diff --git a/go.mod b/go.mod index 62fe76eb..04b43cbc 100644 --- a/go.mod +++ b/go.mod @@ -43,8 +43,8 @@ require ( github.com/sagernet/sing-tun v0.8.12-0.20260727151122-3a09076491df github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1 github.com/sagernet/smux v1.5.50-sing-box-mod.1 - github.com/sagernet/tailscale v1.92.4-sing-box-1.13-mod.8 - github.com/sagernet/wireguard-go v0.0.2-beta.1.0.20260224074747-506b7631853c + github.com/sagernet/tailscale v1.92.4-sing-box-1.13-mod.9 + github.com/sagernet/wireguard-go v0.0.4 github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 github.com/spf13/cobra v1.10.2 github.com/stretchr/testify v1.11.1 diff --git a/go.sum b/go.sum index dd8c104e..4e16efdc 100644 --- a/go.sum +++ b/go.sum @@ -254,10 +254,10 @@ github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1 h1:aSwUNYUkV github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1/go.mod h1:P11scgTxMxVVQ8dlM27yNm3Cro40mD0+gHbnqrNGDuY= github.com/sagernet/smux v1.5.50-sing-box-mod.1 h1:XkJcivBC9V4wBjiGXIXZ229aZCU1hzcbp6kSkkyQ478= github.com/sagernet/smux v1.5.50-sing-box-mod.1/go.mod h1:NjhsCEWedJm7eFLyhuBgIEzwfhRmytrUoiLluxs5Sk8= -github.com/sagernet/tailscale v1.92.4-sing-box-1.13-mod.8 h1:vchb9moOQIxPVOLpTUo2iyZ2E2oUaBpvAh3bBPcEqIM= -github.com/sagernet/tailscale v1.92.4-sing-box-1.13-mod.8/go.mod h1:m87GAn4UcesHQF3leaPFEINZETO5za1LGn1GJdNDgNc= -github.com/sagernet/wireguard-go v0.0.2-beta.1.0.20260224074747-506b7631853c h1:f9cXNB+IOOPnR8DOLMTpr42jf7naxh5Un5Y09BBf5Cg= -github.com/sagernet/wireguard-go v0.0.2-beta.1.0.20260224074747-506b7631853c/go.mod h1:WUxgxUDZoCF2sxVmW+STSxatP02Qn3FcafTiI2BLtE0= +github.com/sagernet/tailscale v1.92.4-sing-box-1.13-mod.9 h1:ytlmw4f8AOjyJH3SeDMF4j6tQ679W4+dMS0JMl/e7pQ= +github.com/sagernet/tailscale v1.92.4-sing-box-1.13-mod.9/go.mod h1:p8Ms8FbGlwQJyHb862XmdShTS50fFJ8C71VdO6xvWyk= +github.com/sagernet/wireguard-go v0.0.4 h1:w/vHtk7AzMG37+D/uQROBL72Gj/Gj+FHMY5kg4q0CQ4= +github.com/sagernet/wireguard-go v0.0.4/go.mod h1:hEqi4y5czEg6LYtX2Bpjg+lV0b/J1n+5rA885Z66Mx0= github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 h1:6uUiZcDRnZSAegryaUGwPC/Fj13JSHwiTftrXhMmYOc= github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854/go.mod h1:LtfoSK3+NG57tvnVEHgcuBW9ujgE8enPSgzgwStwCAA= github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= diff --git a/protocol/tailscale/endpoint.go b/protocol/tailscale/endpoint.go index f1430d59..eb22f678 100644 --- a/protocol/tailscale/endpoint.go +++ b/protocol/tailscale/endpoint.go @@ -27,9 +27,10 @@ import ( "github.com/sagernet/sing-box/adapter/endpoint" "github.com/sagernet/sing-box/common/dialer" C "github.com/sagernet/sing-box/constant" + "github.com/sagernet/sing-box/dns" "github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/option" - "github.com/sagernet/sing-box/route/rule" + R "github.com/sagernet/sing-box/route/rule" "github.com/sagernet/sing-tun" "github.com/sagernet/sing-tun/ping" "github.com/sagernet/sing/common" @@ -60,6 +61,7 @@ import ( "github.com/sagernet/tailscale/wgengine/router" "github.com/sagernet/tailscale/wgengine/wgcfg" + mDNS "github.com/miekg/dns" "go4.org/netipx" ) @@ -260,6 +262,8 @@ func NewEndpoint(ctx context.Context, router adapter.Router, logger log.ContextL func (t *Endpoint) Start(stage adapter.StartStage) error { switch stage { + case adapter.StartStateInitialize: + t.server.PeerDNSQueryHandler = (*peerDNSQueryHandler)(t) case adapter.StartStateStart: return t.start() case adapter.StartStatePostStart: @@ -678,9 +682,9 @@ func (t *Endpoint) PrepareConnection(network string, source M.Socksaddr, destina }, routeContext, timeout, false) if err != nil { switch { - case rule.IsBypassed(err): + case R.IsBypassed(err): err = nil - case rule.IsRejected(err): + case R.IsRejected(err): t.logger.Trace("reject ", network, " connection from ", source.AddrString(), " to ", destination.AddrString()) default: if network == N.NetworkICMP { @@ -888,3 +892,30 @@ func (c *dnsConfigurtor) GetBaseConfig() (tsDNS.OSConfig, error) { func (c *dnsConfigurtor) Close() error { return nil } + +type peerDNSQueryHandler Endpoint + +func (t *peerDNSQueryHandler) HandlePeerDNSQuery(ctx context.Context, query []byte, sourceAddress netip.AddrPort, allowName func(name string) bool) ([]byte, error) { + var message mDNS.Msg + err := message.Unpack(query) + if err != nil { + return nil, err + } + for _, question := range message.Question { + if allowName != nil && !allowName(question.Name) { + return dns.FixedResponseStatus(&message, mDNS.RcodeRefused).Pack() + } + } + var metadata adapter.InboundContext + metadata.Inbound = t.Tag() + metadata.InboundType = t.Type() + metadata.Source = M.SocksaddrFromNetIP(sourceAddress) + response, err := t.dnsRouter.Exchange(adapter.WithContext(ctx, &metadata), &message, adapter.DNSQueryOptions{}) + if err != nil { + if !R.IsRejected(err) && !E.IsClosedOrCanceled(err) { + t.logger.ErrorContext(ctx, E.Cause(err, "process peer DNS query")) + } + return nil, err + } + return response.Pack() +}