Added rate gates for QOS and ACK packets

This commit is contained in:
Joseph Henry 2018-06-07 15:26:18 -07:00
parent b9975845ff
commit b6d97af451
3 changed files with 49 additions and 0 deletions

View File

@ -274,6 +274,23 @@
*/ */
#define ZT_MULTIPATH_BINDER_REFRESH_PERIOD 5000 #define ZT_MULTIPATH_BINDER_REFRESH_PERIOD 5000
/**
* Time horizon for VERB_QOS_MEASUREMENT and VERB_ACK packet processesing cutoff
*/
#define ZT_PATH_QOS_ACK_CUTOFF_TIME 30000
/**
* Maximum number of VERB_QOS_MEASUREMENT and VERB_ACK packets allowed to be
* processesed within cutoff time. Separate totals are kept for each type but
* the limit is the same for both.
*
* This limits how often this peer will compute statistical estimates
* of various QoS measures from a VERB_QOS_MEASUREMENT or VERB_ACK packets to
* CUTOFF_LIMIT times per CUTOFF_TIME milliseconds per peer to prevent
* this from being useful for DOS amplification attacks.
*/
#define ZT_PATH_QOS_ACK_CUTOFF_LIMIT 16
/** /**
* Path choice history window size. This is used to keep track of which paths were * Path choice history window size. This is used to keep track of which paths were
* previously selected so that we can maintain a target allocation over time. * previously selected so that we can maintain a target allocation over time.

View File

@ -204,6 +204,8 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,void *tPtr,const Shar
bool IncomingPacket::_doACK(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer) bool IncomingPacket::_doACK(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer)
{ {
if (!peer->rateGateACK(RR->node->now()))
return true;
/* Dissect incoming ACK packet. From this we can estimate current throughput of the path, establish known /* Dissect incoming ACK packet. From this we can estimate current throughput of the path, establish known
* maximums and detect packet loss. */ * maximums and detect packet loss. */
if (peer->localMultipathSupport()) { if (peer->localMultipathSupport()) {
@ -220,6 +222,8 @@ bool IncomingPacket::_doACK(const RuntimeEnvironment *RR,void *tPtr,const Shared
} }
bool IncomingPacket::_doQOS_MEASUREMENT(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer) bool IncomingPacket::_doQOS_MEASUREMENT(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer)
{ {
if (!peer->rateGateQoS(RR->node->now()))
return true;
/* Dissect incoming QoS packet. From this we can compute latency values and their variance. /* Dissect incoming QoS packet. From this we can compute latency values and their variance.
* The latency variance is used as a measure of "jitter". */ * The latency variance is used as a measure of "jitter". */
if (peer->localMultipathSupport()) { if (peer->localMultipathSupport()) {

View File

@ -523,6 +523,30 @@ public:
return false; return false;
} }
/**
* Rate limit gate for VERB_QOS_MEASUREMENT
*/
inline bool rateGateQoS(const int64_t now)
{
if ((now - _lastQoSReceive) <= ZT_PATH_QOS_ACK_CUTOFF_TIME)
++_QoSCutoffCount;
else _QoSCutoffCount = 0;
_lastQoSReceive = now;
return (_QoSCutoffCount < ZT_PATH_QOS_ACK_CUTOFF_LIMIT);
}
/**
* Rate limit gate for VERB_ACK
*/
inline bool rateGateACK(const int64_t now)
{
if ((now - _lastACKReceive) <= ZT_PATH_QOS_ACK_CUTOFF_TIME)
++_ACKCutoffCount;
else _ACKCutoffCount = 0;
_lastACKReceive = now;
return (_ACKCutoffCount < ZT_PATH_QOS_ACK_CUTOFF_LIMIT);
}
/** /**
* Serialize a peer for storage in local cache * Serialize a peer for storage in local cache
* *
@ -620,6 +644,8 @@ private:
int64_t _lastComRequestSent; int64_t _lastComRequestSent;
int64_t _lastCredentialsReceived; int64_t _lastCredentialsReceived;
int64_t _lastTrustEstablishedPacketReceived; int64_t _lastTrustEstablishedPacketReceived;
int64_t _lastQoSReceive;
int64_t _lastACKReceive;
int64_t _lastSentFullHello; int64_t _lastSentFullHello;
int64_t _lastPathPrune; int64_t _lastPathPrune;
@ -635,6 +661,8 @@ private:
unsigned int _directPathPushCutoffCount; unsigned int _directPathPushCutoffCount;
unsigned int _credentialsCutoffCount; unsigned int _credentialsCutoffCount;
unsigned int _QoSCutoffCount;
unsigned int _ACKCutoffCount;
AtomicCounter __refCount; AtomicCounter __refCount;