Skip to content

Commit 01b1476

Browse files
committed
Track number of sequential bytes received.
This change also updates the algorithm used to send acknowledgments so that it uses the correct ranges as specified by the received-to-be-marked queue. Additionally, messager finalization states are now available. A program wishing to ensure that both the remote side and local side are happy with everything and ready to end a connection may implement a check like follows: while (!messager->my_final || !messager->their_final) /* Process more. */ Closes #2; closes #3.
1 parent b1a69b9 commit 01b1476

2 files changed

Lines changed: 42 additions & 39 deletions

File tree

include/messager.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ struct curvecpr_messager {
5858
unsigned char their_eof;
5959
unsigned char their_final;
6060

61+
crypto_uint64 their_contiguous_sent_bytes;
62+
6163
size_t their_total_bytes;
6264
};
6365

lib/messager.c

Lines changed: 40 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,6 @@
1919

2020
#define _STOP (_STOP_SUCCESS + _STOP_FAILURE)
2121

22-
static unsigned long long _acknowledgment_range_gap_sizes[] = {
23-
UINT32_MAX,
24-
UINT16_MAX,
25-
UINT16_MAX,
26-
UINT16_MAX,
27-
UINT16_MAX
28-
};
29-
3022
/* This is the wire format for a message. It's only used internally here. */
3123
struct _message {
3224
unsigned char id[4];
@@ -113,9 +105,14 @@ int curvecpr_messager_recv (struct curvecpr_messager *messager, const unsigned c
113105
/* Range 1. */
114106
start = 0;
115107
end = curvecpr_bytes_unpack_uint64(message->acknowledging_range_1_size);
116-
if (start - end > 0)
108+
if (start - end > 0) {
117109
cf->ops.sendmarkq_remove_range(messager, start, end);
118110

111+
/* If we're at EOF, see if we can move to a final state. */
112+
if (messager->my_eof && end >= messager->my_sent_bytes)
113+
messager->my_final = 1;
114+
}
115+
119116
/* Range 2. */
120117
start = end + (unsigned long long)curvecpr_bytes_unpack_uint32(message->acknowledging_range_12_gap);
121118
end = start + (unsigned long long)curvecpr_bytes_unpack_uint16(message->acknowledging_range_2_size);
@@ -232,7 +229,7 @@ static int _send_block (struct curvecpr_messager *messager, struct curvecpr_bloc
232229

233230
crypto_uint32 id = 0;
234231

235-
struct { unsigned char exists; unsigned long long start; unsigned long long end; } acknowledgment_ranges[6] = { { .exists = 0, .start = 0, .end = 0 } };
232+
struct { unsigned char exists; crypto_uint64 start; crypto_uint64 end; } acknowledgment_ranges[6] = { { .exists = 0, .start = 0, .end = 0 } };
236233

237234
/* NB: It is perfectly acceptable for block to be null in this function. */
238235

@@ -262,44 +259,40 @@ static int _send_block (struct curvecpr_messager *messager, struct curvecpr_bloc
262259
/* Write range acknowledgments. */
263260
{
264261
struct curvecpr_block *received_block = NULL;
265-
unsigned int received_block_num = 0;
266-
int i = 0;
262+
int block_num = 0, i = 0;
263+
264+
crypto_uint64 check = messager->their_contiguous_sent_bytes;
265+
unsigned long long maximum_gap = UINT32_MAX;
267266

268-
/* XXX: Should really figure out a better way to do this. */
269267
for (;;) {
270-
if (cf->ops.recvmarkq_get(messager, received_block_num++, &received_block))
271-
/* Less than 6 ranges to acknowledge! */
268+
if (cf->ops.recvmarkq_get(messager, block_num++, &received_block))
272269
break;
273270

274-
if (!acknowledgment_ranges[i].exists) {
275-
/* This basically only happens for the first block in the first range. */
271+
acknowledgment_ranges[i].exists = 1;
272+
273+
if (received_block->offset > check) {
274+
acknowledgment_ranges[i].end = check;
275+
276+
if (!(i < 5))
277+
/* Can't fit any more acknowledgments in this message. */
278+
break;
279+
else if (received_block->offset - check > maximum_gap)
280+
/* Gap is too large... need more packets! */
281+
break;
282+
283+
i++;
276284
acknowledgment_ranges[i].exists = 1;
277285
acknowledgment_ranges[i].start = received_block->offset;
278286
acknowledgment_ranges[i].end = received_block->offset + received_block->data_len;
279-
} else if (received_block->offset == acknowledgment_ranges[i].end) {
280-
/* Continuation of the previous block. Just add. */
281-
acknowledgment_ranges[i].end += received_block->data_len;
282-
} else if (i < 5) {
283-
/* Doesn't fit at all. */
284-
unsigned long long maximum_gap = _acknowledgment_range_gap_sizes[i];
285-
if (received_block->offset - acknowledgment_ranges[i].end > maximum_gap) {
286-
/* The gap is too large! We'll have to send another acknowledgment
287-
later. */
288-
break;
289-
} else if (received_block->data_len > UINT16_MAX) {
290-
/* Range size is too large! */
291-
break;
292-
} else {
293-
/* Add a new range. */
294-
++i;
295-
acknowledgment_ranges[i].exists = 1;
296-
acknowledgment_ranges[i].start = received_block->offset;
297-
acknowledgment_ranges[i].end = received_block->offset + received_block->data_len;
298-
}
287+
288+
maximum_gap = UINT16_MAX;
299289
} else {
300-
/* End of the line. We can't fit any more acknowledgments in. */
301-
break;
290+
crypto_uint64 received_block_end = received_block->offset + received_block->data_len;
291+
292+
acknowledgment_ranges[i].end = check > received_block_end ? check : received_block_end;
302293
}
294+
295+
check = acknowledgment_ranges[i].end;
303296
}
304297

305298
if (acknowledgment_ranges[0].exists) {
@@ -409,8 +402,16 @@ static int _send_block (struct curvecpr_messager *messager, struct curvecpr_bloc
409402

410403
for (i = 0; i < 6 && acknowledgment_ranges[i].exists; ++i)
411404
cf->ops.recvmarkq_move_range_to_recvq(messager, acknowledgment_ranges[i].start, acknowledgment_ranges[i].end);
405+
412406
}
413407

408+
if (acknowledgment_ranges[0].exists)
409+
messager->their_contiguous_sent_bytes = acknowledgment_ranges[0].end;
410+
411+
/* The remote side is in a final state if we've acknowledged their EOF. */
412+
if (messager->their_eof && messager->their_contiguous_sent_bytes >= messager->their_total_bytes)
413+
messager->their_final = 1;
414+
414415
/* Update the last sent time for timeout calcuations. */
415416
messager->my_sent_clock = messager->chicago.clock;
416417

0 commit comments

Comments
 (0)