1use crate::buffer::WriteBuffer;
2use crate::stream::{ReadStream, StartError as StreamStartError, Stream, StreamType};
3
4#[cfg(feature = "msquic-2-5")]
5use msquic_v2_5 as msquic;
6#[cfg(feature = "msquic-seera")]
7use seera_msquic as msquic;
8
9use std::collections::VecDeque;
10use std::fs::File;
11use std::future::Future;
12use std::io::{Seek, SeekFrom, Write};
13use std::net::SocketAddr;
14use std::ops::Deref;
15use std::pin::Pin;
16use std::sync::{Arc, Mutex};
17use std::task::{Context, Poll, Waker};
18
19use bytes::Bytes;
20use libc::c_void;
21use msquic::ffi::QUIC_TLS_SECRETS__bindgen_ty_1;
22use thiserror::Error;
23use tracing::{info, trace};
24
25#[derive(Clone)]
26pub struct Connection(Arc<ConnectionInstance>);
27
28impl Connection {
29 pub fn new(registration: &msquic::Registration) -> Result<Self, ConnectionError> {
33 let inner = Arc::new(ConnectionInner::new(ConnectionState::Open, None, None));
34 let inner_in_ev = inner.clone();
35 let msquic_conn = msquic::Connection::open(registration, move |conn_ref, ev| {
36 inner_in_ev.callback_handler_impl(conn_ref, ev)
37 })
38 .map_err(ConnectionError::OtherError)?;
39 let instance = Arc::new(ConnectionInstance { inner, msquic_conn });
40 trace!(
41 "ConnectionInstance({:p}, Inner: {:p}) Open by local",
42 instance,
43 instance.inner
44 );
45 Ok(Self(instance))
46 }
47
48 pub(crate) fn from_raw(
49 #[cfg(feature = "msquic-2-5")] handle: msquic::ffi::HQUIC,
50 #[cfg(not(feature = "msquic-2-5"))] msquic_conn: msquic::Connection,
51 tls_secrets: Option<Box<msquic::ffi::QUIC_TLS_SECRETS>>,
52 sslkeylog_file: Option<File>,
53 ) -> Self {
54 #[cfg(feature = "msquic-2-5")]
55 let msquic_conn = unsafe { msquic::Connection::from_raw(handle) };
56 let inner = Arc::new(ConnectionInner::new(
57 ConnectionState::Connected,
58 tls_secrets,
59 sslkeylog_file,
60 ));
61 let inner_in_ev = inner.clone();
62 msquic_conn.set_callback_handler(move |conn_ref, ev| {
63 inner_in_ev.callback_handler_impl(conn_ref, ev)
64 });
65 let instance = Arc::new(ConnectionInstance { inner, msquic_conn });
66 trace!(
67 "ConnectionInstance({:p}, Inner: {:p}) Open by peer",
68 instance,
69 instance.inner
70 );
71 Self(instance)
72 }
73
74 pub fn start<'a>(
76 &'a self,
77 configuration: &'a msquic::Configuration,
78 host: &'a str,
79 port: u16,
80 ) -> ConnectionStart<'a> {
81 ConnectionStart {
82 conn: self,
83 configuration,
84 host,
85 port,
86 }
87 }
88
89 fn poll_start(
91 &self,
92 cx: &mut Context<'_>,
93 configuration: &msquic::Configuration,
94 host: &str,
95 port: u16,
96 ) -> Poll<Result<(), StartError>> {
97 let mut exclusive = self.0.exclusive.lock().unwrap();
98 match exclusive.state {
99 ConnectionState::Open => {
100 self.0
101 .msquic_conn
102 .start(configuration, host, port)
103 .map_err(StartError::OtherError)?;
104 exclusive.state = ConnectionState::Connecting;
105 }
106 ConnectionState::Connecting => {}
107 ConnectionState::Connected => return Poll::Ready(Ok(())),
108 ConnectionState::Shutdown | ConnectionState::ShutdownComplete => {
109 return Poll::Ready(Err(StartError::ConnectionLost(
110 exclusive.error.as_ref().expect("error").clone(),
111 )));
112 }
113 }
114 exclusive.start_waiters.push(cx.waker().clone());
115 Poll::Pending
116 }
117
118 pub fn open_outbound_stream(
120 &self,
121 stream_type: StreamType,
122 fail_on_blocked: bool,
123 ) -> OpenOutboundStream<'_> {
124 OpenOutboundStream {
125 conn: &self.0,
126 stream_type: Some(stream_type),
127 stream: None,
128 fail_on_blocked,
129 }
130 }
131
132 pub fn accept_inbound_stream(&self) -> AcceptInboundStream<'_> {
134 AcceptInboundStream { conn: self }
135 }
136
137 pub fn poll_accept_inbound_stream(
139 &self,
140 cx: &mut Context<'_>,
141 ) -> Poll<Result<Stream, StreamStartError>> {
142 let mut exclusive = self.0.exclusive.lock().unwrap();
143 match exclusive.state {
144 ConnectionState::Open => {
145 return Poll::Ready(Err(StreamStartError::ConnectionNotStarted));
146 }
147 ConnectionState::Connecting => {
148 exclusive.start_waiters.push(cx.waker().clone());
149 return Poll::Pending;
150 }
151 ConnectionState::Connected => {}
152 ConnectionState::Shutdown | ConnectionState::ShutdownComplete => {
153 return Poll::Ready(Err(StreamStartError::ConnectionLost(
154 exclusive.error.as_ref().expect("error").clone(),
155 )));
156 }
157 }
158
159 if !exclusive.inbound_streams.is_empty() {
160 return Poll::Ready(Ok(exclusive.inbound_streams.pop_front().unwrap()));
161 }
162 exclusive.inbound_stream_waiters.push(cx.waker().clone());
163 Poll::Pending
164 }
165
166 pub fn accept_inbound_uni_stream(&self) -> AcceptInboundUniStream<'_> {
168 AcceptInboundUniStream { conn: self }
169 }
170
171 pub fn poll_accept_inbound_uni_stream(
173 &self,
174 cx: &mut Context<'_>,
175 ) -> Poll<Result<ReadStream, StreamStartError>> {
176 let mut exclusive = self.0.exclusive.lock().unwrap();
177 match exclusive.state {
178 ConnectionState::Open => {
179 return Poll::Ready(Err(StreamStartError::ConnectionNotStarted));
180 }
181 ConnectionState::Connecting => {
182 exclusive.start_waiters.push(cx.waker().clone());
183 return Poll::Pending;
184 }
185 ConnectionState::Connected => {}
186 ConnectionState::Shutdown | ConnectionState::ShutdownComplete => {
187 return Poll::Ready(Err(StreamStartError::ConnectionLost(
188 exclusive.error.as_ref().expect("error").clone(),
189 )));
190 }
191 }
192
193 if !exclusive.inbound_uni_streams.is_empty() {
194 return Poll::Ready(Ok(exclusive.inbound_uni_streams.pop_front().unwrap()));
195 }
196 exclusive
197 .inbound_uni_stream_waiters
198 .push(cx.waker().clone());
199 Poll::Pending
200 }
201
202 pub fn poll_receive_datagram(
204 &self,
205 cx: &mut Context<'_>,
206 ) -> Poll<Result<Bytes, DgramReceiveError>> {
207 let mut exclusive = self.0.exclusive.lock().unwrap();
208 match exclusive.state {
209 ConnectionState::Open => {
210 return Poll::Ready(Err(DgramReceiveError::ConnectionNotStarted));
211 }
212 ConnectionState::Connecting => {
213 exclusive.start_waiters.push(cx.waker().clone());
214 return Poll::Pending;
215 }
216 ConnectionState::Connected => {}
217 ConnectionState::Shutdown | ConnectionState::ShutdownComplete => {
218 return Poll::Ready(Err(DgramReceiveError::ConnectionLost(
219 exclusive.error.as_ref().expect("error").clone(),
220 )));
221 }
222 }
223
224 if let Some(buf) = exclusive.recv_buffers.pop_front() {
225 Poll::Ready(Ok(buf))
226 } else {
227 exclusive.recv_waiters.push(cx.waker().clone());
228 Poll::Pending
229 }
230 }
231
232 pub fn poll_send_datagram(
234 &self,
235 cx: &mut Context<'_>,
236 buf: &Bytes,
237 ) -> Poll<Result<(), DgramSendError>> {
238 let mut exclusive = self.0.exclusive.lock().unwrap();
239 match exclusive.state {
240 ConnectionState::Open => {
241 return Poll::Ready(Err(DgramSendError::ConnectionNotStarted));
242 }
243 ConnectionState::Connecting => {
244 exclusive.start_waiters.push(cx.waker().clone());
245 return Poll::Pending;
246 }
247 ConnectionState::Connected => {}
248 ConnectionState::Shutdown | ConnectionState::ShutdownComplete => {
249 return Poll::Ready(Err(DgramSendError::ConnectionLost(
250 exclusive.error.as_ref().expect("error").clone(),
251 )));
252 }
253 }
254
255 let mut write_buf = exclusive.write_pool.pop().unwrap_or(WriteBuffer::new());
256 let _ = write_buf.put_zerocopy(buf);
257 let buffers = unsafe {
258 let (data, len) = write_buf.get_buffers();
259 std::slice::from_raw_parts(data, len)
260 };
261 let res = unsafe {
262 self.0.msquic_conn.datagram_send(
263 buffers,
264 msquic::SendFlags::NONE,
265 write_buf.into_raw() as *const _,
266 )
267 }
268 .map_err(DgramSendError::OtherError);
269 Poll::Ready(res)
270 }
271
272 pub fn send_datagram(&self, buf: &Bytes) -> Result<(), DgramSendError> {
274 let mut exclusive = self.0.exclusive.lock().unwrap();
275 match exclusive.state {
276 ConnectionState::Open => {
277 return Err(DgramSendError::ConnectionNotStarted);
278 }
279 ConnectionState::Connecting => {
280 return Err(DgramSendError::ConnectionNotStarted);
281 }
282 ConnectionState::Connected => {}
283 ConnectionState::Shutdown | ConnectionState::ShutdownComplete => {
284 return Err(DgramSendError::ConnectionLost(
285 exclusive.error.as_ref().expect("error").clone(),
286 ));
287 }
288 }
289
290 if !exclusive.dgram_send_enabled {
291 return Err(DgramSendError::Denied);
292 }
293 if buf.len() > exclusive.dgram_max_send_length as usize {
294 return Err(DgramSendError::TooBig);
295 }
296
297 let mut write_buf = exclusive.write_pool.pop().unwrap_or(WriteBuffer::new());
298 let _ = write_buf.put_zerocopy(buf);
299 let buffers = unsafe {
300 let (data, len) = write_buf.get_buffers();
301 std::slice::from_raw_parts(data, len)
302 };
303 unsafe {
304 self.0.msquic_conn.datagram_send(
305 buffers,
306 msquic::SendFlags::NONE,
307 write_buf.into_raw() as *const _,
308 )
309 }
310 .map_err(DgramSendError::OtherError)?;
311 Ok(())
312 }
313
314 pub fn poll_shutdown(
316 &self,
317 cx: &mut Context<'_>,
318 error_code: u64,
319 ) -> Poll<Result<(), ShutdownError>> {
320 let mut exclusive = self.0.exclusive.lock().unwrap();
321 match exclusive.state {
322 ConnectionState::Open => {
323 return Poll::Ready(Err(ShutdownError::ConnectionNotStarted));
324 }
325 ConnectionState::Connecting => {
326 exclusive.start_waiters.push(cx.waker().clone());
327 return Poll::Pending;
328 }
329 ConnectionState::Connected => {
330 self.0
331 .msquic_conn
332 .shutdown(msquic::ConnectionShutdownFlags::NONE, error_code);
333 exclusive.state = ConnectionState::Shutdown;
334 exclusive.error = Some(ConnectionError::ShutdownByLocal);
335 }
336 ConnectionState::Shutdown => {}
337 ConnectionState::ShutdownComplete => {
338 if let Some(ConnectionError::ShutdownByLocal) = &exclusive.error {
339 return Poll::Ready(Ok(()));
340 } else {
341 return Poll::Ready(Err(ShutdownError::ConnectionLost(
342 exclusive.error.as_ref().expect("error").clone(),
343 )));
344 }
345 }
346 }
347
348 exclusive.shutdown_waiters.push(cx.waker().clone());
349 Poll::Pending
350 }
351
352 pub fn shutdown(&self, error_code: u64) -> Result<(), ShutdownError> {
354 let mut exclusive = self.0.exclusive.lock().unwrap();
355 match exclusive.state {
356 ConnectionState::Open | ConnectionState::Connecting => {
357 return Err(ShutdownError::ConnectionNotStarted);
358 }
359 ConnectionState::Connected => {
360 self.0
361 .msquic_conn
362 .shutdown(msquic::ConnectionShutdownFlags::NONE, error_code);
363 exclusive.state = ConnectionState::Shutdown;
364 exclusive.error = Some(ConnectionError::ShutdownByLocal);
365 }
366 _ => {}
367 }
368 Ok(())
369 }
370
371 pub fn get_local_addr(&self) -> Result<SocketAddr, ConnectionError> {
373 self.0
374 .msquic_conn
375 .get_local_addr()
376 .map(|addr| addr.as_socket().expect("socket addr"))
377 .map_err(ConnectionError::OtherError)
378 }
379
380 pub fn get_remote_addr(&self) -> Result<SocketAddr, ConnectionError> {
382 self.0
383 .msquic_conn
384 .get_remote_addr()
385 .map(|addr| addr.as_socket().expect("socket addr"))
386 .map_err(ConnectionError::OtherError)
387 }
388
389 pub fn set_share_binding(&self, share: bool) -> Result<(), ConnectionError> {
391 let share: u8 = if share { 1 } else { 0 };
392 unsafe {
393 msquic::Api::set_param(
394 self.0.msquic_conn.as_raw(),
395 msquic::ffi::QUIC_PARAM_CONN_SHARE_UDP_BINDING,
396 std::mem::size_of::<u8>() as u32,
397 &share as *const _ as *const _,
398 )
399 }
400 .map_err(ConnectionError::OtherError)
401 }
402
403 #[cfg(feature = "msquic-seera")]
405 pub fn add_path(
406 &self,
407 local_addr: SocketAddr,
408 remote_addr: SocketAddr,
409 ) -> Result<(), ConnectionError> {
410 unsafe {
411 msquic::Api::set_param(
412 self.0.msquic_conn.as_raw(),
413 msquic::ffi::QUIC_PARAM_CONN_ADD_PATH,
414 std::mem::size_of::<msquic::ffi::QUIC_PATH_PARAM>() as u32,
415 &msquic::ffi::QUIC_PATH_PARAM {
416 LocalAddress: &mut msquic::Addr::from(local_addr) as *mut _ as *mut _,
417 RemoteAddress: &mut msquic::Addr::from(remote_addr) as *mut _ as *mut _,
418 } as *const _ as *const _,
419 )
420 }
421 .map_err(ConnectionError::OtherError)
422 }
423
424 #[cfg(feature = "msquic-seera")]
426 pub fn activate_path(
427 &self,
428 local_addr: SocketAddr,
429 remote_addr: SocketAddr,
430 ) -> Result<(), ConnectionError> {
431 unsafe {
432 msquic::Api::set_param(
433 self.0.msquic_conn.as_raw(),
434 msquic::ffi::QUIC_PARAM_CONN_ACTIVATE_PATH,
435 std::mem::size_of::<msquic::ffi::QUIC_PATH_PARAM>() as u32,
436 &msquic::ffi::QUIC_PATH_PARAM {
437 LocalAddress: &mut msquic::Addr::from(local_addr) as *mut _ as *mut _,
438 RemoteAddress: &mut msquic::Addr::from(remote_addr) as *mut _ as *mut _,
439 } as *const _ as *const _,
440 )
441 }
442 .map_err(ConnectionError::OtherError)
443 }
444
445 #[cfg(feature = "msquic-seera")]
447 pub fn remove_path(
448 &self,
449 local_addr: SocketAddr,
450 remote_addr: SocketAddr,
451 ) -> Result<(), ConnectionError> {
452 unsafe {
453 msquic::Api::set_param(
454 self.0.msquic_conn.as_raw(),
455 msquic::ffi::QUIC_PARAM_CONN_REMOVE_PATH,
456 std::mem::size_of::<msquic::ffi::QUIC_PATH_PARAM>() as u32,
457 &msquic::ffi::QUIC_PATH_PARAM {
458 LocalAddress: &mut msquic::Addr::from(local_addr) as *mut _ as *mut _,
459 RemoteAddress: &mut msquic::Addr::from(remote_addr) as *mut _ as *mut _,
460 } as *const _ as *const _,
461 )
462 }
463 .map_err(ConnectionError::OtherError)
464 }
465
466 #[cfg(feature = "msquic-seera")]
468 pub fn add_bound_addr(&self, addr: SocketAddr) -> Result<(), ConnectionError> {
469 unsafe {
470 msquic::Api::set_param(
471 self.0.msquic_conn.as_raw(),
472 msquic::ffi::QUIC_PARAM_CONN_ADD_BOUND_ADDRESS,
473 std::mem::size_of::<msquic::Addr>() as u32,
474 &msquic::Addr::from(addr) as *const _ as *const _,
475 )
476 }
477 .map_err(ConnectionError::OtherError)
478 }
479
480 #[cfg(feature = "msquic-seera")]
482 pub fn add_observed_addr(
483 &self,
484 addr: SocketAddr,
485 observed_addr: SocketAddr,
486 ) -> Result<(), ConnectionError> {
487 unsafe {
488 msquic::Api::set_param(
489 self.0.msquic_conn.as_raw(),
490 msquic::ffi::QUIC_PARAM_CONN_ADD_OBSERVED_ADDRESS,
491 std::mem::size_of::<msquic::ffi::QUIC_ADD_OBSERVED_ADDRESS>() as u32,
492 &msquic::ffi::QUIC_ADD_OBSERVED_ADDRESS {
493 LocalAddress: &mut msquic::Addr::from(addr) as *mut _ as *mut _,
494 ObservedAddress: &mut msquic::Addr::from(observed_addr) as *mut _ as *mut _,
495 } as *const _ as *const _,
496 )
497 }
498 .map_err(ConnectionError::OtherError)
499 }
500
501 #[cfg(feature = "msquic-seera")]
503 pub fn remove_bound_addr(&self, addr: SocketAddr) -> Result<(), ConnectionError> {
504 unsafe {
505 msquic::Api::set_param(
506 self.0.msquic_conn.as_raw(),
507 msquic::ffi::QUIC_PARAM_CONN_REMOVE_BOUND_ADDRESS,
508 std::mem::size_of::<msquic::Addr>() as u32,
509 &msquic::Addr::from(addr) as *const _ as *const _,
510 )
511 }
512 .map_err(ConnectionError::OtherError)
513 }
514
515 #[cfg(feature = "msquic-seera")]
517 pub fn add_candidate_addr(
518 &self,
519 host_addr: SocketAddr,
520 observed_addr: SocketAddr,
521 ) -> Result<(), ConnectionError> {
522 unsafe {
523 msquic::Api::set_param(
524 self.0.msquic_conn.as_raw(),
525 msquic::ffi::QUIC_PARAM_CONN_ADD_CANDIDATE_ADDRESS,
526 std::mem::size_of::<msquic::ffi::QUIC_CANDIDATE_ADDRESS>() as u32,
527 &msquic::ffi::QUIC_CANDIDATE_ADDRESS {
528 HostAddress: &mut msquic::Addr::from(host_addr) as *mut _ as *mut _,
529 ObservedAddress: &mut msquic::Addr::from(observed_addr) as *mut _ as *mut _,
530 } as *const _ as *const _,
531 )
532 }
533 .map_err(ConnectionError::OtherError)
534 }
535
536 #[cfg(feature = "msquic-seera")]
538 pub fn remove_candidate_addr(
539 &self,
540 host_addr: SocketAddr,
541 observed_addr: SocketAddr,
542 ) -> Result<(), ConnectionError> {
543 unsafe {
544 msquic::Api::set_param(
545 self.0.msquic_conn.as_raw(),
546 msquic::ffi::QUIC_PARAM_CONN_REMOVE_CANDIDATE_ADDRESS,
547 std::mem::size_of::<msquic::ffi::QUIC_CANDIDATE_ADDRESS>() as u32,
548 &msquic::ffi::QUIC_CANDIDATE_ADDRESS {
549 HostAddress: &mut msquic::Addr::from(host_addr) as *mut _ as *mut _,
550 ObservedAddress: &mut msquic::Addr::from(observed_addr) as *mut _ as *mut _,
551 } as *const _ as *const _,
552 )
553 }
554 .map_err(ConnectionError::OtherError)
555 }
556
557 pub fn poll_event(&self, cx: &mut Context<'_>) -> Poll<Result<ConnectionEvent, EventError>> {
559 let mut exclusive = self.0.exclusive.lock().unwrap();
560 match exclusive.state {
561 ConnectionState::Open => {
562 return Poll::Ready(Err(EventError::ConnectionNotStarted));
563 }
564 ConnectionState::Connecting => {
565 exclusive.start_waiters.push(cx.waker().clone());
566 return Poll::Pending;
567 }
568 ConnectionState::Connected | ConnectionState::Shutdown => {}
569 ConnectionState::ShutdownComplete => {
570 return Poll::Ready(Err(EventError::ConnectionLost(
571 exclusive.error.as_ref().expect("error").clone(),
572 )));
573 }
574 }
575
576 if exclusive.events.is_empty() {
577 exclusive.event_waiters.push(cx.waker().clone());
578 Poll::Pending
579 } else {
580 Poll::Ready(Ok(exclusive.events.pop_front().unwrap()))
581 }
582 }
583
584 pub fn set_sslkeylog_file(&self, file: File) -> Result<(), ConnectionError> {
586 let mut exclusive = self.0.exclusive.lock().unwrap();
587 if exclusive.sslkeylog_file.is_some() {
588 return Err(ConnectionError::SslKeyLogFileAlreadySet);
589 }
590 if exclusive.tls_secrets.is_none() {
591 exclusive.tls_secrets = Some(Box::new(msquic::ffi::QUIC_TLS_SECRETS {
592 SecretLength: 0,
593 ClientRandom: [0; 32],
594 IsSet: QUIC_TLS_SECRETS__bindgen_ty_1 {
595 _bitfield_align_1: [0; 0],
596 _bitfield_1: QUIC_TLS_SECRETS__bindgen_ty_1::new_bitfield_1(
597 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
598 ),
599 },
600 ClientEarlyTrafficSecret: [0; 64],
601 ClientHandshakeTrafficSecret: [0; 64],
602 ServerHandshakeTrafficSecret: [0; 64],
603 ClientTrafficSecret0: [0; 64],
604 ServerTrafficSecret0: [0; 64],
605 }));
606 unsafe {
607 msquic::Api::set_param(
608 self.0.msquic_conn.as_raw(),
609 msquic::ffi::QUIC_PARAM_CONN_TLS_SECRETS,
610 std::mem::size_of::<msquic::ffi::QUIC_TLS_SECRETS>() as u32,
611 exclusive.tls_secrets.as_ref().unwrap().as_ref() as *const _ as *const _,
612 )
613 }
614 .map_err(ConnectionError::OtherError)?;
615 }
616 exclusive.sslkeylog_file = Some(file);
617 Ok(())
618 }
619}
620
621struct ConnectionInstance {
622 inner: Arc<ConnectionInner>,
623 msquic_conn: msquic::Connection,
624}
625
626impl Deref for ConnectionInstance {
627 type Target = ConnectionInner;
628
629 fn deref(&self) -> &Self::Target {
630 &self.inner
631 }
632}
633
634impl Drop for ConnectionInstance {
635 fn drop(&mut self) {
636 trace!("ConnectionInstance({:p}) dropping", self);
637 }
638}
639
640struct ConnectionInner {
641 exclusive: Mutex<ConnectionInnerExclusive>,
642}
643
644struct ConnectionInnerExclusive {
645 state: ConnectionState,
646 error: Option<ConnectionError>,
647 start_waiters: Vec<Waker>,
648 inbound_stream_waiters: Vec<Waker>,
649 inbound_uni_stream_waiters: Vec<Waker>,
650 inbound_streams: VecDeque<crate::stream::Stream>,
651 inbound_uni_streams: VecDeque<crate::stream::ReadStream>,
652 recv_buffers: VecDeque<Bytes>,
653 recv_waiters: Vec<Waker>,
654 write_pool: Vec<WriteBuffer>,
655 dgram_send_enabled: bool,
656 dgram_max_send_length: u16,
657 shutdown_waiters: Vec<Waker>,
658 events: VecDeque<ConnectionEvent>,
659 event_waiters: Vec<Waker>,
660 sslkeylog_file: Option<File>,
661 tls_secrets: Option<Box<msquic::ffi::QUIC_TLS_SECRETS>>,
662}
663
664impl ConnectionInner {
665 fn new(
666 state: ConnectionState,
667 tls_secrets: Option<Box<msquic::ffi::QUIC_TLS_SECRETS>>,
668 sslkeylog_file: Option<File>,
669 ) -> Self {
670 Self {
671 exclusive: Mutex::new(ConnectionInnerExclusive {
672 state,
673 error: None,
674 start_waiters: Vec::new(),
675 inbound_stream_waiters: Vec::new(),
676 inbound_uni_stream_waiters: Vec::new(),
677 inbound_streams: VecDeque::new(),
678 inbound_uni_streams: VecDeque::new(),
679 recv_buffers: VecDeque::new(),
680 recv_waiters: Vec::new(),
681 write_pool: Vec::new(),
682 dgram_send_enabled: false,
683 dgram_max_send_length: 0,
684 shutdown_waiters: Vec::new(),
685 events: VecDeque::new(),
686 event_waiters: Vec::new(),
687 sslkeylog_file,
688 tls_secrets,
689 }),
690 }
691 }
692
693 fn handle_event_connected(
694 &self,
695 _session_resumed: bool,
696 _negotiated_alpn: &[u8],
697 ) -> Result<(), msquic::Status> {
698 trace!("ConnectionInner({:p}) Connected", self);
699
700 let mut exclusive = self.exclusive.lock().unwrap();
701 match (
702 exclusive.tls_secrets.take(),
703 exclusive.sslkeylog_file.take(),
704 ) {
705 (Some(tls_secrets), Some(mut file)) => {
706 info!("ConnectionInner({:p}) Writing TLS secrets to file", self);
707 let client_random = if tls_secrets.IsSet.ClientRandom() != 0 {
708 hex::encode(tls_secrets.ClientRandom)
709 } else {
710 String::new()
711 };
712
713 let _ = file.seek(SeekFrom::End(0));
714
715 if tls_secrets.IsSet.ClientEarlyTrafficSecret() != 0 {
716 let _ = writeln!(
717 file,
718 "CLIENT_EARLY_TRAFFIC_SECRET {} {}",
719 client_random,
720 hex::encode(
721 &tls_secrets.ClientEarlyTrafficSecret
722 [0..tls_secrets.SecretLength as usize]
723 )
724 );
725 }
726
727 if tls_secrets.IsSet.ClientHandshakeTrafficSecret() != 0 {
728 let _ = writeln!(
729 file,
730 "CLIENT_HANDSHAKE_TRAFFIC_SECRET {} {}",
731 client_random,
732 hex::encode(
733 &tls_secrets.ClientHandshakeTrafficSecret
734 [0..tls_secrets.SecretLength as usize]
735 )
736 );
737 }
738
739 if tls_secrets.IsSet.ServerHandshakeTrafficSecret() != 0 {
740 let _ = writeln!(
741 file,
742 "SERVER_HANDSHAKE_TRAFFIC_SECRET {} {}",
743 client_random,
744 hex::encode(
745 &tls_secrets.ServerHandshakeTrafficSecret
746 [0..tls_secrets.SecretLength as usize]
747 )
748 );
749 }
750
751 if tls_secrets.IsSet.ClientTrafficSecret0() != 0 {
752 let _ = writeln!(
753 file,
754 "CLIENT_TRAFFIC_SECRET_0 {} {}",
755 client_random,
756 hex::encode(
757 &tls_secrets.ClientTrafficSecret0[0..tls_secrets.SecretLength as usize]
758 )
759 );
760 }
761
762 if tls_secrets.IsSet.ServerTrafficSecret0() != 0 {
763 let _ = writeln!(
764 file,
765 "SERVER_TRAFFIC_SECRET_0 {} {}",
766 client_random,
767 hex::encode(
768 &tls_secrets.ServerTrafficSecret0[0..tls_secrets.SecretLength as usize]
769 )
770 );
771 }
772 exclusive.tls_secrets = Some(tls_secrets);
773 }
774 _ => { }
775 }
776 exclusive.state = ConnectionState::Connected;
777 exclusive
778 .start_waiters
779 .drain(..)
780 .for_each(|waker| waker.wake());
781 Ok(())
782 }
783
784 fn handle_event_shutdown_initiated_by_transport(
785 &self,
786 status: msquic::Status,
787 error_code: u64,
788 ) -> Result<(), msquic::Status> {
789 trace!(
790 "ConnectionInner({:p}) Transport shutdown {:?}",
791 self,
792 status
793 );
794
795 let mut exclusive = self.exclusive.lock().unwrap();
796 exclusive.state = ConnectionState::Shutdown;
797 exclusive.error = Some(ConnectionError::ShutdownByTransport(status, error_code));
798 exclusive
799 .start_waiters
800 .drain(..)
801 .for_each(|waker| waker.wake());
802 exclusive
803 .inbound_stream_waiters
804 .drain(..)
805 .for_each(|waker| waker.wake());
806 exclusive
807 .recv_waiters
808 .drain(..)
809 .for_each(|waker| waker.wake());
810 Ok(())
811 }
812
813 fn handle_event_shutdown_initiated_by_peer(
814 &self,
815 error_code: u64,
816 ) -> Result<(), msquic::Status> {
817 trace!("ConnectionInner({:p}) App shutdown {}", self, error_code);
818
819 let mut exclusive = self.exclusive.lock().unwrap();
820 exclusive.state = ConnectionState::Shutdown;
821 exclusive.error = Some(ConnectionError::ShutdownByPeer(error_code));
822 exclusive
823 .start_waiters
824 .drain(..)
825 .for_each(|waker| waker.wake());
826 exclusive
827 .inbound_stream_waiters
828 .drain(..)
829 .for_each(|waker| waker.wake());
830 exclusive
831 .recv_waiters
832 .drain(..)
833 .for_each(|waker| waker.wake());
834 Ok(())
835 }
836
837 fn handle_event_shutdown_complete(
838 &self,
839 handshake_completed: bool,
840 peer_acknowledged_shutdown: bool,
841 app_close_in_progress: bool,
842 ) -> Result<(), msquic::Status> {
843 trace!("ConnectionInner({:p}) Shutdown complete: handshake_completed={}, peer_acknowledged_shutdown={}, app_close_in_progress={}",
844 self, handshake_completed, peer_acknowledged_shutdown, app_close_in_progress
845 );
846
847 {
848 let mut exclusive = self.exclusive.lock().unwrap();
849 exclusive.state = ConnectionState::ShutdownComplete;
850 if exclusive.error.is_none() {
851 exclusive.error = Some(ConnectionError::ShutdownByLocal);
852 }
853 exclusive
854 .start_waiters
855 .drain(..)
856 .for_each(|waker| waker.wake());
857 exclusive
858 .inbound_stream_waiters
859 .drain(..)
860 .for_each(|waker| waker.wake());
861 exclusive
862 .recv_waiters
863 .drain(..)
864 .for_each(|waker| waker.wake());
865 exclusive
866 .shutdown_waiters
867 .drain(..)
868 .for_each(|waker| waker.wake());
869 exclusive
870 .event_waiters
871 .drain(..)
872 .for_each(|waker| waker.wake());
873 }
874 Ok(())
875 }
876
877 fn handle_event_peer_stream_started(
878 &self,
879 stream: msquic::StreamRef,
880 flags: msquic::StreamOpenFlags,
881 ) -> Result<(), msquic::Status> {
882 let stream_type = if (flags & msquic::StreamOpenFlags::UNIDIRECTIONAL)
883 == msquic::StreamOpenFlags::UNIDIRECTIONAL
884 {
885 StreamType::Unidirectional
886 } else {
887 StreamType::Bidirectional
888 };
889 trace!(
890 "ConnectionInner({:p}) Peer stream started {:?}",
891 self,
892 stream_type
893 );
894
895 let stream = Stream::from_raw(unsafe { stream.as_raw() }, stream_type);
896 if (flags & msquic::StreamOpenFlags::UNIDIRECTIONAL)
897 == msquic::StreamOpenFlags::UNIDIRECTIONAL
898 {
899 if let (Some(read_stream), None) = stream.split() {
900 let mut exclusive = self.exclusive.lock().unwrap();
901 exclusive.inbound_uni_streams.push_back(read_stream);
902 exclusive
903 .inbound_uni_stream_waiters
904 .drain(..)
905 .for_each(|waker| waker.wake());
906 } else {
907 unreachable!();
908 }
909 } else {
910 {
911 let mut exclusive = self.exclusive.lock().unwrap();
912 exclusive.inbound_streams.push_back(stream);
913 exclusive
914 .inbound_stream_waiters
915 .drain(..)
916 .for_each(|waker| waker.wake());
917 }
918 }
919
920 Ok(())
921 }
922
923 fn handle_event_streams_available(
924 &self,
925 bidirectional_count: u16,
926 unidirectional_count: u16,
927 ) -> Result<(), msquic::Status> {
928 trace!(
929 "ConnectionInner({:p}) Streams available bidirectional_count:{} unidirectional_count:{}",
930 self,
931 bidirectional_count,
932 unidirectional_count
933 );
934 Ok(())
935 }
936
937 fn handle_event_datagram_state_changed(
938 &self,
939 send_enabled: bool,
940 max_send_length: u16,
941 ) -> Result<(), msquic::Status> {
942 trace!(
943 "ConnectionInner({:p}) Datagram state changed send_enabled:{} max_send_length:{}",
944 self,
945 send_enabled,
946 max_send_length
947 );
948 let mut exclusive = self.exclusive.lock().unwrap();
949 exclusive.dgram_send_enabled = send_enabled;
950 exclusive.dgram_max_send_length = max_send_length;
951 Ok(())
952 }
953
954 fn handle_event_datagram_received(
955 &self,
956 buffer: &msquic::BufferRef,
957 _flags: msquic::ReceiveFlags,
958 ) -> Result<(), msquic::Status> {
959 trace!("ConnectionInner({:p}) Datagram received", self);
960 let buf = Bytes::copy_from_slice(buffer.as_bytes());
961 {
962 let mut exclusive = self.exclusive.lock().unwrap();
963 exclusive.recv_buffers.push_back(buf);
964 exclusive
965 .recv_waiters
966 .drain(..)
967 .for_each(|waker| waker.wake());
968 }
969 Ok(())
970 }
971
972 fn handle_event_datagram_send_state_changed(
973 &self,
974 client_context: *const c_void,
975 state: msquic::DatagramSendState,
976 ) -> Result<(), msquic::Status> {
977 trace!(
978 "ConnectionInner({:p}) Datagram send state changed state:{:?}",
979 self,
980 state
981 );
982 match state {
983 msquic::DatagramSendState::Sent | msquic::DatagramSendState::Canceled => {
984 let mut write_buf = unsafe { WriteBuffer::from_raw(client_context) };
985 let mut exclusive = self.exclusive.lock().unwrap();
986 write_buf.reset();
987 exclusive.write_pool.push(write_buf);
988 }
989 _ => {}
990 }
991 Ok(())
992 }
993
994 #[cfg(feature = "msquic-seera")]
995 fn handle_event_notify_observed_address(
996 &self,
997 local_address: &msquic::Addr,
998 observed_address: &msquic::Addr,
999 ) -> Result<(), msquic::Status> {
1000 let local_address = local_address.as_socket().expect("socket addr");
1001 let observed_address = observed_address.as_socket().expect("socket addr");
1002 trace!(
1003 "ConnectionInner({:p}) Notify observed address local_address:{} observed_address:{}",
1004 self,
1005 local_address,
1006 observed_address
1007 );
1008 let mut exclusive = self.exclusive.lock().unwrap();
1009 exclusive
1010 .events
1011 .push_back(ConnectionEvent::NotifyObservedAddress {
1012 local_address,
1013 observed_address,
1014 });
1015 exclusive
1016 .event_waiters
1017 .drain(..)
1018 .for_each(|waker| waker.wake());
1019 Ok(())
1020 }
1021
1022 #[cfg(feature = "msquic-seera")]
1023 fn handle_event_notify_remote_address_added(
1024 &self,
1025 address: &msquic::Addr,
1026 sequence_number: u64,
1027 ) -> Result<(), msquic::Status> {
1028 let address = address.as_socket().expect("socket addr");
1029 trace!(
1030 "ConnectionInner({:p}) Notify remote address added address:{} sequence_number:{}",
1031 self,
1032 address,
1033 sequence_number
1034 );
1035 let mut exclusive = self.exclusive.lock().unwrap();
1036 exclusive
1037 .events
1038 .push_back(ConnectionEvent::NotifyRemoteAddressAdded {
1039 address,
1040 sequence_number,
1041 });
1042 exclusive
1043 .event_waiters
1044 .drain(..)
1045 .for_each(|waker| waker.wake());
1046 Ok(())
1047 }
1048
1049 #[cfg(feature = "msquic-seera")]
1050 fn handle_event_path_validated(
1051 &self,
1052 local_address: &msquic::Addr,
1053 remote_address: &msquic::Addr,
1054 ) -> Result<(), msquic::Status> {
1055 let local_address = local_address.as_socket().expect("socket addr");
1056 let remote_address = remote_address.as_socket().expect("socket addr");
1057 trace!(
1058 "ConnectionInner({:p}) path validated local_address:{} remote_address:{}",
1059 self,
1060 local_address,
1061 remote_address
1062 );
1063 let mut exclusive = self.exclusive.lock().unwrap();
1064 exclusive.events.push_back(ConnectionEvent::PathValidated {
1065 local_address,
1066 remote_address,
1067 });
1068 exclusive
1069 .event_waiters
1070 .drain(..)
1071 .for_each(|waker| waker.wake());
1072 Ok(())
1073 }
1074
1075 #[cfg(feature = "msquic-seera")]
1076 fn handle_event_notify_remote_address_removed(
1077 &self,
1078 sequence_number: u64,
1079 ) -> Result<(), msquic::Status> {
1080 trace!(
1081 "ConnectionInner({:p}) Notify remote address removed sequence_number:{}",
1082 self,
1083 sequence_number
1084 );
1085 let mut exclusive = self.exclusive.lock().unwrap();
1086 exclusive
1087 .events
1088 .push_back(ConnectionEvent::NotifyRemoteAddressRemoved { sequence_number });
1089 exclusive
1090 .event_waiters
1091 .drain(..)
1092 .for_each(|waker| waker.wake());
1093 Ok(())
1094 }
1095
1096 fn callback_handler_impl(
1097 &self,
1098 _connection: msquic::ConnectionRef,
1099 ev: msquic::ConnectionEvent,
1100 ) -> Result<(), msquic::Status> {
1101 match ev {
1102 msquic::ConnectionEvent::Connected {
1103 session_resumed,
1104 negotiated_alpn,
1105 } => self.handle_event_connected(session_resumed, negotiated_alpn),
1106 msquic::ConnectionEvent::ShutdownInitiatedByTransport { status, error_code } => {
1107 self.handle_event_shutdown_initiated_by_transport(status, error_code)
1108 }
1109 msquic::ConnectionEvent::ShutdownInitiatedByPeer { error_code } => {
1110 self.handle_event_shutdown_initiated_by_peer(error_code)
1111 }
1112 msquic::ConnectionEvent::ShutdownComplete {
1113 handshake_completed,
1114 peer_acknowledged_shutdown,
1115 app_close_in_progress,
1116 } => self.handle_event_shutdown_complete(
1117 handshake_completed,
1118 peer_acknowledged_shutdown,
1119 app_close_in_progress,
1120 ),
1121 msquic::ConnectionEvent::PeerStreamStarted { stream, flags } => {
1122 self.handle_event_peer_stream_started(stream, flags)
1123 }
1124 msquic::ConnectionEvent::StreamsAvailable {
1125 bidirectional_count,
1126 unidirectional_count,
1127 } => self.handle_event_streams_available(bidirectional_count, unidirectional_count),
1128 msquic::ConnectionEvent::DatagramStateChanged {
1129 send_enabled,
1130 max_send_length,
1131 } => self.handle_event_datagram_state_changed(send_enabled, max_send_length),
1132 msquic::ConnectionEvent::DatagramReceived { buffer, flags } => {
1133 self.handle_event_datagram_received(buffer, flags)
1134 }
1135 msquic::ConnectionEvent::DatagramSendStateChanged {
1136 client_context,
1137 state,
1138 } => self.handle_event_datagram_send_state_changed(client_context, state),
1139 #[cfg(feature = "msquic-seera")]
1140 msquic::ConnectionEvent::NotifyObservedAddress {
1141 local_address,
1142 observed_address,
1143 } => self.handle_event_notify_observed_address(local_address, observed_address),
1144 #[cfg(feature = "msquic-seera")]
1145 msquic::ConnectionEvent::NotifyRemoteAddressAdded {
1146 address,
1147 sequence_number,
1148 } => self.handle_event_notify_remote_address_added(address, sequence_number),
1149 #[cfg(feature = "msquic-seera")]
1150 msquic::ConnectionEvent::PathValidated {
1151 local_address,
1152 remote_address,
1153 } => self.handle_event_path_validated(local_address, remote_address),
1154 #[cfg(feature = "msquic-seera")]
1155 msquic::ConnectionEvent::NotifyRemoteAddressRemoved { sequence_number } => {
1156 self.handle_event_notify_remote_address_removed(sequence_number)
1157 }
1158 _ => {
1159 trace!("ConnectionInner({:p}) Other callback", self);
1160 Ok(())
1161 }
1162 }
1163 }
1164}
1165impl Drop for ConnectionInner {
1166 fn drop(&mut self) {
1167 trace!("ConnectionInner({:p}) dropping", self);
1168 }
1169}
1170
1171#[derive(Debug, PartialEq)]
1172enum ConnectionState {
1173 Open,
1174 Connecting,
1175 Connected,
1176 Shutdown,
1177 ShutdownComplete,
1178}
1179
1180#[derive(Clone, Debug, PartialEq, Eq)]
1182pub enum ConnectionEvent {
1183 NotifyObservedAddress {
1185 local_address: SocketAddr,
1186 observed_address: SocketAddr,
1187 },
1188 NotifyRemoteAddressAdded {
1190 address: SocketAddr,
1191 sequence_number: u64,
1192 },
1193 PathValidated {
1195 local_address: SocketAddr,
1196 remote_address: SocketAddr,
1197 },
1198 NotifyRemoteAddressRemoved { sequence_number: u64 },
1200}
1201
1202#[derive(Debug, Error, Clone)]
1204pub enum ConnectionError {
1205 #[error("connection shutdown by transport: status {0:?}, error 0x{1:x}")]
1206 ShutdownByTransport(msquic::Status, u64),
1207 #[error("connection shutdown by peer: error 0x{0:x}")]
1208 ShutdownByPeer(u64),
1209 #[error("connection shutdown by local")]
1210 ShutdownByLocal,
1211 #[error("connection closed")]
1212 ConnectionClosed,
1213 #[error("SSL key log file already set")]
1214 SslKeyLogFileAlreadySet,
1215 #[error("other error: status {0:?}")]
1216 OtherError(msquic::Status),
1217}
1218
1219#[derive(Debug, Error, Clone)]
1221pub enum DgramReceiveError {
1222 #[error("connection not started yet")]
1223 ConnectionNotStarted,
1224 #[error("connection lost")]
1225 ConnectionLost(#[from] ConnectionError),
1226 #[error("other error: status {0:?}")]
1227 OtherError(msquic::Status),
1228}
1229
1230#[derive(Debug, Error, Clone)]
1232pub enum DgramSendError {
1233 #[error("connection not started yet")]
1234 ConnectionNotStarted,
1235 #[error("not allowed for sending dgram")]
1236 Denied,
1237 #[error("exceeded maximum data size for sending dgram")]
1238 TooBig,
1239 #[error("connection lost")]
1240 ConnectionLost(#[from] ConnectionError),
1241 #[error("other error: status {0:?}")]
1242 OtherError(msquic::Status),
1243}
1244
1245#[derive(Debug, Error, Clone)]
1247pub enum StartError {
1248 #[error("connection lost")]
1249 ConnectionLost(#[from] ConnectionError),
1250 #[error("other error: status {0:?}")]
1251 OtherError(msquic::Status),
1252}
1253
1254#[derive(Debug, Error, Clone)]
1256pub enum ShutdownError {
1257 #[error("connection not started yet")]
1258 ConnectionNotStarted,
1259 #[error("connection lost")]
1260 ConnectionLost(#[from] ConnectionError),
1261 #[error("other error: status {0:?}")]
1262 OtherError(msquic::Status),
1263}
1264
1265#[derive(Debug, Error, Clone)]
1267pub enum EventError {
1268 #[error("connection not started yet")]
1269 ConnectionNotStarted,
1270 #[error("connection lost")]
1271 ConnectionLost(#[from] ConnectionError),
1272 #[error("other error: status {0:?}")]
1273 OtherError(msquic::Status),
1274}
1275
1276pub struct ConnectionStart<'a> {
1278 conn: &'a Connection,
1279 configuration: &'a msquic::Configuration,
1280 host: &'a str,
1281 port: u16,
1282}
1283
1284impl Future for ConnectionStart<'_> {
1285 type Output = Result<(), StartError>;
1286
1287 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
1288 self.conn
1289 .poll_start(cx, self.configuration, self.host, self.port)
1290 }
1291}
1292
1293pub struct OpenOutboundStream<'a> {
1295 conn: &'a ConnectionInstance,
1296 stream_type: Option<crate::stream::StreamType>,
1297 stream: Option<crate::stream::Stream>,
1298 fail_on_blocked: bool,
1299}
1300
1301impl Future for OpenOutboundStream<'_> {
1302 type Output = Result<crate::stream::Stream, StreamStartError>;
1303
1304 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
1305 let this = self.get_mut();
1306 let OpenOutboundStream {
1307 conn,
1308 ref mut stream_type,
1309 ref mut stream,
1310 fail_on_blocked: fail_blocked,
1311 ..
1312 } = *this;
1313
1314 let mut exclusive = conn.inner.exclusive.lock().unwrap();
1315 match exclusive.state {
1316 ConnectionState::Open => {
1317 return Poll::Ready(Err(StreamStartError::ConnectionNotStarted));
1318 }
1319 ConnectionState::Connecting => {
1320 exclusive.start_waiters.push(cx.waker().clone());
1321 return Poll::Pending;
1322 }
1323 ConnectionState::Connected => {}
1324 ConnectionState::Shutdown | ConnectionState::ShutdownComplete => {
1325 return Poll::Ready(Err(StreamStartError::ConnectionLost(
1326 exclusive.error.as_ref().expect("error").clone(),
1327 )));
1328 }
1329 }
1330 if stream.is_none() {
1331 match Stream::open(&conn.msquic_conn, stream_type.take().unwrap()) {
1332 Ok(new_stream) => {
1333 *stream = Some(new_stream);
1334 }
1335 Err(e) => return Poll::Ready(Err(e)),
1336 }
1337 }
1338 stream
1339 .as_mut()
1340 .unwrap()
1341 .poll_start(cx, fail_blocked)
1342 .map(|res| res.map(|_| stream.take().unwrap()))
1343 }
1344}
1345
1346pub struct AcceptInboundStream<'a> {
1348 conn: &'a Connection,
1349}
1350
1351impl Future for AcceptInboundStream<'_> {
1352 type Output = Result<Stream, StreamStartError>;
1353
1354 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
1355 self.conn.poll_accept_inbound_stream(cx)
1356 }
1357}
1358
1359pub struct AcceptInboundUniStream<'a> {
1361 conn: &'a Connection,
1362}
1363
1364impl Future for AcceptInboundUniStream<'_> {
1365 type Output = Result<ReadStream, StreamStartError>;
1366
1367 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
1368 self.conn.poll_accept_inbound_uni_stream(cx)
1369 }
1370}