Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package aws-c-mqtt for openSUSE:Factory checked in at 2024-06-03 17:41:17
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/aws-c-mqtt (Old)
and /work/SRC/openSUSE:Factory/.aws-c-mqtt.new.24587 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "aws-c-mqtt"
Mon Jun 3 17:41:17 2024 rev:4 rq:1177910 version:0.10.4
Changes:
--------
--- /work/SRC/openSUSE:Factory/aws-c-mqtt/aws-c-mqtt.changes 2024-05-22 21:32:24.333822366 +0200
+++ /work/SRC/openSUSE:Factory/.aws-c-mqtt.new.24587/aws-c-mqtt.changes 2024-06-03 17:41:26.746543659 +0200
@@ -1,0 +2,7 @@
+Fri May 31 10:44:17 UTC 2024 - John Paul Adrian Glaubitz
+
+- Update to version 0.10.4
+ * Refactor MQTT5 ping timeout by @bretambrose in (#361)
+ * Disabled keep alive by @bretambrose in (#363)
+
+-------------------------------------------------------------------
Old:
----
v0.10.3.tar.gz
New:
----
v0.10.4.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ aws-c-mqtt.spec ++++++
--- /var/tmp/diff_new_pack.DcLekm/_old 2024-06-03 17:41:27.354565968 +0200
+++ /var/tmp/diff_new_pack.DcLekm/_new 2024-06-03 17:41:27.358566114 +0200
@@ -18,7 +18,7 @@
%global library_version 1_0_0
Name: aws-c-mqtt
-Version: 0.10.3
+Version: 0.10.4
Release: 0
Summary: AWS C99 implementation of the MQTT 3.1.1 specification
License: Apache-2.0
++++++ v0.10.3.tar.gz -> v0.10.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-mqtt-0.10.3/include/aws/mqtt/private/v5/mqtt5_options_storage.h new/aws-c-mqtt-0.10.4/include/aws/mqtt/private/v5/mqtt5_options_storage.h
--- old/aws-c-mqtt-0.10.3/include/aws/mqtt/private/v5/mqtt5_options_storage.h 2024-02-29 17:06:37.000000000 +0100
+++ new/aws-c-mqtt-0.10.4/include/aws/mqtt/private/v5/mqtt5_options_storage.h 2024-03-26 23:12:31.000000000 +0100
@@ -337,10 +337,6 @@
const struct aws_mqtt5_client_options_storage *options_storage,
enum aws_log_level level);
-AWS_MQTT_API bool aws_mqtt5_client_keep_alive_options_are_valid(
- uint16_t keep_alive_interval_seconds,
- uint32_t ping_timeout_ms);
-
AWS_EXTERN_C_END
#endif /* AWS_MQTT_MQTT5_OPERATION_H */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-mqtt-0.10.3/source/v5/mqtt5_client.c new/aws-c-mqtt-0.10.4/source/v5/mqtt5_client.c
--- old/aws-c-mqtt-0.10.3/source/v5/mqtt5_client.c 2024-02-29 17:06:37.000000000 +0100
+++ new/aws-c-mqtt-0.10.4/source/v5/mqtt5_client.c 2024-03-26 23:12:31.000000000 +0100
@@ -1069,7 +1069,11 @@
uint64_t keep_alive_interval_nanos =
aws_timestamp_convert(keep_alive_seconds, AWS_TIMESTAMP_SECS, AWS_TIMESTAMP_NANOS, NULL);
- client->next_ping_time = aws_add_u64_saturating(now, keep_alive_interval_nanos);
+ if (keep_alive_interval_nanos == 0) {
+ client->next_ping_time = UINT64_MAX;
+ } else {
+ client->next_ping_time = aws_add_u64_saturating(now, keep_alive_interval_nanos);
+ }
AWS_LOGF_DEBUG(
AWS_LS_MQTT5_CLIENT, "id=%p: next PINGREQ scheduled for time %" PRIu64, (void *)client, client->next_ping_time);
@@ -2940,7 +2944,20 @@
uint64_t now = client->vtable->get_current_time_fn();
uint64_t ping_timeout_nanos =
aws_timestamp_convert(client->config->ping_timeout_ms, AWS_TIMESTAMP_MILLIS, AWS_TIMESTAMP_NANOS, NULL);
- client->next_ping_timeout_time = aws_add_u64_saturating(now, ping_timeout_nanos);
+ uint64_t half_keep_alive_nanos =
+ aws_timestamp_convert(
+ client->negotiated_settings.server_keep_alive, AWS_TIMESTAMP_SECS, AWS_TIMESTAMP_NANOS, NULL) /
+ 2;
+
+ uint64_t connection_ping_timeout = ping_timeout_nanos;
+ if (connection_ping_timeout == 0 || connection_ping_timeout > half_keep_alive_nanos) {
+ connection_ping_timeout = half_keep_alive_nanos;
+ }
+
+ AWS_LOGF_DEBUG(
+ AWS_LS_MQTT5_CLIENT, "id=%p: dynamic ping timeout: %" PRIu64 " ns", (void *)client, connection_ping_timeout);
+
+ client->next_ping_timeout_time = aws_add_u64_saturating(now, connection_ping_timeout);
}
static int s_apply_throughput_flow_control(struct aws_mqtt5_client *client) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-mqtt-0.10.3/source/v5/mqtt5_options_storage.c new/aws-c-mqtt-0.10.4/source/v5/mqtt5_options_storage.c
--- old/aws-c-mqtt-0.10.3/source/v5/mqtt5_options_storage.c 2024-02-29 17:06:37.000000000 +0100
+++ new/aws-c-mqtt-0.10.4/source/v5/mqtt5_options_storage.c 2024-03-26 23:12:31.000000000 +0100
@@ -3308,26 +3308,6 @@
return pingreq_op;
}
-bool aws_mqtt5_client_keep_alive_options_are_valid(uint16_t keep_alive_interval_seconds, uint32_t ping_timeout_ms) {
- /* The client will not behave properly if ping timeout is not significantly shorter than the keep alive interval */
- if (keep_alive_interval_seconds > 0) {
- uint64_t keep_alive_ms =
- aws_timestamp_convert(keep_alive_interval_seconds, AWS_TIMESTAMP_SECS, AWS_TIMESTAMP_MILLIS, NULL);
- uint64_t one_second_ms = aws_timestamp_convert(1, AWS_TIMESTAMP_SECS, AWS_TIMESTAMP_MILLIS, NULL);
-
- if (ping_timeout_ms == 0) {
- ping_timeout_ms = AWS_MQTT5_CLIENT_DEFAULT_PING_TIMEOUT_MS;
- }
-
- if ((uint64_t)ping_timeout_ms + one_second_ms > keep_alive_ms) {
- AWS_LOGF_ERROR(AWS_LS_MQTT5_GENERAL, "keep alive interval is too small relative to ping timeout interval");
- return false;
- }
- }
-
- return true;
-}
-
/*********************************************************************************************************************
* Client storage options
********************************************************************************************************************/
@@ -3387,17 +3367,10 @@
if (aws_mqtt5_packet_connect_view_validate(options->connect_options)) {
AWS_LOGF_ERROR(AWS_LS_MQTT5_GENERAL, "invalid CONNECT options in mqtt5 client configuration");
- /* connect validation failure will have already rasied the appropriate error */
+ /* connect validation failure will have already raised the appropriate error */
return AWS_OP_ERR;
}
- /* The client will not behave properly if ping timeout is not significantly shorter than the keep alive interval */
- if (!aws_mqtt5_client_keep_alive_options_are_valid(
- options->connect_options->keep_alive_interval_seconds, options->ping_timeout_ms)) {
- AWS_LOGF_ERROR(AWS_LS_MQTT5_GENERAL, "keep alive interval is too small relative to ping timeout interval");
- return aws_raise_error(AWS_ERROR_MQTT5_CLIENT_OPTIONS_VALIDATION);
- }
-
if (options->topic_aliasing_options != NULL) {
if (!aws_mqtt5_outbound_topic_alias_behavior_type_validate(
options->topic_aliasing_options->outbound_topic_alias_behavior)) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-mqtt-0.10.3/source/v5/mqtt5_to_mqtt3_adapter.c new/aws-c-mqtt-0.10.4/source/v5/mqtt5_to_mqtt3_adapter.c
--- old/aws-c-mqtt-0.10.3/source/v5/mqtt5_to_mqtt3_adapter.c 2024-02-29 17:06:37.000000000 +0100
+++ new/aws-c-mqtt-0.10.4/source/v5/mqtt5_to_mqtt3_adapter.c 2024-03-26 23:12:31.000000000 +0100
@@ -309,16 +309,6 @@
}
}
- /* The client will not behave properly if ping timeout is not significantly shorter than the keep alive interval */
- if (!aws_mqtt5_client_keep_alive_options_are_valid(
- connection_options->keep_alive_time_secs, connection_options->ping_timeout_ms)) {
- AWS_LOGF_ERROR(
- AWS_LS_MQTT5_TO_MQTT3_ADAPTER,
- "id=%p: mqtt3-to-5-adapter - keep alive interval is too small relative to ping timeout interval",
- (void *)adapter);
- return aws_raise_error(AWS_ERROR_MQTT5_CLIENT_OPTIONS_VALIDATION);
- }
-
return AWS_OP_SUCCESS;
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-mqtt-0.10.3/tests/CMakeLists.txt new/aws-c-mqtt-0.10.4/tests/CMakeLists.txt
--- old/aws-c-mqtt-0.10.3/tests/CMakeLists.txt 2024-02-29 17:06:37.000000000 +0100
+++ new/aws-c-mqtt-0.10.4/tests/CMakeLists.txt 2024-03-26 23:12:31.000000000 +0100
@@ -244,7 +244,6 @@
add_test_case(mqtt5_client_options_validation_failure_no_publish_received)
add_test_case(mqtt5_client_options_validation_failure_invalid_socket_options)
add_test_case(mqtt5_client_options_validation_failure_invalid_connect)
-add_test_case(mqtt5_client_options_validation_failure_invalid_keep_alive)
add_test_case(mqtt5_client_options_validation_failure_invalid_port)
add_test_case(mqtt5_operation_subscribe_connection_settings_validation_failure_exceeds_maximum_packet_size)
add_test_case(mqtt5_operation_unsubscribe_connection_settings_validation_failure_exceeds_maximum_packet_size)
@@ -330,6 +329,8 @@
add_test_case(mqtt5_client_sub_pub_unsub_qos1)
add_test_case(mqtt5_client_ping_sequence)
add_test_case(mqtt5_client_ping_timeout)
+add_test_case(mqtt5_client_ping_timeout_with_keep_alive_conflict)
+add_test_case(mqtt5_client_disabled_keep_alive)
add_test_case(mqtt5_client_reconnect_failure_backoff)
add_test_case(mqtt5_client_reconnect_backoff_insufficient_reset)
add_test_case(mqtt5_client_reconnect_backoff_sufficient_reset)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-mqtt-0.10.3/tests/v5/mqtt5_client_tests.c new/aws-c-mqtt-0.10.4/tests/v5/mqtt5_client_tests.c
--- old/aws-c-mqtt-0.10.3/tests/v5/mqtt5_client_tests.c 2024-02-29 17:06:37.000000000 +0100
+++ new/aws-c-mqtt-0.10.4/tests/v5/mqtt5_client_tests.c 2024-03-26 23:12:31.000000000 +0100
@@ -986,10 +986,7 @@
struct aws_mqtt5_client_mock_test_fixture *test_fixture;
};
-static bool s_received_at_least_n_pingreqs(void *arg) {
- struct aws_mqtt5_client_test_wait_for_n_context *ping_context = arg;
- struct aws_mqtt5_client_mock_test_fixture *test_fixture = ping_context->test_fixture;
-
+static size_t s_count_pingreqs(struct aws_mqtt5_client_mock_test_fixture *test_fixture) {
size_t ping_count = 0;
size_t packet_count = aws_array_list_length(&test_fixture->server_received_packets);
for (size_t i = 0; i < packet_count; ++i) {
@@ -1001,6 +998,15 @@
}
}
+ return ping_count;
+}
+
+static bool s_received_at_least_n_pingreqs(void *arg) {
+ struct aws_mqtt5_client_test_wait_for_n_context *ping_context = arg;
+ struct aws_mqtt5_client_mock_test_fixture *test_fixture = ping_context->test_fixture;
+
+ size_t ping_count = s_count_pingreqs(test_fixture);
+
return ping_count >= ping_context->required_event_count;
}
@@ -1217,7 +1223,9 @@
#define TIMEOUT_TEST_PING_INTERVAL_MS ((uint64_t)10000)
-static int s_verify_ping_timeout_interval(struct aws_mqtt5_client_mock_test_fixture *test_context) {
+static int s_verify_ping_timeout_interval(
+ struct aws_mqtt5_client_mock_test_fixture *test_context,
+ uint64_t expected_connected_time_ms) {
aws_mutex_lock(&test_context->lock);
uint64_t connected_time = 0;
@@ -1242,8 +1250,6 @@
uint64_t connected_interval_ms =
aws_timestamp_convert(disconnected_time - connected_time, AWS_TIMESTAMP_NANOS, AWS_TIMESTAMP_MILLIS, NULL);
- uint64_t expected_connected_time_ms =
- TIMEOUT_TEST_PING_INTERVAL_MS + (uint64_t)test_context->client->config->ping_timeout_ms;
ASSERT_TRUE(s_is_within_percentage_of(expected_connected_time_ms, connected_interval_ms, .3));
@@ -1310,7 +1316,9 @@
ASSERT_SUCCESS(
s_verify_simple_lifecycle_event_sequence(&test_context, expected_events, AWS_ARRAY_SIZE(expected_events)));
- ASSERT_SUCCESS(s_verify_ping_timeout_interval(&test_context));
+ uint64_t expected_connected_time_ms =
+ TIMEOUT_TEST_PING_INTERVAL_MS + (uint64_t)test_context.client->config->ping_timeout_ms;
+ ASSERT_SUCCESS(s_verify_ping_timeout_interval(&test_context, expected_connected_time_ms));
enum aws_mqtt5_client_state expected_states[] = {
AWS_MCS_CONNECTING,
@@ -1329,6 +1337,147 @@
AWS_TEST_CASE(mqtt5_client_ping_timeout, s_mqtt5_client_ping_timeout_fn)
+/*
+ * A variant of the basic ping timeout test that uses a timeout that is larger than the keep alive. Previously,
+ * we forbid this because taken literally, it leads to broken behavior. We now clamp the ping timeout dynamically
+ * based on the connection's established keep alive.
+ */
+static int s_mqtt5_client_ping_timeout_with_keep_alive_conflict_fn(struct aws_allocator *allocator, void *ctx) {
+ (void)ctx;
+
+ aws_mqtt_library_init(allocator);
+
+ struct mqtt5_client_test_options test_options;
+ aws_mqtt5_client_test_init_default_options(&test_options);
+
+ /* fast keep alive in order keep tests reasonably short */
+ uint16_t keep_alive_seconds =
+ (uint16_t)aws_timestamp_convert(TIMEOUT_TEST_PING_INTERVAL_MS, AWS_TIMESTAMP_MILLIS, AWS_TIMESTAMP_SECS, NULL);
+ test_options.connect_options.keep_alive_interval_seconds = keep_alive_seconds;
+
+ /* don't respond to PINGREQs */
+ test_options.server_function_table.packet_handlers[AWS_MQTT5_PT_PINGREQ] = NULL;
+
+ /* ping timeout slower than keep alive */
+ test_options.client_options.ping_timeout_ms = 2 * TIMEOUT_TEST_PING_INTERVAL_MS;
+
+ struct aws_mqtt5_client_mqtt5_mock_test_fixture_options test_fixture_options = {
+ .client_options = &test_options.client_options,
+ .server_function_table = &test_options.server_function_table,
+ };
+
+ struct aws_mqtt5_client_mock_test_fixture test_context;
+ ASSERT_SUCCESS(aws_mqtt5_client_mock_test_fixture_init(&test_context, allocator, &test_fixture_options));
+
+ struct aws_mqtt5_client *client = test_context.client;
+ ASSERT_SUCCESS(aws_mqtt5_client_start(client));
+
+ aws_wait_for_connected_lifecycle_event(&test_context);
+ s_wait_for_disconnection_lifecycle_event(&test_context);
+
+ ASSERT_SUCCESS(aws_mqtt5_client_stop(client, NULL, NULL));
+
+ aws_wait_for_stopped_lifecycle_event(&test_context);
+
+ struct aws_mqtt5_client_lifecycle_event expected_events[] = {
+ {
+ .event_type = AWS_MQTT5_CLET_ATTEMPTING_CONNECT,
+ },
+ {
+ .event_type = AWS_MQTT5_CLET_CONNECTION_SUCCESS,
+ },
+ {
+ .event_type = AWS_MQTT5_CLET_DISCONNECTION,
+ .error_code = AWS_ERROR_MQTT5_PING_RESPONSE_TIMEOUT,
+ },
+ {
+ .event_type = AWS_MQTT5_CLET_STOPPED,
+ },
+ };
+ ASSERT_SUCCESS(
+ s_verify_simple_lifecycle_event_sequence(&test_context, expected_events, AWS_ARRAY_SIZE(expected_events)));
+
+ uint64_t expected_connected_time_ms = 3 * TIMEOUT_TEST_PING_INTERVAL_MS / 2;
+ ASSERT_SUCCESS(s_verify_ping_timeout_interval(&test_context, expected_connected_time_ms));
+
+ enum aws_mqtt5_client_state expected_states[] = {
+ AWS_MCS_CONNECTING,
+ AWS_MCS_MQTT_CONNECT,
+ AWS_MCS_CONNECTED,
+ AWS_MCS_CLEAN_DISCONNECT,
+ AWS_MCS_CHANNEL_SHUTDOWN,
+ };
+ ASSERT_SUCCESS(aws_verify_client_state_sequence(&test_context, expected_states, AWS_ARRAY_SIZE(expected_states)));
+
+ aws_mqtt5_client_mock_test_fixture_clean_up(&test_context);
+ aws_mqtt_library_clean_up();
+
+ return AWS_OP_SUCCESS;
+}
+
+AWS_TEST_CASE(
+ mqtt5_client_ping_timeout_with_keep_alive_conflict,
+ s_mqtt5_client_ping_timeout_with_keep_alive_conflict_fn)
+
+/*
+ * Set up a zero keep alive and verify no pings get sent over an interval of time.
+ */
+static int s_mqtt5_client_disabled_keep_alive_fn(struct aws_allocator *allocator, void *ctx) {
+ (void)ctx;
+
+ aws_mqtt_library_init(allocator);
+
+ struct mqtt5_client_test_options test_options;
+ aws_mqtt5_client_test_init_default_options(&test_options);
+
+ /* no keep alive at all */
+ test_options.connect_options.keep_alive_interval_seconds = 0;
+
+ struct aws_mqtt5_client_mqtt5_mock_test_fixture_options test_fixture_options = {
+ .client_options = &test_options.client_options,
+ .server_function_table = &test_options.server_function_table,
+ };
+
+ struct aws_mqtt5_client_mock_test_fixture test_context;
+ ASSERT_SUCCESS(aws_mqtt5_client_mock_test_fixture_init(&test_context, allocator, &test_fixture_options));
+
+ struct aws_mqtt5_client *client = test_context.client;
+ ASSERT_SUCCESS(aws_mqtt5_client_start(client));
+
+ aws_wait_for_connected_lifecycle_event(&test_context);
+
+ uint16_t negotiated_keep_alive = 65535;
+ aws_mutex_lock(&test_context.lock);
+ size_t event_count = aws_array_list_length(&test_context.lifecycle_events);
+ struct aws_mqtt5_lifecycle_event_record *record = NULL;
+ aws_array_list_get_at(&test_context.lifecycle_events, &record, event_count - 1);
+ ASSERT_TRUE(AWS_MQTT5_CLET_CONNECTION_SUCCESS == record->event.event_type);
+ negotiated_keep_alive = record->settings_storage.server_keep_alive;
+ aws_mutex_unlock(&test_context.lock);
+
+ ASSERT_INT_EQUALS(0, negotiated_keep_alive);
+
+ // zzz
+ aws_thread_current_sleep(aws_timestamp_convert(5, AWS_TIMESTAMP_SECS, AWS_TIMESTAMP_NANOS, NULL));
+
+ ASSERT_SUCCESS(aws_mqtt5_client_stop(client, NULL, NULL));
+
+ aws_wait_for_stopped_lifecycle_event(&test_context);
+
+ // verify the mock server did not get any PINGREQs
+ aws_mutex_lock(&test_context.lock);
+ size_t pingreq_count = s_count_pingreqs(&test_context);
+ aws_mutex_unlock(&test_context.lock);
+ ASSERT_INT_EQUALS(0, pingreq_count);
+
+ aws_mqtt5_client_mock_test_fixture_clean_up(&test_context);
+ aws_mqtt_library_clean_up();
+
+ return AWS_OP_SUCCESS;
+}
+
+AWS_TEST_CASE(mqtt5_client_disabled_keep_alive, s_mqtt5_client_disabled_keep_alive_fn)
+
struct aws_lifecycle_event_wait_context {
enum aws_mqtt5_client_lifecycle_event_type type;
size_t count;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-mqtt-0.10.3/tests/v5/mqtt5_operation_validation_failure_tests.c new/aws-c-mqtt-0.10.4/tests/v5/mqtt5_operation_validation_failure_tests.c
--- old/aws-c-mqtt-0.10.3/tests/v5/mqtt5_operation_validation_failure_tests.c 2024-02-29 17:06:37.000000000 +0100
+++ new/aws-c-mqtt-0.10.4/tests/v5/mqtt5_operation_validation_failure_tests.c 2024-03-26 23:12:31.000000000 +0100
@@ -1170,20 +1170,6 @@
AWS_CLIENT_CREATION_VALIDATION_FAILURE(invalid_connect, s_good_client_options, s_make_invalid_connect_client_options)
-static struct aws_mqtt5_packet_connect_view s_short_keep_alive_connect_view = {
- .keep_alive_interval_seconds = 20,
-};
-
-static void s_make_invalid_keep_alive_client_options(struct aws_mqtt5_client_options *options) {
- options->connect_options = &s_short_keep_alive_connect_view;
- options->ping_timeout_ms = 30000;
-}
-
-AWS_CLIENT_CREATION_VALIDATION_FAILURE(
- invalid_keep_alive,
- s_good_client_options,
- s_make_invalid_keep_alive_client_options)
-
static void s_make_invalid_port_client_options(struct aws_mqtt5_client_options *options) {
options->port = 0xFFFFFFFF;
}