aboutsummaryrefslogtreecommitdiff
path: root/src/proto.rs
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2022-02-21 13:45:41 +0100
committerAlex Auvolat <alex@adnab.me>2022-02-21 13:45:41 +0100
commit96a3cc1e1f5c0c4e73ad1036a7e0add19d9a197e (patch)
tree3903e11ac310ec441db2360b6951b35c63617974 /src/proto.rs
parent5bf3886fa28812d7009fb3bb481f0d3ce3004e18 (diff)
downloadnetapp-96a3cc1e1f5c0c4e73ad1036a7e0add19d9a197e.tar.gz
netapp-96a3cc1e1f5c0c4e73ad1036a7e0add19d9a197e.zip
Implement version check & transmit more error info
Diffstat (limited to 'src/proto.rs')
-rw-r--r--src/proto.rs22
1 files changed, 21 insertions, 1 deletions
diff --git a/src/proto.rs b/src/proto.rs
index 2db3f83..146211b 100644
--- a/src/proto.rs
+++ b/src/proto.rs
@@ -1,7 +1,7 @@
use std::collections::{HashMap, VecDeque};
use std::sync::Arc;
-use log::trace;
+use log::{error, trace};
use futures::{AsyncReadExt, AsyncWriteExt};
use kuska_handshake::async_std::BoxStreamWrite;
@@ -12,6 +12,10 @@ use async_trait::async_trait;
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).
///
/// This priority value is used to priorize messages
@@ -114,6 +118,10 @@ pub(crate) trait SendLoop: Sync {
where
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 should_exit = false;
while !should_exit || !sending.is_empty() {
@@ -169,6 +177,7 @@ pub(crate) trait SendLoop: Sync {
}
}
}
+
let _ = write.goodbye().await;
Ok(())
}
@@ -189,6 +198,17 @@ pub(crate) trait RecvLoop: Sync + 'static {
where
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();
loop {
trace!("recv_loop: reading packet");