[MERGED] osmo-mgw[master]: network: autdetect rtp bind ip-address

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Harald Welte gerrit-no-reply at lists.osmocom.org
Thu Nov 2 18:06:57 UTC 2017


Harald Welte has submitted this change and it was merged.

Change subject: network: autdetect rtp bind ip-address
......................................................................


network: autdetect rtp bind ip-address

Currently there are two ways to set the rtp bind ip-address (local
ip address where the rtp streams are bound to). It is possible to
set no set an rtp bind ip, if none no address is configured, then
the ip address where the mgcp service is bound to is used.

On a system with multiple network interfaces it is likely that
there are the remote end is not reachable through the interface
that has been configured. In this case rtp ip-probing can be
enabled via vty option in order to automatically detect the
ip address of the interface that points towards the remote end.

The autodetection can only work if the ip-address is known when
a CRCX is performed. For this the remote entity must include the
remote ip address in the sdp trailer.

Implement probing to determine te right local ip address
Add debug log to display which ip address is actually used
Add a VTY option for the probing functionality.

Change-Id: Ia57cf7dab8421fd3ab6e1515727db0080373485e
---
M include/osmocom/mgcp/mgcp.h
M include/osmocom/mgcp/mgcp_internal.h
M src/libosmo-mgcp/mgcp_network.c
M src/libosmo-mgcp/mgcp_protocol.c
M src/libosmo-mgcp/mgcp_vty.c
5 files changed, 97 insertions(+), 20 deletions(-)

Approvals:
  Harald Welte: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/include/osmocom/mgcp/mgcp.h b/include/osmocom/mgcp/mgcp.h
index 59147f0..42a91d8 100644
--- a/include/osmocom/mgcp/mgcp.h
+++ b/include/osmocom/mgcp/mgcp.h
@@ -96,6 +96,12 @@
 	int range_start;
 	int range_end;
 	int last_port;
+
+	/* set to true to enable automatic probing
+	 * of the local bind IP-Address, bind_addr
+	 * (or its fall back) is used when automatic
+	 * probing fails */
+	bool bind_addr_probe;
 };
 
 /* There are up to three modes in which the keep-alive dummy packet can be
diff --git a/include/osmocom/mgcp/mgcp_internal.h b/include/osmocom/mgcp/mgcp_internal.h
index d4c8dc9..b9c1731 100644
--- a/include/osmocom/mgcp/mgcp_internal.h
+++ b/include/osmocom/mgcp/mgcp_internal.h
@@ -318,12 +318,4 @@
 
 #define PTYPE_UNDEFINED (-1)
 
-/*! get the ip-address where the mgw application is bound on.
- *  \param[in] endp mgcp endpoint, that holds a copy of the VTY parameters
- *  \returns pointer to a string that contains the source ip-address */
-static inline const char *mgcp_net_src_addr(struct mgcp_endpoint *endp)
-{
-	if (endp->cfg->net_ports.bind_addr)
-		return endp->cfg->net_ports.bind_addr;
-	return endp->cfg->source_addr;
-}
+void mgcp_get_local_addr(char *addr, struct mgcp_conn_rtp *conn);
diff --git a/src/libosmo-mgcp/mgcp_network.c b/src/libosmo-mgcp/mgcp_network.c
index 3d52d07..7876b33 100644
--- a/src/libosmo-mgcp/mgcp_network.c
+++ b/src/libosmo-mgcp/mgcp_network.c
@@ -32,6 +32,7 @@
 
 #include <osmocom/core/msgb.h>
 #include <osmocom/core/select.h>
+#include <osmocom/core/socket.h>
 #include <osmocom/netif/rtp.h>
 #include <osmocom/mgcp/mgcp.h>
 #include <osmocom/mgcp/mgcp_common.h>
@@ -51,6 +52,56 @@
 	MGCP_PROTO_RTP,
 	MGCP_PROTO_RTCP,
 };
