[][src]Crate cratetorrent

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 IoVecs 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

TorrentId

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.

Type Definitions

Bitfield

The bitfield represents the piece availability of a peer.

PeerId

The peer ID is an arbitrary 20 byte string.

Sha1Hash

A SHA-1 hash digest, 20 bytes long.