perlin-network / noise

A decentralized P2P networking stack written in Go.
https://godoc.org/github.com/perlin-network/noise
MIT License
1.79k stars 211 forks source link

Node Listen blocks indefinitely when assigned port is already taken #281

Open lrahmani opened 4 years ago

lrahmani commented 4 years ago

Issue

When a node is created with noise.NewNode with a specific port number, if the port is already taken (* noise.Node) Listen will hugs indefinitely, even if the port is release and made available later.

Expected behavior

I expect (* noise.Node) Listen to immediately return an error.

How to reproduce it

This behavior is entirely reproducible using the chat example running on a ubuntu:18.4-based docker image.

  1. get the chat example go get -d -v github.com/perlin-network/noise/cmd/chat
  2. start a netcat server listening on port 10123 nc -l -p 10123
  3. run the chat example using the same port go run github.com/perlin-network/noise/cmd/chat -p 10123

How to bypass the issue (workaround)

One can test if the port is already taken before calling (* noise.Node) Listen by binding to it using net.ListenTCP. If the call is successful immediately close the listener and proceed to (* noise.Node) Listen. If the call is unsuccessful report the error produced by net.ListenTCP.

Here is a sample:

// ...
address := "127.0.0.1:10123"
tcp_addr, err := net.ResolveTCPAddr("tcp", address)
if err != nil {
  return err
}
listener, err := net.ListenTCP("tcp", tcp_addr)
if err != nil {
  return err
}
listener.Close()
err = node.Listen()