| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970 |
- package nebula
- import "net/netip"
- // sendBatchCap is the maximum number of encrypted packets accumulated before a
- // flush is forced. TSO superpackets segment to at most ~45 packets on
- // reasonable MTUs, so 128 leaves headroom without bloating the backing
- // allocation.
- const sendBatchCap = 128
- // sendBatch accumulates encrypted UDP packets for a single sendmmsg flush.
- // One sendBatch is owned by each listenIn goroutine; no locking is needed.
- // The backing storage holds up to batchCap packets of slotCap bytes each;
- // bufs and dsts are parallel slices of committed slots.
- type sendBatch struct {
- bufs [][]byte
- dsts []netip.AddrPort
- backing []byte
- slotCap int
- batchCap int
- nextSlot int
- }
- func newSendBatch(batchCap, slotCap int) *sendBatch {
- return &sendBatch{
- bufs: make([][]byte, 0, batchCap),
- dsts: make([]netip.AddrPort, 0, batchCap),
- backing: make([]byte, batchCap*slotCap),
- slotCap: slotCap,
- batchCap: batchCap,
- }
- }
- // Next returns a zero-length slice with slotCap capacity over the next unused
- // slot's backing bytes. The caller writes into the returned slice and then
- // calls Commit with the final length and destination. Next returns nil when
- // the batch is full.
- func (b *sendBatch) Next() []byte {
- if b.nextSlot >= b.batchCap {
- return nil
- }
- start := b.nextSlot * b.slotCap
- return b.backing[start : start : start+b.slotCap]
- }
- // Commit records the slot just returned by Next as a packet of length n
- // destined for dst.
- func (b *sendBatch) Commit(n int, dst netip.AddrPort) {
- start := b.nextSlot * b.slotCap
- b.bufs = append(b.bufs, b.backing[start:start+n])
- b.dsts = append(b.dsts, dst)
- b.nextSlot++
- }
- // Reset clears committed slots; backing storage is retained for reuse.
- func (b *sendBatch) Reset() {
- b.bufs = b.bufs[:0]
- b.dsts = b.dsts[:0]
- b.nextSlot = 0
- }
- // Len returns the number of committed packets.
- func (b *sendBatch) Len() int {
- return len(b.bufs)
- }
- // Cap returns the maximum number of slots in the batch.
- func (b *sendBatch) Cap() int {
- return b.batchCap
- }
|