summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/link
diff options
context:
space:
mode:
authorTamir Duberstein <tamird@google.com>2021-07-12 12:21:49 -0700
committergVisor bot <gvisor-bot@google.com>2021-07-12 12:24:17 -0700
commit4742f7d788e784aa2d86f81aecaef2039caad01c (patch)
treeb0022f4ecd1a5ed6402cd67c8a4493a92beee9d6 /pkg/tcpip/link
parent1f396d8c16e179aa5b7b9ea1da6b16fb0b167016 (diff)
Prevent interleaving in sniffer pcap output
Remove "partial write" handling as io.Writer.Write is not permitted to return a nil error on partial writes, and this code was already panicking on non-nil errors. PiperOrigin-RevId: 384289970
Diffstat (limited to 'pkg/tcpip/link')
-rw-r--r--pkg/tcpip/link/sniffer/pcap.go2
-rw-r--r--pkg/tcpip/link/sniffer/sniffer.go33
2 files changed, 18 insertions, 17 deletions
diff --git a/pkg/tcpip/link/sniffer/pcap.go b/pkg/tcpip/link/sniffer/pcap.go
index 45475dcf1..3bb864ed2 100644
--- a/pkg/tcpip/link/sniffer/pcap.go
+++ b/pkg/tcpip/link/sniffer/pcap.go
@@ -39,8 +39,6 @@ type pcapHeader struct {
Network uint32
}
-const pcapPacketHeaderLen = 16
-
type pcapPacketHeader struct {
// Seconds is the timestamp seconds.
Seconds uint32
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)
}
}
}