1use std::io;
9
10use borsh::{BorshDeserialize, BorshSerialize};
11use num_enum::{IntoPrimitive, TryFromPrimitive};
12
13use crate::topic;
14
15#[derive(Clone, Debug)]
16pub struct Frame {
17 header: FrameHeader,
18 body: FrameBody,
19}
20
21impl Frame {
22 pub fn with_body(body: FrameBody) -> Self {
23 Self {
24 header: FrameHeader {
25 flags: 0,
27 },
28 body,
29 }
30 }
31
32 pub fn body(&self) -> &FrameBody {
34 &self.body
35 }
36
37 pub fn ty(&self) -> FrameType {
39 self.body.ty()
40 }
41}
42
43#[derive(Clone, Debug)]
44pub struct FrameHeader {
45 flags: u16,
46}
47
48#[derive(Copy, Clone, Debug, Eq, PartialEq, BorshDeserialize, BorshSerialize)]
50pub struct MsgFlags {
51 pub close: bool,
54
55 pub err: bool,
57}
58
59impl MsgFlags {
60 pub fn none() -> Self {
62 Self {
63 close: false,
64 err: false,
65 }
66 }
67
68 pub fn close() -> Self {
70 let mut this = Self::default();
71 this.close = true;
72 this
73 }
74
75 pub fn with_close(close: bool) -> Self {
77 Self { close, err: false }
78 }
79}
80
81impl Default for MsgFlags {
82 fn default() -> Self {
83 Self::none()
84 }
85}
86
87#[derive(Copy, Clone, Debug, Eq, PartialEq, IntoPrimitive, TryFromPrimitive)]
88#[repr(u8)]
89pub enum FrameType {
90 ClientHello = 0,
92
93 ServerHello = 1,
95
96 ClientFinish = 2,
98
99 OpenChan = 3,
101
102 PushChan = 4,
104
105 CloseChan = 5,
107
108 Notification = 6,
113
114 Goodbye = 7,
116
117 ClientQuery = 16,
119
120 ServerDump = 17,
122
123 Ping = 252,
125
126 Pong = 253,
128}
129
130#[derive(Clone, Debug, BorshDeserialize, BorshSerialize)]
132pub enum FrameBody {
133 ClientHello(ClientHelloData),
134 ServerHello(ServerHelloData),
135 ClientFinish(ClientFinishData),
136 OpenChan(OpenData),
137 PushChan(PushData),
138 CloseChan(CloseData),
139 Notification(NotificationData),
140 Goodbye(GoodbyeData),
141 ClientQuery(ClientQueryData),
142 ServerDump(ServerDumpData),
143 Ping(Vec<u8>),
144 Pong(Vec<u8>),
145}
146
147impl FrameBody {
148 pub fn from_buf(buf: &[u8]) -> Result<Self, io::Error> {
150 borsh::from_slice(buf)
151 }
152
153 pub fn into_vec(&self, dest: &mut Vec<u8>) -> Result<(), io::Error> {
155 borsh::to_writer(dest, self)
156 }
157
158 pub fn to_vec(&self) -> Result<Vec<u8>, io::Error> {
160 borsh::to_vec(self)
161 }
162
163 pub fn ty(&self) -> FrameType {
164 match self {
165 Self::ClientHello(_) => FrameType::ClientHello,
166 Self::ServerHello(_) => FrameType::ServerHello,
167 Self::ClientFinish(_) => FrameType::ClientFinish,
168 Self::OpenChan(_) => FrameType::OpenChan,
169 Self::PushChan(_) => FrameType::PushChan,
170 Self::CloseChan(_) => FrameType::CloseChan,
171 Self::Notification(_) => FrameType::Notification,
172 Self::Goodbye(_) => FrameType::Goodbye,
173 Self::ClientQuery(_) => FrameType::ClientQuery,
174 Self::ServerDump(_) => FrameType::ServerDump,
175 Self::Ping(_) => FrameType::Ping,
176 Self::Pong(_) => FrameType::Pong,
177 }
178 }
179}
180
181#[derive(Clone, Debug, BorshDeserialize, BorshSerialize)]
184pub struct ClientHelloData {
185 agent: String,
187
188 protocol: topic::Topic,
190
191 server_challenge: Option<ChallengeData>,
194}
195
196impl ClientHelloData {
197 pub fn new(
198 agent: String,
199 protocol: topic::Topic,
200 server_challenge: Option<ChallengeData>,
201 ) -> Self {
202 Self {
203 agent,
204 protocol,
205 server_challenge,
206 }
207 }
208
209 pub fn agent(&self) -> &str {
210 &self.agent
211 }
212
213 pub fn protocol(&self) -> topic::Topic {
214 self.protocol
215 }
216
217 pub fn challenge(&self) -> Option<&ChallengeData> {
218 self.server_challenge.as_ref()
219 }
220}
221
222#[derive(Clone, Debug, BorshDeserialize, BorshSerialize)]
225pub struct ServerHelloData {
226 agent: String,
228
229 response: Option<ResponseData>,
231
232 challenge: Option<ChallengeData>,
234}
235
236impl ServerHelloData {
237 pub fn new(
238 agent: String,
239 response: Option<ResponseData>,
240 challenge: Option<ChallengeData>,
241 ) -> Self {
242 Self {
243 agent,
244 response,
245 challenge,
246 }
247 }
248
249 pub fn agent(&self) -> &str {
250 &self.agent
251 }
252
253 pub fn response(&self) -> Option<&ResponseData> {
254 self.response.as_ref()
255 }
256
257 pub fn challenge(&self) -> Option<&ChallengeData> {
258 self.challenge.as_ref()
259 }
260}
261
262#[derive(Clone, Debug, BorshDeserialize, BorshSerialize)]
265pub struct ClientFinishData {
266 response: Option<ResponseData>,
267}
268
269impl ClientFinishData {
270 pub fn new(response: Option<ResponseData>) -> Self {
271 Self { response }
272 }
273
274 pub fn response(&self) -> Option<&ResponseData> {
275 self.response.as_ref()
276 }
277}
278
279#[derive(Clone, Debug, BorshDeserialize, BorshSerialize)]
281pub struct OpenData {
282 topic: topic::Topic,
284
285 flags: MsgFlags,
287
288 payload: Vec<u8>,
290}
291
292impl OpenData {
293 pub fn new(topic: topic::Topic, flags: MsgFlags, payload: Vec<u8>) -> Self {
294 Self {
295 topic,
296 flags,
297 payload,
298 }
299 }
300
301 pub fn topic(&self) -> topic::Topic {
302 self.topic
303 }
304
305 pub fn flags(&self) -> &MsgFlags {
306 &self.flags
307 }
308
309 pub fn close(&self) -> bool {
310 self.flags.close
311 }
312
313 pub fn payload(&self) -> &[u8] {
314 &self.payload
315 }
316
317 pub fn into_payload(self) -> Vec<u8> {
318 self.payload
319 }
320}
321
322#[derive(Clone, Debug, BorshDeserialize, BorshSerialize)]
324pub struct PushData {
325 chan_id: u32,
327
328 flags: MsgFlags,
330
331 payload: Vec<u8>,
333}
334
335impl PushData {
336 pub fn new(chan_id: u32, flags: MsgFlags, payload: Vec<u8>) -> Self {
337 Self {
338 chan_id,
339 flags,
340 payload,
341 }
342 }
343
344 pub fn chan_id(&self) -> u32 {
345 self.chan_id
346 }
347
348 pub fn flags(&self) -> &MsgFlags {
349 &self.flags
350 }
351
352 pub fn close(&self) -> bool {
353 self.flags.close
354 }
355
356 pub fn payload(&self) -> &[u8] {
357 &self.payload
358 }
359
360 pub fn into_payload(self) -> Vec<u8> {
361 self.payload
362 }
363}
364
365#[derive(Clone, Debug, BorshDeserialize, BorshSerialize)]
366pub struct CloseData {
367 chan_id: u32,
368}
369
370impl CloseData {
371 pub fn new(chan_id: u32) -> Self {
372 Self { chan_id }
373 }
374
375 pub fn chan_id(&self) -> u32 {
376 self.chan_id
377 }
378}
379
380#[derive(Clone, Debug, BorshDeserialize, BorshSerialize)]
381pub struct NotificationData {
382 topic: topic::Topic,
383 payload: Vec<u8>,
384}
385
386impl NotificationData {
387 pub fn new(topic: topic::Topic, payload: Vec<u8>) -> Self {
388 Self { topic, payload }
389 }
390
391 pub fn topic(&self) -> topic::Topic {
392 self.topic
393 }
394
395 pub fn payload(&self) -> &[u8] {
396 &self.payload
397 }
398
399 pub fn into_payload(self) -> Vec<u8> {
400 self.payload
401 }
402}
403
404#[derive(Clone, Debug, BorshDeserialize, BorshSerialize)]
406pub struct GoodbyeData {
407 code: i16,
409
410 msg: String,
412}
413
414impl GoodbyeData {
415 pub fn new(code: i16, msg: String) -> Self {
416 Self { code, msg }
417 }
418
419 pub fn code(&self) -> i16 {
420 self.code
421 }
422
423 pub fn msg(&self) -> &str {
424 &self.msg
425 }
426}
427
428#[derive(Copy, Clone, Debug, BorshDeserialize, BorshSerialize)]
431pub struct ChallengeData {
432 nonce: [u8; 16],
433}
434
435impl ChallengeData {
436 pub fn from_nonce_buf(nonce: [u8; 16]) -> Self {
437 Self { nonce }
438 }
439
440 pub fn nonce(&self) -> &[u8; 16] {
441 &self.nonce
442 }
443}
444
445#[derive(Clone, Debug, BorshDeserialize, BorshSerialize)]
448pub struct ResponseData {
449 data: Vec<u8>,
450}
451
452impl ResponseData {
453 pub fn new(data: Vec<u8>) -> Self {
454 Self { data }
455 }
456
457 pub fn from_buf(buf: &[u8]) -> Self {
458 Self::new(buf.to_vec())
459 }
460
461 pub fn data(&self) -> &[u8] {
462 &self.data
463 }
464}
465
466#[derive(Clone, Debug, BorshDeserialize, BorshSerialize)]
468pub struct ClientQueryData {
469 agent: String,
471}
472
473impl ClientQueryData {
474 pub fn new(agent: String) -> Self {
475 Self { agent }
476 }
477}
478
479#[derive(Clone, Debug, BorshDeserialize, BorshSerialize)]
481pub struct ServerDumpData {
482 agent: String,
484
485 protocols: Vec<topic::Topic>,
487}
488
489impl ServerDumpData {
490 pub fn new(agent: String, protocols: Vec<topic::Topic>) -> Self {
491 Self { agent, protocols }
492 }
493
494 pub fn agent(&self) -> &str {
495 &self.agent
496 }
497
498 pub fn protocols(&self) -> &[topic::Topic] {
499 &self.protocols
500 }
501}
502
503#[derive(Copy, Clone, Debug, Eq, PartialEq)]
506pub enum Side {
507 Client,
508 Server,
509}
510
511#[derive(Copy, Clone, Debug, Eq, PartialEq)]
514pub enum AuthIntent {
515 Neither,
517
518 ClientOnly,
520
521 ServerOnly,
523
524 Mutual,
526}
527
528impl AuthIntent {
529 pub fn should_sign(&self, side: Side) -> bool {
531 match (self, side) {
532 (Self::ClientOnly | Self::Mutual, Side::Client) => true,
533 (Self::ServerOnly | Self::Mutual, Side::Server) => true,
534 _ => false,
535 }
536 }
537
538 pub fn should_exchange_chals(&self) -> bool {
539 !matches!(self, Self::Neither)
540 }
541}