Mdns InterfaceState
never being called again after returning Poll::Pending
#4860
Labels
InterfaceState
never being called again after returning Poll::Pending
#4860
Summary
When updating to
0.53.0
, we encountered a curious bug with Mdns.After sending an incorrect Mdns packet, which is dropped (as expected), no packet is ever received by the peer after that, even if it is correct.
Expected behavior
An incorrect Mdns packet should not stop the polling of an
InterfaceState
.Actual behavior
The polling of an
InterfaceState
is stopped after receiving an incorrect Mdns packet.Relevant log output
No response
Possible Solution
Members of our team diagnosed the problem and managed to find the solution. It seems a dormant bug was present for a long time in the
poll
implementation ofInterfaceState
but it was only awakened with the merge of #4623.rust-libp2p/protocols/mdns/src/behaviour/iface.rs
Lines 313 to 325 in cddc306
As we can see in the above code sample, many
Poll::Ready
are handled and returned asPoll::Pending
. However, in the rust documentation, we can read that "When a function returns Pending, the function must also ensure that the current task is scheduled to be awoken when progress can be made". When looking at the current implementation, we can safely say that, when aPoll::Ready
is caught and converted into aPoll::Pending
, no scheduling is done to ensure the task will be woken up.Even if this bug has been present for a long time, it has not caused any problems up until now. Indeed, before the previously mentioned PR, all
InterfaceState
were stored in theiface_states
HashMap
and were polled no matter what their previous returned value was (sincepoll
was called in aloop
over eachInterfaceState
). So, even if thepoll
method ofInterfaceState
had not scheduled its own awakening, it would still be called at the next iteration of thepoll
method of the mdnsBehaviour
.However, now that each
InterfaceState
isspawned
in its own task, nobody is callingpoll
when it returnsPoll::Pending
. That is why returning aPoll::Pending
when internally getting aPoll::Ready
result in thepoll
method ofInterfaceState
never being called again, causing packets to never be handled.Version
v0.53.0 (master)
Would you like to work on fixing this bug ?
Yes
The text was updated successfully, but these errors were encountered: