Skip to content

Commit cc193a0

Browse files
committed
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 <[email protected]>
1 parent 8cc8b8b commit cc193a0

File tree

2 files changed

+17
-8
lines changed

2 files changed

+17
-8
lines changed

device/receive.go

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,9 @@ func (peer *Peer) RoutineSequentialReceiver(maxBatchSize int) {
445445
return
446446
}
447447
elemsContainer.Lock()
448-
for _, elem := range elemsContainer.elems {
448+
validTailPacket := -1
449+
dataPacketReceived := false
450+
for i, elem := range elemsContainer.elems {
449451
if elem.packet == nil {
450452
// decryption failed
451453
continue
@@ -455,21 +457,19 @@ func (peer *Peer) RoutineSequentialReceiver(maxBatchSize int) {
455457
continue
456458
}
457459

458-
peer.SetEndpointFromPacket(elem.endpoint)
460+
validTailPacket = i
459461
if peer.ReceivedWithKeypair(elem.keypair) {
462+
peer.SetEndpointFromPacket(elem.endpoint)
460463
peer.timersHandshakeComplete()
461464
peer.SendStagedPackets()
462465
}
463-
peer.keepKeyFreshReceiving()
464-
peer.timersAnyAuthenticatedPacketTraversal()
465-
peer.timersAnyAuthenticatedPacketReceived()
466466
peer.rxBytes.Add(uint64(len(elem.packet) + MinMessageSize))
467467

468468
if len(elem.packet) == 0 {
469469
device.log.Verbosef("%v - Receiving keepalive packet", peer)
470470
continue
471471
}
472-
peer.timersDataReceived()
472+
dataPacketReceived = true
473473

474474
switch elem.packet[0] >> 4 {
475475
case 4:
@@ -512,6 +512,15 @@ func (peer *Peer) RoutineSequentialReceiver(maxBatchSize int) {
512512

513513
bufs = append(bufs, elem.buffer[:MessageTransportOffsetContent+len(elem.packet)])
514514
}
515+
if validTailPacket >= 0 {
516+
peer.SetEndpointFromPacket(elemsContainer.elems[validTailPacket].endpoint)
517+
peer.keepKeyFreshReceiving()
518+
peer.timersAnyAuthenticatedPacketTraversal()
519+
peer.timersAnyAuthenticatedPacketReceived()
520+
}
521+
if dataPacketReceived {
522+
peer.timersDataReceived()
523+
}
515524
if len(bufs) > 0 {
516525
_, err := device.tun.device.Write(bufs, MessageTransportOffsetContent)
517526
if err != nil && !device.isClosed() {

device/send.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ func calculatePaddingSize(packetSize, mtu int) int {
436436
return paddedSize - lastUnit
437437
}
438438

439-
/* Encrypts the elems in the queue
439+
/* Encrypts the elements in the queue
440440
* and marks them for sequential consumption (by releasing the mutex)
441441
*
442442
* Obs. One instance per core
@@ -495,7 +495,7 @@ func (peer *Peer) RoutineSequentialSender(maxBatchSize int) {
495495
return
496496
}
497497
if !peer.isRunning.Load() {
498-
// peer has been stopped; return re-usable elemsContainer to the shared pool.
498+
// peer has been stopped; return re-usable elems to the shared pool.
499499
// This is an optimization only. It is possible for the peer to be stopped
500500
// immediately after this check, in which case, elem will get processed.
501501
// The timers and SendBuffers code are resilient to a few stragglers.

0 commit comments

Comments
 (0)