diff --git a/server/pcapport.cpp b/server/pcapport.cpp index cefffb3..9bd2842 100644 --- a/server/pcapport.cpp +++ b/server/pcapport.cpp @@ -127,10 +127,22 @@ void PcapPort::init() PcapPort::~PcapPort() { qDebug("In %s", __FUNCTION__); + + if (monitorRx_) + monitorRx_->stop(); + if (monitorTx_) + monitorTx_->stop(); + delete capturer_; delete transmitter_; - delete monitorTx_; + + if (monitorRx_) + monitorRx_->wait(); delete monitorRx_; + + if (monitorTx_) + monitorTx_->wait(); + delete monitorTx_; } void PcapPort::updateNotes() @@ -167,6 +179,7 @@ PcapPort::PortMonitor::PortMonitor(const char *device, Direction direction, isPromisc_ = true; noLocalCapture = true; stats_ = stats; + stop_ = false; _retry: #ifdef Q_OS_WIN32 @@ -244,7 +257,7 @@ PcapPort::PortMonitor::~PortMonitor() void PcapPort::PortMonitor::run() { - while (1) + while (!stop_) { int ret; struct pcap_pkthdr *hdr; @@ -283,12 +296,21 @@ void PcapPort::PortMonitor::run() __PRETTY_FUNCTION__, ret, pcap_geterr(handle_)); break; case -2: + qWarning("%s: error reading packet (%d): %s", + __PRETTY_FUNCTION__, ret, pcap_geterr(handle_)); + break; default: qFatal("%s: Unexpected return value %d", __PRETTY_FUNCTION__, ret); } } } +void PcapPort::PortMonitor::stop() +{ + stop_ = true; + pcap_breakloop(handle()); +} + PcapPort::PortTransmitter::PortTransmitter(const char *device) { char errbuf[PCAP_ERRBUF_SIZE] = ""; @@ -434,7 +456,7 @@ void PcapPort::PortTransmitter::setHandle(pcap_t *handle) if (usingInternalHandle_) pcap_close(handle_); handle_ = handle; - usingInternalStats_ = false; + usingInternalHandle_ = false; } void PcapPort::PortTransmitter::useExternalStats(AbstractPort::PortStats *stats) diff --git a/server/pcapport.h b/server/pcapport.h index 814528d..d05018b 100644 --- a/server/pcapport.h +++ b/server/pcapport.h @@ -82,12 +82,14 @@ protected: AbstractPort::PortStats *stats); ~PortMonitor(); void run(); + void stop(); pcap_t* handle() { return handle_; } Direction direction() { return direction_; } bool isDirectional() { return isDirectional_; } bool isPromiscuous() { return isPromisc_; } protected: AbstractPort::PortStats *stats_; + bool stop_; private: pcap_t *handle_; Direction direction_; diff --git a/server/winpcapport.cpp b/server/winpcapport.cpp index 4911581..bbd49d8 100644 --- a/server/winpcapport.cpp +++ b/server/winpcapport.cpp @@ -29,6 +29,11 @@ const uint OID_GEN_MEDIA_CONNECT_STATUS = 0x00010114; WinPcapPort::WinPcapPort(int id, const char *device) : PcapPort(id, device) { + monitorRx_->stop(); + monitorTx_->stop(); + monitorRx_->wait(); + monitorTx_->wait(); + delete monitorRx_; delete monitorTx_; @@ -140,7 +145,7 @@ void WinPcapPort::PortMonitor::run() lastTs.tv_sec = 0; lastTs.tv_usec = 0; - while (1) + while (!stop_) { int ret; struct pcap_pkthdr *hdr; @@ -205,12 +210,16 @@ void WinPcapPort::PortMonitor::run() __PRETTY_FUNCTION__, ret, pcap_geterr(handle())); break; case -2: + qWarning("%s: error reading packet (%d): %s", + __PRETTY_FUNCTION__, ret, pcap_geterr(handle())); + break; default: qFatal("%s: Unexpected return value %d", __PRETTY_FUNCTION__, ret); } lastTs.tv_sec = hdr->ts.tv_sec; lastTs.tv_usec = hdr->ts.tv_usec; - QThread::msleep(1000); + if (!stop_) + QThread::msleep(1000); } }