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>
This commit is contained in:
parent
4ffa9c2032
commit
7c20311b3d
@ -445,7 +445,9 @@ func (peer *Peer) RoutineSequentialReceiver(maxBatchSize int) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
elemsContainer.Lock()
|
elemsContainer.Lock()
|
||||||
for _, elem := range elemsContainer.elems {
|
validTailPacket := -1
|
||||||
|
dataPacketReceived := false
|
||||||
|
for i, elem := range elemsContainer.elems {
|
||||||
if elem.packet == nil {
|
if elem.packet == nil {
|
||||||
// decryption failed
|
// decryption failed
|
||||||
continue
|
continue
|
||||||
@ -455,21 +457,19 @@ func (peer *Peer) RoutineSequentialReceiver(maxBatchSize int) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
peer.SetEndpointFromPacket(elem.endpoint)
|
validTailPacket = i
|
||||||
if peer.ReceivedWithKeypair(elem.keypair) {
|
if peer.ReceivedWithKeypair(elem.keypair) {
|
||||||
|
peer.SetEndpointFromPacket(elem.endpoint)
|
||||||
peer.timersHandshakeComplete()
|
peer.timersHandshakeComplete()
|
||||||
peer.SendStagedPackets()
|
peer.SendStagedPackets()
|
||||||
}
|
}
|
||||||
peer.keepKeyFreshReceiving()
|
|
||||||
peer.timersAnyAuthenticatedPacketTraversal()
|
|
||||||
peer.timersAnyAuthenticatedPacketReceived()
|
|
||||||
peer.rxBytes.Add(uint64(len(elem.packet) + MinMessageSize))
|
peer.rxBytes.Add(uint64(len(elem.packet) + MinMessageSize))
|
||||||
|
|
||||||
if len(elem.packet) == 0 {
|
if len(elem.packet) == 0 {
|
||||||
device.log.Verbosef("%v - Receiving keepalive packet", peer)
|
device.log.Verbosef("%v - Receiving keepalive packet", peer)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
peer.timersDataReceived()
|
dataPacketReceived = true
|
||||||
|
|
||||||
switch elem.packet[0] >> 4 {
|
switch elem.packet[0] >> 4 {
|
||||||
case 4:
|
case 4:
|
||||||
@ -512,6 +512,15 @@ func (peer *Peer) RoutineSequentialReceiver(maxBatchSize int) {
|
|||||||
|
|
||||||
bufs = append(bufs, elem.buffer[:MessageTransportOffsetContent+len(elem.packet)])
|
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 {
|
if len(bufs) > 0 {
|
||||||
_, err := device.tun.device.Write(bufs, MessageTransportOffsetContent)
|
_, err := device.tun.device.Write(bufs, MessageTransportOffsetContent)
|
||||||
if err != nil && !device.isClosed() {
|
if err != nil && !device.isClosed() {
|
||||||
|
Loading…
Reference in New Issue
Block a user