Implement version check & transmit more error info
This commit is contained in:
parent
5bf3886fa2
commit
96a3cc1e1f
4 changed files with 33 additions and 6 deletions
|
@ -206,7 +206,8 @@ impl ClientConn {
|
||||||
<T as Message>::Response,
|
<T as Message>::Response,
|
||||||
>(&resp[1..])?)
|
>(&resp[1..])?)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::Remote(format!("Remote error code {}", code)))
|
let msg = String::from_utf8(resp[1..].to_vec()).unwrap_or_default();
|
||||||
|
Err(Error::Remote(code, msg))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
10
src/error.rs
10
src/error.rs
|
@ -34,8 +34,11 @@ pub enum Error {
|
||||||
#[error(display = "Connection closed")]
|
#[error(display = "Connection closed")]
|
||||||
ConnectionClosed,
|
ConnectionClosed,
|
||||||
|
|
||||||
#[error(display = "Remote error: {}", _0)]
|
#[error(display = "Version mismatch: {}", _0)]
|
||||||
Remote(String),
|
VersionMismatch(String),
|
||||||
|
|
||||||
|
#[error(display = "Remote error {}: {}", _0, _1)]
|
||||||
|
Remote(u8, String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error {
|
impl Error {
|
||||||
|
@ -50,7 +53,8 @@ impl Error {
|
||||||
Self::NoHandler => 20,
|
Self::NoHandler => 20,
|
||||||
Self::ConnectionClosed => 21,
|
Self::ConnectionClosed => 21,
|
||||||
Self::Handshake(_) => 30,
|
Self::Handshake(_) => 30,
|
||||||
Self::Remote(_) => 40,
|
Self::VersionMismatch(_) => 31,
|
||||||
|
Self::Remote(c, _) => *c,
|
||||||
Self::Message(_) => 99,
|
Self::Message(_) => 99,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
22
src/proto.rs
22
src/proto.rs
|
@ -1,7 +1,7 @@
|
||||||
use std::collections::{HashMap, VecDeque};
|
use std::collections::{HashMap, VecDeque};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use log::trace;
|
use log::{error, trace};
|
||||||
|
|
||||||
use futures::{AsyncReadExt, AsyncWriteExt};
|
use futures::{AsyncReadExt, AsyncWriteExt};
|
||||||
use kuska_handshake::async_std::BoxStreamWrite;
|
use kuska_handshake::async_std::BoxStreamWrite;
|
||||||
|
@ -12,6 +12,10 @@ use async_trait::async_trait;
|
||||||
|
|
||||||
use crate::error::*;
|
use crate::error::*;
|
||||||
|
|
||||||
|
/// Tag which is exchanged between client and server upon connection establishment
|
||||||
|
/// to check that they are running compatible versions of Netapp
|
||||||
|
pub const VERSION_TAG: [u8; 8] = [b'n', b'e', b't', b'a', b'p', b'p', 0x00, 0x04];
|
||||||
|
|
||||||
/// Priority of a request (click to read more about priorities).
|
/// Priority of a request (click to read more about priorities).
|
||||||
///
|
///
|
||||||
/// This priority value is used to priorize messages
|
/// This priority value is used to priorize messages
|
||||||
|
@ -114,6 +118,10 @@ pub(crate) trait SendLoop: Sync {
|
||||||
where
|
where
|
||||||
W: AsyncWriteExt + Unpin + Send + Sync,
|
W: AsyncWriteExt + Unpin + Send + Sync,
|
||||||
{
|
{
|
||||||
|
// Before anything, send version tag, which is checked in recv_loop
|
||||||
|
write.write_all(&VERSION_TAG[..]).await?;
|
||||||
|
write.flush().await?;
|
||||||
|
|
||||||
let mut sending = SendQueue::new();
|
let mut sending = SendQueue::new();
|
||||||
let mut should_exit = false;
|
let mut should_exit = false;
|
||||||
while !should_exit || !sending.is_empty() {
|
while !should_exit || !sending.is_empty() {
|
||||||
|
@ -169,6 +177,7 @@ pub(crate) trait SendLoop: Sync {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = write.goodbye().await;
|
let _ = write.goodbye().await;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -189,6 +198,17 @@ pub(crate) trait RecvLoop: Sync + 'static {
|
||||||
where
|
where
|
||||||
R: AsyncReadExt + Unpin + Send + Sync,
|
R: AsyncReadExt + Unpin + Send + Sync,
|
||||||
{
|
{
|
||||||
|
let mut their_version_tag = [0u8; 8];
|
||||||
|
read.read_exact(&mut their_version_tag[..]).await?;
|
||||||
|
if their_version_tag != VERSION_TAG {
|
||||||
|
let msg = format!(
|
||||||
|
"Different netapp versions: {:?} (theirs) vs. {:?} (ours)",
|
||||||
|
their_version_tag, VERSION_TAG
|
||||||
|
);
|
||||||
|
error!("{}", msg);
|
||||||
|
return Err(Error::VersionMismatch(msg));
|
||||||
|
}
|
||||||
|
|
||||||
let mut receiving = HashMap::new();
|
let mut receiving = HashMap::new();
|
||||||
loop {
|
loop {
|
||||||
trace!("recv_loop: reading packet");
|
trace!("recv_loop: reading packet");
|
||||||
|
|
|
@ -184,7 +184,9 @@ impl RecvLoop for ServerConn {
|
||||||
resp_bytes
|
resp_bytes
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
vec![e.code()]
|
let mut resp_bytes = vec![e.code()];
|
||||||
|
resp_bytes.extend(e.to_string().into_bytes());
|
||||||
|
resp_bytes
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue