Merge remote-tracking branch 'upstream/dev' into dev-next

# Conflicts:
#	adapter/router.go
#	dns/transport/udp.go
#	docs/configuration/dns/server/index.md
#	docs/configuration/dns/server/index.zh.md
#	docs/installation/tools/install.sh
#	docs/migration.md
#	docs/migration.zh.md
#	option/dns.go
#	option/rule_dns.go
#	route/rule_conds.go
This commit is contained in:
mingtianquan 2025-04-21 15:41:55 +08:00
commit d512411b96
9 changed files with 159 additions and 146 deletions

View File

@ -117,7 +117,7 @@ func (t *UDPTransport) exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.M
conn.access.Unlock() conn.access.Unlock()
defer func() { defer func() {
conn.access.Lock() conn.access.Lock()
delete(conn.callbacks, messageId) delete(conn.callbacks, exMessage.Id)
conn.access.Unlock() conn.access.Unlock()
}() }()
rawMessage, err := exMessage.PackBuffer(buffer.FreeBytes()) rawMessage, err := exMessage.PackBuffer(buffer.FreeBytes())

View File

@ -28,15 +28,16 @@ icon: material/alert-decagram
The type of the DNS server. The type of the DNS server.
| Type | Format | | Type | Format |
|-----------------|-----------------------------| |-----------------|---------------------------|
| empty (default) | [Legacy](./legacy/) | | empty (default) | [Legacy](./legacy/) |
| `local` | [Local](./local/) |
| `hosts` | [Hosts](./hosts/) |
| `tcp` | [TCP](./tcp/) | | `tcp` | [TCP](./tcp/) |
| `udp` | [UDP](./udp/) | | `udp` | [UDP](./udp/) |
| `tls` | [TLS](./tls/) | | `tls` | [TLS](./tls/) |
| `https` | [HTTPS](./https/) |
| `quic` | [QUIC](./quic/) | | `quic` | [QUIC](./quic/) |
| `https` | [HTTPS](./https/) |
| `h3` | [HTTP/3](./http3/) | | `h3` | [HTTP/3](./http3/) |
| `predefined` | [Predefined](./predefined/) |
| `dhcp` | [DHCP](./dhcp/) | | `dhcp` | [DHCP](./dhcp/) |
| `fakeip` | [Fake IP](./fakeip/) | | `fakeip` | [Fake IP](./fakeip/) |
| `tailscale` | [Tailscale](./tailscale/) | | `tailscale` | [Tailscale](./tailscale/) |

View File

@ -28,15 +28,16 @@ icon: material/alert-decagram
DNS 服务器的类型。 DNS 服务器的类型。
| 类型 | 格式 | | 类型 | 格式 |
|-----------------|-----------------------------| |-----------------|---------------------------|
| empty (default) | [Legacy](./legacy/) | | empty (default) | [Legacy](./legacy/) |
| `local` | [Local](./local/) |
| `hosts` | [Hosts](./hosts/) |
| `tcp` | [TCP](./tcp/) | | `tcp` | [TCP](./tcp/) |
| `udp` | [UDP](./udp/) | | `udp` | [UDP](./udp/) |
| `tls` | [TLS](./tls/) | | `tls` | [TLS](./tls/) |
| `https` | [HTTPS](./https/) |
| `quic` | [QUIC](./quic/) | | `quic` | [QUIC](./quic/) |
| `https` | [HTTPS](./https/) |
| `h3` | [HTTP/3](./http3/) | | `h3` | [HTTP/3](./http3/) |
| `predefined` | [Predefined](./predefined/) |
| `dhcp` | [DHCP](./dhcp/) | | `dhcp` | [DHCP](./dhcp/) |
| `fakeip` | [Fake IP](./fakeip/) | | `fakeip` | [Fake IP](./fakeip/) |
| `tailscale` | [Tailscale](./tailscale/) | | `tailscale` | [Tailscale](./tailscale/) |

View File

@ -26,7 +26,7 @@
| QUIC 客户端 | 类型 | | QUIC 客户端 | 类型 |
|:------------------------:|:----------:| |:------------------------:|:----------:|
| Chromium/Cronet | `chrimium` | | Chromium/Cronet | `chromium` |
| Safari/Apple Network API | `safari` | | Safari/Apple Network API | `safari` |
| Firefox / uquic firefox | `firefox` | | Firefox / uquic firefox | `firefox` |
| quic-go / uquic chrome | `quic-go` | | quic-go / uquic chrome | `quic-go` |

