Refactor DTLS MTU logic

- wolfSSL_GetMaxRecordSize will now take additional cipher data into account
- The set MTU size is understood as the maximum size of a DTLS record. The WOLFSSL_MAX_MTU was adjusted to account for UDP/IP headers.
This commit is contained in:
Juliusz Sosinowicz
2021-04-02 10:44:45 +02:00
parent 021c22c038
commit c6077b6767
3 changed files with 26 additions and 33 deletions

View File

@ -17558,8 +17558,6 @@ int CreateOcspResponse(WOLFSSL* ssl, OcspRequest** ocspRequest,
#endif #endif
#endif /* !NO_WOLFSSL_SERVER */ #endif /* !NO_WOLFSSL_SERVER */
#if (!defined(WOLFSSL_NO_TLS12) && !defined(NO_CERTS)) \
|| (defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER))
static int cipherExtraData(WOLFSSL* ssl) static int cipherExtraData(WOLFSSL* ssl)
{ {
/* Cipher data that may be added by BuildMessage */ /* Cipher data that may be added by BuildMessage */
@ -17567,7 +17565,6 @@ static int cipherExtraData(WOLFSSL* ssl)
ssl->specs.aead_mac_size + ssl->specs.iv_size + ssl->specs.aead_mac_size + ssl->specs.iv_size +
ssl->specs.pad_size; ssl->specs.pad_size;
} }
#endif
#ifndef WOLFSSL_NO_TLS12 #ifndef WOLFSSL_NO_TLS12
@ -17631,16 +17628,6 @@ int SendCertificate(WOLFSSL* ssl)
maxFragment = MAX_RECORD_SIZE; maxFragment = MAX_RECORD_SIZE;
if (ssl->options.dtls) {
#ifdef WOLFSSL_DTLS
/* The 100 bytes is used to account for the UDP and IP headers.
It can also include the record padding and MAC if the
SendCertificate is called for a secure renegotiation. */
maxFragment = MAX_MTU - DTLS_RECORD_HEADER_SZ
- DTLS_HANDSHAKE_HEADER_SZ - 100;
#endif /* WOLFSSL_DTLS */
}
maxFragment = wolfSSL_GetMaxRecordSize(ssl, maxFragment); maxFragment = wolfSSL_GetMaxRecordSize(ssl, maxFragment);
while (length > 0 && ret == 0) { while (length > 0 && ret == 0) {
@ -18401,8 +18388,7 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
{ {
int sent = 0, /* plainText size */ int sent = 0, /* plainText size */
sendSz, sendSz,
ret, ret;
dtlsExtra = 0;
int groupMsgs = 0; int groupMsgs = 0;
if (ssl->error == WANT_WRITE if (ssl->error == WANT_WRITE
@ -18478,14 +18464,7 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
} }
} }
#ifdef WOLFSSL_DTLS
if (ssl->options.dtls) {
dtlsExtra = DTLS_RECORD_EXTRA;
}
#endif
for (;;) { for (;;) {
int len;
byte* out; byte* out;
byte* sendBuffer = (byte*)data + sent; /* may switch on comp */ byte* sendBuffer = (byte*)data + sent; /* may switch on comp */
int buffSz; /* may switch on comp */ int buffSz; /* may switch on comp */
@ -18496,19 +18475,21 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
if (sent == sz) break; if (sent == sz) break;
len = wolfSSL_GetMaxRecordSize(ssl, sz - sent); buffSz = wolfSSL_GetMaxRecordSize(ssl, sz - sent);
#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_DTLS_SIZE_CHECK) #if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_DTLS_SIZE_CHECK)
if (ssl->options.dtls && (len < sz - sent)) { if (ssl->options.dtls && (buffSz < sz - sent)) {
ssl->error = DTLS_SIZE_ERROR; ssl->error = DTLS_SIZE_ERROR;
WOLFSSL_ERROR(ssl->error); WOLFSSL_ERROR(ssl->error);
return ssl->error; return ssl->error;
} }
#endif #endif
buffSz = len; outputSz = buffSz + COMP_EXTRA + DTLS_RECORD_HEADER_SZ +
DTLS_HANDSHAKE_HEADER_SZ;
if (IsEncryptionOn(ssl, 1))
outputSz += cipherExtraData(ssl);
/* check for available size */ /* check for available size */
outputSz = len + COMP_EXTRA + dtlsExtra + MAX_MSG_EXTRA;
if ((ret = CheckAvailableSize(ssl, outputSz)) != 0) if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
return ssl->error = ret; return ssl->error = ret;
@ -18551,7 +18532,7 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
WOLFSSL_ERROR(ssl->error); WOLFSSL_ERROR(ssl->error);
/* store for next call if WANT_WRITE or user embedSend() that /* store for next call if WANT_WRITE or user embedSend() that
doesn't present like WANT_WRITE */ doesn't present like WANT_WRITE */
ssl->buffers.plainSz = len; ssl->buffers.plainSz = buffSz;
ssl->buffers.prevSent = sent; ssl->buffers.prevSent = sent;
if (ssl->error == SOCKET_ERROR_E && (ssl->options.connReset || if (ssl->error == SOCKET_ERROR_E && (ssl->options.connReset ||
ssl->options.isClosed)) { ssl->options.isClosed)) {
@ -18562,7 +18543,7 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
return ssl->error; return ssl->error;
} }
sent += len; sent += buffSz;
/* only one message per attempt */ /* only one message per attempt */
if (ssl->options.partialWrite == 1) { if (ssl->options.partialWrite == 1) {
@ -31643,10 +31624,21 @@ int wolfSSL_GetMaxRecordSize(WOLFSSL* ssl, int maxFragment)
if (maxFragment > MAX_UDP_SIZE) { if (maxFragment > MAX_UDP_SIZE) {
maxFragment = MAX_UDP_SIZE; maxFragment = MAX_UDP_SIZE;
} }
if (maxFragment > MAX_MTU - COMP_EXTRA - DTLS_RECORD_HEADER_SZ -
DTLS_HANDSHAKE_HEADER_SZ) {
maxFragment = MAX_MTU - COMP_EXTRA - DTLS_RECORD_HEADER_SZ -
DTLS_HANDSHAKE_HEADER_SZ;
}
#if defined(WOLFSSL_DTLS_MTU) #if defined(WOLFSSL_DTLS_MTU)
if (maxFragment > {
ssl->dtlsMtuSz - RECORD_HEADER_SZ - DTLS_RECORD_EXTRA) { int overheadSz = DTLS_RECORD_HEADER_SZ + DTLS_HANDSHAKE_HEADER_SZ +
maxFragment = ssl->dtlsMtuSz - RECORD_HEADER_SZ - DTLS_RECORD_EXTRA; COMP_EXTRA;
if (IsEncryptionOn(ssl, 1))
overheadSz += cipherExtraData(ssl);
if (maxFragment >
ssl->dtlsMtuSz - overheadSz) {
maxFragment = ssl->dtlsMtuSz - overheadSz;
}
} }
#endif #endif
} }

View File

@ -1157,7 +1157,8 @@ enum {
#endif /* WOLFSSL_MULTICAST */ #endif /* WOLFSSL_MULTICAST */
#ifndef WOLFSSL_MAX_MTU #ifndef WOLFSSL_MAX_MTU
#define WOLFSSL_MAX_MTU 1500 /* 1500 - 100 bytes to account for UDP and IP headers */
#define WOLFSSL_MAX_MTU 1400
#endif /* WOLFSSL_MAX_MTU */ #endif /* WOLFSSL_MAX_MTU */

View File

@ -565,7 +565,7 @@ static WC_INLINE int mygetopt(int argc, char** argv, const char* optstring)
char c; char c;
char* cp; char* cp;
/* Added sanity check becuase scan-build complains argv[myoptind] access /* Added sanity check because scan-build complains argv[myoptind] access
* results in a null pointer dereference. */ * results in a null pointer dereference. */
if (argv == NULL) { if (argv == NULL) {
myoptarg = NULL; myoptarg = NULL;