|
@@ -10,7 +10,12 @@ use anyhow::{self as ah, format_err as err, Context as _};
|
|
|
use letmein_conf::Config;
|
|
|
use letmein_proto::{Message, MsgNetSocket, MsgUdpDispatcher};
|
|
|
use letmein_systemd::{systemd_notify_ready, SystemdSocket};
|
|
|
-use std::{convert::Infallible, net::SocketAddr, sync::Arc, time::Duration};
|
|
|
+use std::{
|
|
|
+ convert::Infallible,
|
|
|
+ net::{Ipv6Addr, SocketAddr},
|
|
|
+ sync::Arc,
|
|
|
+ time::Duration,
|
|
|
+};
|
|
|
use tokio::{
|
|
|
net::{TcpListener, TcpStream, UdpSocket},
|
|
|
task::{self, JoinHandle},
|
|
@@ -138,7 +143,7 @@ impl Server {
|
|
|
// TCP bind.
|
|
|
if conf.port().tcp {
|
|
|
this.tcp = Arc::new(Some(
|
|
|
- TcpListener::bind(("::0", conf.port().port))
|
|
|
+ TcpListener::bind((Ipv6Addr::UNSPECIFIED, conf.port().port))
|
|
|
.await
|
|
|
.context("Bind")?,
|
|
|
));
|
|
@@ -146,7 +151,7 @@ impl Server {
|
|
|
// UDP bind.
|
|
|
if conf.port().udp {
|
|
|
this.udp = Arc::new(Some(Arc::new(MsgUdpDispatcher::new(
|
|
|
- UdpSocket::bind(("::0", conf.port().port))
|
|
|
+ UdpSocket::bind((Ipv6Addr::UNSPECIFIED, conf.port().port))
|
|
|
.await
|
|
|
.context("Bind")?,
|
|
|
max_nr_udp_conn,
|
|
@@ -156,7 +161,8 @@ impl Server {
|
|
|
Ok(this)
|
|
|
}
|
|
|
|
|
|
- pub async fn accept(&mut self) -> ah::Result<Arc<Connection>> {
|
|
|
+ pub async fn accept(&mut self) -> ah::Result<Connection> {
|
|
|
+ // Async task for accepting a new TCP connection.
|
|
|
let join_tcp: JoinHandle<ah::Result<(TcpStream, SocketAddr)>> = task::spawn({
|
|
|
let tcp = Arc::clone(&self.tcp);
|
|
|
async move {
|
|
@@ -168,28 +174,29 @@ impl Server {
|
|
|
}
|
|
|
});
|
|
|
|
|
|
- let join_udp: JoinHandle<ah::Result<SocketAddr>> = task::spawn({
|
|
|
+ // Async task for accepting a new UDP connection.
|
|
|
+ let join_udp: JoinHandle<ah::Result<(Arc<MsgUdpDispatcher>, SocketAddr)>> = task::spawn({
|
|
|
let udp = Arc::clone(&self.udp);
|
|
|
async move {
|
|
|
if let Some(udp) = udp.as_ref() {
|
|
|
- return udp.accept().await;
|
|
|
+ return Ok((Arc::clone(udp), udp.accept().await?));
|
|
|
}
|
|
|
sleep_forever().await;
|
|
|
unreachable!();
|
|
|
}
|
|
|
});
|
|
|
|
|
|
+ // Await any one of the accept tasks.
|
|
|
tokio::select! {
|
|
|
result = join_tcp => {
|
|
|
let (stream, peer_addr) = result??;
|
|
|
let ns = MsgNetSocket::from_tcp(stream);
|
|
|
- Ok(Arc::new(Connection::new(ns, peer_addr)?))
|
|
|
+ Ok(Connection::new(ns, peer_addr)?)
|
|
|
}
|
|
|
result = join_udp => {
|
|
|
- let peer_addr = result??;
|
|
|
- let udp_disp = (*self.udp).as_ref().unwrap();
|
|
|
- let ns = MsgNetSocket::from_udp(Arc::clone(udp_disp), peer_addr);
|
|
|
- Ok(Arc::new(Connection::new(ns, peer_addr)?))
|
|
|
+ let (udp_disp, peer_addr) = result??;
|
|
|
+ let ns = MsgNetSocket::from_udp(udp_disp, peer_addr);
|
|
|
+ Ok(Connection::new(ns, peer_addr)?)
|
|
|
}
|
|
|
}
|
|
|
}
|