mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-05-16 04:41:20 +00:00
fix(quic): allow listening on ipv4 and ipv6 separately
Resolves #4165. Pull-Request: #4289.
This commit is contained in:
parent
b5d993267f
commit
02dc432227
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -3058,7 +3058,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libp2p-quic"
|
name = "libp2p-quic"
|
||||||
version = "0.9.0-alpha"
|
version = "0.9.1-alpha"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-std",
|
"async-std",
|
||||||
"bytes",
|
"bytes",
|
||||||
@ -3079,6 +3079,7 @@ dependencies = [
|
|||||||
"quinn",
|
"quinn",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
"rustls 0.21.5",
|
"rustls 0.21.5",
|
||||||
|
"socket2 0.5.3",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
@ -85,7 +85,7 @@ libp2p-perf = { version = "0.2.0", path = "protocols/perf" }
|
|||||||
libp2p-ping = { version = "0.43.0", path = "protocols/ping" }
|
libp2p-ping = { version = "0.43.0", path = "protocols/ping" }
|
||||||
libp2p-plaintext = { version = "0.40.0", path = "transports/plaintext" }
|
libp2p-plaintext = { version = "0.40.0", path = "transports/plaintext" }
|
||||||
libp2p-pnet = { version = "0.23.0", path = "transports/pnet" }
|
libp2p-pnet = { version = "0.23.0", path = "transports/pnet" }
|
||||||
libp2p-quic = { version = "0.9.0-alpha", path = "transports/quic" }
|
libp2p-quic = { version = "0.9.1-alpha", path = "transports/quic" }
|
||||||
libp2p-relay = { version = "0.16.1", path = "protocols/relay" }
|
libp2p-relay = { version = "0.16.1", path = "protocols/relay" }
|
||||||
libp2p-rendezvous = { version = "0.13.0", path = "protocols/rendezvous" }
|
libp2p-rendezvous = { version = "0.13.0", path = "protocols/rendezvous" }
|
||||||
libp2p-request-response = { version = "0.25.1", path = "protocols/request-response" }
|
libp2p-request-response = { version = "0.25.1", path = "protocols/request-response" }
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
## 0.9.1-alpha - unreleased
|
||||||
|
|
||||||
|
- Allow listening on ipv4 and ipv6 separately.
|
||||||
|
See [PR 4289].
|
||||||
|
|
||||||
|
[PR 4289]: https://github.com/libp2p/rust-libp2p/pull/4289
|
||||||
|
|
||||||
## 0.9.0-alpha
|
## 0.9.0-alpha
|
||||||
|
|
||||||
- Use `quinn` instead of `quinn-proto`.
|
- Use `quinn` instead of `quinn-proto`.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "libp2p-quic"
|
name = "libp2p-quic"
|
||||||
version = "0.9.0-alpha"
|
version = "0.9.1-alpha"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = { workspace = true }
|
rust-version = { workspace = true }
|
||||||
@ -24,6 +24,7 @@ rand = "0.8.5"
|
|||||||
rustls = { version = "0.21.2", default-features = false }
|
rustls = { version = "0.21.2", default-features = false }
|
||||||
thiserror = "1.0.44"
|
thiserror = "1.0.44"
|
||||||
tokio = { version = "1.29.1", default-features = false, features = ["net", "rt", "time"], optional = true }
|
tokio = { version = "1.29.1", default-features = false, features = ["net", "rt", "time"], optional = true }
|
||||||
|
socket2 = "0.5.3"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
tokio = ["dep:tokio", "if-watch/tokio", "quinn/runtime-tokio"]
|
tokio = ["dep:tokio", "if-watch/tokio", "quinn/runtime-tokio"]
|
||||||
|
@ -37,12 +37,13 @@ use libp2p_core::{
|
|||||||
Transport,
|
Transport,
|
||||||
};
|
};
|
||||||
use libp2p_identity::PeerId;
|
use libp2p_identity::PeerId;
|
||||||
|
use socket2::{Domain, Socket, Type};
|
||||||
use std::collections::hash_map::{DefaultHasher, Entry};
|
use std::collections::hash_map::{DefaultHasher, Entry};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt;
|
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, UdpSocket};
|
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, UdpSocket};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
use std::{fmt, io};
|
||||||
use std::{
|
use std::{
|
||||||
net::SocketAddr,
|
net::SocketAddr,
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
@ -172,6 +173,21 @@ impl<P: Provider> GenTransport<P> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn create_socket(&self, socket_addr: SocketAddr) -> io::Result<UdpSocket> {
|
||||||
|
let socket = Socket::new(
|
||||||
|
Domain::for_address(socket_addr),
|
||||||
|
Type::DGRAM,
|
||||||
|
Some(socket2::Protocol::UDP),
|
||||||
|
)?;
|
||||||
|
if socket_addr.is_ipv6() {
|
||||||
|
socket.set_only_v6(true)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.bind(&socket_addr.into())?;
|
||||||
|
|
||||||
|
Ok(socket.into())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: Provider> Transport for GenTransport<P> {
|
impl<P: Provider> Transport for GenTransport<P> {
|
||||||
@ -188,7 +204,8 @@ impl<P: Provider> Transport for GenTransport<P> {
|
|||||||
let (socket_addr, version, _peer_id) = self.remote_multiaddr_to_socketaddr(addr, false)?;
|
let (socket_addr, version, _peer_id) = self.remote_multiaddr_to_socketaddr(addr, false)?;
|
||||||
let endpoint_config = self.quinn_config.endpoint_config.clone();
|
let endpoint_config = self.quinn_config.endpoint_config.clone();
|
||||||
let server_config = self.quinn_config.server_config.clone();
|
let server_config = self.quinn_config.server_config.clone();
|
||||||
let socket = UdpSocket::bind(socket_addr).map_err(Self::Error::from)?;
|
let socket = self.create_socket(socket_addr).map_err(Self::Error::from)?;
|
||||||
|
|
||||||
let socket_c = socket.try_clone().map_err(Self::Error::from)?;
|
let socket_c = socket.try_clone().map_err(Self::Error::from)?;
|
||||||
let endpoint = Self::new_endpoint(endpoint_config, Some(server_config), socket)?;
|
let endpoint = Self::new_endpoint(endpoint_config, Some(server_config), socket)?;
|
||||||
let listener = Listener::new(
|
let listener = Listener::new(
|
||||||
@ -888,4 +905,25 @@ mod test {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(!transport.dialer.contains_key(&SocketFamily::Ipv4));
|
assert!(!transport.dialer.contains_key(&SocketFamily::Ipv4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "tokio")]
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_listens_ipv4_ipv6_separately() {
|
||||||
|
let keypair = libp2p_identity::Keypair::generate_ed25519();
|
||||||
|
let config = Config::new(&keypair);
|
||||||
|
let mut transport = crate::tokio::Transport::new(config);
|
||||||
|
|
||||||
|
transport
|
||||||
|
.listen_on(
|
||||||
|
ListenerId::next(),
|
||||||
|
"/ip4/0.0.0.0/udp/4001/quic-v1".parse().unwrap(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
transport
|
||||||
|
.listen_on(
|
||||||
|
ListenerId::next(),
|
||||||
|
"/ip6/::/udp/4001/quic-v1".parse().unwrap(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user