Skip to content

Commit 0ced98d

Browse files
committed
feat: support sending ping requests via direct in tun mode
1 parent 84086a6 commit 0ced98d

File tree

6 files changed

+79
-15
lines changed

6 files changed

+79
-15
lines changed

component/dialer/bind_darwin.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ func bindControl(ifaceIdx int) controlFn {
2121
var innerErr error
2222
err = c.Control(func(fd uintptr) {
2323
switch network {
24-
case "tcp4", "udp4":
25-
innerErr = unix.SetsockoptInt(int(fd), unix.IPPROTO_IP, unix.IP_BOUND_IF, ifaceIdx)
26-
case "tcp6", "udp6":
24+
case "tcp6", "udp6", "ip6":
2725
innerErr = unix.SetsockoptInt(int(fd), unix.IPPROTO_IPV6, unix.IPV6_BOUND_IF, ifaceIdx)
26+
default:
27+
innerErr = unix.SetsockoptInt(int(fd), unix.IPPROTO_IP, unix.IP_BOUND_IF, ifaceIdx)
2828
}
2929
})
3030

component/dialer/dialer.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"os"
1010
"strings"
1111
"sync"
12+
"syscall"
1213
"time"
1314

1415
"github.com/metacubex/mihomo/component/keepalive"
@@ -177,6 +178,34 @@ func dialContext(ctx context.Context, network string, destination netip.Addr, po
177178
return dialer.DialContext(ctx, network, address)
178179
}
179180

181+
func ICMPControl(destination netip.Addr) func(network, address string, conn syscall.RawConn) error {
182+
return func(network, address string, conn syscall.RawConn) error {
183+
if DefaultSocketHook != nil {
184+
return DefaultSocketHook(network, address, conn)
185+
}
186+
dialer := &net.Dialer{}
187+
interfaceName := DefaultInterface.Load()
188+
if interfaceName == "" {
189+
if finder := DefaultInterfaceFinder.Load(); finder != nil {
190+
interfaceName = finder.FindInterfaceName(destination)
191+
}
192+
}
193+
if interfaceName != "" {
194+
if err := bindIfaceToDialer(interfaceName, dialer, network, destination); err != nil {
195+
return err
196+
}
197+
}
198+
routingMark := int(DefaultRoutingMark.Load())
199+
if routingMark != 0 {
200+
bindMarkToDialer(routingMark, dialer, network, destination)
201+
}
202+
if dialer.ControlContext != nil {
203+
return dialer.ControlContext(context.TODO(), network, address, conn)
204+
}
205+
return nil
206+
}
207+
}
208+
180209
func serialSingleStackDialContext(ctx context.Context, network string, ips []netip.Addr, port string, opt option) (net.Conn, error) {
181210
return serialDialContext(ctx, network, ips, port, opt)
182211
}

go.mod

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ require (
2424
github.com/metacubex/quic-go v0.54.1-0.20250730114134-a1ae705fe295
2525
github.com/metacubex/randv2 v0.2.0
2626
github.com/metacubex/restls-client-go v0.1.7
27-
github.com/metacubex/sing v0.5.5
27+
github.com/metacubex/sing v0.5.6-0.20250826072929-f69b475e017b
2828
github.com/metacubex/sing-mux v0.3.3-0.20250813083925-d7c9aeaeeaac
2929
github.com/metacubex/sing-quic v0.0.0-20250718154553-1b193bec4cbb
3030
github.com/metacubex/sing-shadowsocks v0.2.12
3131
github.com/metacubex/sing-shadowsocks2 v0.2.6
3232
github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2
33-
github.com/metacubex/sing-tun v0.4.7
33+
github.com/metacubex/sing-tun v0.4.8-0.20250827085914-fc5681b9fc9f
3434
github.com/metacubex/sing-vmess v0.2.4-0.20250822020810-4856053566f0
3535
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f
3636
github.com/metacubex/smux v0.0.0-20250503055512-501391591dee
@@ -89,7 +89,7 @@ require (
8989
github.com/mailru/easyjson v0.7.7 // indirect
9090
github.com/mdlayher/socket v0.4.1 // indirect
9191
github.com/metacubex/ascon v0.1.0 // indirect
92-
github.com/metacubex/gvisor v0.0.0-20250324165734-5857f47bd43b // indirect
92+
github.com/metacubex/gvisor v0.0.0-20250826025146-23043f716a2c // indirect
9393
github.com/metacubex/nftables v0.0.0-20250503052935-30a69ab87793 // indirect
9494
github.com/oasisprotocol/deoxysii v0.0.0-20220228165953-2091330c22b7 // indirect
9595
github.com/onsi/ginkgo/v2 v2.9.5 // indirect

go.sum

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ github.com/metacubex/fswatch v0.1.1 h1:jqU7C/v+g0qc2RUFgmAOPoVvfl2BXXUXEumn6oQux
106106
github.com/metacubex/fswatch v0.1.1/go.mod h1:czrTT7Zlbz7vWft8RQu9Qqh+JoX+Nnb+UabuyN1YsgI=
107107
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 h1:cjd4biTvOzK9ubNCCkQ+ldc4YSH/rILn53l/xGBFHHI=
108108
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759/go.mod h1:UHOv2xu+RIgLwpXca7TLrXleEd4oR3sPatW6IF8wU88=
109-
github.com/metacubex/gvisor v0.0.0-20250324165734-5857f47bd43b h1:RUh4OdVPz/jDrM9MQ2ySuqu2aeBqcA8rtfWUYLZ8RtI=
110-
github.com/metacubex/gvisor v0.0.0-20250324165734-5857f47bd43b/go.mod h1:8LpS0IJW1VmWzUm3ylb0e2SK5QDm5lO/2qwWLZgRpBU=
109+
github.com/metacubex/gvisor v0.0.0-20250826025146-23043f716a2c h1:N9m7IAKfBuGDieY/JT2wjfdyURgTNpFNOFpqq+RF0i4=
110+
github.com/metacubex/gvisor v0.0.0-20250826025146-23043f716a2c/go.mod h1:8LpS0IJW1VmWzUm3ylb0e2SK5QDm5lO/2qwWLZgRpBU=
111111
github.com/metacubex/nftables v0.0.0-20250503052935-30a69ab87793 h1:1Qpuy+sU3DmyX9HwI+CrBT/oLNJngvBorR2RbajJcqo=
112112
github.com/metacubex/nftables v0.0.0-20250503052935-30a69ab87793/go.mod h1:RjRNb4G52yAgfR+Oe/kp9G4PJJ97Fnj89eY1BFO3YyA=
113113
github.com/metacubex/quic-go v0.54.1-0.20250730114134-a1ae705fe295 h1:8JVlYuE8uSJAvmyCd4TjvDxs57xjb0WxEoaWafK5+qs=
@@ -117,8 +117,8 @@ github.com/metacubex/randv2 v0.2.0/go.mod h1:kFi2SzrQ5WuneuoLLCMkABtiBu6VRrMrWFq
117117
github.com/metacubex/restls-client-go v0.1.7 h1:eCwiXCTQb5WJu9IlgYvDBA1OgrINv58dEe7hcN5H15k=
118118
github.com/metacubex/restls-client-go v0.1.7/go.mod h1:BN/U52vPw7j8VTSh2vleD/MnmVKCov84mS5VcjVHH4g=
119119
github.com/metacubex/sing v0.5.2/go.mod h1:ypf0mjwlZm0sKdQSY+yQvmsbWa0hNPtkeqyRMGgoN+w=
120-
github.com/metacubex/sing v0.5.5 h1:m5U8iHvRAUxlme3FZlE/LPIGHjU8oMCUzXWGbQQAC1E=
121-
github.com/metacubex/sing v0.5.5/go.mod h1:ypf0mjwlZm0sKdQSY+yQvmsbWa0hNPtkeqyRMGgoN+w=
120+
github.com/metacubex/sing v0.5.6-0.20250826072929-f69b475e017b h1:ukK1IMo7LJ+VmPWQPIdoslHBv4Tr3E2zE34ilQCH2i4=
121+
github.com/metacubex/sing v0.5.6-0.20250826072929-f69b475e017b/go.mod h1:ypf0mjwlZm0sKdQSY+yQvmsbWa0hNPtkeqyRMGgoN+w=
122122
github.com/metacubex/sing-mux v0.3.3-0.20250813083925-d7c9aeaeeaac h1:wDH/Jh/yqWbzPktqJP+Y1cUG8hchcrzKzUxJiSpnaQs=
123123
github.com/metacubex/sing-mux v0.3.3-0.20250813083925-d7c9aeaeeaac/go.mod h1:3rt1soewn0O6j89GCLmwAQFsq257u0jf2zQSPhTL3Bw=
124124
github.com/metacubex/sing-quic v0.0.0-20250718154553-1b193bec4cbb h1:U/m3h8lp/j7i8zFgfvScLdZa1/Y8dd74oO7iZaQq80s=
@@ -129,8 +129,8 @@ github.com/metacubex/sing-shadowsocks2 v0.2.6 h1:ZR1kYT0f0Vi64iQSS09OdhFfppiNkh7
129129
github.com/metacubex/sing-shadowsocks2 v0.2.6/go.mod h1:vOEbfKC60txi0ca+yUlqEwOGc3Obl6cnSgx9Gf45KjE=
130130
github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2 h1:gXU+MYPm7Wme3/OAY2FFzVq9d9GxPHOqu5AQfg/ddhI=
131131
github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2/go.mod h1:mbfboaXauKJNIHJYxQRa+NJs4JU9NZfkA+I33dS2+9E=
132-
github.com/metacubex/sing-tun v0.4.7 h1:ZDY/W+1c7PeWWKeKRyUo18fySF/TWjB0i5ui81Ar778=
133-
github.com/metacubex/sing-tun v0.4.7/go.mod h1:xHecZRwBnKWe6zG9amAK9cXf91lF6blgjBqm+VvOrmU=
132+
github.com/metacubex/sing-tun v0.4.8-0.20250827085914-fc5681b9fc9f h1:1MV/pFn2vjnyvH/0u6sJST0kmaoZXgbUytCCfuelhl8=
133+
github.com/metacubex/sing-tun v0.4.8-0.20250827085914-fc5681b9fc9f/go.mod h1:FQ9zXA+kVhdzqgFqeJdi/AUhJgUgw+SUXqrR++GvbnM=
134134
github.com/metacubex/sing-vmess v0.2.4-0.20250822020810-4856053566f0 h1:WZepq4TOZa6WewB8tGAZrrL+bL2R2ivoBzuEgAeolWc=
135135
github.com/metacubex/sing-vmess v0.2.4-0.20250822020810-4856053566f0/go.mod h1:21R5R1u90uUvBQF0owoooEu96/SAYYD56nDrwm6nFaM=
136136
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f h1:Sr/DYKYofKHKc4GF3qkRGNuj6XA6c0eqPgEDN+VAsYU=

listener/sing_tun/prepare.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package sing_tun
2+
3+
import (
4+
"context"
5+
"time"
6+
7+
"github.com/metacubex/mihomo/component/dialer"
8+
"github.com/metacubex/mihomo/component/resolver"
9+
"github.com/metacubex/mihomo/log"
10+
11+
tun "github.com/metacubex/sing-tun"
12+
"github.com/metacubex/sing-tun/ping"
13+
M "github.com/metacubex/sing/common/metadata"
14+
N "github.com/metacubex/sing/common/network"
15+
)
16+
17+
func (h *ListenerHandler) PrepareConnection(network string, source M.Socksaddr, destination M.Socksaddr, routeContext tun.DirectRouteContext, timeout time.Duration) (tun.DirectRouteDestination, error) {
18+
switch network {
19+
case N.NetworkICMP: // our fork only send those type to PrepareConnection now
20+
if resolver.IsFakeIP(destination.Addr) { // skip fakeip
21+
log.Infoln("[ICMP] %s %s --> %s using fake ping echo", network, source, destination)
22+
return nil, nil
23+
}
24+
log.Infoln("[ICMP] %s %s --> %s using DIRECT", network, source, destination)
25+
directRouteDestination, err := ping.ConnectDestination(context.TODO(), log.SingLogger, dialer.ICMPControl(destination.Addr), destination.Addr, routeContext, timeout)
26+
if err != nil {
27+
log.Warnln("[ICMP] failed to connect to %s", destination)
28+
return nil, err
29+
}
30+
log.Debugln("[ICMP] success connect to %s", destination)
31+
return directRouteDestination, nil
32+
}
33+
return nil, nil
34+
}

listener/sing_tun/server.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"strconv"
1212
"strings"
1313
"sync"
14+
"time"
1415

1516
"github.com/metacubex/mihomo/adapter/inbound"
1617
"github.com/metacubex/mihomo/component/dialer"
@@ -174,11 +175,11 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis
174175
if tunMTU == 0 {
175176
tunMTU = 9000
176177
}
177-
var udpTimeout int64
178+
var udpTimeout time.Duration
178179
if options.UDPTimeout != 0 {
179-
udpTimeout = options.UDPTimeout
180+
udpTimeout = time.Second * time.Duration(options.UDPTimeout)
180181
} else {
181-
udpTimeout = int64(sing.UDPTimeout.Seconds())
182+
udpTimeout = sing.UDPTimeout
182183
}
183184
tableIndex := options.IPRoute2TableIndex
184185
if tableIndex == 0 {

0 commit comments

Comments
 (0)