#include "shared/connection.hh" namespace shared { void connection::send_packet(packet&& packet) noexcept { packet.header.sequence = this->seq_num; shared::send_packet(packet, this->sock, this->info); ++this->seq_num; std::lock_guard guard{*this->lock}; this->sent.push_back(packet); } bool connection::should_discard_packet(const packet& packet) noexcept { std::lock_guard guard{*this->lock}; // ack case if (packet.header.command[0] == '\0') { this->sent.erase(std::remove_if(std::begin(this->sent), std::end(this->sent), [&](const auto& p) { return p.header.sequence <= packet.header.sequence; }), std::end(this->sent)); return true; } // Send an ack for the packet if it's not an ack itself auto ack_pkt = shared::contents_to_packet({}, "\0\0\0"); ack_pkt.header.sequence = packet.header.sequence; shared::send_packet(ack_pkt, this->sock, this->info); if (packet.header.sequence != this->ack_num) { return true; } ++this->ack_num; return false; } // Reliable transport reads our packets on a different thread and resends if // necessary. void connection::do_reliable_transport() noexcept { while (!*this->should_thread_exit) { std::this_thread::sleep_for(std::chrono::milliseconds(500)); std::lock_guard guard{*this->lock}; for (const auto& packet : this->sent) { shared::send_packet(packet, this->sock, this->info); } } } } // namespace shared