networkresult
This commit is contained in:
@@ -526,30 +526,38 @@ impl NetworkManager {
|
||||
}
|
||||
|
||||
// Process a received out-of-band receipt
|
||||
#[instrument(level = "trace", skip(self, receipt_data), err)]
|
||||
#[instrument(level = "trace", skip(self, receipt_data), ret)]
|
||||
pub async fn handle_out_of_band_receipt<R: AsRef<[u8]>>(
|
||||
&self,
|
||||
receipt_data: R,
|
||||
) -> EyreResult<()> {
|
||||
) -> NetworkResult<()> {
|
||||
let receipt_manager = self.receipt_manager();
|
||||
|
||||
let receipt = Receipt::from_signed_data(receipt_data.as_ref())
|
||||
.wrap_err("failed to parse signed out-of-band receipt")?;
|
||||
let receipt = match Receipt::from_signed_data(receipt_data.as_ref()) {
|
||||
Err(e) => {
|
||||
return NetworkResult::invalid_message(e.to_string());
|
||||
}
|
||||
Ok(v) => v,
|
||||
};
|
||||
|
||||
receipt_manager.handle_receipt(receipt, None).await
|
||||
}
|
||||
|
||||
// Process a received in-band receipt
|
||||
#[instrument(level = "trace", skip(self, receipt_data), err)]
|
||||
#[instrument(level = "trace", skip(self, receipt_data), ret)]
|
||||
pub async fn handle_in_band_receipt<R: AsRef<[u8]>>(
|
||||
&self,
|
||||
receipt_data: R,
|
||||
inbound_nr: NodeRef,
|
||||
) -> EyreResult<()> {
|
||||
) -> NetworkResult<()> {
|
||||
let receipt_manager = self.receipt_manager();
|
||||
|
||||
let receipt = Receipt::from_signed_data(receipt_data.as_ref())
|
||||
.wrap_err("failed to parse signed in-band receipt")?;
|
||||
let receipt = match Receipt::from_signed_data(receipt_data.as_ref()) {
|
||||
Err(e) => {
|
||||
return NetworkResult::invalid_message(e.to_string());
|
||||
}
|
||||
Ok(v) => v,
|
||||
};
|
||||
|
||||
receipt_manager
|
||||
.handle_receipt(receipt, Some(inbound_nr))
|
||||
@@ -558,32 +566,51 @@ impl NetworkManager {
|
||||
|
||||
// Process a received signal
|
||||
#[instrument(level = "trace", skip(self), err)]
|
||||
pub async fn handle_signal(&self, signal_info: SignalInfo) -> EyreResult<()> {
|
||||
pub async fn handle_signal(
|
||||
&self,
|
||||
_sender_id: DHTKey,
|
||||
signal_info: SignalInfo,
|
||||
) -> EyreResult<NetworkResult<()>> {
|
||||
match signal_info {
|
||||
SignalInfo::ReverseConnect { receipt, peer_info } => {
|
||||
let routing_table = self.routing_table();
|
||||
let rpc = self.rpc_processor();
|
||||
|
||||
// Add the peer info to our routing table
|
||||
let peer_nr = routing_table.register_node_with_signed_node_info(
|
||||
let peer_nr = match routing_table.register_node_with_signed_node_info(
|
||||
peer_info.node_id.key,
|
||||
peer_info.signed_node_info,
|
||||
)?;
|
||||
) {
|
||||
None => {
|
||||
return Ok(NetworkResult::invalid_message(
|
||||
"unable to register reverse connect peerinfo",
|
||||
))
|
||||
}
|
||||
Some(nr) => nr,
|
||||
};
|
||||
|
||||
// Make a reverse connection to the peer and send the receipt to it
|
||||
rpc.rpc_call_return_receipt(Destination::Direct(peer_nr), None, receipt)
|
||||
.await
|
||||
.wrap_err("rpc failure")?;
|
||||
.wrap_err("rpc failure")
|
||||
}
|
||||
SignalInfo::HolePunch { receipt, peer_info } => {
|
||||
let routing_table = self.routing_table();
|
||||
let rpc = self.rpc_processor();
|
||||
|
||||
// Add the peer info to our routing table
|
||||
let mut peer_nr = routing_table.register_node_with_signed_node_info(
|
||||
let mut peer_nr = match routing_table.register_node_with_signed_node_info(
|
||||
peer_info.node_id.key,
|
||||
peer_info.signed_node_info,
|
||||
)?;
|
||||
) {
|
||||
None => {
|
||||
return Ok(NetworkResult::invalid_message(
|
||||
//sender_id,
|
||||
"unable to register hole punch connect peerinfo",
|
||||
));
|
||||
}
|
||||
Some(nr) => nr,
|
||||
};
|
||||
|
||||
// Get the udp direct dialinfo for the hole punch
|
||||
peer_nr.filter_protocols(ProtocolSet::only(ProtocolType::UDP));
|
||||
@@ -599,23 +626,23 @@ impl NetworkManager {
|
||||
|
||||
// Do our half of the hole punch by sending an empty packet
|
||||
// Both sides will do this and then the receipt will get sent over the punched hole
|
||||
self.net()
|
||||
.send_data_to_dial_info(
|
||||
hole_punch_dial_info_detail.dial_info.clone(),
|
||||
Vec::new(),
|
||||
)
|
||||
.await?;
|
||||
network_result_try!(
|
||||
self.net()
|
||||
.send_data_to_dial_info(
|
||||
hole_punch_dial_info_detail.dial_info.clone(),
|
||||
Vec::new(),
|
||||
)
|
||||
.await?
|
||||
);
|
||||
|
||||
// XXX: do we need a delay here? or another hole punch packet?
|
||||
|
||||
// Return the receipt using the same dial info send the receipt to it
|
||||
rpc.rpc_call_return_receipt(Destination::Direct(peer_nr), None, receipt)
|
||||
.await
|
||||
.wrap_err("rpc failure")?;
|
||||
.wrap_err("rpc failure")
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Builds an envelope for sending over the network
|
||||
@@ -652,7 +679,7 @@ impl NetworkManager {
|
||||
node_ref: NodeRef,
|
||||
envelope_node_id: Option<DHTKey>,
|
||||
body: B,
|
||||
) -> EyreResult<SendDataKind> {
|
||||
) -> EyreResult<NetworkResult<SendDataKind>> {
|
||||
let via_node_id = node_ref.node_id();
|
||||
let envelope_node_id = envelope_node_id.unwrap_or(via_node_id);
|
||||
|
||||
@@ -684,18 +711,17 @@ impl NetworkManager {
|
||||
};
|
||||
|
||||
// Build the envelope to send
|
||||
let out = self
|
||||
.build_envelope(envelope_node_id, version, body)
|
||||
.map_err(logthru_rpc!(error))?;
|
||||
let out = self.build_envelope(envelope_node_id, version, body)?;
|
||||
|
||||
// Send the envelope via whatever means necessary
|
||||
let send_data_kind = self.send_data(node_ref.clone(), out).await?;
|
||||
let send_data_kind = network_result_try!(self.send_data(node_ref.clone(), out).await?);
|
||||
|
||||
// If we asked to relay from the start, then this is always indirect
|
||||
if envelope_node_id != via_node_id {
|
||||
return Ok(SendDataKind::GlobalIndirect);
|
||||
}
|
||||
Ok(send_data_kind)
|
||||
Ok(NetworkResult::value(if envelope_node_id != via_node_id {
|
||||
SendDataKind::GlobalIndirect
|
||||
} else {
|
||||
send_data_kind
|
||||
}))
|
||||
}
|
||||
|
||||
// Called by the RPC handler when we want to issue an direct receipt
|
||||
@@ -712,19 +738,13 @@ impl NetworkManager {
|
||||
// should not be subject to our ability to decode it
|
||||
|
||||
// Send receipt directly
|
||||
match self
|
||||
network_result_value_or_log!(debug self
|
||||
.net()
|
||||
.send_data_unbound_to_dial_info(dial_info, rcpt_data)
|
||||
.await?
|
||||
{
|
||||
NetworkResult::Timeout => {
|
||||
log_net!(debug "Timeout sending out of band receipt");
|
||||
.await? => {
|
||||
return Ok(());
|
||||
}
|
||||
NetworkResult::NoConnection(e) => {
|
||||
log_net!(debug "No connection sending out of band receipt: {}", e);
|
||||
}
|
||||
NetworkResult::Value(()) => {}
|
||||
};
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -851,7 +871,7 @@ impl NetworkManager {
|
||||
relay_nr: NodeRef,
|
||||
target_nr: NodeRef,
|
||||
data: Vec<u8>,
|
||||
) -> EyreResult<()> {
|
||||
) -> EyreResult<NetworkResult<()>> {
|
||||
// Build a return receipt for the signal
|
||||
let receipt_timeout =
|
||||
ms_to_us(self.config.get().network.reverse_connection_receipt_time_ms);
|
||||
@@ -862,13 +882,15 @@ impl NetworkManager {
|
||||
|
||||
// Issue the signal
|
||||
let rpc = self.rpc_processor();
|
||||
rpc.rpc_call_signal(
|
||||
Destination::Relay(relay_nr.clone(), target_nr.node_id()),
|
||||
None,
|
||||
SignalInfo::ReverseConnect { receipt, peer_info },
|
||||
)
|
||||
.await
|
||||
.wrap_err("failed to send signal")?;
|
||||
network_result_try!(rpc
|
||||
.rpc_call_signal(
|
||||
Destination::Relay(relay_nr.clone(), target_nr.node_id()),
|
||||
None,
|
||||
SignalInfo::ReverseConnect { receipt, peer_info },
|
||||
)
|
||||
.await
|
||||
.wrap_err("failed to send signal")?);
|
||||
|
||||
// Wait for the return receipt
|
||||
let inbound_nr = match eventual_value.await.take_value().unwrap() {
|
||||
ReceiptEvent::ReturnedOutOfBand => {
|
||||
@@ -876,7 +898,8 @@ impl NetworkManager {
|
||||
}
|
||||
ReceiptEvent::ReturnedInBand { inbound_noderef } => inbound_noderef,
|
||||
ReceiptEvent::Expired => {
|
||||
bail!("reverse connect receipt expired from {:?}", target_nr);
|
||||
//bail!("reverse connect receipt expired from {:?}", target_nr);
|
||||
return Ok(NetworkResult::timeout());
|
||||
}
|
||||
ReceiptEvent::Cancelled => {
|
||||
bail!("reverse connect receipt cancelled from {:?}", target_nr);
|
||||
@@ -896,8 +919,10 @@ impl NetworkManager {
|
||||
.send_data_to_existing_connection(descriptor, data)
|
||||
.await?
|
||||
{
|
||||
None => Ok(()),
|
||||
Some(_) => bail!("unable to send over reverse connection"),
|
||||
None => Ok(NetworkResult::value(())),
|
||||
Some(_) => Ok(NetworkResult::no_connection_other(
|
||||
"unable to send over reverse connection",
|
||||
)),
|
||||
}
|
||||
} else {
|
||||
bail!("no reverse connection available")
|
||||
@@ -912,7 +937,7 @@ impl NetworkManager {
|
||||
relay_nr: NodeRef,
|
||||
target_nr: NodeRef,
|
||||
data: Vec<u8>,
|
||||
) -> EyreResult<()> {
|
||||
) -> EyreResult<NetworkResult<()>> {
|
||||
// Ensure we are filtered down to UDP (the only hole punch protocol supported today)
|
||||
assert!(target_nr
|
||||
.filter_ref()
|
||||
@@ -932,19 +957,22 @@ impl NetworkManager {
|
||||
|
||||
// Do our half of the hole punch by sending an empty packet
|
||||
// Both sides will do this and then the receipt will get sent over the punched hole
|
||||
self.net()
|
||||
.send_data_to_dial_info(hole_punch_did.dial_info, Vec::new())
|
||||
.await?;
|
||||
network_result_try!(
|
||||
self.net()
|
||||
.send_data_to_dial_info(hole_punch_did.dial_info, Vec::new())
|
||||
.await?
|
||||
);
|
||||
|
||||
// Issue the signal
|
||||
let rpc = self.rpc_processor();
|
||||
rpc.rpc_call_signal(
|
||||
Destination::Relay(relay_nr.clone(), target_nr.node_id()),
|
||||
None,
|
||||
SignalInfo::HolePunch { receipt, peer_info },
|
||||
)
|
||||
.await
|
||||
.wrap_err("failed to send signal")?;
|
||||
network_result_try!(rpc
|
||||
.rpc_call_signal(
|
||||
Destination::Relay(relay_nr.clone(), target_nr.node_id()),
|
||||
None,
|
||||
SignalInfo::HolePunch { receipt, peer_info },
|
||||
)
|
||||
.await
|
||||
.wrap_err("failed to send signal")?);
|
||||
|
||||
// Wait for the return receipt
|
||||
let inbound_nr = match eventual_value.await.take_value().unwrap() {
|
||||
@@ -977,8 +1005,10 @@ impl NetworkManager {
|
||||
.send_data_to_existing_connection(descriptor, data)
|
||||
.await?
|
||||
{
|
||||
None => Ok(()),
|
||||
Some(_) => bail!("unable to send over hole punch"),
|
||||
None => Ok(NetworkResult::value(())),
|
||||
Some(_) => Ok(NetworkResult::no_connection_other(
|
||||
"unable to send over hole punch",
|
||||
)),
|
||||
}
|
||||
} else {
|
||||
bail!("no hole punch available")
|
||||
@@ -998,7 +1028,7 @@ impl NetworkManager {
|
||||
&self,
|
||||
node_ref: NodeRef,
|
||||
data: Vec<u8>,
|
||||
) -> SendPinBoxFuture<EyreResult<SendDataKind>> {
|
||||
) -> SendPinBoxFuture<EyreResult<NetworkResult<SendDataKind>>> {
|
||||
let this = self.clone();
|
||||
Box::pin(async move {
|
||||
// First try to send data to the last socket we've seen this peer on
|
||||
@@ -1010,9 +1040,9 @@ impl NetworkManager {
|
||||
{
|
||||
None => {
|
||||
return Ok(if descriptor.matches_peer_scope(PeerScope::Local) {
|
||||
SendDataKind::LocalDirect
|
||||
NetworkResult::value(SendDataKind::LocalDirect)
|
||||
} else {
|
||||
SendDataKind::GlobalDirect
|
||||
NetworkResult::value(SendDataKind::GlobalDirect)
|
||||
});
|
||||
}
|
||||
Some(d) => d,
|
||||
@@ -1021,13 +1051,17 @@ impl NetworkManager {
|
||||
data
|
||||
};
|
||||
|
||||
log_net!("send_data via dialinfo to {:?}", node_ref);
|
||||
// If we don't have last_connection, try to reach out to the peer via its dial info
|
||||
match this.get_contact_method(node_ref.clone()) {
|
||||
let contact_method = this.get_contact_method(node_ref.clone());
|
||||
log_net!(
|
||||
"send_data via {:?} to dialinfo {:?}",
|
||||
contact_method,
|
||||
node_ref
|
||||
);
|
||||
match contact_method {
|
||||
ContactMethod::OutboundRelay(relay_nr) | ContactMethod::InboundRelay(relay_nr) => {
|
||||
this.send_data(relay_nr, data)
|
||||
.await
|
||||
.map(|_| SendDataKind::GlobalIndirect)
|
||||
network_result_try!(this.send_data(relay_nr, data).await?);
|
||||
Ok(NetworkResult::value(SendDataKind::GlobalIndirect))
|
||||
}
|
||||
ContactMethod::Direct(dial_info) => {
|
||||
let send_data_kind = if dial_info.is_local() {
|
||||
@@ -1035,26 +1069,33 @@ impl NetworkManager {
|
||||
} else {
|
||||
SendDataKind::GlobalDirect
|
||||
};
|
||||
this.net()
|
||||
.send_data_to_dial_info(dial_info, data)
|
||||
.await
|
||||
.map(|_| send_data_kind)
|
||||
network_result_try!(this.net().send_data_to_dial_info(dial_info, data).await?);
|
||||
Ok(NetworkResult::value(send_data_kind))
|
||||
}
|
||||
ContactMethod::SignalReverse(relay_nr, target_node_ref) => this
|
||||
.do_reverse_connect(relay_nr, target_node_ref, data)
|
||||
.await
|
||||
.map(|_| SendDataKind::GlobalDirect),
|
||||
ContactMethod::SignalHolePunch(relay_nr, target_node_ref) => this
|
||||
.do_hole_punch(relay_nr, target_node_ref, data)
|
||||
.await
|
||||
.map(|_| SendDataKind::GlobalDirect),
|
||||
ContactMethod::Unreachable => Err(eyre!("Can't send to this node")),
|
||||
ContactMethod::SignalReverse(relay_nr, target_node_ref) => {
|
||||
network_result_try!(
|
||||
this.do_reverse_connect(relay_nr, target_node_ref, data)
|
||||
.await?
|
||||
);
|
||||
Ok(NetworkResult::value(SendDataKind::GlobalDirect))
|
||||
}
|
||||
ContactMethod::SignalHolePunch(relay_nr, target_node_ref) => {
|
||||
network_result_try!(this.do_hole_punch(relay_nr, target_node_ref, data).await?);
|
||||
Ok(NetworkResult::value(SendDataKind::GlobalDirect))
|
||||
}
|
||||
ContactMethod::Unreachable => Ok(NetworkResult::no_connection_other(
|
||||
"Can't send to this node",
|
||||
)),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Direct bootstrap request handler (separate fallback mechanism from cheaper TXT bootstrap mechanism)
|
||||
async fn handle_boot_request(&self, descriptor: ConnectionDescriptor) -> EyreResult<()> {
|
||||
#[instrument(level = "trace", skip(self), ret, err)]
|
||||
async fn handle_boot_request(
|
||||
&self,
|
||||
descriptor: ConnectionDescriptor,
|
||||
) -> EyreResult<NetworkResult<()>> {
|
||||
let routing_table = self.routing_table();
|
||||
|
||||
// Get a bunch of nodes with the various
|
||||
@@ -1075,9 +1116,11 @@ impl NetworkManager {
|
||||
{
|
||||
None => {
|
||||
// Bootstrap reply was sent
|
||||
Ok(())
|
||||
Ok(NetworkResult::value(()))
|
||||
}
|
||||
Some(_) => Err(eyre!("bootstrap reply could not be sent")),
|
||||
Some(_) => Ok(NetworkResult::no_connection_other(
|
||||
"bootstrap reply could not be sent",
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1109,12 +1152,20 @@ impl NetworkManager {
|
||||
// Called when a packet potentially containing an RPC envelope is received by a low-level
|
||||
// network protocol handler. Processes the envelope, authenticates and decrypts the RPC message
|
||||
// and passes it to the RPC handler
|
||||
#[instrument(level="trace", err, skip(self, data), fields(data.len = data.len()))]
|
||||
async fn on_recv_envelope(
|
||||
&self,
|
||||
data: &[u8],
|
||||
descriptor: ConnectionDescriptor,
|
||||
) -> EyreResult<bool> {
|
||||
let root = span!(
|
||||
parent: None,
|
||||
Level::TRACE,
|
||||
"on_recv_envelope",
|
||||
"data.len" = data.len(),
|
||||
"descriptor" = ?descriptor
|
||||
);
|
||||
let _root_enter = root.enter();
|
||||
|
||||
log_net!(
|
||||
"envelope of {} bytes received from {:?}",
|
||||
data.len(),
|
||||
@@ -1133,18 +1184,19 @@ impl NetworkManager {
|
||||
|
||||
// Ensure we can read the magic number
|
||||
if data.len() < 4 {
|
||||
bail!("short packet");
|
||||
log_net!(debug "short packet".green());
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
// Is this a direct bootstrap request instead of an envelope?
|
||||
if data[0..4] == *BOOT_MAGIC {
|
||||
self.handle_boot_request(descriptor).await?;
|
||||
network_result_value_or_log!(debug self.handle_boot_request(descriptor).await? => {});
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
// Is this an out-of-band receipt instead of an envelope?
|
||||
if data[0..4] == *RECEIPT_MAGIC {
|
||||
self.handle_out_of_band_receipt(data).await?;
|
||||
network_result_value_or_log!(debug self.handle_out_of_band_receipt(data).await => {});
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
@@ -1198,7 +1250,7 @@ impl NetworkManager {
|
||||
// This is a costly operation, so only outbound-relay permitted
|
||||
// nodes are allowed to do this, for example PWA users
|
||||
|
||||
let relay_nr = if self.check_client_whitelist(sender_id) {
|
||||
let some_relay_nr = if self.check_client_whitelist(sender_id) {
|
||||
// Full relay allowed, do a full resolve_node
|
||||
rpc.resolve_node(recipient_id).await.wrap_err(
|
||||
"failed to resolve recipient node for relay, dropping outbound relayed packet",
|
||||
@@ -1211,18 +1263,19 @@ impl NetworkManager {
|
||||
// We should, because relays are chosen by nodes that have established connectivity and
|
||||
// should be mutually in each others routing tables. The node needing the relay will be
|
||||
// pinging this node regularly to keep itself in the routing table
|
||||
routing_table.lookup_node_ref(recipient_id).ok_or_else(|| {
|
||||
eyre!(
|
||||
"Inbound relay asked for recipient not in routing table: sender_id={:?} recipient={:?}",
|
||||
sender_id, recipient_id
|
||||
)
|
||||
})?
|
||||
routing_table.lookup_node_ref(recipient_id)
|
||||
};
|
||||
|
||||
// Relay the packet to the desired destination
|
||||
self.send_data(relay_nr, data.to_vec())
|
||||
.await
|
||||
.wrap_err("failed to forward envelope")?;
|
||||
if let Some(relay_nr) = some_relay_nr {
|
||||
// Relay the packet to the desired destination
|
||||
log_net!("relaying {} bytes to {}", data.len(), relay_nr);
|
||||
network_result_value_or_log!(debug self.send_data(relay_nr, data.to_vec())
|
||||
.await
|
||||
.wrap_err("failed to forward envelope")? => {
|
||||
return Ok(false);
|
||||
}
|
||||
);
|
||||
}
|
||||
// Inform caller that we dealt with the envelope, but did not process it locally
|
||||
return Ok(false);
|
||||
}
|
||||
@@ -1237,11 +1290,18 @@ impl NetworkManager {
|
||||
.wrap_err("failed to decrypt envelope body")?;
|
||||
|
||||
// Cache the envelope information in the routing table
|
||||
let source_noderef = routing_table.register_node_with_existing_connection(
|
||||
let source_noderef = match routing_table.register_node_with_existing_connection(
|
||||
envelope.get_sender_id(),
|
||||
descriptor,
|
||||
ts,
|
||||
)?;
|
||||
) {
|
||||
None => {
|
||||
// If the node couldn't be registered just skip this envelope,
|
||||
// the error will have already been logged
|
||||
return Ok(false);
|
||||
}
|
||||
Some(v) => v,
|
||||
};
|
||||
source_noderef.operate_mut(|e| e.set_min_max_version(envelope.get_min_max_version()));
|
||||
|
||||
// xxx: deal with spoofing and flooding here?
|
||||
@@ -1305,13 +1365,14 @@ impl NetworkManager {
|
||||
let mut inner = self.inner.lock();
|
||||
|
||||
// Register new outbound relay
|
||||
let nr = routing_table.register_node_with_signed_node_info(
|
||||
if let Some(nr) = routing_table.register_node_with_signed_node_info(
|
||||
outbound_relay_peerinfo.node_id.key,
|
||||
outbound_relay_peerinfo.signed_node_info,
|
||||
)?;
|
||||
info!("Outbound relay node selected: {}", nr);
|
||||
inner.relay_node = Some(nr);
|
||||
node_info_changed = true;
|
||||
) {
|
||||
info!("Outbound relay node selected: {}", nr);
|
||||
inner.relay_node = Some(nr);
|
||||
node_info_changed = true;
|
||||
}
|
||||
}
|
||||
// Otherwise we must need an inbound relay
|
||||
} else {
|
||||
|
@@ -309,10 +309,11 @@ impl Network {
|
||||
let h = RawUdpProtocolHandler::new_unspecified_bound_handler(&peer_socket_addr)
|
||||
.await
|
||||
.wrap_err("create socket failure")?;
|
||||
h.send_message(data, peer_socket_addr)
|
||||
network_result_try!(h
|
||||
.send_message(data, peer_socket_addr)
|
||||
.await
|
||||
.map(NetworkResult::Value)
|
||||
.wrap_err("send message failure")?;
|
||||
.wrap_err("send message failure")?);
|
||||
}
|
||||
ProtocolType::TCP => {
|
||||
let peer_socket_addr = dial_info.to_socket_addr();
|
||||
@@ -323,7 +324,7 @@ impl Network {
|
||||
)
|
||||
.await
|
||||
.wrap_err("connect failure")?);
|
||||
pnc.send(data).await.wrap_err("send failure")?;
|
||||
network_result_try!(pnc.send(data).await.wrap_err("send failure")?);
|
||||
}
|
||||
ProtocolType::WS | ProtocolType::WSS => {
|
||||
let pnc = network_result_try!(WebsocketProtocolHandler::connect(
|
||||
@@ -333,7 +334,7 @@ impl Network {
|
||||
)
|
||||
.await
|
||||
.wrap_err("connect failure")?);
|
||||
pnc.send(data).await.wrap_err("send failure")?;
|
||||
network_result_try!(pnc.send(data).await.wrap_err("send failure")?);
|
||||
}
|
||||
}
|
||||
// Network accounting
|
||||
@@ -408,7 +409,7 @@ impl Network {
|
||||
}
|
||||
});
|
||||
|
||||
pnc.send(data).await.wrap_err("send failure")?;
|
||||
network_result_try!(pnc.send(data).await.wrap_err("send failure")?);
|
||||
self.network_manager()
|
||||
.stats_packet_sent(dial_info.to_ip_addr(), data_len as u64);
|
||||
|
||||
|
@@ -78,18 +78,24 @@ impl DiscoveryContext {
|
||||
#[instrument(level = "trace", skip(self), ret)]
|
||||
async fn request_public_address(&self, node_ref: NodeRef) -> Option<SocketAddress> {
|
||||
let rpc = self.routing_table.rpc_processor();
|
||||
rpc.rpc_call_status(node_ref.clone())
|
||||
.await
|
||||
.map_err(logthru_net!(
|
||||
"failed to get status answer from {:?}",
|
||||
node_ref
|
||||
))
|
||||
.map(|sa| {
|
||||
let ret = sa.answer.socket_address;
|
||||
log_net!("request_public_address: {:?}", ret);
|
||||
ret
|
||||
})
|
||||
.unwrap_or(None)
|
||||
let res = network_result_value_or_log!(debug match rpc.rpc_call_status(node_ref.clone()).await {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
log_net!(error
|
||||
"failed to get status answer from {:?}: {}",
|
||||
node_ref, e
|
||||
);
|
||||
return None;
|
||||
}
|
||||
} => { return None; }
|
||||
);
|
||||
|
||||
log_net!(
|
||||
"request_public_address {:?}: Value({:?})",
|
||||
node_ref,
|
||||
res.answer
|
||||
);
|
||||
res.answer.socket_address
|
||||
}
|
||||
|
||||
// find fast peers with a particular address type, and ask them to tell us what our external address is
|
||||
|
@@ -189,10 +189,10 @@ pub async fn nonblocking_connect(
|
||||
let async_stream = Async::new(std::net::TcpStream::from(socket))?;
|
||||
|
||||
// The stream becomes writable when connected
|
||||
intf::timeout(timeout_ms, async_stream.writable())
|
||||
timeout_or_try!(intf::timeout(timeout_ms, async_stream.writable())
|
||||
.await
|
||||
.into_timeout_or()
|
||||
.into_result()?;
|
||||
.into_result()?);
|
||||
|
||||
// Check low level error
|
||||
let async_stream = match async_stream.get_ref().take_error()? {
|
||||
@@ -203,9 +203,9 @@ pub async fn nonblocking_connect(
|
||||
// Convert back to inner and then return async version
|
||||
cfg_if! {
|
||||
if #[cfg(feature="rt-async-std")] {
|
||||
Ok(TimeoutOr::Value(TcpStream::from(async_stream.into_inner()?)))
|
||||
Ok(TimeoutOr::value(TcpStream::from(async_stream.into_inner()?)))
|
||||
} else if #[cfg(feature="rt-tokio")] {
|
||||
Ok(TimeoutOr::Value(TcpStream::from_std(async_stream.into_inner()?)?))
|
||||
Ok(TimeoutOr::value(TcpStream::from_std(async_stream.into_inner()?)?))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -51,7 +51,7 @@ impl RawTcpNetworkConnection {
|
||||
let len = message.len() as u16;
|
||||
let header = [b'V', b'L', len as u8, (len >> 8) as u8];
|
||||
|
||||
stream.write_all(&header).await.into_network_result()?;
|
||||
network_result_try!(stream.write_all(&header).await.into_network_result()?);
|
||||
stream.write_all(&message).await.into_network_result()
|
||||
}
|
||||
|
||||
@@ -59,21 +59,14 @@ impl RawTcpNetworkConnection {
|
||||
pub async fn send(&self, message: Vec<u8>) -> io::Result<NetworkResult<()>> {
|
||||
let mut stream = self.stream.clone();
|
||||
let out = Self::send_internal(&mut stream, message).await?;
|
||||
tracing::Span::current().record(
|
||||
"network_result",
|
||||
&match &out {
|
||||
NetworkResult::Timeout => "Timeout".to_owned(),
|
||||
NetworkResult::NoConnection(e) => format!("No connection: {}", e),
|
||||
NetworkResult::Value(()) => "Value(())".to_owned(),
|
||||
},
|
||||
);
|
||||
tracing::Span::current().record("network_result", &tracing::field::display(&out));
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
async fn recv_internal(stream: &mut AsyncPeekStream) -> io::Result<NetworkResult<Vec<u8>>> {
|
||||
let mut header = [0u8; 4];
|
||||
|
||||
stream.read_exact(&mut header).await.into_network_result()?;
|
||||
network_result_try!(stream.read_exact(&mut header).await.into_network_result()?);
|
||||
|
||||
if header[0] != b'V' || header[1] != b'L' {
|
||||
bail_io_error_other!("received invalid TCP frame header");
|
||||
@@ -84,7 +77,7 @@ impl RawTcpNetworkConnection {
|
||||
}
|
||||
|
||||
let mut out: Vec<u8> = vec![0u8; len];
|
||||
stream.read_exact(&mut out).await.into_network_result()?;
|
||||
network_result_try!(stream.read_exact(&mut out).await.into_network_result()?);
|
||||
|
||||
Ok(NetworkResult::Value(out))
|
||||
}
|
||||
@@ -93,14 +86,7 @@ impl RawTcpNetworkConnection {
|
||||
pub async fn recv(&self) -> io::Result<NetworkResult<Vec<u8>>> {
|
||||
let mut stream = self.stream.clone();
|
||||
let out = Self::recv_internal(&mut stream).await?;
|
||||
tracing::Span::current().record(
|
||||
"network_result",
|
||||
&match &out {
|
||||
NetworkResult::Timeout => "Timeout".to_owned(),
|
||||
NetworkResult::NoConnection(e) => format!("No connection: {}", e),
|
||||
NetworkResult::Value(v) => format!("Value(len={})", v.len()),
|
||||
},
|
||||
);
|
||||
tracing::Span::current().record("network_result", &tracing::field::display(&out));
|
||||
Ok(out)
|
||||
}
|
||||
}
|
||||
|
@@ -92,14 +92,7 @@ where
|
||||
.await
|
||||
.map_err(to_io)
|
||||
.into_network_result()?;
|
||||
tracing::Span::current().record(
|
||||
"network_result",
|
||||
&match &out {
|
||||
NetworkResult::Timeout => "Timeout".to_owned(),
|
||||
NetworkResult::NoConnection(e) => format!("No connection: {}", e),
|
||||
NetworkResult::Value(()) => "Value(())".to_owned(),
|
||||
},
|
||||
);
|
||||
tracing::Span::current().record("network_result", &tracing::field::display(&out));
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
@@ -132,14 +125,7 @@ where
|
||||
)),
|
||||
};
|
||||
|
||||
tracing::Span::current().record(
|
||||
"network_result",
|
||||
&match &out {
|
||||
NetworkResult::Timeout => "Timeout".to_owned(),
|
||||
NetworkResult::NoConnection(e) => format!("No connection: {}", e),
|
||||
NetworkResult::Value(v) => format!("Value(len={})", v.len()),
|
||||
},
|
||||
);
|
||||
tracing::Span::current().record("network_result", &tracing::field::display(&out));
|
||||
Ok(out)
|
||||
}
|
||||
}
|
||||
|
@@ -283,7 +283,12 @@ impl NetworkConnection {
|
||||
let receiver_fut = Self::recv_internal(&protocol_connection, stats.clone())
|
||||
.then(|res| async {
|
||||
match res {
|
||||
Ok(NetworkResult::Value(message)) => {
|
||||
Ok(v) => {
|
||||
|
||||
let message = network_result_value_or_log!(debug v => {
|
||||
return RecvLoopAction::Finish;
|
||||
});
|
||||
|
||||
// Pass received messages up to the network manager for processing
|
||||
if let Err(e) = network_manager
|
||||
.on_recv_envelope(message.as_slice(), descriptor)
|
||||
@@ -295,16 +300,6 @@ impl NetworkConnection {
|
||||
RecvLoopAction::Recv
|
||||
}
|
||||
}
|
||||
Ok(NetworkResult::Timeout) => {
|
||||
// Connection unable to receive, closed
|
||||
log_net!(debug "Timeout");
|
||||
RecvLoopAction::Finish
|
||||
}
|
||||
Ok(NetworkResult::NoConnection(e)) => {
|
||||
// Connection unable to receive, closed
|
||||
log_net!(debug "No connection: {}", e);
|
||||
RecvLoopAction::Finish
|
||||
}
|
||||
Err(e) => {
|
||||
// Connection unable to receive, closed
|
||||
log_net!(error e);
|
||||
|
Reference in New Issue
Block a user