Changeset: fc792f09bd97 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=fc792f09bd97
Modified Files:
        clients/mapilib/mapi.c
        monetdb5/modules/mal/mal_mapi.c
        monetdb5/modules/mal/remote.c
        sql/server/rel_remote.c
        tools/merovingian/client/monetdb.1
        tools/merovingian/daemon/forkmserver.c
        tools/merovingian/daemon/proxy.c
Branch: ipv6
Log Message:

While validating a hostname, check for a possible raw IPv6 address. In that 
case, a colon symbol may appear before the port colon marker. This happens 
because IPv6 uses colons to separate digits, enclosed by brackets.

Also fixed passing the ipv6 property between monetdbd and mserver5.


diffs (181 lines):

diff --git a/clients/mapilib/mapi.c b/clients/mapilib/mapi.c
--- a/clients/mapilib/mapi.c
+++ b/clients/mapilib/mapi.c
@@ -1972,9 +1972,16 @@ mapi_mapiuri(const char *url, const char
                dbname = NULL;
                query = uri;
        } else {
-               char *p;
-
-               if ((p = strchr(uri, ':')) == NULL) {
+               char *p = uri;
+
+               if (*p == '[') {
+                       if ((p = strchr(p, ']')) == NULL) {
+                               free(uri);
+                               mapi_setError(mid, "URI contains an invalid 
IPv6 address", "mapi_mapiuri", MERROR);
+                               return mid;
+                       }
+               }
+               if ((p = strchr(p, ':')) == NULL) {
                        free(uri);
                        mapi_setError(mid,
                                      "URI must contain a port number after "
@@ -2813,6 +2820,14 @@ mapi_reconnect(Mapi mid)
                                red += 15; /* "mapi:monetdb://" */
                                p = red;
                                q = NULL;
+                               if (*red == '[') {
+                                       if ((red = strchr(red, ']')) == NULL) {
+                                               mapi_close_handle(hdl);
+                                               mapi_setError(mid, "invalid 
IPv6 hostname", "mapi_reconnect", MERROR);
+                                               close_connection(mid);
+                                               return mid->error;
+                                       }
+                               }
                                if ((red = strchr(red, ':')) != NULL) {
                                        *red++ = '\0';
                                        q = red;
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
@@ -811,12 +811,12 @@ SERVERlisten(int *Port, str *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");
+                               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 {
-                               snprintf(host, 
sizeof(host),"%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
+                               snprintf(host, 
sizeof(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],
diff --git a/monetdb5/modules/mal/remote.c b/monetdb5/modules/mal/remote.c
--- a/monetdb5/modules/mal/remote.c
+++ b/monetdb5/modules/mal/remote.c
@@ -110,6 +110,11 @@ str RMTresolve(bat *ret, str *pat) {
 
        /* extract port from mero_uri, let mapi figure out the rest */
        mero_uri+=strlen("mapi:monetdb://");
+       if (*mero_uri == '[') {
+               if ((mero_uri = strchr(mero_uri, ']')) == NULL)
+                       throw(MAL, "remote.resolve", "illegal IPv6 address on 
merovingian_uri: %s",
+                                 GDKgetenv("merovingian_uri"));
+       }
        if ((p = strchr(mero_uri, ':')) == NULL)
                throw(MAL, "remote.resolve", "illegal merovingian_uri setting: 
%s",
                                GDKgetenv("merovingian_uri"));
diff --git a/sql/server/rel_remote.c b/sql/server/rel_remote.c
--- a/sql/server/rel_remote.c
+++ b/sql/server/rel_remote.c
@@ -17,14 +17,20 @@ mapiuri_valid( const char *uri)
        int i = 0, l = 0;
        const char *p = uri;
 
-       if (strncmp(p, "mapi:monetdb://", strlen(mapi_prefix)))
+       if (strncmp(p, mapi_prefix, strlen(mapi_prefix)))
                return 0;
        /* optional host (todo limit to valid hostnames ??) */
        p += strlen(mapi_prefix);
-       for(; *p; p++) {
-               if (*p == ':')
-                       break;
-               if (*p == '/')
+       if (*p == '[') { //check for IPv6 addresses
+               for (; *p; p++) {
+                       if (*p == ']')
+                               break;
+               }
+       }
+       if (!p)
+               return 0;
+       for (; *p; p++) {
+               if (*p == ':' || *p == '/')
                        break;
        }
        if (!p)
diff --git a/tools/merovingian/client/monetdb.1 
b/tools/merovingian/client/monetdb.1
--- a/tools/merovingian/client/monetdb.1
+++ b/tools/merovingian/client/monetdb.1
@@ -330,9 +330,6 @@ be changed.  See the
 manpage for available pipelines.  Changing this setting is discouraged
 at all times.
 .TP
-.BR ipv6= < yes | no >
-Forces database to bind on IPv6 addresses only.
-.TP
 .BR readonly= < yes | no >
 Defines if the database has to be started in readonly mode.  Updates are
 rejected in this mode, and the server employs some read-only
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
@@ -501,9 +501,7 @@ 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";
+       ipv6 = getConfNum(_mero_props, "ipv6") == 1 ? "mapi_ipv6=true" : 
"mapi_ipv6=false";
 
        /* ok, now exec that mserver we want */
        snprintf(dbpath, sizeof(dbpath),
@@ -540,9 +538,6 @@ 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
@@ -551,6 +546,7 @@ forkMserver(char *database, sabdb** stat
                snprintf(port, sizeof(port), "mapi_port=%u", mport + 1);
                snprintf(usock, sizeof(usock), "mapi_usock=");
        }
+       argv[c++] = "--set"; argv[c++] = ipv6;
        argv[c++] = "--set"; argv[c++] = port;
        argv[c++] = "--set"; argv[c++] = usock;
        argv[c++] = "--set"; argv[c++] = vaultkey;
diff --git a/tools/merovingian/daemon/proxy.c b/tools/merovingian/daemon/proxy.c
--- a/tools/merovingian/daemon/proxy.c
+++ b/tools/merovingian/daemon/proxy.c
@@ -87,7 +87,7 @@ err
 startProxy(int psock, stream *cfdin, stream *cfout, char *url, char *client)
 {
        int ssock = -1;
-       char *port, *t, *conn;
+       char *port, *t, *conn, *endipv6;
        struct stat statbuf;
        stream *sfdin, *sfout;
        merovingian_proxy *pctos, *pstoc;
@@ -98,8 +98,21 @@ startProxy(int psock, stream *cfdin, str
        /* quick 'n' dirty parsing */
        if (strncmp(url, "mapi:monetdb://", sizeof("mapi:monetdb://") - 1) == 
0) {
                conn = strdup(url + sizeof("mapi:monetdb://") - 1);
-               /* drop anything off after the hostname */
-               if ((port = strchr(conn, ':')) != NULL) {
+
+               if (*conn == '[') { /* check for an IPv6 address */
+                       if ((endipv6 = strchr(conn, ']')) != NULL) {
+                               if ((port = strchr(endipv6, ':')) != NULL) {
+                                       *port = '\0';
+                                       port++;
+                                       if ((t = strchr(port, '/')) != NULL)
+                                               *t = '\0';
+                               } else {
+                                       return(newErr("can't find a port in 
redirect: %s", url));
+                               }
+                       } else {
+                               return(newErr("invalid IPv6 address in 
redirect: %s", url));
+                       }
+               } else if ((port = strchr(conn, ':')) != NULL) { /* drop 
anything off after the hostname */
                        *port = '\0';
                        port++;
                        if ((t = strchr(port, '/')) != NULL)
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to