Fixed a memory leak, too short of connect times across data centers, a deadlock condition with the globals.bindings_rwlock not being released, a buffer overrun possibility or 4, and added the ability to send a body when injecting an event
This commit is contained in:
parent
ed0ac0358c
commit
994f9a8ca6
|
@ -26,6 +26,8 @@
|
||||||
* Anthony Minessale II <anthm@freeswitch.org>
|
* Anthony Minessale II <anthm@freeswitch.org>
|
||||||
* Andrew Thompson <andrew@hijacked.us>
|
* Andrew Thompson <andrew@hijacked.us>
|
||||||
* Rob Charlton <rob.charlton@savageminds.com>
|
* Rob Charlton <rob.charlton@savageminds.com>
|
||||||
|
* Darren Schreiber <d@d-man.org>
|
||||||
|
* Mike Jerris <mike@jerris.com>
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* handle_msg.c -- handle messages received from erlang nodes
|
* handle_msg.c -- handle messages received from erlang nodes
|
||||||
|
@ -590,13 +592,29 @@ static switch_status_t handle_msg_session_setevent(listener_t *listener, erlang_
|
||||||
static switch_status_t handle_msg_api(listener_t *listener, erlang_msg * msg, int arity, ei_x_buff * buf, ei_x_buff * rbuf)
|
static switch_status_t handle_msg_api(listener_t *listener, erlang_msg * msg, int arity, ei_x_buff * buf, ei_x_buff * rbuf)
|
||||||
{
|
{
|
||||||
char api_cmd[MAXATOMLEN];
|
char api_cmd[MAXATOMLEN];
|
||||||
char arg[1024];
|
int type;
|
||||||
if (arity < 3 || ei_decode_atom(buf->buff, &buf->index, api_cmd) || ei_decode_string(buf->buff, &buf->index, arg)) {
|
int size;
|
||||||
ei_x_encode_tuple_header(rbuf, 2);
|
char *arg;
|
||||||
ei_x_encode_atom(rbuf, "error");
|
switch_bool_t fail = SWITCH_FALSE;
|
||||||
ei_x_encode_atom(rbuf, "badarg");
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
if (arity < 3) {
|
||||||
} else {
|
fail = SWITCH_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ei_get_type(buf->buff, &buf->index, &type, &size);
|
||||||
|
|
||||||
|
if ((size > (sizeof(api_cmd) - 1)) || ei_decode_atom(buf->buff, &buf->index, api_cmd)) {
|
||||||
|
fail = SWITCH_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ei_get_type(buf->buff, &buf->index, &type, &size);
|
||||||
|
arg = malloc(size + 1);
|
||||||
|
|
||||||
|
if (ei_decode_string(buf->buff, &buf->index, arg)) {
|
||||||
|
fail = SWITCH_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fail) {
|
||||||
struct api_command_struct acs = { 0 };
|
struct api_command_struct acs = { 0 };
|
||||||
acs.listener = listener;
|
acs.listener = listener;
|
||||||
acs.api_cmd = api_cmd;
|
acs.api_cmd = api_cmd;
|
||||||
|
@ -604,8 +622,17 @@ static switch_status_t handle_msg_api(listener_t *listener, erlang_msg * msg, in
|
||||||
acs.bg = 0;
|
acs.bg = 0;
|
||||||
acs.pid = msg->from;
|
acs.pid = msg->from;
|
||||||
api_exec(NULL, (void *) &acs);
|
api_exec(NULL, (void *) &acs);
|
||||||
|
|
||||||
|
switch_safe_free(arg);
|
||||||
|
|
||||||
/* don't reply */
|
/* don't reply */
|
||||||
return SWITCH_STATUS_FALSE;
|
return SWITCH_STATUS_FALSE;
|
||||||
|
} else {
|
||||||
|
ei_x_encode_tuple_header(rbuf, 2);
|
||||||
|
ei_x_encode_atom(rbuf, "error");
|
||||||
|
ei_x_encode_atom(rbuf, "badarg");
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -670,18 +697,38 @@ static switch_status_t handle_msg_sendevent(listener_t *listener, int arity, ei_
|
||||||
if ((strlen(esname) && switch_event_create_subclass(&event, etype, esname) == SWITCH_STATUS_SUCCESS) ||
|
if ((strlen(esname) && switch_event_create_subclass(&event, etype, esname) == SWITCH_STATUS_SUCCESS) ||
|
||||||
switch_event_create(&event, etype) == SWITCH_STATUS_SUCCESS) {
|
switch_event_create(&event, etype) == SWITCH_STATUS_SUCCESS) {
|
||||||
char key[1024];
|
char key[1024];
|
||||||
char value[1024];
|
char *value;
|
||||||
|
int type;
|
||||||
|
int size;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
switch_bool_t fail = SWITCH_FALSE;
|
switch_bool_t fail = SWITCH_FALSE;
|
||||||
|
|
||||||
while (!ei_decode_tuple_header(buf->buff, &buf->index, &arity) && arity == 2) {
|
while (!ei_decode_tuple_header(buf->buff, &buf->index, &arity) && arity == 2) {
|
||||||
i++;
|
i++;
|
||||||
if (ei_decode_string(buf->buff, &buf->index, key) || ei_decode_string(buf->buff, &buf->index, value)) {
|
|
||||||
|
ei_get_type(buf->buff, &buf->index, &type, &size);
|
||||||
|
|
||||||
|
if ((size > (sizeof(key) - 1)) || ei_decode_string(buf->buff, &buf->index, key)) {
|
||||||
fail = SWITCH_TRUE;
|
fail = SWITCH_TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, key, value);
|
ei_get_type(buf->buff, &buf->index, &type, &size);
|
||||||
|
value = malloc(size + 1);
|
||||||
|
|
||||||
|
if (ei_decode_string(buf->buff, &buf->index, value)) {
|
||||||
|
fail = SWITCH_TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fail && !strcmp(key, "body")) {
|
||||||
|
switch_safe_free(event->body);
|
||||||
|
event->body = value;
|
||||||
|
} else if (!fail) {
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do not free malloc here! The above commands utilize the raw allocated memory and skip any copying/duplication. Faster. */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (headerlength != i || fail) {
|
if (headerlength != i || fail) {
|
||||||
|
@ -715,16 +762,32 @@ static switch_status_t handle_msg_sendmsg(listener_t *listener, int arity, ei_x_
|
||||||
if (switch_event_create(&event, SWITCH_EVENT_SEND_MESSAGE) == SWITCH_STATUS_SUCCESS) {
|
if (switch_event_create(&event, SWITCH_EVENT_SEND_MESSAGE) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
|
||||||
char key[1024];
|
char key[1024];
|
||||||
char value[1024];
|
char *value;
|
||||||
|
int type;
|
||||||
|
int size;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
switch_bool_t fail = SWITCH_FALSE;
|
switch_bool_t fail = SWITCH_FALSE;
|
||||||
|
|
||||||
while (!ei_decode_tuple_header(buf->buff, &buf->index, &arity) && arity == 2) {
|
while (!ei_decode_tuple_header(buf->buff, &buf->index, &arity) && arity == 2) {
|
||||||
i++;
|
i++;
|
||||||
if (ei_decode_string(buf->buff, &buf->index, key) || ei_decode_string(buf->buff, &buf->index, value)) {
|
ei_get_type(buf->buff, &buf->index, &type, &size);
|
||||||
|
|
||||||
|
if ((size > (sizeof(key) - 1)) || ei_decode_string(buf->buff, &buf->index, key)) {
|
||||||
fail = SWITCH_TRUE;
|
fail = SWITCH_TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, key, value);
|
|
||||||
|
ei_get_type(buf->buff, &buf->index, &type, &size);
|
||||||
|
value = malloc(size + 1);
|
||||||
|
|
||||||
|
if (ei_decode_string(buf->buff, &buf->index, value)) {
|
||||||
|
fail = SWITCH_TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fail) {
|
||||||
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, key, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (headerlength != i || fail) {
|
if (headerlength != i || fail) {
|
||||||
|
|
|
@ -389,6 +389,7 @@ static switch_xml_t erlang_fetch(const char *sectionstr, const char *tag_name, c
|
||||||
|
|
||||||
if (!ptr->listener) {
|
if (!ptr->listener) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "NULL pointer binding!\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "NULL pointer binding!\n");
|
||||||
|
switch_thread_rwlock_unlock(globals.bindings_rwlock);
|
||||||
goto cleanup; /* our pointer is trash */
|
goto cleanup; /* our pointer is trash */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -820,7 +821,7 @@ static void listener_main_loop(listener_t *listener)
|
||||||
|
|
||||||
/* do we need the mutex when reading? */
|
/* do we need the mutex when reading? */
|
||||||
/*switch_mutex_lock(listener->sock_mutex); */
|
/*switch_mutex_lock(listener->sock_mutex); */
|
||||||
status = ei_xreceive_msg_tmo(listener->sockfd, &msg, &buf, 100);
|
status = ei_xreceive_msg_tmo(listener->sockfd, &msg, &buf, 500);
|
||||||
/*switch_mutex_unlock(listener->sock_mutex); */
|
/*switch_mutex_unlock(listener->sock_mutex); */
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
|
@ -1818,7 +1819,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(mod_erlang_event_runtime)
|
||||||
#else
|
#else
|
||||||
errno = 0;
|
errno = 0;
|
||||||
#endif
|
#endif
|
||||||
if ((clientfd = ei_accept_tmo(&ec, (int) listen_list.sockfd, &conn, 100)) == ERL_ERROR) {
|
if ((clientfd = ei_accept_tmo(&ec, (int) listen_list.sockfd, &conn, 500)) == ERL_ERROR) {
|
||||||
if (prefs.done) {
|
if (prefs.done) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Shutting Down\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Shutting Down\n");
|
||||||
} else if (erl_errno == ETIMEDOUT) {
|
} else if (erl_errno == ETIMEDOUT) {
|
||||||
|
|
Loading…
Reference in New Issue