diff --git a/server/abstractport.cpp b/server/abstractport.cpp index d121bcf..4aa97c6 100644 --- a/server/abstractport.cpp +++ b/server/abstractport.cpp @@ -46,6 +46,7 @@ AbstractPort::AbstractPort(int id, const char *device) linkState_ = OstProto::LinkStateUnknown; minPacketSetSize_ = 1; + maxStatsValue_ = ULLONG_MAX; // assume 64-bit stats memset((void*) &stats_, 0, sizeof(stats_)); resetStats(); } @@ -560,18 +561,34 @@ void AbstractPort::updatePacketListInterleaved() void AbstractPort::stats(PortStats *stats) { - stats->rxPkts = stats_.rxPkts - epochStats_.rxPkts; - stats->rxBytes = stats_.rxBytes - epochStats_.rxBytes; + stats->rxPkts = (stats_.rxPkts >= epochStats_.rxPkts) ? + stats_.rxPkts - epochStats_.rxPkts : + stats_.rxPkts + (maxStatsValue_ - epochStats_.rxPkts); + stats->rxBytes = (stats_.rxBytes >= epochStats_.rxBytes) ? + stats_.rxBytes - epochStats_.rxBytes : + stats_.rxBytes + (maxStatsValue_ - epochStats_.rxBytes); stats->rxPps = stats_.rxPps; stats->rxBps = stats_.rxBps; - stats->txPkts = stats_.txPkts - epochStats_.txPkts; - stats->txBytes = stats_.txBytes - epochStats_.txBytes; + stats->txPkts = (stats_.txPkts >= epochStats_.txPkts) ? + stats_.txPkts - epochStats_.txPkts : + stats_.txPkts + (maxStatsValue_ - epochStats_.txPkts); + stats->txBytes = (stats_.txBytes >= epochStats_.txBytes) ? + stats_.txBytes - epochStats_.txBytes : + stats_.txBytes + (maxStatsValue_ - epochStats_.txBytes); stats->txPps = stats_.txPps; stats->txBps = stats_.txBps; - stats->rxDrops = stats_.rxDrops - epochStats_.rxDrops; - stats->rxErrors = stats_.rxErrors - epochStats_.rxErrors; - stats->rxFifoErrors = stats_.rxFifoErrors - epochStats_.rxFifoErrors; - stats->rxFrameErrors = stats_.rxFrameErrors - epochStats_.rxFrameErrors; + stats->rxDrops = (stats_.rxDrops >= epochStats_.rxDrops) ? + stats_.rxDrops - epochStats_.rxDrops : + stats_.rxDrops + (maxStatsValue_ - epochStats_.rxDrops); + stats->rxErrors = (stats_.rxErrors >= epochStats_.rxErrors) ? + stats_.rxErrors - epochStats_.rxErrors : + stats_.rxErrors + (maxStatsValue_ - epochStats_.rxErrors); + stats->rxFifoErrors = (stats_.rxFifoErrors >= epochStats_.rxFifoErrors) ? + stats_.rxFifoErrors - epochStats_.rxFifoErrors : + stats_.rxFifoErrors + (maxStatsValue_ - epochStats_.rxFifoErrors); + stats->rxFrameErrors = (stats_.rxFrameErrors >= epochStats_.rxFrameErrors) ? + stats_.rxFrameErrors - epochStats_.rxFrameErrors : + stats_.rxFrameErrors + (maxStatsValue_ - epochStats_.rxFrameErrors); } diff --git a/server/abstractport.h b/server/abstractport.h index b9c7a6e..44f0c1d 100644 --- a/server/abstractport.h +++ b/server/abstractport.h @@ -107,6 +107,7 @@ protected: OstProto::LinkState linkState_; ulong minPacketSetSize_; + quint64 maxStatsValue_; struct PortStats stats_; //! \todo Need lock for stats access/update diff --git a/server/bsdport.cpp b/server/bsdport.cpp index 2382bcb..3229fc3 100644 --- a/server/bsdport.cpp +++ b/server/bsdport.cpp @@ -63,6 +63,8 @@ BsdPort::BsdPort(int id, const char *device) qDebug("adding dev to all ports list <%s>", device); allPorts_.append(this); + + maxStatsValue_ = ULONG_MAX; } BsdPort::~BsdPort() @@ -278,6 +280,7 @@ void BsdPort::StatsMonitor::run() { struct if_data *ifd = &(ifm->ifm_data); OstProto::LinkState *state = linkState[ifm->ifm_index]; + u_long in_packets; Q_ASSERT(state); #ifdef Q_OS_MAC @@ -287,16 +290,29 @@ void BsdPort::StatsMonitor::run() *state = (OstProto::LinkState) ifd->ifi_link_state; #endif - stats->rxPps = (ifd->ifi_ipackets + ifd->ifi_noproto - - stats->rxPkts) /kRefreshFreq_; - stats->rxBps = (ifd->ifi_ibytes - stats->rxBytes) - /kRefreshFreq_; - stats->rxPkts = ifd->ifi_ipackets + ifd->ifi_noproto; + in_packets = ifd->ifi_ipackets + ifd->ifi_noproto; + stats->rxPps = + ((in_packets >= stats->rxPkts) ? + in_packets - stats_->rxPkts : + in_packets + (maxStatsValue_ - stats_->rxPkts)) + / kRefreshFreq_; + stats->rxBps = + ((ifd->ifi_ibytes >= stats->rxBytes) > + ifd->ifi_ibytes - stats->rxBytes : + ifd->ifi_ibytes + (maxStatsValue_ - stats->rxBytes)) + / kRefreshFreq_; + stats->rxPkts = in_packets; stats->rxBytes = ifd->ifi_ibytes; - stats->txPps = (ifd->ifi_opackets - stats->txPkts) - /kRefreshFreq_; - stats->txBps = (ifd->ifi_obytes - stats->txBytes) - /kRefreshFreq_; + stats->txPps = + ((ifd->ifi_opackets >= stats->rxPkts) > + ifd->ifi_opackets - stats->rxPkts : + ifd->ifi_opackets + (maxStatsValue_ - stats->rxPkts)) + / kRefreshFreq_; + stats->txBps = + ((ifd->ifi_obytes >= stats->rxBytes) > + ifd->ifi_obytes - stats->rxBytes : + ifd->ifi_obytes + (maxStatsValue_ - stats->rxBytes)) + / kRefreshFreq_; stats->txPkts = ifd->ifi_opackets; stats->txBytes = ifd->ifi_obytes; diff --git a/server/linuxport.cpp b/server/linuxport.cpp index 74e7c46..11d09cf 100644 --- a/server/linuxport.cpp +++ b/server/linuxport.cpp @@ -58,6 +58,8 @@ LinuxPort::LinuxPort(int id, const char *device) qDebug("adding dev to all ports list <%s>", device); allPorts_.append(this); + + maxStatsValue_ = 0xffffffff; } LinuxPort::~LinuxPort() @@ -327,12 +329,28 @@ void LinuxPort::StatsMonitor::procStats() AbstractPort::PortStats *stats = portStats[index]; if (stats) { - stats->rxPps = (rxPkts - stats->rxPkts)/kRefreshFreq_; - stats->rxBps = (rxBytes - stats->rxBytes)/kRefreshFreq_; + stats->rxPps = + ((rxPkts >= stats->rxPkts) ? + rxPkts - stats->rxPkts : + rxPkts + (maxStatsValue_ - stats->rxPkts)) + / kRefreshFreq_; + stats->rxBps = + ((rxBytes >= stats->rxBytes) ? + rxBytes - stats->rxBytes : + rxBytes + (maxStatsValue_ - stats->rxBytes)) + / kRefreshFreq_; stats->rxPkts = rxPkts; stats->rxBytes = rxBytes; - stats->txPps = (txPkts - stats->txPkts)/kRefreshFreq_; - stats->txBps = (txBytes - stats->txBytes)/kRefreshFreq_; + stats->txPps = + ((txPkts >= stats->txPkts) ? + txPkts - stats->txPkts : + txPkts + (maxStatsValue_ - stats->txPkts)) + / kRefreshFreq_; + stats->txBps = + ((txBytes >= stats->txBytes) ? + txBytes - stats->txBytes : + txBytes + (maxStatsValue_ - stats->txBytes)) + / kRefreshFreq_; stats->txPkts = txPkts; stats->txBytes = txBytes; @@ -629,16 +647,32 @@ _retry_recv: if (!stats) break; - stats->rxPps = (rtnlStats->rx_packets - stats->rxPkts) - / kRefreshFreq_; - stats->rxBps = (rtnlStats->rx_bytes - stats->rxBytes) - / kRefreshFreq_; + stats->rxPps = + ((rtnlStats->rx_packets >= stats->rxPkts) ? + rtnlStats->rx_packets - stats->rxPkts : + rtnlStats->rx_packets + (maxStatsValue_ + - stats->rxPkts)) + / kRefreshFreq_; + stats->rxBps = + ((rtnlStats->rx_bytes >= stats->rxBytes) ? + rtnlStats->rx_bytes - stats->rxBytes : + rtnlStats->rx_bytes + (maxStatsValue_ + - stats->rxBytes)) + / kRefreshFreq_; stats->rxPkts = rtnlStats->rx_packets; stats->rxBytes = rtnlStats->rx_bytes; - stats->txPps = (rtnlStats->tx_packets - stats->txPkts) - / kRefreshFreq_; - stats->txBps = (rtnlStats->tx_bytes - stats->txBytes) - / kRefreshFreq_; + stats->txPps = + ((rtnlStats->tx_packets >= stats->txPkts) ? + rtnlStats->tx_packets - stats->txPkts : + rtnlStats->tx_packets + (maxStatsValue_ + - stats->txPkts)) + / kRefreshFreq_; + stats->txBps = + ((rtnlStats->tx_bytes >= stats->txBytes) ? + rtnlStats->tx_bytes - stats->txBytes : + rtnlStats->tx_bytes + (maxStatsValue_ + - stats->txBytes)) + / kRefreshFreq_; stats->txPkts = rtnlStats->tx_packets; stats->txBytes = rtnlStats->tx_bytes;