diff --git a/cmd/internal/build_libbox/main.go b/cmd/internal/build_libbox/main.go index 3400473cf..045d3dc57 100644 --- a/cmd/internal/build_libbox/main.go +++ b/cmd/internal/build_libbox/main.go @@ -46,7 +46,7 @@ var ( sharedFlags []string debugFlags []string sharedTags []string - macOSTags []string + darwinTags []string memcTags []string notMemcTags []string debugTags []string @@ -63,7 +63,7 @@ func init() { debugFlags = append(debugFlags, "-ldflags", "-X github.com/sagernet/sing-box/constant.Version="+currentTag+" -checklinkname=0") sharedTags = append(sharedTags, "with_gvisor", "with_quic", "with_wireguard", "with_utls", "with_clash_api", "with_conntrack", "badlinkname", "tfogo_checklinkname0") - macOSTags = append(macOSTags, "with_dhcp") + darwinTags = append(darwinTags, "with_dhcp") memcTags = append(memcTags, "with_tailscale") notMemcTags = append(notMemcTags, "with_low_memory") debugTags = append(debugTags, "debug") @@ -158,9 +158,7 @@ func buildApple() { "-tags-not-macos=with_low_memory", } if !withTailscale { - args = append(args, "-tags-macos="+strings.Join(append(macOSTags, memcTags...), ",")) - } else { - args = append(args, "-tags-macos="+strings.Join(macOSTags, ",")) + args = append(args, "-tags-macos="+strings.Join(memcTags, ",")) } if !debugEnabled { @@ -169,7 +167,7 @@ func buildApple() { args = append(args, debugFlags...) } - tags := sharedTags + tags := append(sharedTags, darwinTags...) if withTailscale { tags = append(tags, memcTags...) } diff --git a/constant/dhcp.go b/constant/dhcp.go index 1d9792a2c..bdabd06ec 100644 --- a/constant/dhcp.go +++ b/constant/dhcp.go @@ -4,5 +4,5 @@ import "time" const ( DHCPTTL = time.Hour - DHCPTimeout = time.Minute + DHCPTimeout = 5 * time.Second ) diff --git a/dns/transport/dhcp/dhcp.go b/dns/transport/dhcp/dhcp.go index d25b081f9..3f13d1d95 100644 --- a/dns/transport/dhcp/dhcp.go +++ b/dns/transport/dhcp/dhcp.go @@ -49,6 +49,7 @@ type Transport struct { interfaceCallback *list.Element[tun.DefaultInterfaceUpdateCallback] transportLock sync.RWMutex updatedAt time.Time + lastError error servers []M.Socksaddr search []string ndots int @@ -92,7 +93,7 @@ func (t *Transport) Start(stage adapter.StartStage) error { t.interfaceCallback = t.networkManager.InterfaceMonitor().RegisterCallback(t.interfaceUpdated) } go func() { - _, err := t.Fetch() + _, err := t.fetch() if err != nil { t.logger.Error(E.Cause(err, "fetch DNS servers")) } @@ -108,7 +109,7 @@ func (t *Transport) Close() error { } func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) { - servers, err := t.Fetch() + servers, err := t.fetch() if err != nil { return nil, err } @@ -128,11 +129,20 @@ func (t *Transport) Exchange0(ctx context.Context, message *mDNS.Msg, servers [] } } -func (t *Transport) Fetch() ([]M.Socksaddr, error) { +func (t *Transport) Fetch() []M.Socksaddr { + servers, _ := t.fetch() + return servers +} + +func (t *Transport) fetch() ([]M.Socksaddr, error) { t.transportLock.RLock() updatedAt := t.updatedAt + lastError := t.lastError servers := t.servers t.transportLock.RUnlock() + if lastError != nil { + return nil, lastError + } if time.Since(updatedAt) < C.DHCPTTL { return servers, nil } @@ -143,7 +153,7 @@ func (t *Transport) Fetch() ([]M.Socksaddr, error) { } err := t.updateServers() if err != nil { - return nil, err + return servers, err } return t.servers, nil } @@ -173,12 +183,15 @@ func (t *Transport) updateServers() error { fetchCtx, cancel := context.WithTimeout(t.ctx, C.DHCPTimeout) err = t.fetchServers0(fetchCtx, iface) cancel() + t.updatedAt = time.Now() if err != nil { + t.lastError = err return err } else if len(t.servers) == 0 { - return E.New("dhcp: empty DNS servers response") + t.lastError = E.New("dhcp: empty DNS servers response") + return t.lastError } else { - t.updatedAt = time.Now() + t.lastError = nil return nil } } diff --git a/dns/transport/local/local_darwin.go b/dns/transport/local/local_darwin.go index 3f2b424c0..ee759b914 100644 --- a/dns/transport/local/local_darwin.go +++ b/dns/transport/local/local_darwin.go @@ -43,7 +43,7 @@ type Transport struct { type dhcpTransport interface { adapter.DNSTransport - Fetch() ([]M.Socksaddr, error) + Fetch() []M.Socksaddr Exchange0(ctx context.Context, message *mDNS.Msg, servers []M.Socksaddr) (*mDNS.Msg, error) } @@ -74,14 +74,12 @@ func (t *Transport) Start(stage adapter.StartStage) error { break } } - if !C.IsIos { - if t.fallback { - t.dhcpTransport = newDHCPTransport(t.TransportAdapter, log.ContextWithOverrideLevel(t.ctx, log.LevelDebug), t.dialer, t.logger) - if t.dhcpTransport != nil { - err := t.dhcpTransport.Start(stage) - if err != nil { - return err - } + if t.fallback { + t.dhcpTransport = newDHCPTransport(t.TransportAdapter, log.ContextWithOverrideLevel(t.ctx, log.LevelDebug), t.dialer, t.logger) + if t.dhcpTransport != nil { + err := t.dhcpTransport.Start(stage) + if err != nil { + return err } } } @@ -105,12 +103,10 @@ func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, if !t.fallback { return t.exchange(ctx, message, question.Name) } - if !C.IsIos { - if t.dhcpTransport != nil { - dhcpTransports, _ := t.dhcpTransport.Fetch() - if len(dhcpTransports) > 0 { - return t.dhcpTransport.Exchange0(ctx, message, dhcpTransports) - } + if t.dhcpTransport != nil { + dhcpTransports := t.dhcpTransport.Fetch() + if len(dhcpTransports) > 0 { + return t.dhcpTransport.Exchange0(ctx, message, dhcpTransports) } } if t.preferGo { @@ -134,9 +130,5 @@ func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, } return dns.FixedResponse(message.Id, question, addresses, C.DefaultDNSTTL), nil } - if C.IsIos { - return nil, E.New("only A and AAAA queries are supported on iOS and tvOS when using NetworkExtension.") - } else { - return nil, E.New("only A and AAAA queries are supported on macOS when using NetworkExtension and DHCP unavailable.") - } + return nil, E.New("only A and AAAA queries are supported on Apple platforms when using TUN and DHCP unavailable.") }