Curl IPv4 – How to Ensure Curl Falls Back to IPv4

dockergentooipv6linuxlinux-networking

I have gentoo build with ipv6 and ipv4 configured for localhost

/etc/hosts

# IPv4 and IPv6 localhost aliases
127.0.0.1   sunils-pc.homenetwork sunils-pc localhost
::1     sunils-pc.homenetwork sunils-pc localhost

I have enabled the ipv6 forward as below

sunils@sunils-pc ~ $ cat /proc/sys/net/ipv6/conf/all/forwarding
1

sunils@sunils-pc ~ $ cat /proc/sys/net/ipv4/conf/all/forwarding
1

I have ran the docker swarm with docker container exposing web server at 8080. I can access the website using below command

curl -4 http://localhost:8080/

But when I try to access it using curl http://localhost:8080/ it hangs for infinite time. From the verbose output it shows its trying to reach the service at ipv4 address and hangs indefinitely without falling back to ipv4.

sunils@sunils-pc ~ $ curl -v http://localhost:8080
* Rebuilt URL to: http://localhost:8080/
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.61.0
> Accept: */*
> 

I am not sure where should I investigate further. I am running gentoo linux with ipv6 enabled kernel.

==Update

When I use ipv4 I get the proper HTTP response on terminal, but in case of ipv6 it hangs indefinitely.

sunils@sunils-pc ~ $ curl -4 -v http://localhost:8080
* Rebuilt URL to: http://localhost:8080/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.61.0
> Accept: */*
> 
< HTTP/1.1 200 
< Set-Cookie: XSRF-TOKEN=e20b76f1-78c3-473c-a518-da2519983985; Path=/
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Content-Type: text/html;charset=UTF-8
< Content-Language: en-US
< Transfer-Encoding: chunked
< Date: Wed, 26 Sep 2018 17:13:11 GMT
< 
<!doctype html>
...

Best Answer

It appears that you are successfully connecting to the port via ipv6, per the following message:

* Connected to localhost (::1) port 8080 (#0)

Since the connection has entered the ESTABLISHED state, curl deems this as a successful connection to the IPv6 host, and it is correct.

The next thing that happens is that the curl client sends the HTTP request to the localhost(::1) on port 8080. However, the server never responds back with the document that you expect.

There's no reason at this point why curl would re-try with IPv4 as the connection was established with IPv6, however, the server did not send the HTTP payload.

It appears that the issue may be with the server not being properly bound to the IPv6 port, there are two instances of the server running both trying to bind to the IPv6 port 8080, or another problem with the server being bound to the IPv6 port that does not replicate when you use IPv4.