Change in osmo-mgw[master]: mgcp_client: fix error handling in mgcp message generation

laforge gerrit-no-reply at lists.osmocom.org
Sun Jun 13 18:12:50 UTC 2021


laforge has submitted this change. ( https://gerrit.osmocom.org/c/osmo-mgw/+/24182 )

Change subject: mgcp_client: fix error handling in mgcp message generation
......................................................................

mgcp_client: fix error handling in mgcp message generation

The functions add_lco and add_sdp assert when the codec string can not
be generated. This is the case when an unexpected codec is addressed in
the input parameter mgcp_msg for mgcp_msg_gen(). Even though the API
user is expected only to use the codec identifiers in mgcp_client.h the
check should not be done with an assert. Instead mgcp_msg_gen() should
just return NULL imediately.

Also all generation functions should not use magic numbers as return
codes. Instead constants from errno.h should be used. It is also
problematic that the return codes from msgb_printf are added up.
Depending. It makes more sense to use an OR operator since msgb_printf
only returns 0 or -EINVAL, so the end result will be -EINVAL if one or
more msgb_printf fail and not just a random negative value.

Change-Id: Ibb788343e0bec9c0eaf33e6e4727d4d36c100017
Related: OS#5119
---
M src/libosmo-mgcp-client/mgcp_client.c
M tests/mgcp_client/mgcp_client_test.err
2 files changed, 67 insertions(+), 48 deletions(-)

Approvals:
  Jenkins Builder: Verified
  pespin: Looks good to me, but someone else must approve
  laforge: Looks good to me, approved



diff --git a/src/libosmo-mgcp-client/mgcp_client.c b/src/libosmo-mgcp-client/mgcp_client.c
index 55ce7b2..8e6780e 100644
--- a/src/libosmo-mgcp-client/mgcp_client.c
+++ b/src/libosmo-mgcp-client/mgcp_client.c
@@ -1105,30 +1105,40 @@
 	const char *codec;
 	unsigned int pt;
 
-	rc += msgb_printf(msg, "L:");
+	rc |= msgb_printf(msg, "L:");
 
 	if (mgcp_msg->ptime)
-		rc += msgb_printf(msg, " p:%u,", mgcp_msg->ptime);
+		rc |= msgb_printf(msg, " p:%u,", mgcp_msg->ptime);
 
 	if (mgcp_msg->codecs_len) {
-		rc += msgb_printf(msg, " a:");
+		rc |= msgb_printf(msg, " a:");
 		for (i = 0; i < mgcp_msg->codecs_len; i++) {
 			pt = mgcp_msg->codecs[i];
 			codec = get_value_string_or_null(osmo_mgcpc_codec_names, pt);
 
 			/* Note: Use codec descriptors from enum mgcp_codecs
 			 * in mgcp_client only! */
-			OSMO_ASSERT(codec);
-			rc += msgb_printf(msg, "%s", extract_codec_name(codec));
+			if (!codec) {
+				msgb_free(msg);
+				return -EINVAL;
+			}
+
+			rc |= msgb_printf(msg, "%s", extract_codec_name(codec));
 			if (i < mgcp_msg->codecs_len - 1)
-				rc += msgb_printf(msg, ";");
+				rc |= msgb_printf(msg, ";");
 		}
-		rc += msgb_printf(msg, ",");
+		rc |= msgb_printf(msg, ",");
 	}
 
-	rc += msgb_printf(msg, " nt:IN\r\n");
+	rc |= msgb_printf(msg, " nt:IN\r\n");
 
-	return rc;
+	if (rc != 0) {
+		LOGP(DLMGCP, LOGL_ERROR,
+		     "message buffer to small, can not generate MGCP message (LCO)\n");
+		msgb_free(msg);
+		return -ENOBUFS;
+	}
+	return 0;
 }
 
 /* Helper function for mgcp_msg_gen(): Add SDP information to MGCP message */
@@ -1142,64 +1152,64 @@
 	unsigned int pt;
 
 	/* Add separator to mark the beginning of the SDP block */
