Update On Mon Aug 25 20:39:18 CEST 2025

This commit is contained in:
github-action[bot]
2025-08-25 20:39:19 +02:00
parent 6abcc2677d
commit 0c4b81ed2f
106 changed files with 850 additions and 630 deletions

View File

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

View File

@@ -9,7 +9,6 @@ import (
"os"
"strings"
"sync"
"syscall"
"time"
"github.com/metacubex/mihomo/component/keepalive"
@@ -178,34 +177,6 @@ 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)
}

View File

@@ -24,13 +24,13 @@ require (
github.com/metacubex/quic-go v0.54.1-0.20250730114134-a1ae705fe295
github.com/metacubex/randv2 v0.2.0
github.com/metacubex/restls-client-go v0.1.7
github.com/metacubex/sing v0.5.6-0.20250824161024-672b3e5150b5
github.com/metacubex/sing v0.5.5
github.com/metacubex/sing-mux v0.3.3-0.20250813083925-d7c9aeaeeaac
github.com/metacubex/sing-quic v0.0.0-20250718154553-1b193bec4cbb
github.com/metacubex/sing-shadowsocks v0.2.12
github.com/metacubex/sing-shadowsocks2 v0.2.6
github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2
github.com/metacubex/sing-tun v0.4.8-0.20250824174501-f44ca001b82b
github.com/metacubex/sing-tun v0.4.7
github.com/metacubex/sing-vmess v0.2.4-0.20250822020810-4856053566f0
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f
github.com/metacubex/smux v0.0.0-20250503055512-501391591dee
@@ -89,7 +89,7 @@ require (
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mdlayher/socket v0.4.1 // indirect
github.com/metacubex/ascon v0.1.0 // indirect
github.com/metacubex/gvisor v0.0.0-20250823135502-e52fca163229 // indirect
github.com/metacubex/gvisor v0.0.0-20250324165734-5857f47bd43b // indirect
github.com/metacubex/nftables v0.0.0-20250503052935-30a69ab87793 // indirect
github.com/oasisprotocol/deoxysii v0.0.0-20220228165953-2091330c22b7 // indirect
github.com/onsi/ginkgo/v2 v2.9.5 // indirect

View File

@@ -106,8 +106,8 @@ github.com/metacubex/fswatch v0.1.1 h1:jqU7C/v+g0qc2RUFgmAOPoVvfl2BXXUXEumn6oQux
github.com/metacubex/fswatch v0.1.1/go.mod h1:czrTT7Zlbz7vWft8RQu9Qqh+JoX+Nnb+UabuyN1YsgI=
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 h1:cjd4biTvOzK9ubNCCkQ+ldc4YSH/rILn53l/xGBFHHI=
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759/go.mod h1:UHOv2xu+RIgLwpXca7TLrXleEd4oR3sPatW6IF8wU88=
github.com/metacubex/gvisor v0.0.0-20250823135502-e52fca163229 h1:sXVGoj8TdkMYp/ZiZgZJ5lgNww2DJdA/Lywu63+Z2/w=
github.com/metacubex/gvisor v0.0.0-20250823135502-e52fca163229/go.mod h1:8LpS0IJW1VmWzUm3ylb0e2SK5QDm5lO/2qwWLZgRpBU=
github.com/metacubex/gvisor v0.0.0-20250324165734-5857f47bd43b h1:RUh4OdVPz/jDrM9MQ2ySuqu2aeBqcA8rtfWUYLZ8RtI=
github.com/metacubex/gvisor v0.0.0-20250324165734-5857f47bd43b/go.mod h1:8LpS0IJW1VmWzUm3ylb0e2SK5QDm5lO/2qwWLZgRpBU=
github.com/metacubex/nftables v0.0.0-20250503052935-30a69ab87793 h1:1Qpuy+sU3DmyX9HwI+CrBT/oLNJngvBorR2RbajJcqo=
github.com/metacubex/nftables v0.0.0-20250503052935-30a69ab87793/go.mod h1:RjRNb4G52yAgfR+Oe/kp9G4PJJ97Fnj89eY1BFO3YyA=
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
github.com/metacubex/restls-client-go v0.1.7 h1:eCwiXCTQb5WJu9IlgYvDBA1OgrINv58dEe7hcN5H15k=
github.com/metacubex/restls-client-go v0.1.7/go.mod h1:BN/U52vPw7j8VTSh2vleD/MnmVKCov84mS5VcjVHH4g=
github.com/metacubex/sing v0.5.2/go.mod h1:ypf0mjwlZm0sKdQSY+yQvmsbWa0hNPtkeqyRMGgoN+w=
github.com/metacubex/sing v0.5.6-0.20250824161024-672b3e5150b5 h1:SdDqZsb2RFGe8gDuCAvRgRARo0vdKrq8cYXcKU/3vkk=
github.com/metacubex/sing v0.5.6-0.20250824161024-672b3e5150b5/go.mod h1:ypf0mjwlZm0sKdQSY+yQvmsbWa0hNPtkeqyRMGgoN+w=
github.com/metacubex/sing v0.5.5 h1:m5U8iHvRAUxlme3FZlE/LPIGHjU8oMCUzXWGbQQAC1E=
github.com/metacubex/sing v0.5.5/go.mod h1:ypf0mjwlZm0sKdQSY+yQvmsbWa0hNPtkeqyRMGgoN+w=
github.com/metacubex/sing-mux v0.3.3-0.20250813083925-d7c9aeaeeaac h1:wDH/Jh/yqWbzPktqJP+Y1cUG8hchcrzKzUxJiSpnaQs=
github.com/metacubex/sing-mux v0.3.3-0.20250813083925-d7c9aeaeeaac/go.mod h1:3rt1soewn0O6j89GCLmwAQFsq257u0jf2zQSPhTL3Bw=
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
github.com/metacubex/sing-shadowsocks2 v0.2.6/go.mod h1:vOEbfKC60txi0ca+yUlqEwOGc3Obl6cnSgx9Gf45KjE=
github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2 h1:gXU+MYPm7Wme3/OAY2FFzVq9d9GxPHOqu5AQfg/ddhI=
github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2/go.mod h1:mbfboaXauKJNIHJYxQRa+NJs4JU9NZfkA+I33dS2+9E=
github.com/metacubex/sing-tun v0.4.8-0.20250824174501-f44ca001b82b h1:QQm3Sq6HDkUpcUSnP8UfpGXtkwZVXINwAkHC78KpLzo=
github.com/metacubex/sing-tun v0.4.8-0.20250824174501-f44ca001b82b/go.mod h1:lY1AbDOLhkDNX/8cexsG82Fetg/O6vMA0eUW5SBMKhM=
github.com/metacubex/sing-tun v0.4.7 h1:ZDY/W+1c7PeWWKeKRyUo18fySF/TWjB0i5ui81Ar778=
github.com/metacubex/sing-tun v0.4.7/go.mod h1:xHecZRwBnKWe6zG9amAK9cXf91lF6blgjBqm+VvOrmU=
github.com/metacubex/sing-vmess v0.2.4-0.20250822020810-4856053566f0 h1:WZepq4TOZa6WewB8tGAZrrL+bL2R2ivoBzuEgAeolWc=
github.com/metacubex/sing-vmess v0.2.4-0.20250822020810-4856053566f0/go.mod h1:21R5R1u90uUvBQF0owoooEu96/SAYYD56nDrwm6nFaM=
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f h1:Sr/DYKYofKHKc4GF3qkRGNuj6XA6c0eqPgEDN+VAsYU=

View File

@@ -1,34 +0,0 @@
package sing_tun
import (
"context"
"time"
"github.com/metacubex/mihomo/component/dialer"
"github.com/metacubex/mihomo/component/resolver"
"github.com/metacubex/mihomo/log"
tun "github.com/metacubex/sing-tun"
"github.com/metacubex/sing-tun/ping"
M "github.com/metacubex/sing/common/metadata"
N "github.com/metacubex/sing/common/network"
)
func (h *ListenerHandler) PrepareConnection(network string, source M.Socksaddr, destination M.Socksaddr, routeContext tun.DirectRouteContext, timeout time.Duration) (tun.DirectRouteDestination, error) {
switch network {
case N.NetworkICMPv4, N.NetworkICMPv6: // our fork only send those type to PrepareConnection now
if resolver.IsFakeIP(destination.Addr) { // skip fakeip
log.Infoln("[ICMP] %s %s --> %s using fake ping echo", network, source, destination)
return nil, nil
}
log.Infoln("[ICMP] %s %s --> %s using DIRECT", network, source, destination)
directRouteDestination, err := ping.ConnectDestination(context.TODO(), log.SingLogger, dialer.ICMPControl(destination.Addr), destination.Addr, routeContext, timeout)
if err != nil {
log.Warnln("[ICMP] failed to connect to %s", destination)
return nil, err
}
log.Debugln("[ICMP] success connect to %s", destination)
return directRouteDestination, nil
}
return nil, nil
}

View File

@@ -11,7 +11,6 @@ import (
"strconv"
"strings"
"sync"
"time"
"github.com/metacubex/mihomo/adapter/inbound"
"github.com/metacubex/mihomo/component/dialer"
@@ -175,11 +174,11 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis
if tunMTU == 0 {
tunMTU = 9000
}
var udpTimeout time.Duration
var udpTimeout int64
if options.UDPTimeout != 0 {
udpTimeout = time.Second * time.Duration(options.UDPTimeout)
udpTimeout = options.UDPTimeout
} else {
udpTimeout = sing.UDPTimeout
udpTimeout = int64(sing.UDPTimeout.Seconds())
}
tableIndex := options.IPRoute2TableIndex
if tableIndex == 0 {

View File

@@ -160,7 +160,9 @@ func (i *ClientInstance) Handshake(conn net.Conn) (*CommonConn, error) {
if err != nil {
return nil, err
}
pfsKey := append(mlkem768Key, x25519Key...)
pfsKey := make([]byte, 32+32) // no more capacity
copy(pfsKey, mlkem768Key)
copy(pfsKey[32:], x25519Key)
c.UnitedKey = append(pfsKey, nfsKey...)
c.GCM = NewGCM(pfsPublicKey, c.UnitedKey)
c.PeerGCM = NewGCM(encryptedPfsPublicKey[:1088+32], c.UnitedKey)

View File

@@ -89,7 +89,7 @@ func (c *CommonConn) Read(b []byte) (int, error) {
if err != nil {
if c.Client != nil && strings.HasPrefix(err.Error(), "invalid header: ") { // client's 0-RTT
c.Client.RWLock.Lock()
if bytes.Equal(c.UnitedKey[:32], c.Client.PfsKey) {
if bytes.HasPrefix(c.UnitedKey, c.Client.PfsKey) {
c.Client.Expire = time.Now() // expired
}
c.Client.RWLock.Unlock()

View File

@@ -19,4 +19,5 @@
// https://github.com/XTLS/Xray-core/commit/b33555cc0a52d0af3c23d2af8fca42f8a685d9af
// https://github.com/XTLS/Xray-core/commit/ad7140641c44239c9dcdc3d7215ea639b1f0841c
// https://github.com/XTLS/Xray-core/commit/0199dea39988a1a1b846d0bf8598631bade40902
// https://github.com/XTLS/Xray-core/commit/fce1195b60f48ca18a953dbd5c7d991869de9a5e
package encryption

View File

@@ -19,7 +19,7 @@ import (
type ServerSession struct {
Expire time.Time
PfsKey []byte
Replays sync.Map
NfsKeys sync.Map
}
type ServerInstance struct {
@@ -177,7 +177,7 @@ func (i *ServerInstance) Handshake(conn net.Conn) (*CommonConn, error) {
s := i.Sessions[[16]byte(ticket)]
i.RWLock.RUnlock()
if s == nil {
noises := make([]byte, randBetween(100, 1000))
noises := make([]byte, randBetween(1268, 2268)) // matches 1-RTT's server hello length for "random", though it is not important, just for example
var err error
for err == nil {
rand.Read(noises)
@@ -186,21 +186,21 @@ func (i *ServerInstance) Handshake(conn net.Conn) (*CommonConn, error) {
conn.Write(noises) // make client do new handshake
return nil, errors.New("expired ticket")
}
if _, replay := s.Replays.LoadOrStore([32]byte(nfsKey), true); replay { // prevents bad client also
if _, loaded := s.NfsKeys.LoadOrStore([32]byte(nfsKey), true); loaded { // prevents bad client also
return nil, errors.New("replay detected")
}
c.UnitedKey = append(s.PfsKey, nfsKey...) // the same nfsKey links the upload & download
c.PreWrite = make([]byte, 16) // always trust yourself, not the client
rand.Read(c.PreWrite)
c.UnitedKey = append(s.PfsKey, nfsKey...) // the same nfsKey links the upload & download (prevents server -> client's another request)
c.PreWrite = make([]byte, 16)
rand.Read(c.PreWrite) // always trust yourself, not the client (also prevents being parsed as TLS thus causing false interruption for "native" and "xorpub")
c.GCM = NewGCM(c.PreWrite, c.UnitedKey)
c.PeerGCM = NewGCM(encryptedTicket, c.UnitedKey) // unchangeable ctx, and different ctx length for upload / download
c.PeerGCM = NewGCM(encryptedTicket, c.UnitedKey) // unchangeable ctx (prevents server -> server), and different ctx length for upload / download (prevents client -> client)
if i.XorMode == 2 {
c.Conn = NewXorConn(conn, NewCTR(c.UnitedKey, c.PreWrite), NewCTR(c.UnitedKey, iv), 16, 0) // it doesn't matter if the attacker sends client's iv back to the client
}
return c, nil
}
if length < 1184+32+16 { // client may send more public keys
if length < 1184+32+16 { // client may send more public keys in the future's version
return nil, errors.New("too short length")
}
encryptedPfsPublicKey := make([]byte, length)
@@ -224,7 +224,9 @@ func (i *ServerInstance) Handshake(conn net.Conn) (*CommonConn, error) {
if err != nil {
return nil, err
}
pfsKey := append(mlkem768Key, x25519Key...)
pfsKey := make([]byte, 32+32) // no more capacity
copy(pfsKey, mlkem768Key)
copy(pfsKey[32:], x25519Key)
pfsPublicKey := append(encapsulatedPfsKey, x25519SKey.PublicKey().Bytes()...)
c.UnitedKey = append(pfsKey, nfsKey...)
c.GCM = NewGCM(pfsPublicKey, c.UnitedKey)