mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-02-21 02:01:22 +00:00
Add rate limit on receive of DIRECT_PATH_PUSH to prevent DOS exploitation.
This commit is contained in:
parent
2229e91b57
commit
5ce3aac929
@ -322,7 +322,12 @@
|
||||
/**
|
||||
* Interval between direct path pushes in milliseconds
|
||||
*/
|
||||
#define ZT_DIRECT_PATH_PUSH_INTERVAL 300000
|
||||
#define ZT_DIRECT_PATH_PUSH_INTERVAL 120000
|
||||
|
||||
/**
|
||||
* Minimum interval between direct path pushes from a given peer or we will ignore them
|
||||
*/
|
||||
#define ZT_DIRECT_PATH_PUSH_MIN_RECEIVE_INTERVAL 2500
|
||||
|
||||
/**
|
||||
* How long (max) to remember network certificates of membership?
|
||||
|
@ -861,6 +861,13 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,const Share
|
||||
bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,const SharedPtr<Peer> &peer)
|
||||
{
|
||||
try {
|
||||
const uint64_t now = RR->node->now();
|
||||
if ((now - peer->lastDirectPathPushReceived()) >= ZT_DIRECT_PATH_PUSH_MIN_RECEIVE_INTERVAL) {
|
||||
TRACE("dropped PUSH_DIRECT_PATHS from %s(%s): too frequent!",source().toString().c_str(),_remoteAddress.toString().c_str());
|
||||
return true;
|
||||
}
|
||||
peer->setLastDirectPathPushReceived(now);
|
||||
|
||||
unsigned int count = at<uint16_t>(ZT_PACKET_IDX_PAYLOAD);
|
||||
unsigned int ptr = ZT_PACKET_IDX_PAYLOAD + 2;
|
||||
unsigned int v4Count = 0,v6Count = 0;
|
||||
|
@ -52,7 +52,8 @@ Peer::Peer(const Identity &myIdentity,const Identity &peerIdentity)
|
||||
_lastMulticastFrame(0),
|
||||
_lastAnnouncedTo(0),
|
||||
_lastPathConfirmationSent(0),
|
||||
_lastDirectPathPush(0),
|
||||
_lastDirectPathPushSent(0),
|
||||
_lastDirectPathPushReceived(0),
|
||||
_lastPathSort(0),
|
||||
_vMajor(0),
|
||||
_vMinor(0),
|
||||
@ -210,8 +211,8 @@ void Peer::pushDirectPaths(const RuntimeEnvironment *RR,RemotePath *path,uint64_
|
||||
{
|
||||
Mutex::Lock _l(_lock);
|
||||
|
||||
if (((now - _lastDirectPathPush) >= ZT_DIRECT_PATH_PUSH_INTERVAL)||(force)) {
|
||||
_lastDirectPathPush = now;
|
||||
if (((now - _lastDirectPathPushSent) >= ZT_DIRECT_PATH_PUSH_INTERVAL)||(force)) {
|
||||
_lastDirectPathPushSent = now;
|
||||
|
||||
std::vector<Path> dps(RR->node->directPaths());
|
||||
if (dps.empty())
|
||||
|
@ -408,6 +408,16 @@ public:
|
||||
*/
|
||||
bool needsOurNetworkMembershipCertificate(uint64_t nwid,uint64_t now,bool updateLastPushedTime);
|
||||
|
||||
/**
|
||||
* @return Time last direct path push was received
|
||||
*/
|
||||
inline uint64_t lastDirectPathPushReceived() const throw() { return _lastDirectPathPushReceived; }
|
||||
|
||||
/**
|
||||
* @param t New time of last direct path push received
|
||||
*/
|
||||
inline void setLastDirectPathPushReceived(uint64_t t) throw() { _lastDirectPathPushReceived = t; }
|
||||
|
||||
/**
|
||||
* Perform periodic cleaning operations
|
||||
*/
|
||||
@ -438,10 +448,10 @@ public:
|
||||
{
|
||||
Mutex::Lock _l(_lock);
|
||||
|
||||
const unsigned int atPos = b.size();
|
||||
const unsigned int recSizePos = b.size();
|
||||
b.addSize(4); // space for uint32_t field length
|
||||
|
||||
b.append((uint32_t)1); // version of serialized Peer data
|
||||
b.append((uint16_t)1); // version of serialized Peer data
|
||||
|
||||
_id.serialize(b,false);
|
||||
|
||||
@ -451,7 +461,8 @@ public:
|
||||
b.append((uint64_t)_lastMulticastFrame);
|
||||
b.append((uint64_t)_lastAnnouncedTo);
|
||||
b.append((uint64_t)_lastPathConfirmationSent);
|
||||
b.append((uint64_t)_lastDirectPathPush);
|
||||
b.append((uint64_t)_lastDirectPathPushSent);
|
||||
b.append((uint64_t)_lastDirectPathPushReceived);
|
||||
b.append((uint64_t)_lastPathSort);
|
||||
b.append((uint16_t)_vProto);
|
||||
b.append((uint16_t)_vMajor);
|
||||
@ -486,7 +497,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
b.setAt(atPos,(uint32_t)(b.size() - atPos)); // set size
|
||||
b.setAt(recSizePos,(uint32_t)((b.size() - 4) - recSizePos)); // set size
|
||||
}
|
||||
|
||||
/**
|
||||
@ -500,13 +511,12 @@ public:
|
||||
template<unsigned int C>
|
||||
static inline SharedPtr<Peer> deserializeNew(const Identity &myIdentity,const Buffer<C> &b,unsigned int &p)
|
||||
{
|
||||
const uint32_t recSize = b.template at<uint32_t>(p);
|
||||
const uint32_t recSize = b.template at<uint32_t>(p); p += 4;
|
||||
if ((p + recSize) > b.size())
|
||||
return SharedPtr<Peer>(); // size invalid
|
||||
p += 4;
|
||||
if (b.template at<uint32_t>(p) != 1)
|
||||
if (b.template at<uint16_t>(p) != 1)
|
||||
return SharedPtr<Peer>(); // version mismatch
|
||||
p += 4;
|
||||
p += 2;
|
||||
|
||||
Identity npid;
|
||||
p += npid.deserialize(b,p);
|
||||
@ -521,7 +531,8 @@ public:
|
||||
np->_lastMulticastFrame = b.template at<uint64_t>(p); p += 8;
|
||||
np->_lastAnnouncedTo = b.template at<uint64_t>(p); p += 8;
|
||||
np->_lastPathConfirmationSent = b.template at<uint64_t>(p); p += 8;
|
||||
np->_lastDirectPathPush = b.template at<uint64_t>(p); p += 8;
|
||||
np->_lastDirectPathPushSent = b.template at<uint64_t>(p); p += 8;
|
||||
np->_lastDirectPathPushReceived = b.template at<uint64_t>(p); p += 8;
|
||||
np->_lastPathSort = b.template at<uint64_t>(p); p += 8;
|
||||
np->_vProto = b.template at<uint16_t>(p); p += 2;
|
||||
np->_vMajor = b.template at<uint16_t>(p); p += 2;
|
||||
@ -570,7 +581,8 @@ private:
|
||||
uint64_t _lastMulticastFrame;
|
||||
uint64_t _lastAnnouncedTo;
|
||||
uint64_t _lastPathConfirmationSent;
|
||||
uint64_t _lastDirectPathPush;
|
||||
uint64_t _lastDirectPathPushSent;
|
||||
uint64_t _lastDirectPathPushReceived;
|
||||
uint64_t _lastPathSort;
|
||||
uint16_t _vProto;
|
||||
uint16_t _vMajor;
|
||||
|
Loading…
x
Reference in New Issue
Block a user