mpc_protocol/encoding/
mod.rs

1//! Binary encoding implementation.
2
3mod v1;
4pub use v1::VERSION;
5
6use crate::Error;
7use binary_stream::{
8    futures::{BinaryReader, BinaryWriter, Decodable, Encodable},
9    Endian, Options,
10};
11use futures::io::{AsyncRead, AsyncSeek, AsyncWrite};
12use std::io::Result;
13
14pub(crate) fn encoding_error(
15    e: impl std::error::Error + Send + Sync + 'static,
16) -> std::io::Error {
17    std::io::Error::new(std::io::ErrorKind::Other, e)
18}
19
20/// Maximum buffer size for encoding and decoding.
21pub(crate) const MAX_BUFFER_SIZE: usize = 65535;
22
23/// Identity bytes (MPCR)
24const IDENTITY: [u8; 4] = [0x4D, 0x50, 0x43, 0x52];
25
26/// Encode message preamble.
27async fn encode_preamble<W: AsyncWrite + AsyncSeek + Unpin + Send>(
28    writer: &mut BinaryWriter<W>,
29) -> Result<()> {
30    writer.write_bytes(&IDENTITY).await?;
31    writer.write_u16(&VERSION).await?;
32    Ok(())
33}
34
35/// Decode message preamble.
36async fn decode_preamble<R: AsyncRead + AsyncSeek + Unpin + Send>(
37    reader: &mut BinaryReader<R>,
38) -> Result<()> {
39    let identity = reader.read_bytes(IDENTITY.len()).await?;
40    if identity != IDENTITY {
41        return Err(encoding_error(Error::BadEncodingIdentity));
42    }
43
44    let version = reader.read_u16().await?;
45    if version != VERSION {
46        return Err(encoding_error(Error::EncodingVersion(
47            VERSION, version,
48        )));
49    }
50
51    Ok(())
52}
53
54/// Default binary encoding options.
55fn encoding_options() -> Options {
56    Options {
57        endian: Endian::Little,
58        max_buffer_size: Some(MAX_BUFFER_SIZE),
59    }
60}
61
62/// Encode to a binary buffer.
63pub async fn encode(encodable: &impl Encodable) -> Result<Vec<u8>> {
64    binary_stream::futures::encode(encodable, encoding_options())
65        .await
66}
67
68/// Decode from a binary buffer.
69pub async fn decode<T: Decodable + Default>(
70    buffer: impl AsRef<[u8]>,
71) -> Result<T> {
72    binary_stream::futures::decode(
73        buffer.as_ref(),
74        encoding_options(),
75    )
76    .await
77}
78
79pub(crate) mod types {
80    pub const NOOP: u8 = 0;
81    pub const ERROR: u8 = 255;
82
83    pub const HANDSHAKE_INITIATOR: u8 = 1;
84    pub const HANDSHAKE_RESPONDER: u8 = 2;
85
86    pub const HANDSHAKE_SERVER: u8 = 1;
87    pub const HANDSHAKE_PEER: u8 = 2;
88
89    pub const TRANSPARENT: u8 = 128;
90    pub const OPAQUE: u8 = 129;
91
92    pub const OPAQUE_SERVER: u8 = 1;
93    pub const OPAQUE_PEER: u8 = 2;
94
95    pub const MEETING_NEW: u8 = 1;
96    pub const MEETING_CREATED: u8 = 2;
97    pub const MEETING_JOIN: u8 = 3;
98    pub const MEETING_READY: u8 = 4;
99
100    pub const SESSION_NEW: u8 = 5;
101    pub const SESSION_CREATED: u8 = 6;
102    pub const SESSION_READY: u8 = 7;
103    pub const SESSION_CONNECTION: u8 = 8;
104    pub const SESSION_ACTIVE: u8 = 9;
105    pub const SESSION_TIMEOUT: u8 = 10;
106    pub const SESSION_CLOSE: u8 = 11;
107    pub const SESSION_FINISHED: u8 = 12;
108
109    pub const ENCODING_BLOB: u8 = 1;
110    pub const ENCODING_JSON: u8 = 2;
111}