use std::marker::PhantomData;
/// A composable protocol trait.
///
/// Can be reused to allow for composition of multiple compatible protocols
pub trait Protocol {
/// Allows for handling incoming packets, and returning something up to the handler of the protocol as well
/// as packets to send out
///
/// Usually, this will take in a slice of bytes and return a Vec of some enum or another slice of bytes
/// to be consumed by another protocol
fn handle_event(&mut self, packet: I) -> (T, I);
/// Allows for composing multiple protocols on top of each other, for instance to use
/// TCP fragmenting to work with HTTP to form a complete packet, and then take the HTTP
/// conversation and encode Sparse messages into it
fn compose
(self, other: P) -> ProtocolCompose
where
J: From,
P: Protocol + Sized,
Self: Sized,
{
ProtocolCompose {
protocol1: self,
protocol2: other,
generic_i: PhantomData,
generic_j: PhantomData,
generic_t: PhantomData,
generic_u: PhantomData,
}
}
}
/// A struct to go along with the compose method from before. Represents two underlying protocols
/// which work together to act as one
pub struct ProtocolCompose, P2: Protocol, I, J: From, T, U> {
protocol1: P1,
protocol2: P2,
generic_i: PhantomData,
generic_j: PhantomData,
generic_t: PhantomData,
generic_u: PhantomData,
}
impl, P2: Protocol, I, J: From, T, U> Protocol
for ProtocolCompose
{
fn handle_event(&mut self, packet: I) -> U {
let elem1 = self.protocol1.handle_event(packet);
self.protocol2.handle_event(elem1)
}
}
/// High level protocol that used for the overall application
///
/// Is meant to be composed on top of other protocols
pub struct SparseProtocol {}
/// Protocol for embedding and extracting data in and from DNS requests
pub struct DnsProtocol {}
/// Protocol for raw TCP
pub struct TcpProtocol {}
/// Protocol for HTTP over TCP
///
/// Run for bind shells, this will likely be used even with an HTTP
/// server running, as the port can be "shared" with pcap
pub struct HttpProtocol {}