Пример #1
0
inline int rtsp_media_aggregate_control_enable(void *sdp)
{
	const char* control;

	// rfc 2326 C.1.1 Control URL (p80)
	// If found at the session level, the attribute indicates the URL for aggregate control
	control = sdp_attribute_find(sdp, "control");
	return (control && *control) ? 1 : 0;
}
Пример #2
0
// rfc 2326 C.1.1 Control URL (p81)
// look for a base URL in the following order:
// 1. The RTSP Content-Base field
// 2. The RTSP Content-Location field
// 3. The RTSP request URL
static int rtsp_get_session_uri(void *sdp, char* uri, size_t bytes, const char* requri, const char* baseuri, const char* location)
{
	char path[256] = {0};
	const char* control;

	// C.1.1 Control URL (p81)
	// If this attribute contains only an asterisk (*), then the URL is
	// treated as if it were an empty embedded URL, and thus inherits the entire base URL.
	control = sdp_attribute_find(sdp, "control");
	if(!control || 0==*control || '*' == *control)
		control = "";
	strncpy(uri, control, bytes-1);

	if(!isAbsoluteURL(uri) && baseuri && *baseuri)
	{
		if(*uri)
		{
			uri_join(path, sizeof(path), baseuri, uri);
			baseuri = path;
		}
		strncpy(uri, baseuri, bytes-1);	
	}

	if(!isAbsoluteURL(uri) && location && *location)
	{
		if(*uri)
		{
			uri_join(path, sizeof(path), location, uri);
			location = path;
		}
		strncpy(uri, location, bytes-1);
	}

	if(!isAbsoluteURL(uri) && requri && *requri)
	{
		if(*uri)
		{
			uri_join(path, sizeof(path), requri, uri);
			requri = path;
		}
		strncpy(uri, requri, bytes-1);
	}

	return 0;
}
Пример #3
0
/** Find a mapped attribute.
 *
 * A mapped attribute has form 'a=<name>:<pt> <value>' where pt is a RTP
 * payload type, integer in range 0..127. For example, "a=atmmap" [@RFC3108]
 * is a mapped attribute. Note that common mapped attributes, "a=rtpmap" and
 * "a=fmtp" are already parsed as list of #sdp_rtpmap_t in #sdp_media_t.
 *
 * @param a pointer to first attribute in the list
 * @param name name of the attribute
 * @param pt payload type number (must be 0..127)
 * @param return_result return value parameter for mapped attribute value
 *
 * @return Pointer to a matching attribute structure, or NULL.
 *
 * If a matching attribute is found, @a return_result will point to part of
 * the attribute after the payload type and whitespace.
 */
