int len;
int limit;
int high_tide;
+ int len_before_entries;
+ int previous_len;
/* UDPTL cannot cope with zero length messages, and our buffering for redundancy limits their
maximum length. */
entries = s->error_correction_entries;
else
entries = s->tx_seq_no;
+ len_before_entries = len;
/* The number of entries will always be small, so it is pointless allowing
for the fragmented case here. */
if (encode_length(buf, &len, entries) < 0)
return -1;
/* Encode the elements */
- for (i = 0; i < entries; i++) {
- j = (entry - i - 1) & UDPTL_BUF_MASK;
+ for (m = 0; m < entries; m++) {
+ previous_len = len;
+ j = (entry - m - 1) & UDPTL_BUF_MASK;
if (encode_open_type(buf, &len, s->tx[j].buf, s->tx[j].buf_len) < 0)
return -1;
+
+ /* If we have exceeded the far end's max datagram size, don't include this last chunk,
+ and stop trying to add more. */
+ if (len > s->far_max_datagram_size) {
+ len = previous_len;
+ if (encode_length(buf, &len_before_entries, m) < 0)
+ return -1;
+ break;
+ }
}
break;
case UDPTL_ERROR_CORRECTION_FEC:
/* Span is defined as an inconstrained integer, which it dumb. It will only
ever be a small value. Treat it as such. */
buf[len++] = 1;
- buf[len++] = (uint8_t)span;
+ buf[len++] = (uint8_t) span;
+ len_before_entries = len;
/* The number of entries is defined as a length, but will only ever be a small
value. Treat it as such. */
- buf[len++] = (uint8_t)entries;
+ buf[len++] = (uint8_t) entries;
for (m = 0; m < entries; m++) {
+ previous_len = len;
/* Make an XOR'ed entry the maximum length */
limit = (entry + m) & UDPTL_BUF_MASK;
high_tide = 0;
}
if (encode_open_type(buf, &len, fec, high_tide) < 0)
return -1;
+
+ /* If we have exceeded the far end's max datagram size, don't include this last chunk,
+ and stop trying to add more. */
+ if (len > s->far_max_datagram_size) {
+ len = previous_len;
+ buf[len_before_entries] = (uint8_t) m;
+ break;
+ }
}
break;
}