Skip to content

Commit 8267687

Browse files
committed
wip
1 parent df8d707 commit 8267687

4 files changed

Lines changed: 102 additions & 4 deletions

File tree

src/dtls13.c

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2706,9 +2706,28 @@ int Dtls13DoScheduledWork(WOLFSSL* ssl)
27062706
ret = wc_UnLockMutex(&ssl->dtls13Rtx.mutex);
27072707
#endif
27082708
if (sendAcks) {
2709-
ret = SendDtls13Ack(ssl);
2710-
if (ret != 0)
2711-
return ret;
2709+
#ifdef HAVE_WRITE_DUP
2710+
/* The read side cannot encrypt. Transfer the seenRecords list to the
2711+
* shared WriteDup struct so the write side sends the ACK instead. */
2712+
if (ssl->dupWrite && ssl->dupSide == READ_DUP_SIDE) {
2713+
if (wc_LockMutex(&ssl->dupWrite->dupMutex) == 0) {
2714+
struct Dtls13RecordNumber** tail =
2715+
(struct Dtls13RecordNumber**)&ssl->dupWrite->sendAckList;
2716+
while (*tail != NULL)
2717+
tail = &(*tail)->next;
2718+
*tail = ssl->dtls13Rtx.seenRecords;
2719+
ssl->dtls13Rtx.seenRecords = NULL;
2720+
ssl->dupWrite->sendAcks = 1;
2721+
wc_UnLockMutex(&ssl->dupWrite->dupMutex);
2722+
}
2723+
}
2724+
else
2725+
#endif /* HAVE_WRITE_DUP */
2726+
{
2727+
ret = SendDtls13Ack(ssl);
2728+
if (ret != 0)
2729+
return ret;
2730+
}
27122731
}
27132732

27142733
if (ssl->dtls13Rtx.retransmit) {

src/ssl.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,17 @@ void FreeWriteDup(WOLFSSL* ssl)
748748

749749
if (doFree) {
750750
WOLFSSL_MSG("Doing WriteDup full free, count to zero");
751+
#ifdef WOLFSSL_DTLS13
752+
/* Free any pending ACK list that was never consumed by the write side */
753+
{
754+
struct Dtls13RecordNumber* rn = ssl->dupWrite->sendAckList;
755+
while (rn != NULL) {
756+
struct Dtls13RecordNumber* next = rn->next;
757+
XFREE(rn, ssl->heap, DYNAMIC_TYPE_DTLS_MSG);
758+
rn = next;
759+
}
760+
}
761+
#endif
751762
wc_FreeMutex(&ssl->dupWrite->dupMutex);
752763
XFREE(ssl->dupWrite, ssl->heap, DYNAMIC_TYPE_WRITEDUP);
753764
}
@@ -2480,6 +2491,39 @@ static int wolfSSL_write_internal(WOLFSSL* ssl, const void* data, size_t sz)
24802491
ssl->error = dupErr;
24812492
return WOLFSSL_FATAL_ERROR;
24822493
}
2494+
2495+
#ifdef WOLFSSL_DTLS13
2496+
/* DTLS 1.3: the read side cannot encrypt, so it delegates ACK sending
2497+
* to the write side. Check if an ACK was requested and send it. */
2498+
if (ssl->dupWrite && ssl->dupSide == WRITE_DUP_SIDE &&
2499+
ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version)) {
2500+
byte ackNeeded = 0;
2501+
2502+
if (wc_LockMutex(&ssl->dupWrite->dupMutex) == 0) {
2503+
ackNeeded = ssl->dupWrite->sendAcks;
2504+
if (ackNeeded) {
2505+
/* Claim the seenRecords list from the shared struct and
2506+
* append to our own (write side always has an empty list). */
2507+
struct Dtls13RecordNumber** tail =
2508+
(struct Dtls13RecordNumber**)&ssl->dtls13Rtx.seenRecords;
2509+
while (*tail != NULL)
2510+
tail = &(*tail)->next;
2511+
*tail = ssl->dupWrite->sendAckList;
2512+
ssl->dupWrite->sendAckList = NULL;
2513+
ssl->dupWrite->sendAcks = 0;
2514+
}
2515+
wc_UnLockMutex(&ssl->dupWrite->dupMutex);
2516+
}
2517+
2518+
if (ackNeeded) {
2519+
ret = SendDtls13Ack(ssl);
2520+
if (ret != 0) {
2521+
ssl->error = ret;
2522+
return WOLFSSL_FATAL_ERROR;
2523+
}
2524+
}
2525+
}
2526+
#endif /* WOLFSSL_DTLS13 */
24832527
}
24842528
#endif
24852529

