summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJordan Whited <jordan@tailscale.com>2023-11-07 15:24:21 -0800
committerJason A. Donenfeld <Jason@zx2c4.com>2023-12-11 16:34:09 +0100
commit7c20311b3d30b96576a95fec31f58e4d5e0d3234 (patch)
tree81e434bd02155f6519929562c8e9ee7ed6b303de
parent4ffa9c20327b9471c3eeb142347f679b69f84648 (diff)
device: reduce redundant per-packet overhead in RX path
Peer.RoutineSequentialReceiver() deals with packet vectors and does not need to perform timer and endpoint operations for every packet in a given vector. Changing these per-packet operations to per-vector improves throughput by as much as 10% in some environments. Signed-off-by: Jordan Whited <jordan@tailscale.com> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r--device/receive.go21
1 files changed, 15 insertions, 6 deletions
diff --git a/device/receive.go b/device/receive.go
index 4b32dc5..98e2024 100644
--- a/device/receive.go
+++ b/device/receive.go
@@ -445,7 +445,9 @@ func (peer *Peer) RoutineSequentialReceiver(maxBatchSize int) {
return
}
elemsContainer.Lock()
- for _, elem := range elemsContainer.elems {
+ validTailPacket := -1
+ dataPacketReceived := false
+ for i, elem := range elemsContainer.elems {
if elem.packet == nil {
// decryption failed
continue
@@ -455,21 +457,19 @@ func (peer *Peer) RoutineSequentialReceiver(maxBatchSize int) {
continue
}
- peer.SetEndpointFromPacket(elem.endpoint)
+ validTailPacket = i
if peer.ReceivedWithKeypair(elem.keypair) {
+ peer.SetEndpointFromPacket(elem.endpoint)
peer.timersHandshakeComplete()
peer.SendStagedPackets()
}
- peer.keepKeyFreshReceiving()
- peer.timersAnyAuthenticatedPacketTraversal()
- peer.timersAnyAuthenticatedPacketReceived()
peer.rxBytes.Add(uint64(len(elem.packet) + MinMessageSize))
if len(elem.packet) == 0 {
device.log.Verbosef("%v - Receiving keepalive packet", peer)
continue
}
- peer.timersDataReceived()
+ dataPacketReceived = true
switch elem.packet[0] >> 4 {
case 4:
@@ -512,6 +512,15 @@ func (peer *Peer) RoutineSequentialReceiver(maxBatchSize int) {
bufs = append(bufs, elem.buffer[:MessageTransportOffsetContent+len(elem.packet)])
}
+ if validTailPacket >= 0 {
+ peer.SetEndpointFromPacket(elemsContainer.elems[validTailPacket].endpoint)
+ peer.keepKeyFreshReceiving()
+ peer.timersAnyAuthenticatedPacketTraversal()
+ peer.timersAnyAuthenticatedPacketReceived()
+ }
+ if dataPacketReceived {
+ peer.timersDataReceived()
+ }
if len(bufs) > 0 {
_, err := device.tun.device.Write(bufs, MessageTransportOffsetContent)
if err != nil && !device.isClosed() {