mirror of
https://gitlab.com/veilid/veilid.git
synced 2024-10-01 01:26:08 -04:00
refactor
This commit is contained in:
parent
cd0cd78e30
commit
7e0d7dad06
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -4930,7 +4930,6 @@ dependencies = [
|
||||
"chacha20 0.9.0",
|
||||
"chacha20poly1305",
|
||||
"chrono",
|
||||
"color-eyre",
|
||||
"config",
|
||||
"console_error_panic_hook",
|
||||
"curve25519-dalek-ng",
|
||||
@ -4939,6 +4938,7 @@ dependencies = [
|
||||
"directories",
|
||||
"ed25519-dalek",
|
||||
"enumset",
|
||||
"eyre",
|
||||
"flume",
|
||||
"futures-util",
|
||||
"generic-array 0.14.5",
|
||||
|
@ -22,7 +22,7 @@ tracking = [ "backtrace" ]
|
||||
tracing = { version = "^0", features = ["log", "attributes"] }
|
||||
tracing-subscriber = "^0"
|
||||
tracing-error = "^0"
|
||||
color-eyre = "^0"
|
||||
eyre = "^0"
|
||||
capnp = { version = "^0", default_features = false }
|
||||
rust-fsm = "^0"
|
||||
static_assertions = "^1"
|
||||
|
@ -277,7 +277,7 @@ impl AttachmentManager {
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip_all, err)]
|
||||
pub async fn init(&self, update_callback: UpdateCallback) -> Result<(), String> {
|
||||
pub async fn init(&self, update_callback: UpdateCallback) -> EyreResult<()> {
|
||||
trace!("init");
|
||||
let network_manager = {
|
||||
let mut inner = self.inner.lock();
|
||||
|
@ -58,7 +58,7 @@ impl ServicesContext {
|
||||
}
|
||||
|
||||
#[instrument(err, skip_all)]
|
||||
pub async fn startup(&mut self) -> Result<(), VeilidAPIError> {
|
||||
pub async fn startup(&mut self) -> EyreResult<()> {
|
||||
info!("Veilid API starting up");
|
||||
|
||||
info!("init api tracing");
|
||||
@ -69,14 +69,14 @@ impl ServicesContext {
|
||||
let protected_store = ProtectedStore::new(self.config.clone());
|
||||
if let Err(e) = protected_store.init().await {
|
||||
self.shutdown().await;
|
||||
return Err(VeilidAPIError::Internal { message: e });
|
||||
return Err(e);
|
||||
}
|
||||
self.protected_store = Some(protected_store.clone());
|
||||
|
||||
// Init node id from config now that protected store is set up
|
||||
if let Err(e) = self.config.init_node_id(protected_store.clone()).await {
|
||||
self.shutdown().await;
|
||||
return Err(e);
|
||||
return Err(e).wrap_err("init node id failed");
|
||||
}
|
||||
|
||||
// Set up tablestore
|
||||
@ -84,7 +84,7 @@ impl ServicesContext {
|
||||
let table_store = TableStore::new(self.config.clone());
|
||||
if let Err(e) = table_store.init().await {
|
||||
self.shutdown().await;
|
||||
return Err(VeilidAPIError::Internal { message: e });
|
||||
return Err(e);
|
||||
}
|
||||
self.table_store = Some(table_store.clone());
|
||||
|
||||
@ -93,7 +93,7 @@ impl ServicesContext {
|
||||
let crypto = Crypto::new(self.config.clone(), table_store.clone());
|
||||
if let Err(e) = crypto.init().await {
|
||||
self.shutdown().await;
|
||||
return Err(VeilidAPIError::Internal { message: e });
|
||||
return Err(e);
|
||||
}
|
||||
self.crypto = Some(crypto.clone());
|
||||
|
||||
@ -102,7 +102,7 @@ impl ServicesContext {
|
||||
let block_store = BlockStore::new(self.config.clone());
|
||||
if let Err(e) = block_store.init().await {
|
||||
self.shutdown().await;
|
||||
return Err(VeilidAPIError::Internal { message: e });
|
||||
return Err(e);
|
||||
}
|
||||
self.block_store = Some(block_store.clone());
|
||||
|
||||
@ -112,7 +112,7 @@ impl ServicesContext {
|
||||
let attachment_manager = AttachmentManager::new(self.config.clone(), table_store, crypto);
|
||||
if let Err(e) = attachment_manager.init(update_callback).await {
|
||||
self.shutdown().await;
|
||||
return Err(VeilidAPIError::Internal { message: e });
|
||||
return Err(e);
|
||||
}
|
||||
self.attachment_manager = Some(attachment_manager);
|
||||
|
||||
@ -209,7 +209,7 @@ impl VeilidCoreContext {
|
||||
}
|
||||
|
||||
let mut sc = ServicesContext::new_empty(config.clone(), update_callback);
|
||||
sc.startup().await?;
|
||||
sc.startup().await.map_err(VeilidAPIError::generic)?;
|
||||
|
||||
Ok(VeilidCoreContext {
|
||||
update_callback: sc.update_callback,
|
||||
|
@ -91,7 +91,7 @@ impl Crypto {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn init(&self) -> Result<(), String> {
|
||||
pub async fn init(&self) -> EyreResult<()> {
|
||||
trace!("Crypto::init");
|
||||
|
||||
// make local copy of node id for easy access
|
||||
@ -136,7 +136,7 @@ impl Crypto {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn flush(&self) -> Result<(), String> {
|
||||
pub async fn flush(&self) -> EyreResult<()> {
|
||||
//trace!("Crypto::flush");
|
||||
let (table_store, cache_bytes) = {
|
||||
let inner = self.inner.lock();
|
||||
@ -166,23 +166,27 @@ impl Crypto {
|
||||
};
|
||||
}
|
||||
|
||||
fn ed25519_to_x25519_pk(key: &ed::PublicKey) -> Result<xd::PublicKey, String> {
|
||||
fn ed25519_to_x25519_pk(key: &ed::PublicKey) -> Result<xd::PublicKey, VeilidAPIError> {
|
||||
let bytes = key.to_bytes();
|
||||
let compressed = cd::edwards::CompressedEdwardsY(bytes);
|
||||
let point = compressed
|
||||
.decompress()
|
||||
.ok_or_else(fn_string!("ed25519_to_x25519_pk failed"))?;
|
||||
.ok_or_else(|| VeilidAPIError::internal("ed25519_to_x25519_pk failed"))?;
|
||||
let mp = point.to_montgomery();
|
||||
Ok(xd::PublicKey::from(mp.to_bytes()))
|
||||
}
|
||||
fn ed25519_to_x25519_sk(key: &ed::SecretKey) -> Result<xd::StaticSecret, String> {
|
||||
fn ed25519_to_x25519_sk(key: &ed::SecretKey) -> Result<xd::StaticSecret, VeilidAPIError> {
|
||||
let exp = ed::ExpandedSecretKey::from(key);
|
||||
let bytes: [u8; ed::EXPANDED_SECRET_KEY_LENGTH] = exp.to_bytes();
|
||||
let lowbytes: [u8; 32] = bytes[0..32].try_into().map_err(map_to_string)?;
|
||||
let lowbytes: [u8; 32] = bytes[0..32].try_into().map_err(VeilidAPIError::internal)?;
|
||||
Ok(xd::StaticSecret::from(lowbytes))
|
||||
}
|
||||
|
||||
pub fn cached_dh(&self, key: &DHTKey, secret: &DHTKeySecret) -> Result<SharedSecret, String> {
|
||||
pub fn cached_dh(
|
||||
&self,
|
||||
key: &DHTKey,
|
||||
secret: &DHTKeySecret,
|
||||
) -> Result<SharedSecret, VeilidAPIError> {
|
||||
Ok(
|
||||
match self.inner.lock().dh_cache.entry(DHCacheKey {
|
||||
key: *key,
|
||||
@ -201,12 +205,12 @@ impl Crypto {
|
||||
///////////
|
||||
// These are safe to use regardless of initialization status
|
||||
|
||||
pub fn compute_dh(key: &DHTKey, secret: &DHTKeySecret) -> Result<SharedSecret, String> {
|
||||
pub fn compute_dh(key: &DHTKey, secret: &DHTKeySecret) -> Result<SharedSecret, VeilidAPIError> {
|
||||
assert!(key.valid);
|
||||
assert!(secret.valid);
|
||||
let pk_ed = ed::PublicKey::from_bytes(&key.bytes).map_err(map_to_string)?;
|
||||
let pk_ed = ed::PublicKey::from_bytes(&key.bytes).map_err(VeilidAPIError::internal)?;
|
||||
let pk_xd = Self::ed25519_to_x25519_pk(&pk_ed)?;
|
||||
let sk_ed = ed::SecretKey::from_bytes(&secret.bytes).map_err(map_to_string)?;
|
||||
let sk_ed = ed::SecretKey::from_bytes(&secret.bytes).map_err(VeilidAPIError::internal)?;
|
||||
let sk_xd = Self::ed25519_to_x25519_sk(&sk_ed)?;
|
||||
Ok(sk_xd.diffie_hellman(&pk_xd).to_bytes())
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
use super::crypto::*;
|
||||
use super::key::*;
|
||||
use crate::xx::*;
|
||||
use crate::*;
|
||||
use core::convert::TryInto;
|
||||
|
||||
// #[repr(C, packed)]
|
||||
@ -76,89 +77,103 @@ impl Envelope {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_signed_data(data: &[u8]) -> Result<Envelope, ()> {
|
||||
pub fn from_signed_data(data: &[u8]) -> Result<Envelope, VeilidAPIError> {
|
||||
// Ensure we are at least the length of the envelope
|
||||
// Silent drop here, as we use zero length packets as part of the protocol for hole punching
|
||||
if data.len() < MIN_ENVELOPE_SIZE {
|
||||
return Err(());
|
||||
return Err(VeilidAPIError::generic("envelope data too small"));
|
||||
}
|
||||
|
||||
// Verify magic number
|
||||
let magic: [u8; 4] = data[0x00..0x04].try_into().map_err(drop)?;
|
||||
let magic: [u8; 4] = data[0x00..0x04]
|
||||
.try_into()
|
||||
.map_err(VeilidAPIError::internal)?;
|
||||
if magic != *ENVELOPE_MAGIC {
|
||||
trace!("bad magic number: len={:?}", magic);
|
||||
return Err(());
|
||||
return Err(VeilidAPIError::generic("bad magic number"));
|
||||
}
|
||||
|
||||
// Check version
|
||||
let version = data[0x04];
|
||||
if version > MAX_VERSION || version < MIN_VERSION {
|
||||
trace!("unsupported protocol version: version={}", version);
|
||||
return Err(());
|
||||
return Err(VeilidAPIError::parse_error(
|
||||
"unsupported protocol version",
|
||||
version,
|
||||
));
|
||||
}
|
||||
|
||||
// Get min version
|
||||
let min_version = data[0x05];
|
||||
if min_version > version {
|
||||
trace!(
|
||||
"invalid version information in envelope: min_version={}, version={}",
|
||||
min_version,
|
||||
version,
|
||||
);
|
||||
return Err(());
|
||||
return Err(VeilidAPIError::parse_error("version too low", version));
|
||||
}
|
||||
|
||||
// Get max version
|
||||
let max_version = data[0x06];
|
||||
if version > max_version || min_version > max_version {
|
||||
trace!(
|
||||
"invalid version information in envelope: min_version={}, version={}, max_version={}",
|
||||
min_version,
|
||||
version,
|
||||
max_version
|
||||
);
|
||||
return Err(());
|
||||
if version > max_version {
|
||||
return Err(VeilidAPIError::parse_error("version too high", version));
|
||||
}
|
||||
if min_version > max_version {
|
||||
return Err(VeilidAPIError::generic("version information invalid"));
|
||||
}
|
||||
|
||||
// Get size and ensure it matches the size of the envelope and is less than the maximum message size
|
||||
let size: u16 = u16::from_le_bytes(data[0x08..0x0A].try_into().map_err(drop)?);
|
||||
let size: u16 = u16::from_le_bytes(
|
||||
data[0x08..0x0A]
|
||||
.try_into()
|
||||
.map_err(VeilidAPIError::internal)?,
|
||||
);
|
||||
if (size as usize) > MAX_ENVELOPE_SIZE {
|
||||
trace!("envelope size is too large: size={}", size);
|
||||
return Err(());
|
||||
return Err(VeilidAPIError::parse_error("envelope too large", size));
|
||||
}
|
||||
if (size as usize) != data.len() {
|
||||
trace!(
|
||||
"size doesn't match envelope size: size={} data.len()={}",
|
||||
size,
|
||||
data.len()
|
||||
);
|
||||
return Err(());
|
||||
return Err(VeilidAPIError::parse_error(
|
||||
"size doesn't match envelope size",
|
||||
format!(
|
||||
"size doesn't match envelope size: size={} data.len()={}",
|
||||
size,
|
||||
data.len()
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
// Get the timestamp
|
||||
let timestamp: u64 = u64::from_le_bytes(data[0x0A..0x12].try_into().map_err(drop)?);
|
||||
let timestamp: u64 = u64::from_le_bytes(
|
||||
data[0x0A..0x12]
|
||||
.try_into()
|
||||
.map_err(VeilidAPIError::internal)?,
|
||||
);
|
||||
|
||||
// Get nonce and sender node id
|
||||
let nonce: EnvelopeNonce = data[0x12..0x2A].try_into().map_err(drop)?;
|
||||
let sender_id_slice: [u8; 32] = data[0x2A..0x4A].try_into().map_err(drop)?;
|
||||
let recipient_id_slice: [u8; 32] = data[0x4A..0x6A].try_into().map_err(drop)?;
|
||||
let nonce: EnvelopeNonce = data[0x12..0x2A]
|
||||
.try_into()
|
||||
.map_err(VeilidAPIError::internal)?;
|
||||
let sender_id_slice: [u8; 32] = data[0x2A..0x4A]
|
||||
.try_into()
|
||||
.map_err(VeilidAPIError::internal)?;
|
||||
let recipient_id_slice: [u8; 32] = data[0x4A..0x6A]
|
||||
.try_into()
|
||||
.map_err(VeilidAPIError::internal)?;
|
||||
let sender_id = DHTKey::new(sender_id_slice);
|
||||
let recipient_id = DHTKey::new(recipient_id_slice);
|
||||
|
||||
// Ensure sender_id and recipient_id are not the same
|
||||
if sender_id == recipient_id {
|
||||
trace!(
|
||||
"sender_id should not be same as recipient_id: {}",
|
||||
recipient_id.encode()
|
||||
);
|
||||
return Err(());
|
||||
return Err(VeilidAPIError::parse_error(
|
||||
"sender_id should not be same as recipient_id",
|
||||
recipient_id.encode(),
|
||||
));
|
||||
}
|
||||
|
||||
// Get signature
|
||||
let signature = DHTSignature::new(data[(data.len() - 64)..].try_into().map_err(drop)?);
|
||||
let signature = DHTSignature::new(
|
||||
data[(data.len() - 64)..]
|
||||
.try_into()
|
||||
.map_err(VeilidAPIError::internal)?,
|
||||
);
|
||||
|
||||
// Validate signature
|
||||
verify(&sender_id, &data[0..(data.len() - 64)], &signature).map_err(drop)?;
|
||||
verify(&sender_id, &data[0..(data.len() - 64)], &signature)
|
||||
.map_err(VeilidAPIError::internal)?;
|
||||
|
||||
// Return envelope
|
||||
Ok(Self {
|
||||
@ -177,7 +192,7 @@ impl Envelope {
|
||||
crypto: Crypto,
|
||||
data: &[u8],
|
||||
node_id_secret: &DHTKeySecret,
|
||||
) -> Result<Vec<u8>, String> {
|
||||
) -> Result<Vec<u8>, VeilidAPIError> {
|
||||
// Get DH secret
|
||||
let dh_secret = crypto.cached_dh(&self.sender_id, node_id_secret)?;
|
||||
|
||||
@ -192,20 +207,23 @@ impl Envelope {
|
||||
crypto: Crypto,
|
||||
body: &[u8],
|
||||
node_id_secret: &DHTKeySecret,
|
||||
) -> Result<Vec<u8>, ()> {
|
||||
) -> Result<Vec<u8>, VeilidAPIError> {
|
||||
// Ensure sender node id is valid
|
||||
if !self.sender_id.valid {
|
||||
return Err(());
|
||||
return Err(VeilidAPIError::generic("sender id is invalid"));
|
||||
}
|
||||
// Ensure recipient node id is valid
|
||||
if !self.recipient_id.valid {
|
||||
return Err(());
|
||||
return Err(VeilidAPIError::generic("recipient id is invalid"));
|
||||
}
|
||||
|
||||
// Ensure body isn't too long
|
||||
let envelope_size: usize = body.len() + MIN_ENVELOPE_SIZE;
|
||||
if envelope_size > MAX_ENVELOPE_SIZE {
|
||||
return Err(());
|
||||
return Err(VeilidAPIError::parse_error(
|
||||
"envelope size is too large",
|
||||
envelope_size,
|
||||
));
|
||||
}
|
||||
let mut data = vec![0u8; envelope_size];
|
||||
|
||||
@ -229,9 +247,7 @@ impl Envelope {
|
||||
data[0x4A..0x6A].copy_from_slice(&self.recipient_id.bytes);
|
||||
|
||||
// Generate dh secret
|
||||
let dh_secret = crypto
|
||||
.cached_dh(&self.recipient_id, node_id_secret)
|
||||
.map_err(drop)?;
|
||||
let dh_secret = crypto.cached_dh(&self.recipient_id, node_id_secret)?;
|
||||
|
||||
// Encrypt and authenticate message
|
||||
let encrypted_body = Crypto::crypt_no_auth(body, &self.nonce, &dh_secret);
|
||||
@ -246,8 +262,7 @@ impl Envelope {
|
||||
&self.sender_id,
|
||||
node_id_secret,
|
||||
&data[0..(envelope_size - 64)],
|
||||
)
|
||||
.map_err(drop)?;
|
||||
)?;
|
||||
|
||||
// Append the signature
|
||||
data[(envelope_size - 64)..].copy_from_slice(&signature.bytes);
|
||||
|
@ -3,6 +3,7 @@
|
||||
use super::envelope::{MAX_VERSION, MIN_VERSION};
|
||||
use super::key::*;
|
||||
use crate::xx::*;
|
||||
use crate::*;
|
||||
use core::convert::TryInto;
|
||||
use data_encoding::BASE64URL_NOPAD;
|
||||
|
||||
@ -57,10 +58,13 @@ impl Receipt {
|
||||
nonce: ReceiptNonce,
|
||||
sender_id: DHTKey,
|
||||
extra_data: D,
|
||||
) -> Result<Self, String> {
|
||||
) -> Result<Self, VeilidAPIError> {
|
||||
assert!(sender_id.valid);
|
||||
if extra_data.as_ref().len() > MAX_EXTRA_DATA_SIZE {
|
||||
return Err("extra data too large for receipt".to_owned());
|
||||
return Err(VeilidAPIError::parse_error(
|
||||
"extra data too large for receipt",
|
||||
extra_data.as_ref().len(),
|
||||
));
|
||||
}
|
||||
Ok(Self {
|
||||
version,
|
||||
@ -70,53 +74,70 @@ impl Receipt {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn from_signed_data(data: &[u8]) -> Result<Receipt, ()> {
|
||||
pub fn from_signed_data(data: &[u8]) -> Result<Receipt, VeilidAPIError> {
|
||||
// Ensure we are at least the length of the envelope
|
||||
if data.len() < MIN_RECEIPT_SIZE {
|
||||
trace!("receipt too small: len={}", data.len());
|
||||
return Err(());
|
||||
return Err(VeilidAPIError::parse_error("receipt too small", data.len()));
|
||||
}
|
||||
|
||||
// Verify magic number
|
||||
let magic: [u8; 4] = data[0x00..0x04].try_into().map_err(drop)?;
|
||||
let magic: [u8; 4] = data[0x00..0x04]
|
||||
.try_into()
|
||||
.map_err(VeilidAPIError::internal)?;
|
||||
if magic != *RECEIPT_MAGIC {
|
||||
trace!("bad magic number: len={:?}", magic);
|
||||
return Err(());
|
||||
return Err(VeilidAPIError::generic("bad magic number"));
|
||||
}
|
||||
|
||||
// Check version
|
||||
let version = data[0x04];
|
||||
if version > MAX_VERSION || version < MIN_VERSION {
|
||||
trace!("unsupported protocol version: version={}", version);
|
||||
return Err(());
|
||||
return Err(VeilidAPIError::parse_error(
|
||||
"unsupported protocol version",
|
||||
version,
|
||||
));
|
||||
}
|
||||
|
||||
// Get size and ensure it matches the size of the envelope and is less than the maximum message size
|
||||
let size: u16 = u16::from_le_bytes(data[0x06..0x08].try_into().map_err(drop)?);
|
||||
let size: u16 = u16::from_le_bytes(
|
||||
data[0x06..0x08]
|
||||
.try_into()
|
||||
.map_err(VeilidAPIError::internal)?,
|
||||
);
|
||||
if (size as usize) > MAX_RECEIPT_SIZE {
|
||||
trace!("receipt size is too large: size={}", size);
|
||||
return Err(());
|
||||
return Err(VeilidAPIError::parse_error(
|
||||
"receipt size is too large",
|
||||
size,
|
||||
));
|
||||
}
|
||||
if (size as usize) != data.len() {
|
||||
trace!(
|
||||
"size doesn't match receipt size: size={} data.len()={}",
|
||||
size,
|
||||
data.len()
|
||||
);
|
||||
return Err(());
|
||||
return Err(VeilidAPIError::parse_error(
|
||||
"size doesn't match receipt size",
|
||||
format!("size={} data.len()={}", size, data.len()),
|
||||
));
|
||||
}
|
||||
|
||||
// Get sender id
|
||||
let sender_id = DHTKey::new(data[0x20..0x40].try_into().map_err(drop)?);
|
||||
let sender_id = DHTKey::new(
|
||||
data[0x20..0x40]
|
||||
.try_into()
|
||||
.map_err(VeilidAPIError::internal)?,
|
||||
);
|
||||
|
||||
// Get signature
|
||||
let signature = DHTSignature::new(data[(data.len() - 64)..].try_into().map_err(drop)?);
|
||||
let signature = DHTSignature::new(
|
||||
data[(data.len() - 64)..]
|
||||
.try_into()
|
||||
.map_err(VeilidAPIError::internal)?,
|
||||
);
|
||||
|
||||
// Validate signature
|
||||
verify(&sender_id, &data[0..(data.len() - 64)], &signature).map_err(drop)?;
|
||||
verify(&sender_id, &data[0..(data.len() - 64)], &signature)
|
||||
.map_err(VeilidAPIError::generic)?;
|
||||
|
||||
// Get nonce
|
||||
let nonce: ReceiptNonce = data[0x08..0x20].try_into().map_err(drop)?;
|
||||
let nonce: ReceiptNonce = data[0x08..0x20]
|
||||
.try_into()
|
||||
.map_err(VeilidAPIError::internal)?;
|
||||
|
||||
// Get extra data and signature
|
||||
let extra_data: Vec<u8> = Vec::from(&data[0x40..(data.len() - 64)]);
|
||||
@ -130,16 +151,19 @@ impl Receipt {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn to_signed_data(&self, secret: &DHTKeySecret) -> Result<Vec<u8>, ()> {
|
||||
pub fn to_signed_data(&self, secret: &DHTKeySecret) -> Result<Vec<u8>, VeilidAPIError> {
|
||||
// Ensure sender node id is valid
|
||||
if !self.sender_id.valid {
|
||||
return Err(());
|
||||
return Err(VeilidAPIError::internal("sender id is invalid"));
|
||||
}
|
||||
|
||||
// Ensure extra data isn't too long
|
||||
let receipt_size: usize = self.extra_data.len() + MIN_RECEIPT_SIZE;
|
||||
if receipt_size > MAX_RECEIPT_SIZE {
|
||||
return Err(());
|
||||
return Err(VeilidAPIError::parse_error(
|
||||
"receipt too large",
|
||||
receipt_size,
|
||||
));
|
||||
}
|
||||
let mut data: Vec<u8> = vec![0u8; receipt_size];
|
||||
|
||||
@ -158,8 +182,8 @@ impl Receipt {
|
||||
data[0x40..(receipt_size - 64)].copy_from_slice(self.extra_data.as_slice());
|
||||
}
|
||||
// Sign the receipt
|
||||
let signature =
|
||||
sign(&self.sender_id, secret, &data[0..(receipt_size - 64)]).map_err(drop)?;
|
||||
let signature = sign(&self.sender_id, secret, &data[0..(receipt_size - 64)])
|
||||
.map_err(VeilidAPIError::generic)?;
|
||||
// Append the signature
|
||||
data[(receipt_size - 64)..].copy_from_slice(&signature.bytes);
|
||||
|
||||
|
@ -22,7 +22,7 @@ impl BlockStore {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn init(&self) -> Result<(), String> {
|
||||
pub async fn init(&self) -> EyreResult<()> {
|
||||
// Ensure permissions are correct
|
||||
// ensure_file_private_owner(&dbpath)?;
|
||||
|
||||
|
@ -3,7 +3,6 @@ use crate::*;
|
||||
use data_encoding::BASE64URL_NOPAD;
|
||||
use keyring_manager::*;
|
||||
use std::path::Path;
|
||||
use std::result::Result;
|
||||
|
||||
pub struct ProtectedStoreInner {
|
||||
keyring_manager: Option<KeyringManager>,
|
||||
@ -30,7 +29,7 @@ impl ProtectedStore {
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self), err)]
|
||||
pub async fn delete_all(&self) -> Result<(), String> {
|
||||
pub async fn delete_all(&self) -> EyreResult<()> {
|
||||
// Delete all known keys
|
||||
if self.remove_user_secret_string("node_id").await? {
|
||||
debug!("deleted protected_store key 'node_id'");
|
||||
@ -45,7 +44,7 @@ impl ProtectedStore {
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self), err)]
|
||||
pub async fn init(&self) -> Result<(), String> {
|
||||
pub async fn init(&self) -> EyreResult<()> {
|
||||
let delete = {
|
||||
let c = self.config.get();
|
||||
let mut inner = self.inner.lock();
|
||||
@ -80,12 +79,11 @@ impl ProtectedStore {
|
||||
// Open the insecure keyring
|
||||
inner.keyring_manager = Some(
|
||||
KeyringManager::new_insecure(&c.program_name, &insecure_keyring_file)
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_pstore!(error))?,
|
||||
.wrap_err("failed to create insecure keyring")?,
|
||||
);
|
||||
}
|
||||
if inner.keyring_manager.is_none() {
|
||||
return Err("Could not initialize the protected store.".to_owned());
|
||||
bail!("Could not initialize the protected store.");
|
||||
}
|
||||
c.protected_store.delete
|
||||
};
|
||||
@ -112,56 +110,52 @@ impl ProtectedStore {
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self, value), ret, err)]
|
||||
pub async fn save_user_secret_string(&self, key: &str, value: &str) -> Result<bool, String> {
|
||||
pub async fn save_user_secret_string(&self, key: &str, value: &str) -> EyreResult<bool> {
|
||||
let inner = self.inner.lock();
|
||||
inner
|
||||
.keyring_manager
|
||||
.as_ref()
|
||||
.ok_or_else(|| "Protected store not initialized".to_owned())?
|
||||
.ok_or_else(|| eyre!("Protected store not initialized"))?
|
||||
.with_keyring(&self.service_name(), key, |kr| {
|
||||
let existed = kr.get_value().is_ok();
|
||||
kr.set_value(value)
|
||||
.map_err(|e| format!("Failed to save user secret: {}", e))?;
|
||||
kr.set_value(value)?;
|
||||
Ok(existed)
|
||||
})
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_pstore!())
|
||||
.wrap_err("failed to save user secret")
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self), err)]
|
||||
pub async fn load_user_secret_string(&self, key: &str) -> Result<Option<String>, String> {
|
||||
pub async fn load_user_secret_string(&self, key: &str) -> EyreResult<Option<String>> {
|
||||
let inner = self.inner.lock();
|
||||
match inner
|
||||
.keyring_manager
|
||||
.as_ref()
|
||||
.ok_or_else(|| "Protected store not initialized".to_owned())?
|
||||
.ok_or_else(|| eyre!("Protected store not initialized"))?
|
||||
.with_keyring(&self.service_name(), key, |kr| kr.get_value())
|
||||
.map_err(logthru_pstore!())
|
||||
{
|
||||
Ok(v) => Ok(Some(v)),
|
||||
Err(KeyringError::NoPasswordFound) => Ok(None),
|
||||
Err(e) => Err(format!("Failed to load user secret: {}", e)),
|
||||
Err(e) => Err(eyre!("Failed to load user secret")),
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self), ret, err)]
|
||||
pub async fn remove_user_secret_string(&self, key: &str) -> Result<bool, String> {
|
||||
pub async fn remove_user_secret_string(&self, key: &str) -> EyreResult<bool> {
|
||||
let inner = self.inner.lock();
|
||||
match inner
|
||||
.keyring_manager
|
||||
.as_ref()
|
||||
.ok_or_else(|| "Protected store not initialized".to_owned())?
|
||||
.ok_or_else(|| eyre!("Protected store not initialized"))?
|
||||
.with_keyring(&self.service_name(), key, |kr| kr.delete_value())
|
||||
.map_err(logthru_pstore!())
|
||||
{
|
||||
Ok(_) => Ok(true),
|
||||
Err(KeyringError::NoPasswordFound) => Ok(false),
|
||||
Err(e) => Err(format!("Failed to remove user secret: {}", e)),
|
||||
Err(e) => Err(eyre!("Failed to remove user secret")),
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self, value), ret, err)]
|
||||
pub async fn save_user_secret(&self, key: &str, value: &[u8]) -> Result<bool, String> {
|
||||
pub async fn save_user_secret(&self, key: &str, value: &[u8]) -> EyreResult<bool> {
|
||||
let mut s = BASE64URL_NOPAD.encode(value);
|
||||
s.push('!');
|
||||
|
||||
@ -169,7 +163,7 @@ impl ProtectedStore {
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self), err)]
|
||||
pub async fn load_user_secret(&self, key: &str) -> Result<Option<Vec<u8>>, String> {
|
||||
pub async fn load_user_secret(&self, key: &str) -> EyreResult<Option<Vec<u8>>> {
|
||||
let mut s = match self.load_user_secret_string(key).await? {
|
||||
Some(s) => s,
|
||||
None => {
|
||||
@ -178,7 +172,7 @@ impl ProtectedStore {
|
||||
};
|
||||
|
||||
if s.pop() != Some('!') {
|
||||
return Err("User secret is not a buffer".to_owned());
|
||||
bail!("User secret is not a buffer");
|
||||
}
|
||||
|
||||
let mut bytes = Vec::<u8>::new();
|
||||
@ -188,19 +182,19 @@ impl ProtectedStore {
|
||||
bytes.resize(l, 0u8);
|
||||
}
|
||||
Err(_) => {
|
||||
return Err("Failed to decode".to_owned());
|
||||
bail!("Failed to decode");
|
||||
}
|
||||
}
|
||||
|
||||
let res = BASE64URL_NOPAD.decode_mut(s.as_bytes(), &mut bytes);
|
||||
match res {
|
||||
Ok(_) => Ok(Some(bytes)),
|
||||
Err(_) => Err("Failed to decode".to_owned()),
|
||||
Err(_) => bail!("Failed to decode"),
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self), ret, err)]
|
||||
pub async fn remove_user_secret(&self, key: &str) -> Result<bool, String> {
|
||||
pub async fn remove_user_secret(&self, key: &str) -> EyreResult<bool> {
|
||||
self.remove_user_secret_string(key).await
|
||||
}
|
||||
}
|
||||
|
@ -16,9 +16,9 @@ pub fn get_timestamp_string() -> String {
|
||||
dt.time().format("%H:%M:%S.3f").to_string()
|
||||
}
|
||||
|
||||
pub fn random_bytes(dest: &mut [u8]) -> Result<(), String> {
|
||||
pub fn random_bytes(dest: &mut [u8]) -> EyreResult<()> {
|
||||
let mut rng = rand::thread_rng();
|
||||
rng.try_fill_bytes(dest).map_err(|err| format!("{:?}", err))
|
||||
rng.try_fill_bytes(dest).wrap_err("failed to fill bytes")
|
||||
}
|
||||
|
||||
pub fn get_random_u32() -> u32 {
|
||||
@ -137,23 +137,15 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature="rt-async-std")] {
|
||||
pub use async_std::future::TimeoutError;
|
||||
} else if #[cfg(feature="rt-tokio")] {
|
||||
pub use tokio::time::error::Elapsed as TimeoutError;
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn timeout<F, T>(dur_ms: u32, f: F) -> Result<T, TimeoutError>
|
||||
where
|
||||
F: Future<Output = T>,
|
||||
{
|
||||
cfg_if! {
|
||||
if #[cfg(feature="rt-async-std")] {
|
||||
async_std::future::timeout(Duration::from_millis(dur_ms as u64), f).await
|
||||
async_std::future::timeout(Duration::from_millis(dur_ms as u64), f).await.map_err(|e| e.into())
|
||||
} else if #[cfg(feature="rt-tokio")] {
|
||||
tokio::time::timeout(Duration::from_millis(dur_ms as u64), f).await
|
||||
tokio::time::timeout(Duration::from_millis(dur_ms as u64), f).await.map_err(|e| e.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -228,7 +220,7 @@ cfg_if! {
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(not(target_os = "windows"))] {
|
||||
async fn get_resolver() -> Result<AsyncResolver, String> {
|
||||
async fn get_resolver() -> EyreResult<AsyncResolver> {
|
||||
let mut resolver_lock = RESOLVER.lock().await;
|
||||
if let Some(r) = &*resolver_lock {
|
||||
Ok(r.clone())
|
||||
@ -250,7 +242,7 @@ cfg_if! {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn txt_lookup<S: AsRef<str>>(host: S) -> Result<Vec<String>, String> {
|
||||
pub async fn txt_lookup<S: AsRef<str>>(host: S) -> EyreResult<Vec<String>> {
|
||||
cfg_if! {
|
||||
if #[cfg(target_os = "windows")] {
|
||||
use core::ffi::c_void;
|
||||
@ -263,7 +255,7 @@ pub async fn txt_lookup<S: AsRef<str>>(host: S) -> Result<Vec<String>, String> {
|
||||
let mut p_query_results: *mut DNS_RECORDA = core::ptr::null_mut();
|
||||
let status = DnsQuery_UTF8(host.as_ref(), DNS_TYPE_TEXT as u16, DNS_QUERY_STANDARD, core::ptr::null_mut(), &mut p_query_results as *mut *mut DNS_RECORDA, core::ptr::null_mut());
|
||||
if status != 0 {
|
||||
return Err("Failed to resolve TXT record".to_owned());
|
||||
bail!("Failed to resolve TXT record");
|
||||
}
|
||||
|
||||
let mut p_record: *mut DNS_RECORDA = p_query_results;
|
||||
@ -290,12 +282,11 @@ pub async fn txt_lookup<S: AsRef<str>>(host: S) -> Result<Vec<String>, String> {
|
||||
let resolver = get_resolver().await?;
|
||||
let txt_result = resolver
|
||||
.txt_lookup(host.as_ref())
|
||||
.await
|
||||
.map_err(|e| e.to_string())?;
|
||||
.await?;
|
||||
let mut out = Vec::new();
|
||||
for x in txt_result.iter() {
|
||||
for s in x.txt_data() {
|
||||
out.push(String::from_utf8(s.to_vec()).map_err(|e| e.to_string())?);
|
||||
out.push(String::from_utf8(s.to_vec()).wrap_err("utf8 conversion error")?);
|
||||
}
|
||||
}
|
||||
Ok(out)
|
||||
@ -303,7 +294,7 @@ pub async fn txt_lookup<S: AsRef<str>>(host: S) -> Result<Vec<String>, String> {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn ptr_lookup(ip_addr: IpAddr) -> Result<String, String> {
|
||||
pub async fn ptr_lookup(ip_addr: IpAddr) -> EyreResult<String> {
|
||||
cfg_if! {
|
||||
if #[cfg(target_os = "windows")] {
|
||||
use core::ffi::c_void;
|
||||
@ -329,7 +320,7 @@ pub async fn ptr_lookup(ip_addr: IpAddr) -> Result<String, String> {
|
||||
let mut p_query_results: *mut DNS_RECORDA = core::ptr::null_mut();
|
||||
let status = DnsQuery_UTF8(host, DNS_TYPE_PTR as u16, DNS_QUERY_STANDARD, core::ptr::null_mut(), &mut p_query_results as *mut *mut DNS_RECORDA, core::ptr::null_mut());
|
||||
if status != 0 {
|
||||
return Err("Failed to resolve PTR record".to_owned());
|
||||
bail!("Failed to resolve PTR record");
|
||||
}
|
||||
|
||||
let mut p_record: *mut DNS_RECORDA = p_query_results;
|
||||
@ -346,17 +337,17 @@ pub async fn ptr_lookup(ip_addr: IpAddr) -> Result<String, String> {
|
||||
}
|
||||
DnsFree(p_query_results as *const c_void, DnsFreeRecordList);
|
||||
}
|
||||
return Err("No records returned".to_owned());
|
||||
bail!("No records returned");
|
||||
} else {
|
||||
let resolver = get_resolver().await?;
|
||||
let ptr_result = resolver
|
||||
.reverse_lookup(ip_addr)
|
||||
.await
|
||||
.map_err(|e| e.to_string())?;
|
||||
.wrap_err("resolver error")?;
|
||||
if let Some(r) = ptr_result.iter().next() {
|
||||
Ok(r.to_string().trim_end_matches('.').to_string())
|
||||
} else {
|
||||
Err("PTR lookup returned an empty string".to_owned())
|
||||
bail!("PTR lookup returned an empty string");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,13 +27,13 @@ impl TableStore {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn delete_all(&self) -> Result<(), String> {
|
||||
pub async fn delete_all(&self) -> EyreResult<()> {
|
||||
// Delete all known keys
|
||||
self.delete("crypto_caches").await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn init(&self) -> Result<(), String> {
|
||||
pub async fn init(&self) -> EyreResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -51,28 +51,27 @@ impl TableStore {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_dbpath(&self, table: &str) -> Result<PathBuf, String> {
|
||||
fn get_dbpath(&self, table: &str) -> EyreResult<PathBuf> {
|
||||
if !table
|
||||
.chars()
|
||||
.all(|c| char::is_alphanumeric(c) || c == '_' || c == '-')
|
||||
{
|
||||
return Err(format!("table name '{}' is invalid", table));
|
||||
bail!("table name '{}' is invalid", table);
|
||||
}
|
||||
let c = self.config.get();
|
||||
let tablestoredir = c.table_store.directory.clone();
|
||||
std::fs::create_dir_all(&tablestoredir)
|
||||
.map_err(|e| format!("failed to create tablestore path: {}", e))?;
|
||||
std::fs::create_dir_all(&tablestoredir).wrap_err("failed to create tablestore path")?;
|
||||
|
||||
let dbpath: PathBuf = [tablestoredir, String::from(table)].iter().collect();
|
||||
Ok(dbpath)
|
||||
}
|
||||
|
||||
fn get_table_name(&self, table: &str) -> Result<String, String> {
|
||||
fn get_table_name(&self, table: &str) -> EyreResult<String> {
|
||||
if !table
|
||||
.chars()
|
||||
.all(|c| char::is_alphanumeric(c) || c == '_' || c == '-')
|
||||
{
|
||||
return Err(format!("table name '{}' is invalid", table));
|
||||
bail!("table name '{}' is invalid", table);
|
||||
}
|
||||
let c = self.config.get();
|
||||
let namespace = c.namespace.clone();
|
||||
@ -83,7 +82,7 @@ impl TableStore {
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn open(&self, name: &str, column_count: u32) -> Result<TableDB, String> {
|
||||
pub async fn open(&self, name: &str, column_count: u32) -> EyreResult<TableDB> {
|
||||
let table_name = self.get_table_name(name)?;
|
||||
|
||||
let mut inner = self.inner.lock();
|
||||
@ -104,8 +103,7 @@ impl TableStore {
|
||||
ensure_file_private_owner(&dbpath)?;
|
||||
|
||||
let cfg = DatabaseConfig::with_columns(column_count);
|
||||
let db =
|
||||
Database::open(&dbpath, cfg).map_err(|e| format!("failed to open tabledb: {}", e))?;
|
||||
let db = Database::open(&dbpath, cfg).wrap_err("failed to open tabledb")?;
|
||||
|
||||
// Ensure permissions are correct
|
||||
ensure_file_private_owner(&dbpath)?;
|
||||
@ -123,12 +121,12 @@ impl TableStore {
|
||||
Ok(table_db)
|
||||
}
|
||||
|
||||
pub async fn delete(&self, name: &str) -> Result<bool, String> {
|
||||
pub async fn delete(&self, name: &str) -> EyreResult<bool> {
|
||||
let table_name = self.get_table_name(name)?;
|
||||
|
||||
let inner = self.inner.lock();
|
||||
if inner.opened.contains_key(&table_name) {
|
||||
return Err("Not deleting table that is still opened".to_owned());
|
||||
bail!("Not deleting table that is still opened");
|
||||
}
|
||||
let dbpath = self.get_dbpath(&table_name)?;
|
||||
let ret = std::fs::remove_file(dbpath).is_ok();
|
||||
|
@ -266,13 +266,13 @@ pub struct PlatformSupportApple {
|
||||
}
|
||||
|
||||
impl PlatformSupportApple {
|
||||
pub fn new() -> Result<Self, String> {
|
||||
pub fn new() -> EyreResult<Self> {
|
||||
Ok(PlatformSupportApple {
|
||||
default_route_interfaces: BTreeSet::new(),
|
||||
})
|
||||
}
|
||||
|
||||
async fn refresh_default_route_interfaces(&mut self) -> Result<(), String> {
|
||||
async fn refresh_default_route_interfaces(&mut self) -> EyreResult<()> {
|
||||
self.default_route_interfaces.clear();
|
||||
|
||||
let mut mib = [CTL_NET, PF_ROUTE, 0, 0, NET_RT_FLAGS, RTF_GATEWAY];
|
||||
@ -292,7 +292,7 @@ impl PlatformSupportApple {
|
||||
)
|
||||
} < 0
|
||||
{
|
||||
return Err("Unable to get memory size for routing table".to_owned());
|
||||
bail!("Unable to get memory size for routing table");
|
||||
}
|
||||
|
||||
// Allocate a buffer
|
||||
@ -310,7 +310,7 @@ impl PlatformSupportApple {
|
||||
)
|
||||
} < 0
|
||||
{
|
||||
return Err("Unable to get memory size for routing table".to_owned());
|
||||
bail!("Unable to get memory size for routing table");
|
||||
}
|
||||
|
||||
// Process each routing message
|
||||
@ -363,7 +363,7 @@ impl PlatformSupportApple {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_interface_flags(&self, index: u32, flags: c_int) -> Result<InterfaceFlags, String> {
|
||||
fn get_interface_flags(&self, index: u32, flags: c_int) -> EyreResult<InterfaceFlags> {
|
||||
Ok(InterfaceFlags {
|
||||
is_loopback: (flags & IFF_LOOPBACK) != 0,
|
||||
is_running: (flags & IFF_RUNNING) != 0,
|
||||
@ -371,23 +371,23 @@ impl PlatformSupportApple {
|
||||
})
|
||||
}
|
||||
|
||||
fn get_address_flags(ifname: &str, addr: sockaddr_in6) -> Result<AddressFlags, String> {
|
||||
fn get_address_flags(ifname: &str, addr: sockaddr_in6) -> EyreResult<AddressFlags> {
|
||||
let mut req = in6_ifreq::from_name(&ifname).unwrap();
|
||||
req.set_addr(addr);
|
||||
|
||||
let sock = unsafe { socket(AF_INET6, SOCK_DGRAM, 0) };
|
||||
if sock < 0 {
|
||||
return Err(format!("Socket error {:?}", io::Error::last_os_error()));
|
||||
bail!("Socket error {:?}", io::Error::last_os_error());
|
||||
}
|
||||
|
||||
let res = unsafe { ioctl(sock, SIOCGIFAFLAG_IN6, &mut req) };
|
||||
unsafe { close(sock) };
|
||||
if res < 0 {
|
||||
return Err(format!(
|
||||
bail!(
|
||||
"SIOCGIFAFLAG_IN6 failed with error on device '{}': {:?}",
|
||||
ifname,
|
||||
io::Error::last_os_error()
|
||||
));
|
||||
);
|
||||
}
|
||||
|
||||
let flags = req.get_flags6();
|
||||
@ -404,12 +404,12 @@ impl PlatformSupportApple {
|
||||
pub async fn get_interfaces(
|
||||
&mut self,
|
||||
interfaces: &mut BTreeMap<String, NetworkInterface>,
|
||||
) -> Result<(), String> {
|
||||
) -> EyreResult<()> {
|
||||
self.refresh_default_route_interfaces().await?;
|
||||
|
||||
// If we have no routes, this isn't going to work
|
||||
if self.default_route_interfaces.is_empty() {
|
||||
return Err("no routes available for NetworkInterfaces".to_owned());
|
||||
bail!("no routes available for NetworkInterfaces");
|
||||
}
|
||||
|
||||
// Ask for all the addresses we have
|
||||
|
@ -329,7 +329,7 @@ impl NetworkInterfaces {
|
||||
self.valid = false;
|
||||
}
|
||||
// returns Ok(false) if refresh had no changes, Ok(true) if changes were present
|
||||
pub async fn refresh(&mut self) -> Result<bool, String> {
|
||||
pub async fn refresh(&mut self) -> EyreResult<bool> {
|
||||
self.valid = false;
|
||||
let last_interfaces = core::mem::take(&mut self.interfaces);
|
||||
|
||||
|
@ -25,16 +25,16 @@ use std::io;
|
||||
use std::os::raw::c_int;
|
||||
use tools::*;
|
||||
|
||||
fn get_interface_name(index: u32) -> Result<String, String> {
|
||||
fn get_interface_name(index: u32) -> EyreResult<String> {
|
||||
let mut ifnamebuf = [0u8; (IF_NAMESIZE + 1)];
|
||||
cfg_if! {
|
||||
if #[cfg(all(any(target_os = "android", target_os="linux"), any(target_arch = "arm", target_arch = "aarch64")))] {
|
||||
if unsafe { if_indextoname(index, ifnamebuf.as_mut_ptr()) }.is_null() {
|
||||
return Err("if_indextoname returned null".to_owned());
|
||||
bail!("if_indextoname returned null");
|
||||
}
|
||||
} else {
|
||||
if unsafe { if_indextoname(index, ifnamebuf.as_mut_ptr() as *mut i8) }.is_null() {
|
||||
return Err("if_indextoname returned null".to_owned());
|
||||
bail!("if_indextoname returned null");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -42,11 +42,11 @@ fn get_interface_name(index: u32) -> Result<String, String> {
|
||||
let ifnamebuflen = ifnamebuf
|
||||
.iter()
|
||||
.position(|c| *c == 0u8)
|
||||
.ok_or_else(|| "null not found in interface name".to_owned())?;
|
||||
.ok_or_else(|| eyre!("null not found in interface name"))?;
|
||||
let ifname_str = CStr::from_bytes_with_nul(&ifnamebuf[0..=ifnamebuflen])
|
||||
.map_err(map_to_string)?
|
||||
.wrap_err("failed to convert interface name")?
|
||||
.to_str()
|
||||
.map_err(map_to_string)?;
|
||||
.wrap_err("invalid characters in interface name")?;
|
||||
Ok(ifname_str.to_owned())
|
||||
}
|
||||
|
||||
@ -67,7 +67,7 @@ pub struct PlatformSupportNetlink {
|
||||
}
|
||||
|
||||
impl PlatformSupportNetlink {
|
||||
pub fn new() -> Result<Self, String> {
|
||||
pub fn new() -> EyreResult<Self> {
|
||||
Ok(PlatformSupportNetlink {
|
||||
connection_jh: None,
|
||||
handle: None,
|
||||
@ -76,7 +76,7 @@ impl PlatformSupportNetlink {
|
||||
}
|
||||
|
||||
// Figure out which interfaces have default routes
|
||||
async fn refresh_default_route_interfaces(&mut self) -> Result<(), String> {
|
||||
async fn refresh_default_route_interfaces(&mut self) -> EyreResult<()> {
|
||||
self.default_route_interfaces.clear();
|
||||
let mut routesv4 = self
|
||||
.handle
|
||||
@ -111,12 +111,12 @@ impl PlatformSupportNetlink {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_interface_flags(&self, index: u32, ifname: &str) -> Result<InterfaceFlags, String> {
|
||||
let mut req = ifreq::from_name(ifname).map_err(map_to_string)?;
|
||||
fn get_interface_flags(&self, index: u32, ifname: &str) -> EyreResult<InterfaceFlags> {
|
||||
let mut req = ifreq::from_name(ifname).wrap_err("failed to convert interface name")?;
|
||||
|
||||
let sock = unsafe { socket(AF_INET as i32, SOCK_DGRAM, 0) };
|
||||
if sock < 0 {
|
||||
return Err(io::Error::last_os_error()).map_err(map_to_string);
|
||||
return Err(io::Error::last_os_error()).wrap_err("failed to create socket");
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
@ -128,7 +128,7 @@ impl PlatformSupportNetlink {
|
||||
}
|
||||
unsafe { close(sock) };
|
||||
if res < 0 {
|
||||
return Err(io::Error::last_os_error()).map_err(map_to_string);
|
||||
return Err(io::Error::last_os_error()).wrap_err("failed to close socket");
|
||||
}
|
||||
|
||||
let flags = req.get_flags() as c_int;
|
||||
@ -242,13 +242,13 @@ impl PlatformSupportNetlink {
|
||||
async fn get_interfaces_internal(
|
||||
&mut self,
|
||||
interfaces: &mut BTreeMap<String, NetworkInterface>,
|
||||
) -> Result<(), String> {
|
||||
) -> EyreResult<()> {
|
||||
// Refresh the routes
|
||||
self.refresh_default_route_interfaces().await?;
|
||||
|
||||
// If we have no routes, this isn't going to work
|
||||
if self.default_route_interfaces.is_empty() {
|
||||
return Err("no routes available for NetworkInterfaces".to_owned());
|
||||
bail!("no routes available for NetworkInterfaces");
|
||||
}
|
||||
|
||||
// Ask for all the addresses we have
|
||||
@ -257,8 +257,7 @@ impl PlatformSupportNetlink {
|
||||
while let Some(msg) = addresses
|
||||
.try_next()
|
||||
.await
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!(error))?
|
||||
.wrap_err("failed to iterate interface addresses")?
|
||||
{
|
||||
// Have we seen this interface index yet?
|
||||
// Get the name from the index, cached, if we can
|
||||
@ -268,7 +267,7 @@ impl PlatformSupportNetlink {
|
||||
let ifname = match get_interface_name(msg.header.index) {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
log_net!(
|
||||
log_net!(warn
|
||||
"couldn't get interface name for index {}: {}",
|
||||
msg.header.index,
|
||||
e
|
||||
@ -317,11 +316,10 @@ impl PlatformSupportNetlink {
|
||||
pub async fn get_interfaces(
|
||||
&mut self,
|
||||
interfaces: &mut BTreeMap<String, NetworkInterface>,
|
||||
) -> Result<(), String> {
|
||||
) -> EyreResult<()> {
|
||||
// Get the netlink connection
|
||||
let (connection, handle, _) = new_connection_with_socket::<RTNetLinkSocket>()
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!(error))?;
|
||||
.wrap_err("failed to create rtnetlink socket")?;
|
||||
|
||||
// Spawn a connection handler
|
||||
let connection_jh = intf::spawn(connection);
|
||||
|
@ -28,7 +28,7 @@ use winapi::um::iptypes::{
|
||||
pub struct PlatformSupportWindows {}
|
||||
|
||||
impl PlatformSupportWindows {
|
||||
pub fn new() -> Result<Self, String> {
|
||||
pub fn new() -> EyreResult<Self> {
|
||||
Ok(PlatformSupportWindows {})
|
||||
}
|
||||
|
||||
@ -54,7 +54,7 @@ impl PlatformSupportWindows {
|
||||
pub async fn get_interfaces(
|
||||
&mut self,
|
||||
interfaces: &mut BTreeMap<String, NetworkInterface>,
|
||||
) -> Result<(), String> {
|
||||
) -> EyreResult<()> {
|
||||
//self.refresh_default_route_interfaces().await?;
|
||||
|
||||
// If we have no routes, this isn't going to work
|
||||
@ -63,7 +63,7 @@ impl PlatformSupportWindows {
|
||||
// }
|
||||
|
||||
// Iterate all the interfaces
|
||||
let windows_interfaces = WindowsInterfaces::new().map_err(map_to_string)?;
|
||||
let windows_interfaces = WindowsInterfaces::new().wrap_err("failed to get windows interfaces")?;
|
||||
for windows_interface in windows_interfaces.iter() {
|
||||
// Get name
|
||||
let intf_name = windows_interface.name();
|
||||
|
@ -48,58 +48,52 @@ impl TableDB {
|
||||
Arc::downgrade(&self.inner)
|
||||
}
|
||||
|
||||
pub async fn get_column_count(&self) -> Result<u32, String> {
|
||||
pub async fn get_column_count(&self) -> EyreResult<u32> {
|
||||
let db = &self.inner.lock().database;
|
||||
db.num_columns()
|
||||
.map_err(|e| format!("failed to get column count: {}", e))
|
||||
db.num_columns().wrap_err("failed to get column count: {}")
|
||||
}
|
||||
|
||||
pub async fn get_keys(&self, col: u32) -> Result<Vec<Box<[u8]>>, String> {
|
||||
pub async fn get_keys(&self, col: u32) -> EyreResult<Vec<Box<[u8]>>> {
|
||||
let db = &self.inner.lock().database;
|
||||
let mut out: Vec<Box<[u8]>> = Vec::new();
|
||||
db.iter(col, None, &mut |kv| {
|
||||
out.push(kv.0.clone().into_boxed_slice());
|
||||
Ok(true)
|
||||
})
|
||||
.map_err(|e| format!("failed to get keys for column {}: {}", col, e))?;
|
||||
.wrap_err("failed to get keys for column")?;
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
pub async fn store(&self, col: u32, key: &[u8], value: &[u8]) -> Result<(), String> {
|
||||
pub async fn store(&self, col: u32, key: &[u8], value: &[u8]) -> EyreResult<()> {
|
||||
let db = &self.inner.lock().database;
|
||||
let mut dbt = db.transaction();
|
||||
dbt.put(col, key, value);
|
||||
db.write(dbt)
|
||||
.map_err(|e| format!("failed to store key {:?}: {}", key, e))
|
||||
db.write(dbt).wrap_err("failed to store key")
|
||||
}
|
||||
|
||||
pub async fn store_cbor<T>(&self, col: u32, key: &[u8], value: &T) -> Result<(), String>
|
||||
pub async fn store_cbor<T>(&self, col: u32, key: &[u8], value: &T) -> EyreResult<()>
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
let v = serde_cbor::to_vec(value).map_err(|_| "couldn't store as CBOR".to_owned())?;
|
||||
let v = serde_cbor::to_vec(value).wrap_err("couldn't store as CBOR")?;
|
||||
|
||||
let db = &self.inner.lock().database;
|
||||
let mut dbt = db.transaction();
|
||||
dbt.put(col, key, v.as_slice());
|
||||
db.write(dbt)
|
||||
.map_err(|e| format!("failed to store key {:?}: {}", key, e))
|
||||
db.write(dbt).wrap_err("failed to store key")
|
||||
}
|
||||
|
||||
pub async fn load(&self, col: u32, key: &[u8]) -> Result<Option<Vec<u8>>, String> {
|
||||
pub async fn load(&self, col: u32, key: &[u8]) -> EyreResult<Option<Vec<u8>>> {
|
||||
let db = &self.inner.lock().database;
|
||||
db.get(col, key)
|
||||
.map_err(|e| format!("failed to get key {:?}: {}", key, e))
|
||||
db.get(col, key).wrap_err("failed to get key")
|
||||
}
|
||||
|
||||
pub async fn load_cbor<T>(&self, col: u32, key: &[u8]) -> Result<Option<T>, String>
|
||||
pub async fn load_cbor<T>(&self, col: u32, key: &[u8]) -> EyreResult<Option<T>>
|
||||
where
|
||||
T: for<'de> Deserialize<'de>,
|
||||
{
|
||||
let db = &self.inner.lock().database;
|
||||
let out = db
|
||||
.get(col, key)
|
||||
.map_err(|e| format!("failed to get key {:?}: {}", key, e))?;
|
||||
let out = db.get(col, key).wrap_err("failed to get key")?;
|
||||
let b = match out {
|
||||
Some(v) => v,
|
||||
None => {
|
||||
@ -109,24 +103,21 @@ impl TableDB {
|
||||
let obj = match serde_cbor::from_slice::<T>(&b) {
|
||||
Ok(value) => value,
|
||||
Err(e) => {
|
||||
return Err(format!("failed to deserialize: {}", e));
|
||||
bail!("failed to deserialize");
|
||||
}
|
||||
};
|
||||
Ok(Some(obj))
|
||||
}
|
||||
|
||||
pub async fn delete(&self, col: u32, key: &[u8]) -> Result<bool, String> {
|
||||
pub async fn delete(&self, col: u32, key: &[u8]) -> EyreResult<bool> {
|
||||
let db = &self.inner.lock().database;
|
||||
let found = db
|
||||
.get(col, key)
|
||||
.map_err(|e| format!("failed to get key {:?}: {}", key, e))?;
|
||||
let found = db.get(col, key).wrap_err("failed to get key")?;
|
||||
match found {
|
||||
None => Ok(false),
|
||||
Some(_) => {
|
||||
let mut dbt = db.transaction();
|
||||
dbt.delete(col, key);
|
||||
db.write(dbt)
|
||||
.map_err(|e| format!("failed to delete key {:?}: {}", key, e))?;
|
||||
db.write(dbt).wrap_err("failed to delete key")?;
|
||||
Ok(true)
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ impl BlockStore {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn init(&self) -> Result<(), String> {
|
||||
pub async fn init(&self) -> EyreResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ impl ProtectedStore {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn delete_all(&self) -> Result<(), String> {
|
||||
pub async fn delete_all(&self) -> EyreResult<()> {
|
||||
// Delete all known keys
|
||||
if self.remove_user_secret_string("node_id").await? {
|
||||
debug!("deleted protected_store key 'node_id'");
|
||||
@ -44,7 +44,7 @@ impl ProtectedStore {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn init(&self) -> Result<(), String> {
|
||||
pub async fn init(&self) -> EyreResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -68,11 +68,11 @@ impl ProtectedStore {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn save_user_secret_string(&self, key: &str, value: &str) -> Result<bool, String> {
|
||||
pub async fn save_user_secret_string(&self, key: &str, value: &str) -> EyreResult<bool> {
|
||||
if utils::is_nodejs() {
|
||||
let prev = match JsFuture::from(
|
||||
keytar_getPassword(self.keyring_name().as_str(), key)
|
||||
.map_err(|_| "exception thrown".to_owned())?,
|
||||
.wrap_err("exception thrown")?,
|
||||
)
|
||||
.await
|
||||
{
|
||||
@ -82,12 +82,12 @@ impl ProtectedStore {
|
||||
|
||||
match JsFuture::from(
|
||||
keytar_setPassword(self.keyring_name().as_str(), key, value)
|
||||
.map_err(|_| "exception thrown".to_owned())?,
|
||||
.wrap_err("exception thrown")?,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(_) => {}
|
||||
Err(_) => return Err("Failed to set password".to_owned()),
|
||||
Err(_) => bail!("Failed to set password"),
|
||||
}
|
||||
|
||||
Ok(prev)
|
||||
@ -95,17 +95,17 @@ impl ProtectedStore {
|
||||
let win = match window() {
|
||||
Some(w) => w,
|
||||
None => {
|
||||
return Err("failed to get window".to_owned());
|
||||
bail!("failed to get window");
|
||||
}
|
||||
};
|
||||
|
||||
let ls = match win
|
||||
.local_storage()
|
||||
.map_err(|_| "exception getting local storage".to_owned())?
|
||||
.wrap_err("exception getting local storage")?
|
||||
{
|
||||
Some(l) => l,
|
||||
None => {
|
||||
return Err("failed to get local storage".to_owned());
|
||||
bail!("failed to get local storage");
|
||||
}
|
||||
};
|
||||
|
||||
@ -113,26 +113,26 @@ impl ProtectedStore {
|
||||
|
||||
let prev = match ls
|
||||
.get_item(&vkey)
|
||||
.map_err(|_| "exception_thrown".to_owned())?
|
||||
.wrap_err("exception_thrown")?
|
||||
{
|
||||
Some(_) => true,
|
||||
None => false,
|
||||
};
|
||||
|
||||
ls.set_item(&vkey, value)
|
||||
.map_err(|_| "exception_thrown".to_owned())?;
|
||||
.wrap_err("exception_thrown")?;
|
||||
|
||||
Ok(prev)
|
||||
} else {
|
||||
Err("unimplemented".to_owned())
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn load_user_secret_string(&self, key: &str) -> Result<Option<String>, String> {
|
||||
pub async fn load_user_secret_string(&self, key: &str) -> EyreResult<Option<String>> {
|
||||
if utils::is_nodejs() {
|
||||
let prev = match JsFuture::from(
|
||||
keytar_getPassword(self.keyring_name().as_str(), key)
|
||||
.map_err(|_| "exception thrown".to_owned())?,
|
||||
.wrap_err("exception thrown")?,
|
||||
)
|
||||
.await
|
||||
{
|
||||
@ -149,54 +149,54 @@ impl ProtectedStore {
|
||||
let win = match window() {
|
||||
Some(w) => w,
|
||||
None => {
|
||||
return Err("failed to get window".to_owned());
|
||||
bail!("failed to get window");
|
||||
}
|
||||
};
|
||||
|
||||
let ls = match win
|
||||
.local_storage()
|
||||
.map_err(|_| "exception getting local storage".to_owned())?
|
||||
.wrap_err("exception getting local storage")?
|
||||
{
|
||||
Some(l) => l,
|
||||
None => {
|
||||
return Err("failed to get local storage".to_owned());
|
||||
bail!("failed to get local storage");
|
||||
}
|
||||
};
|
||||
|
||||
let vkey = self.browser_key_name(key);
|
||||
|
||||
ls.get_item(&vkey)
|
||||
.map_err(|_| "exception_thrown".to_owned())
|
||||
.wrap_err("exception_thrown")
|
||||
} else {
|
||||
Err("unimplemented".to_owned())
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn remove_user_secret_string(&self, key: &str) -> Result<bool, String> {
|
||||
pub async fn remove_user_secret_string(&self, key: &str) -> EyreResult<bool> {
|
||||
if utils::is_nodejs() {
|
||||
match JsFuture::from(
|
||||
keytar_deletePassword(self.keyring_name().as_str(), key).map_err(|_| "exception thrown".to_owned())?,
|
||||
keytar_deletePassword(self.keyring_name().as_str(), key).wrap_err("exception thrown")?,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(v) => Ok(v.is_truthy()),
|
||||
Err(_) => Err("Failed to delete".to_owned()),
|
||||
Err(_) => bail!("Failed to delete"),
|
||||
}
|
||||
} else if utils::is_browser() {
|
||||
let win = match window() {
|
||||
Some(w) => w,
|
||||
None => {
|
||||
return Err("failed to get window".to_owned());
|
||||
bail!("failed to get window");
|
||||
}
|
||||
};
|
||||
|
||||
let ls = match win
|
||||
.local_storage()
|
||||
.map_err(|_| "exception getting local storage".to_owned())?
|
||||
.wrap_err("exception getting local storage")?
|
||||
{
|
||||
Some(l) => l,
|
||||
None => {
|
||||
return Err("failed to get local storage".to_owned());
|
||||
bail!("failed to get local storage");
|
||||
}
|
||||
};
|
||||
|
||||
@ -204,28 +204,28 @@ impl ProtectedStore {
|
||||
|
||||
match ls
|
||||
.get_item(&vkey)
|
||||
.map_err(|_| "exception_thrown".to_owned())?
|
||||
.wrap_err("exception_thrown")?
|
||||
{
|
||||
Some(_) => {
|
||||
ls.delete(&vkey)
|
||||
.map_err(|_| "exception_thrown".to_owned())?;
|
||||
.wrap_err("exception_thrown")?;
|
||||
Ok(true)
|
||||
}
|
||||
None => Ok(false),
|
||||
}
|
||||
} else {
|
||||
Err("unimplemented".to_owned())
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn save_user_secret(&self, key: &str, value: &[u8]) -> Result<bool, String> {
|
||||
pub async fn save_user_secret(&self, key: &str, value: &[u8]) -> EyreResult<bool> {
|
||||
let mut s = BASE64URL_NOPAD.encode(value);
|
||||
s.push('!');
|
||||
|
||||
self.save_user_secret_string(key, s.as_str()).await
|
||||
}
|
||||
|
||||
pub async fn load_user_secret(&self, key: &str) -> Result<Option<Vec<u8>>, String> {
|
||||
pub async fn load_user_secret(&self, key: &str) -> EyreResult<Option<Vec<u8>>> {
|
||||
let mut s = match self.load_user_secret_string(key).await? {
|
||||
Some(s) => s,
|
||||
None => {
|
||||
@ -234,7 +234,7 @@ impl ProtectedStore {
|
||||
};
|
||||
|
||||
if s.pop() != Some('!') {
|
||||
return Err("User secret is not a buffer".to_owned());
|
||||
bail!("User secret is not a buffer");
|
||||
}
|
||||
|
||||
let mut bytes = Vec::<u8>::new();
|
||||
@ -244,18 +244,18 @@ impl ProtectedStore {
|
||||
bytes.resize(l, 0u8);
|
||||
}
|
||||
Err(_) => {
|
||||
return Err("Failed to decode".to_owned());
|
||||
bail!("Failed to decode");
|
||||
}
|
||||
}
|
||||
|
||||
let res = BASE64URL_NOPAD.decode_mut(s.as_bytes(), &mut bytes);
|
||||
match res {
|
||||
Ok(_) => Ok(Some(bytes)),
|
||||
Err(_) => Err("Failed to decode".to_owned()),
|
||||
Err(_) => bail!("Failed to decode"),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn remove_user_secret(&self, key: &str) -> Result<bool, String> {
|
||||
pub async fn remove_user_secret(&self, key: &str) -> EyreResult<bool> {
|
||||
self.remove_user_secret_string(key).await
|
||||
}
|
||||
}
|
@ -39,7 +39,7 @@ pub fn get_timestamp_string() -> String {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn random_bytes(dest: &mut [u8]) -> Result<(), String> {
|
||||
pub fn random_bytes(dest: &mut [u8]) -> EyreResult<()> {
|
||||
let len = dest.len();
|
||||
let u32len = len / 4;
|
||||
let remlen = len % 4;
|
||||
@ -161,25 +161,12 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub struct TimeoutError {
|
||||
_private: (),
|
||||
}
|
||||
|
||||
//impl Error for TimeoutError {}
|
||||
|
||||
impl fmt::Display for TimeoutError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
"future has timed out".fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn timeout<F, T>(dur_ms: u32, f: F) -> Result<T, TimeoutError>
|
||||
where
|
||||
F: Future<Output = T>,
|
||||
{
|
||||
match select(Box::pin(intf::sleep(dur_ms)), Box::pin(f)).await {
|
||||
Either::Left((_x, _b)) => Err(TimeoutError { _private: () }),
|
||||
Either::Left((_x, _b)) => Err(TimeoutError()),
|
||||
Either::Right((y, _a)) => Ok(y),
|
||||
}
|
||||
}
|
||||
@ -227,10 +214,10 @@ pub async fn get_outbound_relay_peer() -> Option<crate::veilid_api::PeerInfo> {
|
||||
// }
|
||||
|
||||
|
||||
pub async fn txt_lookup<S: AsRef<str>>(_host: S) -> Result<Vec<String>, String> {
|
||||
Err("wasm does not support txt lookup".to_owned())
|
||||
pub async fn txt_lookup<S: AsRef<str>>(_host: S) -> EyreResult<Vec<String>> {
|
||||
bail!("wasm does not support txt lookup")
|
||||
}
|
||||
|
||||
pub async fn ptr_lookup(_ip_addr: IpAddr) -> Result<String, String> {
|
||||
Err("wasm does not support ptr lookup".to_owned())
|
||||
pub async fn ptr_lookup(_ip_addr: IpAddr) -> EyreResult<String> {
|
||||
bail!("wasm does not support ptr lookup")
|
||||
}
|
||||
|
@ -18,14 +18,16 @@ impl ConnectionHandle {
|
||||
self.descriptor.clone()
|
||||
}
|
||||
|
||||
pub fn send(&self, message: Vec<u8>) -> Result<(), String> {
|
||||
self.channel.send(message).map_err(map_to_string)
|
||||
pub fn send(&self, message: Vec<u8>) -> EyreResult<()> {
|
||||
self.channel
|
||||
.send(message)
|
||||
.wrap_err("failed to send to connection")
|
||||
}
|
||||
pub async fn send_async(&self, message: Vec<u8>) -> Result<(), String> {
|
||||
pub async fn send_async(&self, message: Vec<u8>) -> EyreResult<()> {
|
||||
self.channel
|
||||
.send_async(message)
|
||||
.await
|
||||
.map_err(map_to_string)
|
||||
.wrap_err("failed to send_async to connection")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,33 +1,17 @@
|
||||
use super::*;
|
||||
use alloc::collections::btree_map::Entry;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(ThisError, Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum AddressFilterError {
|
||||
#[error("Count exceeded")]
|
||||
CountExceeded,
|
||||
#[error("Rate exceeded")]
|
||||
RateExceeded,
|
||||
}
|
||||
impl fmt::Display for AddressFilterError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
match *self {
|
||||
Self::CountExceeded => "Count exceeded",
|
||||
Self::RateExceeded => "Rate exceeded",
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
impl std::error::Error for AddressFilterError {}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(ThisError, Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[error("Address not in table")]
|
||||
pub struct AddressNotInTableError {}
|
||||
impl fmt::Display for AddressNotInTableError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Address not in table")
|
||||
}
|
||||
}
|
||||
impl std::error::Error for AddressNotInTableError {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ConnectionLimits {
|
||||
|
@ -142,13 +142,13 @@ impl ConnectionManager {
|
||||
&self,
|
||||
inner: &mut ConnectionManagerInner,
|
||||
conn: ProtocolNetworkConnection,
|
||||
) -> Result<ConnectionHandle, String> {
|
||||
) -> EyreResult<ConnectionHandle> {
|
||||
log_net!("on_new_protocol_network_connection: {:?}", conn);
|
||||
|
||||
// Wrap with NetworkConnection object to start the connection processing loop
|
||||
let stop_token = match &inner.stop_source {
|
||||
Some(ss) => ss.token(),
|
||||
None => return Err("not creating connection because we are stopping".to_owned()),
|
||||
None => bail!("not creating connection because we are stopping"),
|
||||
};
|
||||
|
||||
let conn = NetworkConnection::from_protocol(self.clone(), stop_token, conn);
|
||||
@ -165,7 +165,7 @@ impl ConnectionManager {
|
||||
&self,
|
||||
local_addr: Option<SocketAddr>,
|
||||
dial_info: DialInfo,
|
||||
) -> Result<ConnectionHandle, String> {
|
||||
) -> EyreResult<ConnectionHandle> {
|
||||
let killed = {
|
||||
let mut inner = self.arc.inner.lock();
|
||||
let inner = match &mut *inner {
|
||||
@ -274,7 +274,7 @@ impl ConnectionManager {
|
||||
let inner = match &mut *inner {
|
||||
Some(v) => v,
|
||||
None => {
|
||||
return Err("shutting down".to_owned());
|
||||
bail!("shutting down");
|
||||
}
|
||||
};
|
||||
self.on_new_protocol_network_connection(inner, conn)
|
||||
@ -336,7 +336,7 @@ impl ConnectionManager {
|
||||
pub(super) async fn on_accepted_protocol_network_connection(
|
||||
&self,
|
||||
conn: ProtocolNetworkConnection,
|
||||
) -> Result<(), String> {
|
||||
) -> EyreResult<()> {
|
||||
// Get channel sender
|
||||
let sender = {
|
||||
let mut inner = self.arc.inner.lock();
|
||||
|
@ -3,6 +3,39 @@ use alloc::collections::btree_map::Entry;
|
||||
use futures_util::StreamExt;
|
||||
use hashlink::LruCache;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#[derive(ThisError, Debug, Clone, Eq, PartialEq)]
|
||||
pub enum ConnectionTableAddError {
|
||||
#[error("Connection already added to table")]
|
||||
AlreadyExists,
|
||||
#[error("Connection address was filtered")]
|
||||
AddressFilter(AddressFilterError),
|
||||
}
|
||||
|
||||
impl ConnectionTableAddError {
|
||||
pub fn already_exists() -> Self {
|
||||
ConnectionTableAddError::AlreadyExists
|
||||
}
|
||||
pub fn address_filter(err: AddressFilterError) -> Self {
|
||||
ConnectionTableAddError::AddressFilter(err)
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#[derive(ThisError, Debug, Clone, Eq, PartialEq)]
|
||||
pub enum ConnectionTableRemoveError {
|
||||
#[error("Connection not in table")]
|
||||
NotInTable,
|
||||
}
|
||||
|
||||
impl ConnectionTableRemoveError {
|
||||
pub fn not_in_table() -> Self {
|
||||
ConnectionTableRemoveError::NotInTable
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ConnectionTable {
|
||||
max_connections: Vec<usize>,
|
||||
@ -53,20 +86,22 @@ impl ConnectionTable {
|
||||
while unord.next().await.is_some() {}
|
||||
}
|
||||
|
||||
pub fn add_connection(&mut self, conn: NetworkConnection) -> Result<(), String> {
|
||||
pub fn add_connection(
|
||||
&mut self,
|
||||
conn: NetworkConnection,
|
||||
) -> Result<(), ConnectionTableAddError> {
|
||||
let descriptor = conn.connection_descriptor();
|
||||
let ip_addr = descriptor.remote_address().to_ip_addr();
|
||||
|
||||
let index = protocol_to_index(descriptor.protocol_type());
|
||||
if self.conn_by_descriptor[index].contains_key(&descriptor) {
|
||||
return Err(format!(
|
||||
"Connection already added to table: {:?}",
|
||||
descriptor
|
||||
));
|
||||
return Err(ConnectionTableAddError::already_exists());
|
||||
}
|
||||
|
||||
// Filter by ip for connection limits
|
||||
self.address_filter.add(ip_addr).map_err(map_to_string)?;
|
||||
self.address_filter
|
||||
.add(ip_addr)
|
||||
.map_err(ConnectionTableAddError::address_filter)?;
|
||||
|
||||
// Add the connection to the table
|
||||
let res = self.conn_by_descriptor[index].insert(descriptor.clone(), conn);
|
||||
@ -164,11 +199,11 @@ impl ConnectionTable {
|
||||
pub fn remove_connection(
|
||||
&mut self,
|
||||
descriptor: ConnectionDescriptor,
|
||||
) -> Result<NetworkConnection, String> {
|
||||
) -> Result<NetworkConnection, ConnectionTableRemoveError> {
|
||||
let index = protocol_to_index(descriptor.protocol_type());
|
||||
let conn = self.conn_by_descriptor[index]
|
||||
.remove(&descriptor)
|
||||
.ok_or_else(|| format!("Connection not in table: {:?}", descriptor))?;
|
||||
.ok_or_else(|| ConnectionTableRemoveError::not_in_table())?;
|
||||
|
||||
self.remove_connection_records(descriptor);
|
||||
Ok(conn)
|
||||
|
@ -127,8 +127,8 @@ struct NetworkManagerInner {
|
||||
|
||||
struct NetworkManagerUnlockedInner {
|
||||
// Background processes
|
||||
rolling_transfers_task: TickTask,
|
||||
relay_management_task: TickTask,
|
||||
rolling_transfers_task: TickTask<EyreReport>,
|
||||
relay_management_task: TickTask<EyreReport>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -236,7 +236,7 @@ impl NetworkManager {
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip_all, err)]
|
||||
pub async fn init(&self, update_callback: UpdateCallback) -> Result<(), String> {
|
||||
pub async fn init(&self, update_callback: UpdateCallback) -> EyreResult<()> {
|
||||
let routing_table = RoutingTable::new(self.clone());
|
||||
routing_table.init().await?;
|
||||
self.inner.lock().routing_table = Some(routing_table.clone());
|
||||
@ -257,7 +257,7 @@ impl NetworkManager {
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip_all, err)]
|
||||
pub async fn internal_startup(&self) -> Result<(), String> {
|
||||
pub async fn internal_startup(&self) -> EyreResult<()> {
|
||||
trace!("NetworkManager::internal_startup begin");
|
||||
if self.inner.lock().components.is_some() {
|
||||
debug!("NetworkManager::internal_startup already started");
|
||||
@ -292,7 +292,7 @@ impl NetworkManager {
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip_all, err)]
|
||||
pub async fn startup(&self) -> Result<(), String> {
|
||||
pub async fn startup(&self) -> EyreResult<()> {
|
||||
if let Err(e) = self.internal_startup().await {
|
||||
self.shutdown().await;
|
||||
return Err(e);
|
||||
@ -387,7 +387,7 @@ impl NetworkManager {
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip_all, err)]
|
||||
async fn restart_net(&self, net: Network) -> Result<(), String> {
|
||||
async fn restart_net(&self, net: Network) -> EyreResult<()> {
|
||||
net.shutdown().await;
|
||||
self.send_network_update();
|
||||
net.startup().await?;
|
||||
@ -395,7 +395,7 @@ impl NetworkManager {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn tick(&self) -> Result<(), String> {
|
||||
pub async fn tick(&self) -> EyreResult<()> {
|
||||
let (routing_table, net, receipt_manager) = {
|
||||
let inner = self.inner.lock();
|
||||
let components = inner.components.as_ref().unwrap();
|
||||
@ -481,7 +481,7 @@ impl NetworkManager {
|
||||
expected_returns: u32,
|
||||
extra_data: D,
|
||||
callback: impl ReceiptCallback,
|
||||
) -> Result<Vec<u8>, String> {
|
||||
) -> EyreResult<Vec<u8>> {
|
||||
let receipt_manager = self.receipt_manager();
|
||||
let routing_table = self.routing_table();
|
||||
|
||||
@ -490,7 +490,7 @@ impl NetworkManager {
|
||||
let receipt = Receipt::try_new(0, nonce, routing_table.node_id(), extra_data)?;
|
||||
let out = receipt
|
||||
.to_signed_data(&routing_table.node_id_secret())
|
||||
.map_err(|_| "failed to generate signed receipt".to_owned())?;
|
||||
.wrap_err("failed to generate signed receipt")?;
|
||||
|
||||
// Record the receipt for later
|
||||
let exp_ts = intf::get_timestamp() + expiration_us;
|
||||
@ -505,7 +505,7 @@ impl NetworkManager {
|
||||
&self,
|
||||
expiration_us: u64,
|
||||
extra_data: D,
|
||||
) -> Result<(Vec<u8>, EventualValueFuture<ReceiptEvent>), String> {
|
||||
) -> EyreResult<(Vec<u8>, EventualValueFuture<ReceiptEvent>)> {
|
||||
let receipt_manager = self.receipt_manager();
|
||||
let routing_table = self.routing_table();
|
||||
|
||||
@ -514,7 +514,7 @@ impl NetworkManager {
|
||||
let receipt = Receipt::try_new(0, nonce, routing_table.node_id(), extra_data)?;
|
||||
let out = receipt
|
||||
.to_signed_data(&routing_table.node_id_secret())
|
||||
.map_err(|_| "failed to generate signed receipt".to_owned())?;
|
||||
.wrap_err("failed to generate signed receipt")?;
|
||||
|
||||
// Record the receipt for later
|
||||
let exp_ts = intf::get_timestamp() + expiration_us;
|
||||
@ -530,11 +530,11 @@ impl NetworkManager {
|
||||
pub async fn handle_out_of_band_receipt<R: AsRef<[u8]>>(
|
||||
&self,
|
||||
receipt_data: R,
|
||||
) -> Result<(), String> {
|
||||
) -> EyreResult<()> {
|
||||
let receipt_manager = self.receipt_manager();
|
||||
|
||||
let receipt = Receipt::from_signed_data(receipt_data.as_ref())
|
||||
.map_err(|_| "failed to parse signed out-of-band receipt".to_owned())?;
|
||||
.wrap_err("failed to parse signed out-of-band receipt")?;
|
||||
|
||||
receipt_manager.handle_receipt(receipt, None).await
|
||||
}
|
||||
@ -545,11 +545,11 @@ impl NetworkManager {
|
||||
&self,
|
||||
receipt_data: R,
|
||||
inbound_nr: NodeRef,
|
||||
) -> Result<(), String> {
|
||||
) -> EyreResult<()> {
|
||||
let receipt_manager = self.receipt_manager();
|
||||
|
||||
let receipt = Receipt::from_signed_data(receipt_data.as_ref())
|
||||
.map_err(|_| "failed to parse signed in-band receipt".to_owned())?;
|
||||
.wrap_err("failed to parse signed in-band receipt")?;
|
||||
|
||||
receipt_manager
|
||||
.handle_receipt(receipt, Some(inbound_nr))
|
||||
@ -558,7 +558,7 @@ impl NetworkManager {
|
||||
|
||||
// Process a received signal
|
||||
#[instrument(level = "trace", skip(self), err)]
|
||||
pub async fn handle_signal(&self, signal_info: SignalInfo) -> Result<(), String> {
|
||||
pub async fn handle_signal(&self, signal_info: SignalInfo) -> EyreResult<()> {
|
||||
match signal_info {
|
||||
SignalInfo::ReverseConnect { receipt, peer_info } => {
|
||||
let routing_table = self.routing_table();
|
||||
@ -573,7 +573,7 @@ impl NetworkManager {
|
||||
// Make a reverse connection to the peer and send the receipt to it
|
||||
rpc.rpc_call_return_receipt(Destination::Direct(peer_nr), None, receipt)
|
||||
.await
|
||||
.map_err(map_to_string)?;
|
||||
.wrap_err("rpc failure")?;
|
||||
}
|
||||
SignalInfo::HolePunch { receipt, peer_info } => {
|
||||
let routing_table = self.routing_table();
|
||||
@ -589,7 +589,7 @@ impl NetworkManager {
|
||||
peer_nr.filter_protocols(ProtocolSet::only(ProtocolType::UDP));
|
||||
let hole_punch_dial_info_detail = peer_nr
|
||||
.first_filtered_dial_info_detail(Some(RoutingDomain::PublicInternet))
|
||||
.ok_or_else(|| "No hole punch capable dialinfo found for node".to_owned())?;
|
||||
.ok_or_else(|| eyre!("No hole punch capable dialinfo found for node"))?;
|
||||
|
||||
// Now that we picked a specific dialinfo, further restrict the noderef to the specific address type
|
||||
let mut filter = peer_nr.take_filter().unwrap();
|
||||
@ -611,7 +611,7 @@ impl NetworkManager {
|
||||
// Return the receipt using the same dial info send the receipt to it
|
||||
rpc.rpc_call_return_receipt(Destination::Direct(peer_nr), None, receipt)
|
||||
.await
|
||||
.map_err(map_to_string)?;
|
||||
.wrap_err("rpc failure")?;
|
||||
}
|
||||
}
|
||||
|
||||
@ -625,7 +625,7 @@ impl NetworkManager {
|
||||
dest_node_id: DHTKey,
|
||||
version: u8,
|
||||
body: B,
|
||||
) -> Result<Vec<u8>, String> {
|
||||
) -> EyreResult<Vec<u8>> {
|
||||
// DH to get encryption key
|
||||
let routing_table = self.routing_table();
|
||||
let node_id = routing_table.node_id();
|
||||
@ -639,7 +639,7 @@ impl NetworkManager {
|
||||
let envelope = Envelope::new(version, ts, nonce, node_id, dest_node_id);
|
||||
envelope
|
||||
.to_encrypted_data(self.crypto.clone(), body.as_ref(), &node_id_secret)
|
||||
.map_err(|_| "envelope failed to encode".to_owned())
|
||||
.wrap_err("envelope failed to encode")
|
||||
}
|
||||
|
||||
// Called by the RPC handler when we want to issue an RPC request or response
|
||||
@ -652,7 +652,7 @@ impl NetworkManager {
|
||||
node_ref: NodeRef,
|
||||
envelope_node_id: Option<DHTKey>,
|
||||
body: B,
|
||||
) -> Result<SendDataKind, String> {
|
||||
) -> EyreResult<SendDataKind> {
|
||||
let via_node_id = node_ref.node_id();
|
||||
let envelope_node_id = envelope_node_id.unwrap_or(via_node_id);
|
||||
|
||||
@ -671,11 +671,12 @@ impl NetworkManager {
|
||||
{
|
||||
#[allow(clippy::absurd_extreme_comparisons)]
|
||||
if node_min > MAX_VERSION || node_max < MIN_VERSION {
|
||||
return Err(format!(
|
||||
bail!(
|
||||
"can't talk to this node {} because version is unsupported: ({},{})",
|
||||
via_node_id, node_min, node_max
|
||||
))
|
||||
.map_err(logthru_rpc!(warn));
|
||||
via_node_id,
|
||||
node_min,
|
||||
node_max
|
||||
);
|
||||
}
|
||||
cmp::min(node_max, MAX_VERSION)
|
||||
} else {
|
||||
@ -703,7 +704,7 @@ impl NetworkManager {
|
||||
&self,
|
||||
dial_info: DialInfo,
|
||||
rcpt_data: Vec<u8>,
|
||||
) -> Result<(), String> {
|
||||
) -> EyreResult<()> {
|
||||
// Do we need to validate the outgoing receipt? Probably not
|
||||
// because it is supposed to be opaque and the
|
||||
// recipient/originator does the validation
|
||||
@ -717,8 +718,8 @@ impl NetworkManager {
|
||||
}
|
||||
|
||||
// Figure out how to reach a node
|
||||
#[instrument(level = "trace", skip(self), ret, err)]
|
||||
fn get_contact_method(&self, mut target_node_ref: NodeRef) -> Result<ContactMethod, String> {
|
||||
#[instrument(level = "trace", skip(self), ret)]
|
||||
fn get_contact_method(&self, mut target_node_ref: NodeRef) -> ContactMethod {
|
||||
let routing_table = self.routing_table();
|
||||
|
||||
// Get our network class and protocol config and node id
|
||||
@ -727,14 +728,14 @@ impl NetworkManager {
|
||||
|
||||
// Scope noderef down to protocols we can do outbound
|
||||
if !target_node_ref.filter_protocols(our_protocol_config.outbound) {
|
||||
return Ok(ContactMethod::Unreachable);
|
||||
return ContactMethod::Unreachable;
|
||||
}
|
||||
|
||||
// Get the best matching local direct dial info if we have it
|
||||
let opt_target_local_did =
|
||||
target_node_ref.first_filtered_dial_info_detail(Some(RoutingDomain::LocalNetwork));
|
||||
if let Some(target_local_did) = opt_target_local_did {
|
||||
return Ok(ContactMethod::Direct(target_local_did.dial_info));
|
||||
return ContactMethod::Direct(target_local_did.dial_info);
|
||||
}
|
||||
|
||||
// Get the best match internet dial info if we have it
|
||||
@ -744,7 +745,7 @@ impl NetworkManager {
|
||||
// Do we need to signal before going inbound?
|
||||
if !target_public_did.class.requires_signal() {
|
||||
// Go direct without signaling
|
||||
return Ok(ContactMethod::Direct(target_public_did.dial_info));
|
||||
return ContactMethod::Direct(target_public_did.dial_info);
|
||||
}
|
||||
|
||||
// Get the target's inbound relay, it must have one or it is not reachable
|
||||
@ -767,10 +768,10 @@ impl NetworkManager {
|
||||
) {
|
||||
// Can we receive a direct reverse connection?
|
||||
if !reverse_did.class.requires_signal() {
|
||||
return Ok(ContactMethod::SignalReverse(
|
||||
return ContactMethod::SignalReverse(
|
||||
inbound_relay_nr,
|
||||
target_node_ref,
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -798,16 +799,16 @@ impl NetworkManager {
|
||||
)
|
||||
.is_some();
|
||||
if target_has_udp_dialinfo && self_has_udp_dialinfo {
|
||||
return Ok(ContactMethod::SignalHolePunch(
|
||||
return ContactMethod::SignalHolePunch(
|
||||
inbound_relay_nr,
|
||||
udp_target_nr,
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
// Otherwise we have to inbound relay
|
||||
}
|
||||
|
||||
return Ok(ContactMethod::InboundRelay(inbound_relay_nr));
|
||||
return ContactMethod::InboundRelay(inbound_relay_nr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -818,22 +819,17 @@ impl NetworkManager {
|
||||
.first_filtered_dial_info_detail(Some(RoutingDomain::PublicInternet))
|
||||
.is_some()
|
||||
{
|
||||
return Ok(ContactMethod::InboundRelay(target_inbound_relay_nr));
|
||||
return ContactMethod::InboundRelay(target_inbound_relay_nr);
|
||||
}
|
||||
}
|
||||
|
||||
// If we can't reach the node by other means, try our outbound relay if we have one
|
||||
if let Some(relay_node) = self.relay_node() {
|
||||
return Ok(ContactMethod::OutboundRelay(relay_node));
|
||||
return ContactMethod::OutboundRelay(relay_node);
|
||||
}
|
||||
// Otherwise, we can't reach this node
|
||||
debug!("unable to reach node {:?}", target_node_ref);
|
||||
// trace!(
|
||||
// "unable to reach node {:?}: {}",
|
||||
// target_node_ref,
|
||||
// target_node_ref.operate(|e| format!("{:#?}", e))
|
||||
// );
|
||||
Ok(ContactMethod::Unreachable)
|
||||
ContactMethod::Unreachable
|
||||
}
|
||||
|
||||
// Send a reverse connection signal and wait for the return receipt over it
|
||||
@ -844,13 +840,11 @@ impl NetworkManager {
|
||||
relay_nr: NodeRef,
|
||||
target_nr: NodeRef,
|
||||
data: Vec<u8>,
|
||||
) -> Result<(), String> {
|
||||
) -> EyreResult<()> {
|
||||
// Build a return receipt for the signal
|
||||
let receipt_timeout =
|
||||
ms_to_us(self.config.get().network.reverse_connection_receipt_time_ms);
|
||||
let (receipt, eventual_value) = self
|
||||
.generate_single_shot_receipt(receipt_timeout, [])
|
||||
.map_err(map_to_string)?;
|
||||
let (receipt, eventual_value) = self.generate_single_shot_receipt(receipt_timeout, [])?;
|
||||
|
||||
// Get our peer info
|
||||
let peer_info = self.routing_table().get_own_peer_info();
|
||||
@ -863,32 +857,25 @@ impl NetworkManager {
|
||||
SignalInfo::ReverseConnect { receipt, peer_info },
|
||||
)
|
||||
.await
|
||||
.map_err(logthru_net!("failed to send signal to {:?}", relay_nr))
|
||||
.map_err(map_to_string)?;
|
||||
.wrap_err("failed to send signal")?;
|
||||
// Wait for the return receipt
|
||||
let inbound_nr = match eventual_value.await.take_value().unwrap() {
|
||||
ReceiptEvent::ReturnedOutOfBand => {
|
||||
return Err("reverse connect receipt should be returned in-band".to_owned());
|
||||
bail!("reverse connect receipt should be returned in-band");
|
||||
}
|
||||
ReceiptEvent::ReturnedInBand { inbound_noderef } => inbound_noderef,
|
||||
ReceiptEvent::Expired => {
|
||||
return Err(format!(
|
||||
"reverse connect receipt expired from {:?}",
|
||||
target_nr
|
||||
));
|
||||
bail!("reverse connect receipt expired from {:?}", target_nr);
|
||||
}
|
||||
ReceiptEvent::Cancelled => {
|
||||
return Err(format!(
|
||||
"reverse connect receipt cancelled from {:?}",
|
||||
target_nr
|
||||
));
|
||||
bail!("reverse connect receipt cancelled from {:?}", target_nr);
|
||||
}
|
||||
};
|
||||
|
||||
// We expect the inbound noderef to be the same as the target noderef
|
||||
// if they aren't the same, we should error on this and figure out what then hell is up
|
||||
if target_nr != inbound_nr {
|
||||
error!("unexpected noderef mismatch on reverse connect");
|
||||
bail!("unexpected noderef mismatch on reverse connect");
|
||||
}
|
||||
|
||||
// And now use the existing connection to send over
|
||||
@ -899,10 +886,10 @@ impl NetworkManager {
|
||||
.await?
|
||||
{
|
||||
None => Ok(()),
|
||||
Some(_) => Err("unable to send over reverse connection".to_owned()),
|
||||
Some(_) => bail!("unable to send over reverse connection"),
|
||||
}
|
||||
} else {
|
||||
Err("no reverse connection available".to_owned())
|
||||
bail!("no reverse connection available")
|
||||
}
|
||||
}
|
||||
|
||||
@ -914,7 +901,7 @@ impl NetworkManager {
|
||||
relay_nr: NodeRef,
|
||||
target_nr: NodeRef,
|
||||
data: Vec<u8>,
|
||||
) -> Result<(), String> {
|
||||
) -> EyreResult<()> {
|
||||
// Ensure we are filtered down to UDP (the only hole punch protocol supported today)
|
||||
assert!(target_nr
|
||||
.filter_ref()
|
||||
@ -923,17 +910,14 @@ impl NetworkManager {
|
||||
|
||||
// Build a return receipt for the signal
|
||||
let receipt_timeout = ms_to_us(self.config.get().network.hole_punch_receipt_time_ms);
|
||||
let (receipt, eventual_value) = self
|
||||
.generate_single_shot_receipt(receipt_timeout, [])
|
||||
.map_err(map_to_string)?;
|
||||
|
||||
let (receipt, eventual_value) = self.generate_single_shot_receipt(receipt_timeout, [])?;
|
||||
// Get our peer info
|
||||
let peer_info = self.routing_table().get_own_peer_info();
|
||||
|
||||
// Get the udp direct dialinfo for the hole punch
|
||||
let hole_punch_did = target_nr
|
||||
.first_filtered_dial_info_detail(Some(RoutingDomain::PublicInternet))
|
||||
.ok_or_else(|| "No hole punch capable dialinfo found for node".to_owned())?;
|
||||
.ok_or_else(|| eyre!("No hole punch capable dialinfo found for node"))?;
|
||||
|
||||
// Do our half of the hole punch by sending an empty packet
|
||||
// Both sides will do this and then the receipt will get sent over the punched hole
|
||||
@ -949,30 +933,30 @@ impl NetworkManager {
|
||||
SignalInfo::HolePunch { receipt, peer_info },
|
||||
)
|
||||
.await
|
||||
.map_err(logthru_net!("failed to send signal to {:?}", relay_nr))
|
||||
.map_err(map_to_string)?;
|
||||
.wrap_err("failed to send signal")?;
|
||||
|
||||
// Wait for the return receipt
|
||||
let inbound_nr = match eventual_value.await.take_value().unwrap() {
|
||||
ReceiptEvent::ReturnedOutOfBand => {
|
||||
return Err("hole punch receipt should be returned in-band".to_owned());
|
||||
bail!("hole punch receipt should be returned in-band");
|
||||
}
|
||||
ReceiptEvent::ReturnedInBand { inbound_noderef } => inbound_noderef,
|
||||
ReceiptEvent::Expired => {
|
||||
return Err(format!("hole punch receipt expired from {}", target_nr));
|
||||
bail!("hole punch receipt expired from {}", target_nr);
|
||||
}
|
||||
ReceiptEvent::Cancelled => {
|
||||
return Err(format!("hole punch receipt cancelled from {}", target_nr));
|
||||
bail!("hole punch receipt cancelled from {}", target_nr);
|
||||
}
|
||||
};
|
||||
|
||||
// We expect the inbound noderef to be the same as the target noderef
|
||||
// if they aren't the same, we should error on this and figure out what then hell is up
|
||||
if target_nr != inbound_nr {
|
||||
return Err(format!(
|
||||
bail!(
|
||||
"unexpected noderef mismatch on hole punch {}, expected {}",
|
||||
inbound_nr, target_nr
|
||||
));
|
||||
inbound_nr,
|
||||
target_nr
|
||||
);
|
||||
}
|
||||
|
||||
// And now use the existing connection to send over
|
||||
@ -983,10 +967,10 @@ impl NetworkManager {
|
||||
.await?
|
||||
{
|
||||
None => Ok(()),
|
||||
Some(_) => Err("unable to send over hole punch".to_owned()),
|
||||
Some(_) => bail!("unable to send over hole punch"),
|
||||
}
|
||||
} else {
|
||||
Err("no hole punch available".to_owned())
|
||||
bail!("no hole punch available")
|
||||
}
|
||||
}
|
||||
|
||||
@ -1003,7 +987,7 @@ impl NetworkManager {
|
||||
&self,
|
||||
node_ref: NodeRef,
|
||||
data: Vec<u8>,
|
||||
) -> SystemPinBoxFuture<Result<SendDataKind, String>> {
|
||||
) -> SystemPinBoxFuture<EyreResult<SendDataKind>> {
|
||||
let this = self.clone();
|
||||
Box::pin(async move {
|
||||
// First try to send data to the last socket we've seen this peer on
|
||||
@ -1028,11 +1012,7 @@ impl NetworkManager {
|
||||
|
||||
log_net!("send_data via dialinfo to {:?}", node_ref);
|
||||
// If we don't have last_connection, try to reach out to the peer via its dial info
|
||||
match this
|
||||
.get_contact_method(node_ref.clone())
|
||||
.map_err(logthru_net!(debug))
|
||||
.map(logthru_net!("get_contact_method for {:?}", node_ref))?
|
||||
{
|
||||
match this.get_contact_method(node_ref.clone()) {
|
||||
ContactMethod::OutboundRelay(relay_nr) | ContactMethod::InboundRelay(relay_nr) => {
|
||||
this.send_data(relay_nr, data)
|
||||
.await
|
||||
@ -1057,14 +1037,13 @@ impl NetworkManager {
|
||||
.do_hole_punch(relay_nr, target_node_ref, data)
|
||||
.await
|
||||
.map(|_| SendDataKind::GlobalDirect),
|
||||
ContactMethod::Unreachable => Err("Can't send to this node".to_owned()),
|
||||
ContactMethod::Unreachable => Err(eyre!("Can't send to this node")),
|
||||
}
|
||||
.map_err(logthru_net!(debug))
|
||||
})
|
||||
}
|
||||
|
||||
// Direct bootstrap request handler (separate fallback mechanism from cheaper TXT bootstrap mechanism)
|
||||
async fn handle_boot_request(&self, descriptor: ConnectionDescriptor) -> Result<(), String> {
|
||||
async fn handle_boot_request(&self, descriptor: ConnectionDescriptor) -> EyreResult<()> {
|
||||
let routing_table = self.routing_table();
|
||||
|
||||
// Get a bunch of nodes with the various
|
||||
@ -1087,12 +1066,13 @@ impl NetworkManager {
|
||||
// Bootstrap reply was sent
|
||||
Ok(())
|
||||
}
|
||||
Some(_) => Err("bootstrap reply could not be sent".to_owned()),
|
||||
Some(_) => Err(eyre!("bootstrap reply could not be sent")),
|
||||
}
|
||||
}
|
||||
|
||||
// Direct bootstrap request
|
||||
pub async fn boot_request(&self, dial_info: DialInfo) -> Result<Vec<PeerInfo>, String> {
|
||||
#[instrument(level = "trace", err, skip(self))]
|
||||
pub async fn boot_request(&self, dial_info: DialInfo) -> EyreResult<Vec<PeerInfo>> {
|
||||
let timeout_ms = {
|
||||
let c = self.config.get();
|
||||
c.network.rpc.timeout_ms
|
||||
@ -1105,8 +1085,8 @@ impl NetworkManager {
|
||||
.await?;
|
||||
|
||||
let bootstrap_peerinfo: Vec<PeerInfo> =
|
||||
deserialize_json(std::str::from_utf8(&out_data).map_err(map_to_string)?)
|
||||
.map_err(map_to_string)?;
|
||||
deserialize_json(std::str::from_utf8(&out_data).wrap_err("bad utf8 in boot peerinfo")?)
|
||||
.wrap_err("failed to deserialize boot peerinfo")?;
|
||||
|
||||
Ok(bootstrap_peerinfo)
|
||||
}
|
||||
@ -1119,7 +1099,7 @@ impl NetworkManager {
|
||||
&self,
|
||||
data: &[u8],
|
||||
descriptor: ConnectionDescriptor,
|
||||
) -> Result<bool, String> {
|
||||
) -> EyreResult<bool> {
|
||||
log_net!(
|
||||
"envelope of {} bytes received from {:?}",
|
||||
data.len(),
|
||||
@ -1138,7 +1118,7 @@ impl NetworkManager {
|
||||
|
||||
// Ensure we can read the magic number
|
||||
if data.len() < 4 {
|
||||
return Err("short packet".to_owned());
|
||||
bail!("short packet");
|
||||
}
|
||||
|
||||
// Is this a direct bootstrap request instead of an envelope?
|
||||
@ -1154,13 +1134,7 @@ impl NetworkManager {
|
||||
}
|
||||
|
||||
// Decode envelope header (may fail signature validation)
|
||||
let envelope = Envelope::from_signed_data(data).map_err(|_| {
|
||||
format!(
|
||||
"envelope failed to decode from {:?}: {} bytes",
|
||||
descriptor,
|
||||
data.len()
|
||||
)
|
||||
})?;
|
||||
let envelope = Envelope::from_signed_data(data).wrap_err("envelope failed to decode")?;
|
||||
|
||||
// Get routing table and rpc processor
|
||||
let (routing_table, rpc) = {
|
||||
@ -1185,18 +1159,18 @@ impl NetworkManager {
|
||||
let ets = envelope.get_timestamp();
|
||||
if let Some(tsbehind) = tsbehind {
|
||||
if tsbehind > 0 && (ts > ets && ts - ets > tsbehind) {
|
||||
return Err(format!(
|
||||
bail!(
|
||||
"envelope time was too far in the past: {}ms ",
|
||||
timestamp_to_secs(ts - ets) * 1000f64
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
if let Some(tsahead) = tsahead {
|
||||
if tsahead > 0 && (ts < ets && ets - ts > tsahead) {
|
||||
return Err(format!(
|
||||
bail!(
|
||||
"envelope time was too far in the future: {}ms",
|
||||
timestamp_to_secs(ets - ts) * 1000f64
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1211,12 +1185,9 @@ impl NetworkManager {
|
||||
|
||||
let relay_nr = if self.check_client_whitelist(sender_id) {
|
||||
// Full relay allowed, do a full resolve_node
|
||||
rpc.resolve_node(recipient_id).await.map_err(|e| {
|
||||
format!(
|
||||
"failed to resolve recipient node for relay, dropping outbound relayed packet...: {:?}",
|
||||
e
|
||||
)
|
||||
})?
|
||||
rpc.resolve_node(recipient_id).await.wrap_err(
|
||||
"failed to resolve recipient node for relay, dropping outbound relayed packet",
|
||||
)?
|
||||
} else {
|
||||
// If this is not a node in the client whitelist, only allow inbound relay
|
||||
// which only performs a lightweight lookup before passing the packet back out
|
||||
@ -1226,7 +1197,7 @@ impl NetworkManager {
|
||||
// should be mutually in each others routing tables. The node needing the relay will be
|
||||
// pinging this node regularly to keep itself in the routing table
|
||||
routing_table.lookup_node_ref(recipient_id).ok_or_else(|| {
|
||||
format!(
|
||||
eyre!(
|
||||
"Inbound relay asked for recipient not in routing table: sender_id={:?} recipient={:?}",
|
||||
sender_id, recipient_id
|
||||
)
|
||||
@ -1236,7 +1207,7 @@ impl NetworkManager {
|
||||
// Relay the packet to the desired destination
|
||||
self.send_data(relay_nr, data.to_vec())
|
||||
.await
|
||||
.map_err(|e| format!("failed to forward envelope: {}", e))?;
|
||||
.wrap_err("failed to forward envelope")?;
|
||||
// Inform caller that we dealt with the envelope, but did not process it locally
|
||||
return Ok(false);
|
||||
}
|
||||
@ -1248,19 +1219,20 @@ impl NetworkManager {
|
||||
// xxx: punish nodes that send messages that fail to decrypt eventually
|
||||
let body = envelope
|
||||
.decrypt_body(self.crypto(), data, &node_id_secret)
|
||||
.map_err(|_| "failed to decrypt envelope body".to_owned())?;
|
||||
.wrap_err("failed to decrypt envelope body")?;
|
||||
|
||||
// Cache the envelope information in the routing table
|
||||
let source_noderef = routing_table
|
||||
.register_node_with_existing_connection(envelope.get_sender_id(), descriptor, ts)
|
||||
.map_err(|e| format!("node id registration failed: {}", e))?;
|
||||
let source_noderef = routing_table.register_node_with_existing_connection(
|
||||
envelope.get_sender_id(),
|
||||
descriptor,
|
||||
ts,
|
||||
)?;
|
||||
source_noderef.operate_mut(|e| e.set_min_max_version(envelope.get_min_max_version()));
|
||||
|
||||
// xxx: deal with spoofing and flooding here?
|
||||
|
||||
// Pass message to RPC system
|
||||
rpc.enqueue_message(envelope, body, source_noderef)
|
||||
.map_err(|e| format!("enqueing rpc message failed: {}", e))?;
|
||||
rpc.enqueue_message(envelope, body, source_noderef)?;
|
||||
|
||||
// Inform caller that we dealt with the envelope locally
|
||||
Ok(true)
|
||||
@ -1273,7 +1245,7 @@ impl NetworkManager {
|
||||
stop_token: StopToken,
|
||||
_last_ts: u64,
|
||||
cur_ts: u64,
|
||||
) -> Result<(), String> {
|
||||
) -> EyreResult<()> {
|
||||
// Get our node's current node info and network class and do the right thing
|
||||
let routing_table = self.routing_table();
|
||||
let node_info = routing_table.get_own_node_info();
|
||||
@ -1354,7 +1326,7 @@ impl NetworkManager {
|
||||
stop_token: StopToken,
|
||||
last_ts: u64,
|
||||
cur_ts: u64,
|
||||
) -> Result<(), String> {
|
||||
) -> EyreResult<()> {
|
||||
// log_net!("--- network manager rolling_transfers task");
|
||||
{
|
||||
let inner = &mut *self.inner.lock();
|
||||
|
@ -61,7 +61,7 @@ struct NetworkUnlockedInner {
|
||||
network_manager: NetworkManager,
|
||||
connection_manager: ConnectionManager,
|
||||
// Background processes
|
||||
update_network_class_task: TickTask,
|
||||
update_network_class_task: TickTask<EyreReport>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -266,7 +266,7 @@ impl Network {
|
||||
// See if our interface addresses have changed, if so we need to punt the network
|
||||
// and redo all our addresses. This is overkill, but anything more accurate
|
||||
// would require inspection of routing tables that we dont want to bother with
|
||||
pub async fn check_interface_addresses(&self) -> Result<bool, String> {
|
||||
pub async fn check_interface_addresses(&self) -> EyreResult<bool> {
|
||||
let mut inner = self.inner.lock();
|
||||
if !inner.interfaces.refresh().await? {
|
||||
return Ok(false);
|
||||
@ -286,7 +286,7 @@ impl Network {
|
||||
&self,
|
||||
dial_info: DialInfo,
|
||||
data: Vec<u8>,
|
||||
) -> Result<(), String> {
|
||||
) -> EyreResult<()> {
|
||||
let data_len = data.len();
|
||||
let res = match dial_info.protocol_type() {
|
||||
ProtocolType::UDP => {
|
||||
@ -300,7 +300,8 @@ impl Network {
|
||||
ProtocolType::WS | ProtocolType::WSS => {
|
||||
WebsocketProtocolHandler::send_unbound_message(dial_info.clone(), data).await
|
||||
}
|
||||
};
|
||||
}
|
||||
.wrap_err("low level network error");
|
||||
if res.is_ok() {
|
||||
// Network accounting
|
||||
self.network_manager()
|
||||
@ -320,7 +321,7 @@ impl Network {
|
||||
dial_info: DialInfo,
|
||||
data: Vec<u8>,
|
||||
timeout_ms: u32,
|
||||
) -> Result<Vec<u8>, String> {
|
||||
) -> EyreResult<Vec<u8>> {
|
||||
let data_len = data.len();
|
||||
let out = match dial_info.protocol_type() {
|
||||
ProtocolType::UDP => {
|
||||
@ -358,7 +359,7 @@ impl Network {
|
||||
&self,
|
||||
descriptor: ConnectionDescriptor,
|
||||
data: Vec<u8>,
|
||||
) -> Result<Option<Vec<u8>>, String> {
|
||||
) -> EyreResult<Option<Vec<u8>>> {
|
||||
let data_len = data.len();
|
||||
|
||||
// Handle connectionless protocol
|
||||
@ -369,12 +370,10 @@ impl Network {
|
||||
&peer_socket_addr,
|
||||
&descriptor.local().map(|sa| sa.to_socket_addr()),
|
||||
) {
|
||||
log_net!(
|
||||
"send_data_to_existing_connection connectionless to {:?}",
|
||||
descriptor
|
||||
);
|
||||
|
||||
ph.clone().send_message(data, peer_socket_addr).await?;
|
||||
ph.clone()
|
||||
.send_message(data, peer_socket_addr)
|
||||
.await
|
||||
.wrap_err("sending data to existing conection")?;
|
||||
|
||||
// Network accounting
|
||||
self.network_manager()
|
||||
@ -389,10 +388,10 @@ impl Network {
|
||||
|
||||
// Try to send to the exact existing connection if one exists
|
||||
if let Some(conn) = self.connection_manager().get_connection(descriptor).await {
|
||||
log_net!("send_data_to_existing_connection to {:?}", descriptor);
|
||||
|
||||
// connection exists, send over it
|
||||
conn.send_async(data).await?;
|
||||
conn.send_async(data)
|
||||
.await
|
||||
.wrap_err("sending data to existing connection")?;
|
||||
|
||||
// Network accounting
|
||||
self.network_manager()
|
||||
@ -413,13 +412,16 @@ impl Network {
|
||||
&self,
|
||||
dial_info: DialInfo,
|
||||
data: Vec<u8>,
|
||||
) -> Result<(), String> {
|
||||
) -> EyreResult<()> {
|
||||
let data_len = data.len();
|
||||
// Handle connectionless protocol
|
||||
if dial_info.protocol_type() == ProtocolType::UDP {
|
||||
let peer_socket_addr = dial_info.to_socket_addr();
|
||||
if let Some(ph) = self.find_best_udp_protocol_handler(&peer_socket_addr, &None) {
|
||||
let res = ph.send_message(data, peer_socket_addr).await;
|
||||
let res = ph
|
||||
.send_message(data, peer_socket_addr)
|
||||
.await
|
||||
.wrap_err("failed to send data to dial info");
|
||||
if res.is_ok() {
|
||||
// Network accounting
|
||||
self.network_manager()
|
||||
@ -427,7 +429,7 @@ impl Network {
|
||||
}
|
||||
return res;
|
||||
}
|
||||
return Err("no appropriate UDP protocol handler for dial_info".to_owned());
|
||||
bail!("no appropriate UDP protocol handler for dial_info");
|
||||
}
|
||||
|
||||
// Handle connection-oriented protocols
|
||||
@ -453,7 +455,7 @@ impl Network {
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", err, skip_all)]
|
||||
pub async fn startup(&self) -> Result<(), String> {
|
||||
pub async fn startup(&self) -> EyreResult<()> {
|
||||
// initialize interfaces
|
||||
let mut interfaces = NetworkInterfaces::new();
|
||||
interfaces.refresh().await?;
|
||||
@ -604,7 +606,7 @@ impl Network {
|
||||
|
||||
//////////////////////////////////////////
|
||||
|
||||
pub async fn tick(&self) -> Result<(), String> {
|
||||
pub async fn tick(&self) -> EyreResult<()> {
|
||||
let network_class = self.get_network_class().unwrap_or(NetworkClass::Invalid);
|
||||
let routing_table = self.routing_table();
|
||||
|
||||
|
@ -250,7 +250,7 @@ impl DiscoveryContext {
|
||||
|
||||
// If we know we are not behind NAT, check our firewall status
|
||||
#[instrument(level = "trace", skip(self), err)]
|
||||
pub async fn protocol_process_no_nat(&self) -> Result<(), String> {
|
||||
pub async fn protocol_process_no_nat(&self) -> EyreResult<()> {
|
||||
let (node_1, external_1_dial_info) = {
|
||||
let inner = self.inner.lock();
|
||||
(
|
||||
@ -281,7 +281,7 @@ impl DiscoveryContext {
|
||||
|
||||
// If we know we are behind NAT check what kind
|
||||
#[instrument(level = "trace", skip(self), ret, err)]
|
||||
pub async fn protocol_process_nat(&self) -> Result<bool, String> {
|
||||
pub async fn protocol_process_nat(&self) -> EyreResult<bool> {
|
||||
let (node_1, external_1_dial_info, external_1_address, protocol_type, address_type) = {
|
||||
let inner = self.inner.lock();
|
||||
(
|
||||
@ -375,7 +375,7 @@ impl Network {
|
||||
&self,
|
||||
context: &DiscoveryContext,
|
||||
protocol_type: ProtocolType,
|
||||
) -> Result<(), String> {
|
||||
) -> EyreResult<()> {
|
||||
let mut retry_count = {
|
||||
let c = self.config.get();
|
||||
c.network.restricted_nat_retries
|
||||
@ -437,7 +437,7 @@ impl Network {
|
||||
&self,
|
||||
context: &DiscoveryContext,
|
||||
protocol_type: ProtocolType,
|
||||
) -> Result<(), String> {
|
||||
) -> EyreResult<()> {
|
||||
// Start doing ipv6 protocol
|
||||
context.protocol_begin(protocol_type, AddressType::IPV6);
|
||||
|
||||
@ -479,7 +479,7 @@ impl Network {
|
||||
stop_token: StopToken,
|
||||
_l: u64,
|
||||
_t: u64,
|
||||
) -> Result<(), String> {
|
||||
) -> EyreResult<()> {
|
||||
// Ensure we aren't trying to update this without clearing it first
|
||||
let old_network_class = self.inner.lock().network_class;
|
||||
assert_eq!(old_network_class, None);
|
||||
|
@ -25,14 +25,14 @@ impl ListenerState {
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
impl Network {
|
||||
fn get_or_create_tls_acceptor(&self) -> Result<TlsAcceptor, String> {
|
||||
fn get_or_create_tls_acceptor(&self) -> EyreResult<TlsAcceptor> {
|
||||
if let Some(ts) = self.inner.lock().tls_acceptor.as_ref() {
|
||||
return Ok(ts.clone());
|
||||
}
|
||||
|
||||
let server_config = self
|
||||
.load_server_config()
|
||||
.map_err(|e| format!("Couldn't create TLS configuration: {}", e))?;
|
||||
.wrap_err("Couldn't create TLS configuration")?;
|
||||
let acceptor = TlsAcceptor::from(Arc::new(server_config));
|
||||
self.inner.lock().tls_acceptor = Some(acceptor.clone());
|
||||
Ok(acceptor)
|
||||
@ -45,12 +45,11 @@ impl Network {
|
||||
addr: SocketAddr,
|
||||
protocol_handlers: &[Box<dyn ProtocolAcceptHandler>],
|
||||
tls_connection_initial_timeout_ms: u32,
|
||||
) -> Result<Option<ProtocolNetworkConnection>, String> {
|
||||
) -> EyreResult<Option<ProtocolNetworkConnection>> {
|
||||
let tls_stream = tls_acceptor
|
||||
.accept(stream)
|
||||
.await
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!(debug "TLS stream failed handshake"))?;
|
||||
.wrap_err("TLS stream failed handshake")?;
|
||||
let ps = AsyncPeekStream::new(tls_stream);
|
||||
let mut first_packet = [0u8; PEEK_DETECT_LEN];
|
||||
|
||||
@ -63,8 +62,8 @@ impl Network {
|
||||
ps.peek_exact(&mut first_packet),
|
||||
)
|
||||
.await
|
||||
.map_err(map_to_string)?
|
||||
.map_err(map_to_string)?;
|
||||
.wrap_err("tls initial timeout")?
|
||||
.wrap_err("failed to peek tls stream")?;
|
||||
|
||||
self.try_handlers(ps, addr, protocol_handlers).await
|
||||
}
|
||||
@ -74,9 +73,13 @@ impl Network {
|
||||
stream: AsyncPeekStream,
|
||||
addr: SocketAddr,
|
||||
protocol_accept_handlers: &[Box<dyn ProtocolAcceptHandler>],
|
||||
) -> Result<Option<ProtocolNetworkConnection>, String> {
|
||||
) -> EyreResult<Option<ProtocolNetworkConnection>> {
|
||||
for ah in protocol_accept_handlers.iter() {
|
||||
if let Some(nc) = ah.on_accept(stream.clone(), addr).await? {
|
||||
if let Some(nc) = ah
|
||||
.on_accept(stream.clone(), addr)
|
||||
.await
|
||||
.wrap_err("io error")?
|
||||
{
|
||||
return Ok(Some(nc));
|
||||
}
|
||||
}
|
||||
@ -114,7 +117,7 @@ impl Network {
|
||||
return;
|
||||
}
|
||||
};
|
||||
// XXX limiting
|
||||
// XXX limiting here instead for connection table? may be faster and avoids tls negotiation
|
||||
|
||||
log_net!("TCP connection from: {}", addr);
|
||||
|
||||
@ -185,7 +188,7 @@ impl Network {
|
||||
}
|
||||
}
|
||||
|
||||
async fn spawn_socket_listener(&self, addr: SocketAddr) -> Result<(), String> {
|
||||
async fn spawn_socket_listener(&self, addr: SocketAddr) -> EyreResult<()> {
|
||||
// Get config
|
||||
let (connection_initial_timeout_ms, tls_connection_initial_timeout_ms) = {
|
||||
let c = self.config.get();
|
||||
@ -196,11 +199,12 @@ impl Network {
|
||||
};
|
||||
|
||||
// Create a reusable socket with no linger time, and no delay
|
||||
let socket = new_bound_shared_tcp_socket(addr)?;
|
||||
let socket = new_bound_shared_tcp_socket(addr)
|
||||
.wrap_err("failed to create bound shared tcp socket")?;
|
||||
// Listen on the socket
|
||||
socket
|
||||
.listen(128)
|
||||
.map_err(|e| format!("Couldn't listen on TCP socket: {}", e))?;
|
||||
.wrap_err("Couldn't listen on TCP socket")?;
|
||||
|
||||
// Make an async tcplistener from the socket2 socket
|
||||
let std_listener: std::net::TcpListener = socket.into();
|
||||
@ -209,7 +213,7 @@ impl Network {
|
||||
let listener = TcpListener::from(std_listener);
|
||||
} else if #[cfg(feature="rt-tokio")] {
|
||||
std_listener.set_nonblocking(true).expect("failed to set nonblocking");
|
||||
let listener = TcpListener::from_std(std_listener).map_err(map_to_string)?;
|
||||
let listener = TcpListener::from_std(std_listener).wrap_err("failed to create tokio tcp listener")?;
|
||||
}
|
||||
}
|
||||
|
||||
@ -279,7 +283,7 @@ impl Network {
|
||||
port: u16,
|
||||
is_tls: bool,
|
||||
new_protocol_accept_handler: Box<NewProtocolAcceptHandler>,
|
||||
) -> Result<Vec<SocketAddress>, String> {
|
||||
) -> EyreResult<Vec<SocketAddress>> {
|
||||
let mut out = Vec::<SocketAddress>::new();
|
||||
|
||||
for ip_addr in ip_addrs {
|
||||
|
@ -3,7 +3,7 @@ use sockets::*;
|
||||
use stop_token::future::FutureExt;
|
||||
|
||||
impl Network {
|
||||
pub(super) async fn create_udp_listener_tasks(&self) -> Result<(), String> {
|
||||
pub(super) async fn create_udp_listener_tasks(&self) -> EyreResult<()> {
|
||||
// Spawn socket tasks
|
||||
let mut task_count = {
|
||||
let c = self.config.get();
|
||||
@ -73,7 +73,7 @@ impl Network {
|
||||
.on_recv_envelope(&data[..size], descriptor)
|
||||
.await
|
||||
{
|
||||
log_net!(error "failed to process received udp envelope: {}", e);
|
||||
log_net!(debug "failed to process received udp envelope: {}", e);
|
||||
}
|
||||
}
|
||||
Ok(Err(_)) => {
|
||||
@ -110,7 +110,7 @@ impl Network {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) async fn create_udp_outbound_sockets(&self) -> Result<(), String> {
|
||||
pub(super) async fn create_udp_outbound_sockets(&self) -> EyreResult<()> {
|
||||
let mut inner = self.inner.lock();
|
||||
let mut port = inner.udp_port;
|
||||
// v4
|
||||
@ -119,9 +119,9 @@ impl Network {
|
||||
// Pull the port if we randomly bound, so v6 can be on the same port
|
||||
port = socket
|
||||
.local_addr()
|
||||
.map_err(map_to_string)?
|
||||
.wrap_err("failed to get local address")?
|
||||
.as_socket_ipv4()
|
||||
.ok_or_else(|| "expected ipv4 address type".to_owned())?
|
||||
.ok_or_else(|| eyre!("expected ipv4 address type"))?
|
||||
.port();
|
||||
|
||||
// Make an async UdpSocket from the socket2 socket
|
||||
@ -131,7 +131,7 @@ impl Network {
|
||||
let udp_socket = UdpSocket::from(std_udp_socket);
|
||||
} else if #[cfg(feature="rt-tokio")] {
|
||||
std_udp_socket.set_nonblocking(true).expect("failed to set nonblocking");
|
||||
let udp_socket = UdpSocket::from_std(std_udp_socket).map_err(map_to_string)?;
|
||||
let udp_socket = UdpSocket::from_std(std_udp_socket).wrap_err("failed to make outbound v4 tokio udpsocket")?;
|
||||
}
|
||||
}
|
||||
let socket_arc = Arc::new(udp_socket);
|
||||
@ -152,7 +152,7 @@ impl Network {
|
||||
let udp_socket = UdpSocket::from(std_udp_socket);
|
||||
} else if #[cfg(feature="rt-tokio")] {
|
||||
std_udp_socket.set_nonblocking(true).expect("failed to set nonblocking");
|
||||
let udp_socket = UdpSocket::from_std(std_udp_socket).map_err(map_to_string)?;
|
||||
let udp_socket = UdpSocket::from_std(std_udp_socket).wrap_err("failed to make outbound v6 tokio udpsocket")?;
|
||||
}
|
||||
}
|
||||
let socket_arc = Arc::new(udp_socket);
|
||||
@ -166,7 +166,7 @@ impl Network {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn create_udp_inbound_socket(&self, addr: SocketAddr) -> Result<(), String> {
|
||||
async fn create_udp_inbound_socket(&self, addr: SocketAddr) -> EyreResult<()> {
|
||||
log_net!("create_udp_inbound_socket on {:?}", &addr);
|
||||
|
||||
// Create a reusable socket
|
||||
@ -179,7 +179,7 @@ impl Network {
|
||||
let udp_socket = UdpSocket::from(std_udp_socket);
|
||||
} else if #[cfg(feature="rt-tokio")] {
|
||||
std_udp_socket.set_nonblocking(true).expect("failed to set nonblocking");
|
||||
let udp_socket = UdpSocket::from_std(std_udp_socket).map_err(map_to_string)?;
|
||||
let udp_socket = UdpSocket::from_std(std_udp_socket).wrap_err("failed to make inbound tokio udpsocket")?;
|
||||
}
|
||||
}
|
||||
let socket_arc = Arc::new(udp_socket);
|
||||
@ -200,7 +200,7 @@ impl Network {
|
||||
&self,
|
||||
ip_addrs: Vec<IpAddr>,
|
||||
port: u16,
|
||||
) -> Result<Vec<DialInfo>, String> {
|
||||
) -> EyreResult<Vec<DialInfo>> {
|
||||
let mut out = Vec::<DialInfo>::new();
|
||||
|
||||
for ip_addr in ip_addrs {
|
||||
|
@ -6,6 +6,7 @@ pub mod ws;
|
||||
|
||||
use super::*;
|
||||
use crate::xx::*;
|
||||
use std::io;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ProtocolNetworkConnection {
|
||||
@ -21,7 +22,7 @@ impl ProtocolNetworkConnection {
|
||||
pub async fn connect(
|
||||
local_address: Option<SocketAddr>,
|
||||
dial_info: DialInfo,
|
||||
) -> Result<ProtocolNetworkConnection, String> {
|
||||
) -> io::Result<ProtocolNetworkConnection> {
|
||||
match dial_info.protocol_type() {
|
||||
ProtocolType::UDP => {
|
||||
panic!("Should not connect to UDP dialinfo");
|
||||
@ -35,7 +36,7 @@ impl ProtocolNetworkConnection {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn send_unbound_message(dial_info: DialInfo, data: Vec<u8>) -> Result<(), String> {
|
||||
pub async fn send_unbound_message(dial_info: DialInfo, data: Vec<u8>) -> io::Result<()> {
|
||||
match dial_info.protocol_type() {
|
||||
ProtocolType::UDP => {
|
||||
let peer_socket_addr = dial_info.to_socket_addr();
|
||||
@ -55,7 +56,7 @@ impl ProtocolNetworkConnection {
|
||||
dial_info: DialInfo,
|
||||
data: Vec<u8>,
|
||||
timeout_ms: u32,
|
||||
) -> Result<Vec<u8>, String> {
|
||||
) -> io::Result<Vec<u8>> {
|
||||
match dial_info.protocol_type() {
|
||||
ProtocolType::UDP => {
|
||||
let peer_socket_addr = dial_info.to_socket_addr();
|
||||
@ -102,7 +103,7 @@ impl ProtocolNetworkConnection {
|
||||
// }
|
||||
// }
|
||||
|
||||
pub async fn send(&self, message: Vec<u8>) -> Result<(), String> {
|
||||
pub async fn send(&self, message: Vec<u8>) -> io::Result<()> {
|
||||
match self {
|
||||
Self::Dummy(d) => d.send(message),
|
||||
Self::RawTcp(t) => t.send(message).await,
|
||||
@ -111,7 +112,7 @@ impl ProtocolNetworkConnection {
|
||||
Self::Wss(w) => w.send(message).await,
|
||||
}
|
||||
}
|
||||
pub async fn recv(&self) -> Result<Vec<u8>, String> {
|
||||
pub async fn recv(&self) -> io::Result<Vec<u8>> {
|
||||
match self {
|
||||
Self::Dummy(d) => d.recv(),
|
||||
Self::RawTcp(t) => t.recv().await,
|
||||
|
@ -1,6 +1,8 @@
|
||||
use crate::xx::*;
|
||||
use crate::*;
|
||||
use async_io::Async;
|
||||
use std::io;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature="rt-async-std")] {
|
||||
pub use async_std::net::{TcpStream, TcpListener, Shutdown, UdpSocket};
|
||||
@ -19,12 +21,12 @@ cfg_if! {
|
||||
use winapi::ctypes::c_int;
|
||||
use std::os::windows::io::AsRawSocket;
|
||||
|
||||
fn set_exclusiveaddruse(socket: &Socket) -> Result<(), String> {
|
||||
fn set_exclusiveaddruse(socket: &Socket) -> io::Result<()> {
|
||||
unsafe {
|
||||
let optval:c_int = 1;
|
||||
if setsockopt(socket.as_raw_socket().try_into().unwrap(), SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (&optval as *const c_int).cast(),
|
||||
std::mem::size_of::<c_int>() as c_int) == SOCKET_ERROR {
|
||||
return Err("Unable to SO_EXCLUSIVEADDRUSE".to_owned());
|
||||
return Err(io::Error::last_os_error());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -32,49 +34,37 @@ cfg_if! {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_unbound_shared_udp_socket(domain: Domain) -> Result<Socket, String> {
|
||||
let socket = Socket::new(domain, Type::DGRAM, Some(Protocol::UDP))
|
||||
.map_err(|e| format!("Couldn't create UDP socket: {}", e))?;
|
||||
pub fn new_unbound_shared_udp_socket(domain: Domain) -> io::Result<Socket> {
|
||||
let socket = Socket::new(domain, Type::DGRAM, Some(Protocol::UDP))?;
|
||||
if domain == Domain::IPV6 {
|
||||
socket
|
||||
.set_only_v6(true)
|
||||
.map_err(|e| format!("Couldn't set IPV6_V6ONLY: {}", e))?;
|
||||
socket.set_only_v6(true)?;
|
||||
}
|
||||
socket
|
||||
.set_reuse_address(true)
|
||||
.map_err(|e| format!("Couldn't set reuse address: {}", e))?;
|
||||
socket.set_reuse_address(true)?;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(unix)] {
|
||||
socket.set_reuse_port(true).map_err(|e| format!("Couldn't set reuse port: {}", e))?;
|
||||
socket.set_reuse_port(true)?;
|
||||
}
|
||||
}
|
||||
Ok(socket)
|
||||
}
|
||||
|
||||
pub fn new_bound_shared_udp_socket(local_address: SocketAddr) -> Result<Socket, String> {
|
||||
pub fn new_bound_shared_udp_socket(local_address: SocketAddr) -> io::Result<Socket> {
|
||||
let domain = Domain::for_address(local_address);
|
||||
let socket = new_unbound_shared_udp_socket(domain)?;
|
||||
let socket2_addr = SockAddr::from(local_address);
|
||||
socket.bind(&socket2_addr).map_err(|e| {
|
||||
format!(
|
||||
"failed to bind UDP socket to '{}' in domain '{:?}': {} ",
|
||||
local_address, domain, e
|
||||
)
|
||||
})?;
|
||||
socket.bind(&socket2_addr)?;
|
||||
|
||||
log_net!("created bound shared udp socket on {:?}", &local_address);
|
||||
|
||||
Ok(socket)
|
||||
}
|
||||
|
||||
pub fn new_bound_first_udp_socket(local_address: SocketAddr) -> Result<Socket, String> {
|
||||
pub fn new_bound_first_udp_socket(local_address: SocketAddr) -> io::Result<Socket> {
|
||||
let domain = Domain::for_address(local_address);
|
||||
let socket = Socket::new(domain, Type::DGRAM, Some(Protocol::UDP))
|
||||
.map_err(|e| format!("Couldn't create UDP socket: {}", e))?;
|
||||
let socket = Socket::new(domain, Type::DGRAM, Some(Protocol::UDP))?;
|
||||
if domain == Domain::IPV6 {
|
||||
socket
|
||||
.set_only_v6(true)
|
||||
.map_err(|e| format!("Couldn't set IPV6_V6ONLY: {}", e))?;
|
||||
socket.set_only_v6(true)?;
|
||||
}
|
||||
// Bind the socket -first- before turning on 'reuse address' this way it will
|
||||
// fail if the port is already taken
|
||||
@ -87,18 +77,15 @@ pub fn new_bound_first_udp_socket(local_address: SocketAddr) -> Result<Socket, S
|
||||
}
|
||||
}
|
||||
|
||||
socket
|
||||
.bind(&socket2_addr)
|
||||
.map_err(|e| format!("failed to bind UDP socket: {}", e))?;
|
||||
socket.bind(&socket2_addr)?;
|
||||
|
||||
// Set 'reuse address' so future binds to this port will succeed
|
||||
// This does not work on Windows, where reuse options can not be set after the bind
|
||||
cfg_if! {
|
||||
if #[cfg(unix)] {
|
||||
socket
|
||||
.set_reuse_address(true)
|
||||
.map_err(|e| format!("Couldn't set reuse address: {}", e))?;
|
||||
socket.set_reuse_port(true).map_err(|e| format!("Couldn't set reuse port: {}", e))?;
|
||||
.set_reuse_address(true)?;
|
||||
socket.set_reuse_port(true)?;
|
||||
}
|
||||
}
|
||||
log_net!("created bound first udp socket on {:?}", &local_address);
|
||||
@ -106,10 +93,8 @@ pub fn new_bound_first_udp_socket(local_address: SocketAddr) -> Result<Socket, S
|
||||
Ok(socket)
|
||||
}
|
||||
|
||||
pub fn new_unbound_shared_tcp_socket(domain: Domain) -> Result<Socket, String> {
|
||||
let socket = Socket::new(domain, Type::STREAM, Some(Protocol::TCP))
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!("failed to create TCP socket"))?;
|
||||
pub fn new_unbound_shared_tcp_socket(domain: Domain) -> io::Result<Socket> {
|
||||
let socket = Socket::new(domain, Type::STREAM, Some(Protocol::TCP))?;
|
||||
if let Err(e) = socket.set_linger(Some(core::time::Duration::from_secs(0))) {
|
||||
log_net!(error "Couldn't set TCP linger: {}", e);
|
||||
}
|
||||
@ -117,43 +102,33 @@ pub fn new_unbound_shared_tcp_socket(domain: Domain) -> Result<Socket, String> {
|
||||
log_net!(error "Couldn't set TCP nodelay: {}", e);
|
||||
}
|
||||
if domain == Domain::IPV6 {
|
||||
socket
|
||||
.set_only_v6(true)
|
||||
.map_err(|e| format!("Couldn't set IPV6_V6ONLY: {}", e))?;
|
||||
socket.set_only_v6(true)?;
|
||||
}
|
||||
socket
|
||||
.set_reuse_address(true)
|
||||
.map_err(|e| format!("Couldn't set reuse address: {}", e))?;
|
||||
socket.set_reuse_address(true)?;
|
||||
cfg_if! {
|
||||
if #[cfg(unix)] {
|
||||
socket.set_reuse_port(true).map_err(|e| format!("Couldn't set reuse port: {}", e))?;
|
||||
socket.set_reuse_port(true)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(socket)
|
||||
}
|
||||
|
||||
pub fn new_bound_shared_tcp_socket(local_address: SocketAddr) -> Result<Socket, String> {
|
||||
pub fn new_bound_shared_tcp_socket(local_address: SocketAddr) -> io::Result<Socket> {
|
||||
let domain = Domain::for_address(local_address);
|
||||
|
||||
let socket = new_unbound_shared_tcp_socket(domain)?;
|
||||
|
||||
let socket2_addr = SockAddr::from(local_address);
|
||||
socket
|
||||
.bind(&socket2_addr)
|
||||
.map_err(|e| format!("failed to bind TCP socket: {}", e))?;
|
||||
socket.bind(&socket2_addr)?;
|
||||
|
||||
log_net!("created bound shared tcp socket on {:?}", &local_address);
|
||||
|
||||
Ok(socket)
|
||||
}
|
||||
|
||||
pub fn new_bound_first_tcp_socket(local_address: SocketAddr) -> Result<Socket, String> {
|
||||
pub fn new_bound_first_tcp_socket(local_address: SocketAddr) -> io::Result<Socket> {
|
||||
let domain = Domain::for_address(local_address);
|
||||
|
||||
let socket = Socket::new(domain, Type::STREAM, Some(Protocol::TCP))
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!("failed to create TCP socket"))?;
|
||||
let socket = Socket::new(domain, Type::STREAM, Some(Protocol::TCP))?;
|
||||
if let Err(e) = socket.set_linger(Some(core::time::Duration::from_secs(0))) {
|
||||
log_net!(error "Couldn't set TCP linger: {}", e);
|
||||
}
|
||||
@ -161,9 +136,7 @@ pub fn new_bound_first_tcp_socket(local_address: SocketAddr) -> Result<Socket, S
|
||||
log_net!(error "Couldn't set TCP nodelay: {}", e);
|
||||
}
|
||||
if domain == Domain::IPV6 {
|
||||
socket
|
||||
.set_only_v6(true)
|
||||
.map_err(|e| format!("Couldn't set IPV6_V6ONLY: {}", e))?;
|
||||
socket.set_only_v6(true)?;
|
||||
}
|
||||
|
||||
// On windows, do SO_EXCLUSIVEADDRUSE before the bind to ensure the port is fully available
|
||||
@ -176,18 +149,15 @@ pub fn new_bound_first_tcp_socket(local_address: SocketAddr) -> Result<Socket, S
|
||||
// Bind the socket -first- before turning on 'reuse address' this way it will
|
||||
// fail if the port is already taken
|
||||
let socket2_addr = SockAddr::from(local_address);
|
||||
socket
|
||||
.bind(&socket2_addr)
|
||||
.map_err(|e| format!("failed to bind TCP socket: {}", e))?;
|
||||
socket.bind(&socket2_addr)?;
|
||||
|
||||
// Set 'reuse address' so future binds to this port will succeed
|
||||
// This does not work on Windows, where reuse options can not be set after the bind
|
||||
cfg_if! {
|
||||
if #[cfg(unix)] {
|
||||
socket
|
||||
.set_reuse_address(true)
|
||||
.map_err(|e| format!("Couldn't set reuse address: {}", e))?;
|
||||
socket.set_reuse_port(true).map_err(|e| format!("Couldn't set reuse port: {}", e))?;
|
||||
.set_reuse_address(true)?;
|
||||
socket.set_reuse_port(true)?;
|
||||
}
|
||||
}
|
||||
log_net!("created bound first tcp socket on {:?}", &local_address);
|
||||
@ -196,7 +166,7 @@ pub fn new_bound_first_tcp_socket(local_address: SocketAddr) -> Result<Socket, S
|
||||
}
|
||||
|
||||
// Non-blocking connect is tricky when you want to start with a prepared socket
|
||||
pub async fn nonblocking_connect(socket: Socket, addr: SocketAddr) -> std::io::Result<TcpStream> {
|
||||
pub async fn nonblocking_connect(socket: Socket, addr: SocketAddr) -> io::Result<TcpStream> {
|
||||
// Set for non blocking connect
|
||||
socket.set_nonblocking(true)?;
|
||||
|
||||
|
@ -42,47 +42,45 @@ impl RawTcpNetworkConnection {
|
||||
// }
|
||||
// }
|
||||
|
||||
async fn send_internal(stream: &mut AsyncPeekStream, message: Vec<u8>) -> Result<(), String> {
|
||||
async fn send_internal(stream: &mut AsyncPeekStream, message: Vec<u8>) -> io::Result<()> {
|
||||
log_net!("sending TCP message of size {}", message.len());
|
||||
if message.len() > MAX_MESSAGE_SIZE {
|
||||
return Err("sending too large TCP message".to_owned());
|
||||
bail_io_error_other!("sending too large TCP message");
|
||||
}
|
||||
let len = message.len() as u16;
|
||||
let header = [b'V', b'L', len as u8, (len >> 8) as u8];
|
||||
|
||||
stream.write_all(&header).await.map_err(map_to_string)?;
|
||||
stream.write_all(&message).await.map_err(map_to_string)
|
||||
stream.write_all(&header).await?;
|
||||
stream.write_all(&message).await
|
||||
}
|
||||
|
||||
#[instrument(level="trace", err, skip(self, message), fields(message.len = message.len()))]
|
||||
pub async fn send(&self, message: Vec<u8>) -> Result<(), String> {
|
||||
pub async fn send(&self, message: Vec<u8>) -> io::Result<()> {
|
||||
let mut stream = self.stream.clone();
|
||||
Self::send_internal(&mut stream, message).await
|
||||
}
|
||||
|
||||
pub async fn recv_internal(stream: &mut AsyncPeekStream) -> Result<Vec<u8>, String> {
|
||||
pub async fn recv_internal(stream: &mut AsyncPeekStream) -> io::Result<Vec<u8>> {
|
||||
let mut header = [0u8; 4];
|
||||
|
||||
stream
|
||||
.read_exact(&mut header)
|
||||
.await
|
||||
.map_err(|e| format!("TCP recv error: {}", e))?;
|
||||
stream.read_exact(&mut header).await?;
|
||||
|
||||
if header[0] != b'V' || header[1] != b'L' {
|
||||
return Err("received invalid TCP frame header".to_owned());
|
||||
bail_io_error_other!("received invalid TCP frame header");
|
||||
}
|
||||
let len = ((header[3] as usize) << 8) | (header[2] as usize);
|
||||
if len > MAX_MESSAGE_SIZE {
|
||||
return Err("received too large TCP frame".to_owned());
|
||||
bail_io_error_other!("received too large TCP frame");
|
||||
}
|
||||
|
||||
let mut out: Vec<u8> = vec![0u8; len];
|
||||
stream.read_exact(&mut out).await.map_err(map_to_string)?;
|
||||
stream.read_exact(&mut out).await?;
|
||||
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
#[instrument(level="trace", err, skip(self), fields(ret.len))]
|
||||
pub async fn recv(&self) -> Result<Vec<u8>, String> {
|
||||
pub async fn recv(&self) -> io::Result<Vec<u8>> {
|
||||
let mut stream = self.stream.clone();
|
||||
let out = Self::recv_internal(&mut stream).await?;
|
||||
tracing::Span::current().record("ret.len", &out.len());
|
||||
@ -121,14 +119,10 @@ impl RawTcpProtocolHandler {
|
||||
self,
|
||||
stream: AsyncPeekStream,
|
||||
socket_addr: SocketAddr,
|
||||
) -> Result<Option<ProtocolNetworkConnection>, String> {
|
||||
) -> io::Result<Option<ProtocolNetworkConnection>> {
|
||||
log_net!("TCP: on_accept_async: enter");
|
||||
let mut peekbuf: [u8; PEEK_DETECT_LEN] = [0u8; PEEK_DETECT_LEN];
|
||||
let peeklen = stream
|
||||
.peek(&mut peekbuf)
|
||||
.await
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!("could not peek tcp stream"))?;
|
||||
let peeklen = stream.peek(&mut peekbuf).await?;
|
||||
assert_eq!(peeklen, PEEK_DETECT_LEN);
|
||||
|
||||
let peer_addr = PeerAddress::new(
|
||||
@ -150,7 +144,7 @@ impl RawTcpProtocolHandler {
|
||||
pub async fn connect(
|
||||
local_address: Option<SocketAddr>,
|
||||
dial_info: DialInfo,
|
||||
) -> Result<ProtocolNetworkConnection, String> {
|
||||
) -> io::Result<ProtocolNetworkConnection> {
|
||||
// Get remote socket address to connect to
|
||||
let remote_socket_addr = dial_info.to_socket_addr();
|
||||
|
||||
@ -163,15 +157,10 @@ impl RawTcpProtocolHandler {
|
||||
};
|
||||
|
||||
// Non-blocking connect to remote address
|
||||
let ts = nonblocking_connect(socket, remote_socket_addr).await
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!(error "local_address={:?} remote_addr={}", local_address, remote_socket_addr))?;
|
||||
let ts = nonblocking_connect(socket, remote_socket_addr).await?;
|
||||
|
||||
// See what local address we ended up with and turn this into a stream
|
||||
let actual_local_address = ts
|
||||
.local_addr()
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!("could not get local address from TCP stream"))?;
|
||||
let actual_local_address = ts.local_addr()?;
|
||||
#[cfg(feature = "rt-tokio")]
|
||||
let ts = ts.compat();
|
||||
let ps = AsyncPeekStream::new(ts);
|
||||
@ -189,12 +178,9 @@ impl RawTcpProtocolHandler {
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", err, skip(data), fields(data.len = data.len()))]
|
||||
pub async fn send_unbound_message(
|
||||
socket_addr: SocketAddr,
|
||||
data: Vec<u8>,
|
||||
) -> Result<(), String> {
|
||||
pub async fn send_unbound_message(socket_addr: SocketAddr, data: Vec<u8>) -> io::Result<()> {
|
||||
if data.len() > MAX_MESSAGE_SIZE {
|
||||
return Err("sending too large unbound TCP message".to_owned());
|
||||
bail_io_error_other!("sending too large unbound TCP message");
|
||||
}
|
||||
trace!(
|
||||
"sending unbound message of length {} to {}",
|
||||
@ -206,10 +192,7 @@ impl RawTcpProtocolHandler {
|
||||
let socket = new_unbound_shared_tcp_socket(socket2::Domain::for_address(socket_addr))?;
|
||||
|
||||
// Non-blocking connect to remote address
|
||||
let ts = nonblocking_connect(socket, socket_addr)
|
||||
.await
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!(error "remote_addr={}", socket_addr))?;
|
||||
let ts = nonblocking_connect(socket, socket_addr).await?;
|
||||
|
||||
// See what local address we ended up with and turn this into a stream
|
||||
// let actual_local_address = ts
|
||||
@ -231,9 +214,9 @@ impl RawTcpProtocolHandler {
|
||||
socket_addr: SocketAddr,
|
||||
data: Vec<u8>,
|
||||
timeout_ms: u32,
|
||||
) -> Result<Vec<u8>, String> {
|
||||
) -> io::Result<Vec<u8>> {
|
||||
if data.len() > MAX_MESSAGE_SIZE {
|
||||
return Err("sending too large unbound TCP message".to_owned());
|
||||
bail_io_error_other!("sending too large unbound TCP message");
|
||||
}
|
||||
trace!(
|
||||
"sending unbound message of length {} to {}",
|
||||
@ -245,10 +228,7 @@ impl RawTcpProtocolHandler {
|
||||
let socket = new_unbound_shared_tcp_socket(socket2::Domain::for_address(socket_addr))?;
|
||||
|
||||
// Non-blocking connect to remote address
|
||||
let ts = nonblocking_connect(socket, socket_addr)
|
||||
.await
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!(error "remote_addr={}", socket_addr))?;
|
||||
let ts = nonblocking_connect(socket, socket_addr).await?;
|
||||
|
||||
// See what local address we ended up with and turn this into a stream
|
||||
// let actual_local_address = ts
|
||||
@ -265,7 +245,7 @@ impl RawTcpProtocolHandler {
|
||||
|
||||
let out = timeout(timeout_ms, RawTcpNetworkConnection::recv_internal(&mut ps))
|
||||
.await
|
||||
.map_err(map_to_string)??;
|
||||
.map_err(|e| e.to_io())??;
|
||||
|
||||
tracing::Span::current().record("ret.len", &out.len());
|
||||
Ok(out)
|
||||
@ -277,7 +257,7 @@ impl ProtocolAcceptHandler for RawTcpProtocolHandler {
|
||||
&self,
|
||||
stream: AsyncPeekStream,
|
||||
peer_addr: SocketAddr,
|
||||
) -> SystemPinBoxFuture<core::result::Result<Option<ProtocolNetworkConnection>, String>> {
|
||||
) -> SystemPinBoxFuture<io::Result<Option<ProtocolNetworkConnection>>> {
|
||||
Box::pin(self.clone().on_accept_async(stream, peer_addr))
|
||||
}
|
||||
}
|
||||
|
@ -12,27 +12,30 @@ impl RawUdpProtocolHandler {
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", err, skip(self, data), fields(data.len = data.len(), ret.len, ret.from))]
|
||||
pub async fn recv_message(
|
||||
&self,
|
||||
data: &mut [u8],
|
||||
) -> Result<(usize, ConnectionDescriptor), String> {
|
||||
let (size, remote_addr) = self.socket.recv_from(data).await.map_err(map_to_string)?;
|
||||
|
||||
if size > MAX_MESSAGE_SIZE {
|
||||
return Err("received too large UDP message".to_owned());
|
||||
}
|
||||
|
||||
trace!(
|
||||
"receiving UDP message of length {} from {}",
|
||||
size,
|
||||
remote_addr
|
||||
);
|
||||
pub async fn recv_message(&self, data: &mut [u8]) -> io::Result<(usize, ConnectionDescriptor)> {
|
||||
let (size, remote_addr) = loop {
|
||||
match self.socket.recv_from(data).await {
|
||||
Ok((size, remote_addr)) => {
|
||||
if size > MAX_MESSAGE_SIZE {
|
||||
bail_io_error_other!("received too large UDP message");
|
||||
}
|
||||
break (size, remote_addr);
|
||||
}
|
||||
Err(e) => {
|
||||
if e.kind() == io::ErrorKind::ConnectionReset {
|
||||
// Ignore icmp
|
||||
} else {
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let peer_addr = PeerAddress::new(
|
||||
SocketAddress::from_socket_addr(remote_addr),
|
||||
ProtocolType::UDP,
|
||||
);
|
||||
let local_socket_addr = self.socket.local_addr().map_err(map_to_string)?;
|
||||
let local_socket_addr = self.socket.local_addr()?;
|
||||
let descriptor = ConnectionDescriptor::new(
|
||||
peer_addr,
|
||||
SocketAddress::from_socket_addr(local_socket_addr),
|
||||
@ -44,45 +47,24 @@ impl RawUdpProtocolHandler {
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", err, skip(self, data), fields(data.len = data.len(), ret.len, ret.from))]
|
||||
pub async fn send_message(&self, data: Vec<u8>, socket_addr: SocketAddr) -> Result<(), String> {
|
||||
pub async fn send_message(&self, data: Vec<u8>, socket_addr: SocketAddr) -> io::Result<()> {
|
||||
if data.len() > MAX_MESSAGE_SIZE {
|
||||
return Err("sending too large UDP message".to_owned()).map_err(logthru_net!(error));
|
||||
bail_io_error_other!("sending too large UDP message");
|
||||
}
|
||||
|
||||
log_net!(
|
||||
"sending UDP message of length {} to {}",
|
||||
data.len(),
|
||||
socket_addr
|
||||
);
|
||||
|
||||
let len = self
|
||||
.socket
|
||||
.send_to(&data, socket_addr)
|
||||
.await
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!(error "failed udp send: addr={}", socket_addr))?;
|
||||
|
||||
let len = self.socket.send_to(&data, socket_addr).await?;
|
||||
if len != data.len() {
|
||||
Err("UDP partial send".to_owned()).map_err(logthru_net!(error))
|
||||
} else {
|
||||
Ok(())
|
||||
bail_io_error_other!("UDP partial send")
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", err, skip(data), fields(data.len = data.len()))]
|
||||
pub async fn send_unbound_message(
|
||||
socket_addr: SocketAddr,
|
||||
data: Vec<u8>,
|
||||
) -> Result<(), String> {
|
||||
pub async fn send_unbound_message(socket_addr: SocketAddr, data: Vec<u8>) -> io::Result<()> {
|
||||
if data.len() > MAX_MESSAGE_SIZE {
|
||||
return Err("sending too large unbound UDP message".to_owned())
|
||||
.map_err(logthru_net!(error));
|
||||
bail_io_error_other!("sending too large unbound UDP message");
|
||||
}
|
||||
log_net!(
|
||||
"sending unbound message of length {} to {}",
|
||||
data.len(),
|
||||
socket_addr
|
||||
);
|
||||
|
||||
// get local wildcard address for bind
|
||||
let local_socket_addr = match socket_addr {
|
||||
@ -91,20 +73,13 @@ impl RawUdpProtocolHandler {
|
||||
SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)), 0)
|
||||
}
|
||||
};
|
||||
let socket = UdpSocket::bind(local_socket_addr)
|
||||
.await
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!(error "failed to bind unbound udp socket"))?;
|
||||
let len = socket
|
||||
.send_to(&data, socket_addr)
|
||||
.await
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!(error "failed unbound udp send: addr={}", socket_addr))?;
|
||||
let socket = UdpSocket::bind(local_socket_addr).await?;
|
||||
let len = socket.send_to(&data, socket_addr).await?;
|
||||
if len != data.len() {
|
||||
Err("UDP partial unbound send".to_owned()).map_err(logthru_net!(error))
|
||||
} else {
|
||||
Ok(())
|
||||
bail_io_error_other!("UDP partial unbound send")
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", err, skip(data), fields(data.len = data.len(), ret.len))]
|
||||
@ -112,16 +87,10 @@ impl RawUdpProtocolHandler {
|
||||
socket_addr: SocketAddr,
|
||||
data: Vec<u8>,
|
||||
timeout_ms: u32,
|
||||
) -> Result<Vec<u8>, String> {
|
||||
) -> io::Result<Vec<u8>> {
|
||||
if data.len() > MAX_MESSAGE_SIZE {
|
||||
return Err("sending too large unbound UDP message".to_owned())
|
||||
.map_err(logthru_net!(error));
|
||||
bail_io_error_other!("sending too large unbound UDP message");
|
||||
}
|
||||
log_net!(
|
||||
"sending unbound message of length {} to {}",
|
||||
data.len(),
|
||||
socket_addr
|
||||
);
|
||||
|
||||
// get local wildcard address for bind
|
||||
let local_socket_addr = match socket_addr {
|
||||
@ -132,29 +101,21 @@ impl RawUdpProtocolHandler {
|
||||
};
|
||||
|
||||
// get unspecified bound socket
|
||||
let socket = UdpSocket::bind(local_socket_addr)
|
||||
.await
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!(error "failed to bind unbound udp socket"))?;
|
||||
let len = socket
|
||||
.send_to(&data, socket_addr)
|
||||
.await
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!(error "failed unbound udp send: addr={}", socket_addr))?;
|
||||
let socket = UdpSocket::bind(local_socket_addr).await?;
|
||||
let len = socket.send_to(&data, socket_addr).await?;
|
||||
if len != data.len() {
|
||||
return Err("UDP partial unbound send".to_owned()).map_err(logthru_net!(error));
|
||||
bail_io_error_other!("UDP partial unbound send");
|
||||
}
|
||||
|
||||
// receive single response
|
||||
let mut out = vec![0u8; MAX_MESSAGE_SIZE];
|
||||
let (len, from_addr) = timeout(timeout_ms, socket.recv_from(&mut out))
|
||||
.await
|
||||
.map_err(map_to_string)?
|
||||
.map_err(map_to_string)?;
|
||||
.map_err(|e| e.to_io())??;
|
||||
|
||||
// if the from address is not the same as the one we sent to, then drop this
|
||||
if from_addr != socket_addr {
|
||||
return Err(format!(
|
||||
bail_io_error_other!(format!(
|
||||
"Unbound response received from wrong address: addr={}",
|
||||
from_addr,
|
||||
));
|
||||
|
@ -17,6 +17,25 @@ cfg_if! {
|
||||
}
|
||||
}
|
||||
|
||||
fn to_io(err: async_tungstenite::tungstenite::Error) -> io::Error {
|
||||
let kind = match err {
|
||||
async_tungstenite::tungstenite::Error::ConnectionClosed => io::ErrorKind::ConnectionReset,
|
||||
async_tungstenite::tungstenite::Error::AlreadyClosed => io::ErrorKind::NotConnected,
|
||||
async_tungstenite::tungstenite::Error::Io(x) => {
|
||||
return x;
|
||||
}
|
||||
async_tungstenite::tungstenite::Error::Tls(_) => io::ErrorKind::InvalidData,
|
||||
async_tungstenite::tungstenite::Error::Capacity(_) => io::ErrorKind::Other,
|
||||
async_tungstenite::tungstenite::Error::Protocol(_) => io::ErrorKind::Other,
|
||||
async_tungstenite::tungstenite::Error::SendQueueFull(_) => io::ErrorKind::Other,
|
||||
async_tungstenite::tungstenite::Error::Utf8 => io::ErrorKind::Other,
|
||||
async_tungstenite::tungstenite::Error::Url(_) => io::ErrorKind::Other,
|
||||
async_tungstenite::tungstenite::Error::Http(_) => io::ErrorKind::Other,
|
||||
async_tungstenite::tungstenite::Error::HttpFormat(_) => io::ErrorKind::Other,
|
||||
};
|
||||
io::Error::new(kind, err)
|
||||
}
|
||||
|
||||
pub type WebSocketNetworkConnectionAccepted = WebsocketNetworkConnection<AsyncPeekStream>;
|
||||
|
||||
pub struct WebsocketNetworkConnection<T>
|
||||
@ -62,41 +81,49 @@ where
|
||||
// }
|
||||
|
||||
#[instrument(level = "trace", err, skip(self, message), fields(message.len = message.len()))]
|
||||
pub async fn send(&self, message: Vec<u8>) -> Result<(), String> {
|
||||
pub async fn send(&self, message: Vec<u8>) -> io::Result<()> {
|
||||
if message.len() > MAX_MESSAGE_SIZE {
|
||||
return Err("received too large WS message".to_owned());
|
||||
bail_io_error_other!("received too large WS message");
|
||||
}
|
||||
self.stream
|
||||
.clone()
|
||||
.send(Message::binary(message))
|
||||
.await
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!(error "failed to send websocket message"))
|
||||
.map_err(to_io)
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", err, skip(self), fields(ret.len))]
|
||||
pub async fn recv(&self) -> Result<Vec<u8>, String> {
|
||||
pub async fn recv(&self) -> io::Result<Vec<u8>> {
|
||||
let out = match self.stream.clone().next().await {
|
||||
Some(Ok(Message::Binary(v))) => v,
|
||||
Some(Ok(Message::Close(e))) => {
|
||||
return Err(format!("WS connection closed: {:?}", e));
|
||||
Some(Ok(Message::Binary(v))) => {
|
||||
if v.len() > MAX_MESSAGE_SIZE {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::ConnectionReset,
|
||||
"too large ws message",
|
||||
));
|
||||
}
|
||||
v
|
||||
}
|
||||
Some(Ok(Message::Close(_))) => {
|
||||
return Err(io::Error::new(io::ErrorKind::ConnectionReset, "closeframe"))
|
||||
}
|
||||
Some(Ok(x)) => {
|
||||
return Err(format!("Unexpected WS message type: {:?}", x));
|
||||
}
|
||||
Some(Err(e)) => {
|
||||
return Err(e.to_string()).map_err(logthru_net!(error));
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
format!("Unexpected WS message type: {:?}", x),
|
||||
));
|
||||
}
|
||||
Some(Err(e)) => return Err(to_io(e)),
|
||||
None => {
|
||||
return Err("WS stream closed".to_owned());
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::ConnectionReset,
|
||||
"connection ended",
|
||||
))
|
||||
}
|
||||
};
|
||||
if out.len() > MAX_MESSAGE_SIZE {
|
||||
Err("sending too large WS message".to_owned()).map_err(logthru_net!(error))
|
||||
} else {
|
||||
tracing::Span::current().record("ret.len", &out.len());
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
tracing::Span::current().record("ret.len", &out.len());
|
||||
Ok(out)
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,21 +172,18 @@ impl WebsocketProtocolHandler {
|
||||
self,
|
||||
ps: AsyncPeekStream,
|
||||
socket_addr: SocketAddr,
|
||||
) -> Result<Option<ProtocolNetworkConnection>, String> {
|
||||
) -> io::Result<Option<ProtocolNetworkConnection>> {
|
||||
log_net!("WS: on_accept_async: enter");
|
||||
let request_path_len = self.arc.request_path.len() + 2;
|
||||
|
||||
let mut peekbuf: Vec<u8> = vec![0u8; request_path_len];
|
||||
match timeout(
|
||||
if let Err(_) = timeout(
|
||||
self.arc.connection_initial_timeout_ms,
|
||||
ps.peek_exact(&mut peekbuf),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(_) => (),
|
||||
Err(e) => {
|
||||
return Err(e.to_string());
|
||||
}
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
// Check for websocket path
|
||||
@ -169,15 +193,12 @@ impl WebsocketProtocolHandler {
|
||||
&& peekbuf[request_path_len - 1] == b' '));
|
||||
|
||||
if !matches_path {
|
||||
log_net!("WS: not websocket");
|
||||
return Ok(None);
|
||||
}
|
||||
log_net!("WS: found websocket");
|
||||
|
||||
let ws_stream = accept_async(ps)
|
||||
.await
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!("failed websockets handshake"))?;
|
||||
.map_err(|e| io_error_other!(format!("failed websockets handshake: {}", e)))?;
|
||||
|
||||
// Wrap the websocket in a NetworkConnection and register it
|
||||
let protocol_type = if self.arc.tls {
|
||||
@ -205,7 +226,7 @@ impl WebsocketProtocolHandler {
|
||||
async fn connect_internal(
|
||||
local_address: Option<SocketAddr>,
|
||||
dial_info: DialInfo,
|
||||
) -> Result<ProtocolNetworkConnection, String> {
|
||||
) -> io::Result<ProtocolNetworkConnection> {
|
||||
// Split dial info up
|
||||
let (tls, scheme) = match &dial_info {
|
||||
DialInfo::WS(_) => (false, "ws"),
|
||||
@ -213,9 +234,9 @@ impl WebsocketProtocolHandler {
|
||||
_ => panic!("invalid dialinfo for WS/WSS protocol"),
|
||||
};
|
||||
let request = dial_info.request().unwrap();
|
||||
let split_url = SplitUrl::from_str(&request)?;
|
||||
let split_url = SplitUrl::from_str(&request).map_err(to_io_error_other)?;
|
||||
if split_url.scheme != scheme {
|
||||
return Err("invalid websocket url scheme".to_string());
|
||||
bail_io_error_other!("invalid websocket url scheme");
|
||||
}
|
||||
let domain = split_url.host.clone();
|
||||
|
||||
@ -231,12 +252,10 @@ impl WebsocketProtocolHandler {
|
||||
};
|
||||
|
||||
// Non-blocking connect to remote address
|
||||
let tcp_stream = nonblocking_connect(socket, remote_socket_addr).await
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!(error "local_address={:?} remote_addr={}", local_address, remote_socket_addr))?;
|
||||
let tcp_stream = nonblocking_connect(socket, remote_socket_addr).await?;
|
||||
|
||||
// See what local address we ended up with
|
||||
let actual_local_addr = tcp_stream.local_addr().map_err(map_to_string)?;
|
||||
let actual_local_addr = tcp_stream.local_addr()?;
|
||||
|
||||
#[cfg(feature = "rt-tokio")]
|
||||
let tcp_stream = tcp_stream.compat();
|
||||
@ -249,15 +268,10 @@ impl WebsocketProtocolHandler {
|
||||
// Negotiate TLS if this is WSS
|
||||
if tls {
|
||||
let connector = TlsConnector::default();
|
||||
let tls_stream = connector
|
||||
.connect(domain.to_string(), tcp_stream)
|
||||
.await
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!(error))?;
|
||||
let tls_stream = connector.connect(domain.to_string(), tcp_stream).await?;
|
||||
let (ws_stream, _response) = client_async(request, tls_stream)
|
||||
.await
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!(error))?;
|
||||
.map_err(to_io_error_other)?;
|
||||
|
||||
Ok(ProtocolNetworkConnection::Wss(
|
||||
WebsocketNetworkConnection::new(descriptor, ws_stream),
|
||||
@ -265,8 +279,7 @@ impl WebsocketProtocolHandler {
|
||||
} else {
|
||||
let (ws_stream, _response) = client_async(request, tcp_stream)
|
||||
.await
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!(error))?;
|
||||
.map_err(to_io_error_other)?;
|
||||
Ok(ProtocolNetworkConnection::Ws(
|
||||
WebsocketNetworkConnection::new(descriptor, ws_stream),
|
||||
))
|
||||
@ -277,19 +290,17 @@ impl WebsocketProtocolHandler {
|
||||
pub async fn connect(
|
||||
local_address: Option<SocketAddr>,
|
||||
dial_info: DialInfo,
|
||||
) -> Result<ProtocolNetworkConnection, String> {
|
||||
) -> io::Result<ProtocolNetworkConnection> {
|
||||
Self::connect_internal(local_address, dial_info).await
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", err, skip(data), fields(data.len = data.len()))]
|
||||
pub async fn send_unbound_message(dial_info: DialInfo, data: Vec<u8>) -> Result<(), String> {
|
||||
pub async fn send_unbound_message(dial_info: DialInfo, data: Vec<u8>) -> io::Result<()> {
|
||||
if data.len() > MAX_MESSAGE_SIZE {
|
||||
return Err("sending too large unbound WS message".to_owned());
|
||||
bail_io_error_other!("sending too large unbound WS message");
|
||||
}
|
||||
|
||||
let protconn = Self::connect_internal(None, dial_info.clone())
|
||||
.await
|
||||
.map_err(|e| format!("failed to connect websocket for unbound message: {}", e))?;
|
||||
let protconn = Self::connect_internal(None, dial_info.clone()).await?;
|
||||
|
||||
protconn.send(data).await
|
||||
}
|
||||
@ -299,19 +310,17 @@ impl WebsocketProtocolHandler {
|
||||
dial_info: DialInfo,
|
||||
data: Vec<u8>,
|
||||
timeout_ms: u32,
|
||||
) -> Result<Vec<u8>, String> {
|
||||
) -> io::Result<Vec<u8>> {
|
||||
if data.len() > MAX_MESSAGE_SIZE {
|
||||
return Err("sending too large unbound WS message".to_owned());
|
||||
bail_io_error_other!("sending too large unbound WS message");
|
||||
}
|
||||
|
||||
let protconn = Self::connect_internal(None, dial_info.clone())
|
||||
.await
|
||||
.map_err(|e| format!("failed to connect websocket for unbound message: {}", e))?;
|
||||
let protconn = Self::connect_internal(None, dial_info.clone()).await?;
|
||||
|
||||
protconn.send(data).await?;
|
||||
let out = timeout(timeout_ms, protconn.recv())
|
||||
.await
|
||||
.map_err(map_to_string)??;
|
||||
.map_err(|e| e.to_io())??;
|
||||
|
||||
tracing::Span::current().record("ret.len", &out.len());
|
||||
Ok(out)
|
||||
@ -323,7 +332,7 @@ impl ProtocolAcceptHandler for WebsocketProtocolHandler {
|
||||
&self,
|
||||
stream: AsyncPeekStream,
|
||||
peer_addr: SocketAddr,
|
||||
) -> SystemPinBoxFuture<Result<Option<ProtocolNetworkConnection>, String>> {
|
||||
) -> SystemPinBoxFuture<io::Result<Option<ProtocolNetworkConnection>>> {
|
||||
Box::pin(self.clone().on_accept_async(stream, peer_addr))
|
||||
}
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ impl Network {
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
fn find_available_udp_port(&self) -> Result<u16, String> {
|
||||
fn find_available_udp_port(&self) -> EyreResult<u16> {
|
||||
// If the address is empty, iterate ports until we find one we can use.
|
||||
let mut udp_port = 5150u16;
|
||||
loop {
|
||||
@ -175,14 +175,14 @@ impl Network {
|
||||
break;
|
||||
}
|
||||
if udp_port == 65535 {
|
||||
return Err("Could not find free udp port to listen on".to_owned());
|
||||
bail!("Could not find free udp port to listen on");
|
||||
}
|
||||
udp_port += 1;
|
||||
}
|
||||
Ok(udp_port)
|
||||
}
|
||||
|
||||
fn find_available_tcp_port(&self) -> Result<u16, String> {
|
||||
fn find_available_tcp_port(&self) -> EyreResult<u16> {
|
||||
// If the address is empty, iterate ports until we find one we can use.
|
||||
let mut tcp_port = 5150u16;
|
||||
loop {
|
||||
@ -193,17 +193,14 @@ impl Network {
|
||||
break;
|
||||
}
|
||||
if tcp_port == 65535 {
|
||||
return Err("Could not find free tcp port to listen on".to_owned());
|
||||
bail!("Could not find free tcp port to listen on");
|
||||
}
|
||||
tcp_port += 1;
|
||||
}
|
||||
Ok(tcp_port)
|
||||
}
|
||||
|
||||
async fn allocate_udp_port(
|
||||
&self,
|
||||
listen_address: String,
|
||||
) -> Result<(u16, Vec<IpAddr>), String> {
|
||||
async fn allocate_udp_port(&self, listen_address: String) -> EyreResult<(u16, Vec<IpAddr>)> {
|
||||
if listen_address.is_empty() {
|
||||
// If listen address is empty, find us a port iteratively
|
||||
let port = self.find_available_udp_port()?;
|
||||
@ -217,21 +214,17 @@ impl Network {
|
||||
// If the address is specified, only use the specified port and fail otherwise
|
||||
let sockaddrs = listen_address_to_socket_addrs(&listen_address)?;
|
||||
if sockaddrs.is_empty() {
|
||||
return Err(format!("No valid listen address: {}", listen_address));
|
||||
bail!("No valid listen address: {}", listen_address);
|
||||
}
|
||||
let port = sockaddrs[0].port();
|
||||
if self.bind_first_udp_port(port) {
|
||||
Ok((port, sockaddrs.iter().map(|s| s.ip()).collect()))
|
||||
} else {
|
||||
Err("Could not find free udp port to listen on".to_owned())
|
||||
if !self.bind_first_udp_port(port) {
|
||||
bail!("Could not find free udp port to listen on");
|
||||
}
|
||||
Ok((port, sockaddrs.iter().map(|s| s.ip()).collect()))
|
||||
}
|
||||
}
|
||||
|
||||
async fn allocate_tcp_port(
|
||||
&self,
|
||||
listen_address: String,
|
||||
) -> Result<(u16, Vec<IpAddr>), String> {
|
||||
async fn allocate_tcp_port(&self, listen_address: String) -> EyreResult<(u16, Vec<IpAddr>)> {
|
||||
if listen_address.is_empty() {
|
||||
// If listen address is empty, find us a port iteratively
|
||||
let port = self.find_available_tcp_port()?;
|
||||
@ -245,20 +238,19 @@ impl Network {
|
||||
// If the address is specified, only use the specified port and fail otherwise
|
||||
let sockaddrs = listen_address_to_socket_addrs(&listen_address)?;
|
||||
if sockaddrs.is_empty() {
|
||||
return Err(format!("No valid listen address: {}", listen_address));
|
||||
bail!("No valid listen address: {}", listen_address);
|
||||
}
|
||||
let port = sockaddrs[0].port();
|
||||
if self.bind_first_tcp_port(port) {
|
||||
Ok((port, sockaddrs.iter().map(|s| s.ip()).collect()))
|
||||
} else {
|
||||
Err("Could not find free tcp port to listen on".to_owned())
|
||||
if !self.bind_first_tcp_port(port) {
|
||||
bail!("Could not find free tcp port to listen on");
|
||||
}
|
||||
Ok((port, sockaddrs.iter().map(|s| s.ip()).collect()))
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
pub(super) async fn start_udp_listeners(&self) -> Result<(), String> {
|
||||
pub(super) async fn start_udp_listeners(&self) -> EyreResult<()> {
|
||||
trace!("starting udp listeners");
|
||||
let routing_table = self.routing_table();
|
||||
let (listen_address, public_address, enable_local_peer_scope) = {
|
||||
@ -319,7 +311,7 @@ impl Network {
|
||||
// Resolve statically configured public dialinfo
|
||||
let mut public_sockaddrs = public_address
|
||||
.to_socket_addrs()
|
||||
.map_err(|e| format!("Unable to resolve address: {}\n{}", public_address, e))?;
|
||||
.wrap_err(format!("Unable to resolve address: {}", public_address))?;
|
||||
|
||||
// Add all resolved addresses as public dialinfo
|
||||
for pdi_addr in &mut public_sockaddrs {
|
||||
@ -364,7 +356,7 @@ impl Network {
|
||||
self.create_udp_listener_tasks().await
|
||||
}
|
||||
|
||||
pub(super) async fn start_ws_listeners(&self) -> Result<(), String> {
|
||||
pub(super) async fn start_ws_listeners(&self) -> EyreResult<()> {
|
||||
trace!("starting ws listeners");
|
||||
let routing_table = self.routing_table();
|
||||
let (listen_address, url, path, enable_local_peer_scope) = {
|
||||
@ -405,9 +397,9 @@ impl Network {
|
||||
|
||||
// Add static public dialinfo if it's configured
|
||||
if let Some(url) = url.as_ref() {
|
||||
let mut split_url = SplitUrl::from_str(url)?;
|
||||
let mut split_url = SplitUrl::from_str(url).wrap_err("couldn't split url")?;
|
||||
if split_url.scheme.to_ascii_lowercase() != "ws" {
|
||||
return Err("WS URL must use 'ws://' scheme".to_owned());
|
||||
bail!("WS URL must use 'ws://' scheme");
|
||||
}
|
||||
split_url.scheme = "ws".to_owned();
|
||||
|
||||
@ -415,13 +407,11 @@ impl Network {
|
||||
let global_socket_addrs = split_url
|
||||
.host_port(80)
|
||||
.to_socket_addrs()
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!(error))?;
|
||||
.wrap_err("failed to resolve ws url")?;
|
||||
|
||||
for gsa in global_socket_addrs {
|
||||
let pdi = DialInfo::try_ws(SocketAddress::from_socket_addr(gsa), url.clone())
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!(error))?;
|
||||
.wrap_err("try_ws failed")?;
|
||||
|
||||
routing_table.register_dial_info(
|
||||
RoutingDomain::PublicInternet,
|
||||
@ -458,9 +448,7 @@ impl Network {
|
||||
}
|
||||
// Build dial info request url
|
||||
let local_url = format!("ws://{}/{}", socket_address, path);
|
||||
let local_di = DialInfo::try_ws(socket_address, local_url)
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!(error))?;
|
||||
let local_di = DialInfo::try_ws(socket_address, local_url).wrap_err("try_ws failed")?;
|
||||
|
||||
if url.is_none() && (socket_address.address().is_global() || enable_local_peer_scope) {
|
||||
// Register public dial info
|
||||
@ -490,7 +478,7 @@ impl Network {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) async fn start_wss_listeners(&self) -> Result<(), String> {
|
||||
pub(super) async fn start_wss_listeners(&self) -> EyreResult<()> {
|
||||
trace!("starting wss listeners");
|
||||
|
||||
let routing_table = self.routing_table();
|
||||
@ -538,7 +526,7 @@ impl Network {
|
||||
// Add static public dialinfo if it's configured
|
||||
let mut split_url = SplitUrl::from_str(url)?;
|
||||
if split_url.scheme.to_ascii_lowercase() != "wss" {
|
||||
return Err("WSS URL must use 'wss://' scheme".to_owned());
|
||||
bail!("WSS URL must use 'wss://' scheme");
|
||||
}
|
||||
split_url.scheme = "wss".to_owned();
|
||||
|
||||
@ -546,13 +534,10 @@ impl Network {
|
||||
let global_socket_addrs = split_url
|
||||
.host_port(443)
|
||||
.to_socket_addrs()
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!(error))?;
|
||||
|
||||
.wrap_err("failed to resolve wss url")?;
|
||||
for gsa in global_socket_addrs {
|
||||
let pdi = DialInfo::try_wss(SocketAddress::from_socket_addr(gsa), url.clone())
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_net!(error))?;
|
||||
.wrap_err("try_wss failed")?;
|
||||
|
||||
routing_table.register_dial_info(
|
||||
RoutingDomain::PublicInternet,
|
||||
@ -581,7 +566,7 @@ impl Network {
|
||||
registered_addresses.insert(gsa.ip());
|
||||
}
|
||||
} else {
|
||||
return Err("WSS URL must be specified due to TLS requirements".to_owned());
|
||||
bail!("WSS URL must be specified due to TLS requirements");
|
||||
}
|
||||
|
||||
if static_public {
|
||||
@ -594,7 +579,7 @@ impl Network {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) async fn start_tcp_listeners(&self) -> Result<(), String> {
|
||||
pub(super) async fn start_tcp_listeners(&self) -> EyreResult<()> {
|
||||
trace!("starting tcp listeners");
|
||||
|
||||
let routing_table = self.routing_table();
|
||||
@ -659,7 +644,7 @@ impl Network {
|
||||
// Resolve statically configured public dialinfo
|
||||
let mut public_sockaddrs = public_address
|
||||
.to_socket_addrs()
|
||||
.map_err(|e| format!("Unable to resolve address: {}\n{}", public_address, e))?;
|
||||
.wrap_err("failed to resolve tcp address")?;
|
||||
|
||||
// Add all resolved addresses as public dialinfo
|
||||
for pdi_addr in &mut public_sockaddrs {
|
||||
|
@ -1,5 +1,6 @@
|
||||
use super::*;
|
||||
use futures_util::{FutureExt, StreamExt};
|
||||
use std::io;
|
||||
use stop_token::prelude::*;
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
@ -15,7 +16,7 @@ cfg_if::cfg_if! {
|
||||
&self,
|
||||
stream: AsyncPeekStream,
|
||||
peer_addr: SocketAddr,
|
||||
) -> SystemPinBoxFuture<Result<Option<ProtocolNetworkConnection>, String>>;
|
||||
) -> SystemPinBoxFuture<io::Result<Option<ProtocolNetworkConnection>>>;
|
||||
}
|
||||
|
||||
pub trait ProtocolAcceptHandlerClone {
|
||||
@ -52,13 +53,13 @@ impl DummyNetworkConnection {
|
||||
pub fn descriptor(&self) -> ConnectionDescriptor {
|
||||
self.descriptor.clone()
|
||||
}
|
||||
pub fn close(&self) -> Result<(), String> {
|
||||
// pub fn close(&self) -> Result<(), String> {
|
||||
// Ok(())
|
||||
// }
|
||||
pub fn send(&self, _message: Vec<u8>) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
pub fn send(&self, _message: Vec<u8>) -> Result<(), String> {
|
||||
Ok(())
|
||||
}
|
||||
pub fn recv(&self) -> Result<Vec<u8>, String> {
|
||||
pub fn recv(&self) -> io::Result<Vec<u8>> {
|
||||
Ok(Vec::new())
|
||||
}
|
||||
}
|
||||
@ -178,7 +179,7 @@ impl NetworkConnection {
|
||||
protocol_connection: &ProtocolNetworkConnection,
|
||||
stats: Arc<Mutex<NetworkConnectionStats>>,
|
||||
message: Vec<u8>,
|
||||
) -> Result<(), String> {
|
||||
) -> io::Result<()> {
|
||||
let ts = intf::get_timestamp();
|
||||
let out = protocol_connection.send(message).await;
|
||||
if out.is_ok() {
|
||||
@ -190,7 +191,7 @@ impl NetworkConnection {
|
||||
async fn recv_internal(
|
||||
protocol_connection: &ProtocolNetworkConnection,
|
||||
stats: Arc<Mutex<NetworkConnectionStats>>,
|
||||
) -> Result<Vec<u8>, String> {
|
||||
) -> io::Result<Vec<u8>> {
|
||||
let ts = intf::get_timestamp();
|
||||
let out = protocol_connection.recv().await;
|
||||
if out.is_ok() {
|
||||
@ -222,7 +223,7 @@ impl NetworkConnection {
|
||||
) -> SystemPinBoxFuture<()> {
|
||||
Box::pin(async move {
|
||||
log_net!(
|
||||
"Starting process_connection loop for {:?}",
|
||||
"== Starting process_connection loop for {:?}",
|
||||
descriptor.green()
|
||||
);
|
||||
|
||||
@ -236,7 +237,7 @@ impl NetworkConnection {
|
||||
let new_timer = || {
|
||||
intf::sleep(connection_inactivity_timeout_ms).then(|_| async {
|
||||
// timeout
|
||||
log_net!("connection timeout on {:?}", descriptor.green());
|
||||
log_net!("== Connection timeout on {:?}", descriptor.green());
|
||||
RecvLoopAction::Timeout
|
||||
})
|
||||
};
|
||||
@ -288,7 +289,7 @@ impl NetworkConnection {
|
||||
.on_recv_envelope(message.as_slice(), descriptor)
|
||||
.await
|
||||
{
|
||||
log_net!(error e);
|
||||
log_net!(debug "failed to process received envelope: {}", e);
|
||||
RecvLoopAction::Finish
|
||||
} else {
|
||||
RecvLoopAction::Recv
|
||||
@ -296,7 +297,7 @@ impl NetworkConnection {
|
||||
}
|
||||
Err(e) => {
|
||||
// Connection unable to receive, closed
|
||||
log_net!(warn e);
|
||||
log_net!(debug e);
|
||||
RecvLoopAction::Finish
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ impl Network {
|
||||
&self,
|
||||
dial_info: DialInfo,
|
||||
data: Vec<u8>,
|
||||
) -> Result<(), String> {
|
||||
) -> EyreResult<()> {
|
||||
let data_len = data.len();
|
||||
|
||||
let res = match dial_info.protocol_type() {
|
||||
@ -90,7 +90,7 @@ impl Network {
|
||||
dial_info: DialInfo,
|
||||
data: Vec<u8>,
|
||||
timeout_ms: u32,
|
||||
) -> Result<Vec<u8>, String> {
|
||||
) -> EyreResult<Vec<u8>> {
|
||||
let data_len = data.len();
|
||||
let out = match dial_info.protocol_type() {
|
||||
ProtocolType::UDP => {
|
||||
@ -124,7 +124,7 @@ impl Network {
|
||||
&self,
|
||||
descriptor: ConnectionDescriptor,
|
||||
data: Vec<u8>,
|
||||
) -> Result<Option<Vec<u8>>, String> {
|
||||
) -> EyreResult<Option<Vec<u8>>> {
|
||||
let data_len = data.len();
|
||||
match descriptor.protocol_type() {
|
||||
ProtocolType::UDP => {
|
||||
@ -161,7 +161,7 @@ impl Network {
|
||||
&self,
|
||||
dial_info: DialInfo,
|
||||
data: Vec<u8>,
|
||||
) -> Result<(), String> {
|
||||
) -> EyreResult<()> {
|
||||
let data_len = data.len();
|
||||
if dial_info.protocol_type() == ProtocolType::UDP {
|
||||
return Err("no support for UDP protocol".to_owned()).map_err(logthru_net!(error))
|
||||
@ -187,7 +187,7 @@ impl Network {
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
pub async fn startup(&self) -> Result<(), String> {
|
||||
pub async fn startup(&self) -> EyreResult<()> {
|
||||
// get protocol config
|
||||
self.inner.lock().protocol_config = Some({
|
||||
let c = self.config.get();
|
||||
@ -269,7 +269,7 @@ impl Network {
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
pub async fn tick(&self) -> Result<(), String> {
|
||||
pub async fn tick(&self) -> EyreResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ impl ProtocolNetworkConnection {
|
||||
pub async fn connect(
|
||||
local_address: Option<SocketAddr>,
|
||||
dial_info: DialInfo,
|
||||
) -> Result<ProtocolNetworkConnection, String> {
|
||||
) -> io::Result<ProtocolNetworkConnection> {
|
||||
match dial_info.protocol_type() {
|
||||
ProtocolType::UDP => {
|
||||
panic!("UDP dial info is not supported on WASM targets");
|
||||
@ -32,7 +32,7 @@ impl ProtocolNetworkConnection {
|
||||
pub async fn send_unbound_message(
|
||||
dial_info: DialInfo,
|
||||
data: Vec<u8>,
|
||||
) -> Result<(), String> {
|
||||
) -> io::Result<()> {
|
||||
match dial_info.protocol_type() {
|
||||
ProtocolType::UDP => {
|
||||
panic!("UDP dial info is not supported on WASM targets");
|
||||
@ -50,7 +50,7 @@ impl ProtocolNetworkConnection {
|
||||
dial_info: DialInfo,
|
||||
data: Vec<u8>,
|
||||
timeout_ms: u32,
|
||||
) -> Result<Vec<u8>, String> {
|
||||
) -> io::Result<Vec<u8>> {
|
||||
match dial_info.protocol_type() {
|
||||
ProtocolType::UDP => {
|
||||
panic!("UDP dial info is not supported on WASM targets");
|
||||
@ -72,20 +72,20 @@ impl ProtocolNetworkConnection {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn close(&self) -> Result<(), String> {
|
||||
match self {
|
||||
Self::Dummy(d) => d.close(),
|
||||
Self::Ws(w) => w.close().await,
|
||||
}
|
||||
}
|
||||
pub async fn send(&self, message: Vec<u8>) -> Result<(), String> {
|
||||
// pub async fn close(&self) -> io::Result<()> {
|
||||
// match self {
|
||||
// Self::Dummy(d) => d.close(),
|
||||
// Self::Ws(w) => w.close().await,
|
||||
// }
|
||||
// }
|
||||
pub async fn send(&self, message: Vec<u8>) -> io::Result<()> {
|
||||
match self {
|
||||
Self::Dummy(d) => d.send(message),
|
||||
Self::Ws(w) => w.send(message).await,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn recv(&self) -> Result<Vec<u8>, String> {
|
||||
pub async fn recv(&self) -> io::Result<Vec<u8>> {
|
||||
match self {
|
||||
Self::Dummy(d) => d.recv(),
|
||||
Self::Ws(w) => w.recv().await,
|
||||
|
@ -1,12 +1,19 @@
|
||||
use super::*;
|
||||
use ws_stream_wasm::*;
|
||||
use futures_util::{StreamExt, SinkExt};
|
||||
use std::io;
|
||||
|
||||
struct WebsocketNetworkConnectionInner {
|
||||
ws_meta: WsMeta,
|
||||
ws_stream: CloneStream<WsStream>,
|
||||
}
|
||||
|
||||
fn to_io(err: WsErr) -> io::Error {
|
||||
let kind = match err {
|
||||
WsErr::InvalidWsState {supplied:_} => io::ErrorKind::
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct WebsocketNetworkConnection {
|
||||
descriptor: ConnectionDescriptor,
|
||||
@ -36,15 +43,15 @@ impl WebsocketNetworkConnection {
|
||||
self.descriptor.clone()
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", err, skip(self))]
|
||||
pub async fn close(&self) -> Result<(), String> {
|
||||
self.inner.ws_meta.close().await.map_err(map_to_string).map(drop)
|
||||
}
|
||||
// #[instrument(level = "trace", err, skip(self))]
|
||||
// pub async fn close(&self) -> Result<(), String> {
|
||||
// self.inner.ws_meta.close().await.map_err(map_to_string).map(drop)
|
||||
// }
|
||||
|
||||
#[instrument(level = "trace", err, skip(self, message), fields(message.len = message.len()))]
|
||||
pub async fn send(&self, message: Vec<u8>) -> Result<(), String> {
|
||||
pub async fn send(&self, message: Vec<u8>) -> io::Result<()> {
|
||||
if message.len() > MAX_MESSAGE_SIZE {
|
||||
return Err("sending too large WS message".to_owned()).map_err(logthru_net!(error));
|
||||
bail_io_error_other!("sending too large WS message");
|
||||
}
|
||||
self.inner.ws_stream.clone()
|
||||
.send(WsMessage::Binary(message)).await
|
||||
|
@ -201,7 +201,7 @@ impl ReceiptManager {
|
||||
self.inner.lock().network_manager.clone()
|
||||
}
|
||||
|
||||
pub async fn startup(&self) -> Result<(), String> {
|
||||
pub async fn startup(&self) -> EyreResult<()> {
|
||||
trace!("startup receipt manager");
|
||||
// Retrieve config
|
||||
|
||||
@ -288,7 +288,7 @@ impl ReceiptManager {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn tick(&self) -> Result<(), String> {
|
||||
pub async fn tick(&self) -> EyreResult<()> {
|
||||
let (next_oldest_ts, timeout_task, stop_token) = {
|
||||
let inner = self.inner.lock();
|
||||
let stop_token = match inner.stop_source.as_ref() {
|
||||
@ -390,7 +390,7 @@ impl ReceiptManager {
|
||||
inner.next_oldest_ts = new_next_oldest_ts;
|
||||
}
|
||||
|
||||
pub async fn cancel_receipt(&self, nonce: &ReceiptNonce) -> Result<(), String> {
|
||||
pub async fn cancel_receipt(&self, nonce: &ReceiptNonce) -> EyreResult<()> {
|
||||
log_rpc!(debug "== Cancel Receipt {}", nonce.encode());
|
||||
|
||||
// Remove the record
|
||||
@ -399,7 +399,7 @@ impl ReceiptManager {
|
||||
let record = match inner.records_by_nonce.remove(nonce) {
|
||||
Some(r) => r,
|
||||
None => {
|
||||
return Err("receipt not recorded".to_owned());
|
||||
bail!("receipt not recorded");
|
||||
}
|
||||
};
|
||||
Self::update_next_oldest_timestamp(&mut *inner);
|
||||
@ -424,7 +424,7 @@ impl ReceiptManager {
|
||||
&self,
|
||||
receipt: Receipt,
|
||||
inbound_noderef: Option<NodeRef>,
|
||||
) -> Result<(), String> {
|
||||
) -> EyreResult<()> {
|
||||
let receipt_nonce = receipt.get_nonce();
|
||||
let extra_data = receipt.get_extra_data();
|
||||
|
||||
@ -456,7 +456,7 @@ impl ReceiptManager {
|
||||
let record = match inner.records_by_nonce.get(&receipt_nonce) {
|
||||
Some(r) => r.clone(),
|
||||
None => {
|
||||
return Err("receipt not recorded".to_owned());
|
||||
bail!("receipt not recorded");
|
||||
}
|
||||
};
|
||||
// Generate the callback future
|
||||
|
@ -69,12 +69,12 @@ pub struct RoutingTableHealth {
|
||||
|
||||
struct RoutingTableUnlockedInner {
|
||||
// Background processes
|
||||
rolling_transfers_task: TickTask,
|
||||
bootstrap_task: TickTask,
|
||||
peer_minimum_refresh_task: TickTask,
|
||||
ping_validator_task: TickTask,
|
||||
rolling_transfers_task: TickTask<EyreReport>,
|
||||
bootstrap_task: TickTask<EyreReport>,
|
||||
peer_minimum_refresh_task: TickTask<EyreReport>,
|
||||
ping_validator_task: TickTask<EyreReport>,
|
||||
node_info_update_single_future: MustJoinSingleFuture<()>,
|
||||
kick_buckets_task: TickTask,
|
||||
kick_buckets_task: TickTask<EyreReport>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -283,7 +283,7 @@ impl RoutingTable {
|
||||
domain: RoutingDomain,
|
||||
dial_info: DialInfo,
|
||||
class: DialInfoClass,
|
||||
) -> Result<(), String> {
|
||||
) -> EyreResult<()> {
|
||||
log_rtab!(debug
|
||||
"Registering dial_info with:\n domain: {:?}\n dial_info: {:?}\n class: {:?}",
|
||||
domain, dial_info, class
|
||||
@ -298,15 +298,13 @@ impl RoutingTable {
|
||||
&& matches!(domain, RoutingDomain::PublicInternet)
|
||||
&& dial_info.is_local()
|
||||
{
|
||||
return Err("shouldn't be registering local addresses as public".to_owned())
|
||||
.map_err(logthru_rtab!(error));
|
||||
bail!("shouldn't be registering local addresses as public");
|
||||
}
|
||||
if !dial_info.is_valid() {
|
||||
return Err(format!(
|
||||
bail!(
|
||||
"shouldn't be registering invalid addresses: {:?}",
|
||||
dial_info
|
||||
))
|
||||
.map_err(logthru_rtab!(error));
|
||||
);
|
||||
}
|
||||
|
||||
let mut inner = self.inner.write();
|
||||
@ -379,7 +377,7 @@ impl RoutingTable {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn init(&self) -> Result<(), String> {
|
||||
pub async fn init(&self) -> EyreResult<()> {
|
||||
let mut inner = self.inner.write();
|
||||
// Size the buckets (one per bit)
|
||||
inner.buckets.reserve(DHT_KEY_LENGTH * 8);
|
||||
@ -578,13 +576,13 @@ impl RoutingTable {
|
||||
// Create a node reference, possibly creating a bucket entry
|
||||
// the 'update_func' closure is called on the node, and, if created,
|
||||
// in a locked fashion as to ensure the bucket entry state is always valid
|
||||
pub fn create_node_ref<F>(&self, node_id: DHTKey, update_func: F) -> Result<NodeRef, String>
|
||||
pub fn create_node_ref<F>(&self, node_id: DHTKey, update_func: F) -> EyreResult<NodeRef>
|
||||
where
|
||||
F: FnOnce(&mut BucketEntryInner),
|
||||
{
|
||||
// Ensure someone isn't trying register this node itself
|
||||
if node_id == self.node_id() {
|
||||
return Err("can't register own node".to_owned()).map_err(logthru_rtab!(error));
|
||||
bail!("can't register own node");
|
||||
}
|
||||
|
||||
// Lock this entire operation
|
||||
@ -647,14 +645,14 @@ impl RoutingTable {
|
||||
&self,
|
||||
node_id: DHTKey,
|
||||
signed_node_info: SignedNodeInfo,
|
||||
) -> Result<NodeRef, String> {
|
||||
) -> EyreResult<NodeRef> {
|
||||
// validate signed node info is not something malicious
|
||||
if node_id == self.node_id() {
|
||||
return Err("can't register own node id in routing table".to_owned());
|
||||
bail!("can't register own node id in routing table");
|
||||
}
|
||||
if let Some(rpi) = &signed_node_info.node_info.relay_peer_info {
|
||||
if rpi.node_id.key == node_id {
|
||||
return Err("node can not be its own relay".to_owned());
|
||||
bail!("node can not be its own relay");
|
||||
}
|
||||
}
|
||||
|
||||
@ -672,7 +670,7 @@ impl RoutingTable {
|
||||
node_id: DHTKey,
|
||||
descriptor: ConnectionDescriptor,
|
||||
timestamp: u64,
|
||||
) -> Result<NodeRef, String> {
|
||||
) -> EyreResult<NodeRef> {
|
||||
let nr = self.create_node_ref(node_id, |e| {
|
||||
// set the most recent node address for connection finding and udp replies
|
||||
e.set_last_connection(descriptor, timestamp);
|
||||
@ -681,53 +679,9 @@ impl RoutingTable {
|
||||
Ok(nr)
|
||||
}
|
||||
|
||||
// fn operate_on_bucket_entry_inner_locked<T, F>(
|
||||
// inner: &RoutingTableInner,
|
||||
// node_id: DHTKey,
|
||||
// f: F,
|
||||
// ) -> T
|
||||
// where
|
||||
// F: FnOnce(&BucketEntryInner) -> T,
|
||||
// {
|
||||
// let idx = Self::find_bucket_index(&*inner, node_id);
|
||||
// let bucket = &inner.buckets[idx];
|
||||
// let entry = bucket.entry(&node_id).unwrap();
|
||||
// entry.with(f)
|
||||
// }
|
||||
|
||||
// fn operate_on_bucket_entry_inner_locked_mut<T, F>(
|
||||
// inner: &RoutingTableInner,
|
||||
// node_id: DHTKey,
|
||||
// f: F,
|
||||
// ) -> T
|
||||
// where
|
||||
// F: FnOnce(&mut BucketEntryInner) -> T,
|
||||
// {
|
||||
// let idx = Self::find_bucket_index(&*inner, node_id);
|
||||
// let bucket = &inner.buckets[idx];
|
||||
// let entry = bucket.entry(&node_id).unwrap();
|
||||
// entry.with_mut(f)
|
||||
// }
|
||||
|
||||
// fn operate_on_bucket_entry<T, F>(&self, node_id: DHTKey, f: F) -> T
|
||||
// where
|
||||
// F: FnOnce(&BucketEntryInner) -> T,
|
||||
// {
|
||||
// let inner = self.inner.read();
|
||||
// Self::operate_on_bucket_entry_inner_locked(&mut *inner, node_id, f)
|
||||
// }
|
||||
|
||||
// fn operate_on_bucket_entry_mut<T, F>(&self, node_id: DHTKey, f: F) -> T
|
||||
// where
|
||||
// F: FnOnce(&mut BucketEntryInner) -> T,
|
||||
// {
|
||||
// let inner = self.inner.read();
|
||||
// Self::operate_on_bucket_entry_inner_locked_mut(&*inner, node_id, f)
|
||||
// }
|
||||
|
||||
// Ticks about once per second
|
||||
// to run tick tasks which may run at slower tick rates as configured
|
||||
pub async fn tick(&self) -> Result<(), String> {
|
||||
pub async fn tick(&self) -> EyreResult<()> {
|
||||
// Do rolling transfers every ROLLING_TRANSFERS_INTERVAL_SECS secs
|
||||
self.unlocked_inner.rolling_transfers_task.tick().await?;
|
||||
|
||||
|
@ -13,7 +13,7 @@ impl RoutingTable {
|
||||
_stop_token: StopToken,
|
||||
last_ts: u64,
|
||||
cur_ts: u64,
|
||||
) -> Result<(), String> {
|
||||
) -> EyreResult<()> {
|
||||
// log_rtab!("--- rolling_transfers task");
|
||||
let mut inner = self.inner.write();
|
||||
let inner = &mut *inner;
|
||||
@ -37,7 +37,7 @@ impl RoutingTable {
|
||||
pub(super) async fn resolve_bootstrap(
|
||||
&self,
|
||||
bootstrap: Vec<String>,
|
||||
) -> Result<BootstrapRecordMap, String> {
|
||||
) -> EyreResult<BootstrapRecordMap> {
|
||||
// Resolve from bootstrap root to bootstrap hostnames
|
||||
let mut bsnames = Vec::<String>::new();
|
||||
for bh in bootstrap {
|
||||
@ -202,7 +202,7 @@ impl RoutingTable {
|
||||
self,
|
||||
stop_token: StopToken,
|
||||
bootstrap_dialinfos: Vec<DialInfo>,
|
||||
) -> Result<(), String> {
|
||||
) -> EyreResult<()> {
|
||||
let network_manager = self.network_manager();
|
||||
|
||||
let mut unord = FuturesUnordered::new();
|
||||
@ -219,9 +219,7 @@ impl RoutingTable {
|
||||
for pi in peer_info {
|
||||
let k = pi.node_id.key;
|
||||
// Register the node
|
||||
let nr = self
|
||||
.register_node_with_signed_node_info(k, pi.signed_node_info)
|
||||
.map_err(logthru_rtab!(error "Couldn't add bootstrap node: {}", k))?;
|
||||
let nr = self.register_node_with_signed_node_info(k, pi.signed_node_info)?;
|
||||
|
||||
// Add this our futures to process in parallel
|
||||
unord.push(
|
||||
@ -238,7 +236,7 @@ impl RoutingTable {
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self), err)]
|
||||
pub(super) async fn bootstrap_task_routine(self, stop_token: StopToken) -> Result<(), String> {
|
||||
pub(super) async fn bootstrap_task_routine(self, stop_token: StopToken) -> EyreResult<()> {
|
||||
let (bootstrap, bootstrap_nodes) = {
|
||||
let c = self.config.get();
|
||||
(
|
||||
@ -272,11 +270,7 @@ impl RoutingTable {
|
||||
let mut bootstrap_node_dial_infos = Vec::new();
|
||||
for b in bootstrap_nodes {
|
||||
let ndis = NodeDialInfo::from_str(b.as_str())
|
||||
.map_err(map_to_string)
|
||||
.map_err(logthru_rtab!(
|
||||
"Invalid node dial info in bootstrap entry: {}",
|
||||
b
|
||||
))?;
|
||||
.wrap_err("Invalid node dial info in bootstrap entry")?;
|
||||
bootstrap_node_dial_infos.push(ndis);
|
||||
}
|
||||
for ndi in bootstrap_node_dial_infos {
|
||||
@ -311,19 +305,17 @@ impl RoutingTable {
|
||||
log_rtab!("--- bootstrapping {} with {:?}", k.encode(), &v);
|
||||
|
||||
// Make invalid signed node info (no signature)
|
||||
let nr = self
|
||||
.register_node_with_signed_node_info(
|
||||
k,
|
||||
SignedNodeInfo::with_no_signature(NodeInfo {
|
||||
network_class: NetworkClass::InboundCapable, // Bootstraps are always inbound capable
|
||||
outbound_protocols: ProtocolSet::empty(), // Bootstraps do not participate in relaying and will not make outbound requests
|
||||
min_version: v.min_version, // Minimum protocol version specified in txt record
|
||||
max_version: v.max_version, // Maximum protocol version specified in txt record
|
||||
dial_info_detail_list: v.dial_info_details, // Dial info is as specified in the bootstrap list
|
||||
relay_peer_info: None, // Bootstraps never require a relay themselves
|
||||
}),
|
||||
)
|
||||
.map_err(logthru_rtab!(error "Couldn't add bootstrap node: {}", k))?;
|
||||
let nr = self.register_node_with_signed_node_info(
|
||||
k,
|
||||
SignedNodeInfo::with_no_signature(NodeInfo {
|
||||
network_class: NetworkClass::InboundCapable, // Bootstraps are always inbound capable
|
||||
outbound_protocols: ProtocolSet::empty(), // Bootstraps do not participate in relaying and will not make outbound requests
|
||||
min_version: v.min_version, // Minimum protocol version specified in txt record
|
||||
max_version: v.max_version, // Maximum protocol version specified in txt record
|
||||
dial_info_detail_list: v.dial_info_details, // Dial info is as specified in the bootstrap list
|
||||
relay_peer_info: None, // Bootstraps never require a relay themselves
|
||||
}),
|
||||
)?;
|
||||
|
||||
// Add this our futures to process in parallel
|
||||
let this = self.clone();
|
||||
@ -359,7 +351,7 @@ impl RoutingTable {
|
||||
stop_token: StopToken,
|
||||
_last_ts: u64,
|
||||
cur_ts: u64,
|
||||
) -> Result<(), String> {
|
||||
) -> EyreResult<()> {
|
||||
let rpc = self.rpc_processor();
|
||||
let netman = self.network_manager();
|
||||
let relay_node_id = netman.relay_node().map(|nr| nr.node_id());
|
||||
@ -389,7 +381,7 @@ impl RoutingTable {
|
||||
pub(super) async fn peer_minimum_refresh_task_routine(
|
||||
self,
|
||||
stop_token: StopToken,
|
||||
) -> Result<(), String> {
|
||||
) -> EyreResult<()> {
|
||||
// get list of all peers we know about, even the unreliable ones, and ask them to find nodes close to our node too
|
||||
let noderefs = {
|
||||
let inner = self.inner.read();
|
||||
@ -421,7 +413,7 @@ impl RoutingTable {
|
||||
_stop_token: StopToken,
|
||||
_last_ts: u64,
|
||||
cur_ts: u64,
|
||||
) -> Result<(), String> {
|
||||
) -> EyreResult<()> {
|
||||
let mut inner = self.inner.write();
|
||||
let kick_queue: Vec<usize> = inner.kick_queue.iter().map(|v| *v).collect();
|
||||
inner.kick_queue.clear();
|
||||
|
@ -55,6 +55,12 @@ 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],
|
||||
])))
|
||||
}
|
||||
_ => Err(rpc_error_protocol("invalid address type")),
|
||||
Ok(veilid_capnp::address::Which::Ipv4(Err(_))) => {
|
||||
Err(RPCError::protocol("invalid ipv4 address"))
|
||||
}
|
||||
Ok(veilid_capnp::address::Which::Ipv6(Err(_))) => {
|
||||
Err(RPCError::protocol("invalid ipv6 address"))
|
||||
}
|
||||
Err(_) => Err(RPCError::protocol("invalid address type")),
|
||||
}
|
||||
}
|
||||
|
@ -23,27 +23,19 @@ pub fn encode_block_id(
|
||||
builder: &mut veilid_capnp::b_l_a_k_e3_hash::Builder,
|
||||
) -> Result<(), RPCError> {
|
||||
if !key.valid {
|
||||
return Err(rpc_error_protocol("invalid key"));
|
||||
return Err(RPCError::protocol("invalid key"));
|
||||
}
|
||||
builder.set_u0(u64::from_be_bytes(
|
||||
key.bytes[0..8]
|
||||
.try_into()
|
||||
.map_err(map_error_protocol!("slice with incorrect length"))?,
|
||||
key.bytes[0..8].try_into().map_err(RPCError::internal)?,
|
||||
));
|
||||
builder.set_u1(u64::from_be_bytes(
|
||||
key.bytes[8..16]
|
||||
.try_into()
|
||||
.map_err(map_error_protocol!("slice with incorrect length"))?,
|
||||
key.bytes[8..16].try_into().map_err(RPCError::internal)?,
|
||||
));
|
||||
builder.set_u2(u64::from_be_bytes(
|
||||
key.bytes[16..24]
|
||||
.try_into()
|
||||
.map_err(map_error_protocol!("slice with incorrect length"))?,
|
||||
key.bytes[16..24].try_into().map_err(RPCError::internal)?,
|
||||
));
|
||||
builder.set_u3(u64::from_be_bytes(
|
||||
key.bytes[24..32]
|
||||
.try_into()
|
||||
.map_err(map_error_protocol!("slice with incorrect length"))?,
|
||||
key.bytes[24..32].try_into().map_err(RPCError::internal)?,
|
||||
));
|
||||
Ok(())
|
||||
}
|
||||
|
@ -4,44 +4,51 @@ use core::convert::TryInto;
|
||||
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))) => {
|
||||
match reader
|
||||
.reborrow()
|
||||
.which()
|
||||
.map_err(RPCError::map_protocol("Missing dial info type"))?
|
||||
{
|
||||
veilid_capnp::dial_info::Which::Udp(udp) => {
|
||||
let socket_address_reader = udp
|
||||
.map_err(RPCError::protocol)?
|
||||
.get_socket_address()
|
||||
.map_err(map_error_protocol!("missing UDP socketAddress"))?;
|
||||
.map_err(RPCError::map_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))) => {
|
||||
veilid_capnp::dial_info::Which::Tcp(tcp) => {
|
||||
let socket_address_reader = tcp
|
||||
.map_err(RPCError::protocol)?
|
||||
.get_socket_address()
|
||||
.map_err(map_error_protocol!("missing TCP socketAddress"))?;
|
||||
.map_err(RPCError::map_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))) => {
|
||||
veilid_capnp::dial_info::Which::Ws(ws) => {
|
||||
let ws = ws.map_err(RPCError::protocol)?;
|
||||
let socket_address_reader = ws
|
||||
.get_socket_address()
|
||||
.map_err(map_error_protocol!("missing WS socketAddress"))?;
|
||||
.map_err(RPCError::map_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"))?;
|
||||
.map_err(RPCError::map_protocol("missing WS request"))?;
|
||||
DialInfo::try_ws(socket_address, request.to_owned())
|
||||
.map_err(map_error_protocol!("invalid WS dial info"))
|
||||
.map_err(RPCError::map_protocol("invalid WS dial info"))
|
||||
}
|
||||
Ok(veilid_capnp::dial_info::Which::Wss(Ok(wss))) => {
|
||||
veilid_capnp::dial_info::Which::Wss(wss) => {
|
||||
let wss = wss.map_err(RPCError::protocol)?;
|
||||
let socket_address_reader = wss
|
||||
.get_socket_address()
|
||||
.map_err(map_error_protocol!("missing WSS socketAddress"))?;
|
||||
.map_err(RPCError::map_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"))?;
|
||||
.map_err(RPCError::map_protocol("missing WSS request"))?;
|
||||
DialInfo::try_wss(socket_address, request.to_owned())
|
||||
.map_err(map_error_protocol!("invalid WSS dial info"))
|
||||
.map_err(RPCError::map_protocol("invalid WSS dial info"))
|
||||
}
|
||||
_ => Err(rpc_error_internal("invalid dial info type")),
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,13 +79,13 @@ pub fn encode_dial_info(
|
||||
)?;
|
||||
let request = dial_info
|
||||
.request()
|
||||
.ok_or_else(|| rpc_error_internal("no request for WS dialinfo"))?;
|
||||
.ok_or_else(RPCError::else_internal("no request for WS dialinfo"))?;
|
||||
|
||||
let mut requestb = di_ws_builder.init_request(
|
||||
request
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(map_error_protocol!("request too long"))?,
|
||||
.map_err(RPCError::map_protocol("request too long"))?,
|
||||
);
|
||||
requestb.push_str(request.as_str());
|
||||
}
|
||||
@ -90,13 +97,13 @@ pub fn encode_dial_info(
|
||||
)?;
|
||||
let request = dial_info
|
||||
.request()
|
||||
.ok_or_else(|| rpc_error_internal("no request for WSS dialinfo"))?;
|
||||
.ok_or_else(RPCError::else_internal("no request for WSS dialinfo"))?;
|
||||
|
||||
let mut requestb = di_wss_builder.init_request(
|
||||
request
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(map_error_protocol!("request too long"))?,
|
||||
.map_err(RPCError::map_protocol("request too long"))?,
|
||||
);
|
||||
requestb.push_str(request.as_str());
|
||||
}
|
||||
|
@ -19,15 +19,10 @@ pub fn decode_dial_info_detail(
|
||||
&reader
|
||||
.reborrow()
|
||||
.get_dial_info()
|
||||
.map_err(map_error_capnp_error!())?,
|
||||
.map_err(RPCError::protocol)?,
|
||||
)?;
|
||||
|
||||
let class = decode_dial_info_class(
|
||||
reader
|
||||
.reborrow()
|
||||
.get_class()
|
||||
.map_err(map_error_capnp_notinschema!())?,
|
||||
);
|
||||
let class = decode_dial_info_class(reader.reborrow().get_class().map_err(RPCError::protocol)?);
|
||||
|
||||
Ok(DialInfoDetail { dial_info, class })
|
||||
}
|
||||
|
@ -15,16 +15,12 @@ pub fn encode_node_dial_info(
|
||||
pub fn decode_node_dial_info(
|
||||
reader: &veilid_capnp::node_dial_info::Reader,
|
||||
) -> Result<NodeDialInfo, RPCError> {
|
||||
let node_id = decode_public_key(
|
||||
&reader
|
||||
.get_node_id()
|
||||
.map_err(map_error_protocol!("invalid public key in node_dial_info"))?,
|
||||
);
|
||||
let dial_info = decode_dial_info(
|
||||
&reader
|
||||
.get_dial_info()
|
||||
.map_err(map_error_protocol!("invalid dial_info in node_dial_info"))?,
|
||||
)?;
|
||||
let node_id = decode_public_key(&reader.get_node_id().map_err(RPCError::map_protocol(
|
||||
"invalid public key in node_dial_info",
|
||||
))?);
|
||||
let dial_info = decode_dial_info(&reader.get_dial_info().map_err(RPCError::map_protocol(
|
||||
"invalid dial_info in node_dial_info",
|
||||
))?)?;
|
||||
|
||||
Ok(NodeDialInfo {
|
||||
node_id: NodeId::new(node_id),
|
||||
|
@ -18,8 +18,8 @@ pub fn encode_node_info(
|
||||
.dial_info_detail_list
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(map_error_protocol!(
|
||||
"too many dial info details in node info"
|
||||
.map_err(RPCError::map_protocol(
|
||||
"too many dial info details in node info",
|
||||
))?,
|
||||
);
|
||||
|
||||
@ -44,14 +44,14 @@ pub fn decode_node_info(
|
||||
reader
|
||||
.reborrow()
|
||||
.get_network_class()
|
||||
.map_err(map_error_capnp_notinschema!())?,
|
||||
.map_err(RPCError::protocol)?,
|
||||
);
|
||||
|
||||
let outbound_protocols = decode_protocol_set(
|
||||
&reader
|
||||
.reborrow()
|
||||
.get_outbound_protocols()
|
||||
.map_err(map_error_capnp_error!())?,
|
||||
.map_err(RPCError::protocol)?,
|
||||
)?;
|
||||
|
||||
let min_version = reader.reborrow().get_min_version();
|
||||
@ -60,12 +60,12 @@ pub fn decode_node_info(
|
||||
let didl_reader = reader
|
||||
.reborrow()
|
||||
.get_dial_info_detail_list()
|
||||
.map_err(map_error_capnp_error!())?;
|
||||
.map_err(RPCError::protocol)?;
|
||||
let mut dial_info_detail_list = Vec::<DialInfoDetail>::with_capacity(
|
||||
didl_reader
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(map_error_protocol!("too many dial info details"))?,
|
||||
.map_err(RPCError::map_protocol("too many dial info details"))?,
|
||||
);
|
||||
for did in didl_reader.iter() {
|
||||
dial_info_detail_list.push(decode_dial_info_detail(&did)?)
|
||||
@ -77,7 +77,7 @@ pub fn decode_node_info(
|
||||
&reader
|
||||
.reborrow()
|
||||
.get_relay_peer_info()
|
||||
.map_err(map_error_capnp_error!())?,
|
||||
.map_err(RPCError::protocol)?,
|
||||
false,
|
||||
)?))
|
||||
} else {
|
||||
|
@ -64,55 +64,55 @@ impl RPCAnswerDetail {
|
||||
pub fn decode(
|
||||
reader: &veilid_capnp::answer::detail::Reader,
|
||||
) -> Result<RPCAnswerDetail, RPCError> {
|
||||
let which_reader = reader.which().map_err(map_error_capnp_notinschema!())?;
|
||||
let which_reader = reader.which().map_err(RPCError::protocol)?;
|
||||
let out = match which_reader {
|
||||
veilid_capnp::answer::detail::StatusA(r) => {
|
||||
let op_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let op_reader = r.map_err(RPCError::protocol)?;
|
||||
let out = RPCOperationStatusA::decode(&op_reader)?;
|
||||
RPCAnswerDetail::StatusA(out)
|
||||
}
|
||||
veilid_capnp::answer::detail::FindNodeA(r) => {
|
||||
let op_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let op_reader = r.map_err(RPCError::protocol)?;
|
||||
let out = RPCOperationFindNodeA::decode(&op_reader)?;
|
||||
RPCAnswerDetail::FindNodeA(out)
|
||||
}
|
||||
veilid_capnp::answer::detail::GetValueA(r) => {
|
||||
let op_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let op_reader = r.map_err(RPCError::protocol)?;
|
||||
let out = RPCOperationGetValueA::decode(&op_reader)?;
|
||||
RPCAnswerDetail::GetValueA(out)
|
||||
}
|
||||
veilid_capnp::answer::detail::SetValueA(r) => {
|
||||
let op_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let op_reader = r.map_err(RPCError::protocol)?;
|
||||
let out = RPCOperationSetValueA::decode(&op_reader)?;
|
||||
RPCAnswerDetail::SetValueA(out)
|
||||
}
|
||||
veilid_capnp::answer::detail::WatchValueA(r) => {
|
||||
let op_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let op_reader = r.map_err(RPCError::protocol)?;
|
||||
let out = RPCOperationWatchValueA::decode(&op_reader)?;
|
||||
RPCAnswerDetail::WatchValueA(out)
|
||||
}
|
||||
veilid_capnp::answer::detail::SupplyBlockA(r) => {
|
||||
let op_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let op_reader = r.map_err(RPCError::protocol)?;
|
||||
let out = RPCOperationSupplyBlockA::decode(&op_reader)?;
|
||||
RPCAnswerDetail::SupplyBlockA(out)
|
||||
}
|
||||
veilid_capnp::answer::detail::FindBlockA(r) => {
|
||||
let op_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let op_reader = r.map_err(RPCError::protocol)?;
|
||||
let out = RPCOperationFindBlockA::decode(&op_reader)?;
|
||||
RPCAnswerDetail::FindBlockA(out)
|
||||
}
|
||||
veilid_capnp::answer::detail::StartTunnelA(r) => {
|
||||
let op_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let op_reader = r.map_err(RPCError::protocol)?;
|
||||
let out = RPCOperationStartTunnelA::decode(&op_reader)?;
|
||||
RPCAnswerDetail::StartTunnelA(out)
|
||||
}
|
||||
veilid_capnp::answer::detail::CompleteTunnelA(r) => {
|
||||
let op_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let op_reader = r.map_err(RPCError::protocol)?;
|
||||
let out = RPCOperationCompleteTunnelA::decode(&op_reader)?;
|
||||
RPCAnswerDetail::CompleteTunnelA(out)
|
||||
}
|
||||
veilid_capnp::answer::detail::CancelTunnelA(r) => {
|
||||
let op_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let op_reader = r.map_err(RPCError::protocol)?;
|
||||
let out = RPCOperationCancelTunnelA::decode(&op_reader)?;
|
||||
RPCAnswerDetail::CancelTunnelA(out)
|
||||
}
|
||||
|
@ -21,22 +21,20 @@ impl RPCOperationKind {
|
||||
kind_reader: &veilid_capnp::operation::kind::Reader,
|
||||
sender_node_id: &DHTKey,
|
||||
) -> Result<Self, RPCError> {
|
||||
let which_reader = kind_reader
|
||||
.which()
|
||||
.map_err(map_error_capnp_notinschema!())?;
|
||||
let which_reader = kind_reader.which().map_err(RPCError::protocol)?;
|
||||
let out = match which_reader {
|
||||
veilid_capnp::operation::kind::Which::Question(r) => {
|
||||
let q_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let q_reader = r.map_err(RPCError::protocol)?;
|
||||
let out = RPCQuestion::decode(&q_reader, sender_node_id)?;
|
||||
RPCOperationKind::Question(out)
|
||||
}
|
||||
veilid_capnp::operation::kind::Which::Statement(r) => {
|
||||
let q_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let q_reader = r.map_err(RPCError::protocol)?;
|
||||
let out = RPCStatement::decode(&q_reader, sender_node_id)?;
|
||||
RPCOperationKind::Statement(out)
|
||||
}
|
||||
veilid_capnp::operation::kind::Which::Answer(r) => {
|
||||
let q_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let q_reader = r.map_err(RPCError::protocol)?;
|
||||
let out = RPCAnswer::decode(&q_reader)?;
|
||||
RPCOperationKind::Answer(out)
|
||||
}
|
||||
|
@ -34,12 +34,12 @@ impl RPCOperationCancelTunnelA {
|
||||
pub fn decode(
|
||||
reader: &veilid_capnp::operation_cancel_tunnel_a::Reader,
|
||||
) -> Result<RPCOperationCancelTunnelA, RPCError> {
|
||||
match reader.which().map_err(map_error_capnp_notinschema!())? {
|
||||
match reader.which().map_err(RPCError::protocol)? {
|
||||
veilid_capnp::operation_cancel_tunnel_a::Which::Tunnel(r) => {
|
||||
Ok(RPCOperationCancelTunnelA::Tunnel(r))
|
||||
}
|
||||
veilid_capnp::operation_cancel_tunnel_a::Which::Error(r) => {
|
||||
let tunnel_error = decode_tunnel_error(r.map_err(map_error_capnp_notinschema!())?);
|
||||
let tunnel_error = decode_tunnel_error(r.map_err(RPCError::protocol)?);
|
||||
Ok(RPCOperationCancelTunnelA::Error(tunnel_error))
|
||||
}
|
||||
}
|
||||
|
@ -14,15 +14,12 @@ impl RPCOperationCompleteTunnelQ {
|
||||
reader: &veilid_capnp::operation_complete_tunnel_q::Reader,
|
||||
) -> Result<RPCOperationCompleteTunnelQ, RPCError> {
|
||||
let id = reader.get_id();
|
||||
let local_mode = match reader
|
||||
.get_local_mode()
|
||||
.map_err(map_error_capnp_notinschema!())?
|
||||
{
|
||||
let local_mode = match reader.get_local_mode().map_err(RPCError::protocol)? {
|
||||
veilid_capnp::TunnelEndpointMode::Raw => TunnelMode::Raw,
|
||||
veilid_capnp::TunnelEndpointMode::Turn => TunnelMode::Turn,
|
||||
};
|
||||
let depth = reader.get_depth();
|
||||
let te_reader = reader.get_endpoint().map_err(map_error_capnp_error!())?;
|
||||
let te_reader = reader.get_endpoint().map_err(RPCError::protocol)?;
|
||||
let endpoint = decode_tunnel_endpoint(&te_reader)?;
|
||||
|
||||
Ok(RPCOperationCompleteTunnelQ {
|
||||
@ -59,14 +56,14 @@ impl RPCOperationCompleteTunnelA {
|
||||
pub fn decode(
|
||||
reader: &veilid_capnp::operation_complete_tunnel_a::Reader,
|
||||
) -> Result<RPCOperationCompleteTunnelA, RPCError> {
|
||||
match reader.which().map_err(map_error_capnp_notinschema!())? {
|
||||
match reader.which().map_err(RPCError::protocol)? {
|
||||
veilid_capnp::operation_complete_tunnel_a::Which::Tunnel(r) => {
|
||||
let ft_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let ft_reader = r.map_err(RPCError::protocol)?;
|
||||
let full_tunnel = decode_full_tunnel(&ft_reader)?;
|
||||
Ok(RPCOperationCompleteTunnelA::Tunnel(full_tunnel))
|
||||
}
|
||||
veilid_capnp::operation_complete_tunnel_a::Which::Error(r) => {
|
||||
let tunnel_error = decode_tunnel_error(r.map_err(map_error_capnp_notinschema!())?);
|
||||
let tunnel_error = decode_tunnel_error(r.map_err(RPCError::protocol)?);
|
||||
Ok(RPCOperationCompleteTunnelA::Error(tunnel_error))
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ impl RPCOperationFindBlockQ {
|
||||
pub fn decode(
|
||||
reader: &veilid_capnp::operation_find_block_q::Reader,
|
||||
) -> Result<RPCOperationFindBlockQ, RPCError> {
|
||||
let bi_reader = reader.get_block_id().map_err(map_error_capnp_error!())?;
|
||||
let bi_reader = reader.get_block_id().map_err(RPCError::protocol)?;
|
||||
let block_id = decode_block_id(&bi_reader);
|
||||
|
||||
Ok(RPCOperationFindBlockQ { block_id })
|
||||
@ -37,29 +37,26 @@ impl RPCOperationFindBlockA {
|
||||
pub fn decode(
|
||||
reader: &veilid_capnp::operation_find_block_a::Reader,
|
||||
) -> Result<RPCOperationFindBlockA, RPCError> {
|
||||
let data = reader
|
||||
.get_data()
|
||||
.map_err(map_error_capnp_error!())?
|
||||
.to_vec();
|
||||
let data = reader.get_data().map_err(RPCError::protocol)?.to_vec();
|
||||
|
||||
let suppliers_reader = reader.get_suppliers().map_err(map_error_capnp_error!())?;
|
||||
let suppliers_reader = reader.get_suppliers().map_err(RPCError::protocol)?;
|
||||
let mut suppliers = Vec::<PeerInfo>::with_capacity(
|
||||
suppliers_reader
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(map_error_internal!("too many suppliers"))?,
|
||||
.map_err(RPCError::map_internal("too many suppliers"))?,
|
||||
);
|
||||
for s in suppliers_reader.iter() {
|
||||
let peer_info = decode_peer_info(&s, true)?;
|
||||
suppliers.push(peer_info);
|
||||
}
|
||||
|
||||
let peers_reader = reader.get_peers().map_err(map_error_capnp_error!())?;
|
||||
let peers_reader = reader.get_peers().map_err(RPCError::protocol)?;
|
||||
let mut peers = Vec::<PeerInfo>::with_capacity(
|
||||
peers_reader
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(map_error_internal!("too many peers"))?,
|
||||
.map_err(RPCError::map_internal("too many peers"))?,
|
||||
);
|
||||
for p in peers_reader.iter() {
|
||||
let peer_info = decode_peer_info(&p, true)?;
|
||||
@ -83,7 +80,7 @@ impl RPCOperationFindBlockA {
|
||||
self.suppliers
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(map_error_internal!("invalid suppliers list length"))?,
|
||||
.map_err(RPCError::map_internal("invalid suppliers list length"))?,
|
||||
);
|
||||
for (i, peer) in self.suppliers.iter().enumerate() {
|
||||
let mut pi_builder = suppliers_builder.reborrow().get(i as u32);
|
||||
@ -94,7 +91,7 @@ impl RPCOperationFindBlockA {
|
||||
self.peers
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(map_error_internal!("invalid peers list length"))?,
|
||||
.map_err(RPCError::map_internal("invalid peers list length"))?,
|
||||
);
|
||||
for (i, peer) in self.peers.iter().enumerate() {
|
||||
let mut pi_builder = peers_builder.reborrow().get(i as u32);
|
||||
|
@ -10,7 +10,7 @@ impl RPCOperationFindNodeQ {
|
||||
pub fn decode(
|
||||
reader: &veilid_capnp::operation_find_node_q::Reader,
|
||||
) -> Result<RPCOperationFindNodeQ, RPCError> {
|
||||
let ni_reader = reader.get_node_id().map_err(map_error_capnp_error!())?;
|
||||
let ni_reader = reader.get_node_id().map_err(RPCError::protocol)?;
|
||||
let node_id = decode_public_key(&ni_reader);
|
||||
Ok(RPCOperationFindNodeQ { node_id })
|
||||
}
|
||||
@ -33,12 +33,12 @@ impl RPCOperationFindNodeA {
|
||||
pub fn decode(
|
||||
reader: &veilid_capnp::operation_find_node_a::Reader,
|
||||
) -> Result<RPCOperationFindNodeA, RPCError> {
|
||||
let peers_reader = reader.get_peers().map_err(map_error_capnp_error!())?;
|
||||
let peers_reader = reader.get_peers().map_err(RPCError::protocol)?;
|
||||
let mut peers = Vec::<PeerInfo>::with_capacity(
|
||||
peers_reader
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(map_error_internal!("too many peers"))?,
|
||||
.map_err(RPCError::map_internal("too many peers"))?,
|
||||
);
|
||||
for p in peers_reader.iter() {
|
||||
let peer_info = decode_peer_info(&p, true)?;
|
||||
@ -55,7 +55,7 @@ impl RPCOperationFindNodeA {
|
||||
self.peers
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(map_error_internal!("invalid closest nodes list length"))?,
|
||||
.map_err(RPCError::map_internal("invalid closest nodes list length"))?,
|
||||
);
|
||||
for (i, peer) in self.peers.iter().enumerate() {
|
||||
let mut pi_builder = peers_builder.reborrow().get(i as u32);
|
||||
|
@ -10,7 +10,7 @@ impl RPCOperationGetValueQ {
|
||||
pub fn decode(
|
||||
reader: &veilid_capnp::operation_get_value_q::Reader,
|
||||
) -> Result<RPCOperationGetValueQ, RPCError> {
|
||||
let k_reader = reader.get_key().map_err(map_error_capnp_error!())?;
|
||||
let k_reader = reader.get_key().map_err(RPCError::protocol)?;
|
||||
let key = decode_value_key(&k_reader)?;
|
||||
Ok(RPCOperationGetValueQ { key })
|
||||
}
|
||||
@ -34,18 +34,18 @@ impl RPCOperationGetValueA {
|
||||
pub fn decode(
|
||||
reader: &veilid_capnp::operation_get_value_a::Reader,
|
||||
) -> Result<RPCOperationGetValueA, RPCError> {
|
||||
match reader.which().map_err(map_error_capnp_notinschema!())? {
|
||||
match reader.which().map_err(RPCError::protocol)? {
|
||||
veilid_capnp::operation_get_value_a::Which::Data(r) => {
|
||||
let data = decode_value_data(&r.map_err(map_error_capnp_error!())?)?;
|
||||
let data = decode_value_data(&r.map_err(RPCError::protocol)?)?;
|
||||
Ok(RPCOperationGetValueA::Data(data))
|
||||
}
|
||||
veilid_capnp::operation_get_value_a::Which::Peers(r) => {
|
||||
let peers_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let peers_reader = r.map_err(RPCError::protocol)?;
|
||||
let mut peers = Vec::<PeerInfo>::with_capacity(
|
||||
peers_reader
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(map_error_internal!("too many peers"))?,
|
||||
.map_err(RPCError::map_internal("too many peers"))?,
|
||||
);
|
||||
for p in peers_reader.iter() {
|
||||
let peer_info = decode_peer_info(&p, true)?;
|
||||
@ -70,7 +70,7 @@ impl RPCOperationGetValueA {
|
||||
peers
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(map_error_internal!("invalid peers list length"))?,
|
||||
.map_err(RPCError::map_internal("invalid peers list length"))?,
|
||||
);
|
||||
for (i, peer) in peers.iter().enumerate() {
|
||||
let mut pi_builder = peers_builder.reborrow().get(i as u32);
|
||||
|
@ -11,9 +11,7 @@ impl RPCOperationNodeInfoUpdate {
|
||||
reader: &veilid_capnp::operation_node_info_update::Reader,
|
||||
sender_node_id: &DHTKey,
|
||||
) -> Result<RPCOperationNodeInfoUpdate, RPCError> {
|
||||
let sni_reader = reader
|
||||
.get_signed_node_info()
|
||||
.map_err(map_error_capnp_error!())?;
|
||||
let sni_reader = reader.get_signed_node_info().map_err(RPCError::protocol)?;
|
||||
let signed_node_info = decode_signed_node_info(&sni_reader, sender_node_id, true)?;
|
||||
|
||||
Ok(RPCOperationNodeInfoUpdate { signed_node_info })
|
||||
|
@ -10,7 +10,7 @@ impl RPCOperationReturnReceipt {
|
||||
pub fn decode(
|
||||
reader: &veilid_capnp::operation_return_receipt::Reader,
|
||||
) -> Result<RPCOperationReturnReceipt, RPCError> {
|
||||
let rcpt_reader = reader.get_receipt().map_err(map_error_capnp_error!())?;
|
||||
let rcpt_reader = reader.get_receipt().map_err(RPCError::protocol)?;
|
||||
let receipt = rcpt_reader.to_vec();
|
||||
|
||||
Ok(RPCOperationReturnReceipt { receipt })
|
||||
|
@ -20,24 +20,21 @@ impl RoutedOperation {
|
||||
pub fn decode(
|
||||
reader: &veilid_capnp::routed_operation::Reader,
|
||||
) -> Result<RoutedOperation, RPCError> {
|
||||
let sigs_reader = reader.get_signatures().map_err(map_error_capnp_error!())?;
|
||||
let sigs_reader = reader.get_signatures().map_err(RPCError::protocol)?;
|
||||
let mut signatures = Vec::<DHTSignature>::with_capacity(
|
||||
sigs_reader
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(map_error_internal!("too many signatures"))?,
|
||||
.map_err(RPCError::map_internal("too many signatures"))?,
|
||||
);
|
||||
for s in sigs_reader.iter() {
|
||||
let sig = decode_signature(&s);
|
||||
signatures.push(sig);
|
||||
}
|
||||
|
||||
let n_reader = reader.get_nonce().map_err(map_error_capnp_error!())?;
|
||||
let n_reader = reader.get_nonce().map_err(RPCError::protocol)?;
|
||||
let nonce = decode_nonce(&n_reader);
|
||||
let data = reader
|
||||
.get_data()
|
||||
.map_err(map_error_capnp_error!())?
|
||||
.to_vec();
|
||||
let data = reader.get_data().map_err(RPCError::protocol)?.to_vec();
|
||||
|
||||
Ok(RoutedOperation {
|
||||
signatures,
|
||||
@ -54,7 +51,7 @@ impl RoutedOperation {
|
||||
self.signatures
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(map_error_internal!("invalid signatures list length"))?,
|
||||
.map_err(RPCError::map_internal("invalid signatures list length"))?,
|
||||
);
|
||||
for (i, sig) in self.signatures.iter().enumerate() {
|
||||
let mut sig_builder = sigs_builder.reborrow().get(i as u32);
|
||||
@ -78,12 +75,10 @@ impl RPCOperationRoute {
|
||||
pub fn decode(
|
||||
reader: &veilid_capnp::operation_route::Reader,
|
||||
) -> Result<RPCOperationRoute, RPCError> {
|
||||
let sr_reader = reader
|
||||
.get_safety_route()
|
||||
.map_err(map_error_capnp_error!())?;
|
||||
let sr_reader = reader.get_safety_route().map_err(RPCError::protocol)?;
|
||||
let safety_route = decode_safety_route(&sr_reader)?;
|
||||
|
||||
let o_reader = reader.get_operation().map_err(map_error_capnp_error!())?;
|
||||
let o_reader = reader.get_operation().map_err(RPCError::protocol)?;
|
||||
let operation = RoutedOperation::decode(&o_reader)?;
|
||||
|
||||
Ok(RPCOperationRoute {
|
||||
|
@ -11,9 +11,9 @@ impl RPCOperationSetValueQ {
|
||||
pub fn decode(
|
||||
reader: &veilid_capnp::operation_set_value_q::Reader,
|
||||
) -> Result<RPCOperationSetValueQ, RPCError> {
|
||||
let k_reader = reader.get_key().map_err(map_error_capnp_error!())?;
|
||||
let k_reader = reader.get_key().map_err(RPCError::protocol)?;
|
||||
let key = decode_value_key(&k_reader)?;
|
||||
let v_reader = reader.get_value().map_err(map_error_capnp_error!())?;
|
||||
let v_reader = reader.get_value().map_err(RPCError::protocol)?;
|
||||
let value = decode_value_data(&v_reader)?;
|
||||
Ok(RPCOperationSetValueQ { key, value })
|
||||
}
|
||||
@ -39,18 +39,18 @@ impl RPCOperationSetValueA {
|
||||
pub fn decode(
|
||||
reader: &veilid_capnp::operation_set_value_a::Reader,
|
||||
) -> Result<RPCOperationSetValueA, RPCError> {
|
||||
match reader.which().map_err(map_error_capnp_notinschema!())? {
|
||||
match reader.which().map_err(RPCError::protocol)? {
|
||||
veilid_capnp::operation_set_value_a::Which::Data(r) => {
|
||||
let data = decode_value_data(&r.map_err(map_error_capnp_error!())?)?;
|
||||
let data = decode_value_data(&r.map_err(RPCError::protocol)?)?;
|
||||
Ok(RPCOperationSetValueA::Data(data))
|
||||
}
|
||||
veilid_capnp::operation_set_value_a::Which::Peers(r) => {
|
||||
let peers_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let peers_reader = r.map_err(RPCError::protocol)?;
|
||||
let mut peers = Vec::<PeerInfo>::with_capacity(
|
||||
peers_reader
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(map_error_internal!("too many peers"))?,
|
||||
.map_err(RPCError::map_internal("too many peers"))?,
|
||||
);
|
||||
for p in peers_reader.iter() {
|
||||
let peer_info = decode_peer_info(&p, true)?;
|
||||
@ -75,7 +75,7 @@ impl RPCOperationSetValueA {
|
||||
peers
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(map_error_internal!("invalid peers list length"))?,
|
||||
.map_err(RPCError::map_internal("invalid peers list length"))?,
|
||||
);
|
||||
for (i, peer) in peers.iter().enumerate() {
|
||||
let mut pi_builder = peers_builder.reborrow().get(i as u32);
|
||||
|
@ -13,10 +13,7 @@ impl RPCOperationStartTunnelQ {
|
||||
reader: &veilid_capnp::operation_start_tunnel_q::Reader,
|
||||
) -> Result<RPCOperationStartTunnelQ, RPCError> {
|
||||
let id = reader.get_id();
|
||||
let local_mode = match reader
|
||||
.get_local_mode()
|
||||
.map_err(map_error_capnp_notinschema!())?
|
||||
{
|
||||
let local_mode = match reader.get_local_mode().map_err(RPCError::protocol)? {
|
||||
veilid_capnp::TunnelEndpointMode::Raw => TunnelMode::Raw,
|
||||
veilid_capnp::TunnelEndpointMode::Turn => TunnelMode::Turn,
|
||||
};
|
||||
@ -53,14 +50,14 @@ impl RPCOperationStartTunnelA {
|
||||
pub fn decode(
|
||||
reader: &veilid_capnp::operation_start_tunnel_a::Reader,
|
||||
) -> Result<RPCOperationStartTunnelA, RPCError> {
|
||||
match reader.which().map_err(map_error_capnp_notinschema!())? {
|
||||
match reader.which().map_err(RPCError::protocol)? {
|
||||
veilid_capnp::operation_start_tunnel_a::Which::Partial(r) => {
|
||||
let pt_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let pt_reader = r.map_err(RPCError::protocol)?;
|
||||
let partial_tunnel = decode_partial_tunnel(&pt_reader)?;
|
||||
Ok(RPCOperationStartTunnelA::Partial(partial_tunnel))
|
||||
}
|
||||
veilid_capnp::operation_start_tunnel_a::Which::Error(r) => {
|
||||
let tunnel_error = decode_tunnel_error(r.map_err(map_error_capnp_notinschema!())?);
|
||||
let tunnel_error = decode_tunnel_error(r.map_err(RPCError::protocol)?);
|
||||
Ok(RPCOperationStartTunnelA::Error(tunnel_error))
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ impl RPCOperationStatusQ {
|
||||
pub fn decode(
|
||||
reader: &veilid_capnp::operation_status_q::Reader,
|
||||
) -> Result<RPCOperationStatusQ, RPCError> {
|
||||
let ns_reader = reader.get_node_status().map_err(map_error_capnp_error!())?;
|
||||
let ns_reader = reader.get_node_status().map_err(RPCError::protocol)?;
|
||||
let node_status = decode_node_status(&ns_reader)?;
|
||||
Ok(RPCOperationStatusQ { node_status })
|
||||
}
|
||||
@ -34,10 +34,10 @@ impl RPCOperationStatusA {
|
||||
pub fn decode(
|
||||
reader: &veilid_capnp::operation_status_a::Reader,
|
||||
) -> Result<RPCOperationStatusA, RPCError> {
|
||||
let ns_reader = reader.get_node_status().map_err(map_error_capnp_error!())?;
|
||||
let ns_reader = reader.get_node_status().map_err(RPCError::protocol)?;
|
||||
let node_status = decode_node_status(&ns_reader)?;
|
||||
|
||||
let si_reader = reader.get_sender_info().map_err(map_error_capnp_error!())?;
|
||||
let si_reader = reader.get_sender_info().map_err(RPCError::protocol)?;
|
||||
let sender_info = decode_sender_info(&si_reader)?;
|
||||
|
||||
Ok(RPCOperationStatusA {
|
||||
|
@ -10,7 +10,7 @@ impl RPCOperationSupplyBlockQ {
|
||||
pub fn decode(
|
||||
reader: &veilid_capnp::operation_supply_block_q::Reader,
|
||||
) -> Result<RPCOperationSupplyBlockQ, RPCError> {
|
||||
let bi_reader = reader.get_block_id().map_err(map_error_capnp_error!())?;
|
||||
let bi_reader = reader.get_block_id().map_err(RPCError::protocol)?;
|
||||
let block_id = decode_block_id(&bi_reader);
|
||||
|
||||
Ok(RPCOperationSupplyBlockQ { block_id })
|
||||
@ -36,17 +36,17 @@ impl RPCOperationSupplyBlockA {
|
||||
pub fn decode(
|
||||
reader: &veilid_capnp::operation_supply_block_a::Reader,
|
||||
) -> Result<RPCOperationSupplyBlockA, RPCError> {
|
||||
match reader.which().map_err(map_error_capnp_notinschema!())? {
|
||||
match reader.which().map_err(RPCError::protocol)? {
|
||||
veilid_capnp::operation_supply_block_a::Which::Expiration(r) => {
|
||||
Ok(RPCOperationSupplyBlockA::Expiration(r))
|
||||
}
|
||||
veilid_capnp::operation_supply_block_a::Which::Peers(r) => {
|
||||
let peers_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let peers_reader = r.map_err(RPCError::protocol)?;
|
||||
let mut peers = Vec::<PeerInfo>::with_capacity(
|
||||
peers_reader
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(map_error_internal!("too many peers"))?,
|
||||
.map_err(RPCError::map_internal("too many peers"))?,
|
||||
);
|
||||
for p in peers_reader.iter() {
|
||||
let peer_info = decode_peer_info(&p, true)?;
|
||||
@ -70,7 +70,7 @@ impl RPCOperationSupplyBlockA {
|
||||
peers
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(map_error_internal!("invalid peers list length"))?,
|
||||
.map_err(RPCError::map_internal("invalid peers list length"))?,
|
||||
);
|
||||
for (i, peer) in peers.iter().enumerate() {
|
||||
let mut pi_builder = peers_builder.reborrow().get(i as u32);
|
||||
|
@ -12,9 +12,9 @@ impl RPCOperationValidateDialInfo {
|
||||
pub fn decode(
|
||||
reader: &veilid_capnp::operation_validate_dial_info::Reader,
|
||||
) -> Result<RPCOperationValidateDialInfo, RPCError> {
|
||||
let di_reader = reader.get_dial_info().map_err(map_error_capnp_error!())?;
|
||||
let di_reader = reader.get_dial_info().map_err(RPCError::protocol)?;
|
||||
let dial_info = decode_dial_info(&di_reader)?;
|
||||
let rcpt_reader = reader.get_receipt().map_err(map_error_capnp_error!())?;
|
||||
let rcpt_reader = reader.get_receipt().map_err(RPCError::protocol)?;
|
||||
let receipt = rcpt_reader.to_vec();
|
||||
let redirect = reader.get_redirect();
|
||||
|
||||
|
@ -11,9 +11,9 @@ impl RPCOperationValueChanged {
|
||||
pub fn decode(
|
||||
reader: &veilid_capnp::operation_value_changed::Reader,
|
||||
) -> Result<RPCOperationValueChanged, RPCError> {
|
||||
let k_reader = reader.get_key().map_err(map_error_capnp_error!())?;
|
||||
let k_reader = reader.get_key().map_err(RPCError::protocol)?;
|
||||
let key = decode_value_key(&k_reader)?;
|
||||
let v_reader = reader.get_value().map_err(map_error_capnp_error!())?;
|
||||
let v_reader = reader.get_value().map_err(RPCError::protocol)?;
|
||||
let value = decode_value_data(&v_reader)?;
|
||||
Ok(RPCOperationValueChanged { key, value })
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ impl RPCOperationWatchValueQ {
|
||||
pub fn decode(
|
||||
reader: &veilid_capnp::operation_watch_value_q::Reader,
|
||||
) -> Result<RPCOperationWatchValueQ, RPCError> {
|
||||
let k_reader = reader.get_key().map_err(map_error_capnp_error!())?;
|
||||
let k_reader = reader.get_key().map_err(RPCError::protocol)?;
|
||||
let key = decode_value_key(&k_reader)?;
|
||||
Ok(RPCOperationWatchValueQ { key })
|
||||
}
|
||||
@ -35,12 +35,12 @@ impl RPCOperationWatchValueA {
|
||||
reader: &veilid_capnp::operation_watch_value_a::Reader,
|
||||
) -> Result<RPCOperationWatchValueA, RPCError> {
|
||||
let expiration = reader.get_expiration();
|
||||
let peers_reader = reader.get_peers().map_err(map_error_capnp_error!())?;
|
||||
let peers_reader = reader.get_peers().map_err(RPCError::protocol)?;
|
||||
let mut peers = Vec::<PeerInfo>::with_capacity(
|
||||
peers_reader
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(map_error_internal!("too many peers"))?,
|
||||
.map_err(RPCError::map_internal("too many peers"))?,
|
||||
);
|
||||
for p in peers_reader.iter() {
|
||||
let peer_info = decode_peer_info(&p, true)?;
|
||||
@ -59,7 +59,7 @@ impl RPCOperationWatchValueA {
|
||||
self.peers
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(map_error_internal!("invalid peers list length"))?,
|
||||
.map_err(RPCError::map_internal("invalid peers list length"))?,
|
||||
);
|
||||
for (i, peer) in self.peers.iter().enumerate() {
|
||||
let mut pi_builder = peers_builder.reborrow().get(i as u32);
|
||||
|
@ -78,55 +78,55 @@ impl RPCQuestionDetail {
|
||||
pub fn decode(
|
||||
reader: &veilid_capnp::question::detail::Reader,
|
||||
) -> Result<RPCQuestionDetail, RPCError> {
|
||||
let which_reader = reader.which().map_err(map_error_capnp_notinschema!())?;
|
||||
let which_reader = reader.which().map_err(RPCError::protocol)?;
|
||||
let out = match which_reader {
|
||||
veilid_capnp::question::detail::StatusQ(r) => {
|
||||
let op_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let op_reader = r.map_err(RPCError::protocol)?;
|
||||
let out = RPCOperationStatusQ::decode(&op_reader)?;
|
||||
RPCQuestionDetail::StatusQ(out)
|
||||
}
|
||||
veilid_capnp::question::detail::FindNodeQ(r) => {
|
||||
let op_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let op_reader = r.map_err(RPCError::protocol)?;
|
||||
let out = RPCOperationFindNodeQ::decode(&op_reader)?;
|
||||
RPCQuestionDetail::FindNodeQ(out)
|
||||
}
|
||||
veilid_capnp::question::detail::GetValueQ(r) => {
|
||||
let op_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let op_reader = r.map_err(RPCError::protocol)?;
|
||||
let out = RPCOperationGetValueQ::decode(&op_reader)?;
|
||||
RPCQuestionDetail::GetValueQ(out)
|
||||
}
|
||||
veilid_capnp::question::detail::SetValueQ(r) => {
|
||||
let op_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let op_reader = r.map_err(RPCError::protocol)?;
|
||||
let out = RPCOperationSetValueQ::decode(&op_reader)?;
|
||||
RPCQuestionDetail::SetValueQ(out)
|
||||
}
|
||||
veilid_capnp::question::detail::WatchValueQ(r) => {
|
||||
let op_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let op_reader = r.map_err(RPCError::protocol)?;
|
||||
let out = RPCOperationWatchValueQ::decode(&op_reader)?;
|
||||
RPCQuestionDetail::WatchValueQ(out)
|
||||
}
|
||||
veilid_capnp::question::detail::SupplyBlockQ(r) => {
|
||||
let op_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let op_reader = r.map_err(RPCError::protocol)?;
|
||||
let out = RPCOperationSupplyBlockQ::decode(&op_reader)?;
|
||||
RPCQuestionDetail::SupplyBlockQ(out)
|
||||
}
|
||||
veilid_capnp::question::detail::FindBlockQ(r) => {
|
||||
let op_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let op_reader = r.map_err(RPCError::protocol)?;
|
||||
let out = RPCOperationFindBlockQ::decode(&op_reader)?;
|
||||
RPCQuestionDetail::FindBlockQ(out)
|
||||
}
|
||||
veilid_capnp::question::detail::StartTunnelQ(r) => {
|
||||
let op_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let op_reader = r.map_err(RPCError::protocol)?;
|
||||
let out = RPCOperationStartTunnelQ::decode(&op_reader)?;
|
||||
RPCQuestionDetail::StartTunnelQ(out)
|
||||
}
|
||||
veilid_capnp::question::detail::CompleteTunnelQ(r) => {
|
||||
let op_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let op_reader = r.map_err(RPCError::protocol)?;
|
||||
let out = RPCOperationCompleteTunnelQ::decode(&op_reader)?;
|
||||
RPCQuestionDetail::CompleteTunnelQ(out)
|
||||
}
|
||||
veilid_capnp::question::detail::CancelTunnelQ(r) => {
|
||||
let op_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let op_reader = r.map_err(RPCError::protocol)?;
|
||||
let out = RPCOperationCancelTunnelQ::decode(&op_reader)?;
|
||||
RPCQuestionDetail::CancelTunnelQ(out)
|
||||
}
|
||||
|
@ -32,25 +32,18 @@ impl RespondTo {
|
||||
reader: &veilid_capnp::question::respond_to::Reader,
|
||||
sender_node_id: &DHTKey,
|
||||
) -> Result<Self, RPCError> {
|
||||
let respond_to = match reader.which().map_err(map_error_capnp_notinschema!())? {
|
||||
veilid_capnp::question::respond_to::Sender(_) => RespondTo::Sender(None),
|
||||
veilid_capnp::question::respond_to::SenderWithInfo(Ok(sender_ni_reader)) => {
|
||||
let respond_to = match reader.which().map_err(RPCError::protocol)? {
|
||||
veilid_capnp::question::respond_to::Sender(()) => RespondTo::Sender(None),
|
||||
veilid_capnp::question::respond_to::SenderWithInfo(sender_ni_reader) => {
|
||||
let sender_ni_reader = sender_ni_reader.map_err(RPCError::protocol)?;
|
||||
let sni = decode_signed_node_info(&sender_ni_reader, sender_node_id, true)?;
|
||||
RespondTo::Sender(Some(sni))
|
||||
}
|
||||
veilid_capnp::question::respond_to::SenderWithInfo(Err(e)) => {
|
||||
return Err(rpc_error_protocol(format!(
|
||||
"invalid signed node info: {}",
|
||||
e
|
||||
)))
|
||||
}
|
||||
veilid_capnp::question::respond_to::PrivateRoute(Ok(pr_reader)) => {
|
||||
veilid_capnp::question::respond_to::PrivateRoute(pr_reader) => {
|
||||
let pr_reader = pr_reader.map_err(RPCError::protocol)?;
|
||||
let pr = decode_private_route(&pr_reader)?;
|
||||
RespondTo::PrivateRoute(pr)
|
||||
}
|
||||
veilid_capnp::question::respond_to::PrivateRoute(Err(e)) => {
|
||||
return Err(rpc_error_protocol(format!("invalid private route: {}", e)));
|
||||
}
|
||||
};
|
||||
Ok(respond_to)
|
||||
}
|
||||
|
@ -59,35 +59,35 @@ impl RPCStatementDetail {
|
||||
reader: &veilid_capnp::statement::detail::Reader,
|
||||
sender_node_id: &DHTKey,
|
||||
) -> Result<RPCStatementDetail, RPCError> {
|
||||
let which_reader = reader.which().map_err(map_error_capnp_notinschema!())?;
|
||||
let which_reader = reader.which().map_err(RPCError::protocol)?;
|
||||
let out = match which_reader {
|
||||
veilid_capnp::statement::detail::ValidateDialInfo(r) => {
|
||||
let op_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let op_reader = r.map_err(RPCError::protocol)?;
|
||||
let out = RPCOperationValidateDialInfo::decode(&op_reader)?;
|
||||
RPCStatementDetail::ValidateDialInfo(out)
|
||||
}
|
||||
veilid_capnp::statement::detail::Route(r) => {
|
||||
let op_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let op_reader = r.map_err(RPCError::protocol)?;
|
||||
let out = RPCOperationRoute::decode(&op_reader)?;
|
||||
RPCStatementDetail::Route(out)
|
||||
}
|
||||
veilid_capnp::statement::detail::NodeInfoUpdate(r) => {
|
||||
let op_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let op_reader = r.map_err(RPCError::protocol)?;
|
||||
let out = RPCOperationNodeInfoUpdate::decode(&op_reader, sender_node_id)?;
|
||||
RPCStatementDetail::NodeInfoUpdate(out)
|
||||
}
|
||||
veilid_capnp::statement::detail::ValueChanged(r) => {
|
||||
let op_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let op_reader = r.map_err(RPCError::protocol)?;
|
||||
let out = RPCOperationValueChanged::decode(&op_reader)?;
|
||||
RPCStatementDetail::ValueChanged(out)
|
||||
}
|
||||
veilid_capnp::statement::detail::Signal(r) => {
|
||||
let op_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let op_reader = r.map_err(RPCError::protocol)?;
|
||||
let out = RPCOperationSignal::decode(&op_reader)?;
|
||||
RPCStatementDetail::Signal(out)
|
||||
}
|
||||
veilid_capnp::statement::detail::ReturnReceipt(r) => {
|
||||
let op_reader = r.map_err(map_error_capnp_error!())?;
|
||||
let op_reader = r.map_err(RPCError::protocol)?;
|
||||
let out = RPCOperationReturnReceipt::decode(&op_reader)?;
|
||||
RPCStatementDetail::ReturnReceipt(out)
|
||||
}
|
||||
|
@ -21,11 +21,11 @@ pub fn decode_peer_info(
|
||||
let nid_reader = reader
|
||||
.reborrow()
|
||||
.get_node_id()
|
||||
.map_err(map_error_capnp_error!())?;
|
||||
.map_err(RPCError::protocol)?;
|
||||
let sni_reader = reader
|
||||
.reborrow()
|
||||
.get_signed_node_info()
|
||||
.map_err(map_error_capnp_error!())?;
|
||||
.map_err(RPCError::protocol)?;
|
||||
let node_id = NodeId::new(decode_public_key(&nid_reader));
|
||||
let signed_node_info =
|
||||
decode_signed_node_info(&sni_reader, &node_id.key, allow_relay_peer_info)?;
|
||||
|
@ -83,13 +83,17 @@ pub fn encode_route_hop_data(
|
||||
//
|
||||
let mut nonce_builder = builder.reborrow().init_nonce();
|
||||
encode_nonce(&route_hop_data.nonce, &mut nonce_builder);
|
||||
let blob_builder = builder.reborrow().init_blob(
|
||||
route_hop_data
|
||||
.blob
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(map_error_protocol!("invalid blob length in route hop data"))?,
|
||||
);
|
||||
let blob_builder = builder
|
||||
.reborrow()
|
||||
.init_blob(
|
||||
route_hop_data
|
||||
.blob
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(RPCError::map_protocol(
|
||||
"invalid blob length in route hop data",
|
||||
))?,
|
||||
);
|
||||
blob_builder.copy_from_slice(route_hop_data.blob.as_slice());
|
||||
Ok(())
|
||||
}
|
||||
@ -157,13 +161,13 @@ pub fn decode_route_hop_data(
|
||||
&reader
|
||||
.reborrow()
|
||||
.get_nonce()
|
||||
.map_err(map_error_protocol!("invalid nonce in route hop data"))?,
|
||||
.map_err(RPCError::map_protocol("invalid nonce in route hop data"))?,
|
||||
);
|
||||
|
||||
let blob = reader
|
||||
.reborrow()
|
||||
.get_blob()
|
||||
.map_err(map_error_protocol!("invalid blob in route hop data"))?
|
||||
.map_err(RPCError::map_protocol("invalid blob in route hop data"))?
|
||||
.to_vec();
|
||||
|
||||
Ok(RouteHopData { nonce, blob })
|
||||
@ -174,13 +178,13 @@ pub fn decode_route_hop(reader: &veilid_capnp::route_hop::Reader) -> Result<Rout
|
||||
&reader
|
||||
.reborrow()
|
||||
.get_dial_info()
|
||||
.map_err(map_error_protocol!("invalid dial info in route hop"))?,
|
||||
.map_err(RPCError::map_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_protocol!("invalid next hop in route hop"))?;
|
||||
.map_err(RPCError::map_protocol("invalid next hop in route hop"))?;
|
||||
Some(decode_route_hop_data(&rhd_reader)?)
|
||||
} else {
|
||||
None
|
||||
@ -195,16 +199,14 @@ pub fn decode_route_hop(reader: &veilid_capnp::route_hop::Reader) -> Result<Rout
|
||||
pub fn decode_private_route(
|
||||
reader: &veilid_capnp::private_route::Reader,
|
||||
) -> Result<PrivateRoute, RPCError> {
|
||||
let public_key = decode_public_key(
|
||||
&reader
|
||||
.get_public_key()
|
||||
.map_err(map_error_protocol!("invalid public key in private route"))?,
|
||||
);
|
||||
let public_key = decode_public_key(&reader.get_public_key().map_err(
|
||||
RPCError::map_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_protocol!("invalid first hop in private route"))?;
|
||||
.map_err(RPCError::map_protocol("invalid first hop in private route"))?;
|
||||
Some(decode_route_hop(&rh_reader)?)
|
||||
} else {
|
||||
None
|
||||
@ -223,19 +225,18 @@ pub fn decode_safety_route(
|
||||
let public_key = decode_public_key(
|
||||
&reader
|
||||
.get_public_key()
|
||||
.map_err(map_error_protocol!("invalid public key in safety route"))?,
|
||||
.map_err(RPCError::map_protocol("invalid public key in safety route"))?,
|
||||
);
|
||||
let hop_count = reader.get_hop_count();
|
||||
let hops = match reader.get_hops().which() {
|
||||
Ok(veilid_capnp::safety_route::hops::Which::Data(Ok(rhd_reader))) => {
|
||||
let hops = match reader.get_hops().which().map_err(RPCError::protocol)? {
|
||||
veilid_capnp::safety_route::hops::Which::Data(rhd_reader) => {
|
||||
let rhd_reader = rhd_reader.map_err(RPCError::protocol)?;
|
||||
SafetyRouteHops::Data(decode_route_hop_data(&rhd_reader)?)
|
||||
}
|
||||
Ok(veilid_capnp::safety_route::hops::Which::Private(Ok(pr_reader))) => {
|
||||
veilid_capnp::safety_route::hops::Which::Private(pr_reader) => {
|
||||
let pr_reader = pr_reader.map_err(RPCError::protocol)?;
|
||||
SafetyRouteHops::Private(decode_private_route(&pr_reader)?)
|
||||
}
|
||||
_ => {
|
||||
return Err(rpc_error_protocol("invalid hops in safety route"));
|
||||
}
|
||||
};
|
||||
|
||||
Ok(SafetyRoute {
|
||||
|
@ -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_protocol("invalid key"));
|
||||
return Err(RPCError::protocol("invalid key"));
|
||||
}
|
||||
builder.set_u0(u64::from_be_bytes(
|
||||
key.bytes[0..8]
|
||||
.try_into()
|
||||
.map_err(map_error_protocol!("slice with incorrect length"))?,
|
||||
.map_err(RPCError::map_protocol("slice with incorrect length"))?,
|
||||
));
|
||||
builder.set_u1(u64::from_be_bytes(
|
||||
key.bytes[8..16]
|
||||
.try_into()
|
||||
.map_err(map_error_protocol!("slice with incorrect length"))?,
|
||||
.map_err(RPCError::map_protocol("slice with incorrect length"))?,
|
||||
));
|
||||
builder.set_u2(u64::from_be_bytes(
|
||||
key.bytes[16..24]
|
||||
.try_into()
|
||||
.map_err(map_error_protocol!("slice with incorrect length"))?,
|
||||
.map_err(RPCError::map_protocol("slice with incorrect length"))?,
|
||||
));
|
||||
builder.set_u3(u64::from_be_bytes(
|
||||
key.bytes[24..32]
|
||||
.try_into()
|
||||
.map_err(map_error_protocol!("slice with incorrect length"))?,
|
||||
.map_err(RPCError::map_protocol("slice with incorrect length"))?,
|
||||
));
|
||||
Ok(())
|
||||
}
|
||||
|
@ -16,14 +16,16 @@ pub fn decode_sender_info(
|
||||
reader: &veilid_capnp::sender_info::Reader,
|
||||
) -> Result<SenderInfo, RPCError> {
|
||||
if !reader.has_socket_address() {
|
||||
return Err(rpc_error_internal("invalid socket address type"));
|
||||
return Err(RPCError::internal("invalid socket address type"));
|
||||
}
|
||||
let socket_address = if reader.has_socket_address() {
|
||||
Some(decode_socket_address(
|
||||
&reader
|
||||
.reborrow()
|
||||
.get_socket_address()
|
||||
.map_err(map_error_internal!("invalid socket address in sender_info"))?,
|
||||
.map_err(RPCError::map_internal(
|
||||
"invalid socket address in sender_info",
|
||||
))?,
|
||||
)?)
|
||||
} else {
|
||||
None
|
||||
|
@ -10,8 +10,8 @@ pub fn encode_signal_info(
|
||||
let mut hp_builder = builder.reborrow().init_hole_punch();
|
||||
let r_builder = hp_builder
|
||||
.reborrow()
|
||||
.init_receipt(receipt.len().try_into().map_err(map_error_protocol!(
|
||||
"invalid receipt length in encode_signal_info"
|
||||
.init_receipt(receipt.len().try_into().map_err(RPCError::map_protocol(
|
||||
"invalid receipt length in encode_signal_info",
|
||||
))?);
|
||||
r_builder.copy_from_slice(receipt);
|
||||
let mut pi_builder = hp_builder.init_peer_info();
|
||||
@ -21,8 +21,8 @@ pub fn encode_signal_info(
|
||||
let mut rc_builder = builder.reborrow().init_reverse_connect();
|
||||
let r_builder = rc_builder
|
||||
.reborrow()
|
||||
.init_receipt(receipt.len().try_into().map_err(map_error_protocol!(
|
||||
"invalid receipt length in encode_signal_info"
|
||||
.init_receipt(receipt.len().try_into().map_err(RPCError::map_protocol(
|
||||
"invalid receipt length in encode_signal_info",
|
||||
))?);
|
||||
r_builder.copy_from_slice(receipt);
|
||||
let mut pi_builder = rc_builder.init_peer_info();
|
||||
@ -39,22 +39,19 @@ pub fn decode_signal_info(
|
||||
Ok(
|
||||
match reader
|
||||
.which()
|
||||
.map_err(map_error_internal!("invalid signal operation"))?
|
||||
.map_err(RPCError::map_internal("invalid signal operation"))?
|
||||
{
|
||||
veilid_capnp::operation_signal::HolePunch(r) => {
|
||||
// Extract hole punch reader
|
||||
let r = match r {
|
||||
Ok(r) => r,
|
||||
Err(_) => return Err(rpc_error_internal("invalid hole punch")),
|
||||
};
|
||||
let r = r.map_err(RPCError::protocol)?;
|
||||
let receipt = r
|
||||
.get_receipt()
|
||||
.map_err(map_error_protocol!(
|
||||
"invalid receipt in hole punch signal info"
|
||||
.map_err(RPCError::map_protocol(
|
||||
"invalid receipt in hole punch signal info",
|
||||
))?
|
||||
.to_vec();
|
||||
let pi_reader = r.get_peer_info().map_err(map_error_protocol!(
|
||||
"invalid peer info in hole punch signal info"
|
||||
let pi_reader = r.get_peer_info().map_err(RPCError::map_protocol(
|
||||
"invalid peer info in hole punch signal info",
|
||||
))?;
|
||||
let peer_info = decode_peer_info(&pi_reader, true)?;
|
||||
|
||||
@ -62,18 +59,15 @@ pub fn decode_signal_info(
|
||||
}
|
||||
veilid_capnp::operation_signal::ReverseConnect(r) => {
|
||||
// Extract reverse connect reader
|
||||
let r = match r {
|
||||
Ok(r) => r,
|
||||
Err(_) => return Err(rpc_error_internal("invalid reverse connect")),
|
||||
};
|
||||
let r = r.map_err(RPCError::protocol)?;
|
||||
let receipt = r
|
||||
.get_receipt()
|
||||
.map_err(map_error_protocol!(
|
||||
"invalid receipt in hole punch signal info"
|
||||
.map_err(RPCError::map_protocol(
|
||||
"invalid receipt in hole punch signal info",
|
||||
))?
|
||||
.to_vec();
|
||||
let pi_reader = r.get_peer_info().map_err(map_error_protocol!(
|
||||
"invalid peer info in reverse connect signal info"
|
||||
let pi_reader = r.get_peer_info().map_err(RPCError::map_protocol(
|
||||
"invalid peer info in reverse connect signal info",
|
||||
))?;
|
||||
let peer_info = decode_peer_info(&pi_reader, true)?;
|
||||
|
||||
|
@ -25,17 +25,17 @@ pub fn decode_signed_node_info(
|
||||
let ni_reader = reader
|
||||
.reborrow()
|
||||
.get_node_info()
|
||||
.map_err(map_error_capnp_error!())?;
|
||||
.map_err(RPCError::protocol)?;
|
||||
let node_info = decode_node_info(&ni_reader, allow_relay_peer_info)?;
|
||||
|
||||
let sig_reader = reader
|
||||
.reborrow()
|
||||
.get_signature()
|
||||
.map_err(map_error_capnp_error!())?;
|
||||
.map_err(RPCError::protocol)?;
|
||||
let signature = decode_signature(&sig_reader);
|
||||
|
||||
let timestamp = reader.reborrow().get_timestamp();
|
||||
|
||||
SignedNodeInfo::new(node_info, NodeId::new(*node_id), signature, timestamp)
|
||||
.map_err(map_error_string!())
|
||||
.map_err(RPCError::protocol)
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ pub fn decode_socket_address(
|
||||
let ar = reader
|
||||
.reborrow()
|
||||
.get_address()
|
||||
.map_err(map_error_internal!("missing socketAddress"))?;
|
||||
.map_err(RPCError::map_internal("missing socketAddress"))?;
|
||||
let address = decode_address(&ar)?;
|
||||
let port = reader.get_port();
|
||||
|
||||
|
@ -46,10 +46,10 @@ pub fn encode_tunnel_endpoint(
|
||||
pub fn decode_tunnel_endpoint(
|
||||
reader: &veilid_capnp::tunnel_endpoint::Reader,
|
||||
) -> Result<TunnelEndpoint, RPCError> {
|
||||
let mode = decode_tunnel_mode(reader.get_mode().map_err(map_error_capnp_notinschema!())?);
|
||||
let mode = decode_tunnel_mode(reader.get_mode().map_err(RPCError::protocol)?);
|
||||
let description = reader
|
||||
.get_description()
|
||||
.map_err(map_error_capnp_error!())?
|
||||
.map_err(RPCError::protocol)?
|
||||
.to_owned();
|
||||
|
||||
Ok(TunnelEndpoint { mode, description })
|
||||
@ -73,9 +73,9 @@ pub fn decode_full_tunnel(
|
||||
) -> Result<FullTunnel, RPCError> {
|
||||
let id = reader.get_id();
|
||||
let timeout = reader.get_timeout();
|
||||
let l_reader = reader.get_local().map_err(map_error_capnp_error!())?;
|
||||
let l_reader = reader.get_local().map_err(RPCError::protocol)?;
|
||||
let local = decode_tunnel_endpoint(&l_reader)?;
|
||||
let r_reader = reader.get_remote().map_err(map_error_capnp_error!())?;
|
||||
let r_reader = reader.get_remote().map_err(RPCError::protocol)?;
|
||||
let remote = decode_tunnel_endpoint(&r_reader)?;
|
||||
|
||||
Ok(FullTunnel {
|
||||
@ -102,7 +102,7 @@ pub fn decode_partial_tunnel(
|
||||
) -> Result<PartialTunnel, RPCError> {
|
||||
let id = reader.get_id();
|
||||
let timeout = reader.get_timeout();
|
||||
let l_reader = reader.get_local().map_err(map_error_capnp_error!())?;
|
||||
let l_reader = reader.get_local().map_err(RPCError::protocol)?;
|
||||
let local = decode_tunnel_endpoint(&l_reader)?;
|
||||
|
||||
Ok(PartialTunnel { id, timeout, local })
|
||||
|
@ -11,10 +11,7 @@ pub fn encode_value_data(
|
||||
}
|
||||
|
||||
pub fn decode_value_data(reader: &veilid_capnp::value_data::Reader) -> Result<ValueData, RPCError> {
|
||||
let data = reader
|
||||
.get_data()
|
||||
.map_err(map_error_capnp_error!())?
|
||||
.to_vec();
|
||||
let data = reader.get_data().map_err(RPCError::protocol)?.to_vec();
|
||||
let seq = reader.get_seq();
|
||||
Ok(ValueData { data, seq })
|
||||
}
|
||||
|
@ -14,12 +14,12 @@ pub fn encode_value_key(
|
||||
}
|
||||
|
||||
pub fn decode_value_key(reader: &veilid_capnp::value_key::Reader) -> Result<ValueKey, RPCError> {
|
||||
let pk_reader = reader.get_public_key().map_err(map_error_capnp_error!())?;
|
||||
let pk_reader = reader.get_public_key().map_err(RPCError::protocol)?;
|
||||
let key = decode_public_key(&pk_reader);
|
||||
let subkey = if !reader.has_subkey() {
|
||||
None
|
||||
} else {
|
||||
let subkey = reader.get_subkey().map_err(map_error_capnp_error!())?;
|
||||
let subkey = reader.get_subkey().map_err(RPCError::protocol)?;
|
||||
Some(subkey.to_owned())
|
||||
};
|
||||
Ok(ValueKey { key, subkey })
|
||||
|
@ -1,92 +0,0 @@
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug, Clone, PartialOrd, PartialEq, Eq, Ord)]
|
||||
pub enum RPCError {
|
||||
Timeout,
|
||||
InvalidFormat(String),
|
||||
Unreachable(DHTKey),
|
||||
Unimplemented(String),
|
||||
Protocol(String),
|
||||
Internal(String),
|
||||
}
|
||||
|
||||
pub fn rpc_error_internal<T: ToString>(x: T) -> RPCError {
|
||||
let x = x.to_string();
|
||||
error!("RPCError Internal: {}", x);
|
||||
RPCError::Internal(x)
|
||||
}
|
||||
pub fn rpc_error_invalid_format<T: ToString>(x: T) -> RPCError {
|
||||
let x = x.to_string();
|
||||
error!("RPCError Invalid Format: {}", x);
|
||||
RPCError::InvalidFormat(x)
|
||||
}
|
||||
pub fn rpc_error_protocol<T: ToString>(x: T) -> RPCError {
|
||||
let x = x.to_string();
|
||||
error!("RPCError Protocol: {}", x);
|
||||
RPCError::Protocol(x)
|
||||
}
|
||||
pub fn rpc_error_capnp_error(e: capnp::Error) -> RPCError {
|
||||
error!("RPCError Protocol: capnp error: {}", &e.description);
|
||||
RPCError::Protocol(e.description)
|
||||
}
|
||||
pub fn rpc_error_capnp_notinschema(e: capnp::NotInSchema) -> RPCError {
|
||||
error!("RPCError Protocol: not in schema: {}", &e.0);
|
||||
RPCError::Protocol(format!("not in schema: {}", &e.0))
|
||||
}
|
||||
pub fn rpc_error_unimplemented<T: ToString>(x: T) -> RPCError {
|
||||
let x = x.to_string();
|
||||
error!("RPCError Unimplemented: {}", x);
|
||||
RPCError::Unimplemented(x)
|
||||
}
|
||||
|
||||
impl fmt::Display for RPCError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
RPCError::Timeout => write!(f, "[RPCError: Timeout]"),
|
||||
RPCError::InvalidFormat(s) => write!(f, "[RPCError: InvalidFormat({})]", s),
|
||||
RPCError::Unreachable(k) => write!(f, "[RPCError: Unreachable({})]", k),
|
||||
RPCError::Unimplemented(s) => write!(f, "[RPCError: Unimplemented({})]", s),
|
||||
RPCError::Protocol(s) => write!(f, "[RPCError: Protocol({})]", s),
|
||||
RPCError::Internal(s) => write!(f, "[RPCError: Internal({})]", s),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! map_error_internal {
|
||||
($x:expr) => {
|
||||
|_| rpc_error_internal($x)
|
||||
};
|
||||
}
|
||||
#[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 {
|
||||
() => {
|
||||
|e| rpc_error_capnp_error(e)
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! map_error_capnp_notinschema {
|
||||
() => {
|
||||
|e| rpc_error_capnp_notinschema(e)
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! map_error_panic {
|
||||
() => {
|
||||
|_| panic!("oops")
|
||||
};
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
mod coders;
|
||||
mod debug;
|
||||
mod private_route;
|
||||
mod rpc_cancel_tunnel;
|
||||
mod rpc_complete_tunnel;
|
||||
mod rpc_error;
|
||||
mod rpc_find_block;
|
||||
mod rpc_find_node;
|
||||
mod rpc_get_value;
|
||||
@ -18,8 +18,8 @@ mod rpc_validate_dial_info;
|
||||
mod rpc_value_changed;
|
||||
mod rpc_watch_value;
|
||||
|
||||
pub use debug::*;
|
||||
pub use private_route::*;
|
||||
pub use rpc_error::*;
|
||||
|
||||
use super::*;
|
||||
use crate::dht::*;
|
||||
@ -101,21 +101,22 @@ where
|
||||
let wordvec = builder
|
||||
.into_reader()
|
||||
.canonicalize()
|
||||
.map_err(map_error_capnp_error!())
|
||||
.map_err(logthru_rpc!())?;
|
||||
Ok(capnp::Word::words_to_bytes(wordvec.as_slice()).to_vec())
|
||||
}
|
||||
fn reader_to_vec<'a, T>(reader: &capnp::message::Reader<T>) -> Result<Vec<u8>, RPCError>
|
||||
where
|
||||
T: capnp::message::ReaderSegments + 'a,
|
||||
{
|
||||
let wordvec = reader
|
||||
.canonicalize()
|
||||
.map_err(map_error_capnp_error!())
|
||||
.map_err(RPCError::protocol)
|
||||
.map_err(logthru_rpc!())?;
|
||||
Ok(capnp::Word::words_to_bytes(wordvec.as_slice()).to_vec())
|
||||
}
|
||||
|
||||
// fn reader_to_vec<'a, T>(reader: &capnp::message::Reader<T>) -> Result<Vec<u8>, RPCError>
|
||||
// where
|
||||
// T: capnp::message::ReaderSegments + 'a,
|
||||
// {
|
||||
// let wordvec = reader
|
||||
// .canonicalize()
|
||||
// .map_err(RPCError::protocol)
|
||||
// .map_err(logthru_rpc!())?;
|
||||
// Ok(capnp::Word::words_to_bytes(wordvec.as_slice()).to_vec())
|
||||
// }
|
||||
|
||||
#[derive(Debug)]
|
||||
struct WaitableReply {
|
||||
op_id: OperationId,
|
||||
@ -243,16 +244,16 @@ impl RPCProcessor {
|
||||
// Search the DHT for a single node closest to a key and add it to the routing table and return the node reference
|
||||
pub async fn search_dht_single_key(
|
||||
&self,
|
||||
node_id: DHTKey,
|
||||
_node_id: DHTKey,
|
||||
_count: u32,
|
||||
_fanout: u32,
|
||||
_timeout: Option<u64>,
|
||||
) -> Result<NodeRef, RPCError> {
|
||||
let routing_table = self.routing_table();
|
||||
//let routing_table = self.routing_table();
|
||||
|
||||
// xxx find node but stop if we find the exact node we want
|
||||
// xxx return whatever node is closest after the timeout
|
||||
Err(rpc_error_unimplemented("search_dht_single_key")).map_err(logthru_rpc!(error))
|
||||
Err(RPCError::unimplemented("search_dht_single_key")).map_err(logthru_rpc!(error))
|
||||
}
|
||||
|
||||
// Search the DHT for the 'count' closest nodes to a key, adding them all to the routing table if they are not there and returning their node references
|
||||
@ -264,7 +265,7 @@ impl RPCProcessor {
|
||||
_timeout: Option<u64>,
|
||||
) -> Result<Vec<NodeRef>, RPCError> {
|
||||
// xxx return closest nodes after the timeout
|
||||
Err(rpc_error_unimplemented("search_dht_multi_key")).map_err(logthru_rpc!(error))
|
||||
Err(RPCError::unimplemented("search_dht_multi_key")).map_err(logthru_rpc!(error))
|
||||
}
|
||||
|
||||
// Search the DHT for a specific node corresponding to a key unless we have that node in our routing table already, and return the node reference
|
||||
@ -328,7 +329,7 @@ impl RPCProcessor {
|
||||
inner
|
||||
.waiting_rpc_table
|
||||
.remove(&op_id)
|
||||
.ok_or_else(|| rpc_error_internal("Unmatched operation id"))?
|
||||
.ok_or_else(RPCError::else_internal("Unmatched operation id"))?
|
||||
};
|
||||
eventual.resolve(msg).await;
|
||||
Ok(())
|
||||
@ -340,7 +341,7 @@ impl RPCProcessor {
|
||||
waitable_reply: &WaitableReply,
|
||||
) -> Result<(RPCMessage, u64), RPCError> {
|
||||
let timeout_ms = u32::try_from(waitable_reply.timeout / 1000u64)
|
||||
.map_err(map_error_internal!("invalid timeout"))?;
|
||||
.map_err(RPCError::map_internal("invalid timeout"))?;
|
||||
// wait for eventualvalue
|
||||
let start_ts = intf::get_timestamp();
|
||||
let res = intf::timeout(timeout_ms, waitable_reply.eventual.instance())
|
||||
@ -459,7 +460,7 @@ impl RPCProcessor {
|
||||
out_node_id = sr
|
||||
.hops
|
||||
.first()
|
||||
.ok_or_else(|| rpc_error_internal("no hop in safety route"))?
|
||||
.ok_or_else(RPCError::else_internal("no hop in safety route"))?
|
||||
.dial_info
|
||||
.node_id
|
||||
.key;
|
||||
@ -478,7 +479,7 @@ impl RPCProcessor {
|
||||
out_hop_count = private_route.hop_count as usize;
|
||||
let out_node_id = match &private_route.hops {
|
||||
Some(rh) => rh.dial_info.node_id.key,
|
||||
_ => return Err(rpc_error_internal("private route has no hops")),
|
||||
_ => return Err(RPCError::internal("private route has no hops")),
|
||||
};
|
||||
out_message = self.wrap_with_route(None, private_route, message_vec)?;
|
||||
out_node_id
|
||||
@ -489,7 +490,7 @@ impl RPCProcessor {
|
||||
let out_node_id = sr
|
||||
.hops
|
||||
.first()
|
||||
.ok_or_else(|| rpc_error_internal("no hop in safety route"))?
|
||||
.ok_or_else(RPCError::else_internal("no hop in safety route"))?
|
||||
.dial_info
|
||||
.node_id
|
||||
.key;
|
||||
@ -502,7 +503,7 @@ impl RPCProcessor {
|
||||
|
||||
// Verify hop count isn't larger than out maximum routed hop count
|
||||
if out_hop_count > self.inner.lock().max_route_hop_count {
|
||||
return Err(rpc_error_internal("hop count too long for route"))
|
||||
return Err(RPCError::internal("hop count too long for route"))
|
||||
.map_err(logthru_rpc!(warn));
|
||||
}
|
||||
|
||||
@ -565,7 +566,7 @@ impl RPCProcessor {
|
||||
.network_manager()
|
||||
.send_envelope(node_ref.clone(), Some(node_id), message)
|
||||
.await
|
||||
.map_err(RPCError::Internal)
|
||||
.map_err(RPCError::internal)
|
||||
{
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
@ -637,7 +638,7 @@ impl RPCProcessor {
|
||||
.network_manager()
|
||||
.send_envelope(node_ref.clone(), Some(node_id), message)
|
||||
.await
|
||||
.map_err(RPCError::Internal)
|
||||
.map_err(RPCError::network)
|
||||
{
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
@ -729,7 +730,7 @@ impl RPCProcessor {
|
||||
self.network_manager()
|
||||
.send_envelope(node_ref.clone(), Some(node_id), message)
|
||||
.await
|
||||
.map_err(RPCError::Internal)
|
||||
.map_err(RPCError::network)
|
||||
.map_err(|e| {
|
||||
self.routing_table()
|
||||
.stats_failed_to_send(node_ref.clone(), send_ts, false);
|
||||
@ -763,7 +764,7 @@ impl RPCProcessor {
|
||||
let reader = capnp::message::Reader::new(encoded_msg.data, Default::default());
|
||||
let op_reader = reader
|
||||
.get_root::<veilid_capnp::operation::Reader>()
|
||||
.map_err(map_error_capnp_error!())
|
||||
.map_err(RPCError::protocol)
|
||||
.map_err(logthru_rpc!())?;
|
||||
RPCOperation::decode(&op_reader, &sender_node_id)?
|
||||
};
|
||||
@ -776,13 +777,14 @@ impl RPCProcessor {
|
||||
RespondTo::Sender(Some(sender_ni)) => {
|
||||
// Sender NodeInfo was specified, update our routing table with it
|
||||
if !self.filter_peer_scope(&sender_ni.node_info) {
|
||||
return Err(rpc_error_invalid_format(
|
||||
return Err(RPCError::invalid_format(
|
||||
"respond_to_sender_signed_node_info has invalid peer scope",
|
||||
));
|
||||
}
|
||||
let nr = self
|
||||
.routing_table()
|
||||
.register_node_with_signed_node_info(sender_node_id, sender_ni.clone())
|
||||
.map_err(map_to_string)
|
||||
.map_err(RPCError::Internal)?;
|
||||
opt_sender_nr = Some(nr);
|
||||
}
|
||||
@ -883,7 +885,7 @@ impl RPCProcessor {
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip_all, err)]
|
||||
pub async fn startup(&self) -> Result<(), String> {
|
||||
pub async fn startup(&self) -> EyreResult<()> {
|
||||
trace!("startup rpc processor");
|
||||
let mut inner = self.inner.lock();
|
||||
// make local copy of node id for easy access
|
||||
@ -966,7 +968,7 @@ impl RPCProcessor {
|
||||
envelope: Envelope,
|
||||
body: Vec<u8>,
|
||||
peer_noderef: NodeRef,
|
||||
) -> Result<(), String> {
|
||||
) -> EyreResult<()> {
|
||||
let msg = RPCMessageEncoded {
|
||||
header: RPCMessageHeader {
|
||||
timestamp: intf::get_timestamp(),
|
||||
@ -982,7 +984,7 @@ impl RPCProcessor {
|
||||
};
|
||||
send_channel
|
||||
.try_send(msg)
|
||||
.map_err(|e| format!("failed to enqueue received RPC message: {:?}", e))?;
|
||||
.wrap_err("failed to enqueue received RPC message")?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ impl RPCProcessor {
|
||||
let sr_hopcount = safety_route_spec.hops.len();
|
||||
let hopcount = 1 + sr_hopcount + pr_hopcount;
|
||||
if hopcount > self.inner.lock().max_route_hop_count {
|
||||
return Err(rpc_error_internal("hop count too long for route"));
|
||||
return Err(RPCError::internal("hop count too long for route"));
|
||||
}
|
||||
|
||||
// Create hops
|
||||
@ -47,10 +47,10 @@ impl RPCProcessor {
|
||||
&safety_route_spec.hops[h].dial_info.node_id.key,
|
||||
&safety_route_spec.secret_key,
|
||||
)
|
||||
.map_err(map_error_internal!("dh failed"))?;
|
||||
.map_err(RPCError::map_internal("dh failed"))?;
|
||||
let enc_msg_data =
|
||||
Crypto::encrypt_aead(blob_data.as_slice(), &nonce, &dh_secret, None)
|
||||
.map_err(map_error_internal!("encryption failed"))?;
|
||||
.map_err(RPCError::map_internal("encryption failed"))?;
|
||||
|
||||
// Make route hop data
|
||||
let route_hop_data = RouteHopData {
|
||||
@ -86,9 +86,9 @@ impl RPCProcessor {
|
||||
&safety_route_spec.hops[0].dial_info.node_id.key,
|
||||
&safety_route_spec.secret_key,
|
||||
)
|
||||
.map_err(map_error_internal!("dh failed"))?;
|
||||
.map_err(RPCError::map_internal("dh failed"))?;
|
||||
let enc_msg_data = Crypto::encrypt_aead(blob_data.as_slice(), &nonce, &dh_secret, None)
|
||||
.map_err(map_error_internal!("encryption failed"))?;
|
||||
.map_err(RPCError::map_internal("encryption failed"))?;
|
||||
|
||||
let route_hop_data = RouteHopData {
|
||||
nonce,
|
||||
@ -123,9 +123,9 @@ impl RPCProcessor {
|
||||
let dh_secret = self
|
||||
.crypto
|
||||
.cached_dh(&private_route.public_key, &safety_route_spec.secret_key)
|
||||
.map_err(map_error_internal!("dh failed"))?;
|
||||
.map_err(RPCError::map_internal("dh failed"))?;
|
||||
let enc_msg_data = Crypto::encrypt_aead(&message_data, &nonce, &dh_secret, None)
|
||||
.map_err(map_error_internal!("encryption failed"))?;
|
||||
.map_err(RPCError::map_internal("encryption failed"))?;
|
||||
|
||||
// Compile the safety route with the private route
|
||||
let safety_route = self.compile_safety_route(safety_route_spec, private_route)?;
|
||||
|
@ -2,6 +2,6 @@ use super::*;
|
||||
|
||||
impl RPCProcessor {
|
||||
pub(crate) async fn process_cancel_tunnel_q(&self, msg: RPCMessage) -> Result<(), RPCError> {
|
||||
Err(rpc_error_unimplemented("process_cancel_tunnel_q"))
|
||||
Err(RPCError::unimplemented("process_cancel_tunnel_q"))
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,6 @@ use super::*;
|
||||
|
||||
impl RPCProcessor {
|
||||
pub(crate) async fn process_complete_tunnel_q(&self, msg: RPCMessage) -> Result<(), RPCError> {
|
||||
Err(rpc_error_unimplemented("process_complete_tunnel_q"))
|
||||
Err(RPCError::unimplemented("process_complete_tunnel_q"))
|
||||
}
|
||||
}
|
||||
|
58
veilid-core/src/rpc_processor/rpc_error.rs
Normal file
58
veilid-core/src/rpc_processor/rpc_error.rs
Normal file
@ -0,0 +1,58 @@
|
||||
use super::*;
|
||||
|
||||
#[derive(ThisError, Debug, Clone, PartialOrd, PartialEq, Eq, Ord)]
|
||||
pub enum RPCError {
|
||||
#[error("[RPCError: Timeout]")]
|
||||
Timeout,
|
||||
#[error("[RPCError: Unreachable({0})]")]
|
||||
Unreachable(DHTKey),
|
||||
#[error("[RPCError: Unimplemented({0})]")]
|
||||
Unimplemented(String),
|
||||
#[error("[RPCError: InvalidFormat({0})]")]
|
||||
InvalidFormat(String),
|
||||
#[error("[RPCError: Protocol({0})]")]
|
||||
Protocol(String),
|
||||
#[error("[RPCError: Internal({0})]")]
|
||||
Internal(String),
|
||||
#[error("[RPCError: Network({0})]")]
|
||||
Network(String),
|
||||
}
|
||||
|
||||
impl RPCError {
|
||||
pub fn timeout() -> Self {
|
||||
Self::Timeout
|
||||
}
|
||||
pub fn unreachable(key: DHTKey) -> Self {
|
||||
Self::Unreachable(key)
|
||||
}
|
||||
pub fn unimplemented<X: ToString>(x: X) -> Self {
|
||||
Self::Unimplemented(x.to_string())
|
||||
}
|
||||
pub fn invalid_format<X: ToString>(x: X) -> Self {
|
||||
Self::InvalidFormat(x.to_string())
|
||||
}
|
||||
pub fn map_invalid_format<M: ToString, X: ToString>(message: M) -> impl FnOnce(X) -> Self {
|
||||
move |x| Self::InvalidFormat(format!("{}: {}", message.to_string(), x.to_string()))
|
||||
}
|
||||
pub fn protocol<X: ToString>(x: X) -> Self {
|
||||
Self::Protocol(x.to_string())
|
||||
}
|
||||
pub fn map_protocol<M: ToString, X: ToString>(message: M) -> impl FnOnce(X) -> Self {
|
||||
move |x| Self::Protocol(format!("{}: {}", message.to_string(), x.to_string()))
|
||||
}
|
||||
pub fn internal<X: ToString>(x: X) -> Self {
|
||||
Self::Internal(x.to_string())
|
||||
}
|
||||
pub fn map_internal<M: ToString, X: ToString>(message: M) -> impl FnOnce(X) -> Self {
|
||||
move |x| Self::Internal(format!("{}: {}", message.to_string(), x.to_string()))
|
||||
}
|
||||
pub fn else_internal<M: ToString>(message: M) -> impl FnOnce() -> Self {
|
||||
move || Self::Internal(format!("{}", message.to_string()))
|
||||
}
|
||||
pub fn network<X: ToString>(x: X) -> Self {
|
||||
Self::Network(x.to_string())
|
||||
}
|
||||
pub fn map_network<M: ToString, X: ToString>(message: M) -> impl FnOnce(X) -> Self {
|
||||
move |x| Self::Network(format!("{}: {}", message.to_string(), x.to_string()))
|
||||
}
|
||||
}
|
@ -2,6 +2,6 @@ use super::*;
|
||||
|
||||
impl RPCProcessor {
|
||||
pub(crate) async fn process_find_block_q(&self, msg: RPCMessage) -> Result<(), RPCError> {
|
||||
Err(rpc_error_unimplemented("process_find_block_q"))
|
||||
Err(RPCError::unimplemented("process_find_block_q"))
|
||||
}
|
||||
}
|
||||
|
@ -23,15 +23,15 @@ impl RPCProcessor {
|
||||
let find_node_a = match msg.operation.into_kind() {
|
||||
RPCOperationKind::Answer(a) => match a.into_detail() {
|
||||
RPCAnswerDetail::FindNodeA(a) => a,
|
||||
_ => return Err(rpc_error_invalid_format("not a find_node answer")),
|
||||
_ => return Err(RPCError::invalid_format("not a find_node answer")),
|
||||
},
|
||||
_ => return Err(rpc_error_invalid_format("not an answer")),
|
||||
_ => return Err(RPCError::invalid_format("not an answer")),
|
||||
};
|
||||
|
||||
// Verify peers are in the correct peer scope
|
||||
for peer_info in &find_node_a.peers {
|
||||
if !self.filter_peer_scope(&peer_info.signed_node_info.node_info) {
|
||||
return Err(rpc_error_invalid_format(
|
||||
return Err(RPCError::invalid_format(
|
||||
"find_node response has invalid peer scope",
|
||||
));
|
||||
}
|
||||
|
@ -2,6 +2,6 @@ use super::*;
|
||||
|
||||
impl RPCProcessor {
|
||||
pub(crate) async fn process_get_value_q(&self, msg: RPCMessage) -> Result<(), RPCError> {
|
||||
Err(rpc_error_unimplemented("process_get_value_q"))
|
||||
Err(RPCError::unimplemented("process_get_value_q"))
|
||||
}
|
||||
}
|
||||
|
@ -32,13 +32,14 @@ impl RPCProcessor {
|
||||
|
||||
// Update our routing table with signed node info
|
||||
if !self.filter_peer_scope(&node_info_update.signed_node_info.node_info) {
|
||||
return Err(rpc_error_invalid_format(
|
||||
return Err(RPCError::invalid_format(
|
||||
"node_info_update has invalid peer scope",
|
||||
));
|
||||
}
|
||||
let _ = self
|
||||
.routing_table()
|
||||
.register_node_with_signed_node_info(sender_node_id, node_info_update.signed_node_info)
|
||||
.map_err(map_to_string)
|
||||
.map_err(RPCError::Internal)?;
|
||||
|
||||
Ok(())
|
||||
|
@ -35,6 +35,6 @@ impl RPCProcessor {
|
||||
network_manager
|
||||
.handle_in_band_receipt(receipt, msg.header.peer_noderef)
|
||||
.await
|
||||
.map_err(map_error_string!())
|
||||
.map_err(RPCError::network)
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,6 @@ impl RPCProcessor {
|
||||
|
||||
pub(crate) async fn process_route(&self, _rpcreader: RPCMessage) -> Result<(), RPCError> {
|
||||
// xxx do not process latency for routed messages
|
||||
Err(rpc_error_unimplemented("process_route"))
|
||||
Err(RPCError::unimplemented("process_route"))
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,6 @@ use super::*;
|
||||
|
||||
impl RPCProcessor {
|
||||
pub(crate) async fn process_set_value_q(&self, msg: RPCMessage) -> Result<(), RPCError> {
|
||||
Err(rpc_error_unimplemented("process_set_value_q"))
|
||||
Err(RPCError::unimplemented("process_set_value_q"))
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,6 @@ impl RPCProcessor {
|
||||
network_manager
|
||||
.handle_signal(signal.signal_info)
|
||||
.await
|
||||
.map_err(map_error_string!())
|
||||
.map_err(RPCError::network)
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,6 @@ use super::*;
|
||||
|
||||
impl RPCProcessor {
|
||||
pub(crate) async fn process_start_tunnel_q(&self, msg: RPCMessage) -> Result<(), RPCError> {
|
||||
Err(rpc_error_unimplemented("process_start_tunnel_q"))
|
||||
Err(RPCError::unimplemented("process_start_tunnel_q"))
|
||||
}
|
||||
}
|
||||
|
@ -24,9 +24,9 @@ impl RPCProcessor {
|
||||
let status_a = match msg.operation.into_kind() {
|
||||
RPCOperationKind::Answer(a) => match a.into_detail() {
|
||||
RPCAnswerDetail::StatusA(a) => a,
|
||||
_ => return Err(rpc_error_invalid_format("not a status answer")),
|
||||
_ => return Err(RPCError::invalid_format("not a status answer")),
|
||||
},
|
||||
_ => return Err(rpc_error_invalid_format("not an answer")),
|
||||
_ => return Err(RPCError::invalid_format("not an answer")),
|
||||
};
|
||||
|
||||
// Update latest node status in routing table
|
||||
|
@ -2,6 +2,6 @@ use super::*;
|
||||
|
||||
impl RPCProcessor {
|
||||
pub(crate) async fn process_supply_block_q(&self, msg: RPCMessage) -> Result<(), RPCError> {
|
||||
Err(rpc_error_unimplemented("process_supply_block_q"))
|
||||
Err(RPCError::unimplemented("process_supply_block_q"))
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ impl RPCProcessor {
|
||||
// Generate receipt and waitable eventual so we can see if we get the receipt back
|
||||
let (receipt, eventual_value) = network_manager
|
||||
.generate_single_shot_receipt(receipt_time, [])
|
||||
.map_err(map_error_string!())?;
|
||||
.map_err(RPCError::internal)?;
|
||||
|
||||
let validate_dial_info = RPCOperationValidateDialInfo {
|
||||
dial_info,
|
||||
@ -36,7 +36,7 @@ impl RPCProcessor {
|
||||
|
||||
// Wait for receipt
|
||||
match eventual_value.await.take_value().unwrap() {
|
||||
ReceiptEvent::ReturnedInBand { inbound_noderef: _ } => Err(rpc_error_internal(
|
||||
ReceiptEvent::ReturnedInBand { inbound_noderef: _ } => Err(RPCError::internal(
|
||||
"validate_dial_info receipt should be returned out-of-band",
|
||||
)),
|
||||
ReceiptEvent::ReturnedOutOfBand => {
|
||||
@ -48,7 +48,7 @@ impl RPCProcessor {
|
||||
Ok(false)
|
||||
}
|
||||
ReceiptEvent::Cancelled => {
|
||||
Err(rpc_error_internal("receipt was dropped before expiration"))
|
||||
Err(RPCError::internal("receipt was dropped before expiration"))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -82,7 +82,7 @@ impl RPCProcessor {
|
||||
};
|
||||
let peers = routing_table.find_fast_public_nodes_filtered(node_count, &filter);
|
||||
if peers.is_empty() {
|
||||
return Err(rpc_error_internal(format!(
|
||||
return Err(RPCError::internal(format!(
|
||||
"no peers matching filter '{:?}'",
|
||||
filter
|
||||
)));
|
||||
@ -148,10 +148,7 @@ impl RPCProcessor {
|
||||
network_manager
|
||||
.send_out_of_band_receipt(dial_info.clone(), receipt)
|
||||
.await
|
||||
.map_err(map_error_string!())
|
||||
.map_err(
|
||||
logthru_net!(error "failed to send direct receipt to dial info: {}", dial_info),
|
||||
)?;
|
||||
.map_err(RPCError::network)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -2,6 +2,6 @@ use super::*;
|
||||
|
||||
impl RPCProcessor {
|
||||
pub(crate) async fn process_value_changed(&self, msg: RPCMessage) -> Result<(), RPCError> {
|
||||
Err(rpc_error_unimplemented("process_value_changed"))
|
||||
Err(RPCError::unimplemented("process_value_changed"))
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,6 @@ use super::*;
|
||||
|
||||
impl RPCProcessor {
|
||||
pub(crate) async fn process_watch_value_q(&self, msg: RPCMessage) -> Result<(), RPCError> {
|
||||
Err(rpc_error_unimplemented("process_watch_value_q"))
|
||||
Err(RPCError::unimplemented("process_watch_value_q"))
|
||||
}
|
||||
}
|
||||
|
@ -25,55 +25,59 @@ pub async fn test_protected_store(ps: ProtectedStore) {
|
||||
let d1: [u8; 0] = [];
|
||||
|
||||
assert_eq!(
|
||||
ps.save_user_secret("_test_key", &[2u8, 3u8, 4u8]).await,
|
||||
Ok(false)
|
||||
ps.save_user_secret("_test_key", &[2u8, 3u8, 4u8])
|
||||
.await
|
||||
.unwrap(),
|
||||
false
|
||||
);
|
||||
info!("testing saving user secret");
|
||||
assert_eq!(ps.save_user_secret("_test_key", &d1).await, Ok(true));
|
||||
assert_eq!(ps.save_user_secret("_test_key", &d1).await.unwrap(), true);
|
||||
info!("testing loading user secret");
|
||||
assert_eq!(
|
||||
ps.load_user_secret("_test_key").await,
|
||||
Ok(Some(d1.to_vec()))
|
||||
ps.load_user_secret("_test_key").await.unwrap(),
|
||||
Some(d1.to_vec())
|
||||
);
|
||||
info!("testing loading user secret again");
|
||||
assert_eq!(
|
||||
ps.load_user_secret("_test_key").await,
|
||||
Ok(Some(d1.to_vec()))
|
||||
ps.load_user_secret("_test_key").await.unwrap(),
|
||||
Some(d1.to_vec())
|
||||
);
|
||||
info!("testing loading broken user secret");
|
||||
assert_eq!(ps.load_user_secret("_test_broken").await, Ok(None));
|
||||
assert_eq!(ps.load_user_secret("_test_broken").await.unwrap(), None);
|
||||
info!("testing loading broken user secret again");
|
||||
assert_eq!(ps.load_user_secret("_test_broken").await, Ok(None));
|
||||
assert_eq!(ps.load_user_secret("_test_broken").await.unwrap(), None);
|
||||
info!("testing remove user secret");
|
||||
assert_eq!(ps.remove_user_secret("_test_key").await, Ok(true));
|
||||
assert_eq!(ps.remove_user_secret("_test_key").await.unwrap(), true);
|
||||
info!("testing remove user secret again");
|
||||
assert_eq!(ps.remove_user_secret("_test_key").await, Ok(false));
|
||||
assert_eq!(ps.remove_user_secret("_test_key").await.unwrap(), false);
|
||||
info!("testing remove broken user secret");
|
||||
assert_eq!(ps.remove_user_secret("_test_broken").await, Ok(false));
|
||||
assert_eq!(ps.remove_user_secret("_test_broken").await.unwrap(), false);
|
||||
info!("testing remove broken user secret again");
|
||||
assert_eq!(ps.remove_user_secret("_test_broken").await, Ok(false));
|
||||
assert_eq!(ps.remove_user_secret("_test_broken").await.unwrap(), false);
|
||||
|
||||
let d2: [u8; 10] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
|
||||
assert_eq!(
|
||||
ps.save_user_secret("_test_key", &[2u8, 3u8, 4u8]).await,
|
||||
Ok(false)
|
||||
ps.save_user_secret("_test_key", &[2u8, 3u8, 4u8])
|
||||
.await
|
||||
.unwrap(),
|
||||
false
|
||||
);
|
||||
assert_eq!(ps.save_user_secret("_test_key", &d2).await, Ok(true));
|
||||
assert_eq!(ps.save_user_secret("_test_key", &d2).await.unwrap(), true);
|
||||
assert_eq!(
|
||||
ps.load_user_secret("_test_key").await,
|
||||
Ok(Some(d2.to_vec()))
|
||||
ps.load_user_secret("_test_key").await.unwrap(),
|
||||
Some(d2.to_vec())
|
||||
);
|
||||
assert_eq!(
|
||||
ps.load_user_secret("_test_key").await,
|
||||
Ok(Some(d2.to_vec()))
|
||||
ps.load_user_secret("_test_key").await.unwrap(),
|
||||
Some(d2.to_vec())
|
||||
);
|
||||
assert_eq!(ps.load_user_secret("_test_broken").await, Ok(None));
|
||||
assert_eq!(ps.load_user_secret("_test_broken").await, Ok(None));
|
||||
assert_eq!(ps.remove_user_secret("_test_key").await, Ok(true));
|
||||
assert_eq!(ps.remove_user_secret("_test_key").await, Ok(false));
|
||||
assert_eq!(ps.remove_user_secret("_test_broken").await, Ok(false));
|
||||
assert_eq!(ps.remove_user_secret("_test_broken").await, Ok(false));
|
||||
assert_eq!(ps.load_user_secret("_test_broken").await.unwrap(), None);
|
||||
assert_eq!(ps.load_user_secret("_test_broken").await.unwrap(), None);
|
||||
assert_eq!(ps.remove_user_secret("_test_key").await.unwrap(), true);
|
||||
assert_eq!(ps.remove_user_secret("_test_key").await.unwrap(), false);
|
||||
assert_eq!(ps.remove_user_secret("_test_broken").await.unwrap(), false);
|
||||
assert_eq!(ps.remove_user_secret("_test_broken").await.unwrap(), false);
|
||||
|
||||
let _ = ps.remove_user_secret("_test_key").await;
|
||||
let _ = ps.remove_user_secret("_test_broken").await;
|
||||
|
@ -59,8 +59,8 @@ pub async fn test_store_delete_load(ts: TableStore) {
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
db.load(0, b"foo").await,
|
||||
Ok(None),
|
||||
db.load(0, b"foo").await.unwrap(),
|
||||
None,
|
||||
"should not load missing key"
|
||||
);
|
||||
assert!(
|
||||
@ -68,11 +68,14 @@ pub async fn test_store_delete_load(ts: TableStore) {
|
||||
"should store new key"
|
||||
);
|
||||
assert_eq!(
|
||||
db.load(0, b"foo").await,
|
||||
Ok(None),
|
||||
db.load(0, b"foo").await.unwrap(),
|
||||
None,
|
||||
"should not load missing key"
|
||||
);
|
||||
assert_eq!(db.load(1, b"foo").await, Ok(Some(b"1234567890".to_vec())));
|
||||
assert_eq!(
|
||||
db.load(1, b"foo").await.unwrap(),
|
||||
Some(b"1234567890".to_vec())
|
||||
);
|
||||
|
||||
assert!(
|
||||
db.store(1, b"bar", b"FNORD").await.is_ok(),
|
||||
@ -97,16 +100,19 @@ pub async fn test_store_delete_load(ts: TableStore) {
|
||||
"should store new key"
|
||||
);
|
||||
|
||||
assert_eq!(db.load(1, b"bar").await, Ok(Some(b"FNORD".to_vec())));
|
||||
assert_eq!(db.load(1, b"bar").await.unwrap(), Some(b"FNORD".to_vec()));
|
||||
assert_eq!(
|
||||
db.load(0, b"bar").await,
|
||||
Ok(Some(b"ABCDEFGHIJKLMNOPQRSTUVWXYZ".to_vec()))
|
||||
db.load(0, b"bar").await.unwrap(),
|
||||
Some(b"ABCDEFGHIJKLMNOPQRSTUVWXYZ".to_vec())
|
||||
);
|
||||
assert_eq!(db.load(2, b"bar").await, Ok(Some(b"QWERTYUIOP".to_vec())));
|
||||
assert_eq!(db.load(2, b"baz").await, Ok(Some(b"QWERTY".to_vec())));
|
||||
assert_eq!(
|
||||
db.load(2, b"bar").await.unwrap(),
|
||||
Some(b"QWERTYUIOP".to_vec())
|
||||
);
|
||||
assert_eq!(db.load(2, b"baz").await.unwrap(), Some(b"QWERTY".to_vec()));
|
||||
|
||||
assert_eq!(db.delete(1, b"bar").await, Ok(true));
|
||||
assert_eq!(db.delete(1, b"bar").await, Ok(false));
|
||||
assert_eq!(db.delete(1, b"bar").await.unwrap(), true);
|
||||
assert_eq!(db.delete(1, b"bar").await.unwrap(), false);
|
||||
assert!(
|
||||
db.delete(4, b"bar").await.is_err(),
|
||||
"can't delete from column that doesn't exist"
|
||||
@ -115,13 +121,16 @@ pub async fn test_store_delete_load(ts: TableStore) {
|
||||
drop(db);
|
||||
let db = ts.open("test", 3).await.expect("should have opened");
|
||||
|
||||
assert_eq!(db.load(1, b"bar").await, Ok(None));
|
||||
assert_eq!(db.load(1, b"bar").await.unwrap(), None);
|
||||
assert_eq!(
|
||||
db.load(0, b"bar").await,
|
||||
Ok(Some(b"ABCDEFGHIJKLMNOPQRSTUVWXYZ".to_vec()))
|
||||
db.load(0, b"bar").await.unwrap(),
|
||||
Some(b"ABCDEFGHIJKLMNOPQRSTUVWXYZ".to_vec())
|
||||
);
|
||||
assert_eq!(db.load(2, b"bar").await, Ok(Some(b"QWERTYUIOP".to_vec())));
|
||||
assert_eq!(db.load(2, b"baz").await, Ok(Some(b"QWERTY".to_vec())));
|
||||
assert_eq!(
|
||||
db.load(2, b"bar").await.unwrap(),
|
||||
Some(b"QWERTYUIOP".to_vec())
|
||||
);
|
||||
assert_eq!(db.load(2, b"baz").await.unwrap(), Some(b"QWERTY".to_vec()));
|
||||
}
|
||||
|
||||
pub async fn test_cbor(ts: TableStore) {
|
||||
@ -133,7 +142,7 @@ pub async fn test_cbor(ts: TableStore) {
|
||||
|
||||
assert!(db.store_cbor(0, b"asdf", &dht_key).await.is_ok());
|
||||
|
||||
assert_eq!(db.load_cbor::<DHTKey>(0, b"qwer").await, Ok(None));
|
||||
assert_eq!(db.load_cbor::<DHTKey>(0, b"qwer").await.unwrap(), None);
|
||||
|
||||
let d = match db.load_cbor::<DHTKey>(0, b"asdf").await {
|
||||
Ok(x) => x,
|
||||
|
@ -87,44 +87,39 @@ macro_rules! apibail_parse {
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialOrd, PartialEq, Eq, Ord, Serialize, Deserialize)]
|
||||
#[derive(ThisError, Clone, Debug, PartialOrd, PartialEq, Eq, Ord, Serialize, Deserialize)]
|
||||
#[serde(tag = "kind")]
|
||||
pub enum VeilidAPIError {
|
||||
#[error("Not initialized")]
|
||||
NotInitialized,
|
||||
#[error("Already initialized")]
|
||||
AlreadyInitialized,
|
||||
#[error("Timeout")]
|
||||
Timeout,
|
||||
#[error("Shutdown")]
|
||||
Shutdown,
|
||||
NodeNotFound {
|
||||
node_id: NodeId,
|
||||
},
|
||||
NoDialInfo {
|
||||
node_id: NodeId,
|
||||
},
|
||||
NoPeerInfo {
|
||||
node_id: NodeId,
|
||||
},
|
||||
Internal {
|
||||
message: String,
|
||||
},
|
||||
Unimplemented {
|
||||
message: String,
|
||||
},
|
||||
ParseError {
|
||||
message: String,
|
||||
value: String,
|
||||
},
|
||||
#[error("Node not found: {node_id}")]
|
||||
NodeNotFound { node_id: NodeId },
|
||||
#[error("No dial info: {node_id}")]
|
||||
NoDialInfo { node_id: NodeId },
|
||||
#[error("No peer info: {node_id}")]
|
||||
NoPeerInfo { node_id: NodeId },
|
||||
#[error("Internal: {message}")]
|
||||
Internal { message: String },
|
||||
#[error("Unimplemented: {message}")]
|
||||
Unimplemented { message: String },
|
||||
#[error("Parse error: '{message}' with value '{value}'")]
|
||||
ParseError { message: String, value: String },
|
||||
#[error("Invalid argument: '{argument}' for '{context}' with value '{value}'")]
|
||||
InvalidArgument {
|
||||
context: String,
|
||||
argument: String,
|
||||
value: String,
|
||||
},
|
||||
MissingArgument {
|
||||
context: String,
|
||||
argument: String,
|
||||
},
|
||||
Generic {
|
||||
message: String,
|
||||
},
|
||||
#[error("Missing argument: '{argument}' for '{context}'")]
|
||||
MissingArgument { context: String, argument: String },
|
||||
#[error("Generic: {message}")]
|
||||
Generic { message: String },
|
||||
}
|
||||
|
||||
impl VeilidAPIError {
|
||||
@ -177,79 +172,6 @@ impl VeilidAPIError {
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for VeilidAPIError {}
|
||||
|
||||
impl fmt::Display for VeilidAPIError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||
match self {
|
||||
VeilidAPIError::NotInitialized => write!(f, "VeilidAPIError::NotInitialized"),
|
||||
VeilidAPIError::AlreadyInitialized => write!(f, "VeilidAPIError::AlreadyInitialized"),
|
||||
VeilidAPIError::Timeout => write!(f, "VeilidAPIError::Timeout"),
|
||||
VeilidAPIError::Shutdown => write!(f, "VeilidAPIError::Shutdown"),
|
||||
VeilidAPIError::NodeNotFound { node_id } => {
|
||||
write!(f, "VeilidAPIError::NodeNotFound({})", node_id)
|
||||
}
|
||||
VeilidAPIError::NoDialInfo { node_id } => {
|
||||
write!(f, "VeilidAPIError::NoDialInfo({})", node_id)
|
||||
}
|
||||
VeilidAPIError::NoPeerInfo { node_id } => {
|
||||
write!(f, "VeilidAPIError::NoPeerInfo({})", node_id)
|
||||
}
|
||||
VeilidAPIError::Internal { message } => {
|
||||
write!(f, "VeilidAPIError::Internal({})", message)
|
||||
}
|
||||
VeilidAPIError::Unimplemented { message } => {
|
||||
write!(f, "VeilidAPIError::Unimplemented({})", message)
|
||||
}
|
||||
VeilidAPIError::ParseError { message, value } => {
|
||||
write!(f, "VeilidAPIError::ParseError({}: {})", message, value)
|
||||
}
|
||||
VeilidAPIError::InvalidArgument {
|
||||
context,
|
||||
argument,
|
||||
value,
|
||||
} => {
|
||||
write!(
|
||||
f,
|
||||
"VeilidAPIError::InvalidArgument({}: {} = {})",
|
||||
context, argument, value
|
||||
)
|
||||
}
|
||||
VeilidAPIError::MissingArgument { context, argument } => {
|
||||
write!(
|
||||
f,
|
||||
"VeilidAPIError::MissingArgument({}: {})",
|
||||
context, argument
|
||||
)
|
||||
}
|
||||
VeilidAPIError::Generic { message } => {
|
||||
write!(f, "VeilidAPIError::Generic({})", message)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fn convert_rpc_error(x: RPCError) -> VeilidAPIError {
|
||||
// match x {
|
||||
// RPCError::Timeout => VeilidAPIError::Timeout,
|
||||
// RPCError::Unreachable(n) => VeilidAPIError::NodeNotFound {
|
||||
// node_id: NodeId::new(n),
|
||||
// },
|
||||
// RPCError::Unimplemented(s) => VeilidAPIError::Unimplemented { message: s },
|
||||
// RPCError::Internal(s) => VeilidAPIError::Internal { message: s },
|
||||
// RPCError::Protocol(s) => VeilidAPIError::Internal { message: s },
|
||||
// RPCError::InvalidFormat(s) => VeilidAPIError::Internal {
|
||||
// message: format!("Invalid RPC format: {}", s),
|
||||
// },
|
||||
// }
|
||||
// }
|
||||
|
||||
// macro_rules! map_rpc_error {
|
||||
// () => {
|
||||
// |x| convert_rpc_error(x)
|
||||
// };
|
||||
// }
|
||||
|
||||
macro_rules! parse_error {
|
||||
($msg:expr, $val:expr) => {
|
||||
VeilidAPIError::ParseError {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user