More values are configurable
This commit is contained in:
parent
f5fe87631c
commit
9a31422091
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -1260,6 +1260,14 @@ dependencies = [
|
|||
"tokio-reactor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower-service"
|
||||
version = "0.1.0"
|
||||
|
@ -1364,6 +1372,7 @@ dependencies = [
|
|||
"bincode 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"toml 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1644,6 +1653,7 @@ dependencies = [
|
|||
"checksum tokio-timer 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3a52f00c97fedb6d535d27f65cccb7181c8dd4c6edc3eda9ea93f6d45d05168e"
|
||||
"checksum tokio-udp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "da941144b816d0dcda4db3a1ba87596e4df5e860a72b70783fe435891f80601c"
|
||||
"checksum tokio-uds 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "22e3aa6d1fcc19e635418dc0a30ab5bd65d347973d6f43f1a37bf8d9d1335fc9"
|
||||
"checksum toml 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "4a2ecc31b0351ea18b3fe11274b8db6e4d82bce861bbb22e6dbed40417902c65"
|
||||
"checksum tower-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b32f72af77f1bfe3d3d4da8516a238ebe7039b51dd8637a09841ac7f16d2c987"
|
||||
"checksum trust-dns-proto 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f1525ca4e26f5a09d81b79584f19225e7dba5606ae3a416311c2751c5cea60bb"
|
||||
"checksum trust-dns-proto 0.5.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3fabc184ed90d027afee46386e6418b9c953b7be527f62cc37724a1720e07d68"
|
||||
|
|
|
@ -7,7 +7,17 @@ pub use tracker::TrackerMode;
|
|||
#[derive(Deserialize)]
|
||||
pub struct UDPConfig {
|
||||
bind_address: String,
|
||||
mode: TrackerMode,
|
||||
announce_interval: u32,
|
||||
}
|
||||
|
||||
impl UDPConfig {
|
||||
pub fn get_address(&self) -> &str {
|
||||
self.bind_address.as_str()
|
||||
}
|
||||
|
||||
pub fn get_announce_interval(&self) -> u32 {
|
||||
self.announce_interval
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
|
@ -16,8 +26,19 @@ pub struct HTTPConfig {
|
|||
access_tokens: HashMap<String, String>,
|
||||
}
|
||||
|
||||
impl HTTPConfig {
|
||||
pub fn get_address(&self) -> &str {
|
||||
self.bind_address.as_str()
|
||||
}
|
||||
|
||||
pub fn get_access_tokens(&self) -> &HashMap<String, String> {
|
||||
&self.access_tokens
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Configuration {
|
||||
mode: TrackerMode,
|
||||
udp: UDPConfig,
|
||||
http: Option<HTTPConfig>,
|
||||
}
|
||||
|
@ -39,7 +60,6 @@ impl std::fmt::Display for ConfigError {
|
|||
}
|
||||
impl std::error::Error for ConfigError {}
|
||||
|
||||
|
||||
impl Configuration {
|
||||
pub fn load(data: &[u8]) -> Result<Configuration, toml::de::Error> {
|
||||
toml::from_slice(data)
|
||||
|
@ -56,14 +76,27 @@ impl Configuration {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_mode(&self) -> &TrackerMode {
|
||||
&self.mode
|
||||
}
|
||||
|
||||
pub fn get_udp_config(&self) -> &UDPConfig {
|
||||
&self.udp
|
||||
}
|
||||
|
||||
pub fn get_http_config(&self) -> &Option<HTTPConfig> {
|
||||
&self.http
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Configuration {
|
||||
fn default() -> Configuration {
|
||||
Configuration{
|
||||
mode: TrackerMode::DynamicMode,
|
||||
udp: UDPConfig{
|
||||
announce_interval: 120,
|
||||
bind_address: String::from("0.0.0.0:6969"),
|
||||
mode: TrackerMode::DynamicMode,
|
||||
},
|
||||
http: None,
|
||||
}
|
||||
|
|
22
src/main.rs
22
src/main.rs
|
@ -14,27 +14,25 @@ use config::Configuration;
|
|||
|
||||
fn main() {
|
||||
let cfg = match Configuration::load_file("udpt.toml") {
|
||||
Ok(v) => v,
|
||||
Ok(v) => std::sync::Arc::new(v),
|
||||
Err(e) => {
|
||||
eprintln!("failed to open configuration: {}", e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
let tracker = std::sync::Arc::new(tracker::TorrentTracker::new());
|
||||
let tracker = std::sync::Arc::new(tracker::TorrentTracker::new(cfg.get_mode().clone()));
|
||||
|
||||
// start http server:
|
||||
let mut access_tokens = std::collections::HashMap::new();
|
||||
access_tokens.insert(String::from("MySpecialToken"), String::from("username"));
|
||||
if let Some(http_cfg) = cfg.get_http_config() {
|
||||
let http_tracker_ref = tracker.clone();
|
||||
let cfg_ref = cfg.clone();
|
||||
std::thread::spawn(move || {
|
||||
webserver::WebServer::new(http_tracker_ref, cfg_ref);
|
||||
});
|
||||
}
|
||||
|
||||
let http_tracker_ref = tracker.clone();
|
||||
std::thread::spawn(move || {
|
||||
webserver::WebServer::new(http_tracker_ref);
|
||||
});
|
||||
|
||||
let addr = "0.0.0.0:1212";
|
||||
let s = std::sync::Arc::new(server::UDPTracker::new(addr, tracker.clone()).unwrap());
|
||||
let s = std::sync::Arc::new(server::UDPTracker::new(cfg, tracker.clone()).unwrap());
|
||||
|
||||
loop {
|
||||
match s.accept_packet() {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use std;
|
||||
use std::sync::Arc;
|
||||
use std::net::{SocketAddr, UdpSocket};
|
||||
use std::io::Write;
|
||||
|
||||
|
@ -7,6 +8,7 @@ use serde::{Serialize, Deserialize};
|
|||
|
||||
use tracker;
|
||||
use stackvec::StackVec;
|
||||
use config::Configuration;
|
||||
|
||||
// maximum MTU is usually 1500, but our stack allows us to allocate the maximum - so why not?
|
||||
const MAX_PACKET_SIZE: usize = 0xffff;
|
||||
|
@ -109,11 +111,14 @@ struct UDPAnnounceResponse {
|
|||
pub struct UDPTracker {
|
||||
server: std::net::UdpSocket,
|
||||
tracker: std::sync::Arc<tracker::TorrentTracker>,
|
||||
config: Arc<Configuration>,
|
||||
}
|
||||
|
||||
impl UDPTracker {
|
||||
pub fn new<T: std::net::ToSocketAddrs>(bind_address: T, tracker: std::sync::Arc<tracker::TorrentTracker>) -> Result<UDPTracker, std::io::Error> {
|
||||
let server = match UdpSocket::bind(bind_address) {
|
||||
pub fn new(config: Arc<Configuration>, tracker: std::sync::Arc<tracker::TorrentTracker>) -> Result<UDPTracker, std::io::Error> {
|
||||
let cfg = config.clone();
|
||||
|
||||
let server = match UdpSocket::bind(cfg.get_udp_config().get_address()) {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
return Err(e);
|
||||
|
@ -123,6 +128,7 @@ impl UDPTracker {
|
|||
Ok(UDPTracker{
|
||||
server,
|
||||
tracker,
|
||||
config: cfg,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -216,7 +222,7 @@ impl UDPTracker {
|
|||
transaction_id: packet.header.transaction_id,
|
||||
},
|
||||
seeders,
|
||||
interval: 20,
|
||||
interval: self.config.get_udp_config().get_announce_interval(),
|
||||
leechers,
|
||||
}) {
|
||||
Ok(_) => {},
|
||||
|
|
|
@ -2,7 +2,7 @@ use std;
|
|||
|
||||
use server::Events;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[derive(Deserialize, Clone)]
|
||||
pub enum TrackerMode {
|
||||
|
||||
/// In static mode torrents are tracked only if they were added ahead of time.
|
||||
|
@ -179,9 +179,9 @@ pub enum TorrentStats {
|
|||
}
|
||||
|
||||
impl TorrentTracker {
|
||||
pub fn new() -> TorrentTracker {
|
||||
pub fn new(mode: TrackerMode) -> TorrentTracker {
|
||||
TorrentTracker{
|
||||
mode: TrackerMode::DynamicMode,
|
||||
mode,
|
||||
database: TorrentDatabase{
|
||||
torrent_peers: std::sync::RwLock::new(std::collections::BTreeMap::new()),
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ use std::sync::Arc;
|
|||
use actix_web;
|
||||
use binascii;
|
||||
|
||||
use config;
|
||||
use tracker;
|
||||
|
||||
const SERVER: &str = concat!("udpt/", env!("CARGO_PKG_VERSION"));
|
||||
|
@ -126,9 +127,25 @@ impl actix_web::middleware::Middleware<UdptState> for UdptMiddleware {
|
|||
}
|
||||
|
||||
impl WebServer {
|
||||
pub fn new(tracker: Arc<tracker::TorrentTracker>) -> WebServer {
|
||||
fn get_access_tokens(cfg: &config::HTTPConfig, tokens: &mut HashMap<String, String>) {
|
||||
for (user, token) in cfg.get_access_tokens().iter() {
|
||||
tokens.insert(token.clone(), user.clone());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(tracker: Arc<tracker::TorrentTracker>, cfg: Arc<config::Configuration>) -> WebServer {
|
||||
let cfg_cp = cfg.clone();
|
||||
|
||||
let server = actix_web::server::HttpServer::new(move || {
|
||||
actix_web::App::<UdptState>::with_state(UdptState::new(tracker.clone(), HashMap::new()))
|
||||
let mut access_tokens = HashMap::new();
|
||||
|
||||
if let Some(http_cfg) = cfg_cp.get_http_config() {
|
||||
Self::get_access_tokens(http_cfg, &mut access_tokens);
|
||||
}
|
||||
|
||||
let state = UdptState::new(tracker.clone(), access_tokens);
|
||||
|
||||
actix_web::App::<UdptState>::with_state(state)
|
||||
.middleware(UdptMiddleware)
|
||||
.resource("/t", |r| r.f(Self::view_torrent_list))
|
||||
.scope(r"/t/{info_hash:[\dA-Fa-f]{40,40}}", |scope| {
|
||||
|
@ -141,14 +158,20 @@ impl WebServer {
|
|||
.resource("/", |r| r.method(actix_web::http::Method::GET).f(Self::view_root))
|
||||
});
|
||||
|
||||
match server.bind("0.0.0.0:1212") {
|
||||
Ok(v) => {
|
||||
v.run();
|
||||
},
|
||||
Err(_) => {
|
||||
eprintln!("failed to bind server");
|
||||
if let Some(http_cfg) = cfg.get_http_config() {
|
||||
let bind_addr = http_cfg.get_address();
|
||||
match server.bind(bind_addr) {
|
||||
Ok(v) => {
|
||||
v.run();
|
||||
},
|
||||
Err(_) => {
|
||||
eprintln!("failed to bind server");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
WebServer{}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue