Skip to main content

scion_stack/
quic.rs

1// Copyright 2025 Anapaya Systems
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//   http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//! SCION stack QUIC connection.
15
16use std::future::Future;
17
18use bytes::Bytes;
19
20/// Abstract over different types of Quinn-connections that differ only in the
21/// type of address that is used for the local and remote address.
22pub trait QuinnConn: Clone + Send + Sync {
23    /// The type used to represent the local address.
24    type AddrType: std::fmt::Debug;
25    /// The type used to represent the remote socket address.
26    type SockAddrType: std::fmt::Debug;
27    /// Opens a new bidirectional stream.
28    fn open_bi(&self) -> anapaya_quinn::OpenBi<'_>;
29    /// Accepts a new incoming bidirectional stream.
30    fn accept_bi(&self) -> anapaya_quinn::AcceptBi<'_>;
31    /// Reads a datagram, if one is available.
32    fn read_datagram(&self) -> anapaya_quinn::ReadDatagram<'_>;
33    /// Sends a datagram.
34    fn send_datagram(&self, data: Bytes) -> Result<(), anapaya_quinn::SendDatagramError>;
35    /// Sends a datagram and wait for it to be sent.
36    fn send_datagram_wait(&self, data: Bytes) -> anapaya_quinn::SendDatagram<'_>;
37    /// Waits for the connection to be closed.
38    fn closed(&self) -> impl Future<Output = anapaya_quinn::ConnectionError> + Send;
39    /// Returns the reason why the connection was closed, if it was closed.
40    fn close_reason(&self) -> Option<anapaya_quinn::ConnectionError>;
41    /// Closes the connection with the given error code and reason.
42    fn close(&self, error_code: anapaya_quinn::VarInt, reason: &[u8]);
43    /// Returns the maximum datagram size that can be sent on this connection.
44    fn max_datagram_size(&self) -> Option<usize>;
45    /// Returns the amount of buffer space available for sending datagrams.
46    fn datagram_send_buffer_space(&self) -> usize;
47    /// Returns the remote socket address type.
48    fn remote_address(&self) -> Self::SockAddrType;
49    /// Returns the local address type.
50    fn local_ip(&self) -> Option<Self::AddrType>;
51    /// Returns a stable connection identifier.
52    fn stable_id(&self) -> usize;
53    /// Returns connection statistics.
54    fn stats(&self) -> anapaya_quinn::ConnectionStats;
55}
56
57/// SCION quinn connection.
58#[derive(Clone)]
59pub struct ScionQuinnConn {
60    pub(crate) inner: anapaya_quinn::Connection,
61    /// The local SCION address of the connection.
62    pub(crate) local_addr: Option<scion_proto::address::ScionAddr>,
63    /// The remote SCION socket address of the connection.
64    pub(crate) remote_addr: scion_proto::address::SocketAddr,
65}
66
67impl QuinnConn for ScionQuinnConn {
68    type AddrType = scion_proto::address::ScionAddr;
69
70    type SockAddrType = scion_proto::address::SocketAddr;
71
72    fn open_bi(&self) -> anapaya_quinn::OpenBi<'_> {
73        self.inner.open_bi()
74    }
75
76    fn accept_bi(&self) -> anapaya_quinn::AcceptBi<'_> {
77        self.inner.accept_bi()
78    }
79
80    fn read_datagram(&self) -> anapaya_quinn::ReadDatagram<'_> {
81        self.inner.read_datagram()
82    }
83
84    fn send_datagram(&self, data: Bytes) -> Result<(), anapaya_quinn::SendDatagramError> {
85        self.inner.send_datagram(data)
86    }
87
88    fn send_datagram_wait(&self, data: Bytes) -> anapaya_quinn::SendDatagram<'_> {
89        self.inner.send_datagram_wait(data)
90    }
91
92    async fn closed(&self) -> anapaya_quinn::ConnectionError {
93        self.inner.closed().await
94    }
95
96    fn close_reason(&self) -> Option<anapaya_quinn::ConnectionError> {
97        self.inner.close_reason()
98    }
99
100    fn close(&self, error_code: anapaya_quinn::VarInt, reason: &[u8]) {
101        self.inner.close(error_code, reason)
102    }
103
104    fn max_datagram_size(&self) -> Option<usize> {
105        self.inner.max_datagram_size()
106    }
107
108    fn datagram_send_buffer_space(&self) -> usize {
109        self.inner.datagram_send_buffer_space()
110    }
111
112    fn remote_address(&self) -> Self::SockAddrType {
113        self.remote_addr
114    }
115
116    fn local_ip(&self) -> Option<Self::AddrType> {
117        self.local_addr
118    }
119
120    fn stable_id(&self) -> usize {
121        self.inner.stable_id()
122    }
123    fn stats(&self) -> anapaya_quinn::ConnectionStats {
124        self.inner.stats()
125    }
126}
127
128impl QuinnConn for anapaya_quinn::Connection {
129    type AddrType = std::net::IpAddr;
130
131    type SockAddrType = std::net::SocketAddr;
132
133    fn open_bi(&self) -> anapaya_quinn::OpenBi<'_> {
134        self.open_bi()
135    }
136
137    fn accept_bi(&self) -> anapaya_quinn::AcceptBi<'_> {
138        self.accept_bi()
139    }
140
141    fn read_datagram(&self) -> anapaya_quinn::ReadDatagram<'_> {
142        self.read_datagram()
143    }
144
145    fn send_datagram(&self, data: Bytes) -> Result<(), anapaya_quinn::SendDatagramError> {
146        self.send_datagram(data)
147    }
148
149    fn send_datagram_wait(&self, data: Bytes) -> anapaya_quinn::SendDatagram<'_> {
150        self.send_datagram_wait(data)
151    }
152
153    fn closed(&self) -> impl Future<Output = anapaya_quinn::ConnectionError> + Send {
154        self.closed()
155    }
156
157    fn close_reason(&self) -> Option<anapaya_quinn::ConnectionError> {
158        self.close_reason()
159    }
160
161    fn close(&self, error_code: anapaya_quinn::VarInt, reason: &[u8]) {
162        self.close(error_code, reason);
163    }
164
165    fn max_datagram_size(&self) -> Option<usize> {
166        self.max_datagram_size()
167    }
168
169    fn datagram_send_buffer_space(&self) -> usize {
170        self.datagram_send_buffer_space()
171    }
172
173    fn remote_address(&self) -> Self::SockAddrType {
174        self.remote_address()
175    }
176
177    fn local_ip(&self) -> Option<Self::AddrType> {
178        self.local_ip()
179    }
180
181    fn stable_id(&self) -> usize {
182        self.stable_id()
183    }
184    fn stats(&self) -> anapaya_quinn::ConnectionStats {
185        self.stats()
186    }
187}