config file

This commit is contained in:
serxoz 2024-04-16 13:57:47 +02:00
parent 0d5117e4a4
commit c1c01b51d5
5 changed files with 169 additions and 13 deletions

54
Cargo.lock generated
View File

@ -448,6 +448,15 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_spanned"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1"
dependencies = [
"serde",
]
[[package]]
name = "serde_yaml"
version = "0.9.34+deprecated"
@ -477,7 +486,9 @@ dependencies = [
"log",
"log4rs",
"rand",
"serde",
"tokio",
"toml",
]
[[package]]
@ -579,6 +590,40 @@ dependencies = [
"syn 1.0.105",
]
[[package]]
name = "toml"
version = "0.8.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"toml_edit",
]
[[package]]
name = "toml_datetime"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
dependencies = [
"serde",
]
[[package]]
name = "toml_edit"
version = "0.22.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4"
dependencies = [
"indexmap",
"serde",
"serde_spanned",
"toml_datetime",
"winnow",
]
[[package]]
name = "typemap-ors"
version = "1.0.0"
@ -820,3 +865,12 @@ name = "windows_x86_64_msvc"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
[[package]]
name = "winnow"
version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0c976aaaa0e1f90dbb21e9587cdaf1d9679a1cde8875c0d6bd83ab96a208352"
dependencies = [
"memchr",
]

View File

@ -9,4 +9,6 @@ edition = "2021"
log = "0.4.21"
log4rs = "1.3.0"
rand = "0.8.5"
serde = { version = "1.0.197", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
toml = "0.8.12"

12
config.toml Normal file
View File

@ -0,0 +1,12 @@
[listen]
# address and port to listen
bind_addr = "127.0.0.1"
bind_port = 5063
[log]
# log file location
log_file = "sip-tarpit.log"
[tarpit]
# delay in milliseconds
delay = 1500

87
src/config.rs Normal file
View File

@ -0,0 +1,87 @@
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
struct ConfigToml {
listen: Option<ConfigTomlListen>,
log: Option<ConfigTomlLog>,
tarpit: Option<ConfigTomlTarpit>
}
#[derive(Serialize, Deserialize, Debug)]
struct ConfigTomlListen {
bind_addr: Option<String>,
bind_port: Option<u16>,
}
#[derive(Serialize, Deserialize, Debug)]
struct ConfigTomlLog {
log_file: Option<String>,
}
#[derive(Serialize, Deserialize, Debug)]
struct ConfigTomlTarpit {
delay: Option<u64>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Config {
pub bind_addr: String,
pub bind_port: u16,
pub log_file: String,
pub delay: u64,
}
impl Config {
pub fn new() -> Self {
let config_filepaths: [&str; 3] = [
"./config.toml",
"~/.config/sip-tarpit/config.toml",
"/etc/sip-tarpit/config.toml",
];
let mut content: String = "".to_owned();
for filepath in config_filepaths {
let result: Result<String, std::io::Error> = std::fs::read_to_string(filepath);
if result.is_ok() {
content = result.unwrap();
break;
}
}
let config_toml: ConfigToml = toml::from_str(&content).unwrap_or_else(|_| {
println!("Failed to create Config from config file.");
ConfigToml {
listen: None,
log: None,
tarpit: None
}
});
let (bind_addr, bind_port): (String, u16) = match config_toml.listen {
Some(ConfigTomlListen { bind_addr, bind_port }) => (
bind_addr.unwrap_or("127.0.0.1".to_owned()),
bind_port.unwrap_or(5060)
),
None => ("127.0.0.1".to_owned(), 5060)
};
let log_file = match config_toml.log {
Some(ConfigTomlLog { log_file }) => log_file.unwrap_or("sip-tarpit.log".to_owned()),
None => "sip-tarpit.log".to_owned()
};
let delay = match config_toml.tarpit {
Some(ConfigTomlTarpit { delay }) => delay.unwrap_or(0),
None => 0
};
Config {
bind_addr,
bind_port,
log_file,
delay
}
}
}

View File

@ -3,7 +3,8 @@
* Listens on 5060 udp by default
*
*/
pub mod sip;
mod sip;
mod config;
use crate::sip::generic::*;
use crate::sip::not_found::*;
@ -13,7 +14,7 @@ use crate::sip::unauthorized::*;
use rand::Rng;
use std::error::Error;
use std::net::SocketAddr;
use std::{env, io};
use std::io;
use tokio::net::UdpSocket;
use tokio::time::{sleep, Duration};
use log::LevelFilter;
@ -21,13 +22,11 @@ use log4rs::append::file::FileAppender;
use log4rs::config::{Appender, Config, Root};
use log4rs::encode::pattern::PatternEncoder;
// delay miliseconds for tarpit feature
static TARPIT_DELAY: u64 = 1500; // more than 2 seconds make spivicious go timeout
struct Server {
socket: UdpSocket,
buf: Vec<u8>,
to_send: Option<(usize, SocketAddr)>,
config: config::Config
}
impl Server {
@ -36,6 +35,7 @@ impl Server {
socket,
mut buf,
mut to_send,
config
} = self;
loop {
@ -51,7 +51,7 @@ impl Server {
match msg {
msg if msg.contains("OPTIONS") => {
// esperar - tarpit!
sleep(Duration::from_millis(TARPIT_DELAY)).await;
sleep(Duration::from_millis(config.delay)).await;
let options = Options::parse(&msg);
// respondemos con un 404 not found
@ -80,7 +80,7 @@ impl Server {
},
msg if msg.contains("REGISTER") => {
// esperar - tarpit!
sleep(Duration::from_millis(TARPIT_DELAY)).await;
sleep(Duration::from_millis(config.delay)).await;
let register = Register::parse(&msg);
@ -163,21 +163,21 @@ impl Server {
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let config: config::Config = config::Config::new();
// println!("{:#?}", config);
let logfile = FileAppender::builder()
.encoder(Box::new(PatternEncoder::new("{d} - {l} - {m}\n")))
.build("sip-tarpit.log")
.unwrap();
let config = Config::builder()
let logconfig = Config::builder()
.appender(Appender::builder().build("logfile", Box::new(logfile)))
.build(Root::builder().appender("logfile").build(LevelFilter::Trace))
.unwrap();
log4rs::init_config(config).unwrap();
let addr = env::args()
.nth(1)
.unwrap_or_else(|| "127.0.0.1:5063".to_string());
log4rs::init_config(logconfig).unwrap();
let addr = format!("{}:{}", config.bind_addr, config.bind_port);
let socket = UdpSocket::bind(&addr).await?;
log::info!("Listening on: {}", socket.local_addr()?);
@ -185,6 +185,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
socket,
buf: vec![0; 1024],
to_send: None,
config: config,
};
// This starts the server task.