From 2ac56fd120c3c9dd924fccc169beed2d51658ba9 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Wed, 26 Mar 2014 17:59:45 -0700 Subject: [PATCH] Fix TCP connection accumulation problem, still having issues with TCP tunneling. --- node/InetAddress.cpp | 32 +++++++++++++++++--------------- node/Node.cpp | 5 +++-- node/Peer.cpp | 2 ++ node/RuntimeEnvironment.hpp | 5 +++++ node/SocketManager.cpp | 10 +++++----- node/TcpSocket.cpp | 30 ++++++++++-------------------- node/Utils.cpp | 4 ++-- 7 files changed, 44 insertions(+), 44 deletions(-) diff --git a/node/InetAddress.cpp b/node/InetAddress.cpp index 349646cbc..0a7dd88cb 100644 --- a/node/InetAddress.cpp +++ b/node/InetAddress.cpp @@ -141,27 +141,29 @@ bool InetAddress::operator==(const InetAddress &a) const return (!memcmp(_sa.sin6.sin6_addr.s6_addr,a._sa.sin6.sin6_addr.s6_addr,sizeof(_sa.sin6.sin6_addr.s6_addr))); } return false; - } else if (!_sa.saddr.sa_family) - return (!a._sa.saddr.sa_family); - return (!memcmp(&_sa,&a._sa,sizeof(_sa))); + } else return (memcmp(&_sa,&a._sa,sizeof(_sa)) == 0); } bool InetAddress::operator<(const InetAddress &a) const throw() { - if (_sa.saddr.sa_family == AF_INET) { - if (a._sa.saddr.sa_family == AF_INET) - return ((ntohl(_sa.sin.sin_addr.s_addr < ntohl(a._sa.sin.sin_addr.s_addr)))||((_sa.sin.sin_addr.s_addr == a._sa.sin.sin_addr.s_addr)&&(ntohs(_sa.sin.sin_port) < ntohs(a._sa.sin.sin_port)))); - else if (a._sa.saddr.sa_family == AF_INET6) - return true; - } else if (_sa.saddr.sa_family == AF_INET6) { - if (a._sa.saddr.sa_family == AF_INET6) { - int cmp = memcmp(_sa.sin6.sin6_addr.s6_addr,a._sa.sin6.sin6_addr.s6_addr,16); - return ((cmp < 0)||((!cmp)&&(ntohs(_sa.sin6.sin6_port) < ntohs(a._sa.sin6.sin6_port)))); - } else if (a._sa.saddr.sa_family == AF_INET) - return false; + if (_sa.saddr.sa_family < a._sa.saddr.sa_family) + return true; + else if (_sa.saddr.sa_family == a._sa.saddr.sa_family) { + if (_sa.saddr.sa_family == AF_INET) { + unsigned long x = ntohl(_sa.sin.sin_addr.s_addr); + unsigned long y = ntohl(a._sa.sin.sin_addr.s_addr); + if (x == y) + return (ntohs(_sa.sin.sin_port) < ntohs(a._sa.sin.sin_port)); + else return (x < y); + } else if (_sa.saddr.sa_family == AF_INET6) { + int cmp = (int)memcmp(_sa.sin6.sin6_addr.s6_addr,a._sa.sin6.sin6_addr.s6_addr,16); + if (cmp == 0) + return (ntohs(_sa.sin6.sin6_port) < ntohs(a._sa.sin6.sin6_port)); + else return (cmp < 0); + } else return (memcmp(&_sa,&a._sa,sizeof(_sa)) < 0); } - return (_sa.saddr.sa_family < a._sa.saddr.sa_family); + return false; } } // namespace ZeroTier diff --git a/node/Node.cpp b/node/Node.cpp index 20a049bcf..95e4bb1df 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -577,8 +577,9 @@ Node::ReasonForTermination Node::run() } // Ping supernodes separately for two reasons: (1) supernodes only ping each - // other, and (2) we still want to ping them first on resynchronize. - if ((resynchronize)||((now - lastSupernodePing) >= ZT_PEER_DIRECT_PING_DELAY)) { + // other, and (2) we still want to ping them first on resynchronize. Also ping + // more aggressively if nothing seems to be happening at all. + if ((resynchronize)||((now - lastSupernodePing) >= ZT_PEER_DIRECT_PING_DELAY)||((now - _r->timeOfLastPacketReceived) >= ZT_PING_UNANSWERED_AFTER)) { lastSupernodePing = now; std::vector< SharedPtr > sns(_r->topology->supernodePeers()); TRACE("pinging %d supernodes",(int)sns.size()); diff --git a/node/Peer.cpp b/node/Peer.cpp index 0cd829098..fa8ab3e8f 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -69,6 +69,8 @@ void Peer::receive( Packet::Verb inReVerb, uint64_t now) { + *((const_cast(&(_r->timeOfLastPacketReceived)))) = now; + if (!hops) { // direct packet { Mutex::Lock _l(_lock); diff --git a/node/RuntimeEnvironment.hpp b/node/RuntimeEnvironment.hpp index ffa6cbdb3..29693c559 100644 --- a/node/RuntimeEnvironment.hpp +++ b/node/RuntimeEnvironment.hpp @@ -65,6 +65,7 @@ public: RuntimeEnvironment() : shutdownInProgress(false), timeOfLastNetworkEnvironmentChange(0), + timeOfLastPacketReceived(0), log((Logger *)0), prng((CMWC4096 *)0), mc((Multicaster *)0), @@ -92,6 +93,10 @@ public: // Time network environment (e.g. fingerprint) last changed -- used to determine online-ness volatile uint64_t timeOfLastNetworkEnvironmentChange; + // Time last packet was received -- from anywhere. This is updated in Peer::receive() + // via an ugly const_cast<>. + volatile uint64_t timeOfLastPacketReceived; + /* * Order matters a bit here. These are constructed in this order * and then deleted in the opposite order on Node exit. The order ensures diff --git a/node/SocketManager.cpp b/node/SocketManager.cpp index 2f6eb4fba..893e17d12 100644 --- a/node/SocketManager.cpp +++ b/node/SocketManager.cpp @@ -395,17 +395,17 @@ bool SocketManager::send(const InetAddress &to,bool tcp,const void *msg,unsigned if (!ts->send(to,msg,msglen)) return false; + { + Mutex::Lock _l(_tcpSockets_m); + _tcpSockets[to] = ts; + } + _fdSetLock.lock(); FD_SET(s,&_readfds); if (connecting) FD_SET(s,&_writefds); _fdSetLock.unlock(); - { - Mutex::Lock _l(_tcpSockets_m); - _tcpSockets[to] = ts; - } - return true; } else if (to.isV4()) { if (_udpV4Socket) diff --git a/node/TcpSocket.cpp b/node/TcpSocket.cpp index a422dec6f..b56775d8e 100644 --- a/node/TcpSocket.cpp +++ b/node/TcpSocket.cpp @@ -164,32 +164,22 @@ bool TcpSocket::notifyAvailableForWrite(const SharedPtr &self,SocketMana if (_outptr) { int n = (int)::send(_sock,(const char *)_outbuf,_outptr,0); - if (n < 0) { + if (n <= 0) { switch(errno) { -#ifdef EBADF - case EBADF: +#ifdef EAGAIN + case EAGAIN: #endif -#ifdef EINVAL - case EINVAL: +#if defined(EWOULDBLOCK) && ( !defined(EAGAIN) || (EWOULDBLOCK != EAGAIN) ) + case EWOULDBLOCK: #endif -#ifdef ENOTSOCK - case ENOTSOCK: +#ifdef EINTR + case EINTR: #endif -#ifdef ECONNRESET - case ECONNRESET: -#endif -#ifdef EPIPE - case EPIPE: -#endif -#ifdef ENETDOWN - case ENETDOWN: -#endif - return false; - default: break; + default: + return false; } - } else if (n > 0) - memmove(_outbuf,_outbuf + (unsigned int)n,_outptr -= (unsigned int)n); + } else memmove(_outbuf,_outbuf + (unsigned int)n,_outptr -= (unsigned int)n); } if (!_outptr) diff --git a/node/Utils.cpp b/node/Utils.cpp index fe153af20..95b66337e 100644 --- a/node/Utils.cpp +++ b/node/Utils.cpp @@ -207,11 +207,11 @@ void Utils::getSecureRandom(void *buf,unsigned int bytes) { int fd = ::open("/dev/urandom",O_RDONLY); if (fd < 0) { - fprintf(stderr,"FATAL ERROR: unable to open /dev/urandom%s",ZT_EOL_S); + fprintf(stderr,"FATAL ERROR: unable to open /dev/urandom (%d)"ZT_EOL_S,errno); exit(-1); } if ((int)::read(fd,randbuf,sizeof(randbuf)) != (int)sizeof(randbuf)) { - fprintf(stderr,"FATAL ERROR: unable to read from /dev/urandom%s",ZT_EOL_S); + fprintf(stderr,"FATAL ERROR: unable to read from /dev/urandom"ZT_EOL_S); exit(-1); } ::close(fd);