mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-01-29 15:43:52 +00:00
Outgoing side of packet counter for link quality reporting. Also some cleanup and a cluster mode build fix.
This commit is contained in:
parent
127bcb02ff
commit
2bf9145ae6
@ -79,8 +79,7 @@ public:
|
||||
inline const_reverse_iterator rbegin() const { return const_reverse_iterator(begin()); }
|
||||
inline const_reverse_iterator rend() const { return const_reverse_iterator(end()); }
|
||||
|
||||
Buffer()
|
||||
throw() :
|
||||
Buffer() :
|
||||
_l(0)
|
||||
{
|
||||
}
|
||||
@ -419,87 +418,70 @@ public:
|
||||
/**
|
||||
* Set buffer data length to zero
|
||||
*/
|
||||
inline void clear()
|
||||
throw()
|
||||
{
|
||||
_l = 0;
|
||||
}
|
||||
inline void clear() { _l = 0; }
|
||||
|
||||
/**
|
||||
* Zero buffer up to size()
|
||||
*/
|
||||
inline void zero()
|
||||
throw()
|
||||
{
|
||||
memset(_b,0,_l);
|
||||
}
|
||||
inline void zero() { memset(_b,0,_l); }
|
||||
|
||||
/**
|
||||
* Zero unused capacity area
|
||||
*/
|
||||
inline void zeroUnused()
|
||||
throw()
|
||||
{
|
||||
memset(_b + _l,0,C - _l);
|
||||
}
|
||||
inline void zeroUnused() { memset(_b + _l,0,C - _l); }
|
||||
|
||||
/**
|
||||
* Unconditionally and securely zero buffer's underlying memory
|
||||
*/
|
||||
inline void burn()
|
||||
throw()
|
||||
{
|
||||
Utils::burn(_b,sizeof(_b));
|
||||
}
|
||||
inline void burn() { Utils::burn(_b,sizeof(_b)); }
|
||||
|
||||
/**
|
||||
* @return Constant pointer to data in buffer
|
||||
*/
|
||||
inline const void *data() const throw() { return _b; }
|
||||
inline const void *data() const { return _b; }
|
||||
|
||||
/**
|
||||
* @return Non-constant pointer to data in buffer
|
||||
*/
|
||||
inline void *unsafeData() { return _b; }
|
||||
|
||||
/**
|
||||
* @return Size of data in buffer
|
||||
*/
|
||||
inline unsigned int size() const throw() { return _l; }
|
||||
inline unsigned int size() const { return _l; }
|
||||
|
||||
/**
|
||||
* @return Capacity of buffer
|
||||
*/
|
||||
inline unsigned int capacity() const throw() { return C; }
|
||||
inline unsigned int capacity() const { return C; }
|
||||
|
||||
template<unsigned int C2>
|
||||
inline bool operator==(const Buffer<C2> &b) const
|
||||
throw()
|
||||
{
|
||||
return ((_l == b._l)&&(!memcmp(_b,b._b,_l)));
|
||||
}
|
||||
template<unsigned int C2>
|
||||
inline bool operator!=(const Buffer<C2> &b) const
|
||||
throw()
|
||||
{
|
||||
return ((_l != b._l)||(memcmp(_b,b._b,_l)));
|
||||
}
|
||||
template<unsigned int C2>
|
||||
inline bool operator<(const Buffer<C2> &b) const
|
||||
throw()
|
||||
{
|
||||
return (memcmp(_b,b._b,std::min(_l,b._l)) < 0);
|
||||
}
|
||||
template<unsigned int C2>
|
||||
inline bool operator>(const Buffer<C2> &b) const
|
||||
throw()
|
||||
{
|
||||
return (b < *this);
|
||||
}
|
||||
template<unsigned int C2>
|
||||
inline bool operator<=(const Buffer<C2> &b) const
|
||||
throw()
|
||||
{
|
||||
return !(b < *this);
|
||||
}
|
||||
template<unsigned int C2>
|
||||
inline bool operator>=(const Buffer<C2> &b) const
|
||||
throw()
|
||||
{
|
||||
return !(*this < b);
|
||||
}
|
||||
|
@ -255,7 +255,7 @@ void Cluster::handleIncomingStateMessage(const void *msg,unsigned int len)
|
||||
// One-time-use Poly1305 key from first 32 bytes of Salsa20 keystream (as per DJB/NaCl "standard")
|
||||
char polykey[ZT_POLY1305_KEY_LEN];
|
||||
memset(polykey,0,sizeof(polykey));
|
||||
s20.encrypt12(polykey,polykey,sizeof(polykey));
|
||||
s20.crypt12(polykey,polykey,sizeof(polykey));
|
||||
|
||||
// Compute 16-byte MAC
|
||||
char mac[ZT_POLY1305_MAC_LEN];
|
||||
@ -267,7 +267,7 @@ void Cluster::handleIncomingStateMessage(const void *msg,unsigned int len)
|
||||
|
||||
// Decrypt!
|
||||
dmsg.setSize(len - 24);
|
||||
s20.decrypt12(reinterpret_cast<const char *>(msg) + 24,const_cast<void *>(dmsg.data()),dmsg.size());
|
||||
s20.crypt12(reinterpret_cast<const char *>(msg) + 24,const_cast<void *>(dmsg.data()),dmsg.size());
|
||||
}
|
||||
|
||||
if (dmsg.size() < 4)
|
||||
@ -954,10 +954,10 @@ void Cluster::_flush(uint16_t memberId)
|
||||
// One-time-use Poly1305 key from first 32 bytes of Salsa20 keystream (as per DJB/NaCl "standard")
|
||||
char polykey[ZT_POLY1305_KEY_LEN];
|
||||
memset(polykey,0,sizeof(polykey));
|
||||
s20.encrypt12(polykey,polykey,sizeof(polykey));
|
||||
s20.crypt12(polykey,polykey,sizeof(polykey));
|
||||
|
||||
// Encrypt m.q in place
|
||||
s20.encrypt12(reinterpret_cast<const char *>(m.q.data()) + 24,const_cast<char *>(reinterpret_cast<const char *>(m.q.data())) + 24,m.q.size() - 24);
|
||||
s20.crypt12(reinterpret_cast<const char *>(m.q.data()) + 24,const_cast<char *>(reinterpret_cast<const char *>(m.q.data())) + 24,m.q.size() - 24);
|
||||
|
||||
// Add MAC for authentication (encrypt-then-MAC)
|
||||
char mac[ZT_POLY1305_MAC_LEN];
|
||||
|
@ -243,7 +243,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,const bool alreadyAut
|
||||
outp.append((uint8_t)Packet::VERB_HELLO);
|
||||
outp.append((uint64_t)pid);
|
||||
outp.append((uint8_t)Packet::ERROR_IDENTITY_COLLISION);
|
||||
outp.armor(key,true);
|
||||
outp.armor(key,true,_path->nextOutgoingCounter());
|
||||
_path->send(RR,outp.data(),outp.size(),RR->node->now());
|
||||
} else {
|
||||
TRACE("rejected HELLO from %s(%s): packet failed authentication",id.address().toString().c_str(),_path->address().toString().c_str());
|
||||
@ -405,7 +405,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,const bool alreadyAut
|
||||
RR->topology->appendCertificateOfRepresentation(outp);
|
||||
outp.setAt(corSizeAt,(uint16_t)(outp.size() - (corSizeAt + 2)));
|
||||
|
||||
outp.armor(peer->key(),true);
|
||||
outp.armor(peer->key(),true,_path->nextOutgoingCounter());
|
||||
_path->send(RR,outp.data(),outp.size(),now);
|
||||
|
||||
peer->setRemoteVersion(protoVersion,vMajor,vMinor,vRevision); // important for this to go first so received() knows the version
|
||||
@ -584,7 +584,7 @@ bool IncomingPacket::_doWHOIS(const RuntimeEnvironment *RR,const SharedPtr<Peer>
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
outp.armor(peer->key(),true);
|
||||
outp.armor(peer->key(),true,_path->nextOutgoingCounter());
|
||||
_path->send(RR,outp.data(),outp.size(),RR->node->now());
|
||||
}
|
||||
|
||||
@ -610,7 +610,7 @@ bool IncomingPacket::_doRENDEZVOUS(const RuntimeEnvironment *RR,const SharedPtr<
|
||||
const InetAddress atAddr(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRESS,addrlen),addrlen,port);
|
||||
if (RR->node->shouldUsePathForZeroTierTraffic(with,_path->localAddress(),atAddr)) {
|
||||
RR->node->putPacket(_path->localAddress(),atAddr,"ABRE",4,2); // send low-TTL junk packet to 'open' local NAT(s) and stateful firewalls
|
||||
rendezvousWith->attemptToContactAt(_path->localAddress(),atAddr,RR->node->now(),false);
|
||||
rendezvousWith->attemptToContactAt(_path->localAddress(),atAddr,RR->node->now(),false,0);
|
||||
TRACE("RENDEZVOUS from %s says %s might be at %s, sent verification attempt",peer->address().toString().c_str(),with.toString().c_str(),atAddr.toString().c_str());
|
||||
} else {
|
||||
TRACE("RENDEZVOUS from %s says %s might be at %s, ignoring since path is not suitable",peer->address().toString().c_str(),with.toString().c_str(),atAddr.toString().c_str());
|
||||
@ -732,7 +732,7 @@ bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment *RR,const SharedPtr<P
|
||||
outp.append((uint8_t)Packet::VERB_EXT_FRAME);
|
||||
outp.append((uint64_t)packetId());
|
||||
outp.append((uint64_t)nwid);
|
||||
outp.armor(peer->key(),true);
|
||||
outp.armor(peer->key(),true,_path->nextOutgoingCounter());
|
||||
_path->send(RR,outp.data(),outp.size(),RR->node->now());
|
||||
}
|
||||
|
||||
@ -762,7 +762,7 @@ bool IncomingPacket::_doECHO(const RuntimeEnvironment *RR,const SharedPtr<Peer>
|
||||
outp.append((uint64_t)pid);
|
||||
if (size() > ZT_PACKET_IDX_PAYLOAD)
|
||||
outp.append(reinterpret_cast<const unsigned char *>(data()) + ZT_PACKET_IDX_PAYLOAD,size() - ZT_PACKET_IDX_PAYLOAD);
|
||||
outp.armor(peer->key(),true);
|
||||
outp.armor(peer->key(),true,_path->nextOutgoingCounter());
|
||||
_path->send(RR,outp.data(),outp.size(),RR->node->now());
|
||||
|
||||
peer->received(_path,hops(),pid,Packet::VERB_ECHO,0,Packet::VERB_NOP,false);
|
||||
@ -957,7 +957,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons
|
||||
outp.append(requestPacketId);
|
||||
outp.append((unsigned char)Packet::ERROR_UNSUPPORTED_OPERATION);
|
||||
outp.append(nwid);
|
||||
outp.armor(peer->key(),true);
|
||||
outp.armor(peer->key(),true,_path->nextOutgoingCounter());
|
||||
_path->send(RR,outp.data(),outp.size(),RR->node->now());
|
||||
}
|
||||
|
||||
@ -984,7 +984,7 @@ bool IncomingPacket::_doNETWORK_CONFIG(const RuntimeEnvironment *RR,const Shared
|
||||
outp.append((uint64_t)packetId());
|
||||
outp.append((uint64_t)network->id());
|
||||
outp.append((uint64_t)configUpdateId);
|
||||
outp.armor(peer->key(),true);
|
||||
outp.armor(peer->key(),true,_path->nextOutgoingCounter());
|
||||
_path->send(RR,outp.data(),outp.size(),RR->node->now());
|
||||
}
|
||||
}
|
||||
@ -1033,7 +1033,7 @@ bool IncomingPacket::_doMULTICAST_GATHER(const RuntimeEnvironment *RR,const Shar
|
||||
outp.append((uint32_t)mg.adi());
|
||||
const unsigned int gatheredLocally = RR->mc->gather(peer->address(),nwid,mg,outp,gatherLimit);
|
||||
if (gatheredLocally > 0) {
|
||||
outp.armor(peer->key(),true);
|
||||
outp.armor(peer->key(),true,_path->nextOutgoingCounter());
|
||||
_path->send(RR,outp.data(),outp.size(),RR->node->now());
|
||||
}
|
||||
|
||||
@ -1140,7 +1140,7 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,const Share
|
||||
outp.append((uint32_t)to.adi());
|
||||
outp.append((unsigned char)0x02); // flag 0x02 = contains gather results
|
||||
if (RR->mc->gather(peer->address(),nwid,to,outp,gatherLimit)) {
|
||||
outp.armor(peer->key(),true);
|
||||
outp.armor(peer->key(),true,_path->nextOutgoingCounter());
|
||||
_path->send(RR,outp.data(),outp.size(),RR->node->now());
|
||||
}
|
||||
}
|
||||
@ -1198,7 +1198,7 @@ bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,const Sha
|
||||
if ( ((flags & ZT_PUSH_DIRECT_PATHS_FLAG_FORGET_PATH) == 0) && (!redundant) && (RR->node->shouldUsePathForZeroTierTraffic(peer->address(),_path->localAddress(),a)) ) {
|
||||
if (++countPerScope[(int)a.ipScope()][0] <= ZT_PUSH_DIRECT_PATHS_MAX_PER_SCOPE_AND_FAMILY) {
|
||||
TRACE("attempting to contact %s at pushed direct path %s",peer->address().toString().c_str(),a.toString().c_str());
|
||||
peer->attemptToContactAt(InetAddress(),a,now,false);
|
||||
peer->attemptToContactAt(InetAddress(),a,now,false,0);
|
||||
} else {
|
||||
TRACE("ignoring contact for %s at %s -- too many per scope",peer->address().toString().c_str(),a.toString().c_str());
|
||||
}
|
||||
@ -1217,7 +1217,7 @@ bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,const Sha
|
||||
if ( ((flags & ZT_PUSH_DIRECT_PATHS_FLAG_FORGET_PATH) == 0) && (!redundant) && (RR->node->shouldUsePathForZeroTierTraffic(peer->address(),_path->localAddress(),a)) ) {
|
||||
if (++countPerScope[(int)a.ipScope()][1] <= ZT_PUSH_DIRECT_PATHS_MAX_PER_SCOPE_AND_FAMILY) {
|
||||
TRACE("attempting to contact %s at pushed direct path %s",peer->address().toString().c_str(),a.toString().c_str());
|
||||
peer->attemptToContactAt(InetAddress(),a,now,false);
|
||||
peer->attemptToContactAt(InetAddress(),a,now,false,0);
|
||||
} else {
|
||||
TRACE("ignoring contact for %s at %s -- too many per scope",peer->address().toString().c_str(),a.toString().c_str());
|
||||
}
|
||||
@ -1447,7 +1447,7 @@ void IncomingPacket::_sendErrorNeedCredentials(const RuntimeEnvironment *RR,cons
|
||||
outp.append(packetId());
|
||||
outp.append((uint8_t)Packet::ERROR_NEED_MEMBERSHIP_CERTIFICATE);
|
||||
outp.append(nwid);
|
||||
outp.armor(peer->key(),true);
|
||||
outp.armor(peer->key(),true,_path->nextOutgoingCounter());
|
||||
_path->send(RR,outp.data(),outp.size(),now);
|
||||
}
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ public:
|
||||
for(unsigned long k=0,ptr=(unsigned long)RR->node->prng();k<(unsigned long)upstreamStableEndpoints->size();++k) {
|
||||
const InetAddress &addr = (*upstreamStableEndpoints)[ptr++ % upstreamStableEndpoints->size()];
|
||||
if (addr.ss_family == AF_INET) {
|
||||
p->sendHELLO(InetAddress(),addr,_now);
|
||||
p->sendHELLO(InetAddress(),addr,_now,0);
|
||||
contacted = true;
|
||||
break;
|
||||
}
|
||||
@ -190,7 +190,7 @@ public:
|
||||
for(unsigned long k=0,ptr=(unsigned long)RR->node->prng();k<(unsigned long)upstreamStableEndpoints->size();++k) {
|
||||
const InetAddress &addr = (*upstreamStableEndpoints)[ptr++ % upstreamStableEndpoints->size()];
|
||||
if (addr.ss_family == AF_INET6) {
|
||||
p->sendHELLO(InetAddress(),addr,_now);
|
||||
p->sendHELLO(InetAddress(),addr,_now,0);
|
||||
contacted = true;
|
||||
break;
|
||||
}
|
||||
@ -200,7 +200,7 @@ public:
|
||||
if ((!contacted)&&(_bestCurrentUpstream)) {
|
||||
const SharedPtr<Path> up(_bestCurrentUpstream->getBestPath(_now,true));
|
||||
if (up)
|
||||
p->sendHELLO(up->localAddress(),up->address(),_now);
|
||||
p->sendHELLO(up->localAddress(),up->address(),_now,up->nextOutgoingCounter());
|
||||
}
|
||||
|
||||
lastReceiveFromUpstream = std::max(p->lastReceive(),lastReceiveFromUpstream);
|
||||
|
1784
node/Packet.cpp
1784
node/Packet.cpp
File diff suppressed because it is too large
Load Diff
@ -351,7 +351,7 @@ namespace ZeroTier {
|
||||
* ZeroTier packet
|
||||
*
|
||||
* Packet format:
|
||||
* <[8] 64-bit random packet ID and crypto initialization vector>
|
||||
* <[8] 64-bit packet ID / crypto IV / packet counter>
|
||||
* <[5] destination ZT address>
|
||||
* <[5] source ZT address>
|
||||
* <[1] flags/cipher/hops>
|
||||
@ -362,6 +362,14 @@ namespace ZeroTier {
|
||||
*
|
||||
* Packets smaller than 28 bytes are invalid and silently discarded.
|
||||
*
|
||||
* The 64-bit packet ID is a strongly random value used as a crypto IV.
|
||||
* Its least significant 3 bits are also used as a monotonically increasing
|
||||
* (and looping) counter for sending packets to a particular recipient. This
|
||||
* can be used for link quality monitoring and reporting and has no crypto
|
||||
* impact as it does not increase the likelihood of an IV collision. (The
|
||||
* crypto we use is not sensitive to the nature of the IV, only that it does
|
||||
* not repeat.)
|
||||
*
|
||||
* The flags/cipher/hops bit field is: FFCCCHHH where C is a 3-bit cipher
|
||||
* selection allowing up to 7 cipher suites, F is outside-envelope flags,
|
||||
* and H is hop count.
|
||||
@ -1102,10 +1110,8 @@ public:
|
||||
};
|
||||
|
||||
#ifdef ZT_TRACE
|
||||
static const char *verbString(Verb v)
|
||||
throw();
|
||||
static const char *errorString(ErrorCode e)
|
||||
throw();
|
||||
static const char *verbString(Verb v);
|
||||
static const char *errorString(ErrorCode e);
|
||||
#endif
|
||||
|
||||
template<unsigned int C2>
|
||||
@ -1303,6 +1309,12 @@ public:
|
||||
/**
|
||||
* Get this packet's unique ID (the IV field interpreted as uint64_t)
|
||||
*
|
||||
* Note that the least significant 3 bits of this ID will change when armor()
|
||||
* is called to armor the packet for transport. This is because armor() will
|
||||
* mask the last 3 bits against the send counter for QoS monitoring use prior
|
||||
* to actually using the IV to encrypt and MAC the packet. Be aware of this
|
||||
* when grabbing the packetId of a new packet prior to armor/send.
|
||||
*
|
||||
* @return Packet ID
|
||||
*/
|
||||
inline uint64_t packetId() const { return at<uint64_t>(ZT_PACKET_IDX_IV); }
|
||||
@ -1337,8 +1349,9 @@ public:
|
||||
*
|
||||
* @param key 32-byte key
|
||||
* @param encryptPayload If true, encrypt packet payload, else just MAC
|
||||
* @param counter Packet send counter for destination peer -- only least significant 3 bits are used
|
||||
*/
|
||||
void armor(const void *key,bool encryptPayload);
|
||||
void armor(const void *key,bool encryptPayload,unsigned int counter);
|
||||
|
||||
/**
|
||||
* Verify and (if encrypted) decrypt packet
|
||||
|
@ -105,6 +105,7 @@ public:
|
||||
_lastOut(0),
|
||||
_lastIn(0),
|
||||
_lastTrustEstablishedPacketReceived(0),
|
||||
_outgoingPacketCounter(0),
|
||||
_addr(),
|
||||
_localAddress(),
|
||||
_ipScope(InetAddress::IP_SCOPE_NONE)
|
||||
@ -115,6 +116,7 @@ public:
|
||||
_lastOut(0),
|
||||
_lastIn(0),
|
||||
_lastTrustEstablishedPacketReceived(0),
|
||||
_outgoingPacketCounter(0),
|
||||
_addr(addr),
|
||||
_localAddress(localAddress),
|
||||
_ipScope(addr.ipScope())
|
||||
@ -241,10 +243,18 @@ public:
|
||||
*/
|
||||
inline uint64_t lastIn() const { return _lastIn; }
|
||||
|
||||
/**
|
||||
* Return and increment outgoing packet counter (used with Packet::armor())
|
||||
*
|
||||
* @return Next value that should be used for outgoing packet counter (only least significant 3 bits are used)
|
||||
*/
|
||||
inline unsigned int nextOutgoingCounter() { return _outgoingPacketCounter++; }
|
||||
|
||||
private:
|
||||
uint64_t _lastOut;
|
||||
uint64_t _lastIn;
|
||||
uint64_t _lastTrustEstablishedPacketReceived;
|
||||
unsigned int _outgoingPacketCounter;
|
||||
InetAddress _addr;
|
||||
InetAddress _localAddress;
|
||||
InetAddress::IpScope _ipScope; // memoize this since it's a computed value checked often
|
||||
|
@ -101,7 +101,7 @@ void Peer::received(
|
||||
outp.append(redirectTo.rawIpData(),16);
|
||||
}
|
||||
outp.append((uint16_t)redirectTo.port());
|
||||
outp.armor(_key,true);
|
||||
outp.armor(_key,true,path->nextOutgoingCounter());
|
||||
path->send(RR,outp.data(),outp.size(),now);
|
||||
} else {
|
||||
// For older peers we use RENDEZVOUS to coax them into contacting us elsewhere.
|
||||
@ -116,7 +116,7 @@ void Peer::received(
|
||||
outp.append((uint8_t)16);
|
||||
outp.append(redirectTo.rawIpData(),16);
|
||||
}
|
||||
outp.armor(_key,true);
|
||||
outp.armor(_key,true,path->nextOutgoingCounter());
|
||||
path->send(RR,outp.data(),outp.size(),now);
|
||||
}
|
||||
suboptimalPath = true;
|
||||
@ -203,7 +203,7 @@ void Peer::received(
|
||||
#endif
|
||||
} else {
|
||||
TRACE("got %s via unknown path %s(%s), confirming...",Packet::verbString(verb),_id.address().toString().c_str(),path->address().toString().c_str());
|
||||
attemptToContactAt(path->localAddress(),path->address(),now,true);
|
||||
attemptToContactAt(path->localAddress(),path->address(),now,true,path->nextOutgoingCounter());
|
||||
path->sent(now);
|
||||
}
|
||||
}
|
||||
@ -277,7 +277,7 @@ void Peer::received(
|
||||
|
||||
if (count) {
|
||||
outp.setAt(ZT_PACKET_IDX_PAYLOAD,(uint16_t)count);
|
||||
outp.armor(_key,true);
|
||||
outp.armor(_key,true,path->nextOutgoingCounter());
|
||||
path->send(RR,outp.data(),outp.size(),now);
|
||||
}
|
||||
}
|
||||
@ -342,7 +342,7 @@ SharedPtr<Path> Peer::getBestPath(uint64_t now,bool includeExpired)
|
||||
}
|
||||
}
|
||||
|
||||
void Peer::sendHELLO(const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now)
|
||||
void Peer::sendHELLO(const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now,unsigned int counter)
|
||||
{
|
||||
Packet outp(_id.address(),RR->identity.address(),Packet::VERB_HELLO);
|
||||
|
||||
@ -383,22 +383,22 @@ void Peer::sendHELLO(const InetAddress &localAddr,const InetAddress &atAddress,u
|
||||
RR->node->expectReplyTo(outp.packetId());
|
||||
|
||||
if (atAddress) {
|
||||
outp.armor(_key,false); // false == don't encrypt full payload, but add MAC
|
||||
outp.armor(_key,false,counter); // false == don't encrypt full payload, but add MAC
|
||||
RR->node->putPacket(localAddr,atAddress,outp.data(),outp.size());
|
||||
} else {
|
||||
RR->sw->send(outp,false); // false == don't encrypt full payload, but add MAC
|
||||
}
|
||||
}
|
||||
|
||||
void Peer::attemptToContactAt(const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now,bool sendFullHello)
|
||||
void Peer::attemptToContactAt(const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now,bool sendFullHello,unsigned int counter)
|
||||
{
|
||||
if ( (!sendFullHello) && (_vProto >= 5) && (!((_vMajor == 1)&&(_vMinor == 1)&&(_vRevision == 0))) ) {
|
||||
Packet outp(_id.address(),RR->identity.address(),Packet::VERB_ECHO);
|
||||
RR->node->expectReplyTo(outp.packetId());
|
||||
outp.armor(_key,true);
|
||||
outp.armor(_key,true,counter);
|
||||
RR->node->putPacket(localAddr,atAddress,outp.data(),outp.size());
|
||||
} else {
|
||||
sendHELLO(localAddr,atAddress,now);
|
||||
sendHELLO(localAddr,atAddress,now,counter);
|
||||
}
|
||||
}
|
||||
|
||||
@ -408,7 +408,7 @@ void Peer::tryMemorizedPath(uint64_t now)
|
||||
_lastTriedMemorizedPath = now;
|
||||
InetAddress mp;
|
||||
if (RR->node->externalPathLookup(_id.address(),-1,mp))
|
||||
attemptToContactAt(InetAddress(),mp,now,true);
|
||||
attemptToContactAt(InetAddress(),mp,now,true,0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -430,7 +430,7 @@ bool Peer::doPingAndKeepalive(uint64_t now,int inetAddressFamily)
|
||||
|
||||
if (bestp >= 0) {
|
||||
if ( ((now - _paths[bestp].lastReceive) >= ZT_PEER_PING_PERIOD) || (_paths[bestp].path->needsHeartbeat(now)) ) {
|
||||
attemptToContactAt(_paths[bestp].path->localAddress(),_paths[bestp].path->address(),now,false);
|
||||
attemptToContactAt(_paths[bestp].path->localAddress(),_paths[bestp].path->address(),now,false,_paths[bestp].path->nextOutgoingCounter());
|
||||
_paths[bestp].path->sent(now);
|
||||
}
|
||||
return true;
|
||||
@ -454,7 +454,7 @@ void Peer::resetWithinScope(InetAddress::IpScope scope,int inetAddressFamily,uin
|
||||
Mutex::Lock _l(_paths_m);
|
||||
for(unsigned int p=0;p<_numPaths;++p) {
|
||||
if ( (_paths[p].path->address().ss_family == inetAddressFamily) && (_paths[p].path->address().ipScope() == scope) ) {
|
||||
attemptToContactAt(_paths[p].path->localAddress(),_paths[p].path->address(),now,false);
|
||||
attemptToContactAt(_paths[p].path->localAddress(),_paths[p].path->address(),now,false,_paths[p].path->nextOutgoingCounter());
|
||||
_paths[p].path->sent(now);
|
||||
_paths[p].lastReceive = 0; // path will not be used unless it speaks again
|
||||
}
|
||||
|
@ -150,8 +150,9 @@ public:
|
||||
* @param localAddr Local address
|
||||
* @param atAddress Destination address
|
||||
* @param now Current time
|
||||
* @param counter Outgoing packet counter
|
||||
*/
|
||||
void sendHELLO(const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now);
|
||||
void sendHELLO(const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now,unsigned int counter);
|
||||
|
||||
/**
|
||||
* Send ECHO (or HELLO for older peers) to this peer at the given address
|
||||
@ -162,8 +163,9 @@ public:
|
||||
* @param atAddress Destination address
|
||||
* @param now Current time
|
||||
* @param sendFullHello If true, always send a full HELLO instead of just an ECHO
|
||||
* @param counter Outgoing packet counter
|
||||
*/
|
||||
void attemptToContactAt(const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now,bool sendFullHello);
|
||||
void attemptToContactAt(const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now,bool sendFullHello,unsigned int counter);
|
||||
|
||||
/**
|
||||
* Try a memorized or statically defined path if any are known
|
||||
|
@ -88,7 +88,7 @@ void Switch::onRemotePacket(const InetAddress &localAddr,const InetAddress &from
|
||||
if ((now - _lastBeaconResponse) >= 2500) { // limit rate of responses
|
||||
_lastBeaconResponse = now;
|
||||
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_NOP);
|
||||
outp.armor(peer->key(),true);
|
||||
outp.armor(peer->key(),true,path->nextOutgoingCounter());
|
||||
path->send(RR,outp.data(),outp.size(),now);
|
||||
}
|
||||
}
|
||||
@ -777,7 +777,7 @@ bool Switch::_trySend(Packet &packet,bool encrypt)
|
||||
if ((clusterMostRecentMemberId < 0)||(viaPath->lastIn() > clusterMostRecentTs)) {
|
||||
#endif
|
||||
if ((now - viaPath->lastOut()) > std::max((now - viaPath->lastIn()) * 4,(uint64_t)ZT_PATH_MIN_REACTIVATE_INTERVAL)) {
|
||||
peer->attemptToContactAt(viaPath->localAddress(),viaPath->address(),now,false);
|
||||
peer->attemptToContactAt(viaPath->localAddress(),viaPath->address(),now,false,viaPath->nextOutgoingCounter());
|
||||
viaPath->sent(now);
|
||||
}
|
||||
#ifdef ZT_ENABLE_CLUSTER
|
||||
@ -825,14 +825,14 @@ bool Switch::_trySend(Packet &packet,bool encrypt)
|
||||
if (trustedPathId) {
|
||||
packet.setTrusted(trustedPathId);
|
||||
} else {
|
||||
packet.armor((clusterMostRecentMemberId >= 0) ? clusterPeerSecret : peer->key(),encrypt);
|
||||
packet.armor((clusterMostRecentMemberId >= 0) ? clusterPeerSecret : peer->key(),encrypt,(viaPath) ? viaPath->nextOutgoingCounter() : 0);
|
||||
}
|
||||
#else
|
||||
const uint64_t trustedPathId = RR->topology->getOutboundPathTrust(viaPath->address());
|
||||
if (trustedPathId) {
|
||||
packet.setTrusted(trustedPathId);
|
||||
} else {
|
||||
packet.armor(peer->key(),encrypt);
|
||||
packet.armor(peer->key(),encrypt,viaPath->nextOutgoingCounter());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user