Changeset: 58400be28e18 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=58400be28e18
Modified Files:
common/options/monet_options.c
monetdb5/modules/mal/mal_mapi.c
tools/merovingian/daemon/forkmserver.c
Branch: ipv6
Log Message:
First steps into ipv6 support.
diffs (257 lines):
diff --git a/common/options/monet_options.c b/common/options/monet_options.c
--- a/common/options/monet_options.c
+++ b/common/options/monet_options.c
@@ -219,7 +219,7 @@ mo_builtin_settings(opt **Set)
if (Set == NULL)
return 0;
-#define N_OPTIONS 10 /*MUST MATCH # OPTIONS BELOW */
+#define N_OPTIONS 11 /*MUST MATCH # OPTIONS BELOW */
set = malloc(sizeof(opt) * N_OPTIONS);
if (set == NULL)
return 0;
@@ -264,6 +264,10 @@ mo_builtin_settings(opt **Set)
set[i].value = strdup("false");
i++;
set[i].kind = opt_builtin;
+ set[i].name = strdup("mapi_ipv6");
+ set[i].value = strdup("false");
+ i++;
+ set[i].kind = opt_builtin;
set[i].name = strdup("mapi_autosense");
set[i].value = strdup("false");
i++;
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
@@ -495,55 +495,18 @@ error:
fprintf(stderr, "!mal_mapi.listen: %s, terminating listener\n", msg);
}
-/**
- * Small utility function to call the sabaoth marchConnection function
- * with the right arguments. If the socket is bound to 0.0.0.0 the
- * hostname address is used, to make the info usable for servers outside
- * localhost.
- */
-static void SERVERannounce(struct in_addr addr, int port, str usockfile) {
- str buf;
- char host[128];
+static struct in6_addr ipv6_loopback_addr = IN6ADDR_LOOPBACK_INIT;
- if (port > 0) {
- if (addr.s_addr == INADDR_ANY) {
- gethostname(host, sizeof(host));
- host[sizeof(host) - 1] = '\0';
- } else {
- /* avoid doing this, it requires some includes that
probably
- * give trouble on windowz
- host = inet_ntoa(addr);
- */
- sprintf(host, "%u.%u.%u.%u",
- (unsigned) ((ntohl(addr.s_addr) >> 24)
& 0xff),
- (unsigned) ((ntohl(addr.s_addr) >> 16)
& 0xff),
- (unsigned) ((ntohl(addr.s_addr) >> 8) &
0xff),
- (unsigned) (ntohl(addr.s_addr) & 0xff));
- }
- if ((buf = msab_marchConnection(host, port)) != NULL)
- free(buf);
- else
- /* announce that we're now reachable */
- printf("# Listening for connection requests on "
- "mapi:monetdb://%s:%i/\n", host, port);
- }
- if (usockfile != NULL) {
- port = 0;
- if ((buf = msab_marchConnection(usockfile, port)) != NULL)
- free(buf);
- else
- /* announce that we're now reachable */
- printf("# Listening for UNIX domain connection requests
on "
- "mapi:monetdb://%s\n", usockfile);
- }
-}
+static struct in6_addr ipv6_any_addr = IN6ADDR_ANY_INIT;
static str
SERVERlisten(int *Port, str *Usockfile, int *Maxusers)
{
- struct sockaddr_in server;
+ struct sockaddr_in server_ipv4;
+ struct sockaddr_in6 server_ipv6;
SOCKET sock = INVALID_SOCKET;
SOCKET *psock;
+ bool bind_ipv6 = false;
bool accept_any = false;
bool autosense = false;
#ifdef HAVE_SYS_UN_H
@@ -557,12 +520,15 @@ SERVERlisten(int *Port, str *Usockfile,
int port;
int maxusers;
char *usockfile;
+ str buf;
+ char host[128];
#ifdef DEBUG_SERVER
char msg[512], host[512];
Client cntxt= mal_clients;
#endif
accept_any = GDKgetenv_istrue("mapi_open");
+ bind_ipv6 = GDKgetenv_istrue("mapi_ipv6");
autosense = GDKgetenv_istrue("mapi_autosense");
/* early way out, we do not want to listen on any port when running in
embedded mode */
@@ -607,7 +573,7 @@ SERVERlisten(int *Port, str *Usockfile,
}
if (port > 0) {
- sock = socket(AF_INET, SOCK_STREAM
+ sock = socket(bind_ipv6 ? AF_INET6 : AF_INET, SOCK_STREAM
#ifdef SOCK_CLOEXEC
| SOCK_CLOEXEC
#endif
@@ -640,18 +606,34 @@ SERVERlisten(int *Port, str *Usockfile,
throw(IO, "mal_mapi.listen", OPERATION_FAILED ":
setsockptr failed %s", err);
}
- server.sin_family = AF_INET;
- if (accept_any)
- server.sin_addr.s_addr = htonl(INADDR_ANY);
- else
- server.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- for (i = 0; i < 8; i++)
- server.sin_zero[i] = 0;
- length = (SOCKLEN) sizeof(server);
+ if (bind_ipv6) {
+ server_ipv6.sin6_family = AF_INET6;
+ if (accept_any)
+ memcpy(server_ipv6.sin6_addr.s6_addr,
&ipv6_any_addr, sizeof(struct in6_addr));
+ else
+ memcpy(server_ipv6.sin6_addr.s6_addr,
&ipv6_loopback_addr, sizeof(struct in6_addr));
+ server_ipv6.sin6_flowinfo = 0;
+ server_ipv6.sin6_scope_id = 0;
+ 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;
+ length = (SOCKLEN) sizeof(server_ipv4);
+ }
do {
- server.sin_port = htons((unsigned short) ((port) &
0xFFFF));
- if (bind(sock, (SOCKPTR) &server, length) ==
SOCKET_ERROR) {
+ 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, bind_ipv6 ? (SOCKPTR) &server_ipv6 :
(SOCKPTR) &server_ipv4, length) == SOCKET_ERROR) {
if (
#ifdef _MSC_VER
WSAGetLastError() == WSAEADDRINUSE &&
@@ -683,7 +665,7 @@ SERVERlisten(int *Port, str *Usockfile,
}
} while (1);
- if (getsockname(sock, (SOCKPTR) &server, &length) ==
SOCKET_ERROR) {
+ if (getsockname(sock, bind_ipv6 ? (SOCKPTR) &server_ipv6 :
(SOCKPTR) &server_ipv4, &length) == SOCKET_ERROR) {
closesocket(sock);
GDKfree(psock);
GDKfree(usockfile);
@@ -825,7 +807,58 @@ SERVERlisten(int *Port, str *Usockfile,
* predictable... */
srand((unsigned int) GDKusec());
- SERVERannounce(server.sin_addr, port, usockfile);
+ if (port > 0) {
+ if (bind_ipv6) {
+ if (memcmp(server_ipv6.sin6_addr.s6_addr,
&ipv6_loopback_addr, sizeof(struct in6_addr)) == 0) {
+ sprintf(host, "::1");
+ } else if (memcmp(server_ipv6.sin6_addr.s6_addr,
&ipv6_any_addr, sizeof(struct in6_addr)) == 0) {
+ gethostname(host, sizeof(host));
+ host[sizeof(host) - 1] = '\0';
+ } else {
+
sprintf(host,"%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
+
(int)server_ipv6.sin6_addr.s6_addr[0], (int)server_ipv6.sin6_addr.s6_addr[1],
+
(int)server_ipv6.sin6_addr.s6_addr[2], (int)server_ipv6.sin6_addr.s6_addr[3],
+
(int)server_ipv6.sin6_addr.s6_addr[4], (int)server_ipv6.sin6_addr.s6_addr[5],
+
(int)server_ipv6.sin6_addr.s6_addr[6], (int)server_ipv6.sin6_addr.s6_addr[7],
+
(int)server_ipv6.sin6_addr.s6_addr[8], (int)server_ipv6.sin6_addr.s6_addr[9],
+
(int)server_ipv6.sin6_addr.s6_addr[10], (int)server_ipv6.sin6_addr.s6_addr[11],
+
(int)server_ipv6.sin6_addr.s6_addr[12], (int)server_ipv6.sin6_addr.s6_addr[13],
+
(int)server_ipv6.sin6_addr.s6_addr[14], (int)server_ipv6.sin6_addr.s6_addr[15]);
+ }
+ } else {
+ if (server_ipv4.sin_addr.s_addr == INADDR_ANY) {
+ gethostname(host, sizeof(host));
+ host[sizeof(host) - 1] = '\0';
+ } else {
+ /* avoid doing this, it requires some includes
that probably
+ * give trouble on windowz
+ host = inet_ntoa(addr);
+ */
+ sprintf(host, "%u.%u.%u.%u",
+ (unsigned)
((ntohl(server_ipv4.sin_addr.s_addr) >> 24) & 0xff),
+ (unsigned)
((ntohl(server_ipv4.sin_addr.s_addr) >> 16) & 0xff),
+ (unsigned)
((ntohl(server_ipv4.sin_addr.s_addr) >> 8) & 0xff),
+ (unsigned)
(ntohl(server_ipv4.sin_addr.s_addr) & 0xff));
+ }
+ }
+
+ if ((buf = msab_marchConnection(host, port)) != NULL)
+ free(buf);
+ else
+ /* announce that we're now reachable */
+ printf("# Listening for connection requests on "
+ "mapi:monetdb://%s:%i/\n", host, port);
+ }
+ if (usockfile != NULL) {
+ port = 0;
+ if ((buf = msab_marchConnection(usockfile, port)) != NULL)
+ free(buf);
+ else
+ /* announce that we're now reachable */
+ printf("# Listening for UNIX domain connection requests
on "
+ "mapi:monetdb://%s\n", usockfile);
+ }
+
if (usockfile)
GDKfree(usockfile);
return MAL_SUCCEED;
diff --git a/tools/merovingian/daemon/forkmserver.c
b/tools/merovingian/daemon/forkmserver.c
--- a/tools/merovingian/daemon/forkmserver.c
+++ b/tools/merovingian/daemon/forkmserver.c
@@ -209,6 +209,7 @@ forkMserver(char *database, sabdb** stat
char *embeddedr = NULL;
char *embeddedpy = NULL;
char *embeddedc = NULL;
+ char *ipv6 = NULL;
char *dbextra = NULL;
char *argv[512]; /* for the exec arguments */
char property_other[1024];
@@ -500,6 +501,9 @@ forkMserver(char *database, sabdb** stat
mport = (unsigned int)getConfNum(_mero_props, "port");
+ kv = findConfKey(ckv, "ipv6");
+ if (kv->val != NULL && strcmp(kv->val, "no") != 0)
+ ipv6 = "mapi_ipv6=true";
/* ok, now exec that mserver we want */
snprintf(dbpath, sizeof(dbpath),
@@ -536,6 +540,9 @@ forkMserver(char *database, sabdb** stat
}
} else {
argv[c++] = "--set"; argv[c++] = "mapi_open=true";
+ if (ipv6 != NULL) {
+ argv[c++] = "--set"; argv[c++] = ipv6;
+ }
argv[c++] = "--set"; argv[c++] = "mapi_autosense=true";
/* avoid this mserver binding to the same port as merovingian
* but on another interface, (INADDR_ANY ... sigh) causing
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list