1mod admission;
3use std::{error::Error, fmt, io, time::Duration};
4
5#[derive(Clone, Copy, Debug, PartialEq, Eq)]
6pub enum AdmissionLimit {
7 Pieces,
8 PieceBytes,
9 Files,
10}
11impl fmt::Display for AdmissionLimit {
12 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13 f.write_str(match self {
14 Self::Pieces => "too many pieces",
15 Self::PieceBytes => "piece size is too large",
16 Self::Files => "too many files",
17 })
18 }
19}
20#[derive(Debug)]
21pub enum AdmissionError {
22 Metainfo(crate::protocol::metainfo::Error),
23 ResourceLimit(AdmissionLimit),
24}
25impl AdmissionError {
26 pub(in crate::engine) fn of(error: &io::Error) -> Option<&Self> {
27 error.get_ref().and_then(|e| e.downcast_ref::<Self>())
28 }
29}
30impl fmt::Display for AdmissionError {
31 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32 match self {
33 Self::Metainfo(_) => f.write_str("invalid or unsupported v1 metainfo"),
34 Self::ResourceLimit(limit) => write!(f, "unsupported torrent: {limit}"),
35 }
36 }
37}
38impl Error for AdmissionError {
39 fn source(&self) -> Option<&(dyn Error + 'static)> {
40 match self {
41 Self::Metainfo(error) => Some(error),
42 _ => None,
43 }
44 }
45}
46impl From<AdmissionError> for io::Error {
47 fn from(error: AdmissionError) -> Self {
48 Self::new(io::ErrorKind::InvalidInput, error)
49 }
50}
51
52#[derive(Clone, Copy, Debug)]
53pub struct Profile {
54 pub peers: usize,
56 pub cache_bytes: usize,
57 pub write_queue_bytes: usize,
58}
59impl Default for Profile {
60 fn default() -> Self {
61 Self::DEFAULT
62 }
63}
64impl Profile {
65 pub const DEFAULT: Self = Self {
66 peers: 50,
67 cache_bytes: 16 * 1024 * 1024,
68 write_queue_bytes: 16 * 1024 * 1024,
69 };
70}
71
72pub const MAX_META: usize = 16 * 1024 * 1024;
73pub(in crate::engine) const MAX_PIECES: u32 = 1 << 20;
74pub const BLOCK_LEN: u32 = 16 * 1024;
75pub(in crate::engine) const MAX_REQUEST_QUEUE: usize = 32;
76pub(in crate::engine) const MAX_PIECE_RETRIES: u32 = 2;
77pub(in crate::engine) const MAX_FRAME_LENGTH: u32 = MAX_PIECES / 8 + 1;
80pub(in crate::engine) const MAX_PIECE_LEN: u32 = 512 * 1024 * 1024;
81pub(in crate::engine) const MAX_FILES: usize = crate::protocol::resume::MAX_FILES;
82pub(in crate::engine) const RESUME_INTERVAL: Duration = Duration::from_secs(120);
83pub(in crate::engine) const MAX_REASSIGNMENTS: u32 = 2;
84pub(in crate::engine) const PEER_IGNORED_FRAMES: u64 = 1024;
85pub(in crate::engine) const PEER_IGNORED_BYTES: u64 = 4 * 1024 * 1024;
86pub(in crate::engine) const OUTBOUND_QUEUE: usize = 64;
87pub(in crate::engine) const EVENT_QUEUE: usize = 64;
88pub(in crate::engine) const HANDSHAKE_TIMEOUT: Duration = Duration::from_secs(15);
89pub(in crate::engine) const IDLE_TIMEOUT: Duration = Duration::from_secs(180);
90pub(in crate::engine) const FRAME_TIMEOUT: Duration = Duration::from_secs(30);
91pub(in crate::engine) const WRITE_TIMEOUT: Duration = Duration::from_secs(30);
92pub(in crate::engine) const KEEPALIVE_INTERVAL: Duration = Duration::from_secs(60);
93pub(in crate::engine) const MAX_URL_BYTES: usize = 2048;
94pub(in crate::engine) const MAX_TOTAL_URL_BYTES: usize = 16384;
95pub(in crate::engine) const TOTAL_TIMEOUT: Duration = Duration::from_secs(45);
96pub(in crate::engine) const MAX_QUEUED: usize = 128;
97pub(in crate::engine) const MAX_UPLOAD_REQUESTS: usize = 4096;
98pub(in crate::engine) const MAX_UPLOAD_READS: usize = 4;
99pub(in crate::engine) const UPLOAD_SLOTS: usize = 8;
100pub(in crate::engine) const REQUEST_TIMEOUT: Duration = Duration::from_secs(30);
101pub(in crate::engine) const HASH_CHUNK_LEN: usize = 65536;
102pub(in crate::engine) const DNS_TIMEOUT: Duration = Duration::from_secs(5);
103pub(in crate::engine) const MAX_DNS_ANSWERS: usize = 16;
104pub(in crate::engine) const MAX_WEB_SEEDS: usize = 32;
105pub(in crate::engine) const CONNECT_TIMEOUT: Duration = Duration::from_secs(10);
106pub(in crate::engine) const STALL_RETRY_INITIAL: Duration = Duration::from_secs(1);
107pub(in crate::engine) const STALL_RETRY_MAX: Duration = Duration::from_secs(30);