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