From 77f21f01e95e1210118de556963b4fb4fea9857a Mon Sep 17 00:00:00 2001 From: Green Sky Date: Wed, 11 Oct 2023 03:00:03 +0200 Subject: [PATCH] extend the protocol to support larger data packets and set it to the new tox constants numbers --- solanaceae/ngc_ext/ngcext.cpp | 40 ++++++++++++++++++++++++++++- solanaceae/ngc_ext/ngcext.hpp | 12 ++++++--- solanaceae/ngc_ft1/ngcft1.cpp | 48 +++++++++++++++++++++++------------ solanaceae/ngc_ft1/ngcft1.hpp | 5 +++- 4 files changed, 84 insertions(+), 21 deletions(-) diff --git a/solanaceae/ngc_ext/ngcext.cpp b/solanaceae/ngc_ext/ngcext.cpp index c94612b..5cf0041 100644 --- a/solanaceae/ngc_ext/ngcext.cpp +++ b/solanaceae/ngc_ext/ngcext.cpp @@ -112,6 +112,8 @@ bool NGCEXTEventProvider::parse_ft1_init_ack( _DATA_HAVE(sizeof(e.transfer_id), std::cerr << "NGCEXT: packet too small, missing transfer_id\n"; return false) e.transfer_id = data[curser++]; + e.max_lossy_data_size = 500-4; // -4 and 500 are hardcoded + return dispatch( NGCEXT_Event::FT1_INIT_ACK, e @@ -224,6 +226,41 @@ bool NGCEXTEventProvider::parse_ft1_message( ); } +bool NGCEXTEventProvider::parse_ft1_init_ack_v2( + uint32_t group_number, uint32_t peer_number, + const uint8_t* data, size_t data_size, + bool _private +) { + if (!_private) { + std::cerr << "NGCEXT: ft1_init_ack_v2 cant be public\n"; + return false; + } + + Events::NGCEXT_ft1_init_ack e; + e.group_number = group_number; + e.peer_number = peer_number; + size_t curser = 0; + + // - 1 byte (temporary_file_tf_id) + _DATA_HAVE(sizeof(e.transfer_id), std::cerr << "NGCEXT: packet too small, missing transfer_id\n"; return false) + e.transfer_id = data[curser++]; + + // - 2 byte (max_lossy_data_size) + if ((data_size - curser) >= sizeof(e.max_lossy_data_size)) { + e.max_lossy_data_size = 0; + for (size_t i = 0; i < sizeof(e.max_lossy_data_size); i++, curser++) { + e.max_lossy_data_size |= uint16_t(data[curser]) << (i*8); + } + } else { + e.max_lossy_data_size = 500-4; // default + } + + return dispatch( + NGCEXT_Event::FT1_INIT_ACK, + e + ); +} + bool NGCEXTEventProvider::handlePacket( const uint32_t group_number, const uint32_t peer_number, @@ -247,7 +284,8 @@ bool NGCEXTEventProvider::handlePacket( case NGCEXT_Event::FT1_INIT: return parse_ft1_init(group_number, peer_number, data+1, data_size-1, _private); case NGCEXT_Event::FT1_INIT_ACK: - return parse_ft1_init_ack(group_number, peer_number, data+1, data_size-1, _private); + //return parse_ft1_init_ack(group_number, peer_number, data+1, data_size-1, _private); + return parse_ft1_init_ack_v2(group_number, peer_number, data+1, data_size-1, _private); case NGCEXT_Event::FT1_DATA: return parse_ft1_data(group_number, peer_number, data+1, data_size-1, _private); case NGCEXT_Event::FT1_DATA_ACK: diff --git a/solanaceae/ngc_ext/ngcext.hpp b/solanaceae/ngc_ext/ngcext.hpp index 4932dcf..95ab0f7 100644 --- a/solanaceae/ngc_ext/ngcext.hpp +++ b/solanaceae/ngc_ext/ngcext.hpp @@ -70,8 +70,6 @@ namespace Events { // - X bytes (file_kind dependent id, differnt sizes) std::vector file_id; - - // TODO: max supported lossy packet size }; struct NGCEXT_ft1_init_ack { @@ -81,7 +79,8 @@ namespace Events { // - 1 byte (transfer_id) uint8_t transfer_id; - // TODO: max supported lossy packet size + // - 2 byte (self_max_lossy_data_size) + uint16_t max_lossy_data_size; }; struct NGCEXT_ft1_data { @@ -163,6 +162,7 @@ enum class NGCEXT_Event : uint8_t { // acknowlage init (like an accept) // like tox ft control continue // - 1 byte (transfer_id) + // - 2 byte (self_max_lossy_data_size) (optional since v2) FT1_INIT_ACK, // TODO: init deny, speed up non acceptance @@ -263,6 +263,12 @@ class NGCEXTEventProvider : public ToxEventI, public NGCEXTEventProviderI { bool _private ); + bool parse_ft1_init_ack_v2( + uint32_t group_number, uint32_t peer_number, + const uint8_t* data, size_t data_size, + bool _private + ); + bool handlePacket( const uint32_t group_number, const uint32_t peer_number, diff --git a/solanaceae/ngc_ft1/ngcft1.cpp b/solanaceae/ngc_ft1/ngcft1.cpp index dc723f4..6effa79 100644 --- a/solanaceae/ngc_ft1/ngcft1.cpp +++ b/solanaceae/ngc_ft1/ngcft1.cpp @@ -71,6 +71,12 @@ bool NGCFT1::sendPKG_FT1_INIT_ACK( pkg.push_back(static_cast(NGCEXT_Event::FT1_INIT_ACK)); pkg.push_back(transfer_id); + // - 2 bytes max_lossy_data_size + const uint16_t max_lossy_data_size = _t.toxGroupMaxCustomLossyPacketLength() - 4; + for (size_t i = 0; i < sizeof(uint16_t); i++) { + pkg.push_back((max_lossy_data_size>>(i*8)) & 0xff); + } + // lossless return _t.toxGroupSendCustomPrivatePacket(group_number, peer_number, true, pkg) == TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_OK; } @@ -283,23 +289,25 @@ void NGCFT1::updateSendTransfer(float time_delta, uint32_t group_number, uint32_ } void NGCFT1::iteratePeer(float time_delta, uint32_t group_number, uint32_t peer_number, Group::Peer& peer) { - auto timeouts = peer.cca->getTimeouts(); - std::set timeouts_set{timeouts.cbegin(), timeouts.cend()}; + if (peer.cca) { + auto timeouts = peer.cca->getTimeouts(); + std::set timeouts_set{timeouts.cbegin(), timeouts.cend()}; - int64_t can_packet_size {peer.cca->canSend()}; // might get more space while iterating (time) + int64_t can_packet_size {peer.cca->canSend()}; // might get more space while iterating (time) - // change iterat start position to not starve transfers in the back - size_t iterated_count = 0; - bool last_send_found = false; - for (size_t idx = peer.next_send_transfer_send_idx; iterated_count < peer.send_transfers.size(); idx++, iterated_count++) { - idx = idx % peer.send_transfers.size(); + // change iterat start position to not starve transfers in the back + size_t iterated_count = 0; + bool last_send_found = false; + for (size_t idx = peer.next_send_transfer_send_idx; iterated_count < peer.send_transfers.size(); idx++, iterated_count++) { + idx = idx % peer.send_transfers.size(); - if (peer.send_transfers.at(idx).has_value()) { - if (!last_send_found && can_packet_size <= 0) { - peer.next_send_transfer_send_idx = idx; - last_send_found = true; // only set once + if (peer.send_transfers.at(idx).has_value()) { + if (!last_send_found && can_packet_size <= 0) { + peer.next_send_transfer_send_idx = idx; + last_send_found = true; // only set once + } + updateSendTransfer(time_delta, group_number, peer_number, peer, idx, timeouts_set, can_packet_size); } - updateSendTransfer(time_delta, group_number, peer_number, peer, idx, timeouts_set, can_packet_size); } } @@ -473,7 +481,7 @@ bool NGCFT1::onEvent(const Events::NGCEXT_ft1_init& e) { bool NGCFT1::onEvent(const Events::NGCEXT_ft1_init_ack& e) { //#if !NDEBUG - std::cout << "NGCFT1: FT1_INIT_ACK\n"; + std::cout << "NGCFT1: FT1_INIT_ACK mds:" << e.max_lossy_data_size << "\n"; //#endif // we now should start sending data @@ -493,10 +501,18 @@ bool NGCFT1::onEvent(const Events::NGCEXT_ft1_init_ack& e) { using State = Group::Peer::SendTransfer::State; if (transfer.state != State::INIT_SENT) { - std::cerr << "NGCFT1 error: inti_ack but not in INIT_SENT state\n"; + std::cerr << "NGCFT1 error: init_ack but not in INIT_SENT state\n"; return true; } + // negotiated packet_data_size + const auto negotiated_packet_data_size = std::min(e.max_lossy_data_size, _t.toxGroupMaxCustomLossyPacketLength()-4); + // TODO: reset cca with new pkg size + if (!peer.cca) { + peer.max_packet_data_size = negotiated_packet_data_size; + peer.cca = std::make_unique(peer.max_packet_data_size); + } + // iterate will now call NGC_FT1_send_data_cb transfer.state = State::SENDING; transfer.time_since_activity = 0.f; @@ -698,7 +714,7 @@ bool NGCFT1::onToxEvent(const Tox_Event_Group_Peer_Exit* e) { } // reset cca - peer.cca = std::make_unique(500-4); // TODO: replace with tox_group_max_custom_lossy_packet_length()-4 + peer.cca.reset(); // dont actually reallocate return false; } diff --git a/solanaceae/ngc_ft1/ngcft1.hpp b/solanaceae/ngc_ft1/ngcft1.hpp index 0c51c72..4d30e8d 100644 --- a/solanaceae/ngc_ft1/ngcft1.hpp +++ b/solanaceae/ngc_ft1/ngcft1.hpp @@ -2,6 +2,7 @@ // solanaceae port of tox_ngc_ft1 +#include #include #include @@ -141,7 +142,9 @@ class NGCFT1 : public ToxEventI, public NGCEXTEventI, public NGCFT1EventProvider struct Group { struct Peer { - std::unique_ptr cca = std::make_unique(500-4); // TODO: replace with tox_group_max_custom_lossy_packet_length()-4 + uint32_t max_packet_data_size {500-4}; + //std::unique_ptr cca = std::make_unique(max_packet_data_size); // TODO: replace with tox_group_max_custom_lossy_packet_length()-4 + std::unique_ptr cca; struct RecvTransfer { uint32_t file_kind;