예제 #1
0
static void *SWITCH_THREAD_FUNC limit_remote_thread(switch_thread_t *thread, void *obj)
{
	limit_remote_t *remote = (limit_remote_t*)obj;
	while (remote->state > REMOTE_OFF) {
		if (remote->state != REMOTE_UP) {
			if  (esl_connect_timeout(&remote->handle, remote->host, remote->port, remote->username, remote->password, 5000) == ESL_SUCCESS) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Connected to remote FreeSWITCH (%s) at %s:%d\n",
					remote->name, remote->host, remote->port);
				
				remote->state = REMOTE_UP;
			} else {
				esl_disconnect(&remote->handle);
				memset(&remote->handle, 0, sizeof(remote->handle));
			}
		} else {
			if (esl_send_recv_timed(&remote->handle, "api hash_dump limit", 5000) != ESL_SUCCESS) {
				esl_disconnect(&remote->handle);
				memset(&remote->handle, 0, sizeof(remote->handle));
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Disconnected from remote FreeSWITCH (%s) at %s:%d\n",
					remote->name, remote->host, remote->port);
				memset(&remote->handle, 0, sizeof(remote->handle));
				remote->state = REMOTE_DOWN;
				/* Delete all remote tracking entries */
				switch_thread_rwlock_wrlock(remote->rwlock);
				switch_core_hash_delete_multi(remote->index, limit_hash_remote_cleanup_callback, NULL);
				switch_thread_rwlock_unlock(remote->rwlock);
			} else {
				if (!zstr(remote->handle.last_sr_event->body)) {
					char *data = strdup(remote->handle.last_sr_event->body);
					char *p = data, *p2;
					switch_time_t now = switch_epoch_time_now(NULL);
					while (p && *p) {
						/* We are getting the limit data as:
							L/key/usage/rate/interval/last_checked 
						*/
						if ((p2 = strchr(p, '\n'))) {
							*p2++ = '\0';
						}
						
						/* Now p points at the beginning of the current line, 
						p2 at the start of the next one */
						if (*p == 'L') { /* Limit data */
							char *argv[5]; 
							int argc = switch_split(p+2, '/', argv);
							
							if (argc < 5) {
								switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "[%s] Protocol error: missing argument in line: %s\n", 
									remote->name, p);
							} else {
								limit_hash_item_t *item;
								switch_thread_rwlock_wrlock(remote->rwlock);
								if (!(item = switch_core_hash_find(remote->index, argv[0]))) {
									item = malloc(sizeof(*item));
									switch_core_hash_insert(remote->index, argv[0], item);
								}
								item->total_usage = atoi(argv[1]);
								item->rate_usage = atoi(argv[2]);
								item->interval = atoi(argv[3]);
								item->last_check = atoi(argv[4]);
								item->last_update = now;
								switch_thread_rwlock_unlock(remote->rwlock);
							}
						}
						
						p = p2;
					}
					free(data);
					
					/* Now free up anything that wasn't in this update since it means their usage is 0 */
					switch_thread_rwlock_wrlock(remote->rwlock);
					switch_core_hash_delete_multi(remote->index, limit_hash_remote_cleanup_callback, (void*)(intptr_t)now);
					switch_thread_rwlock_unlock(remote->rwlock);
				}
			}
		}
		
		switch_yield(remote->interval * 1000);
	}
	
	remote->thread = NULL;
	
	return NULL;
}
예제 #2
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);

			switch_thread_rwlock_wrlock(listener->event_rwlock);
			for (x = 0; x <= SWITCH_EVENT_ALL; x++) {
				listener->event_list[x] = 0;
			}

			switch_core_hash_delete_multi(listener->event_hash, NULL, NULL);

			switch_thread_rwlock_unlock(listener->event_rwlock);
			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);

			switch_thread_rwlock_wrlock(session->event_rwlock);
			for (x = 0; x <= SWITCH_EVENT_ALL; x++) {
				session->event_list[x] = 0;
			}
			/* wipe the hash */
			switch_core_hash_delete_multi(session->event_hash, NULL, NULL);
			switch_thread_rwlock_unlock(session->event_rwlock);

			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;
}