dope_session/pool/client/
recv.rs1use crate::CodecLayer;
2use crate::protocol::client::ClientProtocol;
3use dope_core::driver::{DriverOps, PoolDriver, ProvidedRingOps};
4use dope_core::profile::Profile;
5use dope_transport::Transport;
6
7use super::super::Pool;
8use super::super::core::RecvDispatch;
9use super::super::slot::ConnFlags;
10use super::Client;
11use super::connect_source::ConnectSource;
12use crate::SlotId;
13
14impl<P, T, S, F, B> super::super::PoolRecv<B> for Pool<Client<P, T, S>, F, B>
15where
16 P: ClientProtocol,
17 T: Transport,
18 T::Addr: Clone,
19 S: ConnectSource<T>,
20 F: Profile,
21 B: PoolDriver,
22{
23 fn on_recv_event(
24 &mut self,
25 driver: &mut B::Driver,
26 token: B::Token,
27 result: i32,
28 more: bool,
29 bid: Option<u16>,
30 ) {
31 match self.core.classify_recv(driver, token, result, more, bid) {
32 RecvDispatch::Skipped => {}
33 RecvDispatch::EofClose { slot_idx } => {
34 self.disconnect_and_free(driver, slot_idx);
35 }
36 RecvDispatch::Errno {
37 slot_idx,
38 errno,
39 more,
40 } => {
41 if errno == libc::ECANCELED {
42 if !more {
43 self.core.slots[slot_idx].io.recv.armed = false;
44 }
45 return;
46 }
47 self.core.slots[slot_idx].io.recv.armed = false;
48 self.disconnect_and_free(driver, slot_idx);
49 }
50 RecvDispatch::Chunk {
51 slot_idx,
52 ptr,
53 len,
54 bid,
55 more,
56 } => {
57 let src: &[u8] = unsafe { std::slice::from_raw_parts(ptr, len) };
58 if <P::CodecLayer as CodecLayer>::IS_PASSTHROUGH {
59 self.ingest_response_bytes(slot_idx, src);
60 } else {
61 self.ingest_codec_responses(driver, slot_idx, src);
62 }
63 driver.provided_ring().defer(bid);
64 if !self.core.slots[slot_idx]
65 .conn
66 .flags
67 .contains(ConnFlags::LIVE)
68 {
69 return;
70 }
71 self.try_submit_outbound(driver, slot_idx);
72 if !more {
73 let _ = self.core.arm_recv(driver, slot_idx);
74 }
75 }
76 RecvDispatch::DrainOnly { slot_idx, more } => {
77 if !more {
78 let _ = self.core.arm_recv(driver, slot_idx);
79 }
80 }
81 }
82 }
83}
84
85impl<P, T, S, F, B> Pool<Client<P, T, S>, F, B>
86where
87 P: ClientProtocol,
88 T: Transport,
89 T::Addr: Clone,
90 S: ConnectSource<T>,
91 F: Profile,
92 B: PoolDriver,
93{
94 #[cold]
95 fn ingest_codec_responses(&mut self, driver: &mut B::Driver, slot_idx: usize, src: &[u8]) {
96 let Some(plaintext) = self.core.process_codec_inbound(driver, slot_idx, src) else {
97 return;
98 };
99 self.ingest_response_bytes(slot_idx, &plaintext);
100 self.core.install_plaintext(slot_idx, plaintext);
101 }
102
103 fn ingest_response_bytes(&mut self, slot_idx: usize, src: &[u8]) {
104 let conn_id =
105 SlotId::from_parts(slot_idx as u32, self.core.slots[slot_idx].conn.generation);
106 let entry = &mut self.core.slots[slot_idx];
107 let user = entry.user.get_mut();
108 let codec_state = entry.codec_state.get_mut();
109 user.session
110 .ingest(src, &mut self.direction.protocol, conn_id, codec_state);
111 }
112}