/*----------------------------------------------------------------------------*/ 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; }
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 }
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 }