crystal-lang / crystal

The Crystal Programming Language
https://crystal-lang.org
Apache License 2.0
19.21k stars 1.61k forks source link

Default to INET6 for TCPServer, TCPSocket and UDPSocket #14688

Closed carlhoerberg closed 3 weeks ago

carlhoerberg commented 3 weeks ago

Any reason why Family in TCPServer, TCPSocket and UDPSocket defaults to INET and not INET6?

Noticed that

s = TCPServer.new
s.bind("::1", 0)

resulted in

Hostname lookup for ::1 failed: Address family for hostname not supported (Socket::Addrinfo::Error)
carlhoerberg commented 3 weeks ago

Probably should not include TCPSocket nor UDPSocket in this PR..

straight-shoota commented 3 weeks ago

I don't think we can do this. It would break existing code like this where a v4 address gives exactly the same error you're experiencing:

s = TCPServer.new
s.bind("127.0.0.1", 0)

The address family is specified in the constructor. If we change the default value, all use cases expecting the current behaviour would break.

I'm afraid if you need a different value than the default v4, you'll need to state that explicitly in the constructor.

straight-shoota commented 3 weeks ago

We might consider making the default family configurable via a class property: TCPSocket.default_family = :INET6 could declare a preference for the entire application. Not sure if that would be much helpful, though.

ysbaddaden commented 3 weeks ago

Hum, the problem lies in the design: we create the socket before we resolve the address that may be an IPv4 or IPv6. Maybe we could delay the creation of the actual socket :thinking: Nope, that would hinder on Socket itself, the TCPServer's constructor is meant to be TCPServer.new(host, port) that is first resolve the address using Addrinfo and use the result to create the actual socket.