Bug Summary

File:src/mod/event_handlers/mod_event_socket/mod_event_socket.c
Location:line 1781, column 6
Description:Value stored to 'cur' is never read

Annotated Source Code

1/*
2 * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3 * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
4 *
5 * Version: MPL 1.1
6 *
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
16 *
17 * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18 *
19 * The Initial Developer of the Original Code is
20 * Anthony Minessale II <anthm@freeswitch.org>
21 * Portions created by the Initial Developer are Copyright (C)
22 * the Initial Developer. All Rights Reserved.
23 *
24 * Contributor(s):
25 *
26 * Anthony Minessale II <anthm@freeswitch.org>
27 * Seven Du <dujinfang@gmail.com>
28 *
29 *
30 * mod_event_socket.c -- Socket Controlled Event Handler
31 *
32 */
33#include <switch.h>
34#define CMD_BUFLEN1024 * 1000 1024 * 1000
35#define MAX_QUEUE_LEN100000 100000
36#define MAX_MISSED500 500
37SWITCH_MODULE_LOAD_FUNCTION(mod_event_socket_load)switch_status_t mod_event_socket_load (switch_loadable_module_interface_t
**module_interface, switch_memory_pool_t *pool)
;
38SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_event_socket_shutdown)switch_status_t mod_event_socket_shutdown (void);
39SWITCH_MODULE_RUNTIME_FUNCTION(mod_event_socket_runtime)switch_status_t mod_event_socket_runtime (void);
40SWITCH_MODULE_DEFINITION(mod_event_socket, mod_event_socket_load, mod_event_socket_shutdown, mod_event_socket_runtime)static const char modname[] = "mod_event_socket" ; __attribute__
((visibility("default"))) switch_loadable_module_function_table_t
mod_event_socket_module_interface = { 5, mod_event_socket_load
, mod_event_socket_shutdown, mod_event_socket_runtime, SMODF_NONE
}
;
41
42static char *MARKER = "1";
43
44typedef enum {
45 LFLAG_AUTHED = (1 << 0),
46 LFLAG_RUNNING = (1 << 1),
47 LFLAG_EVENTS = (1 << 2),
48 LFLAG_LOG = (1 << 3),
49 LFLAG_FULL = (1 << 4),
50 LFLAG_MYEVENTS = (1 << 5),
51 LFLAG_SESSION = (1 << 6),
52 LFLAG_ASYNC = (1 << 7),
53 LFLAG_STATEFUL = (1 << 8),
54 LFLAG_OUTBOUND = (1 << 9),
55 LFLAG_LINGER = (1 << 10),
56 LFLAG_HANDLE_DISCO = (1 << 11),
57 LFLAG_CONNECTED = (1 << 12),
58 LFLAG_RESUME = (1 << 13),
59 LFLAG_AUTH_EVENTS = (1 << 14),
60 LFLAG_ALL_EVENTS_AUTHED = (1 << 15),
61 LFLAG_ALLOW_LOG = (1 << 16)
62} event_flag_t;
63
64typedef enum {
65 EVENT_FORMAT_PLAIN,
66 EVENT_FORMAT_XML,
67 EVENT_FORMAT_JSON
68} event_format_t;
69
70struct listener {
71 switch_socket_t *sock;
72 switch_queue_t *event_queue;
73 switch_queue_t *log_queue;
74 switch_memory_pool_t *pool;
75 event_format_t format;
76 switch_mutex_t *flag_mutex;
77 switch_mutex_t *filter_mutex;
78 uint32_t flags;
79 switch_log_level_t level;
80 char *ebuf;
81 uint8_t event_list[SWITCH_EVENT_ALL + 1];
82 uint8_t allowed_event_list[SWITCH_EVENT_ALL + 1];
83 switch_hash_t *event_hash;
84 switch_hash_t *allowed_event_hash;
85 switch_hash_t *allowed_api_hash;
86 switch_thread_rwlock_t *rwlock;
87 switch_core_session_t *session;
88 int lost_events;
89 int lost_logs;
90 time_t last_flush;
91 time_t expire_time;
92 uint32_t timeout;
93 uint32_t id;
94 switch_sockaddr_t *sa;
95 char remote_ip[50];
96 switch_port_t remote_port;
97 switch_event_t *filters;
98 time_t linger_timeout;
99 struct listener *next;
100 switch_pollfd_t *pollfd;
101};
102
103typedef struct listener listener_t;
104
105static struct {
106 switch_mutex_t *listener_mutex;
107 switch_event_node_t *node;
108 int debug;
109} globals;
110
111static struct {
112 switch_socket_t *sock;
113 switch_mutex_t *sock_mutex;
114 listener_t *listeners;
115 uint8_t ready;
116} listen_list;
117
118#define MAX_ACL100 100
119
120static struct {
121 switch_mutex_t *mutex;
122 char *ip;
123 uint16_t port;
124 char *password;
125 int done;
126 int threads;
127 char *acl[MAX_ACL100];
128 uint32_t acl_count;
129 uint32_t id;
130 int nat_map;
131 int stop_on_bind_error;
132} prefs;
133
134
135static const char *format2str(event_format_t format)
136{
137 switch (format) {
138 case EVENT_FORMAT_PLAIN:
139 return "plain";
140 case EVENT_FORMAT_XML:
141 return "xml";
142 case EVENT_FORMAT_JSON:
143 return "json";
144 }
145
146 return "invalid";
147}
148
149static void remove_listener(listener_t *listener);
150static void kill_listener(listener_t *l, const char *message);
151static void kill_all_listeners(void);
152
153static uint32_t next_id(void)
154{
155 uint32_t id;
156 switch_mutex_lock(globals.listener_mutex);
157 id = ++prefs.id;
158 switch_mutex_unlock(globals.listener_mutex);
159 return id;
160}
161
162SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_pref_ip, prefs.ip)static void set_pref_ip(const char *string) { if (!string) return
; if (prefs.ip) {free(prefs.ip); prefs.ip = ((void*)0);}prefs
.ip = (__extension__ (__builtin_constant_p (string) &&
((size_t)(const void *)((string) + 1) - (size_t)(const void *
)(string) == 1) ? (((const char *) (string))[0] == '\0' ? (char
*) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen
(string) + 1; char *__retval = (char *) malloc (__len); if (
__retval != ((void*)0)) __retval = (char *) memcpy (__retval,
string, __len); __retval; })) : __strdup (string)));} static
void set_pref_ip(const char *string)
;
163SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_pref_pass, prefs.password)static void set_pref_pass(const char *string) { if (!string) return
; if (prefs.password) {free(prefs.password); prefs.password =
((void*)0);}prefs.password = (__extension__ (__builtin_constant_p
(string) && ((size_t)(const void *)((string) + 1) - (
size_t)(const void *)(string) == 1) ? (((const char *) (string
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen (string) + 1; char *__retval = (char *
) malloc (__len); if (__retval != ((void*)0)) __retval = (char
*) memcpy (__retval, string, __len); __retval; })) : __strdup
(string)));} static void set_pref_pass(const char *string)
;
164
165static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj);
166static void launch_listener_thread(listener_t *listener);
167
168static switch_status_t socket_logger(const switch_log_node_t *node, switch_log_level_t level)
169{
170 listener_t *l;
171
172 switch_mutex_lock(globals.listener_mutex);
173 for (l = listen_list.listeners; l; l = l->next) {
174 if (switch_test_flag(l, LFLAG_LOG)((l)->flags & LFLAG_LOG) && l->level >= node->level) {
175 switch_log_node_t *dnode = switch_log_node_dup(node);
176
177 if (switch_queue_trypush(l->log_queue, dnode) == SWITCH_STATUS_SUCCESS) {
178 if (l->lost_logs) {
179 int ll = l->lost_logs;
180 l->lost_logs = 0;
181 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_event_socket.c", (const char *)__func__
, 181, ((void*)0)
, SWITCH_LOG_CRIT, "Lost %d log lines!\n", ll);
182 }
183 } else {
184 switch_log_node_free(&dnode);
185 if (++l->lost_logs > MAX_MISSED500) {
186 kill_listener(l, NULL((void*)0));
187 }
188 }
189 }
190 }
191 switch_mutex_unlock(globals.listener_mutex);
192
193 return SWITCH_STATUS_SUCCESS;
194}
195
196static void flush_listener(listener_t *listener, switch_bool_t flush_log, switch_bool_t flush_events)
197{
198 void *pop;
199
200 if (listener->log_queue) {
201 while (switch_queue_trypop(listener->log_queue, &pop) == SWITCH_STATUS_SUCCESS) {
202 switch_log_node_t *dnode = (switch_log_node_t *) pop;
203 if (dnode) {
204 switch_log_node_free(&dnode);
205 }
206 }
207 }
208
209 if (listener->event_queue) {
210 while (switch_queue_trypop(listener->event_queue, &pop) == SWITCH_STATUS_SUCCESS) {
211 switch_event_t *pevent = (switch_event_t *) pop;
212 if (!pop)
213 continue;
214 switch_event_destroy(&pevent);
215 }
216 }
217}
218
219static switch_status_t expire_listener(listener_t ** listener)
220{
221 listener_t *l;
222
223 if (!listener || !*listener)
224 return SWITCH_STATUS_FALSE;
225 l = *listener;
226
227 if (!l->expire_time) {
228 l->expire_time = switch_epoch_time_now(NULL((void*)0));
229 }
230
231 if (switch_thread_rwlock_trywrlock(l->rwlock) != SWITCH_STATUS_SUCCESS) {
232 return SWITCH_STATUS_FALSE;
233 }
234
235 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(l->session)SWITCH_CHANNEL_ID_SESSION, "mod_event_socket.c", (const char *
)__func__, 235, (const char*)(l->session)
, SWITCH_LOG_CRIT, "Stateful Listener %u has expired\n", l->id);
236
237 flush_listener(*listener, SWITCH_TRUE, SWITCH_TRUE);
238 switch_core_hash_destroy(&l->event_hash);
239
240 if (l->allowed_event_hash) {
241 switch_core_hash_destroy(&l->allowed_event_hash);
242 }
243
244 if (l->allowed_api_hash) {
245 switch_core_hash_destroy(&l->allowed_api_hash);
246 }
247
248
249 switch_mutex_lock(l->filter_mutex);
250 if (l->filters) {
251 switch_event_destroy(&l->filters);
252 }
253
254 switch_mutex_unlock(l->filter_mutex);
255 switch_thread_rwlock_unlock(l->rwlock);
256 switch_core_destroy_memory_pool(&l->pool)switch_core_perform_destroy_memory_pool(&l->pool, "mod_event_socket.c"
, (const char *)__func__, 256)
;
257
258 *listener = NULL((void*)0);
259 return SWITCH_STATUS_SUCCESS;
260}
261
262static void event_handler(switch_event_t *event)
263{
264 switch_event_t *clone = NULL((void*)0);
265 listener_t *l, *lp, *last = NULL((void*)0);
266 time_t now = switch_epoch_time_now(NULL((void*)0));
267
268 switch_assert(event != NULL)((event != ((void*)0)) ? (void) (0) : __assert_fail ("event != ((void*)0)"
, "mod_event_socket.c", 268, __PRETTY_FUNCTION__))
;
269
270 if (!listen_list.ready) {
271 return;
272 }
273
274 lp = listen_list.listeners;
275
276 switch_mutex_lock(globals.listener_mutex);
277 while (lp) {
278 int send = 0;
279
280 l = lp;
281 lp = lp->next;
282
283 if (switch_test_flag(l, LFLAG_STATEFUL)((l)->flags & LFLAG_STATEFUL) && (l->expire_time || (l->timeout && now - l->last_flush > l->timeout))) {
284 if (expire_listener(&l) == SWITCH_STATUS_SUCCESS) {
285 if (last) {
286 last->next = lp;
287 } else {
288 listen_list.listeners = lp;
289 }
290 continue;
291 }
292 }
293
294 if (l->expire_time || !switch_test_flag(l, LFLAG_EVENTS)((l)->flags & LFLAG_EVENTS)) {
295 last = l;
296 continue;
297 }
298
299 if (l->event_list[SWITCH_EVENT_ALL]) {
300 send = 1;
301 } else if ((l->event_list[event->event_id])) {
302 if (event->event_id != SWITCH_EVENT_CUSTOM || !event->subclass_name || (switch_core_hash_find(l->event_hash, event->subclass_name))) {
303 send = 1;
304 }
305 }
306
307 if (send) {
308 switch_mutex_lock(l->filter_mutex);
309
310 if (l->filters && l->filters->headers) {
311 switch_event_header_t *hp;
312 const char *hval;
313
314 send = 0;
315
316 for (hp = l->filters->headers; hp; hp = hp->next) {
317 if ((hval = switch_event_get_header(event, hp->name)switch_event_get_header_idx(event, hp->name, -1))) {
318 const char *comp_to = hp->value;
319 int pos = 1, cmp = 0;
320
321 while (comp_to && *comp_to) {
322 if (*comp_to == '+') {
323 pos = 1;
324 } else if (*comp_to == '-') {
325 pos = 0;
326 } else if (*comp_to != ' ') {
327 break;
328 }
329 comp_to++;
330 }
331
332 if (send && pos) {
333 continue;
334 }
335
336 if (!comp_to) {
337 continue;
338 }
339
340 if (*hp->value == '/') {
341 switch_regex_t *re = NULL((void*)0);
342 int ovector[30];
343 cmp = !!switch_regex_perform(hval, comp_to, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));
344 switch_regex_safe_free(re)if (re) { switch_regex_free(re); re = ((void*)0); };
345 } else {
346 cmp = !strcasecmp(hval, comp_to);
347 }
348
349 if (cmp) {
350 if (pos) {
351 send = 1;
352 } else {
353 send = 0;
354 break;
355 }
356 }
357 }
358 }
359 }
360
361 switch_mutex_unlock(l->filter_mutex);
362 }
363
364 if (send && switch_test_flag(l, LFLAG_MYEVENTS)((l)->flags & LFLAG_MYEVENTS)) {
365 char *uuid = switch_event_get_header(event, "unique-id")switch_event_get_header_idx(event, "unique-id", -1);
366 if (!uuid || (l->session && strcmp(uuid, switch_core_session_get_uuid(l->session))__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(uuid) && __builtin_constant_p (switch_core_session_get_uuid
(l->session)) && (__s1_len = __builtin_strlen (uuid
), __s2_len = __builtin_strlen (switch_core_session_get_uuid(
l->session)), (!((size_t)(const void *)((uuid) + 1) - (size_t
)(const void *)(uuid) == 1) || __s1_len >= 4) && (
!((size_t)(const void *)((switch_core_session_get_uuid(l->
session)) + 1) - (size_t)(const void *)(switch_core_session_get_uuid
(l->session)) == 1) || __s2_len >= 4)) ? __builtin_strcmp
(uuid, switch_core_session_get_uuid(l->session)) : (__builtin_constant_p
(uuid) && ((size_t)(const void *)((uuid) + 1) - (size_t
)(const void *)(uuid) == 1) && (__s1_len = __builtin_strlen
(uuid), __s1_len < 4) ? (__builtin_constant_p (switch_core_session_get_uuid
(l->session)) && ((size_t)(const void *)((switch_core_session_get_uuid
(l->session)) + 1) - (size_t)(const void *)(switch_core_session_get_uuid
(l->session)) == 1) ? __builtin_strcmp (uuid, switch_core_session_get_uuid
(l->session)) : (__extension__ ({ const unsigned char *__s2
= (const unsigned char *) (const char *) (switch_core_session_get_uuid
(l->session)); int __result = (((const unsigned char *) (const
char *) (uuid))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (uuid))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (uuid))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (uuid))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(switch_core_session_get_uuid(l->session)) && ((size_t
)(const void *)((switch_core_session_get_uuid(l->session))
+ 1) - (size_t)(const void *)(switch_core_session_get_uuid(l
->session)) == 1) && (__s2_len = __builtin_strlen (
switch_core_session_get_uuid(l->session)), __s2_len < 4
) ? (__builtin_constant_p (uuid) && ((size_t)(const void
*)((uuid) + 1) - (size_t)(const void *)(uuid) == 1) ? __builtin_strcmp
(uuid, switch_core_session_get_uuid(l->session)) : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (uuid); int __result = (((const unsigned char *) (const
char *) (switch_core_session_get_uuid(l->session)))[0] - __s2
[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) (switch_core_session_get_uuid
(l->session)))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (switch_core_session_get_uuid(l->session)))[2] - __s2
[2]); if (__s2_len > 2 && __result == 0) __result =
(((const unsigned char *) (const char *) (switch_core_session_get_uuid
(l->session)))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(uuid, switch_core_session_get_uuid(l->session))))); })
)) {
367 send = 0;
368 }
369 }
370
371 if (send) {
372 if (switch_event_dup(&clone, event) == SWITCH_STATUS_SUCCESS) {
373 if (switch_queue_trypush(l->event_queue, clone) == SWITCH_STATUS_SUCCESS) {
374 if (l->lost_events) {
375 int le = l->lost_events;
376 l->lost_events = 0;
377 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(l->session)SWITCH_CHANNEL_ID_SESSION, "mod_event_socket.c", (const char *
)__func__, 377, (const char*)(l->session)
, SWITCH_LOG_CRIT, "Lost %d events!\n", le);
378 }
379 } else {
380 if (++l->lost_events > MAX_MISSED500) {
381 kill_listener(l, NULL((void*)0));
382 }
383 switch_event_destroy(&clone);
384 }
385 } else {
386 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(l->session)SWITCH_CHANNEL_ID_SESSION, "mod_event_socket.c", (const char *
)__func__, 386, (const char*)(l->session)
, SWITCH_LOG_ERROR, "Memory Error!\n");
387 }
388 }
389 last = l;
390 }
391 switch_mutex_unlock(globals.listener_mutex);
392}
393
394SWITCH_STANDARD_APP(socket_function)static void socket_function (switch_core_session_t *session, const
char *data)
395{
396 char *host, *port_name, *path;
397 switch_socket_t *new_sock;
398 switch_sockaddr_t *sa;
399 switch_port_t port = 8084;
400 listener_t *listener;
401 int argc = 0, x = 0;
402 char *argv[80] = { 0 };
403 char *mydata;
404 switch_channel_t *channel = NULL((void*)0);
405
406 channel = switch_core_session_get_channel(session);
407
408 if (data && (mydata = switch_core_session_strdup(session, data)switch_core_perform_session_strdup(session, data, "mod_event_socket.c"
, (const char *)__func__, 408)
)) {
409 argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
410 }
411
412 if (argc < 1) {
413 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_event_socket.c", (const char *
)__func__, 413, (const char*)(session)
, SWITCH_LOG_ERROR, "Parse Error!\n");
414 return;
415 }
416
417 host = argv[0];
418
419 if (zstr(host)_zstr(host)) {
420 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_event_socket.c", (const char *
)__func__, 420, (const char*)(session)
, SWITCH_LOG_ERROR, "Missing Host!\n");
421 return;
422 }
423
424 if ((port_name = strrchr(host, ':'))) {
425 *port_name++ = '\0';
426 port = (switch_port_t) atoi(port_name);
427 }
428
429 if ((path = strchr((port_name ? port_name : host), '/')(__extension__ (__builtin_constant_p ('/') && !__builtin_constant_p
((port_name ? port_name : host)) && ('/') == '\0' ? (
char *) __rawmemchr ((port_name ? port_name : host), '/') : __builtin_strchr
((port_name ? port_name : host), '/')))
)) {
430 *path++ = '\0';
431 switch_channel_set_variable(channel, "socket_path", path)switch_channel_set_variable_var_check(channel, "socket_path",
path, SWITCH_TRUE)
;
432 }
433
434 switch_channel_set_variable(channel, "socket_host", host)switch_channel_set_variable_var_check(channel, "socket_host",
host, SWITCH_TRUE)
;
435
436 if (switch_sockaddr_info_get(&sa, host, SWITCH_UNSPEC0, port, 0, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
437 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_event_socket.c", (const char *
)__func__, 437, (const char*)(session)
, SWITCH_LOG_ERROR, "Socket Error!\n");
438 return;
439 }
440
441 if (switch_socket_create(&new_sock, switch_sockaddr_get_family(sa), SOCK_STREAMSOCK_STREAM, SWITCH_PROTO_TCP6, switch_core_session_get_pool(session))
442 != SWITCH_STATUS_SUCCESS) {
443 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_event_socket.c", (const char *
)__func__, 443, (const char*)(session)
, SWITCH_LOG_ERROR, "Socket Error!\n");
444 return;
445 }
446
447 switch_socket_opt_set(new_sock, SWITCH_SO_KEEPALIVE2, 1);
448 switch_socket_opt_set(new_sock, SWITCH_SO_TCP_NODELAY512, 1);
449 switch_socket_opt_set(new_sock, SWITCH_SO_TCP_KEEPIDLE520, 30);
450 switch_socket_opt_set(new_sock, SWITCH_SO_TCP_KEEPINTVL530, 30);
451
452 if (switch_socket_connect(new_sock, sa) != SWITCH_STATUS_SUCCESS) {
453 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_event_socket.c", (const char *
)__func__, 453, (const char*)(session)
, SWITCH_LOG_ERROR, "Socket Error!\n");
454 return;
455 }
456
457
458 if (!(listener = switch_core_session_alloc(session, sizeof(*listener))switch_core_perform_session_alloc(session, sizeof(*listener),
"mod_event_socket.c", (const char *)__func__, 458)
)) {
459 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_event_socket.c", (const char *
)__func__, 459, (const char*)(session)
, SWITCH_LOG_ERROR, "Memory Error\n");
460 return;
461 }
462
463 switch_thread_rwlock_create(&listener->rwlock, switch_core_session_get_pool(session));
464 switch_queue_create(&listener->event_queue, MAX_QUEUE_LEN100000, switch_core_session_get_pool(session));
465 switch_queue_create(&listener->log_queue, MAX_QUEUE_LEN100000, switch_core_session_get_pool(session));
466
467 listener->sock = new_sock;
468 listener->pool = switch_core_session_get_pool(session);
469 listener->format = EVENT_FORMAT_PLAIN;
470 listener->session = session;
471 switch_set_flag(listener, LFLAG_ALLOW_LOG)(listener)->flags |= (LFLAG_ALLOW_LOG);
472
473 switch_socket_create_pollset(&listener->pollfd, listener->sock, SWITCH_POLLIN0x001 | SWITCH_POLLERR0x010, listener->pool);
474
475 switch_mutex_init(&listener->flag_mutex, SWITCH_MUTEX_NESTED0x1, listener->pool);
476 switch_mutex_init(&listener->filter_mutex, SWITCH_MUTEX_NESTED0x1, listener->pool);
477
478 switch_core_hash_init(&listener->event_hash)switch_core_hash_init_case(&listener->event_hash, SWITCH_TRUE
)
;
479 switch_set_flag(listener, LFLAG_AUTHED)(listener)->flags |= (LFLAG_AUTHED);
480 switch_set_flag(listener, LFLAG_OUTBOUND)(listener)->flags |= (LFLAG_OUTBOUND);
481 for (x = 1; x < argc; x++) {
482 if (argv[x] && !strcasecmp(argv[x], "full")) {
483 switch_set_flag(listener, LFLAG_FULL)(listener)->flags |= (LFLAG_FULL);
484 } else if (argv[x] && !strcasecmp(argv[x], "async")) {
485 switch_set_flag(listener, LFLAG_ASYNC)(listener)->flags |= (LFLAG_ASYNC);
486 }
487 }
488
489 if (switch_test_flag(listener, LFLAG_ASYNC)((listener)->flags & LFLAG_ASYNC)) {
490 const char *var;
491
492 launch_listener_thread(listener);
493
494 while (switch_channel_ready(channel)switch_channel_test_ready(channel, SWITCH_TRUE, SWITCH_FALSE) && !switch_test_flag(listener, LFLAG_CONNECTED)((listener)->flags & LFLAG_CONNECTED)) {
495 switch_cond_next();
496 }
497
498 switch_ivr_park(session, NULL((void*)0));
499
500 switch_ivr_parse_all_events(session);
501
502 if (switch_test_flag(listener, LFLAG_RESUME)((listener)->flags & LFLAG_RESUME) || ((var = switch_channel_get_variable(channel, "socket_resume")switch_channel_get_variable_dup(channel, "socket_resume", SWITCH_TRUE
, -1)
) && switch_true(var))) {
503 switch_channel_set_state(channel, CS_EXECUTE)switch_channel_perform_set_state(channel, "mod_event_socket.c"
, (const char *)__func__, 503, CS_EXECUTE)
;
504 }
505
506 return;
507 } else {
508 listener_run(NULL((void*)0), (void *) listener);
509 }
510
511 if (switch_channel_down(channel)(switch_channel_check_signal(channel, SWITCH_TRUE) || switch_channel_get_state
(channel) >= CS_HANGUP)
) {
512 while (switch_test_flag(listener, LFLAG_SESSION)((listener)->flags & LFLAG_SESSION)) {
513 switch_yield(100000)switch_sleep(100000);;
514 }
515 }
516
517}
518
519
520static void close_socket(switch_socket_t ** sock)
521{
522 switch_mutex_lock(listen_list.sock_mutex);
523 if (*sock) {
524 switch_socket_shutdown(*sock, SWITCH_SHUTDOWN_READWRITE);
525 switch_socket_close(*sock);
526 *sock = NULL((void*)0);
527 }
528 switch_mutex_unlock(listen_list.sock_mutex);
529}
530
531SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_event_socket_shutdown)switch_status_t mod_event_socket_shutdown (void)
532{
533 int sanity = 0;
534
535 prefs.done = 1;
536
537 kill_all_listeners();
538 switch_log_unbind_logger(socket_logger);
539
540 close_socket(&listen_list.sock);
541
542 while (prefs.threads) {
543 switch_yield(100000)switch_sleep(100000);;
544 kill_all_listeners();
545 if (++sanity >= 200) {
546 break;
547 }
548 }
549
550 switch_event_unbind(&globals.node);
551
552 switch_safe_free(prefs.ip)if (prefs.ip) {free(prefs.ip);prefs.ip=((void*)0);};
553 switch_safe_free(prefs.password)if (prefs.password) {free(prefs.password);prefs.password=((void
*)0);}
;
554
555 return SWITCH_STATUS_SUCCESS;
556}
557
558static void add_listener(listener_t *listener)
559{
560 /* add me to the listeners so I get events */
561 switch_mutex_lock(globals.listener_mutex);
562 listener->next = listen_list.listeners;
563 listen_list.listeners = listener;
564 switch_mutex_unlock(globals.listener_mutex);
565}
566
567static void remove_listener(listener_t *listener)
568{
569 listener_t *l, *last = NULL((void*)0);
570
571 switch_mutex_lock(globals.listener_mutex);
572 for (l = listen_list.listeners; l; l = l->next) {
573 if (l == listener) {
574 if (last) {
575 last->next = l->next;
576 } else {
577 listen_list.listeners = l->next;
578 }
579 }
580 last = l;
581 }
582 switch_mutex_unlock(globals.listener_mutex);
583}
584
585static void send_disconnect(listener_t *listener, const char *message)
586{
587
588 char disco_buf[512] = "";
589 switch_size_t len, mlen;
590
591 if (zstr(message)_zstr(message)) {
592 message = "Disconnected.\n";
593 }
594
595 mlen = strlen(message);
596
597 if (listener->session) {
598 switch_snprintf(disco_buf, sizeof(disco_buf), "Content-Type: text/disconnect-notice\n"
599 "Controlled-Session-UUID: %s\n"
600 "Content-Disposition: disconnect\n" "Content-Length: %d\n\n", switch_core_session_get_uuid(listener->session), (int)mlen);
601 } else {
602 switch_snprintf(disco_buf, sizeof(disco_buf), "Content-Type: text/disconnect-notice\nContent-Length: %d\n\n", (int)mlen);
603 }
604
605 if (!listener->sock) return;
606
607 len = strlen(disco_buf);
608 switch_socket_send(listener->sock, disco_buf, &len);
609 if (len > 0) {
610 len = mlen;
611 switch_socket_send(listener->sock, message, &len);
612 }
613}
614
615static void kill_listener(listener_t *l, const char *message)
616{
617
618 if (message) {
619 send_disconnect(l, message);
620 }
621
622 switch_clear_flag(l, LFLAG_RUNNING)(l)->flags &= ~(LFLAG_RUNNING);
623 if (l->sock) {
624 switch_socket_shutdown(l->sock, SWITCH_SHUTDOWN_READWRITE);
625 switch_socket_close(l->sock);
626 }
627
628}
629
630static void kill_all_listeners(void)
631{
632 listener_t *l;
633
634 switch_mutex_lock(globals.listener_mutex);
635 for (l = listen_list.listeners; l; l = l->next) {
636 kill_listener(l, "The system is being shut down.\n");
637 }
638 switch_mutex_unlock(globals.listener_mutex);
639}
640
641
642static listener_t *find_listener(uint32_t id)
643{
644 listener_t *l, *r = NULL((void*)0);
645
646 switch_mutex_lock(globals.listener_mutex);
647 for (l = listen_list.listeners; l; l = l->next) {
648 if (l->id && l->id == id && !l->expire_time) {
649 if (switch_thread_rwlock_tryrdlock(l->rwlock) == SWITCH_STATUS_SUCCESS) {
650 r = l;
651 }
652 break;
653 }
654 }
655 switch_mutex_unlock(globals.listener_mutex);
656 return r;
657}
658
659static void strip_cr(char *s)
660{
661 char *p;
662 if ((p = strchr(s, '\r')(__extension__ (__builtin_constant_p ('\r') && !__builtin_constant_p
(s) && ('\r') == '\0' ? (char *) __rawmemchr (s, '\r'
) : __builtin_strchr (s, '\r')))
) || (p = strchr(s, '\n')(__extension__ (__builtin_constant_p ('\n') && !__builtin_constant_p
(s) && ('\n') == '\0' ? (char *) __rawmemchr (s, '\n'
) : __builtin_strchr (s, '\n')))
)) {
663 *p = '\0';
664 }
665}
666
667
668static void xmlize_listener(listener_t *listener, switch_stream_handle_t *stream)
669{
670 stream->write_function(stream, " <listener>\n");
671 stream->write_function(stream, " <listen-id>%u</listen-id>\n", listener->id);
672 stream->write_function(stream, " <format>%s</format>\n", format2str(listener->format));
673 stream->write_function(stream, " <timeout>%u</timeout>\n", listener->timeout);
674 stream->write_function(stream, " </listener>\n");
675}
676
677SWITCH_STANDARD_API(event_sink_function)static switch_status_t event_sink_function ( const char *cmd,
switch_core_session_t *session, switch_stream_handle_t *stream
)
678{
679 char *http = NULL((void*)0);
680 char *wcmd = NULL((void*)0);
681 char *format = NULL((void*)0);
682 listener_t *listener = NULL((void*)0);
683
684 if (stream->param_event) {
685 http = switch_event_get_header(stream->param_event, "http-host")switch_event_get_header_idx(stream->param_event, "http-host"
, -1)
;
686 wcmd = switch_event_get_header(stream->param_event, "command")switch_event_get_header_idx(stream->param_event, "command"
, -1)
;
687 format = switch_event_get_header(stream->param_event, "format")switch_event_get_header_idx(stream->param_event, "format",
-1)
;
688 }
689
690 if (!http) {
691 stream->write_function(stream, "This is a web application!\n");
692 return SWITCH_STATUS_SUCCESS;
693 }
694
695 if (!format) {
696 format = "xml";
697 }
698
699 if (switch_stristr("json", format)) {
700 stream->write_function(stream, "Content-Type: application/json\n\n");
701 } else {
702 stream->write_function(stream, "Content-Type: text/xml\n\n");
703
704 stream->write_function(stream, "<?xml version=\"1.0\"?>\n");
705 stream->write_function(stream, "<root>\n");
706 }
707
708 if (!wcmd) {
709 stream->write_function(stream, "<data><reply type=\"error\">Missing command parameter!</reply></data>\n");
710 goto end;
711 }
712
713 if (!strcasecmp(wcmd, "filter")) {
714 char *action = switch_event_get_header(stream->param_event, "action")switch_event_get_header_idx(stream->param_event, "action",
-1)
;
715 char *header_name = switch_event_get_header(stream->param_event, "header-name")switch_event_get_header_idx(stream->param_event, "header-name"
, -1)
;
716 char *header_val = switch_event_get_header(stream->param_event, "header-val")switch_event_get_header_idx(stream->param_event, "header-val"
, -1)
;
717 char *id = switch_event_get_header(stream->param_event, "listen-id")switch_event_get_header_idx(stream->param_event, "listen-id"
, -1)
;
718 uint32_t idl = 0;
719
720 if (id) {
721 idl = (uint32_t) atol(id);
722 }
723
724 if (!(listener = find_listener(idl))) {
725 stream->write_function(stream, "<data><reply type=\"error\">Invalid Listen-ID</reply></data>\n");
726 goto end;
727 }
728
729 if (zstr(action)_zstr(action)) {
730 stream->write_function(stream, "<data><reply type=\"error\">Invalid Syntax</reply></data>\n");
731 goto end;
732 }
733
734 switch_mutex_lock(listener->filter_mutex);
735 if (!listener->filters) {
736 switch_event_create_plain(&listener->filters, SWITCH_EVENT_CLONE);
737 }
738
739 if (!strcasecmp(action, "delete")) {
740 if (zstr(header_val)_zstr(header_val)) {
741 stream->write_function(stream, "<data><reply type=\"error\">Invalid Syntax</reply></data>\n");
742 goto filter_end;
743 }
744
745 if (!strcasecmp(header_val, "all")) {
746 switch_event_destroy(&listener->filters);
747 switch_event_create_plain(&listener->filters, SWITCH_EVENT_CLONE);
748 } else {
749 switch_event_del_header(listener->filters, header_val)switch_event_del_header_val(listener->filters, header_val,
((void*)0))
;
750 }
751 stream->write_function(stream, "<data>\n <reply type=\"success\">filter deleted.</reply>\n<api-command>\n");
752 } else if (!strcasecmp(action, "add")) {
753 if (zstr(header_name)_zstr(header_name) || zstr(header_val)_zstr(header_val)) {
754 stream->write_function(stream, "<data><reply type=\"error\">Invalid Syntax</reply></data>\n");
755 goto filter_end;
756 }
757 switch_event_add_header_string(listener->filters, SWITCH_STACK_BOTTOM, header_name, header_val);
758 stream->write_function(stream, "<data>\n <reply type=\"success\">filter added.</reply>\n<api-command>\n");
759 } else {
760 stream->write_function(stream, "<data><reply type=\"error\">Invalid Syntax</reply></data>\n");
761 }
762
763 filter_end:
764
765 switch_mutex_unlock(listener->filter_mutex);
766
767 } else if (!strcasecmp(wcmd, "stop-logging")) {
768 char *id = switch_event_get_header(stream->param_event, "listen-id")switch_event_get_header_idx(stream->param_event, "listen-id"
, -1)
;
769 uint32_t idl = 0;
770
771 if (id) {
772 idl = (uint32_t) atol(id);
773 }
774
775 if (!(listener = find_listener(idl))) {
776 stream->write_function(stream, "<data><reply type=\"error\">Invalid Listen-ID</reply></data>\n");
777 goto end;
778 }
779
780 if (switch_test_flag(listener, LFLAG_LOG)((listener)->flags & LFLAG_LOG)) {
781 switch_clear_flag_locked(listener, LFLAG_LOG)switch_mutex_lock(listener->flag_mutex); (listener)->flags
&= ~(LFLAG_LOG); switch_mutex_unlock(listener->flag_mutex
);
;
782 stream->write_function(stream, "<data><reply type=\"success\">Not Logging</reply></data>\n");
783 } else {
784 stream->write_function(stream, "<data><reply type=\"error\">Not Logging</reply></data>\n");
785 }
786
787 goto end;
788
789 } else if (!strcasecmp(wcmd, "set-loglevel")) {
790 char *loglevel = switch_event_get_header(stream->param_event, "loglevel")switch_event_get_header_idx(stream->param_event, "loglevel"
, -1)
;
791 char *id = switch_event_get_header(stream->param_event, "listen-id")switch_event_get_header_idx(stream->param_event, "listen-id"
, -1)
;
792 uint32_t idl = 0;
793
794 if (id) {
795 idl = (uint32_t) atol(id);
796 }
797
798 if (!(listener = find_listener(idl))) {
799 stream->write_function(stream, "<data><reply type=\"error\">Invalid Listen-ID</reply></data>\n");
800 goto end;
801 }
802
803 if (loglevel) {
804 switch_log_level_t ltype = switch_log_str2level(loglevel);
805 if (ltype != SWITCH_LOG_INVALID) {
806 listener->level = ltype;
807 switch_set_flag(listener, LFLAG_LOG)(listener)->flags |= (LFLAG_LOG);
808 stream->write_function(stream, "<data><reply type=\"success\">Log Level %s</reply></data>\n", loglevel);
809 } else {
810 stream->write_function(stream, "<data><reply type=\"error\">Invalid Level</reply></data>\n");
811 }
812 } else {
813 stream->write_function(stream, "<data><reply type=\"error\">Invalid Syntax</reply></data>\n");
814 }
815
816 goto end;
817
818 } else if (!strcasecmp(wcmd, "create-listener")) {
819 char *events = switch_event_get_header(stream->param_event, "events")switch_event_get_header_idx(stream->param_event, "events",
-1)
;
820 char *loglevel = switch_event_get_header(stream->param_event, "loglevel")switch_event_get_header_idx(stream->param_event, "loglevel"
, -1)
;
821 switch_memory_pool_t *pool;
822 char *next, *cur;
823 uint32_t count = 0, key_count = 0;
824 uint8_t custom = 0;
825 char *edup;
826
827 if (zstr(events)_zstr(events) && zstr(loglevel)_zstr(loglevel)) {
828 if (switch_stristr("json", format)) {
829 stream->write_function(stream, "{\"reply\": \"error\", \"reply_text\":\"Missing parameter!\"}");
830 } else {
831 stream->write_function(stream, "<data><reply type=\"error\">Missing parameter!</reply></data>\n");
832 }
833 goto end;
834 }
835
836 switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "mod_event_socket.c"
, (const char *)__func__, 836)
;
837 listener = switch_core_alloc(pool, sizeof(*listener))switch_core_perform_alloc(pool, sizeof(*listener), "mod_event_socket.c"
, (const char *)__func__, 837)
;
838 listener->pool = pool;
839 listener->format = EVENT_FORMAT_PLAIN;
840 switch_mutex_init(&listener->flag_mutex, SWITCH_MUTEX_NESTED0x1, listener->pool);
841 switch_mutex_init(&listener->filter_mutex, SWITCH_MUTEX_NESTED0x1, listener->pool);
842
843
844 switch_core_hash_init(&listener->event_hash)switch_core_hash_init_case(&listener->event_hash, SWITCH_TRUE
)
;
845 switch_set_flag(listener, LFLAG_AUTHED)(listener)->flags |= (LFLAG_AUTHED);
846 switch_set_flag(listener, LFLAG_STATEFUL)(listener)->flags |= (LFLAG_STATEFUL);
847 switch_set_flag(listener, LFLAG_ALLOW_LOG)(listener)->flags |= (LFLAG_ALLOW_LOG);
848 switch_queue_create(&listener->event_queue, MAX_QUEUE_LEN100000, listener->pool);
849 switch_queue_create(&listener->log_queue, MAX_QUEUE_LEN100000, listener->pool);
850
851 if (loglevel) {
852 switch_log_level_t ltype = switch_log_str2level(loglevel);
853 if (ltype != SWITCH_LOG_INVALID) {
854 listener->level = ltype;
855 switch_set_flag(listener, LFLAG_LOG)(listener)->flags |= (LFLAG_LOG);
856 }
857 }
858 switch_thread_rwlock_create(&listener->rwlock, listener->pool);
859 listener->id = next_id();
860 listener->timeout = 60;
861 listener->last_flush = switch_epoch_time_now(NULL((void*)0));
862
863 if (events) {
864 char delim = ',';
865
866 if (switch_stristr("xml", format)) {
867 listener->format = EVENT_FORMAT_XML;
868 } else if (switch_stristr("json", format)) {
869 listener->format = EVENT_FORMAT_JSON;
870 } else {
871 listener->format = EVENT_FORMAT_PLAIN;
872 }
873
874 edup = strdup(events)(__extension__ (__builtin_constant_p (events) && ((size_t
)(const void *)((events) + 1) - (size_t)(const void *)(events
) == 1) ? (((const char *) (events))[0] == '\0' ? (char *) calloc
((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (events)
+ 1; char *__retval = (char *) malloc (__len); if (__retval !=
((void*)0)) __retval = (char *) memcpy (__retval, events, __len
); __retval; })) : __strdup (events)))
;
875
876 if (strchr(edup, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p
(edup) && (' ') == '\0' ? (char *) __rawmemchr (edup
, ' ') : __builtin_strchr (edup, ' ')))
) {
877 delim = ' ';
878 }
879
880 for (cur = edup; cur; count++) {
881 switch_event_types_t type;
882
883 if ((next = strchr(cur, delim)(__extension__ (__builtin_constant_p (delim) && !__builtin_constant_p
(cur) && (delim) == '\0' ? (char *) __rawmemchr (cur
, delim) : __builtin_strchr (cur, delim)))
)) {
884 *next++ = '\0';
885 }
886
887 if (custom) {
888 switch_core_hash_insert(listener->event_hash, cur, MARKER)switch_core_hash_insert_destructor(listener->event_hash, cur
, MARKER, ((void*)0))
;
889 } else if (switch_name_event(cur, &type) == SWITCH_STATUS_SUCCESS) {
890 key_count++;
891 if (type == SWITCH_EVENT_ALL) {
892 uint32_t x = 0;
893 for (x = 0; x < SWITCH_EVENT_ALL; x++) {
894 listener->event_list[x] = 1;
895 }
896 }
897 if (type <= SWITCH_EVENT_ALL) {
898 listener->event_list[type] = 1;
899 }
900 if (type == SWITCH_EVENT_CUSTOM) {
901 custom++;
902 }
903 }
904
905 cur = next;
906 }
907
908
909 switch_safe_free(edup)if (edup) {free(edup);edup=((void*)0);};
910
911 if (!key_count) {
912 switch_core_hash_destroy(&listener->event_hash);
913 switch_core_destroy_memory_pool(&listener->pool)switch_core_perform_destroy_memory_pool(&listener->pool
, "mod_event_socket.c", (const char *)__func__, 913)
;
914 if (listener->format == EVENT_FORMAT_JSON) {
915 stream->write_function(stream, "{\"reply\": \"error\", \"reply_text\":\"No keywords supplied\"}");
916 } else {
917 stream->write_function(stream, "<data><reply type=\"error\">No keywords supplied</reply></data>\n");
918 }
919 goto end;
920 }
921 }
922
923 switch_set_flag_locked(listener, LFLAG_EVENTS)((listener->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("listener->flag_mutex != ((void*)0)", "mod_event_socket.c"
, 923, __PRETTY_FUNCTION__));switch_mutex_lock(listener->flag_mutex
);(listener)->flags |= (LFLAG_EVENTS);switch_mutex_unlock(
listener->flag_mutex);
;
924 add_listener(listener);
925 if (listener->format == EVENT_FORMAT_JSON) {
926 cJSON *cj, *cjlistener;
927 char *p;
928
929 cj = cJSON_CreateObject();
930 cjlistener = cJSON_CreateObject();
931 cJSON_AddNumberToObject(cjlistener, "listen-id", listener->id)cJSON_AddItemToObject(cjlistener, "listen-id", cJSON_CreateNumber
(listener->id))
;
932 cJSON_AddItemToObject(cjlistener, "format", cJSON_CreateString(format2str(listener->format)));
933 cJSON_AddNumberToObject(cjlistener, "timeout", listener->timeout)cJSON_AddItemToObject(cjlistener, "timeout", cJSON_CreateNumber
(listener->timeout))
;
934 cJSON_AddItemToObject(cj, "listener", cjlistener);
935 p = cJSON_Print(cj);
936 stream->write_function(stream, p);
937 switch_safe_free(p)if (p) {free(p);p=((void*)0);};
938 cJSON_Delete(cj);
939 } else {
940 stream->write_function(stream, "<data>\n");
941 stream->write_function(stream, " <reply type=\"success\">Listener %u Created</reply>\n", listener->id);
942 xmlize_listener(listener, stream);
943 stream->write_function(stream, "</data>\n");
944 }
945
946 if (globals.debug > 0) {
947 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_event_socket.c", (const char *
)__func__, 947, (const char*)(session)
, SWITCH_LOG_DEBUG, "Creating event-sink listener [%u]\n", listener->id);
948 }
949
950 goto end;
951 } else if (!strcasecmp(wcmd, "destroy-listener")) {
952 char *id = switch_event_get_header(stream->param_event, "listen-id")switch_event_get_header_idx(stream->param_event, "listen-id"
, -1)
;
953 uint32_t idl = 0;
954
955 if (id) {
956 idl = (uint32_t) atol(id);
957 }
958
959 if ((listener = find_listener(idl))) {
960 if (globals.debug > 0) {
961 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_event_socket.c", (const char *
)__func__, 961, (const char*)(session)
, SWITCH_LOG_DEBUG, "Destroying event-sink listener [%u]\n", idl);
962 }
963 stream->write_function(stream, "<data>\n <reply type=\"success\">listener %u destroyed</reply>\n", listener->id);
964 xmlize_listener(listener, stream);
965 stream->write_function(stream, "</data>\n");
966 listener->expire_time = switch_epoch_time_now(NULL((void*)0));
967 goto end;
968 } else {
969 if (globals.debug > 0) {
970 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_event_socket.c", (const char *
)__func__, 970, (const char*)(session)
, SWITCH_LOG_DEBUG, "Request to destroy unknown event-sink listener [%u]\n", idl);
971 }
972 stream->write_function(stream, "<data><reply type=\"error\">Can't find listener</reply></data>\n");
973 goto end;
974 }
975
976 } else if (!strcasecmp(wcmd, "check-listener")) {
977 char *id = switch_event_get_header(stream->param_event, "listen-id")switch_event_get_header_idx(stream->param_event, "listen-id"
, -1)
;
978 uint32_t idl = 0;
979 void *pop;
980 switch_event_t *pevent = NULL((void*)0);
981 cJSON *cj = NULL((void*)0), *cjevents = NULL((void*)0);
982
983 if (id) {
984 idl = (uint32_t) atol(id);
985 }
986
987 if (!(listener = find_listener(idl))) {
988 if (switch_stristr("json", format)) {
989 stream->write_function(stream, "{\"reply\": \"error\", \"reply_text\":\"Can't find listener\"}");
990 } else {
991 stream->write_function(stream, "<data><reply type=\"error\">Can't find listener</reply></data>\n");
992 }
993 goto end;
994 }
995
996 listener->last_flush = switch_epoch_time_now(NULL((void*)0));
997
998 if (listener->format == EVENT_FORMAT_JSON) {
999 cJSON *cjlistener;
1000 cj = cJSON_CreateObject();
1001 cjlistener = cJSON_CreateObject();
1002 cJSON_AddNumberToObject(cjlistener, "listen-id", listener->id)cJSON_AddItemToObject(cjlistener, "listen-id", cJSON_CreateNumber
(listener->id))
;
1003 cJSON_AddItemToObject(cjlistener, "format", cJSON_CreateString(format2str(listener->format)));
1004 cJSON_AddNumberToObject(cjlistener, "timeout", listener->timeout)cJSON_AddItemToObject(cjlistener, "timeout", cJSON_CreateNumber
(listener->timeout))
;
1005 cJSON_AddItemToObject(cj, "listener", cjlistener);
1006 } else {
1007 stream->write_function(stream, "<data>\n <reply type=\"success\">Current Events Follow</reply>\n");
1008 xmlize_listener(listener, stream);
1009 }
1010
1011 if (switch_test_flag(listener, LFLAG_LOG)((listener)->flags & LFLAG_LOG)) {
1012 stream->write_function(stream, "<log_data>\n");
1013
1014 while (switch_queue_trypop(listener->log_queue, &pop) == SWITCH_STATUS_SUCCESS) {
1015 switch_log_node_t *dnode = (switch_log_node_t *) pop;
1016 size_t encode_len = (strlen(dnode->data) * 3) + 1;
1017 char *encode_buf = malloc(encode_len);
1018
1019 switch_assert(encode_buf)((encode_buf) ? (void) (0) : __assert_fail ("encode_buf", "mod_event_socket.c"
, 1019, __PRETTY_FUNCTION__))
;
1020
1021 memset(encode_buf, 0, encode_len);
1022 switch_url_encode((char *) dnode->data, encode_buf, encode_len);
1023
1024
1025 stream->write_function(stream,
1026 "<log log-level=\"%d\" text-channel=\"%d\" log-file=\"%s\" log-func=\"%s\" log-line=\"%d\" user-data=\"%s\">%s</log>\n",
1027 dnode->level, dnode->channel, dnode->file, dnode->func, dnode->line, switch_str_nil(dnode->userdata)(dnode->userdata ? dnode->userdata : ""), encode_buf);
1028 free(encode_buf);
1029 switch_log_node_free(&dnode);
1030 }
1031
1032 stream->write_function(stream, "</log_data>\n");
1033 }
1034
1035 if (listener->format == EVENT_FORMAT_JSON) {
1036 cjevents = cJSON_CreateArray();
1037 } else {
1038 stream->write_function(stream, "<events>\n");
1039 }
1040
1041 while (switch_queue_trypop(listener->event_queue, &pop) == SWITCH_STATUS_SUCCESS) {
1042 //char *etype;
1043 pevent = (switch_event_t *) pop;
1044
1045 if (listener->format == EVENT_FORMAT_PLAIN) {
1046 //etype = "plain";
1047 switch_event_serialize(pevent, &listener->ebuf, SWITCH_TRUE);
1048 stream->write_function(stream, "<event type=\"plain\">\n%s</event>", listener->ebuf);
1049 } else if (listener->format == EVENT_FORMAT_JSON) {
1050 //etype = "json";
1051 cJSON *cjevent = NULL((void*)0);
1052
1053 switch_event_serialize_json_obj(pevent, &cjevent);
1054 cJSON_AddItemToArray(cjevents, cjevent);
1055 } else {
1056 switch_xml_t xml;
1057 //etype = "xml";
1058
1059 if ((xml = switch_event_xmlize(pevent, SWITCH_VA_NONE"%s", ""))) {
1060 listener->ebuf = switch_xml_toxml(xml, SWITCH_FALSE);
1061 switch_xml_free(xml);
1062 } else {
1063 stream->write_function(stream, "<data><reply type=\"error\">XML Render Error</reply></data>\n");
1064 break;
1065 }
1066
1067 stream->write_function(stream, "%s\n", listener->ebuf);
1068 }
1069
1070 switch_safe_free(listener->ebuf)if (listener->ebuf) {free(listener->ebuf);listener->
ebuf=((void*)0);}
;
1071 switch_event_destroy(&pevent);
1072 }
1073
1074 if (listener->format == EVENT_FORMAT_JSON) {
1075 char *p = "{}";
1076 cJSON_AddItemToObject(cj, "events", cjevents);
1077 p = cJSON_Print(cj);
1078 if (cj && p) stream->write_function(stream, p);
1079 switch_safe_free(p)if (p) {free(p);p=((void*)0);};
1080 cJSON_Delete(cj);
1081 cj = NULL((void*)0);
1082 } else {
1083 stream->write_function(stream, " </events>\n</data>\n");
1084 }
1085
1086 if (pevent) {
1087 switch_event_destroy(&pevent);
1088 }
1089
1090 switch_thread_rwlock_unlock(listener->rwlock);
1091 } else if (!strcasecmp(wcmd, "exec-fsapi")) {
1092 char *api_command = switch_event_get_header(stream->param_event, "fsapi-command")switch_event_get_header_idx(stream->param_event, "fsapi-command"
, -1)
;
1093 char *api_args = switch_event_get_header(stream->param_event, "fsapi-args")switch_event_get_header_idx(stream->param_event, "fsapi-args"
, -1)
;
1094 switch_event_t *event, *oevent;
1095
1096 if (!(api_command)) {
1097 stream->write_function(stream, "<data><reply type=\"error\">INVALID API COMMAND!</reply></data>\n");
1098 goto end;
1099 }
1100
1101 stream->write_function(stream, "<data>\n <reply type=\"success\">Execute API Command</reply>\n<api-command>\n");
1102 switch_event_create(&event, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("mod_event_socket.c", (
const char * )(const char *)__func__, 1102, &event, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
1103 oevent = stream->param_event;
1104 stream->param_event = event;
1105
1106 if (!strcasecmp(api_command, "unload") && !strcasecmp(api_args, "mod_event_socket")) {
1107 api_command = "bgapi";
1108 api_args = "unload mod_event_socket";
1109 } else if (!strcasecmp(api_command, "reload") && !strcasecmp(api_args, "mod_event_socket")) {
1110 api_command = "bgapi";
1111 api_args = "reload mod_event_socket";
1112 }
1113
1114 switch_api_execute(api_command, api_args, NULL((void*)0), stream);
1115 stream->param_event = oevent;
1116 stream->write_function(stream, " </api-command>\n</data>");
1117 } else {
1118 stream->write_function(stream, "<data><reply type=\"error\">INVALID COMMAND!</reply></data\n");
1119 }
1120
1121 end:
1122
1123 if (switch_stristr("json", format)) {
1124 } else {
1125 stream->write_function(stream, "</root>\n\n");
1126 }
1127
1128 return SWITCH_STATUS_SUCCESS;
1129}
1130
1131
1132SWITCH_MODULE_LOAD_FUNCTION(mod_event_socket_load)switch_status_t mod_event_socket_load (switch_loadable_module_interface_t
**module_interface, switch_memory_pool_t *pool)
1133{
1134 switch_application_interface_t *app_interface;
1135 switch_api_interface_t *api_interface;
1136
1137 memset(&globals, 0, sizeof(globals));
1138
1139 switch_mutex_init(&globals.listener_mutex, SWITCH_MUTEX_NESTED0x1, pool);
1140
1141 memset(&listen_list, 0, sizeof(listen_list));
1142 switch_mutex_init(&listen_list.sock_mutex, SWITCH_MUTEX_NESTED0x1, pool);
1143
1144 if (switch_event_bind_removable(modname, SWITCH_EVENT_ALL, SWITCH_EVENT_SUBCLASS_ANY((void*)0), event_handler, NULL((void*)0), &globals.node) != SWITCH_STATUS_SUCCESS) {
1145 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_event_socket.c", (const char *)__func__
, 1145, ((void*)0)
, SWITCH_LOG_ERROR, "Couldn't bind!\n");
1146 return SWITCH_STATUS_GENERR;
1147 }
1148
1149 switch_log_bind_logger(socket_logger, SWITCH_LOG_DEBUG, SWITCH_FALSE);
1150
1151 /* connect my internal structure to the blank pointer passed to me */
1152 *module_interface = switch_loadable_module_create_module_interface(pool, modname);
1153 SWITCH_ADD_APP(app_interface, "socket", "Connect to a socket", "Connect to a socket", socket_function, "<ip>[:<port>]", SAF_SUPPORT_NOMEDIA)for (;;) { app_interface = (switch_application_interface_t *)
switch_loadable_module_create_interface(*module_interface, SWITCH_APPLICATION_INTERFACE
); app_interface->interface_name = "socket"; app_interface
->application_function = socket_function; app_interface->
short_desc = "Connect to a socket"; app_interface->long_desc
= "Connect to a socket"; app_interface->syntax = "<ip>[:<port>]"
; app_interface->flags = SAF_SUPPORT_NOMEDIA; break; }
;
1154 SWITCH_ADD_API(api_interface, "event_sink", "event_sink", event_sink_function, "<web data>")for (;;) { api_interface = (switch_api_interface_t *)switch_loadable_module_create_interface
(*module_interface, SWITCH_API_INTERFACE); api_interface->
interface_name = "event_sink"; api_interface->desc = "event_sink"
; api_interface->function = event_sink_function; api_interface
->syntax = "<web data>"; break; }
;
1155
1156 /* indicate that the module should continue to be loaded */
1157 return SWITCH_STATUS_SUCCESS;
1158}
1159
1160static switch_status_t read_packet(listener_t *listener, switch_event_t **event, uint32_t timeout)
1161{
1162 switch_size_t mlen, bytes = 0;
1163 char *mbuf = NULL((void*)0);
1164 char buf[1024] = "";
1165 switch_size_t len;
1166 switch_status_t status = SWITCH_STATUS_SUCCESS;
1167 int count = 0;
1168 uint32_t elapsed = 0;
1169 time_t start = 0;
1170 void *pop;
1171 char *ptr;
1172 uint8_t crcount = 0;
1173 uint32_t max_len = 10485760, block_len = 2048, buf_len = 0;
1174 switch_channel_t *channel = NULL((void*)0);
1175 int clen = 0;
1176
1177 *event = NULL((void*)0);
1178
1179 if (prefs.done) {
1180 switch_goto_status(SWITCH_STATUS_FALSE, end)status = SWITCH_STATUS_FALSE; goto end;
1181 }
1182
1183 switch_zmalloc(mbuf, block_len)(void)((((mbuf = calloc(1, (block_len)))) ? (void) (0) : __assert_fail
("(mbuf = calloc(1, (block_len)))", "mod_event_socket.c", 1183
, __PRETTY_FUNCTION__)),mbuf)
;
1184 switch_assert(mbuf)((mbuf) ? (void) (0) : __assert_fail ("mbuf", "mod_event_socket.c"
, 1184, __PRETTY_FUNCTION__))
;
1185 buf_len = block_len;
1186
1187 start = switch_epoch_time_now(NULL((void*)0));
1188 ptr = mbuf;
1189
1190 if (listener->session) {
1191 channel = switch_core_session_get_channel(listener->session);
1192 }
1193
1194 while (listener->sock && !prefs.done) {
1195 uint8_t do_sleep = 1;
1196 mlen = 1;
1197
1198 if (bytes == buf_len - 1) {
1199 char *tmp;
1200 int pos;
1201
1202 pos = (int)(ptr - mbuf);
1203 buf_len += block_len;
1204 tmp = realloc(mbuf, buf_len);
1205 switch_assert(tmp)((tmp) ? (void) (0) : __assert_fail ("tmp", "mod_event_socket.c"
, 1205, __PRETTY_FUNCTION__))
;
1206 mbuf = tmp;
1207 memset(mbuf + bytes, 0, buf_len - bytes);
1208 ptr = (mbuf + pos);
1209
1210 }
1211
1212 status = switch_socket_recv(listener->sock, ptr, &mlen);
1213
1214 if (prefs.done || (!SWITCH_STATUS_IS_BREAK(status)(status == SWITCH_STATUS_BREAK || status == 730035 || status ==
35 || status == SWITCH_STATUS_INTR)
&& status != SWITCH_STATUS_SUCCESS)) {
1215 switch_goto_status(SWITCH_STATUS_FALSE, end)status = SWITCH_STATUS_FALSE; goto end;
1216 }
1217
1218 if (mlen) {
1219 bytes += mlen;
1220 do_sleep = 0;
1221
1222 if (*mbuf == '\r' || *mbuf == '\n') { /* bah */
1223 ptr = mbuf;
1224 mbuf[0] = '\0';
1225 bytes = 0;
1226 continue;
1227 }
1228
1229 if (*ptr == '\n') {
1230 crcount++;
1231 } else if (*ptr != '\r') {
1232 crcount = 0;
1233 }
1234 ptr++;
1235
1236 if (bytes >= max_len) {
1237 crcount = 2;
1238 }
1239
1240 if (crcount == 2) {
1241 char *next;
1242 char *cur = mbuf;
1243 bytes = 0;
1244 while (cur) {
1245 if ((next = strchr(cur, '\r')(__extension__ (__builtin_constant_p ('\r') && !__builtin_constant_p
(cur) && ('\r') == '\0' ? (char *) __rawmemchr (cur,
'\r') : __builtin_strchr (cur, '\r')))
) || (next = strchr(cur, '\n')(__extension__ (__builtin_constant_p ('\n') && !__builtin_constant_p
(cur) && ('\n') == '\0' ? (char *) __rawmemchr (cur,
'\n') : __builtin_strchr (cur, '\n')))
)) {
1246 while (*next == '\r' || *next == '\n') {
1247 next++;
1248 }
1249 }
1250 count++;
1251 if (count == 1) {
1252 switch_event_create(event, SWITCH_EVENT_CLONE)switch_event_create_subclass_detailed("mod_event_socket.c", (
const char * )(const char *)__func__, 1252, event, SWITCH_EVENT_CLONE
, ((void*)0))
;
1253 switch_event_add_header_string(*event, SWITCH_STACK_BOTTOM, "Command", mbuf);
1254 } else if (cur) {
1255 char *var, *val;
1256 var = cur;
1257 strip_cr(var);
1258 if (!zstr(var)_zstr(var)) {
1259 if ((val = strchr(var, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(var) && (':') == '\0' ? (char *) __rawmemchr (var, ':'
) : __builtin_strchr (var, ':')))
)) {
1260 *val++ = '\0';
1261 while (*val == ' ') {
1262 val++;
1263 }
1264 }
1265 if (var && val) {
1266 switch_event_add_header_string(*event, SWITCH_STACK_BOTTOM, var, val);
1267 if (!strcasecmp(var, "content-length")) {
1268 clen = atoi(val);
1269
1270 if (clen > 0) {
1271 char *body;
1272 char *p;
1273
1274 switch_zmalloc(body, clen + 1)(void)((((body = calloc(1, (clen + 1)))) ? (void) (0) : __assert_fail
("(body = calloc(1, (clen + 1)))", "mod_event_socket.c", 1274
, __PRETTY_FUNCTION__)),body)
;
1275
1276 p = body;
1277 while (clen > 0) {
1278 mlen = clen;
1279
1280 status = switch_socket_recv(listener->sock, p, &mlen);
1281
1282 if (prefs.done || (!SWITCH_STATUS_IS_BREAK(status)(status == SWITCH_STATUS_BREAK || status == 730035 || status ==
35 || status == SWITCH_STATUS_INTR)
&& status != SWITCH_STATUS_SUCCESS)) {
1283 free(body);
1284 switch_goto_status(SWITCH_STATUS_FALSE, end)status = SWITCH_STATUS_FALSE; goto end;
1285 }
1286
1287 /*
1288 if (channel && !switch_channel_ready(channel)) {
1289 status = SWITCH_STATUS_FALSE;
1290 break;
1291 }
1292 */
1293
1294 clen -= (int) mlen;
1295 p += mlen;
1296 }
1297
1298 switch_event_add_body(*event, "%s", body);
1299 free(body);
1300 }
1301 }
1302 }
1303 }
1304 }
1305
1306 cur = next;
1307 }
1308 break;
1309 }
1310 }
1311
1312 if (timeout) {
1313 elapsed = (uint32_t) (switch_epoch_time_now(NULL((void*)0)) - start);
1314 if (elapsed >= timeout) {
1315 switch_clear_flag_locked(listener, LFLAG_RUNNING)switch_mutex_lock(listener->flag_mutex); (listener)->flags
&= ~(LFLAG_RUNNING); switch_mutex_unlock(listener->flag_mutex
);
;
1316 switch_goto_status(SWITCH_STATUS_FALSE, end)status = SWITCH_STATUS_FALSE; goto end;
1317 }
1318 }
1319
1320 if (!*mbuf) {
1321 if (switch_test_flag(listener, LFLAG_LOG)((listener)->flags & LFLAG_LOG)) {
1322 if (switch_queue_trypop(listener->log_queue, &pop) == SWITCH_STATUS_SUCCESS) {
1323 switch_log_node_t *dnode = (switch_log_node_t *) pop;
1324
1325 if (dnode->data) {
1326 switch_snprintf(buf, sizeof(buf),
1327 "Content-Type: log/data\n"
1328 "Content-Length: %" SWITCH_SSIZE_T_FMT"ld" "\n"
1329 "Log-Level: %d\n"
1330 "Text-Channel: %d\n"
1331 "Log-File: %s\n"
1332 "Log-Func: %s\n"
1333 "Log-Line: %d\n"
1334 "User-Data: %s\n"
1335 "\n",
1336 strlen(dnode->data),
1337 dnode->level, dnode->channel, dnode->file, dnode->func, dnode->line, switch_str_nil(dnode->userdata)(dnode->userdata ? dnode->userdata : "")
1338 );
1339 len = strlen(buf);
1340 switch_socket_send(listener->sock, buf, &len);
1341 len = strlen(dnode->data);
1342 switch_socket_send(listener->sock, dnode->data, &len);
1343 }
1344
1345 switch_log_node_free(&dnode);
1346 do_sleep = 0;
1347 }
1348 }
1349
1350
1351 if (listener->session) {
1352 switch_channel_t *chan = switch_core_session_get_channel(listener->session);
1353 if (switch_channel_get_state(chan) < CS_HANGUP && switch_channel_test_flag(chan, CF_DIVERT_EVENTS)) {
1354 switch_event_t *e = NULL((void*)0);
1355 while (switch_core_session_dequeue_event(listener->session, &e, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) {
1356 if (switch_queue_trypush(listener->event_queue, e) != SWITCH_STATUS_SUCCESS) {
1357 switch_core_session_queue_event(listener->session, &e);
1358 break;
1359 }
1360 }
1361 }
1362 }
1363
1364 if (switch_test_flag(listener, LFLAG_EVENTS)((listener)->flags & LFLAG_EVENTS)) {
1365 while (switch_queue_trypop(listener->event_queue, &pop) == SWITCH_STATUS_SUCCESS) {
1366 char hbuf[512];
1367 switch_event_t *pevent = (switch_event_t *) pop;
1368 char *etype;
1369
1370 do_sleep = 0;
1371 if (listener->format == EVENT_FORMAT_PLAIN) {
1372 etype = "plain";
1373 switch_event_serialize(pevent, &listener->ebuf, SWITCH_TRUE);
1374 } else if (listener->format == EVENT_FORMAT_JSON) {
1375 etype = "json";
1376 switch_event_serialize_json(pevent, &listener->ebuf);
1377 } else {
1378 switch_xml_t xml;
1379 etype = "xml";
1380
1381 if ((xml = switch_event_xmlize(pevent, SWITCH_VA_NONE"%s", ""))) {
1382 listener->ebuf = switch_xml_toxml(xml, SWITCH_FALSE);
1383 switch_xml_free(xml);
1384 } else {
1385 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(listener->session)SWITCH_CHANNEL_ID_SESSION, "mod_event_socket.c", (const char *
)__func__, 1385, (const char*)(listener->session)
, SWITCH_LOG_ERROR, "XML ERROR!\n");
1386 goto endloop;
1387 }
1388 }
1389
1390 switch_assert(listener->ebuf)((listener->ebuf) ? (void) (0) : __assert_fail ("listener->ebuf"
, "mod_event_socket.c", 1390, __PRETTY_FUNCTION__))
;
1391
1392 len = strlen(listener->ebuf);
1393
1394 switch_snprintf(hbuf, sizeof(hbuf), "Content-Length: %" SWITCH_SSIZE_T_FMT"ld" "\n" "Content-Type: text/event-%s\n" "\n", len, etype);
1395
1396 len = strlen(hbuf);
1397 switch_socket_send(listener->sock, hbuf, &len);
1398
1399 len = strlen(listener->ebuf);
1400 switch_socket_send(listener->sock, listener->ebuf, &len);
1401
1402 switch_safe_free(listener->ebuf)if (listener->ebuf) {free(listener->ebuf);listener->
ebuf=((void*)0);}
;
1403
1404 endloop:
1405
1406 switch_event_destroy(&pevent);
1407 }
1408 }
1409 }
1410
1411 if (switch_test_flag(listener, LFLAG_HANDLE_DISCO)((listener)->flags & LFLAG_HANDLE_DISCO) &&
1412 listener->linger_timeout != (time_t) -1 && switch_epoch_time_now(NULL((void*)0)) > listener->linger_timeout) {
1413 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(listener->session)SWITCH_CHANNEL_ID_SESSION, "mod_event_socket.c", (const char *
)__func__, 1413, (const char*)(listener->session)
, SWITCH_LOG_DEBUG, "linger timeout, closing socket\n");
1414 status = SWITCH_STATUS_FALSE;
1415 break;
1416 }
1417
1418 if (channel && switch_channel_down(channel)(switch_channel_check_signal(channel, SWITCH_TRUE) || switch_channel_get_state
(channel) >= CS_HANGUP)
&& !switch_test_flag(listener, LFLAG_HANDLE_DISCO)((listener)->flags & LFLAG_HANDLE_DISCO)) {
1419 switch_set_flag_locked(listener, LFLAG_HANDLE_DISCO)((listener->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("listener->flag_mutex != ((void*)0)", "mod_event_socket.c"
, 1419, __PRETTY_FUNCTION__));switch_mutex_lock(listener->
flag_mutex);(listener)->flags |= (LFLAG_HANDLE_DISCO);switch_mutex_unlock
(listener->flag_mutex);
;
1420 if (switch_test_flag(listener, LFLAG_LINGER)((listener)->flags & LFLAG_LINGER)) {
1421 char disco_buf[512] = "";
1422
1423 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(listener->session)SWITCH_CHANNEL_ID_SESSION, "mod_event_socket.c", (const char *
)__func__, 1423, (const char*)(listener->session)
, SWITCH_LOG_DEBUG, "%s Socket Linger %d\n",
1424 switch_channel_get_name(channel), (int)listener->linger_timeout);
1425
1426 switch_snprintf(disco_buf, sizeof(disco_buf), "Content-Type: text/disconnect-notice\n"
1427 "Controlled-Session-UUID: %s\n"
1428 "Content-Disposition: linger\n"
1429 "Channel-Name: %s\n"
1430 "Linger-Time: %d\n"
1431 "Content-Length: 0\n\n",
1432 switch_core_session_get_uuid(listener->session), switch_channel_get_name(channel), (int)listener->linger_timeout);
1433
1434
1435 if (listener->linger_timeout != (time_t) -1) {
1436 listener->linger_timeout += switch_epoch_time_now(NULL((void*)0));
1437 }
1438
1439 len = strlen(disco_buf);
1440 switch_socket_send(listener->sock, disco_buf, &len);
1441 } else {
1442 status = SWITCH_STATUS_FALSE;
1443 break;
1444 }
1445 }
1446
1447 if (do_sleep) {
1448 int fdr = 0;
1449 switch_poll(listener->pollfd, 1, &fdr, 20000);
1450 } else {
1451 switch_os_yield();
1452 }
1453 }
1454
1455 end:
1456
1457 switch_safe_free(mbuf)if (mbuf) {free(mbuf);mbuf=((void*)0);};
1458 return status;
1459
1460}
1461
1462struct api_command_struct {
1463 char *api_cmd;
1464 char *arg;
1465 listener_t *listener;
1466 char uuid_str[SWITCH_UUID_FORMATTED_LENGTH256 + 1];
1467 int bg;
1468 int ack;
1469 int console_execute;
1470 switch_memory_pool_t *pool;
1471};
1472
1473static void *SWITCH_THREAD_FUNC api_exec(switch_thread_t *thread, void *obj)
1474{
1475
1476 struct api_command_struct *acs = (struct api_command_struct *) obj;
1477 switch_stream_handle_t stream = { 0 };
1478 char *reply, *freply = NULL((void*)0);
1479 switch_status_t status;
1480
1481 switch_mutex_lock(globals.listener_mutex);
1482 prefs.threads++;
1483 switch_mutex_unlock(globals.listener_mutex);
1484
1485
1486 if (!acs) {
1487 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_event_socket.c", (const char *)__func__
, 1487, ((void*)0)
, SWITCH_LOG_ERROR, "Internal error.\n");
1488 goto cleanup;
1489 }
1490
1491 if (!acs->listener || !switch_test_flag(acs->listener, LFLAG_RUNNING)((acs->listener)->flags & LFLAG_RUNNING) ||
1492 !acs->listener->rwlock || switch_thread_rwlock_tryrdlock(acs->listener->rwlock) != SWITCH_STATUS_SUCCESS) {
1493 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_event_socket.c", (const char *)__func__
, 1493, ((void*)0)
, SWITCH_LOG_ERROR, "Error! cannot get read lock.\n");
1494 acs->ack = -1;
1495 goto done;
1496 }
1497
1498 acs->ack = 1;
1499
1500 SWITCH_STANDARD_STREAM(stream)memset(&stream, 0, sizeof(stream)); stream.data = malloc(
1024); ((stream.data) ? (void) (0) : __assert_fail ("stream.data"
, "mod_event_socket.c", 1500, __PRETTY_FUNCTION__)); memset(stream
.data, 0, 1024); stream.end = stream.data; stream.data_size =
1024; stream.write_function = switch_console_stream_write; stream
.raw_write_function = switch_console_stream_raw_write; stream
.alloc_len = 1024; stream.alloc_chunk = 1024
;
1501
1502 if (acs->console_execute) {
1503 if ((status = switch_console_execute(acs->api_cmd, 0, &stream)) != SWITCH_STATUS_SUCCESS) {
1504 stream.write_function(&stream, "-ERR %s Command not found!\n", acs->api_cmd);
1505 }
1506 } else {
1507 status = switch_api_execute(acs->api_cmd, acs->arg, NULL((void*)0), &stream);
1508 }
1509
1510 if (status == SWITCH_STATUS_SUCCESS) {
1511 reply = stream.data;
1512 } else {
1513 freply = switch_mprintf("-ERR %s Command not found!\n", acs->api_cmd);
1514 reply = freply;
1515 }
1516
1517 if (!reply) {
1518 reply = "Command returned no output!";
1519 }
1520
1521 if (acs->bg) {
1522 switch_event_t *event;
1523
1524 if (switch_event_create(&event, SWITCH_EVENT_BACKGROUND_JOB)switch_event_create_subclass_detailed("mod_event_socket.c", (
const char * )(const char *)__func__, 1524, &event, SWITCH_EVENT_BACKGROUND_JOB
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1525 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Job-UUID", acs->uuid_str);
1526 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Job-Command", acs->api_cmd);
1527 if (acs->arg) {
1528 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Job-Command-Arg", acs->arg);
1529 }
1530 switch_event_add_body(event, "%s", reply);
1531 switch_event_fire(&event)switch_event_fire_detailed("mod_event_socket.c", (const char *
)(const char *)__func__, 1531, &event, ((void*)0))
;
1532 }
1533 } else {
1534 switch_size_t rlen, blen;
1535 char buf[1024] = "";
1536
1537 if (!(rlen = strlen(reply))) {
1538 reply = "-ERR no reply\n";
1539 rlen = strlen(reply);
1540 }
1541
1542 switch_snprintf(buf, sizeof(buf), "Content-Type: api/response\nContent-Length: %" SWITCH_SSIZE_T_FMT"ld" "\n\n", rlen);
1543 blen = strlen(buf);
1544 switch_socket_send(acs->listener->sock, buf, &blen);
1545 switch_socket_send(acs->listener->sock, reply, &rlen);
1546 }
1547
1548 switch_safe_free(stream.data)if (stream.data) {free(stream.data);stream.data=((void*)0);};
1549 switch_safe_free(freply)if (freply) {free(freply);freply=((void*)0);};
1550
1551 if (acs->listener->rwlock) {
1552 switch_thread_rwlock_unlock(acs->listener->rwlock);
1553 }
1554
1555 done:
1556
1557 if (acs->bg) {
1558 switch_memory_pool_t *pool = acs->pool;
1559 if (acs->ack == -1) {
1560 int sanity = 2000;
1561 while (acs->ack == -1) {
1562 switch_cond_next();
1563 if (--sanity <= 0)
1564 break;
1565 }
1566 }
1567
1568 acs = NULL((void*)0);
1569 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "mod_event_socket.c"
, (const char *)__func__, 1569)
;
1570 pool = NULL((void*)0);
1571
1572 }
1573
1574 cleanup:
1575 switch_mutex_lock(globals.listener_mutex);
1576 prefs.threads--;
1577 switch_mutex_unlock(globals.listener_mutex);
1578
1579 return NULL((void*)0);
1580
1581}
1582
1583static switch_bool_t auth_api_command(listener_t *listener, const char *api_cmd, const char *arg)
1584{
1585 const char *check_cmd = api_cmd;
1586 char *sneaky_commands[] = { "bgapi", "sched_api", "eval", "expand", "xml_wrap", NULL((void*)0) };
1587 int x = 0;
1588 char *dup_arg = NULL((void*)0);
1589 char *next = NULL((void*)0);
1590 switch_bool_t ok = SWITCH_TRUE;
1591
1592 top:
1593
1594 if (!switch_core_hash_find(listener->allowed_api_hash, check_cmd)) {
1595 ok = SWITCH_FALSE;
1596 goto end;
1597 }
1598
1599 while (check_cmd) {
1600 for (x = 0; sneaky_commands[x]; x++) {
1601 if (!strcasecmp(sneaky_commands[x], check_cmd)) {
1602 if (check_cmd == api_cmd) {
1603 if (arg) {
1604 switch_safe_free(dup_arg)if (dup_arg) {free(dup_arg);dup_arg=((void*)0);};
1605 dup_arg = strdup(arg)(__extension__ (__builtin_constant_p (arg) && ((size_t
)(const void *)((arg) + 1) - (size_t)(const void *)(arg) == 1
) ? (((const char *) (arg))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen (arg) + 1; char *
__retval = (char *) malloc (__len); if (__retval != ((void*)0
)) __retval = (char *) memcpy (__retval, arg, __len); __retval
; })) : __strdup (arg)))
;
1606 check_cmd = dup_arg;
1607 if ((next = strchr(check_cmd, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p
(check_cmd) && (' ') == '\0' ? (char *) __rawmemchr (
check_cmd, ' ') : __builtin_strchr (check_cmd, ' ')))
)) {
1608 *next++ = '\0';
1609 }
1610 } else {
1611 break;
1612 }
1613 } else {
1614 if (next) {
1615 check_cmd = next;
1616 } else {
1617 check_cmd = dup_arg;
1618 }
1619
1620 if ((next = strchr(check_cmd, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p
(check_cmd) && (' ') == '\0' ? (char *) __rawmemchr (
check_cmd, ' ') : __builtin_strchr (check_cmd, ' ')))
)) {
1621 *next++ = '\0';
1622 }
1623 }
1624 goto top;
1625 }
1626 }
1627 break;
1628 }
1629
1630 end:
1631
1632 switch_safe_free(dup_arg)if (dup_arg) {free(dup_arg);dup_arg=((void*)0);};
1633 return ok;
1634
1635}
1636
1637static switch_status_t parse_command(listener_t *listener, switch_event_t **event, char *reply, uint32_t reply_len)
1638{
1639 switch_status_t status = SWITCH_STATUS_SUCCESS;
1640 char *cmd = NULL((void*)0);
1641 char unload_cheat[] = "api bgapi unload mod_event_socket";
1642 char reload_cheat[] = "api bgapi reload mod_event_socket";
1643
1644 *reply = '\0';
1645
1646 if (!event || !*event || !(cmd = switch_event_get_header(*event, "command")switch_event_get_header_idx(*event, "command", -1))) {
1647 switch_clear_flag_locked(listener, LFLAG_RUNNING)switch_mutex_lock(listener->flag_mutex); (listener)->flags
&= ~(LFLAG_RUNNING); switch_mutex_unlock(listener->flag_mutex
);
;
1648 switch_snprintf(reply, reply_len, "-ERR command parse error.");
1649 goto done;
1650 }
1651
1652 if (switch_stristr("unload", cmd) && switch_stristr("mod_event_socket", cmd)) {
1653 cmd = unload_cheat;
1654 } else if (switch_stristr("reload", cmd) && switch_stristr("mod_event_socket", cmd)) {
1655 cmd = reload_cheat;
1656 }
1657
1658 if (!strncasecmp(cmd, "exit", 4) || !strncasecmp(cmd, "...", 3)) {
1659 switch_clear_flag_locked(listener, LFLAG_RUNNING)switch_mutex_lock(listener->flag_mutex); (listener)->flags
&= ~(LFLAG_RUNNING); switch_mutex_unlock(listener->flag_mutex
);
;
1660 switch_snprintf(reply, reply_len, "+OK bye");
1661 goto done;
1662 }
1663
1664 if (!switch_test_flag(listener, LFLAG_AUTHED)((listener)->flags & LFLAG_AUTHED)) {
1665 if (!strncasecmp(cmd, "auth ", 5)) {
1666 char *pass;
1667 strip_cr(cmd);
1668
1669 pass = cmd + 5;
1670
1671 if (!strcmp(prefs.password, pass)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(prefs.password) && __builtin_constant_p (pass) &&
(__s1_len = __builtin_strlen (prefs.password), __s2_len = __builtin_strlen
(pass), (!((size_t)(const void *)((prefs.password) + 1) - (size_t
)(const void *)(prefs.password) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)((pass) + 1) - (size_t)(const void *
)(pass) == 1) || __s2_len >= 4)) ? __builtin_strcmp (prefs
.password, pass) : (__builtin_constant_p (prefs.password) &&
((size_t)(const void *)((prefs.password) + 1) - (size_t)(const
void *)(prefs.password) == 1) && (__s1_len = __builtin_strlen
(prefs.password), __s1_len < 4) ? (__builtin_constant_p (
pass) && ((size_t)(const void *)((pass) + 1) - (size_t
)(const void *)(pass) == 1) ? __builtin_strcmp (prefs.password
, pass) : (__extension__ ({ const unsigned char *__s2 = (const
unsigned char *) (const char *) (pass); int __result = (((const
unsigned char *) (const char *) (prefs.password))[0] - __s2[
0]); if (__s1_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) (prefs.password))
[1] - __s2[1]); if (__s1_len > 1 && __result == 0)
{ __result = (((const unsigned char *) (const char *) (prefs
.password))[2] - __s2[2]); if (__s1_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) (prefs
.password))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(pass) && ((size_t)(const void *)((pass) + 1) - (size_t
)(const void *)(pass) == 1) && (__s2_len = __builtin_strlen
(pass), __s2_len < 4) ? (__builtin_constant_p (prefs.password
) && ((size_t)(const void *)((prefs.password) + 1) - (
size_t)(const void *)(prefs.password) == 1) ? __builtin_strcmp
(prefs.password, pass) : (- (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (prefs.password
); int __result = (((const unsigned char *) (const char *) (pass
))[0] - __s2[0]); if (__s2_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) (pass
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (pass
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (pass))
[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (prefs
.password, pass)))); })
) {
1672 switch_set_flag_locked(listener, LFLAG_AUTHED)((listener->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("listener->flag_mutex != ((void*)0)", "mod_event_socket.c"
, 1672, __PRETTY_FUNCTION__));switch_mutex_lock(listener->
flag_mutex);(listener)->flags |= (LFLAG_AUTHED);switch_mutex_unlock
(listener->flag_mutex);
;
1673 switch_snprintf(reply, reply_len, "+OK accepted");
1674 } else {
1675 switch_snprintf(reply, reply_len, "-ERR invalid");
1676 switch_clear_flag_locked(listener, LFLAG_RUNNING)switch_mutex_lock(listener->flag_mutex); (listener)->flags
&= ~(LFLAG_RUNNING); switch_mutex_unlock(listener->flag_mutex
);
;
1677 }
1678
1679 goto done;
1680 }
1681
1682 if (!strncasecmp(cmd, "userauth ", 9)) {
1683 const char *passwd;
1684 const char *allowed_api;
1685 const char *allowed_events;
1686 switch_event_t *params;
1687 char *user = NULL((void*)0), *domain_name = NULL((void*)0), *pass = NULL((void*)0);
1688 switch_xml_t x_domain = NULL((void*)0), x_domain_root, x_user = NULL((void*)0), x_params, x_param, x_group = NULL((void*)0);
1689 int authed = 0;
1690 char *edup = NULL((void*)0);
1691 char event_reply[512] = "Allowed-Events: all\n";
1692 char api_reply[512] = "Allowed-API: all\n";
1693 char log_reply[512] = "";
1694 int allowed_log = 1;
1695 char *tmp;
1696
1697 switch_clear_flag(listener, LFLAG_ALLOW_LOG)(listener)->flags &= ~(LFLAG_ALLOW_LOG);
1698
1699 strip_cr(cmd);
1700
1701 user = cmd + 9;
1702
1703 if (user && (domain_name = strchr(user, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p
(user) && ('@') == '\0' ? (char *) __rawmemchr (user
, '@') : __builtin_strchr (user, '@')))
)) {
1704 *domain_name++ = '\0';
1705 }
1706
1707 if (domain_name && (pass = strchr(domain_name, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(domain_name) && (':') == '\0' ? (char *) __rawmemchr
(domain_name, ':') : __builtin_strchr (domain_name, ':')))
)) {
1708 *pass++ = '\0';
1709 }
1710
1711 if ((tmp = strchr(user, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(user) && (':') == '\0' ? (char *) __rawmemchr (user
, ':') : __builtin_strchr (user, ':')))
)) {
1712 *tmp++ = '\0';
1713 pass = tmp;
1714 }
1715
1716 if (zstr(user)_zstr(user) || zstr(domain_name)_zstr(domain_name)) {
1717 switch_snprintf(reply, reply_len, "-ERR invalid");
1718 switch_clear_flag_locked(listener, LFLAG_RUNNING)switch_mutex_lock(listener->flag_mutex); (listener)->flags
&= ~(LFLAG_RUNNING); switch_mutex_unlock(listener->flag_mutex
);
;
1719 goto done;
1720 }
1721
1722
1723 passwd = NULL((void*)0);
1724 allowed_events = NULL((void*)0);
1725 allowed_api = NULL((void*)0);
1726
1727 params = NULL((void*)0);
1728 x_domain_root = NULL((void*)0);
1729
1730
1731 switch_event_create(&params, SWITCH_EVENT_REQUEST_PARAMS)switch_event_create_subclass_detailed("mod_event_socket.c", (
const char * )(const char *)__func__, 1731, &params, SWITCH_EVENT_REQUEST_PARAMS
, ((void*)0))
;
1732 switch_assert(params)((params) ? (void) (0) : __assert_fail ("params", "mod_event_socket.c"
, 1732, __PRETTY_FUNCTION__))
;
1733 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "action", "event_socket_auth");
1734
1735 if (switch_xml_locate_user("id", user, domain_name, NULL((void*)0), &x_domain_root, &x_domain, &x_user, &x_group, params) == SWITCH_STATUS_SUCCESS) {
1736 switch_xml_t list[3];
1737 int x = 0;
1738
1739 list[0] = x_domain;
1740 list[1] = x_group;
1741 list[2] = x_user;
1742
1743 for (x = 0; x < 3; x++) {
1744 if ((x_params = switch_xml_child(list[x], "params"))) {
1745 for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) {
1746 const char *var = switch_xml_attr_soft(x_param, "name");
1747 const char *val = switch_xml_attr_soft(x_param, "value");
1748
1749 if (!strcasecmp(var, "esl-password")) {
1750 passwd = val;
1751 } else if (!strcasecmp(var, "esl-allowed-log")) {
1752 allowed_log = switch_true(val);
1753 } else if (!strcasecmp(var, "esl-allowed-events")) {
1754 allowed_events = val;
1755 } else if (!strcasecmp(var, "esl-allowed-api")) {
1756 allowed_api = val;
1757 }
1758 }
1759 }
1760 }
1761 } else {
1762 authed = 0;
1763 goto bot;
1764 }
1765
1766 if (!zstr(passwd)_zstr(passwd) && !zstr(pass)_zstr(pass) && !strcmp(passwd, pass)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(passwd) && __builtin_constant_p (pass) && (
__s1_len = __builtin_strlen (passwd), __s2_len = __builtin_strlen
(pass), (!((size_t)(const void *)((passwd) + 1) - (size_t)(const
void *)(passwd) == 1) || __s1_len >= 4) && (!((size_t
)(const void *)((pass) + 1) - (size_t)(const void *)(pass) ==
1) || __s2_len >= 4)) ? __builtin_strcmp (passwd, pass) :
(__builtin_constant_p (passwd) && ((size_t)(const void
*)((passwd) + 1) - (size_t)(const void *)(passwd) == 1) &&
(__s1_len = __builtin_strlen (passwd), __s1_len < 4) ? (__builtin_constant_p
(pass) && ((size_t)(const void *)((pass) + 1) - (size_t
)(const void *)(pass) == 1) ? __builtin_strcmp (passwd, pass)
: (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (pass); int __result = (((const unsigned
char *) (const char *) (passwd))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (passwd))[1] - __s2[1]); if (__s1_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (passwd))[2] - __s2[2]); if (__s1_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) (passwd))[3] - __s2[3]); } } __result
; }))) : (__builtin_constant_p (pass) && ((size_t)(const
void *)((pass) + 1) - (size_t)(const void *)(pass) == 1) &&
(__s2_len = __builtin_strlen (pass), __s2_len < 4) ? (__builtin_constant_p
(passwd) && ((size_t)(const void *)((passwd) + 1) - (
size_t)(const void *)(passwd) == 1) ? __builtin_strcmp (passwd
, pass) : (- (__extension__ ({ const unsigned char *__s2 = (const
unsigned char *) (const char *) (passwd); int __result = (((
const unsigned char *) (const char *) (pass))[0] - __s2[0]); if
(__s2_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) (pass))[1] - __s2[1]); if (__s2_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (pass))[2] - __s2[2]); if (__s2_len >
2 && __result == 0) __result = (((const unsigned char
*) (const char *) (pass))[3] - __s2[3]); } } __result; }))))
: __builtin_strcmp (passwd, pass)))); })
) {
1767 authed = 1;
1768
1769 if (allowed_events) {
1770 char delim = ',';
1771 char *cur, *next;
1772 int count = 0, custom = 0, key_count = 0;
1773
1774 switch_set_flag(listener, LFLAG_AUTH_EVENTS)(listener)->flags |= (LFLAG_AUTH_EVENTS);
1775
1776 switch_snprintf(event_reply, sizeof(event_reply), "Allowed-Events: %s\n", allowed_events);
1777
1778 switch_core_hash_init(&listener->allowed_event_hash)switch_core_hash_init_case(&listener->allowed_event_hash
, SWITCH_TRUE)
;
1779
1780 edup = strdup(allowed_events)(__extension__ (__builtin_constant_p (allowed_events) &&
((size_t)(const void *)((allowed_events) + 1) - (size_t)(const
void *)(allowed_events) == 1) ? (((const char *) (allowed_events
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen (allowed_events) + 1; char *__retval =
(char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, allowed_events, __len); __retval
; })) : __strdup (allowed_events)))
;
1781 cur = edup;
Value stored to 'cur' is never read
1782
1783 if (strchr(edup, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p
(edup) && (' ') == '\0' ? (char *) __rawmemchr (edup
, ' ') : __builtin_strchr (edup, ' ')))
) {
1784 delim = ' ';
1785 }
1786
1787 for (cur = edup; cur; count++) {
1788 switch_event_types_t type;
1789
1790 if ((next = strchr(cur, delim)(__extension__ (__builtin_constant_p (delim) && !__builtin_constant_p
(cur) && (delim) == '\0' ? (char *) __rawmemchr (cur
, delim) : __builtin_strchr (cur, delim)))
)) {
1791 *next++ = '\0';
1792 }
1793
1794 if (custom) {
1795 switch_core_hash_insert(listener->allowed_event_hash, cur, MARKER)switch_core_hash_insert_destructor(listener->allowed_event_hash
, cur, MARKER, ((void*)0))
;
1796 } else if (switch_name_event(cur, &type) == SWITCH_STATUS_SUCCESS) {
1797 key_count++;
1798 if (type == SWITCH_EVENT_ALL) {
1799 uint32_t x = 0;
1800 switch_set_flag(listener, LFLAG_ALL_EVENTS_AUTHED)(listener)->flags |= (LFLAG_ALL_EVENTS_AUTHED);
1801 for (x = 0; x < SWITCH_EVENT_ALL; x++) {
1802 listener->allowed_event_list[x] = 1;
1803 }
1804 }
1805 if (type <= SWITCH_EVENT_ALL) {
1806 listener->allowed_event_list[type] = 1;
1807 }
1808
1809 if (type == SWITCH_EVENT_CUSTOM) {
1810 custom++;
1811 }
1812 }
1813
1814 cur = next;
1815 }
1816
1817 switch_safe_free(edup)if (edup) {free(edup);edup=((void*)0);};
1818 }
1819
1820 switch_snprintf(log_reply, sizeof(log_reply), "Allowed-LOG: %s\n", allowed_log ? "true" : "false");
1821
1822 if (allowed_log) {
1823 switch_set_flag(listener, LFLAG_ALLOW_LOG)(listener)->flags |= (LFLAG_ALLOW_LOG);
1824 }
1825
1826 if (allowed_api) {
1827 char delim = ',';
1828 char *cur, *next;
1829 int count = 0;
1830
1831 switch_snprintf(api_reply, sizeof(api_reply), "Allowed-API: %s\n", allowed_api);
1832
1833 switch_core_hash_init(&listener->allowed_api_hash)switch_core_hash_init_case(&listener->allowed_api_hash
, SWITCH_TRUE)
;
1834
1835 edup = strdup(allowed_api)(__extension__ (__builtin_constant_p (allowed_api) &&
((size_t)(const void *)((allowed_api) + 1) - (size_t)(const void
*)(allowed_api) == 1) ? (((const char *) (allowed_api))[0] ==
'\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen (allowed_api) + 1; char *__retval = (char *) malloc
(__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, allowed_api, __len); __retval; })) : __strdup (allowed_api
)))
;
1836 cur = edup;
1837
1838 if (strchr(edup, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p
(edup) && (' ') == '\0' ? (char *) __rawmemchr (edup
, ' ') : __builtin_strchr (edup, ' ')))
) {
1839 delim = ' ';
1840 }
1841
1842 for (cur = edup; cur; count++) {
1843 if ((next = strchr(cur, delim)(__extension__ (__builtin_constant_p (delim) && !__builtin_constant_p
(cur) && (delim) == '\0' ? (char *) __rawmemchr (cur
, delim) : __builtin_strchr (cur, delim)))
)) {
1844 *next++ = '\0';
1845 }
1846
1847 switch_core_hash_insert(listener->allowed_api_hash, cur, MARKER)switch_core_hash_insert_destructor(listener->allowed_api_hash
, cur, MARKER, ((void*)0))
;
1848
1849 cur = next;
1850 }
1851
1852 switch_safe_free(edup)if (edup) {free(edup);edup=((void*)0);};
1853 }
1854
1855 }
1856
1857
1858 bot:
1859
1860 if (params) {
1861 switch_event_destroy(&params);
1862 }
1863
1864 if (authed) {
1865 switch_set_flag_locked(listener, LFLAG_AUTHED)((listener->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("listener->flag_mutex != ((void*)0)", "mod_event_socket.c"
, 1865, __PRETTY_FUNCTION__));switch_mutex_lock(listener->
flag_mutex);(listener)->flags |= (LFLAG_AUTHED);switch_mutex_unlock
(listener->flag_mutex);
;
1866 switch_snprintf(reply, reply_len, "~Reply-Text: +OK accepted\n%s%s%s\n", event_reply, api_reply, log_reply);
1867 } else {
1868 switch_snprintf(reply, reply_len, "-ERR invalid");
1869 switch_clear_flag_locked(listener, LFLAG_RUNNING)switch_mutex_lock(listener->flag_mutex); (listener)->flags
&= ~(LFLAG_RUNNING); switch_mutex_unlock(listener->flag_mutex
);
;
1870 }
1871
1872 if (x_domain_root) {
1873 switch_xml_free(x_domain_root);
1874 }
1875
1876 }
1877
1878 goto done;
1879 }
1880
1881 if (!strncasecmp(cmd, "filter ", 7)) {
1882 char *header_name = cmd + 7;
1883 char *header_val = NULL((void*)0);
1884
1885 strip_cr(header_name);
1886
1887 while (header_name && *header_name && *header_name == ' ')
1888 header_name++;
1889
1890 if ((header_val = strchr(header_name, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p
(header_name) && (' ') == '\0' ? (char *) __rawmemchr
(header_name, ' ') : __builtin_strchr (header_name, ' ')))
)) {
1891 *header_val++ = '\0';
1892 }
1893
1894 switch_mutex_lock(listener->filter_mutex);
1895 if (!listener->filters) {
1896 switch_event_create_plain(&listener->filters, SWITCH_EVENT_CLONE);
1897 switch_clear_flag(listener->filters, EF_UNIQ_HEADERS)(listener->filters)->flags &= ~(EF_UNIQ_HEADERS);
1898 }
1899
1900 if (!strcasecmp(header_name, "delete") && header_val) {
1901 header_name = header_val;
1902 if ((header_val = strchr(header_name, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p
(header_name) && (' ') == '\0' ? (char *) __rawmemchr
(header_name, ' ') : __builtin_strchr (header_name, ' ')))
)) {
1903 *header_val++ = '\0';
1904 }
1905 if (!strcasecmp(header_name, "all")) {
1906 switch_event_destroy(&listener->filters);
1907 switch_event_create_plain(&listener->filters, SWITCH_EVENT_CLONE);
1908 } else {
1909 switch_event_del_header_val(listener->filters, header_name, header_val);
1910 }
1911 switch_snprintf(reply, reply_len, "+OK filter deleted. [%s][%s]", header_name, switch_str_nil(header_val)(header_val ? header_val : ""));
1912 } else if (header_val) {
1913 if (!strcasecmp(header_name, "add")) {
1914 header_name = header_val;
1915 if ((header_val = strchr(header_name, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p
(header_name) && (' ') == '\0' ? (char *) __rawmemchr
(header_name, ' ') : __builtin_strchr (header_name, ' ')))
)) {
1916 *header_val++ = '\0';
1917 }
1918 }
1919 switch_event_add_header_string(listener->filters, SWITCH_STACK_BOTTOM, header_name, header_val);
1920 switch_snprintf(reply, reply_len, "+OK filter added. [%s]=[%s]", header_name, header_val);
1921 } else {
1922 switch_snprintf(reply, reply_len, "-ERR invalid syntax");
1923 }
1924 switch_mutex_unlock(listener->filter_mutex);
1925
1926 goto done;
1927 }
1928
1929 if (listener->session && !strncasecmp(cmd, "resume", 6)) {
1930 switch_set_flag_locked(listener, LFLAG_RESUME)((listener->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("listener->flag_mutex != ((void*)0)", "mod_event_socket.c"
, 1930, __PRETTY_FUNCTION__));switch_mutex_lock(listener->
flag_mutex);(listener)->flags |= (LFLAG_RESUME);switch_mutex_unlock
(listener->flag_mutex);
;
1931 switch_channel_set_variable(switch_core_session_get_channel(listener->session), "socket_resume", "true")switch_channel_set_variable_var_check(switch_core_session_get_channel
(listener->session), "socket_resume", "true", SWITCH_TRUE)
;
1932 switch_snprintf(reply, reply_len, "+OK");
1933 goto done;
1934 }
1935
1936 if (listener->session || !strncasecmp(cmd, "myevents ", 9)) {
1937 switch_channel_t *channel = NULL((void*)0);
1938
1939 if (listener->session) {
1940 channel = switch_core_session_get_channel(listener->session);
1941 }
1942
1943 if (!strncasecmp(cmd, "connect", 7)) {
1944 switch_event_t *call_event;
1945 char *event_str;
1946 switch_size_t len;
1947
1948 switch_set_flag_locked(listener, LFLAG_CONNECTED)((listener->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("listener->flag_mutex != ((void*)0)", "mod_event_socket.c"
, 1948, __PRETTY_FUNCTION__));switch_mutex_lock(listener->
flag_mutex);(listener)->flags |= (LFLAG_CONNECTED);switch_mutex_unlock
(listener->flag_mutex);
;
1949 switch_event_create(&call_event, SWITCH_EVENT_CHANNEL_DATA)switch_event_create_subclass_detailed("mod_event_socket.c", (
const char * )(const char *)__func__, 1949, &call_event, SWITCH_EVENT_CHANNEL_DATA
, ((void*)0))
;
1950
1951 if (channel) {
1952 switch_caller_profile_event_set_data(switch_channel_get_caller_profile(channel), "Channel", call_event);
1953 switch_channel_event_set_data(channel, call_event);
1954 }
1955 switch_event_add_header_string(call_event, SWITCH_STACK_BOTTOM, "Content-Type", "command/reply");
1956 switch_event_add_header_string(call_event, SWITCH_STACK_BOTTOM, "Reply-Text", "+OK\n");
1957 switch_event_add_header_string(call_event, SWITCH_STACK_BOTTOM, "Socket-Mode", switch_test_flag(listener, LFLAG_ASYNC)((listener)->flags & LFLAG_ASYNC) ? "async" : "static");
1958 switch_event_add_header_string(call_event, SWITCH_STACK_BOTTOM, "Control", switch_test_flag(listener, LFLAG_FULL)((listener)->flags & LFLAG_FULL) ? "full" : "single-channel");
1959
1960 switch_event_serialize(call_event, &event_str, SWITCH_TRUE);
1961 switch_assert(event_str)((event_str) ? (void) (0) : __assert_fail ("event_str", "mod_event_socket.c"
, 1961, __PRETTY_FUNCTION__))
;
1962 len = strlen(event_str);
1963 switch_socket_send(listener->sock, event_str, &len);
1964 switch_safe_free(event_str)if (event_str) {free(event_str);event_str=((void*)0);};
1965 switch_event_destroy(&call_event);
1966 //switch_snprintf(reply, reply_len, "+OK");
1967 goto done_noreply;
1968 } else if (!strncasecmp(cmd, "getvar", 6)) {
1969 char *arg;
1970 const char *val = "";
1971
1972 strip_cr(cmd);
1973
1974 if ((arg = strchr(cmd, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p
(cmd) && (' ') == '\0' ? (char *) __rawmemchr (cmd, ' '
) : __builtin_strchr (cmd, ' ')))
)) {
1975 *arg++ = '\0';
1976 if (!(val = switch_channel_get_variable(channel, arg)switch_channel_get_variable_dup(channel, arg, SWITCH_TRUE, -1
)
)) {
1977 val = "";
1978 }
1979
1980 }
1981 switch_snprintf(reply, reply_len, "%s", val);
1982 goto done;
1983 } else if (!strncasecmp(cmd, "myevents", 8)) {
1984 if (switch_test_flag(listener, LFLAG_MYEVENTS)((listener)->flags & LFLAG_MYEVENTS)) {
1985 switch_snprintf(reply, reply_len, "-ERR aready enabled.");
1986 goto done;
1987 }
1988
1989 if (!listener->session) {
1990 char *uuid;
1991
1992 if ((uuid = cmd + 9)) {
1993 char *fmt;
1994 strip_cr(uuid);
1995
1996 if ((fmt = strchr(uuid, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p
(uuid) && (' ') == '\0' ? (char *) __rawmemchr (uuid
, ' ') : __builtin_strchr (uuid, ' ')))
)) {
1997 *fmt++ = '\0';
1998 }
1999
2000 if (!(listener->session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "mod_event_socket.c"
, (const char *)__func__, 2000)
)) {
2001 if (fmt) {
2002 switch_snprintf(reply, reply_len, "-ERR invalid uuid");
2003 goto done;
2004 } else {
2005 fmt = uuid;
2006 }
2007 }
2008
2009 if ((fmt = strchr(uuid, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p
(uuid) && (' ') == '\0' ? (char *) __rawmemchr (uuid
, ' ') : __builtin_strchr (uuid, ' ')))
)) {
2010 if (!strcasecmp(fmt, "xml")) {
2011 listener->format = EVENT_FORMAT_XML;
2012 } else if (!strcasecmp(fmt, "plain")) {
2013 listener->format = EVENT_FORMAT_PLAIN;
2014 } else if (!strcasecmp(fmt, "json")) {
2015 listener->format = EVENT_FORMAT_JSON;
2016 }
2017 }
2018
2019 switch_set_flag_locked(listener, LFLAG_SESSION)((listener->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("listener->flag_mutex != ((void*)0)", "mod_event_socket.c"
, 2019, __PRETTY_FUNCTION__));switch_mutex_lock(listener->
flag_mutex);(listener)->flags |= (LFLAG_SESSION);switch_mutex_unlock
(listener->flag_mutex);
;
2020 switch_set_flag_locked(listener, LFLAG_ASYNC)((listener->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("listener->flag_mutex != ((void*)0)", "mod_event_socket.c"
, 2020, __PRETTY_FUNCTION__));switch_mutex_lock(listener->
flag_mutex);(listener)->flags |= (LFLAG_ASYNC);switch_mutex_unlock
(listener->flag_mutex);
;
2021 }
2022
2023
2024 }
2025
2026 listener->event_list[SWITCH_EVENT_CHANNEL_ANSWER] = 1;
2027 listener->event_list[SWITCH_EVENT_CHANNEL_APPLICATION] = 1;
2028 listener->event_list[SWITCH_EVENT_CHANNEL_BRIDGE] = 1;
2029 listener->event_list[SWITCH_EVENT_CHANNEL_CREATE] = 1;
2030 listener->event_list[SWITCH_EVENT_CHANNEL_DATA] = 1;
2031 listener->event_list[SWITCH_EVENT_CHANNEL_DESTROY] = 1;
2032 listener->event_list[SWITCH_EVENT_CHANNEL_EXECUTE] = 1;
2033 listener->event_list[SWITCH_EVENT_CHANNEL_EXECUTE_COMPLETE] = 1;
2034 listener->event_list[SWITCH_EVENT_CHANNEL_HANGUP] = 1;
2035 listener->event_list[SWITCH_EVENT_CHANNEL_HANGUP_COMPLETE] = 1;
2036 listener->event_list[SWITCH_EVENT_CHANNEL_ORIGINATE] = 1;
2037 listener->event_list[SWITCH_EVENT_CHANNEL_UUID] = 1;
2038 listener->event_list[SWITCH_EVENT_CHANNEL_OUTGOING] = 1;
2039 listener->event_list[SWITCH_EVENT_CHANNEL_PARK] = 1;
2040 listener->event_list[SWITCH_EVENT_CHANNEL_PROGRESS] = 1;
2041 listener->event_list[SWITCH_EVENT_CHANNEL_PROGRESS_MEDIA] = 1;
2042 listener->event_list[SWITCH_EVENT_CHANNEL_STATE] = 1;
2043 listener->event_list[SWITCH_EVENT_CHANNEL_UNBRIDGE] = 1;
2044 listener->event_list[SWITCH_EVENT_CHANNEL_UNPARK] = 1;
2045 listener->event_list[SWITCH_EVENT_DETECTED_SPEECH] = 1;
2046 listener->event_list[SWITCH_EVENT_DTMF] = 1;
2047 listener->event_list[SWITCH_EVENT_NOTALK] = 1;
2048 listener->event_list[SWITCH_EVENT_TALK] = 1;
2049 switch_set_flag_locked(listener, LFLAG_MYEVENTS)((listener->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("listener->flag_mutex != ((void*)0)", "mod_event_socket.c"
, 2049, __PRETTY_FUNCTION__));switch_mutex_lock(listener->
flag_mutex);(listener)->flags |= (LFLAG_MYEVENTS);switch_mutex_unlock
(listener->flag_mutex);
;
2050 switch_set_flag_locked(listener, LFLAG_EVENTS)((listener->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("listener->flag_mutex != ((void*)0)", "mod_event_socket.c"
, 2050, __PRETTY_FUNCTION__));switch_mutex_lock(listener->
flag_mutex);(listener)->flags |= (LFLAG_EVENTS);switch_mutex_unlock
(listener->flag_mutex);
;
2051 if (strstr(cmd, "xml") || strstr(cmd, "XML")) {
2052 listener->format = EVENT_FORMAT_XML;
2053 }
2054 if (strstr(cmd, "json") || strstr(cmd, "JSON")) {
2055 listener->format = EVENT_FORMAT_JSON;
2056 }
2057 switch_snprintf(reply, reply_len, "+OK Events Enabled");
2058 goto done;
2059 }
2060 }
2061
2062
2063 if (!strncasecmp(cmd, "divert_events", 13)) {
2064 char *onoff = cmd + 13;
2065 switch_channel_t *channel;
2066
2067 if (!listener->session) {
2068 switch_snprintf(reply, reply_len, "-ERR not controlling a session.");
2069 goto done;
2070 }
2071
2072 channel = switch_core_session_get_channel(listener->session);
2073
2074 if (onoff) {
2075 while (*onoff == ' ') {
2076 onoff++;
2077 }
2078
2079 if (*onoff == '\r' || *onoff == '\n') {
2080 onoff = NULL((void*)0);
2081 } else {
2082 strip_cr(onoff);
2083 }
2084 }
2085
2086 if (zstr(onoff)_zstr(onoff)) {
2087 switch_snprintf(reply, reply_len, "-ERR missing value.");
2088 goto done;
2089 }
2090
2091
2092 if (!strcasecmp(onoff, "on")) {
2093 switch_snprintf(reply, reply_len, "+OK events diverted");
2094 switch_channel_set_flag(channel, CF_DIVERT_EVENTS)switch_channel_set_flag_value(channel, CF_DIVERT_EVENTS, 1);
2095 } else {
2096 switch_snprintf(reply, reply_len, "+OK events not diverted");
2097 switch_channel_clear_flag(channel, CF_DIVERT_EVENTS);
2098 }
2099
2100 goto done;
2101
2102 }
2103
2104 if (!strncasecmp(cmd, "sendmsg", 7)) {
2105 switch_core_session_t *session;
2106 char *uuid = cmd + 7;
2107 const char *async_var = switch_event_get_header(*event, "async")switch_event_get_header_idx(*event, "async", -1);
2108 int async = switch_test_flag(listener, LFLAG_ASYNC)((listener)->flags & LFLAG_ASYNC);
2109
2110 if (switch_true(async_var)) {
2111 async = 1;
2112 }
2113
2114 if (uuid) {
2115 while (*uuid == ' ') {
2116 uuid++;
2117 }
2118
2119 if (*uuid == '\r' || *uuid == '\n') {
2120 uuid = NULL((void*)0);
2121 } else {
2122 strip_cr(uuid);
2123 }
2124 }
2125
2126 if (zstr(uuid)_zstr(uuid)) {
2127 uuid = switch_event_get_header(*event, "session-id")switch_event_get_header_idx(*event, "session-id", -1);
2128 }
2129
2130 if (uuid && listener->session && !strcmp(uuid, switch_core_session_get_uuid(listener->session))__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(uuid) && __builtin_constant_p (switch_core_session_get_uuid
(listener->session)) && (__s1_len = __builtin_strlen
(uuid), __s2_len = __builtin_strlen (switch_core_session_get_uuid
(listener->session)), (!((size_t)(const void *)((uuid) + 1
) - (size_t)(const void *)(uuid) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)((switch_core_session_get_uuid(listener
->session)) + 1) - (size_t)(const void *)(switch_core_session_get_uuid
(listener->session)) == 1) || __s2_len >= 4)) ? __builtin_strcmp
(uuid, switch_core_session_get_uuid(listener->session)) :
(__builtin_constant_p (uuid) && ((size_t)(const void
*)((uuid) + 1) - (size_t)(const void *)(uuid) == 1) &&
(__s1_len = __builtin_strlen (uuid), __s1_len < 4) ? (__builtin_constant_p
(switch_core_session_get_uuid(listener->session)) &&
((size_t)(const void *)((switch_core_session_get_uuid(listener
->session)) + 1) - (size_t)(const void *)(switch_core_session_get_uuid
(listener->session)) == 1) ? __builtin_strcmp (uuid, switch_core_session_get_uuid
(listener->session)) : (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (switch_core_session_get_uuid
(listener->session)); int __result = (((const unsigned char
*) (const char *) (uuid))[0] - __s2[0]); if (__s1_len > 0
&& __result == 0) { __result = (((const unsigned char
*) (const char *) (uuid))[1] - __s2[1]); if (__s1_len > 1
&& __result == 0) { __result = (((const unsigned char
*) (const char *) (uuid))[2] - __s2[2]); if (__s1_len > 2
&& __result == 0) __result = (((const unsigned char *
) (const char *) (uuid))[3] - __s2[3]); } } __result; }))) : (
__builtin_constant_p (switch_core_session_get_uuid(listener->
session)) && ((size_t)(const void *)((switch_core_session_get_uuid
(listener->session)) + 1) - (size_t)(const void *)(switch_core_session_get_uuid
(listener->session)) == 1) && (__s2_len = __builtin_strlen
(switch_core_session_get_uuid(listener->session)), __s2_len
< 4) ? (__builtin_constant_p (uuid) && ((size_t)(
const void *)((uuid) + 1) - (size_t)(const void *)(uuid) == 1
) ? __builtin_strcmp (uuid, switch_core_session_get_uuid(listener
->session)) : (- (__extension__ ({ const unsigned char *__s2
= (const unsigned char *) (const char *) (uuid); int __result
= (((const unsigned char *) (const char *) (switch_core_session_get_uuid
(listener->session)))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (switch_core_session_get_uuid(listener->session))
)[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (switch_core_session_get_uuid
(listener->session)))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (switch_core_session_get_uuid(listener->session)))[3] -
__s2[3]); } } __result; })))) : __builtin_strcmp (uuid, switch_core_session_get_uuid
(listener->session))))); })
) {
2131 uuid = NULL((void*)0);
2132 }
2133
2134 if (zstr(uuid)_zstr(uuid) && listener->session) {
2135 if (async) {
2136 if ((status = switch_core_session_queue_private_event(listener->session, event, SWITCH_FALSE)) == SWITCH_STATUS_SUCCESS) {
2137 switch_snprintf(reply, reply_len, "+OK");
2138 } else {
2139 switch_snprintf(reply, reply_len, "-ERR memory error");
2140 }
2141 } else {
2142 switch_ivr_parse_event(listener->session, *event);
2143 switch_snprintf(reply, reply_len, "+OK");
2144 }
2145 } else {
2146 if (!zstr(uuid)_zstr(uuid) && (session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "mod_event_socket.c"
, (const char *)__func__, 2146)
)) {
2147 if ((status = switch_core_session_queue_private_event(session, event, SWITCH_FALSE)) == SWITCH_STATUS_SUCCESS) {
2148 switch_snprintf(reply, reply_len, "+OK");
2149 } else {
2150 switch_snprintf(reply, reply_len, "-ERR memory error");
2151 }
2152 switch_core_session_rwunlock(session);
2153 } else {
2154 switch_snprintf(reply, reply_len, "-ERR invalid session id [%s]", switch_str_nil(uuid)(uuid ? uuid : ""));
2155 }
2156 }
2157
2158 goto done;
2159
2160 }
2161
2162 if (switch_test_flag(listener, LFLAG_OUTBOUND)((listener)->flags & LFLAG_OUTBOUND) && !switch_test_flag(listener, LFLAG_FULL)((listener)->flags & LFLAG_FULL)) {
2163 goto done;
2164 }
2165
2166
2167 if (!strncasecmp(cmd, "sendevent", 9)) {
2168 char *ename;
2169 const char *uuid = NULL((void*)0);
2170 char uuid_str[SWITCH_UUID_FORMATTED_LENGTH256 + 1];
2171 switch_uuid_str(uuid_str, sizeof(uuid_str));
2172
2173 switch_event_add_header_string(*event, SWITCH_STACK_BOTTOM, "Event-UUID", uuid_str);
2174
2175 strip_cr(cmd);
2176
2177 ename = cmd + 9;
2178
2179 while (ename && (*ename == '\t' || *ename == ' ')) {
2180 ++ename;
2181 }
2182
2183 if (ename && (*ename == '\r' || *ename == '\n')) {
2184 ename = NULL((void*)0);
2185 }
2186
2187 if (ename) {
2188 switch_event_types_t etype;
2189 if (switch_name_event(ename, &etype) == SWITCH_STATUS_SUCCESS) {
2190 const char *subclass_name = switch_event_get_header(*event, "Event-Subclass")switch_event_get_header_idx(*event, "Event-Subclass", -1);
2191 (*event)->event_id = etype;
2192
2193 if (etype == SWITCH_EVENT_CUSTOM && subclass_name) {
2194 switch_event_set_subclass_name(*event, subclass_name);
2195 }
2196 }
2197 }
2198
2199 if ((uuid = switch_event_get_header(*event, "unique-id")switch_event_get_header_idx(*event, "unique-id", -1))) {
2200 switch_core_session_t *dsession;
2201
2202 if ((dsession = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "mod_event_socket.c"
, (const char *)__func__, 2202)
)) {
2203 switch_core_session_queue_event(dsession, event);
2204 switch_core_session_rwunlock(dsession);
2205 }
2206 }
2207
2208 if (*event) {
2209 switch_event_prep_for_delivery(*event)switch_event_prep_for_delivery_detailed("mod_event_socket.c",
(const char * )(const char *)__func__, 2209, *event)
;
2210 switch_event_fire(event)switch_event_fire_detailed("mod_event_socket.c", (const char *
)(const char *)__func__, 2210, event, ((void*)0))
;
2211 }
2212 switch_snprintf(reply, reply_len, "+OK %s", uuid_str);
2213 goto done;
2214 } else if (!strncasecmp(cmd, "api ", 4)) {
2215 struct api_command_struct acs = { 0 };
2216 char *console_execute = switch_event_get_header(*event, "console_execute")switch_event_get_header_idx(*event, "console_execute", -1);
2217
2218 char *api_cmd = cmd + 4;
2219 char *arg = NULL((void*)0);
2220 strip_cr(api_cmd);
2221
2222 if (listener->allowed_api_hash) {
2223 char *api_copy = strdup(api_cmd)(__extension__ (__builtin_constant_p (api_cmd) && ((size_t
)(const void *)((api_cmd) + 1) - (size_t)(const void *)(api_cmd
) == 1) ? (((const char *) (api_cmd))[0] == '\0' ? (char *) calloc
((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (api_cmd
) + 1; char *__retval = (char *) malloc (__len); if (__retval
!= ((void*)0)) __retval = (char *) memcpy (__retval, api_cmd
, __len); __retval; })) : __strdup (api_cmd)))
;
2224 char *arg_copy = NULL((void*)0);
2225 int ok = 0;
2226
2227 if ((arg_copy = strchr(api_copy, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p
(api_copy) && (' ') == '\0' ? (char *) __rawmemchr (
api_copy, ' ') : __builtin_strchr (api_copy, ' ')))
)) {
2228 *arg_copy++ = '\0';
2229 }
2230
2231 ok = auth_api_command(listener, api_copy, arg_copy);
2232 free(api_copy);
2233
2234 if (!ok) {
2235 switch_snprintf(reply, reply_len, "-ERR permission denied");
2236 status = SWITCH_STATUS_SUCCESS;
2237 goto done;
2238 }
2239 }
2240
2241 if (!(acs.console_execute = switch_true(console_execute))) {
2242 if ((arg = strchr(api_cmd, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p
(api_cmd) && (' ') == '\0' ? (char *) __rawmemchr (api_cmd
, ' ') : __builtin_strchr (api_cmd, ' ')))
)) {
2243 *arg++ = '\0';
2244 }
2245 }
2246
2247 acs.listener = listener;
2248 acs.api_cmd = api_cmd;
2249 acs.arg = arg;
2250 acs.bg = 0;
2251
2252
2253 api_exec(NULL((void*)0), (void *) &acs);
2254
2255 status = SWITCH_STATUS_SUCCESS;
2256 goto done_noreply;
2257 } else if (!strncasecmp(cmd, "bgapi ", 6)) {
2258 struct api_command_struct *acs = NULL((void*)0);
2259 char *api_cmd = cmd + 6;
2260 char *arg = NULL((void*)0);
2261 char *uuid_str = NULL((void*)0);
2262 switch_memory_pool_t *pool;
2263 switch_thread_t *thread;
2264 switch_threadattr_t *thd_attr = NULL((void*)0);
2265 switch_uuid_t uuid;
2266 int sanity;
2267
2268 strip_cr(api_cmd);
2269
2270 if ((arg = strchr(api_cmd, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p
(api_cmd) && (' ') == '\0' ? (char *) __rawmemchr (api_cmd
, ' ') : __builtin_strchr (api_cmd, ' ')))
)) {
2271 *arg++ = '\0';
2272 }
2273
2274 if (listener->allowed_api_hash) {
2275 if (!auth_api_command(listener, api_cmd, arg)) {
2276 switch_snprintf(reply, reply_len, "-ERR permission denied");
2277 status = SWITCH_STATUS_SUCCESS;
2278 goto done;
2279 }
2280 }
2281
2282 switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "mod_event_socket.c"
, (const char *)__func__, 2282)
;
2283 acs = switch_core_alloc(pool, sizeof(*acs))switch_core_perform_alloc(pool, sizeof(*acs), "mod_event_socket.c"
, (const char *)__func__, 2283)
;
2284 switch_assert(acs)((acs) ? (void) (0) : __assert_fail ("acs", "mod_event_socket.c"
, 2284, __PRETTY_FUNCTION__))
;
2285 acs->pool = pool;
2286 acs->listener = listener;
2287 acs->console_execute = 0;
2288
2289 if (api_cmd) {
2290 acs->api_cmd = switch_core_strdup(acs->pool, api_cmd)switch_core_perform_strdup(acs->pool, api_cmd, "mod_event_socket.c"
, (const char *)__func__, 2290)
;
2291 }
2292 if (arg) {
2293 acs->arg = switch_core_strdup(acs->pool, arg)switch_core_perform_strdup(acs->pool, arg, "mod_event_socket.c"
, (const char *)__func__, 2293)
;
2294 }
2295 acs->bg = 1;
2296
2297 switch_threadattr_create(&thd_attr, acs->pool);
2298 switch_threadattr_detach_set(thd_attr, 1);
2299 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024);
2300
2301 if ((uuid_str = switch_event_get_header(*event, "job-uuid")switch_event_get_header_idx(*event, "job-uuid", -1))) {
2302 switch_copy_string(acs->uuid_str, uuid_str, sizeof(acs->uuid_str));
2303 } else {
2304 switch_uuid_get(&uuid);
2305 switch_uuid_format(acs->uuid_str, &uuid);
2306 }
2307 switch_snprintf(reply, reply_len, "~Reply-Text: +OK Job-UUID: %s\nJob-UUID: %s\n\n", acs->uuid_str, acs->uuid_str);
2308 switch_thread_create(&thread, thd_attr, api_exec, acs, acs->pool);
2309 sanity = 2000;
2310 while (!acs->ack) {
2311 switch_cond_next();
2312 if (--sanity <= 0)
2313 break;
2314 }
2315 if (acs->ack == -1) {
2316 acs->ack--;
2317 }
2318
2319 status = SWITCH_STATUS_SUCCESS;
2320 goto done_noreply;
2321 } else if (!strncasecmp(cmd, "log", 3)) {
2322
2323 char *level_s;
2324 switch_log_level_t ltype = SWITCH_LOG_DEBUG;
2325
2326 if (!switch_test_flag(listener, LFLAG_ALLOW_LOG)((listener)->flags & LFLAG_ALLOW_LOG)) {
2327 switch_snprintf(reply, reply_len, "-ERR permission denied");
2328 goto done;
2329 }
2330 //pull off the first newline/carriage return
2331 strip_cr(cmd);
2332
2333 //move past the command
2334 level_s = cmd + 3;
2335
2336 //see if we got an argument
2337 if (!zstr(level_s)_zstr(level_s)) {
2338 //if so move to the argument
2339 level_s++;
2340 }
2341 //see if we lined up on an argument or not
2342 if (!zstr(level_s)_zstr(level_s)) {
2343 ltype = switch_log_str2level(level_s);
2344 }
2345
2346 if (ltype != SWITCH_LOG_INVALID) {
2347 listener->level = ltype;
2348 switch_set_flag(listener, LFLAG_LOG)(listener)->flags |= (LFLAG_LOG);
2349 switch_snprintf(reply, reply_len, "+OK log level %s [%d]", level_s, listener->level);
2350 } else {
2351 switch_snprintf(reply, reply_len, "-ERR invalid log level");
2352 }
2353 } else if (!strncasecmp(cmd, "linger", 6)) {
2354 if (listener->session) {
2355 time_t linger_time = 600; /* sounds reasonable? */
2356 if (*(cmd+6) == ' ' && *(cmd+7)) { /*how long do you want to linger?*/
2357 linger_time = (time_t) atoi(cmd+7);
2358 } else {
2359 linger_time = (time_t) -1;
2360 }
2361
2362 listener->linger_timeout = linger_time;
2363 switch_set_flag_locked(listener, LFLAG_LINGER)((listener->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("listener->flag_mutex != ((void*)0)", "mod_event_socket.c"
, 2363, __PRETTY_FUNCTION__));switch_mutex_lock(listener->
flag_mutex);(listener)->flags |= (LFLAG_LINGER);switch_mutex_unlock
(listener->flag_mutex);
;
2364 if (listener->linger_timeout != (time_t) -1) {
2365 switch_snprintf(reply, reply_len, "+OK will linger %d seconds", (int)linger_time);
2366 } else {
2367 switch_snprintf(reply, reply_len, "+OK will linger");
2368 }
2369 } else {
2370 switch_snprintf(reply, reply_len, "-ERR not controlling a session");
2371 }
2372 } else if (!strncasecmp(cmd, "nolinger", 8)) {
2373 if (listener->session) {
2374 switch_clear_flag_locked(listener, LFLAG_LINGER)switch_mutex_lock(listener->flag_mutex); (listener)->flags
&= ~(LFLAG_LINGER); switch_mutex_unlock(listener->flag_mutex
);
;
2375 switch_snprintf(reply, reply_len, "+OK will not linger");
2376 } else {
2377 switch_snprintf(reply, reply_len, "-ERR not controlling a session");
2378 }
2379 } else if (!strncasecmp(cmd, "nolog", 5)) {
2380 flush_listener(listener, SWITCH_TRUE, SWITCH_FALSE);
2381 if (switch_test_flag(listener, LFLAG_LOG)((listener)->flags & LFLAG_LOG)) {
2382 switch_clear_flag_locked(listener, LFLAG_LOG)switch_mutex_lock(listener->flag_mutex); (listener)->flags
&= ~(LFLAG_LOG); switch_mutex_unlock(listener->flag_mutex
);
;
2383 switch_snprintf(reply, reply_len, "+OK no longer logging");
2384 } else {
2385 switch_snprintf(reply, reply_len, "-ERR not loging");
2386 }
2387 } else if (!strncasecmp(cmd, "event", 5)) {
2388 char *next, *cur;
2389 uint32_t count = 0, key_count = 0;
2390 uint8_t custom = 0;
2391
2392 strip_cr(cmd);
2393 cur = cmd + 5;
2394
2395 if (cur && (cur = strchr(cur, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p
(cur) && (' ') == '\0' ? (char *) __rawmemchr (cur, ' '
) : __builtin_strchr (cur, ' ')))
)) {
2396 for (cur++; cur; count++) {
2397 switch_event_types_t type;
2398
2399 if ((next = strchr(cur, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p
(cur) && (' ') == '\0' ? (char *) __rawmemchr (cur, ' '
) : __builtin_strchr (cur, ' ')))
)) {
2400 *next++ = '\0';
2401 }
2402
2403 if (!count) {
2404 if (!strcasecmp(cur, "xml")) {
2405 listener->format = EVENT_FORMAT_XML;
2406 goto end;
2407 } else if (!strcasecmp(cur, "plain")) {
2408 listener->format = EVENT_FORMAT_PLAIN;
2409 goto end;
2410 } else if (!strcasecmp(cur, "json")) {
2411 listener->format = EVENT_FORMAT_JSON;
2412 goto end;
2413 }
2414 }
2415
2416
2417 if (custom) {
2418 if (!listener->allowed_event_hash || switch_core_hash_find(listener->allowed_event_hash, cur)) {
2419 switch_core_hash_insert(listener->event_hash, cur, MARKER)switch_core_hash_insert_destructor(listener->event_hash, cur
, MARKER, ((void*)0))
;
2420 } else {
2421 switch_snprintf(reply, reply_len, "-ERR permission denied");
2422 goto done;
2423 }
2424 } else if (switch_name_event(cur, &type) == SWITCH_STATUS_SUCCESS) {
2425 if (switch_test_flag(listener, LFLAG_AUTH_EVENTS)((listener)->flags & LFLAG_AUTH_EVENTS) && !listener->allowed_event_list[type] &&
2426 !switch_test_flag(listener, LFLAG_ALL_EVENTS_AUTHED)((listener)->flags & LFLAG_ALL_EVENTS_AUTHED)) {
2427 switch_snprintf(reply, reply_len, "-ERR permission denied");
2428 goto done;
2429 }
2430
2431 key_count++;
2432 if (type == SWITCH_EVENT_ALL) {
2433 uint32_t x = 0;
2434 for (x = 0; x < SWITCH_EVENT_ALL; x++) {
2435 listener->event_list[x] = 1;
2436 }
2437 }
2438 if (type <= SWITCH_EVENT_ALL) {
2439 listener->event_list[type] = 1;
2440 }
2441 if (type == SWITCH_EVENT_CUSTOM) {
2442 custom++;
2443 }
2444 }
2445
2446 end:
2447 cur = next;
2448 }
2449 }
2450
2451 if (!key_count) {
2452 switch_snprintf(reply, reply_len, "-ERR no keywords supplied");
2453 goto done;
2454 }
2455
2456 if (!switch_test_flag(listener, LFLAG_EVENTS)((listener)->flags & LFLAG_EVENTS)) {
2457 switch_set_flag_locked(listener, LFLAG_EVENTS)((listener->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("listener->flag_mutex != ((void*)0)", "mod_event_socket.c"
, 2457, __PRETTY_FUNCTION__));switch_mutex_lock(listener->
flag_mutex);(listener)->flags |= (LFLAG_EVENTS);switch_mutex_unlock
(listener->flag_mutex);
;
2458 }
2459
2460 switch_snprintf(reply, reply_len, "+OK event listener enabled %s", format2str(listener->format));
2461
2462 } else if (!strncasecmp(cmd, "nixevent", 8)) {
2463 char *next, *cur;
2464 uint32_t count = 0, key_count = 0;
2465 uint8_t custom = 0;
2466
2467 strip_cr(cmd);
2468 cur = cmd + 5;
2469
2470 if (cur && (cur = strchr(cur, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p
(cur) && (' ') == '\0' ? (char *) __rawmemchr (cur, ' '
) : __builtin_strchr (cur, ' ')))
)) {
2471 for (cur++; cur; count++) {
2472 switch_event_types_t type;
2473
2474 if ((next = strchr(cur, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p
(cur) && (' ') == '\0' ? (char *) __rawmemchr (cur, ' '
) : __builtin_strchr (cur, ' ')))
)) {
2475 *next++ = '\0';
2476 }
2477
2478 if (custom) {
2479 switch_core_hash_delete(listener->event_hash, cur);
2480 } else if (switch_name_event(cur, &type) == SWITCH_STATUS_SUCCESS) {
2481 uint32_t x = 0;
2482 key_count++;
2483
2484 if (type == SWITCH_EVENT_CUSTOM) {
2485 custom++;
2486 } else if (type == SWITCH_EVENT_ALL) {
2487 for (x = 0; x <= SWITCH_EVENT_ALL; x++) {
2488 listener->event_list[x] = 0;
2489 }
2490 } else {
2491 if (listener->event_list[SWITCH_EVENT_ALL]) {
2492 listener->event_list[SWITCH_EVENT_ALL] = 0;
2493 for (x = 0; x < SWITCH_EVENT_ALL; x++) {
2494 listener->event_list[x] = 1;
2495 }
2496 }
2497 listener->event_list[type] = 0;
2498 }
2499 }
2500
2501 cur = next;
2502 }
2503 }
2504
2505 if (!key_count) {
2506 switch_snprintf(reply, reply_len, "-ERR no keywords supplied");
2507 goto done;
2508 }
2509
2510 if (!switch_test_flag(listener, LFLAG_EVENTS)((listener)->flags & LFLAG_EVENTS)) {
2511 switch_set_flag_locked(listener, LFLAG_EVENTS)((listener->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("listener->flag_mutex != ((void*)0)", "mod_event_socket.c"
, 2511, __PRETTY_FUNCTION__));switch_mutex_lock(listener->
flag_mutex);(listener)->flags |= (LFLAG_EVENTS);switch_mutex_unlock
(listener->flag_mutex);
;
2512 }
2513
2514 switch_snprintf(reply, reply_len, "+OK events nixed");
2515
2516 } else if (!strncasecmp(cmd, "noevents", 8)) {
2517 flush_listener(listener, SWITCH_FALSE, SWITCH_TRUE);
2518
2519 if (switch_test_flag(listener, LFLAG_EVENTS)((listener)->flags & LFLAG_EVENTS)) {
2520 uint8_t x = 0;
2521 switch_clear_flag_locked(listener, LFLAG_EVENTS)switch_mutex_lock(listener->flag_mutex); (listener)->flags
&= ~(LFLAG_EVENTS); switch_mutex_unlock(listener->flag_mutex
);
;
2522 for (x = 0; x <= SWITCH_EVENT_ALL; x++) {
2523 listener->event_list[x] = 0;
2524 }
2525 /* wipe the hash */
2526 switch_core_hash_destroy(&listener->event_hash);
2527 switch_core_hash_init(&listener->event_hash)switch_core_hash_init_case(&listener->event_hash, SWITCH_TRUE
)
;
2528 switch_snprintf(reply, reply_len, "+OK no longer listening for events");
2529 } else {
2530 switch_snprintf(reply, reply_len, "-ERR not listening for events");
2531 }
2532 }
2533
2534 done:
2535
2536 if (zstr(reply)_zstr(reply)) {
2537 switch_snprintf(reply, reply_len, "-ERR command not found");
2538 }
2539
2540 done_noreply:
2541
2542 if (event) {
2543 switch_event_destroy(event);
2544 }
2545
2546 return status;
2547}
2548
2549static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj)
2550{
2551 listener_t *listener = (listener_t *) obj;
2552 char buf[1024];
2553 switch_size_t len;
2554 switch_status_t status;
2555 switch_event_t *event;
2556 char reply[512] = "";
2557 switch_core_session_t *session = NULL((void*)0);
2558 switch_channel_t *channel = NULL((void*)0);
2559 switch_event_t *revent = NULL((void*)0);
2560 const char *var;
2561 int locked = 1;
2562
2563 switch_mutex_lock(globals.listener_mutex);
2564 prefs.threads++;
2565 switch_mutex_unlock(globals.listener_mutex);
2566
2567 switch_assert(listener != NULL)((listener != ((void*)0)) ? (void) (0) : __assert_fail ("listener != ((void*)0)"
, "mod_event_socket.c", 2567, __PRETTY_FUNCTION__))
;
2568
2569 if ((session = listener->session)) {
2570 if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
2571 locked = 0;
2572 goto done;
2573 }
2574 }
2575
2576 switch_socket_opt_set(listener->sock, SWITCH_SO_TCP_NODELAY512, TRUE(!0));
2577 switch_socket_opt_set(listener->sock, SWITCH_SO_NONBLOCK8, TRUE(!0));
2578
2579 if (prefs.acl_count && listener->sa && !zstr(listener->remote_ip)_zstr(listener->remote_ip)) {
2580 uint32_t x = 0;
2581
2582 for (x = 0; x < prefs.acl_count; x++) {
2583 if (!switch_check_network_list_ip(listener->remote_ip, prefs.acl[x])switch_check_network_list_ip_token(listener->remote_ip, prefs
.acl[x], ((void*)0))
) {
2584 const char message[] = "Access Denied, go away.\n";
2585 int mlen = (int)strlen(message);
2586
2587 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_event_socket.c", (const char *
)__func__, 2587, (const char*)(session)
, SWITCH_LOG_WARNING, "IP %s Rejected by acl \"%s\"\n", listener->remote_ip,
2588 prefs.acl[x]);
2589
2590 switch_snprintf(buf, sizeof(buf), "Content-Type: text/rude-rejection\nContent-Length: %d\n\n", mlen);
2591 len = strlen(buf);
2592 switch_socket_send(listener->sock, buf, &len);
2593 len = mlen;
2594 switch_socket_send(listener->sock, message, &len);
2595 goto done;
2596 }
2597 }
2598 }
2599
2600 if (globals.debug > 0) {
2601 if (zstr(listener->remote_ip)_zstr(listener->remote_ip)) {
2602 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_event_socket.c", (const char *
)__func__, 2602, (const char*)(session)
, SWITCH_LOG_DEBUG, "Connection Open\n");
2603 } else {
2604 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_event_socket.c", (const char *
)__func__, 2604, (const char*)(session)
, SWITCH_LOG_DEBUG, "Connection Open from %s:%d\n", listener->remote_ip,
2605 listener->remote_port);
2606 }
2607 }
2608
2609 switch_socket_opt_set(listener->sock, SWITCH_SO_NONBLOCK8, TRUE(!0));
2610 switch_set_flag_locked(listener, LFLAG_RUNNING)((listener->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("listener->flag_mutex != ((void*)0)", "mod_event_socket.c"
, 2610, __PRETTY_FUNCTION__));switch_mutex_lock(listener->
flag_mutex);(listener)->flags |= (LFLAG_RUNNING);switch_mutex_unlock
(listener->flag_mutex);
;
2611 add_listener(listener);
2612
2613 if (session && switch_test_flag(listener, LFLAG_AUTHED)((listener)->flags & LFLAG_AUTHED)) {
2614 switch_event_t *ievent = NULL((void*)0);
2615
2616 switch_set_flag_locked(listener, LFLAG_SESSION)((listener->flag_mutex != ((void*)0)) ? (void) (0) : __assert_fail
("listener->flag_mutex != ((void*)0)", "mod_event_socket.c"
, 2616, __PRETTY_FUNCTION__));switch_mutex_lock(listener->
flag_mutex);(listener)->flags |= (LFLAG_SESSION);switch_mutex_unlock
(listener->flag_mutex);
;
2617 status = read_packet(listener, &ievent, 25);
2618
2619 if (status != SWITCH_STATUS_SUCCESS || !ievent) {
2620 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_event_socket.c", (const char *
)__func__, 2620, (const char*)(session)
, SWITCH_LOG_CRIT, "Socket Error!\n");
2621 switch_clear_flag_locked(listener, LFLAG_RUNNING)switch_mutex_lock(listener->flag_mutex); (listener)->flags
&= ~(LFLAG_RUNNING); switch_mutex_unlock(listener->flag_mutex
);
;
2622 goto done;
2623 }
2624
2625
2626 if (parse_command(listener, &ievent, reply, sizeof(reply)) != SWITCH_STATUS_SUCCESS) {
2627 switch_clear_flag_locked(listener, LFLAG_RUNNING)switch_mutex_lock(listener->flag_mutex); (listener)->flags
&= ~(LFLAG_RUNNING); switch_mutex_unlock(listener->flag_mutex
);
;
2628 goto done;
2629 }
2630
2631
2632 } else {
2633 switch_snprintf(buf, sizeof(buf), "Content-Type: auth/request\n\n");
2634
2635 len = strlen(buf);
2636 switch_socket_send(listener->sock, buf, &len);
2637
2638 while (!switch_test_flag(listener, LFLAG_AUTHED)((listener)->flags & LFLAG_AUTHED)) {
2639 status = read_packet(listener, &event, 25);
2640 if (status != SWITCH_STATUS_SUCCESS) {
2641 goto done;
2642 }
2643 if (!event) {
2644 continue;
2645 }
2646
2647 if (parse_command(listener, &event, reply, sizeof(reply)) != SWITCH_STATUS_SUCCESS) {
2648 switch_clear_flag_locked(listener, LFLAG_RUNNING)switch_mutex_lock(listener->flag_mutex); (listener)->flags
&= ~(LFLAG_RUNNING); switch_mutex_unlock(listener->flag_mutex
);
;
2649 goto done;
2650 }
2651 if (*reply != '\0') {
2652 if (*reply == '~') {
2653 switch_snprintf(buf, sizeof(buf), "Content-Type: command/reply\n%s", reply + 1);
2654 } else {
2655 switch_snprintf(buf, sizeof(buf), "Content-Type: command/reply\nReply-Text: %s\n\n", reply);
2656 }
2657 len = strlen(buf);
2658 switch_socket_send(listener->sock, buf, &len);
2659 }
2660 break;
2661 }
2662 }
2663
2664 while (!prefs.done && switch_test_flag(listener, LFLAG_RUNNING)((listener)->flags & LFLAG_RUNNING) && listen_list.ready) {
2665 len = sizeof(buf);
2666 memset(buf, 0, len);
2667 status = read_packet(listener, &revent, 0);
2668
2669 if (status != SWITCH_STATUS_SUCCESS) {
2670 break;
2671 }
2672
2673 if (!revent) {
2674 continue;
2675 }
2676
2677 if (parse_command(listener, &revent, reply, sizeof(reply)) != SWITCH_STATUS_SUCCESS) {
2678 switch_clear_flag_locked(listener, LFLAG_RUNNING)switch_mutex_lock(listener->flag_mutex); (listener)->flags
&= ~(LFLAG_RUNNING); switch_mutex_unlock(listener->flag_mutex
);
;
2679 break;
2680 }
2681
2682 if (revent) {
2683 switch_event_destroy(&revent);
2684 }
2685
2686 if (*reply != '\0') {
2687 if (*reply == '~') {
2688 switch_snprintf(buf, sizeof(buf), "Content-Type: command/reply\n%s", reply + 1);
2689 } else {
2690 switch_snprintf(buf, sizeof(buf), "Content-Type: command/reply\nReply-Text: %s\n\n", reply);
2691 }
2692 len = strlen(buf);
2693 switch_socket_send(listener->sock, buf, &len);
2694 }
2695
2696 }
2697
2698 done:
2699
2700 if (revent) {
2701 switch_event_destroy(&revent);
2702 }
2703
2704 remove_listener(listener);
2705
2706 if (globals.debug > 0) {
2707 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_event_socket.c", (const char *
)__func__, 2707, (const char*)(session)
, SWITCH_LOG_DEBUG, "Session complete, waiting for children\n");
2708 }
2709
2710 switch_thread_rwlock_wrlock(listener->rwlock);
2711 flush_listener(listener, SWITCH_TRUE, SWITCH_TRUE);
2712 switch_mutex_lock(listener->filter_mutex);
2713 if (listener->filters) {
2714 switch_event_destroy(&listener->filters);
2715 }
2716 switch_mutex_unlock(listener->filter_mutex);
2717
2718 if (listener->session) {
2719 channel = switch_core_session_get_channel(listener->session);
2720 }
2721
2722 if (channel && (switch_test_flag(listener, LFLAG_RESUME)((listener)->flags & LFLAG_RESUME) || ((var = switch_channel_get_variable(channel, "socket_resume")switch_channel_get_variable_dup(channel, "socket_resume", SWITCH_TRUE
, -1)
) && switch_true(var)))) {
2723 switch_channel_set_state(channel, CS_RESET)switch_channel_perform_set_state(channel, "mod_event_socket.c"
, (const char *)__func__, 2723, CS_RESET)
;
2724 }
2725
2726 if (listener->sock) {
2727 send_disconnect(listener, "Disconnected, goodbye.\nSee you at ClueCon! http://www.cluecon.com/\n");
2728 close_socket(&listener->sock);
2729 }
2730
2731 switch_thread_rwlock_unlock(listener->rwlock);
2732
2733 if (globals.debug > 0) {
2734 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "mod_event_socket.c", (const char *
)__func__, 2734, (const char*)(session)
, SWITCH_LOG_DEBUG, "Connection Closed\n");
2735 }
2736
2737 switch_core_hash_destroy(&listener->event_hash);
2738
2739 if (listener->allowed_event_hash) {
2740 switch_core_hash_destroy(&listener->allowed_event_hash);
2741 }
2742
2743 if (listener->allowed_api_hash) {
2744 switch_core_hash_destroy(&listener->allowed_api_hash);
2745 }
2746
2747 if (listener->session) {
2748 switch_channel_clear_flag(switch_core_session_get_channel(listener->session), CF_CONTROLLED);
2749 switch_clear_flag_locked(listener, LFLAG_SESSION)switch_mutex_lock(listener->flag_mutex); (listener)->flags
&= ~(LFLAG_SESSION); switch_mutex_unlock(listener->flag_mutex
);
;
2750 if (locked) {
2751 switch_core_session_rwunlock(listener->session);
2752 }
2753 } else if (listener->pool) {
2754 switch_memory_pool_t *pool = listener->pool;
2755 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "mod_event_socket.c"
, (const char *)__func__, 2755)
;
2756 }
2757
2758 switch_mutex_lock(globals.listener_mutex);
2759 prefs.threads--;
2760 switch_mutex_unlock(globals.listener_mutex);
2761
2762 return NULL((void*)0);
2763}
2764
2765
2766/* Create a thread for the socket and launch it */
2767static void launch_listener_thread(listener_t *listener)
2768{
2769 switch_thread_t *thread;
2770 switch_threadattr_t *thd_attr = NULL((void*)0);
2771
2772 switch_threadattr_create(&thd_attr, listener->pool);
2773 switch_threadattr_detach_set(thd_attr, 1);
2774 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024);
2775 switch_thread_create(&thread, thd_attr, listener_run, listener, listener->pool);
2776}
2777
2778static int config(void)
2779{
2780 char *cf = "event_socket.conf";
2781 switch_xml_t cfg, xml, settings, param;
2782
2783 memset(&prefs, 0, sizeof(prefs));
2784
2785 if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL((void*)0)))) {
2786 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_event_socket.c", (const char *)__func__
, 2786, ((void*)0)
, SWITCH_LOG_ERROR, "Open of %s failed\n", cf);
2787 } else {
2788 if ((settings = switch_xml_child(cfg, "settings"))) {
2789 for (param = switch_xml_child(settings, "param"); param; param = param->next) {
2790 char *var = (char *) switch_xml_attr_soft(param, "name");
2791 char *val = (char *) switch_xml_attr_soft(param, "value");
2792
2793 if (!strcmp(var, "listen-ip")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("listen-ip") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("listen-ip"), (!((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) || __s1_len >= 4) && (!
((size_t)(const void *)(("listen-ip") + 1) - (size_t)(const void
*)("listen-ip") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(var, "listen-ip") : (__builtin_constant_p (var) && (
(size_t)(const void *)((var) + 1) - (size_t)(const void *)(var
) == 1) && (__s1_len = __builtin_strlen (var), __s1_len
< 4) ? (__builtin_constant_p ("listen-ip") && ((size_t
)(const void *)(("listen-ip") + 1) - (size_t)(const void *)("listen-ip"
) == 1) ? __builtin_strcmp (var, "listen-ip") : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) ("listen-ip"); int __result = (((const unsigned char
*) (const char *) (var))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (var))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (var))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (var))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("listen-ip") && ((size_t)(const void *)(("listen-ip"
) + 1) - (size_t)(const void *)("listen-ip") == 1) &&
(__s2_len = __builtin_strlen ("listen-ip"), __s2_len < 4)
? (__builtin_constant_p (var) && ((size_t)(const void
*)((var) + 1) - (size_t)(const void *)(var) == 1) ? __builtin_strcmp
(var, "listen-ip") : (- (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (var); int __result
= (((const unsigned char *) (const char *) ("listen-ip"))[0]
- __s2[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("listen-ip"))[1]
- __s2[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("listen-ip"))[2]
- __s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) ("listen-ip"))[3]
- __s2[3]); } } __result; })))) : __builtin_strcmp (var, "listen-ip"
)))); })
) {
2794 set_pref_ip(val);
2795 } else if (!strcmp(var, "debug")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("debug") && (
__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("debug"), (!((size_t)(const void *)((var) + 1) - (size_t)(const
void *)(var) == 1) || __s1_len >= 4) && (!((size_t
)(const void *)(("debug") + 1) - (size_t)(const void *)("debug"
) == 1) || __s2_len >= 4)) ? __builtin_strcmp (var, "debug"
) : (__builtin_constant_p (var) && ((size_t)(const void
*)((var) + 1) - (size_t)(const void *)(var) == 1) &&
(__s1_len = __builtin_strlen (var), __s1_len < 4) ? (__builtin_constant_p
("debug") && ((size_t)(const void *)(("debug") + 1) -
(size_t)(const void *)("debug") == 1) ? __builtin_strcmp (var
, "debug") : (__extension__ ({ const unsigned char *__s2 = (const
unsigned char *) (const char *) ("debug"); int __result = ((
(const unsigned char *) (const char *) (var))[0] - __s2[0]); if
(__s1_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) (var))[1] - __s2[1]); if (__s1_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (var))[2] - __s2[2]); if (__s1_len >
2 && __result == 0) __result = (((const unsigned char
*) (const char *) (var))[3] - __s2[3]); } } __result; }))) :
(__builtin_constant_p ("debug") && ((size_t)(const void
*)(("debug") + 1) - (size_t)(const void *)("debug") == 1) &&
(__s2_len = __builtin_strlen ("debug"), __s2_len < 4) ? (
__builtin_constant_p (var) && ((size_t)(const void *)
((var) + 1) - (size_t)(const void *)(var) == 1) ? __builtin_strcmp
(var, "debug") : (- (__extension__ ({ const unsigned char *__s2
= (const unsigned char *) (const char *) (var); int __result
= (((const unsigned char *) (const char *) ("debug"))[0] - __s2
[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("debug"))[1] - __s2
[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("debug"))[2] - __s2
[2]); if (__s2_len > 2 && __result == 0) __result =
(((const unsigned char *) (const char *) ("debug"))[3] - __s2
[3]); } } __result; })))) : __builtin_strcmp (var, "debug")))
); })
) {
2796 globals.debug = atoi(val);
2797 } else if (!strcmp(var, "nat-map")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("nat-map") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("nat-map"), (!((size_t)(const void *)((var) + 1) - (size_t)
(const void *)(var) == 1) || __s1_len >= 4) && (!(
(size_t)(const void *)(("nat-map") + 1) - (size_t)(const void
*)("nat-map") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(var, "nat-map") : (__builtin_constant_p (var) && ((
size_t)(const void *)((var) + 1) - (size_t)(const void *)(var
) == 1) && (__s1_len = __builtin_strlen (var), __s1_len
< 4) ? (__builtin_constant_p ("nat-map") && ((size_t
)(const void *)(("nat-map") + 1) - (size_t)(const void *)("nat-map"
) == 1) ? __builtin_strcmp (var, "nat-map") : (__extension__ (
{ const unsigned char *__s2 = (const unsigned char *) (const char
*) ("nat-map"); int __result = (((const unsigned char *) (const
char *) (var))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (var))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (var))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (var))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("nat-map") && ((size_t)(const void *)(("nat-map") +
1) - (size_t)(const void *)("nat-map") == 1) && (__s2_len
= __builtin_strlen ("nat-map"), __s2_len < 4) ? (__builtin_constant_p
(var) && ((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) ? __builtin_strcmp (var, "nat-map"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (var); int __result = (((const unsigned
char *) (const char *) ("nat-map"))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) ("nat-map"))[1] - __s2[1]); if (__s2_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) ("nat-map"))[2] - __s2[2]); if (__s2_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) ("nat-map"))[3] - __s2[3]); } } __result
; })))) : __builtin_strcmp (var, "nat-map")))); })
) {
2798 if (switch_true(val) && switch_nat_get_type()) {
2799 prefs.nat_map = 1;
2800 }
2801 } else if (!strcmp(var, "listen-port")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("listen-port") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("listen-port"), (!((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) || __s1_len >= 4) && (!
((size_t)(const void *)(("listen-port") + 1) - (size_t)(const
void *)("listen-port") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(var, "listen-port") : (__builtin_constant_p (var) &&
((size_t)(const void *)((var) + 1) - (size_t)(const void *)(
var) == 1) && (__s1_len = __builtin_strlen (var), __s1_len
< 4) ? (__builtin_constant_p ("listen-port") && (
(size_t)(const void *)(("listen-port") + 1) - (size_t)(const void
*)("listen-port") == 1) ? __builtin_strcmp (var, "listen-port"
) : (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) ("listen-port"); int __result = (((const
unsigned char *) (const char *) (var))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (var))[1] - __s2[1]); if (__s1_len >
1 && __result == 0) { __result = (((const unsigned char
*) (const char *) (var))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (var))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("listen-port") && ((size_t)(const void *)(("listen-port"
) + 1) - (size_t)(const void *)("listen-port") == 1) &&
(__s2_len = __builtin_strlen ("listen-port"), __s2_len < 4
) ? (__builtin_constant_p (var) && ((size_t)(const void
*)((var) + 1) - (size_t)(const void *)(var) == 1) ? __builtin_strcmp
(var, "listen-port") : (- (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (var); int __result
= (((const unsigned char *) (const char *) ("listen-port"))[
0] - __s2[0]); if (__s2_len > 0 && __result == 0) {
__result = (((const unsigned char *) (const char *) ("listen-port"
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("listen-port"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("listen-port"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (var
, "listen-port")))); })
) {
2802 prefs.port = (uint16_t) atoi(val);
2803 } else if (!strcmp(var, "password")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(var) && __builtin_constant_p ("password") &&
(__s1_len = __builtin_strlen (var), __s2_len = __builtin_strlen
("password"), (!((size_t)(const void *)((var) + 1) - (size_t
)(const void *)(var) == 1) || __s1_len >= 4) && (!
((size_t)(const void *)(("password") + 1) - (size_t)(const void
*)("password") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(var, "password") : (__builtin_constant_p (var) && (
(size_t)(const void *)((var) + 1) - (size_t)(const void *)(var
) == 1) && (__s1_len = __builtin_strlen (var), __s1_len
< 4) ? (__builtin_constant_p ("password") && ((size_t
)(const void *)(("password") + 1) - (size_t)(const void *)("password"
) == 1) ? __builtin_strcmp (var, "password") : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) ("password"); int __result = (((const unsigned char *
) (const char *) (var))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (var))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (var))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (var))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("password") && ((size_t)(const void *)(("password")
+ 1) - (size_t)(const void *)("password") == 1) && (
__s2_len = __builtin_strlen ("password"), __s2_len < 4) ? (
__builtin_constant_p (var) && ((size_t)(const void *)
((var) + 1) - (size_t)(const void *)(var) == 1) ? __builtin_strcmp
(var, "password") : (- (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (var); int __result
= (((const unsigned char *) (const char *) ("password"))[0] -
__s2[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("password"))[1] -
__s2[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("password"))[2] -
__s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) ("password"))[3] -
__s2[3]); } } __result; })))) : __builtin_strcmp (var, "password"
)))); })
) {
2804 set_pref_pass(val);
2805 } else if (!strcasecmp(var, "apply-inbound-acl") && ! zstr(val)_zstr(val)) {
2806 if (prefs.acl_count < MAX_ACL100) {
2807 prefs.acl[prefs.acl_count++] = strdup(val)(__extension__ (__builtin_constant_p (val) && ((size_t
)(const void *)((val) + 1) - (size_t)(const void *)(val) == 1
) ? (((const char *) (val))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen (val) + 1; char *
__retval = (char *) malloc (__len); if (__retval != ((void*)0
)) __retval = (char *) memcpy (__retval, val, __len); __retval
; })) : __strdup (val)))
;
2808 } else {
2809 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_event_socket.c", (const char *)__func__
, 2809, ((void*)0)
, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", MAX_ACL100);
2810 }
2811 } else if (!strcasecmp(var, "stop-on-bind-error")) {
2812 prefs.stop_on_bind_error = switch_true(val) ? 1 : 0;
2813 }
2814 }
2815 }
2816 switch_xml_free(xml);
2817 }
2818
2819 if (zstr(prefs.ip)_zstr(prefs.ip)) {
2820 set_pref_ip("127.0.0.1");
2821 }
2822
2823 if (zstr(prefs.password)_zstr(prefs.password)) {
2824 set_pref_pass("ClueCon");
2825 }
2826
2827 if (!prefs.nat_map) {
2828 prefs.nat_map = 0;
2829 }
2830
2831 if (prefs.nat_map) {
2832 prefs.nat_map = 0;
2833 }
2834
2835 if (!prefs.port) {
2836 prefs.port = 8021;
2837 }
2838
2839 return 0;
2840}
2841
2842
2843SWITCH_MODULE_RUNTIME_FUNCTION(mod_event_socket_runtime)switch_status_t mod_event_socket_runtime (void)
2844{
2845 switch_memory_pool_t *pool = NULL((void*)0), *listener_pool = NULL((void*)0);
2846 switch_status_t rv;
2847 switch_sockaddr_t *sa;
2848 switch_socket_t *inbound_socket = NULL((void*)0);
2849 listener_t *listener;
2850 uint32_t x = 0;
2851 uint32_t errs = 0;
2852
2853 if (switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "mod_event_socket.c"
, (const char *)__func__, 2853)
!= SWITCH_STATUS_SUCCESS) {
2854 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_event_socket.c", (const char *)__func__
, 2854, ((void*)0)
, SWITCH_LOG_ERROR, "OH OH no pool\n");
2855 return SWITCH_STATUS_TERM;
2856 }
2857
2858 config();
2859
2860 while (!prefs.done) {
2861 rv = switch_sockaddr_info_get(&sa, prefs.ip, SWITCH_UNSPEC0, prefs.port, 0, pool);
2862 if (rv)
2863 goto fail;
2864 rv = switch_socket_create(&listen_list.sock, switch_sockaddr_get_family(sa), SOCK_STREAMSOCK_STREAM, SWITCH_PROTO_TCP6, pool);
2865 if (rv)
2866 goto sock_fail;
2867 rv = switch_socket_opt_set(listen_list.sock, SWITCH_SO_REUSEADDR16, 1);
2868 if (rv)
2869 goto sock_fail;
2870#ifdef WIN32
2871 /* Enable dual-stack listening on Windows (if the listening address is IPv6), it's default on Linux */
2872 if (switch_sockaddr_get_family(sa) == AF_INET610) {
2873 rv = switch_socket_opt_set(listen_list.sock, 16384, 0);
2874 if (rv) goto sock_fail;
2875 }
2876#endif
2877 rv = switch_socket_bind(listen_list.sock, sa);
2878 if (rv)
2879 goto sock_fail;
2880 rv = switch_socket_listen(listen_list.sock, 5);
2881 if (rv)
2882 goto sock_fail;
2883 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_event_socket.c", (const char *)__func__
, 2883, ((void*)0)
, SWITCH_LOG_DEBUG, "Socket up listening on %s:%u\n", prefs.ip, prefs.port);
2884
2885 if (prefs.nat_map) {
2886 switch_nat_add_mapping(prefs.port, SWITCH_NAT_TCP, NULL((void*)0), SWITCH_FALSE);
2887 }
2888
2889 break;
2890 sock_fail:
2891 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_event_socket.c", (const char *)__func__
, 2891, ((void*)0)
, SWITCH_LOG_ERROR, "Socket Error! Could not listen on %s:%u\n", prefs.ip, prefs.port);
2892 if (prefs.stop_on_bind_error) {
2893 prefs.done = 1;
2894 goto fail;
2895 }
2896 switch_yield(100000)switch_sleep(100000);;
2897 }
2898
2899 listen_list.ready = 1;
2900
2901
2902 while (!prefs.done) {
2903 if (switch_core_new_memory_pool(&listener_pool)switch_core_perform_new_memory_pool(&listener_pool, "mod_event_socket.c"
, (const char *)__func__, 2903)
!= SWITCH_STATUS_SUCCESS) {
2904 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_event_socket.c", (const char *)__func__
, 2904, ((void*)0)
, SWITCH_LOG_ERROR, "OH OH no pool\n");
2905 goto fail;
2906 }
2907
2908
2909 if ((rv = switch_socket_accept(&inbound_socket, listen_list.sock, listener_pool))) {
2910 if (prefs.done) {
2911 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_event_socket.c", (const char *)__func__
, 2911, ((void*)0)
, SWITCH_LOG_NOTICE, "Shutting Down\n");
2912 goto end;
2913 } else {
2914 /* I wish we could use strerror_r here but its not defined everywhere =/ */
2915 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_event_socket.c", (const char *)__func__
, 2915, ((void*)0)
, SWITCH_LOG_ERROR, "Socket Error [%s]\n", strerror(errno(*__errno_location ())));
2916 if (++errs > 100) {
2917 goto end;
2918 }
2919 }
2920 } else {
2921 errs = 0;
2922 }
2923
2924
2925 if (!(listener = switch_core_alloc(listener_pool, sizeof(*listener))switch_core_perform_alloc(listener_pool, sizeof(*listener), "mod_event_socket.c"
, (const char *)__func__, 2925)
)) {
2926 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_event_socket.c", (const char *)__func__
, 2926, ((void*)0)
, SWITCH_LOG_ERROR, "Memory Error\n");
2927 break;
2928 }
2929
2930 switch_thread_rwlock_create(&listener->rwlock, listener_pool);
2931 switch_queue_create(&listener->event_queue, MAX_QUEUE_LEN100000, listener_pool);
2932 switch_queue_create(&listener->log_queue, MAX_QUEUE_LEN100000, listener_pool);
2933
2934 listener->sock = inbound_socket;
2935 listener->pool = listener_pool;
2936 listener_pool = NULL((void*)0);
2937 listener->format = EVENT_FORMAT_PLAIN;
2938 switch_set_flag(listener, LFLAG_FULL)(listener)->flags |= (LFLAG_FULL);
2939 switch_set_flag(listener, LFLAG_ALLOW_LOG)(listener)->flags |= (LFLAG_ALLOW_LOG);
2940
2941 switch_mutex_init(&listener->flag_mutex, SWITCH_MUTEX_NESTED0x1, listener->pool);
2942 switch_mutex_init(&listener->filter_mutex, SWITCH_MUTEX_NESTED0x1, listener->pool);
2943
2944 switch_core_hash_init(&listener->event_hash)switch_core_hash_init_case(&listener->event_hash, SWITCH_TRUE
)
;
2945 switch_socket_create_pollset(&listener->pollfd, listener->sock, SWITCH_POLLIN0x001 | SWITCH_POLLERR0x010, listener->pool);
2946
2947
2948
2949 if (switch_socket_addr_get(&listener->sa, SWITCH_TRUE, listener->sock) == SWITCH_STATUS_SUCCESS && listener->sa) {
2950 switch_get_addr(listener->remote_ip, sizeof(listener->remote_ip), listener->sa);
2951 if (listener->sa && (listener->remote_port = switch_sockaddr_get_port(listener->sa))) {
2952 launch_listener_thread(listener);
2953 continue;
2954 }
2955 }
2956
2957 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_event_socket.c", (const char *)__func__
, 2957, ((void*)0)
, SWITCH_LOG_ERROR, "Error initilizing connection\n");
2958 close_socket(&listener->sock);
2959 expire_listener(&listener);
2960
2961 }
2962
2963 end:
2964
2965 close_socket(&listen_list.sock);
2966
2967 if (prefs.nat_map && switch_nat_get_type()) {
2968 switch_nat_del_mapping(prefs.port, SWITCH_NAT_TCP);
2969 }
2970
2971 if (pool) {
2972 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "mod_event_socket.c"
, (const char *)__func__, 2972)
;
2973 }
2974
2975 if (listener_pool) {
2976 switch_core_destroy_memory_pool(&listener_pool)switch_core_perform_destroy_memory_pool(&listener_pool, "mod_event_socket.c"
, (const char *)__func__, 2976)
;
2977 }
2978
2979
2980 for (x = 0; x < prefs.acl_count; x++) {
2981 switch_safe_free(prefs.acl[x])if (prefs.acl[x]) {free(prefs.acl[x]);prefs.acl[x]=((void*)0)
;}
;
2982 }
2983
2984 fail:
2985 return SWITCH_STATUS_TERM;
2986}
2987
2988/* For Emacs:
2989 * Local Variables:
2990 * mode:c
2991 * indent-tabs-mode:t
2992 * tab-width:4
2993 * c-basic-offset:4
2994 * End:
2995 * For VIM:
2996 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
2997 */