Skip to content

Commit

Permalink
TCP: explicitly allow IPv4.
Browse files Browse the repository at this point in the history
Ensure that IPv4 support is enabled on created TCP sockets.
  • Loading branch information
surban committed Feb 5, 2024
1 parent c76a11a commit d8129ff
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 9 deletions.
4 changes: 3 additions & 1 deletion aggligator-util/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ repository = "https://github.com/surban/aggligator"

[features]
default = ["cli", "tls", "tcp"]
tcp = ["tokio/net"]
tcp = ["tokio/net", "socket2"]
tls = ["rustls", "tokio-rustls"]
rfcomm = ["bluer/rfcomm"]
rfcomm-profile = ["bluer/rfcomm", "bluer/bluetoothd"]
Expand All @@ -38,6 +38,7 @@ cli = [
"rustls/dangerous_configuration",
"axum-server",
"gethostname",
"socket2",
]
raw-speed-cli = ["cli"]
speed = ["rand", "rand_xoshiro"]
Expand Down Expand Up @@ -81,6 +82,7 @@ upc = { version = "0.4", optional = true }
usb-gadget = { version = "0.6", optional = true }
rusb = { version = "0.9", optional = true }
gethostname = { version = "0.4", optional = true }
socket2 = { version = "0.5", optional = true }

[[bin]]
name = "agg-speed"
Expand Down
36 changes: 28 additions & 8 deletions aggligator-util/src/transport/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
use async_trait::async_trait;
use futures::{future, FutureExt};
use network_interface::{NetworkInterface, NetworkInterfaceConfig};
use network_interface::{Addr, NetworkInterface, NetworkInterfaceConfig};
use socket2::SockRef;
use std::{
any::Any,
cmp::Ordering,
Expand Down Expand Up @@ -348,7 +349,11 @@ impl TcpAcceptor {
let mut listeners = Vec::new();

for addr in addrs {
listeners.push(TcpListener::bind(addr).await?);
let listener = TcpListener::bind(addr).await?;
if addr.is_ipv6() {
let _ = SockRef::from(&listener).set_only_v6(false);
}
listeners.push(listener);
}

Self::from_listeners(listeners)
Expand Down Expand Up @@ -377,25 +382,40 @@ impl TcpAcceptor {
let mut listeners = Vec::new();

for iface in local_interfaces()? {
match Self::listen(&iface, port) {
Ok(listener) => listeners.push(listener),
Err(err) => {
tracing::warn!("cannot listen on {}: {err}", &iface.name);
for version in [IpVersion::IPv6, IpVersion::IPv4] {
match Self::listen(&iface, port, version) {
Ok(listener) => listeners.push(listener),
Err(err) => {
tracing::warn!("cannot listen on {version:?} {}: {err}", &iface.name);
}
}
}
}

Self::from_listeners(listeners)
}

fn listen(interface: &NetworkInterface, port: u16) -> Result<TcpListener> {
let addr = SocketAddr::new(interface.addr.first().ok_or(ErrorKind::NotFound)?.ip(), port);
fn listen(interface: &NetworkInterface, port: u16, ip_version: IpVersion) -> Result<TcpListener> {
let ip = interface
.addr
.iter()
.find_map(|addr| match addr {
Addr::V4(ip) if ip_version != IpVersion::IPv6 => Some(IpAddr::V4(ip.ip)),
Addr::V6(ip) if ip_version != IpVersion::IPv4 => Some(IpAddr::V6(ip.ip)),
_ => None,
})
.ok_or(ErrorKind::NotFound)?;
let addr = SocketAddr::new(ip, port);

let socket = match addr.ip() {
IpAddr::V4(_) => TcpSocket::new_v4()?,
IpAddr::V6(_) => TcpSocket::new_v6()?,
};

if addr.is_ipv6() {
let _ = SockRef::from(&socket).set_only_v6(false);
}

socket.bind(addr)?;

#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
Expand Down

0 comments on commit d8129ff

Please sign in to comment.