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>
This commit is contained in:
Percy Wegmann 2024-05-03 07:21:30 -05:00 committed by Percy Wegmann
parent 2cf764e998
commit 817badf9ca
2 changed files with 16 additions and 20 deletions

View File

@ -312,7 +312,7 @@ func (b *LocalBackend) updateDrivePeersLocked(nm *netmap.NetworkMap) {
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 {

View File

@ -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
// the number of bytesRead.
type responseBodyWrapper struct {
@ -4883,6 +4876,20 @@ func (rbw *responseBodyWrapper) Close() error {
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) {
// Some WebDAV clients include origin and refer headers, which peerapi does
// 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
// 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)
return dt.tr.RoundTrip(req)
}
// roundTraffic rounds bytes. This is used to preserve user privacy within logs.