Skip to content

Commit 77be1b3

Browse files
authored
Merge pull request #96 from chainbound/lore/feat/ipv6
IPv6 support
2 parents d036a78 + b6233ed commit 77be1b3

File tree

3 files changed

+56
-11
lines changed

3 files changed

+56
-11
lines changed

msg-common/src/lib.rs

Lines changed: 48 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::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6},
9+
time::SystemTime,
10+
};
811

912
use futures::future::BoxFuture;
1013

@@ -33,3 +36,47 @@ 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 of the same family as `other`, bound to port 0.
49+
fn as_unspecified(&self) -> Self;
50+
}
51+
52+
impl SocketAddrExt for SocketAddr {
53+
fn unspecified_v4() -> Self {
54+
Self::V4(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 0))
55+
}
56+
57+
fn unspecified_v6() -> Self {
58+
Self::V6(SocketAddrV6::new(Ipv6Addr::UNSPECIFIED, 0, 0, 0))
59+
}
60+
61+
fn as_unspecified(&self) -> Self {
62+
match self {
63+
Self::V4(_) => Self::unspecified_v4(),
64+
Self::V6(_) => Self::unspecified_v6(),
65+
}
66+
}
67+
}
68+
69+
/// Extension trait for IP addresses.
70+
pub trait IpAddrExt: Sized {
71+
/// Returns the localhost address of the same family as `other`.
72+
fn as_localhost(&self) -> Self;
73+
}
74+
75+
impl IpAddrExt for IpAddr {
76+
fn as_localhost(&self) -> Self {
77+
match self {
78+
Self::V4(_) => Self::V4(Ipv4Addr::LOCALHOST),
79+
Self::V6(_) => Self::V6(Ipv6Addr::LOCALHOST),
80+
}
81+
}
82+
}

msg-socket/src/sub/socket.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::{
22
collections::HashSet,
3-
net::{IpAddr, Ipv4Addr, SocketAddr},
3+
net::SocketAddr,
44
path::PathBuf,
55
pin::Pin,
66
sync::Arc,
@@ -14,7 +14,7 @@ use tokio::{
1414
sync::mpsc,
1515
};
1616

17-
use msg_common::JoinMap;
17+
use msg_common::{IpAddrExt, JoinMap};
1818
use msg_transport::{Address, Transport};
1919

2020
// ADDED: Import the specific SubStats struct for the API
@@ -61,8 +61,7 @@ where
6161
// Some transport implementations (e.g. Quinn) can't dial an unspecified
6262
// IP address, so replace it with localhost.
6363
if endpoint.ip().is_unspecified() {
64-
// TODO: support IPv6
65-
endpoint.set_ip(IpAddr::V4(Ipv4Addr::LOCALHOST));
64+
endpoint.set_ip(endpoint.ip().as_localhost());
6665
}
6766

6867
self.connect_inner(endpoint).await
@@ -76,8 +75,7 @@ where
7675
// Some transport implementations (e.g. Quinn) can't dial an unspecified
7776
// IP address, so replace it with localhost.
7877
if endpoint.ip().is_unspecified() {
79-
// TODO: support IPv6
80-
endpoint.set_ip(IpAddr::V4(Ipv4Addr::LOCALHOST));
78+
endpoint.set_ip(endpoint.ip().as_localhost());
8179
}
8280

8381
self.try_connect_inner(endpoint)

msg-transport/src/quic/mod.rs

Lines changed: 4 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};
@@ -67,10 +67,10 @@ impl Quic {
6767
/// `addr` is given, the endpoint will be bound to the default address.
6868
fn new_endpoint(
6969
&self,
70-
addr: Option<SocketAddr>,
70+
addr: SocketAddr,
7171
server_config: Option<quinn::ServerConfig>,
7272
) -> Result<quinn::Endpoint, Error> {
73-
let socket = UdpSocket::bind(addr.unwrap_or(SocketAddr::from(([0, 0, 0, 0], 0))))?;
73+
let socket = UdpSocket::bind(addr)?;
7474

7575
let endpoint = quinn::Endpoint::new(
7676
self.config.endpoint_config.clone(),
@@ -113,7 +113,7 @@ impl Transport<SocketAddr> for Quic {
113113
let endpoint = if let Some(endpoint) = self.endpoint.clone() {
114114
endpoint
115115
} else {
116-
let Ok(mut endpoint) = self.new_endpoint(None, None) else {
116+
let Ok(mut endpoint) = self.new_endpoint(addr.as_unspecified(), None) else {
117117
return async_error(Error::ClosedEndpoint);
118118
};
119119

0 commit comments

Comments
 (0)