]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Return a more precise mtu unit to applications.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 20 Feb 2011 11:11:54 +0000 (12:11 +0100)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 20 Feb 2011 11:11:54 +0000 (12:11 +0100)
lib/gnutls_algorithms.h
lib/gnutls_cipher.c
lib/gnutls_dtls.c
lib/gnutls_int.h
lib/gnutls_state.c
lib/gnutls_state.h

index 07cfd34e972861d6ad64b25bfeaf19387bcb55b5..38e70bc3857cba4de0c215906c72dfae1fbcddd1 100644 (file)
@@ -77,6 +77,8 @@ int _gnutls_cipher_algo_is_aead (gnutls_cipher_algorithm_t algorithm);
 int _gnutls_cipher_is_ok (gnutls_cipher_algorithm_t algorithm);
 int _gnutls_cipher_get_iv_size (gnutls_cipher_algorithm_t algorithm);
 int _gnutls_cipher_get_export_flag (gnutls_cipher_algorithm_t algorithm);
+/* at least for now iv_size == tag_size */
+#define _gnutls_cipher_get_tag_size _gnutls_cipher_get_iv_size
 
 /* Functions for key exchange. */
 int _gnutls_kx_needs_dh_params (gnutls_kx_algorithm_t algorithm);
index 0e4e0f362d54e0bef8dbd1a81945e1e8f959e798..5952813340bdbc73dc5969c4061871ab513d8039 100644 (file)
@@ -326,7 +326,14 @@ _gnutls_compressed2ciphertext (gnutls_session_t session,
   int ver = gnutls_protocol_get_version (session);
   int explicit_iv = _gnutls_version_has_explicit_iv (session->security_parameters.version);
   int auth_cipher = _gnutls_auth_cipher_is_aead(&params->write.cipher_state);
-  int random_pad = (session->internals.priorities.no_padding == 0) ? 1 : 0;
+  int random_pad;
+  
+  /* We don't use long padding if requested or if we are in DTLS.
+   */
+  if (session->internals.priorities.no_padding == 0 && (!IS_DTLS(session)))
+    random_pad = 1;
+  else
+    random_pad = 0;
   
   _gnutls_hard_log("ENC[%p]: cipher: %s, MAC: %s, Epoch: %u\n",
     session, gnutls_cipher_get_name(params->cipher_algorithm), gnutls_mac_get_name(params->mac_algorithm),
index 912f666df662cbdc7f125e72fa09564af1b508dd..a57c67718c2fcfcb84b85b594c71b5ecfde25fa2 100644 (file)
@@ -33,6 +33,7 @@
 #include <gnutls_mbuffers.h>
 #include <gnutls_buffers.h>
 #include <gnutls_constate.h>
+#include <gnutls_state.h>
 #include <gnutls/dtls.h>
 
 
@@ -262,5 +263,11 @@ void gnutls_dtls_set_mtu (gnutls_session_t session, unsigned int mtu)
  **/
 unsigned int gnutls_dtls_get_mtu (gnutls_session_t session)
 {
-  return session->internals.dtls.mtu - RECORD_HEADER_SIZE(session);
+int ret;
+
+  ret = _gnutls_record_overhead_rt(session);
+  if (ret >= 0)
+    return session->internals.dtls.mtu - ret;
+  else
+    return session->internals.dtls.mtu - RECORD_HEADER_SIZE(session);
 }
index bcd18c55b11d4af752d0c1d5ba586e9fb7d63e94..bcc196b3bfc8e13d8d2b99b6d63d9cd4c7cfdc74 100644 (file)
@@ -155,10 +155,11 @@ typedef enum transport_t
 #define MAX_RECORD_HEADER_SIZE DTLS_RECORD_HEADER_SIZE
 
 #define MAX_RECORD_SEND_SIZE(session) (IS_DTLS(session)?((size_t)session->internals.dtls.mtu-DTLS_RECORD_HEADER_SIZE):(size_t)session->security_parameters.max_record_send_size)
-#define MAX_RECORD_RECV_SIZE(session) (size_t)session->security_parameters.max_record_recv_size
+#define MAX_RECORD_RECV_SIZE(session) ((size_t)session->security_parameters.max_record_recv_size)
 #define MAX_PAD_SIZE 255
 #define EXTRA_COMP_SIZE 2048
-#define MAX_RECORD_OVERHEAD (MAX_CIPHER_BLOCK_SIZE/*iv*/+MAX_PAD_SIZE+EXTRA_COMP_SIZE)
+#define MAX_RECORD_OVERHEAD (MAX_CIPHER_BLOCK_SIZE/*iv*/+MAX_PAD_SIZE+EXTRA_COMP_SIZE+MAX_HASH_SIZE/*MAC*/)
+#define MAX_RECORD_OVERHEAD_RT(session) (2*MAX_CIPHER_BLOCK_SIZE/*iv+pad*/+MAX_HASH_SIZE)
 #define MAX_RECV_SIZE(session) (MAX_RECORD_OVERHEAD+MAX_RECORD_RECV_SIZE(session)+RECORD_HEADER_SIZE(session))
 
 #define TLS_HANDSHAKE_HEADER_SIZE 4
@@ -800,6 +801,7 @@ typedef struct
    */
   uint16_t srp_prime_bits;
 
+  /* A handshake process has been completed */
   int initial_negotiation_completed:1;
 
   struct
index 41eeb2da690b33d3aab0cf03b45bec41e9d9ef66..cffbb099d9df0e15186c5f7a4f1c2cd793e69d94 100644 (file)
@@ -1340,3 +1340,50 @@ gnutls_session_channel_binding (gnutls_session_t session,
 
   return 0;
 }
+
+/* returns overhead imposed by the record layer (encryption/compression)
+ * etc. It does include the record layer headers.
+ *
+ * It may return a negative value on error.
+ */
+int _gnutls_record_overhead_rt(gnutls_session_t session)
+{
+record_parameters_st *params;
+int total = 0, ret, iv_size;
+
+  if (session->internals.initial_negotiation_completed == 0)
+    return 0;
+
+  ret = _gnutls_epoch_get (session, EPOCH_WRITE_CURRENT, &params);
+  if (ret < 0)
+    return gnutls_assert_val(ret);
+
+  /* requires padding */
+  iv_size = _gnutls_cipher_get_iv_size(params->cipher_algorithm);
+  total += iv_size;
+
+  if (_gnutls_cipher_is_block (params->cipher_algorithm) == CIPHER_BLOCK)
+    {
+      if (!IS_DTLS(session))
+        total += MAX_PAD_SIZE;
+      else
+        total += iv_size; /* iv_size == block_size */
+    }
+  
+  if (params->mac_algorithm == GNUTLS_MAC_AEAD)
+    total += _gnutls_cipher_get_tag_size(params->cipher_algorithm);
+  else
+    {
+      ret = _gnutls_hmac_get_algo_len(params->mac_algorithm);
+      if (ret < 0)
+        return gnutls_assert_val(ret);
+      total+=ret;
+    }
+
+  if (params->compression_algorithm != GNUTLS_COMP_NULL)
+    total += EXTRA_COMP_SIZE;
+  
+  total += RECORD_HEADER_SIZE(session);
+  
+  return total;
+}
index 995b4a70d27cca30f0bea562060b4fbce19622bc..0035bb528a8d9aadabafe5cdda3f9b56ee62d196 100644 (file)
@@ -34,6 +34,8 @@ void
 _gnutls_record_set_default_version (gnutls_session_t session,
                                     unsigned char major, unsigned char minor);
 
+int _gnutls_record_overhead_rt(gnutls_session_t session);
+
 #include <gnutls_auth.h>
 
 #define CHECK_AUTH(auth, ret) if (gnutls_auth_get_type(session) != auth) { \