A BitTorrent V1 engine library for Rust (and currently Linux)

Overview

cratetorrent

Cratetorrent is a Rust crate implementing the BitTorrent version 1 protocol.

Cargo Documentation License


It can be used as a library and also provides a simple example CLI torrent app. It is built on top of tokio and uses async IO for high performance.

The name is a homage to the C++ libtorrent library, from which many lessons were learned when I first wrote my torrent engine in C++.

Features

  • Multiple torrent downloads or uploads, with an arbitrary number of peer connections.
  • Manually specify seeds to download from.
  • Get peers from HTTP trackers.
  • Basic per-torrent configurability.
  • Decent performance:

    On my fairly slow internet connection with peak download rates of about 9 MBps, Ubuntu 20.04 LTS (~2.8 GB) is downloaded in about 5 minutes at a download rate of 8-9 MBps, that is, almost fully utilizing the link. When testing on localhost, the thruput rate goes up to 270 MBps.

Features are continuously added, see the project milestones.

Eventually, I hope to develop cratetorrent into a full-fledged BitTorrent engine library that can be used as the engine underneath torrent clients. This means that features supported by popular clients (such as DHT, magnet links, BitTorrent protocol 2, stream encryption, and others) will be supported by cratetorrent in the future.

Download example

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
    let metainfo = tokio::fs::read("/tmp/imaginary.torrent").await?;
    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,
        // here we could specify peers we knew of that we'd want
        // to connect to
        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(())
}

Project structure

The project is split up in two:

  • the cratetorrent library, that defines most of the functionality,
  • and a cratetorrent-cli binary for downloading torrents via the CLI. Note, however, that this is extremely simple at present and serves more as a toy for demonstration purposes.

How to run

Tested on stable Rust 1.48.

Requires Linux!

This is because file IO is done using the pwritev(2) and preadv(2) APIs for optimal performance. In the future, API shims for Windows and Darwin may be supported, but at the moment there is no capacity to do this.

Binary

The CLI binary is currently very basic, but you can perform downloads either by directly connecting to seeds or if the torrent is backed by a HTTP tracker.

Run the following from the repo root:

cargo run --release -p cratetorrent-cli -- \
    --seeds 192.168.0.10:50051,192.168.0.172:49985 \
    --metainfo path/to/mytorrent.torrent \
    --download-dir ~/Downloads

Tests

Cratetorrent is well tested to ensure correct functionality. It includes:

  • an exhaustive suite of inline unit tests,
  • and integration tests of various downloads and uploads, in the integration tests folder.

Design

The cratetorrent design is documented in the design doc. This mostly concerns developers of cratetorrent, as it contains fairly low-level descriptions.

