summaryrefslogtreecommitdiff
path: root/node
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2014-03-20 13:21:58 -0700
committerAdam Ierymenko <adam.ierymenko@gmail.com>2014-03-20 13:21:58 -0700
commit6f5a4d7e2984916379b11d688ccc54cac473239e (patch)
tree16966056d2e1a8cbbf23390ff74be943df39ebcb /node
parent4d0ad9abb654d3b987148f024ffeb1a04da2b574 (diff)
downloadinfinitytier-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.cpp2
-rw-r--r--node/Node.cpp9
-rw-r--r--node/SocketManager.cpp55
-rw-r--r--node/Switch.cpp3
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);