static bool udp_helper_recv(struct sa *src, struct mbuf *mb, void *arg) { struct menc_media *st = arg; unsigned int length; zrtp_status_t s; const char *proto_name = "srtp"; enum pkt_type ptype = get_packet_type(mb); if (drop_packets(st)) return true; length = (unsigned int)mbuf_get_left(mb); if (ptype == PKT_TYPE_RTCP) { proto_name = "srtcp"; s = zrtp_process_srtcp(st->zrtp_stream, (char *)mbuf_buf(mb), &length); } else if (ptype == PKT_TYPE_RTP || ptype == PKT_TYPE_ZRTP) { s = zrtp_process_srtp(st->zrtp_stream, (char *)mbuf_buf(mb), &length); } else return false; if (s != zrtp_status_ok) { if (s == zrtp_status_drop) return true; warning("zrtp: recv(port=%d): zrtp_process_%s: %d '%s'\n", sa_port(src), proto_name, s, zrtp_log_status2str(s)); return false; } mb->end = mb->pos + length; return false; }
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 }