Exemplo n.º 1
0
static int insert_raddr_rport(struct sdp_chopper *chop, struct packet_stream *ps, struct interface_address *ifa) {
        char buf[64];
        int len;

	chopper_append_c(chop, " raddr ");
	call_stream_address46(buf, ps, SAF_ICE, &len, ifa);
	chopper_append_dup(chop, buf, len);
	chopper_append_c(chop, " rport ");
	chopper_append_printf(chop, "%hu", ps->sfd->fd.localport);

	return 0;
}
Exemplo n.º 2
0
static void insert_candidates(struct sdp_chopper *chop, struct packet_stream *rtp, struct packet_stream *rtcp,
		struct sdp_ng_flags *flags, struct sdp_media *sdp_media)
{
	const struct local_intf *ifa;
	struct call_media *media;
	struct ice_agent *ag;
	unsigned int type_pref, local_pref;
	enum ice_candidate_type cand_type;
	struct ice_candidate *cand;

	media = rtp->media;

	cand_type = ICT_HOST;
	if (flags->ice_force_relay)
		cand_type = ICT_RELAY;
	if (MEDIA_ISSET(media, PASSTHRU))
		new_priority(sdp_media, cand_type, &type_pref, &local_pref);
	else {
		type_pref = ice_type_preference(cand_type);
		local_pref = -1;
	}

	ag = media->ice_agent;

	if (ag && AGENT_ISSET(ag, COMPLETED)) {
		ifa = rtp->selected_sfd->local_intf;
		insert_candidate(chop, rtp->selected_sfd, type_pref, ifa->unique_id, cand_type);
		if (rtcp) /* rtcp-mux only possible in answer */
			insert_candidate(chop, rtcp->selected_sfd, type_pref, ifa->unique_id, cand_type);

		if (flags->opmode == OP_OFFER && AGENT_ISSET(ag, CONTROLLING)) {
			GQueue rc;
			GList *l;
			chopper_append_c(chop, "a=remote-candidates:");
			ice_remote_candidates(&rc, ag);
			for (l = rc.head; l; l = l->next) {
				if (l != rc.head)
					chopper_append_c(chop, " ");
				cand = l->data;
				chopper_append_printf(chop, "%lu %s %u", cand->component_id,
						sockaddr_print_buf(&cand->endpoint.address), cand->endpoint.port);
			}
			chopper_append_c(chop, "\r\n");
			g_queue_clear(&rc);
		}
		return;
	}

	insert_sfd_candidates(chop, rtp, type_pref, local_pref, cand_type);

	if (rtcp) /* rtcp-mux only possible in answer */
		insert_sfd_candidates(chop, rtcp, type_pref, local_pref, cand_type);
}
Exemplo n.º 3
0
static int insert_raddr_rport(struct sdp_chopper *chop, struct packet_stream *ps, const struct local_intf *ifa) {
        char buf[64];
        int len;

	chopper_append_c(chop, " raddr ");
	call_stream_address46(buf, ps, SAF_ICE, &len, ifa);
	chopper_append_dup(chop, buf, len);
	chopper_append_c(chop, " rport ");
	chopper_append_printf(chop, "%u", ps->selected_sfd->socket.local.port);

	return 0;
}
Exemplo n.º 4
0
static void insert_candidate(struct sdp_chopper *chop, struct packet_stream *ps, unsigned int component,
		unsigned int type_pref, unsigned int local_pref, enum ice_candidate_type type,
		struct interface_address *ifa)
{
	unsigned long priority;

