diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 13228efd4c..581155c2ae 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -33,5 +33,5 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }} FURY_TOKEN: ${{ secrets.FURY_TOKEN }} - NFPM_KEY_PATH: ${{ env.Home }}/.gnupg/sagernet.key + NFPM_KEY_PATH: ${{ env.HOME }}/.gnupg/sagernet.key NFPM_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} diff --git a/common/dialer/default.go b/common/dialer/default.go index 91af85c524..4fbad07deb 100644 --- a/common/dialer/default.go +++ b/common/dialer/default.go @@ -32,14 +32,20 @@ func NewDefault(router adapter.Router, options option.DialerOptions) (*DefaultDi var dialer net.Dialer var listener net.ListenConfig if options.BindInterface != "" { - bindFunc := control.BindToInterface(router.InterfaceFinder(), options.BindInterface, -1) + var interfaceFinder control.InterfaceFinder + if router != nil { + interfaceFinder = router.InterfaceFinder() + } else { + interfaceFinder = control.NewDefaultInterfaceFinder() + } + bindFunc := control.BindToInterface(interfaceFinder, options.BindInterface, -1) dialer.Control = control.Append(dialer.Control, bindFunc) listener.Control = control.Append(listener.Control, bindFunc) - } else if router.AutoDetectInterface() { + } else if router != nil && router.AutoDetectInterface() { bindFunc := router.AutoDetectInterfaceFunc() dialer.Control = control.Append(dialer.Control, bindFunc) listener.Control = control.Append(listener.Control, bindFunc) - } else if router.DefaultInterface() != "" { + } else if router != nil && router.DefaultInterface() != "" { bindFunc := control.BindToInterface(router.InterfaceFinder(), router.DefaultInterface(), -1) dialer.Control = control.Append(dialer.Control, bindFunc) listener.Control = control.Append(listener.Control, bindFunc) @@ -47,7 +53,7 @@ func NewDefault(router adapter.Router, options option.DialerOptions) (*DefaultDi if options.RoutingMark != 0 { dialer.Control = control.Append(dialer.Control, control.RoutingMark(options.RoutingMark)) listener.Control = control.Append(listener.Control, control.RoutingMark(options.RoutingMark)) - } else if router.DefaultMark() != 0 { + } else if router != nil && router.DefaultMark() != 0 { dialer.Control = control.Append(dialer.Control, control.RoutingMark(router.DefaultMark())) listener.Control = control.Append(listener.Control, control.RoutingMark(router.DefaultMark())) } diff --git a/common/dialer/dialer.go b/common/dialer/dialer.go index bbb4b3a92e..a1721b281f 100644 --- a/common/dialer/dialer.go +++ b/common/dialer/dialer.go @@ -13,6 +13,9 @@ func New(router adapter.Router, options option.DialerOptions) (N.Dialer, error) if options.IsWireGuardListener { return NewDefault(router, options) } + if router == nil { + return NewDefault(nil, options) + } var ( dialer N.Dialer err error diff --git a/docs/changelog.md b/docs/changelog.md index 440e8c5315..d0789dbe6b 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -2,7 +2,21 @@ icon: material/alert-decagram --- -#### 1.9.0-rc.10 +#### 1.9.0-rc.12 + +* Fixes and improvements + +#### 1.8.12 + +* Now we have official APT and DNF repositories **1** +* Fix packet MTU for QUIC protocols +* Fixes and improvements + +**1**: + +Including stable and beta versions, see https://sing-box.sagernet.org/installation/package-manager/ + +#### 1.9.0-rc.11 * Fixes and improvements diff --git a/docs/clients/apple/index.md b/docs/clients/apple/index.md index d1db99c6c9..cd090776ef 100644 --- a/docs/clients/apple/index.md +++ b/docs/clients/apple/index.md @@ -15,11 +15,12 @@ platform-specific function implementation, such as TUN transparent proxy impleme ## :material-download: Download * [App Store](https://apps.apple.com/us/app/sing-box/id6451272673) -* ~~[TestFlight (Beta)](https://testflight.apple.com/join/AcqO44FH)~~ +* ~~TestFlight (Beta)~~ -_Our Testflight distribution has been temporarily blocked by Apple (possibly due to too many beta versions) -and you cannot join the test, install or update the sing-box beta app right now. -Please wait patiently for processing._ +TestFlight quota is only available to [sponsors](https://github.com/sponsors/nekohasekai) +(one-time sponsorships are accepted). +Once you donate, you can get an invitation by sending us your Apple ID [via email](mailto:contact@sagernet.org), +or join our Telegram group for sponsors from [@yet_another_sponsor_bot](https://t.me/yet_another_sponsor_bot). ## :material-file-download: Download (macOS standalone version) diff --git a/docs/configuration/inbound/tun.md b/docs/configuration/inbound/tun.md index 15a342ff0d..1d5d8d0f65 100644 --- a/docs/configuration/inbound/tun.md +++ b/docs/configuration/inbound/tun.md @@ -147,7 +147,7 @@ Enforce strict routing rules when `auto_route` is enabled: * Let unsupported network unreachable * Route all connections to tun -It prevents address leaks and makes DNS hijacking work on Android, but your device will not be accessible by others. +It prevents address leaks and makes DNS hijacking work on Android. *In Windows*: diff --git a/docs/configuration/inbound/tun.zh.md b/docs/configuration/inbound/tun.zh.md index 78c4605892..73d31d6497 100644 --- a/docs/configuration/inbound/tun.zh.md +++ b/docs/configuration/inbound/tun.zh.md @@ -147,7 +147,7 @@ tun 接口的 IPv6 前缀。 * 让不支持的网络无法到达 * 将所有连接路由到 tun -它可以防止地址泄漏,并使 DNS 劫持在 Android 上工作,但你的设备将无法其他设备被访问。 +它可以防止地址泄漏,并使 DNS 劫持在 Android 上工作。 *在 Windows 中*: diff --git a/experimental/cachefile/fakeip.go b/experimental/cachefile/fakeip.go index 1c387da8cf..8fe0f1139c 100644 --- a/experimental/cachefile/fakeip.go +++ b/experimental/cachefile/fakeip.go @@ -74,6 +74,7 @@ func (c *CacheFile) FakeIPStore(address netip.Addr, domain string) error { if err != nil { return err } + oldDomain := bucket.Get(address.AsSlice()) err = bucket.Put(address.AsSlice(), []byte(domain)) if err != nil { return err @@ -86,12 +87,24 @@ func (c *CacheFile) FakeIPStore(address netip.Addr, domain string) error { if err != nil { return err } + if oldDomain != nil { + if err := bucket.Delete(oldDomain); err != nil { + return err + } + } return bucket.Put([]byte(domain), address.AsSlice()) }) } func (c *CacheFile) FakeIPStoreAsync(address netip.Addr, domain string, logger logger.Logger) { c.saveFakeIPAccess.Lock() + if oldDomain, loaded := c.saveDomain[address]; loaded { + if address.Is4() { + delete(c.saveAddress4, oldDomain) + } else { + delete(c.saveAddress6, oldDomain) + } + } c.saveDomain[address] = domain if address.Is4() { c.saveAddress4[domain] = address diff --git a/go.mod b/go.mod index b51a33d113..7989dcbe5b 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,7 @@ require ( github.com/sagernet/gvisor v0.0.0-20240315080113-799fb6b6d311 github.com/sagernet/quic-go v0.42.0-beta.3 github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 - github.com/sagernet/sing v0.4.0-beta.17 + github.com/sagernet/sing v0.4.0-beta.18 github.com/sagernet/sing-dns v0.2.0-beta.16 github.com/sagernet/sing-mux v0.2.0 github.com/sagernet/sing-quic v0.1.13-beta.1 diff --git a/go.sum b/go.sum index 66699d04a9..5c01c50f4e 100644 --- a/go.sum +++ b/go.sum @@ -117,8 +117,8 @@ github.com/sagernet/quic-go v0.42.0-beta.3/go.mod h1:lf8OYop+fMxIlrfM/ZHpENt/7ZD github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc= github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU= github.com/sagernet/sing v0.2.18/go.mod h1:OL6k2F0vHmEzXz2KW19qQzu172FDgSbUSODylighuVo= -github.com/sagernet/sing v0.4.0-beta.17 h1:TWvtCTw39YyAbiVT3NXd46ts7LxxDolplJDGedBbsmg= -github.com/sagernet/sing v0.4.0-beta.17/go.mod h1:+60H3Cm91RnL9dpVGWDPHt0zTQImO9Vfqt9a4rSambI= +github.com/sagernet/sing v0.4.0-beta.18 h1:oK+pvyXnFwxwvQkeUqgxIeATiMHcrH5doLKKDGNmQkU= +github.com/sagernet/sing v0.4.0-beta.18/go.mod h1:PFQKbElc2Pke7faBLv8oEba5ehtKO21Ho+TkYemTI3Y= github.com/sagernet/sing-dns v0.2.0-beta.16 h1:bzd4B8eHD7/WO3HrYknvgE8A56/R3n5oXBjNF97iPzQ= github.com/sagernet/sing-dns v0.2.0-beta.16/go.mod h1:XU6Vqr6aHcMz/34Fcv8jmXpRCEuShzW+B7Qg1Xe1nxY= github.com/sagernet/sing-mux v0.2.0 h1:4C+vd8HztJCWNYfufvgL49xaOoOHXty2+EAjnzN3IYo= diff --git a/route/router_dns.go b/route/router_dns.go index fee468fa54..c3383e8b46 100644 --- a/route/router_dns.go +++ b/route/router_dns.go @@ -65,7 +65,7 @@ func (r *Router) matchDNS(ctx context.Context, allowFakeIP bool, index int) (con ruleIndex += index + 1 } r.dnsLogger.DebugContext(ctx, "match[", ruleIndex, "] ", rule.String(), " => ", detour) - if (isFakeIP && !r.dnsIndependentCache) || rule.DisableCache() { + if isFakeIP || rule.DisableCache() { ctx = dns.ContextWithDisableCache(ctx, true) } if rewriteTTL := rule.RewriteTTL(); rewriteTTL != nil { diff --git a/test/go.mod b/test/go.mod index cbb9d2f011..adbb8f5e5b 100644 --- a/test/go.mod +++ b/test/go.mod @@ -12,10 +12,10 @@ require ( github.com/docker/docker v24.0.7+incompatible github.com/docker/go-connections v0.4.0 github.com/gofrs/uuid/v5 v5.1.0 - github.com/sagernet/quic-go v0.42.0-beta.2 - github.com/sagernet/sing v0.4.0-beta.15 + github.com/sagernet/quic-go v0.42.0-beta.3 + github.com/sagernet/sing v0.4.0-beta.18 github.com/sagernet/sing-dns v0.2.0-beta.16 - github.com/sagernet/sing-quic v0.1.12-beta.1 + github.com/sagernet/sing-quic v0.1.13-beta.1 github.com/sagernet/sing-shadowsocks v0.2.6 github.com/sagernet/sing-shadowsocks2 v0.2.0 github.com/spyzhov/ajson v0.9.0 @@ -59,7 +59,7 @@ require ( github.com/libdns/libdns v0.2.2 // indirect github.com/logrusorgru/aurora v2.0.3+incompatible // indirect github.com/mholt/acmez v1.2.0 // indirect - github.com/miekg/dns v1.1.58 // indirect + github.com/miekg/dns v1.1.59 // indirect github.com/moby/term v0.5.0 // indirect github.com/morikuni/aec v1.0.0 // indirect github.com/onsi/ginkgo/v2 v2.9.7 // indirect @@ -94,12 +94,12 @@ require ( go.uber.org/zap v1.27.0 // indirect go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect golang.org/x/crypto v0.22.0 // indirect - golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 // indirect - golang.org/x/mod v0.16.0 // indirect + golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect + golang.org/x/mod v0.17.0 // indirect golang.org/x/sys v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.19.0 // indirect + golang.org/x/tools v0.20.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect google.golang.org/grpc v1.63.2 // indirect google.golang.org/protobuf v1.33.0 // indirect diff --git a/test/go.sum b/test/go.sum index bad7aab933..4943d3a20e 100644 --- a/test/go.sum +++ b/test/go.sum @@ -96,6 +96,7 @@ github.com/mholt/acmez v1.2.0/go.mod h1:VT9YwH1xgNX1kmYY89gY8xPJC84BFAisjo8Egigt github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM= github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk= github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY= +github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk= github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= @@ -136,6 +137,7 @@ github.com/sagernet/quic-go v0.40.0 h1:DvQNPb72lzvNQDe9tcUyHTw8eRv6PLtM2mNYmdlzU github.com/sagernet/quic-go v0.40.0/go.mod h1:VqtdhlbkeeG5Okhb3eDMb/9o0EoglReHunNT9ukrJAI= github.com/sagernet/quic-go v0.41.0-beta.2/go.mod h1:X10Mf9DVHuSEReOLov/XuflD13MVLH3WtppVVFnSItU= github.com/sagernet/quic-go v0.42.0-beta.2/go.mod h1:lf8OYop+fMxIlrfM/ZHpENt/7ZD4JaVNqMhOlq2QMwg= +github.com/sagernet/quic-go v0.42.0-beta.3/go.mod h1:lf8OYop+fMxIlrfM/ZHpENt/7ZD4JaVNqMhOlq2QMwg= github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc= github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU= github.com/sagernet/sing v0.2.18/go.mod h1:OL6k2F0vHmEzXz2KW19qQzu172FDgSbUSODylighuVo= @@ -149,6 +151,7 @@ github.com/sagernet/sing v0.4.0-beta.3/go.mod h1:+60H3Cm91RnL9dpVGWDPHt0zTQImO9V github.com/sagernet/sing v0.4.0-beta.4/go.mod h1:+60H3Cm91RnL9dpVGWDPHt0zTQImO9Vfqt9a4rSambI= github.com/sagernet/sing v0.4.0-beta.6/go.mod h1:+60H3Cm91RnL9dpVGWDPHt0zTQImO9Vfqt9a4rSambI= github.com/sagernet/sing v0.4.0-beta.15/go.mod h1:+60H3Cm91RnL9dpVGWDPHt0zTQImO9Vfqt9a4rSambI= +github.com/sagernet/sing v0.4.0-beta.18/go.mod h1:PFQKbElc2Pke7faBLv8oEba5ehtKO21Ho+TkYemTI3Y= github.com/sagernet/sing-dns v0.1.11 h1:PPrMCVVrAeR3f5X23I+cmvacXJ+kzuyAsBiWyUKhGSE= github.com/sagernet/sing-dns v0.1.11/go.mod h1:zJ/YjnYB61SYE+ubMcMqVdpaSvsyQ2iShQGO3vuLvvE= github.com/sagernet/sing-dns v0.2.0-beta.2/go.mod h1:IxOqfSb6Zt6UVCy8fJpDxb2XxqzHUytNqeOuJfaiLu8= @@ -167,6 +170,7 @@ github.com/sagernet/sing-quic v0.1.9-beta.1/go.mod h1:F4AXCZiwtRtYdLUTjVMO6elTpA github.com/sagernet/sing-quic v0.1.9-beta.3/go.mod h1:oXe0g8T7edh2Xxl0QcpTO4Tret8M478LpMcr3CPuqWE= github.com/sagernet/sing-quic v0.1.10-beta.2/go.mod h1:TTnOMr3o3rI+zNxTo+SGBJwouzjIEC3FchJJY1F1ca4= github.com/sagernet/sing-quic v0.1.12-beta.1/go.mod h1:TTnOMr3o3rI+zNxTo+SGBJwouzjIEC3FchJJY1F1ca4= +github.com/sagernet/sing-quic v0.1.13-beta.1/go.mod h1:Bny0k0Puf7yxhtXfovVyz3gfkHvS1T+/ieKLPhfnhY4= github.com/sagernet/sing-shadowsocks v0.2.6 h1:xr7ylAS/q1cQYS8oxKKajhuQcchd5VJJ4K4UZrrpp0s= github.com/sagernet/sing-shadowsocks v0.2.6/go.mod h1:j2YZBIpWIuElPFL/5sJAj470bcn/3QQ5lxZUNKLDNAM= github.com/sagernet/sing-shadowsocks2 v0.1.6-0.20231207143709-50439739601a h1:uYIKfpE1/EJpa+1Bja7b006VixeRuVduOpeuesMk2lU= @@ -245,12 +249,14 @@ golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3/go.mod h1:idGWGoKP1toJGkd5/i golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ= golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ= +golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -301,6 +307,7 @@ golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0 golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/transport/fakeip/memory.go b/transport/fakeip/memory.go index 0bca491036..1640ab349d 100644 --- a/transport/fakeip/memory.go +++ b/transport/fakeip/memory.go @@ -40,6 +40,13 @@ func (s *MemoryStorage) FakeIPSaveMetadataAsync(metadata *adapter.FakeIPMetadata func (s *MemoryStorage) FakeIPStore(address netip.Addr, domain string) error { s.addressAccess.Lock() s.domainAccess.Lock() + if oldDomain, loaded := s.addressCache[address]; loaded { + if address.Is4() { + delete(s.domainCache4, oldDomain) + } else { + delete(s.domainCache6, oldDomain) + } + } s.addressCache[address] = domain if address.Is4() { s.domainCache4[domain] = address