mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-29 13:05:46 +00:00
net/dns/resolver: bound DoH usage on iOS
Updates tailscale/corp#2238 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
95a9adbb97
commit
2968893add
@ -16,6 +16,7 @@
|
|||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -159,6 +160,7 @@ type forwarder struct {
|
|||||||
logf logger.Logf
|
logf logger.Logf
|
||||||
linkMon *monitor.Mon
|
linkMon *monitor.Mon
|
||||||
linkSel ForwardLinkSelector
|
linkSel ForwardLinkSelector
|
||||||
|
dohSem chan struct{}
|
||||||
|
|
||||||
ctx context.Context // good until Close
|
ctx context.Context // good until Close
|
||||||
ctxCancel context.CancelFunc // closes ctx
|
ctxCancel context.CancelFunc // closes ctx
|
||||||
@ -180,11 +182,18 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newForwarder(logf logger.Logf, responses chan packet, linkMon *monitor.Mon, linkSel ForwardLinkSelector) *forwarder {
|
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
|
||||||
|
}
|
||||||
f := &forwarder{
|
f := &forwarder{
|
||||||
logf: logger.WithPrefix(logf, "forward: "),
|
logf: logger.WithPrefix(logf, "forward: "),
|
||||||
linkMon: linkMon,
|
linkMon: linkMon,
|
||||||
linkSel: linkSel,
|
linkSel: linkSel,
|
||||||
responses: responses,
|
responses: responses,
|
||||||
|
dohSem: make(chan struct{}, maxDoHInFlight),
|
||||||
}
|
}
|
||||||
f.ctx, f.ctxCancel = context.WithCancel(context.Background())
|
f.ctx, f.ctxCancel = context.WithCancel(context.Background())
|
||||||
return f
|
return f
|
||||||
@ -262,7 +271,22 @@ func (f *forwarder) getDoHClient(ip netaddr.IP) (urlBase string, c *http.Client,
|
|||||||
|
|
||||||
const dohType = "application/dns-message"
|
const dohType = "application/dns-message"
|
||||||
|
|
||||||
|
func (f *forwarder) releaseDoHSem() { <-f.dohSem }
|
||||||
|
|
||||||
func (f *forwarder) sendDoH(ctx context.Context, urlBase string, c *http.Client, packet []byte) ([]byte, error) {
|
func (f *forwarder) sendDoH(ctx context.Context, urlBase string, c *http.Client, packet []byte) ([]byte, error) {
|
||||||
|
// Bound the number of HTTP requests in flight. This primarily
|
||||||
|
// matters for iOS where we're very memory constrained and
|
||||||
|
// HTTP requests are heavier on iOS where we don't include
|
||||||
|
// HTTP/2 for binary size reasons (as binaries on iOS linked
|
||||||
|
// with Go code cost memory proportional to the binary size,
|
||||||
|
// for reasons not fully understood).
|
||||||
|
select {
|
||||||
|
case f.dohSem <- struct{}{}:
|
||||||
|
case <-ctx.Done():
|
||||||
|
return nil, ctx.Err()
|
||||||
|
}
|
||||||
|
defer f.releaseDoHSem()
|
||||||
|
|
||||||
req, err := http.NewRequestWithContext(ctx, "POST", urlBase, bytes.NewReader(packet))
|
req, err := http.NewRequestWithContext(ctx, "POST", urlBase, bytes.NewReader(packet))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
Loading…
Reference in New Issue
Block a user