diff options
Diffstat (limited to 'pkg/tcpip/link/sniffer/sniffer.go')
-rw-r--r-- | pkg/tcpip/link/sniffer/sniffer.go | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/pkg/tcpip/link/sniffer/sniffer.go b/pkg/tcpip/link/sniffer/sniffer.go index 232a26a18..3df826f3c 100644 --- a/pkg/tcpip/link/sniffer/sniffer.go +++ b/pkg/tcpip/link/sniffer/sniffer.go @@ -113,8 +113,9 @@ func writePCAPHeader(w io.Writer, maxLen uint32) error { // NewWithWriter creates a new sniffer link-layer endpoint. It wraps around // another endpoint and logs packets as they traverse the endpoint. // -// Packets are logged to writer in the pcap format. A sniffer created with this -// function will not emit packets using the standard log package. +// Each packet is written to writer in the pcap format in a single Write call +// without synchronization. A sniffer created with this function will not emit +// packets using the standard log package. // // snapLen is the maximum amount of a packet to be saved. Packets with a length // less than or equal to snapLen will be saved in their entirety. Longer @@ -155,27 +156,29 @@ func (e *endpoint) dumpPacket(dir direction, protocol tcpip.NetworkProtocolNumbe if max := int(e.maxPCAPLen); length > max { length = max } - if err := binary.Write(writer, binary.BigEndian, newPCAPPacketHeader(time.Now(), uint32(length), uint32(totalLength))); err != nil { - panic(err) - } - write := func(b []byte) { - if len(b) > length { - b = b[:length] + packetHeader := newPCAPPacketHeader(time.Now(), uint32(length), uint32(totalLength)) + packet := make([]byte, binary.Size(packetHeader)+length) + { + writer := tcpip.SliceWriter(packet) + if err := binary.Write(&writer, binary.BigEndian, packetHeader); err != nil { + panic(err) } - for len(b) != 0 { + for _, b := range pkt.Views() { + if length == 0 { + break + } + if len(b) > length { + b = b[:length] + } n, err := writer.Write(b) if err != nil { panic(err) } - b = b[n:] length -= n } } - for _, v := range pkt.Views() { - if length == 0 { - break - } - write(v) + if _, err := writer.Write(packet); err != nil { + panic(err) } } } |