Compare commits
2 Commits
ignore_tim
...
2e6b15e4ad
Author | SHA1 | Date | |
---|---|---|---|
2e6b15e4ad | |||
63de78aaeb |
@ -61,10 +61,6 @@ struct CCAI {
|
||||
// returns -1 if not implemented, can return 0
|
||||
virtual int64_t inFlightBytes(void) const { return -1; }
|
||||
|
||||
// returns -1 if not implemented, can return 0
|
||||
// excluded timed out packets (not those currently resent)
|
||||
virtual int64_t inFlightBytesAccounted(void) const { return -1; }
|
||||
|
||||
public: // callbacks
|
||||
// data size is without overhead
|
||||
virtual void onSent(SeqIDType seq, size_t data_size) = 0;
|
||||
|
@ -93,8 +93,7 @@ int64_t CUBIC::canSend(float time_delta) {
|
||||
}
|
||||
|
||||
const auto window = getCWnD();
|
||||
//int64_t cspace_bytes = window - _in_flight_bytes;
|
||||
int64_t cspace_bytes = window - _in_flight_bytes_accounted;
|
||||
int64_t cspace_bytes = window - _in_flight_bytes;
|
||||
if (cspace_bytes < MAXIMUM_SEGMENT_DATA_SIZE) {
|
||||
//std::cerr << "CUBIC: cspace < seg size\n";
|
||||
return 0u;
|
||||
|
@ -29,25 +29,6 @@ void FlowOnly::updateWindow(void) {
|
||||
_fwnd = std::max(_fwnd, 2.f * MAXIMUM_SEGMENT_DATA_SIZE);
|
||||
}
|
||||
|
||||
void FlowOnly::updateAccounted(void) {
|
||||
int64_t size_timedout {0};
|
||||
|
||||
{ // can be expensive
|
||||
// code see getTimeouts()
|
||||
// after 3 rtt delay, we trigger timeout
|
||||
const auto now_adjusted = getTimeNow() - getCurrentDelay()*3.f;
|
||||
|
||||
for (const auto& [seq, time_stamp, size, _] : _in_flight) {
|
||||
if (now_adjusted > time_stamp) {
|
||||
//list.push_back(seq);
|
||||
size_timedout += size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_in_flight_bytes_accounted = _in_flight_bytes - size_timedout;
|
||||
}
|
||||
|
||||
void FlowOnly::updateCongestion(void) {
|
||||
updateWindow();
|
||||
const auto tmp_window = getWindow();
|
||||
@ -89,10 +70,8 @@ int64_t FlowOnly::canSend(float time_delta) {
|
||||
}
|
||||
|
||||
updateWindow();
|
||||
updateAccounted();
|
||||
|
||||
//int64_t fspace = _fwnd - _in_flight_bytes;
|
||||
int64_t fspace = _fwnd - _in_flight_bytes_accounted;
|
||||
int64_t fspace = _fwnd - _in_flight_bytes;
|
||||
if (fspace < MAXIMUM_SEGMENT_DATA_SIZE) {
|
||||
return 0u;
|
||||
}
|
||||
@ -128,10 +107,6 @@ int64_t FlowOnly::inFlightBytes(void) const {
|
||||
return _in_flight_bytes;
|
||||
}
|
||||
|
||||
int64_t FlowOnly::inFlightBytesAccounted(void) const {
|
||||
return _in_flight_bytes_accounted;
|
||||
}
|
||||
|
||||
void FlowOnly::onSent(SeqIDType seq, size_t data_size) {
|
||||
if constexpr (true) {
|
||||
size_t sum {0u};
|
||||
|
@ -32,7 +32,6 @@ struct FlowOnly : public CCAI {
|
||||
};
|
||||
std::vector<FlyingBunch> _in_flight;
|
||||
int64_t _in_flight_bytes {0};
|
||||
int64_t _in_flight_bytes_accounted {0};
|
||||
|
||||
int32_t _consecutive_events {0};
|
||||
|
||||
@ -59,8 +58,6 @@ struct FlowOnly : public CCAI {
|
||||
|
||||
void updateWindow(void);
|
||||
|
||||
void updateAccounted(void);
|
||||
|
||||
virtual void onCongestion(void) {};
|
||||
|
||||
// internal logic, calls the onCongestion() event
|
||||
@ -80,7 +77,6 @@ struct FlowOnly : public CCAI {
|
||||
|
||||
int64_t inFlightCount(void) const override;
|
||||
int64_t inFlightBytes(void) const override;
|
||||
int64_t inFlightBytesAccounted(void) const override;
|
||||
|
||||
public: // callbacks
|
||||
// data size is without overhead
|
||||
|
@ -3,15 +3,26 @@
|
||||
#include <solanaceae/tox_contacts/tox_contact_model2.hpp>
|
||||
|
||||
NGCHS2::NGCHS2(
|
||||
Contact3Registry& cr,
|
||||
RegistryMessageModelI& rmm,
|
||||
ToxContactModel2& tcm,
|
||||
ToxEventProviderI& tep,
|
||||
NGCFT1& nft
|
||||
) :
|
||||
_cr(cr),
|
||||
_rmm(rmm),
|
||||
_rmm_sr(_rmm.newSubRef(this)),
|
||||
_tcm(tcm),
|
||||
_tep_sr(tep.newSubRef(this)),
|
||||
_nft(nft),
|
||||
_nftep_sr(_nft.newSubRef(this))
|
||||
{
|
||||
_rmm_sr
|
||||
.subscribe(RegistryMessageModel_Event::message_construct)
|
||||
.subscribe(RegistryMessageModel_Event::message_updated)
|
||||
.subscribe(RegistryMessageModel_Event::message_destroy)
|
||||
;
|
||||
|
||||
_tep_sr
|
||||
.subscribe(TOX_EVENT_GROUP_PEER_JOIN)
|
||||
.subscribe(TOX_EVENT_GROUP_PEER_EXIT)
|
||||
@ -35,6 +46,18 @@ float NGCHS2::iterate(float delta) {
|
||||
return 1000.f;
|
||||
}
|
||||
|
||||
bool NGCHS2::onEvent(const Message::Events::MessageConstruct&) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NGCHS2::onEvent(const Message::Events::MessageUpdated&) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NGCHS2::onEvent(const Message::Events::MessageDestory&) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NGCHS2::onEvent(const Events::NGCFT1_recv_request& e) {
|
||||
if (
|
||||
e.file_kind != NGCFT1_file_kind::HS2_INFO_RANGE_TIME &&
|
||||
|
@ -1,25 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
//#include <solanaceae/contact/contact_model3.hpp>
|
||||
#include <solanaceae/toxcore/tox_event_interface.hpp>
|
||||
|
||||
//#include <solanaceae/message3/registry_message_model.hpp>
|
||||
#include <solanaceae/contact/contact_model3.hpp>
|
||||
#include <solanaceae/message3/registry_message_model.hpp>
|
||||
|
||||
#include <solanaceae/ngc_ft1/ngcft1.hpp>
|
||||
|
||||
#include <entt/container/dense_map.hpp>
|
||||
|
||||
// fwd
|
||||
class ToxContactModel2;
|
||||
|
||||
class NGCHS2 : public ToxEventI, public NGCFT1EventI {
|
||||
// time ranges
|
||||
// should we just do last x minutes like zngchs?
|
||||
// properly done, we need to use:
|
||||
// - Message::Components::ViewCurserBegin
|
||||
// - Message::Components::ViewCurserEnd
|
||||
//
|
||||
// on startup, manually check all registries for ranges (meh) (do later)
|
||||
// listen on message events, check if range, see if range satisfied recently
|
||||
// deal with a queue, and delay (at least 1sec, 3-10sec after a peer con change)
|
||||
// or we always overrequest (eg 48h), and only fetch messages in, or close to range
|
||||
|
||||
class NGCHS2 : public RegistryMessageModelEventI, public ToxEventI, public NGCFT1EventI {
|
||||
Contact3Registry& _cr;
|
||||
RegistryMessageModelI& _rmm;
|
||||
RegistryMessageModelI::SubscriptionReference _rmm_sr;
|
||||
ToxContactModel2& _tcm;
|
||||
//Contact3Registry& _cr;
|
||||
//RegistryMessageModelI& _rmm;
|
||||
ToxEventProviderI::SubscriptionReference _tep_sr;
|
||||
NGCFT1& _nft;
|
||||
NGCFT1EventProviderI::SubscriptionReference _nftep_sr;
|
||||
|
||||
// describes our knowlage of a remote peer
|
||||
struct RemoteInfo {
|
||||
// list of all ppk+mid+ts they sent us (filtered by reqs, like range, ppk...)
|
||||
// with when it last sent a range? hmm
|
||||
};
|
||||
entt::dense_map<Contact3, RemoteInfo> _remote_info;
|
||||
|
||||
// open/running info requests (by c)
|
||||
|
||||
// open/running info responses (by c)
|
||||
|
||||
static const bool _only_send_self_observed {true};
|
||||
static const int64_t _max_time_into_past_default {60}; // s
|
||||
|
||||
public:
|
||||
NGCHS2(
|
||||
Contact3Registry& cr,
|
||||
RegistryMessageModelI& rmm,
|
||||
ToxContactModel2& tcm,
|
||||
ToxEventProviderI& tep,
|
||||
NGCFT1& nf
|
||||
@ -29,6 +59,15 @@ class NGCHS2 : public ToxEventI, public NGCFT1EventI {
|
||||
|
||||
float iterate(float delta);
|
||||
|
||||
// add to queue with timer
|
||||
// check and updates all existing cursers for giving reg in queue
|
||||
void enqueueWantCurser(Message3Handle m);
|
||||
|
||||
protected:
|
||||
bool onEvent(const Message::Events::MessageConstruct&) override;
|
||||
bool onEvent(const Message::Events::MessageUpdated&) override;
|
||||
bool onEvent(const Message::Events::MessageDestory&) override;
|
||||
|
||||
protected:
|
||||
bool onEvent(const Events::NGCFT1_recv_request&) override;
|
||||
bool onEvent(const Events::NGCFT1_recv_init&) override;
|
||||
|
77
solanaceae/ngc_hs2/spec_ngc_hs2.md
Normal file
77
solanaceae/ngc_hs2/spec_ngc_hs2.md
Normal file
@ -0,0 +1,77 @@
|
||||
# [NGC] Group-History-Sync (v2) [PoC] [Draft]
|
||||
|
||||
Simple group history sync that uses `peer public key` + `message_id` + `timestamp` (`ppk+mid+ts`) to, mostly, uniquely identify messages and deliver them.
|
||||
|
||||
## Requirements
|
||||
|
||||
TODO
|
||||
|
||||
### File transfers
|
||||
|
||||
For sending packs of messages. A single message can be larger than a single custom packet, so this is a must-have.
|
||||
|
||||
## Procedure
|
||||
|
||||
Peer A can request `ppk+mid+ts` list for a given time range from peer B.
|
||||
|
||||
Peer B then sends a filetransfer (with special file type) of list of `ppk+mid+ts`.
|
||||
Optionally compressed. (Delta-coding / zstd)
|
||||
|
||||
Peer A keeps doing that until the desired time span is covered.
|
||||
|
||||
After that or simultaniously, Peer A requests messages from peer B, either indivitually, or packed? in ranges?.
|
||||
Optionally compressed.
|
||||
|
||||
During all that, peer B usually does the same thing to peer A.
|
||||
|
||||
## Traffic savings
|
||||
|
||||
It is recomended to remember if a range has been requested and answered from a given peer, to reduce traffic.
|
||||
|
||||
While compression is optional, it is recommended.
|
||||
|
||||
## Message uniqueness
|
||||
|
||||
This protocol relies on the randomness of `message_id` and the clocks to be more or less synchronized.
|
||||
|
||||
However, `message_id` can be manipulated freely by any peer, this can make messages appear as duplicates.
|
||||
|
||||
This can be used here, if you don't wish your messages to be syncronized (to an extent).
|
||||
|
||||
## Security
|
||||
|
||||
Only sync publicly sent/recieved messages.
|
||||
|
||||
Only allow sync or extended time ranges from peers you trust (enough).
|
||||
|
||||
The default shall be to not offer any messages.
|
||||
|
||||
Indirect messages shall be low in credibility, while direct synced (by author), with mid credibility.
|
||||
|
||||
Either only high or mid credibility shall be sent.
|
||||
|
||||
|
||||
Manual exceptions to all can be made at the users discretion, eg for other self owned devices.
|
||||
|
||||
## File transfer requests
|
||||
|
||||
TODO: is reusing the ft request api a good idea for this?
|
||||
|
||||
| fttype | name | content (ft id) |
|
||||
|------------|------|---------------------|
|
||||
| 0x00000f00 | time range | - ts start </br> - ts end </br> - supported compression? |
|
||||
| | TODO: id range based request? | |
|
||||
| 0x00000f01 | single message | - ppk </br> - mid </br> - ts |
|
||||
|
||||
## File transfers
|
||||
|
||||
| fttype | name | content |
|
||||
|------------|------|---------------------|
|
||||
| 0x00000f00 | time range | - feature bitset (1byte? different compressions?) </br> - ts start </br> - ts end </br> - list size </br> \\+ entry `ppk` </br> \\+ entry `mid` </br> \\+ entry `ts` |
|
||||
| 0x00000f01 | single message | - message type (text/textaction/file) </br> - text if text or action, file type and file id if file |
|
||||
|
||||
## TODO
|
||||
|
||||
- [ ] figure out a pro-active approach (instead of waiting for a range request)
|
||||
- [ ] compression in the ft layer? (would make it reusable) hint/autodetect?
|
||||
|
Reference in New Issue
Block a user