Exemplo n.º 1
0
/* Incoming data from TURN-server */
static void data_handler(struct allocation *alloc, const struct sa *src,
			 struct mbuf *mb)
{
	int err;

	if (!alloc->ok) {
		re_fprintf(stderr, "allocation not ready"
			   " -- ignore %zu bytes from %J\n",
			   mbuf_get_left(mb), src);
		return;
	}

	if (!sa_cmp(src, &alloc->peer, SA_ALL)) {

		re_printf("updating peer address:  %J  -->  %J\n",
			  &alloc->peer, src);

		alloc->peer = *src;

		if (!alloc->turn_ind)
			turnc_add_chan(alloc->turnc, src, NULL, NULL);

		tmr_start(&alloc->tmr_ping, PING_INTERVAL,
			  tmr_ping_handler, alloc);
	}

	err = receiver_recv(&alloc->recv, src, mb);
	if (err) {
		re_fprintf(stderr, "corrupt packet coming from %J (%m)\n",
			   src, err);
	}
}
Exemplo n.º 2
0
static void turnc_handler(int err, uint16_t scode, const char *reason,
			  const struct sa *relay,
			  const struct sa *mapped,
			  const struct stun_msg *msg, void *arg)
{
	(void)msg;
	(void)arg;

	/* Transaction errors */
	if (err) {
		DEBUG_WARNING("TURN Client error: %m\n", err);
		turn_done();
		return;
	}

	/* STUN errors */
	if (scode) {
		DEBUG_WARNING("TURN Client error: %u %s\n", scode, reason);
		turn_done();
		return;
	}

	(void)re_fprintf(stderr, "Allocate Request: relay_addr=%J"
			 ", mapped_addr=%J\n", relay, mapped);

	if (sa_isset(turnc.peer, SA_ALL)) {
		(void)re_fprintf(stderr, "ChannelBind: %J\n", turnc.peer);

		err = turnc_add_chan(turnc.tc, turnc.peer, NULL, NULL);
		if (err) {
			DEBUG_WARNING("TURN add channel: %m\n", err);
		}
	}
}
Exemplo n.º 3
0
static void sip_recv(struct sip *sip, const struct sip_msg *msg)
{
	struct le *le = sip->lsnrl.head;

	while (le) {
		struct sip_lsnr *lsnr = le->data;

		le = le->next;

		if (msg->req != lsnr->req)
			continue;

		if (lsnr->msgh(msg, lsnr->arg))
			return;
	}

	if (msg->req) {
		(void)re_fprintf(stderr, "unhandeled request from %J: %r %r\n",
				 &msg->src, &msg->met, &msg->ruri);

		if (!pl_strcmp(&msg->met, "CANCEL"))
			(void)sip_reply(sip, msg,
					481, "Transaction Does Not Exist");
		else
			(void)sip_reply(sip, msg,
					501, "Not Implemented");
	}
	else {
		(void)re_fprintf(stderr, "unhandeled response from %J:"
				 " %u %r (%r)\n", &msg->src,
				 msg->scode, &msg->reason, &msg->cseq.met);
	}
}
Exemplo n.º 4
0
static void event_handler(int flags, void *arg)
{
	struct mqueue *mq = arg;
	struct msg msg;
	ssize_t n;

	if (!(flags & FD_READ))
		return;

	n = pipe_read(mq->pfd[0], &msg, sizeof(msg));
	if (n < 0)
		return;

	if (n != sizeof(msg)) {
		(void)re_fprintf(stderr, "mqueue: short read of %d bytes\n",
				 n);
		return;
	}

	if (msg.magic != MAGIC) {
		(void)re_fprintf(stderr, "mqueue: bad magic on read (%08x)\n",
				 msg.magic);
		return;
	}

	mq->h(msg.id, msg.data, mq->arg);
}
Exemplo n.º 5
0
/**
 * Print a message to the logging system
 *
 * @param level Log level
 * @param fmt   Formatted message
 * @param ap    Variable argument list
 */
