-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Acks to unencrypted messages broken after exchange closure #10515
Comments
Can we remove exchange dispatcher now ? As you can see, there is almost no difference between application dispatcher and session establishment dispatcher. The major code divergence have moved into session manager, because it is handling both secure and unauthenticated session now. |
This should be fixed by #12794 |
This is not fixed. The behavior is still exactly the same: null-delegate exchanges default to |
There were two ways we could fail to send an ack to an incoming reliable message: 1) If we found no matching handler, and hence created an ephemeral exchange to handle the message, but the message was unencrypted. In this case our ephemeral exchange would return true for IsEncryptionRequired(), because it would default to an ApplicationExchangeDispatch, and we would never call into ExchangeContext::HandleMessage. 2) If ExchangeMessageDispatch::MessagePermitted returned false for the message. In particular, for an ApplicationExchangeDispatch, this would happen for all the handshake messages except StatusReport. The fix for issue 1 is to ensure we always call into HandleMEssage if we manage to allocate an exchange. If there is an encryption mismatch, which only matters when the exchange is non-ephemeral, we close the exchange first to prevent event delivery to the delegate. The fix for issue 2 is to move the MRP processing out of ExchangeMessageDispatch and into ExchangeContext, and to move the MessagePermitted check so the only thing it prevents is delivery of the message to the delegate, not any other processing by the exchange. Fixes project-chip#10515
There were two ways we could fail to send an ack to an incoming reliable message: 1) If we found no matching handler, and hence created an ephemeral exchange to handle the message, but the message was unencrypted. In this case our ephemeral exchange would return true for IsEncryptionRequired(), because it would default to an ApplicationExchangeDispatch, and we would never call into ExchangeContext::HandleMessage. 2) If ExchangeMessageDispatch::MessagePermitted returned false for the message. In particular, for an ApplicationExchangeDispatch, this would happen for all the handshake messages except StatusReport. The fix for issue 1 is to ensure we always call into HandleMEssage if we manage to allocate an exchange. If there is an encryption mismatch, which only matters when the exchange is non-ephemeral, we close the exchange first to prevent event delivery to the delegate. The fix for issue 2 is to move the MRP processing out of ExchangeMessageDispatch and into ExchangeContext, and to move the MessagePermitted check so the only thing it prevents is delivery of the message to the delegate, not any other processing by the exchange. Fixes project-chip#10515
There were two ways we could fail to send an ack to an incoming reliable message: 1) If we found no matching handler, and hence created an ephemeral exchange to handle the message, but the message was unencrypted. In this case our ephemeral exchange would return true for IsEncryptionRequired(), because it would default to an ApplicationExchangeDispatch, and we would never call into ExchangeContext::HandleMessage. 2) If ExchangeMessageDispatch::MessagePermitted returned false for the message. In particular, for an ApplicationExchangeDispatch, this would happen for all the handshake messages except StatusReport. The fix for issue 1 is to ensure we always call into HandleMEssage if we manage to allocate an exchange. If there is an encryption mismatch, which only matters when the exchange is non-ephemeral, we close the exchange first to prevent event delivery to the delegate. The fix for issue 2 is to move the MRP processing out of ExchangeMessageDispatch and into ExchangeContext, and to move the MessagePermitted check so the only thing it prevents is delivery of the message to the delegate, not any other processing by the exchange. Fixes project-chip#10515
There were two ways we could fail to send an ack to an incoming reliable message: 1) If we found no matching handler, and hence created an ephemeral exchange to handle the message, but the message was unencrypted. In this case our ephemeral exchange would return true for IsEncryptionRequired(), because it would default to an ApplicationExchangeDispatch, and we would never call into ExchangeContext::HandleMessage. 2) If ExchangeMessageDispatch::MessagePermitted returned false for the message. In particular, for an ApplicationExchangeDispatch, this would happen for all the handshake messages except StatusReport. The fix for issue 1 is to ensure we always call into HandleMEssage if we manage to allocate an exchange. If there is an encryption mismatch, which only matters when the exchange is non-ephemeral, we close the exchange first to prevent event delivery to the delegate. The fix for issue 2 is to move the MRP processing out of ExchangeMessageDispatch and into ExchangeContext, and to move the MessagePermitted check so the only thing it prevents is delivery of the message to the delegate, not any other processing by the exchange. Fixes project-chip#10515
There were two ways we could fail to send an ack to an incoming reliable message: 1) If we found no matching handler, and hence created an ephemeral exchange to handle the message, but the message was unencrypted. In this case our ephemeral exchange would return true for IsEncryptionRequired(), because it would default to an ApplicationExchangeDispatch, and we would never call into ExchangeContext::HandleMessage. 2) If ExchangeMessageDispatch::MessagePermitted returned false for the message. In particular, for an ApplicationExchangeDispatch, this would happen for all the handshake messages except StatusReport. The fix for issue 1 is to ensure we always call into HandleMEssage if we manage to allocate an exchange. If there is an encryption mismatch, which only matters when the exchange is non-ephemeral, we close the exchange first to prevent event delivery to the delegate. The fix for issue 2 is to move the MRP processing out of ExchangeMessageDispatch and into ExchangeContext, and to move the MessagePermitted check so the only thing it prevents is delivery of the message to the delegate, not any other processing by the exchange. Fixes #10515
Problem
Consider the case of an unencrypted message coming in after the exchange it was targeting has been closed (e.g. it's a duplicate of the last message in a handshake, because the other side never got our ack).
We land in
ExchangeManager::OnMessageReceived
and don't match any existing exchanges. We create a new exchange to handle the standalone ack. We do this check:and the condition tests true, because the standalone ack exchange has no delegate, hence uses the
mDefaultExchangeDispatch
of the exchange manager, which is anApplicationExchangeDispatch
, which requires encryption.So we never send the ack.
Proposed Solution
Fix things so we send acks properly.
@pan-apple @kghost
The text was updated successfully, but these errors were encountered: