Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement LT_metadata Extension; Implement Generic Extension Protocol… #125

Merged
merged 2 commits into from
Sep 28, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
1 change: 1 addition & 0 deletions bip_peer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,5 @@ pub mod protocols {
pub use protocol::unit::UnitProtocol;
pub use protocol::null::NullProtocol;
pub use protocol::wire::PeerWireProtocol;
pub use protocol::extension::PeerExtensionProtocol;
}
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()
}
22 changes: 11 additions & 11 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 @@ -118,29 +118,29 @@ fn parse_port(bytes: &[u8]) -> IResult<&[u8], PortMessage> {

const ROOT_ERROR_KEY: &'static str = "ExtendedMessage";

const LT_METADATA_ID: &'static str = "LT_metadata";
const UT_METADATA_ID: &'static str = "ut_metadata";
const UT_PEX_ID: &'static str = "ut_pex";

/// Enumeration of extended types activated via `ExtendedMessage`.
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub enum ExtendedType {
LtMetadata,
UtMetadata,
UtPex,
Custom(String)
}

impl ExtendedType {
pub fn from_id(id: &str) -> ExtendedType {
match id {
LT_METADATA_ID => ExtendedType::LtMetadata,
UT_METADATA_ID => ExtendedType::UtMetadata,
UT_PEX_ID => ExtendedType::UtPex,
custom => ExtendedType::Custom(custom.to_string())
}
}

pub fn id(&self) -> &str {
match self {
&ExtendedType::LtMetadata => LT_METADATA_ID,
&ExtendedType::UtMetadata => UT_METADATA_ID,
&ExtendedType::UtPex => UT_PEX_ID,
&ExtendedType::Custom(ref id) => &**id
}
Expand All @@ -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, UtMetadataMessage, UtMetadataRequestMessage, UtMetadataDataMessage, UtMetadataRejectMessage};

/// 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