1use std::io::{self, Read, Write};
3use std::os::unix::net::UnixStream;
4
5pub const MAX_FRAME: usize = 1024 * 1024;
6
7#[derive(Debug)]
8#[allow(dead_code)]
9pub enum ProxyError {
10 DaemonUnavailable,
11 FrameTooLarge,
12 Io(io::Error),
13}
14
15impl From<io::Error> for ProxyError {
16 fn from(e: io::Error) -> Self {
17 Self::Io(e)
18 }
19}
20
21pub fn connect(path: &std::path::Path) -> Result<UnixStream, ProxyError> {
22 connect_timeout(path, 2000)
23}
24
25pub fn connect_timeout(path: &std::path::Path, timeout_ms: u64) -> Result<UnixStream, ProxyError> {
26 let stream = UnixStream::connect(path).map_err(|_| ProxyError::DaemonUnavailable)?;
27 stream.set_read_timeout(Some(std::time::Duration::from_millis(timeout_ms)))?;
28 Ok(stream)
29}
30
31pub fn read_frame<R: Read>(r: &mut R) -> Result<Vec<u8>, ProxyError> {
32 let mut n = [0u8; 4];
33 r.read_exact(&mut n)?;
34 let len = u32::from_be_bytes(n) as usize;
35 if len > MAX_FRAME {
36 return Err(ProxyError::FrameTooLarge);
37 }
38 let mut b = vec![0; len];
39 r.read_exact(&mut b)?;
40 Ok(b)
41}
42
43pub fn write_frame<W: Write>(w: &mut W, payload: &[u8]) -> Result<(), ProxyError> {
44 if payload.len() > MAX_FRAME {
45 return Err(ProxyError::FrameTooLarge);
46 }
47 w.write_all(&(payload.len() as u32).to_be_bytes())?;
48 w.write_all(payload)?;
49 w.flush()?;
50 Ok(())
51}