mirror of
https://gitlab.com/veilid/veilid.git
synced 2025-09-23 22:44:39 -04:00
Add relayed-only mode
This commit is contained in:
parent
d742171aa7
commit
87708d4b3e
18 changed files with 205 additions and 135 deletions
|
@ -136,4 +136,6 @@ core:
|
||||||
max_connections: 16
|
max_connections: 16
|
||||||
listen_address: ':5150'
|
listen_address: ':5150'
|
||||||
path: 'ws'
|
path: 'ws'
|
||||||
# url: ''
|
# url: ''
|
||||||
|
privacy:
|
||||||
|
require_inbound_relay: false
|
||||||
|
|
|
@ -29,6 +29,7 @@ pub const ADDRESS_CHECK_CACHE_SIZE: usize = 10;
|
||||||
pub struct AddressCheckConfig {
|
pub struct AddressCheckConfig {
|
||||||
pub detect_address_changes: bool,
|
pub detect_address_changes: bool,
|
||||||
pub ip6_prefix_size: usize,
|
pub ip6_prefix_size: usize,
|
||||||
|
pub require_inbound_relay: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash)]
|
||||||
|
@ -70,15 +71,18 @@ impl AddressCheck {
|
||||||
pub fn new(net: Network) -> Self {
|
pub fn new(net: Network) -> Self {
|
||||||
let registry = net.registry();
|
let registry = net.registry();
|
||||||
|
|
||||||
let (detect_address_changes, ip6_prefix_size) = registry.config().with(|c| {
|
let (detect_address_changes, ip6_prefix_size, require_inbound_relay) =
|
||||||
(
|
registry.config().with(|c| {
|
||||||
c.network.detect_address_changes,
|
(
|
||||||
c.network.max_connections_per_ip6_prefix_size as usize,
|
c.network.detect_address_changes,
|
||||||
)
|
c.network.max_connections_per_ip6_prefix_size as usize,
|
||||||
});
|
c.network.privacy.require_inbound_relay,
|
||||||
|
)
|
||||||
|
});
|
||||||
let config = AddressCheckConfig {
|
let config = AddressCheckConfig {
|
||||||
detect_address_changes,
|
detect_address_changes,
|
||||||
ip6_prefix_size,
|
ip6_prefix_size,
|
||||||
|
require_inbound_relay,
|
||||||
};
|
};
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
@ -202,6 +206,11 @@ impl AddressCheck {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Configured to only use relays for inbound connections. Thus, skip address detection.
|
||||||
|
if self.config.require_inbound_relay {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Process the state of the address checker and see if we need to
|
// Process the state of the address checker and see if we need to
|
||||||
// perform a full address check for this routing domain
|
// perform a full address check for this routing domain
|
||||||
let needs_address_detection = match peer_info.signed_node_info().node_info().network_class()
|
let needs_address_detection = match peer_info.signed_node_info().node_info().network_class()
|
||||||
|
@ -225,7 +234,7 @@ impl AddressCheck {
|
||||||
};
|
};
|
||||||
|
|
||||||
if needs_address_detection {
|
if needs_address_detection {
|
||||||
if self.config.detect_address_changes {
|
if self.config.detect_address_changes && !self.config.require_inbound_relay {
|
||||||
// Reset the address check cache now so we can start detecting fresh
|
// Reset the address check cache now so we can start detecting fresh
|
||||||
veilid_log!(self info
|
veilid_log!(self info
|
||||||
"{:?} address has changed, detecting dial info",
|
"{:?} address has changed, detecting dial info",
|
||||||
|
|
|
@ -17,7 +17,7 @@ const NEW_CONNECTION_RETRY_DELAY_MS: u32 = 500;
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum ConnectionManagerEvent {
|
enum ConnectionManagerEvent {
|
||||||
Accepted(ProtocolNetworkConnection),
|
Accepted(ProtocolNetworkConnection),
|
||||||
Dead(NetworkConnection),
|
Dead(Box<NetworkConnection>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -330,12 +330,16 @@ impl ConnectionManager {
|
||||||
// Send it to be terminated
|
// Send it to be terminated
|
||||||
#[cfg(feature = "verbose-tracing")]
|
#[cfg(feature = "verbose-tracing")]
|
||||||
veilid_log!(self debug "== LRU kill connection due to limit: {:?}", conn.debug_print(Timestamp::now()));
|
veilid_log!(self debug "== LRU kill connection due to limit: {:?}", conn.debug_print(Timestamp::now()));
|
||||||
let _ = inner.sender.send(ConnectionManagerEvent::Dead(conn));
|
let _ = inner
|
||||||
|
.sender
|
||||||
|
.send(ConnectionManagerEvent::Dead(Box::new(conn)));
|
||||||
}
|
}
|
||||||
Err(ConnectionTableAddError::AddressFilter(conn, e)) => {
|
Err(ConnectionTableAddError::AddressFilter(conn, e)) => {
|
||||||
// Connection filtered
|
// Connection filtered
|
||||||
let desc = conn.flow();
|
let desc = conn.flow();
|
||||||
let _ = inner.sender.send(ConnectionManagerEvent::Dead(conn));
|
let _ = inner
|
||||||
|
.sender
|
||||||
|
.send(ConnectionManagerEvent::Dead(Box::new(conn)));
|
||||||
return Ok(NetworkResult::no_connection_other(format!(
|
return Ok(NetworkResult::no_connection_other(format!(
|
||||||
"connection filtered: {:?} ({})",
|
"connection filtered: {:?} ({})",
|
||||||
desc, e
|
desc, e
|
||||||
|
@ -345,7 +349,9 @@ impl ConnectionManager {
|
||||||
// Connection already exists
|
// Connection already exists
|
||||||
let desc = conn.flow();
|
let desc = conn.flow();
|
||||||
veilid_log!(self debug "== Connection already exists: {:?}", conn.debug_print(Timestamp::now()));
|
veilid_log!(self debug "== Connection already exists: {:?}", conn.debug_print(Timestamp::now()));
|
||||||
let _ = inner.sender.send(ConnectionManagerEvent::Dead(conn));
|
let _ = inner
|
||||||
|
.sender
|
||||||
|
.send(ConnectionManagerEvent::Dead(Box::new(conn)));
|
||||||
return Ok(NetworkResult::no_connection_other(format!(
|
return Ok(NetworkResult::no_connection_other(format!(
|
||||||
"connection already exists: {:?}",
|
"connection already exists: {:?}",
|
||||||
desc
|
desc
|
||||||
|
@ -355,7 +361,9 @@ impl ConnectionManager {
|
||||||
// Connection table is full
|
// Connection table is full
|
||||||
let desc = conn.flow();
|
let desc = conn.flow();
|
||||||
veilid_log!(self debug "== Connection table full: {:?}", conn.debug_print(Timestamp::now()));
|
veilid_log!(self debug "== Connection table full: {:?}", conn.debug_print(Timestamp::now()));
|
||||||
let _ = inner.sender.send(ConnectionManagerEvent::Dead(conn));
|
let _ = inner
|
||||||
|
.sender
|
||||||
|
.send(ConnectionManagerEvent::Dead(Box::new(conn)));
|
||||||
return Ok(NetworkResult::no_connection_other(format!(
|
return Ok(NetworkResult::no_connection_other(format!(
|
||||||
"connection table is full: {:?}",
|
"connection table is full: {:?}",
|
||||||
desc
|
desc
|
||||||
|
@ -687,7 +695,7 @@ impl ConnectionManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let _ = sender.send(ConnectionManagerEvent::Dead(conn));
|
let _ = sender.send(ConnectionManagerEvent::Dead(Box::new(conn)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -884,7 +884,9 @@ impl DiscoveryContext {
|
||||||
// UPNP Automatic Mapping
|
// UPNP Automatic Mapping
|
||||||
///////////
|
///////////
|
||||||
|
|
||||||
let enable_upnp = self.config().with(|c| c.network.upnp);
|
let enable_upnp = self
|
||||||
|
.config()
|
||||||
|
.with(|c| c.network.upnp && !c.network.privacy.require_inbound_relay);
|
||||||
if enable_upnp {
|
if enable_upnp {
|
||||||
// Attempt a port mapping via all available and enabled mechanisms
|
// Attempt a port mapping via all available and enabled mechanisms
|
||||||
// Try this before the direct mapping in the event that we are restarting
|
// Try this before the direct mapping in the event that we are restarting
|
||||||
|
|
|
@ -768,7 +768,9 @@ impl Network {
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
|
||||||
let confirmed_public_internet = !self.config().with(|c| c.network.detect_address_changes);
|
let confirmed_public_internet = self
|
||||||
|
.config()
|
||||||
|
.with(|c| !c.network.detect_address_changes || c.network.privacy.require_inbound_relay);
|
||||||
editor_public_internet.setup_network(
|
editor_public_internet.setup_network(
|
||||||
network_state.protocol_config.outbound,
|
network_state.protocol_config.outbound,
|
||||||
network_state.protocol_config.inbound,
|
network_state.protocol_config.inbound,
|
||||||
|
@ -836,9 +838,18 @@ impl Network {
|
||||||
self.trigger_update_network_class(RoutingDomain::PublicInternet);
|
self.trigger_update_network_class(RoutingDomain::PublicInternet);
|
||||||
} else {
|
} else {
|
||||||
// Warn if we have no public dialinfo, because we're not going to magically find some
|
// Warn if we have no public dialinfo, because we're not going to magically find some
|
||||||
// with detect address changes turned off
|
// with detect_address_changes turned off. Skip the warning if require_inbound_relay is
|
||||||
|
// enabled, this option intentionally disables publishing any dialinfo.
|
||||||
let pi = routing_table.get_current_peer_info(RoutingDomain::PublicInternet);
|
let pi = routing_table.get_current_peer_info(RoutingDomain::PublicInternet);
|
||||||
if !pi.signed_node_info().has_any_dial_info() {
|
if !pi.signed_node_info().has_any_dial_info()
|
||||||
|
&& !self
|
||||||
|
.registry
|
||||||
|
.config()
|
||||||
|
.get()
|
||||||
|
.network
|
||||||
|
.privacy
|
||||||
|
.require_inbound_relay
|
||||||
|
{
|
||||||
veilid_log!(self warn
|
veilid_log!(self warn
|
||||||
"This node has no valid public dial info.\nConfigure this node with a static public IP address and correct firewall rules."
|
"This node has no valid public dial info.\nConfigure this node with a static public IP address and correct firewall rules."
|
||||||
);
|
);
|
||||||
|
|
|
@ -140,13 +140,15 @@ impl Network {
|
||||||
#[instrument(level = "trace", skip_all)]
|
#[instrument(level = "trace", skip_all)]
|
||||||
pub(super) async fn bind_udp_protocol_handlers(&self) -> EyreResult<StartupDisposition> {
|
pub(super) async fn bind_udp_protocol_handlers(&self) -> EyreResult<StartupDisposition> {
|
||||||
veilid_log!(self trace "UDP: binding protocol handlers");
|
veilid_log!(self trace "UDP: binding protocol handlers");
|
||||||
let (listen_address, public_address, detect_address_changes) = self.config().with(|c| {
|
let (listen_address, public_address, detect_address_changes, require_inbound_relay) =
|
||||||
(
|
self.config().with(|c| {
|
||||||
c.network.protocol.udp.listen_address.clone(),
|
(
|
||||||
c.network.protocol.udp.public_address.clone(),
|
c.network.protocol.udp.listen_address.clone(),
|
||||||
c.network.detect_address_changes,
|
c.network.protocol.udp.public_address.clone(),
|
||||||
)
|
c.network.detect_address_changes,
|
||||||
});
|
c.network.privacy.require_inbound_relay,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
// Get the binding parameters from the user-specified listen address
|
// Get the binding parameters from the user-specified listen address
|
||||||
let bind_set = self
|
let bind_set = self
|
||||||
|
@ -175,7 +177,7 @@ impl Network {
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut inner = self.inner.lock();
|
let mut inner = self.inner.lock();
|
||||||
if public_address.is_some() && !detect_address_changes {
|
if public_address.is_some() && !detect_address_changes && !require_inbound_relay {
|
||||||
inner.static_public_dial_info.insert(ProtocolType::UDP);
|
inner.static_public_dial_info.insert(ProtocolType::UDP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,12 +193,14 @@ impl Network {
|
||||||
) -> EyreResult<()> {
|
) -> EyreResult<()> {
|
||||||
veilid_log!(self trace "UDP: registering dial info");
|
veilid_log!(self trace "UDP: registering dial info");
|
||||||
|
|
||||||
let (public_address, detect_address_changes) = self.config().with(|c| {
|
let (public_address, detect_address_changes, require_inbound_relay) =
|
||||||
(
|
self.config().with(|c| {
|
||||||
c.network.protocol.udp.public_address.clone(),
|
(
|
||||||
c.network.detect_address_changes,
|
c.network.protocol.udp.public_address.clone(),
|
||||||
)
|
c.network.detect_address_changes,
|
||||||
});
|
c.network.privacy.require_inbound_relay,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
let local_dial_info_list = {
|
let local_dial_info_list = {
|
||||||
let mut out = vec![];
|
let mut out = vec![];
|
||||||
|
@ -220,7 +224,7 @@ impl Network {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add static public dialinfo if it's configured
|
// Add static public dialinfo if it's configured
|
||||||
if let Some(public_address) = public_address.as_ref() {
|
if let (Some(public_address), false) = (public_address.as_ref(), require_inbound_relay) {
|
||||||
// Resolve statically configured public dialinfo
|
// Resolve statically configured public dialinfo
|
||||||
let mut public_sockaddrs = public_address
|
let mut public_sockaddrs = public_address
|
||||||
.to_socket_addrs()
|
.to_socket_addrs()
|
||||||
|
@ -247,7 +251,11 @@ impl Network {
|
||||||
for di in &local_dial_info_list {
|
for di in &local_dial_info_list {
|
||||||
// If the local interface address is global, then register global dial info
|
// If the local interface address is global, then register global dial info
|
||||||
// if no other public address is specified
|
// if no other public address is specified
|
||||||
if !detect_address_changes && public_address.is_none() && di.address().is_global() {
|
if !detect_address_changes
|
||||||
|
&& !require_inbound_relay
|
||||||
|
&& public_address.is_none()
|
||||||
|
&& di.address().is_global()
|
||||||
|
{
|
||||||
editor_public_internet.add_dial_info(di.clone(), DialInfoClass::Direct);
|
editor_public_internet.add_dial_info(di.clone(), DialInfoClass::Direct);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,13 +269,15 @@ impl Network {
|
||||||
#[instrument(level = "trace", skip_all)]
|
#[instrument(level = "trace", skip_all)]
|
||||||
pub(super) async fn start_ws_listeners(&self) -> EyreResult<StartupDisposition> {
|
pub(super) async fn start_ws_listeners(&self) -> EyreResult<StartupDisposition> {
|
||||||
veilid_log!(self trace "WS: binding protocol handlers");
|
veilid_log!(self trace "WS: binding protocol handlers");
|
||||||
let (listen_address, url, detect_address_changes) = self.config().with(|c| {
|
let (listen_address, url, detect_address_changes, require_inbound_relay) =
|
||||||
(
|
self.config().with(|c| {
|
||||||
c.network.protocol.ws.listen_address.clone(),
|
(
|
||||||
c.network.protocol.ws.url.clone(),
|
c.network.protocol.ws.listen_address.clone(),
|
||||||
c.network.detect_address_changes,
|
c.network.protocol.ws.url.clone(),
|
||||||
)
|
c.network.detect_address_changes,
|
||||||
});
|
c.network.privacy.require_inbound_relay,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
// Get the binding parameters from the user-specified listen address
|
// Get the binding parameters from the user-specified listen address
|
||||||
let bind_set = self
|
let bind_set = self
|
||||||
|
@ -299,7 +309,7 @@ impl Network {
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut inner = self.inner.lock();
|
let mut inner = self.inner.lock();
|
||||||
if url.is_some() && !detect_address_changes {
|
if url.is_some() && !detect_address_changes && !require_inbound_relay {
|
||||||
inner.static_public_dial_info.insert(ProtocolType::WS);
|
inner.static_public_dial_info.insert(ProtocolType::WS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -314,11 +324,12 @@ impl Network {
|
||||||
editor_local_network: &mut RoutingDomainEditorLocalNetwork<'_>,
|
editor_local_network: &mut RoutingDomainEditorLocalNetwork<'_>,
|
||||||
) -> EyreResult<()> {
|
) -> EyreResult<()> {
|
||||||
veilid_log!(self trace "WS: registering dial info");
|
veilid_log!(self trace "WS: registering dial info");
|
||||||
let (url, path, detect_address_changes) = self.config().with(|c| {
|
let (url, path, detect_address_changes, require_inbound_relay) = self.config().with(|c| {
|
||||||
(
|
(
|
||||||
c.network.protocol.ws.url.clone(),
|
c.network.protocol.ws.url.clone(),
|
||||||
c.network.protocol.ws.path.clone(),
|
c.network.protocol.ws.path.clone(),
|
||||||
c.network.detect_address_changes,
|
c.network.detect_address_changes,
|
||||||
|
c.network.privacy.require_inbound_relay,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -389,7 +400,11 @@ impl Network {
|
||||||
let local_di =
|
let local_di =
|
||||||
DialInfo::try_ws(*socket_address, local_url).wrap_err("try_ws failed")?;
|
DialInfo::try_ws(*socket_address, local_url).wrap_err("try_ws failed")?;
|
||||||
|
|
||||||
if !detect_address_changes && url.is_none() && local_di.address().is_global() {
|
if !detect_address_changes
|
||||||
|
&& !require_inbound_relay
|
||||||
|
&& url.is_none()
|
||||||
|
&& local_di.address().is_global()
|
||||||
|
{
|
||||||
// Register public dial info
|
// Register public dial info
|
||||||
editor_public_internet.add_dial_info(local_di.clone(), DialInfoClass::Direct);
|
editor_public_internet.add_dial_info(local_di.clone(), DialInfoClass::Direct);
|
||||||
}
|
}
|
||||||
|
@ -405,13 +420,15 @@ impl Network {
|
||||||
pub(super) async fn start_wss_listeners(&self) -> EyreResult<StartupDisposition> {
|
pub(super) async fn start_wss_listeners(&self) -> EyreResult<StartupDisposition> {
|
||||||
veilid_log!(self trace "WSS: binding protocol handlers");
|
veilid_log!(self trace "WSS: binding protocol handlers");
|
||||||
|
|
||||||
let (listen_address, url, detect_address_changes) = self.config().with(|c| {
|
let (listen_address, url, detect_address_changes, require_inbound_relay) =
|
||||||
(
|
self.config().with(|c| {
|
||||||
c.network.protocol.wss.listen_address.clone(),
|
(
|
||||||
c.network.protocol.wss.url.clone(),
|
c.network.protocol.wss.listen_address.clone(),
|
||||||
c.network.detect_address_changes,
|
c.network.protocol.wss.url.clone(),
|
||||||
)
|
c.network.detect_address_changes,
|
||||||
});
|
c.network.privacy.require_inbound_relay,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
// Get the binding parameters from the user-specified listen address
|
// Get the binding parameters from the user-specified listen address
|
||||||
let bind_set = self
|
let bind_set = self
|
||||||
|
@ -444,7 +461,7 @@ impl Network {
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut inner = self.inner.lock();
|
let mut inner = self.inner.lock();
|
||||||
if url.is_some() && !detect_address_changes {
|
if url.is_some() && !detect_address_changes && !require_inbound_relay {
|
||||||
inner.static_public_dial_info.insert(ProtocolType::WSS);
|
inner.static_public_dial_info.insert(ProtocolType::WSS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -514,13 +531,15 @@ impl Network {
|
||||||
pub(super) async fn start_tcp_listeners(&self) -> EyreResult<StartupDisposition> {
|
pub(super) async fn start_tcp_listeners(&self) -> EyreResult<StartupDisposition> {
|
||||||
veilid_log!(self trace "TCP: binding protocol handlers");
|
veilid_log!(self trace "TCP: binding protocol handlers");
|
||||||
|
|
||||||
let (listen_address, public_address, detect_address_changes) = self.config().with(|c| {
|
let (listen_address, public_address, detect_address_changes, require_inbound_relay) =
|
||||||
(
|
self.config().with(|c| {
|
||||||
c.network.protocol.tcp.listen_address.clone(),
|
(
|
||||||
c.network.protocol.tcp.public_address.clone(),
|
c.network.protocol.tcp.listen_address.clone(),
|
||||||
c.network.detect_address_changes,
|
c.network.protocol.tcp.public_address.clone(),
|
||||||
)
|
c.network.detect_address_changes,
|
||||||
});
|
c.network.privacy.require_inbound_relay,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
// Get the binding parameters from the user-specified listen address
|
// Get the binding parameters from the user-specified listen address
|
||||||
let bind_set = self
|
let bind_set = self
|
||||||
|
@ -552,7 +571,7 @@ impl Network {
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut inner = self.inner.lock();
|
let mut inner = self.inner.lock();
|
||||||
if public_address.is_some() && !detect_address_changes {
|
if public_address.is_some() && !detect_address_changes && !require_inbound_relay {
|
||||||
inner.static_public_dial_info.insert(ProtocolType::TCP);
|
inner.static_public_dial_info.insert(ProtocolType::TCP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -568,12 +587,14 @@ impl Network {
|
||||||
) -> EyreResult<()> {
|
) -> EyreResult<()> {
|
||||||
veilid_log!(self trace "TCP: registering dialinfo");
|
veilid_log!(self trace "TCP: registering dialinfo");
|
||||||
|
|
||||||
let (public_address, detect_address_changes) = self.config().with(|c| {
|
let (public_address, detect_address_changes, require_inbound_relay) =
|
||||||
(
|
self.config().with(|c| {
|
||||||
c.network.protocol.tcp.public_address.clone(),
|
(
|
||||||
c.network.detect_address_changes,
|
c.network.protocol.tcp.public_address.clone(),
|
||||||
)
|
c.network.detect_address_changes,
|
||||||
});
|
c.network.privacy.require_inbound_relay,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
let mut registered_addresses: HashSet<IpAddr> = HashSet::new();
|
let mut registered_addresses: HashSet<IpAddr> = HashSet::new();
|
||||||
|
|
||||||
|
@ -602,7 +623,7 @@ impl Network {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add static public dialinfo if it's configured
|
// Add static public dialinfo if it's configured
|
||||||
if let Some(public_address) = public_address.as_ref() {
|
if let (Some(public_address), false) = (public_address.as_ref(), require_inbound_relay) {
|
||||||
// Resolve statically configured public dialinfo
|
// Resolve statically configured public dialinfo
|
||||||
let mut public_sockaddrs = public_address
|
let mut public_sockaddrs = public_address
|
||||||
.to_socket_addrs()
|
.to_socket_addrs()
|
||||||
|
@ -629,7 +650,11 @@ impl Network {
|
||||||
let di = DialInfo::tcp(*socket_address);
|
let di = DialInfo::tcp(*socket_address);
|
||||||
|
|
||||||
// Register global dial info if no public address is specified
|
// Register global dial info if no public address is specified
|
||||||
if !detect_address_changes && public_address.is_none() && di.address().is_global() {
|
if !detect_address_changes
|
||||||
|
&& !require_inbound_relay
|
||||||
|
&& public_address.is_none()
|
||||||
|
&& di.address().is_global()
|
||||||
|
{
|
||||||
editor_public_internet.add_dial_info(di.clone(), DialInfoClass::Direct);
|
editor_public_internet.add_dial_info(di.clone(), DialInfoClass::Direct);
|
||||||
}
|
}
|
||||||
// Register interface dial info
|
// Register interface dial info
|
||||||
|
|
|
@ -87,12 +87,22 @@ impl Network {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let (detect_address_changes, upnp) = {
|
let (detect_address_changes, upnp, require_inbound_relay) = {
|
||||||
let config = self.network_manager().config();
|
let config = self.network_manager().config();
|
||||||
let c = config.get();
|
let c = config.get();
|
||||||
(c.network.detect_address_changes, c.network.upnp)
|
(
|
||||||
|
c.network.detect_address_changes,
|
||||||
|
c.network.upnp,
|
||||||
|
c.network.privacy.require_inbound_relay,
|
||||||
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if require_inbound_relay {
|
||||||
|
// Configured to only use relays for inbound connections.
|
||||||
|
// This implicitly turns off address detection and upnp.
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
// If we need to figure out our network class, tick the task for it
|
// If we need to figure out our network class, tick the task for it
|
||||||
if detect_address_changes {
|
if detect_address_changes {
|
||||||
// Check our network interfaces to see if they have changed
|
// Check our network interfaces to see if they have changed
|
||||||
|
|
|
@ -287,60 +287,46 @@ impl RouteSpecStore {
|
||||||
let geolocation_info =
|
let geolocation_info =
|
||||||
sni.get_geolocation_info(RoutingDomain::PublicInternet);
|
sni.get_geolocation_info(RoutingDomain::PublicInternet);
|
||||||
|
|
||||||
// Since denylist is used, consider nodes with unknown countries to be automatically
|
// Since denylist is used, consider nodes with unknown countries to be automatically excluded
|
||||||
// excluded as well
|
let Some(node_country_code) = geolocation_info.country_code() else {
|
||||||
if geolocation_info.country_code().is_none() {
|
|
||||||
veilid_log!(self
|
veilid_log!(self
|
||||||
debug "allocate_route_inner: skipping node {} from unknown country",
|
debug "allocate_route_inner: skipping node {:?} from unknown country",
|
||||||
e.best_node_id()
|
e.best_node_id()
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
};
|
||||||
// Same thing applies to relays used by the node
|
// The same thing applies to relays used by the node
|
||||||
if geolocation_info
|
// They must all be from a known country
|
||||||
.relay_country_codes()
|
let relay_country_codes: Option<Vec<CountryCode>> = geolocation_info.relay_country_codes().iter().cloned().collect();
|
||||||
.iter()
|
let Some(relay_country_codes) = relay_country_codes else {
|
||||||
.any(Option::is_none)
|
|
||||||
{
|
|
||||||
veilid_log!(self
|
veilid_log!(self
|
||||||
debug "allocate_route_inner: skipping node {} using relay from unknown country",
|
debug "allocate_route_inner: skipping node {:?} using relay from unknown country",
|
||||||
e.best_node_id()
|
e.best_node_id()
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
};
|
||||||
|
|
||||||
// Ensure that node is not excluded
|
// Ensure that node is not excluded
|
||||||
// Safe to unwrap here, checked above
|
if country_code_denylist.contains(&node_country_code)
|
||||||
if country_code_denylist.contains(&geolocation_info.country_code().unwrap())
|
|
||||||
{
|
{
|
||||||
veilid_log!(self
|
veilid_log!(self
|
||||||
debug "allocate_route_inner: skipping node {} from excluded country {}",
|
debug "allocate_route_inner: skipping node {:?} from excluded country {}",
|
||||||
e.best_node_id(),
|
e.best_node_id(),
|
||||||
geolocation_info.country_code().unwrap()
|
node_country_code
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that node relays are not excluded
|
// Ensure that node relays are not excluded
|
||||||
// Safe to unwrap here, checked above
|
if let Some(cc) = relay_country_codes
|
||||||
if geolocation_info
|
|
||||||
.relay_country_codes()
|
|
||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.filter(|cc| country_code_denylist.contains(cc))
|
||||||
.map(Option::unwrap)
|
.next()
|
||||||
.any(|cc| country_code_denylist.contains(&cc))
|
|
||||||
{
|
{
|
||||||
veilid_log!(self
|
veilid_log!(self
|
||||||
debug "allocate_route_inner: skipping node {} using relay from excluded country {:?}",
|
debug "allocate_route_inner: skipping node {:?} using relay from excluded country {}",
|
||||||
e.best_node_id(),
|
e.best_node_id(),
|
||||||
geolocation_info
|
cc
|
||||||
.relay_country_codes()
|
|
||||||
.iter()
|
|
||||||
.cloned()
|
|
||||||
.map(Option::unwrap)
|
|
||||||
.filter(|cc| country_code_denylist.contains(&cc))
|
|
||||||
.next()
|
|
||||||
.unwrap()
|
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,11 +178,9 @@ impl TableDB {
|
||||||
&Nonce::try_from(&data[0..NONCE_LENGTH]).unwrap(),
|
&Nonce::try_from(&data[0..NONCE_LENGTH]).unwrap(),
|
||||||
&di.typed_key.value,
|
&di.typed_key.value,
|
||||||
);
|
);
|
||||||
decompress_size_prepended(&out, None)
|
decompress_size_prepended(&out, None).map_err(|e| std::io::Error::other(e.to_string()))
|
||||||
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))
|
|
||||||
} else {
|
} else {
|
||||||
decompress_size_prepended(data, None)
|
decompress_size_prepended(data, None).map_err(|e| std::io::Error::other(e.to_string()))
|
||||||
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -289,6 +289,7 @@ pub fn config_callback(key: String) -> ConfigCallbackReturn {
|
||||||
"network.protocol.wss.listen_address" => Ok(Box::new("".to_owned())),
|
"network.protocol.wss.listen_address" => Ok(Box::new("".to_owned())),
|
||||||
"network.protocol.wss.path" => Ok(Box::new(String::from("ws"))),
|
"network.protocol.wss.path" => Ok(Box::new(String::from("ws"))),
|
||||||
"network.protocol.wss.url" => Ok(Box::new(Option::<String>::None)),
|
"network.protocol.wss.url" => Ok(Box::new(Option::<String>::None)),
|
||||||
|
"network.privacy.require_inbound_relay" => Ok(Box::new(false)),
|
||||||
#[cfg(feature = "geolocation")]
|
#[cfg(feature = "geolocation")]
|
||||||
"network.privacy.country_code_denylist" => Ok(Box::new(Vec::<CountryCode>::new())),
|
"network.privacy.country_code_denylist" => Ok(Box::new(Vec::<CountryCode>::new())),
|
||||||
#[cfg(feature = "virtual-network")]
|
#[cfg(feature = "virtual-network")]
|
||||||
|
@ -436,6 +437,7 @@ pub fn test_config() {
|
||||||
assert_eq!(inner.network.protocol.wss.path, "ws");
|
assert_eq!(inner.network.protocol.wss.path, "ws");
|
||||||
assert_eq!(inner.network.protocol.wss.url, None);
|
assert_eq!(inner.network.protocol.wss.url, None);
|
||||||
|
|
||||||
|
assert!(!inner.network.privacy.require_inbound_relay);
|
||||||
#[cfg(feature = "geolocation")]
|
#[cfg(feature = "geolocation")]
|
||||||
assert_eq!(inner.network.privacy.country_code_denylist, Vec::new());
|
assert_eq!(inner.network.privacy.country_code_denylist, Vec::new());
|
||||||
#[cfg(feature = "virtual-network")]
|
#[cfg(feature = "virtual-network")]
|
||||||
|
|
|
@ -280,8 +280,9 @@ pub fn fix_veilidconfig() -> VeilidConfig {
|
||||||
url: Some("https://veilid.com/wss".to_string()),
|
url: Some("https://veilid.com/wss".to_string()),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
#[cfg(feature = "geolocation")]
|
|
||||||
privacy: VeilidConfigPrivacy {
|
privacy: VeilidConfigPrivacy {
|
||||||
|
require_inbound_relay: false,
|
||||||
|
#[cfg(feature = "geolocation")]
|
||||||
country_code_denylist: vec![CountryCode::from_str("NZ").unwrap()],
|
country_code_denylist: vec![CountryCode::from_str("NZ").unwrap()],
|
||||||
},
|
},
|
||||||
#[cfg(feature = "virtual-network")]
|
#[cfg(feature = "virtual-network")]
|
||||||
|
|
|
@ -285,25 +285,18 @@ pub struct VeilidConfigProtocol {
|
||||||
///
|
///
|
||||||
/// ```yaml
|
/// ```yaml
|
||||||
/// privacy:
|
/// privacy:
|
||||||
/// country_code_denylist: []
|
/// require_inbound_relay: false
|
||||||
|
/// country_code_denylist: [] # only with `--features=geolocation`
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg(feature = "geolocation")]
|
#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
|
||||||
#[cfg_attr(target_arch = "wasm32", derive(Tsify))]
|
#[cfg_attr(target_arch = "wasm32", derive(Tsify))]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub struct VeilidConfigPrivacy {
|
pub struct VeilidConfigPrivacy {
|
||||||
|
pub require_inbound_relay: bool,
|
||||||
|
#[cfg(feature = "geolocation")]
|
||||||
pub country_code_denylist: Vec<CountryCode>,
|
pub country_code_denylist: Vec<CountryCode>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "geolocation")]
|
|
||||||
impl Default for VeilidConfigPrivacy {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
country_code_denylist: Vec::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Virtual networking client support for testing/simulation purposes
|
/// Virtual networking client support for testing/simulation purposes
|
||||||
///
|
///
|
||||||
/// ```yaml
|
/// ```yaml
|
||||||
|
@ -568,7 +561,6 @@ pub struct VeilidConfigNetwork {
|
||||||
pub tls: VeilidConfigTLS,
|
pub tls: VeilidConfigTLS,
|
||||||
pub application: VeilidConfigApplication,
|
pub application: VeilidConfigApplication,
|
||||||
pub protocol: VeilidConfigProtocol,
|
pub protocol: VeilidConfigProtocol,
|
||||||
#[cfg(feature = "geolocation")]
|
|
||||||
pub privacy: VeilidConfigPrivacy,
|
pub privacy: VeilidConfigPrivacy,
|
||||||
#[cfg(feature = "virtual-network")]
|
#[cfg(feature = "virtual-network")]
|
||||||
pub virtual_network: VeilidConfigVirtualNetwork,
|
pub virtual_network: VeilidConfigVirtualNetwork,
|
||||||
|
@ -596,7 +588,6 @@ impl Default for VeilidConfigNetwork {
|
||||||
tls: VeilidConfigTLS::default(),
|
tls: VeilidConfigTLS::default(),
|
||||||
application: VeilidConfigApplication::default(),
|
application: VeilidConfigApplication::default(),
|
||||||
protocol: VeilidConfigProtocol::default(),
|
protocol: VeilidConfigProtocol::default(),
|
||||||
#[cfg(feature = "geolocation")]
|
|
||||||
privacy: VeilidConfigPrivacy::default(),
|
privacy: VeilidConfigPrivacy::default(),
|
||||||
#[cfg(feature = "virtual-network")]
|
#[cfg(feature = "virtual-network")]
|
||||||
virtual_network: VeilidConfigVirtualNetwork::default(),
|
virtual_network: VeilidConfigVirtualNetwork::default(),
|
||||||
|
@ -1049,6 +1040,7 @@ impl VeilidStartupOptions {
|
||||||
get_config!(inner.network.protocol.wss.listen_address);
|
get_config!(inner.network.protocol.wss.listen_address);
|
||||||
get_config!(inner.network.protocol.wss.path);
|
get_config!(inner.network.protocol.wss.path);
|
||||||
get_config!(inner.network.protocol.wss.url);
|
get_config!(inner.network.protocol.wss.url);
|
||||||
|
get_config!(inner.network.privacy.require_inbound_relay);
|
||||||
#[cfg(feature = "geolocation")]
|
#[cfg(feature = "geolocation")]
|
||||||
get_config!(inner.network.privacy.country_code_denylist);
|
get_config!(inner.network.privacy.country_code_denylist);
|
||||||
#[cfg(feature = "virtual-network")]
|
#[cfg(feature = "virtual-network")]
|
||||||
|
|
|
@ -189,6 +189,11 @@ class VeilidConfigProtocol(ConfigBase):
|
||||||
wss: VeilidConfigWSS
|
wss: VeilidConfigWSS
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class VeilidConfigPrivacy(ConfigBase):
|
||||||
|
require_inbound_relay: bool
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class VeilidConfigNetwork(ConfigBase):
|
class VeilidConfigNetwork(ConfigBase):
|
||||||
connection_initial_timeout_ms: int
|
connection_initial_timeout_ms: int
|
||||||
|
@ -210,6 +215,7 @@ class VeilidConfigNetwork(ConfigBase):
|
||||||
tls: VeilidConfigTLS
|
tls: VeilidConfigTLS
|
||||||
application: VeilidConfigApplication
|
application: VeilidConfigApplication
|
||||||
protocol: VeilidConfigProtocol
|
protocol: VeilidConfigProtocol
|
||||||
|
privacy: VeilidConfigPrivacy
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|
|
@ -4267,6 +4267,7 @@
|
||||||
"max_connections_per_ip4",
|
"max_connections_per_ip4",
|
||||||
"max_connections_per_ip6_prefix",
|
"max_connections_per_ip6_prefix",
|
||||||
"max_connections_per_ip6_prefix_size",
|
"max_connections_per_ip6_prefix_size",
|
||||||
|
"privacy",
|
||||||
"protocol",
|
"protocol",
|
||||||
"restricted_nat_retries",
|
"restricted_nat_retries",
|
||||||
"reverse_connection_receipt_time_ms",
|
"reverse_connection_receipt_time_ms",
|
||||||
|
@ -4331,6 +4332,9 @@
|
||||||
"null"
|
"null"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"privacy": {
|
||||||
|
"$ref": "#/definitions/VeilidConfigPrivacy"
|
||||||
|
},
|
||||||
"protocol": {
|
"protocol": {
|
||||||
"$ref": "#/definitions/VeilidConfigProtocol"
|
"$ref": "#/definitions/VeilidConfigProtocol"
|
||||||
},
|
},
|
||||||
|
@ -4358,6 +4362,18 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"VeilidConfigPrivacy": {
|
||||||
|
"description": "Privacy preferences for routes.\n\n```yaml privacy: require_inbound_relay: false country_code_denylist: [] # only with `--features=geolocation` ```",
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"require_inbound_relay"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"require_inbound_relay": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"VeilidConfigProtectedStore": {
|
"VeilidConfigProtectedStore": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
|
|
|
@ -35,10 +35,9 @@ pub const PROGRAM_NAME: &str = "veilid-server";
|
||||||
|
|
||||||
pub fn load_default_config() -> EyreResult<config::Config> {
|
pub fn load_default_config() -> EyreResult<config::Config> {
|
||||||
#[cfg(not(feature = "geolocation"))]
|
#[cfg(not(feature = "geolocation"))]
|
||||||
let privacy_section = "";
|
let privacy_geolocation_section = "";
|
||||||
#[cfg(feature = "geolocation")]
|
#[cfg(feature = "geolocation")]
|
||||||
let privacy_section = r#"
|
let privacy_geolocation_section = r#"
|
||||||
privacy:
|
|
||||||
country_code_denylist: []
|
country_code_denylist: []
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
|
@ -224,8 +223,10 @@ core:
|
||||||
listen_address: ':5150'
|
listen_address: ':5150'
|
||||||
path: 'ws'
|
path: 'ws'
|
||||||
# url: ''
|
# url: ''
|
||||||
|
privacy:
|
||||||
|
require_inbound_relay: false
|
||||||
|
%PRIVACY_GEOLOCATION_SECTION%
|
||||||
%VIRTUAL_NETWORK_SECTION%
|
%VIRTUAL_NETWORK_SECTION%
|
||||||
%PRIVACY_SECTION%
|
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.replace(
|
.replace(
|
||||||
|
@ -256,7 +257,7 @@ core:
|
||||||
"%REMOTE_MAX_SUBKEY_CACHE_MEMORY_MB%",
|
"%REMOTE_MAX_SUBKEY_CACHE_MEMORY_MB%",
|
||||||
&Settings::get_default_remote_max_subkey_cache_memory_mb().to_string(),
|
&Settings::get_default_remote_max_subkey_cache_memory_mb().to_string(),
|
||||||
)
|
)
|
||||||
.replace("%PRIVACY_SECTION%", privacy_section)
|
.replace("%PRIVACY_GEOLOCATION_SECTION%", privacy_geolocation_section)
|
||||||
.replace("%VIRTUAL_NETWORK_SECTION%", virtual_network_section)
|
.replace("%VIRTUAL_NETWORK_SECTION%", virtual_network_section)
|
||||||
.replace(
|
.replace(
|
||||||
"%VIRTUAL_NETWORK_SERVER_SECTION%",
|
"%VIRTUAL_NETWORK_SERVER_SECTION%",
|
||||||
|
@ -646,9 +647,10 @@ pub struct Protocol {
|
||||||
pub wss: Wss,
|
pub wss: Wss,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "geolocation")]
|
|
||||||
#[derive(Debug, Deserialize, Serialize)]
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
pub struct Privacy {
|
pub struct Privacy {
|
||||||
|
pub require_inbound_relay: bool,
|
||||||
|
#[cfg(feature = "geolocation")]
|
||||||
pub country_code_denylist: Vec<CountryCode>,
|
pub country_code_denylist: Vec<CountryCode>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -730,7 +732,6 @@ pub struct Network {
|
||||||
pub tls: Tls,
|
pub tls: Tls,
|
||||||
pub application: Application,
|
pub application: Application,
|
||||||
pub protocol: Protocol,
|
pub protocol: Protocol,
|
||||||
#[cfg(feature = "geolocation")]
|
|
||||||
pub privacy: Privacy,
|
pub privacy: Privacy,
|
||||||
#[cfg(feature = "virtual-network")]
|
#[cfg(feature = "virtual-network")]
|
||||||
pub virtual_network: VirtualNetwork,
|
pub virtual_network: VirtualNetwork,
|
||||||
|
@ -1252,6 +1253,7 @@ impl Settings {
|
||||||
set_config_value!(inner.core.network.protocol.wss.listen_address, value);
|
set_config_value!(inner.core.network.protocol.wss.listen_address, value);
|
||||||
set_config_value!(inner.core.network.protocol.wss.path, value);
|
set_config_value!(inner.core.network.protocol.wss.path, value);
|
||||||
set_config_value!(inner.core.network.protocol.wss.url, value);
|
set_config_value!(inner.core.network.protocol.wss.url, value);
|
||||||
|
set_config_value!(inner.core.network.privacy.require_inbound_relay, value);
|
||||||
#[cfg(feature = "geolocation")]
|
#[cfg(feature = "geolocation")]
|
||||||
set_config_value!(inner.core.network.privacy.country_code_denylist, value);
|
set_config_value!(inner.core.network.privacy.country_code_denylist, value);
|
||||||
#[cfg(feature = "virtual-network")]
|
#[cfg(feature = "virtual-network")]
|
||||||
|
@ -1689,6 +1691,9 @@ impl Settings {
|
||||||
None => None,
|
None => None,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
"network.privacy.require_inbound_relay" => {
|
||||||
|
Ok(Box::new(inner.core.network.privacy.require_inbound_relay))
|
||||||
|
}
|
||||||
#[cfg(feature = "geolocation")]
|
#[cfg(feature = "geolocation")]
|
||||||
"network.privacy.country_code_denylist" => Ok(Box::new(
|
"network.privacy.country_code_denylist" => Ok(Box::new(
|
||||||
inner.core.network.privacy.country_code_denylist.clone(),
|
inner.core.network.privacy.country_code_denylist.clone(),
|
||||||
|
@ -1981,6 +1986,7 @@ mod tests {
|
||||||
);
|
);
|
||||||
assert_eq!(s.core.network.protocol.wss.url, None);
|
assert_eq!(s.core.network.protocol.wss.url, None);
|
||||||
//
|
//
|
||||||
|
assert_eq!(s.core.network.privacy.require_inbound_relay, false);
|
||||||
#[cfg(feature = "geolocation")]
|
#[cfg(feature = "geolocation")]
|
||||||
assert_eq!(s.core.network.privacy.country_code_denylist, &[]);
|
assert_eq!(s.core.network.privacy.country_code_denylist, &[]);
|
||||||
#[cfg(feature = "virtual-network")]
|
#[cfg(feature = "virtual-network")]
|
||||||
|
|
|
@ -157,11 +157,7 @@ impl AsyncRead for AsyncPeekStream {
|
||||||
//
|
//
|
||||||
let buflen = buf.len();
|
let buflen = buf.len();
|
||||||
let bufcopylen = core::cmp::min(buflen, inner.peekbuf_len);
|
let bufcopylen = core::cmp::min(buflen, inner.peekbuf_len);
|
||||||
let bufreadlen = if buflen > inner.peekbuf_len {
|
let bufreadlen = buflen.saturating_sub(inner.peekbuf_len);
|
||||||
buflen - inner.peekbuf_len
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
if bufreadlen > 0 {
|
if bufreadlen > 0 {
|
||||||
match Pin::new(&mut inner.stream).poll_read(cx, &mut buf[bufcopylen..buflen]) {
|
match Pin::new(&mut inner.stream).poll_read(cx, &mut buf[bufcopylen..buflen]) {
|
||||||
|
|
|
@ -131,7 +131,7 @@ impl<T> NetworkResult<T> {
|
||||||
Self::NoConnection(e)
|
Self::NoConnection(e)
|
||||||
}
|
}
|
||||||
pub fn no_connection_other<S: ToString>(s: S) -> Self {
|
pub fn no_connection_other<S: ToString>(s: S) -> Self {
|
||||||
Self::NoConnection(io::Error::new(io::ErrorKind::Other, s.to_string()))
|
Self::NoConnection(io::Error::other(s.to_string()))
|
||||||
}
|
}
|
||||||
pub fn invalid_message<S: ToString>(s: S) -> Self {
|
pub fn invalid_message<S: ToString>(s: S) -> Self {
|
||||||
Self::InvalidMessage(s.to_string())
|
Self::InvalidMessage(s.to_string())
|
||||||
|
|
|
@ -22,7 +22,7 @@ macro_rules! io_error_other {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_io_error_other<E: std::error::Error + Send + Sync + 'static>(x: E) -> io::Error {
|
pub fn to_io_error_other<E: std::error::Error + Send + Sync + 'static>(x: E) -> io::Error {
|
||||||
io::Error::new(io::ErrorKind::Other, x)
|
io::Error::other(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue