}
-#define UPDATE_TIMER \
+#define UPDATE_TIMER { \
session->internals.dtls.actual_retrans_timeout_ms *= 2; \
- session->internals.dtls.actual_retrans_timeout_ms %= MAX_DTLS_TIMEOUT
+ session->internals.dtls.actual_retrans_timeout_ms %= MAX_DTLS_TIMEOUT; \
+ }
+
+#define RESET_TIMER \
+ session->internals.dtls.actual_retrans_timeout_ms = session->internals.dtls.retrans_timeout_ms
/* This function transmits the flight that has been previously
* buffered.
{
int ret;
uint8_t* buf = NULL;
+unsigned int timeout;
/* PREPARING -> SENDING state transition */
mbuffer_head_st *const send_buffer =
* non blocking way, check if it is time to retransmit or just
* return.
*/
-
if (session->internals.dtls.flight_init != 0 && session->internals.dtls.blocking == 0)
{
/* just in case previous run was interrupted */
ret = _gnutls_io_write_flush (session);
+ if (ret < 0)
+ {
+ gnutls_assert();
+ goto cleanup;
+ }
- if (session->internals.dtls.last_flight == 0)
+ if (session->internals.dtls.last_flight == 0 || !_dtls_is_async(session))
{
/* check for ACK */
ret = _gnutls_io_check_recv(session, 0);
{
/* if no retransmission is required yet just return
*/
- if (now-session->internals.dtls.handshake_start_time <
- session->internals.dtls.actual_retrans_timeout_ms/1000)
+ if (1000*(now-session->internals.dtls.handshake_start_time) <
+ session->internals.dtls.actual_retrans_timeout_ms)
{
session->internals.dtls.handshake_last_call = now;
goto nb_timeout;
do
{
- if (now-session->internals.dtls.handshake_start_time >= session->internals.dtls.total_timeout_ms/1000)
+ if (1000*(now-session->internals.dtls.handshake_start_time) >= session->internals.dtls.total_timeout_ms)
{
ret = gnutls_assert_val(GNUTLS_E_TIMEDOUT);
goto cleanup;
}
-
- if ((session->internals.dtls.flight_init == 0) ||
- (now - session->internals.dtls.last_retransmit > RETRANSMIT_WINDOW))
- {
- session->internals.dtls.last_retransmit = now;
- _gnutls_dtls_log ("DTLS[%p]: %sStart of flight transmission.\n", session, (session->internals.dtls.flight_init == 0)?"":"re-");
+ _gnutls_dtls_log ("DTLS[%p]: %sStart of flight transmission.\n", session, (session->internals.dtls.flight_init == 0)?"":"re-");
- for (cur = send_buffer->head;
- cur != NULL; cur = cur->next)
+ for (cur = send_buffer->head;
+ cur != NULL; cur = cur->next)
+ {
+ ret = transmit_message (session, cur, &buf);
+ if (ret < 0)
{
- ret = transmit_message (session, cur, &buf);
- if (ret < 0)
- {
- gnutls_assert();
- goto cleanup;
- }
-
- last_type = cur->htype;
+ gnutls_assert();
+ goto cleanup;
}
- if (buf != NULL)
- {
- gnutls_free(buf);
- buf = NULL;
- }
+ last_type = cur->htype;
+ }
- if (session->internals.dtls.flight_init == 0)
- {
- session->internals.dtls.flight_init = 1;
- session->internals.dtls.handshake_last_call = now;
- session->internals.dtls.actual_retrans_timeout_ms = session->internals.dtls.retrans_timeout_ms;
+ if (session->internals.dtls.flight_init == 0)
+ {
+ session->internals.dtls.flight_init = 1;
+ session->internals.dtls.handshake_last_call = now;
+ RESET_TIMER;
+ timeout = session->internals.dtls.actual_retrans_timeout_ms;
- if (last_type == GNUTLS_HANDSHAKE_FINISHED)
- {
- /* On the last flight we cannot ensure retransmission
- * from here. _dtls_wait_and_retransmit() is being called
- * by handshake.
- */
- session->internals.dtls.last_flight = 1;
- }
- else
- session->internals.dtls.last_flight = 0;
- }
+ if (last_type == GNUTLS_HANDSHAKE_FINISHED)
+ {
+ /* On the last flight we cannot ensure retransmission
+ * from here. _dtls_wait_and_retransmit() is being called
+ * by handshake.
+ */
+ session->internals.dtls.last_flight = 1;
+ }
+ else
+ session->internals.dtls.last_flight = 0;
+ }
+ else
+ {
+ timeout = session->internals.dtls.actual_retrans_timeout_ms;
+ UPDATE_TIMER;
}
ret = _gnutls_io_write_flush (session);
else /* all other messages -> implicit ack (receive of next flight) */
{
if (session->internals.dtls.blocking != 0)
- ret = _gnutls_io_check_recv(session, session->internals.dtls.actual_retrans_timeout_ms);
+ ret = _gnutls_io_check_recv(session, timeout);
else
{
ret = _gnutls_io_check_recv(session, 0);
if (ret == GNUTLS_E_TIMEDOUT)
{
- UPDATE_TIMER;
goto nb_timeout;
}
}
}
- UPDATE_TIMER;
now = gnutls_time (0);
} while(ret == GNUTLS_E_TIMEDOUT);
return ret;
nb_timeout:
+ if (buf != NULL)
+ gnutls_free(buf);
+
RETURN_DTLS_EAGAIN_OR_TIMEOUT(session);
}
else
ret = _gnutls_io_check_recv(session, 0);
- UPDATE_TIMER;
-
if (ret == GNUTLS_E_TIMEDOUT)
{
ret = _dtls_retransmit(session);
{
RETURN_DTLS_EAGAIN_OR_TIMEOUT(session);
}
+ else
+ return gnutls_assert_val(ret);
}
return 0;
if (diff >= window_size)
{
/* Probably an epoch change. Check if we can fit it */
- if (window_table[0] == 0)
+ if (window_table[0] == 0 || window_table[0]+1 == seq)
{
window_table[0] = seq;
return 0;
}
- for (i=0;i<window_size-1;i++)
- {
- if (seq == window_table[i])
- return -1;
- if (seq == window_table[i] + 1)
- {
- if (seq == window_table[i+1])
- return -1;
- window_table[i+1] = seq;
- return 0;
- }
- }
- return -1;
- }
+ if ((window_size-2)/2 < 2)
+ return -1;
- offset = window_size-1-diff;
+ offset = 1 + seq % ((window_size-2)/2);
+ }
+ else
+ offset = window_size-1-diff;
if (window_table[offset] == seq)
return -1;
{
if (_gnutls_epoch_is_valid(session, record->epoch) == 0)
{
- _gnutls_audit_log(session, "Discarded message[%u] with invalid epoch 0x%.2x%.2x.\n",
- (unsigned int)_gnutls_uint64touint32 (&record->sequence), (int)record->sequence.i[0],
- (int)record->sequence.i[1]);
+ _gnutls_audit_log(session, "Discarded message[%u] with invalid epoch %u.\n",
+ (unsigned int)_gnutls_uint64touint32 (&record->sequence),
+ (unsigned int)record->sequence.i[0]*256+(unsigned int)record->sequence.i[1]);
gnutls_assert();
/* doesn't matter, just a fatal error */
return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
(unsigned int) _gnutls_uint64touint32 (packet_sequence), _gnutls_packet2str (record.type));
goto sanity_check_error;
}
+ _gnutls_record_log
+ ("REC[%p]: Decrypted Packet[%u.%u] %s(%d) with length: %d\n", session,
+ (unsigned int)record.sequence.i[0]*256 +(unsigned int)record.sequence.i[1],
+ (unsigned int) _gnutls_uint64touint32 (packet_sequence),
+ _gnutls_packet2str (record.type), record.type, (int)_mbuffer_get_udata_size(decrypted));
+ }
+ else
+ {
+ _gnutls_record_log
+ ("REC[%p]: Decrypted Packet[%u] %s(%d) with length: %d\n", session,
+ (unsigned int) _gnutls_uint64touint32 (packet_sequence),
+ _gnutls_packet2str (record.type), record.type, (int)_mbuffer_get_udata_size(decrypted));
}
-
- _gnutls_record_log
- ("REC[%p]: Decrypted Packet[%d] %s(%d) with length: %d\n", session,
- (int) _gnutls_uint64touint32 (packet_sequence),
- _gnutls_packet2str (record.type), record.type, (int)_mbuffer_get_udata_size(decrypted));
/* increase sequence number
*/