示例#1
0
static int replace_network_address(struct sdp_chopper *chop, struct network_address *address,
		struct packet_stream *ps, struct sdp_ng_flags *flags)
{
	char buf[64];
	int len;
	struct packet_stream *sink = packet_stream_sink(ps);

	if (is_addr_unspecified(&address->parsed)
			&& !(sink && is_trickle_ice_address(&sink->advertised_endpoint)))
		return 0;

	if (copy_up_to(chop, &address->address_type))
		return -1;

	if (flags->media_address.s && is_addr_unspecified(&flags->parsed_media_address))
		__parse_address(&flags->parsed_media_address, NULL, NULL, &flags->media_address);

	if (!is_addr_unspecified(&flags->parsed_media_address)) {
		if (IN6_IS_ADDR_V4MAPPED(&flags->parsed_media_address))
			len = sprintf(buf, "IP4 " IPF, IPP(flags->parsed_media_address.s6_addr32[3]));
		else {
			memcpy(buf, "IP6 ", 4);
			inet_ntop(AF_INET6, &flags->parsed_media_address, buf + 4, sizeof(buf)-4);
			len = strlen(buf);
		}
	}
	else
		call_stream_address(buf, ps, SAF_NG, &len);
	chopper_append_dup(chop, buf, len);

	if (skip_over(chop, &address->address))
		return -1;

	return 0;
}
示例#2
0
文件: sdp.c 项目: gnufreex/rtpengine
static int replace_network_address(struct sdp_chopper *chop, struct network_address *address,
		struct packet_stream *ps, struct sdp_ng_flags *flags)
{
	char buf[64];
	int len;
	struct packet_stream *sink = packet_stream_sink(ps);

	if (is_addr_unspecified(&address->parsed)
			&& !(sink && is_trickle_ice_address(&sink->advertised_endpoint)))
		return 0;

	if (copy_up_to(chop, &address->address_type))
		return -1;

	if (flags->media_address.s && is_addr_unspecified(&flags->parsed_media_address))
		__parse_address(&flags->parsed_media_address, NULL, NULL, &flags->media_address);

	if (!is_addr_unspecified(&flags->parsed_media_address))
		len = sprintf(buf, "%s %s",
				flags->parsed_media_address.family->rfc_name,
				sockaddr_print_buf(&flags->parsed_media_address));
	else
		call_stream_address46(buf, ps, SAF_NG, &len, NULL);
	chopper_append_dup(chop, buf, len);

	if (skip_over(chop, &address->address))
		return -1;

