better frame parsing and handling

This commit is contained in:
nora 2022-02-09 14:05:13 +01:00
parent 2b0770705a
commit 706219c046
6 changed files with 132 additions and 31 deletions

View file

@ -1,4 +1,6 @@
use anyhow::{bail, ensure, Result};
use crate::error::{ConError, ProtocolError};
use crate::frame;
use anyhow::{ensure, Context};
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::TcpStream;
use tracing::{debug, error};
@ -19,12 +21,16 @@ impl Connection {
}
}
pub async fn run(&mut self) -> Result<()> {
pub async fn run(&mut self) -> Result<(), ConError> {
self.negotiate_version().await?;
Ok(())
loop {
let frame = frame::read_frame(&mut self.stream, 10000).await?;
debug!(?frame, "received frame");
}
}
async fn negotiate_version(&mut self) -> Result<()> {
async fn negotiate_version(&mut self) -> Result<(), ConError> {
const HEADER_SIZE: usize = 8;
const PROTOCOL_VERSION: &[u8] = &[0, 9, 1];
const PROTOCOL_HEADER: &[u8] = b"AMQP\0\0\x09\x01";
@ -33,26 +39,26 @@ impl Connection {
let mut read_header_buf = [0; HEADER_SIZE];
self.stream.read_exact(&mut read_header_buf).await?;
self.stream
.read_exact(&mut read_header_buf)
.await
.context("read protocol header")?;
debug!(received_header = ?read_header_buf,"Received protocol header");
ensure!(
&read_header_buf[0..5] == b"AMQP\0",
"Received wrong protocol"
);
let version = &read_header_buf[5..8];
self.stream.write_all(PROTOCOL_HEADER).await?;
self.stream
.write_all(PROTOCOL_HEADER)
.await
.context("write protocol header")?;
if version == PROTOCOL_VERSION {
if &read_header_buf[0..5] == b"AMQP\0" && version == PROTOCOL_VERSION {
debug!(?version, "Version negotiation successful");
Ok(())
} else {
debug!(?version, expected_version = ?PROTOCOL_VERSION, "Version negotiation failed, unsupported version");
self.stream.shutdown().await?;
bail!("Unsupported protocol version {:?}", version);
return Err(ProtocolError::OtherCloseConnection.into());
}
}
}