Simplify network.cpp to transmit only strings.
This commit is contained in:
+43
-63
@@ -10,50 +10,40 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace Network;
|
||||
using namespace Crypto;
|
||||
|
||||
template <class Payload>
|
||||
Flow<Payload>::Packet::DecodingCache::DecodingCache( string coded_packet, Session *session )
|
||||
: direction( TO_CLIENT ), seq( -1 ), payload_string()
|
||||
/* Read in packet from coded string */
|
||||
Packet::Packet( string coded_packet, Session *session )
|
||||
: seq( -1 ),
|
||||
direction( TO_SERVER ),
|
||||
payload()
|
||||
{
|
||||
Message message = session->decrypt( coded_packet );
|
||||
|
||||
direction = (message.nonce.val() & 8000000000000000) ? TO_CLIENT : TO_SERVER;
|
||||
seq = message.nonce.val() & 0x7FFFFFFFFFFFFFFF;
|
||||
payload_string = message.text;
|
||||
payload = message.text;
|
||||
}
|
||||
|
||||
template <class Payload>
|
||||
Flow<Payload>::Packet::Packet( string coded_packet, Session *session )
|
||||
: decoding_cache( coded_packet, session ),
|
||||
seq( decoding_cache.seq ),
|
||||
direction( decoding_cache.direction ),
|
||||
payload( decoding_cache.payload_string )
|
||||
{
|
||||
decoding_cache = DecodingCache();
|
||||
}
|
||||
|
||||
template <class Payload>
|
||||
string Flow<Payload>::Packet::tostring( Session *session )
|
||||
/* Output coded string from packet */
|
||||
string Packet::tostring( Session *session )
|
||||
{
|
||||
uint64_t direction_seq = (uint64_t( direction == TO_CLIENT ) << 63) | (seq & 0x7FFFFFFFFFFFFFFF);
|
||||
|
||||
return session->encrypt( Message( direction_seq, payload.tostring() ) );
|
||||
return session->encrypt( Message( direction_seq, payload ) );
|
||||
}
|
||||
|
||||
template <class Payload>
|
||||
typename Flow<Payload>::Packet Flow<Payload>::new_packet( Payload &s_payload )
|
||||
Packet Connection::new_packet( string &s_payload )
|
||||
{
|
||||
return Packet( next_seq++, direction, s_payload );
|
||||
}
|
||||
|
||||
template <class Outgoing, class Incoming>
|
||||
void Connection<Outgoing, Incoming>::setup( void )
|
||||
void Connection::setup( void )
|
||||
{
|
||||
/* create socket */
|
||||
sock = socket( AF_INET, SOCK_DGRAM, 0 );
|
||||
if ( sock < 0 ) {
|
||||
perror( "socket" );
|
||||
exit( 1 );
|
||||
throw NetworkException( "socket", errno );
|
||||
}
|
||||
|
||||
/* Bind to free local port.
|
||||
@@ -63,21 +53,18 @@ void Connection<Outgoing, Incoming>::setup( void )
|
||||
local_addr.sin_port = htons( 0 );
|
||||
local_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
if ( bind( sock, (sockaddr *)&local_addr, sizeof( local_addr ) ) < 0 ) {
|
||||
perror( "bind" );
|
||||
exit( 1 );
|
||||
throw NetworkException( "bind", 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 ) {
|
||||
perror( "setsockopt" );
|
||||
exit( 1 );
|
||||
throw NetworkException( "setsockopt", errno );
|
||||
}
|
||||
}
|
||||
|
||||
template <class Outgoing, class Incoming>
|
||||
Connection<Outgoing, Incoming>::Connection() /* server */
|
||||
Connection::Connection() /* server */
|
||||
: sock( -1 ),
|
||||
remote_addr(),
|
||||
server( true ),
|
||||
@@ -85,13 +72,13 @@ Connection<Outgoing, Incoming>::Connection() /* server */
|
||||
MTU( RECEIVE_MTU ),
|
||||
key(),
|
||||
session( key ),
|
||||
flow( TO_CLIENT, &session )
|
||||
direction( TO_CLIENT ),
|
||||
next_seq( 0 )
|
||||
{
|
||||
setup();
|
||||
}
|
||||
|
||||
template <class Outgoing, class Incoming>
|
||||
Connection<Outgoing, Incoming>::Connection( const char *key_str, const char *ip, int port ) /* client */
|
||||
Connection::Connection( const char *key_str, const char *ip, int port ) /* client */
|
||||
: sock( -1 ),
|
||||
remote_addr(),
|
||||
server( false ),
|
||||
@@ -99,7 +86,8 @@ Connection<Outgoing, Incoming>::Connection( const char *key_str, const char *ip,
|
||||
MTU( RECEIVE_MTU ),
|
||||
key( key_str ),
|
||||
session( key ),
|
||||
flow( TO_SERVER, &session )
|
||||
direction( TO_SERVER ),
|
||||
next_seq( 0 )
|
||||
{
|
||||
setup();
|
||||
|
||||
@@ -107,59 +95,53 @@ Connection<Outgoing, Incoming>::Connection( const char *key_str, const char *ip,
|
||||
remote_addr.sin_family = AF_INET;
|
||||
remote_addr.sin_port = htons( port );
|
||||
if ( !inet_aton( ip, &remote_addr.sin_addr ) ) {
|
||||
fprintf( stderr, "Bad IP address %s\n", ip );
|
||||
exit( 1 );
|
||||
int saved_errno = errno;
|
||||
char buffer[ 2048 ];
|
||||
snprintf( buffer, 2048, "Bad IP address (%s)", ip );
|
||||
throw NetworkException( buffer, saved_errno );
|
||||
}
|
||||
|
||||
if ( connect( sock, (sockaddr *)&remote_addr, sizeof( remote_addr ) ) < 0 ) {
|
||||
perror( "connect" );
|
||||
exit( 1 );
|
||||
throw NetworkException( "connect", errno );
|
||||
}
|
||||
|
||||
attached = true;
|
||||
}
|
||||
|
||||
template <class Outgoing, class Incoming>
|
||||
void Connection<Outgoing, Incoming>::update_MTU( void )
|
||||
void Connection::update_MTU( void )
|
||||
{
|
||||
socklen_t optlen = sizeof( MTU );
|
||||
if ( getsockopt( sock, IPPROTO_IP, IP_MTU, &MTU, &optlen ) < 0 ) {
|
||||
perror( "getsockopt" );
|
||||
exit( 1 );
|
||||
throw NetworkException( "getsockopt", errno );
|
||||
}
|
||||
|
||||
if ( optlen != sizeof( MTU ) ) {
|
||||
fprintf( stderr, "Error getting path MTU.\n" );
|
||||
exit( 1 );
|
||||
throw NetworkException( "Error getting path MTU", errno );
|
||||
}
|
||||
|
||||
fprintf( stderr, "Path MTU: %d\n", MTU );
|
||||
}
|
||||
|
||||
template <class Outgoing, class Incoming>
|
||||
bool Connection<Outgoing, Incoming>::send( Outgoing &s )
|
||||
void Connection::send( string &s )
|
||||
{
|
||||
assert( attached );
|
||||
|
||||
string p = flow.new_packet( s ).tostring( &session );
|
||||
string p = new_packet( s ).tostring( &session );
|
||||
|
||||
ssize_t bytes_sent = sendto( sock, p.data(), p.size(), 0,
|
||||
(sockaddr *)&remote_addr, sizeof( remote_addr ) );
|
||||
|
||||
if ( (bytes_sent < 0) && (errno == EMSGSIZE) ) {
|
||||
update_MTU();
|
||||
return false;
|
||||
throw MTUException( MTU );
|
||||
} else if ( bytes_sent == static_cast<int>( p.size() ) ) {
|
||||
return true;
|
||||
return;
|
||||
} else {
|
||||
perror( "sendto" );
|
||||
exit( 1 );
|
||||
return false;
|
||||
throw NetworkException( "sendto", errno );
|
||||
}
|
||||
}
|
||||
|
||||
template <class Outgoing, class Incoming>
|
||||
Incoming Connection<Outgoing, Incoming>::recv( void )
|
||||
string Connection::recv( void )
|
||||
{
|
||||
struct sockaddr_in packet_remote_addr;
|
||||
|
||||
@@ -170,17 +152,17 @@ Incoming Connection<Outgoing, Incoming>::recv( void )
|
||||
ssize_t received_len = recvfrom( sock, buf, RECEIVE_MTU, 0, (sockaddr *)&packet_remote_addr, &addrlen );
|
||||
|
||||
if ( received_len < 0 ) {
|
||||
perror( "recvfrom" );
|
||||
exit( 1 );
|
||||
throw NetworkException( "recvfrom", errno );
|
||||
}
|
||||
|
||||
if ( received_len > RECEIVE_MTU ) {
|
||||
fprintf( stderr, "Received oversize datagram (size %d) and limit is %d.\n",
|
||||
static_cast<int>( received_len ), RECEIVE_MTU );
|
||||
exit( 1 );
|
||||
char buffer[ 2048 ];
|
||||
snprintf( buffer, 2048, "Received oversize datagram (size %d) and limit is %d\n",
|
||||
static_cast<int>( received_len ), RECEIVE_MTU );
|
||||
throw NetworkException( buffer, errno );
|
||||
}
|
||||
|
||||
typename Flow<Incoming>::Packet p( string( buf, received_len ), &session );
|
||||
Packet p( string( buf, received_len ), &session );
|
||||
dos_assert( p.direction == (server ? TO_SERVER : TO_CLIENT) ); /* prevent malicious playback to sender */
|
||||
|
||||
/* server auto-adjusts to client */
|
||||
@@ -199,15 +181,13 @@ Incoming Connection<Outgoing, Incoming>::recv( void )
|
||||
return p.payload;
|
||||
}
|
||||
|
||||
template <class Outgoing, class Incoming>
|
||||
int Connection<Outgoing, Incoming>::port( void )
|
||||
int Connection::port( void )
|
||||
{
|
||||
struct sockaddr_in local_addr;
|
||||
socklen_t addrlen = sizeof( local_addr );
|
||||
|
||||
if ( getsockname( sock, (sockaddr *)&local_addr, &addrlen ) < 0 ) {
|
||||
perror( "getsockname" );
|
||||
exit( 1 );
|
||||
throw NetworkException( "getsockname", errno );
|
||||
}
|
||||
|
||||
return ntohs( local_addr.sin_port );
|
||||
|
||||
Reference in New Issue
Block a user