diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2014-03-20 13:21:58 -0700 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2014-03-20 13:21:58 -0700 |
commit | 6f5a4d7e2984916379b11d688ccc54cac473239e (patch) | |
tree | 16966056d2e1a8cbbf23390ff74be943df39ebcb /node | |
parent | 4d0ad9abb654d3b987148f024ffeb1a04da2b574 (diff) | |
download | infinitytier-6f5a4d7e2984916379b11d688ccc54cac473239e.tar.gz infinitytier-6f5a4d7e2984916379b11d688ccc54cac473239e.zip |
Fix blocking socket issues in new socket I/O code.
Diffstat (limited to 'node')
-rw-r--r-- | node/Network.cpp | 2 | ||||
-rw-r--r-- | node/Node.cpp | 9 | ||||
-rw-r--r-- | node/SocketManager.cpp | 55 | ||||
-rw-r--r-- | node/Switch.cpp | 3 |
4 files changed, 50 insertions, 19 deletions
diff --git a/node/Network.cpp b/node/Network.cpp index a119ac9c..88c169b2 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -179,7 +179,7 @@ void Network::addMembershipCertificate(const CertificateOfMembership &cert) CertificateOfMembership &old = _membershipCertificates[cert.issuedTo()]; if (cert.timestamp() >= old.timestamp()) { - TRACE("got new certificate for %s on network %.16llx",cert.issuedTo().toString().c_str(),cert.networkId()); + //TRACE("got new certificate for %s on network %.16llx",cert.issuedTo().toString().c_str(),cert.networkId()); old = cert; } } diff --git a/node/Node.cpp b/node/Node.cpp index 653d63cf..21d78f54 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -230,15 +230,24 @@ struct _NodeImpl #ifndef __WINDOWS__ delete renv.netconfService; + TRACE("shutdown: delete netconfService"); #endif delete renv.updater; + TRACE("shutdown: delete updater"); delete renv.nc; + TRACE("shutdown: delete nc"); delete renv.sysEnv; + TRACE("shutdown: delete sysEnv"); delete renv.topology; + TRACE("shutdown: delete topology"); delete renv.sm; + TRACE("shutdown: delete sm"); delete renv.sw; + TRACE("shutdown: delete sw"); delete renv.mc; + TRACE("shutdown: delete mc"); delete renv.prng; + TRACE("shutdown: delete prng"); delete renv.log; return reasonForTermination; diff --git a/node/SocketManager.cpp b/node/SocketManager.cpp index c21b612f..c2261e7a 100644 --- a/node/SocketManager.cpp +++ b/node/SocketManager.cpp @@ -45,7 +45,7 @@ // Allow us to use the same value on Windows and *nix #ifndef INVALID_SOCKET -#define INVALID_SOCKET 0 +#define INVALID_SOCKET (-1) #endif namespace ZeroTier { @@ -107,6 +107,7 @@ SocketManager::SocketManager( _whackReceivePipe = tmpfds[0]; } #endif + fcntl(_whackReceivePipe,F_SETFL,O_NONBLOCK); FD_SET(_whackReceivePipe,&_readfds); if (localTcpPort > 0) { @@ -142,6 +143,7 @@ SocketManager::SocketManager( f = 1; ::setsockopt(_tcpV6ListenSocket,SOL_SOCKET,SO_REUSEADDR,(void *)&f,sizeof(f)); } #endif + fcntl(_tcpV6ListenSocket,F_SETFL,O_NONBLOCK); struct sockaddr_in6 sin6; memset(&sin6,0,sizeof(sin6)); @@ -184,6 +186,7 @@ SocketManager::SocketManager( int f = 1; ::setsockopt(_tcpV4ListenSocket,SOL_SOCKET,SO_REUSEADDR,(void *)&f,sizeof(f)); } #endif + fcntl(_tcpV4ListenSocket,F_SETFL,O_NONBLOCK); struct sockaddr_in sin4; memset(&sin4,0,sizeof(sin4)); @@ -262,8 +265,8 @@ SocketManager::SocketManager( throw std::runtime_error("unable to bind to port"); } - FD_SET(s,&_readfds); _udpV6Socket = SharedPtr<Socket>(new UdpSocket(Socket::ZT_SOCKET_TYPE_UDP_V6,s)); + FD_SET(s,&_readfds); } { // bind UDP IPv4 @@ -312,8 +315,8 @@ SocketManager::SocketManager( throw std::runtime_error("unable to bind to port"); } - FD_SET(s,&_readfds); _udpV4Socket = SharedPtr<Socket>(new UdpSocket(Socket::ZT_SOCKET_TYPE_UDP_V4,s)); + FD_SET(s,&_readfds); } } @@ -375,11 +378,11 @@ void SocketManager::poll(unsigned long timeout) select(_nfds + 1,&rfds,&wfds,&efds,(timeout > 0) ? &tv : (struct timeval *)0); if (FD_ISSET(_whackReceivePipe,&rfds)) { - char tmp[32]; + char tmp; #ifdef __WINDOWS__ - ::recv(_whackReceivePipe,tmp,sizeof(tmp),0); + ::recv(_whackReceivePipe,&tmp,1,0); #else - ::read(_whackReceivePipe,tmp,sizeof(tmp)); + ::read(_whackReceivePipe,&tmp,1); #endif } @@ -394,12 +397,20 @@ void SocketManager::poll(unsigned long timeout) #endif InetAddress fromia((const struct sockaddr *)&from); Mutex::Lock _l2(_tcpSockets_m); - _tcpSockets[fromia] = SharedPtr<Socket>(new TcpSocket(this,sockfd,false,fromia)); - _fdSetLock.lock(); - FD_SET(sockfd,&_readfds); - _fdSetLock.unlock(); - if (sockfd > _nfds) - _nfds = sockfd; + try { + _tcpSockets[fromia] = SharedPtr<Socket>(new TcpSocket(this,sockfd,false,fromia)); + + fcntl(sockfd,F_SETFL,O_NONBLOCK); + + _fdSetLock.lock(); + FD_SET(sockfd,&_readfds); + _fdSetLock.unlock(); + + if (sockfd > _nfds) + _nfds = sockfd; + } catch ( ... ) { + ::close(sockfd); + } } } if ((_tcpV6ListenSocket != INVALID_SOCKET)&&(FD_ISSET(_tcpV6ListenSocket,&rfds))) { @@ -413,12 +424,20 @@ void SocketManager::poll(unsigned long timeout) #endif InetAddress fromia((const struct sockaddr *)&from); Mutex::Lock _l2(_tcpSockets_m); - _tcpSockets[fromia] = SharedPtr<Socket>(new TcpSocket(this,sockfd,false,fromia)); - _fdSetLock.lock(); - FD_SET(sockfd,&_readfds); - _fdSetLock.unlock(); - if (sockfd > _nfds) - _nfds = sockfd; + try { + _tcpSockets[fromia] = SharedPtr<Socket>(new TcpSocket(this,sockfd,false,fromia)); + + fcntl(sockfd,F_SETFL,O_NONBLOCK); + + _fdSetLock.lock(); + FD_SET(sockfd,&_readfds); + _fdSetLock.unlock(); + + if (sockfd > _nfds) + _nfds = sockfd; + } catch ( ... ) { + ::close(sockfd); + } } } diff --git a/node/Switch.cpp b/node/Switch.cpp index a59473b7..351034b2 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -155,6 +155,9 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c outp.append((uint16_t)sig.size()); outp.append(sig.data,(unsigned int)sig.size()); + // FIXME: now we send the netconf cert with every single multicast, + // which pretty much ensures everyone has it ahead of time but adds + // some redundant payload. Maybe think abouut this in the future. if (nconf->com()) nconf->com().serialize(outp); |