Skip to content

Commit da2d55f

Browse files
committed
fix(quic): ipv6 support
1 parent 26b97e3 commit da2d55f

File tree

2 files changed

+39
-5
lines changed

2 files changed

+39
-5
lines changed

msg-common/src/lib.rs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
55
#![cfg_attr(not(test), warn(unused_crate_dependencies))]
66

7-
use std::time::SystemTime;
7+
use std::{
8+
net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6},
9+
time::SystemTime,
10+
};
811

912
use futures::future::BoxFuture;
1013

@@ -33,3 +36,33 @@ pub mod constants {
3336
pub const MiB: u32 = 1024 * KiB;
3437
pub const GiB: u32 = 1024 * MiB;
3538
}
39+
40+
/// Extension trait for `SocketAddr`.
41+
pub trait SocketAddrExt: Sized {
42+
/// Returns the unspecified IPv4 socket address, bound to port 0.
43+
fn unspecified_v4() -> Self;
44+
45+
/// Returns the unspecified IPv6 socket address, bound to port 0.
46+
fn unspecified_v6() -> Self;
47+
48+
/// Returns the unspecified socket address bound to port 0 of the same protocol version of
49+
/// the provided address.
50+
fn unspecified_compatible_with(other: &Self) -> Self;
51+
}
52+
53+
impl SocketAddrExt for SocketAddr {
54+
fn unspecified_v4() -> Self {
55+
SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 0))
56+
}
57+
58+
fn unspecified_v6() -> Self {
59+
SocketAddr::V6(SocketAddrV6::new(Ipv6Addr::UNSPECIFIED, 0, 0, 0))
60+
}
61+
62+
fn unspecified_compatible_with(other: &Self) -> Self {
63+
match other {
64+
SocketAddr::V4(_) => Self::unspecified_v4(),
65+
SocketAddr::V6(_) => Self::unspecified_v6(),
66+
}
67+
}
68+
}

msg-transport/src/quic/mod.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use tracing::{debug, error};
1313

1414
use crate::{Acceptor, Transport, TransportExt};
1515

16-
use msg_common::async_error;
16+
use msg_common::{SocketAddrExt, async_error};
1717

1818
mod config;
1919
pub use config::{Config, ConfigBuilder};
@@ -65,10 +65,10 @@ impl Quic {
6565
/// `addr` is given, the endpoint will be bound to the default address.
6666
fn new_endpoint(
6767
&self,
68-
addr: Option<SocketAddr>,
68+
addr: SocketAddr,
6969
server_config: Option<quinn::ServerConfig>,
7070
) -> Result<quinn::Endpoint, Error> {
71-
let socket = UdpSocket::bind(addr.unwrap_or(SocketAddr::from(([0, 0, 0, 0], 0))))?;
71+
let socket = UdpSocket::bind(addr)?;
7272

7373
let endpoint = quinn::Endpoint::new(
7474
self.config.endpoint_config.clone(),
@@ -111,7 +111,8 @@ impl Transport<SocketAddr> for Quic {
111111
let endpoint = if let Some(endpoint) = self.endpoint.clone() {
112112
endpoint
113113
} else {
114-
let Ok(endpoint) = self.new_endpoint(None, None) else {
114+
let endpoint_addr = SocketAddr::unspecified_compatible_with(&addr);
115+
let Ok(endpoint) = self.new_endpoint(endpoint_addr, None) else {
115116
return async_error(Error::ClosedEndpoint);
116117
};
117118

0 commit comments

Comments
 (0)