1use std::collections::VecDeque;
24use std::future::Future;
25use std::pin::Pin;
26use std::sync::{Arc, Mutex, MutexGuard, Weak};
27use std::time::Duration;
28
29use tokio::sync::{watch, Notify};
30
31use crate::cbor::{self, Value};
32use crate::frame::{
33 self, RequestSpec, StreamEncoding, StreamFields, StreamMode, StreamRole, StreamState,
34 VerifiedRequest,
35};
36use crate::seal::KEY_ID_SIZE;
37
38use super::admission::{Admission, SessionPlace, Verdict};
39use super::authorize::authorize;
40use super::confidential::{
41 clear_allowed, opened_request, refused_key, sealed_request, stated, unsealed, Seal, StreamSeal,
42 CODE_SEALED_REFUSED, CODE_SEALED_REQUIRED,
43};
44use super::framing::{read_frame, FrameWriter, MAX_FRAME_BYTES};
45use super::serve::{
46 bounded_detail, without_caller, BoxFuture, Offer, StreamOffer, CODE_REQUEST_COPY,
47};
48use super::{frame_type_of, now_ms, Inner, Link, LinkError};
49
50const STREAM_OPEN_BYTES: usize = 1024 * 1024;
51const STREAM_OPEN_WAIT: Duration = Duration::from_secs(10);
52const STREAM_INBOX: usize = 16 * 1024 * 1024;
53
54pub const DEFAULT_STREAM_DEADLINE: Duration = Duration::from_secs(30);
57
58const CODE_STREAM_NOT_FOUND: &str = "not_found";
61const CODE_MODE_MISMATCH: &str = "mode_mismatch";
62const CODE_TOO_MANY_SESSIONS: &str = "too_many_sessions";
63const CODE_STREAM_HANDLER_ERROR: &str = "error";
64
65pub type StreamHandler = Arc<dyn Fn(Stream) -> BoxFuture<Result<(), String>> + Send + Sync>;
70
71pub fn stream_handler<F, Fut>(f: F) -> StreamHandler
73where
74 F: Fn(Stream) -> Fut + Send + Sync + 'static,
75 Fut: Future<Output = Result<(), String>> + Send + 'static,
76{
77 Arc::new(move |s| Box::pin(f(s)))
78}
79
80#[derive(Debug, Clone, PartialEq)]
86pub struct StreamCall {
87 pub realm: [u8; 32],
88 pub procedure: String,
89 pub target: [u8; 32],
90 pub mode: StreamMode,
91 pub payload: Value,
92 pub deadline: Duration,
93 pub token: Option<Vec<u8>>,
94 pub proofs: Vec<Vec<u8>>,
95 pub seal: Option<Seal>,
96}
97
98impl Default for StreamCall {
99 fn default() -> Self {
100 StreamCall {
101 realm: [0; 32],
102 procedure: String::new(),
103 target: [0; 32],
104 mode: StreamMode::ServerStream,
105 payload: Value::Map(Vec::new()),
106 deadline: Duration::ZERO,
107 token: None,
108 proofs: Vec::new(),
109 seal: None,
110 }
111 }
112}
113
114#[derive(Debug, Clone, PartialEq)]
118pub enum StreamEvent {
119 Data {
120 encoding: StreamEncoding,
121 body: Value,
122 },
123 End {
124 role: StreamRole,
125 },
126 Reply {
127 payload: Value,
128 },
129}
130
131#[derive(Clone)]
133pub struct Stream {
134 pub(super) inner: Arc<StreamInner>,
135}
136
137pub(crate) type Reseal = Box<
142 dyn FnOnce(
143 Option<[u8; KEY_ID_SIZE]>,
144 ) -> Pin<Box<dyn Future<Output = Result<Stream, LinkError>> + Send>>
145 + Send,
146>;
147
148struct Budget {
151 admission: Arc<Admission>,
152 caller: [u8; 32],
153 place: Option<SessionPlace>,
154}
155
156pub(super) struct StreamInner {
157 link: Arc<Inner>,
158 writer: FrameWriter,
159 pub(super) open: VerifiedRequest,
160 pub(super) caller: bool,
161 pub(super) sealing: Option<StreamSeal>,
163 send_seq: tokio::sync::Mutex<u64>,
165 state: Mutex<StreamSide>,
166 budget: Mutex<Option<Budget>>,
167 notify: Notify,
168 done_tx: watch::Sender<bool>,
169 reseal: Mutex<Option<Reseal>>,
171}
172
173#[derive(Default)]
174pub(super) struct StreamSide {
175 reopening: bool,
177 successor: Option<Arc<StreamInner>>,
179 sent_end: bool,
181 peer_ended: bool,
183 inbox: VecDeque<(StreamEvent, usize)>,
184 held: usize,
185 ended: bool,
186 err: Option<LinkError>,
187 pub(super) settled: bool,
189}
190
191impl Stream {
192 pub fn request(&self) -> &VerifiedRequest {
197 &self.inner.open
198 }
199
200 pub fn sealed(&self) -> bool {
203 self.inner.sealing.is_some()
204 }
205
206 pub async fn send(&self, body: &[u8]) -> Result<(), LinkError> {
208 let at = |seq| StreamFields::Data {
209 seq,
210 encoding: StreamEncoding::Raw,
211 body: Value::Bytes(body.to_vec()),
212 };
213 self.sent(at, false).await.1
214 }
215
216 pub async fn send_value(&self, v: Value) -> Result<(), LinkError> {
218 let at = |seq| StreamFields::Data {
219 seq,
220 encoding: StreamEncoding::Msgpack,
221 body: v.clone(),
222 };
223 self.sent(at, false).await.1
224 }
225
226 pub async fn close_send(&self) -> Result<(), LinkError> {
228 let at = |seq| StreamFields::End {
229 seq,
230 role: StreamRole::Send,
231 };
232 self.sent(at, true).await.1
233 }
234
235 pub async fn close(&self) -> Result<(), LinkError> {
237 let at = |seq| StreamFields::End {
238 seq,
239 role: StreamRole::Both,
240 };
241 let (inner, sent) = self.sent(at, true).await;
242 StreamInner::end(&inner, None);
243 sent
244 }
245
246 pub async fn reply(&self, payload: Value) -> Result<(), LinkError> {
248 let at = |seq| StreamFields::Reply {
249 seq,
250 payload: payload.clone(),
251 };
252 let (inner, sent) = self.sent(at, true).await;
253 StreamInner::end(&inner, None);
254 sent
255 }
256
257 pub async fn abort(&self, code: &str, message: &str) -> Result<(), LinkError> {
259 let at = |seq| StreamFields::Error {
260 seq,
261 code: code.to_string(),
262 message: message.to_string(),
263 };
264 let (inner, sent) = self.sent(at, true).await;
265 StreamInner::end(&inner, Some(aborted(code, message)));
266 sent
267 }
268
269 pub async fn recv(&self) -> Result<StreamEvent, LinkError> {
273 loop {
274 let inner = self.live().await;
275 let notified = inner.notify.notified();
276 match inner.next_event() {
277 Some(outcome) => return outcome,
278 None => notified.await,
279 }
280 }
281 }
282
283 pub async fn done(&self) -> Option<LinkError> {
286 let mut inner = self.live().await;
287 while !inner.released().await {
288 inner = self.live().await;
289 }
290 let err = inner.side().err.clone();
291 err
292 }
293
294 async fn sent(
297 &self,
298 at: impl Fn(u64) -> StreamFields,
299 last: bool,
300 ) -> (Arc<StreamInner>, Result<(), LinkError>) {
301 let mut inner = self.live().await;
302 let mut sent = inner.send_here(&at, last).await;
303 while sent.is_none() {
304 inner = self.live().await;
305 sent = inner.send_here(&at, last).await;
306 }
307 (inner, sent.unwrap_or(Err(LinkError::StreamClosed)))
308 }
309
310 async fn live(&self) -> Arc<StreamInner> {
313 let mut at = self.current();
314 while at.side().reopening {
315 at.reopen_awaited().await;
316 at = self.current();
317 }
318 at
319 }
320
321 pub(super) fn current(&self) -> Arc<StreamInner> {
323 let mut at = self.inner.clone();
324 loop {
325 let next = at.side().successor.clone();
326 match next {
327 Some(next) => at = next,
328 None => return at,
329 }
330 }
331 }
332}
333
334fn aborted(code: &str, message: &str) -> LinkError {
336 LinkError::Stream {
337 code: code.to_string(),
338 message: message.to_string(),
339 relay: false,
340 }
341}
342
343impl StreamInner {
344 fn new(
345 link: Arc<Inner>,
346 send: quinn::SendStream,
347 open: VerifiedRequest,
348 caller: bool,
349 sealing: Option<StreamSeal>,
350 ) -> Arc<StreamInner> {
351 Arc::new(StreamInner {
352 link,
353 writer: FrameWriter::new(send),
354 open,
355 caller,
356 sealing,
357 send_seq: tokio::sync::Mutex::new(0),
358 state: Mutex::new(StreamSide::default()),
359 budget: Mutex::new(None),
360 notify: Notify::new(),
361 done_tx: watch::channel(false).0,
362 reseal: Mutex::new(None),
363 })
364 }
365
366 pub(super) fn side(&self) -> MutexGuard<'_, StreamSide> {
367 self.state.lock().unwrap_or_else(|p| p.into_inner())
368 }
369
370 fn budget(&self) -> MutexGuard<'_, Option<Budget>> {
371 self.budget.lock().unwrap_or_else(|p| p.into_inner())
372 }
373
374 fn next_event(&self) -> Option<Result<StreamEvent, LinkError>> {
378 let mut side = self.side();
379 if let Some((event, size)) = side.inbox.pop_front() {
380 side.held -= size;
381 drop(side);
382 self.release_inbox(size);
383 return Some(Ok(event));
384 }
385 if side.ended {
386 return Some(Err(side.err.clone().unwrap_or(LinkError::EndOfStream)));
387 }
388 None
389 }
390
391 async fn send(
398 self: &Arc<Self>,
399 at: impl FnOnce(u64) -> StreamFields,
400 last: bool,
401 ) -> Result<(), LinkError> {
402 let seq = self.send_seq.lock().await;
403 self.send_at(seq, at, last).await
404 }
405
406 async fn send_here(
410 self: &Arc<Self>,
411 at: &impl Fn(u64) -> StreamFields,
412 last: bool,
413 ) -> Option<Result<(), LinkError>> {
414 let seq = self.send_seq.lock().await;
415 if self.side().reopening || self.side().successor.is_some() {
416 return None;
417 }
418 Some(self.send_at(seq, at, last).await)
419 }
420
421 async fn send_at(
422 self: &Arc<Self>,
423 mut seq: tokio::sync::MutexGuard<'_, u64>,
424 at: impl FnOnce(u64) -> StreamFields,
425 last: bool,
426 ) -> Result<(), LinkError> {
427 if self.side().sent_end {
428 return Err(LinkError::StreamClosed);
429 }
430 let fields = at(*seq);
431 let plain = match &self.sealing {
432 Some(sealing) => sealing.plain_of(&fields)?,
433 None => None,
434 };
435 let spent = plain.is_some();
436 let fields = match (&self.sealing, plain) {
437 (Some(sealing), Some(plain)) => {
438 *seq += 1;
439 let sealed = sealing.sealed(fields, plain);
440 sealed.inspect_err(|_| self.side().sent_end = true)?
441 }
442 _ => fields,
443 };
444 let encoded = self
445 .signed(&fields)
446 .inspect_err(|_| self.unsent_after_spending(spent))?;
447 if let Err(e) = self.writer.write(&encoded, MAX_FRAME_BYTES).await {
448 self.side().sent_end = true;
449 return Err(e);
450 }
451 if !spent {
452 *seq += 1;
453 }
454 if last {
455 self.sent_last().await;
456 }
457 Ok(())
458 }
459
460 fn unsent_after_spending(&self, spent: bool) {
463 if spent {
464 self.side().sent_end = true;
465 }
466 }
467
468 async fn sent_last(self: &Arc<Self>) {
471 let peer_ended = {
472 let mut side = self.side();
473 side.sent_end = true;
474 side.peer_ended
475 };
476 self.writer.finish().await;
477 if peer_ended {
478 StreamInner::end(self, None);
479 }
480 }
481
482 fn signed(&self, fields: &StreamFields) -> Result<Vec<u8>, LinkError> {
484 let signed = if self.caller {
485 frame::sign_caller_stream(fields, &self.open, &self.link.key)?
486 } else {
487 frame::sign_provider_stream(fields, &self.open, &self.link.key)?
488 };
489 cbor::encode(&signed)
490 .map_err(|e| LinkError::Frame(frame::FrameError::Payload(e.to_string())))
491 }
492
493 async fn abort(self: &Arc<Self>, code: &str, message: &str) -> Result<(), LinkError> {
494 let sent = self
495 .send(
496 |seq| StreamFields::Error {
497 seq,
498 code: code.to_string(),
499 message: message.to_string(),
500 },
501 true,
502 )
503 .await;
504 StreamInner::end(self, Some(aborted(code, message)));
505 sent
506 }
507
508 async fn released(&self) -> bool {
511 let mut done = self.done_tx.subscribe();
512 let _ = done.wait_for(|ended| *ended).await;
513 self.side().successor.is_none()
514 }
515
516 async fn reopen_awaited(&self) {
518 let notified = self.notify.notified();
519 if self.side().reopening {
522 notified.await;
523 }
524 }
525
526 fn reseal_slot(&self) -> MutexGuard<'_, Option<Reseal>> {
527 self.reseal.lock().unwrap_or_else(|p| p.into_inner())
528 }
529
530 async fn reopened(self: &Arc<Self>, detail: &str) -> bool {
536 let Some(reseal) = self.reseal_slot().take() else {
537 return false;
538 };
539 let seq = self.send_seq.lock().await;
540 if *seq != 0 || self.side().sent_end {
541 return false;
542 }
543 self.side().reopening = true;
544 drop(seq);
545 self.notify.notify_waiters();
546 let s = self.clone();
547 let named = refused_key(Some(detail));
548 tokio::spawn(async move {
549 let outcome = reseal(named).await;
550 s.adopt(outcome);
551 });
552 true
553 }
554
555 fn adopt(self: &Arc<Self>, outcome: Result<Stream, LinkError>) {
558 let reopened = {
559 let mut side = self.side();
560 side.reopening = false;
561 outcome.map(|next| side.successor = Some(next.inner))
562 };
563 match reopened {
564 Ok(()) => StreamInner::end(self, None),
565 Err(e) => self.peer_finished(Some(e)),
566 }
567 self.notify.notify_waiters();
570 }
571
572 fn deliver(&self, event: StreamEvent, size: usize) -> bool {
575 if !self.queue(event, size) {
576 return false;
577 }
578 self.notify.notify_one();
579 true
580 }
581
582 fn queue(&self, event: StreamEvent, size: usize) -> bool {
585 let mut side = self.side();
586 if side.held + size > STREAM_INBOX {
587 return false;
588 }
589 if !self.charge_inbox(size) {
590 return false;
591 }
592 side.inbox.push_back((event, size));
593 side.held += size;
594 true
595 }
596
597 fn charge_inbox(&self, size: usize) -> bool {
600 let budget = self.budget();
601 let Some(budget) = &*budget else {
602 return true;
603 };
604 budget.admission.charge_inbox(budget.caller, size)
605 }
606
607 fn release_inbox(&self, size: usize) {
608 if let Some(budget) = &*self.budget() {
609 budget.admission.release_inbox(budget.caller, size);
610 }
611 }
612
613 fn peer_finished(self: &Arc<Self>, err: Option<LinkError>) {
616 self.side().peer_ended = true;
617 StreamInner::end(self, err);
618 }
619
620 async fn fail(self: &Arc<Self>, code: &str, cause: Option<String>) {
624 let message = cause
625 .as_deref()
626 .map(bounded_detail)
627 .unwrap_or("")
628 .to_string();
629 let _ = self.abort(code, &message).await;
630 }
631
632 pub(super) fn end(this: &Arc<StreamInner>, err: Option<LinkError>) {
636 let Some(graceful) = this.mark_ended(err) else {
637 return;
638 };
639 if !graceful {
640 StreamInner::reset_sending(this);
641 }
642 if let Some(budget) = this.budget().take() {
643 let held = std::mem::take(&mut this.side().held);
644 budget.admission.release_inbox(budget.caller, held);
645 drop(budget.place);
646 }
647 this.link
648 .lock()
649 .streams
650 .retain(|w| w.strong_count() > 0 && !std::ptr::eq(w.as_ptr(), Arc::as_ptr(this)));
651 let _ = this.done_tx.send_replace(true);
652 this.notify.notify_waiters();
653 this.notify.notify_one();
654 }
655}
656
657impl StreamInner {
658 fn mark_ended(&self, err: Option<LinkError>) -> Option<bool> {
662 let mut side = self.side();
663 if side.ended {
664 return None;
665 }
666 side.ended = true;
667 if side.err.is_none() {
668 side.err = err;
669 }
670 let graceful = side.sent_end;
671 side.sent_end = true;
672 Some(graceful)
673 }
674
675 fn reset_sending(this: &Arc<StreamInner>) {
678 let released = this.clone();
679 let Ok(runtime) = tokio::runtime::Handle::try_current() else {
680 return;
681 };
682 runtime.spawn(async move { released.writer.reset().await });
683 }
684}
685
686fn hold_stream(inner: &Inner, s: &Arc<StreamInner>) -> bool {
689 let mut state = inner.lock();
690 if state.ended.is_some() {
691 return false;
692 }
693 state.streams.push(Arc::downgrade(s));
694 true
695}
696
697fn abandon(mut send: quinn::SendStream, mut recv: quinn::RecvStream) {
699 let _ = send.reset(0u32.into());
700 let _ = recv.stop(0u32.into());
701}
702
703impl Link {
704 pub async fn open_stream(&self, c: StreamCall) -> Result<Stream, LinkError> {
708 self.open_stream_resealing(c, None).await
709 }
710
711 pub(crate) async fn open_stream_resealing(
714 &self,
715 c: StreamCall,
716 reseal: Option<Reseal>,
717 ) -> Result<Stream, LinkError> {
718 let inner = &self.inner;
719 stated(&c.target, &inner.station.node_id, &c.seal)?;
720 let deadline = if c.deadline.is_zero() {
721 DEFAULT_STREAM_DEADLINE
722 } else {
723 c.deadline
724 };
725 let mut request_id = [0u8; 16];
726 aws_lc_rs::rand::fill(&mut request_id)
727 .map_err(|_| LinkError::Io("no randomness".into()))?;
728 let deadline = (now_ms() + deadline.as_millis() as i64) as u64;
729 let (sealed, sealing) = sealed_open(inner, &c, request_id, deadline)?;
730 let signed = frame::sign_stream_open(
731 &RequestSpec {
732 request_id,
733 realm: c.realm,
734 procedure: c.procedure,
735 target: c.target,
736 deadline,
737 payload: c.payload,
738 sealed,
739 mode: Some(c.mode),
740 token: c.token,
741 proofs: c.proofs,
742 source_route: None,
743 retry_budget: None,
744 },
745 &inner.key,
746 )?;
747 let encoded = cbor::encode(&signed)
748 .map_err(|e| LinkError::Frame(frame::FrameError::Payload(e.to_string())))?;
749 if encoded.len() > STREAM_OPEN_BYTES {
750 return Err(LinkError::StreamOpenTooLarge(encoded.len()));
751 }
752 let open = frame::verify_request(&signed, inner.profile)?;
753 let state = frame::open_stream(&open)?;
754 let (send, recv) = inner
755 .connection
756 .open_bi()
757 .await
758 .map_err(|e| LinkError::Io(format!("open a stream: {e}")))?;
759 let s = StreamInner::new(inner.clone(), send, open, true, sealing);
760 let held = hold_stream(inner, &s);
761 let written = match held {
762 true => s.writer.write(&encoded, STREAM_OPEN_BYTES).await,
763 false => Err(inner.lock().ended.clone().unwrap_or(LinkError::Closed)),
764 };
765 if let Err(e) = written {
766 StreamInner::end(&s, Some(e.clone()));
767 let mut recv = recv;
768 let _ = recv.stop(0u32.into());
769 return Err(e);
770 }
771 *s.reseal_slot() = reseal;
772 tokio::spawn(read(s.clone(), recv, state));
773 Ok(Stream { inner: s })
774 }
775}
776
777fn sealed_open(
780 inner: &Inner,
781 c: &StreamCall,
782 request_id: [u8; 16],
783 deadline: u64,
784) -> Result<(Option<frame::Sealed>, Option<StreamSeal>), LinkError> {
785 match &c.seal {
786 Some(Seal::To(key)) => {
787 let (sealed, s) = sealed_request(
788 inner.profile,
789 key,
790 crate::seal::FRAME_STREAM_OPEN,
791 c.realm,
792 &c.procedure,
793 inner.self_id,
794 c.target,
795 request_id,
796 deadline,
797 &c.payload,
798 )?;
799 Ok((Some(sealed), Some(StreamSeal::caller(&s))))
800 }
801 _ => Ok((None, None)),
802 }
803}
804
805pub(super) async fn accept_streams(link: Weak<Inner>) {
807 let Some(connection) = link.upgrade().map(|l| l.connection.clone()) else {
808 return;
809 };
810 while let Ok((send, recv)) = connection.accept_bi().await {
811 tokio::spawn(incoming(link.clone(), send, recv));
812 }
813}
814
815async fn incoming(link: Weak<Inner>, send: quinn::SendStream, mut recv: quinn::RecvStream) {
821 let Some(inner) = link.upgrade() else { return };
822 let Some((open, state)) = read_open(&inner, &mut recv).await else {
823 abandon(send, recv);
824 return;
825 };
826 let offer = inner
827 .lock()
828 .served
829 .get(&(open.realm, open.procedure.clone()))
830 .map(|s| s.offer.clone());
831 let refuse_clear = |code: &str, message: &str, send: quinn::SendStream, recv| {
832 let s = StreamInner::new(inner.clone(), send, open.clone(), false, None);
833 let (code, message) = (code.to_string(), message.to_string());
834 async move { refuse(&s, &code, &message, recv).await }
835 };
836 let place = match admit_stream(&inner, &open) {
839 Ok(place) => place,
840 Err(code) => return refuse_clear(code, "", send, recv).await,
841 };
842 let (session_open, sealing) = match session_open(&inner, &open, offer.as_ref()) {
843 Ok(opened) => opened,
844 Err((code, message)) => return refuse_clear(code, &message, send, recv).await,
845 };
846 let s = StreamInner::new(inner.clone(), send, session_open, false, sealing);
848 let Some((offer, policy)) = offer.and_then(|o| Some((o.stream?, o.policy))) else {
849 return refuse(&s, CODE_STREAM_NOT_FOUND, "", recv).await;
850 };
851 if let Some(code) = authorize(inner.profile, policy.as_ref(), &open) {
852 return refuse(&s, code, "", recv).await;
853 }
854 if Some(offer.mode) != open.mode {
855 return refuse(&s, CODE_MODE_MISMATCH, "", recv).await;
856 }
857 *s.budget() = Some(Budget {
858 admission: inner.admission.clone(),
859 caller: open.caller,
860 place: Some(place),
861 });
862 if !hold_stream(&inner, &s) {
863 StreamInner::end(&s, Some(LinkError::Closed));
864 let _ = recv.stop(0u32.into());
865 return;
866 }
867 tokio::spawn(read(s.clone(), recv, state));
868 tokio::spawn(serve(s, offer));
869}
870
871async fn read_open(
875 inner: &Inner,
876 recv: &mut quinn::RecvStream,
877) -> Option<(VerifiedRequest, StreamState)> {
878 let payload =
879 match tokio::time::timeout(STREAM_OPEN_WAIT, read_frame(recv, STREAM_OPEN_BYTES)).await {
880 Ok(Ok(payload)) => payload,
881 _ => {
882 inner.count("stream_open_unread");
883 return None;
884 }
885 };
886 let v = match cbor::decode(&payload) {
887 Ok(v) if frame_type_of(&v) == "stream_open" => v,
888 _ => {
889 inner.count("stream_open_malformed");
890 return None;
891 }
892 };
893 let Ok(open) = frame::verify_request(&v, inner.profile) else {
894 inner.count("stream_open_unverified");
895 return None;
896 };
897 if open.target != inner.self_id {
898 inner.count("stream_for_another_node");
899 return None;
900 }
901 let state = frame::open_stream(&open).ok()?;
902 Some((open, state))
903}
904
905fn session_open(
911 inner: &Inner,
912 open: &VerifiedRequest,
913 offer: Option<&Offer>,
914) -> Result<(VerifiedRequest, Option<StreamSeal>), (&'static str, String)> {
915 match &open.sealed {
916 Some(_) => opened_request(inner.keyring.as_deref(), open)
917 .map(|(payload, sealed)| {
918 (
919 VerifiedRequest {
920 payload: without_caller(payload),
921 ..open.clone()
922 },
923 Some(StreamSeal::provider(&sealed)),
924 )
925 })
926 .map_err(|detail| (CODE_SEALED_REFUSED, detail)),
927 None if offer
928 .is_some_and(|o| !clear_allowed(o.confidential, inner.keyed_since(o), now_ms())) =>
929 {
930 let message = "this procedure takes sealed opens only";
931 Err((CODE_SEALED_REQUIRED, message.to_string()))
932 }
933 None => Ok((
934 VerifiedRequest {
935 payload: without_caller(open.payload.clone()),
936 ..open.clone()
937 },
938 None,
939 )),
940 }
941}
942
943fn admit_stream(inner: &Inner, open: &VerifiedRequest) -> Result<SessionPlace, &'static str> {
947 match inner.admission.admit(open, &inner.share, now_ms()) {
948 Verdict::Refused(code) => return Err(code),
949 Verdict::Copy(_) => return Err(CODE_REQUEST_COPY),
950 Verdict::New => {}
951 }
952 inner
953 .admission
954 .open_session(open.caller)
955 .ok_or(CODE_TOO_MANY_SESSIONS)
956}
957
958async fn refuse(s: &Arc<StreamInner>, code: &str, message: &str, mut recv: quinn::RecvStream) {
961 s.link.count(&format!("stream_refused_{code}"));
962 let _ = s.abort(code, message).await;
963 let _ = recv.stop(0u32.into());
964}
965
966async fn serve(s: Arc<StreamInner>, offer: StreamOffer) {
970 let stream = Stream { inner: s.clone() };
971 let mut running = tokio::spawn((offer.handler)(stream.clone()));
972 let mut done = s.done_tx.subscribe();
973 let outcome = tokio::select! {
974 outcome = &mut running => outcome,
975 _ = done.wait_for(|ended| *ended) => {
976 running.abort();
977 return;
978 }
979 };
980 match outcome {
981 Ok(Ok(())) => {
982 let _ = stream.close().await;
983 }
984 Ok(Err(e)) => {
985 let _ = stream
986 .abort(CODE_STREAM_HANDLER_ERROR, bounded_detail(&e))
987 .await;
988 }
989 Err(panicked) => {
990 let _ = stream
991 .abort(
992 CODE_STREAM_HANDLER_ERROR,
993 bounded_detail(&panicked.to_string()),
994 )
995 .await;
996 }
997 }
998}
999
1000async fn read(s: Arc<StreamInner>, mut recv: quinn::RecvStream, mut state: StreamState) {
1004 let mut done = s.done_tx.subscribe();
1005 loop {
1006 let payload = tokio::select! {
1007 _ = done.wait_for(|ended| *ended) => return,
1008 payload = read_frame(&mut recv, MAX_FRAME_BYTES) => payload,
1009 };
1010 let payload = match payload {
1011 Ok(payload) => payload,
1012 Err(e) => return read_ended(&s, e),
1013 };
1014 match received(&s, &payload, &state).await {
1015 Some(next) => state = next,
1016 None => return,
1017 }
1018 }
1019}
1020
1021fn read_ended(s: &Arc<StreamInner>, e: LinkError) {
1024 if s.side().peer_ended {
1025 return;
1026 }
1027 let err = s.link.lock().ended.clone().unwrap_or(e);
1028 StreamInner::end(s, Some(err));
1029}
1030
1031async fn received(
1034 s: &Arc<StreamInner>,
1035 payload: &[u8],
1036 state: &StreamState,
1037) -> Option<StreamState> {
1038 let v = match cbor::decode(payload) {
1039 Ok(v) => v,
1040 Err(e) => {
1041 s.fail("malformed_frame", Some(e.to_string())).await;
1042 return None;
1043 }
1044 };
1045 if s.caller && v.get("relay_error").is_some() {
1046 relay_failed(s, &v).await;
1047 return None;
1048 }
1049 let verified = if s.caller {
1050 frame::verify_provider_stream(&v, state, s.link.profile)
1051 } else {
1052 frame::verify_caller_stream(&v, state, s.link.profile)
1053 };
1054 let (verified, next) = match verified {
1055 Ok(verified) => verified,
1056 Err(e) => {
1057 s.fail("malformed_frame", Some(e.to_string())).await;
1058 return None;
1059 }
1060 };
1061 let size = payload.len();
1062 let fields = match unsealed(verified, s.sealing.as_ref()) {
1063 Ok(fields) => fields,
1064 Err(e) => {
1065 StreamInner::end(s, Some(e));
1066 return None;
1067 }
1068 };
1069 if s.caller && settles(&fields, s.sealing.is_some()) {
1072 s.side().settled = true;
1073 }
1074 taken(s, fields, size, next).await
1075}
1076
1077async fn relay_failed(s: &Arc<StreamInner>, v: &Value) {
1080 match frame::verify_relay_error(v, &s.open, s.link.profile, &s.link.station.node_id) {
1081 Ok(relayed) => s.peer_finished(Some(LinkError::Stream {
1082 code: relayed.code,
1083 message: String::new(),
1084 relay: true,
1085 })),
1086 Err(e) => s.fail("malformed_frame", Some(e.to_string())).await,
1087 }
1088}
1089
1090async fn taken(
1093 s: &Arc<StreamInner>,
1094 fields: StreamFields,
1095 size: usize,
1096 next: StreamState,
1097) -> Option<StreamState> {
1098 match fields {
1099 StreamFields::Error {
1100 seq: 0,
1101 ref code,
1102 ref message,
1103 } if s.caller && code == CODE_SEALED_REFUSED && s.reopened(message).await => None,
1104 StreamFields::Error { code, message, .. } => {
1105 s.peer_finished(Some(LinkError::Stream {
1106 code,
1107 message,
1108 relay: false,
1109 }));
1110 None
1111 }
1112 StreamFields::Reply { payload, .. } => {
1113 s.deliver(StreamEvent::Reply { payload }, size);
1114 s.peer_finished(None);
1115 None
1116 }
1117 StreamFields::End { role, .. } => {
1118 s.deliver(StreamEvent::End { role }, size);
1119 if role == StreamRole::Both {
1120 s.peer_finished(None);
1121 return None;
1122 }
1123 let mine = {
1124 let mut side = s.side();
1125 side.peer_ended = true;
1126 side.sent_end
1127 };
1128 if mine {
1129 StreamInner::end(s, None);
1130 }
1131 None
1132 }
1133 StreamFields::Data { encoding, body, .. } => {
1134 if !s.deliver(StreamEvent::Data { encoding, body }, size) {
1135 s.fail("resource_exhausted", None).await;
1136 return None;
1137 }
1138 Some(next)
1139 }
1140 StreamFields::SealedData { .. }
1142 | StreamFields::SealedError { .. }
1143 | StreamFields::SealedReply { .. } => {
1144 StreamInner::end(s, Some(LinkError::ClearAnswerToSealed));
1145 None
1146 }
1147 }
1148}
1149
1150fn settles(fields: &StreamFields, sealed: bool) -> bool {
1156 match fields {
1157 StreamFields::Data { .. } | StreamFields::Reply { .. } => true,
1158 StreamFields::End { .. } => !sealed,
1159 _ => false,
1160 }
1161}