	priority = ice_priority_pref(type_pref, local_pref, component);
	chopper_append_c(chop, "a=candidate:");
	chopper_append_str(chop, &ifa->ice_foundation);
	chopper_append_printf(chop, " %u UDP %lu ", component, priority);
	insert_ice_address(chop, ps, ifa);
	chopper_append_c(chop, " typ ");
	chopper_append_c(chop, ice_candidate_type_str(type));
	/* raddr and rport are required for non-host candidates: rfc5245 section-15.1 */
	if(type != ICT_HOST)
		insert_raddr_rport(chop, ps, ifa);
	chopper_append_c(chop, "\r\n");
}
Exemplo n.º 5
0
static void insert_candidate(struct sdp_chopper *chop, struct stream_fd *sfd,
		unsigned int type_pref, unsigned int local_pref, enum ice_candidate_type type)
{
	unsigned long priority;
	struct packet_stream *ps = sfd->stream;
	const struct local_intf *ifa = sfd->local_intf;

	if (local_pref == -1)
		local_pref = ifa->unique_id;

	priority = ice_priority_pref(type_pref, local_pref, ps->component);
	chopper_append_c(chop, "a=candidate:");
	chopper_append_str(chop, &ifa->ice_foundation);
	chopper_append_printf(chop, " %u UDP %lu ", ps->component, priority);
	insert_ice_address(chop, sfd);
	chopper_append_c(chop, " typ ");
	chopper_append_c(chop, ice_candidate_type_str(type));
	/* raddr and rport are required for non-host candidates: rfc5245 section-15.1 */
	if(type != ICT_HOST)
		insert_raddr_rport(chop, ps, ifa);
	chopper_append_c(chop, "\r\n");
}
Exemplo n.º 6
0
static int replace_transport_protocol(struct sdp_chopper *chop,
		struct sdp_media *media, struct call_media *cm)
{
	str *tp = &media->transport;

	if (!cm->protocol)
		return 0;

	if (copy_up_to(chop, tp))
		return -1;
	chopper_append_c(chop, cm->protocol->name);
	if (skip_over(chop, tp))
		return -1;

	return 0;
}
Exemplo n.º 7
0
static void insert_crypto(struct call_media *media, struct sdp_chopper *chop) {
	char b64_buf[((SRTP_MAX_MASTER_KEY_LEN + SRTP_MAX_MASTER_SALT_LEN) / 3 + 1) * 4 + 4];
	char *p;
	int state = 0, save = 0, i;
	struct crypto_params *cp = &media->sdes_out.params;
	unsigned long long ull;

	if (!cp->crypto_suite || !MEDIA_ISSET(media, SDES) || MEDIA_ISSET(media, PASSTHRU))
		return;

	p = b64_buf;
	p += g_base64_encode_step((unsigned char *) cp->master_key,
			cp->crypto_suite->master_key_len, 0,
			p, &state, &save);
	p += g_base64_encode_step((unsigned char *) cp->master_salt,
			cp->crypto_suite->master_salt_len, 0,
			p, &state, &save);
	p += g_base64_encode_close(0, p, &state, &save);

	chopper_append_c(chop, "a=crypto:");
	chopper_append_printf(chop, "%u ", media->sdes_out.tag);
	chopper_append_c(chop, cp->crypto_suite->name);
	chopper_append_c(chop, " inline:");
	chopper_append_dup(chop, b64_buf, p - b64_buf);
	if (cp->mki_len) {
		ull = 0;
		for (i = 0; i < cp->mki_len && i < sizeof(ull); i++)
			ull |= cp->mki[cp->mki_len - i - 1] << (i * 8);
		chopper_append_printf(chop, "|%llu:%u", ull, cp->mki_len);
	}
	if (cp->session_params.unencrypted_srtp)
		chopper_append_c(chop, " UNENCRYPTED_SRTP");
	if (cp->session_params.unencrypted_srtcp)
		chopper_append_c(chop, " UNENCRYPTED_SRTCP");
	if (cp->session_params.unauthenticated_srtp)
		chopper_append_c(chop, " UNAUTHENTICATED_SRTP");
	chopper_append_c(chop, "\r\n");
}
Exemplo n.º 8
0
static void insert_dtls(struct call_media *media, struct sdp_chopper *chop) {
	char hexbuf[DTLS_MAX_DIGEST_LEN * 3 + 2];
	unsigned char *p;
	char *o;
	int i;
	const struct dtls_hash_func *hf;
	const char *actpass;
	struct call *call = media->call;

	if (!call->dtls_cert || !MEDIA_ISSET(media, DTLS) || MEDIA_ISSET(media, PASSTHRU))
		return;

	hf = call->dtls_cert->fingerprint.hash_func;

	assert(hf->num_bytes > 0);

	p = call->dtls_cert->fingerprint.digest;
	o = hexbuf;
	for (i = 0; i < hf->num_bytes; i++)
		o += sprintf(o, "%02X:", *p++);
	*(--o) = '\0';

	actpass = "******";
	if (MEDIA_ARESET2(media, SETUP_PASSIVE, SETUP_ACTIVE))
		actpass = "******";
	else if (MEDIA_ISSET(media, SETUP_PASSIVE))
		actpass = "******";
	else if (MEDIA_ISSET(media, SETUP_ACTIVE))
		actpass = "******";

	chopper_append_c(chop, "a=setup:");
	chopper_append_c(chop, actpass);
	chopper_append_c(chop, "\r\na=fingerprint:");
	chopper_append_c(chop, hf->name);
	chopper_append_c(chop, " ");
	chopper_append_dup(chop, hexbuf, o - hexbuf);
	chopper_append_c(chop, "\r\n");
}
Exemplo n.º 9
0
/* called with call->master_lock held in W */
int sdp_replace(struct sdp_chopper *chop, GQueue *sessions, struct call_monologue *monologue,
		struct sdp_ng_flags *flags)
{
	struct sdp_session *session;
	struct sdp_media *sdp_media;
	GList *l, *k, *m, *j;
	int media_index, sess_conn;
	struct call_media *call_media;
	struct packet_stream *ps, *ps_rtcp;

