2016-01-24 18:53:54 +01:00
use std ::sync ::Arc ;
2015-12-02 20:11:13 +01:00
use std ::collections ::VecDeque ;
2016-01-21 16:48:37 +01:00
use mio ::{ Handler , Token , EventSet , EventLoop , PollOpt , TryRead , TryWrite } ;
2015-11-30 16:38:55 +01:00
use mio ::tcp ::* ;
use hash ::* ;
2015-12-02 12:07:46 +01:00
use sha3 ::* ;
2015-11-30 16:38:55 +01:00
use bytes ::* ;
2015-12-02 12:07:46 +01:00
use rlp ::* ;
use std ::io ::{ self , Cursor , Read } ;
2016-01-10 12:53:55 +01:00
use error ::* ;
2016-01-21 16:48:37 +01:00
use io ::{ IoContext , StreamToken } ;
2016-01-13 11:31:37 +01:00
use network ::error ::NetworkError ;
2015-12-02 12:07:46 +01:00
use network ::handshake ::Handshake ;
2016-01-24 18:53:54 +01:00
use network ::stats ::NetworkStats ;
2015-12-02 12:07:46 +01:00
use crypto ;
use rcrypto ::blockmodes ::* ;
use rcrypto ::aessafe ::* ;
use rcrypto ::symmetriccipher ::* ;
use rcrypto ::buffer ::* ;
use tiny_keccak ::Keccak ;
const ENCRYPTED_HEADER_LEN : usize = 32 ;
2016-01-21 16:48:37 +01:00
const RECIEVE_PAYLOAD_TIMEOUT : u64 = 30000 ;
2015-11-30 16:38:55 +01:00
2016-01-10 22:42:27 +01:00
/// Low level tcp connection
2015-11-30 16:38:55 +01:00
pub struct Connection {
2016-01-10 22:42:27 +01:00
/// Connection id (token)
2016-01-21 16:48:37 +01:00
pub token : StreamToken ,
2016-01-10 22:42:27 +01:00
/// Network socket
2015-12-03 15:11:40 +01:00
pub socket : TcpStream ,
2016-01-10 22:42:27 +01:00
/// Receive buffer
2015-11-30 16:38:55 +01:00
rec_buf : Bytes ,
2016-01-10 22:42:27 +01:00
/// Expected size
2015-11-30 16:38:55 +01:00
rec_size : usize ,
2016-01-10 22:42:27 +01:00
/// Send out packets FIFO
2015-12-02 20:11:13 +01:00
send_queue : VecDeque < Cursor < Bytes > > ,
2016-01-10 22:42:27 +01:00
/// Event flags this connection expects
2015-11-30 16:38:55 +01:00
interest : EventSet ,
2016-01-24 18:53:54 +01:00
/// Shared network staistics
stats : Arc < NetworkStats > ,
2015-11-30 16:38:55 +01:00
}
2016-01-10 22:42:27 +01:00
/// Connection write status.
2015-12-02 20:11:13 +01:00
#[ derive(PartialEq, Eq) ]
2015-11-30 16:38:55 +01:00
pub enum WriteStatus {
2016-01-10 22:42:27 +01:00
/// Some data is still pending for current packet
2015-11-30 16:38:55 +01:00
Ongoing ,
2016-01-10 22:42:27 +01:00
/// All data sent.
2015-11-30 16:38:55 +01:00
Complete
}
2015-12-02 20:11:13 +01:00
impl Connection {
2016-01-10 22:42:27 +01:00
/// Create a new connection with given id and socket.
2016-01-24 18:53:54 +01:00
pub fn new ( token : StreamToken , socket : TcpStream , stats : Arc < NetworkStats > ) -> Connection {
2015-12-02 20:11:13 +01:00
Connection {
token : token ,
socket : socket ,
send_queue : VecDeque ::new ( ) ,
rec_buf : Bytes ::new ( ) ,
rec_size : 0 ,
2016-01-21 16:48:37 +01:00
interest : EventSet ::hup ( ) | EventSet ::readable ( ) ,
2016-01-24 18:53:54 +01:00
stats : stats ,
2015-12-02 20:11:13 +01:00
}
}
2016-01-10 22:42:27 +01:00
/// Put a connection into read mode. Receiving up `size` bytes of data.
2015-12-02 20:11:13 +01:00
pub fn expect ( & mut self , size : usize ) {
if self . rec_size ! = self . rec_buf . len ( ) {
warn! ( target :" net " , " Unexpected connection read start " ) ;
}
unsafe { self . rec_buf . set_len ( 0 ) }
self . rec_size = size ;
}
2016-01-10 22:42:27 +01:00
/// Readable IO handler. Called when there is some data to be read.
2015-12-02 20:11:13 +01:00
pub fn readable ( & mut self ) -> io ::Result < Option < Bytes > > {
if self . rec_size = = 0 | | self . rec_buf . len ( ) > = self . rec_size {
warn! ( target :" net " , " Unexpected connection read " ) ;
}
let max = self . rec_size - self . rec_buf . len ( ) ;
// resolve "multiple applicable items in scope [E0034]" error
2015-12-03 15:11:40 +01:00
let sock_ref = < TcpStream as Read > ::by_ref ( & mut self . socket ) ;
2015-12-02 20:11:13 +01:00
match sock_ref . take ( max as u64 ) . try_read_buf ( & mut self . rec_buf ) {
2016-01-24 18:53:54 +01:00
Ok ( Some ( size ) ) if size ! = 0 = > {
self . stats . inc_recv ( size ) ;
if self . rec_size ! = 0 & & self . rec_buf . len ( ) = = self . rec_size {
self . rec_size = 0 ;
Ok ( Some ( ::std ::mem ::replace ( & mut self . rec_buf , Bytes ::new ( ) ) ) )
} else { Ok ( None ) }
2015-12-02 20:11:13 +01:00
} ,
Ok ( _ ) = > Ok ( None ) ,
Err ( e ) = > Err ( e ) ,
}
}
2015-12-03 15:11:40 +01:00
2016-01-10 22:42:27 +01:00
/// Add a packet to send queue.
2016-01-08 13:10:00 +01:00
pub fn send ( & mut self , data : Bytes ) {
2016-01-19 12:14:29 +01:00
if ! data . is_empty ( ) {
2015-12-02 20:11:13 +01:00
self . send_queue . push_back ( Cursor ::new ( data ) ) ;
}
2015-12-03 15:11:40 +01:00
if ! self . interest . is_writable ( ) {
self . interest . insert ( EventSet ::writable ( ) ) ;
}
2015-12-02 20:11:13 +01:00
}
2016-01-10 22:42:27 +01:00
/// Writable IO handler. Called when the socket is ready to send.
2015-12-02 20:11:13 +01:00
pub fn writable ( & mut self ) -> io ::Result < WriteStatus > {
if self . send_queue . is_empty ( ) {
return Ok ( WriteStatus ::Complete )
}
{
let buf = self . send_queue . front_mut ( ) . unwrap ( ) ;
let send_size = buf . get_ref ( ) . len ( ) ;
if ( buf . position ( ) as usize ) > = send_size {
warn! ( target :" net " , " Unexpected connection data " ) ;
return Ok ( WriteStatus ::Complete )
}
match self . socket . try_write_buf ( buf ) {
2016-01-24 18:53:54 +01:00
Ok ( Some ( size ) ) if ( buf . position ( ) as usize ) < send_size = > {
2015-12-02 20:11:13 +01:00
self . interest . insert ( EventSet ::writable ( ) ) ;
2016-01-24 18:53:54 +01:00
self . stats . inc_send ( size ) ;
2015-12-02 20:11:13 +01:00
Ok ( WriteStatus ::Ongoing )
} ,
2016-01-24 18:53:54 +01:00
Ok ( Some ( size ) ) if ( buf . position ( ) as usize ) = = send_size = > {
self . stats . inc_send ( size ) ;
2015-12-02 20:11:13 +01:00
Ok ( WriteStatus ::Complete )
} ,
2016-01-24 18:53:54 +01:00
Ok ( Some ( _ ) ) = > { panic! ( " Wrote past buffer " ) ; } ,
Ok ( None ) = > Ok ( WriteStatus ::Ongoing ) ,
2015-12-02 20:11:13 +01:00
Err ( e ) = > Err ( e )
}
2015-12-03 15:11:40 +01:00
} . and_then ( | r | {
if r = = WriteStatus ::Complete {
2015-12-02 20:11:13 +01:00
self . send_queue . pop_front ( ) ;
2016-01-08 13:10:00 +01:00
}
2015-12-03 15:11:40 +01:00
if self . send_queue . is_empty ( ) {
self . interest . remove ( EventSet ::writable ( ) ) ;
2015-12-02 20:11:13 +01:00
}
2015-12-03 15:11:40 +01:00
else {
self . interest . insert ( EventSet ::writable ( ) ) ;
}
Ok ( r )
} )
2015-12-02 20:11:13 +01:00
}
2016-01-10 22:42:27 +01:00
/// Register this connection with the IO event loop.
2016-01-21 16:48:37 +01:00
pub fn register_socket < Host : Handler > ( & self , reg : Token , event_loop : & mut EventLoop < Host > ) -> io ::Result < ( ) > {
trace! ( target : " net " , " connection register; token={:?} " , reg ) ;
event_loop . register ( & self . socket , reg , self . interest , PollOpt ::edge ( ) | PollOpt ::oneshot ( ) ) . or_else ( | e | {
2016-01-23 02:36:58 +01:00
debug! ( " Failed to register {:?}, {:?} " , reg , e ) ;
Ok ( ( ) )
2015-12-03 15:11:40 +01:00
} )
}
2016-01-10 22:42:27 +01:00
/// Update connection registration. Should be called at the end of the IO handler.
2016-01-21 16:48:37 +01:00
pub fn update_socket < Host : Handler > ( & self , reg : Token , event_loop : & mut EventLoop < Host > ) -> io ::Result < ( ) > {
trace! ( target : " net " , " connection reregister; token={:?} " , reg ) ;
event_loop . reregister ( & self . socket , reg , self . interest , PollOpt ::edge ( ) | PollOpt ::oneshot ( ) ) . or_else ( | e | {
2016-01-23 02:36:58 +01:00
debug! ( " Failed to reregister {:?}, {:?} " , reg , e ) ;
Ok ( ( ) )
2015-12-03 15:11:40 +01:00
} )
}
2016-01-22 18:13:59 +01:00
/// Delete connection registration. Should be called at the end of the IO handler.
pub fn deregister_socket < Host : Handler > ( & self , event_loop : & mut EventLoop < Host > ) -> io ::Result < ( ) > {
trace! ( target : " net " , " connection deregister; token={:?} " , self . token ) ;
event_loop . deregister ( & self . socket ) . ok ( ) ; // ignore errors here
Ok ( ( ) )
}
2015-12-02 20:11:13 +01:00
}
2016-01-10 22:42:27 +01:00
/// RLPx packet
2015-12-02 20:11:13 +01:00
pub struct Packet {
pub protocol : u16 ,
pub data : Bytes ,
}
2016-01-10 22:42:27 +01:00
/// Encrypted connection receiving state.
2015-12-02 12:07:46 +01:00
enum EncryptedConnectionState {
2016-01-10 22:42:27 +01:00
/// Reading a header.
2015-12-02 12:07:46 +01:00
Header ,
2016-01-10 22:42:27 +01:00
/// Reading the rest of the packet.
2015-12-02 12:07:46 +01:00
Payload ,
}
2016-01-10 22:42:27 +01:00
/// Connection implementing RLPx framing
/// https://github.com/ethereum/devp2p/blob/master/rlpx.md#framing
2015-12-02 12:07:46 +01:00
pub struct EncryptedConnection {
2016-01-10 22:42:27 +01:00
/// Underlying tcp connection
2015-12-02 12:07:46 +01:00
connection : Connection ,
2016-01-10 22:42:27 +01:00
/// Egress data encryptor
2015-12-03 15:11:40 +01:00
encoder : CtrMode < AesSafe256Encryptor > ,
2016-01-10 22:42:27 +01:00
/// Ingress data decryptor
2015-12-03 15:11:40 +01:00
decoder : CtrMode < AesSafe256Encryptor > ,
2016-01-10 22:42:27 +01:00
/// Ingress data decryptor
2015-12-03 15:11:40 +01:00
mac_encoder : EcbEncryptor < AesSafe256Encryptor , EncPadding < NoPadding > > ,
2016-01-10 22:42:27 +01:00
/// MAC for egress data
2015-12-02 12:07:46 +01:00
egress_mac : Keccak ,
2016-01-10 22:42:27 +01:00
/// MAC for ingress data
2015-12-02 12:07:46 +01:00
ingress_mac : Keccak ,
2016-01-10 22:42:27 +01:00
/// Read state
2015-12-02 12:07:46 +01:00
read_state : EncryptedConnectionState ,
2016-01-10 22:42:27 +01:00
/// Protocol id for the last received packet
2015-12-02 12:07:46 +01:00
protocol_id : u16 ,
2016-01-10 22:42:27 +01:00
/// Payload expected to be received for the last header.
2016-01-10 14:02:01 +01:00
payload_len : usize ,
2015-12-02 12:07:46 +01:00
}
impl EncryptedConnection {
2016-02-02 20:58:12 +01:00
/// Get socket token
pub fn token ( & self ) -> StreamToken {
self . connection . token
}
2016-01-10 22:42:27 +01:00
/// Create an encrypted connection out of the handshake. Consumes a handshake object.
2016-01-21 16:48:37 +01:00
pub fn new ( mut handshake : Handshake ) -> Result < EncryptedConnection , UtilError > {
2015-12-02 12:07:46 +01:00
let shared = try ! ( crypto ::ecdh ::agree ( handshake . ecdhe . secret ( ) , & handshake . remote_public ) ) ;
let mut nonce_material = H512 ::new ( ) ;
if handshake . originated {
handshake . remote_nonce . copy_to ( & mut nonce_material [ 0 .. 32 ] ) ;
handshake . nonce . copy_to ( & mut nonce_material [ 32 .. 64 ] ) ;
}
else {
handshake . nonce . copy_to ( & mut nonce_material [ 0 .. 32 ] ) ;
handshake . remote_nonce . copy_to ( & mut nonce_material [ 32 .. 64 ] ) ;
}
let mut key_material = H512 ::new ( ) ;
shared . copy_to ( & mut key_material [ 0 .. 32 ] ) ;
nonce_material . sha3_into ( & mut key_material [ 32 .. 64 ] ) ;
key_material . sha3 ( ) . copy_to ( & mut key_material [ 32 .. 64 ] ) ;
2015-12-03 15:11:40 +01:00
key_material . sha3 ( ) . copy_to ( & mut key_material [ 32 .. 64 ] ) ;
2015-12-02 12:07:46 +01:00
let iv = vec! [ 0 u8 ; 16 ] ;
2015-12-03 15:11:40 +01:00
let encoder = CtrMode ::new ( AesSafe256Encryptor ::new ( & key_material [ 32 .. 64 ] ) , iv ) ;
2015-12-02 12:07:46 +01:00
let iv = vec! [ 0 u8 ; 16 ] ;
2015-12-03 15:11:40 +01:00
let decoder = CtrMode ::new ( AesSafe256Encryptor ::new ( & key_material [ 32 .. 64 ] ) , iv ) ;
2015-12-02 12:07:46 +01:00
key_material . sha3 ( ) . copy_to ( & mut key_material [ 32 .. 64 ] ) ;
2015-12-03 15:11:40 +01:00
let mac_encoder = EcbEncryptor ::new ( AesSafe256Encryptor ::new ( & key_material [ 32 .. 64 ] ) , NoPadding ) ;
2015-12-02 12:07:46 +01:00
let mut egress_mac = Keccak ::new_keccak256 ( ) ;
let mut mac_material = & H256 ::from_slice ( & key_material [ 32 .. 64 ] ) ^ & handshake . remote_nonce ;
egress_mac . update ( & mac_material ) ;
egress_mac . update ( if handshake . originated { & handshake . auth_cipher } else { & handshake . ack_cipher } ) ;
2015-12-03 15:11:40 +01:00
2015-12-02 12:07:46 +01:00
let mut ingress_mac = Keccak ::new_keccak256 ( ) ;
2015-12-03 15:11:40 +01:00
mac_material = & H256 ::from_slice ( & key_material [ 32 .. 64 ] ) ^ & handshake . nonce ;
2015-12-02 12:07:46 +01:00
ingress_mac . update ( & mac_material ) ;
ingress_mac . update ( if handshake . originated { & handshake . ack_cipher } else { & handshake . auth_cipher } ) ;
2016-01-21 16:48:37 +01:00
handshake . connection . expect ( ENCRYPTED_HEADER_LEN ) ;
2015-12-02 12:07:46 +01:00
Ok ( EncryptedConnection {
connection : handshake . connection ,
encoder : encoder ,
decoder : decoder ,
mac_encoder : mac_encoder ,
egress_mac : egress_mac ,
ingress_mac : ingress_mac ,
read_state : EncryptedConnectionState ::Header ,
protocol_id : 0 ,
payload_len : 0
} )
}
2016-01-10 22:42:27 +01:00
/// Send a packet
2016-01-10 12:53:55 +01:00
pub fn send_packet ( & mut self , payload : & [ u8 ] ) -> Result < ( ) , UtilError > {
2015-12-02 12:07:46 +01:00
let mut header = RlpStream ::new ( ) ;
let len = payload . len ( ) as usize ;
header . append_raw ( & [ ( len > > 16 ) as u8 , ( len > > 8 ) as u8 , len as u8 ] , 1 ) ;
header . append_raw ( & [ 0xc2 u8 , 0x80 u8 , 0x80 u8 ] , 1 ) ;
//TODO: ger rid of vectors here
let mut header = header . out ( ) ;
let padding = ( 16 - ( payload . len ( ) % 16 ) ) % 16 ;
header . resize ( 16 , 0 u8 ) ;
let mut packet = vec! [ 0 u8 ; ( 32 + payload . len ( ) + padding + 16 ) ] ;
self . encoder . encrypt ( & mut RefReadBuffer ::new ( & header ) , & mut RefWriteBuffer ::new ( & mut packet ) , false ) . expect ( " Invalid length or padding " ) ;
2015-12-03 15:11:40 +01:00
EncryptedConnection ::update_mac ( & mut self . egress_mac , & mut self . mac_encoder , & packet [ 0 .. 16 ] ) ;
2015-12-02 12:07:46 +01:00
self . egress_mac . clone ( ) . finalize ( & mut packet [ 16 .. 32 ] ) ;
2015-12-03 15:11:40 +01:00
self . encoder . encrypt ( & mut RefReadBuffer ::new ( & payload ) , & mut RefWriteBuffer ::new ( & mut packet [ 32 .. ( 32 + len ) ] ) , padding = = 0 ) . expect ( " Invalid length or padding " ) ;
2015-12-02 12:07:46 +01:00
if padding ! = 0 {
2016-01-10 14:02:01 +01:00
let pad = [ 0 u8 ; 16 ] ;
2015-12-03 15:11:40 +01:00
self . encoder . encrypt ( & mut RefReadBuffer ::new ( & pad [ 0 .. padding ] ) , & mut RefWriteBuffer ::new ( & mut packet [ ( 32 + len ) .. ( 32 + len + padding ) ] ) , true ) . expect ( " Invalid length or padding " ) ;
2015-12-02 12:07:46 +01:00
}
self . egress_mac . update ( & packet [ 32 .. ( 32 + len + padding ) ] ) ;
2015-12-03 15:11:40 +01:00
EncryptedConnection ::update_mac ( & mut self . egress_mac , & mut self . mac_encoder , & [ 0 u8 ; 0 ] ) ;
2015-12-02 12:07:46 +01:00
self . egress_mac . clone ( ) . finalize ( & mut packet [ ( 32 + len + padding ) .. ] ) ;
2015-12-02 20:11:13 +01:00
self . connection . send ( packet ) ;
2015-12-02 12:07:46 +01:00
Ok ( ( ) )
}
2016-01-10 22:42:27 +01:00
/// Decrypt and authenticate an incoming packet header. Prepare for receiving payload.
2016-01-10 12:53:55 +01:00
fn read_header ( & mut self , header : & [ u8 ] ) -> Result < ( ) , UtilError > {
2015-12-02 12:07:46 +01:00
if header . len ( ) ! = ENCRYPTED_HEADER_LEN {
2016-01-10 12:53:55 +01:00
return Err ( From ::from ( NetworkError ::Auth ) ) ;
2015-12-02 12:07:46 +01:00
}
2015-12-03 15:11:40 +01:00
EncryptedConnection ::update_mac ( & mut self . ingress_mac , & mut self . mac_encoder , & header [ 0 .. 16 ] ) ;
2015-12-02 12:07:46 +01:00
let mac = & header [ 16 .. ] ;
2015-12-03 15:11:40 +01:00
let mut expected = H256 ::new ( ) ;
2015-12-02 12:07:46 +01:00
self . ingress_mac . clone ( ) . finalize ( & mut expected ) ;
2015-12-03 15:11:40 +01:00
if mac ! = & expected [ 0 .. 16 ] {
2016-01-10 12:53:55 +01:00
return Err ( From ::from ( NetworkError ::Auth ) ) ;
2015-12-02 12:07:46 +01:00
}
2015-12-03 15:11:40 +01:00
let mut hdec = H128 ::new ( ) ;
self . decoder . decrypt ( & mut RefReadBuffer ::new ( & header [ 0 .. 16 ] ) , & mut RefWriteBuffer ::new ( & mut hdec ) , false ) . expect ( " Invalid length or padding " ) ;
let length = ( ( ( ( hdec [ 0 ] as u32 ) < < 8 ) + ( hdec [ 1 ] as u32 ) ) < < 8 ) + ( hdec [ 2 ] as u32 ) ;
let header_rlp = UntrustedRlp ::new ( & hdec [ 3 .. 6 ] ) ;
2015-12-17 14:05:13 +01:00
let protocol_id = try ! ( header_rlp . val_at ::< u16 > ( 0 ) ) ;
2015-12-02 12:07:46 +01:00
2016-01-10 14:02:01 +01:00
self . payload_len = length as usize ;
2015-12-02 12:07:46 +01:00
self . protocol_id = protocol_id ;
self . read_state = EncryptedConnectionState ::Payload ;
let padding = ( 16 - ( length % 16 ) ) % 16 ;
let full_length = length + padding + 16 ;
self . connection . expect ( full_length as usize ) ;
Ok ( ( ) )
}
2016-01-10 22:42:27 +01:00
/// Decrypt and authenticate packet payload.
2016-01-10 12:53:55 +01:00
fn read_payload ( & mut self , payload : & [ u8 ] ) -> Result < Packet , UtilError > {
2015-12-02 12:07:46 +01:00
let padding = ( 16 - ( self . payload_len % 16 ) ) % 16 ;
2016-01-10 14:02:01 +01:00
let full_length = self . payload_len + padding + 16 ;
2015-12-02 12:07:46 +01:00
if payload . len ( ) ! = full_length {
2016-01-10 12:53:55 +01:00
return Err ( From ::from ( NetworkError ::Auth ) ) ;
2015-12-02 12:07:46 +01:00
}
self . ingress_mac . update ( & payload [ 0 .. payload . len ( ) - 16 ] ) ;
2015-12-03 15:11:40 +01:00
EncryptedConnection ::update_mac ( & mut self . ingress_mac , & mut self . mac_encoder , & [ 0 u8 ; 0 ] ) ;
2015-12-02 12:07:46 +01:00
let mac = & payload [ ( payload . len ( ) - 16 ) .. ] ;
let mut expected = H128 ::new ( ) ;
self . ingress_mac . clone ( ) . finalize ( & mut expected ) ;
if mac ! = & expected [ .. ] {
2016-01-10 12:53:55 +01:00
return Err ( From ::from ( NetworkError ::Auth ) ) ;
2015-12-02 12:07:46 +01:00
}
2016-01-10 14:02:01 +01:00
let mut packet = vec! [ 0 u8 ; self . payload_len ] ;
self . decoder . decrypt ( & mut RefReadBuffer ::new ( & payload [ 0 .. self . payload_len ] ) , & mut RefWriteBuffer ::new ( & mut packet ) , false ) . expect ( " Invalid length or padding " ) ;
let mut pad_buf = [ 0 u8 ; 16 ] ;
self . decoder . decrypt ( & mut RefReadBuffer ::new ( & payload [ self . payload_len .. ( payload . len ( ) - 16 ) ] ) , & mut RefWriteBuffer ::new ( & mut pad_buf ) , false ) . expect ( " Invalid length or padding " ) ;
2015-12-02 20:11:13 +01:00
Ok ( Packet {
protocol : self . protocol_id ,
data : packet
} )
2015-12-02 12:07:46 +01:00
}
2016-01-10 22:42:27 +01:00
/// Update MAC after reading or writing any data.
2015-12-03 15:11:40 +01:00
fn update_mac ( mac : & mut Keccak , mac_encoder : & mut EcbEncryptor < AesSafe256Encryptor , EncPadding < NoPadding > > , seed : & [ u8 ] ) {
let mut prev = H128 ::new ( ) ;
mac . clone ( ) . finalize ( & mut prev ) ;
let mut enc = H128 ::new ( ) ;
mac_encoder . encrypt ( & mut RefReadBuffer ::new ( & prev ) , & mut RefWriteBuffer ::new ( & mut enc ) , true ) . unwrap ( ) ;
mac_encoder . reset ( ) ;
2016-01-08 13:49:00 +01:00
enc = enc ^ if seed . is_empty ( ) { prev } else { H128 ::from_slice ( seed ) } ;
2015-12-03 15:11:40 +01:00
mac . update ( & enc ) ;
}
2016-01-10 22:42:27 +01:00
/// Readable IO handler. Tracker receive status and returns decoded packet if avaialable.
2016-01-21 16:48:37 +01:00
pub fn readable < Message > ( & mut self , io : & IoContext < Message > ) -> Result < Option < Packet > , UtilError > where Message : Send + Clone {
io . clear_timer ( self . connection . token ) . unwrap ( ) ;
2015-12-02 12:07:46 +01:00
match self . read_state {
EncryptedConnectionState ::Header = > {
2016-01-19 12:14:29 +01:00
if let Some ( data ) = try ! ( self . connection . readable ( ) ) {
try ! ( self . read_header ( & data ) ) ;
2016-01-22 14:44:17 +01:00
try ! ( io . register_timer ( self . connection . token , RECIEVE_PAYLOAD_TIMEOUT ) ) ;
}
2015-12-02 12:07:46 +01:00
Ok ( None )
} ,
EncryptedConnectionState ::Payload = > {
match try ! ( self . connection . readable ( ) ) {
2015-12-03 15:11:40 +01:00
Some ( data ) = > {
2015-12-02 12:07:46 +01:00
self . read_state = EncryptedConnectionState ::Header ;
self . connection . expect ( ENCRYPTED_HEADER_LEN ) ;
Ok ( Some ( try ! ( self . read_payload ( & data ) ) ) )
} ,
None = > Ok ( None )
}
}
}
}
2016-01-10 22:42:27 +01:00
/// Writable IO handler. Processes send queeue.
2016-01-21 16:48:37 +01:00
pub fn writable < Message > ( & mut self , io : & IoContext < Message > ) -> Result < ( ) , UtilError > where Message : Send + Clone {
io . clear_timer ( self . connection . token ) . unwrap ( ) ;
2015-12-02 12:07:46 +01:00
try ! ( self . connection . writable ( ) ) ;
Ok ( ( ) )
}
2016-01-10 22:42:27 +01:00
/// Update connection registration. This should be called at the end of the event loop.
2016-01-21 16:48:37 +01:00
pub fn update_socket < Host :Handler > ( & self , reg : Token , event_loop : & mut EventLoop < Host > ) -> Result < ( ) , UtilError > {
try ! ( self . connection . update_socket ( reg , event_loop ) ) ;
2016-01-10 14:02:01 +01:00
Ok ( ( ) )
}
2016-01-22 18:13:59 +01:00
/// Delete connection registration. This should be called at the end of the event loop.
pub fn deregister_socket < Host :Handler > ( & self , event_loop : & mut EventLoop < Host > ) -> Result < ( ) , UtilError > {
try ! ( self . connection . deregister_socket ( event_loop ) ) ;
Ok ( ( ) )
}
2015-12-02 12:07:46 +01:00
}
2015-12-03 15:11:40 +01:00
#[ test ]
2016-01-08 13:49:00 +01:00
pub fn test_encryption ( ) {
2015-12-03 15:11:40 +01:00
use hash ::* ;
use std ::str ::FromStr ;
let key = H256 ::from_str ( " 2212767d793a7a3d66f869ae324dd11bd17044b82c9f463b8a541a4d089efec5 " ) . unwrap ( ) ;
let before = H128 ::from_str ( " 12532abaec065082a3cf1da7d0136f15 " ) . unwrap ( ) ;
let before2 = H128 ::from_str ( " 7e99f682356fdfbc6b67a9562787b18a " ) . unwrap ( ) ;
let after = H128 ::from_str ( " 89464c6b04e7c99e555c81d3f7266a05 " ) . unwrap ( ) ;
let after2 = H128 ::from_str ( " 85c070030589ef9c7a2879b3a8489316 " ) . unwrap ( ) ;
let mut got = H128 ::new ( ) ;
let mut encoder = EcbEncryptor ::new ( AesSafe256Encryptor ::new ( & key ) , NoPadding ) ;
encoder . encrypt ( & mut RefReadBuffer ::new ( & before ) , & mut RefWriteBuffer ::new ( & mut got ) , true ) . unwrap ( ) ;
encoder . reset ( ) ;
assert_eq! ( got , after ) ;
got = H128 ::new ( ) ;
encoder . encrypt ( & mut RefReadBuffer ::new ( & before2 ) , & mut RefWriteBuffer ::new ( & mut got ) , true ) . unwrap ( ) ;
encoder . reset ( ) ;
assert_eq! ( got , after2 ) ;
}