Compare commits

..

44 Commits

Author SHA1 Message Date
世界
c131c1bdca
documentation: Bump version 2025-03-15 10:48:10 +08:00
世界
07f633af2a
Make domain_resolver optional when only one DNS server is configured 2025-03-15 10:48:10 +08:00
世界
69e8c7b4fb
Fix DNS lookup context pollution 2025-03-15 10:06:59 +08:00
世界
2fa8c77bc4
Fix http3 DNS server connecting to wrong address 2025-03-15 10:06:59 +08:00
Restia-Ashbell
c926fae081
documentation: Fix typo 2025-03-15 10:06:58 +08:00
anytls
06a3712f1d
Update sing-anytls
Co-authored-by: anytls <anytls>
2025-03-15 10:06:58 +08:00
k9982874
6f63c9b416
Fix hosts DNS server 2025-03-15 10:06:58 +08:00
世界
aed9a50988
Fix UDP DNS server crash 2025-03-15 10:06:58 +08:00
世界
be664fb221
documentation: Fix missing ip_accept_any DNS rule option 2025-03-15 10:06:57 +08:00
世界
2e44ecf0ca
Fix anytls dialer usage 2025-03-15 10:06:57 +08:00
世界
f97046b4fa
Move predefined DNS server to rule action 2025-03-15 10:06:57 +08:00
世界
4ab3d1e2a9
Fix domain resolver on direct outbound 2025-03-15 10:06:56 +08:00
Zephyruso
273cd5e726
Fix missing AnyTLS display name 2025-03-15 10:06:56 +08:00
anytls
f3a2fec725
Update sing-anytls
Co-authored-by: anytls <anytls>
2025-03-15 10:06:56 +08:00
Estel
e46d66c5cf
documentation: Fix typo
Signed-off-by: Estel <callmebedrockdigger@gmail.com>
2025-03-15 10:06:55 +08:00
TargetLocked
efc4c653d9
Fix parsing legacy DNS options 2025-03-15 10:06:55 +08:00
世界
becc8dbedf
Fix DNS fallback 2025-03-15 10:06:54 +08:00
世界
84d69f4363
documentation: Fix missing hosts DNS server 2025-03-15 10:06:54 +08:00
anytls
970d4dded1
Add MinIdleSession option to AnyTLS outbound
Co-authored-by: anytls <anytls>
2025-03-15 10:06:53 +08:00
ReleTor
94a2845585
documentation: Minor fixes 2025-03-15 10:06:53 +08:00
libtry486
bb18a23370
documentation: Fix typo
fix typo

Signed-off-by: libtry486 <89328481+libtry486@users.noreply.github.com>
2025-03-15 10:06:53 +08:00
Alireza Ahmadi
6f25cf80e9
Fix Outbound deadlock 2025-03-15 10:06:52 +08:00
世界
c6d6a10ca7
documentation: Fix AnyTLS doc 2025-03-15 10:06:52 +08:00
anytls
8ecfb6feb3
Add AnyTLS protocol 2025-03-15 10:06:52 +08:00
世界
538b0b70b6
Migrate to stdlib ECH support 2025-03-15 10:06:52 +08:00
世界
d7d3c09523
Add fallback local DNS server for iOS 2025-03-15 10:06:52 +08:00
世界
35a227ab4f
Get darwin local DNS server from libresolv 2025-03-15 10:06:51 +08:00
世界
d356f0f0a2
Improve resolve action 2025-03-15 10:06:51 +08:00
世界
3c5e618006
Fix toolchain version 2025-03-15 10:06:51 +08:00
世界
6bdcdfc4de
Add back port hopping to hysteria 1 2025-03-15 10:06:50 +08:00
世界
a7041ee791
Update dependencies 2025-03-15 10:06:50 +08:00
xchacha20-poly1305
36fcffc022
Remove single quotes of raw Moziila certs 2025-03-15 10:06:49 +08:00
世界
b789b69d78
Add Tailscale endpoint 2025-03-15 10:06:49 +08:00
世界
3b21852b85
Build legacy binaries with latest Go 2025-03-15 10:06:48 +08:00
世界
b967be7fde
documentation: Remove outdated icons 2025-03-15 10:06:48 +08:00
世界
7e94fe66f0
documentation: Certificate store 2025-03-15 10:06:47 +08:00
世界
49f4802d2c
documentation: TLS fragment 2025-03-15 10:06:47 +08:00
世界
b1abb73b04
documentation: Outbound domain resolver 2025-03-15 10:06:47 +08:00
世界
9ec5b07bfb
documentation: Refactor DNS 2025-03-15 10:06:46 +08:00
世界
a3c95327e4
Add certificate store 2025-03-15 10:06:45 +08:00
世界
2d45335723
Add TLS fragment support 2025-03-15 10:06:45 +08:00
世界
6e66c232b9
refactor: Outbound domain resolver 2025-03-15 10:06:45 +08:00
世界
ccd3de39eb
refactor: DNS 2025-03-15 10:06:44 +08:00
世界
4f3ee61104
Fix copy early conn 2025-03-15 08:09:04 +08:00
6 changed files with 73 additions and 16 deletions

