| 1234567891011121314151617181920212223242526272829303132 |
- 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)
- }
- }
|