forked from solana-labs/solana
-
Notifications
You must be signed in to change notification settings - Fork 381
/
Copy pathquic_networking.rs
67 lines (55 loc) · 2.14 KB
/
quic_networking.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
//! Utility code to handle quic networking.
use {
quinn::{
crypto::rustls::QuicClientConfig, ClientConfig, Connection, Endpoint, IdleTimeout,
TransportConfig,
},
solana_quic_definitions::{QUIC_KEEP_ALIVE, QUIC_MAX_TIMEOUT, QUIC_SEND_FAIRNESS},
solana_streamer::nonblocking::quic::ALPN_TPU_PROTOCOL_ID,
solana_tls_utils::tls_client_config_builder,
std::{net::SocketAddr, sync::Arc},
};
pub mod error;
pub use {
error::{IoErrorWithPartialEq, QuicError},
solana_tls_utils::QuicClientCertificate,
};
pub(crate) fn create_client_config(client_certificate: QuicClientCertificate) -> ClientConfig {
// adapted from QuicLazyInitializedEndpoint::create_endpoint
let mut crypto = tls_client_config_builder()
.with_client_auth_cert(
vec![client_certificate.certificate.clone()],
client_certificate.key.clone_key(),
)
.expect("Failed to set QUIC client certificates");
crypto.enable_early_data = true;
crypto.alpn_protocols = vec![ALPN_TPU_PROTOCOL_ID.to_vec()];
let transport_config = {
let mut res = TransportConfig::default();
let timeout = IdleTimeout::try_from(QUIC_MAX_TIMEOUT).unwrap();
res.max_idle_timeout(Some(timeout));
res.keep_alive_interval(Some(QUIC_KEEP_ALIVE));
res.send_fairness(QUIC_SEND_FAIRNESS);
res
};
let mut config = ClientConfig::new(Arc::new(QuicClientConfig::try_from(crypto).unwrap()));
config.transport_config(Arc::new(transport_config));
config
}
pub(crate) fn create_client_endpoint(
bind_addr: SocketAddr,
client_config: ClientConfig,
) -> Result<Endpoint, QuicError> {
let mut endpoint = Endpoint::client(bind_addr).map_err(IoErrorWithPartialEq::from)?;
endpoint.set_default_client_config(client_config);
Ok(endpoint)
}
pub(crate) async fn send_data_over_stream(
connection: &Connection,
data: &[u8],
) -> Result<(), QuicError> {
let mut send_stream = connection.open_uni().await?;
send_stream.write_all(data).await.map_err(QuicError::from)?;
// Stream will be finished when dropped. Finishing here explicitly is a noop.
Ok(())
}