コード例 #1
0
ファイル: dtls.c プロジェクト: cahlbin/rtpengine
static int verify_callback(int ok, X509_STORE_CTX *store) {
	SSL *ssl;
	struct stream_fd *sfd;
	struct packet_stream *ps;
	struct call_media *media;

	ssl = X509_STORE_CTX_get_ex_data(store, SSL_get_ex_data_X509_STORE_CTX_idx());
	sfd = SSL_get_app_data(ssl);
	if (sfd->dtls.ssl != ssl)
		return 0;
	ps = sfd->stream;
	if (!ps)
		return 0;
	if (PS_ISSET(ps, FINGERPRINT_VERIFIED))
		return 1;
	media = ps->media;
	if (!media)
		return 0;

	if (ps->dtls_cert)
		X509_free(ps->dtls_cert);
	ps->dtls_cert = X509_dup(X509_STORE_CTX_get_current_cert(store));

	if (!media->fingerprint.hash_func)
		return 1; /* delay verification */

	if (dtls_verify_cert(ps))
		return 0;
	return 1;
}
コード例 #2
0
ファイル: call_interfaces.c プロジェクト: arpagon/rtpengine
static void ng_stats_stream(bencode_item_t *list, const struct packet_stream *ps,
		struct call_stats *totals)
{
	bencode_item_t *dict = NULL, *flags;
	struct stats *s;

	if (!list)
		goto stats;

	dict = bencode_list_add_dictionary(list);

	if (ps->sfd)
		bencode_dictionary_add_integer(dict, "local port", ps->sfd->fd.localport);
	ng_stats_endpoint(bencode_dictionary_add_dictionary(dict, "endpoint"), &ps->endpoint);
	ng_stats_endpoint(bencode_dictionary_add_dictionary(dict, "advertised endpoint"),
			&ps->advertised_endpoint);
	if (ps->crypto.params.crypto_suite)
		bencode_dictionary_add_string(dict, "crypto suite",
				ps->crypto.params.crypto_suite->name);
	bencode_dictionary_add_integer(dict, "last packet", ps->last_packet);

	flags = bencode_dictionary_add_list(dict, "flags");

	BF_PS("RTP", RTP);
	BF_PS("RTCP", RTCP);
	BF_PS("fallback RTCP", FALLBACK_RTCP);
	BF_PS("filled", FILLED);
	BF_PS("confirmed", CONFIRMED);
	BF_PS("kernelized", KERNELIZED);
	BF_PS("no kernel support", NO_KERNEL_SUPPORT);
	BF_PS("DTLS fingerprint verified", FINGERPRINT_VERIFIED);
	BF_PS("strict source address", STRICT_SOURCE);
	BF_PS("media handover", MEDIA_HANDOVER);

stats:
	if (totals->last_packet < ps->last_packet)
		totals->last_packet = ps->last_packet;

	/* XXX distinguish between input and output */
	s = &totals->totals[0];
	if (!PS_ISSET(ps, RTP))
		s = &totals->totals[1];
	ng_stats(bencode_dictionary_add_dictionary(dict, "stats"), &ps->stats, s);
}
コード例 #3
0
ファイル: dtls.c プロジェクト: cahlbin/rtpengine
/* called with call locked in W or R with ps->in_lock held */
int dtls(struct packet_stream *ps, const str *s, struct sockaddr_in6 *fsin) {
	struct dtls_connection *d;
	int ret;
	unsigned char buf[0x10000], ctrl[256];
	struct msghdr mh;
	struct iovec iov;
	struct sockaddr_in6 sin;

	if (!ps || !ps->sfd)
		return 0;
	if (!MEDIA_ISSET(ps->media, DTLS))
		return 0;

	d = &ps->sfd->dtls;

	if (s)
		__DBG("dtls packet input: len %u %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
			s->len,
			(unsigned char) s->s[0], (unsigned char) s->s[1], (unsigned char) s->s[2], (unsigned char) s->s[3],
			(unsigned char) s->s[4], (unsigned char) s->s[5], (unsigned char) s->s[6], (unsigned char) s->s[7],
			(unsigned char) s->s[8], (unsigned char) s->s[9], (unsigned char) s->s[10], (unsigned char) s->s[11],
			(unsigned char) s->s[12], (unsigned char) s->s[13], (unsigned char) s->s[14], (unsigned char) s->s[15]);

	if (d->connected)
		return 0;

	if (!d->init || !d->ssl)
		return -1;

	if (s) {
		BIO_write(d->r_bio, s->s, s->len);
		/* we understand this as preference of DTLS over SDES */
		MEDIA_CLEAR(ps->media, SDES);
	}

	ret = try_connect(d);
	if (ret == -1) {
		ilog(LOG_ERROR, "DTLS error on local port %hu", ps->sfd->fd.localport);
		/* fatal error */
		dtls_connection_cleanup(d);
		return 0;
	}
	else if (ret == 1) {
		/* connected! */
		if (dtls_setup_crypto(ps, d))
			/* XXX ?? */ ;
		if (PS_ISSET(ps, RTP) && PS_ISSET(ps, RTCP) && ps->rtcp_sibling
				&& MEDIA_ISSET(ps->media, RTCP_MUX))
		{
			if (dtls_setup_crypto(ps->rtcp_sibling, d))
				/* XXX ?? */ ;
		}
	}

	ret = BIO_ctrl_pending(d->w_bio);
	if (ret <= 0)
		return 0;

	if (ret > sizeof(buf)) {
		ilog(LOG_ERROR, "BIO buffer overflow");
		(void) BIO_reset(d->w_bio);
		return 0;
	}

	ret = BIO_read(d->w_bio, buf, ret);
	if (ret <= 0)
		return 0;

	__DBG("dtls packet output: len %u %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
		ret,
		buf[0], buf[1], buf[2], buf[3],
		buf[4], buf[5], buf[6], buf[7],
		buf[8], buf[9], buf[10], buf[11],
		buf[12], buf[13], buf[14], buf[15]);

	if (!fsin) {
		ZERO(sin);
		sin.sin6_family = AF_INET6;
		sin.sin6_addr = ps->endpoint.ip46;
		sin.sin6_port = htons(ps->endpoint.port);
		fsin = &sin;
	}

	ZERO(mh);
	mh.msg_control = ctrl;
	mh.msg_controllen = sizeof(ctrl);
	mh.msg_name = fsin;
	mh.msg_namelen = sizeof(*fsin);
	mh.msg_iov = &iov;
	mh.msg_iovlen = 1;

	ZERO(iov);
	iov.iov_base = buf;
	iov.iov_len = ret;

	stream_msg_mh_src(ps, &mh);

	sendmsg(ps->sfd->fd.fd, &mh, 0);

	return 0;
}