diff --git a/controller/EmbeddedNetworkController.cpp b/controller/EmbeddedNetworkController.cpp index 26d43f04f..3500276d0 100644 --- a/controller/EmbeddedNetworkController.cpp +++ b/controller/EmbeddedNetworkController.cpp @@ -1123,7 +1123,7 @@ void EmbeddedNetworkController::onNetworkMemberUpdate(const void *db,uint64_t ne void EmbeddedNetworkController::onNetworkMemberDeauthorize(const void *db,uint64_t networkId,uint64_t memberId) { const int64_t now = OSUtils::now(); - Revocation rev((uint32_t)Utils::random(),networkId,0,now,ZT_REVOCATION_FLAG_FAST_PROPAGATE,Address(memberId),Revocation::CREDENTIAL_TYPE_COM); + Revocation rev((uint32_t)Utils::random(),networkId,0,now,ZT_REVOCATION_FLAG_FAST_PROPAGATE,Address(memberId),ZT_CREDENTIAL_TYPE_COM); rev.sign(_signingId); { std::lock_guard l(_memberStatus_l); diff --git a/include/ZeroTierCore.h b/include/ZeroTierCore.h index d18c75559..4dadb7e4d 100644 --- a/include/ZeroTierCore.h +++ b/include/ZeroTierCore.h @@ -396,7 +396,9 @@ enum ZT_TraceTryingNewPathReason { ZT_TRACE_TRYING_NEW_PATH_REASON_PACKET_RECEIVED_FROM_UNKNOWN_PATH = 1, ZT_TRACE_TRYING_NEW_PATH_REASON_RECEIVED_PUSH_DIRECT_PATHS = 2, - ZT_TRACE_TRYING_NEW_PATH_REASON_RENDEZVOUS = 3 + ZT_TRACE_TRYING_NEW_PATH_REASON_RENDEZVOUS = 3, + ZT_TRACE_TRYING_NEW_PATH_REASON_BOOTSTRAP_ADDRESS = 4, + ZT_TRACE_TRYING_NEW_PATH_REASON_EXPLICITLY_SUGGESTED_ADDRESS = 5 }; /** diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index 2acd557ac..db2973abb 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -355,8 +355,9 @@ ZT_ALWAYS_INLINE bool _doRENDEZVOUS(IncomingPacket &pkt,const RuntimeEnvironment InetAddress atAddr(pkt.field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRESS,addrlen),addrlen,port); if (rendezvousWith->shouldTryPath(tPtr,RR->node->now(),peer,atAddr)) { if (atAddr.isV4()) - RR->node->putPacket(tPtr,path->localSocket(),atAddr,&junk,2,2); // IPv4 "firewall opener" + RR->node->putPacket(tPtr,path->localSocket(),atAddr,&junk,2,2); // IPv4 "firewall opener" hack rendezvousWith->sendHELLO(tPtr,path->localSocket(),atAddr,RR->node->now()); + RR->t->tryingNewPath(tPtr,rendezvousWith->identity(),atAddr,path->address(),pkt.packetId(),Packet::VERB_RENDEZVOUS,peer->address(),peer->identity().hash(),ZT_TRACE_TRYING_NEW_PATH_REASON_RENDEZVOUS); } } } @@ -401,7 +402,7 @@ ZT_ALWAYS_INLINE bool _doEXT_FRAME(IncomingPacket &pkt,const RuntimeEnvironment CertificateOfMembership com; comLen = com.deserialize(pkt,ZT_PROTO_VERB_EXT_FRAME_IDX_COM); if (com) - network->addCredential(tPtr,com); + network->addCredential(tPtr,peer->identity(),com); } if (!network->gate(tPtr,peer)) { @@ -501,7 +502,7 @@ ZT_ALWAYS_INLINE bool _doNETWORK_CREDENTIALS(IncomingPacket &pkt,const RuntimeEn if (com) { network = RR->node->network(com.networkId()); if (network) { - if (network->addCredential(tPtr,com) == Membership::ADD_DEFERRED_FOR_WHOIS) + if (network->addCredential(tPtr,peer->identity(),com) == Membership::ADD_DEFERRED_FOR_WHOIS) return false; } } @@ -515,7 +516,7 @@ ZT_ALWAYS_INLINE bool _doNETWORK_CREDENTIALS(IncomingPacket &pkt,const RuntimeEn if ((!network)||(network->id() != cap.networkId())) network = RR->node->network(cap.networkId()); if (network) { - if (network->addCredential(tPtr,cap) == Membership::ADD_DEFERRED_FOR_WHOIS) + if (network->addCredential(tPtr,peer->identity(),cap) == Membership::ADD_DEFERRED_FOR_WHOIS) return false; } } @@ -528,7 +529,7 @@ ZT_ALWAYS_INLINE bool _doNETWORK_CREDENTIALS(IncomingPacket &pkt,const RuntimeEn if ((!network)||(network->id() != tag.networkId())) network = RR->node->network(tag.networkId()); if (network) { - if (network->addCredential(tPtr,tag) == Membership::ADD_DEFERRED_FOR_WHOIS) + if (network->addCredential(tPtr,peer->identity(),tag) == Membership::ADD_DEFERRED_FOR_WHOIS) return false; } } @@ -541,7 +542,7 @@ ZT_ALWAYS_INLINE bool _doNETWORK_CREDENTIALS(IncomingPacket &pkt,const RuntimeEn if ((!network)||(network->id() != revocation.networkId())) network = RR->node->network(revocation.networkId()); if (network) { - if (network->addCredential(tPtr,peer->address(),revocation) == Membership::ADD_DEFERRED_FOR_WHOIS) + if (network->addCredential(tPtr,peer->identity(),revocation) == Membership::ADD_DEFERRED_FOR_WHOIS) return false; } } @@ -554,7 +555,7 @@ ZT_ALWAYS_INLINE bool _doNETWORK_CREDENTIALS(IncomingPacket &pkt,const RuntimeEn if ((!network)||(network->id() != coo.networkId())) network = RR->node->network(coo.networkId()); if (network) { - if (network->addCredential(tPtr,coo) == Membership::ADD_DEFERRED_FOR_WHOIS) + if (network->addCredential(tPtr,peer->identity(),coo) == Membership::ADD_DEFERRED_FOR_WHOIS) return false; } } @@ -619,12 +620,13 @@ ZT_ALWAYS_INLINE bool _doMULTICAST_GATHER(IncomingPacket &pkt,const RuntimeEnvir const SharedPtr network(RR->node->network(nwid)); - if ((flags & 0x01) != 0) { + // LEGACY: older versions would send this + if ((flags & 0x01U) != 0) { try { CertificateOfMembership com; com.deserialize(pkt,ZT_PROTO_VERB_MULTICAST_GATHER_IDX_COM); if ((com)&&(network)) - network->addCredential(tPtr,com); + network->addCredential(tPtr,peer->identity(),com); } catch ( ... ) {} // discard invalid COMs } @@ -658,6 +660,7 @@ ZT_ALWAYS_INLINE bool _doMULTICAST_GATHER(IncomingPacket &pkt,const RuntimeEnvir return true; } +volatile uint16_t junk = 0; ZT_ALWAYS_INLINE bool _doPUSH_DIRECT_PATHS(IncomingPacket &pkt,const RuntimeEnvironment *const RR,void *const tPtr,const SharedPtr &peer,const SharedPtr &path) { const int64_t now = RR->node->now(); @@ -668,7 +671,6 @@ ZT_ALWAYS_INLINE bool _doPUSH_DIRECT_PATHS(IncomingPacket &pkt,const RuntimeEnvi unsigned int count = pkt.at(ZT_PACKET_IDX_PAYLOAD); unsigned int ptr = ZT_PACKET_IDX_PAYLOAD + 2; - uint16_t junk = (uint16_t)Utils::random(); while (count--) { /* unsigned int flags = (*this)[ptr++]; */ ++ptr; @@ -682,17 +684,20 @@ ZT_ALWAYS_INLINE bool _doPUSH_DIRECT_PATHS(IncomingPacket &pkt,const RuntimeEnvi const InetAddress a(pkt.field(ptr,4),4,pkt.at(ptr + 4)); if (peer->shouldTryPath(tPtr,now,peer,a)) { if (++countPerScope[(int)a.ipScope()][0] <= ZT_PUSH_DIRECT_PATHS_MAX_PER_SCOPE_AND_FAMILY) { - RR->node->putPacket(tPtr,path->localSocket(),a,&junk,2,2); // IPv4 "firewall opener" + RR->node->putPacket(tPtr,path->localSocket(),a,(const void *)&junk,sizeof(junk),2); // IPv4 "firewall opener" ++junk; peer->sendHELLO(tPtr,-1,a,now); + RR->t->tryingNewPath(tPtr,peer->identity(),a,path->address(),pkt.packetId(),Packet::VERB_PUSH_DIRECT_PATHS,peer->address(),peer->identity().hash(),ZT_TRACE_TRYING_NEW_PATH_REASON_RECEIVED_PUSH_DIRECT_PATHS); } } } break; case 6: { const InetAddress a(pkt.field(ptr,16),16,pkt.at(ptr + 16)); if (peer->shouldTryPath(tPtr,now,peer,a)) { - if (++countPerScope[(int)a.ipScope()][1] <= ZT_PUSH_DIRECT_PATHS_MAX_PER_SCOPE_AND_FAMILY) + if (++countPerScope[(int)a.ipScope()][1] <= ZT_PUSH_DIRECT_PATHS_MAX_PER_SCOPE_AND_FAMILY) { peer->sendHELLO(tPtr,-1,a,now); + RR->t->tryingNewPath(tPtr,peer->identity(),a,path->address(),pkt.packetId(),Packet::VERB_PUSH_DIRECT_PATHS,peer->address(),peer->identity().hash(),ZT_TRACE_TRYING_NEW_PATH_REASON_RECEIVED_PUSH_DIRECT_PATHS); + } } } break; } diff --git a/node/Node.cpp b/node/Node.cpp index 98e43706a..ee311bbca 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -698,7 +698,7 @@ void Node::ncSendRevocation(const Address &destination,const Revocation &rev) if (destination == RR->identity.address()) { SharedPtr n(network(rev.networkId())); if (!n) return; - n->addCredential((void *)0,RR->identity.address(),rev); + n->addCredential((void *)0,RR->identity,rev); } else { Packet outp(destination,RR->identity.address(),Packet::VERB_NETWORK_CREDENTIALS); outp.append((uint8_t)0x00); diff --git a/node/Peer.cpp b/node/Peer.cpp index cce2fe535..2058dacb0 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -109,30 +109,35 @@ void Peer::received( } _lastPrioritizedPaths = now; + InetAddress old; + if (_paths[lastReceiveTimeMaxAt]) + old = _paths[lastReceiveTimeMaxAt]->address(); _paths[lastReceiveTimeMaxAt] = path; _bootstrap = path->address(); _prioritizePaths(now); - RR->t->peerLearnedNewPath(tPtr,networkId,*this,path,packetId); + RR->t->learnedNewPath(tPtr,packetId,_id,path->address(),old); } else { if (RR->node->shouldUsePathForZeroTierTraffic(tPtr,_id,path->localSocket(),path->address())) { + RR->t->tryingNewPath(tPtr,_id,path->address(),path->address(),packetId,(uint8_t)verb,_id.address(),_id.hash(),ZT_TRACE_TRYING_NEW_PATH_REASON_PACKET_RECEIVED_FROM_UNKNOWN_PATH); sendHELLO(tPtr,path->localSocket(),path->address(),now); path->sent(now); - RR->t->peerConfirmingUnknownPath(tPtr,networkId,*this,path,packetId,verb); } } } path_check_done: - const int64_t sinceLastP2PInit = now - _lastAttemptedP2PInit; - if (sinceLastP2PInit >= ((hops == 0) ? ZT_DIRECT_PATH_PUSH_INTERVAL_HAVEPATH : ZT_DIRECT_PATH_PUSH_INTERVAL)) { + if ((now - _lastAttemptedP2PInit) >= ((hops == 0) ? ZT_DIRECT_PATH_PUSH_INTERVAL_HAVEPATH : ZT_DIRECT_PATH_PUSH_INTERVAL)) { _lastAttemptedP2PInit = now; InetAddress addr; - if ((_bootstrap.type() == Endpoint::INETADDR_V4)||(_bootstrap.type() == Endpoint::INETADDR_V6)) + if ((_bootstrap.type() == Endpoint::INETADDR_V4)||(_bootstrap.type() == Endpoint::INETADDR_V6)) { + RR->t->tryingNewPath(tPtr,_id,_bootstrap.inetAddr(),InetAddress::NIL,0,0,0,nullptr,ZT_TRACE_TRYING_NEW_PATH_REASON_BOOTSTRAP_ADDRESS); sendHELLO(tPtr,-1,_bootstrap.inetAddr(),now); - if (RR->node->externalPathLookup(tPtr,_id,-1,addr)) { - if (RR->node->shouldUsePathForZeroTierTraffic(tPtr,_id,-1,addr)) + } if (RR->node->externalPathLookup(tPtr,_id,-1,addr)) { + if (RR->node->shouldUsePathForZeroTierTraffic(tPtr,_id,-1,addr)) { + RR->t->tryingNewPath(tPtr,_id,_bootstrap.inetAddr(),InetAddress::NIL,0,0,0,nullptr,ZT_TRACE_TRYING_NEW_PATH_REASON_EXPLICITLY_SUGGESTED_ADDRESS); sendHELLO(tPtr,-1,addr,now); + } } std::vector localInterfaceAddresses(RR->node->localInterfaceAddresses()); @@ -157,7 +162,7 @@ path_check_done: uint8_t addressType = 4; uint8_t addressLength = 6; unsigned int ipLength = 4; - const void *rawIpData = (const void *)0; + const void *rawIpData = nullptr; uint16_t port = 0; switch(a->ss_family) { case AF_INET: diff --git a/node/Switch.cpp b/node/Switch.cpp index 959ee348c..49917fa48 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -12,18 +12,14 @@ /****/ #include -#include - #include #include -#include #include "Constants.hpp" #include "RuntimeEnvironment.hpp" #include "Switch.hpp" #include "Node.hpp" #include "InetAddress.hpp" -#include "Topology.hpp" #include "Peer.hpp" #include "SelfAwareness.hpp" #include "Packet.hpp" @@ -211,7 +207,7 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr &network,const bool fromBridged; if ((fromBridged = (from != network->mac()))) { if (!network->config().permitsBridging(RR->identity.address())) { - RR->t->outgoingNetworkFrameDropped(tPtr,network,from,to,etherType,vlanId,len,ZT_TRACE_FRAME_DROP_REASON_BRIDGING_NOT_ALLOWED_LOCAL); + RR->t->outgoingNetworkFrameDropped(tPtr,network->id(),from,to,(uint16_t)etherType,(uint16_t)len,(const uint8_t *)data,ZT_TRACE_FRAME_DROP_REASON_BRIDGING_NOT_ALLOWED_LOCAL); return; } } @@ -235,7 +231,7 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr &network,const multicastGroup = MulticastGroup::deriveMulticastGroupForAddressResolution(InetAddress(((const unsigned char *)data) + 24,4,0)); } else if (!network->config().enableBroadcast()) { // Don't transmit broadcasts if this network doesn't want them - RR->t->outgoingNetworkFrameDropped(tPtr,network,from,to,etherType,vlanId,len,ZT_TRACE_FRAME_DROP_REASON_BROADCAST_DISABLED); + RR->t->outgoingNetworkFrameDropped(tPtr,network->id(),from,to,(uint16_t)etherType,(uint16_t)len,(const uint8_t *)data,ZT_TRACE_FRAME_DROP_REASON_BROADCAST_DISABLED); return; } } else if ((etherType == ZT_ETHERTYPE_IPV6)&&(len >= (40 + 8 + 16))) { @@ -323,7 +319,7 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr &network,const // Check this after NDP emulation, since that has to be allowed in exactly this case if (network->config().multicastLimit == 0) { - RR->t->outgoingNetworkFrameDropped(tPtr,network,from,to,etherType,vlanId,len,ZT_TRACE_FRAME_DROP_REASON_MULTICAST_DISABLED); + RR->t->outgoingNetworkFrameDropped(tPtr,network->id(),from,to,(uint16_t)etherType,(uint16_t)len,(const uint8_t *)data,ZT_TRACE_FRAME_DROP_REASON_MULTICAST_DISABLED); return; } @@ -336,7 +332,7 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr &network,const // First pass sets noTee to false, but noTee is set to true in OutboundMulticast to prevent duplicates. if (!network->filterOutgoingPacket(tPtr,false,RR->identity.address(),Address(),from,to,(const uint8_t *)data,len,etherType,vlanId,qosBucket)) { - RR->t->outgoingNetworkFrameDropped(tPtr,network,from,to,etherType,vlanId,len,ZT_TRACE_FRAME_DROP_REASON_FILTER_BLOCKED); + RR->t->outgoingNetworkFrameDropped(tPtr,network->id(),from,to,(uint16_t)etherType,(uint16_t)len,(const uint8_t *)data,ZT_TRACE_FRAME_DROP_REASON_FILTER_BLOCKED); return; } @@ -365,7 +361,7 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr &network,const SharedPtr toPeer(RR->topology->get(tPtr,toZT)); if (!network->filterOutgoingPacket(tPtr,false,RR->identity.address(),toZT,from,to,(const uint8_t *)data,len,etherType,vlanId,qosBucket)) { - RR->t->outgoingNetworkFrameDropped(tPtr,network,from,to,etherType,vlanId,len,ZT_TRACE_FRAME_DROP_REASON_FILTER_BLOCKED); + RR->t->outgoingNetworkFrameDropped(tPtr,network->id(),from,to,(uint16_t)etherType,(uint16_t)len,(const uint8_t *)data,ZT_TRACE_FRAME_DROP_REASON_FILTER_BLOCKED); return; } @@ -392,7 +388,7 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr &network,const // for each ZT destination are also done below. This is the same rationale // and design as for multicast. if (!network->filterOutgoingPacket(tPtr,false,RR->identity.address(),Address(),from,to,(const uint8_t *)data,len,etherType,vlanId,qosBucket)) { - RR->t->outgoingNetworkFrameDropped(tPtr,network,from,to,etherType,vlanId,len,ZT_TRACE_FRAME_DROP_REASON_FILTER_BLOCKED); + RR->t->outgoingNetworkFrameDropped(tPtr,network->id(),from,to,(uint16_t)etherType,(uint16_t)len,(const uint8_t *)data,ZT_TRACE_FRAME_DROP_REASON_FILTER_BLOCKED); return; } @@ -442,7 +438,7 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr &network,const outp.append((uint16_t)etherType); outp.append(data,len); } else { - RR->t->outgoingNetworkFrameDropped(tPtr,network,from,to,etherType,vlanId,len,ZT_TRACE_FRAME_DROP_REASON_FILTER_BLOCKED_AT_BRIDGE_REPLICATION); + RR->t->outgoingNetworkFrameDropped(tPtr,network->id(),from,to,(uint16_t)etherType,(uint16_t)len,(const uint8_t *)data,ZT_TRACE_FRAME_DROP_REASON_FILTER_BLOCKED_AT_BRIDGE_REPLICATION); } } } diff --git a/osdep/LinuxEthernetTap.cpp b/osdep/LinuxEthernetTap.cpp index 3f490bed8..7b85179a4 100644 --- a/osdep/LinuxEthernetTap.cpp +++ b/osdep/LinuxEthernetTap.cpp @@ -15,6 +15,10 @@ #ifdef __LINUX__ +#ifdef __GCC__ +#pragma GCC diagnostic ignored "-Wrestrict" +#endif + #include "../node/Utils.hpp" #include "../node/Mutex.hpp" #include "../node/Dictionary.hpp"