AcceptHandshake

This commit is contained in:
debris 2016-09-28 16:41:15 +02:00
parent 22bfeabc41
commit 0140881c38
2 changed files with 68 additions and 1 deletions

View File

@ -9,6 +9,10 @@ fn local_version() -> Message {
unimplemented!();
}
fn verack() -> Message {
unimplemented!();
}
pub struct HandshakeResult {
pub version: Version,
pub negotiated_version: u32,
@ -24,16 +28,38 @@ enum HandshakeState<A> {
},
}
enum AcceptHandshakeState<A> {
ReceiveVersion(ReadMessage<A>),
SendVersion {
version: Version,
future: WriteMessage<A>,
},
SendVerack {
version: Version,
future: WriteMessage<A>,
}
}
pub fn handshake<A>(a: A) -> Handshake<A> where A: io::Write + io::Read {
Handshake {
state: HandshakeState::SendVersion(write_message(a, &local_version())),
}
}
pub fn accept_handshake<A>(a: A) -> AcceptHandshake<A> where A: io::Write + io::Read {
AcceptHandshake {
state: AcceptHandshakeState::ReceiveVersion(read_message(a, 0)),
}
}
pub struct Handshake<A> {
state: HandshakeState<A>,
}
pub struct AcceptHandshake<A> {
state: AcceptHandshakeState<A>,
}
impl<A> Future for Handshake<A> where A: io::Read + io::Write {
type Item = (A, HandshakeResult);
type Error = Error;
@ -75,3 +101,44 @@ impl<A> Future for Handshake<A> where A: io::Read + io::Write {
Ok(Async::NotReady)
}
}
impl<A> Future for AcceptHandshake<A> where A: io::Read + io::Write {
type Item = (A, HandshakeResult);
type Error = Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
let next = match self.state {
AcceptHandshakeState::ReceiveVersion(ref mut future) => {
let (stream, message) = try_async!(future.poll());
let version = match message.payload {
Payload::Version(version) => version,
_ => return Err(Error::HandshakeFailed),
};
AcceptHandshakeState::SendVersion {
version: version,
future: write_message(stream, &local_version()),
}
},
AcceptHandshakeState::SendVersion { ref version, ref mut future } => {
let (stream, _) = try_async!(future.poll());
AcceptHandshakeState::SendVerack {
version: version.clone(),
future: write_message(stream, &verack()),
}
},
AcceptHandshakeState::SendVerack { ref version, ref mut future } => {
let (stream, _) = try_async!(future.poll());
let result = HandshakeResult {
version: version.clone(),
negotiated_version: cmp::min(VERSION, version.version()),
};
return Ok(Async::Ready((stream, result)));
}
};
self.state = next;
Ok(Async::NotReady)
}
}

View File

@ -14,7 +14,7 @@ mod read_payload;
mod write_message;
pub use self::error::Error;
pub use self::handshake::{handshake, Handshake};
pub use self::handshake::{handshake, accept_handshake, Handshake, AcceptHandshake};
pub use self::read_header::{read_header, ReadHeader};
pub use self::read_message::{read_message, ReadMessage};
pub use self::read_payload::{read_payload, ReadPayload};