Fix: multiple port string parsing overflow (#1868)

Ports in TCP and UDP should be parsed as an unsigned integer,
otherwise ports > 32767 get truncated to 32767. As this is
the case with Metadata.UDPAddr(), this fundamentally breaks
UDP connections where demand for high port numbers is high.

This commit fixes all known cases where ParseInt is used for ports,
and has been verified to fix Discord voice connections on port
50001~50004.

Fixes: d40e5e4fe6

Co-authored-by: Hamster Tian <haotia@gmail.com>
This commit is contained in:
gVisor bot 2022-01-02 01:09:29 +08:00
parent 6fa3953335
commit 85f1b22340
3 changed files with 5 additions and 5 deletions

View file

@ -52,7 +52,7 @@ func streamConn(c net.Conn, option streamOption) *snell.Snell {
// StreamConn implements C.ProxyAdapter // StreamConn implements C.ProxyAdapter
func (s *Snell) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) { func (s *Snell) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
c = streamConn(c, streamOption{s.psk, s.version, s.addr, s.obfsOption}) c = streamConn(c, streamOption{s.psk, s.version, s.addr, s.obfsOption})
port, _ := strconv.ParseInt(metadata.DstPort, 10, 16) port, _ := strconv.ParseUint(metadata.DstPort, 10, 16)
err := snell.WriteHeader(c, metadata.String(), uint(port), s.version) err := snell.WriteHeader(c, metadata.String(), uint(port), s.version)
return c, err return c, err
} }

View file

@ -58,11 +58,11 @@ func bindIfaceToDialer(ifaceName string, dialer *net.Dialer, network string, des
return nil return nil
} }
local := int64(0) local := uint64(0)
if dialer.LocalAddr != nil { if dialer.LocalAddr != nil {
_, port, err := net.SplitHostPort(dialer.LocalAddr.String()) _, port, err := net.SplitHostPort(dialer.LocalAddr.String())
if err == nil { if err == nil {
local, _ = strconv.ParseInt(port, 10, 16) local, _ = strconv.ParseUint(port, 10, 16)
} }
} }
@ -82,7 +82,7 @@ func bindIfaceToListenConfig(ifaceName string, _ *net.ListenConfig, network, add
port = "0" port = "0"
} }
local, _ := strconv.ParseInt(port, 10, 16) local, _ := strconv.ParseUint(port, 10, 16)
addr, err := lookupLocalAddr(ifaceName, network, nil, int(local)) addr, err := lookupLocalAddr(ifaceName, network, nil, int(local))
if err != nil { if err != nil {

View file

@ -107,7 +107,7 @@ func (m *Metadata) UDPAddr() *net.UDPAddr {
if m.NetWork != UDP || m.DstIP == nil { if m.NetWork != UDP || m.DstIP == nil {
return nil return nil
} }
port, _ := strconv.ParseInt(m.DstPort, 10, 16) port, _ := strconv.ParseUint(m.DstPort, 10, 16)
return &net.UDPAddr{ return &net.UDPAddr{
IP: m.DstIP, IP: m.DstIP,
Port: int(port), Port: int(port),