protocol: check the packetization in local cx options
When the local connection options in an MDCX or CRCX request
are parsed, then the packetization interval is not checked.
- Check if the packetization is a multiple of 20ms
see also TTCN3 test: MGCP_Test.TC_crcx_unsupp_packet_intv
Change-Id: I02aaa3042f2a0e32eb4ec6b8753deab7082947a0
Related: OS#2654
diff --git a/src/libosmo-mgcp/mgcp_protocol.c b/src/libosmo-mgcp/mgcp_protocol.c
index 73d7f5e..709c04a 100644
--- a/src/libosmo-mgcp/mgcp_protocol.c
+++ b/src/libosmo-mgcp/mgcp_protocol.c
@@ -396,7 +396,7 @@
* The string is stored in the 'string' field. A NULL string is handled exactly
* like an empty string, the 'string' field is never NULL after this function
* has been called. */
-static void set_local_cx_options(void *ctx, struct mgcp_lco *lco,
+static int set_local_cx_options(void *ctx, struct mgcp_lco *lco,
const char *options)
{
char *p_opt, *a_opt;
@@ -420,6 +420,15 @@
LOGP(DLMGCP, LOGL_DEBUG,
"local CX options: lco->pkt_period_max: %i, lco->codec: %s\n",
lco->pkt_period_max, lco->codec);
+
+ /* Check if the packetization fits the 20ms raster */
+ if (lco->pkt_period_min % 20 && lco->pkt_period_max % 20) {
+ LOGP(DLMGCP, LOGL_ERROR,
+ "local CX options: packetization interval is not a multiple of 20ms!\n");
+ return 535;
+ }
+
+ return 0;
}
void mgcp_rtp_end_config(struct mgcp_endpoint *endp, int expect_ssrc_change,
@@ -486,6 +495,7 @@
struct mgcp_conn_rtp *conn = NULL;
struct mgcp_conn *_conn = NULL;
char conn_name[512];
+ int rc;
LOGP(DLMGCP, LOGL_NOTICE, "CRCX: creating new connection ...\n");
@@ -587,8 +597,14 @@
endp->callid = talloc_strdup(tcfg->endpoints, callid);
/* Extract audio codec information */
- set_local_cx_options(endp->tcfg->endpoints, &endp->local_options,
- local_options);
+ rc = set_local_cx_options(endp->tcfg->endpoints, &endp->local_options,
+ local_options);
+ if (rc != 0) {
+ LOGP(DLMGCP, LOGL_ERROR,
+ "CRCX: endpoint:%x inavlid local connection options!\n",
+ ENDPOINT_NUMBER(endp));
+ return create_err_response(endp, rc, "CRCX", p->trans);
+ }
snprintf(conn_name, sizeof(conn_name), "%s", callid);
_conn = mgcp_conn_alloc(NULL, endp, MGCP_CONN_TYPE_RTP, conn_name);
@@ -706,6 +722,7 @@
const char *mode = NULL;
struct mgcp_conn_rtp *conn = NULL;
const char *conn_id = NULL;
+ int rc;
LOGP(DLMGCP, LOGL_NOTICE, "MDCX: modifying existing connection ...\n");
@@ -778,8 +795,14 @@
if (have_sdp)
mgcp_parse_sdp_data(endp, conn, p);
- set_local_cx_options(endp->tcfg->endpoints, &endp->local_options,
- local_options);
+ rc = set_local_cx_options(endp->tcfg->endpoints, &endp->local_options,
+ local_options);
+ if (rc != 0) {
+ LOGP(DLMGCP, LOGL_ERROR,
+ "MDCX: endpoint:%x inavlid local connection options!\n",
+ ENDPOINT_NUMBER(endp));
+ return create_err_response(endp, rc, "MDCX", p->trans);
+ }
if (!have_sdp && endp->local_options.codec)
mgcp_set_audio_info(p->cfg, &conn->end.codec,