diff options
author | Alexander Traud <pabstraud@compuserve.com> | 2017-11-21 13:39:34 +0100 |
---|---|---|
committer | Alexander Traud <pabstraud@compuserve.com> | 2017-11-22 03:07:04 -0600 |
commit | 73a9b88110525713648e1aec8b6786df24f71018 (patch) | |
tree | 1da3ba517ab18c0341ed9d5c147b22b94ba55349 | |
parent | 3e625465116a0fb985d94bcd1eb4096a85026307 (diff) |
res_rtp_asterisk: ICE server-reflexive candidates (srflx) with Dual-Stack.
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
-rw-r--r-- | res/res_rtp_asterisk.c | 49 |
1 files changed, 31 insertions, 18 deletions
diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c index 15ca1503b..839753e41 100644 --- a/res/res_rtp_asterisk.c +++ b/res/res_rtp_asterisk.c @@ -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)); + } } } } |