|
9 | 9 |
|
10 | 10 | "github.com/sagernet/sing/common" |
11 | 11 | "github.com/sagernet/sing/common/auth" |
| 12 | + "github.com/sagernet/sing/common/buf" |
| 13 | + "github.com/sagernet/sing/common/bufio" |
12 | 14 | E "github.com/sagernet/sing/common/exceptions" |
13 | 15 | M "github.com/sagernet/sing/common/metadata" |
14 | 16 | N "github.com/sagernet/sing/common/network" |
@@ -76,6 +78,9 @@ func ClientHandshake5(conn io.ReadWriter, command byte, destination M.Socksaddr, |
76 | 78 | } else if authResponse.Method != socks5.AuthTypeNotRequired { |
77 | 79 | return socks5.Response{}, E.New("socks5: unsupported auth method: ", authResponse.Method) |
78 | 80 | } |
| 81 | + if command == socks5.CommandUDPAssociate { |
| 82 | + destination = M.SocksaddrFrom(netip.IPv4Unspecified(), 0) |
| 83 | + } |
79 | 84 | err = socks5.WriteRequest(conn, socks5.Request{ |
80 | 85 | Command: command, |
81 | 86 | Destination: destination, |
@@ -215,13 +220,20 @@ func HandleConnection0(ctx context.Context, conn net.Conn, version byte, authent |
215 | 220 | if err != nil { |
216 | 221 | return err |
217 | 222 | } |
218 | | - metadata.Protocol = "socks5" |
219 | | - metadata.Destination = request.Destination |
220 | 223 | var innerError error |
221 | 224 | done := make(chan struct{}) |
222 | 225 | associatePacketConn := NewAssociatePacketConn(udpConn, request.Destination, conn) |
| 226 | + buffer := buf.NewPacket() |
| 227 | + defer buffer.Release() |
| 228 | + destination, err := associatePacketConn.ReadPacket(buffer) |
| 229 | + if buffer.IsEmpty() { |
| 230 | + return err |
| 231 | + } |
| 232 | + request.Destination = destination |
| 233 | + metadata.Protocol = "socks5" |
| 234 | + metadata.Destination = request.Destination |
223 | 235 | go func() { |
224 | | - innerError = handler.NewPacketConnection(ctx, associatePacketConn, metadata) |
| 236 | + innerError = handler.NewPacketConnection(ctx, bufio.NewCachedPacketConn(associatePacketConn, buffer, destination), metadata) |
225 | 237 | close(done) |
226 | 238 | }() |
227 | 239 | err = common.Error(io.Copy(io.Discard, conn)) |
|
0 commit comments