From 8679968ab0a3112cfe4368118626e879609bfe67 Mon Sep 17 00:00:00 2001 From: HamsterReserved Date: Sun, 2 Jan 2022 01:09:29 +0800 Subject: [PATCH] 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: d40e5e4fe6c11311ee1de82779a985c3ca47d03a Co-authored-by: Hamster Tian --- adapter/outbound/snell.go | 2 +- component/dialer/bind_others.go | 6 +++--- constant/metadata.go | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/adapter/outbound/snell.go b/adapter/outbound/snell.go index d0a26ecc..3b0dd4bc 100644 --- a/adapter/outbound/snell.go +++ b/adapter/outbound/snell.go @@ -52,7 +52,7 @@ func streamConn(c net.Conn, option streamOption) *snell.Snell { // StreamConn implements C.ProxyAdapter 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}) - port, _ := strconv.ParseInt(metadata.DstPort, 10, 16) + port, _ := strconv.ParseUint(metadata.DstPort, 10, 16) err := snell.WriteHeader(c, metadata.String(), uint(port), s.version) return c, err } diff --git a/component/dialer/bind_others.go b/component/dialer/bind_others.go index a74995b5..2cabb48a 100644 --- a/component/dialer/bind_others.go +++ b/component/dialer/bind_others.go @@ -58,11 +58,11 @@ func bindIfaceToDialer(ifaceName string, dialer *net.Dialer, network string, des return nil } - local := int64(0) + local := uint64(0) if dialer.LocalAddr != nil { _, port, err := net.SplitHostPort(dialer.LocalAddr.String()) 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" } - local, _ := strconv.ParseInt(port, 10, 16) + local, _ := strconv.ParseUint(port, 10, 16) addr, err := lookupLocalAddr(ifaceName, network, nil, int(local)) if err != nil { diff --git a/constant/metadata.go b/constant/metadata.go index 9cc49973..a911b5e8 100644 --- a/constant/metadata.go +++ b/constant/metadata.go @@ -107,7 +107,7 @@ func (m *Metadata) UDPAddr() *net.UDPAddr { if m.NetWork != UDP || m.DstIP == nil { return nil } - port, _ := strconv.ParseInt(m.DstPort, 10, 16) + port, _ := strconv.ParseUint(m.DstPort, 10, 16) return &net.UDPAddr{ IP: m.DstIP, Port: int(port),