pcap handles are not thread safe

they contain an errbuf; there might be other issues too.
So we must use different handles in the sniffer and udplistener
goroutines.
This commit is contained in:
Matthias Radestock committed 2014-08-20 11:42:55 +01:00
1 parent cb2cdc90cc
commit 7c4464c852
2 files changed
+21 -9

No files matched your search

+13 -3
View File
@@ -8,16 +8,26 @@ type PcapIO struct {
handle *pcap.Handle
}
func NewPcapIO(ifName string, bufSz int) (handle *PcapIO, err error) {
func NewPcapIO(ifName string, bufSz int) (pio PacketSourceSink, err error) {
pio, err = newPcapIO(ifName, true, 65535, bufSz)
return
}
func NewPcapO(ifName string) (po PacketSink, err error) {
po, err = newPcapIO(ifName, false, 0, 0)
return
}
func newPcapIO(ifName string, promisc bool, snaplen int, bufSz int) (handle *PcapIO, err error) {
inactive, err := pcap.NewInactiveHandle(ifName)
if err != nil {
return
}
defer inactive.CleanUp()
if inactive.SetPromisc(true) != nil {
if inactive.SetPromisc(promisc) != nil {
return
}
if inactive.SetSnapLen(65535) != nil {
if inactive.SetSnapLen(snaplen) != nil {
return
}
if inactive.SetTimeout(-1) != nil {
+8 -6
View File
@@ -38,13 +38,11 @@ func (router *Router) UsingPassword() bool {
}
func (router *Router) Start() {
pio, err := NewPcapIO(router.Iface.Name, router.BufSz)
checkFatal(err)
router.ConnectionMaker = StartConnectionMaker(router)
router.Topology = StartTopology(router)
router.UDPListener = router.listenUDP(Port, pio)
router.UDPListener = router.listenUDP(Port)
router.listenTCP(Port)
router.sniff(pio)
router.sniff()
}
func (router *Router) Status() string {
@@ -58,7 +56,9 @@ func (router *Router) Status() string {
return buf.String()
}
func (router *Router) sniff(pio PacketSourceSink) {
func (router *Router) sniff() {
pio, err := NewPcapIO(router.Iface.Name, router.BufSz)
checkFatal(err)
log.Println("Sniffing traffic on", router.Iface)
dec := NewEthernetDecoder()
@@ -141,7 +141,7 @@ func (router *Router) acceptTCP(tcpConn *net.TCPConn) {
NewLocalConnection(connRemote, UnknownPeerName, tcpConn, nil, router)
}
func (router *Router) listenUDP(localPort int, po PacketSink) *net.UDPConn {
func (router *Router) listenUDP(localPort int) *net.UDPConn {
localAddr, err := net.ResolveUDPAddr("udp4", fmt.Sprint(":", localPort))
checkFatal(err)
conn, err := net.ListenUDP("udp4", localAddr)
@@ -153,6 +153,8 @@ func (router *Router) listenUDP(localPort int, po PacketSink) *net.UDPConn {
// This one makes sure all packets we send out do not have DF set on them.
err = syscall.SetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_MTU_DISCOVER, syscall.IP_PMTUDISC_DONT)
checkFatal(err)
po, err := NewPcapO(router.Iface.Name)
checkFatal(err)
go router.udpReader(conn, po)
return conn
}