receipt rework and discovery rework
This commit is contained in:
@@ -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,
|
||||
})
|
||||
|
@@ -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,
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@@ -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()
|
||||
};
|
||||
|
Reference in New Issue
Block a user