Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
arm64v8a committed Aug 5, 2022
1 parent bea441f commit 17ca8ab
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 41 deletions.
23 changes: 23 additions & 0 deletions go/iphlpapi/callback_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package iphlpapi

import (
"syscall"
"unsafe"
)

func notifyRouteChange2(family uint16, callback uintptr, callerContext uintptr, initialNotification bool, notificationHandle *syscall.Handle) (ret error) {
var _p0 uint32
if initialNotification {
_p0 = 1
}
r0, _, _ := syscall.Syscall6(proc_notifyRouteChange2.Addr(), 5, uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle)), 0)
if r0 != 0 {
ret = syscall.Errno(r0)
}
return
}

func RegisterNotifyRouteChange2(callback func(callerContext uintptr, row uintptr, notificationType uint32) uintptr, initialNotification bool) (handle syscall.Handle) {
notifyRouteChange2(syscall.AF_UNSPEC, syscall.NewCallback(callback), 0, initialNotification, &handle)
return
}
14 changes: 14 additions & 0 deletions go/iphlpapi/dll_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package iphlpapi

import "syscall"

var (
proc_getIpForwardTable *syscall.LazyProc
proc_notifyRouteChange2 *syscall.LazyProc
)

func init() {
iphlpapi := syscall.NewLazyDLL("iphlpapi.dll")
proc_getIpForwardTable = iphlpapi.NewProc("GetIpForwardTable")
proc_notifyRouteChange2 = iphlpapi.NewProc("NotifyRouteChange2")
}
30 changes: 4 additions & 26 deletions go/toolbox_route_windows.go → go/iphlpapi/route_windows.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package main
package iphlpapi

import (
"fmt"
"net"
"syscall"
"unsafe"
)

