diff --git a/client/admin.go b/client/admin.go index 90456857..b3e3f81a 100644 --- a/client/admin.go +++ b/client/admin.go @@ -21,7 +21,6 @@ import ( "time" "github.com/fatedier/frp/assets" - "github.com/fatedier/frp/g" frpNet "github.com/fatedier/frp/utils/net" "github.com/gorilla/mux" @@ -36,7 +35,7 @@ func (svr *Service) RunAdminServer(addr string, port int) (err error) { // url router 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) // api, see dashboard_api.go diff --git a/client/admin_api.go b/client/admin_api.go index 4d7205bb..af61b395 100644 --- a/client/admin_api.go +++ b/client/admin_api.go @@ -23,7 +23,6 @@ import ( "strings" "github.com/fatedier/frp/client/proxy" - "github.com/fatedier/frp/g" "github.com/fatedier/frp/models/config" "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 { res.Code = 400 res.Msg = err.Error() @@ -55,7 +54,7 @@ func (svr *Service) apiReload(w http.ResponseWriter, r *http.Request) { return } - newCommonCfg, err := config.UnmarshalClientConfFromIni(nil, content) + newCommonCfg, err := config.UnmarshalClientConfFromIni(content) if err != nil { res.Code = 400 res.Msg = err.Error() @@ -63,7 +62,7 @@ func (svr *Service) apiReload(w http.ResponseWriter, r *http.Request) { 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 { res.Code = 400 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) 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{ Name: status.Name, Type: status.Type, @@ -121,18 +120,18 @@ func NewProxyStatusResp(status *proxy.ProxyStatus) ProxyStatusResp { } psr.Plugin = cfg.Plugin if status.Err != "" { - psr.RemoteAddr = fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, cfg.RemotePort) + psr.RemoteAddr = fmt.Sprintf("%s:%d", serverAddr, cfg.RemotePort) } else { - psr.RemoteAddr = g.GlbClientCfg.ServerAddr + status.RemoteAddr + psr.RemoteAddr = serverAddr + status.RemoteAddr } case *config.UdpProxyConf: if cfg.LocalPort != 0 { psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIp, cfg.LocalPort) } if status.Err != "" { - psr.RemoteAddr = fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, cfg.RemotePort) + psr.RemoteAddr = fmt.Sprintf("%s:%d", serverAddr, cfg.RemotePort) } else { - psr.RemoteAddr = g.GlbClientCfg.ServerAddr + status.RemoteAddr + psr.RemoteAddr = serverAddr + status.RemoteAddr } case *config.HttpProxyConf: if cfg.LocalPort != 0 { @@ -184,17 +183,17 @@ func (svr *Service) apiStatus(w http.ResponseWriter, r *http.Request) { for _, status := range ps { switch status.Type { case "tcp": - res.Tcp = append(res.Tcp, NewProxyStatusResp(status)) + res.Tcp = append(res.Tcp, NewProxyStatusResp(status, svr.cfg.ServerAddr)) case "udp": - res.Udp = append(res.Udp, NewProxyStatusResp(status)) + res.Udp = append(res.Udp, NewProxyStatusResp(status, svr.cfg.ServerAddr)) case "http": - res.Http = append(res.Http, NewProxyStatusResp(status)) + res.Http = append(res.Http, NewProxyStatusResp(status, svr.cfg.ServerAddr)) case "https": - res.Https = append(res.Https, NewProxyStatusResp(status)) + res.Https = append(res.Https, NewProxyStatusResp(status, svr.cfg.ServerAddr)) case "stcp": - res.Stcp = append(res.Stcp, NewProxyStatusResp(status)) + res.Stcp = append(res.Stcp, NewProxyStatusResp(status, svr.cfg.ServerAddr)) case "xtcp": - res.Xtcp = append(res.Xtcp, NewProxyStatusResp(status)) + res.Xtcp = append(res.Xtcp, NewProxyStatusResp(status, svr.cfg.ServerAddr)) } } 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.Msg = "frpc has no config file path" log.Warn("%s", res.Msg) return } - content, err := config.GetRenderedConfFromFile(g.GlbClientCfg.CfgFile) + content, err := config.GetRenderedConfFromFile(svr.cfgFile) if err != nil { res.Code = 400 res.Msg = err.Error() @@ -277,7 +276,7 @@ func (svr *Service) apiPutConfig(w http.ResponseWriter, r *http.Request) { // get token from origin content token := "" - b, err := ioutil.ReadFile(g.GlbClientCfg.CfgFile) + b, err := ioutil.ReadFile(svr.cfgFile) if err != nil { res.Code = 400 res.Msg = err.Error() @@ -316,7 +315,7 @@ func (svr *Service) apiPutConfig(w http.ResponseWriter, r *http.Request) { } 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 { res.Code = 500 res.Msg = fmt.Sprintf("write content to frpc config file error: %v", err) diff --git a/client/control.go b/client/control.go index 6a12b8c1..30992f9a 100644 --- a/client/control.go +++ b/client/control.go @@ -23,7 +23,6 @@ import ( "time" "github.com/fatedier/frp/client/proxy" - "github.com/fatedier/frp/g" "github.com/fatedier/frp/models/config" "github.com/fatedier/frp/models/msg" "github.com/fatedier/frp/utils/log" @@ -65,16 +64,24 @@ type Control struct { // last time got the Pong message lastPong time.Time + // The client configuration + clientCfg config.ClientCommonConf + readerShutdown *shutdown.Shutdown writerShutdown *shutdown.Shutdown msgHandlerShutdown *shutdown.Shutdown + // The UDP port that the server is listening on + serverUDPPort int + mu sync.RWMutex 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{ runId: runId, conn: conn, @@ -84,12 +91,14 @@ func NewControl(runId string, conn frpNet.Conn, session *fmux.Session, pxyCfgs m readCh: make(chan msg.Message, 100), closedCh: make(chan struct{}), closedDoneCh: make(chan struct{}), + clientCfg: clientCfg, readerShutdown: shutdown.New(), writerShutdown: shutdown.New(), msgHandlerShutdown: shutdown.New(), + serverUDPPort: serverUDPPort, 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.Reload(visitorCfgs) @@ -161,7 +170,7 @@ func (ctl *Control) ClosedDoneCh() <-chan struct{} { // connectServer return a new connection to frps func (ctl *Control) connectServer() (conn frpNet.Conn, err error) { - if g.GlbClientCfg.TcpMux { + if ctl.clientCfg.TcpMux { stream, errRet := ctl.session.OpenStream() if errRet != nil { err = errRet @@ -171,13 +180,13 @@ func (ctl *Control) connectServer() (conn frpNet.Conn, err error) { conn = frpNet.WrapConn(stream) } else { var tlsConfig *tls.Config - if g.GlbClientCfg.TLSEnable { + if ctl.clientCfg.TLSEnable { tlsConfig = &tls.Config{ InsecureSkipVerify: true, } } - conn, err = frpNet.ConnectServerByProxyWithTLS(g.GlbClientCfg.HttpProxy, g.GlbClientCfg.Protocol, - fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerPort), tlsConfig) + conn, err = frpNet.ConnectServerByProxyWithTLS(ctl.clientCfg.HttpProxy, ctl.clientCfg.Protocol, + fmt.Sprintf("%s:%d", ctl.clientCfg.ServerAddr, ctl.clientCfg.ServerPort), tlsConfig) if err != nil { ctl.Warn("start new connection to server error: %v", err) return @@ -197,7 +206,7 @@ func (ctl *Control) reader() { defer ctl.readerShutdown.Done() defer close(ctl.closedCh) - encReader := crypto.NewReader(ctl.conn, []byte(g.GlbClientCfg.Token)) + encReader := crypto.NewReader(ctl.conn, []byte(ctl.clientCfg.Token)) for { if m, err := msg.ReadMsg(encReader); err != nil { if err == io.EOF { @@ -217,7 +226,7 @@ func (ctl *Control) reader() { // writer writes messages got from sendCh to frps func (ctl *Control) writer() { 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 { ctl.conn.Error("crypto new writer error: %v", err) ctl.conn.Close() @@ -246,7 +255,7 @@ func (ctl *Control) msgHandler() { }() 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() hbCheck := time.NewTicker(time.Second) defer hbCheck.Stop() @@ -260,7 +269,7 @@ func (ctl *Control) msgHandler() { ctl.Debug("send heartbeat to server") ctl.sendCh <- &msg.Ping{} 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") // let reader() stop ctl.conn.Close() diff --git a/client/proxy/proxy.go b/client/proxy/proxy.go index bc230f40..0c43740f 100644 --- a/client/proxy/proxy.go +++ b/client/proxy/proxy.go @@ -25,7 +25,6 @@ import ( "sync" "time" - "github.com/fatedier/frp/g" "github.com/fatedier/frp/models/config" "github.com/fatedier/frp/models/msg" "github.com/fatedier/frp/models/plugin" @@ -51,9 +50,11 @@ type Proxy interface { log.Logger } -func NewProxy(pxyConf config.ProxyConf) (pxy Proxy) { +func NewProxy(pxyConf config.ProxyConf, clientCfg config.ClientCommonConf, serverUDPPort int) (pxy Proxy) { baseProxy := BaseProxy{ - Logger: log.NewPrefixLogger(pxyConf.GetBaseInfo().ProxyName), + Logger: log.NewPrefixLogger(pxyConf.GetBaseInfo().ProxyName), + clientCfg: clientCfg, + serverUDPPort: serverUDPPort, } switch cfg := pxyConf.(type) { case *config.TcpProxyConf: @@ -91,8 +92,10 @@ func NewProxy(pxyConf config.ProxyConf) (pxy Proxy) { } type BaseProxy struct { - closed bool - mu sync.RWMutex + closed bool + mu sync.RWMutex + clientCfg config.ClientCommonConf + serverUDPPort int log.Logger } @@ -122,7 +125,7 @@ func (pxy *TcpProxy) Close() { func (pxy *TcpProxy) InWorkConn(conn frpNet.Conn, m *msg.StartWorkConn) { HandleTcpWorkConnection(&pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, conn, - []byte(g.GlbClientCfg.Token), m) + []byte(pxy.clientCfg.Token), m) } // HTTP @@ -151,7 +154,7 @@ func (pxy *HttpProxy) Close() { func (pxy *HttpProxy) InWorkConn(conn frpNet.Conn, m *msg.StartWorkConn) { HandleTcpWorkConnection(&pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, conn, - []byte(g.GlbClientCfg.Token), m) + []byte(pxy.clientCfg.Token), m) } // HTTPS @@ -180,7 +183,7 @@ func (pxy *HttpsProxy) Close() { func (pxy *HttpsProxy) InWorkConn(conn frpNet.Conn, m *msg.StartWorkConn) { HandleTcpWorkConnection(&pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, conn, - []byte(g.GlbClientCfg.Token), m) + []byte(pxy.clientCfg.Token), m) } // STCP @@ -209,7 +212,7 @@ func (pxy *StcpProxy) Close() { func (pxy *StcpProxy) InWorkConn(conn frpNet.Conn, m *msg.StartWorkConn) { HandleTcpWorkConnection(&pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, conn, - []byte(g.GlbClientCfg.Token), m) + []byte(pxy.clientCfg.Token), m) } // XTCP @@ -250,7 +253,7 @@ func (pxy *XtcpProxy) InWorkConn(conn frpNet.Conn, m *msg.StartWorkConn) { Sid: natHoleSidMsg.Sid, } 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) defer clientConn.Close() diff --git a/client/proxy/proxy_manager.go b/client/proxy/proxy_manager.go index fb230b3e..1d0d8786 100644 --- a/client/proxy/proxy_manager.go +++ b/client/proxy/proxy_manager.go @@ -20,17 +20,24 @@ type ProxyManager struct { closed bool mu sync.RWMutex + clientCfg config.ClientCommonConf + + // The UDP port that the server is listening on + serverUDPPort int + logPrefix string 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{ - proxies: make(map[string]*ProxyWrapper), - sendCh: msgSendCh, - closed: false, - logPrefix: logPrefix, - Logger: log.NewPrefixLogger(logPrefix), + proxies: make(map[string]*ProxyWrapper), + sendCh: msgSendCh, + closed: false, + clientCfg: clientCfg, + serverUDPPort: serverUDPPort, + logPrefix: logPrefix, + Logger: log.NewPrefixLogger(logPrefix), } } @@ -126,7 +133,7 @@ func (pm *ProxyManager) Reload(pxyCfgs map[string]config.ProxyConf) { addPxyNames := make([]string, 0) for name, cfg := range pxyCfgs { 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 addPxyNames = append(addPxyNames, name) diff --git a/client/proxy/proxy_wrapper.go b/client/proxy/proxy_wrapper.go index 0b29e481..b02e5291 100644 --- a/client/proxy/proxy_wrapper.go +++ b/client/proxy/proxy_wrapper.go @@ -65,7 +65,7 @@ type ProxyWrapper struct { 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() pw := &ProxyWrapper{ ProxyStatus: ProxyStatus{ @@ -90,7 +90,7 @@ func NewProxyWrapper(cfg config.ProxyConf, eventHandler event.EventHandler, logP pw.Trace("enable health check monitor") } - pw.pxy = NewProxy(pw.Cfg) + pw.pxy = NewProxy(pw.Cfg, clientCfg, serverUDPPort) return pw } diff --git a/client/service.go b/client/service.go index 356b6bf5..266ab49d 100644 --- a/client/service.go +++ b/client/service.go @@ -24,7 +24,6 @@ import ( "time" "github.com/fatedier/frp/assets" - "github.com/fatedier/frp/g" "github.com/fatedier/frp/models/config" "github.com/fatedier/frp/models/msg" "github.com/fatedier/frp/utils/log" @@ -43,16 +42,26 @@ type Service struct { ctl *Control ctlMu sync.RWMutex + cfg config.ClientCommonConf pxyCfgs map[string]config.ProxyConf visitorCfgs map[string]config.VisitorConf 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 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{ + cfg: cfg, + cfgFile: cfgFile, pxyCfgs: pxyCfgs, visitorCfgs: visitorCfgs, exit: 0, @@ -76,14 +85,14 @@ func (svr *Service) Run() error { // if login_fail_exit is true, just exit this program // otherwise sleep a while and try again to connect to server - if g.GlbClientCfg.LoginFailExit { + if svr.cfg.LoginFailExit { return err } else { time.Sleep(10 * time.Second) } } else { // 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() svr.ctlMu.Lock() svr.ctl = ctl @@ -94,18 +103,18 @@ func (svr *Service) Run() error { go svr.keepControllerWorking() - if g.GlbClientCfg.AdminPort != 0 { + if svr.cfg.AdminPort != 0 { // Init admin server assets - err := assets.Load(g.GlbClientCfg.AssetsDir) + err := assets.Load(svr.cfg.AssetsDir) if err != nil { 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 { 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 @@ -137,7 +146,7 @@ func (svr *Service) keepControllerWorking() { // reconnect success, init delayTime 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() svr.ctlMu.Lock() svr.ctl = ctl @@ -152,13 +161,13 @@ func (svr *Service) keepControllerWorking() { // session: if it's not nil, using tcp mux func (svr *Service) login() (conn frpNet.Conn, session *fmux.Session, err error) { var tlsConfig *tls.Config - if g.GlbClientCfg.TLSEnable { + if svr.cfg.TLSEnable { tlsConfig = &tls.Config{ InsecureSkipVerify: true, } } - conn, err = frpNet.ConnectServerByProxyWithTLS(g.GlbClientCfg.HttpProxy, g.GlbClientCfg.Protocol, - fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerPort), tlsConfig) + conn, err = frpNet.ConnectServerByProxyWithTLS(svr.cfg.HttpProxy, svr.cfg.Protocol, + fmt.Sprintf("%s:%d", svr.cfg.ServerAddr, svr.cfg.ServerPort), tlsConfig) if err != nil { 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.KeepAliveInterval = 20 * time.Second fmuxCfg.LogOutput = ioutil.Discard @@ -193,10 +202,10 @@ func (svr *Service) login() (conn frpNet.Conn, session *fmux.Session, err error) loginMsg := &msg.Login{ Arch: runtime.GOARCH, Os: runtime.GOOS, - PoolCount: g.GlbClientCfg.PoolCount, - User: g.GlbClientCfg.User, + PoolCount: svr.cfg.PoolCount, + User: svr.cfg.User, Version: version.Full(), - PrivilegeKey: util.GetAuthKey(g.GlbClientCfg.Token, now), + PrivilegeKey: util.GetAuthKey(svr.cfg.Token, now), Timestamp: now, RunId: svr.runId, } @@ -219,7 +228,7 @@ func (svr *Service) login() (conn frpNet.Conn, session *fmux.Session, err error) } 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) return } diff --git a/client/visitor.go b/client/visitor.go index 6eb3688c..773aa115 100644 --- a/client/visitor.go +++ b/client/visitor.go @@ -23,7 +23,6 @@ import ( "sync" "time" - "github.com/fatedier/frp/g" "github.com/fatedier/frp/models/config" "github.com/fatedier/frp/models/msg" "github.com/fatedier/frp/utils/log" @@ -193,13 +192,13 @@ func (sv *XtcpVisitor) handleConn(userConn frpNet.Conn) { defer userConn.Close() 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") return } 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 { sv.Error("resolve server UDP addr error") return diff --git a/cmd/frpc/sub/http.go b/cmd/frpc/sub/http.go index 6e682e64..081102cb 100644 --- a/cmd/frpc/sub/http.go +++ b/cmd/frpc/sub/http.go @@ -54,7 +54,7 @@ var httpCmd = &cobra.Command{ Use: "http", Short: "Run frpc with a single http proxy", RunE: func(cmd *cobra.Command, args []string) error { - err := parseClientCommonCfg(CfgFileTypeCmd, "") + clientCfg, err := parseClientCommonCfg(CfgFileTypeCmd, "") if err != nil { fmt.Println(err) os.Exit(1) @@ -87,7 +87,7 @@ var httpCmd = &cobra.Command{ proxyConfs := map[string]config.ProxyConf{ cfg.ProxyName: cfg, } - err = startService(proxyConfs, nil) + err = startService(clientCfg, proxyConfs, nil, "") if err != nil { fmt.Println(err) os.Exit(1) diff --git a/cmd/frpc/sub/https.go b/cmd/frpc/sub/https.go index 6fc06152..7d5fbe8b 100644 --- a/cmd/frpc/sub/https.go +++ b/cmd/frpc/sub/https.go @@ -50,7 +50,7 @@ var httpsCmd = &cobra.Command{ Use: "https", Short: "Run frpc with a single https proxy", RunE: func(cmd *cobra.Command, args []string) error { - err := parseClientCommonCfg(CfgFileTypeCmd, "") + clientCfg, err := parseClientCommonCfg(CfgFileTypeCmd, "") if err != nil { fmt.Println(err) os.Exit(1) @@ -79,7 +79,7 @@ var httpsCmd = &cobra.Command{ proxyConfs := map[string]config.ProxyConf{ cfg.ProxyName: cfg, } - err = startService(proxyConfs, nil) + err = startService(clientCfg, proxyConfs, nil, "") if err != nil { fmt.Println(err) os.Exit(1) diff --git a/cmd/frpc/sub/reload.go b/cmd/frpc/sub/reload.go index 46118c3e..f3514754 100644 --- a/cmd/frpc/sub/reload.go +++ b/cmd/frpc/sub/reload.go @@ -24,7 +24,6 @@ import ( "github.com/spf13/cobra" - "github.com/fatedier/frp/g" "github.com/fatedier/frp/models/config" ) @@ -42,13 +41,13 @@ var reloadCmd = &cobra.Command{ os.Exit(1) } - err = parseClientCommonCfg(CfgFileTypeIni, iniContent) + clientCfg, err := parseClientCommonCfg(CfgFileTypeIni, iniContent) if err != nil { fmt.Println(err) os.Exit(1) } - err = reload() + err = reload(clientCfg) if err != nil { fmt.Printf("frpc reload error: %v\n", err) os.Exit(1) @@ -58,19 +57,19 @@ var reloadCmd = &cobra.Command{ }, } -func reload() error { - if g.GlbClientCfg.AdminPort == 0 { +func reload(clientCfg config.ClientCommonConf) error { + if clientCfg.AdminPort == 0 { return fmt.Errorf("admin_port shoud be set if you want to use reload feature") } 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 { return err } - authStr := "Basic " + base64.StdEncoding.EncodeToString([]byte(g.GlbClientCfg.AdminUser+":"+ - g.GlbClientCfg.AdminPwd)) + authStr := "Basic " + base64.StdEncoding.EncodeToString([]byte(clientCfg.AdminUser+":"+ + clientCfg.AdminPwd)) req.Header.Add("Authorization", authStr) resp, err := http.DefaultClient.Do(req) diff --git a/cmd/frpc/sub/root.go b/cmd/frpc/sub/root.go index 157206f3..82a906bd 100644 --- a/cmd/frpc/sub/root.go +++ b/cmd/frpc/sub/root.go @@ -28,7 +28,6 @@ import ( "github.com/spf13/cobra" "github.com/fatedier/frp/client" - "github.com/fatedier/frp/g" "github.com/fatedier/frp/models/config" "github.com/fatedier/frp/utils/log" "github.com/fatedier/frp/utils/version" @@ -114,60 +113,62 @@ func handleSignal(svr *client.Service) { close(kcpDoneCh) } -func parseClientCommonCfg(fileType int, content string) (err error) { +func parseClientCommonCfg(fileType int, content string) (cfg config.ClientCommonConf, err error) { if fileType == CfgFileTypeIni { - err = parseClientCommonCfgFromIni(content) + cfg, err = parseClientCommonCfgFromIni(content) } else if fileType == CfgFileTypeCmd { - err = parseClientCommonCfgFromCmd() + cfg, err = parseClientCommonCfgFromCmd() } if err != nil { return } - err = g.GlbClientCfg.ClientCommonConf.Check() + err = cfg.Check() if err != nil { return } return } -func parseClientCommonCfgFromIni(content string) (err error) { - cfg, err := config.UnmarshalClientConfFromIni(&g.GlbClientCfg.ClientCommonConf, content) +func parseClientCommonCfgFromIni(content string) (config.ClientCommonConf, error) { + cfg, err := config.UnmarshalClientConfFromIni(content) if err != nil { - return err + return config.ClientCommonConf{}, err } - g.GlbClientCfg.ClientCommonConf = *cfg - return + return cfg, err } -func parseClientCommonCfgFromCmd() (err error) { +func parseClientCommonCfgFromCmd() (cfg config.ClientCommonConf, err error) { + cfg = config.GetDefaultClientConf() + strs := strings.Split(serverAddr, ":") if len(strs) < 2 { err = fmt.Errorf("invalid server_addr") return } 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 { err = fmt.Errorf("invalid server_addr") return } - g.GlbClientCfg.User = user - g.GlbClientCfg.Protocol = protocol - g.GlbClientCfg.Token = token - g.GlbClientCfg.LogLevel = logLevel - g.GlbClientCfg.LogFile = logFile - g.GlbClientCfg.LogMaxDays = int64(logMaxDays) + cfg.User = user + cfg.Protocol = protocol + cfg.Token = token + cfg.LogLevel = logLevel + cfg.LogFile = logFile + cfg.LogMaxDays = int64(logMaxDays) if logFile == "console" { - g.GlbClientCfg.LogWay = "console" + cfg.LogWay = "console" } else { - g.GlbClientCfg.LogWay = "file" + cfg.LogWay = "file" } - g.GlbClientCfg.DisableLogColor = disableLogColor - return nil + cfg.DisableLogColor = disableLogColor + + return } func runClient(cfgFilePath string) (err error) { @@ -176,28 +177,27 @@ func runClient(cfgFilePath string) (err error) { if err != nil { return } - g.GlbClientCfg.CfgFile = cfgFilePath - err = parseClientCommonCfg(CfgFileTypeIni, content) + cfg, err := parseClientCommonCfg(CfgFileTypeIni, content) if err != nil { 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 { return err } - err = startService(pxyCfgs, visitorCfgs) + err = startService(cfg, pxyCfgs, visitorCfgs, cfgFilePath) return } -func startService(pxyCfgs map[string]config.ProxyConf, visitorCfgs map[string]config.VisitorConf) (err error) { - log.InitLog(g.GlbClientCfg.LogWay, g.GlbClientCfg.LogFile, g.GlbClientCfg.LogLevel, - g.GlbClientCfg.LogMaxDays, g.GlbClientCfg.DisableLogColor) +func startService(cfg config.ClientCommonConf, pxyCfgs map[string]config.ProxyConf, visitorCfgs map[string]config.VisitorConf, cfgFile string) (err error) { + log.InitLog(cfg.LogWay, cfg.LogFile, cfg.LogLevel, + cfg.LogMaxDays, cfg.DisableLogColor) - if g.GlbClientCfg.DnsServer != "" { - s := g.GlbClientCfg.DnsServer + if cfg.DnsServer != "" { + s := cfg.DnsServer if !strings.Contains(s, ":") { 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 { err = errRet return } // Capture the exit signal if we use kcp. - if g.GlbClientCfg.Protocol == "kcp" { + if cfg.Protocol == "kcp" { go handleSignal(svr) } err = svr.Run() - if g.GlbClientCfg.Protocol == "kcp" { + if cfg.Protocol == "kcp" { <-kcpDoneCh } return diff --git a/cmd/frpc/sub/status.go b/cmd/frpc/sub/status.go index 8f55ce13..783ec29f 100644 --- a/cmd/frpc/sub/status.go +++ b/cmd/frpc/sub/status.go @@ -27,7 +27,6 @@ import ( "github.com/spf13/cobra" "github.com/fatedier/frp/client" - "github.com/fatedier/frp/g" "github.com/fatedier/frp/models/config" ) @@ -45,13 +44,13 @@ var statusCmd = &cobra.Command{ os.Exit(1) } - err = parseClientCommonCfg(CfgFileTypeIni, iniContent) + clientCfg, err := parseClientCommonCfg(CfgFileTypeIni, iniContent) if err != nil { fmt.Println(err) os.Exit(1) } - err = status() + err = status(clientCfg) if err != nil { fmt.Printf("frpc get status error: %v\n", err) os.Exit(1) @@ -60,19 +59,19 @@ var statusCmd = &cobra.Command{ }, } -func status() error { - if g.GlbClientCfg.AdminPort == 0 { +func status(clientCfg config.ClientCommonConf) error { + if clientCfg.AdminPort == 0 { return fmt.Errorf("admin_port shoud be set if you want to get proxy status") } 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 { return err } - authStr := "Basic " + base64.StdEncoding.EncodeToString([]byte(g.GlbClientCfg.AdminUser+":"+ - g.GlbClientCfg.AdminPwd)) + authStr := "Basic " + base64.StdEncoding.EncodeToString([]byte(clientCfg.AdminUser+":"+ + clientCfg.AdminPwd)) req.Header.Add("Authorization", authStr) resp, err := http.DefaultClient.Do(req) diff --git a/cmd/frpc/sub/stcp.go b/cmd/frpc/sub/stcp.go index 610fd73a..1a04fbf3 100644 --- a/cmd/frpc/sub/stcp.go +++ b/cmd/frpc/sub/stcp.go @@ -52,7 +52,7 @@ var stcpCmd = &cobra.Command{ Use: "stcp", Short: "Run frpc with a single stcp proxy", RunE: func(cmd *cobra.Command, args []string) error { - err := parseClientCommonCfg(CfgFileTypeCmd, "") + clientCfg, err := parseClientCommonCfg(CfgFileTypeCmd, "") if err != nil { fmt.Println(err) os.Exit(1) @@ -104,7 +104,7 @@ var stcpCmd = &cobra.Command{ os.Exit(1) } - err = startService(proxyConfs, visitorConfs) + err = startService(clientCfg, proxyConfs, visitorConfs, "") if err != nil { fmt.Println(err) os.Exit(1) diff --git a/cmd/frpc/sub/tcp.go b/cmd/frpc/sub/tcp.go index 76a2a3c8..c2ccd2b8 100644 --- a/cmd/frpc/sub/tcp.go +++ b/cmd/frpc/sub/tcp.go @@ -48,7 +48,7 @@ var tcpCmd = &cobra.Command{ Use: "tcp", Short: "Run frpc with a single tcp proxy", RunE: func(cmd *cobra.Command, args []string) error { - err := parseClientCommonCfg(CfgFileTypeCmd, "") + clientCfg, err := parseClientCommonCfg(CfgFileTypeCmd, "") if err != nil { fmt.Println(err) os.Exit(1) @@ -76,7 +76,7 @@ var tcpCmd = &cobra.Command{ proxyConfs := map[string]config.ProxyConf{ cfg.ProxyName: cfg, } - err = startService(proxyConfs, nil) + err = startService(clientCfg, proxyConfs, nil, "") if err != nil { fmt.Println(err) os.Exit(1) diff --git a/cmd/frpc/sub/udp.go b/cmd/frpc/sub/udp.go index f2d9d488..0d73c763 100644 --- a/cmd/frpc/sub/udp.go +++ b/cmd/frpc/sub/udp.go @@ -48,7 +48,7 @@ var udpCmd = &cobra.Command{ Use: "udp", Short: "Run frpc with a single udp proxy", RunE: func(cmd *cobra.Command, args []string) error { - err := parseClientCommonCfg(CfgFileTypeCmd, "") + clientCfg, err := parseClientCommonCfg(CfgFileTypeCmd, "") if err != nil { fmt.Println(err) os.Exit(1) @@ -76,7 +76,7 @@ var udpCmd = &cobra.Command{ proxyConfs := map[string]config.ProxyConf{ cfg.ProxyName: cfg, } - err = startService(proxyConfs, nil) + err = startService(clientCfg, proxyConfs, nil, "") if err != nil { fmt.Println(err) os.Exit(1) diff --git a/cmd/frpc/sub/xtcp.go b/cmd/frpc/sub/xtcp.go index 5ba944e7..558294da 100644 --- a/cmd/frpc/sub/xtcp.go +++ b/cmd/frpc/sub/xtcp.go @@ -52,7 +52,7 @@ var xtcpCmd = &cobra.Command{ Use: "xtcp", Short: "Run frpc with a single xtcp proxy", RunE: func(cmd *cobra.Command, args []string) error { - err := parseClientCommonCfg(CfgFileTypeCmd, "") + clientCfg, err := parseClientCommonCfg(CfgFileTypeCmd, "") if err != nil { fmt.Println(err) os.Exit(1) @@ -104,7 +104,7 @@ var xtcpCmd = &cobra.Command{ os.Exit(1) } - err = startService(proxyConfs, visitorConfs) + err = startService(clientCfg, proxyConfs, visitorConfs, "") if err != nil { fmt.Println(err) os.Exit(1) diff --git a/g/g.go b/g/g.go deleted file mode 100644 index ecd2471d..00000000 --- a/g/g.go +++ /dev/null @@ -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 -} diff --git a/models/config/client_common.go b/models/config/client_common.go index 7b7040ee..5d9d127f 100644 --- a/models/config/client_common.go +++ b/models/config/client_common.go @@ -51,8 +51,8 @@ type ClientCommonConf struct { HeartBeatTimeout int64 `json:"heartbeat_timeout"` } -func GetDefaultClientConf() *ClientCommonConf { - return &ClientCommonConf{ +func GetDefaultClientConf() ClientCommonConf { + return ClientCommonConf{ ServerAddr: "0.0.0.0", ServerPort: 7000, HttpProxy: os.Getenv("http_proxy"), @@ -80,16 +80,13 @@ func GetDefaultClientConf() *ClientCommonConf { } } -func UnmarshalClientConfFromIni(defaultCfg *ClientCommonConf, content string) (cfg *ClientCommonConf, err error) { - cfg = defaultCfg - if cfg == nil { - cfg = GetDefaultClientConf() - } +func UnmarshalClientConfFromIni(content string) (cfg ClientCommonConf, err error) { + cfg = GetDefaultClientConf() conf, err := ini.Load(strings.NewReader(content)) if err != nil { err = fmt.Errorf("parse ini conf file error: %v", err) - return nil, err + return ClientCommonConf{}, err } var (