mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-01-29 15:43:52 +00:00
Plumbing through of remote trace into controller code.
This commit is contained in:
parent
0655a1fcbe
commit
4ecc0c59ca
@ -621,6 +621,15 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
|
||||
if (b.count("activeBridge")) member["activeBridge"] = OSUtils::jsonBool(b["activeBridge"],false);
|
||||
if (b.count("noAutoAssignIps")) member["noAutoAssignIps"] = OSUtils::jsonBool(b["noAutoAssignIps"],false);
|
||||
|
||||
if (b.count("remoteTraceTarget")) {
|
||||
const std::string rtt(OSUtils::jsonString(b["remoteTraceTarget"],""));
|
||||
if (rtt.length() == 10) {
|
||||
member["remoteTraceTarget"] = rtt;
|
||||
} else {
|
||||
member["remoteTraceTarget"] = json();
|
||||
}
|
||||
}
|
||||
|
||||
if (b.count("authorized")) {
|
||||
const bool newAuth = OSUtils::jsonBool(b["authorized"],false);
|
||||
if (newAuth != OSUtils::jsonBool(member["authorized"],false)) {
|
||||
@ -764,6 +773,15 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
|
||||
if (b.count("multicastLimit")) network["multicastLimit"] = OSUtils::jsonInt(b["multicastLimit"],32ULL);
|
||||
if (b.count("mtu")) network["mtu"] = std::max(std::min((unsigned int)OSUtils::jsonInt(b["mtu"],ZT_DEFAULT_MTU),(unsigned int)ZT_MAX_MTU),(unsigned int)ZT_MIN_MTU);
|
||||
|
||||
if (b.count("remoteTraceTarget")) {
|
||||
const std::string rtt(OSUtils::jsonString(b["remoteTraceTarget"],""));
|
||||
if (rtt.length() == 10) {
|
||||
network["remoteTraceTarget"] = rtt;
|
||||
} else {
|
||||
network["remoteTraceTarget"] = json();
|
||||
}
|
||||
}
|
||||
|
||||
if (b.count("v4AssignMode")) {
|
||||
json nv4m;
|
||||
json &v4m = b["v4AssignMode"];
|
||||
@ -1065,6 +1083,55 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpDELETE(
|
||||
return 404;
|
||||
}
|
||||
|
||||
void EmbeddedNetworkController::handleRemoteTrace(const ZT_RemoteTrace &rt)
|
||||
{
|
||||
// Convert Dictionary into JSON object
|
||||
json d;
|
||||
char *saveptr = (char *)0;
|
||||
for(char *l=Utils::stok(rt.data,"\n",&saveptr);(l);l=Utils::stok((char *)0,"\n",&saveptr)) {
|
||||
char *eq = strchr(l,'=');
|
||||
if (eq > l) {
|
||||
std::string k(l,(unsigned long)(eq - l));
|
||||
std::string v;
|
||||
++eq;
|
||||
while (*eq) {
|
||||
if (*eq == '\\') {
|
||||
++eq;
|
||||
if (*eq) {
|
||||
switch(*eq) {
|
||||
case 'r':
|
||||
v.push_back('\r');
|
||||
break;
|
||||
case 'n':
|
||||
v.push_back('\n');
|
||||
break;
|
||||
case '0':
|
||||
v.push_back((char)0);
|
||||
break;
|
||||
case 'e':
|
||||
v.push_back('=');
|
||||
break;
|
||||
default:
|
||||
v.push_back(*eq);
|
||||
break;
|
||||
}
|
||||
++eq;
|
||||
}
|
||||
} else {
|
||||
v.push_back(*(eq++));
|
||||
}
|
||||
}
|
||||
if (v.length() > 0)
|
||||
d[k] = v;
|
||||
}
|
||||
}
|
||||
|
||||
char p[128];
|
||||
OSUtils::ztsnprintf(p,sizeof(p),"trace/%.10llx_%.16llx.json",rt.origin,OSUtils::now());
|
||||
_db.writeRaw(p,OSUtils::jsonDump(d));
|
||||
//fprintf(stdout,"%s\n",OSUtils::jsonDump(d).c_str()); fflush(stdout);
|
||||
}
|
||||
|
||||
void EmbeddedNetworkController::threadMain()
|
||||
throw()
|
||||
{
|
||||
|
@ -90,6 +90,8 @@ public:
|
||||
std::string &responseBody,
|
||||
std::string &responseContentType);
|
||||
|
||||
void handleRemoteTrace(const ZT_RemoteTrace &rt);
|
||||
|
||||
void threadMain()
|
||||
throw();
|
||||
|
||||
@ -142,6 +144,7 @@ private:
|
||||
if (!member.count("vRev")) member["vRev"] = -1;
|
||||
if (!member.count("vProto")) member["vProto"] = -1;
|
||||
if (!member.count("physicalAddr")) member["physicalAddr"] = nlohmann::json();
|
||||
if (!member.count("remoteTraceTarget")) member["remoteTraceTarget"] = nlohmann::json();
|
||||
member["objtype"] = "member";
|
||||
}
|
||||
inline void _initNetwork(nlohmann::json &network)
|
||||
@ -159,6 +162,7 @@ private:
|
||||
if (!network.count("routes")) network["routes"] = nlohmann::json::array();
|
||||
if (!network.count("ipAssignmentPools")) network["ipAssignmentPools"] = nlohmann::json::array();
|
||||
if (!network.count("mtu")) network["mtu"] = ZT_DEFAULT_MTU;
|
||||
if (!network.count("remoteTraceTarget")) network["remoteTraceTarget"] = nlohmann::json();
|
||||
if (!network.count("rules")) {
|
||||
// If unspecified, rules are set to allow anything and behave like a flat L2 segment
|
||||
network["rules"] = {{
|
||||
|
@ -470,9 +470,52 @@ enum ZT_Event
|
||||
*
|
||||
* Meta-data: ZT_UserMessage structure
|
||||
*/
|
||||
ZT_EVENT_USER_MESSAGE = 6
|
||||
ZT_EVENT_USER_MESSAGE = 6,
|
||||
|
||||
/**
|
||||
* Remote trace received
|
||||
*
|
||||
* These are generated when a VERB_REMOTE_TRACE is received. Note
|
||||
* that any node can fling one of these at us. It is your responsibility
|
||||
* to filter and determine if it's worth paying attention to. If it's
|
||||
* not just drop it. Most nodes that are not active controllers ignore
|
||||
* these, and controllers only save them if they pertain to networks
|
||||
* with remote tracing enabled.
|
||||
*
|
||||
* Meta-data: ZT_RemoteTrace structure
|
||||
*/
|
||||
ZT_EVENT_REMOTE_TRACE = 7
|
||||
};
|
||||
|
||||
/**
|
||||
* Payload of REMOTE_TRACE event
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
* ZeroTier address of sender
|
||||
*/
|
||||
uint64_t origin;
|
||||
|
||||
/**
|
||||
* Null-terminated Dictionary containing key/value pairs sent by origin
|
||||
*
|
||||
* This *should* be a dictionary, but the implementation only checks
|
||||
* that it is a valid non-empty C-style null-terminated string. Be very
|
||||
* careful to use a well-tested parser to parse this as it represents
|
||||
* data received from a potentially un-trusted peer on the network.
|
||||
* Invalid payloads should be dropped.
|
||||
*
|
||||
* The contents of data[] may be modified.
|
||||
*/
|
||||
char *data;
|
||||
|
||||
/**
|
||||
* Length of dict[] in bytes, including terminating null
|
||||
*/
|
||||
unsigned int len;
|
||||
} ZT_RemoteTrace;
|
||||
|
||||
/**
|
||||
* User message used with ZT_EVENT_USER_MESSAGE
|
||||
*
|
||||
|
@ -1192,7 +1192,7 @@ bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,void *tPt
|
||||
bool IncomingPacket::_doUSER_MESSAGE(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer)
|
||||
{
|
||||
try {
|
||||
if (size() >= (ZT_PACKET_IDX_PAYLOAD + 8)) {
|
||||
if (likely(size() >= (ZT_PACKET_IDX_PAYLOAD + 8))) {
|
||||
ZT_UserMessage um;
|
||||
um.origin = peer->address().toInt();
|
||||
um.typeId = at<uint64_t>(ZT_PACKET_IDX_PAYLOAD);
|
||||
@ -1207,6 +1207,31 @@ bool IncomingPacket::_doUSER_MESSAGE(const RuntimeEnvironment *RR,void *tPtr,con
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IncomingPacket::_doREMOTE_TRACE(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer)
|
||||
{
|
||||
ZT_RemoteTrace rt;
|
||||
try {
|
||||
const char *ptr = reinterpret_cast<const char *>(data()) + ZT_PACKET_IDX_PAYLOAD;
|
||||
const char *const eof = reinterpret_cast<const char *>(data()) + size();
|
||||
rt.origin = peer->address().toInt();
|
||||
rt.data = const_cast<char *>(ptr); // start of first string
|
||||
while (ptr < eof) {
|
||||
if (!*ptr) { // end of string
|
||||
rt.len = (unsigned int)(ptr - rt.data);
|
||||
if ((rt.len > 0)&&(rt.len <= ZT_MAX_REMOTE_TRACE_SIZE))
|
||||
RR->node->postEvent(tPtr,ZT_EVENT_REMOTE_TRACE,&rt);
|
||||
rt.data = const_cast<char *>(++ptr); // start of next string, if any
|
||||
} else {
|
||||
++ptr;
|
||||
}
|
||||
}
|
||||
peer->received(tPtr,_path,hops(),packetId(),Packet::VERB_REMOTE_TRACE,0,Packet::VERB_NOP,false,0);
|
||||
} catch ( ... ) {
|
||||
RR->t->incomingPacketInvalid(tPtr,_path,packetId(),source(),hops(),Packet::VERB_REMOTE_TRACE,"unexpected exception");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void IncomingPacket::_sendErrorNeedCredentials(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer,const uint64_t nwid)
|
||||
{
|
||||
const uint64_t now = RR->node->now();
|
||||
|
@ -139,6 +139,7 @@ private:
|
||||
bool _doMULTICAST_FRAME(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
|
||||
bool _doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
|
||||
bool _doUSER_MESSAGE(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
|
||||
bool _doREMOTE_TRACE(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer);
|
||||
|
||||
void _sendErrorNeedCredentials(const RuntimeEnvironment *RR,void *tPtr,const SharedPtr<Peer> &peer,const uint64_t nwid);
|
||||
|
||||
|
@ -978,9 +978,6 @@ public:
|
||||
* The instance ID is a random 64-bit value generated by each ZeroTier
|
||||
* node on startup. This is helpful in identifying traces from different
|
||||
* members of a cluster.
|
||||
*
|
||||
* The Dictionary serialization format is the same as used for network
|
||||
* configurations. The maximum size of a trace is 10000 bytes.
|
||||
*/
|
||||
VERB_REMOTE_TRACE = 0x15
|
||||
};
|
||||
|
@ -2058,6 +2058,12 @@ public:
|
||||
}
|
||||
} break;
|
||||
|
||||
case ZT_EVENT_REMOTE_TRACE: {
|
||||
const ZT_RemoteTrace *rt = reinterpret_cast<const ZT_RemoteTrace *>(metaData);
|
||||
if ((rt)&&(rt->len > 0)&&(rt->len <= ZT_MAX_REMOTE_TRACE_SIZE)&&(rt->data))
|
||||
_controller->handleRemoteTrace(*rt);
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user