use net.JoinHostPort instead of fmt.Sprintf (#2791)

This commit is contained in:
fatedier 2022-02-09 15:19:35 +08:00 committed by GitHub
parent b2311e55e7
commit 6194273615
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 61 additions and 49 deletions

View File

@ -347,22 +347,18 @@ func (pxy *XTCPProxy) InWorkConn(conn net.Conn, m *msg.StartWorkConn) {
xl.Trace("get natHoleRespMsg, sid [%s], client address [%s] visitor address [%s]", natHoleRespMsg.Sid, natHoleRespMsg.ClientAddr, natHoleRespMsg.VisitorAddr) xl.Trace("get natHoleRespMsg, sid [%s], client address [%s] visitor address [%s]", natHoleRespMsg.Sid, natHoleRespMsg.ClientAddr, natHoleRespMsg.VisitorAddr)
// Send detect message // Send detect message
array := strings.Split(natHoleRespMsg.VisitorAddr, ":") host, portStr, err := net.SplitHostPort(natHoleRespMsg.VisitorAddr)
if len(array) <= 1 { if err != nil {
xl.Error("get NatHoleResp visitor address error: %v", natHoleRespMsg.VisitorAddr) xl.Error("get NatHoleResp visitor address [%s] error: %v", natHoleRespMsg.VisitorAddr, err)
} }
laddr, _ := net.ResolveUDPAddr("udp", clientConn.LocalAddr().String()) laddr, _ := net.ResolveUDPAddr("udp", clientConn.LocalAddr().String())
/*
for i := 1000; i < 65000; i++ { port, err := strconv.ParseInt(portStr, 10, 64)
pxy.sendDetectMsg(array[0], int64(i), laddr, "a")
}
*/
port, err := strconv.ParseInt(array[1], 10, 64)
if err != nil { if err != nil {
xl.Error("get natHoleResp visitor address error: %v", natHoleRespMsg.VisitorAddr) xl.Error("get natHoleResp visitor address error: %v", natHoleRespMsg.VisitorAddr)
return return
} }
pxy.sendDetectMsg(array[0], int(port), laddr, []byte(natHoleRespMsg.Sid)) pxy.sendDetectMsg(host, int(port), laddr, []byte(natHoleRespMsg.Sid))
xl.Trace("send all detect msg done") xl.Trace("send all detect msg done")
msg.WriteMsg(conn, &msg.NatHoleClientDetectOK{}) msg.WriteMsg(conn, &msg.NatHoleClientDetectOK{})

View File

@ -20,6 +20,7 @@ import (
"fmt" "fmt"
"io" "io"
"net" "net"
"strconv"
"sync" "sync"
"time" "time"
@ -85,7 +86,7 @@ type STCPVisitor struct {
} }
func (sv *STCPVisitor) Run() (err error) { func (sv *STCPVisitor) Run() (err error) {
sv.l, err = net.Listen("tcp", fmt.Sprintf("%s:%d", sv.cfg.BindAddr, sv.cfg.BindPort)) sv.l, err = net.Listen("tcp", net.JoinHostPort(sv.cfg.BindAddr, strconv.Itoa(sv.cfg.BindPort)))
if err != nil { if err != nil {
return return
} }
@ -174,7 +175,7 @@ type XTCPVisitor struct {
} }
func (sv *XTCPVisitor) Run() (err error) { func (sv *XTCPVisitor) Run() (err error) {
sv.l, err = net.Listen("tcp", fmt.Sprintf("%s:%d", sv.cfg.BindAddr, sv.cfg.BindPort)) sv.l, err = net.Listen("tcp", net.JoinHostPort(sv.cfg.BindAddr, strconv.Itoa(sv.cfg.BindPort)))
if err != nil { if err != nil {
return return
} }
@ -352,7 +353,7 @@ type SUDPVisitor struct {
func (sv *SUDPVisitor) Run() (err error) { func (sv *SUDPVisitor) Run() (err error) {
xl := xlog.FromContextSafe(sv.ctx) xl := xlog.FromContextSafe(sv.ctx)
addr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", sv.cfg.BindAddr, sv.cfg.BindPort)) addr, err := net.ResolveUDPAddr("udp", net.JoinHostPort(sv.cfg.BindAddr, strconv.Itoa(sv.cfg.BindPort)))
if err != nil { if err != nil {
return fmt.Errorf("sudp ResolveUDPAddr error: %v", err) return fmt.Errorf("sudp ResolveUDPAddr error: %v", err)
} }

View File

@ -18,6 +18,7 @@ import (
"fmt" "fmt"
"io" "io"
"net" "net"
"strconv"
"sync" "sync"
"time" "time"
@ -163,7 +164,7 @@ type UDPListener struct {
} }
func ListenUDP(bindAddr string, bindPort int) (l *UDPListener, err error) { 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", net.JoinHostPort(bindAddr, strconv.Itoa(bindPort)))
if err != nil { if err != nil {
return l, err return l, err
} }

View File

@ -2,9 +2,9 @@ package net
import ( import (
"errors" "errors"
"fmt"
"net" "net"
"net/http" "net/http"
"strconv"
"golang.org/x/net/websocket" "golang.org/x/net/websocket"
) )
@ -52,7 +52,7 @@ func NewWebsocketListener(ln net.Listener) (wl *WebsocketListener) {
} }
func ListenWebsocket(bindAddr string, bindPort int) (*WebsocketListener, error) { func ListenWebsocket(bindAddr string, bindPort int) (*WebsocketListener, error) {
tcpLn, err := net.Listen("tcp", fmt.Sprintf("%s:%d", bindAddr, bindPort)) tcpLn, err := net.Listen("tcp", net.JoinHostPort(bindAddr, strconv.Itoa(bindPort)))
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -48,7 +48,7 @@ func readHTTPConnectRequest(rd io.Reader) (host string, err error) {
return return
} }
host = util.GetHostFromAddr(req.Host) host, _ = util.CanonicalHost(req.Host)
return return
} }

View File

@ -34,17 +34,6 @@ func OkResponse() *http.Response {
return res return res
} }
// TODO: use "CanonicalHost" func to replace all "GetHostFromAddr" func.
func GetHostFromAddr(addr string) (host string) {
strs := strings.Split(addr, ":")
if len(strs) > 1 {
host = strs[0]
} else {
host = addr
}
return
}
// canonicalHost strips port from host if present and returns the canonicalized // canonicalHost strips port from host if present and returns the canonicalized
// host name. // host name.
func CanonicalHost(host string) (string, error) { func CanonicalHost(host string) (string, error) {

View File

@ -19,6 +19,7 @@ import (
"crypto/rand" "crypto/rand"
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"net"
"strconv" "strconv"
"strings" "strings"
) )
@ -52,7 +53,7 @@ func CanonicalAddr(host string, port int) (addr string) {
if port == 80 || port == 443 { if port == 80 || port == 443 {
addr = host addr = host
} else { } else {
addr = fmt.Sprintf("%s:%d", host, port) addr = net.JoinHostPort(host, strconv.Itoa(port))
} }
return return
} }

View File

@ -59,7 +59,7 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) *
Director: func(req *http.Request) { Director: func(req *http.Request) {
req.URL.Scheme = "http" req.URL.Scheme = "http"
url := req.Context().Value(RouteInfoURL).(string) url := req.Context().Value(RouteInfoURL).(string)
oldHost := util.GetHostFromAddr(req.Context().Value(RouteInfoHost).(string)) oldHost, _ := util.CanonicalHost(req.Context().Value(RouteInfoHost).(string))
rc := rp.GetRouteConfig(oldHost, url) rc := rp.GetRouteConfig(oldHost, url)
if rc != nil { if rc != nil {
if rc.RewriteHost != "" { if rc.RewriteHost != "" {
@ -81,7 +81,7 @@ func NewHTTPReverseProxy(option HTTPReverseProxyOptions, vhostRouter *Routers) *
IdleConnTimeout: 60 * time.Second, IdleConnTimeout: 60 * time.Second,
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
url := ctx.Value(RouteInfoURL).(string) url := ctx.Value(RouteInfoURL).(string)
host := util.GetHostFromAddr(ctx.Value(RouteInfoHost).(string)) host, _ := util.CanonicalHost(ctx.Value(RouteInfoHost).(string))
remote := ctx.Value(RouteInfoRemote).(string) remote := ctx.Value(RouteInfoRemote).(string)
return rp.CreateConnection(host, url, remote) return rp.CreateConnection(host, url, remote)
}, },
@ -191,7 +191,7 @@ func (rp *HTTPReverseProxy) getVhost(domain string, location string) (vr *Router
} }
func (rp *HTTPReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) { func (rp *HTTPReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
domain := util.GetHostFromAddr(req.Host) domain, _ := util.CanonicalHost(req.Host)
location := req.URL.Path location := req.URL.Path
user, passwd, _ := req.BasicAuth() user, passwd, _ := req.BasicAuth()
if !rp.CheckAuth(domain, location, user, passwd) { if !rp.CheckAuth(domain, location, user, passwd) {

View File

@ -15,8 +15,8 @@
package group package group
import ( import (
"fmt"
"net" "net"
"strconv"
"sync" "sync"
"github.com/fatedier/frp/server/ports" "github.com/fatedier/frp/server/ports"
@ -101,7 +101,7 @@ func (tg *TCPGroup) Listen(proxyName string, group string, groupKey string, addr
if err != nil { if err != nil {
return return
} }
tcpLn, errRet := net.Listen("tcp", fmt.Sprintf("%s:%d", addr, port)) tcpLn, errRet := net.Listen("tcp", net.JoinHostPort(addr, strconv.Itoa(port)))
if errRet != nil { if errRet != nil {
err = errRet err = errRet
return return

View File

@ -2,8 +2,8 @@ package ports
import ( import (
"errors" "errors"
"fmt"
"net" "net"
"strconv"
"sync" "sync"
"time" "time"
) )
@ -134,7 +134,7 @@ func (pm *Manager) Acquire(name string, port int) (realPort int, err error) {
func (pm *Manager) isPortAvailable(port int) bool { func (pm *Manager) isPortAvailable(port int) bool {
if pm.netType == "udp" { if pm.netType == "udp" {
addr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", pm.bindAddr, port)) addr, err := net.ResolveUDPAddr("udp", net.JoinHostPort(pm.bindAddr, strconv.Itoa(port)))
if err != nil { if err != nil {
return false return false
} }
@ -146,7 +146,7 @@ func (pm *Manager) isPortAvailable(port int) bool {
return true return true
} }
l, err := net.Listen(pm.netType, fmt.Sprintf("%s:%d", pm.bindAddr, port)) l, err := net.Listen(pm.netType, net.JoinHostPort(pm.bindAddr, strconv.Itoa(port)))
if err != nil { if err != nil {
return false return false
} }

View File

@ -17,6 +17,7 @@ package proxy
import ( import (
"fmt" "fmt"
"net" "net"
"strconv"
"github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/config"
) )
@ -54,7 +55,7 @@ func (pxy *TCPProxy) Run() (remoteAddr string, err error) {
pxy.rc.TCPPortManager.Release(pxy.realPort) pxy.rc.TCPPortManager.Release(pxy.realPort)
} }
}() }()
listener, errRet := net.Listen("tcp", fmt.Sprintf("%s:%d", pxy.serverCfg.ProxyBindAddr, pxy.realPort)) listener, errRet := net.Listen("tcp", net.JoinHostPort(pxy.serverCfg.ProxyBindAddr, strconv.Itoa(pxy.realPort)))
if errRet != nil { if errRet != nil {
err = errRet err = errRet
return return

View File

@ -19,6 +19,7 @@ import (
"fmt" "fmt"
"io" "io"
"net" "net"
"strconv"
"time" "time"
"github.com/fatedier/frp/pkg/config" "github.com/fatedier/frp/pkg/config"
@ -70,7 +71,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", pxy.serverCfg.ProxyBindAddr, pxy.realPort)) addr, errRet := net.ResolveUDPAddr("udp", net.JoinHostPort(pxy.serverCfg.ProxyBindAddr, strconv.Itoa(pxy.realPort)))
if errRet != nil { if errRet != nil {
err = errRet err = errRet
return return

View File

@ -124,7 +124,8 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) {
// Create tcpmux httpconnect multiplexer. // Create tcpmux httpconnect multiplexer.
if cfg.TCPMuxHTTPConnectPort > 0 { if cfg.TCPMuxHTTPConnectPort > 0 {
var l net.Listener var l net.Listener
l, err = net.Listen("tcp", fmt.Sprintf("%s:%d", cfg.ProxyBindAddr, cfg.TCPMuxHTTPConnectPort)) address := net.JoinHostPort(cfg.ProxyBindAddr, strconv.Itoa(cfg.TCPMuxHTTPConnectPort))
l, err = net.Listen("tcp", address)
if err != nil { if err != nil {
err = fmt.Errorf("Create server listener error, %v", err) err = fmt.Errorf("Create server listener error, %v", err)
return return
@ -135,7 +136,7 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) {
err = fmt.Errorf("Create vhost tcpMuxer error, %v", err) err = fmt.Errorf("Create vhost tcpMuxer error, %v", err)
return return
} }
log.Info("tcpmux httpconnect multiplexer listen on %s:%d", cfg.ProxyBindAddr, cfg.TCPMuxHTTPConnectPort) log.Info("tcpmux httpconnect multiplexer listen on %s", address)
} }
// Init all plugins // Init all plugins
@ -199,7 +200,7 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) {
err = fmt.Errorf("Listen on kcp address udp %s error: %v", address, err) err = fmt.Errorf("Listen on kcp address udp %s error: %v", address, err)
return return
} }
log.Info("frps kcp listen on udp %s:%d", cfg.BindAddr, cfg.KCPBindPort) log.Info("frps kcp listen on udp %s", address)
} }
// Listen for accepting connections from client using websocket protocol. // Listen for accepting connections from client using websocket protocol.
@ -232,7 +233,7 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) {
} }
} }
go server.Serve(l) go server.Serve(l)
log.Info("http service listen on %s:%d", cfg.ProxyBindAddr, cfg.VhostHTTPPort) log.Info("http service listen on %s", address)
} }
// Create https vhost muxer. // Create https vhost muxer.
@ -288,7 +289,7 @@ func NewService(cfg config.ServerCommonConf) (svr *Service, err error) {
err = fmt.Errorf("Create dashboard web server error, %v", err) err = fmt.Errorf("Create dashboard web server error, %v", err)
return return
} }
log.Info("Dashboard listen on %s:%d", cfg.DashboardAddr, cfg.DashboardPort) log.Info("Dashboard listen on %s", address)
statsEnable = true statsEnable = true
} }
if statsEnable { if statsEnable {

View File

@ -249,4 +249,24 @@ var _ = Describe("[Feature: Client-Server]", func() {
}) })
} }
}) })
Describe("IPv6 bind address", func() {
supportProtocols := []string{"tcp", "kcp", "websocket"}
for _, protocol := range supportProtocols {
tmp := protocol
defineClientServerTest("IPv6 bind address: "+strings.ToUpper(tmp), f, &generalTestConfigures{
server: fmt.Sprintf(`
bind_addr = ::
kcp_bind_port = {{ .%s }}
protocol = %s
`, consts.PortServerName, protocol),
client: fmt.Sprintf(`
tls_enable = true
protocol = %s
disable_custom_tls_first_byte = true
`, protocol),
})
}
})
}) })

