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 checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list