mirror of
https://github.com/feschber/lan-mouse.git
synced 2026-04-09 06:21:28 +03:00
Epoll (#20)
major update: - remove threading overhead by resorting to an event driven design with mio as a backend for epoll - Clients can now have an arbitrary amount of ip adresses and lan-mouse will automatically choose the correct one - -> seemless switching between ethernet and wifi - cli frontend + frontend adapter for future frontends
This commit is contained in:
committed by
GitHub
parent
22e6c531af
commit
1a4d0e05be
@@ -1,19 +1,21 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use core::fmt;
|
||||
use std::net::IpAddr;
|
||||
use std::collections::HashSet;
|
||||
use std::net::{IpAddr, SocketAddr};
|
||||
use std::{error::Error, fs};
|
||||
|
||||
use std::env;
|
||||
use toml;
|
||||
|
||||
use crate::client::Position;
|
||||
use crate::dns;
|
||||
|
||||
pub const DEFAULT_PORT: u16 = 4242;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct ConfigToml {
|
||||
pub port: Option<u16>,
|
||||
pub backend: Option<String>,
|
||||
pub frontend: Option<String>,
|
||||
pub left: Option<Client>,
|
||||
pub right: Option<Client>,
|
||||
pub top: Option<Client>,
|
||||
@@ -23,7 +25,7 @@ pub struct ConfigToml {
|
||||
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
|
||||
pub struct Client {
|
||||
pub host_name: Option<String>,
|
||||
pub ip: Option<IpAddr>,
|
||||
pub ips: Option<Vec<IpAddr>>,
|
||||
pub port: Option<u16>,
|
||||
}
|
||||
|
||||
@@ -62,8 +64,13 @@ fn find_arg(key: &'static str) -> Result<Option<String>, MissingParameter> {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
pub enum Frontend {
|
||||
Gtk,
|
||||
Cli,
|
||||
}
|
||||
|
||||
pub struct Config {
|
||||
pub backend: Option<String>,
|
||||
pub frontend: Frontend,
|
||||
pub port: u16,
|
||||
pub clients: Vec<(Client, Position)>,
|
||||
}
|
||||
@@ -73,19 +80,28 @@ impl Config {
|
||||
let config_path = "config.toml";
|
||||
let config_toml = match ConfigToml::new(config_path) {
|
||||
Err(e) => {
|
||||
eprintln!("config.toml: {e}");
|
||||
eprintln!("Continuing without config file ...");
|
||||
log::error!("config.toml: {e}");
|
||||
log::warn!("Continuing without config file ...");
|
||||
None
|
||||
},
|
||||
Ok(c) => Some(c),
|
||||
};
|
||||
|
||||
let backend = match find_arg("--backend")? {
|
||||
let frontend = match find_arg("--frontend")? {
|
||||
None => match &config_toml {
|
||||
Some(c) => c.backend.clone(),
|
||||
Some(c) => c.frontend.clone(),
|
||||
None => None,
|
||||
},
|
||||
backend => backend,
|
||||
frontend => frontend,
|
||||
};
|
||||
|
||||
let frontend = match frontend {
|
||||
None => Frontend::Cli,
|
||||
Some(s) => match s.as_str() {
|
||||
"cli" => Frontend::Cli,
|
||||
"gtk" => Frontend::Gtk,
|
||||
_ => Frontend::Cli,
|
||||
}
|
||||
};
|
||||
|
||||
let port = match find_arg("--port")? {
|
||||
@@ -113,6 +129,43 @@ impl Config {
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Config { backend, clients, port })
|
||||
Ok(Config { frontend, clients, port })
|
||||
}
|
||||
|
||||
pub fn get_clients(&self) -> Vec<(HashSet<SocketAddr>, Option<String>, Position)> {
|
||||
self.clients.iter().map(|(c,p)| {
|
||||
let port = c.port.unwrap_or(DEFAULT_PORT);
|
||||
// add ips from config
|
||||
let config_ips: Vec<IpAddr> = if let Some(ips) = c.ips.as_ref() {
|
||||
ips.iter().cloned().collect()
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
let host_name = c.host_name.clone();
|
||||
// add ips from dns lookup
|
||||
let dns_ips = match host_name.as_ref() {
|
||||
None => vec![],
|
||||
Some(host_name) => match dns::resolve(host_name) {
|
||||
Err(e) => {
|
||||
log::warn!("{host_name}: could not resolve host: {e}");
|
||||
vec![]
|
||||
}
|
||||
Ok(l) if l.is_empty() => {
|
||||
log::warn!("{host_name}: could not resolve host");
|
||||
vec![]
|
||||
}
|
||||
Ok(l) => l,
|
||||
}
|
||||
};
|
||||
if config_ips.is_empty() && dns_ips.is_empty() {
|
||||
log::error!("no ips found for client {p:?}, ignoring!");
|
||||
log::error!("You can manually specify ip addresses via the `ips` config option");
|
||||
}
|
||||
let ips = config_ips.into_iter().chain(dns_ips.into_iter());
|
||||
|
||||
// map ip addresses to socket addresses
|
||||
let addrs: HashSet<SocketAddr> = ips.map(|ip| SocketAddr::new(ip, port)).collect();
|
||||
(addrs, host_name, *p)
|
||||
}).filter(|(a, _, _)| !a.is_empty()).collect()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user