mirror of
https://github.com/slackhq/nebula.git
synced 2026-05-16 04:47:38 +02:00
33 lines
1.2 KiB
Go
33 lines
1.2 KiB
Go
package wire
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/slackhq/nebula/overlay/tio/virtio"
|
|
)
|
|
|
|
// PerSegment invokes fn once per segment of pkt. For non-GSO pkts
|
|
// fn is called once with pkt.Bytes (no segmentation, no copy). For GSO/USO
|
|
// superpackets fn is called once per segment with a slice of pkt.Bytes
|
|
// holding that segment's plaintext (a freshly-patched L3+L4 header sliced
|
|
// in front of the original payload chunk). The slide is destructive: pkt is
|
|
// consumed by this call and its bytes are in an undefined state when
|
|
// PerSegment returns. Callers must not retain pkt or any earlier
|
|
// seg slice past fn's return for that segment. The scratch parameter is
|
|
// unused on the destructive path and kept only for cross-platform
|
|
// signature compatibility. Aborts and returns the first error from fn or
|
|
// from per-segment construction.
|
|
func (t *TunPacket) PerSegment(fn func(seg []byte) error) error {
|
|
if !t.Meta.IsSuperpacket() {
|
|
return fn(t.Bytes)
|
|
}
|
|
switch t.Meta.Proto {
|
|
case GSOProtoTCP:
|
|
return virtio.SegmentTCP(t.Bytes, t.Meta.HdrLen, t.Meta.CsumStart, t.Meta.Size, fn)
|
|
case GSOProtoUDP:
|
|
return virtio.SegmentUDP(t.Bytes, t.Meta.HdrLen, t.Meta.CsumStart, t.Meta.Size, fn)
|
|
default:
|
|
return fmt.Errorf("unsupported gso proto: %d", t.Meta.Proto)
|
|
}
|
|
}
|