Skip to content

Commit

Permalink
Implement LT_metadata Extension; Implement Generic Extension Protocol…
Browse files Browse the repository at this point in the history
… Message Type
  • Loading branch information
GGist committed Sep 18, 2017
1 parent c6850cc commit 8f195ed
Show file tree
Hide file tree
Showing 9 changed files with 304 additions and 25 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,6 @@ Cargo.lock
# Test Files
spike/
*.torrent

# Visual Studio Code Files
.vscode
2 changes: 2 additions & 0 deletions bip_peer/src/manager/task.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![allow(deprecated)]

use std::io;

use manager::builder::PeerManagerBuilder;
Expand Down
25 changes: 23 additions & 2 deletions bip_peer/src/message/bencode/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ pub const CLIENT_IPV4_ADDR_KEY: &'static [u8] = b"ipv4";
pub const CLIENT_MAX_REQUESTS_KEY: &'static [u8] = b"reqq";
pub const METADATA_SIZE_KEY: &'static [u8] = b"metadata_size";

pub fn parse_id_map<'a, B>(root: &BDictAccess<'a, B>) -> HashMap<ExtendedType, i64>
pub fn parse_id_map<'a, B>(root: &BDictAccess<'a, B>) -> HashMap<ExtendedType, u8>
where B: BRefAccess<'a> {
let mut id_map = HashMap::new();

if let Ok(ben_id_map) = CONVERT.lookup_and_convert_dict(root, ID_MAP_KEY) {
for (id, ben_value) in ben_id_map.to_list() {
match (str::from_utf8(id), CONVERT.convert_int(ben_value, id)) {
(Ok(str_id), Ok(value)) => { id_map.insert(ExtendedType::from_id(str_id), value); },
(Ok(str_id), Ok(value)) => { id_map.insert(ExtendedType::from_id(str_id), value as u8); },
_ => ()
}
}
Expand Down Expand Up @@ -129,4 +129,25 @@ fn parse_ipv6_addr(ipv6_bytes: &[u8]) -> Ipv6Addr {
ipv6_bytes[4], ipv6_bytes[5], ipv6_bytes[6], ipv6_bytes[7],
ipv6_bytes[8], ipv6_bytes[9], ipv6_bytes[10], ipv6_bytes[11],
ipv6_bytes[12], ipv6_bytes[13], ipv6_bytes[14], ipv6_bytes[15]])
}

// ----------------------------------------------------------------------------//

pub const MESSAGE_TYPE_KEY: &'static [u8] = b"msg_type";
pub const PIECE_INDEX_KEY: &'static [u8] = b"piece";
pub const TOTAL_SIZE_KEY: &'static [u8] = b"total_size";

pub fn parse_message_type<'a, B>(root: &BDictAccess<'a, B>) -> io::Result<u8>
where B: BRefAccess<'a> {
CONVERT.lookup_and_convert_int(root, MESSAGE_TYPE_KEY).map(|msg_type| msg_type as u8).into()
}

pub fn parse_piece_index<'a, B>(root: &BDictAccess<'a, B>) -> io::Result<i64>
where B: BRefAccess<'a> {
CONVERT.lookup_and_convert_int(root, PIECE_INDEX_KEY).into()
}

pub fn parse_total_size<'a, B>(root: &BDictAccess<'a, B>) -> io::Result<i64>
where B: BRefAccess<'a> {
CONVERT.lookup_and_convert_int(root, TOTAL_SIZE_KEY).into()
}
14 changes: 7 additions & 7 deletions bip_peer/src/message/bits_extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ use message::bencode;
const PORT_MESSAGE_LEN: u32 = 3;
const BASE_EXTENDED_MESSAGE_LEN: u32 = 6;

const PORT_MESSAGE_ID: u8 = 9;
const EXTENDED_MESSAGE_ID: u8 = 20;
const PORT_MESSAGE_ID: u8 = 9;
pub const EXTENDED_MESSAGE_ID: u8 = 20;

const EXTENDED_MESSAGE_HANDSHAKE_ID: u8 = 0;