-	rc += msgb_printf(msg, "\r\n");
+	rc |= msgb_printf(msg, "\r\n");
 
 	/* Add SDP protocol version */
-	rc += msgb_printf(msg, "v=0\r\n");
+	rc |= msgb_printf(msg, "v=0\r\n");
 
 	/* Determine local IP-Address */
 	if (osmo_sock_local_ip(local_ip, mgcp->actual.remote_addr) < 0) {
 		LOGP(DLMGCP, LOGL_ERROR,
 		     "Could not determine local IP-Address!\n");
 		msgb_free(msg);
-		return -2;
+		return -EINVAL;
 	}
 	local_ip_family = osmo_ip_str_type(local_ip);
 	if (local_ip_family == AF_UNSPEC) {
 		msgb_free(msg);
-		return -2;
+		return -EINVAL;
 	}
 	audio_ip_family = osmo_ip_str_type(mgcp_msg->audio_ip);
 	if (audio_ip_family == AF_UNSPEC) {
 		msgb_free(msg);
-		return -2;
+		return -EINVAL;
 	}
 
 	/* Add owner/creator (SDP) */
-	rc += msgb_printf(msg, "o=- %x 23 IN IP%c %s\r\n", mgcp_msg->call_id,
+	rc |= msgb_printf(msg, "o=- %x 23 IN IP%c %s\r\n", mgcp_msg->call_id,
 			  local_ip_family == AF_INET6 ? '6' : '4',
 			  local_ip);
 
 	/* Add session name (none) */
-	rc += msgb_printf(msg, "s=-\r\n");
+	rc |= msgb_printf(msg, "s=-\r\n");
 
 	/* Add RTP address and port */
 	if (mgcp_msg->audio_port == 0) {
 		LOGP(DLMGCP, LOGL_ERROR,
 		     "Invalid port number, can not generate MGCP message\n");
 		msgb_free(msg);
-		return -2;
+		return -EINVAL;
 	}
 	if (strlen(mgcp_msg->audio_ip) <= 0) {
 		LOGP(DLMGCP, LOGL_ERROR,
 		     "Empty ip address, can not generate MGCP message\n");
 		msgb_free(msg);
-		return -2;
+		return -EINVAL;
 	}
-	rc += msgb_printf(msg, "c=IN IP%c %s\r\n",
+	rc |= msgb_printf(msg, "c=IN IP%c %s\r\n",
 			  audio_ip_family == AF_INET6 ? '6' : '4',
 			  mgcp_msg->audio_ip);
 
 	/* Add time description, active time (SDP) */
-	rc += msgb_printf(msg, "t=0 0\r\n");
+	rc |= msgb_printf(msg, "t=0 0\r\n");
 
-	rc += msgb_printf(msg, "m=audio %u RTP/AVP", mgcp_msg->audio_port);
+	rc |= msgb_printf(msg, "m=audio %u RTP/AVP", mgcp_msg->audio_port);
 	for (i = 0; i < mgcp_msg->codecs_len; i++) {
 		pt = map_codec_to_pt(mgcp_msg->ptmap, mgcp_msg->ptmap_len, mgcp_msg->codecs[i]);
-		rc += msgb_printf(msg, " %u", pt);
+		rc |= msgb_printf(msg, " %u", pt);
 
 	}
-	rc += msgb_printf(msg, "\r\n");
+	rc |= msgb_printf(msg, "\r\n");
 
 	/* Add optional codec parameters (fmtp) */
 	if (mgcp_msg->param_present) {
@@ -1209,9 +1219,9 @@
 				   continue;
 			pt = map_codec_to_pt(mgcp_msg->ptmap, mgcp_msg->ptmap_len, mgcp_msg->codecs[i]);
 			if (mgcp_msg->param.amr_octet_aligned_present && mgcp_msg->param.amr_octet_aligned)
-				rc += msgb_printf(msg, "a=fmtp:%u octet-align=1\r\n", pt);
+				rc |= msgb_printf(msg, "a=fmtp:%u octet-align=1\r\n", pt);
 			else if (mgcp_msg->param.amr_octet_aligned_present && !mgcp_msg->param.amr_octet_aligned)
-				rc += msgb_printf(msg, "a=fmtp:%u octet-align=0\r\n", pt);
+				rc |= msgb_printf(msg, "a=fmtp:%u octet-align=0\r\n", pt);
 		}
 	}
 
@@ -1226,16 +1236,26 @@
 
 			/* Note: Use codec descriptors from enum mgcp_codecs
 			 * in mgcp_client only! */
-			OSMO_ASSERT(codec);
+			if (!codec) {
+				msgb_free(msg);
+				return -EINVAL;
+			}
 
-			rc += msgb_printf(msg, "a=rtpmap:%u %s\r\n", pt, codec);
+			rc |= msgb_printf(msg, "a=rtpmap:%u %s\r\n", pt, codec);
 		}
 	}
 
 	if (mgcp_msg->ptime)
