Fix input packets peer lookup
InputPacket/InputPackets used the deprecated trie-only AllowedIPs.Lookup. With tailscale v1.102 a PeerByIPPacketFunc is installed and the trie is no longer populated, so every injected packet was unmatched. Use LookupFromPacket, and size the sequential sender scratch for full input batches instead of capping containers at the device batch size.
This commit is contained in:
parent
da8671622b
commit
f39689ad35
1 changed files with 47 additions and 5 deletions
|
|
@ -403,8 +403,51 @@ func (device *Device) RoutineReadFromTUN() {
|
|||
// each), so without this cap a flood is buffered instead of dropped.
|
||||
const maxQueuedInputPackets = 2048
|
||||
|
||||
func (device *Device) inputPacketPeer(destination []byte, packetSlices [][]byte) *Peer {
|
||||
var src, dst netip.Addr
|
||||
switch len(destination) {
|
||||
case net.IPv4len:
|
||||
dst = netip.AddrFrom4([4]byte(destination))
|
||||
var srcBytes [net.IPv4len]byte
|
||||
if !gatherPacketBytes(packetSlices, IPv4offsetSrc, srcBytes[:]) {
|
||||
return nil
|
||||
}
|
||||
src = netip.AddrFrom4(srcBytes)
|
||||
case net.IPv6len:
|
||||
dst = netip.AddrFrom16([16]byte(destination))
|
||||
var srcBytes [net.IPv6len]byte
|
||||
if !gatherPacketBytes(packetSlices, IPv6offsetSrc, srcBytes[:]) {
|
||||
return nil
|
||||
}
|
||||
src = netip.AddrFrom16(srcBytes)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
var ipPkt []byte
|
||||
if len(packetSlices) == 1 {
|
||||
ipPkt = packetSlices[0]
|
||||
}
|
||||
return device.allowedips.LookupFromPacket(src, dst, ipPkt)
|
||||
}
|
||||
|
||||
func gatherPacketBytes(packetSlices [][]byte, offset int, destination []byte) bool {
|
||||
for _, packetSlice := range packetSlices {
|
||||
if offset >= len(packetSlice) {
|
||||
offset -= len(packetSlice)
|
||||
continue
|
||||
}
|
||||
n := copy(destination, packetSlice[offset:])
|
||||
destination = destination[n:]
|
||||
offset = 0
|
||||
if len(destination) == 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (device *Device) InputPacket(destination []byte, packetSlices [][]byte) {
|
||||
peer := device.allowedips.Lookup(destination)
|
||||
peer := device.inputPacketPeer(destination, packetSlices)
|
||||
if peer == nil {
|
||||
return
|
||||
}
|
||||
|
|
@ -447,10 +490,9 @@ type InputPacketRef struct {
|
|||
|
||||
func (device *Device) InputPackets(packets []*InputPacketRef) []*InputPacketRef {
|
||||
var unmatched []*InputPacketRef
|
||||
batchSize := device.BatchSize()
|
||||
elemsByPeer := make(map[*Peer][]*QueueOutboundElementsContainer, len(packets))
|
||||
for _, packetRef := range packets {
|
||||
peer := device.allowedips.Lookup(packetRef.Destination)
|
||||
peer := device.inputPacketPeer(packetRef.Destination, packetRef.PacketSlices)
|
||||
if peer == nil {
|
||||
unmatched = append(unmatched, packetRef)
|
||||
continue
|
||||
|
|
@ -476,7 +518,7 @@ func (device *Device) InputPackets(packets []*InputPacketRef) []*InputPacketRef
|
|||
}
|
||||
elem.packet = packet[:n]
|
||||
containers := elemsByPeer[peer]
|
||||
if len(containers) == 0 || len(containers[len(containers)-1].elems) >= batchSize {
|
||||
if len(containers) == 0 || len(containers[len(containers)-1].elems) >= conn.IdealBatchSize {
|
||||
containers = append(containers, device.GetOutboundElementsContainer())
|
||||
elemsByPeer[peer] = containers
|
||||
}
|
||||
|
|
@ -678,7 +720,7 @@ func (peer *Peer) RoutineSequentialSender(maxBatchSize int) {
|
|||
}()
|
||||
device.log.Verbosef("%v - Routine: sequential sender - started", peer)
|
||||
|
||||
bufs := make([][]byte, 0, maxBatchSize)
|
||||
bufs := make([][]byte, 0, max(maxBatchSize, conn.IdealBatchSize))
|
||||
|
||||
for elemsContainer := range peer.queue.outbound.c {
|
||||
if elemsContainer == nil {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue