Changeset: 250587065bec for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=250587065bec
Modified Files:
        tools/merovingian/daemon/client.c
        tools/merovingian/daemon/connections.c
        tools/merovingian/daemon/merovingian.c
        tools/merovingian/daemon/monetdbd.1.in
        tools/merovingian/utils/control.c
Branch: ipv6
Log Message:

Allow monetdbd client to connect on IPv6, plus several corrections.


diffs (268 lines):

diff --git a/tools/merovingian/daemon/client.c 
b/tools/merovingian/daemon/client.c
--- a/tools/merovingian/daemon/client.c
+++ b/tools/merovingian/daemon/client.c
@@ -59,11 +59,12 @@ handleClient(void *data)
        char *user = NULL, *algo = NULL, *passwd = NULL, *lang = NULL;
        char *database = NULL, *s;
        char dbmod[64];
-       char host[128];
+       char host[512];
+       char port[16];
        sabdb *top = NULL;
        sabdb *stat = NULL;
-       struct sockaddr_in saddr;
-       socklen_t saddrlen = sizeof(struct sockaddr_in);
+       struct sockaddr saddr;
+       socklen_t saddrlen = 0;
        err e;
        confkeyval *ckv, *kv;
        char mydoproxy;
@@ -94,23 +95,16 @@ handleClient(void *data)
 
        if (isusock) {
                snprintf(host, sizeof(host), "(local)");
-       } else if (getpeername(sock, (struct sockaddr *)&saddr, &saddrlen) == 
-1) {
-               Mfprintf(stderr, "couldn't get peername of client: %s\n",
-                               strerror(errno));
+       } else if (getpeername(sock, &saddr, &saddrlen) == -1) {
+               Mfprintf(stderr, "couldn't get peername of client: %s\n", 
strerror(errno));
                snprintf(host, sizeof(host), "(unknown)");
        } else {
-               struct hostent *hoste = 
-                       gethostbyaddr(&saddr.sin_addr.s_addr, 4, 
saddr.sin_family);
-               if (hoste == NULL) {
-                       snprintf(host, sizeof(host), "%u.%u.%u.%u:%u",
-                                       (unsigned) 
((ntohl(saddr.sin_addr.s_addr) >> 24) & 0xff),
-                                       (unsigned) 
((ntohl(saddr.sin_addr.s_addr) >> 16) & 0xff),
-                                       (unsigned) 
((ntohl(saddr.sin_addr.s_addr) >> 8) & 0xff),
-                                       (unsigned) 
(ntohl(saddr.sin_addr.s_addr) & 0xff),
-                                       (unsigned) (ntohs(saddr.sin_port)));
+               char ghost[512];
+               if (getnameinfo(&saddr, saddrlen, ghost, sizeof(ghost), port, 
sizeof(port),
+                       NI_NUMERICSERV | NI_NUMERICHOST) == 0) {
+                       snprintf(host, sizeof(host), "%s:%s", ghost, port);
                } else {
-                       snprintf(host, sizeof(host), "%s:%u",
-                                       hoste->h_name, (unsigned) 
(ntohs(saddr.sin_port)));
+                       snprintf(host, sizeof(host), "(unknown):%s", port);
                }
        }
 
diff --git a/tools/merovingian/daemon/connections.c 
b/tools/merovingian/daemon/connections.c
--- a/tools/merovingian/daemon/connections.c
+++ b/tools/merovingian/daemon/connections.c
@@ -32,12 +32,9 @@ openConnectionTCP(int *ret, bool bind_ip
        int sock = -1, check = 0;
        socklen_t length = 0;
        int on = 1;
-       int i = 0;
-       struct hostent *hoste;
-       char *host = NULL;
+       int i = 0, flags = NI_NUMERICSERV;
        char sport[16];
-       char hostip[24];
-       char ghost[512];
+       char host[512];
 
        snprintf(sport, 16, "%hu", port);
        if (bindaddr) {
@@ -46,10 +43,8 @@ openConnectionTCP(int *ret, bool bind_ip
                        .ai_socktype = SOCK_STREAM,
                        .ai_flags = AI_PASSIVE,
                        .ai_protocol = IPPROTO_TCP,
-                       .ai_canonname = NULL,
-                       .ai_addr = NULL,
-                       .ai_next = NULL,
                };
+               flags |= NI_NUMERICHOST;
 
                check = getaddrinfo(bindaddr, sport, &hints, &result);
                if (check != 0)
@@ -82,6 +77,11 @@ openConnectionTCP(int *ret, bool bind_ip
                                closesocket(sock);
                        return newErr("cannot bind to host %s", bindaddr);
                }
+               if (bind_ipv6)
+                       server_ipv6 = *(struct sockaddr_in6*) rp->ai_addr;
+               else
+                       server_ipv4 = *(struct sockaddr_in*) rp->ai_addr;
+               length = rp->ai_addrlen;
        } else {
                sock = socket(bind_ipv6 ? AF_INET6 : AF_INET, SOCK_STREAM
 #ifdef SOCK_CLOEXEC
@@ -126,44 +126,13 @@ openConnectionTCP(int *ret, bool bind_ip
                }
        }
 
-       if (bindaddr) {
-               int res = getnameinfo(rp->ai_addr, rp->ai_addrlen, ghost, 
sizeof(ghost), sport, sizeof(sport), NI_NUMERICSERV);
+       check = getnameinfo(bind_ipv6 ? (struct sockaddr*) &server_ipv6 : 
(struct sockaddr*) &server_ipv4, length, host,
+                                               sizeof(host), sport, 
sizeof(sport), flags);
+       if (result)
                freeaddrinfo(result);
-               if (res != 0) {
-                       closesocket(sock);
-                       return(newErr("failed getting socket name: %s", 
strerror(errno)));
-               }
-               host = ghost;
-       } else {
-               if (bind_ipv6)
-                       hoste = gethostbyaddr(&server_ipv6.sin6_addr.s6_addr, 
sizeof(server_ipv6.sin6_addr.s6_addr),
-                                                                 
server_ipv6.sin6_family);
-               else
-                       hoste = gethostbyaddr(&server_ipv4.sin_addr.s_addr, 
sizeof(server_ipv4.sin_addr.s_addr),
-                                                                 
server_ipv4.sin_family);
-               if (hoste == NULL) {
-                       if (bind_ipv6) {
-                               snprintf(hostip, sizeof(hostip),
-                                               
"%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 {
-                               snprintf(hostip, sizeof(hostip), "%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));
-                       }
-                       host = hostip;
-               } else {
-                       host = hoste->h_name;
-               }
+       if (check != 0) {
+               closesocket(sock);
+               return(newErr("failed getting socket name: %s", 
strerror(errno)));
        }
 
        /* keep queue of 5 */
diff --git a/tools/merovingian/daemon/merovingian.c 
b/tools/merovingian/daemon/merovingian.c
--- a/tools/merovingian/daemon/merovingian.c
+++ b/tools/merovingian/daemon/merovingian.c
@@ -920,11 +920,7 @@ main(int argc, char *argv[])
                                struct addrinfo *multi, hints = (struct 
addrinfo) {
                                        .ai_family = AF_INET6,
                                        .ai_socktype = SOCK_DGRAM,
-                                       .ai_flags = AI_PASSIVE,
-                                       .ai_protocol = 0,
-                                       .ai_canonname = NULL,
-                                       .ai_addr = NULL,
-                                       .ai_next = NULL,
+                                       .ai_protocol = IPPROTO_UDP,
                                };
 
                                _mero_broadcastaddr = (struct sockaddr*) 
&server_ipv6;
diff --git a/tools/merovingian/daemon/monetdbd.1.in 
b/tools/merovingian/daemon/monetdbd.1.in
--- a/tools/merovingian/daemon/monetdbd.1.in
+++ b/tools/merovingian/daemon/monetdbd.1.in
@@ -169,6 +169,12 @@ This property specifies which TCP port
 .I monetdbd
 should listen to for connection requests.  Defaults to 50000.
 .TP
+.B ipv6
+This property forces monetdbd to bind on ipv6 addresses only.  This
+enforcement applies to the discovery service as well if enabled.  In that
+case the discovery service will use IPv6 multicast on ff02::1 address.
+Defaults to false.
+.TP
 .B listenaddr
 This property specifies an address that is allowed to connect to the server.
 The user can specify one IP(v6) address, or use the 0.0.0.0 notation to allow
@@ -196,9 +202,10 @@ one specified at configure time, which i
 Changing this property takes effect immediately at runtime.
 .TP
 .B discovery
-Specifies whether neighbor discovery is to be enabled using UDP
-broadcasts or not.  The broadcasts are done on the same portnumber as
-the port setting.
+Specifies whether neighbor discovery is to be enabled using UDP.
+The discovery method is performed with broadcasts on IPv4 and
+multicasts in IPv6, while using the same portnumber as the port
+setting.
 .TP
 .B discoveryttl
 .I Monetdbd
diff --git a/tools/merovingian/utils/control.c 
b/tools/merovingian/utils/control.c
--- a/tools/merovingian/utils/control.c
+++ b/tools/merovingian/utils/control.c
@@ -76,41 +76,46 @@ char* control_send(
                        return(strdup(sbuf));
                }
        } else {
-               struct sockaddr_in server;
-               struct hostent *hp;
-               char ver = 0;
-               char *p;
+               int check;
+               char ver = 0, *p;
+               char sport[16];
+               struct addrinfo *res, *rp, hints = (struct addrinfo) {
+                       .ai_family = AF_UNSPEC,
+                       .ai_socktype = SOCK_STREAM,
+                       .ai_protocol = IPPROTO_TCP,
+               };
 
-               /* TCP socket connect */
-               if ((sock = socket(PF_INET, SOCK_STREAM
-#ifdef SOCK_CLOEXEC
-                                                  | SOCK_CLOEXEC
-#endif
-                                                  , IPPROTO_TCP)) == -1) {
-                       snprintf(sbuf, sizeof(sbuf), "cannot open connection: 
%s",
-                                       strerror(errno));
+               snprintf(sport, sizeof(sport), "%d", port & 0xFFFF);
+               check = getaddrinfo(host, sport, &hints, &res);
+               if (check) {
+                       snprintf(sbuf, sizeof(sbuf), "cannot connect: %s", 
gai_strerror(check));
                        return(strdup(sbuf));
                }
-#ifndef SOCK_CLOEXEC
-               (void) fcntl(sock, F_SETFD, FD_CLOEXEC);
+               for (rp = res; rp; rp = rp->ai_next) {
+                       sock = socket(rp->ai_family, rp->ai_socktype
+#ifdef SOCK_CLOEXEC
+                                                | SOCK_CLOEXEC
 #endif
-               hp = gethostbyname(host);
-               if (hp == NULL) {
-                       snprintf(sbuf, sizeof(sbuf), "cannot lookup hostname: 
%s",
-                                       hstrerror(h_errno));
-                       closesocket(sock);
+                                                , rp->ai_protocol);
+                       if (sock == INVALID_SOCKET)
+                               continue;
+                       if (connect(sock, rp->ai_addr, (socklen_t) 
rp->ai_addrlen) != SOCKET_ERROR)
+                               break;  /* success */
+               }
+               freeaddrinfo(res);
+               if (rp == NULL) {
+                       snprintf(sbuf, sizeof(sbuf), "cannot connect to %s:%s: 
%s", host, sport,
+#ifdef _MSC_VER
+                                       wsaerror(WSAGetLastError())
+#else
+                                        strerror(errno)
+#endif
+                       );
                        return(strdup(sbuf));
                }
-               server = (struct sockaddr_in) {
-                       .sin_family = hp->h_addrtype,
-                       .sin_port = htons((unsigned short) port),
-               };
-               memcpy(&server.sin_addr, hp->h_addr_list[0], hp->h_length);
-               if (connect(sock, (SOCKPTR) &server, sizeof(struct 
sockaddr_in)) == -1) {
-                       snprintf(sbuf, sizeof(sbuf), "cannot connect: %s", 
strerror(errno));
-                       closesocket(sock);
-                       return(strdup(sbuf));
-               }
+#if !defined(SOCK_CLOEXEC) && defined(HAVE_FCNTL)
+               (void) fcntl(s, F_SETFD, FD_CLOEXEC);
+#endif
 
                /* try reading length */
                len = recv(sock, rbuf, 2, 0);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to