From 781437fe6f8c77b8629f66eec0d0f33e4bc7d284 Mon Sep 17 00:00:00 2001 From: evilsocket Date: Tue, 27 Feb 2018 13:28:57 +0100 Subject: [PATCH] fix: fixing pcap handles w/r ops synchronization here and there (ref #88) --- modules/dhcp6_spoof.go | 19 ++++++++++--------- modules/dns_spoof.go | 17 +++++++++-------- modules/net_sniff.go | 9 ++++++--- packets/queue.go | 25 ++++++++++++++++++------- 4 files changed, 43 insertions(+), 27 deletions(-) diff --git a/modules/dhcp6_spoof.go b/modules/dhcp6_spoof.go index 785cc8d7..7e360088 100644 --- a/modules/dhcp6_spoof.go +++ b/modules/dhcp6_spoof.go @@ -26,12 +26,13 @@ import ( type DHCP6Spoofer struct { session.SessionModule - Handle *pcap.Handle - DUID *dhcp6opts.DUIDLLT - DUIDRaw []byte - Domains []string - RawDomains []byte - waitGroup *sync.WaitGroup + Handle *pcap.Handle + DUID *dhcp6opts.DUIDLLT + DUIDRaw []byte + Domains []string + RawDomains []byte + waitGroup *sync.WaitGroup + pktSourceChan chan gopacket.Packet } func NewDHCP6Spoofer(s *session.Session) *DHCP6Spoofer { @@ -360,13 +361,12 @@ func (s *DHCP6Spoofer) Start() error { } return s.SetRunning(true, func() { - defer s.Handle.Close() - s.waitGroup.Add(1) defer s.waitGroup.Done() src := gopacket.NewPacketSource(s.Handle, s.Handle.LinkType()) - for packet := range src.Packets() { + s.pktSourceChan = src.Packets() + for packet := range s.pktSourceChan { if s.Running() == false { break } @@ -378,6 +378,7 @@ func (s *DHCP6Spoofer) Start() error { func (s *DHCP6Spoofer) Stop() error { return s.SetRunning(false, func() { + s.pktSourceChan <- nil s.Handle.Close() s.waitGroup.Wait() }) diff --git a/modules/dns_spoof.go b/modules/dns_spoof.go index b3d534be..1c2a607f 100644 --- a/modules/dns_spoof.go +++ b/modules/dns_spoof.go @@ -19,11 +19,12 @@ import ( type DNSSpoofer struct { session.SessionModule - Handle *pcap.Handle - Domains []string - Address net.IP - All bool - waitGroup *sync.WaitGroup + Handle *pcap.Handle + Domains []string + Address net.IP + All bool + waitGroup *sync.WaitGroup + pktSourceChan chan gopacket.Packet } func NewDNSSpoofer(s *session.Session) *DNSSpoofer { @@ -273,10 +274,9 @@ func (s *DNSSpoofer) Start() error { s.waitGroup.Add(1) defer s.waitGroup.Done() - defer s.Handle.Close() - src := gopacket.NewPacketSource(s.Handle, s.Handle.LinkType()) - for packet := range src.Packets() { + s.pktSourceChan = src.Packets() + for packet := range s.pktSourceChan { if s.Running() == false { break } @@ -288,6 +288,7 @@ func (s *DNSSpoofer) Start() error { func (s *DNSSpoofer) Stop() error { return s.SetRunning(false, func() { + s.pktSourceChan <- nil s.Handle.Close() s.waitGroup.Wait() }) diff --git a/modules/net_sniff.go b/modules/net_sniff.go index 548a2ae4..6888e049 100644 --- a/modules/net_sniff.go +++ b/modules/net_sniff.go @@ -14,8 +14,9 @@ import ( type Sniffer struct { session.SessionModule - Stats *SnifferStats - Ctx *SnifferContext + Stats *SnifferStats + Ctx *SnifferContext + pktSourceChan chan gopacket.Packet } func NewSniffer(s *session.Session) *Sniffer { @@ -148,7 +149,8 @@ func (s *Sniffer) Start() error { s.Stats = NewSnifferStats() src := gopacket.NewPacketSource(s.Ctx.Handle, s.Ctx.Handle.LinkType()) - for packet := range src.Packets() { + s.pktSourceChan = src.Packets() + for packet := range s.pktSourceChan { if s.Running() == false { break } @@ -183,6 +185,7 @@ func (s *Sniffer) Start() error { func (s *Sniffer) Stop() error { return s.SetRunning(false, func() { + s.pktSourceChan <- nil s.Ctx.Close() }) } diff --git a/packets/queue.go b/packets/queue.go index cfc7b064..5d49d4ab 100644 --- a/packets/queue.go +++ b/packets/queue.go @@ -44,11 +44,13 @@ type Queue struct { Protos map[string]uint64 Traffic map[string]*Traffic - iface *network.Endpoint - handle *pcap.Handle - source *gopacket.PacketSource - pktCb PacketCallback - active bool + iface *network.Endpoint + handle *pcap.Handle + source *gopacket.PacketSource + srcChannel chan gopacket.Packet + writes *sync.WaitGroup + pktCb PacketCallback + active bool } func NewQueue(iface *network.Endpoint) (q *Queue, err error) { @@ -57,6 +59,7 @@ func NewQueue(iface *network.Endpoint) (q *Queue, err error) { Traffic: make(map[string]*Traffic), Activities: make(chan Activity), + writes: &sync.WaitGroup{}, iface: iface, active: !iface.IsMonitor(), pktCb: nil, @@ -68,6 +71,7 @@ func NewQueue(iface *network.Endpoint) (q *Queue, err error) { } q.source = gopacket.NewPacketSource(q.handle, q.handle.LinkType()) + q.srcChannel = q.source.Packets() go q.worker() } @@ -138,7 +142,7 @@ func (q *Queue) trackActivity(eth *layers.Ethernet, ip4 *layers.IPv4, address ne } func (q *Queue) worker() { - for pkt := range q.source.Packets() { + for pkt := range q.srcChannel { if q.active == false { return } @@ -192,6 +196,9 @@ func (q *Queue) Send(raw []byte) error { return fmt.Errorf("Packet queue is not active.") } + q.writes.Add(1) + defer q.writes.Done() + if err := q.handle.WritePacketData(raw); err != nil { q.Stats.Lock() q.Stats.Errors++ @@ -211,7 +218,11 @@ func (q *Queue) Stop() { defer q.Unlock() if q.active == true { - q.handle.Close() + // wait for write operations to be completed + q.writes.Wait() + // signal the main loop to exit and close the handle q.active = false + q.srcChannel <- nil + q.handle.Close() } }