Exemple #1
0
static void send_timer_run(void *ptr) {
	struct send_timer *st = ptr;
	struct call *call = st->call;

	log_info_call(call);

	ilog(LOG_DEBUG, "running scheduled send_timer");

	struct timeval next_send = {0,};

	rwlock_lock_r(&call->master_lock);
	mutex_lock(&st->lock);

	while (st->packets.length) {
		struct codec_packet *cp = st->packets.head->data;
		// XXX this could be made lock-free
		if (!send_timer_send(st, cp)) {
			g_queue_pop_head(&st->packets);
			continue;
		}
		// couldn't send the last one. remember time to schedule
		next_send = cp->to_send;
		break;
	}

	mutex_unlock(&st->lock);
	rwlock_unlock_r(&call->master_lock);

	if (next_send.tv_sec)
		timerthread_obj_schedule_abs(&st->tt_obj, &next_send);

	log_info_clear();
}
Exemple #2
0
void ice_thread_run(void *p) {
	struct ice_agent *ag;
	struct call *call;
	long long sleeptime;
	struct timeval tv;

	mutex_lock(&ice_agents_timers_lock);

	while (!g_shutdown) {
		gettimeofday(&g_now, NULL);

		/* lock our list and get the first element */
		ag = g_tree_find_first(ice_agents_timers, NULL, NULL);
		/* scheduled to run? if not, we just go to sleep, otherwise we remove it from the tree,
		 * steal the reference and run it */
		if (!ag)
			goto sleep;
		if (timeval_cmp(&g_now, &ag->next_check) < 0)
			goto sleep;

		g_tree_remove(ice_agents_timers, ag);
		ZERO(ag->next_check);
		ag->last_run = g_now;
		mutex_unlock(&ice_agents_timers_lock);

		/* this agent is scheduled to run right now */

		/* lock the call */
		call = ag->call;
		log_info_ice_agent(ag);
		rwlock_lock_r(&call->master_lock);

		/* and run our checks */
		__do_ice_checks(ag);

		/* finally, release our reference and start over */
		log_info_clear();
		rwlock_unlock_r(&call->master_lock);
		obj_put(ag);
		mutex_lock(&ice_agents_timers_lock);
		continue;

sleep:
		/* figure out how long we should sleep */
		sleeptime = ag ? timeval_diff(&ag->next_check, &g_now) : 100000;
		sleeptime = MIN(100000, sleeptime); /* 100 ms at the most */
		tv = g_now;
		timeval_add_usec(&tv, sleeptime);
		cond_timedwait(&ice_agents_timers_cond, &ice_agents_timers_lock, &tv);
		continue;
	}

	mutex_unlock(&ice_agents_timers_lock);
}
Exemple #3
0
static int control_stream_parse(struct control_stream *s, char *line) {
	int ovec[60];
	int ret;
	char **out;
	struct control_tcp *c = s->control;
	str *output = NULL;

	ret = pcre_exec(c->parse_re, c->parse_ree, line, strlen(line), 0, 0, ovec, G_N_ELEMENTS(ovec));
	if (ret <= 0) {
		ilog(LOG_WARNING, "Unable to parse command line from " DF ": %s", DP(s->inaddr), line);
		return -1;
	}

	ilog(LOG_INFO, "Got valid command from " DF ": %s", DP(s->inaddr), line);

	pcre_get_substring_list(line, ovec, ret, (const char ***) &out);


	if (out[RE_TCP_RL_CALLID])
		log_info_c_string(out[RE_TCP_RL_CALLID]);
	else if (out[RE_TCP_D_CALLID])
		log_info_c_string(out[RE_TCP_D_CALLID]);


	if (!strcmp(out[RE_TCP_RL_CMD], "request"))
		output = call_request_tcp(out, c->callmaster);
	else if (!strcmp(out[RE_TCP_RL_CMD], "lookup"))
		output = call_lookup_tcp(out, c->callmaster);
	else if (!strcmp(out[RE_TCP_D_CMD], "delete"))
		call_delete_tcp(out, c->callmaster);
	else if (!strcmp(out[RE_TCP_DIV_CMD], "status"))
		calls_status_tcp(c->callmaster, s);
	else if (!strcmp(out[RE_TCP_DIV_CMD], "build") | !strcmp(out[RE_TCP_DIV_CMD], "version"))
		control_stream_printf(s, "Version: %s\n", RTPENGINE_VERSION);
	else if (!strcmp(out[RE_TCP_DIV_CMD], "controls"))
		control_list(c, s);
	else if (!strcmp(out[RE_TCP_DIV_CMD], "quit") || !strcmp(out[RE_TCP_DIV_CMD], "exit"))
		;

	if (output) {
		mutex_lock(&s->lock);
		streambuf_write_str(s->outbuf, output);
		mutex_unlock(&s->lock);
		free(output);
	}

	pcre_free(out);
	log_info_clear();
	return -1;
}
Exemple #4
0
static void media_player_run(void *ptr) {
	struct media_player *mp = ptr;
	struct call *call = mp->call;

	log_info_call(call);

	ilog(LOG_DEBUG, "running scheduled media_player");

	rwlock_lock_r(&call->master_lock);
	mutex_lock(&mp->lock);

	media_player_read_packet(mp);

	mutex_unlock(&mp->lock);
	rwlock_unlock_r(&call->master_lock);

	log_info_clear();
}
Exemple #5
0
static void control_udp_incoming(struct obj *obj, str *buf, const endpoint_t *sin, char *addr,
		struct udp_listener *ul) {
	struct control_udp *u = (void *) obj;
	int ret;
	int ovec[100];
	char **out;
	struct iovec iov[10];
	unsigned int iovlen;
	str cookie, *reply;

	ret = pcre_exec(u->parse_re, u->parse_ree, buf->s, buf->len, 0, 0, ovec, G_N_ELEMENTS(ovec));
	if (ret <= 0) {
		ret = pcre_exec(u->fallback_re, NULL, buf->s, buf->len, 0, 0, ovec, G_N_ELEMENTS(ovec));
		if (ret <= 0) {
			ilog(LOG_WARNING, "Unable to parse command line from udp:%s: %.*s", addr, STR_FMT(buf));
			return;
		}

		ilog(LOG_WARNING, "Failed to properly parse UDP command line '%.*s' from %s, using fallback RE", STR_FMT(buf), addr);

		pcre_get_substring_list(buf->s, ovec, ret, (const char ***) &out);

		iov[0].iov_base = (void *) out[RE_UDP_COOKIE];
		iov[0].iov_len = strlen(out[RE_UDP_COOKIE]);
		if (out[RE_UDP_UL_CMD] && (chrtoupper(out[RE_UDP_UL_CMD][0]) == 'U' || chrtoupper(out[RE_UDP_UL_CMD][0]) == 'L')) {
			iov[1].iov_base = (void *) out[4];
			iov[1].iov_len = strlen(out[4]);
			iov[2].iov_base = (void *) out[3];
			iov[2].iov_len = strlen(out[3]);
			iov[3].iov_base = "\n";
			iov[3].iov_len = 1;
			iovlen = 4;
		}
		else {
			iov[1].iov_base = " E8\n";
			iov[1].iov_len = 4;
			iovlen = 2;
		}

		socket_sendiov(&ul->sock, iov, iovlen, sin);

		pcre_free(out);

		return;
	}

	ilog(LOG_INFO, "Got valid command from udp:%s: %.*s", addr, STR_FMT(buf));

	pcre_get_substring_list(buf->s, ovec, ret, (const char ***) &out);

	str_init(&cookie, (void *) out[RE_UDP_COOKIE]);
	reply = cookie_cache_lookup(&u->cookie_cache, &cookie);
	if (reply) {
		ilog(LOG_INFO, "Detected command from udp:%s as a duplicate", addr);
		socket_sendto(&ul->sock, reply->s, reply->len, sin);
		free(reply);
		goto out;
	}

	if (out[RE_UDP_UL_CALLID])
		log_info_c_string(out[RE_UDP_UL_CALLID]);
	else if (out[RE_UDP_DQ_CALLID])
		log_info_c_string(out[RE_UDP_DQ_CALLID]);

	if (chrtoupper(out[RE_UDP_UL_CMD][0]) == 'U')
		reply = call_update_udp(out, u->callmaster, addr, sin);
	else if (chrtoupper(out[RE_UDP_UL_CMD][0]) == 'L')
		reply = call_lookup_udp(out, u->callmaster);
	else if (chrtoupper(out[RE_UDP_DQ_CMD][0]) == 'D')
		reply = call_delete_udp(out, u->callmaster);
	else if (chrtoupper(out[RE_UDP_DQ_CMD][0]) == 'Q')
		reply = call_query_udp(out, u->callmaster);
	else if (chrtoupper(out[RE_UDP_V_CMD][0]) == 'V') {
		iovlen = 2;

		iov[0].iov_base = (void *) out[RE_UDP_COOKIE];
		iov[0].iov_len = strlen(out[RE_UDP_COOKIE]);
		iov[1].iov_base = " ";
		iov[1].iov_len = 1;

		if (chrtoupper(out[RE_UDP_V_FLAGS][0]) == 'F') {
			ret = 0;
			if (!strcmp(out[RE_UDP_V_PARMS], "20040107"))
				ret = 1;
			else if (!strcmp(out[RE_UDP_V_PARMS], "20050322"))
				ret = 1;
			else if (!strcmp(out[RE_UDP_V_PARMS], "20060704"))
				ret = 1;
			iov[2].iov_base = ret ? "1\n" : "0\n";
			iov[2].iov_len = 2;
			iovlen++;
		}
		else {
			iov[2].iov_base = "20040107\n";
			iov[2].iov_len = 9;
			iovlen++;
		}
		socket_sendiov(&ul->sock, iov, iovlen, sin);
	}

	if (reply) {
		socket_sendto(&ul->sock, reply->s, reply->len, sin);
		cookie_cache_insert(&u->cookie_cache, &cookie, reply);
		free(reply);
	}
	else
		cookie_cache_remove(&u->cookie_cache, &cookie);

out:
	pcre_free(out);
	log_info_clear();
}