Exemple #1
0
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;
}
Exemple #5
0
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));
}
Exemple #7
0
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;
}
Exemple #11
0
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;
}
Exemple #13
0
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;
}