From 8edb74e57276c712444ccfb89ed40dd0ca5c39d6 Mon Sep 17 00:00:00 2001 From: Leonid Bugaev Date: Wed, 7 Jul 2021 20:50:47 +0300 Subject: [PATCH] Add support for "go" timestamp source Windows having issues with generating timestamps, so adding application level timestamp generation Made small refactoring to move "accurate-enough" time to own package. --- capture/capture.go | 8 +++++++- simpletime/time.go | 17 +++++++++++++++++ tcp/tcp_message.go | 5 +++-- tcp/tcp_packet.go | 16 ++++------------ 4 files changed, 31 insertions(+), 15 deletions(-) create mode 100644 simpletime/time.go diff --git a/capture/capture.go b/capture/capture.go index 93fb668..c56e6a4 100644 --- a/capture/capture.go +++ b/capture/capture.go @@ -229,9 +229,10 @@ func (l *Listener) PcapHandle(ifi pcap.Interface) (handle *pcap.Handle, err erro } defer inactive.CleanUp() - if l.TimestampType != "" { + if l.TimestampType != "" && l.TimestampType != "go" { var ts pcap.TimestampSource ts, err = pcap.TimestampSourceFromString(l.TimestampType) + fmt.Println("Setting custom Timestamp Source. Supported values: `simple`, ", inactive.SupportedTimestamps()) err = inactive.SetTimestampSource(ts) if err != nil { return nil, fmt.Errorf("%q: supported timestamps: %q, interface: %q", err, inactive.SupportedTimestamps(), ifi.Name) @@ -345,7 +346,12 @@ func (l *Listener) read(handler PacketHandler) { default: data, ci, err := hndl.handler.ZeroCopyReadPacketData() if err == nil { + if l.TimestampType == "go" { + ci.Timestamp = time.Now() + } + pckt, err := tcp.ParsePacket(data, linkType, linkSize, &ci, false) + if err == nil { for _, p := range l.ports { if pckt.DstPort == p { diff --git a/simpletime/time.go b/simpletime/time.go new file mode 100644 index 0000000..12d9deb --- /dev/null +++ b/simpletime/time.go @@ -0,0 +1,17 @@ +package simpletime + +import ( + "time" +) + +var Now time.Time + +func init() { + go func() { + for { + // Accurate enough + Now = time.Now() + time.Sleep(100 * time.Millisecond) + } + }() +} diff --git a/tcp/tcp_message.go b/tcp/tcp_message.go index 70d6e71..e89d5f8 100644 --- a/tcp/tcp_message.go +++ b/tcp/tcp_message.go @@ -9,6 +9,7 @@ import ( "time" "unsafe" + "github.com/buger/goreplay/simpletime" "github.com/buger/goreplay/size" ) @@ -39,7 +40,7 @@ func NewBufferPool(max int, ttl int) *bufPool { for i := 0; i < 100; i++ { select { case c := <-pool.buffers: - if now.Sub(c.created) < time.Duration(ttl)*time.Second { + if simpletime.Now.Sub(c.created) < time.Duration(ttl)*time.Second { select { case pool.buffers <- c: default: @@ -81,7 +82,7 @@ func (p *bufPool) Get() *buf { c = new(buf) c.b = make([]byte, 1024) - c.created = now + c.created = simpletime.Now // Use this technique to find if pool leaks, and objects get GCd // diff --git a/tcp/tcp_packet.go b/tcp/tcp_packet.go index 4a20331..3358be4 100644 --- a/tcp/tcp_packet.go +++ b/tcp/tcp_packet.go @@ -9,6 +9,8 @@ import ( "runtime/debug" "time" + "github.com/buger/goreplay/simpletime" + "github.com/google/gopacket" ) @@ -31,8 +33,6 @@ func copySlice(to []byte, from ...[]byte) ([]byte, int) { return to, i } -var now time.Time - var stats *expvar.Map var bufPoolCount *expvar.Int var releasedCount *expvar.Int @@ -45,14 +45,6 @@ func init() { stats.Init() stats.Set("buffer_pool_count", bufPoolCount) stats.Set("buffer_released", releasedCount) - - go func() { - for { - // Accurate enough - now = time.Now() - time.Sleep(500 * time.Millisecond) - } - }() } var packetPool = NewPacketPool(10000, 1) @@ -79,7 +71,7 @@ func NewPacketPool(max int, ttl int) *pktPool { select { case c := <-pool.packets: // GC If buffer is too big and lived for too long - if len(c.buf) < 8192 || now.Sub(c.created) < time.Duration(ttl)*time.Second { + if len(c.buf) < 8192 || simpletime.Now.Sub(c.created) < time.Duration(ttl)*time.Second { select { case pool.packets <- c: // Jump to next item in for loop @@ -120,7 +112,7 @@ func (p *pktPool) Get() *Packet { default: stats.Add("active_packet_count", 1) c = new(Packet) - c.created = now + c.created = simpletime.Now // Use this technique to find if pool leaks, and objects get GCd //