forked from torrust/torrust-tracker
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlib.rs
521 lines (514 loc) · 18.3 KB
/
lib.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
//! **Torrust Tracker** is a modern and feature-rich (private) [`BitTorrent`](https://www.bittorrent.org/) tracker.
//!
//! [`BitTorrent`](https://en.wikipedia.org/wiki/BitTorrent) is a protocol for distributing files using a peer-to-peer network.
//!
//! Peers in the networks need to know where they can find other peers with the files they are looking for.
//!
//! Tracker are services that allow peers to quickly find other peers. Client peers announce their existence to a tracker,
//! and the tracker responds to the peer with a list of other peers in the swarm.
//!
//! You can learn more about `BitTorrent` and `BitTorrent` Trackers on these sites:
//!
//! - <https://www.bittorrent.org/>
//! - <https://en.wikipedia.org/wiki/BitTorrent>
//! - <https://en.wikipedia.org/wiki/BitTorrent_tracker>
//!
//! Torrust Tracker is a `BitTorrent` tracker with a focus on:
//!
//! - Performance
//! - Robustness
//! - Extensibility
//! - Security
//! - Usability
//! - And with a community-driven development
//!
//! # Table of contents
//!
//! - [Features](#features)
//! - [Services](#services)
//! - [Installation](#installation)
//! - [Minimum requirements](#minimum-requirements)
//! - [Prerequisites](#prerequisites)
//! - [Install from sources](#install-from-sources)
//! - [Run with docker](#run-with-docker)
//! - [Configuration](#configuration)
//! - [Usage](#usage)
//! - [API](#api)
//! - [HTTP Tracker](#http-tracker)
//! - [UDP Tracker](#udp-tracker)
//! - [Components](#components)
//! - [Implemented BEPs](#implemented-beps)
//! - [Contributing](#contributing)
//! - [Documentation](#documentation)
//!
//! # Features
//!
//! - Multiple UDP server and HTTP(S) server blocks for socket binding possible
//! - Full IPv4 and IPv6 support for both UDP and HTTP(S)
//! - Private and Whitelisted mode
//! - Built-in API
//! - Peer authentication using time-bound keys
//! - Database persistence for authentication keys, whitelist and completed peers counter
//! - DB Support for `SQLite` and `MySQl`
//!
//! # Services
//!
//! From the end-user perspective the Torrust Tracker exposes three different services.
//!
//! - A REST [`API`](crate::servers::apis)
//! - One or more [`UDP`](crate::servers::udp) trackers
//! - One or more [`HTTP`](crate::servers::http) trackers
//!
//! # Installation
//!
//! ## Minimum requirements
//!
//! - Rust Stable `1.68`
//! - You might have problems compiling with a machine with low resources.
//!
//! It has been tested with:
//!
//! Docker containers with:
//!
//! - 6 CPUs
//! - 7.5G of ram
//! - 2GB of swap
//!
//! [VM](https://github.com/torrust/torrust-tracker/issues/321) with:
//!
//! - 1 core of Intel Xeon Processor (Icelake)
//! - 1G of ram
//! - 25G of disk
//! - Debian 11
//! - no swap by default
//!
//! Adding swap may help with compilation. See issue [#321](https://github.com/torrust/torrust-tracker/issues/321).
//!
//! ## Prerequisites
//!
//! The tracker has some system dependencies:
//!
//! Since we are using the `openssl` crate with the [vendored feature](https://docs.rs/openssl/latest/openssl/#vendored),
//! enabled, you will need to install the following dependencies:
//!
//! ```text
//! sudo apt-get install pkg-config libssl-dev make
//! ```
//!
//! If you are using `SQLite3` as database driver, you will need to install the
//! following dependency:
//!
//! ```text
//! sudo apt-get install libsqlite3-dev
//! ```
//!
//! > **NOTICE**: those are the commands for `Ubuntu`. If you are using a
//! different OS, you will need to install the equivalent packages. Please
//! refer to the documentation of your OS.
//!
//! With the default configuration you will need to create the `storage` directory:
//!
//! ```text
//! storage/
//! ├── database
//! │ └── data.db
//! └── tls
//! ├── localhost.crt
//! └── localhost.key
//! ```
//!
//! The default configuration expects a directory `./storage/tracker/lib/database` to be writable by the tracker process.
//!
//! By default the tracker uses `SQLite` and the database file name `data.db`.
//!
//! We will have to have a file to save the torrust-tracker, which we will call "torrust".
//!
//! ```text
//! mkdir torrust
//! cd torrust/
//! ```
//!
//! You only need the `tls` directory in case you are setting up SSL for the HTTP tracker or the tracker API.
//! Visit [`HTTP`](crate::servers::http) or [`API`](crate::servers::apis) if you want to know how you can use HTTPS.
//!
//! ## Install from sources
//!
//!
//! ```text
//! git clone https://github.com/torrust/torrust-tracker.git \
//! && cd torrust-tracker \
//! && cargo build --release \
//! && mkdir -p ./storage/tracker/lib/database \
//! && mkdir -p ./storage/tracker/lib/tls
//! ```
//!
//! To run the tracker we will have to use the commands "cargo run" this will have to compile data while being executed and after being compiled it will start running the tracker.
//!
//! ```text
//! cargo run
//! ```
//!
//! If you want to configure your tracker further, you can go to the "Configuration" section to configure it to your liking.
//!
//!
//! ## Run with docker
//!
//! You can run the tracker with a pre-built docker image. Please refer to the
//! [tracker docker documentation](https://github.com/torrust/torrust-tracker/tree/develop/docker).
//!
//! # Configuration
//!
//! In order to run the tracker you need to provide the configuration. If you run the tracker without providing the configuration,
//! the tracker will generate the default configuration the first time you run it. It will generate a `Cargo.toml` file with
//! in the root directory.
//!
//! The default configuration is:
//!
//! ```toml
//! announce_interval = 120
//! db_driver = "Sqlite3"
//! db_path = "./storage/tracker/lib/database/sqlite3.db"
//! external_ip = "0.0.0.0"
//! inactive_peer_cleanup_interval = 600
//! log_level = "info"
//! max_peer_timeout = 900
//! min_announce_interval = 120
//! mode = "public"
//! on_reverse_proxy = false
//! persistent_torrent_completed_stat = false
//! remove_peerless_torrents = true
//! tracker_usage_statistics = true
//!
//! [[udp_trackers]]
//! bind_address = "0.0.0.0:6969"
//! enabled = false
//!
//! [[http_trackers]]
//! bind_address = "0.0.0.0:7070"
//! enabled = false
//! ssl_cert_path = ""
//! ssl_enabled = false
//! ssl_key_path = ""
//!
//! [http_api]
//! bind_address = "127.0.0.1:1212"
//! enabled = true
//! ssl_cert_path = ""
//! ssl_enabled = false
//! ssl_key_path = ""
//!
//! [http_api.access_tokens]
//! admin = "MyAccessToken"
//!
//! [health_check_api]
//! bind_address = "127.0.0.1:1313"
//!```
//!
//! The default configuration includes one disabled UDP server, one disabled HTTP server and the enabled API.
//!
//! For more information about each service and options you can visit the documentation for the [torrust-tracker-configuration crate](https://docs.rs/torrust-tracker-configuration).
//!
//! Alternatively to the `Cargo.toml` file you can use one environment variable `TORRUST_TRACKER_CONFIG` to pass the configuration to the tracker:
//!
//! ```text
//! TORRUST_TRACKER_CONFIG=$(cat Cargo.toml)
//! cargo run
//! ```
//!
//! In the previous example you are just setting the env var with the contents of the `Cargo.toml` file.
//!
//! The env var contains the same data as the `Cargo.toml`. It's particularly useful in you are [running the tracker with docker](https://github.com/torrust/torrust-tracker/tree/develop/docker).
//!
//! > NOTE: The `TORRUST_TRACKER_CONFIG` env var has priority over the `Cargo.toml` file.
//!
//! # Usage
//!
//! Running the tracker with the default configuration and enabling the UDP and HTTP trackers will expose the services on these URLs:
//!
//! - REST API: <http://localhost:1212>
//! - UDP tracker: <http://localhost:6969>
//! - HTTP tracker: <http://localhost:7070>
//!
//! ## API
//!
//! In order to use the tracker API you need to enable it in the configuration:
//!
//! ```toml
//! [http_api]
//! enabled = true
//! bind_address = "127.0.0.1:1212"
//! ssl_enabled = false
//! ssl_cert_path = ""
//! ssl_key_path = ""
//! ```
//!
//! By default it's enabled on port `1212`. You also need to add access tokens in the configuration:
//!
//! ```toml
//! [http_api.access_tokens]
//! admin = "MyAccessToken"
//! LABEL = "YOUR_TOKEN"
//! ```
//!
//! All tokens give full access the the API. Once you have defined you token you can make request adding the token as a `GET` parameter. For example:
//!
//! <http://127.0.0.1:1212/api/v1/stats?token=MyAccessToken>
//!
//! That endpoint will give you the tracker metrics:
//!
//! ```json
//! {
//! "torrents": 0,
//! "seeders": 0,
//! "completed": 0,
//! "leechers": 0,
//! "tcp4_connections_handled": 0,
//! "tcp4_announces_handled": 0,
//! "tcp4_scrapes_handled": 0,
//! "tcp6_connections_handled": 0,
//! "tcp6_announces_handled": 0,
//! "tcp6_scrapes_handled": 0,
//! "udp4_connections_handled": 0,
//! "udp4_announces_handled": 0,
//! "udp4_scrapes_handled": 0,
//! "udp6_connections_handled": 0,
//! "udp6_announces_handled": 0,
//! "udp6_scrapes_handled": 0
//! }
//! ```
//!
//! Refer to the [`API`](crate::servers::apis) documentation for more information about the [`API`](crate::servers::apis) endpoints.
//!
//! ## HTTP tracker
//!
//! The HTTP tracker implements two type of requests:
//!
//! - Announce: <http://127.0.0.1:7070/announce>
//! - Scrape: <http://127.0.0.1:7070/scrape>
//!
//! In you are using the tracker in `private` or `private_listed` mode you will need to append the authentication key:
//!
//! - Announce: <http://127.0.0.1:7070/announce/key>
//! - Scrape: <http://127.0.0.1:7070/scrape/key>
//!
//! In order to use the HTTP tracker you need to enable at least one server in the configuration:
//!
//! ```toml
//! [[http_trackers]]
//! enabled = true
//! bind_address = "0.0.0.0:7070"
//! ```
//!
//! Refer to the [`HTTP`](crate::servers::http) documentation for more information about the [`HTTP`](crate::servers::http) tracker.
//!
//! ### Announce
//!
//! The `announce` request allows a peer to announce itself and obtain a list of peer for an specific torrent.
//!
//! A sample `announce` request:
//!
//! <http://0.0.0.0:7070/announce?info_hash=%81%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00&peer_addr=2.137.87.41&downloaded=0&uploaded=0&peer_id=-qB00000000000000001&port=17548&left=0&event=completed&compact=0>
//!
//! If you want to know more about the `announce` request:
//!
//! - [BEP 03. The `BitTorrent` Protocol Specification](https://www.bittorrent.org/beps/bep_0003.html)
//! - [BEP 23. Tracker Returns Compact Peer Lists](https://www.bittorrent.org/beps/bep_0023.html)
//! - [Vuze announce docs](https://wiki.vuze.com/w/Announce)
//!
//! ### Scrape
//!
//! The `scrape` request allows a peer to get swarm metadata for multiple torrents at the same time.
//!
//! A sample `scrape` request for only one torrent:
//!
//! <http://0.0.0.0:7070/scrape?info_hash=%81%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00>
//!
//! The response contains the swarm metadata for that torrent:
//!
//! - `complete`: the number of active peers that have completed downloading, also known as seeders. Peers from which other peers can get a full copy of the torrent.
//! - `downloaded`: the number of peers that have ever completed downloading.
//! - `incomplete`: the number of active peers that have not completed downloading, also known as leechers.
//!
//! The `scrape` response is a bencoded byte array like the following:
//!
//! ```text
//! d5:filesd20:xxxxxxxxxxxxxxxxxxxxd8:completei11e10:downloadedi13772e10:incompletei19e20:yyyyyyyyyyyyyyyyyyyyd8:completei21e10:downloadedi206e10:incompletei20eee
//! ```
//!
//! If you save the response as a file and you open it with a program that can handle binary data you would see:
//!
//! ```text
//! 00000000: 6435 3a66 696c 6573 6432 303a 8100 0000 d5:filesd20:....
//! 00000010: 0000 0000 0000 0000 0000 0000 0000 0000 ................
//! 00000020: 6438 3a63 6f6d 706c 6574 6569 3165 3130 d8:completei1e10
//! 00000030: 3a64 6f77 6e6c 6f61 6465 6469 3065 3130 :downloadedi0e10
//! 00000040: 3a69 6e63 6f6d 706c 6574 6569 3065 6565 :incompletei0eee
//! 00000050: 65 e
//! ```
//!
//! `BitTorrent` uses a data formatting specification called [Bencode](https://en.wikipedia.org/wiki/Bencode).
//!
//! If you want to know more about the `scrape` request:
//!
//! - [BEP 48. Tracker Protocol Extension: Scrape](https://www.bittorrent.org/beps/bep_0048.html)
//! - [Vuze scrape docs](https://wiki.vuze.com/w/Scrape)
//!
//! ### Authentication keys
//!
//! If the tracker is running in `private` or `private_listed` mode you will need to provide a valid authentication key.
//!
//! Right now the only way to add new keys is via the REST [`API`](crate::servers::apis). The endpoint `POST /api/vi/key/:duration_in_seconds`
//! will return an expiring key that will be valid for `duration_in_seconds` seconds.
//!
//! Using `curl` you can create a 2-minute valid auth key:
//!
//! ```text
//! $ curl -X POST "http://127.0.0.1:1212/api/v1/key/120?token=MyAccessToken"
//! ```
//!
//! Response:
//!
//! ```json
//! {
//! "key": "nvCFlJCq7fz7Qx6KoKTDiMZvns8l5Kw7",
//! "valid_until": 1679334334,
//! "expiry_time": "2023-03-20 17:45:34.712077008 UTC"
//! }
//! ```
//!
//! You can also use the Torrust Tracker together with the [Torrust Index](https://github.com/torrust/torrust-index). If that's the case,
//! the Index will create the keys by using the tracker [API](crate::servers::apis).
//!
//! ## UDP tracker
//!
//! The UDP tracker also implements two type of requests:
//!
//! - Announce: <udp://127.0.0.1:6969>
//! - Scrape: <udp://127.0.0.1:6969>
//!
//! In order to use the UDP tracker you need to enable at least one server in the configuration:
//!
//! ```toml
//! [[udp_trackers]]
//! enabled = true
//! bind_address = "0.0.0.0:6969"
//! ```
//!
//! Refer to the [`UDP`](crate::servers::udp) documentation for more information about the [`UDP`](crate::servers::udp) tracker.
//!
//! If you want to know more about the UDP tracker protocol:
//!
//! - [BEP 15. UDP Tracker Protocol for `BitTorrent`](https://www.bittorrent.org/beps/bep_0015.html)
//!
//! # Components
//!
//! Torrust Tracker has four main components:
//!
//! - The core tracker [`core`]
//! - The tracker REST [`API`](crate::servers::apis)
//! - The [`UDP`](crate::servers::udp) tracker
//! - The [`HTTP`](crate::servers::http) tracker
//!
//! 
//!
//! ## Core tracker
//!
//! The core tracker is the main containing the tracker generic tracker logic.
//!
//! The core tracker handles:
//!
//! - Authentication with keys
//! - Authorization using a torrent whitelist
//! - Statistics
//! - Persistence
//!
//! See [`core`] for more details on the [`core`] module.
//!
//! ## Tracker API
//!
//! The tracker exposes a REST API. The API has four resource groups:
//!
//! - Authentication keys: to handle the keys for the HTTP tracker
//! - Statistics: to get the tracker metrics like requests counters
//! - Torrents: to get peers for a torrent
//! - Whitelist: to handle the torrent whitelist when the tracker runs on `listed` or `private_listed` mode
//!
//! See [`API`](crate::servers::apis) for more details on the REST API.
//!
//! ## UDP tracker
//!
//! UDP trackers are trackers with focus on performance. By Using UDP instead of HTTP the tracker removed the overhead
//! of opening and closing TCP connections. It also reduces the response size.
//!
//! You can find more information about UDP tracker on:
//!
//! - [Wikipedia: UDP tracker](https://en.wikipedia.org/wiki/UDP_tracker)
//! - [BEP 15: UDP Tracker Protocol for `BitTorrent`](https://www.bittorrent.org/beps/bep_0015.html)
//!
//! See [`UDP`](crate::servers::udp) for more details on the UDP tracker.
//!
//! ## HTTP tracker
//!
//! HTTP tracker was the original tracker specification defined on the [BEP 3]((https://www.bittorrent.org/beps/bep_0003.html)).
//!
//! See [`HTTP`](crate::servers::http) for more details on the HTTP tracker.
//!
//! You can find more information about UDP tracker on:
//!
//! - [Wikipedia: `BitTorrent` tracker](https://en.wikipedia.org/wiki/BitTorrent_tracker)
//! - [BEP 3: The `BitTorrent` Protocol Specification](https://www.bittorrent.org/beps/bep_0003.html)
//!
//! # Implemented BEPs
//!
//! BEP stands for `BitTorrent` Enhancement Proposal. BEPs are documents providing information to the `BitTorrent`
//! community or describing a new feature for the `BitTorrent` protocols.
//!
//! You can find all BEPs on <https://www.bittorrent.org/>
//!
//! Torrust Tracker implements these BEPs:
//!
//! - [BEP 3](https://www.bittorrent.org/beps/bep_0003.html): The `BitTorrent` Protocol
//! - [BEP 7](https://www.bittorrent.org/beps/bep_0007.html): IPv6 Support
//! - [BEP 15](https://www.bittorrent.org/beps/bep_0015.html): UDP Tracker Protocol for `BitTorrent`
//! - [BEP 23](https://www.bittorrent.org/beps/bep_0023.html): Tracker Returns Compact Peer Lists
//! - [BEP 27](https://www.bittorrent.org/beps/bep_0027.html): Private Torrents
//! - [BEP 48](https://www.bittorrent.org/beps/bep_0048.html): Tracker Protocol Extension: Scrape
//!
//! # Contributing
//!
//! If you want to contribute to this documentation you can [open a new pull request](https://github.com/torrust/torrust-tracker/pulls).
//!
//! # Documentation
//!
//! You can find this documentation on [docs.rs](https://docs.rs/torrust-tracker/).
//!
//! If you want to contribute to this documentation you can [open a new pull request](https://github.com/torrust/torrust-tracker/pulls).
//!
//! In addition to the production code documentation you can find a lot of
//! examples on the integration and unit tests.
use torrust_tracker_clock::{clock, time_extent};
pub mod app;
pub mod bootstrap;
pub mod console;
pub mod core;
pub mod servers;
pub mod shared;
#[macro_use]
extern crate lazy_static;
/// This code needs to be copied into each crate.
/// Working version, for production.
#[cfg(not(test))]
#[allow(dead_code)]
pub(crate) type CurrentClock = clock::Working;
/// Stopped version, for testing.
#[cfg(test)]
#[allow(dead_code)]
pub(crate) type CurrentClock = clock::Stopped;
/// Working version, for production.
#[cfg(not(test))]
#[allow(dead_code)]
pub(crate) type DefaultTimeExtentMaker = time_extent::WorkingTimeExtentMaker;
/// Stopped version, for testing.
#[cfg(test)]
#[allow(dead_code)]
pub(crate) type DefaultTimeExtentMaker = time_extent::StoppedTimeExtentMaker;