瀏覽代碼

add remoteAddr in NewProxyResp message

fatedier 7 年之前
父節點
當前提交
3f6799c06a
共有 7 個文件被更改,包括 102 次插入60 次删除
  1. 4 2
      client/admin_api.go
  2. 1 1
      client/control.go
  3. 17 8
      client/proxy_manager.go
  4. 3 2
      models/msg/msg.go
  5. 9 8
      server/control.go
  6. 59 39
      server/proxy.go
  7. 9 0
      utils/util/util.go

+ 4 - 2
client/admin_api.go

@@ -124,22 +124,24 @@ func NewProxyStatusResp(status *ProxyStatus) ProxyStatusResp {
 			psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIp, cfg.LocalPort)
 		}
 		psr.Plugin = cfg.Plugin
-		psr.RemoteAddr = fmt.Sprintf(":%d", cfg.RemotePort)
+		psr.RemoteAddr = config.ClientCommonCfg.ServerAddr + status.RemoteAddr
 	case *config.UdpProxyConf:
 		if cfg.LocalPort != 0 {
 			psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIp, cfg.LocalPort)
 		}
-		psr.RemoteAddr = fmt.Sprintf(":%d", cfg.RemotePort)
+		psr.RemoteAddr = config.ClientCommonCfg.ServerAddr + status.RemoteAddr
 	case *config.HttpProxyConf:
 		if cfg.LocalPort != 0 {
 			psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIp, cfg.LocalPort)
 		}
 		psr.Plugin = cfg.Plugin
+		psr.RemoteAddr = status.RemoteAddr
 	case *config.HttpsProxyConf:
 		if cfg.LocalPort != 0 {
 			psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIp, cfg.LocalPort)
 		}
 		psr.Plugin = cfg.Plugin
+		psr.RemoteAddr = status.RemoteAddr
 	case *config.StcpProxyConf:
 		if cfg.LocalPort != 0 {
 			psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIp, cfg.LocalPort)

+ 1 - 1
client/control.go

