diff --git a/src/handshake/machine.rs b/src/handshake/machine.rs index a7fe04a..ec98f7e 100644 --- a/src/handshake/machine.rs +++ b/src/handshake/machine.rs @@ -40,50 +40,58 @@ impl HandshakeMachine { /// Perform a single handshake round. pub fn single_round(mut self) -> Result> { trace!("Doing handshake round."); - Ok(match self.state { + match self.state { HandshakeState::Reading(mut buf) => { buf.reserve(MIN_READ, usize::max_value()) // TODO limit size .map_err(|_| Error::Capacity("Header too long".into()))?; - if let Some(_) = buf.read_from(&mut self.stream).no_block()? { - if let Some((size, obj)) = Obj::try_parse(Buf::bytes(&buf))? { - buf.advance(size); - RoundResult::StageFinished(StageResult::DoneReading { - result: obj, - stream: self.stream, - tail: buf.into_vec(), + match buf.read_from(&mut self.stream).no_block()? { + Some(0) => { + Err(Error::Protocol("Handshake not finished".into())) + } + Some(_) => { + Ok(if let Some((size, obj)) = Obj::try_parse(Buf::bytes(&buf))? { + buf.advance(size); + RoundResult::StageFinished(StageResult::DoneReading { + result: obj, + stream: self.stream, + tail: buf.into_vec(), + }) + } else { + RoundResult::Incomplete(HandshakeMachine { + state: HandshakeState::Reading(buf), + ..self + }) }) - } else { - RoundResult::Incomplete(HandshakeMachine { + } + None => { + Ok(RoundResult::WouldBlock(HandshakeMachine { state: HandshakeState::Reading(buf), ..self - }) + })) } - } else { - RoundResult::WouldBlock(HandshakeMachine { - state: HandshakeState::Reading(buf), - ..self - }) } } HandshakeState::Writing(mut buf) => { + assert!(buf.has_remaining()); if let Some(size) = self.stream.write(Buf::bytes(&buf)).no_block()? { + assert!(size > 0); buf.advance(size); - if buf.has_remaining() { + Ok(if buf.has_remaining() { RoundResult::Incomplete(HandshakeMachine { state: HandshakeState::Writing(buf), ..self }) } else { RoundResult::StageFinished(StageResult::DoneWriting(self.stream)) - } + }) } else { - RoundResult::WouldBlock(HandshakeMachine { + Ok(RoundResult::WouldBlock(HandshakeMachine { state: HandshakeState::Writing(buf), ..self - }) + })) } } - }) + } } }