From: Nikos Mavrogiannopoulos Date: Sun, 20 Feb 2011 11:11:54 +0000 (+0100) Subject: Return a more precise mtu unit to applications. X-Git-Tag: gnutls_2_99_0~213 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fc0fc2908cd58326e38f69120ae8a06fd569025a;p=thirdparty%2Fgnutls.git Return a more precise mtu unit to applications. --- diff --git a/lib/gnutls_algorithms.h b/lib/gnutls_algorithms.h index 07cfd34e97..38e70bc385 100644 --- a/lib/gnutls_algorithms.h +++ b/lib/gnutls_algorithms.h @@ -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); diff --git a/lib/gnutls_cipher.c b/lib/gnutls_cipher.c index 0e4e0f362d..5952813340 100644 --- a/lib/gnutls_cipher.c +++ b/lib/gnutls_cipher.c @@ -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(¶ms->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), diff --git a/lib/gnutls_dtls.c b/lib/gnutls_dtls.c index 912f666df6..a57c67718c 100644 --- a/lib/gnutls_dtls.c +++ b/lib/gnutls_dtls.c @@ -33,6 +33,7 @@ #include #include #include +#include #include @@ -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); } diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index bcd18c55b1..bcc196b3bf 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -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 diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c index 41eeb2da69..cffbb099d9 100644 --- a/lib/gnutls_state.c +++ b/lib/gnutls_state.c @@ -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, ¶ms); + 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; +} diff --git a/lib/gnutls_state.h b/lib/gnutls_state.h index 995b4a70d2..0035bb528a 100644 --- a/lib/gnutls_state.h +++ b/lib/gnutls_state.h @@ -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 #define CHECK_AUTH(auth, ret) if (gnutls_auth_get_type(session) != auth) { \