Clean out some bugs in sender
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
source = parse.cpp parserstate.cpp parser.cpp templates.cpp terminal.cpp termemu.cpp parseraction.cpp terminalfunctions.cpp swrite.cpp terminalframebuffer.cpp terminaldispatcher.cpp terminaluserinput.cpp terminaldisplay.cpp network.cpp ntester.cpp ocb.cpp base64.cpp encrypt.cpp decrypt.cpp crypto.cpp networktransport.cpp
|
||||
objects = parserstate.o parser.o templates.o terminal.o parseraction.o terminalfunctions.o swrite.o terminalframebuffer.o terminaldispatcher.o terminaluserinput.o terminaldisplay.o network.o ocb.o base64.o crypto.o networktransport.o
|
||||
source = parse.cpp parserstate.cpp parser.cpp templates.cpp terminal.cpp termemu.cpp parseraction.cpp terminalfunctions.cpp swrite.cpp terminalframebuffer.cpp terminaldispatcher.cpp terminaluserinput.cpp terminaldisplay.cpp network.cpp ntester.cpp ocb.cpp base64.cpp encrypt.cpp decrypt.cpp crypto.cpp networktransport.cpp networkinstruction.cpp keystroke.cpp
|
||||
objects = parserstate.o parser.o templates.o terminal.o parseraction.o terminalfunctions.o swrite.o terminalframebuffer.o terminaldispatcher.o terminaluserinput.o terminaldisplay.o network.o ocb.o base64.o crypto.o networktransport.o networkinstruction.o keystroke.o
|
||||
repos = templates.rpo
|
||||
executables = parse termemu ntester encrypt decrypt
|
||||
|
||||
CXX = g++
|
||||
CXXFLAGS = -g --std=c++0x -pedantic -Werror -Wall -Wextra -Weffc++ -fno-implicit-templates -fno-default-inline -pipe -D_FILE_OFFSET_BITS=64 -D_XOPEN_SOURCE=500 -D_GNU_SOURCE
|
||||
CXXFLAGS = -g --std=c++0x -pedantic -Werror -Wall -Wextra -Weffc++ -fno-implicit-templates -fno-default-inline -pipe -D_FILE_OFFSET_BITS=64 -D_XOPEN_SOURCE=500 -D_GNU_SOURCE -D_BSD_SOURCE
|
||||
LIBS = -lutil -lssl -lrt
|
||||
|
||||
all: $(executables)
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "keystroke.hpp"
|
||||
|
||||
void KeyStroke::subtract( KeyStroke * const prefix )
|
||||
{
|
||||
for ( deque<char>::iterator i = prefix->user_bytes.begin();
|
||||
i != prefix->user_bytes.end();
|
||||
i++ ) {
|
||||
assert( *i == user_bytes.front() );
|
||||
user_bytes.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
string KeyStroke::diff_from( KeyStroke const & existing, int length_limit )
|
||||
{
|
||||
string ret;
|
||||
|
||||
deque<char>::iterator my_it = user_bytes.begin();
|
||||
|
||||
for ( deque<char>::const_iterator i = existing.user_bytes.begin();
|
||||
i != existing.user_bytes.end();
|
||||
i++ ) {
|
||||
assert( *i == *my_it );
|
||||
my_it++;
|
||||
}
|
||||
|
||||
while ( (my_it != user_bytes.end())
|
||||
&& ( (length_limit < 0) ? true : (int(ret.size()) < length_limit) ) ) {
|
||||
ret += string( &( *my_it ), 1 );
|
||||
my_it++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void KeyStroke::apply_string( string diff )
|
||||
{
|
||||
for ( string::iterator i = diff.begin();
|
||||
i != diff.end();
|
||||
i++ ) {
|
||||
user_bytes.push_back( *i );
|
||||
}
|
||||
}
|
||||
+12
-4
@@ -1,6 +1,7 @@
|
||||
#ifndef KEYSTROKE_HPP
|
||||
#define KEYSTROKE_HPP
|
||||
|
||||
#include <deque>
|
||||
#include <string>
|
||||
#include <assert.h>
|
||||
|
||||
@@ -9,10 +10,17 @@ using namespace std;
|
||||
class KeyStroke
|
||||
{
|
||||
public:
|
||||
void subtract( KeyStroke * const ) {}
|
||||
string diff_from( KeyStroke const &, int ) { return ""; }
|
||||
void apply_string( string ) {}
|
||||
bool operator==( KeyStroke const & ) const { return true; }
|
||||
deque<char> user_bytes;
|
||||
|
||||
KeyStroke() : user_bytes() {}
|
||||
|
||||
void key_hit( char x ) { user_bytes.push_back( x ); }
|
||||
|
||||
/* interface for Network::Transport */
|
||||
void subtract( KeyStroke * const prefix );
|
||||
string diff_from( KeyStroke const & existing, int length_limit );
|
||||
void apply_string( string diff );
|
||||
bool operator==( KeyStroke const &x ) const { return user_bytes == x.user_bytes; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ string Packet::tostring( Session *session )
|
||||
{
|
||||
uint64_t direction_seq = (uint64_t( direction == TO_CLIENT ) << 63) | (seq & 0x7FFFFFFFFFFFFFFF);
|
||||
|
||||
return session->encrypt( Message( direction_seq, payload ) );
|
||||
return session->encrypt( Message( Nonce( direction_seq ), payload ) );
|
||||
}
|
||||
|
||||
Packet Connection::new_packet( string &s_payload )
|
||||
|
||||
+2
-1
@@ -76,8 +76,9 @@ namespace Network {
|
||||
void send( string &s );
|
||||
string recv( void );
|
||||
int fd( void ) { return sock; }
|
||||
int port( void );
|
||||
int get_MTU( void ) { return MTU; }
|
||||
|
||||
int port( void );
|
||||
string get_key( void ) { return key.printable_key(); }
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
#include <endian.h>
|
||||
|
||||
#include "networktransport.hpp"
|
||||
|
||||
using namespace Network;
|
||||
|
||||
static string network_order_string( uint64_t host_order )
|
||||
{
|
||||
uint64_t net_int = htobe64( host_order );
|
||||
return string( (char *)&net_int, sizeof( net_int ) );
|
||||
}
|
||||
|
||||
string Instruction::tostring( void )
|
||||
{
|
||||
string ret;
|
||||
|
||||
ret += network_order_string( old_num );
|
||||
ret += network_order_string( new_num );
|
||||
ret += network_order_string( ack_num );
|
||||
ret += diff;
|
||||
|
||||
return ret;
|
||||
}
|
||||
+35
-25
@@ -1,4 +1,5 @@
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
|
||||
#include "networktransport.hpp"
|
||||
|
||||
@@ -47,20 +48,16 @@ Transport<MyState, RemoteState>::Transport( MyState &initial_state,
|
||||
/* client */
|
||||
}
|
||||
|
||||
template <class MyState, class RemoteState>
|
||||
void Transport<MyState, RemoteState>::new_state( MyState &s )
|
||||
{
|
||||
current_state = s;
|
||||
|
||||
tick();
|
||||
}
|
||||
|
||||
template <class MyState, class RemoteState>
|
||||
void Transport<MyState, RemoteState>::tick( void )
|
||||
{
|
||||
/* Update assumed receiver state */
|
||||
update_assumed_receiver_state();
|
||||
|
||||
fprintf( stderr, "Assumed receiver state: %d/%d\r\n",
|
||||
int(assumed_receiver_state->num),
|
||||
int(sent_states.back().num) );
|
||||
|
||||
/* Cut out common prefix of all states */
|
||||
rationalize_states();
|
||||
|
||||
@@ -74,20 +71,6 @@ void Transport<MyState, RemoteState>::tick( void )
|
||||
template <class MyState, class RemoteState>
|
||||
void Transport<MyState, RemoteState>::send_to_receiver( void )
|
||||
{
|
||||
if ( assumed_receiver_state->state == sent_states.back().state ) {
|
||||
/* send empty ack */
|
||||
Instruction inst( assumed_receiver_state->num,
|
||||
assumed_receiver_state->num,
|
||||
"",
|
||||
highest_state_received );
|
||||
string s = inst.tostring();
|
||||
connection.send( s );
|
||||
sent_states.back().timestamp = timestamp();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Otherwise, send sequence of diffs between assumed receiver state and current state */
|
||||
|
||||
/* We don't want to assume that this sequence of diffs will
|
||||
necessarily bring the receiver to the _actual_ current
|
||||
state. That requires perfect round-trip stability of the diff
|
||||
@@ -101,11 +84,31 @@ void Transport<MyState, RemoteState>::send_to_receiver( void )
|
||||
MyState target_receiver_state( assumed_receiver_state->state );
|
||||
target_receiver_state.apply_string( current_state.diff_from( target_receiver_state, -1 ) );
|
||||
|
||||
if ( assumed_receiver_state->state == target_receiver_state ) {
|
||||
/* send empty ack */
|
||||
Instruction inst( assumed_receiver_state->num,
|
||||
assumed_receiver_state->num,
|
||||
highest_state_received,
|
||||
"" );
|
||||
string s = inst.tostring();
|
||||
connection.send( s );
|
||||
assumed_receiver_state->timestamp = timestamp();
|
||||
|
||||
fprintf( stderr, "Empty ack.\r\n" );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int tries = 0;
|
||||
while ( !(assumed_receiver_state->state == target_receiver_state) ) {
|
||||
Instruction inst( assumed_receiver_state->num, -1,
|
||||
if ( tries++ > 1024 ) {
|
||||
fprintf( stderr, "BUG: Convergence limit exceeded.\n" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
Instruction inst( assumed_receiver_state->num, -1, highest_state_received,
|
||||
current_state.diff_from( assumed_receiver_state->state,
|
||||
connection.get_MTU() - HEADER_LEN ),
|
||||
highest_state_received );
|
||||
connection.get_MTU() - HEADER_LEN ) );
|
||||
MyState new_state = assumed_receiver_state->state;
|
||||
new_state.apply_string( inst.diff );
|
||||
|
||||
@@ -133,6 +136,11 @@ void Transport<MyState, RemoteState>::send_to_receiver( void )
|
||||
string s = inst.tostring();
|
||||
|
||||
try {
|
||||
fprintf( stderr, "Sending: " );
|
||||
for ( size_t i = 0; i < s.size(); i++ ) {
|
||||
fprintf( stderr, "%c", s[ i ] );
|
||||
}
|
||||
fprintf( stderr, "\r\n" );
|
||||
connection.send( s );
|
||||
} catch ( MTUException m ) {
|
||||
continue;
|
||||
@@ -174,4 +182,6 @@ void Transport<MyState, RemoteState>::rationalize_states( void )
|
||||
i++ ) {
|
||||
i->state.subtract( known_receiver_state );
|
||||
}
|
||||
|
||||
current_state.subtract( known_receiver_state );
|
||||
}
|
||||
|
||||
+10
-6
@@ -15,15 +15,15 @@ namespace Network {
|
||||
{
|
||||
public:
|
||||
uint64_t old_num, new_num;
|
||||
string diff;
|
||||
|
||||
uint64_t ack_num;
|
||||
|
||||
Instruction( uint64_t s_old_num, uint64_t s_new_num, string s_diff, uint64_t s_ack_num )
|
||||
: old_num( s_old_num ), new_num( s_new_num ), diff( s_diff ), ack_num( s_ack_num )
|
||||
string diff;
|
||||
|
||||
Instruction( uint64_t s_old_num, uint64_t s_new_num, uint64_t s_ack_num, string s_diff )
|
||||
: old_num( s_old_num ), new_num( s_new_num ), ack_num( s_ack_num ), diff( s_diff )
|
||||
{}
|
||||
|
||||
string tostring( void ) { return ""; }
|
||||
string tostring( void );
|
||||
};
|
||||
|
||||
template <class State>
|
||||
@@ -76,8 +76,12 @@ namespace Network {
|
||||
Transport( MyState &initial_state );
|
||||
Transport( MyState &initial_state, const char *key_str, const char *ip, int port );
|
||||
|
||||
void new_state( MyState &s );
|
||||
void tick( void );
|
||||
|
||||
int port( void ) { return connection.port(); }
|
||||
string get_key( void ) { return connection.get_key(); }
|
||||
|
||||
MyState &get_current_state( void ) { return current_state; }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+11
-6
@@ -1,8 +1,8 @@
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "network.hpp"
|
||||
#include "keystroke.hpp"
|
||||
#include "networktransport.hpp"
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
@@ -11,7 +11,9 @@ int main( int argc, char *argv[] )
|
||||
char *ip;
|
||||
int port;
|
||||
|
||||
Network::Connection *n;
|
||||
KeyStroke user;
|
||||
|
||||
Network::Transport<KeyStroke, KeyStroke> *n;
|
||||
|
||||
try {
|
||||
if ( argc > 1 ) {
|
||||
@@ -22,9 +24,9 @@ int main( int argc, char *argv[] )
|
||||
ip = argv[ 2 ];
|
||||
port = atoi( argv[ 3 ] );
|
||||
|
||||
n = new Network::Connection( key, ip, port );
|
||||
n = new Network::Transport<KeyStroke, KeyStroke>( user, key, ip, port );
|
||||
} else {
|
||||
n = new Network::Connection();
|
||||
n = new Network::Transport<KeyStroke, KeyStroke>( user );
|
||||
}
|
||||
} catch ( CryptoException e ) {
|
||||
fprintf( stderr, "Fatal error: %s\n", e.text.c_str() );
|
||||
@@ -34,6 +36,7 @@ int main( int argc, char *argv[] )
|
||||
fprintf( stderr, "Port bound is %d, key is %s\n", n->port(), n->get_key().c_str() );
|
||||
|
||||
if ( server ) {
|
||||
/*
|
||||
while ( true ) {
|
||||
try {
|
||||
string s = n->recv();
|
||||
@@ -43,6 +46,8 @@ int main( int argc, char *argv[] )
|
||||
fprintf( stderr, "Cryptographic error: %s\n", e.text.c_str() );
|
||||
}
|
||||
}
|
||||
*/
|
||||
sleep( 6000 );
|
||||
} else {
|
||||
struct termios saved_termios;
|
||||
struct termios the_termios;
|
||||
@@ -64,10 +69,10 @@ int main( int argc, char *argv[] )
|
||||
while( true ) {
|
||||
char x = getchar();
|
||||
|
||||
string prefix = "Key(" + string( &x, 1 ) + ")";
|
||||
n->get_current_state().key_hit( x );
|
||||
|
||||
try {
|
||||
n->send( prefix );
|
||||
n->tick();
|
||||
} catch ( Network::NetworkException e ) {
|
||||
fprintf( stderr, "%s: %s\r\n", e.function.c_str(), strerror( e.the_errno ) );
|
||||
break;
|
||||
|
||||
@@ -24,5 +24,6 @@ template class vector<wchar_t>;
|
||||
template class vector<int>;
|
||||
template class map<string, Function>;
|
||||
template class vector<bool>;
|
||||
template class deque<char>;
|
||||
|
||||
template class Network::Transport<KeyStroke, KeyStroke>;
|
||||
|
||||
Reference in New Issue
Block a user