diff options
Diffstat (limited to 'main/udptl.c')
-rw-r--r-- | main/udptl.c | 74 |
1 files changed, 51 insertions, 23 deletions
diff --git a/main/udptl.c b/main/udptl.c index 6c79490b1..2d192928f 100644 --- a/main/udptl.c +++ b/main/udptl.c @@ -86,7 +86,7 @@ static int udptlfecentries; static int udptlfecspan; static int udptlmaxdatagram; -#define LOCAL_FAX_MAX_DATAGRAM 400 +#define LOCAL_FAX_MAX_DATAGRAM 1400 #define MAX_FEC_ENTRIES 5 #define MAX_FEC_SPAN 5 @@ -159,7 +159,7 @@ struct ast_udptl { static AST_RWLIST_HEAD_STATIC(protos, ast_udptl_protocol); static int udptl_rx_packet(struct ast_udptl *s, uint8_t *buf, int len); -static int udptl_build_packet(struct ast_udptl *s, uint8_t *buf, uint8_t *ifp, int ifp_len); +static int udptl_build_packet(struct ast_udptl *s, uint8_t *buf, int buflen, uint8_t *ifp, int ifp_len); static inline int udptl_debug_test_addr(struct sockaddr_in *addr) { @@ -257,7 +257,7 @@ static int encode_length(uint8_t *buf, int *len, int value) } /*- End of function --------------------------------------------------------*/ -static int encode_open_type(uint8_t *buf, int *len, const uint8_t *data, int num_octets) +static int encode_open_type(uint8_t *buf, int buflen, int *len, const uint8_t *data, int num_octets) { int enclen; int octet_idx; @@ -273,6 +273,10 @@ static int encode_open_type(uint8_t *buf, int *len, const uint8_t *data, int num for (octet_idx = 0; ; num_octets -= enclen, octet_idx += enclen) { if ((enclen = encode_length(buf, len, num_octets)) < 0) return -1; + if (enclen + *len > buflen) { + ast_log(LOG_ERROR, "Buffer overflow detected (%d + %d > %d)\n", enclen, *len, buflen); + return -1; + } if (enclen > 0) { memcpy(&buf[*len], &data[octet_idx], enclen); *len += enclen; @@ -493,9 +497,9 @@ static int udptl_rx_packet(struct ast_udptl *s, uint8_t *buf, int len) } /*- End of function --------------------------------------------------------*/ -static int udptl_build_packet(struct ast_udptl *s, uint8_t *buf, uint8_t *ifp, int ifp_len) +static int udptl_build_packet(struct ast_udptl *s, uint8_t *buf, int buflen, uint8_t *ifp, int ifp_len) { - uint8_t fec[LOCAL_FAX_MAX_DATAGRAM]; + uint8_t fec[LOCAL_FAX_MAX_DATAGRAM * 2]; int i; int j; int seq; @@ -525,7 +529,7 @@ static int udptl_build_packet(struct ast_udptl *s, uint8_t *buf, uint8_t *ifp, i buf[len++] = seq & 0xFF; /* Encode the primary IFP packet */ - if (encode_open_type(buf, &len, ifp, ifp_len) < 0) + if (encode_open_type(buf, buflen, &len, ifp, ifp_len) < 0) return -1; /* Encode the appropriate type of error recovery information */ @@ -553,8 +557,12 @@ static int udptl_build_packet(struct ast_udptl *s, uint8_t *buf, uint8_t *ifp, i /* Encode the elements */ for (i = 0; i < entries; i++) { j = (entry - i - 1) & UDPTL_BUF_MASK; - if (encode_open_type(buf, &len, s->tx[j].buf, s->tx[j].buf_len) < 0) + if (encode_open_type(buf, buflen, &len, s->tx[j].buf, s->tx[j].buf_len) < 0) { + if (option_debug) { + ast_log(LOG_DEBUG, "Encoding failed at i=%d, j=%d\n", i, j); + } return -1; + } } break; case UDPTL_ERROR_CORRECTION_FEC: @@ -591,7 +599,7 @@ static int udptl_build_packet(struct ast_udptl *s, uint8_t *buf, uint8_t *ifp, i fec[j] ^= s->tx[i].buf[j]; } } - if (encode_open_type(buf, &len, fec, high_tide) < 0) + if (encode_open_type(buf, buflen, &len, fec, high_tide) < 0) return -1; } break; @@ -888,7 +896,7 @@ int ast_udptl_write(struct ast_udptl *s, struct ast_frame *f) int seq; int len; int res; - uint8_t buf[LOCAL_FAX_MAX_DATAGRAM]; + uint8_t buf[LOCAL_FAX_MAX_DATAGRAM * 2]; /* If we have no peer, return immediately */ if (s->them.sin_addr.s_addr == INADDR_ANY) @@ -907,7 +915,7 @@ int ast_udptl_write(struct ast_udptl *s, struct ast_frame *f) seq = s->tx_seq_no & 0xFFFF; /* Cook up the UDPTL packet, with the relevant EC info. */ - len = udptl_build_packet(s, buf, f->data.ptr, f->datalen); + len = udptl_build_packet(s, buf, sizeof(buf), f->data.ptr, f->datalen); if (len > 0 && s->them.sin_port && s->them.sin_addr.s_addr) { if ((res = sendto(s->fd, buf, len, 0, (struct sockaddr *) &s->them, sizeof(s->them))) < 0) @@ -1234,17 +1242,25 @@ static void __ast_udptl_reload(int reload) if (cfg) { if ((s = ast_variable_retrieve(cfg, "general", "udptlstart"))) { udptlstart = atoi(s); - if (udptlstart < 1024) + if (udptlstart < 1024) { + ast_log(LOG_WARNING, "Ports under 1024 are not allowed for T.38.\n"); udptlstart = 1024; - if (udptlstart > 65535) + } + if (udptlstart > 65535) { + ast_log(LOG_WARNING, "Ports over 65535 are invalid.\n"); udptlstart = 65535; + } } if ((s = ast_variable_retrieve(cfg, "general", "udptlend"))) { udptlend = atoi(s); - if (udptlend < 1024) + if (udptlend < 1024) { + ast_log(LOG_WARNING, "Ports under 1024 are not allowed for T.38.\n"); udptlend = 1024; - if (udptlend > 65535) + } + if (udptlend > 65535) { + ast_log(LOG_WARNING, "Ports over 65535 are invalid.\n"); udptlend = 65535; + } } if ((s = ast_variable_retrieve(cfg, "general", "udptlchecksums"))) { #ifdef SO_NO_CHECK @@ -1265,24 +1281,36 @@ static void __ast_udptl_reload(int reload) } if ((s = ast_variable_retrieve(cfg, "general", "T38FaxMaxDatagram"))) { udptlmaxdatagram = atoi(s); - if (udptlmaxdatagram < 0) - udptlmaxdatagram = 0; - if (udptlmaxdatagram > LOCAL_FAX_MAX_DATAGRAM) + if (udptlmaxdatagram < 100) { + ast_log(LOG_WARNING, "Too small T38FaxMaxDatagram size. Defaulting to 100.\n"); + udptlmaxdatagram = 100; + } + if (udptlmaxdatagram > LOCAL_FAX_MAX_DATAGRAM) { + ast_log(LOG_WARNING, "Too large T38FaxMaxDatagram size. Defaulting to %d.\n", LOCAL_FAX_MAX_DATAGRAM); udptlmaxdatagram = LOCAL_FAX_MAX_DATAGRAM; + } } if ((s = ast_variable_retrieve(cfg, "general", "UDPTLFECentries"))) { udptlfecentries = atoi(s); - if (udptlfecentries < 0) - udptlfecentries = 0; - if (udptlfecentries > MAX_FEC_ENTRIES) + if (udptlfecentries < 1) { + ast_log(LOG_WARNING, "Too small UDPTLFECentries value. Defaulting to 1.\n"); + udptlfecentries = 1; + } + if (udptlfecentries > MAX_FEC_ENTRIES) { + ast_log(LOG_WARNING, "Too large UDPTLFECentries value. Defaulting to %d.\n", MAX_FEC_ENTRIES); udptlfecentries = MAX_FEC_ENTRIES; + } } if ((s = ast_variable_retrieve(cfg, "general", "UDPTLFECspan"))) { udptlfecspan = atoi(s); - if (udptlfecspan < 0) - udptlfecspan = 0; - if (udptlfecspan > MAX_FEC_SPAN) + if (udptlfecspan < 1) { + ast_log(LOG_WARNING, "Too small UDPTLFECspan value. Defaulting to 1.\n"); + udptlfecspan = 1; + } + if (udptlfecspan > MAX_FEC_SPAN) { + ast_log(LOG_WARNING, "Too large UDPTLFECspan value. Defaulting to %d.\n", MAX_FEC_SPAN); udptlfecspan = MAX_FEC_SPAN; + } } ast_config_destroy(cfg); } |