summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--controller/EmbeddedNetworkController.cpp104
-rw-r--r--controller/JSONDB.cpp14
-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
-rw-r--r--one.cpp55
-rw-r--r--osdep/BSDEthernetTap.cpp19
-rw-r--r--osdep/Http.cpp4
-rw-r--r--osdep/LinuxEthernetTap.cpp33
-rw-r--r--osdep/ManagedRoute.cpp11
-rw-r--r--osdep/OSUtils.cpp28
-rw-r--r--osdep/OSUtils.hpp15
-rw-r--r--osdep/OSXEthernetTap.cpp20
-rw-r--r--osdep/PortMapper.cpp4
-rw-r--r--osdep/WindowsEthernetTap.cpp10
-rw-r--r--selftest.cpp31
-rw-r--r--service/OneService.cpp94
-rw-r--r--service/SoftwareUpdater.cpp5
32 files changed, 620 insertions, 678 deletions
diff --git a/controller/EmbeddedNetworkController.cpp b/controller/EmbeddedNetworkController.cpp
index 85c759e7..b57a37e8 100644
--- a/controller/EmbeddedNetworkController.cpp
+++ b/controller/EmbeddedNetworkController.cpp
@@ -76,19 +76,19 @@ static json _renderRule(ZT_VirtualNetworkRule &rule)
break;
case ZT_NETWORK_RULE_ACTION_TEE:
r["type"] = "ACTION_TEE";
- r["address"] = Address(rule.v.fwd.address).toString();
+ r["address"] = Address(rule.v.fwd.address).toString(tmp);
r["flags"] = (unsigned int)rule.v.fwd.flags;
r["length"] = (unsigned int)rule.v.fwd.length;
break;
case ZT_NETWORK_RULE_ACTION_WATCH:
r["type"] = "ACTION_WATCH";
- r["address"] = Address(rule.v.fwd.address).toString();
+ r["address"] = Address(rule.v.fwd.address).toString(tmp);
r["flags"] = (unsigned int)rule.v.fwd.flags;
r["length"] = (unsigned int)rule.v.fwd.length;
break;
case ZT_NETWORK_RULE_ACTION_REDIRECT:
r["type"] = "ACTION_REDIRECT";
- r["address"] = Address(rule.v.fwd.address).toString();
+ r["address"] = Address(rule.v.fwd.address).toString(tmp);
r["flags"] = (unsigned int)rule.v.fwd.flags;
break;
case ZT_NETWORK_RULE_ACTION_BREAK:
@@ -102,11 +102,11 @@ static json _renderRule(ZT_VirtualNetworkRule &rule)
switch(rt) {
case ZT_NETWORK_RULE_MATCH_SOURCE_ZEROTIER_ADDRESS:
r["type"] = "MATCH_SOURCE_ZEROTIER_ADDRESS";
- r["zt"] = Address(rule.v.zt).toString();
+ r["zt"] = Address(rule.v.zt).toString(tmp);
break;
case ZT_NETWORK_RULE_MATCH_DEST_ZEROTIER_ADDRESS:
r["type"] = "MATCH_DEST_ZEROTIER_ADDRESS";
- r["zt"] = Address(rule.v.zt).toString();
+ r["zt"] = Address(rule.v.zt).toString(tmp);
break;
case ZT_NETWORK_RULE_MATCH_VLAN_ID:
r["type"] = "MATCH_VLAN_ID";
@@ -122,29 +122,29 @@ static json _renderRule(ZT_VirtualNetworkRule &rule)
break;
case ZT_NETWORK_RULE_MATCH_MAC_SOURCE:
r["type"] = "MATCH_MAC_SOURCE";
- Utils::ztsnprintf(tmp,sizeof(tmp),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(unsigned int)rule.v.mac[0],(unsigned int)rule.v.mac[1],(unsigned int)rule.v.mac[2],(unsigned int)rule.v.mac[3],(unsigned int)rule.v.mac[4],(unsigned int)rule.v.mac[5]);
+ OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(unsigned int)rule.v.mac[0],(unsigned int)rule.v.mac[1],(unsigned int)rule.v.mac[2],(unsigned int)rule.v.mac[3],(unsigned int)rule.v.mac[4],(unsigned int)rule.v.mac[5]);
r["mac"] = tmp;
break;
case ZT_NETWORK_RULE_MATCH_MAC_DEST:
r["type"] = "MATCH_MAC_DEST";
- Utils::ztsnprintf(tmp,sizeof(tmp),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(unsigned int)rule.v.mac[0],(unsigned int)rule.v.mac[1],(unsigned int)rule.v.mac[2],(unsigned int)rule.v.mac[3],(unsigned int)rule.v.mac[4],(unsigned int)rule.v.mac[5]);
+ OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(unsigned int)rule.v.mac[0],(unsigned int)rule.v.mac[1],(unsigned int)rule.v.mac[2],(unsigned int)rule.v.mac[3],(unsigned int)rule.v.mac[4],(unsigned int)rule.v.mac[5]);
r["mac"] = tmp;
break;
case ZT_NETWORK_RULE_MATCH_IPV4_SOURCE:
r["type"] = "MATCH_IPV4_SOURCE";
- r["ip"] = InetAddress(&(rule.v.ipv4.ip),4,(unsigned int)rule.v.ipv4.mask).toString();
+ r["ip"] = InetAddress(&(rule.v.ipv4.ip),4,(unsigned int)rule.v.ipv4.mask).toString(tmp);
break;
case ZT_NETWORK_RULE_MATCH_IPV4_DEST:
r["type"] = "MATCH_IPV4_DEST";
- r["ip"] = InetAddress(&(rule.v.ipv4.ip),4,(unsigned int)rule.v.ipv4.mask).toString();
+ r["ip"] = InetAddress(&(rule.v.ipv4.ip),4,(unsigned int)rule.v.ipv4.mask).toString(tmp);
break;
case ZT_NETWORK_RULE_MATCH_IPV6_SOURCE:
r["type"] = "MATCH_IPV6_SOURCE";
- r["ip"] = InetAddress(rule.v.ipv6.ip,16,(unsigned int)rule.v.ipv6.mask).toString();
+ r["ip"] = InetAddress(rule.v.ipv6.ip,16,(unsigned int)rule.v.ipv6.mask).toString(tmp);
break;
case ZT_NETWORK_RULE_MATCH_IPV6_DEST:
r["type"] = "MATCH_IPV6_DEST";
- r["ip"] = InetAddress(rule.v.ipv6.ip,16,(unsigned int)rule.v.ipv6.mask).toString();
+ r["ip"] = InetAddress(rule.v.ipv6.ip,16,(unsigned int)rule.v.ipv6.mask).toString(tmp);
break;
case ZT_NETWORK_RULE_MATCH_IP_TOS:
r["type"] = "MATCH_IP_TOS";
@@ -179,7 +179,7 @@ static json _renderRule(ZT_VirtualNetworkRule &rule)
break;
case ZT_NETWORK_RULE_MATCH_CHARACTERISTICS:
r["type"] = "MATCH_CHARACTERISTICS";
- Utils::ztsnprintf(tmp,sizeof(tmp),"%.16llx",rule.v.characteristics);
+ OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.16llx",rule.v.characteristics);
r["mask"] = tmp;
break;
case ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE:
@@ -312,28 +312,28 @@ static bool _parseRule(json &r,ZT_VirtualNetworkRule &rule)
return true;
} else if (t == "MATCH_IPV4_SOURCE") {
rule.t |= ZT_NETWORK_RULE_MATCH_IPV4_SOURCE;
- InetAddress ip(OSUtils::jsonString(r["ip"],"0.0.0.0"));
+ InetAddress ip(OSUtils::jsonString(r["ip"],"0.0.0.0").c_str());
rule.v.ipv4.ip = reinterpret_cast<struct sockaddr_in *>(&ip)->sin_addr.s_addr;
rule.v.ipv4.mask = Utils::ntoh(reinterpret_cast<struct sockaddr_in *>(&ip)->sin_port) & 0xff;
if (rule.v.ipv4.mask > 32) rule.v.ipv4.mask = 32;
return true;
} else if (t == "MATCH_IPV4_DEST") {
rule.t |= ZT_NETWORK_RULE_MATCH_IPV4_DEST;
- InetAddress ip(OSUtils::jsonString(r["ip"],"0.0.0.0"));
+ InetAddress ip(OSUtils::jsonString(r["ip"],"0.0.0.0").c_str());
rule.v.ipv4.ip = reinterpret_cast<struct sockaddr_in *>(&ip)->sin_addr.s_addr;
rule.v.ipv4.mask = Utils::ntoh(reinterpret_cast<struct sockaddr_in *>(&ip)->sin_port) & 0xff;
if (rule.v.ipv4.mask > 32) rule.v.ipv4.mask = 32;
return true;
} else if (t == "MATCH_IPV6_SOURCE") {
rule.t |= ZT_NETWORK_RULE_MATCH_IPV6_SOURCE;
- InetAddress ip(OSUtils::jsonString(r["ip"],"::0"));
+ InetAddress ip(OSUtils::jsonString(r["ip"],"::0").c_str());
memcpy(rule.v.ipv6.ip,reinterpret_cast<struct sockaddr_in6 *>(&ip)->sin6_addr.s6_addr,16);
rule.v.ipv6.mask = Utils::ntoh(reinterpret_cast<struct sockaddr_in6 *>(&ip)->sin6_port) & 0xff;
if (rule.v.ipv6.mask > 128) rule.v.ipv6.mask = 128;
return true;
} else if (t == "MATCH_IPV6_DEST") {
rule.t |= ZT_NETWORK_RULE_MATCH_IPV6_DEST;
- InetAddress ip(OSUtils::jsonString(r["ip"],"::0"));
+ InetAddress ip(OSUtils::jsonString(r["ip"],"::0").c_str());
memcpy(rule.v.ipv6.ip,reinterpret_cast<struct sockaddr_in6 *>(&ip)->sin6_addr.s6_addr,16);
rule.v.ipv6.mask = Utils::ntoh(reinterpret_cast<struct sockaddr_in6 *>(&ip)->sin6_port) & 0xff;
if (rule.v.ipv6.mask > 128) rule.v.ipv6.mask = 128;
@@ -514,7 +514,7 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpGET(
_db.eachMember(nwid,[&responseBody](uint64_t networkId,uint64_t nodeId,const json &member) {
if ((member.is_object())&&(member.size() > 0)) {
char tmp[128];
- Utils::ztsnprintf(tmp,sizeof(tmp),"%s%.10llx\":%llu",(responseBody.length() > 1) ? ",\"" : "\"",(unsigned long long)nodeId,(unsigned long long)OSUtils::jsonInt(member["revision"],0));
+ OSUtils::ztsnprintf(tmp,sizeof(tmp),"%s%.10llx\":%llu",(responseBody.length() > 1) ? ",\"" : "\"",(unsigned long long)nodeId,(unsigned long long)OSUtils::jsonInt(member["revision"],0));
responseBody.append(tmp);
}
});
@@ -548,7 +548,7 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpGET(
for(std::vector<uint64_t>::const_iterator i(networkIds.begin());i!=networkIds.end();++i) {
if (responseBody.length() > 1)
responseBody.push_back(',');
- Utils::ztsnprintf(tmp,sizeof(tmp),"\"%.16llx\"",(unsigned long long)*i);
+ OSUtils::ztsnprintf(tmp,sizeof(tmp),"\"%.16llx\"",(unsigned long long)*i);
responseBody.append(tmp);
}
responseBody.push_back(']');
@@ -562,7 +562,7 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpGET(
// Controller status
char tmp[4096];
- Utils::ztsnprintf(tmp,sizeof(tmp),"{\n\t\"controller\": true,\n\t\"apiVersion\": %d,\n\t\"clock\": %llu\n}\n",ZT_NETCONF_CONTROLLER_API_VERSION,(unsigned long long)OSUtils::now());
+ OSUtils::ztsnprintf(tmp,sizeof(tmp),"{\n\t\"controller\": true,\n\t\"apiVersion\": %d,\n\t\"clock\": %llu\n}\n",ZT_NETCONF_CONTROLLER_API_VERSION,(unsigned long long)OSUtils::now());
responseBody = tmp;
responseContentType = "application/json";
return 200;
@@ -603,14 +603,14 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
if ((path.size() >= 2)&&(path[1].length() == 16)) {
uint64_t nwid = Utils::hexStrToU64(path[1].c_str());
char nwids[24];
- Utils::ztsnprintf(nwids,sizeof(nwids),"%.16llx",(unsigned long long)nwid);
+ OSUtils::ztsnprintf(nwids,sizeof(nwids),"%.16llx",(unsigned long long)nwid);
if (path.size() >= 3) {
if ((path.size() == 4)&&(path[2] == "member")&&(path[3].length() == 10)) {
uint64_t address = Utils::hexStrToU64(path[3].c_str());
char addrs[24];
- Utils::ztsnprintf(addrs,sizeof(addrs),"%.10llx",(unsigned long long)address);
+ OSUtils::ztsnprintf(addrs,sizeof(addrs),"%.10llx",(unsigned long long)address);
json member;
_db.getNetworkMember(nwid,address,member);
@@ -655,9 +655,10 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
json mipa(json::array());
for(unsigned long i=0;i<ipa.size();++i) {
std::string ips = ipa[i];
- InetAddress ip(ips);
+ InetAddress ip(ips.c_str());
if ((ip.ss_family == AF_INET)||(ip.ss_family == AF_INET6)) {
- mipa.push_back(ip.toIpString());
+ char tmpip[64];
+ mipa.push_back(ip.toIpString(tmpip));
}
}
member["ipAssignments"] = mipa;
@@ -748,7 +749,7 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
if (!nwid)
return 503;
}
- Utils::ztsnprintf(nwids,sizeof(nwids),"%.16llx",(unsigned long long)nwid);
+ OSUtils::ztsnprintf(nwids,sizeof(nwids),"%.16llx",(unsigned long long)nwid);
json network;
_db.getNetwork(nwid,network);
@@ -815,14 +816,15 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
json &target = rt["target"];
json &via = rt["via"];
if (target.is_string()) {
- InetAddress t(target.get<std::string>());
+ InetAddress t(target.get<std::string>().c_str());
InetAddress v;
- if (via.is_string()) v.fromString(via.get<std::string>());
+ if (via.is_string()) v.fromString(via.get<std::string>().c_str());
if ( ((t.ss_family == AF_INET)||(t.ss_family == AF_INET6)) && (t.netmaskBitsValid()) ) {
json tmp;
- tmp["target"] = t.toString();
+ char tmp2[64];
+ tmp["target"] = t.toString(tmp2);
if (v.ss_family == t.ss_family)
- tmp["via"] = v.toIpString();
+ tmp["via"] = v.toIpString(tmp2);
else tmp["via"] = json();
nrts.push_back(tmp);
}
@@ -840,12 +842,13 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
for(unsigned long i=0;i<ipp.size();++i) {
json &ip = ipp[i];
if ((ip.is_object())&&(ip.count("ipRangeStart"))&&(ip.count("ipRangeEnd"))) {
- InetAddress f(OSUtils::jsonString(ip["ipRangeStart"],""));
- InetAddress t(OSUtils::jsonString(ip["ipRangeEnd"],""));
+ InetAddress f(OSUtils::jsonString(ip["ipRangeStart"],"").c_str());
+ InetAddress t(OSUtils::jsonString(ip["ipRangeEnd"],"").c_str());
if ( ((f.ss_family == AF_INET)||(f.ss_family == AF_INET6)) && (f.ss_family == t.ss_family) ) {
json tmp = json::object();
- tmp["ipRangeStart"] = f.toIpString();
- tmp["ipRangeEnd"] = t.toIpString();
+ char tmp2[64];
+ tmp["ipRangeStart"] = f.toIpString(tmp2);
+ tmp["ipRangeEnd"] = t.toIpString(tmp2);
nipp.push_back(tmp);
}
}
@@ -995,7 +998,7 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
_queue.post(qe);
char tmp[64];
- Utils::ztsnprintf(tmp,sizeof(tmp),"{\"clock\":%llu,\"ping\":%s}",(unsigned long long)now,OSUtils::jsonDump(b).c_str());
+ OSUtils::ztsnprintf(tmp,sizeof(tmp),"{\"clock\":%llu,\"ping\":%s}",(unsigned long long)now,OSUtils::jsonDump(b).c_str());
responseBody = tmp;
responseContentType = "application/json";
@@ -1083,7 +1086,7 @@ void EmbeddedNetworkController::threadMain()
auto ms = this->_memberStatus.find(_MemberStatusKey(networkId,nodeId));
if (ms != _memberStatus.end())
lrt = ms->second.lastRequestTime;
- Utils::ztsnprintf(tmp,sizeof(tmp),"%s\"%.16llx-%.10llx\":%llu",
+ OSUtils::ztsnprintf(tmp,sizeof(tmp),"%s\"%.16llx-%.10llx\":%llu",
(first) ? "" : ",",
(unsigned long long)networkId,
(unsigned long long)nodeId,
@@ -1093,7 +1096,7 @@ void EmbeddedNetworkController::threadMain()
});
}
char tmp2[256];
- Utils::ztsnprintf(tmp2,sizeof(tmp2),"},\"clock\":%llu,\"startTime\":%llu}",(unsigned long long)now,(unsigned long long)_startTime);
+ OSUtils::ztsnprintf(tmp2,sizeof(tmp2),"},\"clock\":%llu,\"startTime\":%llu}",(unsigned long long)now,(unsigned long long)_startTime);
pong.append(tmp2);
_db.writeRaw("pong",pong);
}
@@ -1126,7 +1129,7 @@ void EmbeddedNetworkController::_request(
ms.lastRequestTime = now;
}
- Utils::ztsnprintf(nwids,sizeof(nwids),"%.16llx",nwid);
+ OSUtils::ztsnprintf(nwids,sizeof(nwids),"%.16llx",nwid);
if (!_db.getNetworkAndMember(nwid,identity.address().toInt(),network,member,ns)) {
_sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_OBJECT_NOT_FOUND);
return;
@@ -1152,13 +1155,15 @@ void EmbeddedNetworkController::_request(
}
} else {
// If we do not yet know this member's identity, learn it.
- member["identity"] = identity.toString(false);
+ char idtmp[1024];
+ member["identity"] = identity.toString(false,idtmp);
}
}
// These are always the same, but make sure they are set
{
- const std::string addrs(identity.address().toString());
+ char tmpid[128];
+ const std::string addrs(identity.address().toString(tmpid));
member["id"] = addrs;
member["address"] = addrs;
member["nwid"] = nwids;
@@ -1264,8 +1269,9 @@ void EmbeddedNetworkController::_request(
if (fromAddr)
ms.physicalAddr = fromAddr;
+ char tmpip[64];
if (ms.physicalAddr)
- member["physicalAddr"] = ms.physicalAddr.toString();
+ member["physicalAddr"] = ms.physicalAddr.toString(tmpip);
}
}
} else {
@@ -1427,9 +1433,9 @@ void EmbeddedNetworkController::_request(
json &target = route["target"];
json &via = route["via"];
if (target.is_string()) {
- const InetAddress t(target.get<std::string>());
+ const InetAddress t(target.get<std::string>().c_str());
InetAddress v;
- if (via.is_string()) v.fromString(via.get<std::string>());
+ if (via.is_string()) v.fromString(via.get<std::string>().c_str());
if ((t.ss_family == AF_INET)||(t.ss_family == AF_INET6)) {
ZT_VirtualNetworkRoute *r = &(nc->routes[nc->routeCount]);
*(reinterpret_cast<InetAddress *>(&(r->target))) = t;
@@ -1462,7 +1468,7 @@ void EmbeddedNetworkController::_request(
if (!ipAssignments[i].is_string())
continue;
std::string ips = ipAssignments[i];
- InetAddress ip(ips);
+ InetAddress ip(ips.c_str());
// IP assignments are only pushed if there is a corresponding local route. We also now get the netmask bits from
// this route, ignoring the netmask bits field of the assigned IP itself. Using that was worthless and a source
@@ -1492,8 +1498,8 @@ void EmbeddedNetworkController::_request(
for(unsigned long p=0;((p<ipAssignmentPools.size())&&(!haveManagedIpv6AutoAssignment));++p) {
json &pool = ipAssignmentPools[p];
if (pool.is_object()) {
- InetAddress ipRangeStart(OSUtils::jsonString(pool["ipRangeStart"],""));
- InetAddress ipRangeEnd(OSUtils::jsonString(pool["ipRangeEnd"],""));
+ InetAddress ipRangeStart(OSUtils::jsonString(pool["ipRangeStart"],"").c_str());
+ InetAddress ipRangeEnd(OSUtils::jsonString(pool["ipRangeEnd"],"").c_str());
if ( (ipRangeStart.ss_family == AF_INET6) && (ipRangeEnd.ss_family == AF_INET6) ) {
uint64_t s[2],e[2],x[2],xx[2];
memcpy(s,ipRangeStart.rawIpData(),16);
@@ -1534,7 +1540,8 @@ void EmbeddedNetworkController::_request(
// If it's routed, then try to claim and assign it and if successful end loop
if ( (routedNetmaskBits > 0) && (!std::binary_search(ns.allocatedIps.begin(),ns.allocatedIps.end(),ip6)) ) {
- ipAssignments.push_back(ip6.toIpString());
+ char tmpip[64];
+ ipAssignments.push_back(ip6.toIpString(tmpip));
member["ipAssignments"] = ipAssignments;
ip6.setPort((unsigned int)routedNetmaskBits);
if (nc->staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES)
@@ -1552,8 +1559,8 @@ void EmbeddedNetworkController::_request(
for(unsigned long p=0;((p<ipAssignmentPools.size())&&(!haveManagedIpv4AutoAssignment));++p) {
json &pool = ipAssignmentPools[p];
if (pool.is_object()) {
- InetAddress ipRangeStartIA(OSUtils::jsonString(pool["ipRangeStart"],""));
- InetAddress ipRangeEndIA(OSUtils::jsonString(pool["ipRangeEnd"],""));
+ InetAddress ipRangeStartIA(OSUtils::jsonString(pool["ipRangeStart"],"").c_str());
+ InetAddress ipRangeEndIA(OSUtils::jsonString(pool["ipRangeEnd"],"").c_str());
if ( (ipRangeStartIA.ss_family == AF_INET) && (ipRangeEndIA.ss_family == AF_INET) ) {
uint32_t ipRangeStart = Utils::ntoh((uint32_t)(reinterpret_cast<struct sockaddr_in *>(&ipRangeStartIA)->sin_addr.s_addr));
uint32_t ipRangeEnd = Utils::ntoh((uint32_t)(reinterpret_cast<struct sockaddr_in *>(&ipRangeEndIA)->sin_addr.s_addr));
@@ -1586,7 +1593,8 @@ void EmbeddedNetworkController::_request(
// If it's routed, then try to claim and assign it and if successful end loop
const InetAddress ip4(Utils::hton(ip),0);
if ( (routedNetmaskBits > 0) && (!std::binary_search(ns.allocatedIps.begin(),ns.allocatedIps.end(),ip4)) ) {
- ipAssignments.push_back(ip4.toIpString());
+ char tmpip[64];
+ ipAssignments.push_back(ip4.toIpString(tmpip));
member["ipAssignments"] = ipAssignments;
if (nc->staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES) {
struct sockaddr_in *const v4ip = reinterpret_cast<struct sockaddr_in *>(&(nc->staticIps[nc->staticIpCount++]));
diff --git a/controller/JSONDB.cpp b/controller/JSONDB.cpp
index acf23700..97a217a1 100644
--- a/controller/JSONDB.cpp
+++ b/controller/JSONDB.cpp
@@ -39,7 +39,7 @@ JSONDB::JSONDB(const std::string &basePath) :
std::size_t hnsep = hn.find_last_of(':');
if (hnsep != std::string::npos)
hn[hnsep] = '/';
- _httpAddr.fromString(hn);
+ _httpAddr.fromString(hn.c_str());
if (hnend != std::string::npos)
_basePath = _basePath.substr(7 + hnend);
if (_basePath.length() == 0)
@@ -94,7 +94,7 @@ bool JSONDB::writeRaw(const std::string &n,const std::string &obj)
std::string body;
std::map<std::string,std::string> reqHeaders;
char tmp[64];
- Utils::ztsnprintf(tmp,sizeof(tmp),"%lu",(unsigned long)obj.length());
+ OSUtils::ztsnprintf(tmp,sizeof(tmp),"%lu",(unsigned long)obj.length());
reqHeaders["Content-Length"] = tmp;
reqHeaders["Content-Type"] = "application/json";
const unsigned int sc = Http::PUT(0,ZT_JSONDB_HTTP_TIMEOUT,reinterpret_cast<const struct sockaddr *>(&_httpAddr),(_basePath+"/"+n).c_str(),reqHeaders,obj.data(),(unsigned long)obj.length(),headers,body);
@@ -164,7 +164,7 @@ bool JSONDB::getNetworkMember(const uint64_t networkId,const uint64_t nodeId,nlo
void JSONDB::saveNetwork(const uint64_t networkId,const nlohmann::json &networkConfig)
{
char n[64];
- Utils::ztsnprintf(n,sizeof(n),"network/%.16llx",(unsigned long long)networkId);
+ OSUtils::ztsnprintf(n,sizeof(n),"network/%.16llx",(unsigned long long)networkId);
writeRaw(n,OSUtils::jsonDump(networkConfig));
{
Mutex::Lock _l(_networks_m);
@@ -176,7 +176,7 @@ void JSONDB::saveNetwork(const uint64_t networkId,const nlohmann::json &networkC
void JSONDB::saveNetworkMember(const uint64_t networkId,const uint64_t nodeId,const nlohmann::json &memberConfig)
{
char n[256];
- Utils::ztsnprintf(n,sizeof(n),"network/%.16llx/member/%.10llx",(unsigned long long)networkId,(unsigned long long)nodeId);
+ OSUtils::ztsnprintf(n,sizeof(n),"network/%.16llx/member/%.10llx",(unsigned long long)networkId,(unsigned long long)nodeId);
writeRaw(n,OSUtils::jsonDump(memberConfig));
{
Mutex::Lock _l(_networks_m);
@@ -202,7 +202,7 @@ nlohmann::json JSONDB::eraseNetwork(const uint64_t networkId)
}
char n[256];
- Utils::ztsnprintf(n,sizeof(n),"network/%.16llx",(unsigned long long)networkId);
+ OSUtils::ztsnprintf(n,sizeof(n),"network/%.16llx",(unsigned long long)networkId);
if (_httpAddr) {
// Deletion is currently done by Central in harnessed mode
@@ -229,7 +229,7 @@ nlohmann::json JSONDB::eraseNetwork(const uint64_t networkId)
nlohmann::json JSONDB::eraseNetworkMember(const uint64_t networkId,const uint64_t nodeId,bool recomputeSummaryInfo)
{
char n[256];
- Utils::ztsnprintf(n,sizeof(n),"network/%.16llx/member/%.10llx",(unsigned long long)networkId,(unsigned long long)nodeId);
+ OSUtils::ztsnprintf(n,sizeof(n),"network/%.16llx/member/%.10llx",(unsigned long long)networkId,(unsigned long long)nodeId);
if (_httpAddr) {
// Deletion is currently done by the caller in Central harnessed mode
@@ -314,7 +314,7 @@ void JSONDB::threadMain()
const nlohmann::json &mips = member["ipAssignments"];
if (mips.is_array()) {
for(unsigned long i=0;i<mips.size();++i) {
- InetAddress mip(OSUtils::jsonString(mips[i],""));
+ InetAddress mip(OSUtils::jsonString(mips[i],"").c_str());
if ((mip.ss_family == AF_INET)||(mip.ss_family == AF_INET6))
ns.allocatedIps.push_back(mip);
}
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
diff --git a/one.cpp b/one.cpp
index cbf09121..b1a19e8c 100644
--- a/one.cpp
+++ b/one.cpp
@@ -260,9 +260,9 @@ static int cli(int argc,char **argv)
if (hd) {
char p[4096];
#ifdef __APPLE__
- Utils::ztsnprintf(p,sizeof(p),"%s/Library/Application Support/ZeroTier/One/authtoken.secret",hd);
+ OSUtils::ztsnprintf(p,sizeof(p),"%s/Library/Application Support/ZeroTier/One/authtoken.secret",hd);
#else
- Utils::ztsnprintf(p,sizeof(p),"%s/.zeroTierOneAuthToken",hd);
+ OSUtils::ztsnprintf(p,sizeof(p),"%s/.zeroTierOneAuthToken",hd);
#endif
OSUtils::readFile(p,authToken);
}
@@ -278,7 +278,7 @@ static int cli(int argc,char **argv)
InetAddress addr;
{
char addrtmp[256];
- Utils::ztsnprintf(addrtmp,sizeof(addrtmp),"%s/%u",ip.c_str(),port);
+ OSUtils::ztsnprintf(addrtmp,sizeof(addrtmp),"%s/%u",ip.c_str(),port);
addr = InetAddress(addrtmp);
}
@@ -366,7 +366,7 @@ static int cli(int argc,char **argv)
std::string addr = path["address"];
const uint64_t now = OSUtils::now();
const double lq = (path.count("linkQuality")) ? (double)path["linkQuality"] : -1.0;
- Utils::ztsnprintf(tmp,sizeof(tmp),"%s;%llu;%llu;%1.2f",addr.c_str(),now - (uint64_t)path["lastSend"],now - (uint64_t)path["lastReceive"],lq);
+ OSUtils::ztsnprintf(tmp,sizeof(tmp),"%s;%llu;%llu;%1.2f",addr.c_str(),now - (uint64_t)path["lastSend"],now - (uint64_t)path["lastReceive"],lq);
bestPath = tmp;
break;
}
@@ -378,7 +378,7 @@ static int cli(int argc,char **argv)
int64_t vmin = p["versionMinor"];
int64_t vrev = p["versionRev"];
if (vmaj >= 0) {
- Utils::ztsnprintf(ver,sizeof(ver),"%lld.%lld.%lld",vmaj,vmin,vrev);
+ OSUtils::ztsnprintf(ver,sizeof(ver),"%lld.%lld.%lld",vmaj,vmin,vrev);
} else {
ver[0] = '-';
ver[1] = (char)0;
@@ -527,9 +527,9 @@ static int cli(int argc,char **argv)
const uint64_t seed = Utils::hexStrToU64(arg2.c_str());
if ((worldId)&&(seed)) {
char jsons[1024];
- Utils::ztsnprintf(jsons,sizeof(jsons),"{\"seed\":\"%s\"}",arg2.c_str());
+ OSUtils::ztsnprintf(jsons,sizeof(jsons),"{\"seed\":\"%s\"}",arg2.c_str());
char cl[128];
- Utils::ztsnprintf(cl,sizeof(cl),"%u",(unsigned int)strlen(jsons));
+ OSUtils::ztsnprintf(cl,sizeof(cl),"%u",(unsigned int)strlen(jsons));
requestHeaders["Content-Type"] = "application/json";
requestHeaders["Content-Length"] = cl;
unsigned int scode = Http::POST(
@@ -579,11 +579,11 @@ static int cli(int argc,char **argv)
if (eqidx != std::string::npos) {
if ((arg2.substr(0,eqidx) == "allowManaged")||(arg2.substr(0,eqidx) == "allowGlobal")||(arg2.substr(0,eqidx) == "allowDefault")) {
char jsons[1024];
- Utils::ztsnprintf(jsons,sizeof(jsons),"{\"%s\":%s}",
+ OSUtils::ztsnprintf(jsons,sizeof(jsons),"{\"%s\":%s}",
arg2.substr(0,eqidx).c_str(),
(((arg2.substr(eqidx,2) == "=t")||(arg2.substr(eqidx,2) == "=1")) ? "true" : "false"));
char cl[128];
- Utils::ztsnprintf(cl,sizeof(cl),"%u",(unsigned int)strlen(jsons));
+ OSUtils::ztsnprintf(cl,sizeof(cl),"%u",(unsigned int)strlen(jsons));
requestHeaders["Content-Type"] = "application/json";
requestHeaders["Content-Length"] = cl;
unsigned int scode = Http::POST(
@@ -648,7 +648,7 @@ static Identity getIdFromArg(char *arg)
} else { // identity is to be read from a file
std::string idser;
if (OSUtils::readFile(arg,idser)) {
- if (id.fromString(idser))
+ if (id.fromString(idser.c_str()))
return id;
}
}
@@ -689,14 +689,15 @@ static int idtool(int argc,char **argv)
}
}
- std::string idser = id.toString(true);
+ char idtmp[1024];
+ std::string idser = id.toString(true,idtmp);
if (argc >= 3) {
if (!OSUtils::writeFile(argv[2],idser)) {
fprintf(stderr,"Error writing to %s" ZT_EOL_S,argv[2]);
return 1;
} else printf("%s written" ZT_EOL_S,argv[2]);
if (argc >= 4) {
- idser = id.toString(false);
+ idser = id.toString(false,idtmp);
if (!OSUtils::writeFile(argv[3],idser)) {
fprintf(stderr,"Error writing to %s" ZT_EOL_S,argv[3]);
return 1;
@@ -731,7 +732,8 @@ static int idtool(int argc,char **argv)
return 1;
}
- printf("%s",id.toString(false).c_str());
+ char idtmp[1024];
+ printf("%s",id.toString(false,idtmp));
} else if (!strcmp(argv[1],"sign")) {
if (argc < 4) {
idtoolPrintHelp(stdout,argv[0]);
@@ -755,7 +757,8 @@ static int idtool(int argc,char **argv)
return 1;
}
C25519::Signature signature = id.sign(inf.data(),(unsigned int)inf.length());
- printf("%s",Utils::hex(signature.data,(unsigned int)signature.size()).c_str());
+ char hexbuf[1024];
+ printf("%s",Utils::hex(signature.data,(unsigned int)signature.size(),hexbuf));
} else if (!strcmp(argv[1],"verify")) {
if (argc < 4) {
idtoolPrintHelp(stdout,argv[0]);
@@ -774,7 +777,8 @@ static int idtool(int argc,char **argv)
return 1;
}
- std::string signature(Utils::unhex(argv[4]));
+ char buf[4096];
+ std::string signature(buf,Utils::unhex(argv[4],buf,(unsigned int)sizeof(buf)));
if ((signature.length() > ZT_ADDRESS_LENGTH)&&(id.verify(inf.data(),(unsigned int)inf.length(),signature.data(),(unsigned int)signature.length()))) {
printf("%s signature valid" ZT_EOL_S,argv[3]);
} else {
@@ -793,14 +797,15 @@ static int idtool(int argc,char **argv)
C25519::Pair kp(C25519::generate());
+ char idtmp[4096];
nlohmann::json mj;
mj["objtype"] = "world";
mj["worldType"] = "moon";
- mj["updatesMustBeSignedBy"] = mj["signingKey"] = Utils::hex(kp.pub.data,(unsigned int)kp.pub.size());
- mj["signingKey_SECRET"] = Utils::hex(kp.priv.data,(unsigned int)kp.priv.size());
- mj["id"] = id.address().toString();
+ mj["updatesMustBeSignedBy"] = mj["signingKey"] = Utils::hex(kp.pub.data,(unsigned int)kp.pub.size(),idtmp);
+ mj["signingKey_SECRET"] = Utils::hex(kp.priv.data,(unsigned int)kp.priv.size(),idtmp);
+ mj["id"] = id.address().toString(idtmp);
nlohmann::json seedj;
- seedj["identity"] = id.toString(false);
+ seedj["identity"] = id.toString(false,idtmp);
seedj["stableEndpoints"] = nlohmann::json::array();
(mj["roots"] = nlohmann::json::array()).push_back(seedj);
std::string mjd(OSUtils::jsonDump(mj));
@@ -836,9 +841,9 @@ static int idtool(int argc,char **argv)
C25519::Pair signingKey;
C25519::Public updatesMustBeSignedBy;
- Utils::unhex(OSUtils::jsonString(mj["signingKey"],""),signingKey.pub.data,(unsigned int)signingKey.pub.size());
- Utils::unhex(OSUtils::jsonString(mj["signingKey_SECRET"],""),signingKey.priv.data,(unsigned int)signingKey.priv.size());
- Utils::unhex(OSUtils::jsonString(mj["updatesMustBeSignedBy"],""),updatesMustBeSignedBy.data,(unsigned int)updatesMustBeSignedBy.size());
+ Utils::unhex(OSUtils::jsonString(mj["signingKey"],"").c_str(),signingKey.pub.data,(unsigned int)signingKey.pub.size());
+ Utils::unhex(OSUtils::jsonString(mj["signingKey_SECRET"],"").c_str(),signingKey.priv.data,(unsigned int)signingKey.priv.size());
+ Utils::unhex(OSUtils::jsonString(mj["updatesMustBeSignedBy"],"").c_str(),updatesMustBeSignedBy.data,(unsigned int)updatesMustBeSignedBy.size());
std::vector<World::Root> roots;
nlohmann::json &rootsj = mj["roots"];
@@ -847,11 +852,11 @@ static int idtool(int argc,char **argv)
nlohmann::json &r = rootsj[i];
if (r.is_object()) {
roots.push_back(World::Root());
- roots.back().identity = Identity(OSUtils::jsonString(r["identity"],""));
+ roots.back().identity = Identity(OSUtils::jsonString(r["identity"],"").c_str());
nlohmann::json &stableEndpointsj = r["stableEndpoints"];
if (stableEndpointsj.is_array()) {
for(unsigned long k=0;k<(unsigned long)stableEndpointsj.size();++k)
- roots.back().stableEndpoints.push_back(InetAddress(OSUtils::jsonString(stableEndpointsj[k],"")));
+ roots.back().stableEndpoints.push_back(InetAddress(OSUtils::jsonString(stableEndpointsj[k],"").c_str()));
std::sort(roots.back().stableEndpoints.begin(),roots.back().stableEndpoints.end());
}
}
@@ -864,7 +869,7 @@ static int idtool(int argc,char **argv)
Buffer<ZT_WORLD_MAX_SERIALIZED_LENGTH> wbuf;
w.serialize(wbuf);
char fn[128];
- Utils::ztsnprintf(fn,sizeof(fn),"%.16llx.moon",w.id());
+ OSUtils::ztsnprintf(fn,sizeof(fn),"%.16llx.moon",w.id());
OSUtils::writeFile(fn,wbuf.data(),wbuf.size());
printf("wrote %s (signed world with timestamp %llu)" ZT_EOL_S,fn,(unsigned long long)now);
}
diff --git a/osdep/BSDEthernetTap.cpp b/osdep/BSDEthernetTap.cpp
index f07f9e5a..8e57d605 100644
--- a/osdep/BSDEthernetTap.cpp
+++ b/osdep/BSDEthernetTap.cpp
@@ -114,8 +114,8 @@ BSDEthernetTap::BSDEthernetTap(
std::vector<std::string> devFiles(OSUtils::listDirectory("/dev"));
for(int i=9993;i<(9993+128);++i) {
- Utils::ztsnprintf(tmpdevname,sizeof(tmpdevname),"tap%d",i);
- Utils::ztsnprintf(devpath,sizeof(devpath),"/dev/%s",tmpdevname);
+ OSUtils::ztsnprintf(tmpdevname,sizeof(tmpdevname),"tap%d",i);
+ OSUtils::ztsnprintf(devpath,sizeof(devpath),"/dev/%s",tmpdevname);
if (std::find(devFiles.begin(),devFiles.end(),std::string(tmpdevname)) == devFiles.end()) {
long cpid = (long)vfork();
if (cpid == 0) {
@@ -152,8 +152,8 @@ BSDEthernetTap::BSDEthernetTap(
/* Other BSDs like OpenBSD only have a limited number of tap devices that cannot be renamed */
for(int i=0;i<64;++i) {
- Utils::ztsnprintf(tmpdevname,sizeof(tmpdevname),"tap%d",i);
- Utils::ztsnprintf(devpath,sizeof(devpath),"/dev/%s",tmpdevname);
+ OSUtils::ztsnprintf(tmpdevname,sizeof(tmpdevname),"tap%d",i);
+ OSUtils::ztsnprintf(devpath,sizeof(devpath),"/dev/%s",tmpdevname);
_fd = ::open(devpath,O_RDWR);
if (_fd > 0) {
_dev = tmpdevname;
@@ -171,9 +171,9 @@ BSDEthernetTap::BSDEthernetTap(
}
// Configure MAC address and MTU, bring interface up
- Utils::ztsnprintf(ethaddr,sizeof(ethaddr),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(int)mac[0],(int)mac[1],(int)mac[2],(int)mac[3],(int)mac[4],(int)mac[5]);
- Utils::ztsnprintf(mtustr,sizeof(mtustr),"%u",_mtu);
- Utils::ztsnprintf(metstr,sizeof(metstr),"%u",_metric);
+ OSUtils::ztsnprintf(ethaddr,sizeof(ethaddr),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(int)mac[0],(int)mac[1],(int)mac[2],(int)mac[3],(int)mac[4],(int)mac[5]);
+ OSUtils::ztsnprintf(mtustr,sizeof(mtustr),"%u",_mtu);
+ OSUtils::ztsnprintf(metstr,sizeof(metstr),"%u",_metric);
long cpid = (long)vfork();
if (cpid == 0) {
::execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),"lladdr",ethaddr,"mtu",mtustr,"metric",metstr,"up",(const char *)0);
@@ -256,7 +256,8 @@ bool BSDEthernetTap::addIp(const InetAddress &ip)
long cpid = (long)vfork();
if (cpid == 0) {
- ::execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),ip.isV4() ? "inet" : "inet6",ip.toString().c_str(),"alias",(const char *)0);
+ char tmp[128];
+ ::execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),ip.isV4() ? "inet" : "inet6",ip.toString(tmp),"alias",(const char *)0);
::_exit(-1);
} else if (cpid > 0) {
int exitcode = -1;
@@ -385,7 +386,7 @@ void BSDEthernetTap::setMtu(unsigned int mtu)
long cpid = (long)vfork();
if (cpid == 0) {
char tmp[64];
- Utils::ztsnprintf(tmp,sizeof(tmp),"%u",mtu);
+ OSUtils::ztsnprintf(tmp,sizeof(tmp),"%u",mtu);
execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),"mtu",tmp,(const char *)0);
_exit(-1);
} else if (cpid > 0) {
diff --git a/osdep/Http.cpp b/osdep/Http.cpp
index 3c556f44..d6d0238c 100644
--- a/osdep/Http.cpp
+++ b/osdep/Http.cpp
@@ -244,10 +244,10 @@ unsigned int Http::_do(
try {
char tmp[1024];
- Utils::ztsnprintf(tmp,sizeof(tmp),"%s %s HTTP/1.1\r\n",method,path);
+ OSUtils::ztsnprintf(tmp,sizeof(tmp),"%s %s HTTP/1.1\r\n",method,path);
handler.writeBuf.append(tmp);
for(std::map<std::string,std::string>::const_iterator h(requestHeaders.begin());h!=requestHeaders.end();++h) {
- Utils::ztsnprintf(tmp,sizeof(tmp),"%s: %s\r\n",h->first.c_str(),h->second.c_str());
+ OSUtils::ztsnprintf(tmp,sizeof(tmp),"%s: %s\r\n",h->first.c_str(),h->second.c_str());
handler.writeBuf.append(tmp);
}
handler.writeBuf.append("\r\n");
diff --git a/osdep/LinuxEthernetTap.cpp b/osdep/LinuxEthernetTap.cpp
index fc5199f1..c8f9ef9d 100644
--- a/osdep/LinuxEthernetTap.cpp
+++ b/osdep/LinuxEthernetTap.cpp
@@ -97,7 +97,7 @@ LinuxEthernetTap::LinuxEthernetTap(
char procpath[128],nwids[32];
struct stat sbuf;
- Utils::ztsnprintf(nwids,sizeof(nwids),"%.16llx",nwid);
+ OSUtils::ztsnprintf(nwids,sizeof(nwids),"%.16llx",nwid);
Mutex::Lock _l(__tapCreateLock); // create only one tap at a time, globally
@@ -134,7 +134,7 @@ LinuxEthernetTap::LinuxEthernetTap(
std::map<std::string,std::string>::const_iterator gdmEntry = globalDeviceMap.find(nwids);
if (gdmEntry != globalDeviceMap.end()) {
Utils::scopy(ifr.ifr_name,sizeof(ifr.ifr_name),gdmEntry->second.c_str());
- Utils::ztsnprintf(procpath,sizeof(procpath),"/proc/sys/net/ipv4/conf/%s",ifr.ifr_name);
+ OSUtils::ztsnprintf(procpath,sizeof(procpath),"/proc/sys/net/ipv4/conf/%s",ifr.ifr_name);
recalledDevice = (stat(procpath,&sbuf) != 0);
}
@@ -142,8 +142,8 @@ LinuxEthernetTap::LinuxEthernetTap(
#ifdef __SYNOLOGY__
int devno = 50;
do {
- Utils::ztsnprintf(ifr.ifr_name,sizeof(ifr.ifr_name),"eth%d",devno++);
- Utils::ztsnprintf(procpath,sizeof(procpath),"/proc/sys/net/ipv4/conf/%s",ifr.ifr_name);
+ OSUtils::ztsnprintf(ifr.ifr_name,sizeof(ifr.ifr_name),"eth%d",devno++);
+ OSUtils::ztsnprintf(procpath,sizeof(procpath),"/proc/sys/net/ipv4/conf/%s",ifr.ifr_name);
} while (stat(procpath,&sbuf) == 0); // try zt#++ until we find one that does not exist
#else
char devno = 0;
@@ -158,7 +158,7 @@ LinuxEthernetTap::LinuxEthernetTap(
_base32_5_to_8(reinterpret_cast<const uint8_t *>(tmp2) + 5,tmp3 + 10);
tmp3[15] = (char)0;
memcpy(ifr.ifr_name,tmp3,16);
- Utils::ztsnprintf(procpath,sizeof(procpath),"/proc/sys/net/ipv4/conf/%s",ifr.ifr_name);
+ OSUtils::ztsnprintf(procpath,sizeof(procpath),"/proc/sys/net/ipv4/conf/%s",ifr.ifr_name);
} while (stat(procpath,&sbuf) == 0);
#endif
}
@@ -264,7 +264,8 @@ static bool ___removeIp(const std::string &_dev,const InetAddress &ip)
if (cpid == 0) {
OSUtils::redirectUnixOutputs("/dev/null",(const char *)0);
setenv("PATH", "/sbin:/bin:/usr/sbin:/usr/bin", 1);
- ::execlp("ip","ip","addr","del",ip.toString().c_str(),"dev",_dev.c_str(),(const char *)0);
+ char iptmp[128];
+ ::execlp("ip","ip","addr","del",ip.toString(iptmp),"dev",_dev.c_str(),(const char *)0);
::_exit(-1);
} else {
int exitcode = -1;
@@ -296,25 +297,28 @@ bool LinuxEthernetTap::addIpSyn(std::vector<InetAddress> ips)
// Assemble and write contents of ifcfg-dev file
for(int i=0; i<(int)ips.size(); i++) {
if (ips[i].isV4()) {
+ char iptmp[64],iptmp2[64];
std::string numstr4 = ip4_tot > 1 ? std::to_string(ip4) : "";
- cfg_contents += "\nIPADDR"+numstr4+"="+ips[i].toIpString()
- + "\nNETMASK"+numstr4+"="+ips[i].netmask().toIpString()+"\n";
+ cfg_contents += "\nIPADDR"+numstr4+"="+ips[i].toIpString(iptmp)
+ + "\nNETMASK"+numstr4+"="+ips[i].netmask().toIpString(iptmp2)+"\n";
ip4++;
}
else {
+ char iptmp[64],iptmp2[64];
std::string numstr6 = ip6_tot > 1 ? std::to_string(ip6) : "";
- cfg_contents += "\nIPV6ADDR"+numstr6+"="+ips[i].toIpString()
- + "\nNETMASK"+numstr6+"="+ips[i].netmask().toIpString()+"\n";
+ cfg_contents += "\nIPV6ADDR"+numstr6+"="+ips[i].toIpString(iptmp)
+ + "\nNETMASK"+numstr6+"="+ips[i].netmask().toIpString(iptmp2)+"\n";
ip6++;
}
}
OSUtils::writeFile(filepath.c_str(), cfg_contents.c_str(), cfg_contents.length());
// Finaly, add IPs
for(int i=0; i<(int)ips.size(); i++){
+ char iptmp[128],iptmp2[128[;
if (ips[i].isV4())
- ::execlp("ip","ip","addr","add",ips[i].toString().c_str(),"broadcast",ips[i].broadcast().toIpString().c_str(),"dev",_dev.c_str(),(const char *)0);
+ ::execlp("ip","ip","addr","add",ips[i].toString(iptmp),"broadcast",ips[i].broadcast().toIpString(iptmp2),"dev",_dev.c_str(),(const char *)0);
else
- ::execlp("ip","ip","addr","add",ips[i].toString().c_str(),"dev",_dev.c_str(),(const char *)0);
+ ::execlp("ip","ip","addr","add",ips[i].toString(iptmp),"dev",_dev.c_str(),(const char *)0);
}
::_exit(-1);
} else if (cpid > 0) {
@@ -345,10 +349,11 @@ bool LinuxEthernetTap::addIp(const InetAddress &ip)
if (cpid == 0) {
OSUtils::redirectUnixOutputs("/dev/null",(const char *)0);
setenv("PATH", "/sbin:/bin:/usr/sbin:/usr/bin", 1);
+ char iptmp[128],iptmp2[128];
if (ip.isV4()) {
- ::execlp("ip","ip","addr","add",ip.toString().c_str(),"broadcast",ip.broadcast().toIpString().c_str(),"dev",_dev.c_str(),(const char *)0);
+ ::execlp("ip","ip","addr","add",ip.toString(iptmp),"broadcast",ip.broadcast().toIpString(iptmp2),"dev",_dev.c_str(),(const char *)0);
} else {
- ::execlp("ip","ip","addr","add",ip.toString().c_str(),"dev",_dev.c_str(),(const char *)0);
+ ::execlp("ip","ip","addr","add",ip.toString(iptmp),"dev",_dev.c_str(),(const char *)0);
}
::_exit(-1);
} else if (cpid > 0) {
diff --git a/osdep/ManagedRoute.cpp b/osdep/ManagedRoute.cpp
index fca1c290..3a0b8a7e 100644
--- a/osdep/ManagedRoute.cpp
+++ b/osdep/ManagedRoute.cpp
@@ -246,7 +246,6 @@ static std::vector<_RTE> _getRTEs(const InetAddress &target,bool contains)
static void _routeCmd(const char *op,const InetAddress &target,const InetAddress &via,const char *ifscope,const char *localInterface)
{
- //printf("route %s %s %s %s %s\n",op,target.toString().c_str(),(via) ? via.toString().c_str() : "(null)",(ifscope) ? ifscope : "(null)",(localInterface) ? localInterface : "(null)");
long p = (long)fork();
if (p > 0) {
int exitcode = -1;
@@ -254,17 +253,19 @@ static void _routeCmd(const char *op,const InetAddress &target,const InetAddress
} else if (p == 0) {
::close(STDOUT_FILENO);
::close(STDERR_FILENO);
+ char ttmp[64];
+ char iptmp[64];
if (via) {
if ((ifscope)&&(ifscope[0])) {
- ::execl(ZT_BSD_ROUTE_CMD,ZT_BSD_ROUTE_CMD,op,"-ifscope",ifscope,((target.ss_family == AF_INET6) ? "-inet6" : "-inet"),target.toString().c_str(),via.toIpString().c_str(),(const char *)0);
+ ::execl(ZT_BSD_ROUTE_CMD,ZT_BSD_ROUTE_CMD,op,"-ifscope",ifscope,((target.ss_family == AF_INET6) ? "-inet6" : "-inet"),target.toString(ttmp),via.toIpString(iptmp),(const char *)0);
} else {
- ::execl(ZT_BSD_ROUTE_CMD,ZT_BSD_ROUTE_CMD,op,((target.ss_family == AF_INET6) ? "-inet6" : "-inet"),target.toString().c_str(),via.toIpString().c_str(),(const char *)0);
+ ::execl(ZT_BSD_ROUTE_CMD,ZT_BSD_ROUTE_CMD,op,((target.ss_family == AF_INET6) ? "-inet6" : "-inet"),target.toString(ttmp),via.toIpString(iptmp),(const char *)0);
}
} else if ((localInterface)&&(localInterface[0])) {
if ((ifscope)&&(ifscope[0])) {
- ::execl(ZT_BSD_ROUTE_CMD,ZT_BSD_ROUTE_CMD,op,"-ifscope",ifscope,((target.ss_family == AF_INET6) ? "-inet6" : "-inet"),target.toString().c_str(),"-interface",localInterface,(const char *)0);
+ ::execl(ZT_BSD_ROUTE_CMD,ZT_BSD_ROUTE_CMD,op,"-ifscope",ifscope,((target.ss_family == AF_INET6) ? "-inet6" : "-inet"),target.toString(ttmp),"-interface",localInterface,(const char *)0);
} else {
- ::execl(ZT_BSD_ROUTE_CMD,ZT_BSD_ROUTE_CMD,op,((target.ss_family == AF_INET6) ? "-inet6" : "-inet"),target.toString().c_str(),"-interface",localInterface,(const char *)0);
+ ::execl(ZT_BSD_ROUTE_CMD,ZT_BSD_ROUTE_CMD,op,((target.ss_family == AF_INET6) ? "-inet6" : "-inet"),target.toString(ttmp),"-interface",localInterface,(const char *)0);
}
}
::_exit(-1);
diff --git a/osdep/OSUtils.cpp b/osdep/OSUtils.cpp
index 06508e77..882b8255 100644
--- a/osdep/OSUtils.cpp
+++ b/osdep/OSUtils.cpp
@@ -57,6 +57,23 @@
namespace ZeroTier {
+unsigned int OSUtils::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;
+}
+
#ifdef __UNIX_LIKE__
bool OSUtils::redirectUnixOutputs(const char *stdoutPath,const char *stderrPath)
throw()
@@ -134,7 +151,7 @@ long OSUtils::cleanDirectory(const char *path,const uint64_t olderThan)
if (date.QuadPart > 0) {
date.QuadPart -= adjust.QuadPart;
if ((uint64_t)((date.QuadPart / 10000000) * 1000) < olderThan) {
- Utils::ztsnprintf(tmp, sizeof(tmp), "%s\\%s", path, ffd.cFileName);
+ ztsnprintf(tmp, sizeof(tmp), "%s\\%s", path, ffd.cFileName);
if (DeleteFileA(tmp))
++cleaned;
}
@@ -157,7 +174,7 @@ long OSUtils::cleanDirectory(const char *path,const uint64_t olderThan)
break;
if (dptr) {
if ((strcmp(dptr->d_name,"."))&&(strcmp(dptr->d_name,".."))&&(dptr->d_type == DT_REG)) {
- Utils::ztsnprintf(tmp,sizeof(tmp),"%s/%s",path,dptr->d_name);
+ ztsnprintf(tmp,sizeof(tmp),"%s/%s",path,dptr->d_name);
if (stat(tmp,&st) == 0) {
uint64_t mt = (uint64_t)(st.st_mtime);
if ((mt > 0)&&((mt * 1000) < olderThan)) {
@@ -464,7 +481,7 @@ std::string OSUtils::jsonString(const nlohmann::json &jv,const char *dfl)
return jv;
} else if (jv.is_number()) {
char tmp[64];
- Utils::ztsnprintf(tmp,sizeof(tmp),"%llu",(uint64_t)jv);
+ ztsnprintf(tmp,sizeof(tmp),"%llu",(uint64_t)jv);
return tmp;
} else if (jv.is_boolean()) {
return ((bool)jv ? std::string("1") : std::string("0"));
@@ -477,9 +494,10 @@ std::string OSUtils::jsonBinFromHex(const nlohmann::json &jv)
{
std::string s(jsonString(jv,""));
if (s.length() > 0) {
- char *buf = new char[(s.length() / 2) + 1];
+ unsigned int buflen = (s.length() / 2) + 1;
+ char *buf = new char[buflen];
try {
- unsigned int l = Utils::unhex(s,buf,(unsigned int)s.length());
+ unsigned int l = Utils::unhex(s.c_str(),buf,buflen);
std::string b(buf,l);
delete [] buf;
return b;
diff --git a/osdep/OSUtils.hpp b/osdep/OSUtils.hpp
index dff7df86..d6f32822 100644
--- a/osdep/OSUtils.hpp
+++ b/osdep/OSUtils.hpp
@@ -33,7 +33,6 @@
#include <string.h>
#include <time.h>
-#include <string>
#include <stdexcept>
#include <vector>
#include <map>
@@ -66,6 +65,20 @@ namespace ZeroTier {
class OSUtils
{
public:
+ /**
+ * 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,...);
+
#ifdef __UNIX_LIKE__
/**
* Close STDOUT_FILENO and STDERR_FILENO and replace them with output to given path
diff --git a/osdep/OSXEthernetTap.cpp b/osdep/OSXEthernetTap.cpp
index e082408e..b43d34c0 100644
--- a/osdep/OSXEthernetTap.cpp
+++ b/osdep/OSXEthernetTap.cpp
@@ -336,7 +336,7 @@ OSXEthernetTap::OSXEthernetTap(
char devpath[64],ethaddr[64],mtustr[32],metstr[32],nwids[32];
struct stat stattmp;
- Utils::ztsnprintf(nwids,sizeof(nwids),"%.16llx",nwid);
+ OSUtils::ztsnprintf(nwids,sizeof(nwids),"%.16llx",nwid);
Mutex::Lock _gl(globalTapCreateLock);
@@ -391,13 +391,13 @@ OSXEthernetTap::OSXEthernetTap(
// Open the first unused tap device if we didn't recall a previous one.
if (!recalledDevice) {
for(int i=0;i<64;++i) {
- Utils::ztsnprintf(devpath,sizeof(devpath),"/dev/zt%d",i);
+ OSUtils::ztsnprintf(devpath,sizeof(devpath),"/dev/zt%d",i);
if (stat(devpath,&stattmp))
throw std::runtime_error("no more TAP devices available");
_fd = ::open(devpath,O_RDWR);
if (_fd > 0) {
char foo[16];
- Utils::ztsnprintf(foo,sizeof(foo),"zt%d",i);
+ OSUtils::ztsnprintf(foo,sizeof(foo),"zt%d",i);
_dev = foo;
break;
}
@@ -413,9 +413,9 @@ OSXEthernetTap::OSXEthernetTap(
}
// Configure MAC address and MTU, bring interface up
- Utils::ztsnprintf(ethaddr,sizeof(ethaddr),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(int)mac[0],(int)mac[1],(int)mac[2],(int)mac[3],(int)mac[4],(int)mac[5]);
- Utils::ztsnprintf(mtustr,sizeof(mtustr),"%u",_mtu);
- Utils::ztsnprintf(metstr,sizeof(metstr),"%u",_metric);
+ OSUtils::ztsnprintf(ethaddr,sizeof(ethaddr),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(int)mac[0],(int)mac[1],(int)mac[2],(int)mac[3],(int)mac[4],(int)mac[5]);
+ OSUtils::ztsnprintf(mtustr,sizeof(mtustr),"%u",_mtu);
+ OSUtils::ztsnprintf(metstr,sizeof(metstr),"%u",_metric);
long cpid = (long)vfork();
if (cpid == 0) {
::execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),"lladdr",ethaddr,"mtu",mtustr,"metric",metstr,"up",(const char *)0);
@@ -499,7 +499,8 @@ bool OSXEthernetTap::addIp(const InetAddress &ip)
long cpid = (long)vfork();
if (cpid == 0) {
- ::execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),(ip.ss_family == AF_INET6) ? "inet6" : "inet",ip.toString().c_str(),"alias",(const char *)0);
+ char tmp[128];
+ ::execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),(ip.ss_family == AF_INET6) ? "inet6" : "inet",ip.toString(tmp),"alias",(const char *)0);
::_exit(-1);
} else if (cpid > 0) {
int exitcode = -1;
@@ -519,7 +520,8 @@ bool OSXEthernetTap::removeIp(const InetAddress &ip)
if (*i == ip) {
long cpid = (long)vfork();
if (cpid == 0) {
- execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),(ip.ss_family == AF_INET6) ? "inet6" : "inet",ip.toIpString().c_str(),"-alias",(const char *)0);
+ char tmp[128];
+ execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),(ip.ss_family == AF_INET6) ? "inet6" : "inet",ip.toIpString(tmp),"-alias",(const char *)0);
_exit(-1);
} else if (cpid > 0) {
int exitcode = -1;
@@ -636,7 +638,7 @@ void OSXEthernetTap::setMtu(unsigned int mtu)
long cpid = (long)vfork();
if (cpid == 0) {
char tmp[64];
- Utils::ztsnprintf(tmp,sizeof(tmp),"%u",mtu);
+ OSUtils::ztsnprintf(tmp,sizeof(tmp),"%u",mtu);
execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),"mtu",tmp,(const char *)0);
_exit(-1);
} else if (cpid > 0) {
diff --git a/osdep/PortMapper.cpp b/osdep/PortMapper.cpp
index df868e7a..b1990486 100644
--- a/osdep/PortMapper.cpp
+++ b/osdep/PortMapper.cpp
@@ -205,7 +205,7 @@ public:
memset(externalip,0,sizeof(externalip));
memset(&urls,0,sizeof(urls));
memset(&data,0,sizeof(data));
- Utils::ztsnprintf(inport,sizeof(inport),"%d",localPort);
+ OSUtils::ztsnprintf(inport,sizeof(inport),"%d",localPort);
if ((UPNP_GetValidIGD(devlist,&urls,&data,lanaddr,sizeof(lanaddr)))&&(lanaddr[0])) {
#ifdef ZT_PORTMAPPER_TRACE
@@ -220,7 +220,7 @@ public:
int tryPort = (int)localPort + tries;
if (tryPort >= 65535)
tryPort = (tryPort - 65535) + 1025;
- Utils::ztsnprintf(outport,sizeof(outport),"%u",tryPort);
+ OSUtils::ztsnprintf(outport,sizeof(outport),"%u",tryPort);
// First check and see if this port is already mapped to the
// same unique name. If so, keep this mapping and don't try
diff --git a/osdep/WindowsEthernetTap.cpp b/osdep/WindowsEthernetTap.cpp
index b96ad791..5344268f 100644
--- a/osdep/WindowsEthernetTap.cpp
+++ b/osdep/WindowsEthernetTap.cpp
@@ -484,7 +484,7 @@ WindowsEthernetTap::WindowsEthernetTap(
char tag[24];
// We "tag" registry entries with the network ID to identify persistent devices
- Utils::ztsnprintf(tag,sizeof(tag),"%.16llx",(unsigned long long)nwid);
+ OSUtils::ztsnprintf(tag,sizeof(tag),"%.16llx",(unsigned long long)nwid);
Mutex::Lock _l(_systemTapInitLock);
@@ -601,10 +601,10 @@ WindowsEthernetTap::WindowsEthernetTap(
if (_netCfgInstanceId.length() > 0) {
char tmps[64];
- unsigned int tmpsl = Utils::ztsnprintf(tmps,sizeof(tmps),"%.2X-%.2X-%.2X-%.2X-%.2X-%.2X",(unsigned int)mac[0],(unsigned int)mac[1],(unsigned int)mac[2],(unsigned int)mac[3],(unsigned int)mac[4],(unsigned int)mac[5]) + 1;
+ unsigned int tmpsl = OSUtils::ztsnprintf(tmps,sizeof(tmps),"%.2X-%.2X-%.2X-%.2X-%.2X-%.2X",(unsigned int)mac[0],(unsigned int)mac[1],(unsigned int)mac[2],(unsigned int)mac[3],(unsigned int)mac[4],(unsigned int)mac[5]) + 1;
RegSetKeyValueA(nwAdapters,_mySubkeyName.c_str(),"NetworkAddress",REG_SZ,tmps,tmpsl);
RegSetKeyValueA(nwAdapters,_mySubkeyName.c_str(),"MAC",REG_SZ,tmps,tmpsl);
- tmpsl = Utils::ztsnprintf(tmps, sizeof(tmps), "%d", mtu);
+ tmpsl = OSUtils::ztsnprintf(tmps, sizeof(tmps), "%d", mtu);
RegSetKeyValueA(nwAdapters,_mySubkeyName.c_str(),"MTU",REG_SZ,tmps,tmpsl);
DWORD tmp = 0;
@@ -879,7 +879,7 @@ void WindowsEthernetTap::setMtu(unsigned int mtu)
HKEY nwAdapters;
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}", 0, KEY_READ | KEY_WRITE, &nwAdapters) == ERROR_SUCCESS) {
char tmps[64];
- unsigned int tmpsl = Utils::ztsnprintf(tmps, sizeof(tmps), "%d", mtu);
+ unsigned int tmpsl = OSUtils::ztsnprintf(tmps, sizeof(tmps), "%d", mtu);
RegSetKeyValueA(nwAdapters, _mySubkeyName.c_str(), "MTU", REG_SZ, tmps, tmpsl);
RegCloseKey(nwAdapters);
}
@@ -902,7 +902,7 @@ void WindowsEthernetTap::threadMain()
HANDLE wait4[3];
OVERLAPPED tapOvlRead,tapOvlWrite;
- Utils::ztsnprintf(tapPath,sizeof(tapPath),"\\\\.\\Global\\%s.tap",_netCfgInstanceId.c_str());
+ OSUtils::ztsnprintf(tapPath,sizeof(tapPath),"\\\\.\\Global\\%s.tap",_netCfgInstanceId.c_str());
try {
while (_run) {
diff --git a/selftest.cpp b/selftest.cpp
index ff171aa3..e6705700 100644
--- a/selftest.cpp
+++ b/selftest.cpp
@@ -153,10 +153,11 @@ static int testCrypto()
{
static unsigned char buf1[16384];
static unsigned char buf2[sizeof(buf1)],buf3[sizeof(buf1)];
+ static char hexbuf[1024];
for(int i=0;i<3;++i) {
Utils::getSecureRandom(buf1,64);
- std::cout << "[crypto] getSecureRandom: " << Utils::hex(buf1,64) << std::endl;
+ std::cout << "[crypto] getSecureRandom: " << Utils::hex(buf1,64,hexbuf) << std::endl;
}
std::cout << "[crypto] Testing Salsa20... "; std::cout.flush();
@@ -213,7 +214,7 @@ static int testCrypto()
}
uint64_t end = OSUtils::now();
SHA512::hash(buf1,bb,1234567);
- std::cout << ((bytes / 1048576.0) / ((long double)(end - start) / 1024.0)) << " MiB/second (" << Utils::hex(buf1,16) << ')' << std::endl;
+ std::cout << ((bytes / 1048576.0) / ((long double)(end - start) / 1024.0)) << " MiB/second (" << Utils::hex(buf1,16,hexbuf) << ')' << std::endl;
::free((void *)bb);
}
@@ -265,7 +266,7 @@ static int testCrypto()
}
uint64_t end = OSUtils::now();
SHA512::hash(buf1,bb,1234567);
- std::cout << ((bytes / 1048576.0) / ((long double)(end - start) / 1024.0)) << " MiB/second (" << Utils::hex(buf1,16) << ')' << std::endl;
+ std::cout << ((bytes / 1048576.0) / ((long double)(end - start) / 1024.0)) << " MiB/second (" << Utils::hex(buf1,16,hexbuf) << ')' << std::endl;
::free((void *)bb);
}
@@ -427,6 +428,7 @@ static int testIdentity()
{
Identity id;
Buffer<512> buf;
+ char buf2[1024];
std::cout << "[identity] Validate known-good identity... "; std::cout.flush();
if (!id.fromString(KNOWN_GOOD_IDENTITY)) {
@@ -459,7 +461,7 @@ static int testIdentity()
uint64_t genstart = OSUtils::now();
id.generate();
uint64_t genend = OSUtils::now();
- std::cout << "(took " << (genend - genstart) << "ms): " << id.toString(true) << std::endl;
+ std::cout << "(took " << (genend - genstart) << "ms): " << id.toString(true,buf2) << std::endl;
std::cout << "[identity] Locally validate identity: ";
if (id.locallyValidate()) {
std::cout << "PASS" << std::endl;
@@ -499,7 +501,7 @@ static int testIdentity()
{
Identity id2;
- id2.fromString(id.toString(true).c_str());
+ id2.fromString(id.toString(true,buf2));
std::cout << "[identity] Serialize and deserialize (ASCII w/private): ";
if ((id == id2)&&(id2.locallyValidate())) {
std::cout << "PASS" << std::endl;
@@ -511,7 +513,7 @@ static int testIdentity()
{
Identity id2;
- id2.fromString(id.toString(false).c_str());
+ id2.fromString(id.toString(false,buf2));
std::cout << "[identity] Serialize and deserialize (ASCII no private): ";
if ((id == id2)&&(id2.locallyValidate())) {
std::cout << "PASS" << std::endl;
@@ -526,16 +528,18 @@ static int testIdentity()
static int testCertificate()
{
+ char buf[4096];
+
Identity authority;
std::cout << "[certificate] Generating identity to act as authority... "; std::cout.flush();
authority.generate();
- std::cout << authority.address().toString() << std::endl;
+ std::cout << authority.address().toString(buf) << std::endl;
Identity idA,idB;
std::cout << "[certificate] Generating identities A and B... "; std::cout.flush();
idA.generate();
idB.generate();
- std::cout << idA.address().toString() << ", " << idB.address().toString() << std::endl;
+ std::cout << idA.address().toString(buf) << ", " << idB.address().toString(buf) << std::endl;
std::cout << "[certificate] Generating certificates A and B...";
CertificateOfMembership cA(10000,100,1,idA.address());
@@ -641,6 +645,8 @@ static void _testExcept(int &depth)
static int testOther()
{
+ char buf[1024];
+
std::cout << "[other] Testing C++ exceptions... "; std::cout.flush();
int depth = 0;
try {
@@ -657,6 +663,13 @@ static int testOther()
return -1;
}
+ std::cout << "[other] Testing InetAddress encode/decode..."; std::cout.flush();
+ std::cout << " " << InetAddress("127.0.0.1/9993").toString(buf);
+ std::cout << " " << InetAddress("feed:dead:babe:dead:beef:f00d:1234:5678/12345").toString(buf);
+ std::cout << " " << InetAddress("0/9993").toString(buf);
+ std::cout << " " << InetAddress("").toString(buf);
+ std::cout << std::endl;
+
#if 0
std::cout << "[other] Testing Hashtable... "; std::cout.flush();
{
@@ -831,7 +844,7 @@ static int testOther()
memset(key, 0, sizeof(key));
memset(value, 0, sizeof(value));
for(unsigned int q=0;q<32;++q) {
- Utils::ztsnprintf(key[q],16,"%.8lx",(unsigned long)(rand() % 1000) + (q * 1000));
+ OSUtils::ztsnprintf(key[q],16,"%.8lx",(unsigned long)(rand() % 1000) + (q * 1000));
int r = rand() % 128;
for(int x=0;x<r;++x)
value[q][x] = ("0123456789\0\t\r\n= ")[rand() % 16];
diff --git a/service/OneService.cpp b/service/OneService.cpp
index 6c2c9a8b..d6e3e4df 100644
--- a/service/OneService.cpp
+++ b/service/OneService.cpp
@@ -202,10 +202,10 @@ static void _networkToJson(nlohmann::json &nj,const ZT_VirtualNetworkConfig *nc,
case ZT_NETWORK_TYPE_PUBLIC: ntype = "PUBLIC"; break;
}
- Utils::ztsnprintf(tmp,sizeof(tmp),"%.16llx",nc->nwid);
+ OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.16llx",nc->nwid);
nj["id"] = tmp;
nj["nwid"] = tmp;
- Utils::ztsnprintf(tmp,sizeof(tmp),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(unsigned int)((nc->mac >> 40) & 0xff),(unsigned int)((nc->mac >> 32) & 0xff),(unsigned int)((nc->mac >> 24) & 0xff),(unsigned int)((nc->mac >> 16) & 0xff),(unsigned int)((nc->mac >> 8) & 0xff),(unsigned int)(nc->mac & 0xff));
+ OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(unsigned int)((nc->mac >> 40) & 0xff),(unsigned int)((nc->mac >> 32) & 0xff),(unsigned int)((nc->mac >> 24) & 0xff),(unsigned int)((nc->mac >> 16) & 0xff),(unsigned int)((nc->mac >> 8) & 0xff),(unsigned int)(nc->mac & 0xff));
nj["mac"] = tmp;
nj["name"] = nc->name;
nj["status"] = nstatus;
@@ -223,16 +223,16 @@ static void _networkToJson(nlohmann::json &nj,const ZT_VirtualNetworkConfig *nc,
nlohmann::json aa = nlohmann::json::array();
for(unsigned int i=0;i<nc->assignedAddressCount;++i) {
- aa.push_back(reinterpret_cast<const InetAddress *>(&(nc->assignedAddresses[i]))->toString());
+ aa.push_back(reinterpret_cast<const InetAddress *>(&(nc->assignedAddresses[i]))->toString(tmp));
}
nj["assignedAddresses"] = aa;
nlohmann::json ra = nlohmann::json::array();
for(unsigned int i=0;i<nc->routeCount;++i) {
nlohmann::json rj;
- rj["target"] = reinterpret_cast<const InetAddress *>(&(nc->routes[i].target))->toString();
+ rj["target"] = reinterpret_cast<const InetAddress *>(&(nc->routes[i].target))->toString(tmp);
if (nc->routes[i].via.ss_family == nc->routes[i].target.ss_family)
- rj["via"] = reinterpret_cast<const InetAddress *>(&(nc->routes[i].via))->toIpString();
+ rj["via"] = reinterpret_cast<const InetAddress *>(&(nc->routes[i].via))->toIpString(tmp);
else rj["via"] = nlohmann::json();
rj["flags"] = (int)nc->routes[i].flags;
rj["metric"] = (int)nc->routes[i].metric;
@@ -252,12 +252,12 @@ static void _peerToJson(nlohmann::json &pj,const ZT_Peer *peer)
case ZT_PEER_ROLE_PLANET: prole = "PLANET"; break;
}
- Utils::ztsnprintf(tmp,sizeof(tmp),"%.10llx",peer->address);
+ OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.10llx",peer->address);
pj["address"] = tmp;
pj["versionMajor"] = peer->versionMajor;
pj["versionMinor"] = peer->versionMinor;
pj["versionRev"] = peer->versionRev;
- Utils::ztsnprintf(tmp,sizeof(tmp),"%d.%d.%d",peer->versionMajor,peer->versionMinor,peer->versionRev);
+ OSUtils::ztsnprintf(tmp,sizeof(tmp),"%d.%d.%d",peer->versionMajor,peer->versionMinor,peer->versionRev);
pj["version"] = tmp;
pj["latency"] = peer->latency;
pj["role"] = prole;
@@ -265,7 +265,7 @@ static void _peerToJson(nlohmann::json &pj,const ZT_Peer *peer)
nlohmann::json pa = nlohmann::json::array();
for(unsigned int i=0;i<peer->pathCount;++i) {
nlohmann::json j;
- j["address"] = reinterpret_cast<const InetAddress *>(&(peer->paths[i].address))->toString();
+ j["address"] = reinterpret_cast<const InetAddress *>(&(peer->paths[i].address))->toString(tmp);
j["lastSend"] = peer->paths[i].lastSend;
j["lastReceive"] = peer->paths[i].lastReceive;
j["trustedPathId"] = peer->paths[i].trustedPathId;
@@ -280,19 +280,19 @@ static void _peerToJson(nlohmann::json &pj,const ZT_Peer *peer)
static void _moonToJson(nlohmann::json &mj,const World &world)
{
- char tmp[64];
- Utils::ztsnprintf(tmp,sizeof(tmp),"%.16llx",world.id());
+ char tmp[4096];
+ OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.16llx",world.id());
mj["id"] = tmp;
mj["timestamp"] = world.timestamp();
- mj["signature"] = Utils::hex(world.signature().data,(unsigned int)world.signature().size());
- mj["updatesMustBeSignedBy"] = Utils::hex(world.updatesMustBeSignedBy().data,(unsigned int)world.updatesMustBeSignedBy().size());
+ mj["signature"] = Utils::hex(world.signature().data,(unsigned int)world.signature().size(),tmp);
+ mj["updatesMustBeSignedBy"] = Utils::hex(world.updatesMustBeSignedBy().data,(unsigned int)world.updatesMustBeSignedBy().size(),tmp);
nlohmann::json ra = nlohmann::json::array();
for(std::vector<World::Root>::const_iterator r(world.roots().begin());r!=world.roots().end();++r) {
nlohmann::json rj;
- rj["identity"] = r->identity.toString(false);
+ rj["identity"] = r->identity.toString(false,tmp);
nlohmann::json eps = nlohmann::json::array();
for(std::vector<InetAddress>::const_iterator a(r->stableEndpoints.begin());a!=r->stableEndpoints.end();++a)
- eps.push_back(a->toString());
+ eps.push_back(a->toString(tmp));
rj["stableEndpoints"] = eps;
ra.push_back(rj);
}
@@ -613,7 +613,7 @@ public:
json &physical = _localConfig["physical"];
if (physical.is_object()) {
for(json::iterator phy(physical.begin());phy!=physical.end();++phy) {
- InetAddress net(OSUtils::jsonString(phy.key(),""));
+ InetAddress net(OSUtils::jsonString(phy.key(),"").c_str());
if (net) {
if (phy.value().is_object()) {
uint64_t tpid;
@@ -674,7 +674,7 @@ public:
// Save primary port to a file so CLIs and GUIs can learn it easily
char portstr[64];
- Utils::ztsnprintf(portstr,sizeof(portstr),"%u",_ports[0]);
+ OSUtils::ztsnprintf(portstr,sizeof(portstr),"%u",_ports[0]);
OSUtils::writeFile((_homePath + ZT_PATH_SEPARATOR_S "zerotier-one.port").c_str(),std::string(portstr));
// Attempt to bind to a secondary port chosen from our ZeroTier address.
@@ -712,7 +712,7 @@ public:
}
if (_ports[2]) {
char uniqueName[64];
- Utils::ztsnprintf(uniqueName,sizeof(uniqueName),"ZeroTier/%.10llx@%u",_node->address(),_ports[2]);
+ OSUtils::ztsnprintf(uniqueName,sizeof(uniqueName),"ZeroTier/%.10llx@%u",_node->address(),_ports[2]);
_portMapper = new PortMapper(_ports[2],uniqueName);
}
}
@@ -982,7 +982,7 @@ public:
n->second.settings = settings;
char nlcpath[4096];
- Utils::ztsnprintf(nlcpath,sizeof(nlcpath),"%s" ZT_PATH_SEPARATOR_S "%.16llx.local.conf",_networksPath.c_str(),nwid);
+ OSUtils::ztsnprintf(nlcpath,sizeof(nlcpath),"%s" ZT_PATH_SEPARATOR_S "%.16llx.local.conf",_networksPath.c_str(),nwid);
FILE *out = fopen(nlcpath,"w");
if (out) {
fprintf(out,"allowManaged=%d\n",(int)n->second.settings.allowManaged);
@@ -1101,7 +1101,7 @@ public:
ZT_NodeStatus status;
_node->status(&status);
- Utils::ztsnprintf(tmp,sizeof(tmp),"%.10llx",status.address);
+ OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.10llx",status.address);
res["address"] = tmp;
res["publicIdentity"] = status.publicIdentity;
res["online"] = (bool)(status.online != 0);
@@ -1110,7 +1110,7 @@ public:
res["versionMinor"] = ZEROTIER_ONE_VERSION_MINOR;
res["versionRev"] = ZEROTIER_ONE_VERSION_REVISION;
res["versionBuild"] = ZEROTIER_ONE_VERSION_BUILD;
- Utils::ztsnprintf(tmp,sizeof(tmp),"%d.%d.%d",ZEROTIER_ONE_VERSION_MAJOR,ZEROTIER_ONE_VERSION_MINOR,ZEROTIER_ONE_VERSION_REVISION);
+ OSUtils::ztsnprintf(tmp,sizeof(tmp),"%d.%d.%d",ZEROTIER_ONE_VERSION_MAJOR,ZEROTIER_ONE_VERSION_MINOR,ZEROTIER_ONE_VERSION_REVISION);
res["version"] = tmp;
res["clock"] = OSUtils::now();
@@ -1257,7 +1257,7 @@ public:
if ((scode != 200)&&(seed != 0)) {
char tmp[64];
- Utils::ztsnprintf(tmp,sizeof(tmp),"%.16llx",id);
+ OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.16llx",id);
res["id"] = tmp;
res["roots"] = json::array();
res["timestamp"] = 0;
@@ -1395,7 +1395,7 @@ public:
json &tryAddrs = v.value()["try"];
if (tryAddrs.is_array()) {
for(unsigned long i=0;i<tryAddrs.size();++i) {
- const InetAddress ip(OSUtils::jsonString(tryAddrs[i],""));
+ const InetAddress ip(OSUtils::jsonString(tryAddrs[i],"").c_str());
if (ip.ss_family == AF_INET)
v4h.push_back(ip);
else if (ip.ss_family == AF_INET6)
@@ -1405,7 +1405,7 @@ public:
json &blAddrs = v.value()["blacklist"];
if (blAddrs.is_array()) {
for(unsigned long i=0;i<blAddrs.size();++i) {
- const InetAddress ip(OSUtils::jsonString(tryAddrs[i],""));
+ const InetAddress ip(OSUtils::jsonString(tryAddrs[i],"").c_str());
if (ip.ss_family == AF_INET)
v4b.push_back(ip);
else if (ip.ss_family == AF_INET6)
@@ -1427,7 +1427,7 @@ public:
json &physical = lc["physical"];
if (physical.is_object()) {
for(json::iterator phy(physical.begin());phy!=physical.end();++phy) {
- const InetAddress net(OSUtils::jsonString(phy.key(),""));
+ const InetAddress net(OSUtils::jsonString(phy.key(),"").c_str());
if ((net)&&(net.netmaskBits() > 0)) {
if (phy.value().is_object()) {
if (OSUtils::jsonBool(phy.value()["blacklist"],false)) {
@@ -1477,7 +1477,7 @@ public:
json &amf = settings["allowManagementFrom"];
if (amf.is_array()) {
for(unsigned long i=0;i<amf.size();++i) {
- const InetAddress nw(OSUtils::jsonString(amf[i],""));
+ const InetAddress nw(OSUtils::jsonString(amf[i],"").c_str());
if (nw)
_allowManagementFrom.push_back(nw);
}
@@ -1491,7 +1491,7 @@ public:
std::string h = controllerDbHttpHost;
_controllerDbPath.append(h);
char dbp[128];
- Utils::ztsnprintf(dbp,sizeof(dbp),"%d",(int)controllerDbHttpPort);
+ OSUtils::ztsnprintf(dbp,sizeof(dbp),"%d",(int)controllerDbHttpPort);
_controllerDbPath.push_back(':');
_controllerDbPath.append(dbp);
if (controllerDbHttpPath.is_string()) {
@@ -1550,6 +1550,8 @@ public:
// Apply or update managed IPs for a configured network (be sure n.tap exists)
void syncManagedStuff(NetworkState &n,bool syncIps,bool syncRoutes)
{
+ char ipbuf[64];
+
// assumes _nets_m is locked
if (syncIps) {
std::vector<InetAddress> newManagedIps;
@@ -1565,7 +1567,7 @@ public:
for(std::vector<InetAddress>::iterator ip(n.managedIps.begin());ip!=n.managedIps.end();++ip) {
if (std::find(newManagedIps.begin(),newManagedIps.end(),*ip) == newManagedIps.end()) {
if (!n.tap->removeIp(*ip))
- fprintf(stderr,"ERROR: unable to remove ip address %s" ZT_EOL_S, ip->toString().c_str());
+ fprintf(stderr,"ERROR: unable to remove ip address %s" ZT_EOL_S, ip->toString(ipbuf));
}
}
#ifdef __SYNOLOGY__
@@ -1575,7 +1577,7 @@ public:
for(std::vector<InetAddress>::iterator ip(newManagedIps.begin());ip!=newManagedIps.end();++ip) {
if (std::find(n.managedIps.begin(),n.managedIps.end(),*ip) == n.managedIps.end()) {
if (!n.tap->addIp(*ip))
- fprintf(stderr,"ERROR: unable to add ip address %s" ZT_EOL_S, ip->toString().c_str());
+ fprintf(stderr,"ERROR: unable to add ip address %s" ZT_EOL_S, ip->toString(ipbuf));
}
}
#endif
@@ -1585,7 +1587,7 @@ public:
if (syncRoutes) {
char tapdev[64];
#ifdef __WINDOWS__
- Utils::ztsnprintf(tapdev,sizeof(tapdev),"%.16llx",(unsigned long long)n.tap->luid().Value);
+ OSUtils::ztsnprintf(tapdev,sizeof(tapdev),"%.16llx",(unsigned long long)n.tap->luid().Value);
#else
Utils::scopy(tapdev,sizeof(tapdev),n.tap->deviceName().c_str());
#endif
@@ -1670,7 +1672,7 @@ public:
&_nextBackgroundTaskDeadline);
if (ZT_ResultCode_isFatal(rc)) {
char tmp[256];
- Utils::ztsnprintf(tmp,sizeof(tmp),"fatal error code from processWirePacket: %d",(int)rc);
+ OSUtils::ztsnprintf(tmp,sizeof(tmp),"fatal error code from processWirePacket: %d",(int)rc);
Mutex::Lock _l(_termReason_m);
_termReason = ONE_UNRECOVERABLE_ERROR;
_fatalErrorMessage = tmp;
@@ -1851,7 +1853,7 @@ public:
&_nextBackgroundTaskDeadline);
if (ZT_ResultCode_isFatal(rc)) {
char tmp[256];
- Utils::ztsnprintf(tmp,sizeof(tmp),"fatal error code from processWirePacket: %d",(int)rc);
+ OSUtils::ztsnprintf(tmp,sizeof(tmp),"fatal error code from processWirePacket: %d",(int)rc);
Mutex::Lock _l(_termReason_m);
_termReason = ONE_UNRECOVERABLE_ERROR;
_fatalErrorMessage = tmp;
@@ -1919,7 +1921,7 @@ public:
if (!n.tap) {
try {
char friendlyName[128];
- Utils::ztsnprintf(friendlyName,sizeof(friendlyName),"ZeroTier One [%.16llx]",nwid);
+ OSUtils::ztsnprintf(friendlyName,sizeof(friendlyName),"ZeroTier One [%.16llx]",nwid);
n.tap = new EthernetTap(
_homePath.c_str(),
@@ -1933,7 +1935,7 @@ public:
*nuptr = (void *)&n;
char nlcpath[256];
- Utils::ztsnprintf(nlcpath,sizeof(nlcpath),"%s" ZT_PATH_SEPARATOR_S "networks.d" ZT_PATH_SEPARATOR_S "%.16llx.local.conf",_homePath.c_str(),nwid);
+ OSUtils::ztsnprintf(nlcpath,sizeof(nlcpath),"%s" ZT_PATH_SEPARATOR_S "networks.d" ZT_PATH_SEPARATOR_S "%.16llx.local.conf",_homePath.c_str(),nwid);
std::string nlcbuf;
if (OSUtils::readFile(nlcpath,nlcbuf)) {
Dictionary<4096> nc;
@@ -1954,7 +1956,7 @@ public:
while (true) {
size_t nextPos = addresses.find(',', pos);
std::string address = addresses.substr(pos, (nextPos == std::string::npos ? addresses.size() : nextPos) - pos);
- n.settings.allowManagedWhitelist.push_back(InetAddress(address));
+ n.settings.allowManagedWhitelist.push_back(InetAddress(address.c_str()));
if (nextPos == std::string::npos) break;
pos = nextPos + 1;
}
@@ -2019,7 +2021,7 @@ public:
#endif
if (op == ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY) {
char nlcpath[256];
- Utils::ztsnprintf(nlcpath,sizeof(nlcpath),"%s" ZT_PATH_SEPARATOR_S "networks.d" ZT_PATH_SEPARATOR_S "%.16llx.local.conf",_homePath.c_str(),nwid);
+ OSUtils::ztsnprintf(nlcpath,sizeof(nlcpath),"%s" ZT_PATH_SEPARATOR_S "networks.d" ZT_PATH_SEPARATOR_S "%.16llx.local.conf",_homePath.c_str(),nwid);
OSUtils::rm(nlcpath);
}
} else {
@@ -2068,20 +2070,20 @@ public:
switch(type) {
case ZT_STATE_OBJECT_IDENTITY_PUBLIC:
- Utils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "identity.public",_homePath.c_str());
+ OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "identity.public",_homePath.c_str());
break;
case ZT_STATE_OBJECT_IDENTITY_SECRET:
- Utils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "identity.secret",_homePath.c_str());
+ OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "identity.secret",_homePath.c_str());
secure = true;
break;
case ZT_STATE_OBJECT_PLANET:
- Utils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "planet",_homePath.c_str());
+ OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "planet",_homePath.c_str());
break;
case ZT_STATE_OBJECT_MOON:
- Utils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "moons.d/%.16llx.moon",_homePath.c_str(),(unsigned long long)id[0]);
+ OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "moons.d/%.16llx.moon",_homePath.c_str(),(unsigned long long)id[0]);
break;
case ZT_STATE_OBJECT_NETWORK_CONFIG:
- Utils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "networks.d/%.16llx.conf",_homePath.c_str(),(unsigned long long)id[0]);
+ OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "networks.d/%.16llx.conf",_homePath.c_str(),(unsigned long long)id[0]);
secure = true;
break;
default:
@@ -2121,19 +2123,19 @@ public:
char p[4096];
switch(type) {
case ZT_STATE_OBJECT_IDENTITY_PUBLIC:
- Utils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "identity.public",_homePath.c_str());
+ OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "identity.public",_homePath.c_str());
break;
case ZT_STATE_OBJECT_IDENTITY_SECRET:
- Utils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "identity.secret",_homePath.c_str());
+ OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "identity.secret",_homePath.c_str());
break;
case ZT_STATE_OBJECT_NETWORK_CONFIG:
- Utils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "networks.d/%.16llx.conf",_homePath.c_str(),(unsigned long long)id);
+ OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "networks.d/%.16llx.conf",_homePath.c_str(),(unsigned long long)id);
break;
case ZT_STATE_OBJECT_PLANET:
- Utils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "planet",_homePath.c_str());
+ OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "planet",_homePath.c_str());
break;
case ZT_STATE_OBJECT_MOON:
- Utils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "moons.d/%.16llx.moon",_homePath.c_str(),(unsigned long long)id);
+ OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "moons.d/%.16llx.moon",_homePath.c_str(),(unsigned long long)id);
break;
default:
return -1;
@@ -2322,7 +2324,7 @@ public:
default: scodestr = "Error"; break;
}
- Utils::ztsnprintf(tmpn,sizeof(tmpn),"HTTP/1.1 %.3u %s\r\nCache-Control: no-cache\r\nPragma: no-cache\r\nContent-Type: %s\r\nContent-Length: %lu\r\nConnection: close\r\n\r\n",
+ OSUtils::ztsnprintf(tmpn,sizeof(tmpn),"HTTP/1.1 %.3u %s\r\nCache-Control: no-cache\r\nPragma: no-cache\r\nContent-Type: %s\r\nContent-Length: %lu\r\nConnection: close\r\n\r\n",
scode,
scodestr,
contentType.c_str(),
diff --git a/service/SoftwareUpdater.cpp b/service/SoftwareUpdater.cpp
index e0519827..b4bf03ec 100644
--- a/service/SoftwareUpdater.cpp
+++ b/service/SoftwareUpdater.cpp
@@ -284,7 +284,7 @@ bool SoftwareUpdater::check(const uint64_t now)
if ((now - _lastCheckTime) >= ZT_SOFTWARE_UPDATE_CHECK_PERIOD) {
_lastCheckTime = now;
char tmp[512];
- const unsigned int len = Utils::ztsnprintf(tmp,sizeof(tmp),
+ const unsigned int len = OSUtils::ztsnprintf(tmp,sizeof(tmp),
"%c{\"" ZT_SOFTWARE_UPDATE_JSON_VERSION_MAJOR "\":%d,"
"\"" ZT_SOFTWARE_UPDATE_JSON_VERSION_MINOR "\":%d,"
"\"" ZT_SOFTWARE_UPDATE_JSON_VERSION_REVISION "\":%d,"
@@ -321,7 +321,8 @@ bool SoftwareUpdater::check(const uint64_t now)
// (1) Check the hash itself to make sure the image is basically okay
uint8_t sha512[ZT_SHA512_DIGEST_LEN];
SHA512::hash(sha512,_download.data(),(unsigned int)_download.length());
- if (Utils::hex(sha512,ZT_SHA512_DIGEST_LEN) == OSUtils::jsonString(_latestMeta[ZT_SOFTWARE_UPDATE_JSON_UPDATE_HASH],"")) {
+ char hexbuf[(ZT_SHA512_DIGEST_LEN * 2) + 2];
+ if (OSUtils::jsonString(_latestMeta[ZT_SOFTWARE_UPDATE_JSON_UPDATE_HASH],"") == Utils::hex(sha512,ZT_SHA512_DIGEST_LEN,hexbuf)) {
// (2) Check signature by signing authority
const std::string sig(OSUtils::jsonBinFromHex(_latestMeta[ZT_SOFTWARE_UPDATE_JSON_UPDATE_SIGNATURE]));
if (Identity(ZT_SOFTWARE_UPDATE_SIGNING_AUTHORITY).verify(_download.data(),(unsigned int)_download.length(),sig.data(),(unsigned int)sig.length())) {