Pass client configuration as an argument

The ClientCommonConf, configuration file path, and server UDP port are
now passed around as arguments instead of being shared between
components as global variables. This allows for multiple clients to
exist in the same process, and allows client.Session to be used as a
library more easily.
This commit is contained in:
Tyler Compton 2019-08-20 13:53:27 -07:00
parent f999c8a87e
commit 666f122a72
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 (