After hours of trying to debug a third-party application having trouble with fopen(), i finally discovered that
php -r 'echo(file_get_contents("http://www.google.com/robots.txt"));'
fails, but
php -r 'echo(file_get_contents("http://173.194.32.81/robots.txt"));'
Succeeds. Note that as the webserver user, I can ping www.google.com and it resolves just fine.
I straced both executions of PHP, and they diverge like this:
For the numerical v4 URL:
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
fcntl(3, F_GETFL) = 0x2 (flags O_RDWR)
fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
connect(3, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("173.194
poll([{fd=3, events=POLLOUT}], 1, 0) = 0 (Timeout)
...[bunch of poll/select/recvfrom]...
close(3) = 0
For the domain name:
socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP) = 3
close(3) = 0
PHP didn't even try to do anything with that socket, it seems. Or even resolve the domain, for that matter. WTF ?
Recompiling PHP with or without ipv6 support did not seem to matter. Disabling ipv6 on this system is not desirable.
Gentoo Linux, PHP 5.3.14, currently giving a try to PHP 5.4 and see if it helps. Anyone has an idea ?
EDIT:
php -r 'echo gethostbyname("www.google.com");'
Works and yield an ipv4, while
php -r 'echo(file_get_contents("http://[2a00:1450:4007:803::1011]/"));'
Seems to return a blank result.
EDIT 2:
I didn't even notice the first time, that the v6 socket opened when the name is used is a SOCK_DGRAM. Is this PHP trying to resolve the domain name ? I tried switching my resolver from 127.0.0.1 to ::1 in resolv.conf, and it didn't help.
GDB showed that that mysterious unused socket call actually came from libcurl. I recompiled php without libcurl and it works. I'll keep investigating the cause, but so far the workaround seems to work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With