瀏覽代碼

Fix fallbacks xver when original address is not TCP address (#182)

Co-authored-by: RPRX <[email protected]>
Bohan Yang 4 年之前
父節點
當前提交
5bc1bf30ae
共有 4 個文件被更改,包括 65 次插入40 次删除
  1. 1 1
      go.mod
  2. 2 2
      go.sum
  3. 31 18
      proxy/trojan/server.go
  4. 31 19
      proxy/vless/inbound/inbound.go

+ 1 - 1
go.mod

@@ -11,7 +11,7 @@ require (
 	github.com/lucas-clemente/quic-go v0.19.3
 	github.com/lucas-clemente/quic-go v0.19.3
 	github.com/miekg/dns v1.1.35
 	github.com/miekg/dns v1.1.35
 	github.com/pelletier/go-toml v1.8.1
 	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/seiflotfy/cuckoofilter v0.0.0-20201222105146-bc6005554a0c
 	github.com/stretchr/testify v1.7.0
 	github.com/stretchr/testify v1.7.0
 	github.com/xtls/go v0.0.0-20201118062508-3632bf3b7499
 	github.com/xtls/go v0.0.0-20201118062508-3632bf3b7499

+ 2 - 2
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/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 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc=
 github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
 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/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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=

+ 31 - 18
proxy/trojan/server.go

@@ -500,38 +500,51 @@ func (s *Server) fallback(ctx context.Context, sid errors.ExportOption, err erro
 	postRequest := func() error {
 	postRequest := func() error {
 		defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)
 		defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)
 		if fb.Xver != 0 {
 		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()
 			pro := buf.New()
 			defer pro.Release()
 			defer pro.Release()
 			switch fb.Xver {
 			switch fb.Xver {
 			case 1:
 			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")))
 					common.Must2(pro.Write([]byte("PROXY TCP4 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n")))
 				} else {
 				} else {
 					common.Must2(pro.Write([]byte("PROXY TCP6 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n")))
 					common.Must2(pro.Write([]byte("PROXY TCP6 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n")))
 				}
 				}
 			case 2:
 			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(remoteAddr).To4()))
 					common.Must2(pro.Write(net.ParseIP(localAddr).To4()))
 					common.Must2(pro.Write(net.ParseIP(localAddr).To4()))
 				} else {
 				} 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(remoteAddr).To16()))
 					common.Must2(pro.Write(net.ParseIP(localAddr).To16()))
 					common.Must2(pro.Write(net.ParseIP(localAddr).To16()))
 				}
 				}

+ 31 - 19
proxy/vless/inbound/inbound.go

@@ -335,39 +335,51 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection i
 			postRequest := func() error {
 			postRequest := func() error {
 				defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)
 				defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)
 				if fb.Xver != 0 {
 				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()
 					pro := buf.New()
 					defer pro.Release()
 					defer pro.Release()
 					switch fb.Xver {
 					switch fb.Xver {
 					case 1:
 					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"))
 							pro.Write([]byte("PROXY TCP4 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n"))
 						} else {
 						} else {
 							pro.Write([]byte("PROXY TCP6 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n"))
 							pro.Write([]byte("PROXY TCP6 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n"))
 						}
 						}
-
 					case 2:
 					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(remoteAddr).To4())
 							pro.Write(net.ParseIP(localAddr).To4())
 							pro.Write(net.ParseIP(localAddr).To4())
 						} else {
 						} 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(remoteAddr).To16())
 							pro.Write(net.ParseIP(localAddr).To16())
 							pro.Write(net.ParseIP(localAddr).To16())
 						}
 						}