mirror of
https://github.com/rosenpass/rosenpass.git
synced 2025-12-08 05:40:31 -08:00
Compare commits
2 Commits
analyze_py
...
dev/add-ud
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2f8f9006a | ||
|
|
c072b7825f |
@@ -2,6 +2,7 @@ public_key = "peer-a-public-key"
|
||||
secret_key = "peer-a-secret-key"
|
||||
listen = ["[::]:10001"]
|
||||
verbosity = "Quiet"
|
||||
control_socket = "rosenpassd.sock"
|
||||
|
||||
[[peers]]
|
||||
public_key = "peer-b-public-key"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
use anyhow::bail;
|
||||
|
||||
use anyhow::Result;
|
||||
use log::debug;
|
||||
use log::trace;
|
||||
use log::{error, info, warn};
|
||||
use mio::Interest;
|
||||
use mio::Token;
|
||||
@@ -15,6 +17,7 @@ use std::net::SocketAddr;
|
||||
use std::net::SocketAddrV4;
|
||||
use std::net::SocketAddrV6;
|
||||
use std::net::ToSocketAddrs;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use std::process::Stdio;
|
||||
@@ -30,6 +33,7 @@ use crate::{
|
||||
|
||||
const IPV4_ANY_ADDR: Ipv4Addr = Ipv4Addr::new(0, 0, 0, 0);
|
||||
const IPV6_ANY_ADDR: Ipv6Addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0);
|
||||
const CONTROL_SOCKET_TOKEN: mio::Token = mio::Token(usize::MAX);
|
||||
|
||||
fn ipv4_any_binding() -> SocketAddr {
|
||||
// addr, port
|
||||
@@ -78,6 +82,9 @@ pub struct AppServer {
|
||||
pub peers: Vec<AppPeer>,
|
||||
pub verbosity: Verbosity,
|
||||
pub all_sockets_drained: bool,
|
||||
|
||||
/// Optional control socket to change the configuration of a running rosenpassd
|
||||
pub maybe_control_socket: Option<mio::net::UnixDatagram>,
|
||||
}
|
||||
|
||||
/// A socket pointer is an index assigned to a socket;
|
||||
@@ -335,11 +342,13 @@ impl HostPathDiscoveryEndpoint {
|
||||
}
|
||||
|
||||
impl AppServer {
|
||||
pub fn new(
|
||||
pub fn new<P: AsRef<Path> + core::fmt::Debug>(
|
||||
// TODO @wucke13 check if requiring Debug breaks important types that otherwise fulfill AsRef<Path>
|
||||
sk: SSk,
|
||||
pk: SPk,
|
||||
addrs: Vec<SocketAddr>,
|
||||
verbosity: Verbosity,
|
||||
uds: Option<P>,
|
||||
) -> anyhow::Result<Self> {
|
||||
// setup mio
|
||||
let mio_poll = mio::Poll::new()?;
|
||||
@@ -417,13 +426,31 @@ impl AppServer {
|
||||
}
|
||||
|
||||
// register all sockets to mio
|
||||
debug!("registering all UDP sockets to mio");
|
||||
for (i, socket) in sockets.iter_mut().enumerate() {
|
||||
trace!("registering {socket:?}");
|
||||
mio_poll
|
||||
.registry()
|
||||
.register(socket, Token(i), Interest::READABLE)?;
|
||||
}
|
||||
|
||||
let mut maybe_control_socket = uds
|
||||
.map(|p| {
|
||||
debug!("binding control socket {p:?}");
|
||||
mio::net::UnixDatagram::bind(p)
|
||||
})
|
||||
.transpose()?;
|
||||
if let Some(control_socket) = &mut maybe_control_socket {
|
||||
debug!("registering control socket to mio");
|
||||
mio_poll.registry().register(
|
||||
control_socket,
|
||||
CONTROL_SOCKET_TOKEN,
|
||||
Interest::READABLE,
|
||||
)?;
|
||||
}
|
||||
|
||||
// TODO use mio::net::UnixStream together with std::os::unix::net::UnixStream for Linux
|
||||
debug!("finalizing AppServer creation");
|
||||
|
||||
Ok(Self {
|
||||
crypt: CryptoServer::new(sk, pk),
|
||||
@@ -433,6 +460,7 @@ impl AppServer {
|
||||
events,
|
||||
mio_poll,
|
||||
all_sockets_drained: false,
|
||||
maybe_control_socket,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -638,6 +666,7 @@ impl AppServer {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Polls the crypto servers state machine for new actions
|
||||
pub fn poll(&mut self, rx_buf: &mut [u8]) -> anyhow::Result<AppPollResult> {
|
||||
use crate::protocol::PollResult as C;
|
||||
use AppPollResult as A;
|
||||
@@ -654,7 +683,7 @@ impl AppServer {
|
||||
}
|
||||
}
|
||||
|
||||
/// Tries to receive a new message
|
||||
/// Tries to receive a new control socket command or incoming message
|
||||
///
|
||||
/// - might wait for an duration up to `timeout`
|
||||
/// - returns immediately if an error occurs
|
||||
@@ -693,6 +722,27 @@ impl AppServer {
|
||||
self.mio_poll.poll(&mut self.events, Some(timeout))?;
|
||||
}
|
||||
|
||||
trace!("checking for new command on control socket");
|
||||
// control socket always has priority
|
||||
if let Some(control_socket) = &mut self.maybe_control_socket {
|
||||
let mut buf = [0u8; 16];
|
||||
|
||||
match control_socket.recv(&mut buf) {
|
||||
Ok(size) => {
|
||||
// TODO handle command
|
||||
// to send something here, use the following shell snippet:
|
||||
//
|
||||
// printf '\x7\' | nc -NuU rosenpassd.sock
|
||||
log::debug!("buf received {:?}", &buf[0..size]);
|
||||
}
|
||||
Err(e) if e.kind() == ErrorKind::WouldBlock => {
|
||||
trace!("no new commands on control socket")
|
||||
}
|
||||
Err(e) => return Err(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
// then normal traffic is processed
|
||||
let mut would_block_count = 0;
|
||||
for (sock_no, socket) in self.sockets.iter_mut().enumerate() {
|
||||
match socket.recv_from(buf) {
|
||||
|
||||
@@ -228,6 +228,7 @@ impl Cli {
|
||||
pk,
|
||||
config.listen,
|
||||
config.verbosity,
|
||||
config.control_socket.as_ref(),
|
||||
)?);
|
||||
|
||||
for cfg_peer in config.peers {
|
||||
|
||||
@@ -25,6 +25,8 @@ pub struct Rosenpass {
|
||||
|
||||
#[serde(skip)]
|
||||
pub config_file_path: PathBuf,
|
||||
|
||||
pub control_socket: Option<PathBuf>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
@@ -133,6 +135,7 @@ impl Rosenpass {
|
||||
verbosity: Verbosity::Quiet,
|
||||
peers: vec![],
|
||||
config_file_path: PathBuf::new(),
|
||||
control_socket: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
38
src/control_commands.rs
Normal file
38
src/control_commands.rs
Normal file
@@ -0,0 +1,38 @@
|
||||
//! Data structures representing the control messages going over the control socket
|
||||
//!
|
||||
//! This module uses the same de-/serialization mechanism as [crate::msgs].
|
||||
//! If you want to interface with `rosenpassd`, this is where you can look up the format
|
||||
//! of the messages that are accepted.
|
||||
|
||||
use crate::{data_lense, msgs::LenseView, RosenpassError};
|
||||
|
||||
data_lense! { ControlComand<C> :=
|
||||
/// [MsgType] of this message
|
||||
msg_type: 1
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Hash, PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Copy)]
|
||||
pub enum CommandType {
|
||||
/// Add one peer
|
||||
AddPeer = 0x10,
|
||||
|
||||
/// Remove all peers that match the given public key
|
||||
RemovePeerPk = 0x11,
|
||||
|
||||
/// Remove all peers that match the given address
|
||||
RemovePeerIp = 0x12,
|
||||
}
|
||||
|
||||
impl TryFrom<u8> for CommandType {
|
||||
type Error = RosenpassError;
|
||||
|
||||
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||
Ok(match value {
|
||||
0x10 => CommandType::AddPeer,
|
||||
0x11 => CommandType::RemovePeerPk,
|
||||
0x12 => CommandType::RemovePeerIp,
|
||||
_ => return Err(RosenpassError::InvalidMessageType(value)),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ pub mod labeled_prf;
|
||||
pub mod app_server;
|
||||
pub mod cli;
|
||||
pub mod config;
|
||||
pub mod control_commands;
|
||||
pub mod msgs;
|
||||
pub mod pqkem;
|
||||
pub mod prftree;
|
||||
@@ -26,6 +27,9 @@ pub enum RosenpassError {
|
||||
},
|
||||
#[error("invalid message type")]
|
||||
InvalidMessageType(u8),
|
||||
|
||||
#[error("invalid command type")]
|
||||
InvalidCommandType(u8),
|
||||
}
|
||||
|
||||
impl RosenpassError {
|
||||
|
||||
Reference in New Issue
Block a user