void vlog(enum log_level level, const char *fmt, va_list ap)
{
	char buf[4096];
	struct le *le;

	if (level < lg.level)
		return;

	if (re_vsnprintf(buf, sizeof(buf), fmt, ap) < 0)
		return;

	if (lg.enable_stdout) {

		bool color = level == LEVEL_WARN || level == LEVEL_ERROR;

		if (color)
			(void)re_fprintf(stdout, "\x1b[31m"); /* Red */

		(void)re_fprintf(stdout, "%s", buf);

		if (color)
			(void)re_fprintf(stdout, "\x1b[;m");
	}

	le = lg.logl.head;

	while (le) {

		struct log *log = le->data;
		le = le->next;

		if (log->h)
			log->h(level, buf);
	}
}
Exemplo n.º 6
0
static int read_wav(kiss_fftr_cfg fft, const char *infile)
{
	struct aufile *af_in = NULL;
	struct aufile_prm prm;
	size_t sampc_in_total = 0;
	size_t i;
	int err;

	err = aufile_open(&af_in, &prm, infile, AUFILE_READ);
	if (err) {
		re_fprintf(stderr, "%s: could not open input file (%m)\n",
			   infile, err);
		goto out;
	}

	if (prm.fmt != AUFMT_S16LE) {
		err = EINVAL;
		goto out;
	}

	re_printf("%s: %u Hz, %d channels\n", infile, prm.srate, prm.channels);

	for (;;) {
		int16_t sampv[NUM_FFT];
		size_t sz = sizeof(sampv);
		kiss_fft_cpx freqv[NUM_FREQ];

		err = aufile_read(af_in, (void *)sampv, &sz);
		if (err || !sz)
			break;

		if (sz != sizeof(sampv)) {
			re_printf("skipping last %zu samples\n", sz);
			break;
		}

		sampc_in_total += (sz/2);

		/* do FFT transform */
		kiss_fftr(fft, sampv, freqv);

		for (i=0; i<ARRAY_SIZE(freqv); i++) {

			kiss_fft_cpx cpx = freqv[i];
			magv[i] += sqrt(cpx.r * cpx.r + cpx.i * cpx.i);
		}
	}

	re_printf("read %u samples\n", sampc_in_total);

 out:
	if (err) {
		re_fprintf(stderr, "file read error: %m\n", err);
	}

	mem_deref(af_in);

	return err;
}
Exemplo n.º 7
0
/* called upon incoming calls */
static void connect_handler(const struct sip_msg *msg, void *arg)
{
	struct mbuf *mb;
	bool got_offer;
	int err;
	(void)arg;

	if (sess) {
		/* Already in a call */
		(void)sip_treply(NULL, sip, msg, 486, "Busy Here");
		return;
	}

	got_offer = (mbuf_get_left(msg->mb) > 0);

	/* Decode SDP offer if incoming INVITE contains SDP */
	if (got_offer) {

		err = sdp_decode(sdp, msg->mb, true);
		if (err) {
			re_fprintf(stderr, "unable to decode SDP offer: %s\n",
				   strerror(err));
			goto out;
		}

		update_media();
	}

	/* Encode SDP */
	err = sdp_encode(&mb, sdp, !got_offer);
	if (err) {
		re_fprintf(stderr, "unable to encode SDP: %s\n",
			   strerror(err));
		goto out;
	}

	/* Answer incoming call */
	err = sipsess_accept(&sess, sess_sock, msg, 200, "OK",
			     name, "application/sdp", mb,
			     auth_handler, NULL, false,
			     offer_handler, answer_handler,
			     establish_handler, NULL, NULL,
			     close_handler, NULL, NULL);
	mem_deref(mb); /* free SDP buffer */
	if (err) {
		re_fprintf(stderr, "session accept error: %s\n",
			   strerror(err));
		goto out;
	}

 out:
	if (err) {
		(void)sip_treply(NULL, sip, msg, 500, strerror(err));
	}
	else {
		re_printf("accepting incoming call from <%r>\n",
			  &msg->from.auri);
	}
}
Exemplo n.º 8
0
static int gather_srflx2(struct candidate *cand, int proto)
{
	struct ice_lcand *base = cand->base;
	int err;

	switch (proto) {

	case IPPROTO_UDP:
		err = stun_keepalive_alloc(&cand->ska, proto,
					   base->us, LAYER_STUN,
					   &cand->stun_srv,
					   NULL,
					   stun_mapped_handler, cand);
		if (err) {
			re_printf("stun_request failed (%m)\n", err);
		}
		stun_keepalive_enable(cand->ska, 25);
		break;

	case IPPROTO_TCP:
		/* for TCP we must connect FROM the locally bound
		   socket (either passive or S-O) */

		re_printf("SRFLX tcp connecting.. %J -> %J\n",
			  &base->attr.addr, &cand->stun_srv);

		err = tcp_conn_alloc(&cand->tc, &cand->stun_srv,
				     tcp_estab_handler, tcp_recv_handler,
				     tcp_close_handler, cand);
		if (err) {
			re_fprintf(stderr, "tcp_conn_alloc failed (%m)\n",
				   err);
			return err;
		}

		err = tcp_conn_bind(cand->tc, &base->attr.addr);
		if (err) {
			re_fprintf(stderr, "tcp_conn_bind to %J failed"
				   " (%m)\n",
				   &base->attr.addr, err);
			return err;
		}

		err = tcp_conn_connect(cand->tc, &cand->stun_srv);
		if (err) {
			re_fprintf(stderr, "tcp_conn_connect to %J failed"
				   " (%m)\n",
				   err, &cand->stun_srv);
			return err;
		}

		break;

	default:
		return EPROTONOSUPPORT;
	}

	return 0;
}
Exemplo n.º 9
0
static void usage(void)
{
	(void)re_fprintf(stderr, "usage: restund [-dhn] [-f <file>]\n");
	(void)re_fprintf(stderr, "\t-d         Turn on debugging\n");
	(void)re_fprintf(stderr, "\t-h         Show summary of options\n");
	(void)re_fprintf(stderr, "\t-n         Run in foreground\n");
	(void)re_fprintf(stderr, "\t-f <file>  Configuration file\n");
}
Exemplo n.º 10
0
static void print_stats(struct audio_loop *al)
{
	double rw_ratio = 0.0;

	if (al->n_write)
		rw_ratio = 1.0 * al->n_read / al->n_write;

	(void)re_fprintf(stderr, "\r%uHz %dch "
			 " n_read=%u n_write=%u rw_ratio=%.2f",
			 al->srate, al->ch,
			 al->n_read, al->n_write, rw_ratio);

	if (str_isset(aucodec))
		(void)re_fprintf(stderr, " codec='%s'", aucodec);
}
Exemplo n.º 11
0
/* NOTE: This function should not allocate memory */
static void dbg_vprintf(int level, const char *fmt, va_list ap)
{
	if (level > dbg.level)
		return;

	/* Print handler? */
	if (dbg.ph)
		return;

	dbg_lock();

	if (dbg.flags & DBG_ANSI) {

		switch (level) {

		case DBG_WARNING:
			(void)re_fprintf(stderr, "\x1b[31m"); /* Red */
			break;

		case DBG_NOTICE:
			(void)re_fprintf(stderr, "\x1b[33m"); /* Yellow */
			break;

		case DBG_INFO:
			(void)re_fprintf(stderr, "\x1b[32m"); /* Green */
			break;

		default:
			break;
		}
	}

	if (dbg.flags & DBG_TIME) {
		const uint64_t ticks = tmr_jiffies();

		if (0 == dbg.tick)
			dbg.tick = tmr_jiffies();

		(void)re_fprintf(stderr, "[%09llu] ", ticks - dbg.tick);
	}

	(void)re_vfprintf(stderr, fmt, ap);

	if (dbg.flags & DBG_ANSI && level < DBG_DEBUG)
		(void)re_fprintf(stderr, "\x1b[;m");

	dbg_unlock();
}
Exemplo n.º 12
0
static int subscribe(struct presence *pres)
{
	const char *routev[1];
	struct ua *ua;
	char uri[256];
	int err;

	/* We use the first UA */
	ua = uag_find_aor(NULL);
	if (!ua) {
		(void)re_printf("presence: no UA found\n");
		return ENOENT;
	}

	pl_strcpy(&contact_addr(pres->contact)->auri, uri, sizeof(uri));

	routev[0] = ua_outbound(ua);

	err = sipevent_subscribe(&pres->sub, uag_sipevent_sock(), uri, NULL,
				 ua_aor(ua), "presence", NULL, 600,
				 ua_cuser(ua), routev, routev[0] ? 1 : 0,
				 auth_handler, ua_prm(ua), true, NULL,
				 notify_handler, close_handler, pres,
				 "%H", ua_print_supported, ua);
	if (err) {
		(void)re_fprintf(stderr,
				 "presence: sipevent_subscribe failed: %m\n",
				 err);
	}

	return err;
}
Exemplo n.º 13
0
/*
 * called when an SDP offer is received (got offer: true) or
 * when an offer is to be sent (got_offer: false)
 */
