@@ -22,6 +22,7 @@ use crate::protocol::{
2222 IdentifyInfo , IdentifyProtocol , IdentifyPushProtocol , InboundPush , OutboundPush ,
2323 ReplySubstream , UpgradeError ,
2424} ;
25+ use futures:: future:: BoxFuture ;
2526use futures:: prelude:: * ;
2627use futures_timer:: Delay ;
2728use libp2p_core:: either:: { EitherError , EitherOutput } ;
@@ -30,6 +31,7 @@ use libp2p_swarm::{
3031 ConnectionHandler , ConnectionHandlerEvent , ConnectionHandlerUpgrErr , KeepAlive ,
3132 NegotiatedSubstream , SubstreamProtocol ,
3233} ;
34+ use log:: warn;
3335use smallvec:: SmallVec ;
3436use std:: { io, pin:: Pin , task:: Context , task:: Poll , time:: Duration } ;
3537
@@ -39,6 +41,7 @@ use std::{io, pin::Pin, task::Context, task::Poll, time::Duration};
3941/// at least one identification request to be answered by the remote before
4042/// permitting the underlying connection to be closed.
4143pub struct IdentifyHandler {
44+ inbound_identify_push : Option < BoxFuture < ' static , Result < IdentifyInfo , UpgradeError > > > ,
4245 /// Pending events to yield.
4346 events : SmallVec <
4447 [ ConnectionHandlerEvent <
@@ -80,6 +83,7 @@ impl IdentifyHandler {
8083 /// Creates a new `IdentifyHandler`.
8184 pub fn new ( initial_delay : Duration , interval : Duration ) -> Self {
8285 IdentifyHandler {
86+ inbound_identify_push : Default :: default ( ) ,
8387 events : SmallVec :: new ( ) ,
8488 trigger_next_identify : Delay :: new ( initial_delay) ,
8589 keep_alive : KeepAlive :: Yes ,
@@ -113,9 +117,14 @@ impl ConnectionHandler for IdentifyHandler {
113117 EitherOutput :: First ( substream) => self . events . push ( ConnectionHandlerEvent :: Custom (
114118 IdentifyHandlerEvent :: Identify ( substream) ,
115119 ) ) ,
116- EitherOutput :: Second ( info) => self . events . push ( ConnectionHandlerEvent :: Custom (
117- IdentifyHandlerEvent :: Identified ( info) ,
118- ) ) ,
120+ EitherOutput :: Second ( fut) => {
121+ if self . inbound_identify_push . replace ( fut) . is_some ( ) {
122+ warn ! (
123+ "New inbound identify push stream while still upgrading previous one. \
124+ Replacing previous with new.",
125+ ) ;
126+ }
127+ }
119128 }
120129 }
121130
@@ -189,14 +198,30 @@ impl ConnectionHandler for IdentifyHandler {
189198
190199 // Poll the future that fires when we need to identify the node again.
191200 match Future :: poll ( Pin :: new ( & mut self . trigger_next_identify ) , cx) {
192- Poll :: Pending => Poll :: Pending ,
201+ Poll :: Pending => { }
193202 Poll :: Ready ( ( ) ) => {
194203 self . trigger_next_identify . reset ( self . interval ) ;
195204 let ev = ConnectionHandlerEvent :: OutboundSubstreamRequest {
196205 protocol : SubstreamProtocol :: new ( EitherUpgrade :: A ( IdentifyProtocol ) , ( ) ) ,
197206 } ;
198- Poll :: Ready ( ev)
207+ return Poll :: Ready ( ev) ;
208+ }
209+ }
210+
211+ if let Some ( Poll :: Ready ( res) ) = self
212+ . inbound_identify_push
213+ . as_mut ( )
214+ . map ( |f| f. poll_unpin ( cx) )
215+ {
216+ self . inbound_identify_push . take ( ) ;
217+
218+ if let Ok ( info) = res {
219+ return Poll :: Ready ( ConnectionHandlerEvent :: Custom (
220+ IdentifyHandlerEvent :: Identified ( info) ,
221+ ) ) ;
199222 }
200223 }
224+
225+ Poll :: Pending
201226 }
202227}
0 commit comments