Esempio n. 1
0
static int ms_zrtp_rtp_process_on_receive(struct _RtpTransportModifier *t, mblk_t *msg){
	uint32_t *magicField;

	MSZrtpContext *userData = (MSZrtpContext*) t->data;
	bzrtpContext_t *zrtpContext = userData->zrtpContext;
	uint8_t* rtp;
	int rtpVersion;
	int msgLength = msgdsize(msg);

	// send a timer tick to the zrtp engine
	bzrtp_iterate(zrtpContext, userData->self_ssrc, get_timeval_in_millis());

	// check incoming message length
	if (msgLength<RTP_FIXED_HEADER_SIZE) {
		return msgLength;
	}

	rtp=msg->b_rptr;
	rtpVersion = ((rtp_header_t*)rtp)->version;
	magicField=(uint32_t *)(rtp + 4);

	// Check if there is a ZRTP packet to receive
	if (rtpVersion!=0 || ntohl(*magicField) != ZRTP_MAGIC_COOKIE) {
		return msgLength;
	}

	// display received message
	ms_message("ZRTP Receive packet type %.8s", rtp+16);

	// send ZRTP packet to engine
	bzrtp_processMessage(zrtpContext, userData->self_ssrc, rtp, msgLength);
	return 0;
}
Esempio n. 2
0
static void schedule_rtcp(struct _RtpTransportModifier *t) {
	MSDtlsSrtpContext *ctx = (MSDtlsSrtpContext *)t->data;
	if (ctx->role == MSDtlsSrtpRoleIsClient) { /* only if we are client */
		uint64_t current_time = get_timeval_in_millis();
		if (ctx->rtcp_time_reference>0) { /* only when retransmission timer is armed */
			if (current_time - ctx->rtcp_time_reference > READ_TIMEOUT_MS) {
				ms_message("DTLS repeating rtcp ssl_handshake for context [%p]",ctx);
				ms_mutex_lock(&ctx->rtcp_dtls_context->ssl_context_mutex);
				ssl_handshake(&(ctx->rtcp_dtls_context->ssl));
				ms_mutex_unlock(&ctx->rtcp_dtls_context->ssl_context_mutex);
				ctx->rtcp_time_reference = get_timeval_in_millis();
			}
		}

	}
}
Esempio n. 3
0
void ms_dtls_srtp_start(MSDtlsSrtpContext* context) {
	if (context == NULL ) {
		ms_warning("DTLS start but no context\n");
		return;
	}
	ms_message("DTLS start stream on stream sessions [%p]", context->stream_sessions);
	/* if we are client, start the handshake(send a clientHello) */
	if (context->role == MSDtlsSrtpRoleIsClient) {
		ms_mutex_lock(&context->rtp_dtls_context->ssl_context_mutex);
		ms_mutex_lock(&context->rtcp_dtls_context->ssl_context_mutex);
		ssl_set_endpoint(&(context->rtp_dtls_context->ssl), SSL_IS_CLIENT);
		ssl_handshake(&(context->rtp_dtls_context->ssl));
		context->rtp_time_reference = get_timeval_in_millis(); /* arm the timer for retransmission */
		ssl_set_endpoint(&(context->rtcp_dtls_context->ssl), SSL_IS_CLIENT);
		ssl_handshake(&(context->rtcp_dtls_context->ssl));
		context->rtcp_time_reference = get_timeval_in_millis(); /* arm the timer for retransmission */
		ms_mutex_unlock(&context->rtp_dtls_context->ssl_context_mutex);
		ms_mutex_unlock(&context->rtcp_dtls_context->ssl_context_mutex);
	}

}
Esempio n. 4
0
/**
 * Check if the incoming message is a DTLS packet.
 * If it is, store it in the context incoming buffer and call the polarssl function wich will process it.
 * This function also manages the client retransmission timer
 *
 * @param[in] 		msg	the incoming message
 * @param[in/out]	ctx	the context containing the incoming buffer to store the DTLS packet
 * @param[out]		ret	the value returned by the polarssl function processing the packet(ssl_handshake)
 * @param[in]		is_rtp	TRUE if we are dealing with a RTP channel packet, FALSE for RTCP channel
 * @return TRUE if packet is a DTLS one, false otherwise
 */
