feat: fleshed out handling a new connection
This commit is contained in:
parent
d7a0deba0c
commit
cda6388596
@ -37,7 +37,7 @@ args = ["clean"]
|
||||
workspace = false
|
||||
command = "docker-compose"
|
||||
args = ["run", "build", "check", "${@}"]
|
||||
watch = { watch = ["nl-sys/src", "pcap-sys/src"] }
|
||||
watch = { watch = ["nl-sys/src", "pcap-sys/src", "sparse-05/sparse-05-client/src", "sparse-05/sparse-05-common/src", "sparse-05/sparse-05-server/src"] }
|
||||
|
||||
#-----------------------
|
||||
#
|
||||
|
||||
@ -328,7 +328,7 @@ impl<T: Activated> Interface<T> {
|
||||
|
||||
struct ListenHandler<'a, F>
|
||||
where
|
||||
F: Fn(&Interface<DevListening>, packets::EthernetPkt) -> error::Result<bool>,
|
||||
F: FnMut(&Interface<DevListening>, packets::EthernetPkt) -> error::Result<bool>,
|
||||
{
|
||||
packet_handler: F,
|
||||
break_on_fail: bool,
|
||||
@ -344,14 +344,14 @@ impl<T: NotListening> Interface<T> {
|
||||
packet_count: i32,
|
||||
) -> (Option<error::Error>, i32)
|
||||
where
|
||||
F: Fn(&Interface<DevListening>, packets::EthernetPkt) -> error::Result<bool>,
|
||||
F: FnMut(&Interface<DevListening>, packets::EthernetPkt) -> error::Result<bool>,
|
||||
{
|
||||
unsafe extern "C" fn cback<F>(
|
||||
user: *mut libc::c_void,
|
||||
header: *const ffi::PktHeader,
|
||||
data: *const u8,
|
||||
) where
|
||||
F: Fn(&Interface<DevListening>, packets::EthernetPkt) -> error::Result<bool>,
|
||||
F: FnMut(&Interface<DevListening>, packets::EthernetPkt) -> error::Result<bool>,
|
||||
{
|
||||
let info = &mut *(user as *mut ListenHandler<F>);
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ use sparse_05_common::messages::{Capabilities, TransportType};
|
||||
|
||||
const CAP_SETUID: u32 = 1 << 7;
|
||||
const CAP_NET_RAW: u32 = 1 << 13;
|
||||
const SYS_capget: i64 = 125;
|
||||
const SYS_CAPGET: i64 = 125;
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(C)]
|
||||
@ -41,7 +41,7 @@ fn get_username(uid: u32) -> anyhow::Result<Option<String>> {
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn get_capabilities() -> anyhow::Result<Capabilities> {
|
||||
fn get_current_capabilities() -> anyhow::Result<Capabilities> {
|
||||
let mut header = cap_user_header_t {
|
||||
version: 0x20080522,
|
||||
pid: 0,
|
||||
@ -52,7 +52,7 @@ pub fn get_capabilities() -> anyhow::Result<Capabilities> {
|
||||
inheritable: 0,
|
||||
};
|
||||
let oscapabilities =
|
||||
unsafe { libc::syscall(SYS_capget, &mut header as *const _, &mut data as *mut _) };
|
||||
unsafe { libc::syscall(SYS_CAPGET, &mut header as *const _, &mut data as *mut _) };
|
||||
|
||||
if oscapabilities == -1 {
|
||||
return Err(std::io::Error::last_os_error())?;
|
||||
@ -79,3 +79,7 @@ pub fn get_capabilities() -> anyhow::Result<Capabilities> {
|
||||
transport,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_capabilities() -> anyhow::Result<Capabilities> {
|
||||
get_current_capabilities()
|
||||
}
|
||||
|
||||
@ -1,10 +1,22 @@
|
||||
use std::sync::mpsc::Sender;
|
||||
use std::{net::Ipv4Addr, sync::mpsc::Sender};
|
||||
|
||||
use pcap_sys::packets::EthernetPacket;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ConnectionHandle {}
|
||||
|
||||
pub fn spawn_connection_handler(packet_sender: Sender<EthernetPacket>) -> ConnectionHandle {
|
||||
impl ConnectionHandle {
|
||||
pub fn handle_packet(&self, packet: EthernetPacket) -> anyhow::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub enum State {}
|
||||
|
||||
pub fn spawn_connection_handler(
|
||||
packet_sender: Sender<EthernetPacket>,
|
||||
connection_packet: EthernetPacket,
|
||||
connection_killer: Sender<(Ipv4Addr, u16)>,
|
||||
) -> ConnectionHandle {
|
||||
ConnectionHandle {}
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ impl Interface {
|
||||
.find(|eth| eth.starts_with("eth") || eth.starts_with("en"))
|
||||
.ok_or(anyhow!("could not get an ethernet interface"))?;
|
||||
|
||||
let mut interface = loop {
|
||||
let interface = loop {
|
||||
macro_rules! retry {
|
||||
($e:expr) => {{
|
||||
match $e {
|
||||
@ -118,14 +118,14 @@ pub enum InterfaceReceiver {
|
||||
}
|
||||
|
||||
impl InterfaceReceiver {
|
||||
pub fn listen<F>(&self, f: F) -> anyhow::Result<()>
|
||||
pub fn listen<F>(&self, mut f: F) -> anyhow::Result<()>
|
||||
where
|
||||
F: Fn(packets::EthernetPacket) -> anyhow::Result<()>,
|
||||
F: FnMut(packets::EthernetPacket) -> anyhow::Result<()>,
|
||||
{
|
||||
match self {
|
||||
Self::RawUdp(interf) => interf.listen(
|
||||
move |_, packet| {
|
||||
(f)(packet.to_owned());
|
||||
let _ = (f)(packet.to_owned());
|
||||
Ok(false)
|
||||
},
|
||||
false,
|
||||
@ -153,7 +153,7 @@ impl InterfaceReceiver {
|
||||
&Layer3Packet::IPv4(ip_packet),
|
||||
);
|
||||
|
||||
(f)(ether_packet);
|
||||
let _ = (f)(ether_packet);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@ -1,17 +1,19 @@
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
net::Ipv4Addr,
|
||||
sync::{mpsc::channel, Arc},
|
||||
sync::{mpsc::channel, Arc, Mutex},
|
||||
thread,
|
||||
};
|
||||
|
||||
use anyhow::{anyhow, bail, Context};
|
||||
use anyhow::{bail, Context};
|
||||
use connection::ConnectionHandle;
|
||||
use ed25519_dalek::PublicKey;
|
||||
|
||||
use pcap_sys::packets::EthernetPacket;
|
||||
use sparse_05_common::CONFIG_SEPARATOR;
|
||||
|
||||
use crate::connection::spawn_connection_handler;
|
||||
|
||||
mod capabilities;
|
||||
mod connection;
|
||||
mod interface;
|
||||
@ -40,17 +42,56 @@ fn main() -> anyhow::Result<()> {
|
||||
let interface = interface::Interface::new(capabilities.transport, port)?;
|
||||
let (interface_sender, interface_receiver) = interface.split()?;
|
||||
|
||||
let mut connections: HashMap<(Ipv4Addr, u16), ConnectionHandle> = HashMap::new();
|
||||
let connections: Arc<Mutex<HashMap<(Ipv4Addr, u16), ConnectionHandle>>> =
|
||||
Arc::new(Mutex::new(HashMap::new()));
|
||||
let (send_eth_packet, recv_eth_packet) = channel::<EthernetPacket>();
|
||||
let (kill_connection, kill_connection_recv) = channel::<(Ipv4Addr, u16)>();
|
||||
|
||||
{
|
||||
thread::spawn(move || loop {
|
||||
let Ok(packet) = recv_eth_packet.recv() else { continue };
|
||||
if let Err(_) = interface_sender.sendpacket(packet.pkt()) {}
|
||||
});
|
||||
|
||||
thread::spawn({
|
||||
let connections = Arc::clone(&connections);
|
||||
move || loop {
|
||||
let Ok(connection) = kill_connection_recv.recv() else { continue };
|
||||
if let Ok(mut e) = connections.lock() {
|
||||
e.remove(&connection);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
interface_receiver.listen(|pkt| {
|
||||
use pcap_sys::packets::*;
|
||||
|
||||
let pkt = pkt.pkt();
|
||||
|
||||
let Layer3Pkt::IPv4Pkt(ip_pkt) = pkt.get_layer3_pkt()?;
|
||||
let Layer4Pkt::UDP(udp_pkt) = ip_pkt.get_layer4_packet()?;
|
||||
|
||||
let connection_handle = &(ip_pkt.dest_ip(), udp_pkt.srcport());
|
||||
|
||||
if let Ok(mut connections) = connections.lock() {
|
||||
let connection = connections.get(connection_handle);
|
||||
|
||||
match connection {
|
||||
None => {
|
||||
let new_connection = spawn_connection_handler(
|
||||
send_eth_packet.clone(),
|
||||
pkt.to_owned(),
|
||||
kill_connection.clone(),
|
||||
);
|
||||
connections.insert(*connection_handle, new_connection);
|
||||
}
|
||||
Some(conn) => {
|
||||
conn.handle_packet(pkt.to_owned())?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface_receiver.listen(move |_| Ok(()))?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user