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 
<adrian.glaub...@suse.com>
+
+- 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;
 }

Reply via email to