Explicit echo ack protobuf with reliable semantics
This commit is contained in:
@@ -33,7 +33,6 @@ Transport<MyState, RemoteState>::Transport( MyState &initial_state, RemoteState
|
||||
sender( &connection, initial_state ),
|
||||
received_states( 1, TimestampedState<RemoteState>( timestamp(), 0, initial_remote ) ),
|
||||
last_receiver_state( initial_remote ),
|
||||
sent_state_late_acked( 0 ),
|
||||
fragments(),
|
||||
verbose( false )
|
||||
{
|
||||
@@ -47,7 +46,6 @@ Transport<MyState, RemoteState>::Transport( MyState &initial_state, RemoteState
|
||||
sender( &connection, initial_state ),
|
||||
received_states( 1, TimestampedState<RemoteState>( timestamp(), 0, initial_remote ) ),
|
||||
last_receiver_state( initial_remote ),
|
||||
sent_state_late_acked( 0 ),
|
||||
fragments(),
|
||||
verbose( false )
|
||||
{
|
||||
@@ -68,9 +66,6 @@ void Transport<MyState, RemoteState>::recv( void )
|
||||
}
|
||||
|
||||
sender.process_acknowledgment_through( inst.ack_num() );
|
||||
if ( inst.late_ack_num() > sent_state_late_acked ) {
|
||||
sent_state_late_acked = inst.late_ack_num();
|
||||
}
|
||||
|
||||
/* first, make sure we don't already have the new state */
|
||||
for ( typename list< TimestampedState<RemoteState> >::iterator i = received_states.begin();
|
||||
|
||||
@@ -47,7 +47,6 @@ namespace Network {
|
||||
/* simple receiver */
|
||||
list< TimestampedState<RemoteState> > received_states;
|
||||
RemoteState last_receiver_state; /* the state we were in when user last queried state */
|
||||
uint64_t sent_state_late_acked;
|
||||
FragmentAssembly fragments;
|
||||
bool verbose;
|
||||
|
||||
@@ -97,7 +96,6 @@ namespace Network {
|
||||
|
||||
uint64_t get_sent_state_acked( void ) const { return sender.get_sent_state_acked(); }
|
||||
uint64_t get_sent_state_last( void ) const { return sender.get_sent_state_last(); }
|
||||
uint64_t get_sent_state_late_acked( void ) const { return sent_state_late_acked; }
|
||||
|
||||
unsigned int send_interval( void ) const { return sender.send_interval(); }
|
||||
|
||||
|
||||
@@ -142,7 +142,6 @@ vector<Fragment> Fragmenter::make_fragments( Instruction &inst, int MTU )
|
||||
|| (inst.new_num() != last_instruction.new_num())
|
||||
|| (inst.ack_num() != last_instruction.ack_num())
|
||||
|| (inst.throwaway_num() != last_instruction.throwaway_num())
|
||||
|| (inst.late_ack_num() != last_instruction.late_ack_num())
|
||||
|| (inst.protocol_version() != last_instruction.protocol_version())
|
||||
|| (last_MTU != MTU) ) {
|
||||
next_instruction_id++;
|
||||
|
||||
@@ -43,8 +43,6 @@ TransportSender<MyState>::TransportSender( Connection *s_connection, MyState &in
|
||||
shutdown_tries( 0 ),
|
||||
ack_num( 0 ),
|
||||
pending_data_ack( false ),
|
||||
ack_timestamp( 0 ),
|
||||
ack_history(),
|
||||
SEND_MINDELAY( 15 ),
|
||||
last_heard( 0 )
|
||||
{
|
||||
@@ -260,14 +258,11 @@ void TransportSender<MyState>::send_in_fragments( string diff, uint64_t new_num
|
||||
{
|
||||
Instruction inst;
|
||||
|
||||
uint64_t now = timestamp();
|
||||
|
||||
inst.set_protocol_version( MOSH_PROTOCOL_VERSION );
|
||||
inst.set_old_num( assumed_receiver_state->num );
|
||||
inst.set_new_num( new_num );
|
||||
inst.set_ack_num( ack_num );
|
||||
inst.set_throwaway_num( sent_states.front().num );
|
||||
inst.set_late_ack_num( get_late_ack( now ) );
|
||||
inst.set_diff( diff );
|
||||
|
||||
if ( new_num == uint64_t(-1) ) {
|
||||
@@ -280,12 +275,11 @@ void TransportSender<MyState>::send_in_fragments( string diff, uint64_t new_num
|
||||
connection->send( i->tostring() );
|
||||
|
||||
if ( verbose ) {
|
||||
fprintf( stderr, "[%u] Sent [%d=>%d] id %d, frag %d ack=%d, late_ack=%d, throwaway=%d, len=%d, frame rate=%.2f, timeout=%d, srtt=%.1f age=%llu\n",
|
||||
fprintf( stderr, "[%u] Sent [%d=>%d] id %d, frag %d ack=%d, throwaway=%d, len=%d, frame rate=%.2f, timeout=%d, srtt=%.1f\n",
|
||||
(unsigned int)(timestamp() % 100000), (int)inst.old_num(), (int)inst.new_num(), (int)i->id, (int)i->fragment_num,
|
||||
(int)inst.ack_num(), (int)inst.late_ack_num(), (int)inst.throwaway_num(), (int)i->contents.size(),
|
||||
(int)inst.ack_num(), (int)inst.throwaway_num(), (int)i->contents.size(),
|
||||
1000.0 / (double)send_interval(),
|
||||
(int)connection->timeout(), connection->get_SRTT(),
|
||||
(long long)(now - ack_timestamp) );
|
||||
(int)connection->timeout(), connection->get_SRTT() );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -318,23 +312,4 @@ template <class MyState>
|
||||
void TransportSender<MyState>::set_ack_num( uint64_t s_ack_num )
|
||||
{
|
||||
ack_num = s_ack_num;
|
||||
ack_timestamp = timestamp();
|
||||
ack_history.push_back( make_pair( ack_num, ack_timestamp ) );
|
||||
}
|
||||
|
||||
/* The "late" ack is for the input state that has had enough time on the host to have been echoed */
|
||||
template <class MyState>
|
||||
uint64_t TransportSender<MyState>::get_late_ack( uint64_t now )
|
||||
{
|
||||
uint64_t newest_echo_ack = 0;
|
||||
|
||||
for ( BOOST_AUTO( i, ack_history.begin() ); i != ack_history.end(); i++ ) {
|
||||
if ( i->second < now - ECHO_TIMEOUT ) {
|
||||
newest_echo_ack = i->first;
|
||||
}
|
||||
}
|
||||
|
||||
ack_history.remove_if( (&_1)->*&pair<uint64_t, uint64_t>::first < newest_echo_ack );
|
||||
|
||||
return newest_echo_ack;
|
||||
}
|
||||
|
||||
@@ -43,7 +43,6 @@ namespace Network {
|
||||
static const int ACK_INTERVAL = 3000; /* ms between empty acks */
|
||||
static const int ACK_DELAY = 100; /* ms before delayed ack */
|
||||
static const int SHUTDOWN_RETRIES = 3; /* number of shutdown packets to send before giving up */
|
||||
static const int ECHO_TIMEOUT = 50; /* for late ack */
|
||||
static const int ACTIVE_RETRY_TIMEOUT = 10000; /* attempt to resend at frame rate */
|
||||
|
||||
/* helper methods for tick() */
|
||||
@@ -82,10 +81,6 @@ namespace Network {
|
||||
/* information about receiver state */
|
||||
uint64_t ack_num;
|
||||
bool pending_data_ack;
|
||||
uint64_t ack_timestamp;
|
||||
|
||||
list< pair<uint64_t, uint64_t> > ack_history;
|
||||
uint64_t get_late_ack( uint64_t now ); /* calculate delayed "echo" acknowledgment */
|
||||
|
||||
unsigned int SEND_MINDELAY; /* ms to collect all input */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user