@@ -269,6 +269,62 @@ func Reaches(p Proxy, urlOrHostPortOrIPPortCsv string, protos ...string) bool {
269269 return true
270270 }
271271
272+ // auto:[ip,http,https]:[v4,v6]
273+ if strings .HasPrefix (urlOrHostPortOrIPPortCsv , "auto" ) {
274+ const autoSize = 5
275+ prefs := strings .Split (urlOrHostPortOrIPPortCsv , ":" )
276+ scheme := "https"
277+ if len (prefs ) >= 2 {
278+ scheme = prefs [1 ]
279+ }
280+ ipfrag := ""
281+ if len (prefs ) >= 3 {
282+ ipfrag = prefs [2 ] // "v4", "v6", ""
283+ }
284+
285+ protos = []string {}
286+ switch scheme {
287+ case "http" , "https" :
288+ urls := []string {}
289+ for _ , h := range dialers .SampleHosts (autoSize ) {
290+ u := url.URL {
291+ Scheme : scheme ,
292+ Host : h ,
293+ Fragment : ipfrag , // if empty, connectivity over v4+v6 is attempted
294+ }
295+ urls = append (urls , u .String ())
296+ }
297+ log .I ("proxy: %s reaches: auto:http for %v urls" , idstr (p ), urls )
298+ urlOrHostPortOrIPPortCsv = strings .Join (urls , "," )
299+ case "ip" :
300+ ips := make ([]netip.Addr , 0 , autoSize )
301+ log .I ("proxy: %s reaches: auto:ip for %v ips" , idstr (p ), ips )
302+
303+ if ipfrag == "v4" {
304+ protos = append (protos , "tcp4" , "udp4" )
305+ } else if ipfrag == "v6" {
306+ protos = append (protos , "tcp6" , "udp6" )
307+ } else {
308+ protos = append (protos , "tcp" , "udp" )
309+ }
310+ for _ , ip := range dialers .SampleIPs (autoSize ) {
311+ if ipfrag == "v4" && ip .Is4 () {
312+ ips = append (ips , ip )
313+ } else if ipfrag == "v6" && ip .Is6 () {
314+ ips = append (ips , ip )
315+ } else if ipfrag == "" {
316+ ips = append (ips , ip ) // both v4 and v6
317+ }
318+
319+ }
320+ // default port for ip:port is 80 if left unspecified (see below)
321+ urlOrHostPortOrIPPortCsv = strings .Join (core .Map (ips , func (ip netip.Addr ) string { return ip .String () }), "," )
322+ default :
323+ log .E ("proxy: %s reaches: auto:%s for %v protos; unsupported scheme" , idstr (p ), scheme , protos )
324+ return false
325+ }
326+ }
327+
272328 pid := idstr (p )
273329 hostportOrIPPort := strings .Split (urlOrHostPortOrIPPortCsv , "," )
274330 if urls , oth := extractHttpURLs (urlOrHostPortOrIPPortCsv ); len (urls ) > 0 {
0 commit comments