refactor checkpoint
This commit is contained in:
@@ -66,6 +66,7 @@ struct NetworkUnlockedInner {
|
||||
// Background processes
|
||||
update_udpv4_dialinfo_task: TickTask,
|
||||
update_tcpv4_dialinfo_task: TickTask,
|
||||
update_wsv4_dialinfo_task: TickTask,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -107,6 +108,7 @@ impl Network {
|
||||
NetworkUnlockedInner {
|
||||
update_udpv4_dialinfo_task: TickTask::new(1),
|
||||
update_tcpv4_dialinfo_task: TickTask::new(1),
|
||||
update_wsv4_dialinfo_task: TickTask::new(1),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,6 +137,15 @@ impl Network {
|
||||
Box::pin(this2.clone().update_tcpv4_dialinfo_task_routine(l, t))
|
||||
});
|
||||
}
|
||||
// Set ws dialinfo tick task
|
||||
{
|
||||
let this2 = this.clone();
|
||||
this.unlocked_inner
|
||||
.update_wsv4_dialinfo_task
|
||||
.set_routine(move |l, t| {
|
||||
Box::pin(this2.clone().update_wsv4_dialinfo_task_routine(l, t))
|
||||
});
|
||||
}
|
||||
|
||||
this
|
||||
}
|
||||
@@ -289,7 +300,7 @@ impl Network {
|
||||
res
|
||||
}
|
||||
|
||||
async fn send_data_to_existing_connection(
|
||||
pub async fn send_data_to_existing_connection(
|
||||
&self,
|
||||
descriptor: ConnectionDescriptor,
|
||||
data: Vec<u8>,
|
||||
@@ -380,41 +391,6 @@ impl Network {
|
||||
res
|
||||
}
|
||||
|
||||
// Send data to node
|
||||
// We may not have dial info for a node, but have an existing connection for it
|
||||
// because an inbound connection happened first, and no FindNodeQ has happened to that
|
||||
// node yet to discover its dial info. The existing connection should be tried first
|
||||
// in this case.
|
||||
pub async fn send_data(&self, node_ref: NodeRef, data: Vec<u8>) -> Result<(), String> {
|
||||
// First try to send data to the last socket we've seen this peer on
|
||||
let data = if let Some(descriptor) = node_ref.last_connection() {
|
||||
match self
|
||||
.clone()
|
||||
.send_data_to_existing_connection(descriptor, data)
|
||||
.await
|
||||
.map_err(logthru_net!())?
|
||||
{
|
||||
None => {
|
||||
return Ok(());
|
||||
}
|
||||
Some(d) => d,
|
||||
}
|
||||
} else {
|
||||
data
|
||||
};
|
||||
|
||||
// If that fails, try to make a connection or reach out to the peer via its dial info
|
||||
let node_info = node_ref
|
||||
.best_node_info()
|
||||
.ok_or_else(|| "couldn't send data, no dial info or peer address".to_owned())?;
|
||||
|
||||
xxx write logic to determine if a relay needs to be used first xxx
|
||||
|
||||
self.send_data_to_dial_info(dial_info, data)
|
||||
.await
|
||||
.map_err(logthru_net!())
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
pub fn get_protocol_config(&self) -> Option<ProtocolConfig> {
|
||||
@@ -433,28 +409,33 @@ impl Network {
|
||||
let protocol_config = {
|
||||
let c = self.config.get();
|
||||
ProtocolConfig {
|
||||
udp_enabled: c.network.protocol.udp.enabled && c.capabilities.protocol_udp,
|
||||
tcp_connect: c.network.protocol.tcp.connect && c.capabilities.protocol_connect_tcp,
|
||||
tcp_listen: c.network.protocol.tcp.listen && c.capabilities.protocol_accept_tcp,
|
||||
ws_connect: c.network.protocol.ws.connect && c.capabilities.protocol_connect_ws,
|
||||
ws_listen: c.network.protocol.ws.listen && c.capabilities.protocol_accept_ws,
|
||||
wss_connect: c.network.protocol.wss.connect && c.capabilities.protocol_connect_wss,
|
||||
wss_listen: c.network.protocol.wss.listen && c.capabilities.protocol_accept_wss,
|
||||
inbound: ProtocolSet {
|
||||
udp: c.network.protocol.udp.enabled && c.capabilities.protocol_udp,
|
||||
tcp: c.network.protocol.tcp.listen && c.capabilities.protocol_accept_tcp,
|
||||
ws: c.network.protocol.ws.listen && c.capabilities.protocol_accept_ws,
|
||||
wss: c.network.protocol.wss.listen && c.capabilities.protocol_accept_wss,
|
||||
},
|
||||
outbound: ProtocolSet {
|
||||
udp: c.network.protocol.udp.enabled && c.capabilities.protocol_udp,
|
||||
tcp: c.network.protocol.tcp.connect && c.capabilities.protocol_connect_tcp,
|
||||
ws: c.network.protocol.ws.connect && c.capabilities.protocol_connect_ws,
|
||||
wss: c.network.protocol.wss.connect && c.capabilities.protocol_connect_wss,
|
||||
},
|
||||
}
|
||||
};
|
||||
self.inner.lock().protocol_config = Some(protocol_config);
|
||||
|
||||
// start listeners
|
||||
if protocol_config.udp_enabled {
|
||||
if protocol_config.inbound.udp {
|
||||
self.start_udp_listeners().await?;
|
||||
}
|
||||
if protocol_config.ws_listen {
|
||||
if protocol_config.inbound.ws {
|
||||
self.start_ws_listeners().await?;
|
||||
}
|
||||
if protocol_config.wss_listen {
|
||||
if protocol_config.inbound.wss {
|
||||
self.start_wss_listeners().await?;
|
||||
}
|
||||
if protocol_config.tcp_listen {
|
||||
if protocol_config.inbound.tcp {
|
||||
self.start_tcp_listeners().await?;
|
||||
}
|
||||
|
||||
@@ -503,7 +484,7 @@ impl Network {
|
||||
|
||||
// Go through our global dialinfo and see what our best network class is
|
||||
let mut network_class = NetworkClass::Invalid;
|
||||
for did in inner.routing_table.global_dial_info_details() {
|
||||
for did in inner.routing_table.public_dial_info_details() {
|
||||
if let Some(nc) = did.network_class {
|
||||
if nc < network_class {
|
||||
network_class = nc;
|
||||
@@ -521,6 +502,7 @@ impl Network {
|
||||
protocol_config,
|
||||
udp_static_public_dialinfo,
|
||||
tcp_static_public_dialinfo,
|
||||
ws_static_public_dialinfo,
|
||||
network_class,
|
||||
) = {
|
||||
let inner = self.inner.lock();
|
||||
@@ -529,6 +511,7 @@ impl Network {
|
||||
inner.protocol_config.unwrap_or_default(),
|
||||
inner.udp_static_public_dialinfo,
|
||||
inner.tcp_static_public_dialinfo,
|
||||
inner.ws_static_public_dialinfo,
|
||||
inner.network_class.unwrap_or(NetworkClass::Invalid),
|
||||
)
|
||||
};
|
||||
@@ -538,15 +521,15 @@ impl Network {
|
||||
// If we can have public dialinfo, or we haven't figured out our network class yet,
|
||||
// and we're active for UDP, we should attempt to get our public dialinfo sorted out
|
||||
// and assess our network class if we haven't already
|
||||
if protocol_config.udp_enabled
|
||||
if protocol_config.inbound.udp
|
||||
&& !udp_static_public_dialinfo
|
||||
&& (network_class.inbound_capable() || network_class == NetworkClass::Invalid)
|
||||
{
|
||||
let filter = DialInfoFilter::global()
|
||||
let filter = DialInfoFilter::all()
|
||||
.with_protocol_type(ProtocolType::UDP)
|
||||
.with_address_type(AddressType::IPV4);
|
||||
let need_udpv4_dialinfo = routing_table
|
||||
.first_filtered_dial_info_detail(&filter)
|
||||
.first_public_filtered_dial_info_detail(&filter)
|
||||
.is_none();
|
||||
if need_udpv4_dialinfo {
|
||||
// If we have no public UDPv4 dialinfo, then we need to run a NAT check
|
||||
@@ -559,15 +542,15 @@ impl Network {
|
||||
}
|
||||
|
||||
// Same but for TCPv4
|
||||
if protocol_config.tcp_listen
|
||||
if protocol_config.inbound.tcp
|
||||
&& !tcp_static_public_dialinfo
|
||||
&& (network_class.inbound_capable() || network_class == NetworkClass::Invalid)
|
||||
{
|
||||
let filter = DialInfoFilter::global()
|
||||
let filter = DialInfoFilter::all()
|
||||
.with_protocol_type(ProtocolType::TCP)
|
||||
.with_address_type(AddressType::IPV4);
|
||||
let need_tcpv4_dialinfo = routing_table
|
||||
.first_filtered_dial_info_detail(&filter)
|
||||
.first_public_filtered_dial_info_detail(&filter)
|
||||
.is_none();
|
||||
if need_tcpv4_dialinfo {
|
||||
// If we have no public TCPv4 dialinfo, then we need to run a NAT check
|
||||
@@ -579,6 +562,24 @@ impl Network {
|
||||
}
|
||||
}
|
||||
|
||||
// Same but for WSv4
|
||||
if protocol_config.inbound.ws
|
||||
&& !ws_static_public_dialinfo
|
||||
&& (network_class.inbound_capable() || network_class == NetworkClass::Invalid)
|
||||
{
|
||||
let filter = DialInfoFilter::all()
|
||||
.with_protocol_type(ProtocolType::WS)
|
||||
.with_address_type(AddressType::IPV4);
|
||||
let need_wsv4_dialinfo = routing_table
|
||||
.first_public_filtered_dial_info_detail(&filter)
|
||||
.is_none();
|
||||
if need_wsv4_dialinfo {
|
||||
// If we have no public TCPv4 dialinfo, then we need to run a NAT check
|
||||
// ensure the singlefuture is running for this
|
||||
self.unlocked_inner.update_wsv4_dialinfo_task.tick().await?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@@ -227,7 +227,7 @@ impl Network {
|
||||
|
||||
for ip_addr in ip_addrs {
|
||||
let addr = SocketAddr::new(ip_addr, port);
|
||||
let ldi_addrs = Self::translate_unspecified_address(&*(self.inner.lock()), &addr);
|
||||
let idi_addrs = Self::translate_unspecified_address(&*(self.inner.lock()), &addr);
|
||||
|
||||
// see if we've already bound to this already
|
||||
// if not, spawn a listener
|
||||
@@ -262,9 +262,9 @@ impl Network {
|
||||
));
|
||||
}
|
||||
|
||||
// Return local dial infos we listen on
|
||||
for ldi_addr in ldi_addrs {
|
||||
out.push(SocketAddress::from_socket_addr(ldi_addr));
|
||||
// Return interface dial infos we listen on
|
||||
for idi_addr in idi_addrs {
|
||||
out.push(SocketAddress::from_socket_addr(idi_addr));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -173,13 +173,13 @@ impl Network {
|
||||
.inbound_udp_protocol_handlers
|
||||
.contains_key(&addr)
|
||||
{
|
||||
let ldi_addrs = Self::translate_unspecified_address(&*self.inner.lock(), &addr);
|
||||
let idi_addrs = Self::translate_unspecified_address(&*self.inner.lock(), &addr);
|
||||
|
||||
self.clone().create_udp_inbound_socket(addr).await?;
|
||||
|
||||
// Return local dial infos we listen on
|
||||
for ldi_addr in ldi_addrs {
|
||||
out.push(DialInfo::udp_from_socketaddr(ldi_addr));
|
||||
// Return interface dial infos we listen on
|
||||
for idi_addr in idi_addrs {
|
||||
out.push(DialInfo::udp_from_socketaddr(idi_addr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -60,9 +60,15 @@ impl Network {
|
||||
.with_protocol_type(protocol_type)
|
||||
.with_address_type(address_type);
|
||||
routing_table
|
||||
.all_filtered_dial_info_details(&filter)
|
||||
.interface_dial_info_details()
|
||||
.iter()
|
||||
.map(|did| did.dial_info.socket_address())
|
||||
.filter_map(|did| {
|
||||
if did.dial_info.matches_filter(&filter) {
|
||||
Some(did.dial_info.socket_address())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
@@ -130,7 +136,7 @@ impl Network {
|
||||
.await
|
||||
{
|
||||
// Add public dial info with Server network class
|
||||
routing_table.register_dial_info(
|
||||
routing_table.register_public_dial_info(
|
||||
external1_dial_info,
|
||||
DialInfoOrigin::Discovered,
|
||||
Some(NetworkClass::Server),
|
||||
@@ -151,7 +157,7 @@ impl Network {
|
||||
{
|
||||
// Got a port mapping, let's use it
|
||||
let external_mapped_dial_info = DialInfo::udp(external_mapped);
|
||||
routing_table.register_dial_info(
|
||||
routing_table.register_public_dial_info(
|
||||
external_mapped_dial_info,
|
||||
DialInfoOrigin::Mapped,
|
||||
Some(NetworkClass::Mapped),
|
||||
@@ -174,7 +180,7 @@ impl Network {
|
||||
{
|
||||
// Yes, another machine can use the dial info directly, so Full Cone
|
||||
// Add public dial info with full cone NAT network class
|
||||
routing_table.register_dial_info(
|
||||
routing_table.register_public_dial_info(
|
||||
external1_dial_info,
|
||||
DialInfoOrigin::Discovered,
|
||||
Some(NetworkClass::FullConeNAT),
|
||||
@@ -224,14 +230,14 @@ impl Network {
|
||||
.await
|
||||
{
|
||||
// Got a reply from a non-default port, which means we're only address restricted
|
||||
routing_table.register_dial_info(
|
||||
routing_table.register_public_dial_info(
|
||||
external1_dial_info,
|
||||
DialInfoOrigin::Discovered,
|
||||
Some(NetworkClass::AddressRestrictedNAT),
|
||||
);
|
||||
} else {
|
||||
// Didn't get a reply from a non-default port, which means we are also port restricted
|
||||
routing_table.register_dial_info(
|
||||
routing_table.register_public_dial_info(
|
||||
external1_dial_info,
|
||||
DialInfoOrigin::Discovered,
|
||||
Some(NetworkClass::PortRestrictedNAT),
|
||||
@@ -258,4 +264,11 @@ impl Network {
|
||||
//Err("unimplemented".to_owned())
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn update_wsv4_dialinfo_task_routine(self, _l: u64, _t: u64) -> Result<(), String> {
|
||||
log_net!("looking for wsv4 public dial info");
|
||||
// xxx
|
||||
//Err("unimplemented".to_owned())
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@@ -287,22 +287,23 @@ impl Network {
|
||||
"UDP: starting listeners on port {} at {:?}",
|
||||
udp_port, ip_addrs
|
||||
);
|
||||
let dial_infos = self.create_udp_inbound_sockets(ip_addrs, udp_port).await?;
|
||||
let dial_info_list = self.create_udp_inbound_sockets(ip_addrs, udp_port).await?;
|
||||
let mut static_public = false;
|
||||
for di in &dial_infos {
|
||||
// Register local dial info only here if we specify a public address
|
||||
for di in &dial_info_list {
|
||||
// If the local interface address is global,
|
||||
// register global dial info if no public address is specified
|
||||
if public_address.is_none() && di.is_global() {
|
||||
// Register global dial info if no public address is specified
|
||||
routing_table.register_dial_info(
|
||||
routing_table.register_public_dial_info(
|
||||
di.clone(),
|
||||
DialInfoOrigin::Static,
|
||||
Some(NetworkClass::Server),
|
||||
);
|
||||
|
||||
static_public = true;
|
||||
} else if di.is_local() {
|
||||
// Register local dial info
|
||||
routing_table.register_dial_info(di.clone(), DialInfoOrigin::Static, None);
|
||||
}
|
||||
|
||||
// Register interface dial info as well since the address is on the local interface
|
||||
routing_table.register_interface_dial_info(di.clone(), DialInfoOrigin::Static);
|
||||
}
|
||||
|
||||
// Add static public dialinfo if it's configured
|
||||
@@ -315,7 +316,7 @@ impl Network {
|
||||
|
||||
// Add all resolved addresses as public dialinfo
|
||||
for pdi_addr in &mut public_sockaddrs {
|
||||
routing_table.register_dial_info(
|
||||
routing_table.register_public_dial_info(
|
||||
DialInfo::udp_from_socketaddr(pdi_addr),
|
||||
DialInfoOrigin::Static,
|
||||
Some(NetworkClass::Server),
|
||||
@@ -375,22 +376,21 @@ impl Network {
|
||||
let di = DialInfo::try_ws(socket_address, global_url)
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!(error))?;
|
||||
routing_table.register_dial_info(
|
||||
routing_table.register_public_dial_info(
|
||||
di,
|
||||
DialInfoOrigin::Static,
|
||||
Some(NetworkClass::Server),
|
||||
);
|
||||
static_public = true;
|
||||
} else if socket_address.address().is_local() {
|
||||
// Build local dial info request url
|
||||
let local_url = format!("ws://{}/{}", socket_address, path);
|
||||
|
||||
// Create local dial info
|
||||
let di = DialInfo::try_ws(socket_address, local_url)
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!(error))?;
|
||||
routing_table.register_dial_info(di, DialInfoOrigin::Static, None);
|
||||
}
|
||||
// Build interface dial info request url
|
||||
let interface_url = format!("ws://{}/{}", socket_address, path);
|
||||
|
||||
// Create interface dial info
|
||||
let di = DialInfo::try_ws(socket_address, interface_url)
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!(error))?;
|
||||
routing_table.register_interface_dial_info(di, DialInfoOrigin::Static);
|
||||
}
|
||||
|
||||
// Add static public dialinfo if it's configured
|
||||
@@ -410,7 +410,7 @@ impl Network {
|
||||
.map_err(logthru_net!(error))?;
|
||||
|
||||
for gsa in global_socket_addrs {
|
||||
routing_table.register_dial_info(
|
||||
routing_table.register_public_dial_info(
|
||||
DialInfo::try_ws(SocketAddress::from_socket_addr(gsa), url.clone())
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!(error))?,
|
||||
@@ -460,7 +460,7 @@ impl Network {
|
||||
.await?;
|
||||
trace!("WSS: listener started");
|
||||
|
||||
// NOTE: No local dial info for WSS, as there is no way to connect to a local dialinfo via TLS
|
||||
// NOTE: No interface dial info for WSS, as there is no way to connect to a local dialinfo via TLS
|
||||
// If the hostname is specified, it is the public dialinfo via the URL. If no hostname
|
||||
// is specified, then TLS won't validate, so no local dialinfo is possible.
|
||||
// This is not the case with unencrypted websockets, which can be specified solely by an IP address
|
||||
@@ -483,7 +483,7 @@ impl Network {
|
||||
.map_err(logthru_net!(error))?;
|
||||
|
||||
for gsa in global_socket_addrs {
|
||||
routing_table.register_dial_info(
|
||||
routing_table.register_public_dial_info(
|
||||
DialInfo::try_wss(SocketAddress::from_socket_addr(gsa), url.clone())
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!(error))?,
|
||||
@@ -537,19 +537,17 @@ impl Network {
|
||||
for socket_address in socket_addresses {
|
||||
let di = DialInfo::tcp(socket_address);
|
||||
|
||||
// Register local dial info only here if we specify a public address
|
||||
// Register global dial info if no public address is specified
|
||||
if public_address.is_none() && di.is_global() {
|
||||
// Register global dial info if no public address is specified
|
||||
routing_table.register_dial_info(
|
||||
routing_table.register_public_dial_info(
|
||||
di.clone(),
|
||||
DialInfoOrigin::Static,
|
||||
Some(NetworkClass::Server),
|
||||
);
|
||||
static_public = true;
|
||||
} else if di.is_local() {
|
||||
// Register local dial info
|
||||
routing_table.register_dial_info(di.clone(), DialInfoOrigin::Static, None);
|
||||
}
|
||||
// Register interface dial info
|
||||
routing_table.register_interface_dial_info(di.clone(), DialInfoOrigin::Static);
|
||||
}
|
||||
|
||||
// Add static public dialinfo if it's configured
|
||||
@@ -562,7 +560,7 @@ impl Network {
|
||||
|
||||
// Add all resolved addresses as public dialinfo
|
||||
for pdi_addr in &mut public_sockaddrs {
|
||||
routing_table.register_dial_info(
|
||||
routing_table.register_public_dial_info(
|
||||
DialInfo::tcp_from_socketaddr(pdi_addr),
|
||||
DialInfoOrigin::Static,
|
||||
None,
|
||||
|
@@ -75,7 +75,7 @@ impl Network {
|
||||
res
|
||||
}
|
||||
|
||||
async fn send_data_to_existing_connection(
|
||||
pub async fn send_data_to_existing_connection(
|
||||
&self,
|
||||
descriptor: ConnectionDescriptor,
|
||||
data: Vec<u8>,
|
||||
@@ -137,31 +137,6 @@ impl Network {
|
||||
res
|
||||
}
|
||||
|
||||
pub async fn send_data(&self, node_ref: NodeRef, data: Vec<u8>) -> Result<(), String> {
|
||||
// First try to send data to the last socket we've seen this peer on
|
||||
let data = if let Some(descriptor) = node_ref.last_connection() {
|
||||
match self
|
||||
.clone()
|
||||
.send_data_to_existing_connection(descriptor, data)
|
||||
.await?
|
||||
{
|
||||
None => {
|
||||
return Ok(());
|
||||
}
|
||||
Some(d) => d,
|
||||
}
|
||||
} else {
|
||||
data
|
||||
};
|
||||
|
||||
// If that fails, try to make a connection or reach out to the peer via its dial info
|
||||
let dial_info = node_ref
|
||||
.best_dial_info()
|
||||
.ok_or_else(|| "couldn't send data, no dial info or peer address".to_owned())?;
|
||||
|
||||
self.send_data_to_dial_info(dial_info, data).await
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
pub async fn startup(&self) -> Result<(), String> {
|
||||
|
Reference in New Issue
Block a user