From f2512f8fce0905e80cbf9c6bb443b2091d9865dd Mon Sep 17 00:00:00 2001 From: haidy Date: Fri, 4 Jan 2019 22:21:57 +0800 Subject: [PATCH] support ipv6 --- client/admin.go | 3 +-- client/admin_api.go | 24 ++++++++++++++-------- client/control.go | 3 +-- client/proxy/proxy.go | 17 ++++++++++++---- client/service.go | 2 +- client/visitor.go | 6 ++---- cmd/frps.ini | 1 - cmd/main.go | 45 ++++++++++++++++++++---------------------- server/dashboard.go | 3 +-- server/group/tcp.go | 11 ++++++++++- server/ports/ports.go | 13 ++++++++++-- server/proxy.go | 2 +- server/service.go | 17 ++++++++++++---- utils/net/kcp.go | 11 ++++++++++- utils/net/tcp.go | 2 +- utils/net/udp.go | 2 +- utils/net/websocket.go | 3 +-- 17 files changed, 104 insertions(+), 61 deletions(-) diff --git a/client/admin.go b/client/admin.go index e8d49bad..c9665209 100644 --- a/client/admin.go +++ b/client/admin.go @@ -15,7 +15,6 @@ package client import ( - "fmt" "net" "net/http" "time" @@ -42,7 +41,7 @@ func (svr *Service) RunAdminServer(addr string, port int) (err error) { router.HandleFunc("/api/reload", svr.apiReload).Methods("GET") router.HandleFunc("/api/status", svr.apiStatus).Methods("GET") - address := fmt.Sprintf("%s:%d", addr, port) + address := newAddress(addr, port) server := &http.Server{ Addr: address, Handler: router, diff --git a/client/admin_api.go b/client/admin_api.go index 893d127d..525ae4c8 100644 --- a/client/admin_api.go +++ b/client/admin_api.go @@ -132,49 +132,57 @@ func NewProxyStatusResp(status *proxy.ProxyStatus) ProxyStatusResp { switch cfg := status.Cfg.(type) { case *config.TcpProxyConf: if cfg.LocalPort != 0 { - psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIp, cfg.LocalPort) + psr.LocalAddr = newAddress(cfg.LocalIp, cfg.LocalPort) } psr.Plugin = cfg.Plugin if status.Err != "" { - psr.RemoteAddr = fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, cfg.RemotePort) + psr.RemoteAddr = newAddress(g.GlbClientCfg.ServerAddr, cfg.RemotePort) } else { psr.RemoteAddr = g.GlbClientCfg.ServerAddr + status.RemoteAddr } case *config.UdpProxyConf: if cfg.LocalPort != 0 { - psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIp, cfg.LocalPort) + psr.LocalAddr = newAddress(cfg.LocalIp, cfg.LocalPort) } if status.Err != "" { - psr.RemoteAddr = fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, cfg.RemotePort) + psr.RemoteAddr = newAddress(g.GlbClientCfg.ServerAddr, cfg.RemotePort) } else { psr.RemoteAddr = g.GlbClientCfg.ServerAddr + status.RemoteAddr } case *config.HttpProxyConf: if cfg.LocalPort != 0 { - psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIp, cfg.LocalPort) + psr.LocalAddr = newAddress(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.LocalAddr = newAddress(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) + psr.LocalAddr = newAddress(cfg.LocalIp, cfg.LocalPort) } psr.Plugin = cfg.Plugin case *config.XtcpProxyConf: if cfg.LocalPort != 0 { - psr.LocalAddr = fmt.Sprintf("%s:%d", cfg.LocalIp, cfg.LocalPort) + psr.LocalAddr = newAddress(cfg.LocalIp, cfg.LocalPort) } psr.Plugin = cfg.Plugin } return psr } +func newAddress(addr string, port int) string { + if strings.Contains(addr, ".") { + return fmt.Sprintf("%s:%d", addr, port) + } else { + return fmt.Sprintf("[%s]:%d", addr, port) + } +} + // api/status func (svr *Service) apiStatus(w http.ResponseWriter, r *http.Request) { var ( diff --git a/client/control.go b/client/control.go index 260619a1..164625a6 100644 --- a/client/control.go +++ b/client/control.go @@ -15,7 +15,6 @@ package client import ( - "fmt" "io" "runtime/debug" "sync" @@ -169,7 +168,7 @@ func (ctl *Control) connectServer() (conn frpNet.Conn, err error) { conn = frpNet.WrapConn(stream) } else { conn, err = frpNet.ConnectServerByProxy(g.GlbClientCfg.HttpProxy, g.GlbClientCfg.Protocol, - fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerPort)) + newAddress(g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerPort)) if err != nil { ctl.Warn("start new connection to server error: %v", err) return diff --git a/client/proxy/proxy.go b/client/proxy/proxy.go index 610a6f88..0ad02507 100644 --- a/client/proxy/proxy.go +++ b/client/proxy/proxy.go @@ -19,6 +19,7 @@ import ( "fmt" "io" "net" + "strings" "sync" "time" @@ -231,6 +232,14 @@ func (pxy *XtcpProxy) Close() { } } +func newAddress(addr string, port int) string { + if strings.Contains(addr, ".") { + return fmt.Sprintf("%s:%d", addr, port) + } else { + return fmt.Sprintf("[%s]:%d", addr, port) + } +} + func (pxy *XtcpProxy) InWorkConn(conn frpNet.Conn) { defer conn.Close() var natHoleSidMsg msg.NatHoleSid @@ -244,8 +253,8 @@ func (pxy *XtcpProxy) InWorkConn(conn frpNet.Conn) { ProxyName: pxy.cfg.ProxyName, Sid: natHoleSidMsg.Sid, } - raddr, _ := net.ResolveUDPAddr("udp", - fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerUdpPort)) + + raddr, _ := net.ResolveUDPAddr("udp", newAddress(g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerUdpPort)) clientConn, err := net.DialUDP("udp", nil, raddr) defer clientConn.Close() @@ -321,7 +330,7 @@ type UdpProxy struct { } func (pxy *UdpProxy) Run() (err error) { - pxy.localAddr, err = net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", pxy.cfg.LocalIp, pxy.cfg.LocalPort)) + pxy.localAddr, err = net.ResolveUDPAddr("udp", newAddress(pxy.cfg.LocalIp, pxy.cfg.LocalPort)) if err != nil { return } @@ -440,7 +449,7 @@ func HandleTcpWorkConnection(localInfo *config.LocalSvrConf, proxyPlugin plugin. workConn.Debug("handle by plugin finished") return } else { - localConn, err := frpNet.ConnectServer("tcp", fmt.Sprintf("%s:%d", localInfo.LocalIp, localInfo.LocalPort)) + localConn, err := frpNet.ConnectServer("tcp", newAddress(localInfo.LocalIp, localInfo.LocalPort)) if err != nil { workConn.Close() workConn.Error("connect to local service [%s:%d] error: %v", localInfo.LocalIp, localInfo.LocalPort, err) diff --git a/client/service.go b/client/service.go index 98e39957..eca42868 100644 --- a/client/service.go +++ b/client/service.go @@ -156,7 +156,7 @@ func (svr *Service) keepControllerWorking() { // session: if it's not nil, using tcp mux func (svr *Service) login() (conn frpNet.Conn, session *fmux.Session, err error) { conn, err = frpNet.ConnectServerByProxy(g.GlbClientCfg.HttpProxy, g.GlbClientCfg.Protocol, - fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerPort)) + newAddress(g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerPort)) if err != nil { return } diff --git a/client/visitor.go b/client/visitor.go index 66344019..db72b14d 100644 --- a/client/visitor.go +++ b/client/visitor.go @@ -16,7 +16,6 @@ package client import ( "bytes" - "fmt" "io" "net" "strconv" @@ -200,8 +199,7 @@ func (sv *XtcpVisitor) handleConn(userConn frpNet.Conn) { return } - raddr, err := net.ResolveUDPAddr("udp", - fmt.Sprintf("%s:%d", g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerUdpPort)) + raddr, err := net.ResolveUDPAddr("udp", newAddress(g.GlbClientCfg.ServerAddr, g.GlbClientCfg.ServerUdpPort)) if err != nil { sv.Error("resolve server UDP addr error") return @@ -319,7 +317,7 @@ func (sv *XtcpVisitor) handleConn(userConn frpNet.Conn) { } func (sv *XtcpVisitor) sendDetectMsg(addr string, port int, laddr *net.UDPAddr, content []byte) (err error) { - daddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", addr, port)) + daddr, err := net.ResolveUDPAddr("udp", newAddress(addr, port)) if err != nil { return err } diff --git a/cmd/frps.ini b/cmd/frps.ini index 004fd483..82011509 100644 --- a/cmd/frps.ini +++ b/cmd/frps.ini @@ -1,4 +1,3 @@ [common] -bind_addr = 127.0.0.1 bind_port = 7000 allow_ports = 7000, 6000 \ No newline at end of file diff --git a/cmd/main.go b/cmd/main.go index e2b6b037..3bc688cd 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -1,12 +1,9 @@ package main import ( - "log" "runtime" "strings" - "time" - "net/http" _ "net/http/pprof" "github.com/fatedier/frp/cmd/frp" @@ -19,28 +16,28 @@ func main() { frp.RunFrps(path + "/frps.ini") ch := make(chan bool) - go func() { - time.Sleep(time.Second * 5) - frp.RunFrpc(path + "/frpc.ini") - ch <- true - }() - <-ch + // go func() { + // time.Sleep(time.Second * 5) + // frp.RunFrpc(path + "/frpc.ini") + // ch <- true + // }() + // <-ch - go func() { - log.Println(http.ListenAndServe("localhost:10000", nil)) - }() - // frp.RunFrps("./frps.ini") - log.Println("frps is running: ", frp.IsFrpsRunning()) + // go func() { + // log.Println(http.ListenAndServe("localhost:10000", nil)) + // }() + // // frp.RunFrps("./frps.ini") + // log.Println("frps is running: ", frp.IsFrpsRunning()) - //frp.StopFrps() - //log.Println("frps is running: ", frp.IsFrpsRunning()) - ch = make(chan bool) - go func() { - time.Sleep(time.Second * 5) - log.Println("frpc is running: ", frp.IsFrpcRunning()) - frp.StopFrpc() - log.Println("frpc is running: ", frp.IsFrpcRunning()) - ch <- true - }() + // //frp.StopFrps() + // //log.Println("frps is running: ", frp.IsFrpsRunning()) + // ch = make(chan bool) + // go func() { + // time.Sleep(time.Second * 5) + // log.Println("frpc is running: ", frp.IsFrpcRunning()) + // frp.StopFrpc() + // log.Println("frpc is running: ", frp.IsFrpcRunning()) + // ch <- true + // }() <-ch } diff --git a/server/dashboard.go b/server/dashboard.go index e1e0ae3e..65300f6c 100644 --- a/server/dashboard.go +++ b/server/dashboard.go @@ -15,7 +15,6 @@ package server import ( - "fmt" "net" "net/http" "time" @@ -53,7 +52,7 @@ func RunDashboardServer(addr string, port int) (err error) { http.Redirect(w, r, "/static/", http.StatusMovedPermanently) }) - address := fmt.Sprintf("%s:%d", addr, port) + address := newAddress(addr, port) server := &http.Server{ Addr: address, Handler: router, diff --git a/server/group/tcp.go b/server/group/tcp.go index 8c46be65..5f5c26fc 100644 --- a/server/group/tcp.go +++ b/server/group/tcp.go @@ -17,6 +17,7 @@ package group import ( "fmt" "net" + "strings" "sync" "github.com/fatedier/frp/server/ports" @@ -87,6 +88,14 @@ func NewTcpGroup(ctl *TcpGroupCtl) *TcpGroup { } } +func newAddress(addr string, port int) string { + if strings.Contains(addr, ".") { + return fmt.Sprintf("%s:%d", addr, port) + } else { + return fmt.Sprintf("[%s]:%d", addr, port) + } +} + func (tg *TcpGroup) Listen(proxyName string, group string, groupKey string, addr string, port int) (ln *TcpGroupListener, realPort int, err error) { tg.mu.Lock() defer tg.mu.Unlock() @@ -95,7 +104,7 @@ func (tg *TcpGroup) Listen(proxyName string, group string, groupKey string, addr if err != nil { return } - tcpLn, errRet := net.Listen("tcp", fmt.Sprintf("%s:%d", addr, port)) + tcpLn, errRet := net.Listen("tcp", newAddress(addr, port)) if errRet != nil { err = errRet return diff --git a/server/ports/ports.go b/server/ports/ports.go index a42fd91c..3544e873 100644 --- a/server/ports/ports.go +++ b/server/ports/ports.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "net" + "strings" "sync" "time" ) @@ -132,9 +133,17 @@ func (pm *PortManager) Acquire(name string, port int) (realPort int, err error) return } +func newAddress(addr string, port int) string { + if strings.Contains(addr, ".") { + return fmt.Sprintf("%s:%d", addr, port) + } else { + return fmt.Sprintf("[%s]:%d", addr, port) + } +} + func (pm *PortManager) isPortAvailable(port int) bool { if pm.netType == "udp" { - addr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", pm.bindAddr, port)) + addr, err := net.ResolveUDPAddr("udp", newAddress(pm.bindAddr, port)) if err != nil { return false } @@ -145,7 +154,7 @@ func (pm *PortManager) isPortAvailable(port int) bool { l.Close() return true } else { - l, err := net.Listen(pm.netType, fmt.Sprintf("%s:%d", pm.bindAddr, port)) + l, err := net.Listen(pm.netType, newAddress(pm.bindAddr, port)) if err != nil { return false } diff --git a/server/proxy.go b/server/proxy.go index a443626c..07d67903 100644 --- a/server/proxy.go +++ b/server/proxy.go @@ -500,7 +500,7 @@ func (pxy *UdpProxy) Run() (remoteAddr string, err error) { remoteAddr = fmt.Sprintf(":%d", pxy.realPort) pxy.cfg.RemotePort = pxy.realPort - addr, errRet := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", g.GlbServerCfg.ProxyBindAddr, pxy.realPort)) + addr, errRet := net.ResolveUDPAddr("udp", newAddress(g.GlbServerCfg.ProxyBindAddr, pxy.realPort)) if errRet != nil { err = errRet return diff --git a/server/service.go b/server/service.go index f8c2501a..470294a5 100644 --- a/server/service.go +++ b/server/service.go @@ -20,6 +20,7 @@ import ( "io/ioutil" "net" "net/http" + "strings" "time" "github.com/fatedier/frp/assets" @@ -90,6 +91,14 @@ type Service struct { closedCh chan bool } +func newAddress(addr string, port int) string { + if strings.Contains(addr, ".") { + return fmt.Sprintf("%s:%d", addr, port) + } else { + return fmt.Sprintf("[%s]:%d", addr, port) + } +} + func NewService() (svr *Service, err error) { cfg := &g.GlbServerCfg.ServerCommonConf svr = &Service{ @@ -124,7 +133,7 @@ func NewService() (svr *Service, err error) { } // Listen for accepting connections from client. - ln, err := net.Listen("tcp", fmt.Sprintf("%s:%d", cfg.BindAddr, cfg.BindPort)) + ln, err := net.Listen("tcp", newAddress(cfg.BindAddr, cfg.BindPort)) if err != nil { err = fmt.Errorf("Create server listener error, %v", err) return @@ -161,7 +170,7 @@ func NewService() (svr *Service, err error) { }) svr.httpReverseProxy = rp - address := fmt.Sprintf("%s:%d", cfg.ProxyBindAddr, cfg.VhostHttpPort) + address := newAddress(cfg.ProxyBindAddr, cfg.VhostHttpPort) server := &http.Server{ Addr: address, Handler: rp, @@ -186,7 +195,7 @@ func NewService() (svr *Service, err error) { if httpsMuxOn { l = svr.muxer.ListenHttps(1) } else { - l, err = net.Listen("tcp", fmt.Sprintf("%s:%d", cfg.ProxyBindAddr, cfg.VhostHttpsPort)) + l, err = net.Listen("tcp", newAddress(cfg.ProxyBindAddr, cfg.VhostHttpsPort)) if err != nil { err = fmt.Errorf("Create server listener error, %v", err) return @@ -204,7 +213,7 @@ func NewService() (svr *Service, err error) { // Create nat hole controller. if cfg.BindUdpPort > 0 { var nc *NatHoleController - addr := fmt.Sprintf("%s:%d", cfg.BindAddr, cfg.BindUdpPort) + addr := newAddress(cfg.BindAddr, cfg.BindUdpPort) nc, err = NewNatHoleController(addr) if err != nil { err = fmt.Errorf("Create nat hole controller error, %v", err) diff --git a/utils/net/kcp.go b/utils/net/kcp.go index 3d080fdd..e93572db 100644 --- a/utils/net/kcp.go +++ b/utils/net/kcp.go @@ -17,6 +17,7 @@ package net import ( "fmt" "net" + "strings" "github.com/fatedier/frp/utils/log" @@ -31,8 +32,16 @@ type KcpListener struct { log.Logger } +func newAddress(addr string, port int) string { + if strings.Contains(addr, ".") { + return fmt.Sprintf("%s:%d", addr, port) + } else { + return fmt.Sprintf("[%s]:%d", addr, port) + } +} + func ListenKcp(bindAddr string, bindPort int) (l *KcpListener, err error) { - listener, err := kcp.ListenWithOptions(fmt.Sprintf("%s:%d", bindAddr, bindPort), nil, 10, 3) + listener, err := kcp.ListenWithOptions(newAddress(bindAddr, bindPort), nil, 10, 3) if err != nil { return l, err } diff --git a/utils/net/tcp.go b/utils/net/tcp.go index 5c490d90..e0d25d5e 100644 --- a/utils/net/tcp.go +++ b/utils/net/tcp.go @@ -30,7 +30,7 @@ type TcpListener struct { } func ListenTcp(bindAddr string, bindPort int) (l *TcpListener, err error) { - tcpAddr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", bindAddr, bindPort)) + tcpAddr, err := net.ResolveTCPAddr("tcp", newAddress(bindAddr, bindPort)) if err != nil { return l, err } diff --git a/utils/net/udp.go b/utils/net/udp.go index e748e433..68c02f01 100644 --- a/utils/net/udp.go +++ b/utils/net/udp.go @@ -169,7 +169,7 @@ type UdpListener struct { } func ListenUDP(bindAddr string, bindPort int) (l *UdpListener, err error) { - udpAddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", bindAddr, bindPort)) + udpAddr, err := net.ResolveUDPAddr("udp", newAddress(bindAddr, bindPort)) if err != nil { return l, err } diff --git a/utils/net/websocket.go b/utils/net/websocket.go index 8ecc17e1..c6239605 100644 --- a/utils/net/websocket.go +++ b/utils/net/websocket.go @@ -2,7 +2,6 @@ package net import ( "errors" - "fmt" "net" "net/http" "net/url" @@ -59,7 +58,7 @@ func NewWebsocketListener(ln net.Listener) (wl *WebsocketListener) { } func ListenWebsocket(bindAddr string, bindPort int) (*WebsocketListener, error) { - tcpLn, err := net.Listen("tcp", fmt.Sprintf("%s:%d", bindAddr, bindPort)) + tcpLn, err := net.Listen("tcp", newAddress(bindAddr, bindPort)) if err != nil { return nil, err }