New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
inet_aton in Socket.pm core module is broken #11169
Comments
From quanah@zimbra.comCreated by quanah@zimbra.comThis is a bug report for perl from quanah@zimbra.com, ----------------------------------------------------------------- Perl Info
|
From @smpetersOn Wed Mar 02 15:35:49 2011, quanah@zimbra.com wrote:
Can you provide some sample code along with what operating system this Thanks! |
The RT System itself - Status changed from 'new' to 'open' |
From quanah@zimbra.com--On Wednesday, March 02, 2011 3:35 PM -0800 perlbug-followup@perl.org
Here is an example. If /etc/hosts is ordered with IPv6 before IPv4, inet_aton fails to return zimbra@zqa-064:~/libexec$ ./qtest.pl "IO::Socket::INET h:" is the value of inet_aton. Example /etc/hosts used here: 127.0.0.1 localhost # The following lines are desirable for IPv6 capable hosts 10.137.245.250 w1-zbuild-ns120-01-qa-nfs.eng.vmware.com Even modifying it thusly doesn't change the behavior: # The following lines are desirable for IPv6 capable hosts 127.0.0.1 localhost 10.137.245.250 w1-zbuild-ns120-01-qa-nfs.eng.vmware.com Now, if I move the IPv4 addresses to be before the IPv6 configuration, zimbra@zqa-064:~/libexec$ ./qtest.pl Here is /etc/hosts for this run: 127.0.0.1 localhost 10.137.245.250 w1-zbuild-ns120-01-qa-nfs.eng.vmware.com # The following lines are desirable for IPv6 capable hosts It basically seems that Perl's inet_aton stops parsing /etc/hosts for IPv4 --Quanah -- Quanah Gibson-Mount Zimbra :: the leader in open source messaging and collaboration |
From quanah@zimbra.com--On Friday, March 04, 2011 11:37 AM -0800 Steve Peters via RT
I discovered the issue while using Net::LDAP. Here is a brief set of #!/usr/bin/perl my $ldap_master_url="ldap://zqa-064.eng.vmware.com:389"; my $ldap = Net::LDAP->new("$ldap_master_url") or die "$@"; $ldap->unbind(); Net::LDAP makes a call to IO::Socket::INET, which in turn calls inet_aton. I made the following modifications to IO::Socket::INET to see what was root@zqa-064:/opt/zimbra/zimbramon/lib/x86_64-linux-gnu-thread-multi/IO/Socket# Inline Patchdiff -u INET.pm.orig INET.pm
--- INET.pm.orig 2011-03-01 13:07:51.970458204 -1000
+++ INET.pm 2011-03-01 13:10:37.430467992 -1000
@@ -77,6 +77,8 @@
$port = $1
if(defined $addr && $addr =~ s,:([\w\(\)/]+)$,,);
+ print "IO::Socket::INET Address: $addr\n";
+
if(defined $proto && $proto =~ /\D/) {
my $num = _get_proto_number($proto);
unless (defined $num) {
@@ -127,9 +129,12 @@
my @addr;
if ($multi && $addr_str !~ /^\d+(?:\.\d+){3}$/) {
(undef, undef, undef, undef, @addr) = gethostbyname($addr_str);
+ print "IO::Socket::Inet addr_str: $addr_str\n";
} else {
+ print "IO::Socket::Inet addr_str: $addr_str\n";
my $h = inet_aton($addr_str);
push(@addr, $h) if defined $h;
+ print "IO::Socket::INET h: $h\n";
}
@addr;
}
This is perl, v5.10.1 (*) built for x86_64-linux-gnu-thread-multi The version of Socket shipped with it is $VERSION = "1.82"; This is on Ubuntu 10.04 LTS 64-bit --Quanah -- Quanah Gibson-Mount Zimbra :: the leader in open source messaging and collaboration |
From @smpetersOn Fri, Mar 4, 2011 at 2:43 PM, Quanah Gibson-Mount <quanah@zimbra.com>wrote:
The simple answer is that inet_aton() on a libc level does not handle IPv6 Onto the fun part... We are obviously still using inet_aton() in Steve Peters |
From quanah@zimbra.com--On Friday, March 04, 2011 11:57 PM -0600 Steve Peters
Well, there is IO::Socket::INET6, which works great with IPv4 and IPv6. And, as I noted, it is valid to define the IPv4 addresses after the IPv6 --Quanah -- Quanah Gibson-Mount Zimbra :: the leader in open source messaging and collaboration |
From @nwc10On Fri, Mar 04, 2011 at 10:42:28PM -0800, Quanah Gibson-Mount wrote:
That's not quite correct, given that Socket::inet_aton() isn't actually a pure void if ((*host != '\0') && inet_aton(host, &ip_address)) { phe = gethostbyname(host); XSRETURN_UNDEF;
So I think that this is actually a bug in the OS gethostbyname() However, I'm hoping that it can be worked round with something like this: From f0a6093 Mon Sep 17 00:00:00 2001 This is a last resort, in case gethostbyname() is getting confused because it ext/Socket/Socket.xs | 20 +++++++++++++++++++- Inline Patchdiff --git a/ext/Socket/Socket.xs b/ext/Socket/Socket.xs
index 9214fc1..71f0c57 100644
--- a/ext/Socket/Socket.xs
+++ b/ext/Socket/Socket.xs
@@ -435,7 +435,25 @@ inet_aton(host)
XSRETURN(1);
}
- XSRETURN_UNDEF;
+ ST(0) = &PL_sv_undef;
+#ifdef HAS_GETADDRINFO
+ {
+ struct addrinfo hints = { 0 };
+ struct addrinfo *result;
+
+ hints.ai_family = AF_INET;
+ if (!getaddrinfo(host, NULL, &hints, &result) && result) {
+ /* These two checks are just paranoia. */
+ if (result->ai_family == AF_INET && result->ai_addr->sa_family == AF_INET) {
+ ST(0) = newSVpvn_flags((char *)&((const struct sockaddr_in *)result->ai_addr)->sin_addr,
+ sizeof(ip_address), SVs_TEMP);
+ }
+ freeaddrinfo(result);
+ }
+ }
+#endif
+
+ XSRETURN(1);
}
void
--
I can't test that for sure, as I've not found a machine where I can replicate That patch, as inlined, isn't going to apply to 5.10.1's Socket.xs, or even Nicholas Clark |
From @nwc10On Mon, Mar 07, 2011 at 02:09:26PM -0800, Quanah Gibson-Mount wrote: [hmm, I had hoped that that would work]
I think if you can get rewrite the test as a single standalone file of C, and If the C code works, whereas the XS version doesn't, then we need to scratch Nicholas Clark |
From quanah@zimbra.com--On Sunday, March 06, 2011 11:35 AM +0000 Nicholas Clark <nick@ccl4.org>
I downloaded the 5.10.1 Socket code, and modified Socket.xs thusly: root@zqa-064:/tmp/q# diff -u Socket.xs.orig Socket.xs Inline Patch--- Socket.xs.orig 2011-03-07 11:59:03.640485053 -1000
+++ Socket.xs 2011-03-07 12:00:13.840461063 -1000
@@ -231,17 +231,34 @@
{
struct in_addr ip_address;
struct hostent * phe;
- int ok = (*host != '\0') && inet_aton(host, &ip_address);
- if (!ok && (phe = gethostbyname(host)) &&
- phe->h_addrtype == AF_INET && phe->h_length == 4) {
- Copy( phe->h_addr, &ip_address, phe->h_length, char );
- ok = 1;
+ if ((*host != '\0') && inet_aton(host, &ip_address)) {
+ ST(0) = newSVpvn_flags((char *)&ip_address, sizeof
- ST(0) = sv_newmortal(); void I then rebuilt Socket, installing it into a different location I then moved the system socket aside (renamed Socket.pm and Socket.xs in Still fails: zimbra@zqa-064:~/libexec$ ./qtest.pl Maybe I should be bothering the core linux devs instead? --Quanah -- Quanah Gibson-Mount Zimbra :: the leader in open source messaging and collaboration |
From quanah@zimbra.com--On Monday, March 07, 2011 10:15 PM +0000 Nicholas Clark <nick@ccl4.org>
root@zqa-064:~# ./a.out zqa-064.eng.vmware.com So it correctly gets the IPv6 and IPv4 addresses, although it doesn't have I used <http://www.logix.cz/michal/devel/various/getaddrinfo.c.xp> for the --Quanah -- Quanah Gibson-Mount Zimbra :: the leader in open source messaging and collaboration |
From @ikegamiOn Sun, Mar 6, 2011 at 6:35 AM, Nicholas Clark <nick@ccl4.org> wrote:
Or its returning an IPv6 address? Maybe it would be more appropriate to use struct hostent * gethostbyname(const char *name); |
From @nwc10On Wed Mar 02 15:35:49 2011, quanah@zimbra.com wrote:
I'm curious. How many lines of "locally applied patches" did you edit I don't think that it makes a difference to the problem, as Debian Nicholas Clark |
From @nwc10On Mon, Mar 07, 2011 at 02:09:26PM -0800, Quanah Gibson-Mount wrote:
You typed Socket.xs What matters at load time is the shared object (which on Linux is a .so, If you didn't move that, then I think that *it* will still be loaded, and On Mon, Mar 07, 2011 at 02:45:50PM -0800, Quanah Gibson-Mount wrote:
If I compile that code on an Ubuntu box, and use your first /etc/hosts, I $ ./getaddrinfo zqa-064.eng.vmware.com If I change it to pass AF_INET in the hints to getaddrinfo(), and also make it $ ./85308 zqa-064.eng.vmware.com Please could you compile the attached variant, and run it? I'm not sure what Nicholas Clark |
From @nwc10/*
* getaddrinfo.c - Simple example of using getaddrinfo(3) function.
*
* Michal Ludvig <michal@logix.cz> (c) 2002, 2003
* http://www.logix.cz/michal/devel/
*
* License: public domain.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
int
lookup_host (const char *host)
{
struct addrinfo hints, *res;
int errcode;
char addrstr[100];
void *ptr;
memset (&hints, 0, sizeof (hints));
hints.ai_family = PF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags |= AI_CANONNAME;
errcode = getaddrinfo (host, NULL, &hints, &res);
if (errcode != 0)
{
perror ("getaddrinfo");
return -1;
}
printf ("Host: %s\n", host);
while (res)
{
inet_ntop (res->ai_family, res->ai_addr->sa_data, addrstr, 100);
switch (res->ai_family)
{
case AF_INET:
ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr;
break;
case AF_INET6:
ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
break;
}
inet_ntop (res->ai_family, ptr, addrstr, 100);
printf ("IPv%d address: %s (%s)\n", res->ai_family == PF_INET6 ? 6 : 4,
addrstr, res->ai_canonname);
res = res->ai_next;
}
{
struct hostent * phe = gethostbyname(host);
char **addr;
puts("gethostbyname");
if (!phe) {
perror ("gethostbyname");
return -1;
}
addr = phe->h_addr_list;
while (*addr) {
inet_ntop (phe->h_addrtype, *addr, addrstr, 100);
printf ("IPv%d address: %s (%s)\n", phe->h_addrtype == AF_INET6 ? 6 : 4,
addrstr, phe->h_name);
++addr;
}
}
return 0;
}
int
main (int argc, char *argv[])
{
if (argc < 2)
exit (1);
return lookup_host (argv[1]);
} |
From quanah@zimbra.com--On March 8, 2011 12:51:08 PM -0800 Nicholas Clark via RT
I didn't edit any out. I sent the full report that came from perlbug. I --Quanah -- Zimbra :: the leader in open source messaging and collaboration |
From quanah@zimbra.com--On March 8, 2011 9:38:02 PM +0000 Nicholas Clark <nick@ccl4.org> wrote:
Yes, Socket.so, sorry.
Yes, I'm quite aware of that. ;)
It is what was moved, to explicitly avoid it being loaded. I will build the attached variant and let you know how it goes. --Quanah -- Zimbra :: the leader in open source messaging and collaboration |
From @ntyniOn Tue, Mar 08, 2011 at 12:51:08PM -0800, Nicholas Clark via RT wrote:
I only added proper patchlevel.h handling a year ago in Debian package It looks like at least one supported Ubuntu version ("Lucid Lynx") has |
From quanah@zimbra.com--On March 8, 2011 9:38:02 PM +0000 Nicholas Clark <nick@ccl4.org> wrote:
root@zqa-064:~# ./inettest2 zqa-064.eng.vmware.com --Quanah -- Zimbra :: the leader in open source messaging and collaboration |
From @jmcabandaraOperations logged to /tmp/install.log.22392 |
From [Unknown Contact. See original ticket]Operations logged to /tmp/install.log.22392 |
From @tonycozOn Thu May 14 10:06:09 2015, jmcabandara@gmail.com wrote:
This doesn't appear to have anything to do with the original problem in Are you trying to report a new problem? If you're having problems installing pre-built packages supplied by Tony |
From mishikal@yahoo.comOn Thu May 14 10:06:09 2015, jmcabandara@gmail.com wrote: This indicates you installed a version of ZCS that doesn't match your operating system. I.e., you installed a RHEL6 build on RHEL7, or an Ubuntu12 build on Ubuntu14, etc. |
Migrated from rt.perl.org#85308 (status was 'open')
Searchable as RT85308$
The text was updated successfully, but these errors were encountered: