mirror of
https://github.com/YGGverse/aquatic.git
synced 2026-04-02 02:35:31 +00:00
aquatic_udp: simplify access list logic
This commit is contained in:
parent
8639f380f4
commit
b5a2b81bd7
3 changed files with 59 additions and 75 deletions
|
|
@ -9,7 +9,7 @@ use indexmap::IndexMap;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
||||||
pub enum AccessListType {
|
pub enum AccessListType {
|
||||||
Allow,
|
Allow,
|
||||||
Deny,
|
Deny,
|
||||||
|
|
@ -65,8 +65,18 @@ impl AccessList {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn contains(&self, info_hash_bytes: &[u8; 20]) -> bool {
|
pub fn allows(&self, list_type: AccessListType, info_hash_bytes: &[u8; 20]) -> bool {
|
||||||
self.0.contains(info_hash_bytes)
|
match list_type {
|
||||||
|
AccessListType::Allow => {
|
||||||
|
self.0.contains(info_hash_bytes)
|
||||||
|
}
|
||||||
|
AccessListType::Deny => {
|
||||||
|
!self.0.contains(info_hash_bytes)
|
||||||
|
}
|
||||||
|
AccessListType::Ignore => {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ use rand::{
|
||||||
Rng, SeedableRng,
|
Rng, SeedableRng,
|
||||||
};
|
};
|
||||||
|
|
||||||
use aquatic_common::{convert_ipv4_mapped_ipv6, extract_response_peers};
|
use aquatic_common::{AccessListType, convert_ipv4_mapped_ipv6, extract_response_peers};
|
||||||
use aquatic_udp_protocol::*;
|
use aquatic_udp_protocol::*;
|
||||||
|
|
||||||
use crate::common::*;
|
use crate::common::*;
|
||||||
|
|
@ -123,43 +123,29 @@ pub fn run_request_worker(
|
||||||
|
|
||||||
::std::mem::drop(connections);
|
::std::mem::drop(connections);
|
||||||
|
|
||||||
// Check announce requests for allowed info hash
|
// Check announce requests for allowed info hashes
|
||||||
|
|
||||||
let access_list: MutexGuard<AccessList> = state.access_list.lock();
|
match config.access_list.list_type {
|
||||||
|
access_list_type@(AccessListType::Allow | AccessListType::Deny) => {
|
||||||
|
let access_list: MutexGuard<AccessList> = state.access_list.lock();
|
||||||
|
|
||||||
announce_requests.retain(|(request, src)| {
|
announce_requests.retain(|(request, src)| {
|
||||||
match config.access_list.list_type {
|
if !access_list.allows(access_list_type, &request.info_hash.0) {
|
||||||
aquatic_common::AccessListType::Allow => {
|
|
||||||
if !access_list.contains(&request.info_hash.0) {
|
|
||||||
let response = ErrorResponse {
|
let response = ErrorResponse {
|
||||||
transaction_id: request.transaction_id,
|
transaction_id: request.transaction_id,
|
||||||
message: "Forbidden info hash".to_string(),
|
message: "Info hash not allowed".to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.push((response.into(), *src));
|
responses.push((response.into(), *src));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
},
|
|
||||||
aquatic_common::AccessListType::Deny => {
|
|
||||||
if access_list.contains(&request.info_hash.0) {
|
|
||||||
let response = ErrorResponse {
|
|
||||||
transaction_id: request.transaction_id,
|
|
||||||
message: "Forbidden info hash".to_string(),
|
|
||||||
};
|
|
||||||
|
|
||||||
responses.push((response.into(), *src));
|
true
|
||||||
|
});
|
||||||
return false;
|
},
|
||||||
}
|
AccessListType::Ignore => {},
|
||||||
},
|
};
|
||||||
aquatic_common::AccessListType::Ignore => {},
|
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
});
|
|
||||||
|
|
||||||
::std::mem::drop(access_list);
|
|
||||||
|
|
||||||
// Handle announce and scrape requests
|
// Handle announce and scrape requests
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,72 +19,60 @@ pub fn clean_connections_and_torrents(config: &Config, state: &State) {
|
||||||
}
|
}
|
||||||
|
|
||||||
match config.access_list.list_type {
|
match config.access_list.list_type {
|
||||||
AccessListType::Allow => {
|
access_list_type@(AccessListType::Allow | AccessListType::Deny) => {
|
||||||
let mut access_list = state.access_list.lock();
|
let mut access_list = state.access_list.lock();
|
||||||
|
|
||||||
access_list.update_from_path(&config.access_list.path);
|
access_list.update_from_path(&config.access_list.path);
|
||||||
|
|
||||||
let mut torrents = state.torrents.lock();
|
let mut torrents = state.torrents.lock();
|
||||||
|
|
||||||
torrents.ipv4.retain(|info_hash, _| access_list.contains(&info_hash.0));
|
torrents.ipv4.retain(|info_hash, torrent| {
|
||||||
clean_torrent_map(&mut torrents.ipv4, now);
|
access_list.allows(access_list_type, &info_hash.0) && clean_torrent_and_peers(now, torrent)
|
||||||
|
});
|
||||||
|
torrents.ipv4.shrink_to_fit();
|
||||||
|
|
||||||
torrents.ipv6.retain(|info_hash, _| access_list.contains(&info_hash.0));
|
torrents.ipv6.retain(|info_hash, torrent| {
|
||||||
clean_torrent_map(&mut torrents.ipv6, now);
|
access_list.allows(access_list_type, &info_hash.0) && clean_torrent_and_peers(now, torrent)
|
||||||
},
|
});
|
||||||
AccessListType::Deny => {
|
torrents.ipv6.shrink_to_fit();
|
||||||
let mut access_list = state.access_list.lock();
|
|
||||||
|
|
||||||
access_list.update_from_path(&config.access_list.path);
|
|
||||||
|
|
||||||
let mut torrents = state.torrents.lock();
|
|
||||||
|
|
||||||
torrents.ipv4.retain(|info_hash, _| !access_list.contains(&info_hash.0));
|
|
||||||
clean_torrent_map(&mut torrents.ipv4, now);
|
|
||||||
|
|
||||||
torrents.ipv6.retain(|info_hash, _| !access_list.contains(&info_hash.0));
|
|
||||||
clean_torrent_map(&mut torrents.ipv6, now);
|
|
||||||
},
|
},
|
||||||
AccessListType::Ignore => {
|
AccessListType::Ignore => {
|
||||||
let mut torrents = state.torrents.lock();
|
let mut torrents = state.torrents.lock();
|
||||||
|
|
||||||
clean_torrent_map(&mut torrents.ipv4, now);
|
torrents.ipv4.retain(|_, torrent| clean_torrent_and_peers(now, torrent));
|
||||||
clean_torrent_map(&mut torrents.ipv6, now);
|
torrents.ipv4.shrink_to_fit();
|
||||||
|
|
||||||
|
torrents.ipv6.retain(|_, torrent| clean_torrent_and_peers(now, torrent));
|
||||||
|
torrents.ipv6.shrink_to_fit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if torrent is to be kept
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clean_torrent_map<I: Ip>(
|
fn clean_torrent_and_peers<I: Ip>(now: Instant, torrent: &mut TorrentData<I>) -> bool {
|
||||||
torrents: &mut TorrentMap<I>,
|
let num_seeders = &mut torrent.num_seeders;
|
||||||
now: Instant
|
let num_leechers = &mut torrent.num_leechers;
|
||||||
) {
|
|
||||||
torrents.retain(|_, torrent| {
|
|
||||||
let num_seeders = &mut torrent.num_seeders;
|
|
||||||
let num_leechers = &mut torrent.num_leechers;
|
|
||||||
|
|
||||||
torrent.peers.retain(|_, peer| {
|
torrent.peers.retain(|_, peer| {
|
||||||
let keep = peer.valid_until.0 > now;
|
let keep = peer.valid_until.0 > now;
|
||||||
|
|
||||||
if !keep {
|
if !keep {
|
||||||
match peer.status {
|
match peer.status {
|
||||||
PeerStatus::Seeding => {
|
PeerStatus::Seeding => {
|
||||||
*num_seeders -= 1;
|
*num_seeders -= 1;
|
||||||
}
|
}
|
||||||
PeerStatus::Leeching => {
|
PeerStatus::Leeching => {
|
||||||
*num_leechers -= 1;
|
*num_leechers -= 1;
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
keep
|
keep
|
||||||
});
|
|
||||||
|
|
||||||
!torrent.peers.is_empty()
|
|
||||||
});
|
});
|
||||||
|
|
||||||
torrents.shrink_to_fit();
|
!torrent.peers.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gather_and_print_statistics(state: &State, config: &Config) {
|
pub fn gather_and_print_statistics(state: &State, config: &Config) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue