Add DNS mode

This commit is contained in:
世界 2026-05-02 15:42:00 +08:00
parent 3c7d6ad82f
commit 47bdde06c3
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
4 changed files with 103 additions and 58 deletions

62
tun.go
View file

@ -9,8 +9,10 @@ import (
"strings"
"time"
"github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/buf"
"github.com/sagernet/sing/common/control"
E "github.com/sagernet/sing/common/exceptions"
F "github.com/sagernet/sing/common/format"
"github.com/sagernet/sing/common/logger"
M "github.com/sagernet/sing/common/metadata"
@ -68,6 +70,12 @@ const (
DefaultIPRoute2AutoRedirectFallbackRuleIndex = 32768
)
const (
DNSModeDisabled = "disabled"
DNSModeNative = "native"
DNSModeHijack = "hijack"
)
type Options struct {
Name string
Inet4Address []netip.Prefix
@ -78,7 +86,8 @@ type Options struct {
InterfaceScope bool
Inet4Gateway netip.Addr
Inet6Gateway netip.Addr
DNSServers []netip.Addr
DNSMode string
DNSAddress []netip.Addr
IPRoute2TableIndex int
IPRoute2RuleIndex int
IPRoute2AutoRedirectFallbackRuleIndex int
@ -124,6 +133,57 @@ type Options struct {
EXP_SendMsgX bool
}
func (o *Options) DNSModeOrDefault() string {
if o.DNSMode == "" {
return DNSModeHijack
}
return o.DNSMode
}
func (o *Options) DNSServerAddress() ([]netip.Addr, error) {
inet4DNS, err := o.Inet4DNSAddress()
if err != nil {
return nil, err
}
inet6DNS, err := o.Inet6DNSAddress()
if err != nil {
return nil, err
}
return append(inet4DNS, inet6DNS...), nil
}
func (o *Options) Inet4DNSAddress() ([]netip.Addr, error) {
if len(o.Inet4Address) == 0 {
return nil, nil
}
if len(o.DNSAddress) > 0 {
return common.Filter(o.DNSAddress, netip.Addr.Is4), nil
}
if HasNextAddress(o.Inet4Address[0], 1) {
return []netip.Addr{o.Inet4Address[0].Addr().Next()}, nil
}
if !(len(o.Inet6Address) > 0 && HasNextAddress(o.Inet6Address[0], 1)) {
return nil, E.New("no IPv4 server configured and no usable next address in ", o.Inet6Address[0], " for DNS")
}
return nil, nil
}
func (o *Options) Inet6DNSAddress() ([]netip.Addr, error) {
if len(o.Inet6Address) == 0 {
return nil, nil
}
if len(o.DNSAddress) > 0 {
return common.Filter(o.DNSAddress, netip.Addr.Is6), nil
}
if HasNextAddress(o.Inet6Address[0], 1) {
return []netip.Addr{o.Inet6Address[0].Addr().Next()}, nil
}
if !(len(o.Inet4Address) > 0 && HasNextAddress(o.Inet4Address[0], 1)) {
return nil, E.New("no IPv6 server configured and no usable next address in ", o.Inet6Address[0], " for DNS")
}
return nil, nil
}
func (o *Options) Inet4GatewayAddr() netip.Addr {
if o.Inet4Gateway.IsValid() {
return o.Inet4Gateway