	m = monologue->medias.head;

	for (l = sessions->head; l; l = l->next) {
		session = l->data;
		if (!m)
			goto error;
		call_media = m->data;
		if (call_media->index != 1)
			goto error;
		j = call_media->streams.head;
		if (!j)
			goto error;
		ps = j->data;

		sess_conn = 0;
		if (flags->replace_sess_conn)
			sess_conn = 1;
		else {
			for (k = session->media_streams.head; k; k = k->next) {
				sdp_media = k->data;
				if (!sdp_media->connection.parsed) {
					sess_conn = 1;
					break;
				}
			}
		}

		if (session->origin.parsed && flags->replace_origin &&
		    !flags->ice_force_relay) {
			if (replace_network_address(chop, &session->origin.address, ps, flags))
				goto error;
		}
		if (session->connection.parsed && sess_conn &&
		    !flags->ice_force_relay) {
			if (replace_network_address(chop, &session->connection.address, ps, flags))
				goto error;
		}

		if (!MEDIA_ISSET(call_media, PASSTHRU)) {
			if (process_session_attributes(chop, &session->attributes, flags))
				goto error;
		}

		media_index = 1;

		for (k = session->media_streams.head; k; k = k->next) {
			sdp_media = k->data;
			if (!m)
				goto error;
			call_media = m->data;
			if (call_media->index != media_index)
				goto error;
			j = call_media->streams.head;
			if (!j)
				goto error;
			ps = j->data;

			if (!flags->ice_force_relay) {
			        if (replace_media_port(chop, sdp_media, ps))
				        goto error;
			        if (replace_consecutive_port_count(chop, sdp_media, ps, j))
				        goto error;
				if (replace_transport_protocol(chop, sdp_media, call_media))
				        goto error;

				if (sdp_media->connection.parsed) {
				        if (replace_network_address(chop, &sdp_media->connection.address, ps, flags))
					        goto error;
				}
			}

			if (process_media_attributes(chop, sdp_media, flags, call_media))
				goto error;

			copy_up_to_end_of(chop, &sdp_media->s);

			ps_rtcp = NULL;
			if (ps->rtcp_sibling) {
				ps_rtcp = ps->rtcp_sibling;
				j = j->next;
				if (!j)
					goto error;
				assert(j->data == ps_rtcp);
			}

			if (!sdp_media->port_num || !ps->sfd)
				goto next;

			if (MEDIA_ARESET2(call_media, SEND, RECV))
				chopper_append_c(chop, "a=sendrecv\r\n");
			else if (MEDIA_ISSET(call_media, SEND))
				chopper_append_c(chop, "a=sendonly\r\n");
			else if (MEDIA_ISSET(call_media, RECV))
				chopper_append_c(chop, "a=recvonly\r\n");
			else
				chopper_append_c(chop, "a=inactive\r\n");

			if (call_media->protocol && call_media->protocol->rtp) {
				if (MEDIA_ISSET(call_media, RTCP_MUX) && flags->opmode == OP_ANSWER) {
					chopper_append_c(chop, "a=rtcp:");
					chopper_append_printf(chop, "%hu", ps->sfd->fd.localport);
					chopper_append_c(chop, "\r\na=rtcp-mux\r\n");
					ps_rtcp = NULL;
				}
				else if (ps_rtcp && !flags->ice_force_relay) {
					chopper_append_c(chop, "a=rtcp:");
					chopper_append_printf(chop, "%hu", ps_rtcp->sfd->fd.localport);
					if (!MEDIA_ISSET(call_media, RTCP_MUX))
						chopper_append_c(chop, "\r\n");
					else
						chopper_append_c(chop, "\r\na=rtcp-mux\r\n");
				}
			}
			else
				ps_rtcp = NULL;

			insert_crypto(call_media, chop);
			insert_dtls(call_media, chop);

			if (MEDIA_ISSET(call_media, ICE) && call_media->ice_agent) {
				chopper_append_c(chop, "a=ice-ufrag:");
				chopper_append_str(chop, &call_media->ice_agent->ufrag[1]);
				chopper_append_c(chop, "\r\na=ice-pwd:");
				chopper_append_str(chop, &call_media->ice_agent->pwd[1]);
				chopper_append_c(chop, "\r\n");
			}

			if (!flags->ice_remove)
				insert_candidates(chop, ps, ps_rtcp, flags, sdp_media);

next:
			media_index++;
			m = m->next;
		}
	}

