Skip to content

Commit

Permalink
Comments
Browse files Browse the repository at this point in the history
  • Loading branch information
joerivanruth committed Apr 12, 2024
1 parent 1603c78 commit fbd7031
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 13 deletions.
34 changes: 27 additions & 7 deletions src/addr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,18 @@ use mio::net::SocketAddr as UnixSocketAddr;

use lazy_regex::{regex_captures, regex_is_match};

/// A user can pass a listen- or connect address as a host/port combination, a
/// path or a lone port number.
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
pub enum MonetAddr {
/// A host name that must still be resolved to IP addresses, plus a port
Dns { host: String, port: u16 },
/// A specific IP address, plus a port
Ip { ip: IpAddr, port: u16 },
/// The path of a Unix Domain socket in the file system
Unix(PathBuf),
/// Only a port, may resolve to a combination of ip/port pairs and a Unix
/// Domain socket.
PortOnly(u16),
}

Expand All @@ -46,6 +53,8 @@ impl TryFrom<&OsStr> for MonetAddr {
type Error = io::Error;

fn try_from(os_value: &OsStr) -> Result<Self, io::Error> {
// this nested function does all the work but it returns Option rather
// than Result.
fn parse(os_value: &OsStr) -> Option<MonetAddr> {
// If it contains slashes or backslashes, it must be a path
let bytes = os_value.as_encoded_bytes();
Expand Down Expand Up @@ -89,6 +98,7 @@ impl TryFrom<&OsStr> for MonetAddr {
}
}

// now apply the nested function and handle errors
if let Some(monetaddr) = parse(os_value) {
Ok(monetaddr)
} else {
Expand All @@ -109,13 +119,20 @@ impl TryFrom<OsString> for MonetAddr {
}

impl MonetAddr {
/// Resolve the user-specified address into a Vec of concrete addresses.
///
/// For example, a lone port number might resolve to a Unix Domain socket
/// and a number of ip/port pairs.
pub fn resolve(&self) -> io::Result<Vec<Addr>> {
let mut addrs = self.resolve_unix()?;
let tcp_addrs = self.resolve_tcp()?;
addrs.extend(tcp_addrs);
let mut addrs = self.resolve_tcp()?;
if let Some(unix_addr) = self.resolve_unix()? {
// Prepend
addrs.insert(0, unix_addr);
}
Ok(addrs)
}

/// Resolve the user-specified address into TCP-based [`Addr`]'s
pub fn resolve_tcp(&self) -> io::Result<Vec<Addr>> {
fn gather<T: ToSocketAddrs>(a: T) -> io::Result<Vec<Addr>> {
Ok(a.to_socket_addrs()?.map(Addr::Tcp).collect())
Expand All @@ -129,20 +146,23 @@ impl MonetAddr {
}
}

pub fn resolve_unix(&self) -> io::Result<Vec<Addr>> {
/// Resolve the user-specified address into a Unix Domain TCP-based [`Addr`]
pub fn resolve_unix(&self) -> io::Result<Option<Addr>> {
if cfg!(unix) {
let path = match self {
MonetAddr::Dns { .. } | MonetAddr::Ip { .. } => return Ok(vec![]),
MonetAddr::Dns { .. } | MonetAddr::Ip { .. } => return Ok(None),
MonetAddr::Unix(p) => p.clone(),
MonetAddr::PortOnly(port) => PathBuf::from(format!("/tmp/.s.monetdb.{port}")),
};
Ok(vec![Addr::Unix(path)])
Ok(Some(Addr::Unix(path)))
} else {
Ok(vec![])
Ok(None)
}
}
}

/// A generalization of [std::net::SocketAddr] that also allows Unix Domain
/// sockets.
#[derive(Debug, Clone)]
pub enum Addr {
Tcp(TcpSocketAddr),
Expand Down
7 changes: 5 additions & 2 deletions src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,10 @@ pub enum MapiEvent {

/// Something went wrong in Mapiproxy (not in the client or the server), no
/// more events on this [ConnectionId] will be reported.
Aborted { id: ConnectionId, error: Box<dyn Error + Send + Sync + 'static> },
Aborted {
id: ConnectionId,
error: Box<dyn Error + Send + Sync + 'static>,
},

/// Data has been observed flowing from client to server
/// ([Direction::Upstream]) or from server to client
Expand Down Expand Up @@ -135,7 +138,7 @@ pub enum MapiEvent {
/// Struct [EventSink] knows what to do with new [MapiEvent]s and
/// provides helper functions to generate such events.
///
/// Method [connection_sink] returns a derived struct that also holds
/// Method [connection_sink][EventSink::connection_sink] returns a derived struct that also holds
/// a connection id and is used to emit events specific to a single
/// connection.
pub struct EventSink(Box<dyn FnMut(MapiEvent) + 'static + Send>);
Expand Down
16 changes: 12 additions & 4 deletions src/pcap/tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,13 @@ impl<'a> Tracker<'a> {
bail!("pcap file contains fragmented ipv6 packet, not supported");
}

let Some(IpNumber::TCP) = ipv6.extensions().first_header() else { return Ok(()); };
let Some(IpNumber::TCP) = ipv6.extensions().first_header() else {
return Ok(());
};
let payload = ipv6.payload().payload;
let Ok(tcp) = TcpSlice::from_slice(payload) else { return Ok(()); };
let Ok(tcp) = TcpSlice::from_slice(payload) else {
return Ok(());
};

let header = &ipv6.header();
let src = IpAddr::from(header.source_addr());
Expand All @@ -55,9 +59,13 @@ impl<'a> Tracker<'a> {
bail!("pcap file contains fragmented ipv4 packet, not supported");
}

let IpNumber::TCP = ipv4.payload_ip_number() else { return Ok(()) };
let IpNumber::TCP = ipv4.payload_ip_number() else {
return Ok(());
};
let payload = ipv4.payload().payload;
let Ok(tcp) = TcpSlice::from_slice(payload) else { return Ok(()); };
let Ok(tcp) = TcpSlice::from_slice(payload) else {
return Ok(());
};

let header = &ipv4.header();
let src = IpAddr::from(header.source_addr());
Expand Down

0 comments on commit fbd7031

Please sign in to comment.