#![allow(unused)]
use std::io::{self, Write};
use protocol::PeerProtocol;
use manager::ManagedMessage;
use bytes::Bytes;
use byteorder::{WriteBytesExt, BigEndian};
use nom::{IResult, be_u32, be_u8};
const KEEP_ALIVE_MESSAGE_LEN: u32 = 0;
const CHOKE_MESSAGE_LEN: u32 = 1;
const UNCHOKE_MESSAGE_LEN: u32 = 1;
const INTERESTED_MESSAGE_LEN: u32 = 1;
const UNINTERESTED_MESSAGE_LEN: u32 = 1;
const HAVE_MESSAGE_LEN: u32 = 5;
const BASE_BITFIELD_MESSAGE_LEN: u32 = 1;
const REQUEST_MESSAGE_LEN: u32 = 13;
const BASE_PIECE_MESSAGE_LEN: u32 = 9;
const CANCEL_MESSAGE_LEN: u32 = 13;
const CHOKE_MESSAGE_ID: u8 = 0;
const UNCHOKE_MESSAGE_ID: u8 = 1;
const INTERESTED_MESSAGE_ID: u8 = 2;
const UNINTERESTED_MESSAGE_ID: u8 = 3;
const HAVE_MESSAGE_ID: u8 = 4;
const BITFIELD_MESSAGE_ID: u8 = 5;
const REQUEST_MESSAGE_ID: u8 = 6;
const PIECE_MESSAGE_ID: u8 = 7;
const CANCEL_MESSAGE_ID: u8 = 8;
const MESSAGE_LENGTH_LEN_BYTES: usize = 4;
const MESSAGE_ID_LEN_BYTES: usize = 1;
const HEADER_LEN: usize = MESSAGE_LENGTH_LEN_BYTES + MESSAGE_ID_LEN_BYTES;
mod bencode;
mod bits_ext;
mod prot_ext;
mod standard;
mod null;
pub use message::bits_ext::{BitsExtensionMessage, PortMessage, ExtendedMessage, ExtendedMessageBuilder, ExtendedType};
pub use message::standard::{HaveMessage, BitFieldMessage, BitFieldIter, RequestMessage, PieceMessage, CancelMessage};
pub use message::null::NullProtocolMessage;
pub use message::prot_ext::{PeerExtensionProtocolMessage, UtMetadataMessage, UtMetadataRequestMessage, UtMetadataDataMessage, UtMetadataRejectMessage};
pub enum PeerWireProtocolMessage<P> where P: PeerProtocol {
KeepAlive,
Choke,
UnChoke,
Interested,
UnInterested,
Have(HaveMessage),
BitField(BitFieldMessage),
Request(RequestMessage),
Piece(PieceMessage),
Cancel(CancelMessage),
BitsExtension(BitsExtensionMessage),
ProtExtension(P::ProtocolMessage)
}
impl<P> ManagedMessage for PeerWireProtocolMessage<P>
where P: PeerProtocol {
fn keep_alive() -> PeerWireProtocolMessage<P> {
PeerWireProtocolMessage::KeepAlive
}
fn is_keep_alive(&self) -> bool {
match self {
&PeerWireProtocolMessage::KeepAlive => true,
_ => false
}
}
}
impl<P> PeerWireProtocolMessage<P>
where P: PeerProtocol {
pub fn bytes_needed(bytes: &[u8]) -> io::Result<Option<usize>> {
match be_u32(bytes) {
IResult::Done(_, length) => Ok(Some(MESSAGE_LENGTH_LEN_BYTES + u32_to_usize(length))),
_ => Ok(None)
}
}
pub fn parse_bytes(bytes: Bytes, ext_protocol: &mut P) -> io::Result<PeerWireProtocolMessage<P>> {
match parse_message(bytes, ext_protocol) {
IResult::Done(_, result) => result,
_ => Err(io::Error::new(io::ErrorKind::Other, "Failed To Parse PeerWireProtocolMessage"))
}
}
pub fn write_bytes<W>(&self, writer: W, ext_protocol: &mut P) -> io::Result<()>
where W: Write
{
match self {
&PeerWireProtocolMessage::KeepAlive => write_length_id_pair(writer, KEEP_ALIVE_MESSAGE_LEN, None),
&PeerWireProtocolMessage::Choke => write_length_id_pair(writer, CHOKE_MESSAGE_LEN, Some(CHOKE_MESSAGE_ID)),
&PeerWireProtocolMessage::UnChoke => write_length_id_pair(writer, UNCHOKE_MESSAGE_LEN, Some(UNCHOKE_MESSAGE_ID)),
&PeerWireProtocolMessage::Interested => write_length_id_pair(writer, INTERESTED_MESSAGE_LEN, Some(INTERESTED_MESSAGE_ID)),
&PeerWireProtocolMessage::UnInterested => write_length_id_pair(writer, UNINTERESTED_MESSAGE_LEN, Some(UNINTERESTED_MESSAGE_ID)),
&PeerWireProtocolMessage::Have(ref msg) => msg.write_bytes(writer),
&PeerWireProtocolMessage::BitField(ref msg) => msg.write_bytes(writer),
&PeerWireProtocolMessage::Request(ref msg) => msg.write_bytes(writer),
&PeerWireProtocolMessage::Piece(ref msg) => msg.write_bytes(writer),
&PeerWireProtocolMessage::Cancel(ref msg) => msg.write_bytes(writer),
&PeerWireProtocolMessage::BitsExtension(ref ext) => ext.write_bytes(writer),
&PeerWireProtocolMessage::ProtExtension(ref ext) => ext_protocol.write_bytes(ext, writer)
}
}
pub fn message_size(&self, ext_protocol: &mut P) -> usize {
let message_specific_len = match self {
&PeerWireProtocolMessage::KeepAlive => KEEP_ALIVE_MESSAGE_LEN as usize,
&PeerWireProtocolMessage::Choke => CHOKE_MESSAGE_LEN as usize,
&PeerWireProtocolMessage::UnChoke => UNCHOKE_MESSAGE_LEN as usize,
&PeerWireProtocolMessage::Interested => INTERESTED_MESSAGE_LEN as usize,
&PeerWireProtocolMessage::UnInterested => UNINTERESTED_MESSAGE_LEN as usize,
&PeerWireProtocolMessage::Have(_) => HAVE_MESSAGE_LEN as usize,
&PeerWireProtocolMessage::BitField(ref msg) => BASE_BITFIELD_MESSAGE_LEN as usize + msg.bitfield().len(),
&PeerWireProtocolMessage::Request(_) => REQUEST_MESSAGE_LEN as usize,
&PeerWireProtocolMessage::Piece(ref msg) => BASE_PIECE_MESSAGE_LEN as usize + msg.block().len(),
&PeerWireProtocolMessage::Cancel(_) => CANCEL_MESSAGE_LEN as usize,
&PeerWireProtocolMessage::BitsExtension(ref ext) => ext.message_size(),
&PeerWireProtocolMessage::ProtExtension(ref ext) => ext_protocol.message_size(ext)
};
MESSAGE_LENGTH_LEN_BYTES + message_specific_len
}
}
fn write_length_id_pair<W>(mut writer: W, length: u32, opt_id: Option<u8>) -> io::Result<()>
where W: Write
{
try!(writer.write_u32::<BigEndian>(length));
if let Some(id) = opt_id {
writer.write_u8(id)
} else {
Ok(())
}
}
fn parse_message_length(bytes: &[u8]) -> usize {
if let IResult::Done(_, len) = be_u32(bytes) {
u32_to_usize(len)
} else {
panic!("bip_peer: Message Length Was Less Than 4 Bytes")
}
}
fn u32_to_usize(value: u32) -> usize {
if value as usize as u32 != value {
panic!("bip_peer: Cannot Convert u32 To usize, usize Is Less Than 32-Bits")
}
value as usize
}
fn parse_message<P>(mut bytes: Bytes, ext_protocol: &mut P) -> IResult<(), io::Result<PeerWireProtocolMessage<P>>>
where P: PeerProtocol {
let header_bytes = bytes.clone();
alt!((),
ignore_input!(
switch!(header_bytes.as_ref(), throwaway_input!(tuple!(be_u32, opt!(be_u8))),
(KEEP_ALIVE_MESSAGE_LEN, None) => value!(
Ok(PeerWireProtocolMessage::KeepAlive)
) |
(CHOKE_MESSAGE_LEN, Some(CHOKE_MESSAGE_ID)) => value!(
Ok(PeerWireProtocolMessage::Choke)
) |
(UNCHOKE_MESSAGE_LEN, Some(UNCHOKE_MESSAGE_ID)) => value!(
Ok(PeerWireProtocolMessage::UnChoke)
) |
(INTERESTED_MESSAGE_LEN, Some(INTERESTED_MESSAGE_ID)) => value!(
Ok(PeerWireProtocolMessage::Interested)
) |
(UNINTERESTED_MESSAGE_LEN, Some(UNINTERESTED_MESSAGE_ID)) => value!(
Ok(PeerWireProtocolMessage::UnInterested)
) |
(HAVE_MESSAGE_LEN, Some(HAVE_MESSAGE_ID)) => map!(
call!(HaveMessage::parse_bytes, bytes.split_off(HEADER_LEN)),
|res_have| res_have.map(|have| PeerWireProtocolMessage::Have(have))
) |
(message_len, Some(BITFIELD_MESSAGE_ID)) => map!(
call!(BitFieldMessage::parse_bytes, bytes.split_off(HEADER_LEN), message_len - 1),
|res_bitfield| res_bitfield.map(|bitfield| PeerWireProtocolMessage::BitField(bitfield))
) |
(REQUEST_MESSAGE_LEN, Some(REQUEST_MESSAGE_ID)) => map!(
call!(RequestMessage::parse_bytes, bytes.split_off(HEADER_LEN)),
|res_request| res_request.map(|request| PeerWireProtocolMessage::Request(request))
) |
(message_len, Some(PIECE_MESSAGE_ID)) => map!(
call!(PieceMessage::parse_bytes, bytes.split_off(HEADER_LEN), message_len - 1),
|res_piece| res_piece.map(|piece| PeerWireProtocolMessage::Piece(piece))
) |
(CANCEL_MESSAGE_LEN, Some(CANCEL_MESSAGE_ID)) => map!(
call!(CancelMessage::parse_bytes, bytes.split_off(HEADER_LEN)),
|res_cancel| res_cancel.map(|cancel| PeerWireProtocolMessage::Cancel(cancel))
)
)
) | map!(call!(BitsExtensionMessage::parse_bytes, bytes.clone()),
|res_bits_ext| res_bits_ext.map(|bits_ext| PeerWireProtocolMessage::BitsExtension(bits_ext)))
| map!(value!(ext_protocol.parse_bytes(bytes)),
|res_prot_ext| res_prot_ext.map(|prot_ext| PeerWireProtocolMessage::ProtExtension(prot_ext)))
)
}