use crate::{connection::preauth_hash::PreauthHashValue, packets::smb2::*};
use maybe_async::*;
use std::sync::Arc;
#[derive(Debug)]
pub struct OutgoingMessage {
pub message: PlainRequest,
pub finalize_preauth_hash: bool,
pub compress: bool,
pub encrypt: bool,
pub has_response: bool,
}
impl OutgoingMessage {
pub fn new(content: RequestContent) -> OutgoingMessage {
OutgoingMessage {
message: PlainRequest::new(content),
finalize_preauth_hash: false,
compress: true,
encrypt: false,
has_response: true,
}
}
}
#[derive(Debug)]
pub struct SendMessageResult {
pub msg_id: u64,
pub preauth_hash: Option<PreauthHashValue>,
}
impl SendMessageResult {
pub fn new(msg_id: u64, preauth_hash: Option<PreauthHashValue>) -> SendMessageResult {
SendMessageResult {
msg_id,
preauth_hash,
}
}
}
#[derive(Debug)]
pub struct IncomingMessage {
pub message: PlainResponse,
pub raw: Vec<u8>,
pub form: MessageForm,
}
#[derive(Debug, Default)]
pub struct MessageForm {
pub compressed: bool,
pub encrypted: bool,
pub signed: bool,
}
impl MessageForm {
pub fn signed_or_encrypted(&self) -> bool {
self.signed || self.encrypted
}
}
#[derive(Debug)]
pub struct ReceiveOptions<'a> {
pub status: &'a [Status],
pub cmd: Option<Command>,
pub msg_id: u64,
pub allow_async: bool,
}
impl<'a> ReceiveOptions<'a> {
pub fn new() -> Self {
Self::default()
}
pub fn with_status(mut self, status: &'a [Status]) -> Self {
self.status = status;
self
}
pub fn with_cmd(mut self, cmd: Option<Command>) -> Self {
self.cmd = cmd;
self
}
pub fn with_msg_id_filter(mut self, msg_id: u64) -> Self {
self.msg_id = msg_id;
self
}
pub fn with_allow_async(mut self, allow_async: bool) -> Self {
self.allow_async = allow_async;
self
}
}
impl<'a> Default for ReceiveOptions<'a> {
fn default() -> Self {
ReceiveOptions {
status: &[Status::Success],
cmd: None,
msg_id: 0,
allow_async: false,
}
}
}
#[maybe_async(AFIT)]
#[allow(async_fn_in_trait)] pub trait MessageHandler: Send + Sync {
async fn sendo(&self, msg: OutgoingMessage) -> crate::Result<SendMessageResult>;
async fn recvo(&self, options: ReceiveOptions) -> crate::Result<IncomingMessage>;
#[maybe_async]
async fn send(&self, msg: RequestContent) -> crate::Result<SendMessageResult> {
self.sendo(OutgoingMessage::new(msg)).await
}
#[maybe_async]
async fn recv(&self, cmd: Command) -> crate::Result<IncomingMessage> {
self.recvo(ReceiveOptions::new().with_cmd(Some(cmd))).await
}
#[maybe_async]
async fn sendo_recvo(
&self,
msg: OutgoingMessage,
mut options: ReceiveOptions<'_>,
) -> crate::Result<IncomingMessage> {
let send_result = self.sendo(msg).await?;
options.msg_id = send_result.msg_id;
self.recvo(options).await
}
#[maybe_async]
async fn send_recvo(
&self,
msg: RequestContent,
options: ReceiveOptions<'_>,
) -> crate::Result<IncomingMessage> {
self.sendo_recvo(OutgoingMessage::new(msg), options).await
}
#[maybe_async]
async fn sendo_recv(&self, msg: OutgoingMessage) -> crate::Result<IncomingMessage> {
let cmd = msg.message.content.associated_cmd();
let options = ReceiveOptions::new().with_cmd(Some(cmd));
self.sendo_recvo(msg, options).await
}
#[maybe_async]
async fn send_recv(&self, msg: RequestContent) -> crate::Result<IncomingMessage> {
self.sendo_recv(OutgoingMessage::new(msg)).await
}
}
pub struct HandlerReference<T: MessageHandler + ?Sized> {
pub handler: Arc<T>,
}
impl<T: MessageHandler> HandlerReference<T> {
pub fn new(handler: T) -> HandlerReference<T> {
HandlerReference {
handler: Arc::new(handler),
}
}
}
impl<T: MessageHandler> std::ops::Deref for HandlerReference<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.handler
}
}
impl<T: MessageHandler> Clone for HandlerReference<T> {
fn clone(&self) -> Self {
HandlerReference {
handler: self.handler.clone(),
}
}
}