From b52e64e56a2235b673c0d39fcd94ae431987c0da Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Sun, 22 Jun 2025 19:06:26 -0400 Subject: [PATCH] Handle NotInSchema --- CHANGELOG.md | 5 + .../src/rpc_processor/coders/address.rs | 53 ++--- .../rpc_processor/coders/address_type_set.rs | 28 +-- .../src/rpc_processor/coders/dial_info.rs | 40 ++-- .../rpc_processor/coders/dial_info_class.rs | 22 +- .../rpc_processor/coders/dial_info_detail.rs | 26 +-- .../src/rpc_processor/coders/network_class.rs | 18 +- .../src/rpc_processor/coders/node_info.rs | 207 ++++++++---------- .../rpc_processor/coders/operations/answer.rs | 26 +-- .../coders/operations/operation.rs | 12 +- .../coders/operations/operation_app_call.rs | 16 +- .../operations/operation_app_message.rs | 9 +- .../operations/operation_cancel_tunnel.rs | 4 +- .../operations/operation_complete_tunnel.rs | 13 +- .../coders/operations/operation_find_block.rs | 54 ++--- .../coders/operations/operation_find_node.rs | 19 +- .../coders/operations/operation_get_value.rs | 33 ++- .../operations/operation_inspect_value.rs | 51 ++--- .../operations/operation_return_receipt.rs | 10 +- .../coders/operations/operation_route.rs | 18 +- .../coders/operations/operation_set_value.rs | 34 ++- .../operations/operation_start_tunnel.rs | 2 +- .../coders/operations/operation_status.rs | 6 +- .../operations/operation_supply_block.rs | 19 +- .../operation_validate_dial_info.rs | 18 +- .../operations/operation_value_changed.rs | 14 +- .../operations/operation_watch_value.rs | 37 ++-- .../coders/operations/question.rs | 26 +-- .../coders/operations/respond_to.rs | 30 +-- .../coders/operations/statement.rs | 14 +- .../src/rpc_processor/coders/peer_info.rs | 49 +++-- .../coders/private_safety_route.rs | 179 +++++++-------- .../rpc_processor/coders/protocol_type_set.rs | 42 ++-- .../src/rpc_processor/coders/sender_info.rs | 24 +- .../src/rpc_processor/coders/sequencing.rs | 16 +- .../src/rpc_processor/coders/signal_info.rs | 75 +++---- .../coders/signed_direct_node_info.rs | 61 +++--- .../rpc_processor/coders/signed_node_info.rs | 37 ++-- .../coders/signed_relayed_node_info.rs | 100 ++++----- .../rpc_processor/coders/signed_value_data.rs | 35 +-- .../coders/signed_value_descriptor.rs | 28 +-- .../rpc_processor/coders/socket_address.rs | 26 +-- .../src/rpc_processor/coders/tunnel.rs | 91 ++++---- .../src/rpc_processor/coders/typed_key.rs | 29 +-- .../rpc_processor/coders/typed_signature.rs | 9 +- .../src/rpc_processor/coders/value_data.rs | 38 ++-- veilid-core/src/rpc_processor/error.rs | 74 +++++++ veilid-core/src/rpc_processor/mod.rs | 4 +- veilid-core/src/rpc_processor/rpc_route.rs | 4 +- 49 files changed, 858 insertions(+), 927 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0260e468..8174ab08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ - Rename crypto types: - {CryptoBytes} -> Bare{CryptoBytes} - Typed{CryptoBytes} -> {CryptoBytes} + - Handle NotInSchema: + - switch match alternative failures and list decode failures to `RPCError::Ignore` from `RPCError::Protocol` to keep from punishing newer nodes + - add `.ignore_ok()` trait that makes it easy to 'soft fail' `RPCError::Ignore` + - add `rpc_ignore_*` macros + - canonicalize coders' handling of lengths **Changed in Veilid 0.4.8** diff --git a/veilid-core/src/rpc_processor/coders/address.rs b/veilid-core/src/rpc_processor/coders/address.rs index 7e18ac02..191ac7f4 100644 --- a/veilid-core/src/rpc_processor/coders/address.rs +++ b/veilid-core/src/rpc_processor/coders/address.rs @@ -1,10 +1,28 @@ use super::*; use core::convert::TryInto; -pub fn encode_address( - address: &Address, - builder: &mut veilid_capnp::address::Builder, -) -> Result<(), RPCError> { +pub fn decode_address(reader: &veilid_capnp::address::Reader) -> Result { + match reader.reborrow().which()? { + veilid_capnp::address::Which::Ipv4(v4) => { + let v4 = v4?; + let v4b = v4.get_addr().to_be_bytes(); + Ok(Address::IPV4(Ipv4Addr::new(v4b[0], v4b[1], v4b[2], v4b[3]))) + } + veilid_capnp::address::Which::Ipv6(v6) => { + let v6 = v6?; + let v6b0 = v6.get_addr0().to_be_bytes(); + let v6b1 = v6.get_addr1().to_be_bytes(); + let v6b2 = v6.get_addr2().to_be_bytes(); + let v6b3 = v6.get_addr3().to_be_bytes(); + Ok(Address::IPV6(Ipv6Addr::from([ + v6b0[0], v6b0[1], v6b0[2], v6b0[3], v6b1[0], v6b1[1], v6b1[2], v6b1[3], v6b2[0], + v6b2[1], v6b2[2], v6b2[3], v6b3[0], v6b3[1], v6b3[2], v6b3[3], + ]))) + } + } +} + +pub fn encode_address(address: &Address, builder: &mut veilid_capnp::address::Builder) { match address { Address::IPV4(v4) => { let mut v4b = builder.reborrow().init_ipv4(); @@ -34,31 +52,4 @@ pub fn encode_address( )); } }; - Ok(()) -} - -pub fn decode_address(reader: &veilid_capnp::address::Reader) -> Result { - match reader.reborrow().which() { - Ok(veilid_capnp::address::Which::Ipv4(Ok(v4))) => { - let v4b = v4.get_addr().to_be_bytes(); - Ok(Address::IPV4(Ipv4Addr::new(v4b[0], v4b[1], v4b[2], v4b[3]))) - } - Ok(veilid_capnp::address::Which::Ipv6(Ok(v6))) => { - let v6b0 = v6.get_addr0().to_be_bytes(); - let v6b1 = v6.get_addr1().to_be_bytes(); - let v6b2 = v6.get_addr2().to_be_bytes(); - let v6b3 = v6.get_addr3().to_be_bytes(); - Ok(Address::IPV6(Ipv6Addr::from([ - v6b0[0], v6b0[1], v6b0[2], v6b0[3], v6b1[0], v6b1[1], v6b1[2], v6b1[3], v6b2[0], - v6b2[1], v6b2[2], v6b2[3], v6b3[0], v6b3[1], v6b3[2], v6b3[3], - ]))) - } - 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")), - } } diff --git a/veilid-core/src/rpc_processor/coders/address_type_set.rs b/veilid-core/src/rpc_processor/coders/address_type_set.rs index f341d980..d370ba0c 100644 --- a/veilid-core/src/rpc_processor/coders/address_type_set.rs +++ b/veilid-core/src/rpc_processor/coders/address_type_set.rs @@ -1,24 +1,20 @@ use super::*; +pub fn decode_address_type_set(reader: &veilid_capnp::address_type_set::Reader) -> AddressTypeSet { + let mut out = AddressTypeSet::new(); + if reader.get_ipv4() { + out.insert(AddressType::IPV4); + } + if reader.get_ipv6() { + out.insert(AddressType::IPV6); + } + out +} + pub fn encode_address_type_set( address_type_set: &AddressTypeSet, builder: &mut veilid_capnp::address_type_set::Builder, -) -> Result<(), RPCError> { +) { builder.set_ipv4(address_type_set.contains(AddressType::IPV4)); builder.set_ipv6(address_type_set.contains(AddressType::IPV6)); - - Ok(()) -} - -pub fn decode_address_type_set( - reader: &veilid_capnp::address_type_set::Reader, -) -> Result { - let mut out = AddressTypeSet::new(); - if reader.reborrow().get_ipv4() { - out.insert(AddressType::IPV4); - } - if reader.reborrow().get_ipv6() { - out.insert(AddressType::IPV6); - } - Ok(out) } diff --git a/veilid-core/src/rpc_processor/coders/dial_info.rs b/veilid-core/src/rpc_processor/coders/dial_info.rs index 94d3c9ae..052543a1 100644 --- a/veilid-core/src/rpc_processor/coders/dial_info.rs +++ b/veilid-core/src/rpc_processor/coders/dial_info.rs @@ -2,36 +2,28 @@ use super::*; use core::convert::TryInto; pub fn decode_dial_info(reader: &veilid_capnp::dial_info::Reader) -> Result { - match reader - .reborrow() - .which() - .map_err(RPCError::map_protocol("Missing dial info type"))? - { + match reader.reborrow().which()? { veilid_capnp::dial_info::Which::Udp(udp) => { - let socket_address_reader = udp - .map_err(RPCError::protocol)? - .get_socket_address() - .map_err(RPCError::map_protocol("missing UDP socketAddress"))?; + let udp = udp?; + rpc_ignore_missing_property!(udp, socket_address); + let socket_address_reader = udp.get_socket_address()?; let socket_address = decode_socket_address(&socket_address_reader)?; Ok(DialInfo::udp(socket_address)) } veilid_capnp::dial_info::Which::Tcp(tcp) => { - let socket_address_reader = tcp - .map_err(RPCError::protocol)? - .get_socket_address() - .map_err(RPCError::map_protocol("missing TCP socketAddress"))?; + let tcp = tcp?; + rpc_ignore_missing_property!(tcp, socket_address); + let socket_address_reader = tcp.get_socket_address()?; let socket_address = decode_socket_address(&socket_address_reader)?; Ok(DialInfo::tcp(socket_address)) } veilid_capnp::dial_info::Which::Ws(ws) => { - let ws = ws.map_err(RPCError::protocol)?; - let socket_address_reader = ws - .get_socket_address() - .map_err(RPCError::map_protocol("missing WS socketAddress"))?; + let ws = ws?; + rpc_ignore_missing_property!(ws, socket_address); + let socket_address_reader = ws.get_socket_address()?; let socket_address = decode_socket_address(&socket_address_reader)?; - let request = ws - .get_request() - .map_err(RPCError::map_protocol("missing WS request"))?; + rpc_ignore_missing_property!(ws, request); + let request = ws.get_request()?; DialInfo::try_ws( socket_address, request @@ -41,14 +33,14 @@ pub fn decode_dial_info(reader: &veilid_capnp::dial_info::Reader) -> Result { - let wss = wss.map_err(RPCError::protocol)?; + let wss = wss?; + rpc_ignore_missing_property!(wss, socket_address); let socket_address_reader = wss .get_socket_address() .map_err(RPCError::map_protocol("missing WSS socketAddress"))?; let socket_address = decode_socket_address(&socket_address_reader)?; - let request = wss - .get_request() - .map_err(RPCError::map_protocol("missing WSS request"))?; + rpc_ignore_missing_property!(wss, request); + let request = wss.get_request()?; DialInfo::try_wss( socket_address, request diff --git a/veilid-core/src/rpc_processor/coders/dial_info_class.rs b/veilid-core/src/rpc_processor/coders/dial_info_class.rs index 835f060e..7aa4ca85 100644 --- a/veilid-core/src/rpc_processor/coders/dial_info_class.rs +++ b/veilid-core/src/rpc_processor/coders/dial_info_class.rs @@ -1,16 +1,5 @@ use super::*; -pub fn encode_dial_info_class(dial_info_class: DialInfoClass) -> veilid_capnp::DialInfoClass { - match dial_info_class { - DialInfoClass::Direct => veilid_capnp::DialInfoClass::Direct, - DialInfoClass::Mapped => veilid_capnp::DialInfoClass::Mapped, - DialInfoClass::FullConeNAT => veilid_capnp::DialInfoClass::FullConeNAT, - DialInfoClass::Blocked => veilid_capnp::DialInfoClass::Blocked, - DialInfoClass::AddressRestrictedNAT => veilid_capnp::DialInfoClass::AddressRestrictedNAT, - DialInfoClass::PortRestrictedNAT => veilid_capnp::DialInfoClass::PortRestrictedNAT, - } -} - pub fn decode_dial_info_class(dial_info_class: veilid_capnp::DialInfoClass) -> DialInfoClass { match dial_info_class { veilid_capnp::DialInfoClass::Direct => DialInfoClass::Direct, @@ -21,3 +10,14 @@ pub fn decode_dial_info_class(dial_info_class: veilid_capnp::DialInfoClass) -> D veilid_capnp::DialInfoClass::PortRestrictedNAT => DialInfoClass::PortRestrictedNAT, } } + +pub fn encode_dial_info_class(dial_info_class: DialInfoClass) -> veilid_capnp::DialInfoClass { + match dial_info_class { + DialInfoClass::Direct => veilid_capnp::DialInfoClass::Direct, + DialInfoClass::Mapped => veilid_capnp::DialInfoClass::Mapped, + DialInfoClass::FullConeNAT => veilid_capnp::DialInfoClass::FullConeNAT, + DialInfoClass::Blocked => veilid_capnp::DialInfoClass::Blocked, + DialInfoClass::AddressRestrictedNAT => veilid_capnp::DialInfoClass::AddressRestrictedNAT, + DialInfoClass::PortRestrictedNAT => veilid_capnp::DialInfoClass::PortRestrictedNAT, + } +} diff --git a/veilid-core/src/rpc_processor/coders/dial_info_detail.rs b/veilid-core/src/rpc_processor/coders/dial_info_detail.rs index 7b012fe3..94594656 100644 --- a/veilid-core/src/rpc_processor/coders/dial_info_detail.rs +++ b/veilid-core/src/rpc_processor/coders/dial_info_detail.rs @@ -1,5 +1,16 @@ use super::*; +pub fn decode_dial_info_detail( + reader: &veilid_capnp::dial_info_detail::Reader, +) -> Result { + rpc_ignore_missing_property!(reader, dial_info); + let dial_info = decode_dial_info(&reader.get_dial_info()?)?; + + let class = decode_dial_info_class(reader.get_class()?); + + Ok(DialInfoDetail { dial_info, class }) +} + pub fn encode_dial_info_detail( dial_info_detail: &DialInfoDetail, builder: &mut veilid_capnp::dial_info_detail::Builder, @@ -10,18 +21,3 @@ pub fn encode_dial_info_detail( builder.set_class(encode_dial_info_class(dial_info_detail.class)); Ok(()) } - -pub fn decode_dial_info_detail( - reader: &veilid_capnp::dial_info_detail::Reader, -) -> Result { - let dial_info = decode_dial_info( - &reader - .reborrow() - .get_dial_info() - .map_err(RPCError::protocol)?, - )?; - - let class = decode_dial_info_class(reader.reborrow().get_class().map_err(RPCError::protocol)?); - - Ok(DialInfoDetail { dial_info, class }) -} diff --git a/veilid-core/src/rpc_processor/coders/network_class.rs b/veilid-core/src/rpc_processor/coders/network_class.rs index 65bb9e74..e574ab74 100644 --- a/veilid-core/src/rpc_processor/coders/network_class.rs +++ b/veilid-core/src/rpc_processor/coders/network_class.rs @@ -1,14 +1,5 @@ use super::*; -pub fn encode_network_class(network_class: NetworkClass) -> veilid_capnp::NetworkClass { - match network_class { - NetworkClass::InboundCapable => veilid_capnp::NetworkClass::InboundCapable, - NetworkClass::OutboundOnly => veilid_capnp::NetworkClass::OutboundOnly, - NetworkClass::WebApp => veilid_capnp::NetworkClass::WebApp, - NetworkClass::Invalid => veilid_capnp::NetworkClass::Invalid, - } -} - pub fn decode_network_class(network_class: veilid_capnp::NetworkClass) -> NetworkClass { match network_class { veilid_capnp::NetworkClass::InboundCapable => NetworkClass::InboundCapable, @@ -17,3 +8,12 @@ pub fn decode_network_class(network_class: veilid_capnp::NetworkClass) -> Networ veilid_capnp::NetworkClass::Invalid => NetworkClass::Invalid, } } + +pub fn encode_network_class(network_class: NetworkClass) -> veilid_capnp::NetworkClass { + match network_class { + NetworkClass::InboundCapable => veilid_capnp::NetworkClass::InboundCapable, + NetworkClass::OutboundOnly => veilid_capnp::NetworkClass::OutboundOnly, + NetworkClass::WebApp => veilid_capnp::NetworkClass::WebApp, + NetworkClass::Invalid => veilid_capnp::NetworkClass::Invalid, + } +} diff --git a/veilid-core/src/rpc_processor/coders/node_info.rs b/veilid-core/src/rpc_processor/coders/node_info.rs index 197b160d..0a627550 100644 --- a/veilid-core/src/rpc_processor/coders/node_info.rs +++ b/veilid-core/src/rpc_processor/coders/node_info.rs @@ -1,5 +1,89 @@ use super::*; +pub fn decode_node_info(reader: &veilid_capnp::node_info::Reader) -> Result { + let network_class = decode_network_class(reader.get_network_class()?); + + rpc_ignore_missing_property!(reader, outbound_protocols); + let outbound_protocols = decode_protocol_type_set(&reader.get_outbound_protocols()?); + + rpc_ignore_missing_property!(reader, address_types); + let address_types = decode_address_type_set(&reader.get_address_types()?); + + rpc_ignore_missing_property!(reader, envelope_support); + let es_reader = reader.reborrow().get_envelope_support()?; + rpc_ignore_min_max_len!(es_reader, 1, MAX_ENVELOPE_VERSIONS); + let envelope_support = es_reader.as_slice().map(|s| s.to_vec()).unwrap_or_default(); + + // Ensure envelope versions are not duplicated + // Unsorted is okay, some nodes may have a different envelope order preference + // But nothing should show up more than once + let mut eversions = envelope_support.clone(); + eversions.sort(); + eversions.dedup(); + if eversions.len() != envelope_support.len() { + return Err(RPCError::protocol("duplicate envelope versions")); + } + + rpc_ignore_missing_property!(reader, crypto_support); + let cs_reader = reader.get_crypto_support()?; + rpc_ignore_min_max_len!(cs_reader, 1, MAX_CRYPTO_KINDS); + let crypto_support: Vec = cs_reader + .as_slice() + .map(|s| { + s.iter() + .map(|x| CryptoKind::from(x.to_be_bytes())) + .collect() + }) + .unwrap_or_default(); + + // Ensure crypto kinds are not duplicated + // Unsorted is okay, some nodes may have a different crypto order preference + // But nothing should show up more than once + let mut ckinds = crypto_support.clone(); + ckinds.sort(); + ckinds.dedup(); + if ckinds.len() != crypto_support.len() { + return Err(RPCError::protocol("duplicate crypto kinds")); + } + + rpc_ignore_missing_property!(reader, capabilities); + let cap_reader = reader.get_capabilities()?; + rpc_ignore_max_len!(cap_reader, MAX_CAPABILITIES); + let capabilities = cap_reader + .as_slice() + .map(|s| { + s.iter() + .map(|x| VeilidCapability::from(x.to_be_bytes())) + .collect() + }) + .unwrap_or_default(); + + rpc_ignore_missing_property!(reader, dial_info_detail_list); + let didl_reader = reader.get_dial_info_detail_list()?; + let mut dial_info_detail_list = Vec::::with_capacity( + didl_reader + .len() + .try_into() + .map_err(RPCError::map_protocol("too many dial info details"))?, + ); + for did in didl_reader.iter() { + let Some(dial_info_detail) = decode_dial_info_detail(&did).ignore_ok()? else { + continue; + }; + dial_info_detail_list.push(dial_info_detail) + } + + Ok(NodeInfo::new( + network_class, + outbound_protocols, + address_types, + envelope_support, + crypto_support, + capabilities, + dial_info_detail_list, + )) +} + pub fn encode_node_info( node_info: &NodeInfo, builder: &mut veilid_capnp::node_info::Builder, @@ -7,10 +91,10 @@ pub fn encode_node_info( builder.set_network_class(encode_network_class(node_info.network_class())); let mut ps_builder = builder.reborrow().init_outbound_protocols(); - encode_protocol_type_set(&node_info.outbound_protocols(), &mut ps_builder)?; + encode_protocol_type_set(&node_info.outbound_protocols(), &mut ps_builder); let mut ats_builder = builder.reborrow().init_address_types(); - encode_address_type_set(&node_info.address_types(), &mut ats_builder)?; + encode_address_type_set(&node_info.address_types(), &mut ats_builder); let mut es_builder = builder .reborrow() @@ -60,122 +144,3 @@ pub fn encode_node_info( Ok(()) } - -pub fn decode_node_info(reader: &veilid_capnp::node_info::Reader) -> Result { - let network_class = decode_network_class( - reader - .reborrow() - .get_network_class() - .map_err(RPCError::protocol)?, - ); - - let outbound_protocols = decode_protocol_type_set( - &reader - .reborrow() - .get_outbound_protocols() - .map_err(RPCError::protocol)?, - )?; - - let address_types = decode_address_type_set( - &reader - .reborrow() - .get_address_types() - .map_err(RPCError::protocol)?, - )?; - - let es_reader = reader - .reborrow() - .get_envelope_support() - .map_err(RPCError::protocol)?; - let envelope_support = es_reader.as_slice().map(|s| s.to_vec()).unwrap_or_default(); - - // Ensure envelope versions are not duplicated - // Unsorted is okay, some nodes may have a different envelope order preference - // But nothing should show up more than once - let mut eversions = envelope_support.clone(); - eversions.sort(); - eversions.dedup(); - if eversions.len() != envelope_support.len() { - return Err(RPCError::protocol("duplicate envelope versions")); - } - if envelope_support.len() > MAX_ENVELOPE_VERSIONS { - return Err(RPCError::protocol("too many envelope versions")); - } - if envelope_support.is_empty() { - return Err(RPCError::protocol("no envelope versions")); - } - - let cs_reader = reader - .reborrow() - .get_crypto_support() - .map_err(RPCError::protocol)?; - - if cs_reader.len() as usize > MAX_CRYPTO_KINDS { - return Err(RPCError::protocol("too many crypto kinds")); - } - - let crypto_support: Vec = cs_reader - .as_slice() - .map(|s| { - s.iter() - .map(|x| CryptoKind::from(x.to_be_bytes())) - .collect() - }) - .unwrap_or_default(); - - // Ensure crypto kinds are not duplicated - // Unsorted is okay, some nodes may have a different crypto order preference - // But nothing should show up more than once - let mut ckinds = crypto_support.clone(); - ckinds.sort(); - ckinds.dedup(); - if ckinds.len() != crypto_support.len() { - return Err(RPCError::protocol("duplicate crypto kinds")); - } - if crypto_support.len() > MAX_CRYPTO_KINDS { - return Err(RPCError::protocol("too many crypto kinds")); - } - if crypto_support.is_empty() { - return Err(RPCError::protocol("no crypto kinds")); - } - - let cap_reader = reader - .reborrow() - .get_capabilities() - .map_err(RPCError::protocol)?; - if cap_reader.len() as usize > MAX_CAPABILITIES { - return Err(RPCError::protocol("too many capabilities")); - } - let capabilities = cap_reader - .as_slice() - .map(|s| { - s.iter() - .map(|x| VeilidCapability::from(x.to_be_bytes())) - .collect() - }) - .unwrap_or_default(); - - let didl_reader = reader - .reborrow() - .get_dial_info_detail_list() - .map_err(RPCError::protocol)?; - let mut dial_info_detail_list = Vec::::with_capacity( - didl_reader - .len() - .try_into() - .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)?) - } - - Ok(NodeInfo::new( - network_class, - outbound_protocols, - address_types, - envelope_support, - crypto_support, - capabilities, - dial_info_detail_list, - )) -} diff --git a/veilid-core/src/rpc_processor/coders/operations/answer.rs b/veilid-core/src/rpc_processor/coders/operations/answer.rs index f40962e6..da4d9178 100644 --- a/veilid-core/src/rpc_processor/coders/operations/answer.rs +++ b/veilid-core/src/rpc_processor/coders/operations/answer.rs @@ -100,70 +100,70 @@ impl RPCAnswerDetail { decode_context: &RPCDecodeContext, reader: &veilid_capnp::answer::detail::Reader, ) -> Result { - let which_reader = reader.which().map_err(RPCError::protocol)?; + let which_reader = reader.which()?; let out = match which_reader { veilid_capnp::answer::detail::StatusA(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationStatusA::decode(decode_context, &op_reader)?; RPCAnswerDetail::StatusA(Box::new(out)) } veilid_capnp::answer::detail::FindNodeA(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationFindNodeA::decode(decode_context, &op_reader)?; RPCAnswerDetail::FindNodeA(Box::new(out)) } veilid_capnp::answer::detail::AppCallA(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationAppCallA::decode(decode_context, &op_reader)?; RPCAnswerDetail::AppCallA(Box::new(out)) } veilid_capnp::answer::detail::GetValueA(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationGetValueA::decode(decode_context, &op_reader)?; RPCAnswerDetail::GetValueA(Box::new(out)) } veilid_capnp::answer::detail::SetValueA(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationSetValueA::decode(decode_context, &op_reader)?; RPCAnswerDetail::SetValueA(Box::new(out)) } veilid_capnp::answer::detail::WatchValueA(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationWatchValueA::decode(decode_context, &op_reader)?; RPCAnswerDetail::WatchValueA(Box::new(out)) } veilid_capnp::answer::detail::InspectValueA(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationInspectValueA::decode(decode_context, &op_reader)?; RPCAnswerDetail::InspectValueA(Box::new(out)) } #[cfg(feature = "unstable-blockstore")] veilid_capnp::answer::detail::SupplyBlockA(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationSupplyBlockA::decode(decode_context, &op_reader)?; RPCAnswerDetail::SupplyBlockA(Box::new(out)) } #[cfg(feature = "unstable-blockstore")] veilid_capnp::answer::detail::FindBlockA(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationFindBlockA::decode(decode_context, &op_reader)?; RPCAnswerDetail::FindBlockA(Box::new(out)) } #[cfg(feature = "unstable-tunnels")] veilid_capnp::answer::detail::StartTunnelA(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationStartTunnelA::decode(decode_context, &op_reader)?; RPCAnswerDetail::StartTunnelA(Box::new(out)) } #[cfg(feature = "unstable-tunnels")] veilid_capnp::answer::detail::CompleteTunnelA(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationCompleteTunnelA::decode(decode_context, &op_reader)?; RPCAnswerDetail::CompleteTunnelA(Box::new(out)) } #[cfg(feature = "unstable-tunnels")] veilid_capnp::answer::detail::CancelTunnelA(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationCancelTunnelA::decode(decode_context, &op_reader)?; RPCAnswerDetail::CancelTunnelA(Box::new(out)) } diff --git a/veilid-core/src/rpc_processor/coders/operations/operation.rs b/veilid-core/src/rpc_processor/coders/operations/operation.rs index 4ce3916d..0e14bb0a 100644 --- a/veilid-core/src/rpc_processor/coders/operations/operation.rs +++ b/veilid-core/src/rpc_processor/coders/operations/operation.rs @@ -28,20 +28,20 @@ impl RPCOperationKind { decode_context: &RPCDecodeContext, kind_reader: &veilid_capnp::operation::kind::Reader, ) -> Result { - let which_reader = kind_reader.which().map_err(RPCError::protocol)?; + let which_reader = kind_reader.which()?; let out = match which_reader { veilid_capnp::operation::kind::Which::Question(r) => { - let q_reader = r.map_err(RPCError::protocol)?; + let q_reader = r?; let out = RPCQuestion::decode(decode_context, &q_reader)?; RPCOperationKind::Question(Box::new(out)) } veilid_capnp::operation::kind::Which::Statement(r) => { - let q_reader = r.map_err(RPCError::protocol)?; + let q_reader = r?; let out = RPCStatement::decode(decode_context, &q_reader)?; RPCOperationKind::Statement(Box::new(out)) } veilid_capnp::operation::kind::Which::Answer(r) => { - let q_reader = r.map_err(RPCError::protocol)?; + let q_reader = r?; let out = RPCAnswer::decode(decode_context, &q_reader)?; RPCOperationKind::Answer(Box::new(out)) } @@ -133,9 +133,7 @@ impl RPCOperation { let op_id = OperationId::new(operation_reader.get_op_id()); let opt_peer_info = if operation_reader.has_sender_peer_info() { - let pi_reader = operation_reader - .get_sender_peer_info() - .map_err(RPCError::protocol)?; + let pi_reader = operation_reader.get_sender_peer_info()?; let pi = Arc::new(decode_peer_info(decode_context, &pi_reader)?); Some(pi) } else { diff --git a/veilid-core/src/rpc_processor/coders/operations/operation_app_call.rs b/veilid-core/src/rpc_processor/coders/operations/operation_app_call.rs index 9b5fb1f3..16363e7b 100644 --- a/veilid-core/src/rpc_processor/coders/operations/operation_app_call.rs +++ b/veilid-core/src/rpc_processor/coders/operations/operation_app_call.rs @@ -31,9 +31,12 @@ impl RPCOperationAppCallQ { _decode_context: &RPCDecodeContext, reader: &veilid_capnp::operation_app_call_q::Reader, ) -> Result { - let mr = reader.get_message().map_err(RPCError::protocol)?; + if !reader.has_message() { + return Err(RPCError::ignore("AppCallQ has no message")); + } + let mr = reader.get_message()?; if mr.len() > MAX_APP_CALL_Q_MESSAGE_LEN { - return Err(RPCError::protocol("AppCallQ message too long to set")); + return Err(RPCError::ignore("AppCallQ message too long to set")); } Ok(Self { message: mr.to_vec(), @@ -58,7 +61,7 @@ pub(in crate::rpc_processor) struct RPCOperationAppCallA { impl RPCOperationAppCallA { pub fn new(message: Vec) -> Result { if message.len() > MAX_APP_CALL_A_MESSAGE_LEN { - return Err(RPCError::protocol("AppCallA message too long to set")); + return Err(RPCError::ignore("AppCallA message too long to set")); } Ok(Self { message }) } @@ -79,10 +82,9 @@ impl RPCOperationAppCallA { _decode_context: &RPCDecodeContext, reader: &veilid_capnp::operation_app_call_a::Reader, ) -> Result { - let mr = reader.get_message().map_err(RPCError::protocol)?; - if mr.len() > MAX_APP_CALL_A_MESSAGE_LEN { - return Err(RPCError::protocol("AppCallA message too long to set")); - } + rpc_ignore_missing_property!(reader, message); + let mr = reader.get_message()?; + rpc_ignore_max_len!(mr, MAX_APP_CALL_A_MESSAGE_LEN); Ok(Self { message: mr.to_vec(), }) diff --git a/veilid-core/src/rpc_processor/coders/operations/operation_app_message.rs b/veilid-core/src/rpc_processor/coders/operations/operation_app_message.rs index 91155806..ef118088 100644 --- a/veilid-core/src/rpc_processor/coders/operations/operation_app_message.rs +++ b/veilid-core/src/rpc_processor/coders/operations/operation_app_message.rs @@ -10,7 +10,7 @@ pub(in crate::rpc_processor) struct RPCOperationAppMessage { impl RPCOperationAppMessage { pub fn new(message: Vec) -> Result { if message.len() > MAX_APP_MESSAGE_MESSAGE_LEN { - return Err(RPCError::protocol("AppMessage message too long to set")); + return Err(RPCError::ignore("AppMessage message too long to set")); } Ok(Self { message }) } @@ -30,10 +30,9 @@ impl RPCOperationAppMessage { _decode_context: &RPCDecodeContext, reader: &veilid_capnp::operation_app_message::Reader, ) -> Result { - let mr = reader.get_message().map_err(RPCError::protocol)?; - if mr.len() > MAX_APP_MESSAGE_MESSAGE_LEN { - return Err(RPCError::protocol("AppMessage message too long to set")); - } + rpc_ignore_missing_property!(reader, message); + let mr = reader.get_message()?; + rpc_ignore_max_len!(mr, MAX_APP_MESSAGE_MESSAGE_LEN); Ok(Self { message: mr.to_vec(), }) diff --git a/veilid-core/src/rpc_processor/coders/operations/operation_cancel_tunnel.rs b/veilid-core/src/rpc_processor/coders/operations/operation_cancel_tunnel.rs index 5b9af72f..399e71f1 100644 --- a/veilid-core/src/rpc_processor/coders/operations/operation_cancel_tunnel.rs +++ b/veilid-core/src/rpc_processor/coders/operations/operation_cancel_tunnel.rs @@ -61,12 +61,12 @@ impl RPCOperationCancelTunnelA { pub fn decode( reader: &veilid_capnp::operation_cancel_tunnel_a::Reader, ) -> Result { - match reader.which().map_err(RPCError::protocol)? { + match reader.which()? { veilid_capnp::operation_cancel_tunnel_a::Which::Tunnel(r) => { Ok(Self::Tunnel(TunnelId::new(r))) } veilid_capnp::operation_cancel_tunnel_a::Which::Error(r) => { - let tunnel_error = decode_tunnel_error(r.map_err(RPCError::protocol)?); + let tunnel_error = decode_tunnel_error(r?); Ok(Self::Error(tunnel_error)) } } diff --git a/veilid-core/src/rpc_processor/coders/operations/operation_complete_tunnel.rs b/veilid-core/src/rpc_processor/coders/operations/operation_complete_tunnel.rs index 7b6315a2..1becfab2 100644 --- a/veilid-core/src/rpc_processor/coders/operations/operation_complete_tunnel.rs +++ b/veilid-core/src/rpc_processor/coders/operations/operation_complete_tunnel.rs @@ -44,12 +44,15 @@ impl RPCOperationCompleteTunnelQ { reader: &veilid_capnp::operation_complete_tunnel_q::Reader, ) -> Result { let id = TunnelId::new(reader.get_id()); - let local_mode = match reader.get_local_mode().map_err(RPCError::protocol)? { + let local_mode = match reader.get_local_mode()? { 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(RPCError::protocol)?; + if !reader.has_endpoint() { + return Err(RPCError::ignore); + } + let te_reader = reader.get_endpoint()?; let endpoint = decode_tunnel_endpoint(&te_reader)?; Ok(Self { @@ -99,14 +102,14 @@ impl RPCOperationCompleteTunnelA { pub fn decode( reader: &veilid_capnp::operation_complete_tunnel_a::Reader, ) -> Result { - match reader.which().map_err(RPCError::protocol)? { + match reader.which()? { veilid_capnp::operation_complete_tunnel_a::Which::Tunnel(r) => { - let ft_reader = r.map_err(RPCError::protocol)?; + let ft_reader = r?; let full_tunnel = decode_full_tunnel(&ft_reader)?; Ok(Self::Tunnel(full_tunnel)) } veilid_capnp::operation_complete_tunnel_a::Which::Error(r) => { - let tunnel_error = decode_tunnel_error(r.map_err(RPCError::protocol)?); + let tunnel_error = decode_tunnel_error(r?); Ok(Self::Error(tunnel_error)) } } diff --git a/veilid-core/src/rpc_processor/coders/operations/operation_find_block.rs b/veilid-core/src/rpc_processor/coders/operations/operation_find_block.rs index 77eb3c1b..4127c572 100644 --- a/veilid-core/src/rpc_processor/coders/operations/operation_find_block.rs +++ b/veilid-core/src/rpc_processor/coders/operations/operation_find_block.rs @@ -29,7 +29,10 @@ impl RPCOperationFindBlockQ { decode_context: &RPCDecodeContext, reader: &veilid_capnp::operation_find_block_q::Reader, ) -> Result { - let bi_reader = reader.get_block_id().map_err(RPCError::protocol)?; + if !reader.has_block_id() { + return Err(RPCError::ignore); + } + let bi_reader = reader.get_block_id()?; let block_id = decode_typed_key(&bi_reader)?; Ok(Self { block_id }) @@ -61,13 +64,13 @@ impl RPCOperationFindBlockA { peers: Vec, ) -> Result { if data.len() > MAX_FIND_BLOCK_A_DATA_LEN { - return Err(RPCError::protocol("find block data length too long")); + return Err(RPCError::ignore("find block data length too long")); } if suppliers.len() > MAX_FIND_BLOCK_A_SUPPLIERS_LEN { - return Err(RPCError::protocol("find block suppliers length too long")); + return Err(RPCError::ignore("find block suppliers length too long")); } if peers.len() > MAX_FIND_BLOCK_A_PEERS_LEN { - return Err(RPCError::protocol("find block peers length too long")); + return Err(RPCError::ignore("find block peers length too long")); } Ok(Self { @@ -96,40 +99,31 @@ impl RPCOperationFindBlockA { (self.data, self.suppliers, self.peers) } pub fn decode(reader: &veilid_capnp::operation_find_block_a::Reader) -> Result { - let data = reader.get_data().map_err(RPCError::protocol)?; - if data.len() > MAX_FIND_BLOCK_A_DATA_LEN { - return Err(RPCError::protocol("find block data length too long")); - } + rpc_ignore_missing_property!(reader, data); + let data = reader.get_data()?; + rpc_ignore_max_len!(data, MAX_FIND_BLOCK_A_DATA_LEN); - let suppliers_reader = reader.get_suppliers().map_err(RPCError::protocol)?; - if suppliers_reader.len() as usize > MAX_FIND_BLOCK_A_SUPPLIERS_LEN { - return Err(RPCError::protocol("find block suppliers length too long")); - } + rpc_ignore_missing_property!(reader, suppliers); + let suppliers_reader = reader.get_suppliers()?; + let suppliers_len = rpc_ignore_max_len!(suppliers_reader, MAX_FIND_BLOCK_A_SUPPLIERS_LEN); - let peers_reader = reader.get_peers().map_err(RPCError::protocol)?; - if peers_reader.len() as usize > MAX_FIND_BLOCK_A_PEERS_LEN { - return Err(RPCError::protocol("find block peers length too long")); - } + rpc_ignore_missing_property!(reader, peers); + let peers_reader = reader.get_peers()?; + let peers_len = rpc_ignore_max_len!(peers_reader, MAX_FIND_BLOCK_A_PEERS_LEN); - let mut suppliers = Vec::::with_capacity( - suppliers_reader - .len() - .try_into() - .map_err(RPCError::map_internal("too many suppliers"))?, - ); + let mut suppliers = Vec::::with_capacity(suppliers_len); for s in suppliers_reader.iter() { - let peer_info = decode_peer_info(&s)?; + let Some(peer_info) = decode_peer_info(&s).ignore_ok()? else { + continue; + }; suppliers.push(peer_info); } - let mut peers = Vec::::with_capacity( - peers_reader - .len() - .try_into() - .map_err(RPCError::map_internal("too many peers"))?, - ); + let mut peers = Vec::::with_capacity(peers_len); for p in peers_reader.iter() { - let peer_info = decode_peer_info(&p)?; + let Some(peer_info) = decode_peer_info(&p).ignore_ok()? else { + continue; + }; peers.push(peer_info); } diff --git a/veilid-core/src/rpc_processor/coders/operations/operation_find_node.rs b/veilid-core/src/rpc_processor/coders/operations/operation_find_node.rs index 55b03d9b..5a7bc4b7 100644 --- a/veilid-core/src/rpc_processor/coders/operations/operation_find_node.rs +++ b/veilid-core/src/rpc_processor/coders/operations/operation_find_node.rs @@ -34,15 +34,13 @@ impl RPCOperationFindNodeQ { _decode_context: &RPCDecodeContext, reader: &veilid_capnp::operation_find_node_q::Reader, ) -> Result { - let ni_reader = reader.get_node_id().map_err(RPCError::protocol)?; + rpc_ignore_missing_property!(reader, node_id); + let ni_reader = reader.get_node_id()?; let node_id = decode_typed_node_id(&ni_reader)?; - let cap_reader = reader - .reborrow() - .get_capabilities() - .map_err(RPCError::protocol)?; - if cap_reader.len() as usize > MAX_CAPABILITIES { - return Err(RPCError::protocol("too many capabilities")); - } + + rpc_ignore_missing_property!(reader, capabilities); + let cap_reader = reader.get_capabilities()?; + rpc_ignore_max_len!(cap_reader, MAX_CAPABILITIES); let capabilities = cap_reader .as_slice() .map(|s| { @@ -116,7 +114,10 @@ impl RPCOperationFindNodeA { decode_context: &RPCDecodeContext, reader: &veilid_capnp::operation_find_node_a::Reader, ) -> Result { - let peers_reader = reader.get_peers().map_err(RPCError::protocol)?; + if !reader.has_peers() { + return Err(RPCError::ignore("missing peers")); + } + let peers_reader = reader.get_peers()?; if peers_reader.len() as usize > MAX_FIND_NODE_A_PEERS_LEN { return Err(RPCError::protocol( diff --git a/veilid-core/src/rpc_processor/coders/operations/operation_get_value.rs b/veilid-core/src/rpc_processor/coders/operations/operation_get_value.rs index e53764f9..d8ef152d 100644 --- a/veilid-core/src/rpc_processor/coders/operations/operation_get_value.rs +++ b/veilid-core/src/rpc_processor/coders/operations/operation_get_value.rs @@ -56,10 +56,11 @@ impl RPCOperationGetValueQ { _decode_context: &RPCDecodeContext, reader: &veilid_capnp::operation_get_value_q::Reader, ) -> Result { - let k_reader = reader.reborrow().get_key().map_err(RPCError::protocol)?; + rpc_ignore_missing_property!(reader, key); + let k_reader = reader.get_key()?; let key = decode_typed_record_key(&k_reader)?; - let subkey = reader.reborrow().get_subkey(); - let want_descriptor = reader.reborrow().get_want_descriptor(); + let subkey = reader.get_subkey(); + let want_descriptor = reader.get_want_descriptor(); Ok(Self { key, subkey, @@ -184,32 +185,26 @@ impl RPCOperationGetValueA { reader: &veilid_capnp::operation_get_value_a::Reader, ) -> Result { let value = if reader.has_value() { - let value_reader = reader.get_value().map_err(RPCError::protocol)?; + let value_reader = reader.get_value()?; let value = decode_signed_value_data(&value_reader)?; Some(value) } else { None }; - let peers_reader = reader.get_peers().map_err(RPCError::protocol)?; - if peers_reader.len() as usize > MAX_GET_VALUE_A_PEERS_LEN { - return Err(RPCError::protocol( - "decoded GetValueA peers length too long", - )); - } - let mut peers = Vec::>::with_capacity( - peers_reader - .len() - .try_into() - .map_err(RPCError::map_internal("too many peers"))?, - ); + rpc_ignore_missing_property!(reader, peers); + let peers_reader = reader.get_peers()?; + let peers_len = rpc_ignore_max_len!(peers_reader, MAX_GET_VALUE_A_PEERS_LEN); + let mut peers = Vec::>::with_capacity(peers_len); for p in peers_reader.iter() { - let peer_info = Arc::new(decode_peer_info(decode_context, &p)?); - peers.push(peer_info); + let Some(peer_info) = decode_peer_info(decode_context, &p).ignore_ok()? else { + continue; + }; + peers.push(Arc::new(peer_info)); } let descriptor = if reader.has_descriptor() { - let d_reader = reader.get_descriptor().map_err(RPCError::protocol)?; + let d_reader = reader.get_descriptor()?; let descriptor = decode_signed_value_descriptor(&d_reader)?; Some(descriptor) } else { diff --git a/veilid-core/src/rpc_processor/coders/operations/operation_inspect_value.rs b/veilid-core/src/rpc_processor/coders/operations/operation_inspect_value.rs index 64d7ffe7..baf801ce 100644 --- a/veilid-core/src/rpc_processor/coders/operations/operation_inspect_value.rs +++ b/veilid-core/src/rpc_processor/coders/operations/operation_inspect_value.rs @@ -52,13 +52,15 @@ impl RPCOperationInspectValueQ { _decode_context: &RPCDecodeContext, reader: &veilid_capnp::operation_inspect_value_q::Reader, ) -> Result { - let k_reader = reader.reborrow().get_key().map_err(RPCError::protocol)?; + rpc_ignore_missing_property!(reader, key); + let k_reader = reader.get_key()?; let key = decode_typed_record_key(&k_reader)?; - let sk_reader = reader.get_subkeys().map_err(RPCError::protocol)?; + + rpc_ignore_missing_property!(reader, subkeys); + let sk_reader = reader.get_subkeys()?; // Maximum number of ranges that can hold the maximum number of subkeys is one subkey per range - if sk_reader.len() as usize > MAX_INSPECT_VALUE_Q_SUBKEY_RANGES_LEN { - return Err(RPCError::protocol("InspectValueQ too many subkey ranges")); - } + rpc_ignore_max_len!(sk_reader, MAX_INSPECT_VALUE_Q_SUBKEY_RANGES_LEN); + let mut subkeys = ValueSubkeyRangeSet::new(); for skr in sk_reader.iter() { let vskr = (skr.get_start(), skr.get_end()); @@ -75,7 +77,7 @@ impl RPCOperationInspectValueQ { subkeys.ranges_insert(vskr.0..=vskr.1); } - let want_descriptor = reader.reborrow().get_want_descriptor(); + let want_descriptor = reader.get_want_descriptor(); Ok(Self { key, subkeys, @@ -211,40 +213,29 @@ impl RPCOperationInspectValueA { decode_context: &RPCDecodeContext, reader: &veilid_capnp::operation_inspect_value_a::Reader, ) -> Result { - let seqs = if reader.has_seqs() { - let seqs_reader = reader.get_seqs().map_err(RPCError::protocol)?; - if seqs_reader.len() as usize > MAX_INSPECT_VALUE_A_SEQS_LEN { - return Err(RPCError::protocol( - "decoded InspectValueA seqs length too long", - )); - } + rpc_ignore_missing_property!(reader, seqs); + let seqs = { + let seqs_reader = reader.get_seqs()?; + rpc_ignore_max_len!(seqs_reader, MAX_INSPECT_VALUE_A_SEQS_LEN); let Some(seqs) = seqs_reader.as_slice().map(|s| s.to_vec()) else { return Err(RPCError::protocol("invalid decoded InspectValueA seqs")); }; seqs - } else { - return Err(RPCError::protocol("missing decoded InspectValueA seqs")); }; - let peers_reader = reader.get_peers().map_err(RPCError::protocol)?; - if peers_reader.len() as usize > MAX_INSPECT_VALUE_A_PEERS_LEN { - return Err(RPCError::protocol( - "decoded InspectValueA peers length too long", - )); - } - let mut peers = Vec::>::with_capacity( - peers_reader - .len() - .try_into() - .map_err(RPCError::map_internal("too many peers"))?, - ); + rpc_ignore_missing_property!(reader, peers); + let peers_reader = reader.get_peers()?; + let peers_len = rpc_ignore_max_len!(peers_reader, MAX_INSPECT_VALUE_A_PEERS_LEN); + let mut peers = Vec::>::with_capacity(peers_len); for p in peers_reader.iter() { - let peer_info = Arc::new(decode_peer_info(decode_context, &p)?); - peers.push(peer_info); + let Some(peer_info) = decode_peer_info(decode_context, &p).ignore_ok()? else { + continue; + }; + peers.push(Arc::new(peer_info)); } let descriptor = if reader.has_descriptor() { - let d_reader = reader.get_descriptor().map_err(RPCError::protocol)?; + let d_reader = reader.get_descriptor()?; let descriptor = decode_signed_value_descriptor(&d_reader)?; Some(descriptor) } else { diff --git a/veilid-core/src/rpc_processor/coders/operations/operation_return_receipt.rs b/veilid-core/src/rpc_processor/coders/operations/operation_return_receipt.rs index 38bda921..3c268546 100644 --- a/veilid-core/src/rpc_processor/coders/operations/operation_return_receipt.rs +++ b/veilid-core/src/rpc_processor/coders/operations/operation_return_receipt.rs @@ -32,13 +32,9 @@ impl RPCOperationReturnReceipt { _decode_context: &RPCDecodeContext, reader: &veilid_capnp::operation_return_receipt::Reader, ) -> Result { - let rr = reader.get_receipt().map_err(RPCError::protocol)?; - if rr.len() < MIN_RECEIPT_SIZE { - return Err(RPCError::protocol("ReturnReceipt receipt too short to set")); - } - if rr.len() > MAX_RECEIPT_SIZE { - return Err(RPCError::protocol("ReturnReceipt receipt too long to set")); - } + rpc_ignore_missing_property!(reader, receipt); + let rr = reader.get_receipt()?; + rpc_ignore_min_max_len!(rr, MIN_RECEIPT_SIZE, MAX_RECEIPT_SIZE); Ok(Self { receipt: rr.to_vec(), diff --git a/veilid-core/src/rpc_processor/coders/operations/operation_route.rs b/veilid-core/src/rpc_processor/coders/operations/operation_route.rs index 8f7c18fe..9b462d9c 100644 --- a/veilid-core/src/rpc_processor/coders/operations/operation_route.rs +++ b/veilid-core/src/rpc_processor/coders/operations/operation_route.rs @@ -69,7 +69,8 @@ impl RoutedOperation { decode_context: &RPCDecodeContext, reader: &veilid_capnp::routed_operation::Reader, ) -> Result { - let sigs_reader = reader.get_signatures().map_err(RPCError::protocol)?; + rpc_ignore_missing_property!(reader, signatures); + let sigs_reader = reader.get_signatures()?; let mut signatures = Vec::::with_capacity( sigs_reader .len() @@ -77,14 +78,17 @@ impl RoutedOperation { .map_err(RPCError::map_internal("too many signatures"))?, ); for s in sigs_reader.iter() { + // TODO: wants .ignore_ok() eventually let sig = decode_signature512(&s); signatures.push(sig); } - let sequencing = decode_sequencing(reader.get_sequencing().map_err(RPCError::protocol)?); - let n_reader = reader.get_nonce().map_err(RPCError::protocol)?; + let sequencing = decode_sequencing(reader.get_sequencing()?); + rpc_ignore_missing_property!(reader, nonce); + let n_reader = reader.get_nonce()?; let nonce = decode_nonce(&n_reader); - let data = reader.get_data().map_err(RPCError::protocol)?; + rpc_ignore_missing_property!(reader, data); + let data = reader.get_data()?; Ok(Self { routing_domain: decode_context.routing_domain, @@ -151,10 +155,12 @@ impl RPCOperationRoute { decode_context: &RPCDecodeContext, reader: &veilid_capnp::operation_route::Reader, ) -> Result { - let sr_reader = reader.get_safety_route().map_err(RPCError::protocol)?; + rpc_ignore_missing_property!(reader, safety_route); + let sr_reader = reader.get_safety_route()?; let safety_route = decode_safety_route(decode_context, &sr_reader)?; - let o_reader = reader.get_operation().map_err(RPCError::protocol)?; + rpc_ignore_missing_property!(reader, operation); + let o_reader = reader.get_operation()?; let operation = RoutedOperation::decode(decode_context, &o_reader)?; Ok(Self { diff --git a/veilid-core/src/rpc_processor/coders/operations/operation_set_value.rs b/veilid-core/src/rpc_processor/coders/operations/operation_set_value.rs index 6e69787e..758a4d5f 100644 --- a/veilid-core/src/rpc_processor/coders/operations/operation_set_value.rs +++ b/veilid-core/src/rpc_processor/coders/operations/operation_set_value.rs @@ -76,13 +76,18 @@ impl RPCOperationSetValueQ { _decode_context: &RPCDecodeContext, reader: &veilid_capnp::operation_set_value_q::Reader, ) -> Result { - let k_reader = reader.get_key().map_err(RPCError::protocol)?; + rpc_ignore_missing_property!(reader, key); + let k_reader = reader.get_key()?; let key = decode_typed_record_key(&k_reader)?; + let subkey = reader.get_subkey(); - let v_reader = reader.get_value().map_err(RPCError::protocol)?; + + rpc_ignore_missing_property!(reader, value); + let v_reader = reader.get_value()?; let value = decode_signed_value_data(&v_reader)?; + let descriptor = if reader.has_descriptor() { - let d_reader = reader.get_descriptor().map_err(RPCError::protocol)?; + let d_reader = reader.get_descriptor()?; let descriptor = decode_signed_value_descriptor(&d_reader)?; Some(descriptor) } else { @@ -192,27 +197,20 @@ impl RPCOperationSetValueA { ) -> Result { let set = reader.get_set(); let value = if reader.has_value() { - let v_reader = reader.get_value().map_err(RPCError::protocol)?; + let v_reader = reader.get_value()?; let value = decode_signed_value_data(&v_reader)?; Some(value) } else { None }; - let peers_reader = reader.get_peers().map_err(RPCError::protocol)?; - if peers_reader.len() as usize > MAX_SET_VALUE_A_PEERS_LEN { - return Err(RPCError::protocol( - "decoded SetValueA peers length too long", - )); - } - let mut peers = Vec::>::with_capacity( - peers_reader - .len() - .try_into() - .map_err(RPCError::map_internal("too many peers"))?, - ); + let peers_reader = reader.get_peers()?; + let peers_len = rpc_ignore_max_len!(peers_reader, MAX_SET_VALUE_A_PEERS_LEN); + let mut peers = Vec::>::with_capacity(peers_len); for p in peers_reader.iter() { - let peer_info = Arc::new(decode_peer_info(decode_context, &p)?); - peers.push(peer_info); + let Some(peer_info) = decode_peer_info(decode_context, &p).ignore_ok()? else { + continue; + }; + peers.push(Arc::new(peer_info)); } Ok(Self { set, value, peers }) diff --git a/veilid-core/src/rpc_processor/coders/operations/operation_start_tunnel.rs b/veilid-core/src/rpc_processor/coders/operations/operation_start_tunnel.rs index f79dce52..0e062428 100644 --- a/veilid-core/src/rpc_processor/coders/operations/operation_start_tunnel.rs +++ b/veilid-core/src/rpc_processor/coders/operations/operation_start_tunnel.rs @@ -39,7 +39,7 @@ impl RPCOperationStartTunnelQ { reader: &veilid_capnp::operation_start_tunnel_q::Reader, ) -> Result { let id = TunnelId::new(reader.get_id()); - let local_mode = match reader.get_local_mode().map_err(RPCError::protocol)? { + let local_mode = match reader.get_local_mode()? { veilid_capnp::TunnelEndpointMode::Raw => TunnelMode::Raw, veilid_capnp::TunnelEndpointMode::Turn => TunnelMode::Turn, }; diff --git a/veilid-core/src/rpc_processor/coders/operations/operation_status.rs b/veilid-core/src/rpc_processor/coders/operations/operation_status.rs index 5cf6638d..633d6a75 100644 --- a/veilid-core/src/rpc_processor/coders/operations/operation_status.rs +++ b/veilid-core/src/rpc_processor/coders/operations/operation_status.rs @@ -25,7 +25,7 @@ impl RPCOperationStatusQ { reader: &veilid_capnp::operation_status_q::Reader, ) -> Result { let node_status = if reader.has_node_status() { - let ns_reader = reader.get_node_status().map_err(RPCError::protocol)?; + let ns_reader = reader.get_node_status()?; let node_status = decode_node_status(&ns_reader)?; Some(node_status) } else { @@ -80,7 +80,7 @@ impl RPCOperationStatusA { reader: &veilid_capnp::operation_status_a::Reader, ) -> Result { let node_status = if reader.has_node_status() { - let ns_reader = reader.get_node_status().map_err(RPCError::protocol)?; + let ns_reader = reader.get_node_status()?; let node_status = decode_node_status(&ns_reader)?; Some(node_status) } else { @@ -88,7 +88,7 @@ impl RPCOperationStatusA { }; let sender_info = if reader.has_sender_info() { - let si_reader = reader.get_sender_info().map_err(RPCError::protocol)?; + let si_reader = reader.get_sender_info()?; let sender_info = decode_sender_info(&si_reader)?; Some(sender_info) } else { diff --git a/veilid-core/src/rpc_processor/coders/operations/operation_supply_block.rs b/veilid-core/src/rpc_processor/coders/operations/operation_supply_block.rs index 0bd001ee..283d59fe 100644 --- a/veilid-core/src/rpc_processor/coders/operations/operation_supply_block.rs +++ b/veilid-core/src/rpc_processor/coders/operations/operation_supply_block.rs @@ -27,7 +27,8 @@ impl RPCOperationSupplyBlockQ { decode_context: &RPCDecodeContext, reader: &veilid_capnp::operation_supply_block_q::Reader, ) -> Result { - let bi_reader = reader.get_block_id().map_err(RPCError::protocol)?; + rpc_ignore_missing_property!(reader, block_id); + let bi_reader = reader.get_block_id()?; let block_id = decode_typed_key(&bi_reader)?; Ok(Self { block_id }) @@ -78,18 +79,12 @@ impl RPCOperationSupplyBlockA { ) -> Result { let expiration = reader.get_expiration(); - let peers_reader = reader.get_peers().map_err(RPCError::protocol)?; - if peers_reader.len() as usize > MAX_SUPPLY_BLOCK_A_PEERS_LEN { - return Err(RPCError::protocol("SupplyBlockA peers length too long")); - } - let mut peers = Vec::::with_capacity( - peers_reader - .len() - .try_into() - .map_err(RPCError::map_internal("too many peers"))?, - ); + rpc_ignore_missing_property!(reader, peers); + let peers_reader = reader.get_peers()?; + let peers_len = rpc_ignore_max_len!(peers_reader, MAX_SUPPLY_BLOCK_A_PEERS_LEN); + let mut peers = Vec::::with_capacity(peers_len); for p in peers_reader.iter() { - let peer_info = decode_peer_info(decode_context, &p)?; + let Some(peer_info) = decode_peer_info(decode_context, &p).ignore_ok()?; peers.push(peer_info); } diff --git a/veilid-core/src/rpc_processor/coders/operations/operation_validate_dial_info.rs b/veilid-core/src/rpc_processor/coders/operations/operation_validate_dial_info.rs index 47d05b16..1b734ed2 100644 --- a/veilid-core/src/rpc_processor/coders/operations/operation_validate_dial_info.rs +++ b/veilid-core/src/rpc_processor/coders/operations/operation_validate_dial_info.rs @@ -47,19 +47,13 @@ impl RPCOperationValidateDialInfo { _decode_context: &RPCDecodeContext, reader: &veilid_capnp::operation_validate_dial_info::Reader, ) -> Result { - let di_reader = reader.get_dial_info().map_err(RPCError::protocol)?; + rpc_ignore_missing_property!(reader, dial_info); + let di_reader = reader.get_dial_info()?; let dial_info = decode_dial_info(&di_reader)?; - let rcpt_reader = reader.get_receipt().map_err(RPCError::protocol)?; - if rcpt_reader.len() < MIN_RECEIPT_SIZE { - return Err(RPCError::protocol( - "ValidateDialInfo receipt too short to set", - )); - } - if rcpt_reader.len() > MAX_RECEIPT_SIZE { - return Err(RPCError::protocol( - "ValidateDialInfo receipt too long to set", - )); - } + + rpc_ignore_missing_property!(reader, receipt); + let rcpt_reader = reader.get_receipt()?; + rpc_ignore_min_max_len!(rcpt_reader, MIN_RECEIPT_SIZE, MAX_RECEIPT_SIZE); let receipt = rcpt_reader.to_vec(); let redirect = reader.get_redirect(); diff --git a/veilid-core/src/rpc_processor/coders/operations/operation_value_changed.rs b/veilid-core/src/rpc_processor/coders/operations/operation_value_changed.rs index 1893afb7..c4388887 100644 --- a/veilid-core/src/rpc_processor/coders/operations/operation_value_changed.rs +++ b/veilid-core/src/rpc_processor/coders/operations/operation_value_changed.rs @@ -104,15 +104,13 @@ impl RPCOperationValueChanged { _decode_context: &RPCDecodeContext, reader: &veilid_capnp::operation_value_changed::Reader, ) -> Result { - let k_reader = reader.get_key().map_err(RPCError::protocol)?; + rpc_ignore_missing_property!(reader, key); + let k_reader = reader.get_key()?; let key = decode_typed_record_key(&k_reader)?; - let sk_reader = reader.get_subkeys().map_err(RPCError::protocol)?; - if sk_reader.len() as usize > MAX_VALUE_CHANGED_SUBKEY_RANGES_LEN { - return Err(RPCError::protocol( - "ValueChanged subkey ranges length too long", - )); - } + rpc_ignore_missing_property!(reader, subkeys); + let sk_reader = reader.get_subkeys()?; + rpc_ignore_max_len!(sk_reader, MAX_VALUE_CHANGED_SUBKEY_RANGES_LEN); let mut subkeys = ValueSubkeyRangeSet::new(); for skr in sk_reader.iter() { @@ -132,7 +130,7 @@ impl RPCOperationValueChanged { let count = reader.get_count(); let watch_id = reader.get_watch_id(); let value = if reader.has_value() { - let v_reader = reader.get_value().map_err(RPCError::protocol)?; + let v_reader = reader.get_value()?; Some(decode_signed_value_data(&v_reader)?) } else { None diff --git a/veilid-core/src/rpc_processor/coders/operations/operation_watch_value.rs b/veilid-core/src/rpc_processor/coders/operations/operation_watch_value.rs index 3d5a556d..d01f5344 100644 --- a/veilid-core/src/rpc_processor/coders/operations/operation_watch_value.rs +++ b/veilid-core/src/rpc_processor/coders/operations/operation_watch_value.rs @@ -162,13 +162,13 @@ impl RPCOperationWatchValueQ { _decode_context: &RPCDecodeContext, reader: &veilid_capnp::operation_watch_value_q::Reader, ) -> Result { - let k_reader = reader.get_key().map_err(RPCError::protocol)?; + rpc_ignore_missing_property!(reader, key); + let k_reader = reader.get_key()?; let key = decode_typed_record_key(&k_reader)?; - let sk_reader = reader.get_subkeys().map_err(RPCError::protocol)?; - if sk_reader.len() as usize > MAX_WATCH_VALUE_Q_SUBKEY_RANGES_LEN { - return Err(RPCError::protocol("WatchValueQ too many subkey ranges")); - } + rpc_ignore_missing_property!(reader, subkeys); + let sk_reader = reader.get_subkeys()?; + rpc_ignore_max_len!(sk_reader, MAX_WATCH_VALUE_Q_SUBKEY_RANGES_LEN); let mut subkeys = ValueSubkeyRangeSet::new(); for skr in sk_reader.iter() { let vskr = (skr.get_start(), skr.get_end()); @@ -193,10 +193,12 @@ impl RPCOperationWatchValueQ { None }; - let w_reader = reader.get_watcher().map_err(RPCError::protocol)?; + rpc_ignore_missing_property!(reader, watcher); + let w_reader = reader.get_watcher()?; let watcher = decode_key256(&w_reader); - let s_reader = reader.get_signature().map_err(RPCError::protocol)?; + rpc_ignore_missing_property!(reader, signature); + let s_reader = reader.get_signature()?; let signature = decode_signature512(&s_reader); Ok(Self { @@ -302,19 +304,16 @@ impl RPCOperationWatchValueA { ) -> Result { let accepted = reader.get_accepted(); let expiration = reader.get_expiration(); - let peers_reader = reader.get_peers().map_err(RPCError::protocol)?; - if peers_reader.len() as usize > MAX_WATCH_VALUE_A_PEERS_LEN { - return Err(RPCError::protocol("WatchValueA peers length too long")); - } - let mut peers = Vec::>::with_capacity( - peers_reader - .len() - .try_into() - .map_err(RPCError::map_internal("too many peers"))?, - ); + + rpc_ignore_missing_property!(reader, peers); + let peers_reader = reader.get_peers()?; + let peers_len = rpc_ignore_max_len!(peers_reader, MAX_WATCH_VALUE_A_PEERS_LEN); + let mut peers = Vec::>::with_capacity(peers_len); for p in peers_reader.iter() { - let peer_info = Arc::new(decode_peer_info(decode_context, &p)?); - peers.push(peer_info); + let Some(peer_info) = decode_peer_info(decode_context, &p).ignore_ok()? else { + continue; + }; + peers.push(Arc::new(peer_info)); } let watch_id = reader.get_watch_id(); diff --git a/veilid-core/src/rpc_processor/coders/operations/question.rs b/veilid-core/src/rpc_processor/coders/operations/question.rs index 4434ba8d..94008afd 100644 --- a/veilid-core/src/rpc_processor/coders/operations/question.rs +++ b/veilid-core/src/rpc_processor/coders/operations/question.rs @@ -114,70 +114,70 @@ impl RPCQuestionDetail { decode_context: &RPCDecodeContext, reader: &veilid_capnp::question::detail::Reader, ) -> Result { - let which_reader = reader.which().map_err(RPCError::protocol)?; + let which_reader = reader.which()?; let out = match which_reader { veilid_capnp::question::detail::StatusQ(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationStatusQ::decode(decode_context, &op_reader)?; RPCQuestionDetail::StatusQ(Box::new(out)) } veilid_capnp::question::detail::FindNodeQ(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationFindNodeQ::decode(decode_context, &op_reader)?; RPCQuestionDetail::FindNodeQ(Box::new(out)) } veilid_capnp::question::detail::Which::AppCallQ(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationAppCallQ::decode(decode_context, &op_reader)?; RPCQuestionDetail::AppCallQ(Box::new(out)) } veilid_capnp::question::detail::GetValueQ(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationGetValueQ::decode(decode_context, &op_reader)?; RPCQuestionDetail::GetValueQ(Box::new(out)) } veilid_capnp::question::detail::SetValueQ(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationSetValueQ::decode(decode_context, &op_reader)?; RPCQuestionDetail::SetValueQ(Box::new(out)) } veilid_capnp::question::detail::WatchValueQ(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationWatchValueQ::decode(decode_context, &op_reader)?; RPCQuestionDetail::WatchValueQ(Box::new(out)) } veilid_capnp::question::detail::InspectValueQ(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationInspectValueQ::decode(decode_context, &op_reader)?; RPCQuestionDetail::InspectValueQ(Box::new(out)) } #[cfg(feature = "unstable-blockstore")] veilid_capnp::question::detail::SupplyBlockQ(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationSupplyBlockQ::decode(decode_context, &op_reader)?; RPCQuestionDetail::SupplyBlockQ(Box::new(out)) } #[cfg(feature = "unstable-blockstore")] veilid_capnp::question::detail::FindBlockQ(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationFindBlockQ::decode(decode_context, &op_reader)?; RPCQuestionDetail::FindBlockQ(Box::new(out)) } #[cfg(feature = "unstable-tunnels")] veilid_capnp::question::detail::StartTunnelQ(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationStartTunnelQ::decode(decode_context, &op_reader)?; RPCQuestionDetail::StartTunnelQ(Box::new(out)) } #[cfg(feature = "unstable-tunnels")] veilid_capnp::question::detail::CompleteTunnelQ(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationCompleteTunnelQ::decode(decode_context, &op_reader)?; RPCQuestionDetail::CompleteTunnelQ(Box::new(out)) } #[cfg(feature = "unstable-tunnels")] veilid_capnp::question::detail::CancelTunnelQ(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationCancelTunnelQ::decode(decode_context, &op_reader)?; RPCQuestionDetail::CancelTunnelQ(Box::new(out)) } diff --git a/veilid-core/src/rpc_processor/coders/operations/respond_to.rs b/veilid-core/src/rpc_processor/coders/operations/respond_to.rs index 2cf3e053..29e7e6d8 100644 --- a/veilid-core/src/rpc_processor/coders/operations/respond_to.rs +++ b/veilid-core/src/rpc_processor/coders/operations/respond_to.rs @@ -14,6 +14,21 @@ impl RespondTo { } } + pub fn decode( + decode_context: &RPCDecodeContext, + reader: &veilid_capnp::question::respond_to::Reader, + ) -> Result { + let respond_to = match reader.which()? { + veilid_capnp::question::respond_to::Sender(()) => RespondTo::Sender, + veilid_capnp::question::respond_to::PrivateRoute(pr_reader) => { + let pr_reader = pr_reader?; + let pr = decode_private_route(decode_context, &pr_reader)?; + RespondTo::PrivateRoute(pr) + } + }; + Ok(respond_to) + } + pub fn encode( &self, builder: &mut veilid_capnp::question::respond_to::Builder, @@ -29,19 +44,4 @@ impl RespondTo { }; Ok(()) } - - pub fn decode( - decode_context: &RPCDecodeContext, - reader: &veilid_capnp::question::respond_to::Reader, - ) -> Result { - let respond_to = match reader.which().map_err(RPCError::protocol)? { - veilid_capnp::question::respond_to::Sender(()) => RespondTo::Sender, - veilid_capnp::question::respond_to::PrivateRoute(pr_reader) => { - let pr_reader = pr_reader.map_err(RPCError::protocol)?; - let pr = decode_private_route(decode_context, &pr_reader)?; - RespondTo::PrivateRoute(pr) - } - }; - Ok(respond_to) - } } diff --git a/veilid-core/src/rpc_processor/coders/operations/statement.rs b/veilid-core/src/rpc_processor/coders/operations/statement.rs index 904c2c86..7c84bcf4 100644 --- a/veilid-core/src/rpc_processor/coders/operations/statement.rs +++ b/veilid-core/src/rpc_processor/coders/operations/statement.rs @@ -70,35 +70,35 @@ impl RPCStatementDetail { decode_context: &RPCDecodeContext, reader: &veilid_capnp::statement::detail::Reader, ) -> Result { - let which_reader = reader.which().map_err(RPCError::protocol)?; + let which_reader = reader.which()?; let out = match which_reader { veilid_capnp::statement::detail::ValidateDialInfo(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationValidateDialInfo::decode(decode_context, &op_reader)?; RPCStatementDetail::ValidateDialInfo(Box::new(out)) } veilid_capnp::statement::detail::Route(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationRoute::decode(decode_context, &op_reader)?; RPCStatementDetail::Route(Box::new(out)) } veilid_capnp::statement::detail::ValueChanged(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationValueChanged::decode(decode_context, &op_reader)?; RPCStatementDetail::ValueChanged(Box::new(out)) } veilid_capnp::statement::detail::Signal(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationSignal::decode(decode_context, &op_reader)?; RPCStatementDetail::Signal(Box::new(out)) } veilid_capnp::statement::detail::ReturnReceipt(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationReturnReceipt::decode(decode_context, &op_reader)?; RPCStatementDetail::ReturnReceipt(Box::new(out)) } veilid_capnp::statement::detail::AppMessage(r) => { - let op_reader = r.map_err(RPCError::protocol)?; + let op_reader = r?; let out = RPCOperationAppMessage::decode(decode_context, &op_reader)?; RPCStatementDetail::AppMessage(Box::new(out)) } diff --git a/veilid-core/src/rpc_processor/coders/peer_info.rs b/veilid-core/src/rpc_processor/coders/peer_info.rs index c258fad9..8408047d 100644 --- a/veilid-core/src/rpc_processor/coders/peer_info.rs +++ b/veilid-core/src/rpc_processor/coders/peer_info.rs @@ -1,5 +1,30 @@ use super::*; +pub fn decode_peer_info( + decode_context: &RPCDecodeContext, + reader: &veilid_capnp::peer_info::Reader, +) -> Result { + rpc_ignore_missing_property!(reader, node_ids); + let nids_reader = reader.get_node_ids()?; + + rpc_ignore_missing_property!(reader, signed_node_info); + let sni_reader = reader.get_signed_node_info()?; + + let mut node_ids = NodeIdGroup::with_capacity(nids_reader.len() as usize); + for nid_reader in nids_reader.iter() { + let Some(nid) = decode_typed_node_id(&nid_reader).ignore_ok()? else { + continue; + }; + node_ids.add(nid); + } + if node_ids.is_empty() { + return Err(RPCError::ignore("no verified node ids")); + } + let signed_node_info = decode_signed_node_info(&sni_reader)?; + PeerInfo::new(decode_context.routing_domain, node_ids, signed_node_info) + .map_err(RPCError::map_invalid_format("invalid peer info")) +} + pub fn encode_peer_info( peer_info: &PeerInfo, builder: &mut veilid_capnp::peer_info::Builder, @@ -26,27 +51,3 @@ pub fn encode_peer_info( Ok(()) } - -pub fn decode_peer_info( - decode_context: &RPCDecodeContext, - reader: &veilid_capnp::peer_info::Reader, -) -> Result { - let nids_reader = reader - .reborrow() - .get_node_ids() - .map_err(RPCError::protocol)?; - let sni_reader = reader - .reborrow() - .get_signed_node_info() - .map_err(RPCError::protocol)?; - let mut node_ids = NodeIdGroup::with_capacity(nids_reader.len() as usize); - for nid_reader in nids_reader.iter() { - node_ids.add(decode_typed_node_id(&nid_reader)?); - } - let signed_node_info = decode_signed_node_info(&sni_reader)?; - if node_ids.is_empty() { - return Err(RPCError::protocol("no verified node ids")); - } - PeerInfo::new(decode_context.routing_domain, node_ids, signed_node_info) - .map_err(RPCError::map_invalid_format("invalid peer info")) -} diff --git a/veilid-core/src/rpc_processor/coders/private_safety_route.rs b/veilid-core/src/rpc_processor/coders/private_safety_route.rs index e1a1c10e..72e21a12 100644 --- a/veilid-core/src/rpc_processor/coders/private_safety_route.rs +++ b/veilid-core/src/rpc_processor/coders/private_safety_route.rs @@ -2,6 +2,18 @@ use super::*; //////////////////////////////////////////////////////////////////////////////////////////////////// +pub fn decode_route_hop_data( + reader: &veilid_capnp::route_hop_data::Reader, +) -> Result { + rpc_ignore_missing_property!(reader, nonce); + let nonce = decode_nonce(&reader.get_nonce()?); + + rpc_ignore_missing_property!(reader, blob); + let blob = reader.get_blob()?.to_vec(); + + Ok(RouteHopData { nonce, blob }) +} + pub fn encode_route_hop_data( route_hop_data: &RouteHopData, builder: &mut veilid_capnp::route_hop_data::Builder, @@ -24,27 +36,35 @@ pub fn encode_route_hop_data( Ok(()) } -pub fn decode_route_hop_data( - reader: &veilid_capnp::route_hop_data::Reader, -) -> Result { - let nonce = decode_nonce( - &reader - .reborrow() - .get_nonce() - .map_err(RPCError::map_protocol("invalid nonce in route hop data"))?, - ); - - let blob = reader - .reborrow() - .get_blob() - .map_err(RPCError::map_protocol("invalid blob in route hop data"))? - .to_vec(); - - Ok(RouteHopData { nonce, blob }) -} - //////////////////////////////////////////////////////////////////////////////////////////////////// +pub fn decode_route_hop( + decode_context: &RPCDecodeContext, + reader: &veilid_capnp::route_hop::Reader, +) -> Result { + let node = match reader.get_node().which()? { + veilid_capnp::route_hop::node::Which::NodeId(ni) => { + let ni_reader = ni?; + RouteNode::BareNodeId(decode_key256(&ni_reader).into()) + } + veilid_capnp::route_hop::node::Which::PeerInfo(pi) => { + let pi_reader = pi?; + RouteNode::PeerInfo(Arc::new(decode_peer_info(decode_context, &pi_reader)?)) + } + }; + + let next_hop = if reader.has_next_hop() { + let rhd_reader = reader + .get_next_hop() + .map_err(RPCError::map_protocol("invalid next hop in route hop"))?; + Some(decode_route_hop_data(&rhd_reader)?) + } else { + None + }; + + Ok(RouteHop { node, next_hop }) +} + pub fn encode_route_hop( route_hop: &RouteHop, builder: &mut veilid_capnp::route_hop::Builder, @@ -67,39 +87,35 @@ pub fn encode_route_hop( Ok(()) } -pub fn decode_route_hop( - decode_context: &RPCDecodeContext, - reader: &veilid_capnp::route_hop::Reader, -) -> Result { - let n_reader = reader.reborrow().get_node(); - let node = match n_reader.which().map_err(RPCError::protocol)? { - veilid_capnp::route_hop::node::Which::NodeId(ni) => { - let ni_reader = ni.map_err(RPCError::protocol)?; - RouteNode::BareNodeId(decode_key256(&ni_reader).into()) - } - veilid_capnp::route_hop::node::Which::PeerInfo(pi) => { - let pi_reader = pi.map_err(RPCError::protocol)?; - RouteNode::PeerInfo(Arc::new( - decode_peer_info(decode_context, &pi_reader) - .map_err(RPCError::map_protocol("invalid peer info in route hop"))?, - )) - } - }; - - let next_hop = if reader.has_next_hop() { - let rhd_reader = reader - .get_next_hop() - .map_err(RPCError::map_protocol("invalid next hop in route hop"))?; - Some(decode_route_hop_data(&rhd_reader)?) - } else { - None - }; - - Ok(RouteHop { node, next_hop }) -} - //////////////////////////////////////////////////////////////////////////////////////////////////// +pub fn decode_private_route( + decode_context: &RPCDecodeContext, + reader: &veilid_capnp::private_route::Reader, +) -> Result { + rpc_ignore_missing_property!(reader, public_key); + let public_key = decode_typed_public_key(&reader.get_public_key()?)?; + let hop_count = reader.get_hop_count(); + + let hops = match reader.get_hops().which()? { + veilid_capnp::private_route::hops::Which::FirstHop(rh_reader) => { + let rh_reader = rh_reader?; + PrivateRouteHops::FirstHop(Box::new(decode_route_hop(decode_context, &rh_reader)?)) + } + veilid_capnp::private_route::hops::Which::Data(rhd_reader) => { + let rhd_reader = rhd_reader?; + PrivateRouteHops::Data(decode_route_hop_data(&rhd_reader)?) + } + veilid_capnp::private_route::hops::Which::Empty(_) => PrivateRouteHops::Empty, + }; + + Ok(PrivateRoute { + public_key, + hop_count, + hops, + }) +} + pub fn encode_private_route( private_route: &PrivateRoute, builder: &mut veilid_capnp::private_route::Builder, @@ -126,36 +142,33 @@ pub fn encode_private_route( Ok(()) } -pub fn decode_private_route( - decode_context: &RPCDecodeContext, - reader: &veilid_capnp::private_route::Reader, -) -> Result { - let public_key = decode_typed_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 = match reader.get_hops().which().map_err(RPCError::protocol)? { - veilid_capnp::private_route::hops::Which::FirstHop(rh_reader) => { - let rh_reader = rh_reader.map_err(RPCError::protocol)?; - PrivateRouteHops::FirstHop(Box::new(decode_route_hop(decode_context, &rh_reader)?)) +pub fn decode_safety_route( + decode_context: &RPCDecodeContext, + reader: &veilid_capnp::safety_route::Reader, +) -> Result { + rpc_ignore_missing_property!(reader, public_key); + let public_key = decode_typed_public_key(&reader.get_public_key()?)?; + let hop_count = reader.get_hop_count(); + let hops = match reader.get_hops().which()? { + veilid_capnp::safety_route::hops::Which::Data(rhd_reader) => { + let rhd_reader = rhd_reader?; + SafetyRouteHops::Data(decode_route_hop_data(&rhd_reader)?) } - veilid_capnp::private_route::hops::Which::Data(rhd_reader) => { - let rhd_reader = rhd_reader.map_err(RPCError::protocol)?; - PrivateRouteHops::Data(decode_route_hop_data(&rhd_reader)?) + veilid_capnp::safety_route::hops::Which::Private(pr_reader) => { + let pr_reader = pr_reader?; + SafetyRouteHops::Private(decode_private_route(decode_context, &pr_reader)?) } - veilid_capnp::private_route::hops::Which::Empty(_) => PrivateRouteHops::Empty, }; - Ok(PrivateRoute { + Ok(SafetyRoute { public_key, hop_count, hops, }) } -//////////////////////////////////////////////////////////////////////////////////////////////////// - pub fn encode_safety_route( safety_route: &SafetyRoute, builder: &mut veilid_capnp::safety_route::Builder, @@ -179,31 +192,3 @@ pub fn encode_safety_route( Ok(()) } - -pub fn decode_safety_route( - decode_context: &RPCDecodeContext, - reader: &veilid_capnp::safety_route::Reader, -) -> Result { - let public_key = decode_typed_public_key( - &reader - .get_public_key() - .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().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)?) - } - veilid_capnp::safety_route::hops::Which::Private(pr_reader) => { - let pr_reader = pr_reader.map_err(RPCError::protocol)?; - SafetyRouteHops::Private(decode_private_route(decode_context, &pr_reader)?) - } - }; - - Ok(SafetyRoute { - public_key, - hop_count, - hops, - }) -} diff --git a/veilid-core/src/rpc_processor/coders/protocol_type_set.rs b/veilid-core/src/rpc_processor/coders/protocol_type_set.rs index 6ebf71e7..4f033f61 100644 --- a/veilid-core/src/rpc_processor/coders/protocol_type_set.rs +++ b/veilid-core/src/rpc_processor/coders/protocol_type_set.rs @@ -1,32 +1,30 @@ use super::*; +pub fn decode_protocol_type_set( + reader: &veilid_capnp::protocol_type_set::Reader, +) -> ProtocolTypeSet { + let mut out = ProtocolTypeSet::new(); + if reader.get_udp() { + out.insert(ProtocolType::UDP); + } + if reader.get_tcp() { + out.insert(ProtocolType::TCP); + } + if reader.get_ws() { + out.insert(ProtocolType::WS); + } + if reader.get_wss() { + out.insert(ProtocolType::WSS); + } + out +} + pub fn encode_protocol_type_set( protocol_type_set: &ProtocolTypeSet, builder: &mut veilid_capnp::protocol_type_set::Builder, -) -> Result<(), RPCError> { +) { builder.set_udp(protocol_type_set.contains(ProtocolType::UDP)); builder.set_tcp(protocol_type_set.contains(ProtocolType::TCP)); builder.set_ws(protocol_type_set.contains(ProtocolType::WS)); builder.set_wss(protocol_type_set.contains(ProtocolType::WSS)); - - Ok(()) -} - -pub fn decode_protocol_type_set( - reader: &veilid_capnp::protocol_type_set::Reader, -) -> Result { - let mut out = ProtocolTypeSet::new(); - if reader.reborrow().get_udp() { - out.insert(ProtocolType::UDP); - } - if reader.reborrow().get_tcp() { - out.insert(ProtocolType::TCP); - } - if reader.reborrow().get_ws() { - out.insert(ProtocolType::WS); - } - if reader.reborrow().get_wss() { - out.insert(ProtocolType::WSS); - } - Ok(out) } diff --git a/veilid-core/src/rpc_processor/coders/sender_info.rs b/veilid-core/src/rpc_processor/coders/sender_info.rs index 45fd96c8..394bb1fd 100644 --- a/veilid-core/src/rpc_processor/coders/sender_info.rs +++ b/veilid-core/src/rpc_processor/coders/sender_info.rs @@ -1,5 +1,15 @@ use super::*; +pub fn decode_sender_info( + reader: &veilid_capnp::sender_info::Reader, +) -> Result { + rpc_ignore_missing_property!(reader, socket_address); + let sa_reader = reader.get_socket_address()?; + let socket_address = decode_socket_address(&sa_reader)?; + + Ok(SenderInfo { socket_address }) +} + pub fn encode_sender_info( sender_info: &SenderInfo, builder: &mut veilid_capnp::sender_info::Builder, @@ -8,17 +18,3 @@ pub fn encode_sender_info( encode_socket_address(&sender_info.socket_address, &mut sab)?; Ok(()) } - -pub fn decode_sender_info( - reader: &veilid_capnp::sender_info::Reader, -) -> Result { - let sa_reader = reader - .reborrow() - .get_socket_address() - .map_err(RPCError::map_internal( - "invalid socket address in sender_info", - ))?; - let socket_address = decode_socket_address(&sa_reader)?; - - Ok(SenderInfo { socket_address }) -} diff --git a/veilid-core/src/rpc_processor/coders/sequencing.rs b/veilid-core/src/rpc_processor/coders/sequencing.rs index 187762fc..1565668a 100644 --- a/veilid-core/src/rpc_processor/coders/sequencing.rs +++ b/veilid-core/src/rpc_processor/coders/sequencing.rs @@ -1,13 +1,5 @@ use super::*; -pub fn encode_sequencing(sequencing: Sequencing) -> veilid_capnp::Sequencing { - match sequencing { - Sequencing::NoPreference => veilid_capnp::Sequencing::NoPreference, - Sequencing::PreferOrdered => veilid_capnp::Sequencing::PreferOrdered, - Sequencing::EnsureOrdered => veilid_capnp::Sequencing::EnsureOrdered, - } -} - pub fn decode_sequencing(sequencing: veilid_capnp::Sequencing) -> Sequencing { match sequencing { veilid_capnp::Sequencing::NoPreference => Sequencing::NoPreference, @@ -15,3 +7,11 @@ pub fn decode_sequencing(sequencing: veilid_capnp::Sequencing) -> Sequencing { veilid_capnp::Sequencing::EnsureOrdered => Sequencing::EnsureOrdered, } } + +pub fn encode_sequencing(sequencing: Sequencing) -> veilid_capnp::Sequencing { + match sequencing { + Sequencing::NoPreference => veilid_capnp::Sequencing::NoPreference, + Sequencing::PreferOrdered => veilid_capnp::Sequencing::PreferOrdered, + Sequencing::EnsureOrdered => veilid_capnp::Sequencing::EnsureOrdered, + } +} diff --git a/veilid-core/src/rpc_processor/coders/signal_info.rs b/veilid-core/src/rpc_processor/coders/signal_info.rs index 2965ec49..4681d0a1 100644 --- a/veilid-core/src/rpc_processor/coders/signal_info.rs +++ b/veilid-core/src/rpc_processor/coders/signal_info.rs @@ -1,5 +1,35 @@ use super::*; +pub fn decode_signal_info( + decode_context: &RPCDecodeContext, + reader: &veilid_capnp::operation_signal::Reader, +) -> Result { + Ok(match reader.which()? { + veilid_capnp::operation_signal::HolePunch(r) => { + // Extract hole punch reader + let r = r?; + rpc_ignore_missing_property!(r, receipt); + let receipt = r.get_receipt()?.to_vec(); + rpc_ignore_missing_property!(r, peer_info); + let pi_reader = r.get_peer_info()?; + let peer_info = Arc::new(decode_peer_info(decode_context, &pi_reader)?); + + SignalInfo::HolePunch { receipt, peer_info } + } + veilid_capnp::operation_signal::ReverseConnect(r) => { + // Extract reverse connect reader + let r = r?; + rpc_ignore_missing_property!(r, receipt); + let receipt = r.get_receipt()?.to_vec(); + rpc_ignore_missing_property!(r, peer_info); + let pi_reader = r.get_peer_info()?; + let peer_info = Arc::new(decode_peer_info(decode_context, &pi_reader)?); + + SignalInfo::ReverseConnect { receipt, peer_info } + } + }) +} + pub fn encode_signal_info( signal_info: &SignalInfo, builder: &mut veilid_capnp::operation_signal::Builder, @@ -31,48 +61,3 @@ pub fn encode_signal_info( Ok(()) } - -pub fn decode_signal_info( - decode_context: &RPCDecodeContext, - reader: &veilid_capnp::operation_signal::Reader, -) -> Result { - Ok( - match reader - .which() - .map_err(RPCError::map_internal("invalid signal operation"))? - { - veilid_capnp::operation_signal::HolePunch(r) => { - // Extract hole punch reader - let r = r.map_err(RPCError::protocol)?; - let receipt = r - .get_receipt() - .map_err(RPCError::map_protocol( - "invalid receipt in hole punch signal info", - ))? - .to_vec(); - let pi_reader = r.get_peer_info().map_err(RPCError::map_protocol( - "invalid peer info in hole punch signal info", - ))?; - let peer_info = Arc::new(decode_peer_info(decode_context, &pi_reader)?); - - SignalInfo::HolePunch { receipt, peer_info } - } - veilid_capnp::operation_signal::ReverseConnect(r) => { - // Extract reverse connect reader - let r = r.map_err(RPCError::protocol)?; - let receipt = r - .get_receipt() - .map_err(RPCError::map_protocol( - "invalid receipt in hole punch signal info", - ))? - .to_vec(); - let pi_reader = r.get_peer_info().map_err(RPCError::map_protocol( - "invalid peer info in reverse connect signal info", - ))?; - let peer_info = Arc::new(decode_peer_info(decode_context, &pi_reader)?); - - SignalInfo::ReverseConnect { receipt, peer_info } - } - }, - ) -} diff --git a/veilid-core/src/rpc_processor/coders/signed_direct_node_info.rs b/veilid-core/src/rpc_processor/coders/signed_direct_node_info.rs index 4740ea59..2a0d817e 100644 --- a/veilid-core/src/rpc_processor/coders/signed_direct_node_info.rs +++ b/veilid-core/src/rpc_processor/coders/signed_direct_node_info.rs @@ -1,5 +1,32 @@ use super::*; +pub fn decode_signed_direct_node_info( + reader: &veilid_capnp::signed_direct_node_info::Reader, +) -> Result { + rpc_ignore_missing_property!(reader, node_info); + let ni_reader = reader.get_node_info()?; + let node_info = decode_node_info(&ni_reader)?; + + let timestamp = reader.get_timestamp().into(); + + rpc_ignore_missing_property!(reader, signatures); + let sigs_reader = reader.get_signatures()?; + let sigs_len = rpc_ignore_max_len!(sigs_reader, MAX_CRYPTO_KINDS); + let mut typed_signatures = Vec::with_capacity(sigs_len); + for sig_reader in sigs_reader { + let Some(typed_signature) = decode_typed_signature(&sig_reader).ignore_ok()? else { + continue; + }; + typed_signatures.push(typed_signature); + } + + Ok(SignedDirectNodeInfo::new( + node_info, + timestamp, + typed_signatures, + )) +} + pub fn encode_signed_direct_node_info( signed_direct_node_info: &SignedDirectNodeInfo, builder: &mut veilid_capnp::signed_direct_node_info::Builder, @@ -31,37 +58,3 @@ pub fn encode_signed_direct_node_info( Ok(()) } - -pub fn decode_signed_direct_node_info( - reader: &veilid_capnp::signed_direct_node_info::Reader, -) -> Result { - let ni_reader = reader - .reborrow() - .get_node_info() - .map_err(RPCError::protocol)?; - let node_info = decode_node_info(&ni_reader)?; - - let timestamp = reader.reborrow().get_timestamp().into(); - - let sigs_reader = reader - .reborrow() - .get_signatures() - .map_err(RPCError::protocol)?; - - let sig_count = sigs_reader.len() as usize; - if sig_count > MAX_CRYPTO_KINDS { - return Err(RPCError::protocol("too many signatures")); - } - - let mut typed_signatures = Vec::with_capacity(sig_count); - for sig_reader in sigs_reader { - let typed_signature = decode_typed_signature(&sig_reader)?; - typed_signatures.push(typed_signature); - } - - Ok(SignedDirectNodeInfo::new( - node_info, - timestamp, - typed_signatures, - )) -} diff --git a/veilid-core/src/rpc_processor/coders/signed_node_info.rs b/veilid-core/src/rpc_processor/coders/signed_node_info.rs index e3ced6ad..90bc82c6 100644 --- a/veilid-core/src/rpc_processor/coders/signed_node_info.rs +++ b/veilid-core/src/rpc_processor/coders/signed_node_info.rs @@ -1,5 +1,22 @@ use super::*; +pub fn decode_signed_node_info( + reader: &veilid_capnp::signed_node_info::Reader, +) -> Result { + match reader.which()? { + veilid_capnp::signed_node_info::Direct(d) => { + let d_reader = d?; + let sdni = decode_signed_direct_node_info(&d_reader)?; + Ok(SignedNodeInfo::Direct(sdni)) + } + veilid_capnp::signed_node_info::Relayed(r) => { + let r_reader = r?; + let srni = decode_signed_relayed_node_info(&r_reader)?; + Ok(SignedNodeInfo::Relayed(srni)) + } + } +} + pub fn encode_signed_node_info( signed_node_info: &SignedNodeInfo, builder: &mut veilid_capnp::signed_node_info::Builder, @@ -17,23 +34,3 @@ pub fn encode_signed_node_info( Ok(()) } - -pub fn decode_signed_node_info( - reader: &veilid_capnp::signed_node_info::Reader, -) -> Result { - match reader - .which() - .map_err(RPCError::map_internal("invalid signed node info"))? - { - veilid_capnp::signed_node_info::Direct(d) => { - let d_reader = d.map_err(RPCError::protocol)?; - let sdni = decode_signed_direct_node_info(&d_reader)?; - Ok(SignedNodeInfo::Direct(sdni)) - } - veilid_capnp::signed_node_info::Relayed(r) => { - let r_reader = r.map_err(RPCError::protocol)?; - let srni = decode_signed_relayed_node_info(&r_reader)?; - Ok(SignedNodeInfo::Relayed(srni)) - } - } -} diff --git a/veilid-core/src/rpc_processor/coders/signed_relayed_node_info.rs b/veilid-core/src/rpc_processor/coders/signed_relayed_node_info.rs index c7c00bd4..8aae1e93 100644 --- a/veilid-core/src/rpc_processor/coders/signed_relayed_node_info.rs +++ b/veilid-core/src/rpc_processor/coders/signed_relayed_node_info.rs @@ -1,5 +1,50 @@ use super::*; +pub fn decode_signed_relayed_node_info( + reader: &veilid_capnp::signed_relayed_node_info::Reader, +) -> Result { + rpc_ignore_missing_property!(reader, node_info); + let ni_reader = reader.get_node_info()?; + let node_info = decode_node_info(&ni_reader)?; + + rpc_ignore_missing_property!(reader, relay_ids); + let rids_reader = reader.get_relay_ids()?; + let rid_count = rpc_ignore_max_len!(rids_reader, MAX_CRYPTO_KINDS); + let mut relay_ids = NodeIdGroup::with_capacity(rid_count); + for rid_reader in rids_reader { + let Some(relay_id) = decode_typed_node_id(&rid_reader).ignore_ok()? else { + continue; + }; + relay_ids.add(relay_id); + } + + let ri_reader = reader + .reborrow() + .get_relay_info() + .map_err(RPCError::protocol)?; + let relay_info = decode_signed_direct_node_info(&ri_reader)?; + + let timestamp = reader.reborrow().get_timestamp().into(); + + rpc_ignore_missing_property!(reader, signatures); + let sigs_reader = reader.get_signatures()?; + let sig_count = rpc_ignore_max_len!(sigs_reader, MAX_CRYPTO_KINDS); + let mut typed_signatures = Vec::with_capacity(sig_count); + for sig_reader in sigs_reader { + let Some(typed_signature) = decode_typed_signature(&sig_reader).ignore_ok()? else { + continue; + }; + typed_signatures.push(typed_signature); + } + Ok(SignedRelayedNodeInfo::new( + node_info, + relay_ids, + relay_info, + timestamp, + typed_signatures, + )) +} + pub fn encode_signed_relayed_node_info( signed_relayed_node_info: &SignedRelayedNodeInfo, builder: &mut veilid_capnp::signed_relayed_node_info::Builder, @@ -51,58 +96,3 @@ pub fn encode_signed_relayed_node_info( Ok(()) } - -pub fn decode_signed_relayed_node_info( - reader: &veilid_capnp::signed_relayed_node_info::Reader, -) -> Result { - let ni_reader = reader - .reborrow() - .get_node_info() - .map_err(RPCError::protocol)?; - let node_info = decode_node_info(&ni_reader)?; - - let rids_reader = reader - .reborrow() - .get_relay_ids() - .map_err(RPCError::protocol)?; - let rid_count = rids_reader.len() as usize; - if rid_count > MAX_CRYPTO_KINDS { - return Err(RPCError::protocol("too many relay ids")); - } - let mut relay_ids = NodeIdGroup::with_capacity(rid_count); - for rid_reader in rids_reader { - let relay_id = decode_typed_node_id(&rid_reader)?; - relay_ids.add(relay_id); - } - - let ri_reader = reader - .reborrow() - .get_relay_info() - .map_err(RPCError::protocol)?; - let relay_info = decode_signed_direct_node_info(&ri_reader)?; - - let timestamp = reader.reborrow().get_timestamp().into(); - - let sigs_reader = reader - .reborrow() - .get_signatures() - .map_err(RPCError::protocol)?; - - let sig_count = sigs_reader.len() as usize; - if sig_count > MAX_CRYPTO_KINDS { - return Err(RPCError::protocol("too many signatures")); - } - - let mut typed_signatures = Vec::with_capacity(sig_count); - for sig_reader in sigs_reader { - let typed_signature = decode_typed_signature(&sig_reader)?; - typed_signatures.push(typed_signature); - } - Ok(SignedRelayedNodeInfo::new( - node_info, - relay_ids, - relay_info, - timestamp, - typed_signatures, - )) -} diff --git a/veilid-core/src/rpc_processor/coders/signed_value_data.rs b/veilid-core/src/rpc_processor/coders/signed_value_data.rs index bb866413..fa1675e2 100644 --- a/veilid-core/src/rpc_processor/coders/signed_value_data.rs +++ b/veilid-core/src/rpc_processor/coders/signed_value_data.rs @@ -1,6 +1,25 @@ use super::*; use crate::storage_manager::*; +pub fn decode_signed_value_data( + reader: &veilid_capnp::signed_value_data::Reader, +) -> Result { + let seq = reader.get_seq(); + rpc_ignore_missing_property!(reader, data); + let data = reader.get_data()?.to_vec(); + rpc_ignore_missing_property!(reader, writer); + let wr = reader.get_writer()?; + let writer = decode_key256(&wr); + rpc_ignore_missing_property!(reader, signature); + let sr = reader.get_signature()?; + let signature = decode_signature512(&sr); + + Ok(SignedValueData::new( + ValueData::new_with_seq(seq, data, writer).map_err(RPCError::protocol)?, + signature, + )) +} + pub fn encode_signed_value_data( signed_value_data: &SignedValueData, builder: &mut veilid_capnp::signed_value_data::Builder, @@ -13,19 +32,3 @@ pub fn encode_signed_value_data( encode_signature512(signed_value_data.signature(), &mut sb); Ok(()) } - -pub fn decode_signed_value_data( - reader: &veilid_capnp::signed_value_data::Reader, -) -> Result { - let seq = reader.get_seq(); - let data = reader.get_data().map_err(RPCError::protocol)?.to_vec(); - let wr = reader.get_writer().map_err(RPCError::protocol)?; - let writer = decode_key256(&wr); - let sr = reader.get_signature().map_err(RPCError::protocol)?; - let signature = decode_signature512(&sr); - - Ok(SignedValueData::new( - ValueData::new_with_seq(seq, data, writer).map_err(RPCError::protocol)?, - signature, - )) -} diff --git a/veilid-core/src/rpc_processor/coders/signed_value_descriptor.rs b/veilid-core/src/rpc_processor/coders/signed_value_descriptor.rs index c1c93f69..d62b257b 100644 --- a/veilid-core/src/rpc_processor/coders/signed_value_descriptor.rs +++ b/veilid-core/src/rpc_processor/coders/signed_value_descriptor.rs @@ -1,6 +1,20 @@ use super::*; use crate::storage_manager::SignedValueDescriptor; +pub fn decode_signed_value_descriptor( + reader: &veilid_capnp::signed_value_descriptor::Reader, +) -> Result { + rpc_ignore_missing_property!(reader, owner); + let or = reader.get_owner()?; + let owner = decode_key256(&or); + rpc_ignore_missing_property!(reader, schema_data); + let schema_data = reader.get_schema_data()?.to_vec(); + rpc_ignore_missing_property!(reader, signature); + let sr = reader.get_signature()?; + let signature = decode_signature512(&sr); + Ok(SignedValueDescriptor::new(owner, schema_data, signature)) +} + pub fn encode_signed_value_descriptor( signed_value_descriptor: &SignedValueDescriptor, builder: &mut veilid_capnp::signed_value_descriptor::Builder, @@ -12,17 +26,3 @@ pub fn encode_signed_value_descriptor( encode_signature512(signed_value_descriptor.signature(), &mut sb); Ok(()) } - -pub fn decode_signed_value_descriptor( - reader: &veilid_capnp::signed_value_descriptor::Reader, -) -> Result { - let or = reader.get_owner().map_err(RPCError::protocol)?; - let owner = decode_key256(&or); - let schema_data = reader - .get_schema_data() - .map_err(RPCError::protocol)? - .to_vec(); - let sr = reader.get_signature().map_err(RPCError::protocol)?; - let signature = decode_signature512(&sr); - Ok(SignedValueDescriptor::new(owner, schema_data, signature)) -} diff --git a/veilid-core/src/rpc_processor/coders/socket_address.rs b/veilid-core/src/rpc_processor/coders/socket_address.rs index 41542550..eb0a9a39 100644 --- a/veilid-core/src/rpc_processor/coders/socket_address.rs +++ b/veilid-core/src/rpc_processor/coders/socket_address.rs @@ -1,24 +1,22 @@ use super::*; +pub fn decode_socket_address( + reader: &veilid_capnp::socket_address::Reader, +) -> Result { + rpc_ignore_missing_property!(reader, address); + let ar = reader.get_address()?; + let address = decode_address(&ar)?; + let port = reader.get_port(); + + Ok(SocketAddress::new(address, port)) +} + pub fn encode_socket_address( socket_address: &SocketAddress, builder: &mut veilid_capnp::socket_address::Builder, ) -> Result<(), RPCError> { let mut ab = builder.reborrow().init_address(); - encode_address(&socket_address.address(), &mut ab)?; + encode_address(&socket_address.address(), &mut ab); builder.set_port(socket_address.port()); Ok(()) } - -pub fn decode_socket_address( - reader: &veilid_capnp::socket_address::Reader, -) -> Result { - let ar = reader - .reborrow() - .get_address() - .map_err(RPCError::map_internal("missing socketAddress"))?; - let address = decode_address(&ar)?; - let port = reader.get_port(); - - Ok(SocketAddress::new(address, port)) -} diff --git a/veilid-core/src/rpc_processor/coders/tunnel.rs b/veilid-core/src/rpc_processor/coders/tunnel.rs index 994cd0da..7768ed55 100644 --- a/veilid-core/src/rpc_processor/coders/tunnel.rs +++ b/veilid-core/src/rpc_processor/coders/tunnel.rs @@ -1,12 +1,5 @@ use super::*; -pub fn encode_tunnel_mode(tunnel_mode: TunnelMode) -> veilid_capnp::TunnelEndpointMode { - match tunnel_mode { - TunnelMode::Raw => veilid_capnp::TunnelEndpointMode::Raw, - TunnelMode::Turn => veilid_capnp::TunnelEndpointMode::Turn, - } -} - pub fn decode_tunnel_mode(tunnel_endpoint_mode: veilid_capnp::TunnelEndpointMode) -> TunnelMode { match tunnel_endpoint_mode { veilid_capnp::TunnelEndpointMode::Raw => TunnelMode::Raw, @@ -14,12 +7,10 @@ pub fn decode_tunnel_mode(tunnel_endpoint_mode: veilid_capnp::TunnelEndpointMode } } -pub fn encode_tunnel_error(tunnel_error: TunnelError) -> veilid_capnp::TunnelError { - match tunnel_error { - TunnelError::BadId => veilid_capnp::TunnelError::BadId, - TunnelError::NoEndpoint => veilid_capnp::TunnelError::NoEndpoint, - TunnelError::RejectedMode => veilid_capnp::TunnelError::RejectedMode, - TunnelError::NoCapacity => veilid_capnp::TunnelError::NoCapacity, +pub fn encode_tunnel_mode(tunnel_mode: TunnelMode) -> veilid_capnp::TunnelEndpointMode { + match tunnel_mode { + TunnelMode::Raw => veilid_capnp::TunnelEndpointMode::Raw, + TunnelMode::Turn => veilid_capnp::TunnelEndpointMode::Turn, } } @@ -32,6 +23,25 @@ pub fn decode_tunnel_error(tunnel_error: veilid_capnp::TunnelError) -> TunnelErr } } +pub fn encode_tunnel_error(tunnel_error: TunnelError) -> veilid_capnp::TunnelError { + match tunnel_error { + TunnelError::BadId => veilid_capnp::TunnelError::BadId, + TunnelError::NoEndpoint => veilid_capnp::TunnelError::NoEndpoint, + TunnelError::RejectedMode => veilid_capnp::TunnelError::RejectedMode, + TunnelError::NoCapacity => veilid_capnp::TunnelError::NoCapacity, + } +} + +pub fn decode_tunnel_endpoint( + reader: &veilid_capnp::tunnel_endpoint::Reader, +) -> Result { + let mode = decode_tunnel_mode(reader.get_mode()?); + rpc_ignore_missing_property!(reader, description); + let description = reader.get_description()?.to_owned(); + + Ok(TunnelEndpoint { mode, description }) +} + pub fn encode_tunnel_endpoint( tunnel_endpoint: &TunnelEndpoint, builder: &mut veilid_capnp::tunnel_endpoint::Builder, @@ -42,16 +52,24 @@ pub fn encode_tunnel_endpoint( Ok(()) } -pub fn decode_tunnel_endpoint( - reader: &veilid_capnp::tunnel_endpoint::Reader, -) -> Result { - let mode = decode_tunnel_mode(reader.get_mode().map_err(RPCError::protocol)?); - let description = reader - .get_description() - .map_err(RPCError::protocol)? - .to_owned(); +pub fn decode_full_tunnel( + reader: &veilid_capnp::full_tunnel::Reader, +) -> Result { + let id = TunnelId::new(reader.get_id()); + let timeout = TimestampDuration::new(reader.get_timeout()); + rpc_ignore_missing_property!(reader, local); + let l_reader = reader.get_local()?; + let local = decode_tunnel_endpoint(&l_reader)?; + rpc_ignore_missing_property!(reader, remote); + let r_reader = reader.get_remote()?; + let remote = decode_tunnel_endpoint(&r_reader)?; - Ok(TunnelEndpoint { mode, description }) + Ok(FullTunnel { + id, + timeout, + local, + remote, + }) } pub fn encode_full_tunnel( @@ -67,22 +85,16 @@ pub fn encode_full_tunnel( Ok(()) } -pub fn decode_full_tunnel( - reader: &veilid_capnp::full_tunnel::Reader, -) -> Result { +pub fn decode_partial_tunnel( + reader: &veilid_capnp::partial_tunnel::Reader, +) -> Result { let id = TunnelId::new(reader.get_id()); let timeout = TimestampDuration::new(reader.get_timeout()); - let l_reader = reader.get_local().map_err(RPCError::protocol)?; + rpc_ignore_missing_property!(reader, local); + let l_reader = reader.get_local()?; let local = decode_tunnel_endpoint(&l_reader)?; - let r_reader = reader.get_remote().map_err(RPCError::protocol)?; - let remote = decode_tunnel_endpoint(&r_reader)?; - Ok(FullTunnel { - id, - timeout, - local, - remote, - }) + Ok(PartialTunnel { id, timeout, local }) } pub fn encode_partial_tunnel( @@ -95,14 +107,3 @@ pub fn encode_partial_tunnel( encode_tunnel_endpoint(&partial_tunnel.local, &mut l_builder)?; Ok(()) } - -pub fn decode_partial_tunnel( - reader: &veilid_capnp::partial_tunnel::Reader, -) -> Result { - let id = TunnelId::new(reader.get_id()); - let timeout = TimestampDuration::new(reader.get_timeout()); - let l_reader = reader.get_local().map_err(RPCError::protocol)?; - let local = decode_tunnel_endpoint(&l_reader)?; - - Ok(PartialTunnel { id, timeout, local }) -} diff --git a/veilid-core/src/rpc_processor/coders/typed_key.rs b/veilid-core/src/rpc_processor/coders/typed_key.rs index 32c3cced..8b9c0578 100644 --- a/veilid-core/src/rpc_processor/coders/typed_key.rs +++ b/veilid-core/src/rpc_processor/coders/typed_key.rs @@ -1,12 +1,11 @@ use super::*; pub fn decode_typed_public_key( - typed_key: &veilid_capnp::typed_key::Reader, + reader: &veilid_capnp::typed_key::Reader, ) -> Result { - let key_reader = typed_key - .get_key() - .map_err(RPCError::map_invalid_format("invalid typed key"))?; - let kind = typed_key.get_kind(); + rpc_ignore_missing_property!(reader, key); + let key_reader = reader.get_key()?; + let kind = reader.get_kind(); Ok(PublicKey::new( CryptoKind::from(kind.to_be_bytes()), @@ -23,13 +22,10 @@ pub fn encode_typed_public_key( encode_key256(&typed_key.value, &mut key_builder); } -pub fn decode_typed_node_id( - typed_key: &veilid_capnp::typed_key::Reader, -) -> Result { - let key_reader = typed_key - .get_key() - .map_err(RPCError::map_invalid_format("invalid typed key"))?; - let kind = typed_key.get_kind(); +pub fn decode_typed_node_id(reader: &veilid_capnp::typed_key::Reader) -> Result { + rpc_ignore_missing_property!(reader, key); + let key_reader = reader.get_key()?; + let kind = reader.get_kind(); Ok(NodeId::new( CryptoKind::from(kind.to_be_bytes()), @@ -44,12 +40,11 @@ pub fn encode_typed_node_id(typed_key: &NodeId, builder: &mut veilid_capnp::type } pub fn decode_typed_record_key( - typed_key: &veilid_capnp::typed_key::Reader, + reader: &veilid_capnp::typed_key::Reader, ) -> Result { - let key_reader = typed_key - .get_key() - .map_err(RPCError::map_invalid_format("invalid typed key"))?; - let kind = typed_key.get_kind(); + rpc_ignore_missing_property!(reader, key); + let key_reader = reader.get_key()?; + let kind = reader.get_kind(); Ok(RecordKey::new( CryptoKind::from(kind.to_be_bytes()), diff --git a/veilid-core/src/rpc_processor/coders/typed_signature.rs b/veilid-core/src/rpc_processor/coders/typed_signature.rs index 916c79b6..0a8acb16 100644 --- a/veilid-core/src/rpc_processor/coders/typed_signature.rs +++ b/veilid-core/src/rpc_processor/coders/typed_signature.rs @@ -1,12 +1,11 @@ use super::*; pub fn decode_typed_signature( - typed_signature: &veilid_capnp::typed_signature::Reader, + reader: &veilid_capnp::typed_signature::Reader, ) -> Result { - let sig_reader = typed_signature - .get_signature() - .map_err(RPCError::map_invalid_format("invalid typed signature"))?; - let kind = typed_signature.get_kind(); + rpc_ignore_missing_property!(reader, signature); + let sig_reader = reader.get_signature()?; + let kind = reader.get_kind(); Ok(Signature::new( CryptoKind::from(kind.to_be_bytes()), diff --git a/veilid-core/src/rpc_processor/coders/value_data.rs b/veilid-core/src/rpc_processor/coders/value_data.rs index c5985b6c..42f8dc42 100644 --- a/veilid-core/src/rpc_processor/coders/value_data.rs +++ b/veilid-core/src/rpc_processor/coders/value_data.rs @@ -1,5 +1,27 @@ use super::*; +pub fn decode_signed_value_data( + reader: &veilid_capnp::signed_value_data::Reader, +) -> Result { + let seq = reader.get_seq(); + + rpc_ignore_missing_property!(reader, data); + let data = reader.get_data()?.to_vec(); + + rpc_ignore_missing_property!(reader, writer); + let wr = reader.get_writer()?; + let writer = decode_key256(&wr); + + rpc_ignore_missing_property!(reader, signature); + let sr = reader.get_signature()?; + let signature = decode_signature512(&sr); + + Ok(SignedValueData { + value_data: ValueData { seq, data, writer }, + signature, + }) +} + pub fn encode_signed_value_data( signed_value_data: &SignedValueData, builder: &mut veilid_capnp::signed_value_data::Builder, @@ -12,19 +34,3 @@ pub fn encode_signed_value_data( encode_signature512(signed_value_data.signature(), &mut sb); Ok(()) } - -pub fn decode_signed_value_data( - reader: &veilid_capnp::signed_value_data::Reader, -) -> Result { - let seq = reader.get_seq(); - let data = reader.get_data().map_err(RPCError::protocol)?.to_vec(); - let wr = reader.get_writer().map_err(RPCError::protocol)?; - let writer = decode_key256(&wr); - let sr = reader.get_signature().map_err(RPCError::protocol)?; - let signature = decode_signature512(&sr); - - Ok(SignedValueData { - value_data: ValueData { seq, data, writer }, - signature, - }) -} diff --git a/veilid-core/src/rpc_processor/error.rs b/veilid-core/src/rpc_processor/error.rs index 25fac16d..c13ea161 100644 --- a/veilid-core/src/rpc_processor/error.rs +++ b/veilid-core/src/rpc_processor/error.rs @@ -102,3 +102,77 @@ impl ToRPCNetworkResult for VeilidAPIResult { } } } + +impl From for RPCError { + fn from(_value: capnp::NotInSchema) -> Self { + RPCError::ignore("not in schema") + } +} + +impl From for RPCError { + fn from(value: capnp::Error) -> Self { + RPCError::protocol(value) + } +} + +pub trait RPCErrorIgnoreOk { + fn ignore_ok(self) -> Result, RPCError>; +} + +impl RPCErrorIgnoreOk for Result { + fn ignore_ok(self) -> Result, RPCError> { + match self { + Ok(v) => Ok(Some(v)), + Err(RPCError::Ignore(_)) => Ok(None), + Err(e) => Err(e), + } + } +} + +#[macro_export] +macro_rules! rpc_ignore_missing_property { + ($reader:expr, $propname:tt) => { + paste::paste! { + if !$reader.[]() { + return Err(RPCError::ignore(concat!("missing ", stringify!($propname)))); + } + } + }; +} + +#[macro_export] +macro_rules! rpc_ignore_max_len { + ($reader:expr, $max_len:expr) => {{ + let _len = $reader.len() as usize; + if _len > $max_len { + return Err(RPCError::ignore(concat!( + stringify!($reader), + " length > ", + stringify!($max_len) + ))); + } + _len + }}; +} + +#[macro_export] +macro_rules! rpc_ignore_min_max_len { + ($reader:expr, $min_len:expr, $max_len:expr) => {{ + let _len = $reader.len() as usize; + if _len < $min_len { + return Err(RPCError::ignore(concat!( + stringify!($reader), + " length < ", + stringify!($min_len) + ))); + } + if _len > $max_len { + return Err(RPCError::ignore(concat!( + stringify!($reader), + " length > ", + stringify!($max_len) + ))); + } + _len + }}; +} diff --git a/veilid-core/src/rpc_processor/mod.rs b/veilid-core/src/rpc_processor/mod.rs index b8d88b8c..70bff655 100644 --- a/veilid-core/src/rpc_processor/mod.rs +++ b/veilid-core/src/rpc_processor/mod.rs @@ -1375,9 +1375,7 @@ impl RPCProcessor { #[instrument(level = "trace", target = "rpc", skip_all)] fn decode_rpc_operation(&self, encoded_msg: &MessageEncoded) -> Result { let reader = encoded_msg.data.get_reader()?; - let op_reader = reader - .get_root::() - .map_err(RPCError::protocol)?; + let op_reader = reader.get_root::()?; let decode_context = RPCDecodeContext { routing_domain: encoded_msg.header.routing_domain(), }; diff --git a/veilid-core/src/rpc_processor/rpc_route.rs b/veilid-core/src/rpc_processor/rpc_route.rs index cb2e7653..47f9e9c6 100644 --- a/veilid-core/src/rpc_processor/rpc_route.rs +++ b/veilid-core/src/rpc_processor/rpc_route.rs @@ -366,9 +366,7 @@ impl RPCProcessor { // Decode next RouteHop let route_hop = { - let rh_reader = dec_blob_reader - .get_root::() - .map_err(RPCError::protocol)?; + let rh_reader = dec_blob_reader.get_root::()?; let decode_context = RPCDecodeContext { routing_domain: routed_operation.routing_domain(), };