diff --git a/go.mod b/go.mod index 68b3789e..904f9ef5 100644 --- a/go.mod +++ b/go.mod @@ -26,12 +26,12 @@ require ( github.com/sagernet/gomobile v0.0.0-20221130124640-349ebaa752ca github.com/sagernet/quic-go v0.0.0-20230202071646-a8c8afb18b32 github.com/sagernet/reality v0.0.0-20230228045158-d3e085a8e5d1 - github.com/sagernet/sing v0.1.8-0.20230301160041-9fab0a9f4304 + github.com/sagernet/sing v0.1.8-0.20230303052048-c875a4ffab1a github.com/sagernet/sing-dns v0.1.4 github.com/sagernet/sing-shadowsocks v0.1.2-0.20230221080503-769c01d6bba9 github.com/sagernet/sing-shadowtls v0.0.0-20230221123345-78e50cd7b587 github.com/sagernet/sing-tun v0.1.2-0.20230226091124-0cdb0eed74d9 - github.com/sagernet/sing-vmess v0.1.2 + github.com/sagernet/sing-vmess v0.1.3-0.20230303082804-627cc46ae68b github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195 github.com/sagernet/tfo-go v0.0.0-20230303015439-ffcfd8c41cf9 github.com/sagernet/utls v0.0.0-20230225061716-536a007c8b01 diff --git a/go.sum b/go.sum index 46fb9ae8..13b9ef42 100644 --- a/go.sum +++ b/go.sum @@ -133,8 +133,8 @@ github.com/sagernet/reality v0.0.0-20230228045158-d3e085a8e5d1 h1:8mSzchN6DkM26J github.com/sagernet/reality v0.0.0-20230228045158-d3e085a8e5d1/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU= github.com/sagernet/sing v0.0.0-20220812082120-05f9836bff8f/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY= github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY= -github.com/sagernet/sing v0.1.8-0.20230301160041-9fab0a9f4304 h1:Yi7wqvHv+ZFLHPQn1DiSAdnMZkb5Cra7Y4s8vzBLrFE= -github.com/sagernet/sing v0.1.8-0.20230301160041-9fab0a9f4304/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk= +github.com/sagernet/sing v0.1.8-0.20230303052048-c875a4ffab1a h1:NvhI/8DMFt2yV3eoYhw6P/XyWzzIKkMiGvFglJbWHWg= +github.com/sagernet/sing v0.1.8-0.20230303052048-c875a4ffab1a/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk= github.com/sagernet/sing-dns v0.1.4 h1:7VxgeoSCiiazDSaXXQVcvrTBxFpOePPq/4XdgnUDN+0= github.com/sagernet/sing-dns v0.1.4/go.mod h1:1+6pCa48B1AI78lD+/i/dLgpw4MwfnsSpZo0Ds8wzzk= github.com/sagernet/sing-shadowsocks v0.1.2-0.20230221080503-769c01d6bba9 h1:qS39eA4C7x+zhEkySbASrtmb6ebdy5v0y2M6mgkmSO0= @@ -143,8 +143,8 @@ github.com/sagernet/sing-shadowtls v0.0.0-20230221123345-78e50cd7b587 h1:OjIXlHT github.com/sagernet/sing-shadowtls v0.0.0-20230221123345-78e50cd7b587/go.mod h1:Kn1VUIprdkwCgkS6SXYaLmIpKzQbqBIKJBMY+RvBhYc= github.com/sagernet/sing-tun v0.1.2-0.20230226091124-0cdb0eed74d9 h1:tq1kc0HFj/jfhLfVC1NJI6lex2g6w2W+gVsFu6H2Kis= github.com/sagernet/sing-tun v0.1.2-0.20230226091124-0cdb0eed74d9/go.mod h1:KnRkwaDHbb06zgeNPu0LQ8A+vA9myMxKEgHN1brCPHg= -github.com/sagernet/sing-vmess v0.1.2 h1:RbOZNAId2LrCai8epMoQXlf0XTrou0bfcw08hNBg6lM= -github.com/sagernet/sing-vmess v0.1.2/go.mod h1:9NSj8mZTx1JIY/HF9LaYRppUsVkysIN5tEFpNZujXxY= +github.com/sagernet/sing-vmess v0.1.3-0.20230303082804-627cc46ae68b h1:NZeF0ATeJwe4W3gTJNeIfTB6yBxai665q1HvDOaWmmU= +github.com/sagernet/sing-vmess v0.1.3-0.20230303082804-627cc46ae68b/go.mod h1:9NSj8mZTx1JIY/HF9LaYRppUsVkysIN5tEFpNZujXxY= github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195 h1:5VBIbVw9q7aKbrFdT83mjkyvQ+VaRsQ6yflTepfln38= github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195/go.mod h1:yedWtra8nyGJ+SyI+ziwuaGMzBatbB10P1IOOZbbSK8= github.com/sagernet/tfo-go v0.0.0-20230303015439-ffcfd8c41cf9 h1:2ItpW1nMNkPzmBTxV0/eClCklHrFSQMnUGcpUmJxVeE= diff --git a/outbound/vless.go b/outbound/vless.go index 1b86bb47..bdae7d90 100644 --- a/outbound/vless.go +++ b/outbound/vless.go @@ -15,6 +15,7 @@ import ( "github.com/sagernet/sing-dns" "github.com/sagernet/sing-vmess/packetaddr" "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/bufio" E "github.com/sagernet/sing/common/exceptions" M "github.com/sagernet/sing/common/metadata" N "github.com/sagernet/sing/common/network" @@ -101,7 +102,17 @@ func (h *VLESS) DialContext(ctx context.Context, network string, destination M.S return h.client.DialEarlyConn(conn, destination) case N.NetworkUDP: h.logger.InfoContext(ctx, "outbound packet connection to ", destination) - return h.client.DialEarlyPacketConn(conn, destination) + if h.xudp { + return h.client.DialEarlyXUDPPacketConn(conn, destination) + } else if h.packetAddr { + packetConn, err := h.client.DialEarlyPacketConn(conn, M.Socksaddr{Fqdn: packetaddr.SeqPacketMagicAddress}) + if err != nil { + return nil, err + } + return &bufio.BindPacketConn{PacketConn: dialer.NewResolvePacketConn(ctx, h.router, dns.DomainStrategyAsIS, packetaddr.NewConn(packetConn, destination)), Addr: destination}, nil + } else { + return h.client.DialEarlyPacketConn(conn, destination) + } default: return nil, E.Extend(N.ErrUnknownNetwork, network) } diff --git a/test/go.mod b/test/go.mod index 6e711e14..22af465a 100644 --- a/test/go.mod +++ b/test/go.mod @@ -10,7 +10,7 @@ require ( github.com/docker/docker v20.10.18+incompatible github.com/docker/go-connections v0.4.0 github.com/gofrs/uuid v4.4.0+incompatible - github.com/sagernet/sing v0.1.8-0.20230301160041-9fab0a9f4304 + github.com/sagernet/sing v0.1.8-0.20230303052048-c875a4ffab1a github.com/sagernet/sing-shadowsocks v0.1.2-0.20230221080503-769c01d6bba9 github.com/spyzhov/ajson v0.7.1 github.com/stretchr/testify v1.8.1 @@ -73,9 +73,9 @@ require ( github.com/sagernet/sing-dns v0.1.4 // indirect github.com/sagernet/sing-shadowtls v0.0.0-20230221123345-78e50cd7b587 // indirect github.com/sagernet/sing-tun v0.1.2-0.20230226091124-0cdb0eed74d9 // indirect - github.com/sagernet/sing-vmess v0.1.2 // indirect + github.com/sagernet/sing-vmess v0.1.3-0.20230303082804-627cc46ae68b // indirect github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195 // indirect - github.com/sagernet/tfo-go v0.0.0-20230207095944-549363a7327d // indirect + github.com/sagernet/tfo-go v0.0.0-20230303015439-ffcfd8c41cf9 // indirect github.com/sagernet/utls v0.0.0-20230225061716-536a007c8b01 // indirect github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e // indirect github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c // indirect diff --git a/test/go.sum b/test/go.sum index 46d3082f..150f79f6 100644 --- a/test/go.sum +++ b/test/go.sum @@ -146,8 +146,8 @@ github.com/sagernet/reality v0.0.0-20230228045158-d3e085a8e5d1 h1:8mSzchN6DkM26J github.com/sagernet/reality v0.0.0-20230228045158-d3e085a8e5d1/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU= github.com/sagernet/sing v0.0.0-20220812082120-05f9836bff8f/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY= github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY= -github.com/sagernet/sing v0.1.8-0.20230301160041-9fab0a9f4304 h1:Yi7wqvHv+ZFLHPQn1DiSAdnMZkb5Cra7Y4s8vzBLrFE= -github.com/sagernet/sing v0.1.8-0.20230301160041-9fab0a9f4304/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk= +github.com/sagernet/sing v0.1.8-0.20230303052048-c875a4ffab1a h1:NvhI/8DMFt2yV3eoYhw6P/XyWzzIKkMiGvFglJbWHWg= +github.com/sagernet/sing v0.1.8-0.20230303052048-c875a4ffab1a/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk= github.com/sagernet/sing-dns v0.1.4 h1:7VxgeoSCiiazDSaXXQVcvrTBxFpOePPq/4XdgnUDN+0= github.com/sagernet/sing-dns v0.1.4/go.mod h1:1+6pCa48B1AI78lD+/i/dLgpw4MwfnsSpZo0Ds8wzzk= github.com/sagernet/sing-shadowsocks v0.1.2-0.20230221080503-769c01d6bba9 h1:qS39eA4C7x+zhEkySbASrtmb6ebdy5v0y2M6mgkmSO0= @@ -156,12 +156,12 @@ github.com/sagernet/sing-shadowtls v0.0.0-20230221123345-78e50cd7b587 h1:OjIXlHT github.com/sagernet/sing-shadowtls v0.0.0-20230221123345-78e50cd7b587/go.mod h1:Kn1VUIprdkwCgkS6SXYaLmIpKzQbqBIKJBMY+RvBhYc= github.com/sagernet/sing-tun v0.1.2-0.20230226091124-0cdb0eed74d9 h1:tq1kc0HFj/jfhLfVC1NJI6lex2g6w2W+gVsFu6H2Kis= github.com/sagernet/sing-tun v0.1.2-0.20230226091124-0cdb0eed74d9/go.mod h1:KnRkwaDHbb06zgeNPu0LQ8A+vA9myMxKEgHN1brCPHg= -github.com/sagernet/sing-vmess v0.1.2 h1:RbOZNAId2LrCai8epMoQXlf0XTrou0bfcw08hNBg6lM= -github.com/sagernet/sing-vmess v0.1.2/go.mod h1:9NSj8mZTx1JIY/HF9LaYRppUsVkysIN5tEFpNZujXxY= +github.com/sagernet/sing-vmess v0.1.3-0.20230303082804-627cc46ae68b h1:NZeF0ATeJwe4W3gTJNeIfTB6yBxai665q1HvDOaWmmU= +github.com/sagernet/sing-vmess v0.1.3-0.20230303082804-627cc46ae68b/go.mod h1:9NSj8mZTx1JIY/HF9LaYRppUsVkysIN5tEFpNZujXxY= github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195 h1:5VBIbVw9q7aKbrFdT83mjkyvQ+VaRsQ6yflTepfln38= github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195/go.mod h1:yedWtra8nyGJ+SyI+ziwuaGMzBatbB10P1IOOZbbSK8= -github.com/sagernet/tfo-go v0.0.0-20230207095944-549363a7327d h1:trP/l6ZPWvQ/5Gv99Z7/t/v8iYy06akDMejxW1sznUk= -github.com/sagernet/tfo-go v0.0.0-20230207095944-549363a7327d/go.mod h1:jk6Ii8Y3En+j2KQDLgdgQGwb3M6y7EL567jFnGYhN9g= +github.com/sagernet/tfo-go v0.0.0-20230303015439-ffcfd8c41cf9 h1:2ItpW1nMNkPzmBTxV0/eClCklHrFSQMnUGcpUmJxVeE= +github.com/sagernet/tfo-go v0.0.0-20230303015439-ffcfd8c41cf9/go.mod h1:FUyTEc5ye5NjKnDTDMuiLF2M6T4BE6y6KZuax//UCEg= github.com/sagernet/utls v0.0.0-20230225061716-536a007c8b01 h1:m4MI13+NRKddIvbdSN0sFHK8w5ROTa60Zi9diZ7EE08= github.com/sagernet/utls v0.0.0-20230225061716-536a007c8b01/go.mod h1:JKQMZq/O2qnZjdrt+B57olmfgEmLtY9iiSIEYtWvoSM= github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e h1:7uw2njHFGE+VpWamge6o56j2RWk4omF6uLKKxMmcWvs= diff --git a/test/vless_test.go b/test/vless_test.go index bd0b6130..49e99f98 100644 --- a/test/vless_test.go +++ b/test/vless_test.go @@ -192,7 +192,7 @@ func testVLESSXray(t *testing.T, packetEncoding string, flow string) { }, }) - testTCP(t, clientPort, testPort) + testSuit(t, clientPort, testPort) } func TestVLESSSelf(t *testing.T) { diff --git a/transport/vless/protocol.go b/transport/vless/protocol.go index 17f18942..60980d61 100644 --- a/transport/vless/protocol.go +++ b/transport/vless/protocol.go @@ -128,7 +128,7 @@ func WriteRequest(writer io.Writer, request Request, payload []byte) error { requestLen += 1 // protobuf length var addonsLen int - if request.Flow != "" { + if request.Command == vmess.CommandTCP && request.Flow != "" { addonsLen += 1 // protobuf header addonsLen += UvarintLen(uint64(len(request.Flow))) addonsLen += len(request.Flow) diff --git a/transport/vless/service.go b/transport/vless/service.go index c25a3e50..7a6cf97d 100644 --- a/transport/vless/service.go +++ b/transport/vless/service.go @@ -68,27 +68,30 @@ func (s *Service[T]) NewConnection(ctx context.Context, conn net.Conn, metadata metadata.Destination = request.Destination userFlow := s.userFlow[user] - if request.Flow != userFlow { - return E.New("flow mismatch: expected ", flowName(userFlow), ", but got ", flowName(request.Flow)) - } - protocolConn := conn - switch userFlow { - case "": - case FlowVision: - protocolConn, err = NewVisionConn(conn, request.UUID, s.logger) - if err != nil { - return E.Cause(err, "initialize vision") + var responseWriter io.Writer + if request.Command == vmess.CommandTCP { + if request.Flow != userFlow { + return E.New("flow mismatch: expected ", flowName(userFlow), ", but got ", flowName(request.Flow)) + } + switch userFlow { + case "": + case FlowVision: + responseWriter = conn + conn, err = NewVisionConn(conn, request.UUID, s.logger) + if err != nil { + return E.Cause(err, "initialize vision") + } } } switch request.Command { case vmess.CommandTCP: - return s.handler.NewConnection(ctx, &serverConn{Conn: protocolConn, responseWriter: conn}, metadata) + return s.handler.NewConnection(ctx, &serverConn{Conn: conn, responseWriter: responseWriter}, metadata) case vmess.CommandUDP: return s.handler.NewPacketConnection(ctx, &serverPacketConn{ExtendedConn: bufio.NewExtendedConn(conn), destination: request.Destination}, metadata) case vmess.CommandMux: - return vmess.HandleMuxConnection(ctx, &serverConn{Conn: conn}, s.handler) + return vmess.HandleMuxConnection(ctx, &serverConn{Conn: conn, responseWriter: responseWriter}, s.handler) default: return E.New("unknown command: ", request.Command) } diff --git a/transport/vless/vision.go b/transport/vless/vision.go index 39593f3a..2b62635c 100644 --- a/transport/vless/vision.go +++ b/transport/vless/vision.go @@ -337,3 +337,7 @@ func (c *VisionConn) unPadding(buffer []byte) [][]byte { } return buffers } + +func (c *VisionConn) Upstream() any { + return c.Conn +}