]> 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:24:15 +0000 (00:24 +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 99dd7af55bf2b9d2eacf009a228673a681e6e691..507623be5ced11e3963612e3387a07ec95d954cd 100644 (file)
@@ -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;
index 8e41a882a613c35983a0489009fcc8e6540ded31..6ebfc82ed44e2d98a654f28822e2ec20aa7611f8 100644 (file)
@@ -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);
 
index e43db7be082ac6af726621d4aaebd4ae9b5e6873..fbfecd7538532a8ecd4e0f8db3e4b961e6e1cbc1 100644 (file)
@@ -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;
 
index 612256b942388b930f2ded52c6ac9ba7e9350f68..737cdfab1b7c6ada7fb6018568dca4ee2fc54bd6 100644 (file)
@@ -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)) {
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 f1ed3c6ba52b9740946a7c92850ee154d8497fb5..4e7ca5aca1a8c48e54a8e622edda41e906b3570f 100644 (file)
@@ -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();
                }