	copy_remainder(chop);
	return 0;

error:
	ilog(LOG_ERROR, "Error rewriting SDP");
	return -1;
}
Exemplo n.º 10
0
static void insert_candidates(struct sdp_chopper *chop, struct packet_stream *rtp, struct packet_stream *rtcp,
		struct sdp_ng_flags *flags, struct sdp_media *sdp_media)
{
	GList *l;
	struct interface_address *ifa;
	unsigned int pref;
	struct call_media *media;
	struct local_interface *lif;
	struct ice_agent *ag;
	unsigned int type_pref, local_pref;
	enum ice_candidate_type cand_type;
	struct ice_candidate *cand;

	media = rtp->media;

	cand_type = ICT_HOST;
	if (flags->ice_force_relay)
		cand_type = ICT_RELAY;
	if (MEDIA_ISSET(media, PASSTHRU))
		new_priority(sdp_media, cand_type, &type_pref, &local_pref);
	else {
		type_pref = ice_type_preference(cand_type);
		local_pref = -1;
	}

	ag = media->ice_agent;
	lif = ag ? ag->local_interface : media->interface;

	if (ag && AGENT_ISSET(ag, COMPLETED)) {
		ifa = g_atomic_pointer_get(&media->local_address);
		insert_candidate(chop, rtp, 1, type_pref, ifa->preference, cand_type, ifa);
		if (rtcp) /* rtcp-mux only possible in answer */
			insert_candidate(chop, rtcp, 2, type_pref, ifa->preference, cand_type, ifa);

		if (flags->opmode == OP_OFFER && AGENT_ISSET(ag, CONTROLLING)) {
			GQueue rc;
			GList *l;
			chopper_append_c(chop, "a=remote-candidates:");
			ice_remote_candidates(&rc, ag);
			for (l = rc.head; l; l = l->next) {
				if (l != rc.head)
					chopper_append_c(chop, " ");
				cand = l->data;
				chopper_append_printf(chop, "%lu %s %u", cand->component_id,
						smart_ntop_buf(&cand->endpoint.ip46), cand->endpoint.port);
			}
			chopper_append_c(chop, "\r\n");
			g_queue_clear(&rc);
		}
		return;
	}

	for (l = lif->list.head; l; l = l->next) {
		ifa = l->data;
		pref = (local_pref == -1) ? ifa->preference : local_pref;

		insert_candidate(chop, rtp, 1, type_pref, pref, cand_type, ifa);

		if (rtcp) /* rtcp-mux only possible in answer */
			insert_candidate(chop, rtcp, 2, type_pref, pref, cand_type, ifa);

		if (local_pref != -1)
			local_pref++;
	}
}