chan_sip: Fix RTCP port for SRFLX ICE candidates
authorKinsey Moore <kmoore@digium.com>
Fri, 1 Nov 2013 12:40:40 +0000 (12:40 +0000)
committerKinsey Moore <kmoore@digium.com>
Fri, 1 Nov 2013 12:40:40 +0000 (12:40 +0000)
This corrects one-way audio between Asterisk and Chrome/jssip as a
result of Asterisk inserting the incorrect RTCP port into RTCP SRFLX
ICE candidates. This also exposes an ICE component enumeration to
extract further details from candidates.

(closes issue ASTERISK-21383)
Reported by: Shaun Clark
Review: https://reviewboard.asterisk.org/r/2967/
........

Merged revisions 402345 from http://svn.asterisk.org/svn/asterisk/branches/11
........

Merged revisions 402348 from http://svn.asterisk.org/svn/asterisk/branches/12

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@402349 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_sip.c
include/asterisk/rtp_engine.h
res/res_rtp_asterisk.c

index 52e7cdd..9364a11 100644 (file)
@@ -12775,7 +12775,13 @@ static void add_ice_to_sdp(struct ast_rtp_instance *instance, struct ast_str **a
        while ((candidate = ao2_iterator_next(&i))) {
                ast_str_append(a_buf, 0, "a=candidate:%s %d %s %d ", candidate->foundation, candidate->id, candidate->transport, candidate->priority);
                ast_str_append(a_buf, 0, "%s ", ast_sockaddr_stringify_host(&candidate->address));
        while ((candidate = ao2_iterator_next(&i))) {
                ast_str_append(a_buf, 0, "a=candidate:%s %d %s %d ", candidate->foundation, candidate->id, candidate->transport, candidate->priority);
                ast_str_append(a_buf, 0, "%s ", ast_sockaddr_stringify_host(&candidate->address));
-               ast_str_append(a_buf, 0, "%s typ ", ast_sockaddr_stringify_port(&candidate->address));
+
+               if (candidate->type == AST_RTP_ICE_CANDIDATE_TYPE_SRFLX
+                       && candidate->id == AST_RTP_ICE_COMPONENT_RTCP) {
+                       ast_str_append(a_buf, 0, "%d typ ", ast_sockaddr_port(&candidate->address) + 1);
+               } else {
+                       ast_str_append(a_buf, 0, "%s typ ", ast_sockaddr_stringify_port(&candidate->address));
+               }
 
                if (candidate->type == AST_RTP_ICE_CANDIDATE_TYPE_HOST) {
                        ast_str_append(a_buf, 0, "host");
 
                if (candidate->type == AST_RTP_ICE_CANDIDATE_TYPE_HOST) {
                        ast_str_append(a_buf, 0, "host");
index 68003f5..9d6c7b4 100644 (file)
@@ -381,10 +381,16 @@ enum ast_rtp_ice_candidate_type {
        AST_RTP_ICE_CANDIDATE_TYPE_RELAYED, /*!< ICE relayed candidate, which represents the address allocated in TURN server. */
 };
 
        AST_RTP_ICE_CANDIDATE_TYPE_RELAYED, /*!< ICE relayed candidate, which represents the address allocated in TURN server. */
 };
 
+/*! \brief ICE component types */
+enum ast_rtp_ice_component_type {
+       AST_RTP_ICE_COMPONENT_RTP = 1,
+       AST_RTP_ICE_COMPONENT_RTCP = 2,
+};
+
 /*! \brief Structure for an ICE candidate */
 struct ast_rtp_engine_ice_candidate {
        char *foundation;                     /*!< Foundation identifier */
 /*! \brief Structure for an ICE candidate */
 struct ast_rtp_engine_ice_candidate {
        char *foundation;                     /*!< Foundation identifier */
-       unsigned int id;                      /*!< Component identifier */
+       enum ast_rtp_ice_component_type id;   /*!< Component identifier */
        char *transport;                      /*!< Transport for the media */
        int priority;                         /*!< Priority which is used if multiple candidates can be used */
        struct ast_sockaddr address;          /*!< Address of the candidate */
        char *transport;                      /*!< Transport for the media */
        int priority;                         /*!< Priority which is used if multiple candidates can be used */
        struct ast_sockaddr address;          /*!< Address of the candidate */
index 075978e..14dbe24 100644 (file)
@@ -174,9 +174,6 @@ static int worker_terminate;
 #define TRANSPORT_TURN_RTP 3
 #define TRANSPORT_TURN_RTCP 4
 
 #define TRANSPORT_TURN_RTP 3
 #define TRANSPORT_TURN_RTCP 4
 
-#define COMPONENT_RTP 1
-#define COMPONENT_RTCP 2
-
 /*! \brief RTP learning mode tracking information */
 struct rtp_learning_info {
        int max_seq;    /*!< The highest sequence number received */
 /*! \brief RTP learning mode tracking information */
 struct rtp_learning_info {
        int max_seq;    /*!< The highest sequence number received */
@@ -542,9 +539,9 @@ static void ast_rtp_ice_start(struct ast_rtp_instance *instance)
                        candidates[cand_cnt].type = PJ_ICE_CAND_TYPE_RELAYED;
                }
 
                        candidates[cand_cnt].type = PJ_ICE_CAND_TYPE_RELAYED;
                }
 
-               if (candidate->id == COMPONENT_RTP && rtp->turn_rtp) {
+               if (candidate->id == AST_RTP_ICE_COMPONENT_RTP && rtp->turn_rtp) {
                        pj_turn_sock_set_perm(rtp->turn_rtp, 1, &candidates[cand_cnt].addr, 1);
                        pj_turn_sock_set_perm(rtp->turn_rtp, 1, &candidates[cand_cnt].addr, 1);
-               } else if (candidate->id == COMPONENT_RTCP && rtp->turn_rtcp) {
+               } else if (candidate->id == AST_RTP_ICE_COMPONENT_RTCP && rtp->turn_rtcp) {
                        pj_turn_sock_set_perm(rtp->turn_rtcp, 1, &candidates[cand_cnt].addr, 1);
                }
 
                        pj_turn_sock_set_perm(rtp->turn_rtcp, 1, &candidates[cand_cnt].addr, 1);
                }
 
@@ -1479,7 +1476,7 @@ static int __rtp_recvfrom(struct ast_rtp_instance *instance, void *buf, size_t s
 
                pj_sockaddr_parse(pj_AF_UNSPEC(), 0, &combined, &address);
 
 
                pj_sockaddr_parse(pj_AF_UNSPEC(), 0, &combined, &address);
 
-               status = pj_ice_sess_on_rx_pkt(rtp->ice, rtcp ? COMPONENT_RTCP : COMPONENT_RTP,
+               status = pj_ice_sess_on_rx_pkt(rtp->ice, rtcp ? AST_RTP_ICE_COMPONENT_RTCP : AST_RTP_ICE_COMPONENT_RTP,
                        rtcp ? TRANSPORT_SOCKET_RTCP : TRANSPORT_SOCKET_RTP, buf, len, &address,
                        pj_sockaddr_get_len(&address));
                if (status != PJ_SUCCESS) {
                        rtcp ? TRANSPORT_SOCKET_RTCP : TRANSPORT_SOCKET_RTP, buf, len, &address,
                        pj_sockaddr_get_len(&address));
                if (status != PJ_SUCCESS) {
@@ -1531,7 +1528,7 @@ static int __rtp_sendto(struct ast_rtp_instance *instance, void *buf, size_t siz
        if (rtp->ice) {
                pj_thread_register_check();
 
        if (rtp->ice) {
                pj_thread_register_check();
 
-               if (pj_ice_sess_send_data(rtp->ice, rtcp ? COMPONENT_RTCP : COMPONENT_RTP, temp, len) == PJ_SUCCESS) {
+               if (pj_ice_sess_send_data(rtp->ice, rtcp ? AST_RTP_ICE_COMPONENT_RTCP : AST_RTP_ICE_COMPONENT_RTP, temp, len) == PJ_SUCCESS) {
                        *ice = 1;
                        return 0;
                }
                        *ice = 1;
                        return 0;
                }
@@ -1841,7 +1838,7 @@ static int ast_rtp_new(struct ast_rtp_instance *instance,
                rtp->ice->user_data = rtp;
 
                /* Add all of the available candidates to the ICE session */
                rtp->ice->user_data = rtp;
 
                /* Add all of the available candidates to the ICE session */
-               rtp_add_candidates_to_ice(instance, rtp, addr, x, COMPONENT_RTP, TRANSPORT_SOCKET_RTP, &ast_rtp_turn_rtp_sock_cb, &rtp->turn_rtp);
+               rtp_add_candidates_to_ice(instance, rtp, addr, x, AST_RTP_ICE_COMPONENT_RTP, TRANSPORT_SOCKET_RTP, &ast_rtp_turn_rtp_sock_cb, &rtp->turn_rtp);
        }
 #endif
 
        }
 #endif
 
@@ -2006,7 +2003,7 @@ static int ast_rtp_dtmf_begin(struct ast_rtp_instance *instance, char digit)
                                ast_sockaddr_stringify(&remote_address),
                                strerror(errno));
                }
                                ast_sockaddr_stringify(&remote_address),
                                strerror(errno));
                }
-               update_address_with_ice_candidate(rtp, COMPONENT_RTP, &remote_address);
+               update_address_with_ice_candidate(rtp, AST_RTP_ICE_COMPONENT_RTP, &remote_address);
                if (rtp_debug_test_addr(&remote_address)) {
                        ast_verbose("Sent RTP DTMF packet to %s%s (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n",
                                    ast_sockaddr_stringify(&remote_address),
                if (rtp_debug_test_addr(&remote_address)) {
                        ast_verbose("Sent RTP DTMF packet to %s%s (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n",
                                    ast_sockaddr_stringify(&remote_address),
@@ -2056,7 +2053,7 @@ static int ast_rtp_dtmf_continuation(struct ast_rtp_instance *instance)
                        strerror(errno));
        }
 
                        strerror(errno));
        }
 
-       update_address_with_ice_candidate(rtp, COMPONENT_RTP, &remote_address);
+       update_address_with_ice_candidate(rtp, AST_RTP_ICE_COMPONENT_RTP, &remote_address);
 
        if (rtp_debug_test_addr(&remote_address)) {
                ast_verbose("Sent RTP DTMF packet to %s%s (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n",
 
        if (rtp_debug_test_addr(&remote_address)) {
                ast_verbose("Sent RTP DTMF packet to %s%s (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n",
@@ -2132,7 +2129,7 @@ static int ast_rtp_dtmf_end_with_duration(struct ast_rtp_instance *instance, cha
                                strerror(errno));
                }
 
                                strerror(errno));
                }
 
-               update_address_with_ice_candidate(rtp, COMPONENT_RTP, &remote_address);
+               update_address_with_ice_candidate(rtp, AST_RTP_ICE_COMPONENT_RTP, &remote_address);
 
                if (rtp_debug_test_addr(&remote_address)) {
                        ast_verbose("Sent RTP DTMF packet to %s%s (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n",
 
                if (rtp_debug_test_addr(&remote_address)) {
                        ast_verbose("Sent RTP DTMF packet to %s%s (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n",
@@ -2383,7 +2380,7 @@ static int ast_rtcp_write_report(struct ast_rtp_instance *instance, int sr)
                rtp->rtcp->rr_count++;
        }
 
                rtp->rtcp->rr_count++;
        }
 
-       update_address_with_ice_candidate(rtp, COMPONENT_RTCP, &remote_address);
+       update_address_with_ice_candidate(rtp, AST_RTP_ICE_COMPONENT_RTCP, &remote_address);
 
        if (rtcp_debug_test_addr(&rtp->rtcp->them)) {
                ast_verbose("* Sent RTCP %s to %s%s\n", sr ? "SR" : "RR",
 
        if (rtcp_debug_test_addr(&rtp->rtcp->them)) {
                ast_verbose("* Sent RTCP %s to %s%s\n", sr ? "SR" : "RR",
@@ -2564,7 +2561,7 @@ static int ast_rtp_raw_write(struct ast_rtp_instance *instance, struct ast_frame
                        }
                }
 
                        }
                }
 
-               update_address_with_ice_candidate(rtp, COMPONENT_RTP, &remote_address);
+               update_address_with_ice_candidate(rtp, AST_RTP_ICE_COMPONENT_RTP, &remote_address);
 
                if (rtp_debug_test_addr(&remote_address)) {
                        ast_verbose("Sent RTP packet to      %s%s (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n",
 
                if (rtp_debug_test_addr(&remote_address)) {
                        ast_verbose("Sent RTP packet to      %s%s (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n",
@@ -3525,7 +3522,7 @@ static int bridge_p2p_rtp_write(struct ast_rtp_instance *instance, unsigned int
                return 0;
        }
 
                return 0;
        }
 
-       update_address_with_ice_candidate(rtp, COMPONENT_RTP, &remote_address);
+       update_address_with_ice_candidate(rtp, AST_RTP_ICE_COMPONENT_RTP, &remote_address);
 
        if (rtp_debug_test_addr(&remote_address)) {
                ast_verbose("Sent RTP P2P packet to %s%s (type %-2.2d, len %-6.6u)\n",
 
        if (rtp_debug_test_addr(&remote_address)) {
                ast_verbose("Sent RTP P2P packet to %s%s (type %-2.2d, len %-6.6u)\n",
@@ -3984,7 +3981,7 @@ static void ast_rtp_prop_set(struct ast_rtp_instance *instance, enum ast_rtp_pro
 
 #ifdef HAVE_PJPROJECT
                        if (rtp->ice) {
 
 #ifdef HAVE_PJPROJECT
                        if (rtp->ice) {
-                               rtp_add_candidates_to_ice(instance, rtp, &rtp->rtcp->us, ast_sockaddr_port(&rtp->rtcp->us), COMPONENT_RTCP, TRANSPORT_SOCKET_RTCP,
+                               rtp_add_candidates_to_ice(instance, rtp, &rtp->rtcp->us, ast_sockaddr_port(&rtp->rtcp->us), AST_RTP_ICE_COMPONENT_RTCP, TRANSPORT_SOCKET_RTCP,
                                                          &ast_rtp_turn_rtcp_sock_cb, &rtp->turn_rtcp);
                        }
 #endif
                                                          &ast_rtp_turn_rtcp_sock_cb, &rtp->turn_rtcp);
                        }
 #endif
@@ -4265,7 +4262,7 @@ static int ast_rtp_sendcng(struct ast_rtp_instance *instance, int level)
                return res;
        }
 
                return res;
        }
 
-       update_address_with_ice_candidate(rtp, COMPONENT_RTP, &remote_address);
+       update_address_with_ice_candidate(rtp, AST_RTP_ICE_COMPONENT_RTP, &remote_address);
 
        if (rtp_debug_test_addr(&remote_address)) {
                ast_verbose("Sent Comfort Noise RTP packet to %s%s (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n",
 
        if (rtp_debug_test_addr(&remote_address)) {
                ast_verbose("Sent Comfort Noise RTP packet to %s%s (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n",