Skip to content

Commit eb42788

Browse files
authored
QUIC: generate unique server_name for client connections (#7260)
generate unique server_name for QUIC connections
1 parent 9dad705 commit eb42788

File tree

5 files changed

+38
-16
lines changed

5 files changed

+38
-16
lines changed

core/src/repair/quic_endpoint.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ use {
1818
solana_pubkey::Pubkey,
1919
solana_runtime::bank_forks::BankForks,
2020
solana_tls_utils::{
21-
new_dummy_x509_certificate, tls_client_config_builder, tls_server_config_builder,
21+
new_dummy_x509_certificate, socket_addr_to_quic_server_name, tls_client_config_builder,
22+
tls_server_config_builder,
2223
},
2324
std::{
2425
cmp::Reverse,
@@ -73,7 +74,6 @@ const CLIENT_CHANNEL_BUFFER: usize = 1 << 14;
7374
const ROUTER_CHANNEL_BUFFER: usize = 64;
7475
const CONNECTION_CACHE_CAPACITY: usize = 3072;
7576
const ALPN_REPAIR_PROTOCOL_ID: &[u8] = b"solana-repair";
76-
const CONNECT_SERVER_NAME: &str = "solana-repair";
7777

7878
// Transport config.
7979
const DATAGRAM_RECEIVE_BUFFER_SIZE: usize = 256 * 1024 * 1024;
@@ -672,9 +672,8 @@ async fn make_connection<T>(
672672
where
673673
T: 'static + From<(Pubkey, SocketAddr, Bytes)> + Send,
674674
{
675-
let connection = endpoint
676-
.connect(remote_address, CONNECT_SERVER_NAME)?
677-
.await?;
675+
let server_name = socket_addr_to_quic_server_name(remote_address);
676+
let connection = endpoint.connect(remote_address, &server_name)?.await?;
678677
handle_connection(
679678
endpoint,
680679
connection.remote_address(),

quic-client/src/nonblocking/quic_client.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ use {
2727
solana_rpc_client_api::client_error::ErrorKind as ClientErrorKind,
2828
solana_streamer::nonblocking::quic::ALPN_TPU_PROTOCOL_ID,
2929
solana_tls_utils::{
30-
new_dummy_x509_certificate, tls_client_config_builder, QuicClientCertificate,
30+
new_dummy_x509_certificate, socket_addr_to_quic_server_name, tls_client_config_builder,
31+
QuicClientCertificate,
3132
},
3233
solana_transaction_error::TransportResult,
3334
std::{
@@ -154,8 +155,8 @@ impl QuicNewConnection {
154155
) -> Result<Self, QuicError> {
155156
let mut make_connection_measure = Measure::start("make_connection_measure");
156157
let endpoint = endpoint.get_endpoint().await;
157-
158-
let connecting = endpoint.connect(addr, "connect")?;
158+
let server_name = socket_addr_to_quic_server_name(addr);
159+
let connecting = endpoint.connect(addr, &server_name)?;
159160
stats.total_connections.fetch_add(1, Ordering::Relaxed);
160161
if let Ok(connecting_result) = timeout(QUIC_CONNECTION_HANDSHAKE_TIMEOUT, connecting).await
161162
{
@@ -190,7 +191,8 @@ impl QuicNewConnection {
190191
addr: SocketAddr,
191192
stats: &ClientStats,
192193
) -> Result<Arc<Connection>, QuicError> {
193-
let connecting = self.endpoint.connect(addr, "connect")?;
194+
let server_name = socket_addr_to_quic_server_name(addr);
195+
let connecting = self.endpoint.connect(addr, &server_name)?;
194196
stats.total_connections.fetch_add(1, Ordering::Relaxed);
195197
let connection = match connecting.into_0rtt() {
196198
Ok((connection, zero_rtt)) => {

tls-utils/src/tls_certificates.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use {
22
solana_keypair::Keypair,
33
solana_pubkey::Pubkey,
44
solana_signer::Signer,
5+
std::net::SocketAddr,
56
x509_parser::{prelude::*, public_key::PublicKey},
67
};
78

@@ -126,9 +127,28 @@ pub fn get_pubkey_from_tls_certificate(
126127
}
127128
}
128129

130+
/// Translate a SocketAddr into a valid SNI for the purposes of QUIC connection
131+
///
132+
/// We do not actually check if the server holds a cert for this server_name
133+
/// since Solana does not rely on DNS names, but we need to provide a unique
134+
/// one to ensure that we present correct QUIC tokens to the correct server.
135+
pub fn socket_addr_to_quic_server_name(peer: SocketAddr) -> String {
136+
format!("{}.{}.sol", peer.ip(), peer.port())
137+
}
138+
129139
#[cfg(test)]
130140
mod tests {
131-
use {super::*, solana_signer::Signer};
141+
use {
142+
super::*,
143+
solana_signer::Signer,
144+
std::net::{IpAddr, Ipv4Addr},
145+
};
146+
147+
#[test]
148+
fn test_socket_addr_to_quic_server_name() {
149+
let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(1, 2, 3, 4)), 8004);
150+
assert_eq!(socket_addr_to_quic_server_name(socket), "1.2.3.4.8004.sol");
151+
}
132152

133153
#[test]
134154
fn test_generate_tls_certificate() {

tpu-client-next/src/connection_worker.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use {
1212
solana_clock::{DEFAULT_MS_PER_SLOT, MAX_PROCESSING_AGE, NUM_CONSECUTIVE_LEADER_SLOTS},
1313
solana_measure::measure::Measure,
1414
solana_time_utils::timestamp,
15+
solana_tls_utils::socket_addr_to_quic_server_name,
1516
std::{
1617
net::SocketAddr,
1718
sync::{atomic::Ordering, Arc},
@@ -209,7 +210,8 @@ impl ConnectionWorker {
209210
/// If an error occurs, the state may transition to `Retry` or `Closing`,
210211
/// depending on the nature of the error.
211212
async fn create_connection(&mut self, retries_attempt: usize) {
212-
let connecting = self.endpoint.connect(self.peer, "connect");
213+
let server_name = socket_addr_to_quic_server_name(self.peer);
214+
let connecting = self.endpoint.connect(self.peer, &server_name);
213215
match connecting {
214216
Ok(connecting) => {
215217
let mut measure_connection = Measure::start("establish connection");

turbine/src/quic_endpoint.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ use {
1717
solana_pubkey::Pubkey,
1818
solana_runtime::bank_forks::BankForks,
1919
solana_tls_utils::{
20-
new_dummy_x509_certificate, tls_client_config_builder, tls_server_config_builder,
20+
new_dummy_x509_certificate, socket_addr_to_quic_server_name, tls_client_config_builder,
21+
tls_server_config_builder,
2122
},
2223
std::{
2324
cmp::Reverse,
@@ -44,7 +45,6 @@ const CLIENT_CHANNEL_BUFFER: usize = 1 << 14;
4445
const ROUTER_CHANNEL_BUFFER: usize = 64;
4546
const CONNECTION_CACHE_CAPACITY: usize = 3072;
4647
const ALPN_TURBINE_PROTOCOL_ID: &[u8] = b"solana-turbine";
47-
const CONNECT_SERVER_NAME: &str = "solana-turbine";
4848

4949
// Transport config.
5050
const DATAGRAM_RECEIVE_BUFFER_SIZE: usize = 256 * 1024 * 1024;
@@ -504,9 +504,8 @@ async fn make_connection(
504504
cache: Arc<Mutex<HashMap<Pubkey, Connection>>>,
505505
stats: Arc<TurbineQuicStats>,
506506
) -> Result<(), Error> {
507-
let connection = endpoint
508-
.connect(remote_address, CONNECT_SERVER_NAME)?
509-
.await?;
507+
let server_name = socket_addr_to_quic_server_name(remote_address);
508+
let connection = endpoint.connect(remote_address, &server_name)?.await?;
510509
handle_connection(
511510
endpoint,
512511
connection.remote_address(),

0 commit comments

Comments
 (0)