Skip to content

Commit

Permalink
Making pcapgo Writer routine safe
Browse files Browse the repository at this point in the history
  • Loading branch information
gboddin committed Oct 22, 2023
1 parent 32ee382 commit f10efb8
Showing 1 changed file with 29 additions and 24 deletions.
53 changes: 29 additions & 24 deletions pcapgo/write.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"encoding/binary"
"fmt"
"io"
"sync"
"time"

"github.com/google/gopacket"
Expand All @@ -27,6 +28,8 @@ type Writer struct {
tsScaler int
// Moving this into the struct seems to save an allocation for each call to writePacketHeader
buf [16]byte
// Make sure our writer is routine safe
writeLock sync.Mutex
}

const magicMicroseconds = 0xA1B2C3D4
Expand All @@ -38,18 +41,18 @@ const versionMinor = 4
// an append), you must call WriteFileHeader before WritePacket. Packet
// timestamps are written with nanosecond precision.
//
// // Write a new file:
// f, _ := os.Create("/tmp/file.pcap")
// w := pcapgo.NewWriterNanos(f)
// w.WriteFileHeader(65536, layers.LinkTypeEthernet) // new file, must do this.
// w.WritePacket(gopacket.CaptureInfo{...}, data1)
// f.Close()
// // Append to existing file (must have same snaplen and linktype)
// f2, _ := os.OpenFile("/tmp/fileNano.pcap", os.O_APPEND, 0700)
// w2 := pcapgo.NewWriter(f2)
// // no need for file header, it's already written.
// w2.WritePacket(gopacket.CaptureInfo{...}, data2)
// f2.Close()
// // Write a new file:
// f, _ := os.Create("/tmp/file.pcap")
// w := pcapgo.NewWriterNanos(f)
// w.WriteFileHeader(65536, layers.LinkTypeEthernet) // new file, must do this.
// w.WritePacket(gopacket.CaptureInfo{...}, data1)
// f.Close()
// // Append to existing file (must have same snaplen and linktype)
// f2, _ := os.OpenFile("/tmp/fileNano.pcap", os.O_APPEND, 0700)
// w2 := pcapgo.NewWriter(f2)
// // no need for file header, it's already written.
// w2.WritePacket(gopacket.CaptureInfo{...}, data2)
// f2.Close()
func NewWriterNanos(w io.Writer) *Writer {
return &Writer{w: w, tsScaler: nanosPerNano}
}
Expand All @@ -59,18 +62,18 @@ func NewWriterNanos(w io.Writer) *Writer {
// an append), you must call WriteFileHeader before WritePacket.
// Packet timestamps are written witn microsecond precision.
//
// // Write a new file:
// f, _ := os.Create("/tmp/file.pcap")
// w := pcapgo.NewWriter(f)
// w.WriteFileHeader(65536, layers.LinkTypeEthernet) // new file, must do this.
// w.WritePacket(gopacket.CaptureInfo{...}, data1)
// f.Close()
// // Append to existing file (must have same snaplen and linktype)
// f2, _ := os.OpenFile("/tmp/file.pcap", os.O_APPEND, 0700)
// w2 := pcapgo.NewWriter(f2)
// // no need for file header, it's already written.
// w2.WritePacket(gopacket.CaptureInfo{...}, data2)
// f2.Close()
// // Write a new file:
// f, _ := os.Create("/tmp/file.pcap")
// w := pcapgo.NewWriter(f)
// w.WriteFileHeader(65536, layers.LinkTypeEthernet) // new file, must do this.
// w.WritePacket(gopacket.CaptureInfo{...}, data1)
// f.Close()
// // Append to existing file (must have same snaplen and linktype)
// f2, _ := os.OpenFile("/tmp/file.pcap", os.O_APPEND, 0700)
// w2 := pcapgo.NewWriter(f2)
// // no need for file header, it's already written.
// w2.WritePacket(gopacket.CaptureInfo{...}, data2)
// f2.Close()
func NewWriter(w io.Writer) *Writer {
return &Writer{w: w, tsScaler: nanosPerMicro}
}
Expand Down Expand Up @@ -115,6 +118,8 @@ func (w *Writer) writePacketHeader(ci gopacket.CaptureInfo) error {

// WritePacket writes the given packet data out to the file.
func (w *Writer) WritePacket(ci gopacket.CaptureInfo, data []byte) error {
w.writeLock.Lock()
defer w.writeLock.Unlock()
if ci.CaptureLength != len(data) {
return fmt.Errorf("capture length %d does not match data length %d", ci.CaptureLength, len(data))
}
Expand Down

0 comments on commit f10efb8

Please sign in to comment.