Compare commits

...

9 Commits

Author SHA1 Message Date
世界
c09544f29d stack: Fix close before start 2024-11-18 12:46:20 +08:00
世界
f9755b8947 Update gvisor to 20241007.0 2024-11-18 12:46:20 +08:00
世界
50f0cff186 Update dependencies 2024-11-18 12:46:20 +08:00
Benyamin
28a4e968f4 Fix android routing rules about vpn protection 2024-11-13 10:27:26 +08:00
世界
b2b56ffcf8 Fix gateway select 2024-11-08 12:15:07 +08:00
世界
d95423e833 Update dependencies 2024-11-04 11:21:52 +08:00
世界
92c18cc7ec Add renovate configuration 2024-10-31 21:59:32 +08:00
世界
10f73346a0 Fix gateway & FIx prefix check 2024-10-31 21:58:09 +08:00
世界
07278fb470 Retry system listen 2024-10-14 22:10:23 +08:00
17 changed files with 232 additions and 65 deletions

19
.github/renovate.json vendored Normal file
View File

@@ -0,0 +1,19 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"commitMessagePrefix": "[dependencies]",
"extends": [
"config:base",
":disableRateLimiting"
],
"golang": {
"enabled": false
},
"packageRules": [
{
"matchManagers": [
"github-actions"
],
"groupName": "github-actions"
}
]
}

12
go.mod
View File

@@ -5,24 +5,24 @@ go 1.20
require (
github.com/go-ole/go-ole v1.3.0
github.com/sagernet/fswatch v0.1.1
github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f
github.com/sagernet/gvisor v0.0.0-20241021032506-a4324256e4a3
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a
github.com/sagernet/nftables v0.3.0-beta.4
github.com/sagernet/sing v0.5.0-rc.2
github.com/sagernet/sing v0.5.1
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8
golang.org/x/net v0.26.0
golang.org/x/sys v0.21.0
golang.org/x/net v0.31.0
golang.org/x/sys v0.27.0
)
require (
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/josharian/native v1.1.0 // indirect
github.com/mdlayher/netlink v1.7.2 // indirect
github.com/mdlayher/socket v0.4.1 // indirect
github.com/vishvananda/netns v0.0.4 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/time v0.7.0 // indirect
)

24
go.sum
View File

@@ -3,8 +3,8 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA=
@@ -16,14 +16,14 @@ github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8Ku
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/sagernet/fswatch v0.1.1 h1:YqID+93B7VRfqIH3PArW/XpJv5H4OLEVWDfProGoRQs=
github.com/sagernet/fswatch v0.1.1/go.mod h1:nz85laH0mkQqJfaOrqPpkwtU1znMFNVTpT/5oRsVz/o=
github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f h1:NkhuupzH5ch7b/Y/6ZHJWrnNLoiNnSJaow6DPb8VW2I=
github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f/go.mod h1:KXmw+ouSJNOsuRpg4wgwwCQuunrGz4yoAqQjsLjc6N0=
github.com/sagernet/gvisor v0.0.0-20241021032506-a4324256e4a3 h1:RxEz7LhPNiF/gX/Hg+OXr5lqsM9iVAgmaK1L1vzlDRM=
github.com/sagernet/gvisor v0.0.0-20241021032506-a4324256e4a3/go.mod h1:ehZwnT2UpmOWAHFL48XdBhnd4Qu4hN2O3Ji0us3ZHMw=
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a h1:ObwtHN2VpqE0ZNjr6sGeT00J8uU7JF4cNUdb44/Duis=
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
github.com/sagernet/nftables v0.3.0-beta.4 h1:kbULlAwAC3jvdGAC1P5Fa3GSxVwQJibNenDW2zaXr8I=
github.com/sagernet/nftables v0.3.0-beta.4/go.mod h1:OQXAjvjNGGFxaTgVCSTRIhYB5/llyVDeapVoENYBDS8=
github.com/sagernet/sing v0.5.0-rc.2 h1:tIrs6pRbjJWvI0ITRSg47P1wosY+iSuHpw9t5/hBx+Q=
github.com/sagernet/sing v0.5.0-rc.2/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/sagernet/sing v0.5.1 h1:mhL/MZVq0TjuvHcpYcFtmSD1BFOxZ/+8ofbNZcg1k1Y=
github.com/sagernet/sing v0.5.1/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
@@ -31,13 +31,13 @@ go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBs
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY=
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

