Compare commits

..

36 Commits

Author SHA1 Message Date
世界
d1b7bf80ea
documentation: Bump version 2025-02-26 09:59:10 +08:00
世界
f6a94c3b4c
release: Use latest goreleaser 2025-02-26 09:59:10 +08:00
世界
3b39989324
Move predefined DNS server to rule action 2025-02-26 09:14:50 +08:00
世界
7b459aa0c1
Fix domain resolver on direct outbound 2025-02-26 09:14:50 +08:00
Zephyruso
6f8d292b51
Fix missing AnyTLS display name 2025-02-26 08:59:29 +08:00
anytls
cb9fd0a856
Update sing-anytls
Co-authored-by: anytls <anytls>
2025-02-26 08:59:29 +08:00
Estel
103edbc456
documentation: Fix typo
Signed-off-by: Estel <callmebedrockdigger@gmail.com>
2025-02-26 08:59:29 +08:00
TargetLocked
489c453591
Fix parsing legacy DNS options 2025-02-26 08:59:29 +08:00
世界
7d6f81ec3f
Fix DNS fallback 2025-02-26 08:59:29 +08:00
世界
72994e5ce0
documentation: Fix missing hosts DNS server 2025-02-26 07:35:35 +08:00
世界
140192ad2f
documentation: Bump version 2025-02-26 07:35:26 +08:00
anytls
080340e8bf
Add MinIdleSession option to AnyTLS outbound
Co-authored-by: anytls <anytls>
2025-02-26 07:35:26 +08:00
ReleTor
2427cd9a35
documentation: Minor fixes 2025-02-26 07:35:25 +08:00
libtry486
80c2332baa
documentation: Fix typo
fix typo

Signed-off-by: libtry486 <89328481+libtry486@users.noreply.github.com>
2025-02-26 07:35:25 +08:00
Alireza Ahmadi
5638226587
Fix Outbound deadlock 2025-02-26 07:35:25 +08:00
世界
3f220129ff
documentation: Fix AnyTLS doc 2025-02-26 07:35:25 +08:00
anytls
dc4201cec2
Add AnyTLS protocol 2025-02-26 07:35:20 +08:00
世界
b750c01eed
Migrate to stdlib ECH support 2025-02-26 07:35:20 +08:00
世界
e3390e292e
Add fallback local DNS server for iOS 2025-02-26 07:35:20 +08:00
世界
5f04bd0a34
Get darwin local DNS server from libresolv 2025-02-26 07:35:19 +08:00
世界
d0aa2b7805
Improve resolve action 2025-02-26 07:35:10 +08:00
世界
cd211c3eaa
Fix toolchain version 2025-02-26 07:35:09 +08:00
世界
76a3e6ac8d
Add back port hopping to hysteria 1 2025-02-26 07:34:55 +08:00
世界
b8afc9eae7
Update dependencies 2025-02-26 07:34:55 +08:00
xchacha20-poly1305
1bf22530c4
Remove single quotes of raw Moziila certs 2025-02-26 07:34:54 +08:00
世界
49abc049cd
Add Tailscale endpoint 2025-02-26 07:34:54 +08:00
世界
fcb7aca80c
Build legacy binaries with latest Go 2025-02-26 07:34:54 +08:00
世界
7d9ccfd03d
documentation: Remove outdated icons 2025-02-26 07:34:53 +08:00
世界
0ebdefa311
documentation: Certificate store 2025-02-26 07:34:53 +08:00
世界
e7b3bc5dbe
documentation: TLS fragment 2025-02-26 07:34:53 +08:00
世界
e5775a7ecb
documentation: Outbound domain resolver 2025-02-26 07:34:53 +08:00
世界
0059810fc5
documentation: Refactor DNS 2025-02-26 07:34:52 +08:00
世界
e5bcb64b35
Add certificate store 2025-02-26 07:34:51 +08:00
世界
2fca0758d7
Add TLS fragment support 2025-02-26 07:34:51 +08:00
世界
2fffb6f896
refactor: Outbound domain resolver 2025-02-26 07:34:51 +08:00
世界
30748cf4d1
refactor: DNS 2025-02-26 07:34:51 +08:00
27 changed files with 95 additions and 170 deletions

View File

@ -155,7 +155,7 @@ jobs:
uses: goreleaser/goreleaser-action@v6
with:
distribution: goreleaser-pro
version: nightly
version: '~> v2'
install-only: true
- name: Extract signing key
run: |-

