aquatic_http: add PeerMapKey with PeerID and Either<Ip, announce key>

This commit is contained in:
Joakim Frostegård 2020-07-04 12:00:36 +02:00
parent 73807baacb
commit c50dec3496
3 changed files with 36 additions and 14 deletions

View file

@ -1,6 +1,7 @@
use std::net::SocketAddr; use std::net::{IpAddr, SocketAddr};
use std::sync::Arc; use std::sync::Arc;
use either::Either;
use flume::{Sender, Receiver}; use flume::{Sender, Receiver};
use hashbrown::HashMap; use hashbrown::HashMap;
use indexmap::IndexMap; use indexmap::IndexMap;
@ -15,7 +16,6 @@ use crate::protocol::request::Request;
use crate::protocol::response::Response; use crate::protocol::response::Response;
// identical to ws version
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct ConnectionMeta { pub struct ConnectionMeta {
/// Index of socket worker responsible for this connection. Required for /// Index of socket worker responsible for this connection. Required for
@ -26,7 +26,6 @@ pub struct ConnectionMeta {
} }
// identical to ws version
#[derive(PartialEq, Eq, Clone, Copy, Debug)] #[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum PeerStatus { pub enum PeerStatus {
Seeding, Seeding,
@ -35,7 +34,6 @@ pub enum PeerStatus {
} }
// almost identical to ws version - FIXME only if bytes left is optional
impl PeerStatus { impl PeerStatus {
/// Determine peer status from announce event and number of bytes left. /// Determine peer status from announce event and number of bytes left.
/// ///
@ -65,11 +63,16 @@ pub struct Peer {
} }
// identical to ws version #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub type PeerMap = IndexMap<PeerId, Peer>; pub struct PeerMapKey {
pub peer_id: PeerId,
pub ip_or_key: Either<IpAddr, String>
}
pub type PeerMap = IndexMap<PeerMapKey, Peer>;
// identical to ws version
pub struct TorrentData { pub struct TorrentData {
pub peers: PeerMap, pub peers: PeerMap,
pub num_seeders: usize, pub num_seeders: usize,
@ -77,7 +80,6 @@ pub struct TorrentData {
} }
// identical to ws version
impl Default for TorrentData { impl Default for TorrentData {
#[inline] #[inline]
fn default() -> Self { fn default() -> Self {
@ -90,11 +92,9 @@ impl Default for TorrentData {
} }
// identical to ws version
pub type TorrentMap = HashMap<InfoHash, TorrentData>; pub type TorrentMap = HashMap<InfoHash, TorrentData>;
// identical to ws version
#[derive(Default)] #[derive(Default)]
pub struct TorrentMaps { pub struct TorrentMaps {
pub ipv4: TorrentMap, pub ipv4: TorrentMap,
@ -102,7 +102,6 @@ pub struct TorrentMaps {
} }
// identical to ws version
#[derive(Clone)] #[derive(Clone)]
pub struct State { pub struct State {
pub torrent_maps: Arc<Mutex<TorrentMaps>>, pub torrent_maps: Arc<Mutex<TorrentMaps>>,

View file

@ -1,6 +1,7 @@
use std::time::Duration; use std::time::Duration;
use std::vec::Drain; use std::vec::Drain;
use either::Either;
use hashbrown::HashMap; use hashbrown::HashMap;
use parking_lot::MutexGuard; use parking_lot::MutexGuard;
use rand::{Rng, SeedableRng, rngs::SmallRng}; use rand::{Rng, SeedableRng, rngs::SmallRng};
@ -116,19 +117,30 @@ pub fn handle_announce_requests(
valid_until, valid_until,
}; };
let ip_or_key = request.key
.map(|k| Either::Right(k))
.unwrap_or_else(||
Either::Left(request_sender_meta.peer_addr.ip())
);
let peer_map_key = PeerMapKey {
peer_id: request.peer_id,
ip_or_key,
};
let opt_removed_peer = match peer_status { let opt_removed_peer = match peer_status {
PeerStatus::Leeching => { PeerStatus::Leeching => {
torrent_data.num_leechers += 1; torrent_data.num_leechers += 1;
torrent_data.peers.insert(request.peer_id, peer) torrent_data.peers.insert(peer_map_key, peer)
}, },
PeerStatus::Seeding => { PeerStatus::Seeding => {
torrent_data.num_seeders += 1; torrent_data.num_seeders += 1;
torrent_data.peers.insert(request.peer_id, peer) torrent_data.peers.insert(peer_map_key, peer)
}, },
PeerStatus::Stopped => { PeerStatus::Stopped => {
torrent_data.peers.remove(&request.peer_id) torrent_data.peers.remove(&peer_map_key)
} }
}; };

View file

@ -15,6 +15,7 @@ pub struct AnnounceRequest {
pub compact: bool, pub compact: bool,
/// Number of response peers wanted /// Number of response peers wanted
pub numwant: Option<usize>, pub numwant: Option<usize>,
pub key: Option<String>,
} }
@ -78,6 +79,15 @@ impl Request {
} else { } else {
None None
}; };
let key = if let Some(s) = data.get("key"){
if s.len() > 100 {
return Err(anyhow::anyhow!("'key' is too long"))
}
Some(s.clone())
} else {
None
};
let request = AnnounceRequest { let request = AnnounceRequest {
info_hash: info_hashes.get(0) info_hash: info_hashes.get(0)
@ -103,6 +113,7 @@ impl Request {
.map(|s| s == "1") .map(|s| s == "1")
.unwrap_or(true), .unwrap_or(true),
numwant, numwant,
key,
}; };
Ok(Request::Announce(request)) Ok(Request::Announce(request))