Beispiel #1
0
/*----------------------------------------------------------------------------*/
zrtp_status_t _zrtp_protocol_decrypt( zrtp_protocol_t *proto,
									  zrtp_rtp_info_t *packet,
									  uint8_t is_rtp)
{
	zrtp_status_t s = zrtp_status_ok;

	if (is_rtp) {
		s = zrtp_srtp_unprotect(proto->context->zrtp->srtp_global, proto->_srtp, packet);
	} else {
		s = zrtp_srtp_unprotect_rtcp(proto->context->zrtp->srtp_global, proto->_srtp, packet);
	}

	if (zrtp_status_ok != s) {
		ZRTP_UNALIGNED(zrtp_rtp_hdr_t) *hdr = (zrtp_rtp_hdr_t*) packet->packet;
		ZRTP_LOG(2,(_ZTU_,"ERROR! Decrypt failed. ID=%u:%s s=%s (%s size=%d ssrc=%u seq=%u/%u pt=%d)\n",
					    proto->context->id,
						zrtp_log_mode2str(proto->context->mode),
						zrtp_log_status2str(s),
						is_rtp ? "RTP" : "RTCP",
						*packet->length,
						zrtp_ntoh32(hdr->ssrc),
						zrtp_ntoh16(hdr->seq),
						packet->seq,
						hdr->pt));
    }

	return s;
}
Beispiel #2
0
void *process_outgoing(void *param)
#endif
{
	unsigned packets_counter = 0;
	zrtp_endpoint_t *the_endpoint = (zrtp_endpoint_t *)param;

	while (the_endpoint->is_running) {
		zrtp_test_stream_t* stream = NULL;
		unsigned i;

		zrtp_status_t s = zrtp_status_fail;
		zrtp_test_packet_t* packet;
		zrtp_queue_elem_t* elem;
		char* word = NULL;

		zrtp_sleep(K_ZRTP_TEST_RTP_RATE);

		/* Get random channel to operate with and select random peer */
		stream = get_stream_to_process_(the_endpoint);
		if (!stream) {
			continue;
		}

		elem = zrtp_sys_alloc(sizeof(zrtp_queue_elem_t));
		if (!elem) {
			break;
		}
		packet = (zrtp_test_packet_t*) elem->data;
		packet->is_rtp = (packets_counter++ % 20); /* Every 20-th packet is RTCP */

		/*
		 * Construct RTP/RTCP Packet
		 */
		if (packet->is_rtp)
		{
			ZRTP_UNALIGNED(zrtp_rtp_hdr_t) *rtp_hdr = (zrtp_rtp_hdr_t*)packet->body;

			/* Fill RTP Header according to the specification */
			zrtp_memset(rtp_hdr, 0, sizeof(zrtp_rtp_hdr_t));
			rtp_hdr->version = 2;			/* Current RTP version 2 */
			rtp_hdr->pt = 0;				/* PCMU padding type */
			rtp_hdr->ssrc = zrtp_hton32(stream->id);		/* Use stream Identifier as it's SSRC */
			if (stream->seq >= 0xFFFF) {
				stream->seq = 0;
			}
			rtp_hdr->seq = zrtp_hton16(stream->seq++);
			rtp_hdr->ts = zrtp_hton32((uint32_t)(zrtp_time_now()/1000));

			/* Get RTP body from PGP words lists */
			word = (char*)(i ? hash_word_list_odd[packets_counter % 256] : hash_word_list_even[packets_counter % 256]);

			zrtp_memcpy(packet->body + sizeof(zrtp_rtp_hdr_t), word, (uint32_t)strlen(word));
			packet->length = sizeof(zrtp_rtp_hdr_t) + (uint32_t)strlen(word);

			/* Process RTP media with libzrtp */
			s = zrtp_process_rtp(stream->zrtp, packet->body, &packet->length);
		}
		else {
			ZRTP_UNALIGNED(zrtp_rtcp_hdr_t) *rtcp_hdr = (zrtp_rtcp_hdr_t*)packet->body;

			/* Fill RTCP Header according to the specification */
			rtcp_hdr->rc = 0;
			rtcp_hdr->version = 2;
			rtcp_hdr->ssrc = stream->id;

			/* Get RTP body from PGP words lists. Put RTCP marker at the beginning */
			zrtp_memcpy(packet->body + sizeof(zrtp_rtcp_hdr_t), "RTCP", 4);
			word = (char*)( i ? hash_word_list_odd[packets_counter % 256] : hash_word_list_even[packets_counter % 256]);

			zrtp_memcpy(packet->body + sizeof(zrtp_rtcp_hdr_t) + 4, word, (uint32_t)strlen(word));
			packet->length = sizeof(zrtp_rtcp_hdr_t) + (uint32_t)strlen(word) + 4;
			/* RTCP packets sould be 32 byes aligned */
			packet->length += (packet->length % 4) ? (4 - packet->length % 4) : 0;

			/* Process RTCP control with libzrtp */
			s = zrtp_process_rtcp(stream->zrtp, packet->body, &packet->length);
		}

		elem->size = packet->length;

		/* Handle zrtp_process_xxx() instructions */
		switch (s) {
		/* Put the packet to the queue ==> send packet to the other side pear */
		case zrtp_status_ok: {
			ZRTP_LOG(3, (_ZTU_,"Outgoing: (%s) [%p:ssrc=%u] OK. <%s%s> encrypted %d bytes.\n",
					zrtp_log_state2str(stream->zrtp->state), stream->zrtp, stream->id, packet->is_rtp ? "" : "RTCP", word, packet->length));
			zrtp_test_queue_push(stream->output, elem);
		} break;

		case zrtp_status_drop: {
			ZRTP_LOG(1, (_ZTU_,"Outgoing: (%s) [%p:ssrc=%u] DROPPED.\n",
					zrtp_log_state2str(stream->zrtp->state), stream->zrtp, stream->id));
		} break;

		case zrtp_status_fail: {
			ZRTP_LOG(1, (_ZTU_,"Outgoing: (%s) [%p:ssrc=%u] ENCRYPT FAILED.\n",
					zrtp_log_state2str(stream->zrtp->state), stream->zrtp, stream->id));
		}	break;

		default:
			break;
		}

		if (zrtp_status_ok != s) {
			zrtp_sys_free(packet);
		}
	}
#if   (ZRTP_PLATFORM == ZP_WIN32) || (ZRTP_PLATFORM == ZP_WINCE)
	return 0;
#else
	return NULL;
#endif
}
Beispiel #3
0
void *process_incoming(void *param)
#endif
{
	zrtp_endpoint_t *the_endpoint = (zrtp_endpoint_t *)param;

	while (the_endpoint->is_running) {
		zrtp_test_packet_t* packet = NULL;
		zrtp_queue_elem_t* elem = NULL;
		zrtp_status_t s = zrtp_status_fail;
		zrtp_test_stream_t *stream;
		int is_protocol = 0;

		// TODO: use peak to not to block processing if queue for this stream is empty
		elem = zrtp_test_queue_pop(the_endpoint->input_queue);
		if (!elem || elem->size <= 0) {
			if (elem) zrtp_sys_free(elem);
			break;
		}

		packet = (zrtp_test_packet_t*) elem->data;
		zrtp_test_id_t stream_id;
		{
			if (packet->is_rtp) {
				ZRTP_UNALIGNED(zrtp_rtp_hdr_t) *rtp_hdr = (zrtp_rtp_hdr_t*)packet->body;
				stream_id = zrtp_ntoh32(rtp_hdr->ssrc); /* remember, we use stream Id as it's RTP SSRC */
			} else {
				ZRTP_UNALIGNED(zrtp_rtcp_hdr_t) *rtcp_hdr = (zrtp_rtcp_hdr_t*)packet->body;
				stream_id = zrtp_ntoh32(rtcp_hdr->ssrc); /* remember, we use stream Id as it's RTP SSRC */
			}
			stream = zrtp_test_stream_by_peerid(stream_id);
		}

		/*
		 * Process incoming packet by libzrtp. Is this a RTP media packet - copy it to the buffer
		 * to print out later.
		 */
		if (packet->is_rtp) {
			s = zrtp_process_srtp(stream->zrtp, packet->body, &packet->length);
		} else {
			s = zrtp_process_srtcp(stream->zrtp, packet->body, &packet->length);
		}

		if (!is_protocol) {
			char *body;
			if (packet->is_rtp) {
				body = packet->body + sizeof(zrtp_rtp_hdr_t);
				body[packet->length - sizeof(zrtp_rtp_hdr_t)] = 0;
			} else {
				body = packet->body + sizeof(zrtp_rtcp_hdr_t);
				body[packet->length - sizeof(zrtp_rtcp_hdr_t)] = 0;
			}

			switch (s)
			{
			case zrtp_status_ok: {
				ZRTP_LOG(1, (_ZTU_,"Incoming: (%s) [%p:ssrc=%u] OK. <%s> decrypted %d bytes.\n",
						zrtp_log_state2str(stream->zrtp->state), stream->zrtp,  stream->id, body, packet->length));
			} break;

			case zrtp_status_drop: {
				ZRTP_LOG(1, (_ZTU_,"Incoming: (%s) [%p:ssrc=%u] DROPPED. <%s>\n",
						zrtp_log_state2str(stream->zrtp->state), stream->zrtp, stream->id, body));
			} break;

			case zrtp_status_fail: {
				ZRTP_LOG(1, (_ZTU_,"Incoming: (%s) [%p:ssrc=%u] DECRYPT FAILED. <%s>\n",
						zrtp_log_state2str(stream->zrtp->state), stream->zrtp, stream->id, body));
			} break;

			default:
				break;
			}
		}

		zrtp_sys_free(elem);

		/*
		 * When zrtp_stream is in the pending clear state and other side wants to send plain
		 * traffic. We have to call zrtp_clear_stream().
		 */
		if (stream->zrtp->state == ZRTP_STATE_PENDINGCLEAR) {
			zrtp_stream_clear(stream->zrtp);
		}
	}
#if   (ZRTP_PLATFORM == ZP_WIN32) || (ZRTP_PLATFORM == ZP_WINCE)
	return 0;
#else
	return NULL;
#endif
}