aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2020-08-28 20:21:55 +0200
committerPau Espin Pedrol <pespin@sysmocom.de>2020-09-07 15:55:30 +0200
commit9dc73593a3c1e7c5cc1b0a42c551d616f29762f9 (patch)
tree36b8cf1c2ccc8e28c779363dc73f5624c36aae7d
parentae6858bddf2201f1ba31d0b4cd996e14747c2be5 (diff)
mgcp_client: Allow submitting and parsing IPv6 addr in SDP
Existing mgcp_client_test code required the '.' to trigger the same code path, since with this commit we do extra checks and without a dot the address is not accepted as IPv4 by osmo_ip_str_type(). Change-Id: I936bf57d37f5f0607dfe7fc66c37e424c3793f9b
-rw-r--r--src/libosmo-mgcp-client/mgcp_client.c60
-rw-r--r--tests/mgcp_client/mgcp_client_test.c79
-rw-r--r--tests/mgcp_client/mgcp_client_test.err57
-rw-r--r--tests/mgcp_client/mgcp_client_test.ok32
4 files changed, 212 insertions, 16 deletions
diff --git a/src/libosmo-mgcp-client/mgcp_client.c b/src/libosmo-mgcp-client/mgcp_client.c
index 146a59d59..df84226e4 100644
--- a/src/libosmo-mgcp-client/mgcp_client.c
+++ b/src/libosmo-mgcp-client/mgcp_client.c
@@ -25,6 +25,7 @@
#include <osmocom/core/logging.h>
#include <osmocom/core/byteswap.h>
#include <osmocom/core/socket.h>
+#include <osmocom/core/sockaddr_str.h>
#include <osmocom/mgcp_client/mgcp_client.h>
#include <osmocom/mgcp_client/mgcp_client_internal.h>
@@ -370,22 +371,37 @@ static int mgcp_parse_audio_ptime_rtpmap(struct mgcp_response *r, const char *li
/* Parse a line like "c=IN IP4 10.11.12.13" */
static int mgcp_parse_audio_ip(struct mgcp_response *r, const char *line)
{
- struct in_addr ip_test;
+ struct in6_addr ip_test;
+ bool is_ipv6;
- if (strlen(line) < 16)
+ if (strncmp("c=IN IP", line, 7) != 0)
goto response_parse_failure;
-
- /* The current implementation strictly supports IPV4 only ! */
- if (memcmp("c=IN IP4 ", line, 9) != 0)
+ line += 7;
+ if (*line == '6')
+ is_ipv6 = true;
+ else if (*line == '4')
+ is_ipv6 = false;
+ else
goto response_parse_failure;
-
- /* Extract IP-Address */
- osmo_strlcpy(r->audio_ip, line + 9, sizeof(r->audio_ip));
-
- /* Check IP-Address */
- if (inet_aton(r->audio_ip, &ip_test) == 0)
+ line++;
+ if (*line != ' ')
goto response_parse_failure;
-
+ line++;
+
+ /* Extract and check IP-Address */
+ if (is_ipv6) {
+ /* 45 = INET6_ADDRSTRLEN -1 */
+ if (sscanf(line, "%45s", r->audio_ip) != 1)
+ goto response_parse_failure;
+ if (inet_pton(AF_INET6, r->audio_ip, &ip_test) != 1)
+ goto response_parse_failure;
+ } else {
+ /* 15 = INET_ADDRSTRLEN -1 */
+ if (sscanf(line, "%15s", r->audio_ip) != 1)
+ goto response_parse_failure;
+ if (inet_pton(AF_INET, r->audio_ip, &ip_test) != 1)
+ goto response_parse_failure;
+ }
return 0;
response_parse_failure:
@@ -1122,6 +1138,7 @@ static int add_sdp(struct msgb *msg, struct mgcp_msg *mgcp_msg, struct mgcp_clie
unsigned int i;
int rc = 0;
char local_ip[INET6_ADDRSTRLEN];
+ int local_ip_family, audio_ip_family;
const char *codec;
unsigned int pt;
@@ -1138,10 +1155,21 @@ static int add_sdp(struct msgb *msg, struct mgcp_msg *mgcp_msg, struct mgcp_clie
msgb_free(msg);
return -2;
}
+ local_ip_family = osmo_ip_str_type(local_ip);
+ if (local_ip_family == AF_UNSPEC) {
+ msgb_free(msg);
+ return -2;
+ }
+ audio_ip_family = osmo_ip_str_type(mgcp_msg->audio_ip);
+ if (audio_ip_family == AF_UNSPEC) {
+ msgb_free(msg);
+ return -2;
+ }
/* Add owner/creator (SDP) */
- rc += msgb_printf(msg, "o=- %x 23 IN IP4 %s\r\n",
- mgcp_msg->call_id, local_ip);
+ 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");
@@ -1159,7 +1187,9 @@ static int add_sdp(struct msgb *msg, struct mgcp_msg *mgcp_msg, struct mgcp_clie
msgb_free(msg);
return -2;
}
- rc += msgb_printf(msg, "c=IN IP4 %s\r\n", mgcp_msg->audio_ip);
+ 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");
diff --git a/tests/mgcp_client/mgcp_client_test.c b/tests/mgcp_client/mgcp_client_test.c
index db9f4f8c7..e2e8bf83a 100644
--- a/tests/mgcp_client/mgcp_client_test.c
+++ b/tests/mgcp_client/mgcp_client_test.c
@@ -294,11 +294,23 @@ void test_mgcp_msg(void)
MGCP_MSG_PRESENCE_CONN_ID | MGCP_MSG_PRESENCE_CONN_MODE |
MGCP_MSG_PRESENCE_AUDIO_IP | MGCP_MSG_PRESENCE_AUDIO_PORT);
memset(audio_ip_overflow, 'X', sizeof(audio_ip_overflow));
+ audio_ip_overflow[1] = '.';
audio_ip_overflow[sizeof(audio_ip_overflow) - 1] = '\0';
mgcp_msg.audio_ip = audio_ip_overflow;
msg = mgcp_msg_gen(mgcp, &mgcp_msg);
OSMO_ASSERT(msg == NULL);
+ printf("IPv6 test:\n");
+ mgcp_msg.verb = MGCP_VERB_MDCX;
+ mgcp_msg.presence =
+ (MGCP_MSG_PRESENCE_ENDPOINT | MGCP_MSG_PRESENCE_CALL_ID |
+ MGCP_MSG_PRESENCE_CONN_ID | MGCP_MSG_PRESENCE_CONN_MODE |
+ MGCP_MSG_PRESENCE_AUDIO_IP | MGCP_MSG_PRESENCE_AUDIO_PORT);
+ mgcp_msg.audio_ip = "2001:db8:1::ab9:c0a8:102";
+ mgcp->actual.remote_addr = "::1";
+ msg = mgcp_msg_gen(mgcp, &mgcp_msg);
+ printf("%s\n", (char *)msg->data);
+
printf("\n");
msgb_free(msg);
}
@@ -413,6 +425,66 @@ static struct sdp_section_start_test sdp_section_start_tests[] = {
"m=audio 23\r\n",
.expect_rc = 0,
},
+ {
+ .body = "some mgcp header data\r\nand header params"
+ "\r\n\r\n"
+ "c=IN IP4 1.2.3.4\r\n",
+ .expect_params = {
+ .audio_ip = "1.2.3.4",
+ },
+ .expect_rc = 0,
+ },
+ {
+ .body = "some mgcp header data\r\nand header params"
+ "\r\n\r\n"
+ "c=IN IP6 2001:db8:1::ab9:c0a8:102\r\n",
+ .expect_params = {
+ .audio_ip = "2001:db8:1::ab9:c0a8:102",
+ },
+ .expect_rc = 0,
+ },
+ {
+ .body = "some mgcp header data\r\nand header params"
+ "\r\n\r\n"
+ "c=IN IP6 1.2.3.4\r\n",
+ .expect_rc = -22,
+ },
+ {
+ .body = "some mgcp header data\r\nand header params"
+ "\r\n\r\n"
+ "c=IN IP4 ::1\r\n",
+ .expect_rc = -22,
+ },
+ {
+ .body = "some mgcp header data\r\nand header params"
+ "\r\n\r\n"
+ "c=IN IP4 notanip\r\n",
+ .expect_rc = -22,
+ },
+ {
+ .body = "some mgcp header data\r\nand header params"
+ "\r\n\r\n"
+ "c=IN IP4 1.2.3.4.5.6\r\n",
+ .expect_rc = -22,
+ },
+ {
+ .body = "some mgcp header data\r\nand header params"
+ "\r\n\r\n"
+ "c=IN IP4 1.2 .3\r\n",
+ .expect_rc = -22,
+ },
+ {
+ .body = "some mgcp header data\r\nand header params"
+ "\r\n\r\n"
+ "c=IN IP4 1.2 .3\r\n",
+ .expect_rc = -22,
+ },
+ {
+ .body = "some mgcp header data\r\nand header params"
+ "\r\n\r\n"
+ "c=IN IP4 \r\n",
+ .expect_rc = -22,
+ },
};
void test_sdp_section_start()
@@ -443,7 +515,12 @@ void test_sdp_section_start()
continue;
}
- fprintf(stderr, "got audio_port=%u\n", t->expect_params.audio_port);
+ fprintf(stderr, "got audio_ip=\"%s\"\n", r->audio_ip);
+ if (strcmp(r->audio_ip, t->expect_params.audio_ip)) {
+ fprintf(stderr, "FAIL: Expected audio_ip=\"%s\"\n", t->expect_params.audio_ip);
+ failures++;
+ }
+ fprintf(stderr, "got audio_port=%u\n", r->audio_port);
if (r->audio_port != t->expect_params.audio_port) {
fprintf(stderr, "FAIL: Expected audio_port=%u\n", t->expect_params.audio_port);
failures++;
diff --git a/tests/mgcp_client/mgcp_client_test.err b/tests/mgcp_client/mgcp_client_test.err
index e114f791c..ac13f035c 100644
--- a/tests/mgcp_client/mgcp_client_test.err
+++ b/tests/mgcp_client/mgcp_client_test.err
@@ -19,55 +19,112 @@ test_sdp_section_start() test [0]:
body: ""
DLMGCP MGCP response contains no SDP parameters
got rc=0
+got audio_ip=""
got audio_port=0
test_sdp_section_start() test [1]:
body: "\n\n"
got rc=0
+got audio_ip=""
got audio_port=0
test_sdp_section_start() test [2]:
body: "\r\n\r\n"
got rc=0
+got audio_ip=""
got audio_port=0
test_sdp_section_start() test [3]:
body: "\n\r\n\r"
got rc=0
+got audio_ip=""
got audio_port=0
test_sdp_section_start() test [4]:
body: "some mgcp header data\r\nand header params\n\nm=audio 23\r\n"
got rc=0
+got audio_ip=""
got audio_port=23
test_sdp_section_start() test [5]:
body: "some mgcp header data\r\nand header params\r\n\r\nm=audio 23\r\n"
got rc=0
+got audio_ip=""
got audio_port=23
test_sdp_section_start() test [6]:
body: "some mgcp header data\r\nand header params\n\r\n\rm=audio 23\r\n"
got rc=0
+got audio_ip=""
got audio_port=23
test_sdp_section_start() test [7]:
body: "some mgcp header data\r\nand header params\n\r\nm=audio 23\r\n"
DLMGCP MGCP response contains no SDP parameters
got rc=0
+got audio_ip=""
got audio_port=0
test_sdp_section_start() test [8]:
body: "some mgcp header data\r\nand header params\r\n\rm=audio 23\r\n"
DLMGCP MGCP response contains no SDP parameters
got rc=0
+got audio_ip=""
got audio_port=0
test_sdp_section_start() test [9]:
body: "some mgcp header data\r\nand header params\n\r\rm=audio 23\r\n"
DLMGCP MGCP response contains no SDP parameters
got rc=0
+got audio_ip=""
got audio_port=0
+
+test_sdp_section_start() test [10]:
+body: "some mgcp header data\r\nand header params\r\n\r\nc=IN IP4 1.2.3.4\r\n"
+got rc=0
+got audio_ip="1.2.3.4"
+got audio_port=0
+
+test_sdp_section_start() test [11]:
+body: "some mgcp header data\r\nand header params\r\n\r\nc=IN IP6 2001:db8:1::ab9:c0a8:102\r\n"
+got rc=0
+got audio_ip="2001:db8:1::ab9:c0a8:102"
+got audio_port=0
+
+test_sdp_section_start() test [12]:
+body: "some mgcp header data\r\nand header params\r\n\r\nc=IN IP6 1.2.3.4\r\n"
+DLMGCP Failed to parse MGCP response header (audio ip)
+got rc=-22
+
+test_sdp_section_start() test [13]:
+body: "some mgcp header data\r\nand header params\r\n\r\nc=IN IP4 ::1\r\n"
+DLMGCP Failed to parse MGCP response header (audio ip)
+got rc=-22
+
+test_sdp_section_start() test [14]:
+body: "some mgcp header data\r\nand header params\r\n\r\nc=IN IP4 notanip\r\n"
+DLMGCP Failed to parse MGCP response header (audio ip)
+got rc=-22
+
+test_sdp_section_start() test [15]:
+body: "some mgcp header data\r\nand header params\r\n\r\nc=IN IP4 1.2.3.4.5.6\r\n"
+DLMGCP Failed to parse MGCP response header (audio ip)
+got rc=-22
+
+test_sdp_section_start() test [16]:
+body: "some mgcp header data\r\nand header params\r\n\r\nc=IN IP4 1.2 .3\r\n"
+DLMGCP Failed to parse MGCP response header (audio ip)
+got rc=-22
+
+test_sdp_section_start() test [17]:
+body: "some mgcp header data\r\nand header params\r\n\r\nc=IN IP4 1.2 .3\r\n"
+DLMGCP Failed to parse MGCP response header (audio ip)
+got rc=-22
+
+test_sdp_section_start() test [18]:
+body: "some mgcp header data\r\nand header params\r\n\r\nc=IN IP4 \r\n"
+DLMGCP Failed to parse MGCP response header (audio ip)
+got rc=-22
DLMGCP ptmap contains illegal mapping: codec=113 maps to pt=2
DLMGCP ptmap contains illegal mapping: codec=0 maps to pt=100
DLMGCP ptmap contains illegal mapping: codec=113 maps to pt=2
diff --git a/tests/mgcp_client/mgcp_client_test.ok b/tests/mgcp_client/mgcp_client_test.ok
index 2b03ba171..039fbd9b6 100644
--- a/tests/mgcp_client/mgcp_client_test.ok
+++ b/tests/mgcp_client/mgcp_client_test.ok
@@ -109,6 +109,20 @@ M: sendrecv
X-Osmux: 2
Overfolow test:
+IPv6 test:
+MDCX 19 23@mgw MGCP 1.0
+C: 2f
+I: 11
+M: sendrecv
+
+v=0
+o=- 2f 23 IN IP6 ::1
+s=-
+c=IN IP6 2001:db8:1::ab9:c0a8:102
+t=0 0
+m=audio 1234 RTP/AVP 3
+a=ptime:20
+
test_mgcp_client_cancel():
@@ -149,6 +163,24 @@ test_sdp_section_start() test [7]:
test_sdp_section_start() test [8]:
test_sdp_section_start() test [9]:
+
+test_sdp_section_start() test [10]:
+
+test_sdp_section_start() test [11]:
+
+test_sdp_section_start() test [12]:
+
+test_sdp_section_start() test [13]:
+
+test_sdp_section_start() test [14]:
+
+test_sdp_section_start() test [15]:
+
+test_sdp_section_start() test [16]:
+
+test_sdp_section_start() test [17]:
+
+test_sdp_section_start() test [18]:
110 => 96
111 => 97
112 => 98