diff options
Diffstat (limited to 'node')
-rw-r--r-- | node/Buffer.hpp | 2 | ||||
-rw-r--r-- | node/Dictionary.hpp | 4 | ||||
-rw-r--r-- | node/EllipticCurveKey.hpp | 2 | ||||
-rw-r--r-- | node/EllipticCurveKeyPair.cpp | 4 | ||||
-rw-r--r-- | node/EthernetTap.cpp | 144 | ||||
-rw-r--r-- | node/EthernetTap.hpp | 6 | ||||
-rw-r--r-- | node/Filter.hpp | 2 | ||||
-rw-r--r-- | node/Identity.cpp | 8 | ||||
-rw-r--r-- | node/Logger.cpp | 5 | ||||
-rw-r--r-- | node/Node.cpp | 30 | ||||
-rw-r--r-- | node/Node.hpp | 14 | ||||
-rw-r--r-- | node/Switch.cpp | 2 | ||||
-rw-r--r-- | node/Topology.cpp | 2 | ||||
-rw-r--r-- | node/UdpSocket.cpp | 23 | ||||
-rw-r--r-- | node/UdpSocket.hpp | 8 | ||||
-rw-r--r-- | node/Utils.cpp | 4 | ||||
-rw-r--r-- | node/Utils.hpp | 8 |
17 files changed, 239 insertions, 29 deletions
diff --git a/node/Buffer.hpp b/node/Buffer.hpp index 91bc1027..73d0e5de 100644 --- a/node/Buffer.hpp +++ b/node/Buffer.hpp @@ -284,7 +284,7 @@ public: inline void append(const std::string &s) throw(std::out_of_range) { - append(s.data(),s.length()); + append(s.data(),(unsigned int)s.length()); } /** diff --git a/node/Dictionary.hpp b/node/Dictionary.hpp index f706168f..178810ff 100644 --- a/node/Dictionary.hpp +++ b/node/Dictionary.hpp @@ -114,9 +114,9 @@ public: std::string s; for(const_iterator kv(begin());kv!=end();++kv) { - _appendEsc(kv->first.data(),kv->first.length(),s); + _appendEsc(kv->first.data(),(unsigned int)kv->first.length(),s); s.push_back('='); - _appendEsc(kv->second.data(),kv->second.length(),s); + _appendEsc(kv->second.data(),(unsigned int)kv->second.length(),s); s.append(ZT_EOL_S); } diff --git a/node/EllipticCurveKey.hpp b/node/EllipticCurveKey.hpp index 5a3a60c4..c3439c62 100644 --- a/node/EllipticCurveKey.hpp +++ b/node/EllipticCurveKey.hpp @@ -78,7 +78,7 @@ public: EllipticCurveKey(const std::string &data) throw(std::out_of_range) { - set(data.data(),data.length()); + set(data.data(),(unsigned int)data.length()); } inline void set(const void *data,unsigned int len) diff --git a/node/EllipticCurveKeyPair.cpp b/node/EllipticCurveKeyPair.cpp index 047b2b4f..dd95d9a7 100644 --- a/node/EllipticCurveKeyPair.cpp +++ b/node/EllipticCurveKeyPair.cpp @@ -153,7 +153,7 @@ bool EllipticCurveKeyPair::generate() } memset(_priv._key,0,sizeof(_priv._key)); - len = BN_num_bytes(EC_KEY_get0_private_key(key)); + len = (int)BN_num_bytes(EC_KEY_get0_private_key(key)); if ((len > ZT_EC_PRIME_BYTES)||(len < 0)) { EC_KEY_free(key); return false; @@ -162,7 +162,7 @@ bool EllipticCurveKeyPair::generate() _priv._bytes = ZT_EC_PRIME_BYTES; memset(_pub._key,0,sizeof(_pub._key)); - len = EC_POINT_point2oct(ZT_EC_GROUP.g,EC_KEY_get0_public_key(key),POINT_CONVERSION_COMPRESSED,_pub._key,sizeof(_pub._key),0); + len = (int)EC_POINT_point2oct(ZT_EC_GROUP.g,EC_KEY_get0_public_key(key),POINT_CONVERSION_COMPRESSED,_pub._key,sizeof(_pub._key),0); if (len != ZT_EC_PUBLIC_KEY_BYTES) { EC_KEY_free(key); return false; diff --git a/node/EthernetTap.cpp b/node/EthernetTap.cpp index 48e93a34..745b8c8e 100644 --- a/node/EthernetTap.cpp +++ b/node/EthernetTap.cpp @@ -693,11 +693,37 @@ void EthernetTap::threadMain() #include <tchar.h> #include <winreg.h> #include <wchar.h> +#include <nldef.h> +#include <netioapi.h> #include "..\vsprojects\TapDriver\tap-windows.h" namespace ZeroTier { +// Helper function to get an adapter's LUID and index from its GUID. The LUID is +// constant but the index can change, so go ahead and just look them both up by +// the GUID which is constant. (The GUID is the instance ID in the registry.) +static inline std::pair<NET_LUID,NET_IFINDEX> _findAdapterByGuid(const GUID &guid) + throw(std::runtime_error) +{ + MIB_IF_TABLE2 *ift = (MIB_IF_TABLE2 *)0; + + if (GetIfTable2Ex(MibIfTableRaw,&ift) != NO_ERROR) + throw std::runtime_error("GetIfTable2Ex() failed"); + + for(ULONG i=0;i<ift->NumEntries;++i) { + if (ift->Table[i].InterfaceGuid == guid) { + std::pair<NET_LUID,NET_IFINDEX> tmp(ift->Table[i].InterfaceLuid,ift->Table[i].InterfaceIndex); + FreeMibTable(&ift); + return tmp; + } + } + + FreeMibTable(&ift); + + throw std::runtime_error("interface not found"); +} + static Mutex _systemTapInitLock; EthernetTap::EthernetTap( @@ -721,6 +747,9 @@ EthernetTap::EthernetTap( char subkeyClass[4096]; char data[4096]; + if (mtu > ZT_IF_MTU) + throw std::runtime_error("MTU too large for Windows tap"); + Mutex::Lock _l(_systemTapInitLock); // only init one tap at a time, process-wide HKEY nwAdapters; @@ -813,7 +842,7 @@ EthernetTap::EthernetTap( dataLen = sizeof(data); if (RegGetValueA(nwAdapters,subkeyName,"NetCfgInstanceId",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) { if (existingDeviceInstances.count(std::string(data,dataLen)) == 0) { - RegSetKeyValueA(nwAdapters,subkeyName,"_ZeroTierTapIdentifier",REG_SZ,tag,strlen(tag)+1); + RegSetKeyValueA(nwAdapters,subkeyName,"_ZeroTierTapIdentifier",REG_SZ,tag,(DWORD)(strlen(tag)+1)); _myDeviceInstanceId.assign(data,dataLen); mySubkeyName = subkeyName; subkeyIndex = -1; // break outer loop @@ -842,8 +871,27 @@ EthernetTap::EthernetTap( if (_myDeviceInstanceId.length() == 0) throw std::runtime_error("unable to create new tap adapter"); + { + char nobraces[128]; + const char *nbtmp1 = _myDeviceInstanceId.c_str(); + char *nbtmp2 = nobraces; + while (*nbtmp1) { + if ((*nbtmp1 != '{')&&(*nbtmp1 != '}')) + *nbtmp2++ = *nbtmp1; + ++nbtmp1; + } + *nbtmp2 = (char)0; + if (UuidFromStringA((RPC_CSTR)nobraces,&_deviceGuid) != RPC_S_OK) + throw std::runtime_error("unable to convert instance ID GUID to native GUID (invalid NetCfgInstanceId in registry?)"); + } + +#ifdef UNICODE wchar_t tapPath[4096]; swprintf_s(tapPath,L"\\\\.\\Global\\%S.tap",_myDeviceInstanceId.c_str()); +#else + char tapPath[4096]; + sprintf_s(tapPath,"\\\\.\\Global\\%s.tap",_myDeviceInstanceId.c_str()); +#endif _tap = CreateFile(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"); @@ -878,14 +926,104 @@ void EthernetTap::whack() bool EthernetTap::addIP(const InetAddress &ip) { + Mutex::Lock _l(_ips_m); + + if (_ips.count(ip)) + return true; + + if (!ip.port()) + return false; + + try { + std::pair<NET_LUID,NET_IFINDEX> ifidx = _findAdapterByGuid(_deviceGuid); + MIB_UNICASTIPADDRESS_ROW ipr; + + InitializeUnicastIpAddressEntry(&ipr); + if (ip.isV4()) { + ipr.Address.Ipv4.sin_family = AF_INET; + ipr.Address.Ipv4.sin_addr.S_un.S_addr = *((const uint32_t *)ip.rawIpData()); + ipr.OnLinkPrefixLength = ip.port(); + } else if (ip.isV6()) { + } else return false; + + ipr.PrefixOrigin = IpPrefixOriginManual; + ipr.SuffixOrigin = IpSuffixOriginManual; + ipr.ValidLifetime = 0xffffffff; + ipr.PreferredLifetime = 0xffffffff; + + ipr.InterfaceLuid = ifidx.first; + ipr.InterfaceIndex = ifidx.second; + + if (CreateUnicastIpAddressEntry(&ipr) == NO_ERROR) { + _ips.insert(ip); + return true; + } + } catch ( ... ) {} + return false; } bool EthernetTap::removeIP(const InetAddress &ip) { + try { + MIB_UNICASTIPADDRESS_TABLE *ipt = (MIB_UNICASTIPADDRESS_TABLE *)0; + std::pair<NET_LUID,NET_IFINDEX> ifidx = _findAdapterByGuid(_deviceGuid); + + if (GetUnicastIpAddressTable(AF_UNSPEC,&ipt) == NO_ERROR) { + for(DWORD i=0;i<ipt->NumEntries;++i) { + if ((ipt->Table[i].InterfaceLuid.Value == ifidx.first.Value)&&(ipt->Table[i].InterfaceIndex == ifidx.second)) { + InetAddress addr; + switch(ipt->Table[i].Address.si_family) { + case AF_INET: + addr.set(&(ipt->Table[i].Address.Ipv4.sin_addr.S_un.S_addr),4,ipt->Table[i].OnLinkPrefixLength); + break; + case AF_INET6: + addr.set(ipt->Table[i].Address.Ipv6.sin6_addr.u.Byte,16,ipt->Table[i].OnLinkPrefixLength); + break; + } + if (addr == ip) { + DeleteUnicastIpAddressEntry(&(ipt->Table[i])); + FreeMibTable(&ipt); + Mutex::Lock _l(_ips_m); + _ips.erase(ip); + return true; + } + } + } + FreeMibTable(&ipt); + } + } catch ( ... ) {} return false; } +std::set<InetAddress> EthernetTap::allIps() const +{ + std::set<InetAddress> addrs; + + try { + MIB_UNICASTIPADDRESS_TABLE *ipt = (MIB_UNICASTIPADDRESS_TABLE *)0; + std::pair<NET_LUID,NET_IFINDEX> ifidx = _findAdapterByGuid(_deviceGuid); + + if (GetUnicastIpAddressTable(AF_UNSPEC,&ipt) == NO_ERROR) { + for(DWORD i=0;i<ipt->NumEntries;++i) { + if ((ipt->Table[i].InterfaceLuid.Value == ifidx.first.Value)&&(ipt->Table[i].InterfaceIndex == ifidx.second)) { + switch(ipt->Table[i].Address.si_family) { + case AF_INET: + addrs.insert(InetAddress(&(ipt->Table[i].Address.Ipv4.sin_addr.S_un.S_addr),4,ipt->Table[i].OnLinkPrefixLength)); + break; + case AF_INET6: + addrs.insert(InetAddress(ipt->Table[i].Address.Ipv6.sin6_addr.u.Byte,16,ipt->Table[i].OnLinkPrefixLength)); + break; + } + } + } + FreeMibTable(&ipt); + } + } catch ( ... ) {} + + return addrs; +} + void EthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len) { if (len > (ZT_IF_MTU)) @@ -939,8 +1077,8 @@ void EthernetTap::threadMain() MAC from(_tapReadBuf + 6); unsigned int etherType = Utils::ntoh(*((const uint16_t *)(_tapReadBuf + 12))); Buffer<4096> tmp(_tapReadBuf + 14,bytesRead - 14); - printf("GOT FRAME: %u bytes: %s\r\n",(unsigned int)bytesRead,Utils::hex(_tapReadBuf,bytesRead).c_str()); - //_handler(_arg,from,to,etherType,tmp); + //printf("GOT FRAME: %u bytes: %s\r\n",(unsigned int)bytesRead,Utils::hex(_tapReadBuf,bytesRead).c_str()); + _handler(_arg,from,to,etherType,tmp); } } ReadFile(_tap,_tapReadBuf,sizeof(_tapReadBuf),NULL,&_tapOvlRead); diff --git a/node/EthernetTap.hpp b/node/EthernetTap.hpp index cff0953b..b4128abd 100644 --- a/node/EthernetTap.hpp +++ b/node/EthernetTap.hpp @@ -135,6 +135,11 @@ public: } /** + * @return Set of IP addresses / netmasks included any we did not assign, link-local, etc. + */ + std::set<InetAddress> allIps() const; + + /** * Set this tap's IP addresses to exactly this set of IPs * * New IPs are created, ones not in this list are removed. @@ -213,6 +218,7 @@ private: OVERLAPPED _tapOvlRead,_tapOvlWrite; char _tapReadBuf[ZT_IF_MTU + 32]; HANDLE _injectSemaphore; + GUID _deviceGuid; std::string _myDeviceInstanceId; std::queue< std::pair< Array<char,ZT_IF_MTU + 32>,unsigned int > > _injectPending; Mutex _injectPending_m; diff --git a/node/Filter.hpp b/node/Filter.hpp index 8b86b48f..ac493b28 100644 --- a/node/Filter.hpp +++ b/node/Filter.hpp @@ -298,7 +298,7 @@ public: throw() { Mutex::Lock _l(_chain_m); - return _chain.size(); + return (unsigned int)_chain.size(); } /** diff --git a/node/Identity.cpp b/node/Identity.cpp index 66ddae04..391b436e 100644 --- a/node/Identity.cpp +++ b/node/Identity.cpp @@ -88,7 +88,7 @@ bool Identity::locallyValidate(bool doAddressDerivationCheck) const SHA256_Update(&sha,&zero,1); SHA256_Final(dig,&sha); - return ((EllipticCurveKeyPair::verify(dig,_publicKey,_signature.data(),_signature.length()))&&((!doAddressDerivationCheck)||(deriveAddress(_publicKey.data(),_publicKey.size()) == _address))); + return ((EllipticCurveKeyPair::verify(dig,_publicKey,_signature.data(),(unsigned int)_signature.length()))&&((!doAddressDerivationCheck)||(deriveAddress(_publicKey.data(),_publicKey.size()) == _address))); } std::string Identity::toString(bool includePrivate) const @@ -98,7 +98,7 @@ std::string Identity::toString(bool includePrivate) const r.append(":1:"); // 1 == IDENTITY_TYPE_NIST_P_521 r.append(Utils::base64Encode(_publicKey.data(),_publicKey.size())); r.push_back(':'); - r.append(Utils::base64Encode(_signature.data(),_signature.length())); + r.append(Utils::base64Encode(_signature.data(),(unsigned int)_signature.length())); if ((includePrivate)&&(_keyPair)) { r.push_back(':'); r.append(Utils::base64Encode(_keyPair->priv().data(),_keyPair->priv().size())); @@ -127,7 +127,7 @@ bool Identity::fromString(const char *str) b = Utils::base64Decode(fields[2]); if ((!b.length())||(b.length() > ZT_EC_MAX_BYTES)) return false; - _publicKey.set(b.data(),b.length()); + _publicKey.set(b.data(),(unsigned int)b.length()); _signature = Utils::base64Decode(fields[3]); if (!_signature.length()) @@ -137,7 +137,7 @@ bool Identity::fromString(const char *str) b = Utils::base64Decode(fields[4]); if ((!b.length())||(b.length() > ZT_EC_MAX_BYTES)) return false; - _keyPair = new EllipticCurveKeyPair(_publicKey,EllipticCurveKey(b.data(),b.length())); + _keyPair = new EllipticCurveKeyPair(_publicKey,EllipticCurveKey(b.data(),(unsigned int)b.length())); } return true; diff --git a/node/Logger.cpp b/node/Logger.cpp index 71b4893d..7084ba6c 100644 --- a/node/Logger.cpp +++ b/node/Logger.cpp @@ -107,7 +107,12 @@ void Logger::trace(const char *module,unsigned int line,const char *fmt,...) if (_log) { time_t now = time(0); +#ifdef __WINDOWS__ + ctime_s(tmp,sizeof(tmp),&now); + char *nowstr = tmp; +#else char *nowstr = ctime_r(&now,tmp); +#endif for(char *c=nowstr;*c;++c) { if (*c == '\n') *c = '\0'; diff --git a/node/Node.cpp b/node/Node.cpp index 1884f9ce..c9aef8a5 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -258,7 +258,7 @@ Node::Node(const char *hp) { _NodeImpl *impl = (_NodeImpl *)_impl; - if (hp) + if ((hp)&&(strlen(hp) > 0)) impl->renv.homePath = hp; else impl->renv.homePath = ZT_DEFAULTS.defaultHomePath; impl->reasonForTermination = Node::NODE_RUNNING; @@ -382,10 +382,10 @@ Node::ReasonForTermination Node::run() _r->sysEnv = new SysEnv(_r); try { _r->nc = new NodeConfig(_r,configAuthToken.c_str()); - } catch ( ... ) { + } catch (std::exception &exc) { // An exception here currently means that another instance of ZeroTier // One is running. - return impl->terminateBecause(Node::NODE_UNRECOVERABLE_ERROR,"another instance of ZeroTier One appears to be running, or local control UDP port cannot be bound"); + return impl->terminateBecause(Node::NODE_UNRECOVERABLE_ERROR,(std::string("another instance of ZeroTier One appears to be running, or local control UDP port cannot be bound: ") + exc.what()).c_str()); } // TODO: make configurable @@ -618,3 +618,27 @@ const unsigned char EMBEDDED_VERSION_STAMP[20] = { }; } // namespace ZeroTier + +extern "C" { + +ZeroTier::Node *zeroTierCreateNode(const char *hp) +{ + return new ZeroTier::Node(hp); +} + +void zeroTierDeleteNode(ZeroTier::Node *n) +{ + delete n; +} + +ZeroTier::Node::LocalClient *zeroTierCreateLocalClient(const char *authToken,void (*resultHandler)(void *,unsigned long,const char *),void *arg) +{ + return new ZeroTier::Node::LocalClient(authToken,resultHandler,arg); +} + +void zeroTierDeleteLocalClient(ZeroTier::Node::LocalClient *lc) +{ + delete lc; +} + +} // extern "C" diff --git a/node/Node.hpp b/node/Node.hpp index b716b556..9fb4666d 100644 --- a/node/Node.hpp +++ b/node/Node.hpp @@ -163,5 +163,17 @@ extern const unsigned char EMBEDDED_VERSION_STAMP[20]; } // namespace ZeroTier -#endif +extern "C" { + +// Functions with C-style linkage for easy DLL symbol table +// lookup. These just create instances of Node and LocalClient. + +ZeroTier::Node *zeroTierCreateNode(const char *hp); +void zeroTierDeleteNode(ZeroTier::Node *n); +ZeroTier::Node::LocalClient *zeroTierCreateLocalClient(const char *authToken,void (*resultHandler)(void *,unsigned long,const char *),void *arg); +void zeroTierDeleteLocalClient(ZeroTier::Node::LocalClient *lc); + +} // extern "C" + +#endif diff --git a/node/Switch.cpp b/node/Switch.cpp index aed37307..9370522e 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -142,7 +142,7 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c outpTmpl.append((uint16_t)data.size()); outpTmpl.append((uint16_t)signature.length()); outpTmpl.append(data.data(),data.size()); - outpTmpl.append(signature.data(),signature.length()); + outpTmpl.append(signature.data(),(unsigned int)signature.length()); outpTmpl.compress(); send(outpTmpl,true); for(unsigned int i=1;i<np;++i) { diff --git a/node/Topology.cpp b/node/Topology.cpp index 71d73a9d..f830cbb6 100644 --- a/node/Topology.cpp +++ b/node/Topology.cpp @@ -232,7 +232,7 @@ void Topology::threadMain() } _PeerDeepVerifyJob job(_peerDeepVerifyJobs.front()); _peerDeepVerifyJobs.pop_front(); - unsigned long queueRemaining = _peerDeepVerifyJobs.size(); + unsigned long queueRemaining = (unsigned long)_peerDeepVerifyJobs.size(); _peerDeepVerifyJobs_m.unlock(); switch(job.type) { diff --git a/node/UdpSocket.cpp b/node/UdpSocket.cpp index 2f59a03c..24c130ca 100644 --- a/node/UdpSocket.cpp +++ b/node/UdpSocket.cpp @@ -63,7 +63,11 @@ UdpSocket::UdpSocket( _packetHandler(packetHandler), _arg(arg), _localPort(localPort), +#ifdef __WINDOWS__ + _sock(INVALID_SOCKET), +#else _sock(0), +#endif _v6(ipv6) { #ifdef __WINDOWS__ @@ -77,8 +81,13 @@ UdpSocket::UdpSocket( if (ipv6) { _sock = socket(AF_INET6,SOCK_DGRAM,0); +#ifdef __WINDOWS__ + if (_sock == INVALID_SOCKET) + throw std::runtime_error("unable to create IPv6 SOCK_DGRAM socket"); +#else if (_sock <= 0) throw std::runtime_error("unable to create IPv6 SOCK_DGRAM socket"); +#endif #ifdef __WINDOWS__ yes = TRUE; setsockopt(_sock,IPPROTO_IPV6,IPV6_V6ONLY,(const char *)&yes,sizeof(yes)); @@ -115,8 +124,13 @@ UdpSocket::UdpSocket( } } else { _sock = socket(AF_INET,SOCK_DGRAM,0); +#ifdef __WINDOWS__ + if (_sock == INVALID_SOCKET) + throw std::runtime_error("unable to create IPv4 SOCK_DGRAM socket"); +#else if (_sock <= 0) throw std::runtime_error("unable to create IPv4 SOCK_DGRAM socket"); +#endif #ifdef __WINDOWS__ no = FALSE; setsockopt(_sock,SOL_SOCKET,SO_REUSEADDR,(const char *)&no,sizeof(no)); @@ -154,16 +168,19 @@ UdpSocket::UdpSocket( UdpSocket::~UdpSocket() { int s = _sock; - _sock = 0; - if (s > 0) { #ifdef __WINDOWS__ + _sock = INVALID_SOCKET; + if (s != INVALID_SOCKET) { ::shutdown(s,SD_BOTH); ::closesocket(s); + } #else + _sock = 0; + if (s > 0) { ::shutdown(s,SHUT_RDWR); ::close(s); -#endif } +#endif Thread::join(_thread); } diff --git a/node/UdpSocket.hpp b/node/UdpSocket.hpp index 6b7d488c..d8467f64 100644 --- a/node/UdpSocket.hpp +++ b/node/UdpSocket.hpp @@ -35,6 +35,10 @@ #include "InetAddress.hpp" #include "Mutex.hpp" +#ifdef __WINDOWS__ +#include <WinSock2.h> +#endif + namespace ZeroTier { /** @@ -100,7 +104,11 @@ private: void (*_packetHandler)(UdpSocket *,void *,const InetAddress &,const void *,unsigned int); void *_arg; int _localPort; +#ifdef __WINDOWS__ + volatile SOCKET _sock; +#else volatile int _sock; +#endif bool _v6; Mutex _sendLock; }; diff --git a/node/Utils.cpp b/node/Utils.cpp index 32cfe2d1..94f66c11 100644 --- a/node/Utils.cpp +++ b/node/Utils.cpp @@ -501,7 +501,7 @@ uint64_t Utils::fromRfc1123(const char *tstr) struct tm t; char wdays[128],mons[128]; - int l = strlen(tstr); + int l = (int)strlen(tstr); if ((l < 29)||(l > 64)) return 0; int assigned = sscanf(tstr,"%3s, %02d %3s %4d %02d:%02d:%02d GMT",wdays,&t.tm_mday,mons,&t.tm_year,&t.tm_hour,&t.tm_min,&t.tm_sec); @@ -620,7 +620,7 @@ std::vector<std::string> Utils::split(const char *s,const char *const sep,const std::string Utils::trim(const std::string &s) { - unsigned long end = s.length(); + unsigned long end = (unsigned long)s.length(); while (end) { char c = s[end - 1]; if ((c == ' ')||(c == '\r')||(c == '\n')||(!c)||(c == '\t')) diff --git a/node/Utils.hpp b/node/Utils.hpp index ff88124b..1a3adec6 100644 --- a/node/Utils.hpp +++ b/node/Utils.hpp @@ -102,7 +102,7 @@ public: * @return Hexadecimal string */ static std::string hex(const void *data,unsigned int len); - static inline std::string hex(const std::string &data) { return hex(data.data(),data.length()); } + static inline std::string hex(const std::string &data) { return hex(data.data(),(unsigned int)data.length()); } /** * @param hex Hexadecimal ASCII code (non-hex chars are ignored) @@ -413,7 +413,7 @@ public: */ static inline bool writeFile(const char *path,const std::string &s) { - return writeFile(path,s.data(),s.length()); + return writeFile(path,s.data(),(unsigned int)s.length()); } /** @@ -422,7 +422,7 @@ public: * @return Base64-encoded string */ static std::string base64Encode(const void *data,unsigned int len); - inline static std::string base64Encode(const std::string &data) { return base64Encode(data.data(),data.length()); } + inline static std::string base64Encode(const std::string &data) { return base64Encode(data.data(),(unsigned int)data.length()); } /** * @param data Base64-encoded string @@ -430,7 +430,7 @@ public: * @return Decoded binary date */ static std::string base64Decode(const char *data,unsigned int len); - inline static std::string base64Decode(const std::string &data) { return base64Decode(data.data(),data.length()); } + inline static std::string base64Decode(const std::string &data) { return base64Decode(data.data(),(unsigned int)data.length()); } /** * Split a string by delimiter, with optional escape and quote characters |