1use std::collections::HashMap;
4
5use byteorder::{ByteOrder, NetworkEndian};
6use pallas_codec::{Fragment, minicbor};
7use thiserror::Error;
8use tokio::io::{AsyncReadExt, AsyncWriteExt};
9use tokio::task::JoinHandle;
10use tokio::time::Instant;
11use tokio::{select, sync::mpsc::error::SendError};
12use tracing::{debug, error, trace, warn};
13
14type IOResult<T> = tokio::io::Result<T>;
15
16use tokio::net as tcp;
17
18#[cfg(unix)]
19use tokio::net as unix;
20
21#[cfg(windows)]
22use tokio::net::windows::named_pipe::NamedPipeClient;
23
24#[cfg(windows)]
25use tokio::io::{ReadHalf, WriteHalf};
26
27const HEADER_LEN: usize = 8;
28
29pub type Timestamp = u32;
31
32pub type Payload = Vec<u8>;
34
35pub type Protocol = u16;
37
38#[derive(Debug)]
40pub struct Header {
41 pub protocol: Protocol,
43 pub timestamp: Timestamp,
45 pub payload_len: u16,
47}
48
49impl From<&[u8]> for Header {
50 fn from(value: &[u8]) -> Self {
51 let timestamp = NetworkEndian::read_u32(&value[0..4]);
52 let protocol = NetworkEndian::read_u16(&value[4..6]);
53 let payload_len = NetworkEndian::read_u16(&value[6..8]);
54
55 Self {
56 timestamp,
57 protocol,
58 payload_len,
59 }
60 }
61}
62
63impl From<Header> for [u8; 8] {
64 fn from(value: Header) -> Self {
65 let mut out = [0u8; 8];
66 NetworkEndian::write_u32(&mut out[0..4], value.timestamp);
67 NetworkEndian::write_u16(&mut out[4..6], value.protocol);
68 NetworkEndian::write_u16(&mut out[6..8], value.payload_len);
69
70 out
71 }
72}
73
74pub struct Segment {
76 pub header: Header,
78 pub payload: Payload,
80}
81
82pub enum Bearer {
84 Tcp(tcp::TcpStream),
86
87 #[cfg(unix)]
89 Unix(unix::UnixStream),
90
91 #[cfg(windows)]
93 NamedPipe(NamedPipeClient),
94}
95
96impl Bearer {
97 fn configure_tcp(stream: &tcp::TcpStream) -> IOResult<()> {
98 let sock_ref = socket2::SockRef::from(&stream);
99 let mut tcp_keepalive = socket2::TcpKeepalive::new();
100 tcp_keepalive = tcp_keepalive.with_time(tokio::time::Duration::from_secs(20));
101 tcp_keepalive = tcp_keepalive.with_interval(tokio::time::Duration::from_secs(20));
102 sock_ref.set_tcp_keepalive(&tcp_keepalive)?;
103 sock_ref.set_tcp_nodelay(true)?;
104 sock_ref.set_linger(Some(std::time::Duration::from_secs(0)))?;
105
106 Ok(())
107 }
108
109 pub async fn connect_tcp(addr: impl tcp::ToSocketAddrs) -> Result<Self, tokio::io::Error> {
112 let stream = tcp::TcpStream::connect(addr).await?;
113 Self::configure_tcp(&stream)?;
114 Ok(Self::Tcp(stream))
115 }
116
117 pub async fn connect_tcp_timeout(
119 addr: impl tcp::ToSocketAddrs,
120 timeout: std::time::Duration,
121 ) -> IOResult<Self> {
122 select! {
123 result = Self::connect_tcp(addr) => result,
124 _ = tokio::time::sleep(timeout) => Err(tokio::io::Error::new(tokio::io::ErrorKind::TimedOut, "connect timeout")),
125 }
126 }
127
128 pub async fn accept_tcp(listener: &tcp::TcpListener) -> IOResult<(Self, std::net::SocketAddr)> {
130 let (stream, addr) = listener.accept().await?;
131 Self::configure_tcp(&stream)?;
132 Ok((Self::Tcp(stream), addr))
133 }
134
135 #[cfg(unix)]
137 pub async fn connect_unix(path: impl AsRef<std::path::Path>) -> IOResult<Self> {
138 let stream = unix::UnixStream::connect(path).await?;
139 Ok(Self::Unix(stream))
140 }
141
142 #[cfg(unix)]
144 pub async fn accept_unix(
145 listener: &unix::UnixListener,
146 ) -> IOResult<(Self, unix::unix::SocketAddr)> {
147 let (stream, addr) = listener.accept().await?;
148 Ok((Self::Unix(stream), addr))
149 }
150
151 #[cfg(windows)]
153 pub fn connect_named_pipe(pipe_name: impl AsRef<std::ffi::OsStr>) -> IOResult<Self> {
154 let client = tokio::net::windows::named_pipe::ClientOptions::new().open(&pipe_name)?;
155 Ok(Self::NamedPipe(client))
156 }
157
158 pub fn into_split(self) -> (BearerReadHalf, BearerWriteHalf) {
160 match self {
161 Bearer::Tcp(x) => {
162 let (r, w) = x.into_split();
163 (BearerReadHalf::Tcp(r), BearerWriteHalf::Tcp(w))
164 }
165
166 #[cfg(unix)]
167 Bearer::Unix(x) => {
168 let (r, w) = x.into_split();
169 (BearerReadHalf::Unix(r), BearerWriteHalf::Unix(w))
170 }
171
172 #[cfg(windows)]
173 Bearer::NamedPipe(x) => {
174 let (read, write) = tokio::io::split(x);
175 let reader = BearerReadHalf::NamedPipe(read);
176 let writer = BearerWriteHalf::NamedPipe(write);
177
178 (reader, writer)
179 }
180 }
181 }
182}
183
184pub enum BearerReadHalf {
186 Tcp(tcp::tcp::OwnedReadHalf),
188
189 #[cfg(unix)]
191 Unix(unix::unix::OwnedReadHalf),
192
193 #[cfg(windows)]
195 NamedPipe(ReadHalf<NamedPipeClient>),
196}
197
198impl BearerReadHalf {
199 async fn read_exact(&mut self, buf: &mut [u8]) -> IOResult<usize> {
200 match self {
201 BearerReadHalf::Tcp(x) => x.read_exact(buf).await,
202
203 #[cfg(unix)]
204 BearerReadHalf::Unix(x) => x.read_exact(buf).await,
205
206 #[cfg(windows)]
207 BearerReadHalf::NamedPipe(x) => x.read_exact(buf).await,
208 }
209 }
210}
211
212pub enum BearerWriteHalf {
214 Tcp(tcp::tcp::OwnedWriteHalf),
216
217 #[cfg(unix)]
219 Unix(unix::unix::OwnedWriteHalf),
220
221 #[cfg(windows)]
223 NamedPipe(WriteHalf<NamedPipeClient>),
224}
225
226impl BearerWriteHalf {
227 async fn write_all(&mut self, buf: &[u8]) -> IOResult<()> {
228 match self {
229 Self::Tcp(x) => x.write_all(buf).await,
230
231 #[cfg(unix)]
232 Self::Unix(x) => x.write_all(buf).await,
233
234 #[cfg(windows)]
235 Self::NamedPipe(x) => x.write_all(buf).await,
236 }
237 }
238
239 async fn flush(&mut self) -> IOResult<()> {
240 match self {
241 Self::Tcp(x) => x.flush().await,
242
243 #[cfg(unix)]
244 Self::Unix(x) => x.flush().await,
245
246 #[cfg(windows)]
247 Self::NamedPipe(x) => x.flush().await,
248 }
249 }
250}
251
252#[derive(Debug, Error)]
254pub enum Error {
255 #[error("no data available in bearer to complete segment")]
257 EmptyBearer,
258
259 #[error("bearer I/O error")]
261 BearerIo(tokio::io::Error),
262
263 #[error("failure to encode channel message")]
265 Decoding(String),
266
267 #[error("failure to decode channel message")]
269 Encoding(String),
270
271 #[error("agent failed to enqueue chunk for protocol {0}")]
273 AgentEnqueue(Protocol, Payload),
274
275 #[error("agent failed to dequeue chunk")]
277 AgentDequeue,
278
279 #[error("plexer failed to dumux chunk for protocol {0}")]
281 PlexerDemux(Protocol, Payload),
282
283 #[error("plexer failed to mux chunk")]
285 PlexerMux,
286
287 #[error("failure to abort the plexer threads")]
289 AbortFailure,
290}
291
292type EgressChannel = tokio::sync::mpsc::Sender<Payload>;
293type Egress = HashMap<Protocol, EgressChannel>;
294
295const EGRESS_MSG_QUEUE_BUFFER: usize = 100;
296
297pub struct Demuxer(BearerReadHalf, Egress);
299
300impl Demuxer {
301 pub fn new(bearer: BearerReadHalf) -> Self {
303 let egress = HashMap::new();
304 Self(bearer, egress)
305 }
306
307 pub async fn read_segment(&mut self) -> Result<(Protocol, Payload), Error> {
309 trace!("waiting for segment header");
310 let mut buf = vec![0u8; HEADER_LEN];
311 self.0.read_exact(&mut buf).await.map_err(Error::BearerIo)?;
312 let header = Header::from(buf.as_slice());
313
314 trace!("waiting for full segment");
315 let segment_size = header.payload_len as usize;
316 let mut buf = vec![0u8; segment_size];
317 self.0.read_exact(&mut buf).await.map_err(Error::BearerIo)?;
318
319 Ok((header.protocol, buf))
320 }
321
322 async fn demux(&mut self, protocol: Protocol, payload: Payload) -> Result<(), Error> {
323 let channel = self.1.get(&protocol);
324
325 if let Some(sender) = channel {
326 sender
327 .send(payload)
328 .await
329 .map_err(|err| Error::PlexerDemux(protocol, err.0))?;
330 } else {
331 warn!(protocol, "message for unregistered protocol");
332 }
333
334 Ok(())
335 }
336
337 pub fn subscribe(&mut self, protocol: Protocol) -> tokio::sync::mpsc::Receiver<Payload> {
340 let (sender, recv) = tokio::sync::mpsc::channel(EGRESS_MSG_QUEUE_BUFFER);
341
342 self.1.insert(protocol, sender);
344
345 recv
347 }
348
349 pub async fn tick(&mut self) -> Result<(), Error> {
351 let (protocol, payload) = self.read_segment().await?;
352 trace!(protocol, "demux happening");
353 self.demux(protocol, payload).await
354 }
355
356 pub async fn run(&mut self) -> Result<(), Error> {
358 loop {
359 if let Err(err) = self.tick().await {
360 break Err(err);
361 }
362 }
363 }
364}
365
366type Ingress = (
367 tokio::sync::mpsc::Sender<(Protocol, Payload)>,
368 tokio::sync::mpsc::Receiver<(Protocol, Payload)>,
369);
370
371type Clock = Instant;
372
373const INGRESS_MSG_QUEUE_BUFFER: usize = 100;
374
375pub struct Muxer(BearerWriteHalf, Clock, Ingress);
377
378impl Muxer {
379 pub fn new(bearer: BearerWriteHalf) -> Self {
381 let ingress = tokio::sync::mpsc::channel(INGRESS_MSG_QUEUE_BUFFER);
382 let clock = Instant::now();
383 Self(bearer, clock, ingress)
384 }
385
386 async fn write_segment(&mut self, protocol: u16, payload: &[u8]) -> Result<(), std::io::Error> {
387 let header = Header {
388 protocol,
389 timestamp: self.1.elapsed().as_micros() as u32,
390 payload_len: payload.len() as u16,
391 };
392
393 let buf: [u8; 8] = header.into();
394 self.0.write_all(&buf).await?;
395 self.0.write_all(payload).await?;
396
397 self.0.flush().await?;
398
399 Ok(())
400 }
401
402 pub async fn mux(&mut self, msg: (Protocol, Payload)) -> Result<(), Error> {
404 self.write_segment(msg.0, &msg.1)
405 .await
406 .map_err(|_| Error::PlexerMux)?;
407
408 if tracing::event_enabled!(tracing::Level::TRACE) {
409 trace!(
410 protocol = msg.0,
411 data = hex::encode(&msg.1),
412 "write to bearer"
413 );
414 }
415
416 Ok(())
417 }
418
419 pub fn clone_sender(&self) -> tokio::sync::mpsc::Sender<(Protocol, Payload)> {
421 self.2.0.clone()
422 }
423
424 pub async fn tick(&mut self) -> Result<(), Error> {
426 let msg = self.2.1.recv().await;
427
428 if let Some(x) = msg {
429 trace!(protocol = x.0, "mux happening");
430 self.mux(x).await?
431 }
432
433 Ok(())
434 }
435
436 pub async fn run(&mut self) -> Result<(), Error> {
438 loop {
439 if let Err(err) = self.tick().await {
440 break Err(err);
441 }
442 }
443 }
444}
445
446type ToPlexerPort = tokio::sync::mpsc::Sender<(Protocol, Payload)>;
447type FromPlexerPort = tokio::sync::mpsc::Receiver<Payload>;
448
449pub struct AgentChannel {
452 protocol: Protocol,
453 to_plexer: ToPlexerPort,
454 from_plexer: FromPlexerPort,
455}
456
457impl AgentChannel {
458 fn for_client(
459 protocol: Protocol,
460 to_plexer: ToPlexerPort,
461 from_plexer: FromPlexerPort,
462 ) -> Self {
463 Self {
464 protocol,
465 from_plexer,
466 to_plexer,
467 }
468 }
469
470 fn for_server(
471 protocol: Protocol,
472 to_plexer: ToPlexerPort,
473 from_plexer: FromPlexerPort,
474 ) -> Self {
475 Self {
476 protocol,
477 from_plexer,
478 to_plexer,
479 }
480 }
481
482 pub async fn enqueue_chunk(&mut self, chunk: Payload) -> Result<(), Error> {
484 self.to_plexer
485 .send((self.protocol, chunk))
486 .await
487 .map_err(|SendError((protocol, payload))| Error::AgentEnqueue(protocol, payload))
488 }
489
490 pub async fn dequeue_chunk(&mut self) -> Result<Payload, Error> {
492 self.from_plexer.recv().await.ok_or(Error::AgentDequeue)
493 }
494}
495
496pub struct RunningPlexer {
498 demuxer: JoinHandle<Result<(), Error>>,
499 muxer: JoinHandle<Result<(), Error>>,
500}
501
502impl RunningPlexer {
503 pub async fn abort(self) {
505 self.demuxer.abort();
506 self.muxer.abort();
507 }
508}
509
510pub struct Plexer {
512 demuxer: Demuxer,
513 muxer: Muxer,
514}
515
516impl Plexer {
517 pub fn new(bearer: Bearer) -> Self {
519 let (r, w) = bearer.into_split();
520
521 Self {
522 demuxer: Demuxer::new(r),
523 muxer: Muxer::new(w),
524 }
525 }
526
527 pub fn subscribe_client(&mut self, protocol: Protocol) -> AgentChannel {
529 let to_plexer = self.muxer.clone_sender();
530 let from_plexer = self.demuxer.subscribe(protocol ^ 0x8000);
531 AgentChannel::for_client(protocol, to_plexer, from_plexer)
532 }
533
534 pub fn subscribe_server(&mut self, protocol: Protocol) -> AgentChannel {
536 let to_plexer = self.muxer.clone_sender();
537 let from_plexer = self.demuxer.subscribe(protocol);
538 AgentChannel::for_server(protocol ^ 0x8000, to_plexer, from_plexer)
539 }
540
541 pub fn spawn(self) -> RunningPlexer {
544 let mut demuxer = self.demuxer;
545 let mut muxer = self.muxer;
546
547 let demuxer = tokio::spawn(async move { demuxer.run().await });
548 let muxer = tokio::spawn(async move { muxer.run().await });
549
550 RunningPlexer { demuxer, muxer }
551 }
552}
553
554pub const MAX_SEGMENT_PAYLOAD_LENGTH: usize = 65535;
556
557fn try_decode_message<M>(buffer: &mut Vec<u8>) -> Result<Option<M>, Error>
558where
559 M: Fragment,
560{
561 let mut decoder = minicbor::Decoder::new(buffer);
562 let maybe_msg = decoder.decode();
563
564 match maybe_msg {
565 Ok(msg) => {
566 let pos = decoder.position();
567 buffer.drain(0..pos);
568 Ok(Some(msg))
569 }
570 Err(err) if err.is_end_of_input() => Ok(None),
571 Err(err) => {
572 error!(?err);
573 trace!("{}", hex::encode(buffer));
574 Err(Error::Decoding(err.to_string()))
575 }
576 }
577}
578
579pub struct ChannelBuffer {
581 channel: AgentChannel,
582 temp: Vec<u8>,
583}
584
585impl ChannelBuffer {
586 pub fn new(channel: AgentChannel) -> Self {
588 Self {
589 channel,
590 temp: Vec::new(),
591 }
592 }
593
594 pub async fn send_msg_chunks<M>(&mut self, msg: &M) -> Result<(), Error>
596 where
597 M: Fragment,
598 {
599 let mut payload = Vec::new();
600 minicbor::encode(msg, &mut payload).map_err(|err| Error::Encoding(err.to_string()))?;
601
602 let chunks = payload.chunks(MAX_SEGMENT_PAYLOAD_LENGTH);
603
604 for chunk in chunks {
605 self.channel.enqueue_chunk(Vec::from(chunk)).await?;
606 }
607
608 Ok(())
609 }
610
611 pub async fn recv_full_msg<M>(&mut self) -> Result<M, Error>
613 where
614 M: Fragment,
615 {
616 trace!(len = self.temp.len(), "waiting for full message");
617
618 if !self.temp.is_empty() {
619 trace!("buffer has data from previous payload");
620
621 if let Some(msg) = try_decode_message::<M>(&mut self.temp)? {
622 debug!("decoding done");
623 return Ok(msg);
624 }
625 }
626
627 loop {
628 let chunk = self.channel.dequeue_chunk().await?;
629 self.temp.extend(chunk);
630
631 if let Some(msg) = try_decode_message::<M>(&mut self.temp)? {
632 debug!("decoding done");
633 return Ok(msg);
634 }
635
636 trace!("not enough data");
637 }
638 }
639
640 pub fn unwrap(self) -> AgentChannel {
642 self.channel
643 }
644}
645
646impl From<AgentChannel> for ChannelBuffer {
647 fn from(channel: AgentChannel) -> Self {
648 ChannelBuffer::new(channel)
649 }
650}
651
652#[cfg(test)]
653mod tests {
654 use super::*;
655 use pallas_codec::minicbor;
656
657 #[tokio::test]
658 async fn multiple_messages_in_same_payload() {
659 let mut input = Vec::new();
660 let in_part1 = (1u8, 2u8, 3u8);
661 let in_part2 = (6u8, 5u8, 4u8);
662
663 minicbor::encode(in_part1, &mut input).unwrap();
664 minicbor::encode(in_part2, &mut input).unwrap();
665
666 let (to_plexer, _) = tokio::sync::mpsc::channel(100);
667 let (into_plexer, from_plexer) = tokio::sync::mpsc::channel(100);
668
669 let channel = AgentChannel::for_client(0, to_plexer, from_plexer);
670
671 into_plexer.send(input).await.unwrap();
672
673 let mut buf = ChannelBuffer::new(channel);
674
675 let out_part1 = buf.recv_full_msg::<(u8, u8, u8)>().await.unwrap();
676 let out_part2 = buf.recv_full_msg::<(u8, u8, u8)>().await.unwrap();
677
678 assert_eq!(in_part1, out_part1);
679 assert_eq!(in_part2, out_part2);
680 }
681
682 #[tokio::test]
683 async fn fragmented_message_in_multiple_payloads() {
684 let mut input = Vec::new();
685 let msg = (11u8, 12u8, 13u8, 14u8, 15u8, 16u8, 17u8);
686 minicbor::encode(msg, &mut input).unwrap();
687
688 let (to_plexer, _) = tokio::sync::mpsc::channel(100);
689 let (into_plexer, from_plexer) = tokio::sync::mpsc::channel(100);
690
691 let channel = AgentChannel::for_client(0, to_plexer, from_plexer);
692
693 while !input.is_empty() {
694 let chunk = Vec::from(input.drain(0..2).as_slice());
695 into_plexer.send(chunk).await.unwrap();
696 }
697
698 let mut buf = ChannelBuffer::new(channel);
699
700 let out_msg = buf
701 .recv_full_msg::<(u8, u8, u8, u8, u8, u8, u8)>()
702 .await
703 .unwrap();
704
705 assert_eq!(msg, out_msg);
706 }
707}