mirror of
https://github.com/fatedier/frp.git
synced 2025-01-22 17:42:09 +00:00
cmd: support more cli command
This commit is contained in:
parent
82dc1e924f
commit
0f6f674a64
2
Makefile
2
Makefile
@ -39,7 +39,7 @@ ci:
|
|||||||
go test -v ./tests/...
|
go test -v ./tests/...
|
||||||
cd ./tests && ./clean_test.sh && cd -
|
cd ./tests && ./clean_test.sh && cd -
|
||||||
|
|
||||||
ciclean:
|
cic:
|
||||||
cd ./tests && ./clean_test.sh && cd -
|
cd ./tests && ./clean_test.sh && cd -
|
||||||
|
|
||||||
alltest: gotest ci
|
alltest: gotest ci
|
||||||
|
@ -383,7 +383,7 @@ Then visit `http://[server_addr]:7500` to see dashboard, default username and pa
|
|||||||
|
|
||||||
### Authentication
|
### Authentication
|
||||||
|
|
||||||
Since v0.10.0, you only need to set `privilege_token` in frps.ini and frpc.ini.
|
Since v0.10.0, you only need to set `token` in frps.ini and frpc.ini.
|
||||||
|
|
||||||
Note that time duration between server of frpc and frps mustn't exceed 15 minutes because timestamp is used for authentication.
|
Note that time duration between server of frpc and frps mustn't exceed 15 minutes because timestamp is used for authentication.
|
||||||
|
|
||||||
@ -539,7 +539,7 @@ type = http
|
|||||||
local_port = 80
|
local_port = 80
|
||||||
custom_domains = test.yourdomain.com
|
custom_domains = test.yourdomain.com
|
||||||
http_user = abc
|
http_user = abc
|
||||||
http_pwd = abc
|
http_passwd = abc
|
||||||
```
|
```
|
||||||
|
|
||||||
Visit `http://test.yourdomain.com` and now you need to input username and password.
|
Visit `http://test.yourdomain.com` and now you need to input username and password.
|
||||||
|
@ -401,7 +401,7 @@ dashboard_pwd = admin
|
|||||||
|
|
||||||
### 身份验证
|
### 身份验证
|
||||||
|
|
||||||
从 v0.10.0 版本开始,所有 proxy 配置全部放在客户端(也就是之前版本的特权模式),服务端和客户端的 common 配置中的 `privilege_token` 参数一致则身份验证通过。
|
从 v0.10.0 版本开始,所有 proxy 配置全部放在客户端(也就是之前版本的特权模式),服务端和客户端的 common 配置中的 `token` 参数一致则身份验证通过。
|
||||||
|
|
||||||
需要注意的是 frpc 所在机器和 frps 所在机器的时间相差不能超过 15 分钟,因为时间戳会被用于加密验证中,防止报文被劫持后被其他人利用。
|
需要注意的是 frpc 所在机器和 frps 所在机器的时间相差不能超过 15 分钟,因为时间戳会被用于加密验证中,防止报文被劫持后被其他人利用。
|
||||||
|
|
||||||
@ -565,7 +565,7 @@ type = http
|
|||||||
local_port = 80
|
local_port = 80
|
||||||
custom_domains = test.yourdomain.com
|
custom_domains = test.yourdomain.com
|
||||||
http_user = abc
|
http_user = abc
|
||||||
http_pwd = abc
|
http_passwd = abc
|
||||||
```
|
```
|
||||||
|
|
||||||
通过浏览器访问 `http://test.yourdomain.com`,需要输入配置的用户名和密码才能访问。
|
通过浏览器访问 `http://test.yourdomain.com`,需要输入配置的用户名和密码才能访问。
|
||||||
|
@ -20,7 +20,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/fatedier/frp/models/config"
|
"github.com/fatedier/frp/g"
|
||||||
frpNet "github.com/fatedier/frp/utils/net"
|
frpNet "github.com/fatedier/frp/utils/net"
|
||||||
|
|
||||||
"github.com/julienschmidt/httprouter"
|
"github.com/julienschmidt/httprouter"
|
||||||
@ -35,7 +35,7 @@ func (svr *Service) RunAdminServer(addr string, port int) (err error) {
|
|||||||
// url router
|
// url router
|
||||||
router := httprouter.New()
|
router := httprouter.New()
|
||||||
|
|
||||||
user, passwd := config.ClientCommonCfg.AdminUser, config.ClientCommonCfg.AdminPwd
|
user, passwd := g.GlbClientCfg.AdminUser, g.GlbClientCfg.AdminPwd
|
||||||
|
|
||||||
// api, see dashboard_api.go
|
// api, see dashboard_api.go
|
||||||
router.GET("/api/reload", frpNet.HttprouterBasicAuth(svr.apiReload, user, passwd))
|
router.GET("/api/reload", frpNet.HttprouterBasicAuth(svr.apiReload, user, passwd))
|
||||||
|
@ -17,6 +17,7 @@ package client
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
@ -24,6 +25,7 @@ import (
|
|||||||
"github.com/julienschmidt/httprouter"
|
"github.com/julienschmidt/httprouter"
|
||||||
ini "github.com/vaughan0/go-ini"
|
ini "github.com/vaughan0/go-ini"
|
||||||
|
|
||||||
|
"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"
|
||||||
)
|
)
|
||||||
@ -51,15 +53,16 @@ func (svr *Service) apiReload(w http.ResponseWriter, r *http.Request, _ httprout
|
|||||||
|
|
||||||
log.Info("Http request: [/api/reload]")
|
log.Info("Http request: [/api/reload]")
|
||||||
|
|
||||||
conf, err := ini.LoadFile(config.ClientCommonCfg.ConfigFile)
|
b, err := ioutil.ReadFile(g.GlbClientCfg.CfgFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
res.Code = 1
|
res.Code = 1
|
||||||
res.Msg = err.Error()
|
res.Msg = err.Error()
|
||||||
log.Error("reload frpc config file error: %v", err)
|
log.Error("reload frpc config file error: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
content := string(b)
|
||||||
|
|
||||||
newCommonCfg, err := config.LoadClientCommonConf(conf)
|
newCommonCfg, err := config.UnmarshalClientConfFromIni(nil, content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
res.Code = 2
|
res.Code = 2
|
||||||
res.Msg = err.Error()
|
res.Msg = err.Error()
|
||||||
@ -67,7 +70,15 @@ func (svr *Service) apiReload(w http.ResponseWriter, r *http.Request, _ httprout
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
pxyCfgs, visitorCfgs, err := config.LoadProxyConfFromFile(config.ClientCommonCfg.User, conf, newCommonCfg.Start)
|
conf, err := ini.LoadFile(g.GlbClientCfg.CfgFile)
|
||||||
|
if err != nil {
|
||||||
|
res.Code = 1
|
||||||
|
res.Msg = err.Error()
|
||||||
|
log.Error("reload frpc config file error: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pxyCfgs, visitorCfgs, err := config.LoadProxyConfFromIni(g.GlbClientCfg.User, conf, newCommonCfg.Start)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
res.Code = 3
|
res.Code = 3
|
||||||
res.Msg = err.Error()
|
res.Msg = err.Error()
|
||||||
@ -125,18 +136,18 @@ func NewProxyStatusResp(status *ProxyStatus) ProxyStatusResp {
|
|||||||
}
|
}
|
||||||
psr.Plugin = cfg.Plugin
|
psr.Plugin = cfg.Plugin
|
||||||
if status.Err != "" {
|
if status.Err != "" {
|
||||||
psr.RemoteAddr = fmt.Sprintf("%s:%d", config.ClientCommonCfg.ServerAddr, cfg.RemotePort)
|
psr.RemoteAddr = fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, cfg.RemotePort)
|
||||||
} else {
|
} else {
|
||||||
psr.RemoteAddr = config.ClientCommonCfg.ServerAddr + status.RemoteAddr
|
psr.RemoteAddr = g.GlbClientCfg.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", config.ClientCommonCfg.ServerAddr, cfg.RemotePort)
|
psr.RemoteAddr = fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, cfg.RemotePort)
|
||||||
} else {
|
} else {
|
||||||
psr.RemoteAddr = config.ClientCommonCfg.ServerAddr + status.RemoteAddr
|
psr.RemoteAddr = g.GlbClientCfg.ServerAddr + status.RemoteAddr
|
||||||
}
|
}
|
||||||
case *config.HttpProxyConf:
|
case *config.HttpProxyConf:
|
||||||
if cfg.LocalPort != 0 {
|
if cfg.LocalPort != 0 {
|
||||||
|
@ -21,6 +21,9 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/xtaci/smux"
|
||||||
|
|
||||||
|
"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/crypto"
|
"github.com/fatedier/frp/utils/crypto"
|
||||||
@ -29,7 +32,6 @@ import (
|
|||||||
"github.com/fatedier/frp/utils/shutdown"
|
"github.com/fatedier/frp/utils/shutdown"
|
||||||
"github.com/fatedier/frp/utils/util"
|
"github.com/fatedier/frp/utils/util"
|
||||||
"github.com/fatedier/frp/utils/version"
|
"github.com/fatedier/frp/utils/version"
|
||||||
"github.com/xtaci/smux"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -82,8 +84,8 @@ func NewControl(svr *Service, pxyCfgs map[string]config.ProxyConf, visitorCfgs m
|
|||||||
loginMsg := &msg.Login{
|
loginMsg := &msg.Login{
|
||||||
Arch: runtime.GOARCH,
|
Arch: runtime.GOARCH,
|
||||||
Os: runtime.GOOS,
|
Os: runtime.GOOS,
|
||||||
PoolCount: config.ClientCommonCfg.PoolCount,
|
PoolCount: g.GlbClientCfg.PoolCount,
|
||||||
User: config.ClientCommonCfg.User,
|
User: g.GlbClientCfg.User,
|
||||||
Version: version.Full(),
|
Version: version.Full(),
|
||||||
}
|
}
|
||||||
ctl := &Control{
|
ctl := &Control{
|
||||||
@ -110,7 +112,7 @@ func (ctl *Control) Run() (err 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 continues relogin to server
|
// otherwise sleep a while and continues relogin to server
|
||||||
if config.ClientCommonCfg.LoginFailExit {
|
if g.GlbClientCfg.LoginFailExit {
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
time.Sleep(10 * time.Second)
|
time.Sleep(10 * time.Second)
|
||||||
@ -183,8 +185,8 @@ func (ctl *Control) login() (err error) {
|
|||||||
ctl.session.Close()
|
ctl.session.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
conn, err := frpNet.ConnectServerByHttpProxy(config.ClientCommonCfg.HttpProxy, config.ClientCommonCfg.Protocol,
|
conn, err := frpNet.ConnectServerByHttpProxy(g.GlbClientCfg.HttpProxy, g.GlbClientCfg.Protocol,
|
||||||
fmt.Sprintf("%s:%d", config.ClientCommonCfg.ServerAddr, config.ClientCommonCfg.ServerPort))
|
fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerPort))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -195,7 +197,7 @@ func (ctl *Control) login() (err error) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if config.ClientCommonCfg.TcpMux {
|
if g.GlbClientCfg.TcpMux {
|
||||||
session, errRet := smux.Client(conn, nil)
|
session, errRet := smux.Client(conn, nil)
|
||||||
if errRet != nil {
|
if errRet != nil {
|
||||||
return errRet
|
return errRet
|
||||||
@ -210,7 +212,7 @@ func (ctl *Control) login() (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
now := time.Now().Unix()
|
now := time.Now().Unix()
|
||||||
ctl.loginMsg.PrivilegeKey = util.GetAuthKey(config.ClientCommonCfg.PrivilegeToken, now)
|
ctl.loginMsg.PrivilegeKey = util.GetAuthKey(g.GlbClientCfg.Token, now)
|
||||||
ctl.loginMsg.Timestamp = now
|
ctl.loginMsg.Timestamp = now
|
||||||
ctl.loginMsg.RunId = ctl.runId
|
ctl.loginMsg.RunId = ctl.runId
|
||||||
|
|
||||||
@ -234,7 +236,7 @@ func (ctl *Control) login() (err error) {
|
|||||||
ctl.conn = conn
|
ctl.conn = conn
|
||||||
// update runId got from server
|
// update runId got from server
|
||||||
ctl.runId = loginRespMsg.RunId
|
ctl.runId = loginRespMsg.RunId
|
||||||
config.ClientCommonCfg.ServerUdpPort = loginRespMsg.ServerUdpPort
|
g.GlbClientCfg.ServerUdpPort = loginRespMsg.ServerUdpPort
|
||||||
ctl.ClearLogPrefix()
|
ctl.ClearLogPrefix()
|
||||||
ctl.AddLogPrefix(loginRespMsg.RunId)
|
ctl.AddLogPrefix(loginRespMsg.RunId)
|
||||||
ctl.Info("login to server success, get run id [%s], server udp port [%d]", loginRespMsg.RunId, loginRespMsg.ServerUdpPort)
|
ctl.Info("login to server success, get run id [%s], server udp port [%d]", loginRespMsg.RunId, loginRespMsg.ServerUdpPort)
|
||||||
@ -242,7 +244,7 @@ func (ctl *Control) login() (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ctl *Control) connectServer() (conn frpNet.Conn, err error) {
|
func (ctl *Control) connectServer() (conn frpNet.Conn, err error) {
|
||||||
if config.ClientCommonCfg.TcpMux {
|
if g.GlbClientCfg.TcpMux {
|
||||||
stream, errRet := ctl.session.OpenStream()
|
stream, errRet := ctl.session.OpenStream()
|
||||||
if errRet != nil {
|
if errRet != nil {
|
||||||
err = errRet
|
err = errRet
|
||||||
@ -251,8 +253,8 @@ func (ctl *Control) connectServer() (conn frpNet.Conn, err error) {
|
|||||||
}
|
}
|
||||||
conn = frpNet.WrapConn(stream)
|
conn = frpNet.WrapConn(stream)
|
||||||
} else {
|
} else {
|
||||||
conn, err = frpNet.ConnectServerByHttpProxy(config.ClientCommonCfg.HttpProxy, config.ClientCommonCfg.Protocol,
|
conn, err = frpNet.ConnectServerByHttpProxy(g.GlbClientCfg.HttpProxy, g.GlbClientCfg.Protocol,
|
||||||
fmt.Sprintf("%s:%d", config.ClientCommonCfg.ServerAddr, config.ClientCommonCfg.ServerPort))
|
fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerPort))
|
||||||
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
|
||||||
@ -271,7 +273,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(config.ClientCommonCfg.PrivilegeToken))
|
encReader := crypto.NewReader(ctl.conn, []byte(g.GlbClientCfg.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 {
|
||||||
@ -290,7 +292,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(config.ClientCommonCfg.PrivilegeToken))
|
encWriter, err := crypto.NewWriter(ctl.conn, []byte(g.GlbClientCfg.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()
|
||||||
@ -318,7 +320,7 @@ func (ctl *Control) msgHandler() {
|
|||||||
}()
|
}()
|
||||||
defer ctl.msgHandlerShutdown.Done()
|
defer ctl.msgHandlerShutdown.Done()
|
||||||
|
|
||||||
hbSend := time.NewTicker(time.Duration(config.ClientCommonCfg.HeartBeatInterval) * time.Second)
|
hbSend := time.NewTicker(time.Duration(g.GlbClientCfg.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()
|
||||||
@ -332,7 +334,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(config.ClientCommonCfg.HeartBeatTimeout)*time.Second {
|
if time.Since(ctl.lastPong) > time.Duration(g.GlbClientCfg.HeartBeatTimeout)*time.Second {
|
||||||
ctl.Warn("heartbeat timeout")
|
ctl.Warn("heartbeat timeout")
|
||||||
// let reader() stop
|
// let reader() stop
|
||||||
ctl.conn.Close()
|
ctl.conn.Close()
|
||||||
|
@ -22,6 +22,7 @@ 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"
|
||||||
@ -46,7 +47,7 @@ type Proxy interface {
|
|||||||
|
|
||||||
func NewProxy(pxyConf config.ProxyConf) (pxy Proxy) {
|
func NewProxy(pxyConf config.ProxyConf) (pxy Proxy) {
|
||||||
baseProxy := BaseProxy{
|
baseProxy := BaseProxy{
|
||||||
Logger: log.NewPrefixLogger(pxyConf.GetName()),
|
Logger: log.NewPrefixLogger(pxyConf.GetBaseInfo().ProxyName),
|
||||||
}
|
}
|
||||||
switch cfg := pxyConf.(type) {
|
switch cfg := pxyConf.(type) {
|
||||||
case *config.TcpProxyConf:
|
case *config.TcpProxyConf:
|
||||||
@ -115,7 +116,7 @@ func (pxy *TcpProxy) Close() {
|
|||||||
|
|
||||||
func (pxy *TcpProxy) InWorkConn(conn frpNet.Conn) {
|
func (pxy *TcpProxy) InWorkConn(conn frpNet.Conn) {
|
||||||
HandleTcpWorkConnection(&pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, conn,
|
HandleTcpWorkConnection(&pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, conn,
|
||||||
[]byte(config.ClientCommonCfg.PrivilegeToken))
|
[]byte(g.GlbClientCfg.Token))
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTP
|
// HTTP
|
||||||
@ -144,7 +145,7 @@ func (pxy *HttpProxy) Close() {
|
|||||||
|
|
||||||
func (pxy *HttpProxy) InWorkConn(conn frpNet.Conn) {
|
func (pxy *HttpProxy) InWorkConn(conn frpNet.Conn) {
|
||||||
HandleTcpWorkConnection(&pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, conn,
|
HandleTcpWorkConnection(&pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, conn,
|
||||||
[]byte(config.ClientCommonCfg.PrivilegeToken))
|
[]byte(g.GlbClientCfg.Token))
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTPS
|
// HTTPS
|
||||||
@ -173,7 +174,7 @@ func (pxy *HttpsProxy) Close() {
|
|||||||
|
|
||||||
func (pxy *HttpsProxy) InWorkConn(conn frpNet.Conn) {
|
func (pxy *HttpsProxy) InWorkConn(conn frpNet.Conn) {
|
||||||
HandleTcpWorkConnection(&pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, conn,
|
HandleTcpWorkConnection(&pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, conn,
|
||||||
[]byte(config.ClientCommonCfg.PrivilegeToken))
|
[]byte(g.GlbClientCfg.Token))
|
||||||
}
|
}
|
||||||
|
|
||||||
// STCP
|
// STCP
|
||||||
@ -202,7 +203,7 @@ func (pxy *StcpProxy) Close() {
|
|||||||
|
|
||||||
func (pxy *StcpProxy) InWorkConn(conn frpNet.Conn) {
|
func (pxy *StcpProxy) InWorkConn(conn frpNet.Conn) {
|
||||||
HandleTcpWorkConnection(&pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, conn,
|
HandleTcpWorkConnection(&pxy.cfg.LocalSvrConf, pxy.proxyPlugin, &pxy.cfg.BaseProxyConf, conn,
|
||||||
[]byte(config.ClientCommonCfg.PrivilegeToken))
|
[]byte(g.GlbClientCfg.Token))
|
||||||
}
|
}
|
||||||
|
|
||||||
// XTCP
|
// XTCP
|
||||||
@ -243,7 +244,7 @@ func (pxy *XtcpProxy) InWorkConn(conn frpNet.Conn) {
|
|||||||
Sid: natHoleSidMsg.Sid,
|
Sid: natHoleSidMsg.Sid,
|
||||||
}
|
}
|
||||||
raddr, _ := net.ResolveUDPAddr("udp",
|
raddr, _ := net.ResolveUDPAddr("udp",
|
||||||
fmt.Sprintf("%s:%d", config.ClientCommonCfg.ServerAddr, config.ClientCommonCfg.ServerUdpPort))
|
fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerUdpPort))
|
||||||
clientConn, err := net.DialUDP("udp", nil, raddr)
|
clientConn, err := net.DialUDP("udp", nil, raddr)
|
||||||
defer clientConn.Close()
|
defer clientConn.Close()
|
||||||
|
|
||||||
|
@ -62,8 +62,8 @@ type ProxyStatus struct {
|
|||||||
|
|
||||||
func NewProxyWrapper(cfg config.ProxyConf) *ProxyWrapper {
|
func NewProxyWrapper(cfg config.ProxyConf) *ProxyWrapper {
|
||||||
return &ProxyWrapper{
|
return &ProxyWrapper{
|
||||||
Name: cfg.GetName(),
|
Name: cfg.GetBaseInfo().ProxyName,
|
||||||
Type: cfg.GetType(),
|
Type: cfg.GetBaseInfo().ProxyType,
|
||||||
Status: ProxyStatusNew,
|
Status: ProxyStatusNew,
|
||||||
Cfg: cfg,
|
Cfg: cfg,
|
||||||
pxy: nil,
|
pxy: nil,
|
||||||
@ -227,7 +227,7 @@ func (pm *ProxyManager) CheckAndStartProxy(pxyStatus []string) {
|
|||||||
for _, s := range pxyStatus {
|
for _, s := range pxyStatus {
|
||||||
if status == s {
|
if status == s {
|
||||||
var newProxyMsg msg.NewProxy
|
var newProxyMsg msg.NewProxy
|
||||||
pxy.Cfg.UnMarshalToMsg(&newProxyMsg)
|
pxy.Cfg.MarshalToMsg(&newProxyMsg)
|
||||||
err := pm.sendMsg(&newProxyMsg)
|
err := pm.sendMsg(&newProxyMsg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
pm.Warn("[%s] proxy send NewProxy message error")
|
pm.Warn("[%s] proxy send NewProxy message error")
|
||||||
@ -240,15 +240,16 @@ func (pm *ProxyManager) CheckAndStartProxy(pxyStatus []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, cfg := range pm.visitorCfgs {
|
for _, cfg := range pm.visitorCfgs {
|
||||||
if _, exist := pm.visitors[cfg.GetName()]; !exist {
|
name := cfg.GetBaseInfo().ProxyName
|
||||||
pm.Info("try to start visitor [%s]", cfg.GetName())
|
if _, exist := pm.visitors[name]; !exist {
|
||||||
|
pm.Info("try to start visitor [%s]", name)
|
||||||
visitor := NewVisitor(pm.ctl, cfg)
|
visitor := NewVisitor(pm.ctl, cfg)
|
||||||
err := visitor.Run()
|
err := visitor.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
visitor.Warn("start error: %v", err)
|
visitor.Warn("start error: %v", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
pm.visitors[cfg.GetName()] = visitor
|
pm.visitors[name] = visitor
|
||||||
visitor.Info("start visitor success")
|
visitor.Info("start visitor success")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"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"
|
||||||
)
|
)
|
||||||
@ -41,12 +42,12 @@ func (svr *Service) Run() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.ClientCommonCfg.AdminPort != 0 {
|
if g.GlbClientCfg.AdminPort != 0 {
|
||||||
err = svr.RunAdminServer(config.ClientCommonCfg.AdminAddr, config.ClientCommonCfg.AdminPort)
|
err = svr.RunAdminServer(g.GlbClientCfg.AdminAddr, g.GlbClientCfg.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", config.ClientCommonCfg.AdminAddr, config.ClientCommonCfg.AdminPort)
|
log.Info("admin server listen on %s:%d", g.GlbClientCfg.AdminAddr, g.GlbClientCfg.AdminPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
<-svr.closedCh
|
<-svr.closedCh
|
||||||
|
@ -26,6 +26,7 @@ import (
|
|||||||
|
|
||||||
"golang.org/x/net/ipv4"
|
"golang.org/x/net/ipv4"
|
||||||
|
|
||||||
|
"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"
|
||||||
frpIo "github.com/fatedier/frp/utils/io"
|
frpIo "github.com/fatedier/frp/utils/io"
|
||||||
@ -45,7 +46,7 @@ type Visitor interface {
|
|||||||
func NewVisitor(ctl *Control, pxyConf config.ProxyConf) (visitor Visitor) {
|
func NewVisitor(ctl *Control, pxyConf config.ProxyConf) (visitor Visitor) {
|
||||||
baseVisitor := BaseVisitor{
|
baseVisitor := BaseVisitor{
|
||||||
ctl: ctl,
|
ctl: ctl,
|
||||||
Logger: log.NewPrefixLogger(pxyConf.GetName()),
|
Logger: log.NewPrefixLogger(pxyConf.GetBaseInfo().ProxyName),
|
||||||
}
|
}
|
||||||
switch cfg := pxyConf.(type) {
|
switch cfg := pxyConf.(type) {
|
||||||
case *config.StcpProxyConf:
|
case *config.StcpProxyConf:
|
||||||
@ -193,13 +194,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 config.ClientCommonCfg.ServerUdpPort == 0 {
|
if g.GlbClientCfg.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", config.ClientCommonCfg.ServerAddr, config.ClientCommonCfg.ServerUdpPort))
|
fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerUdpPort))
|
||||||
visitorConn, err := net.DialUDP("udp", nil, raddr)
|
visitorConn, err := net.DialUDP("udp", nil, raddr)
|
||||||
defer visitorConn.Close()
|
defer visitorConn.Close()
|
||||||
|
|
||||||
|
286
cmd/frpc/main.go
286
cmd/frpc/main.go
@ -15,291 +15,9 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"github.com/fatedier/frp/cmd/frpc/sub"
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"os/signal"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"syscall"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
docopt "github.com/docopt/docopt-go"
|
|
||||||
"github.com/rodaine/table"
|
|
||||||
ini "github.com/vaughan0/go-ini"
|
|
||||||
|
|
||||||
"github.com/fatedier/frp/client"
|
|
||||||
"github.com/fatedier/frp/models/config"
|
|
||||||
"github.com/fatedier/frp/utils/log"
|
|
||||||
"github.com/fatedier/frp/utils/version"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
configFile string = "./frpc.ini"
|
|
||||||
)
|
|
||||||
|
|
||||||
var usage string = `frpc is the client of frp
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
frpc [-c config_file] [-L log_file] [--log-level=<log_level>] [--server-addr=<server_addr>]
|
|
||||||
frpc reload [-c config_file]
|
|
||||||
frpc status [-c config_file]
|
|
||||||
frpc -h | --help
|
|
||||||
frpc -v | --version
|
|
||||||
|
|
||||||
Options:
|
|
||||||
-c config_file set config file
|
|
||||||
-L log_file set output log file, including console
|
|
||||||
--log-level=<log_level> set log level: debug, info, warn, error
|
|
||||||
--server-addr=<server_addr> addr which frps is listening for, example: 0.0.0.0:7000
|
|
||||||
-h --help show this screen
|
|
||||||
-v --version show version
|
|
||||||
`
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var err error
|
sub.Execute()
|
||||||
confFile := "./frpc.ini"
|
|
||||||
// the configures parsed from file will be replaced by those from command line if exist
|
|
||||||
args, err := docopt.Parse(usage, nil, true, version.Full(), false)
|
|
||||||
|
|
||||||
if args["-c"] != nil {
|
|
||||||
confFile = args["-c"].(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
conf, err := ini.LoadFile(confFile)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
config.ClientCommonCfg, err = config.LoadClientCommonConf(conf)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
config.ClientCommonCfg.ConfigFile = confFile
|
|
||||||
|
|
||||||
// check if reload command
|
|
||||||
if args["reload"] != nil {
|
|
||||||
if args["reload"].(bool) {
|
|
||||||
if err = CmdReload(); err != nil {
|
|
||||||
fmt.Printf("frpc reload error: %v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
} else {
|
|
||||||
fmt.Printf("reload success\n")
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if status command
|
|
||||||
if args["status"] != nil {
|
|
||||||
if args["status"].(bool) {
|
|
||||||
if err = CmdStatus(); err != nil {
|
|
||||||
fmt.Printf("frpc get status error: %v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
} else {
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if args["-L"] != nil {
|
|
||||||
if args["-L"].(string) == "console" {
|
|
||||||
config.ClientCommonCfg.LogWay = "console"
|
|
||||||
} else {
|
|
||||||
config.ClientCommonCfg.LogWay = "file"
|
|
||||||
config.ClientCommonCfg.LogFile = args["-L"].(string)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if args["--log-level"] != nil {
|
|
||||||
config.ClientCommonCfg.LogLevel = args["--log-level"].(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
if args["--server-addr"] != nil {
|
|
||||||
addr := strings.Split(args["--server-addr"].(string), ":")
|
|
||||||
if len(addr) != 2 {
|
|
||||||
fmt.Println("--server-addr format error: example 0.0.0.0:7000")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
serverPort, err := strconv.ParseInt(addr[1], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("--server-addr format error, example 0.0.0.0:7000")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
config.ClientCommonCfg.ServerAddr = addr[0]
|
|
||||||
config.ClientCommonCfg.ServerPort = int(serverPort)
|
|
||||||
}
|
|
||||||
|
|
||||||
if args["-v"] != nil {
|
|
||||||
if args["-v"].(bool) {
|
|
||||||
fmt.Println(version.Full())
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pxyCfgs, visitorCfgs, err := config.LoadProxyConfFromFile(config.ClientCommonCfg.User, conf, config.ClientCommonCfg.Start)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.InitLog(config.ClientCommonCfg.LogWay, config.ClientCommonCfg.LogFile,
|
|
||||||
config.ClientCommonCfg.LogLevel, config.ClientCommonCfg.LogMaxDays)
|
|
||||||
|
|
||||||
svr := client.NewService(pxyCfgs, visitorCfgs)
|
|
||||||
|
|
||||||
// Capture the exit signal if we use kcp.
|
|
||||||
if config.ClientCommonCfg.Protocol == "kcp" {
|
|
||||||
go HandleSignal(svr)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = svr.Run()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func HandleSignal(svr *client.Service) {
|
|
||||||
ch := make(chan os.Signal)
|
|
||||||
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
|
|
||||||
<-ch
|
|
||||||
svr.Close()
|
|
||||||
time.Sleep(250 * time.Millisecond)
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func CmdReload() error {
|
|
||||||
if config.ClientCommonCfg.AdminPort == 0 {
|
|
||||||
return fmt.Errorf("admin_port shoud be set if you want to use reload feature")
|
|
||||||
}
|
|
||||||
|
|
||||||
req, err := http.NewRequest("GET", "http://"+
|
|
||||||
config.ClientCommonCfg.AdminAddr+":"+fmt.Sprintf("%d", config.ClientCommonCfg.AdminPort)+"/api/reload", nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
authStr := "Basic " + base64.StdEncoding.EncodeToString([]byte(config.ClientCommonCfg.AdminUser+":"+
|
|
||||||
config.ClientCommonCfg.AdminPwd))
|
|
||||||
|
|
||||||
req.Header.Add("Authorization", authStr)
|
|
||||||
resp, err := http.DefaultClient.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
} else {
|
|
||||||
if resp.StatusCode != 200 {
|
|
||||||
return fmt.Errorf("admin api status code [%d]", resp.StatusCode)
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
res := &client.GeneralResponse{}
|
|
||||||
err = json.Unmarshal(body, &res)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unmarshal http response error: %s", strings.TrimSpace(string(body)))
|
|
||||||
} else if res.Code != 0 {
|
|
||||||
return fmt.Errorf(res.Msg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func CmdStatus() error {
|
|
||||||
if config.ClientCommonCfg.AdminPort == 0 {
|
|
||||||
return fmt.Errorf("admin_port shoud be set if you want to get proxy status")
|
|
||||||
}
|
|
||||||
|
|
||||||
req, err := http.NewRequest("GET", "http://"+
|
|
||||||
config.ClientCommonCfg.AdminAddr+":"+fmt.Sprintf("%d", config.ClientCommonCfg.AdminPort)+"/api/status", nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
authStr := "Basic " + base64.StdEncoding.EncodeToString([]byte(config.ClientCommonCfg.AdminUser+":"+
|
|
||||||
config.ClientCommonCfg.AdminPwd))
|
|
||||||
|
|
||||||
req.Header.Add("Authorization", authStr)
|
|
||||||
resp, err := http.DefaultClient.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
} else {
|
|
||||||
if resp.StatusCode != 200 {
|
|
||||||
return fmt.Errorf("admin api status code [%d]", resp.StatusCode)
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
res := &client.StatusResp{}
|
|
||||||
err = json.Unmarshal(body, &res)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unmarshal http response error: %s", strings.TrimSpace(string(body)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("Proxy Status...")
|
|
||||||
if len(res.Tcp) > 0 {
|
|
||||||
fmt.Printf("TCP")
|
|
||||||
tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error")
|
|
||||||
for _, ps := range res.Tcp {
|
|
||||||
tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err)
|
|
||||||
}
|
|
||||||
tbl.Print()
|
|
||||||
fmt.Println("")
|
|
||||||
}
|
|
||||||
if len(res.Udp) > 0 {
|
|
||||||
fmt.Printf("UDP")
|
|
||||||
tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error")
|
|
||||||
for _, ps := range res.Udp {
|
|
||||||
tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err)
|
|
||||||
}
|
|
||||||
tbl.Print()
|
|
||||||
fmt.Println("")
|
|
||||||
}
|
|
||||||
if len(res.Http) > 0 {
|
|
||||||
fmt.Printf("HTTP")
|
|
||||||
tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error")
|
|
||||||
for _, ps := range res.Http {
|
|
||||||
tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err)
|
|
||||||
}
|
|
||||||
tbl.Print()
|
|
||||||
fmt.Println("")
|
|
||||||
}
|
|
||||||
if len(res.Https) > 0 {
|
|
||||||
fmt.Printf("HTTPS")
|
|
||||||
tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error")
|
|
||||||
for _, ps := range res.Https {
|
|
||||||
tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err)
|
|
||||||
}
|
|
||||||
tbl.Print()
|
|
||||||
fmt.Println("")
|
|
||||||
}
|
|
||||||
if len(res.Stcp) > 0 {
|
|
||||||
fmt.Printf("STCP")
|
|
||||||
tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error")
|
|
||||||
for _, ps := range res.Stcp {
|
|
||||||
tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err)
|
|
||||||
}
|
|
||||||
tbl.Print()
|
|
||||||
fmt.Println("")
|
|
||||||
}
|
|
||||||
if len(res.Xtcp) > 0 {
|
|
||||||
fmt.Printf("XTCP")
|
|
||||||
tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error")
|
|
||||||
for _, ps := range res.Xtcp {
|
|
||||||
tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err)
|
|
||||||
}
|
|
||||||
tbl.Print()
|
|
||||||
fmt.Println("")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
96
cmd/frpc/sub/http.go
Normal file
96
cmd/frpc/sub/http.go
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
// Copyright 2018 fatedier, fatedier@gmail.com
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package sub
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/fatedier/frp/models/config"
|
||||||
|
"github.com/fatedier/frp/models/consts"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
httpCmd.PersistentFlags().StringVarP(&serverAddr, "server_addr", "s", "127.0.0.1:7000", "frp server's address")
|
||||||
|
httpCmd.PersistentFlags().StringVarP(&user, "user", "u", "", "user")
|
||||||
|
httpCmd.PersistentFlags().StringVarP(&protocol, "protocol", "p", "tcp", "tcp or kcp")
|
||||||
|
httpCmd.PersistentFlags().StringVarP(&token, "token", "t", "", "auth token")
|
||||||
|
httpCmd.PersistentFlags().StringVarP(&logLevel, "log_level", "", "info", "log level")
|
||||||
|
httpCmd.PersistentFlags().StringVarP(&logFile, "log_file", "", "console", "console or file path")
|
||||||
|
httpCmd.PersistentFlags().IntVarP(&logMaxDays, "log_max_days", "", 3, "log file reversed days")
|
||||||
|
|
||||||
|
httpCmd.PersistentFlags().StringVarP(&proxyName, "proxy_name", "n", "", "proxy name")
|
||||||
|
httpCmd.PersistentFlags().StringVarP(&localIp, "local_ip", "i", "127.0.0.1", "local ip")
|
||||||
|
httpCmd.PersistentFlags().IntVarP(&localPort, "local_port", "l", 0, "local port")
|
||||||
|
httpCmd.PersistentFlags().StringVarP(&customDomains, "custom_domain", "d", "", "custom domain")
|
||||||
|
httpCmd.PersistentFlags().StringVarP(&subDomain, "sd", "", "", "sub domain")
|
||||||
|
httpCmd.PersistentFlags().StringVarP(&locations, "locations", "", "", "locations")
|
||||||
|
httpCmd.PersistentFlags().StringVarP(&httpUser, "http_user", "", "admin", "http auth user")
|
||||||
|
httpCmd.PersistentFlags().StringVarP(&httpPwd, "http_pwd", "", "admin", "http auth password")
|
||||||
|
httpCmd.PersistentFlags().StringVarP(&hostHeaderRewrite, "host_header_rewrite", "", "", "host header rewrite")
|
||||||
|
httpCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption")
|
||||||
|
httpCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression")
|
||||||
|
|
||||||
|
rootCmd.AddCommand(httpCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
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, "")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg := &config.HttpProxyConf{}
|
||||||
|
var prefix string
|
||||||
|
if user != "" {
|
||||||
|
prefix = user + "."
|
||||||
|
}
|
||||||
|
cfg.ProxyName = prefix + proxyName
|
||||||
|
cfg.ProxyType = consts.HttpProxy
|
||||||
|
cfg.LocalIp = localIp
|
||||||
|
cfg.LocalPort = localPort
|
||||||
|
cfg.CustomDomains = strings.Split(customDomains, ",")
|
||||||
|
cfg.SubDomain = subDomain
|
||||||
|
cfg.Locations = strings.Split(locations, ",")
|
||||||
|
cfg.HttpUser = httpUser
|
||||||
|
cfg.HttpPwd = httpPwd
|
||||||
|
cfg.HostHeaderRewrite = hostHeaderRewrite
|
||||||
|
cfg.UseEncryption = useEncryption
|
||||||
|
cfg.UseCompression = useCompression
|
||||||
|
|
||||||
|
err = cfg.CheckForCli()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
proxyConfs := map[string]config.ProxyConf{
|
||||||
|
cfg.ProxyName: cfg,
|
||||||
|
}
|
||||||
|
err = startService(proxyConfs, nil)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
88
cmd/frpc/sub/https.go
Normal file
88
cmd/frpc/sub/https.go
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
// Copyright 2018 fatedier, fatedier@gmail.com
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package sub
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/fatedier/frp/models/config"
|
||||||
|
"github.com/fatedier/frp/models/consts"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
httpsCmd.PersistentFlags().StringVarP(&serverAddr, "server_addr", "s", "127.0.0.1:7000", "frp server's address")
|
||||||
|
httpsCmd.PersistentFlags().StringVarP(&user, "user", "u", "", "user")
|
||||||
|
httpsCmd.PersistentFlags().StringVarP(&protocol, "protocol", "p", "tcp", "tcp or kcp")
|
||||||
|
httpsCmd.PersistentFlags().StringVarP(&token, "token", "t", "", "auth token")
|
||||||
|
httpsCmd.PersistentFlags().StringVarP(&logLevel, "log_level", "", "info", "log level")
|
||||||
|
httpsCmd.PersistentFlags().StringVarP(&logFile, "log_file", "", "console", "console or file path")
|
||||||
|
httpsCmd.PersistentFlags().IntVarP(&logMaxDays, "log_max_days", "", 3, "log file reversed days")
|
||||||
|
|
||||||
|
httpsCmd.PersistentFlags().StringVarP(&proxyName, "proxy_name", "n", "", "proxy name")
|
||||||
|
httpsCmd.PersistentFlags().StringVarP(&localIp, "local_ip", "i", "127.0.0.1", "local ip")
|
||||||
|
httpsCmd.PersistentFlags().IntVarP(&localPort, "local_port", "l", 0, "local port")
|
||||||
|
httpsCmd.PersistentFlags().StringVarP(&customDomains, "custom_domain", "d", "", "custom domain")
|
||||||
|
httpsCmd.PersistentFlags().StringVarP(&subDomain, "sd", "", "", "sub domain")
|
||||||
|
httpsCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption")
|
||||||
|
httpsCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression")
|
||||||
|
|
||||||
|
rootCmd.AddCommand(httpsCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
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, "")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg := &config.HttpsProxyConf{}
|
||||||
|
var prefix string
|
||||||
|
if user != "" {
|
||||||
|
prefix = user + "."
|
||||||
|
}
|
||||||
|
cfg.ProxyName = prefix + proxyName
|
||||||
|
cfg.ProxyType = consts.HttpsProxy
|
||||||
|
cfg.LocalIp = localIp
|
||||||
|
cfg.LocalPort = localPort
|
||||||
|
cfg.CustomDomains = strings.Split(customDomains, ",")
|
||||||
|
cfg.SubDomain = subDomain
|
||||||
|
cfg.UseEncryption = useEncryption
|
||||||
|
cfg.UseCompression = useCompression
|
||||||
|
|
||||||
|
err = cfg.CheckForCli()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
proxyConfs := map[string]config.ProxyConf{
|
||||||
|
cfg.ProxyName: cfg,
|
||||||
|
}
|
||||||
|
err = startService(proxyConfs, nil)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
92
cmd/frpc/sub/reload.go
Normal file
92
cmd/frpc/sub/reload.go
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
// Copyright 2018 fatedier, fatedier@gmail.com
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package sub
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/fatedier/frp/client"
|
||||||
|
"github.com/fatedier/frp/g"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.AddCommand(reloadCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
var reloadCmd = &cobra.Command{
|
||||||
|
Use: "reload",
|
||||||
|
Short: "Hot-Reload frpc configuration",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
err := parseClientCommonCfg(CfgFileTypeIni, cfgFile)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = reload()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("frpc reload error: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
fmt.Printf("reload success\n")
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func reload() error {
|
||||||
|
if g.GlbClientCfg.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)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
authStr := "Basic " + base64.StdEncoding.EncodeToString([]byte(g.GlbClientCfg.AdminUser+":"+
|
||||||
|
g.GlbClientCfg.AdminPwd))
|
||||||
|
|
||||||
|
req.Header.Add("Authorization", authStr)
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
return fmt.Errorf("admin api status code [%d]", resp.StatusCode)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
res := &client.GeneralResponse{}
|
||||||
|
err = json.Unmarshal(body, &res)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unmarshal http response error: %s", strings.TrimSpace(string(body)))
|
||||||
|
} else if res.Code != 0 {
|
||||||
|
return fmt.Errorf(res.Msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
200
cmd/frpc/sub/root.go
Normal file
200
cmd/frpc/sub/root.go
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
// Copyright 2018 fatedier, fatedier@gmail.com
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package sub
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
ini "github.com/vaughan0/go-ini"
|
||||||
|
|
||||||
|
"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"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
CfgFileTypeIni = iota
|
||||||
|
CfgFileTypeCmd
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
cfgFile string
|
||||||
|
showVersion bool
|
||||||
|
|
||||||
|
serverAddr string
|
||||||
|
user string
|
||||||
|
protocol string
|
||||||
|
token string
|
||||||
|
logLevel string
|
||||||
|
logFile string
|
||||||
|
logMaxDays int
|
||||||
|
|
||||||
|
proxyName string
|
||||||
|
localIp string
|
||||||
|
localPort int
|
||||||
|
remotePort int
|
||||||
|
useEncryption bool
|
||||||
|
useCompression bool
|
||||||
|
customDomains string
|
||||||
|
subDomain string
|
||||||
|
httpUser string
|
||||||
|
httpPwd string
|
||||||
|
locations string
|
||||||
|
hostHeaderRewrite string
|
||||||
|
role string
|
||||||
|
sk string
|
||||||
|
serverName string
|
||||||
|
bindAddr string
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.PersistentFlags().StringVarP(&cfgFile, "", "c", "./frpc.ini", "config file of frpc")
|
||||||
|
rootCmd.PersistentFlags().BoolVarP(&showVersion, "version", "v", false, "version of frpc")
|
||||||
|
}
|
||||||
|
|
||||||
|
var rootCmd = &cobra.Command{
|
||||||
|
Use: "frpc",
|
||||||
|
Short: "frpc is the client of frp (https://github.com/fatedier/frp)",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
if showVersion {
|
||||||
|
fmt.Println(version.Full())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not show command usage here.
|
||||||
|
err := runClient(cfgFile)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func Execute() {
|
||||||
|
if err := rootCmd.Execute(); err != nil {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleSignal(svr *client.Service) {
|
||||||
|
ch := make(chan os.Signal)
|
||||||
|
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
|
||||||
|
<-ch
|
||||||
|
svr.Close()
|
||||||
|
time.Sleep(250 * time.Millisecond)
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseClientCommonCfg(fileType int, filePath string) (err error) {
|
||||||
|
if fileType == CfgFileTypeIni {
|
||||||
|
err = parseClientCommonCfgFromIni(filePath)
|
||||||
|
} else if fileType == CfgFileTypeCmd {
|
||||||
|
err = parseClientCommonCfgFromCmd()
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
g.GlbClientCfg.CfgFile = cfgFile
|
||||||
|
|
||||||
|
err = g.GlbClientCfg.ClientCommonConf.Check()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseClientCommonCfgFromIni(filePath string) (err error) {
|
||||||
|
b, err := ioutil.ReadFile(filePath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
content := string(b)
|
||||||
|
|
||||||
|
cfg, err := config.UnmarshalClientConfFromIni(&g.GlbClientCfg.ClientCommonConf, content)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
g.GlbClientCfg.ClientCommonConf = *cfg
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseClientCommonCfgFromCmd() (err error) {
|
||||||
|
strs := strings.Split(serverAddr, ":")
|
||||||
|
if len(strs) < 2 {
|
||||||
|
err = fmt.Errorf("invalid server_addr")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if strs[0] != "" {
|
||||||
|
g.GlbClientCfg.ServerAddr = strs[0]
|
||||||
|
}
|
||||||
|
g.GlbClientCfg.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)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func runClient(cfgFilePath string) (err error) {
|
||||||
|
err = parseClientCommonCfg(CfgFileTypeIni, cfgFilePath)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
conf, err := ini.LoadFile(cfgFilePath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
pxyCfgs, visitorCfgs, err := config.LoadProxyConfFromIni(g.GlbClientCfg.User, conf, g.GlbClientCfg.Start)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = startService(pxyCfgs, visitorCfgs)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func startService(pxyCfgs map[string]config.ProxyConf, visitorCfgs map[string]config.ProxyConf) (err error) {
|
||||||
|
log.InitLog(g.GlbClientCfg.LogWay, g.GlbClientCfg.LogFile, g.GlbClientCfg.LogLevel, g.GlbClientCfg.LogMaxDays)
|
||||||
|
svr := client.NewService(pxyCfgs, visitorCfgs)
|
||||||
|
|
||||||
|
// Capture the exit signal if we use kcp.
|
||||||
|
if g.GlbClientCfg.Protocol == "kcp" {
|
||||||
|
go handleSignal(svr)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = svr.Run()
|
||||||
|
return
|
||||||
|
}
|
146
cmd/frpc/sub/status.go
Normal file
146
cmd/frpc/sub/status.go
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
// Copyright 2018 fatedier, fatedier@gmail.com
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package sub
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/rodaine/table"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/fatedier/frp/client"
|
||||||
|
"github.com/fatedier/frp/g"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.AddCommand(statusCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
var statusCmd = &cobra.Command{
|
||||||
|
Use: "status",
|
||||||
|
Short: "Overview of all proxies status",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
err := parseClientCommonCfg(CfgFileTypeIni, cfgFile)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = status()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("frpc get status error: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func status() error {
|
||||||
|
if g.GlbClientCfg.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)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
authStr := "Basic " + base64.StdEncoding.EncodeToString([]byte(g.GlbClientCfg.AdminUser+":"+
|
||||||
|
g.GlbClientCfg.AdminPwd))
|
||||||
|
|
||||||
|
req.Header.Add("Authorization", authStr)
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
return fmt.Errorf("admin api status code [%d]", resp.StatusCode)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
res := &client.StatusResp{}
|
||||||
|
err = json.Unmarshal(body, &res)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unmarshal http response error: %s", strings.TrimSpace(string(body)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Proxy Status...")
|
||||||
|
if len(res.Tcp) > 0 {
|
||||||
|
fmt.Printf("TCP")
|
||||||
|
tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error")
|
||||||
|
for _, ps := range res.Tcp {
|
||||||
|
tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err)
|
||||||
|
}
|
||||||
|
tbl.Print()
|
||||||
|
fmt.Println("")
|
||||||
|
}
|
||||||
|
if len(res.Udp) > 0 {
|
||||||
|
fmt.Printf("UDP")
|
||||||
|
tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error")
|
||||||
|
for _, ps := range res.Udp {
|
||||||
|
tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err)
|
||||||
|
}
|
||||||
|
tbl.Print()
|
||||||
|
fmt.Println("")
|
||||||
|
}
|
||||||
|
if len(res.Http) > 0 {
|
||||||
|
fmt.Printf("HTTP")
|
||||||
|
tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error")
|
||||||
|
for _, ps := range res.Http {
|
||||||
|
tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err)
|
||||||
|
}
|
||||||
|
tbl.Print()
|
||||||
|
fmt.Println("")
|
||||||
|
}
|
||||||
|
if len(res.Https) > 0 {
|
||||||
|
fmt.Printf("HTTPS")
|
||||||
|
tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error")
|
||||||
|
for _, ps := range res.Https {
|
||||||
|
tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err)
|
||||||
|
}
|
||||||
|
tbl.Print()
|
||||||
|
fmt.Println("")
|
||||||
|
}
|
||||||
|
if len(res.Stcp) > 0 {
|
||||||
|
fmt.Printf("STCP")
|
||||||
|
tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error")
|
||||||
|
for _, ps := range res.Stcp {
|
||||||
|
tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err)
|
||||||
|
}
|
||||||
|
tbl.Print()
|
||||||
|
fmt.Println("")
|
||||||
|
}
|
||||||
|
if len(res.Xtcp) > 0 {
|
||||||
|
fmt.Printf("XTCP")
|
||||||
|
tbl := table.New("Name", "Status", "LocalAddr", "Plugin", "RemoteAddr", "Error")
|
||||||
|
for _, ps := range res.Xtcp {
|
||||||
|
tbl.AddRow(ps.Name, ps.Status, ps.LocalAddr, ps.Plugin, ps.RemoteAddr, ps.Err)
|
||||||
|
}
|
||||||
|
tbl.Print()
|
||||||
|
fmt.Println("")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
102
cmd/frpc/sub/stcp.go
Normal file
102
cmd/frpc/sub/stcp.go
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
// Copyright 2018 fatedier, fatedier@gmail.com
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package sub
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/fatedier/frp/models/config"
|
||||||
|
"github.com/fatedier/frp/models/consts"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
stcpCmd.PersistentFlags().StringVarP(&serverAddr, "server_addr", "s", "127.0.0.1:7000", "frp server's address")
|
||||||
|
stcpCmd.PersistentFlags().StringVarP(&user, "user", "u", "", "user")
|
||||||
|
stcpCmd.PersistentFlags().StringVarP(&protocol, "protocol", "p", "tcp", "tcp or kcp")
|
||||||
|
stcpCmd.PersistentFlags().StringVarP(&token, "token", "t", "", "auth token")
|
||||||
|
stcpCmd.PersistentFlags().StringVarP(&logLevel, "log_level", "", "info", "log level")
|
||||||
|
stcpCmd.PersistentFlags().StringVarP(&logFile, "log_file", "", "console", "console or file path")
|
||||||
|
stcpCmd.PersistentFlags().IntVarP(&logMaxDays, "log_max_days", "", 3, "log file reversed days")
|
||||||
|
|
||||||
|
stcpCmd.PersistentFlags().StringVarP(&proxyName, "proxy_name", "n", "", "proxy name")
|
||||||
|
stcpCmd.PersistentFlags().StringVarP(&role, "role", "", "server", "role")
|
||||||
|
stcpCmd.PersistentFlags().StringVarP(&sk, "sk", "", "", "secret key")
|
||||||
|
stcpCmd.PersistentFlags().StringVarP(&serverName, "server_name", "", "", "server name")
|
||||||
|
stcpCmd.PersistentFlags().StringVarP(&localIp, "local_ip", "i", "127.0.0.1", "local ip")
|
||||||
|
stcpCmd.PersistentFlags().IntVarP(&localPort, "local_port", "l", 0, "local port")
|
||||||
|
stcpCmd.PersistentFlags().StringVarP(&bindAddr, "bind_addr", "", "", "bind addr")
|
||||||
|
stcpCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption")
|
||||||
|
stcpCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression")
|
||||||
|
|
||||||
|
rootCmd.AddCommand(stcpCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
var stcpCmd = &cobra.Command{
|
||||||
|
Use: "http",
|
||||||
|
Short: "Run frpc with a single http proxy",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
err := parseClientCommonCfg(CfgFileTypeCmd, "")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg := &config.StcpProxyConf{}
|
||||||
|
var prefix string
|
||||||
|
if user != "" {
|
||||||
|
prefix = user + "."
|
||||||
|
}
|
||||||
|
cfg.ProxyName = prefix + proxyName
|
||||||
|
cfg.ProxyType = consts.StcpProxy
|
||||||
|
cfg.Role = role
|
||||||
|
cfg.Sk = sk
|
||||||
|
cfg.ServerName = serverName
|
||||||
|
cfg.LocalIp = localIp
|
||||||
|
cfg.LocalPort = localPort
|
||||||
|
cfg.BindAddr = bindAddr
|
||||||
|
cfg.UseEncryption = useEncryption
|
||||||
|
cfg.UseCompression = useCompression
|
||||||
|
|
||||||
|
err = cfg.CheckForCli()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfg.Role == "server" {
|
||||||
|
proxyConfs := map[string]config.ProxyConf{
|
||||||
|
cfg.ProxyName: cfg,
|
||||||
|
}
|
||||||
|
err = startService(proxyConfs, nil)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
visitorConfs := map[string]config.ProxyConf{
|
||||||
|
cfg.ProxyName: cfg,
|
||||||
|
}
|
||||||
|
err = startService(nil, visitorConfs)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
85
cmd/frpc/sub/tcp.go
Normal file
85
cmd/frpc/sub/tcp.go
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
// Copyright 2018 fatedier, fatedier@gmail.com
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package sub
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/fatedier/frp/models/config"
|
||||||
|
"github.com/fatedier/frp/models/consts"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
tcpCmd.PersistentFlags().StringVarP(&serverAddr, "server_addr", "s", "127.0.0.1:7000", "frp server's address")
|
||||||
|
tcpCmd.PersistentFlags().StringVarP(&user, "user", "u", "", "user")
|
||||||
|
tcpCmd.PersistentFlags().StringVarP(&protocol, "protocol", "p", "tcp", "tcp or kcp")
|
||||||
|
tcpCmd.PersistentFlags().StringVarP(&token, "token", "t", "", "auth token")
|
||||||
|
tcpCmd.PersistentFlags().StringVarP(&logLevel, "log_level", "", "info", "log level")
|
||||||
|
tcpCmd.PersistentFlags().StringVarP(&logFile, "log_file", "", "console", "console or file path")
|
||||||
|
tcpCmd.PersistentFlags().IntVarP(&logMaxDays, "log_max_days", "", 3, "log file reversed days")
|
||||||
|
|
||||||
|
tcpCmd.PersistentFlags().StringVarP(&proxyName, "proxy_name", "n", "", "proxy name")
|
||||||
|
tcpCmd.PersistentFlags().StringVarP(&localIp, "local_ip", "i", "127.0.0.1", "local ip")
|
||||||
|
tcpCmd.PersistentFlags().IntVarP(&localPort, "local_port", "l", 0, "local port")
|
||||||
|
tcpCmd.PersistentFlags().IntVarP(&remotePort, "remote_port", "r", 0, "remote port")
|
||||||
|
tcpCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption")
|
||||||
|
tcpCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression")
|
||||||
|
|
||||||
|
rootCmd.AddCommand(tcpCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
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, "")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg := &config.TcpProxyConf{}
|
||||||
|
var prefix string
|
||||||
|
if user != "" {
|
||||||
|
prefix = user + "."
|
||||||
|
}
|
||||||
|
cfg.ProxyName = prefix + proxyName
|
||||||
|
cfg.ProxyType = consts.TcpProxy
|
||||||
|
cfg.LocalIp = localIp
|
||||||
|
cfg.LocalPort = localPort
|
||||||
|
cfg.RemotePort = remotePort
|
||||||
|
cfg.UseEncryption = useEncryption
|
||||||
|
cfg.UseCompression = useCompression
|
||||||
|
|
||||||
|
err = cfg.CheckForCli()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
proxyConfs := map[string]config.ProxyConf{
|
||||||
|
cfg.ProxyName: cfg,
|
||||||
|
}
|
||||||
|
err = startService(proxyConfs, nil)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
85
cmd/frpc/sub/udp.go
Normal file
85
cmd/frpc/sub/udp.go
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
// Copyright 2018 fatedier, fatedier@gmail.com
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package sub
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/fatedier/frp/models/config"
|
||||||
|
"github.com/fatedier/frp/models/consts"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
udpCmd.PersistentFlags().StringVarP(&serverAddr, "server_addr", "s", "127.0.0.1:7000", "frp server's address")
|
||||||
|
udpCmd.PersistentFlags().StringVarP(&user, "user", "u", "", "user")
|
||||||
|
udpCmd.PersistentFlags().StringVarP(&protocol, "protocol", "p", "tcp", "tcp or kcp")
|
||||||
|
udpCmd.PersistentFlags().StringVarP(&token, "token", "t", "", "auth token")
|
||||||
|
udpCmd.PersistentFlags().StringVarP(&logLevel, "log_level", "", "info", "log level")
|
||||||
|
udpCmd.PersistentFlags().StringVarP(&logFile, "log_file", "", "console", "console or file path")
|
||||||
|
udpCmd.PersistentFlags().IntVarP(&logMaxDays, "log_max_days", "", 3, "log file reversed days")
|
||||||
|
|
||||||
|
udpCmd.PersistentFlags().StringVarP(&proxyName, "proxy_name", "n", "", "proxy name")
|
||||||
|
udpCmd.PersistentFlags().StringVarP(&localIp, "local_ip", "i", "127.0.0.1", "local ip")
|
||||||
|
udpCmd.PersistentFlags().IntVarP(&localPort, "local_port", "l", 0, "local port")
|
||||||
|
udpCmd.PersistentFlags().IntVarP(&remotePort, "remote_port", "r", 0, "remote port")
|
||||||
|
udpCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption")
|
||||||
|
udpCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression")
|
||||||
|
|
||||||
|
rootCmd.AddCommand(udpCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
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, "")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg := &config.UdpProxyConf{}
|
||||||
|
var prefix string
|
||||||
|
if user != "" {
|
||||||
|
prefix = user + "."
|
||||||
|
}
|
||||||
|
cfg.ProxyName = prefix + proxyName
|
||||||
|
cfg.ProxyType = consts.UdpProxy
|
||||||
|
cfg.LocalIp = localIp
|
||||||
|
cfg.LocalPort = localPort
|
||||||
|
cfg.RemotePort = remotePort
|
||||||
|
cfg.UseEncryption = useEncryption
|
||||||
|
cfg.UseCompression = useCompression
|
||||||
|
|
||||||
|
err = cfg.CheckForCli()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
proxyConfs := map[string]config.ProxyConf{
|
||||||
|
cfg.ProxyName: cfg,
|
||||||
|
}
|
||||||
|
err = startService(proxyConfs, nil)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
102
cmd/frpc/sub/xtcp.go
Normal file
102
cmd/frpc/sub/xtcp.go
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
// Copyright 2018 fatedier, fatedier@gmail.com
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package sub
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/fatedier/frp/models/config"
|
||||||
|
"github.com/fatedier/frp/models/consts"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
xtcpCmd.PersistentFlags().StringVarP(&serverAddr, "server_addr", "s", "127.0.0.1:7000", "frp server's address")
|
||||||
|
xtcpCmd.PersistentFlags().StringVarP(&user, "user", "u", "", "user")
|
||||||
|
xtcpCmd.PersistentFlags().StringVarP(&protocol, "protocol", "p", "tcp", "tcp or kcp")
|
||||||
|
xtcpCmd.PersistentFlags().StringVarP(&token, "token", "t", "", "auth token")
|
||||||
|
xtcpCmd.PersistentFlags().StringVarP(&logLevel, "log_level", "", "info", "log level")
|
||||||
|
xtcpCmd.PersistentFlags().StringVarP(&logFile, "log_file", "", "console", "console or file path")
|
||||||
|
xtcpCmd.PersistentFlags().IntVarP(&logMaxDays, "log_max_days", "", 3, "log file reversed days")
|
||||||
|
|
||||||
|
xtcpCmd.PersistentFlags().StringVarP(&proxyName, "proxy_name", "n", "", "proxy name")
|
||||||
|
xtcpCmd.PersistentFlags().StringVarP(&role, "role", "", "server", "role")
|
||||||
|
xtcpCmd.PersistentFlags().StringVarP(&sk, "sk", "", "", "secret key")
|
||||||
|
xtcpCmd.PersistentFlags().StringVarP(&serverName, "server_name", "", "", "server name")
|
||||||
|
xtcpCmd.PersistentFlags().StringVarP(&localIp, "local_ip", "i", "127.0.0.1", "local ip")
|
||||||
|
xtcpCmd.PersistentFlags().IntVarP(&localPort, "local_port", "l", 0, "local port")
|
||||||
|
xtcpCmd.PersistentFlags().StringVarP(&bindAddr, "bind_addr", "", "", "bind addr")
|
||||||
|
xtcpCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption")
|
||||||
|
xtcpCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression")
|
||||||
|
|
||||||
|
rootCmd.AddCommand(xtcpCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
var xtcpCmd = &cobra.Command{
|
||||||
|
Use: "http",
|
||||||
|
Short: "Run frpc with a single http proxy",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
err := parseClientCommonCfg(CfgFileTypeCmd, "")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg := &config.XtcpProxyConf{}
|
||||||
|
var prefix string
|
||||||
|
if user != "" {
|
||||||
|
prefix = user + "."
|
||||||
|
}
|
||||||
|
cfg.ProxyName = prefix + proxyName
|
||||||
|
cfg.ProxyType = consts.XtcpProxy
|
||||||
|
cfg.Role = role
|
||||||
|
cfg.Sk = sk
|
||||||
|
cfg.ServerName = serverName
|
||||||
|
cfg.LocalIp = localIp
|
||||||
|
cfg.LocalPort = localPort
|
||||||
|
cfg.BindAddr = bindAddr
|
||||||
|
cfg.UseEncryption = useEncryption
|
||||||
|
cfg.UseCompression = useCompression
|
||||||
|
|
||||||
|
err = cfg.CheckForCli()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfg.Role == "server" {
|
||||||
|
proxyConfs := map[string]config.ProxyConf{
|
||||||
|
cfg.ProxyName: cfg,
|
||||||
|
}
|
||||||
|
err = startService(proxyConfs, nil)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
visitorConfs := map[string]config.ProxyConf{
|
||||||
|
cfg.ProxyName: cfg,
|
||||||
|
}
|
||||||
|
err = startService(nil, visitorConfs)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
103
cmd/frps/main.go
103
cmd/frps/main.go
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2016 fatedier, fatedier@gmail.com
|
// Copyright 2018 fatedier, fatedier@gmail.com
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
@ -14,105 +14,6 @@
|
|||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
docopt "github.com/docopt/docopt-go"
|
|
||||||
ini "github.com/vaughan0/go-ini"
|
|
||||||
|
|
||||||
"github.com/fatedier/frp/models/config"
|
|
||||||
"github.com/fatedier/frp/server"
|
|
||||||
"github.com/fatedier/frp/utils/log"
|
|
||||||
"github.com/fatedier/frp/utils/version"
|
|
||||||
)
|
|
||||||
|
|
||||||
var usage string = `frps is the server of frp
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
frps [-c config_file] [-L log_file] [--log-level=<log_level>] [--addr=<bind_addr>]
|
|
||||||
frps -h | --help
|
|
||||||
frps -v | --version
|
|
||||||
|
|
||||||
Options:
|
|
||||||
-c config_file set config file
|
|
||||||
-L log_file set output log file, including console
|
|
||||||
--log-level=<log_level> set log level: debug, info, warn, error
|
|
||||||
--addr=<bind_addr> listen addr for client, example: 0.0.0.0:7000
|
|
||||||
-h --help show this screen
|
|
||||||
-v --version show version
|
|
||||||
`
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var err error
|
Execute()
|
||||||
confFile := "./frps.ini"
|
|
||||||
// the configures parsed from file will be replaced by those from command line if exist
|
|
||||||
args, err := docopt.Parse(usage, nil, true, version.Full(), false)
|
|
||||||
|
|
||||||
if args["-c"] != nil {
|
|
||||||
confFile = args["-c"].(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
conf, err := ini.LoadFile(confFile)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
config.ServerCommonCfg, err = config.LoadServerCommonConf(conf)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
if args["-L"] != nil {
|
|
||||||
if args["-L"].(string) == "console" {
|
|
||||||
config.ServerCommonCfg.LogWay = "console"
|
|
||||||
} else {
|
|
||||||
config.ServerCommonCfg.LogWay = "file"
|
|
||||||
config.ServerCommonCfg.LogFile = args["-L"].(string)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if args["--log-level"] != nil {
|
|
||||||
config.ServerCommonCfg.LogLevel = args["--log-level"].(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
if args["--addr"] != nil {
|
|
||||||
addr := strings.Split(args["--addr"].(string), ":")
|
|
||||||
if len(addr) != 2 {
|
|
||||||
fmt.Println("--addr format error: example 0.0.0.0:7000")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
bindPort, err := strconv.ParseInt(addr[1], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("--addr format error, example 0.0.0.0:7000")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
config.ServerCommonCfg.BindAddr = addr[0]
|
|
||||||
config.ServerCommonCfg.BindPort = int(bindPort)
|
|
||||||
}
|
|
||||||
|
|
||||||
if args["-v"] != nil {
|
|
||||||
if args["-v"].(bool) {
|
|
||||||
fmt.Println(version.Full())
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log.InitLog(config.ServerCommonCfg.LogWay, config.ServerCommonCfg.LogFile,
|
|
||||||
config.ServerCommonCfg.LogLevel, config.ServerCommonCfg.LogMaxDays)
|
|
||||||
|
|
||||||
svr, err := server.NewService()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
log.Info("Start frps success")
|
|
||||||
if config.ServerCommonCfg.PrivilegeMode == true {
|
|
||||||
log.Info("PrivilegeMode is enabled, you should pay more attention to security issues")
|
|
||||||
}
|
|
||||||
server.ServerService = svr
|
|
||||||
svr.Run()
|
|
||||||
}
|
}
|
||||||
|
174
cmd/frps/root.go
Normal file
174
cmd/frps/root.go
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/fatedier/frp/g"
|
||||||
|
"github.com/fatedier/frp/models/config"
|
||||||
|
"github.com/fatedier/frp/server"
|
||||||
|
"github.com/fatedier/frp/utils/log"
|
||||||
|
"github.com/fatedier/frp/utils/version"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
CfgFileTypeIni = iota
|
||||||
|
CfgFileTypeCmd
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
cfgFile string
|
||||||
|
showVersion bool
|
||||||
|
|
||||||
|
bindAddr string
|
||||||
|
bindPort int
|
||||||
|
bindUdpPort int
|
||||||
|
kcpBindPort int
|
||||||
|
proxyBindAddr string
|
||||||
|
vhostHttpPort int
|
||||||
|
vhostHttpsPort int
|
||||||
|
dashboardAddr string
|
||||||
|
dashboardPort int
|
||||||
|
dashboardUser string
|
||||||
|
dashboardPwd string
|
||||||
|
assetsDir string
|
||||||
|
logFile string
|
||||||
|
logWay string
|
||||||
|
logLevel string
|
||||||
|
logMaxDays int64
|
||||||
|
token string
|
||||||
|
authTimeout int64
|
||||||
|
subDomainHost string
|
||||||
|
tcpMux bool
|
||||||
|
allowPorts string
|
||||||
|
maxPoolCount int64
|
||||||
|
maxPortsPerClient int64
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.PersistentFlags().StringVarP(&cfgFile, "", "c", "", "config file of frps")
|
||||||
|
rootCmd.PersistentFlags().BoolVarP(&showVersion, "version", "v", false, "version of frpc")
|
||||||
|
|
||||||
|
rootCmd.PersistentFlags().StringVarP(&bindAddr, "bind_addr", "h", "0.0.0.0", "bind address")
|
||||||
|
rootCmd.PersistentFlags().IntVarP(&bindPort, "bind_port", "p", 7000, "bind port")
|
||||||
|
rootCmd.PersistentFlags().IntVarP(&bindUdpPort, "bind_udp_port", "", 0, "bind udp port")
|
||||||
|
rootCmd.PersistentFlags().IntVarP(&kcpBindPort, "kcp_bind_port", "", 0, "kcp bind udp port")
|
||||||
|
rootCmd.PersistentFlags().StringVarP(&proxyBindAddr, "proxy_bind_addr", "", "0.0.0.0", "proxy bind address")
|
||||||
|
rootCmd.PersistentFlags().IntVarP(&vhostHttpPort, "vhost_http_port", "", 0, "vhost http port")
|
||||||
|
rootCmd.PersistentFlags().IntVarP(&vhostHttpsPort, "vhost_https_port", "", 0, "vhost https port")
|
||||||
|
rootCmd.PersistentFlags().StringVarP(&dashboardAddr, "dashboard_addr", "", "0.0.0.0", "dasboard address")
|
||||||
|
rootCmd.PersistentFlags().IntVarP(&dashboardPort, "dashboard_port", "", 0, "dashboard port")
|
||||||
|
rootCmd.PersistentFlags().StringVarP(&dashboardUser, "dashboard_user", "", "admin", "dashboard user")
|
||||||
|
rootCmd.PersistentFlags().StringVarP(&dashboardPwd, "dashboard_pwd", "", "admin", "dashboard password")
|
||||||
|
rootCmd.PersistentFlags().StringVarP(&logFile, "log_file", "", "console", "log file")
|
||||||
|
rootCmd.PersistentFlags().StringVarP(&logWay, "log_way", "", "console", "log way")
|
||||||
|
rootCmd.PersistentFlags().StringVarP(&logLevel, "log_level", "", "info", "log level")
|
||||||
|
rootCmd.PersistentFlags().Int64VarP(&logMaxDays, "log_max_days", "", 3, "log_max_days")
|
||||||
|
rootCmd.PersistentFlags().StringVarP(&token, "token", "", "", "auth token")
|
||||||
|
rootCmd.PersistentFlags().Int64VarP(&authTimeout, "auth_timeout", "", 900, "auth timeout")
|
||||||
|
rootCmd.PersistentFlags().StringVarP(&subDomainHost, "subdomain_host", "", "", "subdomain host")
|
||||||
|
rootCmd.PersistentFlags().Int64VarP(&maxPortsPerClient, "max_ports_per_client", "", 0, "max ports per client")
|
||||||
|
}
|
||||||
|
|
||||||
|
var rootCmd = &cobra.Command{
|
||||||
|
Use: "frps",
|
||||||
|
Short: "frps is the server of frp (https://github.com/fatedier/frp)",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
if showVersion {
|
||||||
|
fmt.Println(version.Full())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfgFile != "" {
|
||||||
|
parseServerCommonCfg(CfgFileTypeIni, cfgFile)
|
||||||
|
} else {
|
||||||
|
parseServerCommonCfg(CfgFileTypeCmd, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
err := runServer()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func Execute() {
|
||||||
|
if err := rootCmd.Execute(); err != nil {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseServerCommonCfg(fileType int, filePath string) (err error) {
|
||||||
|
if fileType == CfgFileTypeIni {
|
||||||
|
err = parseServerCommonCfgFromIni(filePath)
|
||||||
|
} else if fileType == CfgFileTypeCmd {
|
||||||
|
err = parseServerCommonCfgFromCmd()
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
g.GlbServerCfg.CfgFile = cfgFile
|
||||||
|
|
||||||
|
err = g.GlbServerCfg.ServerCommonConf.Check()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseServerCommonCfgFromIni(filePath string) (err error) {
|
||||||
|
b, err := ioutil.ReadFile(filePath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
content := string(b)
|
||||||
|
|
||||||
|
cfg, err := config.UnmarshalServerConfFromIni(&g.GlbServerCfg.ServerCommonConf, content)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
g.GlbServerCfg.ServerCommonConf = *cfg
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseServerCommonCfgFromCmd() (err error) {
|
||||||
|
g.GlbServerCfg.BindAddr = bindAddr
|
||||||
|
g.GlbServerCfg.BindPort = bindPort
|
||||||
|
g.GlbServerCfg.BindUdpPort = bindUdpPort
|
||||||
|
g.GlbServerCfg.KcpBindPort = kcpBindPort
|
||||||
|
g.GlbServerCfg.ProxyBindAddr = proxyBindAddr
|
||||||
|
g.GlbServerCfg.VhostHttpPort = vhostHttpPort
|
||||||
|
g.GlbServerCfg.VhostHttpsPort = vhostHttpsPort
|
||||||
|
g.GlbServerCfg.DashboardAddr = dashboardAddr
|
||||||
|
g.GlbServerCfg.DashboardPort = dashboardPort
|
||||||
|
g.GlbServerCfg.DashboardUser = dashboardUser
|
||||||
|
g.GlbServerCfg.DashboardPwd = dashboardPwd
|
||||||
|
g.GlbServerCfg.LogFile = logFile
|
||||||
|
g.GlbServerCfg.LogWay = logWay
|
||||||
|
g.GlbServerCfg.LogLevel = logLevel
|
||||||
|
g.GlbServerCfg.LogMaxDays = logMaxDays
|
||||||
|
g.GlbServerCfg.Token = token
|
||||||
|
g.GlbServerCfg.AuthTimeout = authTimeout
|
||||||
|
g.GlbServerCfg.SubDomainHost = subDomainHost
|
||||||
|
g.GlbServerCfg.MaxPortsPerClient = maxPortsPerClient
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func runServer() (err error) {
|
||||||
|
log.InitLog(g.GlbServerCfg.LogWay, g.GlbServerCfg.LogFile, g.GlbServerCfg.LogLevel,
|
||||||
|
g.GlbServerCfg.LogMaxDays)
|
||||||
|
svr, err := server.NewService()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Info("Start frps success")
|
||||||
|
server.ServerService = svr
|
||||||
|
svr.Run()
|
||||||
|
return
|
||||||
|
}
|
@ -7,7 +7,7 @@ server_port = 7000
|
|||||||
|
|
||||||
# if you want to connect frps by http proxy, you can set http_proxy here or in global environment variables
|
# if you want to connect frps by http proxy, you can set http_proxy here or in global environment variables
|
||||||
# it only works when protocol is tcp
|
# it only works when protocol is tcp
|
||||||
# http_proxy = http://user:pwd@192.168.1.128:8080
|
# http_proxy = http://user:passwd@192.168.1.128:8080
|
||||||
|
|
||||||
# console or real logFile path like ./frpc.log
|
# console or real logFile path like ./frpc.log
|
||||||
log_file = ./frpc.log
|
log_file = ./frpc.log
|
||||||
@ -18,13 +18,13 @@ log_level = info
|
|||||||
log_max_days = 3
|
log_max_days = 3
|
||||||
|
|
||||||
# for authentication
|
# for authentication
|
||||||
privilege_token = 12345678
|
token = 12345678
|
||||||
|
|
||||||
# set admin address for control frpc's action by http api such as reload
|
# set admin address for control frpc's action by http api such as reload
|
||||||
admin_addr = 127.0.0.1
|
admin_addr = 127.0.0.1
|
||||||
admin_port = 7400
|
admin_port = 7400
|
||||||
admin_user = admin
|
admin_user = admin
|
||||||
admin_pwd = admin
|
admin_passwd = admin
|
||||||
|
|
||||||
# connections will be established in advance, default value is zero
|
# connections will be established in advance, default value is zero
|
||||||
pool_count = 5
|
pool_count = 5
|
||||||
@ -109,7 +109,7 @@ use_compression = true
|
|||||||
# http username and password are safety certification for http protocol
|
# http username and password are safety certification for http protocol
|
||||||
# if not set, you can access this custom_domains without certification
|
# if not set, you can access this custom_domains without certification
|
||||||
http_user = admin
|
http_user = admin
|
||||||
http_pwd = admin
|
http_passwd = admin
|
||||||
# if domain for frps is frps.com, then you can access [web01] proxy by URL http://test.frps.com
|
# if domain for frps is frps.com, then you can access [web01] proxy by URL http://test.frps.com
|
||||||
subdomain = web01
|
subdomain = web01
|
||||||
custom_domains = web02.yourdomain.com
|
custom_domains = web02.yourdomain.com
|
||||||
|
@ -25,9 +25,9 @@ vhost_https_port = 443
|
|||||||
dashboard_addr = 0.0.0.0
|
dashboard_addr = 0.0.0.0
|
||||||
dashboard_port = 7500
|
dashboard_port = 7500
|
||||||
|
|
||||||
# dashboard user and pwd for basic auth protect, if not set, both default value is admin
|
# dashboard user and passwd for basic auth protect, if not set, both default value is admin
|
||||||
dashboard_user = admin
|
dashboard_user = admin
|
||||||
dashboard_pwd = admin
|
dashboard_passwd = admin
|
||||||
|
|
||||||
# dashboard assets directory(only for debug mode)
|
# dashboard assets directory(only for debug mode)
|
||||||
# assets_dir = ./static
|
# assets_dir = ./static
|
||||||
@ -39,8 +39,8 @@ log_level = info
|
|||||||
|
|
||||||
log_max_days = 3
|
log_max_days = 3
|
||||||
|
|
||||||
# privilege mode is the only supported mode since v0.10.0
|
# auth token
|
||||||
privilege_token = 12345678
|
token = 12345678
|
||||||
|
|
||||||
# heartbeat configure, it's not recommended to modify the default value
|
# heartbeat configure, it's not recommended to modify the default value
|
||||||
# the default value of heartbeat_timeout is 90
|
# the default value of heartbeat_timeout is 90
|
||||||
|
32
g/g.go
Normal file
32
g/g.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package g
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/fatedier/frp/models/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
GlbClientCfg *ClientCfg
|
||||||
|
GlbServerCfg *ServerCfg
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
GlbClientCfg = &ClientCfg{
|
||||||
|
ClientCommonConf: *config.GetDefaultClientConf(),
|
||||||
|
}
|
||||||
|
GlbServerCfg = &ServerCfg{
|
||||||
|
ServerCommonConf: *config.GetDefaultServerConf(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type ClientCfg struct {
|
||||||
|
config.ClientCommonConf
|
||||||
|
|
||||||
|
CfgFile string
|
||||||
|
ServerUdpPort int // this is configured by login response from frps
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServerCfg struct {
|
||||||
|
config.ServerCommonConf
|
||||||
|
|
||||||
|
CfgFile string
|
||||||
|
}
|
@ -23,46 +23,40 @@ import (
|
|||||||
ini "github.com/vaughan0/go-ini"
|
ini "github.com/vaughan0/go-ini"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ClientCommonCfg *ClientCommonConf
|
|
||||||
|
|
||||||
// client common config
|
// client common config
|
||||||
type ClientCommonConf struct {
|
type ClientCommonConf struct {
|
||||||
ConfigFile string
|
ServerAddr string `json:"server_addr"`
|
||||||
ServerAddr string
|
ServerPort int `json:"server_port"`
|
||||||
ServerPort int
|
HttpProxy string `json:"http_proxy"`
|
||||||
ServerUdpPort int // this is specified by login response message from frps
|
LogFile string `json:"log_file"`
|
||||||
HttpProxy string
|
LogWay string `json:"log_way"`
|
||||||
LogFile string
|
LogLevel string `json:"log_level"`
|
||||||
LogWay string
|
LogMaxDays int64 `json:"log_max_days"`
|
||||||
LogLevel string
|
Token string `json:"token"`
|
||||||
LogMaxDays int64
|
AdminAddr string `json:"admin_addr"`
|
||||||
PrivilegeToken string
|
AdminPort int `json:"admin_port"`
|
||||||
AdminAddr string
|
AdminUser string `json:"admin_user"`
|
||||||
AdminPort int
|
AdminPwd string `json:"admin_pwd"`
|
||||||
AdminUser string
|
PoolCount int `json:"pool_count"`
|
||||||
AdminPwd string
|
TcpMux bool `json:"tcp_mux"`
|
||||||
PoolCount int
|
User string `json:"user"`
|
||||||
TcpMux bool
|
LoginFailExit bool `json:"login_fail_exit"`
|
||||||
User string
|
Start map[string]struct{} `json:"start"`
|
||||||
LoginFailExit bool
|
Protocol string `json:"protocol"`
|
||||||
Start map[string]struct{}
|
HeartBeatInterval int64 `json:"heartbeat_interval"`
|
||||||
Protocol string
|
HeartBeatTimeout int64 `json:"heartbeat_timeout"`
|
||||||
HeartBeatInterval int64
|
|
||||||
HeartBeatTimeout int64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetDeaultClientCommonConf() *ClientCommonConf {
|
func GetDefaultClientConf() *ClientCommonConf {
|
||||||
return &ClientCommonConf{
|
return &ClientCommonConf{
|
||||||
ConfigFile: "./frpc.ini",
|
|
||||||
ServerAddr: "0.0.0.0",
|
ServerAddr: "0.0.0.0",
|
||||||
ServerPort: 7000,
|
ServerPort: 7000,
|
||||||
ServerUdpPort: 0,
|
HttpProxy: os.Getenv("http_proxy"),
|
||||||
HttpProxy: "",
|
|
||||||
LogFile: "console",
|
LogFile: "console",
|
||||||
LogWay: "console",
|
LogWay: "console",
|
||||||
LogLevel: "info",
|
LogLevel: "info",
|
||||||
LogMaxDays: 3,
|
LogMaxDays: 3,
|
||||||
PrivilegeToken: "",
|
Token: "",
|
||||||
AdminAddr: "127.0.0.1",
|
AdminAddr: "127.0.0.1",
|
||||||
AdminPort: 0,
|
AdminPort: 0,
|
||||||
AdminUser: "",
|
AdminUser: "",
|
||||||
@ -78,21 +72,28 @@ func GetDeaultClientCommonConf() *ClientCommonConf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadClientCommonConf(conf ini.File) (cfg *ClientCommonConf, err error) {
|
func UnmarshalClientConfFromIni(defaultCfg *ClientCommonConf, content string) (cfg *ClientCommonConf, err error) {
|
||||||
|
cfg = defaultCfg
|
||||||
|
if cfg == nil {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
tmpStr string
|
tmpStr string
|
||||||
ok bool
|
ok bool
|
||||||
v int64
|
v int64
|
||||||
)
|
)
|
||||||
cfg = GetDeaultClientCommonConf()
|
if tmpStr, ok = conf.Get("common", "server_addr"); ok {
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "server_addr")
|
|
||||||
if ok {
|
|
||||||
cfg.ServerAddr = tmpStr
|
cfg.ServerAddr = tmpStr
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "server_port")
|
if tmpStr, ok = conf.Get("common", "server_port"); ok {
|
||||||
if ok {
|
|
||||||
v, err = strconv.ParseInt(tmpStr, 10, 64)
|
v, err = strconv.ParseInt(tmpStr, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("Parse conf error: invalid server_port")
|
err = fmt.Errorf("Parse conf error: invalid server_port")
|
||||||
@ -101,16 +102,11 @@ func LoadClientCommonConf(conf ini.File) (cfg *ClientCommonConf, err error) {
|
|||||||
cfg.ServerPort = int(v)
|
cfg.ServerPort = int(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "http_proxy")
|
if tmpStr, ok = conf.Get("common", "http_proxy"); ok {
|
||||||
if ok {
|
|
||||||
cfg.HttpProxy = tmpStr
|
cfg.HttpProxy = tmpStr
|
||||||
} else {
|
|
||||||
// get http_proxy from env
|
|
||||||
cfg.HttpProxy = os.Getenv("http_proxy")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "log_file")
|
if tmpStr, ok = conf.Get("common", "log_file"); ok {
|
||||||
if ok {
|
|
||||||
cfg.LogFile = tmpStr
|
cfg.LogFile = tmpStr
|
||||||
if cfg.LogFile == "console" {
|
if cfg.LogFile == "console" {
|
||||||
cfg.LogWay = "console"
|
cfg.LogWay = "console"
|
||||||
@ -119,30 +115,25 @@ func LoadClientCommonConf(conf ini.File) (cfg *ClientCommonConf, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "log_level")
|
if tmpStr, ok = conf.Get("common", "log_level"); ok {
|
||||||
if ok {
|
|
||||||
cfg.LogLevel = tmpStr
|
cfg.LogLevel = tmpStr
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "log_max_days")
|
if tmpStr, ok = conf.Get("common", "log_max_days"); ok {
|
||||||
if ok {
|
|
||||||
if v, err = strconv.ParseInt(tmpStr, 10, 64); err == nil {
|
if v, err = strconv.ParseInt(tmpStr, 10, 64); err == nil {
|
||||||
cfg.LogMaxDays = v
|
cfg.LogMaxDays = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "privilege_token")
|
if tmpStr, ok = conf.Get("common", "token"); ok {
|
||||||
if ok {
|
cfg.Token = tmpStr
|
||||||
cfg.PrivilegeToken = tmpStr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "admin_addr")
|
if tmpStr, ok = conf.Get("common", "admin_addr"); ok {
|
||||||
if ok {
|
|
||||||
cfg.AdminAddr = tmpStr
|
cfg.AdminAddr = tmpStr
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "admin_port")
|
if tmpStr, ok = conf.Get("common", "admin_port"); ok {
|
||||||
if ok {
|
|
||||||
if v, err = strconv.ParseInt(tmpStr, 10, 64); err == nil {
|
if v, err = strconv.ParseInt(tmpStr, 10, 64); err == nil {
|
||||||
cfg.AdminPort = int(v)
|
cfg.AdminPort = int(v)
|
||||||
} else {
|
} else {
|
||||||
@ -151,55 +142,44 @@ func LoadClientCommonConf(conf ini.File) (cfg *ClientCommonConf, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "admin_user")
|
if tmpStr, ok = conf.Get("common", "admin_user"); ok {
|
||||||
if ok {
|
|
||||||
cfg.AdminUser = tmpStr
|
cfg.AdminUser = tmpStr
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "admin_pwd")
|
if tmpStr, ok = conf.Get("common", "admin_pwd"); ok {
|
||||||
if ok {
|
|
||||||
cfg.AdminPwd = tmpStr
|
cfg.AdminPwd = tmpStr
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "pool_count")
|
if tmpStr, ok = conf.Get("common", "pool_count"); ok {
|
||||||
if ok {
|
if v, err = strconv.ParseInt(tmpStr, 10, 64); err == nil {
|
||||||
v, err = strconv.ParseInt(tmpStr, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
cfg.PoolCount = 1
|
|
||||||
} else {
|
|
||||||
cfg.PoolCount = int(v)
|
cfg.PoolCount = int(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "tcp_mux")
|
if tmpStr, ok = conf.Get("common", "tcp_mux"); ok && tmpStr == "false" {
|
||||||
if ok && tmpStr == "false" {
|
|
||||||
cfg.TcpMux = false
|
cfg.TcpMux = false
|
||||||
} else {
|
} else {
|
||||||
cfg.TcpMux = true
|
cfg.TcpMux = true
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "user")
|
if tmpStr, ok = conf.Get("common", "user"); ok {
|
||||||
if ok {
|
|
||||||
cfg.User = tmpStr
|
cfg.User = tmpStr
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "start")
|
if tmpStr, ok = conf.Get("common", "start"); ok {
|
||||||
if ok {
|
|
||||||
proxyNames := strings.Split(tmpStr, ",")
|
proxyNames := strings.Split(tmpStr, ",")
|
||||||
for _, name := range proxyNames {
|
for _, name := range proxyNames {
|
||||||
cfg.Start[strings.TrimSpace(name)] = struct{}{}
|
cfg.Start[strings.TrimSpace(name)] = struct{}{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "login_fail_exit")
|
if tmpStr, ok = conf.Get("common", "login_fail_exit"); ok && tmpStr == "false" {
|
||||||
if ok && tmpStr == "false" {
|
|
||||||
cfg.LoginFailExit = false
|
cfg.LoginFailExit = false
|
||||||
} else {
|
} else {
|
||||||
cfg.LoginFailExit = true
|
cfg.LoginFailExit = true
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "protocol")
|
if tmpStr, ok = conf.Get("common", "protocol"); ok {
|
||||||
if ok {
|
|
||||||
// Now it only support tcp and kcp.
|
// Now it only support tcp and kcp.
|
||||||
if tmpStr != "kcp" {
|
if tmpStr != "kcp" {
|
||||||
tmpStr = "tcp"
|
tmpStr = "tcp"
|
||||||
@ -207,10 +187,8 @@ func LoadClientCommonConf(conf ini.File) (cfg *ClientCommonConf, err error) {
|
|||||||
cfg.Protocol = tmpStr
|
cfg.Protocol = tmpStr
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "heartbeat_timeout")
|
if tmpStr, ok = conf.Get("common", "heartbeat_timeout"); ok {
|
||||||
if ok {
|
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
||||||
v, err = strconv.ParseInt(tmpStr, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
err = fmt.Errorf("Parse conf error: invalid heartbeat_timeout")
|
err = fmt.Errorf("Parse conf error: invalid heartbeat_timeout")
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
@ -218,17 +196,18 @@ func LoadClientCommonConf(conf ini.File) (cfg *ClientCommonConf, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "heartbeat_interval")
|
if tmpStr, ok = conf.Get("common", "heartbeat_interval"); ok {
|
||||||
if ok {
|
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
||||||
v, err = strconv.ParseInt(tmpStr, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
err = fmt.Errorf("Parse conf error: invalid heartbeat_interval")
|
err = fmt.Errorf("Parse conf error: invalid heartbeat_interval")
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
cfg.HeartBeatInterval = v
|
cfg.HeartBeatInterval = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *ClientCommonConf) Check() (err error) {
|
||||||
if cfg.HeartBeatInterval <= 0 {
|
if cfg.HeartBeatInterval <= 0 {
|
||||||
err = fmt.Errorf("Parse conf error: invalid heartbeat_interval")
|
err = fmt.Errorf("Parse conf error: invalid heartbeat_interval")
|
||||||
return
|
return
|
||||||
|
@ -27,7 +27,9 @@ import (
|
|||||||
ini "github.com/vaughan0/go-ini"
|
ini "github.com/vaughan0/go-ini"
|
||||||
)
|
)
|
||||||
|
|
||||||
var proxyConfTypeMap map[string]reflect.Type
|
var (
|
||||||
|
proxyConfTypeMap map[string]reflect.Type
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
proxyConfTypeMap = make(map[string]reflect.Type)
|
proxyConfTypeMap = make(map[string]reflect.Type)
|
||||||
@ -51,17 +53,16 @@ func NewConfByType(proxyType string) ProxyConf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ProxyConf interface {
|
type ProxyConf interface {
|
||||||
GetName() string
|
|
||||||
GetType() string
|
|
||||||
GetBaseInfo() *BaseProxyConf
|
GetBaseInfo() *BaseProxyConf
|
||||||
LoadFromMsg(pMsg *msg.NewProxy)
|
UnmarshalFromMsg(pMsg *msg.NewProxy)
|
||||||
LoadFromFile(name string, conf ini.Section) error
|
UnmarshalFromIni(prefix string, name string, conf ini.Section) error
|
||||||
UnMarshalToMsg(pMsg *msg.NewProxy)
|
MarshalToMsg(pMsg *msg.NewProxy)
|
||||||
Check() error
|
CheckForCli() error
|
||||||
|
CheckForSvr() error
|
||||||
Compare(conf ProxyConf) bool
|
Compare(conf ProxyConf) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewProxyConf(pMsg *msg.NewProxy) (cfg ProxyConf, err error) {
|
func NewProxyConfFromMsg(pMsg *msg.NewProxy) (cfg ProxyConf, err error) {
|
||||||
if pMsg.ProxyType == "" {
|
if pMsg.ProxyType == "" {
|
||||||
pMsg.ProxyType = consts.TcpProxy
|
pMsg.ProxyType = consts.TcpProxy
|
||||||
}
|
}
|
||||||
@ -71,12 +72,12 @@ func NewProxyConf(pMsg *msg.NewProxy) (cfg ProxyConf, err error) {
|
|||||||
err = fmt.Errorf("proxy [%s] type [%s] error", pMsg.ProxyName, pMsg.ProxyType)
|
err = fmt.Errorf("proxy [%s] type [%s] error", pMsg.ProxyName, pMsg.ProxyType)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cfg.LoadFromMsg(pMsg)
|
cfg.UnmarshalFromMsg(pMsg)
|
||||||
err = cfg.Check()
|
err = cfg.CheckForSvr()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewProxyConfFromFile(name string, section ini.Section) (cfg ProxyConf, err error) {
|
func NewProxyConfFromIni(prefix string, name string, section ini.Section) (cfg ProxyConf, err error) {
|
||||||
proxyType := section["type"]
|
proxyType := section["type"]
|
||||||
if proxyType == "" {
|
if proxyType == "" {
|
||||||
proxyType = consts.TcpProxy
|
proxyType = consts.TcpProxy
|
||||||
@ -87,7 +88,10 @@ func NewProxyConfFromFile(name string, section ini.Section) (cfg ProxyConf, err
|
|||||||
err = fmt.Errorf("proxy [%s] type [%s] error", name, proxyType)
|
err = fmt.Errorf("proxy [%s] type [%s] error", name, proxyType)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = cfg.LoadFromFile(name, section)
|
if err = cfg.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = cfg.CheckForCli()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,14 +104,6 @@ type BaseProxyConf struct {
|
|||||||
UseCompression bool `json:"use_compression"`
|
UseCompression bool `json:"use_compression"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *BaseProxyConf) GetName() string {
|
|
||||||
return cfg.ProxyName
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cfg *BaseProxyConf) GetType() string {
|
|
||||||
return cfg.ProxyType
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cfg *BaseProxyConf) GetBaseInfo() *BaseProxyConf {
|
func (cfg *BaseProxyConf) GetBaseInfo() *BaseProxyConf {
|
||||||
return cfg
|
return cfg
|
||||||
}
|
}
|
||||||
@ -122,23 +118,19 @@ func (cfg *BaseProxyConf) compare(cmp *BaseProxyConf) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *BaseProxyConf) LoadFromMsg(pMsg *msg.NewProxy) {
|
func (cfg *BaseProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
|
||||||
cfg.ProxyName = pMsg.ProxyName
|
cfg.ProxyName = pMsg.ProxyName
|
||||||
cfg.ProxyType = pMsg.ProxyType
|
cfg.ProxyType = pMsg.ProxyType
|
||||||
cfg.UseEncryption = pMsg.UseEncryption
|
cfg.UseEncryption = pMsg.UseEncryption
|
||||||
cfg.UseCompression = pMsg.UseCompression
|
cfg.UseCompression = pMsg.UseCompression
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *BaseProxyConf) LoadFromFile(name string, section ini.Section) error {
|
func (cfg *BaseProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) error {
|
||||||
var (
|
var (
|
||||||
tmpStr string
|
tmpStr string
|
||||||
ok bool
|
ok bool
|
||||||
)
|
)
|
||||||
if ClientCommonCfg.User != "" {
|
cfg.ProxyName = prefix + name
|
||||||
cfg.ProxyName = ClientCommonCfg.User + "." + name
|
|
||||||
} else {
|
|
||||||
cfg.ProxyName = name
|
|
||||||
}
|
|
||||||
cfg.ProxyType = section["type"]
|
cfg.ProxyType = section["type"]
|
||||||
|
|
||||||
tmpStr, ok = section["use_encryption"]
|
tmpStr, ok = section["use_encryption"]
|
||||||
@ -153,7 +145,7 @@ func (cfg *BaseProxyConf) LoadFromFile(name string, section ini.Section) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *BaseProxyConf) UnMarshalToMsg(pMsg *msg.NewProxy) {
|
func (cfg *BaseProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
|
||||||
pMsg.ProxyName = cfg.ProxyName
|
pMsg.ProxyName = cfg.ProxyName
|
||||||
pMsg.ProxyType = cfg.ProxyType
|
pMsg.ProxyType = cfg.ProxyType
|
||||||
pMsg.UseEncryption = cfg.UseEncryption
|
pMsg.UseEncryption = cfg.UseEncryption
|
||||||
@ -162,24 +154,21 @@ func (cfg *BaseProxyConf) UnMarshalToMsg(pMsg *msg.NewProxy) {
|
|||||||
|
|
||||||
// Bind info
|
// Bind info
|
||||||
type BindInfoConf struct {
|
type BindInfoConf struct {
|
||||||
BindAddr string `json:"bind_addr"`
|
|
||||||
RemotePort int `json:"remote_port"`
|
RemotePort int `json:"remote_port"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *BindInfoConf) compare(cmp *BindInfoConf) bool {
|
func (cfg *BindInfoConf) compare(cmp *BindInfoConf) bool {
|
||||||
if cfg.BindAddr != cmp.BindAddr ||
|
if cfg.RemotePort != cmp.RemotePort {
|
||||||
cfg.RemotePort != cmp.RemotePort {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *BindInfoConf) LoadFromMsg(pMsg *msg.NewProxy) {
|
func (cfg *BindInfoConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
|
||||||
cfg.BindAddr = ServerCommonCfg.ProxyBindAddr
|
|
||||||
cfg.RemotePort = pMsg.RemotePort
|
cfg.RemotePort = pMsg.RemotePort
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *BindInfoConf) LoadFromFile(name string, section ini.Section) (err error) {
|
func (cfg *BindInfoConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||||
var (
|
var (
|
||||||
tmpStr string
|
tmpStr string
|
||||||
ok bool
|
ok bool
|
||||||
@ -197,14 +186,10 @@ func (cfg *BindInfoConf) LoadFromFile(name string, section ini.Section) (err err
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *BindInfoConf) UnMarshalToMsg(pMsg *msg.NewProxy) {
|
func (cfg *BindInfoConf) MarshalToMsg(pMsg *msg.NewProxy) {
|
||||||
pMsg.RemotePort = cfg.RemotePort
|
pMsg.RemotePort = cfg.RemotePort
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *BindInfoConf) check() (err error) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Domain info
|
// Domain info
|
||||||
type DomainConf struct {
|
type DomainConf struct {
|
||||||
CustomDomains []string `json:"custom_domains"`
|
CustomDomains []string `json:"custom_domains"`
|
||||||
@ -219,12 +204,12 @@ func (cfg *DomainConf) compare(cmp *DomainConf) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *DomainConf) LoadFromMsg(pMsg *msg.NewProxy) {
|
func (cfg *DomainConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
|
||||||
cfg.CustomDomains = pMsg.CustomDomains
|
cfg.CustomDomains = pMsg.CustomDomains
|
||||||
cfg.SubDomain = pMsg.SubDomain
|
cfg.SubDomain = pMsg.SubDomain
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *DomainConf) LoadFromFile(name string, section ini.Section) (err error) {
|
func (cfg *DomainConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||||
var (
|
var (
|
||||||
tmpStr string
|
tmpStr string
|
||||||
ok bool
|
ok bool
|
||||||
@ -239,42 +224,60 @@ func (cfg *DomainConf) LoadFromFile(name string, section ini.Section) (err error
|
|||||||
if tmpStr, ok = section["subdomain"]; ok {
|
if tmpStr, ok = section["subdomain"]; ok {
|
||||||
cfg.SubDomain = tmpStr
|
cfg.SubDomain = tmpStr
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(cfg.CustomDomains) == 0 && cfg.SubDomain == "" {
|
|
||||||
return fmt.Errorf("Parse conf error: proxy [%s] custom_domains and subdomain should set at least one of them", name)
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *DomainConf) UnMarshalToMsg(pMsg *msg.NewProxy) {
|
func (cfg *DomainConf) MarshalToMsg(pMsg *msg.NewProxy) {
|
||||||
pMsg.CustomDomains = cfg.CustomDomains
|
pMsg.CustomDomains = cfg.CustomDomains
|
||||||
pMsg.SubDomain = cfg.SubDomain
|
pMsg.SubDomain = cfg.SubDomain
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *DomainConf) check() (err error) {
|
func (cfg *DomainConf) check() (err error) {
|
||||||
|
if len(cfg.CustomDomains) == 0 && cfg.SubDomain == "" {
|
||||||
|
err = fmt.Errorf("custom_domains and subdomain should set at least one of them")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *DomainConf) checkForCli() (err error) {
|
||||||
|
if err = cfg.check(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *DomainConf) checkForSvr() (err error) {
|
||||||
|
if err = cfg.check(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
for _, domain := range cfg.CustomDomains {
|
for _, domain := range cfg.CustomDomains {
|
||||||
if ServerCommonCfg.SubDomainHost != "" && len(strings.Split(ServerCommonCfg.SubDomainHost, ".")) < len(strings.Split(domain, ".")) {
|
if subDomainHost != "" && len(strings.Split(subDomainHost, ".")) < len(strings.Split(domain, ".")) {
|
||||||
if strings.Contains(domain, ServerCommonCfg.SubDomainHost) {
|
if strings.Contains(domain, subDomainHost) {
|
||||||
return fmt.Errorf("custom domain [%s] should not belong to subdomain_host [%s]", domain, ServerCommonCfg.SubDomainHost)
|
return fmt.Errorf("custom domain [%s] should not belong to subdomain_host [%s]", domain, subDomainHost)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.SubDomain != "" {
|
if cfg.SubDomain != "" {
|
||||||
if ServerCommonCfg.SubDomainHost == "" {
|
if subDomainHost == "" {
|
||||||
return fmt.Errorf("subdomain is not supported because this feature is not enabled by frps")
|
return fmt.Errorf("subdomain is not supported because this feature is not enabled by frps")
|
||||||
}
|
}
|
||||||
if strings.Contains(cfg.SubDomain, ".") || strings.Contains(cfg.SubDomain, "*") {
|
if strings.Contains(cfg.SubDomain, ".") || strings.Contains(cfg.SubDomain, "*") {
|
||||||
return fmt.Errorf("'.' and '*' is not supported in subdomain")
|
return fmt.Errorf("'.' and '*' is not supported in subdomain")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Local service info
|
// Local service info
|
||||||
type LocalSvrConf struct {
|
type LocalSvrConf struct {
|
||||||
LocalIp string `json:"-"`
|
LocalIp string `json:"local_ip"`
|
||||||
LocalPort int `json:"-"`
|
LocalPort int `json:"local_port"`
|
||||||
|
|
||||||
|
Plugin string `json:"plugin"`
|
||||||
|
PluginParams map[string]string `json:"plugin_params"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *LocalSvrConf) compare(cmp *LocalSvrConf) bool {
|
func (cfg *LocalSvrConf) compare(cmp *LocalSvrConf) bool {
|
||||||
@ -282,30 +285,6 @@ func (cfg *LocalSvrConf) compare(cmp *LocalSvrConf) bool {
|
|||||||
cfg.LocalPort != cmp.LocalPort {
|
cfg.LocalPort != cmp.LocalPort {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cfg *LocalSvrConf) LoadFromFile(name string, section ini.Section) (err error) {
|
|
||||||
if cfg.LocalIp = section["local_ip"]; cfg.LocalIp == "" {
|
|
||||||
cfg.LocalIp = "127.0.0.1"
|
|
||||||
}
|
|
||||||
|
|
||||||
if tmpStr, ok := section["local_port"]; ok {
|
|
||||||
if cfg.LocalPort, err = strconv.Atoi(tmpStr); err != nil {
|
|
||||||
return fmt.Errorf("Parse conf error: proxy [%s] local_port error", name)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return fmt.Errorf("Parse conf error: proxy [%s] local_port not found", name)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type PluginConf struct {
|
|
||||||
Plugin string `json:"-"`
|
|
||||||
PluginParams map[string]string `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cfg *PluginConf) compare(cmp *PluginConf) bool {
|
|
||||||
if cfg.Plugin != cmp.Plugin ||
|
if cfg.Plugin != cmp.Plugin ||
|
||||||
len(cfg.PluginParams) != len(cmp.PluginParams) {
|
len(cfg.PluginParams) != len(cmp.PluginParams) {
|
||||||
return false
|
return false
|
||||||
@ -319,7 +298,7 @@ func (cfg *PluginConf) compare(cmp *PluginConf) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *PluginConf) LoadFromFile(name string, section ini.Section) (err error) {
|
func (cfg *LocalSvrConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||||
cfg.Plugin = section["plugin"]
|
cfg.Plugin = section["plugin"]
|
||||||
cfg.PluginParams = make(map[string]string)
|
cfg.PluginParams = make(map[string]string)
|
||||||
if cfg.Plugin != "" {
|
if cfg.Plugin != "" {
|
||||||
@ -330,7 +309,17 @@ func (cfg *PluginConf) LoadFromFile(name string, section ini.Section) (err error
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("Parse conf error: proxy [%s] no plugin info found", name)
|
if cfg.LocalIp = section["local_ip"]; cfg.LocalIp == "" {
|
||||||
|
cfg.LocalIp = "127.0.0.1"
|
||||||
|
}
|
||||||
|
|
||||||
|
if tmpStr, ok := section["local_port"]; ok {
|
||||||
|
if cfg.LocalPort, err = strconv.Atoi(tmpStr); err != nil {
|
||||||
|
return fmt.Errorf("Parse conf error: proxy [%s] local_port error", name)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("Parse conf error: proxy [%s] local_port not found", name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -341,7 +330,6 @@ type TcpProxyConf struct {
|
|||||||
BindInfoConf
|
BindInfoConf
|
||||||
|
|
||||||
LocalSvrConf
|
LocalSvrConf
|
||||||
PluginConf
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *TcpProxyConf) Compare(cmp ProxyConf) bool {
|
func (cfg *TcpProxyConf) Compare(cmp ProxyConf) bool {
|
||||||
@ -352,43 +340,38 @@ func (cfg *TcpProxyConf) Compare(cmp ProxyConf) bool {
|
|||||||
|
|
||||||
if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) ||
|
if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) ||
|
||||||
!cfg.BindInfoConf.compare(&cmpConf.BindInfoConf) ||
|
!cfg.BindInfoConf.compare(&cmpConf.BindInfoConf) ||
|
||||||
!cfg.LocalSvrConf.compare(&cmpConf.LocalSvrConf) ||
|
!cfg.LocalSvrConf.compare(&cmpConf.LocalSvrConf) {
|
||||||
!cfg.PluginConf.compare(&cmpConf.PluginConf) {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *TcpProxyConf) LoadFromMsg(pMsg *msg.NewProxy) {
|
func (cfg *TcpProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
|
||||||
cfg.BaseProxyConf.LoadFromMsg(pMsg)
|
cfg.BaseProxyConf.UnmarshalFromMsg(pMsg)
|
||||||
cfg.BindInfoConf.LoadFromMsg(pMsg)
|
cfg.BindInfoConf.UnmarshalFromMsg(pMsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *TcpProxyConf) LoadFromFile(name string, section ini.Section) (err error) {
|
func (cfg *TcpProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||||
if err = cfg.BaseProxyConf.LoadFromFile(name, section); err != nil {
|
if err = cfg.BaseProxyConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = cfg.BindInfoConf.LoadFromFile(name, section); err != nil {
|
if err = cfg.BindInfoConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if err = cfg.LocalSvrConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||||
if err = cfg.PluginConf.LoadFromFile(name, section); err != nil {
|
|
||||||
if err = cfg.LocalSvrConf.LoadFromFile(name, section); err != nil {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *TcpProxyConf) UnMarshalToMsg(pMsg *msg.NewProxy) {
|
func (cfg *TcpProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
|
||||||
cfg.BaseProxyConf.UnMarshalToMsg(pMsg)
|
cfg.BaseProxyConf.MarshalToMsg(pMsg)
|
||||||
cfg.BindInfoConf.UnMarshalToMsg(pMsg)
|
cfg.BindInfoConf.MarshalToMsg(pMsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *TcpProxyConf) Check() (err error) {
|
func (cfg *TcpProxyConf) CheckForCli() error { return nil }
|
||||||
err = cfg.BindInfoConf.check()
|
|
||||||
return
|
func (cfg *TcpProxyConf) CheckForSvr() error { return nil }
|
||||||
}
|
|
||||||
|
|
||||||
// UDP
|
// UDP
|
||||||
type UdpProxyConf struct {
|
type UdpProxyConf struct {
|
||||||
@ -412,33 +395,32 @@ func (cfg *UdpProxyConf) Compare(cmp ProxyConf) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *UdpProxyConf) LoadFromMsg(pMsg *msg.NewProxy) {
|
func (cfg *UdpProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
|
||||||
cfg.BaseProxyConf.LoadFromMsg(pMsg)
|
cfg.BaseProxyConf.UnmarshalFromMsg(pMsg)
|
||||||
cfg.BindInfoConf.LoadFromMsg(pMsg)
|
cfg.BindInfoConf.UnmarshalFromMsg(pMsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *UdpProxyConf) LoadFromFile(name string, section ini.Section) (err error) {
|
func (cfg *UdpProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||||
if err = cfg.BaseProxyConf.LoadFromFile(name, section); err != nil {
|
if err = cfg.BaseProxyConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = cfg.BindInfoConf.LoadFromFile(name, section); err != nil {
|
if err = cfg.BindInfoConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = cfg.LocalSvrConf.LoadFromFile(name, section); err != nil {
|
if err = cfg.LocalSvrConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *UdpProxyConf) UnMarshalToMsg(pMsg *msg.NewProxy) {
|
func (cfg *UdpProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
|
||||||
cfg.BaseProxyConf.UnMarshalToMsg(pMsg)
|
cfg.BaseProxyConf.MarshalToMsg(pMsg)
|
||||||
cfg.BindInfoConf.UnMarshalToMsg(pMsg)
|
cfg.BindInfoConf.MarshalToMsg(pMsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *UdpProxyConf) Check() (err error) {
|
func (cfg *UdpProxyConf) CheckForCli() error { return nil }
|
||||||
err = cfg.BindInfoConf.check()
|
|
||||||
return
|
func (cfg *UdpProxyConf) CheckForSvr() error { return nil }
|
||||||
}
|
|
||||||
|
|
||||||
// HTTP
|
// HTTP
|
||||||
type HttpProxyConf struct {
|
type HttpProxyConf struct {
|
||||||
@ -446,12 +428,11 @@ type HttpProxyConf struct {
|
|||||||
DomainConf
|
DomainConf
|
||||||
|
|
||||||
LocalSvrConf
|
LocalSvrConf
|
||||||
PluginConf
|
|
||||||
|
|
||||||
Locations []string `json:"locations"`
|
Locations []string `json:"locations"`
|
||||||
HostHeaderRewrite string `json:"host_header_rewrite"`
|
HostHeaderRewrite string `json:"host_header_rewrite"`
|
||||||
HttpUser string `json:"-"`
|
HttpUser string `json:"http_user"`
|
||||||
HttpPwd string `json:"-"`
|
HttpPwd string `json:"http_pwd"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *HttpProxyConf) Compare(cmp ProxyConf) bool {
|
func (cfg *HttpProxyConf) Compare(cmp ProxyConf) bool {
|
||||||
@ -463,7 +444,6 @@ func (cfg *HttpProxyConf) Compare(cmp ProxyConf) bool {
|
|||||||
if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) ||
|
if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) ||
|
||||||
!cfg.DomainConf.compare(&cmpConf.DomainConf) ||
|
!cfg.DomainConf.compare(&cmpConf.DomainConf) ||
|
||||||
!cfg.LocalSvrConf.compare(&cmpConf.LocalSvrConf) ||
|
!cfg.LocalSvrConf.compare(&cmpConf.LocalSvrConf) ||
|
||||||
!cfg.PluginConf.compare(&cmpConf.PluginConf) ||
|
|
||||||
strings.Join(cfg.Locations, " ") != strings.Join(cmpConf.Locations, " ") ||
|
strings.Join(cfg.Locations, " ") != strings.Join(cmpConf.Locations, " ") ||
|
||||||
cfg.HostHeaderRewrite != cmpConf.HostHeaderRewrite ||
|
cfg.HostHeaderRewrite != cmpConf.HostHeaderRewrite ||
|
||||||
cfg.HttpUser != cmpConf.HttpUser ||
|
cfg.HttpUser != cmpConf.HttpUser ||
|
||||||
@ -473,9 +453,9 @@ func (cfg *HttpProxyConf) Compare(cmp ProxyConf) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *HttpProxyConf) LoadFromMsg(pMsg *msg.NewProxy) {
|
func (cfg *HttpProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
|
||||||
cfg.BaseProxyConf.LoadFromMsg(pMsg)
|
cfg.BaseProxyConf.UnmarshalFromMsg(pMsg)
|
||||||
cfg.DomainConf.LoadFromMsg(pMsg)
|
cfg.DomainConf.UnmarshalFromMsg(pMsg)
|
||||||
|
|
||||||
cfg.Locations = pMsg.Locations
|
cfg.Locations = pMsg.Locations
|
||||||
cfg.HostHeaderRewrite = pMsg.HostHeaderRewrite
|
cfg.HostHeaderRewrite = pMsg.HostHeaderRewrite
|
||||||
@ -483,18 +463,16 @@ func (cfg *HttpProxyConf) LoadFromMsg(pMsg *msg.NewProxy) {
|
|||||||
cfg.HttpPwd = pMsg.HttpPwd
|
cfg.HttpPwd = pMsg.HttpPwd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *HttpProxyConf) LoadFromFile(name string, section ini.Section) (err error) {
|
func (cfg *HttpProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||||
if err = cfg.BaseProxyConf.LoadFromFile(name, section); err != nil {
|
if err = cfg.BaseProxyConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = cfg.DomainConf.LoadFromFile(name, section); err != nil {
|
if err = cfg.DomainConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = cfg.PluginConf.LoadFromFile(name, section); err != nil {
|
if err = cfg.LocalSvrConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||||
if err = cfg.LocalSvrConf.LoadFromFile(name, section); err != nil {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
tmpStr string
|
tmpStr string
|
||||||
@ -512,9 +490,9 @@ func (cfg *HttpProxyConf) LoadFromFile(name string, section ini.Section) (err er
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *HttpProxyConf) UnMarshalToMsg(pMsg *msg.NewProxy) {
|
func (cfg *HttpProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
|
||||||
cfg.BaseProxyConf.UnMarshalToMsg(pMsg)
|
cfg.BaseProxyConf.MarshalToMsg(pMsg)
|
||||||
cfg.DomainConf.UnMarshalToMsg(pMsg)
|
cfg.DomainConf.MarshalToMsg(pMsg)
|
||||||
|
|
||||||
pMsg.Locations = cfg.Locations
|
pMsg.Locations = cfg.Locations
|
||||||
pMsg.HostHeaderRewrite = cfg.HostHeaderRewrite
|
pMsg.HostHeaderRewrite = cfg.HostHeaderRewrite
|
||||||
@ -522,11 +500,20 @@ func (cfg *HttpProxyConf) UnMarshalToMsg(pMsg *msg.NewProxy) {
|
|||||||
pMsg.HttpPwd = cfg.HttpPwd
|
pMsg.HttpPwd = cfg.HttpPwd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *HttpProxyConf) Check() (err error) {
|
func (cfg *HttpProxyConf) CheckForCli() (err error) {
|
||||||
if ServerCommonCfg.VhostHttpPort == 0 {
|
if err = cfg.DomainConf.checkForCli(); err != nil {
|
||||||
return fmt.Errorf("type [http] not support when vhost_http_port is not set")
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *HttpProxyConf) CheckForSvr() (err error) {
|
||||||
|
if vhostHttpPort == 0 {
|
||||||
|
err = fmt.Errorf("type [http] not support when vhost_http_port is not set")
|
||||||
|
}
|
||||||
|
if err = cfg.DomainConf.checkForSvr(); err != nil {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
err = cfg.DomainConf.check()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -536,7 +523,6 @@ type HttpsProxyConf struct {
|
|||||||
DomainConf
|
DomainConf
|
||||||
|
|
||||||
LocalSvrConf
|
LocalSvrConf
|
||||||
PluginConf
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *HttpsProxyConf) Compare(cmp ProxyConf) bool {
|
func (cfg *HttpsProxyConf) Compare(cmp ProxyConf) bool {
|
||||||
@ -547,43 +533,49 @@ func (cfg *HttpsProxyConf) Compare(cmp ProxyConf) bool {
|
|||||||
|
|
||||||
if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) ||
|
if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) ||
|
||||||
!cfg.DomainConf.compare(&cmpConf.DomainConf) ||
|
!cfg.DomainConf.compare(&cmpConf.DomainConf) ||
|
||||||
!cfg.LocalSvrConf.compare(&cmpConf.LocalSvrConf) ||
|
!cfg.LocalSvrConf.compare(&cmpConf.LocalSvrConf) {
|
||||||
!cfg.PluginConf.compare(&cmpConf.PluginConf) {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *HttpsProxyConf) LoadFromMsg(pMsg *msg.NewProxy) {
|
func (cfg *HttpsProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
|
||||||
cfg.BaseProxyConf.LoadFromMsg(pMsg)
|
cfg.BaseProxyConf.UnmarshalFromMsg(pMsg)
|
||||||
cfg.DomainConf.LoadFromMsg(pMsg)
|
cfg.DomainConf.UnmarshalFromMsg(pMsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *HttpsProxyConf) LoadFromFile(name string, section ini.Section) (err error) {
|
func (cfg *HttpsProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||||
if err = cfg.BaseProxyConf.LoadFromFile(name, section); err != nil {
|
if err = cfg.BaseProxyConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = cfg.DomainConf.LoadFromFile(name, section); err != nil {
|
if err = cfg.DomainConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = cfg.PluginConf.LoadFromFile(name, section); err != nil {
|
if err = cfg.LocalSvrConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||||
if err = cfg.LocalSvrConf.LoadFromFile(name, section); err != nil {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *HttpsProxyConf) UnMarshalToMsg(pMsg *msg.NewProxy) {
|
func (cfg *HttpsProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
|
||||||
cfg.BaseProxyConf.UnMarshalToMsg(pMsg)
|
cfg.BaseProxyConf.MarshalToMsg(pMsg)
|
||||||
cfg.DomainConf.UnMarshalToMsg(pMsg)
|
cfg.DomainConf.MarshalToMsg(pMsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *HttpsProxyConf) Check() (err error) {
|
func (cfg *HttpsProxyConf) CheckForCli() (err error) {
|
||||||
if ServerCommonCfg.VhostHttpsPort == 0 {
|
if err = cfg.DomainConf.checkForCli(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *HttpsProxyConf) CheckForSvr() (err error) {
|
||||||
|
if vhostHttpsPort == 0 {
|
||||||
return fmt.Errorf("type [https] not support when vhost_https_port is not set")
|
return fmt.Errorf("type [https] not support when vhost_https_port is not set")
|
||||||
}
|
}
|
||||||
err = cfg.DomainConf.check()
|
if err = cfg.DomainConf.checkForSvr(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -596,7 +588,6 @@ type StcpProxyConf struct {
|
|||||||
|
|
||||||
// used in role server
|
// used in role server
|
||||||
LocalSvrConf
|
LocalSvrConf
|
||||||
PluginConf
|
|
||||||
|
|
||||||
// used in role visitor
|
// used in role visitor
|
||||||
ServerName string `json:"server_name"`
|
ServerName string `json:"server_name"`
|
||||||
@ -612,7 +603,6 @@ func (cfg *StcpProxyConf) Compare(cmp ProxyConf) bool {
|
|||||||
|
|
||||||
if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) ||
|
if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) ||
|
||||||
!cfg.LocalSvrConf.compare(&cmpConf.LocalSvrConf) ||
|
!cfg.LocalSvrConf.compare(&cmpConf.LocalSvrConf) ||
|
||||||
!cfg.PluginConf.compare(&cmpConf.PluginConf) ||
|
|
||||||
cfg.Role != cmpConf.Role ||
|
cfg.Role != cmpConf.Role ||
|
||||||
cfg.Sk != cmpConf.Sk ||
|
cfg.Sk != cmpConf.Sk ||
|
||||||
cfg.ServerName != cmpConf.ServerName ||
|
cfg.ServerName != cmpConf.ServerName ||
|
||||||
@ -624,13 +614,13 @@ func (cfg *StcpProxyConf) Compare(cmp ProxyConf) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Only for role server.
|
// Only for role server.
|
||||||
func (cfg *StcpProxyConf) LoadFromMsg(pMsg *msg.NewProxy) {
|
func (cfg *StcpProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
|
||||||
cfg.BaseProxyConf.LoadFromMsg(pMsg)
|
cfg.BaseProxyConf.UnmarshalFromMsg(pMsg)
|
||||||
cfg.Sk = pMsg.Sk
|
cfg.Sk = pMsg.Sk
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *StcpProxyConf) LoadFromFile(name string, section ini.Section) (err error) {
|
func (cfg *StcpProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||||
if err = cfg.BaseProxyConf.LoadFromFile(name, section); err != nil {
|
if err = cfg.BaseProxyConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -661,21 +651,33 @@ func (cfg *StcpProxyConf) LoadFromFile(name string, section ini.Section) (err er
|
|||||||
return fmt.Errorf("Parse conf error: proxy [%s] bind_port not found", name)
|
return fmt.Errorf("Parse conf error: proxy [%s] bind_port not found", name)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if err = cfg.PluginConf.LoadFromFile(name, section); err != nil {
|
if err = cfg.LocalSvrConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||||
if err = cfg.LocalSvrConf.LoadFromFile(name, section); err != nil {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *StcpProxyConf) UnMarshalToMsg(pMsg *msg.NewProxy) {
|
func (cfg *StcpProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
|
||||||
cfg.BaseProxyConf.UnMarshalToMsg(pMsg)
|
cfg.BaseProxyConf.MarshalToMsg(pMsg)
|
||||||
pMsg.Sk = cfg.Sk
|
pMsg.Sk = cfg.Sk
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *StcpProxyConf) Check() (err error) {
|
func (cfg *StcpProxyConf) CheckForCli() (err error) {
|
||||||
|
if cfg.Role != "server" && cfg.Role != "visitor" {
|
||||||
|
err = fmt.Errorf("role should be 'server' or 'visitor'")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if cfg.Role == "visitor" {
|
||||||
|
if cfg.BindAddr == "" {
|
||||||
|
err = fmt.Errorf("bind_addr shouldn't be empty")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *StcpProxyConf) CheckForSvr() (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -688,7 +690,6 @@ type XtcpProxyConf struct {
|
|||||||
|
|
||||||
// used in role server
|
// used in role server
|
||||||
LocalSvrConf
|
LocalSvrConf
|
||||||
PluginConf
|
|
||||||
|
|
||||||
// used in role visitor
|
// used in role visitor
|
||||||
ServerName string `json:"server_name"`
|
ServerName string `json:"server_name"`
|
||||||
@ -704,7 +705,6 @@ func (cfg *XtcpProxyConf) Compare(cmp ProxyConf) bool {
|
|||||||
|
|
||||||
if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) ||
|
if !cfg.BaseProxyConf.compare(&cmpConf.BaseProxyConf) ||
|
||||||
!cfg.LocalSvrConf.compare(&cmpConf.LocalSvrConf) ||
|
!cfg.LocalSvrConf.compare(&cmpConf.LocalSvrConf) ||
|
||||||
!cfg.PluginConf.compare(&cmpConf.PluginConf) ||
|
|
||||||
cfg.Role != cmpConf.Role ||
|
cfg.Role != cmpConf.Role ||
|
||||||
cfg.Sk != cmpConf.Sk ||
|
cfg.Sk != cmpConf.Sk ||
|
||||||
cfg.ServerName != cmpConf.ServerName ||
|
cfg.ServerName != cmpConf.ServerName ||
|
||||||
@ -716,13 +716,13 @@ func (cfg *XtcpProxyConf) Compare(cmp ProxyConf) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Only for role server.
|
// Only for role server.
|
||||||
func (cfg *XtcpProxyConf) LoadFromMsg(pMsg *msg.NewProxy) {
|
func (cfg *XtcpProxyConf) UnmarshalFromMsg(pMsg *msg.NewProxy) {
|
||||||
cfg.BaseProxyConf.LoadFromMsg(pMsg)
|
cfg.BaseProxyConf.UnmarshalFromMsg(pMsg)
|
||||||
cfg.Sk = pMsg.Sk
|
cfg.Sk = pMsg.Sk
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *XtcpProxyConf) LoadFromFile(name string, section ini.Section) (err error) {
|
func (cfg *XtcpProxyConf) UnmarshalFromIni(prefix string, name string, section ini.Section) (err error) {
|
||||||
if err = cfg.BaseProxyConf.LoadFromFile(name, section); err != nil {
|
if err = cfg.BaseProxyConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -753,21 +753,33 @@ func (cfg *XtcpProxyConf) LoadFromFile(name string, section ini.Section) (err er
|
|||||||
return fmt.Errorf("Parse conf error: proxy [%s] bind_port not found", name)
|
return fmt.Errorf("Parse conf error: proxy [%s] bind_port not found", name)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if err = cfg.PluginConf.LoadFromFile(name, section); err != nil {
|
if err = cfg.LocalSvrConf.UnmarshalFromIni(prefix, name, section); err != nil {
|
||||||
if err = cfg.LocalSvrConf.LoadFromFile(name, section); err != nil {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *XtcpProxyConf) UnMarshalToMsg(pMsg *msg.NewProxy) {
|
func (cfg *XtcpProxyConf) MarshalToMsg(pMsg *msg.NewProxy) {
|
||||||
cfg.BaseProxyConf.UnMarshalToMsg(pMsg)
|
cfg.BaseProxyConf.MarshalToMsg(pMsg)
|
||||||
pMsg.Sk = cfg.Sk
|
pMsg.Sk = cfg.Sk
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *XtcpProxyConf) Check() (err error) {
|
func (cfg *XtcpProxyConf) CheckForCli() (err error) {
|
||||||
|
if cfg.Role != "server" && cfg.Role != "visitor" {
|
||||||
|
err = fmt.Errorf("role should be 'server' or 'visitor'")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if cfg.Role == "visitor" {
|
||||||
|
if cfg.BindAddr == "" {
|
||||||
|
err = fmt.Errorf("bind_addr shouldn't be empty")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *XtcpProxyConf) CheckForSvr() (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -805,7 +817,7 @@ func ParseRangeSection(name string, section ini.Section) (sections map[string]in
|
|||||||
|
|
||||||
// if len(startProxy) is 0, start all
|
// if len(startProxy) is 0, start all
|
||||||
// otherwise just start proxies in startProxy map
|
// otherwise just start proxies in startProxy map
|
||||||
func LoadProxyConfFromFile(prefix string, conf ini.File, startProxy map[string]struct{}) (
|
func LoadProxyConfFromIni(prefix string, conf ini.File, startProxy map[string]struct{}) (
|
||||||
proxyConfs map[string]ProxyConf, visitorConfs map[string]ProxyConf, err error) {
|
proxyConfs map[string]ProxyConf, visitorConfs map[string]ProxyConf, err error) {
|
||||||
|
|
||||||
if prefix != "" {
|
if prefix != "" {
|
||||||
@ -842,9 +854,7 @@ func LoadProxyConfFromFile(prefix string, conf ini.File, startProxy map[string]s
|
|||||||
}
|
}
|
||||||
|
|
||||||
for subName, subSection := range subSections {
|
for subName, subSection := range subSections {
|
||||||
// some proxy or visotr configure may be used this prefix
|
cfg, err := NewProxyConfFromIni(prefix, subName, subSection)
|
||||||
subSection["prefix"] = prefix
|
|
||||||
cfg, err := NewProxyConfFromFile(subName, subSection)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return proxyConfs, visitorConfs, err
|
return proxyConfs, visitorConfs, err
|
||||||
}
|
}
|
||||||
|
@ -24,49 +24,59 @@ import (
|
|||||||
"github.com/fatedier/frp/utils/util"
|
"github.com/fatedier/frp/utils/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ServerCommonCfg *ServerCommonConf
|
var (
|
||||||
|
// server global configure used for generate proxy conf used in frps
|
||||||
|
proxyBindAddr string
|
||||||
|
subDomainHost string
|
||||||
|
vhostHttpPort int
|
||||||
|
vhostHttpsPort int
|
||||||
|
)
|
||||||
|
|
||||||
|
func InitServerCfg(cfg *ServerCommonConf) {
|
||||||
|
proxyBindAddr = cfg.ProxyBindAddr
|
||||||
|
subDomainHost = cfg.SubDomainHost
|
||||||
|
vhostHttpPort = cfg.VhostHttpPort
|
||||||
|
vhostHttpsPort = cfg.VhostHttpsPort
|
||||||
|
}
|
||||||
|
|
||||||
// common config
|
// common config
|
||||||
type ServerCommonConf struct {
|
type ServerCommonConf struct {
|
||||||
ConfigFile string
|
BindAddr string `json:"bind_addr"`
|
||||||
BindAddr string
|
BindPort int `json:"bind_port"`
|
||||||
BindPort int
|
BindUdpPort int `json:"bind_udp_port"`
|
||||||
BindUdpPort int
|
KcpBindPort int `json:"kcp_bind_port"`
|
||||||
KcpBindPort int
|
ProxyBindAddr string `json:"proxy_bind_addr"`
|
||||||
ProxyBindAddr string
|
|
||||||
|
|
||||||
// If VhostHttpPort equals 0, don't listen a public port for http protocol.
|
// If VhostHttpPort equals 0, don't listen a public port for http protocol.
|
||||||
VhostHttpPort int
|
VhostHttpPort int `json:"vhost_http_port"`
|
||||||
|
|
||||||
// if VhostHttpsPort equals 0, don't listen a public port for https protocol
|
// if VhostHttpsPort equals 0, don't listen a public port for https protocol
|
||||||
VhostHttpsPort int
|
VhostHttpsPort int `json:"vhost_http_port"`
|
||||||
DashboardAddr string
|
DashboardAddr string `json:"dashboard_addr"`
|
||||||
|
|
||||||
// if DashboardPort equals 0, dashboard is not available
|
// if DashboardPort equals 0, dashboard is not available
|
||||||
DashboardPort int
|
DashboardPort int `json:"dashboard_port"`
|
||||||
DashboardUser string
|
DashboardUser string `json:"dashboard_user"`
|
||||||
DashboardPwd string
|
DashboardPwd string `json:"dashboard_pwd"`
|
||||||
AssetsDir string
|
AssetsDir string `json:"asserts_dir"`
|
||||||
LogFile string
|
LogFile string `json:"log_file"`
|
||||||
LogWay string // console or file
|
LogWay string `json:"log_way"` // console or file
|
||||||
LogLevel string
|
LogLevel string `json:"log_level"`
|
||||||
LogMaxDays int64
|
LogMaxDays int64 `json:"log_max_days"`
|
||||||
PrivilegeMode bool
|
Token string `json:"token"`
|
||||||
PrivilegeToken string
|
AuthTimeout int64 `json:"auth_timeout"`
|
||||||
AuthTimeout int64
|
SubDomainHost string `json:"subdomain_host"`
|
||||||
SubDomainHost string
|
TcpMux bool `json:"tcp_mux"`
|
||||||
TcpMux bool
|
|
||||||
|
|
||||||
PrivilegeAllowPorts map[int]struct{}
|
PrivilegeAllowPorts map[int]struct{}
|
||||||
MaxPoolCount int64
|
MaxPoolCount int64 `json:"max_pool_count"`
|
||||||
MaxPortsPerClient int64
|
MaxPortsPerClient int64 `json:"max_ports_per_client"`
|
||||||
HeartBeatTimeout int64
|
HeartBeatTimeout int64 `json:"heart_beat_timeout"`
|
||||||
UserConnTimeout int64
|
UserConnTimeout int64 `json:"user_conn_timeout"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetDefaultServerCommonConf() *ServerCommonConf {
|
func GetDefaultServerConf() *ServerCommonConf {
|
||||||
return &ServerCommonConf{
|
return &ServerCommonConf{
|
||||||
ConfigFile: "./frps.ini",
|
|
||||||
BindAddr: "0.0.0.0",
|
BindAddr: "0.0.0.0",
|
||||||
BindPort: 7000,
|
BindPort: 7000,
|
||||||
BindUdpPort: 0,
|
BindUdpPort: 0,
|
||||||
@ -83,8 +93,7 @@ func GetDefaultServerCommonConf() *ServerCommonConf {
|
|||||||
LogWay: "console",
|
LogWay: "console",
|
||||||
LogLevel: "info",
|
LogLevel: "info",
|
||||||
LogMaxDays: 3,
|
LogMaxDays: 3,
|
||||||
PrivilegeMode: true,
|
Token: "",
|
||||||
PrivilegeToken: "",
|
|
||||||
AuthTimeout: 900,
|
AuthTimeout: 900,
|
||||||
SubDomainHost: "",
|
SubDomainHost: "",
|
||||||
TcpMux: true,
|
TcpMux: true,
|
||||||
@ -96,22 +105,28 @@ func GetDefaultServerCommonConf() *ServerCommonConf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load server common configure.
|
func UnmarshalServerConfFromIni(defaultCfg *ServerCommonConf, content string) (cfg *ServerCommonConf, err error) {
|
||||||
func LoadServerCommonConf(conf ini.File) (cfg *ServerCommonConf, err error) {
|
cfg = defaultCfg
|
||||||
|
if cfg == nil {
|
||||||
|
cfg = GetDefaultServerConf()
|
||||||
|
}
|
||||||
|
|
||||||
|
conf, err := ini.Load(strings.NewReader(content))
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("parse ini conf file error: %v", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
tmpStr string
|
tmpStr string
|
||||||
ok bool
|
ok bool
|
||||||
v int64
|
v int64
|
||||||
)
|
)
|
||||||
cfg = GetDefaultServerCommonConf()
|
if tmpStr, ok = conf.Get("common", "bind_addr"); ok {
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "bind_addr")
|
|
||||||
if ok {
|
|
||||||
cfg.BindAddr = tmpStr
|
cfg.BindAddr = tmpStr
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "bind_port")
|
if tmpStr, ok = conf.Get("common", "bind_port"); ok {
|
||||||
if ok {
|
|
||||||
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
||||||
err = fmt.Errorf("Parse conf error: invalid bind_port")
|
err = fmt.Errorf("Parse conf error: invalid bind_port")
|
||||||
return
|
return
|
||||||
@ -120,8 +135,7 @@ func LoadServerCommonConf(conf ini.File) (cfg *ServerCommonConf, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "bind_udp_port")
|
if tmpStr, ok = conf.Get("common", "bind_udp_port"); ok {
|
||||||
if ok {
|
|
||||||
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
||||||
err = fmt.Errorf("Parse conf error: invalid bind_udp_port")
|
err = fmt.Errorf("Parse conf error: invalid bind_udp_port")
|
||||||
return
|
return
|
||||||
@ -130,8 +144,7 @@ func LoadServerCommonConf(conf ini.File) (cfg *ServerCommonConf, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "kcp_bind_port")
|
if tmpStr, ok = conf.Get("common", "kcp_bind_port"); ok {
|
||||||
if ok {
|
|
||||||
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
||||||
err = fmt.Errorf("Parse conf error: invalid kcp_bind_port")
|
err = fmt.Errorf("Parse conf error: invalid kcp_bind_port")
|
||||||
return
|
return
|
||||||
@ -140,15 +153,13 @@ func LoadServerCommonConf(conf ini.File) (cfg *ServerCommonConf, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "proxy_bind_addr")
|
if tmpStr, ok = conf.Get("common", "proxy_bind_addr"); ok {
|
||||||
if ok {
|
|
||||||
cfg.ProxyBindAddr = tmpStr
|
cfg.ProxyBindAddr = tmpStr
|
||||||
} else {
|
} else {
|
||||||
cfg.ProxyBindAddr = cfg.BindAddr
|
cfg.ProxyBindAddr = cfg.BindAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "vhost_http_port")
|
if tmpStr, ok = conf.Get("common", "vhost_http_port"); ok {
|
||||||
if ok {
|
|
||||||
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
||||||
err = fmt.Errorf("Parse conf error: invalid vhost_http_port")
|
err = fmt.Errorf("Parse conf error: invalid vhost_http_port")
|
||||||
return
|
return
|
||||||
@ -159,8 +170,7 @@ func LoadServerCommonConf(conf ini.File) (cfg *ServerCommonConf, err error) {
|
|||||||
cfg.VhostHttpPort = 0
|
cfg.VhostHttpPort = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "vhost_https_port")
|
if tmpStr, ok = conf.Get("common", "vhost_https_port"); ok {
|
||||||
if ok {
|
|
||||||
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
||||||
err = fmt.Errorf("Parse conf error: invalid vhost_https_port")
|
err = fmt.Errorf("Parse conf error: invalid vhost_https_port")
|
||||||
return
|
return
|
||||||
@ -171,15 +181,13 @@ func LoadServerCommonConf(conf ini.File) (cfg *ServerCommonConf, err error) {
|
|||||||
cfg.VhostHttpsPort = 0
|
cfg.VhostHttpsPort = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "dashboard_addr")
|
if tmpStr, ok = conf.Get("common", "dashboard_addr"); ok {
|
||||||
if ok {
|
|
||||||
cfg.DashboardAddr = tmpStr
|
cfg.DashboardAddr = tmpStr
|
||||||
} else {
|
} else {
|
||||||
cfg.DashboardAddr = cfg.BindAddr
|
cfg.DashboardAddr = cfg.BindAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "dashboard_port")
|
if tmpStr, ok = conf.Get("common", "dashboard_port"); ok {
|
||||||
if ok {
|
|
||||||
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
||||||
err = fmt.Errorf("Parse conf error: invalid dashboard_port")
|
err = fmt.Errorf("Parse conf error: invalid dashboard_port")
|
||||||
return
|
return
|
||||||
@ -190,23 +198,19 @@ func LoadServerCommonConf(conf ini.File) (cfg *ServerCommonConf, err error) {
|
|||||||
cfg.DashboardPort = 0
|
cfg.DashboardPort = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "dashboard_user")
|
if tmpStr, ok = conf.Get("common", "dashboard_user"); ok {
|
||||||
if ok {
|
|
||||||
cfg.DashboardUser = tmpStr
|
cfg.DashboardUser = tmpStr
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "dashboard_pwd")
|
if tmpStr, ok = conf.Get("common", "dashboard_pwd"); ok {
|
||||||
if ok {
|
|
||||||
cfg.DashboardPwd = tmpStr
|
cfg.DashboardPwd = tmpStr
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "assets_dir")
|
if tmpStr, ok = conf.Get("common", "assets_dir"); ok {
|
||||||
if ok {
|
|
||||||
cfg.AssetsDir = tmpStr
|
cfg.AssetsDir = tmpStr
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "log_file")
|
if tmpStr, ok = conf.Get("common", "log_file"); ok {
|
||||||
if ok {
|
|
||||||
cfg.LogFile = tmpStr
|
cfg.LogFile = tmpStr
|
||||||
if cfg.LogFile == "console" {
|
if cfg.LogFile == "console" {
|
||||||
cfg.LogWay = "console"
|
cfg.LogWay = "console"
|
||||||
@ -215,32 +219,20 @@ func LoadServerCommonConf(conf ini.File) (cfg *ServerCommonConf, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "log_level")
|
if tmpStr, ok = conf.Get("common", "log_level"); ok {
|
||||||
if ok {
|
|
||||||
cfg.LogLevel = tmpStr
|
cfg.LogLevel = tmpStr
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "log_max_days")
|
if tmpStr, ok = conf.Get("common", "log_max_days"); ok {
|
||||||
if ok {
|
|
||||||
v, err = strconv.ParseInt(tmpStr, 10, 64)
|
v, err = strconv.ParseInt(tmpStr, 10, 64)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
cfg.LogMaxDays = v
|
cfg.LogMaxDays = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "privilege_mode")
|
cfg.Token, _ = conf.Get("common", "token")
|
||||||
if ok {
|
|
||||||
if tmpStr == "true" {
|
|
||||||
cfg.PrivilegeMode = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// PrivilegeMode configure
|
if allowPortsStr, ok := conf.Get("common", "privilege_allow_ports"); ok {
|
||||||
if cfg.PrivilegeMode == true {
|
|
||||||
cfg.PrivilegeToken, _ = conf.Get("common", "privilege_token")
|
|
||||||
|
|
||||||
allowPortsStr, ok := conf.Get("common", "privilege_allow_ports")
|
|
||||||
if ok {
|
|
||||||
// e.g. 1000-2000,2001,2002,3000-4000
|
// e.g. 1000-2000,2001,2002,3000-4000
|
||||||
ports, errRet := util.ParseRangeNumbers(allowPortsStr)
|
ports, errRet := util.ParseRangeNumbers(allowPortsStr)
|
||||||
if errRet != nil {
|
if errRet != nil {
|
||||||
@ -252,10 +244,8 @@ func LoadServerCommonConf(conf ini.File) (cfg *ServerCommonConf, err error) {
|
|||||||
cfg.PrivilegeAllowPorts[int(port)] = struct{}{}
|
cfg.PrivilegeAllowPorts[int(port)] = struct{}{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "max_pool_count")
|
if tmpStr, ok = conf.Get("common", "max_pool_count"); ok {
|
||||||
if ok {
|
|
||||||
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
||||||
err = fmt.Errorf("Parse conf error: invalid max_pool_count")
|
err = fmt.Errorf("Parse conf error: invalid max_pool_count")
|
||||||
return
|
return
|
||||||
@ -268,8 +258,7 @@ func LoadServerCommonConf(conf ini.File) (cfg *ServerCommonConf, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "max_ports_per_client")
|
if tmpStr, ok = conf.Get("common", "max_ports_per_client"); ok {
|
||||||
if ok {
|
|
||||||
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
if v, err = strconv.ParseInt(tmpStr, 10, 64); err != nil {
|
||||||
err = fmt.Errorf("Parse conf error: invalid max_ports_per_client")
|
err = fmt.Errorf("Parse conf error: invalid max_ports_per_client")
|
||||||
return
|
return
|
||||||
@ -282,8 +271,7 @@ func LoadServerCommonConf(conf ini.File) (cfg *ServerCommonConf, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "authentication_timeout")
|
if tmpStr, ok = conf.Get("common", "authentication_timeout"); ok {
|
||||||
if ok {
|
|
||||||
v, errRet := strconv.ParseInt(tmpStr, 10, 64)
|
v, errRet := strconv.ParseInt(tmpStr, 10, 64)
|
||||||
if errRet != nil {
|
if errRet != nil {
|
||||||
err = fmt.Errorf("Parse conf error: authentication_timeout is incorrect")
|
err = fmt.Errorf("Parse conf error: authentication_timeout is incorrect")
|
||||||
@ -293,20 +281,17 @@ func LoadServerCommonConf(conf ini.File) (cfg *ServerCommonConf, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "subdomain_host")
|
if tmpStr, ok = conf.Get("common", "subdomain_host"); ok {
|
||||||
if ok {
|
|
||||||
cfg.SubDomainHost = strings.ToLower(strings.TrimSpace(tmpStr))
|
cfg.SubDomainHost = strings.ToLower(strings.TrimSpace(tmpStr))
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "tcp_mux")
|
if tmpStr, ok = conf.Get("common", "tcp_mux"); ok && tmpStr == "false" {
|
||||||
if ok && tmpStr == "false" {
|
|
||||||
cfg.TcpMux = false
|
cfg.TcpMux = false
|
||||||
} else {
|
} else {
|
||||||
cfg.TcpMux = true
|
cfg.TcpMux = true
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpStr, ok = conf.Get("common", "heartbeat_timeout")
|
if tmpStr, ok = conf.Get("common", "heartbeat_timeout"); ok {
|
||||||
if ok {
|
|
||||||
v, errRet := strconv.ParseInt(tmpStr, 10, 64)
|
v, errRet := strconv.ParseInt(tmpStr, 10, 64)
|
||||||
if errRet != nil {
|
if errRet != nil {
|
||||||
err = fmt.Errorf("Parse conf error: heartbeat_timeout is incorrect")
|
err = fmt.Errorf("Parse conf error: heartbeat_timeout is incorrect")
|
||||||
@ -317,3 +302,7 @@ func LoadServerCommonConf(conf ini.File) (cfg *ServerCommonConf, err error) {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cfg *ServerCommonConf) Check() (err error) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
@ -20,6 +20,7 @@ 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/consts"
|
"github.com/fatedier/frp/models/consts"
|
||||||
"github.com/fatedier/frp/models/msg"
|
"github.com/fatedier/frp/models/msg"
|
||||||
@ -103,7 +104,7 @@ func (ctl *Control) Start() {
|
|||||||
loginRespMsg := &msg.LoginResp{
|
loginRespMsg := &msg.LoginResp{
|
||||||
Version: version.Full(),
|
Version: version.Full(),
|
||||||
RunId: ctl.runId,
|
RunId: ctl.runId,
|
||||||
ServerUdpPort: config.ServerCommonCfg.BindUdpPort,
|
ServerUdpPort: g.GlbServerCfg.BindUdpPort,
|
||||||
Error: "",
|
Error: "",
|
||||||
}
|
}
|
||||||
msg.WriteMsg(ctl.conn, loginRespMsg)
|
msg.WriteMsg(ctl.conn, loginRespMsg)
|
||||||
@ -172,7 +173,7 @@ func (ctl *Control) GetWorkConn() (workConn net.Conn, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
case <-time.After(time.Duration(config.ServerCommonCfg.UserConnTimeout) * time.Second):
|
case <-time.After(time.Duration(g.GlbServerCfg.UserConnTimeout) * time.Second):
|
||||||
err = fmt.Errorf("timeout trying to get work connection")
|
err = fmt.Errorf("timeout trying to get work connection")
|
||||||
ctl.conn.Warn("%v", err)
|
ctl.conn.Warn("%v", err)
|
||||||
return
|
return
|
||||||
@ -202,7 +203,7 @@ func (ctl *Control) writer() {
|
|||||||
defer ctl.allShutdown.Start()
|
defer ctl.allShutdown.Start()
|
||||||
defer ctl.writerShutdown.Done()
|
defer ctl.writerShutdown.Done()
|
||||||
|
|
||||||
encWriter, err := crypto.NewWriter(ctl.conn, []byte(config.ServerCommonCfg.PrivilegeToken))
|
encWriter, err := crypto.NewWriter(ctl.conn, []byte(g.GlbServerCfg.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.allShutdown.Start()
|
ctl.allShutdown.Start()
|
||||||
@ -231,7 +232,7 @@ func (ctl *Control) reader() {
|
|||||||
defer ctl.allShutdown.Start()
|
defer ctl.allShutdown.Start()
|
||||||
defer ctl.readerShutdown.Done()
|
defer ctl.readerShutdown.Done()
|
||||||
|
|
||||||
encReader := crypto.NewReader(ctl.conn, []byte(config.ServerCommonCfg.PrivilegeToken))
|
encReader := crypto.NewReader(ctl.conn, []byte(g.GlbServerCfg.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 {
|
||||||
@ -301,7 +302,7 @@ func (ctl *Control) manager() {
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-heartbeat.C:
|
case <-heartbeat.C:
|
||||||
if time.Since(ctl.lastPing) > time.Duration(config.ServerCommonCfg.HeartBeatTimeout)*time.Second {
|
if time.Since(ctl.lastPing) > time.Duration(g.GlbServerCfg.HeartBeatTimeout)*time.Second {
|
||||||
ctl.conn.Warn("heartbeat timeout")
|
ctl.conn.Warn("heartbeat timeout")
|
||||||
ctl.allShutdown.Start()
|
ctl.allShutdown.Start()
|
||||||
return
|
return
|
||||||
@ -342,7 +343,7 @@ func (ctl *Control) manager() {
|
|||||||
func (ctl *Control) RegisterProxy(pxyMsg *msg.NewProxy) (remoteAddr string, err error) {
|
func (ctl *Control) RegisterProxy(pxyMsg *msg.NewProxy) (remoteAddr string, err error) {
|
||||||
var pxyConf config.ProxyConf
|
var pxyConf config.ProxyConf
|
||||||
// Load configures from NewProxy message and check.
|
// Load configures from NewProxy message and check.
|
||||||
pxyConf, err = config.NewProxyConf(pxyMsg)
|
pxyConf, err = config.NewProxyConfFromMsg(pxyMsg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -355,9 +356,9 @@ func (ctl *Control) RegisterProxy(pxyMsg *msg.NewProxy) (remoteAddr string, err
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check ports used number in each client
|
// Check ports used number in each client
|
||||||
if config.ServerCommonCfg.MaxPortsPerClient > 0 {
|
if g.GlbServerCfg.MaxPortsPerClient > 0 {
|
||||||
ctl.mu.Lock()
|
ctl.mu.Lock()
|
||||||
if ctl.portsUsedNum+pxy.GetUsedPortsNum() > int(config.ServerCommonCfg.MaxPortsPerClient) {
|
if ctl.portsUsedNum+pxy.GetUsedPortsNum() > int(g.GlbServerCfg.MaxPortsPerClient) {
|
||||||
ctl.mu.Unlock()
|
ctl.mu.Unlock()
|
||||||
err = fmt.Errorf("exceed the max_ports_per_client")
|
err = fmt.Errorf("exceed the max_ports_per_client")
|
||||||
return
|
return
|
||||||
@ -404,7 +405,7 @@ func (ctl *Control) CloseProxy(closeMsg *msg.CloseProxy) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.ServerCommonCfg.MaxPortsPerClient > 0 {
|
if g.GlbServerCfg.MaxPortsPerClient > 0 {
|
||||||
ctl.portsUsedNum = ctl.portsUsedNum - pxy.GetUsedPortsNum()
|
ctl.portsUsedNum = ctl.portsUsedNum - pxy.GetUsedPortsNum()
|
||||||
}
|
}
|
||||||
pxy.Close()
|
pxy.Close()
|
||||||
|
@ -21,7 +21,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/fatedier/frp/assets"
|
"github.com/fatedier/frp/assets"
|
||||||
"github.com/fatedier/frp/models/config"
|
"github.com/fatedier/frp/g"
|
||||||
frpNet "github.com/fatedier/frp/utils/net"
|
frpNet "github.com/fatedier/frp/utils/net"
|
||||||
|
|
||||||
"github.com/julienschmidt/httprouter"
|
"github.com/julienschmidt/httprouter"
|
||||||
@ -36,7 +36,7 @@ func RunDashboardServer(addr string, port int) (err error) {
|
|||||||
// url router
|
// url router
|
||||||
router := httprouter.New()
|
router := httprouter.New()
|
||||||
|
|
||||||
user, passwd := config.ServerCommonCfg.DashboardUser, config.ServerCommonCfg.DashboardPwd
|
user, passwd := g.GlbServerCfg.DashboardUser, g.GlbServerCfg.DashboardPwd
|
||||||
|
|
||||||
// api, see dashboard_api.go
|
// api, see dashboard_api.go
|
||||||
router.GET("/api/serverinfo", frpNet.HttprouterBasicAuth(apiServerInfo, user, passwd))
|
router.GET("/api/serverinfo", frpNet.HttprouterBasicAuth(apiServerInfo, user, passwd))
|
||||||
|
@ -18,6 +18,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/fatedier/frp/g"
|
||||||
"github.com/fatedier/frp/models/config"
|
"github.com/fatedier/frp/models/config"
|
||||||
"github.com/fatedier/frp/models/consts"
|
"github.com/fatedier/frp/models/consts"
|
||||||
"github.com/fatedier/frp/utils/log"
|
"github.com/fatedier/frp/utils/log"
|
||||||
@ -60,7 +61,7 @@ func apiServerInfo(w http.ResponseWriter, r *http.Request, _ httprouter.Params)
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
log.Info("Http request: [/api/serverinfo]")
|
log.Info("Http request: [/api/serverinfo]")
|
||||||
cfg := config.ServerCommonCfg
|
cfg := &g.GlbServerCfg.ServerCommonConf
|
||||||
serverStats := StatsGetServer()
|
serverStats := StatsGetServer()
|
||||||
res = ServerInfoResp{
|
res = ServerInfoResp{
|
||||||
Version: version.Full(),
|
Version: version.Full(),
|
||||||
|
@ -18,7 +18,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/fatedier/frp/models/config"
|
"github.com/fatedier/frp/g"
|
||||||
"github.com/fatedier/frp/utils/log"
|
"github.com/fatedier/frp/utils/log"
|
||||||
"github.com/fatedier/frp/utils/metric"
|
"github.com/fatedier/frp/utils/metric"
|
||||||
)
|
)
|
||||||
@ -92,19 +92,19 @@ func StatsClearUselessInfo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func StatsNewClient() {
|
func StatsNewClient() {
|
||||||
if config.ServerCommonCfg.DashboardPort != 0 {
|
if g.GlbServerCfg.DashboardPort != 0 {
|
||||||
globalStats.ClientCounts.Inc(1)
|
globalStats.ClientCounts.Inc(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func StatsCloseClient() {
|
func StatsCloseClient() {
|
||||||
if config.ServerCommonCfg.DashboardPort != 0 {
|
if g.GlbServerCfg.DashboardPort != 0 {
|
||||||
globalStats.ClientCounts.Dec(1)
|
globalStats.ClientCounts.Dec(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func StatsNewProxy(name string, proxyType string) {
|
func StatsNewProxy(name string, proxyType string) {
|
||||||
if config.ServerCommonCfg.DashboardPort != 0 {
|
if g.GlbServerCfg.DashboardPort != 0 {
|
||||||
globalStats.mu.Lock()
|
globalStats.mu.Lock()
|
||||||
defer globalStats.mu.Unlock()
|
defer globalStats.mu.Unlock()
|
||||||
counter, ok := globalStats.ProxyTypeCounts[proxyType]
|
counter, ok := globalStats.ProxyTypeCounts[proxyType]
|
||||||
@ -130,7 +130,7 @@ func StatsNewProxy(name string, proxyType string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func StatsCloseProxy(proxyName string, proxyType string) {
|
func StatsCloseProxy(proxyName string, proxyType string) {
|
||||||
if config.ServerCommonCfg.DashboardPort != 0 {
|
if g.GlbServerCfg.DashboardPort != 0 {
|
||||||
globalStats.mu.Lock()
|
globalStats.mu.Lock()
|
||||||
defer globalStats.mu.Unlock()
|
defer globalStats.mu.Unlock()
|
||||||
if counter, ok := globalStats.ProxyTypeCounts[proxyType]; ok {
|
if counter, ok := globalStats.ProxyTypeCounts[proxyType]; ok {
|
||||||
@ -143,7 +143,7 @@ func StatsCloseProxy(proxyName string, proxyType string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func StatsOpenConnection(name string) {
|
func StatsOpenConnection(name string) {
|
||||||
if config.ServerCommonCfg.DashboardPort != 0 {
|
if g.GlbServerCfg.DashboardPort != 0 {
|
||||||
globalStats.CurConns.Inc(1)
|
globalStats.CurConns.Inc(1)
|
||||||
|
|
||||||
globalStats.mu.Lock()
|
globalStats.mu.Lock()
|
||||||
@ -157,7 +157,7 @@ func StatsOpenConnection(name string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func StatsCloseConnection(name string) {
|
func StatsCloseConnection(name string) {
|
||||||
if config.ServerCommonCfg.DashboardPort != 0 {
|
if g.GlbServerCfg.DashboardPort != 0 {
|
||||||
globalStats.CurConns.Dec(1)
|
globalStats.CurConns.Dec(1)
|
||||||
|
|
||||||
globalStats.mu.Lock()
|
globalStats.mu.Lock()
|
||||||
@ -171,7 +171,7 @@ func StatsCloseConnection(name string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func StatsAddTrafficIn(name string, trafficIn int64) {
|
func StatsAddTrafficIn(name string, trafficIn int64) {
|
||||||
if config.ServerCommonCfg.DashboardPort != 0 {
|
if g.GlbServerCfg.DashboardPort != 0 {
|
||||||
globalStats.TotalTrafficIn.Inc(trafficIn)
|
globalStats.TotalTrafficIn.Inc(trafficIn)
|
||||||
|
|
||||||
globalStats.mu.Lock()
|
globalStats.mu.Lock()
|
||||||
@ -186,7 +186,7 @@ func StatsAddTrafficIn(name string, trafficIn int64) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func StatsAddTrafficOut(name string, trafficOut int64) {
|
func StatsAddTrafficOut(name string, trafficOut int64) {
|
||||||
if config.ServerCommonCfg.DashboardPort != 0 {
|
if g.GlbServerCfg.DashboardPort != 0 {
|
||||||
globalStats.TotalTrafficOut.Inc(trafficOut)
|
globalStats.TotalTrafficOut.Inc(trafficOut)
|
||||||
|
|
||||||
globalStats.mu.Lock()
|
globalStats.mu.Lock()
|
||||||
|
@ -23,6 +23,7 @@ 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/proto/udp"
|
"github.com/fatedier/frp/models/proto/udp"
|
||||||
@ -126,7 +127,7 @@ func (pxy *BaseProxy) startListenHandler(p Proxy, handler func(Proxy, frpNet.Con
|
|||||||
|
|
||||||
func NewProxy(ctl *Control, pxyConf config.ProxyConf) (pxy Proxy, err error) {
|
func NewProxy(ctl *Control, pxyConf config.ProxyConf) (pxy Proxy, err error) {
|
||||||
basePxy := BaseProxy{
|
basePxy := BaseProxy{
|
||||||
name: pxyConf.GetName(),
|
name: pxyConf.GetBaseInfo().ProxyName,
|
||||||
ctl: ctl,
|
ctl: ctl,
|
||||||
listeners: make([]frpNet.Listener, 0),
|
listeners: make([]frpNet.Listener, 0),
|
||||||
Logger: log.NewPrefixLogger(ctl.runId),
|
Logger: log.NewPrefixLogger(ctl.runId),
|
||||||
@ -191,7 +192,7 @@ func (pxy *TcpProxy) Run() (remoteAddr string, err error) {
|
|||||||
|
|
||||||
remoteAddr = fmt.Sprintf(":%d", pxy.realPort)
|
remoteAddr = fmt.Sprintf(":%d", pxy.realPort)
|
||||||
pxy.cfg.RemotePort = pxy.realPort
|
pxy.cfg.RemotePort = pxy.realPort
|
||||||
listener, errRet := frpNet.ListenTcp(config.ServerCommonCfg.ProxyBindAddr, pxy.realPort)
|
listener, errRet := frpNet.ListenTcp(g.GlbServerCfg.ProxyBindAddr, pxy.realPort)
|
||||||
if errRet != nil {
|
if errRet != nil {
|
||||||
err = errRet
|
err = errRet
|
||||||
return
|
return
|
||||||
@ -244,7 +245,7 @@ func (pxy *HttpProxy) Run() (remoteAddr string, err error) {
|
|||||||
}
|
}
|
||||||
tmpDomain := routeConfig.Domain
|
tmpDomain := routeConfig.Domain
|
||||||
tmpLocation := routeConfig.Location
|
tmpLocation := routeConfig.Location
|
||||||
addrs = append(addrs, util.CanonicalAddr(tmpDomain, int(config.ServerCommonCfg.VhostHttpPort)))
|
addrs = append(addrs, util.CanonicalAddr(tmpDomain, int(g.GlbServerCfg.VhostHttpPort)))
|
||||||
pxy.closeFuncs = append(pxy.closeFuncs, func() {
|
pxy.closeFuncs = append(pxy.closeFuncs, func() {
|
||||||
pxy.ctl.svr.httpReverseProxy.UnRegister(tmpDomain, tmpLocation)
|
pxy.ctl.svr.httpReverseProxy.UnRegister(tmpDomain, tmpLocation)
|
||||||
})
|
})
|
||||||
@ -253,7 +254,7 @@ func (pxy *HttpProxy) Run() (remoteAddr string, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if pxy.cfg.SubDomain != "" {
|
if pxy.cfg.SubDomain != "" {
|
||||||
routeConfig.Domain = pxy.cfg.SubDomain + "." + config.ServerCommonCfg.SubDomainHost
|
routeConfig.Domain = pxy.cfg.SubDomain + "." + g.GlbServerCfg.SubDomainHost
|
||||||
for _, location := range locations {
|
for _, location := range locations {
|
||||||
routeConfig.Location = location
|
routeConfig.Location = location
|
||||||
err = pxy.ctl.svr.httpReverseProxy.Register(routeConfig)
|
err = pxy.ctl.svr.httpReverseProxy.Register(routeConfig)
|
||||||
@ -262,7 +263,7 @@ func (pxy *HttpProxy) Run() (remoteAddr string, err error) {
|
|||||||
}
|
}
|
||||||
tmpDomain := routeConfig.Domain
|
tmpDomain := routeConfig.Domain
|
||||||
tmpLocation := routeConfig.Location
|
tmpLocation := routeConfig.Location
|
||||||
addrs = append(addrs, util.CanonicalAddr(tmpDomain, int(config.ServerCommonCfg.VhostHttpPort)))
|
addrs = append(addrs, util.CanonicalAddr(tmpDomain, g.GlbServerCfg.VhostHttpPort))
|
||||||
pxy.closeFuncs = append(pxy.closeFuncs, func() {
|
pxy.closeFuncs = append(pxy.closeFuncs, func() {
|
||||||
pxy.ctl.svr.httpReverseProxy.UnRegister(tmpDomain, tmpLocation)
|
pxy.ctl.svr.httpReverseProxy.UnRegister(tmpDomain, tmpLocation)
|
||||||
})
|
})
|
||||||
@ -286,7 +287,7 @@ func (pxy *HttpProxy) GetRealConn() (workConn frpNet.Conn, err error) {
|
|||||||
|
|
||||||
var rwc io.ReadWriteCloser = tmpConn
|
var rwc io.ReadWriteCloser = tmpConn
|
||||||
if pxy.cfg.UseEncryption {
|
if pxy.cfg.UseEncryption {
|
||||||
rwc, err = frpIo.WithEncryption(rwc, []byte(config.ServerCommonCfg.PrivilegeToken))
|
rwc, err = frpIo.WithEncryption(rwc, []byte(g.GlbServerCfg.Token))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
pxy.Error("create encryption stream error: %v", err)
|
pxy.Error("create encryption stream error: %v", err)
|
||||||
return
|
return
|
||||||
@ -334,11 +335,11 @@ func (pxy *HttpsProxy) Run() (remoteAddr string, err error) {
|
|||||||
l.AddLogPrefix(pxy.name)
|
l.AddLogPrefix(pxy.name)
|
||||||
pxy.Info("https proxy listen for host [%s]", routeConfig.Domain)
|
pxy.Info("https proxy listen for host [%s]", routeConfig.Domain)
|
||||||
pxy.listeners = append(pxy.listeners, l)
|
pxy.listeners = append(pxy.listeners, l)
|
||||||
addrs = append(addrs, util.CanonicalAddr(routeConfig.Domain, int(config.ServerCommonCfg.VhostHttpsPort)))
|
addrs = append(addrs, util.CanonicalAddr(routeConfig.Domain, g.GlbServerCfg.VhostHttpsPort))
|
||||||
}
|
}
|
||||||
|
|
||||||
if pxy.cfg.SubDomain != "" {
|
if pxy.cfg.SubDomain != "" {
|
||||||
routeConfig.Domain = pxy.cfg.SubDomain + "." + config.ServerCommonCfg.SubDomainHost
|
routeConfig.Domain = pxy.cfg.SubDomain + "." + g.GlbServerCfg.SubDomainHost
|
||||||
l, errRet := pxy.ctl.svr.VhostHttpsMuxer.Listen(routeConfig)
|
l, errRet := pxy.ctl.svr.VhostHttpsMuxer.Listen(routeConfig)
|
||||||
if errRet != nil {
|
if errRet != nil {
|
||||||
err = errRet
|
err = errRet
|
||||||
@ -347,7 +348,7 @@ func (pxy *HttpsProxy) Run() (remoteAddr string, err error) {
|
|||||||
l.AddLogPrefix(pxy.name)
|
l.AddLogPrefix(pxy.name)
|
||||||
pxy.Info("https proxy listen for host [%s]", routeConfig.Domain)
|
pxy.Info("https proxy listen for host [%s]", routeConfig.Domain)
|
||||||
pxy.listeners = append(pxy.listeners, l)
|
pxy.listeners = append(pxy.listeners, l)
|
||||||
addrs = append(addrs, util.CanonicalAddr(routeConfig.Domain, int(config.ServerCommonCfg.VhostHttpsPort)))
|
addrs = append(addrs, util.CanonicalAddr(routeConfig.Domain, int(g.GlbServerCfg.VhostHttpsPort)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pxy.startListenHandler(pxy, HandleUserTcpConnection)
|
pxy.startListenHandler(pxy, HandleUserTcpConnection)
|
||||||
@ -478,7 +479,7 @@ func (pxy *UdpProxy) Run() (remoteAddr string, err error) {
|
|||||||
|
|
||||||
remoteAddr = fmt.Sprintf(":%d", pxy.realPort)
|
remoteAddr = fmt.Sprintf(":%d", pxy.realPort)
|
||||||
pxy.cfg.RemotePort = pxy.realPort
|
pxy.cfg.RemotePort = pxy.realPort
|
||||||
addr, errRet := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", config.ServerCommonCfg.ProxyBindAddr, pxy.realPort))
|
addr, errRet := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", g.GlbServerCfg.ProxyBindAddr, pxy.realPort))
|
||||||
if errRet != nil {
|
if errRet != nil {
|
||||||
err = errRet
|
err = errRet
|
||||||
return
|
return
|
||||||
@ -644,7 +645,7 @@ func HandleUserTcpConnection(pxy Proxy, userConn frpNet.Conn) {
|
|||||||
var local io.ReadWriteCloser = workConn
|
var local io.ReadWriteCloser = workConn
|
||||||
cfg := pxy.GetConf().GetBaseInfo()
|
cfg := pxy.GetConf().GetBaseInfo()
|
||||||
if cfg.UseEncryption {
|
if cfg.UseEncryption {
|
||||||
local, err = frpIo.WithEncryption(local, []byte(config.ServerCommonCfg.PrivilegeToken))
|
local, err = frpIo.WithEncryption(local, []byte(g.GlbServerCfg.Token))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
pxy.Error("create encryption stream error: %v", err)
|
pxy.Error("create encryption stream error: %v", err)
|
||||||
return
|
return
|
||||||
|
@ -21,7 +21,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/fatedier/frp/assets"
|
"github.com/fatedier/frp/assets"
|
||||||
"github.com/fatedier/frp/models/config"
|
"github.com/fatedier/frp/g"
|
||||||
"github.com/fatedier/frp/models/msg"
|
"github.com/fatedier/frp/models/msg"
|
||||||
"github.com/fatedier/frp/utils/log"
|
"github.com/fatedier/frp/utils/log"
|
||||||
frpNet "github.com/fatedier/frp/utils/net"
|
frpNet "github.com/fatedier/frp/utils/net"
|
||||||
@ -71,7 +71,7 @@ type Service struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewService() (svr *Service, err error) {
|
func NewService() (svr *Service, err error) {
|
||||||
cfg := config.ServerCommonCfg
|
cfg := &g.GlbServerCfg.ServerCommonConf
|
||||||
svr = &Service{
|
svr = &Service{
|
||||||
ctlManager: NewControlManager(),
|
ctlManager: NewControlManager(),
|
||||||
pxyManager: NewProxyManager(),
|
pxyManager: NewProxyManager(),
|
||||||
@ -170,7 +170,7 @@ func (svr *Service) Run() {
|
|||||||
if svr.natHoleController != nil {
|
if svr.natHoleController != nil {
|
||||||
go svr.natHoleController.Run()
|
go svr.natHoleController.Run()
|
||||||
}
|
}
|
||||||
if config.ServerCommonCfg.KcpBindPort > 0 {
|
if g.GlbServerCfg.KcpBindPort > 0 {
|
||||||
go svr.HandleListener(svr.kcpListener)
|
go svr.HandleListener(svr.kcpListener)
|
||||||
}
|
}
|
||||||
svr.HandleListener(svr.listener)
|
svr.HandleListener(svr.listener)
|
||||||
@ -233,7 +233,7 @@ func (svr *Service) HandleListener(l frpNet.Listener) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.ServerCommonCfg.TcpMux {
|
if g.GlbServerCfg.TcpMux {
|
||||||
session, err := smux.Server(frpConn, nil)
|
session, err := smux.Server(frpConn, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("Failed to create mux connection: %v", err)
|
log.Warn("Failed to create mux connection: %v", err)
|
||||||
@ -270,11 +270,11 @@ func (svr *Service) RegisterControl(ctlConn frpNet.Conn, loginMsg *msg.Login) (e
|
|||||||
|
|
||||||
// Check auth.
|
// Check auth.
|
||||||
nowTime := time.Now().Unix()
|
nowTime := time.Now().Unix()
|
||||||
if config.ServerCommonCfg.AuthTimeout != 0 && nowTime-loginMsg.Timestamp > config.ServerCommonCfg.AuthTimeout {
|
if g.GlbServerCfg.AuthTimeout != 0 && nowTime-loginMsg.Timestamp > g.GlbServerCfg.AuthTimeout {
|
||||||
err = fmt.Errorf("authorization timeout")
|
err = fmt.Errorf("authorization timeout")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if util.GetAuthKey(config.ServerCommonCfg.PrivilegeToken, loginMsg.Timestamp) != loginMsg.PrivilegeKey {
|
if util.GetAuthKey(g.GlbServerCfg.Token, loginMsg.Timestamp) != loginMsg.PrivilegeKey {
|
||||||
err = fmt.Errorf("authorization failed")
|
err = fmt.Errorf("authorization failed")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ server_port = 10700
|
|||||||
log_file = ./frpc.log
|
log_file = ./frpc.log
|
||||||
# debug, info, warn, error
|
# debug, info, warn, error
|
||||||
log_level = debug
|
log_level = debug
|
||||||
privilege_token = 123456
|
token = 123456
|
||||||
admin_port = 10600
|
admin_port = 10600
|
||||||
admin_user = abc
|
admin_user = abc
|
||||||
admin_pwd = abc
|
admin_pwd = abc
|
||||||
|
@ -4,7 +4,7 @@ server_port = 10700
|
|||||||
log_file = ./frpc_visitor.log
|
log_file = ./frpc_visitor.log
|
||||||
# debug, info, warn, error
|
# debug, info, warn, error
|
||||||
log_level = debug
|
log_level = debug
|
||||||
privilege_token = 123456
|
token = 123456
|
||||||
|
|
||||||
[stcp_visitor]
|
[stcp_visitor]
|
||||||
type = stcp
|
type = stcp
|
||||||
|
@ -4,6 +4,6 @@ bind_port = 10700
|
|||||||
vhost_http_port = 10804
|
vhost_http_port = 10804
|
||||||
log_file = ./frps.log
|
log_file = ./frps.log
|
||||||
log_level = debug
|
log_level = debug
|
||||||
privilege_token = 123456
|
token = 123456
|
||||||
privilege_allow_ports = 10000-20000,20002,30000-50000
|
privilege_allow_ports = 10000-20000,20002,30000-50000
|
||||||
subdomain_host = sub.com
|
subdomain_host = sub.com
|
||||||
|
@ -19,7 +19,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var version string = "0.16.1"
|
var version string = "0.17.0"
|
||||||
|
|
||||||
func Full() string {
|
func Full() string {
|
||||||
return version
|
return version
|
||||||
|
4
vendor/github.com/fatedier/beego/controller_test.go
generated
vendored
4
vendor/github.com/fatedier/beego/controller_test.go
generated
vendored
@ -172,10 +172,10 @@ func TestAdditionalViewPaths(t *testing.T) {
|
|||||||
t.Fatal("TestAdditionalViewPaths expected error")
|
t.Fatal("TestAdditionalViewPaths expected error")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
ctrl.RenderString();
|
ctrl.RenderString()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
ctrl.TplName = "file2.tpl"
|
ctrl.TplName = "file2.tpl"
|
||||||
ctrl.ViewPath = dir2
|
ctrl.ViewPath = dir2
|
||||||
ctrl.RenderString();
|
ctrl.RenderString()
|
||||||
}
|
}
|
||||||
|
1
vendor/github.com/fatedier/beego/logs/alils/signature.go
generated
vendored
1
vendor/github.com/fatedier/beego/logs/alils/signature.go
generated
vendored
@ -109,4 +109,3 @@ func signature(project *LogProject, method, uri string,
|
|||||||
digest = base64.StdEncoding.EncodeToString(mac.Sum(nil))
|
digest = base64.StdEncoding.EncodeToString(mac.Sum(nil))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
vendor/github.com/fatedier/beego/template.go
generated
vendored
2
vendor/github.com/fatedier/beego/template.go
generated
vendored
@ -184,7 +184,7 @@ func BuildTemplate(dir string, files ...string) error {
|
|||||||
}
|
}
|
||||||
return errors.New("dir open err")
|
return errors.New("dir open err")
|
||||||
}
|
}
|
||||||
beeTemplates,ok := beeViewPathTemplates[dir];
|
beeTemplates, ok := beeViewPathTemplates[dir]
|
||||||
if !ok {
|
if !ok {
|
||||||
panic("Unknown view path: " + dir)
|
panic("Unknown view path: " + dir)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user