Expand description
cratetorrent
is a peer-to-peer file-sharing engine implementing the
BitTorrent version 1 protocol.
It is built on top of tokio
for
async IO.
§Caveats
The engine currently only supports Linux. This is expected to change in the future, however.
It also lacks most features present in battle-hardened torrent engines, such as libtorrent. These include: DHT for peer exchange, magnet links, stream encryption, UDP trackers, and many more.
Therefore in the current state of the project, this should only be viewed as a toy program.
§The engine
Users of the library will be interacting with the engine, which drives uploads and downloads (in short, torrents).
As a first step of using cratetorrent, the engine needs to be spawned and
started. This must happen within a tokio context–that is, on a task
already spawned on the tokio executor. A useful macro for this is
tokio::main
.
The engine may be configured via the types in the conf
module, though
options at the moment are fairly limited.
§Downloading
To start a download, as decribed above, the cratetorrent engine has to be already running.
Then, the metainfo of the torrent needs to be constructed. This, as its name suggests, contains metadata about the torrent. It will be most commonly be downloaded as a file from a torrent tracker.
This then can be read in as a file and parsed into
a Metainfo
instance using its
constructor. This will fail if the
metainfo is semantically or syntactically invalid.
Note that in order to download a torrent the metainfo has to contain HTTP trackers, or some seeds have to be manually specified. As mentioned above, DHT or even UDP trackers are not currently supported.
Once this is done, a command to the engine has to be sent to create the
torrent. This is done using
EngineHandle::create_torrent
,
which takes a TorrentParams
instance for
the torrent’s parameters.
Also included is an option to override the global torrent configuration
(passed to engine, as mentioned above) via
TorrentConf
. If not set, the global
configuration is used for all new torrents, but this way it is possible to
configure a torrent on a case-by-case basis.
For now, the torrent’s download mode has to be specified via Mode
:
whether to download or seed (upload) the torrent. If the latter is chosen,
the torrent’s contents have to exist in the directory specified as the
torrent’s download directory in TorrentConf
.
§Full example of a download
An example download of an arbitrary torrent download that exits a soon as the download is complete might look like this:
use cratetorrent::prelude::*;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// spawn the engine with a default config
let conf = Conf::new("/tmp/downloads");
let (engine, mut alert_rx) = engine::spawn(conf)?;
// parse torrent metainfo and start the download (use tokio::fs)
let metainfo = std::fs::read("/tmp/imaginary.torrent")?;
let metainfo = Metainfo::from_bytes(&metainfo)?;
let torrent_id = engine.create_torrent(TorrentParams {
metainfo,
// tell the engine to assign a randomly chosen free port
listen_addr: None,
mode: Mode::Download { seeds: Vec::new() },
conf: None,
})?;
// listen to alerts from the engine
while let Some(alert) = alert_rx.next().await {
match alert {
Alert::TorrentStats { id, stats } => {
println!("{}: {:#?}", id, stats);
}
Alert::TorrentComplete(id) => {
println!("{} complete, shutting down", id);
break;
}
Alert::Error(e) => {
// this is where you'd handle recoverable errors
println!("Engine error: {}", e);
}
_ => (),
}
}
// Don't forget to call shutdown on the engine to gracefully stop all
// entities in the engine. This will wait for announcing the client's
// leave to all trackers of torrent, finish pending disk and network IO,
// as well as wait for peer connections to cleanly shut down.
engine.shutdown().await?;
Ok(())
}
§Seeding
Seeding is fairly analogous to the above.
The major differences are that the torrent mode has to be specified as
Mode::Seed
and that the engine won’t send
a notification of completion, as the concept is not applicable to
seeding–it’s indefinite until the user stops it.
Therefore the application must make sure to provide its own way of stopping the download.
Re-exports§
pub use storage_info::FileInfo;
Modules§
- alert
- This module defines the alerts the API user may receive from the torrent engine.
- conf
- This module defines types used to configure the engine and its parts.
- engine
- The engine is the top-level coordinator that runs and manages all entities
in the torrent engine. The user interacts with the engine via the
EngineHandle
which exposes a restricted public API. The underlying communication method is tokio mpsc channels. - error
- This module includes the errors that could occur in the engine. They are reported via the alert system, as most operations via the engine happen asynchronously.
- iovecs
- This crate provides a helper type for a slice of
IoVec
s for zero-copy functionality to bound iovecs by a byte count and to advance the buffer cursor after partial vectored IO. - metainfo
- This module contains a type safe representation of a torrent’s metainfo, as well as utilities to construct it.
- peer
- This module defines the implementation of the BitTorrent peer wire protocol.
- prelude
- This module exports types commonly used by applications as a convenience.
- storage_
info - torrent
Structs§
- Torrent
Id - Each torrent gets a randomly assigned ID that is unique within the engine. This id is used in engine APIs to interact with torrents.
Enums§
- Side
- Whether a torrent or peer connection is a seed or a leech.