MQTTnet is a high performance .NET library for MQTT based communication. It provides a MQTT client and a MQTT server (broker). The implementation is based on the documentation from http://mqtt.org/.
MIT License
4.5k
stars
1.07k
forks
source link
Server subscriber sessions hash set can contain sessions with no subscriptions #2062
In the server implementation, MqttClientSessionsManager keeps an internal hash set of "subscriber sessions" that have one or more subscriptions.
However, there is a bug that can result in this hash set containing sessions that have no subscriptions. If a subscribe message is intercepted and ProcessSubscription = false is set for all topic filters, then there will be no subscriptions to add. MqttClientSubscriptionsManager.Subscribe will still call MqttClientSessionsManager.OnSubscriptionsAdded with an empty topics list. This method will blindly add the session to _subscriberSessions.
As a result, the server will need to check the session for subscriptions for every subsequent application message received which incurs some performance overhead for locking. There may also be other side effects due to this inconsistency.
Which component is your bug related to?
Server
To Reproduce
Steps to reproduce the behavior:
Setup application to start up a server to intercept subscribe messages and set ProcessSubscription = false
Confirm in debugger that session has been added to _subscriberSessions
Expected behavior
Session should only be added to the _subscriberSessions if there was at least one subscription added. This then also avoids taking the _sessionsManagementLock when there is no work to do and avoids any other potential side effects.
if (addedSubscriptions.Count > 0)
{
_subscriptionChangedNotification?.OnSubscriptionsAdded(_session, addedSubscriptions);
}
Describe the bug
In the server implementation,
MqttClientSessionsManager
keeps an internal hash set of "subscriber sessions" that have one or more subscriptions.However, there is a bug that can result in this hash set containing sessions that have no subscriptions. If a subscribe message is intercepted and
ProcessSubscription = false
is set for all topic filters, then there will be no subscriptions to add.MqttClientSubscriptionsManager.Subscribe
will still callMqttClientSessionsManager.OnSubscriptionsAdded
with an emptytopics
list. This method will blindly add the session to_subscriberSessions
.https://github.com/dotnet/MQTTnet/blob/master/Source/MQTTnet/Server/Internal/MqttClientSubscriptionsManager.cs#L215 https://github.com/dotnet/MQTTnet/blob/master/Source/MQTTnet/Server/Internal/MqttClientSessionsManager.cs#L455
As a result, the server will need to check the session for subscriptions for every subsequent application message received which incurs some performance overhead for locking. There may also be other side effects due to this inconsistency.
Which component is your bug related to?
Server
To Reproduce
Steps to reproduce the behavior:
ProcessSubscription = false
_subscriberSessions
Expected behavior
Session should only be added to the
_subscriberSessions
if there was at least one subscription added. This then also avoids taking the_sessionsManagementLock
when there is no work to do and avoids any other potential side effects.