diff options
author | Pau Espin Pedrol <pespin@sysmocom.de> | 2020-08-28 20:21:55 +0200 |
---|---|---|
committer | Pau Espin Pedrol <pespin@sysmocom.de> | 2020-09-07 15:55:30 +0200 |
commit | 9dc73593a3c1e7c5cc1b0a42c551d616f29762f9 (patch) | |
tree | 36b8cf1c2ccc8e28c779363dc73f5624c36aae7d | |
parent | ae6858bddf2201f1ba31d0b4cd996e14747c2be5 (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.c | 60 | ||||
-rw-r--r-- | tests/mgcp_client/mgcp_client_test.c | 79 | ||||
-rw-r--r-- | tests/mgcp_client/mgcp_client_test.err | 57 | ||||
-rw-r--r-- | tests/mgcp_client/mgcp_client_test.ok | 32 |
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 |