mirror of
https://github.com/ZeroTier/ZeroTierOne
synced 2025-08-21 05:43:59 -07:00
Add events for packet decode errors, etc., and re-implement TRACE as an event.
This commit is contained in:
parent
9d9d0ef12c
commit
4d5a6a25d3
8 changed files with 149 additions and 42 deletions
|
@ -213,7 +213,8 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR)
|
|||
unsigned char key[ZT_PEER_SECRET_KEY_LENGTH];
|
||||
if (RR->identity.agree(id,key,ZT_PEER_SECRET_KEY_LENGTH)) {
|
||||
if (dearmor(key)) { // ensure packet is authentic, otherwise drop
|
||||
LOG("rejected HELLO from %s(%s): address already claimed",id.address().toString().c_str(),_remoteAddress.toString().c_str());
|
||||
RR->node->postEvent(ZT1_EVENT_AUTHENTICATION_FAILURE,(const void *)&_remoteAddress);
|
||||
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());
|
||||
|
@ -221,10 +222,12 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR)
|
|||
outp.armor(key,true);
|
||||
RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation);
|
||||
} else {
|
||||
LOG("rejected HELLO from %s(%s): packet failed authentication",id.address().toString().c_str(),_remoteAddress.toString().c_str());
|
||||
RR->node->postEvent(ZT1_EVENT_AUTHENTICATION_FAILURE,(const void *)&_remoteAddress);
|
||||
TRACE("rejected HELLO from %s(%s): packet failed authentication",id.address().toString().c_str(),_remoteAddress.toString().c_str());
|
||||
}
|
||||
} else {
|
||||
LOG("rejected HELLO from %s(%s): key agreement failed",id.address().toString().c_str(),_remoteAddress.toString().c_str());
|
||||
RR->node->postEvent(ZT1_EVENT_AUTHENTICATION_FAILURE,(const void *)&_remoteAddress);
|
||||
TRACE("rejected HELLO from %s(%s): key agreement failed",id.address().toString().c_str(),_remoteAddress.toString().c_str());
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -232,7 +235,8 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR)
|
|||
// Identity is the same as the one we already have -- check packet integrity
|
||||
|
||||
if (!dearmor(peer->key())) {
|
||||
LOG("rejected HELLO from %s(%s): packet failed authentication",id.address().toString().c_str(),_remoteAddress.toString().c_str());
|
||||
RR->node->postEvent(ZT1_EVENT_AUTHENTICATION_FAILURE,(const void *)&_remoteAddress);
|
||||
TRACE("rejected HELLO from %s(%s): packet failed authentication",id.address().toString().c_str(),_remoteAddress.toString().c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -242,13 +246,15 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR)
|
|||
// We don't already have an identity with this address -- validate and learn it
|
||||
|
||||
if (!id.locallyValidate()) {
|
||||
RR->node->postEvent(ZT1_EVENT_AUTHENTICATION_FAILURE,(const void *)&_remoteAddress);
|
||||
TRACE("dropped HELLO from %s(%s): identity invalid",id.address().toString().c_str(),_remoteAddress.toString().c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
SharedPtr<Peer> newPeer(new Peer(RR->identity,id));
|
||||
if (!dearmor(newPeer->key())) {
|
||||
LOG("rejected HELLO from %s(%s): packet failed authentication",id.address().toString().c_str(),_remoteAddress.toString().c_str());
|
||||
RR->node->postEvent(ZT1_EVENT_AUTHENTICATION_FAILURE,(const void *)&_remoteAddress);
|
||||
TRACE("rejected HELLO from %s(%s): packet failed authentication",id.address().toString().c_str(),_remoteAddress.toString().c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -672,7 +678,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons
|
|||
case NetworkConfigMaster::NETCONF_QUERY_OK: {
|
||||
const std::string netconfStr(netconf.toString());
|
||||
if (netconfStr.length() > 0xffff) { // sanity check since field ix 16-bit
|
||||
LOG("NETWORK_CONFIG_REQUEST failed: internal error: netconf size %u is too large",(unsigned int)netconfStr.length());
|
||||
TRACE("NETWORK_CONFIG_REQUEST failed: internal error: netconf size %u is too large",(unsigned int)netconfStr.length());
|
||||
} else {
|
||||
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_OK);
|
||||
outp.append((unsigned char)Packet::VERB_NETWORK_CONFIG_REQUEST);
|
||||
|
@ -682,7 +688,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons
|
|||
outp.append(netconfStr.data(),netconfStr.length());
|
||||
outp.compress();
|
||||
if (outp.size() > ZT_PROTO_MAX_PACKET_LENGTH) {
|
||||
LOG("NETWORK_CONFIG_REQUEST failed: internal error: netconf size %u is too large",(unsigned int)netconfStr.length());
|
||||
TRACE("NETWORK_CONFIG_REQUEST failed: internal error: netconf size %u is too large",(unsigned int)netconfStr.length());
|
||||
} else {
|
||||
RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation);
|
||||
}
|
||||
|
@ -709,7 +715,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *RR,cons
|
|||
RR->node->putPacket(_remoteAddress,outp.data(),outp.size(),_linkDesperation);
|
||||
} break;
|
||||
case NetworkConfigMaster::NETCONF_QUERY_INTERNAL_SERVER_ERROR:
|
||||
LOG("NETWORK_CONFIG_REQUEST failed: internal error: %s",netconf.get("error","(unknown)").c_str());
|
||||
TRACE("NETWORK_CONFIG_REQUEST failed: internal error: %s",netconf.get("error","(unknown)").c_str());
|
||||
break;
|
||||
default:
|
||||
TRACE("NETWORK_CONFIG_REQUEST failed: invalid return value from NetworkConfigMaster::doNetworkConfigRequest()");
|
||||
|
|
|
@ -199,12 +199,12 @@ bool Network::applyConfiguration(const SharedPtr<NetworkConfig> &conf)
|
|||
|
||||
return true;
|
||||
} else {
|
||||
LOG("ignored invalid configuration for network %.16llx (configuration contains mismatched network ID or issued-to address)",(unsigned long long)_id);
|
||||
TRACE("ignored invalid configuration for network %.16llx (configuration contains mismatched network ID or issued-to address)",(unsigned long long)_id);
|
||||
}
|
||||
} catch (std::exception &exc) {
|
||||
LOG("ignored invalid configuration for network %.16llx (%s)",(unsigned long long)_id,exc.what());
|
||||
TRACE("ignored invalid configuration for network %.16llx (%s)",(unsigned long long)_id,exc.what());
|
||||
} catch ( ... ) {
|
||||
LOG("ignored invalid configuration for network %.16llx (unknown exception)",(unsigned long long)_id);
|
||||
TRACE("ignored invalid configuration for network %.16llx (unknown exception)",(unsigned long long)_id);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -227,7 +227,7 @@ int Network::setConfiguration(const Dictionary &conf,bool saveToDisk)
|
|||
return 2; // OK and configuration has changed
|
||||
}
|
||||
} catch ( ... ) {
|
||||
LOG("ignored invalid configuration for network %.16llx (dictionary decode failed)",(unsigned long long)_id);
|
||||
TRACE("ignored invalid configuration for network %.16llx (dictionary decode failed)",(unsigned long long)_id);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -288,7 +288,7 @@ void Network::addMembershipCertificate(const CertificateOfMembership &cert,bool
|
|||
// Check signature, log and return if cert is invalid
|
||||
if (!forceAccept) {
|
||||
if (cert.signedBy() != controller()) {
|
||||
LOG("rejected network membership certificate for %.16llx signed by %s: signer not a controller of this network",(unsigned long long)_id,cert.signedBy().toString().c_str());
|
||||
TRACE("rejected network membership certificate for %.16llx signed by %s: signer not a controller of this network",(unsigned long long)_id,cert.signedBy().toString().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -302,7 +302,7 @@ void Network::addMembershipCertificate(const CertificateOfMembership &cert,bool
|
|||
}
|
||||
|
||||
if (!cert.verify(signer->identity())) {
|
||||
LOG("rejected network membership certificate for %.16llx signed by %s: signature check failed",(unsigned long long)_id,cert.signedBy().toString().c_str());
|
||||
TRACE("rejected network membership certificate for %.16llx signed by %s: signature check failed",(unsigned long long)_id,cert.signedBy().toString().c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -333,6 +333,13 @@ public:
|
|||
*/
|
||||
void destroy();
|
||||
|
||||
inline bool operator==(const Network &n) const throw() { return (_id == n._id); }
|
||||
inline bool operator!=(const Network &n) const throw() { return (_id != n._id); }
|
||||
inline bool operator<(const Network &n) const throw() { return (_id < n._id); }
|
||||
inline bool operator>(const Network &n) const throw() { return (_id > n._id); }
|
||||
inline bool operator<=(const Network &n) const throw() { return (_id <= n._id); }
|
||||
inline bool operator>=(const Network &n) const throw() { return (_id >= n._id); }
|
||||
|
||||
private:
|
||||
ZT1_VirtualNetworkStatus _status() const;
|
||||
void _externalConfig(ZT1_VirtualNetworkConfig *ec) const; // assumes _lock is locked
|
||||
|
|
|
@ -175,14 +175,10 @@ ZT1_ResultCode Node::processVirtualNetworkFrame(
|
|||
return rc;
|
||||
} else _now = now;
|
||||
|
||||
try {
|
||||
SharedPtr<Network> nw(network(nwid));
|
||||
if (nw)
|
||||
RR->sw->onLocalEthernet(nw,MAC(sourceMac),MAC(destMac),etherType,vlanId,frameData,frameLength);
|
||||
else return ZT1_RESULT_ERROR_NETWORK_NOT_FOUND;
|
||||
} catch ( ... ) {
|
||||
return ZT1_RESULT_FATAL_ERROR_INTERNAL;
|
||||
}
|
||||
SharedPtr<Network> nw(network(nwid));
|
||||
if (nw)
|
||||
RR->sw->onLocalEthernet(nw,MAC(sourceMac),MAC(destMac),etherType,vlanId,frameData,frameLength);
|
||||
else return ZT1_RESULT_ERROR_NETWORK_NOT_FOUND;
|
||||
|
||||
return ZT1_RESULT_OK;
|
||||
}
|
||||
|
@ -364,10 +360,37 @@ void Node::postNewerVersionIfNewer(unsigned int major,unsigned int minor,unsigne
|
|||
_newestVersionSeen[0] = major;
|
||||
_newestVersionSeen[1] = minor;
|
||||
_newestVersionSeen[2] = rev;
|
||||
this->postEvent(ZT1_EVENT_SAW_MORE_RECENT_VERSION);
|
||||
this->postEvent(ZT1_EVENT_SAW_MORE_RECENT_VERSION,(const void *)_newestVersionSeen);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ZT_TRACE
|
||||
void Node::postTrace(const char *module,unsigned int line,const char *fmt,...)
|
||||
{
|
||||
static Mutex traceLock;
|
||||
|
||||
va_list ap;
|
||||
char tmp1[1024],tmp2[1024],tmp3[256];
|
||||
|
||||
Mutex::Lock _l(traceLock);
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
ctime_s(tmp3,sizeof(tmp3),&now);
|
||||
const char *nowstr = tmp3;
|
||||
#else
|
||||
const char *nowstr = ctime_r(&now,tmp3);
|
||||
#endif
|
||||
|
||||
va_start(ap,fmt);
|
||||
vsnprintf(tmp2,sizeof(tmp2),fmt,ap);
|
||||
va_end(ap);
|
||||
tmp2[sizeof(tmp2)-1] = (char)0;
|
||||
|
||||
Utils::snprintf(tmp1,sizeof(tmp1),"[%s] %s:%u %s",nowstr,module,line,tmp2);
|
||||
postEvent(ZT1_EVENT_TRACE,tmp1);
|
||||
}
|
||||
#endif // ZT_TRACE
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
/****************************************************************************/
|
||||
|
@ -421,7 +444,8 @@ enum ZT1_ResultCode ZT1_Node_processWirePacket(
|
|||
} catch (std::bad_alloc &exc) {
|
||||
return ZT1_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
|
||||
} catch ( ... ) {
|
||||
return ZT1_RESULT_ERROR_PACKET_INVALID;
|
||||
reinterpret_cast<ZeroTier::Node *>(node)->postEvent(ZT1_EVENT_INVALID_PACKET,(const void *)remoteAddress);
|
||||
return ZT1_RESULT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,13 @@
|
|||
#include "MAC.hpp"
|
||||
#include "Network.hpp"
|
||||
|
||||
#undef TRACE
|
||||
#ifdef ZT_TRACE
|
||||
#define TRACE(f,...) RR->node->postTrace(__FILE__,__LINE__,f,##__VA_ARGS__)
|
||||
#else
|
||||
#define TRACE(f,...) {}
|
||||
#endif
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
class RuntimeEnvironment;
|
||||
|
@ -164,6 +171,9 @@ public:
|
|||
return nw;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Overall system level of desperation based on how long it's been since an upstream node (supernode) has talked to us
|
||||
*/
|
||||
inline unsigned int coreDesperation() const throw() { return _coreDesperation; }
|
||||
|
||||
inline bool dataStorePut(const char *name,const void *data,unsigned int len,bool secure) { return (_dataStorePutFunction(reinterpret_cast<ZT1_Node *>(this),name,data,len,(int)secure) == 0); }
|
||||
|
@ -171,12 +181,32 @@ public:
|
|||
inline void dataStoreDelete(const char *name) { _dataStorePutFunction(reinterpret_cast<ZT1_Node *>(this),name,(const void *)0,0,0); }
|
||||
std::string dataStoreGet(const char *name);
|
||||
|
||||
inline void postEvent(ZT1_Event ev) { _eventCallback(reinterpret_cast<ZT1_Node *>(this),ev); }
|
||||
/**
|
||||
* Post an event to the external user
|
||||
*
|
||||
* @param ev Event type
|
||||
* @param md Meta-data (default: NULL/none)
|
||||
*/
|
||||
inline void postEvent(ZT1_Event ev,const void *md = (const void *)0) { _eventCallback(reinterpret_cast<ZT1_Node *>(this),ev,md); }
|
||||
|
||||
/**
|
||||
* Update virtual network port configuration
|
||||
*
|
||||
* @param nwid Network ID
|
||||
* @param op Configuration operation
|
||||
* @param nc Network configuration
|
||||
*/
|
||||
inline int configureVirtualNetworkPort(uint64_t nwid,ZT1_VirtualNetworkConfigOperation op,const ZT1_VirtualNetworkConfig *nc) { return _virtualNetworkConfigFunction(reinterpret_cast<ZT1_Node *>(this),nwid,op,nc); }
|
||||
|
||||
/**
|
||||
* If this version is newer than the newest we've seen, post a new version seen event
|
||||
*/
|
||||
void postNewerVersionIfNewer(unsigned int major,unsigned int minor,unsigned int rev);
|
||||
|
||||
#ifdef ZT_TRACE
|
||||
void postTrace(const char *module,unsigned int line,const char *fmt,...);
|
||||
#endif
|
||||
|
||||
private:
|
||||
RuntimeEnvironment *RR;
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c
|
|||
bool fromBridged = false;
|
||||
if (from != network->mac()) {
|
||||
if (!network->permitsBridging(RR->identity.address())) {
|
||||
LOG("%.16llx: %s -> %s %s not forwarded, bridging disabled or this peer not a bridge",network->id(),from.toString().c_str(),to.toString().c_str(),etherTypeName(etherType));
|
||||
TRACE("%.16llx: %s -> %s %s not forwarded, bridging disabled or this peer not a bridge",network->id(),from.toString().c_str(),to.toString().c_str(),etherTypeName(etherType));
|
||||
return;
|
||||
}
|
||||
fromBridged = true;
|
||||
|
|
|
@ -86,7 +86,7 @@ void Topology::setSupernodes(const Dictionary &sn)
|
|||
if (udp.length() > 0)
|
||||
a.push_back(InetAddress(udp));
|
||||
} catch ( ... ) {
|
||||
LOG("supernode list contained invalid entry for: %s",d->first.c_str());
|
||||
TRACE("supernode list contained invalid entry for: %s",d->first.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue