From 5bc1bf30ae08b14525f0eda326df65df52e794fb Mon Sep 17 00:00:00 2001 From: Bohan Yang Date: Fri, 22 Jan 2021 11:26:57 +0800 Subject: [PATCH] Fix fallbacks xver when original address is not TCP address (#182) Co-authored-by: RPRX <63339210+rprx@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 +-- proxy/trojan/server.go | 49 +++++++++++++++++++++------------ proxy/vless/inbound/inbound.go | 50 +++++++++++++++++++++------------- 4 files changed, 65 insertions(+), 40 deletions(-) diff --git a/go.mod b/go.mod index 57799448..f0bc2ce0 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/lucas-clemente/quic-go v0.19.3 github.com/miekg/dns v1.1.35 github.com/pelletier/go-toml v1.8.1 - github.com/pires/go-proxyproto v0.3.3 + github.com/pires/go-proxyproto v0.4.1 github.com/seiflotfy/cuckoofilter v0.0.0-20201222105146-bc6005554a0c github.com/stretchr/testify v1.7.0 github.com/xtls/go v0.0.0-20201118062508-3632bf3b7499 diff --git a/go.sum b/go.sum index 7607b5e3..f844a4be 100644 --- a/go.sum +++ b/go.sum @@ -127,8 +127,8 @@ github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNC github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc= github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= -github.com/pires/go-proxyproto v0.3.3 h1:jOXGrsAfSQVFiD1hWg1aiHpLYsd6SJw/8cLN594sB7Q= -github.com/pires/go-proxyproto v0.3.3/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= +github.com/pires/go-proxyproto v0.4.1 h1:30QkyOjKU3FcTLiu1359sSQ7ml56wpM4i/uViqODSsI= +github.com/pires/go-proxyproto v0.4.1/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= diff --git a/proxy/trojan/server.go b/proxy/trojan/server.go index 4871524f..1d64b442 100644 --- a/proxy/trojan/server.go +++ b/proxy/trojan/server.go @@ -500,38 +500,51 @@ func (s *Server) fallback(ctx context.Context, sid errors.ExportOption, err erro postRequest := func() error { defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly) if fb.Xver != 0 { - remoteAddr, remotePort, err := net.SplitHostPort(connection.RemoteAddr().String()) - if err != nil { - return err - } - localAddr, localPort, err := net.SplitHostPort(connection.LocalAddr().String()) - if err != nil { - return err - } - ipv4 := true - for i := 0; i < len(remoteAddr); i++ { - if remoteAddr[i] == ':' { - ipv4 = false - break + var remoteAddr, remotePort, localAddr, localPort string + ipType, network := 0, connection.RemoteAddr().Network() + if len(network) >= 3 && network[:3] == "tcp" { + var err error + remoteAddr, remotePort, err = net.SplitHostPort(connection.RemoteAddr().String()) + if err != nil { + return err + } + localAddr, localPort, err = net.SplitHostPort(connection.LocalAddr().String()) + if err != nil { + return err + } + ipType = 4 + for i := 0; i < len(remoteAddr); i++ { + if remoteAddr[i] == ':' { + ipType = 6 + break + } } } pro := buf.New() defer pro.Release() switch fb.Xver { case 1: - if ipv4 { + if ipType == 0 { + common.Must2(pro.Write([]byte("PROXY UNKNOWN\r\n"))) + break + } + if ipType == 4 { common.Must2(pro.Write([]byte("PROXY TCP4 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n"))) } else { common.Must2(pro.Write([]byte("PROXY TCP6 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n"))) } case 2: - common.Must2(pro.Write([]byte("\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A\x21"))) // signature + v2 + PROXY - if ipv4 { - common.Must2(pro.Write([]byte("\x11\x00\x0C"))) // AF_INET + STREAM + 12 bytes + common.Must2(pro.Write([]byte("\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A"))) // signature + if ipType == 0 { + common.Must2(pro.Write([]byte("\x20\x00\x00\x00"))) // v2 + LOCAL + UNSPEC + UNSPEC + 0 bytes + break + } + if ipType == 4 { + common.Must2(pro.Write([]byte("\x21\x11\x00\x0C"))) // v2 + PROXY + AF_INET + STREAM + 12 bytes common.Must2(pro.Write(net.ParseIP(remoteAddr).To4())) common.Must2(pro.Write(net.ParseIP(localAddr).To4())) } else { - common.Must2(pro.Write([]byte("\x21\x00\x24"))) // AF_INET6 + STREAM + 36 bytes + common.Must2(pro.Write([]byte("\x21\x21\x00\x24"))) // v2 + PROXY + AF_INET6 + STREAM + 36 bytes common.Must2(pro.Write(net.ParseIP(remoteAddr).To16())) common.Must2(pro.Write(net.ParseIP(localAddr).To16())) } diff --git a/proxy/vless/inbound/inbound.go b/proxy/vless/inbound/inbound.go index 8766d391..d73107d1 100644 --- a/proxy/vless/inbound/inbound.go +++ b/proxy/vless/inbound/inbound.go @@ -335,39 +335,51 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection i postRequest := func() error { defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly) if fb.Xver != 0 { - remoteAddr, remotePort, err := net.SplitHostPort(connection.RemoteAddr().String()) - if err != nil { - return err - } - localAddr, localPort, err := net.SplitHostPort(connection.LocalAddr().String()) - if err != nil { - return err - } - ipv4 := true - for i := 0; i < len(remoteAddr); i++ { - if remoteAddr[i] == ':' { - ipv4 = false - break + var remoteAddr, remotePort, localAddr, localPort string + ipType, network := 0, connection.RemoteAddr().Network() + if len(network) >= 3 && network[:3] == "tcp" { + var err error + remoteAddr, remotePort, err = net.SplitHostPort(connection.RemoteAddr().String()) + if err != nil { + return err + } + localAddr, localPort, err = net.SplitHostPort(connection.LocalAddr().String()) + if err != nil { + return err + } + ipType = 4 + for i := 0; i < len(remoteAddr); i++ { + if remoteAddr[i] == ':' { + ipType = 6 + break + } } } pro := buf.New() defer pro.Release() switch fb.Xver { case 1: - if ipv4 { + if ipType == 0 { + pro.Write([]byte("PROXY UNKNOWN\r\n")) + break + } + if ipType == 4 { pro.Write([]byte("PROXY TCP4 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n")) } else { pro.Write([]byte("PROXY TCP6 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n")) } - case 2: - pro.Write([]byte("\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A\x21")) // signature + v2 + PROXY - if ipv4 { - pro.Write([]byte("\x11\x00\x0C")) // AF_INET + STREAM + 12 bytes + pro.Write([]byte("\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A")) // signature + if ipType == 0 { + pro.Write([]byte("\x20\x00\x00\x00")) // v2 + LOCAL + UNSPEC + UNSPEC + 0 bytes + break + } + if ipType == 4 { + pro.Write([]byte("\x21\x11\x00\x0C")) // v2 + PROXY + AF_INET + STREAM + 12 bytes pro.Write(net.ParseIP(remoteAddr).To4()) pro.Write(net.ParseIP(localAddr).To4()) } else { - pro.Write([]byte("\x21\x00\x24")) // AF_INET6 + STREAM + 36 bytes + pro.Write([]byte("\x21\x21\x00\x24")) // v2 + PROXY + AF_INET6 + STREAM + 36 bytes pro.Write(net.ParseIP(remoteAddr).To16()) pro.Write(net.ParseIP(localAddr).To16()) }