diff options
-rw-r--r-- | node/IncomingPacket.cpp | 49 |
1 files changed, 34 insertions, 15 deletions
diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index a8d564bb..f73b20af 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -179,18 +179,17 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR) Identity id; unsigned int destAddrPtr = id.deserialize(*this,ZT_PROTO_VERB_HELLO_IDX_IDENTITY) + ZT_PROTO_VERB_HELLO_IDX_IDENTITY; - unsigned int destAddrType = ZT_PROTO_DEST_ADDRESS_TYPE_NONE; - if (destAddrPtr < size()) // ZeroTier One < 1.0.3 did not include this field - destAddrType = (*this)[destAddrPtr++]; - InetAddress destAddr; - switch(destAddrType) { - case ZT_PROTO_DEST_ADDRESS_TYPE_IPV4: - destAddr.set(field(destAddrPtr,4),4,at<uint16_t>(destAddrPtr + 4)); - break; - case ZT_PROTO_DEST_ADDRESS_TYPE_IPV6: - destAddr.set(field(destAddrPtr,16),16,at<uint16_t>(destAddrPtr + 16)); - break; + if (destAddrPtr < size()) { // ZeroTier One < 1.0.3 did not include this field + const unsigned int destAddrType = (*this)[destAddrPtr++]; + switch(destAddrType) { + case ZT_PROTO_DEST_ADDRESS_TYPE_IPV4: + destAddr.set(field(destAddrPtr,4),4,at<uint16_t>(destAddrPtr + 4)); + break; + case ZT_PROTO_DEST_ADDRESS_TYPE_IPV6: + destAddr.set(field(destAddrPtr,16),16,at<uint16_t>(destAddrPtr + 16)); + break; + } } if (source() != id.address()) { @@ -268,12 +267,13 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR) peer->received(RR,_remoteAddress,_linkDesperation,hops(),packetId(),Packet::VERB_HELLO,0,Packet::VERB_NOP); peer->setRemoteVersion(protoVersion,vMajor,vMinor,vRevision); + bool trusted = false; if (RR->topology->isSupernode(id.address())) { RR->node->postNewerVersionIfNewer(vMajor,vMinor,vRevision); - RR->sa->iam(id.address(),_remoteAddress,destAddr,true); - } else { - RR->sa->iam(id.address(),_remoteAddress,destAddr,false); + trusted = true; } + if (destAddr) + RR->sa->iam(id.address(),_remoteAddress,destAddr,trusted); Packet outp(id.address(),RR->identity.address(),Packet::VERB_OK); @@ -328,6 +328,20 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr<Peer> &p const unsigned int vMinor = (*this)[ZT_PROTO_VERB_HELLO__OK__IDX_MINOR_VERSION]; const unsigned int vRevision = at<uint16_t>(ZT_PROTO_VERB_HELLO__OK__IDX_REVISION); + InetAddress destAddr; + unsigned int destAddrPtr = ZT_PROTO_VERB_HELLO__OK__IDX_REVISION + 2; // dest address, if present, will start after 16-bit revision + if (destAddrPtr < size()) { // ZeroTier One < 1.0.3 did not include this field + const unsigned int destAddrType = (*this)[destAddrPtr++]; + switch(destAddrType) { + case ZT_PROTO_DEST_ADDRESS_TYPE_IPV4: + destAddr.set(field(destAddrPtr,4),4,at<uint16_t>(destAddrPtr + 4)); + break; + case ZT_PROTO_DEST_ADDRESS_TYPE_IPV6: + destAddr.set(field(destAddrPtr,16),16,at<uint16_t>(destAddrPtr + 16)); + break; + } + } + if (vProto < ZT_PROTO_VERSION_MIN) { TRACE("%s(%s): OK(HELLO) dropped, protocol version too old",source().toString().c_str(),_remoteAddress.toString().c_str()); return true; @@ -338,8 +352,13 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr<Peer> &p peer->addDirectLatencyMeasurment(latency); peer->setRemoteVersion(vProto,vMajor,vMinor,vRevision); - if (RR->topology->isSupernode(peer->address())) + bool trusted = false; + if (RR->topology->isSupernode(peer->address())) { RR->node->postNewerVersionIfNewer(vMajor,vMinor,vRevision); + trusted = true; + } + if (destAddr) + RR->sa->iam(peer->address(),_remoteAddress,destAddr,trusted); } break; case Packet::VERB_WHOIS: { |