Merge branch 'duplicate_pkts'
This commit is contained in:
commit
69a02c05a8
|
@ -50,8 +50,11 @@ uvgrtp::formats::FRAG_TYPE uvgrtp::formats::h264::get_fragment_type(uvgrtp::fram
|
|||
bool first_frag = frame->payload[1] & 0x80;
|
||||
bool last_frag = frame->payload[1] & 0x40;
|
||||
|
||||
if ((frame->payload[0] & 0x1f) == uvgrtp::formats::H264_PKT_AGGR)
|
||||
return uvgrtp::formats::FRAG_TYPE::FT_AGGR;
|
||||
if ((frame->payload[0] & 0x1f) == uvgrtp::formats::H264_STAP_A)
|
||||
return uvgrtp::formats::FRAG_TYPE::FT_AGGR; // STAP-A packet, RFC 6184 5.7.1
|
||||
|
||||
if ((frame->payload[0] & 0x1f) == uvgrtp::formats::H264_STAP_B)
|
||||
return uvgrtp::formats::FRAG_TYPE::FT_STAP_B; // STAP-B packet, RFC 6184 5.7.1
|
||||
|
||||
if ((frame->payload[0] & 0x1f) != uvgrtp::formats::H264_PKT_FRAG)
|
||||
return uvgrtp::formats::FRAG_TYPE::FT_NOT_FRAG; // Single NAL unit
|
||||
|
@ -93,6 +96,14 @@ void uvgrtp::formats::h264::clear_aggregation_info()
|
|||
aggr_pkt_info_.aggr_pkt.clear();
|
||||
}
|
||||
|
||||
rtp_error_t uvgrtp::formats::h264::add_aggregate_packet(uint8_t* data, size_t data_len)
|
||||
{
|
||||
/* If there is more data coming in (possibly another small packet)
|
||||
* create entry to "aggr_pkt_info_" to construct an aggregation packet */
|
||||
aggr_pkt_info_.nalus.push_back(std::make_pair(data_len, data));
|
||||
return RTP_OK;
|
||||
}
|
||||
|
||||
rtp_error_t uvgrtp::formats::h264::finalize_aggregation_pkt()
|
||||
{
|
||||
rtp_error_t ret = RTP_OK;
|
||||
|
@ -110,7 +121,7 @@ rtp_error_t uvgrtp::formats::h264::finalize_aggregation_pkt()
|
|||
|
||||
/* create header for the packet and craft the aggregation packet
|
||||
* according to the format defined in RFC 6184 */
|
||||
aggr_pkt_info_.fu_indicator[0] = (0 << 7) | ((nri & 0x3) << 5) | H264_PKT_AGGR;
|
||||
aggr_pkt_info_.fu_indicator[0] = (0 << 7) | ((nri & 0x3) << 5) | H264_STAP_A;
|
||||
|
||||
aggr_pkt_info_.aggr_pkt.push_back(
|
||||
std::make_pair(HEADER_SIZE_H264_FU, aggr_pkt_info_.fu_indicator)
|
||||
|
|
|
@ -24,7 +24,8 @@ namespace uvgrtp {
|
|||
enum H264_NAL_TYPES {
|
||||
H264_NON_IDR = 1,
|
||||
H264_IDR = 5,
|
||||
H264_PKT_AGGR = 24,
|
||||
H264_STAP_A = 24,
|
||||
H264_STAP_B = 25,
|
||||
H264_PKT_FRAG = 28
|
||||
};
|
||||
|
||||
|
@ -58,6 +59,9 @@ namespace uvgrtp {
|
|||
/* Clear aggregation buffers */
|
||||
virtual void clear_aggregation_info();
|
||||
|
||||
// Constructs aggregate packets
|
||||
virtual rtp_error_t add_aggregate_packet(uint8_t* data, size_t data_len);
|
||||
|
||||
// constructs h264 RTP header with correct values
|
||||
virtual rtp_error_t fu_division(uint8_t* data, size_t data_len, size_t payload_size);
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <iostream>
|
||||
#include <unordered_map>
|
||||
#include <queue>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -45,6 +46,10 @@ constexpr int GARBAGE_COLLECTION_INTERVAL_MS = 100;
|
|||
// any value less than 30 minutes is ok here, since that is how long it takes to go through all timestamps
|
||||
constexpr int TIME_TO_KEEP_TRACK_OF_PREVIOUS_FRAMES_MS = 5000;
|
||||
|
||||
// how many RTP frames and sequence numbers get saved for duplicate detection
|
||||
constexpr int RECEIVED_FRAMES = 5000;
|
||||
constexpr int RECEIVED_SEQ_NUMBERS = UINT16_MAX / 2;
|
||||
|
||||
static inline uint8_t determine_start_prefix_precense(uint32_t value, bool& additional_byte)
|
||||
{
|
||||
additional_byte = false;
|
||||
|
@ -96,6 +101,9 @@ uvgrtp::formats::h26x::h26x(std::shared_ptr<uvgrtp::socket> socket, std::shared_
|
|||
media(socket, rtp, rce_flags),
|
||||
queued_(),
|
||||
frames_(),
|
||||
received_frames_(),
|
||||
received_timestamps_(),
|
||||
received_seq_nums_(),
|
||||
fragments_(UINT16_MAX + 1, nullptr),
|
||||
dropped_ts_(),
|
||||
completed_ts_(),
|
||||
|
@ -601,10 +609,43 @@ rtp_error_t uvgrtp::formats::h26x::handle_aggregation_packet(uvgrtp::frame::rtp_
|
|||
return RTP_MULTIPLE_PKTS_READY;
|
||||
}
|
||||
|
||||
bool uvgrtp::formats::h26x::is_duplicate_frame(uint32_t timestamp, uint16_t seq_num)
|
||||
{
|
||||
//UVG_LOG_DEBUG("ts: %u, seq num: %u, ts storage size: %i, seq storage size %i", timestamp, seq_num, received_timestamps_.size(), received_seq_nums_.size());
|
||||
if (received_timestamps_.find(timestamp) != received_timestamps_.end()) {
|
||||
|
||||
//UVG_LOG_DEBUG("duplicate rtp ts received, checking seq num");
|
||||
if (received_seq_nums_.find(seq_num) != received_seq_nums_.end()) {
|
||||
|
||||
//UVG_LOG_DEBUG("duplicate seq num received, discarding frame");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
pkt_stats stats = {timestamp, seq_num};
|
||||
|
||||
received_timestamps_.insert(timestamp);
|
||||
received_seq_nums_.insert(seq_num);
|
||||
received_frames_.push_back(stats);
|
||||
|
||||
if (received_frames_.size() > RECEIVED_FRAMES) {
|
||||
received_timestamps_.erase(received_frames_.front().ts);
|
||||
|
||||
if (received_seq_nums_.size() > RECEIVED_SEQ_NUMBERS) {
|
||||
received_seq_nums_.erase(received_frames_.front().seq);
|
||||
}
|
||||
received_frames_.pop_front();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
rtp_error_t uvgrtp::formats::h26x::packet_handler(int rce_flags, uvgrtp::frame::rtp_frame** out)
|
||||
{
|
||||
uvgrtp::frame::rtp_frame* frame = *out;
|
||||
|
||||
if (is_duplicate_frame(frame->header.timestamp, frame->header.seq)) {
|
||||
return RTP_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
// aggregate, start, middle, end or single NAL
|
||||
uvgrtp::formats::FRAG_TYPE frag_type = get_fragment_type(frame);
|
||||
|
||||
|
@ -623,12 +664,19 @@ rtp_error_t uvgrtp::formats::h26x::packet_handler(int rce_flags, uvgrtp::frame::
|
|||
return RTP_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
|
||||
if (frag_type == uvgrtp::formats::FRAG_TYPE::FT_AGGR) {
|
||||
|
||||
// handle aggregate packets (packets with multiple NAL units in them)
|
||||
return handle_aggregation_packet(out, get_payload_header_size(), rce_flags);
|
||||
}
|
||||
else if (frag_type == uvgrtp::formats::FRAG_TYPE::FT_STAP_B) {
|
||||
// Handle H264 STAP-B packet, RFC 6184 5.7.1
|
||||
// DON is made up of the 16 bits after STAP-B header.
|
||||
// Commented out to prevent werrors, DON is not currently used anywhere.
|
||||
/* uint16_t don = ((uint16_t)frame->payload[1] << 8) | frame->payload[2]; */
|
||||
|
||||
// payload_header_size + 2 comes from DON field in STAP-B packets being 16 bits long
|
||||
return handle_aggregation_packet(out, get_payload_header_size()+2, rce_flags);
|
||||
}
|
||||
else if (frag_type == uvgrtp::formats::FRAG_TYPE::FT_NOT_FRAG) { // Single NAL unit
|
||||
|
||||
// TODO: Check if previous dependencies have been sent forward
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <deque>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <unordered_set>
|
||||
#ifdef _WIN32
|
||||
#include <ws2def.h>
|
||||
#include <ws2ipdef.h>
|
||||
|
@ -30,7 +31,8 @@ namespace uvgrtp {
|
|||
FT_START = 1, /* frame contains a fragment with S bit set */
|
||||
FT_MIDDLE = 2, /* frame is fragment but not S or E fragment */
|
||||
FT_END = 3, /* frame contains a fragment with E bit set */
|
||||
FT_AGGR = 4 /* aggregation packet */
|
||||
FT_AGGR = 4, /* aggregation packet (without DON) */
|
||||
FT_STAP_B = 5 /* aggregation packet, H264 STAP-B, RFC 6184 5.7.1 */
|
||||
};
|
||||
|
||||
enum class NAL_TYPE {
|
||||
|
@ -173,9 +175,20 @@ namespace uvgrtp {
|
|||
rtp_error_t reconstruction(uvgrtp::frame::rtp_frame** out,
|
||||
int rce_flags, uint32_t frame_timestamp, const uint8_t sizeof_fu_headers);
|
||||
|
||||
bool is_duplicate_frame(uint32_t timestamp, uint16_t seq_num);
|
||||
|
||||
std::deque<uvgrtp::frame::rtp_frame*> queued_;
|
||||
std::unordered_map<uint32_t, h26x_info_t> frames_;
|
||||
|
||||
// Save received RTP frame stats, used to check for duplicates in is_duplicate_frame()
|
||||
struct pkt_stats {
|
||||
uint32_t ts;
|
||||
uint16_t seq;
|
||||
};
|
||||
std::deque<pkt_stats> received_frames_;
|
||||
std::unordered_set<uint32_t> received_timestamps_;
|
||||
std::unordered_set<uint16_t> received_seq_nums_;
|
||||
|
||||
// Holds all possible fragments in sequence number order
|
||||
std::vector<uvgrtp::frame::rtp_frame*> fragments_;
|
||||
|
||||
|
|
|
@ -55,7 +55,11 @@ void uvgrtp::holepuncher::keepalive()
|
|||
{
|
||||
UVG_LOG_DEBUG("Starting holepuncher");
|
||||
|
||||
// TODO: Make this follow https://datatracker.ietf.org/doc/html/rfc6263
|
||||
/* RFC 6263 https://datatracker.ietf.org/doc/html/rfc6263
|
||||
* The RFC above describes several methods of implementing keep-alive. One of them (described in section 4.1) is
|
||||
* sending empty (0-Byte) packets, which is implemented here.
|
||||
* Another method (section 4.3) is multiplexing RTCP and RTP packets into a single socket, which keeps the connection
|
||||
* alive at all times with RTCP packets. This will be implemented into uvgRTP in the future. */
|
||||
while (active_) {
|
||||
if (uvgrtp::clock::ntp::diff_now(last_dgram_sent_) < THRESHOLD) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
|
|
|
@ -45,6 +45,10 @@ rtp_error_t uvgrtp::base_srtp::derive_key(int label, size_t key_size,
|
|||
|
||||
input[7] ^= label;
|
||||
|
||||
/* SRTP in uvgRTP uses ECB encryption for encrypting the session keys. For encrypting SRTP payloads, AES CTR mode is used.
|
||||
* ECB encryption is fine for encrypting short messages. However, using a different encryption method for
|
||||
* encrypting the keys too might be a more secure solution and should be explored. */
|
||||
|
||||
uvgrtp::crypto::aes::ecb ecb(key, key_size); // srtp_ctx_->n_e);
|
||||
ecb.encrypt(ks, input, UVG_IV_LENGTH);
|
||||
|
||||
|
|
250
src/zrtp.cc
250
src/zrtp.cc
|
@ -11,6 +11,7 @@
|
|||
#include "crypto.hh"
|
||||
#include "random.hh"
|
||||
#include "debug.hh"
|
||||
#include "uvgrtp/clock.hh"
|
||||
#ifdef _WIN32
|
||||
#include <ws2ipdef.h>
|
||||
#else
|
||||
|
@ -374,28 +375,31 @@ rtp_error_t uvgrtp::zrtp::begin_session()
|
|||
auto hello = uvgrtp::zrtp_msg::hello(session_);
|
||||
auto hello_ack = uvgrtp::zrtp_msg::hello_ack();
|
||||
bool hello_recv = false;
|
||||
int rto = 50;
|
||||
|
||||
for (int i = 0; i < 20; ++i) {
|
||||
|
||||
// This was disabled when remote_addresses were removed from socket
|
||||
// -> get_socket_path_to_string will need some changes, <--TODO
|
||||
|
||||
//std::string path = local_socket_->get_socket_path_string();
|
||||
//UVG_LOG_DEBUG("Sending ZRTP hello # %i, path: %s", i + 1, path.c_str());
|
||||
UVG_LOG_DEBUG("Sending ZRTP hello # %i", i + 1);
|
||||
|
||||
uvgrtp::clock::hrc::hrc_t start = uvgrtp::clock::hrc::now();
|
||||
int interval = 50;
|
||||
int i = 1;
|
||||
|
||||
while (true) {
|
||||
long int next_sendslot = i * interval;
|
||||
long int run_time = (long int)uvgrtp::clock::hrc::diff_now(start);
|
||||
long int diff_ms = next_sendslot - run_time;
|
||||
int type = 0;
|
||||
int poll_timeout = (int)diff_ms;
|
||||
|
||||
if (hello.send_msg(local_socket_, remote_addr_, remote_ip6_addr_) != RTP_OK) {
|
||||
UVG_LOG_ERROR("Failed to send Hello message");
|
||||
if (diff_ms < 0) {
|
||||
UVG_LOG_DEBUG("Sending ZRTP hello # %i", i);
|
||||
if (hello.send_msg(local_socket_, remote_addr_, remote_ip6_addr_) != RTP_OK) {
|
||||
UVG_LOG_ERROR("Failed to send Hello message");
|
||||
}
|
||||
++i;
|
||||
}
|
||||
else if (receiver_.recv_msg(local_socket_, rto, 0, type) == RTP_OK) {
|
||||
else if (receiver_.recv_msg(local_socket_, poll_timeout, 0, type) == RTP_OK) {
|
||||
/* We received something interesting, either Hello message from remote in which case
|
||||
* we need to send HelloACK message back and keep sending our Hello until HelloACK is received,
|
||||
* or HelloACK message which means we can stop sending our */
|
||||
* we need to send HelloACK message back and keep sending our Hello until HelloACK is received,
|
||||
* or HelloACK message which means we can stop sending our */
|
||||
|
||||
/* We received Hello message from remote, parse it and send */
|
||||
/* We received Hello message from remote, parse it and send */
|
||||
if (type == ZRTP_FT_HELLO) {
|
||||
UVG_LOG_DEBUG("Got ZRTP Hello. Sending Hello ACK");
|
||||
hello_ack.send_msg(local_socket_, remote_addr_, remote_ip6_addr_);
|
||||
|
@ -410,12 +414,12 @@ rtp_error_t uvgrtp::zrtp::begin_session()
|
|||
if (session_.capabilities.version != ZRTP_VERSION) {
|
||||
|
||||
/* Section 4.1.1:
|
||||
*
|
||||
* "If an endpoint receives a Hello message with an unsupported
|
||||
* version number that is lower than the endpoint's current Hello
|
||||
* message, the endpoint MUST send an Error message (Section 5.9)
|
||||
* indicating failure to support this ZRTP version."
|
||||
*/
|
||||
*
|
||||
* "If an endpoint receives a Hello message with an unsupported
|
||||
* version number that is lower than the endpoint's current Hello
|
||||
* message, the endpoint MUST send an Error message (Section 5.9)
|
||||
* indicating failure to support this ZRTP version."
|
||||
*/
|
||||
if (session_.capabilities.version < ZRTP_VERSION) {
|
||||
UVG_LOG_ERROR("Remote supports version %d, uvgRTP supports %d. Session cannot continue!",
|
||||
session_.capabilities.version, ZRTP_VERSION);
|
||||
|
@ -424,14 +428,14 @@ rtp_error_t uvgrtp::zrtp::begin_session()
|
|||
}
|
||||
|
||||
UVG_LOG_WARN("ZRTP Protocol version %u not supported, keep sending Hello Messages",
|
||||
session_.capabilities.version);
|
||||
session_.capabilities.version);
|
||||
hello_recv = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* We received ACK for our Hello message.
|
||||
* Make sure we've received Hello message also before exiting */
|
||||
} else if (type == ZRTP_FT_HELLO_ACK) {
|
||||
/* We received ACK for our Hello message.
|
||||
* Make sure we've received Hello message also before exiting */
|
||||
}
|
||||
else if (type == ZRTP_FT_HELLO_ACK) {
|
||||
|
||||
if (hello_recv)
|
||||
{
|
||||
|
@ -442,18 +446,23 @@ rtp_error_t uvgrtp::zrtp::begin_session()
|
|||
{
|
||||
UVG_LOG_DEBUG("Got Hello ACK without Hello!");
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
/* at this point we do not care about other messages */
|
||||
UVG_LOG_DEBUG("Got an unknown ZRTP message!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UVG_LOG_DEBUG("Did not get any ZRTP messages on try # %i", i + 1);
|
||||
UVG_LOG_DEBUG("Did not get any ZRTP messages on try # %i", i);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(diff_ms));
|
||||
if (interval < 200) {
|
||||
interval *= 2;
|
||||
}
|
||||
}
|
||||
if (i > 20) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (rto < 200)
|
||||
rto *= 2;
|
||||
}
|
||||
|
||||
/* Hello timed out, perhaps remote did not answer at all or it has an incompatible ZRTP version in use. */
|
||||
|
@ -470,7 +479,6 @@ rtp_error_t uvgrtp::zrtp::init_session(int key_agreement)
|
|||
session_.sas_type = B32;
|
||||
|
||||
int type = 0;
|
||||
int rto = 0;
|
||||
auto commit = uvgrtp::zrtp_msg::commit(session_);
|
||||
|
||||
/* First check if remote has already sent the message.
|
||||
|
@ -487,13 +495,23 @@ rtp_error_t uvgrtp::zrtp::init_session(int key_agreement)
|
|||
* This assumption may prove to be false if remote also sends Commit message
|
||||
* and Commit contention is resolved in their favor. */
|
||||
session_.role = INITIATOR;
|
||||
rto = 150;
|
||||
uvgrtp::clock::hrc::hrc_t start = uvgrtp::clock::hrc::now();
|
||||
int interval = 150;
|
||||
int i = 1;
|
||||
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
if (commit.send_msg(local_socket_, remote_addr_, remote_ip6_addr_) != RTP_OK) {
|
||||
UVG_LOG_ERROR("Failed to send Commit message!");
|
||||
while (true) {
|
||||
long int next_sendslot = i * interval;
|
||||
long int run_time = (long int)uvgrtp::clock::hrc::diff_now(start);
|
||||
long int diff_ms = next_sendslot - run_time;
|
||||
int poll_timeout = (int)diff_ms;
|
||||
|
||||
if (diff_ms < 0) {
|
||||
if (commit.send_msg(local_socket_, remote_addr_, remote_ip6_addr_) != RTP_OK) {
|
||||
UVG_LOG_ERROR("Failed to send Commit message!");
|
||||
}
|
||||
++i;
|
||||
}
|
||||
else if (receiver_.recv_msg(local_socket_, rto, 0, type) == RTP_OK) {
|
||||
else if (receiver_.recv_msg(local_socket_, poll_timeout, 0, type) == RTP_OK) {
|
||||
|
||||
/* As per RFC 6189, if both parties have sent Commit message and the mode is DH,
|
||||
* hvi shall determine who is the initiator (the party with larger hvi is initiator) */
|
||||
|
@ -512,11 +530,17 @@ rtp_error_t uvgrtp::zrtp::init_session(int key_agreement)
|
|||
return RTP_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (rto < 1200)
|
||||
rto *= 2;
|
||||
else
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(diff_ms));
|
||||
if (interval < 1200) {
|
||||
interval *= 2;
|
||||
}
|
||||
}
|
||||
if (i > 10) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remote didn't send us any messages, it can be considered dead
|
||||
* and ZRTP cannot thus continue any further */
|
||||
return RTP_TIMEOUT;
|
||||
|
@ -525,15 +549,24 @@ rtp_error_t uvgrtp::zrtp::init_session(int key_agreement)
|
|||
rtp_error_t uvgrtp::zrtp::dh_part1()
|
||||
{
|
||||
auto dhpart = uvgrtp::zrtp_msg::dh_key_exchange(session_, 1);
|
||||
int rto = 150;
|
||||
int type = 0;
|
||||
uvgrtp::clock::hrc::hrc_t start = uvgrtp::clock::hrc::now();
|
||||
int interval = 150;
|
||||
int i = 1;
|
||||
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
if (dhpart.send_msg(local_socket_, remote_addr_, remote_ip6_addr_) != RTP_OK) {
|
||||
UVG_LOG_ERROR("Failed to send DHPart1 Message!");
|
||||
while (true) {
|
||||
long int next_sendslot = i * interval;
|
||||
long int run_time = (long int)uvgrtp::clock::hrc::diff_now(start);
|
||||
long int diff_ms = next_sendslot - run_time;
|
||||
int poll_timeout = (int)diff_ms;
|
||||
|
||||
if (diff_ms < 0) {
|
||||
if (dhpart.send_msg(local_socket_, remote_addr_, remote_ip6_addr_) != RTP_OK) {
|
||||
UVG_LOG_ERROR("Failed to send DHPart1 Message!");
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
if (receiver_.recv_msg(local_socket_, rto, 0, type) == RTP_OK) {
|
||||
if (receiver_.recv_msg(local_socket_, poll_timeout, 0, type) == RTP_OK) {
|
||||
if (type == ZRTP_FT_DH_PART2) {
|
||||
if (dhpart.parse_msg(receiver_, session_) != RTP_OK) {
|
||||
UVG_LOG_ERROR("Failed to parse DHPart2 Message!");
|
||||
|
@ -548,9 +581,16 @@ rtp_error_t uvgrtp::zrtp::dh_part1()
|
|||
return RTP_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (rto < 1200)
|
||||
rto *= 2;
|
||||
else
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(diff_ms));
|
||||
if (interval < 1200) {
|
||||
interval *= 2;
|
||||
}
|
||||
}
|
||||
if (i > 10) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return RTP_TIMEOUT;
|
||||
|
@ -559,7 +599,6 @@ rtp_error_t uvgrtp::zrtp::dh_part1()
|
|||
rtp_error_t uvgrtp::zrtp::dh_part2()
|
||||
{
|
||||
int type = 0;
|
||||
int rto = 150;
|
||||
rtp_error_t ret = RTP_OK;
|
||||
auto dhpart = uvgrtp::zrtp_msg::dh_key_exchange(session_, 2);
|
||||
|
||||
|
@ -572,23 +611,40 @@ rtp_error_t uvgrtp::zrtp::dh_part2()
|
|||
* Now we must generate shared secrets (DHResult, total_hash, and s0) */
|
||||
generate_shared_secrets_dh();
|
||||
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
if ((ret = dhpart.send_msg(local_socket_, remote_addr_, remote_ip6_addr_)) != RTP_OK) {
|
||||
UVG_LOG_ERROR("Failed to send DHPart2 Message!");
|
||||
return ret;
|
||||
}
|
||||
uvgrtp::clock::hrc::hrc_t start = uvgrtp::clock::hrc::now();
|
||||
int interval = 150;
|
||||
int i = 1;
|
||||
|
||||
if (receiver_.recv_msg(local_socket_, rto, 0, type) == RTP_OK) {
|
||||
while (true) {
|
||||
long int next_sendslot = i * interval;
|
||||
long int run_time = (long int)uvgrtp::clock::hrc::diff_now(start);
|
||||
long int diff_ms = next_sendslot - run_time;
|
||||
int poll_timeout = (int)diff_ms;
|
||||
|
||||
if (diff_ms < 0) {
|
||||
if ((ret = dhpart.send_msg(local_socket_, remote_addr_, remote_ip6_addr_)) != RTP_OK) {
|
||||
UVG_LOG_ERROR("Failed to send DHPart2 Message!");
|
||||
return ret;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
if (receiver_.recv_msg(local_socket_, poll_timeout, 0, type) == RTP_OK) {
|
||||
if (type == ZRTP_FT_CONFIRM1) {
|
||||
UVG_LOG_DEBUG("Confirm1 Message received");
|
||||
return RTP_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (rto < 1200)
|
||||
rto *= 2;
|
||||
else
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(diff_ms));
|
||||
if (interval < 1200) {
|
||||
interval *= 2;
|
||||
}
|
||||
}
|
||||
if (i > 10) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return RTP_TIMEOUT;
|
||||
}
|
||||
|
||||
|
@ -596,15 +652,24 @@ rtp_error_t uvgrtp::zrtp::responder_finalize_session()
|
|||
{
|
||||
auto confirm = uvgrtp::zrtp_msg::confirm(session_, 1);
|
||||
auto confack = uvgrtp::zrtp_msg::confack(session_);
|
||||
int rto = 150;
|
||||
int type = 0;
|
||||
uvgrtp::clock::hrc::hrc_t start = uvgrtp::clock::hrc::now();
|
||||
int interval = 150;
|
||||
int i = 1;
|
||||
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
if (confirm.send_msg(local_socket_, remote_addr_, remote_ip6_addr_) != RTP_OK) {
|
||||
UVG_LOG_ERROR("Failed to send Confirm1 Message!");
|
||||
while (true) {
|
||||
long int next_sendslot = i * interval;
|
||||
long int run_time = (long int)uvgrtp::clock::hrc::diff_now(start);
|
||||
long int diff_ms = next_sendslot - run_time;
|
||||
int poll_timeout = (int)diff_ms;
|
||||
|
||||
if (diff_ms < 0) {
|
||||
if (confirm.send_msg(local_socket_, remote_addr_, remote_ip6_addr_) != RTP_OK) {
|
||||
UVG_LOG_ERROR("Failed to send Confirm1 Message!");
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
if (receiver_.recv_msg(local_socket_, rto, 0, type) == RTP_OK) {
|
||||
if (receiver_.recv_msg(local_socket_, poll_timeout, 0, type) == RTP_OK) {
|
||||
if (type == ZRTP_FT_CONFIRM2) {
|
||||
if (confirm.parse_msg(receiver_, session_) != RTP_OK) {
|
||||
UVG_LOG_ERROR("Failed to parse Confirm2 Message!");
|
||||
|
@ -622,9 +687,16 @@ rtp_error_t uvgrtp::zrtp::responder_finalize_session()
|
|||
return RTP_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (rto < 1200)
|
||||
rto *= 2;
|
||||
else
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(diff_ms));
|
||||
if (interval < 1200) {
|
||||
interval *= 2;
|
||||
}
|
||||
}
|
||||
if (i > 10) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return RTP_TIMEOUT;
|
||||
|
@ -634,8 +706,10 @@ rtp_error_t uvgrtp::zrtp::initiator_finalize_session()
|
|||
{
|
||||
rtp_error_t ret = RTP_OK;
|
||||
auto confirm = uvgrtp::zrtp_msg::confirm(session_, 2);
|
||||
int rto = 150;
|
||||
int type = 0;
|
||||
uvgrtp::clock::hrc::hrc_t start = uvgrtp::clock::hrc::now();
|
||||
int interval = 150;
|
||||
int i = 1;
|
||||
|
||||
if ((ret = confirm.parse_msg(receiver_, session_)) != RTP_OK) {
|
||||
UVG_LOG_ERROR("Failed to parse Confirm1 Message!");
|
||||
|
@ -647,21 +721,35 @@ rtp_error_t uvgrtp::zrtp::initiator_finalize_session()
|
|||
return ret;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
if ((ret = confirm.send_msg(local_socket_, remote_addr_, remote_ip6_addr_)) != RTP_OK) {
|
||||
UVG_LOG_ERROR("Failed to send Confirm2 Message!");
|
||||
return ret;
|
||||
}
|
||||
while (true) {
|
||||
long int next_sendslot = i * interval;
|
||||
long int run_time = (long int)uvgrtp::clock::hrc::diff_now(start);
|
||||
long int diff_ms = next_sendslot - run_time;
|
||||
int poll_timeout = (int)diff_ms;
|
||||
|
||||
if (receiver_.recv_msg(local_socket_, rto, 0, type) == RTP_OK) {
|
||||
if (diff_ms < 0) {
|
||||
if ((ret = confirm.send_msg(local_socket_, remote_addr_, remote_ip6_addr_)) != RTP_OK) {
|
||||
UVG_LOG_ERROR("Failed to send Confirm2 Message!");
|
||||
return ret;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
if (receiver_.recv_msg(local_socket_, poll_timeout, 0, type) == RTP_OK) {
|
||||
if (type == ZRTP_FT_CONF2_ACK) {
|
||||
UVG_LOG_DEBUG("Conf2ACK received successfully!");
|
||||
return RTP_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (rto < 1200)
|
||||
rto *= 2;
|
||||
else
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(diff_ms));
|
||||
if (interval < 1200) {
|
||||
interval *= 2;
|
||||
}
|
||||
}
|
||||
if (i > 10) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return RTP_TIMEOUT;
|
||||
|
|
Loading…
Reference in New Issue