Browse Source

Make the `wolfSSL_GetMaxFragSize` parameter meaning consistent

- Add testing for sending as much app data as possible in a single DTLS record
Juliusz Sosinowicz 2 years ago
parent
commit
894303be59
5 changed files with 1150 additions and 45 deletions
  1. 1 1
      examples/client/client.c
  2. 8 8
      examples/server/server.c
  3. 21 32
      src/internal.c
  4. 1111 0
      tests/test-dtls-mtu.conf
  5. 9 4
      tests/unit.c

+ 1 - 1
examples/client/client.c

@@ -3184,7 +3184,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
                                       useLibOqs, oqsAlg, exitWithRet, version,
                                       onlyKeyShare);
         wolfSSL_CTX_free(ctx); ctx = NULL;
-        if (!exitWithRet)
+        if (((func_args*)args)->return_code != EXIT_SUCCESS && !exitWithRet)
             XEXIT_T(EXIT_SUCCESS);
         else
             goto exit;

+ 8 - 8
examples/server/server.c

@@ -395,7 +395,7 @@ int ServerEchoData(SSL* ssl, int clientfd, int echoData, int block,
             /* Read data */
             while (rx_pos < len) {
                 ret = SSL_read(ssl, &buffer[rx_pos], len - rx_pos);
-                if (ret < 0) {
+                if (ret <= 0) {
                     err = SSL_get_error(ssl, 0);
                 #ifdef WOLFSSL_ASYNC_CRYPT
                     if (err == WC_PENDING_E) {
@@ -3180,6 +3180,8 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
         }
         else if (err == 0 || err == WOLFSSL_ERROR_ZERO_RETURN) {
             err = ServerEchoData(ssl, clientfd, echoData, block, throughput);
+            if (err == WOLFSSL_ERROR_ZERO_RETURN) /* Got close notify */
+                err = 0;
             if (err != 0) {
                 SSL_free(ssl); ssl = NULL;
                 SSL_CTX_free(ctx); ctx = NULL;
@@ -3196,13 +3198,11 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
         Task_yield();
 #endif
 
-        if (dtlsUDP == 0) {
-            ret = SSL_shutdown(ssl);
-            if (wc_shutdown && ret == WOLFSSL_SHUTDOWN_NOT_DONE) {
-                ret = SSL_shutdown(ssl); /* bidirectional shutdown */
-                if (ret == WOLFSSL_SUCCESS)
-                    printf("Bidirectional shutdown complete\n");
-            }
+        ret = SSL_shutdown(ssl);
+        if (wc_shutdown && ret == WOLFSSL_SHUTDOWN_NOT_DONE) {
+            ret = SSL_shutdown(ssl); /* bidirectional shutdown */
+            if (ret == WOLFSSL_SUCCESS)
+                printf("Bidirectional shutdown complete\n");
         }
 
         /* display collected statistics */

+ 21 - 32
src/internal.c

@@ -19378,33 +19378,18 @@ int IsSCR(WOLFSSL* ssl)
 #ifdef WOLFSSL_DTLS
 static int ModifyForMTU(WOLFSSL* ssl, int buffSz, int outputSz, int mtuSz)
 {
-    int overflowSz = outputSz - mtuSz;
+    int recordExtra = outputSz - buffSz;
 
     (void)ssl;
 
-    if (overflowSz > 0) {
+    if (recordExtra > 0 && outputSz > mtuSz) {
+        buffSz = mtuSz - recordExtra;
 #ifndef WOLFSSL_AEAD_ONLY
-        if (ssl->specs.cipher_type == block) {
-            int overflowBlocks = (overflowSz / ssl->specs.block_size);
-
-            if (overflowSz % ssl->specs.block_size != 0)
-                overflowBlocks++;
-            buffSz -= ssl->specs.block_size * overflowBlocks;
-        }
-        else {
-            buffSz -= overflowSz;
-        }
-#else
-        buffSz -= overflowSz;
-#endif
-
-#ifdef WOLFSSL_DTLS
-        if (ssl->options.dtls)
-            buffSz -= DTLS_HANDSHAKE_HEADER_SZ;
-        else
+        /* Subtract a block size to be certain that returned fragment
+         * size won't get more padding. */
+        if (ssl->specs.cipher_type == block)
+            buffSz -= ssl->specs.block_size;
 #endif
-            buffSz -= HANDSHAKE_HEADER_SZ;
-
     }
 
     return buffSz;
@@ -19509,16 +19494,12 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
 
 #ifdef WOLFSSL_DTLS
         if (ssl->options.dtls) {
-            buffSz = wolfSSL_GetMaxFragSize(ssl, sz - sent +
-                    DTLS_HANDSHAKE_HEADER_SZ);
-            buffSz -= DTLS_HANDSHAKE_HEADER_SZ;
+            buffSz = wolfSSL_GetMaxFragSize(ssl, sz - sent);
         }
         else
 #endif
         {
-            buffSz = wolfSSL_GetMaxFragSize(ssl, sz - sent +
-                    HANDSHAKE_HEADER_SZ);
-            buffSz -= HANDSHAKE_HEADER_SZ;
+            buffSz = wolfSSL_GetMaxFragSize(ssl, sz - sent);
 
         }
 
@@ -32402,8 +32383,14 @@ int wolfSSL_AsyncPush(WOLFSSL* ssl, WC_ASYNC_DEV* asyncDev)
 #endif /* WOLFSSL_ASYNC_CRYPT */
 
 
-/* Return the max fragment size. This is essentially the maximum
- * fragment_length available. */
+/**
+ * Return the max fragment size. This is essentially the maximum
+ * fragment_length available.
+ * @param ssl         WOLFSSL object containing ciphersuite information.
+ * @param maxFragment The amount of space we want to check is available. This
+ *                    is only the fragment length WITHOUT the (D)TLS headers.
+ * @return            Max fragment size
+ */
 int wolfSSL_GetMaxFragSize(WOLFSSL* ssl, int maxFragment)
 {
     (void) ssl; /* Avoid compiler warnings */
@@ -32424,11 +32411,13 @@ int wolfSSL_GetMaxFragSize(WOLFSSL* ssl, int maxFragment)
         /* Given a input buffer size of maxFragment, how big will the
          * encrypted output be? */
         if (IsEncryptionOn(ssl, 1)) {
-            outputSz = BuildMessage(ssl, NULL, 0, NULL, maxFragment,
+            outputSz = BuildMessage(ssl, NULL, 0, NULL,
+                    maxFragment + DTLS_HANDSHAKE_HEADER_SZ,
                     application_data, 0, 1, 0, CUR_ORDER);
         }
         else {
-            outputSz = maxFragment + DTLS_RECORD_HEADER_SZ;
+            outputSz = maxFragment + DTLS_RECORD_HEADER_SZ +
+                    DTLS_HANDSHAKE_HEADER_SZ;
         }
 
         /* Readjust maxFragment for MTU size. */

File diff suppressed because it is too large
+ 1111 - 0
tests/test-dtls-mtu.conf


+ 9 - 4
tests/unit.c

@@ -122,11 +122,16 @@ int unit_test(int argc, char** argv)
     }
 #endif
 
-    ApiTest();
+#ifdef WOLFSSL_ALLOW_SKIP_UNIT_TESTS
+    if (argc == 1)
+#endif
+    {
+        ApiTest();
 
-    if ( (ret = HashTest()) != 0){
-        printf("hash test failed with %d\n", ret);
-        goto exit;
+        if ( (ret = HashTest()) != 0){
+            printf("hash test failed with %d\n", ret);
+            goto exit;
+        }
     }
 
 #ifndef NO_WOLFSSL_CIPHER_SUITE_TEST

Some files were not shown because too many files changed in this diff