From 063d59922bcaf63e4b23fa42f8c22d6d9a555204 Mon Sep 17 00:00:00 2001 From: Steve Underwood Date: Sat, 26 Jan 2013 01:31:38 +0800 Subject: [PATCH] Properly enforce the far end max datagram when constructing UDPTL packets --- src/mod/applications/mod_spandsp/udptl.c | 31 +++++++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/mod/applications/mod_spandsp/udptl.c b/src/mod/applications/mod_spandsp/udptl.c index cde248c3d9..94a31e6772 100644 --- a/src/mod/applications/mod_spandsp/udptl.c +++ b/src/mod/applications/mod_spandsp/udptl.c @@ -349,6 +349,8 @@ int udptl_build_packet(udptl_state_t *s, uint8_t buf[], const uint8_t msg[], int 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. */ @@ -392,15 +394,26 @@ int udptl_build_packet(udptl_state_t *s, uint8_t buf[], const uint8_t msg[], int 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: @@ -417,11 +430,13 @@ int udptl_build_packet(udptl_state_t *s, uint8_t buf[], const uint8_t msg[], int /* 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; @@ -439,6 +454,14 @@ int udptl_build_packet(udptl_state_t *s, uint8_t buf[], const uint8_t msg[], int } 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; }