From he@uninett.no Wed Jan 18 10:20:58 2017 Received: from smistad.uninett.no (smistad.uninett.no [158.38.62.77]) by underdog.stansell.org (8.15.2/8.15.2) with ESMTP id v0IAKof2017664 for ; Wed, 18 Jan 2017 10:20:56 GMT Received: from smistad.uninett.no (smistad.uninett.no [158.38.62.77]) by smistad.uninett.no (Postfix) with ESMTP id 8CE2B43E9C9 for ; Wed, 18 Jan 2017 11:20:47 +0100 (CET) Date: Wed, 18 Jan 2017 11:20:47 +0100 (CET) Message-Id: <20170118.112047.436369708957766433.he@uninett.no> To: users@conserver.com Subject: conserver's IPv6 support not fully baked... From: Havard Eidnes X-Mailer: Mew version 6.7 on Emacs 24.5 / Mule 6.0 (HANACHIRUSATO) Mime-Version: 1.0 Content-Type: Multipart/Mixed; boundary="--Next_Part(Wed_Jan_18_11_20_47_2017_872)--" Content-Transfer-Encoding: 7bit X-Spam-Score: -5.1 () BAYES_00,RP_MATCHES_RCVD,SPF_PASS X-Scanned-By: MIMEDefang 2.72 on 198.151.248.21 X-BeenThere: users@conserver.com X-Mailman-Version: 2.1.23 Precedence: list List-Id: Conserver Users List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Jan 2017 10:20:59 -0000 ----Next_Part(Wed_Jan_18_11_20_47_2017_872)-- Content-Type: Text/Plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable Hi, I recently had to deal with a conserver version upgrade, and someone had decided to turn on the "IPv6" option in the package. Attached below are two patches which do three things: 1) (unrelated to IPv6) print decoded errno on connection failure 2) use temp variables to walk address lists, avoid trying to do freeaddrinfo(NULL), as that leads to SEGV for the main server process 3) use correct socket address length when calling getnameinfo() in the IPv6 case, avoid early return with "permanent failure" because the socket address length is wrong In my case I'm running this on NetBSD, and on that platform you need to open two server sockets, one for IPv6 and one for IPv4 if you are going to serve both. The code as it stands on NetBSD only opens an IPv6 socket if the IPv6 option is enabled, and hence IPv4 is not served, causing backward compatibility problems and failure to interoperate with conserver installations which don't have IPv6 configured. Plus ... it seems that it also can't connect to remote consoles which are only reachable via IPv4 when the IPv6 option is enabled, but admittedly I did not debug that more thoroughly. It seems to be a bigger task to fix the Master() function in conserver/master.c to do the "two server sockets" dance needed on NetBSD. Plus one needs to portably distinguish where two sockets are needed and where they are not, so I've punted on that for now. Regards, - H=E5vard ----Next_Part(Wed_Jan_18_11_20_47_2017_872)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="patch-conserver_consent.c" $NetBSD: patch-conserver_consent.c,v 1.1 2017/01/18 09:54:51 he Exp $ Print strerror() on failure. Use scratch variables for walking address info list, so that we don't end up trying to freeaddrinfo(NULL). --- conserver/consent.c.orig 2015-06-02 17:17:45.000000000 +0000 +++ conserver/consent.c @@ -919,13 +919,16 @@ ConsInit(CONSENT *pCE) rp->ai_addrlen)) == 0) goto success; fail: + error = errno; close(cofile); + } else { + error = errno; } rp = rp->ai_next; } - Error("[%s]: Unable to connect to %s:%s", pCE->server, - host, serv); + Error("[%s]: Unable to connect to %s:%s %s", pCE->server, + host, serv, strerror(error)); ConsDown(pCE, FLAGTRUE, FLAGTRUE); return; success: @@ -1252,7 +1255,7 @@ AddrsMatch(char *addr1, char *addr2) { #if USE_IPV6 int error, ret = 0; - struct addrinfo *ai1, *ai2, hints; + struct addrinfo *ai1, *aip1, *ai2, *aip2, hints; #else /* so, since we might use inet_addr, we're going to use * (in_addr_t)(-1) as a sign of an invalid ip address. @@ -1290,17 +1293,17 @@ AddrsMatch(char *addr1, char *addr2) goto done; } - for (; ai1 != NULL; ai1 = ai1->ai_next) { - for (; ai2 != NULL; ai2 = ai2->ai_next) { - if (ai1->ai_addr->sa_family != ai2->ai_addr->sa_family) + for (aip1 = ai1; aip1 != NULL; aip1 = aip1->ai_next) { + for (aip2 = ai2; aip2 != NULL; aip2 = aip2->ai_next) { + if (aip1->ai_addr->sa_family != aip2->ai_addr->sa_family) continue; if ( # if HAVE_MEMCMP - memcmp(&ai1->ai_addr, &ai2->ai_addr, + memcmp(&aip1->ai_addr, &aip2->ai_addr, sizeof(struct sockaddr_storage)) # else - bcmp(&ai1->ai_addr, &ai2->ai_addr, + bcmp(&aip1->ai_addr, &aip2->ai_addr, sizeof(struct sockaddr_storage)) # endif == 0) { @@ -1311,8 +1314,10 @@ AddrsMatch(char *addr1, char *addr2) } done: - freeaddrinfo(ai1); - freeaddrinfo(ai2); + if (ai1) + freeaddrinfo(ai1); + if (ai2) + freeaddrinfo(ai2); Msg("compare %s and %s returns %d", addr1, addr2, ret); return ret; #else ----Next_Part(Wed_Jan_18_11_20_47_2017_872)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="patch-conserver_access.c" $NetBSD: patch-conserver_access.c,v 1.1 2017/01/18 09:54:51 he Exp $ Make sure to use correct sockaddr length when doing getnameinfo(). --- conserver/access.c.orig 2017-01-18 09:20:03.000000000 +0000 +++ conserver/access.c @@ -150,6 +150,7 @@ AccType(INADDR_STYPE *addr, char **peern so = sizeof(*addr); #if USE_IPV6 + so = sizeof(struct sockaddr_in6); error = getnameinfo((struct sockaddr *)addr, so, ipaddr, sizeof(ipaddr), NULL, 0, NI_NUMERICHOST); ----Next_Part(Wed_Jan_18_11_20_47_2017_872)----