[Freeswitch-svn] [commit] r6658 - in freeswitch/trunk/src: . include mod/applications/mod_esf mod/endpoints/mod_dingaling mod/endpoints/mod_sofia
Freeswitch SVN
anthm at freeswitch.org
Tue Dec 11 14:15:03 EST 2007
Author: anthm
Date: Tue Dec 11 14:15:02 2007
New Revision: 6658
Modified:
freeswitch/trunk/src/include/switch_core.h
freeswitch/trunk/src/include/switch_rtp.h
freeswitch/trunk/src/include/switch_types.h
freeswitch/trunk/src/mod/applications/mod_esf/mod_esf.c
freeswitch/trunk/src/mod/endpoints/mod_dingaling/mod_dingaling.c
freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c
freeswitch/trunk/src/switch_core.c
freeswitch/trunk/src/switch_core_port_allocator.c
freeswitch/trunk/src/switch_rtp.c
Log:
add rtp port allocator
Modified: freeswitch/trunk/src/include/switch_core.h
==============================================================================
--- freeswitch/trunk/src/include/switch_core.h (original)
+++ freeswitch/trunk/src/include/switch_core.h Tue Dec 11 14:15:02 2007
@@ -216,14 +216,16 @@
\return SWITCH_STATUS_SUCCESS if the operation was a success
*/
SWITCH_DECLARE(switch_status_t) switch_core_port_allocator_new(switch_port_t start,
- switch_port_t end, uint8_t inc, switch_core_port_allocator_t **new_allocator);
+ switch_port_t end, switch_port_flag_t flags, switch_core_port_allocator_t **new_allocator);
/*!
\brief Get a port from the port allocator
\param alloc the allocator object
- \return the port
+ \param port a pointer to the port
+ \return SUCCESS
*/
-SWITCH_DECLARE(switch_port_t) switch_core_port_allocator_request_port(switch_core_port_allocator_t *alloc);
+SWITCH_DECLARE(switch_status_t) switch_core_port_allocator_request_port(switch_core_port_allocator_t *alloc, switch_port_t *port_ptr);
+SWITCH_DECLARE(switch_status_t) switch_core_port_allocator_free_port(switch_core_port_allocator_t *alloc, switch_port_t port);
/*!
\brief destroythe port allocator
Modified: freeswitch/trunk/src/include/switch_rtp.h
==============================================================================
--- freeswitch/trunk/src/include/switch_rtp.h (original)
+++ freeswitch/trunk/src/include/switch_rtp.h Tue Dec 11 14:15:02 2007
@@ -53,6 +53,7 @@
\note Generally called by the core_init
*/
SWITCH_DECLARE(void) switch_rtp_init(switch_memory_pool_t *pool);
+SWITCH_DECLARE(void) switch_rtp_shutdown(void);
/*!
\brief Set/Get RTP start port
@@ -70,9 +71,10 @@
/*!
\brief Request a new port to be used for media
+ \param ip the ip to request a port from
\return the new port to use
*/
-SWITCH_DECLARE(switch_port_t) switch_rtp_request_port(void);
+SWITCH_DECLARE(switch_port_t) switch_rtp_request_port(const char *ip);
/*!
\brief create a new RTP session handle
Modified: freeswitch/trunk/src/include/switch_types.h
==============================================================================
--- freeswitch/trunk/src/include/switch_types.h (original)
+++ freeswitch/trunk/src/include/switch_types.h Tue Dec 11 14:15:02 2007
@@ -137,6 +137,12 @@
typedef uint8_t switch_byte_t;
typedef enum {
+ SPF_NONE = 0,
+ SPF_ODD = (1 << 0),
+ SPF_EVEN = (1 << 1)
+} switch_port_flag_t;
+
+typedef enum {
ED_MUX_READ = (1 << 0),
ED_MUX_WRITE = (1 << 1),
ED_DTMF = (1 << 2)
Modified: freeswitch/trunk/src/mod/applications/mod_esf/mod_esf.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_esf/mod_esf.c (original)
+++ freeswitch/trunk/src/mod/applications/mod_esf/mod_esf.c Tue Dec 11 14:15:02 2007
@@ -153,7 +153,10 @@
}
if (ready == SEND_TYPE_RTP) {
- rtp_port = switch_rtp_request_port();
+ if (!(rtp_port = switch_rtp_request_port(guess_ip))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "RTP Port Error\n");
+ goto fail;
+ }
switch_find_local_ip(guess_ip, sizeof(guess_ip), AF_INET);
rtp_session = switch_rtp_new(guess_ip,
rtp_port,
Modified: freeswitch/trunk/src/mod/endpoints/mod_dingaling/mod_dingaling.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_dingaling/mod_dingaling.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_dingaling/mod_dingaling.c Tue Dec 11 14:15:02 2007
@@ -1697,7 +1697,11 @@
switch_core_session_set_private(*new_session, tech_pvt);
tech_pvt->session = *new_session;
tech_pvt->codec_index = -1;
- tech_pvt->local_port = switch_rtp_request_port();
+ if (!(tech_pvt->local_port = switch_rtp_request_port(tech_pvt->profile->ip))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No RTP port available!\n");
+ terminate_session(new_session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+ return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
+ }
tech_pvt->recip = switch_core_session_strdup(*new_session, full_id);
tech_pvt->dnis = switch_core_session_strdup(*new_session, dnis);
} else {
@@ -2584,7 +2588,12 @@
tech_pvt->session = session;
tech_pvt->codec_index = -1;
tech_pvt->profile = profile;
- tech_pvt->local_port = switch_rtp_request_port();
+ if (!(tech_pvt->local_port = switch_rtp_request_port(profile->ip))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No RTP port available!\n");
+ terminate_session(&session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+ status = LDL_STATUS_FALSE;
+ goto done;
+ }
switch_set_flag_locked(tech_pvt, TFLAG_ANSWER);
tech_pvt->recip = switch_core_session_strdup(session, from);
if (!(exten = ldl_session_get_value(dlsession, "dnis"))) {
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c Tue Dec 11 14:15:02 2007
@@ -398,7 +398,10 @@
}
tech_pvt->local_sdp_audio_ip = ip;
- tech_pvt->local_sdp_audio_port = switch_rtp_request_port();
+ if (!(tech_pvt->local_sdp_audio_port = switch_rtp_request_port(tech_pvt->profile->rtpip))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No RTP ports available!\n");
+ return SWITCH_STATUS_FALSE;
+ }
sdp_port = tech_pvt->local_sdp_audio_port;
if (tech_pvt->profile->extrtpip) {
@@ -428,7 +431,10 @@
return SWITCH_STATUS_SUCCESS;
}
- tech_pvt->local_sdp_video_port = switch_rtp_request_port();
+ if (!(tech_pvt->local_sdp_video_port = switch_rtp_request_port(tech_pvt->profile->rtpip))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No RTP ports available!\n");
+ return SWITCH_STATUS_FALSE;
+ }
sdp_port = tech_pvt->local_sdp_video_port;
if (tech_pvt->profile->extrtpip) {
Modified: freeswitch/trunk/src/switch_core.c
==============================================================================
--- freeswitch/trunk/src/switch_core.c (original)
+++ freeswitch/trunk/src/switch_core.c Tue Dec 11 14:15:02 2007
@@ -994,13 +994,12 @@
}
switch_scheduler_task_thread_stop();
+ switch_rtp_shutdown();
switch_xml_destroy();
switch_core_memory_stop();
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Finalizing Shutdown.\n");
switch_log_shutdown();
-
-
if (runtime.console && runtime.console != stdout && runtime.console != stderr) {
fclose(runtime.console);
runtime.console = NULL;
@@ -1028,6 +1027,18 @@
return SWITCH_STATUS_SUCCESS;
}
+SWITCH_DECLARE(switch_status_t) switch_core_management_exec(char *relative_oid, switch_management_action_t action, char *data, switch_size_t datalen)
+{
+ const switch_management_interface_t *ptr;
+ switch_status_t status = SWITCH_STATUS_FALSE;
+
+ if ((ptr = switch_loadable_module_get_management_interface(relative_oid))) {
+ status = ptr->management_function(relative_oid, action, data, datalen);
+ }
+
+ return status;
+}
+
SWITCH_DECLARE(void) switch_core_memory_reclaim_all(void)
{
switch_core_memory_reclaim_logger();
Modified: freeswitch/trunk/src/switch_core_port_allocator.c
==============================================================================
--- freeswitch/trunk/src/switch_core_port_allocator.c (original)
+++ freeswitch/trunk/src/switch_core_port_allocator.c Tue Dec 11 14:15:02 2007
@@ -38,18 +38,21 @@
switch_port_t start;
switch_port_t end;
switch_port_t next;
- uint8_t inc;
+ switch_byte_t *track;
+ uint32_t track_len;
+ uint32_t track_used;
+ switch_port_flag_t flags;
switch_mutex_t *mutex;
switch_memory_pool_t *pool;
};
SWITCH_DECLARE(switch_status_t) switch_core_port_allocator_new(switch_port_t start,
- switch_port_t end, uint8_t inc, switch_core_port_allocator_t **new_allocator)
+ switch_port_t end, switch_port_flag_t flags, switch_core_port_allocator_t **new_allocator)
{
switch_status_t status;
switch_memory_pool_t *pool;
switch_core_port_allocator_t *alloc;
-
+
if ((status = switch_core_new_memory_pool(&pool)) != SWITCH_STATUS_SUCCESS) {
return status;
}
@@ -58,13 +61,21 @@
switch_core_destroy_memory_pool(&pool);
return SWITCH_STATUS_MEMERR;
}
+
+ alloc->track_len = (end - start) + 2;
+ alloc->flags = flags;
+
+ if (!(switch_test_flag(alloc, SPF_EVEN) && switch_test_flag(alloc, SPF_ODD))) {
+ alloc->track_len /= 2;
+ }
+
+ alloc->track = switch_core_alloc(pool, (alloc->track_len + 2) * sizeof(switch_byte_t));
alloc->start = start;
alloc->next = start;
alloc->end = end;
- if (!(alloc->inc = inc)) {
- alloc->inc = 2;
- }
+
+
switch_mutex_init(&alloc->mutex, SWITCH_MUTEX_NESTED, pool);
alloc->pool = pool;
*new_allocator = alloc;
@@ -72,34 +83,89 @@
return SWITCH_STATUS_SUCCESS;
}
-SWITCH_DECLARE(switch_status_t) switch_core_management_exec(char *relative_oid, switch_management_action_t action, char *data, switch_size_t datalen)
+
+SWITCH_DECLARE(switch_status_t) switch_core_port_allocator_request_port(switch_core_port_allocator_t *alloc, switch_port_t *port_ptr)
{
- const switch_management_interface_t *ptr;
+ switch_port_t port = 0;
switch_status_t status = SWITCH_STATUS_FALSE;
+ int even = switch_test_flag(alloc, SPF_EVEN);
+ int odd = switch_test_flag(alloc, SPF_ODD);
+
+ switch_mutex_lock(alloc->mutex);
+ srand(getpid() + time(NULL));
+
+ while(alloc->track_used < alloc->track_len) {
+ double r;
+ int index;
+ int tries = 0;
+
+ do {
+ r = ((double)rand() / ((double)(RAND_MAX)+(double)(1)));
+ index = (int) (r * alloc->track_len);
+ tries++;
+ } while((alloc->track[index] || index >= alloc->track_len) && tries < 10000);
+
+ while(alloc->track[index]) {
+ if (++index >= alloc->track_len) {
+ index = 0;
+ }
+ }
+
+ if (index < alloc->track_len) {
+ alloc->track[index] = 1;
+ alloc->track_used++;
+ status = SWITCH_STATUS_SUCCESS;
+
+ if ((even && odd)) {
+ port = index + alloc->start;
+ } else {
+ port = index + (alloc->start / 2);
+ port *= 2;
+ }
+ goto end;
+ }
+ }
+
+
+ end:
- if ((ptr = switch_loadable_module_get_management_interface(relative_oid))) {
- status = ptr->management_function(relative_oid, action, data, datalen);
+ switch_mutex_unlock(alloc->mutex);
+
+ if (status == SWITCH_STATUS_SUCCESS) {
+ *port_ptr = port;
+ } else {
+ *port_ptr = 0;
}
+
return status;
+
}
-
-SWITCH_DECLARE(switch_port_t) switch_core_port_allocator_request_port(switch_core_port_allocator_t *alloc)
+SWITCH_DECLARE(switch_status_t) switch_core_port_allocator_free_port(switch_core_port_allocator_t *alloc, switch_port_t port)
{
- switch_port_t port;
+ switch_status_t status = SWITCH_STATUS_FALSE;
+ int even = switch_test_flag(alloc, SPF_EVEN);
+ int odd = switch_test_flag(alloc, SPF_ODD);
+ int index = port - alloc->start;
+
+ if (!(even && odd)) {
+ index /= 2;
+ }
switch_mutex_lock(alloc->mutex);
- port = alloc->next;
- alloc->next = alloc->next + alloc->inc;
- if (alloc->next > alloc->end) {
- alloc->next = alloc->start;
+ if (alloc->track[index]) {
+ alloc->track[index] = 0;
+ alloc->track_used--;
+ status = SWITCH_STATUS_SUCCESS;
}
switch_mutex_unlock(alloc->mutex);
- return port;
+
+ return status;
}
+
SWITCH_DECLARE(void) switch_core_port_allocator_destroy(switch_core_port_allocator_t **alloc)
{
switch_memory_pool_t *pool = (*alloc)->pool;
Modified: freeswitch/trunk/src/switch_rtp.c
==============================================================================
--- freeswitch/trunk/src/switch_rtp.c (original)
+++ freeswitch/trunk/src/switch_rtp.c Tue Dec 11 14:15:02 2007
@@ -67,7 +67,7 @@
#pragma pack()
#endif
-
+static switch_hash_t *alloc_hash = NULL;
typedef struct {
srtp_hdr_t header;
@@ -147,7 +147,8 @@
uint32_t flags;
switch_memory_pool_t *pool;
switch_sockaddr_t *from_addr;
-
+ char *rx_host;
+ switch_port_t rx_port;
char *ice_user;
char *user_ice;
char *timer_name;
@@ -261,12 +262,17 @@
if (global_init) {
return;
}
-
+ switch_core_hash_init(&alloc_hash, pool);
srtp_init();
switch_mutex_init(&port_lock, SWITCH_MUTEX_NESTED, pool);
global_init = 1;
}
+SWITCH_DECLARE(void) switch_rtp_shutdown(void)
+{
+ switch_core_hash_destroy(&alloc_hash);
+}
+
SWITCH_DECLARE(switch_port_t) switch_rtp_set_start_port(switch_port_t port)
{
if (port) {
@@ -304,16 +310,43 @@
return END_PORT;
}
-SWITCH_DECLARE(switch_port_t) switch_rtp_request_port(void)
+static void release_port(switch_rtp_t *rtp_session)
{
- switch_port_t port;
+ switch_core_port_allocator_t *alloc = NULL;
+ if (!rtp_session->rx_host) {
+ return;
+ }
+
+ switch_mutex_lock(port_lock);
+ if ((alloc = switch_core_hash_find(alloc_hash, rtp_session->rx_host))) {
+ switch_core_port_allocator_free_port(alloc, rtp_session->rx_port);
+ }
+ switch_mutex_unlock(port_lock);
+
+}
+
+SWITCH_DECLARE(switch_port_t) switch_rtp_request_port(const char *ip)
+{
+ switch_port_t port = 0;
+ switch_core_port_allocator_t *alloc = NULL;
+
switch_mutex_lock(port_lock);
- port = NEXT_PORT;
- NEXT_PORT += 2;
- if (NEXT_PORT > END_PORT) {
- NEXT_PORT = START_PORT;
+ 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) {
+ port = 0;
+ goto end;
+ }
+
+ switch_core_hash_insert(alloc_hash, ip, alloc);
+ }
+
+ if (switch_core_port_allocator_request_port(alloc, &port) != SWITCH_STATUS_SUCCESS) {
+ port = 0;
}
+
+ end:
switch_mutex_unlock(port_lock);
return port;
}
@@ -379,7 +412,8 @@
*err = "Send myself a packet failed!";
goto done;
}
-
+ release_port(rtp_session);
+
old_sock = rtp_session->sock;
rtp_session->sock = new_sock;
new_sock = NULL;
@@ -395,7 +429,9 @@
done:
- if (status != SWITCH_STATUS_SUCCESS) {
+ if (status == SWITCH_STATUS_SUCCESS) {
+ rtp_session->rx_host = switch_core_strdup(rtp_session->pool, host);
+ rtp_session->rx_port = port;
rtp_session->ready = 1;
}
@@ -653,6 +689,7 @@
return;
}
+
(*rtp_session)->ready = 0;
switch_mutex_lock((*rtp_session)->flag_mutex);
@@ -683,6 +720,8 @@
switch_core_timer_destroy(&(*rtp_session)->timer);
}
+ release_port(*rtp_session);
+
switch_mutex_unlock((*rtp_session)->flag_mutex);
return;
}
More information about the Freeswitch-svn
mailing list