harden network errors
This commit is contained in:
parent
44cde7a939
commit
0106f682f7
@ -316,7 +316,7 @@ impl Network {
|
|||||||
let h = RawUdpProtocolHandler::new_unspecified_bound_handler(&peer_socket_addr)
|
let h = RawUdpProtocolHandler::new_unspecified_bound_handler(&peer_socket_addr)
|
||||||
.await
|
.await
|
||||||
.wrap_err("create socket failure")?;
|
.wrap_err("create socket failure")?;
|
||||||
network_result_try!(h
|
let _ = network_result_try!(h
|
||||||
.send_message(data, peer_socket_addr)
|
.send_message(data, peer_socket_addr)
|
||||||
.await
|
.await
|
||||||
.map(NetworkResult::Value)
|
.map(NetworkResult::Value)
|
||||||
@ -375,9 +375,10 @@ impl Network {
|
|||||||
let h = RawUdpProtocolHandler::new_unspecified_bound_handler(&peer_socket_addr)
|
let h = RawUdpProtocolHandler::new_unspecified_bound_handler(&peer_socket_addr)
|
||||||
.await
|
.await
|
||||||
.wrap_err("create socket failure")?;
|
.wrap_err("create socket failure")?;
|
||||||
h.send_message(data, peer_socket_addr)
|
network_result_try!(h
|
||||||
|
.send_message(data, peer_socket_addr)
|
||||||
.await
|
.await
|
||||||
.wrap_err("send message failure")?;
|
.wrap_err("send message failure")?);
|
||||||
self.network_manager()
|
self.network_manager()
|
||||||
.stats_packet_sent(dial_info.to_ip_addr(), data_len as u64);
|
.stats_packet_sent(dial_info.to_ip_addr(), data_len as u64);
|
||||||
|
|
||||||
@ -449,10 +450,10 @@ impl Network {
|
|||||||
&peer_socket_addr,
|
&peer_socket_addr,
|
||||||
&descriptor.local().map(|sa| sa.to_socket_addr()),
|
&descriptor.local().map(|sa| sa.to_socket_addr()),
|
||||||
) {
|
) {
|
||||||
ph.clone()
|
network_result_value_or_log!(debug ph.clone()
|
||||||
.send_message(data, peer_socket_addr)
|
.send_message(data.clone(), peer_socket_addr)
|
||||||
.await
|
.await
|
||||||
.wrap_err("sending data to existing conection")?;
|
.wrap_err("sending data to existing conection")? => { return Ok(Some(data)); } );
|
||||||
|
|
||||||
// Network accounting
|
// Network accounting
|
||||||
self.network_manager()
|
self.network_manager()
|
||||||
@ -506,7 +507,7 @@ impl Network {
|
|||||||
Some(ph) => ph,
|
Some(ph) => ph,
|
||||||
None => bail!("no appropriate UDP protocol handler for dial_info"),
|
None => bail!("no appropriate UDP protocol handler for dial_info"),
|
||||||
};
|
};
|
||||||
network_result_try!(ph
|
let _ = network_result_try!(ph
|
||||||
.send_message(data, peer_socket_addr)
|
.send_message(data, peer_socket_addr)
|
||||||
.await
|
.await
|
||||||
.into_network_result()
|
.into_network_result()
|
||||||
@ -532,7 +533,7 @@ impl Network {
|
|||||||
self.network_manager()
|
self.network_manager()
|
||||||
.stats_packet_sent(dial_info.to_ip_addr(), data_len as u64);
|
.stats_packet_sent(dial_info.to_ip_addr(), data_len as u64);
|
||||||
|
|
||||||
Ok(NetworkResult::Value(()))
|
Ok(NetworkResult::value(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
|
@ -14,21 +14,12 @@ impl RawUdpProtocolHandler {
|
|||||||
#[instrument(level = "trace", err, skip(self, data), fields(data.len = data.len(), ret.len, ret.from))]
|
#[instrument(level = "trace", err, skip(self, data), fields(data.len = data.len(), ret.len, ret.from))]
|
||||||
pub async fn recv_message(&self, data: &mut [u8]) -> io::Result<(usize, ConnectionDescriptor)> {
|
pub async fn recv_message(&self, data: &mut [u8]) -> io::Result<(usize, ConnectionDescriptor)> {
|
||||||
let (size, remote_addr) = loop {
|
let (size, remote_addr) = loop {
|
||||||
match self.socket.recv_from(data).await {
|
let (size, remote_addr) = network_result_value_or_log!(debug self.socket.recv_from(data).await.into_network_result()? => continue);
|
||||||
Ok((size, remote_addr)) => {
|
|
||||||
if size > MAX_MESSAGE_SIZE {
|
if size > MAX_MESSAGE_SIZE {
|
||||||
bail_io_error_other!("received too large UDP message");
|
log_net!(debug "{}({}) at {}@{}:{}", "Invalid message".green(), "received too large UDP message", file!(), line!(), column!());
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
break (size, remote_addr);
|
break (size, remote_addr);
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
if e.kind() == io::ErrorKind::ConnectionReset {
|
|
||||||
// Ignore icmp
|
|
||||||
} else {
|
|
||||||
return Err(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let peer_addr = PeerAddress::new(
|
let peer_addr = PeerAddress::new(
|
||||||
@ -47,17 +38,25 @@ impl RawUdpProtocolHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "trace", err, skip(self, data), fields(data.len = data.len(), ret.len, ret.from))]
|
#[instrument(level = "trace", err, skip(self, data), fields(data.len = data.len(), ret.len, ret.from))]
|
||||||
pub async fn send_message(&self, data: Vec<u8>, socket_addr: SocketAddr) -> io::Result<()> {
|
pub async fn send_message(
|
||||||
|
&self,
|
||||||
|
data: Vec<u8>,
|
||||||
|
socket_addr: SocketAddr,
|
||||||
|
) -> io::Result<NetworkResult<()>> {
|
||||||
if data.len() > MAX_MESSAGE_SIZE {
|
if data.len() > MAX_MESSAGE_SIZE {
|
||||||
bail_io_error_other!("sending too large UDP message");
|
bail_io_error_other!("sending too large UDP message");
|
||||||
}
|
}
|
||||||
|
|
||||||
let len = self.socket.send_to(&data, socket_addr).await?;
|
let len = network_result_try!(self
|
||||||
|
.socket
|
||||||
|
.send_to(&data, socket_addr)
|
||||||
|
.await
|
||||||
|
.into_network_result()?);
|
||||||
if len != data.len() {
|
if len != data.len() {
|
||||||
bail_io_error_other!("UDP partial send")
|
bail_io_error_other!("UDP partial send")
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(NetworkResult::value(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "trace", err)]
|
#[instrument(level = "trace", err)]
|
||||||
|
@ -38,13 +38,20 @@ impl<T> IoNetworkResultExt<T> for io::Result<T> {
|
|||||||
_ => Err(e),
|
_ => Err(e),
|
||||||
},
|
},
|
||||||
#[cfg(not(feature = "io_error_more"))]
|
#[cfg(not(feature = "io_error_more"))]
|
||||||
Err(e) => match e.kind() {
|
Err(e) => {
|
||||||
|
if let Some(os_err) = e.raw_os_error() {
|
||||||
|
if os_err == libc::EHOSTUNREACH || os_err == libc::ENETUNREACH {
|
||||||
|
return Ok(NetworkResult::NoConnection(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match e.kind() {
|
||||||
io::ErrorKind::TimedOut => Ok(NetworkResult::Timeout),
|
io::ErrorKind::TimedOut => Ok(NetworkResult::Timeout),
|
||||||
io::ErrorKind::ConnectionAborted
|
io::ErrorKind::ConnectionAborted
|
||||||
| io::ErrorKind::ConnectionRefused
|
| io::ErrorKind::ConnectionRefused
|
||||||
| io::ErrorKind::ConnectionReset => Ok(NetworkResult::NoConnection(e)),
|
| io::ErrorKind::ConnectionReset => Ok(NetworkResult::NoConnection(e)),
|
||||||
_ => Err(e),
|
_ => Err(e),
|
||||||
},
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,13 +92,20 @@ impl<T> FoldedNetworkResultExt<T> for io::Result<TimeoutOr<T>> {
|
|||||||
_ => Err(e),
|
_ => Err(e),
|
||||||
},
|
},
|
||||||
#[cfg(not(feature = "io_error_more"))]
|
#[cfg(not(feature = "io_error_more"))]
|
||||||
Err(e) => match e.kind() {
|
Err(e) => {
|
||||||
|
if let Some(os_err) = e.raw_os_error() {
|
||||||
|
if os_err == libc::EHOSTUNREACH || os_err == libc::ENETUNREACH {
|
||||||
|
return Ok(NetworkResult::NoConnection(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match e.kind() {
|
||||||
io::ErrorKind::TimedOut => Ok(NetworkResult::Timeout),
|
io::ErrorKind::TimedOut => Ok(NetworkResult::Timeout),
|
||||||
io::ErrorKind::ConnectionAborted
|
io::ErrorKind::ConnectionAborted
|
||||||
| io::ErrorKind::ConnectionRefused
|
| io::ErrorKind::ConnectionRefused
|
||||||
| io::ErrorKind::ConnectionReset => Ok(NetworkResult::NoConnection(e)),
|
| io::ErrorKind::ConnectionReset => Ok(NetworkResult::NoConnection(e)),
|
||||||
_ => Err(e),
|
_ => Err(e),
|
||||||
},
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,13 +125,20 @@ impl<T> FoldedNetworkResultExt<T> for io::Result<NetworkResult<T>> {
|
|||||||
_ => Err(e),
|
_ => Err(e),
|
||||||
},
|
},
|
||||||
#[cfg(not(feature = "io_error_more"))]
|
#[cfg(not(feature = "io_error_more"))]
|
||||||
Err(e) => match e.kind() {
|
Err(e) => {
|
||||||
|
if let Some(os_err) = e.raw_os_error() {
|
||||||
|
if os_err == libc::EHOSTUNREACH || os_err == libc::ENETUNREACH {
|
||||||
|
return Ok(NetworkResult::NoConnection(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match e.kind() {
|
||||||
io::ErrorKind::TimedOut => Ok(NetworkResult::Timeout),
|
io::ErrorKind::TimedOut => Ok(NetworkResult::Timeout),
|
||||||
io::ErrorKind::ConnectionAborted
|
io::ErrorKind::ConnectionAborted
|
||||||
| io::ErrorKind::ConnectionRefused
|
| io::ErrorKind::ConnectionRefused
|
||||||
| io::ErrorKind::ConnectionReset => Ok(NetworkResult::NoConnection(e)),
|
| io::ErrorKind::ConnectionReset => Ok(NetworkResult::NoConnection(e)),
|
||||||
_ => Err(e),
|
_ => Err(e),
|
||||||
},
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -270,7 +291,7 @@ macro_rules! network_result_value_or_log {
|
|||||||
$f
|
$f
|
||||||
}
|
}
|
||||||
NetworkResult::InvalidMessage(s) => {
|
NetworkResult::InvalidMessage(s) => {
|
||||||
log_net!($level "{}({}) at {}@{}:{}", "No connection".green(), s, file!(), line!(), column!());
|
log_net!($level "{}({}) at {}@{}:{}", "Invalid message".green(), s, file!(), line!(), column!());
|
||||||
$f
|
$f
|
||||||
}
|
}
|
||||||
NetworkResult::Value(v) => v,
|
NetworkResult::Value(v) => v,
|
||||||
|
Loading…
Reference in New Issue
Block a user