mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-10-20 08:14:24 +00:00
Fix resolved service
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user