	return 0;
}
示例#3
0
static void __sdp_ice(struct stream_params *sp, struct sdp_media *media) {
	struct sdp_attribute *attr;
	struct attribute_candidate *ac;
	struct ice_candidate *cand;
	GQueue *q;
	GList *ql;

	attr = attr_get_by_id_m_s(media, ATTR_ICE_UFRAG);
	if (!attr)
		return;
	sp->ice_ufrag = attr->value;

	SP_SET(sp, ICE);

	q = attr_list_get_by_id(&media->attributes, ATTR_CANDIDATE);
	if (!q)
		goto no_cand;

	for (ql = q->head; ql; ql = ql->next) {
		attr = ql->data;
		ac = &attr->u.candidate;
		if (!ac->parsed)
			continue;
		cand = g_slice_alloc(sizeof(*cand));
		*cand = ac->cand_parsed;
		g_queue_push_tail(&sp->ice_candidates, cand);
	}

no_cand:
	if ((attr = attr_get_by_id(&media->attributes, ATTR_ICE_OPTIONS))) {
		if (str_str(&attr->value, "trickle") >= 0)
			SP_SET(sp, TRICKLE_ICE);
	}
	else if (is_trickle_ice_address(&sp->rtp_endpoint))
		SP_SET(sp, TRICKLE_ICE);

	if (attr_get_by_id(&media->attributes, ATTR_ICE_LITE))
		SP_SET(sp, ICE_LITE);

	attr = attr_get_by_id_m_s(media, ATTR_ICE_PWD);
	if (attr)
		sp->ice_pwd = attr->value;
}
示例#4
0
/* XXX split this function up */
int sdp_streams(const GQueue *sessions, GQueue *streams, struct sdp_ng_flags *flags) {
	struct sdp_session *session;
	struct sdp_media *media;
	struct stream_params *sp;
	GList *l, *k;
	const char *errstr;
	int num;
	struct sdp_attribute *attr;

	num = 0;
	for (l = sessions->head; l; l = l->next) {
		session = l->data;

		for (k = session->media_streams.head; k; k = k->next) {
			media = k->data;

			sp = g_slice_alloc0(sizeof(*sp));
			sp->index = ++num;

			errstr = "No address info found for stream";
			if (fill_endpoint(&sp->rtp_endpoint, media, flags, NULL, media->port_num))
				goto error;

			sp->consecutive_ports = media->port_count;
			sp->protocol = transport_protocol(&media->transport);
			sp->type = media->media_type;
			memcpy(sp->direction, flags->direction, sizeof(sp->direction));
			sp->desired_family = flags->address_family;
			bf_set_clear(&sp->sp_flags, SP_FLAG_ASYMMETRIC, flags->asymmetric);
			bf_set_clear(&sp->sp_flags, SP_FLAG_STRICT_SOURCE, flags->strict_source);
			bf_set_clear(&sp->sp_flags, SP_FLAG_MEDIA_HANDOVER, flags->media_handover);

			errstr = "Invalid RTP payload types";
			if (__rtp_payload_types(sp, media))
				goto error;

			/* a=crypto */
			attr = attr_get_by_id(&media->attributes, ATTR_CRYPTO);
			if (attr) {
				sp->crypto.crypto_suite = attr->u.crypto.crypto_suite;
				sp->crypto.mki_len = attr->u.crypto.mki_len;
				if (sp->crypto.mki_len) {
					sp->crypto.mki = malloc(sp->crypto.mki_len);
					memcpy(sp->crypto.mki, attr->u.crypto.mki, sp->crypto.mki_len);
				}
				sp->sdes_tag = attr->u.crypto.tag;
				assert(sizeof(sp->crypto.master_key) >= attr->u.crypto.master_key.len);
				assert(sizeof(sp->crypto.master_salt) >= attr->u.crypto.salt.len);
				memcpy(sp->crypto.master_key, attr->u.crypto.master_key.s,
						attr->u.crypto.master_key.len);
				memcpy(sp->crypto.master_salt, attr->u.crypto.salt.s,
						attr->u.crypto.salt.len);
				sp->crypto.session_params.unencrypted_srtp = attr->u.crypto.unencrypted_srtp;
				sp->crypto.session_params.unencrypted_srtcp = attr->u.crypto.unencrypted_srtcp;
				sp->crypto.session_params.unauthenticated_srtp = attr->u.crypto.unauthenticated_srtp;
			}

			/* a=sendrecv/sendonly/recvonly/inactive */
			SP_SET(sp, SEND);
			SP_SET(sp, RECV);
			if (attr_get_by_id_m_s(media, ATTR_RECVONLY))
				SP_CLEAR(sp, SEND);
			else if (attr_get_by_id_m_s(media, ATTR_SENDONLY))
				SP_CLEAR(sp, RECV);
			else if (attr_get_by_id_m_s(media, ATTR_INACTIVE))
			{
				SP_CLEAR(sp, RECV);
				SP_CLEAR(sp, SEND);
			}

			/* a=setup */
			attr = attr_get_by_id_m_s(media, ATTR_SETUP);
			if (attr) {
				if (attr->u.setup.value == SETUP_ACTPASS
						|| attr->u.setup.value == SETUP_ACTIVE)
					SP_SET(sp, SETUP_ACTIVE);
				if (attr->u.setup.value == SETUP_ACTPASS
						|| attr->u.setup.value == SETUP_PASSIVE)
					SP_SET(sp, SETUP_PASSIVE);
			}

			/* a=fingerprint */
			attr = attr_get_by_id_m_s(media, ATTR_FINGERPRINT);
			if (attr && attr->u.fingerprint.hash_func) {
				sp->fingerprint.hash_func = attr->u.fingerprint.hash_func;
				memcpy(sp->fingerprint.digest, attr->u.fingerprint.fingerprint,
						sp->fingerprint.hash_func->num_bytes);
			}

			__sdp_ice(sp, media);

			/* determine RTCP endpoint */

			if (attr_get_by_id(&media->attributes, ATTR_RTCP_MUX)) {
				SP_SET(sp, RTCP_MUX);
				goto next;
			}

			if (media->port_count != 1)
				goto next;

			attr = attr_get_by_id(&media->attributes, ATTR_RTCP);
			if (!attr) {
				SP_SET(sp, IMPLICIT_RTCP);
				goto next;
			}
			if (attr->u.rtcp.port_num == sp->rtp_endpoint.port
					&& !is_trickle_ice_address(&sp->rtp_endpoint))
			{
				SP_SET(sp, RTCP_MUX);
				goto next;
			}
			errstr = "Invalid RTCP attribute";
			if (fill_endpoint(&sp->rtcp_endpoint, media, flags, &attr->u.rtcp.address,
						attr->u.rtcp.port_num))
				goto error;

next:
			g_queue_push_tail(streams, sp);
		}
	}

	return 0;

error:
	ilog(LOG_WARNING, "Failed to extract streams from SDP: %s", errstr);
	if (sp)
		g_slice_free1(sizeof(*sp), sp);
	return -1;
}