passes through concrete QUIC connection errors up the call stack (#31168)
This commit is contained in:
parent
602297e29f
commit
34da001cda
|
@ -5449,6 +5449,7 @@ dependencies = [
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
"rand_chacha 0.2.2",
|
"rand_chacha 0.2.2",
|
||||||
"rayon",
|
"rayon",
|
||||||
|
"rcgen",
|
||||||
"solana-logger 1.16.0",
|
"solana-logger 1.16.0",
|
||||||
"solana-measure",
|
"solana-measure",
|
||||||
"solana-metrics",
|
"solana-metrics",
|
||||||
|
@ -6430,6 +6431,7 @@ dependencies = [
|
||||||
"quinn",
|
"quinn",
|
||||||
"quinn-proto",
|
"quinn-proto",
|
||||||
"quinn-udp",
|
"quinn-udp",
|
||||||
|
"rcgen",
|
||||||
"rustls 0.20.6",
|
"rustls 0.20.6",
|
||||||
"solana-connection-cache",
|
"solana-connection-cache",
|
||||||
"solana-logger 1.16.0",
|
"solana-logger 1.16.0",
|
||||||
|
|
|
@ -18,6 +18,7 @@ indicatif = { workspace = true, optional = true }
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
rand = { workspace = true }
|
rand = { workspace = true }
|
||||||
rayon = { workspace = true }
|
rayon = { workspace = true }
|
||||||
|
rcgen = { workspace = true }
|
||||||
solana-measure = { workspace = true }
|
solana-measure = { workspace = true }
|
||||||
solana-metrics = { workspace = true }
|
solana-metrics = { workspace = true }
|
||||||
solana-sdk = { workspace = true }
|
solana-sdk = { workspace = true }
|
||||||
|
|
|
@ -287,7 +287,7 @@ pub enum ConnectionPoolError {
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum ClientError {
|
pub enum ClientError {
|
||||||
#[error("Certificate error: {0}")]
|
#[error("Certificate error: {0}")]
|
||||||
CertificateError(String),
|
CertificateError(#[from] rcgen::RcgenError),
|
||||||
|
|
||||||
#[error("IO error: {0:?}")]
|
#[error("IO error: {0:?}")]
|
||||||
IoError(#[from] std::io::Error),
|
IoError(#[from] std::io::Error),
|
||||||
|
|
|
@ -4725,6 +4725,7 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
"rayon",
|
"rayon",
|
||||||
|
"rcgen",
|
||||||
"solana-measure",
|
"solana-measure",
|
||||||
"solana-metrics",
|
"solana-metrics",
|
||||||
"solana-sdk 1.16.0",
|
"solana-sdk 1.16.0",
|
||||||
|
@ -5392,6 +5393,7 @@ dependencies = [
|
||||||
"quinn",
|
"quinn",
|
||||||
"quinn-proto",
|
"quinn-proto",
|
||||||
"quinn-udp",
|
"quinn-udp",
|
||||||
|
"rcgen",
|
||||||
"rustls 0.20.6",
|
"rustls 0.20.6",
|
||||||
"solana-connection-cache",
|
"solana-connection-cache",
|
||||||
"solana-measure",
|
"solana-measure",
|
||||||
|
|
|
@ -19,6 +19,7 @@ log = { workspace = true }
|
||||||
quinn = { workspace = true }
|
quinn = { workspace = true }
|
||||||
quinn-proto = { workspace = true }
|
quinn-proto = { workspace = true }
|
||||||
quinn-udp = { workspace = true }
|
quinn-udp = { workspace = true }
|
||||||
|
rcgen = { workspace = true }
|
||||||
rustls = { workspace = true, features = ["dangerous_configuration"] }
|
rustls = { workspace = true, features = ["dangerous_configuration"] }
|
||||||
solana-connection-cache = { workspace = true }
|
solana-connection-cache = { workspace = true }
|
||||||
solana-measure = { workspace = true }
|
solana-measure = { workspace = true }
|
||||||
|
|
|
@ -15,6 +15,7 @@ use {
|
||||||
quic_client::QuicClientConnection as BlockingQuicClientConnection,
|
quic_client::QuicClientConnection as BlockingQuicClientConnection,
|
||||||
},
|
},
|
||||||
quinn::Endpoint,
|
quinn::Endpoint,
|
||||||
|
rcgen::RcgenError,
|
||||||
solana_connection_cache::{
|
solana_connection_cache::{
|
||||||
connection_cache::{
|
connection_cache::{
|
||||||
BaseClientConnection, ClientError, ConnectionManager, ConnectionPool,
|
BaseClientConnection, ClientError, ConnectionManager, ConnectionPool,
|
||||||
|
@ -29,7 +30,6 @@ use {
|
||||||
tls_certificates::new_self_signed_tls_certificate,
|
tls_certificates::new_self_signed_tls_certificate,
|
||||||
},
|
},
|
||||||
std::{
|
std::{
|
||||||
error::Error,
|
|
||||||
net::{IpAddr, Ipv4Addr, SocketAddr},
|
net::{IpAddr, Ipv4Addr, SocketAddr},
|
||||||
sync::{Arc, RwLock},
|
sync::{Arc, RwLock},
|
||||||
},
|
},
|
||||||
|
@ -39,7 +39,7 @@ use {
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum QuicClientError {
|
pub enum QuicClientError {
|
||||||
#[error("Certificate error: {0}")]
|
#[error("Certificate error: {0}")]
|
||||||
CertificateError(String),
|
CertificateError(#[from] RcgenError),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct QuicPool {
|
pub struct QuicPool {
|
||||||
|
@ -92,8 +92,7 @@ pub struct QuicConfig {
|
||||||
impl NewConnectionConfig for QuicConfig {
|
impl NewConnectionConfig for QuicConfig {
|
||||||
fn new() -> Result<Self, ClientError> {
|
fn new() -> Result<Self, ClientError> {
|
||||||
let (cert, priv_key) =
|
let (cert, priv_key) =
|
||||||
new_self_signed_tls_certificate(&Keypair::new(), IpAddr::V4(Ipv4Addr::UNSPECIFIED))
|
new_self_signed_tls_certificate(&Keypair::new(), IpAddr::V4(Ipv4Addr::UNSPECIFIED))?;
|
||||||
.map_err(|err| ClientError::CertificateError(err.to_string()))?;
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
client_certificate: Arc::new(QuicClientCertificate {
|
client_certificate: Arc::new(QuicClientCertificate {
|
||||||
certificate: cert,
|
certificate: cert,
|
||||||
|
@ -136,7 +135,7 @@ impl QuicConfig {
|
||||||
&mut self,
|
&mut self,
|
||||||
keypair: &Keypair,
|
keypair: &Keypair,
|
||||||
ipaddr: IpAddr,
|
ipaddr: IpAddr,
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), RcgenError> {
|
||||||
let (cert, priv_key) = new_self_signed_tls_certificate(keypair, ipaddr)?;
|
let (cert, priv_key) = new_self_signed_tls_certificate(keypair, ipaddr)?;
|
||||||
self.client_certificate = Arc::new(QuicClientCertificate {
|
self.client_certificate = Arc::new(QuicClientCertificate {
|
||||||
certificate: cert,
|
certificate: cert,
|
||||||
|
|
|
@ -101,11 +101,8 @@ pub fn spawn_server(
|
||||||
info!("Start quic server on {:?}", sock);
|
info!("Start quic server on {:?}", sock);
|
||||||
let (config, _cert) = configure_server(keypair, gossip_host)?;
|
let (config, _cert) = configure_server(keypair, gossip_host)?;
|
||||||
|
|
||||||
let endpoint = {
|
let endpoint = Endpoint::new(EndpointConfig::default(), Some(config), sock, TokioRuntime)
|
||||||
Endpoint::new(EndpointConfig::default(), Some(config), sock, TokioRuntime)
|
.map_err(QuicServerError::EndpointFailed)?;
|
||||||
.map_err(|_e| QuicServerError::EndpointFailed)?
|
|
||||||
};
|
|
||||||
|
|
||||||
let handle = tokio::spawn(run_server(
|
let handle = tokio::spawn(run_server(
|
||||||
endpoint.clone(),
|
endpoint.clone(),
|
||||||
packet_sender,
|
packet_sender,
|
||||||
|
|
|
@ -57,8 +57,7 @@ pub(crate) fn configure_server(
|
||||||
identity_keypair: &Keypair,
|
identity_keypair: &Keypair,
|
||||||
gossip_host: IpAddr,
|
gossip_host: IpAddr,
|
||||||
) -> Result<(ServerConfig, String), QuicServerError> {
|
) -> Result<(ServerConfig, String), QuicServerError> {
|
||||||
let (cert, priv_key) = new_self_signed_tls_certificate(identity_keypair, gossip_host)
|
let (cert, priv_key) = new_self_signed_tls_certificate(identity_keypair, gossip_host)?;
|
||||||
.map_err(|_e| QuicServerError::ConfigureFailed)?;
|
|
||||||
let cert_chain_pem_parts = vec![Pem {
|
let cert_chain_pem_parts = vec![Pem {
|
||||||
tag: "CERTIFICATE".to_string(),
|
tag: "CERTIFICATE".to_string(),
|
||||||
contents: cert.0.clone(),
|
contents: cert.0.clone(),
|
||||||
|
@ -68,8 +67,7 @@ pub(crate) fn configure_server(
|
||||||
let mut server_tls_config = rustls::ServerConfig::builder()
|
let mut server_tls_config = rustls::ServerConfig::builder()
|
||||||
.with_safe_defaults()
|
.with_safe_defaults()
|
||||||
.with_client_cert_verifier(SkipClientVerification::new())
|
.with_client_cert_verifier(SkipClientVerification::new())
|
||||||
.with_single_cert(vec![cert], priv_key)
|
.with_single_cert(vec![cert], priv_key)?;
|
||||||
.map_err(|_e| QuicServerError::ConfigureFailed)?;
|
|
||||||
server_tls_config.alpn_protocols = vec![ALPN_TPU_PROTOCOL_ID.to_vec()];
|
server_tls_config.alpn_protocols = vec![ALPN_TPU_PROTOCOL_ID.to_vec()];
|
||||||
|
|
||||||
let mut server_config = ServerConfig::with_crypto(Arc::new(server_tls_config));
|
let mut server_config = ServerConfig::with_crypto(Arc::new(server_tls_config));
|
||||||
|
@ -106,11 +104,12 @@ fn rt() -> Runtime {
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
pub enum QuicServerError {
|
pub enum QuicServerError {
|
||||||
#[error("Server configure failed")]
|
#[error("Endpoint creation failed: {0}")]
|
||||||
ConfigureFailed,
|
EndpointFailed(std::io::Error),
|
||||||
|
#[error("Certificate error: {0}")]
|
||||||
#[error("Endpoint creation failed")]
|
CertificateError(#[from] rcgen::RcgenError),
|
||||||
EndpointFailed,
|
#[error("TLS error: {0}")]
|
||||||
|
TlsError(#[from] rustls::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
use {
|
use {
|
||||||
pkcs8::{der::Document, AlgorithmIdentifier, ObjectIdentifier},
|
pkcs8::{der::Document, AlgorithmIdentifier, ObjectIdentifier},
|
||||||
rcgen::{CertificateParams, DistinguishedName, DnType, SanType},
|
rcgen::{CertificateParams, DistinguishedName, DnType, RcgenError, SanType},
|
||||||
solana_sdk::{pubkey::Pubkey, signature::Keypair},
|
solana_sdk::{pubkey::Pubkey, signature::Keypair},
|
||||||
std::{error::Error, net::IpAddr},
|
std::net::IpAddr,
|
||||||
x509_parser::{prelude::*, public_key::PublicKey},
|
x509_parser::{prelude::*, public_key::PublicKey},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn new_self_signed_tls_certificate(
|
pub fn new_self_signed_tls_certificate(
|
||||||
keypair: &Keypair,
|
keypair: &Keypair,
|
||||||
san: IpAddr,
|
san: IpAddr,
|
||||||
) -> Result<(rustls::Certificate, rustls::PrivateKey), Box<dyn Error>> {
|
) -> Result<(rustls::Certificate, rustls::PrivateKey), RcgenError> {
|
||||||
// TODO(terorie): Is it safe to sign the TLS cert with the identity private key?
|
// TODO(terorie): Is it safe to sign the TLS cert with the identity private key?
|
||||||
|
|
||||||
// Unfortunately, rcgen does not accept a "raw" Ed25519 key.
|
// Unfortunately, rcgen does not accept a "raw" Ed25519 key.
|
||||||
|
|
Loading…
Reference in New Issue