Skip to content

Commit 94205ff

Browse files
committed
dtls.c: refactor dtls_send_handshake_msg_hash()
* create a single handshake header when message is not fragmented * improve readability of code Change-Id: I825b84351acd315c311f5c22d9830421863e3bc8
1 parent 7b8358a commit 94205ff

1 file changed

Lines changed: 62 additions & 36 deletions

File tree

dtls.c

Lines changed: 62 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,8 @@ dtls_set_record_header(uint8 type, dtls_security_parameters_t *security,
502502
return buf + sizeof(uint16);
503503
}
504504

505+
enum seq_inc_t { DTLS_SEQ_NR_DONT_INCREASE, DTLS_SEQ_NR_INCREASE };
506+
505507
/**
506508
* Initializes \p buf as handshake header. The caller must ensure that \p
507509
* buf is capable of holding at least \c sizeof(dtls_handshake_header_t)
@@ -512,7 +514,7 @@ static inline uint8 *
512514
dtls_set_handshake_header(uint8 type, dtls_peer_t *peer,
513515
int length, int frag_offset,
514516
int frag_length, uint8 *buf,
515-
int seq_nr_inc) {
517+
enum seq_inc_t seq_nr_inc) {
516518

517519
dtls_int_to_uint8(buf, type);
518520
buf += sizeof(uint8);
@@ -525,7 +527,7 @@ dtls_set_handshake_header(uint8 type, dtls_peer_t *peer,
525527
dtls_int_to_uint16(buf, peer->handshake_params->hs_state.mseq_s);
526528

527529
/* increment handshake message sequence counter by 1 */
528-
if(seq_nr_inc) {
530+
if(seq_nr_inc == DTLS_SEQ_NR_INCREASE) {
529531
peer->handshake_params->hs_state.mseq_s++;
530532
}
531533
} else {
@@ -1481,66 +1483,90 @@ dtls_send_handshake_msg_hash(dtls_context_t *ctx,
14811483
uint8 *data, size_t data_length,
14821484
int add_hash)
14831485
{
1484-
int ret = 0;
1486+
int ret = 0, result;
14851487
int last_fragment = 0; /* indicates if the fragment being processed is the last one */
14861488
size_t remaining_data_length = data_length;
14871489

14881490
uint8 buf[DTLS_HS_LENGTH];
1489-
uint8 *end; /* a pointer used to calculate the amount of data written into buf */
1491+
uint8 *end = NULL; /* a pointer used to calculate the amount of data written into buf */
14901492
uint8 *data_array[2];
14911493
size_t data_len_array[2];
14921494
dtls_security_parameters_t *security = peer ? dtls_security_params(peer) : NULL;
14931495
const size_t fragment_size = DTLS_MAXIMUM_HANDSHAKE_FRAGMENT_SIZE;
14941496

1495-
do {
1496-
size_t i = 0;
1497+
last_fragment = (data_length <= fragment_size);
1498+
1499+
if (add_hash) {
1500+
/* Update hash values for Finished MAC. The hash value is
1501+
* calculated as if the data has been sent in a single
1502+
* fragment. Setting the end pointer != NULL indicates that buf
1503+
* already contains a handshake header for a single fragment. If
1504+
* there is only one fragment so send, the sequence number will be
1505+
* increased as indicated by inc. */
1506+
enum seq_inc_t inc = last_fragment ? DTLS_SEQ_NR_INCREASE : DTLS_SEQ_NR_DONT_INCREASE;
1507+
end = dtls_set_handshake_header(header_type, peer, data_length,
1508+
0, data_length, /* fragment offset and length */
1509+
buf, inc);
1510+
update_hs_hash(peer, buf, end - buf);
1511+
if (data)
1512+
update_hs_hash(peer, data, data_length);
14971513

1498-
last_fragment = (remaining_data_length <= fragment_size);
1514+
/* clear end pointer if message is fragmented. */
1515+
if (!last_fragment)
1516+
end = NULL;
1517+
}
1518+
1519+
do {
1520+
size_t data_array_len = 1;
1521+
size_t len = remaining_data_length; /* data length of current fragment */
14991522

15001523
dtls_debug("sending (fragmented) handshake, %zu bytes remaining\n", remaining_data_length);
15011524

1502-
// Create single fragment header for full data and hash it, see RFC6347 Section 4.2.6
1503-
// TODO: Do not create same header twice for non-fragmented packets
1504-
if (add_hash && remaining_data_length == data_length) {
1525+
/* Create fragment header, see RFC6347 Section 4.2.6. If end is
1526+
* set, the message is not fragmented and buf already contains the
1527+
* handshake header. */
1528+
if (!end) {
1529+
enum seq_inc_t inc;
1530+
1531+
if (last_fragment) {
1532+
inc = DTLS_SEQ_NR_INCREASE;
1533+
} else {
1534+
len = fragment_size;
1535+
inc = DTLS_SEQ_NR_DONT_INCREASE;
1536+
}
15051537
end = dtls_set_handshake_header(header_type, peer, data_length, data_length - remaining_data_length,
1506-
min(remaining_data_length, fragment_size),
1507-
buf, 0);
1508-
update_hs_hash(peer, buf, end - buf);
1538+
len, buf, inc);
15091539
}
1540+
data_array[0] = buf;
1541+
data_len_array[0] = end - buf;
15101542

1511-
end = dtls_set_handshake_header(header_type, peer, data_length, data_length - remaining_data_length,
1512-
min(remaining_data_length, fragment_size), buf, last_fragment);
1513-
1514-
data_array[i] = buf;
1515-
data_len_array[i] = end - buf;
1516-
i++;
1543+
end = NULL;
15171544

1545+
/* set data to send in this fragment */
15181546
if (data != NULL) {
1519-
// Hash full data while sending first fragment, see RFC6347 Section 4.2.6
1520-
if (add_hash && remaining_data_length == data_length) {
1521-
update_hs_hash(peer, data, data_length);
1522-
}
1523-
data_array[i] = data;
1524-
data_len_array[i] = (last_fragment ? remaining_data_length : fragment_size);
1525-
i++;
1547+
data_array[1] = data;
1548+
data_len_array[1] = len;
1549+
data_array_len = 2;
15261550
}
15271551
dtls_debug("send handshake packet of type: %s (%i)\n",
15281552
dtls_handshake_type_to_name(header_type), header_type);
15291553

15301554
dtls_debug("sending fragment: offset: %zu, length: %zu \n",
15311555
data_length-remaining_data_length, (last_fragment ? remaining_data_length : fragment_size));
15321556

1533-
// TODO: Treat send errors here
1534-
ret += dtls_send_multi(ctx, peer, security, session, DTLS_CT_HANDSHAKE,
1535-
data_array, data_len_array, i);
1536-
1537-
// If not in last fragment
1538-
if(last_fragment){
1539-
remaining_data_length = 0;
1540-
} else {
1541-
remaining_data_length -= fragment_size;
1542-
data += fragment_size;
1557+
result = dtls_send_multi(ctx, peer, security, session, DTLS_CT_HANDSHAKE,
1558+
data_array, data_len_array, data_array_len);
1559+
if (result < 0) {
1560+
dtls_debug("error %d from dtls_send_multi()\n", result);
1561+
return result;
15431562
}
1563+
ret += result;
1564+
1565+
/* update data pointer and length */
1566+
remaining_data_length -= len;
1567+
data += len;
1568+
1569+
last_fragment = (remaining_data_length <= fragment_size);
15441570
} while(remaining_data_length > 0);
15451571

15461572
return ret;

0 commit comments

Comments
 (0)