1use bytes::Bytes;
6
7use crate::{
8 Version,
9 coding::{self, Decode, DecodeError, Encode, EncodeError, Sizer},
10 ietf, lite,
11};
12
13const CLIENT_SETUP: u8 = 0x20;
14const SERVER_SETUP: u8 = 0x21;
15
16pub(crate) const SETUP_V17: u64 = 0x2F00;
18
19#[derive(Debug, Clone, PartialEq, Eq)]
23pub struct Token {
24 pub kind: u64,
26 pub value: Vec<u8>,
28}
29
30impl Token {
31 pub const OUT_OF_BAND: u64 = 0x0;
33 pub const CAT: u64 = 0x1;
35}
36
37#[derive(Debug, Clone)]
39pub(crate) struct Setup {
40 pub parameters: Bytes,
41}
42
43impl Setup {
44 fn check_version(v: Version) {
45 match v {
46 Version::Ietf(ietf::Version::Draft14 | ietf::Version::Draft15 | ietf::Version::Draft16)
47 | Version::Lite(_) => unreachable!("Setup is draft-17+ only"),
48 _ => {}
49 }
50 }
51}
52
53impl Encode<Version> for Setup {
54 fn encode<W: bytes::BufMut>(&self, w: &mut W, v: Version) -> Result<(), EncodeError> {
55 Self::check_version(v);
56 SETUP_V17.encode(w, v)?;
57 u16::try_from(self.parameters.len())
58 .map_err(|_| EncodeError::TooLarge)?
59 .encode(w, v)?;
60 if w.remaining_mut() < self.parameters.len() {
61 return Err(EncodeError::Short);
62 }
63 w.put_slice(&self.parameters);
64 Ok(())
65 }
66}
67
68impl Decode<Version> for Setup {
69 fn decode<R: bytes::Buf>(r: &mut R, v: Version) -> Result<Self, DecodeError> {
70 Self::check_version(v);
71 let kind = u64::decode(r, v)?;
72 if kind != SETUP_V17 {
73 return Err(DecodeError::InvalidValue);
74 }
75 let size = u16::decode(r, v)? as usize;
76 if r.remaining() < size {
77 return Err(DecodeError::Short);
78 }
79 let msg = r.copy_to_bytes(size);
80 Ok(Self { parameters: msg })
81 }
82}
83
84#[derive(Clone, Copy, Debug, PartialEq, Eq)]
85enum SetupVersion {
86 Draft14,
87 Draft15Plus,
88 Modern,
90 LiteLegacy,
91 Unsupported,
92}
93
94impl SetupVersion {
95 fn from_version(v: Version) -> Self {
96 match v {
97 Version::Ietf(ietf::Version::Draft14) => Self::Draft14,
98 Version::Ietf(ietf::Version::Draft15) | Version::Ietf(ietf::Version::Draft16) => Self::Draft15Plus,
99 Version::Ietf(ietf::Version::Draft17)
100 | Version::Ietf(ietf::Version::Draft18)
101 | Version::Ietf(ietf::Version::Draft19)
102 | Version::Ietf(ietf::Version::Draft20)
103 | Version::Ietf(ietf::Version::Draft21)
104 | Version::Ietf(ietf::Version::Draft22) => Self::Modern,
105 Version::Lite(lite::Version::Lite01) | Version::Lite(lite::Version::Lite02) => Self::LiteLegacy,
106 Version::Lite(_) => Self::Unsupported,
107 }
108 }
109}
110
111#[derive(Debug, Clone)]
113pub(crate) struct Client {
114 pub versions: coding::Versions,
116
117 pub parameters: Bytes,
119}
120
121impl Client {
122 fn encode_inner<W: bytes::BufMut>(&self, w: &mut W, v: Version) -> Result<(), EncodeError> {
123 match SetupVersion::from_version(v) {
124 SetupVersion::Draft15Plus => {
125 }
127 SetupVersion::Draft14 | SetupVersion::LiteLegacy => self.versions.encode(w, v)?,
128 SetupVersion::Modern | SetupVersion::Unsupported => return Err(EncodeError::Version),
129 };
130 if w.remaining_mut() < self.parameters.len() {
131 return Err(EncodeError::Short);
132 }
133 w.put_slice(&self.parameters);
134 Ok(())
135 }
136}
137
138impl Decode<Version> for Client {
139 fn decode<R: bytes::Buf>(r: &mut R, v: Version) -> Result<Self, DecodeError> {
141 let kind = u8::decode(r, v)?;
142 if kind != CLIENT_SETUP {
143 return Err(DecodeError::InvalidValue);
144 }
145
146 let size = match SetupVersion::from_version(v) {
147 SetupVersion::Draft14 | SetupVersion::Draft15Plus => u16::decode(r, v)? as usize,
148 SetupVersion::LiteLegacy => u64::decode(r, v)? as usize,
149 SetupVersion::Modern | SetupVersion::Unsupported => return Err(DecodeError::Version),
150 };
151
152 if r.remaining() < size {
153 return Err(DecodeError::Short);
154 }
155
156 let mut msg = r.copy_to_bytes(size);
157
158 let versions = match SetupVersion::from_version(v) {
159 SetupVersion::Draft15Plus => {
160 coding::Versions::from([v.into()])
162 }
163 SetupVersion::Draft14 | SetupVersion::LiteLegacy => coding::Versions::decode(&mut msg, v)?,
164 SetupVersion::Modern | SetupVersion::Unsupported => return Err(DecodeError::Version),
165 };
166
167 Ok(Self {
168 versions,
169 parameters: msg,
170 })
171 }
172}
173
174impl Encode<Version> for Client {
175 fn encode<W: bytes::BufMut>(&self, w: &mut W, v: Version) -> Result<(), EncodeError> {
177 CLIENT_SETUP.encode(w, v)?;
178
179 let mut sizer = Sizer::default();
180 self.encode_inner(&mut sizer, v)?;
181 let size = sizer.size;
182
183 match SetupVersion::from_version(v) {
184 SetupVersion::Draft14 | SetupVersion::Draft15Plus => {
185 u16::try_from(size).map_err(|_| EncodeError::TooLarge)?.encode(w, v)?;
186 }
187 SetupVersion::LiteLegacy => (size as u64).encode(w, v)?,
188 SetupVersion::Modern | SetupVersion::Unsupported => return Err(EncodeError::Version),
189 }
190 self.encode_inner(w, v)
191 }
192}
193
194#[derive(Debug, Clone)]
196pub(crate) struct Server {
197 pub version: coding::Version,
199
200 pub parameters: Bytes,
202}
203
204impl Server {
205 fn encode_inner<W: bytes::BufMut>(&self, w: &mut W, v: Version) -> Result<(), EncodeError> {
206 match SetupVersion::from_version(v) {
207 SetupVersion::Draft15Plus => {
208 }
210 SetupVersion::Draft14 | SetupVersion::LiteLegacy => self.version.encode(w, v)?,
211 SetupVersion::Modern | SetupVersion::Unsupported => return Err(EncodeError::Version),
212 };
213 if w.remaining_mut() < self.parameters.len() {
214 return Err(EncodeError::Short);
215 }
216 w.put_slice(&self.parameters);
217 Ok(())
218 }
219}
220
221impl Encode<Version> for Server {
222 fn encode<W: bytes::BufMut>(&self, w: &mut W, v: Version) -> Result<(), EncodeError> {
224 SERVER_SETUP.encode(w, v)?;
225
226 let mut sizer = Sizer::default();
227 self.encode_inner(&mut sizer, v)?;
228 let size = sizer.size;
229
230 match SetupVersion::from_version(v) {
231 SetupVersion::Draft14 | SetupVersion::Draft15Plus => {
232 u16::try_from(size).map_err(|_| EncodeError::TooLarge)?.encode(w, v)?;
233 }
234 SetupVersion::LiteLegacy => (size as u64).encode(w, v)?,
235 SetupVersion::Modern | SetupVersion::Unsupported => return Err(EncodeError::Version),
236 }
237
238 self.encode_inner(w, v)
239 }
240}
241
242impl Decode<Version> for Server {
243 fn decode<R: bytes::Buf>(r: &mut R, v: Version) -> Result<Self, DecodeError> {
245 let kind = u8::decode(r, v)?;
246 if kind != SERVER_SETUP {
247 return Err(DecodeError::InvalidValue);
248 }
249
250 let size = match SetupVersion::from_version(v) {
251 SetupVersion::Draft14 | SetupVersion::Draft15Plus => u16::decode(r, v)? as usize,
252 SetupVersion::LiteLegacy => u64::decode(r, v)? as usize,
253 SetupVersion::Modern | SetupVersion::Unsupported => return Err(DecodeError::Version),
254 };
255
256 if r.remaining() < size {
257 return Err(DecodeError::Short);
258 }
259
260 let mut msg = r.copy_to_bytes(size);
261 let version = match SetupVersion::from_version(v) {
262 SetupVersion::Draft15Plus => v.into(),
263 SetupVersion::Draft14 | SetupVersion::LiteLegacy => coding::Version::decode(&mut msg, v)?,
264 SetupVersion::Modern | SetupVersion::Unsupported => return Err(DecodeError::Version),
265 };
266
267 Ok(Self {
268 version,
269 parameters: msg,
270 })
271 }
272}