Пример #1
0
static int setup_dtls_srtp(struct ast_sip_session *session,
	struct ast_sip_session_media *session_media)
{
	struct ast_rtp_engine_dtls *dtls;

	if (!session->endpoint->media.rtp.dtls_cfg.enabled || !session_media->rtp) {
		return -1;
	}

	dtls = ast_rtp_instance_get_dtls(session_media->rtp);
	if (!dtls) {
		return -1;
	}

	session->endpoint->media.rtp.dtls_cfg.suite = ((session->endpoint->media.rtp.srtp_tag_32) ? AST_AES_CM_128_HMAC_SHA1_32 : AST_AES_CM_128_HMAC_SHA1_80);
	if (dtls->set_configuration(session_media->rtp, &session->endpoint->media.rtp.dtls_cfg)) {
		ast_log(LOG_ERROR, "Attempted to set an invalid DTLS-SRTP configuration on RTP instance '%p'\n",
			session_media->rtp);
		return -1;
	}

	if (setup_srtp(session_media)) {
		return -1;
	}
	return 0;
}
Пример #2
0
static int setup_sdes_srtp(struct ast_sip_session_media *session_media,
	const struct pjmedia_sdp_media *stream)
{
	int i;

	for (i = 0; i < stream->attr_count; i++) {
		pjmedia_sdp_attr *attr;
		RAII_VAR(char *, crypto_str, NULL, ast_free);

		/* check the stream for the required crypto attribute */
		attr = stream->attr[i];
		if (pj_strcmp2(&attr->name, "crypto")) {
			continue;
		}

		crypto_str = ast_strndup(attr->value.ptr, attr->value.slen);
		if (!crypto_str) {
			return -1;
		}

		if (setup_srtp(session_media)) {
			return -1;
		}

		if (!ast_sdp_crypto_process(session_media->rtp, session_media->srtp, crypto_str)) {
			/* found a valid crypto attribute */
			return 0;
		}

		ast_debug(1, "Ignoring crypto offer with unsupported parameters: %s\n", crypto_str);
	}

	/* no usable crypto attributes found */
	return -1;
}
Пример #3
0
static int alloc(struct menc_media **stp, struct menc_sess *sess,
		 struct rtp_sock *rtp,
		 int proto, void *rtpsock, void *rtcpsock,
		 struct sdp_media *sdpm)
{
	struct menc_st *st;
	const char *rattr = NULL;
	int layer = 10; /* above zero */
	int err = 0;
	bool mux = (rtpsock == rtcpsock);
	(void)sess;
	(void)rtp;

	if (!stp || !sdpm)
		return EINVAL;
	if (proto != IPPROTO_UDP)
		return EPROTONOSUPPORT;

	st = (struct menc_st *)*stp;
	if (!st) {

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

		st->sdpm = mem_ref(sdpm);

		err = sdp_media_set_alt_protos(st->sdpm, 4,
					       "RTP/AVP",
					       "RTP/AVPF",
					       "RTP/SAVP",
					       "RTP/SAVPF");
		if (err)
			goto out;

		if (rtpsock) {
			st->rtpsock = mem_ref(rtpsock);
			err |= udp_register_helper(&st->uh_rtp, rtpsock,
						   layer, send_handler,
						   recv_handler, st);
		}
		if (rtcpsock && !mux) {
			st->rtcpsock = mem_ref(rtcpsock);
			err |= udp_register_helper(&st->uh_rtcp, rtcpsock,
						   layer, send_handler,
						   recv_handler, st);
		}
		if (err)
			goto out;

		/* set our preferred crypto-suite */
		err |= str_dup(&st->crypto_suite, aes_cm_128_hmac_sha1_80);
		if (err)
			goto out;

		err = setup_srtp(st);
		if (err)
			goto out;
	}

	/* SDP handling */

	if (sdp_media_rattr(st->sdpm, "crypto")) {

		rattr = sdp_media_rattr_apply(st->sdpm, "crypto",
					      sdp_attr_handler, st);
		if (!rattr) {
			DEBUG_WARNING("no valid a=crypto attribute from"
				      " remote peer\n");
		}
	}

	if (!rattr)
		err = sdp_enc(st, sdpm, 0, st->crypto_suite);

 out:
	if (err)
		mem_deref(st);
	else
		*stp = (struct menc_media *)st;

	return err;
}