Compare commits

..

24 Commits

Author SHA1 Message Date
wwqgtxx
b585bfdf1b Update cast using in sing-vmess 2025-08-19 23:55:11 +08:00
wwqgtxx
194aad8d40 Make utlsConnWrapper replaceable 2025-08-19 23:26:00 +08:00
wwqgtxx
4e52c357fe Make realityConnWrapper replaceable 2025-08-19 23:26:00 +08:00
世界
3d8a72b9ba
documentation: Bump version 2025-08-19 23:13:53 +08:00
世界
31fca03ef5
Fix wireguard crash 2025-08-19 23:13:53 +08:00
世界
eb09af768c
documentation: Update behavior of local DNS server on darwin 2025-08-19 23:04:22 +08:00
世界
023fcf6572
Stop using DHCP on iOS and tvOS
We do not have the `com.apple.developer.networking.multicast` entitlement and are unable to obtain it for non-technical reasons.
2025-08-19 23:04:22 +08:00
世界
1596e072ab
Remove use of ldflags -checklinkname=0 on darwin 2025-08-19 21:56:56 +08:00
世界
31d88ac7d3
Fix local DNS server on darwin
We mistakenly believed that `libresolv`'s `search` function worked correctly in NetworkExtension, but it seems only `getaddrinfo` does.

This commit changes the behavior of the `local` DNS server in NetworkExtension to prefer DHCP, falling back to `getaddrinfo` if DHCP servers are unavailable.

It's worth noting that `prefer_go` does not disable DHCP since it respects Dial Fields, but `getaddrinfo` does the opposite. The new behavior only applies to NetworkExtension, not to all scenarios (primarily command-line binaries) as it did previously.

In addition, this commit also improves the DHCP DNS server to use the same robust query logic as `local`.
2025-08-19 21:56:56 +08:00
世界
ea9f344763
Fix legacy DNS config 2025-08-19 21:56:56 +08:00
世界
6adc6a5a1d
Fix rule-set format 2025-08-19 21:56:56 +08:00
世界
ec2695aff6
documentation: Remove outdated icons 2025-08-19 21:56:56 +08:00
世界
5f2ec82448
documentation: Improve local DNS server 2025-08-19 21:56:56 +08:00
世界
c84e5d7784
Use libresolv in local DNS server on darwin 2025-08-19 21:56:55 +08:00
世界
169d496b37
Use resolved in local DNS server if available 2025-08-19 21:56:55 +08:00
xchacha20-poly1305
6c468eee6d
Fix rule set version 2025-08-19 21:56:55 +08:00
世界
a031cf2160
documentation: Add preferred_by route rule item 2025-08-19 21:56:54 +08:00
世界
1c39344e00
Add preferred_by route rule item 2025-08-19 21:56:54 +08:00
世界
8e86ada5eb
documentation: Add interface address rule items 2025-08-19 21:56:54 +08:00
世界
fa8141f0d0
Add interface address rule items 2025-08-19 21:56:54 +08:00
neletor
6054fd8ab4
Add support for ech retry configs 2025-08-19 21:56:54 +08:00
Zephyruso
da3cabb548
Add /dns/flush-clash meta api 2025-08-19 21:56:54 +08:00
世界
57e945300c
Bump version 2025-08-19 21:56:05 +08:00
世界
f462ce5615
Update tfo-go 2025-08-19 21:56:05 +08:00
11 changed files with 86 additions and 57 deletions

View File

