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

IO::Socket::INET fails to connect if a resource is available over IPv6 and the client is misconfigured to use IPv6 #3590

Open
p6rt opened this issue Nov 23, 2014 · 3 comments
Labels

Comments

@p6rt
Copy link

p6rt commented Nov 23, 2014

Migrated from rt.perl.org#123282 (status was 'new')

Searchable as RT123282$

@p6rt
Copy link
Author

p6rt commented Nov 23, 2014

From @hoelzro

I have a machine that gets IPv6 router advertisements, but IPv6 isn't correctly routed. When I run the following code​:

  IO​::Socket​::INET.new(​:host<feather.perl6.nl>, :port(3000))

rakudo tries to connect to feather.perl6.nl​:3000 over IPv6, which doesn't work. When it doesn't work, it doesn't try IPv4; it just fails. If I specify the socket family​:

  IO​::Socket​::INET.new(​:host<feather.perl6.nl>, :port(3000), :family(2)) # 2 is INET

...the family parameter is not respected. I've disabled IPv6 on the machine for the time being, but I figured that others might run into this situation.

@p6rt
Copy link
Author

p6rt commented Oct 19, 2015

From @jonathanstowe

Hi,
the background for this is in

sergot/http-useragent#92

It presumably hasn't been picked up earlier because no-one has tested on an IPV6 enabled network.

It appears that if the network connection has IPV6 and the host has an AAAA record then IO​::Socket​::INET will attempt to connect first to the V6 address despite the family default being unchanged from PIO​::SOCK_INET, if this attempt fails to connect (in the case in the bug report above, the server isn't listening on V6,) then the IPV4 isn't tried and the connection fails.

I think that for least surprise it should probably only attempt to connect on the socket family request, however if the V6 behaviour is to stay it should attempt both V6 and V4 and only fail if it isn't able to create either connection.

I might add I am personally not able to test on V6 just passing on a triaged 3rd party report.

@p6rt
Copy link
Author

p6rt commented Mar 22, 2016

From @jonathanstowe

There's actually a much simpler test for this and this was noticed in the wild as an issue against CheckSocket.

If you you have an /etc/hosts that does something like​:

  127.0.0.1 localhost
  :​:1 localhost

(Which seems to be perfectly valid - FreeBSD for instance will create a hosts file like this if it is configured for IPv6 as well as v4,)

And you have some code that does something like​:

  my $socket = IO​::Socket​::INET.new(localhost => 'localhost', localport => $port, listen => True);
  loop {
  my $client = $socket.accept;
  }

Then​:

  IO​::Socket​::INET.new(host => '127.0.0.1', port => $port)

Will fail, as will swapping the numeric IP and name in the server and client. Because you can't either specify the address family to be used, nor determine from the server socket which family it has been bound with there is no way to work around this which is somewhat unfortunate.

I think this kind of thing is going to come up more often as people start making network applications.

 

@p6rt p6rt added the IO label Jan 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant