Change in osmo-sip-connector[master]: mncc: Support IPv6 addresses (new version mncc 7)

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/.

pespin gerrit-no-reply at lists.osmocom.org
Wed Sep 9 16:41:06 UTC 2020


pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-sip-connector/+/20052 )


Change subject: mncc: Support IPv6 addresses (new version mncc 7)
......................................................................

mncc: Support IPv6 addresses (new version mncc 7)

Change-Id: I3b1bebbcc9e36be43d8d055c8d28cbb38ff21b37
---
M src/call.h
M src/mncc.c
M src/mncc_protocol.h
M src/sdp.c
M src/sip.c
5 files changed, 75 insertions(+), 49 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-sip-connector refs/changes/52/20052/1

diff --git a/src/call.h b/src/call.h
index 7f67066..d1732f9 100644
--- a/src/call.h
+++ b/src/call.h
@@ -7,6 +7,7 @@
 #include <osmocom/core/utils.h>
 
 #include <stdbool.h>
+#include <netinet/in.h>
 
 struct sip_agent;
 struct mncc_connection;
@@ -49,8 +50,7 @@
 	/**
 	 * RTP data
 	 */
-	uint32_t	ip;
-	uint16_t	port;
+	struct sockaddr_storage addr;
 	uint32_t	payload_type;
 	uint32_t	payload_msg_type;
 
diff --git a/src/mncc.c b/src/mncc.c
index 16eed96..0725d4c 100644
--- a/src/mncc.c
+++ b/src/mncc.c
@@ -174,7 +174,7 @@
 {
 	struct gsm_mncc_rtp mncc = { 0, };
 	int rc;
-	char ip_addr[INET_ADDRSTRLEN];
+	char ip_addr[INET6_ADDRSTRLEN];
 
 	/*
 	 * Send RTP CONNECT and we handle the general failure of it by
@@ -182,16 +182,15 @@
 	 */
 	mncc.msg_type = MNCC_RTP_CONNECT;
 	mncc.callref = leg->callref;
-	mncc.ip = ntohl(other->ip);
-	mncc.port = other->port;
+	mncc.addr = other->addr;
 	mncc.payload_type = other->payload_type;
 	/*
 	 * FIXME: mncc.payload_msg_type should already be compatible.. but
 	 * payload_type should be different..
 	 */
-	struct in_addr net = { .s_addr = other->ip };
-	inet_ntop(AF_INET, &net, ip_addr, sizeof(ip_addr));
-	LOGP(DMNCC, LOGL_DEBUG, "SEND rtp_connect: IP=(%s) PORT=(%u)\n", ip_addr, mncc.port);
+	LOGP(DMNCC, LOGL_DEBUG, "SEND rtp_connect: IP=(%s) PORT=(%u)\n",
+	     osmo_sockaddr_ntop((const struct sockaddr*)&other->addr, ip_addr),
+	     osmo_sockaddr_port((const struct sockaddr*)&other->addr));
 	rc = write(leg->conn->fd.fd, &mncc, sizeof(mncc));
 	if (rc != sizeof(mncc)) {
 		LOGP(DMNCC, LOGL_ERROR, "Failed to send message for call(%u)\n",
@@ -272,7 +271,8 @@
 	 * FIXME: We would like to keep this as recvonly...
 	 */
 	other_leg = call_leg_other(&leg->base);
-	if (other_leg && other_leg->port != 0 && other_leg->ip != 0)
+	if (other_leg && other_leg->addr.ss_family != AF_UNSPEC &&
+	    osmo_sockaddr_port((const struct sockaddr *)&other_leg->addr) != 0)
 		send_rtp_connect(leg, other_leg);
 }
 
@@ -397,7 +397,9 @@
 	}
 
 	/* extract information about where the RTP is */
-	if (rtp->ip != 0 || rtp->port != 0 || rtp->payload_type != 0)
+	if (rtp->addr.ss_family != AF_UNSPEC ||
+	    osmo_sockaddr_port((const struct sockaddr *)&rtp->addr) != 0 ||
+	    rtp->payload_type != 0)
 		return;
 
 	LOGP(DMNCC, LOGL_ERROR, "leg(%u) rtp connect failed\n", rtp->callref);
@@ -412,7 +414,7 @@
 {
 	const struct gsm_mncc_rtp *rtp;
 	struct mncc_call_leg *leg;
-	char ip_addr[INET_ADDRSTRLEN];
+	char ip_addr[INET6_ADDRSTRLEN];
 
 	if (rc < sizeof(*rtp)) {
 		LOGP(DMNCC, LOGL_ERROR, "gsm_mncc_rtp of wrong size %d < %zu\n",
@@ -428,17 +430,16 @@
 	}
 
 	/* extract information about where the RTP is */
-	leg->base.ip = htonl(rtp->ip);
-	leg->base.port = rtp->port;
+	leg->base.addr = rtp->addr;
 	leg->base.payload_type = rtp->payload_type;
 	leg->base.payload_msg_type = rtp->payload_msg_type;
 
 	/* TODO.. now we can continue with the call */
-	struct in_addr net = { .s_addr = leg->base.ip };
-	inet_ntop(AF_INET, &net, ip_addr, sizeof(ip_addr));
 	LOGP(DMNCC, LOGL_INFO,
 		"RTP continue leg(%u) ip(%s), port(%u) pt(%u) ptm(%u)\n",
-		leg->callref, ip_addr, leg->base.port,
+		leg->callref,
+		osmo_sockaddr_ntop((const struct sockaddr*)&leg->base.addr, ip_addr),
+		osmo_sockaddr_port((const struct sockaddr*)&leg->base.addr),
 		leg->base.payload_type, leg->base.payload_msg_type);
 	stop_cmd_timer(leg, MNCC_RTP_CREATE);
 	continue_call(leg);
diff --git a/src/mncc_protocol.h b/src/mncc_protocol.h
index b6f6635..5d35191 100644
--- a/src/mncc_protocol.h
+++ b/src/mncc_protocol.h
@@ -1,4 +1,4 @@
-/* GSM Mobile Radio Interface Layer 3 messages on the A-bis interface 
+/* GSM Mobile Radio Interface Layer 3 messages on the A-bis interface
  * 3GPP TS 04.08 version 7.21.0 Release 1998 / ETSI TS 100 940 V7.21.0 */
 
 /* (C) 2008-2009 by Harald Welte <laforge at gnumonks.org>
@@ -28,6 +28,7 @@
 #include <osmocom/gsm/mncc.h>
 
 #include <stdint.h>
+#include <netinet/in.h>
 
 struct gsm_network;
 struct msgb;
@@ -169,7 +170,7 @@
 	unsigned char	data[0];
 };
 
-#define MNCC_SOCK_VERSION	6
+#define MNCC_SOCK_VERSION	7
 struct gsm_mncc_hello {
 	uint32_t	msg_type;
 	uint32_t	version;
@@ -188,8 +189,7 @@
 struct gsm_mncc_rtp {
 	uint32_t	msg_type;
 	uint32_t	callref;
-	uint32_t	ip;
-	uint16_t	port;
+	struct sockaddr_storage addr;
 	uint32_t	payload_type;
 	uint32_t	payload_msg_type;
 	char		sdp[1024];
diff --git a/src/sdp.c b/src/sdp.c
index 46330cd..0fd7a09 100644
--- a/src/sdp.c
+++ b/src/sdp.c
@@ -32,6 +32,8 @@
 
 #include <string.h>
 
+#include <osmocom/core/socket.h>
+
 /*
  * Check if the media mode attribute exists in SDP, in this
  * case update the passed pointer with the media mode
@@ -136,6 +138,7 @@
 	sdp_parser_t *parser;
 	sdp_media_t *media;
 	const char *sdp_data;
+	uint16_t port;
 	bool found_conn = false, found_map = false;
 
 	if (!sip->sip_payload || !sip->sip_payload->pl_data) {
@@ -159,13 +162,22 @@
 	}
 
 	for (conn = sdp->sdp_connection; conn; conn = conn->c_next) {
-		struct in_addr addr;
-
-		if (conn->c_addrtype != sdp_addr_ip4)
+		switch (conn->c_addrtype) {
+		case sdp_addr_ip4:
+			leg->base.addr.ss_family = AF_INET;
+			inet_pton(AF_INET, conn->c_address,
+				  &((struct sockaddr_in*)&leg->base.addr)->sin_addr);
+			found_conn = true;
+			break;
+		case sdp_addr_ip6:
+			leg->base.addr.ss_family = AF_INET6;
+			inet_pton(AF_INET6, conn->c_address,
+				  &((struct sockaddr_in6*)&leg->base.addr)->sin6_addr);
+			found_conn = true;
+			break;
+		default:
 			continue;
-		inet_aton(conn->c_address, &addr);
-		leg->base.ip = addr.s_addr;
-		found_conn = true;
+		}
 		break;
 	}
 
@@ -181,7 +193,7 @@
 			if (!any_codec && strcasecmp(map->rm_encoding, leg->wanted_codec) != 0)
 				continue;
 
-			leg->base.port = media->m_port;
+			port = media->m_port;
 			leg->base.payload_type = map->rm_pt;
 			found_map = true;
 			break;
@@ -198,18 +210,30 @@
 		return false;
 	}
 
+	switch (leg->base.addr.ss_family) {
+	case AF_INET:
+		((struct sockaddr_in*)&leg->base.addr)->sin_port = port;
+		break;
+	case AF_INET6:
+		((struct sockaddr_in6*)&leg->base.addr)->sin6_port = port;
+		break;
+	default:
+		OSMO_ASSERT(0);
+	}
+
 	sdp_parser_free(parser);
 	return true;
 }
 
 char *sdp_create_file(struct sip_call_leg *leg, struct call_leg *other, sdp_mode_t mode)
 {
-	struct in_addr net = { .s_addr = other->ip };
 	char *fmtp_str = NULL, *sdp;
 	char *mode_attribute;
-	char ip_addr[INET_ADDRSTRLEN];
+	char ip_addr[INET6_ADDRSTRLEN];
+	char ipv;
 
-	inet_ntop(AF_INET, &net, ip_addr, sizeof(ip_addr));
+	osmo_sockaddr_ntop((const struct sockaddr*)&other->addr, ip_addr);
+	ipv = other->addr.ss_family == AF_INET6 ? '6' : '4';
 	leg->wanted_codec = app_media_name(other->payload_msg_type);
 
 	if (strcmp(leg->wanted_codec, "AMR") == 0)
@@ -235,16 +259,17 @@
 
 	sdp = talloc_asprintf(leg,
 				"v=0\r\n"
-				"o=Osmocom 0 0 IN IP4 %s\r\n"
+				"o=Osmocom 0 0 IN IP%c %s\r\n"
 				"s=GSM Call\r\n"
-				"c=IN IP4 %s\r\n"
+				"c=IN IP%c %s\r\n"
 				"t=0 0\r\n"
 				"m=audio %d RTP/AVP %d\r\n"
 				"%s"
 				"a=rtpmap:%d %s/8000\r\n"
 				"%s",
-				ip_addr, ip_addr,
-				other->port, other->payload_type,
+				ipv, ip_addr, ipv, ip_addr,
+				osmo_sockaddr_port((const struct sockaddr *)&other->addr),
+				other->payload_type,
 				fmtp_str ? fmtp_str : "",
 				other->payload_type,
 				leg->wanted_codec,
diff --git a/src/sip.c b/src/sip.c
index c635542..1854f39 100644
--- a/src/sip.c
+++ b/src/sip.c
@@ -25,6 +25,7 @@
 #include "sdp.h"
 
 #include <osmocom/core/utils.h>
+#include <osmocom/core/socket.h>
 
 #include <sofia-sip/sip_status.h>
 #include <sofia-sip/su_log.h>
@@ -33,6 +34,7 @@
 #include <talloc.h>
 
 #include <string.h>
+#include <netinet/in.h>
 
 extern void *tall_mncc_ctx;
 
@@ -110,7 +112,7 @@
 	struct call *call;
 	struct sip_call_leg *leg;
 	const char *from = NULL, *to = NULL;
-	char ip_addr[INET_ADDRSTRLEN];
+	char ip_addr[INET6_ADDRSTRLEN];
 
 	LOGP(DSIP, LOGL_INFO, "Incoming call(%s) handle(%p)\n", sip->sip_call_id->i_id, nh);
 
@@ -159,11 +161,9 @@
 		call_leg_release(&leg->base);
 		return;
 	}
-	struct in_addr net = { .s_addr = leg->base.ip };
-	inet_ntop(AF_INET, &net, ip_addr, sizeof(ip_addr));
 	LOGP(DSIP, LOGL_INFO, "SDP Extracted: IP=(%s) PORT=(%u) PAYLOAD=(%u).\n",
-		               ip_addr,
-		               leg->base.port,
+		               osmo_sockaddr_ntop((const struct sockaddr *)&leg->base.addr, ip_addr),
+		               osmo_sockaddr_port((const struct sockaddr *)&leg->base.addr),
 		               leg->base.payload_type);
 
 	leg->base.release_call = sip_release_call;
@@ -186,9 +186,8 @@
 
 	char *sdp;
 	sdp_mode_t mode = sdp_sendrecv;
-	uint32_t ip = leg->base.ip;
-	uint16_t port = leg->base.port;
-	char ip_addr[INET_ADDRSTRLEN];
+	char ip_addr[INE6T_ADDRSTRLEN];
+	struct sockaddr_storage prev_addr = leg->base.addr;
 
 	LOGP(DSIP, LOGL_INFO, "re-INVITE for call %s\n", sip->sip_call_id->i_id);
 
@@ -214,9 +213,9 @@
 		return;
 	}
 
-	struct in_addr net = { .s_addr = leg->base.ip };
-	inet_ntop(AF_INET, &net, ip_addr, sizeof(ip_addr));
-	LOGP(DSIP, LOGL_DEBUG, "pre re-INVITE have IP:port (%s:%u)\n", ip_addr, leg->base.port);
+	LOGP(DSIP, LOGL_DEBUG, "pre re-INVITE have IP:port (%s:%u)\n",
+	     osmo_sockaddr_ntop((struct sockaddr*)&leg->base.addr, ip_addr),
+	     osmo_sockaddr_port((struct sockaddr*)&leg->base.addr));
 
 	if (mode == sdp_sendonly) {
 		/* SIP side places call on HOLD */
@@ -231,10 +230,11 @@
 			call_leg_release(&leg->base);
 			return;
 		}
-		struct in_addr net = { .s_addr = leg->base.ip };
-		inet_ntop(AF_INET, &net, ip_addr, sizeof(ip_addr));
-		LOGP(DSIP, LOGL_DEBUG, "Media IP:port in re-INVITE: (%s:%u)\n", ip_addr, leg->base.port);
-		if (ip != leg->base.ip || port != leg->base.port) {
+		LOGP(DSIP, LOGL_DEBUG, "Media IP:port in re-INVITE: (%s:%u)\n",
+		     osmo_sockaddr_ntop((struct sockaddr*)&leg->base.addr, ip_addr),
+		     osmo_sockaddr_port((struct sockaddr*)&leg->base.addr));
+		if (osmo_sockaddr_cmp((struct osmo_sockaddr *)&prev_addr,
+				      (struct osmo_sockaddr *)&leg->base)) {
 			LOGP(DSIP, LOGL_INFO, "re-INVITE changes media connection.\n");
 			if (other->update_rtp)
 				other->update_rtp(leg->base.call->remote);

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

Gerrit-Project: osmo-sip-connector
Gerrit-Branch: master
Gerrit-Change-Id: I3b1bebbcc9e36be43d8d055c8d28cbb38ff21b37
Gerrit-Change-Number: 20052
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin at sysmocom.de>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200909/01723fa9/attachment.htm>


More information about the gerrit-log mailing list