feat: support sending ping requests via direct in tun mode

This commit is contained in:
wwqgtxx
2025-08-27 18:00:25 +08:00
parent 84086a6e6c
commit 0ced98da4d
6 changed files with 79 additions and 15 deletions

View File

@@ -21,10 +21,10 @@ func bindControl(ifaceIdx int) controlFn {
var innerErr error
err = c.Control(func(fd uintptr) {
switch network {
case "tcp4", "udp4":
innerErr = unix.SetsockoptInt(int(fd), unix.IPPROTO_IP, unix.IP_BOUND_IF, ifaceIdx)
case "tcp6", "udp6":
case "tcp6", "udp6", "ip6":
innerErr = unix.SetsockoptInt(int(fd), unix.IPPROTO_IPV6, unix.IPV6_BOUND_IF, ifaceIdx)
default:
innerErr = unix.SetsockoptInt(int(fd), unix.IPPROTO_IP, unix.IP_BOUND_IF, ifaceIdx)
}
})

View File

@@ -9,6 +9,7 @@ import (
"os"
"strings"
"sync"
"syscall"
"time"
"github.com/metacubex/mihomo/component/keepalive"
@@ -177,6 +178,34 @@ func dialContext(ctx context.Context, network string, destination netip.Addr, po
return dialer.DialContext(ctx, network, address)
}
func ICMPControl(destination netip.Addr) func(network, address string, conn syscall.RawConn) error {
return func(network, address string, conn syscall.RawConn) error {
if DefaultSocketHook != nil {
return DefaultSocketHook(network, address, conn)
}
dialer := &net.Dialer{}
interfaceName := DefaultInterface.Load()
if interfaceName == "" {
if finder := DefaultInterfaceFinder.Load(); finder != nil {
interfaceName = finder.FindInterfaceName(destination)
}
}
if interfaceName != "" {
if err := bindIfaceToDialer(interfaceName, dialer, network, destination); err != nil {
return err
}
}
routingMark := int(DefaultRoutingMark.Load())
if routingMark != 0 {
bindMarkToDialer(routingMark, dialer, network, destination)
}
if dialer.ControlContext != nil {
return dialer.ControlContext(context.TODO(), network, address, conn)
}
return nil
}
}
func serialSingleStackDialContext(ctx context.Context, network string, ips []netip.Addr, port string, opt option) (net.Conn, error) {
return serialDialContext(ctx, network, ips, port, opt)
}