@ -149,7 +149,7 @@ jobs:
TAGS='with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale'
echo "BUILD_TAGS=${TAGS}" >> "${GITHUB_ENV}"
- name: Build
if: matrix.os != 'darwin' && matrix.os != 'android'
if: matrix.os != 'android'
run: |
set -xeuo pipefail
mkdir -p dist
@ -165,23 +165,6 @@ jobs:
GOMIPS: ${{ matrix.gomips }}
GOMIPS64: ${{ matrix.gomips }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build darwin
if: matrix.os == 'darwin'
run: |
set -xeuo pipefail
mkdir -p dist
go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
-ldflags '-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -checklinkname=0' \
./cmd/sing-box
env:
CGO_ENABLED: "0"
GOOS: ${{ matrix.os }}
GOARCH: ${{ matrix.arch }}
GO386: ${{ matrix.go386 }}
GOARM: ${{ matrix.goarm }}
GOMIPS: ${{ matrix.gomips }}
GOMIPS64: ${{ matrix.gomips }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build Android
if: matrix.os == 'android'
run: |

View File

@ -46,7 +46,7 @@ var (
sharedFlags []string
debugFlags []string
sharedTags []string
darwinTags []string
macOSTags []string
memcTags []string
notMemcTags []string
debugTags []string
@ -59,11 +59,11 @@ func init() {
if err != nil {
currentTag = "unknown"
}
sharedFlags = append(sharedFlags, "-ldflags", "-X github.com/sagernet/sing-box/constant.Version="+currentTag+" -s -w -buildid= -checklinkname=0")
debugFlags = append(debugFlags, "-ldflags", "-X github.com/sagernet/sing-box/constant.Version="+currentTag+"-s -w -buildid= -checklinkname=0")
sharedFlags = append(sharedFlags, "-ldflags", "-X github.com/sagernet/sing-box/constant.Version="+currentTag+" -s -w -buildid=")
debugFlags = append(debugFlags, "-ldflags", "-X github.com/sagernet/sing-box/constant.Version="+currentTag)
sharedTags = append(sharedTags, "with_gvisor", "with_quic", "with_wireguard", "with_utls", "with_clash_api", "with_conntrack")
darwinTags = append(darwinTags, "with_dhcp")
macOSTags = append(macOSTags, "with_dhcp")
memcTags = append(memcTags, "with_tailscale")
notMemcTags = append(notMemcTags, "with_low_memory")
debugTags = append(debugTags, "debug")
@ -106,17 +106,19 @@ func buildAndroid() {
"-libname=box",
}
if !debugEnabled {
sharedFlags[3] = sharedFlags[3] + " -checklinkname=0"
args = append(args, sharedFlags...)
} else {
debugFlags[1] = debugFlags[1] + " -checklinkname=0"
args = append(args, debugFlags...)
}
tags := append(sharedTags, memcTags...)
if debugEnabled {
tags = append(tags, debugTags...)
}
if !debugEnabled {
args = append(args, sharedFlags...)
} else {
args = append(args, debugFlags...)
}
args = append(args, "-tags", strings.Join(tags, ","))
args = append(args, "./experimental/libbox")
@ -158,7 +160,9 @@ func buildApple() {
"-tags-not-macos=with_low_memory",
}
if !withTailscale {
args = append(args, "-tags-macos="+strings.Join(memcTags, ","))
args = append(args, "-tags-macos="+strings.Join(append(macOSTags, memcTags...), ","))
} else {
args = append(args, "-tags-macos="+strings.Join(macOSTags, ","))
}
if !debugEnabled {
@ -167,7 +171,7 @@ func buildApple() {
args = append(args, debugFlags...)
}
tags := append(sharedTags, darwinTags...)
tags := sharedTags
if withTailscale {
tags = append(tags, memcTags...)
}

View File

@ -206,3 +206,11 @@ func (c *realityConnWrapper) Upstream() any {
func (c *realityConnWrapper) CloseWrite() error {
return c.Close()
}
func (c *realityConnWrapper) ReaderReplaceable() bool {
return true
}
func (c *realityConnWrapper) WriterReplaceable() bool {
return true
}

View File

@ -106,6 +106,14 @@ func (c *utlsConnWrapper) Upstream() any {
return c.UConn
}
func (c *utlsConnWrapper) ReaderReplaceable() bool {
return true
}
func (c *utlsConnWrapper) WriterReplaceable() bool {
return true
}
type utlsALPNWrapper struct {
utlsConnWrapper
nextProtocols []string

View File

@ -197,7 +197,11 @@ func (t *Transport) fetchServers0(ctx context.Context, iface *control.Interface)
}
defer packetConn.Close()
discovery, err := dhcpv4.NewDiscovery(iface.HardwareAddr, dhcpv4.WithBroadcast(true), dhcpv4.WithRequestedOptions(dhcpv4.OptionDomainNameServer, dhcpv4.OptionDNSDomainSearchList))
discovery, err := dhcpv4.NewDiscovery(iface.HardwareAddr, dhcpv4.WithBroadcast(true), dhcpv4.WithRequestedOptions(
dhcpv4.OptionDomainName,
dhcpv4.OptionDomainNameServer,
dhcpv4.OptionDNSDomainSearchList,
))
if err != nil {
return err
}
@ -249,8 +253,10 @@ func (t *Transport) fetchServersResponse(iface *control.Interface, packetConn ne
func (t *Transport) recreateServers(iface *control.Interface, dhcpPacket *dhcpv4.DHCPv4) error {
searchList := dhcpPacket.DomainSearch()
if searchList != nil {
if searchList != nil && len(searchList.Labels) > 0 {
t.search = searchList.Labels
} else if dhcpPacket.DomainName() != "" {
t.search = []string{dhcpPacket.DomainName()}
}
serverAddrs := common.Map(dhcpPacket.DNS(), func(it net.IP) M.Socksaddr {
return M.SocksaddrFrom(M.AddrFromIP(it), 53)

View File

@ -7,6 +7,7 @@ import (
"errors"
"net"
mDNS "github.com/miekg/dns"
"github.com/sagernet/sing-box/adapter"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/dns"
@ -19,8 +20,6 @@ import (
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
"github.com/sagernet/sing/service"
mDNS "github.com/miekg/dns"
)
func RegisterTransport(registry *dns.TransportRegistry) {
@ -74,6 +73,7 @@ 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 {
@ -83,6 +83,7 @@ func (t *Transport) Start(stage adapter.StartStage) error {
}
}
}
}
return nil
}
@ -104,12 +105,14 @@ func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg,
if !t.fallback {
return t.exchange(ctx, message, domain)
}
if !C.IsIos {
if t.dhcpTransport != nil {
dhcpTransports, _ := t.dhcpTransport.Fetch()
if len(dhcpTransports) > 0 {
return t.dhcpTransport.Exchange0(ctx, message, dhcpTransports)
}
}
}
if t.preferGo {
// Assuming the user knows what they are doing, we still execute the query which will fail.
return t.exchange(ctx, message, domain)
@ -131,5 +134,9 @@ func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg,
}
return dns.FixedResponse(message.Id, question, addresses, C.DefaultDNSTTL), nil
}
return nil, E.New("only A and AAAA queries are supported on Apple platforms when using TUN and DHCP unavailable.")
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.")
}
}

View File

@ -2,6 +2,14 @@
icon: material/alert-decagram
---
#### 1.13.0-alpha.4
* Fixes and improvements
#### 1.12.2
* Fixes and improvements
#### 1.13.0-alpha.3
* Improve `local` DNS server **1**

View File

@ -43,16 +43,18 @@ When enabled, `local` DNS server will resolve DNS by dialing itself whenever pos
Specifically, it disables following behaviors which was added as features in sing-box 1.13.0:
* On Apple platforms: Use `libresolv` for resolution, as it is the only one that works properly with NetworkExtension
that overrides DNS servers (DHCP is also possible but is not considered).
* On Linux: Resolve through `systemd-resolvd`'s DBus interface when available.
1. On Apple platforms: Attempt to resolve A/AAAA requests using `getaddrinfo` in NetworkExtension.
2. On Linux: Resolve through `systemd-resolvd`'s DBus interface when available.
As a sole exception, it cannot disable the following behavior:
In the Android graphical client, the `local` DNS server will always resolve DNS through the platform interface,
as there is no other way to obtain upstream DNS servers.
1. In the Android graphical client,
`local` will always resolve DNS through the platform interface,
as there is no other way to obtain upstream DNS servers;
On devices running Android versions lower than 10, this interface can only resolve A/AAAA requests.
On devices running Android versions lower than 10, this interface can only resolve IP queries.
2. On macOS, `local` will try DHCP first in Network Extension, since DHCP respects DIal Fields,
it will not be disabled by `prefer_go`.
### Dial Fields

4
go.mod
View File

@ -15,7 +15,7 @@ require (
github.com/libdns/alidns v1.0.5-libdns.v1.beta1
github.com/libdns/cloudflare v0.2.2-0.20250708034226-c574dccb31a6
github.com/logrusorgru/aurora v2.0.3+incompatible
github.com/metacubex/tfo-go v0.0.0-20241231083714-66613d49c422
github.com/metacubex/tfo-go v0.0.0-20250516165257-e29c16ae41d4
github.com/metacubex/utls v1.8.0
github.com/mholt/acmez/v3 v3.1.2
github.com/miekg/dns v1.1.67
@ -34,7 +34,7 @@ require (
github.com/sagernet/sing-shadowsocks2 v0.2.1
github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11
github.com/sagernet/sing-tun v0.7.0-beta.1
github.com/sagernet/sing-vmess v0.2.6
github.com/sagernet/sing-vmess v0.2.7
github.com/sagernet/smux v1.5.34-mod.2
github.com/sagernet/tailscale v1.80.3-mod.5
github.com/sagernet/wireguard-go v0.0.1-beta.7

8
go.sum
View File

@ -122,8 +122,8 @@ github.com/mdlayher/sdnotify v1.0.0 h1:Ma9XeLVN/l0qpyx1tNeMSeTjCPH6NtuD6/N9XdTlQ
github.com/mdlayher/sdnotify v1.0.0/go.mod h1:HQUmpM4XgYkhDLtd+Uad8ZFK1T9D5+pNxnXQjCeJlGE=
github.com/mdlayher/socket v0.5.1 h1:VZaqt6RkGkt2OE9l3GcC6nZkqD3xKeQLyfleW/uBcos=
github.com/mdlayher/socket v0.5.1/go.mod h1:TjPLHI1UgwEv5J1B5q0zTZq12A/6H7nKmtTanQE37IQ=
github.com/metacubex/tfo-go v0.0.0-20241231083714-66613d49c422 h1:zGeQt3UyNydIVrMRB97AA5WsYEau/TyCnRtTf1yUmJY=
github.com/metacubex/tfo-go v0.0.0-20241231083714-66613d49c422/go.mod h1:l9oLnLoEXyGZ5RVLsh7QCC5XsouTUyKk4F2nLm2DHLw=
github.com/metacubex/tfo-go v0.0.0-20250516165257-e29c16ae41d4 h1:j1VRTiC9JLR4nUbSikx9OGdu/3AgFDqgcLj4GoqyQkc=
github.com/metacubex/tfo-go v0.0.0-20250516165257-e29c16ae41d4/go.mod h1:l9oLnLoEXyGZ5RVLsh7QCC5XsouTUyKk4F2nLm2DHLw=
github.com/metacubex/utls v1.8.0 h1:mSYi6FMnmc5riARl5UZDmWVy710z+P5b7xuGW0lV9ac=
github.com/metacubex/utls v1.8.0/go.mod h1:FdjYzVfCtgtna19hX0ER1Xsa5uJInwdQ4IcaaI98lEQ=
github.com/mholt/acmez/v3 v3.1.2 h1:auob8J/0FhmdClQicvJvuDavgd5ezwLBfKuYmynhYzc=
@ -181,8 +181,8 @@ github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11 h1:tK+75
github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11/go.mod h1:sWqKnGlMipCHaGsw1sTTlimyUpgzP4WP3pjhCsYt9oA=
github.com/sagernet/sing-tun v0.7.0-beta.1 h1:mBIFXYAnGO5ey/HcCYanqnBx61E7yF8zTFGRZonGYmY=
github.com/sagernet/sing-tun v0.7.0-beta.1/go.mod h1:AHJuRrLbNRJuivuFZ2VhXwDj4ViYp14szG5EkkKAqRQ=
github.com/sagernet/sing-vmess v0.2.6 h1:1c4dGzeGy0kpBXXrT1sgiMZtHhdJylIT8eWrGhJYZec=
github.com/sagernet/sing-vmess v0.2.6/go.mod h1:5aYoOtYksAyS0NXDm0qKeTYW1yoE1bJVcv+XLcVoyJs=
github.com/sagernet/sing-vmess v0.2.7 h1:2ee+9kO0xW5P4mfe6TYVWf9VtY8k1JhNysBqsiYj0sk=
github.com/sagernet/sing-vmess v0.2.7/go.mod h1:5aYoOtYksAyS0NXDm0qKeTYW1yoE1bJVcv+XLcVoyJs=
github.com/sagernet/smux v1.5.34-mod.2 h1:gkmBjIjlJ2zQKpLigOkFur5kBKdV6bNRoFu2WkltRQ4=
github.com/sagernet/smux v1.5.34-mod.2/go.mod h1:0KW0+R+ycvA2INW4gbsd7BNyg+HEfLIAxa5N02/28Zc=
github.com/sagernet/tailscale v1.80.3-mod.5 h1:7V7z+p2C//TGtff20pPnDCt3qP6uFyY62peJoKF9z/A=

View File

@ -223,6 +223,9 @@ func (e *Endpoint) Close() error {
}
func (e *Endpoint) Lookup(address netip.Addr) *device.Peer {
if e.allowedIPs == nil {
return nil
}
return e.allowedIPs.Lookup(address.AsSlice())
}