Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP cURL consistently taking 15s to resolve DNS

Tags:

php

curl

I'm running PHP on a CentOS virtual machine under MacOS X, and any cURL request consistently takes 15s to run:

$c = curl_init('https://graph.facebook.com');
curl_exec($c); // takes 15s to return...
echo curl_getinfo($c, CURLINFO_NAMELOOKUP_TIME); // 15.01 seconds

However, gethostbyname() is very fast:

echo gethostbyname('graph.facebook.com'); // almost instant

And, ping resolves the name almost instantly as well.

By default, /etc/resolv.conf only had nameserver 192.168.1.1 in it, so I changed it to use the Google DNS servers:

nameserver 8.8.8.8
nameserver 8.8.4.4

But with no luck. Any hints?


Update 1: The following fixes the problem:

curl_setopt($curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);

So as far as I understand it, it's trying to resolve both IPv4 and IPv6, and IPv6 resolution fails, after a timeout of 15s.

It that because of a misconfiguration on the Linux machine?


Update 2:

dig graph.facebook.com aaaa

;; reply from unexpected source: 10.0.2.2#53, expected 192.168.1.1#53
;; reply from unexpected source: 10.0.2.2#60944, expected 192.168.1.1#53
;; reply from unexpected source: 10.0.2.2#53, expected 192.168.1.1#53

; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.17.rc1.el6_4.4 <<>> graph.facebook.com aaaa
;; global options: +cmd
;; connection timed out; no servers could be reached
like image 593
BenMorel Avatar asked Jul 23 '13 15:07

BenMorel


People also ask

Is PHP cURL secure?

Curl is as secure as a normal HTTP request.

Does cURL use PHP?

Uses of cURL in PHP cURL is a PHP extension that allows you to use the URL syntax to receive and submit data. cURL makes it simple to connect between various websites and domains.

What is Curl_setopt?

The curl_setopt() function will set options for a CURL session identified by the ch parameter. The option parameter is the option you want to set, and the value is the value of the option given by the option.


2 Answers

The problem was an IPv6 lookup failing on my machine. The solution:

Changed /etc/resolv.conf to:

nameserver 8.8.8.8
nameserver 8.8.4.4

After rebooting, resolv.conf got overwritten, so adding this line to /etc/sysconfig/network-scripts/ifcfg-eth0 (which was using BOOTPROTO=dhcp) fixed the problem:

PEERDNS=no

And everything now works like a charm.

As an alternative, if you experience this problem on a server on which you can not change the configuration, configure cURL this way:

curl_setopt($curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
like image 72
BenMorel Avatar answered Oct 05 '22 15:10

BenMorel


With PHP 7.1.32 installed with brew on macos, I got exactly this problem. file_get_contents and curl do not use the same DNS.

Like @schumyxp said, you can resolve manually first:

<?php
$ip = gethostbyname("XXXXX.infra");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://" . $ip);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Host: XXXXX.infra'));

BTW it's may be a good to force an IP instead of rely on a resolver.

like image 39
Thomas Decaux Avatar answered Oct 05 '22 14:10

Thomas Decaux