mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2024-12-24 15:16:40 +00:00
Bug fixes.
This commit is contained in:
parent
1c555e4b96
commit
15e8c18106
@ -38,6 +38,8 @@
|
|||||||
#else
|
#else
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -56,29 +58,29 @@ IpcListener::IpcListener(const char *ep,void (*commandHandler)(void *,IpcConnect
|
|||||||
strncpy(unaddr.sun_path,_endpoint.c_str(),sizeof(unaddr.sun_path));
|
strncpy(unaddr.sun_path,_endpoint.c_str(),sizeof(unaddr.sun_path));
|
||||||
unaddr.sun_path[sizeof(unaddr.sun_path) - 1] = (char)0;
|
unaddr.sun_path[sizeof(unaddr.sun_path) - 1] = (char)0;
|
||||||
|
|
||||||
for(int tries=0;tries<3;++tries) {
|
struct stat stattmp;
|
||||||
_sock = socket(AF_UNIX,SOCK_STREAM,0);
|
if (stat(_endpoint.c_str(),&stattmp)) {
|
||||||
if (_sock <= 0)
|
|
||||||
throw std::runtime_error("unable to create socket of type AF_UNIX");
|
|
||||||
if (bind(_sock,(struct sockaddr *)&unaddr,sizeof(unaddr))) {
|
|
||||||
::close(_sock);
|
|
||||||
if (errno == EADDRINUSE) {
|
|
||||||
int testSock = socket(AF_UNIX,SOCK_STREAM,0);
|
int testSock = socket(AF_UNIX,SOCK_STREAM,0);
|
||||||
if (testSock <= 0)
|
if (testSock <= 0)
|
||||||
throw std::runtime_error("unable to create socket of type AF_UNIX");
|
throw std::runtime_error("unable to create socket of type AF_UNIX");
|
||||||
if (connect(testSock,(struct sockaddr *)&unaddr,sizeof(unaddr))) {
|
if (connect(testSock,(struct sockaddr *)&unaddr,sizeof(unaddr))) {
|
||||||
// error indicates nothing is listening on other end, so unlink and try again
|
// error means nothing is listening, orphaned name
|
||||||
::close(testSock);
|
::close(testSock);
|
||||||
unlink(_endpoint.c_str());
|
|
||||||
} else {
|
} else {
|
||||||
// success means endpoint is being actively listened to by a process
|
// success means endpoint is being actively listened to by a process
|
||||||
::close(testSock);
|
::close(testSock);
|
||||||
throw std::runtime_error("IPC endpoint address in use");
|
throw std::runtime_error("IPC endpoint address in use");
|
||||||
}
|
}
|
||||||
} else throw std::runtime_error("IPC endpoint could not be bound");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
::unlink(_endpoint.c_str());
|
||||||
|
|
||||||
|
_sock = socket(AF_UNIX,SOCK_STREAM,0);
|
||||||
|
if (_sock <= 0)
|
||||||
|
throw std::runtime_error("unable to create socket of type AF_UNIX");
|
||||||
|
if (bind(_sock,(struct sockaddr *)&unaddr,sizeof(unaddr))) {
|
||||||
|
::close(_sock);
|
||||||
|
throw std::runtime_error("IPC endpoint could not be bound");
|
||||||
|
}
|
||||||
if (listen(_sock,8)) {
|
if (listen(_sock,8)) {
|
||||||
::close(_sock);
|
::close(_sock);
|
||||||
throw std::runtime_error("listen() failed for bound AF_UNIX socket");
|
throw std::runtime_error("listen() failed for bound AF_UNIX socket");
|
||||||
|
@ -316,6 +316,8 @@ SocketManager::SocketManager(
|
|||||||
_udpV4Socket = SharedPtr<Socket>(new UdpSocket(Socket::ZT_SOCKET_TYPE_UDP_V4,s));
|
_udpV4Socket = SharedPtr<Socket>(new UdpSocket(Socket::ZT_SOCKET_TYPE_UDP_V4,s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_updateNfds();
|
||||||
}
|
}
|
||||||
|
|
||||||
SocketManager::~SocketManager()
|
SocketManager::~SocketManager()
|
||||||
@ -370,7 +372,7 @@ void SocketManager::poll(unsigned long timeout)
|
|||||||
|
|
||||||
tv.tv_sec = (long)(timeout / 1000);
|
tv.tv_sec = (long)(timeout / 1000);
|
||||||
tv.tv_usec = (long)((timeout % 1000) * 1000);
|
tv.tv_usec = (long)((timeout % 1000) * 1000);
|
||||||
select(_nfds,&rfds,&wfds,&efds,(timeout > 0) ? &tv : (struct timeval *)0);
|
select(_nfds + 1,&rfds,&wfds,&efds,(timeout > 0) ? &tv : (struct timeval *)0);
|
||||||
|
|
||||||
if (FD_ISSET(_whackReceivePipe,&rfds)) {
|
if (FD_ISSET(_whackReceivePipe,&rfds)) {
|
||||||
char tmp[32];
|
char tmp[32];
|
||||||
@ -396,6 +398,8 @@ void SocketManager::poll(unsigned long timeout)
|
|||||||
_fdSetLock.lock();
|
_fdSetLock.lock();
|
||||||
FD_SET(sockfd,&_readfds);
|
FD_SET(sockfd,&_readfds);
|
||||||
_fdSetLock.unlock();
|
_fdSetLock.unlock();
|
||||||
|
if (sockfd > _nfds)
|
||||||
|
_nfds = sockfd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((_tcpV6ListenSocket != INVALID_SOCKET)&&(FD_ISSET(_tcpV6ListenSocket,&rfds))) {
|
if ((_tcpV6ListenSocket != INVALID_SOCKET)&&(FD_ISSET(_tcpV6ListenSocket,&rfds))) {
|
||||||
@ -413,6 +417,8 @@ void SocketManager::poll(unsigned long timeout)
|
|||||||
_fdSetLock.lock();
|
_fdSetLock.lock();
|
||||||
FD_SET(sockfd,&_readfds);
|
FD_SET(sockfd,&_readfds);
|
||||||
_fdSetLock.unlock();
|
_fdSetLock.unlock();
|
||||||
|
if (sockfd > _nfds)
|
||||||
|
_nfds = sockfd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -421,6 +427,7 @@ void SocketManager::poll(unsigned long timeout)
|
|||||||
if ((_udpV6Socket)&&(FD_ISSET(_udpV6Socket->_sock,&rfds)))
|
if ((_udpV6Socket)&&(FD_ISSET(_udpV6Socket->_sock,&rfds)))
|
||||||
_udpV6Socket->notifyAvailableForRead(_udpV6Socket,this);
|
_udpV6Socket->notifyAvailableForRead(_udpV6Socket,this);
|
||||||
|
|
||||||
|
bool closedSockets = false;
|
||||||
{ // grab copy of TCP sockets list because _tcpSockets[] might be changed in a handler
|
{ // grab copy of TCP sockets list because _tcpSockets[] might be changed in a handler
|
||||||
Mutex::Lock _l2(_tcpSockets_m);
|
Mutex::Lock _l2(_tcpSockets_m);
|
||||||
if (_tcpSockets.size()) {
|
if (_tcpSockets.size()) {
|
||||||
@ -436,6 +443,7 @@ void SocketManager::poll(unsigned long timeout)
|
|||||||
FD_CLR(s->second->_sock,&_writefds);
|
FD_CLR(s->second->_sock,&_writefds);
|
||||||
_fdSetLock.unlock();
|
_fdSetLock.unlock();
|
||||||
_tcpSockets.erase(s++);
|
_tcpSockets.erase(s++);
|
||||||
|
closedSockets = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -451,6 +459,7 @@ void SocketManager::poll(unsigned long timeout)
|
|||||||
FD_CLR((*s)->_sock,&_readfds);
|
FD_CLR((*s)->_sock,&_readfds);
|
||||||
FD_CLR((*s)->_sock,&_writefds);
|
FD_CLR((*s)->_sock,&_writefds);
|
||||||
_fdSetLock.unlock();
|
_fdSetLock.unlock();
|
||||||
|
closedSockets = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -464,10 +473,13 @@ void SocketManager::poll(unsigned long timeout)
|
|||||||
FD_CLR((*s)->_sock,&_readfds);
|
FD_CLR((*s)->_sock,&_readfds);
|
||||||
FD_CLR((*s)->_sock,&_writefds);
|
FD_CLR((*s)->_sock,&_writefds);
|
||||||
_fdSetLock.unlock();
|
_fdSetLock.unlock();
|
||||||
|
closedSockets = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (closedSockets)
|
||||||
|
_updateNfds();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocketManager::whack()
|
void SocketManager::whack()
|
||||||
|
@ -169,6 +169,27 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void _updateNfds()
|
||||||
|
{
|
||||||
|
int nfds = _whackSendPipe;
|
||||||
|
if (_whackReceivePipe > nfds)
|
||||||
|
nfds = _whackReceivePipe;
|
||||||
|
if (_tcpV4ListenSocket > nfds)
|
||||||
|
nfds = _tcpV4ListenSocket;
|
||||||
|
if (_tcpV6ListenSocket > nfds)
|
||||||
|
nfds = _tcpV6ListenSocket;
|
||||||
|
if ((_udpV4Socket)&&(_udpV4Socket->_sock > nfds))
|
||||||
|
nfds = _udpV4Socket->_sock;
|
||||||
|
if ((_udpV6Socket)&&(_udpV6Socket->_sock > nfds))
|
||||||
|
nfds = _udpV6Socket->_sock;
|
||||||
|
Mutex::Lock _l(_tcpSockets_m);
|
||||||
|
for(std::map< InetAddress,SharedPtr<Socket> >::const_iterator s(_tcpSockets.begin());s!=_tcpSockets.end();++s) {
|
||||||
|
if (s->second->_sock > nfds)
|
||||||
|
nfds = s->second->_sock;
|
||||||
|
}
|
||||||
|
_nfds = nfds;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
SOCKET _whackSendPipe;
|
SOCKET _whackSendPipe;
|
||||||
SOCKET _whackReceivePipe;
|
SOCKET _whackReceivePipe;
|
||||||
@ -187,7 +208,7 @@ private:
|
|||||||
|
|
||||||
fd_set _readfds;
|
fd_set _readfds;
|
||||||
fd_set _writefds;
|
fd_set _writefds;
|
||||||
int _nfds;
|
volatile int _nfds;
|
||||||
Mutex _fdSetLock;
|
Mutex _fdSetLock;
|
||||||
|
|
||||||
std::map< InetAddress,SharedPtr<Socket> > _tcpSockets;
|
std::map< InetAddress,SharedPtr<Socket> > _tcpSockets;
|
||||||
|
Loading…
Reference in New Issue
Block a user