receipt rework and discovery rework

This commit is contained in:
John Smith
2022-05-28 10:07:57 -04:00
parent d80a81e460
commit b6e568f664
23 changed files with 817 additions and 431 deletions

View File

@@ -10,6 +10,9 @@ pub fn encode_node_info(
let mut ps_builder = builder.reborrow().init_outbound_protocols();
encode_protocol_set(&node_info.outbound_protocols, &mut ps_builder)?;
builder.set_min_version(node_info.min_version);
builder.set_max_version(node_info.max_version);
let mut didl_builder = builder.reborrow().init_dial_info_detail_list(
node_info
.dial_info_detail_list
@@ -51,6 +54,9 @@ pub fn decode_node_info(
.map_err(map_error_capnp_error!())?,
)?;
let min_version = reader.reborrow().get_min_version();
let max_version = reader.reborrow().get_max_version();
let didl_reader = reader
.reborrow()
.get_dial_info_detail_list()
@@ -84,6 +90,8 @@ pub fn decode_node_info(
Ok(NodeInfo {
network_class,
outbound_protocols,
min_version,
max_version,
dial_info_detail_list,
relay_peer_info,
})

View File

@@ -6,28 +6,24 @@ pub fn encode_signal_info(
builder: &mut veilid_capnp::operation_signal::Builder,
) -> Result<(), RPCError> {
match signal_info {
SignalInfo::HolePunch { receipt, peer_info } => {
SignalInfo::HolePunch {
receipt_nonce,
peer_info,
} => {
let mut hp_builder = builder.reborrow().init_hole_punch();
let rcpt_builder =
hp_builder
.reborrow()
.init_receipt(receipt.len().try_into().map_err(map_error_protocol!(
"invalid receipt length in hole punch signal info"
))?);
rcpt_builder.copy_from_slice(receipt.as_slice());
let mut rn_builder = hp_builder.reborrow().init_receipt_nonce();
encode_nonce(receipt_nonce, &mut rn_builder);
let mut pi_builder = hp_builder.init_peer_info();
encode_peer_info(peer_info, &mut pi_builder)?;
}
SignalInfo::ReverseConnect { receipt, peer_info } => {
let mut hp_builder = builder.reborrow().init_reverse_connect();
let rcpt_builder =
hp_builder
.reborrow()
.init_receipt(receipt.len().try_into().map_err(map_error_protocol!(
"invalid receipt length in reverse connect signal info"
))?);
rcpt_builder.copy_from_slice(receipt.as_slice());
let mut pi_builder = hp_builder.init_peer_info();
SignalInfo::ReverseConnect {
receipt_nonce,
peer_info,
} => {
let mut rc_builder = builder.reborrow().init_reverse_connect();
let mut rn_builder = rc_builder.reborrow().init_receipt_nonce();
encode_nonce(receipt_nonce, &mut rn_builder);
let mut pi_builder = rc_builder.init_peer_info();
encode_peer_info(peer_info, &mut pi_builder)?;
}
}
@@ -49,18 +45,17 @@ pub fn decode_signal_info(
Ok(r) => r,
Err(_) => return Err(rpc_error_internal("invalid hole punch")),
};
let receipt = r
.get_receipt()
.map_err(map_error_protocol!(
"invalid receipt in hole punch signal info"
))?
.to_vec();
let receipt_nonce =
decode_nonce(&r.get_receipt_nonce().map_err(map_error_capnp_error!())?);
let pi_reader = r.get_peer_info().map_err(map_error_protocol!(
"invalid peer info in hole punch signal info"
))?;
let peer_info = decode_peer_info(&pi_reader, true)?;
SignalInfo::HolePunch { receipt, peer_info }
SignalInfo::HolePunch {
receipt_nonce,
peer_info,
}
}
veilid_capnp::operation_signal::ReverseConnect(r) => {
// Extract reverse connect reader
@@ -68,18 +63,17 @@ pub fn decode_signal_info(
Ok(r) => r,
Err(_) => return Err(rpc_error_internal("invalid reverse connect")),
};
let receipt = r
.get_receipt()
.map_err(map_error_protocol!(
"invalid receipt in reverse connect signal info"
))?
.to_vec();
let receipt_nonce =
decode_nonce(&r.get_receipt_nonce().map_err(map_error_capnp_error!())?);
let pi_reader = r.get_peer_info().map_err(map_error_protocol!(
"invalid peer info in reverse connect signal info"
))?;
let peer_info = decode_peer_info(&pi_reader, true)?;
SignalInfo::ReverseConnect { receipt, peer_info }
SignalInfo::ReverseConnect {
receipt_nonce,
peer_info,
}
}
},
)

View File

@@ -872,7 +872,7 @@ impl RPCProcessor {
rpcreader: RPCMessageReader,
) -> Result<(), RPCError> {
//
let (alternate_port, redirect, dial_info, rcpt_data) = {
let (redirect, dial_info, receipt_nonce, min_version, max_version) = {
let operation = rpcreader
.reader
.get_root::<veilid_capnp::operation::Reader>()
@@ -893,18 +893,20 @@ impl RPCProcessor {
};
// Parse out fields
let alternate_port = vdi_reader.get_alternate_port();
let min_version = vdi_reader.get_min_version();
let max_version = vdi_reader.get_max_version();
let redirect = vdi_reader.get_redirect();
let dial_info = decode_dial_info(
&vdi_reader
.get_dial_info()
.map_err(map_error_internal!("no valid dial info"))?,
)?;
let rcpt_data = vdi_reader
.get_receipt()
.map_err(map_error_internal!("no valid receipt"))?;
let rn_reader = vdi_reader
.get_receipt_nonce()
.map_err(map_error_internal!("no valid receipt nonce"))?;
let receipt_nonce = decode_nonce(&rn_reader);
(alternate_port, redirect, dial_info, rcpt_data)
(redirect, dial_info, receipt_nonce, min_version, max_version)
};
// Redirect this request if we are asked to
@@ -946,18 +948,13 @@ impl RPCProcessor {
respond_to.set_none(());
let detail = question.reborrow().init_detail();
let mut vdi_builder = detail.init_validate_dial_info();
vdi_builder.set_alternate_port(alternate_port);
vdi_builder.set_redirect(false);
vdi_builder.set_min_version(min_version);
vdi_builder.set_max_version(max_version);
let mut di_builder = vdi_builder.reborrow().init_dial_info();
encode_dial_info(&dial_info, &mut di_builder)?;
let r_builder = vdi_builder.reborrow().init_receipt(
rcpt_data
.len()
.try_into()
.map_err(map_error_internal!("receipt too large"))?,
);
r_builder.copy_from_slice(rcpt_data);
let mut rn_builder = vdi_builder.reborrow().init_receipt_nonce();
encode_nonce(&receipt_nonce, &mut rn_builder);
vdi_msg.into_reader()
};
@@ -970,13 +967,25 @@ impl RPCProcessor {
// Otherwise send a return receipt directly
// Possibly from an alternate port
let version = {
#[allow(clippy::absurd_extreme_comparisons)]
if min_version > MAX_VERSION || max_version < MIN_VERSION {
return Err(rpc_error_protocol(format!(
"can't send direct receipt to {} because version is unsupported: ({},{})",
dial_info, min_version, max_version
)))
.map_err(
logthru_rpc!(debug));
}
cmp::min(max_version, MAX_VERSION)
};
let network_manager = self.network_manager();
network_manager
.send_direct_receipt(dial_info.clone(), rcpt_data, alternate_port)
.send_out_of_band_receipt(dial_info.clone(), version, receipt_nonce, [])
.await
.map_err(map_error_string!())
.map_err(
logthru_net!(error "failed to send direct receipt to dial info: {}, alternate_port={}", dial_info, alternate_port),
logthru_net!(error "failed to send direct receipt to dial info: {}, version={}", dial_info, version),
)?;
Ok(())
@@ -1157,7 +1166,7 @@ impl RPCProcessor {
}
async fn process_return_receipt(&self, rpcreader: RPCMessageReader) -> Result<(), RPCError> {
let rcpt_data = {
let (receipt_nonce, extra_data) = {
let operation = rpcreader
.reader
.get_root::<veilid_capnp::operation::Reader>()
@@ -1177,18 +1186,24 @@ impl RPCProcessor {
_ => panic!("invalid operation type in process_return_receipt"),
};
// Get receipt data
let rcpt_data = rr_reader
.get_receipt()
.map_err(map_error_internal!("no valid receipt"))?;
// Get receipt nonce
let rn_reader = rr_reader
.get_receipt_nonce()
.map_err(map_error_internal!("no valid receipt_nonce"))?;
let receipt_nonce = decode_nonce(&rn_reader);
rcpt_data.to_vec()
// Get receipt extra data
let extra_data = rr_reader
.get_extra_data()
.map_err(map_error_internal!("no valid extra data"))?;
(receipt_nonce, extra_data.to_vec())
};
// Handle it
let network_manager = self.network_manager();
network_manager
.handle_in_band_receipt(rcpt_data, rpcreader.header.peer_noderef)
.handle_in_band_receipt(receipt_nonce, extra_data, rpcreader.header.peer_noderef)
.await
.map_err(map_error_string!())
}
@@ -1567,7 +1582,6 @@ impl RPCProcessor {
peer: NodeRef,
dial_info: DialInfo,
redirect: bool,
alternate_port: bool,
) -> Result<bool, RPCError> {
let network_manager = self.network_manager();
let receipt_time = ms_to_us(
@@ -1588,21 +1602,18 @@ impl RPCProcessor {
let mut vdi_builder = detail.init_validate_dial_info();
// Generate receipt and waitable eventual so we can see if we get the receipt back
let (rcpt_data, eventual_value) = network_manager
.generate_single_shot_receipt(receipt_time, [])
let (receipt_nonce, eventual_value) = network_manager
.generate_single_shot_receipt(receipt_time)
.map_err(map_error_string!())?;
vdi_builder.set_redirect(redirect);
vdi_builder.set_alternate_port(alternate_port);
vdi_builder.set_min_version(MIN_VERSION);
vdi_builder.set_max_version(MAX_VERSION);
let mut di_builder = vdi_builder.reborrow().init_dial_info();
encode_dial_info(&dial_info, &mut di_builder)?;
let r_builder = vdi_builder.reborrow().init_receipt(
rcpt_data
.len()
.try_into()
.map_err(map_error_internal!("receipt too large"))?,
);
r_builder.copy_from_slice(rcpt_data.as_slice());
let mut rn_builder = vdi_builder.reborrow().init_receipt_nonce();
encode_nonce(&receipt_nonce, &mut rn_builder);
(vdi_msg.into_reader(), eventual_value)
};
@@ -1614,7 +1625,15 @@ impl RPCProcessor {
log_net!(debug "waiting for validate_dial_info receipt");
// Wait for receipt
match eventual_value.await.take_value().unwrap() {
ReceiptEvent::Returned(_) => {
ReceiptEvent::ReturnedInBand {
inbound_noderef: _,
extra_data:_
} => {
Err(rpc_error_internal("validate_dial_info receipt should be returned out-of-band"))
}
ReceiptEvent::ReturnedOutOfBand {
extra_data:_
} => {
log_net!(debug "validate_dial_info receipt returned");
Ok(true)
}
@@ -1764,12 +1783,10 @@ impl RPCProcessor {
&self,
dest: Destination,
safety_route: Option<&SafetyRouteSpec>,
rcpt_data: B,
) -> Result<(), RPCError> {
// Validate receipt before we send it, otherwise this may be arbitrary data!
let _ = Receipt::from_signed_data(rcpt_data.as_ref())
.map_err(|_| "failed to validate direct receipt".to_owned())
.map_err(map_error_string!())?;
receipt_nonce: Nonce,
extra_data: B,
) -> Result<(), RPCError> {
let extra_data = extra_data.as_ref();
let rr_msg = {
let mut rr_msg = ::capnp::message::Builder::new_default();
@@ -1778,12 +1795,13 @@ impl RPCProcessor {
let mut respond_to = question.reborrow().init_respond_to();
respond_to.set_none(());
let detail = question.reborrow().init_detail();
let rr_builder = detail.init_return_receipt();
let r_builder = rr_builder.init_receipt(rcpt_data.as_ref().len().try_into().map_err(
map_error_protocol!("invalid receipt length in return receipt"),
let mut rr_builder = detail.init_return_receipt();
let mut rn_builder = rr_builder.reborrow().init_receipt_nonce();
encode_nonce(&receipt_nonce, &mut rn_builder);
let ed_builder = rr_builder.init_extra_data(extra_data.len().try_into().map_err(
map_error_protocol!("invalid extra data length in return receipt"),
)?);
r_builder.copy_from_slice(rcpt_data.as_ref());
ed_builder.copy_from_slice(extra_data);
rr_msg.into_reader()
};