res_rtp_asterisk: ICE server-reflexive candidates (srflx) with Dual-Stack.
authorAlexander Traud <pabstraud@compuserve.com>
Tue, 21 Nov 2017 12:39:34 +0000 (13:39 +0100)
committerAlexander Traud <pabstraud@compuserve.com>
Wed, 22 Nov 2017 09:06:45 +0000 (03:06 -0600)
Previously, Asterisk sent srflx only when configured exclusively for IPv4. Now,
srflx is gathered and sent via SDP, even when Asterisk is enabled for
Dual Stack (IPv4+IPv6) and an IPv4 interface is available/used.

ASTERISK-27437

Change-Id: Ie07d8e2bfa7b6fe06fcdc73d390a7a9a4d8c0bc1

res/res_rtp_asterisk.c

index 15ca150..839753e 100644 (file)
@@ -3193,8 +3193,8 @@ static void rtp_add_candidates_to_ice(struct ast_rtp_instance *instance, struct
        }
 
        /* If configured to use a STUN server to get our external mapped address do so */
-       if (stunaddr.sin_addr.s_addr && count && ast_sockaddr_is_ipv4(addr)
-               && !stun_address_is_blacklisted(addr)) {
+       if (count && stunaddr.sin_addr.s_addr && !stun_address_is_blacklisted(addr) &&
+               (ast_sockaddr_is_ipv4(addr) || ast_sockaddr_is_any(addr))) {
                struct sockaddr_in answer;
                int rsp;
 
@@ -3208,27 +3208,40 @@ static void rtp_add_candidates_to_ice(struct ast_rtp_instance *instance, struct
                ao2_lock(instance);
                if (!rsp) {
                        pj_sockaddr base;
-                       pj_sockaddr ext;
-                       pj_str_t mapped = pj_str(ast_strdupa(ast_inet_ntoa(answer.sin_addr)));
-                       int srflx = 1;
 
-                       /* Use the first local host candidate as the base */
-                       pj_sockaddr_cp(&base, &address[basepos]);
-
-                       pj_sockaddr_init(pj_AF_INET(), &ext, &mapped, ntohs(answer.sin_port));
-
-                       /* If the returned address is the same as one of our host candidates, don't send the srflx */
-                       for (pos = 0; pos < count; pos++) {
-                               if ((pj_sockaddr_cmp(&address[pos], &ext) == 0) && !rtp_address_is_ice_blacklisted(&address[pos])) {
-                                       srflx = 0;
+                       /* Use the first local IPv4 host candidate as the base */
+                       for (pos = basepos; pos < count; pos++) {
+                               if (address[pos].addr.sa_family == PJ_AF_INET &&
+                                       !rtp_address_is_ice_blacklisted(&address[pos])) {
+                                       pj_sockaddr_cp(&base, &address[pos]);
                                        break;
                                }
                        }
 
-                       if (srflx) {
-                               ast_rtp_ice_add_cand(instance, rtp, component, transport,
-                                       PJ_ICE_CAND_TYPE_SRFLX, 65535, &ext, &base, &base,
-                                       pj_sockaddr_get_len(&ext));
+                       if (pos < count) {
+                               pj_sockaddr ext;
+                               pj_str_t mapped = pj_str(ast_strdupa(ast_inet_ntoa(answer.sin_addr)));
+                               int srflx = 1;
+
+                               pj_sockaddr_init(pj_AF_INET(), &ext, &mapped, ntohs(answer.sin_port));
+
+                               /*
+                                * If the returned address is the same as one of our host
+                                * candidates, don't send the srflx
+                                */
+                               for (pos = 0; pos < count; pos++) {
+                                       if (pj_sockaddr_cmp(&address[pos], &ext) == 0 &&
+                                               !rtp_address_is_ice_blacklisted(&address[pos])) {
+                                               srflx = 0;
+                                               break;
+                                       }
+                               }
+
+                               if (srflx) {
+                                       ast_rtp_ice_add_cand(instance, rtp, component, transport,
+                                               PJ_ICE_CAND_TYPE_SRFLX, 65535, &ext, &base, &base,
+                                               pj_sockaddr_get_len(&ext));
+                               }
                        }
                }
        }