mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-05 12:16:00 +00:00
Prevent multiple local candidates from being added with the same information and add support for disabling ICE on a per-peer basis.
(closes issue ASTERISK-20088) Reported by: wimpy Review: https://reviewboard.asterisk.org/r/2044/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@370347 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -5468,6 +5468,7 @@ static void copy_socket_data(struct sip_socket *to_sock, const struct sip_socket
|
|||||||
static int dialog_initialize_rtp(struct sip_pvt *dialog)
|
static int dialog_initialize_rtp(struct sip_pvt *dialog)
|
||||||
{
|
{
|
||||||
struct ast_sockaddr bindaddr_tmp;
|
struct ast_sockaddr bindaddr_tmp;
|
||||||
|
struct ast_rtp_engine_ice *ice;
|
||||||
|
|
||||||
if (!sip_methods[dialog->method].need_rtp) {
|
if (!sip_methods[dialog->method].need_rtp) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -5478,11 +5479,20 @@ static int dialog_initialize_rtp(struct sip_pvt *dialog)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ast_test_flag(&dialog->flags[2], SIP_PAGE3_ICE_SUPPORT) && (ice = ast_rtp_instance_get_ice(dialog->rtp))) {
|
||||||
|
ice->stop(dialog->rtp);
|
||||||
|
}
|
||||||
|
|
||||||
if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS) ||
|
if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS) ||
|
||||||
(ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) && (ast_format_cap_has_type(dialog->caps, AST_FORMAT_TYPE_VIDEO)))) {
|
(ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) && (ast_format_cap_has_type(dialog->caps, AST_FORMAT_TYPE_VIDEO)))) {
|
||||||
if (!(dialog->vrtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) {
|
if (!(dialog->vrtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ast_test_flag(&dialog->flags[2], SIP_PAGE3_ICE_SUPPORT) && (ice = ast_rtp_instance_get_ice(dialog->vrtp))) {
|
||||||
|
ice->stop(dialog->vrtp);
|
||||||
|
}
|
||||||
|
|
||||||
ast_rtp_instance_set_timeout(dialog->vrtp, dialog->rtptimeout);
|
ast_rtp_instance_set_timeout(dialog->vrtp, dialog->rtptimeout);
|
||||||
ast_rtp_instance_set_hold_timeout(dialog->vrtp, dialog->rtpholdtimeout);
|
ast_rtp_instance_set_hold_timeout(dialog->vrtp, dialog->rtpholdtimeout);
|
||||||
ast_rtp_instance_set_keepalive(dialog->vrtp, dialog->rtpkeepalive);
|
ast_rtp_instance_set_keepalive(dialog->vrtp, dialog->rtpkeepalive);
|
||||||
@@ -5494,6 +5504,11 @@ static int dialog_initialize_rtp(struct sip_pvt *dialog)
|
|||||||
if (!(dialog->trtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) {
|
if (!(dialog->trtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ast_test_flag(&dialog->flags[2], SIP_PAGE3_ICE_SUPPORT) && (ice = ast_rtp_instance_get_ice(dialog->trtp))) {
|
||||||
|
ice->stop(dialog->trtp);
|
||||||
|
}
|
||||||
|
|
||||||
/* Do not timeout text as its not constant*/
|
/* Do not timeout text as its not constant*/
|
||||||
ast_rtp_instance_set_keepalive(dialog->trtp, dialog->rtpkeepalive);
|
ast_rtp_instance_set_keepalive(dialog->trtp, dialog->rtpkeepalive);
|
||||||
|
|
||||||
@@ -12417,7 +12432,7 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
|
|||||||
ast_verbose("Video is at %s\n", ast_sockaddr_stringify(&vdest));
|
ast_verbose("Video is at %s\n", ast_sockaddr_stringify(&vdest));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!doing_directmedia) {
|
if (!doing_directmedia && ast_test_flag(&p->flags[2], SIP_PAGE3_ICE_SUPPORT)) {
|
||||||
add_ice_to_sdp(p->vrtp, &a_video);
|
add_ice_to_sdp(p->vrtp, &a_video);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -12434,7 +12449,7 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
|
|||||||
ast_verbose("Text is at %s\n", ast_sockaddr_stringify(&taddr));
|
ast_verbose("Text is at %s\n", ast_sockaddr_stringify(&taddr));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!doing_directmedia) {
|
if (!doing_directmedia && ast_test_flag(&p->flags[2], SIP_PAGE3_ICE_SUPPORT)) {
|
||||||
add_ice_to_sdp(p->trtp, &a_text);
|
add_ice_to_sdp(p->trtp, &a_text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -12533,7 +12548,7 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
|
|||||||
if (min_text_packet_size)
|
if (min_text_packet_size)
|
||||||
ast_str_append(&a_text, 0, "a=ptime:%d\r\n", min_text_packet_size);
|
ast_str_append(&a_text, 0, "a=ptime:%d\r\n", min_text_packet_size);
|
||||||
|
|
||||||
if (!doing_directmedia) {
|
if (!doing_directmedia && ast_test_flag(&p->flags[2], SIP_PAGE3_ICE_SUPPORT)) {
|
||||||
add_ice_to_sdp(p->rtp, &a_audio);
|
add_ice_to_sdp(p->rtp, &a_audio);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29752,6 +29767,8 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
|
|||||||
ast_set2_flag(&peer->flags[2], ast_true(v->value), SIP_PAGE3_SNOM_AOC);
|
ast_set2_flag(&peer->flags[2], ast_true(v->value), SIP_PAGE3_SNOM_AOC);
|
||||||
} else if (!strcasecmp(v->name, "avpf")) {
|
} else if (!strcasecmp(v->name, "avpf")) {
|
||||||
ast_set2_flag(&peer->flags[2], ast_true(v->value), SIP_PAGE3_USE_AVPF);
|
ast_set2_flag(&peer->flags[2], ast_true(v->value), SIP_PAGE3_USE_AVPF);
|
||||||
|
} else if (!strcasecmp(v->name, "icesupport")) {
|
||||||
|
ast_set2_flag(&peer->flags[2], ast_true(v->value), SIP_PAGE3_ICE_SUPPORT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30285,6 +30302,7 @@ static int reload_config(enum channelreloadreason reason)
|
|||||||
ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */
|
ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */
|
||||||
ast_set_flag(&global_flags[0], SIP_DIRECT_MEDIA); /*!< Allow re-invites */
|
ast_set_flag(&global_flags[0], SIP_DIRECT_MEDIA); /*!< Allow re-invites */
|
||||||
ast_set_flag(&global_flags[2], SIP_PAGE3_NAT_AUTO_RPORT); /*!< Default to nat=auto_force_rport */
|
ast_set_flag(&global_flags[2], SIP_PAGE3_NAT_AUTO_RPORT); /*!< Default to nat=auto_force_rport */
|
||||||
|
ast_set_flag(&global_flags[2], SIP_PAGE3_ICE_SUPPORT); /*!< Default to enabling ICE support */
|
||||||
ast_copy_string(default_engine, DEFAULT_ENGINE, sizeof(default_engine));
|
ast_copy_string(default_engine, DEFAULT_ENGINE, sizeof(default_engine));
|
||||||
ast_copy_string(default_parkinglot, DEFAULT_PARKINGLOT, sizeof(default_parkinglot));
|
ast_copy_string(default_parkinglot, DEFAULT_PARKINGLOT, sizeof(default_parkinglot));
|
||||||
|
|
||||||
@@ -30841,6 +30859,8 @@ static int reload_config(enum channelreloadreason reason)
|
|||||||
}
|
}
|
||||||
} else if (!strcasecmp(v->name, "snom_aoc_enabled")) {
|
} else if (!strcasecmp(v->name, "snom_aoc_enabled")) {
|
||||||
ast_set2_flag(&global_flags[2], ast_true(v->value), SIP_PAGE3_SNOM_AOC);
|
ast_set2_flag(&global_flags[2], ast_true(v->value), SIP_PAGE3_SNOM_AOC);
|
||||||
|
} else if (!strcasecmp(v->name, "icesupport")) {
|
||||||
|
ast_set2_flag(&global_flags[2], ast_true(v->value), SIP_PAGE3_ICE_SUPPORT);
|
||||||
} else if (!strcasecmp(v->name, "parkinglot")) {
|
} else if (!strcasecmp(v->name, "parkinglot")) {
|
||||||
ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
|
ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
|
||||||
}
|
}
|
||||||
|
@@ -371,10 +371,11 @@
|
|||||||
#define SIP_PAGE3_NAT_AUTO_COMEDIA (1 << 3) /*!< DGP: Set SIP_PAGE2_SYMMETRICRTP when NAT is detected */
|
#define SIP_PAGE3_NAT_AUTO_COMEDIA (1 << 3) /*!< DGP: Set SIP_PAGE2_SYMMETRICRTP when NAT is detected */
|
||||||
#define SIP_PAGE3_DIRECT_MEDIA_OUTGOING (1 << 4) /*!< DP: Only send direct media reinvites on outgoing calls */
|
#define SIP_PAGE3_DIRECT_MEDIA_OUTGOING (1 << 4) /*!< DP: Only send direct media reinvites on outgoing calls */
|
||||||
#define SIP_PAGE3_USE_AVPF (1 << 5) /*!< DGP: Support a minimal AVPF-compatible profile */
|
#define SIP_PAGE3_USE_AVPF (1 << 5) /*!< DGP: Support a minimal AVPF-compatible profile */
|
||||||
|
#define SIP_PAGE3_ICE_SUPPORT (1 << 6) /*!< DGP: Enable ICE support */
|
||||||
|
|
||||||
#define SIP_PAGE3_FLAGS_TO_COPY \
|
#define SIP_PAGE3_FLAGS_TO_COPY \
|
||||||
(SIP_PAGE3_SNOM_AOC | SIP_PAGE3_SRTP_TAG_32 | SIP_PAGE3_NAT_AUTO_RPORT | SIP_PAGE3_NAT_AUTO_COMEDIA | \
|
(SIP_PAGE3_SNOM_AOC | SIP_PAGE3_SRTP_TAG_32 | SIP_PAGE3_NAT_AUTO_RPORT | SIP_PAGE3_NAT_AUTO_COMEDIA | \
|
||||||
SIP_PAGE3_DIRECT_MEDIA_OUTGOING | SIP_PAGE3_USE_AVPF)
|
SIP_PAGE3_DIRECT_MEDIA_OUTGOING | SIP_PAGE3_USE_AVPF | SIP_PAGE3_ICE_SUPPORT)
|
||||||
|
|
||||||
#define CHECK_AUTH_BUF_INITLEN 256
|
#define CHECK_AUTH_BUF_INITLEN 256
|
||||||
|
|
||||||
|
@@ -900,6 +900,11 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
|
|||||||
; this feature.
|
; this feature.
|
||||||
;
|
;
|
||||||
; subscribe_network_change_event = yes ; on by default
|
; subscribe_network_change_event = yes ; on by default
|
||||||
|
;
|
||||||
|
; ICE/STUN/TURN usage can be disabled globally or on a per-peer basis using the icesupport
|
||||||
|
; configuration option. When set to yes ICE support is enabled. When set to no it is disabled.
|
||||||
|
;
|
||||||
|
; icesupport = no
|
||||||
|
|
||||||
;----------------------------------- MEDIA HANDLING --------------------------------
|
;----------------------------------- MEDIA HANDLING --------------------------------
|
||||||
; By default, Asterisk tries to re-invite media streams to an optimal path. If there's
|
; By default, Asterisk tries to re-invite media streams to an optimal path. If there's
|
||||||
|
@@ -547,18 +547,32 @@ static void ast_rtp_ice_lite(struct ast_rtp_instance *instance)
|
|||||||
pj_ice_sess_change_role(rtp->ice, PJ_ICE_SESS_ROLE_CONTROLLING);
|
pj_ice_sess_change_role(rtp->ice, PJ_ICE_SESS_ROLE_CONTROLLING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ice_candidate_cmp(void *obj, void *arg, int flags)
|
||||||
|
{
|
||||||
|
struct ast_rtp_engine_ice_candidate *candidate1 = obj, *candidate2 = arg;
|
||||||
|
|
||||||
|
if ((strcmp(candidate1->foundation, candidate2->foundation)) ||
|
||||||
|
(candidate1->id != candidate2->id) ||
|
||||||
|
(ast_sockaddr_cmp(&candidate1->address, &candidate2->address)) ||
|
||||||
|
(candidate1->type != candidate1->type)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CMP_MATCH | CMP_STOP;
|
||||||
|
}
|
||||||
|
|
||||||
static void ast_rtp_ice_add_cand(struct ast_rtp *rtp, unsigned comp_id, unsigned transport_id, pj_ice_cand_type type, pj_uint16_t local_pref,
|
static void ast_rtp_ice_add_cand(struct ast_rtp *rtp, unsigned comp_id, unsigned transport_id, pj_ice_cand_type type, pj_uint16_t local_pref,
|
||||||
const pj_sockaddr_t *addr, const pj_sockaddr_t *base_addr, const pj_sockaddr_t *rel_addr, int addr_len)
|
const pj_sockaddr_t *addr, const pj_sockaddr_t *base_addr, const pj_sockaddr_t *rel_addr, int addr_len)
|
||||||
{
|
{
|
||||||
pj_str_t foundation;
|
pj_str_t foundation;
|
||||||
struct ast_rtp_engine_ice_candidate *candidate;
|
struct ast_rtp_engine_ice_candidate *candidate, *existing;
|
||||||
char address[PJ_INET6_ADDRSTRLEN];
|
char address[PJ_INET6_ADDRSTRLEN];
|
||||||
|
|
||||||
pj_thread_register_check();
|
pj_thread_register_check();
|
||||||
|
|
||||||
pj_ice_calc_foundation(rtp->ice->pool, &foundation, type, addr);
|
pj_ice_calc_foundation(rtp->ice->pool, &foundation, type, addr);
|
||||||
|
|
||||||
if (!rtp->local_candidates && !(rtp->local_candidates = ao2_container_alloc(1, NULL, NULL))) {
|
if (!rtp->local_candidates && !(rtp->local_candidates = ao2_container_alloc(1, NULL, ice_candidate_cmp))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -586,6 +600,12 @@ static void ast_rtp_ice_add_cand(struct ast_rtp *rtp, unsigned comp_id, unsigned
|
|||||||
candidate->type = AST_RTP_ICE_CANDIDATE_TYPE_RELAYED;
|
candidate->type = AST_RTP_ICE_CANDIDATE_TYPE_RELAYED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((existing = ao2_find(rtp->local_candidates, candidate, OBJ_POINTER))) {
|
||||||
|
ao2_ref(existing, -1);
|
||||||
|
ao2_ref(candidate, -1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (pj_ice_sess_add_cand(rtp->ice, comp_id, transport_id, type, local_pref, &foundation, addr, addr, rel_addr, addr_len, NULL) != PJ_SUCCESS) {
|
if (pj_ice_sess_add_cand(rtp->ice, comp_id, transport_id, type, local_pref, &foundation, addr, addr, rel_addr, addr_len, NULL) != PJ_SUCCESS) {
|
||||||
ao2_ref(candidate, -1);
|
ao2_ref(candidate, -1);
|
||||||
return;
|
return;
|
||||||
|
Reference in New Issue
Block a user