cmd/derper,derp: make TCP write timeout configurable

The timeout still defaults to 2 seconds, but can now be changed via command-line flag.

Updates tailscale/corp#26045

Signed-off-by: Percy Wegmann <percy@tailscale.com>
This commit is contained in:
Percy Wegmann
2025-01-23 14:32:22 -06:00
committed by Percy Wegmann
parent 5e9056a356
commit 450bc9a6b8
2 changed files with 19 additions and 3 deletions

View File

@@ -84,7 +84,7 @@ func init() {
const (
defaultPerClientSendQueueDepth = 32 // default packets buffered for sending
writeTimeout = 2 * time.Second
DefaultTCPWiteTimeout = 2 * time.Second
privilegedWriteTimeout = 30 * time.Second // for clients with the mesh key
)
@@ -201,6 +201,8 @@ type Server struct {
// Sets the client send queue depth for the server.
perClientSendQueueDepth int
tcpWriteTimeout time.Duration
clock tstime.Clock
}
@@ -377,6 +379,7 @@ func NewServer(privateKey key.NodePrivate, logf logger.Logf) *Server {
bufferedWriteFrames: metrics.NewHistogram([]float64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 50, 100}),
keyOfAddr: map[netip.AddrPort]key.NodePublic{},
clock: tstime.StdClock{},
tcpWriteTimeout: DefaultTCPWiteTimeout,
}
s.initMetacert()
s.packetsRecvDisco = s.packetsRecvByKind.Get(string(packetKindDisco))
@@ -481,6 +484,13 @@ func (s *Server) SetVerifyClientURLFailOpen(v bool) {
s.verifyClientsURLFailOpen = v
}
// SetTCPWriteTimeout sets the timeout for writing to connected clients.
// This timeout does not apply to mesh connections.
// Defaults to 2 seconds.
func (s *Server) SetTCPWriteTimeout(d time.Duration) {
s.tcpWriteTimeout = d
}
// HasMeshKey reports whether the server is configured with a mesh key.
func (s *Server) HasMeshKey() bool { return s.meshKey != "" }
@@ -1805,7 +1815,7 @@ func (c *sclient) sendLoop(ctx context.Context) error {
}
func (c *sclient) setWriteDeadline() {
d := writeTimeout
d := c.s.tcpWriteTimeout
if c.canMesh {
// Trusted peers get more tolerance.
//
@@ -1817,7 +1827,10 @@ func (c *sclient) setWriteDeadline() {
// of connected peers.
d = privilegedWriteTimeout
}
c.nc.SetWriteDeadline(time.Now().Add(d))
// Ignore the error from setting the write deadline. In practice,
// setting the deadline will only fail if the connection is closed
// or closing, so the subsequent Write() will fail anyway.
_ = c.nc.SetWriteDeadline(time.Now().Add(d))
}
// sendKeepAlive sends a keep-alive frame, without flushing.