@@ -158,7 +158,7 @@ func (ctl *Control) HandleReqWorkConn(inMsg *msg.ReqWorkConn) {
 func (ctl *Control) HandleNewProxyResp(inMsg *msg.NewProxyResp) {
 	// Server will return NewProxyResp message to each NewProxy message.
 	// Start a new proxy handler if no error got
-	err := ctl.pm.StartProxy(inMsg.ProxyName, inMsg.Error)
+	err := ctl.pm.StartProxy(inMsg.ProxyName, inMsg.RemoteAddr, inMsg.Error)
 	if err != nil {
 		ctl.Warn("[%s] start error: %v", inMsg.ProxyName, err)
 	} else {

+ 17 - 8
client/proxy_manager.go

@@ -41,6 +41,8 @@ type ProxyWrapper struct {
 	Err    string
 	Cfg    config.ProxyConf
 
+	RemoteAddr string
+
 	pxy Proxy
 
 	mu sync.RWMutex
@@ -52,6 +54,9 @@ type ProxyStatus struct {
 	Status string           `json:"status"`
 	Err    string           `json:"err"`
 	Cfg    config.ProxyConf `json:"cfg"`
+
+	// Got from server.
+	RemoteAddr string `json:"remote_addr"`
 }
 
 func NewProxyWrapper(cfg config.ProxyConf) *ProxyWrapper {
@@ -78,16 +83,17 @@ func (pw *ProxyWrapper) GetStatus() *ProxyStatus {
 	pw.mu.RLock()
 	defer pw.mu.RUnlock()
 	ps := &ProxyStatus{
-		Name:   pw.Name,
-		Type:   pw.Type,
-		Status: pw.Status,
-		Err:    pw.Err,
-		Cfg:    pw.Cfg,
+		Name:       pw.Name,
+		Type:       pw.Type,
+		Status:     pw.Status,
+		Err:        pw.Err,
+		Cfg:        pw.Cfg,
+		RemoteAddr: pw.RemoteAddr,
 	}
 	return ps
 }
 
-func (pw *ProxyWrapper) Start(serverRespErr string) error {
+func (pw *ProxyWrapper) Start(remoteAddr string, serverRespErr string) error {
 	if pw.pxy != nil {
 		pw.pxy.Close()
 		pw.pxy = nil
@@ -96,6 +102,7 @@ func (pw *ProxyWrapper) Start(serverRespErr string) error {
 	if serverRespErr != "" {
 		pw.mu.Lock()
 		pw.Status = ProxyStatusStartErr
+		pw.RemoteAddr = remoteAddr
 		pw.Err = serverRespErr
 		pw.mu.Unlock()
 		return fmt.Errorf(serverRespErr)
@@ -104,6 +111,7 @@ func (pw *ProxyWrapper) Start(serverRespErr string) error {
 	pxy := NewProxy(pw.Cfg)
 	pw.mu.Lock()
 	defer pw.mu.Unlock()
+	pw.RemoteAddr = remoteAddr
 	if err := pxy.Run(); err != nil {
 		pw.Status = ProxyStatusStartErr
 		pw.Err = err.Error()
@@ -139,6 +147,7 @@ func (pw *ProxyWrapper) Close() {
 
 func NewProxyManager(ctl *Control, msgSendCh chan (msg.Message), logPrefix string) *ProxyManager {
 	return &ProxyManager{
+		ctl:         ctl,
 		proxies:     make(map[string]*ProxyWrapper),
 		visitorCfgs: make(map[string]config.ProxyConf),
 		visitors:    make(map[string]Visitor),
@@ -168,7 +177,7 @@ func (pm *ProxyManager) sendMsg(m msg.Message) error {
 	return err
 }
 
-func (pm *ProxyManager) StartProxy(name string, serverRespErr string) error {
+func (pm *ProxyManager) StartProxy(name string, remoteAddr string, serverRespErr string) error {
 	pm.mu.Lock()
 	defer pm.mu.Unlock()
 	if pm.closed {
@@ -180,7 +189,7 @@ func (pm *ProxyManager) StartProxy(name string, serverRespErr string) error {
 		return fmt.Errorf("no proxy found")
 	}
 
-	if err := pxy.Start(serverRespErr); err != nil {
+	if err := pxy.Start(remoteAddr, serverRespErr); err != nil {
 		errRet := err
 		err = pm.sendMsg(&msg.CloseProxy{
 			ProxyName: name,

+ 3 - 2
models/msg/msg.go

@@ -119,8 +119,9 @@ type NewProxy struct {
 }
 
 type NewProxyResp struct {
-	ProxyName string `json:"proxy_name"`
-	Error     string `json:"error"`
+	ProxyName  string `json:"proxy_name"`
+	RemoteAddr string `json:"remote_addr"`
+	Error      string `json:"error"`
 }
 
 type CloseProxy struct {

+ 9 - 8
server/control.go

@@ -308,7 +308,7 @@ func (ctl *Control) manager() {
 			switch m := rawMsg.(type) {
 			case *msg.NewProxy:
 				// register proxy in this control
-				err := ctl.RegisterProxy(m)
+				remoteAddr, err := ctl.RegisterProxy(m)
 				resp := &msg.NewProxyResp{
 					ProxyName: m.ProxyName,
 				}
@@ -316,6 +316,7 @@ func (ctl *Control) manager() {
 					resp.Error = err.Error()
 					ctl.conn.Warn("new proxy [%s] error: %v", m.ProxyName, err)
 				} else {
+					resp.RemoteAddr = remoteAddr
 					ctl.conn.Info("new proxy [%s] success", m.ProxyName)
 					StatsNewProxy(m.ProxyName, m.ProxyType)
 				}
@@ -332,24 +333,24 @@ func (ctl *Control) manager() {
 	}
 }
 
-func (ctl *Control) RegisterProxy(pxyMsg *msg.NewProxy) (err error) {
+func (ctl *Control) RegisterProxy(pxyMsg *msg.NewProxy) (remoteAddr string, err error) {
 	var pxyConf config.ProxyConf
 	// Load configures from NewProxy message and check.
 	pxyConf, err = config.NewProxyConf(pxyMsg)
 	if err != nil {
-		return err
+		return
 	}
 
 	// NewProxy will return a interface Proxy.
 	// In fact it create different proxies by different proxy type, we just call run() here.
 	pxy, err := NewProxy(ctl, pxyConf)
 	if err != nil {
-		return err
+		return remoteAddr, err
 	}
 
-	err = pxy.Run()
+	remoteAddr, err = pxy.Run()
 	if err != nil {
-		return err
+		return
 	}
 	defer func() {
 		if err != nil {
@@ -359,13 +360,13 @@ func (ctl *Control) RegisterProxy(pxyMsg *msg.NewProxy) (err error) {
 
 	err = ctl.svr.RegisterProxy(pxyMsg.ProxyName, pxy)
 	if err != nil {
-		return err
+		return
 	}
 
 	ctl.mu.Lock()
 	ctl.proxies[pxy.GetName()] = pxy
 	ctl.mu.Unlock()
-	return nil
+	return
 }
 
 func (ctl *Control) CloseProxy(closeMsg *msg.CloseProxy) (err error) {

+ 59 - 39
server/proxy.go

@@ -19,6 +19,7 @@ import (
 	"fmt"
 	"io"
 	"net"
+	"strings"
 	"sync"
 	"time"
 
@@ -29,11 +30,12 @@ import (
 	frpIo "github.com/fatedier/frp/utils/io"
 	"github.com/fatedier/frp/utils/log"
 	frpNet "github.com/fatedier/frp/utils/net"
+	"github.com/fatedier/frp/utils/util"
 	"github.com/fatedier/frp/utils/vhost"
 )
 
 type Proxy interface {
-	Run() error
+	Run() (remoteAddr string, err error)
 	GetControl() *Control
 	GetName() string
 	GetConf() config.ProxyConf
@@ -165,17 +167,19 @@ type TcpProxy struct {
 	cfg *config.TcpProxyConf
 }
 
-func (pxy *TcpProxy) Run() error {
-	listener, err := frpNet.ListenTcp(config.ServerCommonCfg.ProxyBindAddr, pxy.cfg.RemotePort)
-	if err != nil {
-		return err
+func (pxy *TcpProxy) Run() (remoteAddr string, err error) {
+	remoteAddr = fmt.Sprintf(":%d", pxy.cfg.RemotePort)
+	listener, errRet := frpNet.ListenTcp(config.ServerCommonCfg.ProxyBindAddr, pxy.cfg.RemotePort)
+	if errRet != nil {
+		err = errRet
+		return
 	}
 	listener.AddLogPrefix(pxy.name)
 	pxy.listeners = append(pxy.listeners, listener)
 	pxy.Info("tcp proxy listen port [%d]", pxy.cfg.RemotePort)
 
 	pxy.startListenHandler(pxy, HandleUserTcpConnection)
-	return nil
+	return
 }
 
 func (pxy *TcpProxy) GetConf() config.ProxyConf {
@@ -193,7 +197,7 @@ type HttpProxy struct {
 	closeFuncs []func()
 }
 
-func (pxy *HttpProxy) Run() (err error) {
+func (pxy *HttpProxy) Run() (remoteAddr string, err error) {
 	routeConfig := vhost.VhostRouteConfig{
 		RewriteHost:  pxy.cfg.HostHeaderRewrite,
 		Username:     pxy.cfg.HttpUser,
@@ -205,16 +209,19 @@ func (pxy *HttpProxy) Run() (err error) {
 	if len(locations) == 0 {
 		locations = []string{""}
 	}
+
+	addrs := make([]string, 0)
 	for _, domain := range pxy.cfg.CustomDomains {
 		routeConfig.Domain = domain
 		for _, location := range locations {
 			routeConfig.Location = location
-			err := pxy.ctl.svr.httpReverseProxy.Register(routeConfig)
+			err = pxy.ctl.svr.httpReverseProxy.Register(routeConfig)
 			if err != nil {
-				return err
+				return
 			}
 			tmpDomain := routeConfig.Domain
 			tmpLocation := routeConfig.Location
+			addrs = append(addrs, util.CanonicalAddr(tmpDomain, int(config.ServerCommonCfg.VhostHttpPort)))
 			pxy.closeFuncs = append(pxy.closeFuncs, func() {
 				pxy.ctl.svr.httpReverseProxy.UnRegister(tmpDomain, tmpLocation)
 			})
@@ -226,18 +233,20 @@ func (pxy *HttpProxy) Run() (err error) {
 		routeConfig.Domain = pxy.cfg.SubDomain + "." + config.ServerCommonCfg.SubDomainHost
 		for _, location := range locations {
 			routeConfig.Location = location
-			err := pxy.ctl.svr.httpReverseProxy.Register(routeConfig)
+			err = pxy.ctl.svr.httpReverseProxy.Register(routeConfig)
 			if err != nil {
-				return err
+				return
 			}
 			tmpDomain := routeConfig.Domain
 			tmpLocation := routeConfig.Location
+			addrs = append(addrs, util.CanonicalAddr(tmpDomain, int(config.ServerCommonCfg.VhostHttpPort)))
 			pxy.closeFuncs = append(pxy.closeFuncs, func() {
 				pxy.ctl.svr.httpReverseProxy.UnRegister(tmpDomain, tmpLocation)
 			})
 			pxy.Info("http proxy listen for host [%s] location [%s]", routeConfig.Domain, routeConfig.Location)
 		}
 	}
+	remoteAddr = strings.Join(addrs, ",")
 	return
 }
 
@@ -279,32 +288,38 @@ type HttpsProxy struct {
 	cfg *config.HttpsProxyConf
 }
 
-func (pxy *HttpsProxy) Run() (err error) {
+func (pxy *HttpsProxy) Run() (remoteAddr string, err error) {
 	routeConfig := &vhost.VhostRouteConfig{}
 
+	addrs := make([]string, 0)
 	for _, domain := range pxy.cfg.CustomDomains {
 		routeConfig.Domain = domain
-		l, err := pxy.ctl.svr.VhostHttpsMuxer.Listen(routeConfig)
-		if err != nil {
-			return err
+		l, errRet := pxy.ctl.svr.VhostHttpsMuxer.Listen(routeConfig)
+		if errRet != nil {
+			err = errRet
+			return
 		}
 		l.AddLogPrefix(pxy.name)
 		pxy.Info("https proxy listen for host [%s]", routeConfig.Domain)
 		pxy.listeners = append(pxy.listeners, l)
+		addrs = append(addrs, util.CanonicalAddr(routeConfig.Domain, int(config.ServerCommonCfg.VhostHttpsPort)))
 	}
 
 	if pxy.cfg.SubDomain != "" {
 		routeConfig.Domain = pxy.cfg.SubDomain + "." + config.ServerCommonCfg.SubDomainHost
-		l, err := pxy.ctl.svr.VhostHttpsMuxer.Listen(routeConfig)
-		if err != nil {
-			return err
+		l, errRet := pxy.ctl.svr.VhostHttpsMuxer.Listen(routeConfig)
+		if errRet != nil {
+			err = errRet
+			return
 		}
 		l.AddLogPrefix(pxy.name)
 		pxy.Info("https proxy listen for host [%s]", routeConfig.Domain)
 		pxy.listeners = append(pxy.listeners, l)
+		addrs = append(addrs, util.CanonicalAddr(routeConfig.Domain, int(config.ServerCommonCfg.VhostHttpsPort)))
 	}
 
 	pxy.startListenHandler(pxy, HandleUserTcpConnection)
+	remoteAddr = strings.Join(addrs, ",")
 	return
 }
 
@@ -321,17 +336,18 @@ type StcpProxy struct {
 	cfg *config.StcpProxyConf
 }
 
-func (pxy *StcpProxy) Run() error {
-	listener, err := pxy.ctl.svr.visitorManager.Listen(pxy.GetName(), pxy.cfg.Sk)
-	if err != nil {
-		return err
+func (pxy *StcpProxy) Run() (remoteAddr string, err error) {
+	listener, errRet := pxy.ctl.svr.visitorManager.Listen(pxy.GetName(), pxy.cfg.Sk)
+	if errRet != nil {
+		err = errRet
+		return
 	}
 	listener.AddLogPrefix(pxy.name)
 	pxy.listeners = append(pxy.listeners, listener)
 	pxy.Info("stcp proxy custom listen success")
 
 	pxy.startListenHandler(pxy, HandleUserTcpConnection)
-	return nil
+	return
 }
 
 func (pxy *StcpProxy) GetConf() config.ProxyConf {
@@ -350,10 +366,11 @@ type XtcpProxy struct {
 	closeCh chan struct{}
 }
 
-func (pxy *XtcpProxy) Run() error {
+func (pxy *XtcpProxy) Run() (remoteAddr string, err error) {
 	if pxy.ctl.svr.natHoleController == nil {
 		pxy.Error("udp port for xtcp is not specified.")
-		return fmt.Errorf("xtcp is not supported in frps")
+		err = fmt.Errorf("xtcp is not supported in frps")
+		return
 	}
 	sidCh := pxy.ctl.svr.natHoleController.ListenClient(pxy.GetName(), pxy.cfg.Sk)
 	go func() {
@@ -362,21 +379,21 @@ func (pxy *XtcpProxy) Run() error {
 			case <-pxy.closeCh:
 				break
 			case sid := <-sidCh:
-				workConn, err := pxy.GetWorkConnFromPool()
-				if err != nil {
+				workConn, errRet := pxy.GetWorkConnFromPool()
+				if errRet != nil {
 					continue
 				}
 				m := &msg.NatHoleSid{
 					Sid: sid,
 				}
-				err = msg.WriteMsg(workConn, m)
-				if err != nil {
-					pxy.Warn("write nat hole sid package error, %v", err)
+				errRet = msg.WriteMsg(workConn, m)
+				if errRet != nil {
+					pxy.Warn("write nat hole sid package error, %v", errRet)
 				}
 			}
 		}
 	}()
-	return nil
+	return
 }
 
 func (pxy *XtcpProxy) GetConf() config.ProxyConf {
@@ -414,15 +431,18 @@ type UdpProxy struct {
 	isClosed bool
 }
 
-func (pxy *UdpProxy) Run() (err error) {
-	addr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", config.ServerCommonCfg.ProxyBindAddr, pxy.cfg.RemotePort))
-	if err != nil {
-		return err
+func (pxy *UdpProxy) Run() (remoteAddr string, err error) {
+	remoteAddr = fmt.Sprintf(":%d", pxy.cfg.RemotePort)
+	addr, errRet := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", config.ServerCommonCfg.ProxyBindAddr, pxy.cfg.RemotePort))
+	if errRet != nil {
+		err = errRet
+		return
 	}
-	udpConn, err := net.ListenUDP("udp", addr)
-	if err != nil {
+	udpConn, errRet := net.ListenUDP("udp", addr)
+	if errRet != nil {
+		err = errRet
 		pxy.Warn("listen udp port error: %v", err)
-		return err
+		return
 	}
 	pxy.Info("udp proxy listen port [%d]", pxy.cfg.RemotePort)
 
@@ -537,7 +557,7 @@ func (pxy *UdpProxy) Run() (err error) {
 		udp.ForwardUserConn(udpConn, pxy.readCh, pxy.sendCh)
 		pxy.Close()
 	}()
-	return nil
+	return remoteAddr, nil
 }
 
 func (pxy *UdpProxy) GetConf() config.ProxyConf {

+ 9 - 0
utils/util/util.go

@@ -110,3 +110,12 @@ func PortRangesCut(portRanges [][2]int64, port int64) [][2]int64 {
 	}
 	return tmpRanges
 }
+
+func CanonicalAddr(host string, port int) (addr string) {
+	if port == 80 || port == 443 {
+		addr = host
+	} else {
+		addr = fmt.Sprintf("%s:%d", host, port)
+	}
+	return
+}