View File

@ -1,6 +1,4 @@
#!/bin/bash #!/bin/sh
set -xeuo pipefail
download_beta=false download_beta=false
download_version="" download_version=""
@ -51,37 +49,49 @@ else
fi fi
if [[ -z "$download_version" ]]; then if [[ -z "$download_version" ]]; then
header=""
if [ -n "$GITHUB_TOKEN" ]; then
header="-H \"Authorization: token $GITHUB_TOKEN\""
fi
if [[ "$download_beta" != 'true' ]]; then if [[ "$download_beta" != 'true' ]]; then
download_version=$(curl -s --fail-with-body "$header" https://api.github.com/repos/SagerNet/sing-box/releases/latest | if [[ -n "$GITHUB_TOKEN" ]]; then
grep tag_name | latest_release=$(curl -s --fail-with-body -H "Authorization: token ${GITHUB_TOKEN}" https://api.github.com/repos/SagerNet/sing-box/releases/latest)
cut -d ":" -f2 |
sed 's/\"//g;s/\,//g;s/\ //g;s/v//')
else else
download_version=$(curl -s --fail-with-body "$header" https://api.github.com/repos/SagerNet/sing-box/releases | latest_release=$(curl -s --fail-with-body https://api.github.com/repos/SagerNet/sing-box/releases/latest)
grep tag_name | fi
head -n 1 | curl_exit_status=$?
cut -d ":" -f2 | if [[ $curl_exit_status -ne 0 ]]; then
sed 's/\"//g;s/\,//g;s/\ //g;s/v//') echo "$latest_release"
exit $?
fi
download_version=$(echo "$latest_release" | grep tag_name | cut -d ":" -f2 | sed 's/\"//g;s/\,//g;s/\ //g;s/v//')
else
if [[ -n "$GITHUB_TOKEN" ]]; then
latest_release=$(curl -s --fail-with-body -H "Authorization: token ${GITHUB_TOKEN}" https://api.github.com/repos/SagerNet/sing-box/releases)
else
latest_release=$(curl -s --fail-with-body https://api.github.com/repos/SagerNet/sing-box/releases)
fi
curl_exit_status=$?
if [[ $? -ne 0 ]]; then
echo "$latest_release"
exit $?
fi
download_version=$(echo "$latest_release" | grep tag_name | head -n 1 | cut -d ":" -f2 | sed 's/\"//g;s/\,//g;s/\ //g;s/v//')
fi fi
fi fi
package_name="sing-box_${download_version}_${os}_${arch}${package_suffix}" package_name="sing-box_${download_version}_${os}_${arch}${package_suffix}"
package_url="https://github.com/SagerNet/sing-box/releases/download/v${download_version}/${package_name}" package_url="https://github.com/SagerNet/sing-box/releases/download/v${download_version}/${package_name}"
echo "Downloading $package_url" echo "Downloading $package_url"
curl --fail-with-body -Lo "$package_name" "$package_url" if [[ -n "$GITHUB_TOKEN" ]]; then
curl --fail-with-body -Lo "$package_name" -H "Authorization: token ${GITHUB_TOKEN}" "$package_url"
else
curl --fail-with-body -Lo "$package_name" "$package_url"
fi
if [[ $? -ne 0 ]]; then
exit $?
fi
if [[ $(command -v sudo) ]]; then if [[ $(command -v sudo) ]]; then
package_install="sudo $package_install" package_install="sudo $package_install"
fi fi
echo "$package_install $package_name" echo "$package_install $package_name" && $package_install "$package_name" && rm "$package_name"
$package_install "$package_name"
rm "$package_name"

View File

@ -292,7 +292,7 @@ DNS servers are refactored for better performance and scalability.
} }
], ],
"fakeip": { "fakeip": {
"enable": true, "enabled": true,
"inet4_range": "198.18.0.0/15", "inet4_range": "198.18.0.0/15",
"inet6_range": "fc00::/18" "inet6_range": "fc00::/18"
} }
@ -556,7 +556,8 @@ The legacy outbound DNS rules are deprecated and can be replaced by new domain r
"dns": { "dns": {
"servers": [ "servers": [
{ {
"type": "local" "type": "local",
"tag": "local"
} }
] ]
}, },
@ -619,7 +620,8 @@ some people mistakenly believe that `domain_strategy` is the same feature as in
"dns": { "dns": {
"servers": [ "servers": [
{ {
"type": "local" "type": "local",
"tag": "local"
} }
] ]
}, },

