1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-12-21 17:46:58 -05:00

🎳 Refine socks5 server UdpAssociate response behavior (#523)

- Previously, without specifying the server IP, the remote address in the response to a UdpAssoicate command is `127.0.0.1`, which might break UDP for non-localhost clients.
- This commit changes it so that, localhost clients get responses with the corresponding loopback IP, non-localhost clients get responses with the corresponding `net.AnyIP` or `net.AnyIPv6`.
- The new behavior is also consistent with many other implementations. So the compatibility is guaranteed. It also makes specifying server IP optional.
This commit is contained in:
database64128 2020-12-16 16:39:14 +08:00 committed by GitHub
parent eed3f5a13f
commit 29f16cd054
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 11 deletions

View File

@ -41,8 +41,10 @@ var addrParser = protocol.NewAddressParser(
) )
type ServerSession struct { type ServerSession struct {
config *ServerConfig config *ServerConfig
port net.Port address net.Address
port net.Port
clientAddress net.Address
} }
func (s *ServerSession) handshake4(cmd byte, reader io.Reader, writer io.Writer) (*protocol.RequestHeader, error) { func (s *ServerSession) handshake4(cmd byte, reader io.Reader, writer io.Writer) (*protocol.RequestHeader, error) {
@ -187,15 +189,20 @@ func (s *ServerSession) handshake5(nMethod byte, reader io.Reader, writer io.Wri
request.Address = addr request.Address = addr
request.Port = port request.Port = port
responseAddress := net.AnyIP responseAddress := s.address
responsePort := net.Port(1717) responsePort := s.port
//nolint:gocritic // Use if else chain for clarity
if request.Command == protocol.RequestCommandUDP { if request.Command == protocol.RequestCommandUDP {
addr := s.config.Address.AsAddress() if s.config.Address != nil {
if addr == nil { // Use configured IP as remote address in the response to UdpAssociate
addr = net.LocalHostIP responseAddress = s.config.Address.AsAddress()
} else if s.clientAddress == net.LocalHostIP || s.clientAddress == net.LocalHostIPv6 {
// For localhost clients use loopback IP
responseAddress = s.clientAddress
} else {
// For non-localhost clients use inbound listening address
responseAddress = s.address
} }
responseAddress = addr
responsePort = s.port
} }
if err := writeSocks5Response(writer, statusSuccess, responseAddress, responsePort); err != nil { if err := writeSocks5Response(writer, statusSuccess, responseAddress, responsePort); err != nil {
return nil, err return nil, err

View File

@ -91,8 +91,10 @@ func (s *Server) processTCP(ctx context.Context, conn internet.Connection, dispa
} }
svrSession := &ServerSession{ svrSession := &ServerSession{
config: s.config, config: s.config,
port: inbound.Gateway.Port, address: inbound.Gateway.Address,
port: inbound.Gateway.Port,
clientAddress: inbound.Source.Address,
} }
reader := &buf.BufferedReader{Reader: buf.NewReader(conn)} reader := &buf.BufferedReader{Reader: buf.NewReader(conn)}