finalise bep 15 support

This commit is contained in:
Adam 2025-08-07 19:48:15 +01:00
parent b07a2847d9
commit 8caaf55101
4 changed files with 24 additions and 5 deletions

View File

@ -1,3 +1,13 @@
# meteoro # meteoro
A UDP BitTorrent tracker written in Rust A BitTorrent tracker, written in Rust, implementing a BEP 15-compliant UDP tracker server.
## Building
`$ cargo build`
## Usage
After building the binary as described above, one can run the executable with the `--help` flag to see a listing of options the server software provides.
The server software currently binds to the `localhost`, both IPv4 and IPv6, when run with no arguments. One can supply the `-a IPV4_ADDRESS:PORT` option or `-A IPV6_ADDRESS:PORT` option to specify interfaces for the server to bind to. Example: `$ meteoro -a 192.168.1.23:6969` to bind on 192.168.1.23, port 6969.

3
TODO.md Normal file
View File

@ -0,0 +1,3 @@
# The Big To-Do List
- **Metrics/management API**, for returning statistics and modifying configurations at runtime using HTTP & JSON

View File

@ -1,12 +1,11 @@
use std::net::{SocketAddr, UdpSocket}; use std::net::{SocketAddr, UdpSocket};
use std::thread; use std::thread;
use std::time::Duration;
use anyhow::Result; use anyhow::Result;
use flume::Sender; use flume::Sender;
use threadpool::ThreadPool; use threadpool::ThreadPool;
use crate::tracker::{self, RequestMessage, ResponseMessage, Tracker}; use crate::tracker::{RequestMessage, ResponseMessage, Tracker};
use crate::udp_server; use crate::udp_server;
/// Instance of the meteoro BitTorrent tracker /// Instance of the meteoro BitTorrent tracker

View File

@ -1,5 +1,5 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::net::{SocketAddr, SocketAddrV4, SocketAddrV6}; use std::net::SocketAddr;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
@ -74,9 +74,13 @@ impl Tracker {
let mut next_gc = Instant::now() + GARBAGE_COLLECTION_INTERVAL; let mut next_gc = Instant::now() + GARBAGE_COLLECTION_INTERVAL;
let should_exit = AtomicBool::new(false); let should_exit = AtomicBool::new(false);
// Wait for messages from the networking threads / main application
while !should_exit.load(Ordering::Relaxed) { while !should_exit.load(Ordering::Relaxed) {
let _ = Selector::new() let _ = Selector::new()
.recv(&reqs, |request| { .recv(&reqs, |request| {
// Tracker request
let request = request.unwrap(); let request = request.unwrap();
log::trace!("Request from {} | {:?}", request.src_addr, request.request); log::trace!("Request from {} | {:?}", request.src_addr, request.request);
@ -89,6 +93,8 @@ impl Tracker {
}; };
}) })
.recv(&ctrl, |msg| { .recv(&ctrl, |msg| {
// Control message
let msg = msg.unwrap(); let msg = msg.unwrap();
match msg { match msg {
@ -99,8 +105,9 @@ impl Tracker {
}) })
.wait(); .wait();
// Garbage collection
if Instant::now() > next_gc { if Instant::now() > next_gc {
// Garbage collect
self.garbage_collect(); self.garbage_collect();
next_gc = Instant::now() next_gc = Instant::now()