+
+/*! Determine the local rtp bind IP-address.
+ *  \param[out] addr caller provided memory to store the resulting IP-Address
+ *  \param[in] endp mgcp endpoint, that holds a copy of the VTY parameters
+ *
+ *  The local bind IP-address is automatically selected by probing the
+ *  IP-Address of the interface that is pointing towards the remote IP-Address,
+ *  if no remote IP-Address is known yet, the statically configured
+ *  IP-Addresses are used as fallback. */
+void mgcp_get_local_addr(char *addr, struct mgcp_conn_rtp *conn)
+{
+
+	struct mgcp_endpoint *endp;
+	int rc;
+	endp = conn->conn->endp;
+
+	/* Try probing the local IP-Address */
+	if (endp->cfg->net_ports.bind_addr_probe && conn->end.addr.s_addr != 0) {
+		rc = osmo_sock_local_ip(addr, inet_ntoa(conn->end.addr));
+		if (rc < 0)
+			LOGP(DRTP, LOGL_ERROR,
+			     "endpoint:%x CI:%i local interface auto detection failed, using configured addresses...\n",
+			     ENDPOINT_NUMBER(endp), conn->conn->id);
+		else {
+			LOGP(DRTP, LOGL_DEBUG,
+			     "endpoint:%x CI:%i selected local rtp bind ip %s by probing using remote ip %s\n",
+			     ENDPOINT_NUMBER(endp), conn->conn->id, addr,
+			     inet_ntoa(conn->end.addr));
+			return;
+		}
+	}
+
+	/* Select from preconfigured IP-Addresses */
+	if (endp->cfg->net_ports.bind_addr) {
+		/* Check there is a bind IP for the RTP traffic configured,
+		 * if so, use that IP-Address */
+		strncpy(addr, endp->cfg->net_ports.bind_addr, INET_ADDRSTRLEN);
+		LOGP(DRTP, LOGL_DEBUG,
+		     "endpoint:%x CI:%i using configured rtp bind ip as local bind ip %s\n",
+		     ENDPOINT_NUMBER(endp), conn->conn->id, addr);
+	} else {
+		/* No specific bind IP is configured for the RTP traffic, so
+		 * assume the IP where we listen for incoming MGCP messages
+		 * as bind IP */
+		strncpy(addr, endp->cfg->source_addr, INET_ADDRSTRLEN);
+		LOGP(DRTP, LOGL_DEBUG,
+		     "endpoint:%x CI:%i using mgcp bind ip as local rtp bind ip: %s\n",
+		     ENDPOINT_NUMBER(endp), conn->conn->id, addr);
+	}
+}
 
 /* This does not need to be a precision timestamp and
  * is allowed to wrap quite fast. The returned value is
@@ -1158,6 +1209,7 @@
 {
 	char name[512];
 	struct mgcp_rtp_end *end;
+	char local_ip_addr[INET_ADDRSTRLEN];
 
 	snprintf(name, sizeof(name), "%s-%u", conn->conn->name, conn->conn->id);
 	end = &conn->end;
@@ -1182,7 +1234,9 @@
 	end->rtcp.data = conn;
 	end->rtcp.cb = rtp_data_net;
 
-	return bind_rtp(endp->cfg, mgcp_net_src_addr(endp), end,
+	mgcp_get_local_addr(local_ip_addr, conn);
+
+	return bind_rtp(endp->cfg, local_ip_addr, end,
 			ENDPOINT_NUMBER(endp));
 }
 
diff --git a/src/libosmo-mgcp/mgcp_protocol.c b/src/libosmo-mgcp/mgcp_protocol.c
index 4826790..8c6bd6e 100644
--- a/src/libosmo-mgcp/mgcp_protocol.c
+++ b/src/libosmo-mgcp/mgcp_protocol.c
@@ -203,13 +203,16 @@
 	int rc;
 	struct msgb *result;
 	char osmux_extension[strlen("\nX-Osmux: 255") + 1];
+	char local_ip_addr[INET_ADDRSTRLEN];
 
 	sdp = msgb_alloc_headroom(4096, 128, "sdp record");
 	if (!sdp)
 		return NULL;
 
-	if (!addr)
-		addr = mgcp_net_src_addr(endp);
+	if (!addr) {
+		mgcp_get_local_addr(local_ip_addr, conn);
+		addr = local_ip_addr;
+	}
 
 	if (conn->osmux.state == OSMUX_STATE_NEGOTIATING) {
 		sprintf(osmux_extension, "\nX-Osmux: %u", conn->osmux.cid);
@@ -597,12 +600,6 @@
 		goto error2;
 	}
 
-	mgcp_rtp_end_config(endp, 0, &conn->end);
-
-	if (allocate_port(endp, conn) != 0) {
-		goto error2;
-	}
-
 	/* Annotate Osmux circuit ID and set it to negotiating state until this
 	 * is fully set up from the dummy load. */
 	conn->osmux.state = OSMUX_STATE_DISABLED;
