diff --git a/src/include/switch_core_media.h b/src/include/switch_core_media.h index 19a923e64e..105cd50f97 100644 --- a/src/include/switch_core_media.h +++ b/src/include/switch_core_media.h @@ -390,7 +390,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_printf(switch_core_session_t SWITCH_DECLARE(switch_msrp_session_t *) switch_core_media_get_msrp_session(switch_core_session_t *session); SWITCH_DECLARE(void) switch_core_media_set_smode(switch_core_session_t *session, switch_media_type_t type, switch_media_flow_t smode, switch_sdp_type_t sdp_type); - + +SWITCH_DECLARE(void) switch_core_media_set_resolveice(switch_bool_t resolve_ice); +SWITCH_DECLARE(switch_bool_t) switch_core_media_has_resolveice(void); + SWITCH_END_EXTERN_C #endif /* For Emacs: diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 73c91d961e..4757ed1c3a 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -2291,7 +2291,8 @@ typedef enum { SCSC_SPS_PEAK, SCSC_SPS_PEAK_FIVEMIN, SCSC_SESSIONS_PEAK, - SCSC_SESSIONS_PEAK_FIVEMIN + SCSC_SESSIONS_PEAK_FIVEMIN, + SCSC_MDNS_RESOLVE } switch_session_ctl_t; typedef enum { diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index aec3097e45..5d8313e5c5 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -2417,7 +2417,7 @@ SWITCH_STANDARD_API(uptime_function) return SWITCH_STATUS_SUCCESS; } -#define CTL_SYNTAX "[recover|send_sighup|hupall|pause [inbound|outbound]|resume [inbound|outbound]|shutdown [cancel|elegant|asap|now|restart]|sps|sps_peak_reset|sync_clock|sync_clock_when_idle|reclaim_mem|max_sessions|min_dtmf_duration [num]|max_dtmf_duration [num]|default_dtmf_duration [num]|min_idle_cpu|loglevel [level]|debug_level [level]]" +#define CTL_SYNTAX "[recover|send_sighup|hupall|pause [inbound|outbound]|resume [inbound|outbound]|shutdown [cancel|elegant|asap|now|restart]|sps|sps_peak_reset|sync_clock|sync_clock_when_idle|reclaim_mem|max_sessions|min_dtmf_duration [num]|max_dtmf_duration [num]|default_dtmf_duration [num]|min_idle_cpu|loglevel [level]|debug_level [level]|mdns_resolve [enable|disable]]" SWITCH_STANDARD_API(ctl_function) { int argc; @@ -2673,6 +2673,25 @@ SWITCH_STANDARD_API(ctl_function) } else { stream->write_function(stream, "+OK clock will synchronize when there are no more calls\n"); } + } else if (!strcasecmp(argv[0], "mdns_resolve")) { + switch_bool_t set = 0; + if (argv[1]) { + if (!strcasecmp(argv[1], "enable")) { + arg = 1; + set = 1; + } else if (!strcasecmp(argv[1], "disable")) { + arg = 0; + set = 1; + } + } + if (set) { + switch_core_session_ctl(SCSC_MDNS_RESOLVE, &arg); + stream->write_function(stream, "+OK\n"); + arg = 0; + } else { + stream->write_function(stream, "-ERR Invalid command\nUSAGE: fsctl %s\n", CTL_SYNTAX); + goto end; + } } else { stream->write_function(stream, "-ERR Invalid command\nUSAGE: fsctl %s\n", CTL_SYNTAX); goto end; @@ -7733,6 +7752,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) switch_console_set_complete("add fsctl flush_db_handles"); switch_console_set_complete("add fsctl min_idle_cpu"); switch_console_set_complete("add fsctl send_sighup"); + switch_console_set_complete("add fsctl mdns_resolve disable"); + switch_console_set_complete("add fsctl mdns_resolve enable"); switch_console_set_complete("add interface_ip auto ::console::list_interfaces"); switch_console_set_complete("add interface_ip ipv4 ::console::list_interfaces"); switch_console_set_complete("add interface_ip ipv6 ::console::list_interfaces"); diff --git a/src/switch_core.c b/src/switch_core.c index ac6001c612..81b6de762b 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -2348,6 +2348,8 @@ static void switch_load_core_config(const char *file) } else { runtime.timer_affinity = atoi(val); } + } else if (!strcasecmp(var, "ice-resolve-candidate")) { + switch_core_media_set_resolveice(switch_true(val)); } else if (!strcasecmp(var, "rtp-start-port") && !zstr(val)) { switch_rtp_set_start_port((switch_port_t) atoi(val)); } else if (!strcasecmp(var, "rtp-end-port") && !zstr(val)) { @@ -3008,6 +3010,9 @@ SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, void * switch_core_memory_reclaim_all(); newintval = 0; break; + case SCSC_MDNS_RESOLVE: + switch_core_media_set_resolveice(!!oldintval); + break; } if (intval) { diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 065ad0566f..71c02aa6a9 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -291,6 +291,19 @@ switch_srtp_crypto_suite_t SUITES[CRYPTO_INVALID] = { { "AES_CM_128_NULL_AUTH", "", AES_CM_128_NULL_AUTH, 30, 14} }; +static switch_bool_t ice_resolve_candidate = 0; + +SWITCH_DECLARE(void) switch_core_media_set_resolveice(switch_bool_t resolve_ice) +{ + ice_resolve_candidate = resolve_ice; +} + +SWITCH_DECLARE(switch_bool_t) switch_core_media_has_resolveice(void) +{ + return ice_resolve_candidate; +} + + SWITCH_DECLARE(switch_rtp_crypto_key_type_t) switch_core_media_crypto_str2type(const char *str) { int i; @@ -4153,6 +4166,9 @@ static switch_status_t check_ice(switch_media_handle_t *smh, switch_media_type_t int i = 0, got_rtcp_mux = 0; const char *val; int ice_seen = 0, cid = 0, ai = 0, attr_idx = 0, cand_seen = 0, relay_ok = 0; + char con_addr[256]; + int ice_resolve = 0; + ip_t ip; if (switch_true(switch_channel_get_variable_dup(smh->session->channel, "ignore_sdp_ice", SWITCH_FALSE, -1))) { return SWITCH_STATUS_BREAK; @@ -4177,6 +4193,8 @@ static switch_status_t check_ice(switch_media_handle_t *smh, switch_media_type_t attrs[0] = sdp->sdp_attributes; } + ice_resolve = switch_core_media_has_resolveice(); + for (attr_idx = 0; attr_idx < 2 && !(ice_seen && cand_seen); attr_idx++) { for (attr = attrs[attr_idx]; attr; attr = attr->a_next) { char *data; @@ -4291,17 +4309,38 @@ static switch_status_t check_ice(switch_media_handle_t *smh, switch_media_type_t switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG1, "CAND %d [%s]\n", i, fields[i]); } - if (!ip_possible(smh, fields[4])) { + if (fields[4] && (switch_inet_pton(AF_INET, fields[4], &ip) || switch_inet_pton(AF_INET6, fields[4], &ip))) { + switch_copy_string(con_addr, fields[4], sizeof(con_addr)); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG1, "Is an IP address: %s\n", con_addr); + } else if (fields[4] && ice_resolve) { + if (switch_resolve_host(fields[4], con_addr, sizeof(con_addr)) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_INFO, "Resolved %s to %s\n", fields[4], con_addr); + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_INFO, + "Drop %s Candidate cid: %d proto: %s type: %s addr: %s:%s (cannot resolve)\n", + type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio", + cid+1, fields[2], fields[7], fields[4], fields[5]); + continue; + } + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_INFO, + "Drop %s Candidate cid: %d proto: %s type: %s addr: %s:%s (not an IP address)\n", + type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio", + cid+1, fields[2], fields[7], fields[4] ? fields[4] : "(null)", fields[5]); + continue; + } + + if (!ip_possible(smh, con_addr)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG, "Drop %s Candidate cid: %d proto: %s type: %s addr: %s:%s (no network path)\n", type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio", - cid+1, fields[2], fields[7] ? fields[7] : "N/A", fields[4], fields[5]); + cid+1, fields[2], fields[7] ? fields[7] : "N/A", con_addr, fields[5]); continue; } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG, "Save %s Candidate cid: %d proto: %s type: %s addr: %s:%s\n", type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio", - cid+1, fields[2], fields[7] ? fields[7] : "N/A", fields[4], fields[5]); + cid+1, fields[2], fields[7] ? fields[7] : "N/A", con_addr, fields[5]); } @@ -4309,7 +4348,7 @@ static switch_status_t check_ice(switch_media_handle_t *smh, switch_media_type_t engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].component_id = atoi(fields[1]); engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].transport = switch_core_session_strdup(smh->session, fields[2]); engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].priority = atol(fields[3]); - engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].con_addr = switch_core_session_strdup(smh->session, fields[4]); + engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].con_addr = switch_core_session_strdup(smh->session, con_addr); engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].con_port = (switch_port_t)atoi(fields[5]); j = 6;