9
box.go
View File

@ -216,15 +216,8 @@ func New(options Options) (*Box, error) {
} else {
tag = F.ToString(i)
}
endpointCtx := ctx
if tag != "" {
// TODO: remove this
endpointCtx = adapter.WithContext(endpointCtx, &adapter.InboundContext{
Outbound: tag,
})
}
err = endpointManager.Create(
endpointCtx,
ctx,
router,
logFactory.NewLogger(F.ToString("endpoint/", endpointOptions.Type, "[", tag, "]")),
tag,

@ -1 +1 @@
Subproject commit aefe3c029096ddac5189a20a8203a68858152f0a
Subproject commit 0576fd75a67e56048c29d00ef539b4f8f05aec2a

@ -1 +1 @@
Subproject commit ae5818ee5a24af965dc91f80bffa16e1e6c109c1
Subproject commit a828bb3a93b57d0c1b13d74246f0675c5244466d

View File

@ -537,7 +537,7 @@ func FixedResponse(id uint16, question dns.Question, addresses []netip.Addr, tim
Question: []dns.Question{question},
}
for _, address := range addresses {
if address.Is4() && question.Qtype == dns.TypeA {
if address.Is4() {
response.Answer = append(response.Answer, &dns.A{
Hdr: dns.RR_Header{
Name: question.Name,
@ -547,7 +547,7 @@ func FixedResponse(id uint16, question dns.Question, addresses []netip.Addr, tim
},
A: address.AsSlice(),
})
} else if address.Is6() && question.Qtype == dns.TypeAAAA {
} else {
response.Answer = append(response.Answer, &dns.AAAA{
Hdr: dns.RR_Header{
Name: question.Name,

View File

@ -2,7 +2,6 @@ package hosts
import (
"context"
"net/netip"
"os"
"github.com/sagernet/sing-box/adapter"
@ -23,15 +22,11 @@ var _ adapter.DNSTransport = (*Transport)(nil)
type Transport struct {
dns.TransportAdapter
files []*File
predefined map[string][]netip.Addr
files []*File
}
func NewTransport(ctx context.Context, logger log.ContextLogger, tag string, options option.HostsDNSServerOptions) (adapter.DNSTransport, error) {
var (
files []*File
predefined = make(map[string][]netip.Addr)
)
var files []*File
if len(options.Path) == 0 {
files = append(files, NewFile(DefaultPath))
} else {
@ -39,15 +34,9 @@ func NewTransport(ctx context.Context, logger log.ContextLogger, tag string, opt
files = append(files, NewFile(filemanager.BasePath(ctx, os.ExpandEnv(path))))
}
}
if options.Predefined != nil {
for _, entry := range options.Predefined.Entries() {
predefined[mDNS.CanonicalName(entry.Key)] = entry.Value
}
}
return &Transport{
TransportAdapter: dns.NewTransportAdapter(C.DNSTypeHosts, tag, nil),
files: files,
predefined: predefined,
}, nil
}
@ -56,11 +45,8 @@ func (t *Transport) Reset() {
func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
question := message.Question[0]
domain := mDNS.CanonicalName(question.Name)
domain := dns.FqdnToDomain(question.Name)
if question.Qtype == mDNS.TypeA || question.Qtype == mDNS.TypeAAAA {
if addresses, ok := t.predefined[domain]; ok {
return dns.FixedResponse(message.Id, question, addresses, C.DefaultDNSTTL), nil
}
for _, file := range t.files {
addresses := file.Lookup(domain)
if len(addresses) > 0 {

View File

@ -34,7 +34,7 @@ func (f *File) Lookup(name string) []netip.Addr {
f.access.Lock()
defer f.access.Unlock()
f.update()
return f.byName[dns.CanonicalName(name)]
return f.byName[name]
}
func (f *File) update() {

View File

@ -11,6 +11,6 @@ import (
func TestHosts(t *testing.T) {
t.Parallel()
require.Equal(t, []netip.Addr{netip.AddrFrom4([4]byte{127, 0, 0, 1}), netip.IPv6Loopback()}, hosts.NewFile("testdata/hosts").Lookup("localhost"))
require.NotEmpty(t, hosts.NewFile(hosts.DefaultPath).Lookup("localhost"))
require.Equal(t, []netip.Addr{netip.AddrFrom4([4]byte{127, 0, 0, 1}), netip.IPv6Loopback()}, hosts.NewFile("testdata/hosts").Lookup("localhost."))
require.NotEmpty(t, hosts.NewFile(hosts.DefaultPath).Lookup("localhost."))
}

View File

@ -110,6 +110,13 @@ func (t *UDPTransport) exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.M
conn.access.Lock()
delete(conn.callbacks, messageId)
conn.access.Unlock()
callback.access.Lock()
select {
case <-callback.done:
default:
close(callback.done)
}
callback.access.Unlock()
}()
rawMessage, err := exMessage.PackBuffer(buffer.FreeBytes())
if err != nil {

View File

@ -2,16 +2,6 @@
icon: material/alert-decagram
---
#### 1.12.0-alpha.14
* Fixes and improvements
### 1.11.5
* Fixes and improvements
_We are temporarily unable to update sing-box apps on the App Store because the reviewer mistakenly found that we violated the rules (TestFlight users are not affected)._
#### 1.12.0-alpha.13
* Move `predefined` DNS server to DNS rule action **1**

View File

@ -7,10 +7,6 @@ icon: material/apple
SFI/SFM/SFT allows users to manage and run local or remote sing-box configuration files, and provides
platform-specific function implementation, such as TUN transparent proxy implementation.
!!! failure ""
We are temporarily unable to update sing-box apps on the App Store because the reviewer mistakenly found that we violated the rules (TestFlight users are not affected).
## :material-graph: Requirements
* iOS 15.0+ / macOS 13.0+ / Apple tvOS 17.0+

View File

@ -4,7 +4,6 @@ icon: material/alert-decagram
!!! quote "Changes in sing-box 1.12.0"
:material-plus: [ip_accept_any](#ip_accept_any)
:material-delete-clock: [outbound](#outbound)
!!! quote "Changes in sing-box 1.11.0"
@ -78,6 +77,15 @@ icon: material/alert-decagram
"domain_regex": [
"^stun\\..+"
],
"geosite": [
"cn"
],
"source_geoip": [
"private"
],
"geoip": [
"cn"
],
"source_ip_cidr": [
"10.0.0.0/24",
"192.168.0.1"
@ -88,7 +96,6 @@ icon: material/alert-decagram
"192.168.0.1"
],
"ip_is_private": false,
"ip_accept_any": false,
"source_port": [
12345
],
@ -140,6 +147,8 @@ icon: material/alert-decagram
"geoip-cn",
"geosite-cn"
],
// deprecated
"rule_set_ipcidr_match_source": false,
"rule_set_ip_cidr_match_source": false,
"rule_set_ip_cidr_accept_empty": false,
"invert": false,
@ -147,20 +156,7 @@ icon: material/alert-decagram
"direct"
],
"action": "route",
"server": "local",
// Deprecated
"rule_set_ipcidr_match_source": false,
"geosite": [
"cn"
],
"source_geoip": [
"private"
],
"geoip": [
"cn"
]
"server": "local"
},
{
"type": "logical",
@ -455,9 +451,7 @@ Only takes effect for address requests (A/AAAA/HTTPS). When the query results do
#### geoip
!!! failure "Removed in sing-box 1.12.0"
GeoIP is deprecated in sing-box 1.8.0 and removed in sing-box 1.12.0, check [Migration](/migration/#migrate-geoip-to-rule-sets).
!!! question "Since sing-box 1.9.0"
Match GeoIP with query response.
@ -479,12 +473,6 @@ Match private IP with query response.
Make `ip_cidr` rules in rule-sets accept empty query response.
#### ip_accept_any
!!! question "Since sing-box 1.12.0"
Match any IP with query response.
### Logical Fields
#### type

View File

@ -4,7 +4,6 @@ icon: material/alert-decagram
!!! quote "sing-box 1.12.0 中的更改"
:material-plus: [ip_accept_any](#ip_accept_any)
:material-delete-clock: [outbound](#outbound)
!!! quote "sing-box 1.11.0 中的更改"
@ -78,6 +77,15 @@ icon: material/alert-decagram
"domain_regex": [
"^stun\\..+"
],
"geosite": [
"cn"
],
"source_geoip": [
"private"
],
"geoip": [
"cn"
],
"source_ip_cidr": [
"10.0.0.0/24",
"192.168.0.1"
@ -88,7 +96,6 @@ icon: material/alert-decagram
"192.168.0.1"
],
"ip_is_private": false,
"ip_accept_any": false,
"source_port": [
12345
],
@ -140,6 +147,8 @@ icon: material/alert-decagram
"geoip-cn",
"geosite-cn"
],
// 已弃用
"rule_set_ipcidr_match_source": false,
"rule_set_ip_cidr_match_source": false,
"rule_set_ip_cidr_accept_empty": false,
"invert": false,
@ -147,19 +156,7 @@ icon: material/alert-decagram
"direct"
],
"action": "route",
"server": "local",
// 已弃用
"rule_set_ipcidr_match_source": false,
"geosite": [
"cn"
],
"source_geoip": [
"private"
],
"geoip": [
"cn"
]
"server": "local"
},
{
"type": "logical",
@ -235,17 +232,17 @@ DNS 查询类型。值可以为整数或者类型名称字符串。
#### geosite
!!! failure "已在 sing-box 1.12.0 中被移除"
!!! failure "已在 sing-box 1.8.0 废弃"
GeoSite 已在 sing-box 1.8.0 废弃且在 sing-box 1.12.0 中被移除,参阅 [迁移指南](/zh/migration/#geosite)。
Geosite 已废弃且可能在不久的将来移除,参阅 [迁移指南](/zh/migration/#geosite)。
匹配 Geosite。
#### source_geoip
!!! failure "已在 sing-box 1.12.0 中被移除"
!!! failure "已在 sing-box 1.8.0 废弃"
GeoIP 已在 sing-box 1.8.0 废弃且在 sing-box 1.12.0 中被移除,参阅 [迁移指南](/zh/migration/#geoip)。
GeoIP 已废弃且可能在不久的将来移除,参阅 [迁移指南](/zh/migration/#geoip)。
匹配源 GeoIP。
@ -454,10 +451,7 @@ Available values: `wifi`, `cellular`, `ethernet` and `other`.
#### geoip
!!! failure "已在 sing-box 1.12.0 中被移除"
GeoIP 已在 sing-box 1.8.0 废弃且在 sing-box 1.12.0 中被移除,参阅 [迁移指南](/zh/migration/#geoip)。
!!! question "自 sing-box 1.9.0 起"
与查询响应匹配 GeoIP。
@ -473,12 +467,6 @@ Available values: `wifi`, `cellular`, `ethernet` and `other`.
与查询响应匹配非公开 IP。
#### ip_accept_any
!!! question "自 sing-box 1.12.0 起"
匹配任意 IP。
#### rule_set_ip_cidr_accept_empty
!!! question "自 sing-box 1.10.0 起"

View File

@ -13,7 +13,8 @@ icon: material/new-box
```json
{
"action": "route", // 默认
"action": "route",
// 默认
"server": "",
"strategy": "",
"disable_cache": false,

View File

@ -31,11 +31,12 @@ The protocol version, `1` or `2`.
### Application support
| Project | UoT v1 | UoT v2 |
|--------------|----------------------|----------------------|
| sing-box | v0 (2022/08/11) | v1.2-beta9 |
| Clash.Meta | v1.12.0 (2022/07/02) | v1.14.3 (2023/03/31) |
| Shadowrocket | v2.2.12 (2022/08/13) | / |
| Project | UoT v1 | UoT v2 |
|--------------|----------------------|-------------------------------------------------------------------------------------------------------------------|
| sing-box | v0 (2022/08/11) | v1.2-beta9 |
| Xray-core | v1.5.7 (2022/06/05) | [f57ec13](https://github.com/XTLS/Xray-core/commit/f57ec1388084df041a2289bacab14e446bf1b357) (Not released) |
| Clash.Meta | v1.12.0 (2022/07/02) | [8cb67b6](https://github.com/MetaCubeX/Clash.Meta/commit/8cb67b6480649edfa45dcc9ac89ce0789651e8b3) (Not released) |
| Shadowrocket | v2.2.12 (2022/08/13) | / |
### Protocol details
@ -49,13 +50,7 @@ The client requests the magic address to the upper layer proxy protocol to indic
|------|----------|-------|--------|----------|
| u8 | variable | u16be | u16be | variable |
**ATYP / address / port**: Uses the SOCKS address format, but with different address types:
| ATYP | Address type |
|--------|--------------|
| `0x00` | IPv4 Address |
| `0x01` | IPv6 Address |
| `0x02` | Domain Name |
**ATYP / address / port**: Uses the SOCKS address format.
#### Protocol version 2

View File

@ -567,7 +567,7 @@ The legacy outbound DNS rules are deprecated and can be replaced by new domain r
"server_port": 2080,
"domain_resolver": {
"server": "local",
"rewrite_ttl": 60,
"rewrite_tll": 60,
"client_subnet": "1.1.1.1"
},
// or "domain_resolver": "local",
@ -579,7 +579,7 @@ The legacy outbound DNS rules are deprecated and can be replaced by new domain r
"route": {
"default_domain_resolver": {
"server": "local",
"rewrite_ttl": 60,
"rewrite_tll": 60,
"client_subnet": "1.1.1.1"
}
}

View File

@ -565,21 +565,13 @@ DNS 服务器已经重构。
"type": "socks",
"server": "example.org",
"server_port": 2080,
"domain_resolver": {
"server": "local",
"rewrite_ttl": 60,
"client_subnet": "1.1.1.1"
},
// 或 "domain_resolver": "local",
"domain_resolver": "local",
}
],
// 或
"route": {
"default_domain_resolver": {
"server": "local",
"rewrite_ttl": 60,
"rewrite_tll": 60,
"client_subnet": "1.1.1.1"
}
}

View File

@ -77,15 +77,15 @@ func (s *Server) downloadExternalUI() error {
if response.StatusCode != http.StatusOK {
return E.New("download external ui failed: ", response.Status)
}
err = s.downloadZIP(response.Body, s.externalUI)
err = s.downloadZIP(filepath.Base(downloadURL), response.Body, s.externalUI)
if err != nil {
removeAllInDirectory(s.externalUI)
}
return err
}
func (s *Server) downloadZIP(body io.Reader, output string) error {
tempFile, err := filemanager.CreateTemp(s.ctx, "external-ui.zip")
func (s *Server) downloadZIP(name string, body io.Reader, output string) error {
tempFile, err := filemanager.CreateTemp(s.ctx, name)
if err != nil {
return err
}

View File

@ -56,12 +56,7 @@ func (m *platformDefaultInterfaceMonitor) UnregisterCallback(element *list.Eleme
func (m *platformDefaultInterfaceMonitor) UpdateDefaultInterface(interfaceName string, interfaceIndex32 int32, isExpensive bool, isConstrained bool) {
if sFixAndroidStack {
done := make(chan struct{})
go func() {
m.updateDefaultInterface(interfaceName, interfaceIndex32, isExpensive, isConstrained)
close(done)
}()
<-done
go m.updateDefaultInterface(interfaceName, interfaceIndex32, isExpensive, isConstrained)
} else {
m.updateDefaultInterface(interfaceName, interfaceIndex32, isExpensive, isConstrained)
}

4
go.mod
View File

@ -3,7 +3,7 @@ module github.com/sagernet/sing-box
go 1.23.1
require (
github.com/anytls/sing-anytls v0.0.6
github.com/anytls/sing-anytls v0.0.5
github.com/caddyserver/certmagic v0.21.7
github.com/cloudflare/circl v1.6.0
github.com/cretz/bine v0.2.0
@ -26,7 +26,7 @@ require (
github.com/sagernet/gvisor v0.0.0-20241123041152-536d05261cff
github.com/sagernet/quic-go v0.49.0-beta.1
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691
github.com/sagernet/sing v0.6.4-0.20250309232452-1c3b777fe509
github.com/sagernet/sing v0.6.2-0.20250210072154-8dff604468ff
github.com/sagernet/sing-mux v0.3.1
github.com/sagernet/sing-quic v0.4.1-beta.1
github.com/sagernet/sing-shadowsocks v0.2.7

8
go.sum
View File

@ -8,8 +8,8 @@ github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa h1:LHTHcTQiSGT7V
github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4=
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
github.com/anytls/sing-anytls v0.0.6 h1:UatIjl/OvzWQGXQ1I2bAIkabL9WtihW0fA7G+DXGBUg=
github.com/anytls/sing-anytls v0.0.6/go.mod h1:7rjN6IukwysmdusYsrV51Fgu1uW6vsrdd6ctjnEAln8=
github.com/anytls/sing-anytls v0.0.5 h1:I1NIh3zKTSXThLG5UgjsOOT/x2DZJqjfBzjuP/wZlDk=
github.com/anytls/sing-anytls v0.0.5/go.mod h1:7rjN6IukwysmdusYsrV51Fgu1uW6vsrdd6ctjnEAln8=
github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE=
github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
github.com/caddyserver/certmagic v0.21.7 h1:66KJioPFJwttL43KYSWk7ErSmE6LfaJgCQuhm8Sg6fg=
@ -182,8 +182,8 @@ github.com/sagernet/quic-go v0.49.0-beta.1/go.mod h1:uesWD1Ihrldq1M3XtjuEvIUqi8W
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.6.4-0.20250309232452-1c3b777fe509 h1:rDWToc7O295Xh/uFSLqg67MVPftzXnICH/EUI4NL/a8=
github.com/sagernet/sing v0.6.4-0.20250309232452-1c3b777fe509/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/sagernet/sing v0.6.2-0.20250210072154-8dff604468ff h1:5UGghwx8cI14qFa0ienrLekAYfhdKAiWvJUkY7rHmsI=
github.com/sagernet/sing v0.6.2-0.20250210072154-8dff604468ff/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/sagernet/sing-mux v0.3.1 h1:kvCc8HyGAskDHDQ0yQvoTi/7J4cZPB/VJMsAM3MmdQI=
github.com/sagernet/sing-mux v0.3.1/go.mod h1:Mkdz8LnDstthz0HWuA/5foncnDIdcNN5KZ6AdJX+x78=
github.com/sagernet/sing-quic v0.4.1-beta.1 h1:V2VfMckT3EQR3ZdfSzJgZZDsvfZZH42QAZpnOnHKa0s=

View File

@ -316,8 +316,8 @@ type LegacyDNSServerOptions struct {
}
type HostsDNSServerOptions struct {
Path badoption.Listable[string] `json:"path,omitempty"`
Predefined *badjson.TypedMap[string, badoption.Listable[netip.Addr]] `json:"predefined,omitempty"`
Path badoption.Listable[string] `json:"path,omitempty"`
Predefined badjson.TypedMap[string, badoption.Listable[netip.Addr]] `json:"predefined,omitempty"`
}
type LocalDNSServerOptions struct {

View File

@ -51,9 +51,8 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
outbound.tlsConfig = tlsConfig
outboundDialer, err := dialer.NewWithOptions(dialer.Options{
Context: ctx,
Options: options.DialerOptions,
RemoteIsDomain: options.ServerIsDomain(),
Context: ctx,
Options: options.DialerOptions,
})
if err != nil {
return nil, err

View File

@ -12,7 +12,6 @@ import (
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing/common/buf"
"github.com/sagernet/sing/common/bufio"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
"github.com/sagernet/sing/common/udpnat2"
@ -81,7 +80,7 @@ func (i *Inbound) Close() error {
}
func (i *Inbound) NewPacketEx(buffer *buf.Buffer, source M.Socksaddr) {
i.udpNat.NewPacket([][]byte{buffer.Bytes()}, source, i.listener.UDPAddr(), nil)
i.udpNat.NewPacket([][]byte{buffer.Bytes()}, source, M.Socksaddr{}, nil)
}
func (i *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
@ -105,6 +104,7 @@ func (i *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata a
func (i *Inbound) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
i.logger.InfoContext(ctx, "inbound packet connection from ", source)
i.logger.InfoContext(ctx, "inbound packet connection to ", destination)
var metadata adapter.InboundContext
metadata.Inbound = i.Tag()
metadata.InboundType = i.Type()
@ -123,11 +123,8 @@ func (i *Inbound) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn,
destination.Port = i.overrideDestination.Port
default:
}
i.logger.InfoContext(ctx, "inbound packet connection to ", destination)
metadata.Destination = destination
if i.overrideOption != 0 {
conn = bufio.NewDestinationNATPacketConn(bufio.NewNetPacketConn(conn), i.listener.UDPAddr(), destination)
}
metadata.OriginDestination = i.listener.UDPAddr()
i.router.RoutePacketConnectionEx(ctx, conn, metadata, onClose)
}

View File

@ -61,7 +61,7 @@ func newInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
logger: logger,
}
var err error
inbound.router, err = mux.NewRouterWithOptions(inbound.router, logger, common.PtrValueOrDefault(options.Multiplex))
inbound.router, err = mux.NewRouterWithOptions(router, logger, common.PtrValueOrDefault(options.Multiplex))
if err != nil {
return nil, err
}

View File

@ -165,17 +165,22 @@ func (m *ConnectionManager) NewPacketConnection(ctx context.Context, this N.Dial
} else {
originDestination = metadata.Destination
}
if natConn, loaded := common.Cast[bufio.NATPacketConn](conn); loaded {
natConn.UpdateDestination(destinationAddress)
} else if metadata.Destination != M.SocksaddrFrom(destinationAddress, metadata.Destination.Port) {
if metadata.Destination != M.SocksaddrFrom(destinationAddress, metadata.Destination.Port) {
if metadata.UDPDisableDomainUnmapping {
remotePacketConn = bufio.NewUnidirectionalNATPacketConn(bufio.NewPacketConn(remotePacketConn), M.SocksaddrFrom(destinationAddress, metadata.Destination.Port), originDestination)
} else {
remotePacketConn = bufio.NewNATPacketConn(bufio.NewPacketConn(remotePacketConn), M.SocksaddrFrom(destinationAddress, metadata.Destination.Port), originDestination)
}
}
if natConn, loaded := common.Cast[bufio.NATPacketConn](conn); loaded {
natConn.UpdateDestination(destinationAddress)
}
} else if metadata.RouteOriginalDestination.IsValid() && metadata.RouteOriginalDestination != metadata.Destination {
remotePacketConn = bufio.NewDestinationNATPacketConn(bufio.NewPacketConn(remotePacketConn), metadata.Destination, metadata.RouteOriginalDestination)
if metadata.UDPDisableDomainUnmapping {
remotePacketConn = bufio.NewUnidirectionalNATPacketConn(bufio.NewPacketConn(remotePacketConn), metadata.Destination, metadata.RouteOriginalDestination)
} else {
remotePacketConn = bufio.NewNATPacketConn(bufio.NewPacketConn(remotePacketConn), metadata.Destination, metadata.RouteOriginalDestination)
}
}
var udpTimeout time.Duration
if metadata.UDPTimeout > 0 {
@ -290,17 +295,13 @@ func (m *ConnectionManager) connectionCopy(ctx context.Context, source io.Reader
func (m *ConnectionManager) packetConnectionCopy(ctx context.Context, source N.PacketReader, destination N.PacketWriter, direction bool, done *atomic.Bool, onClose N.CloseHandlerFunc) {
_, err := bufio.CopyPacket(destination, source)
if !direction {
if err == nil {
m.logger.DebugContext(ctx, "packet upload finished")
} else if E.IsClosedOrCanceled(err) {
if E.IsClosedOrCanceled(err) {
m.logger.TraceContext(ctx, "packet upload closed")
} else {
m.logger.DebugContext(ctx, "packet upload closed: ", err)
}
} else {
if err == nil {
m.logger.DebugContext(ctx, "packet download finished")
} else if E.IsClosedOrCanceled(err) {
if E.IsClosedOrCanceled(err) {
m.logger.TraceContext(ctx, "packet download closed")
} else {
m.logger.DebugContext(ctx, "packet download closed: ", err)

View File

@ -21,7 +21,6 @@ import (
var _ net.Conn = (*GunConn)(nil)
type GunConn struct {
rawReader io.Reader
reader *std_bufio.Reader
writer io.Writer
flusher http.Flusher
@ -32,10 +31,9 @@ type GunConn struct {
func newGunConn(reader io.Reader, writer io.Writer, flusher http.Flusher) *GunConn {
return &GunConn{
rawReader: reader,
reader: std_bufio.NewReader(reader),
writer: writer,
flusher: flusher,
reader: std_bufio.NewReader(reader),
writer: writer,
flusher: flusher,
}
}
@ -48,7 +46,6 @@ func newLateGunConn(writer io.Writer) *GunConn {
func (c *GunConn) setup(reader io.Reader, err error) {
if reader != nil {
c.rawReader = reader
c.reader = std_bufio.NewReader(reader)
}
c.err = err
@ -141,7 +138,7 @@ func (c *GunConn) FrontHeadroom() int {
}
func (c *GunConn) Close() error {
return common.Close(c.rawReader, c.writer)
return common.Close(c.reader, c.writer)
}
func (c *GunConn) LocalAddr() net.Addr {