Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions internal/server/transport/kcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -572,12 +572,7 @@ func (s *KcpTransport) parsePortMappings(g *kcpGen) {
continue
}

port, err := strconv.Atoi(localPortOrRange)
if err == nil && port > 1 && port < 65535 { // format port=remoteAddress
localAddr = fmt.Sprintf(":%d", port)
} else {
localAddr = localPortOrRange // format ip:port=remoteAddress
}
localAddr = mappingListenAddress(localPortOrRange)
} else {
s.logger.Fatalf("invalid port mapping format: %s", portMapping)
}
Expand Down
19 changes: 19 additions & 0 deletions internal/server/transport/portmapping.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package transport

import (
"fmt"
"strconv"
"strings"
)

// mappingListenAddress converts the numeric shorthand used by forwarded-port
// mappings into a wildcard listen address. Non-numeric values are already full
// listen addresses and are returned unchanged.
func mappingListenAddress(value string) string {
value = strings.TrimSpace(value)
port, err := strconv.Atoi(value)
if err == nil && port >= 1 && port <= 65535 {
return fmt.Sprintf(":%d", port)
}
return value
}
28 changes: 28 additions & 0 deletions internal/server/transport/portmapping_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package transport

import "testing"

func TestMappingListenAddress(t *testing.T) {
tests := []struct {
name string
value string
want string
}{
{"lowest port", "1", ":1"},
{"highest port", "65535", ":65535"},
{"typical port", "443", ":443"},
{"whitespace", " 443 ", ":443"},
{"IPv4 address", "127.0.0.1:443", "127.0.0.1:443"},
{"IPv6 address", "[::1]:443", "[::1]:443"},
{"below range", "0", "0"},
{"above range", "65536", "65536"},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := mappingListenAddress(tt.value); got != tt.want {
t.Fatalf("mappingListenAddress(%q) = %q, want %q", tt.value, got, tt.want)
}
})
}
}
7 changes: 1 addition & 6 deletions internal/server/transport/quic.go
Original file line number Diff line number Diff line change
Expand Up @@ -459,12 +459,7 @@ func (s *QuicTransport) parsePortMappings(g *quicGen) {
continue
}

port, err := strconv.Atoi(localPortOrRange)
if err == nil && port > 1 && port < 65535 { // format port=remoteAddress
localAddr = fmt.Sprintf(":%d", port)
} else {
localAddr = localPortOrRange // format ip:port=remoteAddress
}
localAddr = mappingListenAddress(localPortOrRange)
} else {
s.logger.Fatalf("invalid port mapping format: %s", portMapping)
}
Expand Down
7 changes: 1 addition & 6 deletions internal/server/transport/tcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -577,12 +577,7 @@ func (s *TcpTransport) parsePortMappings(g *tcpGen) {
continue
} else {
// Handle single local port case
port, err := strconv.Atoi(localPortOrRange)
if err == nil && port > 1 && port < 65535 { // format port=remoteAddress
localAddr = fmt.Sprintf(":%d", port)
} else {
localAddr = localPortOrRange // format ip:port=remoteAddress
}
localAddr = mappingListenAddress(localPortOrRange)
}
} else {
s.logger.Fatalf("invalid port mapping format: %s", portMapping)
Expand Down
7 changes: 1 addition & 6 deletions internal/server/transport/tcpmux.go
Original file line number Diff line number Diff line change
Expand Up @@ -601,12 +601,7 @@ func (s *TcpMuxTransport) parsePortMappings(g *tcpMuxGen) {
continue
} else {
// Handle single local port case
port, err := strconv.Atoi(localPortOrRange)
if err == nil && port > 1 && port < 65535 { // format port=remoteAddress
localAddr = fmt.Sprintf(":%d", port)
} else {
localAddr = localPortOrRange // format ip:port=remoteAddress
}
localAddr = mappingListenAddress(localPortOrRange)
}
} else {
s.logger.Fatalf("invalid port mapping format: %s", portMapping)
Expand Down
7 changes: 1 addition & 6 deletions internal/server/transport/udp.go
Original file line number Diff line number Diff line change
Expand Up @@ -536,12 +536,7 @@ func (s *UdpTransport) parsePortMappings(g *udpGen) {
continue
} else {
// Handle single local port case
port, err := strconv.Atoi(localPortOrRange)
if err == nil && port > 1 && port < 65535 { // format port=remoteAddress
localAddr = fmt.Sprintf(":%d", port)
} else {
localAddr = localPortOrRange // format ip:port=remoteAddress
}
localAddr = mappingListenAddress(localPortOrRange)
}
} else {
s.logger.Fatalf("invalid port mapping format: %s", portMapping)
Expand Down
7 changes: 1 addition & 6 deletions internal/server/transport/ws.go
Original file line number Diff line number Diff line change
Expand Up @@ -451,12 +451,7 @@ func (s *WsTransport) parsePortMappings(g *wsGen) {
continue
} else {
// Handle single local port case
port, err := strconv.Atoi(localPortOrRange)
if err == nil && port > 1 && port < 65535 { // format port=remoteAddress
localAddr = fmt.Sprintf(":%d", port)
} else {
localAddr = localPortOrRange // format ip:port=remoteAddress
}
localAddr = mappingListenAddress(localPortOrRange)
}
} else {
s.logger.Fatalf("invalid port mapping format: %s", portMapping)
Expand Down
7 changes: 1 addition & 6 deletions internal/server/transport/wsmux.go
Original file line number Diff line number Diff line change
Expand Up @@ -476,12 +476,7 @@ func (s *WsMuxTransport) parsePortMappings(g *wsMuxGen) {
continue
} else {
// Handle single local port case
port, err := strconv.Atoi(localPortOrRange)
if err == nil && port > 1 && port < 65535 { // format port=remoteAddress
localAddr = fmt.Sprintf(":%d", port)
} else {
localAddr = localPortOrRange // format ip:port=remoteAddress
}
localAddr = mappingListenAddress(localPortOrRange)
}
} else {
s.logger.Fatalf("invalid port mapping format: %s", portMapping)
Expand Down