Concordium / concordium-client

A command line client to interact with the concordium-node
Apache License 2.0
8 stars 6 forks source link

Does not work with localhost only 127.0.0.1 #49

Open martoko opened 3 years ago

martoko commented 3 years ago

Bug Description Running concordium-client --grpc-ip localhost --grpc-port 10000 consensus status results in Error: I/O error: Cannot establish connection to GRPC endpoint..

Whereas running concordium-client --grpc-ip 127.0.0.1 --grpc-port 10000 consensus status works just fine.

Other programs work fine with localhost.

⟩ ping -4 localhost
PING  (127.0.0.1) 56(84) bytes of data.
64 バイト応答 送信元 localhost (127.0.0.1): icmp_seq=1 ttl=64 時間=0.021ミリ秒
64 バイト応答 送信元 localhost (127.0.0.1): icmp_seq=2 ttl=64 時間=0.028ミリ秒
64 バイト応答 送信元 localhost (127.0.0.1): icmp_seq=3 ttl=64 時間=0.023ミリ秒

And localhost has been configured correctly in /etc/hosts

⟩ cat /etc/hosts
127.0.0.1 localhost
127.0.0.1 localhost.localdomain
127.0.0.1 local
255.255.255.255 broadcasthost
::1 localhost
::1 ip6-localhost
::1 ip6-loopback
fe80::1%lo0 localhost
ff00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts

Steps to Reproduce Run concordium-client --grpc-ip localhost --grpc-port 10000 consensus status in an Arch Linux installation with a node running on port 10000.

Expected Result Should output consensus status.

Actual Result Gives an error.

Versions concordium-node 1.0.1 concordium-client 1.0.1 Operating System: Arch Linux
Kernel: Linux 5.12.14-arch1-1 Architecture: x86-64

Further details The node is bound on IPv4 only.

⟩ sudo lsof -i:10000
COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
concordiu 1653 root   30u  IPv4  29462      0t0  TCP *:ndmp (LISTEN)

Running netcat on both localhost and 127.0.0.1 seems to output some data, suggesting that a connection has been established.

⟩ netcat localhost 10000

@^C⏎                                                                                                                                                               
⟩ netcat 127.0.0.1 10000

@^C⏎                                                                                                                                                               

Naturally running netcat on the IPv6 localhost does not work.

⟩ netcat ::1 10000

Further experimentation reveals that by binding the node on the IPv6 localhost by setting Environment=RPC_SERVER_ADDR=::1 makes the command work with localhost.

This makes sense as localhost resolves to both 127.0.0.1 and ::1, but concordium-node is only running on one of these by default.

Maybe the concordium-node should bind to both IPv4 and IPv6 by default, or the concordium-client should be able to handle localhost returning both IPv4 and IPv6 addresses (something which other programs such as netcat seems to be able to do just fine).

abizjak commented 3 years ago

Thank you for the report.

I don't think the correct solution is to bind both addresses by default. I think this needs to be an explicit choice by the node operator.

But indeed, this is an annoying issue, but it is ultimately a limitation of the http2-client library which is used by the GRPC client library which just takes the first address returned from address lookup, see https://hackage.haskell.org/package/http2-client-0.10.0.0/docs/src/Network.HTTP2.Client.RawConnection.html#newRawHttp2Connection

It would be good to make this more robust, but it is unfortunately not as straightforward to fix as it could be.