Expand Down Expand Up @@ -152,7 +152,7 @@ impl ExtendedType {
/// See `http://www.bittorrent.org/beps/bep_0010.html`.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ExtendedMessage {
id_map: HashMap<ExtendedType, i64>,
id_map: HashMap<ExtendedType, u8>,
client_id: Option<String>,
client_tcp_port: Option<u16>,
our_ip: Option<IpAddr>,
Expand All @@ -164,15 +164,15 @@ pub struct ExtendedMessage {
}

impl ExtendedMessage {
fn with_raw(id_map: HashMap<ExtendedType, i64>, client_id: Option<String>, client_tcp_port: Option<u16>,
fn with_raw(id_map: HashMap<ExtendedType, u8>, client_id: Option<String>, client_tcp_port: Option<u16>,
our_ip: Option<IpAddr>, client_ipv6_addr: Option<Ipv6Addr>, client_ipv4_addr: Option<Ipv4Addr>,
client_max_requests: Option<i64>, metadata_size: Option<i64>, raw_bencode: Bytes) -> ExtendedMessage {
ExtendedMessage{ id_map: id_map, client_id: client_id, client_tcp_port: client_tcp_port,
our_ip: our_ip, client_ipv6_addr: client_ipv6_addr, client_ipv4_addr: client_ipv4_addr,
client_max_requests: client_max_requests, metadata_size: metadata_size, raw_bencode: raw_bencode }
}

pub fn new(id_map: HashMap<ExtendedType, i64>, client_id: Option<String>, client_tcp_port: Option<u16>,
pub fn new(id_map: HashMap<ExtendedType, u8>, client_id: Option<String>, client_tcp_port: Option<u16>,
our_ip: Option<IpAddr>, client_ipv6_addr: Option<Ipv6Addr>, client_ipv4_addr: Option<Ipv4Addr>,
client_max_requests: Option<i64>, metadata_size: Option<i64>) -> ExtendedMessage {
let mut message = ExtendedMessage{ id_map: id_map, client_id: client_id, client_tcp_port: client_tcp_port,
Expand Down Expand Up @@ -236,7 +236,7 @@ impl ExtendedMessage {
self.raw_bencode.len()
}

pub fn query_id(&self, ext_type: &ExtendedType) -> Option<i64> {
pub fn query_id(&self, ext_type: &ExtendedType) -> Option<u8> {
self.id_map.get(ext_type).map(|id| *id)
}

Expand Down Expand Up @@ -291,7 +291,7 @@ fn bencode_from_extended_params(extended: &ExtendedMessage) -> Vec<u8> {
{
let ben_id_map_access = ben_id_map.dict_mut().unwrap();
for (ext_id, &value) in extended.id_map.iter() {
ben_id_map_access.insert(ext_id.id().as_bytes(), ben_int!(value));
ben_id_map_access.insert(ext_id.id().as_bytes(), ben_int!(value as i64));
}
}

Expand Down
4 changes: 3 additions & 1 deletion bip_peer/src/message/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,14 @@ const HEADER_LEN: usize = MESSAGE_LENGTH_LEN_BYTES + MESSAGE_ID_LE

mod bencode;
mod bits_extension;
mod prot_extension;
mod standard;
mod null;

pub use message::bits_extension::{BitsExtensionMessage, PortMessage, ExtendedMessage, ExtendedType};
pub use message::standard::{HaveMessage, BitFieldMessage, BitFieldIter, RequestMessage, PieceMessage, CancelMessage};
pub use message::null::NullProtocolMessage;
pub use message::prot_extension::{PeerExtensionProtocolMessage, LtMetadataMessage, LtMetadataRequestMessage, LtMetadataDataMessage, LtMetadataRejectMessage};

/// Enumeration of messages for `PeerWireProtocol`.
pub enum PeerWireProtocolMessage<P> where P: PeerProtocol {
Expand Down Expand Up @@ -100,7 +102,7 @@ impl<P> ManagedMessage for PeerWireProtocolMessage<P>

impl<P> PeerWireProtocolMessage<P>
where P: PeerProtocol {
pub fn bytes_needed(bytes: &[u8], _ext_protocol: &mut P) -> io::Result<Option<usize>> {
pub fn bytes_needed(bytes: &[u8]) -> io::Result<Option<usize>> {
match be_u32(bytes) {
// We need 4 bytes for the length, plus whatever the length is...
IResult::Done(_, length) => Ok(Some(MESSAGE_LENGTH_LEN_BYTES + u32_to_usize(length))),
Expand Down
Loading

0 comments on commit 8f195ed

Please sign in to comment.