From ce988fde2b4a75186ac8298c504c9b6373525c95 Mon Sep 17 00:00:00 2001 From: mdb-ad <198671546+mdb-ad@users.noreply.github.com> Date: Sat, 17 May 2025 16:34:42 -0700 Subject: [PATCH 01/18] implement --- src/mongocrypt-kms-ctx.c | 47 ++++++++++------ src/mongocrypt.h | 17 ++++++ .../data/kms-aws/encrypt-response-partial.txt | 3 ++ test/test-mongocrypt-datakey.c | 53 +++++++++++++++++++ 4 files changed, 103 insertions(+), 17 deletions(-) create mode 100644 test/data/kms-aws/encrypt-response-partial.txt diff --git a/src/mongocrypt-kms-ctx.c b/src/mongocrypt-kms-ctx.c index 6e18df16a..34c4ad752 100644 --- a/src/mongocrypt-kms-ctx.c +++ b/src/mongocrypt-kms-ctx.c @@ -1120,6 +1120,35 @@ static bool _ctx_done_kmip_decrypt(mongocrypt_kms_ctx_t *kms_ctx) { return ret; } +static bool _is_retryable_req(_kms_request_type_t req_type) { + // Check if request type is retryable. Some requests are non-idempotent and cannot be safely retried. + _kms_request_type_t retryable_types[] = {MONGOCRYPT_KMS_AZURE_OAUTH, + MONGOCRYPT_KMS_GCP_OAUTH, + MONGOCRYPT_KMS_AWS_ENCRYPT, + MONGOCRYPT_KMS_AWS_DECRYPT, + MONGOCRYPT_KMS_AZURE_WRAPKEY, + MONGOCRYPT_KMS_AZURE_UNWRAPKEY, + MONGOCRYPT_KMS_GCP_ENCRYPT, + MONGOCRYPT_KMS_GCP_DECRYPT}; + for (size_t i = 0; i < sizeof(retryable_types) / sizeof(retryable_types[0]); i++) { + if (retryable_types[i] == req_type) { + return true; + } + } + return false; +} + +bool mongocrypt_kms_ctx_should_retry_http(mongocrypt_kms_ctx_t *kms) { + return kms && kms->should_retry; +} + +void mongocrypt_kms_ctx_reset(mongocrypt_kms_ctx_t *kms) { + if (kms->parser) { + kms_response_parser_reset(kms->parser); + } + kms->should_retry = false; +} + bool mongocrypt_kms_ctx_fail(mongocrypt_kms_ctx_t *kms) { if (!kms) { return false; @@ -1138,23 +1167,7 @@ bool mongocrypt_kms_ctx_fail(mongocrypt_kms_ctx_t *kms) { return false; } - // Check if request type is retryable. Some requests are non-idempotent and cannot be safely retried. - _kms_request_type_t retryable_types[] = {MONGOCRYPT_KMS_AZURE_OAUTH, - MONGOCRYPT_KMS_GCP_OAUTH, - MONGOCRYPT_KMS_AWS_ENCRYPT, - MONGOCRYPT_KMS_AWS_DECRYPT, - MONGOCRYPT_KMS_AZURE_WRAPKEY, - MONGOCRYPT_KMS_AZURE_UNWRAPKEY, - MONGOCRYPT_KMS_GCP_ENCRYPT, - MONGOCRYPT_KMS_GCP_DECRYPT}; - bool is_retryable = false; - for (size_t i = 0; i < sizeof(retryable_types) / sizeof(retryable_types[0]); i++) { - if (retryable_types[i] == kms->req_type) { - is_retryable = true; - break; - } - } - if (!is_retryable) { + if (!_is_retryable_req(kms->req_type)) { CLIENT_ERR("KMS request failed due to network error"); return false; } diff --git a/src/mongocrypt.h b/src/mongocrypt.h index 894d0b463..7f36b26d5 100644 --- a/src/mongocrypt.h +++ b/src/mongocrypt.h @@ -1188,6 +1188,23 @@ bool mongocrypt_kms_ctx_feed(mongocrypt_kms_ctx_t *kms, mongocrypt_binary_t *byt MONGOCRYPT_EXPORT bool mongocrypt_kms_ctx_fail(mongocrypt_kms_ctx_t *kms); +/** + * Reset a KMS context allowing it to be retried. + * + * @param[in] kms The @ref mongocrypt_kms_ctx_t. + */ +MONGOCRYPT_EXPORT +void mongocrypt_kms_ctx_reset(mongocrypt_kms_ctx_t *kms); + +/** + * Indicate if a KMS is completed but should be retried due to an HTTP error. + * + * @param[in] kms The @ref mongocrypt_kms_ctx_t. + * @return A boolean indicating whether the failed request is complete but should be retried. + */ +MONGOCRYPT_EXPORT +bool mongocrypt_kms_ctx_should_retry_http(mongocrypt_kms_ctx_t *kms); + /** * Get the status associated with a @ref mongocrypt_kms_ctx_t object. * diff --git a/test/data/kms-aws/encrypt-response-partial.txt b/test/data/kms-aws/encrypt-response-partial.txt new file mode 100644 index 000000000..6ec20de97 --- /dev/null +++ b/test/data/kms-aws/encrypt-response-partial.txt @@ -0,0 +1,3 @@ +HTTP/1.1 200 OK +x-amzn-RequestId: deeb35e5-4ecb-4bf1-9af5-84a54ff0af0e +Content-Type: appli \ No newline at end of file diff --git a/test/test-mongocrypt-datakey.c b/test/test-mongocrypt-datakey.c index 1d48940cb..420d07dd9 100644 --- a/test/test-mongocrypt-datakey.c +++ b/test/test-mongocrypt-datakey.c @@ -427,6 +427,33 @@ static void _test_create_datakey_with_retry(_mongocrypt_tester_t *tester) { mongocrypt_destroy(crypt); } + // Test that an HTTP error is retried in-place. + { + mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); + mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt); + ASSERT_OK( + mongocrypt_ctx_setopt_key_encryption_key(ctx, + TEST_BSON("{'provider': 'aws', 'key': 'foo', 'region': 'bar'}")), + ctx); + ASSERT_OK(mongocrypt_ctx_datakey_init(ctx), ctx); + ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS); + mongocrypt_kms_ctx_t *kms_ctx = mongocrypt_ctx_next_kms_ctx(ctx); + ASSERT_OK(kms_ctx, ctx); + // Expect no sleep is requested before any error. + ASSERT_CMPINT64(mongocrypt_kms_ctx_usleep(kms_ctx), ==, 0); + // Feed a retryable HTTP error. + ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/rmd/kms-decrypt-reply-429.txt")), kms_ctx); + // In-place retry is indicated. + ASSERT(mongocrypt_kms_ctx_should_retry_http(kms_ctx)); + mongocrypt_kms_ctx_reset(kms_ctx); + // Feed a successful response. + ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/kms-aws/encrypt-response.txt")), kms_ctx); + ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx); + _mongocrypt_tester_run_ctx_to(tester, ctx, MONGOCRYPT_CTX_DONE); + mongocrypt_ctx_destroy(ctx); + mongocrypt_destroy(crypt); + } + // Test that a network error is retried. { mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); @@ -454,6 +481,32 @@ static void _test_create_datakey_with_retry(_mongocrypt_tester_t *tester) { mongocrypt_destroy(crypt); } + // Test that a network error is retried in-place. + { + mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); + mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt); + ASSERT_OK( + mongocrypt_ctx_setopt_key_encryption_key(ctx, + TEST_BSON("{'provider': 'aws', 'key': 'foo', 'region': 'bar'}")), + ctx); + ASSERT_OK(mongocrypt_ctx_datakey_init(ctx), ctx); + ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS); + mongocrypt_kms_ctx_t *kms_ctx = mongocrypt_ctx_next_kms_ctx(ctx); + ASSERT_OK(kms_ctx, ctx); + // Expect no sleep is requested before any error. + ASSERT_CMPINT64(mongocrypt_kms_ctx_usleep(kms_ctx), ==, 0); + // Feed part of a response + ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/kms-aws/encrypt-response-partial.txt")), kms_ctx); + // Assume a network error and reset the context. + mongocrypt_kms_ctx_reset(kms_ctx); + // Feed a successful response. + ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/kms-aws/encrypt-response.txt")), kms_ctx); + ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx); + _mongocrypt_tester_run_ctx_to(tester, ctx, MONGOCRYPT_CTX_DONE); + mongocrypt_ctx_destroy(ctx); + mongocrypt_destroy(crypt); + } + // Test that an oauth request is retried for a network error. { mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); From f6151535d14e1df0355e96a2105858592ad2b919 Mon Sep 17 00:00:00 2001 From: mdb-ad <198671546+mdb-ad@users.noreply.github.com> Date: Sat, 17 May 2025 16:38:49 -0700 Subject: [PATCH 02/18] format --- src/mongocrypt.h | 2 +- test/test-mongocrypt-datakey.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mongocrypt.h b/src/mongocrypt.h index 7f36b26d5..0bb6fc34d 100644 --- a/src/mongocrypt.h +++ b/src/mongocrypt.h @@ -1197,7 +1197,7 @@ MONGOCRYPT_EXPORT void mongocrypt_kms_ctx_reset(mongocrypt_kms_ctx_t *kms); /** - * Indicate if a KMS is completed but should be retried due to an HTTP error. + * Indicate if a KMS context is completed but should be retried due to an HTTP error. * * @param[in] kms The @ref mongocrypt_kms_ctx_t. * @return A boolean indicating whether the failed request is complete but should be retried. diff --git a/test/test-mongocrypt-datakey.c b/test/test-mongocrypt-datakey.c index 420d07dd9..beb581a3c 100644 --- a/test/test-mongocrypt-datakey.c +++ b/test/test-mongocrypt-datakey.c @@ -496,7 +496,8 @@ static void _test_create_datakey_with_retry(_mongocrypt_tester_t *tester) { // Expect no sleep is requested before any error. ASSERT_CMPINT64(mongocrypt_kms_ctx_usleep(kms_ctx), ==, 0); // Feed part of a response - ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/kms-aws/encrypt-response-partial.txt")), kms_ctx); + ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/kms-aws/encrypt-response-partial.txt")), + kms_ctx); // Assume a network error and reset the context. mongocrypt_kms_ctx_reset(kms_ctx); // Feed a successful response. From 4cb532638b0a1087658215be32bcca7e00f05186 Mon Sep 17 00:00:00 2001 From: mdb-ad <198671546+mdb-ad@users.noreply.github.com> Date: Tue, 17 Jun 2025 17:33:12 -0700 Subject: [PATCH 03/18] Apply suggestions from code review Co-authored-by: Kevin Albertson --- test/data/kms-aws/encrypt-response-partial.txt | 6 +++++- test/test-mongocrypt-datakey.c | 7 +++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/test/data/kms-aws/encrypt-response-partial.txt b/test/data/kms-aws/encrypt-response-partial.txt index 6ec20de97..65eaa01fe 100644 --- a/test/data/kms-aws/encrypt-response-partial.txt +++ b/test/data/kms-aws/encrypt-response-partial.txt @@ -1,3 +1,7 @@ HTTP/1.1 200 OK x-amzn-RequestId: deeb35e5-4ecb-4bf1-9af5-84a54ff0af0e -Content-Type: appli \ No newline at end of file +Content-Type: application/x-amz-json-1.1 +Content-Length: 446 +Connection: close + +{"KeyId": "arn:aws:k \ No newline at end of file diff --git a/test/test-mongocrypt-datakey.c b/test/test-mongocrypt-datakey.c index beb581a3c..121789de9 100644 --- a/test/test-mongocrypt-datakey.c +++ b/test/test-mongocrypt-datakey.c @@ -495,10 +495,9 @@ static void _test_create_datakey_with_retry(_mongocrypt_tester_t *tester) { ASSERT_OK(kms_ctx, ctx); // Expect no sleep is requested before any error. ASSERT_CMPINT64(mongocrypt_kms_ctx_usleep(kms_ctx), ==, 0); - // Feed part of a response - ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/kms-aws/encrypt-response-partial.txt")), - kms_ctx); - // Assume a network error and reset the context. + // Mark a network error. + ASSERT_OK(mongocrypt_kms_ctx_fail(kms_ctx), kms_ctx); + // Reset the context. mongocrypt_kms_ctx_reset(kms_ctx); // Feed a successful response. ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/kms-aws/encrypt-response.txt")), kms_ctx); From ab662af193aa8fd9cfeb436b2c297f0b188ada1d Mon Sep 17 00:00:00 2001 From: mdb-ad <198671546+mdb-ad@users.noreply.github.com> Date: Tue, 17 Jun 2025 18:36:21 -0700 Subject: [PATCH 04/18] Combine fail and reset --- src/mongocrypt-kms-ctx.c | 6 +++++- src/mongocrypt.h | 17 +++++------------ test/test-mongocrypt-datakey.c | 6 ++---- 3 files changed, 12 insertions(+), 17 deletions(-) diff --git a/src/mongocrypt-kms-ctx.c b/src/mongocrypt-kms-ctx.c index 34c4ad752..0c1206f0d 100644 --- a/src/mongocrypt-kms-ctx.c +++ b/src/mongocrypt-kms-ctx.c @@ -1138,7 +1138,7 @@ static bool _is_retryable_req(_kms_request_type_t req_type) { return false; } -bool mongocrypt_kms_ctx_should_retry_http(mongocrypt_kms_ctx_t *kms) { +bool mongocrypt_kms_ctx_should_retry(mongocrypt_kms_ctx_t *kms) { return kms && kms->should_retry; } @@ -1191,6 +1191,10 @@ bool mongocrypt_kms_ctx_feed(mongocrypt_kms_ctx_t *kms, mongocrypt_binary_t *byt if (!mongocrypt_status_ok(status)) { return false; } + if (kms->should_retry) { + // This happens when a KMS context is reused in-place + kms->should_retry = false; + } if (!bytes) { CLIENT_ERR("argument 'bytes' is required"); diff --git a/src/mongocrypt.h b/src/mongocrypt.h index 0bb6fc34d..b8275f5b6 100644 --- a/src/mongocrypt.h +++ b/src/mongocrypt.h @@ -1180,7 +1180,8 @@ MONGOCRYPT_EXPORT bool mongocrypt_kms_ctx_feed(mongocrypt_kms_ctx_t *kms, mongocrypt_binary_t *bytes); /** - * Indicate a network-level failure. + * Indicate a failure. Discards all data fed to this KMS context with @ref mongocrypt_kms_ctx_feed. + * The @ref mongocrypt_kms_ctx_t may be reused. * * @param[in] kms The @ref mongocrypt_kms_ctx_t. * @return A boolean indicating whether the failed request may be retried. @@ -1189,21 +1190,13 @@ MONGOCRYPT_EXPORT bool mongocrypt_kms_ctx_fail(mongocrypt_kms_ctx_t *kms); /** - * Reset a KMS context allowing it to be retried. + * Indicate if a KMS context is completed but should be retried. * * @param[in] kms The @ref mongocrypt_kms_ctx_t. + * @return A boolean indicating whether the failed request should be retried. */ MONGOCRYPT_EXPORT -void mongocrypt_kms_ctx_reset(mongocrypt_kms_ctx_t *kms); - -/** - * Indicate if a KMS context is completed but should be retried due to an HTTP error. - * - * @param[in] kms The @ref mongocrypt_kms_ctx_t. - * @return A boolean indicating whether the failed request is complete but should be retried. - */ -MONGOCRYPT_EXPORT -bool mongocrypt_kms_ctx_should_retry_http(mongocrypt_kms_ctx_t *kms); +bool mongocrypt_kms_ctx_should_retry(mongocrypt_kms_ctx_t *kms); /** * Get the status associated with a @ref mongocrypt_kms_ctx_t object. diff --git a/test/test-mongocrypt-datakey.c b/test/test-mongocrypt-datakey.c index 121789de9..e4d20b918 100644 --- a/test/test-mongocrypt-datakey.c +++ b/test/test-mongocrypt-datakey.c @@ -444,8 +444,8 @@ static void _test_create_datakey_with_retry(_mongocrypt_tester_t *tester) { // Feed a retryable HTTP error. ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/rmd/kms-decrypt-reply-429.txt")), kms_ctx); // In-place retry is indicated. - ASSERT(mongocrypt_kms_ctx_should_retry_http(kms_ctx)); - mongocrypt_kms_ctx_reset(kms_ctx); + ASSERT(mongocrypt_kms_ctx_should_retry(kms_ctx)); + ASSERT(mongocrypt_kms_ctx_fail(kms_ctx)); // Feed a successful response. ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/kms-aws/encrypt-response.txt")), kms_ctx); ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx); @@ -497,8 +497,6 @@ static void _test_create_datakey_with_retry(_mongocrypt_tester_t *tester) { ASSERT_CMPINT64(mongocrypt_kms_ctx_usleep(kms_ctx), ==, 0); // Mark a network error. ASSERT_OK(mongocrypt_kms_ctx_fail(kms_ctx), kms_ctx); - // Reset the context. - mongocrypt_kms_ctx_reset(kms_ctx); // Feed a successful response. ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/kms-aws/encrypt-response.txt")), kms_ctx); ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx); From db1b417acad6d14e16264177fcc30793beaa18cf Mon Sep 17 00:00:00 2001 From: mdb-ad <198671546+mdb-ad@users.noreply.github.com> Date: Tue, 17 Jun 2025 18:43:09 -0700 Subject: [PATCH 05/18] describe combined retry API --- integrating.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrating.md b/integrating.md index 1773e0ce5..a8a62f4d0 100644 --- a/integrating.md +++ b/integrating.md @@ -249,7 +249,7 @@ Ensure `mongocrypt_setopt_retry_kms` is called on the `mongocrypt_t` to enable r > until `mongocrypt_kms_ctx_bytes_needed` returns 0. If any step encounters a network error, call `mongocrypt_kms_ctx_fail`. - If `mongocrypt_kms_ctx_fail` returns true, continue to the next KMS context. + If `mongocrypt_kms_ctx_fail` returns true, retry the request by continuing to the next KMS context or by feeding the new response into the same context. If `mongocrypt_kms_ctx_fail` returns false, abort and report an error. Consider wrapping the error reported in `mongocrypt_kms_ctx_status` to include the last network error. 2. When done feeding all replies, call `mongocrypt_ctx_kms_done`. From 63b36a275f0f3329962189e01a916d2143929037 Mon Sep 17 00:00:00 2001 From: mdb-ad <198671546+mdb-ad@users.noreply.github.com> Date: Wed, 2 Jul 2025 22:57:25 -0700 Subject: [PATCH 06/18] document in-place retry --- integrating.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrating.md b/integrating.md index a8a62f4d0..230bdfd99 100644 --- a/integrating.md +++ b/integrating.md @@ -248,7 +248,7 @@ Ensure `mongocrypt_setopt_retry_kms` is called on the `mongocrypt_t` to enable r d. Feed the reply back with `mongocrypt_kms_ctx_feed`. Repeat > until `mongocrypt_kms_ctx_bytes_needed` returns 0. - If any step encounters a network error, call `mongocrypt_kms_ctx_fail`. + If any step encounters a network error or if `mongocrypt_kms_ctx_should_retry` returns true after feeding the reply, call `mongocrypt_kms_ctx_fail`. If `mongocrypt_kms_ctx_fail` returns true, retry the request by continuing to the next KMS context or by feeding the new response into the same context. If `mongocrypt_kms_ctx_fail` returns false, abort and report an error. Consider wrapping the error reported in `mongocrypt_kms_ctx_status` to include the last network error. From 7e44b5fbc2cfd3e064be43dc532e8ec8fa88a49d Mon Sep 17 00:00:00 2001 From: mdb-ad <198671546+mdb-ad@users.noreply.github.com> Date: Wed, 2 Jul 2025 22:57:36 -0700 Subject: [PATCH 07/18] remove unused kms_ctx_reset --- src/mongocrypt-kms-ctx.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/mongocrypt-kms-ctx.c b/src/mongocrypt-kms-ctx.c index 0c1206f0d..25ffa9f93 100644 --- a/src/mongocrypt-kms-ctx.c +++ b/src/mongocrypt-kms-ctx.c @@ -1142,13 +1142,6 @@ bool mongocrypt_kms_ctx_should_retry(mongocrypt_kms_ctx_t *kms) { return kms && kms->should_retry; } -void mongocrypt_kms_ctx_reset(mongocrypt_kms_ctx_t *kms) { - if (kms->parser) { - kms_response_parser_reset(kms->parser); - } - kms->should_retry = false; -} - bool mongocrypt_kms_ctx_fail(mongocrypt_kms_ctx_t *kms) { if (!kms) { return false; From 1b18ce8c98b92a1a661a3112aa3b4273f1dbffe5 Mon Sep 17 00:00:00 2001 From: mdb-ad <198671546+mdb-ad@users.noreply.github.com> Date: Wed, 16 Jul 2025 22:07:50 -0700 Subject: [PATCH 08/18] reset in set_retry --- src/mongocrypt-kms-ctx.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/mongocrypt-kms-ctx.c b/src/mongocrypt-kms-ctx.c index 25ffa9f93..cad880c38 100644 --- a/src/mongocrypt-kms-ctx.c +++ b/src/mongocrypt-kms-ctx.c @@ -15,6 +15,7 @@ */ #include "kms_message/kms_kmip_request.h" +#include "kms_message/kms_response_parser.h" #include "mongocrypt-binary-private.h" #include "mongocrypt-buffer-private.h" #include "mongocrypt-crypto-private.h" @@ -518,6 +519,9 @@ static void set_retry(mongocrypt_kms_ctx_t *kms) { kms->should_retry = true; kms->attempts++; kms->sleep_usec = backoff_time_usec(kms->attempts); + if (kms->parser) { + kms_response_parser_reset(kms->parser); + } } /* An AWS KMS context has received full response. Parse out the result or error. @@ -1167,11 +1171,6 @@ bool mongocrypt_kms_ctx_fail(mongocrypt_kms_ctx_t *kms) { // Mark KMS context as retryable. Return again in `mongocrypt_ctx_next_kms_ctx`. set_retry(kms); - - // Reset intermediate state of parser. - if (kms->parser) { - kms_response_parser_reset(kms->parser); - } return true; } From 9d920b832976c24c4e9fe0e40908b2121fb3118a Mon Sep 17 00:00:00 2001 From: mdb-ad <198671546+mdb-ad@users.noreply.github.com> Date: Wed, 20 Aug 2025 23:25:49 -0700 Subject: [PATCH 09/18] new api with ctx_feed_with_retry --- src/mongocrypt-kms-ctx.c | 11 +++--- src/mongocrypt.h | 22 ++++++++---- test/test-mongocrypt-datakey.c | 61 ++++++++++++++++++++++++++++++++-- 3 files changed, 80 insertions(+), 14 deletions(-) diff --git a/src/mongocrypt-kms-ctx.c b/src/mongocrypt-kms-ctx.c index cad880c38..6b045502b 100644 --- a/src/mongocrypt-kms-ctx.c +++ b/src/mongocrypt-kms-ctx.c @@ -1142,10 +1142,6 @@ static bool _is_retryable_req(_kms_request_type_t req_type) { return false; } -bool mongocrypt_kms_ctx_should_retry(mongocrypt_kms_ctx_t *kms) { - return kms && kms->should_retry; -} - bool mongocrypt_kms_ctx_fail(mongocrypt_kms_ctx_t *kms) { if (!kms) { return false; @@ -1174,6 +1170,13 @@ bool mongocrypt_kms_ctx_fail(mongocrypt_kms_ctx_t *kms) { return true; } +bool mongocrypt_kms_ctx_feed_with_retry(mongocrypt_kms_ctx_t *kms, mongocrypt_binary_t *bytes, bool *should_retry) { + *should_retry = false; + const bool res = mongocrypt_kms_ctx_feed(kms, bytes); + *should_retry = kms->should_retry && kms->retry_enabled; + return res; +} + bool mongocrypt_kms_ctx_feed(mongocrypt_kms_ctx_t *kms, mongocrypt_binary_t *bytes) { if (!kms) { return false; diff --git a/src/mongocrypt.h b/src/mongocrypt.h index b8275f5b6..46ecc19a2 100644 --- a/src/mongocrypt.h +++ b/src/mongocrypt.h @@ -1180,23 +1180,31 @@ MONGOCRYPT_EXPORT bool mongocrypt_kms_ctx_feed(mongocrypt_kms_ctx_t *kms, mongocrypt_binary_t *bytes); /** - * Indicate a failure. Discards all data fed to this KMS context with @ref mongocrypt_kms_ctx_feed. - * The @ref mongocrypt_kms_ctx_t may be reused. + * Feed bytes from the HTTP response. + * + * Feeding more bytes than what has been returned in @ref + * mongocrypt_kms_ctx_bytes_needed is an error. * * @param[in] kms The @ref mongocrypt_kms_ctx_t. - * @return A boolean indicating whether the failed request may be retried. + * @param[in] bytes The bytes to feed. The viewed data is copied. It is valid to + * destroy @p bytes with @ref mongocrypt_binary_destroy immediately after. + * @param[out] should_retry Whether the KMS request should be retried. Retry in-place + * without calling @ref mongocrypt_kms_ctx_fail. + * @returns A boolean indicating success. If false, an error status is set. + * Retrieve it with @ref mongocrypt_kms_ctx_status */ MONGOCRYPT_EXPORT -bool mongocrypt_kms_ctx_fail(mongocrypt_kms_ctx_t *kms); +bool mongocrypt_kms_ctx_feed_with_retry(mongocrypt_kms_ctx_t *kms, mongocrypt_binary_t *bytes, bool *should_retry); /** - * Indicate if a KMS context is completed but should be retried. + * Indicate a network error. Discards all data fed to this KMS context with @ref mongocrypt_kms_ctx_feed. + * The @ref mongocrypt_kms_ctx_t may be reused. * * @param[in] kms The @ref mongocrypt_kms_ctx_t. - * @return A boolean indicating whether the failed request should be retried. + * @return A boolean indicating whether the failed request may be retried. */ MONGOCRYPT_EXPORT -bool mongocrypt_kms_ctx_should_retry(mongocrypt_kms_ctx_t *kms); +bool mongocrypt_kms_ctx_fail(mongocrypt_kms_ctx_t *kms); /** * Get the status associated with a @ref mongocrypt_kms_ctx_t object. diff --git a/test/test-mongocrypt-datakey.c b/test/test-mongocrypt-datakey.c index e4d20b918..9d76e90ed 100644 --- a/test/test-mongocrypt-datakey.c +++ b/test/test-mongocrypt-datakey.c @@ -431,6 +431,7 @@ static void _test_create_datakey_with_retry(_mongocrypt_tester_t *tester) { { mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt); + bool should_retry; ASSERT_OK( mongocrypt_ctx_setopt_key_encryption_key(ctx, TEST_BSON("{'provider': 'aws', 'key': 'foo', 'region': 'bar'}")), @@ -442,10 +443,22 @@ static void _test_create_datakey_with_retry(_mongocrypt_tester_t *tester) { // Expect no sleep is requested before any error. ASSERT_CMPINT64(mongocrypt_kms_ctx_usleep(kms_ctx), ==, 0); // Feed a retryable HTTP error. - ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/rmd/kms-decrypt-reply-429.txt")), kms_ctx); + ASSERT_OK(mongocrypt_kms_ctx_feed_with_retry(kms_ctx, + TEST_FILE("./test/data/rmd/kms-decrypt-reply-429.txt"), + &should_retry), + kms_ctx); + // In-place retry is indicated. + ASSERT(should_retry); + // Feed another retryable HTTP error. + ASSERT_OK(mongocrypt_kms_ctx_feed_with_retry(kms_ctx, + TEST_FILE("./test/data/rmd/kms-decrypt-reply-429.txt"), + &should_retry), + kms_ctx); + // Expect some sleep is requested + ASSERT_CMPINT64(mongocrypt_kms_ctx_usleep(kms_ctx), >=, 0); // In-place retry is indicated. - ASSERT(mongocrypt_kms_ctx_should_retry(kms_ctx)); - ASSERT(mongocrypt_kms_ctx_fail(kms_ctx)); + ASSERT(should_retry); + ASSERT(kms_ctx->attempts == 2); // Feed a successful response. ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/kms-aws/encrypt-response.txt")), kms_ctx); ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx); @@ -497,6 +510,48 @@ static void _test_create_datakey_with_retry(_mongocrypt_tester_t *tester) { ASSERT_CMPINT64(mongocrypt_kms_ctx_usleep(kms_ctx), ==, 0); // Mark a network error. ASSERT_OK(mongocrypt_kms_ctx_fail(kms_ctx), kms_ctx); + // Feed a partial response + ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/kms-aws/encrypt-response-partial.txt")), + kms_ctx); + // Mark another network error. + ASSERT_OK(mongocrypt_kms_ctx_fail(kms_ctx), kms_ctx); + // Expect some sleep is requested + ASSERT_CMPINT64(mongocrypt_kms_ctx_usleep(kms_ctx), >=, 0); + ASSERT(kms_ctx->attempts == 2); + // Feed a successful response. + ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/kms-aws/encrypt-response.txt")), kms_ctx); + ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx); + _mongocrypt_tester_run_ctx_to(tester, ctx, MONGOCRYPT_CTX_DONE); + mongocrypt_ctx_destroy(ctx); + mongocrypt_destroy(crypt); + } + // Test that subsequent network and HTTP errors can be retried in-place + { + mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); + mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt); + bool should_retry; + ASSERT_OK( + mongocrypt_ctx_setopt_key_encryption_key(ctx, + TEST_BSON("{'provider': 'aws', 'key': 'foo', 'region': 'bar'}")), + ctx); + ASSERT_OK(mongocrypt_ctx_datakey_init(ctx), ctx); + ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS); + mongocrypt_kms_ctx_t *kms_ctx = mongocrypt_ctx_next_kms_ctx(ctx); + ASSERT_OK(kms_ctx, ctx); + // Expect no sleep is requested before any error. + ASSERT_CMPINT64(mongocrypt_kms_ctx_usleep(kms_ctx), ==, 0); + // Mark a network error. + ASSERT_OK(mongocrypt_kms_ctx_fail(kms_ctx), kms_ctx); + // Feed a retryable HTTP error. + ASSERT_OK(mongocrypt_kms_ctx_feed_with_retry(kms_ctx, + TEST_FILE("./test/data/rmd/kms-decrypt-reply-429.txt"), + &should_retry), + kms_ctx); + // In-place retry is indicated. + ASSERT(should_retry); + // Expect some sleep is requested + ASSERT_CMPINT64(mongocrypt_kms_ctx_usleep(kms_ctx), >=, 0); + ASSERT(kms_ctx->attempts == 2); // Feed a successful response. ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/kms-aws/encrypt-response.txt")), kms_ctx); ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx); From 33f4c2654e9c72fda73b01bc6a1eef8cab616ef0 Mon Sep 17 00:00:00 2001 From: mdb-ad <198671546+mdb-ad@users.noreply.github.com> Date: Wed, 20 Aug 2025 23:33:30 -0700 Subject: [PATCH 10/18] subsequent error tests --- test/test-mongocrypt-datakey.c | 50 ++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/test/test-mongocrypt-datakey.c b/test/test-mongocrypt-datakey.c index 9d76e90ed..f979783d1 100644 --- a/test/test-mongocrypt-datakey.c +++ b/test/test-mongocrypt-datakey.c @@ -443,17 +443,11 @@ static void _test_create_datakey_with_retry(_mongocrypt_tester_t *tester) { // Expect no sleep is requested before any error. ASSERT_CMPINT64(mongocrypt_kms_ctx_usleep(kms_ctx), ==, 0); // Feed a retryable HTTP error. - ASSERT_OK(mongocrypt_kms_ctx_feed_with_retry(kms_ctx, - TEST_FILE("./test/data/rmd/kms-decrypt-reply-429.txt"), - &should_retry), - kms_ctx); + ASSERT_OK(mongocrypt_kms_ctx_feed_with_retry(kms_ctx, TEST_FILE("./test/data/rmd/kms-decrypt-reply-429.txt"), &should_retry), kms_ctx); // In-place retry is indicated. ASSERT(should_retry); // Feed another retryable HTTP error. - ASSERT_OK(mongocrypt_kms_ctx_feed_with_retry(kms_ctx, - TEST_FILE("./test/data/rmd/kms-decrypt-reply-429.txt"), - &should_retry), - kms_ctx); + ASSERT_OK(mongocrypt_kms_ctx_feed_with_retry(kms_ctx, TEST_FILE("./test/data/rmd/kms-decrypt-reply-429.txt"), &should_retry), kms_ctx); // Expect some sleep is requested ASSERT_CMPINT64(mongocrypt_kms_ctx_usleep(kms_ctx), >=, 0); // In-place retry is indicated. @@ -511,8 +505,7 @@ static void _test_create_datakey_with_retry(_mongocrypt_tester_t *tester) { // Mark a network error. ASSERT_OK(mongocrypt_kms_ctx_fail(kms_ctx), kms_ctx); // Feed a partial response - ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/kms-aws/encrypt-response-partial.txt")), - kms_ctx); + ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/kms-aws/encrypt-response-partial.txt")), kms_ctx); // Mark another network error. ASSERT_OK(mongocrypt_kms_ctx_fail(kms_ctx), kms_ctx); // Expect some sleep is requested @@ -543,10 +536,7 @@ static void _test_create_datakey_with_retry(_mongocrypt_tester_t *tester) { // Mark a network error. ASSERT_OK(mongocrypt_kms_ctx_fail(kms_ctx), kms_ctx); // Feed a retryable HTTP error. - ASSERT_OK(mongocrypt_kms_ctx_feed_with_retry(kms_ctx, - TEST_FILE("./test/data/rmd/kms-decrypt-reply-429.txt"), - &should_retry), - kms_ctx); + ASSERT_OK(mongocrypt_kms_ctx_feed_with_retry(kms_ctx, TEST_FILE("./test/data/rmd/kms-decrypt-reply-429.txt"), &should_retry), kms_ctx); // In-place retry is indicated. ASSERT(should_retry); // Expect some sleep is requested @@ -560,6 +550,38 @@ static void _test_create_datakey_with_retry(_mongocrypt_tester_t *tester) { mongocrypt_destroy(crypt); } + // Test that subsequent HTTP and network errors can be retried in-place + { + mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); + mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt); + bool should_retry; + ASSERT_OK( + mongocrypt_ctx_setopt_key_encryption_key(ctx, + TEST_BSON("{'provider': 'aws', 'key': 'foo', 'region': 'bar'}")), + ctx); + ASSERT_OK(mongocrypt_ctx_datakey_init(ctx), ctx); + ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS); + mongocrypt_kms_ctx_t *kms_ctx = mongocrypt_ctx_next_kms_ctx(ctx); + ASSERT_OK(kms_ctx, ctx); + // Expect no sleep is requested before any error. + ASSERT_CMPINT64(mongocrypt_kms_ctx_usleep(kms_ctx), ==, 0); + // Feed a retryable HTTP error. + ASSERT_OK(mongocrypt_kms_ctx_feed_with_retry(kms_ctx, TEST_FILE("./test/data/rmd/kms-decrypt-reply-429.txt"), &should_retry), kms_ctx); + // In-place retry is indicated. + ASSERT(should_retry); + // Mark a network error. + ASSERT_OK(mongocrypt_kms_ctx_fail(kms_ctx), kms_ctx); + // Expect some sleep is requested + ASSERT_CMPINT64(mongocrypt_kms_ctx_usleep(kms_ctx), >=, 0); + ASSERT(kms_ctx->attempts == 2); + // Feed a successful response. + ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/kms-aws/encrypt-response.txt")), kms_ctx); + ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx); + _mongocrypt_tester_run_ctx_to(tester, ctx, MONGOCRYPT_CTX_DONE); + mongocrypt_ctx_destroy(ctx); + mongocrypt_destroy(crypt); + } + // Test that an oauth request is retried for a network error. { mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); From 9745fa7e81b80b5fbd58e1dab417d2426beea13d Mon Sep 17 00:00:00 2001 From: mdb-ad <198671546+mdb-ad@users.noreply.github.com> Date: Wed, 20 Aug 2025 23:33:40 -0700 Subject: [PATCH 11/18] feed_with_retry in integrating.md --- integrating.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/integrating.md b/integrating.md index 230bdfd99..d835df41e 100644 --- a/integrating.md +++ b/integrating.md @@ -245,10 +245,11 @@ Ensure `mongocrypt_setopt_retry_kms` is called on the `mongocrypt_t` to enable r c. Write the message from `mongocrypt_kms_ctx_message` to the > socket. - d. Feed the reply back with `mongocrypt_kms_ctx_feed`. Repeat - > until `mongocrypt_kms_ctx_bytes_needed` returns 0. + d. Feed the reply back with `mongocrypt_kms_ctx_feed` or `mongocrypt_kms_ctx_feed_with_retry`. Repeat + > until `mongocrypt_kms_ctx_bytes_needed` returns 0. If the `should_retry` outparam returns true, + the request may be retried by feeding the new response into the same context. - If any step encounters a network error or if `mongocrypt_kms_ctx_should_retry` returns true after feeding the reply, call `mongocrypt_kms_ctx_fail`. + If any step encounters a network error, call `mongocrypt_kms_ctx_fail`. If `mongocrypt_kms_ctx_fail` returns true, retry the request by continuing to the next KMS context or by feeding the new response into the same context. If `mongocrypt_kms_ctx_fail` returns false, abort and report an error. Consider wrapping the error reported in `mongocrypt_kms_ctx_status` to include the last network error. From 10198ca4af2daa5a0d6ad033064689cea32450c7 Mon Sep 17 00:00:00 2001 From: mdb-ad <198671546+mdb-ad@users.noreply.github.com> Date: Tue, 9 Sep 2025 21:09:51 -0700 Subject: [PATCH 12/18] Apply suggestions from code review Co-authored-by: Kevin Albertson --- integrating.md | 2 +- src/mongocrypt-kms-ctx.c | 3 +++ src/mongocrypt.h | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/integrating.md b/integrating.md index d835df41e..488ac1394 100644 --- a/integrating.md +++ b/integrating.md @@ -246,7 +246,7 @@ Ensure `mongocrypt_setopt_retry_kms` is called on the `mongocrypt_t` to enable r > socket. d. Feed the reply back with `mongocrypt_kms_ctx_feed` or `mongocrypt_kms_ctx_feed_with_retry`. Repeat - > until `mongocrypt_kms_ctx_bytes_needed` returns 0. If the `should_retry` outparam returns true, + until `mongocrypt_kms_ctx_bytes_needed` returns 0. If the `should_retry` outparam returns true, the request may be retried by feeding the new response into the same context. If any step encounters a network error, call `mongocrypt_kms_ctx_fail`. diff --git a/src/mongocrypt-kms-ctx.c b/src/mongocrypt-kms-ctx.c index 6b045502b..b775057ca 100644 --- a/src/mongocrypt-kms-ctx.c +++ b/src/mongocrypt-kms-ctx.c @@ -1171,6 +1171,9 @@ bool mongocrypt_kms_ctx_fail(mongocrypt_kms_ctx_t *kms) { } bool mongocrypt_kms_ctx_feed_with_retry(mongocrypt_kms_ctx_t *kms, mongocrypt_binary_t *bytes, bool *should_retry) { + BSON_ASSERT_PARAM(kms); + BSON_ASSERT_PARAM(bytes); + BSON_ASSERT_PARAM(should_retry); *should_retry = false; const bool res = mongocrypt_kms_ctx_feed(kms, bytes); *should_retry = kms->should_retry && kms->retry_enabled; diff --git a/src/mongocrypt.h b/src/mongocrypt.h index 46ecc19a2..91190e0f3 100644 --- a/src/mongocrypt.h +++ b/src/mongocrypt.h @@ -1180,7 +1180,7 @@ MONGOCRYPT_EXPORT bool mongocrypt_kms_ctx_feed(mongocrypt_kms_ctx_t *kms, mongocrypt_binary_t *bytes); /** - * Feed bytes from the HTTP response. + * Feed bytes from the KMS response. * * Feeding more bytes than what has been returned in @ref * mongocrypt_kms_ctx_bytes_needed is an error. From e194d3f57655312919f627efef4cfc0d3f13ad90 Mon Sep 17 00:00:00 2001 From: mdb-ad <198671546+mdb-ad@users.noreply.github.com> Date: Tue, 9 Sep 2025 21:49:20 -0700 Subject: [PATCH 13/18] ctx_feed (non-retry) on context requiring retry is an error --- src/mongocrypt-kms-ctx.c | 5 +++-- test/test-mongocrypt-datakey.c | 23 ++++++++++++++++++----- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/mongocrypt-kms-ctx.c b/src/mongocrypt-kms-ctx.c index b775057ca..ebc85e735 100644 --- a/src/mongocrypt-kms-ctx.c +++ b/src/mongocrypt-kms-ctx.c @@ -1174,6 +1174,7 @@ bool mongocrypt_kms_ctx_feed_with_retry(mongocrypt_kms_ctx_t *kms, mongocrypt_bi BSON_ASSERT_PARAM(kms); BSON_ASSERT_PARAM(bytes); BSON_ASSERT_PARAM(should_retry); + kms->should_retry = false; *should_retry = false; const bool res = mongocrypt_kms_ctx_feed(kms, bytes); *should_retry = kms->should_retry && kms->retry_enabled; @@ -1190,8 +1191,8 @@ bool mongocrypt_kms_ctx_feed(mongocrypt_kms_ctx_t *kms, mongocrypt_binary_t *byt return false; } if (kms->should_retry) { - // This happens when a KMS context is reused in-place - kms->should_retry = false; + CLIENT_ERR("KMS context needs retry. Call mongocrypt_kms_ctx_feed_with_retry instead"); + return false; } if (!bytes) { diff --git a/test/test-mongocrypt-datakey.c b/test/test-mongocrypt-datakey.c index f979783d1..98886cf08 100644 --- a/test/test-mongocrypt-datakey.c +++ b/test/test-mongocrypt-datakey.c @@ -443,11 +443,17 @@ static void _test_create_datakey_with_retry(_mongocrypt_tester_t *tester) { // Expect no sleep is requested before any error. ASSERT_CMPINT64(mongocrypt_kms_ctx_usleep(kms_ctx), ==, 0); // Feed a retryable HTTP error. - ASSERT_OK(mongocrypt_kms_ctx_feed_with_retry(kms_ctx, TEST_FILE("./test/data/rmd/kms-decrypt-reply-429.txt"), &should_retry), kms_ctx); + ASSERT_OK(mongocrypt_kms_ctx_feed_with_retry(kms_ctx, + TEST_FILE("./test/data/rmd/kms-decrypt-reply-429.txt"), + &should_retry), + kms_ctx); // In-place retry is indicated. ASSERT(should_retry); // Feed another retryable HTTP error. - ASSERT_OK(mongocrypt_kms_ctx_feed_with_retry(kms_ctx, TEST_FILE("./test/data/rmd/kms-decrypt-reply-429.txt"), &should_retry), kms_ctx); + ASSERT_OK(mongocrypt_kms_ctx_feed_with_retry(kms_ctx, + TEST_FILE("./test/data/rmd/kms-decrypt-reply-429.txt"), + &should_retry), + kms_ctx); // Expect some sleep is requested ASSERT_CMPINT64(mongocrypt_kms_ctx_usleep(kms_ctx), >=, 0); // In-place retry is indicated. @@ -505,7 +511,8 @@ static void _test_create_datakey_with_retry(_mongocrypt_tester_t *tester) { // Mark a network error. ASSERT_OK(mongocrypt_kms_ctx_fail(kms_ctx), kms_ctx); // Feed a partial response - ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/kms-aws/encrypt-response-partial.txt")), kms_ctx); + ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/kms-aws/encrypt-response-partial.txt")), + kms_ctx); // Mark another network error. ASSERT_OK(mongocrypt_kms_ctx_fail(kms_ctx), kms_ctx); // Expect some sleep is requested @@ -536,7 +543,10 @@ static void _test_create_datakey_with_retry(_mongocrypt_tester_t *tester) { // Mark a network error. ASSERT_OK(mongocrypt_kms_ctx_fail(kms_ctx), kms_ctx); // Feed a retryable HTTP error. - ASSERT_OK(mongocrypt_kms_ctx_feed_with_retry(kms_ctx, TEST_FILE("./test/data/rmd/kms-decrypt-reply-429.txt"), &should_retry), kms_ctx); + ASSERT_OK(mongocrypt_kms_ctx_feed_with_retry(kms_ctx, + TEST_FILE("./test/data/rmd/kms-decrypt-reply-429.txt"), + &should_retry), + kms_ctx); // In-place retry is indicated. ASSERT(should_retry); // Expect some sleep is requested @@ -566,7 +576,10 @@ static void _test_create_datakey_with_retry(_mongocrypt_tester_t *tester) { // Expect no sleep is requested before any error. ASSERT_CMPINT64(mongocrypt_kms_ctx_usleep(kms_ctx), ==, 0); // Feed a retryable HTTP error. - ASSERT_OK(mongocrypt_kms_ctx_feed_with_retry(kms_ctx, TEST_FILE("./test/data/rmd/kms-decrypt-reply-429.txt"), &should_retry), kms_ctx); + ASSERT_OK(mongocrypt_kms_ctx_feed_with_retry(kms_ctx, + TEST_FILE("./test/data/rmd/kms-decrypt-reply-429.txt"), + &should_retry), + kms_ctx); // In-place retry is indicated. ASSERT(should_retry); // Mark a network error. From bb6803c2063e438f131f9d24be29982d9554c409 Mon Sep 17 00:00:00 2001 From: mdb-ad <198671546+mdb-ad@users.noreply.github.com> Date: Tue, 9 Sep 2025 21:50:05 -0700 Subject: [PATCH 14/18] retry description in integrating.md --- integrating.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/integrating.md b/integrating.md index 488ac1394..f975cc7d2 100644 --- a/integrating.md +++ b/integrating.md @@ -255,7 +255,18 @@ Ensure `mongocrypt_setopt_retry_kms` is called on the `mongocrypt_t` to enable r 2. When done feeding all replies, call `mongocrypt_ctx_kms_done`. -Note, the driver MAY fan out KMS requests in parallel. More KMS requests may be added when processing responses to retry. +##### Retry and Iteration + +Call `mongocrypt_setopt_retry_kms` to enable retry behavior. + +There are two options for retry: +- Lazy retry: After processing KMS contexts, iterate again by calling `mongocrypt_ctx_next_kms_ctx`. KMS contexts + needing a retry will be returned. +- In-place retry: If a KMS context indicates retry, retry the KMS request and feed the new response to the same KMS + context. Use `mongocrypt_kms_ctx_feed_with_retry` and check the return of `mongocrypt_kms_ctx_fail` to check if a + retry is indicated. + +The driver MAY fan out KMS requests in parallel. It is not safe to iterate KMS contexts (i.e. call `mongocrypt_ctx_next_kms_ctx`) while operating on KMS contexts (e.g. calling `mongocrypt_kms_ctx_feed`). Drivers are recommended to do an in-place retry on KMS requests. **Applies to...** From 3f808191850daf1d5ca4ff196d2bd1cc0d95663c Mon Sep 17 00:00:00 2001 From: mdb-ad <198671546+mdb-ad@users.noreply.github.com> Date: Tue, 9 Sep 2025 22:51:47 -0700 Subject: [PATCH 15/18] use feed_with_retry in tests --- test/test-mongocrypt-datakey.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/test/test-mongocrypt-datakey.c b/test/test-mongocrypt-datakey.c index 98886cf08..cade8049b 100644 --- a/test/test-mongocrypt-datakey.c +++ b/test/test-mongocrypt-datakey.c @@ -459,8 +459,13 @@ static void _test_create_datakey_with_retry(_mongocrypt_tester_t *tester) { // In-place retry is indicated. ASSERT(should_retry); ASSERT(kms_ctx->attempts == 2); + // Feed a successful response. - ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/kms-aws/encrypt-response.txt")), kms_ctx); + ASSERT_OK(mongocrypt_kms_ctx_feed_with_retry(kms_ctx, + TEST_FILE("./test/data/kms-aws/encrypt-response.txt"), + &should_retry), + kms_ctx); + ASSERT(!should_retry); ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx); _mongocrypt_tester_run_ctx_to(tester, ctx, MONGOCRYPT_CTX_DONE); mongocrypt_ctx_destroy(ctx); @@ -498,6 +503,7 @@ static void _test_create_datakey_with_retry(_mongocrypt_tester_t *tester) { { mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt); + bool should_retry; ASSERT_OK( mongocrypt_ctx_setopt_key_encryption_key(ctx, TEST_BSON("{'provider': 'aws', 'key': 'foo', 'region': 'bar'}")), @@ -511,7 +517,9 @@ static void _test_create_datakey_with_retry(_mongocrypt_tester_t *tester) { // Mark a network error. ASSERT_OK(mongocrypt_kms_ctx_fail(kms_ctx), kms_ctx); // Feed a partial response - ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/kms-aws/encrypt-response-partial.txt")), + ASSERT_OK(mongocrypt_kms_ctx_feed_with_retry(kms_ctx, + TEST_FILE("./test/data/kms-aws/encrypt-response-partial.txt"), + &should_retry), kms_ctx); // Mark another network error. ASSERT_OK(mongocrypt_kms_ctx_fail(kms_ctx), kms_ctx); @@ -519,7 +527,11 @@ static void _test_create_datakey_with_retry(_mongocrypt_tester_t *tester) { ASSERT_CMPINT64(mongocrypt_kms_ctx_usleep(kms_ctx), >=, 0); ASSERT(kms_ctx->attempts == 2); // Feed a successful response. - ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/kms-aws/encrypt-response.txt")), kms_ctx); + ASSERT_OK(mongocrypt_kms_ctx_feed_with_retry(kms_ctx, + TEST_FILE("./test/data/kms-aws/encrypt-response.txt"), + &should_retry), + kms_ctx); + ASSERT(!should_retry); ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx); _mongocrypt_tester_run_ctx_to(tester, ctx, MONGOCRYPT_CTX_DONE); mongocrypt_ctx_destroy(ctx); @@ -553,7 +565,11 @@ static void _test_create_datakey_with_retry(_mongocrypt_tester_t *tester) { ASSERT_CMPINT64(mongocrypt_kms_ctx_usleep(kms_ctx), >=, 0); ASSERT(kms_ctx->attempts == 2); // Feed a successful response. - ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/kms-aws/encrypt-response.txt")), kms_ctx); + ASSERT_OK(mongocrypt_kms_ctx_feed_with_retry(kms_ctx, + TEST_FILE("./test/data/kms-aws/encrypt-response.txt"), + &should_retry), + kms_ctx); + ASSERT(!should_retry); ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx); _mongocrypt_tester_run_ctx_to(tester, ctx, MONGOCRYPT_CTX_DONE); mongocrypt_ctx_destroy(ctx); @@ -588,7 +604,10 @@ static void _test_create_datakey_with_retry(_mongocrypt_tester_t *tester) { ASSERT_CMPINT64(mongocrypt_kms_ctx_usleep(kms_ctx), >=, 0); ASSERT(kms_ctx->attempts == 2); // Feed a successful response. - ASSERT_OK(mongocrypt_kms_ctx_feed(kms_ctx, TEST_FILE("./test/data/kms-aws/encrypt-response.txt")), kms_ctx); + ASSERT_OK(mongocrypt_kms_ctx_feed_with_retry(kms_ctx, + TEST_FILE("./test/data/kms-aws/encrypt-response.txt"), + &should_retry), + kms_ctx); ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx); _mongocrypt_tester_run_ctx_to(tester, ctx, MONGOCRYPT_CTX_DONE); mongocrypt_ctx_destroy(ctx); From 0344b1c8374f3dfa4e32f5864b6a67fc3da0efc4 Mon Sep 17 00:00:00 2001 From: mdb-ad <198671546+mdb-ad@users.noreply.github.com> Date: Tue, 9 Sep 2025 23:10:06 -0700 Subject: [PATCH 16/18] format integrating.md --- integrating.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/integrating.md b/integrating.md index f975cc7d2..cec26fa88 100644 --- a/integrating.md +++ b/integrating.md @@ -266,7 +266,9 @@ There are two options for retry: context. Use `mongocrypt_kms_ctx_feed_with_retry` and check the return of `mongocrypt_kms_ctx_fail` to check if a retry is indicated. -The driver MAY fan out KMS requests in parallel. It is not safe to iterate KMS contexts (i.e. call `mongocrypt_ctx_next_kms_ctx`) while operating on KMS contexts (e.g. calling `mongocrypt_kms_ctx_feed`). Drivers are recommended to do an in-place retry on KMS requests. +The driver MAY fan out KMS requests in parallel. It is not safe to iterate KMS contexts (i.e. call +`mongocrypt_ctx_next_kms_ctx`) while operating on KMS contexts (e.g. calling `mongocrypt_kms_ctx_feed`). Drivers are +recommended to do an in-place retry on KMS requests. **Applies to...** From 80c91ec1943f4de46f96be61285f6799c1b3b3e2 Mon Sep 17 00:00:00 2001 From: mdb-ad <198671546+mdb-ad@users.noreply.github.com> Date: Thu, 11 Sep 2025 19:32:10 -0700 Subject: [PATCH 17/18] Apply suggestions from code review Co-authored-by: Kevin Albertson --- test/test-mongocrypt-datakey.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/test-mongocrypt-datakey.c b/test/test-mongocrypt-datakey.c index cade8049b..c6a6183d5 100644 --- a/test/test-mongocrypt-datakey.c +++ b/test/test-mongocrypt-datakey.c @@ -521,6 +521,7 @@ static void _test_create_datakey_with_retry(_mongocrypt_tester_t *tester) { TEST_FILE("./test/data/kms-aws/encrypt-response-partial.txt"), &should_retry), kms_ctx); + ASSERT(!should_retry); // Mark another network error. ASSERT_OK(mongocrypt_kms_ctx_fail(kms_ctx), kms_ctx); // Expect some sleep is requested @@ -608,6 +609,7 @@ static void _test_create_datakey_with_retry(_mongocrypt_tester_t *tester) { TEST_FILE("./test/data/kms-aws/encrypt-response.txt"), &should_retry), kms_ctx); + ASSERT(!should_retry); ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx); _mongocrypt_tester_run_ctx_to(tester, ctx, MONGOCRYPT_CTX_DONE); mongocrypt_ctx_destroy(ctx); From 4734aafee69d2f25f9ac17eda17d90bf5de3c18e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20C=2E=20S=C3=A1nchez?= Date: Fri, 12 Sep 2025 09:46:32 -0400 Subject: [PATCH 18/18] MONGOCRYPT-845 rename mlib directory to avoid header conflicts (#1070) --- CMakeLists.txt | 34 ++++++++++++------------ src/mc-dec128.h | 6 ++--- src/mc-dec128.test.cpp | 2 +- src/mc-efc.c | 2 +- src/mc-fle2-rfds.c | 4 +-- src/{mlib => mc-mlib}/check.hpp | 0 src/{mlib => mc-mlib}/endian.h | 0 src/{mlib => mc-mlib}/error.h | 0 src/{mlib => mc-mlib}/int128.h | 0 src/{mlib => mc-mlib}/int128.test.c | 0 src/{mlib => mc-mlib}/int128.test.cpp | 0 src/{mlib => mc-mlib}/macros.h | 0 src/{mlib => mc-mlib}/path.h | 0 src/{mlib => mc-mlib}/path.test.c | 0 src/{mlib => mc-mlib}/str.h | 0 src/{mlib => mc-mlib}/str.test.c | 0 src/{mlib => mc-mlib}/thread.h | 0 src/{mlib => mc-mlib}/user-check.h | 0 src/{mlib => mc-mlib}/windows-lean.h | 2 +- src/mc-optional-private.h | 2 +- src/mc-range-edge-generation-private.h | 2 +- src/mc-range-encoding-private.h | 2 +- src/mongocrypt-ctx.c | 2 +- src/mongocrypt-dll-private.h | 4 +-- src/mongocrypt-opts-private.h | 2 +- src/mongocrypt-private.h | 2 +- src/mongocrypt-util-private.h | 2 +- src/mongocrypt-util.c | 2 +- src/mongocrypt.c | 6 ++--- src/os_win/os_dll.c | 6 ++--- test/test-mongocrypt-assert-match-bson.c | 2 +- test/test-mongocrypt-dll.c | 2 +- 32 files changed, 43 insertions(+), 43 deletions(-) rename src/{mlib => mc-mlib}/check.hpp (100%) rename src/{mlib => mc-mlib}/endian.h (100%) rename src/{mlib => mc-mlib}/error.h (100%) rename src/{mlib => mc-mlib}/int128.h (100%) rename src/{mlib => mc-mlib}/int128.test.c (100%) rename src/{mlib => mc-mlib}/int128.test.cpp (100%) rename src/{mlib => mc-mlib}/macros.h (100%) rename src/{mlib => mc-mlib}/path.h (100%) rename src/{mlib => mc-mlib}/path.test.c (100%) rename src/{mlib => mc-mlib}/str.h (100%) rename src/{mlib => mc-mlib}/str.test.c (100%) rename src/{mlib => mc-mlib}/thread.h (100%) rename src/{mlib => mc-mlib}/user-check.h (100%) rename src/{mlib => mc-mlib}/windows-lean.h (85%) diff --git a/CMakeLists.txt b/CMakeLists.txt index d43082c02..3fe687997 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -233,22 +233,22 @@ configure_file ( "${PROJECT_BINARY_DIR}/src/mongocrypt-config.h" ) -# Define the mlib target, which is private and header-only. It is not exported +# Define the mc-mlib target, which is private and header-only. It is not exported # nor are its headers installed. -add_library (_mongo-mlib INTERFACE) -add_library (mongo::mlib ALIAS _mongo-mlib) -list (APPEND MLIB_DEFINITIONS MLIB_USER) +add_library (_mongo-mc-mlib INTERFACE) +add_library (mongo::mc-mlib ALIAS _mongo-mc-mlib) +list (APPEND MCMLIB_DEFINITIONS MLIB_USER) CHECK_INCLUDE_FILE (strings.h HAVE_STRINGS_H) if (HAVE_STRINGS_H) - list (APPEND MLIB_DEFINITIONS MLIB_HAVE_STRINGS_H) + list (APPEND MCMLIB_DEFINITIONS MLIB_HAVE_STRINGS_H) endif () set_property( - TARGET _mongo-mlib + TARGET _mongo-mc-mlib APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS - ${MLIB_DEFINITIONS} + ${MCMLIB_DEFINITIONS} ) set_property( - TARGET _mongo-mlib + TARGET _mongo-mc-mlib APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$" ) @@ -271,7 +271,7 @@ target_link_libraries ( PRIVATE _mongocrypt::libbson_for_shared kms_message_static - $ + $ PUBLIC mongocrypt::platform ${maybe_dfp_library} @@ -327,7 +327,7 @@ target_link_libraries ( PRIVATE _mongocrypt::libbson_for_static kms_message_static - $ + $ PUBLIC mongocrypt::platform ${maybe_dfp_library} @@ -507,7 +507,7 @@ set (TEST_MONGOCRYPT_SOURCES add_executable (test-mongocrypt ${TEST_MONGOCRYPT_SOURCES}) # Use the static version since it allows the test binary to use private symbols target_include_directories (test-mongocrypt PRIVATE ./src "${CMAKE_CURRENT_SOURCE_DIR}/kms-message/src") -target_link_libraries (test-mongocrypt PRIVATE _mongocrypt::libbson_for_static mongocrypt_static mongo::mlib) +target_link_libraries (test-mongocrypt PRIVATE _mongocrypt::libbson_for_static mongocrypt_static mongo::mc-mlib) target_include_directories (test-mongocrypt PRIVATE "${CMAKE_CURRENT_LIST_DIR}/test") target_compile_definitions (test-mongocrypt PRIVATE # Set a definition so that testcases can know where test-mongocrypt.exe was written to @@ -525,9 +525,9 @@ add_test ( ) foreach (test IN ITEMS path str) - add_executable (mlib.${test}.test src/mlib/${test}.test.c) + add_executable (mlib.${test}.test src/mc-mlib/${test}.test.c) add_test (mlib.${test} mlib.${test}.test) - target_link_libraries (mlib.${test}.test PRIVATE mongo::mlib) + target_link_libraries (mlib.${test}.test PRIVATE mongo::mc-mlib) endforeach () if ("cxx_relaxed_constexpr" IN_LIST CMAKE_CXX_COMPILE_FEATURES) @@ -545,7 +545,7 @@ if ("cxx_relaxed_constexpr" IN_LIST CMAKE_CXX_COMPILE_FEATURES) target_compile_features ("${exe_name}" PRIVATE cxx_relaxed_constexpr) target_link_libraries ("${exe_name}" PRIVATE mongocrypt - mongo::mlib + mongo::mc-mlib ${maybe_dfp_library} _mongocrypt::libbson_for_static ) @@ -555,7 +555,7 @@ endif () if ("cxx_std_20" IN_LIST CMAKE_CXX_COMPILE_FEATURES) add_executable (csfle-markup src/csfle-markup.cpp) - target_link_libraries (csfle-markup PRIVATE mongocrypt_static _mongocrypt::libbson_for_static mongo::mlib) + target_link_libraries (csfle-markup PRIVATE mongocrypt_static _mongocrypt::libbson_for_static mongo::mc-mlib) target_compile_features (csfle-markup PRIVATE cxx_std_20) endif () @@ -606,8 +606,8 @@ install ( INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) -# This export set is not installed, and is only to allow export() of the mlib-using targets -install (TARGETS _mongo-mlib EXPORT _exports_for_export) +# This export set is not installed, and is only to allow export() of the mc-mlib-using targets +install (TARGETS _mongo-mc-mlib EXPORT _exports_for_export) export (EXPORT _exports_for_export) install ( diff --git a/src/mc-dec128.h b/src/mc-dec128.h index 0a6e7a29f..584e23ab3 100644 --- a/src/mc-dec128.h +++ b/src/mc-dec128.h @@ -3,9 +3,9 @@ #include -#include -#include -#include +#include +#include +#include // Conditional preprocessor definition set by the usage of an intel_dfp from // the ImportDFP.cmake script: diff --git a/src/mc-dec128.test.cpp b/src/mc-dec128.test.cpp index fa1d11c2d..a34e970ff 100644 --- a/src/mc-dec128.test.cpp +++ b/src/mc-dec128.test.cpp @@ -6,7 +6,7 @@ #include -#include +#include #define CHECK MLIB_CHECK inline std::ostream &operator<<(std::ostream &out, mc_dec128 d) noexcept { diff --git a/src/mc-efc.c b/src/mc-efc.c index 28f25ffdf..a5e25db98 100644 --- a/src/mc-efc.c +++ b/src/mc-efc.c @@ -16,7 +16,7 @@ #include "mc-efc-private.h" -#include "mlib/str.h" +#include "mc-mlib/str.h" #include "mongocrypt-private.h" #include "mongocrypt-util-private.h" // mc_iter_document_as_bson #include diff --git a/src/mc-fle2-rfds.c b/src/mc-fle2-rfds.c index 14fb07d29..279712639 100644 --- a/src/mc-fle2-rfds.c +++ b/src/mc-fle2-rfds.c @@ -20,8 +20,8 @@ #include "mc-fle-blob-subtype-private.h" // MC_SUBTYPE_FLE2EncryptionPlaceholder #include "mongocrypt-private.h" // CLIENT_ERR -#include "mlib/thread.h" // mlib_once_flag -#include // INFINITY +#include "mc-mlib/thread.h" // mlib_once_flag +#include // INFINITY static mc_FLE2RangeOperator_t get_operator_type(const char *key) { BSON_ASSERT_PARAM(key); diff --git a/src/mlib/check.hpp b/src/mc-mlib/check.hpp similarity index 100% rename from src/mlib/check.hpp rename to src/mc-mlib/check.hpp diff --git a/src/mlib/endian.h b/src/mc-mlib/endian.h similarity index 100% rename from src/mlib/endian.h rename to src/mc-mlib/endian.h diff --git a/src/mlib/error.h b/src/mc-mlib/error.h similarity index 100% rename from src/mlib/error.h rename to src/mc-mlib/error.h diff --git a/src/mlib/int128.h b/src/mc-mlib/int128.h similarity index 100% rename from src/mlib/int128.h rename to src/mc-mlib/int128.h diff --git a/src/mlib/int128.test.c b/src/mc-mlib/int128.test.c similarity index 100% rename from src/mlib/int128.test.c rename to src/mc-mlib/int128.test.c diff --git a/src/mlib/int128.test.cpp b/src/mc-mlib/int128.test.cpp similarity index 100% rename from src/mlib/int128.test.cpp rename to src/mc-mlib/int128.test.cpp diff --git a/src/mlib/macros.h b/src/mc-mlib/macros.h similarity index 100% rename from src/mlib/macros.h rename to src/mc-mlib/macros.h diff --git a/src/mlib/path.h b/src/mc-mlib/path.h similarity index 100% rename from src/mlib/path.h rename to src/mc-mlib/path.h diff --git a/src/mlib/path.test.c b/src/mc-mlib/path.test.c similarity index 100% rename from src/mlib/path.test.c rename to src/mc-mlib/path.test.c diff --git a/src/mlib/str.h b/src/mc-mlib/str.h similarity index 100% rename from src/mlib/str.h rename to src/mc-mlib/str.h diff --git a/src/mlib/str.test.c b/src/mc-mlib/str.test.c similarity index 100% rename from src/mlib/str.test.c rename to src/mc-mlib/str.test.c diff --git a/src/mlib/thread.h b/src/mc-mlib/thread.h similarity index 100% rename from src/mlib/thread.h rename to src/mc-mlib/thread.h diff --git a/src/mlib/user-check.h b/src/mc-mlib/user-check.h similarity index 100% rename from src/mlib/user-check.h rename to src/mc-mlib/user-check.h diff --git a/src/mlib/windows-lean.h b/src/mc-mlib/windows-lean.h similarity index 85% rename from src/mlib/windows-lean.h rename to src/mc-mlib/windows-lean.h index 7c0682650..d26ee781d 100644 --- a/src/mlib/windows-lean.h +++ b/src/mc-mlib/windows-lean.h @@ -7,7 +7,7 @@ #ifdef __has_include #if !__has_include() -#error " is only available when in available." +#error " is only available when in available." #endif #endif diff --git a/src/mc-optional-private.h b/src/mc-optional-private.h index 5d7f411b7..4a5578e57 100644 --- a/src/mc-optional-private.h +++ b/src/mc-optional-private.h @@ -21,7 +21,7 @@ #include #include "./mc-dec128.h" -#include "./mlib/int128.h" +#include "./mc-mlib/int128.h" typedef struct { bool set; diff --git a/src/mc-range-edge-generation-private.h b/src/mc-range-edge-generation-private.h index 303b7ffa0..8e146efc4 100644 --- a/src/mc-range-edge-generation-private.h +++ b/src/mc-range-edge-generation-private.h @@ -20,7 +20,7 @@ #include "mc-dec128.h" #include "mc-optional-private.h" #include "mongocrypt-status-private.h" -#include +#include #include // size_t #include diff --git a/src/mc-range-encoding-private.h b/src/mc-range-encoding-private.h index 8c2832c3a..2da3f0a77 100644 --- a/src/mc-range-encoding-private.h +++ b/src/mc-range-encoding-private.h @@ -21,7 +21,7 @@ #include "mc-optional-private.h" #include "mongocrypt-status-private.h" -#include +#include #include diff --git a/src/mongocrypt-ctx.c b/src/mongocrypt-ctx.c index 8853933f2..15f4f372d 100644 --- a/src/mongocrypt-ctx.c +++ b/src/mongocrypt-ctx.c @@ -16,8 +16,8 @@ #include +#include "mc-mlib/str.h" #include "mc-textopts-private.h" -#include "mlib/str.h" #include "mongocrypt-binary-private.h" #include "mongocrypt-ctx-private.h" #include "mongocrypt-key-broker-private.h" diff --git a/src/mongocrypt-dll-private.h b/src/mongocrypt-dll-private.h index 7560b3f68..fdbde02d0 100644 --- a/src/mongocrypt-dll-private.h +++ b/src/mongocrypt-dll-private.h @@ -1,8 +1,8 @@ #ifndef MONGOCRYPT_DLL_PRIVATE_H #define MONGOCRYPT_DLL_PRIVATE_H -#include -#include +#include +#include #include diff --git a/src/mongocrypt-opts-private.h b/src/mongocrypt-opts-private.h index 2c46f4c50..5b2cc29f1 100644 --- a/src/mongocrypt-opts-private.h +++ b/src/mongocrypt-opts-private.h @@ -19,7 +19,7 @@ #include -#include "mlib/str.h" +#include "mc-mlib/str.h" #include "mongocrypt-buffer-private.h" #include "mongocrypt-endpoint-private.h" diff --git a/src/mongocrypt-private.h b/src/mongocrypt-private.h index 4959229a4..fc161a672 100644 --- a/src/mongocrypt-private.h +++ b/src/mongocrypt-private.h @@ -33,7 +33,7 @@ #include "mongo_crypt-v1.h" -#include +#include #define MONGOCRYPT_GENERIC_ERROR_CODE 1 diff --git a/src/mongocrypt-util-private.h b/src/mongocrypt-util-private.h index 7965690d1..8086e7274 100644 --- a/src/mongocrypt-util-private.h +++ b/src/mongocrypt-util-private.h @@ -19,7 +19,7 @@ #include "mongocrypt-status-private.h" -#include "mlib/str.h" +#include "mc-mlib/str.h" #include diff --git a/src/mongocrypt-util.c b/src/mongocrypt-util.c index 880eea0aa..53cf429ef 100644 --- a/src/mongocrypt-util.c +++ b/src/mongocrypt-util.c @@ -37,7 +37,7 @@ #include "mongocrypt-private.h" // CLIENT_ERR #include "mongocrypt-util-private.h" -#include "mlib/thread.h" +#include "mc-mlib/thread.h" #include #include // isinf, isnan, isfinite diff --git a/src/mongocrypt.c b/src/mongocrypt.c index 42379d16b..93fafbbd0 100644 --- a/src/mongocrypt.c +++ b/src/mongocrypt.c @@ -15,9 +15,9 @@ */ #include "mongocrypt.h" -#include "mlib/error.h" -#include "mlib/path.h" -#include "mlib/thread.h" +#include "mc-mlib/error.h" +#include "mc-mlib/path.h" +#include "mc-mlib/thread.h" #include #include diff --git a/src/os_win/os_dll.c b/src/os_win/os_dll.c index 6e9c91691..f82700eee 100644 --- a/src/os_win/os_dll.c +++ b/src/os_win/os_dll.c @@ -2,9 +2,9 @@ #ifdef _WIN32 -#include -#include -#include +#include +#include +#include #include #include diff --git a/test/test-mongocrypt-assert-match-bson.c b/test/test-mongocrypt-assert-match-bson.c index c4b342064..d1c8ec46b 100644 --- a/test/test-mongocrypt-assert-match-bson.c +++ b/test/test-mongocrypt-assert-match-bson.c @@ -17,7 +17,7 @@ #include "test-mongocrypt-assert-match-bson.h" #include "test-mongocrypt-assert.h" -#include +#include /* string comparison functions for Windows */ #ifdef _WIN32 diff --git a/test/test-mongocrypt-dll.c b/test/test-mongocrypt-dll.c index 2cfc889a9..bb698a865 100644 --- a/test/test-mongocrypt-dll.c +++ b/test/test-mongocrypt-dll.c @@ -2,7 +2,7 @@ #include "mongocrypt-dll-private.h" -#include +#include #include "test-mongocrypt.h"