mirror of
https://github.com/v2fly/v2ray-core.git
synced 2025-02-20 23:47:21 -05:00
🧦 Fix socks client UDP outbound's wrong destination (#522)
- When you connect to a non-localhost socks5 server, in the response of a UdpAssociate from a socks5 server, the remote address may be `::` or `0.0.0.0`. The previous behavior is to connect to the remote address in the response, which obviously fails. - This commit changes the behavior to dial to the outbound server's address when the remote address in the response is `::` or `0.0.0.0`. - Rename `cmdUDPPort` to `cmdUDPAssociate` for clarity.
This commit is contained in:
parent
d9db22093b
commit
0eccf52399
@ -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))
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user