Dubious logic in `TcpStream::connect`
Due to the current implementation of TcpStream::connect
(!473 (merged)), picodata run
appears to be broken in certain setups (many modern linux distributions e.g. Arch, Fedora; Mac):
$ picodata run
...
2024-04-26 12:16:08.171 [574389] main/103/interactive I> tx_binary: bound to [::1]:3301
2024-04-26 12:16:08.171 [574389] main/103/interactive/box.load_cfg I> set 'listen' configuration option to "localhost:3301"
2024-04-26 12:16:08.173 [574389] main/103/interactive discovery.rs:199 W> calling .proc_discover failed to 'localhost:3301' failed: failed to connect to address 'localhost:3301': Connection refused (os error 111)
2024-04-26 12:16:08.373 [574389] main/103/interactive discovery.rs:199 W> calling .proc_discover failed to 'localhost:3301' failed: failed to connect to address 'localhost:3301': Connection refused (os error 111)
2024-04-26 12:16:08.574 [574389] main/103/interactive discovery.rs:199 W> calling .proc_discover failed to 'localhost:3301' failed: failed to connect to address 'localhost:3301': Connection refused (os error 111)
...
$ picodata run --listen localhost:3301
...
2024-04-26 12:16:08.171 [574389] main/103/interactive I> tx_binary: bound to [::1]:3301
2024-04-26 12:16:08.171 [574389] main/103/interactive/box.load_cfg I> set 'listen' configuration option to "localhost:3301"
2024-04-26 12:16:08.173 [574389] main/103/interactive discovery.rs:199 W> calling .proc_discover failed to 'localhost:3301' failed: failed to connect to address 'localhost:3301': Connection refused (os error 111)
2024-04-26 12:16:08.373 [574389] main/103/interactive discovery.rs:199 W> calling .proc_discover failed to 'localhost:3301' failed: failed to connect to address 'localhost:3301': Connection refused (os error 111)
2024-04-26 12:16:08.574 [574389] main/103/interactive discovery.rs:199 W> calling .proc_discover failed to 'localhost:3301' failed: failed to connect to address 'localhost:3301': Connection refused (os error 111)
...
The key takeaway here is that localhost
has been resolved to an IPv6 address [::1]
in the server socket binding logic, but the connection establishing function used by picodata run
:
- prioritizes IPv4 addresses (which is fine)
- only tries to connect to a first IPv4 address, completely disregarding IPv6 addresses (which is wrong).
Furthermore, nonblocking_socket()
is also flawed, because it only creates IPv4 sockets (AF_INET
), whereas IPv6 sockets require AF_INET6
.
While it is true that the problem can be solved by using an explicit IPv4 address (i.e. picodata run --listen 127.0.0.1:3301
), at the very least we should fix the defaults in picodata run
.
Addendum: example of a correct solution to this problem:
Edited by Dmitry Ivanov