Skip to main content

ethrex_p2p/discovery/
codec.rs

1//! Discriminating codec for multiplexing discv4 and discv5 on a shared UDP socket.
2//!
3//! This codec simply passes through raw bytes - the actual protocol discrimination
4//! happens in the multiplexer based on the keccak hash check.
5
6use bytes::BytesMut;
7use std::io::{Error, ErrorKind};
8use std::net::SocketAddr;
9use tokio_util::codec::{Decoder, Encoder};
10
11/// A raw packet received from the UDP socket.
12#[derive(Debug, Clone)]
13pub struct RawPacket {
14    pub data: BytesMut,
15    pub from: SocketAddr,
16}
17
18/// A codec that passes through raw bytes for the multiplexer to process.
19/// The actual protocol discrimination happens in the multiplexer.
20#[derive(Debug)]
21pub struct DiscriminatingCodec;
22
23impl DiscriminatingCodec {
24    pub fn new() -> Self {
25        Self
26    }
27}
28
29impl Default for DiscriminatingCodec {
30    fn default() -> Self {
31        Self::new()
32    }
33}
34
35impl Decoder for DiscriminatingCodec {
36    type Item = BytesMut;
37    type Error = std::io::Error;
38
39    fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
40        if src.is_empty() {
41            Ok(None)
42        } else {
43            Ok(Some(src.split_to(src.len())))
44        }
45    }
46}
47
48impl Encoder<BytesMut> for DiscriminatingCodec {
49    type Error = std::io::Error;
50
51    fn encode(&mut self, _item: BytesMut, _dst: &mut BytesMut) -> Result<(), Self::Error> {
52        Err(Error::new(
53            ErrorKind::Unsupported,
54            "DiscriminatingCodec is receive-only; each protocol handles its own encoding",
55        ))
56    }
57}