diff --git a/adapter/adapter.go b/adapter/adapter.go index 5e89e8bf..53f7c6d9 100644 --- a/adapter/adapter.go +++ b/adapter/adapter.go @@ -7,9 +7,7 @@ import ( "fmt" "net" "net/http" - "net/netip" "net/url" - "strconv" "strings" "time" @@ -316,15 +314,7 @@ func urlToMetadata(rawURL string) (addr C.Metadata, err error) { return } } - uintPort, err := strconv.ParseUint(port, 10, 16) - if err != nil { - return - } - addr = C.Metadata{ - Host: u.Hostname(), - DstIP: netip.Addr{}, - DstPort: uint16(uintPort), - } + err = addr.SetRemoteAddress(net.JoinHostPort(u.Hostname(), port)) return } diff --git a/adapter/inbound/util.go b/adapter/inbound/util.go index d67a96db..17e6479c 100644 --- a/adapter/inbound/util.go +++ b/adapter/inbound/util.go @@ -4,7 +4,6 @@ import ( "net" "net/http" "net/netip" - "strconv" "strings" C "github.com/metacubex/mihomo/constant" @@ -41,23 +40,8 @@ func parseHTTPAddr(request *http.Request) *C.Metadata { // trim FQDN (#737) host = strings.TrimRight(host, ".") - var uint16Port uint16 - if port, err := strconv.ParseUint(port, 10, 16); err == nil { - uint16Port = uint16(port) - } - - metadata := &C.Metadata{ - NetWork: C.TCP, - Host: host, - DstIP: netip.Addr{}, - DstPort: uint16Port, - } - - ip, err := netip.ParseAddr(host) - if err == nil { - metadata.DstIP = ip - } - + metadata := &C.Metadata{} + _ = metadata.SetRemoteAddress(net.JoinHostPort(host, port)) return metadata } diff --git a/component/resolver/host.go b/component/resolver/host.go index 34da8e9f..c214acfc 100644 --- a/component/resolver/host.go +++ b/component/resolver/host.go @@ -77,7 +77,7 @@ func NewHostValue(value any) (HostValue, error) { isDomain = false for _, str := range valueArr { if ip, err := netip.ParseAddr(str); err == nil { - ips = append(ips, ip) + ips = append(ips, ip.Unmap()) } else { return HostValue{}, err } @@ -85,7 +85,7 @@ func NewHostValue(value any) (HostValue, error) { } else if len(valueArr) == 1 { host := valueArr[0] if ip, err := netip.ParseAddr(host); err == nil { - ips = append(ips, ip) + ips = append(ips, ip.Unmap()) isDomain = false } else { domain = host diff --git a/component/resolver/resolver.go b/component/resolver/resolver.go index 46038303..44ad2d71 100644 --- a/component/resolver/resolver.go +++ b/component/resolver/resolver.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "net/netip" - "strings" "time" "github.com/metacubex/mihomo/common/utils" @@ -68,7 +67,8 @@ func LookupIPv4WithResolver(ctx context.Context, host string, r Resolver) ([]net ip, err := netip.ParseAddr(host) if err == nil { - if ip.Is4() || ip.Is4In6() { + ip = ip.Unmap() + if ip.Is4() { return []netip.Addr{ip}, nil } return []netip.Addr{}, ErrIPVersion @@ -117,7 +117,8 @@ func LookupIPv6WithResolver(ctx context.Context, host string, r Resolver) ([]net } if ip, err := netip.ParseAddr(host); err == nil { - if strings.Contains(host, ":") { + ip = ip.Unmap() + if ip.Is6() { return []netip.Addr{ip}, nil } return nil, ErrIPVersion @@ -166,6 +167,7 @@ func LookupIPWithResolver(ctx context.Context, host string, r Resolver) ([]netip } if ip, err := netip.ParseAddr(host); err == nil { + ip = ip.Unmap() return []netip.Addr{ip}, nil } diff --git a/dns/resolver.go b/dns/resolver.go index b0807863..adcea094 100644 --- a/dns/resolver.go +++ b/dns/resolver.go @@ -348,7 +348,8 @@ func (r *Resolver) ipExchange(ctx context.Context, m *D.Msg) (msg *D.Msg, err er func (r *Resolver) lookupIP(ctx context.Context, host string, dnsType uint16) (ips []netip.Addr, err error) { ip, err := netip.ParseAddr(host) if err == nil { - isIPv4 := ip.Is4() || ip.Is4In6() + ip = ip.Unmap() + isIPv4 := ip.Is4() if dnsType == D.TypeAAAA && !isIPv4 { return []netip.Addr{ip}, nil } else if dnsType == D.TypeA && isIPv4 { diff --git a/tunnel/tunnel.go b/tunnel/tunnel.go index 6edc2303..744a01b1 100644 --- a/tunnel/tunnel.go +++ b/tunnel/tunnel.go @@ -287,17 +287,21 @@ func isHandle(t C.Type) bool { return status == Running || (status == Inner && t == C.INNER) } +func fixMetadata(metadata *C.Metadata) { + // first unmap dstIP + metadata.DstIP = metadata.DstIP.Unmap() + // handle IP string on host + if ip, err := netip.ParseAddr(metadata.Host); err == nil { + metadata.DstIP = ip.Unmap() + metadata.Host = "" + } +} + func needLookupIP(metadata *C.Metadata) bool { return resolver.MappingEnabled() && metadata.Host == "" && metadata.DstIP.IsValid() } func preHandleMetadata(metadata *C.Metadata) error { - // handle IP string on host - if ip, err := netip.ParseAddr(metadata.Host); err == nil { - metadata.DstIP = ip - metadata.Host = "" - } - // preprocess enhanced-mode metadata if needLookupIP(metadata) { host, exist := resolver.FindHostByIP(metadata.DstIP) @@ -365,6 +369,7 @@ func handleUDPConn(packet C.PacketAdapter) { log.Warnln("[Metadata] not valid: %#v", metadata) return } + fixMetadata(metadata) // fix some metadata not set via metadata.SetRemoteAddr or metadata.SetRemoteAddress if err := preHandleMetadata(metadata.Clone()); err != nil { // precheck without modify metadata packet.Drop() @@ -449,6 +454,7 @@ func handleTCPConn(connCtx C.ConnContext) { log.Warnln("[Metadata] not valid: %#v", metadata) return } + fixMetadata(metadata) // fix some metadata not set via metadata.SetRemoteAddr or metadata.SetRemoteAddress preHandleFailed := false if err := preHandleMetadata(metadata); err != nil {