View File

@ -104,7 +104,12 @@ func NewWithOptions(options Options) (N.Dialer, error) {
} else if options.NewDialer { } else if options.NewDialer {
return nil, E.New("missing domain resolver for domain server address") return nil, E.New("missing domain resolver for domain server address")
} else { } else {
deprecated.Report(options.Context, deprecated.OptionMissingDomainResolver) transports := dnsTransport.Transports()
if len(transports) < 2 {
dnsQueryOptions.Transport = dnsTransport.Default()
} else {
deprecated.Report(options.Context, deprecated.OptionMissingDomainResolver)
}
} }
dialer = NewResolveDialer( dialer = NewResolveDialer(
options.Context, options.Context,

View File

@ -4,8 +4,15 @@ icon: material/alert-decagram
#### 1.12.0-alpha.16 #### 1.12.0-alpha.16
* Update `domain_resolver` behavior **1**
* Fixes and improvements * Fixes and improvements
**1**:
`route.default_domain_resolver` or `outbound.domain_resolver` is now optional when only one DNS server is configured.
See [Dial Fields](/configuration/shared/dial/#domain_resolver).
### 1.11.5 ### 1.11.5
* Fixes and improvements * Fixes and improvements

View File

@ -106,6 +106,10 @@ Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
`outbound` DNS rule items are deprecated and will be removed in sing-box 1.14.0, so this item will be required for outbound/endpoints using domain name in server address since sing-box 1.14.0. `outbound` DNS rule items are deprecated and will be removed in sing-box 1.14.0, so this item will be required for outbound/endpoints using domain name in server address since sing-box 1.14.0.
!!! info ""
`domain_resolver` or `route.default_domain_resolver` is optional when only one DNS server is configured.
Set domain resolver to use for resolving domain names. Set domain resolver to use for resolving domain names.
This option uses the same format as the [route DNS rule action](/configuration/dns/rule_action/#route) without the `action` field. This option uses the same format as the [route DNS rule action](/configuration/dns/rule_action/#route) without the `action` field.

View File

@ -105,6 +105,10 @@ icon: material/new-box
`outbound` DNS 规则项已弃用,且将在 sing-box 1.14.0 中被移除。因此,从 sing-box 1.14.0 版本开始,所有在服务器地址中使用域名的出站/端点均需配置此项。 `outbound` DNS 规则项已弃用,且将在 sing-box 1.14.0 中被移除。因此,从 sing-box 1.14.0 版本开始,所有在服务器地址中使用域名的出站/端点均需配置此项。
!!! info ""
当只有一个 DNS 服务器已配置时,`domain_resolver``route.default_domain_resolver` 是可选的。
用于设置解析域名的域名解析器。 用于设置解析域名的域名解析器。
此选项的格式与 [路由 DNS 规则动作](/configuration/dns/rule_action/#route) 相同,但不包含 `action` 字段。 此选项的格式与 [路由 DNS 规则动作](/configuration/dns/rule_action/#route) 相同,但不包含 `action` 字段。

View File

@ -116,7 +116,14 @@ func (o *DomainResolveOptions) UnmarshalJSON(bytes []byte) error {
o.Server = stringValue o.Server = stringValue
return nil return nil
} }
return json.Unmarshal(bytes, (*_DomainResolveOptions)(o)) err = json.Unmarshal(bytes, (*_DomainResolveOptions)(o))
if err != nil {
return err
}
if o.Server == "" {
return E.New("empty domain_resolver.server")
}
return nil
} }
func (o *DialerOptions) TakeDialerOptions() DialerOptions { func (o *DialerOptions) TakeDialerOptions() DialerOptions {

View File

@ -5,6 +5,7 @@ import (
"io" "io"
"net" "net"
"net/netip" "net/netip"
"os"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time" "time"
@ -14,6 +15,7 @@ import (
"github.com/sagernet/sing-box/common/tlsfragment" "github.com/sagernet/sing-box/common/tlsfragment"
C "github.com/sagernet/sing-box/constant" C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing/common" "github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/buf"
"github.com/sagernet/sing/common/bufio" "github.com/sagernet/sing/common/bufio"
"github.com/sagernet/sing/common/canceler" "github.com/sagernet/sing/common/canceler"
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
@ -206,14 +208,16 @@ func (m *ConnectionManager) NewPacketConnection(ctx context.Context, this N.Dial
go m.packetConnectionCopy(ctx, destination, conn, true, &done, onClose) go m.packetConnectionCopy(ctx, destination, conn, true, &done, onClose)
} }
func (m *ConnectionManager) connectionCopy(ctx context.Context, source io.Reader, destination io.Writer, direction bool, done *atomic.Bool, onClose N.CloseHandlerFunc) { func (m *ConnectionManager) connectionCopy(ctx context.Context, source net.Conn, destination net.Conn, direction bool, done *atomic.Bool, onClose N.CloseHandlerFunc) {
originSource := source var (
originDestination := destination sourceReader io.Reader = source
destinationWriter io.Writer = destination
)
var readCounters, writeCounters []N.CountFunc var readCounters, writeCounters []N.CountFunc
for { for {
source, readCounters = N.UnwrapCountReader(source, readCounters) sourceReader, readCounters = N.UnwrapCountReader(sourceReader, readCounters)
destination, writeCounters = N.UnwrapCountWriter(destination, writeCounters) destinationWriter, writeCounters = N.UnwrapCountWriter(destinationWriter, writeCounters)
if cachedSrc, isCached := source.(N.CachedReader); isCached { if cachedSrc, isCached := sourceReader.(N.CachedReader); isCached {
cachedBuffer := cachedSrc.ReadCached() cachedBuffer := cachedSrc.ReadCached()
if cachedBuffer != nil { if cachedBuffer != nil {
dataLen := cachedBuffer.Len() dataLen := cachedBuffer.Len()
@ -223,7 +227,7 @@ func (m *ConnectionManager) connectionCopy(ctx context.Context, source io.Reader
if done.Swap(true) { if done.Swap(true) {
onClose(err) onClose(err)
} }
common.Close(originSource, originDestination) common.Close(source, destination)
if !direction { if !direction {
m.logger.ErrorContext(ctx, "connection upload payload: ", err) m.logger.ErrorContext(ctx, "connection upload payload: ", err)
} else { } else {
@ -242,9 +246,13 @@ func (m *ConnectionManager) connectionCopy(ctx context.Context, source io.Reader
} }
break break
} }
if earlyConn, isEarlyConn := common.Cast[N.EarlyConn](destination); isEarlyConn && earlyConn.NeedHandshake() { if earlyConn, isEarlyConn := common.Cast[N.EarlyConn](destinationWriter); isEarlyConn && earlyConn.NeedHandshake() {
_, err := destination.Write(nil) err := m.connectionCopyEarly(source, destination)
if err != nil { if err != nil {
if done.Swap(true) {
onClose(err)
}
common.Close(source, destination)
if !direction { if !direction {
m.logger.ErrorContext(ctx, "connection upload handshake: ", err) m.logger.ErrorContext(ctx, "connection upload handshake: ", err)
} else { } else {
@ -253,20 +261,20 @@ func (m *ConnectionManager) connectionCopy(ctx context.Context, source io.Reader
return return
} }
} }
_, err := bufio.CopyWithCounters(destination, source, originSource, readCounters, writeCounters) _, err := bufio.CopyWithCounters(destination, sourceReader, source, readCounters, writeCounters)
if err != nil { if err != nil {
common.Close(originDestination) common.Close(source, destination)
} else if duplexDst, isDuplex := destination.(N.WriteCloser); isDuplex { } else if duplexDst, isDuplex := destination.(N.WriteCloser); isDuplex {
err = duplexDst.CloseWrite() err = duplexDst.CloseWrite()
if err != nil { if err != nil {
common.Close(originSource, originDestination) common.Close(source, destination)
} }
} else { } else {
common.Close(originDestination) destination.Close()
} }
if done.Swap(true) { if done.Swap(true) {
onClose(err) onClose(err)
common.Close(originSource, originDestination) common.Close(source, destination)
} }
if !direction { if !direction {
if err == nil { if err == nil {
@ -287,6 +295,28 @@ func (m *ConnectionManager) connectionCopy(ctx context.Context, source io.Reader
} }
} }
func (m *ConnectionManager) connectionCopyEarly(source net.Conn, destination io.Writer) error {
payload := buf.NewPacket()
defer payload.Release()
err := source.SetReadDeadline(time.Now().Add(C.ReadPayloadTimeout))
if err != nil {
if err == os.ErrInvalid {
return common.Error(destination.Write(nil))
}
return err
}
_, err = payload.ReadOnceFrom(source)
if err != nil && !E.IsTimeout(err) {
return E.Cause(err, "read payload")
}
_ = source.SetReadDeadline(time.Time{})
_, err = destination.Write(payload.Bytes())
if err != nil {
return E.Cause(err, "write payload")
}
return nil
}
func (m *ConnectionManager) packetConnectionCopy(ctx context.Context, source N.PacketReader, destination N.PacketWriter, direction bool, done *atomic.Bool, onClose N.CloseHandlerFunc) { 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) _, err := bufio.CopyPacket(destination, source)
if !direction { if !direction {