FreeSWITCH API Documentation  1.7.0
Data Structures | Functions
switch_core_port_allocator.c File Reference
#include <switch.h>
#include "private/switch_core_pvt.h"
+ Include dependency graph for switch_core_port_allocator.c:

Go to the source code of this file.

Data Structures

struct  switch_core_port_allocator
 

Functions

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)
 
static switch_bool_t test_port (switch_core_port_allocator_t *alloc, int family, int type, switch_port_t port)
 
switch_status_t switch_core_port_allocator_request_port (switch_core_port_allocator_t *alloc, switch_port_t *port_ptr)
 
switch_status_t switch_core_port_allocator_free_port (switch_core_port_allocator_t *alloc, switch_port_t port)
 
void switch_core_port_allocator_destroy (switch_core_port_allocator_t **alloc)
 

Function Documentation

void switch_core_port_allocator_destroy ( switch_core_port_allocator_t **  alloc)

Definition at line 246 of file switch_core_port_allocator.c.

References pool, and switch_core_destroy_memory_pool.

247 {
248  switch_memory_pool_t *pool = (*alloc)->pool;
250  *alloc = NULL;
251 }
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:640
switch_memory_pool_t * pool
struct apr_pool_t switch_memory_pool_t
switch_status_t switch_core_port_allocator_free_port ( switch_core_port_allocator_t alloc,
switch_port_t  port 
)

Definition at line 218 of file switch_core_port_allocator.c.

References SPF_EVEN, SPF_ODD, switch_mutex_lock(), switch_mutex_unlock(), SWITCH_STATUS_FALSE, SWITCH_STATUS_GENERR, SWITCH_STATUS_SUCCESS, and switch_test_flag.

219 {
221  int even = switch_test_flag(alloc, SPF_EVEN);
222  int odd = switch_test_flag(alloc, SPF_ODD);
223  int index;
224 
225  if (port < alloc->start) {
226  return SWITCH_STATUS_GENERR;
227  }
228 
229  index = port - alloc->start;
230 
231  if (!(even && odd)) {
232  index /= 2;
233  }
234 
235  switch_mutex_lock(alloc->mutex);
236  if (alloc->track[index] > 0) {
237  alloc->track[index] = -4;
238  alloc->track_used--;
239  status = SWITCH_STATUS_SUCCESS;
240  }
241  switch_mutex_unlock(alloc->mutex);
242 
243  return status;
244 }
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
switch_status_t
Common return values.
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
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 
)

Definition at line 51 of file switch_core_port_allocator.c.

References switch_core_port_allocator::end, switch_core_port_allocator::flags, switch_core_port_allocator::ip, switch_core_port_allocator::mutex, switch_core_port_allocator::next, switch_core_port_allocator::pool, pool, switch_runtime::port_alloc_flags, runtime, SPF_EVEN, SPF_ODD, switch_core_port_allocator::start, SWITCH_CHANNEL_LOG, switch_core_alloc, switch_core_destroy_memory_pool, switch_core_new_memory_pool, switch_core_strdup, switch_log_printf(), SWITCH_LOG_WARNING, switch_mutex_init(), SWITCH_MUTEX_NESTED, SWITCH_STATUS_MEMERR, SWITCH_STATUS_SUCCESS, switch_test_flag, switch_core_port_allocator::track, and switch_core_port_allocator::track_len.

53 {
54  switch_status_t status;
57  int even, odd;
58 
59  if ((status = switch_core_new_memory_pool(&pool)) != SWITCH_STATUS_SUCCESS) {
60  return status;
61  }
62 
63  if (!(alloc = switch_core_alloc(pool, sizeof(*alloc)))) {
65  return SWITCH_STATUS_MEMERR;
66  }
67 
68  alloc->flags = flags;
69  alloc->ip = switch_core_strdup(pool, ip);
70  even = switch_test_flag(alloc, SPF_EVEN);
71  odd = switch_test_flag(alloc, SPF_ODD);
72 
73  alloc->flags |= runtime.port_alloc_flags;
74 
75 
76  if (!(even && odd)) {
77  if (even) {
78  if ((start % 2) != 0) {
79  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Rounding odd start port %d to %d\n", start, start + 1);
80  start++;
81  }
82  if ((end % 2) != 0) {
83  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Rounding odd end port %d to %d\n", end, end - 1);
84  end--;
85  }
86  } else if (odd) {
87  if ((start % 2) == 0) {
88  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Rounding even start port %d to %d\n", start, start + 1);
89  start++;
90  }
91  if ((end % 2) == 0) {
92  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Rounding even end port %d to %d\n", end, end - 1);
93  end--;
94  }
95  }
96  }
97 
98  alloc->track_len = (end - start) + 2;
99 
100  if (!(even && odd)) {
101  alloc->track_len /= 2;
102  }
103 
104  alloc->track = switch_core_alloc(pool, (alloc->track_len + 2) * sizeof(switch_byte_t));
105 
106  alloc->start = start;
107  alloc->next = start;
108  alloc->end = end;
109 
110 
112  alloc->pool = pool;
113  *new_allocator = alloc;
114 
115  return SWITCH_STATUS_SUCCESS;
116 }
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core's master pool.
Definition: switch_core.h:631
#define SWITCH_CHANNEL_LOG
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:729
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:640
switch_memory_pool_t * pool
struct switch_runtime runtime
Definition: switch_core.c:64
uint8_t switch_byte_t
Definition: switch_types.h:246
#define SWITCH_MUTEX_NESTED
Definition: switch_apr.h:318
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:682
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:270
switch_status_t
Common return values.
uint32_t port_alloc_flags
struct apr_pool_t switch_memory_pool_t
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
switch_status_t switch_core_port_allocator_request_port ( switch_core_port_allocator_t alloc,
switch_port_t port_ptr 
)