View File

@ -292,7 +292,7 @@ DNS 服务器已经重构。
} }
], ],
"fakeip": { "fakeip": {
"enable": true, "enabled": true,
"inet4_range": "198.18.0.0/15", "inet4_range": "198.18.0.0/15",
"inet6_range": "fc00::/18" "inet6_range": "fc00::/18"
} }
@ -556,7 +556,8 @@ DNS 服务器已经重构。
"dns": { "dns": {
"servers": [ "servers": [
{ {
"type": "local" "type": "local",
"tag": "local"
} }
] ]
}, },
@ -618,7 +619,8 @@ DNS 服务器已经重构。
"dns": { "dns": {
"servers": [ "servers": [
{ {
"type": "local" "type": "local",
"tag": "local"
} }
] ]
}, },

View File

@ -387,50 +387,3 @@ type DHCPDNSServerOptions struct {
LocalDNSServerOptions LocalDNSServerOptions
Interface string `json:"interface,omitempty"` Interface string `json:"interface,omitempty"`
} }
type RawDefaultDNSRule struct {
Inbound badoption.Listable[string] `json:"inbound,omitempty"`
IPVersion int `json:"ip_version,omitempty"`
QueryType badoption.Listable[DNSQueryType] `json:"query_type,omitempty"`
Network badoption.Listable[string] `json:"network,omitempty"`
AuthUser badoption.Listable[string] `json:"auth_user,omitempty"`
Protocol badoption.Listable[string] `json:"protocol,omitempty"`
Client badoption.Listable[string] `json:"client,omitempty"`
Domain badoption.Listable[string] `json:"domain,omitempty"`
DomainSuffix badoption.Listable[string] `json:"domain_suffix,omitempty"`
DomainKeyword badoption.Listable[string] `json:"domain_keyword,omitempty"`
DomainRegex badoption.Listable[string] `json:"domain_regex,omitempty"`
Geosite badoption.Listable[string] `json:"geosite,omitempty"`
SourceGeoIP badoption.Listable[string] `json:"source_geoip,omitempty"`
GeoIP badoption.Listable[string] `json:"geoip,omitempty"`
SourceIPCIDR badoption.Listable[string] `json:"source_ip_cidr,omitempty"`
SourceIPIsPrivate bool `json:"source_ip_is_private,omitempty"`
IPCIDR badoption.Listable[string] `json:"ip_cidr,omitempty"`
IPIsPrivate bool `json:"ip_is_private,omitempty"`
IPAcceptAny bool `json:"ip_accept_any,omitempty"`
SourcePort badoption.Listable[uint16] `json:"source_port,omitempty"`
SourcePortRange badoption.Listable[string] `json:"source_port_range,omitempty"`
Port badoption.Listable[uint16] `json:"port,omitempty"`
PortRange badoption.Listable[string] `json:"port_range,omitempty"`
ProcessName badoption.Listable[string] `json:"process_name,omitempty"`
ProcessPath badoption.Listable[string] `json:"process_path,omitempty"`
ProcessPathRegex badoption.Listable[string] `json:"process_path_regex,omitempty"`
ProcessPID badoption.Listable[uint32] `json:"process_pid,omitempty"`
PackageName badoption.Listable[string] `json:"package_name,omitempty"`
User badoption.Listable[string] `json:"user,omitempty"`
UserID badoption.Listable[int32] `json:"user_id,omitempty"`
Outbound badoption.Listable[string] `json:"outbound,omitempty"`
ClashMode string `json:"clash_mode,omitempty"`
NetworkType badoption.Listable[InterfaceType] `json:"network_type,omitempty"`
NetworkIsExpensive bool `json:"network_is_expensive,omitempty"`
NetworkIsConstrained bool `json:"network_is_constrained,omitempty"`
WIFISSID badoption.Listable[string] `json:"wifi_ssid,omitempty"`
WIFIBSSID badoption.Listable[string] `json:"wifi_bssid,omitempty"`
RuleSet badoption.Listable[string] `json:"rule_set,omitempty"`
RuleSetIPCIDRMatchSource bool `json:"rule_set_ip_cidr_match_source,omitempty"`
RuleSetIPCIDRAcceptEmpty bool `json:"rule_set_ip_cidr_accept_empty,omitempty"`
Invert bool `json:"invert,omitempty"`
// Deprecated: renamed to rule_set_ip_cidr_match_source
Deprecated_RulesetIPCIDRMatchSource bool `json:"rule_set_ipcidr_match_source,omitempty"`
}

