From: Nikos Mavrogiannopoulos Date: Sun, 20 Feb 2011 09:38:33 +0000 (+0100) Subject: Combined DTLS buffers and normal TLS buffers. X-Git-Tag: gnutls_2_99_0~217 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3acdfac30e451bf8737f6c4774cbf212b6149c3b;p=thirdparty%2Fgnutls.git Combined DTLS buffers and normal TLS buffers. --- diff --git a/lib/gnutls_buffers.c b/lib/gnutls_buffers.c index 41b024488f..4df1d57154 100644 --- a/lib/gnutls_buffers.c +++ b/lib/gnutls_buffers.c @@ -57,7 +57,7 @@ #include #include #include - +#include /* gnutls_epoch_get */ #include #ifndef EAGAIN @@ -827,7 +827,6 @@ _gnutls_handshake_io_write_flush (gnutls_session_t session) if (IS_DTLS(session)) return _gnutls_dtls_transmit(session); - for (cur = _mbuffer_get_first (send_buffer, &msg); cur != NULL; cur = _mbuffer_get_first (send_buffer, &msg)) { @@ -870,9 +869,22 @@ _gnutls_handshake_io_cache_int (gnutls_session_t session, mbuffer_st * bufel) { mbuffer_head_st * send_buffer; - + if (IS_DTLS(session)) - return _gnutls_dtls_handshake_enqueue(session, bufel, htype, session->internals.dtls.hsk_write_seq-1); + { + 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; + + params->usage_cnt++; + } send_buffer = &session->internals.handshake_send_buffer; diff --git a/lib/gnutls_dtls.c b/lib/gnutls_dtls.c index fdb8479347..43ce1e824c 100644 --- a/lib/gnutls_dtls.c +++ b/lib/gnutls_dtls.c @@ -35,88 +35,44 @@ #include #include -/* This function is called once a handshake message is ready to be - * queued in the next outgoing flight. The actual transmission occurs - * in _gnutls_dtls_transmit. - * - * This function is called from the handshake layer. - */ -int -_gnutls_dtls_handshake_enqueue (gnutls_session_t session, - mbuffer_st* bufel, - gnutls_handshake_description_t type, - uint16_t sequence) -{ - dtls_hsk_retransmit_buffer *msg; - record_parameters_st * params; - int ret; - - ret = _gnutls_epoch_get( session, EPOCH_WRITE_CURRENT, ¶ms); - if (ret < 0) - return gnutls_assert_val(ret); - - msg = gnutls_malloc (sizeof(dtls_hsk_retransmit_buffer)); - if (msg == NULL) - return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); - - msg->bufel = bufel; - - msg->next = NULL; - - msg->epoch = params->epoch; - msg->type = type; - msg->sequence = sequence; - - params->usage_cnt++; - - _gnutls_dtls_log ("DTLS[%p]: Enqueued Packet[%u] %s(%d) with length: %u on epoch %d\n", - session, (uint)sequence, _gnutls_handshake2str (type), - type, msg->bufel->msg.size, msg->epoch); - - *(session->internals.dtls.retransmit_end) = msg; - session->internals.dtls.retransmit_end = &msg->next; - - return 0; -} /* This function fragments and transmits a previously buffered * outgoing message. */ static inline int transmit_message (gnutls_session_t session, - dtls_hsk_retransmit_buffer *msg) + mbuffer_st *bufel) { opaque *data, *mtu_data; int ret = 0; unsigned int offset, frag_len, data_size; const uint mtu = session->internals.dtls.hsk_mtu; - if (msg->type == GNUTLS_HANDSHAKE_CHANGE_CIPHER_SPEC) + if (bufel->htype == GNUTLS_HANDSHAKE_CHANGE_CIPHER_SPEC) { - ret = _gnutls_send_int (session, GNUTLS_CHANGE_CIPHER_SPEC, -1, - msg->epoch, - _mbuffer_get_uhead_ptr(msg->bufel), - _mbuffer_get_uhead_size(msg->bufel), 0); - goto leave_epoch; + return _gnutls_send_int (session, GNUTLS_CHANGE_CIPHER_SPEC, -1, + bufel->epoch, + _mbuffer_get_uhead_ptr(bufel), + _mbuffer_get_uhead_size(bufel), 0); } mtu_data = gnutls_malloc(mtu + DTLS_HANDSHAKE_HEADER_SIZE); if (mtu_data == NULL) return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); - data = _mbuffer_get_udata_ptr( msg->bufel); - data_size = _mbuffer_get_udata_size(msg->bufel); + data = _mbuffer_get_udata_ptr( bufel); + data_size = _mbuffer_get_udata_size(bufel); /* Write fixed headers */ /* Handshake type */ - mtu_data[0] = (uint8_t) msg->type; + mtu_data[0] = (uint8_t) bufel->htype; /* Total length */ _gnutls_write_uint24 (data_size, &mtu_data[1]); /* Handshake sequence */ - _gnutls_write_uint16 (msg->sequence, &mtu_data[4]); + _gnutls_write_uint16 (bufel->sequence, &mtu_data[4]); /* Chop up and send handshake message into mtu-size pieces. */ for (offset=0; offset <= data_size; offset += mtu) @@ -133,46 +89,48 @@ transmit_message (gnutls_session_t session, /* Fragment length */ _gnutls_write_uint24 (frag_len, &mtu_data[9]); - memcpy (&mtu_data[12], data+offset, frag_len); _gnutls_dtls_log ("DTLS[%p]: Sending Packet[%u] fragment %s(%d) with " "length: %u, offset: %u, fragment length: %u\n", - session, msg->sequence, - _gnutls_handshake2str (msg->type), - msg->type, data_size, offset, frag_len); + session, bufel->sequence, + _gnutls_handshake2str (bufel->htype), + bufel->htype, data_size, offset, frag_len); /* FIXME: We should collaborate with the record layer to pack as * 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, msg->type, msg->epoch, - mtu_data, DTLS_HANDSHAKE_HEADER_SIZE + frag_len, 0); + ret = _gnutls_send_int (session, GNUTLS_HANDSHAKE, bufel->htype, + bufel->epoch, mtu_data, DTLS_HANDSHAKE_HEADER_SIZE + frag_len, 0); if (ret < 0) break; } gnutls_free (mtu_data); -leave_epoch: return ret; } static int drop_usage_count(gnutls_session_t session) { - dtls_hsk_retransmit_buffer *msg; - record_parameters_st * params; int ret; + record_parameters_st * params; + mbuffer_head_st *const send_buffer = + &session->internals.handshake_send_buffer; + mbuffer_st *cur; - for (msg = session->internals.dtls.retransmit; msg != NULL; msg = msg->next) + for (cur = send_buffer->head; + cur != NULL; cur = cur->next) { - ret = _gnutls_epoch_get( session, msg->epoch, ¶ms); + ret = _gnutls_epoch_get( session, cur->epoch, ¶ms); if (ret < 0) return gnutls_assert_val(ret); params->usage_cnt--; if (params->usage_cnt < 0) return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); } + return 0; } @@ -188,7 +146,9 @@ _gnutls_dtls_transmit (gnutls_session_t session) int ret; /* PREPARING -> SENDING state transition */ - dtls_hsk_retransmit_buffer *msg; + mbuffer_head_st *const send_buffer = + &session->internals.handshake_send_buffer; + mbuffer_st *cur; unsigned int total_timeout = 0; gnutls_handshake_description_t last_type = 0; @@ -196,10 +156,11 @@ int ret; { _gnutls_dtls_log ("DTLS[%p]: Start of flight transmission.\n", session); - for (msg = session->internals.dtls.retransmit; msg != NULL; msg = msg->next) + for (cur = send_buffer->head; + cur != NULL; cur = cur->next) { - transmit_message (session, msg); - last_type = msg->type; + transmit_message (session, cur); + last_type = cur->htype; } ret = _gnutls_io_write_flush (session); @@ -207,8 +168,9 @@ int ret; return gnutls_assert_val(ret); /* last message in handshake -> no ack */ - if (session->security_parameters.entity == GNUTLS_SERVER && - last_type == GNUTLS_HANDSHAKE_FINISHED) + if (last_type == GNUTLS_HANDSHAKE_FINISHED && + ((session->security_parameters.entity == GNUTLS_SERVER && session->internals.resumed == RESUME_FALSE) || + (session->security_parameters.entity == GNUTLS_CLIENT && session->internals.resumed == RESUME_TRUE))) { opaque c; ret = _gnutls_io_check_recv(session, &c, 1, session->internals.dtls.retrans_timeout); @@ -244,33 +206,12 @@ int ret; cleanup: drop_usage_count(session); - _gnutls_dtls_clear_outgoing_buffer (session); + _mbuffer_clear(send_buffer); /* SENDING -> WAITING state transition */ return ret; } -/* This function clears the outgoing flight buffer. */ -void -_gnutls_dtls_clear_outgoing_buffer (gnutls_session_t session) -{ - dtls_hsk_retransmit_buffer *msg, *next; - - _gnutls_dtls_log ("DTLS[%p]: Clearing outgoing buffer.\n", session); - - for (msg = session->internals.dtls.retransmit; msg != NULL;) - { - next = msg->next; - - _mbuffer_xfree(&msg->bufel); - gnutls_free (msg); - - msg = next; - } - - session->internals.dtls.retransmit_end = &session->internals.dtls.retransmit; - session->internals.dtls.retransmit = NULL; -} /** * gnutls_dtls_set_timeouts: diff --git a/lib/gnutls_dtls.h b/lib/gnutls_dtls.h index 80958dd6f2..d3a4870bbb 100644 --- a/lib/gnutls_dtls.h +++ b/lib/gnutls_dtls.h @@ -27,13 +27,6 @@ #include "gnutls_int.h" -int -_gnutls_dtls_handshake_enqueue (gnutls_session_t session, - mbuffer_st* bufel, - gnutls_handshake_description_t type, - uint16_t sequence); - int _gnutls_dtls_transmit(gnutls_session_t session); -void _gnutls_dtls_clear_outgoing_buffer(gnutls_session_t session); #endif diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index d3da01d6ef..45bfbeb2ed 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -265,8 +265,15 @@ typedef struct mbuffer_st unsigned int user_mark; /* only used during fill in */ size_t maximum_size; - gnutls_handshake_description_t htype; + /* record layer content type */ content_type_t type; + + /* Record layer epoch of message */ + uint16_t epoch; + + /* Handshake layer type and sequence of message */ + gnutls_handshake_description_t htype; + uint16_t sequence; } mbuffer_st; typedef struct mbuffer_head_st @@ -278,25 +285,6 @@ typedef struct mbuffer_head_st size_t byte_length; } mbuffer_head_st; -/* This is a linked list used to buffer the next flight of outgoing - handshake messages. Messages are queued whole; they are fragmented - dynamically on transmit. */ -typedef struct dtls_hsk_retransmit_buffer -{ - struct dtls_hsk_retransmit_buffer *next; - - /* The actual handshake message */ - mbuffer_st* bufel; - - /* Record layer epoch of message */ - uint16_t epoch; - - /* Handshake layer type and sequence of message */ - gnutls_handshake_description_t type; - uint16_t sequence; -} dtls_hsk_retransmit_buffer; - - typedef enum { HANDSHAKE_MAC_TYPE_10 = 1, /* TLS 1.0 style */ @@ -568,10 +556,6 @@ typedef struct unsigned int retrans_timeout; unsigned int total_timeout; - /* Head of the next outgoing flight. */ - dtls_hsk_retransmit_buffer *retransmit; - dtls_hsk_retransmit_buffer **retransmit_end; - unsigned int hsk_hello_verify_requests; } dtls_st; diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c index ab2350e2cd..4ab2c09b94 100644 --- a/lib/gnutls_state.c +++ b/lib/gnutls_state.c @@ -405,9 +405,6 @@ gnutls_init_dtls (gnutls_session_t * session, (*session)->internals.dtls.hsk_mtu = DTLS_DEFAULT_MTU; (*session)->internals.transport = GNUTLS_DGRAM; - /* Initialize pointer used to enqueue messages for retransmit. */ - (*session)->internals.dtls.retransmit_end = &(*session)->internals.dtls.retransmit; - (*session)->internals.dtls.retrans_timeout = 1000; (*session)->internals.dtls.total_timeout = 4000;