View File

@@ -142,41 +142,47 @@ func (r *autoRedirect) setupIPTablesForFamily(iptablesPath string) error {
})
if !dnsServer.IsValid() {
if iptablesPath == r.iptablesPath {
dnsServer = r.tunOptions.Inet4Address[0].Addr().Next()
if HasNextAddress(r.tunOptions.Inet4Address[0], 1) {
dnsServer = r.tunOptions.Inet4Address[0].Addr().Next()
}
} else {
dnsServer = r.tunOptions.Inet6Address[0].Addr().Next()
if HasNextAddress(r.tunOptions.Inet6Address[0], 1) {
dnsServer = r.tunOptions.Inet6Address[0].Addr().Next()
}
}
}
if len(routeAddress) > 0 {
for _, address := range routeAddress {
err = r.runShell(iptablesPath, "-t nat -A", tableNamePreRouteing,
"-d", address.String(), "-p udp --dport 53 -j DNAT --to", dnsServer)
if err != nil {
return err
}
}
} else if len(r.tunOptions.IncludeInterface) > 0 || len(r.tunOptions.IncludeUID) > 0 {
for _, name := range r.tunOptions.IncludeInterface {
err = r.runShell(iptablesPath, "-t nat -A", tableNamePreRouteing,
"-i", name, "-p udp --dport 53 -j DNAT --to", dnsServer)
if err != nil {
return err
}
}
for _, uidRange := range r.tunOptions.IncludeUID {
for uid := uidRange.Start; uid <= uidRange.End; uid++ {
if dnsServer.IsValid() {
if len(routeAddress) > 0 {
for _, address := range routeAddress {
err = r.runShell(iptablesPath, "-t nat -A", tableNamePreRouteing,
"-m owner --uid-owner", uid, "-p udp --dport 53 -j DNAT --to", dnsServer)
"-d", address.String(), "-p udp --dport 53 -j DNAT --to", dnsServer)
if err != nil {
return err
}
}
}
} else {
err = r.runShell(iptablesPath, "-t nat -A", tableNamePreRouteing,
"-p udp --dport 53 -j DNAT --to", dnsServer)
if err != nil {
return err
} else if len(r.tunOptions.IncludeInterface) > 0 || len(r.tunOptions.IncludeUID) > 0 {
for _, name := range r.tunOptions.IncludeInterface {
err = r.runShell(iptablesPath, "-t nat -A", tableNamePreRouteing,
"-i", name, "-p udp --dport 53 -j DNAT --to", dnsServer)
if err != nil {
return err
}
}
for _, uidRange := range r.tunOptions.IncludeUID {
for uid := uidRange.Start; uid <= uidRange.End; uid++ {
err = r.runShell(iptablesPath, "-t nat -A", tableNamePreRouteing,
"-m owner --uid-owner", uid, "-p udp --dport 53 -j DNAT --to", dnsServer)
if err != nil {
return err
}
}
}
} else {
err = r.runShell(iptablesPath, "-t nat -A", tableNamePreRouteing,
"-p udp --dport 53 -j DNAT --to", dnsServer)
if err != nil {
return err
}
}
}
}

View File

@@ -573,11 +573,18 @@ func (r *autoRedirect) nftablesCreateDNSHijackRulesForFamily(
})
if !dnsServer.IsValid() {
if family == nftables.TableFamilyIPv4 {
dnsServer = r.tunOptions.Inet4Address[0].Addr().Next()
if HasNextAddress(r.tunOptions.Inet4Address[0], 1) {
dnsServer = r.tunOptions.Inet4Address[0].Addr().Next()
}
} else {
dnsServer = r.tunOptions.Inet6Address[0].Addr().Next()
if HasNextAddress(r.tunOptions.Inet6Address[0], 1) {
dnsServer = r.tunOptions.Inet6Address[0].Addr().Next()
}
}
}
if !dnsServer.IsValid() {
return nil
}
exprs := []expr.Any{
&expr.Meta{
Key: expr.MetaKeyNFPROTO,

View File

@@ -59,6 +59,14 @@ func NewStack(
}
}
func HasNextAddress(prefix netip.Prefix, count int) bool {
checkAddr := prefix.Addr()
for i := 0; i < count; i++ {
checkAddr = checkAddr.Next()
}
return prefix.Contains(checkAddr)
}
func BroadcastAddr(inet4Address []netip.Prefix) netip.Addr {
if len(inet4Address) == 0 {
return netip.Addr{}

View File

@@ -152,6 +152,9 @@ func (t *GVisor) Start() error {
}
func (t *GVisor) Close() error {
if t.stack == nil {
return nil
}
t.endpoint.Attach(nil)
t.stack.Close()
for _, endpoint := range t.stack.CleanupEndpoints() {

View File

@@ -260,6 +260,9 @@ func (m *Mixed) packetLoop() {
}
func (m *Mixed) Close() error {
if m.stack == nil {
return nil
}
m.endpoint.Attach(nil)
m.stack.Close()
for _, endpoint := range m.stack.CleanupEndpoints() {

View File

@@ -70,14 +70,14 @@ func NewSystem(options StackOptions) (Stack, error) {
interfaceFinder: options.InterfaceFinder,
}
if len(options.TunOptions.Inet4Address) > 0 {
if options.TunOptions.Inet4Address[0].Bits() == 32 {
if !HasNextAddress(options.TunOptions.Inet4Address[0], 1) {
return nil, E.New("need one more IPv4 address in first prefix for system stack")
}
stack.inet4ServerAddress = options.TunOptions.Inet4Address[0].Addr()
stack.inet4Address = stack.inet4ServerAddress.Next()
}
if len(options.TunOptions.Inet6Address) > 0 {
if options.TunOptions.Inet6Address[0].Bits() == 128 {
if !HasNextAddress(options.TunOptions.Inet6Address[0], 1) {
return nil, E.New("need one more IPv6 address in first prefix for system stack")
}
stack.inet6ServerAddress = options.TunOptions.Inet6Address[0].Addr()
@@ -120,8 +120,15 @@ func (s *System) start() error {
return nil
})
}
var tcpListener net.Listener
if s.inet4Address.IsValid() {
tcpListener, err := listener.Listen(s.ctx, "tcp4", net.JoinHostPort(s.inet4ServerAddress.String(), "0"))
for i := 0; i < 3; i++ {
tcpListener, err = listener.Listen(s.ctx, "tcp4", net.JoinHostPort(s.inet4ServerAddress.String(), "0"))
if !retryableListenError(err) {
break
}
time.Sleep(time.Second)
}
if err != nil {
return err
}
@@ -130,7 +137,13 @@ func (s *System) start() error {
go s.acceptLoop(tcpListener)
}
if s.inet6Address.IsValid() {
tcpListener, err := listener.Listen(s.ctx, "tcp6", net.JoinHostPort(s.inet6ServerAddress.String(), "0"))
for i := 0; i < 3; i++ {
tcpListener, err = listener.Listen(s.ctx, "tcp6", net.JoinHostPort(s.inet6ServerAddress.String(), "0"))
if !retryableListenError(err) {
break
}
time.Sleep(time.Second)
}
if err != nil {
return err
}

View File

@@ -2,6 +2,16 @@
package tun
import (
"errors"
"golang.org/x/sys/unix"
)
func fixWindowsFirewall() error {
return nil
}
func retryableListenError(err error) bool {
return errors.Is(err, unix.EADDRNOTAVAIL)
}

View File

@@ -1,10 +1,13 @@
package tun
import (
"errors"
"os"
"path/filepath"
"github.com/sagernet/sing-tun/internal/winfw"
"golang.org/x/sys/windows"
)
func fixWindowsFirewall() error {
@@ -23,3 +26,7 @@ func fixWindowsFirewall() error {
_, err = winfw.FirewallRuleAddAdvanced(rule)
return err
}
func retryableListenError(err error) bool {
return errors.Is(err, windows.WSAEADDRNOTAVAIL)
}

50
tun.go
View File

@@ -53,6 +53,8 @@ type Options struct {
MTU uint32
GSO bool
AutoRoute bool
Inet4Gateway netip.Addr
Inet6Gateway netip.Addr
DNSServers []netip.Addr
IPRoute2TableIndex int
IPRoute2RuleIndex int
@@ -82,6 +84,54 @@ type Options struct {
EXP_DisableDNSHijack bool
}
func (o *Options) Inet4GatewayAddr() netip.Addr {
if o.Inet4Gateway.IsValid() {
return o.Inet4Gateway
}
if len(o.Inet4Address) > 0 {
switch runtime.GOOS {
case "android":
case "linux":
if HasNextAddress(o.Inet4Address[0], 1) {
return o.Inet4Address[0].Addr().Next()
}
case "darwin":
return o.Inet4Address[0].Addr()
default:
if HasNextAddress(o.Inet4Address[0], 1) {
return o.Inet4Address[0].Addr().Next()
} else {
return o.Inet4Address[0].Addr()
}
}
}
return netip.IPv4Unspecified()
}
func (o *Options) Inet6GatewayAddr() netip.Addr {
if o.Inet6Gateway.IsValid() {
return o.Inet6Gateway
}
if len(o.Inet6Address) > 0 {
switch runtime.GOOS {
case "android":
case "linux":
if HasNextAddress(o.Inet6Address[0], 1) {
return o.Inet6Address[0].Addr().Next()
}
case "darwin":
return o.Inet6Address[0].Addr()
default:
if HasNextAddress(o.Inet6Address[0], 1) {
return o.Inet6Address[0].Addr().Next()
} else {
return o.Inet6Address[0].Addr()
}
}
}
return netip.IPv6Unspecified()
}
func CalculateInterfaceName(name string) (tunName string) {
if runtime.GOOS == "darwin" {
tunName = "utun"

View File

@@ -245,11 +245,12 @@ func configure(tunFd int, ifIndex int, name string, options Options) error {
if err != nil {
return err
}
gateway4, gateway6 := options.Inet4GatewayAddr(), options.Inet6GatewayAddr()
for _, routeRange := range routeRanges {
if routeRange.Addr().Is4() {
err = addRoute(routeRange, options.Inet4Address[0].Addr())
err = addRoute(routeRange, gateway4)
} else {
err = addRoute(routeRange, options.Inet6Address[0].Addr())
err = addRoute(routeRange, gateway6)
}
if err != nil {
return E.Cause(err, "add route: ", routeRange)

View File

@@ -27,6 +27,9 @@ func (e *DarwinEndpoint) MTU() uint32 {
return e.tun.mtu
}
func (e *DarwinEndpoint) SetMTU(mtu uint32) {
}
func (e *DarwinEndpoint) MaxHeaderLength() uint16 {
return 0
}
@@ -35,6 +38,9 @@ func (e *DarwinEndpoint) LinkAddress() tcpip.LinkAddress {
return ""
}
func (e *DarwinEndpoint) SetLinkAddress(addr tcpip.LinkAddress) {
}
func (e *DarwinEndpoint) Capabilities() stack.LinkEndpointCapabilities {
return stack.CapabilityRXChecksumOffload
}
@@ -120,3 +126,9 @@ func (e *DarwinEndpoint) WritePackets(packetBufferList stack.PacketBufferList) (
}
return n, nil
}
func (e *DarwinEndpoint) Close() {
}
func (e *DarwinEndpoint) SetOnCloseAction(f func()) {
}

View File

@@ -350,9 +350,18 @@ func (t *NativeTun) routes(tunLink netlink.Link) ([]netlink.Route, error) {
if err != nil {
return nil, err
}
// Do not create gateway on linux by default
gateway4, gateway6 := t.options.Inet4GatewayAddr(), t.options.Inet6GatewayAddr()
return common.Map(routeRanges, func(it netip.Prefix) netlink.Route {
var gateway net.IP
if it.Addr().Is4() && !gateway4.IsUnspecified() {
gateway = gateway4.AsSlice()
} else if it.Addr().Is6() && !gateway6.IsUnspecified() {
gateway = gateway6.AsSlice()
}
return netlink.Route{
Dst: prefixToIPNet(it),
Gw: gateway,
LinkIndex: tunLink.Attrs().Index,
Table: t.options.IPRoute2TableIndex,
}
@@ -569,6 +578,7 @@ func (t *NativeTun) rules() []*netlink.Rule {
it = netlink.NewRule()
if t.options.InterfaceMonitor.OverrideAndroidVPN() {
it.Mark = protectedFromVPN
it.MarkSet = true
}
it.Mask = protectedFromVPN
it.Priority = priority
@@ -581,6 +591,7 @@ func (t *NativeTun) rules() []*netlink.Rule {
it = netlink.NewRule()
if t.options.InterfaceMonitor.OverrideAndroidVPN() {
it.Mark = protectedFromVPN
it.MarkSet = true
}
it.Mask = protectedFromVPN
it.Family = unix.AF_INET6
@@ -881,10 +892,10 @@ func (t *NativeTun) setSearchDomainForSystemdResolved() {
}
dnsServer := t.options.DNSServers
if len(dnsServer) == 0 {
if len(t.options.Inet4Address) > 0 {
if len(t.options.Inet4Address) > 0 && HasNextAddress(t.options.Inet4Address[0], 1) {
dnsServer = append(dnsServer, t.options.Inet4Address[0].Addr().Next())
}
if len(t.options.Inet6Address) > 0 {
if len(t.options.Inet6Address) > 0 && HasNextAddress(t.options.Inet6Address[0], 1) {
dnsServer = append(dnsServer, t.options.Inet6Address[0].Addr().Next())
}
}

View File

@@ -74,12 +74,14 @@ func (t *NativeTun) configure() error {
}
if !t.options.EXP_DisableDNSHijack {
dnsServers := common.Filter(t.options.DNSServers, netip.Addr.Is4)
if len(dnsServers) == 0 {
if len(dnsServers) == 0 && HasNextAddress(t.options.Inet4Address[0], 1) {
dnsServers = []netip.Addr{t.options.Inet4Address[0].Addr().Next()}
}
err = luid.SetDNS(winipcfg.AddressFamily(windows.AF_INET), dnsServers, nil)
if err != nil {
return E.Cause(err, "set ipv4 dns")
if len(dnsServers) > 0 {
err = luid.SetDNS(winipcfg.AddressFamily(windows.AF_INET), dnsServers, nil)
if err != nil {
return E.Cause(err, "set ipv4 dns")
}
}
}
}
@@ -90,12 +92,14 @@ func (t *NativeTun) configure() error {
}
if !t.options.EXP_DisableDNSHijack {
dnsServers := common.Filter(t.options.DNSServers, netip.Addr.Is6)
if len(dnsServers) == 0 {
if len(dnsServers) == 0 && HasNextAddress(t.options.Inet6Address[0], 1) {
dnsServers = []netip.Addr{t.options.Inet6Address[0].Addr().Next()}
}
err = luid.SetDNS(winipcfg.AddressFamily(windows.AF_INET6), dnsServers, nil)
if err != nil {
return E.Cause(err, "set ipv6 dns")
if len(dnsServers) > 0 {
err = luid.SetDNS(winipcfg.AddressFamily(windows.AF_INET6), dnsServers, nil)
if err != nil {
return E.Cause(err, "set ipv6 dns")
}
}
}
}
@@ -103,15 +107,16 @@ func (t *NativeTun) configure() error {
_ = luid.DisableDNSRegistration()
}
if t.options.AutoRoute {
gateway4, gateway6 := t.options.Inet4GatewayAddr(), t.options.Inet6GatewayAddr()
routeRanges, err := t.options.BuildAutoRouteRanges(false)
if err != nil {
return err
}
for _, routeRange := range routeRanges {
if routeRange.Addr().Is4() {
err = luid.AddRoute(routeRange, netip.IPv4Unspecified(), 0)
err = luid.AddRoute(routeRange, gateway4, 0)
} else {
err = luid.AddRoute(routeRange, netip.IPv6Unspecified(), 0)
err = luid.AddRoute(routeRange, gateway6, 0)
}
}
if err != nil {

View File

@@ -26,6 +26,9 @@ func (e *WintunEndpoint) MTU() uint32 {
return e.tun.options.MTU
}
func (e *WintunEndpoint) SetMTU(mtu uint32) {
}
func (e *WintunEndpoint) MaxHeaderLength() uint16 {
return 0
}
@@ -34,6 +37,9 @@ func (e *WintunEndpoint) LinkAddress() tcpip.LinkAddress {
return ""
}
func (e *WintunEndpoint) SetLinkAddress(addr tcpip.LinkAddress) {
}
func (e *WintunEndpoint) Capabilities() stack.LinkEndpointCapabilities {
return stack.CapabilityRXChecksumOffload
}
@@ -117,3 +123,9 @@ func (e *WintunEndpoint) WritePackets(packetBufferList stack.PacketBufferList) (
}
return n, nil
}
func (e *WintunEndpoint) Close() {
}
func (e *WintunEndpoint) SetOnCloseAction(f func()) {
}