Skip to content
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

curl: (45) bind failed with errno 22: Invalid argument #3993

Closed
gralex54 opened this issue Jun 6, 2019 · 9 comments
Closed

curl: (45) bind failed with errno 22: Invalid argument #3993

gralex54 opened this issue Jun 6, 2019 · 9 comments

Comments

@gralex54
Copy link

gralex54 commented Jun 6, 2019

Hello,

Error

An error curl: (45) bind failed with errno 22: Invalid argument occurs whenever we specify IPv4 from local interface as a source address trying to connect to a site which have both IPv4 and IPv6.

Steps to reproduce

Pick up a domain which resolves both to IPv4 and IPv6:

# host canhazip.com
canhazip.com has address 104.16.222.38
canhazip.com has address 104.16.223.38
canhazip.com has IPv6 address 2606:4700::6810:de26
canhazip.com has IPv6 address 2606:4700::6810:df26

The request:

# curl --interface 1.2.3.4 https://canhazip.com/
curl: (45) bind failed with errno 22: Invalid argument

can be fixed with -4 flag:

# curl --interface 1.2.3.4 -4 https://canhazip.com/
1.2.3.4 

OS

Tested with CentOS 7:

  • default version cURL: curl-7.29.0-51.el7.x86_64
  • and from a git repository: curl 7.65.1-DEV (x86_64-unknown-linux-gnu) libcurl/7.65.1-DEV OpenSSL/1.0.2k-fips zlib/1.2.7

Results are the same.

Expected behavior:

Whenever a source IPv4 is specified cURL should auto add -4 flag, i.e.:

curl_easy_setopt(easyhandle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);

The same with IPv6, whenever a source IPv6 is specified cURL should auto add -6 flag, i.e.

curl_easy_setopt(easyhandle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6);

Regards,
Alex.

@bagder
Copy link
Member

bagder commented Jun 7, 2019

Related issue: #686

@gralex54
Copy link
Author

gralex54 commented Jun 8, 2019

So whenever I specify --interface 1.2.3.4 cURL tries to connect to the destination address from an unusable IPv6. Do I understand it correct?

And the related issue #686 has been reported 3 years ago, so I can conclude it won't be fixed. Correct?

@bagder
Copy link
Member

bagder commented Jun 8, 2019

So whenever I specify --interface 1.2.3.4 cURL tries to connect to the destination address from an unusable IPv6. Do I understand it correct?

No, I don't think that's even close. The problem with the current local bind code is that it works rather independently of the remote end which creates this weirdo problems with v4 vs v6 or problems with different v6 scopes.

And the related issue #686 has been reported 3 years ago, so I can conclude it won't be fixed. Correct?

It means that the issue has been reported and we know about it but nobody has yet fixed it. It is a bug and we'd like to have it fixed.

@gralex54
Copy link
Author

gralex54 commented Jun 8, 2019

@bagder
Copy link
Member

bagder commented Jun 8, 2019

I don't think so. I believe this problem you see happens because curl first resolves the host name and tries to connect to it (over both IPv4 and IPv6), and also tries to bind that socket to the address you've asked - without properly caring for IP version mixes.

A proper fix would probably be something like:

if --interface is provided with an IPv4 address, curl should disable trying to use IPv6 completely since it can't bind such a socket to the IPv4 address.

@gralex54
Copy link
Author

gralex54 commented Jun 8, 2019

And the code snippet shows how to detect which IP is specified in --interface, whether it belongs either to AF_INET or AF_INET6 address family.

Actually found the issue in Zabbix first, they use cURL library, and connections to monitored hosts over HTTP/HTTPs fails in mentioned here cases. Reported the issue to https://support.zabbix.com/browse/ZBX-16082

Kindly advise.

Regards,
Alex.

@bagder
Copy link
Member

bagder commented Jun 8, 2019

Not necessary, since all the info is already there. We just need to fix the detection logic. Something like I've tried now in #4002. Can you see if this works or if you can make it work?

@gralex54
Copy link
Author

gralex54 commented Jun 9, 2019

Thanks. The suggested patch works.

@bagder
Copy link
Member

bagder commented Jun 10, 2019

Excellent, thanks for confirming!

@bagder bagder closed this as completed in 1667d55 Jun 10, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Sep 8, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Development

Successfully merging a pull request may close this issue.

2 participants