]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-5675 --resolve
authorAnthony Minessale <anthm@freeswitch.org>
Thu, 23 Jan 2014 19:23:58 +0000 (00:23 +0500)
committerAnthony Minessale <anthm@freeswitch.org>
Thu, 23 Jan 2014 19:23:58 +0000 (00:23 +0500)
conf/vanilla/autoload_configs/switch.conf.xml
src/include/private/switch_core_pvt.h
src/include/switch_core.h
src/include/switch_types.h
src/switch_core.c
src/switch_core_port_allocator.c
src/switch_rtp.c

index ddf41f8996dad28c5d76435bc29f1dfbc4fe168f..6c8250f6cbce0c41d71c0f0cf92192509591bc96 100644 (file)
     <!-- <param name="rtp-start-port" value="16384"/> -->
     <!-- <param name="rtp-end-port" value="32768"/> -->
 
+    <!-- Test each port to make sure it is not in use by some other process before allocating it to RTP -->
+    <!-- <param name="rtp-port-usage-robustness" value="true"/> -->
+
     <param name="rtp-enable-zrtp" value="true"/>
 
     <!-- <param name="core-db-dsn" value="pgsql://hostaddr=127.0.0.1 dbname=freeswitch user=freeswitch password='' options='-c client_min_messages=NOTICE' application_name='freeswitch'" /> -->
index aa6adb67e9cf9fd58f598ca1baa131b918ace3be..77bfcb0657c9bfcf5300e83e30aa3ca1dfbf1fd3 100644 (file)
@@ -277,6 +277,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;
index f1512aeaa7a7740076bc06c1afdbadc91f017378..ec01bf30d513180d7cd3a68daeca626e42860125 100644 (file)
@@ -415,7 +415,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);
 
index ced44eb05ee2ba4c8ab152356b4d79fc86ccaa1b..bf91cd82966802e5d98f0d514faa99dd6c6f98bc 100644 (file)
@@ -311,7 +311,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;
 
index 137bf0babad994406b88269865d9ebe8815bc06a..80392b20eb8751907c79b63fb673edd862c97d91 100644 (file)
@@ -2014,6 +2014,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)) {
index 9e9486aeebec766d78c6156131ce6cbea3c041ee..ab99fa668d19ef0f2c4e5100713ce322fedece84 100644 (file)
@@ -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;
+                       }
                }
        }
 
index ef242708331cd03e60d8e9898c51d61af0533565..a53dc5b7faf5d4936f7a6d16df0222f457a9dcb7 100644 (file)
@@ -1869,7 +1869,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();
                }