summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--node/Address.hpp4
-rw-r--r--node/Demarc.cpp5
-rw-r--r--node/Demarc.hpp3
-rw-r--r--node/EthernetTap.cpp25
-rw-r--r--node/Filter.cpp16
-rw-r--r--node/InetAddress.cpp5
-rw-r--r--node/MAC.hpp5
-rw-r--r--node/MulticastGroup.hpp2
-rw-r--r--node/Network.cpp2
-rw-r--r--node/Network.hpp10
-rw-r--r--node/Node.cpp2
-rw-r--r--node/PacketDecoder.cpp4
-rw-r--r--node/Peer.hpp2
-rw-r--r--node/Utils.cpp20
-rw-r--r--node/Utils.hpp12
-rw-r--r--selftest.cpp27
16 files changed, 75 insertions, 69 deletions
diff --git a/node/Address.hpp b/node/Address.hpp
index 8baf9dbe..805c439d 100644
--- a/node/Address.hpp
+++ b/node/Address.hpp
@@ -32,7 +32,9 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
+
#include <string>
+
#include "Utils.hpp"
#include "MAC.hpp"
#include "Constants.hpp"
@@ -198,7 +200,7 @@ public:
inline std::string toString() const
{
char buf[16];
- sprintf(buf,"%.10llx",(unsigned long long)_a);
+ Utils::snprintf(buf,sizeof(buf),"%.10llx",(unsigned long long)_a);
return std::string(buf);
};
diff --git a/node/Demarc.cpp b/node/Demarc.cpp
index ddbed6c8..f4060dac 100644
--- a/node/Demarc.cpp
+++ b/node/Demarc.cpp
@@ -68,15 +68,14 @@ Demarc::~Demarc()
}
std::string Demarc::describe(Demarc::Port p)
- throw()
{
char buf[64];
switch ((DemarcPortType)(((uint64_t)p) >> 60)) {
case PORT_TYPE_UDP_SOCKET_V4:
- sprintf(buf,"udp/4/%d",(int)((uint64_t)p & 0xffff));
+ Utils::snprintf(buf,sizeof(buf),"udp/4/%d",(int)((uint64_t)p & 0xffff));
return std::string(buf);
case PORT_TYPE_UDP_SOCKET_V6:
- sprintf(buf,"udp/6/%d",(int)((uint64_t)p & 0xffff));
+ Utils::snprintf(buf,sizeof(buf),"udp/6/%d",(int)((uint64_t)p & 0xffff));
return std::string(buf);
case PORT_TYPE_LOCAL_ETHERNET:
return std::string("ethernet");
diff --git a/node/Demarc.hpp b/node/Demarc.hpp
index 670e5b0a..79db26d5 100644
--- a/node/Demarc.hpp
+++ b/node/Demarc.hpp
@@ -83,8 +83,7 @@ public:
* @param p Port
* @return Human-readable description of port
*/
- static std::string describe(Port p)
- throw();
+ static std::string describe(Port p);
/**
* @param p Port to check
diff --git a/node/EthernetTap.cpp b/node/EthernetTap.cpp
index 94ee8adb..226d0397 100644
--- a/node/EthernetTap.cpp
+++ b/node/EthernetTap.cpp
@@ -36,6 +36,7 @@
#include "RuntimeEnvironment.hpp"
#include "Utils.hpp"
#include "Mutex.hpp"
+#include "Utils.hpp"
// ff:ff:ff:ff:ff:ff with no ADI
static const ZeroTier::MulticastGroup _blindWildcardMulticastGroup(ZeroTier::MAC(0xff),0);
@@ -99,22 +100,22 @@ private:
inline void _findCmd(int id,const char *name)
{
char tmp[4096];
- sprintf(tmp,"/sbin/%s",name);
+ ZeroTier::Utils::snprintf(tmp,sizeof(tmp),"/sbin/%s",name);
if (ZeroTier::Utils::fileExists(tmp)) {
_paths[id] = tmp;
return;
}
- sprintf(tmp,"/usr/sbin/%s",name);
+ ZeroTier::Utils::snprintf(tmp,sizeof(tmp),"/usr/sbin/%s",name);
if (ZeroTier::Utils::fileExists(tmp)) {
_paths[id] = tmp;
return;
}
- sprintf(tmp,"/bin/%s",name);
+ ZeroTier::Utils::snprintf(tmp,sizeof(tmp),"/bin/%s",name);
if (ZeroTier::Utils::fileExists(tmp)) {
_paths[id] = tmp;
return;
}
- sprintf(tmp,"/usr/bin/%s",name);
+ ZeroTier::Utils::snprintf(tmp,sizeof(tmp),"/usr/bin/%s",name);
if (ZeroTier::Utils::fileExists(tmp)) {
_paths[id] = tmp;
return;
@@ -178,8 +179,8 @@ EthernetTap::EthernetTap(
int devno = 0;
struct stat sbuf;
do {
- sprintf(ifr.ifr_name,"zt%d",devno++);
- sprintf(procpath,"/proc/sys/net/ipv4/conf/%s",ifr.ifr_name);
+ Utils::snprintf(ifr.ifr_name,sizeof(ifr.ifr_name),"zt%d",devno++);
+ Utils::snprintf(procpath,sizeof(procpath),"/proc/sys/net/ipv4/conf/%s",ifr.ifr_name);
} while (stat(procpath,&sbuf) == 0);
}
@@ -292,12 +293,12 @@ EthernetTap::EthernetTap(
// Open the first available device (ones in use will fail with resource busy)
for(int i=0;i<256;++i) {
- sprintf(devpath,"/dev/zt%d",i);
+ Utils::snprintf(devpath,sizeof(devpath),"/dev/zt%d",i);
if (stat(devpath,&tmp))
throw std::runtime_error("no more TAP devices available");
_fd = ::open(devpath,O_RDWR);
if (_fd > 0) {
- sprintf(_dev,"zt%d",i);
+ Utils::snprintf(_dev,sizeof(_dev),"zt%d",i);
break;
}
}
@@ -316,8 +317,8 @@ EthernetTap::EthernetTap(
}
// Configure MAC address and MTU, bring interface up
- sprintf(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]);
- sprintf(mtustr,"%u",mtu);
+ Utils::snprintf(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::snprintf(mtustr,sizeof(mtustr),"%u",mtu);
long cpid;
if ((cpid = (long)vfork()) == 0) {
execl(ifconfig,ifconfig,_dev,"lladdr",ethaddr,"mtu",mtustr,"up",(const char *)0);
@@ -895,7 +896,7 @@ EthernetTap::EthernetTap(
// If we have a device, configure it
if (_myDeviceInstanceId.length() > 0) {
char tmps[4096];
- unsigned int tmpsl = sprintf_s(tmps,"%.2X-%.2X-%.2X-%.2X-%.2X-%.2X",(unsigned int)mac.data[0],(unsigned int)mac.data[1],(unsigned int)mac.data[2],(unsigned int)mac.data[3],(unsigned int)mac.data[4],(unsigned int)mac.data[5]) + 1;
+ unsigned int tmpsl = Utils::snprintf(tmps,sizeof(tmps),"%.2X-%.2X-%.2X-%.2X-%.2X-%.2X",(unsigned int)mac.data[0],(unsigned int)mac.data[1],(unsigned int)mac.data[2],(unsigned int)mac.data[3],(unsigned int)mac.data[4],(unsigned int)mac.data[5]) + 1;
RegSetKeyValueA(nwAdapters,mySubkeyName.c_str(),"NetworkAddress",REG_SZ,tmps,tmpsl);
RegSetKeyValueA(nwAdapters,mySubkeyName.c_str(),"MAC",REG_SZ,tmps,tmpsl);
DWORD tmp = mtu;
@@ -961,7 +962,7 @@ EthernetTap::EthernetTap(
// Open the tap, which is in this weird Windows analog of /dev
char tapPath[4096];
- sprintf_s(tapPath,"\\\\.\\Global\\%s.tap",_myDeviceInstanceId.c_str());
+ Utils::snprintf(tapPath,sizeof(tapPath),"\\\\.\\Global\\%s.tap",_myDeviceInstanceId.c_str());
_tap = CreateFileA(tapPath,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_SYSTEM|FILE_FLAG_OVERLAPPED,NULL);
if (_tap == INVALID_HANDLE_VALUE)
throw std::runtime_error("unable to open tap in \\\\.\\Global\\ namespace");
diff --git a/node/Filter.cpp b/node/Filter.cpp
index 75a7036a..6e28b7cd 100644
--- a/node/Filter.cpp
+++ b/node/Filter.cpp
@@ -186,7 +186,7 @@ bool Filter::Rule::operator()(unsigned int etype,const void *data,unsigned int l
break;
default: {
char foo[128];
- sprintf(foo,"unrecognized IPv6 header type %d",(int)nextHeader);
+ Utils::snprintf(foo,sizeof(foo),"unrecognized IPv6 header type %d",(int)nextHeader);
throw std::invalid_argument(foo);
}
}
@@ -215,11 +215,11 @@ std::string Filter::Rule::toString() const
s.push_back('*');
break;
case 1:
- sprintf(buf,"%u",_etherType.start);
+ Utils::snprintf(buf,sizeof(buf),"%u",_etherType.start);
s.append(buf);
break;
default:
- sprintf(buf,"%u-%u",_etherType.start,_etherType.end);
+ Utils::snprintf(buf,sizeof(buf),"%u-%u",_etherType.start,_etherType.end);
s.append(buf);
break;
}
@@ -229,11 +229,11 @@ std::string Filter::Rule::toString() const
s.push_back('*');
break;
case 1:
- sprintf(buf,"%u",_protocol.start);
+ Utils::snprintf(buf,sizeof(buf),"%u",_protocol.start);
s.append(buf);
break;
default:
- sprintf(buf,"%u-%u",_protocol.start,_protocol.end);
+ Utils::snprintf(buf,sizeof(buf),"%u-%u",_protocol.start,_protocol.end);
s.append(buf);
break;
}
@@ -243,11 +243,11 @@ std::string Filter::Rule::toString() const
s.push_back('*');
break;
case 1:
- sprintf(buf,"%u",_port.start);
+ Utils::snprintf(buf,sizeof(buf),"%u",_port.start);
s.append(buf);
break;
default:
- sprintf(buf,"%u-%u",_port.start,_port.end);
+ Utils::snprintf(buf,sizeof(buf),"%u-%u",_port.start,_port.end);
s.append(buf);
break;
}
@@ -269,7 +269,7 @@ Filter::Filter(const char *s)
++fn;
} catch (std::invalid_argument &exc) {
char tmp[256];
- sprintf(tmp,"invalid rule at index %u: %s",fn,exc.what());
+ Utils::snprintf(tmp,sizeof(tmp),"invalid rule at index %u: %s",fn,exc.what());
throw std::invalid_argument(tmp);
}
}
diff --git a/node/InetAddress.cpp b/node/InetAddress.cpp
index 24ec1f62..b2476893 100644
--- a/node/InetAddress.cpp
+++ b/node/InetAddress.cpp
@@ -32,6 +32,7 @@
#include "Constants.hpp"
#include "InetAddress.hpp"
+#include "Utils.hpp"
namespace ZeroTier {
@@ -66,7 +67,7 @@ std::string InetAddress::toString() const
#else
if (inet_ntop(AF_INET,(const void *)&(_sa.sin.sin_addr.s_addr),buf,sizeof(buf))) {
#endif
- sprintf(buf2,"%s/%u",buf,(unsigned int)ntohs(_sa.sin.sin_port));
+ Utils::snprintf(buf2,sizeof(buf2),"%s/%u",buf,(unsigned int)ntohs(_sa.sin.sin_port));
return std::string(buf2);
}
break;
@@ -76,7 +77,7 @@ std::string InetAddress::toString() const
#else
if (inet_ntop(AF_INET6,(const void *)&(_sa.sin6.sin6_addr.s6_addr),buf,sizeof(buf))) {
#endif
- sprintf(buf2,"%s/%u",buf,(unsigned int)ntohs(_sa.sin6.sin6_port));
+ Utils::snprintf(buf2,sizeof(buf2),"%s/%u",buf,(unsigned int)ntohs(_sa.sin6.sin6_port));
return std::string(buf2);
}
break;
diff --git a/node/MAC.hpp b/node/MAC.hpp
index f33277c0..9765aa59 100644
--- a/node/MAC.hpp
+++ b/node/MAC.hpp
@@ -30,8 +30,9 @@
#include <stdio.h>
#include <stdlib.h>
-#include "Array.hpp"
+
#include "Constants.hpp"
+#include "Array.hpp"
#include "Utils.hpp"
namespace ZeroTier {
@@ -150,7 +151,7 @@ public:
inline std::string toString() const
{
char tmp[32];
- sprintf(tmp,"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(int)data[0],(int)data[1],(int)data[2],(int)data[3],(int)data[4],(int)data[5]);
+ Utils::snprintf(tmp,sizeof(tmp),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(int)data[0],(int)data[1],(int)data[2],(int)data[3],(int)data[4],(int)data[5]);
return std::string(tmp);
}
};
diff --git a/node/MulticastGroup.hpp b/node/MulticastGroup.hpp
index 3c654ea2..9f2b111d 100644
--- a/node/MulticastGroup.hpp
+++ b/node/MulticastGroup.hpp
@@ -106,7 +106,7 @@ public:
inline std::string toString() const
{
char buf[64];
- sprintf(buf,"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x/%.8lx",(unsigned int)_mac.data[0],(unsigned int)_mac.data[1],(unsigned int)_mac.data[2],(unsigned int)_mac.data[3],(unsigned int)_mac.data[4],(unsigned int)_mac.data[5],(unsigned long)_adi);
+ Utils::snprintf(buf,sizeof(buf),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x/%.8lx",(unsigned int)_mac.data[0],(unsigned int)_mac.data[1],(unsigned int)_mac.data[2],(unsigned int)_mac.data[3],(unsigned int)_mac.data[4],(unsigned int)_mac.data[5],(unsigned long)_adi);
return std::string(buf);
}
diff --git a/node/Network.cpp b/node/Network.cpp
index fc52e6d7..b66cc3b5 100644
--- a/node/Network.cpp
+++ b/node/Network.cpp
@@ -140,7 +140,7 @@ SharedPtr<Network> Network::newInstance(const RuntimeEnvironment *renv,uint64_t
throw(std::runtime_error)
{
char tag[32];
- sprintf(tag,"%.16llx",(unsigned long long)id);
+ Utils::snprintf(tag,sizeof(tag),"%.16llx",(unsigned long long)id);
// We construct Network via a static method to ensure that it is immediately
// wrapped in a SharedPtr<>. Otherwise if there is traffic on the Ethernet
diff --git a/node/Network.hpp b/node/Network.hpp
index 0cb542bf..4c18d93d 100644
--- a/node/Network.hpp
+++ b/node/Network.hpp
@@ -107,7 +107,7 @@ public:
inline void setNetworkId(uint64_t id)
{
char buf[32];
- sprintf(buf,"%.16llx",(unsigned long long)id);
+ Utils::snprintf(buf,sizeof(buf),"%.16llx",(unsigned long long)id);
(*this)["nwid"] = buf;
}
@@ -141,9 +141,9 @@ public:
inline void setTimestamp(uint64_t ts,uint64_t maxDelta)
{
char foo[32];
- sprintf(foo,"%llu",(unsigned long long)ts);
+ Utils::snprintf(foo,sizeof(foo),"%llu",(unsigned long long)ts);
(*this)["ts"] = foo;
- sprintf(foo,"%llu",(unsigned long long)maxDelta);
+ Utils::snprintf(foo,sizeof(foo),"%llu",(unsigned long long)maxDelta);
(*this)["~ts"] = foo;
}
@@ -237,7 +237,7 @@ public:
if (contains("name"))
return get("name");
char buf[32];
- sprintf(buf,"%.16llx",(unsigned long long)networkId());
+ Utils::snprintf(buf,sizeof(buf),"%.16llx",(unsigned long long)networkId());
return std::string(buf);
}
@@ -373,7 +373,7 @@ public:
inline std::string toString()
{
char buf[64];
- sprintf(buf,"%.16llx",(unsigned long long)_id);
+ Utils::snprintf(buf,sizeof(buf),"%.16llx",(unsigned long long)_id);
return std::string(buf);
}
diff --git a/node/Node.cpp b/node/Node.cpp
index 96d1f87a..1286342d 100644
--- a/node/Node.cpp
+++ b/node/Node.cpp
@@ -590,7 +590,7 @@ public:
char vs[32];
_VersionStringMaker()
{
- sprintf(vs,"%d.%d.%d",(int)ZEROTIER_ONE_VERSION_MAJOR,(int)ZEROTIER_ONE_VERSION_MINOR,(int)ZEROTIER_ONE_VERSION_REVISION);
+ Utils::snprintf(vs,sizeof(vs),"%d.%d.%d",(int)ZEROTIER_ONE_VERSION_MAJOR,(int)ZEROTIER_ONE_VERSION_MINOR,(int)ZEROTIER_ONE_VERSION_REVISION);
}
~_VersionStringMaker() {}
};
diff --git a/node/PacketDecoder.cpp b/node/PacketDecoder.cpp
index fd817410..18d8c4e2 100644
--- a/node/PacketDecoder.cpp
+++ b/node/PacketDecoder.cpp
@@ -635,9 +635,9 @@ bool PacketDecoder::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment *_r,const
request["meta"] = std::string((const char *)field(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT,dictLen),dictLen);
request["type"] = "netconf-request";
request["peerId"] = peer->identity().toString(false);
- sprintf(tmp,"%llx",(unsigned long long)nwid);
+ Utils::snprintf(tmp,sizeof(tmp),"%llx",(unsigned long long)nwid);
request["nwid"] = tmp;
- sprintf(tmp,"%llx",(unsigned long long)packetId());
+ Utils::snprintf(tmp,sizeof(tmp),"%llx",(unsigned long long)packetId());
request["requestId"] = tmp;
//TRACE("to netconf:\n%s",request.toString().c_str());
_r->netconfService->send(request);
diff --git a/node/Peer.hpp b/node/Peer.hpp
index b9ade9b1..85f045ef 100644
--- a/node/Peer.hpp
+++ b/node/Peer.hpp
@@ -356,7 +356,7 @@ public:
{
if ((_vMajor)||(_vMinor)||(_vRevision)) {
char tmp[32];
- sprintf(tmp,"%u.%u.%u",_vMajor,_vMinor,_vRevision);
+ Utils::snprintf(tmp,sizeof(tmp),"%u.%u.%u",_vMajor,_vMinor,_vRevision);
return std::string(tmp);
}
return std::string("?");
diff --git a/node/Utils.cpp b/node/Utils.cpp
index 94f66c11..0b5afcbd 100644
--- a/node/Utils.cpp
+++ b/node/Utils.cpp
@@ -464,7 +464,7 @@ std::string Utils::toRfc1123(uint64_t t64)
#else
gmtime_r(&utc,&t);
#endif
- sprintf(buf,"%3s, %02d %3s %4d %02d:%02d:%02d GMT",DAY_NAMES[t.tm_wday],t.tm_mday,MONTH_NAMES[t.tm_mon],t.tm_year + 1900,t.tm_hour,t.tm_min,t.tm_sec);
+ Utils::snprintf(buf,sizeof(buf),"%3s, %02d %3s %4d %02d:%02d:%02d GMT",DAY_NAMES[t.tm_wday],t.tm_mday,MONTH_NAMES[t.tm_mon],t.tm_year + 1900,t.tm_hour,t.tm_min,t.tm_sec);
return std::string(buf);
}
@@ -653,4 +653,22 @@ void Utils::stdsprintf(std::string &s,const char *fmt,...)
s.append(buf);
}
+unsigned int Utils::snprintf(char *buf,unsigned int len,const char *fmt,...)
+ throw(std::length_error)
+{
+ 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 in Utils::snprintf");
+ }
+
+ return (unsigned int)n;
+}
+
} // namespace ZeroTier
diff --git a/node/Utils.hpp b/node/Utils.hpp
index 8bced8ad..0d40e370 100644
--- a/node/Utils.hpp
+++ b/node/Utils.hpp
@@ -537,6 +537,18 @@ public:
throw(std::bad_alloc,std::length_error);
/**
+ * Variant of snprintf that is portable and throws an exception
+ *
+ * @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 snprintf(char *buf,unsigned int len,const char *fmt,...)
+ throw(std::length_error);
+
+ /**
* Count the number of bits set in an integer
*
* @param v 32-bit integer
diff --git a/selftest.cpp b/selftest.cpp
index 64189862..c9ca9c71 100644
--- a/selftest.cpp
+++ b/selftest.cpp
@@ -376,32 +376,6 @@ static int testOther()
return 0;
}
-static int testRateLimiter()
-{
- RateLimiter limiter;
- RateLimiter::Limit limit;
-
- std::cout << "[ratelimiter] preload: 10000.0, rate: 1000.0/sec, max: 15000.0, min: -7500.0" << std::endl;
- limit.bytesPerSecond = 1000.0;
- limit.maxBalance = 15000.0;
- limit.minBalance = -7500.0;
- limiter.init(10000.0);
- for(int i=0;i<25;++i) {
- Thread::sleep(100);
- std::cout << "[ratelimiter] delayed 0.1s, gate(1000.0): " << (limiter.gate(limit,1000.0) ? "OK" : "BLOCK");
- std::cout << " (new balance afterwords: " << limiter.balance() << ")" << std::endl;
- }
- std::cout << "[ratelimiter] delaying 15s..." << std::endl;
- Thread::sleep(15000);
- for(int i=0;i<20;++i) {
- Thread::sleep(1000);
- std::cout << "[ratelimiter] delayed 1s, gate(2000.0): " << (limiter.gate(limit,2000.0) ? "OK" : "BLOCK");
- std::cout << " (new balance afterwords: " << limiter.balance() << ")" << std::endl;
- }
-
- return 0;
-}
-
#ifdef __WINDOWS__
int _tmain(int argc, _TCHAR* argv[])
#else
@@ -417,7 +391,6 @@ int main(int argc,char **argv)
r |= testPacket();
r |= testOther();
r |= testIdentity();
- r |= testRateLimiter();
if (r)
std::cout << std::endl << "SOMETHING FAILED!" << std::endl;