tests/api.c

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32012,7 +32012,7 @@ static int test_write_dup(void)
3201232012
{
3201332013
EXPECT_DECLS;
3201432014
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(HAVE_WRITE_DUP)
32015-
size_t i, j;
32015+
size_t i, j, k;
3201632016
char hiWorld[] = "dup message";
3201732017
char readData[sizeof(hiWorld) + 5];
3201832018
struct {
@@ -32132,6 +32132,35 @@ static int test_write_dup(void)
3213232132
WC_NO_ERR_TRACE(WRITE_DUP_READ_E));
3213332133
ExpectIntEQ(wolfSSL_read(ssl_c, readData, sizeof(readData)),
3213432134
sizeof(hiWorld));
32135+
#ifdef WOLFSSL_DTLS13
32136+
/* After ssl_c (read side) processes the post-handshake
32137+
* NewSessionTicket it must have delegated the ACK to the
32138+
* write side via the shared WriteDup struct. */
32139+
if (ssl_c != NULL && ssl_c->options.dtls &&
32140+
IsAtLeastTLSv1_3(ssl_c->version) &&
32141+
ssl_c->dupWrite != NULL)
32142+
ExpectIntEQ(ssl_c->dupWrite->sendAcks, 1);
32143+
#endif
32144+
32145+
for (k = 0; k < 10; k++) {
32146+
ExpectIntEQ(wolfSSL_write(ssl_c2, hiWorld, sizeof(hiWorld)),
32147+
sizeof(hiWorld));
32148+
ExpectIntEQ(wolfSSL_read(ssl_s, readData, sizeof(readData)),
32149+
sizeof(hiWorld));
32150+
#ifdef WOLFSSL_DTLS13
32151+
/* On the first iteration the write side must have sent the
32152+
* ACK for the NewSessionTicket. Once the server reads it,
32153+
* its retransmit list for the NST must be empty. */
32154+
if (k == 0 && ssl_s != NULL && ssl_c != NULL &&
32155+
ssl_c->options.dtls &&
32156+
IsAtLeastTLSv1_3(ssl_c->version))
32157+
ExpectNull(ssl_s->dtls13Rtx.rtxRecords);
32158+
#endif
32159+
ExpectIntEQ(wolfSSL_write(ssl_s, hiWorld, sizeof(hiWorld)),
32160+
sizeof(hiWorld));
32161+
ExpectIntEQ(wolfSSL_read(ssl_c, readData, sizeof(readData)),
32162+
sizeof(hiWorld));
32163+
}
3213532164

3213632165
if (EXPECT_SUCCESS())
3213732166
printf("ok\n");

wolfssl/internal.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5759,6 +5759,12 @@ typedef struct BuildMsgArgs {
57595759
wolfSSL_Mutex dupMutex; /* reference count mutex */
57605760
int dupCount; /* reference count */
57615761
int dupErr; /* under dupMutex, pass to other side */
5762+
#ifdef WOLFSSL_DTLS13
5763+
/* DTLS 1.3: read side cannot encrypt, so it passes ACK work to the
5764+
* write side. Protected by dupMutex. */
5765+
byte sendAcks;
5766+
struct Dtls13RecordNumber* sendAckList; /* ownership transferred */
5767+
#endif
57625768
} WriteDup;
57635769

57645770
WOLFSSL_LOCAL void FreeWriteDup(WOLFSSL* ssl);

0 commit comments

Comments
 (0)