@@ -630,6 +627,12 @@
 		conn->end.force_output_ptime = 1;
 	}
 
+	mgcp_rtp_end_config(endp, 0, &conn->end);
+
+	if (allocate_port(endp, conn) != 0) {
+		goto error2;
+	}
+
 	if (setup_rtp_processing(endp, conn) != 0) {
 		LOGP(DLMGCP, LOGL_ERROR,
 		     "CRCX: endpoint:%x could not start RTP processing!\n",
diff --git a/src/libosmo-mgcp/mgcp_vty.c b/src/libosmo-mgcp/mgcp_vty.c
index 7107bcc..7ff1fdd 100644
--- a/src/libosmo-mgcp/mgcp_vty.c
+++ b/src/libosmo-mgcp/mgcp_vty.c
@@ -70,11 +70,13 @@
 	vty_out(vty, "  rtp net-range %u %u%s",
 		g_cfg->net_ports.range_start, g_cfg->net_ports.range_end,
 		VTY_NEWLINE);
-
 	if (g_cfg->net_ports.bind_addr)
 		vty_out(vty, "  rtp net-bind-ip %s%s",
 			g_cfg->net_ports.bind_addr, VTY_NEWLINE);
-
+	if (g_cfg->net_ports.bind_addr_probe)
+		vty_out(vty, "  rtp ip-probing%s", VTY_NEWLINE);
+	else
+		vty_out(vty, "  no rtp ip-probing%s", VTY_NEWLINE);
 	vty_out(vty, "  rtp ip-dscp %d%s", g_cfg->endp_dscp, VTY_NEWLINE);
 	if (g_cfg->trunk.keepalive_interval == MGCP_KEEPALIVE_ONCE)
 		vty_out(vty, "  rtp keep-alive once%s", VTY_NEWLINE);
@@ -317,6 +319,24 @@
 {
 	talloc_free(g_cfg->net_ports.bind_addr);
 	g_cfg->net_ports.bind_addr = NULL;
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_mgcp_rtp_net_bind_ip_probing,
+      cfg_mgcp_rtp_net_bind_ip_probing_cmd,
+      "rtp ip-probing",
+      RTP_STR "automatic rtp bind ip selection\n")
+{
+	g_cfg->net_ports.bind_addr_probe = true;
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_mgcp_rtp_no_net_bind_ip_probing,
+      cfg_mgcp_rtp_no_net_bind_ip_probing_cmd,
+      "no rtp ip-probing",
+      NO_STR RTP_STR "no automatic rtp bind ip selection\n")
+{
+	g_cfg->net_ports.bind_addr_probe = false;
 	return CMD_SUCCESS;
 }
 
@@ -1163,6 +1183,8 @@
 	install_element(MGCP_NODE, &cfg_mgcp_rtp_net_range_cmd);
 	install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_cmd);
 	install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_cmd);
+	install_element(MGCP_NODE, &cfg_mgcp_rtp_net_bind_ip_probing_cmd);
+	install_element(MGCP_NODE, &cfg_mgcp_rtp_no_net_bind_ip_probing_cmd);
 	install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_dscp_cmd);
 	install_element(MGCP_NODE, &cfg_mgcp_rtp_ip_tos_cmd);
 	install_element(MGCP_NODE, &cfg_mgcp_rtp_force_ptime_cmd);

-- 
To view, visit https://gerrit.osmocom.org/4650
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ia57cf7dab8421fd3ab6e1515727db0080373485e
Gerrit-PatchSet: 1
Gerrit-Project: osmo-mgw
Gerrit-Branch: master
Gerrit-Owner: dexter <pmaier at sysmocom.de>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder



More information about the gerrit-log mailing list