Skip to content

Commit

Permalink
fix: infinite loop when connection is aborted before being accepted (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
diegomrsantos authored Aug 7, 2024
1 parent 6ec038d commit cde5ed7
Showing 1 changed file with 23 additions and 20 deletions.
43 changes: 23 additions & 20 deletions libp2p/transports/tcptransport.nim
Original file line number Diff line number Diff line change
Expand Up @@ -230,40 +230,43 @@ method accept*(self: TcpTransport): Future[Connection] =
raise newTransportClosedError()

if self.acceptFuts.len <= 0:
# Holds futures representing ongoing accept calls on multiple servers.
self.acceptFuts = self.servers.mapIt(it.accept())

let
finished =
try:
# Waits for any one of these futures to complete, indicating that a new connection has been accepted on one of the servers.
await one(self.acceptFuts)
except ValueError:
raise (ref TcpTransportError)(msg: "No listeners configured")

index = self.acceptFuts.find(finished)
transp =
try:
await finished
except TransportTooManyError as exc:
debug "Too many files opened", exc = exc.msg
return nil
except TransportAbortedError as exc:
debug "Connection aborted", exc = exc.msg
return nil
except TransportUseClosedError as exc:
raise newTransportClosedError(exc)
except TransportOsError as exc:
raise (ref TcpTransportError)(msg: exc.msg, parent: exc)
except common.TransportError as exc: # Needed for chronos 4.0.0 support
raise (ref TcpTransportError)(msg: exc.msg, parent: exc)
except CancelledError as exc:
raise exc

# A new connection has been accepted. The corresponding server should immediately start accepting another connection.
# Thus we replace the completed future with a new one by calling accept on the same server again.
self.acceptFuts[index] = self.servers[index].accept()
let transp =
try:
await finished
except TransportTooManyError as exc:
debug "Too many files opened", exc = exc.msg
return nil
except TransportAbortedError as exc:
debug "Connection aborted", exc = exc.msg
return nil
except TransportUseClosedError as exc:
raise newTransportClosedError(exc)
except TransportOsError as exc:
raise (ref TcpTransportError)(msg: exc.msg, parent: exc)
except common.TransportError as exc: # Needed for chronos 4.0.0 support
raise (ref TcpTransportError)(msg: exc.msg, parent: exc)
except CancelledError as exc:
raise exc

if not self.running: # Stopped while waiting
await transp.closeWait()
raise newTransportClosedError()

self.acceptFuts[index] = self.servers[index].accept()

let remote =
try:
transp.remoteAddress
Expand Down

0 comments on commit cde5ed7

Please sign in to comment.