|
|
|
|
@ -17,12 +17,14 @@ import ( |
|
|
|
|
"net/http" |
|
|
|
|
"runtime" |
|
|
|
|
"sort" |
|
|
|
|
"strconv" |
|
|
|
|
"strings" |
|
|
|
|
"sync" |
|
|
|
|
"time" |
|
|
|
|
|
|
|
|
|
dns "golang.org/x/net/dns/dnsmessage" |
|
|
|
|
"inet.af/netaddr" |
|
|
|
|
"tailscale.com/hostinfo" |
|
|
|
|
"tailscale.com/net/netns" |
|
|
|
|
"tailscale.com/types/dnstype" |
|
|
|
|
"tailscale.com/types/logger" |
|
|
|
|
@ -179,19 +181,37 @@ func init() { |
|
|
|
|
rand.Seed(time.Now().UnixNano()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func newForwarder(logf logger.Logf, responses chan packet, linkMon *monitor.Mon, linkSel ForwardLinkSelector) *forwarder { |
|
|
|
|
maxDoHInFlight := 1000 // effectively unlimited
|
|
|
|
|
if runtime.GOOS == "ios" { |
|
|
|
|
// No HTTP/2 on iOS yet (for size reasons), so DoH is
|
|
|
|
|
// pricier.
|
|
|
|
|
maxDoHInFlight = 10 |
|
|
|
|
func maxDoHInFlight(goos string) int { |
|
|
|
|
if goos != "ios" { |
|
|
|
|
return 1000 // effectively unlimited
|
|
|
|
|
} |
|
|
|
|
// iOS < 15 limits the memory to 15MB for NetworkExtensions.
|
|
|
|
|
// iOS >= 15 gives us 50MB.
|
|
|
|
|
// See: https://tailscale.com/blog/go-linker/
|
|
|
|
|
ver := hostinfo.GetOSVersion() |
|
|
|
|
if ver == "" { |
|
|
|
|
// Unknown iOS version, be cautious.
|
|
|
|
|
return 10 |
|
|
|
|
} |
|
|
|
|
idx := strings.Index(ver, ".") |
|
|
|
|
if idx == -1 { |
|
|
|
|
// Unknown iOS version, be cautious.
|
|
|
|
|
return 10 |
|
|
|
|
} |
|
|
|
|
major := ver[:idx] |
|
|
|
|
if m, err := strconv.Atoi(major); err != nil || m < 15 { |
|
|
|
|
return 10 |
|
|
|
|
} |
|
|
|
|
return 1000 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func newForwarder(logf logger.Logf, responses chan packet, linkMon *monitor.Mon, linkSel ForwardLinkSelector) *forwarder { |
|
|
|
|
f := &forwarder{ |
|
|
|
|
logf: logger.WithPrefix(logf, "forward: "), |
|
|
|
|
linkMon: linkMon, |
|
|
|
|
linkSel: linkSel, |
|
|
|
|
responses: responses, |
|
|
|
|
dohSem: make(chan struct{}, maxDoHInFlight), |
|
|
|
|
dohSem: make(chan struct{}, maxDoHInFlight(runtime.GOOS)), |
|
|
|
|
} |
|
|
|
|
f.ctx, f.ctxCancel = context.WithCancel(context.Background()) |
|
|
|
|
return f |
|
|
|
|
|