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

View File

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

View File

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

View File

@ -221,11 +221,8 @@ impl WebsocketProtocolHandler {
ProtocolType::WS
};
let peer_addr = PeerAddress::new(
Address::from_socket_addr(socket_addr),
socket_addr.port(),
protocol_type,
);
let peer_addr =
PeerAddress::new(SocketAddress::from_socket_addr(socket_addr), protocol_type);
let conn = NetworkConnection::WsAccepted(WebsocketNetworkConnection::new(
self.inner.tls,
@ -235,7 +232,10 @@ impl WebsocketProtocolHandler {
.network_manager
.clone()
.on_new_connection(
ConnectionDescriptor::new(peer_addr, self.inner.local_address),
ConnectionDescriptor::new(
peer_addr,
SocketAddress::from_socket_addr(self.inner.local_address),
),
conn,
)
.await?;
@ -248,27 +248,20 @@ impl WebsocketProtocolHandler {
dial_info: &DialInfo,
) -> Result<NetworkConnection, String> {
// Split dial info up
let (tls, request, domain, port, protocol_type) = match &dial_info {
DialInfo::WS(di) => (
false,
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,
),
let (tls, protocol_type, scheme) = match &dial_info {
DialInfo::WS(_) => (false, ProtocolType::WS, "ws"),
DialInfo::WSS(_) => (true, ProtocolType::WSS, "wss"),
_ => 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
let remote_ip_addr = dial_info.resolve()?;
let remote_socket_addr = SocketAddr::new(remote_ip_addr, port);
let remote_socket_addr = dial_info.to_socket_addr();
// Make a shared socket
let socket = new_shared_tcp_socket(local_address)?;
@ -304,15 +297,17 @@ impl WebsocketProtocolHandler {
// Make the connection descriptor peer address
let peer_addr = PeerAddress::new(
Address::from_socket_addr(remote_socket_addr),
port,
SocketAddress::from_socket_addr(remote_socket_addr),
ProtocolType::WSS,
);
// Register the WSS connection
network_manager
.on_new_connection(
ConnectionDescriptor::new(peer_addr, actual_local_addr),
ConnectionDescriptor::new(
peer_addr,
SocketAddress::from_socket_addr(actual_local_addr),
),
conn.clone(),
)
.await?;
@ -326,15 +321,17 @@ impl WebsocketProtocolHandler {
// Make the connection descriptor peer address
let peer_addr = PeerAddress::new(
Address::from_socket_addr(remote_socket_addr),
port,
SocketAddress::from_socket_addr(remote_socket_addr),
ProtocolType::WS,
);
// Register the WS connection
network_manager
.on_new_connection(
ConnectionDescriptor::new(peer_addr, actual_local_addr),
ConnectionDescriptor::new(
peer_addr,
SocketAddress::from_socket_addr(actual_local_addr),
),
conn.clone(),
)
.await?;

View File

@ -12,12 +12,15 @@ pub use protocol::*;
struct NetworkInner {
network_manager: NetworkManager,
stop_network: Eventual,
network_started: bool,
network_needs_restart: bool,
protocol_config: Option<ProtocolConfig>,
//join_handle: TryJoin?
}
#[derive(Clone)]
pub struct Network {
config: VeilidConfig,
inner: Arc<Mutex<NetworkInner>>,
}
@ -26,13 +29,15 @@ impl Network {
NetworkInner {
network_manager,
stop_network: Eventual::new(),
network_started: false,
network_needs_restart: false,
//join_handle: None,
protocol_config: None, //join_handle: None,
}
}
pub fn new(network_manager: NetworkManager) -> Self {
Self {
config: network_manager.config(),
inner: Arc::new(Mutex::new(Self::new_inner(network_manager))),
}
}
@ -150,10 +155,21 @@ impl Network {
/////////////////////////////////////////////////////////////////
pub async fn startup(&self) -> Result<(), String> {
//let network_manager = self.inner.lock().network_manager.clone();
//let config_shared = network_manager.core().config();
//let config = config_shared.get();
// get protocol config
self.inner.lock().protocol_config = Some({
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(())
}
@ -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?
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 {
return false;
}
let network_class = inner.network_manager.get_network_class();
match network_class {
NetworkClass::Server => true,
NetworkClass::Mapped => true,
NetworkClass::FullNAT => true,
NetworkClass::AddressRestrictedNAT => false,
NetworkClass::PortRestrictedNAT => false,
NetworkClass::OutboundOnly => false,
NetworkClass::WebApp => false,
NetworkClass::TorWebApp => false,
NetworkClass::Invalid => false,
if let Some(network_class) = inner.network_manager.get_network_class() {
match network_class {
NetworkClass::Server => true,
NetworkClass::Mapped => true,
NetworkClass::FullNAT => true,
NetworkClass::AddressRestrictedNAT => false,
NetworkClass::PortRestrictedNAT => false,
NetworkClass::OutboundOnly => false,
NetworkClass::WebApp => false,
NetworkClass::TorWebApp => false,
NetworkClass::Invalid => false,
}
} else {
false
}
}
pub fn server_will_provide_signal_lease(&self) -> bool {
@ -152,17 +155,20 @@ impl LeaseManager {
if inner.max_server_signal_leases == 0 {
return false;
}
let network_class = inner.network_manager.get_network_class();
match network_class {
NetworkClass::Server => true,
NetworkClass::Mapped => true,
NetworkClass::FullNAT => true,
NetworkClass::AddressRestrictedNAT => false,
NetworkClass::PortRestrictedNAT => false,
NetworkClass::OutboundOnly => false,
NetworkClass::WebApp => false,
NetworkClass::TorWebApp => false,
NetworkClass::Invalid => false,
if let Some(network_class) = inner.network_manager.get_network_class() {
match network_class {
NetworkClass::Server => true,
NetworkClass::Mapped => true,
NetworkClass::FullNAT => true,
NetworkClass::AddressRestrictedNAT => false,
NetworkClass::PortRestrictedNAT => false,
NetworkClass::OutboundOnly => false,
NetworkClass::WebApp => false,
NetworkClass::TorWebApp => false,
NetworkClass::Invalid => false,
}
} else {
false
}
// 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
// Routing table is not in here because we want it to survive a network shutdown/startup restart
#[derive(Clone)]
@ -381,11 +392,20 @@ impl NetworkManager {
}
// 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 {
components.net.get_network_class()
} 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,
min_max_version: Option<(u8, u8)>,
last_connection: Option<(ConnectionDescriptor, u64)>,
dial_info_entries: VecDeque<DialInfoEntry>,
dial_infos: Vec<DialInfo>,
stats_accounting: StatsAccounting,
peer_stats: PeerStats,
}
@ -43,7 +43,7 @@ impl BucketEntry {
ref_count: 0,
min_max_version: None,
last_connection: None,
dial_info_entries: VecDeque::new(),
dial_infos: Vec::new(),
stats_accounting: StatsAccounting::new(),
peer_stats: PeerStats {
time_added: now,
@ -56,145 +56,48 @@ impl BucketEntry {
}
}
pub fn add_dial_info(&mut self, dial_info: DialInfo) -> Result<(), String> {
let mut idx: Option<usize> = None;
for i in 0..self.dial_info_entries.len() {
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 update_dial_infos(&mut self, dial_infos: &[DialInfo]) {
self.dial_infos = dial_infos.to_vec();
self.dial_infos.sort();
}
pub fn best_dial_info(&self) -> Option<DialInfo> {
self.dial_info_entries
.front()
.map(|die| die.dial_info().clone())
}
pub fn filtered_dial_info<F>(&self, filter: F) -> Option<DialInfo>
pub fn first_filtered_dial_info<F>(&self, filter: F) -> Option<DialInfo>
where
F: Fn(&DialInfoEntry) -> bool,
F: Fn(&DialInfo) -> bool,
{
for die in &self.dial_info_entries {
if filter(die) {
return Some(die.dial_info().clone());
for di in &self.dial_infos {
if filter(di) {
return Some(di.clone());
}
}
None
}
pub fn dial_info_entries_as_ref(&self) -> &VecDeque<DialInfoEntry> {
&self.dial_info_entries
pub fn all_filtered_dial_infos<F>(&self, filter: F) -> Vec<DialInfo>
where
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> {
self.dial_info_entries
.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 dial_infos(&self) -> &[DialInfo] {
&self.dial_infos.clone()
}
pub fn get_peer_info(&self, key: DHTKey, scope: PeerScope) -> PeerInfo {
PeerInfo {
node_id: NodeId::new(key),
dial_infos: match scope {
PeerScope::All => self.dial_info(),
PeerScope::Global => self.global_dial_info(),
PeerScope::Local => self.local_dial_info(),
},
dial_infos: self.all_filtered_dial_infos(|di| di.matches_peer_scope(scope)),
}
}
pub fn set_last_connection(&mut self, last_connection: ConnectionDescriptor, timestamp: u64) {
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> {

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> {
let nr = self.create_node_ref(node_id)?;
nr.operate(move |e| -> Result<(), String> {
for di in dial_infos {
e.add_dial_info(di.clone())?;
}
e.update_dial_info(dial_infos);
Ok(())
})?;

View File

@ -5,7 +5,9 @@ use alloc::fmt;
pub struct NodeRef {
routing_table: RoutingTable,
node_id: DHTKey,
protocol_address_type: Option<ProtocolAddressType>,
// Filters
protocol_type: Option<ProtocolType>,
address_type: Option<AddressType>,
}
impl NodeRef {
@ -14,20 +16,23 @@ impl NodeRef {
Self {
routing_table,
node_id: key,
protocol_address_type: None,
protocol_type: None,
address_type: None,
}
}
pub fn new_filtered(
routing_table: RoutingTable,
key: DHTKey,
entry: &mut BucketEntry,
protocol_address_type: ProtocolAddressType,
protocol_type: Option<ProtocolType>,
address_type: Option<AddressType>,
) -> Self {
entry.ref_count += 1;
Self {
routing_table,
node_id: key,
protocol_address_type: Some(protocol_address_type),
protocol_type,
address_type,
}
}
@ -35,15 +40,20 @@ impl NodeRef {
self.node_id
}
pub fn protocol_address_type(&self) -> Option<ProtocolAddressType> {
self.protocol_address_type
pub fn protocol_type(&self) -> Option<ProtocolType> {
self.protocol_type
}
pub fn set_protocol_address_type(
&mut self,
protocol_address_type: Option<ProtocolAddressType>,
) {
self.protocol_address_type = protocol_address_type;
pub fn set_protocol_type(&mut self, protocol_type: Option<ProtocolType>) {
self.protocol_type = protocol_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
@ -53,8 +63,9 @@ impl NodeRef {
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> {
match self.protocol_address_type {
if self.protocol_type || self. {
None => self.operate(|e| e.best_dial_info()),
Some(pat) => self.operate(|e| {
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"),
));
}
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(())
}
@ -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],
])))
}
Ok(veilid_capnp::address::Which::Hostname(Ok(tr))) => Ok(Address::Hostname(tr.to_owned())),
_ => Err(rpc_error_internal("invalid address type")),
_ => Err(rpc_error_protocol("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> {
match reader.reborrow().which() {
Ok(veilid_capnp::dial_info::Which::Udp(Ok(udp))) => {
let address_reader = udp
.get_address()
.map_err(map_error_internal!("missing udp address"))?;
let address = decode_address(&address_reader)?;
let port = udp.get_port();
Ok(DialInfo::udp(address, port))
let socket_address_reader = udp
.get_socket_address()
.map_err(map_error_protocol!("missing UDP socketAddress"))?;
let socket_address = decode_socket_address(&socket_address_reader)?;
Ok(DialInfo::udp(socket_address))
}
Ok(veilid_capnp::dial_info::Which::Tcp(Ok(tcp))) => {
let address_reader = tcp
.get_address()
.map_err(map_error_internal!("missing tcp address"))?;
let address = decode_address(&address_reader)?;
let port = tcp.get_port();
Ok(DialInfo::tcp(address, port))
let socket_address_reader = tcp
.get_socket_address()
.map_err(map_error_protocol!("missing TCP socketAddress"))?;
let socket_address = decode_socket_address(&socket_address_reader)?;
Ok(DialInfo::tcp(socket_address))
}
Ok(veilid_capnp::dial_info::Which::Ws(Ok(ws))) => {
let host = ws
.get_host()
.map_err(map_error_internal!("missing ws host"))?;
let port = ws.get_port();
let path = ws
.get_path()
.map_err(map_error_internal!("missing ws path"))?;
Ok(DialInfo::ws(host.to_owned(), port, path.to_owned()))
let socket_address_reader = ws
.get_socket_address()
.map_err(map_error_protocol!("missing WS socketAddress"))?;
let socket_address = decode_socket_address(&socket_address_reader)?;
let request = ws
.get_request()
.map_err(map_error_protocol!("missing WS request"))?;
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))) => {
let host = wss
.get_host()
.map_err(map_error_internal!("missing wss host"))?;
let port = wss.get_port();
let path = wss
.get_path()
.map_err(map_error_internal!("missing wss path"))?;
Ok(DialInfo::wss(host.to_owned(), port, path.to_owned()))
let socket_address_reader = wss
.get_socket_address()
.map_err(map_error_protocol!("missing WSS socketAddress"))?;
let socket_address = decode_socket_address(&socket_address_reader)?;
let request = wss
.get_request()
.map_err(map_error_protocol!("missing WSS request"))?;
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")),
}
@ -52,49 +52,45 @@ pub fn encode_dial_info(
match dial_info {
DialInfo::UDP(udp) => {
let mut di_udp_builder = builder.reborrow().init_udp();
encode_address(&udp.address, &mut di_udp_builder.reborrow().init_address())?;
di_udp_builder.set_port(udp.port);
encode_socket_address(
&udp.socket_address,
&mut di_udp_builder.reborrow().init_socket_address(),
)?;
}
DialInfo::TCP(tcp) => {
let mut di_tcp_builder = builder.reborrow().init_tcp();
encode_address(&tcp.address, &mut di_tcp_builder.reborrow().init_address())?;
di_tcp_builder.set_port(tcp.port);
encode_socket_address(
&tcp.socket_address,
&mut di_tcp_builder.reborrow().init_socket_address(),
)?;
}
DialInfo::WS(ws) => {
let mut di_ws_builder = builder.reborrow().init_ws();
let mut hostb = di_ws_builder.reborrow().init_host(
ws.host
encode_socket_address(
&ws.socket_address,
&mut di_ws_builder.reborrow().init_socket_address(),
)?;
let mut requestb = di_ws_builder.init_request(
ws.request
.len()
.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());
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());
requestb.push_str(ws.request.as_str());
}
DialInfo::WSS(wss) => {
let mut di_wss_builder = builder.reborrow().init_wss();
let mut hostb = di_wss_builder.reborrow().init_host(
wss.host
encode_socket_address(
&wss.socket_address,
&mut di_wss_builder.reborrow().init_socket_address(),
)?;
let mut requestb = di_wss_builder.init_request(
wss.request
.len()
.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());
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());
requestb.push_str(wss.request.as_str());
}
};
Ok(())

View File

@ -15,10 +15,10 @@ pub fn encode_node_dial_info_single(
pub fn decode_node_dial_info_single(
reader: &veilid_capnp::node_dial_info_single::Reader,
) -> 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"
))?);
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"
))?)?;

View File

@ -15,7 +15,7 @@ pub fn encode_peer_info(
.dial_infos
.len()
.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() {
@ -38,7 +38,7 @@ pub fn decode_peer_info(reader: &veilid_capnp::peer_info::Reader) -> Result<Peer
dil_reader
.len()
.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() {
dial_infos.push(decode_dial_info(&di)?)

View File

@ -51,7 +51,7 @@ pub fn encode_route_hop_data(
.blob
.len()
.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());
Ok(())
@ -120,13 +120,13 @@ pub fn decode_route_hop_data(
&reader
.reborrow()
.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
.reborrow()
.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();
Ok(RouteHopData { nonce, blob })
@ -137,13 +137,13 @@ pub fn decode_route_hop(reader: &veilid_capnp::route_hop::Reader) -> Result<Rout
&reader
.reborrow()
.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 rhd_reader = reader
.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)?)
} else {
None
@ -161,13 +161,13 @@ pub fn decode_private_route(
let public_key = decode_public_key(
&reader
.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 hops = if reader.has_first_hop() {
let rh_reader = reader
.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)?)
} else {
None
@ -186,7 +186,7 @@ pub fn decode_safety_route(
let public_key = decode_public_key(
&reader
.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 hops = match reader.get_hops().which() {
@ -197,7 +197,7 @@ pub fn decode_safety_route(
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,
) -> Result<(), RPCError> {
if !key.valid {
return Err(rpc_error_internal("invalid key"));
return Err(rpc_error_protocol("invalid key"));
}
builder.set_u0(u64::from_be_bytes(
key.bytes[0..8]
.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(
key.bytes[8..16]
.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(
key.bytes[16..24]
.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(
key.bytes[24..32]
.try_into()
.map_err(map_error_internal!("slice with incorrect length"))?,
.map_err(map_error_protocol!("slice with incorrect length"))?,
));
Ok(())
}

View File

@ -1,72 +1,25 @@
use crate::xx::*;
use crate::*;
use core::convert::TryInto;
use rpc_processor::*;
pub fn encode_socket_address(
address: &SocketAddr,
socket_address: &SocketAddress,
builder: &mut veilid_capnp::socket_address::Builder,
) -> Result<(), RPCError> {
match address {
SocketAddr::V4(v4) => {
let mut v4b = builder.reborrow().init_ipv4();
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());
}
};
let mut ab = builder.reborrow().init_address();
encode_address(&socket_address.address(), &mut ab)?;
builder.set_port(socket_address.port());
Ok(())
}
pub fn decode_socket_address(
reader: &veilid_capnp::socket_address::Reader,
) -> Result<SocketAddr, RPCError> {
match reader.reborrow().which() {
Ok(veilid_capnp::socket_address::Which::Ipv4(Ok(v4))) => {
let v4b = v4.get_addr().to_be_bytes();
Ok(SocketAddr::V4(SocketAddrV4::new(
Ipv4Addr::new(v4b[0], v4b[1], v4b[2], v4b[3]),
reader.get_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")),
}
) -> Result<SocketAddress, RPCError> {
let ar = reader
.reborrow()
.get_address()
.map_err(map_error_internal!("missing socketAddress"))?;
let address = decode_address(&ar)?;
let port = reader.get_port();
Ok(SocketAddress::new(address, port))
}

View File

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

View File

@ -779,7 +779,7 @@ impl RPCProcessor {
.peer_noderef
.operate(|entry| match entry.last_connection() {
None => None,
Some(c) => c.remote.to_socket_addr().ok(),
Some(c) => Some(c.remote.to_socket_addr()),
});
SenderInfo { socket_address }
}
@ -955,7 +955,7 @@ impl RPCProcessor {
let address_filter = self.config.get().network.address_filter;
if address_filter {
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
return Err(RPCError::InvalidFormat);
}
@ -1508,7 +1508,7 @@ impl RPCProcessor {
// reject attempts to include non-public addresses in results
if address_filter {
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
return Err(RPCError::InvalidFormat);
}

View File

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

View File

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