vmm: accept migration connections over TLS

Extend ReceiveListener with a TLS-backed listener variant for migration
receivers.

Store the TCP listener together with the server TLS configuration, wrap
accepted sockets in TlsStream::new_server(), and preserver the existing
listener cloning and fd polling behavior so receive-side migration code
can treat TLS listeners like the existing TCP and UNIX cases.

On-behalf-of: SAP sebastian.eydam@sap.com
Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
This commit is contained in:
Sebastian Eydam
2026-04-14 13:56:18 +02:00
committed by Rob Bradford
parent f3623e6403
commit 0ec2ae376b
2 changed files with 21 additions and 2 deletions

View File

@@ -273,7 +273,7 @@ impl WriteVolatile for TlsStream {
/// Carries a TLS server configuration. Intended to be turned into a [`TlsStream`] /// Carries a TLS server configuration. Intended to be turned into a [`TlsStream`]
/// when paired with a [`TcpStream`]. /// when paired with a [`TcpStream`].
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct TlsServerConfig { pub struct TlsServerConfig {
/// This config is shared between all server connections. /// This config is shared between all server connections.
config: Arc<ServerConfig>, config: Arc<ServerConfig>,

View File

@@ -26,7 +26,7 @@ use vm_memory::{
VolatileSlice, WriteVolatile, VolatileSlice, WriteVolatile,
}; };
use vm_migration::protocol::{Command, MemoryRangeTable, Request, Response}; use vm_migration::protocol::{Command, MemoryRangeTable, Request, Response};
use vm_migration::tls::TlsStream; use vm_migration::tls::{TlsServerConfig, TlsStream};
use vm_migration::{MigratableError, Snapshot}; use vm_migration::{MigratableError, Snapshot};
use vmm_sys_util::eventfd::EventFd; use vmm_sys_util::eventfd::EventFd;
@@ -42,6 +42,7 @@ pub(crate) const MAX_MIGRATION_CONNECTIONS: u32 = 128;
pub(crate) enum ReceiveListener { pub(crate) enum ReceiveListener {
Tcp(TcpListener), Tcp(TcpListener),
Unix(UnixListener), Unix(UnixListener),
Tls(TcpListener, TlsServerConfig),
} }
impl ReceiveListener { impl ReceiveListener {
@@ -58,6 +59,18 @@ impl ReceiveListener {
.map(|(socket, _)| SocketStream::Unix(socket)) .map(|(socket, _)| SocketStream::Unix(socket))
.context("Failed to accept Unix migration connection") .context("Failed to accept Unix migration connection")
.map_err(MigratableError::MigrateReceive), .map_err(MigratableError::MigrateReceive),
ReceiveListener::Tls(listener, config) => {
let (socket, _) = listener
.accept()
.context("Failed to accept TCP connection")
.map_err(MigratableError::MigrateReceive)?;
TlsStream::new_server(socket, config)
.map(Box::new)
.map(SocketStream::Tls)
.context("Failed to accept TLS migration connection")
.map_err(MigratableError::MigrateReceive)
}
} }
} }
@@ -91,6 +104,11 @@ impl ReceiveListener {
.map(ReceiveListener::Unix) .map(ReceiveListener::Unix)
.context("Failed to clone Unix listener") .context("Failed to clone Unix listener")
.map_err(MigratableError::MigrateReceive), .map_err(MigratableError::MigrateReceive),
ReceiveListener::Tls(listener, config) => listener
.try_clone()
.map(|listener| ReceiveListener::Tls(listener, config.clone()))
.context("Failed to clone TLS listener")
.map_err(MigratableError::MigrateReceive),
} }
} }
} }
@@ -100,6 +118,7 @@ impl AsFd for ReceiveListener {
match self { match self {
ReceiveListener::Tcp(listener) => listener.as_fd(), ReceiveListener::Tcp(listener) => listener.as_fd(),
ReceiveListener::Unix(listener) => listener.as_fd(), ReceiveListener::Unix(listener) => listener.as_fd(),
ReceiveListener::Tls(listener, _) => listener.as_fd(),
} }
} }
} }