Skip to content

Commit

Permalink
feat: Supports outbound IP4P address translationfrom
Browse files Browse the repository at this point in the history
  • Loading branch information
xishang0128 committed Mar 9, 2024
1 parent e39dbb7 commit 90fee64
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 1 deletion.
29 changes: 28 additions & 1 deletion component/dialer/dialer.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ import (
"net"
"net/netip"
"os"
"strconv"
"strings"
"sync"
"time"

"github.com/metacubex/mihomo/component/resolver"
"github.com/metacubex/mihomo/constant/features"
"github.com/metacubex/mihomo/log"
)

const (
Expand All @@ -24,6 +26,7 @@ type dialFunc func(ctx context.Context, network string, ips []netip.Addr, port s

var (
dialMux sync.Mutex
IP4PEnable bool
actualSingleStackDialContext = serialSingleStackDialContext
actualDualStackDialContext = serialDualStackDialContext
tcpConcurrent = false
Expand Down Expand Up @@ -128,7 +131,13 @@ func dialContext(ctx context.Context, network string, destination netip.Addr, po
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
switch netDialer.(type) {
Expand Down Expand Up @@ -383,3 +392,21 @@ func NewDialer(options ...Option) Dialer {
opt := applyOptions(options...)
return Dialer{Opt: *opt}
}

// 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
}

func DialWithIP4PTranslation(enableIP4PTranslation bool) {
IP4PEnable = enableIP4PTranslation
}
1 change: 1 addition & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ type Experimental struct {
Fingerprints []string `yaml:"fingerprints"`
QUICGoDisableGSO bool `yaml:"quic-go-disable-gso"`
QUICGoDisableECN bool `yaml:"quic-go-disable-ecn"`
IP4PEnable bool `yaml:"dialer-ip4p-onvert"`
}

// Config is mihomo config manager
Expand Down
1 change: 1 addition & 0 deletions hub/executor/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ func updateExperimental(c *config.Config) {
if c.Experimental.QUICGoDisableECN {
_ = os.Setenv("QUIC_GO_DISABLE_ECN", strconv.FormatBool(true))
}
dialer.DialWithIP4PTranslation(c.Experimental.IP4PEnable)
}

func updateNTP(c *config.NTP) {
Expand Down

0 comments on commit 90fee64

Please sign in to comment.