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

--interface for ipv6 binds to unusable IP address #686

Closed
arnottcr opened this Issue Feb 28, 2016 · 7 comments

Comments

Projects
None yet
2 participants
@arnottcr

arnottcr commented Feb 28, 2016

I did this

curl --verbose --interface eth0 ipv6.google.com

I received the following output

* Rebuilt URL to: ipv6.google.com/
*   Trying 2607:f8b0:400c:c06::71...
* Local Interface eth0 is ip fdde:xxxx:xxxx:xxxx:xxxx:xxff:fexx:xxxx using address family 10
* SO_BINDTODEVICE eth0 failed with errno 1: Operation not permitted; will do regular bind
* Local port: 0
* connect to 2607:f8b0:400c:c06::71 port 80 failed: Permission denied
* Failed to connect to ipv6.google.com port 80: Permission denied
* Closing connection 0
curl: (7) Failed to connect to ipv6.google.com port 80: Permission denied

I have this machine sitting behind an openwrt router that sets up public facing ipv6 addresses, the actual route that I would like curl to take, and a unique-local subnet (as described in RFC 5156). Curl appears to prefer this fdde:: address, as it is listed first in ip addr output.

[user@localhost ~]$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.1/24 brd 10.0.0.255 scope global enp2s0
       valid_lft forever preferred_lft forever
    inet6 fdde:xxxx:xxxx:xxxx:xxxx:xxff:fexx:xxxx/64 scope global mngtmpaddr dynamic 
       valid_lft forever preferred_lft forever
    inet6 xxxx:xxxx:xxxx:xxxx:xxxx:xxff:fexx:xxxx/64 scope global mngtmpaddr dynamic 
       valid_lft 86400sec preferred_lft 86400sec
    inet6 fe80:xxxx:xxxx:xxxx:xxxx:xxff:fexx:xxxx/64 scope link 
       valid_lft forever preferred_lft forever

If I run curl --interface '<public ipv6 address>' ipv6.google.com, this succeeds, but as my client's ipv6 address is dynamic, it is not feasible to hardcore this.

If I run curl ipv6.google.com, this succeeds, but my client has multiple interfaces, it uses the wrong one.

Since the fc00::/7 is a reserved block, would it be possible to intelligently match the bind address based on the destination address?

  • google.com → 2607:f8b0:4002:c08::71 → use a public address
  • example.com → fdde:: → use an address in fc00::/7

curl/libcurl version

curl 7.47.1 (x86_64-pc-linux-gnu) libcurl/7.47.1 OpenSSL/1.0.2f zlib/1.2.8 libidn/1.32 libssh2/1.7.0
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp 
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz TLS-SRP UnixSockets

operating system

Arch Linux: Linux 4.4.1-2-ARCH #1 SMP PREEMPT x86_64 GNU/Linux

@bagder

This comment has been minimized.

Member

bagder commented Mar 20, 2016

would it be possible to intelligently match the bind address based on the destination address?

That seems... tricky. Why would 'example.com' use a different address? It typically resolves to an address just as good as google.com etc.

@arnottcr

This comment has been minimized.

arnottcr commented Mar 21, 2016

so, my request would be to match at the IP level, not the domain level.

if you are trying to reach:
-fe80::2, use an address in fe80::/10
-fdde::2, use an address in fc00::/7
-2000::2, use a non Special-Use ip address

you could even use the subnet mask to more explicitly specify which inet6 address should be used, because there could be more complex subnetting defined, over the defaults spesified in RFC5156.

Is this clear, or should I elaborate more?

@bagder bagder changed the title from curl chooses the wrong bind address to select bind address based on IP Mar 21, 2016

@bagder

This comment has been minimized.

Member

bagder commented Mar 21, 2016

It is clear what you'd like. It is also clear to me that this is not a bug and it couldn't do this by default, but sure one could imagine a feature that allows curl to work like this. Feel free to suggest a patch, I personally don't see this as a very high prio feature.

@arnottcr

This comment has been minimized.

arnottcr commented Mar 21, 2016

So, I realize that my solution is complex and likely constitutes a feature request, however there does seem to be bug at the root of my inquiry.

By default, curl -6 ipv6.google.com has some automation logic to select a valid inet6 address that can reach ipv6.google.com, however curl -6--interface eth0 ipv6.google.com uses different logic that fails to connect after deciding to bind to the first inet6 address it tries.

I designed a solution that should work optimally, and while requiring more code, would prevent nasty timeout issues, or other corner case related hassles. However, if you simply applied the same automation logic that can be seen in curl -6 ipv6.google.com to curl -6--interface eth0 ipv6.google.com, this could constitute a stop gap measure. Either way, this seems like a bug do you disagree?

@bagder

This comment has been minimized.

Member

bagder commented Mar 21, 2016

Yes, using --interface with IPv6 requires more careful considerations than what is currently done and yes, binding to an address than then makes the connection fail instead of binding to one that would work I think is a bug.

I would probably suggest that an ipv6 binding would start with the widest possible scoped address instead of just the one that happens to be first.

@arnottcr

This comment has been minimized.

arnottcr commented Mar 22, 2016

In that case, would it be of merit to spin your aforementioned fix, as a separate issue, leaving this for the more complete rfe?

@bagder bagder removed the feature-request label Mar 23, 2016

@bagder bagder changed the title from select bind address based on IP to --interface for ipv6 binds to unusable IP address Mar 23, 2016

@bagder

This comment has been minimized.

Member

bagder commented Mar 23, 2016

lets make this issue about the bug

@bagder bagder closed this in 27a6393 Apr 25, 2016

@lock lock bot locked as resolved and limited conversation to collaborators May 7, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.