1use async_trait::async_trait;
12use tokio::io::{AsyncReadExt, AsyncWriteExt};
13
14use std::result;
15use std::net::{Ipv4Addr, Ipv6Addr};
16
17pub mod downstream;
20mod error;
21pub mod upstream;
23
24pub use crate::error::{Result, Error};
26
27const VERSION: u8 = 0x05;
28
29#[async_trait]
30pub trait AsyncWrite {
31 async fn write<W>(&self, buf: &mut W) -> Result<()> where W: AsyncWriteExt + Unpin + Send;
32}
33
34#[async_trait]
35pub trait AsyncRead: Sized {
36 async fn read<R>(buf: &mut R) -> Result<Self> where R: AsyncReadExt + Unpin + Send;
37}
38
39#[derive(Clone, Copy, PartialEq, Eq, Debug)]
41pub enum Method {
42 NoAuth,
44 Gssapi,
46 Auth,
48 Other(u8),
50 NoAcceptable,
52}
53
54impl From<u8> for Method {
55 fn from(val: u8) -> Self {
56 match val {
57 0x00 => Self::NoAuth,
58 0x01 => Self::Gssapi,
59 0x02 => Self::Auth,
60 _ => Self::Other(val),
61 }
62 }
63}
64
65impl From<Method> for u8 {
66 fn from(method: Method) -> Self {
67 match method {
68 Method::NoAuth => 0x00,
69 Method::Gssapi => 0x01,
70 Method::Auth => 0x02,
71 Method::Other(val) => val,
72 Method::NoAcceptable => 0xFF,
73 }
74 }
75}
76
77#[derive(Clone, Copy, PartialEq, Eq, Debug)]
79pub enum Command {
80 Connect,
82 Bind,
84 UdpAssociate,
86}
87
88impl TryFrom<u8> for Command {
89 type Error = Error;
90
91 fn try_from(val: u8) -> result::Result<Self, Self::Error> {
92 match val {
93 0x01 => Ok(Self::Connect),
94 0x02 => Ok(Self::Bind),
95 0x03 => Ok(Self::UdpAssociate),
96 _ => Err(Error::InvalidCommand)
97 }
98 }
99}
100
101impl From<Command> for u8 {
102 fn from(cmd: Command) -> Self {
103 match cmd {
104 Command::Connect => 0x01,
105 Command::Bind => 0x02,
106 Command::UdpAssociate => 0x03,
107 }
108 }
109}
110
111#[derive(Clone, PartialEq, Eq, Debug)]
113pub enum Addr {
114 V4(Ipv4Addr),
116 Domain(String),
118 V6(Ipv6Addr),
120}
121
122#[derive(Clone, Copy, PartialEq, Eq, Debug)]
124pub enum Reply {
125 Success,
127 ServerFailure,
129 NotAllowedByRuleset,
131 NetworkUnreachable,
133 HostUnreachable,
135 ConnectionRefused,
137 TtlExpired,
139 CommandNotSupported,
141 AddrTypeNotSupported,
143}
144
145impl From<Reply> for u8 {
146 fn from(reply: Reply) -> Self {
147 match reply {
148 Reply::Success => 0x00,
149 Reply::ServerFailure => 0x01,
150 Reply::NotAllowedByRuleset => 0x02,
151 Reply::NetworkUnreachable => 0x03,
152 Reply::HostUnreachable => 0x04,
153 Reply::ConnectionRefused => 0x05,
154 Reply::TtlExpired => 0x06,
155 Reply::CommandNotSupported => 0x07,
156 Reply::AddrTypeNotSupported => 0x08,
157 }
158 }
159}