Comments
  • Upgrade dependencies

    Upgrade dependencies

    Fixes #76 Fixes #101

    Upgrade all dependencies (except bitvec).

    some not straightforward updates:

    1. No need to use fused futures with UnboundedReceiver .
    2. length reading code in codec.rs changed to use some extra apis provided in bytes 1.0 (tests work, but not sure if code can be improved further).
    opened by pawanjay176 5
  • cratetorrent-cli Mode and Metainfo options conflict

    cratetorrent-cli Mode and Metainfo options conflict

    The master branch (I checked out at 0a6225b4e626c2ff13f37c4c3f1469fdcc1795f2) contains an issue in the cratetorrent-cli utility. There are two options specifying a short "-m" option in the StructOpt argument parsing code:

    #[derive(StructOpt, Debug)]
    pub struct Args {
        /// Whether to 'seed' or 'download' the torrent.
        #[structopt(
            short,
            long,
            parse(from_str = parse_mode),
            default_value = "Mode::Download { seeds: Vec::new() }",
        )]
    ....
        mode: Mode,
        /// The path to the torrent metainfo file.
        #[structopt(short, long)]
        metainfo: PathBuf,
    ....
    }
    

    This leads to this issue:

     $ cratetorrent (master) → ./target/debug/cratetorrent-cli --help
    thread 'main' panicked at 'Argument short must be unique
    
            -m is already in use', /home/josh/.cargo/registry/src/github.com-1ecc6299db9ec823/clap-2.33.3/src/app/parser.rs:193:13
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    
    opened by jabedude 2
  • Panic in time related function

    Panic in time related function

    Sometimes occurs when running tests/test_multi_connection_download.sh --size $(( 50 * 1024 * 1024 )).

    [2020-11-14T19:20:55Z DEBUG cratetorrent::disk::io] Piece 761 intersects files: 0..1
    [2020-11-14T19:20:55Z DEBUG cratetorrent::torrent] Disk write result Ok(BatchWrite { blocks: [BlockInfo { piece_index: 760, offset: 0, len: 16384 }, BlockInfo { piece_index: 760, offset: 16384, len: 16384 }, BlockInfo { piece_index: 760, offset: 32768, len: 16384 }, BlockInfo { piece_index: 760, offset: 49152, len: 16384 }], is_piece_valid: Some(true) })
    [2020-11-14T19:20:55Z DEBUG cratetorrent::disk::io] Disk received command
    [2020-11-14T19:20:55Z TRACE cratetorrent::disk::io] Saving torrent 0 block BlockInfo { piece_index: 761, offset: 16384, len: 16384 } to disk
    [2020-11-14T19:20:55Z TRACE cratetorrent::disk::io] Saving block BlockInfo { piece_index: 761, offset: 16384, len: 16384 } to disk
    [2020-11-14T19:20:55Z DEBUG cratetorrent::disk::io] Disk received command
    [2020-11-14T19:20:55Z INFO  cratetorrent::torrent] Finished piece 760 download, valid: true, left: 38
    [2020-11-14T19:20:55Z TRACE cratetorrent::disk::io] Saving torrent 0 block BlockInfo { piece_index: 761, offset: 32768, len: 16384 } to disk
    [2020-11-14T19:20:55Z TRACE cratetorrent::disk::io] Saving block BlockInfo { piece_index: 761, offset: 32768, len: 16384 } to disk
    [2020-11-14T19:20:55Z DEBUG cratetorrent::disk::io] Disk received command
    [2020-11-14T19:20:55Z TRACE cratetorrent::disk::io] Saving torrent 0 block BlockInfo { piece_index: 761, offset: 49152, len: 16384 } to disk
    [2020-11-14T19:20:55Z TRACE cratetorrent::disk::io] Saving block BlockInfo { piece_index: 761, offset: 49152, len: 16384 } to disk
    [2020-11-14T19:20:55Z DEBUG cratetorrent::disk::io] Piece 761 is complete (65536 bytes), flushing 4 block(s) to disk
    [2020-11-14T19:20:55Z DEBUG cratetorrent::disk::io] Piece hash: f1a938c768f7efbcc26b33a112bbf3ec381aa40b
    [2020-11-14T19:20:55Z DEBUG cratetorrent::disk::io] Piece 761 is valid
    [2020-11-14T19:20:55Z DEBUG cratetorrent::disk::io] Disk received command
    [2020-11-14T19:20:55Z DEBUG cratetorrent::torrent] Disk write result Ok(BatchWrite { blocks: [BlockInfo { piece_index: 761, offset: 0, len: 16384 }, BlockInfo { piece_index: 761, offset: 16384, len: 16384 }, BlockInfo { piece_index: 761, offset: 32768, len: 16384 }, BlockInfo { piece_index: 761, offset: 49152, len: 16384 }], is_piece_valid: Some(true) })
    [2020-11-14T19:20:55Z INFO  cratetorrent::torrent] Finished piece 761 download, valid: true, left: 38
    [2020-11-14T19:20:55Z TRACE cratetorrent::disk::io] Saving torrent 0 block BlockInfo { piece_index: 762, offset: 0, len: 16384 } to disk
    [2020-11-14T19:20:55Z TRACE cratetorrent::disk::io] Saving block BlockInfo { piece_index: 762, offset: 0, len: 16384 } to disk
    [2020-11-14T19:20:55Z TRACE cratetorrent::disk::io] Creating piece 762 write buffer
    [2020-11-14T19:20:55Z DEBUG cratetorrent::disk::io] Piece 762 expected hash 6292ef9ee99381ddd8fb524c64daa61047bbe88b
    [2020-11-14T19:20:55Z DEBUG cratetorrent::disk::io] Piece 762 is 65536 bytes long
    [2020-11-14T19:20:55Z TRACE cratetorrent::storage_info] Returning files intersecting piece 762
    [2020-11-14T19:20:55Z DEBUG cratetorrent::disk::io] Piece 762 intersects files: 0..1
    [2020-11-14T19:20:55Z DEBUG cratetorrent::disk::io] Disk received command
    [2020-11-14T19:20:55Z TRACE cratetorrent::disk::io] Saving torrent 0 block BlockInfo { piece_index: 762, offset: 16384, len: 16384 } to disk
    [2020-11-14T19:20:55Z TRACE cratetorrent::disk::io] Saving block BlockInfo { piece_index: 762, offset: 16384, len: 16384 } to disk
    [2020-11-14T19:20:55Z DEBUG cratetorrent::disk::io] Disk received command
    [2020-11-14T19:20:55Z TRACE cratetorrent::disk::io] Saving torrent 0 block BlockInfo { piece_index: 762, offset: 32768, len: 16384 } to disk
    [2020-11-14T19:20:55Z TRACE cratetorrent::disk::io] Saving block BlockInfo { piece_index: 762, offset: 32768, len: 16384 } to disk
    [2020-11-14T19:20:55Z WARN  cratetorrent::peer] [Peer 172.17.0.2:51413] timeout after 14935 ms (timeouts: 13)
    [2020-11-14T19:20:55Z TRACE cratetorrent::peer] Making requests to peer 172.17.0.2:51413
    [2020-11-14T19:20:55Z DEBUG cratetorrent::peer] Session 172.17.0.2:51413 starting new piece download
    [2020-11-14T19:20:55Z TRACE cratetorrent::piece_picker] Picking next piece
    [2020-11-14T19:20:55Z TRACE cratetorrent::piece_picker] Could not pick piece
    [2020-11-14T19:20:55Z DEBUG cratetorrent::peer] Could not pick more pieces from peer 172.17.0.2:51413
    [2020-11-14T19:20:55Z INFO  cratetorrent::peer] [Peer 172.17.0.2:51413] download rate: 34311 b/s (peak: 780141 b/s, total: 4128768 b) queue: 1, rtt: 616 ms (~0 s)
    [2020-11-14T19:20:55Z WARN  cratetorrent::peer] [Peer 172.17.0.3:51413] timeout after 14951 ms (timeouts: 1)
    [2020-11-14T19:20:55Z TRACE cratetorrent::download] Canceling request for piece 762 block BlockInfo { piece_index: 762, offset: 49152, len: 16384 }
    [2020-11-14T19:20:55Z TRACE cratetorrent::download] Canceling request for piece 763 block BlockInfo { piece_index: 763, offset: 0, len: 16384 }
    < snip>
    [2020-11-14T19:20:55Z TRACE cratetorrent::download] Canceling request for piece 799 block BlockInfo { piece_index: 799, offset: 49152, len: 16384 }
    [2020-11-14T19:20:55Z TRACE cratetorrent::peer] Making requests to peer 172.17.0.3:51413
    [2020-11-14T19:20:55Z DEBUG cratetorrent::peer] Peer 172.17.0.3:51413 trying to continue download 784
    [2020-11-14T19:20:55Z TRACE cratetorrent::download] Picking 1 block(s) in piece 784 (length: 65536, blocks: 4)
    [2020-11-14T19:20:55Z DEBUG cratetorrent::download] Picked 1 block(s) for piece 784: [BlockInfo { piece_index: 784, offset: 0, len: 16384 }]
    [2020-11-14T19:20:55Z DEBUG cratetorrent::peer] Peer 172.17.0.3:51413 trying to continue download 791
    [2020-11-14T19:20:55Z INFO  cratetorrent::peer] Requesting 1 block(s) from peer 172.17.0.3:51413 (0 pending)
    [2020-11-14T19:20:55Z INFO  cratetorrent::peer] [Peer 172.17.0.3:51413] download rate: 2593852 b/s (peak: 2593852 b/s, total: 45858816 b) queue: 1, rtt: 14627 ms (~14 s)
    [2020-11-14T19:20:55Z TRACE cratetorrent::peer::codec] Decoder has 16371 byte(s) remaining
    [2020-11-14T19:20:55Z TRACE cratetorrent::peer::codec] Read buffer is 16371 bytes long but message is 16393 bytes long
    [2020-11-14T19:20:55Z TRACE cratetorrent::peer::codec] Decoder has 16397 byte(s) remaining
    [2020-11-14T19:20:55Z DEBUG cratetorrent::peer] Received message 172.17.0.3:51413 from peer Some(Block)
    [2020-11-14T19:20:55Z INFO  cratetorrent::peer] Received block from peer 172.17.0.3:51413: BlockInfo { piece_index: 784, offset: 0, len: 16384 }
    [2020-11-14T19:20:55Z TRACE cratetorrent::download] Received piece 784 block BlockInfo { piece_index: 784, offset: 0, len: 16384 }
    thread 'tokio-runtime-worker' panicked at 'supplied instant is later than self', library/std/src/time.rs:271:48
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    [2020-11-14T19:20:56Z DEBUG cratetorrent::torrent] Torrent running for 26s
    
    bug 
    opened by mandreyel 2
  • Constant Assertion Error

    Constant Assertion Error

    thread 'main' panicked at 'assertion failed: matches!(self.blocks [block.index_in_piece()], BlockStatus :: Requested)', /home/username/.cargo/git/checkouts/cratetorrent-25088b08ab150db1/34aa138/cratetorrent/src/download.rs:127:9

    Looks to me like this is being triggered whenever a received block hash doesn't match up correctly or something? Not sure if asserting and causing a panic on every invalid block is the correct solution here.

    opened by TBye101 1
  • Upgrading to Tokio v1

    Upgrading to Tokio v1

    I've recently been working on cratetorrent, and it's really great. The only gripe I have is that it uses Tokio v0.2, instead of Tokio v1, making it incompatible with a project I'm working on.

    opened by billyb2 1
  • Acknowledge that TorrentIds are globally unique

    Acknowledge that TorrentIds are globally unique

    This code probably doesn't do what it's supposed to:

    https://github.com/mandreyel/cratetorrent/blob/dbb3719c776f0b74ac6ea1aabcbb724d08078127/cratetorrent/src/lib.rs#L168-L185

    What caught my attention is that lazy_static doesn't really do anything here. static TORRENT_ID: AtomicU32 = AtomicU32::new(0); would do the same thing.

    But the real concern is that the comments suggest different behaviour.

    • Each torrent gets a randomly assigned ID that is unique **within the engine**. This implies that an id may be not unique across different engines, but in fact the ID generator isn't even aware about engines. It issues globally unique IDs.
    • Produces a new unique torrent id per process. This hints that you meant to make the generator per-process (i.e every preocess gets TORRENT_ID initialized with 0), but it's not how lazy_static works. There's thread_local for that.

    I don't recommend issuing per-whatever IDs. What if, for example, process A creates let a = ID(0), process B creates let b = ID(0), then b is send to the process A? Just issuing global u32 ids is free from this problem.

    opened by ExceptionallyHandsome 1
  • Fix clap errors

    Fix clap errors

    cratetorrent-cli would panic at runtime with this error: thread 'main' panicked at 'Argument short must be unique

    this was because both the mode and metainfo options had an automatic short option generated for them and they both used -m. I've removed the short option from mode.

    Closes #93

    opened by nikitalita 1
  • Torrent peer management

    Torrent peer management

    Currently the torrent doesn't do much with the peer sessions it has. This is partly because there is no existing infrastructure for a peer to report its state to its torrent.

    This is crucial for a few reasons: if torrent requests peers from its tracker, the peers returned are not guaranteed to be seeds, so the torrent may end up in a situation where it is stuck. Therefore it needs to periodically check (in its "torrent tick") whether we need to disconnect idle peers and request new ones to drive forward the download.

    enhancement 
    opened by mandreyel 1
  • Use channels for engine-torrent communication

    Use channels for engine-torrent communication

    Although currently there is no real 'engine' entity, we still want to communicate two things:

    • torrent sending a "DownloadComplete" event to engine
    • engine's ability to send a "Stop" command to torrent

    These can be used to more cleanly implement stopping the torrent than how it is currently done.

    Later of course this will expand to many more types of commands engine can send to torrent, and events torrent can send to engine.

    enhancement 
    opened by mandreyel 1
  • Seed a torrent

    Seed a torrent

    Disk IO

    • [x] read specified block from disk
    • [x] read cache, read cache lines (pull in more blocks with one read)
    • [x] handle concurrent requests for same block with "read faults"

    Peer

    • [x] handle request messages to upload block data
    • [x] handle cancel message to cancel block read:
      • probably can't cancel in-progress disk IO
      • but shouldn't upload block that was cancelled.
      • use cancel buffer and check presence before uploading after successful disk read?
    • [x] inbound connections:
      • peer session inbound constructor
      • handle inbound handhsakes
      • remove all checks that peer is not a seed (previously only downloading from seeds was supported)
      • if we have pieces, send bitfield message
    • [x] send have message to non-seed peers

    Torrent

    • [x] conditionally allocate torrent on disk
    • [x] accept new connections
    • [x] unchoking peers: simplified or full unchoke algorithm? -> out of scope, we unchoke unconditionally for now (#60)
    • ~~stop torrent alert (sent by engine)~~ separate MR, out of scope (#62)

    Engine & CLI

    • [x] parameter to seed a file: cli arg with corresponding option in engine
    • ~~'torrent complete' alert from torrent to engine, stopping a download session~~ separate MR, out of scope (#62)

    Integration tests

    Use cratetorrent for seeding and downloading as we already have test infrastructure to easily set up and verify cratetorrent downloads. As a next step we could have leech tests for e.g. transmission to ensure compatibility, but probably not before alpha release.

    • [x] set up 1 cratetorrent peer to seed a file
    • [x] set up 1 cratetorrent peer to download same file (can reuse existing test for the most part)
    enhancement 
    opened by mandreyel 1
  • Optimize download performance

    Optimize download performance

    This issue tracks potential ways to speed up downloads.

    • [x] Request pipelining. Done to a basic extent (fixed pipeline size).
    • [x] Self-adjusting request queue size. We should always keep the download pipeline at capacity to ensure we don't waste bandwidth.
    • [x] TCP like slow-start to reach optimal request queue size as fast as possible. The problem here is that if we linearly increment the request queue size, for fast links we would waste performance instead of ramping up the download rate exponentially.
    • [x] Batch disk writes. This is done for the most part but configurability and maybe self-adjustment would be great.
    • [x] Request timeouts, which are important when there are multiple peers with the same piece. If a peer has it but times out, we can try to download it from another peer faster. (#18)
    • [x] Share downloads. This way, a piece may be completed faster if downloaded from multiple peers, resulting in fewer unfinished pieces overall. It's also important for end game mode. (#45)
    • [x] End game mode: here for the last n pieces (for a small n, possibly n = 1), we request all blocks from all peers (that have it), so that we're not stalled on a single peer to finish the download. If we receive a block, we send a cancel request to other peers. (#70)
    meta optimization 
    opened by mandreyel 1
  • Can't build due to yanked bitvec dependency

    Can't build due to yanked bitvec dependency

    This crate depends on bitvec = "0.22" which depends on funty = "1.2", which has been yanked. Because of this, it's currently not possible to build the crate.

    It might be worth upgrading to bitvec to 1.0. From my simple skim over, it looks like the only required change would be to flip the type parameters for Bitfield from:

    pub type Bitfield = BitVec<Msb0, u8>;
    

    to

    pub type Bitfield = BitVec<u8, Msb0>;
    
    opened by ansg191 0
  • CLI not working

    CLI not working

    https://github.com/mandreyel/cratetorrent#binary

    Tried to run the CLI command from above, the UI also appears. but the download doesn't start and gets stuck at 0%

    OS -> WSL(Ubuntu)

    opened by muddlebee 1
  • CLI not appearing

    CLI not appearing

    Running this command: cargo run --release -p cratetorrent-cli -- --metainfo ./test.torrent --download-dir ~/Downloads

    Yields the following result and nothing happens:

        Finished release [optimized] target(s) in 0.09s
         Running `target/release/cratetorrent-cli --metainfo ./test.torrent --download-dir /home/vscode/Downloads
    

    there are no errors, and the file isn't downloaded either. Can something be blocking its progress, like port issues etc. ?

    opened by nikita-fuchs 0
  • Implement tracker error timeout

    Implement tracker error timeout

    Let me know if you think the approach is valid or if there's something you would like to be changed (e.g. variable names).

    I still need to add the documentation comments.

    I tried compiling the test CLI to run the integration tests but I got the following error:

    error[E0599]: the method `next` exists for struct `tokio::sync::mpsc::unbounded::UnboundedReceiver<cratetorrent::alert::Alert>`, but its trait bounds were not satisfied
      --> src/main.rs:72:38
       |
    72 |     while let Some(alert) = alert_rx.next().await {
       |                                      ^^^^ method cannot be called on `tokio::sync::mpsc::unbounded::UnboundedReceiver<cratetorrent::alert::Alert>` due to unsatisfied trait bounds
    
    opened by Awkor 0
Owner
null
BitTorrent peer ID registry/parser/(soon) encoder for Rust

BitTorrent peer ID registry/parser/(soon) encoder By convention, BitTorrent clients identify themselves and their versions in peer IDs they send to tr

TORRENTDYNE 3 Oct 16, 2023
A multi-functional lightweight BitTorrent Tracker

Torrust-Axum Tracker Project Description Torrust-Axum Tracker is a lightweight but incredibly powerful and feature-rich BitTorrent Tracker made using

Jasper 55 Apr 21, 2023
Simple CLI to manage your systemd clash.service and config subscriptions on Linux.

clashrup Simple CLI to manage your systemd clash.service and config subscriptions on Linux. Setup, update, apply overrides, and manage via systemctl.

Spencer (Shangbo Wu) 44 Jan 29, 2023
BLEZ - Asynchronous Bluetooth Low Energy on Linux for Rust

BLEZ - Asynchronous Bluetooth Low Energy on Linux for Rust This library provides an asynchronous, fully featured interface to the Bluetooth Low Energy

Sebastian Urban 40 Oct 21, 2021
Interactive bind/reverse PTY shell with Windows&Linux support implementation by Rust.

Cliws Lightweight interactive bind/reverse PTY shell with Windows&Linux support implementation by Rust. Features WebSocket Full pty support: VIM, SSH,

b23r0 215 Dec 3, 2021
Listen to bluetooth headphone keys (Linux only)

What Take action when you use your bluetooth headphone to indicate pause, play, next or previous. For Linux only. Why You can bind global keys to XF86

依云 8 Dec 30, 2022
pam-send-slack-message is a program that publishes messages on slack when a linux server is accessed through ssh.

pam-send-slack-message pam-send-slack-message is a program that publishes messages on slack when the linux server is accessed through ssh. Installatio

Iuri Diniz 2 Aug 17, 2022
A metrics collection application for Linux machines. Created for MSCS 710 Project at Marist College.

Linux-Metrics-Collector A metrics collection application for Linux machines. Created for MSCS 710 Project at Marist College. Development Environment S

Christopher Ravosa 2 May 2, 2022
Asynchronous Linux SocketCAN - Broadcast Manager support (BCM) with tokio

tokio-socketcan-bcm The Broadcast Manager protocol provides a command based configuration interface to filter and send (e.g. cyclic) CAN messages in k

Marcel 4 Nov 8, 2022
A transparent QUIC to SOCKSv5 proxy on Linux, UDP/QUIC verison of moproxy.

quproxy A transparent QUIC to SOCKSv5 proxy on Linux, UDP/QUIC verison of moproxy. ?? WORKING IN PROGRESS ?? Features: Transparent forward QUIC to ups

Shell Chen 4 Dec 15, 2022
Afterglow-Server provides back-end APIs for the Afterglow workflow engine.

Afterglow-Server ?? Note: This project is still heavily in development and is at an early stage. Afterglow-Server provides back-end APIs for the After

梦歆 0 Jun 2, 2022
The open source distributed web search engine that searches by meaning.

DawnSearch DawnSearch is an open source distributed web search engine that searches by meaning. It uses semantic search (searching on meaning), using

DawnSearch 4 Aug 8, 2023
The gRPC library for Rust built on C Core library and futures

gRPC-rs gRPC-rs is a Rust wrapper of gRPC Core. gRPC is a high performance, open source universal RPC framework that puts mobile and HTTP/2 first. Sta

TiKV Project 1.6k Jan 7, 2023
A µTP (Micro/uTorrent Transport Library) library implemented in Rust

rust-utp A Micro Transport Protocol library implemented in Rust. API documentation Overview The Micro Transport Protocol is a reliable transport proto

Ricardo Martins 134 Dec 11, 2022
A simple web server(and library) to display server stats over HTTP and Websockets/SSE or stream it to other systems.

x-server-stats A simple web server(and library) to display server stats over HTTP and Websockets/SSE or stream it to other systems. x-server(in x-serv

Pratyaksh 11 Oct 17, 2022
A Rust compiler plugin and support library to annotate overflow behavior

overflower This project contains a compiler plugin and supporting library to allow the programmer to annotate their code to declare how integer overfl

null 104 Nov 28, 2022
Rust library for A-law and μ-law (mu-law) audio encoding.

law-encoder ⚖️️‍️law-encoder??‍⚖ is a Rust library for A-law and μ-law (mu-law) audio encoding. These encoding schemes are defined in ITU-T standards

Beric Bearnson 5 Feb 7, 2024
Library + CLI-Tool to measure the TTFB (time to first byte) of HTTP requests. Additionally, this crate measures the times of DNS lookup, TCP connect and TLS handshake.

TTFB: CLI + Lib to Measure the TTFB of HTTP/1.1 Requests Similar to the network tab in Google Chrome or Mozilla Firefox, this crate helps you find the

Philipp Schuster 24 Dec 1, 2022
Tachyon is a performant and highly parallel reliable udp library that uses a nack based model

Tachyon Tachyon is a performant and highly parallel reliable udp library that uses a nack based model. Strongly reliable Reliable fragmentation Ordere

Chris Ochs 47 Oct 15, 2022