Example #1
0
static bool recv_handler(struct sa *src, struct mbuf *mb, void *arg)
{
	struct menc_st *st = arg;
	err_status_t e;
	int len;
	(void)src;

	if (!st->use_srtp || !is_rtp_or_rtcp(mb))
		return false;

	len = (int)mbuf_get_left(mb);

	if (is_rtcp_packet(mb)) {
		e = srtp_unprotect_rtcp(st->srtp_rx, mbuf_buf(mb), &len);
	}
	else {
		e = srtp_unprotect(st->srtp_rx, mbuf_buf(mb), &len);
	}

	if (e != err_status_ok) {
		DEBUG_WARNING("recv: failed to unprotect %s-packet"
			      " with %d bytes (%H)\n",
			      is_rtcp_packet(mb) ? "RTCP" : "RTP",
			      len, errstatus_print, e);
		return true;   /* error - drop packet */
	}

	mbuf_set_end(mb, mb->pos + len);

	return false;  /* continue processing */
}
Example #2
0
static bool raw_handler(int proto, const struct sa *src,
			const struct sa *dst, struct mbuf *mb)
{
	struct allocation *al;
	uint16_t numb, len;
	struct perm *perm;
	struct chan *chan;
	int err;

	al = allocation_find(proto, src, dst);
	if (!al)
		return false;

	if (mbuf_get_left(mb) < 4)
		return false;

	numb = ntohs(mbuf_read_u16(mb));
	len  = ntohs(mbuf_read_u16(mb));

	if (mbuf_get_left(mb) < len)
		return false;


    // strip any optional padding
    if (len != mbuf_get_left(mb))
        mbuf_set_end(mb, mb->pos + len);

	chan = chan_numb_find(al->chans, numb);
	if (!chan)
		return false;

	perm = perm_find(al->perms, chan_peer(chan));
	if (!perm) {
		++al->dropc_tx;
		return false;
	}

	err = udp_send(al->rel_us, chan_peer(chan), mb);
	if (err)
		turnd.errc_tx++;
	else {
		const size_t bytes = mbuf_get_left(mb);

		perm_tx_stat(perm, bytes);
		turnd.bytec_tx += bytes;
	}

	return true;
}
Example #3
0
static bool send_handler(int *err, struct sa *dst, struct mbuf *mb, void *arg)
{
	struct menc_st *st = arg;
	err_status_t e;
	int len;
	(void)dst;

	if (!st->use_srtp || !is_rtp_or_rtcp(mb))
		return false;

	len = (int)mbuf_get_left(mb);

	if (mbuf_get_space(mb) < ((size_t)len + SRTP_MAX_TRAILER_LEN)) {
		mbuf_resize(mb, mb->pos + len + SRTP_MAX_TRAILER_LEN);
	}

	if (is_rtcp_packet(mb)) {
		e = srtp_protect_rtcp(st->srtp_tx, mbuf_buf(mb), &len);
	}
	else {
		e = srtp_protect(st->srtp_tx, mbuf_buf(mb), &len);
	}

	if (err_status_ok != e) {
		DEBUG_WARNING("send: failed to protect %s-packet"
			      " with %d bytes (%H)\n",
			      is_rtcp_packet(mb) ? "RTCP" : "RTP",
			      len, errstatus_print, e);
		*err = EPROTO;
		return false;
	}

	mbuf_set_end(mb, mb->pos + len);

	return false;  /* continue processing */
}
Example #4
0
int encode(struct videnc_state *st, bool update, const struct vidframe *frame)
{
	int i, err, ret;
	int pix_fmt;

	if (!st || !frame)
		return EINVAL;

	switch (frame->fmt) {

	case VID_FMT_YUV420P:
		pix_fmt = AV_PIX_FMT_YUV420P;
		break;

	case VID_FMT_NV12:
		pix_fmt = AV_PIX_FMT_NV12;
		break;

	default:
		warning("avcodec: pixel format not supported (%s)\n",
			vidfmt_name(frame->fmt));
		return ENOTSUP;
	}

	if (!st->ctx || !vidsz_cmp(&st->encsize, &frame->size)) {

		err = open_encoder(st, &st->encprm, &frame->size, pix_fmt);
		if (err) {
			warning("avcodec: open_encoder: %m\n", err);
			return err;
		}
	}

	for (i=0; i<4; i++) {
		st->pict->data[i]     = frame->data[i];
		st->pict->linesize[i] = frame->linesize[i];
	}
	st->pict->pts = st->pts++;
	if (update) {
		debug("avcodec: encoder picture update\n");
		st->pict->key_frame = 1;
#ifdef FF_I_TYPE
		st->pict->pict_type = FF_I_TYPE;  /* Infra Frame */
#else
		st->pict->pict_type = AV_PICTURE_TYPE_I;
#endif
	}
	else {
		st->pict->key_frame = 0;
		st->pict->pict_type = 0;
	}

	mbuf_rewind(st->mb);

#if LIBAVCODEC_VERSION_INT >= ((54<<16)+(1<<8)+0)
	do {
		AVPacket avpkt;
		int got_packet;

		av_init_packet(&avpkt);

		avpkt.data = st->mb->buf;
		avpkt.size = (int)st->mb->size;

		ret = avcodec_encode_video2(st->ctx, &avpkt,
					    st->pict, &got_packet);
		if (ret < 0)
			return EBADMSG;
		if (!got_packet)
			return 0;

		mbuf_set_end(st->mb, avpkt.size);

	} while (0);
#else
	ret = avcodec_encode_video(st->ctx, st->mb->buf,
				   (int)st->mb->size, st->pict);
	if (ret < 0 )
		return EBADMSG;

	/* todo: figure out proper buffer size */
	if (ret > (int)st->sz_max) {
		debug("avcodec: grow encode buffer %u --> %d\n",
		      st->sz_max, ret);
		st->sz_max = ret;
	}

	mbuf_set_end(st->mb, ret);
#endif

	switch (st->codec_id) {

	case AV_CODEC_ID_H263:
		err = h263_packetize(st, st->mb, st->pkth, st->arg);
		break;

	case AV_CODEC_ID_H264:
		err = h264_packetize(st->mb->buf, st->mb->end,
				     st->encprm.pktsize,
				     st->pkth, st->arg);
		break;

	case AV_CODEC_ID_MPEG4:
		err = general_packetize(st->mb, st->encprm.pktsize,
					st->pkth, st->arg);
		break;

	default:
		err = EPROTO;
		break;
	}

	return err;
}
Example #5
0
static int enc(struct vidcodec_st *st, bool update,
	       const struct vidframe *frame)
{
	int i, err, ret;

	if (!st->enc.ctx || !vidsz_cmp(&st->encsize, &frame->size)) {

		err = open_encoder(st, &st->encprm, &frame->size);
		if (err) {
			DEBUG_WARNING("open_encoder: %m\n", err);
			return err;
		}
	}

	for (i=0; i<4; i++) {
		st->enc.pict->data[i]     = frame->data[i];
		st->enc.pict->linesize[i] = frame->linesize[i];
	}
	st->enc.pict->pts = st->pts++;
	if (update) {
		re_printf("avcodec encoder picture update\n");
		st->enc.pict->key_frame = 1;
#ifdef FF_I_TYPE
		st->enc.pict->pict_type = FF_I_TYPE;  /* Infra Frame */
#else
		st->enc.pict->pict_type = AV_PICTURE_TYPE_I;
#endif
	}
	else {
		st->enc.pict->key_frame = 0;
		st->enc.pict->pict_type = 0;
	}

	mbuf_rewind(st->enc.mb);

#if LIBAVCODEC_VERSION_INT >= ((54<<16)+(1<<8)+0)
	do {
		AVPacket avpkt;
		int got_packet;

		avpkt.data = st->enc.mb->buf;
		avpkt.size = (int)st->enc.mb->size;

		ret = avcodec_encode_video2(st->enc.ctx, &avpkt,
					    st->enc.pict, &got_packet);
		if (ret < 0)
			return EBADMSG;
		if (!got_packet)
			return 0;

		mbuf_set_end(st->enc.mb, avpkt.size);

	} while (0);
#else
	ret = avcodec_encode_video(st->enc.ctx, st->enc.mb->buf,
				   (int)st->enc.mb->size, st->enc.pict);
	if (ret < 0 )
		return EBADMSG;

	/* todo: figure out proper buffer size */
	if (ret > (int)st->enc.sz_max) {
		re_printf("note: grow encode buffer %u --> %d\n",
			  st->enc.sz_max, ret);
		st->enc.sz_max = ret;
	}

	mbuf_set_end(st->enc.mb, ret);
#endif

	switch (st->codec_id) {

	case CODEC_ID_H263:
		err = h263_packetize(st, st->enc.mb);
		break;

	case CODEC_ID_H264:
		err = h264_packetize(st, st->enc.mb);
		break;

	case CODEC_ID_MPEG4:
		err = general_packetize(st, st->enc.mb);
		break;

	default:
		err = EPROTO;
		break;
	}

	return err;
}
Example #6
0
static bool recv_handler(int *err, struct mbuf *mb, bool *estab, void *arg)
{
	struct tls_conn *tc = arg;
	int r;

	/* feed SSL data to the BIO */
	r = BIO_write(tc->sbio_in, mbuf_buf(mb), (int)mbuf_get_left(mb));
	if (r <= 0) {
		DEBUG_WARNING("recv: BIO_write %d\n", r);
		*err = ENOMEM;
		return true;
	}

	if (SSL_state(tc->ssl) != SSL_ST_OK) {

		if (tc->up) {
			*err = EPROTO;
			return true;
		}

		if (tc->active) {
			*err = tls_connect(tc);
		}
		else {
			*err = tls_accept(tc);
		}

		DEBUG_INFO("state=0x%04x\n", SSL_state(tc->ssl));

		/* TLS connection is established */
		if (SSL_state(tc->ssl) != SSL_ST_OK)
			return true;

		*estab = true;
		tc->up = true;
	}

	mbuf_set_pos(mb, 0);

	for (;;) {
		int n;

		if (mbuf_get_space(mb) < 4096) {
			*err = mbuf_resize(mb, mb->size + 8192);
			if (*err)
				return true;
		}

		n = SSL_read(tc->ssl, mbuf_buf(mb), (int)mbuf_get_space(mb));
		if (n < 0) {
			const int ssl_err = SSL_get_error(tc->ssl, n);

			switch (ssl_err) {

			case SSL_ERROR_WANT_READ:
				break;

			default:
				*err = EPROTO;
				return true;
			}

			break;
		}
		else if (n == 0)
			break;

		mb->pos += n;
	}

	mbuf_set_end(mb, mb->pos);
	mbuf_set_pos(mb, 0);

	return false;
}
Example #7
0
static bool recv_handler(struct sa *src, struct mbuf *mb, void *arg)
{
	struct tls_sock *ts = arg;
	struct tls_conn *tc;
	int r;

	tc = tls_udp_conn(ts, src);
	if (!tc) {

		/* No connection found, assuming Server role */

		tc = conn_alloc(ts, src);
		if (!tc)
			return true;

		SSL_set_verify(tc->ssl, 0, 0);
		SSL_set_accept_state(tc->ssl);
	}

	/* feed SSL data to the BIO */
	r = BIO_write(tc->sbio_in, mbuf_buf(mb), (int)mbuf_get_left(mb));
	if (r <= 0)
		return true;

	check_timer(tc);

	mbuf_set_pos(mb, 0);

	for (;;) {
		int n;

		if (mbuf_get_space(mb) < 4096) {
			if (mbuf_resize(mb, mb->size + 8192))
				return true;
		}

		n = SSL_read(tc->ssl, mbuf_buf(mb), (int)mbuf_get_space(mb));
		if (n < 0) {
			const int ssl_err = SSL_get_error(tc->ssl, n);

			switch (ssl_err) {

			case SSL_ERROR_WANT_READ:
				break;

			default:
				return true;
			}

			break;
		}
		else if (n == 0)
			break;

		mb->pos += n;
	}

	if (!mb->pos)
		return true;

	mbuf_set_end(mb, mb->pos);
	mbuf_set_pos(mb, 0);

	return false;
}