Chore: format with go 1.17

This commit is contained in:
yaling888 2021-09-24 04:37:04 +08:00
parent 32d8f849ee
commit 433d35e866
29 changed files with 447 additions and 150 deletions

View file

@ -37,9 +37,9 @@ Documentations are now moved to [GitHub Wiki](https://github.com/Dreamacro/clash
## Advanced usage for this fork branch
### 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
# Enable the TUN listener
tun:
@ -53,11 +53,12 @@ tun:
- Support `multiport` condition for rule `SRC-PORT` and `DST-PORT`.
- Support not match condition for rule `GEOIP`.
- 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.
```yaml
rules:
# network condition for rules
# network condition for all rules
- DOMAIN-SUFFIX,bilibili.com,DIRECT,tcp
- DOMAIN-SUFFIX,bilibili.com,REJECT,udp
@ -83,6 +84,9 @@ rules:
# Not match condition for rule GEOIP
#- 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
```
@ -100,7 +104,6 @@ proxies:
uuid: uuid
network: tcp
servername: example.com # AKA SNI
# udp: true
# flow: xtls-rprx-direct # xtls-rprx-origin # enable XTLS
# skip-cert-verify: true
@ -116,49 +119,6 @@ proxies:
ws-path: /path
ws-headers:
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

View file

@ -1,3 +1,4 @@
//go:build darwin
// +build darwin
package dev

View file

@ -1,3 +1,4 @@
//go:build linux || android
// +build linux android
package dev

View file

@ -1,3 +1,4 @@
//go:build !linux && !android && !darwin && !windows
// +build !linux,!android,!darwin,!windows
package dev

View file

@ -1,5 +1,9 @@
//go: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
import (
@ -38,8 +42,8 @@ type rateJuggler struct {
type tunWindows struct {
wt *wintun.Adapter
handle windows.Handle
closed bool
closing sync.RWMutex
close int32
running sync.WaitGroup
forcedMTU int
rate rateJuggler
session wintun.Session
@ -152,31 +156,30 @@ func CreateTUNWithRequestedGUID(ifname string, requestedGUID *windows.GUID, mtu
}
func (tun *tunWindows) getName() (string, error) {
tun.closing.RLock()
defer tun.closing.RUnlock()
if tun.closed {
tun.running.Add(1)
defer tun.running.Done()
if atomic.LoadInt32(&tun.close) == 1 {
return "", os.ErrClosed
}
return tun.wt.Name()
}
func (tun *tunWindows) IsClose() bool {
return tun.closed
return atomic.LoadInt32(&tun.close) == 1
}
func (tun *tunWindows) Close() error {
tun.stopOnce.Do(func() {
//tun.closing.Lock()
//defer tun.closing.Unlock()
tun.closed = true
atomic.StoreInt32(&tun.close, 1)
//tun.running.Wait()
tun.session.End()
if tun.wt != nil {
forceCloseSessions := false
rebootRequired, err := tun.wt.Delete(forceCloseSessions)
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 {
log.Infoln("Delete Wintun success.")
log.Infoln("Remove Wintun adapter success.")
}
if err != nil {
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.
func (tun *tunWindows) ReadO(buff []byte, offset int) (int, error) {
tun.closing.RLock()
defer tun.closing.RUnlock()
tun.running.Add(1)
defer tun.running.Done()
retry:
if tun.closed {
if atomic.LoadInt32(&tun.close) == 1 {
return 0, os.ErrClosed
}
start := nanotime()
shouldSpin := atomic.LoadUint64(&tun.rate.current) >= spinloopRateThreshold && uint64(start-atomic.LoadInt64(&tun.rate.nextStartTime)) <= rateMeasurementGranularity*2
for {
if tun.closed {
if atomic.LoadInt32(&tun.close) == 1 {
return 0, os.ErrClosed
}
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) {
tun.closing.RLock()
defer tun.closing.RUnlock()
if tun.closed {
tun.running.Add(1)
defer tun.running.Done()
if atomic.LoadInt32(&tun.close) == 1 {
return 0, os.ErrClosed
}
if len(buff) == 0 {
return 0, nil
}
packetSize := len(buff) - offset
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.
func (tun *tunWindows) LUID() uint64 {
tun.closing.RLock()
defer tun.closing.RUnlock()
if tun.closed {
tun.running.Add(1)
defer tun.running.Done()
if atomic.LoadInt32(&tun.close) == 1 {
return 0
}
return tun.wt.LUID()
@ -311,7 +317,7 @@ func (t *tunWindows) URL() string {
func (tun *tunWindows) configureInterface() error {
luid := winipcfg.LUID(tun.LUID())
log.Infoln("[wintun]: tun adapter LUID: %d", luid)
mtu, err := tun.MTU()
if err != nil {
@ -338,18 +344,17 @@ func (tun *tunWindows) configureInterface() error {
return err
}
err = luid.FlushRoutes(familyV6)
if err != nil {
return err
}
//if err != nil {
// return err
//}
err = luid.SetIPAddressesForFamily(family, addresses)
if err == windows.ERROR_OBJECT_ALREADY_EXISTS {
cleanupAddressesOnDisconnectedInterfaces(family, addresses)
err = luid.SetIPAddressesForFamily(family, addresses)
}
if err != nil {
return err
return fmt.Errorf("unable to set ips %+v: %w", addresses, err)
}
foundDefault4 := false
@ -357,6 +362,7 @@ func (tun *tunWindows) configureInterface() error {
if tun.autoRoute {
allowedIPs := []*winipcfg.IPCidr{
//winipcfg.ParseIPCidr("0.0.0.0/0"),
winipcfg.ParseIPCidr("1.0.0.0/8"),
winipcfg.ParseIPCidr("2.0.0.0/7"),
winipcfg.ParseIPCidr("4.0.0.0/6"),
@ -427,7 +433,7 @@ func (tun *tunWindows) configureInterface() error {
err = luid.SetRoutesForFamily(family, deduplicatedRoutes)
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 {
return err
}
ipif.RouterDiscoveryBehavior = winipcfg.RouterDiscoveryDisabled
ipif.DadTransmits = 0
ipif.ManagedAddressConfigurationSupported = false
ipif.OtherStatefulConfigurationSupported = false
ipif.NLMTU = uint32(mtu)
if family == windows.AF_INET {
if foundDefault4 {
ipif.UseAutomaticMetric = false
ipif.Metric = 0
}
} else if family == windows.AF_INET6 {
if foundDefault6 {
ipif.UseAutomaticMetric = false
ipif.Metric = 0
}
ipif.DadTransmits = 0
ipif.RouterDiscoveryBehavior = winipcfg.RouterDiscoveryDisabled
if (family == windows.AF_INET && foundDefault4) || (family == windows.AF_INET6 && foundDefault6) {
ipif.UseAutomaticMetric = false
ipif.Metric = 0
}
err = ipif.Set()
if err != nil {
return err
return fmt.Errorf("unable to set metric and MTU: %w", err)
}
ipif6, err := luid.IPInterface(familyV6)
ipif6.RouterDiscoveryBehavior = winipcfg.RouterDiscoveryDisabled
ipif6.DadTransmits = 0
ipif6.ManagedAddressConfigurationSupported = false
ipif6.OtherStatefulConfigurationSupported = false
if err != nil {
return err
}
err = ipif6.Set()
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) {

View file

@ -1,3 +1,4 @@
//go:build windows
// +build windows
package winipcfg

View file

@ -1,5 +1,11 @@
//go:build windows
// +build windows
/* SPDX-License-Identifier: MIT
*
* Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved.
*/
package winipcfg
import (

View file

@ -1,9 +1,16 @@
//go:build windows
// +build windows
/* SPDX-License-Identifier: MIT
*
* Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved.
*/
package winipcfg
import (
"errors"
"fmt"
"net"
"strings"
@ -95,6 +102,9 @@ func (luid LUID) AddIPAddress(address net.IPNet) error {
row := &MibUnicastIPAddressRow{}
row.Init()
row.InterfaceLUID = luid
row.DadState = DadStatePreferred
row.ValidLifetime = 0xffffffff
row.PreferredLifetime = 0xffffffff
err := row.Address.SetIP(address.IP, 0)
if err != nil {
return err
@ -186,6 +196,8 @@ func (luid LUID) Route(destination net.IPNet, nextHop net.IP) (*MibIPforwardRow2
row := &MibIPforwardRow2{}
row.Init()
row.InterfaceLUID = luid
row.ValidLifetime = 0xffffffff
row.PreferredLifetime = 0xffffffff
err := row.DestinationPrefix.SetIPNet(destination)
if err != nil {
return nil, err
@ -210,14 +222,19 @@ func (luid LUID) AddRoute(destination net.IPNet, nextHop net.IP, metric uint32)
row.InterfaceLUID = luid
err := row.DestinationPrefix.SetIPNet(destination)
if err != nil {
return err
return fmt.Errorf("AddRoute1: %w", err)
}
err = row.NextHop.SetIP(nextHop, 0)
if err != nil {
return err
return fmt.Errorf("AddRoute2: %w", err)
}
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.
@ -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.
func (luid LUID) SetRoutesForFamily(family AddressFamily, routesData []*RouteData) error {
err := luid.FlushRoutes(family)
if err != nil {
return err
}
//err := luid.FlushRoutes(family)
//if err != nil {
// return err
//}
_ = luid.FlushRoutes(family)
for _, rd := range routesData {
asV4 := rd.Destination.IP.To4()
if asV4 == nil && family == windows.AF_INET {
@ -288,7 +306,7 @@ func (luid LUID) FlushRoutes(family AddressFamily) error {
var tab *mibIPforwardTable2
err := getIPForwardTable2(family, &tab)
if err != nil {
return err
return fmt.Errorf("FlushRoutes1: %w", err)
}
t := tab.get()
for i := range t {
@ -300,7 +318,10 @@ func (luid LUID) FlushRoutes(family AddressFamily) error {
}
}
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.
@ -350,17 +371,17 @@ func (luid LUID) SetDNS(family AddressFamily, servers []net.IP, domains []string
if err != nil {
return err
}
var maybeV6 uint64
if family == windows.AF_INET6 {
maybeV6 = disFlagsIPv6
}
// For >= Windows 10 1809
err = setInterfaceDnsSettings(*guid, &dnsInterfaceSettings{
Version: disVersion1,
Flags: disFlagsNameServer | disFlagsSearchList | maybeV6,
dnsInterfaceSettings := &DnsInterfaceSettings{
Version: DnsInterfaceSettingsVersion1,
Flags: DnsInterfaceSettingsFlagNameserver | DnsInterfaceSettingsFlagSearchList,
NameServer: servers16,
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) {
return err
}

View file

@ -1,3 +1,11 @@
//go:build windows
// +build windows
/* SPDX-License-Identifier: MIT
*
* Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved.
*/
package winipcfg
//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zwinipcfg_windows.go winipcfg.go

View file

@ -1,5 +1,11 @@
//go:build windows
// +build windows
/* SPDX-License-Identifier: MIT
*
* Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved.
*/
package winipcfg
import (

View 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

View file

@ -1,5 +1,11 @@
//go:build windows
// +build windows
/* SPDX-License-Identifier: MIT
*
* Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved.
*/
package winipcfg
import (

View file

@ -1,8 +1,16 @@
//go:build windows
// +build windows
/* SPDX-License-Identifier: MIT
*
* Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved.
*/
package winipcfg
import (
"encoding/binary"
"fmt"
"net"
"unsafe"
@ -584,6 +592,10 @@ type RouteData struct {
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.
// https://docs.microsoft.com/en-us/windows/desktop/api/iptypes/ns-iptypes-_ip_adapter_dns_suffix
type IPAdapterDNSSuffix struct {
@ -731,6 +743,16 @@ type RawSockaddrInet struct {
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.
// All other members of the structure are set to zero.
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.Family = windows.AF_INET
copy(addr4.Addr[:], v4)
addr4.Port = port
addr4.Port = htons(port)
for i := 0; i < 8; i++ {
addr4.Zero[i] = 0
}
@ -748,7 +770,7 @@ func (addr *RawSockaddrInet) SetIP(ip net.IP, port uint16) error {
if v6 := ip.To16(); v6 != nil {
addr6 := (*windows.RawSockaddrInet6)(unsafe.Pointer(addr))
addr6.Family = windows.AF_INET6
addr6.Port = port
addr6.Port = htons(port)
addr6.Flowinfo = 0
copy(addr6.Addr[:], v6)
addr6.Scope_id = 0
@ -758,8 +780,7 @@ func (addr *RawSockaddrInet) SetIP(ip net.IP, port uint16) error {
return windows.ERROR_INVALID_PARAMETER
}
// IP method returns IPv4 or IPv6 address.
// If the address is neither IPv4 not IPv6 nil is returned.
// IP returns IPv4 or IPv6 address, or nil if the address is neither.
func (addr *RawSockaddrInet) IP() net.IP {
switch addr.Family {
case windows.AF_INET:
@ -772,6 +793,19 @@ func (addr *RawSockaddrInet) IP() net.IP {
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.
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/nf-netioapi-initializeunicastipaddressentry
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
type dnsInterfaceSettings struct {
// DnsInterfaceSettings is meant to be used with SetInterfaceDnsSettings
type DnsInterfaceSettings struct {
Version uint32
_ [4]byte
Flags uint64
@ -957,21 +991,24 @@ type dnsInterfaceSettings struct {
}
const (
disVersion1 = 1
disVersion2 = 2
DnsInterfaceSettingsVersion1 = 1 // for DnsInterfaceSettings
DnsInterfaceSettingsVersion2 = 2 // for DnsInterfaceSettingsEx
DnsInterfaceSettingsVersion3 = 3 // for DnsInterfaceSettings3
disFlagsIPv6 = 0x1
disFlagsNameServer = 0x2
disFlagsSearchList = 0x4
disFlagsRegistrationEnabled = 0x8
disFlagsRegisterAdapterName = 0x10
disFlagsDomain = 0x20
disFlagsHostname = 0x40 // ??
disFlagsEnableLLMNR = 0x80
disFlagsQueryAdapterName = 0x100
disFlagsProfileNameServer = 0x200
disFlagsVersion2 = 0x400 // ?? - v2 only
disFlagsMoreFlags = 0x800 // ?? - v2 only
DnsInterfaceSettingsFlagIPv6 = 0x0001
DnsInterfaceSettingsFlagNameserver = 0x0002
DnsInterfaceSettingsFlagSearchList = 0x0004
DnsInterfaceSettingsFlagRegistrationEnabled = 0x0008
DnsInterfaceSettingsFlagRegisterAdapterName = 0x0010
DnsInterfaceSettingsFlagDomain = 0x0020
DnsInterfaceSettingsFlagHostname = 0x0040
DnsInterfaceSettingsFlagEnableLLMNR = 0x0080
DnsInterfaceSettingsFlagQueryAdapterName = 0x0100
DnsInterfaceSettingsFlagProfileNameserver = 0x0200
DnsInterfaceSettingsFlagDisableUnconstrainedQueries = 0x0400 // v2 only
DnsInterfaceSettingsFlagSupplementalSearchList = 0x0800 // v2 only
DnsInterfaceSettingsFlagDOH = 0x1000 // v3 only
DnsInterfaceSettingsFlagDOHProfile = 0x2000 // v3 only
)
// unsafeSlice updates the slice slicePtr to be a slice

View file

@ -1,5 +1,12 @@
//go:build windows && (386 || arm)
// +build windows
// +build 386 arm
/* SPDX-License-Identifier: MIT
*
* Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved.
*/
package winipcfg
import (

View file

@ -1,6 +1,12 @@
//go:build windows && (amd64 || arm64)
// +build windows
// +build amd64 arm64
/* SPDX-License-Identifier: MIT
*
* Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved.
*/
package winipcfg
import (

View file

@ -1,5 +1,11 @@
//go:build windows
// +build windows
/* SPDX-License-Identifier: MIT
*
* Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved.
*/
package winipcfg
import (

View file

@ -1,5 +1,11 @@
//go:build windows
// +build windows
/* SPDX-License-Identifier: MIT
*
* Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved.
*/
package winipcfg
import (
@ -167,18 +173,18 @@ func GetIPForwardTable2(family AddressFamily) ([]MibIPforwardRow2, error) {
//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 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 setInterfaceDnsSettingsByPtr(guid *windows.GUID, 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?
// The GUID is passed by value, not by reference, which means different
// things on different calling conventions. On amd64, this means it's
// passed by reference anyway, while on arm, arm64, and 386, it's split
// into words.
func setInterfaceDnsSettings(guid windows.GUID, settings *dnsInterfaceSettings) error {
func SetInterfaceDnsSettings(guid windows.GUID, settings *DnsInterfaceSettings) error {
words := (*[4]uintptr)(unsafe.Pointer(&guid))
switch runtime.GOARCH {
case "amd64":

View file

@ -289,7 +289,7 @@ func notifyUnicastIPAddressChange(family AddressFamily, callback uintptr, caller
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()
if ret != nil {
return
@ -301,24 +301,24 @@ func setInterfaceDnsSettingsByDwords(guid1 uintptr, guid2 uintptr, guid3 uintptr
return
}
func setInterfaceDnsSettingsByPtr(guid *windows.GUID, settings *dnsInterfaceSettings) (ret error) {
func setInterfaceDnsSettingsByQwords(guid1 uintptr, guid2 uintptr, settings *DnsInterfaceSettings) (ret error) {
ret = procSetInterfaceDnsSettings.Find()
if ret != nil {
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 {
ret = syscall.Errno(r0)
}
return
}
func setInterfaceDnsSettingsByQwords(guid1 uintptr, guid2 uintptr, settings *dnsInterfaceSettings) (ret error) {
func setInterfaceDnsSettingsByPtr(guid *windows.GUID, settings *DnsInterfaceSettings) (ret error) {
ret = procSetInterfaceDnsSettings.Find()
if ret != nil {
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 {
ret = syscall.Errno(r0)
}

View file

@ -1,3 +1,4 @@
//go:build !load_wintun_from_rsrc
// +build !load_wintun_from_rsrc
package wintun
@ -8,6 +9,7 @@ import (
"sync/atomic"
"unsafe"
C "github.com/Dreamacro/clash/constant"
"golang.org/x/sys/windows"
)
@ -28,11 +30,12 @@ func (d *lazyDLL) Load() error {
return nil
}
const (
LOAD_LIBRARY_SEARCH_APPLICATION_DIR = 0x00000200
LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800
)
module, err := windows.LoadLibraryEx(d.Name, 0, LOAD_LIBRARY_SEARCH_APPLICATION_DIR|LOAD_LIBRARY_SEARCH_SYSTEM32)
//const (
// LOAD_LIBRARY_SEARCH_APPLICATION_DIR = 0x00000200
// 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(C.Path.GetAssetLocation(d.Name), 0, windows.LOAD_WITH_ALTERED_SEARCH_PATH)
if err != nil {
return fmt.Errorf("Unable to load library: %w", err)
}

View file

@ -1,3 +1,4 @@
//go:build load_wintun_from_rsrc
// +build load_wintun_from_rsrc
package wintun

View file

@ -41,12 +41,12 @@ func (module *Module) headerDirectory(idx int) *IMAGE_DATA_DIRECTORY {
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()
for i := range sections {
if sections[i].SizeOfRawData == 0 {
// 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 {
continue
}
@ -159,6 +159,16 @@ func (module *Module) finalizeSection(sectionData *sectionFinalizeData) error {
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 {
sections := module.headers.Sections()
imageOffset := module.headers.OptionalHeader.imageOffset()
@ -166,6 +176,7 @@ func (module *Module) finalizeSections() error {
sectionData.address = uintptr(sections[0].PhysicalAddress()) | imageOffset
sectionData.alignedAddress = alignDown(sectionData.address, uintptr(module.headers.OptionalHeader.SectionAlignment))
sectionData.size = module.realSectionSize(&sections[0])
sections[0].SetVirtualSize(uint32(sectionData.size))
sectionData.characteristics = sections[0].Characteristics
// Loop through all sections and change access flags.
@ -173,6 +184,7 @@ func (module *Module) finalizeSections() error {
sectionAddress := uintptr(sections[i].PhysicalAddress()) | imageOffset
alignedAddress := alignDown(sectionAddress, uintptr(module.headers.OptionalHeader.SectionAlignment))
sectionSize := module.realSectionSize(&sections[i])
sections[i].SetVirtualSize(uint32(sectionSize))
// 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.
if sectionData.alignedAddress == alignedAddress || sectionData.address+sectionData.size > alignedAddress {
@ -498,6 +510,9 @@ func LoadLibrary(data []byte) (module *Module, err error) {
return
}
// Register exception tables, if they exist.
module.registerExceptionHandlers()
// TLS callbacks are executed BEFORE the main loading.
module.executeTLS()

View file

@ -1,4 +1,6 @@
// +build windows,386 windows,arm
//go:build windows && (386 || arm)
// +build windows
// +build 386 arm
/* SPDX-License-Identifier: MIT
*

View file

@ -1,4 +1,6 @@
// +build windows,amd64 windows,arm64
//go:build windows && (amd64 || arm64)
// +build windows
// +build amd64 arm64
/* SPDX-License-Identifier: MIT
*

View file

@ -174,6 +174,21 @@ func (ishdr *IMAGE_SECTION_HEADER) SetVirtualSize(addr uint32) {
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 (
// Section characteristics.
IMAGE_SCN_TYPE_REG = 0x00000000 // Reserved.
@ -317,6 +332,50 @@ func (imgimpdesc *IMAGE_IMPORT_DESCRIPTOR) OriginalFirstThunk() uint32 {
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 (
DLL_PROCESS_ATTACH = 1
DLL_THREAD_ATTACH = 2

View file

@ -1,4 +1,6 @@
// +build windows,386 windows,arm
//go:build windows && (386 || arm)
// +build windows
// +build 386 arm
/* SPDX-License-Identifier: MIT
*
@ -43,3 +45,54 @@ type IMAGE_OPTIONAL_HEADER struct {
}
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
}

View file

@ -1,4 +1,6 @@
// +build windows,amd64 windows,arm64
//go:build windows && (amd64 || arm64)
// +build windows
// +build amd64 arm64
/* SPDX-License-Identifier: MIT
*
@ -42,3 +44,54 @@ type IMAGE_OPTIONAL_HEADER struct {
}
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
}

View 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

View file

@ -0,0 +1,4 @@
// Modified from: https://github.com/v2fly/v2ray-core/tree/master/infra/conf/geodata
// License: MIT
package geodata

View file

@ -0,0 +1,4 @@
// Modified from: https://github.com/v2fly/v2ray-core/tree/master/common/strmatcher
// License: MIT
package strmatcher