Definition at line 143 of file switch_core_port_allocator.c.

References SPF_EVEN, SPF_ODD, SPF_ROBUST_TCP, SPF_ROBUST_UDP, SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, switch_log_printf(), switch_micro_time_now(), switch_mutex_lock(), switch_mutex_unlock(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_test_flag, switch_thread_self(), SWITCH_TRUE, and test_port().

144 {
145  switch_port_t port = 0;
147  int even = switch_test_flag(alloc, SPF_EVEN);
148  int odd = switch_test_flag(alloc, SPF_ODD);
149 
150  switch_mutex_lock(alloc->mutex);
151  srand((unsigned) ((unsigned) (intptr_t) port_ptr + (unsigned) (intptr_t) switch_thread_self() + switch_micro_time_now()));
152 
153  while (alloc->track_used < alloc->track_len) {
154  uint32_t index;
155  uint32_t tries = 0;
156 
157  /* randomly pick a port */
158  index = rand() % alloc->track_len;
159 
160  /* if it is used walk up the list to find a free one */
161  while (alloc->track[index] && tries < alloc->track_len) {
162  tries++;
163  if (alloc->track[index] < 0) {
164  alloc->track[index]++;
165  }
166  if (++index >= alloc->track_len) {
167  index = 0;
168  }
169  }
170 
171  if (tries < alloc->track_len) {
173 
174  if ((even && odd)) {
175  port = (switch_port_t) (index + alloc->start);
176  } else {
177  port = (switch_port_t) (index + (alloc->start / 2));
178  port *= 2;
179  }
180 
181  if ((alloc->flags & SPF_ROBUST_UDP)) {
182  r = test_port(alloc, AF_INET, SOCK_DGRAM, port);
183  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "UDP port robustness check for port %d %s\n", port, r ? "pass" : "fail");
184  }
185 
186  if ((alloc->flags & SPF_ROBUST_TCP)) {
187  r = test_port(alloc, AF_INET, SOCK_STREAM, port);
188  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TCP port robustness check for port %d %s\n", port, r ? "pass" : "fail");
189  }
190 
191  if (r) {
192  alloc->track[index] = 1;
193  alloc->track_used++;
194  status = SWITCH_STATUS_SUCCESS;
195  goto end;
196  } else {
197  alloc->track[index] = -4;
198  }
199  }
200  }
201 
202 
203  end:
204 
205  switch_mutex_unlock(alloc->mutex);
206 
207  if (status == SWITCH_STATUS_SUCCESS) {
208  *port_ptr = port;
209  } else {
210  *port_ptr = 0;
211  }
212 
213 
214  return status;
215 
216 }
switch_time_t switch_micro_time_now(void)
Get the current epoch time in microseconds.
Definition: switch_time.c:310
#define SWITCH_CHANNEL_LOG
switch_bool_t
Definition: switch_types.h:405
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
uint16_t switch_port_t
switch_status_t
Common return values.
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
switch_thread_id_t switch_thread_self(void)
Definition: switch_apr.c:79
static switch_bool_t test_port(switch_core_port_allocator_t *alloc, int family, int type, switch_port_t port)
static switch_bool_t test_port ( switch_core_port_allocator_t alloc,
int  family,
int  type,
switch_port_t  port 
)
static

Definition at line 118 of file switch_core_port_allocator.c.

References switch_core_port_allocator::ip, pool, switch_core_destroy_memory_pool, switch_core_new_memory_pool, SWITCH_FALSE, switch_sockaddr_info_get(), switch_socket_bind(), switch_socket_close(), switch_socket_create(), SWITCH_STATUS_SUCCESS, SWITCH_TRUE, and SWITCH_UNSPEC.

Referenced by switch_core_port_allocator_request_port().

119 {
120  switch_memory_pool_t *pool = NULL;
121  switch_sockaddr_t *local_addr = NULL;
122  switch_socket_t *sock = NULL;
124 
126  return SWITCH_FALSE;
127  }
128 
129  if (switch_sockaddr_info_get(&local_addr, alloc->ip, SWITCH_UNSPEC, port, 0, pool) == SWITCH_STATUS_SUCCESS) {
130  if (switch_socket_create(&sock, family, type, 0, pool) == SWITCH_STATUS_SUCCESS) {
131  if (switch_socket_bind(sock, local_addr) == SWITCH_STATUS_SUCCESS) {
132  r = SWITCH_TRUE;
133  }
134  switch_socket_close(sock);
135  }
136  }
137 
139 
140  return r;
141 }
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core's master pool.
Definition: switch_core.h:631
switch_status_t switch_socket_bind(switch_socket_t *sock, switch_sockaddr_t *sa)
Definition: switch_apr.c:719
switch_bool_t
Definition: switch_types.h:405
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:640
switch_memory_pool_t * pool
struct apr_sockaddr_t switch_sockaddr_t
Definition: switch_apr.h:1029
switch_status_t switch_socket_create(switch_socket_t **new_sock, int family, int type, int protocol, switch_memory_pool_t *pool)
Definition: switch_apr.c:704
switch_status_t switch_socket_close(switch_socket_t *sock)
Definition: switch_apr.c:714
#define SWITCH_UNSPEC
Definition: switch_apr.h:1022
struct apr_pool_t switch_memory_pool_t
struct apr_socket_t switch_socket_t
Definition: switch_apr.h:1026
switch_status_t switch_sockaddr_info_get(switch_sockaddr_t **sa, const char *hostname, int32_t family, switch_port_t port, int32_t flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:817