Fix resolved service

This commit is contained in:
世界
2026-09-24 17:23:36 +08:00
parent 4abede8ceb
commit 6b6c20a248
3 changed files with 58 additions and 76 deletions
+28 -62
View File
@@ -5,12 +5,10 @@ package resolved
import (
"context"
"errors"
"fmt"
"net/netip"
"os"
"os/user"
"path/filepath"
"slices"
"strconv"
"strings"
"syscall"
@@ -79,17 +77,27 @@ type LinkDomain struct {
func (t *resolve1Manager) getLink(ifIndex int32) (*TransportLink, *dbus.Error) {
link, loaded := t.links[ifIndex]
if !loaded {
link = &TransportLink{}
t.links[ifIndex] = link
iif, err := t.network.InterfaceFinder().ByIndex(int(ifIndex))
if err != nil {
return nil, wrapError(err)
}
link.iif = iif
link = &TransportLink{iif: iif}
t.links[ifIndex] = link
}
return link, nil
}
func (t *resolve1Manager) interfaceName(ifIndex int32) string {
if ifIndex == 0 {
return "*"
}
iif, err := t.network.InterfaceFinder().ByIndex(int(ifIndex))
if err != nil {
return F.ToString(ifIndex)
}
return iif.Name
}
func (t *resolve1Manager) getSenderProcess(sender dbus.Sender) (int32, error) {
var senderPid int32
dbusObject := t.systemBus.Object("org.freedesktop.DBus", "/org/freedesktop/DBus")
@@ -203,12 +211,6 @@ func familyToString(family int32) string {
}
func (t *resolve1Manager) ResolveHostname(sender dbus.Sender, ifIndex int32, hostname string, family int32, flags uint64) (addresses []Address, canonical string, outflags uint64, err *dbus.Error) {
t.linkAccess.Lock()
link, err := t.getLink(ifIndex)
if err != nil {
return
}
t.linkAccess.Unlock()
var strategy C.DomainStrategy
switch family {
case syscall.AF_UNSPEC:
@@ -218,12 +220,12 @@ func (t *resolve1Manager) ResolveHostname(sender dbus.Sender, ifIndex int32, hos
case syscall.AF_INET6:
strategy = C.DomainStrategyIPv6Only
}
ctx := t.logRequest(sender, "ResolveHostname ", link.iif.Name, " ", hostname, " ", familyToString(family), " ", flags)
ctx := t.logRequest(sender, "ResolveHostname", t.interfaceName(ifIndex), hostname, familyToString(family), flags)
responseAddresses, lookupErr := t.dnsRouter.Lookup(ctx, hostname, adapter.DNSQueryOptions{
LookupStrategy: strategy,
})
if lookupErr != nil {
err = wrapError(err)
err = wrapError(lookupErr)
return
}
addresses = common.Map(responseAddresses, func(it netip.Addr) Address {
@@ -244,48 +246,27 @@ func (t *resolve1Manager) ResolveHostname(sender dbus.Sender, ifIndex int32, hos
}
func (t *resolve1Manager) ResolveAddress(sender dbus.Sender, ifIndex int32, family int32, address []byte, flags uint64) (names []Name, outflags uint64, err *dbus.Error) {
t.linkAccess.Lock()
link, err := t.getLink(ifIndex)
if err != nil {
return
}
t.linkAccess.Unlock()
addr, ok := netip.AddrFromSlice(address)
if !ok {
err = wrapError(E.New("invalid address"))
return
}
var nibbles []string
for _, v := range slices.Backward(address) {
b := v
nibbles = append(nibbles, fmt.Sprintf("%x", b&0x0F))
nibbles = append(nibbles, fmt.Sprintf("%x", b>>4))
}
var ptrDomain string
if addr.Is4() {
ptrDomain = strings.Join(nibbles, ".") + ".in-addr.arpa."
} else {
ptrDomain = strings.Join(nibbles, ".") + ".ip6.arpa."
}
request := &mDNS.Msg{
MsgHdr: mDNS.MsgHdr{
RecursionDesired: true,
},
Question: []mDNS.Question{
{
Name: mDNS.Fqdn(ptrDomain),
Name: common.Must1(mDNS.ReverseAddr(addr.String())),
Qtype: mDNS.TypePTR,
Qclass: mDNS.ClassINET,
},
},
}
ctx := t.logRequest(sender, "ResolveAddress ", link.iif.Name, familyToString(family), addr, flags)
var metadata adapter.InboundContext
metadata.InboundType = t.Type()
metadata.Inbound = t.Tag()
response, lookupErr := t.dnsRouter.Exchange(adapter.WithContext(ctx, &metadata), request, adapter.DNSQueryOptions{})
ctx := t.logRequest(sender, "ResolveAddress", t.interfaceName(ifIndex), familyToString(family), addr, flags)
response, lookupErr := t.dnsRouter.Exchange(ctx, request, adapter.DNSQueryOptions{})
if lookupErr != nil {
err = wrapError(err)
err = wrapError(lookupErr)
return
}
if response.Rcode != mDNS.RcodeSuccess {
@@ -305,12 +286,6 @@ func (t *resolve1Manager) ResolveAddress(sender dbus.Sender, ifIndex int32, fami
}
func (t *resolve1Manager) ResolveRecord(sender dbus.Sender, ifIndex int32, hostname string, qClass uint16, qType uint16, flags uint64) (records []ResourceRecord, outflags uint64, err *dbus.Error) {
t.linkAccess.Lock()
link, err := t.getLink(ifIndex)
if err != nil {
return
}
t.linkAccess.Unlock()
request := &mDNS.Msg{
MsgHdr: mDNS.MsgHdr{
RecursionDesired: true,
@@ -323,11 +298,8 @@ func (t *resolve1Manager) ResolveRecord(sender dbus.Sender, ifIndex int32, hostn
},
},
}
ctx := t.logRequest(sender, "ResolveRecord", link.iif.Name, hostname, mDNS.Class(qClass), mDNS.Type(qType), flags)
var metadata adapter.InboundContext
metadata.InboundType = t.Type()
metadata.Inbound = t.Tag()
response, exchangeErr := t.dnsRouter.Exchange(adapter.WithContext(ctx, &metadata), request, adapter.DNSQueryOptions{})
ctx := t.logRequest(sender, "ResolveRecord", t.interfaceName(ifIndex), hostname, mDNS.Class(qClass), mDNS.Type(qType), flags)
response, exchangeErr := t.dnsRouter.Exchange(ctx, request, adapter.DNSQueryOptions{})
if exchangeErr != nil {
err = wrapError(exchangeErr)
return
@@ -353,13 +325,6 @@ func (t *resolve1Manager) ResolveRecord(sender dbus.Sender, ifIndex int32, hostn
}
func (t *resolve1Manager) ResolveService(sender dbus.Sender, ifIndex int32, hostname string, sType string, domain string, family int32, flags uint64) (srvData []SRVRecord, txtData []TXTRecord, canonicalName string, canonicalType string, canonicalDomain string, outflags uint64, err *dbus.Error) {
t.linkAccess.Lock()
link, err := t.getLink(ifIndex)
if err != nil {
return
}
t.linkAccess.Unlock()
serviceName := hostname
if hostname != "" && !strings.HasSuffix(hostname, ".") {
serviceName += "."
@@ -373,7 +338,7 @@ func (t *resolve1Manager) ResolveService(sender dbus.Sender, ifIndex int32, host
serviceName += "."
}
ctx := t.logRequest(sender, "ResolveService ", link.iif.Name, " ", hostname, " ", sType, " ", domain, " ", familyToString(family), " ", flags)
ctx := t.logRequest(sender, "ResolveService", t.interfaceName(ifIndex), hostname, sType, domain, familyToString(family), flags)
srvRequest := &mDNS.Msg{
MsgHdr: mDNS.MsgHdr{
@@ -387,10 +352,7 @@ func (t *resolve1Manager) ResolveService(sender dbus.Sender, ifIndex int32, host
},
},
}
var metadata adapter.InboundContext
metadata.InboundType = t.Type()
metadata.Inbound = t.Tag()
srvResponse, exchangeErr := t.dnsRouter.Exchange(adapter.WithContext(ctx, &metadata), srvRequest, adapter.DNSQueryOptions{})
srvResponse, exchangeErr := t.dnsRouter.Exchange(ctx, srvRequest, adapter.DNSQueryOptions{})
if exchangeErr != nil {
err = wrapError(exchangeErr)
return
@@ -606,8 +568,12 @@ func (t *resolve1Manager) RevertLink(sender dbus.Sender, ifIndex int32) *dbus.Er
return wrapError(err)
}
delete(t.links, ifIndex)
t.defaultRouteSequence = common.Filter(t.defaultRouteSequence, func(it int32) bool { return it != ifIndex })
t.log(sender, "RevertLink ", link.iif.Name)
return t.postUpdate(link)
if t.deleteCallback != nil {
t.deleteCallback(link)
}
return nil
}
// TODO: implement RegisterService, UnregisterService
+4 -7
View File
@@ -185,12 +185,12 @@ func (i *Service) exchangePacket0(ctx context.Context, buffer *buf.Buffer, oob [
func (i *Service) onNetworkUpdate() {
i.linkAccess.Lock()
defer i.linkAccess.Unlock()
var deleteIfIndex []int
for ifIndex, link := range i.links {
iif, err := i.network.InterfaceFinder().ByIndex(int(ifIndex))
if err != nil || iif != link.iif {
deleteIfIndex = append(deleteIfIndex, int(ifIndex))
netInterface, err := net.InterfaceByIndex(int(ifIndex))
if err == nil && netInterface.Name == link.iif.Name {
continue
}
delete(i.links, ifIndex)
i.defaultRouteSequence = common.Filter(i.defaultRouteSequence, func(it int32) bool {
return it != ifIndex
})
@@ -198,9 +198,6 @@ func (i *Service) onNetworkUpdate() {
i.deleteCallback(link)
}
}
for _, ifIndex := range deleteIfIndex {
delete(i.links, int32(ifIndex))
}
}
func (conf *TransportLink) nameList(ndots int, name string) []string {
+26 -7
View File
@@ -192,7 +192,7 @@ func (t *Transport) updateTransports(link *TransportLink) error {
Enabled: true,
ServerName: serverAddr.String(),
}))
transports = append(transports, transport.NewTLSRaw(t.logger, t.TransportAdapter, serverDialer, M.SocksaddrFrom(serverAddr, 53), tlsConfig))
transports = append(transports, transport.NewTLSRaw(t.logger, t.TransportAdapter, serverDialer, M.SocksaddrFrom(serverAddr, 853), tlsConfig))
} else {
transports = append(transports, transport.NewUDPRaw(t.logger, t.TransportAdapter, serverDialer, M.SocksaddrFrom(serverAddr, 53)))
@@ -203,7 +203,11 @@ func (t *Transport) updateTransports(link *TransportLink) error {
if !ok {
return os.ErrInvalid
}
serverPort := address.Port
if link.dnsOverTLS {
if serverPort == 0 {
serverPort = 853
}
var serverName string
if address.Name != "" {
serverName = address.Name
@@ -214,10 +218,13 @@ func (t *Transport) updateTransports(link *TransportLink) error {
Enabled: true,
ServerName: serverName,
}))
transports = append(transports, transport.NewTLSRaw(t.logger, t.TransportAdapter, serverDialer, M.SocksaddrFrom(serverAddr, address.Port), tlsConfig))
transports = append(transports, transport.NewTLSRaw(t.logger, t.TransportAdapter, serverDialer, M.SocksaddrFrom(serverAddr, serverPort), tlsConfig))
} else {
transports = append(transports, transport.NewUDPRaw(t.logger, t.TransportAdapter, serverDialer, M.SocksaddrFrom(serverAddr, address.Port)))
if serverPort == 0 {
serverPort = 53
}
transports = append(transports, transport.NewUDPRaw(t.logger, t.TransportAdapter, serverDialer, M.SocksaddrFrom(serverAddr, serverPort)))
}
}
t.linkServers[link] = &LinkServers{
@@ -248,7 +255,7 @@ func (t *Transport) PreferredDomain(domain string) bool {
if linkDomain.Domain == "." {
continue
}
if mDNS.IsSubDomain(linkDomain.Domain, domain) {
if mDNS.IsSubDomain(mDNS.Fqdn(linkDomain.Domain), domain) {
return true
}
}
@@ -273,15 +280,25 @@ func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg,
func (t *Transport) ExchangeAsync(ctx context.Context, message *mDNS.Msg, callback func(response *mDNS.Msg, err error)) {
question := message.Question[0]
var selectedLink *TransportLink
var (
selectedLink *TransportLink
selectedLabels int
names []string
)
t.service.linkAccess.RLock()
for _, link := range t.service.links {
for _, domain := range link.domain {
if domain.Domain == "." && domain.RoutingOnly && !t.acceptDefaultResolvers {
continue
}
if mDNS.IsSubDomain(domain.Domain, question.Name) {
domainName := mDNS.Fqdn(domain.Domain)
if !mDNS.IsSubDomain(domainName, question.Name) {
continue
}
labels := mDNS.CountLabel(domainName)
if selectedLink == nil || labels > selectedLabels {
selectedLink = link
selectedLabels = labels
}
}
}
@@ -293,6 +310,9 @@ func (t *Transport) ExchangeAsync(ctx context.Context, message *mDNS.Msg, callba
}
}
}
if selectedLink != nil {
names = selectedLink.nameList(t.ndots, question.Name)
}
t.service.linkAccess.RUnlock()
if selectedLink == nil {
callback(dns.FixedResponseStatus(message, mDNS.RcodeNameError), nil)
@@ -305,7 +325,6 @@ func (t *Transport) ExchangeAsync(ctx context.Context, message *mDNS.Msg, callba
callback(dns.FixedResponseStatus(message, mDNS.RcodeNameError), nil)
return
}
names := servers.Link.nameList(t.ndots, question.Name)
if len(names) == 0 {
callback(nil, E.New("invalid domain: ", question.Name))
return