mirror of
https://github.com/v2rayA/v2rayA.git
synced 2026-10-28 12:56:51 +08:00
On Linux the module's upstream, bootstrap and health-check sockets carry SO_MARK 0x80, which the transparent-proxy rules exempt. Windows and macOS have no mark: once a TUN holds the default route, those sockets would send the module's own queries into the TUN, where the core's port-53 interception hands them straight back to the module. The module config gains egress_interface; when set, every dialer created by newMarkedDnsClient binds to it with IP_UNICAST_IF / IPV6_UNICAST_IF on Windows and IP_BOUND_IF / IPV6_BOUND_IF on macOS. Unset, the dialers are unchanged, and Linux keeps the mark. The darwin and windows tests dial through the dialer and read the option back; they run on those platforms. The interface lookup itself is tested everywhere.
55 lines
1.3 KiB
Go
55 lines
1.3 KiB
Go
//go:build windows
|
|
|
|
package dns
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"net"
|
|
"syscall"
|
|
"testing"
|
|
"unsafe"
|
|
|
|
"golang.org/x/sys/windows"
|
|
)
|
|
|
|
// The dialer's sockets must carry IP_UNICAST_IF for the configured
|
|
// interface and nothing when none is configured.
|
|
func TestMarkedDialerBindsEgressInterface(t *testing.T) {
|
|
t.Cleanup(func() { SetEgressInterface("") })
|
|
pc, err := net.ListenPacket("udp4", "127.0.0.1:0")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer pc.Close()
|
|
|
|
boundIf := func() int {
|
|
conn, err := markedDialer().Dial("udp4", pc.LocalAddr().String())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer conn.Close()
|
|
raw, err := conn.(*net.UDPConn).SyscallConn()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// The option is set in network byte order, but getsockopt hands
|
|
// the index back in host order.
|
|
var buf [4]byte
|
|
raw.Control(func(fd uintptr) {
|
|
n := int32(len(buf))
|
|
_ = windows.Getsockopt(windows.Handle(fd), syscall.IPPROTO_IP, ipUnicastIf, (*byte)(unsafe.Pointer(&buf[0])), &n)
|
|
})
|
|
return int(binary.LittleEndian.Uint32(buf[:]))
|
|
}
|
|
|
|
SetEgressInterface("")
|
|
if idx := boundIf(); idx != 0 {
|
|
t.Fatalf("unconfigured dialer bound to interface %d", idx)
|
|
}
|
|
lo := loopbackInterface(t)
|
|
SetEgressInterface(lo.Name)
|
|
if idx := boundIf(); idx != lo.Index {
|
|
t.Fatalf("bound to %d, want %d", idx, lo.Index)
|
|
}
|
|
}
|