&session->internals.handshake_send_buffer;
gnutls_datum_t msg;
int ret;
+ uint16_t epoch;
ssize_t total = 0;
mbuffer_st *cur;
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
{
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;
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;
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);
* 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;
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;
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);
}
{
_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...
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;
/* 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;
/* 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.
*
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);
}
* 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;
*
* 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.
{
size_t left = bytes;
mbuffer_st *bufel, *next;
+ int ret = 0;
if (bytes > buf->byte_length)
{
{
left -= (bufel->msg.size - bufel->mark);
remove_front (buf);
+ ret = 1;
}
else
{