Deprecate Socksaddr.IsFqdn: do not reject potentially valid domain names

This commit is contained in:
世界
2026-03-16 09:36:24 +08:00
parent d3768cca36
commit d2fa21d07b
16 changed files with 29 additions and 29 deletions

View File

@@ -239,7 +239,7 @@ func setMarkWrapper(networkManager adapter.NetworkManager, mark uint32, isDefaul
func (d *DefaultDialer) DialContext(ctx context.Context, network string, address M.Socksaddr) (net.Conn, error) {
if !address.IsValid() {
return nil, E.New("invalid address")
} else if address.IsFqdn() {
} else if address.IsDomain() {
return nil, E.New("domain not resolved")
}
if d.networkStrategy == nil {

View File

@@ -96,7 +96,7 @@ func (d *resolveDialer) DialContext(ctx context.Context, network string, destina
if err != nil {
return nil, err
}
if !destination.IsFqdn() {
if !destination.IsDomain() {
return d.dialer.DialContext(ctx, network, destination)
}
ctx = log.ContextWithOverrideLevel(ctx, log.LevelDebug)
@@ -116,7 +116,7 @@ func (d *resolveDialer) ListenPacket(ctx context.Context, destination M.Socksadd
if err != nil {
return nil, err
}
if !destination.IsFqdn() {
if !destination.IsDomain() {
return d.dialer.ListenPacket(ctx, destination)
}
ctx = log.ContextWithOverrideLevel(ctx, log.LevelDebug)
@@ -144,7 +144,7 @@ func (d *resolveParallelNetworkDialer) DialParallelInterface(ctx context.Context
if err != nil {
return nil, err
}
if !destination.IsFqdn() {
if !destination.IsDomain() {
return d.dialer.DialContext(ctx, network, destination)
}
ctx = log.ContextWithOverrideLevel(ctx, log.LevelDebug)
@@ -167,7 +167,7 @@ func (d *resolveParallelNetworkDialer) ListenSerialInterfacePacket(ctx context.C
if err != nil {
return nil, err
}
if !destination.IsFqdn() {
if !destination.IsDomain() {
return d.dialer.ListenPacket(ctx, destination)
}
ctx = log.ContextWithOverrideLevel(ctx, log.LevelDebug)

2
go.mod
View File

@@ -33,7 +33,7 @@ require (
github.com/sagernet/gomobile v0.1.12
github.com/sagernet/gvisor v0.0.0-20250811.0-sing-box-mod.1
github.com/sagernet/quic-go v0.59.0-sing-box-mod.4
github.com/sagernet/sing v0.8.2
github.com/sagernet/sing v0.8.3-0.20260315153529-ed51f65fbfde
github.com/sagernet/sing-mux v0.3.4
github.com/sagernet/sing-quic v0.6.0
github.com/sagernet/sing-shadowsocks v0.2.8

4
go.sum
View File

@@ -236,8 +236,8 @@ github.com/sagernet/nftables v0.3.0-beta.4 h1:kbULlAwAC3jvdGAC1P5Fa3GSxVwQJibNen
github.com/sagernet/nftables v0.3.0-beta.4/go.mod h1:OQXAjvjNGGFxaTgVCSTRIhYB5/llyVDeapVoENYBDS8=
github.com/sagernet/quic-go v0.59.0-sing-box-mod.4 h1:6qvrUW79S+CrPwWz6cMePXohgjHoKxLo3c+MDhNwc3o=
github.com/sagernet/quic-go v0.59.0-sing-box-mod.4/go.mod h1:OqILvS182CyOol5zNNo6bguvOGgXzV459+chpRaUC+4=
github.com/sagernet/sing v0.8.2 h1:kX1IH9SWJv4S0T9M8O+HNahWgbOuY1VauxbF7NU5lOg=
github.com/sagernet/sing v0.8.2/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/sagernet/sing v0.8.3-0.20260315153529-ed51f65fbfde h1:RNQzlpnsXIuu1HGts/fIzJ1PR7RhrzaNlU52MDyiX1c=
github.com/sagernet/sing v0.8.3-0.20260315153529-ed51f65fbfde/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/sagernet/sing-mux v0.3.4 h1:ZQplKl8MNXutjzbMVtWvWG31fohhgOfCuUZR4dVQ8+s=
github.com/sagernet/sing-mux v0.3.4/go.mod h1:QvlKMyNBNrQoyX4x+gq028uPbLM2XeRpWtDsWBJbFSk=
github.com/sagernet/sing-quic v0.6.0 h1:dhrFnP45wgVKEOT1EvtsToxdzRnHIDIAgj6WHV9pLyM=

View File

@@ -339,7 +339,7 @@ func (o DNSServerAddressOptions) Build() M.Socksaddr {
}
func (o DNSServerAddressOptions) ServerIsDomain() bool {
return M.IsDomainName(o.Server)
return o.Build().IsDomain()
}
func (o *DNSServerAddressOptions) TakeServerOptions() ServerOptions {

View File

@@ -155,7 +155,7 @@ func (o ServerOptions) Build() M.Socksaddr {
}
func (o ServerOptions) ServerIsDomain() bool {
return M.IsDomainName(o.Server)
return o.Build().IsDomain()
}
func (o *ServerOptions) TakeServerOptions() ServerOptions {

View File

@@ -61,7 +61,7 @@ func (d DERPVerifyClientURLOptions) ServerIsDomain() bool {
if err != nil {
return false
}
return M.IsDomainName(verifyURL.Host)
return M.ParseSocksaddr(verifyURL.Hostname()).IsDomain()
}
func (d DERPVerifyClientURLOptions) MarshalJSON() ([]byte, error) {

View File

@@ -83,7 +83,7 @@ func (h *Outbound) DialContext(ctx context.Context, network string, destination
default:
return nil, E.Extend(N.ErrUnknownNetwork, network)
}
if h.resolve && destination.IsFqdn() {
if h.resolve && destination.IsDomain() {
destinationAddresses, err := h.dnsRouter.Lookup(ctx, destination.Fqdn, adapter.DNSQueryOptions{})
if err != nil {
return nil, err
@@ -101,7 +101,7 @@ func (h *Outbound) ListenPacket(ctx context.Context, destination M.Socksaddr) (n
h.logger.InfoContext(ctx, "outbound UoT packet connection to ", destination)
return h.uotClient.ListenPacket(ctx, destination)
}
if h.resolve && destination.IsFqdn() {
if h.resolve && destination.IsDomain() {
destinationAddresses, err := h.dnsRouter.Lookup(ctx, destination.Fqdn, adapter.DNSQueryOptions{})
if err != nil {
return nil, err

View File

@@ -287,7 +287,7 @@ type DNSDialer struct {
}
func (d *DNSDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
if destination.IsFqdn() {
if destination.IsDomain() {
panic("invalid request here")
}
for _, prefix := range d.transport.routePrefixes {
@@ -299,7 +299,7 @@ func (d *DNSDialer) DialContext(ctx context.Context, network string, destination
}
func (d *DNSDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
if destination.IsFqdn() {
if destination.IsDomain() {
panic("invalid request here")
}
for _, prefix := range d.transport.routePrefixes {

View File

@@ -190,7 +190,7 @@ func NewEndpoint(ctx context.Context, router adapter.Router, logger log.ContextL
if err != nil {
return nil, E.Cause(err, "parse control URL")
}
remoteIsDomain = M.IsDomainName(controlURL.Hostname())
remoteIsDomain = M.ParseSocksaddr(controlURL.Hostname()).IsDomain()
} else {
// controlplane.tailscale.com
remoteIsDomain = true
@@ -492,7 +492,7 @@ func (t *Endpoint) DialContext(ctx context.Context, network string, destination
case N.NetworkUDP:
t.logger.InfoContext(ctx, "outbound packet connection to ", destination)
}
if destination.IsFqdn() {
if destination.IsDomain() {
destinationAddresses, err := t.dnsRouter.Lookup(ctx, destination.Fqdn, adapter.DNSQueryOptions{})
if err != nil {
return nil, err
@@ -578,7 +578,7 @@ func (t *Endpoint) listenPacketWithAddress(ctx context.Context, destination M.So
func (t *Endpoint) ListenPacketWithDestination(ctx context.Context, destination M.Socksaddr) (net.PacketConn, netip.Addr, error) {
t.logger.InfoContext(ctx, "outbound packet connection to ", destination)
if destination.IsFqdn() {
if destination.IsDomain() {
destinationAddresses, err := t.dnsRouter.Lookup(ctx, destination.Fqdn, adapter.DNSQueryOptions{})
if err != nil {
return nil, netip.Addr{}, err

View File

@@ -167,7 +167,7 @@ func (h *vlessDialer) DialContext(ctx context.Context, network string, destinati
if h.xudp {
return h.client.DialEarlyXUDPPacketConn(conn, destination)
} else if h.packetAddr {
if destination.IsFqdn() {
if destination.IsDomain() {
return nil, E.New("packetaddr: domain destination is not supported")
}
packetConn, err := h.client.DialEarlyPacketConn(conn, M.Socksaddr{Fqdn: packetaddr.SeqPacketMagicAddress})
@@ -204,7 +204,7 @@ func (h *vlessDialer) ListenPacket(ctx context.Context, destination M.Socksaddr)
if h.xudp {
return h.client.DialEarlyXUDPPacketConn(conn, destination)
} else if h.packetAddr {
if destination.IsFqdn() {
if destination.IsDomain() {
return nil, E.New("packetaddr: domain destination is not supported")
}
conn, err := h.client.DialEarlyPacketConn(conn, M.Socksaddr{Fqdn: packetaddr.SeqPacketMagicAddress})

View File

@@ -194,7 +194,7 @@ func (h *vmessDialer) ListenPacket(ctx context.Context, destination M.Socksaddr)
return nil, err
}
if h.packetAddr {
if destination.IsFqdn() {
if destination.IsDomain() {
return nil, E.New("packetaddr: domain destination is not supported")
}
return packetaddr.NewConn(h.client.DialEarlyPacketConn(conn, M.Socksaddr{Fqdn: packetaddr.SeqPacketMagicAddress}), destination), nil

View File

@@ -210,7 +210,7 @@ func (w *Endpoint) DialContext(ctx context.Context, network string, destination
case N.NetworkUDP:
w.logger.InfoContext(ctx, "outbound packet connection to ", destination)
}
if destination.IsFqdn() {
if destination.IsDomain() {
destinationAddresses, err := w.dnsRouter.Lookup(ctx, destination.Fqdn, adapter.DNSQueryOptions{})
if err != nil {
return nil, err
@@ -224,7 +224,7 @@ func (w *Endpoint) DialContext(ctx context.Context, network string, destination
func (w *Endpoint) ListenPacketWithDestination(ctx context.Context, destination M.Socksaddr) (net.PacketConn, netip.Addr, error) {
w.logger.InfoContext(ctx, "outbound packet connection to ", destination)
if destination.IsFqdn() {
if destination.IsDomain() {
destinationAddresses, err := w.dnsRouter.Lookup(ctx, destination.Fqdn, adapter.DNSQueryOptions{})
if err != nil {
return nil, netip.Addr{}, err

View File

@@ -349,7 +349,7 @@ func (r *Router) PreMatch(metadata adapter.InboundContext, routeContext tun.Dire
}
directRouteOutbound = defaultOutbound.(adapter.DirectRouteOutbound)
}
if metadata.Destination.IsFqdn() {
if metadata.Destination.IsDomain() {
if len(metadata.DestinationAddresses) == 0 {
var strategy C.DomainStrategy
if metadata.Source.IsIPv4() {
@@ -790,7 +790,7 @@ func (r *Router) actionSniff(
}
func (r *Router) actionResolve(ctx context.Context, metadata *adapter.InboundContext, action *R.RuleActionResolve) error {
if metadata.Destination.IsFqdn() {
if metadata.Destination.IsDomain() {
var transport adapter.DNSTransport
if action.Server != "" {
var loaded bool

View File

@@ -136,7 +136,7 @@ func (c *ClientPacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error)
return
}
n = buffer.Len()
if destination.IsFqdn() {
if destination.IsDomain() {
addr = destination
} else {
addr = destination.UDPAddr()

View File

@@ -63,7 +63,7 @@ func NewEndpoint(options EndpointOptions) (*Endpoint, error) {
}
if rawPeer.Endpoint.Addr.IsValid() {
peer.endpoint = rawPeer.Endpoint.AddrPort()
} else if rawPeer.Endpoint.IsFqdn() {
} else if rawPeer.Endpoint.IsDomain() {
peer.destination = rawPeer.Endpoint
}
publicKeyBytes, err := base64.StdEncoding.DecodeString(rawPeer.PublicKey)
@@ -135,13 +135,13 @@ func NewEndpoint(options EndpointOptions) (*Endpoint, error) {
func (e *Endpoint) Start(resolve bool) error {
if common.Any(e.peers, func(peer peerConfig) bool {
return !peer.endpoint.IsValid() && peer.destination.IsFqdn()
return !peer.endpoint.IsValid() && peer.destination.IsDomain()
}) {
if !resolve {
return nil
}
for peerIndex, peer := range e.peers {
if peer.endpoint.IsValid() || !peer.destination.IsFqdn() {
if peer.endpoint.IsValid() || !peer.destination.IsDomain() {
continue
}
destinationAddress, err := e.options.ResolvePeer(peer.destination.Fqdn)