fix: fixing pcap handles w/r ops synchronization here and there (ref #88)

This commit is contained in:
evilsocket 2018-02-27 13:28:57 +01:00
parent b2e559a206
commit 781437fe6f
4 changed files with 43 additions and 27 deletions

View file

@ -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()
})

View file

@ -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()
})

View file

@ -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()
})
}

View file

@ -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()
}
}