diff options
| author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2013-12-24 10:39:29 -0800 |
|---|---|---|
| committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2013-12-24 10:39:29 -0800 |
| commit | 92969b442625007823dd0accf7ffec295f1ea4b1 (patch) | |
| tree | a792846c305540c4d26d84fb29a2024bb1ccaf0b /node/Peer.cpp | |
| parent | 026442f28fc6da30ce16b44cee94553a7730b2ac (diff) | |
| download | infinitytier-92969b442625007823dd0accf7ffec295f1ea4b1.tar.gz infinitytier-92969b442625007823dd0accf7ffec295f1ea4b1.zip | |
Fix for GitHub issue #20 (untested)
Diffstat (limited to 'node/Peer.cpp')
| -rw-r--r-- | node/Peer.cpp | 53 |
1 files changed, 41 insertions, 12 deletions
diff --git a/node/Peer.cpp b/node/Peer.cpp index d30a1d31..8c2c9f9b 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -28,6 +28,8 @@ #include "Peer.hpp" #include "Switch.hpp" +#include <algorithm> + namespace ZeroTier { Peer::Peer() : @@ -38,9 +40,11 @@ Peer::Peer() : _lastUnicastFrame(0), _lastMulticastFrame(0), _lastAnnouncedTo(0), + _latency(0), _vMajor(0), _vMinor(0), - _vRevision(0) + _vRevision(0), + _requestHistoryPtr(0) { } @@ -61,19 +65,44 @@ Peer::Peer(const Identity &myIdentity,const Identity &peerIdentity) throw std::runtime_error("new peer identity key agreement failed"); } -void Peer::onReceive(const RuntimeEnvironment *_r,Demarc::Port localPort,const InetAddress &remoteAddr,unsigned int hops,Packet::Verb verb,uint64_t now) +void Peer::onReceive( + const RuntimeEnvironment *_r, + Demarc::Port localPort, + const InetAddress &remoteAddr, + unsigned int hops, + uint64_t packetId, + Packet::Verb verb, + uint64_t inRePacketId, + Packet::Verb inReVerb, + uint64_t now) { if (!hops) { // direct packet - WanPath *wp = (remoteAddr.isV4() ? &_ipv4p : &_ipv6p); - wp->lastReceive = now; - wp->localPort = localPort; - if (!wp->fixed) - wp->addr = remoteAddr; - + // Announce multicast LIKEs to peers to whom we have a direct link if ((now - _lastAnnouncedTo) >= ((ZT_MULTICAST_LIKE_EXPIRE / 2) - 1000)) { _lastAnnouncedTo = now; _r->sw->announceMulticastGroups(SharedPtr<Peer>(this)); } + + // Do things like learn latency or endpoints on OK or ERROR replies + if (inReVerb != Packet::VERB_NOP) { + for(unsigned int p=0;p<ZT_PEER_REQUEST_HISTORY_LENGTH;++p) { + if ((_requestHistory[p].packetId == inRePacketId)&&(_requestHistory[p].verb == inReVerb)) { + _latency = std::min((unsigned int)(now - _requestHistory[p].timestamp),(unsigned int)0xffff); + + // Only learn paths on replies to packets we have sent, otherwise paths + // this introduces both an asymmetry problem in NAT-t and a potential + // reply DOS attack. + WanPath *const wp = (remoteAddr.isV4() ? &_ipv4p : &_ipv6p); + wp->lastReceive = now; + wp->localPort = ((localPort) ? localPort : Demarc::ANY_PORT); + if (!wp->fixed) + wp->addr = remoteAddr; + + _requestHistory[p].packetId = 0; + break; + } + } + } } if (verb == Packet::VERB_FRAME) { @@ -83,23 +112,23 @@ void Peer::onReceive(const RuntimeEnvironment *_r,Demarc::Port localPort,const I } } -bool Peer::send(const RuntimeEnvironment *_r,const void *data,unsigned int len,uint64_t now) +Demarc::Port Peer::send(const RuntimeEnvironment *_r,const void *data,unsigned int len,uint64_t now) { if ((_ipv6p.isActive(now))||((!(_ipv4p.addr))&&(_ipv6p.addr))) { if (_r->demarc->send(_ipv6p.localPort,_ipv6p.addr,data,len,-1)) { _ipv6p.lastSend = now; - return true; + return _ipv6p.localPort; } } if (_ipv4p.addr) { if (_r->demarc->send(_ipv4p.localPort,_ipv4p.addr,data,len,-1)) { _ipv4p.lastSend = now; - return true; + return _ipv4p.localPort; } } - return false; + return Demarc::NULL_PORT; } bool Peer::sendFirewallOpener(const RuntimeEnvironment *_r,uint64_t now) |
