frp client
This commit is contained in:
parent
d3f88fe5ea
commit
d320d7c030
@ -71,6 +71,7 @@ type Control struct {
|
|||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
|
|
||||||
log.Logger
|
log.Logger
|
||||||
|
ProxyFunc func(err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewControl(runId string, conn frpNet.Conn, session *fmux.Session, pxyCfgs map[string]config.ProxyConf, visitorCfgs map[string]config.VisitorConf) *Control {
|
func NewControl(runId string, conn frpNet.Conn, session *fmux.Session, pxyCfgs map[string]config.ProxyConf, visitorCfgs map[string]config.VisitorConf) *Control {
|
||||||
@ -139,6 +140,9 @@ func (ctl *Control) HandleNewProxyResp(inMsg *msg.NewProxyResp) {
|
|||||||
err := ctl.pm.StartProxy(inMsg.ProxyName, inMsg.RemoteAddr, inMsg.Error)
|
err := ctl.pm.StartProxy(inMsg.ProxyName, inMsg.RemoteAddr, inMsg.Error)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctl.Warn("[%s] start error: %v", inMsg.ProxyName, err)
|
ctl.Warn("[%s] start error: %v", inMsg.ProxyName, err)
|
||||||
|
if ctl.ProxyFunc != nil {
|
||||||
|
ctl.ProxyFunc(err)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ctl.Info("[%s] start proxy success", inMsg.ProxyName)
|
ctl.Info("[%s] start proxy success", inMsg.ProxyName)
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,10 @@ import (
|
|||||||
fmux "github.com/hashicorp/yamux"
|
fmux "github.com/hashicorp/yamux"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ServiceClosedListener interface {
|
||||||
|
OnClosed(msg string)
|
||||||
|
}
|
||||||
|
|
||||||
type Service struct {
|
type Service struct {
|
||||||
// uniq id got from frps, attach it in loginMsg
|
// uniq id got from frps, attach it in loginMsg
|
||||||
runId string
|
runId string
|
||||||
@ -51,6 +55,19 @@ type Service struct {
|
|||||||
closedCh chan bool
|
closedCh chan bool
|
||||||
|
|
||||||
closed bool
|
closed bool
|
||||||
|
ReConnectByCount bool
|
||||||
|
reConnectCount int
|
||||||
|
onClosedListener ServiceClosedListener
|
||||||
|
}
|
||||||
|
|
||||||
|
func (svr *Service) SetProxyFailedFunc(proxyFailedFunc func(err error)) {
|
||||||
|
if svr.ctl != nil {
|
||||||
|
svr.ctl.ProxyFunc = proxyFailedFunc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (svr *Service) SetOnCloseListener(listener ServiceClosedListener) {
|
||||||
|
svr.onClosedListener = listener
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewService(pxyCfgs map[string]config.ProxyConf, visitorCfgs map[string]config.VisitorConf) (svr *Service, err error) {
|
func NewService(pxyCfgs map[string]config.ProxyConf, visitorCfgs map[string]config.VisitorConf) (svr *Service, err error) {
|
||||||
@ -67,6 +84,7 @@ func NewService(pxyCfgs map[string]config.ProxyConf, visitorCfgs map[string]conf
|
|||||||
exit: 0,
|
exit: 0,
|
||||||
closedCh: make(chan bool),
|
closedCh: make(chan bool),
|
||||||
closed: true,
|
closed: true,
|
||||||
|
reConnectCount: 0,
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -120,6 +138,10 @@ func (svr *Service) Run(cmd bool) error {
|
|||||||
go func() {
|
go func() {
|
||||||
svr.closed = <-svr.closedCh
|
svr.closed = <-svr.closedCh
|
||||||
log.Info("svr closed")
|
log.Info("svr closed")
|
||||||
|
|
||||||
|
if svr.onClosedListener != nil {
|
||||||
|
svr.onClosedListener.OnClosed("")
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -145,6 +167,13 @@ func (svr *Service) keepControllerWorking() {
|
|||||||
if delayTime > maxDelayTime {
|
if delayTime > maxDelayTime {
|
||||||
delayTime = maxDelayTime
|
delayTime = maxDelayTime
|
||||||
}
|
}
|
||||||
|
if svr.ReConnectByCount {
|
||||||
|
svr.reConnectCount++
|
||||||
|
if svr.reConnectCount == 3 {
|
||||||
|
svr.Close()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// reconnect success, init delayTime
|
// reconnect success, init delayTime
|
||||||
|
56
cmd/frp/frpc.go
Normal file
56
cmd/frp/frpc.go
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
package frp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/fatedier/frp/client"
|
||||||
|
"github.com/fatedier/frp/cmd/frpc/sub"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FRPCService struct {
|
||||||
|
*client.Service
|
||||||
|
l FRPCClosedListener
|
||||||
|
proxyFailedListener ProxyFailedListener
|
||||||
|
}
|
||||||
|
|
||||||
|
type FRPCClosedListener interface {
|
||||||
|
OnClosed(msg string)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProxyFailedListener interface {
|
||||||
|
OnProxyFailed()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (frp *FRPCService) OnClosed(msg string) {
|
||||||
|
log.Printf("OnClosed() l = %v", frp.l)
|
||||||
|
if frp.l != nil {
|
||||||
|
frp.l.OnClosed(msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (frp *FRPCService) SetFRPCCloseListener(listener FRPCClosedListener) {
|
||||||
|
frp.l = listener
|
||||||
|
frp.SetOnCloseListener(frp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (frp *FRPCService) onProxyFailed(err error) {
|
||||||
|
if frp.proxyFailedListener != nil {
|
||||||
|
frp.proxyFailedListener.OnProxyFailed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (frp *FRPCService) SetProxyFailedListener(listener ProxyFailedListener) {
|
||||||
|
frp.proxyFailedListener = listener
|
||||||
|
frp.SetProxyFailedFunc(frp.onProxyFailed)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (frp *FRPCService) SetReConnectByCount(reConnectByCount bool) {
|
||||||
|
frp.ReConnectByCount = reConnectByCount
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFrpcServiceWithPath(path string) (*FRPCService, error) {
|
||||||
|
svr, err := sub.NewService(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &FRPCService{Service: svr}, nil
|
||||||
|
}
|
@ -117,6 +117,12 @@ func RunFrpc(cfgFilePath string) (err error) {
|
|||||||
return runClient(cfgFilePath)
|
return runClient(cfgFilePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewService(cfgFilePath string) (ser *client.Service, err error) {
|
||||||
|
cmd = false
|
||||||
|
crypto.DefaultSalt = "frp"
|
||||||
|
return returnClient(cfgFilePath, false)
|
||||||
|
}
|
||||||
|
|
||||||
func StopFrp() (err error) {
|
func StopFrp() (err error) {
|
||||||
if service == nil {
|
if service == nil {
|
||||||
return fmt.Errorf("frp not start")
|
return fmt.Errorf("frp not start")
|
||||||
@ -214,8 +220,28 @@ func runClient(cfgFilePath string) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = startService(pxyCfgs, visitorCfgs)
|
return startService(pxyCfgs, visitorCfgs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func returnClient(cfgFilePath string, run bool) (svr *client.Service, err error) {
|
||||||
|
var content string
|
||||||
|
content, err = config.GetRenderedConfFromFile(cfgFilePath)
|
||||||
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
}
|
||||||
|
g.GlbClientCfg.CfgFile = cfgFilePath
|
||||||
|
|
||||||
|
err = parseClientCommonCfg(CfgFileTypeIni, content)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pxyCfgs, visitorCfgs, err := config.LoadAllConfFromIni(g.GlbClientCfg.User, content, g.GlbClientCfg.Start)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnService(pxyCfgs, visitorCfgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func startService(pxyCfgs map[string]config.ProxyConf, visitorCfgs map[string]config.VisitorConf) (err error) {
|
func startService(pxyCfgs map[string]config.ProxyConf, visitorCfgs map[string]config.VisitorConf) (err error) {
|
||||||
@ -251,3 +277,32 @@ func startService(pxyCfgs map[string]config.ProxyConf, visitorCfgs map[string]co
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func returnService(pxyCfgs map[string]config.ProxyConf, visitorCfgs map[string]config.VisitorConf) (svr *client.Service, err error) {
|
||||||
|
log.InitLog(g.GlbClientCfg.LogWay, g.GlbClientCfg.LogFile, g.GlbClientCfg.LogLevel, g.GlbClientCfg.LogMaxDays)
|
||||||
|
if g.GlbClientCfg.DnsServer != "" {
|
||||||
|
s := g.GlbClientCfg.DnsServer
|
||||||
|
if !strings.Contains(s, ":") {
|
||||||
|
s += ":53"
|
||||||
|
}
|
||||||
|
// Change default dns server for frpc
|
||||||
|
net.DefaultResolver = &net.Resolver{
|
||||||
|
PreferGo: true,
|
||||||
|
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
|
||||||
|
return net.Dial("udp", s)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
svr, errRet := client.NewService(pxyCfgs, visitorCfgs)
|
||||||
|
if errRet != nil {
|
||||||
|
err = errRet
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Capture the exit signal if we use kcp.
|
||||||
|
if g.GlbClientCfg.Protocol == "kcp" {
|
||||||
|
go handleSignal(svr)
|
||||||
|
}
|
||||||
|
|
||||||
|
return svr, err
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user