mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2025-09-19 20:15:59 +08:00
feat: Experimental supports dialer IP4P address convert
form https://github.com/heiher/natmap/wiki/faq
This commit is contained in:
@ -7,12 +7,14 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/metacubex/mihomo/component/resolver"
|
"github.com/metacubex/mihomo/component/resolver"
|
||||||
"github.com/metacubex/mihomo/constant/features"
|
"github.com/metacubex/mihomo/constant/features"
|
||||||
|
"github.com/metacubex/mihomo/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -24,6 +26,7 @@ type dialFunc func(ctx context.Context, network string, ips []netip.Addr, port s
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
dialMux sync.Mutex
|
dialMux sync.Mutex
|
||||||
|
IP4PEnable bool
|
||||||
actualSingleStackDialContext = serialSingleStackDialContext
|
actualSingleStackDialContext = serialSingleStackDialContext
|
||||||
actualDualStackDialContext = serialDualStackDialContext
|
actualDualStackDialContext = serialDualStackDialContext
|
||||||
tcpConcurrent = false
|
tcpConcurrent = false
|
||||||
@ -128,7 +131,13 @@ func dialContext(ctx context.Context, network string, destination netip.Addr, po
|
|||||||
return dialContextHooked(ctx, network, destination, port)
|
return dialContextHooked(ctx, network, destination, port)
|
||||||
}
|
}
|
||||||
|
|
||||||
address := net.JoinHostPort(destination.String(), port)
|
var address string
|
||||||
|
if IP4PEnable {
|
||||||
|
NewDestination, NewPort := lookupIP4P(destination.String(), port)
|
||||||
|
address = net.JoinHostPort(NewDestination, NewPort)
|
||||||
|
} else {
|
||||||
|
address = net.JoinHostPort(destination.String(), port)
|
||||||
|
}
|
||||||
|
|
||||||
netDialer := opt.netDialer
|
netDialer := opt.netDialer
|
||||||
switch netDialer.(type) {
|
switch netDialer.(type) {
|
||||||
@ -383,3 +392,21 @@ func NewDialer(options ...Option) Dialer {
|
|||||||
opt := applyOptions(options...)
|
opt := applyOptions(options...)
|
||||||
return Dialer{Opt: *opt}
|
return Dialer{Opt: *opt}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetIP4PEnable(enableIP4PConvert bool) {
|
||||||
|
IP4PEnable = enableIP4PConvert
|
||||||
|
}
|
||||||
|
|
||||||
|
// kanged from https://github.com/heiher/frp/blob/ip4p/client/ip4p.go
|
||||||
|
|
||||||
|
func lookupIP4P(addr string, port string) (string, string) {
|
||||||
|
ip := net.ParseIP(addr)
|
||||||
|
if ip[0] == 0x20 && ip[1] == 0x01 &&
|
||||||
|
ip[2] == 0x00 && ip[3] == 0x00 {
|
||||||
|
addr = net.IPv4(ip[12], ip[13], ip[14], ip[15]).String()
|
||||||
|
port = strconv.Itoa(int(ip[10])<<8 + int(ip[11]))
|
||||||
|
log.Debugln("Convert IP4P address %s to %s", ip, net.JoinHostPort(addr, port))
|
||||||
|
return addr, port
|
||||||
|
}
|
||||||
|
return addr, port
|
||||||
|
}
|
||||||
|
@ -169,6 +169,7 @@ type Experimental struct {
|
|||||||
Fingerprints []string `yaml:"fingerprints"`
|
Fingerprints []string `yaml:"fingerprints"`
|
||||||
QUICGoDisableGSO bool `yaml:"quic-go-disable-gso"`
|
QUICGoDisableGSO bool `yaml:"quic-go-disable-gso"`
|
||||||
QUICGoDisableECN bool `yaml:"quic-go-disable-ecn"`
|
QUICGoDisableECN bool `yaml:"quic-go-disable-ecn"`
|
||||||
|
IP4PEnable bool `yaml:"dialer-ip4p-convert"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config is mihomo config manager
|
// Config is mihomo config manager
|
||||||
|
@ -197,6 +197,7 @@ func updateExperimental(c *config.Config) {
|
|||||||
if c.Experimental.QUICGoDisableECN {
|
if c.Experimental.QUICGoDisableECN {
|
||||||
_ = os.Setenv("QUIC_GO_DISABLE_ECN", strconv.FormatBool(true))
|
_ = os.Setenv("QUIC_GO_DISABLE_ECN", strconv.FormatBool(true))
|
||||||
}
|
}
|
||||||
|
dialer.GetIP4PEnable(c.Experimental.IP4PEnable)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateNTP(c *config.NTP) {
|
func updateNTP(c *config.NTP) {
|
||||||
|
Reference in New Issue
Block a user