From c67c4a54d780258fff4498376772955dc79a41e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Mon, 30 Oct 2023 12:00:00 +0800 Subject: [PATCH] Add udp_disable_domain_unmapping inbound listen option --- docs/configuration/shared/listen.md | 54 +++++++++++++------------- docs/configuration/shared/listen.zh.md | 38 ++++++++---------- go.mod | 2 +- go.sum | 4 +- option/inbound.go | 9 +++-- outbound/default.go | 10 +++-- 6 files changed, 58 insertions(+), 59 deletions(-) diff --git a/docs/configuration/shared/listen.md b/docs/configuration/shared/listen.md index d4a0e58e..c1b1ed33 100644 --- a/docs/configuration/shared/listen.md +++ b/docs/configuration/shared/listen.md @@ -7,28 +7,26 @@ "tcp_fast_open": false, "tcp_multi_path": false, "udp_fragment": false, + "udp_timeout": 300, + "detour": "another-in", "sniff": false, "sniff_override_destination": false, "sniff_timeout": "300ms", "domain_strategy": "prefer_ipv6", - "udp_timeout": 300, - "proxy_protocol": false, - "proxy_protocol_accept_no_header": false, - "detour": "another-in" + "udp_disable_domain_unmapping": false } ``` ### Fields -| Field | Available Context | -|-----------------------------------|-------------------------------------------------------------------| -| `listen` | Needs to listen on TCP or UDP. | -| `listen_port` | Needs to listen on TCP or UDP. | -| `tcp_fast_open` | Needs to listen on TCP. | -| `tcp_multi_path` | Needs to listen on TCP. | -| `udp_timeout` | Needs to assemble UDP connections, currently Tun and Shadowsocks. | -| `proxy_protocol` | Needs to listen on TCP. | -| `proxy_protocol_accept_no_header` | When `proxy_protocol` enabled | +| Field | Available Context | +|--------------------------------|-------------------------------------------------------------------| +| `listen` | Needs to listen on TCP or UDP. | +| `listen_port` | Needs to listen on TCP or UDP. | +| `tcp_fast_open` | Needs to listen on TCP. | +| `tcp_multi_path` | Needs to listen on TCP. | +| `udp_timeout` | Needs to assemble UDP connections, currently Tun and Shadowsocks. | +| `udp_disable_domain_unmapping` | Needs to listen on UDP and accept domain UDP addresses. | #### listen @@ -56,6 +54,16 @@ Enable TCP Multi Path. Enable UDP fragmentation. +#### udp_timeout + +UDP NAT expiration time in seconds, default is 300 (5 minutes). + +#### detour + +If set, connections will be forwarded to the specified inbound. + +Requires target inbound support, see [Injectable](/configuration/inbound/#fields). + #### sniff Enable sniffing. @@ -82,20 +90,10 @@ If set, the requested domain name will be resolved to IP before routing. If `sniff_override_destination` is in effect, its value will be taken as a fallback. -#### udp_timeout +#### udp_disable_domain_unmapping -UDP NAT expiration time in seconds, default is 300 (5 minutes). +If enabled, for UDP proxy requests addressed to a domain, +the original packet address will be sent in the response instead of the mapped domain. -#### proxy_protocol - -Parse [Proxy Protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) in the connection header. - -#### proxy_protocol_accept_no_header - -Accept connections without Proxy Protocol header. - -#### detour - -If set, connections will be forwarded to the specified inbound. - -Requires target inbound support, see [Injectable](/configuration/inbound/#fields). \ No newline at end of file +This option is used for compatibility with clients that +do not support receiving UDP packets with domain addresses, such as Surge. diff --git a/docs/configuration/shared/listen.zh.md b/docs/configuration/shared/listen.zh.md index b25ce295..b7fd7487 100644 --- a/docs/configuration/shared/listen.zh.md +++ b/docs/configuration/shared/listen.zh.md @@ -7,14 +7,13 @@ "tcp_fast_open": false, "tcp_multi_path": false, "udp_fragment": false, + "udp_timeout": 300, + "detour": "another-in", "sniff": false, "sniff_override_destination": false, "sniff_timeout": "300ms", "domain_strategy": "prefer_ipv6", - "udp_timeout": 300, - "proxy_protocol": false, - "proxy_protocol_accept_no_header": false, - "detour": "another-in" + "udp_disable_domain_unmapping": false } ``` @@ -26,8 +25,7 @@ | `tcp_fast_open` | 需要监听 TCP。 | | `tcp_multi_path` | 需要监听 TCP。 | | `udp_timeout` | 需要组装 UDP 连接, 当前为 Tun 和 Shadowsocks。 | -| `proxy_protocol` | 需要监听 TCP。 | -| `proxy_protocol_accept_no_header` | `proxy_protocol` 启用时 | +| ### 字段 @@ -57,6 +55,16 @@ 启用 UDP 分段。 +#### udp_timeout + +UDP NAT 过期时间,以秒为单位,默认为 300(5 分钟)。 + +#### detour + +如果设置,连接将被转发到指定的入站。 + +需要目标入站支持,参阅 [注入支持](/zh/configuration/inbound/#_3)。 + #### sniff 启用协议探测。 @@ -83,20 +91,8 @@ 如果 `sniff_override_destination` 生效,它的值将作为后备。 -#### udp_timeout +#### udp_disable_domain_unmapping -UDP NAT 过期时间,以秒为单位,默认为 300(5 分钟)。 +如果启用,对于地址为域的 UDP 代理请求,将在响应中发送原始包地址而不是映射的域。 -#### proxy_protocol - -解析连接头中的 [代理协议](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)。 - -#### proxy_protocol_accept_no_header - -接受没有代理协议标头的连接。 - -#### detour - -如果设置,连接将被转发到指定的入站。 - -需要目标入站支持,参阅 [注入支持](/zh/configuration/inbound/#_3)。 \ No newline at end of file +此选项用于兼容不支持接收带有域地址的 UDP 包的客户端,如 Surge。 diff --git a/go.mod b/go.mod index 64f98d0e..1ec90f80 100644 --- a/go.mod +++ b/go.mod @@ -26,7 +26,7 @@ require ( github.com/sagernet/gvisor v0.0.0-20230930141345-5fef6f2e17ab github.com/sagernet/quic-go v0.0.0-20231008035953-32727fef9460 github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 - github.com/sagernet/sing v0.2.16-0.20231021090846-8002db54c028 + github.com/sagernet/sing v0.2.16-0.20231028125948-afcc9cb766c2 github.com/sagernet/sing-dns v0.1.10 github.com/sagernet/sing-mux v0.1.3 github.com/sagernet/sing-quic v0.1.3-0.20231026034240-fa3d997246b6 diff --git a/go.sum b/go.sum index ac72c9a4..93175f12 100644 --- a/go.sum +++ b/go.sum @@ -114,8 +114,8 @@ github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byL github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU= github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY= github.com/sagernet/sing v0.1.8/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk= -github.com/sagernet/sing v0.2.16-0.20231021090846-8002db54c028 h1:6GbQt7SC9y5Imrq5jDMbXDSaNiMhJ8KBjhjtQRuqQvE= -github.com/sagernet/sing v0.2.16-0.20231021090846-8002db54c028/go.mod h1:AhNEHu0GXrpqkuzvTwvC8+j2cQUU/dh+zLEmq4C99pg= +github.com/sagernet/sing v0.2.16-0.20231028125948-afcc9cb766c2 h1:PW18IgRodvppd09d4mewYM3Hedu3PtFERN8yOqkTVk0= +github.com/sagernet/sing v0.2.16-0.20231028125948-afcc9cb766c2/go.mod h1:AhNEHu0GXrpqkuzvTwvC8+j2cQUU/dh+zLEmq4C99pg= github.com/sagernet/sing-dns v0.1.10 h1:iIU7nRBlUYj+fF2TaktGIvRiTFFrHwSMedLQsvlTZCI= github.com/sagernet/sing-dns v0.1.10/go.mod h1:vtUimtf7Nq9EdvD5WTpfCr69KL1M7bcgOVKiYBiAY/c= github.com/sagernet/sing-mux v0.1.3 h1:fAf7PZa2A55mCeh0KKM02f1k2Y4vEmxuZZ/51ahkkLA= diff --git a/option/inbound.go b/option/inbound.go index 06408f58..c61428ad 100644 --- a/option/inbound.go +++ b/option/inbound.go @@ -120,10 +120,11 @@ func (h *Inbound) UnmarshalJSON(bytes []byte) error { } type InboundOptions struct { - SniffEnabled bool `json:"sniff,omitempty"` - SniffOverrideDestination bool `json:"sniff_override_destination,omitempty"` - SniffTimeout Duration `json:"sniff_timeout,omitempty"` - DomainStrategy DomainStrategy `json:"domain_strategy,omitempty"` + SniffEnabled bool `json:"sniff,omitempty"` + SniffOverrideDestination bool `json:"sniff_override_destination,omitempty"` + SniffTimeout Duration `json:"sniff_timeout,omitempty"` + DomainStrategy DomainStrategy `json:"domain_strategy,omitempty"` + UDPDisableDomainUnmapping bool `json:"udp_disable_domain_unmapping,omitempty"` } type ListenOptions struct { diff --git a/outbound/default.go b/outbound/default.go index 79ed7b33..b0ced5ac 100644 --- a/outbound/default.go +++ b/outbound/default.go @@ -121,9 +121,13 @@ func NewPacketConnection(ctx context.Context, this N.Dialer, conn N.PacketConn, } if destinationAddress.IsValid() { if metadata.Destination.IsFqdn() { - outConn = bufio.NewNATPacketConn(bufio.NewPacketConn(outConn), M.SocksaddrFrom(destinationAddress, metadata.Destination.Port), metadata.Destination) + if metadata.InboundOptions.UDPDisableDomainUnmapping { + outConn = bufio.NewUnidirectionalNATPacketConn(bufio.NewPacketConn(outConn), M.SocksaddrFrom(destinationAddress, metadata.Destination.Port), metadata.Destination) + } else { + outConn = bufio.NewNATPacketConn(bufio.NewPacketConn(outConn), M.SocksaddrFrom(destinationAddress, metadata.Destination.Port), metadata.Destination) + } } - if natConn, loaded := common.Cast[*bufio.NATPacketConn](conn); loaded { + if natConn, loaded := common.Cast[bufio.NATPacketConn](conn); loaded { natConn.UpdateDestination(destinationAddress) } } @@ -166,7 +170,7 @@ func NewDirectPacketConnection(ctx context.Context, router adapter.Router, this if metadata.Destination.IsFqdn() { outConn = bufio.NewNATPacketConn(bufio.NewPacketConn(outConn), M.SocksaddrFrom(destinationAddress, metadata.Destination.Port), metadata.Destination) } - if natConn, loaded := common.Cast[*bufio.NATPacketConn](conn); loaded { + if natConn, loaded := common.Cast[bufio.NATPacketConn](conn); loaded { natConn.UpdateDestination(destinationAddress) } }