Improve code security posture by replacing sprintf with a safer function.

This commit is contained in:
Adam Ierymenko 2013-08-30 17:05:43 -04:00
parent 1a7e303f97
commit f3ad05347e
16 changed files with 75 additions and 69 deletions

View File

@ -32,7 +32,9 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <string> #include <string>
#include "Utils.hpp" #include "Utils.hpp"
#include "MAC.hpp" #include "MAC.hpp"
#include "Constants.hpp" #include "Constants.hpp"
@ -198,7 +200,7 @@ public:
inline std::string toString() const inline std::string toString() const
{ {
char buf[16]; char buf[16];
sprintf(buf,"%.10llx",(unsigned long long)_a); Utils::snprintf(buf,sizeof(buf),"%.10llx",(unsigned long long)_a);
return std::string(buf); return std::string(buf);
}; };

View File

@ -68,15 +68,14 @@ Demarc::~Demarc()
} }
std::string Demarc::describe(Demarc::Port p) std::string Demarc::describe(Demarc::Port p)
throw()
{ {
char buf[64]; char buf[64];
switch ((DemarcPortType)(((uint64_t)p) >> 60)) { switch ((DemarcPortType)(((uint64_t)p) >> 60)) {
case PORT_TYPE_UDP_SOCKET_V4: 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); return std::string(buf);
case PORT_TYPE_UDP_SOCKET_V6: 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); return std::string(buf);
case PORT_TYPE_LOCAL_ETHERNET: case PORT_TYPE_LOCAL_ETHERNET:
return std::string("ethernet"); return std::string("ethernet");

View File

@ -83,8 +83,7 @@ public:
* @param p Port * @param p Port
* @return Human-readable description of port * @return Human-readable description of port
*/ */
static std::string describe(Port p) static std::string describe(Port p);
throw();
/** /**
* @param p Port to check * @param p Port to check

View File

@ -36,6 +36,7 @@
#include "RuntimeEnvironment.hpp" #include "RuntimeEnvironment.hpp"
#include "Utils.hpp" #include "Utils.hpp"
#include "Mutex.hpp" #include "Mutex.hpp"
#include "Utils.hpp"
// ff:ff:ff:ff:ff:ff with no ADI // ff:ff:ff:ff:ff:ff with no ADI
static const ZeroTier::MulticastGroup _blindWildcardMulticastGroup(ZeroTier::MAC(0xff),0); static const ZeroTier::MulticastGroup _blindWildcardMulticastGroup(ZeroTier::MAC(0xff),0);
@ -99,22 +100,22 @@ private:
inline void _findCmd(int id,const char *name) inline void _findCmd(int id,const char *name)
{ {
char tmp[4096]; char tmp[4096];
sprintf(tmp,"/sbin/%s",name); ZeroTier::Utils::snprintf(tmp,sizeof(tmp),"/sbin/%s",name);
if (ZeroTier::Utils::fileExists(tmp)) { if (ZeroTier::Utils::fileExists(tmp)) {
_paths[id] = tmp; _paths[id] = tmp;
return; return;
} }
sprintf(tmp,"/usr/sbin/%s",name); ZeroTier::Utils::snprintf(tmp,sizeof(tmp),"/usr/sbin/%s",name);
if (ZeroTier::Utils::fileExists(tmp)) { if (ZeroTier::Utils::fileExists(tmp)) {
_paths[id] = tmp; _paths[id] = tmp;
return; return;
} }
sprintf(tmp,"/bin/%s",name); ZeroTier::Utils::snprintf(tmp,sizeof(tmp),"/bin/%s",name);
if (ZeroTier::Utils::fileExists(tmp)) { if (ZeroTier::Utils::fileExists(tmp)) {
_paths[id] = tmp; _paths[id] = tmp;
return; return;
} }
sprintf(tmp,"/usr/bin/%s",name); ZeroTier::Utils::snprintf(tmp,sizeof(tmp),"/usr/bin/%s",name);
if (ZeroTier::Utils::fileExists(tmp)) { if (ZeroTier::Utils::fileExists(tmp)) {
_paths[id] = tmp; _paths[id] = tmp;
return; return;
@ -178,8 +179,8 @@ EthernetTap::EthernetTap(
int devno = 0; int devno = 0;
struct stat sbuf; struct stat sbuf;
do { do {
sprintf(ifr.ifr_name,"zt%d",devno++); Utils::snprintf(ifr.ifr_name,sizeof(ifr.ifr_name),"zt%d",devno++);
sprintf(procpath,"/proc/sys/net/ipv4/conf/%s",ifr.ifr_name); Utils::snprintf(procpath,sizeof(procpath),"/proc/sys/net/ipv4/conf/%s",ifr.ifr_name);
} while (stat(procpath,&sbuf) == 0); } while (stat(procpath,&sbuf) == 0);
} }
@ -292,12 +293,12 @@ EthernetTap::EthernetTap(
// Open the first available device (ones in use will fail with resource busy) // Open the first available device (ones in use will fail with resource busy)
for(int i=0;i<256;++i) { 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)) if (stat(devpath,&tmp))
throw std::runtime_error("no more TAP devices available"); throw std::runtime_error("no more TAP devices available");
_fd = ::open(devpath,O_RDWR); _fd = ::open(devpath,O_RDWR);
if (_fd > 0) { if (_fd > 0) {
sprintf(_dev,"zt%d",i); Utils::snprintf(_dev,sizeof(_dev),"zt%d",i);
break; break;
} }
} }
@ -316,8 +317,8 @@ EthernetTap::EthernetTap(
} }
// Configure MAC address and MTU, bring interface up // 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]); 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]);
sprintf(mtustr,"%u",mtu); Utils::snprintf(mtustr,sizeof(mtustr),"%u",mtu);
long cpid; long cpid;
if ((cpid = (long)vfork()) == 0) { if ((cpid = (long)vfork()) == 0) {
execl(ifconfig,ifconfig,_dev,"lladdr",ethaddr,"mtu",mtustr,"up",(const char *)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 we have a device, configure it
if (_myDeviceInstanceId.length() > 0) { if (_myDeviceInstanceId.length() > 0) {
char tmps[4096]; 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(),"NetworkAddress",REG_SZ,tmps,tmpsl);
RegSetKeyValueA(nwAdapters,mySubkeyName.c_str(),"MAC",REG_SZ,tmps,tmpsl); RegSetKeyValueA(nwAdapters,mySubkeyName.c_str(),"MAC",REG_SZ,tmps,tmpsl);
DWORD tmp = mtu; DWORD tmp = mtu;
@ -961,7 +962,7 @@ EthernetTap::EthernetTap(
// Open the tap, which is in this weird Windows analog of /dev // Open the tap, which is in this weird Windows analog of /dev
char tapPath[4096]; 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); _tap = CreateFileA(tapPath,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_SYSTEM|FILE_FLAG_OVERLAPPED,NULL);
if (_tap == INVALID_HANDLE_VALUE) if (_tap == INVALID_HANDLE_VALUE)
throw std::runtime_error("unable to open tap in \\\\.\\Global\\ namespace"); throw std::runtime_error("unable to open tap in \\\\.\\Global\\ namespace");

View File

@ -186,7 +186,7 @@ bool Filter::Rule::operator()(unsigned int etype,const void *data,unsigned int l
break; break;
default: { default: {
char foo[128]; 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); throw std::invalid_argument(foo);
} }
} }
@ -215,11 +215,11 @@ std::string Filter::Rule::toString() const
s.push_back('*'); s.push_back('*');
break; break;
case 1: case 1:
sprintf(buf,"%u",_etherType.start); Utils::snprintf(buf,sizeof(buf),"%u",_etherType.start);
s.append(buf); s.append(buf);
break; break;
default: default:
sprintf(buf,"%u-%u",_etherType.start,_etherType.end); Utils::snprintf(buf,sizeof(buf),"%u-%u",_etherType.start,_etherType.end);
s.append(buf); s.append(buf);
break; break;
} }
@ -229,11 +229,11 @@ std::string Filter::Rule::toString() const
s.push_back('*'); s.push_back('*');
break; break;
case 1: case 1:
sprintf(buf,"%u",_protocol.start); Utils::snprintf(buf,sizeof(buf),"%u",_protocol.start);
s.append(buf); s.append(buf);
break; break;
default: default:
sprintf(buf,"%u-%u",_protocol.start,_protocol.end); Utils::snprintf(buf,sizeof(buf),"%u-%u",_protocol.start,_protocol.end);
s.append(buf); s.append(buf);
break; break;
} }
@ -243,11 +243,11 @@ std::string Filter::Rule::toString() const
s.push_back('*'); s.push_back('*');
break; break;
case 1: case 1:
sprintf(buf,"%u",_port.start); Utils::snprintf(buf,sizeof(buf),"%u",_port.start);
s.append(buf); s.append(buf);
break; break;
default: default:
sprintf(buf,"%u-%u",_port.start,_port.end); Utils::snprintf(buf,sizeof(buf),"%u-%u",_port.start,_port.end);
s.append(buf); s.append(buf);
break; break;
} }
@ -269,7 +269,7 @@ Filter::Filter(const char *s)
++fn; ++fn;
} catch (std::invalid_argument &exc) { } catch (std::invalid_argument &exc) {
char tmp[256]; 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); throw std::invalid_argument(tmp);
} }
} }

View File

@ -32,6 +32,7 @@
#include "Constants.hpp" #include "Constants.hpp"
#include "InetAddress.hpp" #include "InetAddress.hpp"
#include "Utils.hpp"
namespace ZeroTier { namespace ZeroTier {
@ -66,7 +67,7 @@ std::string InetAddress::toString() const
#else #else
if (inet_ntop(AF_INET,(const void *)&(_sa.sin.sin_addr.s_addr),buf,sizeof(buf))) { if (inet_ntop(AF_INET,(const void *)&(_sa.sin.sin_addr.s_addr),buf,sizeof(buf))) {
#endif #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); return std::string(buf2);
} }
break; break;
@ -76,7 +77,7 @@ std::string InetAddress::toString() const
#else #else
if (inet_ntop(AF_INET6,(const void *)&(_sa.sin6.sin6_addr.s6_addr),buf,sizeof(buf))) { if (inet_ntop(AF_INET6,(const void *)&(_sa.sin6.sin6_addr.s6_addr),buf,sizeof(buf))) {
#endif #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); return std::string(buf2);
} }
break; break;

View File

@ -30,8 +30,9 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "Array.hpp"
#include "Constants.hpp" #include "Constants.hpp"
#include "Array.hpp"
#include "Utils.hpp" #include "Utils.hpp"
namespace ZeroTier { namespace ZeroTier {
@ -150,7 +151,7 @@ public:
inline std::string toString() const inline std::string toString() const
{ {
char tmp[32]; 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); return std::string(tmp);
} }
}; };

View File

@ -106,7 +106,7 @@ public:
inline std::string toString() const inline std::string toString() const
{ {
char buf[64]; 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); return std::string(buf);
} }

View File

@ -140,7 +140,7 @@ SharedPtr<Network> Network::newInstance(const RuntimeEnvironment *renv,uint64_t
throw(std::runtime_error) throw(std::runtime_error)
{ {
char tag[32]; 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 // 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 // wrapped in a SharedPtr<>. Otherwise if there is traffic on the Ethernet

View File

@ -107,7 +107,7 @@ public:
inline void setNetworkId(uint64_t id) inline void setNetworkId(uint64_t id)
{ {
char buf[32]; char buf[32];
sprintf(buf,"%.16llx",(unsigned long long)id); Utils::snprintf(buf,sizeof(buf),"%.16llx",(unsigned long long)id);
(*this)["nwid"] = buf; (*this)["nwid"] = buf;
} }
@ -141,9 +141,9 @@ public:
inline void setTimestamp(uint64_t ts,uint64_t maxDelta) inline void setTimestamp(uint64_t ts,uint64_t maxDelta)
{ {
char foo[32]; char foo[32];
sprintf(foo,"%llu",(unsigned long long)ts); Utils::snprintf(foo,sizeof(foo),"%llu",(unsigned long long)ts);
(*this)["ts"] = foo; (*this)["ts"] = foo;
sprintf(foo,"%llu",(unsigned long long)maxDelta); Utils::snprintf(foo,sizeof(foo),"%llu",(unsigned long long)maxDelta);
(*this)["~ts"] = foo; (*this)["~ts"] = foo;
} }
@ -237,7 +237,7 @@ public:
if (contains("name")) if (contains("name"))
return get("name"); return get("name");
char buf[32]; char buf[32];
sprintf(buf,"%.16llx",(unsigned long long)networkId()); Utils::snprintf(buf,sizeof(buf),"%.16llx",(unsigned long long)networkId());
return std::string(buf); return std::string(buf);
} }
@ -373,7 +373,7 @@ public:
inline std::string toString() inline std::string toString()
{ {
char buf[64]; char buf[64];
sprintf(buf,"%.16llx",(unsigned long long)_id); Utils::snprintf(buf,sizeof(buf),"%.16llx",(unsigned long long)_id);
return std::string(buf); return std::string(buf);
} }

View File

@ -590,7 +590,7 @@ public:
char vs[32]; char vs[32];
_VersionStringMaker() _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() {} ~_VersionStringMaker() {}
}; };

View File

@ -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["meta"] = std::string((const char *)field(ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT,dictLen),dictLen);
request["type"] = "netconf-request"; request["type"] = "netconf-request";
request["peerId"] = peer->identity().toString(false); 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; request["nwid"] = tmp;
sprintf(tmp,"%llx",(unsigned long long)packetId()); Utils::snprintf(tmp,sizeof(tmp),"%llx",(unsigned long long)packetId());
request["requestId"] = tmp; request["requestId"] = tmp;
//TRACE("to netconf:\n%s",request.toString().c_str()); //TRACE("to netconf:\n%s",request.toString().c_str());
_r->netconfService->send(request); _r->netconfService->send(request);

View File

@ -356,7 +356,7 @@ public:
{ {
if ((_vMajor)||(_vMinor)||(_vRevision)) { if ((_vMajor)||(_vMinor)||(_vRevision)) {
char tmp[32]; 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(tmp);
} }
return std::string("?"); return std::string("?");

View File

@ -464,7 +464,7 @@ std::string Utils::toRfc1123(uint64_t t64)
#else #else
gmtime_r(&utc,&t); gmtime_r(&utc,&t);
#endif #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); return std::string(buf);
} }
@ -653,4 +653,22 @@ void Utils::stdsprintf(std::string &s,const char *fmt,...)
s.append(buf); 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 } // namespace ZeroTier

View File

@ -536,6 +536,18 @@ public:
static void stdsprintf(std::string &s,const char *fmt,...) static void stdsprintf(std::string &s,const char *fmt,...)
throw(std::bad_alloc,std::length_error); 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 * Count the number of bits set in an integer
* *

View File

@ -376,32 +376,6 @@ static int testOther()
return 0; 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__ #ifdef __WINDOWS__
int _tmain(int argc, _TCHAR* argv[]) int _tmain(int argc, _TCHAR* argv[])
#else #else
@ -417,7 +391,6 @@ int main(int argc,char **argv)
r |= testPacket(); r |= testPacket();
r |= testOther(); r |= testOther();
r |= testIdentity(); r |= testIdentity();
r |= testRateLimiter();
if (r) if (r)
std::cout << std::endl << "SOMETHING FAILED!" << std::endl; std::cout << std::endl << "SOMETHING FAILED!" << std::endl;