Skip to content

Commit 80d3f33

Browse files
authored
xtcp: add configuration to disable assisted addresses in NAT traversal (#4951)
1 parent 14253af commit 80d3f33

File tree

8 files changed

+63
-11
lines changed

8 files changed

+63
-11
lines changed

Release.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
11
## Features
22

3-
* Support tokenSource for loading authentication tokens from files.
4-
5-
## Fixes
6-
7-
* Fix SSH tunnel gateway incorrectly binding to proxyBindAddr instead of bindAddr, which caused external connections to fail when proxyBindAddr was set to 127.0.0.1.
3+
* Add NAT traversal configuration options for XTCP proxies and visitors. Support disabling assisted addresses to avoid using slow VPN connections during NAT hole punching.

client/proxy/xtcp.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,19 @@ func (pxy *XTCPProxy) InWorkConn(conn net.Conn, startWorkConnMsg *msg.StartWorkC
6464
}
6565

6666
xl.Tracef("nathole prepare start")
67-
prepareResult, err := nathole.Prepare([]string{pxy.clientCfg.NatHoleSTUNServer})
67+
68+
// Prepare NAT traversal options
69+
var opts nathole.PrepareOptions
70+
if pxy.cfg.NatTraversal != nil && pxy.cfg.NatTraversal.DisableAssistedAddrs {
71+
opts.DisableAssistedAddrs = true
72+
}
73+
74+
prepareResult, err := nathole.Prepare([]string{pxy.clientCfg.NatHoleSTUNServer}, opts)
6875
if err != nil {
6976
xl.Warnf("nathole prepare error: %v", err)
7077
return
7178
}
79+
7280
xl.Infof("nathole prepare success, nat type: %s, behavior: %s, addresses: %v, assistedAddresses: %v",
7381
prepareResult.NatType, prepareResult.Behavior, prepareResult.Addrs, prepareResult.AssistedAddrs)
7482
defer prepareResult.ListenConn.Close()

client/visitor/xtcp.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,11 +276,19 @@ func (sv *XTCPVisitor) makeNatHole() {
276276
}
277277

278278
xl.Tracef("nathole prepare start")
279-
prepareResult, err := nathole.Prepare([]string{sv.clientCfg.NatHoleSTUNServer})
279+
280+
// Prepare NAT traversal options
281+
var opts nathole.PrepareOptions
282+
if sv.cfg.NatTraversal != nil && sv.cfg.NatTraversal.DisableAssistedAddrs {
283+
opts.DisableAssistedAddrs = true
284+
}
285+
286+
prepareResult, err := nathole.Prepare([]string{sv.clientCfg.NatHoleSTUNServer}, opts)
280287
if err != nil {
281288
xl.Warnf("nathole prepare error: %v", err)
282289
return
283290
}
291+
284292
xl.Infof("nathole prepare success, nat type: %s, behavior: %s, addresses: %v, assistedAddresses: %v",
285293
prepareResult.NatType, prepareResult.Behavior, prepareResult.Addrs, prepareResult.AssistedAddrs)
286294

conf/frpc_full_example.toml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,14 @@ localPort = 22
372372
# Otherwise, visitors from same user can connect. '*' means allow all users.
373373
allowUsers = ["user1", "user2"]
374374

375+
# NAT traversal configuration (optional)
376+
[proxies.natTraversal]
377+
# Disable the use of local network interfaces (assisted addresses) for NAT traversal.
378+
# When enabled, only STUN-discovered public addresses will be used.
379+
# This can improve performance when you have slow VPN connections.
380+
# Default: false
381+
disableAssistedAddrs = false
382+
375383
[[proxies]]
376384
name = "vnet-server"
377385
type = "stcp"
@@ -411,6 +419,13 @@ minRetryInterval = 90
411419
# fallbackTo = "stcp_visitor"
412420
# fallbackTimeoutMs = 500
413421

422+
# NAT traversal configuration (optional)
423+
[visitors.natTraversal]
424+
# Disable the use of local network interfaces (assisted addresses) for NAT traversal.
425+
# When enabled, only STUN-discovered public addresses will be used.
426+
# Default: false
427+
disableAssistedAddrs = false
428+
414429
[[visitors]]
415430
name = "vnet-visitor"
416431
type = "stcp"

pkg/config/v1/common.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,14 @@ type TLSConfig struct {
9696
ServerName string `json:"serverName,omitempty"`
9797
}
9898

99+
// NatTraversalConfig defines configuration options for NAT traversal
100+
type NatTraversalConfig struct {
101+
// DisableAssistedAddrs disables the use of local network interfaces
102+
// for assisted connections during NAT traversal. When enabled,
103+
// only STUN-discovered public addresses will be used.
104+
DisableAssistedAddrs bool `json:"disableAssistedAddrs,omitempty"`
105+
}
106+
99107
type LogConfig struct {
100108
// This is destination where frp should write the logs.
101109
// If "console" is used, logs will be printed to stdout, otherwise,

pkg/config/v1/proxy.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,9 @@ type XTCPProxyConfig struct {
422422

423423
Secretkey string `json:"secretKey,omitempty"`
424424
AllowUsers []string `json:"allowUsers,omitempty"`
425+
426+
// NatTraversal configuration for NAT traversal
427+
NatTraversal *NatTraversalConfig `json:"natTraversal,omitempty"`
425428
}
426429

427430
func (c *XTCPProxyConfig) MarshalToMsg(m *msg.NewProxy) {

pkg/config/v1/visitor.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,9 @@ type XTCPVisitorConfig struct {
160160
MinRetryInterval int `json:"minRetryInterval,omitempty"`
161161
FallbackTo string `json:"fallbackTo,omitempty"`
162162
FallbackTimeoutMs int `json:"fallbackTimeoutMs,omitempty"`
163+
164+
// NatTraversal configuration for NAT traversal
165+
NatTraversal *NatTraversalConfig `json:"natTraversal,omitempty"`
163166
}
164167

165168
func (c *XTCPVisitorConfig) Complete(g *ClientCommonConfig) {

pkg/nathole/nathole.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,13 @@ var (
6868
DetectRoleReceiver = "receiver"
6969
)
7070

71+
// PrepareOptions defines options for NAT traversal preparation
72+
type PrepareOptions struct {
73+
// DisableAssistedAddrs disables the use of local network interfaces
74+
// for assisted connections during NAT traversal
75+
DisableAssistedAddrs bool
76+
}
77+
7178
type PrepareResult struct {
7279
Addrs []string
7380
AssistedAddrs []string
@@ -108,7 +115,7 @@ func PreCheck(
108115
}
109116

110117
// Prepare is used to do some preparation work before penetration.
111-
func Prepare(stunServers []string) (*PrepareResult, error) {
118+
func Prepare(stunServers []string, opts PrepareOptions) (*PrepareResult, error) {
112119
// discover for Nat type
113120
addrs, localAddr, err := Discover(stunServers, "")
114121
if err != nil {
@@ -133,9 +140,13 @@ func Prepare(stunServers []string) (*PrepareResult, error) {
133140
return nil, fmt.Errorf("listen local udp addr error: %v", err)
134141
}
135142

136-
assistedAddrs := make([]string, 0, len(localIPs))
137-
for _, ip := range localIPs {
138-
assistedAddrs = append(assistedAddrs, net.JoinHostPort(ip, strconv.Itoa(laddr.Port)))
143+
// Apply NAT traversal options
144+
var assistedAddrs []string
145+
if !opts.DisableAssistedAddrs {
146+
assistedAddrs = make([]string, 0, len(localIPs))
147+
for _, ip := range localIPs {
148+
assistedAddrs = append(assistedAddrs, net.JoinHostPort(ip, strconv.Itoa(laddr.Port)))
149+
}
139150
}
140151
return &PrepareResult{
141152
Addrs: addrs,

0 commit comments

Comments
 (0)