diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2015-10-07 10:30:47 -0700 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2015-10-07 10:30:47 -0700 |
commit | ab0228f626573381db93173cd5849cb934481ca5 (patch) | |
tree | 1550ca232a7ec877dabdd5b525bfac4ea05d619f | |
parent | 6c7ce79c8960cd2360657f9247788ff5640ae974 (diff) | |
download | infinitytier-ab0228f626573381db93173cd5849cb934481ca5.tar.gz infinitytier-ab0228f626573381db93173cd5849cb934481ca5.zip |
More cleanup and simple refactoring, consolidate InetAddres serialize/deserialize into the class.
-rw-r--r-- | node/IncomingPacket.cpp | 102 | ||||
-rw-r--r-- | node/InetAddress.hpp | 5 | ||||
-rw-r--r-- | node/Packet.hpp | 15 | ||||
-rw-r--r-- | node/Peer.cpp | 19 |
4 files changed, 43 insertions, 98 deletions
diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index 26d4bda8..6186affd 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -46,6 +46,7 @@ namespace ZeroTier { bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR) { + const Address sourceAddress(source()); try { if ((cipher() == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_NONE)&&(verb() == Packet::VERB_HELLO)) { // Unencrypted HELLOs are handled here since they are used to @@ -54,23 +55,24 @@ bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR) return _doHELLO(RR); } - SharedPtr<Peer> peer = RR->topology->getPeer(source()); + SharedPtr<Peer> peer = RR->topology->getPeer(sourceAddress); if (peer) { if (!dearmor(peer->key())) { - TRACE("dropped packet from %s(%s), MAC authentication failed (size: %u)",source().toString().c_str(),_remoteAddress.toString().c_str(),size()); + TRACE("dropped packet from %s(%s), MAC authentication failed (size: %u)",peer->address().toString().c_str(),_remoteAddress.toString().c_str(),size()); return true; } if (!uncompress()) { - TRACE("dropped packet from %s(%s), compressed data invalid",source().toString().c_str(),_remoteAddress.toString().c_str()); + TRACE("dropped packet from %s(%s), compressed data invalid",peer->address().toString().c_str(),_remoteAddress.toString().c_str()); return true; } - //TRACE("<< %s from %s(%s)",Packet::verbString(verb()),source().toString().c_str(),_remoteAddress.toString().c_str()); + //TRACE("<< %s from %s(%s)",Packet::verbString(v),sourceAddress.toString().c_str(),_remoteAddress.toString().c_str()); - switch(verb()) { + const Packet::Verb v = verb(); + switch(v) { //case Packet::VERB_NOP: default: // ignore unknown verbs, but if they pass auth check they are "received" - peer->received(RR,_localAddress,_remoteAddress,hops(),packetId(),verb(),0,Packet::VERB_NOP); + peer->received(RR,_localAddress,_remoteAddress,hops(),packetId(),v,0,Packet::VERB_NOP); return true; case Packet::VERB_HELLO: return _doHELLO(RR); case Packet::VERB_ERROR: return _doERROR(RR,peer); @@ -90,13 +92,13 @@ bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR) case Packet::VERB_CIRCUIT_TEST_REPORT: return _doCIRCUIT_TEST_REPORT(RR,peer); } } else { - RR->sw->requestWhois(source()); + RR->sw->requestWhois(sourceAddress); return false; } } catch ( ... ) { // Exceptions are more informatively caught in _do...() handlers but // this outer try/catch will catch anything else odd. - TRACE("dropped ??? from %s(%s): unexpected exception in tryDecode()",source().toString().c_str(),_remoteAddress.toString().c_str()); + TRACE("dropped ??? from %s(%s): unexpected exception in tryDecode()",sourceAddress.toString().c_str(),_remoteAddress.toString().c_str()); return true; } } @@ -108,7 +110,7 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,const SharedPtr<Peer> const uint64_t inRePacketId = at<uint64_t>(ZT_PROTO_VERB_ERROR_IDX_IN_RE_PACKET_ID); const Packet::ErrorCode errorCode = (Packet::ErrorCode)(*this)[ZT_PROTO_VERB_ERROR_IDX_ERROR_CODE]; - //TRACE("ERROR %s from %s(%s) in-re %s",Packet::errorString(errorCode),source().toString().c_str(),_remoteAddress.toString().c_str(),Packet::verbString(inReVerb)); + //TRACE("ERROR %s from %s(%s) in-re %s",Packet::errorString(errorCode),peer->address().toString().c_str(),_remoteAddress.toString().c_str(),Packet::verbString(inReVerb)); switch(errorCode) { @@ -118,7 +120,7 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,const SharedPtr<Peer> RR->sw->cancelWhoisRequest(Address(field(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH)); } else if (inReVerb == Packet::VERB_NETWORK_CONFIG_REQUEST) { SharedPtr<Network> network(RR->node->network(at<uint64_t>(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD))); - if ((network)&&(network->controller() == source())) + if ((network)&&(network->controller() == peer->address())) network->setNotFound(); } break; @@ -126,7 +128,7 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,const SharedPtr<Peer> case Packet::ERROR_UNSUPPORTED_OPERATION: if (inReVerb == Packet::VERB_NETWORK_CONFIG_REQUEST) { SharedPtr<Network> network(RR->node->network(at<uint64_t>(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD))); - if ((network)&&(network->controller() == source())) + if ((network)&&(network->controller() == peer->address())) network->setNotFound(); } break; @@ -154,7 +156,7 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,const SharedPtr<Peer> case Packet::ERROR_NETWORK_ACCESS_DENIED_: { SharedPtr<Network> network(RR->node->network(at<uint64_t>(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD))); - if ((network)&&(network->controller() == source())) + if ((network)&&(network->controller() == peer->address())) network->setAccessDenied(); } break; @@ -170,9 +172,9 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,const SharedPtr<Peer> peer->received(RR,_localAddress,_remoteAddress,hops(),packetId(),Packet::VERB_ERROR,inRePacketId,inReVerb); } catch (std::exception &ex) { - TRACE("dropped ERROR from %s(%s): unexpected exception: %s",source().toString().c_str(),_remoteAddress.toString().c_str(),ex.what()); + TRACE("dropped ERROR from %s(%s): unexpected exception: %s",peer->address().toString().c_str(),_remoteAddress.toString().c_str(),ex.what()); } catch ( ... ) { - TRACE("dropped ERROR from %s(%s): unexpected exception: (unknown)",source().toString().c_str(),_remoteAddress.toString().c_str()); + TRACE("dropped ERROR from %s(%s): unexpected exception: (unknown)",peer->address().toString().c_str(),_remoteAddress.toString().c_str()); } return true; } @@ -187,36 +189,29 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR) * in the first place. */ try { + const uint64_t pid = packetId(); + const Address fromAddress(source()); const unsigned int protoVersion = (*this)[ZT_PROTO_VERB_HELLO_IDX_PROTOCOL_VERSION]; const unsigned int vMajor = (*this)[ZT_PROTO_VERB_HELLO_IDX_MAJOR_VERSION]; const unsigned int vMinor = (*this)[ZT_PROTO_VERB_HELLO_IDX_MINOR_VERSION]; const unsigned int vRevision = at<uint16_t>(ZT_PROTO_VERB_HELLO_IDX_REVISION); const uint64_t timestamp = at<uint64_t>(ZT_PROTO_VERB_HELLO_IDX_TIMESTAMP); + Identity id; - unsigned int destAddrPtr = id.deserialize(*this,ZT_PROTO_VERB_HELLO_IDX_IDENTITY) + ZT_PROTO_VERB_HELLO_IDX_IDENTITY; + const unsigned int destAddrPtr = ZT_PROTO_VERB_HELLO_IDX_IDENTITY + id.deserialize(*this,ZT_PROTO_VERB_HELLO_IDX_IDENTITY); + InetAddress destAddr; + if (destAddrPtr < size()) // ZeroTier One < 1.0.3 did not include this field + destAddr.deserialize(*this,destAddrPtr); if (protoVersion < ZT_PROTO_VERSION_MIN) { TRACE("dropped HELLO from %s(%s): protocol version too old",id.address().toString().c_str(),_remoteAddress.toString().c_str()); return true; } - if (source() != id.address()) { - TRACE("dropped HELLO from %s(%s): identity not for sending address",source().toString().c_str(),_remoteAddress.toString().c_str()); + if (fromAddress != id.address()) { + TRACE("dropped HELLO from %s(%s): identity not for sending address",fromAddress.toString().c_str(),_remoteAddress.toString().c_str()); return true; } - InetAddress destAddr; - 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; - } - } - SharedPtr<Peer> peer(RR->topology->getPeer(id.address())); if (peer) { // We already have an identity with this address -- check for collisions @@ -230,7 +225,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR) TRACE("rejected HELLO from %s(%s): address already claimed",id.address().toString().c_str(),_remoteAddress.toString().c_str()); Packet outp(id.address(),RR->identity.address(),Packet::VERB_ERROR); outp.append((unsigned char)Packet::VERB_HELLO); - outp.append(packetId()); + outp.append((uint64_t)pid); outp.append((unsigned char)Packet::ERROR_IDENTITY_COLLISION); outp.armor(key,true); RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size()); @@ -273,41 +268,23 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR) // Continue at // VALID } - // VALID -- continues here + // VALID -- if we made it here, packet passed identity and authenticity checks! - peer->received(RR,_localAddress,_remoteAddress,hops(),packetId(),Packet::VERB_HELLO,0,Packet::VERB_NOP); + peer->received(RR,_localAddress,_remoteAddress,hops(),pid,Packet::VERB_HELLO,0,Packet::VERB_NOP); peer->setRemoteVersion(protoVersion,vMajor,vMinor,vRevision); - bool trusted = RR->topology->isRoot(id); if (destAddr) - RR->sa->iam(id.address(),_remoteAddress,destAddr,trusted,RR->node->now()); + RR->sa->iam(id.address(),_remoteAddress,destAddr,RR->topology->isRoot(id),RR->node->now()); Packet outp(id.address(),RR->identity.address(),Packet::VERB_OK); - outp.append((unsigned char)Packet::VERB_HELLO); - outp.append(packetId()); - outp.append(timestamp); + outp.append((uint64_t)pid); + outp.append((uint64_t)timestamp); outp.append((unsigned char)ZT_PROTO_VERSION); outp.append((unsigned char)ZEROTIER_ONE_VERSION_MAJOR); outp.append((unsigned char)ZEROTIER_ONE_VERSION_MINOR); outp.append((uint16_t)ZEROTIER_ONE_VERSION_REVISION); - - switch(_remoteAddress.ss_family) { - case AF_INET: - outp.append((unsigned char)ZT_PROTO_DEST_ADDRESS_TYPE_IPV4); - outp.append(_remoteAddress.rawIpData(),4); - outp.append((uint16_t)_remoteAddress.port()); - break; - case AF_INET6: - outp.append((unsigned char)ZT_PROTO_DEST_ADDRESS_TYPE_IPV6); - outp.append(_remoteAddress.rawIpData(),16); - outp.append((uint16_t)_remoteAddress.port()); - break; - default: - outp.append((unsigned char)ZT_PROTO_DEST_ADDRESS_TYPE_NONE); - break; - } - + _remoteAddress.serialize(outp); outp.armor(peer->key(),true); RR->node->putPacket(_localAddress,_remoteAddress,outp.data(),outp.size()); } catch (std::exception &ex) { @@ -336,18 +313,9 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr<Peer> &p 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 ((ZT_PROTO_VERB_HELLO__OK__IDX_REVISION + 2) < size()) // ZeroTier One < 1.0.3 did not include this field + destAddr.deserialize(*this,ZT_PROTO_VERB_HELLO__OK__IDX_REVISION + 2); + printf("OK(HELLO) %s\n",destAddr.toString().c_str()); if (vProto < ZT_PROTO_VERSION_MIN) { TRACE("%s(%s): OK(HELLO) dropped, protocol version too old",source().toString().c_str(),_remoteAddress.toString().c_str()); diff --git a/node/InetAddress.hpp b/node/InetAddress.hpp index c376a032..6970e92d 100644 --- a/node/InetAddress.hpp +++ b/node/InetAddress.hpp @@ -366,7 +366,8 @@ struct InetAddress : public sockaddr_storage template<unsigned int C> inline void serialize(Buffer<C> &b) const { - // Format is the same as in VERB_HELLO in Packet.hpp + // This is used in the protocol and must be the same as describe in places + // like VERB_HELLO in Packet.hpp. switch(ss_family) { case AF_INET: b.append((uint8_t)0x04); @@ -387,8 +388,8 @@ struct InetAddress : public sockaddr_storage template<unsigned int C> inline unsigned int deserialize(const Buffer<C> &b,unsigned int startAt = 0) { - unsigned int p = startAt; memset(this,0,sizeof(InetAddress)); + unsigned int p = startAt; switch(b[p++]) { case 0: return 1; diff --git a/node/Packet.hpp b/node/Packet.hpp index 409762c7..1413db10 100644 --- a/node/Packet.hpp +++ b/node/Packet.hpp @@ -55,13 +55,15 @@ * 3 - 0.5.0 ... 0.6.0 * * Yet another multicast redesign * * New crypto completely changes key agreement cipher - * 4 - 0.6.0 ... CURRENT + * 4 - 0.6.0 ... 1.0.6 * * New identity format based on hashcash design + * 5 - 1.0.6 ... CURRENT + * * Supports CIRCUIT_TEST and friends, otherwise compatibie w/v4 * * This isn't going to change again for a long time unless your * author wakes up again at 4am with another great idea. :P */ -#define ZT_PROTO_VERSION 4 +#define ZT_PROTO_VERSION 5 /** * Minimum supported protocol version @@ -233,15 +235,6 @@ */ #define ZT_PROTO_MIN_FRAGMENT_LENGTH ZT_PACKET_FRAGMENT_IDX_PAYLOAD -// Destination address types from HELLO, OK(HELLO), and other message types -#define ZT_PROTO_DEST_ADDRESS_TYPE_NONE 0 -#define ZT_PROTO_DEST_ADDRESS_TYPE_ZEROTIER 1 // reserved but unused -#define ZT_PROTO_DEST_ADDRESS_TYPE_ETHERNET 2 // future use -#define ZT_PROTO_DEST_ADDRESS_TYPE_BLUETOOTH 3 // future use -#define ZT_PROTO_DEST_ADDRESS_TYPE_IPV4 4 -#define ZT_PROTO_DEST_ADDRESS_TYPE_LTE_DIRECT 5 // future use -#define ZT_PROTO_DEST_ADDRESS_TYPE_IPV6 6 - // Ephemeral key record flags #define ZT_PROTO_EPHEMERAL_KEY_FLAG_FIPS 0x01 // future use diff --git a/node/Peer.cpp b/node/Peer.cpp index 757f822c..15648e0f 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -170,25 +170,8 @@ void Peer::attemptToContactAt(const RuntimeEnvironment *RR,const InetAddress &lo outp.append((unsigned char)ZEROTIER_ONE_VERSION_MINOR); outp.append((uint16_t)ZEROTIER_ONE_VERSION_REVISION); outp.append(now); - RR->identity.serialize(outp,false); - - switch(atAddress.ss_family) { - case AF_INET: - outp.append((unsigned char)ZT_PROTO_DEST_ADDRESS_TYPE_IPV4); - outp.append(atAddress.rawIpData(),4); - outp.append((uint16_t)atAddress.port()); - break; - case AF_INET6: - outp.append((unsigned char)ZT_PROTO_DEST_ADDRESS_TYPE_IPV6); - outp.append(atAddress.rawIpData(),16); - outp.append((uint16_t)atAddress.port()); - break; - default: - outp.append((unsigned char)ZT_PROTO_DEST_ADDRESS_TYPE_NONE); - break; - } - + atAddress.serialize(outp); outp.armor(_key,false); // HELLO is sent in the clear RR->node->putPacket(localAddr,atAddress,outp.data(),outp.size()); } |