diff --git a/modules/dtls_gw/rtpp_dtls_conn.c b/modules/dtls_gw/rtpp_dtls_conn.c index 52400ca63..75d4eb65c 100644 --- a/modules/dtls_gw/rtpp_dtls_conn.c +++ b/modules/dtls_gw/rtpp_dtls_conn.c @@ -472,6 +472,11 @@ rtpp_dtls_conn_dtls_recv(struct rtpp_dtls_conn *self, #define SRTCP_PROTECT(a, b, c) srtp_protect_rtcp(a, b, c) #endif +/* libsrtp2 < 2.6.0 only documents it as SRTP_MAX_TRAILER_LEN+4 */ +#if !defined(SRTP_MAX_SRTCP_TRAILER_LEN) +#define SRTP_MAX_SRTCP_TRAILER_LEN (SRTP_MAX_TRAILER_LEN + 4) +#endif + static struct res_loc rtpp_dtls_conn_rtp_send(struct rtpp_dtls_conn *self, struct pkt_proc_ctx *pktxp) { @@ -489,6 +494,15 @@ rtpp_dtls_conn_rtp_send(struct rtpp_dtls_conn *self, struct pkt_proc_ctx *pktxp) return (RES_HERE(-1)); } + /* + * srtp_protect() and srtp_protect_rtcp() append the trailer in place, + * make sure it fits in data.buf (the SRTCP one is the larger of the two). + */ + if (pktxp->pktp->size > sizeof(pktxp->pktp->data.buf) - + SRTP_MAX_SRTCP_TRAILER_LEN) { + return (RES_HERE(-1)); + } + if (pktxp->flags & PPROC_FLAG_COW) { struct rtp_packet *p = rtp_packet_alloc(); if (p == NULL) diff --git a/tests/dtls_gw/basic b/tests/dtls_gw/basic index fc65adfea..bfc04242c 100755 --- a/tests/dtls_gw/basic +++ b/tests/dtls_gw/basic @@ -14,7 +14,7 @@ rm -f dtls_gw.?.rlog -D DSO="${TOP_BUILDDIR}/modules/dtls_gw/.libs/rtpp_dtls_gw_debug.so" \ -D RECORD_DIR="${RECORD_DIR}" -D RECORD_SPL_DIR="${RECORD_SPL_DIR}" \ -D SCENARIO="${RPTL_DIR}/examples/dtls.scenario.rptl" \ - -D PROMPT_NAME="${BUILDDIR}/dtls_gw.prompt" \ + -D PROMPT_NAME="${BUILDDIR}/dtls_gw.prompt" -D PYINT="${PYINT}" \ 2>&1 > dtls_gw.vars echo ${?} > dtls_gw.rptl.rc } | tee dtls_gw.rlog diff --git a/tests/dtls_gw/basic.rptl b/tests/dtls_gw/basic.rptl index a1778ad3a..d72ea72fa 100644 --- a/tests/dtls_gw/basic.rptl +++ b/tests/dtls_gw/basic.rptl @@ -13,6 +13,7 @@ socket fwd: stdio: %%RTPPROXY_ARGS%% -i -> dtls_gw.f.creplies socket geno: stdio: %%RTPPROXY_ARGS%% -P -r %%RECORD_DIR%% -S %%RECORD_SPL_DIR%% -> dtls_gw.o.creplies .echo: OK: rtpproxy GenO started .include: %%SCENARIO%% +.include: oversize.rptl .close: geno .echo: OK: wait for rtpproxy GenO shutdown .close: fwd diff --git a/tests/dtls_gw/oversize.check.rptl b/tests/dtls_gw/oversize.check.rptl new file mode 100644 index 000000000..d290c012f --- /dev/null +++ b/tests/dtls_gw/oversize.check.rptl @@ -0,0 +1,2 @@ +fwd: Qv %%OS_CALLID%% from_tag_1 to_tag_1 npkts_ina nrelayed ndropped -> OS_STATS +.eval: %%OS_STATS%% -> str_equal(OS_EXPECTED, OS_DONE) diff --git a/tests/dtls_gw/oversize.rptl b/tests/dtls_gw/oversize.rptl new file mode 100644 index 000000000..b3a018acb --- /dev/null +++ b/tests/dtls_gw/oversize.rptl @@ -0,0 +1,16 @@ +# A plain RTP datagram that fills the whole receive buffer leaves no room +# for the SRTP trailer: Fwd has to drop it instead of protecting it in place. +.eval: dtls_gw_oversize -> OS_CALLID +fwd: U %%OS_CALLID%% 0.0.0.0 0 from_tag_1 && M4:1 S -> str_split(&&, OS_PORT1, DTLS_PARAMS) +.eval: %%DTLS_PARAMS%% -> str_split( , DTLS_MODE, DTLS_DIGALG, DTLS_DIGSUM) +geno: U %%OS_CALLID%% 127.0.0.1 %%OS_PORT1%% from_tag_1 && M4:1 A %%DTLS_DIGALG%% %%DTLS_DIGSUM%% -> validate_port(_) +geno: L %%OS_CALLID%% 0.0.0.0 0 from_tag_1 to_tag_1 && M4:1 S -> str_split(&&, OS_PORTO, DTLS_PARAMS) +.eval: %%DTLS_PARAMS%% -> str_split( , DTLS_MODE, DTLS_DIGALG, DTLS_DIGSUM) +fwd: L %%OS_CALLID%% 127.0.0.1 %%OS_PORTO%% from_tag_1 to_tag_1 && M4:1 P %%DTLS_DIGALG%% %%DTLS_DIGSUM%% -> validate_port(OS_PORT2) +.sleep: 1 +.exec: %%PYINT%% -c "import socket; s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM); [s.sendto(bytes.fromhex('8000%04x%08x00000001' % (q, q * 160))+bytes(n),('127.0.0.1',%%OS_PORT2%%)) for q, n in ((1, 160), (2, 9000), (3, 160))]" +.eval: npkts_ina=3 nrelayed=2 ndropped=1 -> OS_EXPECTED +.until: OS_DONE do oversize.check.rptl every 0.1 5 +.eval: 0 -> RES_OK +fwd: D %%OS_CALLID%% from_tag_1 to_tag_1 -> str_compare(RES_OK) +geno: D %%OS_CALLID%% from_tag_1 to_tag_1 -> str_compare(RES_OK)