ipn/ipnlocal: reuse transport across Taildrive remotes

This prevents us from opening a new connection on each HTTP
request.

Updates #11967

Signed-off-by: Percy Wegmann <percy@tailscale.com>
pull/12002/head
Percy Wegmann 6 months ago committed by Percy Wegmann
parent 2cf764e998
commit 817badf9ca

@ -312,7 +312,7 @@ func (b *LocalBackend) updateDrivePeersLocked(nm *netmap.NetworkMap) {
driveRemotes = b.driveRemotesFromPeers(nm) driveRemotes = b.driveRemotesFromPeers(nm)
} }
fs.SetRemotes(b.netMap.Domain, driveRemotes, &driveTransport{b: b}) fs.SetRemotes(b.netMap.Domain, driveRemotes, b.newDriveTransport())
} }
func (b *LocalBackend) driveRemotesFromPeers(nm *netmap.NetworkMap) []*drive.Remote { func (b *LocalBackend) driveRemotesFromPeers(nm *netmap.NetworkMap) []*drive.Remote {

@ -4823,13 +4823,6 @@ func (b *LocalBackend) updatePeersFromNetmapLocked(nm *netmap.NetworkMap) {
} }
} }
// driveTransport is an http.RoundTripper that uses the latest value of
// b.Dialer().PeerAPITransport() for each round trip and imposes a short
// dial timeout to avoid hanging on connecting to offline/unreachable hosts.
type driveTransport struct {
b *LocalBackend
}
// responseBodyWrapper wraps an io.ReadCloser and stores // responseBodyWrapper wraps an io.ReadCloser and stores
// the number of bytesRead. // the number of bytesRead.
type responseBodyWrapper struct { type responseBodyWrapper struct {
@ -4883,6 +4876,20 @@ func (rbw *responseBodyWrapper) Close() error {
return err return err
} }
// driveTransport is an http.RoundTripper that wraps
// b.Dialer().PeerAPITransport() with metrics tracking.
type driveTransport struct {
b *LocalBackend
tr *http.Transport
}
func (b *LocalBackend) newDriveTransport() *driveTransport {
return &driveTransport{
b: b,
tr: b.Dialer().PeerAPITransport(),
}
}
func (dt *driveTransport) RoundTrip(req *http.Request) (resp *http.Response, err error) { func (dt *driveTransport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
// Some WebDAV clients include origin and refer headers, which peerapi does // Some WebDAV clients include origin and refer headers, which peerapi does
// not like. Remove them. // not like. Remove them.
@ -4940,18 +4947,7 @@ func (dt *driveTransport) RoundTrip(req *http.Request) (resp *http.Response, err
} }
}() }()
// dialTimeout is fairly aggressive to avoid hangs on contacting offline or return dt.tr.RoundTrip(req)
// unreachable hosts.
dialTimeout := 1 * time.Second // TODO(oxtoacart): tune this
tr := dt.b.Dialer().PeerAPITransport().Clone()
dialContext := tr.DialContext
tr.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
ctxWithTimeout, cancel := context.WithTimeout(ctx, dialTimeout)
defer cancel()
return dialContext(ctxWithTimeout, network, addr)
}
return tr.RoundTrip(req)
} }
// roundTraffic rounds bytes. This is used to preserve user privacy within logs. // roundTraffic rounds bytes. This is used to preserve user privacy within logs.

Loading…
Cancel
Save