derp: use a dedicated queue for disco traffic.

Signed-off-by: David Anderson <danderson@tailscale.com>
This commit is contained in:
David Anderson 2021-07-12 14:01:51 -07:00 committed by Dave Anderson
parent 67158549ab
commit d98829583a

View File

@ -490,6 +490,7 @@ func (s *Server) accept(nc Conn, brw *bufio.ReadWriter, remoteAddr string, connN
remoteIPPort: remoteIPPort, remoteIPPort: remoteIPPort,
connectedAt: time.Now(), connectedAt: time.Now(),
sendQueue: make(chan pkt, perClientSendQueueDepth), sendQueue: make(chan pkt, perClientSendQueueDepth),
discoSendQueue: make(chan pkt, perClientSendQueueDepth),
peerGone: make(chan key.Public), peerGone: make(chan key.Public),
canMesh: clientInfo.MeshKey != "" && clientInfo.MeshKey == s.meshKey, canMesh: clientInfo.MeshKey != "" && clientInfo.MeshKey == s.meshKey,
} }
@ -739,6 +740,10 @@ func (c *sclient) sendPkt(dst *sclient, p pkt) error {
// Attempt to queue for sending up to 3 times. On each attempt, if // Attempt to queue for sending up to 3 times. On each attempt, if
// the queue is full, try to drop from queue head to prioritize // the queue is full, try to drop from queue head to prioritize
// fresher packets. // fresher packets.
sendQueue := dst.sendQueue
if disco.LooksLikeDiscoWrapper(p.bs) {
sendQueue = dst.discoSendQueue
}
for attempt := 0; attempt < 3; attempt++ { for attempt := 0; attempt < 3; attempt++ {
select { select {
case <-dst.done: case <-dst.done:
@ -747,13 +752,13 @@ func (c *sclient) sendPkt(dst *sclient, p pkt) error {
default: default:
} }
select { select {
case dst.sendQueue <- p: case sendQueue <- p:
return nil return nil
default: default:
} }
select { select {
case pkt := <-dst.sendQueue: case pkt := <-sendQueue:
s.recordDrop(pkt.bs, c.key, dstKey, dropReasonQueueHead) s.recordDrop(pkt.bs, c.key, dstKey, dropReasonQueueHead)
c.recordQueueTime(pkt.enqueuedAt) c.recordQueueTime(pkt.enqueuedAt)
default: default:
@ -942,6 +947,7 @@ type sclient struct {
remoteAddr string // usually ip:port from net.Conn.RemoteAddr().String() remoteAddr string // usually ip:port from net.Conn.RemoteAddr().String()
remoteIPPort netaddr.IPPort // zero if remoteAddr is not ip:port. remoteIPPort netaddr.IPPort // zero if remoteAddr is not ip:port.
sendQueue chan pkt // packets queued to this client; never closed sendQueue chan pkt // packets queued to this client; never closed
discoSendQueue chan pkt // important packets queued to this client; never closed
peerGone chan key.Public // write request that a previous sender has disconnected (not used by mesh peers) peerGone chan key.Public // write request that a previous sender has disconnected (not used by mesh peers)
meshUpdate chan struct{} // write request to write peerStateChange meshUpdate chan struct{} // write request to write peerStateChange
canMesh bool // clientInfo had correct mesh token for inter-region routing canMesh bool // clientInfo had correct mesh token for inter-region routing
@ -1039,6 +1045,8 @@ func (c *sclient) sendLoop(ctx context.Context) error {
select { select {
case pkt := <-c.sendQueue: case pkt := <-c.sendQueue:
c.s.recordDrop(pkt.bs, pkt.src, c.key, dropReasonGone) c.s.recordDrop(pkt.bs, pkt.src, c.key, dropReasonGone)
case pkt := <-c.discoSendQueue:
c.s.recordDrop(pkt.bs, pkt.src, c.key, dropReasonGone)
default: default:
return return
} }
@ -1069,6 +1077,10 @@ func (c *sclient) sendLoop(ctx context.Context) error {
werr = c.sendPacket(msg.src, msg.bs) werr = c.sendPacket(msg.src, msg.bs)
c.recordQueueTime(msg.enqueuedAt) c.recordQueueTime(msg.enqueuedAt)
continue continue
case msg := <-c.discoSendQueue:
werr = c.sendPacket(msg.src, msg.bs)
c.recordQueueTime(msg.enqueuedAt)
continue
case <-keepAliveTick.C: case <-keepAliveTick.C:
werr = c.sendKeepAlive() werr = c.sendKeepAlive()
continue continue
@ -1092,6 +1104,9 @@ func (c *sclient) sendLoop(ctx context.Context) error {
case msg := <-c.sendQueue: case msg := <-c.sendQueue:
werr = c.sendPacket(msg.src, msg.bs) werr = c.sendPacket(msg.src, msg.bs)
c.recordQueueTime(msg.enqueuedAt) c.recordQueueTime(msg.enqueuedAt)
case msg := <-c.discoSendQueue:
werr = c.sendPacket(msg.src, msg.bs)
c.recordQueueTime(msg.enqueuedAt)
case <-keepAliveTick.C: case <-keepAliveTick.C:
werr = c.sendKeepAlive() werr = c.sendKeepAlive()
} }