mirror of
https://github.com/Cuprate/cuprate.git
synced 2024-12-22 19:49:28 +00:00
net: fix network address parsing
This commit is contained in:
parent
83b59c557c
commit
ec4fe9b79d
9 changed files with 58 additions and 29 deletions
|
@ -33,7 +33,9 @@ impl<T: Containerable + EpeeValue> EpeeValue for ContainerAsBlob<T> {
|
||||||
fn read<B: Buf>(r: &mut B, marker: &Marker) -> Result<Self> {
|
fn read<B: Buf>(r: &mut B, marker: &Marker) -> Result<Self> {
|
||||||
let bytes = Bytes::read(r, marker)?;
|
let bytes = Bytes::read(r, marker)?;
|
||||||
if bytes.len() % T::SIZE != 0 {
|
if bytes.len() % T::SIZE != 0 {
|
||||||
return Err(Error::Value("Can't convert blob container to Vec type."));
|
return Err(Error::Value(
|
||||||
|
"Can't convert blob container to Vec type.".to_string(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ContainerAsBlob(
|
Ok(ContainerAsBlob(
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub enum Error {
|
||||||
#[cfg_attr(feature = "std", error("Format error: {0}"))]
|
#[cfg_attr(feature = "std", error("Format error: {0}"))]
|
||||||
Format(&'static str),
|
Format(&'static str),
|
||||||
#[cfg_attr(feature = "std", error("Value error: {0}"))]
|
#[cfg_attr(feature = "std", error("Value error: {0}"))]
|
||||||
Value(&'static str),
|
Value(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error {
|
impl Error {
|
||||||
|
@ -22,7 +22,7 @@ impl Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn field_data(&self) -> &'static str {
|
fn field_data(&self) -> &str {
|
||||||
match self {
|
match self {
|
||||||
Error::IO(data) => data,
|
Error::IO(data) => data,
|
||||||
Error::Format(data) => data,
|
Error::Format(data) => data,
|
||||||
|
@ -41,12 +41,12 @@ impl Debug for Error {
|
||||||
|
|
||||||
impl From<TryFromIntError> for Error {
|
impl From<TryFromIntError> for Error {
|
||||||
fn from(_: TryFromIntError) -> Self {
|
fn from(_: TryFromIntError) -> Self {
|
||||||
Error::Value("Int is too large")
|
Error::Value("Int is too large".to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Utf8Error> for Error {
|
impl From<Utf8Error> for Error {
|
||||||
fn from(_: Utf8Error) -> Self {
|
fn from(_: Utf8Error) -> Self {
|
||||||
Error::Value("Invalid utf8 str")
|
Error::Value("Invalid utf8 str".to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
//!
|
//!
|
||||||
//!
|
//!
|
||||||
//! let data = [1, 17, 1, 1, 1, 1, 2, 1, 1, 4, 3, 118, 97, 108, 5, 4, 0, 0, 0, 0, 0, 0, 0]; // the data to decode;
|
//! let data = [1, 17, 1, 1, 1, 1, 2, 1, 1, 4, 3, 118, 97, 108, 5, 4, 0, 0, 0, 0, 0, 0, 0]; // the data to decode;
|
||||||
//! let val: Test = from_bytes(&mut &data).unwrap();
|
//! let val: Test = from_bytes(&mut data.as_slice()).unwrap();
|
||||||
//! let data = to_bytes(val).unwrap();
|
//! let data = to_bytes(val).unwrap();
|
||||||
//!
|
//!
|
||||||
//!
|
//!
|
||||||
|
@ -79,7 +79,7 @@
|
||||||
//!
|
//!
|
||||||
//!
|
//!
|
||||||
//! let data = [1, 17, 1, 1, 1, 1, 2, 1, 1, 4, 3, 118, 97, 108, 5, 4, 0, 0, 0, 0, 0, 0, 0]; // the data to decode;
|
//! let data = [1, 17, 1, 1, 1, 1, 2, 1, 1, 4, 3, 118, 97, 108, 5, 4, 0, 0, 0, 0, 0, 0, 0]; // the data to decode;
|
||||||
//! let val: Test2 = from_bytes(&mut &data).unwrap();
|
//! let val: Test2 = from_bytes(&mut data.as_slice()).unwrap();
|
||||||
//! let data = to_bytes(val).unwrap();
|
//! let data = to_bytes(val).unwrap();
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
|
@ -279,7 +279,7 @@ fn skip_epee_value<B: Buf>(r: &mut B, skipped_objects: &mut u8) -> Result<()> {
|
||||||
if let Some(size) = marker.inner_marker.size() {
|
if let Some(size) = marker.inner_marker.size() {
|
||||||
let bytes_to_skip = size
|
let bytes_to_skip = size
|
||||||
.checked_mul(len.try_into()?)
|
.checked_mul(len.try_into()?)
|
||||||
.ok_or(Error::Value("List is too big"))?;
|
.ok_or(Error::Value("List is too big".to_string()))?;
|
||||||
return advance(bytes_to_skip, r);
|
return advance(bytes_to_skip, r);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ macro_rules! epee_object {
|
||||||
if core::mem::replace(&mut self.$field, Some(
|
if core::mem::replace(&mut self.$field, Some(
|
||||||
epee_encoding::try_right_then_left!(epee_encoding::read_epee_value(b)?, $($read_fn(b)?)?)
|
epee_encoding::try_right_then_left!(epee_encoding::read_epee_value(b)?, $($read_fn(b)?)?)
|
||||||
)).is_some() {
|
)).is_some() {
|
||||||
Err(epee_encoding::error::Error::Value("Duplicate field in data"))?;
|
Err(epee_encoding::error::Error::Value(format!("Duplicate field in data: {}", epee_encoding::field_name!($field, $($alt_name)?))))?;
|
||||||
}
|
}
|
||||||
Ok(true)
|
Ok(true)
|
||||||
},)+
|
},)+
|
||||||
|
@ -87,7 +87,7 @@ macro_rules! epee_object {
|
||||||
$(.or(Some($default)))?
|
$(.or(Some($default)))?
|
||||||
.or(epee_default_value)
|
.or(epee_default_value)
|
||||||
$(.map(<$ty_as>::into))?
|
$(.map(<$ty_as>::into))?
|
||||||
.ok_or(epee_encoding::error::Error::Value("Missing field in data"))?
|
.ok_or(epee_encoding::error::Error::Value(format!("Missing field in data: {}", epee_encoding::field_name!($field, $($alt_name)?))))?
|
||||||
},
|
},
|
||||||
)+
|
)+
|
||||||
|
|
||||||
|
|
|
@ -189,6 +189,14 @@ impl EpeeValue for Vec<u8> {
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn epee_default_value() -> Option<Self> {
|
||||||
|
Some(Vec::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn should_write(&self) -> bool {
|
||||||
|
!self.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
|
fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
|
||||||
write_varint(self.len().try_into()?, w)?;
|
write_varint(self.len().try_into()?, w)?;
|
||||||
|
|
||||||
|
@ -222,6 +230,14 @@ impl EpeeValue for Bytes {
|
||||||
Ok(r.copy_to_bytes(len.try_into()?))
|
Ok(r.copy_to_bytes(len.try_into()?))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn epee_default_value() -> Option<Self> {
|
||||||
|
Some(Bytes::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn should_write(&self) -> bool {
|
||||||
|
!self.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
|
fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
|
||||||
write_varint(self.len().try_into()?, w)?;
|
write_varint(self.len().try_into()?, w)?;
|
||||||
|
|
||||||
|
@ -258,6 +274,14 @@ impl EpeeValue for BytesMut {
|
||||||
Ok(bytes)
|
Ok(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn epee_default_value() -> Option<Self> {
|
||||||
|
Some(BytesMut::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn should_write(&self) -> bool {
|
||||||
|
!self.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
|
fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
|
||||||
write_varint(self.len().try_into()?, w)?;
|
write_varint(self.len().try_into()?, w)?;
|
||||||
|
|
||||||
|
@ -287,7 +311,7 @@ impl<const N: usize> EpeeValue for ByteArrayVec<N> {
|
||||||
if r.remaining()
|
if r.remaining()
|
||||||
< usize::try_from(len)?
|
< usize::try_from(len)?
|
||||||
.checked_mul(N)
|
.checked_mul(N)
|
||||||
.ok_or(Error::Value("Length of field is too long"))?
|
.ok_or(Error::Value("Length of field is too long".to_string()))?
|
||||||
{
|
{
|
||||||
return Err(Error::IO("Not enough bytes to fill object"));
|
return Err(Error::IO("Not enough bytes to fill object"));
|
||||||
}
|
}
|
||||||
|
@ -296,6 +320,14 @@ impl<const N: usize> EpeeValue for ByteArrayVec<N> {
|
||||||
.map_err(|_| Error::Format("Field has invalid length"))
|
.map_err(|_| Error::Format("Field has invalid length"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn epee_default_value() -> Option<Self> {
|
||||||
|
Some(ByteArrayVec::try_from(Bytes::new()).unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn should_write(&self) -> bool {
|
||||||
|
!self.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
|
fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
|
||||||
let bytes = self.take_bytes();
|
let bytes = self.take_bytes();
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
//! I2p. Currently this module only has IPv(4/6).
|
//! I2p. Currently this module only has IPv(4/6).
|
||||||
//!
|
//!
|
||||||
use bytes::BufMut;
|
use bytes::BufMut;
|
||||||
use epee_encoding::{EpeeObject, EpeeValue};
|
use epee_encoding::EpeeObject;
|
||||||
use std::{hash::Hash, net, net::SocketAddr};
|
use std::{hash::Hash, net, net::SocketAddr};
|
||||||
|
|
||||||
mod serde_helper;
|
mod serde_helper;
|
||||||
|
@ -46,7 +46,7 @@ impl EpeeObject for NetworkAddress {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_fields<B: BufMut>(self, w: &mut B) -> epee_encoding::Result<()> {
|
fn write_fields<B: BufMut>(self, w: &mut B) -> epee_encoding::Result<()> {
|
||||||
TaggedNetworkAddress::from(self).write(w)
|
TaggedNetworkAddress::from(self).write_fields(w)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ pub struct TaggedNetworkAddress {
|
||||||
|
|
||||||
epee_object!(
|
epee_object!(
|
||||||
TaggedNetworkAddress,
|
TaggedNetworkAddress,
|
||||||
ty: Option<u8>,
|
ty("type"): Option<u8>,
|
||||||
addr: Option<AllFieldsNetworkAddress>,
|
addr: Option<AllFieldsNetworkAddress>,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -27,21 +27,21 @@ impl EpeeObjectBuilder<NetworkAddress> for TaggedNetworkAddress {
|
||||||
{
|
{
|
||||||
return Err(epee_encoding::Error::Format("Duplicate field in data."));
|
return Err(epee_encoding::Error::Format("Duplicate field in data."));
|
||||||
}
|
}
|
||||||
|
Ok(true)
|
||||||
}
|
}
|
||||||
"addr" => {
|
"addr" => {
|
||||||
if std::mem::replace(&mut self.addr, epee_encoding::read_epee_value(b)?).is_some() {
|
if std::mem::replace(&mut self.addr, epee_encoding::read_epee_value(b)?).is_some() {
|
||||||
return Err(epee_encoding::Error::Format("Duplicate field in data."));
|
return Err(epee_encoding::Error::Format("Duplicate field in data."));
|
||||||
}
|
}
|
||||||
|
Ok(true)
|
||||||
}
|
}
|
||||||
_ => return Ok(false),
|
_ => Ok(false),
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finish(self) -> epee_encoding::Result<NetworkAddress> {
|
fn finish(self) -> epee_encoding::Result<NetworkAddress> {
|
||||||
self.try_into()
|
self.try_into()
|
||||||
.map_err(|_| epee_encoding::Error::Value("Invalid network address"))
|
.map_err(|_| epee_encoding::Error::Value("Invalid network address".to_string()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ impl From<NetworkAddress> for TaggedNetworkAddress {
|
||||||
addr: Some(AllFieldsNetworkAddress {
|
addr: Some(AllFieldsNetworkAddress {
|
||||||
m_ip: Some(u32::from_be_bytes(addr.ip().octets())),
|
m_ip: Some(u32::from_be_bytes(addr.ip().octets())),
|
||||||
m_port: Some(addr.port()),
|
m_port: Some(addr.port()),
|
||||||
..Default::default()
|
addr: None,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
SocketAddr::V6(addr) => TaggedNetworkAddress {
|
SocketAddr::V6(addr) => TaggedNetworkAddress {
|
||||||
|
@ -78,7 +78,7 @@ impl From<NetworkAddress> for TaggedNetworkAddress {
|
||||||
addr: Some(AllFieldsNetworkAddress {
|
addr: Some(AllFieldsNetworkAddress {
|
||||||
addr: Some(addr.ip().octets()),
|
addr: Some(addr.ip().octets()),
|
||||||
m_port: Some(addr.port()),
|
m_port: Some(addr.port()),
|
||||||
..Default::default()
|
m_ip: None,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -115,7 +115,6 @@ epee_object!(
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use super::{BasicNodeData, CoreSyncData, HandshakeRequest, HandshakeResponse};
|
use super::{BasicNodeData, CoreSyncData, HandshakeRequest, HandshakeResponse};
|
||||||
use crate::p2p::common::PeerSupportFlags;
|
use crate::p2p::common::PeerSupportFlags;
|
||||||
|
|
||||||
|
@ -971,6 +970,7 @@ mod tests {
|
||||||
assert_eq!(250, handshake.local_peerlist_new.len());
|
assert_eq!(250, handshake.local_peerlist_new.len());
|
||||||
|
|
||||||
let mut encoded_bytes = epee_encoding::to_bytes(handshake.clone()).unwrap();
|
let mut encoded_bytes = epee_encoding::to_bytes(handshake.clone()).unwrap();
|
||||||
|
|
||||||
let handshake_2: HandshakeResponse = epee_encoding::from_bytes(&mut encoded_bytes).unwrap();
|
let handshake_2: HandshakeResponse = epee_encoding::from_bytes(&mut encoded_bytes).unwrap();
|
||||||
|
|
||||||
assert_eq!(handshake, handshake_2);
|
assert_eq!(handshake, handshake_2);
|
||||||
|
|
|
@ -171,13 +171,6 @@ epee_object! {
|
||||||
rpc_credits_per_hash: u32 = 0_u32,
|
rpc_credits_per_hash: u32 = 0_u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::hash::Hash for PeerListEntryBase {
|
|
||||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
|
||||||
// We only hash the adr so we can look this up in a HashSet.
|
|
||||||
self.adr.hash(state)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A pruned tx with the hash of the missing prunable data
|
/// A pruned tx with the hash of the missing prunable data
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct PrunedTxBlobEntry {
|
pub struct PrunedTxBlobEntry {
|
||||||
|
@ -256,7 +249,9 @@ fn tx_blob_read<B: Buf>(b: &mut B) -> epee_encoding::Result<TransactionBlobs> {
|
||||||
match marker.inner_marker {
|
match marker.inner_marker {
|
||||||
InnerMarker::Object => Ok(TransactionBlobs::Pruned(Vec::read(b, &marker)?)),
|
InnerMarker::Object => Ok(TransactionBlobs::Pruned(Vec::read(b, &marker)?)),
|
||||||
InnerMarker::String => Ok(TransactionBlobs::Normal(Vec::read(b, &marker)?)),
|
InnerMarker::String => Ok(TransactionBlobs::Normal(Vec::read(b, &marker)?)),
|
||||||
_ => Err(epee_encoding::Error::Value("Invalid marker for tx blobs")),
|
_ => Err(epee_encoding::Error::Value(
|
||||||
|
"Invalid marker for tx blobs".to_string(),
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue