WordPress.org

Make WordPress Core

Opened 6 years ago

Last modified 19 months ago

#21446 reopened enhancement

plugins using curl with IPV6 enabled servers

Reported by: mippie32 Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 3.4.1
Component: HTTP API Keywords: close
Focuses: Cc:

Description

plugins using curl give problems on servers having both IPV4 and IPV6 network interfaces running. Basically the performance is poor because curl is timing out on the IPv6 address.. The workaround is:

add line: curl_setopt( $handle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); in ../wp-includes/class-http.php

Why not have this set as default?

Change History (9)

#1 @SergeyBiryukov
6 years ago

  • Component changed from Plugins to HTTP

#2 follow-up: @markoheijnen
6 years ago

If I'm correct this will not allow IPv6 right? so making it default would be temporarily? If so then this looks like plugin material to me. I do believe you can mange this by using a filter.

#3 in reply to: ↑ 2 @SteveAtty
6 years ago

Replying to markoheijnen:

If I'm correct this will not allow IPv6 right? so making it default would be temporarily? If so then this looks like plugin material to me. I do believe you can mange this by using a filter.

It forces Curl to use IPv4 resolution rather than attempting IPv6 resolution and if that fails then trying IPv4 resolution. Or that is what the documentation suggests

#4 @markoheijnen
6 years ago

And what happens when servers only have IPv6? You got a problem then with this solution?

#5 @mippie32
6 years ago

@marko,

Good point. Yes, when only IPV6 the plugin(s) with curl wouldnt work. Yeah, basically the plugin itself is the culprit.. but given the fact curl itself has a problem with mixed IPV4/IPV6 ???

#6 @dd32
6 years ago

  • Keywords close added; needs-testing removed

While I've never had a issue with curl and ipv4/6 connections.. googling around does indeed suggest curl has issues in certain circumstances.

Specifically, if the server claims to support ipv6 routing to a global subnet, and it doesn't, curl will simply timeout connecting to the ipv6 address and return a connection error, whereas most browsers would attempt the ipv6 connection, expect users to have bad configurations, and attempt an ipv4 connection.

Ultimately this is down to a server misconfiguration - either the one curl is running on, or the server being connected to, one is advertising itself as ipv6 enabled when it actually isn't (or there's network issues).

I don't think that disabling ipv6 globally for all instances of WP_HTTP is a viable option, it's not in the spirit of progress.. If anything, we should do all that we can to enable transitions to take place (which we are doing, by supporting ipv6 in any way that we need to).

A work around for servers with bad configurations would be using the filters available and doing something like this in a plugin or mu-plugin even.

add_action( 'http_api_curl', function( $curl_handle ) {
   curl_setopt( $curl_handle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );
});

#7 @dd32
5 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to worksforme
  • Status changed from new to closed

We can't lock WP_HTTP down to just IPv4, IPv6 adoption is increasing, it's only a matter of time until we hit IPv6-only servers in the wild.

Hosting environments need to be sane, if they have an incorrectly configured cURL or ethernet interface, issues like this are possible, but entirely avoidable by proper configuration.

In the event that someone else runs into an issue such as this, we can re-open to investigate further, and, perhaps consider having IPv6-failure detection added.

#8 @svovaf
20 months ago

  • Resolution worksforme deleted
  • Status changed from closed to reopened

I'm not sure if I should open a new ticket or put it here. We are rewriting [Freemius](https://freemius.com) cURL based SDK to work directly with wp_remote to support websites without cURL. While rewriting the SDK I stumbled in a use-case that seems to be not covered by the Requests_Transport_cURL. With dual stacked DNS responses, it's possible for a server to have IPv6 enabled but not have IPv6 connectivity. If this is the case, cURL will try IPv4 first and if that fails, then it will fall back to IPv6 and the error EHOSTUNREACH will be returned by the operating system.

Here's a code we've been using to tackle it on (I think it was originally inspired by the login in the Facebook SDK):

<?php
// With dual stacked DNS responses, it's possible for a server to
// have IPv6 enabled but not have IPv6 connectivity.  If this is
// the case, curl will try IPv4 first and if that fails, then it will
// fall back to IPv6 and the error EHOSTUNREACH is returned by the
// operating system.
if ( false === $result && empty( $opts[ CURLOPT_IPRESOLVE ] ) ) {
        $matches = array();
        $regex   = '/Failed to connect to ([^:].*): Network is unreachable/';
        if ( preg_match( $regex, curl_error( $pCurlHandler ), $matches ) ) {
                if ( strlen( @inet_pton( $matches[1] ) ) === 16 ) {
//                        errorLog('Invalid IPv6 configuration on server, Please disable or get native IPv6 on your server.');
                        curl_setopt( $pCurlHandler, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );
                }
        }
}

Any idea of how can we tackle it?

Another issue worth mentioning is that cURL < v.7.37 doesn't support SSLv3, so all HTTPS requests to servers with the new protocol will basically fail. I didn't see any code related to that in the Requests_Transport_cURL.

#9 @netweb
19 months ago

  • Milestone set to Awaiting Review

Moving reopened tickets without a milestone back to Awaiting Review for review

Note: See TracTickets for help on using tickets.