diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index a120a208a..12534117f 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -37,6 +37,7 @@ #include "Trace.hpp" #include "Path.hpp" #include "Bond.hpp" +#include "Metrics.hpp" namespace ZeroTier { @@ -130,6 +131,8 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,void *tPtr,const Shar const Packet::ErrorCode errorCode = (Packet::ErrorCode)(*this)[ZT_PROTO_VERB_ERROR_IDX_ERROR_CODE]; uint64_t networkId = 0; + Metrics::pkt_error++; + /* Security note: we do not gate doERROR() with expectingReplyTo() to * avoid having to log every outgoing packet ID. Instead we put the * logic to determine whether we should consider an ERROR in each @@ -145,6 +148,7 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,void *tPtr,const Shar if ((network)&&(network->controller() == peer->address())) network->setNotFound(tPtr); } + Metrics::pkt_error_obj_not_found++; break; case Packet::ERROR_UNSUPPORTED_OPERATION: @@ -156,12 +160,15 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,void *tPtr,const Shar if ((network)&&(network->controller() == peer->address())) network->setNotFound(tPtr); } + Metrics::pkt_error_unsupported_op++; break; case Packet::ERROR_IDENTITY_COLLISION: // FIXME: for federation this will need a payload with a signature or something. - if (RR->topology->isUpstream(peer->identity())) + if (RR->topology->isUpstream(peer->identity())) { RR->node->postEvent(tPtr,ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION); + } + Metrics::pkt_error_identity_collision++; break; case Packet::ERROR_NEED_MEMBERSHIP_CERTIFICATE: { @@ -169,15 +176,19 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,void *tPtr,const Shar networkId = at(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD); const SharedPtr network(RR->node->network(networkId)); const int64_t now = RR->node->now(); - if ((network)&&(network->config().com)) + if ((network)&&(network->config().com)) { network->peerRequestedCredentials(tPtr,peer->address(),now); + } + Metrics::pkt_error_need_membership_cert++; } break; case Packet::ERROR_NETWORK_ACCESS_DENIED_: { // Network controller: network access denied. const SharedPtr network(RR->node->network(at(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD))); - if ((network)&&(network->controller() == peer->address())) + if ((network)&&(network->controller() == peer->address())) { network->setAccessDenied(tPtr); + } + Metrics::pkt_error_network_access_denied++; } break; case Packet::ERROR_UNWANTED_MULTICAST: { @@ -189,6 +200,7 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,void *tPtr,const Shar const MulticastGroup mg(MAC(field(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD + 8,6),6),at(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD + 14)); RR->mc->remove(network->id(),mg,peer->address()); } + Metrics::pkt_error_unwanted_multicast++; } break; case Packet::ERROR_NETWORK_AUTHENTICATION_REQUIRED: { @@ -247,6 +259,7 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,void *tPtr,const Shar network->setAuthenticationRequired(tPtr, ""); } } + Metrics::pkt_error_authentication_required++; } break; default: break; @@ -273,11 +286,13 @@ bool IncomingPacket::_doACK(const RuntimeEnvironment* RR, void* tPtr, const Shar bond->receivedAck(_path, RR->node->now(), Utils::ntoh(ackedBytes)); } */ + Metrics::pkt_ack++; return true; } bool IncomingPacket::_doQOS_MEASUREMENT(const RuntimeEnvironment* RR, void* tPtr, const SharedPtr& peer) { + Metrics::pkt_qos++; SharedPtr bond = peer->bond(); if (! bond || ! bond->rateGateQoS(RR->node->now(), _path)) { return true; @@ -308,6 +323,7 @@ bool IncomingPacket::_doQOS_MEASUREMENT(const RuntimeEnvironment* RR, void* tPtr bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,void *tPtr,const bool alreadyAuthenticated) { + Metrics::pkt_hello++; const int64_t now = RR->node->now(); const uint64_t pid = packetId(); @@ -510,6 +526,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,void *tPtr,const bool bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer) { + Metrics::pkt_ok++; const Packet::Verb inReVerb = (Packet::Verb)(*this)[ZT_PROTO_VERB_OK_IDX_IN_RE_VERB]; const uint64_t inRePacketId = at(ZT_PROTO_VERB_OK_IDX_IN_RE_PACKET_ID); uint64_t networkId = 0; @@ -623,8 +640,11 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,void *tPtr,const SharedP bool IncomingPacket::_doWHOIS(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer) { - if ((!RR->topology->amUpstream())&&(!peer->rateGateInboundWhoisRequest(RR->node->now()))) + if ((!RR->topology->amUpstream())&&(!peer->rateGateInboundWhoisRequest(RR->node->now()))) { return true; + } + + Metrics::pkt_whois++; Packet outp(peer->address(),RR->identity.address(),Packet::VERB_OK); outp.append((unsigned char)Packet::VERB_WHOIS); @@ -658,6 +678,7 @@ bool IncomingPacket::_doWHOIS(const RuntimeEnvironment *RR,void *tPtr,const Shar bool IncomingPacket::_doRENDEZVOUS(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer) { + Metrics::pkt_rendezvous++; if (RR->topology->isUpstream(peer->identity())) { const Address with(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ZTADDRESS,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH); const SharedPtr rendezvousWith(RR->topology->getPeer(tPtr,with)); @@ -711,6 +732,7 @@ static bool _ipv6GetPayload(const uint8_t *frameData,unsigned int frameLen,unsig bool IncomingPacket::_doFRAME(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer,int32_t flowId) { + Metrics::pkt_frame++; int32_t _flowId = ZT_QOS_NO_FLOW; SharedPtr bond = peer->bond(); if (bond && bond->flowHashingSupported()) { @@ -803,6 +825,7 @@ bool IncomingPacket::_doFRAME(const RuntimeEnvironment *RR,void *tPtr,const Shar bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer,int32_t flowId) { + Metrics::pkt_ext_frame++; const uint64_t nwid = at(ZT_PROTO_VERB_EXT_FRAME_IDX_NETWORK_ID); const SharedPtr network(RR->node->network(nwid)); if (network) { @@ -885,6 +908,7 @@ bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment *RR,void *tPtr,const bool IncomingPacket::_doECHO(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer) { + Metrics::pkt_echo++; uint64_t now = RR->node->now(); if (!_path->rateGateEchoRequest(now)) { return true; @@ -907,6 +931,7 @@ bool IncomingPacket::_doECHO(const RuntimeEnvironment *RR,void *tPtr,const Share bool IncomingPacket::_doMULTICAST_LIKE(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer) { + Metrics::pkt_multicast_like++; const int64_t now = RR->node->now(); bool authorized = false; uint64_t lastNwid = 0; @@ -932,8 +957,10 @@ bool IncomingPacket::_doMULTICAST_LIKE(const RuntimeEnvironment *RR,void *tPtr,c bool IncomingPacket::_doNETWORK_CREDENTIALS(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer) { - if (!peer->rateGateCredentialsReceived(RR->node->now())) + Metrics::pkt_network_credentials++; + if (!peer->rateGateCredentialsReceived(RR->node->now())) { return true; + } CertificateOfMembership com; Capability cap; @@ -1055,6 +1082,7 @@ bool IncomingPacket::_doNETWORK_CREDENTIALS(const RuntimeEnvironment *RR,void *t bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer) { + Metrics::pkt_network_config_request++; const uint64_t nwid = at(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_NETWORK_ID); const unsigned int hopCount = hops(); const uint64_t requestPacketId = packetId(); @@ -1081,6 +1109,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,void bool IncomingPacket::_doNETWORK_CONFIG(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer) { + Metrics::pkt_network_config++; const SharedPtr network(RR->node->network(at(ZT_PACKET_IDX_PAYLOAD))); if (network) { const uint64_t configUpdateId = network->handleConfigChunk(tPtr,packetId(),source(),*this,ZT_PACKET_IDX_PAYLOAD); @@ -1104,6 +1133,7 @@ bool IncomingPacket::_doNETWORK_CONFIG(const RuntimeEnvironment *RR,void *tPtr,c bool IncomingPacket::_doMULTICAST_GATHER(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer) { + Metrics::pkt_multicast_gather++; const uint64_t nwid = at(ZT_PROTO_VERB_MULTICAST_GATHER_IDX_NETWORK_ID); const unsigned int flags = (*this)[ZT_PROTO_VERB_MULTICAST_GATHER_IDX_FLAGS]; const MulticastGroup mg(MAC(field(ZT_PROTO_VERB_MULTICAST_GATHER_IDX_MAC,6),6),at(ZT_PROTO_VERB_MULTICAST_GATHER_IDX_ADI)); @@ -1144,6 +1174,7 @@ bool IncomingPacket::_doMULTICAST_GATHER(const RuntimeEnvironment *RR,void *tPtr bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer) { + Metrics::pkt_multicast_frame++; const uint64_t nwid = at(ZT_PROTO_VERB_MULTICAST_FRAME_IDX_NETWORK_ID); const unsigned int flags = (*this)[ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FLAGS]; @@ -1244,6 +1275,7 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,void *tPtr, bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer) { + Metrics::pkt_push_direct_paths++; const int64_t now = RR->node->now(); if (!peer->rateGatePushDirectPaths(now)) { @@ -1306,6 +1338,7 @@ bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,void *tPt bool IncomingPacket::_doUSER_MESSAGE(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer) { + Metrics::pkt_user_message++; if (likely(size() >= (ZT_PACKET_IDX_PAYLOAD + 8))) { ZT_UserMessage um; um.origin = peer->address().toInt(); @@ -1322,6 +1355,7 @@ bool IncomingPacket::_doUSER_MESSAGE(const RuntimeEnvironment *RR,void *tPtr,con bool IncomingPacket::_doREMOTE_TRACE(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer) { + Metrics::pkt_remote_trace++; ZT_RemoteTrace rt; const char *ptr = reinterpret_cast(data()) + ZT_PACKET_IDX_PAYLOAD; const char *const eof = reinterpret_cast(data()) + size(); @@ -1346,6 +1380,7 @@ bool IncomingPacket::_doREMOTE_TRACE(const RuntimeEnvironment *RR,void *tPtr,con bool IncomingPacket::_doPATH_NEGOTIATION_REQUEST(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr &peer) { + Metrics::pkt_path_negotiation_request++; uint64_t now = RR->node->now(); SharedPtr bond = peer->bond(); if (!bond || !bond->rateGatePathNegotiation(now, _path)) { diff --git a/node/Metrics.cpp b/node/Metrics.cpp index a89954f59..8ccef869f 100644 --- a/node/Metrics.cpp +++ b/node/Metrics.cpp @@ -22,6 +22,68 @@ namespace prometheus { namespace ZeroTier { namespace Metrics { + // Packet Type Counts + prometheus::simpleapi::counter_family_t packets + { "zt_packet_incoming", "incoming packet type counts"}; + prometheus::simpleapi::counter_metric_t pkt_error + { packets.Add({{"packet_type", "error"}}) }; + prometheus::simpleapi::counter_metric_t pkt_ack + { packets.Add({{"packet_type", "ack"}}) }; + prometheus::simpleapi::counter_metric_t pkt_qos + { packets.Add({{"packet_type", "qos"}}) }; + prometheus::simpleapi::counter_metric_t pkt_hello + { packets.Add({{"packet_type", "hello"}}) }; + prometheus::simpleapi::counter_metric_t pkt_ok + { packets.Add({{"packet_type", "ok"}}) }; + prometheus::simpleapi::counter_metric_t pkt_whois + { packets.Add({{"packet_type", "whois"}}) }; + prometheus::simpleapi::counter_metric_t pkt_rendezvous + { packets.Add({{"packet_type", "rendezvous"}}) }; + prometheus::simpleapi::counter_metric_t pkt_frame + { packets.Add({{"packet_type", "frame"}}) }; + prometheus::simpleapi::counter_metric_t pkt_ext_frame + { packets.Add({{"packet_type", "ext_frame"}}) }; + prometheus::simpleapi::counter_metric_t pkt_echo + { packets.Add({{"packet_type", "echo"}}) }; + prometheus::simpleapi::counter_metric_t pkt_multicast_like + { packets.Add({{"packet_type", "multicast_like"}}) }; + prometheus::simpleapi::counter_metric_t pkt_network_credentials + { packets.Add({{"packet_type", "network_credentials"}}) }; + prometheus::simpleapi::counter_metric_t pkt_network_config_request + { packets.Add({{"packet_type", "network_config_request"}}) }; + prometheus::simpleapi::counter_metric_t pkt_network_config + { packets.Add({{"packet_type", "network_config"}}) }; + prometheus::simpleapi::counter_metric_t pkt_multicast_gather + { packets.Add({{"packet_type", "multicast_gather"}}) }; + prometheus::simpleapi::counter_metric_t pkt_multicast_frame + { packets.Add({{"packet_type", "multicast_frame"}}) }; + prometheus::simpleapi::counter_metric_t pkt_push_direct_paths + { packets.Add({{"packet_type", "push_direct_paths"}}) }; + prometheus::simpleapi::counter_metric_t pkt_user_message + { packets.Add({{"packet_type", "user_message"}}) }; + prometheus::simpleapi::counter_metric_t pkt_remote_trace + { packets.Add({{"packet_type", "remote_trace"}}) }; + prometheus::simpleapi::counter_metric_t pkt_path_negotiation_request + { packets.Add({{"packet_type", "path_negotiation_request"}}) }; + + // Packet Error Counts + prometheus::simpleapi::counter_family_t packet_errors + { "zt_packet_incoming_error", "incoming packet errors"}; + prometheus::simpleapi::counter_metric_t pkt_error_obj_not_found + { packet_errors.Add({{"error_type", "obj_not_found"}}) }; + prometheus::simpleapi::counter_metric_t pkt_error_unsupported_op + { packet_errors.Add({{"error_type", "unsupported_operation"}}) }; + prometheus::simpleapi::counter_metric_t pkt_error_identity_collision + { packet_errors.Add({{"error_type", "identity_collision"}}) }; + prometheus::simpleapi::counter_metric_t pkt_error_need_membership_cert + { packet_errors.Add({{"error_type", "need_membership_certificate"}}) }; + prometheus::simpleapi::counter_metric_t pkt_error_network_access_denied + { packet_errors.Add({{"error_type", "network_access_denied"}}) }; + prometheus::simpleapi::counter_metric_t pkt_error_unwanted_multicast + { packet_errors.Add({{"error_type", "unwanted_multicast"}}) }; + prometheus::simpleapi::counter_metric_t pkt_error_authentication_required + { packet_errors.Add({{"error_type", "authentication_required"}}) }; + // Data Sent/Received Metrics prometheus::simpleapi::counter_metric_t udp_send { "zt_udp_data_sent", "number of bytes ZeroTier has sent via UDP" }; diff --git a/node/Metrics.hpp b/node/Metrics.hpp index 9dd77017d..3b65ea4b9 100644 --- a/node/Metrics.hpp +++ b/node/Metrics.hpp @@ -22,6 +22,40 @@ namespace prometheus { namespace ZeroTier { namespace Metrics { + // Packet Type Counts + extern prometheus::simpleapi::counter_family_t packets; + extern prometheus::simpleapi::counter_metric_t pkt_error; + extern prometheus::simpleapi::counter_metric_t pkt_ack; + extern prometheus::simpleapi::counter_metric_t pkt_qos; + extern prometheus::simpleapi::counter_metric_t pkt_hello; + extern prometheus::simpleapi::counter_metric_t pkt_ok; + extern prometheus::simpleapi::counter_metric_t pkt_whois; + extern prometheus::simpleapi::counter_metric_t pkt_rendezvous; + extern prometheus::simpleapi::counter_metric_t pkt_frame; + extern prometheus::simpleapi::counter_metric_t pkt_ext_frame; + extern prometheus::simpleapi::counter_metric_t pkt_echo; + extern prometheus::simpleapi::counter_metric_t pkt_multicast_like; + extern prometheus::simpleapi::counter_metric_t pkt_network_credentials; + extern prometheus::simpleapi::counter_metric_t pkt_network_config_request; + extern prometheus::simpleapi::counter_metric_t pkt_network_config; + extern prometheus::simpleapi::counter_metric_t pkt_multicast_gather; + extern prometheus::simpleapi::counter_metric_t pkt_multicast_frame; + extern prometheus::simpleapi::counter_metric_t pkt_push_direct_paths; + extern prometheus::simpleapi::counter_metric_t pkt_user_message; + extern prometheus::simpleapi::counter_metric_t pkt_remote_trace; + extern prometheus::simpleapi::counter_metric_t pkt_path_negotiation_request; + + // Packet Error Counts + extern prometheus::simpleapi::counter_family_t packet_errors; + extern prometheus::simpleapi::counter_metric_t pkt_error_obj_not_found; + extern prometheus::simpleapi::counter_metric_t pkt_error_unsupported_op; + extern prometheus::simpleapi::counter_metric_t pkt_error_identity_collision; + extern prometheus::simpleapi::counter_metric_t pkt_error_need_membership_cert; + extern prometheus::simpleapi::counter_metric_t pkt_error_network_access_denied; + extern prometheus::simpleapi::counter_metric_t pkt_error_unwanted_multicast; + extern prometheus::simpleapi::counter_metric_t pkt_error_authentication_required; + + // Data Sent/Received Metrics extern prometheus::simpleapi::counter_metric_t udp_send; extern prometheus::simpleapi::counter_metric_t udp_recv;