View File

@ -2,7 +2,6 @@ package httpserver
import ( import (
"crypto/tls" "crypto/tls"
"fmt"
"net" "net"
"net/http" "net/http"
"strconv" "strconv"
@ -97,7 +96,7 @@ func (s *Server) Close() error {
} }
func (s *Server) initListener() (err error) { func (s *Server) initListener() (err error) {
s.l, err = net.Listen("tcp", fmt.Sprintf("%s:%d", s.bindAddr, s.bindPort)) s.l, err = net.Listen("tcp", net.JoinHostPort(s.bindAddr, strconv.Itoa(s.bindPort)))
return return
} }

View File

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"io" "io"
"net" "net"
"strconv"
libnet "github.com/fatedier/frp/pkg/util/net" libnet "github.com/fatedier/frp/pkg/util/net"
"github.com/fatedier/frp/test/e2e/pkg/rpc" "github.com/fatedier/frp/test/e2e/pkg/rpc"
@ -99,7 +100,7 @@ func (s *Server) Close() error {
func (s *Server) initListener() (err error) { func (s *Server) initListener() (err error) {
switch s.netType { switch s.netType {
case TCP: case TCP:
s.l, err = net.Listen("tcp", fmt.Sprintf("%s:%d", s.bindAddr, s.bindPort)) s.l, err = net.Listen("tcp", net.JoinHostPort(s.bindAddr, strconv.Itoa(s.bindPort)))
case UDP: case UDP:
s.l, err = libnet.ListenUDP(s.bindAddr, s.bindPort) s.l, err = libnet.ListenUDP(s.bindAddr, s.bindPort)
case Unix: case Unix:

View File

@ -3,6 +3,7 @@ package port
import ( import (
"fmt" "fmt"
"net" "net"
"strconv"
"sync" "sync"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
@ -57,7 +58,7 @@ func (pa *Allocator) GetByName(portName string) int {
return 0 return 0
} }
l, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", port)) l, err := net.Listen("tcp", net.JoinHostPort("127.0.0.1", strconv.Itoa(port)))
if err != nil { if err != nil {
// Maybe not controlled by us, mark it used. // Maybe not controlled by us, mark it used.
pa.used.Insert(port) pa.used.Insert(port)
@ -65,7 +66,7 @@ func (pa *Allocator) GetByName(portName string) int {
} }
l.Close() l.Close()
udpAddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("127.0.0.1:%d", port)) udpAddr, err := net.ResolveUDPAddr("udp", net.JoinHostPort("127.0.0.1", strconv.Itoa(port)))
if err != nil { if err != nil {
continue continue
} }