sing-tun-lx/ping/socket_windows.go

43 lines
1.3 KiB
Go

package ping
import (
"context"
"net"
"net/netip"
"syscall"
"github.com/sagernet/sing/common/bufio"
"github.com/sagernet/sing/common/control"
M "github.com/sagernet/sing/common/metadata"
"golang.org/x/sys/windows"
)
func connect(privileged bool, controlFunc control.Func, destination netip.Addr) (net.Conn, error) {
var listenConfig net.ListenConfig
listenConfig.Control = controlFunc
if destination.Is6() {
listenConfig.Control = control.Append(listenConfig.Control, func(network, address string, conn syscall.RawConn) error {
return control.Raw(conn, func(fd uintptr) error {
err := windows.SetsockoptInt(windows.Handle(fd), windows.IPPROTO_IPV6, IPV6_HOPLIMIT, 1)
if err != nil {
return err
}
return windows.SetsockoptInt(windows.Handle(fd), windows.IPPROTO_IPV6, IPV6_RECVTCLASS, 1)
})
})
}
var network string
if destination.Is4() {
network = "ip4:icmp"
} else {
network = "ip6:ipv6-icmp"
}
// A connected raw socket only receives messages from the connected peer, so transit routers'
// Time Exceeded replies needed by traceroute never arrive.
packetConn, err := listenConfig.ListenPacket(context.Background(), network, "")
if err != nil {
return nil, err
}
return bufio.NewBindPacketConn(packetConn, M.SocksaddrFrom(destination, 0).IPAddr()), nil
}