@@ -126,6 +126,7 @@ pub struct Handler {
126126 local_peer_id : PeerId ,
127127 remote_peer_id : PeerId ,
128128 remote_addr : Multiaddr ,
129+ /// A pending fatal error that results in the connection being closed.
129130 pending_error : Option <
130131 ProtocolsHandlerUpgrErr <
131132 EitherError < inbound_stop:: UpgradeError , outbound_hop:: UpgradeError > ,
@@ -158,6 +159,10 @@ pub struct Handler {
158159
159160 circuit_deny_futs : FuturesUnordered < BoxFuture < ' static , ( PeerId , Result < ( ) , std:: io:: Error > ) > > ,
160161
162+ /// Futures that try to send errors to the transport.
163+ ///
164+ /// We may drop errors if this handler ends up in a terminal state (by returning
165+ /// [`ProtocolsHandlerEvent::Close`]).
161166 send_error_futs : FuturesUnordered < BoxFuture < ' static , ( ) > > ,
162167}
163168
@@ -392,14 +397,19 @@ impl ProtocolsHandler for Handler {
392397 }
393398 }
394399
395- self . send_error_futs . push (
396- async move {
397- let _ = to_listener
398- . send ( transport:: ToListenerMsg :: Reservation ( Err ( ( ) ) ) )
399- . await ;
400- }
401- . boxed ( ) ,
402- ) ;
400+ if self . pending_error . is_none ( ) {
401+ self . send_error_futs . push (
402+ async move {
403+ let _ = to_listener
404+ . send ( transport:: ToListenerMsg :: Reservation ( Err ( ( ) ) ) )
405+ . await ;
406+ }
407+ . boxed ( ) ,
408+ ) ;
409+ } else {
410+ // Fatal error occured, thus handler is closing as quickly as possible.
411+ // Transport is notified through dropping `to_listener`.
412+ }
403413
404414 self . queued_events . push_back ( ProtocolsHandlerEvent :: Custom (
405415 Event :: ReservationReqFailed { renewal } ,
0 commit comments