In case of IPv6 and NON Windows make sure to not listen on dualstack,

for that we need to create a socket2 socket and set_only_v6 to true.
We need to privude set_nonblocking for tokio to work and we need to set reuseaddr for it to work on linux systems
This commit is contained in:
Marcel Märtens 2022-01-29 19:50:32 +01:00
parent e9bee485ae
commit dcfde616d0
3 changed files with 21 additions and 5 deletions

9
Cargo.lock generated
View File

@ -2893,9 +2893,9 @@ dependencies = [
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.107" version = "0.2.116"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219" checksum = "565dbd88872dbe4cc8a46e527f26483c1d1f7afa6b884a3bd6cd893d4f98da74"
[[package]] [[package]]
name = "libgit2-sys" name = "libgit2-sys"
@ -5383,9 +5383,9 @@ dependencies = [
[[package]] [[package]]
name = "socket2" name = "socket2"
version = "0.4.2" version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5dc90fe6c7be1a323296982db1836d1ea9e47b6839496dde9a541bc496df3516" checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0"
dependencies = [ dependencies = [
"libc", "libc",
"winapi 0.3.9", "winapi 0.3.9",
@ -6374,6 +6374,7 @@ dependencies = [
"rustls 0.20.1", "rustls 0.20.1",
"serde", "serde",
"shellexpand", "shellexpand",
"socket2",
"tokio", "tokio",
"tokio-stream", "tokio-stream",
"tracing", "tracing",

View File

@ -20,6 +20,8 @@ network-protocol = { package = "veloren-network-protocol", path = "protocol" }
#serialisation #serialisation
bincode = "1.3.2" bincode = "1.3.2"
serde = { version = "1.0" } serde = { version = "1.0" }
#ipv4/ipv6 behavior
socket2 = "0.4.4"
#sending #sending
crossbeam-channel = "0.5" crossbeam-channel = "0.5"
tokio = { version = "1.14", default-features = false, features = ["io-util", "macros", "rt", "net", "time"] } tokio = { version = "1.14", default-features = false, features = ["io-util", "macros", "rt", "net", "time"] }

View File

@ -94,7 +94,20 @@ impl Protocols {
s2s_stop_listening_r: oneshot::Receiver<()>, s2s_stop_listening_r: oneshot::Receiver<()>,
c2s_protocol_s: mpsc::UnboundedSender<(Self, Cid)>, c2s_protocol_s: mpsc::UnboundedSender<(Self, Cid)>,
) -> std::io::Result<()> { ) -> std::io::Result<()> {
let listener = net::TcpListener::bind(addr).await?; use socket2::{Domain, Socket, Type};
use tokio::net::TcpSocket;
let domain = Domain::for_address(addr);
let socket2_socket = Socket::new(domain, Type::STREAM, None)?;
if domain == Domain::IPV6 {
socket2_socket.set_only_v6(true)?
}
socket2_socket.set_nonblocking(true)?; //needed by tokio
let socket = TcpSocket::from_std_stream(socket2_socket.into());
// See https://docs.rs/tokio/latest/tokio/net/struct.TcpSocket.html
#[cfg(not(windows))]
socket.set_reuseaddr(true)?;
socket.bind(addr)?;
let listener = socket.listen(1024)?;
trace!(?addr, "Tcp Listener bound"); trace!(?addr, "Tcp Listener bound");
let mut end_receiver = s2s_stop_listening_r.fuse(); let mut end_receiver = s2s_stop_listening_r.fuse();
tokio::spawn(async move { tokio::spawn(async move {