This commit is contained in:
John Smith 2022-07-10 17:36:50 -04:00
parent cd0cd78e30
commit 7e0d7dad06
108 changed files with 1378 additions and 1535 deletions

2
Cargo.lock generated
View File

@ -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",

View File

@ -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"

View File

@ -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();

View File

@ -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,

View File

@ -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())
}

View File

@ -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);

View File

@ -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);

View File

@ -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)?;

View File

@ -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
}
}

View File

@ -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");
}
}
}

View File

@ -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();

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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();

View File

@ -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)
}
}

View File

@ -23,7 +23,7 @@ impl BlockStore {
}
}
pub async fn init(&self) -> Result<(), String> {
pub async fn init(&self) -> EyreResult<()> {
Ok(())
}

View File

@ -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
}
}

View File

@ -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")
}

View File

@ -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")
}
}

View File

@ -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 {

View File

@ -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();

View File

@ -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)

View File

@ -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();

View File

@ -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();

View File

@ -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);

View File

@ -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 {

View File

@ -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 {

View File

@ -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,

View File

@ -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)?;

View File

@ -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))
}
}

View File

@ -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,
));

View File

@ -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))
}
}

View File

@ -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 {

View File

@ -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
}
}

View File

@ -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(())
}
}

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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?;

View File

@ -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();

View File

@ -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")),
}
}

View File

@ -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(())
}

View File

@ -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());
}

View File

@ -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 })
}

View File

@ -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),

View File

@ -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 {

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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))
}
}

View File

@ -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))
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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 })

View File

@ -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 })

View File

@ -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 {

View File

@ -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);

View File

@ -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))
}
}

View File

@ -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 {

View File

@ -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);

View File

@ -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();

View File

@ -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 })
}

View File

@ -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);

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)?;

View File

@ -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 {

View File

@ -23,27 +23,27 @@ pub fn encode_public_key(
builder: &mut veilid_capnp::curve25519_public_key::Builder,
) -> Result<(), RPCError> {
if !key.valid {
return Err(rpc_error_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(())
}

View File

@ -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

View File

@ -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)?;

View File

@ -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)
}

View File

@ -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();

View File

@ -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 })

View File

@ -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 })
}

View File

@ -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 })

View File

@ -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")
};
}

View File

@ -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(())
}
}

View File

@ -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)?;

View File

@ -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"))
}
}

View File

@ -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"))
}
}

View 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()))
}
}

View File

@ -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"))
}
}

View File

@ -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",
));
}

View File

@ -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"))
}
}

View File

@ -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(())

View File

@ -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)
}
}

View File

@ -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"))
}
}

View File

@ -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"))
}
}

View File

@ -34,6 +34,6 @@ impl RPCProcessor {
network_manager
.handle_signal(signal.signal_info)
.await
.map_err(map_error_string!())
.map_err(RPCError::network)
}
}

View File

@ -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"))
}
}

View File

@ -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

View File

@ -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"))
}
}

View File

@ -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(())
}

View File

@ -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"))
}
}

View File

@ -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"))
}
}

View File

@ -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;

View File

@ -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,

View File

@ -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