Chore: format with go 1.17
This commit is contained in:
parent
32d8f849ee
commit
433d35e866
29 changed files with 447 additions and 150 deletions
54
README.md
54
README.md
|
@ -37,9 +37,9 @@ Documentations are now moved to [GitHub Wiki](https://github.com/Dreamacro/clash
|
||||||
|
|
||||||
## Advanced usage for this fork branch
|
## Advanced usage for this fork branch
|
||||||
### TUN configuration
|
### TUN configuration
|
||||||
Support macOS,Linux and Windows.
|
Supports macOS, Linux and Windows.
|
||||||
|
|
||||||
For Windows, you should download the [Wintun](https://www.wintun.net) driver and copy `wintun.dll` into the System32 directory.
|
On Windows, you should download the [Wintun](https://www.wintun.net) driver and copy `wintun.dll` into Clash home directory.
|
||||||
```yaml
|
```yaml
|
||||||
# Enable the TUN listener
|
# Enable the TUN listener
|
||||||
tun:
|
tun:
|
||||||
|
@ -53,11 +53,12 @@ tun:
|
||||||
- Support `multiport` condition for rule `SRC-PORT` and `DST-PORT`.
|
- Support `multiport` condition for rule `SRC-PORT` and `DST-PORT`.
|
||||||
- Support not match condition for rule `GEOIP`.
|
- Support not match condition for rule `GEOIP`.
|
||||||
- Support `network` condition for all rules.
|
- Support `network` condition for all rules.
|
||||||
|
- Support source IPCIDR condition for all rules, just append to the end.
|
||||||
|
|
||||||
The `GEOSITE` and `GEOIP` databases via https://github.com/Loyalsoldier/v2ray-rules-dat.
|
The `GEOSITE` and `GEOIP` databases via https://github.com/Loyalsoldier/v2ray-rules-dat.
|
||||||
```yaml
|
```yaml
|
||||||
rules:
|
rules:
|
||||||
# network condition for rules
|
# network condition for all rules
|
||||||
- DOMAIN-SUFFIX,bilibili.com,DIRECT,tcp
|
- DOMAIN-SUFFIX,bilibili.com,DIRECT,tcp
|
||||||
- DOMAIN-SUFFIX,bilibili.com,REJECT,udp
|
- DOMAIN-SUFFIX,bilibili.com,REJECT,udp
|
||||||
|
|
||||||
|
@ -84,6 +85,9 @@ rules:
|
||||||
# Not match condition for rule GEOIP
|
# Not match condition for rule GEOIP
|
||||||
#- GEOIP,!cn,PROXY
|
#- GEOIP,!cn,PROXY
|
||||||
|
|
||||||
|
# source IPCIDR condition for all rules in gateway proxy
|
||||||
|
#- GEOIP,!cn,PROXY,192.168.1.88/32,192.168.1.99/32
|
||||||
|
|
||||||
- MATCH,PROXY
|
- MATCH,PROXY
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -100,7 +104,6 @@ proxies:
|
||||||
uuid: uuid
|
uuid: uuid
|
||||||
network: tcp
|
network: tcp
|
||||||
servername: example.com # AKA SNI
|
servername: example.com # AKA SNI
|
||||||
# udp: true
|
|
||||||
# flow: xtls-rprx-direct # xtls-rprx-origin # enable XTLS
|
# flow: xtls-rprx-direct # xtls-rprx-origin # enable XTLS
|
||||||
# skip-cert-verify: true
|
# skip-cert-verify: true
|
||||||
|
|
||||||
|
@ -116,49 +119,6 @@ proxies:
|
||||||
ws-path: /path
|
ws-path: /path
|
||||||
ws-headers:
|
ws-headers:
|
||||||
Host: example.com
|
Host: example.com
|
||||||
|
|
||||||
- name: "vless-h2"
|
|
||||||
type: vless
|
|
||||||
server: server
|
|
||||||
port: 443
|
|
||||||
uuid: uuid
|
|
||||||
network: h2
|
|
||||||
servername: example.com
|
|
||||||
# skip-cert-verify: true
|
|
||||||
h2-opts:
|
|
||||||
host:
|
|
||||||
- http.example.com
|
|
||||||
- http-alt.example.com
|
|
||||||
path: /
|
|
||||||
|
|
||||||
- name: "vless-http"
|
|
||||||
type: vless
|
|
||||||
server: server
|
|
||||||
port: 443
|
|
||||||
uuid: uuid
|
|
||||||
# udp: true
|
|
||||||
network: http
|
|
||||||
servername: example.com
|
|
||||||
# skip-cert-verify: true
|
|
||||||
http-opts:
|
|
||||||
method: "GET"
|
|
||||||
path:
|
|
||||||
- '/'
|
|
||||||
- '/video'
|
|
||||||
headers:
|
|
||||||
Connection:
|
|
||||||
- keep-alive
|
|
||||||
|
|
||||||
- name: vless-grpc
|
|
||||||
server: server
|
|
||||||
port: 443
|
|
||||||
type: vless
|
|
||||||
uuid: uuid
|
|
||||||
network: grpc
|
|
||||||
servername: example.com
|
|
||||||
# skip-cert-verify: true
|
|
||||||
grpc-opts:
|
|
||||||
grpc-service-name: "example"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### IPTABLES auto-configuration
|
### IPTABLES auto-configuration
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
//go:build darwin
|
||||||
// +build darwin
|
// +build darwin
|
||||||
|
|
||||||
package dev
|
package dev
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
//go:build linux || android
|
||||||
// +build linux android
|
// +build linux android
|
||||||
|
|
||||||
package dev
|
package dev
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
//go:build !linux && !android && !darwin && !windows
|
||||||
// +build !linux,!android,!darwin,!windows
|
// +build !linux,!android,!darwin,!windows
|
||||||
|
|
||||||
package dev
|
package dev
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
|
//go:build windows
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
|
// Modified from: https://git.zx2c4.com/wireguard-go/tree/tun/tun_windows.go and https://git.zx2c4.com/wireguard-windows/tree/tunnel/addressconfig.go
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
package dev
|
package dev
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -38,8 +42,8 @@ type rateJuggler struct {
|
||||||
type tunWindows struct {
|
type tunWindows struct {
|
||||||
wt *wintun.Adapter
|
wt *wintun.Adapter
|
||||||
handle windows.Handle
|
handle windows.Handle
|
||||||
closed bool
|
close int32
|
||||||
closing sync.RWMutex
|
running sync.WaitGroup
|
||||||
forcedMTU int
|
forcedMTU int
|
||||||
rate rateJuggler
|
rate rateJuggler
|
||||||
session wintun.Session
|
session wintun.Session
|
||||||
|
@ -152,31 +156,30 @@ func CreateTUNWithRequestedGUID(ifname string, requestedGUID *windows.GUID, mtu
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *tunWindows) getName() (string, error) {
|
func (tun *tunWindows) getName() (string, error) {
|
||||||
tun.closing.RLock()
|
tun.running.Add(1)
|
||||||
defer tun.closing.RUnlock()
|
defer tun.running.Done()
|
||||||
if tun.closed {
|
if atomic.LoadInt32(&tun.close) == 1 {
|
||||||
return "", os.ErrClosed
|
return "", os.ErrClosed
|
||||||
}
|
}
|
||||||
return tun.wt.Name()
|
return tun.wt.Name()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *tunWindows) IsClose() bool {
|
func (tun *tunWindows) IsClose() bool {
|
||||||
return tun.closed
|
return atomic.LoadInt32(&tun.close) == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *tunWindows) Close() error {
|
func (tun *tunWindows) Close() error {
|
||||||
tun.stopOnce.Do(func() {
|
tun.stopOnce.Do(func() {
|
||||||
//tun.closing.Lock()
|
atomic.StoreInt32(&tun.close, 1)
|
||||||
//defer tun.closing.Unlock()
|
//tun.running.Wait()
|
||||||
tun.closed = true
|
|
||||||
tun.session.End()
|
tun.session.End()
|
||||||
if tun.wt != nil {
|
if tun.wt != nil {
|
||||||
forceCloseSessions := false
|
forceCloseSessions := false
|
||||||
rebootRequired, err := tun.wt.Delete(forceCloseSessions)
|
rebootRequired, err := tun.wt.Delete(forceCloseSessions)
|
||||||
if rebootRequired {
|
if rebootRequired {
|
||||||
log.Infoln("Delete Wintun failure, Windows indicated a reboot is required.")
|
log.Infoln("Remove Wintun failure, Windows indicated a reboot is required.")
|
||||||
} else {
|
} else {
|
||||||
log.Infoln("Delete Wintun success.")
|
log.Infoln("Remove Wintun adapter success.")
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorln("Close Wintun Sessions failure: %v", err)
|
log.Errorln("Close Wintun Sessions failure: %v", err)
|
||||||
|
@ -202,16 +205,16 @@ func (tun *tunWindows) Read(buff []byte) (int, error) {
|
||||||
// Note: Read() and Write() assume the caller comes only from a single thread; there's no locking.
|
// Note: Read() and Write() assume the caller comes only from a single thread; there's no locking.
|
||||||
|
|
||||||
func (tun *tunWindows) ReadO(buff []byte, offset int) (int, error) {
|
func (tun *tunWindows) ReadO(buff []byte, offset int) (int, error) {
|
||||||
tun.closing.RLock()
|
tun.running.Add(1)
|
||||||
defer tun.closing.RUnlock()
|
defer tun.running.Done()
|
||||||
retry:
|
retry:
|
||||||
if tun.closed {
|
if atomic.LoadInt32(&tun.close) == 1 {
|
||||||
return 0, os.ErrClosed
|
return 0, os.ErrClosed
|
||||||
}
|
}
|
||||||
start := nanotime()
|
start := nanotime()
|
||||||
shouldSpin := atomic.LoadUint64(&tun.rate.current) >= spinloopRateThreshold && uint64(start-atomic.LoadInt64(&tun.rate.nextStartTime)) <= rateMeasurementGranularity*2
|
shouldSpin := atomic.LoadUint64(&tun.rate.current) >= spinloopRateThreshold && uint64(start-atomic.LoadInt64(&tun.rate.nextStartTime)) <= rateMeasurementGranularity*2
|
||||||
for {
|
for {
|
||||||
if tun.closed {
|
if atomic.LoadInt32(&tun.close) == 1 {
|
||||||
return 0, os.ErrClosed
|
return 0, os.ErrClosed
|
||||||
}
|
}
|
||||||
packet, err := tun.session.ReceivePacket()
|
packet, err := tun.session.ReceivePacket()
|
||||||
|
@ -247,12 +250,15 @@ func (tun *tunWindows) Write(buff []byte) (int, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tun *tunWindows) WriteO(buff []byte, offset int) (int, error) {
|
func (tun *tunWindows) WriteO(buff []byte, offset int) (int, error) {
|
||||||
tun.closing.RLock()
|
tun.running.Add(1)
|
||||||
defer tun.closing.RUnlock()
|
defer tun.running.Done()
|
||||||
if tun.closed {
|
if atomic.LoadInt32(&tun.close) == 1 {
|
||||||
return 0, os.ErrClosed
|
return 0, os.ErrClosed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(buff) == 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
packetSize := len(buff) - offset
|
packetSize := len(buff) - offset
|
||||||
tun.rate.update(uint64(packetSize))
|
tun.rate.update(uint64(packetSize))
|
||||||
|
|
||||||
|
@ -273,9 +279,9 @@ func (tun *tunWindows) WriteO(buff []byte, offset int) (int, error) {
|
||||||
|
|
||||||
// LUID returns Windows interface instance ID.
|
// LUID returns Windows interface instance ID.
|
||||||
func (tun *tunWindows) LUID() uint64 {
|
func (tun *tunWindows) LUID() uint64 {
|
||||||
tun.closing.RLock()
|
tun.running.Add(1)
|
||||||
defer tun.closing.RUnlock()
|
defer tun.running.Done()
|
||||||
if tun.closed {
|
if atomic.LoadInt32(&tun.close) == 1 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return tun.wt.LUID()
|
return tun.wt.LUID()
|
||||||
|
@ -311,7 +317,7 @@ func (t *tunWindows) URL() string {
|
||||||
|
|
||||||
func (tun *tunWindows) configureInterface() error {
|
func (tun *tunWindows) configureInterface() error {
|
||||||
luid := winipcfg.LUID(tun.LUID())
|
luid := winipcfg.LUID(tun.LUID())
|
||||||
|
log.Infoln("[wintun]: tun adapter LUID: %d", luid)
|
||||||
mtu, err := tun.MTU()
|
mtu, err := tun.MTU()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -338,18 +344,17 @@ func (tun *tunWindows) configureInterface() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = luid.FlushRoutes(familyV6)
|
err = luid.FlushRoutes(familyV6)
|
||||||
if err != nil {
|
//if err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
//}
|
||||||
|
|
||||||
err = luid.SetIPAddressesForFamily(family, addresses)
|
err = luid.SetIPAddressesForFamily(family, addresses)
|
||||||
|
|
||||||
if err == windows.ERROR_OBJECT_ALREADY_EXISTS {
|
if err == windows.ERROR_OBJECT_ALREADY_EXISTS {
|
||||||
cleanupAddressesOnDisconnectedInterfaces(family, addresses)
|
cleanupAddressesOnDisconnectedInterfaces(family, addresses)
|
||||||
err = luid.SetIPAddressesForFamily(family, addresses)
|
err = luid.SetIPAddressesForFamily(family, addresses)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("unable to set ips %+v: %w", addresses, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
foundDefault4 := false
|
foundDefault4 := false
|
||||||
|
@ -357,6 +362,7 @@ func (tun *tunWindows) configureInterface() error {
|
||||||
|
|
||||||
if tun.autoRoute {
|
if tun.autoRoute {
|
||||||
allowedIPs := []*winipcfg.IPCidr{
|
allowedIPs := []*winipcfg.IPCidr{
|
||||||
|
//winipcfg.ParseIPCidr("0.0.0.0/0"),
|
||||||
winipcfg.ParseIPCidr("1.0.0.0/8"),
|
winipcfg.ParseIPCidr("1.0.0.0/8"),
|
||||||
winipcfg.ParseIPCidr("2.0.0.0/7"),
|
winipcfg.ParseIPCidr("2.0.0.0/7"),
|
||||||
winipcfg.ParseIPCidr("4.0.0.0/6"),
|
winipcfg.ParseIPCidr("4.0.0.0/6"),
|
||||||
|
@ -427,7 +433,7 @@ func (tun *tunWindows) configureInterface() error {
|
||||||
|
|
||||||
err = luid.SetRoutesForFamily(family, deduplicatedRoutes)
|
err = luid.SetRoutesForFamily(family, deduplicatedRoutes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("unable to set routes %+v: %w", deduplicatedRoutes, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,38 +441,42 @@ func (tun *tunWindows) configureInterface() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
ipif.RouterDiscoveryBehavior = winipcfg.RouterDiscoveryDisabled
|
||||||
|
ipif.DadTransmits = 0
|
||||||
|
ipif.ManagedAddressConfigurationSupported = false
|
||||||
|
ipif.OtherStatefulConfigurationSupported = false
|
||||||
|
|
||||||
ipif.NLMTU = uint32(mtu)
|
ipif.NLMTU = uint32(mtu)
|
||||||
|
|
||||||
if family == windows.AF_INET {
|
if (family == windows.AF_INET && foundDefault4) || (family == windows.AF_INET6 && foundDefault6) {
|
||||||
if foundDefault4 {
|
|
||||||
ipif.UseAutomaticMetric = false
|
ipif.UseAutomaticMetric = false
|
||||||
ipif.Metric = 0
|
ipif.Metric = 0
|
||||||
}
|
}
|
||||||
} else if family == windows.AF_INET6 {
|
|
||||||
if foundDefault6 {
|
|
||||||
ipif.UseAutomaticMetric = false
|
|
||||||
ipif.Metric = 0
|
|
||||||
}
|
|
||||||
ipif.DadTransmits = 0
|
|
||||||
ipif.RouterDiscoveryBehavior = winipcfg.RouterDiscoveryDisabled
|
|
||||||
}
|
|
||||||
|
|
||||||
err = ipif.Set()
|
err = ipif.Set()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("unable to set metric and MTU: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ipif6, err := luid.IPInterface(familyV6)
|
ipif6, err := luid.IPInterface(familyV6)
|
||||||
|
ipif6.RouterDiscoveryBehavior = winipcfg.RouterDiscoveryDisabled
|
||||||
|
ipif6.DadTransmits = 0
|
||||||
|
ipif6.ManagedAddressConfigurationSupported = false
|
||||||
|
ipif6.OtherStatefulConfigurationSupported = false
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = ipif6.Set()
|
err = ipif6.Set()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("unable to set v6 metric and MTU: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return luid.SetDNS(family, []net.IP{net.ParseIP("198.18.0.2")}, nil)
|
err = luid.SetDNS(family, []net.IP{net.ParseIP("198.18.0.2")}, nil)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to set DNS %s %s: %w", "198.18.0.2", "nil", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func cleanupAddressesOnDisconnectedInterfaces(family winipcfg.AddressFamily, addresses []net.IPNet) {
|
func cleanupAddressesOnDisconnectedInterfaces(family winipcfg.AddressFamily, addresses []net.IPNet) {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
//go:build windows
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
package winipcfg
|
package winipcfg
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
|
//go:build windows
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
|
/* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
package winipcfg
|
package winipcfg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,9 +1,16 @@
|
||||||
|
//go:build windows
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
|
/* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
package winipcfg
|
package winipcfg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -95,6 +102,9 @@ func (luid LUID) AddIPAddress(address net.IPNet) error {
|
||||||
row := &MibUnicastIPAddressRow{}
|
row := &MibUnicastIPAddressRow{}
|
||||||
row.Init()
|
row.Init()
|
||||||
row.InterfaceLUID = luid
|
row.InterfaceLUID = luid
|
||||||
|
row.DadState = DadStatePreferred
|
||||||
|
row.ValidLifetime = 0xffffffff
|
||||||
|
row.PreferredLifetime = 0xffffffff
|
||||||
err := row.Address.SetIP(address.IP, 0)
|
err := row.Address.SetIP(address.IP, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -186,6 +196,8 @@ func (luid LUID) Route(destination net.IPNet, nextHop net.IP) (*MibIPforwardRow2
|
||||||
row := &MibIPforwardRow2{}
|
row := &MibIPforwardRow2{}
|
||||||
row.Init()
|
row.Init()
|
||||||
row.InterfaceLUID = luid
|
row.InterfaceLUID = luid
|
||||||
|
row.ValidLifetime = 0xffffffff
|
||||||
|
row.PreferredLifetime = 0xffffffff
|
||||||
err := row.DestinationPrefix.SetIPNet(destination)
|
err := row.DestinationPrefix.SetIPNet(destination)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -210,14 +222,19 @@ func (luid LUID) AddRoute(destination net.IPNet, nextHop net.IP, metric uint32)
|
||||||
row.InterfaceLUID = luid
|
row.InterfaceLUID = luid
|
||||||
err := row.DestinationPrefix.SetIPNet(destination)
|
err := row.DestinationPrefix.SetIPNet(destination)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("AddRoute1: %w", err)
|
||||||
}
|
}
|
||||||
err = row.NextHop.SetIP(nextHop, 0)
|
err = row.NextHop.SetIP(nextHop, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("AddRoute2: %w", err)
|
||||||
}
|
}
|
||||||
row.Metric = metric
|
row.Metric = metric
|
||||||
return row.Create()
|
|
||||||
|
err = row.Create()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("AddRoute3: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddRoutes method adds multiple routes to the interface.
|
// AddRoutes method adds multiple routes to the interface.
|
||||||
|
@ -242,10 +259,11 @@ func (luid LUID) SetRoutes(routesData []*RouteData) error {
|
||||||
|
|
||||||
// SetRoutesForFamily method sets (flush than add) multiple routes for a specific family to the interface.
|
// SetRoutesForFamily method sets (flush than add) multiple routes for a specific family to the interface.
|
||||||
func (luid LUID) SetRoutesForFamily(family AddressFamily, routesData []*RouteData) error {
|
func (luid LUID) SetRoutesForFamily(family AddressFamily, routesData []*RouteData) error {
|
||||||
err := luid.FlushRoutes(family)
|
//err := luid.FlushRoutes(family)
|
||||||
if err != nil {
|
//if err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
//}
|
||||||
|
_ = luid.FlushRoutes(family)
|
||||||
for _, rd := range routesData {
|
for _, rd := range routesData {
|
||||||
asV4 := rd.Destination.IP.To4()
|
asV4 := rd.Destination.IP.To4()
|
||||||
if asV4 == nil && family == windows.AF_INET {
|
if asV4 == nil && family == windows.AF_INET {
|
||||||
|
@ -288,7 +306,7 @@ func (luid LUID) FlushRoutes(family AddressFamily) error {
|
||||||
var tab *mibIPforwardTable2
|
var tab *mibIPforwardTable2
|
||||||
err := getIPForwardTable2(family, &tab)
|
err := getIPForwardTable2(family, &tab)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("FlushRoutes1: %w", err)
|
||||||
}
|
}
|
||||||
t := tab.get()
|
t := tab.get()
|
||||||
for i := range t {
|
for i := range t {
|
||||||
|
@ -300,7 +318,10 @@ func (luid LUID) FlushRoutes(family AddressFamily) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tab.free()
|
tab.free()
|
||||||
return err
|
if err != nil {
|
||||||
|
return fmt.Errorf("FlushRoutes2: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DNS method returns all DNS server addresses associated with the adapter.
|
// DNS method returns all DNS server addresses associated with the adapter.
|
||||||
|
@ -350,17 +371,17 @@ func (luid LUID) SetDNS(family AddressFamily, servers []net.IP, domains []string
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var maybeV6 uint64
|
dnsInterfaceSettings := &DnsInterfaceSettings{
|
||||||
if family == windows.AF_INET6 {
|
Version: DnsInterfaceSettingsVersion1,
|
||||||
maybeV6 = disFlagsIPv6
|
Flags: DnsInterfaceSettingsFlagNameserver | DnsInterfaceSettingsFlagSearchList,
|
||||||
}
|
|
||||||
// For >= Windows 10 1809
|
|
||||||
err = setInterfaceDnsSettings(*guid, &dnsInterfaceSettings{
|
|
||||||
Version: disVersion1,
|
|
||||||
Flags: disFlagsNameServer | disFlagsSearchList | maybeV6,
|
|
||||||
NameServer: servers16,
|
NameServer: servers16,
|
||||||
SearchList: domains16,
|
SearchList: domains16,
|
||||||
})
|
}
|
||||||
|
if family == windows.AF_INET6 {
|
||||||
|
dnsInterfaceSettings.Flags |= DnsInterfaceSettingsFlagIPv6
|
||||||
|
}
|
||||||
|
// For >= Windows 10 1809
|
||||||
|
err = SetInterfaceDnsSettings(*guid, dnsInterfaceSettings)
|
||||||
if err == nil || !errors.Is(err, windows.ERROR_PROC_NOT_FOUND) {
|
if err == nil || !errors.Is(err, windows.ERROR_PROC_NOT_FOUND) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
//go:build windows
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
/* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
package winipcfg
|
package winipcfg
|
||||||
|
|
||||||
//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zwinipcfg_windows.go winipcfg.go
|
//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zwinipcfg_windows.go winipcfg.go
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
|
//go:build windows
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
|
/* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
package winipcfg
|
package winipcfg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
7
listener/tun/dev/winipcfg/package_info.go
Normal file
7
listener/tun/dev/winipcfg/package_info.go
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
//go:build windows
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
// Modified from: https://git.zx2c4.com/wireguard-windows/tree/tunnel/winipcfg
|
||||||
|
// License: MIT
|
||||||
|
|
||||||
|
package winipcfg
|
|
@ -1,5 +1,11 @@
|
||||||
|
//go:build windows
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
|
/* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
package winipcfg
|
package winipcfg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,8 +1,16 @@
|
||||||
|
//go:build windows
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
|
/* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
package winipcfg
|
package winipcfg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
@ -584,6 +592,10 @@ type RouteData struct {
|
||||||
Metric uint32
|
Metric uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (routeData *RouteData) String() string {
|
||||||
|
return fmt.Sprintf("%+v", *routeData)
|
||||||
|
}
|
||||||
|
|
||||||
// IPAdapterDNSSuffix structure stores a DNS suffix in a linked list of DNS suffixes for a particular adapter.
|
// IPAdapterDNSSuffix structure stores a DNS suffix in a linked list of DNS suffixes for a particular adapter.
|
||||||
// https://docs.microsoft.com/en-us/windows/desktop/api/iptypes/ns-iptypes-_ip_adapter_dns_suffix
|
// https://docs.microsoft.com/en-us/windows/desktop/api/iptypes/ns-iptypes-_ip_adapter_dns_suffix
|
||||||
type IPAdapterDNSSuffix struct {
|
type IPAdapterDNSSuffix struct {
|
||||||
|
@ -731,6 +743,16 @@ type RawSockaddrInet struct {
|
||||||
data [26]byte
|
data [26]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ntohs(i uint16) uint16 {
|
||||||
|
return binary.BigEndian.Uint16((*[2]byte)(unsafe.Pointer(&i))[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
func htons(i uint16) uint16 {
|
||||||
|
b := make([]byte, 2)
|
||||||
|
binary.BigEndian.PutUint16(b, i)
|
||||||
|
return *(*uint16)(unsafe.Pointer(&b[0]))
|
||||||
|
}
|
||||||
|
|
||||||
// SetIP method sets family, address, and port to the given IPv4 or IPv6 address and port.
|
// SetIP method sets family, address, and port to the given IPv4 or IPv6 address and port.
|
||||||
// All other members of the structure are set to zero.
|
// All other members of the structure are set to zero.
|
||||||
func (addr *RawSockaddrInet) SetIP(ip net.IP, port uint16) error {
|
func (addr *RawSockaddrInet) SetIP(ip net.IP, port uint16) error {
|
||||||
|
@ -738,7 +760,7 @@ func (addr *RawSockaddrInet) SetIP(ip net.IP, port uint16) error {
|
||||||
addr4 := (*windows.RawSockaddrInet4)(unsafe.Pointer(addr))
|
addr4 := (*windows.RawSockaddrInet4)(unsafe.Pointer(addr))
|
||||||
addr4.Family = windows.AF_INET
|
addr4.Family = windows.AF_INET
|
||||||
copy(addr4.Addr[:], v4)
|
copy(addr4.Addr[:], v4)
|
||||||
addr4.Port = port
|
addr4.Port = htons(port)
|
||||||
for i := 0; i < 8; i++ {
|
for i := 0; i < 8; i++ {
|
||||||
addr4.Zero[i] = 0
|
addr4.Zero[i] = 0
|
||||||
}
|
}
|
||||||
|
@ -748,7 +770,7 @@ func (addr *RawSockaddrInet) SetIP(ip net.IP, port uint16) error {
|
||||||
if v6 := ip.To16(); v6 != nil {
|
if v6 := ip.To16(); v6 != nil {
|
||||||
addr6 := (*windows.RawSockaddrInet6)(unsafe.Pointer(addr))
|
addr6 := (*windows.RawSockaddrInet6)(unsafe.Pointer(addr))
|
||||||
addr6.Family = windows.AF_INET6
|
addr6.Family = windows.AF_INET6
|
||||||
addr6.Port = port
|
addr6.Port = htons(port)
|
||||||
addr6.Flowinfo = 0
|
addr6.Flowinfo = 0
|
||||||
copy(addr6.Addr[:], v6)
|
copy(addr6.Addr[:], v6)
|
||||||
addr6.Scope_id = 0
|
addr6.Scope_id = 0
|
||||||
|
@ -758,8 +780,7 @@ func (addr *RawSockaddrInet) SetIP(ip net.IP, port uint16) error {
|
||||||
return windows.ERROR_INVALID_PARAMETER
|
return windows.ERROR_INVALID_PARAMETER
|
||||||
}
|
}
|
||||||
|
|
||||||
// IP method returns IPv4 or IPv6 address.
|
// IP returns IPv4 or IPv6 address, or nil if the address is neither.
|
||||||
// If the address is neither IPv4 not IPv6 nil is returned.
|
|
||||||
func (addr *RawSockaddrInet) IP() net.IP {
|
func (addr *RawSockaddrInet) IP() net.IP {
|
||||||
switch addr.Family {
|
switch addr.Family {
|
||||||
case windows.AF_INET:
|
case windows.AF_INET:
|
||||||
|
@ -772,6 +793,19 @@ func (addr *RawSockaddrInet) IP() net.IP {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Port returns the port if the address if IPv4 or IPv6, or 0 if neither.
|
||||||
|
func (addr *RawSockaddrInet) Port() uint16 {
|
||||||
|
switch addr.Family {
|
||||||
|
case windows.AF_INET:
|
||||||
|
return ntohs((*windows.RawSockaddrInet4)(unsafe.Pointer(addr)).Port)
|
||||||
|
|
||||||
|
case windows.AF_INET6:
|
||||||
|
return ntohs((*windows.RawSockaddrInet6)(unsafe.Pointer(addr)).Port)
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
// Init method initializes a MibUnicastIPAddressRow structure with default values for a unicast IP address entry on the local computer.
|
// Init method initializes a MibUnicastIPAddressRow structure with default values for a unicast IP address entry on the local computer.
|
||||||
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/nf-netioapi-initializeunicastipaddressentry
|
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/nf-netioapi-initializeunicastipaddressentry
|
||||||
func (row *MibUnicastIPAddressRow) Init() {
|
func (row *MibUnicastIPAddressRow) Init() {
|
||||||
|
@ -938,11 +972,11 @@ func (tab *mibIPforwardTable2) free() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Undocumented DNS API
|
// DNS API
|
||||||
//
|
//
|
||||||
|
|
||||||
// dnsInterfaceSettings is mean to be used with setInterfaceDnsSettings
|
// DnsInterfaceSettings is meant to be used with SetInterfaceDnsSettings
|
||||||
type dnsInterfaceSettings struct {
|
type DnsInterfaceSettings struct {
|
||||||
Version uint32
|
Version uint32
|
||||||
_ [4]byte
|
_ [4]byte
|
||||||
Flags uint64
|
Flags uint64
|
||||||
|
@ -957,21 +991,24 @@ type dnsInterfaceSettings struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
disVersion1 = 1
|
DnsInterfaceSettingsVersion1 = 1 // for DnsInterfaceSettings
|
||||||
disVersion2 = 2
|
DnsInterfaceSettingsVersion2 = 2 // for DnsInterfaceSettingsEx
|
||||||
|
DnsInterfaceSettingsVersion3 = 3 // for DnsInterfaceSettings3
|
||||||
|
|
||||||
disFlagsIPv6 = 0x1
|
DnsInterfaceSettingsFlagIPv6 = 0x0001
|
||||||
disFlagsNameServer = 0x2
|
DnsInterfaceSettingsFlagNameserver = 0x0002
|
||||||
disFlagsSearchList = 0x4
|
DnsInterfaceSettingsFlagSearchList = 0x0004
|
||||||
disFlagsRegistrationEnabled = 0x8
|
DnsInterfaceSettingsFlagRegistrationEnabled = 0x0008
|
||||||
disFlagsRegisterAdapterName = 0x10
|
DnsInterfaceSettingsFlagRegisterAdapterName = 0x0010
|
||||||
disFlagsDomain = 0x20
|
DnsInterfaceSettingsFlagDomain = 0x0020
|
||||||
disFlagsHostname = 0x40 // ??
|
DnsInterfaceSettingsFlagHostname = 0x0040
|
||||||
disFlagsEnableLLMNR = 0x80
|
DnsInterfaceSettingsFlagEnableLLMNR = 0x0080
|
||||||
disFlagsQueryAdapterName = 0x100
|
DnsInterfaceSettingsFlagQueryAdapterName = 0x0100
|
||||||
disFlagsProfileNameServer = 0x200
|
DnsInterfaceSettingsFlagProfileNameserver = 0x0200
|
||||||
disFlagsVersion2 = 0x400 // ?? - v2 only
|
DnsInterfaceSettingsFlagDisableUnconstrainedQueries = 0x0400 // v2 only
|
||||||
disFlagsMoreFlags = 0x800 // ?? - v2 only
|
DnsInterfaceSettingsFlagSupplementalSearchList = 0x0800 // v2 only
|
||||||
|
DnsInterfaceSettingsFlagDOH = 0x1000 // v3 only
|
||||||
|
DnsInterfaceSettingsFlagDOHProfile = 0x2000 // v3 only
|
||||||
)
|
)
|
||||||
|
|
||||||
// unsafeSlice updates the slice slicePtr to be a slice
|
// unsafeSlice updates the slice slicePtr to be a slice
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
|
//go:build windows && (386 || arm)
|
||||||
|
// +build windows
|
||||||
// +build 386 arm
|
// +build 386 arm
|
||||||
|
|
||||||
|
/* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
package winipcfg
|
package winipcfg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
|
//go:build windows && (amd64 || arm64)
|
||||||
// +build windows
|
// +build windows
|
||||||
// +build amd64 arm64
|
// +build amd64 arm64
|
||||||
|
|
||||||
|
/* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
package winipcfg
|
package winipcfg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
|
//go:build windows
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
|
/* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
package winipcfg
|
package winipcfg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
|
//go:build windows
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
|
/* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
package winipcfg
|
package winipcfg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -167,18 +173,18 @@ func GetIPForwardTable2(family AddressFamily) ([]MibIPforwardRow2, error) {
|
||||||
//sys cancelMibChangeNotify2(notificationHandle windows.Handle) (ret error) = iphlpapi.CancelMibChangeNotify2
|
//sys cancelMibChangeNotify2(notificationHandle windows.Handle) (ret error) = iphlpapi.CancelMibChangeNotify2
|
||||||
|
|
||||||
//
|
//
|
||||||
// Undocumented DNS API
|
// DNS-related functions
|
||||||
//
|
//
|
||||||
|
|
||||||
//sys setInterfaceDnsSettingsByPtr(guid *windows.GUID, settings *dnsInterfaceSettings) (ret error) = iphlpapi.SetInterfaceDnsSettings?
|
//sys setInterfaceDnsSettingsByPtr(guid *windows.GUID, settings *DnsInterfaceSettings) (ret error) = iphlpapi.SetInterfaceDnsSettings?
|
||||||
//sys setInterfaceDnsSettingsByQwords(guid1 uintptr, guid2 uintptr, settings *dnsInterfaceSettings) (ret error) = iphlpapi.SetInterfaceDnsSettings?
|
//sys setInterfaceDnsSettingsByQwords(guid1 uintptr, guid2 uintptr, settings *DnsInterfaceSettings) (ret error) = iphlpapi.SetInterfaceDnsSettings?
|
||||||
//sys setInterfaceDnsSettingsByDwords(guid1 uintptr, guid2 uintptr, guid3 uintptr, guid4 uintptr, settings *dnsInterfaceSettings) (ret error) = iphlpapi.SetInterfaceDnsSettings?
|
//sys setInterfaceDnsSettingsByDwords(guid1 uintptr, guid2 uintptr, guid3 uintptr, guid4 uintptr, settings *DnsInterfaceSettings) (ret error) = iphlpapi.SetInterfaceDnsSettings?
|
||||||
|
|
||||||
// The GUID is passed by value, not by reference, which means different
|
// The GUID is passed by value, not by reference, which means different
|
||||||
// things on different calling conventions. On amd64, this means it's
|
// things on different calling conventions. On amd64, this means it's
|
||||||
// passed by reference anyway, while on arm, arm64, and 386, it's split
|
// passed by reference anyway, while on arm, arm64, and 386, it's split
|
||||||
// into words.
|
// into words.
|
||||||
func setInterfaceDnsSettings(guid windows.GUID, settings *dnsInterfaceSettings) error {
|
func SetInterfaceDnsSettings(guid windows.GUID, settings *DnsInterfaceSettings) error {
|
||||||
words := (*[4]uintptr)(unsafe.Pointer(&guid))
|
words := (*[4]uintptr)(unsafe.Pointer(&guid))
|
||||||
switch runtime.GOARCH {
|
switch runtime.GOARCH {
|
||||||
case "amd64":
|
case "amd64":
|
||||||
|
|
|
@ -289,7 +289,7 @@ func notifyUnicastIPAddressChange(family AddressFamily, callback uintptr, caller
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func setInterfaceDnsSettingsByDwords(guid1 uintptr, guid2 uintptr, guid3 uintptr, guid4 uintptr, settings *dnsInterfaceSettings) (ret error) {
|
func setInterfaceDnsSettingsByDwords(guid1 uintptr, guid2 uintptr, guid3 uintptr, guid4 uintptr, settings *DnsInterfaceSettings) (ret error) {
|
||||||
ret = procSetInterfaceDnsSettings.Find()
|
ret = procSetInterfaceDnsSettings.Find()
|
||||||
if ret != nil {
|
if ret != nil {
|
||||||
return
|
return
|
||||||
|
@ -301,24 +301,24 @@ func setInterfaceDnsSettingsByDwords(guid1 uintptr, guid2 uintptr, guid3 uintptr
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func setInterfaceDnsSettingsByPtr(guid *windows.GUID, settings *dnsInterfaceSettings) (ret error) {
|
func setInterfaceDnsSettingsByQwords(guid1 uintptr, guid2 uintptr, settings *DnsInterfaceSettings) (ret error) {
|
||||||
ret = procSetInterfaceDnsSettings.Find()
|
ret = procSetInterfaceDnsSettings.Find()
|
||||||
if ret != nil {
|
if ret != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r0, _, _ := syscall.Syscall(procSetInterfaceDnsSettings.Addr(), 2, uintptr(unsafe.Pointer(guid)), uintptr(unsafe.Pointer(settings)), 0)
|
r0, _, _ := syscall.Syscall(procSetInterfaceDnsSettings.Addr(), 3, uintptr(guid1), uintptr(guid2), uintptr(unsafe.Pointer(settings)))
|
||||||
if r0 != 0 {
|
if r0 != 0 {
|
||||||
ret = syscall.Errno(r0)
|
ret = syscall.Errno(r0)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func setInterfaceDnsSettingsByQwords(guid1 uintptr, guid2 uintptr, settings *dnsInterfaceSettings) (ret error) {
|
func setInterfaceDnsSettingsByPtr(guid *windows.GUID, settings *DnsInterfaceSettings) (ret error) {
|
||||||
ret = procSetInterfaceDnsSettings.Find()
|
ret = procSetInterfaceDnsSettings.Find()
|
||||||
if ret != nil {
|
if ret != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r0, _, _ := syscall.Syscall(procSetInterfaceDnsSettings.Addr(), 3, uintptr(guid1), uintptr(guid2), uintptr(unsafe.Pointer(settings)))
|
r0, _, _ := syscall.Syscall(procSetInterfaceDnsSettings.Addr(), 2, uintptr(unsafe.Pointer(guid)), uintptr(unsafe.Pointer(settings)), 0)
|
||||||
if r0 != 0 {
|
if r0 != 0 {
|
||||||
ret = syscall.Errno(r0)
|
ret = syscall.Errno(r0)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
//go:build !load_wintun_from_rsrc
|
||||||
// +build !load_wintun_from_rsrc
|
// +build !load_wintun_from_rsrc
|
||||||
|
|
||||||
package wintun
|
package wintun
|
||||||
|
@ -8,6 +9,7 @@ import (
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
C "github.com/Dreamacro/clash/constant"
|
||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -28,11 +30,12 @@ func (d *lazyDLL) Load() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
//const (
|
||||||
LOAD_LIBRARY_SEARCH_APPLICATION_DIR = 0x00000200
|
// LOAD_LIBRARY_SEARCH_APPLICATION_DIR = 0x00000200
|
||||||
LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800
|
// LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800
|
||||||
)
|
//)
|
||||||
module, err := windows.LoadLibraryEx(d.Name, 0, LOAD_LIBRARY_SEARCH_APPLICATION_DIR|LOAD_LIBRARY_SEARCH_SYSTEM32)
|
//module, err := windows.LoadLibraryEx(d.Name, 0, LOAD_LIBRARY_SEARCH_APPLICATION_DIR|LOAD_LIBRARY_SEARCH_SYSTEM32)
|
||||||
|
module, err := windows.LoadLibraryEx(C.Path.GetAssetLocation(d.Name), 0, windows.LOAD_WITH_ALTERED_SEARCH_PATH)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Unable to load library: %w", err)
|
return fmt.Errorf("Unable to load library: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
//go:build load_wintun_from_rsrc
|
||||||
// +build load_wintun_from_rsrc
|
// +build load_wintun_from_rsrc
|
||||||
|
|
||||||
package wintun
|
package wintun
|
||||||
|
|
|
@ -41,12 +41,12 @@ func (module *Module) headerDirectory(idx int) *IMAGE_DATA_DIRECTORY {
|
||||||
return &module.headers.OptionalHeader.DataDirectory[idx]
|
return &module.headers.OptionalHeader.DataDirectory[idx]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (module *Module) copySections(address uintptr, size uintptr, old_headers *IMAGE_NT_HEADERS) error {
|
func (module *Module) copySections(address uintptr, size uintptr, oldHeaders *IMAGE_NT_HEADERS) error {
|
||||||
sections := module.headers.Sections()
|
sections := module.headers.Sections()
|
||||||
for i := range sections {
|
for i := range sections {
|
||||||
if sections[i].SizeOfRawData == 0 {
|
if sections[i].SizeOfRawData == 0 {
|
||||||
// Section doesn't contain data in the dll itself, but may define uninitialized data.
|
// Section doesn't contain data in the dll itself, but may define uninitialized data.
|
||||||
sectionSize := old_headers.OptionalHeader.SectionAlignment
|
sectionSize := oldHeaders.OptionalHeader.SectionAlignment
|
||||||
if sectionSize == 0 {
|
if sectionSize == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -159,6 +159,16 @@ func (module *Module) finalizeSection(sectionData *sectionFinalizeData) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var rtlAddFunctionTable = windows.NewLazySystemDLL("ntdll.dll").NewProc("RtlAddFunctionTable")
|
||||||
|
|
||||||
|
func (module *Module) registerExceptionHandlers() {
|
||||||
|
directory := module.headerDirectory(IMAGE_DIRECTORY_ENTRY_EXCEPTION)
|
||||||
|
if directory.Size == 0 || directory.VirtualAddress == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rtlAddFunctionTable.Call(module.codeBase+uintptr(directory.VirtualAddress), uintptr(directory.Size)/unsafe.Sizeof(IMAGE_RUNTIME_FUNCTION_ENTRY{}), module.codeBase)
|
||||||
|
}
|
||||||
|
|
||||||
func (module *Module) finalizeSections() error {
|
func (module *Module) finalizeSections() error {
|
||||||
sections := module.headers.Sections()
|
sections := module.headers.Sections()
|
||||||
imageOffset := module.headers.OptionalHeader.imageOffset()
|
imageOffset := module.headers.OptionalHeader.imageOffset()
|
||||||
|
@ -166,6 +176,7 @@ func (module *Module) finalizeSections() error {
|
||||||
sectionData.address = uintptr(sections[0].PhysicalAddress()) | imageOffset
|
sectionData.address = uintptr(sections[0].PhysicalAddress()) | imageOffset
|
||||||
sectionData.alignedAddress = alignDown(sectionData.address, uintptr(module.headers.OptionalHeader.SectionAlignment))
|
sectionData.alignedAddress = alignDown(sectionData.address, uintptr(module.headers.OptionalHeader.SectionAlignment))
|
||||||
sectionData.size = module.realSectionSize(§ions[0])
|
sectionData.size = module.realSectionSize(§ions[0])
|
||||||
|
sections[0].SetVirtualSize(uint32(sectionData.size))
|
||||||
sectionData.characteristics = sections[0].Characteristics
|
sectionData.characteristics = sections[0].Characteristics
|
||||||
|
|
||||||
// Loop through all sections and change access flags.
|
// Loop through all sections and change access flags.
|
||||||
|
@ -173,6 +184,7 @@ func (module *Module) finalizeSections() error {
|
||||||
sectionAddress := uintptr(sections[i].PhysicalAddress()) | imageOffset
|
sectionAddress := uintptr(sections[i].PhysicalAddress()) | imageOffset
|
||||||
alignedAddress := alignDown(sectionAddress, uintptr(module.headers.OptionalHeader.SectionAlignment))
|
alignedAddress := alignDown(sectionAddress, uintptr(module.headers.OptionalHeader.SectionAlignment))
|
||||||
sectionSize := module.realSectionSize(§ions[i])
|
sectionSize := module.realSectionSize(§ions[i])
|
||||||
|
sections[i].SetVirtualSize(uint32(sectionSize))
|
||||||
// Combine access flags of all sections that share a page.
|
// Combine access flags of all sections that share a page.
|
||||||
// TODO: We currently share flags of a trailing large section with the page of a first small section. This should be optimized.
|
// TODO: We currently share flags of a trailing large section with the page of a first small section. This should be optimized.
|
||||||
if sectionData.alignedAddress == alignedAddress || sectionData.address+sectionData.size > alignedAddress {
|
if sectionData.alignedAddress == alignedAddress || sectionData.address+sectionData.size > alignedAddress {
|
||||||
|
@ -498,6 +510,9 @@ func LoadLibrary(data []byte) (module *Module, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Register exception tables, if they exist.
|
||||||
|
module.registerExceptionHandlers()
|
||||||
|
|
||||||
// TLS callbacks are executed BEFORE the main loading.
|
// TLS callbacks are executed BEFORE the main loading.
|
||||||
module.executeTLS()
|
module.executeTLS()
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
// +build windows,386 windows,arm
|
//go:build windows && (386 || arm)
|
||||||
|
// +build windows
|
||||||
|
// +build 386 arm
|
||||||
|
|
||||||
/* SPDX-License-Identifier: MIT
|
/* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
// +build windows,amd64 windows,arm64
|
//go:build windows && (amd64 || arm64)
|
||||||
|
// +build windows
|
||||||
|
// +build amd64 arm64
|
||||||
|
|
||||||
/* SPDX-License-Identifier: MIT
|
/* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
|
|
|
@ -174,6 +174,21 @@ func (ishdr *IMAGE_SECTION_HEADER) SetVirtualSize(addr uint32) {
|
||||||
ishdr.physicalAddressOrVirtualSize = addr
|
ishdr.physicalAddressOrVirtualSize = addr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Dll characteristics.
|
||||||
|
IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020
|
||||||
|
IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040
|
||||||
|
IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080
|
||||||
|
IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100
|
||||||
|
IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION = 0x0200
|
||||||
|
IMAGE_DLL_CHARACTERISTICS_NO_SEH = 0x0400
|
||||||
|
IMAGE_DLL_CHARACTERISTICS_NO_BIND = 0x0800
|
||||||
|
IMAGE_DLL_CHARACTERISTICS_APPCONTAINER = 0x1000
|
||||||
|
IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER = 0x2000
|
||||||
|
IMAGE_DLL_CHARACTERISTICS_GUARD_CF = 0x4000
|
||||||
|
IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Section characteristics.
|
// Section characteristics.
|
||||||
IMAGE_SCN_TYPE_REG = 0x00000000 // Reserved.
|
IMAGE_SCN_TYPE_REG = 0x00000000 // Reserved.
|
||||||
|
@ -317,6 +332,50 @@ func (imgimpdesc *IMAGE_IMPORT_DESCRIPTOR) OriginalFirstThunk() uint32 {
|
||||||
return imgimpdesc.characteristicsOrOriginalFirstThunk
|
return imgimpdesc.characteristicsOrOriginalFirstThunk
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type IMAGE_DELAYLOAD_DESCRIPTOR struct {
|
||||||
|
Attributes uint32
|
||||||
|
DllNameRVA uint32
|
||||||
|
ModuleHandleRVA uint32
|
||||||
|
ImportAddressTableRVA uint32
|
||||||
|
ImportNameTableRVA uint32
|
||||||
|
BoundImportAddressTableRVA uint32
|
||||||
|
UnloadInformationTableRVA uint32
|
||||||
|
TimeDateStamp uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type IMAGE_LOAD_CONFIG_CODE_INTEGRITY struct {
|
||||||
|
Flags uint16
|
||||||
|
Catalog uint16
|
||||||
|
CatalogOffset uint32
|
||||||
|
Reserved uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
IMAGE_GUARD_CF_INSTRUMENTED = 0x00000100
|
||||||
|
IMAGE_GUARD_CFW_INSTRUMENTED = 0x00000200
|
||||||
|
IMAGE_GUARD_CF_FUNCTION_TABLE_PRESENT = 0x00000400
|
||||||
|
IMAGE_GUARD_SECURITY_COOKIE_UNUSED = 0x00000800
|
||||||
|
IMAGE_GUARD_PROTECT_DELAYLOAD_IAT = 0x00001000
|
||||||
|
IMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTION = 0x00002000
|
||||||
|
IMAGE_GUARD_CF_EXPORT_SUPPRESSION_INFO_PRESENT = 0x00004000
|
||||||
|
IMAGE_GUARD_CF_ENABLE_EXPORT_SUPPRESSION = 0x00008000
|
||||||
|
IMAGE_GUARD_CF_LONGJUMP_TABLE_PRESENT = 0x00010000
|
||||||
|
IMAGE_GUARD_RF_INSTRUMENTED = 0x00020000
|
||||||
|
IMAGE_GUARD_RF_ENABLE = 0x00040000
|
||||||
|
IMAGE_GUARD_RF_STRICT = 0x00080000
|
||||||
|
IMAGE_GUARD_RETPOLINE_PRESENT = 0x00100000
|
||||||
|
IMAGE_GUARD_EH_CONTINUATION_TABLE_PRESENT = 0x00400000
|
||||||
|
IMAGE_GUARD_XFG_ENABLED = 0x00800000
|
||||||
|
IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK = 0xF0000000
|
||||||
|
IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_SHIFT = 28
|
||||||
|
)
|
||||||
|
|
||||||
|
type IMAGE_RUNTIME_FUNCTION_ENTRY struct {
|
||||||
|
BeginAddress uint32
|
||||||
|
EndAddress uint32
|
||||||
|
UnwindInfoAddress uint32
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DLL_PROCESS_ATTACH = 1
|
DLL_PROCESS_ATTACH = 1
|
||||||
DLL_THREAD_ATTACH = 2
|
DLL_THREAD_ATTACH = 2
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
// +build windows,386 windows,arm
|
//go:build windows && (386 || arm)
|
||||||
|
// +build windows
|
||||||
|
// +build 386 arm
|
||||||
|
|
||||||
/* SPDX-License-Identifier: MIT
|
/* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
|
@ -43,3 +45,54 @@ type IMAGE_OPTIONAL_HEADER struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
const IMAGE_ORDINAL_FLAG uintptr = 0x80000000
|
const IMAGE_ORDINAL_FLAG uintptr = 0x80000000
|
||||||
|
|
||||||
|
type IMAGE_LOAD_CONFIG_DIRECTORY struct {
|
||||||
|
Size uint32
|
||||||
|
TimeDateStamp uint32
|
||||||
|
MajorVersion uint16
|
||||||
|
MinorVersion uint16
|
||||||
|
GlobalFlagsClear uint32
|
||||||
|
GlobalFlagsSet uint32
|
||||||
|
CriticalSectionDefaultTimeout uint32
|
||||||
|
DeCommitFreeBlockThreshold uint32
|
||||||
|
DeCommitTotalFreeThreshold uint32
|
||||||
|
LockPrefixTable uint32
|
||||||
|
MaximumAllocationSize uint32
|
||||||
|
VirtualMemoryThreshold uint32
|
||||||
|
ProcessHeapFlags uint32
|
||||||
|
ProcessAffinityMask uint32
|
||||||
|
CSDVersion uint16
|
||||||
|
DependentLoadFlags uint16
|
||||||
|
EditList uint32
|
||||||
|
SecurityCookie uint32
|
||||||
|
SEHandlerTable uint32
|
||||||
|
SEHandlerCount uint32
|
||||||
|
GuardCFCheckFunctionPointer uint32
|
||||||
|
GuardCFDispatchFunctionPointer uint32
|
||||||
|
GuardCFFunctionTable uint32
|
||||||
|
GuardCFFunctionCount uint32
|
||||||
|
GuardFlags uint32
|
||||||
|
CodeIntegrity IMAGE_LOAD_CONFIG_CODE_INTEGRITY
|
||||||
|
GuardAddressTakenIatEntryTable uint32
|
||||||
|
GuardAddressTakenIatEntryCount uint32
|
||||||
|
GuardLongJumpTargetTable uint32
|
||||||
|
GuardLongJumpTargetCount uint32
|
||||||
|
DynamicValueRelocTable uint32
|
||||||
|
CHPEMetadataPointer uint32
|
||||||
|
GuardRFFailureRoutine uint32
|
||||||
|
GuardRFFailureRoutineFunctionPointer uint32
|
||||||
|
DynamicValueRelocTableOffset uint32
|
||||||
|
DynamicValueRelocTableSection uint16
|
||||||
|
Reserved2 uint16
|
||||||
|
GuardRFVerifyStackPointerFunctionPointer uint32
|
||||||
|
HotPatchTableOffset uint32
|
||||||
|
Reserved3 uint32
|
||||||
|
EnclaveConfigurationPointer uint32
|
||||||
|
VolatileMetadataPointer uint32
|
||||||
|
GuardEHContinuationTable uint32
|
||||||
|
GuardEHContinuationCount uint32
|
||||||
|
GuardXFGCheckFunctionPointer uint32
|
||||||
|
GuardXFGDispatchFunctionPointer uint32
|
||||||
|
GuardXFGTableDispatchFunctionPointer uint32
|
||||||
|
CastGuardOsDeterminedFailureMode uint32
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
// +build windows,amd64 windows,arm64
|
//go:build windows && (amd64 || arm64)
|
||||||
|
// +build windows
|
||||||
|
// +build amd64 arm64
|
||||||
|
|
||||||
/* SPDX-License-Identifier: MIT
|
/* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
|
@ -42,3 +44,54 @@ type IMAGE_OPTIONAL_HEADER struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
const IMAGE_ORDINAL_FLAG uintptr = 0x8000000000000000
|
const IMAGE_ORDINAL_FLAG uintptr = 0x8000000000000000
|
||||||
|
|
||||||
|
type IMAGE_LOAD_CONFIG_DIRECTORY struct {
|
||||||
|
Size uint32
|
||||||
|
TimeDateStamp uint32
|
||||||
|
MajorVersion uint16
|
||||||
|
MinorVersion uint16
|
||||||
|
GlobalFlagsClear uint32
|
||||||
|
GlobalFlagsSet uint32
|
||||||
|
CriticalSectionDefaultTimeout uint32
|
||||||
|
DeCommitFreeBlockThreshold uint64
|
||||||
|
DeCommitTotalFreeThreshold uint64
|
||||||
|
LockPrefixTable uint64
|
||||||
|
MaximumAllocationSize uint64
|
||||||
|
VirtualMemoryThreshold uint64
|
||||||
|
ProcessAffinityMask uint64
|
||||||
|
ProcessHeapFlags uint32
|
||||||
|
CSDVersion uint16
|
||||||
|
DependentLoadFlags uint16
|
||||||
|
EditList uint64
|
||||||
|
SecurityCookie uint64
|
||||||
|
SEHandlerTable uint64
|
||||||
|
SEHandlerCount uint64
|
||||||
|
GuardCFCheckFunctionPointer uint64
|
||||||
|
GuardCFDispatchFunctionPointer uint64
|
||||||
|
GuardCFFunctionTable uint64
|
||||||
|
GuardCFFunctionCount uint64
|
||||||
|
GuardFlags uint32
|
||||||
|
CodeIntegrity IMAGE_LOAD_CONFIG_CODE_INTEGRITY
|
||||||
|
GuardAddressTakenIatEntryTable uint64
|
||||||
|
GuardAddressTakenIatEntryCount uint64
|
||||||
|
GuardLongJumpTargetTable uint64
|
||||||
|
GuardLongJumpTargetCount uint64
|
||||||
|
DynamicValueRelocTable uint64
|
||||||
|
CHPEMetadataPointer uint64
|
||||||
|
GuardRFFailureRoutine uint64
|
||||||
|
GuardRFFailureRoutineFunctionPointer uint64
|
||||||
|
DynamicValueRelocTableOffset uint32
|
||||||
|
DynamicValueRelocTableSection uint16
|
||||||
|
Reserved2 uint16
|
||||||
|
GuardRFVerifyStackPointerFunctionPointer uint64
|
||||||
|
HotPatchTableOffset uint32
|
||||||
|
Reserved3 uint32
|
||||||
|
EnclaveConfigurationPointer uint64
|
||||||
|
VolatileMetadataPointer uint64
|
||||||
|
GuardEHContinuationTable uint64
|
||||||
|
GuardEHContinuationCount uint64
|
||||||
|
GuardXFGCheckFunctionPointer uint64
|
||||||
|
GuardXFGDispatchFunctionPointer uint64
|
||||||
|
GuardXFGTableDispatchFunctionPointer uint64
|
||||||
|
CastGuardOsDeterminedFailureMode uint64
|
||||||
|
}
|
||||||
|
|
11
listener/tun/dev/wintun/package_info.go
Normal file
11
listener/tun/dev/wintun/package_info.go
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
//go:build windows
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
// Modified from: https://git.zx2c4.com/wireguard-go/tree/tun/wintun
|
||||||
|
|
||||||
|
/* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package wintun
|
4
rule/geodata/package_info.go
Normal file
4
rule/geodata/package_info.go
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
// Modified from: https://github.com/v2fly/v2ray-core/tree/master/infra/conf/geodata
|
||||||
|
// License: MIT
|
||||||
|
|
||||||
|
package geodata
|
4
rule/geodata/strmatcher/package_info.go
Normal file
4
rule/geodata/strmatcher/package_info.go
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
// Modified from: https://github.com/v2fly/v2ray-core/tree/master/common/strmatcher
|
||||||
|
// License: MIT
|
||||||
|
|
||||||
|
package strmatcher
|
Loading…
Reference in a new issue