diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index be51c3dcf09..836664580ec 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -979,31 +979,41 @@ where // overridden as it avoids having to load the existing record in the // first place. - // The record is cloned because of the weird libp2p protocol requirement - // to send back the value in the response, although this is a waste of - // resources. - match self.store.put(record.clone()) { - Ok(()) => { - debug!("Record stored: {:?}; {} bytes", record.key, record.value.len()); - self.queued_events.push_back(NetworkBehaviourAction::NotifyHandler { - peer_id: source, - handler: NotifyHandler::One(connection), - event: KademliaHandlerIn::PutRecordRes { - key: record.key, - value: record.value, - request_id, - }, - }) - } - Err(e) => { - info!("Record not stored: {:?}", e); - self.queued_events.push_back(NetworkBehaviourAction::NotifyHandler { - peer_id: source, - handler: NotifyHandler::One(connection), - event: KademliaHandlerIn::Reset(request_id) - }) + if !record.is_expired(now) { + // The record is cloned because of the weird libp2p protocol + // requirement to send back the value in the response, although this + // is a waste of resources. + match self.store.put(record.clone()) { + Ok(()) => debug!("Record stored: {:?}; {} bytes", record.key, record.value.len()), + Err(e) => { + info!("Record not stored: {:?}", e); + self.queued_events.push_back(NetworkBehaviourAction::NotifyHandler { + peer_id: source, + handler: NotifyHandler::One(connection), + event: KademliaHandlerIn::Reset(request_id) + }); + + return + } } } + + // The remote receives a [`KademliaHandlerIn::PutRecordRes`] even in the + // case where the record is discarded due to being expired. Given that + // the remote sent the local node a [`KademliaHandlerEvent::PutRecord`] + // request, the remote perceives the local node as one node among the k + // closest nodes to the target. In addition returning + // [`KademliaHandlerIn::PutRecordRes`] does not reveal any internal + // information to a possibly malicious remote node. + self.queued_events.push_back(NetworkBehaviourAction::NotifyHandler { + peer_id: source, + handler: NotifyHandler::One(connection), + event: KademliaHandlerIn::PutRecordRes { + key: record.key, + value: record.value, + request_id, + }, + }) } /// Processes a provider record received from a peer.