Changeset: 32cf70aec25e for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=32cf70aec25e
Modified Files:
monetdb5/modules/mal/mal_mapi.c
tools/merovingian/daemon/forkmserver.c
tools/merovingian/utils/properties.c
Branch: ipv6
Log Message:
Added property "mapi_listenaddr". Mserver5 can now bind to a specific interface
if this property is provided.
diffs (truncated from 433 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
@@ -523,6 +523,7 @@ SERVERlisten(int *Port, str *Usockfile,
char *usockfile;
str buf;
char host[128];
+ const char *listenaddr;
#ifdef DEBUG_SERVER
char msg[512], host[512];
Client cntxt= mal_clients;
@@ -531,12 +532,17 @@ SERVERlisten(int *Port, str *Usockfile,
accept_any = GDKgetenv_istrue("mapi_open");
bind_ipv6 = GDKgetenv_istrue("mapi_ipv6");
autosense = GDKgetenv_istrue("mapi_autosense");
+ listenaddr = GDKgetenv("mapi_listenaddr");
/* early way out, we do not want to listen on any port when running in
embedded mode */
if (GDKgetenv_istrue("mapi_disable")) {
return MAL_SUCCEED;
}
+ if (listenaddr && accept_any)
+ throw(ILLARG,"mal_mapi.listen", OPERATION_FAILED
+ ":
mapi_open and mapi_listenaddr cannot be set at the same time");
+
psock = GDKmalloc(sizeof(SOCKET) * 3);
if (psock == NULL)
throw(MAL,"mal_mapi.listen", SQLSTATE(HY001) MAL_MALLOC_FAIL);
@@ -574,117 +580,208 @@ SERVERlisten(int *Port, str *Usockfile,
}
if (port > 0) {
- sock = socket(bind_ipv6 ? AF_INET6 : AF_INET, SOCK_STREAM
+ if (listenaddr && *listenaddr) {
+ int check = 0;
+ char sport[16];
+ struct addrinfo *result = NULL, *rp = NULL, hints =
(struct addrinfo) {
+ .ai_family = bind_ipv6 ? AF_INET6 : AF_INET,
+ .ai_socktype = SOCK_STREAM,
+ .ai_flags = AI_PASSIVE,
+ .ai_protocol = IPPROTO_TCP,
+ };
+
+ do {
+ bool ok = false;
+ snprintf(sport, 16, "%d", port);
+ check = getaddrinfo(listenaddr, sport, &hints,
&result);
+ if (check != 0) {
+ if (autosense && port <= 65535) {
+ port++;
+ continue;
+ }
+ GDKfree(psock);
+ GDKfree(usockfile);
+ throw(IO, "mal_mapi.listen",
OPERATION_FAILED
+ ": bind to stream
socket on address %s and port %d failed: %s", listenaddr, port,
+ gai_strerror(check));
+ }
+
+ for (rp = result; rp != NULL; rp = rp->ai_next)
{
+ sock = socket(rp->ai_family,
rp->ai_socktype
#ifdef SOCK_CLOEXEC
- | SOCK_CLOEXEC
+ | SOCK_CLOEXEC
#endif
- , 0);
- if (sock == INVALID_SOCKET) {
- GDKfree(psock);
- GDKfree(usockfile);
- throw(IO, "mal_mapi.listen",
- OPERATION_FAILED ": creation of stream socket
failed: %s",
-#ifdef _MSC_VER
- wsaerror(WSAGetLastError())
-#else
- strerror(errno)
-#endif
- );
- }
-#if !defined(SOCK_CLOEXEC) && defined(HAVE_FCNTL)
- (void) fcntl(sock, F_SETFD, FD_CLOEXEC);
+ ,
rp->ai_protocol);
+ if (sock == INVALID_SOCKET)
+ continue;
+#ifndef SOCK_CLOEXEC
+ (void) fcntl(sock, F_SETFD, FD_CLOEXEC);
#endif
- if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &on,
sizeof on) == SOCKET_ERROR) {
-#ifdef _MSC_VER
- const char *err = wsaerror(WSAGetLastError());
-#else
- const char *err = strerror(errno);
-#endif
- GDKfree(psock);
- GDKfree(usockfile);
- closesocket(sock);
- throw(IO, "mal_mapi.listen", OPERATION_FAILED ":
setsockptr failed %s", err);
- }
+ if (setsockopt(sock, SOL_SOCKET,
SO_REUSEADDR, (char *) &on, sizeof on) == SOCKET_ERROR) {
+ closesocket(sock);
+ continue;
+ }
- if (bind_ipv6) {
- memset(&server_ipv6, 0, sizeof(server_ipv6));
- server_ipv6.sin6_family = AF_INET6;
- if (accept_any)
- server_ipv6.sin6_addr = ipv6_any_addr;
- else
- server_ipv6.sin6_addr = ipv6_loopback_addr;
- server = (struct sockaddr*) &server_ipv6;
- length = (SOCKLEN) sizeof(server_ipv6);
- } else {
- server_ipv4.sin_family = AF_INET;
- if (accept_any)
- server_ipv4.sin_addr.s_addr = htonl(INADDR_ANY);
- else
- server_ipv4.sin_addr.s_addr =
htonl(INADDR_LOOPBACK);
- for (i = 0; i < 8; i++)
- server_ipv4.sin_zero[i] = 0;
- server = (struct sockaddr*) &server_ipv4;
- length = (SOCKLEN) sizeof(server_ipv4);
- }
-
- do {
- if (bind_ipv6)
- server_ipv6.sin6_port = htons((unsigned short)
((port) & 0xFFFF));
- else
- server_ipv4.sin_port = htons((unsigned short)
((port) & 0xFFFF));
-
- if (bind(sock, server, length) == SOCKET_ERROR) {
- if (
+ if (bind(sock, rp->ai_addr,
rp->ai_addrlen) != SOCKET_ERROR) {
+ ok = true;
+ break;
+ }
+ }
+ if (ok) {
+ if (result)
+ freeaddrinfo(result);
+ break;
+ } else if (port > 65535) {
+ if (sock != -1)
+ closesocket(sock);
+ if (result)
+ freeaddrinfo(result);
+ GDKfree(psock);
+ GDKfree(usockfile);
+ throw(IO, "mal_mapi.listen",
OPERATION_FAILED ": bind to stream socket port %d failed", port);
+ } else {
+ if (
#ifdef _MSC_VER
- WSAGetLastError() == WSAEADDRINUSE &&
+ WSAGetLastError() ==
WSAEADDRINUSE &&
#else
#ifdef EADDRINUSE
- errno == EADDRINUSE &&
+ errno == EADDRINUSE &&
#else
#endif
#endif
- autosense && port <= 65535)
- {
- port++;
- continue;
+ autosense && port <= 65535) {
+ closesocket(sock);
+ if (result)
+ freeaddrinfo(result);
+ port++;
+ continue;
+ }
+ str err = createException(IO,
"mal_mapi.listen",
+
OPERATION_FAILED ": bind to stream socket port %d failed: %s", port,
+#ifdef _MSC_VER
+
wsaerror(WSAGetLastError())
+#else
+
strerror(errno)
+#endif
+ );
+ closesocket(sock);
+ if (result)
+ freeaddrinfo(result);
+ GDKfree(psock);
+ GDKfree(usockfile);
+ return err;
}
- closesocket(sock);
+ } while (1);
+ } else {
+ sock = socket(bind_ipv6 ? AF_INET6 : AF_INET,
SOCK_STREAM
+#ifdef SOCK_CLOEXEC
+ | SOCK_CLOEXEC
+#endif
+ , 0);
+ if (sock == INVALID_SOCKET) {
GDKfree(psock);
GDKfree(usockfile);
- throw(IO, "mal_mapi.listen",
- OPERATION_FAILED ": bind to stream
socket port %d "
- "failed: %s", port,
+ throw(IO, "mal_mapi.listen", OPERATION_FAILED
": creation of stream socket failed: %s",
#ifdef _MSC_VER
wsaerror(WSAGetLastError())
#else
strerror(errno)
#endif
- );
+ );
+ }
+#if !defined(SOCK_CLOEXEC) && defined(HAVE_FCNTL)
+ (void) fcntl(sock, F_SETFD, FD_CLOEXEC);
+#endif
+
+ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)
&on, sizeof on) == SOCKET_ERROR) {
+#ifdef _MSC_VER
+ const char *err = wsaerror(WSAGetLastError());
+#else
+ const char *err = strerror(errno);
+#endif
+ GDKfree(psock);
+ GDKfree(usockfile);
+ closesocket(sock);
+ throw(IO, "mal_mapi.listen", OPERATION_FAILED
": setsockptr failed %s", err);
+ }
+
+ if (bind_ipv6) {
+ memset(&server_ipv6, 0, sizeof(server_ipv6));
+ server_ipv6.sin6_family = AF_INET6;
+ if (accept_any)
+ server_ipv6.sin6_addr = ipv6_any_addr;
+ else
+ server_ipv6.sin6_addr =
ipv6_loopback_addr;
+ server = (struct sockaddr*) &server_ipv6;
+ length = (SOCKLEN) sizeof(server_ipv6);
} else {
- break;
+ server_ipv4.sin_family = AF_INET;
+ if (accept_any)
+ server_ipv4.sin_addr.s_addr =
htonl(INADDR_ANY);
+ else
+ server_ipv4.sin_addr.s_addr =
htonl(INADDR_LOOPBACK);
+ for (i = 0; i < 8; i++)
+ server_ipv4.sin_zero[i] = 0;
+ server = (struct sockaddr*) &server_ipv4;
+ length = (SOCKLEN) sizeof(server_ipv4);
}
- } while (1);
+
+ do {
+ if (bind_ipv6)
+ server_ipv6.sin6_port = htons((unsigned
short) ((port) & 0xFFFF));
+ else
+ server_ipv4.sin_port = htons((unsigned
short) ((port) & 0xFFFF));
- if (getsockname(sock, server, &length) == SOCKET_ERROR) {
+ if (bind(sock, server, length) == SOCKET_ERROR)
{
+ if (
+#ifdef _MSC_VER
+ WSAGetLastError() ==
WSAEADDRINUSE &&
+#else
+#ifdef EADDRINUSE
+ errno == EADDRINUSE &&
+#else
+#endif
+#endif
+ autosense && port <= 65535)
+ {
+ port++;
+ continue;
+ }
+ closesocket(sock);
+ GDKfree(psock);
+ GDKfree(usockfile);
+ throw(IO, "mal_mapi.listen",
OPERATION_FAILED ": bind to stream socket port %d failed: %s", port,
+#ifdef _MSC_VER
+ wsaerror(WSAGetLastError())
+#else
+ strerror(errno)
+#endif
+ );
+ } else {
+ break;
+ }
+ } while (1);
+
+ if (getsockname(sock, server, &length) == SOCKET_ERROR)
{
+ closesocket(sock);
+ GDKfree(psock);
+ GDKfree(usockfile);
+ throw(IO, "mal_mapi.listen", OPERATION_FAILED
": failed getting socket name: %s",
+#ifdef _MSC_VER
+ wsaerror(WSAGetLastError())
+#else
+ strerror(errno)
+#endif
+ );
+ }
+ }
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list