Merge pull request #1401 from velovix/issue-1387_client-conf-as-argument

Pass client configuration as an argument
This commit is contained in:
fatedier 2019-08-22 00:14:56 +08:00 committed by GitHub
commit bc4df74b5e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 162 additions and 164 deletions

View File

@ -21,7 +21,6 @@ import (
"time" "time"
"github.com/fatedier/frp/assets" "github.com/fatedier/frp/assets"
"github.com/fatedier/frp/g"
frpNet "github.com/fatedier/frp/utils/net" frpNet "github.com/fatedier/frp/utils/net"
"github.com/gorilla/mux" "github.com/gorilla/mux"
@ -36,7 +35,7 @@ func (svr *Service) RunAdminServer(addr string, port int) (err error) {
// url router // url router
router := mux.NewRouter() router := mux.NewRouter()
user, passwd := g.GlbClientCfg.AdminUser, g.GlbClientCfg.AdminPwd user, passwd := svr.cfg.AdminUser, svr.cfg.AdminPwd
router.Use(frpNet.NewHttpAuthMiddleware(user, passwd).Middleware) router.Use(frpNet.NewHttpAuthMiddleware(user, passwd).Middleware)
// api, see dashboard_api.go // api, see dashboard_api.go

View File

@ -23,7 +23,6 @@ import (
"strings" "strings"
"github.com/fatedier/frp/client/proxy" "github.com/fatedier/frp/client/proxy"
"github.com/fatedier/frp/g"
"github.com/fatedier/frp/models/config" "github.com/fatedier/frp/models/config"
"github.com/fatedier/frp/utils/log" "github.com/fatedier/frp/utils/log"
) )
@ -47,7 +46,7 @@ func (svr *Service) apiReload(w http.ResponseWriter, r *http.Request) {
} }
}() }()
content, err := config.GetRenderedConfFromFile(g.GlbClientCfg.CfgFile) content, err := config.GetRenderedConfFromFile(svr.cfgFile)
if err != nil { if err != nil {
res.Code = 400 res.Code = 400
res.Msg = err.Error() res.Msg = err.Error()
@ -55,7 +54,7 @@ func (svr *Service) apiReload(w http.ResponseWriter, r *http.Request) {
return return
} }
newCommonCfg, err := config.UnmarshalClientConfFromIni(nil, content) newCommonCfg, err := config.UnmarshalClientConfFromIni(content)
if err != nil { if err != nil {
res.Code = 400 res.Code = 400
res.Msg = err.Error() res.Msg = err.Error()
@ -63,7 +62,7 @@ func (svr *Service) apiReload(w http.ResponseWriter, r *http.Request) {
return return
} }
pxyCfgs, visitorCfgs, err := config.LoadAllConfFromIni(g.GlbClientCfg.User, content, newCommonCfg.Start) pxyCfgs, visitorCfgs, err := config.LoadAllConfFromIni(svr.cfg.User, content, newCommonCfg.Start)
if err != nil { if err != nil {
res.Code = 400 res.Code = 400
res.Msg = err.Error() res.Msg = err.Error()
@ -107,7 +106,7 @@ func (a ByProxyStatusResp) Len() int { return len(a) }
func (a ByProxyStatusResp) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a ByProxyStatusResp) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByProxyStatusResp) Less(i, j int) bool { return strings.Compare(a[i].Name, a[j].Name) < 0 } func (a ByProxyStatusResp) Less(i, j int) bool { return strings.Compare(a[i].Name, a[j].Name) < 0 }
func NewProxyStatusResp(status *proxy.ProxyStatus) ProxyStatusResp { func NewProxyStatusResp(status *proxy.ProxyStatus, serverAddr string) ProxyStatusResp {
psr := ProxyStatusResp{ psr := ProxyStatusResp{
Name: status.Name, Name: status.Name,
Type: status.Type, Type: status.Type,
@ -121,18 +120,18 @@ func NewProxyStatusResp(status *proxy.ProxyStatus) ProxyStatusResp {
} }
psr.Plugin = cfg.Plugin psr.Plugin = cfg.Plugin
if status.Err != "" { if status.Err != "" {
psr.RemoteAddr = fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, cfg.RemotePort) psr.RemoteAddr = fmt.Sprintf("%s:%d", serverAddr, cfg.RemotePort)
} else { } else {
psr.RemoteAddr = g.GlbClientCfg.ServerAddr + status.RemoteAddr psr.RemoteAddr = serverAddr + status.RemoteAddr
} }
case *config.UdpProxyConf: case *config.UdpProxyConf:
if cfg.LocalPort != 0 { if cfg.LocalPort != 0 {
psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIp, cfg.LocalPort) psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIp, cfg.LocalPort)
} }
if status.Err != "" { if status.Err != "" {
psr.RemoteAddr = fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, cfg.RemotePort) psr.RemoteAddr = fmt.Sprintf("%s:%d", serverAddr, cfg.RemotePort)
} else { } else {
psr.RemoteAddr = g.GlbClientCfg.ServerAddr + status.RemoteAddr psr.RemoteAddr = serverAddr + status.RemoteAddr
} }
case *config.HttpProxyConf: case *config.HttpProxyConf:
if cfg.LocalPort != 0 { if cfg.LocalPort != 0 {
@ -184,17 +183,17 @@ func (svr *Service) apiStatus(w http.ResponseWriter, r *http.Request) {
for _, status := range ps { for _, status := range ps {
switch status.Type { switch status.Type {
case "tcp": case "tcp":
res.Tcp = append(res.Tcp, NewProxyStatusResp(status)) res.Tcp = append(res.Tcp, NewProxyStatusResp(status, svr.cfg.ServerAddr))
case "udp": case "udp":
res.Udp = append(res.Udp, NewProxyStatusResp(status)) res.Udp = append(res.Udp, NewProxyStatusResp(status, svr.cfg.ServerAddr))
case "http": case "http":
res.Http = append(res.Http, NewProxyStatusResp(status)) res.Http = append(res.Http, NewProxyStatusResp(status, svr.cfg.ServerAddr))
case "https": case "https":
res.Https = append(res.Https, NewProxyStatusResp(status)) res.Https = append(res.Https, NewProxyStatusResp(status, svr.cfg.ServerAddr))
case "stcp": case "stcp":
res.Stcp = append(res.Stcp, NewProxyStatusResp(status)) res.Stcp = append(res.Stcp, NewProxyStatusResp(status, svr.cfg.ServerAddr))
case "xtcp": case "xtcp":
res.Xtcp = append(res.Xtcp, NewProxyStatusResp(status)) res.Xtcp = append(res.Xtcp, NewProxyStatusResp(status, svr.cfg.ServerAddr))
} }
} }
sort.Sort(ByProxyStatusResp(res.Tcp)) sort.Sort(ByProxyStatusResp(res.Tcp))
@ -219,14 +218,14 @@ func (svr *Service) apiGetConfig(w http.ResponseWriter, r *http.Request) {
} }
}() }()
if g.GlbClientCfg.CfgFile == "" { if svr.cfgFile == "" {
res.Code = 400 res.Code = 400
res.Msg = "frpc has no config file path" res.Msg = "frpc has no config file path"
log.Warn("%s", res.Msg) log.Warn("%s", res.Msg)
return return
} }
content, err := config.GetRenderedConfFromFile(g.GlbClientCfg.CfgFile) content, err := config.GetRenderedConfFromFile(svr.cfgFile)
if err != nil { if err != nil {
res.Code = 400 res.Code = 400
res.Msg = err.Error() res.Msg = err.Error()
@ -277,7 +276,7 @@ func (svr *Service) apiPutConfig(w http.ResponseWriter, r *http.Request) {
// get token from origin content // get token from origin content
token := "" token := ""
b, err := ioutil.ReadFile(g.GlbClientCfg.CfgFile) b, err := ioutil.ReadFile(svr.cfgFile)
if err != nil { if err != nil {
res.Code = 400 res.Code = 400
res.Msg = err.Error() res.Msg = err.Error()
@ -316,7 +315,7 @@ func (svr *Service) apiPutConfig(w http.ResponseWriter, r *http.Request) {
} }
content = strings.Join(newRows, "\n") content = strings.Join(newRows, "\n")
err = ioutil.WriteFile(g.GlbClientCfg.CfgFile, []byte(content), 0644) err = ioutil.WriteFile(svr.cfgFile, []byte(content), 0644)
if err != nil { if err != nil {
res.Code = 500 res.Code = 500
res.Msg = fmt.Sprintf("write content to frpc config file error: %v", err) res.Msg = fmt.Sprintf("write content to frpc config file error: %v", err)

View File

@ -23,7 +23,6 @@ import (
"time" "time"
"github.com/fatedier/frp/client/proxy" "github.com/fatedier/frp/client/proxy"
"github.com/fatedier/frp/g"
"github.com/fatedier/frp/models/config" "github.com/fatedier/frp/models/config"
"github.com/fatedier/frp/models/msg" "github.com/fatedier/frp/models/msg"
"github.com/fatedier/frp/utils/log" "github.com/fatedier/frp/utils/log"
@ -65,16 +64,24 @@ type Control struct {
// last time got the Pong message // last time got the Pong message
lastPong time.Time lastPong time.Time
// The client configuration
clientCfg config.ClientCommonConf
readerShutdown *shutdown.Shutdown readerShutdown *shutdown.Shutdown
writerShutdown *shutdown.Shutdown writerShutdown *shutdown.Shutdown
msgHandlerShutdown *shutdown.Shutdown msgHandlerShutdown *shutdown.Shutdown
// The UDP port that the server is listening on
serverUDPPort int
mu sync.RWMutex mu sync.RWMutex
log.Logger log.Logger
} }
func NewControl(runId string, conn frpNet.Conn, session *fmux.Session, pxyCfgs map[string]config.ProxyConf, visitorCfgs map[string]config.VisitorConf) *Control { func NewControl(runId string, conn frpNet.Conn, session *fmux.Session, clientCfg config.ClientCommonConf,
pxyCfgs map[string]config.ProxyConf, visitorCfgs map[string]config.VisitorConf, serverUDPPort int) *Control {
ctl := &Control{ ctl := &Control{
runId: runId, runId: runId,
conn: conn, conn: conn,
@ -84,12 +91,14 @@ func NewControl(runId string, conn frpNet.Conn, session *fmux.Session, pxyCfgs m
readCh: make(chan msg.Message, 100), readCh: make(chan msg.Message, 100),
closedCh: make(chan struct{}), closedCh: make(chan struct{}),
closedDoneCh: make(chan struct{}), closedDoneCh: make(chan struct{}),
clientCfg: clientCfg,
readerShutdown: shutdown.New(), readerShutdown: shutdown.New(),
writerShutdown: shutdown.New(), writerShutdown: shutdown.New(),
msgHandlerShutdown: shutdown.New(), msgHandlerShutdown: shutdown.New(),
serverUDPPort: serverUDPPort,
Logger: log.NewPrefixLogger(""), Logger: log.NewPrefixLogger(""),
} }
ctl.pm = proxy.NewProxyManager(ctl.sendCh, runId) ctl.pm = proxy.NewProxyManager(ctl.sendCh, runId, clientCfg, serverUDPPort)
ctl.vm = NewVisitorManager(ctl) ctl.vm = NewVisitorManager(ctl)
ctl.vm.Reload(visitorCfgs) ctl.vm.Reload(visitorCfgs)
@ -161,7 +170,7 @@ func (ctl *Control) ClosedDoneCh() <-chan struct{} {
// connectServer return a new connection to frps // connectServer return a new connection to frps
func (ctl *Control) connectServer() (conn frpNet.Conn, err error) { func (ctl *Control) connectServer() (conn frpNet.Conn, err error) {
if g.GlbClientCfg.TcpMux { if ctl.clientCfg.TcpMux {
stream, errRet := ctl.session.OpenStream() stream, errRet := ctl.session.OpenStream()
if errRet != nil { if errRet != nil {
err = errRet err = errRet
@ -171,13 +180,13 @@ func (ctl *Control) connectServer() (conn frpNet.Conn, err error) {
conn = frpNet.WrapConn(stream) conn = frpNet.WrapConn(stream)
} else { } else {
var tlsConfig *tls.Config var tlsConfig *tls.Config
if g.GlbClientCfg.TLSEnable { if ctl.clientCfg.TLSEnable {
tlsConfig = &tls.Config{ tlsConfig = &tls.Config{
InsecureSkipVerify: true, InsecureSkipVerify: true,
} }
} }
conn, err = frpNet.ConnectServerByProxyWithTLS(g.GlbClientCfg.HttpProxy, g.GlbClientCfg.Protocol, conn, err = frpNet.ConnectServerByProxyWithTLS(ctl.clientCfg.HttpProxy, ctl.clientCfg.Protocol,
fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerPort), tlsConfig) fmt.Sprintf("%s:%d", ctl.clientCfg.ServerAddr, ctl.clientCfg.ServerPort), tlsConfig)
if err != nil { if err != nil {
ctl.Warn("start new connection to server error: %v", err) ctl.Warn("start new connection to server error: %v", err)
return return
@ -197,7 +206,7 @@ func (ctl *Control) reader() {
defer ctl.readerShutdown.Done() defer ctl.readerShutdown.Done()
defer close(ctl.closedCh) defer close(ctl.closedCh)
encReader := crypto.NewReader(ctl.conn, []byte(g.GlbClientCfg.Token)) encReader := crypto.NewReader(ctl.conn, []byte(ctl.clientCfg.Token))
for { for {
if m, err := msg.ReadMsg(encReader); err != nil { if m, err := msg.ReadMsg(encReader); err != nil {
if err == io.EOF { if err == io.EOF {
@ -217,7 +226,7 @@ func (ctl *Control) reader() {
// writer writes messages got from sendCh to frps // writer writes messages got from sendCh to frps
func (ctl *Control) writer() { func (ctl *Control) writer() {
defer ctl.writerShutdown.Done() defer ctl.writerShutdown.Done()
encWriter, err := crypto.NewWriter(ctl.conn, []byte(g.GlbClientCfg.Token)) encWriter, err := crypto.NewWriter(ctl.conn, []byte(ctl.clientCfg.Token))
if err != nil { if err != nil {
ctl.conn.Error("crypto new writer error: %v", err) ctl.conn.Error("crypto new writer error: %v", err)
ctl.conn.Close() ctl.conn.Close()
@ -246,7 +255,7 @@ func (ctl *Control) msgHandler() {
}() }()
defer ctl.msgHandlerShutdown.Done() defer ctl.msgHandlerShutdown.Done()
hbSend := time.NewTicker(time.Duration(g.GlbClientCfg.HeartBeatInterval) * time.Second) hbSend := time.NewTicker(time.Duration(ctl.clientCfg.HeartBeatInterval) * time.Second)
defer hbSend.Stop() defer hbSend.Stop()
hbCheck := time.NewTicker(time.Second) hbCheck := time.NewTicker(time.Second)
defer hbCheck.Stop() defer hbCheck.Stop()
@ -260,7 +269,7 @@ func (ctl *Control) msgHandler() {
ctl.Debug("send heartbeat to server") ctl.Debug("send heartbeat to server")
ctl.sendCh <- &msg.Ping{} ctl.sendCh <- &msg.Ping{}
case <-hbCheck.C: case <-hbCheck.C:
if time.Since(ctl.lastPong) > time.Duration(g.GlbClientCfg.HeartBeatTimeout)*time.Second { if time.Since(ctl.lastPong) > time.Duration(ctl.clientCfg.HeartBeatTimeout)*time.Second {
ctl.Warn("heartbeat timeout") ctl.Warn("heartbeat timeout")
// let reader() stop // let reader() stop
ctl.conn.Close() ctl.conn.Close()

View File

@ -25,7 +25,6 @@ import (
"sync" "sync"
"time" "time"
"github.com/fatedier/frp/g"
"github.com/fatedier/frp/models/config" "github.com/fatedier/frp/models/config"
"github.com/fatedier/frp/models/msg" "github.com/fatedier/frp/models/msg"
"github.com/fatedier/frp/models/plugin" "github.com/fatedier/frp/models/plugin"
@ -51,9 +50,11 @@ type Proxy interface {
log.Logger log.Logger
} }
func NewProxy(pxyConf config.ProxyConf) (pxy Proxy) { func NewProxy(pxyConf config.ProxyConf, clientCfg config.ClientCommonConf, serverUDPPort int) (pxy Proxy) {
baseProxy := BaseProxy{ baseProxy := BaseProxy{
Logger: log.NewPrefixLogger(pxyConf.GetBaseInfo().ProxyName), Logger: log.NewPrefixLogger(pxyConf.GetBaseInfo().ProxyName),
clientCfg: clientCfg,
serverUDPPort: serverUDPPort,
} }
switch cfg := pxyConf.(type) { switch cfg := pxyConf.(type) {
case *config.TcpProxyConf: case *config.TcpProxyConf:
@ -93,6 +94,8 @@ func NewProxy(pxyConf config.ProxyConf) (pxy Proxy) {
type BaseProxy struct { type BaseProxy struct {
closed bool closed bool
mu sync.RWMutex mu sync.RWMutex
clientCfg config.ClientCommonConf
serverUDPPort int
log.Logger log.Logger
} }
@ -122,7 +125,7 @@ func (pxy *TcpProxy) Close() {
func (pxy *TcpProxy) InWorkConn(conn frpNet.Conn, m *msg.StartWorkConn) { func (pxy *TcpProxy) InWorkConn(conn frpNet.Conn, m *msg.StartWorkConn) {
HandleTcpWorkConnection(&pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, conn, HandleTcpWorkConnection(&pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, conn,
[]byte(g.GlbClientCfg.Token), m) []byte(pxy.clientCfg.Token), m)
} }
// HTTP // HTTP
@ -151,7 +154,7 @@ func (pxy *HttpProxy) Close() {
func (pxy *HttpProxy) InWorkConn(conn frpNet.Conn, m *msg.StartWorkConn) { func (pxy *HttpProxy) InWorkConn(conn frpNet.Conn, m *msg.StartWorkConn) {
HandleTcpWorkConnection(&pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, conn, HandleTcpWorkConnection(&pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, conn,
[]byte(g.GlbClientCfg.Token), m) []byte(pxy.clientCfg.Token), m)
} }
// HTTPS // HTTPS
@ -180,7 +183,7 @@ func (pxy *HttpsProxy) Close() {
func (pxy *HttpsProxy) InWorkConn(conn frpNet.Conn, m *msg.StartWorkConn) { func (pxy *HttpsProxy) InWorkConn(conn frpNet.Conn, m *msg.StartWorkConn) {
HandleTcpWorkConnection(&pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, conn, HandleTcpWorkConnection(&pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, conn,
[]byte(g.GlbClientCfg.Token), m) []byte(pxy.clientCfg.Token), m)
} }
// STCP // STCP
@ -209,7 +212,7 @@ func (pxy *StcpProxy) Close() {
func (pxy *StcpProxy) InWorkConn(conn frpNet.Conn, m *msg.StartWorkConn) { func (pxy *StcpProxy) InWorkConn(conn frpNet.Conn, m *msg.StartWorkConn) {
HandleTcpWorkConnection(&pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, conn, HandleTcpWorkConnection(&pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, conn,
[]byte(g.GlbClientCfg.Token), m) []byte(pxy.clientCfg.Token), m)
} }
// XTCP // XTCP
@ -250,7 +253,7 @@ func (pxy *XtcpProxy) InWorkConn(conn frpNet.Conn, m *msg.StartWorkConn) {
Sid: natHoleSidMsg.Sid, Sid: natHoleSidMsg.Sid,
} }
raddr, _ := net.ResolveUDPAddr("udp", raddr, _ := net.ResolveUDPAddr("udp",
fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerUdpPort)) fmt.Sprintf("%s:%d", pxy.clientCfg.ServerAddr, pxy.serverUDPPort))
clientConn, err := net.DialUDP("udp", nil, raddr) clientConn, err := net.DialUDP("udp", nil, raddr)
defer clientConn.Close() defer clientConn.Close()

View File

@ -20,15 +20,22 @@ type ProxyManager struct {
closed bool closed bool
mu sync.RWMutex mu sync.RWMutex
clientCfg config.ClientCommonConf
// The UDP port that the server is listening on
serverUDPPort int
logPrefix string logPrefix string
log.Logger log.Logger
} }
func NewProxyManager(msgSendCh chan (msg.Message), logPrefix string) *ProxyManager { func NewProxyManager(msgSendCh chan (msg.Message), logPrefix string, clientCfg config.ClientCommonConf, serverUDPPort int) *ProxyManager {
return &ProxyManager{ return &ProxyManager{
proxies: make(map[string]*ProxyWrapper), proxies: make(map[string]*ProxyWrapper),
sendCh: msgSendCh, sendCh: msgSendCh,
closed: false, closed: false,
clientCfg: clientCfg,
serverUDPPort: serverUDPPort,
logPrefix: logPrefix, logPrefix: logPrefix,
Logger: log.NewPrefixLogger(logPrefix), Logger: log.NewPrefixLogger(logPrefix),
} }
@ -126,7 +133,7 @@ func (pm *ProxyManager) Reload(pxyCfgs map[string]config.ProxyConf) {
addPxyNames := make([]string, 0) addPxyNames := make([]string, 0)
for name, cfg := range pxyCfgs { for name, cfg := range pxyCfgs {
if _, ok := pm.proxies[name]; !ok { if _, ok := pm.proxies[name]; !ok {
pxy := NewProxyWrapper(cfg, pm.HandleEvent, pm.logPrefix) pxy := NewProxyWrapper(cfg, pm.clientCfg, pm.HandleEvent, pm.logPrefix, pm.serverUDPPort)
pm.proxies[name] = pxy pm.proxies[name] = pxy
addPxyNames = append(addPxyNames, name) addPxyNames = append(addPxyNames, name)

View File

@ -65,7 +65,7 @@ type ProxyWrapper struct {
log.Logger log.Logger
} }
func NewProxyWrapper(cfg config.ProxyConf, eventHandler event.EventHandler, logPrefix string) *ProxyWrapper { func NewProxyWrapper(cfg config.ProxyConf, clientCfg config.ClientCommonConf, eventHandler event.EventHandler, logPrefix string, serverUDPPort int) *ProxyWrapper {
baseInfo := cfg.GetBaseInfo() baseInfo := cfg.GetBaseInfo()
pw := &ProxyWrapper{ pw := &ProxyWrapper{
ProxyStatus: ProxyStatus{ ProxyStatus: ProxyStatus{
@ -90,7 +90,7 @@ func NewProxyWrapper(cfg config.ProxyConf, eventHandler event.EventHandler, logP
pw.Trace("enable health check monitor") pw.Trace("enable health check monitor")
} }
pw.pxy = NewProxy(pw.Cfg) pw.pxy = NewProxy(pw.Cfg, clientCfg, serverUDPPort)
return pw return pw
} }

View File

@ -24,7 +24,6 @@ import (
"time" "time"
"github.com/fatedier/frp/assets" "github.com/fatedier/frp/assets"
"github.com/fatedier/frp/g"
"github.com/fatedier/frp/models/config" "github.com/fatedier/frp/models/config"
"github.com/fatedier/frp/models/msg" "github.com/fatedier/frp/models/msg"
"github.com/fatedier/frp/utils/log" "github.com/fatedier/frp/utils/log"
@ -43,16 +42,26 @@ type Service struct {
ctl *Control ctl *Control
ctlMu sync.RWMutex ctlMu sync.RWMutex
cfg config.ClientCommonConf
pxyCfgs map[string]config.ProxyConf pxyCfgs map[string]config.ProxyConf
visitorCfgs map[string]config.VisitorConf visitorCfgs map[string]config.VisitorConf
cfgMu sync.RWMutex cfgMu sync.RWMutex
// The configuration file used to initialize this client, or an empty
// string if no configuration file was used.
cfgFile string
// This is configured by the login response from frps
serverUDPPort int
exit uint32 // 0 means not exit exit uint32 // 0 means not exit
closedCh chan int closedCh chan int
} }
func NewService(pxyCfgs map[string]config.ProxyConf, visitorCfgs map[string]config.VisitorConf) (svr *Service, err error) { func NewService(cfg config.ClientCommonConf, pxyCfgs map[string]config.ProxyConf, visitorCfgs map[string]config.VisitorConf, cfgFile string) (svr *Service, err error) {
svr = &Service{ svr = &Service{
cfg: cfg,
cfgFile: cfgFile,
pxyCfgs: pxyCfgs, pxyCfgs: pxyCfgs,
visitorCfgs: visitorCfgs, visitorCfgs: visitorCfgs,
exit: 0, exit: 0,
@ -76,14 +85,14 @@ func (svr *Service) Run() error {
// if login_fail_exit is true, just exit this program // if login_fail_exit is true, just exit this program
// otherwise sleep a while and try again to connect to server // otherwise sleep a while and try again to connect to server
if g.GlbClientCfg.LoginFailExit { if svr.cfg.LoginFailExit {
return err return err
} else { } else {
time.Sleep(10 * time.Second) time.Sleep(10 * time.Second)
} }
} else { } else {
// login success // login success
ctl := NewControl(svr.runId, conn, session, svr.pxyCfgs, svr.visitorCfgs) ctl := NewControl(svr.runId, conn, session, svr.cfg, svr.pxyCfgs, svr.visitorCfgs, svr.serverUDPPort)
ctl.Run() ctl.Run()
svr.ctlMu.Lock() svr.ctlMu.Lock()
svr.ctl = ctl svr.ctl = ctl
@ -94,18 +103,18 @@ func (svr *Service) Run() error {
go svr.keepControllerWorking() go svr.keepControllerWorking()
if g.GlbClientCfg.AdminPort != 0 { if svr.cfg.AdminPort != 0 {
// Init admin server assets // Init admin server assets
err := assets.Load(g.GlbClientCfg.AssetsDir) err := assets.Load(svr.cfg.AssetsDir)
if err != nil { if err != nil {
return fmt.Errorf("Load assets error: %v", err) return fmt.Errorf("Load assets error: %v", err)
} }
err = svr.RunAdminServer(g.GlbClientCfg.AdminAddr, g.GlbClientCfg.AdminPort) err = svr.RunAdminServer(svr.cfg.AdminAddr, svr.cfg.AdminPort)
if err != nil { if err != nil {
log.Warn("run admin server error: %v", err) log.Warn("run admin server error: %v", err)
} }
log.Info("admin server listen on %s:%d", g.GlbClientCfg.AdminAddr, g.GlbClientCfg.AdminPort) log.Info("admin server listen on %s:%d", svr.cfg.AdminAddr, svr.cfg.AdminPort)
} }
<-svr.closedCh <-svr.closedCh
@ -137,7 +146,7 @@ func (svr *Service) keepControllerWorking() {
// reconnect success, init delayTime // reconnect success, init delayTime
delayTime = time.Second delayTime = time.Second
ctl := NewControl(svr.runId, conn, session, svr.pxyCfgs, svr.visitorCfgs) ctl := NewControl(svr.runId, conn, session, svr.cfg, svr.pxyCfgs, svr.visitorCfgs, svr.serverUDPPort)
ctl.Run() ctl.Run()
svr.ctlMu.Lock() svr.ctlMu.Lock()
svr.ctl = ctl svr.ctl = ctl
@ -152,13 +161,13 @@ func (svr *Service) keepControllerWorking() {
// session: if it's not nil, using tcp mux // session: if it's not nil, using tcp mux
func (svr *Service) login() (conn frpNet.Conn, session *fmux.Session, err error) { func (svr *Service) login() (conn frpNet.Conn, session *fmux.Session, err error) {
var tlsConfig *tls.Config var tlsConfig *tls.Config
if g.GlbClientCfg.TLSEnable { if svr.cfg.TLSEnable {
tlsConfig = &tls.Config{ tlsConfig = &tls.Config{
InsecureSkipVerify: true, InsecureSkipVerify: true,
} }
} }
conn, err = frpNet.ConnectServerByProxyWithTLS(g.GlbClientCfg.HttpProxy, g.GlbClientCfg.Protocol, conn, err = frpNet.ConnectServerByProxyWithTLS(svr.cfg.HttpProxy, svr.cfg.Protocol,
fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerPort), tlsConfig) fmt.Sprintf("%s:%d", svr.cfg.ServerAddr, svr.cfg.ServerPort), tlsConfig)
if err != nil { if err != nil {
return return
} }
@ -172,7 +181,7 @@ func (svr *Service) login() (conn frpNet.Conn, session *fmux.Session, err error)
} }
}() }()
if g.GlbClientCfg.TcpMux { if svr.cfg.TcpMux {
fmuxCfg := fmux.DefaultConfig() fmuxCfg := fmux.DefaultConfig()
fmuxCfg.KeepAliveInterval = 20 * time.Second fmuxCfg.KeepAliveInterval = 20 * time.Second
fmuxCfg.LogOutput = ioutil.Discard fmuxCfg.LogOutput = ioutil.Discard
@ -193,10 +202,10 @@ func (svr *Service) login() (conn frpNet.Conn, session *fmux.Session, err error)
loginMsg := &msg.Login{ loginMsg := &msg.Login{
Arch: runtime.GOARCH, Arch: runtime.GOARCH,
Os: runtime.GOOS, Os: runtime.GOOS,
PoolCount: g.GlbClientCfg.PoolCount, PoolCount: svr.cfg.PoolCount,
User: g.GlbClientCfg.User, User: svr.cfg.User,
Version: version.Full(), Version: version.Full(),
PrivilegeKey: util.GetAuthKey(g.GlbClientCfg.Token, now), PrivilegeKey: util.GetAuthKey(svr.cfg.Token, now),
Timestamp: now, Timestamp: now,
RunId: svr.runId, RunId: svr.runId,
} }
@ -219,7 +228,7 @@ func (svr *Service) login() (conn frpNet.Conn, session *fmux.Session, err error)
} }
svr.runId = loginRespMsg.RunId svr.runId = loginRespMsg.RunId
g.GlbClientCfg.ServerUdpPort = loginRespMsg.ServerUdpPort svr.serverUDPPort = loginRespMsg.ServerUdpPort
log.Info("login to server success, get run id [%s], server udp port [%d]", loginRespMsg.RunId, loginRespMsg.ServerUdpPort) log.Info("login to server success, get run id [%s], server udp port [%d]", loginRespMsg.RunId, loginRespMsg.ServerUdpPort)
return return
} }

View File

@ -23,7 +23,6 @@ import (
"sync" "sync"
"time" "time"
"github.com/fatedier/frp/g"
"github.com/fatedier/frp/models/config" "github.com/fatedier/frp/models/config"
"github.com/fatedier/frp/models/msg" "github.com/fatedier/frp/models/msg"
"github.com/fatedier/frp/utils/log" "github.com/fatedier/frp/utils/log"
@ -193,13 +192,13 @@ func (sv *XtcpVisitor) handleConn(userConn frpNet.Conn) {
defer userConn.Close() defer userConn.Close()
sv.Debug("get a new xtcp user connection") sv.Debug("get a new xtcp user connection")
if g.GlbClientCfg.ServerUdpPort == 0 { if sv.ctl.serverUDPPort == 0 {
sv.Error("xtcp is not supported by server") sv.Error("xtcp is not supported by server")
return return
} }
raddr, err := net.ResolveUDPAddr("udp", raddr, err := net.ResolveUDPAddr("udp",
fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerUdpPort)) fmt.Sprintf("%s:%d", sv.ctl.clientCfg.ServerAddr, sv.ctl.serverUDPPort))
if err != nil { if err != nil {
sv.Error("resolve server UDP addr error") sv.Error("resolve server UDP addr error")
return return

View File

@ -54,7 +54,7 @@ var httpCmd = &cobra.Command{
Use: "http", Use: "http",
Short: "Run frpc with a single http proxy", Short: "Run frpc with a single http proxy",
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
err := parseClientCommonCfg(CfgFileTypeCmd, "") clientCfg, err := parseClientCommonCfg(CfgFileTypeCmd, "")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
os.Exit(1) os.Exit(1)
@ -87,7 +87,7 @@ var httpCmd = &cobra.Command{
proxyConfs := map[string]config.ProxyConf{ proxyConfs := map[string]config.ProxyConf{
cfg.ProxyName: cfg, cfg.ProxyName: cfg,
} }
err = startService(proxyConfs, nil) err = startService(clientCfg, proxyConfs, nil, "")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
os.Exit(1) os.Exit(1)

View File

@ -50,7 +50,7 @@ var httpsCmd = &cobra.Command{
Use: "https", Use: "https",
Short: "Run frpc with a single https proxy", Short: "Run frpc with a single https proxy",
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
err := parseClientCommonCfg(CfgFileTypeCmd, "") clientCfg, err := parseClientCommonCfg(CfgFileTypeCmd, "")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
os.Exit(1) os.Exit(1)
@ -79,7 +79,7 @@ var httpsCmd = &cobra.Command{
proxyConfs := map[string]config.ProxyConf{ proxyConfs := map[string]config.ProxyConf{
cfg.ProxyName: cfg, cfg.ProxyName: cfg,
} }
err = startService(proxyConfs, nil) err = startService(clientCfg, proxyConfs, nil, "")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
os.Exit(1) os.Exit(1)

View File

@ -24,7 +24,6 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/fatedier/frp/g"
"github.com/fatedier/frp/models/config" "github.com/fatedier/frp/models/config"
) )
@ -42,13 +41,13 @@ var reloadCmd = &cobra.Command{
os.Exit(1) os.Exit(1)
} }
err = parseClientCommonCfg(CfgFileTypeIni, iniContent) clientCfg, err := parseClientCommonCfg(CfgFileTypeIni, iniContent)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
os.Exit(1) os.Exit(1)
} }
err = reload() err = reload(clientCfg)
if err != nil { if err != nil {
fmt.Printf("frpc reload error: %v\n", err) fmt.Printf("frpc reload error: %v\n", err)
os.Exit(1) os.Exit(1)
@ -58,19 +57,19 @@ var reloadCmd = &cobra.Command{
}, },
} }
func reload() error { func reload(clientCfg config.ClientCommonConf) error {
if g.GlbClientCfg.AdminPort == 0 { if clientCfg.AdminPort == 0 {
return fmt.Errorf("admin_port shoud be set if you want to use reload feature") return fmt.Errorf("admin_port shoud be set if you want to use reload feature")
} }
req, err := http.NewRequest("GET", "http://"+ req, err := http.NewRequest("GET", "http://"+
g.GlbClientCfg.AdminAddr+":"+fmt.Sprintf("%d", g.GlbClientCfg.AdminPort)+"/api/reload", nil) clientCfg.AdminAddr+":"+fmt.Sprintf("%d", clientCfg.AdminPort)+"/api/reload", nil)
if err != nil { if err != nil {
return err return err
} }
authStr := "Basic " + base64.StdEncoding.EncodeToString([]byte(g.GlbClientCfg.AdminUser+":"+ authStr := "Basic " + base64.StdEncoding.EncodeToString([]byte(clientCfg.AdminUser+":"+
g.GlbClientCfg.AdminPwd)) clientCfg.AdminPwd))
req.Header.Add("Authorization", authStr) req.Header.Add("Authorization", authStr)
resp, err := http.DefaultClient.Do(req) resp, err := http.DefaultClient.Do(req)

View File

@ -28,7 +28,6 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/fatedier/frp/client" "github.com/fatedier/frp/client"
"github.com/fatedier/frp/g"
"github.com/fatedier/frp/models/config" "github.com/fatedier/frp/models/config"
"github.com/fatedier/frp/utils/log" "github.com/fatedier/frp/utils/log"
"github.com/fatedier/frp/utils/version" "github.com/fatedier/frp/utils/version"
@ -114,60 +113,62 @@ func handleSignal(svr *client.Service) {
close(kcpDoneCh) close(kcpDoneCh)
} }
func parseClientCommonCfg(fileType int, content string) (err error) { func parseClientCommonCfg(fileType int, content string) (cfg config.ClientCommonConf, err error) {
if fileType == CfgFileTypeIni { if fileType == CfgFileTypeIni {
err = parseClientCommonCfgFromIni(content) cfg, err = parseClientCommonCfgFromIni(content)
} else if fileType == CfgFileTypeCmd { } else if fileType == CfgFileTypeCmd {
err = parseClientCommonCfgFromCmd() cfg, err = parseClientCommonCfgFromCmd()
} }
if err != nil { if err != nil {
return return
} }
err = g.GlbClientCfg.ClientCommonConf.Check() err = cfg.Check()
if err != nil { if err != nil {
return return
} }
return return
} }
func parseClientCommonCfgFromIni(content string) (err error) { func parseClientCommonCfgFromIni(content string) (config.ClientCommonConf, error) {
cfg, err := config.UnmarshalClientConfFromIni(&g.GlbClientCfg.ClientCommonConf, content) cfg, err := config.UnmarshalClientConfFromIni(content)
if err != nil { if err != nil {
return err return config.ClientCommonConf{}, err
} }
g.GlbClientCfg.ClientCommonConf = *cfg return cfg, err
return
} }
func parseClientCommonCfgFromCmd() (err error) { func parseClientCommonCfgFromCmd() (cfg config.ClientCommonConf, err error) {
cfg = config.GetDefaultClientConf()
strs := strings.Split(serverAddr, ":") strs := strings.Split(serverAddr, ":")
if len(strs) < 2 { if len(strs) < 2 {
err = fmt.Errorf("invalid server_addr") err = fmt.Errorf("invalid server_addr")
return return
} }
if strs[0] != "" { if strs[0] != "" {
g.GlbClientCfg.ServerAddr = strs[0] cfg.ServerAddr = strs[0]
} }
g.GlbClientCfg.ServerPort, err = strconv.Atoi(strs[1]) cfg.ServerPort, err = strconv.Atoi(strs[1])
if err != nil { if err != nil {
err = fmt.Errorf("invalid server_addr") err = fmt.Errorf("invalid server_addr")
return return
} }
g.GlbClientCfg.User = user cfg.User = user
g.GlbClientCfg.Protocol = protocol cfg.Protocol = protocol
g.GlbClientCfg.Token = token cfg.Token = token
g.GlbClientCfg.LogLevel = logLevel cfg.LogLevel = logLevel
g.GlbClientCfg.LogFile = logFile cfg.LogFile = logFile
g.GlbClientCfg.LogMaxDays = int64(logMaxDays) cfg.LogMaxDays = int64(logMaxDays)
if logFile == "console" { if logFile == "console" {
g.GlbClientCfg.LogWay = "console" cfg.LogWay = "console"
} else { } else {
g.GlbClientCfg.LogWay = "file" cfg.LogWay = "file"
} }
g.GlbClientCfg.DisableLogColor = disableLogColor cfg.DisableLogColor = disableLogColor
return nil
return
} }
func runClient(cfgFilePath string) (err error) { func runClient(cfgFilePath string) (err error) {
@ -176,28 +177,27 @@ func runClient(cfgFilePath string) (err error) {
if err != nil { if err != nil {
return return
} }
g.GlbClientCfg.CfgFile = cfgFilePath
err = parseClientCommonCfg(CfgFileTypeIni, content) cfg, err := parseClientCommonCfg(CfgFileTypeIni, content)
if err != nil { if err != nil {
return return
} }
pxyCfgs, visitorCfgs, err := config.LoadAllConfFromIni(g.GlbClientCfg.User, content, g.GlbClientCfg.Start) pxyCfgs, visitorCfgs, err := config.LoadAllConfFromIni(cfg.User, content, cfg.Start)
if err != nil { if err != nil {
return err return err
} }
err = startService(pxyCfgs, visitorCfgs) err = startService(cfg, pxyCfgs, visitorCfgs, cfgFilePath)
return return
} }
func startService(pxyCfgs map[string]config.ProxyConf, visitorCfgs map[string]config.VisitorConf) (err error) { func startService(cfg config.ClientCommonConf, pxyCfgs map[string]config.ProxyConf, visitorCfgs map[string]config.VisitorConf, cfgFile string) (err error) {
log.InitLog(g.GlbClientCfg.LogWay, g.GlbClientCfg.LogFile, g.GlbClientCfg.LogLevel, log.InitLog(cfg.LogWay, cfg.LogFile, cfg.LogLevel,
g.GlbClientCfg.LogMaxDays, g.GlbClientCfg.DisableLogColor) cfg.LogMaxDays, cfg.DisableLogColor)
if g.GlbClientCfg.DnsServer != "" { if cfg.DnsServer != "" {
s := g.GlbClientCfg.DnsServer s := cfg.DnsServer
if !strings.Contains(s, ":") { if !strings.Contains(s, ":") {
s += ":53" s += ":53"
} }
@ -209,19 +209,19 @@ func startService(pxyCfgs map[string]config.ProxyConf, visitorCfgs map[string]co
}, },
} }
} }
svr, errRet := client.NewService(pxyCfgs, visitorCfgs) svr, errRet := client.NewService(cfg, pxyCfgs, visitorCfgs, cfgFile)
if errRet != nil { if errRet != nil {
err = errRet err = errRet
return return
} }
// Capture the exit signal if we use kcp. // Capture the exit signal if we use kcp.
if g.GlbClientCfg.Protocol == "kcp" { if cfg.Protocol == "kcp" {
go handleSignal(svr) go handleSignal(svr)
} }
err = svr.Run() err = svr.Run()
if g.GlbClientCfg.Protocol == "kcp" { if cfg.Protocol == "kcp" {
<-kcpDoneCh <-kcpDoneCh
} }
return return

View File

@ -27,7 +27,6 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/fatedier/frp/client" "github.com/fatedier/frp/client"
"github.com/fatedier/frp/g"
"github.com/fatedier/frp/models/config" "github.com/fatedier/frp/models/config"
) )
@ -45,13 +44,13 @@ var statusCmd = &cobra.Command{
os.Exit(1) os.Exit(1)
} }
err = parseClientCommonCfg(CfgFileTypeIni, iniContent) clientCfg, err := parseClientCommonCfg(CfgFileTypeIni, iniContent)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
os.Exit(1) os.Exit(1)
} }
err = status() err = status(clientCfg)
if err != nil { if err != nil {
fmt.Printf("frpc get status error: %v\n", err) fmt.Printf("frpc get status error: %v\n", err)
os.Exit(1) os.Exit(1)
@ -60,19 +59,19 @@ var statusCmd = &cobra.Command{
}, },
} }
func status() error { func status(clientCfg config.ClientCommonConf) error {
if g.GlbClientCfg.AdminPort == 0 { if clientCfg.AdminPort == 0 {
return fmt.Errorf("admin_port shoud be set if you want to get proxy status") return fmt.Errorf("admin_port shoud be set if you want to get proxy status")
} }
req, err := http.NewRequest("GET", "http://"+ req, err := http.NewRequest("GET", "http://"+
g.GlbClientCfg.AdminAddr+":"+fmt.Sprintf("%d", g.GlbClientCfg.AdminPort)+"/api/status", nil) clientCfg.AdminAddr+":"+fmt.Sprintf("%d", clientCfg.AdminPort)+"/api/status", nil)
if err != nil { if err != nil {
return err return err
} }
authStr := "Basic " + base64.StdEncoding.EncodeToString([]byte(g.GlbClientCfg.AdminUser+":"+ authStr := "Basic " + base64.StdEncoding.EncodeToString([]byte(clientCfg.AdminUser+":"+
g.GlbClientCfg.AdminPwd)) clientCfg.AdminPwd))
req.Header.Add("Authorization", authStr) req.Header.Add("Authorization", authStr)
resp, err := http.DefaultClient.Do(req) resp, err := http.DefaultClient.Do(req)

View File

@ -52,7 +52,7 @@ var stcpCmd = &cobra.Command{
Use: "stcp", Use: "stcp",
Short: "Run frpc with a single stcp proxy", Short: "Run frpc with a single stcp proxy",
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
err := parseClientCommonCfg(CfgFileTypeCmd, "") clientCfg, err := parseClientCommonCfg(CfgFileTypeCmd, "")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
os.Exit(1) os.Exit(1)
@ -104,7 +104,7 @@ var stcpCmd = &cobra.Command{
os.Exit(1) os.Exit(1)
} }
err = startService(proxyConfs, visitorConfs) err = startService(clientCfg, proxyConfs, visitorConfs, "")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
os.Exit(1) os.Exit(1)

View File

@ -48,7 +48,7 @@ var tcpCmd = &cobra.Command{
Use: "tcp", Use: "tcp",
Short: "Run frpc with a single tcp proxy", Short: "Run frpc with a single tcp proxy",
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
err := parseClientCommonCfg(CfgFileTypeCmd, "") clientCfg, err := parseClientCommonCfg(CfgFileTypeCmd, "")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
os.Exit(1) os.Exit(1)
@ -76,7 +76,7 @@ var tcpCmd = &cobra.Command{
proxyConfs := map[string]config.ProxyConf{ proxyConfs := map[string]config.ProxyConf{
cfg.ProxyName: cfg, cfg.ProxyName: cfg,
} }
err = startService(proxyConfs, nil) err = startService(clientCfg, proxyConfs, nil, "")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
os.Exit(1) os.Exit(1)

View File

@ -48,7 +48,7 @@ var udpCmd = &cobra.Command{
Use: "udp", Use: "udp",
Short: "Run frpc with a single udp proxy", Short: "Run frpc with a single udp proxy",
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
err := parseClientCommonCfg(CfgFileTypeCmd, "") clientCfg, err := parseClientCommonCfg(CfgFileTypeCmd, "")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
os.Exit(1) os.Exit(1)
@ -76,7 +76,7 @@ var udpCmd = &cobra.Command{
proxyConfs := map[string]config.ProxyConf{ proxyConfs := map[string]config.ProxyConf{
cfg.ProxyName: cfg, cfg.ProxyName: cfg,
} }
err = startService(proxyConfs, nil) err = startService(clientCfg, proxyConfs, nil, "")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
os.Exit(1) os.Exit(1)

View File

@ -52,7 +52,7 @@ var xtcpCmd = &cobra.Command{
Use: "xtcp", Use: "xtcp",
Short: "Run frpc with a single xtcp proxy", Short: "Run frpc with a single xtcp proxy",
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
err := parseClientCommonCfg(CfgFileTypeCmd, "") clientCfg, err := parseClientCommonCfg(CfgFileTypeCmd, "")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
os.Exit(1) os.Exit(1)
@ -104,7 +104,7 @@ var xtcpCmd = &cobra.Command{
os.Exit(1) os.Exit(1)
} }
err = startService(proxyConfs, visitorConfs) err = startService(clientCfg, proxyConfs, visitorConfs, "")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
os.Exit(1) os.Exit(1)

22
g/g.go
View File

@ -1,22 +0,0 @@
package g
import (
"github.com/fatedier/frp/models/config"
)
var (
GlbClientCfg *ClientCfg
)
func init() {
GlbClientCfg = &ClientCfg{
ClientCommonConf: *config.GetDefaultClientConf(),
}
}
type ClientCfg struct {
config.ClientCommonConf
CfgFile string
ServerUdpPort int // this is configured by login response from frps
}

View File

@ -51,8 +51,8 @@ type ClientCommonConf struct {
HeartBeatTimeout int64 `json:"heartbeat_timeout"` HeartBeatTimeout int64 `json:"heartbeat_timeout"`
} }
func GetDefaultClientConf() *ClientCommonConf { func GetDefaultClientConf() ClientCommonConf {
return &ClientCommonConf{ return ClientCommonConf{
ServerAddr: "0.0.0.0", ServerAddr: "0.0.0.0",
ServerPort: 7000, ServerPort: 7000,
HttpProxy: os.Getenv("http_proxy"), HttpProxy: os.Getenv("http_proxy"),
@ -80,16 +80,13 @@ func GetDefaultClientConf() *ClientCommonConf {
} }
} }
func UnmarshalClientConfFromIni(defaultCfg *ClientCommonConf, content string) (cfg *ClientCommonConf, err error) { func UnmarshalClientConfFromIni(content string) (cfg ClientCommonConf, err error) {
cfg = defaultCfg
if cfg == nil {
cfg = GetDefaultClientConf() cfg = GetDefaultClientConf()
}
conf, err := ini.Load(strings.NewReader(content)) conf, err := ini.Load(strings.NewReader(content))
if err != nil { if err != nil {
err = fmt.Errorf("parse ini conf file error: %v", err) err = fmt.Errorf("parse ini conf file error: %v", err)
return nil, err return ClientCommonConf{}, err
} }
var ( var (