static bool_t ms_dtls_srtp_process_dtls_packet(mblk_t *msg, MSDtlsSrtpContext *ctx, int *ret, bool_t is_rtp) {
	size_t msgLength = msgdsize(msg);
	uint64_t *time_reference = (is_rtp == TRUE)?&(ctx->rtp_time_reference):&(ctx->rtcp_time_reference);
	ssl_context *ssl = (is_rtp == TRUE)?&(ctx->rtp_dtls_context->ssl):&(ctx->rtcp_dtls_context->ssl);
	ms_mutex_t *mutex = (is_rtp == TRUE)?&ctx->rtp_dtls_context->ssl_context_mutex:&ctx->rtcp_dtls_context->ssl_context_mutex;
	// check if incoming message length is compatible with potential DTLS message
	if (msgLength<RTP_FIXED_HEADER_SIZE) {
		return FALSE;
	}

	/* check if it is a DTLS packet (first byte B as 19 < B < 64) rfc5764 section 5.1.2 */
	if ((*(msg->b_rptr)>19) && (*(msg->b_rptr)<64)) {

		DtlsRawPacket *incoming_dtls_packet;
		RtpSession *rtp_session = ctx->stream_sessions->rtp_session;
		OrtpStream *ortp_stream = is_rtp?&rtp_session->rtp.gs:&rtp_session->rtcp.gs;
		incoming_dtls_packet = (DtlsRawPacket *)ms_malloc0(sizeof(DtlsRawPacket));
		//DtlsRawPacket *incoming_dtls_packet = (DtlsRawPacket *)ms_malloc0(sizeof(DtlsRawPacket));
		incoming_dtls_packet->next=NULL;
		incoming_dtls_packet->data=(unsigned char *)ms_malloc(msgLength);
		incoming_dtls_packet->length=msgLength;
		memcpy(incoming_dtls_packet->data, msg->b_rptr, msgLength);

		/*required by webrtc in server case when ice is not completed yet*/
		if (!rtp_session->use_connect){
			struct sockaddr *addr = NULL;
			socklen_t addrlen;
			addr = (struct sockaddr *)&msg->net_addr;
			addrlen = msg->net_addrlen;
			if (ortp_stream->socket>0 && rtp_session->symmetric_rtp){
				/* store the sender rtp address to do symmetric DTLS */
				memcpy(&ortp_stream->rem_addr,addr,addrlen);
				ortp_stream->rem_addrlen=addrlen;
			}
		}

		/* store the packet in the incoming buffer */
		if (is_rtp == TRUE) {
			if (ctx->rtp_incoming_buffer==NULL) { /* buffer is empty */
				ctx->rtp_incoming_buffer = incoming_dtls_packet;
			} else { /* queue it at the end of current buffer */
				DtlsRawPacket *last_packet = ctx->rtp_incoming_buffer;
				while (last_packet->next != NULL) last_packet = last_packet->next;
				last_packet->next = incoming_dtls_packet;
			}
		} else {
			if (ctx->rtcp_incoming_buffer==NULL) { /* buffer is empty */
				ctx->rtcp_incoming_buffer = incoming_dtls_packet;
			} else { /* queue it at the end of current buffer */
				DtlsRawPacket *last_packet = ctx->rtcp_incoming_buffer;
				while (last_packet->next != NULL) last_packet = last_packet->next;
				last_packet->next = incoming_dtls_packet;
			}
		}
		
		/* role is unset but we receive a packet: we are caller and shall initialise as server and then process the incoming packet */
		if (ctx->role == MSDtlsSrtpRoleUnset) {
			ms_dtls_srtp_set_role(ctx, MSDtlsSrtpRoleIsServer); /* this call will update role and complete server setup */
		}
		ms_mutex_lock(mutex);
		/* process the packet and store result */
		*ret = ssl_handshake(ssl);

		/* when we are server, we may issue a hello verify, so reset session, keep cookies(transport id) and expect an other Hello from client */
		if (*ret==POLARSSL_ERR_SSL_HELLO_VERIFY_REQUIRED) {
			ssl_session_reset(ssl);
			ssl_set_client_transport_id(ssl, (const unsigned char *)(&(ctx->stream_sessions->rtp_session->snd.ssrc)), 4);
		}

		/* if we are client, manage the retransmission timer */
		if (ctx->role == MSDtlsSrtpRoleIsClient) {
			*time_reference = get_timeval_in_millis();
		}
		ms_mutex_unlock(mutex);
		return TRUE;
	}

	return FALSE;

}