diff --git a/controller/EmbeddedNetworkController.cpp b/controller/EmbeddedNetworkController.cpp index 85c759e73..b57a37e81 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 acf23700d..97a217a11 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 98e328585..12c52a3ff 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 a5445e423..100253e10 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 0b000f136..6cbbfc0ec 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 ba77aa475..3b00b4c0c 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 79e17f4d8..5804b9f8a 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 17d7c72e6..f7585bdba 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 4cb9a4dc9..dd0550841 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 db50aeb13..52388d592 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 7cbec2e02..f56c675b9 100644 --- a/node/MulticastGroup.hpp +++ b/node/MulticastGroup.hpp @@ -29,8 +29,6 @@ #include <stdint.h> -#include <string> - #include "MAC.hpp" #include "InetAddress.hpp" @@ -94,16 +92,6 @@ public: return MulticastGroup(); } - /** - * @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 */ diff --git a/node/Network.cpp b/node/Network.cpp index bccc0397e..f2b6771b2 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 65101c3ad..e59299230 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 4b598f615..e28accee3 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 55491b064..40903f7c1 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 99afe25db..94b96d348 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 809bc7e78..e7bbdfae1 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 d2321e169..a3a4c3c38 100644 --- a/node/Utils.cpp +++ b/node/Utils.cpp @@ -55,6 +55,27 @@ namespace ZeroTier { const char Utils::HEXCHARS[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' }; +static unsigned long _Utils_itoa(unsigned long n,char *s) +{ + 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; +} +char *Utils::decimal(unsigned long n,char s[24]) +{ + if (n == 0) { + s[0] = '0'; + s[1] = (char)0; + return s; + } + s[_Utils_itoa(n,s)] = (char)0; + return s; +} + // 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) { @@ -64,82 +85,6 @@ static void _Utils_doBurn(volatile uint8_t *ptr,unsigned int len) 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) -{ - 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; -} - -std::string Utils::unhex(const char *hex,unsigned int maxlen) -{ - 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; - } - - return r; -} - -unsigned int Utils::unhex(const char *hex,unsigned int maxlen,void *buf,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; -} - void Utils::getSecureRandom(void *buf,unsigned int bytes) { static Mutex globalLock; @@ -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 212ef247e..5a5e9f396 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 @@ -232,20 +334,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 * diff --git a/one.cpp b/one.cpp index cbf091214..b1a19e8c0 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 f07f9e5a0..8e57d6057 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 3c556f44a..d6d0238c5 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 fc5199f1c..c8f9ef9d1 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 fca1c290d..3a0b8a7e8 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 06508e773..882b82550 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 dff7df868..d6f328228 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 e082408e3..b43d34c08 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 df868e7a6..b1990486d 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 b96ad791a..5344268f3 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 ff171aa3e..e67057000 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 6c2c9a8b9..d6e3e4dff 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 e05198270..b4bf03ec3 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())) {