From fa8392a8c0366024e754b9329c3257b9de602381 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 24 Jan 2014 00:23:58 +0500 Subject: [PATCH] FS-5675 --resolve --- conf/vanilla/autoload_configs/switch.conf.xml | 3 + src/include/private/switch_core_pvt.h | 1 + src/include/switch_core.h | 3 +- src/include/switch_types.h | 4 +- src/switch_core.c | 2 + src/switch_core_port_allocator.c | 56 +++++++++++++++++-- src/switch_rtp.c | 2 +- 7 files changed, 63 insertions(+), 8 deletions(-) diff --git a/conf/vanilla/autoload_configs/switch.conf.xml b/conf/vanilla/autoload_configs/switch.conf.xml index ddf41f8996..6c8250f6cb 100644 --- a/conf/vanilla/autoload_configs/switch.conf.xml +++ b/conf/vanilla/autoload_configs/switch.conf.xml @@ -142,6 +142,9 @@ + + + diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index 99dd7af55b..507623be5c 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -274,6 +274,7 @@ struct switch_runtime { char *core_db_inner_pre_trans_execute; char *core_db_inner_post_trans_execute; int events_use_dispatch; + uint32_t port_alloc_flags; }; extern struct switch_runtime runtime; diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 8e41a882a6..6ebfc82ed4 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -384,7 +384,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_set_pre_buffer_framecount( \param new_allocator new pointer for the return value \return SWITCH_STATUS_SUCCESS if the operation was a success */ -SWITCH_DECLARE(switch_status_t) switch_core_port_allocator_new(_In_ switch_port_t start, +SWITCH_DECLARE(switch_status_t) switch_core_port_allocator_new(_In_ const char *ip, + _In_ switch_port_t start, _In_ switch_port_t end, _In_ switch_port_flag_t flags, _Out_ switch_core_port_allocator_t **new_allocator); diff --git a/src/include/switch_types.h b/src/include/switch_types.h index e43db7be08..fbfecd7538 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -300,7 +300,9 @@ typedef uint32_t switch_originate_flag_t; typedef enum { SPF_NONE = 0, SPF_ODD = (1 << 0), - SPF_EVEN = (1 << 1) + SPF_EVEN = (1 << 1), + SPF_ROBUST_TCP = (1 << 2), + SPF_ROBUST_UDP = (1 << 3) } switch_port_flag_enum_t; typedef uint32_t switch_port_flag_t; diff --git a/src/switch_core.c b/src/switch_core.c index 612256b942..737cdfab1b 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -1989,6 +1989,8 @@ static void switch_load_core_config(const char *file) switch_rtp_set_start_port((switch_port_t) atoi(val)); } else if (!strcasecmp(var, "rtp-end-port") && !zstr(val)) { switch_rtp_set_end_port((switch_port_t) atoi(val)); + } else if (!strcasecmp(var, "rtp-port-usage-robustness") && switch_true(val)) { + runtime.port_alloc_flags |= SPF_ROBUST_UDP; } else if (!strcasecmp(var, "core-db-name") && !zstr(val)) { runtime.dbname = switch_core_strdup(runtime.memory_pool, val); } else if (!strcasecmp(var, "core-db-dsn") && !zstr(val)) { diff --git a/src/switch_core_port_allocator.c b/src/switch_core_port_allocator.c index 9e9486aeeb..ab99fa668d 100644 --- a/src/switch_core_port_allocator.c +++ b/src/switch_core_port_allocator.c @@ -36,6 +36,7 @@ #include "private/switch_core_pvt.h" struct switch_core_port_allocator { + char *ip; switch_port_t start; switch_port_t end; switch_port_t next; @@ -47,7 +48,7 @@ struct switch_core_port_allocator { switch_memory_pool_t *pool; }; -SWITCH_DECLARE(switch_status_t) switch_core_port_allocator_new(switch_port_t start, +SWITCH_DECLARE(switch_status_t) switch_core_port_allocator_new(const char *ip, switch_port_t start, switch_port_t end, switch_port_flag_t flags, switch_core_port_allocator_t **new_allocator) { switch_status_t status; @@ -65,9 +66,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_port_allocator_new(switch_port_t sta } alloc->flags = flags; + alloc->ip = switch_core_strdup(pool, ip); even = switch_test_flag(alloc, SPF_EVEN); odd = switch_test_flag(alloc, SPF_ODD); + alloc->flags |= runtime.port_alloc_flags; + + if (!(even && odd)) { if (even) { if ((start % 2) != 0) { @@ -110,6 +115,31 @@ SWITCH_DECLARE(switch_status_t) switch_core_port_allocator_new(switch_port_t sta return SWITCH_STATUS_SUCCESS; } +static switch_bool_t test_port(switch_core_port_allocator_t *alloc, int family, int type, switch_port_t port) +{ + switch_memory_pool_t *pool = NULL; + switch_sockaddr_t *local_addr = NULL; + switch_socket_t *sock = NULL; + switch_bool_t r = SWITCH_FALSE; + + if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { + return SWITCH_FALSE; + } + + if (switch_sockaddr_info_get(&local_addr, alloc->ip, SWITCH_UNSPEC, port, 0, pool) == SWITCH_STATUS_SUCCESS) { + if (switch_socket_create(&sock, family, type, 0, pool) == SWITCH_STATUS_SUCCESS) { + if (switch_socket_bind(sock, local_addr) == SWITCH_STATUS_SUCCESS) { + r = SWITCH_TRUE; + } + switch_socket_close(sock); + } + } + + switch_core_destroy_memory_pool(&pool); + + return r; +} + SWITCH_DECLARE(switch_status_t) switch_core_port_allocator_request_port(switch_core_port_allocator_t *alloc, switch_port_t *port_ptr) { switch_port_t port = 0; @@ -139,9 +169,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_port_allocator_request_port(switch_c } if (tries < alloc->track_len) { - alloc->track[index] = 1; - alloc->track_used++; - status = SWITCH_STATUS_SUCCESS; + switch_bool_t r = SWITCH_TRUE; if ((even && odd)) { port = (switch_port_t) (index + alloc->start); @@ -149,7 +177,25 @@ SWITCH_DECLARE(switch_status_t) switch_core_port_allocator_request_port(switch_c port = (switch_port_t) (index + (alloc->start / 2)); port *= 2; } - goto end; + + if ((alloc->flags & SPF_ROBUST_UDP)) { + r = test_port(alloc, AF_INET, SOCK_DGRAM, port); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "UDP port robustness check for port %d %s\n", port, r ? "pass" : "fail"); + } + + if ((alloc->flags & SPF_ROBUST_TCP)) { + r = test_port(alloc, AF_INET, SOCK_STREAM, port); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TCP port robustness check for port %d %s\n", port, r ? "pass" : "fail"); + } + + if (r) { + alloc->track[index] = 1; + alloc->track_used++; + status = SWITCH_STATUS_SUCCESS; + goto end; + } else { + alloc->track[index] = -4; + } } } diff --git a/src/switch_rtp.c b/src/switch_rtp.c index f1ed3c6ba5..4e7ca5aca1 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -1310,7 +1310,7 @@ SWITCH_DECLARE(switch_port_t) switch_rtp_request_port(const char *ip) switch_mutex_lock(port_lock); alloc = switch_core_hash_find(alloc_hash, ip); if (!alloc) { - if (switch_core_port_allocator_new(START_PORT, END_PORT, SPF_EVEN, &alloc) != SWITCH_STATUS_SUCCESS) { + if (switch_core_port_allocator_new(ip, START_PORT, END_PORT, SPF_EVEN, &alloc) != SWITCH_STATUS_SUCCESS) { abort(); }