Get rid of path MTU discovery

This commit is contained in:
Keith Winstein
2012-01-01 21:42:05 -05:00
parent 3a722cb3d3
commit 267f5a31a7
5 changed files with 19 additions and 90 deletions
+1 -1
View File
@@ -74,7 +74,7 @@ Base64Key::Base64Key()
} }
} }
string Base64Key::printable_key( void ) string Base64Key::printable_key( void ) const
{ {
char base64[ 25 ]; char base64[ 25 ];
+1 -1
View File
@@ -23,7 +23,7 @@ namespace Crypto {
public: public:
Base64Key(); /* random key */ Base64Key(); /* random key */
Base64Key( string printable_key ); Base64Key( string printable_key );
string printable_key( void ); string printable_key( void ) const;
unsigned char *data( void ) { return key; } unsigned char *data( void ) { return key; }
}; };
+3 -46
View File
@@ -75,13 +75,6 @@ void Connection::setup( void )
if ( sock < 0 ) { if ( sock < 0 ) {
throw NetworkException( "socket", errno ); throw NetworkException( "socket", errno );
} }
/* Enable path MTU discovery */
char flag = IP_PMTUDISC_DO;
socklen_t optlen = sizeof( flag );
if ( setsockopt( sock, IPPROTO_IP, IP_MTU_DISCOVER, &flag, optlen ) < 0 ) {
throw NetworkException( "setsockopt", errno );
}
} }
Connection::Connection() /* server */ Connection::Connection() /* server */
@@ -89,7 +82,6 @@ Connection::Connection() /* server */
remote_addr(), remote_addr(),
server( true ), server( true ),
attached( false ), attached( false ),
MTU( RECEIVE_MTU ),
key(), key(),
session( key ), session( key ),
direction( TO_CLIENT ), direction( TO_CLIENT ),
@@ -119,7 +111,6 @@ Connection::Connection( const char *key_str, const char *ip, int port ) /* clien
remote_addr(), remote_addr(),
server( false ), server( false ),
attached( false ), attached( false ),
MTU( RECEIVE_MTU ),
key( key_str ), key( key_str ),
session( key ), session( key ),
direction( TO_SERVER ), direction( TO_SERVER ),
@@ -152,37 +143,6 @@ Connection::Connection( const char *key_str, const char *ip, int port ) /* clien
attached = true; attached = true;
} }
void Connection::update_MTU( void )
{
if ( !attached ) {
return;
}
/* We don't want to use our main socket because we don't want to have to connect it */
int path_MTU_socket = socket( AF_INET, SOCK_DGRAM, 0 );
if ( path_MTU_socket < 0 ) {
throw NetworkException( "socket", errno );
}
/* Connect socket so we can retrieve path MTU */
if ( connect( path_MTU_socket, (sockaddr *)&remote_addr, sizeof( remote_addr ) ) < 0 ) {
throw NetworkException( "connect", errno );
}
socklen_t optlen = sizeof( MTU );
if ( getsockopt( path_MTU_socket, IPPROTO_IP, IP_MTU, &MTU, &optlen ) < 0 ) {
throw NetworkException( "getsockopt", errno );
}
if ( optlen != sizeof( MTU ) ) {
throw NetworkException( "Error getting path MTU", errno );
}
if ( close( path_MTU_socket ) < 0 ) {
throw NetworkException( "close", errno );
}
}
void Connection::send( string s ) void Connection::send( string s )
{ {
assert( attached ); assert( attached );
@@ -194,10 +154,7 @@ void Connection::send( string s )
ssize_t bytes_sent = sendto( sock, p.data(), p.size(), 0, ssize_t bytes_sent = sendto( sock, p.data(), p.size(), 0,
(sockaddr *)&remote_addr, sizeof( remote_addr ) ); (sockaddr *)&remote_addr, sizeof( remote_addr ) );
if ( (bytes_sent < 0) && (errno == EMSGSIZE) ) { if ( bytes_sent == static_cast<int>( p.size() ) ) {
update_MTU();
throw MTUException( MTU );
} else if ( bytes_sent == static_cast<int>( p.size() ) ) {
return; return;
} else { } else {
throw NetworkException( "sendto", errno ); throw NetworkException( "sendto", errno );
@@ -274,7 +231,7 @@ string Connection::recv( void )
return p.payload; /* we do return out-of-order or duplicated packets to caller */ return p.payload; /* we do return out-of-order or duplicated packets to caller */
} }
int Connection::port( void ) int Connection::port( void ) const
{ {
struct sockaddr_in local_addr; struct sockaddr_in local_addr;
socklen_t addrlen = sizeof( local_addr ); socklen_t addrlen = sizeof( local_addr );
@@ -322,7 +279,7 @@ uint16_t Network::timestamp_diff( uint16_t tsnew, uint16_t tsold )
return diff; return diff;
} }
uint64_t Connection::timeout( void ) uint64_t Connection::timeout( void ) const
{ {
uint64_t RTO = lrint( ceil( SRTT + 4 * RTTVAR ) ); uint64_t RTO = lrint( ceil( SRTT + 4 * RTTVAR ) );
if ( RTO < MIN_RTO ) { if ( RTO < MIN_RTO ) {
+8 -17
View File
@@ -18,12 +18,6 @@ namespace Network {
uint16_t timestamp16( void ); uint16_t timestamp16( void );
uint16_t timestamp_diff( uint16_t tsnew, uint16_t tsold ); uint16_t timestamp_diff( uint16_t tsnew, uint16_t tsold );
class MTUException {
public:
int MTU;
MTUException( int s_MTU ) : MTU( s_MTU ) {};
};
class NetworkException { class NetworkException {
public: public:
string function; string function;
@@ -57,6 +51,7 @@ namespace Network {
class Connection { class Connection {
private: private:
static const int RECEIVE_MTU = 2048; static const int RECEIVE_MTU = 2048;
static const int SEND_MTU = 1400;
static const uint64_t MIN_RTO = 50; /* ms */ static const uint64_t MIN_RTO = 50; /* ms */
static const uint64_t MAX_RTO = 1000; /* ms */ static const uint64_t MAX_RTO = 1000; /* ms */
@@ -66,8 +61,6 @@ namespace Network {
bool server; bool server;
bool attached; bool attached;
int MTU;
Base64Key key; Base64Key key;
Session session; Session session;
@@ -91,17 +84,15 @@ namespace Network {
void send( string s ); void send( string s );
string recv( void ); string recv( void );
int fd( void ) { return sock; } int fd( void ) const { return sock; }
void update_MTU( void ); int get_MTU( void ) const { return SEND_MTU; }
int get_MTU( void ) { return MTU; }
int port( void ); int port( void ) const;
string get_key( void ) { return key.printable_key(); } string get_key( void ) const { return key.printable_key(); }
bool get_attached( void ) { return attached; } bool get_attached( void ) const { return attached; }
uint64_t timeout( void ); uint64_t timeout( void ) const;
double get_SRTT( void ) { return SRTT; } double get_SRTT( void ) const { return SRTT; }
// bool pending_timestamp( void ) { return ( saved_timestamp != uint16_t(-1) ); }
}; };
} }
+6 -25
View File
@@ -159,32 +159,14 @@ void TransportSender<MyState>::send_to_receiver( string diff )
new_num = uint64_t( -1 ); new_num = uint64_t( -1 );
} }
int MTU_tries = 0; if ( new_num == sent_states.back().num ) {
while ( 1 ) { sent_states.back().timestamp = timestamp();
MTU_tries++; } else {
add_sent_state( timestamp(), new_num, current_state );
if ( MTU_tries > 20 ) {
fprintf( stderr, "Error, could not send fragments after 20 tries (MTU = %d).\n",
connection->get_MTU() );
return;
}
if ( new_num == sent_states.back().num ) {
sent_states.back().timestamp = timestamp();
} else {
// sent_states.push_back( TimestampedState<MyState>( timestamp(), new_num, current_state ) );
add_sent_state( timestamp(), new_num, current_state );
}
try {
send_in_fragments( diff, new_num ); // Can throw NetworkException
break;
} catch ( MTUException m ) {
fprintf( stderr, "Caught Path MTU exception, MTU now = %d\n", connection->get_MTU() );
new_num++;
}
} }
send_in_fragments( diff, new_num ); // Can throw NetworkException
/* successfully sent, probably */ /* successfully sent, probably */
/* ("probably" because the FIRST size-exceeded datagram doesn't get an error) */ /* ("probably" because the FIRST size-exceeded datagram doesn't get an error) */
assumed_receiver_state = sent_states.end(); assumed_receiver_state = sent_states.end();
@@ -246,7 +228,6 @@ void TransportSender<MyState>::send_in_fragments( string diff, uint64_t new_num
shutdown_tries++; shutdown_tries++;
} }
connection->update_MTU();
vector<Fragment> fragments = fragmenter.make_fragments( inst, connection->get_MTU() ); vector<Fragment> fragments = fragmenter.make_fragments( inst, connection->get_MTU() );
for ( auto i = fragments.begin(); i != fragments.end(); i++ ) { for ( auto i = fragments.begin(); i != fragments.end(); i++ ) {