[Asterisk-code-review] res pjsip: Re-use IP version of signaling (SIP) for media (R... (asterisk[14])
Alexander Traud
asteriskteam at digium.com
Sat Aug 20 14:24:53 CDT 2016
Alexander Traud has uploaded a new change for review.
https://gerrit.asterisk.org/3664
Change subject: res_pjsip: Re-use IP version of signaling (SIP) for media (RTP).
......................................................................
res_pjsip: Re-use IP version of signaling (SIP) for media (RTP).
Previously, the parameter rtp_ipv6 had to be configured for each endpoint in the
file pjsip.conf, in advance, before a SIP client connected to Asterisk. That
defeated the idea of an IPv4/IPv6 Dual Stack server, for which the IP versions
of the client is *not* known in advance. This was no issue for the channel
driver chan_sip and therefore this was changed in res_pjsip only.
ASTERISK-26309 #close
Change-Id: I01a85a8c6723fcc12e86139f80e090e2078d04bb
---
M configs/samples/pjsip.conf.sample
M contrib/scripts/sip_to_pjsip/sip_to_pjsip.py
M res/res_pjsip_sdp_rtp.c
M res/res_pjsip_session.c
M res/res_pjsip_t38.c
5 files changed, 78 insertions(+), 32 deletions(-)
git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/64/3664/1
diff --git a/configs/samples/pjsip.conf.sample b/configs/samples/pjsip.conf.sample
index 0d1c039..6d749aa 100644
--- a/configs/samples/pjsip.conf.sample
+++ b/configs/samples/pjsip.conf.sample
@@ -112,9 +112,6 @@
; the prefix "external_" will only apply to communication with addresses
; outside the range set with "local_net=".
;
-; IPv6: For endpoints using IPv6, remember to set "rtp_ipv6=yes" so that the RTP
-; engine will also be able to bind to an IPv6 address.
-;
; You can have more than one of any type of transport, as long as it doesn't
; use the same resources (bind address, port, etc) as the others.
@@ -294,8 +291,6 @@
; If using the TLS enabled transport, you may want the "media_encryption=sdes"
; option to additionally enable SRTP, though they are not mutually inclusive.
;
-; Use the "rtp_ipv6=yes" option if you want to utilize RTP over an ipv6 transport.
-;
; If this endpoint were remote, and it was using a transport configured for NAT
; then you likely want to use "direct_media=no" to prevent audio issues.
@@ -314,8 +309,6 @@
;
;transport=transport-tls
;media_encryption=sdes
-;transport=transport-udp-ipv6
-;rtp_ipv6=yes
;transport=transport-udp-nat
;direct_media=no
;
@@ -646,7 +639,6 @@
; must be provided (default: "")
;rewrite_contact=no ; Allow Contact header to be rewritten with the source
; IP address port (default: "no")
-;rtp_ipv6=no ; Allow use of IPv6 for RTP traffic (default: "no")
;rtp_symmetric=no ; Enforce that RTP must be symmetric (default: "no")
;send_diversion=yes ; Send the Diversion header conveying the diversion
; information to the called user agent (default: "yes")
@@ -699,8 +691,6 @@
; (default: "0")
;t38_udptl_nat=no ; Whether NAT support is enabled on UDPTL sessions
; (default: "no")
-;t38_udptl_ipv6=no ; Whether IPv6 is used for UDPTL Sessions (default:
- ; "no")
;tone_zone= ; Set which country s indications to use for channels created
; for this endpoint (default: "")
;language= ; Set the default language to use for channels created for this
diff --git a/contrib/scripts/sip_to_pjsip/sip_to_pjsip.py b/contrib/scripts/sip_to_pjsip/sip_to_pjsip.py
index ee01edf..898f226 100755
--- a/contrib/scripts/sip_to_pjsip/sip_to_pjsip.py
+++ b/contrib/scripts/sip_to_pjsip/sip_to_pjsip.py
@@ -368,8 +368,7 @@
###############################################################################
# options in pjsip.conf on an endpoint that have no sip.conf equivalent:
-# type, rtp_ipv6, 100rel, trust_id_outbound, aggregate_mwi,
-# connected_line_method
+# type, 100rel, trust_id_outbound, aggregate_mwi, connected_line_method
# known sip.conf peer keys that can be mapped to a pjsip.conf section/key
peer_map = [
diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c
index 6610ef1..ef9faec 100644
--- a/res/res_pjsip_sdp_rtp.c
+++ b/res/res_pjsip_sdp_rtp.c
@@ -1074,8 +1074,22 @@
(!use_override_prefs && !ast_format_cap_has_type(session->endpoint->media.codecs, media_type))) {
/* If no type formats are configured don't add a stream */
return 0;
- } else if (!session_media->rtp && create_rtp(session, session_media, session->endpoint->media.rtp.ipv6)) {
- return -1;
+ } else if (!session_media->rtp) {
+ unsigned int ip6;
+
+ if (session->contact) {
+ /* IP6 addresses contain at least one colon. IP4 do not, because
+ * a port is stored in another variable: contact->via_port
+ */
+ ip6 = strstr(session->contact->via_addr, ":") ? 1 : 0;
+ } else {
+ ast_log(LOG_ERROR, "Cannot determine whether to use IP4 or IP6; falling back to rtp_ipv6 of endpoint. Please, report as issue!\n");
+ ip6 = session->endpoint->media.rtp.ipv6;
+ }
+
+ if (create_rtp(session, session_media, ip6)) {
+ return -1;
+ }
}
if (!(media = pj_pool_zalloc(pool, sizeof(struct pjmedia_sdp_media))) ||
@@ -1101,10 +1115,11 @@
}
/* Add connection level details */
+ ast_rtp_instance_get_local_address(session_media->rtp, &addr);
if (direct_media_enabled) {
hostip = ast_sockaddr_stringify_fmt(&session_media->direct_media_addr, AST_SOCKADDR_STR_ADDR);
} else if (ast_strlen_zero(session->endpoint->media.address)) {
- hostip = ast_sip_get_host_ip_string(session->endpoint->media.rtp.ipv6 ? pj_AF_INET6() : pj_AF_INET());
+ hostip = ast_sip_get_host_ip_string((ast_sockaddr_is_ipv6(&addr)) ? pj_AF_INET6() : pj_AF_INET());
} else {
hostip = session->endpoint->media.address;
}
@@ -1115,9 +1130,8 @@
}
media->conn->net_type = STR_IN;
- media->conn->addr_type = session->endpoint->media.rtp.ipv6 ? STR_IP6 : STR_IP4;
+ media->conn->addr_type = (ast_sockaddr_is_ipv6(&addr)) ? STR_IP6 : STR_IP4;
pj_strdup2(pool, &media->conn->addr, hostip);
- ast_rtp_instance_get_local_address(session_media->rtp, &addr);
media->desc.port = direct_media_enabled ? ast_sockaddr_port(&session_media->direct_media_addr) : (pj_uint16_t) ast_sockaddr_port(&addr);
media->desc.port_count = 1;
@@ -1252,8 +1266,24 @@
}
/* Create an RTP instance if need be */
- if (!session_media->rtp && create_rtp(session, session_media, session->endpoint->media.rtp.ipv6)) {
- return -1;
+ if (!session_media->rtp) {
+ unsigned int ip6;
+
+ if (remote_stream->conn) { /* query RTP, but c= is optional */
+ ip6 = pj_stricmp2(&remote_stream->conn->addr_type, "IP4");
+ } else if (session->contact) { /* query SIP */
+ /* IP6 addresses contain at least one colon. IP4 do not, because
+ * a port is stored in another variable: contact->via_port
+ */
+ ip6 = strstr(session->contact->via_addr, ":") ? 1 : 0;
+ } else {
+ ast_log(LOG_ERROR, "Cannot determine whether to use IP4 or IP6; falling back to rtp_ipv6 of endpoint. Please, report as issue!\n");
+ ip6 = session->endpoint->media.rtp.ipv6;
+ }
+
+ if (create_rtp(session, session_media, ip6)) {
+ return -1;
+ }
}
res = setup_media_encryption(session, session_media, remote, remote_stream);
diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index 315393f..af58c12 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -2954,13 +2954,25 @@
}
}
} else {
+ unsigned int ip6;
+
+ if (session->contact) {
+ /* IP6 addresses contain at least one colon. IP4 do not, because
+ * a port is stored in another variable: contact->via_port
+ */
+ ip6 = strstr(session->contact->via_addr, ":") ? 1 : 0;
+ } else {
+ ast_log(LOG_ERROR, "Cannot determine whether to use IP4 or IP6; falling back to rtp_ipv6 of endpoint. Please, report as issue!\n");
+ ip6 = session->endpoint->media.rtp.ipv6;
+ }
+
local->origin.net_type = STR_IN;
- local->origin.addr_type = session->endpoint->media.rtp.ipv6 ? STR_IP6 : STR_IP4;
+ local->origin.addr_type = ip6 ? STR_IP6 : STR_IP4;
if (!ast_strlen_zero(session->endpoint->media.address)) {
pj_strdup2(inv->pool_prov, &local->origin.addr, session->endpoint->media.address);
} else {
- pj_strdup2(inv->pool_prov, &local->origin.addr, ast_sip_get_host_ip_string(session->endpoint->media.rtp.ipv6 ? pj_AF_INET6() : pj_AF_INET()));
+ pj_strdup2(inv->pool_prov, &local->origin.addr, ast_sip_get_host_ip_string(ip6 ? pj_AF_INET6() : pj_AF_INET()));
}
}
diff --git a/res/res_pjsip_t38.c b/res/res_pjsip_t38.c
index 76720ac..b75c22c 100644
--- a/res/res_pjsip_t38.c
+++ b/res/res_pjsip_t38.c
@@ -255,12 +255,24 @@
/*! \brief Initializes UDPTL support on a session, only done when actually needed */
static int t38_initialize_session(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
{
+ unsigned int ip6;
+
if (session_media->udptl) {
return 0;
}
+ if (session->contact) {
+ /* IP6 addresses contain at least one colon. IP4 do not, because
+ * a port is stored in another variable: contact->via_port
+ */
+ ip6 = strstr(session->contact->via_addr, ":") ? 1 : 0;
+ } else {
+ ast_log(LOG_ERROR, "Cannot determine whether to use IP4 or IP6; falling back to t38_udptl_ipv6 of endpoint. Please, report as issue!\n");
+ ip6 = session->endpoint->media.t38.ipv6;
+ }
+
if (!(session_media->udptl = ast_udptl_new_with_bindaddr(NULL, NULL, 0,
- session->endpoint->media.t38.ipv6 ? &address_ipv6 : &address_ipv4))) {
+ ip6 ? &address_ipv6 : &address_ipv4))) {
return -1;
}
@@ -700,14 +712,6 @@
return -1;
}
- /* Check the address family to make sure it matches configured */
- if ((ast_sockaddr_is_ipv6(addrs) && !session->endpoint->media.t38.ipv6) ||
- (ast_sockaddr_is_ipv4(addrs) && session->endpoint->media.t38.ipv6)) {
- /* The address does not match configured */
- ast_debug(3, "Declining, provided host does not match configured address family\n");
- return -1;
- }
-
return 1;
}
@@ -731,6 +735,7 @@
struct ast_sockaddr addr;
char tmp[512];
pj_str_t stmp;
+ unsigned int ip6;
if (!session->endpoint->media.t38.enabled) {
ast_debug(3, "Not creating outgoing SDP stream: T.38 not enabled\n");
@@ -754,8 +759,18 @@
media->desc.media = pj_str(session_media->stream_type);
media->desc.transport = STR_UDPTL;
+ if (session->contact) {
+ /* IP6 addresses contain at least one colon. IP4 do not, because
+ * a port is stored in another variable: contact->via_port
+ */
+ ip6 = strstr(session->contact->via_addr, ":") ? 1 : 0;
+ } else {
+ ast_log(LOG_ERROR, "Cannot determine whether to use IP4 or IP6; falling back to t38_udptl_ipv6 of endpoint. Please, report as issue!\n");
+ ip6 = session->endpoint->media.t38.ipv6;
+ }
+
if (ast_strlen_zero(session->endpoint->media.address)) {
- hostip = ast_sip_get_host_ip_string(session->endpoint->media.t38.ipv6 ? pj_AF_INET6() : pj_AF_INET());
+ hostip = ast_sip_get_host_ip_string(ip6 ? pj_AF_INET6() : pj_AF_INET());
} else {
hostip = session->endpoint->media.address;
}
@@ -766,7 +781,7 @@
}
media->conn->net_type = STR_IN;
- media->conn->addr_type = session->endpoint->media.t38.ipv6 ? STR_IP6 : STR_IP4;
+ media->conn->addr_type = ip6 ? STR_IP6 : STR_IP4;
pj_strdup2(pool, &media->conn->addr, hostip);
ast_udptl_get_us(session_media->udptl, &addr);
media->desc.port = (pj_uint16_t) ast_sockaddr_port(&addr);
--
To view, visit https://gerrit.asterisk.org/3664
To unsubscribe, visit https://gerrit.asterisk.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I01a85a8c6723fcc12e86139f80e090e2078d04bb
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: 14
Gerrit-Owner: Alexander Traud <pabstraud at compuserve.com>
More information about the asterisk-code-review
mailing list