sdp_attribute_t *sdp_attribute_mapped_find(sdp_attribute_t const *a,
					   char const *name,
					   int pt, char **return_result)
{
  char pt_value[4];
  size_t pt_len;

  if (return_result)
    *return_result = NULL;

  if (0 > pt || pt > 127)
    return NULL;

  snprintf(pt_value, sizeof(pt_value), "%u", (unsigned)pt);
  pt_len = strlen(pt_value);

  for (; (a = sdp_attribute_find(a, name)); a = a->a_next) {
    char const *value = a->a_value;
    size_t wlen;

    if (strncmp(value, pt_value, pt_len))
      continue;

    wlen = strspn(value + pt_len, " \t");

    if (wlen == 0 || value[pt_len + wlen] == '\0')
      continue;

    if (return_result)
      *return_result = (char *)value + pt_len + wlen;

    return (sdp_attribute_t *)a;
  }

  return NULL;
}
Пример #4
0
char *janus_sdp_anonymize(const char *sdp) {
	if(sdp == NULL)
		return NULL;
	sdp_session_t *anon = NULL;
	sdp_parser_t *parser = sdp_parse(home, sdp, strlen(sdp), 0);
	if(!(anon = sdp_session(parser))) {
		JANUS_LOG(LOG_ERR, "Error parsing/merging SDP: %s\n", sdp_parsing_error(parser));
		sdp_parser_free(parser);
		return NULL;
	}
	/* c= */
	if(anon->sdp_connection && anon->sdp_connection->c_address) {
		anon->sdp_connection->c_address = "1.1.1.1";
	}
	/* a= */
	if(anon->sdp_attributes) {
		/* These are attributes we handle ourselves, the plugins don't need them */
		while(sdp_attribute_find(anon->sdp_attributes, "ice-ufrag"))
			sdp_attribute_remove(&anon->sdp_attributes, "ice-ufrag");
		while(sdp_attribute_find(anon->sdp_attributes, "ice-pwd"))
			sdp_attribute_remove(&anon->sdp_attributes, "ice-pwd");
		while(sdp_attribute_find(anon->sdp_attributes, "ice-options"))
			sdp_attribute_remove(&anon->sdp_attributes, "ice-options");
		while(sdp_attribute_find(anon->sdp_attributes, "fingerprint"))
			sdp_attribute_remove(&anon->sdp_attributes, "fingerprint");
		while(sdp_attribute_find(anon->sdp_attributes, "group"))
			sdp_attribute_remove(&anon->sdp_attributes, "group");
		while(sdp_attribute_find(anon->sdp_attributes, "msid-semantic"))
			sdp_attribute_remove(&anon->sdp_attributes, "msid-semantic");
	}
		/* m= */
	if(anon->sdp_media) {
		int audio = 0, video = 0;
#ifdef HAVE_SCTP
		int data = 0;
#endif
		sdp_media_t *m = anon->sdp_media;
		while(m) {
			if(m->m_type == sdp_media_audio && m->m_port > 0) {
				audio++;
				m->m_port = audio == 1 ? 1 : 0;
			} else if(m->m_type == sdp_media_video && m->m_port > 0) {
				video++;
				m->m_port = video == 1 ? 1 : 0;
#ifdef HAVE_SCTP
			} else if(m->m_type == sdp_media_application) {
				if(m->m_proto_name != NULL && !strcasecmp(m->m_proto_name, "DTLS/SCTP") && m->m_port != 0) {
					data++;
					m->m_port = data == 1 ? 1 : 0;
				} else {
					m->m_port = 0;
				}
#endif
			} else {
				m->m_port = 0;
			}
				/* c= */
			if(m->m_connections) {
				sdp_connection_t *c = m->m_connections;
				while(c) {
					if(c->c_address) {
						c->c_address = "1.1.1.1";
					}
					c = c->c_next;
				}
			}
				/* a= */
			if(m->m_attributes) {
				/* These are attributes we handle ourselves, the plugins don't need them */
				while(sdp_attribute_find(m->m_attributes, "ice-ufrag"))
					sdp_attribute_remove(&m->m_attributes, "ice-ufrag");
				while(sdp_attribute_find(m->m_attributes, "ice-pwd"))
					sdp_attribute_remove(&m->m_attributes, "ice-pwd");
				while(sdp_attribute_find(m->m_attributes, "ice-options"))
					sdp_attribute_remove(&m->m_attributes, "ice-options");
				while(sdp_attribute_find(m->m_attributes, "crypto"))
					sdp_attribute_remove(&m->m_attributes, "crypto");
				while(sdp_attribute_find(m->m_attributes, "fingerprint"))
					sdp_attribute_remove(&m->m_attributes, "fingerprint");
				while(sdp_attribute_find(m->m_attributes, "setup"))
					sdp_attribute_remove(&m->m_attributes, "setup");
				while(sdp_attribute_find(m->m_attributes, "connection"))
					sdp_attribute_remove(&m->m_attributes, "connection");
				while(sdp_attribute_find(m->m_attributes, "group"))
					sdp_attribute_remove(&m->m_attributes, "group");
				while(sdp_attribute_find(m->m_attributes, "mid"))
					sdp_attribute_remove(&m->m_attributes, "mid");
				while(sdp_attribute_find(m->m_attributes, "msid"))
					sdp_attribute_remove(&m->m_attributes, "msid");
				while(sdp_attribute_find(m->m_attributes, "msid-semantic"))
					sdp_attribute_remove(&m->m_attributes, "msid-semantic");
				while(sdp_attribute_find(m->m_attributes, "rtcp"))
					sdp_attribute_remove(&m->m_attributes, "rtcp");
				while(sdp_attribute_find(m->m_attributes, "rtcp-mux"))
					sdp_attribute_remove(&m->m_attributes, "rtcp-mux");
				while(sdp_attribute_find(m->m_attributes, "candidate"))
					sdp_attribute_remove(&m->m_attributes, "candidate");
				while(sdp_attribute_find(m->m_attributes, "ssrc"))
					sdp_attribute_remove(&m->m_attributes, "ssrc");
				while(sdp_attribute_find(m->m_attributes, "ssrc-group"))
					sdp_attribute_remove(&m->m_attributes, "ssrc-group");
				while(sdp_attribute_find(m->m_attributes, "extmap"))	/* TODO Actually implement RTP extensions */
					sdp_attribute_remove(&m->m_attributes, "extmap");
				while(sdp_attribute_find(m->m_attributes, "sctpmap"))
					sdp_attribute_remove(&m->m_attributes, "sctpmap");
			}
			if(m->m_type != sdp_media_application && m->m_mode == sdp_sendrecv) {
				/* FIXME sendrecv hack: sofia-sdp doesn't print sendrecv, but we want it to */
				sdp_attribute_t *fakedir = calloc(1, sizeof(sdp_attribute_t));
				fakedir->a_size = sizeof(sdp_attribute_t);
				fakedir->a_name = g_strdup("jfmod");
				fakedir->a_value = g_strdup("sr");
				sdp_attribute_append(&m->m_attributes, fakedir);
			}
			m = m->m_next;
		}
	}
	char buf[BUFSIZE];
	sdp_printer_t *printer = sdp_print(home, anon, buf, BUFSIZE, 0);
	if(sdp_message(printer)) {
		int retval = sdp_message_size(printer);
		sdp_printer_free(printer);
		sdp_parser_free(parser);
		/* FIXME Take care of the sendrecv hack, if needed */
		char *replace = strstr(buf, "a=jfmod:sr");
		while(replace != NULL) {
			memcpy(replace, "a=sendrecv", strlen("a=sendrecv"));
			replace++;
			replace = strstr(replace, "a=jfmod:sr");
		}
		JANUS_LOG(LOG_VERB, " -------------------------------------------\n");
		JANUS_LOG(LOG_VERB, "  >> Anonymized (%zu --> %d bytes)\n", strlen(sdp), retval);
		JANUS_LOG(LOG_VERB, " -------------------------------------------\n");
		JANUS_LOG(LOG_VERB, "%s\n", buf);
		return g_strdup(buf);
	} else {
		JANUS_LOG(LOG_ERR, "Error anonymizing SDP: %s\n", sdp_printing_error(printer));
		sdp_printer_free(printer);
		sdp_parser_free(parser);
		return NULL;
	}
}
Пример #5
0
char *janus_sdp_anonymize(const char *sdp) {
	if(sdp == NULL)
		return NULL;
	//~ su_home_t home[1] = { SU_HOME_INIT(home) };
	sdp_session_t *anon = NULL;
	sdp_parser_t *parser = sdp_parse(home, sdp, strlen(sdp), 0);
	if(!(anon = sdp_session(parser))) {
		JANUS_DEBUG("Error parsing/merging SDP: %s\n", sdp_parsing_error(parser));
		return NULL;
	}
		//~ /* o= */
	//~ if(anon->sdp_origin && anon->sdp_origin->o_username) {
		//~ free(anon->sdp_origin->o_username);
		//~ anon->sdp_origin->o_username = strdup("JANUS");
	//~ }
		/* c= */
	if(anon->sdp_connection && anon->sdp_connection->c_address) {
		//~ free(anon->sdp_connection->c_address);
		anon->sdp_connection->c_address = strdup("1.1.1.1");
	}
		/* a= */
	if(anon->sdp_attributes) {
		/* FIXME These are attributes we handle ourselves, the plugins don't need them */
		while(sdp_attribute_find(anon->sdp_attributes, "ice-ufrag"))
			sdp_attribute_remove(&anon->sdp_attributes, "ice-ufrag");
		while(sdp_attribute_find(anon->sdp_attributes, "ice-pwd"))
			sdp_attribute_remove(&anon->sdp_attributes, "ice-pwd");
		while(sdp_attribute_find(anon->sdp_attributes, "ice-options"))
			sdp_attribute_remove(&anon->sdp_attributes, "ice-options");
		while(sdp_attribute_find(anon->sdp_attributes, "fingerprint"))
			sdp_attribute_remove(&anon->sdp_attributes, "fingerprint");
		while(sdp_attribute_find(anon->sdp_attributes, "group"))
			sdp_attribute_remove(&anon->sdp_attributes, "group");
		while(sdp_attribute_find(anon->sdp_attributes, "msid-semantic"))
			sdp_attribute_remove(&anon->sdp_attributes, "msid-semantic");
	}
		/* m= */
	int a_sendrecv = 0, v_sendrecv = 0;
	if(anon->sdp_media) {
		int audio = 0, video = 0;
		sdp_media_t *m = anon->sdp_media;
		while(m) {
			if(m->m_type == sdp_media_audio) {
				audio++;
				m->m_port = audio == 1 ? 1 : 0;
			} else if(m->m_type == sdp_media_video) {
				video++;
				m->m_port = audio == 1 ? 1 : 0;
			} else {
				m->m_port = 0;
			}
				/* c= */
			if(m->m_connections) {
				sdp_connection_t *c = m->m_connections;
				while(c) {
					if(c->c_address) {
						//~ free(c->c_address);
						c->c_address = strdup("1.1.1.1");
					}
					c = c->c_next;
				}
			}
				/* a= */
			if(m->m_attributes) {
				/* FIXME These are attributes we handle ourselves, the plugins don't need them */
				while(sdp_attribute_find(m->m_attributes, "ice-ufrag"))
					sdp_attribute_remove(&m->m_attributes, "ice-ufrag");
				while(sdp_attribute_find(m->m_attributes, "ice-pwd"))
					sdp_attribute_remove(&m->m_attributes, "ice-pwd");
				while(sdp_attribute_find(m->m_attributes, "ice-options"))
					sdp_attribute_remove(&m->m_attributes, "ice-options");
				while(sdp_attribute_find(m->m_attributes, "crypto"))
					sdp_attribute_remove(&m->m_attributes, "crypto");
				while(sdp_attribute_find(m->m_attributes, "fingerprint"))
					sdp_attribute_remove(&m->m_attributes, "fingerprint");
				while(sdp_attribute_find(m->m_attributes, "setup"))
					sdp_attribute_remove(&m->m_attributes, "setup");
				while(sdp_attribute_find(m->m_attributes, "connection"))
					sdp_attribute_remove(&m->m_attributes, "connection");
				while(sdp_attribute_find(m->m_attributes, "group"))
					sdp_attribute_remove(&m->m_attributes, "group");
				while(sdp_attribute_find(m->m_attributes, "msid-semantic"))
					sdp_attribute_remove(&m->m_attributes, "msid-semantic");
				while(sdp_attribute_find(m->m_attributes, "rtcp"))
					sdp_attribute_remove(&m->m_attributes, "rtcp");
				while(sdp_attribute_find(m->m_attributes, "rtcp-mux"))
					sdp_attribute_remove(&m->m_attributes, "rtcp-mux");
				while(sdp_attribute_find(m->m_attributes, "candidate"))
					sdp_attribute_remove(&m->m_attributes, "candidate");
				while(sdp_attribute_find(m->m_attributes, "ssrc"))
					sdp_attribute_remove(&m->m_attributes, "ssrc");
				while(sdp_attribute_find(m->m_attributes, "extmap"))	/* TODO Actually implement RTP extensions */
					sdp_attribute_remove(&m->m_attributes, "extmap");
			}
			/* FIXME sendrecv hack: sofia-sdp doesn't print sendrecv, but we want it to */
			if(m->m_mode == sdp_sendrecv) {
				m->m_mode = sdp_inactive;
				if(m->m_type == sdp_media_audio)
					a_sendrecv = 1;
				else if(m->m_type == sdp_media_video)
					v_sendrecv = 1;
			}
			m = m->m_next;
		}
	}
	char buf[BUFSIZE];
	sdp_printer_t *printer = sdp_print(home, anon, buf, BUFSIZE, 0);
	if(sdp_message(printer)) {
		int retval = sdp_message_size(printer);
		sdp_printer_free(printer);
		/* FIXME Take care of the sendrecv hack */
		if(a_sendrecv || v_sendrecv) {
			char *replace = strstr(buf, "a=inactive");
			while(replace != NULL) {
				memcpy(replace, "a=sendrecv", strlen("a=sendrecv"));
				replace++;
				replace = strstr(replace, "a=inactive");
			}
		}
		JANUS_PRINT(" -------------------------------------------\n");
		JANUS_PRINT("  >> Anonymized (%zu --> %d bytes)\n", strlen(sdp), retval);
		JANUS_PRINT(" -------------------------------------------\n");
		JANUS_PRINT("%s\n", buf);
		return g_strdup(buf);
	} else {
		JANUS_DEBUG("Error anonymizing SDP: %s\n", sdp_printing_error(printer));
		return NULL;
	}
}