chan_sip: Fix RTCP port for SRFLX ICE candidates

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/


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/11@402345 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Kinsey Moore
2013-11-01 12:31:49 +00:00
parent 45a6969b3c
commit 2d5debf45c
3 changed files with 28 additions and 19 deletions

View File

@@ -12616,7 +12616,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));
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");

View File

@@ -322,10 +322,16 @@ enum ast_rtp_ice_candidate_type {
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 */
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 */

View File

@@ -177,9 +177,6 @@ static int worker_terminate;
#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 */
@@ -541,9 +538,9 @@ static void ast_rtp_ice_start(struct ast_rtp_instance *instance)
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);
} 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);
}
@@ -1478,7 +1475,7 @@ static int __rtp_recvfrom(struct ast_rtp_instance *instance, void *buf, size_t s
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) {
@@ -1530,7 +1527,7 @@ static int __rtp_sendto(struct ast_rtp_instance *instance, void *buf, size_t siz
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;
}
@@ -1842,7 +1839,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_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
@@ -2008,7 +2005,7 @@ static int ast_rtp_dtmf_begin(struct ast_rtp_instance *instance, char digit)
strerror(errno));
}
#ifdef USE_PJPROJECT
update_address_with_ice_candidate(rtp, COMPONENT_RTP, &remote_address);
update_address_with_ice_candidate(rtp, AST_RTP_ICE_COMPONENT_RTP, &remote_address);
#endif
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",
@@ -2060,7 +2057,7 @@ static int ast_rtp_dtmf_continuation(struct ast_rtp_instance *instance)
}
#ifdef USE_PJPROJECT
update_address_with_ice_candidate(rtp, COMPONENT_RTP, &remote_address);
update_address_with_ice_candidate(rtp, AST_RTP_ICE_COMPONENT_RTP, &remote_address);
#endif
if (rtp_debug_test_addr(&remote_address)) {
@@ -2138,7 +2135,7 @@ static int ast_rtp_dtmf_end_with_duration(struct ast_rtp_instance *instance, cha
}
#ifdef USE_PJPROJECT
update_address_with_ice_candidate(rtp, COMPONENT_RTP, &remote_address);
update_address_with_ice_candidate(rtp, AST_RTP_ICE_COMPONENT_RTP, &remote_address);
#endif
if (rtp_debug_test_addr(&remote_address)) {
@@ -2304,7 +2301,7 @@ static int ast_rtcp_write_rr(struct ast_rtp_instance *instance)
rtp->rtcp->rr_count++;
#ifdef USE_PJPROJECT
update_address_with_ice_candidate(rtp, COMPONENT_RTCP, &remote_address);
update_address_with_ice_candidate(rtp, AST_RTP_ICE_COMPONENT_RTCP, &remote_address);
#endif
if (rtcp_debug_test_addr(&remote_address)) {
@@ -2417,7 +2414,7 @@ static int ast_rtcp_write_sr(struct ast_rtp_instance *instance)
rtp->rtcp->lastsrtxcount = rtp->txcount;
#ifdef USE_PJPROJECT
update_address_with_ice_candidate(rtp, COMPONENT_RTCP, &remote_address);
update_address_with_ice_candidate(rtp, AST_RTP_ICE_COMPONENT_RTCP, &remote_address);
#endif
if (rtcp_debug_test_addr(&rtp->rtcp->them)) {
@@ -2608,7 +2605,7 @@ static int ast_rtp_raw_write(struct ast_rtp_instance *instance, struct ast_frame
}
#ifdef USE_PJPROJECT
update_address_with_ice_candidate(rtp, COMPONENT_RTP, &remote_address);
update_address_with_ice_candidate(rtp, AST_RTP_ICE_COMPONENT_RTP, &remote_address);
#endif
if (rtp_debug_test_addr(&remote_address)) {
@@ -3489,7 +3486,7 @@ static int bridge_p2p_rtp_write(struct ast_rtp_instance *instance, unsigned int
}
#ifdef USE_PJPROJECT
update_address_with_ice_candidate(rtp, COMPONENT_RTP, &remote_address);
update_address_with_ice_candidate(rtp, AST_RTP_ICE_COMPONENT_RTP, &remote_address);
#endif
if (rtp_debug_test_addr(&remote_address)) {
@@ -3949,7 +3946,7 @@ static void ast_rtp_prop_set(struct ast_rtp_instance *instance, enum ast_rtp_pro
#ifdef USE_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
@@ -4242,7 +4239,7 @@ static int ast_rtp_sendcng(struct ast_rtp_instance *instance, int level)
}
#ifdef USE_PJPROJECT
update_address_with_ice_candidate(rtp, COMPONENT_RTP, &remote_address);
update_address_with_ice_candidate(rtp, AST_RTP_ICE_COMPONENT_RTP, &remote_address);
#endif
if (rtp_debug_test_addr(&remote_address)) {