@@ -27,6 +27,7 @@ import (
2727 "github.com/celzero/firestack/intra/core"
2828 "github.com/celzero/firestack/intra/dialers"
2929 "github.com/celzero/firestack/intra/log"
30+ "github.com/celzero/firestack/intra/settings"
3031)
3132
3233const (
@@ -120,10 +121,27 @@ func fetchIPMetadata(p Proxy, network string) (*x.IPMetadata, error) {
120121 if cached := getCachedIPMeta (p , network ); cached != nil {
121122 return cached , nil
122123 }
123- if s := p .Status (); s != TOK && s != TKO {
124+
125+ st := p .Status ()
126+ if st != TOK && st != TKO {
124127 return nil , errNotActive
125128 }
126129
130+ rt := p .Router ()
131+ // "tcp" and "udp" are dual-stack
132+ is4 := network == "tcp4" || network == "udp4" || network == "ip4"
133+ is6 := network == "tcp6" || network == "udp6" || network == "ip6"
134+ is46 := network == "tcp" || network == "udp" || network == "ip"
135+ if ! rt .IP4 () && is4 {
136+ return nil , errProxyRoute
137+ }
138+ if ! rt .IP6 () && is6 {
139+ return nil , errProxyRoute
140+ }
141+ if ! rt .IP4 () && ! rt .IP6 () && is46 {
142+ return nil , errProxyRoute
143+ }
144+
127145 meta := & x.IPMetadata {ID : idstr (p )}
128146 mullvadURL := mullvadV4URL
129147 if network == "tcp6" {
@@ -146,12 +164,12 @@ func fetchIPMetadata(p Proxy, network string) (*x.IPMetadata, error) {
146164 applyMullvad (meta , mull )
147165 meta .ProviderURL = mullvadURL
148166 } else {
149- perr := fmt .Errorf ("proxy: client: %s ip lookup failed" , idstr (p ))
167+ perr := fmt .Errorf ("proxy: client: %s %s lookup failed" , idstr (p ), network )
150168 return nil , core .JoinErr (perr , err0 , err1 , err2 , err3 , err4 )
151169 }
152170
153171 if len (meta .IP ) <= 0 {
154- return nil , fmt .Errorf ("proxy: client: %s ip lookup failed" , idstr (p ))
172+ return nil , fmt .Errorf ("proxy: client: %s %s lookup failed" , idstr (p ), network )
155173 }
156174
157175 setCachedIPMeta (p , network , meta )
@@ -602,7 +620,24 @@ func httpClient(p Proxy, network string, u *url.URL) *http.Client {
602620 }
603621 }
604622
605- ips := dialers .For (host )
623+ dnsid := x .Default
624+ if hasDNS := len (p .DNS ()) > 0 ; hasDNS {
625+ dnsid = p .ID ()
626+ }
627+
628+ ips , err := dialers .Resolve (host , dnsid )
629+ if err != nil {
630+ if settings .DefaultDNSAsFallback .Load () {
631+ log .D ("proxy: client: %s on %s resolve %s err %s: %v; using Default" ,
632+ idstr (p ), network , dnsid , host , err )
633+ ips = dialers .For (host )
634+ } else {
635+ log .E ("proxy: client: %s on %s resolve %s err %s: %v" ,
636+ idstr (p ), network , dnsid , host , err )
637+ return nil , err
638+ }
639+ }
640+
606641 filtered := make ([]netip.Addr , 0 , len (ips ))
607642 for _ , ip := range ips {
608643 if network == "tcp4" && ip .Is4 () {
@@ -617,16 +652,19 @@ func httpClient(p Proxy, network string, u *url.URL) *http.Client {
617652 return nil , errNoSuitableAddress
618653 }
619654
620- log .VV ("proxy: client: %s resolved %s to %v on port %d for %s" , idstr (p ), host , filtered , on , network )
655+ log .VV ("proxy: client: %s resolved %s to %v on port %d for %s" ,
656+ idstr (p ), host , filtered , on , network )
621657
622658 var lastErr error
623659 for _ , ip := range filtered {
624660 dest := netip .AddrPortFrom (ip , uint16 (on )).String ()
625661 if conn , err := p .Dial (network , dest ); err == nil {
626- log .VV ("proxy: client: %s dialed %s @ %s on %s" , idstr (p ), host , dest , network )
662+ log .VV ("proxy: client: %s dialed %s @ %s on %s" ,
663+ idstr (p ), host , dest , network )
627664 return conn , nil
628665 } else {
629- log .E ("proxy: client: %s failed to dial %s @ %s on %s: %v" , idstr (p ), host , dest , network , err )
666+ log .E ("proxy: client: %s failed to dial %s @ %s on %s: %v" ,
667+ idstr (p ), host , dest , network , err )
630668 lastErr = err
631669 }
632670 }
0 commit comments