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:
1 parent
cb2cdc90cc
commit
7c4464c852
2 files changed
+21
-9
No files matched your search
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user