mirror of
https://github.com/slackhq/nebula.git
synced 2025-11-22 00:15:37 +01:00
reduce copying
This commit is contained in:
10
interface.go
10
interface.go
@@ -297,7 +297,10 @@ func (f *Interface) listenIn(reader io.ReadWriteCloser, i int) {
|
|||||||
|
|
||||||
func (f *Interface) listenInSingle(reader io.ReadWriteCloser, i int) {
|
func (f *Interface) listenInSingle(reader io.ReadWriteCloser, i int) {
|
||||||
packet := make([]byte, mtu)
|
packet := make([]byte, mtu)
|
||||||
out := make([]byte, mtu)
|
// Allocate out buffer with virtio header headroom (10 bytes) to avoid copies on write
|
||||||
|
const virtioNetHdrLen = 10
|
||||||
|
outBuf := make([]byte, virtioNetHdrLen+mtu)
|
||||||
|
out := outBuf[virtioNetHdrLen:] // Use slice starting after headroom
|
||||||
fwPacket := &firewall.Packet{}
|
fwPacket := &firewall.Packet{}
|
||||||
nb := make([]byte, 12, 12)
|
nb := make([]byte, 12, 12)
|
||||||
|
|
||||||
@@ -321,6 +324,7 @@ func (f *Interface) listenInSingle(reader io.ReadWriteCloser, i int) {
|
|||||||
|
|
||||||
func (f *Interface) listenInBatch(reader io.ReadWriteCloser, batchReader BatchReader, i int) {
|
func (f *Interface) listenInBatch(reader io.ReadWriteCloser, batchReader BatchReader, i int) {
|
||||||
batchSize := batchReader.BatchSize()
|
batchSize := batchReader.BatchSize()
|
||||||
|
const virtioNetHdrLen = 10
|
||||||
|
|
||||||
// Allocate buffers for batch reading
|
// Allocate buffers for batch reading
|
||||||
bufs := make([][]byte, batchSize)
|
bufs := make([][]byte, batchSize)
|
||||||
@@ -330,7 +334,9 @@ func (f *Interface) listenInBatch(reader io.ReadWriteCloser, batchReader BatchRe
|
|||||||
sizes := make([]int, batchSize)
|
sizes := make([]int, batchSize)
|
||||||
|
|
||||||
// Per-packet state (reused across batches)
|
// Per-packet state (reused across batches)
|
||||||
out := make([]byte, mtu)
|
// Allocate out buffer with virtio header headroom to avoid copies on write
|
||||||
|
outBuf := make([]byte, virtioNetHdrLen+mtu)
|
||||||
|
out := outBuf[virtioNetHdrLen:]
|
||||||
fwPacket := &firewall.Packet{}
|
fwPacket := &firewall.Packet{}
|
||||||
nb := make([]byte, 12, 12)
|
nb := make([]byte, 12, 12)
|
||||||
|
|
||||||
|
|||||||
@@ -92,9 +92,24 @@ func (w *wgDeviceWrapper) Read(b []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *wgDeviceWrapper) Write(b []byte) (int, error) {
|
func (w *wgDeviceWrapper) Write(b []byte) (int, error) {
|
||||||
// Allocate buffer with space for virtio header
|
// Check if buffer has the expected headroom pattern to avoid copy
|
||||||
buf := make([]byte, virtioNetHdrLen+len(b))
|
var buf []byte
|
||||||
copy(buf[virtioNetHdrLen:], b)
|
|
||||||
|
if cap(b) >= len(b)+virtioNetHdrLen {
|
||||||
|
buf = b[:cap(b)]
|
||||||
|
if len(buf) == len(b)+virtioNetHdrLen {
|
||||||
|
// Perfect! Buffer has headroom, no copy needed
|
||||||
|
buf = buf[:len(b)+virtioNetHdrLen]
|
||||||
|
} else {
|
||||||
|
// Unexpected capacity, safer to copy
|
||||||
|
buf = make([]byte, virtioNetHdrLen+len(b))
|
||||||
|
copy(buf[virtioNetHdrLen:], b)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// No headroom, need to allocate and copy
|
||||||
|
buf = make([]byte, virtioNetHdrLen+len(b))
|
||||||
|
copy(buf[virtioNetHdrLen:], b)
|
||||||
|
}
|
||||||
|
|
||||||
bufs := [][]byte{buf}
|
bufs := [][]byte{buf}
|
||||||
n, err := w.dev.Write(bufs, virtioNetHdrLen)
|
n, err := w.dev.Write(bufs, virtioNetHdrLen)
|
||||||
@@ -404,9 +419,28 @@ func (t *tun) BatchSize() int {
|
|||||||
func (t *tun) Write(b []byte) (int, error) {
|
func (t *tun) Write(b []byte) (int, error) {
|
||||||
if t.wgDevice != nil {
|
if t.wgDevice != nil {
|
||||||
// Use wireguard device which handles virtio headers internally
|
// Use wireguard device which handles virtio headers internally
|
||||||
// Allocate buffer with space for virtio header
|
// Check if buffer has the expected headroom pattern:
|
||||||
buf := make([]byte, virtioNetHdrLen+len(b))
|
// cap(b) should be len(b) + virtioNetHdrLen, indicating pre-allocated headroom
|
||||||
copy(buf[virtioNetHdrLen:], b)
|
var buf []byte
|
||||||
|
|
||||||
|
if cap(b) >= len(b)+virtioNetHdrLen {
|
||||||
|
// Buffer likely has headroom - use unsafe to access it
|
||||||
|
// Create a slice that includes the headroom by re-slicing from capacity
|
||||||
|
buf = b[:cap(b)]
|
||||||
|
// Check if we have exactly the right amount of extra capacity
|
||||||
|
if len(buf) == len(b)+virtioNetHdrLen {
|
||||||
|
// Perfect! This buffer was allocated with headroom, no copy needed
|
||||||
|
buf = buf[:len(b)+virtioNetHdrLen]
|
||||||
|
} else {
|
||||||
|
// Unexpected capacity, safer to copy
|
||||||
|
buf = make([]byte, virtioNetHdrLen+len(b))
|
||||||
|
copy(buf[virtioNetHdrLen:], b)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// No headroom, need to allocate and copy
|
||||||
|
buf = make([]byte, virtioNetHdrLen+len(b))
|
||||||
|
copy(buf[virtioNetHdrLen:], b)
|
||||||
|
}
|
||||||
|
|
||||||
bufs := [][]byte{buf}
|
bufs := [][]byte{buf}
|
||||||
n, err := t.wgDevice.Write(bufs, virtioNetHdrLen)
|
n, err := t.wgDevice.Write(bufs, virtioNetHdrLen)
|
||||||
|
|||||||
Reference in New Issue
Block a user