-		rc += msgb_printf(msg, "a=ptime:%u\r\n", mgcp_msg->ptime);
+		rc |= msgb_printf(msg, "a=ptime:%u\r\n", mgcp_msg->ptime);
 
-	return rc;
+	if (rc != 0) {
+		LOGP(DLMGCP, LOGL_ERROR,
+		     "message buffer to small, can not generate MGCP message (SDP)\n");
+		msgb_free(msg);
+		return -ENOBUFS;
+	}
+
+	return 0;
 }
 
 /*! Generate an MGCP message
@@ -1248,7 +1268,6 @@
 	uint32_t mandatory_mask;
 	struct msgb *msg = msgb_alloc_headroom(4096, 128, "MGCP tx");
 	int rc = 0;
-	int rc_sdp;
 	bool use_sdp = false;
 	char buf[32];
 
@@ -1259,23 +1278,23 @@
 	switch (mgcp_msg->verb) {
 	case MGCP_VERB_CRCX:
 		mandatory_mask = MGCP_CRCX_MANDATORY;
-		rc += msgb_printf(msg, "CRCX %u", trans_id);
+		rc |= msgb_printf(msg, "CRCX %u", trans_id);
 		break;
 	case MGCP_VERB_MDCX:
 		mandatory_mask = MGCP_MDCX_MANDATORY;
-		rc += msgb_printf(msg, "MDCX %u", trans_id);
+		rc |= msgb_printf(msg, "MDCX %u", trans_id);
 		break;
 	case MGCP_VERB_DLCX:
 		mandatory_mask = MGCP_DLCX_MANDATORY;
-		rc += msgb_printf(msg, "DLCX %u", trans_id);
+		rc |= msgb_printf(msg, "DLCX %u", trans_id);
 		break;
 	case MGCP_VERB_AUEP:
 		mandatory_mask = MGCP_AUEP_MANDATORY;
-		rc += msgb_printf(msg, "AUEP %u", trans_id);
+		rc |= msgb_printf(msg, "AUEP %u", trans_id);
 		break;
 	case MGCP_VERB_RSIP:
 		mandatory_mask = MGCP_RSIP_MANDATORY;
-		rc += msgb_printf(msg, "RSIP %u", trans_id);
+		rc |= msgb_printf(msg, "RSIP %u", trans_id);
 		break;
 	default:
 		LOGP(DLMGCP, LOGL_ERROR,
@@ -1309,15 +1328,15 @@
 			return NULL;
 		}
 
-		rc += msgb_printf(msg, " %s", mgcp_msg->endpoint);
+		rc |= msgb_printf(msg, " %s", mgcp_msg->endpoint);
 	}
 
 	/* Add protocol version */
-	rc += msgb_printf(msg, " MGCP 1.0\r\n");
+	rc |= msgb_printf(msg, " MGCP 1.0\r\n");
 
 	/* Add call id */
 	if (mgcp_msg->presence & MGCP_MSG_PRESENCE_CALL_ID)
