Changeset: c7d9fbdb511e for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=c7d9fbdb511e
Modified Files:
monetdb5/modules/mal/mal_mapi.c
tools/merovingian/daemon/connections.c
Branch: Oct2020
Log Message:
For mserver5, listen to IPv4 and IPv6 sockets separately.
diffs (truncated from 646 to 300 lines):
diff --git a/monetdb5/modules/mal/mal_mapi.c b/monetdb5/modules/mal/mal_mapi.c
--- a/monetdb5/modules/mal/mal_mapi.c
+++ b/monetdb5/modules/mal/mal_mapi.c
@@ -272,60 +272,51 @@ static ATOMIC_TYPE threadno = ATOMIC_VAR
static void
SERVERlistenThread(SOCKET *Sock)
{
- char *msg = 0;
+ char *msg = NULL;
int retval;
- SOCKET sock = Sock[0];
- SOCKET usock = Sock[1];
- SOCKET msgsock = INVALID_SOCKET;
+ SOCKET socks[3] = {Sock[0], Sock[1], Sock[2]};
struct challengedata *data;
MT_Id tid;
stream *s;
+ int i;
GDKfree(Sock);
(void) ATOMIC_INC(&nlistener);
do {
+ SOCKET msgsock = INVALID_SOCKET;
#ifdef HAVE_POLL
- struct pollfd pfd[2];
+ struct pollfd pfd[3];
nfds_t npfd;
npfd = 0;
- if (sock != INVALID_SOCKET)
- pfd[npfd++] = (struct pollfd) {.fd = sock, .events =
POLLIN};
-#ifdef HAVE_SYS_UN_H
- if (usock != INVALID_SOCKET)
- pfd[npfd++] = (struct pollfd) {.fd = usock, .events =
POLLIN};
-#endif
+ for (i = 0; i < 3; i++) {
+ if (socks[i] != INVALID_SOCKET)
+ pfd[npfd++] = (struct pollfd) {.fd = socks[i],
+
.events = POLLIN};
+ }
/* Wait up to 0.1 seconds (0.01 if testing) */
retval = poll(pfd, npfd, GDKdebug & FORCEMITOMASK ? 10 : 100);
if (retval == -1 && errno == EINTR)
continue;
#else
- struct timeval tv;
fd_set fds;
FD_ZERO(&fds);
- if (sock != INVALID_SOCKET)
- FD_SET(sock, &fds);
-#ifdef HAVE_SYS_UN_H
- if (usock != INVALID_SOCKET)
- FD_SET(usock, &fds);
-#endif
+ /* temporarily use msgsock to record the highest socket fd */
+ for (i = 0; i < 3; i++) {
+ if (socks[i] != INVALID_SOCKET) {
+ FD_SET(socks[i], &fds);
+ if (msgsock == INVALID_SOCKET || socks[i] >
msgsock)
+ msgsock = socks[i];
+ }
+ }
/* Wait up to 0.1 seconds (0.01 if testing) */
- tv = (struct timeval) {
+ struct timeval tv = (struct timeval) {
.tv_usec = GDKdebug & FORCEMITOMASK ? 10000 : 100000,
};
- /* temporarily use msgsock to record the larger of sock and
usock */
-#ifdef _MSC_VER
- msgsock = 0; /* value is ignored on Windows
*/
-#else
- msgsock = sock;
-#ifdef HAVE_SYS_UN_H
- if (usock != INVALID_SOCKET && (sock == INVALID_SOCKET || usock
> sock))
- msgsock = usock;
-#endif
-#endif
- retval = select((int)msgsock + 1, &fds, NULL, NULL, &tv);
+ retval = select((int) msgsock + 1, &fds, NULL, NULL, &tv);
+ msgsock = INVALID_SOCKET;
#endif
if (ATOMIC_GET(&serverexiting) || GDKexiting())
break;
@@ -346,38 +337,45 @@ SERVERlistenThread(SOCKET *Sock)
}
continue;
}
- if (sock != INVALID_SOCKET &&
+ bool isusock = false;
#ifdef HAVE_POLL
- (npfd > 0 && pfd[0].fd == sock && pfd[0].revents &
POLLIN)
+ for (i = 0; i < (int) npfd; i++) {
+ if (pfd[i].revents & POLLIN) {
+ msgsock = pfd[i].fd;
+ isusock = msgsock == socks[2];
+ break;
+ }
+ }
#else
- FD_ISSET(sock, &fds)
+ for (i = 0; i < 3; i++) {
+ if (socks[i] >= 0 && FD_ISSET(socks[i], &fds)) {
+ msgsock = socks[i];
+ isusock = i == 2;
+ break;
+ }
+ }
#endif
- ) {
- if ((msgsock = accept4(sock, NULL, NULL, SOCK_CLOEXEC))
== INVALID_SOCKET) {
- if (
+ if (msgsock == INVALID_SOCKET)
+ continue;
+
+ if ((msgsock = accept4(msgsock, NULL, NULL, SOCK_CLOEXEC)) ==
INVALID_SOCKET) {
+ if (
#ifdef _MSC_VER
- WSAGetLastError() != WSAEINTR
+ WSAGetLastError() != WSAEINTR
#else
- errno != EINTR
+ errno != EINTR
#endif
- || !ATOMIC_GET(&serveractive)) {
- msg = "accept failed";
- goto error;
- }
- continue;
+ || !ATOMIC_GET(&serveractive)) {
+ msg = "accept failed";
+ goto error;
}
+ continue;
+ }
#if defined(HAVE_FCNTL) && (!defined(SOCK_CLOEXEC) || !defined(HAVE_ACCEPT4))
- (void) fcntl(msgsock, F_SETFD, FD_CLOEXEC);
+ (void) fcntl(msgsock, F_SETFD, FD_CLOEXEC);
#endif
#ifdef HAVE_SYS_UN_H
- } else if (usock != INVALID_SOCKET &&
-#ifdef HAVE_POLL
- ((npfd > 0 && pfd[0].fd == usock &&
pfd[0].revents & POLLIN) ||
- (npfd > 1 && pfd[1].fd == usock &&
pfd[1].revents & POLLIN))
-#else
- FD_ISSET(usock, &fds)
-#endif
- ) {
+ if (isusock) {
struct msghdr msgh;
struct iovec iov;
char buf[1];
@@ -385,23 +383,6 @@ SERVERlistenThread(SOCKET *Sock)
char ccmsg[CMSG_SPACE(sizeof(int))];
struct cmsghdr *cmsg;
- if ((msgsock = accept4(usock, NULL, NULL,
SOCK_CLOEXEC)) == INVALID_SOCKET) {
- if (
-#ifdef _MSC_VER
- WSAGetLastError() != WSAEINTR
-#else
- errno != EINTR
-#endif
- ) {
- msg = "accept failed";
- goto error;
- }
- continue;
- }
-#if defined(HAVE_FCNTL) && (!defined(SOCK_CLOEXEC) || !defined(HAVE_ACCEPT4))
- (void) fcntl(msgsock, F_SETFD, FD_CLOEXEC);
-#endif
-
/* BEWARE: unix domain sockets have a slightly different
* behaviour initialy than normal sockets, because we
can
* send filedescriptors or credentials with them. To
do so,
@@ -461,8 +442,6 @@ SERVERlistenThread(SOCKET *Sock)
continue;
}
#endif
- } else {
- continue;
}
data = GDKmalloc(sizeof(*data));
@@ -511,18 +490,14 @@ SERVERlistenThread(SOCKET *Sock)
continue;
}
} while (!ATOMIC_GET(&serverexiting) && !GDKexiting());
+ error:
(void) ATOMIC_DEC(&nlistener);
- if (sock != INVALID_SOCKET)
- closesocket(sock);
- if (usock != INVALID_SOCKET)
- closesocket(usock);
+ for (i = 0; i < 3; i++)
+ if (socks[i] != INVALID_SOCKET)
+ closesocket(socks[i]);
+ if (msg)
+ TRC_CRITICAL(MAL_SERVER, "Terminating listener: %s\n", msg);
return;
-error:
- TRC_CRITICAL(MAL_SERVER, "Terminating listener: %s\n", msg);
- if (sock != INVALID_SOCKET)
- closesocket(sock);
- if (usock != INVALID_SOCKET)
- closesocket(usock);
}
#ifdef _MSC_VER
@@ -542,13 +517,12 @@ start_listen(SOCKET *sockp, int *portp,
.ai_socktype = SOCK_STREAM,
.ai_protocol = IPPROTO_TCP,
};
- struct sockaddr_storage addr;
- SOCKLEN addrlen = (SOCKLEN) sizeof(addr);
int e = 0;
int ipv6_vs6only = -1;
SOCKET sock = INVALID_SOCKET;
const char *err;
- *sockp = INVALID_SOCKET;
+ int nsock = 0;
+ sockp[0] = sockp[1] = INVALID_SOCKET;
host[0] = 0;
if (listenaddr == NULL || strcmp(listenaddr, "localhost") == 0) {
hints.ai_family = AF_INET6;
@@ -583,110 +557,106 @@ start_listen(SOCKET *sockp, int *portp,
}
char sport[8]; /* max "65535" */
snprintf(sport, sizeof(sport), "%d", *portp);
- int check = getaddrinfo(listenaddr, sport, &hints, &result);
- if (check != 0 && ipv6_vs6only == 0) {
- /* if IPv6 didn't work and we can use IPv4 as well, try just
IPv4 */
- hints.ai_family = AF_INET;
- ipv6_vs6only = -1;
- if (listenaddr && strcmp(listenaddr, "::1") == 0)
- listenaddr = "127.0.0.1";
- check = getaddrinfo(listenaddr, sport, &hints, &result);
- }
- if (check != 0) {
-#ifdef _MSC_VER
- err = wsaerror(WSAGetLastError());
-#else
- err = gai_strerror(check);
-#endif
- throw(IO, "mal_mapi.listen", OPERATION_FAILED ": cannot get
address "
- "information for %s and port %s: %s",
- listenaddr ? listenaddr : hints.ai_family == AF_INET6
? "::" : "0.0.0.0",
- sport, err);
- }
-
- for (struct addrinfo *rp = result; rp; rp = rp->ai_next) {
- sock = socket(rp->ai_family, rp->ai_socktype
-#ifdef SOCK_CLOEXEC
- | SOCK_CLOEXEC
-#endif
- , rp->ai_protocol);
- if (sock == INVALID_SOCKET) {
-#ifdef _MSC_VER
- e = WSAGetLastError();
-#else
- e = errno;
-#endif
- continue;
- }
-#if defined(HAVE_FCNTL) && !defined(SOCK_CLOEXEC)
- (void) fcntl(sock, F_SETFD, FD_CLOEXEC);
-#endif
- if (ipv6_vs6only >= 0)
- if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY,
- (const char *)
&ipv6_vs6only, (SOCKLEN) sizeof(int)) == -1)
- perror("setsockopt IPV6_V6ONLY");
-
- /* do not reuse addresses for ephemeral (autosense) ports */
- if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
- (const char *) &(int){*portp != 0},
- (SOCKLEN) sizeof(int)) ==
SOCKET_ERROR) {
-#ifdef _MSC_VER
- e = WSAGetLastError();
-#else
- e = errno;
-#endif
- closesocket(sock);
- sock = INVALID_SOCKET;
- continue;
- }
- if (bind(sock, rp->ai_addr, (SOCKLEN) rp->ai_addrlen) ==
SOCKET_ERROR) {
-#ifdef _MSC_VER
- e = WSAGetLastError();
-#else
- e = errno;
-#endif
- closesocket(sock);
- sock = INVALID_SOCKET;
- if (e == EADDRNOTAVAIL && ipv6_vs6only == 0 &&
- (strcmp(listenaddr, "::") == 0 ||
- strcmp(listenaddr, "::1") == 0)) {
- /* IPv6 failed, maybe just IPv4 will work */
- freeaddrinfo(result);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list