mirror of
https://gitlab.com/veilid/veilid.git
synced 2025-01-25 22:15:59 -05:00
fix windows
This commit is contained in:
parent
c9bf4260c5
commit
e729682804
@ -52,12 +52,12 @@ struct NetworkInner {
|
|||||||
wss_port: u16,
|
wss_port: u16,
|
||||||
interfaces: NetworkInterfaces,
|
interfaces: NetworkInterfaces,
|
||||||
// udp
|
// udp
|
||||||
bound_first_udp: BTreeMap<u16, (socket2::Socket, socket2::Socket)>,
|
bound_first_udp: BTreeMap<u16, Option<(socket2::Socket, socket2::Socket)>>,
|
||||||
inbound_udp_protocol_handlers: BTreeMap<SocketAddr, RawUdpProtocolHandler>,
|
inbound_udp_protocol_handlers: BTreeMap<SocketAddr, RawUdpProtocolHandler>,
|
||||||
outbound_udpv4_protocol_handler: Option<RawUdpProtocolHandler>,
|
outbound_udpv4_protocol_handler: Option<RawUdpProtocolHandler>,
|
||||||
outbound_udpv6_protocol_handler: Option<RawUdpProtocolHandler>,
|
outbound_udpv6_protocol_handler: Option<RawUdpProtocolHandler>,
|
||||||
//tcp
|
//tcp
|
||||||
bound_first_tcp: BTreeMap<u16, (socket2::Socket, socket2::Socket)>,
|
bound_first_tcp: BTreeMap<u16, Option<(socket2::Socket, socket2::Socket)>>,
|
||||||
tls_acceptor: Option<TlsAcceptor>,
|
tls_acceptor: Option<TlsAcceptor>,
|
||||||
listener_states: BTreeMap<SocketAddr, Arc<RwLock<ListenerState>>>,
|
listener_states: BTreeMap<SocketAddr, Arc<RwLock<ListenerState>>>,
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use super::sockets::*;
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::intf::*;
|
use crate::intf::*;
|
||||||
use crate::network_connection::*;
|
use crate::network_connection::*;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use super::sockets::*;
|
||||||
use super::*;
|
use super::*;
|
||||||
use futures_util::stream;
|
use futures_util::stream;
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
pub mod sockets;
|
||||||
pub mod tcp;
|
pub mod tcp;
|
||||||
pub mod udp;
|
pub mod udp;
|
||||||
pub mod wrtc;
|
pub mod wrtc;
|
||||||
@ -6,7 +7,6 @@ pub mod ws;
|
|||||||
use crate::network_connection::*;
|
use crate::network_connection::*;
|
||||||
use crate::xx::*;
|
use crate::xx::*;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use socket2::{Domain, Protocol, Socket, Type};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ProtocolNetworkConnection {
|
pub enum ProtocolNetworkConnection {
|
||||||
@ -85,141 +85,3 @@ impl ProtocolNetworkConnection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_unbound_shared_udp_socket(domain: Domain) -> Result<socket2::Socket, String> {
|
|
||||||
let socket = Socket::new(domain, Type::DGRAM, Some(Protocol::UDP))
|
|
||||||
.map_err(|e| format!("Couldn't create UDP socket: {}", e))?;
|
|
||||||
if domain == Domain::IPV6 {
|
|
||||||
socket
|
|
||||||
.set_only_v6(true)
|
|
||||||
.map_err(|e| format!("Couldn't set IPV6_V6ONLY: {}", e))?;
|
|
||||||
}
|
|
||||||
socket
|
|
||||||
.set_reuse_address(true)
|
|
||||||
.map_err(|e| format!("Couldn't set reuse address: {}", e))?;
|
|
||||||
cfg_if! {
|
|
||||||
if #[cfg(unix)] {
|
|
||||||
socket.set_reuse_port(true).map_err(|e| format!("Couldn't set reuse port: {}", e))?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(socket)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_bound_shared_udp_socket(local_address: SocketAddr) -> Result<socket2::Socket, String> {
|
|
||||||
let domain = Domain::for_address(local_address);
|
|
||||||
let socket = new_unbound_shared_udp_socket(domain)?;
|
|
||||||
let socket2_addr = socket2::SockAddr::from(local_address);
|
|
||||||
socket
|
|
||||||
.bind(&socket2_addr)
|
|
||||||
.map_err(|e| format!("failed to bind UDP socket: {}", e))?;
|
|
||||||
|
|
||||||
log_net!("created shared udp socket on {:?}", &local_address);
|
|
||||||
|
|
||||||
Ok(socket)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_bound_first_udp_socket(local_address: SocketAddr) -> Result<socket2::Socket, String> {
|
|
||||||
let domain = Domain::for_address(local_address);
|
|
||||||
let socket = Socket::new(domain, Type::DGRAM, Some(Protocol::UDP))
|
|
||||||
.map_err(|e| format!("Couldn't create UDP socket: {}", e))?;
|
|
||||||
if domain == Domain::IPV6 {
|
|
||||||
socket
|
|
||||||
.set_only_v6(true)
|
|
||||||
.map_err(|e| format!("Couldn't set IPV6_V6ONLY: {}", e))?;
|
|
||||||
}
|
|
||||||
// Bind the socket -first- before turning on 'reuse address' this way it will
|
|
||||||
// fail if the port is already taken
|
|
||||||
let socket2_addr = socket2::SockAddr::from(local_address);
|
|
||||||
socket
|
|
||||||
.bind(&socket2_addr)
|
|
||||||
.map_err(|e| format!("failed to bind UDP socket: {}", e))?;
|
|
||||||
|
|
||||||
// Set 'reuse address' so future binds to this port will succeed
|
|
||||||
socket
|
|
||||||
.set_reuse_address(true)
|
|
||||||
.map_err(|e| format!("Couldn't set reuse address: {}", e))?;
|
|
||||||
cfg_if! {
|
|
||||||
if #[cfg(unix)] {
|
|
||||||
socket.set_reuse_port(true).map_err(|e| format!("Couldn't set reuse port: {}", e))?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log_net!("created shared udp socket on {:?}", &local_address);
|
|
||||||
|
|
||||||
Ok(socket)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_unbound_shared_tcp_socket(domain: Domain) -> Result<socket2::Socket, String> {
|
|
||||||
let socket = Socket::new(domain, Type::STREAM, Some(Protocol::TCP))
|
|
||||||
.map_err(map_to_string)
|
|
||||||
.map_err(logthru_net!("failed to create TCP socket"))?;
|
|
||||||
if let Err(e) = socket.set_linger(None) {
|
|
||||||
log_net!(error "Couldn't set TCP linger: {}", e);
|
|
||||||
}
|
|
||||||
if let Err(e) = socket.set_nodelay(true) {
|
|
||||||
log_net!(error "Couldn't set TCP nodelay: {}", e);
|
|
||||||
}
|
|
||||||
if domain == Domain::IPV6 {
|
|
||||||
socket
|
|
||||||
.set_only_v6(true)
|
|
||||||
.map_err(|e| format!("Couldn't set IPV6_V6ONLY: {}", e))?;
|
|
||||||
}
|
|
||||||
socket
|
|
||||||
.set_reuse_address(true)
|
|
||||||
.map_err(|e| format!("Couldn't set reuse address: {}", e))?;
|
|
||||||
cfg_if! {
|
|
||||||
if #[cfg(unix)] {
|
|
||||||
socket.set_reuse_port(true).map_err(|e| format!("Couldn't set reuse port: {}", e))?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(socket)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_bound_shared_tcp_socket(local_address: SocketAddr) -> Result<socket2::Socket, String> {
|
|
||||||
let domain = Domain::for_address(local_address);
|
|
||||||
|
|
||||||
let socket = new_unbound_shared_tcp_socket(domain)?;
|
|
||||||
|
|
||||||
let socket2_addr = socket2::SockAddr::from(local_address);
|
|
||||||
socket
|
|
||||||
.bind(&socket2_addr)
|
|
||||||
.map_err(|e| format!("failed to bind TCP socket: {}", e))?;
|
|
||||||
|
|
||||||
Ok(socket)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_bound_first_tcp_socket(local_address: SocketAddr) -> Result<socket2::Socket, String> {
|
|
||||||
let domain = Domain::for_address(local_address);
|
|
||||||
|
|
||||||
let socket = Socket::new(domain, Type::STREAM, Some(Protocol::TCP))
|
|
||||||
.map_err(map_to_string)
|
|
||||||
.map_err(logthru_net!("failed to create TCP socket"))?;
|
|
||||||
if let Err(e) = socket.set_linger(None) {
|
|
||||||
log_net!(error "Couldn't set TCP linger: {}", e);
|
|
||||||
}
|
|
||||||
if let Err(e) = socket.set_nodelay(true) {
|
|
||||||
log_net!(error "Couldn't set TCP nodelay: {}", e);
|
|
||||||
}
|
|
||||||
if domain == Domain::IPV6 {
|
|
||||||
socket
|
|
||||||
.set_only_v6(true)
|
|
||||||
.map_err(|e| format!("Couldn't set IPV6_V6ONLY: {}", e))?;
|
|
||||||
}
|
|
||||||
// Bind the socket -first- before turning on 'reuse address' this way it will
|
|
||||||
// fail if the port is already taken
|
|
||||||
|
|
||||||
let socket2_addr = socket2::SockAddr::from(local_address);
|
|
||||||
socket
|
|
||||||
.bind(&socket2_addr)
|
|
||||||
.map_err(|e| format!("failed to bind TCP socket: {}", e))?;
|
|
||||||
|
|
||||||
// Set 'reuse address' so future binds to this port will succeed
|
|
||||||
socket
|
|
||||||
.set_reuse_address(true)
|
|
||||||
.map_err(|e| format!("Couldn't set reuse address: {}", e))?;
|
|
||||||
cfg_if! {
|
|
||||||
if #[cfg(unix)] {
|
|
||||||
socket.set_reuse_port(true).map_err(|e| format!("Couldn't set reuse port: {}", e))?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(socket)
|
|
||||||
}
|
|
||||||
|
181
veilid-core/src/intf/native/network/protocol/sockets.rs
Normal file
181
veilid-core/src/intf/native/network/protocol/sockets.rs
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
use crate::xx::*;
|
||||||
|
use crate::*;
|
||||||
|
use socket2::{Domain, Protocol, Socket, Type};
|
||||||
|
|
||||||
|
cfg_if! {
|
||||||
|
if #[cfg(windows)] {
|
||||||
|
use winapi::shared::ws2def::{ SOL_SOCKET, SO_EXCLUSIVEADDRUSE};
|
||||||
|
use winapi::um::winsock2::{SOCKET_ERROR, setsockopt};
|
||||||
|
use winapi::ctypes::c_int;
|
||||||
|
use std::os::windows::io::AsRawSocket;
|
||||||
|
|
||||||
|
fn set_exclusiveaddruse(socket: &Socket) -> Result<(), String> {
|
||||||
|
unsafe {
|
||||||
|
let optval:c_int = 1;
|
||||||
|
if setsockopt(socket.as_raw_socket().try_into().unwrap(), SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (&optval as *const c_int).cast(),
|
||||||
|
std::mem::size_of::<c_int>() as c_int) == SOCKET_ERROR {
|
||||||
|
return Err("Unable to SO_EXCLUSIVEADDRUSE".to_owned());
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_unbound_shared_udp_socket(domain: Domain) -> Result<Socket, String> {
|
||||||
|
let socket = Socket::new(domain, Type::DGRAM, Some(Protocol::UDP))
|
||||||
|
.map_err(|e| format!("Couldn't create UDP socket: {}", e))?;
|
||||||
|
if domain == Domain::IPV6 {
|
||||||
|
socket
|
||||||
|
.set_only_v6(true)
|
||||||
|
.map_err(|e| format!("Couldn't set IPV6_V6ONLY: {}", e))?;
|
||||||
|
}
|
||||||
|
socket
|
||||||
|
.set_reuse_address(true)
|
||||||
|
.map_err(|e| format!("Couldn't set reuse address: {}", e))?;
|
||||||
|
cfg_if! {
|
||||||
|
if #[cfg(unix)] {
|
||||||
|
socket.set_reuse_port(true).map_err(|e| format!("Couldn't set reuse port: {}", e))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(socket)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_bound_shared_udp_socket(local_address: SocketAddr) -> Result<Socket, String> {
|
||||||
|
let domain = Domain::for_address(local_address);
|
||||||
|
let socket = new_unbound_shared_udp_socket(domain)?;
|
||||||
|
let socket2_addr = socket2::SockAddr::from(local_address);
|
||||||
|
socket.bind(&socket2_addr).map_err(|e| {
|
||||||
|
format!(
|
||||||
|
"failed to bind UDP socket to '{}' in domain '{:?}': {} ",
|
||||||
|
local_address, domain, e
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
log_net!("created shared udp socket on {:?}", &local_address);
|
||||||
|
|
||||||
|
Ok(socket)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_bound_first_udp_socket(local_address: SocketAddr) -> Result<Socket, String> {
|
||||||
|
let domain = Domain::for_address(local_address);
|
||||||
|
let socket = Socket::new(domain, Type::DGRAM, Some(Protocol::UDP))
|
||||||
|
.map_err(|e| format!("Couldn't create UDP socket: {}", e))?;
|
||||||
|
if domain == Domain::IPV6 {
|
||||||
|
socket
|
||||||
|
.set_only_v6(true)
|
||||||
|
.map_err(|e| format!("Couldn't set IPV6_V6ONLY: {}", e))?;
|
||||||
|
}
|
||||||
|
// Bind the socket -first- before turning on 'reuse address' this way it will
|
||||||
|
// fail if the port is already taken
|
||||||
|
let socket2_addr = socket2::SockAddr::from(local_address);
|
||||||
|
|
||||||
|
// On windows, do SO_EXCLUSIVEADDRUSE before the bind to ensure the port is fully available
|
||||||
|
cfg_if! {
|
||||||
|
if #[cfg(windows)] {
|
||||||
|
set_exclusiveaddruse(&socket)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
socket
|
||||||
|
.bind(&socket2_addr)
|
||||||
|
.map_err(|e| format!("failed to bind UDP socket: {}", e))?;
|
||||||
|
|
||||||
|
// Set 'reuse address' so future binds to this port will succeed
|
||||||
|
// This does not work on Windows, where reuse options can not be set after the bind
|
||||||
|
cfg_if! {
|
||||||
|
if #[cfg(unix)] {
|
||||||
|
socket
|
||||||
|
.set_reuse_address(true)
|
||||||
|
.map_err(|e| format!("Couldn't set reuse address: {}", e))?;
|
||||||
|
socket.set_reuse_port(true).map_err(|e| format!("Couldn't set reuse port: {}", e))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log_net!("created shared udp socket on {:?}", &local_address);
|
||||||
|
|
||||||
|
Ok(socket)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_unbound_shared_tcp_socket(domain: Domain) -> Result<Socket, String> {
|
||||||
|
let socket = Socket::new(domain, Type::STREAM, Some(Protocol::TCP))
|
||||||
|
.map_err(map_to_string)
|
||||||
|
.map_err(logthru_net!("failed to create TCP socket"))?;
|
||||||
|
if let Err(e) = socket.set_linger(None) {
|
||||||
|
log_net!(error "Couldn't set TCP linger: {}", e);
|
||||||
|
}
|
||||||
|
if let Err(e) = socket.set_nodelay(true) {
|
||||||
|
log_net!(error "Couldn't set TCP nodelay: {}", e);
|
||||||
|
}
|
||||||
|
if domain == Domain::IPV6 {
|
||||||
|
socket
|
||||||
|
.set_only_v6(true)
|
||||||
|
.map_err(|e| format!("Couldn't set IPV6_V6ONLY: {}", e))?;
|
||||||
|
}
|
||||||
|
socket
|
||||||
|
.set_reuse_address(true)
|
||||||
|
.map_err(|e| format!("Couldn't set reuse address: {}", e))?;
|
||||||
|
cfg_if! {
|
||||||
|
if #[cfg(unix)] {
|
||||||
|
socket.set_reuse_port(true).map_err(|e| format!("Couldn't set reuse port: {}", e))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(socket)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_bound_shared_tcp_socket(local_address: SocketAddr) -> Result<Socket, String> {
|
||||||
|
let domain = Domain::for_address(local_address);
|
||||||
|
|
||||||
|
let socket = new_unbound_shared_tcp_socket(domain)?;
|
||||||
|
|
||||||
|
let socket2_addr = socket2::SockAddr::from(local_address);
|
||||||
|
socket
|
||||||
|
.bind(&socket2_addr)
|
||||||
|
.map_err(|e| format!("failed to bind TCP socket: {}", e))?;
|
||||||
|
|
||||||
|
Ok(socket)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_bound_first_tcp_socket(local_address: SocketAddr) -> Result<Socket, String> {
|
||||||
|
let domain = Domain::for_address(local_address);
|
||||||
|
|
||||||
|
let socket = Socket::new(domain, Type::STREAM, Some(Protocol::TCP))
|
||||||
|
.map_err(map_to_string)
|
||||||
|
.map_err(logthru_net!("failed to create TCP socket"))?;
|
||||||
|
if let Err(e) = socket.set_linger(None) {
|
||||||
|
log_net!(error "Couldn't set TCP linger: {}", e);
|
||||||
|
}
|
||||||
|
if let Err(e) = socket.set_nodelay(true) {
|
||||||
|
log_net!(error "Couldn't set TCP nodelay: {}", e);
|
||||||
|
}
|
||||||
|
if domain == Domain::IPV6 {
|
||||||
|
socket
|
||||||
|
.set_only_v6(true)
|
||||||
|
.map_err(|e| format!("Couldn't set IPV6_V6ONLY: {}", e))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// On windows, do SO_EXCLUSIVEADDRUSE before the bind to ensure the port is fully available
|
||||||
|
cfg_if! {
|
||||||
|
if #[cfg(windows)] {
|
||||||
|
set_exclusiveaddruse(&socket)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind the socket -first- before turning on 'reuse address' this way it will
|
||||||
|
// fail if the port is already taken
|
||||||
|
let socket2_addr = socket2::SockAddr::from(local_address);
|
||||||
|
socket
|
||||||
|
.bind(&socket2_addr)
|
||||||
|
.map_err(|e| format!("failed to bind TCP socket: {}", e))?;
|
||||||
|
|
||||||
|
// Set 'reuse address' so future binds to this port will succeed
|
||||||
|
// This does not work on Windows, where reuse options can not be set after the bind
|
||||||
|
cfg_if! {
|
||||||
|
if #[cfg(unix)] {
|
||||||
|
socket
|
||||||
|
.set_reuse_address(true)
|
||||||
|
.map_err(|e| format!("Couldn't set reuse address: {}", e))?;
|
||||||
|
socket.set_reuse_port(true).map_err(|e| format!("Couldn't set reuse port: {}", e))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(socket)
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
|
use super::sockets::*;
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::intf::*;
|
use crate::intf::*;
|
||||||
use crate::network_manager::MAX_MESSAGE_SIZE;
|
use crate::network_manager::MAX_MESSAGE_SIZE;
|
||||||
@ -139,7 +140,9 @@ impl RawTcpProtocolHandler {
|
|||||||
// Make a shared socket
|
// Make a shared socket
|
||||||
let socket = match local_address {
|
let socket = match local_address {
|
||||||
Some(a) => new_bound_shared_tcp_socket(a)?,
|
Some(a) => new_bound_shared_tcp_socket(a)?,
|
||||||
None => new_unbound_shared_tcp_socket(Domain::for_address(remote_socket_addr))?,
|
None => {
|
||||||
|
new_unbound_shared_tcp_socket(socket2::Domain::for_address(remote_socket_addr))?
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Connect to the remote address
|
// Connect to the remote address
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use super::sockets::*;
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::intf::*;
|
use crate::intf::*;
|
||||||
use crate::network_manager::MAX_MESSAGE_SIZE;
|
use crate::network_manager::MAX_MESSAGE_SIZE;
|
||||||
@ -207,7 +208,9 @@ impl WebsocketProtocolHandler {
|
|||||||
// Make a shared socket
|
// Make a shared socket
|
||||||
let socket = match local_address {
|
let socket = match local_address {
|
||||||
Some(a) => new_bound_shared_tcp_socket(a)?,
|
Some(a) => new_bound_shared_tcp_socket(a)?,
|
||||||
None => new_unbound_shared_tcp_socket(Domain::for_address(remote_socket_addr))?,
|
None => {
|
||||||
|
new_unbound_shared_tcp_socket(socket2::Domain::for_address(remote_socket_addr))?
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Connect to the remote address
|
// Connect to the remote address
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use super::sockets::*;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
impl Network {
|
impl Network {
|
||||||
@ -26,7 +27,18 @@ impl Network {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let (Some(bfs4), Some(bfs6)) = (bound_first_socket_v4, bound_first_socket_v6) {
|
if let (Some(bfs4), Some(bfs6)) = (bound_first_socket_v4, bound_first_socket_v6) {
|
||||||
inner.bound_first_udp.insert(udp_port, (bfs4, bfs6));
|
cfg_if! {
|
||||||
|
if #[cfg(windows)] {
|
||||||
|
// On windows, drop the socket. This is a race condition, but there's
|
||||||
|
// no way around it. This isn't for security anyway, it's to prevent multiple copies of the
|
||||||
|
// app from binding on the same port.
|
||||||
|
drop(bfs4);
|
||||||
|
drop(bfs6);
|
||||||
|
inner.bound_first_udp.insert(udp_port, None);
|
||||||
|
} else {
|
||||||
|
inner.bound_first_udp.insert(udp_port, Some(bfs4, bfs6));
|
||||||
|
}
|
||||||
|
}
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
@ -53,7 +65,18 @@ impl Network {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let (Some(bfs4), Some(bfs6)) = (bound_first_socket_v4, bound_first_socket_v6) {
|
if let (Some(bfs4), Some(bfs6)) = (bound_first_socket_v4, bound_first_socket_v6) {
|
||||||
inner.bound_first_tcp.insert(tcp_port, (bfs4, bfs6));
|
cfg_if! {
|
||||||
|
if #[cfg(windows)] {
|
||||||
|
// On windows, drop the socket. This is a race condition, but there's
|
||||||
|
// no way around it. This isn't for security anyway, it's to prevent multiple copies of the
|
||||||
|
// app from binding on the same port.
|
||||||
|
drop(bfs4);
|
||||||
|
drop(bfs6);
|
||||||
|
inner.bound_first_tcp.insert(tcp_port, None);
|
||||||
|
} else {
|
||||||
|
inner.bound_first_tcp.insert(tcp_port, Some(bfs4, bfs6));
|
||||||
|
}
|
||||||
|
}
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
Loading…
x
Reference in New Issue
Block a user