-		rc += msgb_printf(msg, "C: %x\r\n", mgcp_msg->call_id);
+		rc |= msgb_printf(msg, "C: %x\r\n", mgcp_msg->call_id);
 
 	/* Add connection id */
 	if (mgcp_msg->presence & MGCP_MSG_PRESENCE_CONN_ID) {
@@ -1327,7 +1346,7 @@
 			msgb_free(msg);
 			return NULL;
 		}
-		rc += msgb_printf(msg, "I: %s\r\n", mgcp_msg->conn_id);
+		rc |= msgb_printf(msg, "I: %s\r\n", mgcp_msg->conn_id);
 	}
 
 	/* Using SDP makes sense when a valid IP/Port combination is specifiec,
@@ -1339,19 +1358,21 @@
 	/* Add local connection options (LCO) */
 	if (!use_sdp
 	    && (mgcp_msg->verb == MGCP_VERB_CRCX
-		|| mgcp_msg->verb == MGCP_VERB_MDCX))
-		rc += add_lco(msg, mgcp_msg);
+		|| mgcp_msg->verb == MGCP_VERB_MDCX)) {
+	        if (add_lco(msg, mgcp_msg) < 0)
+			return NULL;
+	}
 
 	/* Add mode */
 	if (mgcp_msg->presence & MGCP_MSG_PRESENCE_CONN_MODE)
-		rc +=
+		rc |=
 		    msgb_printf(msg, "M: %s\r\n",
 				mgcp_client_cmode_name(mgcp_msg->conn_mode));
 
 	/* Add X-Osmo-IGN */
 	if ((mgcp_msg->presence & MGCP_MSG_PRESENCE_X_OSMO_IGN)
 	    && (mgcp_msg->x_osmo_ign != 0))
-		rc +=
+		rc |=
 		    msgb_printf(msg, MGCP_X_OSMO_IGN_HEADER "%s\r\n",
 				mgcp_msg->x_osmo_ign & MGCP_X_OSMO_IGN_CALLID ? " C": "");
 
@@ -1365,7 +1386,7 @@
 			return NULL;
 		}
 		snprintf(buf, sizeof(buf), " %d", mgcp_msg->x_osmo_osmux_cid);
-		rc +=
+		rc |=
 		    msgb_printf(msg, MGCP_X_OSMO_OSMUX_HEADER "%s\r\n",
 				mgcp_msg->x_osmo_osmux_cid == -1 ? " *": buf);
 	}
@@ -1375,10 +1396,8 @@
 	if (use_sdp
 	    && (mgcp_msg->verb == MGCP_VERB_CRCX
 		|| mgcp_msg->verb == MGCP_VERB_MDCX)) {
-		rc_sdp = add_sdp(msg, mgcp_msg, mgcp);
-		if (rc_sdp == -2)
+	        if (add_sdp(msg, mgcp_msg, mgcp) < 0)
 			return NULL;
-		rc += rc_sdp;
 	}
 
 	if (rc != 0) {
diff --git a/tests/mgcp_client/mgcp_client_test.err b/tests/mgcp_client/mgcp_client_test.err
index ac13f03..80119cb 100644
--- a/tests/mgcp_client/mgcp_client_test.err
+++ b/tests/mgcp_client/mgcp_client_test.err
@@ -1,5 +1,5 @@
 DLMGCP MGCP client: using endpoint domain '@mgw'
-DLMGCP message buffer to small, can not generate MGCP message
+DLMGCP message buffer to small, can not generate MGCP message (SDP)
 
 test_mgcp_client_cancel():
 DLMGCP MGCP client: using endpoint domain '@mgw'

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-mgw/+/24182
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-mgw
Gerrit-Branch: master
Gerrit-Change-Id: Ibb788343e0bec9c0eaf33e6e4727d4d36c100017
Gerrit-Change-Number: 24182
Gerrit-PatchSet: 4
Gerrit-Owner: dexter <pmaier at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy at sysmocom.de>
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: neels <nhofmeyr at sysmocom.de>
Gerrit-Reviewer: pespin <pespin at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210613/455d1081/attachment.htm>


More information about the gerrit-log mailing list