Expand All @@ -21,13 +20,6 @@ import (
// 太低的值添加路由时会返回 106 错误
const routeMetric = 93

type routeTable struct {
iphlpapi *syscall.LazyDLL
getIpForwardTable *syscall.LazyProc
createIpForwardEntry *syscall.LazyProc
deleteIpForwardEntry *syscall.LazyProc
}

type RouteRow struct {
ForwardDest [4]byte //目标网络
ForwardMask [4]byte //掩码
Expand Down Expand Up @@ -55,31 +47,17 @@ func (rr *RouteRow) GetForwardNextHop() net.IP {
return net.IP(rr.ForwardNextHop[:])
}

func NewRouteTable() *routeTable {
iphlpapi := syscall.NewLazyDLL("iphlpapi.dll")
getIpForwardTable := iphlpapi.NewProc("GetIpForwardTable")
createIpForwardEntry := iphlpapi.NewProc("CreateIpForwardEntry")
deleteIpForwardEntry := iphlpapi.NewProc("DeleteIpForwardEntry")

return &routeTable{
iphlpapi: iphlpapi,
getIpForwardTable: getIpForwardTable,
createIpForwardEntry: createIpForwardEntry,
deleteIpForwardEntry: deleteIpForwardEntry,
}
}

func (rt *routeTable) getRoutes() ([]RouteRow, error) {
func GetRoutes() ([]RouteRow, error) {
buf := make([]byte, 4+unsafe.Sizeof(RouteRow{}))
buf_len := uint32(len(buf))

rt.getIpForwardTable.Call(uintptr(unsafe.Pointer(&buf[0])),
proc_getIpForwardTable.Call(uintptr(unsafe.Pointer(&buf[0])),
uintptr(unsafe.Pointer(&buf_len)), 0)

var r1 uintptr
for i := 0; i < 5; i++ {
buf = make([]byte, buf_len)
r1, _, _ = rt.getIpForwardTable.Call(uintptr(unsafe.Pointer(&buf[0])),
r1, _, _ = proc_getIpForwardTable.Call(uintptr(unsafe.Pointer(&buf[0])),
uintptr(unsafe.Pointer(&buf_len)), 0)
if r1 == 122 {
continue
Expand Down
75 changes: 66 additions & 9 deletions go/protect_bindinterface_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,21 @@ package main
import (
"encoding/binary"
"log"
"nekoray_core/iphlpapi"
"net"
"strings"
"sync"
"syscall"
"unsafe"

"github.com/v2fly/v2ray-core/v5/transport/internet"
"golang.org/x/sys/windows"
)

// https://docs.microsoft.com/en-us/windows/win32/api/ipmib/ns-ipmib-mib_ipforwardrow
var routes []iphlpapi.RouteRow
var interfaces []net.Interface
var lock sync.Mutex

func init() {
internet.RegisterListenerController(func(network, address string, fd uintptr) error {
bindInterfaceIndex := getBindInterfaceIndex()
Expand Down Expand Up @@ -40,19 +47,69 @@ func init() {
}
return nil
})
iphlpapi.RegisterNotifyRouteChange2(func(callerContext uintptr, row uintptr, notificationType uint32) uintptr {
updateRoutes()
return 0
}, true)
}

func getBindInterfaceIndex() uint32 {
intfs, err := net.Interfaces()
func updateRoutes() {
lock.Lock()
defer lock.Unlock()

var err error
routes, err = iphlpapi.GetRoutes()
if err != nil {
log.Println("warning: GetRoutes failed", err)
}
interfaces, err = net.Interfaces()
if err != nil {
log.Println("warning: Interfaces failed", err)
}
}

func getBindInterfaceIndex() uint32 {
lock.Lock()
defer lock.Unlock()

if routes == nil {
log.Println("warning: no routes info")
return 0
}
if len(intfs) > 1 {
if intfs[0].Name == "nekoray-tun" || intfs[0].Name == "wintun" || intfs[0].Name == "TunMax" {
return uint32(intfs[1].Index)
if interfaces == nil {
log.Println("warning: no interfaces info")
return 0
}

var nextInterface int
for i, intf := range interfaces {
if intf.Name == "nekoray-tun" || intf.Name == "wintun" || intf.Name == "TunMax" {
if len(interfaces) > i+1 {
nextInterface = interfaces[i+1].Index
}
break
}
}
return 0

// Not in VPN mode
if nextInterface == 0 {
return 0
}

for _, route := range routes {
// MIB_IPROUTE_TYPE_INDIRECT
if route.ForwardType == 4 {
// MIB_IPPROTO_NETMGMT
if route.ForwardProto == 3 {
if route.GetForwardMask().IsUnspecified() {
return route.ForwardIfIndex
}
}
}
}

// Default route not found
return uint32(nextInterface)
}

const (
Expand All @@ -67,13 +124,13 @@ func bindInterface(fd uintptr, interfaceIndex uint32, v4, v6 bool) error {
binary.BigEndian.PutUint32(bytes, interfaceIndex)
interfaceIndex_v4 := *(*uint32)(unsafe.Pointer(&bytes[0]))

if err := windows.SetsockoptInt(windows.Handle(fd), windows.IPPROTO_IP, IP_UNICAST_IF, int(interfaceIndex_v4)); err != nil {
if err := syscall.SetsockoptInt(syscall.Handle(fd), syscall.IPPROTO_IP, IP_UNICAST_IF, int(interfaceIndex_v4)); err != nil {
return err
}
}

if v6 {
if err := windows.SetsockoptInt(windows.Handle(fd), windows.IPPROTO_IPV6, IPV6_UNICAST_IF, int(interfaceIndex)); err != nil {
if err := syscall.SetsockoptInt(syscall.Handle(fd), syscall.IPPROTO_IPV6, IPV6_UNICAST_IF, int(interfaceIndex)); err != nil {
return err
}
}
Expand Down
4 changes: 0 additions & 4 deletions go/toolbox_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ func ToolBox() {
for _, intf := range intfs {
log.Println(intf)
}
routes, err := NewRouteTable().getRoutes()
if err != nil {
log.Fatalln(err)
}
for _, route := range routes {
log.Println(route)
}
Expand Down
2 changes: 1 addition & 1 deletion main/NekoRay_DataStore.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ namespace NekoRay {
bool fake_dns = false;
QString domain_strategy = "AsIs";
QString outbound_domain_strategy = "AsIs";
int sniffing_mode = SniffingMode::DISABLE;
int sniffing_mode = SniffingMode::FOR_ROUTING;
int domain_matcher = DomainMatcher::MPH;
QString custom_route_global = "{\"rules\": []}";
QString active_routing = "Default";
Expand Down
2 changes: 1 addition & 1 deletion matsuri_commit.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
9f3c3fc5a7240af2fad813fc952adf38b8b45295
3dd90ce8b7dcb7001f3de42f6bcc8edf0093353a

0 comments on commit 17ca8ab

Please sign in to comment.