summaryrefslogtreecommitdiff
path: root/node
diff options
context:
space:
mode:
Diffstat (limited to 'node')
-rw-r--r--node/Address.hpp15
-rw-r--r--node/CertificateOfMembership.cpp7
-rw-r--r--node/Dictionary.hpp6
-rw-r--r--node/Identity.cpp26
-rw-r--r--node/Identity.hpp18
-rw-r--r--node/InetAddress.cpp195
-rw-r--r--node/InetAddress.hpp94
-rw-r--r--node/MAC.hpp83
-rw-r--r--node/MulticastGroup.hpp12
-rw-r--r--node/Network.cpp14
-rw-r--r--node/NetworkConfig.cpp12
-rw-r--r--node/Node.cpp51
-rw-r--r--node/Node.hpp4
-rw-r--r--node/RuntimeEnvironment.hpp10
-rw-r--r--node/Topology.cpp8
-rw-r--r--node/Utils.cpp114
-rw-r--r--node/Utils.hpp182
17 files changed, 362 insertions, 489 deletions
diff --git a/node/Address.hpp b/node/Address.hpp
index 98e32858..12c52a3f 100644
--- a/node/Address.hpp
+++ b/node/Address.hpp
@@ -141,20 +141,9 @@ public:
/**
* @return Hexadecimal string
*/
- inline std::string toString() const
+ inline char *toString(char buf[11]) const
{
- char buf[16];
- Utils::ztsnprintf(buf,sizeof(buf),"%.10llx",(unsigned long long)_a);
- return std::string(buf);
- };
-
- /**
- * @param buf Buffer to fill
- * @param len Length of buffer
- */
- inline void toString(char *buf,unsigned int len) const
- {
- Utils::ztsnprintf(buf,len,"%.10llx",(unsigned long long)_a);
+ return Utils::hex10(_a,buf);
}
/**
diff --git a/node/CertificateOfMembership.cpp b/node/CertificateOfMembership.cpp
index a5445e42..100253e1 100644
--- a/node/CertificateOfMembership.cpp
+++ b/node/CertificateOfMembership.cpp
@@ -57,6 +57,7 @@ void CertificateOfMembership::setQualifier(uint64_t id,uint64_t value,uint64_t m
std::string CertificateOfMembership::toString() const
{
+ char tmp[ZT_NETWORK_COM_MAX_QUALIFIERS * 32];
std::string s;
s.append("1:"); // COM_UINT64_ED25519
@@ -69,7 +70,7 @@ std::string CertificateOfMembership::toString() const
buf[ptr++] = Utils::hton(_qualifiers[i].value);
buf[ptr++] = Utils::hton(_qualifiers[i].maxDelta);
}
- s.append(Utils::hex(buf,ptr * sizeof(uint64_t)));
+ s.append(Utils::hex(buf,ptr * sizeof(uint64_t),tmp));
delete [] buf;
} catch ( ... ) {
delete [] buf;
@@ -78,11 +79,11 @@ std::string CertificateOfMembership::toString() const
s.push_back(':');
- s.append(_signedBy.toString());
+ s.append(_signedBy.toString(tmp));
if (_signedBy) {
s.push_back(':');
- s.append(Utils::hex(_signature.data,(unsigned int)_signature.size()));
+ s.append(Utils::hex(_signature.data,(unsigned int)_signature.size(),tmp));
}
return s;
diff --git a/node/Dictionary.hpp b/node/Dictionary.hpp
index 0b000f13..6cbbfc0e 100644
--- a/node/Dictionary.hpp
+++ b/node/Dictionary.hpp
@@ -391,8 +391,7 @@ public:
inline bool add(const char *key,uint64_t value)
{
char tmp[32];
- Utils::ztsnprintf(tmp,sizeof(tmp),"%llx",(unsigned long long)value);
- return this->add(key,tmp,-1);
+ return this->add(key,Utils::hex(value,tmp),-1);
}
/**
@@ -401,8 +400,7 @@ public:
inline bool add(const char *key,const Address &a)
{
char tmp[32];
- Utils::ztsnprintf(tmp,sizeof(tmp),"%.10llx",(unsigned long long)a.toInt());
- return this->add(key,tmp,-1);
+ return this->add(key,Utils::hex(a.toInt(),tmp),-1);
}
/**
diff --git a/node/Identity.cpp b/node/Identity.cpp
index ba77aa47..3b00b4c0 100644
--- a/node/Identity.cpp
+++ b/node/Identity.cpp
@@ -136,19 +136,23 @@ bool Identity::locallyValidate() const
(digest[63] == addrb[4]));
}
-std::string Identity::toString(bool includePrivate) const
+char *Identity::toString(bool includePrivate,char buf[ZT_IDENTITY_STRING_BUFFER_LENGTH]) const
{
- std::string r;
-
- r.append(_address.toString());
- r.append(":0:"); // 0 == ZT_OBJECT_TYPE_IDENTITY
- r.append(Utils::hex(_publicKey.data,(unsigned int)_publicKey.size()));
+ char *p = buf;
+ Utils::hex10(_address.toInt(),p);
+ p += 10;
+ *(p++) = ':';
+ *(p++) = '0';
+ *(p++) = ':';
+ Utils::hex(_publicKey.data,ZT_C25519_PUBLIC_KEY_LEN,p);
+ p += ZT_C25519_PUBLIC_KEY_LEN * 2;
if ((_privateKey)&&(includePrivate)) {
- r.push_back(':');
- r.append(Utils::hex(_privateKey->data,(unsigned int)_privateKey->size()));
+ *(p++) = ':';
+ Utils::hex(_privateKey->data,ZT_C25519_PRIVATE_KEY_LEN,p);
+ p += ZT_C25519_PRIVATE_KEY_LEN * 2;
}
-
- return r;
+ *(p++) = (char)0;
+ return buf;
}
bool Identity::fromString(const char *str)
@@ -157,7 +161,7 @@ bool Identity::fromString(const char *str)
return false;
char *saveptr = (char *)0;
- char tmp[1024];
+ char tmp[ZT_IDENTITY_STRING_BUFFER_LENGTH];
if (!Utils::scopy(tmp,sizeof(tmp),str))
return false;
diff --git a/node/Identity.hpp b/node/Identity.hpp
index 79e17f4d..5804b9f8 100644
--- a/node/Identity.hpp
+++ b/node/Identity.hpp
@@ -29,7 +29,6 @@
#include <stdio.h>
#include <stdlib.h>
-#include <string>
#include "Constants.hpp"
#include "Array.hpp"
@@ -39,6 +38,8 @@
#include "Buffer.hpp"
#include "SHA512.hpp"
+#define ZT_IDENTITY_STRING_BUFFER_LENGTH 384
+
namespace ZeroTier {
/**
@@ -66,16 +67,7 @@ public:
{
}
- Identity(const char *str)
- throw(std::invalid_argument) :
- _privateKey((C25519::Private *)0)
- {
- if (!fromString(str))
- throw std::invalid_argument(std::string("invalid string-serialized identity: ") + str);
- }
-
- Identity(const std::string &str)
- throw(std::invalid_argument) :
+ Identity(const char *str) :
_privateKey((C25519::Private *)0)
{
if (!fromString(str))
@@ -277,9 +269,10 @@ public:
* Serialize to a more human-friendly string
*
* @param includePrivate If true, include private key (if it exists)
+ * @param buf Buffer to store string
* @return ASCII string representation of identity
*/
- std::string toString(bool includePrivate) const;
+ char *toString(bool includePrivate,char buf[ZT_IDENTITY_STRING_BUFFER_LENGTH]) const;
/**
* Deserialize a human-friendly string
@@ -291,7 +284,6 @@ public:
* @return True if deserialization appears successful
*/
bool fromString(const char *str);
- inline bool fromString(const std::string &str) { return fromString(str.c_str()); }
/**
* @return C25519 public key
diff --git a/node/InetAddress.cpp b/node/InetAddress.cpp
index 17d7c72e..f7585bdb 100644
--- a/node/InetAddress.cpp
+++ b/node/InetAddress.cpp
@@ -5,7 +5,7 @@
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * (at your oion) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -40,7 +40,6 @@ const InetAddress InetAddress::LO4((const void *)("\x7f\x00\x00\x01"),4,0);
const InetAddress InetAddress::LO6((const void *)("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"),16,0);
InetAddress::IpScope InetAddress::ipScope() const
- throw()
{
switch(ss_family) {
@@ -111,27 +110,7 @@ InetAddress::IpScope InetAddress::ipScope() const
return IP_SCOPE_NONE;
}
-void InetAddress::set(const std::string &ip,unsigned int port)
- throw()
-{
- memset(this,0,sizeof(InetAddress));
- if (ip.find(':') != std::string::npos) {
- struct sockaddr_in6 *sin6 = reinterpret_cast<struct sockaddr_in6 *>(this);
- ss_family = AF_INET6;
- sin6->sin6_port = Utils::hton((uint16_t)port);
- if (inet_pton(AF_INET6,ip.c_str(),(void *)&(sin6->sin6_addr.s6_addr)) <= 0)
- memset(this,0,sizeof(InetAddress));
- } else if (ip.find('.') != std::string::npos) {
- struct sockaddr_in *sin = reinterpret_cast<struct sockaddr_in *>(this);
- ss_family = AF_INET;
- sin->sin_port = Utils::hton((uint16_t)port);
- if (inet_pton(AF_INET,ip.c_str(),(void *)&(sin->sin_addr.s_addr)) <= 0)
- memset(this,0,sizeof(InetAddress));
- }
-}
-
void InetAddress::set(const void *ipBytes,unsigned int ipLen,unsigned int port)
- throw()
{
memset(this,0,sizeof(InetAddress));
if (ipLen == 4) {
@@ -147,90 +126,98 @@ void InetAddress::set(const void *ipBytes,unsigned int ipLen,unsigned int port)
}
}
-std::string InetAddress::toString() const
+char *InetAddress::toString(char buf[64]) const
{
- char buf[128];
- switch(ss_family) {
- case AF_INET:
- Utils::ztsnprintf(buf,sizeof(buf),"%d.%d.%d.%d/%d",
- (int)(reinterpret_cast<const unsigned char *>(&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr)))[0],
- (int)(reinterpret_cast<const unsigned char *>(&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr)))[1],
- (int)(reinterpret_cast<const unsigned char *>(&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr)))[2],
- (int)(reinterpret_cast<const unsigned char *>(&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr)))[3],
- (int)Utils::ntoh((uint16_t)(reinterpret_cast<const struct sockaddr_in *>(this)->sin_port))
- );
- return std::string(buf);
- case AF_INET6:
- Utils::ztsnprintf(buf,sizeof(buf),"%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x/%d",
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[0]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[1]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[2]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[3]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[4]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[5]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[6]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[7]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[8]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[9]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[10]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[11]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[12]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[13]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[14]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[15]),
- (int)Utils::ntoh((uint16_t)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_port))
- );
- return std::string(buf);
+ char *p = toIpString(buf);
+ if (*p) {
+ while (*p) ++p;
+ *(p++) = '/';
+ Utils::decimal(port(),p);
}
- return std::string();
+ return buf;
}
-std::string InetAddress::toIpString() const
+char *InetAddress::toIpString(char buf[64]) const
{
- char buf[128];
switch(ss_family) {
- case AF_INET:
- Utils::ztsnprintf(buf,sizeof(buf),"%d.%d.%d.%d",
- (int)(reinterpret_cast<const unsigned char *>(&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr)))[0],
- (int)(reinterpret_cast<const unsigned char *>(&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr)))[1],
- (int)(reinterpret_cast<const unsigned char *>(&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr)))[2],
- (int)(reinterpret_cast<const unsigned char *>(&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr)))[3]
- );
- return std::string(buf);
- case AF_INET6:
- Utils::ztsnprintf(buf,sizeof(buf),"%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x",
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[0]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[1]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[2]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[3]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[4]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[5]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[6]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[7]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[8]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[9]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[10]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[11]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[12]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[13]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[14]),
- (int)(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr[15])
- );
- return std::string(buf);
+ case AF_INET: {
+ const uint8_t *a = reinterpret_cast<const uint8_t *>(&(reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr));
+ char *p = buf;
+ for(int i=0;;++i) {
+ Utils::decimal((unsigned long)a[i],p);
+ if (i != 3) {
+ while (*p) ++p;
+ *(p++) = '.';
+ } else break;
+ }
+ } break;
+
+ case AF_INET6: {
+ uint16_t a[8];
+ memcpy(a,reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr,16);
+ char *p = buf;
+ for(int i=0;i<8;++i) {
+ Utils::hex(Utils::ntoh(a[i]),p);
+ p[4] = (i == 7) ? (char)0 : ':';
+ p += 5;
+ }
+ } break;
+
+ default:
+ buf[0] = (char)0;
+ break;
}
- return std::string();
+ return buf;
}
-void InetAddress::fromString(const std::string &ipSlashPort)
+bool InetAddress::fromString(const char *ipSlashPort)
{
- const std::size_t slashAt = ipSlashPort.find('/');
- if (slashAt == std::string::npos) {
- set(ipSlashPort,0);
+ char buf[64];
+
+ memset(this,0,sizeof(InetAddress));
+
+ if (!*ipSlashPort)
+ return true;
+ if (!Utils::scopy(buf,sizeof(buf),ipSlashPort))
+ return false;
+
+ char *portAt = buf;
+ while ((*portAt)&&(*portAt != '/'))
+ ++portAt;
+ unsigned int port = 0;
+ if (*portAt) {
+ *(portAt++) = (char)0;
+ port = Utils::strToUInt(portAt) & 0xffff;
+ }
+
+ if (strchr(buf,':')) {
+ uint16_t a[8];
+ unsigned int b = 0;
+ char *saveptr = (char *)0;
+ for(char *s=Utils::stok(buf,":",&saveptr);((s)&&(b<8));s=Utils::stok((char *)0,":",&saveptr))
+ a[b++] = Utils::hton((uint16_t)(Utils::hexStrToUInt(s) & 0xffff));
+
+ struct sockaddr_in6 *const in6 = reinterpret_cast<struct sockaddr_in6 *>(this);
+ in6->sin6_family = AF_INET6;
+ memcpy(in6->sin6_addr.s6_addr,a,16);
+ in6->sin6_port = Utils::hton((uint16_t)port);
+
+ return true;
+ } else if (strchr(buf,'.')) {
+ uint8_t a[4];
+ unsigned int b = 0;
+ char *saveptr = (char *)0;
+ for(char *s=Utils::stok(buf,".",&saveptr);((s)&&(b<4));s=Utils::stok((char *)0,".",&saveptr))
+ a[b++] = (uint8_t)(Utils::strToUInt(s) & 0xff);
+
+ struct sockaddr_in *const in = reinterpret_cast<struct sockaddr_in *>(this);
+ in->sin_family = AF_INET;
+ memcpy(&(in->sin_addr.s_addr),a,4);
+ in->sin_port = Utils::hton((uint16_t)port);
+
+ return true;
} else {
- long p = strtol(ipSlashPort.substr(slashAt+1).c_str(),(char **)0,10);
- if ((p > 0)&&(p <= 0xffff))
- set(ipSlashPort.substr(0,slashAt),(unsigned int)p);
- else set(ipSlashPort.substr(0,slashAt),0);
+ return false;
}
}
@@ -244,14 +231,13 @@ InetAddress InetAddress::netmask() const
case AF_INET6: {
uint64_t nm[2];
const unsigned int bits = netmaskBits();
- if(bits) {
- nm[0] = Utils::hton((uint64_t)((bits >= 64) ? 0xffffffffffffffffULL : (0xffffffffffffffffULL << (64 - bits))));
- nm[1] = Utils::hton((uint64_t)((bits <= 64) ? 0ULL : (0xffffffffffffffffULL << (128 - bits))));
- }
- else {
- nm[0] = 0;
- nm[1] = 0;
- }
+ if(bits) {
+ nm[0] = Utils::hton((uint64_t)((bits >= 64) ? 0xffffffffffffffffULL : (0xffffffffffffffffULL << (64 - bits))));
+ nm[1] = Utils::hton((uint64_t)((bits <= 64) ? 0ULL : (0xffffffffffffffffULL << (128 - bits))));
+ } else {
+ nm[0] = 0;
+ nm[1] = 0;
+ }
memcpy(reinterpret_cast<struct sockaddr_in6 *>(&r)->sin6_addr.s6_addr,nm,16);
} break;
}
@@ -338,7 +324,6 @@ bool InetAddress::containsAddress(const InetAddress &addr) const
}
bool InetAddress::isNetwork() const
- throw()
{
switch(ss_family) {
case AF_INET: {
@@ -371,7 +356,6 @@ bool InetAddress::isNetwork() const
}
bool InetAddress::operator==(const InetAddress &a) const
- throw()
{
if (ss_family == a.ss_family) {
switch(ss_family) {
@@ -395,7 +379,6 @@ bool InetAddress::operator==(const InetAddress &a) const
}
bool InetAddress::operator<(const InetAddress &a) const
- throw()
{
if (ss_family < a.ss_family)
return true;
diff --git a/node/InetAddress.hpp b/node/InetAddress.hpp
index 4cb9a4dc..dd055084 100644
--- a/node/InetAddress.hpp
+++ b/node/InetAddress.hpp
@@ -31,8 +31,6 @@
#include <string.h>
#include <stdint.h>
-#include <string>
-
#include "Constants.hpp"
#include "../include/ZeroTierOne.h"
#include "Utils.hpp"
@@ -85,25 +83,22 @@ struct InetAddress : public sockaddr_storage
IP_SCOPE_PRIVATE = 7 // 10.x.x.x, 192.168.x.x, etc.
};
- InetAddress() throw() { memset(this,0,sizeof(InetAddress)); }
- InetAddress(const InetAddress &a) throw() { memcpy(this,&a,sizeof(InetAddress)); }
- InetAddress(const InetAddress *a) throw() { memcpy(this,a,sizeof(InetAddress)); }
- InetAddress(const struct sockaddr_storage &ss) throw() { *this = ss; }
- InetAddress(const struct sockaddr_storage *ss) throw() { *this = ss; }
- InetAddress(const struct sockaddr &sa) throw() { *this = sa; }
- InetAddress(const struct sockaddr *sa) throw() { *this = sa; }
- InetAddress(const struct sockaddr_in &sa) throw() { *this = sa; }
- InetAddress(const struct sockaddr_in *sa) throw() { *this = sa; }
- InetAddress(const struct sockaddr_in6 &sa) throw() { *this = sa; }
- InetAddress(const struct sockaddr_in6 *sa) throw() { *this = sa; }
- InetAddress(const void *ipBytes,unsigned int ipLen,unsigned int port) throw() { this->set(ipBytes,ipLen,port); }
- InetAddress(const uint32_t ipv4,unsigned int port) throw() { this->set(&ipv4,4,port); }
- InetAddress(const std::string &ip,unsigned int port) throw() { this->set(ip,port); }
- InetAddress(const std::string &ipSlashPort) throw() { this->fromString(ipSlashPort); }
- InetAddress(const char *ipSlashPort) throw() { this->fromString(std::string(ipSlashPort)); }
+ InetAddress() { memset(this,0,sizeof(InetAddress)); }
+ InetAddress(const InetAddress &a) { memcpy(this,&a,sizeof(InetAddress)); }
+ InetAddress(const InetAddress *a) { memcpy(this,a,sizeof(InetAddress)); }
+ InetAddress(const struct sockaddr_storage &ss) { *this = ss; }
+ InetAddress(const struct sockaddr_storage *ss) { *this = ss; }
+ InetAddress(const struct sockaddr &sa) { *this = sa; }
+ InetAddress(const struct sockaddr *sa) { *this = sa; }
+ InetAddress(const struct sockaddr_in &sa) { *this = sa; }
+ InetAddress(const struct sockaddr_in *sa) { *this = sa; }
+ InetAddress(const struct sockaddr_in6 &sa) { *this = sa; }
+ InetAddress(const struct sockaddr_in6 *sa) { *this = sa; }
+ InetAddress(const void *ipBytes,unsigned int ipLen,unsigned int port) { this->set(ipBytes,ipLen,port); }
+ InetAddress(const uint32_t ipv4,unsigned int port) { this->set(&ipv4,4,port); }
+ InetAddress(const char *ipSlashPort) { this->fromString(ipSlashPort); }
inline InetAddress &operator=(const InetAddress &a)
- throw()
{
if (&a != this)
memcpy(this,&a,sizeof(InetAddress));
@@ -111,7 +106,6 @@ struct InetAddress : public sockaddr_storage
}
inline InetAddress &operator=(const InetAddress *a)
- throw()
{
if (a != this)
memcpy(this,a,sizeof(InetAddress));
@@ -119,7 +113,6 @@ struct InetAddress : public sockaddr_storage
}
inline InetAddress &operator=(const struct sockaddr_storage &ss)
- throw()
{
if (reinterpret_cast<const InetAddress *>(&ss) != this)
memcpy(this,&ss,sizeof(InetAddress));
@@ -127,7 +120,6 @@ struct InetAddress : public sockaddr_storage
}
inline InetAddress &operator=(const struct sockaddr_storage *ss)
- throw()
{
if (reinterpret_cast<const InetAddress *>(ss) != this)
memcpy(this,ss,sizeof(InetAddress));
@@ -135,7 +127,6 @@ struct InetAddress : public sockaddr_storage
}
inline InetAddress &operator=(const struct sockaddr_in &sa)
- throw()
{
if (reinterpret_cast<const InetAddress *>(&sa) != this) {
memset(this,0,sizeof(InetAddress));
@@ -145,7 +136,6 @@ struct InetAddress : public sockaddr_storage
}
inline InetAddress &operator=(const struct sockaddr_in *sa)
- throw()
{
if (reinterpret_cast<const InetAddress *>(sa) != this) {
memset(this,0,sizeof(InetAddress));
@@ -155,7 +145,6 @@ struct InetAddress : public sockaddr_storage
}
inline InetAddress &operator=(const struct sockaddr_in6 &sa)
- throw()
{
if (reinterpret_cast<const InetAddress *>(&sa) != this) {
memset(this,0,sizeof(InetAddress));
@@ -165,7 +154,6 @@ struct InetAddress : public sockaddr_storage
}
inline InetAddress &operator=(const struct sockaddr_in6 *sa)
- throw()
{
if (reinterpret_cast<const InetAddress *>(sa) != this) {
memset(this,0,sizeof(InetAddress));
@@ -175,7 +163,6 @@ struct InetAddress : public sockaddr_storage
}
inline InetAddress &operator=(const struct sockaddr &sa)
- throw()
{
if (reinterpret_cast<const InetAddress *>(&sa) != this) {
memset(this,0,sizeof(InetAddress));
@@ -192,7 +179,6 @@ struct InetAddress : public sockaddr_storage
}
inline InetAddress &operator=(const struct sockaddr *sa)
- throw()
{
if (reinterpret_cast<const InetAddress *>(sa) != this) {
memset(this,0,sizeof(InetAddress));
@@ -211,17 +197,7 @@ struct InetAddress : public sockaddr_storage
/**
* @return IP scope classification (e.g. loopback, link-local, private, global)
*/
- IpScope ipScope() const
- throw();
-
- /**
- * Set from a string-format IP and a port
- *
- * @param ip IP address in V4 or V6 ASCII notation
- * @param port Port or 0 for none
- */
- void set(const std::string &ip,unsigned int port)
- throw();
+ IpScope ipScope() const;
/**
* Set from a raw IP and port number
@@ -230,8 +206,7 @@ struct InetAddress : public sockaddr_storage
* @param ipLen Length of IP address: 4 or 16
* @param port Port number or 0 for none
*/
- void set(const void *ipBytes,unsigned int ipLen,unsigned int port)
- throw();
+ void set(const void *ipBytes,unsigned int ipLen,unsigned int port);
/**
* Set the port component
@@ -272,23 +247,23 @@ struct InetAddress : public sockaddr_storage
/**
* @return ASCII IP/port format representation
*/
- std::string toString() const;
+ char *toString(char buf[64]) const;
/**
* @return IP portion only, in ASCII string format
*/
- std::string toIpString() const;
+ char *toIpString(char buf[64]) const;
/**
- * @param ipSlashPort ASCII IP/port format notation
+ * @param ipSlashPort IP/port (port is optional, will be 0 if not included)
+ * @return True if address appeared to be valid
*/
- void fromString(const std::string &ipSlashPort);
+ bool fromString(const char *ipSlashPort);
/**
* @return Port or 0 if no port component defined
*/
inline unsigned int port() const
- throw()
{
switch(ss_family) {
case AF_INET: return Utils::ntoh((uint16_t)(reinterpret_cast<const struct sockaddr_in *>(this)->sin_port));
@@ -306,7 +281,7 @@ struct InetAddress : public sockaddr_storage
*
* @return Netmask bits
*/
- inline unsigned int netmaskBits() const throw() { return port(); }
+ inline unsigned int netmaskBits() const { return port(); }
/**
* @return True if netmask bits is valid for the address type
@@ -329,7 +304,7 @@ struct InetAddress : public sockaddr_storage
*
* @return Gateway metric
*/
- inline unsigned int metric() const throw() { return port(); }
+ inline unsigned int metric() const { return port(); }
/**
* Construct a full netmask as an InetAddress
@@ -376,12 +351,12 @@ struct InetAddress : public sockaddr_storage
/**
* @return True if this is an IPv4 address
*/
- inline bool isV4() const throw() { return (ss_family == AF_INET); }
+ inline bool isV4() const { return (ss_family == AF_INET); }
/**
* @return True if this is an IPv6 address
*/
- inline bool isV6() const throw() { return (ss_family == AF_INET6); }
+ inline bool isV6() const { return (ss_family == AF_INET6); }
/**
* @return pointer to raw address bytes or NULL if not available
@@ -454,7 +429,7 @@ struct InetAddress : public sockaddr_storage
/**
* Set to null/zero
*/
- inline void zero() throw() { memset(this,0,sizeof(InetAddress)); }
+ inline void zero() { memset(this,0,sizeof(InetAddress)); }
/**
* Check whether this is a network/route rather than an IP assignment
@@ -464,8 +439,7 @@ struct InetAddress : public sockaddr_storage
*
* @return True if everything after netmask bits is zero
*/
- bool isNetwork() const
- throw();
+ bool isNetwork() const;
/**
* @return 14-bit (0-16383) hash of this IP's first 24 or 48 bits (for V4 or V6) for rate limiting code, or 0 if non-IP
@@ -494,7 +468,7 @@ struct InetAddress : public sockaddr_storage
/**
* @return True if address family is non-zero
*/
- inline operator bool() const throw() { return (ss_family != 0); }
+ inline operator bool() const { return (ss_family != 0); }
template<unsigned int C>
inline void serialize(Buffer<C> &b) const
@@ -552,12 +526,12 @@ struct InetAddress : public sockaddr_storage
return (p - startAt);
}
- bool operator==(const InetAddress &a) const throw();
- bool operator<(const InetAddress &a) const throw();
- inline bool operator!=(const InetAddress &a) const throw() { return !(*this == a); }
- inline bool operator>(const InetAddress &a) const throw() { return (a < *this); }
- inline bool operator<=(const InetAddress &a) const throw() { return !(a < *this); }
- inline bool operator>=(const InetAddress &a) const throw() { return !(*this < a); }
+ bool operator==(const InetAddress &a) const;
+ bool operator<(const InetAddress &a) const;
+ inline bool operator!=(const InetAddress &a) const { return !(*this == a); }
+ inline bool operator>(const InetAddress &a) const { return (a < *this); }
+ inline bool operator<=(const InetAddress &a) const { return !(a < *this); }
+ inline bool operator>=(const InetAddress &a) const { return !(*this < a); }
/**
* @param mac MAC address seed
diff --git a/node/MAC.hpp b/node/MAC.hpp
index db50aeb1..52388d59 100644
--- a/node/MAC.hpp
+++ b/node/MAC.hpp
@@ -44,30 +44,24 @@ namespace ZeroTier {
class MAC
{
public:
- MAC() throw() : _m(0ULL) {}
- MAC(const MAC &m) throw() : _m(m._m) {}
+ MAC() : _m(0ULL) {}
+ MAC(const MAC &m) : _m(m._m) {}
- MAC(const unsigned char a,const unsigned char b,const unsigned char c,const unsigned char d,const unsigned char e,const unsigned char f) throw() :
+ MAC(const unsigned char a,const unsigned char b,const unsigned char c,const unsigned char d,const unsigned char e,const unsigned char f) :
_m( ((((uint64_t)a) & 0xffULL) << 40) |
((((uint64_t)b) & 0xffULL) << 32) |
((((uint64_t)c) & 0xffULL) << 24) |
((((uint64_t)d) & 0xffULL) << 16) |
((((uint64_t)e) & 0xffULL) << 8) |
(((uint64_t)f) & 0xffULL) ) {}
-
- MAC(const char *s) throw() { fromString(s); }
- MAC(const std::string &s) throw() { fromString(s.c_str()); }
-
- MAC(const void *bits,unsigned int len) throw() { setTo(bits,len); }
-
- MAC(const Address &ztaddr,uint64_t nwid) throw() { fromAddress(ztaddr,nwid); }
-
- MAC(const uint64_t m) throw() : _m(m & 0xffffffffffffULL) {}
+ MAC(const void *bits,unsigned int len) { setTo(bits,len); }
+ MAC(const Address &ztaddr,uint64_t nwid) { fromAddress(ztaddr,nwid); }
+ MAC(const uint64_t m) : _m(m & 0xffffffffffffULL) {}
/**
* @return MAC in 64-bit integer
*/
- inline uint64_t toInt() const throw() { return _m; }
+ inline uint64_t toInt() const { return _m; }
/**
* Set MAC to zero
@@ -77,14 +71,13 @@ public:
/**
* @return True if MAC is non-zero
*/
- inline operator bool() const throw() { return (_m != 0ULL); }
+ inline operator bool() const { return (_m != 0ULL); }
/**
* @param bits Raw MAC in big-endian byte order
* @param len Length, must be >= 6 or result is zero
*/
inline void setTo(const void *bits,unsigned int len)
- throw()
{
if (len < 6) {
_m = 0ULL;
@@ -104,7 +97,6 @@ public:
* @param len Length of buffer, must be >= 6 or nothing is copied
*/
inline void copyTo(void *buf,unsigned int len) const
- throw()
{
if (len < 6)
return;
@@ -124,7 +116,6 @@ public:
*/
template<unsigned int C>
inline void appendTo(Buffer<C> &b) const
- throw(std::out_of_range)
{
unsigned char *p = (unsigned char *)b.appendField(6);
*(p++) = (unsigned char)((_m >> 40) & 0xff);
@@ -138,48 +129,17 @@ public:
/**
* @return True if this is broadcast (all 0xff)
*/
- inline bool isBroadcast() const throw() { return (_m == 0xffffffffffffULL); }
+ inline bool isBroadcast() const { return (_m == 0xffffffffffffULL); }
/**
* @return True if this is a multicast MAC
*/
- inline bool isMulticast() const throw() { return ((_m & 0x010000000000ULL) != 0ULL); }
+ inline bool isMulticast() const { return ((_m & 0x010000000000ULL) != 0ULL); }
/**
* @param True if this is a locally-administered MAC
*/
- inline bool isLocallyAdministered() const throw() { return ((_m & 0x020000000000ULL) != 0ULL); }
-
- /**
- * @param s Hex MAC, with or without : delimiters
- */
- inline void fromString(const char *s)
- {
- char tmp[8];
- for(int i=0;i<6;++i)
- tmp[i] = (char)0;
- Utils::unhex(s,tmp,6);
- setTo(tmp,6);
- }
-
- /**
- * @return MAC address in standard :-delimited hex format
- */
- inline std::string toString() const
- {
- char tmp[24];
- toString(tmp,sizeof(tmp));
- return std::string(tmp);
- }
-
- /**
- * @param buf Buffer to contain human-readable MAC
- * @param len Length of buffer
- */
- inline void toString(char *buf,unsigned int len) const
- {
- Utils::ztsnprintf(buf,len,"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(int)(*this)[0],(int)(*this)[1],(int)(*this)[2],(int)(*this)[3],(int)(*this)[4],(int)(*this)[5]);
- }
+ inline bool isLocallyAdministered() const { return ((_m & 0x020000000000ULL) != 0ULL); }
/**
* Set this MAC to a MAC derived from an address and a network ID
@@ -188,7 +148,6 @@ public:
* @param nwid 64-bit network ID
*/
inline void fromAddress(const Address &ztaddr,uint64_t nwid)
- throw()
{
uint64_t m = ((uint64_t)firstOctetForNetwork(nwid)) << 40;
m |= ztaddr.toInt(); // a is 40 bits
@@ -208,7 +167,6 @@ public:
* @param nwid Network ID
*/
inline Address toAddress(uint64_t nwid) const
- throw()
{
uint64_t a = _m & 0xffffffffffULL; // least significant 40 bits of MAC are formed from address
a ^= ((nwid >> 8) & 0xff) << 32; // ... XORed with bits 8-48 of the nwid in little-endian byte order, so unmask it
@@ -224,7 +182,6 @@ public:
* @return First octet of MAC for this network
*/
static inline unsigned char firstOctetForNetwork(uint64_t nwid)
- throw()
{
unsigned char a = ((unsigned char)(nwid & 0xfe) | 0x02); // locally administered, not multicast, from LSB of network ID
return ((a == 0x52) ? 0x32 : a); // blacklist 0x52 since it's used by KVM, libvirt, and other popular virtualization engines... seems de-facto standard on Linux
@@ -239,29 +196,27 @@ public:
/**
* @return 6, which is the number of bytes in a MAC, for container compliance
*/
- inline unsigned int size() const throw() { return 6; }
+ inline unsigned int size() const { return 6; }
- inline unsigned long hashCode() const throw() { return (unsigned long)_m; }
+ inline unsigned long hashCode() const { return (unsigned long)_m; }
inline MAC &operator=(const MAC &m)
- throw()
{
_m = m._m;
return *this;
}
inline MAC &operator=(const uint64_t m)
- throw()
{
_m = m;
return *this;
}
- inline bool operator==(const MAC &m) const throw() { return (_m == m._m); }
- inline bool operator!=(const MAC &m) const throw() { return (_m != m._m); }
- inline bool operator<(const MAC &m) const throw() { return (_m < m._m); }
- inline bool operator<=(const MAC &m) const throw() { return (_m <= m._m); }
- inline bool operator>(const MAC &m) const throw() { return (_m > m._m); }
- inline bool operator>=(const MAC &m) const throw() { return (_m >= m._m); }
+ inline bool operator==(const MAC &m) const { return (_m == m._m); }
+ inline bool operator!=(const MAC &m) const { return (_m != m._m); }
+ inline bool operator<(const MAC &m) const { return (_m < m._m); }
+ inline bool operator<=(const MAC &m) const { return (_m <= m._m); }
+ inline bool operator>(const MAC &m) const { return (_m > m._m); }
+ inline bool operator>=(const MAC &m) const { return (_m >= m._m); }
private:
uint64_t _m;
diff --git a/node/MulticastGroup.hpp b/node/MulticastGroup.hpp
index 7cbec2e0..f56c675b 100644
--- a/node/MulticastGroup.hpp
+++ b/node/MulticastGroup.hpp
@@ -29,8 +29,6 @@
#include <stdint.h>
-#include <string>
-
#include "MAC.hpp"
#include "InetAddress.hpp"
@@ -95,16 +93,6 @@ public:
}
/**
- * @return Human readable string representing this group (MAC/ADI in hex)
- */
- inline std::string toString() const
- {
- char buf[64];
- Utils::ztsnprintf(buf,sizeof(buf),"%.2x%.2x%.2x%.2x%.2x%.2x/%.8lx",(unsigned int)_mac[0],(unsigned int)_mac[1],(unsigned int)_mac[2],(unsigned int)_mac[3],(unsigned int)_mac[4],(unsigned int)_mac[5],(unsigned long)_adi);
- return std::string(buf);
- }
-
- /**
* @return Multicast address
*/
inline const MAC &mac() const throw() { return _mac; }
diff --git a/node/Network.cpp b/node/Network.cpp
index bccc0397..f2b6771b 100644
--- a/node/Network.cpp
+++ b/node/Network.cpp
@@ -51,7 +51,7 @@ namespace ZeroTier {
namespace {
#ifdef ZT_RULES_ENGINE_DEBUGGING
-#define FILTER_TRACE(f,...) { Utils::ztsnprintf(dpbuf,sizeof(dpbuf),f,##__VA_ARGS__); dlog.push_back(std::string(dpbuf)); }
+#define FILTER_TRACE(f,...) { snprintf(dpbuf,sizeof(dpbuf),f,##__VA_ARGS__); dlog.push_back(std::string(dpbuf)); }
static const char *_rtn(const ZT_VirtualNetworkRuleType rt)
{
switch(rt) {
@@ -1257,7 +1257,17 @@ void Network::requestConfiguration(void *tPtr)
nconf->rules[13].t = (uint8_t)ZT_NETWORK_RULE_ACTION_DROP;
nconf->type = ZT_NETWORK_TYPE_PUBLIC;
- Utils::ztsnprintf(nconf->name,sizeof(nconf->name),"adhoc-%.04x-%.04x",(int)startPortRange,(int)endPortRange);
+
+ nconf->name[0] = 'a';
+ nconf->name[1] = 'd';
+ nconf->name[2] = 'h';
+ nconf->name[3] = 'o';
+ nconf->name[4] = 'c';
+ nconf->name[5] = '-';
+ Utils::hex((uint16_t)startPortRange,nconf->name + 6);
+ nconf->name[10] = '-';
+ Utils::hex((uint16_t)endPortRange,nconf->name + 11);
+ nconf->name[15] = (char)0;
this->setConfiguration(tPtr,*nconf,false);
delete nconf;
diff --git a/node/NetworkConfig.cpp b/node/NetworkConfig.cpp
index 65101c3a..e5929923 100644
--- a/node/NetworkConfig.cpp
+++ b/node/NetworkConfig.cpp
@@ -64,7 +64,8 @@ bool NetworkConfig::toDictionary(Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> &d,b
if (this->staticIps[i].ss_family == AF_INET) {
if (v4s.length() > 0)
v4s.push_back(',');
- v4s.append(this->staticIps[i].toString());
+ char buf[64];
+ v4s.append(this->staticIps[i].toString(buf));
}
}
if (v4s.length() > 0) {
@@ -75,7 +76,8 @@ bool NetworkConfig::toDictionary(Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> &d,b
if (this->staticIps[i].ss_family == AF_INET6) {
if (v6s.length() > 0)
v6s.push_back(',');
- v6s.append(this->staticIps[i].toString());
+ char buf[64];
+ v6s.append(this->staticIps[i].toString(buf));
}
}
if (v6s.length() > 0) {
@@ -94,8 +96,7 @@ bool NetworkConfig::toDictionary(Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> &d,b
if (ets.length() > 0)
ets.push_back(',');
char tmp2[16];
- Utils::ztsnprintf(tmp2,sizeof(tmp2),"%x",et);
- ets.append(tmp2);
+ ets.append(Utils::hex((uint16_t)et,tmp2));
}
et = 0;
}
@@ -114,7 +115,8 @@ bool NetworkConfig::toDictionary(Dictionary<ZT_NETWORKCONFIG_DICT_CAPACITY> &d,b
if ((this->specialists[i] & ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE) != 0) {
if (ab.length() > 0)
ab.push_back(',');
- ab.append(Address(this->specialists[i]).toString().c_str());
+ char tmp2[16];
+ ab.append(Address(this->specialists[i]).toString(tmp2));
}
}
if (ab.length() > 0) {
diff --git a/node/Node.cpp b/node/Node.cpp
index 4b598f61..e28accee 100644
--- a/node/Node.cpp
+++ b/node/Node.cpp
@@ -82,8 +82,8 @@ Node::Node(void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,uint6
if (n > 0) {
tmp[n] = (char)0;
if (RR->identity.fromString(tmp)) {
- RR->publicIdentityStr = RR->identity.toString(false);
- RR->secretIdentityStr = RR->identity.toString(true);
+ RR->identity.toString(false,RR->publicIdentityStr);
+ RR->identity.toString(true,RR->secretIdentityStr);
} else {
n = -1;
}
@@ -92,10 +92,10 @@ Node::Node(void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,uint6
idtmp[0] = RR->identity.address().toInt(); idtmp[1] = 0;
if (n <= 0) {
RR->identity.generate();
- RR->publicIdentityStr = RR->identity.toString(false);
- RR->secretIdentityStr = RR->identity.toString(true);
- stateObjectPut(tptr,ZT_STATE_OBJECT_IDENTITY_SECRET,idtmp,RR->secretIdentityStr.data(),(unsigned int)RR->secretIdentityStr.length());
- stateObjectPut(tptr,ZT_STATE_OBJECT_IDENTITY_PUBLIC,idtmp,RR->publicIdentityStr.data(),(unsigned int)RR->publicIdentityStr.length());
+ RR->identity.toString(false,RR->publicIdentityStr);
+ RR->identity.toString(true,RR->secretIdentityStr);
+ stateObjectPut(tptr,ZT_STATE_OBJECT_IDENTITY_SECRET,idtmp,RR->secretIdentityStr,(unsigned int)strlen(RR->secretIdentityStr));
+ stateObjectPut(tptr,ZT_STATE_OBJECT_IDENTITY_PUBLIC,idtmp,RR->publicIdentityStr,(unsigned int)strlen(RR->publicIdentityStr));
} else {
n = stateObjectGet(tptr,ZT_STATE_OBJECT_IDENTITY_PUBLIC,idtmp,tmp,sizeof(tmp) - 1);
if (n > 0) {
@@ -104,7 +104,7 @@ Node::Node(void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,uint6
n = -1;
}
if (n <= 0)
- stateObjectPut(tptr,ZT_STATE_OBJECT_IDENTITY_PUBLIC,idtmp,RR->publicIdentityStr.data(),(unsigned int)RR->publicIdentityStr.length());
+ stateObjectPut(tptr,ZT_STATE_OBJECT_IDENTITY_PUBLIC,idtmp,RR->publicIdentityStr,(unsigned int)strlen(RR->publicIdentityStr));
}
try {
@@ -386,8 +386,8 @@ uint64_t Node::address() const
void Node::status(ZT_NodeStatus *status) const
{
status->address = RR->identity.address().toInt();
- status->publicIdentity = RR->publicIdentityStr.c_str();
- status->secretIdentity = RR->secretIdentityStr.c_str();
+ status->publicIdentity = RR->publicIdentityStr;
+ status->secretIdentity = RR->secretIdentityStr;
status->online = _online ? 1 : 0;
}
@@ -544,39 +544,6 @@ bool Node::shouldUsePathForZeroTierTraffic(void *tPtr,const Address &ztaddr,cons
return ( (_cb.pathCheckFunction) ? (_cb.pathCheckFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,ztaddr.toInt(),localSocket,reinterpret_cast<const struct sockaddr_storage *>(&remoteAddress)) != 0) : true);
}
-#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);
-
- time_t now = (time_t)(_now / 1000ULL);
-#ifdef __WINDOWS__
- ctime_s(tmp3,sizeof(tmp3),&now);
- char *nowstr = tmp3;
-#else
- char *nowstr = ctime_r(&now,tmp3);
-#endif
- unsigned long nowstrlen = (unsigned long)strlen(nowstr);
- if (nowstr[nowstrlen-1] == '\n')
- nowstr[--nowstrlen] = (char)0;
- if (nowstr[nowstrlen-1] == '\r')
- nowstr[--nowstrlen] = (char)0;
-
- va_start(ap,fmt);
- vsnprintf(tmp2,sizeof(tmp2),fmt,ap);
- va_end(ap);
- tmp2[sizeof(tmp2)-1] = (char)0;
-
- Utils::ztsnprintf(tmp1,sizeof(tmp1),"[%s] %s:%u %s",nowstr,module,line,tmp2);
- postEvent((void *)0,ZT_EVENT_TRACE,tmp1);
-}
-#endif // ZT_TRACE
-
uint64_t Node::prng()
{
// https://en.wikipedia.org/wiki/Xorshift#xorshift.2B
diff --git a/node/Node.hpp b/node/Node.hpp
index 55491b06..40903f7c 100644
--- a/node/Node.hpp
+++ b/node/Node.hpp
@@ -195,10 +195,6 @@ public:
inline void stateObjectPut(void *const tPtr,ZT_StateObjectType type,const uint64_t id[2],const void *const data,const unsigned int len) { _cb.statePutFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,type,id,data,(int)len); }
inline void stateObjectDelete(void *const tPtr,ZT_StateObjectType type,const uint64_t id[2]) { _cb.statePutFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,type,id,(const void *)0,-1); }
-#ifdef ZT_TRACE
- void postTrace(const char *module,unsigned int line,const char *fmt,...);
-#endif
-
bool shouldUsePathForZeroTierTraffic(void *tPtr,const Address &ztaddr,const int64_t localSocket,const InetAddress &remoteAddress);
inline bool externalPathLookup(void *tPtr,const Address &ztaddr,int family,InetAddress &addr) { return ( (_cb.pathLookupFunction) ? (_cb.pathLookupFunction(reinterpret_cast<ZT_Node *>(this),_uPtr,tPtr,ztaddr.toInt(),family,reinterpret_cast<struct sockaddr_storage *>(&addr)) != 0) : false ); }
diff --git a/node/RuntimeEnvironment.hpp b/node/RuntimeEnvironment.hpp
index 99afe25d..94b96d34 100644
--- a/node/RuntimeEnvironment.hpp
+++ b/node/RuntimeEnvironment.hpp
@@ -27,7 +27,7 @@
#ifndef ZT_RUNTIMEENVIRONMENT_HPP
#define ZT_RUNTIMEENVIRONMENT_HPP
-#include <string>
+#include <string.h>
#include "Constants.hpp"
#include "Utils.hpp"
@@ -60,11 +60,13 @@ public:
,sa((SelfAwareness *)0)
{
Utils::getSecureRandom(&instanceId,sizeof(instanceId));
+ memset(publicIdentityStr,0,sizeof(publicIdentityStr));
+ memset(secretIdentityStr,0,sizeof(secretIdentityStr));
}
~RuntimeEnvironment()
{
- Utils::burn(reinterpret_cast<void *>(const_cast<char *>(secretIdentityStr.data())),(unsigned int)secretIdentityStr.length());
+ Utils::burn(secretIdentityStr,sizeof(secretIdentityStr));
}
/**
@@ -77,8 +79,8 @@ public:
// This node's identity
Identity identity;
- std::string publicIdentityStr;
- std::string secretIdentityStr;
+ char publicIdentityStr[ZT_IDENTITY_STRING_BUFFER_LENGTH];
+ char secretIdentityStr[ZT_IDENTITY_STRING_BUFFER_LENGTH];
// This is set externally to an instance of this base class
NetworkController *localNetworkController;
diff --git a/node/Topology.cpp b/node/Topology.cpp
index 809bc7e7..e7bbdfae 100644
--- a/node/Topology.cpp
+++ b/node/Topology.cpp
@@ -91,12 +91,8 @@ Topology::Topology(const RuntimeEnvironment *renv,void *tPtr) :
SharedPtr<Peer> Topology::addPeer(void *tPtr,const SharedPtr<Peer> &peer)
{
#ifdef ZT_TRACE
- if ((!peer)||(peer->address() == RR->identity.address())) {
- if (!peer)
- fprintf(stderr,"FATAL BUG: addPeer() caught attempt to add NULL peer" ZT_EOL_S);
- else fprintf(stderr,"FATAL BUG: addPeer() caught attempt to add peer for self" ZT_EOL_S);
- abort();
- }
+ if ((!peer)||(peer->address() == RR->identity.address()))
+ return SharedPtr<Peer>();
#endif
SharedPtr<Peer> np;
diff --git a/node/Utils.cpp b/node/Utils.cpp
index d2321e16..a3a4c3c3 100644
--- a/node/Utils.cpp
+++ b/node/Utils.cpp
@@ -55,90 +55,35 @@ namespace ZeroTier {
const char Utils::HEXCHARS[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' };
-// Crazy hack to force memory to be securely zeroed in spite of the best efforts of optimizing compilers.
-static void _Utils_doBurn(volatile uint8_t *ptr,unsigned int len)
-{
- volatile uint8_t *const end = ptr + len;
- while (ptr != end) *(ptr++) = (uint8_t)0;
-}
-static void (*volatile _Utils_doBurn_ptr)(volatile uint8_t *,unsigned int) = _Utils_doBurn;
-void Utils::burn(void *ptr,unsigned int len) { (_Utils_doBurn_ptr)((volatile uint8_t *)ptr,len); }
-
-std::string Utils::hex(const void *data,unsigned int len)
+static unsigned long _Utils_itoa(unsigned long n,char *s)
{
- std::string r;
- r.reserve(len * 2);
- for(unsigned int i=0;i<len;++i) {
- r.push_back(HEXCHARS[(((const unsigned char *)data)[i] & 0xf0) >> 4]);
- r.push_back(HEXCHARS[((const unsigned char *)data)[i] & 0x0f]);
- }
- return r;
+ if (n == 0)
+ return 0;
+ unsigned long pos = _Utils_itoa(n / 10,s);
+ if (pos >= 22) // sanity check, should be impossible
+ pos = 22;
+ s[pos] = '0' + (char)(n % 10);
+ return pos + 1;
}
-
-std::string Utils::unhex(const char *hex,unsigned int maxlen)
+char *Utils::decimal(unsigned long n,char s[24])
{
- int n = 1;
- unsigned char c,b = 0;
- const char *eof = hex + maxlen;
- std::string r;
-
- if (!maxlen)
- return r;
-
- while ((c = (unsigned char)*(hex++))) {
- if ((c >= 48)&&(c <= 57)) { // 0..9
- if ((n ^= 1))
- r.push_back((char)(b | (c - 48)));
- else b = (c - 48) << 4;
- } else if ((c >= 65)&&(c <= 70)) { // A..F
- if ((n ^= 1))
- r.push_back((char)(b | (c - (65 - 10))));
- else b = (c - (65 - 10)) << 4;
- } else if ((c >= 97)&&(c <= 102)) { // a..f
- if ((n ^= 1))
- r.push_back((char)(b | (c - (97 - 10))));
- else b = (c - (97 - 10)) << 4;
- }
- if (hex == eof)
- break;
+ if (n == 0) {
+ s[0] = '0';
+ s[1] = (char)0;
+ return s;
}
-
- return r;
+ s[_Utils_itoa(n,s)] = (char)0;
+ return s;
}
-unsigned int Utils::unhex(const char *hex,unsigned int maxlen,void *buf,unsigned int len)
+// Crazy hack to force memory to be securely zeroed in spite of the best efforts of optimizing compilers.
+static void _Utils_doBurn(volatile uint8_t *ptr,unsigned int len)
{
- int n = 1;
- unsigned char c,b = 0;
- unsigned int l = 0;
- const char *eof = hex + maxlen;
-
- if (!maxlen)
- return 0;
-
- while ((c = (unsigned char)*(hex++))) {
- if ((c >= 48)&&(c <= 57)) { // 0..9
- if ((n ^= 1)) {
- if (l >= len) break;
- ((unsigned char *)buf)[l++] = (b | (c - 48));
- } else b = (c - 48) << 4;
- } else if ((c >= 65)&&(c <= 70)) { // A..F
- if ((n ^= 1)) {
- if (l >= len) break;
- ((unsigned char *)buf)[l++] = (b | (c - (65 - 10)));
- } else b = (c - (65 - 10)) << 4;
- } else if ((c >= 97)&&(c <= 102)) { // a..f
- if ((n ^= 1)) {
- if (l >= len) break;
- ((unsigned char *)buf)[l++] = (b | (c - (97 - 10)));
- } else b = (c - (97 - 10)) << 4;
- }
- if (hex == eof)
- break;
- }
-
- return l;
+ volatile uint8_t *const end = ptr + len;
+ while (ptr != end) *(ptr++) = (uint8_t)0;
}
+static void (*volatile _Utils_doBurn_ptr)(volatile uint8_t *,unsigned int) = _Utils_doBurn;
+void Utils::burn(void *ptr,unsigned int len) { (_Utils_doBurn_ptr)((volatile uint8_t *)ptr,len); }
void Utils::getSecureRandom(void *buf,unsigned int bytes)
{
@@ -244,21 +189,4 @@ bool Utils::scopy(char *dest,unsigned int len,const char *src)
return true;
}
-unsigned int Utils::ztsnprintf(char *buf,unsigned int len,const char *fmt,...)
-{
- va_list ap;
-
- va_start(ap,fmt);
- int n = (int)vsnprintf(buf,len,fmt,ap);
- va_end(ap);
-
- if ((n >= (int)len)||(n < 0)) {
- if (len)
- buf[len - 1] = (char)0;
- throw std::length_error("buf[] overflow");
- }
-
- return (unsigned int)n;
-}
-
} // namespace ZeroTier
diff --git a/node/Utils.hpp b/node/Utils.hpp
index 212ef247..5a5e9f39 100644
--- a/node/Utils.hpp
+++ b/node/Utils.hpp
@@ -70,42 +70,144 @@ public:
static void burn(void *ptr,unsigned int len);
/**
- * Convert binary data to hexadecimal
- *
- * @param data Data to convert to hex
- * @param len Length of data
- * @return Hexadecimal string
+ * @param n Number to convert
+ * @param s Buffer, at least 24 bytes in size
+ * @return String containing 'n' in base 10 form
*/
- static std::string hex(const void *data,unsigned int len);
- static inline std::string hex(const std::string &data) { return hex(data.data(),(unsigned int)data.length()); }
+ static char *decimal(unsigned long n,char s[24]);
- /**
- * Convert hexadecimal to binary data
- *
- * This ignores all non-hex characters, just stepping over them and
- * continuing. Upper and lower case are supported for letters a-f.
- *
- * @param hex Hexadecimal ASCII code (non-hex chars are ignored, stops at zero or maxlen)
- * @param maxlen Maximum length of hex string buffer
- * @return Binary data
- */
- static std::string unhex(const char *hex,unsigned int maxlen);
- static inline std::string unhex(const std::string &hex) { return unhex(hex.c_str(),(unsigned int)hex.length()); }
+ static inline char *hex(uint64_t i,char *const s)
+ {
+ s[0] = HEXCHARS[(i >> 60) & 0xf];
+ s[1] = HEXCHARS[(i >> 56) & 0xf];
+ s[2] = HEXCHARS[(i >> 52) & 0xf];
+ s[3] = HEXCHARS[(i >> 48) & 0xf];
+ s[4] = HEXCHARS[(i >> 44) & 0xf];
+ s[5] = HEXCHARS[(i >> 40) & 0xf];
+ s[6] = HEXCHARS[(i >> 36) & 0xf];
+ s[7] = HEXCHARS[(i >> 32) & 0xf];
+ s[8] = HEXCHARS[(i >> 28) & 0xf];
+ s[9] = HEXCHARS[(i >> 24) & 0xf];
+ s[10] = HEXCHARS[(i >> 20) & 0xf];
+ s[11] = HEXCHARS[(i >> 16) & 0xf];
+ s[12] = HEXCHARS[(i >> 12) & 0xf];
+ s[13] = HEXCHARS[(i >> 8) & 0xf];
+ s[14] = HEXCHARS[(i >> 4) & 0xf];
+ s[15] = HEXCHARS[i & 0xf];
+ s[16] = (char)0;
+ return s;
+ }
- /**
- * Convert hexadecimal to binary data
- *
- * This ignores all non-hex characters, just stepping over them and
- * continuing. Upper and lower case are supported for letters a-f.
- *
- * @param hex Hexadecimal ASCII
- * @param maxlen Maximum length of hex string buffer
- * @param buf Buffer to fill
- * @param len Length of buffer
- * @return Number of characters actually written
- */
- static unsigned int unhex(const char *hex,unsigned int maxlen,void *buf,unsigned int len);
- static inline unsigned int unhex(const std::string &hex,void *buf,unsigned int len) { return unhex(hex.c_str(),(unsigned int)hex.length(),buf,len); }
+ static inline char *hex10(uint64_t i,char *const s)
+ {
+ s[0] = HEXCHARS[(i >> 36) & 0xf];
+ s[1] = HEXCHARS[(i >> 32) & 0xf];
+ s[2] = HEXCHARS[(i >> 28) & 0xf];
+ s[3] = HEXCHARS[(i >> 24) & 0xf];
+ s[4] = HEXCHARS[(i >> 20) & 0xf];
+ s[5] = HEXCHARS[(i >> 16) & 0xf];
+ s[6] = HEXCHARS[(i >> 12) & 0xf];
+ s[7] = HEXCHARS[(i >> 8) & 0xf];
+ s[8] = HEXCHARS[(i >> 4) & 0xf];
+ s[9] = HEXCHARS[i & 0xf];
+ s[10] = (char)0;
+ return s;
+ }
+
+ static inline char *hex(uint16_t i,char *const s)
+ {
+ s[0] = HEXCHARS[(i >> 12) & 0xf];
+ s[1] = HEXCHARS[(i >> 8) & 0xf];
+ s[2] = HEXCHARS[(i >> 4) & 0xf];
+ s[3] = HEXCHARS[i & 0xf];
+ s[4] = (char)0;
+ return s;
+ }
+
+ static inline char *hex(uint8_t i,char *const s)
+ {
+ s[0] = HEXCHARS[(i >> 4) & 0xf];
+ s[1] = HEXCHARS[i & 0xf];
+ s[2] = (char)0;
+ return s;
+ }
+
+ static inline char *hex(const void *d,unsigned int l,char *s)
+ {
+ char *save = s;
+ for(unsigned int i=0;i<l;++i) {
+ unsigned int b = reinterpret_cast<const uint8_t *>(d)[i];
+ *(s++) = HEXCHARS[(b >> 4) & 0xf];
+ *(s++) = HEXCHARS[b & 0xf];
+ }
+ *s = (char)0;
+ return save;
+ }
+
+ static inline unsigned int unhex(const char *h,void *buf,unsigned int buflen)
+ {
+ unsigned int l = 0;
+ while (l < buflen) {
+ uint8_t hc = (uint8_t)*(h++);
+ if (!hc) break;
+
+ uint8_t c = 0;
+ if ((hc >= 48)&&(hc <= 57))
+ c = hc - 48;
+ else if ((hc >= 97)&&(hc <= 102))
+ c = hc - 87;
+ else if ((hc >= 65)&&(hc <= 70))
+ c = hc - 55;
+
+ hc = (uint8_t)*(h++);
+ if (!hc) break;
+
+ c <<= 4;
+ if ((hc >= 48)&&(hc <= 57))
+ c |= hc - 48;
+ else if ((hc >= 97)&&(hc <= 102))
+ c |= hc - 87;
+ else if ((hc >= 65)&&(hc <= 70))
+ c |= hc - 55;
+
+ reinterpret_cast<uint8_t *>(buf)[l++] = c;
+ }
+ return l;
+ }
+
+ static inline unsigned int unhex(const char *h,unsigned int hlen,void *buf,unsigned int buflen)
+ {
+ unsigned int l = 0;
+ const char *hend = h + hlen;
+ while (l < buflen) {
+ if (h == hend) break;
+ uint8_t hc = (uint8_t)*(h++);
+ if (!hc) break;
+
+ uint8_t c = 0;
+ if ((hc >= 48)&&(hc <= 57))
+ c = hc - 48;
+ else if ((hc >= 97)&&(hc <= 102))
+ c = hc - 87;
+ else if ((hc >= 65)&&(hc <= 70))
+ c = hc - 55;
+
+ if (h == hend) break;
+ hc = (uint8_t)*(h++);
+ if (!hc) break;
+
+ c <<= 4;
+ if ((hc >= 48)&&(hc <= 57))
+ c |= hc - 48;
+ else if ((hc >= 97)&&(hc <= 102))
+ c |= hc - 87;
+ else if ((hc >= 65)&&(hc <= 70))
+ c |= hc - 55;
+
+ reinterpret_cast<uint8_t *>(buf)[l++] = c;
+ }
+ return l;
+ }
/**
* Generate secure random bytes
@@ -233,20 +335,6 @@ public:
static bool scopy(char *dest,unsigned int len,const char *src);
/**
- * Variant of snprintf that is portable and throws an exception
- *
- * This just wraps the local implementation whatever it's called, while
- * performing a few other checks and adding exceptions for overflow.
- *
- * @param buf Buffer to write to
- * @param len Length of buffer in bytes
- * @param fmt Format string
- * @param ... Format arguments
- * @throws std::length_error buf[] too short (buf[] will still be left null-terminated)
- */
- static unsigned int ztsnprintf(char *buf,unsigned int len,const char *fmt,...);
-
- /**
* Count the number of bits set in an integer
*
* @param v 32-bit integer