Skip to content

Commit 5ec08f0

Browse files
authored
MONGOCRYPT-749 Retry rewrapManyDataKey encrypt requests (#979)
1 parent 27452ca commit 5ec08f0

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

src/mongocrypt-ctx-rewrap-many-datakey.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,18 @@ static mongocrypt_kms_ctx_t *_next_kms_ctx_encrypt(mongocrypt_ctx_t *ctx) {
136136
mongocrypt_ctx_t *dkctx = NULL;
137137

138138
BSON_ASSERT_PARAM(ctx);
139+
/* Check if any need retry */
140+
{
141+
_mongocrypt_ctx_rmd_datakey_t *it = rmdctx->datakeys;
142+
while (it != NULL) {
143+
_mongocrypt_ctx_datakey_t *dkctx = (_mongocrypt_ctx_datakey_t *)it->dkctx;
144+
if (dkctx->kms.should_retry) {
145+
dkctx->kms.should_retry = false; // Reset retry state.
146+
return &dkctx->kms;
147+
}
148+
it = it->next;
149+
}
150+
}
139151

140152
/* No more datakey contexts requiring KMS. */
141153
if (!rmdctx->datakeys_iter) {

test/test-mongocrypt-ctx-rewrap-many-datakey.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,33 @@ static void _test_rewrap_many_datakey_need_kms_retry(_mongocrypt_tester_t *teste
570570
ASSERT(mongocrypt_kms_ctx_bytes_needed(kms) == 0);
571571
ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
572572
ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS); // To encrypt.
573+
mongocrypt_ctx_destroy(ctx);
574+
575+
/* Clear key cache. */
576+
mongocrypt_destroy(crypt);
577+
crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT);
578+
579+
/* Ensure KMS encrypt requests retry for network errors */
580+
ctx = mongocrypt_ctx_new(crypt);
581+
ASSERT_OK(mongocrypt_ctx_rewrap_many_datakey_init(ctx, filter), ctx);
582+
ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS);
583+
ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, TEST_FILE("./test/data/rmd/key-document-a.json")), ctx);
584+
ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx);
585+
ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS); // To decrypt.
586+
ASSERT((kms = mongocrypt_ctx_next_kms_ctx(ctx)));
587+
ASSERT_OK(mongocrypt_kms_ctx_feed(kms, TEST_FILE("./test/data/rmd/kms-decrypt-reply-a.txt")), kms);
588+
ASSERT(mongocrypt_kms_ctx_bytes_needed(kms) == 0);
589+
ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
590+
ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS); // To encrypt.
591+
ASSERT((kms = mongocrypt_ctx_next_kms_ctx(ctx)));
592+
ASSERT(mongocrypt_kms_ctx_fail(kms)); // Simulate driver-side network failure for an encrypt request.
593+
ASSERT((kms = mongocrypt_ctx_next_kms_ctx(ctx))); // Assert fails. Expected KMS request to retry but did not.
594+
ASSERT_OK(mongocrypt_kms_ctx_feed(kms, TEST_FILE("./test/data/rmd/kms-encrypt-reply-a.txt")), kms);
595+
ASSERT(mongocrypt_kms_ctx_bytes_needed(kms) == 0);
596+
ASSERT_OK(!mongocrypt_ctx_next_kms_ctx(ctx), ctx);
597+
ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
598+
ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
599+
573600
mongocrypt_ctx_destroy(ctx);
574601
mongocrypt_destroy(crypt);
575602
}

0 commit comments

Comments
 (0)