continue to refactor

This commit is contained in:
John Smith 2021-12-21 22:20:55 -05:00
parent c0a42ac90c
commit 5826551763
22 changed files with 381 additions and 551 deletions

View File

@ -39,13 +39,11 @@ pub const PEEK_DETECT_LEN: usize = 64;
struct NetworkInner { struct NetworkInner {
routing_table: RoutingTable, routing_table: RoutingTable,
network_manager: NetworkManager, network_manager: NetworkManager,
network_started: bool,
network_needs_restart: bool, network_needs_restart: bool,
udp_listen: bool, protocol_config: Option<ProtocolConfig>,
udp_static_public_dialinfo: bool, udp_static_public_dialinfo: bool,
tcp_listen: bool,
tcp_static_public_dialinfo: bool, tcp_static_public_dialinfo: bool,
ws_listen: bool,
wss_listen: bool,
network_class: Option<NetworkClass>, network_class: Option<NetworkClass>,
join_handles: Vec<JoinHandle<()>>, join_handles: Vec<JoinHandle<()>>,
listener_states: BTreeMap<SocketAddr, Arc<RwLock<ListenerState>>>, listener_states: BTreeMap<SocketAddr, Arc<RwLock<ListenerState>>>,
@ -81,13 +79,11 @@ impl Network {
NetworkInner { NetworkInner {
routing_table: network_manager.routing_table(), routing_table: network_manager.routing_table(),
network_manager, network_manager,
network_started: false,
network_needs_restart: false, network_needs_restart: false,
udp_listen: false, protocol_config: None,
udp_static_public_dialinfo: false, udp_static_public_dialinfo: false,
tcp_listen: false,
tcp_static_public_dialinfo: false, tcp_static_public_dialinfo: false,
ws_listen: false,
wss_listen: false,
network_class: None, network_class: None,
join_handles: Vec::new(), join_handles: Vec::new(),
listener_states: BTreeMap::new(), listener_states: BTreeMap::new(),
@ -681,14 +677,11 @@ impl Network {
match descriptor.protocol_type() { match descriptor.protocol_type() {
ProtocolType::UDP => { ProtocolType::UDP => {
// send over the best udp socket we have bound since UDP is not connection oriented // send over the best udp socket we have bound since UDP is not connection oriented
let peer_socket_addr = descriptor let peer_socket_addr = descriptor.remote.to_socket_addr();
.remote if let Some(ph) = self.find_best_udp_protocol_handler(
.to_socket_addr() &peer_socket_addr,
.map_err(map_to_string) &descriptor.local.map(|sa| sa.to_socket_addr()),
.map_err(logthru_net!(error))?; ) {
if let Some(ph) =
self.find_best_udp_protocol_handler(&peer_socket_addr, &descriptor.local)
{
ph.clone() ph.clone()
.send_message(data, peer_socket_addr) .send_message(data, peer_socket_addr)
.await .await
@ -724,14 +717,13 @@ impl Network {
) -> Result<(), String> { ) -> Result<(), String> {
match &dial_info { match &dial_info {
DialInfo::UDP(_) => { DialInfo::UDP(_) => {
let peer_socket_addr = dial_info.to_socket_addr().map_err(logthru_net!())?; let peer_socket_addr = dial_info.to_socket_addr();
RawUdpProtocolHandler::send_unbound_message(data, peer_socket_addr) RawUdpProtocolHandler::send_unbound_message(data, peer_socket_addr)
.await .await
.map_err(logthru_net!()) .map_err(logthru_net!())
} }
DialInfo::TCP(_) => { DialInfo::TCP(_) => {
let peer_socket_addr = dial_info.to_socket_addr().map_err(logthru_net!())?; let peer_socket_addr = dial_info.to_socket_addr();
RawTcpProtocolHandler::send_unbound_message(data, peer_socket_addr) RawTcpProtocolHandler::send_unbound_message(data, peer_socket_addr)
.await .await
.map_err(logthru_net!()) .map_err(logthru_net!())
@ -752,7 +744,7 @@ impl Network {
let conn = match &dial_info { let conn = match &dial_info {
DialInfo::UDP(_) => { DialInfo::UDP(_) => {
let peer_socket_addr = dial_info.to_socket_addr().map_err(logthru_net!())?; let peer_socket_addr = dial_info.to_socket_addr();
if let Some(ph) = self.find_best_udp_protocol_handler(&peer_socket_addr, &None) { if let Some(ph) = self.find_best_udp_protocol_handler(&peer_socket_addr, &None) {
return ph return ph
.send_message(data, peer_socket_addr) .send_message(data, peer_socket_addr)
@ -764,7 +756,7 @@ impl Network {
} }
} }
DialInfo::TCP(_) => { DialInfo::TCP(_) => {
let peer_socket_addr = dial_info.to_socket_addr().map_err(logthru_net!())?; let peer_socket_addr = dial_info.to_socket_addr();
let local_addr = let local_addr =
self.get_preferred_local_address(self.inner.lock().tcp_port, &peer_socket_addr); self.get_preferred_local_address(self.inner.lock().tcp_port, &peer_socket_addr);
RawTcpProtocolHandler::connect(network_manager, local_addr, peer_socket_addr) RawTcpProtocolHandler::connect(network_manager, local_addr, peer_socket_addr)
@ -772,22 +764,20 @@ impl Network {
.map_err(logthru_net!())? .map_err(logthru_net!())?
} }
DialInfo::WS(_) => { DialInfo::WS(_) => {
let remote_ip_addr = dial_info.resolve()?; let peer_socket_addr = dial_info.to_socket_addr();
let local_addr = let local_addr =
self.get_preferred_local_address(self.inner.lock().ws_port, &peer_socket_addr); self.get_preferred_local_address(self.inner.lock().ws_port, &peer_socket_addr);
WebsocketProtocolHandler::connect(network_manager, local_addr, dial_info) WebsocketProtocolHandler::connect(network_manager, local_addr, dial_info)
.await .await
.map_err(logthru_net!(error))? .map_err(logthru_net!(error))?
} }
DialInfo::WSS(_) => { DialInfo::WSS(_) => {
let peer_socket_addr = dial_info.to_socket_addr();
let local_addr = let local_addr =
self.get_preferred_local_address(self.inner.lock().ws_port, &peer_socket_addr); self.get_preferred_local_address(self.inner.lock().wss_port, &peer_socket_addr);
WebsocketProtocolHandler::connect(network_manager, local_addr, dial_info)
WebsocketProtocolHandler::connect(network_manager, dial_info) .await
.await .map_err(logthru_net!(error))?
.map_err(logthru_net!(error))?,
} }
}; };
@ -865,7 +855,7 @@ impl Network {
} else { } else {
// Register local dial info as public if it is publicly routable // Register local dial info as public if it is publicly routable
for x in &dial_infos { for x in &dial_infos {
if x.is_public().unwrap_or(false) { if x.is_global() {
routing_table.register_global_dial_info( routing_table.register_global_dial_info(
x.clone(), x.clone(),
Some(NetworkClass::Server), Some(NetworkClass::Server),
@ -875,7 +865,6 @@ impl Network {
} }
} }
} }
self.inner.lock().udp_listen = true;
self.inner.lock().udp_static_public_dialinfo = static_public; self.inner.lock().udp_static_public_dialinfo = static_public;
Ok(()) Ok(())
} }
@ -904,8 +893,8 @@ impl Network {
for (a, p) in addresses { for (a, p) in addresses {
// Pick out WS port for outbound connections (they will all be the same) // Pick out WS port for outbound connections (they will all be the same)
self.inner.lock().ws_port = p; self.inner.lock().ws_port = p;
xxx continue here
let di = DialInfo::ws(a.address_string(), p, path.clone()); let di = DialInfo::try_ws(a.address_string(), p, path.clone());
dial_infos.push(di.clone()); dial_infos.push(di.clone());
routing_table.register_local_dial_info(di, DialInfoOrigin::Static); routing_table.register_local_dial_info(di, DialInfoOrigin::Static);
} }
@ -930,7 +919,6 @@ impl Network {
); );
} }
self.inner.lock().ws_listen = true;
Ok(()) Ok(())
} }
@ -990,7 +978,6 @@ impl Network {
return Err("WSS URL must be specified due to TLS requirements".to_owned()); return Err("WSS URL must be specified due to TLS requirements".to_owned());
} }
self.inner.lock().wss_listen = true;
Ok(()) Ok(())
} }
@ -1044,7 +1031,7 @@ impl Network {
} else { } else {
// Register local dial info as public if it is publicly routable // Register local dial info as public if it is publicly routable
for x in &dial_infos { for x in &dial_infos {
if x.is_public().unwrap_or(false) { if x.is_global() {
routing_table.register_global_dial_info( routing_table.register_global_dial_info(
x.clone(), x.clone(),
Some(NetworkClass::Server), Some(NetworkClass::Server),
@ -1055,12 +1042,15 @@ impl Network {
} }
} }
self.inner.lock().tcp_listen = true;
self.inner.lock().tcp_static_public_dialinfo = static_public; self.inner.lock().tcp_static_public_dialinfo = static_public;
Ok(()) Ok(())
} }
pub fn get_protocol_config(&self) -> Option<ProtocolConfig> {
self.inner.lock().protocol_config.clone()
}
pub async fn startup(&self) -> Result<(), String> { pub async fn startup(&self) -> Result<(), String> {
info!("starting network"); info!("starting network");
let network_manager = self.inner.lock().network_manager.clone(); let network_manager = self.inner.lock().network_manager.clone();
@ -1068,36 +1058,38 @@ impl Network {
// initialize interfaces // initialize interfaces
self.inner.lock().interfaces.refresh()?; self.inner.lock().interfaces.refresh()?;
// get network config // get protocol config
let (enabled_udp, connect_tcp, listen_tcp, connect_ws, listen_ws, connect_wss, listen_wss) = { let protocol_config = {
let c = self.config.get(); let c = self.config.get();
( ProtocolConfig {
c.network.protocol.udp.enabled && c.capabilities.protocol_udp, udp_enabled: c.network.protocol.udp.enabled && c.capabilities.protocol_udp,
c.network.protocol.tcp.connect && c.capabilities.protocol_connect_tcp, tcp_connect: c.network.protocol.tcp.connect && c.capabilities.protocol_connect_tcp,
c.network.protocol.tcp.listen && c.capabilities.protocol_accept_tcp, tcp_listen: c.network.protocol.tcp.listen && c.capabilities.protocol_accept_tcp,
c.network.protocol.ws.connect && c.capabilities.protocol_connect_ws, ws_connect: c.network.protocol.ws.connect && c.capabilities.protocol_connect_ws,
c.network.protocol.ws.listen && c.capabilities.protocol_accept_ws, ws_listen: c.network.protocol.ws.listen && c.capabilities.protocol_accept_ws,
c.network.protocol.wss.connect && c.capabilities.protocol_connect_wss, wss_connect: c.network.protocol.wss.connect && c.capabilities.protocol_connect_wss,
c.network.protocol.wss.listen && c.capabilities.protocol_accept_wss, wss_listen: c.network.protocol.wss.listen && c.capabilities.protocol_accept_wss,
) }
}; };
self.inner.lock().protocol_config = Some(protocol_config);
// start listeners // start listeners
if enabled_udp { if protocol_config.udp_enabled {
self.start_udp_listeners().await?; self.start_udp_listeners().await?;
self.create_udp_outbound_sockets().await?; self.create_udp_outbound_sockets().await?;
} }
if listen_ws { if protocol_config.ws_listen {
self.start_ws_listeners().await?; self.start_ws_listeners().await?;
} }
if listen_wss { if protocol_config.wss_listen {
self.start_wss_listeners().await?; self.start_wss_listeners().await?;
} }
if listen_tcp { if protocol_config.tcp_listen {
self.start_tcp_listeners().await?; self.start_tcp_listeners().await?;
} }
info!("network started"); info!("network started");
self.inner.lock().network_started = true;
Ok(()) Ok(())
} }
@ -1123,13 +1115,17 @@ impl Network {
} }
////////////////////////////////////////// //////////////////////////////////////////
pub fn get_network_class(&self) -> NetworkClass { pub fn get_network_class(&self) -> Option<NetworkClass> {
let inner = self.inner.lock(); let inner = self.inner.lock();
let routing_table = inner.routing_table.clone(); let routing_table = inner.routing_table.clone();
if !inner.network_started {
return None;
}
// If we've fixed the network class, return it rather than calculating it // If we've fixed the network class, return it rather than calculating it
if let Some(network_class) = inner.network_class { if inner.network_class.is_some() {
return network_class; return inner.network_class;
} }
// Go through our public dialinfo and see what our best network class is // Go through our public dialinfo and see what our best network class is
@ -1141,7 +1137,7 @@ impl Network {
} }
} }
} }
network_class Some(network_class)
} }
////////////////////////////////////////// //////////////////////////////////////////
@ -1149,18 +1145,19 @@ impl Network {
pub async fn tick(&self) -> Result<(), String> { pub async fn tick(&self) -> Result<(), String> {
let ( let (
routing_table, routing_table,
udp_listen, protocol_config,
udp_static_public_dialinfo, udp_static_public_dialinfo,
tcp_listen,
tcp_static_public_dialinfo, tcp_static_public_dialinfo,
network_class, network_class,
) = { ) = {
let inner = self.inner.lock(); let inner = self.inner.lock();
( (
inner.network_manager.routing_table(), inner.network_manager.routing_table(),
inner.udp_listen, inner
.protocol_config
.clone()
.unwrap_or_else(|| ProtocolConfig::default()),
inner.udp_static_public_dialinfo, inner.udp_static_public_dialinfo,
inner.tcp_listen,
inner.tcp_static_public_dialinfo, inner.tcp_static_public_dialinfo,
inner.network_class.unwrap_or(NetworkClass::Invalid), inner.network_class.unwrap_or(NetworkClass::Invalid),
) )
@ -1171,7 +1168,7 @@ impl Network {
// If we can have public dialinfo, or we haven't figured out our network class yet, // 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 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 // and assess our network class if we haven't already
if udp_listen if protocol_config.udp_enabled
&& !udp_static_public_dialinfo && !udp_static_public_dialinfo
&& (network_class.inbound_capable() || network_class == NetworkClass::Invalid) && (network_class.inbound_capable() || network_class == NetworkClass::Invalid)
{ {
@ -1189,7 +1186,7 @@ impl Network {
} }
// Same but for TCPv4 // Same but for TCPv4
if tcp_listen if protocol_config.tcp_enabled
&& !tcp_static_public_dialinfo && !tcp_static_public_dialinfo
&& (network_class.inbound_capable() || network_class == NetworkClass::Invalid) && (network_class.inbound_capable() || network_class == NetworkClass::Invalid)
{ {

View File

@ -153,8 +153,7 @@ impl RawTcpProtocolHandler {
let conn = NetworkConnection::RawTcp(RawTcpNetworkConnection::new(stream)); let conn = NetworkConnection::RawTcp(RawTcpNetworkConnection::new(stream));
let peer_addr = PeerAddress::new( let peer_addr = PeerAddress::new(
Address::from_socket_addr(socket_addr).to_canonical(), SocketAddress::from_socket_addr(socket_addr),
socket_addr.port(),
ProtocolType::TCP, ProtocolType::TCP,
); );
let (network_manager, local_address) = { let (network_manager, local_address) = {
@ -162,7 +161,13 @@ impl RawTcpProtocolHandler {
(inner.network_manager.clone(), inner.local_address) (inner.network_manager.clone(), inner.local_address)
}; };
network_manager network_manager
.on_new_connection(ConnectionDescriptor::new(peer_addr, local_address), conn) .on_new_connection(
ConnectionDescriptor::new(
peer_addr,
SocketAddress::from_socket_addr(local_address),
),
conn,
)
.await?; .await?;
Ok(true) Ok(true)
} }
@ -191,8 +196,7 @@ impl RawTcpProtocolHandler {
.map_err(logthru_net!())?; .map_err(logthru_net!())?;
let ps = AsyncPeekStream::new(ts); let ps = AsyncPeekStream::new(ts);
let peer_addr = PeerAddress::new( let peer_addr = PeerAddress::new(
Address::from_socket_addr(remote_socket_addr).to_canonical(), SocketAddress::from_socket_addr(remote_socket_addr),
remote_socket_addr.port(),
ProtocolType::TCP, ProtocolType::TCP,
); );
@ -200,7 +204,10 @@ impl RawTcpProtocolHandler {
let conn = NetworkConnection::RawTcp(RawTcpNetworkConnection::new(ps)); let conn = NetworkConnection::RawTcp(RawTcpNetworkConnection::new(ps));
network_manager network_manager
.on_new_connection( .on_new_connection(
ConnectionDescriptor::new(peer_addr, local_address), ConnectionDescriptor::new(
peer_addr,
SocketAddress::from_socket_addr(local_address),
),
conn.clone(), conn.clone(),
) )
.await?; .await?;

View File

@ -48,15 +48,17 @@ impl RawUdpProtocolHandler {
}; };
let peer_addr = PeerAddress::new( let peer_addr = PeerAddress::new(
Address::from_socket_addr(remote_addr), SocketAddress::from_socket_addr(remote_addr),
remote_addr.port(),
ProtocolType::UDP, ProtocolType::UDP,
); );
let local_socket_addr = socket.local_addr().map_err(|e| format!("{}", e))?; let local_socket_addr = socket.local_addr().map_err(|e| format!("{}", e))?;
network_manager network_manager
.on_recv_envelope( .on_recv_envelope(
data, data,
&ConnectionDescriptor::new(peer_addr, local_socket_addr), &ConnectionDescriptor::new(
peer_addr,
SocketAddress::from_socket_addr(local_socket_addr),
),
) )
.await .await
} }

View File

@ -221,11 +221,8 @@ impl WebsocketProtocolHandler {
ProtocolType::WS ProtocolType::WS
}; };
let peer_addr = PeerAddress::new( let peer_addr =
Address::from_socket_addr(socket_addr), PeerAddress::new(SocketAddress::from_socket_addr(socket_addr), protocol_type);
socket_addr.port(),
protocol_type,
);
let conn = NetworkConnection::WsAccepted(WebsocketNetworkConnection::new( let conn = NetworkConnection::WsAccepted(WebsocketNetworkConnection::new(
self.inner.tls, self.inner.tls,
@ -235,7 +232,10 @@ impl WebsocketProtocolHandler {
.network_manager .network_manager
.clone() .clone()
.on_new_connection( .on_new_connection(
ConnectionDescriptor::new(peer_addr, self.inner.local_address), ConnectionDescriptor::new(
peer_addr,
SocketAddress::from_socket_addr(self.inner.local_address),
),
conn, conn,
) )
.await?; .await?;
@ -248,27 +248,20 @@ impl WebsocketProtocolHandler {
dial_info: &DialInfo, dial_info: &DialInfo,
) -> Result<NetworkConnection, String> { ) -> Result<NetworkConnection, String> {
// Split dial info up // Split dial info up
let (tls, request, domain, port, protocol_type) = match &dial_info { let (tls, protocol_type, scheme) = match &dial_info {
DialInfo::WS(di) => ( DialInfo::WS(_) => (false, ProtocolType::WS, "ws"),
false, DialInfo::WSS(_) => (true, ProtocolType::WSS, "wss"),
format!("ws://{}:{}/{}", di.host, di.port, di.path),
di.host.clone(),
di.port,
ProtocolType::WS,
),
DialInfo::WSS(di) => (
true,
format!("wss://{}:{}/{}", di.host, di.port, di.path),
di.host.clone(),
di.port,
ProtocolType::WSS,
),
_ => panic!("invalid dialinfo for WS/WSS protocol"), _ => panic!("invalid dialinfo for WS/WSS protocol"),
}; };
let request = dial_info.request().unwrap();
let split_url = SplitUrl::from_str(&request)?;
if split_url.scheme != scheme {
return Err("invalid websocket url scheme".to_string());
}
let domain = split_url.host.clone();
// Resolve remote address // Resolve remote address
let remote_ip_addr = dial_info.resolve()?; let remote_socket_addr = dial_info.to_socket_addr();
let remote_socket_addr = SocketAddr::new(remote_ip_addr, port);
// Make a shared socket // Make a shared socket
let socket = new_shared_tcp_socket(local_address)?; let socket = new_shared_tcp_socket(local_address)?;
@ -304,15 +297,17 @@ impl WebsocketProtocolHandler {
// Make the connection descriptor peer address // Make the connection descriptor peer address
let peer_addr = PeerAddress::new( let peer_addr = PeerAddress::new(
Address::from_socket_addr(remote_socket_addr), SocketAddress::from_socket_addr(remote_socket_addr),
port,
ProtocolType::WSS, ProtocolType::WSS,
); );
// Register the WSS connection // Register the WSS connection
network_manager network_manager
.on_new_connection( .on_new_connection(
ConnectionDescriptor::new(peer_addr, actual_local_addr), ConnectionDescriptor::new(
peer_addr,
SocketAddress::from_socket_addr(actual_local_addr),
),
conn.clone(), conn.clone(),
) )
.await?; .await?;
@ -326,15 +321,17 @@ impl WebsocketProtocolHandler {
// Make the connection descriptor peer address // Make the connection descriptor peer address
let peer_addr = PeerAddress::new( let peer_addr = PeerAddress::new(
Address::from_socket_addr(remote_socket_addr), SocketAddress::from_socket_addr(remote_socket_addr),
port,
ProtocolType::WS, ProtocolType::WS,
); );
// Register the WS connection // Register the WS connection
network_manager network_manager
.on_new_connection( .on_new_connection(
ConnectionDescriptor::new(peer_addr, actual_local_addr), ConnectionDescriptor::new(
peer_addr,
SocketAddress::from_socket_addr(actual_local_addr),
),
conn.clone(), conn.clone(),
) )
.await?; .await?;

View File

@ -12,12 +12,15 @@ pub use protocol::*;
struct NetworkInner { struct NetworkInner {
network_manager: NetworkManager, network_manager: NetworkManager,
stop_network: Eventual, stop_network: Eventual,
network_started: bool,
network_needs_restart: bool, network_needs_restart: bool,
protocol_config: Option<ProtocolConfig>,
//join_handle: TryJoin? //join_handle: TryJoin?
} }
#[derive(Clone)] #[derive(Clone)]
pub struct Network { pub struct Network {
config: VeilidConfig,
inner: Arc<Mutex<NetworkInner>>, inner: Arc<Mutex<NetworkInner>>,
} }
@ -26,13 +29,15 @@ impl Network {
NetworkInner { NetworkInner {
network_manager, network_manager,
stop_network: Eventual::new(), stop_network: Eventual::new(),
network_started: false,
network_needs_restart: false, network_needs_restart: false,
//join_handle: None, protocol_config: None, //join_handle: None,
} }
} }
pub fn new(network_manager: NetworkManager) -> Self { pub fn new(network_manager: NetworkManager) -> Self {
Self { Self {
config: network_manager.config(),
inner: Arc::new(Mutex::new(Self::new_inner(network_manager))), inner: Arc::new(Mutex::new(Self::new_inner(network_manager))),
} }
} }
@ -150,10 +155,21 @@ impl Network {
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
pub async fn startup(&self) -> Result<(), String> { pub async fn startup(&self) -> Result<(), String> {
//let network_manager = self.inner.lock().network_manager.clone(); // get protocol config
//let config_shared = network_manager.core().config(); self.inner.lock().protocol_config = Some({
//let config = config_shared.get(); let c = self.config.get();
ProtocolConfig {
udp_enabled: false, //c.network.protocol.udp.enabled && c.capabilities.protocol_udp,
tcp_connect: false, //c.network.protocol.tcp.connect && c.capabilities.protocol_connect_tcp,
tcp_listen: false, //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,
}
});
self.inner.lock().network_started = true;
Ok(()) Ok(())
} }
@ -179,9 +195,16 @@ impl Network {
} }
////////////////////////////////////////// //////////////////////////////////////////
pub fn get_network_class(&self) -> NetworkClass { pub fn get_network_class(&self) -> Option<NetworkClass> {
// xxx eventually detect tor browser? // xxx eventually detect tor browser?
return NetworkClass::WebApp; return if self.inner.lock().network_started {
Some(NetworkClass::WebApp)
} else {
None
};
}
pub fn get_protocol_config(&self) -> Option<ProtocolConfig> {
self.inner.lock().protocol_config.clone()
} }
////////////////////////////////////////// //////////////////////////////////////////

View File

@ -110,17 +110,20 @@ impl LeaseManager {
if inner.max_server_signal_leases == 0 { if inner.max_server_signal_leases == 0 {
return false; return false;
} }
let network_class = inner.network_manager.get_network_class(); if let Some(network_class) = inner.network_manager.get_network_class() {
match network_class { match network_class {
NetworkClass::Server => true, NetworkClass::Server => true,
NetworkClass::Mapped => true, NetworkClass::Mapped => true,
NetworkClass::FullNAT => true, NetworkClass::FullNAT => true,
NetworkClass::AddressRestrictedNAT => false, NetworkClass::AddressRestrictedNAT => false,
NetworkClass::PortRestrictedNAT => false, NetworkClass::PortRestrictedNAT => false,
NetworkClass::OutboundOnly => false, NetworkClass::OutboundOnly => false,
NetworkClass::WebApp => false, NetworkClass::WebApp => false,
NetworkClass::TorWebApp => false, NetworkClass::TorWebApp => false,
NetworkClass::Invalid => false, NetworkClass::Invalid => false,
}
} else {
false
} }
} }
pub fn server_will_provide_signal_lease(&self) -> bool { pub fn server_will_provide_signal_lease(&self) -> bool {
@ -152,17 +155,20 @@ impl LeaseManager {
if inner.max_server_signal_leases == 0 { if inner.max_server_signal_leases == 0 {
return false; return false;
} }
let network_class = inner.network_manager.get_network_class(); if let Some(network_class) = inner.network_manager.get_network_class() {
match network_class { match network_class {
NetworkClass::Server => true, NetworkClass::Server => true,
NetworkClass::Mapped => true, NetworkClass::Mapped => true,
NetworkClass::FullNAT => true, NetworkClass::FullNAT => true,
NetworkClass::AddressRestrictedNAT => false, NetworkClass::AddressRestrictedNAT => false,
NetworkClass::PortRestrictedNAT => false, NetworkClass::PortRestrictedNAT => false,
NetworkClass::OutboundOnly => false, NetworkClass::OutboundOnly => false,
NetworkClass::WebApp => false, NetworkClass::WebApp => false,
NetworkClass::TorWebApp => false, NetworkClass::TorWebApp => false,
NetworkClass::Invalid => false, NetworkClass::Invalid => false,
}
} else {
false
} }
// xxx: also depends on network strength / bandwidth availability? // xxx: also depends on network strength / bandwidth availability?
} }

View File

@ -42,6 +42,17 @@ impl NetworkClass {
} }
} }
#[derive(Copy, Clone, Debug, Default)]
pub struct ProtocolConfig {
pub udp_enabled: bool,
pub tcp_connect: bool,
pub tcp_listen: bool,
pub ws_connect: bool,
pub ws_listen: bool,
pub wss_connect: bool,
pub wss_listen: bool,
}
// Things we get when we start up and go away when we shut down // Things we get when we start up and go away when we shut down
// Routing table is not in here because we want it to survive a network shutdown/startup restart // Routing table is not in here because we want it to survive a network shutdown/startup restart
#[derive(Clone)] #[derive(Clone)]
@ -381,11 +392,20 @@ impl NetworkManager {
} }
// Return what network class we are in // Return what network class we are in
pub fn get_network_class(&self) -> NetworkClass { pub fn get_network_class(&self) -> Option<NetworkClass> {
if let Some(components) = &self.inner.lock().components { if let Some(components) = &self.inner.lock().components {
components.net.get_network_class() components.net.get_network_class()
} else { } else {
NetworkClass::Invalid None
}
}
// Return what protocols we have enabled
pub fn get_protocol_config(&self) -> Option<ProtocolConfig> {
if let Some(components) = &self.inner.lock().components {
components.net.get_protocol_config()
} else {
None
} }
} }

View File

@ -31,7 +31,7 @@ pub struct BucketEntry {
pub(super) ref_count: u32, pub(super) ref_count: u32,
min_max_version: Option<(u8, u8)>, min_max_version: Option<(u8, u8)>,
last_connection: Option<(ConnectionDescriptor, u64)>, last_connection: Option<(ConnectionDescriptor, u64)>,
dial_info_entries: VecDeque<DialInfoEntry>, dial_infos: Vec<DialInfo>,
stats_accounting: StatsAccounting, stats_accounting: StatsAccounting,
peer_stats: PeerStats, peer_stats: PeerStats,
} }
@ -43,7 +43,7 @@ impl BucketEntry {
ref_count: 0, ref_count: 0,
min_max_version: None, min_max_version: None,
last_connection: None, last_connection: None,
dial_info_entries: VecDeque::new(), dial_infos: Vec::new(),
stats_accounting: StatsAccounting::new(), stats_accounting: StatsAccounting::new(),
peer_stats: PeerStats { peer_stats: PeerStats {
time_added: now, time_added: now,
@ -56,145 +56,48 @@ impl BucketEntry {
} }
} }
pub fn add_dial_info(&mut self, dial_info: DialInfo) -> Result<(), String> { pub fn update_dial_infos(&mut self, dial_infos: &[DialInfo]) {
let mut idx: Option<usize> = None; self.dial_infos = dial_infos.to_vec();
for i in 0..self.dial_info_entries.len() { self.dial_infos.sort();
if self.dial_info_entries[i].dial_info() == &dial_info {
idx = Some(i);
break;
}
}
match idx {
None => {
self.dial_info_entries
.push_front(DialInfoEntry::try_new(dial_info)?);
}
Some(idx) => {
let die = self.dial_info_entries.remove(idx).unwrap();
self.dial_info_entries.push_front(die);
}
}
Ok(())
} }
pub fn best_dial_info(&self) -> Option<DialInfo> { pub fn first_filtered_dial_info<F>(&self, filter: F) -> Option<DialInfo>
self.dial_info_entries
.front()
.map(|die| die.dial_info().clone())
}
pub fn filtered_dial_info<F>(&self, filter: F) -> Option<DialInfo>
where where
F: Fn(&DialInfoEntry) -> bool, F: Fn(&DialInfo) -> bool,
{ {
for die in &self.dial_info_entries { for di in &self.dial_infos {
if filter(die) { if filter(di) {
return Some(die.dial_info().clone()); return Some(di.clone());
} }
} }
None None
} }
pub fn all_filtered_dial_infos<F>(&self, filter: F) -> Vec<DialInfo>
pub fn dial_info_entries_as_ref(&self) -> &VecDeque<DialInfoEntry> { where
&self.dial_info_entries F: Fn(&DialInfo) -> bool,
{
let ret = Vec::new();
for di in &self.dial_infos {
if filter(di) {
ret.push(di.clone());
}
}
ret
} }
pub fn dial_info(&self) -> Vec<DialInfo> { pub fn dial_infos(&self) -> &[DialInfo] {
self.dial_info_entries &self.dial_infos.clone()
.iter()
.map(|e| e.dial_info().clone())
.collect()
}
pub fn global_dial_info(&self) -> Vec<DialInfo> {
self.dial_info_entries
.iter()
.filter_map(|e| {
if e.is_public() {
Some(e.dial_info().clone())
} else {
None
}
})
.collect()
}
pub fn global_dial_info_for_protocol(&self, protocol_type: ProtocolType) -> Vec<DialInfo> {
self.dial_info_entries
.iter()
.filter_map(|e| {
if e.dial_info().protocol_type() != protocol_type {
None
} else if e.is_public() {
Some(e.dial_info().clone())
} else {
None
}
})
.collect()
}
pub fn local_dial_info(&self) -> Vec<DialInfo> {
self.dial_info_entries
.iter()
.filter_map(|e| {
if e.is_private() {
Some(e.dial_info().clone())
} else {
None
}
})
.collect()
}
pub fn local_dial_info_for_protocol(&mut self, protocol_type: ProtocolType) -> Vec<DialInfo> {
self.dial_info_entries
.iter_mut()
.filter_map(|e| {
if e.dial_info().protocol_type() != protocol_type {
None
} else if e.is_private() {
Some(e.dial_info().clone())
} else {
None
}
})
.collect()
} }
pub fn get_peer_info(&self, key: DHTKey, scope: PeerScope) -> PeerInfo { pub fn get_peer_info(&self, key: DHTKey, scope: PeerScope) -> PeerInfo {
PeerInfo { PeerInfo {
node_id: NodeId::new(key), node_id: NodeId::new(key),
dial_infos: match scope { dial_infos: self.all_filtered_dial_infos(|di| di.matches_peer_scope(scope)),
PeerScope::All => self.dial_info(),
PeerScope::Global => self.global_dial_info(),
PeerScope::Local => self.local_dial_info(),
},
} }
} }
pub fn set_last_connection(&mut self, last_connection: ConnectionDescriptor, timestamp: u64) { pub fn set_last_connection(&mut self, last_connection: ConnectionDescriptor, timestamp: u64) {
self.last_connection = Some((last_connection, timestamp)); self.last_connection = Some((last_connection, timestamp));
// sort the dialinfoentries by the last peer address if we have a match
// if one particular peer address is being used and matches a dialinfoentry
// then we should prefer it
for i in 0..self.dial_info_entries.len() {
let die = &mut self.dial_info_entries[i];
// see if we have a matching address
if RoutingTable::dial_info_peer_address_match(
die.dial_info(),
&self.last_connection.as_ref().unwrap().0.remote,
) {
// push the most recent dialinfo to the front
let dies = &mut self.dial_info_entries;
let die = dies.remove(i).unwrap();
dies.push_front(die);
break;
}
}
} }
pub fn last_connection(&self) -> Option<ConnectionDescriptor> { pub fn last_connection(&self) -> Option<ConnectionDescriptor> {

View File

@ -1,60 +0,0 @@
use super::*;
#[derive(Debug, Clone)]
pub struct DialInfoEntry {
dial_info: DialInfo,
resolved_address: IpAddr,
}
impl DialInfoEntry {
pub fn try_new(dial_info: DialInfo) -> Result<Self, String> {
let addr = dial_info
.resolve()
.map_err(|e| format!("failed to resolve address: {:?}", e))?;
Ok(Self {
dial_info,
resolved_address: addr,
})
}
pub fn dial_info(&self) -> &DialInfo {
&self.dial_info
}
pub fn address(&self) -> IpAddr {
self.resolved_address
}
pub fn resolve(&mut self) -> Result<Vec<IpAddr, String> {
let addr = match self.dial_info.resolve() {
Ok(a) => a,
Err(_) => return Err("failed to resolve address".to_owned()),
};
self.resolved_address = addr;
Ok(addr)
}
pub fn matches_peer_scope(&self, scope: PeerScope) -> bool {
match scope {
PeerScope::All => true,
PeerScope::Global => self.is_public(),
PeerScope::Local => self.is_private(),
}
}
pub fn is_public(&self) -> bool {
ipaddr_is_global(&self.resolved_address)
}
pub fn is_private(&self) -> bool {
match self.resolved_address {
IpAddr::V4(a) => ipv4addr_is_private(&a),
IpAddr::V6(a) => ipv6addr_is_unicast_site_local(&a),
}
}
pub fn is_valid(&self) -> bool {
self.is_public() || self.is_private()
}
pub fn is_loopback(&self) -> bool {
ipaddr_is_loopback(&self.resolved_address)
}
}

View File

@ -482,9 +482,7 @@ impl RoutingTable {
) -> Result<NodeRef, String> { ) -> Result<NodeRef, String> {
let nr = self.create_node_ref(node_id)?; let nr = self.create_node_ref(node_id)?;
nr.operate(move |e| -> Result<(), String> { nr.operate(move |e| -> Result<(), String> {
for di in dial_infos { e.update_dial_info(dial_infos);
e.add_dial_info(di.clone())?;
}
Ok(()) Ok(())
})?; })?;

View File

@ -5,7 +5,9 @@ use alloc::fmt;
pub struct NodeRef { pub struct NodeRef {
routing_table: RoutingTable, routing_table: RoutingTable,
node_id: DHTKey, node_id: DHTKey,
protocol_address_type: Option<ProtocolAddressType>, // Filters
protocol_type: Option<ProtocolType>,
address_type: Option<AddressType>,
} }
impl NodeRef { impl NodeRef {
@ -14,20 +16,23 @@ impl NodeRef {
Self { Self {
routing_table, routing_table,
node_id: key, node_id: key,
protocol_address_type: None, protocol_type: None,
address_type: None,
} }
} }
pub fn new_filtered( pub fn new_filtered(
routing_table: RoutingTable, routing_table: RoutingTable,
key: DHTKey, key: DHTKey,
entry: &mut BucketEntry, entry: &mut BucketEntry,
protocol_address_type: ProtocolAddressType, protocol_type: Option<ProtocolType>,
address_type: Option<AddressType>,
) -> Self { ) -> Self {
entry.ref_count += 1; entry.ref_count += 1;
Self { Self {
routing_table, routing_table,
node_id: key, node_id: key,
protocol_address_type: Some(protocol_address_type), protocol_type,
address_type,
} }
} }
@ -35,15 +40,20 @@ impl NodeRef {
self.node_id self.node_id
} }
pub fn protocol_address_type(&self) -> Option<ProtocolAddressType> { pub fn protocol_type(&self) -> Option<ProtocolType> {
self.protocol_address_type self.protocol_type
} }
pub fn set_protocol_address_type( pub fn set_protocol_type(&mut self, protocol_type: Option<ProtocolType>) {
&mut self, self.protocol_type = protocol_type;
protocol_address_type: Option<ProtocolAddressType>, }
) {
self.protocol_address_type = protocol_address_type; pub fn address_type(&self) -> Option<AddressType> {
self.address_type
}
pub fn set_address_type(&mut self, address_type: Option<AddressType>) {
self.address_type = address_type;
} }
pub fn operate<T, F>(&self, f: F) -> T pub fn operate<T, F>(&self, f: F) -> T
@ -53,8 +63,9 @@ impl NodeRef {
self.routing_table.operate_on_bucket_entry(self.node_id, f) self.routing_table.operate_on_bucket_entry(self.node_id, f)
} }
xxx fix the notion of 'best dial info' to sort by capability and udp/tcp/ws/wss preference order
pub fn dial_info(&self) -> Option<DialInfo> { pub fn dial_info(&self) -> Option<DialInfo> {
match self.protocol_address_type { if self.protocol_type || self. {
None => self.operate(|e| e.best_dial_info()), None => self.operate(|e| e.best_dial_info()),
Some(pat) => self.operate(|e| { Some(pat) => self.operate(|e| {
e.filtered_dial_info(|die| die.dial_info().protocol_address_type() == pat) e.filtered_dial_info(|die| die.dial_info().protocol_address_type() == pat)

View File

@ -35,14 +35,6 @@ pub fn encode_address(
.expect("slice with incorrect length"), .expect("slice with incorrect length"),
)); ));
} }
Address::Hostname(h) => {
let mut tb = builder.reborrow().init_hostname(
h.len()
.try_into()
.map_err(map_error_internal!("hostname too long"))?,
);
tb.push_str(h.as_str());
}
}; };
Ok(()) Ok(())
} }
@ -63,7 +55,6 @@ pub fn decode_address(reader: &veilid_capnp::address::Reader) -> Result<Address,
v6b2[1], v6b2[2], v6b2[3], v6b3[0], v6b3[1], v6b3[2], v6b3[3], v6b2[1], v6b2[2], v6b2[3], v6b3[0], v6b3[1], v6b3[2], v6b3[3],
]))) ])))
} }
Ok(veilid_capnp::address::Which::Hostname(Ok(tr))) => Ok(Address::Hostname(tr.to_owned())), _ => Err(rpc_error_protocol("invalid address type")),
_ => Err(rpc_error_internal("invalid address type")),
} }
} }

View File

@ -6,40 +6,40 @@ use rpc_processor::*;
pub fn decode_dial_info(reader: &veilid_capnp::dial_info::Reader) -> Result<DialInfo, RPCError> { pub fn decode_dial_info(reader: &veilid_capnp::dial_info::Reader) -> Result<DialInfo, RPCError> {
match reader.reborrow().which() { match reader.reborrow().which() {
Ok(veilid_capnp::dial_info::Which::Udp(Ok(udp))) => { Ok(veilid_capnp::dial_info::Which::Udp(Ok(udp))) => {
let address_reader = udp let socket_address_reader = udp
.get_address() .get_socket_address()
.map_err(map_error_internal!("missing udp address"))?; .map_err(map_error_protocol!("missing UDP socketAddress"))?;
let address = decode_address(&address_reader)?; let socket_address = decode_socket_address(&socket_address_reader)?;
let port = udp.get_port(); Ok(DialInfo::udp(socket_address))
Ok(DialInfo::udp(address, port))
} }
Ok(veilid_capnp::dial_info::Which::Tcp(Ok(tcp))) => { Ok(veilid_capnp::dial_info::Which::Tcp(Ok(tcp))) => {
let address_reader = tcp let socket_address_reader = tcp
.get_address() .get_socket_address()
.map_err(map_error_internal!("missing tcp address"))?; .map_err(map_error_protocol!("missing TCP socketAddress"))?;
let address = decode_address(&address_reader)?; let socket_address = decode_socket_address(&socket_address_reader)?;
let port = tcp.get_port(); Ok(DialInfo::tcp(socket_address))
Ok(DialInfo::tcp(address, port))
} }
Ok(veilid_capnp::dial_info::Which::Ws(Ok(ws))) => { Ok(veilid_capnp::dial_info::Which::Ws(Ok(ws))) => {
let host = ws let socket_address_reader = ws
.get_host() .get_socket_address()
.map_err(map_error_internal!("missing ws host"))?; .map_err(map_error_protocol!("missing WS socketAddress"))?;
let port = ws.get_port(); let socket_address = decode_socket_address(&socket_address_reader)?;
let path = ws let request = ws
.get_path() .get_request()
.map_err(map_error_internal!("missing ws path"))?; .map_err(map_error_protocol!("missing WS request"))?;
Ok(DialInfo::ws(host.to_owned(), port, path.to_owned())) DialInfo::try_ws(socket_address, request.to_owned())
.map_err(map_error_protocol!("invalid WS dial info"))
} }
Ok(veilid_capnp::dial_info::Which::Wss(Ok(wss))) => { Ok(veilid_capnp::dial_info::Which::Wss(Ok(wss))) => {
let host = wss let socket_address_reader = wss
.get_host() .get_socket_address()
.map_err(map_error_internal!("missing wss host"))?; .map_err(map_error_protocol!("missing WSS socketAddress"))?;
let port = wss.get_port(); let socket_address = decode_socket_address(&socket_address_reader)?;
let path = wss let request = wss
.get_path() .get_request()
.map_err(map_error_internal!("missing wss path"))?; .map_err(map_error_protocol!("missing WSS request"))?;
Ok(DialInfo::wss(host.to_owned(), port, path.to_owned())) DialInfo::try_wss(socket_address, request.to_owned())
.map_err(map_error_protocol!("invalid WSS dial info"))
} }
_ => Err(rpc_error_internal("invalid dial info type")), _ => Err(rpc_error_internal("invalid dial info type")),
} }
@ -52,49 +52,45 @@ pub fn encode_dial_info(
match dial_info { match dial_info {
DialInfo::UDP(udp) => { DialInfo::UDP(udp) => {
let mut di_udp_builder = builder.reborrow().init_udp(); let mut di_udp_builder = builder.reborrow().init_udp();
encode_address(&udp.address, &mut di_udp_builder.reborrow().init_address())?; encode_socket_address(
di_udp_builder.set_port(udp.port); &udp.socket_address,
&mut di_udp_builder.reborrow().init_socket_address(),
)?;
} }
DialInfo::TCP(tcp) => { DialInfo::TCP(tcp) => {
let mut di_tcp_builder = builder.reborrow().init_tcp(); let mut di_tcp_builder = builder.reborrow().init_tcp();
encode_address(&tcp.address, &mut di_tcp_builder.reborrow().init_address())?; encode_socket_address(
di_tcp_builder.set_port(tcp.port); &tcp.socket_address,
&mut di_tcp_builder.reborrow().init_socket_address(),
)?;
} }
DialInfo::WS(ws) => { DialInfo::WS(ws) => {
let mut di_ws_builder = builder.reborrow().init_ws(); let mut di_ws_builder = builder.reborrow().init_ws();
let mut hostb = di_ws_builder.reborrow().init_host( encode_socket_address(
ws.host &ws.socket_address,
&mut di_ws_builder.reborrow().init_socket_address(),
)?;
let mut requestb = di_ws_builder.init_request(
ws.request
.len() .len()
.try_into() .try_into()
.map_err(map_error_internal!("host too long"))?, .map_err(map_error_protocol!("request too long"))?,
); );
hostb.push_str(ws.host.as_str()); requestb.push_str(ws.request.as_str());
di_ws_builder.set_port(ws.port);
let mut pathb = di_ws_builder.init_path(
ws.path
.len()
.try_into()
.map_err(map_error_internal!("path too long"))?,
);
pathb.push_str(ws.path.as_str());
} }
DialInfo::WSS(wss) => { DialInfo::WSS(wss) => {
let mut di_wss_builder = builder.reborrow().init_wss(); let mut di_wss_builder = builder.reborrow().init_wss();
let mut hostb = di_wss_builder.reborrow().init_host( encode_socket_address(
wss.host &wss.socket_address,
&mut di_wss_builder.reborrow().init_socket_address(),
)?;
let mut requestb = di_wss_builder.init_request(
wss.request
.len() .len()
.try_into() .try_into()
.map_err(map_error_internal!("host too long"))?, .map_err(map_error_protocol!("request too long"))?,
); );
hostb.push_str(wss.host.as_str()); requestb.push_str(wss.request.as_str());
di_wss_builder.set_port(wss.port);
let mut pathb = di_wss_builder.init_path(
wss.path
.len()
.try_into()
.map_err(map_error_internal!("path too long"))?,
);
pathb.push_str(wss.path.as_str());
} }
}; };
Ok(()) Ok(())

View File

@ -15,10 +15,10 @@ pub fn encode_node_dial_info_single(
pub fn decode_node_dial_info_single( pub fn decode_node_dial_info_single(
reader: &veilid_capnp::node_dial_info_single::Reader, reader: &veilid_capnp::node_dial_info_single::Reader,
) -> Result<NodeDialInfoSingle, RPCError> { ) -> Result<NodeDialInfoSingle, RPCError> {
let node_id = decode_public_key(&reader.get_node_id().map_err(map_error_internal!( let node_id = decode_public_key(&reader.get_node_id().map_err(map_error_protocol!(
"invalid public key in node_dial_info_single" "invalid public key in node_dial_info_single"
))?); ))?);
let dial_info = decode_dial_info(&reader.get_dial_info().map_err(map_error_internal!( let dial_info = decode_dial_info(&reader.get_dial_info().map_err(map_error_protocol!(
"invalid dial_info in node_dial_info_single" "invalid dial_info in node_dial_info_single"
))?)?; ))?)?;

View File

@ -15,7 +15,7 @@ pub fn encode_peer_info(
.dial_infos .dial_infos
.len() .len()
.try_into() .try_into()
.map_err(map_error_internal!("too many dial infos in peer info"))?, .map_err(map_error_protocol!("too many dial infos in peer info"))?,
); );
for idx in 0..peer_info.dial_infos.len() { for idx in 0..peer_info.dial_infos.len() {
@ -38,7 +38,7 @@ pub fn decode_peer_info(reader: &veilid_capnp::peer_info::Reader) -> Result<Peer
dil_reader dil_reader
.len() .len()
.try_into() .try_into()
.map_err(map_error_internal!("too many dial infos"))?, .map_err(map_error_protocol!("too many dial infos"))?,
); );
for di in dil_reader.iter() { for di in dil_reader.iter() {
dial_infos.push(decode_dial_info(&di)?) dial_infos.push(decode_dial_info(&di)?)

View File

@ -51,7 +51,7 @@ pub fn encode_route_hop_data(
.blob .blob
.len() .len()
.try_into() .try_into()
.map_err(map_error_internal!("invalid blob length in route hop data"))?, .map_err(map_error_protocol!("invalid blob length in route hop data"))?,
); );
blob_builder.copy_from_slice(route_hop_data.blob.as_slice()); blob_builder.copy_from_slice(route_hop_data.blob.as_slice());
Ok(()) Ok(())
@ -120,13 +120,13 @@ pub fn decode_route_hop_data(
&reader &reader
.reborrow() .reborrow()
.get_nonce() .get_nonce()
.map_err(map_error_internal!("invalid nonce in route hop data"))?, .map_err(map_error_protocol!("invalid nonce in route hop data"))?,
); );
let blob = reader let blob = reader
.reborrow() .reborrow()
.get_blob() .get_blob()
.map_err(map_error_internal!("invalid blob in route hop data"))? .map_err(map_error_protocol!("invalid blob in route hop data"))?
.to_vec(); .to_vec();
Ok(RouteHopData { nonce, blob }) Ok(RouteHopData { nonce, blob })
@ -137,13 +137,13 @@ pub fn decode_route_hop(reader: &veilid_capnp::route_hop::Reader) -> Result<Rout
&reader &reader
.reborrow() .reborrow()
.get_dial_info() .get_dial_info()
.map_err(map_error_internal!("invalid dial info in route hop"))?, .map_err(map_error_protocol!("invalid dial info in route hop"))?,
)?; )?;
let next_hop = if reader.has_next_hop() { let next_hop = if reader.has_next_hop() {
let rhd_reader = reader let rhd_reader = reader
.get_next_hop() .get_next_hop()
.map_err(map_error_internal!("invalid next hop in route hop"))?; .map_err(map_error_protocol!("invalid next hop in route hop"))?;
Some(decode_route_hop_data(&rhd_reader)?) Some(decode_route_hop_data(&rhd_reader)?)
} else { } else {
None None
@ -161,13 +161,13 @@ pub fn decode_private_route(
let public_key = decode_public_key( let public_key = decode_public_key(
&reader &reader
.get_public_key() .get_public_key()
.map_err(map_error_internal!("invalid public key in private route"))?, .map_err(map_error_protocol!("invalid public key in private route"))?,
); );
let hop_count = reader.get_hop_count(); let hop_count = reader.get_hop_count();
let hops = if reader.has_first_hop() { let hops = if reader.has_first_hop() {
let rh_reader = reader let rh_reader = reader
.get_first_hop() .get_first_hop()
.map_err(map_error_internal!("invalid first hop in private route"))?; .map_err(map_error_protocol!("invalid first hop in private route"))?;
Some(decode_route_hop(&rh_reader)?) Some(decode_route_hop(&rh_reader)?)
} else { } else {
None None
@ -186,7 +186,7 @@ pub fn decode_safety_route(
let public_key = decode_public_key( let public_key = decode_public_key(
&reader &reader
.get_public_key() .get_public_key()
.map_err(map_error_internal!("invalid public key in safety route"))?, .map_err(map_error_protocol!("invalid public key in safety route"))?,
); );
let hop_count = reader.get_hop_count(); let hop_count = reader.get_hop_count();
let hops = match reader.get_hops().which() { let hops = match reader.get_hops().which() {
@ -197,7 +197,7 @@ pub fn decode_safety_route(
SafetyRouteHops::Private(decode_private_route(&pr_reader)?) SafetyRouteHops::Private(decode_private_route(&pr_reader)?)
} }
_ => { _ => {
return Err(rpc_error_internal("invalid hops in safety route")); return Err(rpc_error_protocol("invalid hops in safety route"));
} }
}; };

View File

@ -23,27 +23,27 @@ pub fn encode_public_key(
builder: &mut veilid_capnp::curve25519_public_key::Builder, builder: &mut veilid_capnp::curve25519_public_key::Builder,
) -> Result<(), RPCError> { ) -> Result<(), RPCError> {
if !key.valid { if !key.valid {
return Err(rpc_error_internal("invalid key")); return Err(rpc_error_protocol("invalid key"));
} }
builder.set_u0(u64::from_be_bytes( builder.set_u0(u64::from_be_bytes(
key.bytes[0..8] key.bytes[0..8]
.try_into() .try_into()
.map_err(map_error_internal!("slice with incorrect length"))?, .map_err(map_error_protocol!("slice with incorrect length"))?,
)); ));
builder.set_u1(u64::from_be_bytes( builder.set_u1(u64::from_be_bytes(
key.bytes[8..16] key.bytes[8..16]
.try_into() .try_into()
.map_err(map_error_internal!("slice with incorrect length"))?, .map_err(map_error_protocol!("slice with incorrect length"))?,
)); ));
builder.set_u2(u64::from_be_bytes( builder.set_u2(u64::from_be_bytes(
key.bytes[16..24] key.bytes[16..24]
.try_into() .try_into()
.map_err(map_error_internal!("slice with incorrect length"))?, .map_err(map_error_protocol!("slice with incorrect length"))?,
)); ));
builder.set_u3(u64::from_be_bytes( builder.set_u3(u64::from_be_bytes(
key.bytes[24..32] key.bytes[24..32]
.try_into() .try_into()
.map_err(map_error_internal!("slice with incorrect length"))?, .map_err(map_error_protocol!("slice with incorrect length"))?,
)); ));
Ok(()) Ok(())
} }

View File

@ -1,72 +1,25 @@
use crate::xx::*;
use crate::*; use crate::*;
use core::convert::TryInto;
use rpc_processor::*; use rpc_processor::*;
pub fn encode_socket_address( pub fn encode_socket_address(
address: &SocketAddr, socket_address: &SocketAddress,
builder: &mut veilid_capnp::socket_address::Builder, builder: &mut veilid_capnp::socket_address::Builder,
) -> Result<(), RPCError> { ) -> Result<(), RPCError> {
match address { let mut ab = builder.reborrow().init_address();
SocketAddr::V4(v4) => { encode_address(&socket_address.address(), &mut ab)?;
let mut v4b = builder.reborrow().init_ipv4(); builder.set_port(socket_address.port());
v4b.set_addr(u32::from_be_bytes(v4.ip().octets()));
builder.set_port(v4.port());
}
SocketAddr::V6(v6) => {
let mut v6b = builder.reborrow().init_ipv6();
v6b.set_addr0(u32::from_be_bytes(
v6.ip().octets()[0..4]
.try_into()
.expect("slice with incorrect length"),
));
v6b.set_addr1(u32::from_be_bytes(
v6.ip().octets()[4..8]
.try_into()
.expect("slice with incorrect length"),
));
v6b.set_addr2(u32::from_be_bytes(
v6.ip().octets()[8..12]
.try_into()
.expect("slice with incorrect length"),
));
v6b.set_addr3(u32::from_be_bytes(
v6.ip().octets()[12..16]
.try_into()
.expect("slice with incorrect length"),
));
builder.set_port(v6.port());
}
};
Ok(()) Ok(())
} }
pub fn decode_socket_address( pub fn decode_socket_address(
reader: &veilid_capnp::socket_address::Reader, reader: &veilid_capnp::socket_address::Reader,
) -> Result<SocketAddr, RPCError> { ) -> Result<SocketAddress, RPCError> {
match reader.reborrow().which() { let ar = reader
Ok(veilid_capnp::socket_address::Which::Ipv4(Ok(v4))) => { .reborrow()
let v4b = v4.get_addr().to_be_bytes(); .get_address()
Ok(SocketAddr::V4(SocketAddrV4::new( .map_err(map_error_internal!("missing socketAddress"))?;
Ipv4Addr::new(v4b[0], v4b[1], v4b[2], v4b[3]), let address = decode_address(&ar)?;
reader.get_port(), let port = reader.get_port();
)))
} Ok(SocketAddress::new(address, port))
Ok(veilid_capnp::socket_address::Which::Ipv6(Ok(v6))) => {
let v6b0 = v6.get_addr0().to_be_bytes();
let v6b1 = v6.get_addr1().to_be_bytes();
let v6b2 = v6.get_addr2().to_be_bytes();
let v6b3 = v6.get_addr3().to_be_bytes();
Ok(SocketAddr::V6(SocketAddrV6::new(
Ipv6Addr::from([
v6b0[0], v6b0[1], v6b0[2], v6b0[3], v6b1[0], v6b1[1], v6b1[2], v6b1[3],
v6b2[0], v6b2[1], v6b2[2], v6b2[3], v6b3[0], v6b3[1], v6b3[2], v6b3[3],
]),
reader.get_port(),
0,
0,
)))
}
_ => Err(rpc_error_internal("invalid socket address type")),
}
} }

View File

@ -12,8 +12,12 @@ pub fn rpc_error_internal<T: AsRef<str>>(x: T) -> RPCError {
error!("RPCError Internal: {}", x.as_ref()); error!("RPCError Internal: {}", x.as_ref());
RPCError::Internal(x.as_ref().to_owned()) RPCError::Internal(x.as_ref().to_owned())
} }
pub fn rpc_error_protocol<T: AsRef<str>>(x: T) -> RPCError {
error!("RPCError Protocol: {}", x.as_ref());
RPCError::Protocol(x.as_ref().to_owned())
}
pub fn rpc_error_capnp_error(e: capnp::Error) -> RPCError { pub fn rpc_error_capnp_error(e: capnp::Error) -> RPCError {
error!("RPCError Protocol: {}", &e.description); error!("RPCError Protocol: capnp error: {}", &e.description);
RPCError::Protocol(e.description) RPCError::Protocol(e.description)
} }
pub fn rpc_error_capnp_notinschema(e: capnp::NotInSchema) -> RPCError { pub fn rpc_error_capnp_notinschema(e: capnp::NotInSchema) -> RPCError {
@ -44,12 +48,17 @@ macro_rules! map_error_internal {
}; };
} }
#[macro_export] #[macro_export]
macro_rules! map_error_protocol {
($x:expr) => {
|_| rpc_error_protocol($x)
};
}
#[macro_export]
macro_rules! map_error_string { macro_rules! map_error_string {
() => { () => {
|s| rpc_error_internal(&s) |s| rpc_error_internal(&s)
}; };
} }
#[macro_export] #[macro_export]
macro_rules! map_error_capnp_error { macro_rules! map_error_capnp_error {
() => { () => {

View File

@ -779,7 +779,7 @@ impl RPCProcessor {
.peer_noderef .peer_noderef
.operate(|entry| match entry.last_connection() { .operate(|entry| match entry.last_connection() {
None => None, None => None,
Some(c) => c.remote.to_socket_addr().ok(), Some(c) => Some(c.remote.to_socket_addr()),
}); });
SenderInfo { socket_address } SenderInfo { socket_address }
} }
@ -955,7 +955,7 @@ impl RPCProcessor {
let address_filter = self.config.get().network.address_filter; let address_filter = self.config.get().network.address_filter;
if address_filter { if address_filter {
for di in &peer_info.dial_infos { for di in &peer_info.dial_infos {
if !di.is_public().map_err(map_error_string!())? { if !di.is_global() {
// non-public address causes rejection // non-public address causes rejection
return Err(RPCError::InvalidFormat); return Err(RPCError::InvalidFormat);
} }
@ -1508,7 +1508,7 @@ impl RPCProcessor {
// reject attempts to include non-public addresses in results // reject attempts to include non-public addresses in results
if address_filter { if address_filter {
for di in &peer_info.dial_infos { for di in &peer_info.dial_infos {
if !di.is_public().map_err(map_error_string!())? { if !di.is_global() {
// non-public address causes rejection // non-public address causes rejection
return Err(RPCError::InvalidFormat); return Err(RPCError::InvalidFormat);
} }

View File

@ -11,53 +11,48 @@ pub async fn test_add_get_remove() {
let c3 = NetworkConnection::Dummy(DummyNetworkConnection {}); let c3 = NetworkConnection::Dummy(DummyNetworkConnection {});
let a1 = ConnectionDescriptor::new_no_local(PeerAddress::new( let a1 = ConnectionDescriptor::new_no_local(PeerAddress::new(
Address::IPV4(Ipv4Addr::new(127, 0, 0, 1)), SocketAddress::new(Address::IPV4(Ipv4Addr::new(127, 0, 0, 1)), 8080),
8080,
ProtocolType::TCP, ProtocolType::TCP,
)); ));
let a2 = ConnectionDescriptor::new_no_local(PeerAddress::new( let a2 = ConnectionDescriptor::new_no_local(PeerAddress::new(
Address::IPV4(Ipv4Addr::new(127, 0, 0, 1)), SocketAddress::new(Address::IPV4(Ipv4Addr::new(127, 0, 0, 1)), 8080),
8080,
ProtocolType::TCP, ProtocolType::TCP,
)); ));
let a3 = ConnectionDescriptor::new( let a3 = ConnectionDescriptor::new(
PeerAddress::new( PeerAddress::new(
Address::IPV6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), SocketAddress::new(Address::IPV6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), 8090),
8090,
ProtocolType::TCP, ProtocolType::TCP,
), ),
SocketAddr::V6(SocketAddrV6::new( SocketAddress::from_socket_addr(SocketAddr::V6(SocketAddrV6::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
8080, 8080,
0, 0,
0, 0,
)), ))),
); );
let a4 = ConnectionDescriptor::new( let a4 = ConnectionDescriptor::new(
PeerAddress::new( PeerAddress::new(
Address::IPV6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), SocketAddress::new(Address::IPV6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), 8090),
8090,
ProtocolType::TCP, ProtocolType::TCP,
), ),
SocketAddr::V6(SocketAddrV6::new( SocketAddress::from_socket_addr(SocketAddr::V6(SocketAddrV6::new(
Ipv6Addr::new(1, 0, 0, 0, 0, 0, 0, 1), Ipv6Addr::new(1, 0, 0, 0, 0, 0, 0, 1),
8080, 8080,
0, 0,
0, 0,
)), ))),
); );
let a5 = ConnectionDescriptor::new( let a5 = ConnectionDescriptor::new(
PeerAddress::new( PeerAddress::new(
Address::Hostname("example.com".to_owned()), SocketAddress::new(Address::IPV6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), 8090),
8090,
ProtocolType::WSS, ProtocolType::WSS,
), ),
SocketAddr::V6(SocketAddrV6::new( SocketAddress::from_socket_addr(SocketAddr::V6(SocketAddrV6::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
8080, 8080,
0, 0,
0, 0,
)), ))),
); );
assert_eq!(a1, a2); assert_eq!(a1, a2);

View File

@ -155,7 +155,7 @@ impl BlockId {
#[derive(Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash, Default)] #[derive(Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash, Default)]
pub struct SenderInfo { pub struct SenderInfo {
pub socket_address: Option<SocketAddr>, pub socket_address: Option<SocketAddress>,
} }
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
@ -173,6 +173,8 @@ pub struct NodeInfo {
} }
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash)] #[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash)]
// The derived ordering here is the order of preference, lower is preferred for connections
// Must match DialInfo order
pub enum ProtocolType { pub enum ProtocolType {
UDP, UDP,
TCP, TCP,
@ -181,11 +183,9 @@ pub enum ProtocolType {
} }
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash)] #[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash)]
pub enum ProtocolNetworkType { pub enum AddressType {
UDPv4, IPV4,
UDPv6, IPV6,
TCPv4,
TCPv6,
} }
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash)] #[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash)]
@ -207,6 +207,12 @@ impl Address {
SocketAddr::V6(v6) => Address::IPV6(*v6.ip()), SocketAddr::V6(v6) => Address::IPV6(*v6.ip()),
} }
} }
pub fn address_type(&self) -> AddressType {
match self {
Address::IPV4(v4) => AddressType::IPV4,
Address::IPV6(v6) => AddressType::IPV6,
}
}
pub fn address_string(&self) -> String { pub fn address_string(&self) -> String {
match self { match self {
Address::IPV4(v4) => v4.to_string(), Address::IPV4(v4) => v4.to_string(),
@ -219,13 +225,13 @@ impl Address {
Address::IPV6(v6) => format!("[{}]:{}", v6.to_string(), port), Address::IPV6(v6) => format!("[{}]:{}", v6.to_string(), port),
} }
} }
pub fn is_public(&self) -> bool { pub fn is_global(&self) -> bool {
match self { match self {
Address::IPV4(v4) => ipv4addr_is_global(&v4), Address::IPV4(v4) => ipv4addr_is_global(&v4),
Address::IPV6(v6) => ipv6addr_is_global(&v6), Address::IPV6(v6) => ipv6addr_is_global(&v6),
} }
} }
pub fn is_private(&self) -> bool { pub fn is_local(&self) -> bool {
match self { match self {
Address::IPV4(v4) => ipv4addr_is_private(&v4), Address::IPV4(v4) => ipv4addr_is_private(&v4),
Address::IPV6(v6) => ipv6addr_is_unicast_site_local(&v6), Address::IPV6(v6) => ipv6addr_is_unicast_site_local(&v6),
@ -283,6 +289,9 @@ impl SocketAddress {
pub fn address(&self) -> Address { pub fn address(&self) -> Address {
self.address self.address
} }
pub fn address_type(&self) -> AddressType {
self.address.address_type()
}
pub fn port(&self) -> u16 { pub fn port(&self) -> u16 {
self.port self.port
} }
@ -346,6 +355,8 @@ pub struct DialInfoWSS {
} }
#[derive(Clone, Debug, PartialEq, PartialOrd, Ord, Eq)] #[derive(Clone, Debug, PartialEq, PartialOrd, Ord, Eq)]
// The derived ordering here is the order of preference, lower is preferred for connections
// Must match ProtocolType order
pub enum DialInfo { pub enum DialInfo {
UDP(DialInfoUDP), UDP(DialInfoUDP),
TCP(DialInfoTCP), TCP(DialInfoTCP),
@ -479,25 +490,8 @@ impl DialInfo {
Self::WSS(_) => ProtocolType::WSS, Self::WSS(_) => ProtocolType::WSS,
} }
} }
pub fn protocol_network_type(&self) -> ProtocolNetworkType { pub fn address_type(&self) -> AddressType {
match self { self.socket_address().address_type()
Self::UDP(di) => match di.socket_address.address() {
Address::IPV4(_) => ProtocolNetworkType::UDPv4,
Address::IPV6(_) => ProtocolNetworkType::UDPv6,
},
Self::TCP(di) => match di.socket_address.address() {
Address::IPV4(_) => ProtocolNetworkType::TCPv4,
Address::IPV6(_) => ProtocolNetworkType::TCPv6,
},
Self::WS(di) => match di.socket_address.address() {
Address::IPV4(_) => ProtocolNetworkType::TCPv4,
Address::IPV6(_) => ProtocolNetworkType::TCPv6,
},
Self::WSS(di) => match di.socket_address.address() {
Address::IPV4(_) => ProtocolNetworkType::TCPv4,
Address::IPV6(_) => ProtocolNetworkType::TCPv6,
},
}
} }
pub fn socket_address(&self) -> SocketAddress { pub fn socket_address(&self) -> SocketAddress {
match self { match self {
@ -539,19 +533,24 @@ impl DialInfo {
Self::WSS(di) => Some(format!("wss://{}", di.request)), Self::WSS(di) => Some(format!("wss://{}", di.request)),
} }
} }
pub fn is_public(&self) -> bool { pub fn is_global(&self) -> bool {
self.socket_address().address().is_public() self.socket_address().address().is_global()
} }
pub fn is_local(&self) -> bool {
pub fn is_private(&self) -> bool { self.socket_address().address().is_local()
self.socket_address().address().is_private()
} }
pub fn is_valid(&self) -> bool { pub fn is_valid(&self) -> bool {
let socket_address = self.socket_address(); let socket_address = self.socket_address();
let address = socket_address.address(); let address = socket_address.address();
let port = socket_address.port(); let port = socket_address.port();
(address.is_public() || address.is_private()) && port > 0 (address.is_global() || address.is_local()) && port > 0
}
pub fn matches_peer_scope(&self, scope: PeerScope) -> bool {
match scope {
PeerScope::All => true,
PeerScope::Global => self.is_global(),
PeerScope::Local => self.is_local(),
}
} }
} }
@ -579,7 +578,7 @@ pub struct PeerAddress {
impl PeerAddress { impl PeerAddress {
pub fn new(socket_address: SocketAddress, protocol_type: ProtocolType) -> Self { pub fn new(socket_address: SocketAddress, protocol_type: ProtocolType) -> Self {
Self { Self {
socket_address, socket_address: socket_address.to_canonical(),
protocol_type, protocol_type,
} }
} }
@ -588,36 +587,19 @@ impl PeerAddress {
self.socket_address.to_socket_addr() self.socket_address.to_socket_addr()
} }
pub fn protocol_network_type(&self) -> ProtocolNetworkType { pub fn address_type(&self) -> AddressType {
match self.protocol_type { self.socket_address.address_type()
ProtocolType::UDP => match self.socket_address.address() {
Address::IPV4(_) => ProtocolNetworkType::UDPv4,
Address::IPV6(_) => ProtocolNetworkType::UDPv6,
},
ProtocolType::TCP => match self.socket_address.address() {
Address::IPV4(_) => ProtocolNetworkType::TCPv4,
Address::IPV6(_) => ProtocolNetworkType::TCPv6,
},
ProtocolType::WS => match self.socket_address.address() {
Address::IPV4(_) => ProtocolNetworkType::TCPv4,
Address::IPV6(_) => ProtocolNetworkType::TCPv6,
},
ProtocolType::WSS => match self.socket_address.address() {
Address::IPV4(_) => ProtocolNetworkType::TCPv4,
Address::IPV6(_) => ProtocolNetworkType::TCPv6,
},
}
} }
} }
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ConnectionDescriptor { pub struct ConnectionDescriptor {
pub remote: PeerAddress, pub remote: PeerAddress,
pub local: Option<SocketAddr>, pub local: Option<SocketAddress>,
} }
impl ConnectionDescriptor { impl ConnectionDescriptor {
pub fn new(remote: PeerAddress, local: SocketAddr) -> Self { pub fn new(remote: PeerAddress, local: SocketAddress) -> Self {
Self { Self {
remote, remote,
local: Some(local), local: Some(local),
@ -632,8 +614,8 @@ impl ConnectionDescriptor {
pub fn protocol_type(&self) -> ProtocolType { pub fn protocol_type(&self) -> ProtocolType {
self.remote.protocol_type self.remote.protocol_type
} }
pub fn protocol_network_type(&self) -> ProtocolNetworkType { pub fn address_type(&self) -> AddressType {
self.remote.protocol_network_type() self.remote.address_type()
} }
} }
@ -1074,7 +1056,7 @@ impl VeilidAPI {
let answer = node_ref.operate(|e| SearchDHTAnswer { let answer = node_ref.operate(|e| SearchDHTAnswer {
node_id: NodeId::new(node_ref.node_id()), node_id: NodeId::new(node_ref.node_id()),
dial_info: e.dial_info(), dial_info: e.dial_infos().to_vec(),
}); });
Ok(answer) Ok(answer)
@ -1104,7 +1086,7 @@ impl VeilidAPI {
for nr in node_refs { for nr in node_refs {
let a = nr.operate(|e| SearchDHTAnswer { let a = nr.operate(|e| SearchDHTAnswer {
node_id: NodeId::new(nr.node_id()), node_id: NodeId::new(nr.node_id()),
dial_info: e.dial_info(), dial_info: e.dial_infos().to_vec(),
}); });
answer.push(a); answer.push(a);
} }