diff --git a/.github/update_dependencies.sh b/.github/update_dependencies.sh index 3284229d..39593713 100755 --- a/.github/update_dependencies.sh +++ b/.github/update_dependencies.sh @@ -5,3 +5,6 @@ PROJECTS=$(dirname "$0")/../.. go get -x github.com/sagernet/sing@$(git -C $PROJECTS/sing rev-parse HEAD) go get -x github.com/sagernet/sing-shadowsocks@$(git -C $PROJECTS/sing-shadowsocks rev-parse HEAD) go mod tidy +pushd test +go mod tidy +popd diff --git a/common/dialer/router.go b/common/dialer/router.go new file mode 100644 index 00000000..4f82c16c --- /dev/null +++ b/common/dialer/router.go @@ -0,0 +1,31 @@ +package dialer + +import ( + "context" + "net" + + "github.com/sagernet/sing-box/adapter" + C "github.com/sagernet/sing-box/constant" + M "github.com/sagernet/sing/common/metadata" + N "github.com/sagernet/sing/common/network" +) + +type RouterDialer struct { + router adapter.Router +} + +func NewRouter(router adapter.Router) N.Dialer { + return &RouterDialer{router: router} +} + +func (d *RouterDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) { + return d.router.DefaultOutbound(network).DialContext(ctx, network, destination) +} + +func (d *RouterDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) { + return d.router.DefaultOutbound(C.NetworkUDP).ListenPacket(ctx, destination) +} + +func (d *RouterDialer) Upstream() any { + return d.router +} diff --git a/docs/configuration/dns/index.md b/docs/configuration/dns/index.md index 2434e3e6..505d8b76 100644 --- a/docs/configuration/dns/index.md +++ b/docs/configuration/dns/index.md @@ -6,7 +6,7 @@ "servers": [], "rules": [], "final": "", - "strategy": "prefer_ipv6", + "strategy": "", "disable_cache": false, "disable_expire": false } @@ -23,7 +23,9 @@ #### final -Default dns server tag. the first server will be used if empty. +Default dns server tag. + +The first server will be used if empty. #### strategy diff --git a/docs/configuration/dns/rule.md b/docs/configuration/dns/rule.md index 27c03f8a..e322ed4b 100644 --- a/docs/configuration/dns/rule.md +++ b/docs/configuration/dns/rule.md @@ -140,4 +140,6 @@ Included default rules. #### server +==Required== + Tag of the target dns server. diff --git a/docs/configuration/dns/server.md b/docs/configuration/dns/server.md index 31cf02c3..fe61d861 100644 --- a/docs/configuration/dns/server.md +++ b/docs/configuration/dns/server.md @@ -25,6 +25,8 @@ The tag of the dns server. #### address +==Required== + The address of the dns server. | Protocol | Format | @@ -41,6 +43,8 @@ The address of the dns server. #### address_resolver +==Required if address contains domain== + Tag of a another server to resolve the domain name in the address. #### address_strategy @@ -55,4 +59,4 @@ One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`. Tag of an outbound for connecting to the dns server. -Requests will be sent directly if the empty. \ No newline at end of file +Default outbound will be used if empty. \ No newline at end of file diff --git a/docs/configuration/inbound/direct.md b/docs/configuration/inbound/direct.md index 276a17ac..25ee5507 100644 --- a/docs/configuration/inbound/direct.md +++ b/docs/configuration/inbound/direct.md @@ -29,10 +29,14 @@ #### listen +==Required== + Listen address. #### listen_port +==Required== + Listen port. #### tcp_fast_open diff --git a/docs/configuration/inbound/http.md b/docs/configuration/inbound/http.md index 5ddd1a58..b1975ef6 100644 --- a/docs/configuration/inbound/http.md +++ b/docs/configuration/inbound/http.md @@ -31,10 +31,14 @@ #### listen +==Required== + Listen address. #### listen_port +==Required== + Listen port. #### tcp_fast_open diff --git a/docs/configuration/inbound/mixed.md b/docs/configuration/inbound/mixed.md index d2f23411..81430559 100644 --- a/docs/configuration/inbound/mixed.md +++ b/docs/configuration/inbound/mixed.md @@ -31,10 +31,14 @@ #### listen +==Required== + Listen address. #### listen_port +==Required== + Listen port. #### tcp_fast_open diff --git a/docs/configuration/inbound/shadowsocks.md b/docs/configuration/inbound/shadowsocks.md index f8cbf463..163f4e59 100644 --- a/docs/configuration/inbound/shadowsocks.md +++ b/docs/configuration/inbound/shadowsocks.md @@ -29,10 +29,14 @@ #### listen +==Required== + Listen address. #### listen_port +==Required== + Listen port. #### tcp_fast_open @@ -75,6 +79,8 @@ Both if empty. #### method +==Required== + | Method | Key Length | |-------------------------------|------------| | 2022-blake3-aes-128-gcm | 16 | @@ -89,6 +95,8 @@ Both if empty. #### password +==Required== + | Method | Password Format | |---------------|-------------------------------------| | none | / | diff --git a/docs/configuration/inbound/socks.md b/docs/configuration/inbound/socks.md index 77c28205..a14c011e 100644 --- a/docs/configuration/inbound/socks.md +++ b/docs/configuration/inbound/socks.md @@ -31,10 +31,14 @@ #### listen +==Required== + Listen address. #### listen_port +==Required== + Listen port. #### tcp_fast_open diff --git a/docs/configuration/outbound/http.md b/docs/configuration/outbound/http.md index 13fb06c4..89139d35 100644 --- a/docs/configuration/outbound/http.md +++ b/docs/configuration/outbound/http.md @@ -31,10 +31,14 @@ #### server +==Required== + The server address. #### server_port +==Required== + The server port. #### username diff --git a/docs/configuration/outbound/shadowsocks.md b/docs/configuration/outbound/shadowsocks.md index 06df08fd..1bed475e 100644 --- a/docs/configuration/outbound/shadowsocks.md +++ b/docs/configuration/outbound/shadowsocks.md @@ -32,14 +32,20 @@ #### server +==Required== + The server address. #### server_port +==Required== + The server port. #### method +==Required== + Encryption methods: * `2022-blake3-aes-128-gcm` @@ -66,6 +72,8 @@ Legacy encryption methods: #### password +==Required== + The shadowsocks password. #### network diff --git a/docs/configuration/outbound/socks.md b/docs/configuration/outbound/socks.md index 8a30d9d4..92041fa6 100644 --- a/docs/configuration/outbound/socks.md +++ b/docs/configuration/outbound/socks.md @@ -33,10 +33,14 @@ #### server +==Required== + The server address. #### server_port +==Required== + The server port. #### version diff --git a/mkdocs.yml b/mkdocs.yml index 5e56361b..881119a6 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -63,8 +63,13 @@ markdown_extensions: - pymdownx.inlinehilite - pymdownx.snippets - pymdownx.superfences - - admonition - pymdownx.details + - pymdownx.critic + - pymdownx.caret + - pymdownx.keys + - pymdownx.mark + - pymdownx.tilde + - admonition - attr_list - md_in_html - footnotes diff --git a/option/dns.go b/option/dns.go index a891070d..ba21bb2a 100644 --- a/option/dns.go +++ b/option/dns.go @@ -34,7 +34,7 @@ type DNSServerOptions struct { Address string `json:"address"` AddressResolver string `json:"address_resolver,omitempty"` AddressStrategy DomainStrategy `json:"address_strategy,omitempty"` - DialerOptions + Detour string `json:"detour,omitempty"` } type _DNSRule struct { diff --git a/route/router.go b/route/router.go index 65a61430..46f75cf8 100644 --- a/route/router.go +++ b/route/router.go @@ -6,6 +6,7 @@ import ( "net" "net/http" "net/netip" + "net/url" "os" "path/filepath" "strings" @@ -116,7 +117,18 @@ func NewRouter(ctx context.Context, logger log.Logger, options option.RouteOptio if _, exists := dummyTransportMap[tag]; exists { continue } - detour := dialer.New(router, server.DialerOptions) + var detour N.Dialer + if server.Detour == "" { + detour = dialer.NewRouter(router) + } else { + detour = dialer.NewDetour(router, server.Detour) + } + serverURL, err := url.Parse(server.Address) + if err != nil { + return nil, err + } + serverAddress := serverURL.Hostname() + _, notIpAddress := netip.ParseAddr(serverAddress) if server.AddressResolver != "" { if !transportTagMap[server.AddressResolver] { return nil, E.New("parse dns server[", tag, "]: address resolver not found: ", server.AddressResolver) @@ -126,6 +138,8 @@ func NewRouter(ctx context.Context, logger log.Logger, options option.RouteOptio } else { continue } + } else if notIpAddress != nil { + return nil, E.New("parse dns server[", tag, "]: missing address_resolver") } transport, err := dns.NewTransport(ctx, detour, logger, server.Address) if err != nil {