From: Nikos Mavrogiannopoulos Date: Sun, 20 Feb 2011 13:06:39 +0000 (+0100) Subject: Cleanups in combination of DTLS and TLS buffers. X-Git-Tag: gnutls_2_99_0~211 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9b385d3e93c6897744417a56da18086daedace56;p=thirdparty%2Fgnutls.git Cleanups in combination of DTLS and TLS buffers. --- diff --git a/lib/gnutls_buffers.c b/lib/gnutls_buffers.c index 9ba73c8c1f..5c6b17b0df 100644 --- a/lib/gnutls_buffers.c +++ b/lib/gnutls_buffers.c @@ -818,6 +818,7 @@ _gnutls_handshake_io_write_flush (gnutls_session_t session) &session->internals.handshake_send_buffer; gnutls_datum_t msg; int ret; + uint16_t epoch; ssize_t total = 0; mbuffer_st *cur; @@ -830,19 +831,24 @@ _gnutls_handshake_io_write_flush (gnutls_session_t session) for (cur = _mbuffer_get_first (send_buffer, &msg); cur != NULL; cur = _mbuffer_get_first (send_buffer, &msg)) { + epoch = cur->epoch; + ret = _gnutls_send_int (session, cur->type, cur->htype, - EPOCH_WRITE_CURRENT, + epoch, msg.data, msg.size, 0); if (ret >= 0) { - _mbuffer_remove_bytes (send_buffer, ret); + total += ret; + + ret = _mbuffer_remove_bytes (send_buffer, ret); + if (ret == 1) + _gnutls_epoch_refcount_dec(session, epoch); _gnutls_write_log ("HWRITE: wrote %d bytes, %d bytes left.\n", ret, (int) send_buffer->byte_length); - total += ret; } else { @@ -872,23 +878,14 @@ _gnutls_handshake_io_cache_int (gnutls_session_t session, if (IS_DTLS(session)) { - record_parameters_st * params; - int ret; - - ret = _gnutls_epoch_get( session, EPOCH_WRITE_CURRENT, ¶ms); - if (ret < 0) - return gnutls_assert_val(ret); - - bufel->epoch = params->epoch; - bufel->htype = htype; bufel->sequence = session->internals.dtls.hsk_write_seq-1; - - _gnutls_epoch_refcount_inc(params); } send_buffer = &session->internals.handshake_send_buffer; + bufel->epoch = (uint16_t)_gnutls_epoch_refcount_inc(session, EPOCH_WRITE_CURRENT); + bufel->htype = htype; if (bufel->htype == GNUTLS_HANDSHAKE_CHANGE_CIPHER_SPEC) bufel->type = GNUTLS_CHANGE_CIPHER_SPEC; diff --git a/lib/gnutls_constate.h b/lib/gnutls_constate.h index 9ec9f33b5c..65b609d24b 100644 --- a/lib/gnutls_constate.h +++ b/lib/gnutls_constate.h @@ -47,13 +47,29 @@ void _gnutls_epoch_gc (gnutls_session_t session); void _gnutls_epoch_free (gnutls_session_t session, record_parameters_st * state); -static inline void _gnutls_epoch_refcount_inc(record_parameters_st * params) +static inline int _gnutls_epoch_refcount_inc(gnutls_session_t session, int epoch) { + record_parameters_st * params; + int ret; + + ret = _gnutls_epoch_get( session, epoch, ¶ms); + if (ret < 0) + return ret; + params->usage_cnt++; + + return params->epoch; } -static inline int _gnutls_epoch_refcount_dec(record_parameters_st * params) +static inline int _gnutls_epoch_refcount_dec(gnutls_session_t session, uint16_t epoch) { + record_parameters_st * params; + int ret; + + ret = _gnutls_epoch_get( session, epoch, ¶ms); + if (ret < 0) + return ret; + params->usage_cnt--; if (params->usage_cnt < 0) return GNUTLS_E_INTERNAL_ERROR; diff --git a/lib/gnutls_dtls.c b/lib/gnutls_dtls.c index a57c67718c..a2004362ee 100644 --- a/lib/gnutls_dtls.c +++ b/lib/gnutls_dtls.c @@ -48,9 +48,9 @@ transmit_message (gnutls_session_t session, unsigned int offset, frag_len, data_size; const uint mtu = session->internals.dtls.mtu; - if (bufel->htype == GNUTLS_HANDSHAKE_CHANGE_CIPHER_SPEC) + if (bufel->type == GNUTLS_CHANGE_CIPHER_SPEC) { - return _gnutls_send_int (session, GNUTLS_CHANGE_CIPHER_SPEC, -1, + return _gnutls_send_int (session, bufel->type, -1, bufel->epoch, _mbuffer_get_uhead_ptr(bufel), _mbuffer_get_uhead_size(bufel), 0); @@ -102,7 +102,7 @@ transmit_message (gnutls_session_t session, * many records possible into a single datagram. We should also * tell the record layer which epoch to use for encryption. */ - ret = _gnutls_send_int (session, GNUTLS_HANDSHAKE, bufel->htype, + ret = _gnutls_send_int (session, bufel->type, bufel->htype, bufel->epoch, mtu_data, DTLS_HANDSHAKE_HEADER_SIZE + frag_len, 0); if (ret < 0) break; @@ -116,7 +116,6 @@ transmit_message (gnutls_session_t session, static int drop_usage_count(gnutls_session_t session) { int ret; - record_parameters_st * params; mbuffer_head_st *const send_buffer = &session->internals.handshake_send_buffer; mbuffer_st *cur; @@ -124,11 +123,7 @@ static int drop_usage_count(gnutls_session_t session) for (cur = send_buffer->head; cur != NULL; cur = cur->next) { - ret = _gnutls_epoch_get( session, cur->epoch, ¶ms); - if (ret < 0) - return gnutls_assert_val(ret); - - ret = _gnutls_epoch_refcount_dec(params); + ret = _gnutls_epoch_refcount_dec(session, cur->epoch); if (ret < 0) return gnutls_assert_val(ret); } diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c index 0547075ac5..5be063b81d 100644 --- a/lib/gnutls_handshake.c +++ b/lib/gnutls_handshake.c @@ -1226,10 +1226,10 @@ _gnutls_send_handshake (gnutls_session_t session, mbuffer_st * bufel, { _gnutls_handshake_hash_buffers_clear (session); if ((ret = _gnutls_handshake_hash_init (session)) < 0) - { - gnutls_assert (); - return ret; - } + { + gnutls_assert (); + return ret; + } } /* Here we keep the handshake messages in order to hash them... @@ -2115,9 +2115,9 @@ _gnutls_send_client_hello (gnutls_session_t session, int again) if (again == 0) { if(_gnutls_is_dtls(session)) - { - cookie_len = session->internals.dtls.cookie_len + 1; - } + { + cookie_len = session->internals.dtls.cookie_len + 1; + } else { cookie_len = 0; @@ -2185,15 +2185,15 @@ _gnutls_send_client_hello (gnutls_session_t session, int again) /* Generate random data */ if (!_gnutls_is_dtls (session) - || session->internals.dtls.hsk_hello_verify_requests == 0) - { - _gnutls_tls_create_random (rnd); - _gnutls_set_client_random (session, rnd); + || session->internals.dtls.hsk_hello_verify_requests == 0) + { + _gnutls_tls_create_random (rnd); + _gnutls_set_client_random (session, rnd); - memcpy (&data[pos], rnd, GNUTLS_RANDOM_SIZE); - } + memcpy (&data[pos], rnd, GNUTLS_RANDOM_SIZE); + } else - memcpy (&data[pos], session->security_parameters.client_random, GNUTLS_RANDOM_SIZE); + memcpy (&data[pos], session->security_parameters.client_random, GNUTLS_RANDOM_SIZE); pos += GNUTLS_RANDOM_SIZE; @@ -2212,11 +2212,11 @@ _gnutls_send_client_hello (gnutls_session_t session, int again) /* Copy the DTLS cookie */ if (_gnutls_is_dtls(session)) - { - data[pos++] = session->internals.dtls.cookie_len; - memcpy(&data[pos], &session->internals.dtls.cookie, session->internals.dtls.cookie_len); - pos += session->internals.dtls.cookie_len; - } + { + data[pos++] = session->internals.dtls.cookie_len; + memcpy(&data[pos], &session->internals.dtls.cookie, session->internals.dtls.cookie_len); + pos += session->internals.dtls.cookie_len; + } /* Copy the ciphersuites. * @@ -3007,13 +3007,6 @@ send_change_cipher_spec (gnutls_session_t session, int again) return gnutls_assert_val(ret); } - if (!IS_DTLS(session)) /* remove once combined */ - { - ret = _gnutls_handshake_io_write_flush (session); - if (ret < 0) - return gnutls_assert_val(ret); - } - _gnutls_handshake_log ("REC[%p]: Sent ChangeCipherSpec\n", session); } diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index bcc196b3bf..8093d9a9aa 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -639,6 +639,7 @@ typedef struct * protocol only. freed using _gnutls_handshake_io_buffer_clear(); */ mbuffer_head_st handshake_send_buffer; + content_type_t handshake_recv_buffer_type; gnutls_handshake_description_t handshake_recv_buffer_htype; gnutls_buffer_st handshake_recv_buffer; diff --git a/lib/gnutls_mbuffers.c b/lib/gnutls_mbuffers.c index a12f640790..b964771203 100644 --- a/lib/gnutls_mbuffers.c +++ b/lib/gnutls_mbuffers.c @@ -176,7 +176,8 @@ remove_front (mbuffer_head_st * buf) * * Useful for uses that treat the buffer as a simple array of bytes. * - * Returns 0 on success or an error code otherwise. + * If more than one mbuffer_st have been removed it + * returns 1, 0 otherwise and an error code on error. * * Cost: O(n) * n: Number of segments needed to remove the specified amount of data. @@ -186,6 +187,7 @@ _mbuffer_remove_bytes (mbuffer_head_st * buf, size_t bytes) { size_t left = bytes; mbuffer_st *bufel, *next; + int ret = 0; if (bytes > buf->byte_length) { @@ -201,6 +203,7 @@ _mbuffer_remove_bytes (mbuffer_head_st * buf, size_t bytes) { left -= (bufel->msg.size - bufel->mark); remove_front (buf); + ret = 1; } else {