diff --git a/proxy/socks/client.go b/proxy/socks/client.go index 836caf205..feb6e4ae7 100644 --- a/proxy/socks/client.go +++ b/proxy/socks/client.go @@ -53,14 +53,19 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter if outbound == nil || !outbound.Target.IsValid() { return newError("target not specified.") } + // Destination of the inner request. destination := outbound.Target + // Outbound server. var server *protocol.ServerSpec + // Outbound server's destination. + var dest net.Destination + // Connection to the outbound server. var conn internet.Connection if err := retry.ExponentialBackoff(5, 100).On(func() error { server = c.serverPicker.PickServer() - dest := server.Destination() + dest = server.Destination() rawConn, err := dialer.Dial(ctx, dest) if err != nil { return err @@ -103,6 +108,11 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter if err != nil { return newError("failed to establish connection to server").AtWarning().Base(err) } + if udpRequest != nil { + if udpRequest.Address == net.AnyIP || udpRequest.Address == net.AnyIPv6 { + udpRequest.Address = dest.Address + } + } if err := conn.SetDeadline(time.Time{}); err != nil { newError("failed to clear deadline after handshake").Base(err).WriteToLog(session.ExportIDToError(ctx)) diff --git a/proxy/socks/protocol.go b/proxy/socks/protocol.go index 47ad3f30f..9fb268c5d 100644 --- a/proxy/socks/protocol.go +++ b/proxy/socks/protocol.go @@ -18,7 +18,7 @@ const ( cmdTCPConnect = 0x01 cmdTCPBind = 0x02 - cmdUDPPort = 0x03 + cmdUDPAssociate = 0x03 cmdTorResolve = 0xF0 cmdTorResolvePTR = 0xF1 @@ -164,7 +164,7 @@ func (s *ServerSession) handshake5(nMethod byte, reader io.Reader, writer io.Wri case cmdTCPConnect, cmdTorResolve, cmdTorResolvePTR: // We don't have a solution for Tor case now. Simply treat it as connect command. request.Command = protocol.RequestCommandTCP - case cmdUDPPort: + case cmdUDPAssociate: if !s.config.UdpEnabled { writeSocks5Response(writer, statusCmdNotSupport, net.AnyIP, net.Port(0)) return nil, newError("UDP is not enabled.") @@ -448,7 +448,7 @@ func ClientHandshake(request *protocol.RequestHeader, reader io.Reader, writer i command := byte(cmdTCPConnect) if request.Command == protocol.RequestCommandUDP { - command = byte(cmdUDPPort) + command = byte(cmdUDPAssociate) } common.Must2(b.Write([]byte{socks5Version, command, 0x00 /* reserved */})) if err := addrParser.WriteAddressPort(b, request.Address, request.Port); err != nil {