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 {}