diff --git a/coverage/examples/basic.rs.html b/coverage/examples/basic.rs.html index 09b858c..238f60c 100644 --- a/coverage/examples/basic.rs.html +++ b/coverage/examples/basic.rs.html @@ -9,7 +9,7 @@
Current view:top level - examples - basic.rs
-
Date:2023-07-07 10:30:44
+
Date:2023-08-25 14:31:32
HitTotalCoverage
@@ -19,168 +19,172 @@
-
1use anyhow::{Error, Result};
-
2use fabruic::{Endpoint, KeyPair};
-
3use futures_util::{future, StreamExt, TryFutureExt};
-
4
-
5const SERVER_NAME: &str = "test";
-
6/// Some random port.
-
7const SERVER_PORT: u16 = 34857;
-
8const CLIENTS: usize = 100;
-
9
-
10#[tokio::main]
-
111#[cfg_attr(test, test)]
-
121async fn main() -> Result<()> {
-
131 // collect all tasks
-
141 let mut clients = Vec::with_capacity(CLIENTS);
-
151
-
161 // generate a certificate pair
-
171 let key_pair = KeyPair::new_self_signed(SERVER_NAME);
-
18
-
19 // build the server
-
20 // we want to do this outside to reserve the `SERVER_PORT`, otherwise spawned
-
21 // clients may take it
-
221 let mut server = Endpoint::new_server(SERVER_PORT, key_pair.clone())?;
-
231 let address = format!("quic://{}", server.local_address()?);
-
24
-
25 // start 100 clients
-
26101 for index in 0..CLIENTS {
-
27100 let address = address.clone();
-
28100 let certificate = key_pair.end_entity_certificate().clone();
-
29100
-
30100 clients.push(
-
31100 tokio::spawn(async move {
-
32 // build a client
-
33100 let client = Endpoint::new_client()?;
-
34
-
35100 let connecting = client.connect_pinned(address, &certificate, None).await?;
-
36100 println!(
-
37100 "[client:{}] Connecting to {}",
-
38100 index,
-
39100 connecting.remote_address()
-
40100 );
-
41100 let connection = connecting.accept::<()>().await?;
-
42100 println!(
-
43100 "[client:{}] Successfully connected to {}",
-
44100 index,
-
45100 connection.remote_address()
-
46100 );
-
47100 connection.close_incoming().await?;
-
48
-
49 // initiate a stream
-
50100 let (sender, mut receiver) = connection.open_stream::<String, String>(&()).await?;
-
51100 println!(
-
52100 "[client:{}] Successfully opened stream to {}",
-
53100 index,
-
54100 connection.remote_address()
-
55100 );
-
56100
-
57100 // send message
-
58100 sender.send(&format!("hello from client {}", index))?;
-
59
-
60 // start listening to new incoming messages
-
61 // in this example we know there is only 1 incoming message, so we will
-
62 // not wait for more
-
63100 let message = receiver.next().await.expect("no message found")?;
-
64100 println!(
-
65100 "[client:{}] New message from {}: {}",
-
66100 index,
-
67100 connection.remote_address(),
-
68100 message
-
69100 );
-
70100
-
71100 // wait for stream to finish
-
72100 sender.finish().await?;
-
73100 receiver.finish().await?;
-
74
-
75 // wait for client to finish cleanly
-
76100 client.wait_idle().await;
-
77100 println!(
-
78100 "[client:{}] Successfully finished {}",
-
79100 index,
-
80100 client.local_address()?
-
81 );
-
82
-
83100 Result::<_, Error>::Ok(())
-
84100 })
-
85100 .map_err(Error::from)
-
86100 .and_then(future::ready),
-
87100 );
-
88100 }
-
89
-
90 // start the server
-
911 println!("[server] Listening on {}", server.local_address()?);
-
92
-
93 // collect incoming connection tasks
-
941 let mut connections = Vec::with_capacity(CLIENTS);
-
95
-
96 // start listening to new incoming connections
-
97 // in this example we know there is `CLIENTS` number of clients, so we will not
-
98 // wait for more
-
99101 for _ in 0..CLIENTS {
-
100100 let connecting = server.next().await.expect("connection failed");
-
101100
-
102100 println!(
-
103100 "[server] New incoming Connection: {}",
-
104100 connecting.remote_address()
-
105100 );
-
106100
-
107100 // every new incoming connections is handled in it's own task
-
108100 connections.push(
-
109100 tokio::spawn(async move {
-
110100 let mut connection = connecting.accept::<()>().await?;
-
111100 println!("[server] New Connection: {}", connection.remote_address());
-
112
-
113 // start listening to new incoming streams
-
114 // in this example we know there is only 1 incoming stream, so we will not wait
-
115 // for more
-
116100 let incoming = connection.next().await.expect("no stream found")?;
-
117100 connection.close_incoming().await?;
-
118100 println!(
-
119100 "[server] New incoming stream from: {}",
-
120100 connection.remote_address()
-
121100 );
-
122
-
123 // accept stream
-
124100 let (sender, mut receiver) = incoming.accept::<String, String>().await?;
-
125
-
126 // start listening to new incoming messages
-
127 // in this example we know there is only 1 incoming message, so we will not wait
-
128 // for more
-
129100 let message = receiver.next().await.expect("no message found")?;
-
130100 println!(
-
131100 "[server] New message from {}: {}",
-
132100 connection.remote_address(),
-
133100 message
-
134100 );
-
135100
-
136100 // respond
-
137100 sender.send(&String::from("hello from server"))?;
-
138
-
139 // wait for stream to finish
-
140100 sender.finish().await?;
-
141100 receiver.finish().await?;
+
1//! TODO
+
2
+
3use anyhow::{Error, Result};
+
4use fabruic::{Endpoint, KeyPair};
+
5use futures_util::{future, StreamExt, TryFutureExt};
+
6
+
7/// Used in the certificate.
+
8const SERVER_NAME: &str = "test";
+
9/// Some random port.
+
10const SERVER_PORT: u16 = 34857;
+
11/// Number of clients to simulate.
+
12const CLIENTS: usize = 100;
+
13
+
14#[tokio::main]
+
151#[cfg_attr(test, test)]
+
161async fn main() -> Result<()> {
+
171 // collect all tasks
+
181 let mut clients = Vec::with_capacity(CLIENTS);
+
191
+
201 // generate a certificate pair
+
211 let key_pair = KeyPair::new_self_signed(SERVER_NAME);
+
22
+
23 // build the server
+
24 // we want to do this outside to reserve the `SERVER_PORT`, otherwise spawned
+
25 // clients may take it
+
261 let mut server = Endpoint::new_server(SERVER_PORT, key_pair.clone())?;
+
271 let address = format!("quic://{}", server.local_address()?);
+
28
+
29 // start 100 clients
+
30101 for index in 0..CLIENTS {
+
31100 let address = address.clone();
+
32100 let certificate = key_pair.end_entity_certificate().clone();
+
33100
+
34100 clients.push(
+
35100 tokio::spawn(async move {
+
36 // build a client
+
37100 let client = Endpoint::new_client()?;
+
38
+
39100 let connecting = client.connect_pinned(address, &certificate, None).await?;
+
40100 println!(
+
41100 "[client:{}] Connecting to {}",
+
42100 index,
+
43100 connecting.remote_address()
+
44100 );
+
45100 let connection = connecting.accept::<()>().await?;
+
46100 println!(
+
47100 "[client:{}] Successfully connected to {}",
+
48100 index,
+
49100 connection.remote_address()
+
50100 );
+
51100 connection.close_incoming().await?;
+
52
+
53 // initiate a stream
+
54100 let (sender, mut receiver) = connection.open_stream::<String, String>(&()).await?;
+
55100 println!(
+
56100 "[client:{}] Successfully opened stream to {}",
+
57100 index,
+
58100 connection.remote_address()
+
59100 );
+
60100
+
61100 // send message
+
62100 sender.send(&format!("hello from client {index}"))?;
+
63
+
64 // start listening to new incoming messages
+
65 // in this example we know there is only 1 incoming message, so we will
+
66 // not wait for more
+
67100 let message = receiver.next().await.expect("no message found")?;
+
68100 println!(
+
69100 "[client:{}] New message from {}: {}",
+
70100 index,
+
71100 connection.remote_address(),
+
72100 message
+
73100 );
+
74100
+
75100 // wait for stream to finish
+
76100 sender.finish().await?;
+
77100 receiver.finish().await?;
+
78
+
79 // wait for client to finish cleanly
+
80100 client.wait_idle().await;
+
81100 println!(
+
82100 "[client:{}] Successfully finished {}",
+
83100 index,
+
84100 client.local_address()?
+
85 );
+
86
+
87100 Result::<_, Error>::Ok(())
+
88100 })
+
89100 .map_err(Error::from)
+
90100 .and_then(future::ready),
+
91100 );
+
92100 }
+
93
+
94 // start the server
+
951 println!("[server] Listening on {}", server.local_address()?);
+
96
+
97 // collect incoming connection tasks
+
981 let mut connections = Vec::with_capacity(CLIENTS);
+
99
+
100 // start listening to new incoming connections
+
101 // in this example we know there is `CLIENTS` number of clients, so we will not
+
102 // wait for more
+
103101 for _ in 0..CLIENTS {
+
104100 let connecting = server.next().await.expect("connection failed");
+
105100
+
106100 println!(
+
107100 "[server] New incoming Connection: {}",
+
108100 connecting.remote_address()
+
109100 );
+
110100
+
111100 // every new incoming connections is handled in it's own task
+
112100 connections.push(
+
113100 tokio::spawn(async move {
+
114100 let mut connection = connecting.accept::<()>().await?;
+
115100 println!("[server] New Connection: {}", connection.remote_address());
+
116
+
117 // start listening to new incoming streams
+
118 // in this example we know there is only 1 incoming stream, so we will not wait
+
119 // for more
+
120100 let incoming = connection.next().await.expect("no stream found")?;
+
121100 connection.close_incoming().await?;
+
122100 println!(
+
123100 "[server] New incoming stream from: {}",
+
124100 connection.remote_address()
+
125100 );
+
126
+
127 // accept stream
+
128100 let (sender, mut receiver) = incoming.accept::<String, String>().await?;
+
129
+
130 // start listening to new incoming messages
+
131 // in this example we know there is only 1 incoming message, so we will not wait
+
132 // for more
+
133100 let message = receiver.next().await.expect("no message found")?;
+
134100 println!(
+
135100 "[server] New message from {}: {}",
+
136100 connection.remote_address(),
+
137100 message
+
138100 );
+
139100
+
140100 // respond
+
141100 sender.send(&String::from("hello from server"))?;
142
-
143100 Result::<_, Error>::Ok(())
-
144100 })
-
145100 .map_err(Error::from)
-
146100 .and_then(future::ready),
-
147100 );
-
148 }
-
149
-
1501 server.close_incoming().await?;
-
151
-
152 // wait for all connections to finish
-
15333 future::try_join_all(connections).await?;
-
154
-
155 // wait for server to finish cleanly
-
1561 server.wait_idle().await;
-
1571 println!("[server] Successfully finished {}", server.local_address()?);
+
143 // wait for stream to finish
+
144100 sender.finish().await?;
+
145100 receiver.finish().await?;
+
146
+
147100 Result::<_, Error>::Ok(())
+
148100 })
+
149100 .map_err(Error::from)
+
150100 .and_then(future::ready),
+
151100 );
+
152 }
+
153
+
1541 server.close_incoming().await?;
+
155
+
156 // wait for all connections to finish
+
15735 future::try_join_all(connections).await?;
158
-
15963 future::try_join_all(clients).await?;
-
160
-
1611 Ok(())
-
162}
+
159 // wait for server to finish cleanly
+
1601 server.wait_idle().await;
+
1611 println!("[server] Successfully finished {}", server.local_address()?);
+
162
+
16331 future::try_join_all(clients).await?;
+
164
+
1651 Ok(())
+
166}
diff --git a/coverage/examples/index.html b/coverage/examples/index.html index 2182245..c077ea6 100644 --- a/coverage/examples/index.html +++ b/coverage/examples/index.html @@ -9,18 +9,20 @@
Current view:top level - examples
-
Date:2023-07-07 10:30:44
+
Date:2023-08-25 14:31:32
HitTotalCoverage
-
Lines104104100.0 %
-
Functions55100.0 %
+
Lines21722496.9 %
+
Functions2525100.0 %
Branches000.0 %
FilenameLine CoverageFunctionsBranches
basic.rs100.0%104 / 104100.0%5 / 50.0%0 / 0
+
onestream.rs92.9%52 / 56100.0%7 / 70.0%0 / 0
+
twostream.rs95.3%61 / 64100.0%13 / 130.0%0 / 0
diff --git a/coverage/examples/onestream.rs.html b/coverage/examples/onestream.rs.html new file mode 100644 index 0000000..e6b8d6f --- /dev/null +++ b/coverage/examples/onestream.rs.html @@ -0,0 +1,124 @@ + + + +Grcov report —onestream.rs + + + + +
+
+
Current view:top level - examples - onestream.rs
+
Date:2023-08-25 14:31:32
+
+
+
HitTotalCoverage
+
Lines525692.9 %
+
Functions77100.0 %
+
Branches000.0 %
+
+
+
+
1//! TODO
+
2
+
3#![allow(clippy::missing_docs_in_private_items)]
+
4
+
5use anyhow::{Error, Result};
+
6use fabruic::{Endpoint, KeyPair};
+
7use futures_util::StreamExt;
+
8
+
9const SERVER_NAME: &str = "test";
+
10const SERVER_PORT: u16 = 5001;
+
11const CLIENTS: usize = 100;
+
12
+
13#[tokio::main]
+
141#[cfg_attr(test, test)]
+
151async fn main() -> Result<()> {
+
161 // generate a certificate pair
+
171 let key_pair = KeyPair::new_self_signed(SERVER_NAME);
+
18
+
19 // start the server
+
201 let server = Endpoint::new_server(SERVER_PORT, key_pair.clone())?;
+
211 let address = format!("quic://{}", server.local_address()?);
+
221 println!("[server] Listening on {address}");
+
231 tokio::spawn(run_server(server));
+
24
+
25 // build a client
+
261 let client = Endpoint::new_client()?;
+
27
+
281 let connection = client
+
291 .connect_pinned(address, key_pair.end_entity_certificate(), None)
+
300 .await?
+
311 .accept::<()>()
+
321 .await?;
+
331 connection.close_incoming().await?;
+
34
+
35 // initiate a stream
+
361 let (sender, receiver) = connection.open_stream::<String, String>(&()).await?;
+
37
+
381 let tasks = (0..CLIENTS)
+
39100 .map(|_| {
+
40100 let sender = sender.clone();
+
41100 let mut receiver = receiver.clone();
+
42 async move {
+
43100 sender.send(&String::from("test"))?;
+
44100 let value = receiver.next().await.expect("didn't get a response")?;
+
45100 assert_eq!(value, "test");
+
46100 Ok(())
+
47100 }
+
48100 })
+
491 .collect::<Vec<_>>();
+
501
+
511 futures_util::future::join_all(tasks)
+
522 .await
+
531 .into_iter()
+
541 .collect::<Result<Vec<()>, Error>>()?;
+
55
+
56 // wait for client to finish cleanly
+
571 client.wait_idle().await;
+
58
+
591 Ok(())
+
60}
+
61
+
621async fn run_server(mut server: Endpoint) -> Result<(), Error> {
+
63 // start listening to new incoming connections
+
64 // in this example we know there is `CLIENTS` number of clients, so we will not
+
65 // wait for more
+
661 let mut connection = server
+
671 .next()
+
681 .await
+
691 .expect("connection failed")
+
701 .accept::<()>()
+
711 .await?;
+
721 println!("[server] New Connection: {}", connection.remote_address());
+
73
+
74 // start listening to new incoming streams
+
75 // in this example we know there is only 1 incoming stream, so we will not wait
+
76 // for more
+
771 let incoming = connection.next().await.expect("no stream found")?;
+
781 connection.close_incoming().await?;
+
791 println!(
+
801 "[server] New incoming stream from: {}",
+
811 connection.remote_address()
+
821 );
+
83
+
84 // accept stream
+
851 let (sender, mut receiver) = incoming.accept::<String, String>().await?;
+
86
+
87 // start listening to new incoming messages
+
88 // in this example we know there is only 1 incoming message, so we will not wait
+
89 // for more
+
90101 while let Some(message) = receiver.next().await {
+
91101 let message = message?;
+
92100 sender.send(&message)?;
+
93 }
+
94
+
95 // wait for stream to finish
+
960 sender.finish().await?;
+
970 receiver.finish().await?;
+
98
+
990 Ok(())
+
1001}
+
+ + diff --git a/coverage/examples/twostream.rs.html b/coverage/examples/twostream.rs.html new file mode 100644 index 0000000..b89d951 --- /dev/null +++ b/coverage/examples/twostream.rs.html @@ -0,0 +1,139 @@ + + + +Grcov report —twostream.rs + + + + +
+
+
Current view:top level - examples - twostream.rs
+
Date:2023-08-25 14:31:32
+
+
+
HitTotalCoverage
+
Lines616495.3 %
+
Functions1313100.0 %
+
Branches000.0 %
+
+
+
+
1//! TODO
+
2
+
3#![allow(clippy::missing_docs_in_private_items)]
+
4
+
5use anyhow::{Error, Result};
+
6use fabruic::{Endpoint, Incoming, KeyPair};
+
7use futures_util::StreamExt;
+
8
+
9const SERVER_NAME: &str = "test";
+
10const SERVER_PORT: u16 = 5002;
+
11const REQUESTS_PER_STREAM: usize = 10;
+
12const STREAMS: usize = 1000;
+
13
+
14#[tokio::main(worker_threads = 16)]
+
151#[cfg_attr(test, test)]
+
161async fn main() -> Result<()> {
+
171 // generate a certificate pair
+
181 let key_pair = KeyPair::new_self_signed(SERVER_NAME);
+
19
+
20 // start the server
+
211 let server = Endpoint::new_server(SERVER_PORT, key_pair.clone())?;
+
221 let address = format!("quic://{}", server.local_address()?);
+
231 println!("[server] Listening on {address}");
+
241 tokio::spawn(run_server(server));
+
25
+
26 // build a client
+
271 let client = Endpoint::new_client()?;
+
28
+
291 let connection = client
+
301 .connect_pinned(address, key_pair.end_entity_certificate(), None)
+
310 .await?
+
321 .accept::<()>()
+
331 .await?;
+
341 connection.close_incoming().await?;
+
35
+
36 // initiate a stream
+
37
+
381 let tasks = (0..STREAMS)
+
391000 .map(|_| async {
+
406870 let (sender, receiver) = connection.open_stream::<String, String>(&()).await.unwrap();
+
4110000 (0..REQUESTS_PER_STREAM).for_each(|_| {
+
4210000 let sender = sender.clone();
+
4310000 let mut receiver = receiver.clone();
+
4410000 tokio::task::spawn(async move {
+
4510000 sender.send(&String::from("test"))?;
+
4610695 let value = receiver.next().await.expect("didn't get a response")?;
+
4710000 assert_eq!(value, "test");
+
4810000 Result::<(), Error>::Ok(())
+
4910000 });
+
5010000 });
+
511000 Ok(())
+
521000 })
+
531 .collect::<Vec<_>>();
+
541
+
551 futures_util::future::join_all(tasks)
+
5628 .await
+
571 .into_iter()
+
581 .collect::<Result<Vec<()>, Error>>()
+
591 .unwrap();
+
601
+
611 // wait for client to finish cleanly
+
621 client.wait_idle().await;
+
63
+
641 Ok(())
+
65}
+
66
+
671async fn run_server(mut server: Endpoint) -> Result<(), Error> {
+
68 // start listening to new incoming connections
+
69 // in this example we know there is `CLIENTS` number of clients, so we will not
+
70 // wait for more
+
712 while let Some(connection) = server.next().await {
+
721 let connection = connection.accept::<()>().await?;
+
731 println!("[server] New Connection: {}", connection.remote_address());
+
741
+
751 // every new incoming connections is handled in it's own task
+
761 tokio::spawn(run_connection(connection));
+
77 }
+
78
+
790 Ok(())
+
800}
+
81
+
821async fn run_connection(mut connection: fabruic::Connection<()>) -> Result<(), Error> {
+
83 // start listening to new incoming streams
+
84 // in this example we know there is only 1 incoming stream, so we will not wait
+
85 // for more
+
861001 while let Some(incoming) = connection.next().await {
+
87 // connection.close_incoming().await?;
+
88 /*println!(
+
89 "[server] New incoming stream from: {}",
+
90 connection.remote_address()
+
91 );*/
+
92
+
931000 tokio::spawn(run_stream(incoming?));
+
94 }
+
95
+
961 Ok(())
+
971}
+
98
+
991000async fn run_stream(incoming: Incoming<()>) -> Result<(), Error> {
+
1001000 let (sender, mut receiver) = incoming.accept::<String, String>().await?;
+
101
+
102 // start listening to new incoming messages
+
103 // in this example we know there is only 1 incoming message, so we will not wait
+
104 // for more
+
10511000 while let Some(message) = receiver.next().await {
+
10610000 let message = message?;
+
10710000 sender.send(&message)?;
+
108 }
+
109
+
110 // wait for stream to finish
+
1111000 sender.finish().await?;
+
1121000 receiver.finish().await?;
+
113
+
1141000 Ok(())
+
1151000}
+
+ + diff --git a/coverage/index.html b/coverage/index.html index 0aedce5..8387f20 100644 --- a/coverage/index.html +++ b/coverage/index.html @@ -9,24 +9,24 @@
Current view:top level
-
Date:2023-07-07 10:30:44
+
Date:2023-08-25 14:31:32
HitTotalCoverage
-
Lines1721217679.1 %
-
Functions44699944.6 %
+
Lines1851230980.2 %
+
Functions610119551.0 %
Branches000.0 %
DirectoryLine CoverageFunctionsBranches
-
examples100.0%104 / 104100.0%5 / 50.0%0 / 0
-
src23.1%9 / 391.2%2 / 1640.0%0 / 0
-
src/quic97.1%101 / 10483.6%56 / 670.0%0 / 0
-
src/quic/connection78.4%298 / 38040.5%98 / 2420.0%0 / 0
-
src/quic/endpoint91.4%392 / 42972.5%79 / 1090.0%0 / 0
-
src/quic/endpoint/builder92.3%579 / 62757.4%113 / 1970.0%0 / 0
-
src/x50973.9%238 / 32244.9%93 / 2070.0%0 / 0
+
examples96.9%217 / 224100.0%25 / 250.0%0 / 0
+
src21.4%9 / 421.8%3 / 1640.0%0 / 0
+
src/quic97.1%101 / 10481.7%76 / 930.0%0 / 0
+
src/quic/connection80.7%305 / 37854.6%200 / 3660.0%0 / 0
+
src/quic/endpoint91.2%394 / 43272.4%89 / 1230.0%0 / 0
+
src/quic/endpoint/builder92.3%584 / 63357.4%113 / 1970.0%0 / 0
+
src/x50974.2%241 / 32547.5%104 / 2190.0%0 / 0
target/debug/build/oid-registry-94bd6a17a18236d5/out0.0%0 / 1710.0%0 / 80.0%0 / 0
diff --git a/coverage/src/error.rs.html b/coverage/src/error.rs.html index 8532174..e01de84 100644 --- a/coverage/src/error.rs.html +++ b/coverage/src/error.rs.html @@ -9,289 +9,284 @@
Current view:top level - src - error.rs
-
Date:2023-07-07 10:30:44
+
Date:2023-08-25 14:31:32
HitTotalCoverage
-
Lines93923.1 %
-
Functions21641.2 %
+
Lines94221.4 %
+
Functions31641.8 %
Branches000.0 %
-
1#![allow(
-
2 box_pointers,
-
3 clippy::module_name_repetitions,
-
4 clippy::exhaustive_structs
-
5)]
-
6
-
7//! [`Error`](std::error::Error) for this [`crate`].
-
8// TODO: error type is becoming too big, split it up
-
9
-
10use std::{
-
11 fmt::{self, Debug, Formatter},
-
12 io,
-
13};
-
14
-
15pub use bincode::ErrorKind;
-
16use quinn::ConnectionClose;
-
17pub use quinn::{ConnectError, ConnectionError, ReadError, WriteError};
-
18use thiserror::Error;
-
19#[cfg(feature = "trust-dns")]
-
20#[cfg_attr(doc, doc(cfg(feature = "trust-dns")))]
-
21pub use trust_dns_resolver::error::ResolveError;
-
22pub use url::ParseError;
-
23pub use webpki::Error;
-
24pub use x509_parser::{error::X509Error, nom::Err};
-
25use zeroize::Zeroize;
-
26
-
27/// Error constructing [`Certificate`](crate::Certificate) with
-
28/// [`Certificate::from_der`](crate::Certificate::from_der).
-
290#[derive(Clone, Debug, Error, PartialEq)]
-
30#[error("Error constructing `Certificate` from bytes: {error}")]
-
31pub struct Certificate {
-
32 /// The error.
-
33 #[source]
-
34 pub error: CertificateError,
-
35 /// The bytes used to build the [`Certificate`](crate::Certificate).
-
36 pub certificate: Vec<u8>,
-
37}
-
38
-
39/// Error constructing [`Certificate`](crate::Certificate) with
-
40/// [`Certificate::from_der`](crate::Certificate::from_der).
-
41#[allow(clippy::module_name_repetitions)]
-
420#[derive(Clone, Debug, Error, PartialEq)]
-
43pub enum CertificateError {
-
44 /// [`Error`](std::error::Error) returned by [`webpki`].
-
45 #[error(transparent)]
-
46 WebPki(Error),
-
47 /// [`Error`](std::error::Error) returned by [`x509_parser`].
-
48 #[error(transparent)]
-
49 X509(Err<X509Error>),
-
50 /// Bytes passed contain uncorrelated bytes.
-
51 #[error("Found dangling bytes in `Certificate`")]
-
52 Dangling(Vec<u8>),
-
53 /// [`Certificate`](crate::Certificate) has expired.
-
54 #[error("`Certificate` has expired")]
-
55 Expired,
-
56 /// [`Certificate`](crate::Certificate) is missing a domain name.
-
57 #[error("`Certificate` is missing a domain name")]
-
58 Domain,
-
59}
-
60
-
61/// Failed to parse the given private key with
-
62/// [`PrivateKey::from_der`](crate::PrivateKey::from_der).
-
630#[derive(Clone, Eq, Error, Hash, Ord, PartialEq, PartialOrd, Zeroize)]
-
64#[error("Failed parsing private key")]
-
65#[zeroize(drop)]
-
66pub struct PrivateKey(pub Vec<u8>);
-
67
-
68impl Debug for PrivateKey {
-
690 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-
700 f.debug_tuple("PrivateKey").field(&"[[redacted]]").finish()
-
710 }
-
72}
-
73
-
74/// Failed to pair given [`CertificateChain`](crate::CertificateChain) and
-
75/// [`PrivateKey`](crate::PrivateKey) with
-
76/// [`KeyPair::from_parts`](crate::KeyPair::from_parts).
-
770#[derive(Clone, Debug, Eq, Error, Hash, Ord, PartialEq, PartialOrd)]
-
78#[error("Failed pairing `Certificate` and `PrivateKey`")]
-
79pub struct KeyPair {
-
80 /// [`CertificateChain`](crate::CertificateChain).
-
81 certificate: crate::CertificateChain,
-
82 /// [`PrivateKey`](crate::PrivateKey).
-
83 private_key: crate::PrivateKey,
-
84}
-
85
-
86/// Failed to verify the certificate chain with
-
87/// [`CertificateChain::from_certificates`].
-
88///
-
89/// [`CertificateChain::from_certificates`]:
-
90/// crate::CertificateChain::from_certificates
-
910#[derive(Clone, Debug, Eq, Error, Hash, Ord, PartialEq, PartialOrd)]
-
92#[error("Failed verifiying certificate chhain")]
-
93pub struct CertificateChain(Vec<crate::Certificate>);
-
94
-
95/// Attempting to close something that is already closed.
-
960#[derive(Clone, Copy, Debug, Eq, Error, Hash, Ord, PartialEq, PartialOrd)]
-
97#[error("This is already closed")]
-
98pub struct AlreadyClosed;
-
99
-
100/// Error during construction of [`Endpoint`](crate::Endpoint)
-
101/// with [`Builder::build`](crate::Builder::build).
-
1020#[derive(Debug, Error)]
-
1030#[error("Error constructing `Endpoint` with `Builder`: {error}")]
-
104pub struct Builder {
-
105 /// Configuration error.
-
106 #[source]
-
107 pub error: Config,
-
108 /// Recovered [`Builder`](crate::Builder) for re-use.
-
109 pub builder: crate::Builder,
-
110}
-
111
-
112/// Configuration error.
-
1130#[derive(Debug, Error)]
-
1140pub enum Config {
-
115 /// The error binding [`Endpoint`](crate::Endpoint).
-
116 #[error("Error binding socket during construction of `Endpoint`: {0}")]
-
117 Bind(io::Error),
-
118 /// Error aquiring or parsing root certificates from the OS.
-
119 #[error(transparent)]
-
120 NativeCert(#[from] OsStore),
-
121 /// Returned when timeout chosen is equal or bigger than 2^62 ms.
-
122 #[error("Invalid timeout, can't exceed 2^62 ms")]
-
123 MaxIdleTimeout,
-
124}
-
125
-
126/// Error aquiring or parsing root certs from OS.
-
1270#[derive(Debug, Error)]
-
1280#[allow(variant_size_differences)]
-
129pub enum OsStore {
-
130 /// Failed to aquire root certs from OS.
-
131 #[error("Error aquiring root certificates from the OS: {0}")]
-
132 Aquire(io::Error),
-
133 /// Failed to parse root certs from OS.
-
134 #[error("Error parsing root certificates from the OS: {0}")]
-
135 Parse(Error),
-
136}
-
137
-
138/// Error connecting to a server with
-
139/// [`Endpoint::connect`](crate::Endpoint::connect).
-
1400#[derive(Debug, Error)]
-
1410pub enum Connect {
-
142 /// The passed [`Certificate`](crate::Certificate) has multiple domains,
-
143 /// this is not supported with
-
144 /// [`Endpoint::connect_pinned`](crate::Endpoint::connect_pinned).
-
145 #[error(
-
146 "Using a `Certificate` with multiple domains for connecting with a pinned server \
-
147 certificate is not supported"
-
148 )]
-
149 MultipleDomains,
-
150 /// Failed to parse URL.
-
151 #[error("Error parsing URL: {0}")]
-
152 ParseUrl(ParseError),
-
153 /// URL didn't contain a domain.
-
154 #[error("URL without a domain is invalid")]
-
155 Domain,
-
156 /// URL didn't contain a port.
-
157 #[error("URL without a port is invalid")]
-
158 Port,
-
159 /// Failed to parse domain.
-
160 #[error("Error parsing domain: {0}")]
-
161 ParseDomain(ParseError),
-
162 /// Failed to resolve domain with [`trust-dns`](trust_dns_resolver).
-
163 #[cfg(feature = "trust-dns")]
-
164 #[cfg_attr(doc, doc(cfg(feature = "trust-dns")))]
-
165 #[error("Error resolving domain with trust-dns: {0}")]
-
166 TrustDns(#[from] Box<ResolveError>),
-
167 /// Failed to resolve domain with
-
168 /// [`ToSocketAddrs`](std::net::ToSocketAddrs).
-
169 #[error("Error resolving domain with `ToSocketAddrs`: {0}")]
-
170 StdDns(io::Error),
-
171 /// Found no IP address for that domain.
-
172 #[error("Found no IP address for that domain")]
-
173 NoIp,
-
174 /// Configuration needed to connect to a server is faulty.
-
175 #[error("Error in configuration to connect to server: {0}")]
-
176 ConnectConfig(#[from] ConnectError),
-
177 /// Configuration faulty.
-
178 #[error("Error in configuration: {0}")]
-
179 Config(#[from] Config),
-
180}
-
181
-
182/// Error receiving stream from peer with [`Stream`](futures_util::Stream)
-
183/// on from [`Connection`](crate::Connection).
-
1840#[derive(Clone, Debug, Eq, Error, PartialEq)]
-
185#[error("Error receiving connection from peer: {0}")]
-
186pub struct Connection(pub ConnectionError);
-
187
-
188/// Error completing connection with peer with
-
189/// [`Incoming::type`](crate::Incoming::type) or
-
190/// [`Incoming::accept`](crate::Incoming::accept).
-
1910#[derive(Clone, Debug, Eq, Error, PartialEq)]
-
192pub enum Connecting {
-
193 /// The peer did not accept any of the protocols specified.
-
194 #[error("Peer failed to negotiate a protocol")]
-
195 ProtocolMismatch,
-
196 /// An error completing the connection.
-
197 #[error("Error completing connection with peer: {0}")]
-
198 Connection(ConnectionError),
-
199}
-
200
-
201impl From<ConnectionError> for Connecting {
-
202 fn from(err: ConnectionError) -> Self {
-
2032 match err {
-
204 ConnectionError::ConnectionClosed(ConnectionClose {
-
2051 error_code,
-
2061 frame_type: None,
-
2071 reason,
-
2082 }) if reason.as_ref() == b"peer doesn't support any known protocol"
-
2091 && error_code.to_string() == "the cryptographic handshake failed: error 120" =>
-
2101 Self::ProtocolMismatch,
-
2114 other => Self::Connection(other),
-
212 }
-
2135 }
-
214}
-
215
-
216/// Error opening a new stream to peer with
-
217/// [`Connection::open_stream`](crate::Connection::open_stream).
-
2180#[derive(Debug, Error)]
-
2190pub enum Stream {
-
220 /// Opening a new stream with
-
221 /// [`Connection::open_stream`](crate::Connection::open_stream) failed.
-
222 #[error("Error opening a new stream to peer: {0}")]
-
223 Open(#[from] ConnectionError),
-
224 /// Sending the type information to peer failed.
-
225 #[error("Error sending type information to peer: {0}")]
-
226 Sender(#[from] Sender),
-
227}
-
228
-
229/// Error receiving type information from [`Incoming`](crate::Incoming) stream.
-
2300#[derive(Debug, Error)]
-
2310pub enum Incoming {
-
232 /// Failed receiving type information from [`Incoming`](crate::Incoming)
-
233 /// stream.
-
234 #[error("Error receiving type information from `Incoming` stream: {0}")]
-
235 Receiver(Receiver),
-
236 /// [`Incoming`](crate::Incoming) was closed before type information could
-
237 /// be received.
-
238 #[error("Incoming stream was closed")]
-
239 Closed,
-
240}
-
241
-
242/// Error receiving a message from a [`Receiver`](crate::Receiver).
-
2430#[derive(Debug, Error)]
-
2440pub enum Receiver {
-
245 /// Failed to read from a [`Receiver`](crate::Receiver).
-
246 #[error("Error reading from `Receiver`: {0}")]
-
247 Read(#[from] ReadError),
-
248 /// Failed to [`Deserialize`](serde::Deserialize) a message from a
-
249 /// [`Receiver`](crate::Receiver).
-
250 #[error("Error deserializing a message from `Receiver`: {0}")]
-
251 Deserialize(#[from] ErrorKind),
-
252}
-
253
-
254/// Error sending a message to a [`Sender`](crate::Sender).
-
2550#[derive(Debug, Error)]
-
2560pub enum Sender {
-
257 /// Failed to [`Serialize`](serde::Serialize) a message for a
-
258 /// [`Sender`](crate::Sender).
-
259 #[error("Error serializing a message to `Sender`: {0}")]
-
260 Serialize(ErrorKind),
-
261 /// Failed to write to a [`Sender`](crate::Sender).
-
262 #[error("Error writing to `Sender`: {0}")]
-
263 Write(#[from] WriteError),
-
264 /// [`Sender`] is closed.
-
265 #[error(transparent)]
-
266 Closed(#[from] AlreadyClosed),
-
267}
-
268
-
269impl From<Box<ErrorKind>> for Sender {
-
2700 fn from(error: Box<ErrorKind>) -> Self {
-
2710 Self::Serialize(*error)
-
2720 }
-
273}
+
1#![allow(clippy::module_name_repetitions)]
+
2
+
3//! [`Error`](std::error::Error) for this [`crate`].
+
4// TODO: error type is becoming too big, split it up
+
5
+
6use std::{
+
7 fmt::{self, Debug, Formatter},
+
8 io,
+
9};
+
10
+
11pub use bincode::ErrorKind;
+
12use quinn::ConnectionClose;
+
13pub use quinn::{ConnectError, ConnectionError, ReadError, WriteError};
+
14use thiserror::Error;
+
15#[cfg(feature = "trust-dns")]
+
16pub use trust_dns_resolver::error::ResolveError;
+
17pub use url::ParseError;
+
18pub use webpki::Error;
+
19pub use x509_parser::{error::X509Error, nom::Err};
+
20use zeroize::Zeroize;
+
21
+
22/// Error constructing [`Certificate`](crate::Certificate) with
+
23/// [`Certificate::from_der`](crate::Certificate::from_der).
+
240#[derive(Clone, Debug, Error, PartialEq)]
+
25#[error("Error constructing `Certificate` from bytes: {error}")]
+
26pub struct Certificate {
+
27 /// The error.
+
28 #[source]
+
29 pub error: CertificateError,
+
30 /// The bytes used to build the [`Certificate`](crate::Certificate).
+
31 pub certificate: Vec<u8>,
+
32}
+
33
+
34/// Error constructing [`Certificate`](crate::Certificate) with
+
35/// [`Certificate::from_der`](crate::Certificate::from_der).
+
360#[derive(Clone, Debug, Error, PartialEq)]
+
37pub enum CertificateError {
+
38 /// [`Error`](std::error::Error) returned by [`webpki`].
+
39 #[error(transparent)]
+
40 WebPki(Error),
+
41 /// [`Error`](std::error::Error) returned by [`x509_parser`].
+
42 #[error(transparent)]
+
43 X509(Err<X509Error>),
+
44 /// Bytes passed contain uncorrelated bytes.
+
45 #[error("Found dangling bytes in `Certificate`")]
+
46 Dangling(Vec<u8>),
+
47 /// [`Certificate`](crate::Certificate) has expired.
+
48 #[error("`Certificate` has expired")]
+
49 Expired,
+
50 /// [`Certificate`](crate::Certificate) is missing a domain name.
+
51 #[error("`Certificate` is missing a domain name")]
+
52 Domain,
+
53}
+
54
+
55/// Failed to parse the given private key with
+
56/// [`PrivateKey::from_der`](crate::PrivateKey::from_der).
+
570#[derive(Clone, Eq, Error, Hash, Ord, PartialEq, PartialOrd, Zeroize)]
+
58#[error("Failed parsing private key")]
+
59#[zeroize(drop)]
+
60pub struct PrivateKey(pub Vec<u8>);
+
61
+
62impl Debug for PrivateKey {
+
630 fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
+
640 formatter
+
650 .debug_tuple("PrivateKey")
+
660 .field(&"[[redacted]]")
+
670 .finish()
+
680 }
+
69}
+
70
+
71/// Failed to pair given [`CertificateChain`](crate::CertificateChain) and
+
72/// [`PrivateKey`](crate::PrivateKey) with
+
73/// [`KeyPair::from_parts`](crate::KeyPair::from_parts).
+
740#[derive(Clone, Debug, Eq, Error, Hash, Ord, PartialEq, PartialOrd)]
+
75#[error("Failed pairing `Certificate` and `PrivateKey`")]
+
76pub struct KeyPair {
+
77 /// [`CertificateChain`](crate::CertificateChain).
+
78 certificate: crate::CertificateChain,
+
79 /// [`PrivateKey`](crate::PrivateKey).
+
80 private_key: crate::PrivateKey,
+
81}
+
82
+
83/// Failed to verify the certificate chain with
+
84/// [`CertificateChain::from_certificates`].
+
85///
+
86/// [`CertificateChain::from_certificates`]:
+
87/// crate::CertificateChain::from_certificates
+
880#[derive(Clone, Debug, Eq, Error, Hash, Ord, PartialEq, PartialOrd)]
+
89#[error("Failed verifiying certificate chhain")]
+
90pub struct CertificateChain(Vec<crate::Certificate>);
+
91
+
92/// Attempting to close something that is already closed.
+
930#[derive(Clone, Copy, Debug, Eq, Error, Hash, Ord, PartialEq, PartialOrd)]
+
94#[error("This is already closed")]
+
95pub struct AlreadyClosed;
+
96
+
97/// Error during construction of [`Endpoint`](crate::Endpoint)
+
98/// with [`Builder::build`](crate::Builder::build).
+
990#[derive(Debug, Error)]
+
1000#[error("Error constructing `Endpoint` with `Builder`: {error}")]
+
101pub struct Builder {
+
102 /// Configuration error.
+
103 #[source]
+
104 pub error: Config,
+
105 /// Recovered [`Builder`](crate::Builder) for re-use.
+
106 pub builder: crate::Builder,
+
107}
+
108
+
109/// Configuration error.
+
1100#[derive(Debug, Error)]
+
1110pub enum Config {
+
112 /// The error binding [`Endpoint`](crate::Endpoint).
+
113 #[error("Error binding socket during construction of `Endpoint`: {0}")]
+
114 Bind(io::Error),
+
115 /// Error aquiring or parsing root certificates from the OS.
+
116 #[error(transparent)]
+
117 NativeCert(#[from] OsStore),
+
118 /// Returned when timeout chosen is equal or bigger than 2^62 ms.
+
119 #[error("Invalid timeout, can't exceed 2^62 ms")]
+
120 MaxIdleTimeout,
+
121}
+
122
+
123/// Error aquiring or parsing root certs from OS.
+
1240#[derive(Debug, Error)]
+
1250pub enum OsStore {
+
126 /// Failed to aquire root certs from OS.
+
127 #[error("Error aquiring root certificates from the OS: {0}")]
+
128 Aquire(io::Error),
+
129 /// Failed to parse root certs from OS.
+
130 #[error("Error parsing root certificates from the OS: {0}")]
+
131 Parse(Error),
+
132}
+
133
+
134/// Error connecting to a server with
+
135/// [`Endpoint::connect`](crate::Endpoint::connect).
+
1360#[derive(Debug, Error)]
+
1370pub enum Connect {
+
138 /// The passed [`Certificate`](crate::Certificate) has multiple domains,
+
139 /// this is not supported with
+
140 /// [`Endpoint::connect_pinned`](crate::Endpoint::connect_pinned).
+
141 #[error(
+
142 "Using a `Certificate` with multiple domains for connecting with a pinned server \
+
143 certificate is not supported"
+
144 )]
+
145 MultipleDomains,
+
146 /// Failed to parse URL.
+
147 #[error("Error parsing URL: {0}")]
+
148 ParseUrl(ParseError),
+
149 /// URL didn't contain a domain.
+
150 #[error("URL without a domain is invalid")]
+
151 Domain,
+
152 /// URL didn't contain a port.
+
153 #[error("URL without a port is invalid")]
+
154 Port,
+
155 /// Failed to parse domain.
+
156 #[error("Error parsing domain: {0}")]
+
157 ParseDomain(ParseError),
+
158 /// Failed to resolve domain with [`trust-dns`](trust_dns_resolver).
+
159 #[cfg(feature = "trust-dns")]
+
160 #[error("Error resolving domain with trust-dns: {0}")]
+
161 TrustDns(#[from] Box<ResolveError>),
+
162 /// Failed to resolve domain with
+
163 /// [`ToSocketAddrs`](std::net::ToSocketAddrs).
+
164 #[error("Error resolving domain with `ToSocketAddrs`: {0}")]
+
165 StdDns(io::Error),
+
166 /// Found no IP address for that domain.
+
167 #[error("Found no IP address for that domain")]
+
168 NoIp,
+
169 /// Configuration needed to connect to a server is faulty.
+
170 #[error("Error in configuration to connect to server: {0}")]
+
171 ConnectConfig(#[from] ConnectError),
+
172 /// Configuration faulty.
+
173 #[error("Error in configuration: {0}")]
+
174 Config(#[from] Config),
+
175}
+
176
+
177/// Error receiving stream from peer with [`Stream`](futures_util::Stream)
+
178/// on from [`Connection`](crate::Connection).
+
1790#[derive(Clone, Debug, Eq, Error, PartialEq)]
+
180#[error("Error receiving connection from peer: {0}")]
+
181pub struct Connection(pub ConnectionError);
+
182
+
183/// Error completing connection with peer with
+
184/// [`Incoming::type`](crate::Incoming::type) or
+
185/// [`Incoming::accept`](crate::Incoming::accept).
+
1860#[derive(Clone, Debug, Eq, Error, PartialEq)]
+
187pub enum Connecting {
+
188 /// The peer did not accept any of the protocols specified.
+
189 #[error("Peer failed to negotiate a protocol")]
+
190 ProtocolMismatch,
+
191 /// An error completing the connection.
+
192 #[error("Error completing connection with peer: {0}")]
+
193 Connection(ConnectionError),
+
194}
+
195
+
196impl From<ConnectionError> for Connecting {
+
197 fn from(err: ConnectionError) -> Self {
+
1982 match err {
+
199 ConnectionError::ConnectionClosed(ConnectionClose {
+
2001 error_code,
+
2011 frame_type: None,
+
2021 reason,
+
2032 }) if reason.as_ref() == b"peer doesn't support any known protocol"
+
2041 && error_code.to_string() == "the cryptographic handshake failed: error 120" =>
+
2051 Self::ProtocolMismatch,
+
2064 other => Self::Connection(other),
+
207 }
+
2085 }
+
209}
+
210
+
211/// Error opening a new stream to peer with
+
212/// [`Connection::open_stream`](crate::Connection::open_stream).
+
2130#[derive(Debug, Error)]
+
2140pub enum Stream {
+
215 /// Opening a new stream with
+
216 /// [`Connection::open_stream`](crate::Connection::open_stream) failed.
+
217 #[error("Error opening a new stream to peer: {0}")]
+
218 Open(#[from] ConnectionError),
+
219 /// Sending the type information to peer failed.
+
220 #[error("Error sending type information to peer: {0}")]
+
221 Sender(#[from] Sender),
+
222}
+
223
+
224/// Error receiving type information from [`Incoming`](crate::Incoming) stream.
+
2250#[derive(Debug, Error)]
+
2260pub enum Incoming {
+
227 /// Failed receiving type information from [`Incoming`](crate::Incoming)
+
228 /// stream.
+
229 #[error("Error receiving type information from `Incoming` stream: {0}")]
+
230 Receiver(Receiver),
+
231 /// [`Incoming`](crate::Incoming) was closed before type information could
+
232 /// be received.
+
233 #[error("Incoming stream was closed")]
+
234 Closed,
+
235}
+
236
+
237/// Error receiving a message from a [`Receiver`](crate::Receiver).
+
2380#[derive(Debug, Error)]
+
2390pub enum Receiver {
+
240 /// Failed to read from a [`Receiver`](crate::Receiver).
+
241 #[error("Error reading from `Receiver`: {0}")]
+
242 Read(#[from] ReadError),
+
243 /// Failed to [`Deserialize`](serde::Deserialize) a message from a
+
244 /// [`Receiver`](crate::Receiver).
+
245 #[error("Error deserializing a message from `Receiver`: {0}")]
+
246 Deserialize(#[from] ErrorKind),
+
247}
+
248
+
249/// Error sending a message to a [`Sender`](crate::Sender).
+
2500#[derive(Debug, Error)]
+
2510pub enum Sender {
+
252 /// Failed to [`Serialize`](serde::Serialize) a message for a
+
253 /// [`Sender`](crate::Sender).
+
254 #[error("Error serializing a message to `Sender`: {0}")]
+
255 Serialize(ErrorKind),
+
256 /// Failed to write to a [`Sender`](crate::Sender).
+
257 #[error("Error writing to `Sender`: {0}")]
+
258 Write(#[from] WriteError),
+
259 /// [`Sender`] is closed.
+
260 #[error(transparent)]
+
261 Closed(#[from] AlreadyClosed),
+
262}
+
263
+
264impl From<Box<ErrorKind>> for Sender {
+
2650 fn from(error: Box<ErrorKind>) -> Self {
+
2660 Self::Serialize(*error)
+
2670 }
+
268}
diff --git a/coverage/src/index.html b/coverage/src/index.html index 61c6291..b98598e 100644 --- a/coverage/src/index.html +++ b/coverage/src/index.html @@ -9,18 +9,18 @@
Current view:top level - src
-
Date:2023-07-07 10:30:44
+
Date:2023-08-25 14:31:32
HitTotalCoverage
-
Lines93923.1 %
-
Functions21641.2 %
+
Lines94221.4 %
+
Functions31641.8 %
Branches000.0 %
FilenameLine CoverageFunctionsBranches
-
error.rs23.1%9 / 391.2%2 / 1640.0%0 / 0
+
error.rs21.4%9 / 421.8%3 / 1640.0%0 / 0
diff --git a/coverage/src/quic/connection/connecting.rs.html b/coverage/src/quic/connection/connecting.rs.html index 9c7f8b0..2c9496b 100644 --- a/coverage/src/quic/connection/connecting.rs.html +++ b/coverage/src/quic/connection/connecting.rs.html @@ -9,12 +9,12 @@
Current view:top level - src/quic/connection - connecting.rs
-
Date:2023-07-07 10:30:44
+
Date:2023-08-25 14:31:32
HitTotalCoverage
Lines242596.0 %
-
Functions112055.0 %
+
Functions152462.5 %
Branches000.0 %
@@ -36,9 +36,9 @@
15
16impl Connecting {
17 /// Builds a new [`Connecting`].
-
18230 pub(in crate::quic) const fn new(connecting: quinn::Connecting) -> Self {
-
19230 Self(connecting)
-
20230 }
+
18642 pub(in crate::quic) const fn new(connecting: quinn::Connecting) -> Self {
+
19642 Self(connecting)
+
20642 }
21
22 /// The negotiated application protocol. See
23 /// [`Builder::set_protocols`](crate::Builder::set_protocols).
@@ -59,23 +59,23 @@
38 /// The peer's address. Clients may change addresses at will, e.g. when
39 /// switching to a cellular internet connection.
40 #[must_use]
-
41200 pub fn remote_address(&self) -> SocketAddr {
-
42200 self.0.remote_address()
-
43200 }
+
41600 pub fn remote_address(&self) -> SocketAddr {
+
42600 self.0.remote_address()
+
43600 }
44
45 /// Accept the [`Connection`] with the given `T` as the type negotiator for
46 /// new streams.
47 ///
48 /// # Errors
49 /// [`error::Connecting`] if the [`Connection`] failed to be established.
-
50226 pub async fn accept<T: DeserializeOwned + Serialize + Send + 'static>(
-
51226 self,
-
52226 ) -> Result<Connection<T>, error::Connecting> {
-
53226 self.0
-
54225 .await
-
55226 .map(Connection::new)
-
56226 .map_err(error::Connecting::from)
-
57226 }
+
50230 pub async fn accept<T: DeserializeOwned + Serialize + Send + 'static>(
+
51230 self,
+
52230 ) -> Result<Connection<T>, error::Connecting> {
+
53230 self.0
+
54229 .await
+
55230 .map(Connection::new)
+
56230 .map_err(error::Connecting::from)
+
57230 }
58}
diff --git a/coverage/src/quic/connection/incoming.rs.html b/coverage/src/quic/connection/incoming.rs.html index 3289a97..c33e1c0 100644 --- a/coverage/src/quic/connection/incoming.rs.html +++ b/coverage/src/quic/connection/incoming.rs.html @@ -9,12 +9,12 @@
Current view:top level - src/quic/connection - incoming.rs
-
Date:2023-07-07 10:30:44
+
Date:2023-08-25 14:31:32
HitTotalCoverage
-
Lines255347.2 %
-
Functions52025.0 %
+
Lines264953.1 %
+
Functions112839.3 %
Branches000.0 %
@@ -43,90 +43,86 @@
22}
23
24impl<T: DeserializeOwned> Debug for Incoming<T> {
-
250 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-
260 f.debug_struct("Incoming")
-
270 .field("sender", &self.sender)
-
280 .field("receiver", &"ReceiverStream")
-
290 .field("type", &"Option<Result<T>>")
-
300 .finish()
-
310 }
-
32}
-
33
-
34impl<T: DeserializeOwned> Incoming<T> {
-
35 /// Builds a new [`Incoming`] from raw [`quinn`] types.
-
36101 pub(super) fn new(sender: SendStream, receiver: RecvStream) -> Self {
-
37101 Self {
-
38101 sender,
-
39101 receiver: ReceiverStream::new(receiver),
-
40101 r#type: None,
-
41101 }
-
42101 }
-
43
-
44 /// Returns the type information for that stream.
-
45 ///
-
46 /// # Errors
-
47 /// - [`error::Incoming::Receiver`] if receiving the type information to the
-
48 /// peer failed, see [`error::Receiver`] for more details
-
49 /// - [`error::Incoming::Closed`] if the stream was closed
-
50 // TODO: fix lint
-
51 #[allow(unused_lifetimes)]
-
52 // TODO: return different state, because error can't be cloned and state is
-
53 // unusable anyway
+
250 fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
+
260 formatter
+
270 .debug_struct("Incoming")
+
280 .field("sender", &self.sender)
+
290 .field("receiver", &"ReceiverStream")
+
300 .field("type", &"Option<Result<T>>")
+
310 .finish()
+
320 }
+
33}
+
34
+
35impl<T: DeserializeOwned> Incoming<T> {
+
36 /// Builds a new [`Incoming`] from raw [`quinn`] types.
+
371102 pub(super) fn new(sender: SendStream, receiver: RecvStream) -> Self {
+
381102 Self {
+
391102 sender,
+
401102 receiver: ReceiverStream::new(receiver),
+
411102 r#type: None,
+
421102 }
+
431102 }
+
44
+
45 /// Returns the type information for that stream.
+
46 ///
+
47 /// # Errors
+
48 /// - [`error::Incoming::Receiver`] if receiving the type information to the
+
49 /// peer failed, see [`error::Receiver`] for more details
+
50 /// - [`error::Incoming::Closed`] if the stream was closed
+
51 // TODO: return different state, because error can't be cloned and state is
+
52 // unusable anyway
+
53 #[allow(clippy::missing_panics_doc)]
540 pub async fn r#type(&mut self) -> Result<&T, &error::Incoming> {
-
550 if let Some(ref r#type) = self.r#type {
-
560 r#type.as_ref()
-
57 } else {
-
580 let r#type = self
-
590 .receiver
-
600 .next()
-
610 .await
-
620 .map_or(Err(error::Incoming::Closed), |result| {
-
630 result.map_err(error::Incoming::Receiver)
-
640 });
-
650 // TODO: replace with `Option::insert`
-
660 self.r#type = Some(r#type);
-
670 self.r#type
-
680 .as_ref()
-
690 .expect("`type` just inserted missing")
-
700 .as_ref()
-
71 }
-
720 }
-
73
-
74 /// Accept the incoming stream with the given types.
-
75 ///
-
76 /// Use `S` and `R` to define which type this stream is sending and
-
77 /// receiving.
-
78 ///
-
79 /// # Errors
-
80 /// - [`error::Incoming::Receiver`] if receiving the type information to the
-
81 /// peer failed, see [`error::Receiver`] for more details
-
82 /// - [`error::Incoming::Closed`] if the stream was closed
-
83101 pub async fn accept<
-
84101 S: DeserializeOwned + Serialize + Send + 'static,
-
85101 R: DeserializeOwned + Serialize + Send + 'static,
-
86101 >(
-
87101 mut self,
-
88101 ) -> Result<(Sender<S>, Receiver<R>), error::Incoming> {
-
890 match self.r#type {
-
900 Some(Ok(_)) => (),
-
910 Some(Err(error)) => return Err(error),
-
92100 None => {
-
93100 let _type = self
-
94100 .receiver
-
95100 .next()
-
960 .await
-
97100 .map_or(Err(error::Incoming::Closed), |result| {
-
98100 result.map_err(error::Incoming::Receiver)
-
99100 });
-
100 }
-
101 }
-
102
-
103100 let sender = Sender::new(self.sender);
-
104100 let receiver = Receiver::new(self.receiver.transmute());
-
105100
-
106100 Ok((sender, receiver))
-
107100 }
-
108}
+
55 #[allow(clippy::ref_patterns)]
+
560 if let Some(ref r#type) = self.r#type {
+
570 r#type.as_ref()
+
58 } else {
+
590 let r#type = self
+
600 .receiver
+
610 .next()
+
620 .await
+
630 .map_or(Err(error::Incoming::Closed), |result| {
+
640 result.map_err(error::Incoming::Receiver)
+
650 });
+
660 self.r#type.insert(r#type).as_ref()
+
67 }
+
680 }
+
69
+
70 /// Accept the incoming stream with the given types.
+
71 ///
+
72 /// Use `S` and `R` to define which type this stream is sending and
+
73 /// receiving.
+
74 ///
+
75 /// # Errors
+
76 /// - [`error::Incoming::Receiver`] if receiving the type information to the
+
77 /// peer failed, see [`error::Receiver`] for more details
+
78 /// - [`error::Incoming::Closed`] if the stream was closed
+
791102 pub async fn accept<
+
801102 S: DeserializeOwned + Serialize + Send + 'static,
+
811102 R: DeserializeOwned + Serialize + Send + 'static,
+
821102 >(
+
831102 mut self,
+
841102 ) -> Result<(Sender<S>, Receiver<R>), error::Incoming> {
+
850 match self.r#type {
+
860 Some(Ok(_)) => (),
+
870 Some(Err(error)) => return Err(error),
+
881101 None => {
+
891101 let _type = self
+
901101 .receiver
+
911101 .next()
+
9247 .await
+
931101 .map_or(Err(error::Incoming::Closed), |result| {
+
941101 result.map_err(error::Incoming::Receiver)
+
951101 });
+
96 }
+
97 }
+
98
+
991101 let sender = Sender::new(self.sender);
+
1001101 let receiver = Receiver::new(self.receiver.transmute());
+
1011101
+
1021101 Ok((sender, receiver))
+
1031101 }
+
104}
diff --git a/coverage/src/quic/connection/index.html b/coverage/src/quic/connection/index.html index 342145d..9aeff1a 100644 --- a/coverage/src/quic/connection/index.html +++ b/coverage/src/quic/connection/index.html @@ -9,23 +9,23 @@
Current view:top level - src/quic/connection
-
Date:2023-07-07 10:30:44
+
Date:2023-08-25 14:31:32
HitTotalCoverage
-
Lines29838078.4 %
-
Functions9824240.5 %
+
Lines30537880.7 %
+
Functions20036654.6 %
Branches000.0 %
FilenameLine CoverageFunctionsBranches
-
connecting.rs96.0%24 / 2555.0%11 / 200.0%0 / 0
-
incoming.rs47.2%25 / 5325.0%5 / 200.0%0 / 0
-
mod.rs82.0%91 / 11142.2%27 / 640.0%0 / 0
-
receiver.rs72.0%36 / 5037.1%13 / 350.0%0 / 0
-
receiver_stream.rs88.0%66 / 7542.9%24 / 560.0%0 / 0
-
sender.rs84.8%56 / 6638.3%18 / 470.0%0 / 0
+
connecting.rs96.0%24 / 2562.5%15 / 240.0%0 / 0
+
incoming.rs53.1%26 / 4939.3%11 / 280.0%0 / 0
+
mod.rs82.1%92 / 11256.0%47 / 840.0%0 / 0
+
receiver.rs74.5%38 / 5152.7%29 / 550.0%0 / 0
+
receiver_stream.rs90.7%68 / 7560.0%60 / 1000.0%0 / 0
+
sender.rs86.4%57 / 6650.7%38 / 750.0%0 / 0
diff --git a/coverage/src/quic/connection/mod.rs.html b/coverage/src/quic/connection/mod.rs.html index 008b860..adb9a5d 100644 --- a/coverage/src/quic/connection/mod.rs.html +++ b/coverage/src/quic/connection/mod.rs.html @@ -9,12 +9,12 @@
Current view:top level - src/quic/connection - mod.rs
-
Date:2023-07-07 10:30:44
+
Date:2023-08-25 14:31:32
HitTotalCoverage
-
Lines9111182.0 %
-
Functions276442.2 %
+
Lines9211282.1 %
+
Functions478456.0 %
Branches000.0 %
@@ -37,14 +37,14 @@
16
17use std::{
18 fmt::{self, Debug, Formatter},
-
19 marker::PhantomData,
-
20 net::SocketAddr,
-
21 pin::{pin, Pin},
-
22 task::{Context, Poll},
-
23};
-
24
-
25pub use connecting::Connecting;
-
26use flume::r#async::RecvStream;
+
19 future::Future,
+
20 marker::PhantomData,
+
21 net::SocketAddr,
+
22 pin::{pin, Pin},
+
23 task::{Context, Poll},
+
24};
+
25
+
26pub use connecting::Connecting;
27use futures_channel::oneshot;
28use futures_util::{
29 stream::{self, FusedStream},
@@ -52,7 +52,7 @@
31};
32pub use incoming::Incoming;
33use pin_project::pin_project;
-
34use quinn::{crypto::rustls::HandshakeData, AcceptBi, VarInt};
+
34use quinn::{crypto::rustls::HandshakeData, AcceptBi, RecvStream, SendStream, VarInt};
35pub use receiver::Receiver;
36use receiver_stream::ReceiverStream;
37pub use sender::Sender;
@@ -70,7 +70,7 @@
49 connection: quinn::Connection,
50 /// Receive incoming streams.
51 receiver:
-
52 RecvStream<'static, Result<(quinn::SendStream, quinn::RecvStream), error::Connection>>,
+
52 flume::r#async::RecvStream<'static, Result<(SendStream, RecvStream), error::Connection>>,
53 /// [`Task`] handling new incoming streams.
54 task: Task<()>,
55 /// Type for type negotiation for new streams.
@@ -78,46 +78,46 @@
57}
58
59impl<T: DeserializeOwned + Serialize + Send + 'static> Debug for Connection<T> {
-
600 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-
610 f.debug_struct("Connection")
-
620 .field("connection", &self.connection)
-
630 .field("receiver", &"RecvStream")
-
640 .field("task", &self.task)
-
650 .field("types", &self.types)
-
660 .finish()
-
670 }
-
68}
-
69
-
70impl<T: DeserializeOwned + Serialize + Send + 'static> Connection<T> {
-
71 /// Builds a new [`Connection`] from raw [`quinn`] types.
-
72 #[allow(clippy::mut_mut)] // futures_util::select_biased internal usage
-
73221 pub(super) fn new(connection: quinn::Connection) -> Self {
-
74221 // channels for passing down new `Incoming` `Connection`s
-
75221 let (sender, receiver) = flume::unbounded();
-
76221 let receiver = receiver.into_stream();
-
77221
-
78221 // `Task` handling incoming streams
-
79221 let task = Task::new(|shutdown| {
-
80221 let connection = connection.clone();
-
81213 async move {
-
82213 IncomingStreams {
-
83213 connection: &connection,
-
84213 accept: None,
-
85213 shutdown,
-
86213 sender,
-
87213 complete: false,
-
88213 }
-
89200 .await;
-
90208 }
-
91221 });
-
92221
-
93221 Self {
-
94221 connection,
-
95221 receiver,
-
96221 task,
-
97221 types: PhantomData,
-
98221 }
-
99221 }
+
600 fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
+
610 formatter
+
620 .debug_struct("Connection")
+
630 .field("connection", &self.connection)
+
640 .field("receiver", &"RecvStream")
+
650 .field("task", &self.task)
+
660 .field("types", &self.types)
+
670 .finish()
+
680 }
+
69}
+
70
+
71impl<T: DeserializeOwned + Serialize + Send + 'static> Connection<T> {
+
72 /// Builds a new [`Connection`] from raw [`quinn`] types.
+
73225 pub(super) fn new(connection: quinn::Connection) -> Self {
+
74225 // channels for passing down new `Incoming` `Connection`s
+
75225 let (sender, receiver) = flume::unbounded();
+
76225 let receiver = receiver.into_stream();
+
77225
+
78225 // `Task` handling incoming streams
+
79225 let task = Task::new(|shutdown| {
+
80225 let connection = connection.clone();
+
81217 async move {
+
82217 IncomingStreams {
+
83217 connection: &connection,
+
84217 accept: None,
+
85217 shutdown,
+
86217 sender,
+
87217 complete: false,
+
88217 }
+
89293 .await;
+
90212 }
+
91225 });
+
92225
+
93225 Self {
+
94225 connection,
+
95225 receiver,
+
96225 task,
+
97225 types: PhantomData,
+
98225 }
+
99225 }
100
101 /// Open a stream on this [`Connection`], allowing to send data back and
102 /// forth.
@@ -129,22 +129,22 @@
108 /// - [`error::Stream::Open`] if opening a stream failed
109 /// - [`error::Stream::Sender`] if sending the type information to the peer
110 /// failed, see [`error::Sender`] for more details
-
111101 pub async fn open_stream<
-
112101 S: DeserializeOwned + Serialize + Send + 'static,
-
113101 R: DeserializeOwned + Serialize + Send + 'static,
-
114101 >(
-
115101 &self,
-
116101 r#type: &T,
-
117101 ) -> Result<(Sender<S>, Receiver<R>), error::Stream> {
-
118101 let (sender, receiver) = self.connection.open_bi().await?;
+
1111102 pub async fn open_stream<
+
1121102 S: DeserializeOwned + Serialize + Send + 'static,
+
1131102 R: DeserializeOwned + Serialize + Send + 'static,
+
1141102 >(
+
1151102 &self,
+
1161102 r#type: &T,
+
1171102 ) -> Result<(Sender<S>, Receiver<R>), error::Stream> {
+
1186972 let (sender, receiver) = self.connection.open_bi().await?;
119
-
120101 let sender = Sender::new(sender);
-
121101 let receiver = Receiver::new(ReceiverStream::new(receiver));
-
122101
-
123101 sender.send_any(&r#type)?;
+
1201102 let sender = Sender::new(sender);
+
1211102 let receiver = Receiver::new(ReceiverStream::new(receiver));
+
1221102
+
1231102 sender.send_any(&r#type)?;
124
-
125101 Ok((sender, receiver))
-
126101 }
+
1251102 Ok((sender, receiver))
+
1261102 }
127
128 /// The negotiated application protocol. See
129 /// [`Builder::set_protocols`](crate::Builder::set_protocols).
@@ -168,18 +168,18 @@
147 /// The peer's address. Clients may change addresses at will, e.g. when
148 /// switching to a cellular internet connection.
149 #[must_use]
-
150600 pub fn remote_address(&self) -> SocketAddr {
-
151600 self.connection.remote_address()
-
152600 }
+
150603 pub fn remote_address(&self) -> SocketAddr {
+
151603 self.connection.remote_address()
+
152603 }
153
154 /// Prevents any new incoming streams. Already incoming streams will
155 /// finish first.
156 ///
157 /// # Errors
158 /// [`error::AlreadyClosed`] if it was already closed.
-
159200 pub async fn close_incoming(&self) -> Result<(), error::AlreadyClosed> {
-
160200 self.task.close(()).await
-
161200 }
+
159203 pub async fn close_incoming(&self) -> Result<(), error::AlreadyClosed> {
+
160203 self.task.close(()).await
+
161203 }
162
163 /// Close the [`Connection`] immediately.
164 ///
@@ -197,15 +197,15 @@
176impl<T: DeserializeOwned + Serialize + Send + 'static> Stream for Connection<T> {
177 type Item = Result<Incoming<T>, error::Connection>;
178
-
179202 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
-
180202 if self.receiver.is_terminated() {
-
1810 Poll::Ready(None)
+
1791294 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+
1801294 if self.receiver.is_terminated() {
+
1811 Poll::Ready(None)
182 } else {
-
183202 self.receiver
-
184202 .poll_next_unpin(cx)
-
185202 .map_ok(|(sender, receiver)| Incoming::new(sender, receiver))
+
1831293 self.receiver
+
1841293 .poll_next_unpin(cx)
+
1851293 .map_ok(|(sender, receiver)| Incoming::new(sender, receiver))
186 }
-
187202 }
+
1871294 }
188}
189
190impl<T: DeserializeOwned + Serialize + Send + 'static> FusedStream for Connection<T> {
@@ -214,57 +214,57 @@
1930 }
194}
195
-
196struct IncomingStreams<'a> {
-
197 connection: &'a quinn::Connection,
-
198 accept: Option<Pin<Box<AcceptBi<'a>>>>,
+
196struct IncomingStreams<'connection> {
+
197 connection: &'connection quinn::Connection,
+
198 accept: Option<Pin<Box<AcceptBi<'connection>>>>,
199 shutdown: oneshot::Receiver<()>,
-
200 sender: flume::Sender<Result<(quinn::SendStream, quinn::RecvStream), error::Connection>>,
+
200 sender: flume::Sender<Result<(SendStream, RecvStream), error::Connection>>,
201 complete: bool,
202}
203
-
204impl std::future::Future for IncomingStreams<'_> {
+
204impl Future for IncomingStreams<'_> {
205 type Output = ();
206
-
207413 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
-
208413 if self.complete || self.connection.close_reason().is_some() {
-
2094 return Poll::Ready(());
-
210409 }
-
211409
-
212409 match self.shutdown.poll_unpin(cx) {
+
2071488 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+
2081488 if self.complete || self.connection.close_reason().is_some() {
+
2097 return Poll::Ready(());
+
2101481 }
+
2111481
+
2121481 match self.shutdown.poll_unpin(cx) {
213 Poll::Ready(_) => {
-
214204 self.complete = true;
-
215204 self.accept = None;
-
216204 Poll::Ready(())
+
214613 self.complete = true;
+
215613 self.accept = None;
+
216613 Poll::Ready(())
217 }
218 Poll::Pending => {
-
219306 loop {
-
220306 let mut accept = self
-
221306 .accept
-
222306 .take()
-
223306 .unwrap_or_else(|| Box::pin(self.connection.accept_bi()));
-
224306 match accept.poll_unpin(cx) {
-
225101 Poll::Ready(incoming) => {
-
226101 // if there is no receiver, it means that we dropped the last
-
227101 // `Endpoint`
-
228101 if self
-
229101 .sender
-
230101 .send(incoming.map_err(error::Connection))
-
231101 .is_err()
+
2194172 loop {
+
2204172 let mut accept = self
+
2214172 .accept
+
2224172 .take()
+
2234172 .unwrap_or_else(|| Box::pin(self.connection.accept_bi()));
+
2244172 match accept.poll_unpin(cx) {
+
2253304 Poll::Ready(incoming) => {
+
2263304 // if there is no receiver, it means that we dropped the last
+
2273304 // `Endpoint`
+
2283304 if self
+
2293304 .sender
+
2303304 .send(incoming.map_err(error::Connection))
+
2313304 .is_err()
232 {
2330 self.complete = true;
2340 return Poll::Ready(());
-
235101 }
+
2353304 }
236 }
237 Poll::Pending => {
238 // Restore the same accept future to our state.
-
239205 self.accept = Some(accept);
-
240205 return Poll::Pending;
+
239868 self.accept = Some(accept);
+
240868 return Poll::Pending;
241 }
242 }
243 }
244 }
245 }
-
246413 }
+
2461488 }
247}
diff --git a/coverage/src/quic/connection/receiver.rs.html b/coverage/src/quic/connection/receiver.rs.html index d755f71..893c110 100644 --- a/coverage/src/quic/connection/receiver.rs.html +++ b/coverage/src/quic/connection/receiver.rs.html @@ -9,12 +9,12 @@
Current view:top level - src/quic/connection - receiver.rs
-
Date:2023-07-07 10:30:44
+
Date:2023-08-25 14:31:32
HitTotalCoverage
-
Lines365072.0 %
-
Functions133537.1 %
+
Lines385174.5 %
+
Functions295552.7 %
Branches000.0 %
@@ -35,7 +35,7 @@
14
15/// Used to receive data from a stream. Will stop receiving message if
16/// deserialization failed.
-
170#[derive(Clone)]
+
1710100#[derive(Clone)]
18pub struct Receiver<T: 'static> {
19 /// Send [`Deserialize`](serde::Deserialize)d data to the sending task.
20 receiver: flume::r#async::RecvStream<'static, Result<T, error::Receiver>>,
@@ -44,28 +44,28 @@
23}
24
25impl<T> Debug for Receiver<T> {
-
260 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-
270 f.debug_struct("Receiver")
-
280 .field("receiver", &"RecvStream")
-
290 .field("task", &self.task)
-
300 .finish()
-
310 }
-
32}
-
33
-
34impl<T> Receiver<T> {
-
35 /// Builds a new [`Receiver`] from a raw [`quinn`] type. Spawns a task that
-
36 /// receives data from the stream.
-
37 #[allow(clippy::mut_mut)] // futures_util::select_biased internal usage
-
38201 pub(super) fn new(mut stream: ReceiverStream<T>) -> Self
-
39201 where
-
40201 T: DeserializeOwned + Send,
-
41201 {
-
42201 // receiver channels
-
43201 let (sender, receiver) = flume::unbounded();
-
44201 let receiver = receiver.into_stream();
-
45201
-
46201 // `Task` handling `Receiver`
-
47201 let task = Task::new(|mut shutdown| async move {
+
260 fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
+
270 formatter
+
280 .debug_struct("Receiver")
+
290 .field("receiver", &"RecvStream")
+
300 .field("task", &self.task)
+
310 .finish()
+
320 }
+
33}
+
34
+
35impl<T> Receiver<T> {
+
36 /// Builds a new [`Receiver`] from a raw [`quinn`] type. Spawns a task that
+
37 /// receives data from the stream.
+
382203 pub(super) fn new(mut stream: ReceiverStream<T>) -> Self
+
392203 where
+
402203 T: DeserializeOwned + Send,
+
412203 {
+
422203 // receiver channels
+
432203 let (sender, receiver) = flume::unbounded();
+
442203 let receiver = receiver.into_stream();
+
452203
+
462203 // `Task` handling `Receiver`
+
472203 let task = Task::new(|mut shutdown| async move {
48 /// Help Group Messages
49 enum Message<T> {
50 /// Data arrived from stream.
@@ -74,23 +74,23 @@
53 Close,
54 }
55
-
561003 while let Some(message) = futures_util::select_biased! {
-
57803 message = stream.next() => message.map(Message::Data),
-
58803 shutdown = shutdown => shutdown.ok().map(|_| Message::Close),
-
59803 complete => None,
-
60803 } {
-
61200 match message {
-
62200 Message::Data(message) => {
-
63200 let failed = message.is_err();
-
64200
-
65200 // the receiver might have been dropped
-
66200 if sender.send(message).is_err() {
+
5649659 while let Some(message) = futures_util::select_biased! {
+
5731509 message = stream.next() => message.map(Message::Data),
+
5831509 shutdown = shutdown => shutdown.ok().map(|_| Message::Close),
+
5931509 complete => None,
+
6031509 } {
+
6120402 match message {
+
6220402 Message::Data(message) => {
+
6320402 let failed = message.is_err();
+
6420402
+
6520402 // the receiver might have been dropped
+
6620402 if sender.send(message).is_err() {
670 break;
-
68200 }
-
69200
-
70200 if failed {
-
710 break;
-
72200 }
+
6820402 }
+
6920402
+
7020402 if failed {
+
712 break;
+
7220400 }
73 }
74 Message::Close => {
750 stream.stop()?;
@@ -99,11 +99,11 @@
78 }
79 }
80
-
81201 Ok(())
-
82201 });
-
83201
-
84201 Self { receiver, task }
-
85201 }
+
812203 Ok(())
+
822203 });
+
832203
+
842203 Self { receiver, task }
+
852203 }
86
87 /// Wait for the [`Receiver`] part of the stream to finish gracefully.
88 ///
@@ -112,9 +112,9 @@
91 ///
92 /// # Errors
93 /// [`error::AlreadyClosed`] if it has already been closed.
-
94200 pub async fn finish(&self) -> Result<(), error::AlreadyClosed> {
-
95200 (&self.task).await?
-
96200 }
+
941200 pub async fn finish(&self) -> Result<(), error::AlreadyClosed> {
+
951200 (&self.task).await?
+
961200 }
97
98 /// Close the [`Receiver`] immediately. To close a [`Receiver`] gracefully
99 /// use [`finish`](Self::finish).
@@ -129,9 +129,9 @@
108impl<T> Stream for Receiver<T> {
109 type Item = Result<T, error::Receiver>;
110
-
111400 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
-
112400 self.receiver.poll_next_unpin(cx)
-
113400 }
+
11134511 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+
11234511 self.receiver.poll_next_unpin(cx)
+
11334511 }
114}
diff --git a/coverage/src/quic/connection/receiver_stream.rs.html b/coverage/src/quic/connection/receiver_stream.rs.html index 2aee2fd..050e6da 100644 --- a/coverage/src/quic/connection/receiver_stream.rs.html +++ b/coverage/src/quic/connection/receiver_stream.rs.html @@ -9,12 +9,12 @@
Current view:top level - src/quic/connection - receiver_stream.rs
-
Date:2023-07-07 10:30:44
+
Date:2023-08-25 14:31:32
HitTotalCoverage
-
Lines667588.0 %
-
Functions245642.9 %
+
Lines687590.7 %
+
Functions6010060.0 %
Branches000.0 %
@@ -58,27 +58,27 @@
37
38impl<M: DeserializeOwned> ReceiverStream<M> {
39 /// Builds a new [`ReceiverStream`].
-
40202 pub(super) fn new(stream: RecvStream) -> Self {
-
41202 Self {
-
42202 length: 0,
-
43202 // 1480 bytes is a default MTU size configured by quinn-proto
-
44202 buffer: BytesMut::with_capacity(1480),
-
45202 stream,
-
46202 complete: false,
-
47202 _type: PhantomData,
-
48202 }
-
49202 }
+
402204 pub(super) fn new(stream: RecvStream) -> Self {
+
412204 Self {
+
422204 length: 0,
+
432204 // 1480 bytes is a default MTU size configured by quinn-proto
+
442204 buffer: BytesMut::with_capacity(1480),
+
452204 stream,
+
462204 complete: false,
+
472204 _type: PhantomData,
+
482204 }
+
492204 }
50
51 /// Transmutes this [`ReceiverStream`] to a different message type.
-
52100 pub(super) fn transmute<T: DeserializeOwned>(self) -> ReceiverStream<T> {
-
53100 ReceiverStream {
-
54100 length: self.length,
-
55100 buffer: self.buffer,
-
56100 stream: self.stream,
-
57100 complete: self.complete,
-
58100 _type: PhantomData,
-
59100 }
-
60100 }
+
521101 pub(super) fn transmute<T: DeserializeOwned>(self) -> ReceiverStream<T> {
+
531101 ReceiverStream {
+
541101 length: self.length,
+
551101 buffer: self.buffer,
+
561101 stream: self.stream,
+
571101 complete: self.complete,
+
581101 _type: PhantomData,
+
591101 }
+
601101 }
61
62 /// Calls [`RecvStream::stop`](RecvStream::stop).
63 ///
@@ -96,34 +96,34 @@
75 ///
76 /// # Errors
77 /// [`ReadError`] on failure to read from the [`RecvStream`].
-
78602 fn poll(&mut self, cx: &mut Context<'_>) -> Poll<Result<Option<()>, ReadError>> {
-
79602 pin!(self.stream.read_chunk(usize::MAX, true))
-
80602 .poll_unpin(cx)
-
81602 .map_ok(|option| {
-
82401 option.map(|Chunk { bytes, .. }| {
-
83200 // reserves enough space to put in incoming bytes
-
84200 self.buffer.reserve(bytes.len());
-
85200 self.buffer.put(bytes);
-
86401 })
-
87602 })
-
88602 }
+
789884 fn poll(&mut self, cx: &mut Context<'_>) -> Poll<Result<Option<()>, ReadError>> {
+
799884 pin!(self.stream.read_chunk(usize::MAX, true))
+
809884 .poll_unpin(cx)
+
819884 .map_ok(|option| {
+
825382 option.map(|Chunk { bytes, .. }| {
+
833181 // reserves enough space to put in incoming bytes
+
843181 self.buffer.reserve(bytes.len());
+
853181 self.buffer.put(bytes);
+
865382 })
+
879884 })
+
889884 }
89
90 /// Check if we currently have enough data to build
91 /// [`length`](Self::length) and returns it. Returns [`None`] if there isn't
92 /// enough data to extract [`length`](Self::length) yet.
-
93902 fn length(&mut self) -> Option<usize> {
-
94902 if self.length == 0 {
-
95902 (self.buffer.len() >= size_of::<u64>()).then(|| {
-
96300 // aquire the length by reading the first 8 bytes (u64)
-
97300 self.length = usize::try_from(self.buffer.get_uint_le(size_of::<u64>()))
-
98300 .expect("not a 64-bit system");
-
99300
-
100300 self.length
-
101902 })
+
9331385 fn length(&mut self) -> Option<usize> {
+
9431385 if self.length == 0 {
+
9531267 (self.buffer.len() >= size_of::<u64>()).then(|| {
+
9621501 // aquire the length by reading the first 8 bytes (u64)
+
9721501 self.length = usize::try_from(self.buffer.get_uint_le(size_of::<u64>()))
+
9821501 .expect("not a 64-bit system");
+
9921501
+
10021501 self.length
+
10131267 })
102 } else {
-
1030 Some(self.length)
+
103118 Some(self.length)
104 }
-
105902 }
+
10531385 }
106
107 /// [`Deserialize`](serde::Deserialize)s the currents
108 /// [`buffer`](Self::buffer). Returns [`None`] if there isn't enough data to
@@ -133,38 +133,38 @@
112 /// [`ErrorKind`] if `data` failed to be
113 /// [`Deserialize`](serde::Deserialize)d.
114 fn deserialize(&mut self) -> Result<Option<M>, ErrorKind> {
-
115902 if let Some(length) = self.length() {
-
116300 if self.buffer.len() >= length {
+
11531385 if let Some(length) = self.length() {
+
11621619 if self.buffer.len() >= length {
117 // split off the correct amount of data
-
118300 let data = self.buffer.split_to(length).reader();
-
119300 // reset the length
-
120300 self.length = 0;
-
121300
-
122300 // deserialize message
-
123300 // TODO: configure bincode, for example make it bounded
-
124300 bincode::deserialize_from::<_, M>(data)
-
125300 .map(Some)
-
126300 .map_err(|error| *error)
+
11821501 let data = self.buffer.split_to(length).reader();
+
11921501 // reset the length
+
12021501 self.length = 0;
+
12121501
+
12221501 // deserialize message
+
12321501 // TODO: configure bincode, for example make it bounded
+
12421501 bincode::deserialize_from::<_, M>(data)
+
12521501 .map(Some)
+
12621501 .map_err(|error| *error)
127 } else {
-
1280 Ok(None)
+
128118 Ok(None)
129 }
130 } else {
-
131602 Ok(None)
+
1319766 Ok(None)
132 }
-
133902 }
+
13331385 }
134}
135
136impl<M: DeserializeOwned> Stream for ReceiverStream<M> {
137 type Item = Result<M, error::Receiver>;
138
-
139702 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+
13928204 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
140 use futures_util::ready;
141
142 // did already have enough data to return a message without polling?
-
143702 if let Some(message) = self.deserialize()? {
+
14328204 if let Some(message) = self.deserialize()? {
144 // send back the message
-
145100 return Poll::Ready(Some(Ok(message)));
-
146602 }
+
14518320 return Poll::Ready(Some(Ok(message)));
+
1469884 }
147
148 // try to poll for more data. This loop is important, because if the
149 // stream receives data between returning Poll::Ready and our failed
@@ -172,24 +172,24 @@
151 // data, we want to poll the stream again before yielding to the
152 // runtime.
153 loop {
-
154602 if ready!(self.poll(cx)?).is_some() {
+
1549884 if ready!(self.poll(cx)?).is_some() {
155 // The stream received some data, but we may not have a full packet.
-
156200 if let Some(message) = self.deserialize()? {
-
157200 break Poll::Ready(Some(Ok(message)));
+
1563181 if let Some(message) = self.deserialize()? {
+
1573181 break Poll::Ready(Some(Ok(message)));
1580 }
159 } else {
160 // The stream has ended
-
161201 self.complete = true;
-
162201 break Poll::Ready(None);
+
1612201 self.complete = true;
+
1622201 break Poll::Ready(None);
163 }
164 }
-
165702 }
+
16528204 }
166}
167
168impl<M: DeserializeOwned> FusedStream for ReceiverStream<M> {
-
169602 fn is_terminated(&self) -> bool {
-
170602 self.complete
-
171602 }
+
16927056 fn is_terminated(&self) -> bool {
+
17027056 self.complete
+
17127056 }
172}
diff --git a/coverage/src/quic/connection/sender.rs.html b/coverage/src/quic/connection/sender.rs.html index 68886d1..a2d44db 100644 --- a/coverage/src/quic/connection/sender.rs.html +++ b/coverage/src/quic/connection/sender.rs.html @@ -9,12 +9,12 @@
Current view:top level - src/quic/connection - sender.rs
-
Date:2023-07-07 10:30:44
+
Date:2023-08-25 14:31:32
HitTotalCoverage
-
Lines566684.8 %
-
Functions184738.3 %
+
Lines576686.4 %
+
Functions387550.7 %
Branches000.0 %
@@ -32,7 +32,7 @@
11use crate::error;
12
13/// Used to send data to a stream.
-
140#[derive(Clone, Debug)]
+
1410100#[derive(Clone, Debug)]
15pub struct Sender<T: Serialize> {
16 /// Send [`Serialize`]d data to the sending task.
17 sender: flume::Sender<Bytes>,
@@ -56,24 +56,24 @@
35impl<T: Serialize> Sender<T> {
36 /// Builds a new [`Sender`] from a raw [`quinn`] type. Spawns a task that
37 /// sends data into the stream.
-
38201 pub(super) fn new(mut stream_sender: SendStream) -> Self {
-
39201 // sender channels
-
40201 let (sender, receiver) = flume::unbounded();
-
41201
-
42201 // `Task` handling `Sender`
-
43201 let task = Task::new(|mut shutdown| async move {
-
44201 let mut receiver = receiver.into_stream().fuse();
+
382203 pub(super) fn new(mut stream_sender: SendStream) -> Self {
+
392203 // sender channels
+
402203 let (sender, receiver) = flume::unbounded();
+
412203
+
422203 // `Task` handling `Sender`
+
432203 let task = Task::new(|mut shutdown| async move {
+
442203 let mut receiver = receiver.into_stream().fuse();
45
-
46605 while let Some(message) = futures_util::select_biased! {
-
47909 message = receiver.next() => message.map(Message::Data),
-
48909 shutdown = shutdown => shutdown.ok(),
-
49909 complete => None,
-
50909 } {
-
51502 match message {
-
52301 Message::Data(bytes) => stream_sender.write_chunk(bytes).await?,
+
4630954 while let Some(message) = futures_util::select_biased! {
+
4739404 message = receiver.next() => message.map(Message::Data),
+
4839404 shutdown = shutdown => shutdown.ok(),
+
4939404 complete => None,
+
5039404 } {
+
5122703 match message {
+
5221502 Message::Data(bytes) => stream_sender.write_chunk(bytes).await?,
53 Message::Finish => {
-
54201 stream_sender.finish().await?;
-
55201 break;
+
541201 stream_sender.finish().await?;
+
551201 break;
56 }
57 Message::Close => {
580 stream_sender
@@ -84,15 +84,15 @@
63 }
64 }
65
-
66201 Ok(())
-
67201 });
-
68201
-
69201 Self {
-
70201 sender,
-
71201 _type: PhantomData,
-
72201 task,
-
73201 }
-
74201 }
+
662203 Ok(())
+
672203 });
+
682203
+
692203 Self {
+
702203 sender,
+
712203 _type: PhantomData,
+
722203 task,
+
732203 }
+
742203 }
75
76 /// Send `data` into the stream.
77 ///
@@ -101,9 +101,9 @@
80 /// - [`error::Sender::Write`] if the [`Sender`] failed to to write to the
81 /// stream
82 /// - [`error::Sender::Closed`] if the [`Sender`] is closed
-
83200 pub fn send(&self, data: &T) -> Result<(), error::Sender> {
-
84200 self.send_any(data)
-
85200 }
+
8320400 pub fn send(&self, data: &T) -> Result<(), error::Sender> {
+
8420400 self.send_any(data)
+
8520400 }
86
87 /// Send any `data` into the stream. This will fail on the receiving end if
88 /// not decoded into the proper type.
@@ -113,73 +113,72 @@
92 /// - [`error::Sender::Write`] if the [`Sender`] failed to to write to the
93 /// stream
94 /// - [`error::Sender::Closed`] if the [`Sender`] is closed
-
95 #[allow(clippy::panic_in_result_fn, clippy::unwrap_in_result)]
-
96301 pub(super) fn send_any<A: Serialize>(&self, data: &A) -> Result<(), error::Sender> {
-
97301 let mut bytes = BytesMut::new();
-
98
-
99 // get size
-
100301 let len = bincode::serialized_size(&data)?;
-
101 // reserve an appropriate amount of space
-
102301 bytes.reserve(
-
103301 usize::try_from(len)
-
104301 .expect("not a 64-bit system")
-
105301 .checked_add(size_of::<u64>())
-
106301 .expect("data trying to be sent is too big"),
-
107301 );
-
108301 // insert length first, this enables framing
-
109301 bytes.put_u64_le(len);
-
110301
-
111301 let mut bytes = bytes.writer();
-
112301
-
113301 // serialize `data` into `bytes`
-
114301 bincode::serialize_into(&mut bytes, &data)?;
-
115
-
116 // send data to task
-
117301 let bytes = bytes.into_inner().freeze();
-
118
-
119 // make sure that our length is correct
-
120 debug_assert_eq!(
-
121301 u64::try_from(bytes.len()).expect("not a 64-bit system"),
-
122301 u64::try_from(size_of::<u64>())
-
123301 .expect("not a 64-bit system")
-
124301 .checked_add(len)
-
125301 .expect("message to long")
-
126 );
-
127
-
128 // if the sender task has been dropped, return it's error
-
129301 if self.sender.send(bytes).is_err() {
-
130 // TODO: configurable executor
-
1310 futures_executor::block_on(async { (&self.task).await })?
-
132 } else {
-
133301 Ok(())
-
134 }
-
135301 }
-
136
-
137 /// Shut down the [`Send`] part of the stream gracefully.
-
138 ///
-
139 /// No new data may be written after calling this method. Completes when the
-
140 /// peer has acknowledged all sent data, retransmitting data as needed.
-
141 ///
-
142 /// # Errors
-
143 /// This can only return [`error::Sender::Closed`] as an [`Err`], if it was
-
144 /// already closed, but if the [`Sender`] failed to write to the stream it
-
145 /// will return a queued [`error::Sender::Write`].
-
146201 pub async fn finish(&self) -> Result<(), error::Sender> {
-
147201 self.task.close(Message::Finish).await?
-
148201 }
-
149
-
150 /// Close the [`Sender`] immediately.
-
151 ///
-
152 /// To close a [`Sender`] gracefully use [`Sender::finish`].
-
153 ///
-
154 /// # Errors
-
155 /// This can only return [`error::Sender::Closed`] as an [`Err`], if it was
-
156 /// already closed, but if the [`Sender`] failed to write to the stream it
-
157 /// will return a queued [`error::Sender::Write`].
-
1580 pub async fn close(&self) -> Result<(), error::Sender> {
-
1590 self.task.close(Message::Close).await?
-
1600 }
-
161}
+
9521502 pub(super) fn send_any<A: Serialize>(&self, data: &A) -> Result<(), error::Sender> {
+
9621502 let mut bytes = BytesMut::new();
+
97
+
98 // get size
+
9921502 let len = bincode::serialized_size(&data)?;
+
100 // reserve an appropriate amount of space
+
10121502 bytes.reserve(
+
10221502 usize::try_from(len)
+
10321502 .expect("not a 64-bit system")
+
10421502 .checked_add(size_of::<u64>())
+
10521502 .expect("data trying to be sent is too big"),
+
10621502 );
+
10721502 // insert length first, this enables framing
+
10821502 bytes.put_u64_le(len);
+
10921502
+
11021502 let mut bytes = bytes.writer();
+
11121502
+
11221502 // serialize `data` into `bytes`
+
11321502 bincode::serialize_into(&mut bytes, &data)?;
+
114
+
115 // send data to task
+
11621502 let bytes = bytes.into_inner().freeze();
+
117
+
118 // make sure that our length is correct
+
119 debug_assert_eq!(
+
12021502 u64::try_from(bytes.len()).expect("not a 64-bit system"),
+
12121502 u64::try_from(size_of::<u64>())
+
12221502 .expect("not a 64-bit system")
+
12321502 .checked_add(len)
+
12421502 .expect("message to long")
+
125 );
+
126
+
127 // if the sender task has been dropped, return it's error
+
12821502 if self.sender.send(bytes).is_err() {
+
129 // TODO: configurable executor
+
1300 futures_executor::block_on(async { (&self.task).await })?
+
131 } else {
+
13221502 Ok(())
+
133 }
+
13421502 }
+
135
+
136 /// Shut down the [`Send`] part of the stream gracefully.
+
137 ///
+
138 /// No new data may be written after calling this method. Completes when the
+
139 /// peer has acknowledged all sent data, retransmitting data as needed.
+
140 ///
+
141 /// # Errors
+
142 /// This can only return [`error::Sender::Closed`] as an [`Err`], if it was
+
143 /// already closed, but if the [`Sender`] failed to write to the stream it
+
144 /// will return a queued [`error::Sender::Write`].
+
1451201 pub async fn finish(&self) -> Result<(), error::Sender> {
+
1461201 self.task.close(Message::Finish).await?
+
1471201 }
+
148
+
149 /// Close the [`Sender`] immediately.
+
150 ///
+
151 /// To close a [`Sender`] gracefully use [`Sender::finish`].
+
152 ///
+
153 /// # Errors
+
154 /// This can only return [`error::Sender::Closed`] as an [`Err`], if it was
+
155 /// already closed, but if the [`Sender`] failed to write to the stream it
+
156 /// will return a queued [`error::Sender::Write`].
+
1570 pub async fn close(&self) -> Result<(), error::Sender> {
+
1580 self.task.close(Message::Close).await?
+
1590 }
+
160}
diff --git a/coverage/src/quic/endpoint/builder/config.rs.html b/coverage/src/quic/endpoint/builder/config.rs.html index 9714161..9ae27c0 100644 --- a/coverage/src/quic/endpoint/builder/config.rs.html +++ b/coverage/src/quic/endpoint/builder/config.rs.html @@ -9,11 +9,11 @@
Current view:top level - src/quic/endpoint/builder - config.rs
-
Date:2023-07-07 10:30:44
+
Date:2023-08-25 14:31:32
HitTotalCoverage
-
Lines17318394.5 %
+
Lines17018094.4 %
Functions305257.7 %
Branches000.0 %
@@ -46,7 +46,7 @@
25
26/// Persistent configuration shared between [`Builder`](crate::Builder) and
27/// [`Endpoint`](crate::Endpoint).
-
28135#[derive(Clone, Debug)]
+
28349#[derive(Clone, Debug)]
29pub(in crate::quic::endpoint) struct Config {
30 /// Protocols used.
31 protocols: Vec<Vec<u8>>,
@@ -54,319 +54,304 @@
33 max_idle_timeout: Option<Duration>,
34 /// Enable [`trust-dns`](trust_dns_resolver).
35 #[cfg(feature = "trust-dns")]
-
36 #[cfg_attr(doc, doc(cfg(feature = "trust-dns")))]
-
37 trust_dns: bool,
-
38 /// Enables DNSSEC validation for [`trust-dns`](trust_dns_resolver).
-
39 #[cfg(feature = "trust-dns")]
-
40 #[cfg_attr(doc, doc(cfg(feature = "trust-dns")))]
-
41 dnssec: bool,
-
42 /// Enables `/etc/hosts` file support for [`trust-dns`](trust_dns_resolver).
-
43 #[cfg(feature = "trust-dns")]
-
44 #[cfg_attr(doc, doc(cfg(feature = "trust-dns")))]
-
45 hosts_file: bool,
-
46}
-
47
-
48impl Config {
-
49 /// Builds a new [`Config`].
-
50139 pub(super) const fn new() -> Self {
-
51139 Self {
-
52139 protocols: Vec::new(),
-
53139 // default set by quinn
-
54139 max_idle_timeout: Some(Duration::from_secs(10)),
-
55139 #[cfg(feature = "trust-dns")]
-
56139 trust_dns: true,
-
57139 #[cfg(feature = "trust-dns")]
-
58139 dnssec: true,
-
59139 #[cfg(feature = "trust-dns")]
-
60139 hosts_file: false,
-
61139 }
-
62139 }
-
63
-
64 /// Creates a with the correct settings [`TransportConfig`].
-
65260 pub(super) fn transport(&self) -> TransportConfig {
-
66260 let mut transport = TransportConfig::default();
-
67260
-
68260 // set transport defaults
-
69260 // TODO: research other settings
-
70260 let _ =
-
71260 transport
-
72260 // TODO: research if this is necessary, it improves privacy, but may hurt network
-
73260 // providers?
-
74260 .allow_spin(false)
-
75260 // we don't support unordered for now
-
76260 .datagram_receive_buffer_size(None)
-
77260 // for compatibility with WebRTC, we won't be using uni-directional streams
-
78260 .max_concurrent_uni_streams(quinn::VarInt::from_u32(0))
-
79260 .max_idle_timeout(self.max_idle_timeout.map(|time| {
-
80260 IdleTimeout::try_from(time).expect("unexpected failure conversion")
-
81260 }));
-
82260
-
83260 transport
-
84260 }
-
85
-
86 /// Set the application-layer protocols.
-
878 pub(super) fn set_protocols(&mut self, protocols: impl Into<Vec<Vec<u8>>>) {
-
888 self.protocols = protocols.into();
-
898 }
-
90
-
91 /// Returns the configured application-layer protocols.
-
9213 pub(super) fn protocols(&self) -> &[Vec<u8>] {
-
9313 self.protocols.as_slice()
-
9413 }
-
95
-
96 /// Controls the use of [`trust-dns`](trust_dns_resolver) for
-
97 /// [`Endpoint::connect`](crate::Endpoint::connect).
-
98 #[cfg(feature = "trust-dns")]
-
99 #[cfg_attr(doc, doc(cfg(feature = "trust-dns")))]
-
1002 pub(super) fn set_trust_dns(&mut self, enable: bool) {
-
1012 self.trust_dns = enable;
-
1022 }
-
103
-
104 /// Disables the use of [`trust-dns`](trust_dns_resolver) for
-
105 /// [`Endpoint::connect`](crate::Endpoint::connect) despite the activates
-
106 /// crate features.
-
107 #[cfg_attr(
-
108 not(feature = "trust-dns"),
-
109 allow(clippy::unused_self, unused_variables)
-
110 )]
-
1113 pub(super) fn disable_trust_dns(&mut self) {
-
1123 #[cfg(feature = "trust-dns")]
-
1133 {
-
1143 self.trust_dns = false;
-
1153 }
-
1163 }
-
117
-
118 /// Returns if [`trust-dns`](trust_dns_resolver) is enabled.
-
119 #[cfg_attr(not(feature = "trust-dns"), allow(clippy::unused_self))]
-
12014 pub(in crate::quic::endpoint) const fn trust_dns(&self) -> bool {
-
12114 #[cfg(feature = "trust-dns")]
-
12214 return self.trust_dns;
-
12314 #[cfg(not(feature = "trust-dns"))]
-
12414 false
-
12514 }
-
126
-
127 /// Controls DNSSEC validation for [`trust-dns`](trust_dns_resolver).
-
128 #[cfg(feature = "trust-dns")]
-
129 #[cfg_attr(doc, doc(cfg(feature = "trust-dns")))]
-
1306 pub(super) fn set_dnssec(&mut self, enable: bool) {
-
1316 self.dnssec = enable;
-
1326 }
-
133
-
134 /// Returns if DNSSEC is enabled for [`trust-dns`](trust_dns_resolver).
-
135 #[cfg(feature = "trust-dns")]
-
136 #[cfg_attr(doc, doc(cfg(feature = "trust-dns")))]
-
13711 pub(in crate::quic::endpoint) const fn dnssec(&self) -> bool {
-
13811 self.dnssec
-
13911 }
-
140
-
141 /// Controls `/etc/hosts` file support for
-
142 /// [`trust-dns`](trust_dns_resolver).
-
143 #[cfg(feature = "trust-dns")]
-
144 #[cfg_attr(doc, doc(cfg(feature = "trust-dns")))]
-
1452 pub(super) fn set_hosts_file(&mut self, enable: bool) {
-
1462 self.hosts_file = enable;
-
1472 }
-
148
-
149 /// Returns if `/etc/hosts` file support is enabled for
-
150 /// [`trust-dns`](trust_dns_resolver).
-
151 #[cfg(feature = "trust-dns")]
-
152 #[cfg_attr(doc, doc(cfg(feature = "trust-dns")))]
-
15311 pub(in crate::quic::endpoint) const fn hosts_file(&self) -> bool {
-
15411 self.hosts_file
-
15511 }
-
156
-
157 /// Set's the maximum idle timeout a client can have before getting
-
158 /// automatically disconnected. Set [`None`] to disable automatic
-
159 /// disconnecting completely.
-
160 ///
-
161 /// # Errors
-
162 /// [`Config::MaxIdleTimeout`](error::Config::MaxIdleTimeout) if time
-
163 /// exceeds 2^62 ms.
-
164 pub(in crate::quic::endpoint) fn set_max_idle_timeout(
-
165 &mut self,
-
166 time: Option<Duration>,
-
167 ) -> Result<(), error::Config> {
-
1680 if let Some(time) = time {
-
1690 let _ = IdleTimeout::try_from(time).map_err(|_error| error::Config::MaxIdleTimeout)?;
-
1700 }
-
171
-
1720 self.max_idle_timeout = time;
-
1730
-
1740 Ok(())
-
1750 }
-
176
-
177 /// Returns the set [`Duration`] specified for idle clients to automatically
-
178 /// get disconnected. [`None`] means clients don't get automatically
-
179 /// disconnected.
-
180 #[must_use]
-
1810 pub(in crate::quic::endpoint) const fn max_idle_timeout(&self) -> Option<Duration> {
-
1820 self.max_idle_timeout
-
1830 }
-
184
-
185 /// Builds a new [`ClientConfig`] with this [`Config`] and adds
-
186 /// [`Certificate`]s to the CA store.
-
187 ///
-
188 /// # Panics
-
189 /// Panics if the given [`KeyPair`] or [`Certificate`]s are invalid. Can't
-
190 /// happen if they were properly validated through [`KeyPair::from_parts`]
-
191 /// or [`Certificate::from_der`].
-
192 #[allow(clippy::unwrap_in_result)]
-
193248 pub(in crate::quic::endpoint) fn new_client(
-
194248 &self,
-
195248 certificates: &[Certificate],
-
196248 store: Store,
-
197248 client_key_pair: Option<KeyPair>,
-
198248 disable_server_verification: bool,
-
199248 ) -> Result<ClientConfig, OsStore> {
-
200 // disable server certificate verification if demanded
-
201248 let server_verifier: Arc<dyn ServerCertVerifier> = if disable_server_verification {
-
2021 NoServerCertVerification::new()
-
203 } else {
-
204 // set default root certificates
-
205247 let mut root_store = match store {
-
206113 Store::Empty => RootCertStore::empty(),
-
207 Store::Os => {
-
2081 let mut store = RootCertStore::empty();
-
209
-
2101 store.roots = rustls_native_certs::load_native_certs()
-
2111 .map_err(error::OsStore::Aquire)?
-
2121 .into_iter()
-
213137 .map(|certificate| {
-
214137 let ta = TrustAnchor::try_from_cert_der(&certificate.0)
-
215137 .map_err(error::OsStore::Parse)?;
-
216
-
217137 Ok(OwnedTrustAnchor::from_subject_spki_name_constraints(
-
218137 ta.subject,
-
219137 ta.spki,
-
220137 ta.name_constraints,
-
221137 ))
-
222137 })
-
2231 .collect::<Result<_, _>>()?;
-
224
-
2251 store
-
226 }
-
227 Store::Embedded => {
-
228133 let mut store = RootCertStore::empty();
-
229133
-
230133 store.add_server_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.0.iter().map(
-
23118487 |ta| {
-
23218487 OwnedTrustAnchor::from_subject_spki_name_constraints(
-
23318487 ta.subject,
-
23418487 ta.spki,
-
23518487 ta.name_constraints,
-
23618487 )
-
23718487 },
-
238133 ));
-
239133
-
240133 store
-
241 }
-
242 };
-
243
-
244 // add custom root certificates
-
245247 let additional_anchors = certificates.iter().map(|certificate| {
-
246113 let anchor = TrustAnchor::try_from_cert_der(certificate.as_ref())
-
247113 .expect("`Certificate` couldn't be parsed");
-
248113 OwnedTrustAnchor::from_subject_spki_name_constraints(
-
249113 anchor.subject,
-
250113 anchor.spki,
-
251113 anchor.name_constraints,
-
252113 )
-
253247 });
-
254247 root_store.add_server_trust_anchors(additional_anchors);
-
255
-
256 // Add certificate transparency logs
-
257 // TODO: configuratbility
-
258247 let ct_policy = match store {
-
259113 Store::Empty => None,
-
260134 Store::Os | Store::Embedded => Some(CertificateTransparencyPolicy::new(
-
261134 ct_logs::LOGS,
-
262134 // Add one year to last release.
-
263134 PrimitiveDateTime::new(
-
264134 #[allow(clippy::integer_arithmetic)]
-
265134 Date::from_calendar_date(2021 + 1, Month::April, 10).expect("invalid date"),
-
266134 Time::MIDNIGHT,
-
267134 )
-
268134 .assume_utc()
-
269134 .into(),
-
270134 )),
-
271 };
-
272
-
273247 Arc::new(WebPkiVerifier::new(root_store, ct_policy))
-
274 };
-
275
-
276248 let crypto = rustls::ClientConfig::builder()
-
277248 .with_safe_default_cipher_suites()
-
278248 .with_safe_default_kx_groups()
-
279248 .with_protocol_versions(&[&rustls::version::TLS13])
-
280248 .expect("failed to configure correct protocol")
-
281248 .with_custom_certificate_verifier(server_verifier);
+
36 trust_dns: bool,
+
37 /// Enables DNSSEC validation for [`trust-dns`](trust_dns_resolver).
+
38 #[cfg(feature = "trust-dns")]
+
39 dnssec: bool,
+
40 /// Enables `/etc/hosts` file support for [`trust-dns`](trust_dns_resolver).
+
41 #[cfg(feature = "trust-dns")]
+
42 hosts_file: bool,
+
43}
+
44
+
45impl Config {
+
46 /// Builds a new [`Config`].
+
47353 pub(super) const fn new() -> Self {
+
48353 Self {
+
49353 protocols: Vec::new(),
+
50353 // default set by quinn
+
51353 max_idle_timeout: Some(Duration::from_secs(10)),
+
52353 #[cfg(feature = "trust-dns")]
+
53353 trust_dns: true,
+
54353 #[cfg(feature = "trust-dns")]
+
55353 dnssec: true,
+
56353 #[cfg(feature = "trust-dns")]
+
57353 hosts_file: false,
+
58353 }
+
59353 }
+
60
+
61 /// Creates a with the correct settings [`TransportConfig`].
+
62688 pub(super) fn transport(&self) -> TransportConfig {
+
63688 let mut transport = TransportConfig::default();
+
64688
+
65688 // set transport defaults
+
66688 // TODO: research other settings
+
67688 let _ =
+
68688 transport
+
69688 // TODO: research if this is necessary, it improves privacy, but may hurt network
+
70688 // providers?
+
71688 .allow_spin(false)
+
72688 // we don't support unordered for now
+
73688 .datagram_receive_buffer_size(None)
+
74688 // for compatibility with WebRTC, we won't be using uni-directional streams
+
75688 .max_concurrent_uni_streams(quinn::VarInt::from_u32(0))
+
76688 .max_idle_timeout(self.max_idle_timeout.map(|time| {
+
77688 IdleTimeout::try_from(time).expect("unexpected failure conversion")
+
78688 }));
+
79688
+
80688 transport
+
81688 }
+
82
+
83 /// Set the application-layer protocols.
+
848 pub(super) fn set_protocols(&mut self, protocols: impl Into<Vec<Vec<u8>>>) {
+
858 self.protocols = protocols.into();
+
868 }
+
87
+
88 /// Returns the configured application-layer protocols.
+
8921 pub(super) fn protocols(&self) -> &[Vec<u8>] {
+
9021 self.protocols.as_slice()
+
9121 }
+
92
+
93 /// Controls the use of [`trust-dns`](trust_dns_resolver) for
+
94 /// [`Endpoint::connect`](crate::Endpoint::connect).
+
95 #[cfg(feature = "trust-dns")]
+
962 pub(super) fn set_trust_dns(&mut self, enable: bool) {
+
972 self.trust_dns = enable;
+
982 }
+
99
+
100 /// Disables the use of [`trust-dns`](trust_dns_resolver) for
+
101 /// [`Endpoint::connect`](crate::Endpoint::connect) despite the activates
+
102 /// crate features.
+
103 #[cfg_attr(not(feature = "trust-dns"), allow(clippy::unused_self))]
+
1043 pub(super) fn disable_trust_dns(&mut self) {
+
1053 #[cfg(feature = "trust-dns")]
+
1063 {
+
1073 self.trust_dns = false;
+
1083 }
+
1093 }
+
110
+
111 /// Returns if [`trust-dns`](trust_dns_resolver) is enabled.
+
112 #[cfg_attr(not(feature = "trust-dns"), allow(clippy::unused_self))]
+
11314 pub(in crate::quic::endpoint) const fn trust_dns(&self) -> bool {
+
11414 #[cfg(feature = "trust-dns")]
+
11514 return self.trust_dns;
+
11614 #[cfg(not(feature = "trust-dns"))]
+
11714 false
+
11814 }
+
119
+
120 /// Controls DNSSEC validation for [`trust-dns`](trust_dns_resolver).
+
121 #[cfg(feature = "trust-dns")]
+
1226 pub(super) fn set_dnssec(&mut self, enable: bool) {
+
1236 self.dnssec = enable;
+
1246 }
+
125
+
126 /// Returns if DNSSEC is enabled for [`trust-dns`](trust_dns_resolver).
+
127 #[cfg(feature = "trust-dns")]
+
12811 pub(in crate::quic::endpoint) const fn dnssec(&self) -> bool {
+
12911 self.dnssec
+
13011 }
+
131
+
132 /// Controls `/etc/hosts` file support for
+
133 /// [`trust-dns`](trust_dns_resolver).
+
134 #[cfg(feature = "trust-dns")]
+
1352 pub(super) fn set_hosts_file(&mut self, enable: bool) {
+
1362 self.hosts_file = enable;
+
1372 }
+
138
+
139 /// Returns if `/etc/hosts` file support is enabled for
+
140 /// [`trust-dns`](trust_dns_resolver).
+
141 #[cfg(feature = "trust-dns")]
+
14211 pub(in crate::quic::endpoint) const fn hosts_file(&self) -> bool {
+
14311 self.hosts_file
+
14411 }
+
145
+
146 /// Set's the maximum idle timeout a client can have before getting
+
147 /// automatically disconnected. Set [`None`] to disable automatic
+
148 /// disconnecting completely.
+
149 ///
+
150 /// # Errors
+
151 /// [`Config::MaxIdleTimeout`](error::Config::MaxIdleTimeout) if time
+
152 /// exceeds 2^62 ms.
+
153 pub(in crate::quic::endpoint) fn set_max_idle_timeout(
+
154 &mut self,
+
155 time: Option<Duration>,
+
156 ) -> Result<(), error::Config> {
+
1570 if let Some(time) = time {
+
1580 let _ = IdleTimeout::try_from(time).map_err(|_error| error::Config::MaxIdleTimeout)?;
+
1590 }
+
160
+
1610 self.max_idle_timeout = time;
+
1620
+
1630 Ok(())
+
1640 }
+
165
+
166 /// Returns the set [`Duration`] specified for idle clients to automatically
+
167 /// get disconnected. [`None`] means clients don't get automatically
+
168 /// disconnected.
+
169 #[must_use]
+
1700 pub(in crate::quic::endpoint) const fn max_idle_timeout(&self) -> Option<Duration> {
+
1710 self.max_idle_timeout
+
1720 }
+
173
+
174 /// Builds a new [`ClientConfig`] with this [`Config`] and adds
+
175 /// [`Certificate`]s to the CA store.
+
176 ///
+
177 /// # Panics
+
178 /// Panics if the given [`KeyPair`] or [`Certificate`]s are invalid. Can't
+
179 /// happen if they were properly validated through [`KeyPair::from_parts`]
+
180 /// or [`Certificate::from_der`].
+
181668 pub(in crate::quic::endpoint) fn new_client(
+
182668 &self,
+
183668 certificates: &[Certificate],
+
184668 store: Store,
+
185668 client_key_pair: Option<KeyPair>,
+
186668 disable_server_verification: bool,
+
187668 ) -> Result<ClientConfig, OsStore> {
+
188 // disable server certificate verification if demanded
+
189668 let server_verifier: Arc<dyn ServerCertVerifier> = if disable_server_verification {
+
1901 NoServerCertVerification::new()
+
191 } else {
+
192 // set default root certificates
+
193667 let mut root_store = match store {
+
194319 Store::Empty => RootCertStore::empty(),
+
195 Store::Os => {
+
1961 let mut store = RootCertStore::empty();
+
197
+
1981 store.roots = rustls_native_certs::load_native_certs()
+
1991 .map_err(error::OsStore::Aquire)?
+
2001 .into_iter()
+
201137 .map(|certificate| {
+
202137 let ta = TrustAnchor::try_from_cert_der(&certificate.0)
+
203137 .map_err(error::OsStore::Parse)?;
+
204
+
205137 Ok(OwnedTrustAnchor::from_subject_spki_name_constraints(
+
206137 ta.subject,
+
207137 ta.spki,
+
208137 ta.name_constraints,
+
209137 ))
+
210137 })
+
2111 .collect::<Result<_, _>>()?;
+
212
+
2131 store
+
214 }
+
215 Store::Embedded => {
+
216347 let mut store = RootCertStore::empty();
+
217347
+
21848927 store.add_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.iter().map(|ta| {
+
21948927 OwnedTrustAnchor::from_subject_spki_name_constraints(
+
22048927 ta.subject,
+
22148927 ta.spki,
+
22248927 ta.name_constraints,
+
22348927 )
+
22448927 }));
+
225347
+
226347 store
+
227 }
+
228 };
+
229
+
230 // add custom root certificates
+
231667 let additional_anchors = certificates.iter().map(|certificate| {
+
232319 let anchor = TrustAnchor::try_from_cert_der(certificate.as_ref())
+
233319 .expect("`Certificate` couldn't be parsed");
+
234319 OwnedTrustAnchor::from_subject_spki_name_constraints(
+
235319 anchor.subject,
+
236319 anchor.spki,
+
237319 anchor.name_constraints,
+
238319 )
+
239667 });
+
240667 root_store.add_trust_anchors(additional_anchors);
+
241
+
242 // Add certificate transparency logs
+
243 // TODO: configuratbility
+
244667 let ct_policy = match store {
+
245319 Store::Empty => None,
+
246348 Store::Os | Store::Embedded => Some(CertificateTransparencyPolicy::new(
+
247348 ct_logs::LOGS,
+
248348 // Add one year to last release.
+
249348 PrimitiveDateTime::new(
+
250348 Date::from_calendar_date(2021 + 1, Month::April, 10).expect("invalid date"),
+
251348 Time::MIDNIGHT,
+
252348 )
+
253348 .assume_utc()
+
254348 .into(),
+
255348 )),
+
256 };
+
257
+
258667 Arc::new(WebPkiVerifier::new(root_store, ct_policy))
+
259 };
+
260
+
261668 let crypto = rustls::ClientConfig::builder()
+
262668 .with_safe_default_cipher_suites()
+
263668 .with_safe_default_kx_groups()
+
264668 .with_protocol_versions(&[&rustls::version::TLS13])
+
265668 .expect("failed to configure correct protocol")
+
266668 .with_custom_certificate_verifier(server_verifier);
+
267
+
268668 let mut crypto = if let Some(key_pair) = client_key_pair {
+
2691 crypto.with_client_cert_resolver(CertificateResolver::new(key_pair))
+
270 } else {
+
271667 crypto.with_no_client_auth()
+
272 };
+
273
+
274668 crypto.enable_early_data = true;
+
275668 crypto.alpn_protocols = self.protocols.clone();
+
276668
+
277668 let mut client = ClientConfig::new(Arc::new(crypto));
+
278668 let _client = client.transport_config(Arc::new(self.transport()));
+
279668 Ok(client)
+
280668 }
+
281}
282
-
283248 let mut crypto = if let Some(key_pair) = client_key_pair {
-
2841 crypto.with_client_cert_resolver(CertificateResolver::new(key_pair))
-
285 } else {
-
286247 crypto.with_no_client_auth()
-
287 };
-
288
-
289248 crypto.enable_early_data = true;
-
290248 crypto.alpn_protocols = self.protocols.clone();
-
291248
-
292248 let mut client = ClientConfig::new(Arc::new(crypto));
-
293248 let _client = client.transport_config(Arc::new(self.transport()));
-
294248 Ok(client)
-
295248 }
-
296}
-
297
-
298/// Client certificate handler.
-
299struct CertificateResolver(Arc<CertifiedKey>);
-
300
-
301impl ResolvesClientCert for CertificateResolver {
-
3021 fn resolve(
-
3031 &self,
-
3041 _acceptable_issuers: &[&[u8]],
-
3051 _sigschemes: &[SignatureScheme],
-
3061 ) -> Option<Arc<CertifiedKey>> {
-
3071 Some(Arc::clone(&self.0))
-
3081 }
-
309
-
3101 fn has_certs(&self) -> bool {
-
3111 true
-
3121 }
-
313}
-
314
-
315impl CertificateResolver {
-
316 /// Builds a new [`CertificateResolver`].
-
3171 fn new(key_pair: KeyPair) -> Arc<Self> {
-
3181 Arc::new(Self(Arc::new(key_pair.into_rustls())))
-
3191 }
-
320}
-
321
-
322/// Disables clients verification of the servers [`Certificate`] when used with
-
323/// [`Endpoint::connect_unverified`].
-
324///
-
325/// [`Endpoint::connect_unverified`]:
-
326/// crate::dangerous::Endpoint::connect_unverified
-
327struct NoServerCertVerification;
-
328
-
329impl ServerCertVerifier for NoServerCertVerification {
-
3301 fn verify_server_cert(
-
3311 &self,
-
3321 _end_entity: &rustls::Certificate,
-
3331 _intermediates: &[rustls::Certificate],
-
3341 _server_name: &ServerName,
-
3351 _scts: &mut dyn Iterator<Item = &[u8]>,
-
3361 _ocsp_response: &[u8],
-
3371 _now: SystemTime,
-
3381 ) -> Result<ServerCertVerified, rustls::Error> {
-
3391 Ok(ServerCertVerified::assertion())
-
3401 }
-
341}
-
342
-
343impl NoServerCertVerification {
-
344 /// Builds a new [`NoServerCertVerification`].
-
3451 fn new() -> Arc<Self> {
-
3461 Arc::new(Self)
-
3471 }
-
348}
+
283/// Client certificate handler.
+
284struct CertificateResolver(Arc<CertifiedKey>);
+
285
+
286impl ResolvesClientCert for CertificateResolver {
+
2871 fn resolve(
+
2881 &self,
+
2891 _acceptable_issuers: &[&[u8]],
+
2901 _sigschemes: &[SignatureScheme],
+
2911 ) -> Option<Arc<CertifiedKey>> {
+
2921 Some(Arc::clone(&self.0))
+
2931 }
+
294
+
2951 fn has_certs(&self) -> bool {
+
2961 true
+
2971 }
+
298}
+
299
+
300impl CertificateResolver {
+
301 /// Builds a new [`CertificateResolver`].
+
3021 fn new(key_pair: KeyPair) -> Arc<Self> {
+
3031 Arc::new(Self(Arc::new(key_pair.into_rustls())))
+
3041 }
+
305}
+
306
+
307/// Disables clients verification of the servers [`Certificate`] when used with
+
308/// [`Endpoint::connect_unverified`].
+
309///
+
310/// [`Endpoint::connect_unverified`]:
+
311/// crate::dangerous::Endpoint::connect_unverified
+
312struct NoServerCertVerification;
+
313
+
314impl ServerCertVerifier for NoServerCertVerification {
+
3151 fn verify_server_cert(
+
3161 &self,
+
3171 _end_entity: &rustls::Certificate,
+
3181 _intermediates: &[rustls::Certificate],
+
3191 _server_name: &ServerName,
+
3201 _scts: &mut dyn Iterator<Item = &[u8]>,
+
3211 _ocsp_response: &[u8],
+
3221 _now: SystemTime,
+
3231 ) -> Result<ServerCertVerified, rustls::Error> {
+
3241 Ok(ServerCertVerified::assertion())
+
3251 }
+
326}
+
327
+
328impl NoServerCertVerification {
+
329 /// Builds a new [`NoServerCertVerification`].
+
3301 fn new() -> Arc<Self> {
+
3311 Arc::new(Self)
+
3321 }
+
333}
diff --git a/coverage/src/quic/endpoint/builder/index.html b/coverage/src/quic/endpoint/builder/index.html index b98792f..4bd4b3b 100644 --- a/coverage/src/quic/endpoint/builder/index.html +++ b/coverage/src/quic/endpoint/builder/index.html @@ -9,19 +9,19 @@
Current view:top level - src/quic/endpoint/builder
-
Date:2023-07-07 10:30:44
+
Date:2023-08-25 14:31:32
HitTotalCoverage
-
Lines57962792.3 %
+
Lines58463392.3 %
Functions11319757.4 %
Branches000.0 %
FilenameLine CoverageFunctionsBranches
-
config.rs94.5%173 / 18357.7%30 / 520.0%0 / 0
-
mod.rs91.4%406 / 44457.2%83 / 1450.0%0 / 0
+
config.rs94.4%170 / 18057.7%30 / 520.0%0 / 0
+
mod.rs91.4%414 / 45357.2%83 / 1450.0%0 / 0
diff --git a/coverage/src/quic/endpoint/builder/mod.rs.html b/coverage/src/quic/endpoint/builder/mod.rs.html index ab33df1..ff1a245 100644 --- a/coverage/src/quic/endpoint/builder/mod.rs.html +++ b/coverage/src/quic/endpoint/builder/mod.rs.html @@ -9,11 +9,11 @@
Current view:top level - src/quic/endpoint/builder - mod.rs
-
Date:2023-07-07 10:30:44
+
Date:2023-08-25 14:31:32
HitTotalCoverage
-
Lines40644491.4 %
+
Lines41445391.4 %
Functions8314557.2 %
Branches000.0 %
@@ -87,23 +87,23 @@
66 /// let mut endpoint = Builder::new().build()?;
67 /// # Ok(()) }
68 /// ```
-
69139 pub fn new() -> Self {
-
70139 let config = Config::new();
-
71139
-
72139 Self {
-
73139 #[cfg(not(feature = "test"))]
-
74139 address: ([0; 8], 0).into(),
-
75139 // while testing always use the default loopback address
-
76139 #[cfg(feature = "test")]
-
77139 address: ([0, 0, 0, 0, 0, 0, 0, 1], 0).into(),
-
78139 reuse_address: false,
-
79139 root_certificates: Vec::new(),
-
80139 server_key_pair: None,
-
81139 client_key_pair: None,
-
82139 store: Store::Embedded,
-
83139 config,
-
84139 }
-
85139 }
+
69353 pub fn new() -> Self {
+
70353 let config = Config::new();
+
71353
+
72353 Self {
+
73353 #[cfg(not(feature = "test"))]
+
74353 address: ([0; 8], 0).into(),
+
75353 // while testing always use the default loopback address
+
76353 #[cfg(feature = "test")]
+
77353 address: ([0, 0, 0, 0, 0, 0, 0, 1], 0).into(),
+
78353 reuse_address: false,
+
79353 root_certificates: Vec::new(),
+
80353 server_key_pair: None,
+
81353 client_key_pair: None,
+
82353 store: Store::Embedded,
+
83353 config,
+
84353 }
+
85353 }
86
87 /// Set's the [`SocketAddr`] to bind to.
88 ///
@@ -119,9 +119,9 @@
98 /// builder.set_address("[::1]:0".parse()?);
99 /// # Ok(()) }
100 /// ```
-
10111 pub fn set_address(&mut self, address: SocketAddr) {
-
10211 self.address = address;
-
10311 }
+
10119 pub fn set_address(&mut self, address: SocketAddr) {
+
10219 self.address = address;
+
10319 }
104
105 /// Returns the [`SocketAddr`] to bind to.
106 ///
@@ -178,9 +178,9 @@
157 /// let mut builder = Builder::new();
158 /// builder.set_server_key_pair(Some(KeyPair::new_self_signed("test")));
159 /// ```
-
16012 pub fn set_server_key_pair(&mut self, key_pair: Option<KeyPair>) {
-
16112 self.server_key_pair = key_pair;
-
16212 }
+
16020 pub fn set_server_key_pair(&mut self, key_pair: Option<KeyPair>) {
+
16120 self.server_key_pair = key_pair;
+
16220 }
163
164 /// Returns the server certificate [`KeyPair`].
165 ///
@@ -293,728 +293,728 @@
272 /// builder.set_trust_dns(false);
273 /// ```
274 #[cfg(feature = "trust-dns")]
-
275 #[cfg_attr(doc, doc(cfg(feature = "trust-dns")))]
-
2762 pub fn set_trust_dns(&mut self, enable: bool) {
-
2772 self.config.set_trust_dns(enable);
-
2782 }
-
279
-
280 /// Disables the use of [`trust-dns`](trust_dns_resolver) for
-
281 /// [`Endpoint::connect`] despite the activated crate feature.
-
282 ///
-
283 /// # Default
-
284 /// Not disabled if the crate feature <span
-
285 /// class="module-item stab portability"
-
286 /// style="display: inline; border-radius: 3px; padding: 2px; font-size:
-
287 /// 80%; line-height: 1.2;" ><code>trust-dns</code></span> is enabled.
-
288 ///
-
289 /// # Examples
-
290 /// ```
-
291 /// use fabruic::Builder;
-
292 ///
-
293 /// let mut builder = Builder::new();
-
294 /// builder.disable_trust_dns();
-
295 /// ```
-
2963 pub fn disable_trust_dns(&mut self) {
-
2973 self.config.disable_trust_dns();
-
2983 }
-
299
-
300 /// Returns if [`trust-dns`](trust_dns_resolver) is enabled.
-
301 ///
-
302 /// See [`set_trust_dns`](Self::set_trust_dns) or
-
303 /// [`disable_trust_dns`](Self::disable_trust_dns).
-
304 ///
-
305 /// # Examples
-
306 /// ```
-
307 /// use fabruic::Builder;
-
308 ///
-
309 /// let mut builder = Builder::new();
-
310 ///
-
311 /// builder.set_trust_dns(true);
-
312 /// assert_eq!(builder.trust_dns(), true);
-
313 ///
-
314 /// builder.disable_trust_dns();
-
315 /// assert_eq!(builder.trust_dns(), false);
-
316 /// ```
-
317 #[must_use]
-
3184 pub const fn trust_dns(&self) -> bool {
-
3194 self.config.trust_dns()
-
3204 }
-
321
-
322 /// Controls DNSSEC validation for [`trust-dns`](trust_dns_resolver) in
-
323 /// [`Endpoint::connect`]. This doesn't affect the
-
324 /// [`ToSocketAddrs`](std::net::ToSocketAddrs) resolver.
-
325 ///
-
326 /// # Default
-
327 /// [`true`].
-
328 ///
-
329 /// # Examples
-
330 /// ```
-
331 /// use fabruic::Builder;
-
332 ///
-
333 /// let mut builder = Builder::new();
-
334 /// builder.set_dnssec(false);
-
335 /// ```
-
336 #[cfg(feature = "trust-dns")]
-
337 #[cfg_attr(doc, doc(cfg(feature = "trust-dns")))]
-
3386 pub fn set_dnssec(&mut self, enable: bool) {
-
3396 self.config.set_dnssec(enable);
-
3406 }
-
341
-
342 /// Returns if DNSSEC is enabled for [`trust-dns`](trust_dns_resolver).
+
2752 pub fn set_trust_dns(&mut self, enable: bool) {
+
2762 self.config.set_trust_dns(enable);
+
2772 }
+
278
+
279 /// Disables the use of [`trust-dns`](trust_dns_resolver) for
+
280 /// [`Endpoint::connect`] despite the activated crate feature.
+
281 ///
+
282 /// # Default
+
283 /// Not disabled if the crate feature <span
+
284 /// class="module-item stab portability"
+
285 /// style="display: inline; border-radius: 3px; padding: 2px; font-size:
+
286 /// 80%; line-height: 1.2;" ><code>trust-dns</code></span> is enabled.
+
287 ///
+
288 /// # Examples
+
289 /// ```
+
290 /// use fabruic::Builder;
+
291 ///
+
292 /// let mut builder = Builder::new();
+
293 /// builder.disable_trust_dns();
+
294 /// ```
+
2953 pub fn disable_trust_dns(&mut self) {
+
2963 self.config.disable_trust_dns();
+
2973 }
+
298
+
299 /// Returns if [`trust-dns`](trust_dns_resolver) is enabled.
+
300 ///
+
301 /// See [`set_trust_dns`](Self::set_trust_dns) or
+
302 /// [`disable_trust_dns`](Self::disable_trust_dns).
+
303 ///
+
304 /// # Examples
+
305 /// ```
+
306 /// use fabruic::Builder;
+
307 ///
+
308 /// let mut builder = Builder::new();
+
309 ///
+
310 /// builder.set_trust_dns(true);
+
311 /// assert_eq!(builder.trust_dns(), true);
+
312 ///
+
313 /// builder.disable_trust_dns();
+
314 /// assert_eq!(builder.trust_dns(), false);
+
315 /// ```
+
316 #[must_use]
+
3174 pub const fn trust_dns(&self) -> bool {
+
3184 self.config.trust_dns()
+
3194 }
+
320
+
321 /// Controls DNSSEC validation for [`trust-dns`](trust_dns_resolver) in
+
322 /// [`Endpoint::connect`]. This doesn't affect the
+
323 /// [`ToSocketAddrs`](std::net::ToSocketAddrs) resolver.
+
324 ///
+
325 /// # Default
+
326 /// [`true`].
+
327 ///
+
328 /// # Examples
+
329 /// ```
+
330 /// use fabruic::Builder;
+
331 ///
+
332 /// let mut builder = Builder::new();
+
333 /// builder.set_dnssec(false);
+
334 /// ```
+
335 #[cfg(feature = "trust-dns")]
+
3366 pub fn set_dnssec(&mut self, enable: bool) {
+
3376 self.config.set_dnssec(enable);
+
3386 }
+
339
+
340 /// Returns if DNSSEC is enabled for [`trust-dns`](trust_dns_resolver).
+
341 ///
+
342 /// See [`set_dnssec`](Self::set_dnssec).
343 ///
-
344 /// See [`set_dnssec`](Self::set_dnssec).
-
345 ///
-
346 /// # Examples
-
347 /// ```
-
348 /// use fabruic::Builder;
+
344 /// # Examples
+
345 /// ```
+
346 /// use fabruic::Builder;
+
347 ///
+
348 /// let mut builder = Builder::new();
349 ///
-
350 /// let mut builder = Builder::new();
-
351 ///
-
352 /// builder.set_dnssec(false);
-
353 /// assert_eq!(builder.dnssec(), false);
-
354 /// ```
-
355 #[must_use]
-
356 #[cfg(feature = "trust-dns")]
-
357 #[cfg_attr(doc, doc(cfg(feature = "trust-dns")))]
-
3583 pub const fn dnssec(&self) -> bool {
-
3593 self.config.dnssec()
-
3603 }
-
361
-
362 /// Controls `/etc/hosts` file support for [`trust-dns`](trust_dns_resolver)
-
363 /// in [`Endpoint::connect`]. This doesn't affect the
-
364 /// [`ToSocketAddrs`](std::net::ToSocketAddrs) resolver.
+
350 /// builder.set_dnssec(false);
+
351 /// assert_eq!(builder.dnssec(), false);
+
352 /// ```
+
353 #[must_use]
+
354 #[cfg(feature = "trust-dns")]
+
3553 pub const fn dnssec(&self) -> bool {
+
3563 self.config.dnssec()
+
3573 }
+
358
+
359 /// Controls `/etc/hosts` file support for [`trust-dns`](trust_dns_resolver)
+
360 /// in [`Endpoint::connect`]. This doesn't affect the
+
361 /// [`ToSocketAddrs`](std::net::ToSocketAddrs) resolver.
+
362 ///
+
363 /// # Default
+
364 /// [`false`]. Only affects UNIX like OS's.
365 ///
-
366 /// # Default
-
367 /// [`false`]. Only affects UNIX like OS's.
-
368 ///
-
369 /// # Examples
-
370 /// ```
-
371 /// use fabruic::Builder;
-
372 ///
-
373 /// let mut builder = Builder::new();
-
374 /// builder.set_hosts_file(false);
-
375 /// ```
-
376 #[cfg(feature = "trust-dns")]
-
377 #[cfg_attr(doc, doc(cfg(feature = "trust-dns")))]
-
3782 pub fn set_hosts_file(&mut self, enable: bool) {
-
3792 self.config.set_hosts_file(enable);
-
3802 }
-
381
-
382 /// Returns if `/etc/hosts` file support is enabled for
-
383 /// [`trust-dns`](trust_dns_resolver).
-
384 ///
-
385 /// See [`set_dnssec`](Self::set_hosts_file).
+
366 /// # Examples
+
367 /// ```
+
368 /// use fabruic::Builder;
+
369 ///
+
370 /// let mut builder = Builder::new();
+
371 /// builder.set_hosts_file(false);
+
372 /// ```
+
373 #[cfg(feature = "trust-dns")]
+
3742 pub fn set_hosts_file(&mut self, enable: bool) {
+
3752 self.config.set_hosts_file(enable);
+
3762 }
+
377
+
378 /// Returns if `/etc/hosts` file support is enabled for
+
379 /// [`trust-dns`](trust_dns_resolver).
+
380 ///
+
381 /// See [`set_dnssec`](Self::set_hosts_file).
+
382 ///
+
383 /// # Examples
+
384 /// ```
+
385 /// use fabruic::Builder;
386 ///
-
387 /// # Examples
-
388 /// ```
-
389 /// use fabruic::Builder;
-
390 ///
-
391 /// let mut builder = Builder::new();
-
392 ///
-
393 /// builder.set_hosts_file(true);
-
394 /// assert_eq!(builder.hosts_file(), true);
-
395 /// ```
-
396 #[must_use]
-
397 #[cfg(feature = "trust-dns")]
-
398 #[cfg_attr(doc, doc(cfg(feature = "trust-dns")))]
-
3993 pub const fn hosts_file(&self) -> bool {
-
4003 self.config.hosts_file()
-
4013 }
-
402
-
403 /// Set's the default root certificate store.
+
387 /// let mut builder = Builder::new();
+
388 ///
+
389 /// builder.set_hosts_file(true);
+
390 /// assert_eq!(builder.hosts_file(), true);
+
391 /// ```
+
392 #[must_use]
+
393 #[cfg(feature = "trust-dns")]
+
3943 pub const fn hosts_file(&self) -> bool {
+
3953 self.config.hosts_file()
+
3963 }
+
397
+
398 /// Set's the default root certificate store.
+
399 ///
+
400 /// See [`Store`] for more details.
+
401 ///
+
402 /// # Default
+
403 /// [`Store::Embedded`].
404 ///
-
405 /// See [`Store`] for more details.
-
406 ///
-
407 /// # Default
-
408 /// [`Store::Embedded`].
-
409 ///
-
410 /// # Examples
+
405 /// # Examples
+
406 /// ```
+
407 /// use fabruic::{Builder, Store};
+
408 ///
+
409 /// let mut builder = Builder::new();
+
410 /// builder.set_store(Store::Os);
411 /// ```
-
412 /// use fabruic::{Builder, Store};
-
413 ///
-
414 /// let mut builder = Builder::new();
-
415 /// builder.set_store(Store::Os);
-
416 /// ```
-
4173 pub fn set_store(&mut self, store: Store) {
-
4183 self.store = store;
-
4193 }
-
420
-
421 /// Returns the set [`Store`].
-
422 ///
-
423 /// See [`set_store`](Self::set_store).
-
424 ///
-
425 /// # Examples
-
426 /// ```
-
427 /// use fabruic::{Builder, Store};
+
4123 pub fn set_store(&mut self, store: Store) {
+
4133 self.store = store;
+
4143 }
+
415
+
416 /// Returns the set [`Store`].
+
417 ///
+
418 /// See [`set_store`](Self::set_store).
+
419 ///
+
420 /// # Examples
+
421 /// ```
+
422 /// use fabruic::{Builder, Store};
+
423 ///
+
424 /// let mut builder = Builder::new();
+
425 ///
+
426 /// // default
+
427 /// assert_eq!(builder.store(), Store::Embedded);
428 ///
-
429 /// let mut builder = Builder::new();
-
430 ///
-
431 /// // default
-
432 /// assert_eq!(builder.store(), Store::Embedded);
-
433 ///
-
434 /// builder.set_store(Store::Os);
-
435 /// assert_eq!(builder.store(), Store::Os);
-
436 ///
-
437 /// builder.set_store(Store::Empty);
-
438 /// assert_eq!(builder.store(), Store::Empty);
-
439 /// ```
-
4404 pub const fn store(&self) -> Store {
-
4414 self.store
-
4424 }
-
443
-
444 /// Set's the maximum idle timeout a client can have before getting
-
445 /// automatically disconnected. Set [`None`] to disable automatic
-
446 /// disconnecting completely.
-
447 ///
-
448 /// # Default
-
449 /// 10s
-
450 ///
-
451 /// # Examples
-
452 /// ```
-
453 /// use std::time::Duration;
-
454 ///
-
455 /// use fabruic::{Builder, Store};
-
456 ///
-
457 /// let mut builder = Builder::new();
-
458 /// builder.set_max_idle_timeout(Some(Duration::from_millis(1000)));
-
459 /// ```
-
460 ///
-
461 /// # Errors
-
462 /// [`Config::MaxIdleTimeout`](error::Config::MaxIdleTimeout) if time
-
463 /// exceeds 2^62 ms.
-
464 #[allow(clippy::unwrap_in_result)]
-
4650 pub fn set_max_idle_timeout(&mut self, time: Option<Duration>) -> Result<(), error::Config> {
-
4660 self.config.set_max_idle_timeout(time)
-
4670 }
-
468
-
469 /// Returns the set [`Duration`] specified for idle clients to automatically
-
470 /// get disconnected. [`None`] means clients don't get automatically
-
471 /// disconnected.
+
429 /// builder.set_store(Store::Os);
+
430 /// assert_eq!(builder.store(), Store::Os);
+
431 ///
+
432 /// builder.set_store(Store::Empty);
+
433 /// assert_eq!(builder.store(), Store::Empty);
+
434 /// ```
+
4354 pub const fn store(&self) -> Store {
+
4364 self.store
+
4374 }
+
438
+
439 /// Set's the maximum idle timeout a client can have before getting
+
440 /// automatically disconnected. Set [`None`] to disable automatic
+
441 /// disconnecting completely.
+
442 ///
+
443 /// # Default
+
444 /// 10s
+
445 ///
+
446 /// # Examples
+
447 /// ```
+
448 /// use std::time::Duration;
+
449 ///
+
450 /// use fabruic::{Builder, Store};
+
451 ///
+
452 /// let mut builder = Builder::new();
+
453 /// builder.set_max_idle_timeout(Some(Duration::from_millis(1000)));
+
454 /// ```
+
455 ///
+
456 /// # Errors
+
457 /// [`Config::MaxIdleTimeout`](error::Config::MaxIdleTimeout) if time
+
458 /// exceeds 2^62 ms.
+
4590 pub fn set_max_idle_timeout(&mut self, time: Option<Duration>) -> Result<(), error::Config> {
+
4600 self.config.set_max_idle_timeout(time)
+
4610 }
+
462
+
463 /// Returns the set [`Duration`] specified for idle clients to automatically
+
464 /// get disconnected. [`None`] means clients don't get automatically
+
465 /// disconnected.
+
466 ///
+
467 /// See [`set_max_idle_timeout`](Self::set_max_idle_timeout).
+
468 ///
+
469 /// # Examples
+
470 /// ```
+
471 /// use std::time::Duration;
472 ///
-
473 /// See [`set_max_idle_timeout`](Self::set_max_idle_timeout).
+
473 /// use fabruic::{Builder, Store};
474 ///
-
475 /// # Examples
-
476 /// ```
-
477 /// use std::time::Duration;
-
478 ///
-
479 /// use fabruic::{Builder, Store};
-
480 ///
-
481 /// let mut builder = Builder::new();
+
475 /// let mut builder = Builder::new();
+
476 ///
+
477 /// // default
+
478 /// assert_eq!(builder.max_idle_timeout(), Some(Duration::from_secs(10)));
+
479 ///
+
480 /// builder.set_max_idle_timeout(None);
+
481 /// assert_eq!(builder.max_idle_timeout(), None);
482 ///
-
483 /// // default
-
484 /// assert_eq!(builder.max_idle_timeout(), Some(Duration::from_secs(10)));
-
485 ///
-
486 /// builder.set_max_idle_timeout(None);
-
487 /// assert_eq!(builder.max_idle_timeout(), None);
-
488 ///
-
489 /// builder.set_max_idle_timeout(Some(Duration::from_secs(30)));
-
490 /// assert_eq!(builder.max_idle_timeout(), Some(Duration::from_secs(30)));
-
491 /// ```
-
492 #[must_use]
-
4930 pub const fn max_idle_timeout(&self) -> Option<Duration> {
-
4940 self.config.max_idle_timeout()
-
4950 }
-
496
-
497 /// Consumes [`Builder`] to build [`Endpoint`]. Must be called from inside a
-
498 /// Tokio [`Runtime`](tokio::runtime::Runtime).
-
499 ///
-
500 /// # Errors
-
501 /// [`error::Builder`] if the socket couldn't be bound to the given
-
502 /// `address`.
+
483 /// builder.set_max_idle_timeout(Some(Duration::from_secs(30)));
+
484 /// assert_eq!(builder.max_idle_timeout(), Some(Duration::from_secs(30)));
+
485 /// ```
+
486 #[must_use]
+
4870 pub const fn max_idle_timeout(&self) -> Option<Duration> {
+
4880 self.config.max_idle_timeout()
+
4890 }
+
490
+
491 /// Consumes [`Builder`] to build [`Endpoint`]. Must be called from inside a
+
492 /// Tokio [`Runtime`](tokio::runtime::Runtime).
+
493 ///
+
494 /// # Errors
+
495 /// [`error::Builder`] if the socket couldn't be bound to the given
+
496 /// `address`.
+
497 ///
+
498 /// # Panics
+
499 /// - if the given [`KeyPair`]s or [`Certificate`]s are invalid - can't
+
500 /// happen if they were properly validated through [`KeyPair::from_parts`]
+
501 /// or [`Certificate::from_der`]
+
502 /// - if not called from inside a Tokio [`Runtime`](tokio::runtime::Runtime)
503 ///
-
504 /// # Panics
-
505 /// - if the given [`KeyPair`]s or [`Certificate`]s are invalid - can't
-
506 /// happen if they were properly validated through [`KeyPair::from_parts`]
-
507 /// or [`Certificate::from_der`]
-
508 /// - if not called from inside a Tokio [`Runtime`](tokio::runtime::Runtime)
-
509 ///
-
510 /// # Examples
+
504 /// # Examples
+
505 /// ```
+
506 /// # #[tokio::main] async fn main() -> anyhow::Result<()> {
+
507 /// use fabruic::Builder;
+
508 ///
+
509 /// let endpoint = Builder::new().build()?;
+
510 /// # Ok(()) }
511 /// ```
-
512 /// # #[tokio::main] async fn main() -> anyhow::Result<()> {
-
513 /// use fabruic::Builder;
-
514 ///
-
515 /// let endpoint = Builder::new().build()?;
-
516 /// # Ok(()) }
-
517 /// ```
-
518 #[allow(clippy::result_large_err)]
-
519135 pub fn build(self) -> Result<Endpoint, error::Builder> {
-
520135 match {
-
521135 // build client
-
522135 let client = match self.config.new_client(
-
523135 &self.root_certificates,
-
524135 self.store,
-
525135 self.client_key_pair.clone(),
-
526135 false,
-
527135 ) {
-
528135 Ok(client) => client,
-
5290 Err(error) =>
-
5300 return Err(error::Builder {
-
5310 error: error.into(),
-
5320 builder: self,
-
5330 }),
-
534 };
-
535
-
536 // build server only if we have a key-pair
-
537135 let server = self.server_key_pair.as_ref().map(|key_pair| {
-
53812 let mut crypto = rustls::ServerConfig::builder()
-
53912 .with_safe_default_cipher_suites()
-
54012 .with_safe_default_kx_groups()
-
54112 .with_protocol_versions(&[&rustls::version::TLS13])
-
54212 .expect("failed to configure correct protocol")
-
54312 .with_client_cert_verifier(Arc::new(ClientVerifier))
-
54412 .with_single_cert(
-
54512 key_pair.certificate_chain().clone().into_rustls(),
-
54612 key_pair.private_key().clone().into_rustls(),
-
54712 )
-
54812 .expect("`CertificateChain` couldn't be verified");
-
54912
-
55012 // set protocols
-
55112 crypto.alpn_protocols = self.config.protocols().to_vec();
-
55212
-
55312 let mut server = quinn::ServerConfig::with_crypto(Arc::new(crypto));
-
55412
-
55512 // set transport
-
55612 server.transport = Arc::new(self.config.transport());
-
55712
-
55812 server
-
559135 });
-
560135
-
561135 Endpoint::new(
-
562135 self.address,
-
563135 self.reuse_address,
-
564135 client,
-
565135 server,
-
566135 self.config.clone(),
-
567135 )
-
568 } {
-
569135 Ok(endpoint) => Ok(endpoint),
-
5700 Err(error) => Err(error::Builder {
-
5710 error: error::Config::Bind(error),
-
5720 builder: self,
-
5730 }),
-
574 }
-
575135 }
-
576}
-
577
-
578/// Client certificate verifier accepting anything. Verification has to happen
-
579/// on an application level.
-
580struct ClientVerifier;
-
581
-
582impl ClientCertVerifier for ClientVerifier {
-
583109 fn client_auth_mandatory(&self) -> bool {
-
584109 false
-
585109 }
-
586
-
587110 fn client_auth_root_subjects(&self) -> &[DistinguishedName] {
-
588110 &[]
-
589110 }
-
590
-
5911 fn verify_client_cert(
-
5921 &self,
-
5931 _end_entity: &rustls::Certificate,
-
5941 _intermediates: &[rustls::Certificate],
-
5951 _now: SystemTime,
-
5961 ) -> Result<ClientCertVerified, rustls::Error> {
-
5971 Ok(ClientCertVerified::assertion())
-
5981 }
-
599}
-
600
-
601/// Configuration option for [`Builder::set_store`].
-
602///
-
603/// # Examples
-
604/// ```
-
605/// use fabruic::{Builder, Store};
-
606///
-
607/// let mut builder = Builder::new();
-
608/// builder.set_store(Store::Os);
-
609/// ```
-
610#[must_use = "doesn't do anything unless passed into `Builder::set_store`"]
-
6114#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
-
612pub enum Store {
-
613 /// Empty root certificate store.
-
614 Empty,
-
615 /// Uses the OS root certificate store, see
-
616 /// [`rustls-native-certs`](rustls_native_certs).
-
617 Os,
-
618 /// Use an embedded root certificate store, see
-
619 /// [`webpki-roots`](webpki_roots).
-
620 Embedded,
-
621}
-
622
-
623/// Security-sensitive configuration for [`Builder`].
-
624pub trait Dangerous {
-
625 /// Set [`Certificate`]s to be added into the root certificate store for
-
626 /// [`connect`](Endpoint::connect)ing to a server. This is added
-
627 /// additionally to the [`Store`] root certificates and does **not** replace
-
628 /// them.
-
629 ///
-
630 /// See [`Builder::set_store`].
-
631 ///
-
632 /// # Default
-
633 /// No additional [`Certificate`]s.
-
634 ///
-
635 /// # Security
-
636 /// Managing your own root certificate store can make sense if a private CA
-
637 /// is used. Otherwise use [`Endpoint::connect_pinned`].
-
638 ///
-
639 /// # Examples
-
640 /// ```
-
641 /// use fabruic::{dangerous, Builder, Store};
-
642 ///
-
643 /// let mut builder = Builder::new();
-
644 /// builder.set_store(Store::Empty);
-
645 /// // CA certificate has to be imported from somewhere else
-
646 /// # let (server_certificate, _) = fabruic::KeyPair::new_self_signed("localhost").into_parts();
-
647 /// # let ca_certificate = server_certificate.into_end_entity_certificate();
-
648 /// dangerous::Builder::set_root_certificates(&mut builder, [ca_certificate]);
-
649 /// ```
-
650 fn set_root_certificates<C: Into<Vec<Certificate>>>(builder: &mut Self, certificates: C);
-
651
-
652 /// Returns [`Certificate`]s set to be added into the root certificate
-
653 /// store.
+
512 #[allow(clippy::result_large_err)]
+
513349 pub fn build(self) -> Result<Endpoint, error::Builder> {
+
514349 match {
+
515349 // build client
+
516349 let client = match self.config.new_client(
+
517349 &self.root_certificates,
+
518349 self.store,
+
519349 self.client_key_pair.clone(),
+
520349 false,
+
521349 ) {
+
522349 Ok(client) => client,
+
5230 Err(error) =>
+
5240 return Err(error::Builder {
+
5250 error: error.into(),
+
5260 builder: self,
+
5270 }),
+
528 };
+
529
+
530 // build server only if we have a key-pair
+
531349 let server = self.server_key_pair.as_ref().map(|key_pair| {
+
53220 let mut crypto = rustls::ServerConfig::builder()
+
53320 .with_safe_default_cipher_suites()
+
53420 .with_safe_default_kx_groups()
+
53520 .with_protocol_versions(&[&rustls::version::TLS13])
+
53620 .expect("failed to configure correct protocol")
+
53720 .with_client_cert_verifier(Arc::new(ClientVerifier))
+
53820 .with_single_cert(
+
53920 key_pair.certificate_chain().clone().into_rustls(),
+
54020 key_pair.private_key().clone().into_rustls(),
+
54120 )
+
54220 .expect("`CertificateChain` couldn't be verified");
+
54320
+
54420 // set protocols
+
54520 crypto.alpn_protocols = self.config.protocols().to_vec();
+
54620
+
54720 let mut server = quinn::ServerConfig::with_crypto(Arc::new(crypto));
+
54820
+
54920 // set transport
+
55020 server.transport = Arc::new(self.config.transport());
+
55120
+
55220 server
+
553349 });
+
554349
+
555349 Endpoint::new(
+
556349 self.address,
+
557349 self.reuse_address,
+
558349 client,
+
559349 server,
+
560349 self.config.clone(),
+
561349 )
+
562 } {
+
563349 Ok(endpoint) => Ok(endpoint),
+
5640 Err(error) => Err(error::Builder {
+
5650 error: error::Config::Bind(error),
+
5660 builder: self,
+
5670 }),
+
568 }
+
569349 }
+
570}
+
571
+
572/// Client certificate verifier accepting anything. Verification has to happen
+
573/// on an application level.
+
574struct ClientVerifier;
+
575
+
576impl ClientCertVerifier for ClientVerifier {
+
577315 fn client_auth_mandatory(&self) -> bool {
+
578315 false
+
579315 }
+
580
+
581316 fn client_auth_root_subjects(&self) -> &[DistinguishedName] {
+
582316 &[]
+
583316 }
+
584
+
5851 fn verify_client_cert(
+
5861 &self,
+
5871 _end_entity: &rustls::Certificate,
+
5881 _intermediates: &[rustls::Certificate],
+
5891 _now: SystemTime,
+
5901 ) -> Result<ClientCertVerified, rustls::Error> {
+
5911 Ok(ClientCertVerified::assertion())
+
5921 }
+
593}
+
594
+
595/// Configuration option for [`Builder::set_store`].
+
596///
+
597/// # Examples
+
598/// ```
+
599/// use fabruic::{Builder, Store};
+
600///
+
601/// let mut builder = Builder::new();
+
602/// builder.set_store(Store::Os);
+
603/// ```
+
604#[must_use = "doesn't do anything unless passed into `Builder::set_store`"]
+
6054#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
+
606pub enum Store {
+
607 /// Empty root certificate store.
+
608 Empty,
+
609 /// Uses the OS root certificate store, see
+
610 /// [`rustls-native-certs`](rustls_native_certs).
+
611 Os,
+
612 /// Use an embedded root certificate store, see
+
613 /// [`webpki-roots`](webpki_roots).
+
614 Embedded,
+
615}
+
616
+
617/// Security-sensitive configuration for [`Builder`].
+
618pub trait Dangerous {
+
619 /// Set [`Certificate`]s to be added into the root certificate store for
+
620 /// [`connect`](Endpoint::connect)ing to a server. This is added
+
621 /// additionally to the [`Store`] root certificates and does **not** replace
+
622 /// them.
+
623 ///
+
624 /// See [`Builder::set_store`].
+
625 ///
+
626 /// # Default
+
627 /// No additional [`Certificate`]s.
+
628 ///
+
629 /// # Security
+
630 /// Managing your own root certificate store can make sense if a private CA
+
631 /// is used. Otherwise use [`Endpoint::connect_pinned`].
+
632 ///
+
633 /// # Examples
+
634 /// ```
+
635 /// use fabruic::{dangerous, Builder, Store};
+
636 ///
+
637 /// let mut builder = Builder::new();
+
638 /// builder.set_store(Store::Empty);
+
639 /// // CA certificate has to be imported from somewhere else
+
640 /// # let (server_certificate, _) = fabruic::KeyPair::new_self_signed("localhost").into_parts();
+
641 /// # let ca_certificate = server_certificate.into_end_entity_certificate();
+
642 /// dangerous::Builder::set_root_certificates(&mut builder, [ca_certificate]);
+
643 /// ```
+
644 fn set_root_certificates<C: Into<Vec<Certificate>>>(builder: &mut Self, certificates: C);
+
645
+
646 /// Returns [`Certificate`]s set to be added into the root certificate
+
647 /// store.
+
648 ///
+
649 /// See [`set_root_certificates`](Self::set_root_certificates).
+
650 ///
+
651 /// # Examples
+
652 /// ```
+
653 /// use fabruic::{dangerous, Builder, Store};
654 ///
-
655 /// See [`set_root_certificates`](Self::set_root_certificates).
-
656 ///
-
657 /// # Examples
-
658 /// ```
-
659 /// use fabruic::{dangerous, Builder, Store};
-
660 ///
-
661 /// let mut builder = Builder::new();
-
662 /// builder.set_store(Store::Empty);
-
663 /// // CA certificate has to be imported from somewhere else
-
664 /// # let (server_certificate, _) = fabruic::KeyPair::new_self_signed("localhost").into_parts();
-
665 /// # let ca_certificate = server_certificate.into_end_entity_certificate();
-
666 /// dangerous::Builder::set_root_certificates(&mut builder, [ca_certificate.clone()]);
-
667 /// assert_eq!(dangerous::Builder::root_certificates(&builder), [
-
668 /// ca_certificate
-
669 /// ]);
-
670 /// ```
-
671 fn root_certificates(builder: &Self) -> &[Certificate];
-
672}
-
673
-
674impl Dangerous for Builder {
-
6751 fn set_root_certificates<C: Into<Vec<Certificate>>>(builder: &mut Self, certificates: C) {
-
6761 builder.root_certificates = certificates.into();
-
6771 }
-
678
-
6790 fn root_certificates(builder: &Self) -> &[Certificate] {
-
6800 &builder.root_certificates
-
6810 }
-
682}
-
683
-
684#[cfg(test)]
-
685mod test {
-
686 use std::task::Poll;
-
687
-
688 use anyhow::Result;
-
689 use futures_util::StreamExt;
-
690 use quinn::ConnectionError;
-
691 use quinn_proto::TransportError;
-
692 use trust_dns_proto::error::ProtoErrorKind;
-
693 use trust_dns_resolver::error::ResolveErrorKind;
+
655 /// let mut builder = Builder::new();
+
656 /// builder.set_store(Store::Empty);
+
657 /// // CA certificate has to be imported from somewhere else
+
658 /// # let (server_certificate, _) = fabruic::KeyPair::new_self_signed("localhost").into_parts();
+
659 /// # let ca_certificate = server_certificate.into_end_entity_certificate();
+
660 /// dangerous::Builder::set_root_certificates(&mut builder, [ca_certificate.clone()]);
+
661 /// assert_eq!(dangerous::Builder::root_certificates(&builder), [
+
662 /// ca_certificate
+
663 /// ]);
+
664 /// ```
+
665 fn root_certificates(builder: &Self) -> &[Certificate];
+
666}
+
667
+
668impl Dangerous for Builder {
+
6691 fn set_root_certificates<C: Into<Vec<Certificate>>>(builder: &mut Self, certificates: C) {
+
6701 builder.root_certificates = certificates.into();
+
6711 }
+
672
+
6730 fn root_certificates(builder: &Self) -> &[Certificate] {
+
6740 &builder.root_certificates
+
6750 }
+
676}
+
677
+
678#[cfg(test)]
+
679mod test {
+
680 use std::task::Poll;
+
681
+
682 use anyhow::Result;
+
683 use futures_util::StreamExt;
+
684 use quinn::ConnectionError;
+
685 use quinn_proto::TransportError;
+
686
+
687 use super::*;
+
688
+
6891 #[tokio::test]
+
6901 async fn default() -> Result<()> {
+
6911 let _endpoint = Builder::default().build()?;
+
6921 Ok(())
+
693 }
694
-
695 use super::*;
-
696
-
6971 #[tokio::test]
-
6981 async fn default() -> Result<()> {
-
6991 let _endpoint = Builder::default().build()?;
-
7001 Ok(())
-
701 }
-
702
-
7031 #[tokio::test]
-
7041 async fn new() -> Result<()> {
-
7051 let _endpoint = Builder::new().build()?;
-
7061 Ok(())
-
707 }
+
6951 #[tokio::test]
+
6961 async fn new() -> Result<()> {
+
6971 let _endpoint = Builder::new().build()?;
+
6981 Ok(())
+
699 }
+
700
+
7011 #[tokio::test]
+
7021 async fn address() -> Result<()> {
+
7031 let mut builder = Builder::new();
+
7041
+
7051 let address = ([0, 0, 0, 0, 0, 0, 0, 1], 5000).into();
+
7061 builder.set_address(address);
+
7071 assert_eq!(builder.address(), &address);
708
-
7091 #[tokio::test]
-
7101 async fn address() -> Result<()> {
-
7111 let mut builder = Builder::new();
-
7121
-
7131 let address = ([0, 0, 0, 0, 0, 0, 0, 1], 5000).into();
-
7141 builder.set_address(address);
-
7151 assert_eq!(builder.address(), &address);
-
716
-
7171 let endpoint = builder.build()?;
-
7181 assert_eq!(endpoint.local_address()?, address);
-
719
-
7201 Ok(())
-
721 }
-
722
-
7231 #[tokio::test]
-
7241 async fn server_certificate() -> Result<()> {
-
7251 let key_pair = KeyPair::new_self_signed("localhost");
+
7091 let endpoint = builder.build()?;
+
7101 assert_eq!(endpoint.local_address()?, address);
+
711
+
7121 Ok(())
+
713 }
+
714
+
7151 #[tokio::test]
+
7161 async fn server_certificate() -> Result<()> {
+
7171 let key_pair = KeyPair::new_self_signed("localhost");
+
718
+
719 // build client
+
7201 let client = Builder::new().build()?;
+
721
+
722 // build server
+
7231 let mut builder = Builder::new();
+
7241 builder.set_server_key_pair(Some(key_pair.clone()));
+
7251 let mut server = builder.build()?;
726
-
727 // build client
-
7281 let client = Builder::new().build()?;
-
729
-
730 // build server
-
7311 let mut builder = Builder::new();
-
7321 builder.set_server_key_pair(Some(key_pair.clone()));
-
7331 let mut server = builder.build()?;
-
734
-
735 // test connection to server
-
7361 let _connection = client
-
7371 .connect_pinned(
-
7381 format!("quic://{}", server.local_address()?),
-
7391 key_pair.end_entity_certificate(),
-
7401 None,
-
741 )
-
7420 .await?
+
727 // test connection to server
+
7281 let _connection = client
+
7291 .connect_pinned(
+
7301 format!("quic://{}", server.local_address()?),
+
7311 key_pair.end_entity_certificate(),
+
7321 None,
+
733 )
+
7340 .await?
+
7351 .accept::<()>()
+
7361 .await?;
+
737
+
738 // test receiving client on server
+
7391 let _connection = server
+
7401 .next()
+
7410 .await
+
7421 .expect("server dropped")
7431 .accept::<()>()
7441 .await?;
745
-
746 // test receiving client on server
-
7471 let _connection = server
-
7481 .next()
-
7490 .await
-
7501 .expect("server dropped")
-
7511 .accept::<()>()
-
7521 .await?;
-
753
-
7541 Ok(())
-
755 }
-
756
-
7571 #[tokio::test]
-
7581 async fn client_certificate() -> Result<()> {
-
7591 let server_key_pair = KeyPair::new_self_signed("localhost");
-
7601 let client_key_pair = KeyPair::new_self_signed("client");
-
7611
-
7621 // build client
+
7461 Ok(())
+
747 }
+
748
+
7491 #[tokio::test]
+
7501 async fn client_certificate() -> Result<()> {
+
7511 let server_key_pair = KeyPair::new_self_signed("localhost");
+
7521 let client_key_pair = KeyPair::new_self_signed("client");
+
7531
+
7541 // build client
+
7551 let mut builder = Builder::new();
+
7561 Dangerous::set_root_certificates(&mut builder, [server_key_pair
+
7571 .end_entity_certificate()
+
7581 .clone()]);
+
7591 builder.set_client_key_pair(Some(client_key_pair.clone()));
+
7601 let client = builder.build()?;
+
761
+
762 // build server
7631 let mut builder = Builder::new();
-
7641 Dangerous::set_root_certificates(&mut builder, [server_key_pair
-
7651 .end_entity_certificate()
-
7661 .clone()]);
-
7671 builder.set_client_key_pair(Some(client_key_pair.clone()));
-
7681 let client = builder.build()?;
-
769
-
770 // build server
-
7711 let mut builder = Builder::new();
-
7721 builder.set_server_key_pair(Some(server_key_pair));
-
7731 let mut server = builder.build()?;
-
774
-
775 // test connection to server
-
7761 let _connection = client
-
7771 .connect(format!(
-
7781 "quic://localhost:{}",
-
7791 server.local_address()?.port()
-
780 ))
-
7810 .await?
+
7641 builder.set_server_key_pair(Some(server_key_pair));
+
7651 let mut server = builder.build()?;
+
766
+
767 // test connection to server
+
7681 let _connection = client
+
7691 .connect(format!(
+
7701 "quic://localhost:{}",
+
7711 server.local_address()?.port()
+
772 ))
+
7730 .await?
+
7741 .accept::<()>()
+
7751 .await?;
+
776
+
777 // test receiving client on server
+
7781 let connection = server
+
7791 .next()
+
7800 .await
+
7811 .expect("server dropped")
7821 .accept::<()>()
7831 .await?;
784
-
785 // test receiving client on server
-
7861 let connection = server
-
7871 .next()
-
7880 .await
-
7891 .expect("server dropped")
-
7901 .accept::<()>()
-
7911 .await?;
+
785 // validate client certificate
+
7861 assert_eq!(
+
7871 client_key_pair.certificate_chain(),
+
7881 &connection
+
7891 .peer_identity()
+
7901 .expect("found no client certificate")
+
7911 );
792
-
793 // validate client certificate
-
7941 assert_eq!(
-
7951 client_key_pair.certificate_chain(),
-
7961 &connection
-
7971 .peer_identity()
-
7981 .expect("found no client certificate")
-
7991 );
-
800
-
8011 Ok(())
-
802 }
+
7931 Ok(())
+
794 }
+
795
+
7961 #[tokio::test]
+
7971 async fn protocols() -> Result<()> {
+
7981 let mut builder = Builder::new();
+
7991
+
8001 let protocols = [b"test".to_vec()];
+
8011 builder.set_protocols(protocols.clone());
+
8021 assert_eq!(builder.protocols(), protocols);
803
-
8041 #[tokio::test]
-
8051 async fn protocols() -> Result<()> {
-
8061 let mut builder = Builder::new();
-
8071
-
8081 let protocols = [b"test".to_vec()];
-
8091 builder.set_protocols(protocols.clone());
-
8101 assert_eq!(builder.protocols(), protocols);
-
811
-
8121 let _endpoint = builder.build()?;
-
813
-
8141 Ok(())
-
815 }
-
816
-
8171 #[tokio::test]
-
8181 async fn protocols_compatible() -> Result<()> {
-
8191 let key_pair = KeyPair::new_self_signed("test");
-
8201 let protocols = [b"test".to_vec()];
-
8211
-
8221 // build client
-
8231 let mut builder = Builder::new();
-
8241 builder.set_protocols(protocols.clone());
-
8251 let client = builder.build()?;
-
826
-
827 // build server
-
8281 let mut builder = Builder::new();
-
8291 builder.set_server_key_pair(Some(key_pair.clone()));
-
8301 builder.set_protocols(protocols.clone());
-
8311 let mut server = builder.build()?;
-
832
-
833 // connect with server
-
8341 let mut connecting = client
-
8351 .connect_pinned(
-
8361 format!("quic://{}", server.local_address()?),
-
8371 key_pair.end_entity_certificate(),
-
8381 None,
-
839 )
-
8400 .await?;
-
841
-
842 // check protocol on `Connecting`
-
8431 assert_eq!(
-
8441 protocols[0],
-
8451 connecting.protocol().await?.expect("no protocol found")
-
846 );
-
847
-
848 // check protocol on `Connection`
-
8491 let connection = connecting.accept::<()>().await?;
-
8501 assert_eq!(
-
8511 protocols[0],
-
8521 connection.protocol().expect("no protocol found")
-
8531 );
-
854
-
855 // receive connection from client
-
8561 let mut connecting = server.next().await.expect("server dropped");
-
8571
-
8581 // check protocol on `Connecting`
-
8591 assert_eq!(
-
8601 protocols[0],
-
8611 connecting.protocol().await?.expect("no protocol found")
-
862 );
-
863
-
864 // check protocol on `Connection`
-
8651 let connection = connecting.accept::<()>().await?;
-
8661 assert_eq!(
-
8671 protocols[0],
-
8681 connection.protocol().expect("no protocol found")
-
8691 );
-
870
-
8711 Ok(())
-
872 }
-
873
-
8741 #[tokio::test]
-
8751 async fn protocols_incompatible() -> Result<()> {
-
8761 let key_pair = KeyPair::new_self_signed("test");
-
8771
-
8781 // build client
-
8791 let mut builder = Builder::new();
-
8801 builder.set_protocols([b"test1".to_vec()]);
-
8811 let client = builder.build()?;
-
882
-
883 // build server
-
8841 let mut builder = Builder::new();
-
8851 builder.set_server_key_pair(Some(key_pair.clone()));
-
8861 builder.set_protocols([b"test2".to_vec()]);
-
8871 let mut server = builder.build()?;
-
888
-
889 // connect with server
-
8901 let result = client
-
8911 .connect_pinned(
-
8921 format!("quic://{}", server.local_address()?),
-
8931 key_pair.end_entity_certificate(),
-
8941 None,
-
895 )
-
8960 .await?
-
8971 .accept::<()>()
-
8981 .await;
-
899
-
900 // check result
-
9011 assert!(matches!(result, Err(error::Connecting::ProtocolMismatch)));
-
902
-
903 // on protocol mismatch, the server receives nothing
-
9041 assert!(matches!(futures_util::poll!(server.next()), Poll::Pending));
-
905
-
9061 Ok(())
-
907 }
+
8041 let _endpoint = builder.build()?;
+
805
+
8061 Ok(())
+
807 }
+
808
+
8091 #[tokio::test]
+
8101 async fn protocols_compatible() -> Result<()> {
+
8111 let key_pair = KeyPair::new_self_signed("test");
+
8121 let protocols = [b"test".to_vec()];
+
8131
+
8141 // build client
+
8151 let mut builder = Builder::new();
+
8161 builder.set_protocols(protocols.clone());
+
8171 let client = builder.build()?;
+
818
+
819 // build server
+
8201 let mut builder = Builder::new();
+
8211 builder.set_server_key_pair(Some(key_pair.clone()));
+
8221 builder.set_protocols(protocols.clone());
+
8231 let mut server = builder.build()?;
+
824
+
825 // connect with server
+
8261 let mut connecting = client
+
8271 .connect_pinned(
+
8281 format!("quic://{}", server.local_address()?),
+
8291 key_pair.end_entity_certificate(),
+
8301 None,
+
831 )
+
8320 .await?;
+
833
+
834 // check protocol on `Connecting`
+
8351 assert_eq!(
+
8361 protocols[0],
+
8371 connecting.protocol().await?.expect("no protocol found")
+
838 );
+
839
+
840 // check protocol on `Connection`
+
8411 let connection = connecting.accept::<()>().await?;
+
8421 assert_eq!(
+
8431 protocols[0],
+
8441 connection.protocol().expect("no protocol found")
+
8451 );
+
846
+
847 // receive connection from client
+
8481 let mut connecting = server.next().await.expect("server dropped");
+
8491
+
8501 // check protocol on `Connecting`
+
8511 assert_eq!(
+
8521 protocols[0],
+
8531 connecting.protocol().await?.expect("no protocol found")
+
854 );
+
855
+
856 // check protocol on `Connection`
+
8571 let connection = connecting.accept::<()>().await?;
+
8581 assert_eq!(
+
8591 protocols[0],
+
8601 connection.protocol().expect("no protocol found")
+
8611 );
+
862
+
8631 Ok(())
+
864 }
+
865
+
8661 #[tokio::test]
+
8671 async fn protocols_incompatible() -> Result<()> {
+
8681 let key_pair = KeyPair::new_self_signed("test");
+
8691
+
8701 // build client
+
8711 let mut builder = Builder::new();
+
8721 builder.set_protocols([b"test1".to_vec()]);
+
8731 let client = builder.build()?;
+
874
+
875 // build server
+
8761 let mut builder = Builder::new();
+
8771 builder.set_server_key_pair(Some(key_pair.clone()));
+
8781 builder.set_protocols([b"test2".to_vec()]);
+
8791 let mut server = builder.build()?;
+
880
+
881 // connect with server
+
8821 let result = client
+
8831 .connect_pinned(
+
8841 format!("quic://{}", server.local_address()?),
+
8851 key_pair.end_entity_certificate(),
+
8861 None,
+
887 )
+
8880 .await?
+
8891 .accept::<()>()
+
8901 .await;
+
891
+
892 // check result
+
8931 assert!(matches!(result, Err(error::Connecting::ProtocolMismatch)));
+
894
+
895 // on protocol mismatch, the server receives nothing
+
8961 assert!(matches!(futures_util::poll!(server.next()), Poll::Pending));
+
897
+
8981 Ok(())
+
899 }
+
900
+
9011 #[test]
+
902 #[cfg(feature = "trust-dns")]
+
9031 fn trust_dns() {
+
9041 let mut builder = Builder::new();
+
9051
+
9061 // default
+
9071 assert!(builder.trust_dns());
908
-
9091 #[test]
-
9101 fn trust_dns() {
-
9111 let mut builder = Builder::new();
-
9121
-
9131 // default
-
9141 assert!(builder.trust_dns());
-
915
-
9161 builder.set_trust_dns(false);
-
9171 assert!(!builder.trust_dns());
+
9091 builder.set_trust_dns(false);
+
9101 assert!(!builder.trust_dns());
+
911
+
9121 builder.set_trust_dns(true);
+
9131 assert!(builder.trust_dns());
+
914
+
9151 builder.disable_trust_dns();
+
9161 assert!(!builder.trust_dns());
+
9171 }
918
-
9191 builder.set_trust_dns(true);
-
9201 assert!(builder.trust_dns());
-
921
+
9191 #[tokio::test]
+
9201 async fn trust_dns_disabled() -> Result<()> {
+
9211 let mut builder = Builder::new();
9221 builder.disable_trust_dns();
-
9231 assert!(!builder.trust_dns());
-
9241 }
-
925
-
9261 #[tokio::test]
-
9271 async fn trust_dns_disabled() -> Result<()> {
-
9281 let mut builder = Builder::new();
-
9291 builder.disable_trust_dns();
-
9301 let endpoint = builder.build()?;
-
931
-
932 // TODO: find a better target without DNSSEC support then Google
-
9331 assert!(endpoint.connect("https://google.com").await.is_ok());
-
934
-
9351 Ok(())
-
936 }
-
937
-
9381 #[tokio::test]
-
9391 async fn trust_dns_success() -> Result<()> {
-
9401 let mut builder = Builder::new();
-
9411 builder.disable_trust_dns();
-
9421 let endpoint = builder.build()?;
-
943
-
944 // TODO: find a better target with DNSSEC support then Cloudflare
-
9451 assert!(endpoint.connect("https://cloudflare.com").await.is_ok());
-
946
-
9471 Ok(())
-
948 }
-
949
-
9501 #[tokio::test]
-
9511 async fn trust_dns_fail() -> Result<()> {
-
9521 let endpoint = Builder::new().build()?;
+
9231 let endpoint = builder.build()?;
+
924
+
925 // TODO: find a better target without DNSSEC support then Google
+
9261 let _ = endpoint.connect("https://google.com").await.unwrap();
+
9271
+
9281 Ok(())
+
929 }
+
930
+
9311 #[tokio::test]
+
9321 async fn trust_dns_success() -> Result<()> {
+
9331 let mut builder = Builder::new();
+
9341 builder.disable_trust_dns();
+
9351 let endpoint = builder.build()?;
+
936
+
937 // TODO: find a better target with DNSSEC support then Cloudflare
+
9381 let _ = endpoint.connect("https://cloudflare.com").await.unwrap();
+
9391
+
9401 Ok(())
+
941 }
+
942
+
9431 #[tokio::test]
+
944 #[cfg(feature = "trust-dns")]
+
9451 async fn trust_dns_fail() -> Result<()> {
+
946 use trust_dns_proto::error::ProtoErrorKind;
+
947 use trust_dns_resolver::error::ResolveErrorKind;
+
948
+
9491 let endpoint = Builder::new().build()?;
+
950
+
951 // TODO: find a better target without DNSSEC support then Google
+
95211 let result = endpoint.connect("https://google.com").await;
953
-
954 // TODO: find a better target without DNSSEC support then Google
-
95510 let result = endpoint.connect("https://google.com").await;
-
956
-
957 // target has no DNSSEC records
-
9581 if let Err(error::Connect::TrustDns(error)) = &result {
-
9591 if let ResolveErrorKind::Proto(error) = error.kind() {
-
9601 if let ProtoErrorKind::RrsigsNotPresent { .. } = error.kind() {
-
9611 return Ok(());
-
9620 }
-
9630 }
-
9640 }
-
965
-
966 // any other error or `Ok` should fail the test
-
9670 panic!("unexpected result: {result:?}")
-
968 }
-
969
-
9701 #[test]
-
9711 fn dnssec() {
-
9721 let mut builder = Builder::new();
-
9731
-
9741 // default
-
9751 assert!(builder.dnssec());
-
976
-
9771 builder.set_dnssec(false);
-
9781 assert!(!builder.dnssec());
-
979
-
9801 builder.set_dnssec(true);
-
9811 assert!(builder.dnssec());
-
9821 }
-
983
-
9841 #[tokio::test]
-
9851 async fn dnssec_disabled() -> Result<()> {
-
9861 let mut builder = Builder::new();
-
9871 builder.set_dnssec(false);
-
9881 let endpoint = builder.build()?;
-
989
-
990 // TODO: find a better target without DNSSEC support then Google
-
9917 assert!(endpoint.connect("https://google.com").await.is_ok());
-
992
-
9931 Ok(())
-
994 }
-
995
-
9961 #[test]
+
954 // target has no DNSSEC records
+
9551 if let Err(error::Connect::TrustDns(error)) = &result {
+
9561 if let ResolveErrorKind::Proto(error) = error.kind() {
+
9571 if let ProtoErrorKind::RrsigsNotPresent { .. } = error.kind() {
+
9581 return Ok(());
+
9590 }
+
9600 }
+
9610 }
+
962
+
963 // any other error or `Ok` should fail the test
+
9640 panic!("unexpected result: {result:?}")
+
965 }
+
966
+
9671 #[test]
+
968 #[cfg(feature = "trust-dns")]
+
9691 fn dnssec() {
+
9701 let mut builder = Builder::new();
+
9711
+
9721 // default
+
9731 assert!(builder.dnssec());
+
974
+
9751 builder.set_dnssec(false);
+
9761 assert!(!builder.dnssec());
+
977
+
9781 builder.set_dnssec(true);
+
9791 assert!(builder.dnssec());
+
9801 }
+
981
+
9821 #[tokio::test]
+
983 #[cfg(feature = "trust-dns")]
+
9841 async fn dnssec_disabled() -> Result<()> {
+
9851 let mut builder = Builder::new();
+
9861 builder.set_dnssec(false);
+
9871 let endpoint = builder.build()?;
+
988
+
989 // TODO: find a better target without DNSSEC support then Google
+
9907 let _ = endpoint.connect("https://google.com").await.unwrap();
+
9911
+
9921 Ok(())
+
993 }
+
994
+
9951 #[test]
+
996 #[cfg(feature = "trust-dns")]
9971 fn hosts_file() {
9981 let mut builder = Builder::new();
9991
@@ -1035,94 +1035,100 @@
10141 // connection, for some reason IPv6 `[::]` doesn't work on GitHub Actions
10151 builder.set_address(([0, 0, 0, 0], 0).into());
10161 // QUIC is comptaible with HTTP/3 to establish a connection only
-
10171 builder.set_protocols([b"h3-29".to_vec()]);
+
10171 builder.set_protocols([b"h3".to_vec()]);
10181 // `cloudflare-quic` doesn't support DNSSEC
-
10191 builder.set_dnssec(false);
-
10201
-
10211 // default
-
10221 assert_eq!(builder.store(), Store::Embedded);
-
1023
-
10241 builder.set_store(Store::Embedded);
-
10251 assert_eq!(builder.store(), Store::Embedded);
-
1026
-
10271 let endpoint = builder.build()?;
-
1028
-
1029 // TODO: find a better target to test our root certificate store against
-
10301 assert!(endpoint
-
10311 .connect("https://cloudflare-quic.com:443")
-
10327 .await?
-
10331 .accept::<()>()
-
10341 .await
-
10351 .is_ok());
-
1036
-
10371 Ok(())
-
1038 }
-
1039
-
10401 #[tokio::test]
-
10411 async fn store_os() -> Result<()> {
-
10421 let mut builder = Builder::new();
-
10431 // `cfg(test)` will use `[::1]` by default, but we need to do an outgoing
-
10441 // connection, for some reason IPv6 `[::]` doesn't work on GitHub Actions
-
10451 builder.set_address(([0, 0, 0, 0], 0).into());
-
10461 // QUIC is comptaible with HTTP/3 to establish a connection only
-
10471 builder.set_protocols([b"h3-29".to_vec()]);
-
10481 // `cloudflare-quic` doesn't support DNSSEC
-
10491 builder.set_dnssec(false);
-
10501
-
10511 builder.set_store(Store::Os);
-
10521 assert_eq!(builder.store(), Store::Os);
-
1053
-
10541 let endpoint = builder.build()?;
+
10191 #[cfg(feature = "trust-dns")]
+
10201 builder.set_dnssec(false);
+
10211
+
10221 // default
+
10231 assert_eq!(builder.store(), Store::Embedded);
+
1024
+
10251 builder.set_store(Store::Embedded);
+
10261 assert_eq!(builder.store(), Store::Embedded);
+
1027
+
10281 let endpoint = builder.build()?;
+
1029
+
1030 // TODO: find a better target to test our root certificate store against
+
10311 let _ = endpoint
+
10321 .connect("https://cloudflare-quic.com:443")
+
10336 .await?
+
10341 .accept::<()>()
+
10351 .await
+
10361 .unwrap();
+
10371
+
10381 Ok(())
+
1039 }
+
1040
+
10411 #[tokio::test]
+
10421 async fn store_os() -> Result<()> {
+
10431 let mut builder = Builder::new();
+
10441 // `cfg(test)` will use `[::1]` by default, but we need to do an outgoing
+
10451 // connection, for some reason IPv6 `[::]` doesn't work on GitHub Actions
+
10461 builder.set_address(([0, 0, 0, 0], 0).into());
+
10471 // QUIC is comptaible with HTTP/3 to establish a connection only
+
10481 builder.set_protocols([b"h3".to_vec()]);
+
10491 // `cloudflare-quic` doesn't support DNSSEC
+
10501 #[cfg(feature = "trust-dns")]
+
10511 builder.set_dnssec(false);
+
10521
+
10531 builder.set_store(Store::Os);
+
10541 assert_eq!(builder.store(), Store::Os);
1055
-
1056 // TODO: find a better target to test our root certificate store against
-
10571 assert!(endpoint
-
10581 .connect("https://cloudflare-quic.com:443")
-
10597 .await?
-
10601 .accept::<()>()
-
10611 .await
-
10621 .is_ok());
-
1063
-
10641 Ok(())
-
1065 }
-
1066
-
10671 #[tokio::test]
-
10681 async fn store_empty() -> Result<()> {
-
10691 let mut builder = Builder::new();
-
10701 // `cfg(test)` will use `[::1]` by default, but we need to do an outgoing
-
10711 // connection, for some reason IPv6 `[::]` doesn't work on GitHub Actions
-
10721 builder.set_address(([0, 0, 0, 0], 0).into());
-
10731 // QUIC is comptaible with HTTP/3 to establish a connection only
-
10741 builder.set_protocols([b"h3-29".to_vec()]);
-
10751 // `cloudflare-quic` doesn't support DNSSEC
-
10761 builder.set_dnssec(false);
-
10771
-
10781 builder.set_store(Store::Empty);
-
10791 assert_eq!(builder.store(), Store::Empty);
-
1080
-
10811 let endpoint = builder.build()?;
-
1082
-
1083 // TODO: find a better target to test our root certificate store against
-
10841 let result = endpoint
-
10851 .connect("https://cloudflare-quic.com:443")
-
10867 .await?
-
10871 .accept::<()>()
-
10881 .await;
-
1089
-
1090 // check result
-
1091 let Err(error::Connecting::Connection(ConnectionError::TransportError(TransportError {
-
10921 code,
-
10931 frame: None,
-
10941 reason
-
10951 }))) = result else { unreachable!("expected TransportError") };
-
10961 assert_eq!(reason, "invalid peer certificate: UnknownIssuer");
-
10971 assert_eq!(
-
10981 code.to_string(),
-
10991 "the cryptographic handshake failed: error 48"
-
11001 );
-
1101
-
11021 Ok(())
-
1103 }
-
1104}
+
10561 let endpoint = builder.build()?;
+
1057
+
1058 // TODO: find a better target to test our root certificate store against
+
10591 let _ = endpoint
+
10601 .connect("https://cloudflare-quic.com:443")
+
10616 .await?
+
10621 .accept::<()>()
+
10631 .await
+
10641 .unwrap();
+
10651
+
10661 Ok(())
+
1067 }
+
1068
+
10691 #[tokio::test]
+
10701 async fn store_empty() -> Result<()> {
+
10711 let mut builder = Builder::new();
+
10721 // `cfg(test)` will use `[::1]` by default, but we need to do an outgoing
+
10731 // connection, for some reason IPv6 `[::]` doesn't work on GitHub Actions
+
10741 builder.set_address(([0, 0, 0, 0], 0).into());
+
10751 // QUIC is comptaible with HTTP/3 to establish a connection only
+
10761 builder.set_protocols([b"h3".to_vec()]);
+
10771 // `cloudflare-quic` doesn't support DNSSEC
+
10781 #[cfg(feature = "trust-dns")]
+
10791 builder.set_dnssec(false);
+
10801
+
10811 builder.set_store(Store::Empty);
+
10821 assert_eq!(builder.store(), Store::Empty);
+
1083
+
10841 let endpoint = builder.build()?;
+
1085
+
1086 // TODO: find a better target to test our root certificate store against
+
10871 let result = endpoint
+
10881 .connect("https://cloudflare-quic.com:443")
+
10896 .await?
+
10901 .accept::<()>()
+
10911 .await;
+
1092
+
1093 // check result
+
1094 let Err(error::Connecting::Connection(ConnectionError::TransportError(TransportError {
+
10951 code,
+
10961 frame: None,
+
10971 reason,
+
10981 }))) = result
+
1099 else {
+
11000 unreachable!("expected TransportError")
+
1101 };
+
11021 assert_eq!(reason, "invalid peer certificate: UnknownIssuer");
+
11031 assert_eq!(
+
11041 code.to_string(),
+
11051 "the cryptographic handshake failed: error 48"
+
11061 );
+
1107
+
11081 Ok(())
+
1109 }
+
1110}
diff --git a/coverage/src/quic/endpoint/index.html b/coverage/src/quic/endpoint/index.html index 890309d..dce07bd 100644 --- a/coverage/src/quic/endpoint/index.html +++ b/coverage/src/quic/endpoint/index.html @@ -9,18 +9,18 @@
Current view:top level - src/quic/endpoint
-
Date:2023-07-07 10:30:44
+
Date:2023-08-25 14:31:32
HitTotalCoverage
-
Lines39242991.4 %
-
Functions7910972.5 %
+
Lines39443291.2 %
+
Functions8912372.4 %
Branches000.0 %
FilenameLine CoverageFunctionsBranches
-
mod.rs91.4%392 / 42972.5%79 / 1090.0%0 / 0
+
mod.rs91.2%394 / 43272.4%89 / 1230.0%0 / 0
diff --git a/coverage/src/quic/endpoint/mod.rs.html b/coverage/src/quic/endpoint/mod.rs.html index 911281d..53ee840 100644 --- a/coverage/src/quic/endpoint/mod.rs.html +++ b/coverage/src/quic/endpoint/mod.rs.html @@ -9,12 +9,12 @@
Current view:top level - src/quic/endpoint - mod.rs
-
Date:2023-07-07 10:30:44
+
Date:2023-08-25 14:31:32
HitTotalCoverage
-
Lines39242991.4 %
-
Functions7910972.5 %
+
Lines39443291.2 %
+
Functions8912372.4 %
Branches000.0 %
@@ -30,7 +30,7 @@
9 pin::Pin,
10 slice,
11 sync::Arc,
-
12 task::{Context, Poll},
+
12 task::{Context, Poll}, future::Future,
13};
14
15use async_trait::async_trait;
@@ -71,314 +71,314 @@
50}
51
52impl Debug for Endpoint {
-
530 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-
540 f.debug_struct("Server")
-
550 .field("endpoint", &self.endpoint)
-
560 .field("receiver", &"RecvStream")
-
570 .field("task", &self.task)
-
580 .field("config", &self.config)
-
590 .finish()
-
600 }
-
61}
-
62
-
63impl Endpoint {
-
64 /// Builds a new [`Builder`]. See [`Builder`] methods for defaults.
-
65 ///
-
66 /// # Examples
-
67 /// ```
-
68 /// # #[tokio::main] async fn main() -> anyhow::Result<()> {
-
69 /// use fabruic::Endpoint;
-
70 ///
-
71 /// let endpoint = Endpoint::builder().build()?;
-
72 /// # Ok(()) }
-
73 /// ```
-
743 pub fn builder() -> Builder {
-
753 Builder::new()
-
763 }
-
77
-
78 /// Builds a new [`Endpoint`] from raw [`quinn`] types. Must be called from
-
79 /// inside a Tokio [`Runtime`](tokio::runtime::Runtime).
-
80 ///
-
81 /// # Errors
-
82 /// [`std::io::Error`] if the socket couldn't be bound to the given
-
83 /// `address`.
-
84 ///
-
85 /// # Panics
-
86 /// If not called from inside a Tokio [`Runtime`](tokio::runtime::Runtime).
-
87135 fn new(
-
88135 address: SocketAddr,
-
89135 reuse_address: bool,
-
90135 client: ClientConfig,
-
91135 server: Option<ServerConfig>,
-
92135 config: Config,
-
93135 ) -> Result<Self, Error> {
-
94135 let socket = if reuse_address {
-
952 let socket = socket2::Socket::new(
-
962 if address.is_ipv4() {
-
970 Domain::IPV4
-
98 } else {
-
992 Domain::IPV6
-
100 },
-
101 Type::DGRAM,
-
1022 Some(Protocol::UDP),
-
1030 )?;
-
1042 socket.set_reuse_address(true)?;
-
1052 socket.bind(&socket2::SockAddr::from(address))?;
-
1062 socket.into()
-
107 } else {
-
108133 UdpSocket::bind(address)?
-
109 };
-
110
-
111 // configure endpoint for server and client
-
112135 let is_server = server.is_some();
-
113135 let mut endpoint = quinn::Endpoint::new(
-
114135 EndpointConfig::default(),
-
115135 server.clone(),
-
116135 socket,
-
117135 Arc::new(TokioRuntime),
-
118135 )?;
-
119
-
120135 endpoint.set_default_client_config(client);
-
121135
-
122135 // create channels that will receive incoming `Connection`s
-
123135 let (sender, receiver) = flume::unbounded();
-
124135 let receiver = receiver.into_stream();
-
125
-
126135 let task = if is_server {
-
12712 Task::new(|shutdown| Self::incoming(endpoint.clone(), sender, shutdown))
-
128 } else {
-
129123 Task::empty()
-
130 };
-
131
-
132135 Ok(Self {
-
133135 endpoint,
-
134135 receiver,
-
135135 task,
-
136135 config: Arc::new(config),
-
137135 server: server.map(|server| Arc::new(Mutex::new(server))),
-
138135 })
-
139135 }
-
140
-
141 /// Simplified version of creating a client. See [`Builder`] for more
-
142 /// sophisticated configuration options. Must be called from inside a Tokio
-
143 /// [`Runtime`](tokio::runtime::Runtime).
-
144 ///
-
145 /// # Notes
-
146 /// This configuration will not be able to receive incoming
-
147 /// [`Connection`](crate::Connection)s.
-
148 ///
-
149 /// # Errors
-
150 /// [`std::io::Error`] if the socket couldn't be bound to the given
-
151 /// `address`.
-
152 ///
-
153 /// # Panics
-
154 /// If not called from inside a Tokio [`Runtime`](tokio::runtime::Runtime).
-
155 ///
-
156 /// # Examples
-
157 /// ```
-
158 /// # #[tokio::main] async fn main() -> anyhow::Result<()> {
-
159 /// use fabruic::Endpoint;
-
160 ///
-
161 /// let endpoint = Endpoint::new_client()?;
-
162 /// # Ok(()) }
-
163 /// ```
-
164108 pub fn new_client() -> Result<Self, error::Config> {
-
165108 Builder::new()
-
166108 .build()
-
167108 .map_err(|error::Builder { error, .. }| error)
-
168108 }
-
169
-
170 /// Simplified version of creating a server. See [`Builder`] for more
-
171 /// sophisticated configuration options. Must be called from inside a Tokio
-
172 /// [`Runtime`](tokio::runtime::Runtime).
-
173 ///
-
174 /// # Errors
-
175 /// [`std::io::Error`] if the socket couldn't be bound to the given
-
176 /// `address`.
-
177 ///
-
178 /// # Panics
-
179 /// - if the given [`KeyPair`] is invalid - can't happen if properly
-
180 /// validated through [`KeyPair::from_parts`]
-
181 /// - if not called from inside a Tokio [`Runtime`](tokio::runtime::Runtime)
-
182 ///
-
183 /// # Examples
-
184 /// ```
-
185 /// # #[tokio::main] async fn main() -> anyhow::Result<()> {
-
186 /// use fabruic::{Endpoint, KeyPair};
-
187 ///
-
188 /// let endpoint = Endpoint::new_server(0, KeyPair::new_self_signed("self-signed"))?;
-
189 /// # Ok(()) }
-
190 /// ```
-
1916 pub fn new_server(port: u16, key_pair: KeyPair) -> Result<Self, error::Config> {
-
1926 let mut builder = Builder::new();
-
1936 #[cfg(not(feature = "test"))]
-
1946 builder.set_address(([0; 8], port).into());
-
1956 // while testing always use the default loopback address
-
1966 #[cfg(feature = "test")]
-
1976 builder.set_address(([0, 0, 0, 0, 0, 0, 0, 1], port).into());
-
1986 builder.set_server_key_pair(Some(key_pair));
-
1996
-
2006 builder
-
2016 .build()
-
2026 .map_err(|error::Builder { error, .. }| error)
-
2036 }
-
204
-
205 /// Handle incoming connections. Accessed through [`Stream`] in
-
206 /// [`Endpoint`].
-
20712 async fn incoming(
-
20812 endpoint: quinn::Endpoint,
-
20912 sender: Sender<Connecting>,
-
21012 shutdown: Receiver<()>,
-
21112 ) {
-
21212 IncomingConnections {
-
21312 endpoint: &endpoint,
-
21412 accept: None,
-
21512 shutdown,
-
21612 sender,
-
21712 complete: false,
-
21812 }
-
21921 .await;
-
2204 }
-
221
-
222 /// Establishes a new [`Connection`](crate::Connection) to a server. The
-
223 /// servers [`Certificate`] will be validated aggainst the root certificate
-
224 /// store and the domain in the URL.
-
225 ///
-
226 /// Attempts to resolve the IP from the given URL. Uses
-
227 /// [`trust-dns`](trust_dns_resolver) by default if the crate feature <span
-
228 /// class="module-item stab portability"
-
229 /// style="display: inline; border-radius: 3px; padding: 2px; font-size:
-
230 /// 80%; line-height: 1.2;" ><code>trust-dns</code></span> is enabled.
-
231 /// Otherwise [`ToSocketAddrs`] is used.
-
232 ///
-
233 /// See [`Builder::set_trust_dns`] or [`Builder::disable_trust_dns`] for
-
234 /// more control.
-
235 ///
-
236 /// # Notes
-
237 /// The following settings are used when using
-
238 /// [`trust-dns`](trust_dns_resolver):
-
239 /// - all system configurations are ignored, see [`Builder::set_hosts_file`]
-
240 /// - Cloudflare with DoH is used as the name server
-
241 /// - DNSSEC is enabled, see [`Builder::set_dnssec`]
-
242 /// - IPv6 is preferred over IPv4 if the bound socket is IPv6
-
243 ///
-
244 /// # Errors
-
245 /// - [`error::Connect::ParseUrl`] if the URL couldn't be parsed
-
246 /// - [`error::Connect::Domain`] if the URL didn't contain a domain
-
247 /// - [`error::Connect::Port`] if the URL didn't contain a port
-
248 /// - [`error::Connect::ParseDomain`] if the domain couldn't be parsed
-
249 /// - [`error::Connect::TrustDns`] if the URL couldn't be resolved to an IP
-
250 /// address with [`trust-dns`](trust_dns_resolver)
-
251 /// - [`error::Connect::StdDns`] if the URL couldn't be resolved to an IP
-
252 /// address with [`ToSocketAddrs`]
-
253 /// - [`error::Connect::NoIp`] if no IP address was found for that domain
-
254 ///
-
255 /// # Examples
-
256 /// ```
-
257 /// # #[tokio::main] async fn main() -> anyhow::Result<()> {
-
258 /// use fabruic::Endpoint;
-
259 ///
-
260 /// let endpoint = Endpoint::new_client()?;
-
261 /// // not going to actually work because `localhost` can't have a valid certificate
-
262 /// let connecting = endpoint.connect("quic://localhost:443").await?;
-
263 /// # Ok(()) }
-
264 /// ```
-
2658 pub async fn connect<U: AsRef<str>>(&self, url: U) -> Result<Connecting, error::Connect> {
-
26640 let (address, domain) = self.resolve_domain(url).await?;
-
267
-
268 Ok(Connecting::new(
-
2697 self.endpoint
-
2707 .connect(address, &domain)
-
2717 .map_err(error::Connect::ConnectConfig)?,
-
272 ))
-
2738 }
-
274
-
275 /// Establishes a new [`Connection`](crate::Connection) to a server.
-
276 ///
-
277 /// See [`connect`](Self::connect) for more information on host name
-
278 /// resolution.
-
279 ///
-
280 /// # Notes
-
281 /// The root certificate store will be ignored and the given [`Certificate`]
-
282 /// will validate the server.
-
283 ///
-
284 /// A client certificate [`KeyPair`] set with
-
285 /// [`Builder::set_client_key_pair`] will be ignored, use `client_key_pair`
-
286 /// to add a client certificate to this connection.
-
287 ///
-
288 /// This method is intended for direct connection to a known server, the
-
289 /// domain name in the URL is not checked against the [`Certificate`].
-
290 /// Multiple domain names in the [`Certificate`] aren't supported.
-
291 ///
-
292 /// # Errors
-
293 /// - [`error::Connect::MultipleDomains`] if multiple domains are present in
-
294 /// the [`Certificate`], which isn't supported
-
295 /// - [`error::Connect::ParseUrl`] if the URL couldn't be parsed
-
296 /// - [`error::Connect::Domain`] if the URL didn't contain a domain
-
297 /// - [`error::Connect::Port`] if the URL didn't contain a port
-
298 /// - [`error::Connect::ParseDomain`] if the domain couldn't be parsed
-
299 /// - [`error::Connect::TrustDns`] if the URL couldn't be resolved to an IP
-
300 /// address with [`trust-dns`](trust_dns_resolver)
-
301 /// - [`error::Connect::StdDns`] if the URL couldn't be resolved to an IP
-
302 /// address with [`ToSocketAddrs`]
-
303 /// - [`error::Connect::NoIp`] if no IP address was found for that domain
-
304 ///
-
305 /// # Panics
-
306 /// Panics if the given [`Certificate`] or [`KeyPair`] are invalid. Can't
-
307 /// happen if they were properly validated through [`Certificate::from_der`]
-
308 /// or [`KeyPair::from_parts`].
-
309 ///
-
310 /// # Examples
-
311 /// ```
-
312 /// # #[tokio::main] async fn main() -> anyhow::Result<()> {
-
313 /// use fabruic::Endpoint;
-
314 ///
-
315 /// let endpoint = Endpoint::new_client()?;
-
316 /// // the server certificate has to be imported from somewhere else
-
317 /// # let (server_certificate, _) = fabruic::KeyPair::new_self_signed("localhost").into_parts();
-
318 /// # let server_certificate = server_certificate.into_end_entity_certificate();
-
319 /// let connecting = endpoint
-
320 /// .connect_pinned("quic://localhost:443", &server_certificate, None)
-
321 /// .await?;
-
322 /// # Ok(()) }
-
323 /// ```
-
324 #[allow(clippy::unwrap_in_result)]
-
325112 pub async fn connect_pinned<U: AsRef<str>>(
-
326112 &self,
-
327112 url: U,
-
328112 server_certificate: &Certificate,
-
329112 client_key_pair: Option<KeyPair>,
-
330112 ) -> Result<Connecting, error::Connect> {
-
331112 // check `Certificate` for a domain
-
332112 let mut domains = server_certificate.domains().into_iter();
-
333112 let domain = domains
-
334112 .next()
-
335112 .expect("`Certificate` contained no valid domains");
-
336112
-
337112 // multiple domains aren't supported
-
338112 if domains.next().is_some() {
+
530 fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
+
540 formatter
+
550 .debug_struct("Server")
+
560 .field("endpoint", &self.endpoint)
+
570 .field("receiver", &"RecvStream")
+
580 .field("task", &self.task)
+
590 .field("config", &self.config)
+
600 .finish_non_exhaustive()
+
610 }
+
62}
+
63
+
64impl Endpoint {
+
65 /// Builds a new [`Builder`]. See [`Builder`] methods for defaults.
+
66 ///
+
67 /// # Examples
+
68 /// ```
+
69 /// # #[tokio::main] async fn main() -> anyhow::Result<()> {
+
70 /// use fabruic::Endpoint;
+
71 ///
+
72 /// let endpoint = Endpoint::builder().build()?;
+
73 /// # Ok(()) }
+
74 /// ```
+
753 pub fn builder() -> Builder {
+
763 Builder::new()
+
773 }
+
78
+
79 /// Builds a new [`Endpoint`] from raw [`quinn`] types. Must be called from
+
80 /// inside a Tokio [`Runtime`](tokio::runtime::Runtime).
+
81 ///
+
82 /// # Errors
+
83 /// [`std::io::Error`] if the socket couldn't be bound to the given
+
84 /// `address`.
+
85 ///
+
86 /// # Panics
+
87 /// If not called from inside a Tokio [`Runtime`](tokio::runtime::Runtime).
+
88349 fn new(
+
89349 address: SocketAddr,
+
90349 reuse_address: bool,
+
91349 client: ClientConfig,
+
92349 server: Option<ServerConfig>,
+
93349 config: Config,
+
94349 ) -> Result<Self, Error> {
+
95349 let socket = if reuse_address {
+
962 let socket = socket2::Socket::new(
+
972 if address.is_ipv4() {
+
980 Domain::IPV4
+
99 } else {
+
1002 Domain::IPV6
+
101 },
+
102 Type::DGRAM,
+
1032 Some(Protocol::UDP),
+
1040 )?;
+
1052 socket.set_reuse_address(true)?;
+
1062 socket.bind(&socket2::SockAddr::from(address))?;
+
1072 socket.into()
+
108 } else {
+
109347 UdpSocket::bind(address)?
+
110 };
+
111
+
112 // configure endpoint for server and client
+
113349 let is_server = server.is_some();
+
114349 let mut endpoint = quinn::Endpoint::new(
+
115349 EndpointConfig::default(),
+
116349 server.clone(),
+
117349 socket,
+
118349 Arc::new(TokioRuntime),
+
119349 )?;
+
120
+
121349 endpoint.set_default_client_config(client);
+
122349
+
123349 // create channels that will receive incoming `Connection`s
+
124349 let (sender, receiver) = flume::unbounded();
+
125349 let receiver = receiver.into_stream();
+
126
+
127349 let task = if is_server {
+
12820 Task::new(|shutdown| Self::incoming(endpoint.clone(), sender, shutdown))
+
129 } else {
+
130329 Task::empty()
+
131 };
+
132
+
133349 Ok(Self {
+
134349 endpoint,
+
135349 receiver,
+
136349 task,
+
137349 config: Arc::new(config),
+
138349 server: server.map(|server| Arc::new(Mutex::new(server))),
+
139349 })
+
140349 }
+
141
+
142 /// Simplified version of creating a client. See [`Builder`] for more
+
143 /// sophisticated configuration options. Must be called from inside a Tokio
+
144 /// [`Runtime`](tokio::runtime::Runtime).
+
145 ///
+
146 /// # Notes
+
147 /// This configuration will not be able to receive incoming
+
148 /// [`Connection`](crate::Connection)s.
+
149 ///
+
150 /// # Errors
+
151 /// [`std::io::Error`] if the socket couldn't be bound to the given
+
152 /// `address`.
+
153 ///
+
154 /// # Panics
+
155 /// If not called from inside a Tokio [`Runtime`](tokio::runtime::Runtime).
+
156 ///
+
157 /// # Examples
+
158 /// ```
+
159 /// # #[tokio::main] async fn main() -> anyhow::Result<()> {
+
160 /// use fabruic::Endpoint;
+
161 ///
+
162 /// let endpoint = Endpoint::new_client()?;
+
163 /// # Ok(()) }
+
164 /// ```
+
165314 pub fn new_client() -> Result<Self, error::Config> {
+
166314 Builder::new()
+
167314 .build()
+
168314 .map_err(|error::Builder { error, .. }| error)
+
169314 }
+
170
+
171 /// Simplified version of creating a server. See [`Builder`] for more
+
172 /// sophisticated configuration options. Must be called from inside a Tokio
+
173 /// [`Runtime`](tokio::runtime::Runtime).
+
174 ///
+
175 /// # Errors
+
176 /// [`std::io::Error`] if the socket couldn't be bound to the given
+
177 /// `address`.
+
178 ///
+
179 /// # Panics
+
180 /// - if the given [`KeyPair`] is invalid - can't happen if properly
+
181 /// validated through [`KeyPair::from_parts`]
+
182 /// - if not called from inside a Tokio [`Runtime`](tokio::runtime::Runtime)
+
183 ///
+
184 /// # Examples
+
185 /// ```
+
186 /// # #[tokio::main] async fn main() -> anyhow::Result<()> {
+
187 /// use fabruic::{Endpoint, KeyPair};
+
188 ///
+
189 /// let endpoint = Endpoint::new_server(0, KeyPair::new_self_signed("self-signed"))?;
+
190 /// # Ok(()) }
+
191 /// ```
+
19214 pub fn new_server(port: u16, key_pair: KeyPair) -> Result<Self, error::Config> {
+
19314 let mut builder = Builder::new();
+
19414 #[cfg(not(feature = "test"))]
+
19514 builder.set_address(([0; 8], port).into());
+
19614 // while testing always use the default loopback address
+
19714 #[cfg(feature = "test")]
+
19814 builder.set_address(([0, 0, 0, 0, 0, 0, 0, 1], port).into());
+
19914 builder.set_server_key_pair(Some(key_pair));
+
20014
+
20114 builder
+
20214 .build()
+
20314 .map_err(|error::Builder { error, .. }| error)
+
20414 }
+
205
+
206 /// Handle incoming connections. Accessed through [`Stream`] in
+
207 /// [`Endpoint`].
+
20820 async fn incoming(
+
20920 endpoint: quinn::Endpoint,
+
21020 sender: Sender<Connecting>,
+
21120 shutdown: Receiver<()>,
+
21220 ) {
+
21320 IncomingConnections {
+
21420 endpoint: &endpoint,
+
21520 accept: None,
+
21620 shutdown,
+
21720 sender,
+
21820 complete: false,
+
21920 }
+
22046 .await;
+
2219 }
+
222
+
223 /// Establishes a new [`Connection`](crate::Connection) to a server. The
+
224 /// servers [`Certificate`] will be validated aggainst the root certificate
+
225 /// store and the domain in the URL.
+
226 ///
+
227 /// Attempts to resolve the IP from the given URL. Uses
+
228 /// [`trust-dns`](trust_dns_resolver) by default if the crate feature <span
+
229 /// class="module-item stab portability"
+
230 /// style="display: inline; border-radius: 3px; padding: 2px; font-size:
+
231 /// 80%; line-height: 1.2;" ><code>trust-dns</code></span> is enabled.
+
232 /// Otherwise [`ToSocketAddrs`] is used.
+
233 ///
+
234 /// See [`Builder::set_trust_dns`] or [`Builder::disable_trust_dns`] for
+
235 /// more control.
+
236 ///
+
237 /// # Notes
+
238 /// The following settings are used when using
+
239 /// [`trust-dns`](trust_dns_resolver):
+
240 /// - all system configurations are ignored, see [`Builder::set_hosts_file`]
+
241 /// - Cloudflare with DoH is used as the name server
+
242 /// - DNSSEC is enabled, see [`Builder::set_dnssec`]
+
243 /// - IPv6 is preferred over IPv4 if the bound socket is IPv6
+
244 ///
+
245 /// # Errors
+
246 /// - [`error::Connect::ParseUrl`] if the URL couldn't be parsed
+
247 /// - [`error::Connect::Domain`] if the URL didn't contain a domain
+
248 /// - [`error::Connect::Port`] if the URL didn't contain a port
+
249 /// - [`error::Connect::ParseDomain`] if the domain couldn't be parsed
+
250 /// - [`error::Connect::TrustDns`] if the URL couldn't be resolved to an IP
+
251 /// address with [`trust-dns`](trust_dns_resolver)
+
252 /// - [`error::Connect::StdDns`] if the URL couldn't be resolved to an IP
+
253 /// address with [`ToSocketAddrs`]
+
254 /// - [`error::Connect::NoIp`] if no IP address was found for that domain
+
255 ///
+
256 /// # Examples
+
257 /// ```
+
258 /// # #[tokio::main] async fn main() -> anyhow::Result<()> {
+
259 /// use fabruic::Endpoint;
+
260 ///
+
261 /// let endpoint = Endpoint::new_client()?;
+
262 /// // not going to actually work because `localhost` can't have a valid certificate
+
263 /// let connecting = endpoint.connect("quic://localhost:443").await?;
+
264 /// # Ok(()) }
+
265 /// ```
+
2668 pub async fn connect<U: AsRef<str>>(&self, url: U) -> Result<Connecting, error::Connect> {
+
26738 let (address, domain) = self.resolve_domain(url).await?;
+
268
+
269 Ok(Connecting::new(
+
2707 self.endpoint
+
2717 .connect(address, &domain)
+
2727 .map_err(error::Connect::ConnectConfig)?,
+
273 ))
+
2748 }
+
275
+
276 /// Establishes a new [`Connection`](crate::Connection) to a server.
+
277 ///
+
278 /// See [`connect`](Self::connect) for more information on host name
+
279 /// resolution.
+
280 ///
+
281 /// # Notes
+
282 /// The root certificate store will be ignored and the given [`Certificate`]
+
283 /// will validate the server.
+
284 ///
+
285 /// A client certificate [`KeyPair`] set with
+
286 /// [`Builder::set_client_key_pair`] will be ignored, use `client_key_pair`
+
287 /// to add a client certificate to this connection.
+
288 ///
+
289 /// This method is intended for direct connection to a known server, the
+
290 /// domain name in the URL is not checked against the [`Certificate`].
+
291 /// Multiple domain names in the [`Certificate`] aren't supported.
+
292 ///
+
293 /// # Errors
+
294 /// - [`error::Connect::MultipleDomains`] if multiple domains are present in
+
295 /// the [`Certificate`], which isn't supported
+
296 /// - [`error::Connect::ParseUrl`] if the URL couldn't be parsed
+
297 /// - [`error::Connect::Domain`] if the URL didn't contain a domain
+
298 /// - [`error::Connect::Port`] if the URL didn't contain a port
+
299 /// - [`error::Connect::ParseDomain`] if the domain couldn't be parsed
+
300 /// - [`error::Connect::TrustDns`] if the URL couldn't be resolved to an IP
+
301 /// address with [`trust-dns`](trust_dns_resolver)
+
302 /// - [`error::Connect::StdDns`] if the URL couldn't be resolved to an IP
+
303 /// address with [`ToSocketAddrs`]
+
304 /// - [`error::Connect::NoIp`] if no IP address was found for that domain
+
305 ///
+
306 /// # Panics
+
307 /// Panics if the given [`Certificate`] or [`KeyPair`] are invalid. Can't
+
308 /// happen if they were properly validated through [`Certificate::from_der`]
+
309 /// or [`KeyPair::from_parts`].
+
310 ///
+
311 /// # Examples
+
312 /// ```
+
313 /// # #[tokio::main] async fn main() -> anyhow::Result<()> {
+
314 /// use fabruic::Endpoint;
+
315 ///
+
316 /// let endpoint = Endpoint::new_client()?;
+
317 /// // the server certificate has to be imported from somewhere else
+
318 /// # let (server_certificate, _) = fabruic::KeyPair::new_self_signed("localhost").into_parts();
+
319 /// # let server_certificate = server_certificate.into_end_entity_certificate();
+
320 /// let connecting = endpoint
+
321 /// .connect_pinned("quic://localhost:443", &server_certificate, None)
+
322 /// .await?;
+
323 /// # Ok(()) }
+
324 /// ```
+
325114 pub async fn connect_pinned<U: AsRef<str>>(
+
326114 &self,
+
327114 url: U,
+
328114 server_certificate: &Certificate,
+
329114 client_key_pair: Option<KeyPair>,
+
330114 ) -> Result<Connecting, error::Connect> {
+
331114 // check `Certificate` for a domain
+
332114 let mut domains = server_certificate.domains().into_iter();
+
333114 let domain = domains
+
334114 .next()
+
335114 .expect("`Certificate` contained no valid domains");
+
336114
+
337114 // multiple domains aren't supported
+
338114 if domains.next().is_some() {
3390 return Err(error::Connect::MultipleDomains);
-
340112 }
+
340114 }
341
342 // resolve URL
-
343112 let (address, _) = self.resolve_domain(url).await?;
+
343114 let (address, _) = self.resolve_domain(url).await?;
344
345 // build client configuration
-
346112 let client = self.config.new_client(
-
347112 slice::from_ref(server_certificate),
-
348112 Store::Empty,
-
349112 client_key_pair,
-
350112 false,
-
351112 );
+
346114 let client = self.config.new_client(
+
347114 slice::from_ref(server_certificate),
+
348114 Store::Empty,
+
349114 client_key_pair,
+
350114 false,
+
351114 );
352
353 // connect
-
354112 let connecting = self
-
355 .endpoint
-
356112 .connect_with(client.map_err(error::Config::from)?, address, &domain)
-
357112 .map_err(error::Connect::ConnectConfig)?;
+
354114 let connecting = self
+
355114 .endpoint
+
356114 .connect_with(client.map_err(error::Config::from)?, address, &domain)
+
357114 .map_err(error::Connect::ConnectConfig)?;
358
-
359112 Ok(Connecting::new(connecting))
-
360112 }
+
359114 Ok(Connecting::new(connecting))
+
360114 }
361
362 /// Resolve the IP from the given domain. See [`connect`](Self::connect) for
363 /// more details.
@@ -393,21 +393,21 @@
372 /// - [`error::Connect::StdDns`] if the URL couldn't be resolved to an IP
373 /// address with [`ToSocketAddrs`]
374 /// - [`error::Connect::NoIp`] if no IP address was found for that domain
-
375124 async fn resolve_domain(
-
376124 &self,
-
377124 url: impl AsRef<str>,
-
378124 ) -> Result<(SocketAddr, String), error::Connect> {
-
379124 let url = Url::parse(url.as_ref()).map_err(error::Connect::ParseUrl)?;
+
375126 async fn resolve_domain(
+
376126 &self,
+
377126 url: impl AsRef<str>,
+
378126 ) -> Result<(SocketAddr, String), error::Connect> {
+
379126 let url = Url::parse(url.as_ref()).map_err(error::Connect::ParseUrl)?;
380 // url removes known default ports, we don't actually want to accept known
381 // scheme's, but this is probably not intended behaviour
-
382124 let port = url.port_or_known_default().ok_or(error::Connect::Port)?;
-
383123 let domain = url.host_str().ok_or(error::Connect::Domain)?;
+
382126 let port = url.port_or_known_default().ok_or(error::Connect::Port)?;
+
383125 let domain = url.host_str().ok_or(error::Connect::Domain)?;
384 // url doesn't parse IP addresses unless the schema is known, which doesn't
385 // work for "quic://" for example
-
386123 let domain = match Host::parse(domain).map_err(error::Connect::ParseDomain)? {
+
386125 let domain = match Host::parse(domain).map_err(error::Connect::ParseDomain)? {
38710 Host::Domain(domain) => domain,
3880 Host::Ipv4(ip) => return Ok((SocketAddr::from((ip, port)), ip.to_string())),
-
389113 Host::Ipv6(ip) => return Ok((SocketAddr::from((ip, port)), ip.to_string())),
+
389115 Host::Ipv6(ip) => return Ok((SocketAddr::from((ip, port)), ip.to_string())),
390 };
391
392 #[cfg(feature = "trust-dns")]
@@ -431,598 +431,597 @@
4108 opts.use_hosts_file = self.config.hosts_file();
4118 opts.validate = self.config.dnssec();
4128 opts.try_tcp_on_error = true;
-
413
-
414 // build the `Resolver`
-
4158 let resolver = TokioAsyncResolver::tokio(ResolverConfig::cloudflare_https(), opts)
-
4168 .map_err(Box::new)?;
-
417 // query the IP
-
41838 let ip = resolver.lookup_ip(domain.clone()).await.map_err(Box::new)?;
-
419
-
420 // take the first IP found
-
421 // TODO: retry connection on other found IPs
-
4227 let ip = ip.into_iter().next().ok_or(error::Connect::NoIp)?;
-
423
-
4247 return Ok((SocketAddr::from((ip, port)), domain));
-
4252 }
-
426
-
427 // TODO: configurable executor
-
4282 let address = {
-
429 // `ToSocketAddrs` needs a port
-
4302 let domain = format!("{domain}:{port}");
-
4312 tokio::task::spawn_blocking(move || {
-
4322 domain
-
4332 .to_socket_addrs()
-
4342 .map_err(error::Connect::StdDns)?
-
4352 .next()
-
4362 .ok_or(error::Connect::NoIp)
-
4372 })
-
4382 .await
-
4392 .expect("Resolving domain panicked")?
-
440 };
-
441
-
4422 Ok((address, domain))
-
443124 }
-
444
-
445 /// Get the local [`SocketAddr`] the underlying socket is bound to.
-
446 ///
-
447 /// # Errors
-
448 /// [`std::io::Error`] if aquiring the local address failed.
-
449 ///
-
450 /// # Examples
-
451 /// ```
-
452 /// # #[tokio::main] async fn main() -> anyhow::Result<()> {
-
453 /// use fabruic::Endpoint;
-
454 ///
-
455 /// let endpoint = Endpoint::new_client()?;
-
456 /// assert!(endpoint.local_address().is_ok());
-
457 /// # Ok(()) }
-
458 /// ```
-
459124 pub fn local_address(&self) -> Result<SocketAddr, Error> {
-
460124 self.endpoint.local_addr()
-
461124 }
-
462
-
463 /// Close all of this [`Endpoint`]'s [`Connection`](crate::Connection)s
-
464 /// immediately and cease accepting new [`Connection`](crate::Connection)s.
-
465 ///
-
466 /// To close an [`Endpoint`] gracefully use
-
467 /// [`close_incoming`](Self::close_incoming),
-
468 /// [`Sender::finish`](crate::Sender::finish) and
-
469 /// [`wait_idle`](Self::wait_idle).
-
470 ///
-
471 /// # Examples
-
472 /// ```
-
473 /// # #[tokio::main] async fn main() -> anyhow::Result<()> {
-
474 /// use fabruic::Endpoint;
-
475 ///
-
476 /// let endpoint = Endpoint::new_client()?;
-
477 /// endpoint.close();
-
478 /// # Ok(()) }
-
479 /// ```
-
4804 pub async fn close(&self) {
-
4814 self.endpoint.close(VarInt::from_u32(0), &[]);
-
482 // Close the ability for incoming connections, and wait for the incoming
-
483 // connection task to exit.
-
4844 let _result = self.close_incoming().await;
-
4854 }
-
486
-
487 /// Prevents any new incoming connections. Already incoming connections will
-
488 /// finish first. This will always return [`error::AlreadyClosed`] if the
-
489 /// [`Endpoint`] wasn't started with a listener.
-
490 ///
-
491 /// See [`Builder::set_server_key_pair`].
-
492 ///
-
493 /// # Errors
-
494 /// [`error::AlreadyClosed`] if it was already closed.
-
495 ///
-
496 /// # Examples
-
497 /// ```
-
498 /// # #[tokio::main] async fn main() -> anyhow::Result<()> {
-
499 /// use fabruic::{Endpoint, KeyPair};
-
500 ///
-
501 /// let endpoint = Endpoint::new_server(0, KeyPair::new_self_signed("test"))?;
-
502 /// assert!(endpoint.close_incoming().await.is_ok());
-
503 /// # Ok(()) }
-
504 /// ```
-
5058 pub async fn close_incoming(&self) -> Result<(), error::AlreadyClosed> {
-
5068 if let Some(server) = &self.server {
-
5075 let mut server = server.lock();
-
5085 let _config = server.concurrent_connections(0);
-
5095 self.endpoint.set_server_config(Some(server.clone()));
-
5105 }
-
5118 self.task.close(()).await?;
-
5124 Ok(())
-
5138 }
-
514
-
515 /// Wait for all [`Connection`](crate::Connection)s to the [`Endpoint`] to
-
516 /// be cleanly shut down. Does not close existing connections or cause
-
517 /// incoming connections to be rejected. See
-
518 /// [`close_incoming`](`Self::close_incoming`).
-
519 ///
-
520 /// # Examples
-
521 /// ```
-
522 /// # #[tokio::main] async fn main() -> anyhow::Result<()> {
-
523 /// use fabruic::Endpoint;
-
524 ///
-
525 /// let endpoint = Endpoint::new_client()?;
-
526 /// endpoint.wait_idle().await;
-
527 /// # Ok(()) }
-
528 /// ```
-
529109 pub async fn wait_idle(&self) {
-
530109 self.endpoint.wait_idle().await;
-
531109 }
-
532}
-
533
-
534struct IncomingConnections<'a> {
-
535 endpoint: &'a quinn::Endpoint,
-
536 accept: Option<Pin<Box<Accept<'a>>>>,
-
537 shutdown: Receiver<()>,
-
538 sender: Sender<Connecting>,
-
539 complete: bool,
-
540}
-
541
-
542impl std::future::Future for IncomingConnections<'_> {
-
543 type Output = ();
-
544
-
54533 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
-
54633 if self.complete {
-
5470 return Poll::Ready(());
-
54833 }
-
54933
-
55033 match self.shutdown.poll_unpin(cx) {
-
551 Poll::Ready(_) => {
-
5524 self.complete = true;
-
5534 self.accept = None;
-
5544 Poll::Ready(())
-
555 }
-
556 Poll::Pending => {
-
557139 loop {
-
558139 let mut accept = self
-
559139 .accept
-
560139 .take()
-
561139 .unwrap_or_else(|| Box::pin(self.endpoint.accept()));
-
562139 match accept.poll_unpin(cx) {
-
563110 Poll::Ready(Some(connecting)) => {
-
564110 // if there is no receiver, it means that we dropped the last
-
565110 // `Endpoint`
-
566110 if self.sender.send(Connecting::new(connecting)).is_err() {
-
5670 self.complete = true;
-
5680 return Poll::Ready(());
-
569110 }
-
570 }
-
571 Poll::Ready(None) => {
-
5720 self.complete = true;
-
5730 return Poll::Ready(());
-
574 }
-
575 Poll::Pending => {
-
576 // Restore the same accept future to our state.
-
57729 self.accept = Some(accept);
-
57829 return Poll::Pending;
-
579 }
-
580 }
-
581 }
-
582 }
-
583 }
-
58433 }
-
585}
-
586
-
587/// Security-sensitive features for [`Endpoint`].
-
588#[async_trait]
-
589pub trait Dangerous {
-
590 /// Establishes a new [`Connection`](crate::Connection) to a server without
-
591 /// verifying the servers [`Certificate`]. The servers
-
592 /// [`CertificateChain`](crate::CertificateChain) can still be manually
-
593 /// insepcted through
-
594 /// [`Connection::peer_identity`](crate::Connection::peer_identity).
-
595 ///
-
596 /// See [`connect`](Endpoint::connect) for more information on host name
-
597 /// resolution.
-
598 ///
-
599 /// # Notes
-
600 /// A client certificate [`KeyPair`] set with
-
601 /// [`Builder::set_client_key_pair`] will be ignored, use `client_key_pair`
-
602 /// to add a client certificate to this connection.
-
603 ///
-
604 /// # Safety
-
605 /// Connecting to a server without verifying the [`Certificate`] provides no
-
606 /// way for the client to authenticate the servers identity.
-
607 /// This is primarily used to enable connections to unknown user-hosted
-
608 /// servers, e.g. multiplayer.
-
609 ///
-
610 /// There are many ways to prevent the need for this feature in certain
-
611 /// situations:
-
612 /// - during testing, a temporary certificate can be created
-
613 /// - use [Let's Encrypt](https://en.wikipedia.org/wiki/Let%27s_Encrypt) to
-
614 /// get a free certificate if a domain is present
-
615 /// - provide a middle-man service that helps connect clients with servers
-
616 /// by automatically communicating the servers public key
-
617 /// - share a public key over third-party communication channels beforehand
-
618 /// as a last resort
-
619 ///
-
620 /// # Errors
-
621 /// - [`error::Connect::ParseUrl`] if the URL couldn't be parsed
-
622 /// - [`error::Connect::Port`] if the URL didn't contain a port
-
623 /// - [`error::Connect::ParseDomain`] if the domain couldn't be parsed
-
624 /// - [`error::Connect::TrustDns`] if the URL couldn't be resolved to an IP
-
625 /// address with [`trust-dns`](trust_dns_resolver)
-
626 /// - [`error::Connect::StdDns`] if the URL couldn't be resolved to an IP
-
627 /// address with [`ToSocketAddrs`]
-
628 /// - [`error::Connect::NoIp`] if no IP address was found for that domain
-
629 ///
-
630 /// # Examples
-
631 /// ```
-
632 /// # #[tokio::main] async fn main() -> anyhow::Result<()> {
-
633 /// use fabruic::{dangerous, Endpoint};
-
634 ///
-
635 /// let endpoint = Endpoint::new_client()?;
-
636 /// let connecting =
-
637 /// dangerous::Endpoint::connect_unverified(&endpoint, "quic://localhost:443", None).await?;
-
638 /// # Ok(()) }
-
639 /// ```
-
640 async fn connect_unverified<U: AsRef<str> + Send>(
-
641 endpoint: &Self,
-
642 url: U,
-
643 client_key_pair: Option<KeyPair>,
-
644 ) -> Result<Connecting, error::Connect>;
-
645}
-
646
-
647#[async_trait]
-
648impl Dangerous for Endpoint {
-
6491 async fn connect_unverified<U: AsRef<str> + Send>(
-
6501 endpoint: &Self,
-
6511 url: U,
-
6521 client_key_pair: Option<KeyPair>,
-
6531 ) -> Result<Connecting, error::Connect> {
-
654 // resolve URL
-
6551 let (address, _) = endpoint.resolve_domain(url).await?;
-
656
-
657 // build client configuration
-
6581 let client = endpoint
-
6591 .config
-
6601 .new_client(&[], Store::Empty, client_key_pair, true);
-
661
-
662 // connect
-
6631 let connecting = endpoint
-
664 .endpoint
-
6651 .connect_with(client.map_err(error::Config::from)?, address, "placeholder")
-
6661 .map_err(error::Connect::ConnectConfig)?;
-
667
-
6681 Ok(Connecting::new(connecting))
-
6692 }
-
670}
-
671
-
672impl Stream for Endpoint {
-
673 type Item = Connecting;
-
674
-
675171 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
-
676171 if self.receiver.is_terminated() {
-
6773 Poll::Ready(None)
-
678 } else {
-
679168 self.receiver.poll_next_unpin(cx)
-
680 }
-
681171 }
-
682}
-
683
-
684impl FusedStream for Endpoint {
-
6850 fn is_terminated(&self) -> bool {
-
6860 self.receiver.is_terminated()
-
6870 }
-
688}
-
689
-
690#[cfg(test)]
-
691mod test {
-
692 use std::str::FromStr;
-
693
-
694 use anyhow::Result;
-
695 use futures_util::StreamExt;
-
696 use quinn::{ConnectionClose, ConnectionError};
-
697 use quinn_proto::TransportErrorCode;
-
698
-
699 use super::*;
-
700 use crate::KeyPair;
-
701
-
7021 #[test]
-
7031 fn builder() {
-
7041 let _builder: Builder = Endpoint::builder();
-
7051 }
-
706
-
7071 #[tokio::test]
-
7081 async fn endpoint() -> Result<()> {
-
7091 let key_pair = KeyPair::new_self_signed("test");
-
710
-
7111 let client = Endpoint::new_client()?;
-
7121 let mut server = Endpoint::new_server(0, key_pair.clone())?;
-
713
-
7141 let _connection = client
-
7151 .connect_pinned(
-
7161 format!("quic://{}", server.local_address()?),
-
7171 key_pair.end_entity_certificate(),
-
7181 None,
-
719 )
-
7200 .await?
-
7211 .accept::<()>()
-
7221 .await?;
-
7231 let _connection = server
-
7241 .next()
-
7250 .await
-
7261 .expect("client dropped")
-
7271 .accept::<()>()
-
7281 .await?;
-
729
-
7301 Ok(())
-
731 }
-
732
-
7331 #[tokio::test]
-
7341 async fn unverified() -> Result<()> {
-
7351 let key_pair = KeyPair::new_self_signed("test");
-
736
-
7371 let client = Endpoint::new_client()?;
-
7381 let mut server = Endpoint::new_server(0, key_pair.clone())?;
-
739
-
7401 let _connection = Dangerous::connect_unverified(
-
7411 &client,
-
7421 format!("quic://{}", server.local_address()?),
-
7431 None,
-
744 )
-
7450 .await?
-
7461 .accept::<()>()
-
7471 .await?;
-
7481 let _connection = server
-
7491 .next()
-
7500 .await
-
7511 .expect("client dropped")
-
7521 .accept::<()>()
-
7531 .await?;
-
754
-
7551 Ok(())
-
756 }
-
757
-
7581 #[tokio::test]
-
7591 async fn port() -> Result<()> {
-
7601 let client = Endpoint::new_client()?;
-
761
-
7621 assert!(matches!(
-
7631 client.resolve_domain("https://localhost").await,
-
7641 Ok((address, domain))
-
7651 if address == SocketAddr::from_str("[::1]:443")? && domain == "localhost"
-
766 ));
-
767
-
7681 assert!(matches!(
-
7691 client.resolve_domain("quic://localhost").await,
-
770 Err(error::Connect::Port)
-
771 ));
-
772
-
7731 assert!(matches!(
-
7741 client.resolve_domain("quic://localhost:443").await,
-
7751 Ok((address, domain))
-
7761 if address == SocketAddr::from_str("[::1]:443")? && domain == "localhost"
-
777 ));
-
778
-
7791 Ok(())
-
780 }
-
781
-
7821 #[tokio::test]
-
7831 async fn close() -> Result<()> {
-
7841 let key_pair = KeyPair::new_self_signed("test");
-
785
-
7861 let client = Endpoint::new_client()?;
-
7871 let mut server = Endpoint::new_server(0, key_pair.clone())?;
-
7881 let address = format!("quic://{}", server.local_address()?);
-
789
-
790 // `wait_idle` should never finish unless these `Connection`s are closed, which
-
791 // they won't unless they are dropped or explicitly closed
-
7921 let _connection = client
-
7931 .connect_pinned(&address, key_pair.end_entity_certificate(), None)
-
7940 .await?
-
7951 .accept::<()>()
-
7961 .await?;
-
7971 let _connection = server
-
7981 .next()
-
7990 .await
-
8001 .expect("client dropped")
-
8011 .accept::<()>()
-
8021 .await?;
-
803
-
804 // closing the client/server will close all connection immediately
-
8051 client.close().await;
-
8061 server.close().await;
-
807
-
808 // connecting to a closed server shouldn't work
-
8091 assert!(matches!(
-
8101 client
-
8111 .connect_pinned(address, key_pair.end_entity_certificate(), None)
-
8120 .await?
-
8131 .accept::<()>()
-
8141 .await,
-
815 Err(error::Connecting::Connection(
-
816 ConnectionError::LocallyClosed
-
817 ))
-
818 ));
-
819
-
820 // waiting for a new connection on a closed server shouldn't work
-
8211 assert!(matches!(server.next().await, None));
-
822
-
8231 client.wait_idle().await;
-
8241 server.wait_idle().await;
-
825
-
8261 Ok(())
-
827 }
-
828
-
8291 #[tokio::test]
-
8301 async fn close_and_reuse() -> Result<()> {
-
8311 let key_pair = KeyPair::new_self_signed("test");
-
832
-
8331 let client = Endpoint::new_client()?;
-
8341 let mut server = Endpoint::builder();
-
8351 server.set_server_key_pair(Some(key_pair.clone()));
-
8361 server.set_reuse_address(true);
-
8371 let mut server = server.build()?;
-
8381 let bound_address = server.local_address()?;
-
8391 let address = format!("quic://{}", server.local_address()?);
-
840
-
841 // `wait_idle` should never finish unless these `Connection`s are closed, which
-
842 // they won't unless they are dropped or explicitly closed
-
8431 let _connection = client
-
8441 .connect_pinned(&address, key_pair.end_entity_certificate(), None)
-
8450 .await?
-
8461 .accept::<()>()
-
8471 .await?;
-
8481 let _connection = server
-
8491 .next()
-
8500 .await
-
8511 .expect("client dropped")
-
8521 .accept::<()>()
-
8531 .await?;
-
854
-
855 // closing the client/server will close all connection immediately
-
8561 client.close().await;
-
8571 server.close().await;
-
858
-
859 // connecting to a closed server shouldn't work
-
8601 assert!(matches!(
-
8611 client
-
8621 .connect_pinned(address, key_pair.end_entity_certificate(), None)
-
8630 .await?
-
8641 .accept::<()>()
-
8651 .await,
-
866 Err(error::Connecting::Connection(
-
867 ConnectionError::LocallyClosed
-
868 ))
-
869 ));
-
870
-
871 // waiting for a new connection on a closed server shouldn't work
-
8721 assert!(matches!(server.next().await, None));
-
873
-
8741 client.wait_idle().await;
-
8751 server.wait_idle().await;
-
876
-
877 // Try listening again.
-
8781 let mut server = Endpoint::builder();
-
8791 server.set_address(bound_address);
-
8801 server.set_server_key_pair(Some(key_pair.clone()));
-
8811 server.set_reuse_address(true);
-
8821 let mut server = server.build()?;
-
8831 let address = format!("quic://{}", server.local_address()?);
-
884
-
8851 let client = Endpoint::new_client()?;
-
8861 let _connection = client
-
8871 .connect_pinned(&address, key_pair.end_entity_certificate(), None)
-
8880 .await
-
8891 .unwrap()
-
8901 .accept::<()>()
-
8911 .await
-
8921 .unwrap();
-
8931 let _connection = server.next().await.expect("client dropped");
-
8941
-
8951 Ok(())
-
896 }
-
897
-
8981 #[tokio::test]
-
8991 async fn close_incoming() -> Result<()> {
-
9001 let key_pair = KeyPair::new_self_signed("test");
-
901
-
9021 let client = Endpoint::new_client()?;
-
9031 let mut server = Endpoint::new_server(0, key_pair.clone())?;
-
9041 let address = format!("quic://{}", server.local_address()?);
-
905
-
906 // these `Connection`s should still work even if new incoming connections are
-
907 // refused
-
9081 let client_connection = client
-
9091 .connect_pinned(&address, key_pair.end_entity_certificate(), None)
-
9100 .await?
-
9111 .accept::<()>()
-
9121 .await?;
-
9131 let mut server_connection = server
-
9141 .next()
-
9150 .await
-
9161 .expect("client dropped")
-
9171 .accept::<()>()
-
9181 .await?;
-
919
-
920 // refuse new incoming connections
-
921 // client never accepts incoming connections
-
9221 assert!(matches!(
-
9231 client.close_incoming().await,
-
924 Err(error::AlreadyClosed)
-
925 ));
-
9261 server.close_incoming().await?;
-
9271 assert!(matches!(
-
9281 server.close_incoming().await,
-
929 Err(error::AlreadyClosed)
-
930 ));
-
931
-
932 // connecting to a server that refuses new `Connection`s shouldn't work
-
9331 let result = client
-
9341 .connect_pinned(address, key_pair.end_entity_certificate(), None)
-
9350 .await?
-
9361 .accept::<()>()
-
9371 .await;
-
9381 assert!(matches!(
-
9391 result,
-
940 Err(error::Connecting::Connection(ConnectionError::ConnectionClosed(
-
941 ConnectionClose {
-
942 error_code: TransportErrorCode::CONNECTION_REFUSED,
-
943 frame_type: None,
-
9441 reason: bytes,
-
9451 }
-
9461 ))) if bytes.is_empty()
-
947 ));
-
948
-
949 // waiting for a new connection on a server that refuses new `Connection`s
-
950 // shouldn't work
-
9511 assert!(matches!(server.next().await, None));
-
952
-
953 {
-
9541 let (sender, _) = client_connection.open_stream::<(), ()>(&()).await?;
-
9551 let _server_stream = server_connection
-
9561 .next()
-
9571 .await
-
9581 .expect("client dropped")?
-
9591 .accept::<(), ()>();
-
9601 sender.finish().await?;
-
961 }
-
962
-
9631 drop(client_connection);
-
9641 drop(server_connection);
-
9651
-
9661 client.wait_idle().await;
-
9671 server.wait_idle().await;
-
968
-
9691 Ok(())
-
970 }
-
971
-
9721 #[tokio::test]
-
9731 async fn wait_idle() -> Result<()> {
-
9741 let key_pair = KeyPair::new_self_signed("test");
-
975
-
9761 let client = Endpoint::new_client()?;
-
9771 let mut server = Endpoint::new_server(0, key_pair.clone())?;
-
978
-
979 // `wait_idle` will never finish unless the `Connection` closes, which happens
-
980 // automatically when it's dropped
-
981 {
-
9821 let _connection = client
-
9831 .connect_pinned(
-
9841 format!("quic://{}", server.local_address()?),
-
9851 key_pair.end_entity_certificate(),
-
9861 None,
-
987 )
-
9880 .await?
-
9891 .accept::<()>()
-
9901 .await?;
-
9911 let _connection = server
-
9921 .next()
-
9930 .await
-
9941 .expect("client dropped")
-
9951 .accept::<()>()
-
9961 .await?;
-
997 }
-
998
-
9991 client.wait_idle().await;
-
10001 server.wait_idle().await;
-
1001
-
10021 Ok(())
-
1003 }
-
1004}
+
4138
+
4148 // build the `Resolver`
+
4158 let resolver = TokioAsyncResolver::tokio(ResolverConfig::cloudflare_https(), opts);
+
416 // query the IP
+
41736 let ip = resolver.lookup_ip(domain.clone()).await.map_err(Box::new)?;
+
418
+
419 // take the first IP found
+
420 // TODO: retry connection on other found IPs
+
4217 let ip = ip.into_iter().next().ok_or(error::Connect::NoIp)?;
+
422
+
4237 return Ok((SocketAddr::from((ip, port)), domain));
+
4242 }
+
425
+
426 // TODO: configurable executor
+
4272 let address = {
+
428 // `ToSocketAddrs` needs a port
+
4292 let domain = format!("{domain}:{port}");
+
4302 tokio::task::spawn_blocking(move || {
+
4312 domain
+
4322 .to_socket_addrs()
+
4332 .map_err(error::Connect::StdDns)?
+
4342 .next()
+
4352 .ok_or(error::Connect::NoIp)
+
4362 })
+
4372 .await
+
4382 .expect("Resolving domain panicked")?
+
439 };
+
440
+
4412 Ok((address, domain))
+
442126 }
+
443
+
444 /// Get the local [`SocketAddr`] the underlying socket is bound to.
+
445 ///
+
446 /// # Errors
+
447 /// [`std::io::Error`] if aquiring the local address failed.
+
448 ///
+
449 /// # Examples
+
450 /// ```
+
451 /// # #[tokio::main] async fn main() -> anyhow::Result<()> {
+
452 /// use fabruic::Endpoint;
+
453 ///
+
454 /// let endpoint = Endpoint::new_client()?;
+
455 /// assert!(endpoint.local_address().is_ok());
+
456 /// # Ok(()) }
+
457 /// ```
+
458336 pub fn local_address(&self) -> Result<SocketAddr, Error> {
+
459336 self.endpoint.local_addr()
+
460336 }
+
461
+
462 /// Close all of this [`Endpoint`]'s [`Connection`](crate::Connection)s
+
463 /// immediately and cease accepting new [`Connection`](crate::Connection)s.
+
464 ///
+
465 /// To close an [`Endpoint`] gracefully use
+
466 /// [`close_incoming`](Self::close_incoming),
+
467 /// [`Sender::finish`](crate::Sender::finish) and
+
468 /// [`wait_idle`](Self::wait_idle).
+
469 ///
+
470 /// # Examples
+
471 /// ```
+
472 /// # #[tokio::main] async fn main() -> anyhow::Result<()> {
+
473 /// use fabruic::Endpoint;
+
474 ///
+
475 /// let endpoint = Endpoint::new_client()?;
+
476 /// endpoint.close();
+
477 /// # Ok(()) }
+
478 /// ```
+
4794 pub async fn close(&self) {
+
4804 self.endpoint.close(VarInt::from_u32(0), &[]);
+
481 // Close the ability for incoming connections, and wait for the incoming
+
482 // connection task to exit.
+
4834 let _result = self.close_incoming().await;
+
4844 }
+
485
+
486 /// Prevents any new incoming connections. Already incoming connections will
+
487 /// finish first. This will always return [`error::AlreadyClosed`] if the
+
488 /// [`Endpoint`] wasn't started with a listener.
+
489 ///
+
490 /// See [`Builder::set_server_key_pair`].
+
491 ///
+
492 /// # Errors
+
493 /// [`error::AlreadyClosed`] if it was already closed.
+
494 ///
+
495 /// # Examples
+
496 /// ```
+
497 /// # #[tokio::main] async fn main() -> anyhow::Result<()> {
+
498 /// use fabruic::{Endpoint, KeyPair};
+
499 ///
+
500 /// let endpoint = Endpoint::new_server(0, KeyPair::new_self_signed("test"))?;
+
501 /// assert!(endpoint.close_incoming().await.is_ok());
+
502 /// # Ok(()) }
+
503 /// ```
+
50410 pub async fn close_incoming(&self) -> Result<(), error::AlreadyClosed> {
+
5058 if let Some(server) = &self.server {
+
5065 let mut server = server.lock();
+
5075 let _config = server.concurrent_connections(0);
+
5085 self.endpoint.set_server_config(Some(server.clone()));
+
5095 }
+
5108 self.task.close(()).await?;
+
5114 Ok(())
+
5128 }
+
513
+
514 /// Wait for all [`Connection`](crate::Connection)s to the [`Endpoint`] to
+
515 /// be cleanly shut down. Does not close existing connections or cause
+
516 /// incoming connections to be rejected. See
+
517 /// [`close_incoming`](`Self::close_incoming`).
+
518 ///
+
519 /// # Examples
+
520 /// ```
+
521 /// # #[tokio::main] async fn main() -> anyhow::Result<()> {
+
522 /// use fabruic::Endpoint;
+
523 ///
+
524 /// let endpoint = Endpoint::new_client()?;
+
525 /// endpoint.wait_idle().await;
+
526 /// # Ok(()) }
+
527 /// ```
+
528317 pub async fn wait_idle(&self) {
+
529111 self.endpoint.wait_idle().await;
+
530111 }
+
531}
+
532
+
533struct IncomingConnections<'connection> {
+
534 endpoint: &'connection quinn::Endpoint,
+
535 accept: Option<Pin<Box<Accept<'connection>>>>,
+
536 shutdown: Receiver<()>,
+
537 sender: Sender<Connecting>,
+
538 complete: bool,
+
539}
+
540
+
541impl Future for IncomingConnections<'_> {
+
542 type Output = ();
+
543
+
54466 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+
54566 if self.complete {
+
5460 return Poll::Ready(());
+
54766 }
+
54866
+
54966 match self.shutdown.poll_unpin(cx) {
+
550 Poll::Ready(_) => {
+
5519 self.complete = true;
+
5529 self.accept = None;
+
5539 Poll::Ready(())
+
554 }
+
555 Poll::Pending => {
+
556373 loop {
+
557373 let mut accept = self
+
558373 .accept
+
559373 .take()
+
560373 .unwrap_or_else(|| Box::pin(self.endpoint.accept()));
+
561373 match accept.poll_unpin(cx) {
+
562316 Poll::Ready(Some(connecting)) => {
+
563316 // if there is no receiver, it means that we dropped the last
+
564316 // `Endpoint`
+
565316 if self.sender.send(Connecting::new(connecting)).is_err() {
+
5660 self.complete = true;
+
5670 return Poll::Ready(());
+
568316 }
+
569 }
+
570 Poll::Ready(None) => {
+
5710 self.complete = true;
+
5720 return Poll::Ready(());
+
573 }
+
574 Poll::Pending => {
+
575 // Restore the same accept future to our state.
+
57657 self.accept = Some(accept);
+
57757 return Poll::Pending;
+
578 }
+
579 }
+
580 }
+
581 }
+
582 }
+
58366 }
+
584}
+
585
+
586/// Security-sensitive features for [`Endpoint`].
+
587#[async_trait]
+
588pub trait Dangerous {
+
589 /// Establishes a new [`Connection`](crate::Connection) to a server without
+
590 /// verifying the servers [`Certificate`]. The servers
+
591 /// [`CertificateChain`](crate::CertificateChain) can still be manually
+
592 /// insepcted through
+
593 /// [`Connection::peer_identity`](crate::Connection::peer_identity).
+
594 ///
+
595 /// See [`connect`](Endpoint::connect) for more information on host name
+
596 /// resolution.
+
597 ///
+
598 /// # Notes
+
599 /// A client certificate [`KeyPair`] set with
+
600 /// [`Builder::set_client_key_pair`] will be ignored, use `client_key_pair`
+
601 /// to add a client certificate to this connection.
+
602 ///
+
603 /// # Safety
+
604 /// Connecting to a server without verifying the [`Certificate`] provides no
+
605 /// way for the client to authenticate the servers identity.
+
606 /// This is primarily used to enable connections to unknown user-hosted
+
607 /// servers, e.g. multiplayer.
+
608 ///
+
609 /// There are many ways to prevent the need for this feature in certain
+
610 /// situations:
+
611 /// - during testing, a temporary certificate can be created
+
612 /// - use [Let's Encrypt](https://en.wikipedia.org/wiki/Let%27s_Encrypt) to
+
613 /// get a free certificate if a domain is present
+
614 /// - provide a middle-man service that helps connect clients with servers
+
615 /// by automatically communicating the servers public key
+
616 /// - share a public key over third-party communication channels beforehand
+
617 /// as a last resort
+
618 ///
+
619 /// # Errors
+
620 /// - [`error::Connect::ParseUrl`] if the URL couldn't be parsed
+
621 /// - [`error::Connect::Port`] if the URL didn't contain a port
+
622 /// - [`error::Connect::ParseDomain`] if the domain couldn't be parsed
+
623 /// - [`error::Connect::TrustDns`] if the URL couldn't be resolved to an IP
+
624 /// address with [`trust-dns`](trust_dns_resolver)
+
625 /// - [`error::Connect::StdDns`] if the URL couldn't be resolved to an IP
+
626 /// address with [`ToSocketAddrs`]
+
627 /// - [`error::Connect::NoIp`] if no IP address was found for that domain
+
628 ///
+
629 /// # Examples
+
630 /// ```
+
631 /// # #[tokio::main] async fn main() -> anyhow::Result<()> {
+
632 /// use fabruic::{dangerous, Endpoint};
+
633 ///
+
634 /// let endpoint = Endpoint::new_client()?;
+
635 /// let connecting =
+
636 /// dangerous::Endpoint::connect_unverified(&endpoint, "quic://localhost:443", None).await?;
+
637 /// # Ok(()) }
+
638 /// ```
+
639 async fn connect_unverified<U: AsRef<str> + Send>(
+
640 endpoint: &Self,
+
641 url: U,
+
642 client_key_pair: Option<KeyPair>,
+
643 ) -> Result<Connecting, error::Connect>;
+
644}
+
645
+
646#[async_trait]
+
647impl Dangerous for Endpoint {
+
6481 async fn connect_unverified<U: AsRef<str> + Send>(
+
6491 endpoint: &Self,
+
6501 url: U,
+
6511 client_key_pair: Option<KeyPair>,
+
6521 ) -> Result<Connecting, error::Connect> {
+
653 // resolve URL
+
6541 let (address, _) = endpoint.resolve_domain(url).await?;
+
655
+
656 // build client configuration
+
6571 let client = endpoint
+
6581 .config
+
6591 .new_client(&[], Store::Empty, client_key_pair, true);
+
660
+
661 // connect
+
6621 let connecting = endpoint
+
6631 .endpoint
+
6641 .connect_with(client.map_err(error::Config::from)?, address, "placeholder")
+
6651 .map_err(error::Connect::ConnectConfig)?;
+
666
+
6671 Ok(Connecting::new(connecting))
+
6682 }
+
669}
+
670
+
671impl Stream for Endpoint {
+
672 type Item = Connecting;
+
673
+
674440 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+
675440 if self.receiver.is_terminated() {
+
6763 Poll::Ready(None)
+
677 } else {
+
678437 self.receiver.poll_next_unpin(cx)
+
679 }
+
680440 }
+
681}
+
682
+
683impl FusedStream for Endpoint {
+
6840 fn is_terminated(&self) -> bool {
+
6850 self.receiver.is_terminated()
+
6860 }
+
687}
+
688
+
689#[cfg(test)]
+
690mod test {
+
691 use std::str::FromStr;
+
692
+
693 use anyhow::Result;
+
694 use futures_util::StreamExt;
+
695 use quinn::{ConnectionClose, ConnectionError};
+
696 use quinn_proto::TransportErrorCode;
+
697
+
698 use super::*;
+
699 use crate::KeyPair;
+
700
+
7011 #[test]
+
7021 fn builder() {
+
7031 let _builder = Endpoint::builder();
+
7041 }
+
705
+
7061 #[tokio::test]
+
7071 async fn endpoint() -> Result<()> {
+
7081 let key_pair = KeyPair::new_self_signed("test");
+
709
+
7101 let client = Endpoint::new_client()?;
+
7111 let mut server = Endpoint::new_server(0, key_pair.clone())?;
+
712
+
7131 let _connection = client
+
7141 .connect_pinned(
+
7151 format!("quic://{}", server.local_address()?),
+
7161 key_pair.end_entity_certificate(),
+
7171 None,
+
718 )
+
7190 .await?
+
7201 .accept::<()>()
+
7211 .await?;
+
7221 let _connection = server
+
7231 .next()
+
7240 .await
+
7251 .expect("client dropped")
+
7261 .accept::<()>()
+
7271 .await?;
+
728
+
7291 Ok(())
+
730 }
+
731
+
7321 #[tokio::test]
+
7331 async fn unverified() -> Result<()> {
+
7341 let key_pair = KeyPair::new_self_signed("test");
+
735
+
7361 let client = Endpoint::new_client()?;
+
7371 let mut server = Endpoint::new_server(0, key_pair.clone())?;
+
738
+
7391 let _connection = Dangerous::connect_unverified(
+
7401 &client,
+
7411 format!("quic://{}", server.local_address()?),
+
7421 None,
+
743 )
+
7440 .await?
+
7451 .accept::<()>()
+
7461 .await?;
+
7471 let _connection = server
+
7481 .next()
+
7490 .await
+
7501 .expect("client dropped")
+
7511 .accept::<()>()
+
7521 .await?;
+
753
+
7541 Ok(())
+
755 }
+
756
+
7571 #[tokio::test]
+
7581 async fn port() -> Result<()> {
+
7591 let client = Endpoint::new_client()?;
+
760
+
7611 assert!(matches!(
+
7621 client.resolve_domain("https://localhost").await,
+
7631 Ok((address, domain))
+
7641 if address == SocketAddr::from_str("[::1]:443")? && domain == "localhost"
+
765 ));
+
766
+
7671 assert!(matches!(
+
7681 client.resolve_domain("quic://localhost").await,
+
769 Err(error::Connect::Port)
+
770 ));
+
771
+
7721 assert!(matches!(
+
7731 client.resolve_domain("quic://localhost:443").await,
+
7741 Ok((address, domain))
+
7751 if address == SocketAddr::from_str("[::1]:443")? && domain == "localhost"
+
776 ));
+
777
+
7781 Ok(())
+
779 }
+
780
+
7811 #[tokio::test]
+
7821 async fn close() -> Result<()> {
+
7831 let key_pair = KeyPair::new_self_signed("test");
+
784
+
7851 let client = Endpoint::new_client()?;
+
7861 let mut server = Endpoint::new_server(0, key_pair.clone())?;
+
7871 let address = format!("quic://{}", server.local_address()?);
+
788
+
789 // `wait_idle` should never finish unless these `Connection`s are closed, which
+
790 // they won't unless they are dropped or explicitly closed
+
7911 let _connection = client
+
7921 .connect_pinned(&address, key_pair.end_entity_certificate(), None)
+
7930 .await?
+
7941 .accept::<()>()
+
7951 .await?;
+
7961 let _connection = server
+
7971 .next()
+
7980 .await
+
7991 .expect("client dropped")
+
8001 .accept::<()>()
+
8011 .await?;
+
802
+
803 // closing the client/server will close all connection immediately
+
8041 client.close().await;
+
8051 server.close().await;
+
806
+
807 // connecting to a closed server shouldn't work
+
8081 assert!(matches!(
+
8091 client
+
8101 .connect_pinned(address, key_pair.end_entity_certificate(), None)
+
8110 .await?
+
8121 .accept::<()>()
+
8131 .await,
+
814 Err(error::Connecting::Connection(
+
815 ConnectionError::LocallyClosed
+
816 ))
+
817 ));
+
818
+
819 // waiting for a new connection on a closed server shouldn't work
+
8201 assert!(server.next().await.is_none());
+
821
+
8221 client.wait_idle().await;
+
8231 server.wait_idle().await;
+
824
+
8251 Ok(())
+
826 }
+
827
+
8281 #[tokio::test]
+
8291 async fn close_and_reuse() -> Result<()> {
+
8301 let key_pair = KeyPair::new_self_signed("test");
+
831
+
8321 let client = Endpoint::new_client()?;
+
8331 let mut server = Endpoint::builder();
+
8341 server.set_server_key_pair(Some(key_pair.clone()));
+
8351 server.set_reuse_address(true);
+
8361 let mut server = server.build()?;
+
8371 let bound_address = server.local_address()?;
+
8381 let address = format!("quic://{}", server.local_address()?);
+
839
+
840 // `wait_idle` should never finish unless these `Connection`s are closed, which
+
841 // they won't unless they are dropped or explicitly closed
+
8421 let _connection = client
+
8431 .connect_pinned(&address, key_pair.end_entity_certificate(), None)
+
8440 .await?
+
8451 .accept::<()>()
+
8461 .await?;
+
8471 let _connection = server
+
8481 .next()
+
8490 .await
+
8501 .expect("client dropped")
+
8511 .accept::<()>()
+
8521 .await?;
+
853
+
854 // closing the client/server will close all connection immediately
+
8551 client.close().await;
+
8561 server.close().await;
+
857
+
858 // connecting to a closed server shouldn't work
+
8591 assert!(matches!(
+
8601 client
+
8611 .connect_pinned(address, key_pair.end_entity_certificate(), None)
+
8620 .await?
+
8631 .accept::<()>()
+
8641 .await,
+
865 Err(error::Connecting::Connection(
+
866 ConnectionError::LocallyClosed
+
867 ))
+
868 ));
+
869
+
870 // waiting for a new connection on a closed server shouldn't work
+
8711 assert!(server.next().await.is_none());
+
872
+
8731 client.wait_idle().await;
+
8741 server.wait_idle().await;
+
875
+
876 // Try listening again.
+
8771 let mut server = Endpoint::builder();
+
8781 server.set_address(bound_address);
+
8791 server.set_server_key_pair(Some(key_pair.clone()));
+
8801 server.set_reuse_address(true);
+
8811 let mut server = server.build()?;
+
8821 let address = format!("quic://{}", server.local_address()?);
+
883
+
8841 let client = Endpoint::new_client()?;
+
8851 let _connection = client
+
8861 .connect_pinned(&address, key_pair.end_entity_certificate(), None)
+
8870 .await
+
8881 .unwrap()
+
8891 .accept::<()>()
+
8901 .await
+
8911 .unwrap();
+
8921 let _connection = server.next().await.expect("client dropped");
+
8931
+
8941 Ok(())
+
895 }
+
896
+
8971 #[tokio::test]
+
8981 async fn close_incoming() -> Result<()> {
+
8991 let key_pair = KeyPair::new_self_signed("test");
+
900
+
9011 let client = Endpoint::new_client()?;
+
9021 let mut server = Endpoint::new_server(0, key_pair.clone())?;
+
9031 let address = format!("quic://{}", server.local_address()?);
+
904
+
905 // these `Connection`s should still work even if new incoming connections are
+
906 // refused
+
9071 let client_connection = client
+
9081 .connect_pinned(&address, key_pair.end_entity_certificate(), None)
+
9090 .await?
+
9101 .accept::<()>()
+
9111 .await?;
+
9121 let mut server_connection = server
+
9131 .next()
+
9140 .await
+
9151 .expect("client dropped")
+
9161 .accept::<()>()
+
9171 .await?;
+
918
+
919 // refuse new incoming connections
+
920 // client never accepts incoming connections
+
9211 assert!(matches!(
+
9221 client.close_incoming().await,
+
923 Err(error::AlreadyClosed)
+
924 ));
+
9251 server.close_incoming().await?;
+
9261 assert!(matches!(
+
9271 server.close_incoming().await,
+
928 Err(error::AlreadyClosed)
+
929 ));
+
930
+
931 // connecting to a server that refuses new `Connection`s shouldn't work
+
9321 let result = client
+
9331 .connect_pinned(address, key_pair.end_entity_certificate(), None)
+
9340 .await?
+
9351 .accept::<()>()
+
9361 .await;
+
9371 assert!(matches!(
+
9381 result,
+
939 Err(error::Connecting::Connection(ConnectionError::ConnectionClosed(
+
940 ConnectionClose {
+
941 error_code: TransportErrorCode::CONNECTION_REFUSED,
+
942 frame_type: None,
+
9431 reason: bytes,
+
944 }
+
9451 ))) if bytes.is_empty()
+
946 ));
+
947
+
948 // waiting for a new connection on a server that refuses new `Connection`s
+
949 // shouldn't work
+
9501 assert!(server.next().await.is_none());
+
951
+
952 {
+
9531 let (sender, _) = client_connection.open_stream::<(), ()>(&()).await?;
+
9541 let _server_stream = server_connection
+
9551 .next()
+
9561 .await
+
9571 .expect("client dropped")?
+
9581 .accept::<(), ()>();
+
9591 sender.finish().await?;
+
960 }
+
961
+
9621 drop(client_connection);
+
9631 drop(server_connection);
+
9641
+
9651 client.wait_idle().await;
+
9661 server.wait_idle().await;
+
967
+
9681 Ok(())
+
969 }
+
970
+
9711 #[tokio::test]
+
9721 async fn wait_idle() -> Result<()> {
+
9731 let key_pair = KeyPair::new_self_signed("test");
+
974
+
9751 let client = Endpoint::new_client()?;
+
9761 let mut server = Endpoint::new_server(0, key_pair.clone())?;
+
977
+
978 // `wait_idle` will never finish unless the `Connection` closes, which happens
+
979 // automatically when it's dropped
+
980 {
+
9811 let _connection = client
+
9821 .connect_pinned(
+
9831 format!("quic://{}", server.local_address()?),
+
9841 key_pair.end_entity_certificate(),
+
9851 None,
+
986 )
+
9870 .await?
+
9881 .accept::<()>()
+
9891 .await?;
+
9901 let _connection = server
+
9911 .next()
+
9920 .await
+
9931 .expect("client dropped")
+
9941 .accept::<()>()
+
9951 .await?;
+
996 }
+
997
+
9981 client.wait_idle().await;
+
9991 server.wait_idle().await;
+
1000
+
10011 Ok(())
+
1002 }
+
1003}
diff --git a/coverage/src/quic/index.html b/coverage/src/quic/index.html index 0bd8ec7..92e6d59 100644 --- a/coverage/src/quic/index.html +++ b/coverage/src/quic/index.html @@ -9,18 +9,18 @@
Current view:top level - src/quic
-
Date:2023-07-07 10:30:44
+
Date:2023-08-25 14:31:32
HitTotalCoverage
Lines10110497.1 %
-
Functions566783.6 %
+
Functions769381.7 %
Branches000.0 %
FilenameLine CoverageFunctionsBranches
-
task.rs97.1%101 / 10483.6%56 / 670.0%0 / 0
+
task.rs97.1%101 / 10481.7%76 / 930.0%0 / 0
diff --git a/coverage/src/quic/task.rs.html b/coverage/src/quic/task.rs.html index a158767..4968889 100644 --- a/coverage/src/quic/task.rs.html +++ b/coverage/src/quic/task.rs.html @@ -9,12 +9,12 @@
Current view:top level - src/quic - task.rs
-
Date:2023-07-07 10:30:44
+
Date:2023-08-25 14:31:32
HitTotalCoverage
Lines10110497.1 %
-
Functions566783.6 %
+
Functions769381.7 %
Branches000.0 %
@@ -41,9 +41,9 @@
20pub(super) struct Task<R, S = ()>(Arc<Mutex<Option<Inner<R, S>>>>);
21
22impl<R, S> Clone for Task<R, S> {
-
231 fn clone(&self) -> Self {
-
241 Self(Arc::clone(&self.0))
-
251 }
+
2320201 fn clone(&self) -> Self {
+
2420201 Self(Arc::clone(&self.0))
+
2520201 }
26}
27
28/// Inner wrapper for [`Task`].
@@ -57,34 +57,34 @@
36
37impl<R> Task<R> {
38 /// Builds a new [`Task`].
-
39639 pub(super) fn new<T, F, S>(task: T) -> Task<R, S>
-
40639 where
-
41639 T: FnOnce(Receiver<S>) -> F,
-
42639 F: Future<Output = R> + Send + 'static,
-
43639 F::Output: Send + 'static,
-
44639 {
-
45639 let (sender, receiver) = oneshot::channel();
-
46639
-
47639 // TODO: configurable executor
-
48639 let handle = tokio::spawn(task(receiver));
-
49639
-
50639 Task(Arc::new(Mutex::new(Some(Inner {
-
51639 handle,
-
52639 close: sender,
-
53639 }))))
-
54639 }
+
394655 pub(super) fn new<T, F, S>(task: T) -> Task<R, S>
+
404655 where
+
414655 T: FnOnce(Receiver<S>) -> F,
+
424655 F: Future<Output = R> + Send + 'static,
+
434655 F::Output: Send + 'static,
+
444655 {
+
454655 let (sender, receiver) = oneshot::channel();
+
464655
+
474655 // TODO: configurable executor
+
484655 let handle = tokio::spawn(task(receiver));
+
494655
+
504655 Task(Arc::new(Mutex::new(Some(Inner {
+
514655 handle,
+
524655 close: sender,
+
534655 }))))
+
544655 }
55
56 /// Builds a new empty [`Task`] that is already closed. This is useful to
57 /// not have to wrap [`Task`] in another [`Option`].
-
58124 pub(super) fn empty() -> Self {
-
59124 Self(Arc::new(Mutex::new(None)))
-
60124 }
+
58330 pub(super) fn empty() -> Self {
+
59330 Self(Arc::new(Mutex::new(None)))
+
60330 }
61}
62
63impl<R, S> Task<R, S> {
-
64411 fn take_inner(&self) -> Option<Inner<R, S>> {
-
65411 self.0.lock().take()
-
66411 }
+
641414 fn take_inner(&self) -> Option<Inner<R, S>> {
+
651414 self.0.lock().take()
+
661414 }
67
68 /// Shuts down the [`Task`] by sending the close signal. Futher calls to
69 /// [`close`](Self::close) or [`poll`](Future::poll)ing the [`Task`] will
@@ -96,50 +96,50 @@
75 ///
76 /// # Panics
77 /// Will propagate any panics that happened in the task.
-
78411 pub(super) async fn close(&self, message: S) -> Result<R, error::AlreadyClosed> {
-
79411 if let Some(Inner { handle, close }) = self.take_inner() {
+
781414 pub(super) async fn close(&self, message: S) -> Result<R, error::AlreadyClosed> {
+
791414 if let Some(Inner { handle, close }) = self.take_inner() {
80 // task could have finished and dropped the receiver, it's also possible that
81 // the receiver got dropped otherwise, in any case, not our problem
-
82407 let _result = close.send(message);
-
83407
-
84407 match handle.await.map_err(JoinError::into_panic) {
-
85406 Ok(result) => Ok(result),
+
821410 let _result = close.send(message);
+
831410
+
841410 match handle.await.map_err(JoinError::into_panic) {
+
851409 Ok(result) => Ok(result),
86 // propagate any panics
871 Err(panic) => panic::resume_unwind(panic),
88 }
89 } else {
904 Err(error::AlreadyClosed)
91 }
-
92410 }
+
921413 }
93}
94
95impl<R, S> Future for &Task<R, S> {
96 type Output = Result<R, error::AlreadyClosed>;
97
-
98210 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
-
99210 // save the lock in a separate variable to be able to drop it
-
100210 let mut inner = self.0.lock();
+
981225 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+
991225 // save the lock in a separate variable to be able to drop it
+
1001225 let mut inner = self.0.lock();
101
-
102210 if let Some(Inner { handle, .. }) = inner.as_mut() {
-
103207 if let Poll::Ready(result) = handle.poll_unpin(cx) {
+
1021225 if let Some(Inner { handle, .. }) = inner.as_mut() {
+
1031222 if let Poll::Ready(result) = handle.poll_unpin(cx) {
104 // drop inner, `close` might be called simultaneously, so we don't handle this
-
105202 let _inner = inner.take();
-
106202 // drop `Mutex` before doing anything rash (parking_lot `Mutex` can't be
-
107202 // poisoned anyway)
-
108202 drop(inner);
-
109202
-
110202 match result.map_err(JoinError::into_panic) {
-
111201 Ok(result) => Poll::Ready(Ok(result)),
+
1051202 let _inner = inner.take();
+
1061202 // drop `Mutex` before doing anything rash (parking_lot `Mutex` can't be
+
1071202 // poisoned anyway)
+
1081202 drop(inner);
+
1091202
+
1101202 match result.map_err(JoinError::into_panic) {
+
1111201 Ok(result) => Poll::Ready(Ok(result)),
112 // propagate any panics
1131 Err(panic) => panic::resume_unwind(panic),
114 }
115 } else {
-
1165 Poll::Pending
+
11620 Poll::Pending
117 }
118 } else {
1193 Poll::Ready(Err(error::AlreadyClosed))
120 }
-
121209 }
+
1211224 }
122}
123
124#[cfg(test)]
@@ -213,30 +213,26 @@
192
1931 #[tokio::test]
194 #[should_panic = "test"]
-
195 // TODO: fix lint (https://github.com/rust-lang/rust-clippy/issues/7438)
-
196 #[allow(clippy::semicolon_if_nothing_returned)]
-
1971 async fn panic_await() {
-
1981 let task: Task<()> = Task::new(|_| async move {
-
1991 panic!("test");
-
2001 });
-
2011
-
2021 (&task).await.expect("should panic before unwrapping");
-
203 }
-
204
-
2051 #[tokio::test]
-
206 #[should_panic = "test"]
-
207 // TODO: fix lint (https://github.com/rust-lang/rust-clippy/issues/7438)
-
208 #[allow(clippy::semicolon_if_nothing_returned)]
-
2091 async fn panic_close() {
-
2101 let task = Task::new(|_| async move {
-
2111 panic!("test");
-
2121 });
-
2131
-
2141 task.close(())
-
2151 .await
-
2160 .expect("should panic before unwrapping");
-
217 }
-
218}
+
1951 async fn panic_await() {
+
1961 let task: Task<()> = Task::new(|_| async move {
+
1971 panic!("test");
+
1981 });
+
1991
+
2001 (&task).await.expect("should panic before unwrapping");
+
201 }
+
202
+
2031 #[tokio::test]
+
204 #[should_panic = "test"]
+
2051 async fn panic_close() {
+
2061 let task = Task::new(|_| async move {
+
2071 panic!("test");
+
2081 });
+
2091
+
2101 task.close(())
+
2111 .await
+
2120 .expect("should panic before unwrapping");
+
213 }
+
214}
diff --git a/coverage/src/x509/certificate.rs.html b/coverage/src/x509/certificate.rs.html index 940944e..1cf0799 100644 --- a/coverage/src/x509/certificate.rs.html +++ b/coverage/src/x509/certificate.rs.html @@ -9,7 +9,7 @@
Current view:top level - src/x509 - certificate.rs
-
Date:2023-07-07 10:30:44
+
Date:2023-08-25 14:31:32
HitTotalCoverage
@@ -31,19 +31,19 @@
10use crate::error;
12/// A public certificate. You can distribute it freely to peers.
-
13126#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
+
13142#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
14pub struct Certificate(Vec<u8>);
16impl AsRef<[u8]> for Certificate {
-
17114 fn as_ref(&self) -> &[u8] {
-
18114 &self.0
-
19114 }
+
17320 fn as_ref(&self) -> &[u8] {
+
18320 &self.0
+
19320 }
22impl From<Certificate> for Vec<u8> {
-
2313 fn from(certificate: Certificate) -> Self {
-
2413 certificate.0
-
2513 }
+
2321 fn from(certificate: Certificate) -> Self {
+
2421 certificate.0
+
2521 }
28impl TryFrom<Vec<u8>> for Certificate {
@@ -138,39 +138,39 @@
117 /// [`from_der`](Self::from_der), which isn't `unsafe`, but could fail
118 /// nonetheless when used on an [`Endpoint`](crate::Endpoint).
119 #[must_use]
-
12019 pub fn unchecked_from_der<C: Into<Vec<u8>>>(certificate: C) -> Self {
-
12119 Self(certificate.into())
-
12219 }
+
12027 pub fn unchecked_from_der<C: Into<Vec<u8>>>(certificate: C) -> Self {
+
12127 Self(certificate.into())
+
12227 }
124 /// # Panics
125 /// Panics if [`Certificate`] couldn't be parsed or contained no valid
126 /// domain names. This can't happen if [`Certificate`] is constructed
127 /// correctly from [`from_der`](Self::from_der).
128 #[must_use]
-
129112 pub fn domains(&self) -> Vec<String> {
-
130112 let (_, certificate) =
-
131112 X509Certificate::from_der(&self.0).expect("`Certificate` couldn't be parsed");
-
132112
-
133112 certificate
-
134112 .tbs_certificate
-
135112 .subject_alternative_name()
-
136112 .ok()
-
137112 .flatten()
-
138112 .map(|name| {
-
139112 name.value
-
140112 .general_names
-
141112 .iter()
-
142112 .filter_map(|name| {
-
143112 if let GeneralName::DNSName(name) = name {
-
144112 Some((*name).to_owned())
+
129318 pub fn domains(&self) -> Vec<String> {
+
130318 let (_, certificate) =
+
131318 X509Certificate::from_der(&self.0).expect("`Certificate` couldn't be parsed");
+
132318
+
133318 certificate
+
134318 .tbs_certificate
+
135318 .subject_alternative_name()
+
136318 .ok()
+
137318 .flatten()
+
138318 .map(|name| {
+
139318 name.value
+
140318 .general_names
+
141318 .iter()
+
142318 .filter_map(|name| {
+
143318 if let GeneralName::DNSName(name) = name {
+
144318 Some((*name).to_owned())
145 } else {
1460 None
147 }
-
148112 })
-
149112 .collect()
-
150112 })
-
151112 .expect("`Certificate` contained no valid domains")
-
152112 }
+
148318 })
+
149318 .collect()
+
150318 })
+
151318 .expect("`Certificate` contained no valid domains")
+
152318 }
154 /// Convert from a [`rustls`] type.
1551 pub(crate) fn from_rustls(certificate: rustls::Certificate) -> Self {
@@ -183,9 +183,9 @@
162 /// Panics if [`Certificate`] couldn't be parsed or contained no valid
163 /// domain names. This can't happen if [`Certificate`] is constructed
164 /// correctly from [`from_der`](Self::from_der).
-
16513 pub(crate) fn into_rustls(self) -> rustls::Certificate {
-
16613 rustls::Certificate(self.into())
-
16713 }
+
16521 pub(crate) fn into_rustls(self) -> rustls::Certificate {
+
16621 rustls::Certificate(self.into())
+
16721 }
1701#[test]
diff --git a/coverage/src/x509/certificate_chain.rs.html b/coverage/src/x509/certificate_chain.rs.html index d486652..fdced8b 100644 --- a/coverage/src/x509/certificate_chain.rs.html +++ b/coverage/src/x509/certificate_chain.rs.html @@ -9,12 +9,12 @@
Current view:top level - src/x509 - certificate_chain.rs
-
Date:2023-07-07 10:30:44
+
Date:2023-08-25 14:31:32
HitTotalCoverage
Lines194542.2 %
-
Functions154632.6 %
+
Functions195038.0 %
Branches000.0 %
@@ -28,7 +28,7 @@
7use crate::{error, Certificate};
9/// A public [`Certificate`] chain, used to prese
-
1025#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
+
1035#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
11pub struct CertificateChain(Vec<Certificate>);
13impl TryFrom<Vec<Certificate>> for CertificateChain {
@@ -75,9 +75,9 @@
54 /// the validation from [`from_certificates`](Self::from_certificates),
55 /// which isn't `unsafe`, but could fail nonetheless when used on an
56 /// [`Endpoint`](crate::Endpoint).
-
5718 pub fn unchecked_from_certificates<C: Into<Vec<Certificate>>>(certificates: C) -> Self {
-
5818 Self(certificates.into())
-
5918 }
+
5720 pub fn unchecked_from_certificates<C: Into<Vec<Certificate>>>(certificates: C) -> Self {
+
5820 Self(certificates.into())
+
5920 }
61 /// Returns the end-entity [`Certificate`].
62 ///
@@ -98,9 +98,9 @@
77 /// If the [`CertificateChain`] is invalid. This can't happen if validated
78 /// through [`from_certificates`](Self::from_certificates).
79 #[must_use]
-
80114 pub fn end_entity_certificate(&self) -> &Certificate {
-
81114 self.0.get(0).expect("`CertificateChain` is invalid")
-
82114 }
+
80320 pub fn end_entity_certificate(&self) -> &Certificate {
+
81320 self.0.get(0).expect("`CertificateChain` is invalid")
+
82320 }
84 /// Returns an iterator over the [`CertificateChain`].
850 pub fn iter(&self) -> Iter<'_, Certificate> {
@@ -114,9 +114,9 @@
930 }
95 /// Convert into a type [`rustls`] can consume.
-
9613 pub(crate) fn into_rustls(self) -> Vec<rustls::Certificate> {
-
9713 self.0.into_iter().map(Certificate::into_rustls).collect()
-
9813 }
+
9621 pub(crate) fn into_rustls(self) -> Vec<rustls::Certificate> {
+
9721 self.0.into_iter().map(Certificate::into_rustls).collect()
+
9821 }
100 /// Converts from a slice of rustls certificates with no validation.
1011 pub(crate) fn from_rustls(certs: &[rustls::Certificate]) -> Self {
diff --git a/coverage/src/x509/index.html b/coverage/src/x509/index.html index 84530ab..b795ba7 100644 --- a/coverage/src/x509/index.html +++ b/coverage/src/x509/index.html @@ -9,21 +9,21 @@
Current view:top level - src/x509
-
Date:2023-07-07 10:30:44
+
Date:2023-08-25 14:31:32
HitTotalCoverage
-
Lines23832273.9 %
-
Functions9320744.9 %
+
Lines24132574.2 %
+
Functions10421947.5 %
Branches000.0 %
FilenameLine CoverageFunctionsBranches
certificate.rs73.3%74 / 10157.4%27 / 470.0%0 / 0
-
certificate_chain.rs42.2%19 / 4532.6%15 / 460.0%0 / 0
-
mod.rs75.9%85 / 11236.4%24 / 660.0%0 / 0
-
private_key.rs93.8%60 / 6456.2%27 / 480.0%0 / 0
+
certificate_chain.rs42.2%19 / 4538.0%19 / 500.0%0 / 0
+
mod.rs75.9%85 / 11238.6%27 / 700.0%0 / 0
+
private_key.rs94.0%63 / 6759.6%31 / 520.0%0 / 0
diff --git a/coverage/src/x509/mod.rs.html b/coverage/src/x509/mod.rs.html index 43f35ae..237d94c 100644 --- a/coverage/src/x509/mod.rs.html +++ b/coverage/src/x509/mod.rs.html @@ -9,12 +9,12 @@
Current view:top level - src/x509 - mod.rs
-
Date:2023-07-07 10:30:44
+
Date:2023-08-25 14:31:32
HitTotalCoverage
Lines8511275.9 %
-
Functions246636.4 %
+
Functions277038.6 %
Branches000.0 %
@@ -23,7 +23,7 @@
3mod certificate;
4mod certificate_chain;
-
5pub mod private_key;
+
5pub(crate) mod private_key;
7pub use certificate::Certificate;
8pub use certificate_chain::CertificateChain;
@@ -34,7 +34,7 @@
13use crate::error;
15/// A key-pair, consisting of a [`CertificateChain`] and [`PrivateKey`].
-
1613#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd)]
+
1615#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd)]
17pub struct KeyPair {
18 /// The public [`CertificateChain`].
19 certificate_chain: CertificateChain,
@@ -56,25 +56,25 @@
35impl KeyPair {
36 /// Generate a self signed certificate.
37 #[cfg(feature = "rcgen")]
-
38 #[cfg_attr(doc, doc(cfg(feature = "rcgen")))]
-
3918 pub fn new_self_signed<S: Into<String>>(domain: S) -> Self {
-
4018 let key_pair = rcgen::generate_simple_self_signed([domain.into()])
-
4118 .expect("`rcgen` failed generating a self-signed certificate");
-
4218
-
4318 let certificate = Certificate::unchecked_from_der(
-
4418 key_pair
-
4518 .serialize_der()
-
4618 .expect("`rcgen` failed serializing a certificate"),
-
4718 );
-
4818 let certificate_chain = CertificateChain::unchecked_from_certificates([certificate]);
-
4918
-
5018 let private_key = PrivateKey::unchecked_from_der(key_pair.serialize_private_key_der());
-
5118
-
5218 Self {
-
5318 certificate_chain,
-
5418 private_key,
-
5518 }
-
5618 }
+
38 #[allow(clippy::missing_panics_doc)]
+
3920 pub fn new_self_signed<S: Into<String>>(domain: S) -> Self {
+
4020 let key_pair = rcgen::generate_simple_self_signed([domain.into()])
+
4120 .expect("`rcgen` failed generating a self-signed certificate");
+
4220
+
4320 let certificate = Certificate::unchecked_from_der(
+
4420 key_pair
+
4520 .serialize_der()
+
4620 .expect("`rcgen` failed serializing a certificate"),
+
4720 );
+
4820 let certificate_chain = CertificateChain::unchecked_from_certificates([certificate]);
+
4920
+
5020 let private_key = PrivateKey::unchecked_from_der(key_pair.serialize_private_key_der());
+
5120
+
5220 Self {
+
5320 certificate_chain,
+
5420 private_key,
+
5520 }
+
5620 }
58 /// Builds a new [`KeyPair`] from the given [`CertificateChain`] and
59 /// [`PrivateKey`]. Will validate if they pair up correctly.
@@ -113,9 +113,9 @@
93 /// Return the [`CertificateChain`] of this [`KeyPair`].
94 #[must_use]
-
9514 pub const fn certificate_chain(&self) -> &CertificateChain {
-
9614 &self.certificate_chain
-
9714 }
+
9522 pub const fn certificate_chain(&self) -> &CertificateChain {
+
9622 &self.certificate_chain
+
9722 }
99 /// Returns the end-entity [`Certificate`].
100 ///
@@ -123,118 +123,116 @@
102 /// If the [`KeyPair`] is invalid. This can't happen if validated
103 /// through [`from_parts`](Self::from_parts).
104 #[must_use]
-
105114 pub fn end_entity_certificate(&self) -> &Certificate {
-
106114 self.certificate_chain.end_entity_certificate()
-
107114 }
+
105320 pub fn end_entity_certificate(&self) -> &Certificate {
+
106320 self.certificate_chain.end_entity_certificate()
+
107320 }
109 /// Return the secret [`PrivateKey`] of this [`KeyPair`].
110 #[must_use]
-
11112 pub const fn private_key(&self) -> &PrivateKey {
-
11212 &self.private_key
-
11312 }
+
11120 pub const fn private_key(&self) -> &PrivateKey {
+
11220 &self.private_key
+
11320 }
115 /// Destructure [`KeyPair`] into it's owned parts.
116 #[must_use]
-
117 #[allow(clippy::missing_const_for_fn)]
-
1183 pub fn into_parts(self) -> (CertificateChain, PrivateKey) {
-
1193 (self.certificate_chain, self.private_key)
-
1203 }
- -
122 /// Destructure [`KeyPair`] into it's borrowed parts.
-
123 #[must_use]
-
1240 pub const fn parts(&self) -> (&CertificateChain, &PrivateKey) {
-
1250 (&self.certificate_chain, &self.private_key)
-
1260 }
- -
128 /// Convert into a type [`rustls`] can consume.
-
1291 pub(crate) fn into_rustls(self) -> CertifiedKey {
-
1301 CertifiedKey::new(
-
1311 self.certificate_chain.into_rustls(),
-
1321 self.private_key.into_rustls_signing_key(),
-
1331 )
-
1341 }
- - -
137/// Gives serialization access to [`KeyPair`].
-
138///
-
139/// # Security
-
140/// This is only dangerous in the sense that you aren't supposed to leak the
-
141/// [`PrivateKey`]. Make sure to use this carefully!
-
142pub trait Dangerous {
-
143 /// Serialize with [`serde`].
-
144 ///
-
145 /// # Security
-
146 /// This is only dangerous in the sense that you aren't supposed to leak the
-
147 /// [`PrivateKey`]. Make sure to use this carefully!
-
148 ///
-
149 /// # Errors
-
150 /// [`S::Error`](Serializer::Error) if serialization failed.
-
151 fn serialize<S: Serializer>(key_pair: &Self, serializer: S) -> Result<S::Ok, S::Error>;
- - -
154impl Dangerous for KeyPair {
-
1551 fn serialize<S: Serializer>(key_pair: &Self, serializer: S) -> Result<S::Ok, S::Error> {
-
1561 let mut serializer = serializer.serialize_struct("KeyPair", 2)?;
-
1571 serializer.serialize_field("certificate_chain", &key_pair.certificate_chain)?;
-
158 // we can't directly serialize `PrivateKey`, so instead we serialize it's
-
159 // innards - when deserializing we have to do this in revert and be careful not
-
160 // to directly deserialize `PrivateKey`
-
1611 serializer.serialize_field(
-
1621 "private_key",
-
1631 private_key::Dangerous::as_ref(&key_pair.private_key),
-
1641 )?;
-
1651 serializer.end()
-
1661 }
- - -
169/// Custom [`Deserializer`] for [`PrivateKey`] in [`KeyPair`].
-
170///
-
171/// We [`Serialize`](serde::Serialize) [`PrivateKey`] in [`KeyPair`] not
-
172/// directly, we have to correspondingly do the same when [`Deserialize`]ing.
-
173#[allow(single_use_lifetimes)]
-
1741fn deserialize_private_key<'de, D>(deserializer: D) -> Result<PrivateKey, D::Error>
-
1751where
-
1761 D: Deserializer<'de>,
-
1771{
-
1781 Ok(PrivateKey::unchecked_from_der(Vec::<u8>::deserialize(
-
1791 deserializer,
-
1801 )?))
-
1811}
- -
1831#[test]
-
1841fn serialize() -> anyhow::Result<()> {
-
1851 use bincode::{config::DefaultOptions, Options, Serializer};
+
1173 pub fn into_parts(self) -> (CertificateChain, PrivateKey) {
+
1183 (self.certificate_chain, self.private_key)
+
1193 }
+ +
121 /// Destructure [`KeyPair`] into it's borrowed parts.
+
122 #[must_use]
+
1230 pub const fn parts(&self) -> (&CertificateChain, &PrivateKey) {
+
1240 (&self.certificate_chain, &self.private_key)
+
1250 }
+ +
127 /// Convert into a type [`rustls`] can consume.
+
1281 pub(crate) fn into_rustls(self) -> CertifiedKey {
+
1291 CertifiedKey::new(
+
1301 self.certificate_chain.into_rustls(),
+
1311 self.private_key.into_rustls_signing_key(),
+
1321 )
+
1331 }
+ + +
136/// Gives serialization access to [`KeyPair`].
+
137///
+
138/// # Security
+
139/// This is only dangerous in the sense that you aren't supposed to leak the
+
140/// [`PrivateKey`]. Make sure to use this carefully!
+
141pub trait Dangerous {
+
142 /// Serialize with [`serde`].
+
143 ///
+
144 /// # Security
+
145 /// This is only dangerous in the sense that you aren't supposed to leak the
+
146 /// [`PrivateKey`]. Make sure to use this carefully!
+
147 ///
+
148 /// # Errors
+
149 /// [`S::Error`](Serializer::Error) if serialization failed.
+
150 fn serialize<S: Serializer>(key_pair: &Self, serializer: S) -> Result<S::Ok, S::Error>;
+ + +
153impl Dangerous for KeyPair {
+
1541 fn serialize<S: Serializer>(key_pair: &Self, serializer: S) -> Result<S::Ok, S::Error> {
+
1551 let mut serializer = serializer.serialize_struct("KeyPair", 2)?;
+
1561 serializer.serialize_field("certificate_chain", &key_pair.certificate_chain)?;
+
157 // we can't directly serialize `PrivateKey`, so instead we serialize it's
+
158 // innards - when deserializing we have to do this in revert and be careful not
+
159 // to directly deserialize `PrivateKey`
+
1601 serializer.serialize_field(
+
1611 "private_key",
+
1621 private_key::Dangerous::as_ref(&key_pair.private_key),
+
1631 )?;
+
1641 serializer.end()
+
1651 }
+ + +
168/// Custom [`Deserializer`] for [`PrivateKey`] in [`KeyPair`].
+
169///
+
170/// We [`Serialize`](serde::Serialize) [`PrivateKey`] in [`KeyPair`] not
+
171/// directly, we have to correspondingly do the same when [`Deserialize`]ing.
+
1721fn deserialize_private_key<'de, D>(deserializer: D) -> Result<PrivateKey, D::Error>
+
1731where
+
1741 D: Deserializer<'de>,
+
1751{
+
1761 Ok(PrivateKey::unchecked_from_der(Vec::<u8>::deserialize(
+
1771 deserializer,
+
1781 )?))
+
1791}
+ +
1811#[test]
+
1821fn serialize() -> anyhow::Result<()> {
+
1831 use bincode::{config::DefaultOptions, Options, Serializer};
+ +
1851 let key_pair = KeyPair::new_self_signed("test");
-
1871 let key_pair = KeyPair::new_self_signed("test");
+
1871 let mut buffer = Vec::new();
-
1891 let mut buffer = Vec::new();
- -
1911 Dangerous::serialize(
-
1921 &key_pair,
-
1931 &mut Serializer::new(
-
1941 &mut buffer,
-
1951 DefaultOptions::default()
-
1961 .with_fixint_encoding()
-
1971 .allow_trailing_bytes(),
-
1981 ),
-
1991 )?;
+
1891 Dangerous::serialize(
+
1901 &key_pair,
+
1911 &mut Serializer::new(
+
1921 &mut buffer,
+
1931 DefaultOptions::default()
+
1941 .with_fixint_encoding()
+
1951 .allow_trailing_bytes(),
+
1961 ),
+
1971 )?;
+ +
1991 assert_eq!(key_pair, bincode::deserialize(&buffer)?);
-
2011 assert_eq!(key_pair, bincode::deserialize(&buffer)?);
- -
2031 Ok(())
-
2041}
- -
2061#[test]
-
2071fn debug() {
-
2081 let key_pair = KeyPair::new_self_signed("test");
-
2091 assert_eq!(
-
2101 format!(
-
2111 "KeyPair {{ certificate_chain: {:?}, private_key: PrivateKey(\"[[redacted]]\") }}",
-
2121 key_pair.certificate_chain()
-
2131 ),
-
2141 format!("{:?}", key_pair)
-
2151 );
-
2161}
+
2011 Ok(())
+
2021}
+ +
2041#[test]
+
2051fn debug() {
+
2061 let key_pair = KeyPair::new_self_signed("test");
+
2071 assert_eq!(
+
2081 format!(
+
2091 "KeyPair {{ certificate_chain: {:?}, private_key: PrivateKey(\"[[redacted]]\") }}",
+
2101 key_pair.certificate_chain()
+
2111 ),
+
2121 format!("{:?}", key_pair)
+
2131 );
+
2141}
diff --git a/coverage/src/x509/private_key.rs.html b/coverage/src/x509/private_key.rs.html index 89afd9d..b4fa9a2 100644 --- a/coverage/src/x509/private_key.rs.html +++ b/coverage/src/x509/private_key.rs.html @@ -9,12 +9,12 @@
Current view:top level - src/x509 - private_key.rs
-
Date:2023-07-07 10:30:44
+
Date:2023-08-25 14:31:32
HitTotalCoverage
-
Lines606493.8 %
-
Functions274856.2 %
+
Lines636794.0 %
+
Functions315259.6 %
Branches000.0 %
@@ -36,164 +36,167 @@
15///
16/// # Safety
17/// Never give this to anybody.
-
1894#[derive(Clone, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Zeroize)]
+
18142#[derive(Clone, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Zeroize)]
19#[zeroize(drop)]
20pub struct PrivateKey(Option<Vec<u8>>);
21
22impl Debug for PrivateKey {
-
232 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-
242 f.debug_tuple("PrivateKey").field(&"[[redacted]]").finish()
-
252 }
-
26}
-
27
-
28impl TryFrom<Vec<u8>> for PrivateKey {
-
29 type Error = error::PrivateKey;
+
232 fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
+
242 formatter
+
252 .debug_tuple("PrivateKey")
+
262 .field(&"[[redacted]]")
+
272 .finish()
+
282 }
+
29}
30
-
310 fn try_from(certificate: Vec<u8>) -> Result<Self, Self::Error> {
-
320 Self::from_der(certificate)
-
330 }
-
34}
-
35
-
36impl PrivateKey {
-
37 /// Build [`PrivateKey`] from DER-format. This is not meant as a full
-
38 /// validation of a [`PrivateKey`], it just offers some sane protections.
-
39 ///
-
40 /// # Errors
-
41 /// [`error::PrivateKey`] if the certificate couldn't be parsed.
-
421 pub fn from_der<P: Into<Vec<u8>>>(private_key: P) -> Result<Self, error::PrivateKey> {
-
431 let private_key = rustls::PrivateKey(private_key.into());
-
44
-
451 if let Err(_error) = sign::any_supported_type(&private_key) {
-
460 Err(error::PrivateKey(private_key.0))
-
47 } else {
-
481 Ok(Self(Some(private_key.0)))
-
49 }
-
501 }
-
51
-
52 /// Build [`PrivateKey`] from DER-format. This skips the validation from
-
53 /// [`from_der`](Self::from_der), which isn't `unsafe`, but could fail
-
54 /// nonetheless when used on an [`Endpoint`](crate::Endpoint).
-
55 #[must_use]
-
5619 pub fn unchecked_from_der<P: Into<Vec<u8>>>(private_key: P) -> Self {
-
5719 Self(Some(private_key.into()))
-
5819 }
-
59
-
60 /// Convert into a rustls `PrivateKey`.
-
61 ///
-
62 /// # Panics
-
63 /// Panics if [`PrivateKey`] couldn't be parsed. This can't happen if
-
64 /// [`PrivateKey`] is constructed correctly from
-
65 /// [`from_der`](Self::from_der).
-
6613 pub(crate) fn into_rustls(self) -> rustls::PrivateKey {
-
6713 rustls::PrivateKey(Dangerous::into(self))
-
6813 }
-
69
-
70 /// Convert into a type [`rustls`] can use for signatures.
-
71 ///
-
72 /// # Panics
-
73 /// Panics if [`PrivateKey`] couldn't be parsed. This can't happen if
-
74 /// [`PrivateKey`] is constructed correctly from
-
75 /// [`from_der`](Self::from_der).
-
761 pub(crate) fn into_rustls_signing_key(self) -> Arc<dyn SigningKey> {
-
771 sign::any_supported_type(&self.into_rustls())
-
781 .expect("`PrivateKey` not compatible with `rustls`")
-
791 }
-
80}
-
81
-
82/// Gives read access to the [`PrivateKey`].
-
83///
-
84/// # Security
-
85/// This is only dangerous in the sense that you aren't supposed to leak the
-
86/// [`PrivateKey`]. Make sure to use this carefully!
-
87pub trait Dangerous {
-
88 /// Returns a [`&[u8]`](slice) to the [`PrivateKey`].
-
89 ///
-
90 /// # Security
-
91 /// This is only dangerous in the sense that you aren't supposed to leak the
-
92 /// [`PrivateKey`]. Make sure to use this carefully!
-
93 #[must_use]
-
94 fn as_ref(private_key: &Self) -> &[u8];
-
95
-
96 /// Returns a [`Vec<u8>`] to the [`PrivateKey`].
-
97 ///
-
98 /// # Security
-
99 /// This is only dangerous in the sense that you aren't supposed to leak the
-
100 /// [`PrivateKey`]. Make sure to use this carefully!
-
101 #[must_use]
-
102 fn into(private_key: Self) -> Vec<u8>;
-
103
-
104 /// Serialize with [`serde`].
-
105 ///
-
106 /// # Security
-
107 /// This is only dangerous in the sense that you aren't supposed to leak the
-
108 /// [`PrivateKey`]. Make sure to use this carefully!
-
109 ///
-
110 /// # Errors
-
111 /// [`S::Error`](Serializer::Error) if serialization failed.
-
112 fn serialize<S: Serializer>(private_key: &Self, serializer: S) -> Result<S::Ok, S::Error>;
-
113}
-
114
-
115impl Dangerous for PrivateKey {
-
1161 fn as_ref(private_key: &Self) -> &[u8] {
-
1171 private_key.0.as_deref().expect("value already dropped")
-
1181 }
-
119
-
12014 fn into(mut private_key: Self) -> Vec<u8> {
-
12114 private_key.0.take().expect("value already dropped")
-
12214 }
-
123
-
1241 fn serialize<S: Serializer>(private_key: &Self, serializer: S) -> Result<S::Ok, S::Error> {
-
1251 serializer.serialize_newtype_struct("PrivateKey", &private_key.0)
-
1261 }
-
127}
-
128
-
129#[cfg(test)]
-
130mod test {
-
131 use anyhow::Result;
-
132 use bincode::{config::DefaultOptions, Options, Serializer};
-
133
-
134 use super::*;
-
135 use crate::KeyPair;
+
31impl TryFrom<Vec<u8>> for PrivateKey {
+
32 type Error = error::PrivateKey;
+
33
+
340 fn try_from(certificate: Vec<u8>) -> Result<Self, Self::Error> {
+
350 Self::from_der(certificate)
+
360 }
+
37}
+
38
+
39impl PrivateKey {
+
40 /// Build [`PrivateKey`] from DER-format. This is not meant as a full
+
41 /// validation of a [`PrivateKey`], it just offers some sane protections.
+
42 ///
+
43 /// # Errors
+
44 /// [`error::PrivateKey`] if the certificate couldn't be parsed.
+
451 pub fn from_der<P: Into<Vec<u8>>>(private_key: P) -> Result<Self, error::PrivateKey> {
+
461 let private_key = rustls::PrivateKey(private_key.into());
+
47
+
481 if let Err(_error) = sign::any_supported_type(&private_key) {
+
490 Err(error::PrivateKey(private_key.0))
+
50 } else {
+
511 Ok(Self(Some(private_key.0)))
+
52 }
+
531 }
+
54
+
55 /// Build [`PrivateKey`] from DER-format. This skips the validation from
+
56 /// [`from_der`](Self::from_der), which isn't `unsafe`, but could fail
+
57 /// nonetheless when used on an [`Endpoint`](crate::Endpoint).
+
58 #[must_use]
+
5921 pub fn unchecked_from_der<P: Into<Vec<u8>>>(private_key: P) -> Self {
+
6021 Self(Some(private_key.into()))
+
6121 }
+
62
+
63 /// Convert into a rustls `PrivateKey`.
+
64 ///
+
65 /// # Panics
+
66 /// Panics if [`PrivateKey`] couldn't be parsed. This can't happen if
+
67 /// [`PrivateKey`] is constructed correctly from
+
68 /// [`from_der`](Self::from_der).
+
6921 pub(crate) fn into_rustls(self) -> rustls::PrivateKey {
+
7021 rustls::PrivateKey(Dangerous::into(self))
+
7121 }
+
72
+
73 /// Convert into a type [`rustls`] can use for signatures.
+
74 ///
+
75 /// # Panics
+
76 /// Panics if [`PrivateKey`] couldn't be parsed. This can't happen if
+
77 /// [`PrivateKey`] is constructed correctly from
+
78 /// [`from_der`](Self::from_der).
+
791 pub(crate) fn into_rustls_signing_key(self) -> Arc<dyn SigningKey> {
+
801 sign::any_supported_type(&self.into_rustls())
+
811 .expect("`PrivateKey` not compatible with `rustls`")
+
821 }
+
83}
+
84
+
85/// Gives read access to the [`PrivateKey`].
+
86///
+
87/// # Security
+
88/// This is only dangerous in the sense that you aren't supposed to leak the
+
89/// [`PrivateKey`]. Make sure to use this carefully!
+
90pub trait Dangerous {
+
91 /// Returns a [`&[u8]`](slice) to the [`PrivateKey`].
+
92 ///
+
93 /// # Security
+
94 /// This is only dangerous in the sense that you aren't supposed to leak the
+
95 /// [`PrivateKey`]. Make sure to use this carefully!
+
96 #[must_use]
+
97 fn as_ref(private_key: &Self) -> &[u8];
+
98
+
99 /// Returns a [`Vec<u8>`] to the [`PrivateKey`].
+
100 ///
+
101 /// # Security
+
102 /// This is only dangerous in the sense that you aren't supposed to leak the
+
103 /// [`PrivateKey`]. Make sure to use this carefully!
+
104 #[must_use]
+
105 fn into(private_key: Self) -> Vec<u8>;
+
106
+
107 /// Serialize with [`serde`].
+
108 ///
+
109 /// # Security
+
110 /// This is only dangerous in the sense that you aren't supposed to leak the
+
111 /// [`PrivateKey`]. Make sure to use this carefully!
+
112 ///
+
113 /// # Errors
+
114 /// [`S::Error`](Serializer::Error) if serialization failed.
+
115 fn serialize<S: Serializer>(private_key: &Self, serializer: S) -> Result<S::Ok, S::Error>;
+
116}
+
117
+
118impl Dangerous for PrivateKey {
+
1191 fn as_ref(private_key: &Self) -> &[u8] {
+
1201 private_key.0.as_deref().expect("value already dropped")
+
1211 }
+
122
+
12322 fn into(mut private_key: Self) -> Vec<u8> {
+
12422 private_key.0.take().expect("value already dropped")
+
12522 }
+
126
+
1271 fn serialize<S: Serializer>(private_key: &Self, serializer: S) -> Result<S::Ok, S::Error> {
+
1281 serializer.serialize_newtype_struct("PrivateKey", &private_key.0)
+
1291 }
+
130}
+
131
+
132#[cfg(test)]
+
133mod test {
+
134 use anyhow::Result;
+
135 use bincode::{config::DefaultOptions, Options, Serializer};
136
-
1371 #[test]
-
1381 fn validate() -> Result<()> {
-
1391 let (_, private_key) = KeyPair::new_self_signed("test").into_parts();
-
1401
-
1411 assert_eq!(
-
1421 private_key,
-
1431 PrivateKey::from_der(Dangerous::into(private_key.clone()))?,
-
144 );
-
145
-
1461 Ok(())
-
1471 }
+
137 use super::*;
+
138 use crate::KeyPair;
+
139
+
1401 #[test]
+
1411 fn validate() -> Result<()> {
+
1421 let (_, private_key) = KeyPair::new_self_signed("test").into_parts();
+
1431
+
1441 assert_eq!(
+
1451 private_key,
+
1461 PrivateKey::from_der(Dangerous::into(private_key.clone()))?,
+
147 );
148
-
1491 #[test]
-
1501 fn serialize() -> Result<()> {
-
1511 let (_, private_key) = KeyPair::new_self_signed("test").into_parts();
-
1521
-
1531 let mut buffer = Vec::new();
-
1541
-
1551 Dangerous::serialize(
-
1561 &private_key,
-
1571 &mut Serializer::new(
-
1581 &mut buffer,
-
1591 DefaultOptions::default()
-
1601 .with_fixint_encoding()
-
1611 .allow_trailing_bytes(),
-
1621 ),
-
1631 )?;
-
164
-
1651 assert_eq!(private_key, bincode::deserialize(&buffer)?);
-
166
-
1671 Ok(())
-
1681 }
+
1491 Ok(())
+
1501 }
+
151
+
1521 #[test]
+
1531 fn serialize() -> Result<()> {
+
1541 let (_, private_key) = KeyPair::new_self_signed("test").into_parts();
+
1551
+
1561 let mut buffer = Vec::new();
+
1571
+
1581 Dangerous::serialize(
+
1591 &private_key,
+
1601 &mut Serializer::new(
+
1611 &mut buffer,
+
1621 DefaultOptions::default()
+
1631 .with_fixint_encoding()
+
1641 .allow_trailing_bytes(),
+
1651 ),
+
1661 )?;
+
167
+
1681 assert_eq!(private_key, bincode::deserialize(&buffer)?);
169
-
1701 #[test]
-
1711 fn debug() {
-
1721 let (_, private_key) = KeyPair::new_self_signed("test").into_parts();
-
1731 assert_eq!("PrivateKey(\"[[redacted]]\")", format!("{private_key:?}"));
-
1741 }
-
175}
+
1701 Ok(())
+
1711 }
+
172
+
1731 #[test]
+
1741 fn debug() {
+
1751 let (_, private_key) = KeyPair::new_self_signed("test").into_parts();
+
1761 assert_eq!("PrivateKey(\"[[redacted]]\")", format!("{private_key:?}"));
+
1771 }
+
178}
diff --git a/coverage/target/debug/build/oid-registry-94bd6a17a18236d5/out/index.html b/coverage/target/debug/build/oid-registry-94bd6a17a18236d5/out/index.html index 4952012..28f70f5 100644 --- a/coverage/target/debug/build/oid-registry-94bd6a17a18236d5/out/index.html +++ b/coverage/target/debug/build/oid-registry-94bd6a17a18236d5/out/index.html @@ -9,7 +9,7 @@
Current view:top level - target/debug/build/oid-registry-94bd6a17a18236d5/out
-
Date:2023-07-07 10:30:44
+
Date:2023-08-25 14:31:32
HitTotalCoverage
diff --git a/coverage/target/debug/build/oid-registry-94bd6a17a18236d5/out/oid_db.rs.html b/coverage/target/debug/build/oid-registry-94bd6a17a18236d5/out/oid_db.rs.html index 62b9f0d..d2f4b48 100644 --- a/coverage/target/debug/build/oid-registry-94bd6a17a18236d5/out/oid_db.rs.html +++ b/coverage/target/debug/build/oid-registry-94bd6a17a18236d5/out/oid_db.rs.html @@ -9,7 +9,7 @@
-
Date:2023-07-07 10:30:44
+
Date:2023-08-25 14:31:32
HitTotalCoverage