use std::fmt;
use std::time::Duration;
use crate::wal::WAL_FORMAT_VERSION;
pub const CONNECT_TIMEOUT: Duration = Duration::from_secs(10);
pub const ALPN_GNITZ: &[u8] = b"gnitz/1";
pub const HELLO: [u8; 8] = {
let v = WAL_FORMAT_VERSION.to_le_bytes();
[b'G', b'N', b'T', b'Z', v[0], v[1], v[2], v[3]]
};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum HelloError {
Malformed,
Version { peer: u32 },
}
impl fmt::Display for HelloError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
HelloError::Malformed => f.write_str("peer is not a gnitz endpoint (malformed HELLO)"),
HelloError::Version { peer } => {
write!(f, "wire version mismatch: peer={peer}, local={WAL_FORMAT_VERSION}")
}
}
}
}
pub fn check_hello(payload: &[u8]) -> Result<(), HelloError> {
if payload.len() != HELLO.len() || payload[..4] != HELLO[..4] {
return Err(HelloError::Malformed);
}
match crate::read_u32_le(payload, 4) {
WAL_FORMAT_VERSION => Ok(()),
peer => Err(HelloError::Version { peer }),
}
}
#[cfg(test)]
#[path = "tests/handshake.rs"]
mod tests;