|
@@ -21,6 +21,7 @@
|
|
|
|
|
|
#include <stdint.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
#include <string.h>
|
|
|
|
+#include <stdlib.h>
|
|
|
|
|
|
#include <stdexcept>
|
|
#include <stdexcept>
|
|
#include <algorithm>
|
|
#include <algorithm>
|
|
@@ -30,6 +31,7 @@
|
|
#include "SharedPtr.hpp"
|
|
#include "SharedPtr.hpp"
|
|
#include "AtomicCounter.hpp"
|
|
#include "AtomicCounter.hpp"
|
|
#include "NonCopyable.hpp"
|
|
#include "NonCopyable.hpp"
|
|
|
|
+#include "Utils.hpp"
|
|
|
|
|
|
/**
|
|
/**
|
|
* Maximum return value of preferenceRank()
|
|
* Maximum return value of preferenceRank()
|
|
@@ -105,22 +107,34 @@ public:
|
|
_lastOut(0),
|
|
_lastOut(0),
|
|
_lastIn(0),
|
|
_lastIn(0),
|
|
_lastTrustEstablishedPacketReceived(0),
|
|
_lastTrustEstablishedPacketReceived(0),
|
|
|
|
+ _incomingLinkQualityFastLog(0xffffffffffffffffULL),
|
|
|
|
+ _incomingLinkQualitySlowLogPtr(0),
|
|
|
|
+ _incomingLinkQualitySlowLogCounter(-64), // discard first fast log
|
|
|
|
+ _incomingLinkQualityPreviousPacketCounter(0),
|
|
_outgoingPacketCounter(0),
|
|
_outgoingPacketCounter(0),
|
|
_addr(),
|
|
_addr(),
|
|
_localAddress(),
|
|
_localAddress(),
|
|
_ipScope(InetAddress::IP_SCOPE_NONE)
|
|
_ipScope(InetAddress::IP_SCOPE_NONE)
|
|
{
|
|
{
|
|
|
|
+ for(int i=0;i<(int)sizeof(_incomingLinkQualitySlowLog);++i)
|
|
|
|
+ _incomingLinkQualitySlowLog[i] = ZT_PATH_LINK_QUALITY_MAX;
|
|
}
|
|
}
|
|
|
|
|
|
Path(const InetAddress &localAddress,const InetAddress &addr) :
|
|
Path(const InetAddress &localAddress,const InetAddress &addr) :
|
|
_lastOut(0),
|
|
_lastOut(0),
|
|
_lastIn(0),
|
|
_lastIn(0),
|
|
_lastTrustEstablishedPacketReceived(0),
|
|
_lastTrustEstablishedPacketReceived(0),
|
|
|
|
+ _incomingLinkQualityFastLog(0xffffffffffffffffULL),
|
|
|
|
+ _incomingLinkQualitySlowLogPtr(0),
|
|
|
|
+ _incomingLinkQualitySlowLogCounter(-64), // discard first fast log
|
|
|
|
+ _incomingLinkQualityPreviousPacketCounter(0),
|
|
_outgoingPacketCounter(0),
|
|
_outgoingPacketCounter(0),
|
|
_addr(addr),
|
|
_addr(addr),
|
|
_localAddress(localAddress),
|
|
_localAddress(localAddress),
|
|
_ipScope(addr.ipScope())
|
|
_ipScope(addr.ipScope())
|
|
{
|
|
{
|
|
|
|
+ for(int i=0;i<(int)sizeof(_incomingLinkQualitySlowLog);++i)
|
|
|
|
+ _incomingLinkQualitySlowLog[i] = ZT_PATH_LINK_QUALITY_MAX;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -130,6 +144,39 @@ public:
|
|
*/
|
|
*/
|
|
inline void received(const uint64_t t) { _lastIn = t; }
|
|
inline void received(const uint64_t t) { _lastIn = t; }
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Update link quality using a counter from an incoming packet (or packet head in fragmented case)
|
|
|
|
+ *
|
|
|
|
+ * @param counter Packet link quality counter (range 0 to 7, must not have other bits set)
|
|
|
|
+ */
|
|
|
|
+ inline void updateLinkQuality(const unsigned int counter)
|
|
|
|
+ {
|
|
|
|
+ const unsigned int prev = _incomingLinkQualityPreviousPacketCounter;
|
|
|
|
+ _incomingLinkQualityPreviousPacketCounter = counter;
|
|
|
|
+ const uint64_t fl = (_incomingLinkQualityFastLog = ((_incomingLinkQualityFastLog << 1) | (uint64_t)(prev == ((counter - 1) & 0x7))));
|
|
|
|
+ if (++_incomingLinkQualitySlowLogCounter >= 64) {
|
|
|
|
+ _incomingLinkQualitySlowLogCounter = 0;
|
|
|
|
+ _incomingLinkQualitySlowLog[_incomingLinkQualitySlowLogPtr++ % sizeof(_incomingLinkQualitySlowLog)] = Utils::countBits(fl);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * @return Link quality from 0 (min) to 255 (max)
|
|
|
|
+ */
|
|
|
|
+ inline unsigned int linkQuality() const
|
|
|
|
+ {
|
|
|
|
+ unsigned long slsize = _incomingLinkQualitySlowLogPtr;
|
|
|
|
+ if (slsize > (unsigned long)sizeof(_incomingLinkQualitySlowLog))
|
|
|
|
+ slsize = (unsigned long)sizeof(_incomingLinkQualitySlowLog);
|
|
|
|
+ else if (!slsize)
|
|
|
|
+ return 255; // ZT_PATH_LINK_QUALITY_MAX
|
|
|
|
+ unsigned long lq = 0;
|
|
|
|
+ for(unsigned long i=0;i<slsize;++i)
|
|
|
|
+ lq += (unsigned long)_incomingLinkQualitySlowLog[i] * 4;
|
|
|
|
+ lq /= slsize;
|
|
|
|
+ return (unsigned int)((lq >= 255) ? 255 : lq);
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Set time last trusted packet was received (done in Peer::received())
|
|
* Set time last trusted packet was received (done in Peer::received())
|
|
*/
|
|
*/
|
|
@@ -251,13 +298,18 @@ public:
|
|
inline unsigned int nextOutgoingCounter() { return _outgoingPacketCounter++; }
|
|
inline unsigned int nextOutgoingCounter() { return _outgoingPacketCounter++; }
|
|
|
|
|
|
private:
|
|
private:
|
|
- uint64_t _lastOut;
|
|
|
|
- uint64_t _lastIn;
|
|
|
|
- uint64_t _lastTrustEstablishedPacketReceived;
|
|
|
|
- unsigned int _outgoingPacketCounter;
|
|
|
|
|
|
+ volatile uint64_t _lastOut;
|
|
|
|
+ volatile uint64_t _lastIn;
|
|
|
|
+ volatile uint64_t _lastTrustEstablishedPacketReceived;
|
|
|
|
+ volatile uint64_t _incomingLinkQualityFastLog;
|
|
|
|
+ volatile unsigned long _incomingLinkQualitySlowLogPtr;
|
|
|
|
+ volatile signed int _incomingLinkQualitySlowLogCounter;
|
|
|
|
+ volatile unsigned int _incomingLinkQualityPreviousPacketCounter;
|
|
|
|
+ volatile unsigned int _outgoingPacketCounter;
|
|
InetAddress _addr;
|
|
InetAddress _addr;
|
|
InetAddress _localAddress;
|
|
InetAddress _localAddress;
|
|
InetAddress::IpScope _ipScope; // memoize this since it's a computed value checked often
|
|
InetAddress::IpScope _ipScope; // memoize this since it's a computed value checked often
|
|
|
|
+ volatile uint8_t _incomingLinkQualitySlowLog[32];
|
|
AtomicCounter __refCount;
|
|
AtomicCounter __refCount;
|
|
};
|
|
};
|
|
|
|
|