Forráskód Böngészése

Fix TCP connection accumulation problem, still having issues with TCP tunneling.

Adam Ierymenko 11 éve
szülő
commit
2ac56fd120
7 módosított fájl, 44 hozzáadás és 44 törlés
  1. 17 15
      node/InetAddress.cpp
  2. 3 2
      node/Node.cpp
  3. 2 0
      node/Peer.cpp
  4. 5 0
      node/RuntimeEnvironment.hpp
  5. 5 5
      node/SocketManager.cpp
  6. 10 20
      node/TcpSocket.cpp
  7. 2 2
      node/Utils.cpp

+ 17 - 15
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

+ 3 - 2
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<Peer> > sns(_r->topology->supernodePeers());
 				TRACE("pinging %d supernodes",(int)sns.size());

+ 2 - 0
node/Peer.cpp

@@ -69,6 +69,8 @@ void Peer::receive(
 	Packet::Verb inReVerb,
 	uint64_t now)
 {
+	*((const_cast<uint64_t *>(&(_r->timeOfLastPacketReceived)))) = now;
+
 	if (!hops) { // direct packet
 		{
 			Mutex::Lock _l(_lock);

+ 5 - 0
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

+ 5 - 5
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)

+ 10 - 20
node/TcpSocket.cpp

@@ -164,32 +164,22 @@ bool TcpSocket::notifyAvailableForWrite(const SharedPtr<Socket> &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)

+ 2 - 2
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);