-
Notifications
You must be signed in to change notification settings - Fork 30
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
Sync up on_suback_multi behavior between adapter and Mqtt3 client #328
Conversation
|
||
aws_array_list_push_back(&multi_sub_list, &subscription); | ||
if (suback != NULL) { | ||
subscription->qos = s_convert_mqtt5_suback_reason_code_to_mqtt3_granted_qos(suback->reason_codes[i]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Debatable: If suback != null && length(suback->reason_codes) == 0
, we'll get out of bounds access here.
It's debatable becuase when suback
is not null then we received it from the server, and according to the mqtt standard the size of suback->reason_codes
must be equal to the number of subscriptions. However, on the line 2258 we handle the case length(suback->reason_codes) > subscription_count
, i.e. we handle the situation when the received suback
packet violates the standard. So, for consistency, we should handle here the case suback != null && length(suback->reason_codes) == 0
.
Or, maybe it'll be better to verify that length(suback->reason_codes) == subscription_count
prior to this loop. And if it's not true, idk, at least add error log.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Debatable: I think instead of setting reason_code_count = subscription_count
in the event of reason_code_count == 0
, we should just use subscription_count
in the creation of arrays and iterating in this loop. Then we could use if (i < reason_code_count)
here which would account for both a null suback and length(suback->reason_codes) ==0
as well as being able to remove the if (i < subscription_count)
check on 2258 since the loop is already doing that check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Debatable: If
suback != null && length(suback->reason_codes) == 0
, we'll get out of bounds access here.It's debatable becuase when
suback
is not null then we received it from the server, and according to the mqtt standard the size ofsuback->reason_codes
must be equal to the number of subscriptions. However, on the line 2258 we handle the caselength(suback->reason_codes) > subscription_count
, i.e. we handle the situation when the receivedsuback
packet violates the standard. So, for consistency, we should handle here the casesuback != null && length(suback->reason_codes) == 0
. Or, maybe it'll be better to verify thatlength(suback->reason_codes) == subscription_count
prior to this loop. And if it's not true, idk, at least add error log.
We don't need to worry about out of bounds here because the loop will loop through the reason_code_count
as long as suback!=NULL
. If suback->reason_codes) == 0
, we will not go into the loop here.
source/v5/mqtt5_to_mqtt3_adapter.c
Outdated
|
||
if (i < subscription_count) { | ||
aws_array_list_get_at(&subscribe_op->subscriptions, &record, i); | ||
// If the suback does not contains any data, we directly extract the data from subscribe_op |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trivial: "If suback does not contain data, we extract data from subscribe_op"
} | ||
if (reason_code_count > 0) { | ||
granted_qos = s_convert_mqtt5_suback_reason_code_to_mqtt3_granted_qos(suback->reason_codes[0]); | ||
} else if (record) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am confused as to what's going on here. Under no circumstances should we ever "invent" reason codes where none exist. A suback with no reason codes in it (or a mismatch relative to the subscribe) should tear down the connection as a protocol error. If we're not doing so atm, we should.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MQTT3 on a timeout will return a timeout error code with the original subscribe request topic and request qos. If we have no suback packet due to a timeout or shutting down the client in mqtt5, to emulate mqtt3 behavior we need to also send back the same along with the error code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's absurd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
haha, yea. I had the same thought when I checked. The sins of our fathers...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do any bindings do anything with those values when an error is set? There are also (buggy) cases where an error may not get set properly in which case doing this makes it look like the subscribe succeeded.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, aws-crt-cpp extracts info regardless of the error code: https://github.com/awslabs/aws-crt-cpp/blob/main/source/mqtt/MqttConnectionCore.cpp#L417
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Python bindings returns a future on a subscribe() and if there's an error code, sets an exception from the error_code in the future...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yikes. So in cpp, it's up to the customer to check the error code to make sure they're not assuming successful subscribes. I need to double-check that we're not at least setting the request.qos to fail in a timeout. If we are, then we should be fine everywhere
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Java binding will directly return error_code, while JS binding will extract the data regardless of the error_code.
It is probably reasonable to keep the topic and qos data when the subscription failed with an error_code. The user still wanna get the information of a failing subscription for possible operations. (For a simply example, the user would need the info to print out a proper error message, or try subscribe again on the same topic/qos value.)
Codecov ReportAll modified lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #328 +/- ##
==========================================
- Coverage 82.43% 82.31% -0.13%
==========================================
Files 20 20
Lines 8732 8729 -3
==========================================
- Hits 7198 7185 -13
- Misses 1534 1544 +10
☔ View full report in Codecov by Sentry. |
I leave the |
if (suback != NULL && suback->reason_code_count > 0) { | ||
granted_qos = s_convert_mqtt5_suback_reason_code_to_mqtt3_granted_qos(suback->reason_codes[0]); | ||
} else if (record) { | ||
granted_qos = (enum aws_mqtt_qos)(record->subscription_view.qos); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at this again, I think this is not what we want to do. This is a bug in the 311 client (to report the requested qos rather than the returned qos). We should fix the bug instead of making the 5 adapater also do the wrong thing.
This would apply to both the single and multi acks.
Fixed mqtt3 behavior #340 instead of updating the adapter. |
Issue #, if available:
Description of changes:
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.