2021-07-02 13:00:46 +01:00
use std ::{
collections ::HashMap ,
io ::Write ,
marker ::PhantomData ,
net ::{ IpAddr , Ipv4Addr , Ipv6Addr } ,
} ;
2021-07-01 23:37:57 +01:00
2021-06-25 13:47:51 +01:00
use bincode ::Options ;
2021-06-28 16:09:20 +01:00
use byteorder ::{ ByteOrder , BE } ;
2021-07-02 13:00:46 +01:00
use serde ::{ Deserialize , Deserializer , Serialize } ;
2021-06-25 13:47:51 +01:00
use crate ::{
2021-07-01 23:37:57 +01:00
bencode_value ::BencodeValue ,
2021-06-25 13:47:51 +01:00
buffers ::{ ByteBuf , ByteString } ,
clone_to_owned ::CloneToOwned ,
2021-06-28 20:40:13 +01:00
constants ::CHUNK_SIZE ,
2021-06-28 16:09:20 +01:00
lengths ::ChunkInfo ,
2021-07-02 13:00:46 +01:00
serde_bencode_de ::BencodeDeserializer ,
serde_bencode_ser ,
2021-06-25 13:47:51 +01:00
} ;
2021-06-28 20:40:13 +01:00
const INTEGER_LEN : usize = 4 ;
const MSGID_LEN : usize = 1 ;
const PREAMBLE_LEN : usize = INTEGER_LEN + MSGID_LEN ;
const PIECE_MESSAGE_PREAMBLE_LEN : usize = PREAMBLE_LEN + INTEGER_LEN * 2 ;
pub const PIECE_MESSAGE_DEFAULT_LEN : usize = PIECE_MESSAGE_PREAMBLE_LEN + CHUNK_SIZE as usize ;
2021-06-25 13:47:51 +01:00
const NO_PAYLOAD_MSG_LEN : usize = PREAMBLE_LEN ;
const PSTR_BT1 : & str = " BitTorrent protocol " ;
const LEN_PREFIX_KEEPALIVE : u32 = 0 ;
const LEN_PREFIX_CHOKE : u32 = 1 ;
const LEN_PREFIX_UNCHOKE : u32 = 1 ;
const LEN_PREFIX_INTERESTED : u32 = 1 ;
const LEN_PREFIX_NOT_INTERESTED : u32 = 1 ;
const LEN_PREFIX_HAVE : u32 = 5 ;
2021-06-28 16:09:20 +01:00
const LEN_PREFIX_PIECE : u32 = 9 ;
2021-06-25 13:47:51 +01:00
const LEN_PREFIX_REQUEST : u32 = 13 ;
const MSGID_CHOKE : u8 = 0 ;
const MSGID_UNCHOKE : u8 = 1 ;
const MSGID_INTERESTED : u8 = 2 ;
const MSGID_NOT_INTERESTED : u8 = 3 ;
const MSGID_HAVE : u8 = 4 ;
const MSGID_BITFIELD : u8 = 5 ;
const MSGID_REQUEST : u8 = 6 ;
const MSGID_PIECE : u8 = 7 ;
2021-07-01 23:37:57 +01:00
const MSGID_EXTENDED : u8 = 20 ;
2021-06-25 13:47:51 +01:00
2021-07-02 17:58:53 +01:00
const MY_EXTENDED_UT_METADATA : u8 = 3 ;
2021-07-02 13:00:46 +01:00
2021-06-25 13:47:51 +01:00
#[ derive(Debug) ]
pub enum MessageDeserializeError {
NotEnoughData ( usize , & 'static str ) ,
UnsupportedMessageId ( u8 ) ,
IncorrectLenPrefix {
received : u32 ,
expected : u32 ,
msg_id : u8 ,
} ,
OtherBincode {
error : bincode ::Error ,
msg_id : u8 ,
len_prefix : u32 ,
name : & 'static str ,
} ,
2021-07-02 01:38:07 +01:00
Other ( anyhow ::Error ) ,
2021-06-25 13:47:51 +01:00
}
2021-06-28 16:09:20 +01:00
pub fn serialize_piece_preamble ( chunk : & ChunkInfo , mut buf : & mut [ u8 ] ) -> usize {
BE ::write_u32 ( & mut buf [ 0 .. 4 ] , LEN_PREFIX_PIECE + chunk . size ) ;
buf [ 4 ] = MSGID_PIECE ;
buf = & mut buf [ PREAMBLE_LEN .. ] ;
BE ::write_u32 ( & mut buf [ 0 .. 4 ] , chunk . piece_index . get ( ) ) ;
BE ::write_u32 ( & mut buf [ 4 .. 8 ] , chunk . offset ) ;
2021-06-28 20:40:13 +01:00
PIECE_MESSAGE_PREAMBLE_LEN
2021-06-28 16:09:20 +01:00
}
2021-06-25 13:47:51 +01:00
#[ derive(Debug) ]
pub struct Piece < ByteBuf > {
pub index : u32 ,
pub begin : u32 ,
pub block : ByteBuf ,
}
impl < ByteBuf > Piece < ByteBuf >
where
ByteBuf : AsRef < [ u8 ] > ,
{
2021-06-28 15:44:29 +01:00
pub fn from_data < T > ( index : u32 , begin : u32 , block : T ) -> Piece < ByteBuf >
2021-06-26 00:32:52 +01:00
where
2021-06-28 15:44:29 +01:00
ByteBuf : From < T > ,
2021-06-26 00:32:52 +01:00
{
Piece {
index ,
begin ,
block : ByteBuf ::from ( block ) ,
}
}
2021-06-26 17:29:59 +01:00
pub fn serialize ( & self , mut buf : & mut [ u8 ] ) -> usize {
2021-06-25 13:47:51 +01:00
byteorder ::BigEndian ::write_u32 ( & mut buf [ 0 .. 4 ] , self . index ) ;
byteorder ::BigEndian ::write_u32 ( & mut buf [ 4 .. 8 ] , self . begin ) ;
2021-06-26 17:29:59 +01:00
buf = & mut buf [ 8 .. ] ;
buf . copy_from_slice ( self . block . as_ref ( ) ) ;
2021-06-25 13:47:51 +01:00
self . block . as_ref ( ) . len ( ) + 8
}
pub fn deserialize < ' a > ( buf : & ' a [ u8 ] ) -> Piece < ByteBuf >
where
ByteBuf : From < & ' a [ u8 ] > + ' a ,
{
let index = byteorder ::BigEndian ::read_u32 ( & buf [ 0 .. 4 ] ) ;
let begin = byteorder ::BigEndian ::read_u32 ( & buf [ 4 .. 8 ] ) ;
let block = ByteBuf ::from ( & buf [ 8 .. ] ) ;
Piece {
index ,
begin ,
block ,
}
}
}
impl std ::fmt ::Display for MessageDeserializeError {
fn fmt ( & self , f : & mut std ::fmt ::Formatter < '_ > ) -> std ::fmt ::Result {
match self {
MessageDeserializeError ::NotEnoughData ( b , name ) = > {
write! (
f ,
" not enough data to deserialize {}: expected at least {} more bytes " ,
name , b
)
}
MessageDeserializeError ::UnsupportedMessageId ( msg_id ) = > {
write! ( f , " unsupported message id {} " , msg_id )
}
MessageDeserializeError ::IncorrectLenPrefix {
received ,
expected ,
msg_id ,
} = > write! (
f ,
" incorrect len prefix for message id {}, expected {}, received {} " ,
msg_id , expected , received
) ,
MessageDeserializeError ::OtherBincode {
error ,
msg_id ,
name ,
len_prefix ,
} = > write! (
f ,
" error deserializing {} (msg_id={}, len_prefix={}): {:?} " ,
name , msg_id , len_prefix , error
) ,
2021-07-02 01:38:07 +01:00
MessageDeserializeError ::Other ( e ) = > write! ( f , " {} " , e ) ,
2021-06-25 13:47:51 +01:00
}
}
}
impl std ::error ::Error for MessageDeserializeError {
fn source ( & self ) -> Option < & ( dyn std ::error ::Error + 'static ) > {
match self {
MessageDeserializeError ::OtherBincode { error , .. } = > Some ( error ) ,
_ = > None ,
}
}
}
2021-07-02 01:38:07 +01:00
impl From < anyhow ::Error > for MessageDeserializeError {
fn from ( e : anyhow ::Error ) -> Self {
MessageDeserializeError ::Other ( e )
}
}
2021-06-25 13:47:51 +01:00
#[ derive(Debug) ]
2021-07-01 23:37:57 +01:00
pub enum Message < ByteBuf : std ::hash ::Hash + Eq > {
2021-06-25 13:47:51 +01:00
Request ( Request ) ,
Bitfield ( ByteBuf ) ,
KeepAlive ,
Have ( u32 ) ,
Choke ,
Unchoke ,
Interested ,
NotInterested ,
Piece ( Piece < ByteBuf > ) ,
2021-07-01 23:37:57 +01:00
Extended ( ExtendedMessage < ByteBuf > ) ,
2021-06-25 13:47:51 +01:00
}
pub type MessageBorrowed < ' a > = Message < ByteBuf < ' a > > ;
pub type MessageOwned = Message < ByteString > ;
pub type BitfieldBorrowed < ' a > = & ' a bitvec ::slice ::BitSlice < bitvec ::order ::Lsb0 , u8 > ;
pub type BitfieldOwned = bitvec ::vec ::BitVec < bitvec ::order ::Lsb0 , u8 > ;
pub struct Bitfield < ' a > {
pub data : BitfieldBorrowed < ' a > ,
}
2021-07-01 23:37:57 +01:00
impl < ByteBuf > CloneToOwned for Message < ByteBuf >
where
ByteBuf : CloneToOwned + std ::hash ::Hash + Eq ,
< ByteBuf as CloneToOwned > ::Target : std ::hash ::Hash + Eq ,
{
2021-06-25 13:47:51 +01:00
type Target = Message < < ByteBuf as CloneToOwned > ::Target > ;
fn clone_to_owned ( & self ) -> Self ::Target {
match self {
Message ::Request ( req ) = > Message ::Request ( * req ) ,
Message ::Bitfield ( b ) = > Message ::Bitfield ( b . clone_to_owned ( ) ) ,
Message ::Choke = > Message ::Choke ,
Message ::Unchoke = > Message ::Unchoke ,
Message ::Interested = > Message ::Interested ,
Message ::Piece ( piece ) = > Message ::Piece ( Piece {
index : piece . index ,
begin : piece . begin ,
block : piece . block . clone_to_owned ( ) ,
} ) ,
Message ::KeepAlive = > Message ::KeepAlive ,
Message ::Have ( v ) = > Message ::Have ( * v ) ,
Message ::NotInterested = > Message ::NotInterested ,
2021-07-02 17:58:53 +01:00
Message ::Extended ( e ) = > Message ::Extended ( e . clone_to_owned ( ) ) ,
2021-06-25 13:47:51 +01:00
}
}
}
impl < ' a > Bitfield < ' a > {
pub fn new_from_slice ( buf : & ' a [ u8 ] ) -> anyhow ::Result < Self > {
Ok ( Self {
data : bitvec ::slice ::BitSlice ::from_slice ( buf ) ? ,
} )
}
}
impl < ' a > std ::fmt ::Debug for Bitfield < ' a > {
fn fmt ( & self , f : & mut std ::fmt ::Formatter < '_ > ) -> std ::fmt ::Result {
f . debug_struct ( " Bitfield " )
. field ( " _ones " , & self . data . count_ones ( ) )
. field ( " _len " , & self . data . len ( ) )
. finish ( )
}
}
impl < ByteBuf > Message < ByteBuf >
where
2021-07-02 01:38:07 +01:00
ByteBuf : AsRef < [ u8 ] > + std ::hash ::Hash + Eq + Serialize ,
2021-06-25 13:47:51 +01:00
{
pub fn len_prefix_and_msg_id ( & self ) -> ( u32 , u8 ) {
match self {
Message ::Request ( _ ) = > ( LEN_PREFIX_REQUEST , MSGID_REQUEST ) ,
Message ::Bitfield ( b ) = > ( 1 + b . as_ref ( ) . len ( ) as u32 , MSGID_BITFIELD ) ,
Message ::Choke = > ( LEN_PREFIX_CHOKE , MSGID_CHOKE ) ,
Message ::Unchoke = > ( LEN_PREFIX_UNCHOKE , MSGID_UNCHOKE ) ,
Message ::Interested = > ( LEN_PREFIX_INTERESTED , MSGID_INTERESTED ) ,
Message ::NotInterested = > ( LEN_PREFIX_NOT_INTERESTED , MSGID_NOT_INTERESTED ) ,
2021-06-28 16:09:20 +01:00
Message ::Piece ( p ) = > (
LEN_PREFIX_PIECE + p . block . as_ref ( ) . len ( ) as u32 ,
MSGID_PIECE ,
) ,
2021-06-25 13:47:51 +01:00
Message ::KeepAlive = > ( LEN_PREFIX_KEEPALIVE , 0 ) ,
Message ::Have ( _ ) = > ( LEN_PREFIX_HAVE , MSGID_HAVE ) ,
2021-07-02 01:38:07 +01:00
Message ::Extended ( _ ) = > ( 0 , MSGID_EXTENDED ) ,
2021-06-25 13:47:51 +01:00
}
}
2021-07-02 13:00:46 +01:00
pub fn serialize (
& self ,
out : & mut Vec < u8 > ,
peer_extended_handshake : Option < & ExtendedHandshake < ByteString > > ,
) -> anyhow ::Result < usize > {
2021-06-25 13:47:51 +01:00
let ( lp , msg_id ) = self . len_prefix_and_msg_id ( ) ;
out . resize ( PREAMBLE_LEN , 0 ) ;
byteorder ::BigEndian ::write_u32 ( & mut out [ .. 4 ] , lp ) ;
out [ 4 ] = msg_id ;
let ser = bopts ( ) ;
match self {
Message ::Request ( request ) = > {
const MSG_LEN : usize = PREAMBLE_LEN + 12 ;
out . resize ( MSG_LEN , 0 ) ;
debug_assert_eq! ( ( & out [ PREAMBLE_LEN .. ] ) . len ( ) , 12 ) ;
ser . serialize_into ( & mut out [ PREAMBLE_LEN .. ] , request )
. unwrap ( ) ;
2021-07-02 13:00:46 +01:00
Ok ( MSG_LEN )
2021-06-25 13:47:51 +01:00
}
2021-06-26 21:00:17 +01:00
Message ::Bitfield ( b ) = > {
let block_len = b . as_ref ( ) . len ( ) ;
let msg_len = PREAMBLE_LEN + block_len ;
out . resize ( msg_len , 0 ) ;
( & mut out [ PREAMBLE_LEN .. PREAMBLE_LEN + block_len ] ) . copy_from_slice ( b . as_ref ( ) ) ;
2021-07-02 13:00:46 +01:00
Ok ( msg_len )
2021-06-26 21:00:17 +01:00
}
2021-06-27 14:49:41 +01:00
Message ::Choke | Message ::Unchoke | Message ::Interested | Message ::NotInterested = > {
2021-07-02 13:00:46 +01:00
Ok ( PREAMBLE_LEN )
2021-06-27 14:49:41 +01:00
}
2021-06-25 13:47:51 +01:00
Message ::Piece ( p ) = > {
2021-06-26 21:00:17 +01:00
let block_len = p . block . as_ref ( ) . len ( ) ;
let payload_len = 8 + block_len ;
2021-06-26 17:29:59 +01:00
let msg_len = PREAMBLE_LEN + payload_len ;
2021-06-25 13:47:51 +01:00
out . resize ( msg_len , 0 ) ;
2021-06-26 17:29:59 +01:00
let tmp = & mut out [ PREAMBLE_LEN .. ] ;
p . serialize ( & mut tmp [ .. payload_len ] ) ;
2021-07-02 13:00:46 +01:00
Ok ( msg_len )
2021-06-25 13:47:51 +01:00
}
2021-06-26 17:29:59 +01:00
Message ::KeepAlive = > {
// the len prefix was already written out to buf
2021-07-02 13:00:46 +01:00
Ok ( 4 )
2021-06-26 17:29:59 +01:00
}
2021-06-25 13:47:51 +01:00
Message ::Have ( v ) = > {
let msg_len = PREAMBLE_LEN + 4 ;
out . resize ( msg_len , 0 ) ;
2021-06-28 16:09:20 +01:00
BE ::write_u32 ( & mut out [ PREAMBLE_LEN .. ] , * v ) ;
2021-07-02 13:00:46 +01:00
Ok ( msg_len )
2021-06-25 13:47:51 +01:00
}
2021-07-02 01:38:07 +01:00
Message ::Extended ( e ) = > {
2021-07-02 17:58:53 +01:00
e . serialize ( out , peer_extended_handshake ) ? ;
2021-07-02 01:38:07 +01:00
let msg_size = out . len ( ) ;
2021-07-02 17:58:53 +01:00
// no fucking idea why +1, but I tweaked that for it all to match up
// with real messages.
BE ::write_u32 ( & mut out [ .. 4 ] , ( msg_size - PREAMBLE_LEN + 1 ) as u32 ) ;
2021-07-02 13:00:46 +01:00
Ok ( msg_size )
2021-07-02 01:38:07 +01:00
}
2021-06-25 13:47:51 +01:00
}
}
pub fn deserialize < ' a > (
buf : & ' a [ u8 ] ,
) -> Result < ( Message < ByteBuf > , usize ) , MessageDeserializeError >
where
2021-07-02 01:38:07 +01:00
ByteBuf : From < & ' a [ u8 ] > + ' a + Deserialize < ' a > ,
2021-06-25 13:47:51 +01:00
{
let len_prefix = match buf . get ( 0 .. 4 ) {
Some ( bytes ) = > byteorder ::BigEndian ::read_u32 ( bytes ) ,
None = > return Err ( MessageDeserializeError ::NotEnoughData ( 4 , " message " ) ) ,
} ;
if len_prefix = = 0 {
return Ok ( ( Message ::KeepAlive , 4 ) ) ;
}
let msg_id = match buf . get ( 4 ) {
Some ( msg_id ) = > * msg_id ,
None = > return Err ( MessageDeserializeError ::NotEnoughData ( 1 , " message " ) ) ,
} ;
let rest = & buf [ 5 .. ] ;
let decoder_config = bincode ::DefaultOptions ::new ( )
. with_fixint_encoding ( )
. with_big_endian ( ) ;
match msg_id {
MSGID_CHOKE = > {
if len_prefix ! = LEN_PREFIX_CHOKE {
return Err ( MessageDeserializeError ::IncorrectLenPrefix {
received : len_prefix ,
expected : LEN_PREFIX_CHOKE ,
msg_id ,
} ) ;
}
Ok ( ( Message ::Choke , NO_PAYLOAD_MSG_LEN ) )
}
MSGID_UNCHOKE = > {
if len_prefix ! = LEN_PREFIX_UNCHOKE {
return Err ( MessageDeserializeError ::IncorrectLenPrefix {
received : len_prefix ,
expected : LEN_PREFIX_UNCHOKE ,
msg_id ,
} ) ;
}
Ok ( ( Message ::Unchoke , NO_PAYLOAD_MSG_LEN ) )
}
MSGID_INTERESTED = > {
if len_prefix ! = LEN_PREFIX_INTERESTED {
return Err ( MessageDeserializeError ::IncorrectLenPrefix {
received : len_prefix ,
expected : LEN_PREFIX_INTERESTED ,
msg_id ,
} ) ;
}
Ok ( ( Message ::Interested , NO_PAYLOAD_MSG_LEN ) )
}
MSGID_NOT_INTERESTED = > {
if len_prefix ! = LEN_PREFIX_NOT_INTERESTED {
return Err ( MessageDeserializeError ::IncorrectLenPrefix {
received : len_prefix ,
expected : LEN_PREFIX_NOT_INTERESTED ,
msg_id ,
} ) ;
}
Ok ( ( Message ::NotInterested , NO_PAYLOAD_MSG_LEN ) )
}
MSGID_HAVE = > {
let expected_len = 4 ;
match rest . get ( .. expected_len as usize ) {
2021-06-28 16:09:20 +01:00
Some ( h ) = > Ok ( ( Message ::Have ( BE ::read_u32 ( & h ) ) , PREAMBLE_LEN + expected_len ) ) ,
2021-06-25 13:47:51 +01:00
None = > {
let missing = expected_len - rest . len ( ) ;
Err ( MessageDeserializeError ::NotEnoughData ( missing , " have " ) )
}
}
}
MSGID_BITFIELD = > {
if len_prefix < = 1 {
return Err ( MessageDeserializeError ::IncorrectLenPrefix {
expected : 2 ,
received : len_prefix ,
msg_id ,
} ) ;
}
let expected_len = len_prefix as usize - 1 ;
match rest . get ( .. expected_len as usize ) {
Some ( bitfield ) = > Ok ( (
Message ::Bitfield ( ByteBuf ::from ( bitfield ) ) ,
PREAMBLE_LEN + expected_len ,
) ) ,
None = > {
let missing = expected_len - rest . len ( ) ;
Err ( MessageDeserializeError ::NotEnoughData ( missing , " bitfield " ) )
}
}
}
MSGID_REQUEST = > {
let expected_len = 12 ;
match rest . get ( .. expected_len as usize ) {
Some ( b ) = > {
let request = decoder_config . deserialize ::< Request > ( & b ) . unwrap ( ) ;
Ok ( ( Message ::Request ( request ) , PREAMBLE_LEN + expected_len ) )
}
None = > {
let missing = expected_len - rest . len ( ) ;
Err ( MessageDeserializeError ::NotEnoughData ( missing , " request " ) )
}
}
}
MSGID_PIECE = > {
if len_prefix < = 9 {
return Err ( MessageDeserializeError ::IncorrectLenPrefix {
expected : 10 ,
received : len_prefix ,
msg_id ,
} ) ;
}
// <len=0009+X> is for "9", "8" is for 2 integer fields in the piece.
let expected_len = len_prefix as usize - 9 + 8 ;
match rest . get ( .. expected_len ) {
Some ( b ) = > Ok ( (
Message ::Piece ( Piece ::deserialize ( & b ) ) ,
PREAMBLE_LEN + expected_len ,
) ) ,
None = > Err ( MessageDeserializeError ::NotEnoughData (
expected_len - rest . len ( ) ,
" piece " ,
) ) ,
}
}
2021-07-02 01:38:07 +01:00
MSGID_EXTENDED = > {
if len_prefix < = 6 {
return Err ( MessageDeserializeError ::IncorrectLenPrefix {
expected : 6 ,
received : len_prefix ,
msg_id ,
} ) ;
}
// TODO: NO clue why - 1 here. Empirically figured out.
let expected_len = len_prefix as usize - 1 ;
match rest . get ( .. expected_len ) {
Some ( b ) = > Ok ( (
Message ::Extended ( ExtendedMessage ::deserialize ( & b ) ? ) ,
PREAMBLE_LEN + expected_len ,
) ) ,
None = > Err ( MessageDeserializeError ::NotEnoughData (
expected_len - rest . len ( ) ,
" extended " ,
) ) ,
}
}
2021-06-25 13:47:51 +01:00
msg_id = > Err ( MessageDeserializeError ::UnsupportedMessageId ( msg_id ) ) ,
}
}
}
#[ derive(Serialize, Deserialize, Debug) ]
pub struct Handshake < ' a > {
pub pstr : & ' a str ,
pub reserved : [ u8 ; 8 ] ,
pub info_hash : [ u8 ; 20 ] ,
pub peer_id : [ u8 ; 20 ] ,
}
fn bopts ( ) -> impl bincode ::Options {
bincode ::DefaultOptions ::new ( )
. with_fixint_encoding ( )
. with_big_endian ( )
}
impl < ' a > Handshake < ' a > {
pub fn new ( info_hash : [ u8 ; 20 ] , peer_id : [ u8 ; 20 ] ) -> Handshake < 'static > {
debug_assert_eq! ( PSTR_BT1 . len ( ) , 19 ) ;
2021-07-02 01:38:07 +01:00
let mut reserved : u64 = 0 ;
// supports extended messaging
reserved | = 1 < < 20 ;
let mut reserved_arr = [ 0 u8 ; 8 ] ;
BE ::write_u64 ( & mut reserved_arr , reserved ) ;
2021-06-25 13:47:51 +01:00
Handshake {
pstr : PSTR_BT1 ,
2021-07-02 01:38:07 +01:00
reserved : reserved_arr ,
2021-06-25 13:47:51 +01:00
info_hash ,
peer_id ,
}
}
2021-07-02 13:00:46 +01:00
pub fn supports_extended ( & self ) -> bool {
self . reserved [ 5 ] & 0x10 > 0
}
2021-06-25 13:47:51 +01:00
fn bopts ( ) -> impl bincode ::Options {
bincode ::DefaultOptions ::new ( )
}
pub fn deserialize ( b : & [ u8 ] ) -> Result < ( Handshake < '_ > , usize ) , MessageDeserializeError > {
let pstr_len = * b
. get ( 0 )
. ok_or ( MessageDeserializeError ::NotEnoughData ( 1 , " handshake " ) ) ? ;
let expected_len = 1 usize + pstr_len as usize + 48 ;
let hbuf = b
. get ( .. expected_len )
. ok_or ( MessageDeserializeError ::NotEnoughData (
expected_len ,
" handshake " ,
) ) ? ;
Ok ( ( Self ::bopts ( ) . deserialize ( & hbuf ) . unwrap ( ) , expected_len ) )
}
2021-07-02 17:58:53 +01:00
pub fn serialize ( & self , buf : & mut Vec < u8 > ) {
Self ::bopts ( ) . serialize_into ( buf , & self ) . unwrap ( )
2021-06-25 13:47:51 +01:00
}
}
#[ derive(Serialize, Deserialize, Debug, Clone, Copy) ]
pub struct Request {
pub index : u32 ,
pub begin : u32 ,
pub length : u32 ,
}
impl Request {
pub fn new ( index : u32 , begin : u32 , length : u32 ) -> Self {
Self {
index ,
begin ,
length ,
}
}
}
2021-07-02 13:00:46 +01:00
#[ derive(Debug) ]
pub enum UtMetadata < ByteBuf > {
Request ( u32 ) ,
2021-07-02 17:58:53 +01:00
Data {
piece : u32 ,
total_size : u32 ,
data : ByteBuf ,
} ,
2021-07-02 13:00:46 +01:00
Reject ( u32 ) ,
}
impl < ByteBuf : CloneToOwned > CloneToOwned for UtMetadata < ByteBuf > {
type Target = UtMetadata < < ByteBuf as CloneToOwned > ::Target > ;
fn clone_to_owned ( & self ) -> Self ::Target {
match self {
UtMetadata ::Request ( req ) = > UtMetadata ::Request ( * req ) ,
2021-07-02 17:58:53 +01:00
UtMetadata ::Data {
piece ,
total_size ,
data ,
} = > UtMetadata ::Data {
piece : * piece ,
total_size : * total_size ,
data : data . clone_to_owned ( ) ,
} ,
2021-07-02 13:00:46 +01:00
UtMetadata ::Reject ( piece ) = > UtMetadata ::Reject ( * piece ) ,
}
}
}
impl < ' a , ByteBuf : ' a > UtMetadata < ByteBuf > {
fn serialize ( & self , buf : & mut Vec < u8 > )
where
ByteBuf : AsRef < [ u8 ] > ,
{
#[ derive(Serialize) ]
struct Message {
msg_type : u32 ,
piece : u32 ,
#[ serde(skip_serializing_if = " Option::is_none " ) ]
total_size : Option < u32 > ,
}
match self {
UtMetadata ::Request ( piece ) = > {
let message = Message {
msg_type : 0 ,
piece : * piece ,
total_size : None ,
} ;
serde_bencode_ser ::bencode_serialize_to_writer ( message , buf ) . unwrap ( )
}
2021-07-02 17:58:53 +01:00
UtMetadata ::Data {
piece ,
total_size ,
data ,
} = > {
2021-07-02 13:00:46 +01:00
let message = Message {
msg_type : 1 ,
piece : * piece ,
2021-07-02 17:58:53 +01:00
total_size : Some ( * total_size ) ,
2021-07-02 13:00:46 +01:00
} ;
serde_bencode_ser ::bencode_serialize_to_writer ( message , buf ) . unwrap ( ) ;
buf . write_all ( data . as_ref ( ) ) . unwrap ( ) ;
}
UtMetadata ::Reject ( piece ) = > {
let message = Message {
msg_type : 2 ,
piece : * piece ,
total_size : None ,
} ;
serde_bencode_ser ::bencode_serialize_to_writer ( message , buf ) . unwrap ( ) ;
}
}
}
fn deserialize ( buf : & ' a [ u8 ] ) -> Result < Self , MessageDeserializeError >
where
ByteBuf : From < & ' a [ u8 ] > ,
{
let mut de = BencodeDeserializer ::new_from_buf ( buf ) ;
#[ derive(Deserialize) ]
struct Message {
msg_type : u32 ,
piece : u32 ,
total_size : Option < u32 > ,
}
let message =
Message ::deserialize ( & mut de ) . map_err ( | e | MessageDeserializeError ::Other ( e . into ( ) ) ) ? ;
let remaining = de . into_remaining ( ) ;
match message . msg_type {
// request
0 = > {
if ! remaining . is_empty ( ) {
return Err ( MessageDeserializeError ::Other ( anyhow ::anyhow! (
" trailing bytes when decoding UtMetadata "
) ) ) ;
}
Ok ( UtMetadata ::Request ( message . piece ) )
}
// data
1 = > {
let total_size = message . total_size . ok_or_else ( | | {
MessageDeserializeError ::Other ( anyhow ::anyhow! (
" expected key total_size to be present in UtMetadata \" data \" message "
) )
} ) ? ;
2021-07-02 17:58:53 +01:00
Ok ( UtMetadata ::Data {
piece : message . piece ,
total_size ,
data : ByteBuf ::from ( remaining ) ,
} )
2021-07-02 13:00:46 +01:00
}
// reject
2 = > {
if ! remaining . is_empty ( ) {
return Err ( MessageDeserializeError ::Other ( anyhow ::anyhow! (
" trailing bytes when decoding UtMetadata "
) ) ) ;
}
Ok ( UtMetadata ::Reject ( message . piece ) )
}
other = > {
return Err ( MessageDeserializeError ::Other ( anyhow ::anyhow! (
" unrecognized ut_metadata message type {} " ,
other
) ) )
}
}
}
}
2021-07-01 23:37:57 +01:00
#[ derive(Debug) ]
pub enum ExtendedMessage < ByteBuf : std ::hash ::Hash + Eq > {
2021-07-02 01:38:07 +01:00
Handshake ( ExtendedHandshake < ByteBuf > ) ,
2021-07-02 13:00:46 +01:00
UtMetadata ( UtMetadata < ByteBuf > ) ,
2021-07-02 01:38:07 +01:00
Dyn ( u8 , BencodeValue < ByteBuf > ) ,
}
2021-07-02 13:00:46 +01:00
impl < ByteBuf > CloneToOwned for ExtendedMessage < ByteBuf >
where
ByteBuf : CloneToOwned + std ::hash ::Hash + Eq ,
< ByteBuf as CloneToOwned > ::Target : std ::hash ::Hash + Eq ,
{
type Target = ExtendedMessage < < ByteBuf as CloneToOwned > ::Target > ;
fn clone_to_owned ( & self ) -> Self ::Target {
match self {
ExtendedMessage ::Handshake ( h ) = > ExtendedMessage ::Handshake ( h . clone_to_owned ( ) ) ,
ExtendedMessage ::Dyn ( u , d ) = > ExtendedMessage ::Dyn ( * u , d . clone_to_owned ( ) ) ,
ExtendedMessage ::UtMetadata ( m ) = > ExtendedMessage ::UtMetadata ( m . clone_to_owned ( ) ) ,
}
}
}
impl < ' a , ByteBuf : ' a + std ::hash ::Hash + Eq + Serialize > ExtendedMessage < ByteBuf > {
fn serialize (
& self ,
out : & mut Vec < u8 > ,
extended_handshake : Option < & ExtendedHandshake < ByteString > > ,
) -> anyhow ::Result < ( ) >
where
ByteBuf : AsRef < [ u8 ] > ,
{
2021-07-02 01:38:07 +01:00
match self {
ExtendedMessage ::Dyn ( msg_id , v ) = > {
out . push ( * msg_id ) ;
2021-07-02 13:00:46 +01:00
crate ::serde_bencode_ser ::bencode_serialize_to_writer ( v , out ) ? ;
2021-07-02 01:38:07 +01:00
}
ExtendedMessage ::Handshake ( h ) = > {
out . push ( 0 ) ;
2021-07-02 13:00:46 +01:00
crate ::serde_bencode_ser ::bencode_serialize_to_writer ( h , out ) ? ;
}
ExtendedMessage ::UtMetadata ( u ) = > {
let h = extended_handshake . ok_or_else ( | | {
anyhow ::anyhow! ( " need peer's handshake to serialize ut_metadata " )
} ) ? ;
let emsg_id = h
. get_msgid ( b " ut_metadata " )
. ok_or_else ( | | anyhow ::anyhow! ( " peer doesn't support ut_metadata " ) ) ? ;
out . push ( emsg_id ) ;
u . serialize ( out ) ;
2021-07-02 01:38:07 +01:00
}
}
2021-07-02 13:00:46 +01:00
Ok ( ( ) )
2021-07-02 01:38:07 +01:00
}
2021-07-02 13:00:46 +01:00
fn deserialize ( mut buf : & ' a [ u8 ] ) -> Result < Self , MessageDeserializeError >
2021-07-02 01:38:07 +01:00
where
2021-07-02 13:00:46 +01:00
ByteBuf : Deserialize < ' a > + From < & ' a [ u8 ] > ,
2021-07-02 01:38:07 +01:00
{
use crate ::serde_bencode_de ::from_bytes ;
let emsg_id = buf . get ( 0 ) . copied ( ) . ok_or_else ( | | {
MessageDeserializeError ::Other ( anyhow ::anyhow! (
" cannot deserialize extended message: can't read first byte "
) )
} ) ? ;
buf = & buf . get ( 1 .. ) . ok_or_else ( | | {
MessageDeserializeError ::Other ( anyhow ::anyhow! (
" cannot deserialize extended message: buffer empty "
) )
} ) ? ;
match emsg_id {
0 = > Ok ( ExtendedMessage ::Handshake ( from_bytes ( & buf ) ? ) ) ,
2021-07-02 13:00:46 +01:00
MY_EXTENDED_UT_METADATA = > {
Ok ( ExtendedMessage ::UtMetadata ( UtMetadata ::deserialize ( & buf ) ? ) )
}
2021-07-02 17:58:53 +01:00
_ = > Ok ( ExtendedMessage ::Dyn ( emsg_id , from_bytes ( & buf ) ? ) ) ,
2021-07-02 01:38:07 +01:00
}
}
2021-07-01 23:37:57 +01:00
}
2021-07-02 13:00:46 +01:00
#[ derive(Debug, Clone, Copy) ]
pub struct YourIP ( pub IpAddr ) ;
impl Serialize for YourIP {
2021-07-02 17:58:53 +01:00
fn serialize < S > ( & self , serializer : S ) -> Result < S ::Ok , S ::Error >
2021-07-02 13:00:46 +01:00
where
S : serde ::Serializer ,
{
2021-07-02 17:58:53 +01:00
match self . 0 {
IpAddr ::V4 ( ipv4 ) = > {
let buf = ipv4 . octets ( ) ;
serializer . serialize_bytes ( & buf )
}
IpAddr ::V6 ( _ ) = > todo! ( ) ,
}
2021-07-02 13:00:46 +01:00
}
}
impl < ' de > Deserialize < ' de > for YourIP {
fn deserialize < D > ( de : D ) -> Result < YourIP , D ::Error >
where
D : Deserializer < ' de > ,
{
struct Visitor { }
impl < ' de > serde ::de ::Visitor < ' de > for Visitor {
type Value = YourIP ;
fn expecting ( & self , f : & mut std ::fmt ::Formatter ) -> std ::fmt ::Result {
write! ( f , " expecting 4 bytes of ipv4 or 16 bytes of ipv6 " )
}
fn visit_bytes < E > ( self , v : & [ u8 ] ) -> Result < Self ::Value , E >
where
E : serde ::de ::Error ,
{
if v . len ( ) = = 4 {
return Ok ( YourIP ( IpAddr ::V4 ( Ipv4Addr ::new ( v [ 0 ] , v [ 1 ] , v [ 2 ] , v [ 3 ] ) ) ) ) ;
} else if v . len ( ) = = 16 {
return Ok ( YourIP ( IpAddr ::V6 ( Ipv6Addr ::new (
BE ::read_u16 ( & v [ .. 2 ] ) ,
BE ::read_u16 ( & v [ 2 .. 4 ] ) ,
BE ::read_u16 ( & v [ 4 .. 6 ] ) ,
BE ::read_u16 ( & v [ 6 .. 8 ] ) ,
BE ::read_u16 ( & v [ 8 .. 10 ] ) ,
BE ::read_u16 ( & v [ 10 .. 12 ] ) ,
BE ::read_u16 ( & v [ 12 .. 14 ] ) ,
BE ::read_u16 ( & v [ 14 .. ] ) ,
) ) ) ) ;
}
Err ( E ::custom ( " expected 4 or 16 byte address " ) )
}
}
de . deserialize_bytes ( Visitor { } )
}
}
2021-07-02 17:58:53 +01:00
#[ derive(Deserialize, Serialize, Debug, Default) ]
2021-07-02 01:38:07 +01:00
pub struct ExtendedHandshake < ByteBuf : Eq + std ::hash ::Hash > {
#[ serde(bound(deserialize = " ByteBuf: From<&'de [u8]> " )) ]
2021-07-02 13:00:46 +01:00
pub m : HashMap < ByteBuf , u8 > ,
2021-07-02 01:38:07 +01:00
#[ serde(skip_serializing_if = " Option::is_none " ) ]
pub p : Option < u32 > ,
#[ serde(skip_serializing_if = " Option::is_none " ) ]
pub v : Option < ByteBuf > ,
#[ serde(skip_serializing_if = " Option::is_none " ) ]
2021-07-02 13:00:46 +01:00
pub yourip : Option < YourIP > ,
2021-07-02 01:38:07 +01:00
#[ serde(skip_serializing_if = " Option::is_none " ) ]
pub ipv6 : Option < ByteBuf > ,
#[ serde(skip_serializing_if = " Option::is_none " ) ]
pub ipv4 : Option < ByteBuf > ,
#[ serde(skip_serializing_if = " Option::is_none " ) ]
pub reqq : Option < u32 > ,
2021-07-02 17:58:53 +01:00
#[ serde(skip_serializing_if = " Option::is_none " ) ]
2021-07-02 13:00:46 +01:00
pub metadata_size : Option < u32 > ,
2021-07-02 17:58:53 +01:00
#[ serde(skip_serializing_if = " Option::is_none " ) ]
pub complete_ago : Option < u32 > ,
#[ serde(skip_serializing_if = " Option::is_none " ) ]
pub upload_only : Option < u32 > ,
}
impl ExtendedHandshake < ByteBuf < 'static > > {
pub fn new ( ) -> Self {
let mut features = HashMap ::new ( ) ;
features . insert ( ByteBuf ( b " ut_metadata " ) , MY_EXTENDED_UT_METADATA ) ;
Self {
m : features ,
.. Default ::default ( )
}
}
2021-07-02 13:00:46 +01:00
}
impl < ByteBuf : Eq + std ::hash ::Hash > ExtendedHandshake < ByteBuf > {
fn get_msgid ( & self , msg_type : & [ u8 ] ) -> Option < u8 >
where
ByteBuf : AsRef < [ u8 ] > ,
{
self . m . iter ( ) . find_map ( | ( k , v ) | {
if k . as_ref ( ) = = msg_type {
Some ( * v )
} else {
None
}
} )
}
}
impl < ByteBuf > CloneToOwned for ExtendedHandshake < ByteBuf >
where
ByteBuf : CloneToOwned + Eq + std ::hash ::Hash ,
< ByteBuf as CloneToOwned > ::Target : Eq + std ::hash ::Hash ,
{
type Target = ExtendedHandshake < < ByteBuf as CloneToOwned > ::Target > ;
fn clone_to_owned ( & self ) -> Self ::Target {
ExtendedHandshake {
m : self . m . clone_to_owned ( ) ,
p : self . p ,
v : self . v . clone_to_owned ( ) ,
yourip : self . yourip ,
ipv6 : self . ipv6 . clone_to_owned ( ) ,
ipv4 : self . ipv4 . clone_to_owned ( ) ,
reqq : self . reqq ,
metadata_size : self . metadata_size ,
2021-07-02 17:58:53 +01:00
complete_ago : self . complete_ago ,
upload_only : self . upload_only ,
2021-07-02 13:00:46 +01:00
}
}
2021-07-01 23:37:57 +01:00
}
2021-06-25 13:47:51 +01:00
#[ cfg(test) ]
mod tests {
2021-07-02 17:58:53 +01:00
use std ::{ fs ::File , io ::Read , net ::SocketAddr , str ::FromStr } ;
2021-07-02 01:38:07 +01:00
2021-07-02 13:00:46 +01:00
use log ::info ;
2021-07-02 17:58:53 +01:00
use parking_lot ::RwLock ;
2021-07-02 13:00:46 +01:00
use tokio ::sync ::mpsc ::UnboundedSender ;
2021-07-02 01:38:07 +01:00
2021-07-02 13:00:46 +01:00
use crate ::{
2021-07-02 17:58:53 +01:00
lengths ::ceil_div_u64 ,
2021-07-02 13:00:46 +01:00
peer_connection ::{ PeerConnection , PeerConnectionHandler , WriterRequest } ,
peer_id ::generate_peer_id ,
2021-07-02 17:58:53 +01:00
torrent_metainfo ::TorrentMetaV1Borrowed ,
2021-07-02 13:00:46 +01:00
} ;
use std ::sync ::Once ;
static LOG_INIT : Once = std ::sync ::Once ::new ( ) ;
fn init_logging ( ) {
LOG_INIT . call_once ( pretty_env_logger ::init )
}
2021-07-02 01:38:07 +01:00
fn decode_info_hash ( hash_str : & str ) -> [ u8 ; 20 ] {
let mut hash_arr = [ 0 u8 ; 20 ] ;
hex ::decode_to_slice ( hash_str , & mut hash_arr ) . unwrap ( ) ;
hash_arr
}
2021-06-25 13:47:51 +01:00
use super ::* ;
#[ test ]
fn test_handshake_serialize ( ) {
let info_hash = [
1 u8 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 ,
] ;
let peer_id = [
1 u8 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 ,
] ;
2021-07-02 17:58:53 +01:00
let mut buf = Vec ::new ( ) ;
Handshake ::new ( info_hash , peer_id ) . serialize ( & mut buf ) ;
assert_eq! ( buf . len ( ) , 20 + 20 + 8 + 19 + 1 ) ;
2021-06-25 13:47:51 +01:00
}
2021-07-02 01:38:07 +01:00
#[ test ]
fn test_extended_serialize ( ) {
2021-07-02 17:58:53 +01:00
let msg = Message ::Extended ( ExtendedMessage ::Handshake ( ExtendedHandshake ::new ( ) ) ) ;
2021-07-02 01:38:07 +01:00
let mut out = Vec ::new ( ) ;
2021-07-02 17:58:53 +01:00
msg . serialize ( & mut out , None ) . unwrap ( ) ;
2021-07-02 01:38:07 +01:00
dbg! ( out ) ;
}
2021-07-02 17:58:53 +01:00
#[ test ]
fn test_deserialize_serialize_extended_is_same ( ) {
use std ::fs ::File ;
use std ::io ::Read ;
let mut buf = Vec ::new ( ) ;
File ::open ( " resources/test/extended-handshake.bin " )
. unwrap ( )
. read_to_end ( & mut buf )
. unwrap ( ) ;
let ( msg , size ) = MessageBorrowed ::deserialize ( & buf ) . unwrap ( ) ;
assert_eq! ( size , buf . len ( ) ) ;
let mut write_buf = Vec ::new ( ) ;
msg . serialize ( & mut write_buf , None ) . unwrap ( ) ;
if buf ! = write_buf {
{
use std ::io ::Write ;
let mut f = std ::fs ::OpenOptions ::new ( )
. create ( true )
. write ( true )
. open ( " /tmp/test_deserialize_serialize_extended_is_same " )
. unwrap ( ) ;
f . write_all ( & write_buf ) . unwrap ( ) ;
}
panic! ( " resources/test/extended-handshake.bin did not serialize exactly the same. Dumped to /tmp/test_deserialize_serialize_extended_is_same, you can compare with resources/test/extended-handshake.bin " )
}
}
2021-07-02 01:38:07 +01:00
#[ tokio::test ]
async fn test_connect_to_local_qbittorrent ( ) {
2021-07-02 13:00:46 +01:00
init_logging ( ) ;
2021-07-02 01:38:07 +01:00
2021-07-02 13:00:46 +01:00
struct Handler {
ehandshake : RwLock < Option < ExtendedHandshake < ByteString > > > ,
tx : UnboundedSender < WriterRequest > ,
}
2021-07-02 01:38:07 +01:00
2021-07-02 13:00:46 +01:00
impl PeerConnectionHandler for Handler {
fn get_have_bytes ( & self ) -> u64 {
0
}
2021-07-02 01:38:07 +01:00
2021-07-02 13:00:46 +01:00
fn serialize_bitfield_message_to_buf ( & self , _buf : & mut Vec < u8 > ) -> Option < usize > {
None
}
2021-07-02 01:38:07 +01:00
2021-07-02 13:00:46 +01:00
fn on_handshake ( & self , handshake : Handshake ) {
info! ( " received handshake: {:?} " , handshake )
}
2021-07-02 01:38:07 +01:00
2021-07-02 13:00:46 +01:00
fn on_received_message ( & self , msg : Message < ByteBuf < '_ > > ) -> anyhow ::Result < ( ) > {
info! ( " received message: {:?} " , msg ) ;
2021-07-02 17:58:53 +01:00
if let Message ::Extended ( ExtendedMessage ::UtMetadata ( UtMetadata ::Data {
piece ,
total_size ,
data ,
} ) ) = msg
{
// this just assumes piece come in the order requested.
let mut f = std ::fs ::OpenOptions ::new ( )
. create ( true )
. append ( true )
. open ( " /tmp/torrent " )
. unwrap ( ) ;
f . write_all ( & data ) . unwrap ( ) ;
// test if it's the last piece
if data . len ( ) < CHUNK_SIZE as usize {
let mut buf = Vec ::new ( ) ;
let mut f = File ::open ( " /tmp/torrent " ) . unwrap ( ) ;
f . read_to_end ( & mut buf ) . unwrap ( ) ;
// let torrent: TorrentMetaV1Borrowed =
// crate::torrent_metainfo::torrent_from_bytes(&buf).unwrap();
let torrent : BencodeValue < ByteBuf > =
crate ::bencode_value ::dyn_from_bytes ( & buf ) . unwrap ( ) ;
dbg! ( torrent ) ;
}
}
2021-07-02 13:00:46 +01:00
Ok ( ( ) )
}
2021-07-02 01:38:07 +01:00
2021-07-02 13:00:46 +01:00
fn on_uploaded_bytes ( & self , _bytes : u32 ) { }
2021-07-02 01:38:07 +01:00
2021-07-02 13:00:46 +01:00
fn read_chunk ( & self , _chunk : & ChunkInfo , _buf : & mut [ u8 ] ) -> anyhow ::Result < ( ) > {
panic! ( " dude, why are you requesting chunks " )
}
2021-07-02 01:38:07 +01:00
2021-07-02 13:00:46 +01:00
fn on_extended_handshake ( & self , extended_handshake : & ExtendedHandshake < ByteBuf > ) {
self . ehandshake
. write ( )
. replace ( extended_handshake . clone_to_owned ( ) ) ;
self . tx
2021-07-02 17:58:53 +01:00
. send ( WriterRequest ::Message ( Message ::Unchoke ) )
. unwrap ( ) ;
self . tx
. send ( WriterRequest ::Message ( Message ::Interested ) )
. unwrap ( ) ;
let total_metadata_chunks = ceil_div_u64 (
extended_handshake . metadata_size . unwrap ( ) as u64 ,
CHUNK_SIZE as u64 ,
) ;
for i in 0 .. total_metadata_chunks {
self . tx
. send ( WriterRequest ::Message ( Message ::Extended (
ExtendedMessage ::UtMetadata ( UtMetadata ::Request ( i as u32 ) ) ,
) ) )
. unwrap ( )
}
2021-07-02 01:38:07 +01:00
}
}
2021-07-02 13:00:46 +01:00
let addr = SocketAddr ::from_str ( " 127.0.0.1:27311 " ) . unwrap ( ) ;
let ( tx , rx ) = tokio ::sync ::mpsc ::unbounded_channel ( ) ;
let handler = Handler {
tx ,
ehandshake : RwLock ::new ( None ) ,
} ;
let peer_id = generate_peer_id ( ) ;
let info_hash = decode_info_hash ( " 9905f844e5d8787ecd5e08fb46b2eb0a42c131d7 " ) ;
let conn = PeerConnection ::new ( addr , info_hash , peer_id , handler ) ;
// tx.send(WriterRequest::Message(Message::Extended(ExtendedMessage)));
conn . manage_peer ( rx ) . await . unwrap ( ) ;
2021-07-02 01:38:07 +01:00
}
2021-06-25 13:47:51 +01:00
}