static int offer_handler(struct mbuf **mbp, const struct sip_msg *msg,
			 void *arg)
{
	const bool got_offer = mbuf_get_left(msg->mb);
	int err;
	(void)arg;

	if (got_offer) {

		err = sdp_decode(sdp, msg->mb, true);
		if (err) {
			re_fprintf(stderr, "unable to decode SDP offer: %s\n",
				   strerror(err));
			return err;
		}

		re_printf("SDP offer received\n");
		update_media();
	}
	else {
		re_printf("sending SDP offer\n");
	}

	return sdp_encode(mbp, sdp, !got_offer);
}
Exemplo n.º 14
0
void agent_gather(struct agent *ag)
{
	int err;

	if (!ag)
		return;

	net_if_apply(interface_handler, ag);

	re_printf("HOST gathering complete (interfaces = %u)\n",
		  ag->interfacec);

	if (is_gathering_complete(ag)) {

		re_printf("local candidate gathering completed"
			  " -- sending EOC\n");

		ag->local_eoc = true;

		err = control_send_message(ag->cli, "a=end-of-candidates\r\n");
		if (err) {
			re_fprintf(stderr, "failed to send EOC\n");
		}
	}
}
Exemplo n.º 15
0
static void stun_dns_handler(int err, const struct sa *srv, void *arg)
{
	struct candidate *cand = arg;

	if (err) {
		re_fprintf(stderr, "could not resolve STUN server (%m)\n",
			   err);
		candidate_done(cand);
		return;
	}

	switch (cand->type) {

	case TYPE_STUN:
		re_printf("resolved STUN-server (%J)\n", srv);
		cand->stun_srv = *srv;
		gather_srflx2(cand, cand->base->attr.proto);
		break;

	case TYPE_TURN:
		re_printf("resolved TURN-server (%J)\n", srv);
		cand->turn_srv = *srv;
		gather_relay2(cand, cand->turn_proto);
		break;

	default:
		re_printf("unknown type\n");
		break;
	}
}
Exemplo n.º 16
0
/* only used for STUN gathering */
static void process_stun(struct candidate *cand, struct mbuf *mb)
{
	struct stun_unknown_attr ua;
	struct stun_msg *msg;
	int err;

	err = stun_msg_decode(&msg, mb, &ua);
	if (err) {
		re_fprintf(stderr, "could not decode STUN message\n");
		return;
	}

	switch (stun_msg_class(msg)) {

	case STUN_CLASS_ERROR_RESP:
	case STUN_CLASS_SUCCESS_RESP:
		(void)stun_ctrans_recv(cand->ag->stun, msg, &ua);
		break;

	default:
		break;
	}

	mem_deref(msg);
}
TEST_F(TestMedia, verify_sha256_fingerprint_in_offer)
{
	char sdp[4096];
	struct pl pl;
	size_t i;
	int err;

	err = mediaflow_generate_offer(mf, sdp, sizeof(sdp));
	ASSERT_EQ(0, err);

	ASSERT_TRUE(find_in_sdp(sdp, "fingerprint:sha-256"));
	ASSERT_TRUE(find_in_sdp(sdp, "setup:actpass"));

	err = re_regex(sdp, strlen(sdp), "fingerprint:sha-256 [^\r\n]+", &pl);
	ASSERT_EQ(0, err);

	/* Firefox has a strict SDP parser, hex values MUST be uppercase! */
	for (i=0; i<pl.l; i++) {

		char c = pl.p[i];

		if (c == ':' ||
		    ('0' <= c && c <= '9') ||
		    ('A' <= c && c <= 'F'))
			continue;

		re_fprintf(stderr, "invalid character in fingerprint (%r)\n", &pl);
		ASSERT_TRUE(false);
	}
}
Exemplo n.º 18
0
int pcp_payload_encode(struct mbuf *mb, enum pcp_opcode opcode,
		       const union pcp_payload *pld)
{
	int err;

	if (!mb || !pld)
		return EINVAL;

	switch (opcode) {

	case PCP_MAP:
		err = pcp_map_encode(mb, &pld->map);
		break;

	case PCP_PEER:
		err = pcp_peer_encode(mb, &pld->peer);
		break;

	default:
		re_fprintf(stderr, "pcp: dont know how to encode payload"
			   " for opcode %d\n", opcode);
		err = EPROTO;
		break;
	}

	return err;
}
Exemplo n.º 19
0
static int uuid_init(const char *file)
{
	char uuid[37];
	uuid_t uu;
	FILE *f = NULL;
	int err = 0;

	f = fopen(file, "r");
	if (f) {
		err = 0;
		goto out;
	}

	f = fopen(file, "w");
	if (!f) {
		err = errno;
		DEBUG_WARNING("init: fopen() %s (%m)\n", file, err);
		goto out;
	}

	uuid_generate(uu);

	uuid_unparse(uu, uuid);

	re_fprintf(f, "%s", uuid);

	DEBUG_NOTICE("init: generated new UUID (%s)\n", uuid);

 out:
	if (f)
		fclose(f);

	return err;
}
Exemplo n.º 20
0
static void resp_handler(int err, const struct sip_msg *msg, void *arg)
{
	struct ua *ua = arg;

	(void)ua;

	if (err) {
		(void)re_fprintf(stderr, " \x1b[31m%m\x1b[;m\n", err);
		return;
	}

	if (msg->scode >= 300) {
		(void)re_fprintf(stderr, " \x1b[31m%u %r\x1b[;m\n",
				 msg->scode, &msg->reason);
	}
}
Exemplo n.º 21
0
static void tls_endpoint_estab_handler(const char *cipher, void *arg)
{
	int err;
	(void)arg;

	re_fprintf(stderr, "\r[ %u .. %c ]",
		   tlsperf.count,
		   0x20 + tlsperf.count % 0x60);

	if (tls_endpoint_established(tlsperf.ep_cli) &&
	    tls_endpoint_established(tlsperf.ep_srv)) {

		if (tlsperf.count >= tlsperf.num) {

			tlsperf.ts_estab = tmr_jiffies();

			re_printf("\nDONE!\n");
			re_printf("cipher:        %s\n", cipher);
			print_report();

			re_cancel();
		}
		else {
			stop_test();
			err = start_test();
			if (err)
				abort_test(err);
		}
	}
}
Exemplo n.º 22
0
static void tls_endpoint_error_handler(int err, void *arg)
{
	(void)arg;

	re_fprintf(stderr, "TLS Endpoint error (%m) -- ABORT\n", err);

	abort_test(err);
}
Exemplo n.º 23
0
static void usage(void)
{
	(void)re_fprintf(stderr,
			 "Usage: selftest [options]\n"
			 "options:\n"
			 "\t-v               Verbose output (INFO level)\n"
			 );
}
Exemplo n.º 24
0
static void dtls_close_handler(int err, void *arg)
{
	struct allocation *alloc = arg;

	re_fprintf(stderr, "dtls: close (%m)\n", err);

	alloc->alloch(err ? err : ECONNRESET, 0, NULL, NULL, NULL, alloc->arg);
}
Exemplo n.º 25
0
int agent_process_remote_attr(struct agent *ag,
			      const char *name, const char *value)
{
	int err = 0;

	if (!ag || !name)
		return EINVAL;

	if (0 == str_casecmp(name, "ice-ufrag")) {
		ag->rufrag = true;
		err = trice_set_remote_ufrag(ag->icem, value);
	}
	else if (0 == str_casecmp(name, "ice-pwd")) {
		ag->rpwd = true;
		err = trice_set_remote_pwd(ag->icem, value);
	}
	else if (0 == str_casecmp(name, "candidate")) {
		unsigned i;

		err = agent_rcand_decode_add(ag->icem, value);

		for (i=0; i<ag->candc; i++)
			candidate_add_permissions(&ag->candv[i]);
	}
	else if (0 == str_casecmp(name, "end-of-candidates")) {
		re_printf("got end-of-candidates from remote\n");
		ag->remote_eoc = true;
	}
	else {
		re_printf("attribute ignored: %s\n", name);
	}

	if (err) {
		re_printf("remote attr error (%m)\n", err);
		return err;
	}

	if (ag->rufrag && ag->rpwd && ag->cli->param.run_checklist
	    && !list_isempty(trice_rcandl(ag->icem))
	    && !trice_checklist_isrunning(ag->icem)) {

		re_printf("starting ICE checklist with pacing interval"
			  " %u milliseconds..\n",
			  ag->cli->param.pacing_interval);

		err = trice_checklist_start(ag->icem, NULL,
					    ag->cli->param.pacing_interval,
					    true,
					    ice_estab_handler,
					    ice_failed_handler, ag);
		if (err) {
			re_fprintf(stderr, "could not start checklist (%m)\n",
				   err);
		}
	}

	return 0;
}
Exemplo n.º 26
0
int main(void)
{
	struct sa laddr;
	int err; /* errno return values */

	/* enable coredumps to aid debugging */
	(void)sys_coredump_set(true);

	/* initialize libre state */
	err = libre_init();
	if (err) {
		re_fprintf(stderr, "re init failed: %s\n", strerror(err));
		goto out;
	}

	(void)sa_set_str(&laddr, "0.0.0.0", 3456);

	/* Create listening TCP socket, IP address 0.0.0.0, TCP port 3456 */
	err = tcp_listen(&ts, &laddr, connect_handler, NULL);
	if (err) {
		re_fprintf(stderr, "tcp listen error: %s\n", strerror(err));
		goto out;
	}

	re_printf("listening on TCP socket: %J\n", &laddr);

	/* main loop */
	err = re_main(signal_handler);

 out:
	/* destroy active TCP connections */
	list_flush(&connl);

	/* free TCP socket */
	ts = mem_deref(ts);

	/* free library state */
	libre_close();

	/* check for memory leaks */
	tmr_debug();
	mem_debug();

	return err;
}
Exemplo n.º 27
0
int allocation_create(struct allocator *allocator, unsigned ix, int proto,
		      const struct sa *srv,
		      const char *username, const char *password,
		      struct tls *tls, bool turn_ind,
		      allocation_h *alloch, void *arg)
{
	struct allocation *alloc;
	struct sa laddr;
	int err;

	if (!allocator || !proto || !srv)
		return EINVAL;

	sa_init(&laddr, sa_af(srv));

	alloc = mem_zalloc(sizeof(*alloc), destructor);
	if (!alloc)
		return ENOMEM;

	list_append(&allocator->allocl, &alloc->le, alloc);

	(void)gettimeofday(&alloc->sent, NULL);

	alloc->atime     = -1;
	alloc->ix        = ix;
	alloc->allocator = allocator;
	alloc->proto     = proto;
	alloc->secure    = tls != NULL;
	alloc->srv       = *srv;
	alloc->user      = username;
	alloc->pass      = password;
	alloc->turn_ind  = turn_ind;
	alloc->alloch    = alloch;
	alloc->arg       = arg;
	alloc->tls       = mem_ref(tls);

	receiver_init(&alloc->recv, allocator->session_cookie, alloc->ix);

	err = udp_listen(&alloc->us_tx, &laddr, NULL, NULL);
	if (err) {
		re_fprintf(stderr, "allocation: failed to create UDP tx socket"
			   " (%m)\n", err);
		goto out;
	}

	udp_local_get(alloc->us_tx, &alloc->laddr_tx);

	err = start(alloc);
	if (err)
		goto out;

 out:
	if (err)
		mem_deref(alloc);

	return err;
}
Exemplo n.º 28
0
static int generate_random_uuid(FILE *f)
{
	if (re_fprintf(f, "%08x-%04x-%04x-%04x-%08x%04x",
		       rand_u32(), rand_u16(), rand_u16(), rand_u16(),
		       rand_u32(), rand_u16()) != UUID_LEN)
		return ENOMEM;

	return 0;
}
Exemplo n.º 29
0
static void print_stats(struct audio_loop *al)
{
	(void)re_fprintf(stderr, "\r%uHz %dch frame_size=%u"
			 " n_read=%u n_write=%u"
			 " aubuf=%5u codec=%s",
			 al->srate, al->ch, al->fs,
			 al->n_read, al->n_write,
			 aubuf_cur_size(al->ab), aucodec);
}
Exemplo n.º 30
0
int allocator_start_senders(struct allocator *allocator, unsigned bitrate,
			    size_t psize)
{
	struct le *le;
	double tbps = allocator->num_allocations * bitrate;
	unsigned ptime;
	int err = 0;

	ptime = calculate_ptime(bitrate, psize);

	re_printf("starting traffic generators:"
		  " psize=%zu, ptime=%u (total target bitrate is %H)\n",
		  psize, ptime, print_bitrate, &tbps);

	tmr_start(&allocator->tmr_ui, 1, tmr_ui_handler, allocator);

	for (le = allocator->allocl.head; le; le = le->next) {
		struct allocation *alloc = le->data;

		if (alloc->sender) {
			re_fprintf(stderr, "sender already started\n");
			return EALREADY;
		}

		err = sender_alloc(&alloc->sender, alloc,
				   allocator->session_cookie,
				   alloc->ix, bitrate, ptime, psize);
		if (err)
			return err;

		err = sender_start(alloc->sender);
		if (err) {
			re_fprintf(stderr, "could not start sender (%m)", err);
			return err;
		}
	}

	/* start sending timer/thread */
	tmr_start(&allocator->tmr_pace, PACING_INTERVAL_MS,
		  tmr_pace_handler, allocator);

	return 0;
}