static void do_unload(void) { switch_hash_index_t *hi = NULL; switch_mutex_lock(MUTEX); while ((hi = switch_core_hash_first( globals.translate_profiles))) { void *val = NULL; const void *key; switch_ssize_t keylen; translate_rule_t *rl, *nrl; switch_core_hash_this(hi, &key, &keylen, &val); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "deleting translate profile [%s]\n", (char *) key); for (nrl = val; rl;) { rl = nrl; nrl = nrl->next; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "deleting rule for [%s]\n", rl->regex); switch_safe_free(rl->regex); switch_safe_free(rl->replace); switch_safe_free(rl); } switch_core_hash_delete_wrlock(globals.translate_profiles, key, globals.profile_hash_rwlock); } switch_thread_rwlock_destroy(globals.profile_hash_rwlock); switch_core_hash_destroy(&globals.translate_profiles); switch_mutex_unlock(MUTEX); }
/** * Stop input CPA */ void rayo_cpa_component_shutdown(void) { switch_event_unbind_callback(on_rayo_cpa_detector_event); switch_event_unbind_callback(on_channel_hangup_complete_event); rayo_cpa_detector_shutdown(); switch_core_hash_destroy(&globals.subscribers); }
/** * Shutdown output component * @return SWITCH_STATUS_SUCCESS if successful */ switch_status_t rayo_output_component_shutdown(void) { if (fileman_globals.hash) { switch_core_hash_destroy(&fileman_globals.hash); } return SWITCH_STATUS_SUCCESS; }
static switch_status_t config_logger(void) { char *cf = "console.conf"; switch_xml_t cfg, xml, settings, param; if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf); return SWITCH_STATUS_TERM; } if (log_hash) { switch_core_hash_destroy(&log_hash); } switch_core_hash_init(&log_hash, module_pool); if ((settings = switch_xml_child(cfg, "mappings"))) { for (param = switch_xml_child(settings, "param"); param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); char *val = (char *) switch_xml_attr_soft(param, "value"); add_mapping(var, val, 1); } for (param = switch_xml_child(settings, "map"); param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); char *val = (char *) switch_xml_attr_soft(param, "value"); add_mapping(var, val, 0); } } if ((settings = switch_xml_child(cfg, "settings"))) { for (param = switch_xml_child(settings, "param"); param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); char *val = (char *) switch_xml_attr_soft(param, "value"); if (!strcasecmp(var, "colorize") && switch_true(val)) { #ifdef WIN32 hStdout = GetStdHandle(STD_OUTPUT_HANDLE); if (switch_core_get_console() == stdout && hStdout != INVALID_HANDLE_VALUE && GetConsoleScreenBufferInfo(hStdout, &csbiInfo)) { wOldColorAttrs = csbiInfo.wAttributes; COLORIZE = 1; } #else COLORIZE = 1; #endif } else if (!strcasecmp(var, "loglevel") && !zstr(val)) { hard_log_level = switch_log_str2level(val); } else if (!strcasecmp(var, "uuid") && switch_true(val)) { log_uuid = SWITCH_TRUE; } } } switch_xml_free(xml); return SWITCH_STATUS_SUCCESS; }
static void cleanup_profile(void *ptr) { logfile_profile_t *profile = (logfile_profile_t *) ptr; switch_core_hash_destroy(&profile->log_hash); switch_file_close(profile->log_afd); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Closing %s\n", profile->logfile); switch_safe_free(profile->logfile); }
/** * Stop all CPA detectors */ static void stop_cpa_detectors(struct cpa_component *cpa) { if (cpa->signals) { switch_hash_index_t *hi = NULL; for (hi = switch_core_hash_first(cpa->signals); hi; hi = switch_core_hash_next(hi)) { const void *signal_type; void *cpa_signal = NULL; switch_core_hash_this(hi, &signal_type, NULL, &cpa_signal); if (cpa_signal) { rayo_cpa_detector_stop(RAYO_COMPONENT(cpa)->parent->id, ((struct cpa_signal *)cpa_signal)->name); unsubscribe(RAYO_COMPONENT(cpa)->parent->id, ((struct cpa_signal *)cpa_signal)->name, RAYO_JID(cpa)); } } switch_core_hash_destroy(&cpa->signals); cpa->signals = NULL; } unsubscribe(RAYO_COMPONENT(cpa)->parent->id, "hangup", RAYO_JID(cpa)); }
void switch_load_timezones(switch_bool_t reload) { switch_xml_t xml = NULL, x_lists = NULL, x_list = NULL, cfg = NULL; unsigned total = 0; if (TIMEZONES_LIST.hash) { switch_core_hash_destroy(&TIMEZONES_LIST.hash); } if (TIMEZONES_LIST.pool) { switch_core_destroy_memory_pool(&TIMEZONES_LIST.pool); } memset(&TIMEZONES_LIST, 0, sizeof(TIMEZONES_LIST)); switch_core_new_memory_pool(&TIMEZONES_LIST.pool); switch_core_hash_init(&TIMEZONES_LIST.hash, TIMEZONES_LIST.pool); if ((xml = switch_xml_open_cfg("timezones.conf", &cfg, NULL))) { if ((x_lists = switch_xml_child(cfg, "timezones"))) { for (x_list = switch_xml_child(x_lists, "zone"); x_list; x_list = x_list->next) { const char *name = switch_xml_attr(x_list, "name"); const char *value = switch_xml_attr(x_list, "value"); if (zstr(name)) { continue; } if (zstr(value)) { continue; } switch_core_hash_insert(TIMEZONES_LIST.hash, name, switch_core_strdup(TIMEZONES_LIST.pool, value)); total++; } } switch_xml_free(xml); } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Timezone %sloaded %d definitions\n", reload ? "re" : "", total); }
/** * Stop receiving signals */ static void unsubscribe(const char *uuid, const char *signal_type, const char *jid) { char *key = switch_mprintf("%s:%s", uuid, signal_type); switch_mutex_lock(globals.subscribers_mutex); { switch_hash_t *signal_subscribers = switch_core_hash_find(globals.subscribers, key); if (signal_subscribers) { switch_core_hash_delete(signal_subscribers, jid); switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Unsubscribe %s => %s\n", signal_type, jid); /* clean up hash if empty */ if (!switch_core_hash_first(signal_subscribers)) { switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Destroy %s subscriber hash\n", signal_type); switch_core_hash_destroy(&signal_subscribers); switch_core_hash_delete(globals.subscribers, key); } } } switch_mutex_unlock(globals.subscribers_mutex); switch_safe_free(key); }
static switch_status_t do_config(void) { char *cf = "xml_scgi.conf"; switch_xml_t cfg, xml, bindings_tag, binding_tag, param; xml_binding_t *binding = NULL; int x = 0; int need_vars_map = 0; switch_hash_t *vars_map = NULL; if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf); return SWITCH_STATUS_TERM; } if (!(bindings_tag = switch_xml_child(cfg, "bindings"))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing <bindings> tag!\n"); goto done; } for (binding_tag = switch_xml_child(bindings_tag, "binding"); binding_tag; binding_tag = binding_tag->next) { char *bname = (char *) switch_xml_attr_soft(binding_tag, "name"); char *host = "127.0.0.1"; char *port = "8080"; char *bind_mask = NULL; int timeout = 0; char *server = NULL; hash_node_t *hash_node; need_vars_map = 0; vars_map = NULL; for (param = switch_xml_child(binding_tag, "param"); param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); char *val = (char *) switch_xml_attr_soft(param, "value"); if (!strcasecmp(var, "host")) { bind_mask = (char *) switch_xml_attr_soft(param, "bindings"); if (val) { host = val; } } else if (!strcasecmp(var, "port")) { port = val; } else if (!strcasecmp(var, "timeout")) { int tmp = atoi(val); if (tmp >= 0) { timeout = tmp; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't set a negative timeout!\n"); } } else if (!strcasecmp(var, "enable-post-var")) { if (!vars_map && need_vars_map == 0) { if (switch_core_hash_init(&vars_map, globals.pool) != SWITCH_STATUS_SUCCESS) { need_vars_map = -1; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't init params hash!\n"); continue; } need_vars_map = 1; } if (vars_map && val) { if (switch_core_hash_insert(vars_map, val, ENABLE_PARAM_VALUE) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't add %s to params hash!\n", val); } } } else if (!strcasecmp(var, "server")) { server = val; } } if (!host) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Binding has no host!\n"); if (vars_map) { switch_core_hash_destroy(&vars_map); } continue; } if (!(binding = switch_core_alloc(globals.pool, sizeof(*binding)))) { if (vars_map) { switch_core_hash_destroy(&vars_map); } goto done; } memset(binding, 0, sizeof(*binding)); binding->timeout = timeout; binding->host = switch_core_strdup(globals.pool, host); binding->port = atoi(port); binding->vars_map = vars_map; binding->uri = switch_mprintf("/%s", bname); binding->url = switch_mprintf("scgi://%s:%s/%s", host, port, bname); if (server) { binding->server = switch_core_strdup(globals.pool, server); } if (bind_mask) { binding->bindings = switch_core_strdup(globals.pool, bind_mask); } if (vars_map) { switch_zmalloc(hash_node, sizeof(hash_node_t)); hash_node->hash = vars_map; hash_node->next = NULL; if (!globals.hash_root) { globals.hash_root = hash_node; globals.hash_tail = globals.hash_root; } else { globals.hash_tail->next = hash_node; globals.hash_tail = globals.hash_tail->next; } } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Binding [%s] XML Fetch Function [%s] [%s]\n", zstr(bname) ? "N/A" : bname, binding->url, binding->bindings ? binding->bindings : "all"); switch_xml_bind_search_function(xml_url_fetch, switch_xml_parse_section_string(binding->bindings), binding); if (binding->server) { launch_monitor_thread(binding); } binding->next = globals.bindings; globals.bindings = binding; x++; binding = NULL; } done: switch_xml_free(xml); return x ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; }
static switch_status_t do_config(void) { char *cf = "xml_curl.conf"; switch_xml_t cfg, xml, bindings_tag, binding_tag, param; xml_binding_t *binding = NULL; int x = 0; int need_vars_map = 0; switch_hash_t *vars_map = NULL; if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf); return SWITCH_STATUS_TERM; } if (!(bindings_tag = switch_xml_child(cfg, "bindings"))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing <bindings> tag!\n"); goto done; } for (binding_tag = switch_xml_child(bindings_tag, "binding"); binding_tag; binding_tag = binding_tag->next) { char *bname = (char *) switch_xml_attr_soft(binding_tag, "name"); char *url = NULL; char *bind_cred = NULL; char *bind_mask = NULL; char *method = NULL; int disable100continue = 1; int use_dynamic_url = 0, timeout = 0; uint32_t enable_cacert_check = 0; char *ssl_cert_file = NULL; char *ssl_key_file = NULL; char *ssl_key_password = NULL; char *ssl_version = NULL; char *ssl_cacert_file = NULL; uint32_t enable_ssl_verifyhost = 0; char *cookie_file = NULL; hash_node_t *hash_node; int auth_scheme = CURLAUTH_BASIC; need_vars_map = 0; vars_map = NULL; for (param = switch_xml_child(binding_tag, "param"); param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); char *val = (char *) switch_xml_attr_soft(param, "value"); if (!strcasecmp(var, "gateway-url")) { bind_mask = (char *) switch_xml_attr_soft(param, "bindings"); if (val) { url = val; } } else if (!strcasecmp(var, "gateway-credentials")) { bind_cred = val; } else if (!strcasecmp(var, "auth-scheme")) { if (*val == '=') { auth_scheme = 0; val++; } if (!strcasecmp(val, "basic")) { auth_scheme |= CURLAUTH_BASIC; } else if (!strcasecmp(val, "digest")) { auth_scheme |= CURLAUTH_DIGEST; } else if (!strcasecmp(val, "NTLM")) { auth_scheme |= CURLAUTH_NTLM; } else if (!strcasecmp(val, "GSS-NEGOTIATE")) { auth_scheme |= CURLAUTH_GSSNEGOTIATE; } else if (!strcasecmp(val, "any")) { auth_scheme = CURLAUTH_ANY; } } else if (!strcasecmp(var, "disable-100-continue") && !switch_true(val)) { disable100continue = 0; } else if (!strcasecmp(var, "method")) { method = val; } else if (!strcasecmp(var, "timeout")) { int tmp = atoi(val); if (tmp >= 0) { timeout = tmp; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't set a negative timeout!\n"); } } else if (!strcasecmp(var, "enable-cacert-check") && switch_true(val)) { enable_cacert_check = 1; } else if (!strcasecmp(var, "ssl-cert-path")) { ssl_cert_file = val; } else if (!strcasecmp(var, "ssl-key-path")) { ssl_key_file = val; } else if (!strcasecmp(var, "ssl-key-password")) { ssl_key_password = val; } else if (!strcasecmp(var, "ssl-version")) { ssl_version = val; } else if (!strcasecmp(var, "ssl-cacert-file")) { ssl_cacert_file = val; } else if (!strcasecmp(var, "enable-ssl-verifyhost") && switch_true(val)) { enable_ssl_verifyhost = 1; } else if (!strcasecmp(var, "cookie-file")) { cookie_file = val; } else if (!strcasecmp(var, "use-dynamic-url") && switch_true(val)) { use_dynamic_url = 1; } else if (!strcasecmp(var, "enable-post-var")) { if (!vars_map && need_vars_map == 0) { if (switch_core_hash_init(&vars_map, globals.pool) != SWITCH_STATUS_SUCCESS) { need_vars_map = -1; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't init params hash!\n"); continue; } need_vars_map = 1; } if (vars_map && val) if (switch_core_hash_insert(vars_map, val, ENABLE_PARAM_VALUE) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't add %s to params hash!\n", val); } } } if (!url) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Binding has no url!\n"); if (vars_map) switch_core_hash_destroy(&vars_map); continue; } if (!(binding = malloc(sizeof(*binding)))) { if (vars_map) switch_core_hash_destroy(&vars_map); goto done; } memset(binding, 0, sizeof(*binding)); binding->auth_scheme = auth_scheme; binding->timeout = timeout; binding->url = strdup(url); switch_assert(binding->url); if (method != NULL) { binding->method = strdup(method); } else { binding->method = NULL; } if (bind_mask) { binding->bindings = strdup(bind_mask); } if (bind_cred) { binding->cred = strdup(bind_cred); } binding->disable100continue = disable100continue; binding->use_get_style = method != NULL && strcasecmp(method, "post") != 0; binding->use_dynamic_url = use_dynamic_url; binding->enable_cacert_check = enable_cacert_check; if (ssl_cert_file) { binding->ssl_cert_file = strdup(ssl_cert_file); } if (ssl_key_file) { binding->ssl_key_file = strdup(ssl_key_file); } if (ssl_key_password) { binding->ssl_key_password = strdup(ssl_key_password); } if (ssl_version) { binding->ssl_version = strdup(ssl_version); } if (ssl_cacert_file) { binding->ssl_cacert_file = strdup(ssl_cacert_file); } binding->enable_ssl_verifyhost = enable_ssl_verifyhost; if (cookie_file) { binding->cookie_file = strdup(cookie_file); } binding->vars_map = vars_map; if (vars_map) { switch_zmalloc(hash_node, sizeof(hash_node_t)); hash_node->hash = vars_map; hash_node->next = NULL; if (!globals.hash_root) { globals.hash_root = hash_node; globals.hash_tail = globals.hash_root; } else { globals.hash_tail->next = hash_node; globals.hash_tail = globals.hash_tail->next; } } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Binding [%s] XML Fetch Function [%s] [%s]\n", zstr(bname) ? "N/A" : bname, binding->url, binding->bindings ? binding->bindings : "all"); switch_xml_bind_search_function(xml_url_fetch, switch_xml_parse_section_string(binding->bindings), binding); x++; binding = NULL; } done: switch_xml_free(xml); return x ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; }
static switch_status_t handle_msg_atom(listener_t *listener, erlang_msg * msg, ei_x_buff * buf, ei_x_buff * rbuf) { char atom[MAXATOMLEN]; switch_status_t ret = SWITCH_STATUS_SUCCESS; if (ei_decode_atom(buf->buff, &buf->index, atom)) { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "badarg"); } else if (!strncmp(atom, "nolog", MAXATOMLEN)) { if (switch_test_flag(listener, LFLAG_LOG)) { void *pop; /*purge the log queue */ while (switch_queue_trypop(listener->log_queue, &pop) == SWITCH_STATUS_SUCCESS); switch_clear_flag_locked(listener, LFLAG_LOG); } ei_x_encode_atom(rbuf, "ok"); } else if (!strncmp(atom, "register_log_handler", MAXATOMLEN)) { ei_link(listener, ei_self(listener->ec), &msg->from); listener->log_process.type = ERLANG_PID; memcpy(&listener->log_process.pid, &msg->from, sizeof(erlang_pid)); listener->level = SWITCH_LOG_DEBUG; switch_set_flag(listener, LFLAG_LOG); ei_x_encode_atom(rbuf, "ok"); } else if (!strncmp(atom, "register_event_handler", MAXATOMLEN)) { ei_link(listener, ei_self(listener->ec), &msg->from); listener->event_process.type = ERLANG_PID; memcpy(&listener->event_process.pid, &msg->from, sizeof(erlang_pid)); if (!switch_test_flag(listener, LFLAG_EVENTS)) { switch_set_flag_locked(listener, LFLAG_EVENTS); } ei_x_encode_atom(rbuf, "ok"); } else if (!strncmp(atom, "noevents", MAXATOMLEN)) { void *pop; /*purge the event queue */ while (switch_queue_trypop(listener->event_queue, &pop) == SWITCH_STATUS_SUCCESS); if (switch_test_flag(listener, LFLAG_EVENTS)) { uint8_t x = 0; switch_clear_flag_locked(listener, LFLAG_EVENTS); for (x = 0; x <= SWITCH_EVENT_ALL; x++) { listener->event_list[x] = 0; } /* wipe the hash */ switch_core_hash_destroy(&listener->event_hash); switch_core_hash_init(&listener->event_hash, listener->pool); ei_x_encode_atom(rbuf, "ok"); } else { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "notlistening"); } } else if (!strncmp(atom, "session_noevents", MAXATOMLEN)) { session_elem_t *session; if ((session = find_session_elem_by_pid(listener, &msg->from))) { void *pop; uint8_t x = 0; /*purge the event queue */ while (switch_queue_trypop(session->event_queue, &pop) == SWITCH_STATUS_SUCCESS); for (x = 0; x <= SWITCH_EVENT_ALL; x++) { session->event_list[x] = 0; } /* wipe the hash */ switch_core_hash_destroy(&session->event_hash); switch_core_hash_init(&session->event_hash, session->pool); ei_x_encode_atom(rbuf, "ok"); } else { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "notlistening"); } } else if (!strncmp(atom, "exit", MAXATOMLEN)) { ei_x_encode_atom(rbuf, "ok"); ret = SWITCH_STATUS_TERM; } else if (!strncmp(atom, "getpid", MAXATOMLEN)) { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "ok"); ei_x_encode_pid(rbuf, ei_self(listener->ec)); } else if (!strncmp(atom, "link", MAXATOMLEN)) { /* debugging */ ei_link(listener, ei_self(listener->ec), &msg->from); ret = SWITCH_STATUS_FALSE; } else { ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "undef"); } return ret; }
static void event_handler(switch_event_t *event) { uint8_t send = 0; if (globals.running != 1) { return; } if (event->subclass_name && (!strcmp(event->subclass_name, MULTICAST_EVENT) || !strcmp(event->subclass_name, MULTICAST_PEERUP) || !strcmp(event->subclass_name, MULTICAST_PEERDOWN))) { char *event_name, *sender; if ((event_name = switch_event_get_header(event, "orig-event-name")) && !strcasecmp(event_name, "HEARTBEAT") && (sender = switch_event_get_header(event, "orig-multicast-sender"))) { struct peer_status *p; time_t now = switch_epoch_time_now(NULL); if (!(p = switch_core_hash_find(globals.peer_hash, sender))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Host %s not already in hash\n", sender); p = switch_core_alloc(module_pool, sizeof(struct peer_status)); p->active = SWITCH_FALSE; p->lastseen = 0; /*} else { */ /*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Host %s last seen %d seconds ago\n", sender, now - p->lastseen); */ } if (!p->active) { switch_event_t *local_event; if (switch_event_create_subclass(&local_event, SWITCH_EVENT_CUSTOM, MULTICAST_PEERUP) == SWITCH_STATUS_SUCCESS) { char lastseen[21]; switch_event_add_header_string(local_event, SWITCH_STACK_BOTTOM, "Peer", sender); if (p->lastseen) { switch_snprintf(lastseen, sizeof(lastseen), "%d", (int) p->lastseen); } else { switch_snprintf(lastseen, sizeof(lastseen), "%s", "Never"); } switch_event_add_header_string(local_event, SWITCH_STACK_BOTTOM, "Lastseen", lastseen); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Peer %s has come up; last seen: %s\n", sender, lastseen); switch_event_fire(&local_event); } } p->active = SWITCH_TRUE; p->lastseen = now; switch_core_hash_insert(globals.peer_hash, sender, p); } /* ignore our own events to avoid ping pong */ return; } if (event->event_id == SWITCH_EVENT_RELOADXML) { switch_mutex_lock(globals.mutex); switch_core_hash_destroy(&globals.event_hash); globals.event_hash = NULL; if (globals.psk) { switch_safe_free(globals.psk); globals.psk = NULL; } switch_core_hash_init(&globals.event_hash, module_pool); memset(globals.event_list, 0, SWITCH_EVENT_ALL + 1); if (load_config() != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to reload config file\n"); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Event Multicast Reloaded\n"); } switch_mutex_unlock(globals.mutex); } if (event->event_id == SWITCH_EVENT_HEARTBEAT) { switch_hash_index_t *cur; switch_ssize_t keylen; const void *key; void *value; time_t now = switch_epoch_time_now(NULL); struct peer_status *last; char *host; for (cur = switch_hash_first(NULL, globals.peer_hash); cur; cur = switch_hash_next(cur)) { switch_hash_this(cur, &key, &keylen, &value); host = (char *) key; last = (struct peer_status *) value; if (last->active && (now - (last->lastseen)) > 60) { switch_event_t *local_event; last->active = SWITCH_FALSE; if (switch_event_create_subclass(&local_event, SWITCH_EVENT_CUSTOM, MULTICAST_PEERDOWN) == SWITCH_STATUS_SUCCESS) { char lastseen[21]; switch_event_add_header_string(local_event, SWITCH_STACK_BOTTOM, "Peer", host); switch_snprintf(lastseen, sizeof(lastseen), "%d", (int) last->lastseen); switch_event_add_header_string(local_event, SWITCH_STACK_BOTTOM, "Lastseen", lastseen); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Peer %s has gone down; last seen: %s\n", host, lastseen); switch_event_fire(&local_event); } } } } switch_mutex_lock(globals.mutex); if (globals.event_list[(uint8_t) SWITCH_EVENT_ALL]) { send = 1; } else if ((globals.event_list[(uint8_t) event->event_id])) { if (event->event_id != SWITCH_EVENT_CUSTOM || (event->subclass_name && switch_core_hash_find(globals.event_hash, event->subclass_name))) { send = 1; } } switch_mutex_unlock(globals.mutex); if (send) { char *packet; switch (event->event_id) { case SWITCH_EVENT_LOG: return; default: switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Multicast-Sender", switch_core_get_switchname()); if (switch_event_serialize(event, &packet, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) { size_t len; char *buf; #ifdef HAVE_OPENSSL int outlen, tmplen; EVP_CIPHER_CTX ctx; char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; switch_uuid_t uuid; switch_uuid_get(&uuid); switch_uuid_format(uuid_str, &uuid); len = strlen(packet) + SWITCH_UUID_FORMATTED_LENGTH + EVP_MAX_IV_LENGTH + strlen((char *) MAGIC); #else len = strlen(packet) + strlen((char *) MAGIC); #endif buf = malloc(len + 1); memset(buf, 0, len + 1); switch_assert(buf); #ifdef HAVE_OPENSSL if (globals.psk) { switch_copy_string(buf, uuid_str, SWITCH_UUID_FORMATTED_LENGTH); EVP_CIPHER_CTX_init(&ctx); EVP_EncryptInit(&ctx, EVP_bf_cbc(), NULL, NULL); EVP_CIPHER_CTX_set_key_length(&ctx, strlen(globals.psk)); EVP_EncryptInit(&ctx, NULL, (unsigned char *) globals.psk, (unsigned char *) uuid_str); EVP_EncryptUpdate(&ctx, (unsigned char *) buf + SWITCH_UUID_FORMATTED_LENGTH, &outlen, (unsigned char *) packet, (int) strlen(packet)); EVP_EncryptUpdate(&ctx, (unsigned char *) buf + SWITCH_UUID_FORMATTED_LENGTH + outlen, &tmplen, (unsigned char *) MAGIC, (int) strlen((char *) MAGIC)); outlen += tmplen; EVP_EncryptFinal(&ctx, (unsigned char *) buf + SWITCH_UUID_FORMATTED_LENGTH + outlen, &tmplen); outlen += tmplen; len = (size_t) outlen + SWITCH_UUID_FORMATTED_LENGTH; *(buf + SWITCH_UUID_FORMATTED_LENGTH + outlen) = '\0'; } else { #endif switch_copy_string(buf, packet, len); switch_copy_string(buf + strlen(packet), (char *) MAGIC, strlen((char *) MAGIC) + 1); #ifdef HAVE_OPENSSL } #endif switch_socket_sendto(globals.udp_socket, globals.addr, 0, buf, &len); switch_safe_free(packet); switch_safe_free(buf); } break; } } return; }
static switch_status_t handle_msg_session_setevent(listener_t *listener, erlang_msg *msg, int arity, ei_x_buff * buf, ei_x_buff * rbuf) { char atom[MAXATOMLEN]; if (arity == 1){ ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "badarg"); } else { session_elem_t *session; if ((session = find_session_elem_by_pid(listener, &msg->from))) { uint8_t event_list[SWITCH_EVENT_ALL + 1]; switch_hash_t *event_hash; int custom = 0; int i = 0; switch_event_types_t type; uint32_t x = 0; /* clear any previous event registrations */ for (x = 0; x <= SWITCH_EVENT_ALL; x++){ event_list[x] = 0; } /* create new hash */ switch_core_hash_init(&event_hash, session->pool); for (i = 1; i < arity; i++){ if (!ei_decode_atom(buf->buff, &buf->index, atom)) { if (custom) { switch_core_hash_insert(event_hash, atom, MARKER); } else if (switch_name_event(atom, &type) == SWITCH_STATUS_SUCCESS) { if (type == SWITCH_EVENT_ALL) { ei_x_encode_tuple_header(rbuf, 1); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "badarg"); break; } if (type <= SWITCH_EVENT_ALL) { event_list[type] = 1; } if (type == SWITCH_EVENT_CUSTOM) { custom++; } } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "enable event %s for session %s\n", atom, session->uuid_str); } } /* update the event subscriptions with the new ones */ switch_thread_rwlock_wrlock(session->event_rwlock); memcpy(session->event_list, event_list, sizeof(uint8_t) * (SWITCH_EVENT_ALL + 1)); /* wipe the old hash, and point the pointer at the new one */ switch_core_hash_destroy(&session->event_hash); session->event_hash = event_hash; switch_thread_rwlock_unlock(session->event_rwlock); /* TODO - we should flush any non-matching events from the queue */ ei_x_encode_atom(rbuf, "ok"); } else { /* no session for this pid */ ei_x_encode_tuple_header(rbuf, 2); ei_x_encode_atom(rbuf, "error"); ei_x_encode_atom(rbuf, "notlistening"); } } return SWITCH_STATUS_SUCCESS; }