Commit f79b85a6 authored by Alex Hultman's avatar Alex Hultman
Browse files

Begin new networking wrapper, set SOCK_CLOEXEC on Linux & FreeBSD

parent aad7447d
......@@ -145,7 +145,7 @@ void Group<isServer>::stopListening() {
} else if (listenData->listenTimer) {
uv_os_sock_t fd = listenData->sock;
listenData->listenTimer->stop();
::close(fd);
uS::Networking::closeSocket(fd);
SSL *ssl = listenData->ssl;
if (ssl) {
......
......@@ -23,6 +23,7 @@
#define NOMINMAX
#include <WinSock2.h>
#include <Ws2tcpip.h>
#pargma comment(lib, "ws2_32.lib")
#define SHUT_WR SD_SEND
#ifdef __MINGW32__
// Windows has always been tied to LE
......@@ -73,6 +74,38 @@ inline SOCKET dup(SOCKET socket) {
namespace uS {
// todo: mark sockets nonblocking in these functions
struct Networking {
// returns INVALID_SOCKET on error
static uv_os_sock_t acceptSocket(uv_os_sock_t fd) {
#if defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK)
// Linux, FreeBSD
return accept4(fd, nullptr, nullptr, SOCK_CLOEXEC | SOCK_NONBLOCK);
#else
// Windows, OS X
return accept(fd, nullptr, nullptr);
#endif
}
// returns INVALID_SOCKET on error
static uv_os_sock_t createSocket(int domain, int type, int protocol) {
int flags = 0;
#if defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK)
flags = SOCK_CLOEXEC | SOCK_NONBLOCK;
#endif
return socket(domain, type | flags, protocol);
}
static void closeSocket(uv_os_sock_t fd) {
#ifdef _WIN32
closesocket(fd);
#else
close(fd);
#endif
}
};
namespace TLS {
class WIN32_EXPORT Context {
......
......@@ -85,7 +85,7 @@ public:
template <void A(Socket *s), bool TIMER>
static void accept_cb(ListenData *listenData) {
uv_os_sock_t serverFd = listenData->sock;
uv_os_sock_t clientFd = accept(serverFd, nullptr, nullptr);
uv_os_sock_t clientFd = Networking::acceptSocket(serverFd);
// if (clientFd == INVALID_SOCKET) {
// /*
// * If accept is failing, the pending connection won't be removed and the
......@@ -129,7 +129,7 @@ public:
Socket *socket = new Socket(listenData->nodeData, listenData->nodeData->loop, clientFd, ssl);
socket->setPoll(UV_READABLE);
A(socket);
} while ((clientFd = accept(serverFd, nullptr, nullptr)) != INVALID_SOCKET);
} while ((clientFd = Networking::acceptSocket(serverFd)) != INVALID_SOCKET);
}
// todo: hostname, backlog
......@@ -151,7 +151,7 @@ public:
if ((options & uS::ONLY_IPV4) == 0) {
for (addrinfo *a = result; a && listenFd == SOCKET_ERROR; a = a->ai_next) {
if (a->ai_family == AF_INET6) {
listenFd = socket(a->ai_family, a->ai_socktype, a->ai_protocol);
listenFd = Networking::createSocket(a->ai_family, a->ai_socktype, a->ai_protocol);
listenAddr = a;
}
}
......@@ -159,7 +159,7 @@ public:
for (addrinfo *a = result; a && listenFd == SOCKET_ERROR; a = a->ai_next) {
if (a->ai_family == AF_INET) {
listenFd = socket(a->ai_family, a->ai_socktype, a->ai_protocol);
listenFd = Networking::createSocket(a->ai_family, a->ai_socktype, a->ai_protocol);
listenAddr = a;
}
}
......@@ -182,7 +182,7 @@ public:
setsockopt(listenFd, SOL_SOCKET, SO_REUSEADDR, &enabled, sizeof(enabled));
if (bind(listenFd, listenAddr->ai_addr, listenAddr->ai_addrlen) || ::listen(listenFd, 512)) {
::close(listenFd);
Networking::closeSocket(listenFd);
freeaddrinfo(result);
return true;
}
......
......@@ -325,7 +325,7 @@ struct WIN32_EXPORT Socket : Poll {
void closeSocket() {
uv_os_sock_t fd = getFd();
stop(nodeData->loop);
::close(fd);
Networking::closeSocket(fd);
if (ssl) {
SSL_free(ssl);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment