Clean out some bugs in sender

This commit is contained in:
Keith Winstein
2011-08-09 02:34:20 -04:00
parent cae526fceb
commit 188c44f5be
10 changed files with 142 additions and 46 deletions
+3 -3
View File
@@ -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)
+44
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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(); }
};
}
+23
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+1
View File
@@ -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>;