* [libp2p-swarm] Correct returned connections from notify_all.
If at least one connection was not ready (i.e. pending), only
those (pending) connections would be returned and considered on the next
iteration, whereas those which were ready should also remain
in the list of connections to notify on retry of `notify_all`.
* Simplify.
It seems unnecessary to use "poll all" -> "send all" semantics,
i.e. attempting an "atomic" broadcast. Rather, events send via
`notify_all` can be delivered as soon as possible, simplifying
the code further.
* Add addresses field for closing listeners
Add an addresses field to the ListenersEvent and the ListenerClosed to
hold the addresses of a listener that has just closed. When we return a
ListenerClosed network event loop over the addresses and call
inject_expired_listen_address on each one.
Fixes: #1482
* Use Vec instead of SmallVec
In order to not expose a third party dependency in our API use a `Vec`
type for the addresses list instead of a `SmallVec`.
* Do not clone for ListenersEvent::Closed
We would like to avoid clones where possible for efficiency reasons.
When returning a `ListenersEvent::Closed` we are already consuming the
listener (by way of a pin projection). We can therefore use a consuming
iterator instead of cloning.
Use `drain(..).collect()` instead of clone to consume the addresses when
returning a `ListenersEvent::Closed`.
* Expire addresses before listener
The listener and its addresses technically expire at the same time, but
since here we have to pick an order, it makes more sense that the
addresses expire first.
Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>
* protocols/kad: Do not attempt to store expired record in record store
`Kademlia::record_received` calculates the expiration time of a record
before inserting it into the record store. Instead of inserting the
record into the record store in any case, with this patch the record is
only inserted if it is not expired. If the record is expired a
`KademliaHandlerIn::Reset` for the given (sub) stream is triggered.
This would serve as a tiny defense mechanism against an attacker trying
to fill a node's record store with expired records before the record
store's clean up procedure removes the records.
* protocols/kad: Send regular ack when record discarded due to expiration
With this commit 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.
Returning a [`KademliaHandlerIn::Reset`] instead of an
[`KademliaHandlerIn::PutRecordRes`] to have the remote try another node
would only result in the remote node to contact an even more distant
node. In addition returning [`KademliaHandlerIn::PutRecordRes`] does not
reveal any internal information to a possibly malicious remote node.
* protocols/kad/src/behaviour: Use `now` and reword expiration comment
Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
* protocols/kad: Add test to reproduce right shift overflow panic
* protocols/kad: Fix right shift overflow panic in record_received
Within `Behaviour::record_received` the exponentially decreasing
expiration based on the distance to the target for a record is
calculated as following:
1. Calculate the amount of nodes between us and the record key beyond
the k replication constant as `n`.
2. Shift the configured record time-to-live `n` times to the right to
calculate an exponentially decreasing expiration.
The configured record time-to-live is a u64. If `n` is larger or equal
to 64 the right shift will lead to an overflow which panics in debug
mode.
This patch uses a checked right shift instead, defaulting to 0 (`now +
0`) for the expiration on overflow.
* protocols/kad: Put attribute below comment
* protocols/kad: Extract shifting logic and rework test
Extract right shift into isolated function and replace complex
regression test with small isolated one.
* protocols/kad/src/behaviour: Refactor exp_decr_expiration
Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>