View File

@ -9,6 +9,7 @@ import (
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/json" "github.com/sagernet/sing/common/json"
"github.com/sagernet/sing/common/json/badjson" "github.com/sagernet/sing/common/json/badjson"
"github.com/sagernet/sing/common/json/badoption"
) )
type _DNSRule struct { type _DNSRule struct {
@ -66,7 +67,50 @@ func (r DNSRule) IsValid() bool {
} }
} }
// RawDefaultDNSRule已在dns.go中定义 type RawDefaultDNSRule struct {
Inbound badoption.Listable[string] `json:"inbound,omitempty"`
IPVersion int `json:"ip_version,omitempty"`
QueryType badoption.Listable[DNSQueryType] `json:"query_type,omitempty"`
Network badoption.Listable[string] `json:"network,omitempty"`
AuthUser badoption.Listable[string] `json:"auth_user,omitempty"`
Protocol badoption.Listable[string] `json:"protocol,omitempty"`
Domain badoption.Listable[string] `json:"domain,omitempty"`
DomainSuffix badoption.Listable[string] `json:"domain_suffix,omitempty"`
DomainKeyword badoption.Listable[string] `json:"domain_keyword,omitempty"`
DomainRegex badoption.Listable[string] `json:"domain_regex,omitempty"`
Geosite badoption.Listable[string] `json:"geosite,omitempty"`
SourceGeoIP badoption.Listable[string] `json:"source_geoip,omitempty"`
GeoIP badoption.Listable[string] `json:"geoip,omitempty"`
IPCIDR badoption.Listable[string] `json:"ip_cidr,omitempty"`
IPIsPrivate bool `json:"ip_is_private,omitempty"`
IPAcceptAny bool `json:"ip_accept_any,omitempty"`
SourceIPCIDR badoption.Listable[string] `json:"source_ip_cidr,omitempty"`
SourceIPIsPrivate bool `json:"source_ip_is_private,omitempty"`
SourcePort badoption.Listable[uint16] `json:"source_port,omitempty"`
SourcePortRange badoption.Listable[string] `json:"source_port_range,omitempty"`
Port badoption.Listable[uint16] `json:"port,omitempty"`
PortRange badoption.Listable[string] `json:"port_range,omitempty"`
ProcessName badoption.Listable[string] `json:"process_name,omitempty"`
ProcessPath badoption.Listable[string] `json:"process_path,omitempty"`
ProcessPathRegex badoption.Listable[string] `json:"process_path_regex,omitempty"`
PackageName badoption.Listable[string] `json:"package_name,omitempty"`
User badoption.Listable[string] `json:"user,omitempty"`
UserID badoption.Listable[int32] `json:"user_id,omitempty"`
Outbound badoption.Listable[string] `json:"outbound,omitempty"`
ClashMode string `json:"clash_mode,omitempty"`
NetworkType badoption.Listable[InterfaceType] `json:"network_type,omitempty"`
NetworkIsExpensive bool `json:"network_is_expensive,omitempty"`
NetworkIsConstrained bool `json:"network_is_constrained,omitempty"`
WIFISSID badoption.Listable[string] `json:"wifi_ssid,omitempty"`
WIFIBSSID badoption.Listable[string] `json:"wifi_bssid,omitempty"`
RuleSet badoption.Listable[string] `json:"rule_set,omitempty"`
RuleSetIPCIDRMatchSource bool `json:"rule_set_ip_cidr_match_source,omitempty"`
RuleSetIPCIDRAcceptEmpty bool `json:"rule_set_ip_cidr_accept_empty,omitempty"`
Invert bool `json:"invert,omitempty"`
// Deprecated: renamed to rule_set_ip_cidr_match_source
Deprecated_RulesetIPCIDRMatchSource bool `json:"rule_set_ipcidr_match_source,omitempty"`
}
type DefaultDNSRule struct { type DefaultDNSRule struct {
RawDefaultDNSRule RawDefaultDNSRule