diff --git a/include/uvgrtp/frame.hh b/include/uvgrtp/frame.hh index 46d652c..e6b0001 100644 --- a/include/uvgrtp/frame.hh +++ b/include/uvgrtp/frame.hh @@ -117,7 +117,7 @@ namespace uvgrtp { struct rtcp_sdes_item { uint8_t type = 0; uint8_t length = 0; - void *data = nullptr; + uint8_t *data = nullptr; }; struct rtcp_sdes_chunk { diff --git a/include/uvgrtp/rtcp.hh b/include/uvgrtp/rtcp.hh index 4648f12..24def2d 100644 --- a/include/uvgrtp/rtcp.hh +++ b/include/uvgrtp/rtcp.hh @@ -176,7 +176,7 @@ namespace uvgrtp { uvgrtp::frame::rtcp_app_packet *get_app_packet(uint32_t ssrc); /* Return a reference to vector that contains the sockets of all participants */ - std::vector& get_sockets(); + std::vector>& get_sockets(); /* Somebody joined the multicast group the owner of this RTCP instance is part of * Add it to RTCP participant list so we can start listening for reports @@ -388,7 +388,9 @@ namespace uvgrtp { /* Takes ownership of the frame */ rtp_error_t send_rtcp_packet_to_participants(uint8_t* frame, uint32_t frame_size, bool encrypt); - void free_participant(rtcp_participant* participant); + void free_participant(std::unique_ptr participant); + + void cleanup_participants(); /* Secure RTCP context */ std::shared_ptr srtcp_; @@ -451,7 +453,7 @@ namespace uvgrtp { /* The first value of RTP timestamp (aka t = 0) */ uint32_t rtp_ts_start_; - std::map participants_; + std::map> participants_; uint8_t num_receivers_; // maximum is 32 at the moment (5 bits) /* statistics for RTCP Sender and Receiver Reports */ @@ -459,13 +461,13 @@ namespace uvgrtp { /* If we expect frames from remote but haven't received anything from remote yet, * the participant resides in this vector until he's moved to participants_ */ - std::vector initial_participants_; + std::vector> initial_participants_; /* Vector of sockets the RTCP runner is listening to * * The socket are also stored here (in addition to participants_ map) so they're easier * to pass to poll when RTCP runner is listening to incoming packets */ - std::vector sockets_; + std::vector> sockets_; void (*sender_hook_)(uvgrtp::frame::rtcp_sender_report *); void (*receiver_hook_)(uvgrtp::frame::rtcp_receiver_report *); diff --git a/src/formats/h26x.cc b/src/formats/h26x.cc index 461c705..46176be 100644 --- a/src/formats/h26x.cc +++ b/src/formats/h26x.cc @@ -104,10 +104,20 @@ uvgrtp::formats::h26x::~h26x() { for (auto& frame : queued_) { - delete[] frame; + (void)uvgrtp::frame::dealloc_frame(frame); } queued_.clear(); + + for (auto& fragment : fragments_) + { + if (fragment != nullptr) + { + (void)uvgrtp::frame::dealloc_frame(fragment); + } + } + + fragments_.clear(); } /* NOTE: the area 0 - len (ie data[0] - data[len - 1]) must be addressable @@ -613,12 +623,14 @@ rtp_error_t uvgrtp::formats::h26x::packet_handler(int rce_flags, uvgrtp::frame:: if (dropped_ts_.find(frame->header.timestamp) != dropped_ts_.end()) { UVG_LOG_DEBUG("Received an RTP packet belonging to a dropped frame! Timestamp: %lu, seq: %u", frame->header.timestamp, frame->header.seq); + (void)uvgrtp::frame::dealloc_frame(frame); // free fragment memory return RTP_GENERIC_ERROR; } if (completed_ts_.find(frame->header.timestamp) != completed_ts_.end()) { UVG_LOG_DEBUG("Received an RTP packet belonging to a completed frame! Timestamp: %lu, seq: %u", frame->header.timestamp, frame->header.seq); + (void)uvgrtp::frame::dealloc_frame(frame); // free fragment memory return RTP_GENERIC_ERROR; } @@ -676,6 +688,7 @@ rtp_error_t uvgrtp::formats::h26x::packet_handler(int rce_flags, uvgrtp::frame:: if (frames_[fragment_ts].nal_type != nal_type) { UVG_LOG_ERROR("The fragment has different NAL type fragments before!"); + (void)uvgrtp::frame::dealloc_frame(frame); // free fragment memory return RTP_GENERIC_ERROR; } diff --git a/src/frame_queue.cc b/src/frame_queue.cc index 3248b1b..d9fad7a 100644 --- a/src/frame_queue.cc +++ b/src/frame_queue.cc @@ -210,7 +210,10 @@ rtp_error_t uvgrtp::frame_queue::enqueue_message(uint8_t *message, size_t messag /* If SRTP with proper encryption has been enabled but * RCE_SRTP_INPLACE_ENCRYPTION has **not** been enabled, make a copy of the memory block*/ if ((rce_flags_ & (RCE_SRTP | RCE_SRTP_INPLACE_ENCRYPTION | RCE_SRTP_NULL_CIPHER)) == RCE_SRTP) - message = (uint8_t *)memdup(message, message_len); + { + // TODO: This memory is never deleted + message = (uint8_t*)memdup(message, message_len); + } tmp.push_back({ message_len, message }); diff --git a/src/poll.cc b/src/poll.cc index eb5dae3..afb6014 100644 --- a/src/poll.cc +++ b/src/poll.cc @@ -53,7 +53,7 @@ rtp_error_t uvgrtp::poll::blocked_recv(std::shared_ptr socket, u return rtp_ret; } -rtp_error_t uvgrtp::poll::poll(std::vector& sockets, uint8_t *buf, size_t buf_len, int timeout, int *bytes_read) +rtp_error_t uvgrtp::poll::poll(std::vector>& sockets, uint8_t *buf, size_t buf_len, int timeout, int *bytes_read) { if (buf == nullptr || buf_len == 0) return RTP_INVALID_VALUE; @@ -68,7 +68,7 @@ rtp_error_t uvgrtp::poll::poll(std::vector& sockets, uint8_t *bu int ret; for (size_t i = 0; i < sockets.size(); ++i) { - fds[i].fd = sockets.at(i).get_raw_socket(); + fds[i].fd = sockets.at(i)->get_raw_socket(); fds[i].events = POLLIN | POLLERR; } @@ -87,7 +87,7 @@ rtp_error_t uvgrtp::poll::poll(std::vector& sockets, uint8_t *bu for (size_t i = 0; i < sockets.size(); ++i) { if (fds[i].revents & POLLIN) { - auto rtp_ret = sockets.at(i).recv(buf, buf_len, 0, bytes_read); + auto rtp_ret = sockets.at(i)->recv(buf, buf_len, 0, bytes_read); if (rtp_ret != RTP_OK) { UVG_LOG_ERROR("recv() for socket %d failed: %s", fds[i].fd, strerror(errno)); @@ -107,7 +107,7 @@ rtp_error_t uvgrtp::poll::poll(std::vector& sockets, uint8_t *bu FD_ZERO(&read_fds); for (size_t i = 0; i < sockets.size(); ++i) { - auto fd = sockets.at(i).get_raw_socket(); + auto fd = sockets.at(i)->get_raw_socket(); FD_SET(fd, &read_fds); } @@ -125,7 +125,7 @@ rtp_error_t uvgrtp::poll::poll(std::vector& sockets, uint8_t *bu } for (size_t i = 0; i < sockets.size(); ++i) { - auto rtp_ret = sockets.at(i).recv((uint8_t *)buf, (int)buf_len, 0, bytes_read); + auto rtp_ret = sockets.at(i)->recv((uint8_t *)buf, (int)buf_len, 0, bytes_read); if (rtp_ret != RTP_OK) { if (WSAGetLastError() == WSAEWOULDBLOCK) diff --git a/src/poll.hh b/src/poll.hh index c956049..ee83e9e 100644 --- a/src/poll.hh +++ b/src/poll.hh @@ -17,7 +17,7 @@ namespace uvgrtp { * * If some actions happens with the socket, return status * If the timeout is exceeded, return RTP_INTERRUPTED */ - rtp_error_t poll(std::vector& sockets, uint8_t *buf, size_t buf_len, int timeout, int *bytes_read); + rtp_error_t poll(std::vector>& sockets, uint8_t *buf, size_t buf_len, int timeout, int *bytes_read); /* TODO: */ rtp_error_t blocked_recv(std::shared_ptr socket, uint8_t *buf, size_t buf_len, int timeout, int *bytes_read); diff --git a/src/reception_flow.cc b/src/reception_flow.cc index 45ea927..3849461 100644 --- a/src/reception_flow.cc +++ b/src/reception_flow.cc @@ -48,7 +48,7 @@ void uvgrtp::reception_flow::clear_frames() frames_mtx_.lock(); for (auto& frame : frames_) { - delete[] frame; + (void)uvgrtp::frame::dealloc_frame(frame); } frames_.clear(); @@ -256,12 +256,12 @@ void uvgrtp::reception_flow::call_aux_handlers(uint32_t key, int rce_flags, uvgr case RTP_MULTIPLE_PKTS_READY: { while ((*aux.getter)(aux.arg, frame) == RTP_PKT_READY) - this->return_frame(*frame); + return_frame(*frame); } break; case RTP_PKT_READY: - this->return_frame(*frame); + return_frame(*frame); break; /* packet was not handled or only partially handled by the handler @@ -291,13 +291,13 @@ void uvgrtp::reception_flow::call_aux_handlers(uint32_t key, int rce_flags, uvgr case RTP_MULTIPLE_PKTS_READY: { while (aux.getter(frame) == RTP_PKT_READY) - this->return_frame(*frame); + return_frame(*frame); break; } case RTP_PKT_READY: { - this->return_frame(*frame); + return_frame(*frame); break; } @@ -461,7 +461,7 @@ void uvgrtp::reception_flow::process_packet(int rce_flags) } case RTP_PKT_MODIFIED: { - this->call_aux_handlers(handler.first, rce_flags, &frame); + call_aux_handlers(handler.first, rce_flags, &frame); break; } case RTP_GENERIC_ERROR: diff --git a/src/rtcp.cc b/src/rtcp.cc index a0f4758..6e03abb 100644 --- a/src/rtcp.cc +++ b/src/rtcp.cc @@ -81,7 +81,7 @@ uvgrtp::rtcp::rtcp(std::shared_ptr rtp, std::string cname, int rce_ memcpy(cname_, c, cname.length()); uint8_t length = (uint8_t)cname.length(); - cnameItem_ = { 1, length, (void*)cname_ }; + cnameItem_ = { 1, length, (uint8_t*)cname_ }; ourItems_.push_back(cnameItem_); } } @@ -100,7 +100,28 @@ uvgrtp::rtcp::~rtcp() stop(); } + cleanup_participants(); + ourItems_.clear(); + sockets_.clear(); +} + +void uvgrtp::rtcp::cleanup_participants() +{ + UVG_LOG_DEBUG("Removing all participants"); + + /* free all receiver statistic structs */ + for (auto& participant : participants_) + { + free_participant(std::move(participant.second)); + } + participants_.clear(); + + for (auto& participant : initial_participants_) + { + free_participant(std::move(participant)); + } + initial_participants_.clear(); } uvgrtp::rtcp_app_packet::rtcp_app_packet(const char* name, uint8_t subtype, uint32_t payload_len, const uint8_t* payload) @@ -122,7 +143,7 @@ uvgrtp::rtcp_app_packet::~rtcp_app_packet() { delete[] payload; } -void uvgrtp::rtcp::free_participant(rtcp_participant* participant) +void uvgrtp::rtcp::free_participant(std::unique_ptr participant) { participant->socket = nullptr; @@ -136,14 +157,27 @@ void uvgrtp::rtcp::free_participant(rtcp_participant* participant) } if (participant->sdes_frame) { + for (auto& chunk : participant->sdes_frame->chunks) + { + for (auto& item : chunk.items) + { + if (item.data != nullptr) + { + delete[] item.data; + } + } + } + delete participant->sdes_frame; } if (participant->app_frame) { + if (participant->app_frame->payload != nullptr) + { + delete[] participant->app_frame->payload; + } delete participant->app_frame; } - - delete participant; } rtp_error_t uvgrtp::rtcp::start() @@ -163,23 +197,11 @@ rtp_error_t uvgrtp::rtcp::start() rtp_error_t uvgrtp::rtcp::stop() { UVG_LOG_DEBUG("Stopping RTCP"); + // TODO: Make thread safe. I think this kind of works, but not in a flexible way if (!active_) { - UVG_LOG_DEBUG("Removing all participants"); - /* free all receiver statistic structs */ - for (auto& participant : participants_) - { - free_participant(participant.second); - } - participants_.clear(); - - for (auto& participant : initial_participants_) - { - free_participant(participant); - } - initial_participants_.clear(); - + cleanup_participants(); return RTP_OK; } @@ -320,7 +342,7 @@ rtp_error_t uvgrtp::rtcp::add_participant(std::string dst_addr, uint16_t dst_por } rtp_error_t ret; - rtcp_participant *p = new rtcp_participant(); + std::unique_ptr p = std::unique_ptr(new rtcp_participant()); zero_stats(&p->stats); @@ -328,7 +350,7 @@ rtp_error_t uvgrtp::rtcp::add_participant(std::string dst_addr, uint16_t dst_por if ((ret = p->socket->init(AF_INET, SOCK_DGRAM, 0)) != RTP_OK) { - delete p; + free_participant(std::move(p)); return ret; } @@ -336,7 +358,7 @@ rtp_error_t uvgrtp::rtcp::add_participant(std::string dst_addr, uint16_t dst_por if ((ret = p->socket->setsockopt(SOL_SOCKET, SO_REUSEADDR, (const char *)&enable, sizeof(int))) != RTP_OK) { - delete p; + free_participant(std::move(p)); return ret; } @@ -360,7 +382,7 @@ rtp_error_t uvgrtp::rtcp::add_participant(std::string dst_addr, uint16_t dst_por if ((ret = p->socket->setsockopt(SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv))) != RTP_OK) { - delete p; + free_participant(std::move(p)); return ret; } @@ -368,7 +390,7 @@ rtp_error_t uvgrtp::rtcp::add_participant(std::string dst_addr, uint16_t dst_por if ((ret = p->socket->bind(AF_INET, INADDR_ANY, src_port)) != RTP_OK) { - delete p; + free_participant(std::move(p)); return ret; } @@ -376,8 +398,8 @@ rtp_error_t uvgrtp::rtcp::add_participant(std::string dst_addr, uint16_t dst_por p->address = p->socket->create_sockaddr(AF_INET, dst_addr, dst_port); p->stats.clock_rate = clock_rate; - initial_participants_.push_back(p); - sockets_.push_back(*p->socket); + sockets_.push_back(p->socket); + initial_participants_.push_back(std::move(p)); return RTP_OK; } @@ -395,10 +417,10 @@ rtp_error_t uvgrtp::rtcp::add_participant(uint32_t ssrc) * create a "fake" participant that is only used for storing statistics information */ if (initial_participants_.empty()) { - participants_[ssrc] = new rtcp_participant(); + participants_[ssrc] = std::unique_ptr (new rtcp_participant()); zero_stats(&participants_[ssrc]->stats); } else { - participants_[ssrc] = initial_participants_.back(); + participants_[ssrc] = std::move(initial_participants_.back()); initial_participants_.pop_back(); } num_receivers_++; @@ -691,7 +713,7 @@ uvgrtp::frame::rtcp_app_packet* uvgrtp::rtcp::get_app_packet(uint32_t ssrc) return frame; } -std::vector& uvgrtp::rtcp::get_sockets() +std::vector>& uvgrtp::rtcp::get_sockets() { return sockets_; } @@ -847,48 +869,47 @@ rtp_error_t uvgrtp::rtcp::update_participant_seq(uint32_t ssrc, uint16_t seq) return RTP_GENERIC_ERROR; } - auto p = participants_[ssrc]; - uint16_t udelta = seq - p->stats.max_seq; + uint16_t udelta = seq - participants_[ssrc]->stats.max_seq; /* Source is not valid until MIN_SEQUENTIAL packets with * sequential sequence numbers have been received. */ - if (p->probation) + if (participants_[ssrc]->probation) { /* packet is in sequence */ - if (seq == p->stats.max_seq + 1) + if (seq == participants_[ssrc]->stats.max_seq + 1) { - p->probation--; - p->stats.max_seq = seq; - if (!p->probation) + participants_[ssrc]->probation--; + participants_[ssrc]->stats.max_seq = seq; + if (!participants_[ssrc]->probation) { uvgrtp::rtcp::init_participant_seq(ssrc, seq); return RTP_OK; } } else { - p->probation = MIN_SEQUENTIAL - 1; - p->stats.max_seq = seq; + participants_[ssrc]->probation = MIN_SEQUENTIAL - 1; + participants_[ssrc]->stats.max_seq = seq; } return RTP_NOT_READY; } else if (udelta < MAX_DROPOUT) { /* in order, with permissible gap */ - if (seq < p->stats.max_seq) + if (seq < participants_[ssrc]->stats.max_seq) { /* Sequence number wrapped - count another 64K cycle. */ - p->stats.cycles += 1; + participants_[ssrc]->stats.cycles += 1; } - p->stats.max_seq = seq; + participants_[ssrc]->stats.max_seq = seq; } else if (udelta <= RTP_SEQ_MOD - MAX_MISORDER) { /* the sequence number made a very large jump */ - if (seq == p->stats.bad_seq) + if (seq == participants_[ssrc]->stats.bad_seq) { /* Two sequential packets -- assume that the other side * restarted without telling us so just re-sync * (i.e., pretend this was the first packet). */ uvgrtp::rtcp::init_participant_seq(ssrc, seq); } else { - p->stats.bad_seq = (seq + 1) & (RTP_SEQ_MOD - 1); - UVG_LOG_ERROR("Invalid sequence number. Seq jump: %u -> %u", p->stats.max_seq, seq); + participants_[ssrc]->stats.bad_seq = (seq + 1) & (RTP_SEQ_MOD - 1); + UVG_LOG_ERROR("Invalid sequence number. Seq jump: %u -> %u", participants_[ssrc]->stats.max_seq, seq); return RTP_GENERIC_ERROR; } } else { @@ -917,10 +938,8 @@ bool uvgrtp::rtcp::collision_detected(uint32_t ssrc, const sockaddr_in& src_addr return false; } - auto sender = participants_.at(ssrc); - - if (src_addr.sin_port != sender->address.sin_port && - src_addr.sin_addr.s_addr != sender->address.sin_addr.s_addr) + if (src_addr.sin_port != participants_.at(ssrc)->address.sin_port && + src_addr.sin_addr.s_addr != participants_.at(ssrc)->address.sin_addr.s_addr) { return true; } @@ -930,31 +949,32 @@ bool uvgrtp::rtcp::collision_detected(uint32_t ssrc, const sockaddr_in& src_addr void uvgrtp::rtcp::update_session_statistics(const uvgrtp::frame::rtp_frame *frame) { - auto p = participants_[frame->header.ssrc]; + participants_[frame->header.ssrc]->stats.received_rtp_packet = true; - p->stats.received_rtp_packet = true; - - p->stats.received_pkts += 1; - p->stats.received_bytes += (uint32_t)frame->payload_len; + participants_[frame->header.ssrc]->stats.received_pkts += 1; + participants_[frame->header.ssrc]->stats.received_bytes += (uint32_t)frame->payload_len; /* calculate number of dropped packets */ - int extended_max = (static_cast(p->stats.cycles) << 16) + p->stats.max_seq; - int expected = extended_max - p->stats.base_seq + 1; + int extended_max = (static_cast(participants_[frame->header.ssrc]->stats.cycles) << 16) + + participants_[frame->header.ssrc]->stats.max_seq; + int expected = extended_max - participants_[frame->header.ssrc]->stats.base_seq + 1; - int dropped = expected - p->stats.received_pkts; - p->stats.dropped_pkts = dropped >= 0 ? dropped : 0; + int dropped = expected - participants_[frame->header.ssrc]->stats.received_pkts; + participants_[frame->header.ssrc]->stats.dropped_pkts = dropped >= 0 ? dropped : 0; // the arrival time expressed as an RTP timestamp - uint32_t arrival = p->stats.initial_rtp + - (uint32_t)uvgrtp::clock::ntp::diff_now(p->stats.initial_ntp)*(p->stats.clock_rate / 1000); + uint32_t arrival = participants_[frame->header.ssrc]->stats.initial_rtp + + (uint32_t)uvgrtp::clock::ntp::diff_now(participants_[frame->header.ssrc]->stats.initial_ntp)* + (participants_[frame->header.ssrc]->stats.clock_rate / 1000); // calculate interarrival jitter. See RFC 3550 A.8 uint32_t transit = arrival - frame->header.timestamp; // A.8: int transit = arrival - r->ts - uint32_t trans_difference = std::abs((int)(transit - p->stats.transit)); + uint32_t trans_difference = std::abs((int)(transit - participants_[frame->header.ssrc]->stats.transit)); // update statistics - p->stats.transit = transit; - p->stats.jitter += (1.f / 16.f) * ((double)trans_difference - p->stats.jitter); + participants_[frame->header.ssrc]->stats.transit = transit; + participants_[frame->header.ssrc]->stats.jitter += (1.f / 16.f) * + ((double)trans_difference - participants_[frame->header.ssrc]->stats.jitter); } /* RTCP packet handler is responsible for doing two things: @@ -1330,8 +1350,6 @@ rtp_error_t uvgrtp::rtcp::handle_sdes_packet(uint8_t* packet, size_t& read_ptr, auto frame = new uvgrtp::frame::rtcp_sdes_packet; frame->header = header; - // TODO: The SDES parsing is incorrect at the moment - // Read SDES chunks while (read_ptr + SSRC_CSRC_SIZE <= packet_end) { @@ -1348,7 +1366,7 @@ rtp_error_t uvgrtp::rtcp::handle_sdes_packet(uint8_t* packet, size_t& read_ptr, if (read_ptr + item.length <= packet_end) { - item.data = (void*)new uint8_t[item.length]; + item.data = new uint8_t[item.length]; memcpy(item.data, &packet[read_ptr], item.length); read_ptr += item.length; @@ -1363,7 +1381,6 @@ rtp_error_t uvgrtp::rtcp::handle_sdes_packet(uint8_t* packet, size_t& read_ptr, } frame->chunks.push_back(chunk); - } sdes_mutex_.lock(); @@ -1415,8 +1432,7 @@ rtp_error_t uvgrtp::rtcp::handle_bye_packet(uint8_t* packet, size_t& read_ptr, } UVG_LOG_DEBUG("Destroying participant with BYE"); - participants_[ssrc]->socket = nullptr; - delete participants_[ssrc]; + free_participant(std::move(participants_[ssrc])); participants_.erase(ssrc); } @@ -1445,9 +1461,16 @@ rtp_error_t uvgrtp::rtcp::handle_app_packet(uint8_t* packet, size_t& read_ptr, size_t application_data_size = packet_end - read_ptr; - // application data is saved to payload - frame->payload = new uint8_t[application_data_size]; - memcpy(frame->payload, &packet[read_ptr], application_data_size); + if (application_data_size > 0) + { + // application data is saved to payload + frame->payload = new uint8_t[application_data_size]; + memcpy(frame->payload, &packet[read_ptr], application_data_size); + } + else + { + frame->payload = nullptr; + } app_mutex_.lock(); if (app_hook_) { diff --git a/src/socket.cc b/src/socket.cc index 25e8e00..53b57c9 100644 --- a/src/socket.cc +++ b/src/socket.cc @@ -170,6 +170,8 @@ std::string uvgrtp::socket::sockaddr_to_string(const sockaddr_in& addr) const std::string string(c_string); string.append(":" + std::to_string(ntohs(addr.sin_port))); + + delete[] c_string; return string; } diff --git a/src/zrtp.cc b/src/zrtp.cc index 3fd3c8b..5b382b5 100644 --- a/src/zrtp.cc +++ b/src/zrtp.cc @@ -646,7 +646,7 @@ rtp_error_t uvgrtp::zrtp::init(uint32_t ssrc, std::shared_ptr so "to select which streams should not perform DH"); } - // perform Diffie-Helmann (DH) + // perform Diffie-Hellman (DH) ret = init_dhm(ssrc, socket, addr); zrtp_mtx_.unlock(); } diff --git a/test/test_3_rtcp.cpp b/test/test_3_rtcp.cpp index a1210e2..e2d48aa 100644 --- a/test/test_3_rtcp.cpp +++ b/test/test_3_rtcp.cpp @@ -244,6 +244,17 @@ void sdes_hook(uvgrtp::frame::rtcp_sdes_packet* frame) { std::cout << "Got SDES frame with " << frame->chunks.size() << " chunk" << std::endl; + for (auto& chunk : frame->chunks) + { + for (auto& item : chunk.items) + { + if (item.data != nullptr) + { + delete[] item.data; + } + } + } + /* RTCP frames can be deallocated using delete */ delete frame; } @@ -258,6 +269,10 @@ void app_hook(uvgrtp::frame::rtcp_app_packet* frame) std::cout << "ssrc: " << frame->ssrc << std::endl; std::cout << "Name: " << name << std::endl; std::cout << "Payload length " << payload_len << " and content: " << payload << std::endl; + if (payload_len > 0) + { + delete[] frame->payload; + } delete frame; } diff --git a/test/test_5_srtp_zrtp.cpp b/test/test_5_srtp_zrtp.cpp index 51b400b..27f6e7f 100644 --- a/test/test_5_srtp_zrtp.cpp +++ b/test/test_5_srtp_zrtp.cpp @@ -188,6 +188,9 @@ TEST(EncryptionTests, zrtp) { receiver_thread->join(); } + + cleanup_sess(ctx, sender_session); + cleanup_sess(ctx, receiver_session); } TEST(EncryptionTests, zrtp_multistream)