Merge pull request #96 from greatest-ape/work-2022-10-09

ws: allow peers to use multiple PeerIds, but only one per torrent; update deps; improve CI file structure
This commit is contained in:
Joakim Frostegård 2022-10-09 22:50:02 +02:00 committed by GitHub
commit 7cb7366569
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 125 additions and 119 deletions

View file

@ -1,5 +1,5 @@
name: 'test-transfer' name: 'test-file-transfers'
description: 'test aquatic file transfer' description: 'test aquatic file transfers'
outputs: outputs:
# http_ipv4: # http_ipv4:
# description: 'HTTP IPv4 status' # description: 'HTTP IPv4 status'

View file

@ -1,4 +1,4 @@
name: 'cargo: build and test' name: CI
on: on:
push: push:
@ -10,9 +10,9 @@ env:
CARGO_TERM_COLOR: always CARGO_TERM_COLOR: always
jobs: jobs:
build-test-linux: build-linux:
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 25 timeout-minutes: 20
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Install latest stable Rust - name: Install latest stable Rust
@ -30,9 +30,6 @@ jobs:
cargo build --verbose -p aquatic_udp --features "cpu-pinning" cargo build --verbose -p aquatic_udp --features "cpu-pinning"
cargo build --verbose -p aquatic_http cargo build --verbose -p aquatic_http
cargo build --verbose -p aquatic_ws cargo build --verbose -p aquatic_ws
- name: Run tests
run: cargo test --verbose --workspace --profile "test-fast"
build-macos: build-macos:
runs-on: macos-latest runs-on: macos-latest
@ -49,3 +46,35 @@ jobs:
uses: Swatinem/rust-cache@v2 uses: Swatinem/rust-cache@v2
- name: Build - name: Build
run: cargo build --verbose -p aquatic_udp run: cargo build --verbose -p aquatic_udp
test:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v3
- name: Install latest stable Rust
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- name: Install dependencies
run: sudo apt-get update -y && sudo apt-get install libhwloc-dev -y
- name: Setup Rust dependency caching
uses: Swatinem/rust-cache@v2
- name: Run tests
run: cargo test --verbose --workspace --profile "test-fast"
test-file-transfers:
runs-on: ubuntu-latest
name: "Test BitTorrent file transfers over UDP, TLS and WSS"
timeout-minutes: 20
container:
image: rust:1-bullseye
options: --ulimit memlock=524288:524288
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Test file transfers
uses: ./.github/actions/test-file-transfers
id: test_file_transfers

View file

@ -1,22 +0,0 @@
name: "Test UDP, TLS and WSS file transfer"
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
test-transfer-http:
runs-on: ubuntu-latest
name: "Test BitTorrent file transfer over UDP, TLS and WSS"
timeout-minutes: 20
container:
image: rust:1-bullseye
options: --ulimit memlock=524288:524288
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Test file transfers
uses: ./.github/actions/test-transfer
id: test_transfer

95
Cargo.lock generated
View file

@ -107,7 +107,7 @@ dependencies = [
"futures-lite", "futures-lite",
"futures-rustls", "futures-rustls",
"glommio", "glommio",
"itoa 1.0.3", "itoa 1.0.4",
"libc", "libc",
"log", "log",
"memchr", "memchr",
@ -182,7 +182,7 @@ dependencies = [
"criterion", "criterion",
"hex", "hex",
"httparse", "httparse",
"itoa 1.0.3", "itoa 1.0.4",
"log", "log",
"memchr", "memchr",
"quickcheck", "quickcheck",
@ -462,7 +462,7 @@ dependencies = [
"http", "http",
"http-body", "http-body",
"hyper", "hyper",
"itoa 1.0.3", "itoa 1.0.4",
"matchit", "matchit",
"memchr", "memchr",
"mime", "mime",
@ -665,13 +665,13 @@ dependencies = [
[[package]] [[package]]
name = "console" name = "console"
version = "0.15.1" version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89eab4d20ce20cea182308bca13088fecea9c05f6776cf287205d41a0ed3c847" checksum = "c050367d967ced717c04b65d8c619d863ef9292ce0c5760028655a2fb298718c"
dependencies = [ dependencies = [
"encode_unicode", "encode_unicode",
"lazy_static",
"libc", "libc",
"once_cell",
"terminal_size", "terminal_size",
"winapi 0.3.9", "winapi 0.3.9",
] ]
@ -800,15 +800,14 @@ dependencies = [
[[package]] [[package]]
name = "crossbeam-epoch" name = "crossbeam-epoch"
version = "0.9.10" version = "0.9.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1" checksum = "f916dfc5d356b0ed9dae65f1db9fc9770aa2851d2662b988ccf4fe3516e86348"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"cfg-if", "cfg-if",
"crossbeam-utils", "crossbeam-utils",
"memoffset 0.6.5", "memoffset 0.6.5",
"once_cell",
"scopeguard", "scopeguard",
] ]
@ -824,12 +823,11 @@ dependencies = [
[[package]] [[package]]
name = "crossbeam-utils" name = "crossbeam-utils"
version = "0.8.11" version = "0.8.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"once_cell",
] ]
[[package]] [[package]]
@ -1409,7 +1407,7 @@ checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399"
dependencies = [ dependencies = [
"bytes", "bytes",
"fnv", "fnv",
"itoa 1.0.3", "itoa 1.0.4",
] ]
[[package]] [[package]]
@ -1470,7 +1468,7 @@ dependencies = [
"http-body", "http-body",
"httparse", "httparse",
"httpdate", "httpdate",
"itoa 1.0.3", "itoa 1.0.4",
"pin-project-lite", "pin-project-lite",
"socket2 0.4.7", "socket2 0.4.7",
"tokio", "tokio",
@ -1557,9 +1555,9 @@ checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.3" version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
[[package]] [[package]]
name = "js-sys" name = "js-sys"
@ -1591,9 +1589,9 @@ dependencies = [
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.133" version = "0.2.134"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966" checksum = "329c933548736bc49fd575ee68c89e8be4d260064184389a5b77517cddd99ffb"
[[package]] [[package]]
name = "libm" name = "libm"
@ -2114,9 +2112,9 @@ dependencies = [
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.44" version = "1.0.46"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7bd7356a8122b6c4a24a82b278680c73357984ca2fc79a0f9fa6dea7dced7c58" checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@ -2418,11 +2416,11 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.85" version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" checksum = "41feea4228a6f1cd09ec7a3593a682276702cd67b5273544757dae23c096f074"
dependencies = [ dependencies = [
"itoa 1.0.3", "itoa 1.0.4",
"ryu", "ryu",
"serde", "serde",
] ]
@ -2528,9 +2526,9 @@ dependencies = [
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.9.0" version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
[[package]] [[package]]
name = "smartstring" name = "smartstring"
@ -2635,7 +2633,7 @@ dependencies = [
"hashlink", "hashlink",
"hex", "hex",
"indexmap", "indexmap",
"itoa 1.0.3", "itoa 1.0.4",
"libc", "libc",
"log", "log",
"memchr", "memchr",
@ -2713,9 +2711,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.100" version = "1.0.102"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52205623b1b0f064a4e71182c3b18ae902267282930c6d5462c91b859668426e" checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -2761,18 +2759,18 @@ dependencies = [
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.36" version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a99cb8c4b9a8ef0e7907cd3b617cc8dc04d571c4e73c8ae403d80ac160bb122" checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "1.0.36" version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a891860d3c8d66fec8e73ddb3765f90082374dbaaa833407b904a94f1a7eb43" checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -2781,11 +2779,11 @@ dependencies = [
[[package]] [[package]]
name = "time" name = "time"
version = "0.3.14" version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c3f9a28b618c3a6b9251b6908e9c99e04b9e5c02e6581ccbb67d59c34ef7f9b" checksum = "d634a985c4d4238ec39cacaed2e7ae552fbd3c476b552c1deac3021b7d7eaf0c"
dependencies = [ dependencies = [
"itoa 1.0.3", "itoa 1.0.4",
"libc", "libc",
"num_threads", "num_threads",
"time-macros", "time-macros",
@ -2824,9 +2822,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.21.1" version = "1.21.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0020c875007ad96677dcc890298f4b942882c5d4eb7cc8f439fc3bf813dc9c95" checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"bytes", "bytes",
@ -2834,7 +2832,6 @@ dependencies = [
"memchr", "memchr",
"mio", "mio",
"num_cpus", "num_cpus",
"once_cell",
"parking_lot 0.12.1", "parking_lot 0.12.1",
"pin-project-lite", "pin-project-lite",
"signal-hook-registry", "signal-hook-registry",
@ -2934,9 +2931,9 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
[[package]] [[package]]
name = "tracing" name = "tracing"
version = "0.1.36" version = "0.1.37"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307" checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"log", "log",
@ -2947,9 +2944,9 @@ dependencies = [
[[package]] [[package]]
name = "tracing-attributes" name = "tracing-attributes"
version = "0.1.22" version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2" checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -2958,9 +2955,9 @@ dependencies = [
[[package]] [[package]]
name = "tracing-core" name = "tracing-core"
version = "0.1.29" version = "0.1.30"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7" checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"
dependencies = [ dependencies = [
"once_cell", "once_cell",
] ]
@ -3004,9 +3001,9 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.4" version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd" checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
[[package]] [[package]]
name = "unicode-normalization" name = "unicode-normalization"
@ -3078,7 +3075,7 @@ checksum = "c0a635407649b66e125e4d2ffd208153210179f8c7c8b71c030aa2ad3eeb4c8f"
dependencies = [ dependencies = [
"float-cmp", "float-cmp",
"halfbrown", "halfbrown",
"itoa 1.0.3", "itoa 1.0.4",
"ryu", "ryu",
] ]
@ -3197,9 +3194,9 @@ dependencies = [
[[package]] [[package]]
name = "webpki-roots" name = "webpki-roots"
version = "0.22.4" version = "0.22.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1c760f0d366a6c24a02ed7816e23e691f5d92291f94d15e836006fd11b04daf" checksum = "368bfe657969fb01238bb756d351dcade285e0f6fcbd36dcb23359a5169975be"
dependencies = [ dependencies = [
"webpki", "webpki",
] ]

View file

@ -1,6 +1,6 @@
# aquatic: high-performance open BitTorrent tracker # aquatic: high-performance open BitTorrent tracker
[![CargoBuildAndTest](https://github.com/greatest-ape/aquatic/actions/workflows/cargo-build-and-test.yml/badge.svg)](https://github.com/greatest-ape/aquatic/actions/workflows/cargo-build-and-test.yml) [![Test HTTP, UDP and WSS file transfer](https://github.com/greatest-ape/aquatic/actions/workflows/test-transfer.yml/badge.svg)](https://github.com/greatest-ape/aquatic/actions/workflows/test-transfer.yml) [![CI](https://github.com/greatest-ape/aquatic/actions/workflows/ci.yml/badge.svg)](https://github.com/greatest-ape/aquatic/actions/workflows/ci.yml)
High-performance open BitTorrent tracker, consisting High-performance open BitTorrent tracker, consisting
of sub-implementations for different protocols: of sub-implementations for different protocols:

View file

@ -24,7 +24,8 @@ use glommio::net::{TcpListener, TcpStream};
use glommio::task::JoinHandle; use glommio::task::JoinHandle;
use glommio::timer::{sleep, timeout, TimerActionRepeat}; use glommio::timer::{sleep, timeout, TimerActionRepeat};
use glommio::{enclose, prelude::*}; use glommio::{enclose, prelude::*};
use hashbrown::{HashMap, HashSet}; use hashbrown::hash_map::Entry;
use hashbrown::HashMap;
use slab::Slab; use slab::Slab;
use crate::config::Config; use crate::config::Config;
@ -45,8 +46,7 @@ struct ConnectionReference {
out_message_sender: Rc<LocalSender<(OutMessageMeta, OutMessage)>>, out_message_sender: Rc<LocalSender<(OutMessageMeta, OutMessage)>>,
/// Updated after sending message to peer /// Updated after sending message to peer
valid_until: ValidUntil, valid_until: ValidUntil,
peer_id: Option<PeerId>, announced_info_hashes: HashMap<InfoHash, PeerId>,
announced_info_hashes: HashSet<InfoHash>,
ip_version: IpVersion, ip_version: IpVersion,
} }
@ -145,7 +145,6 @@ pub async fn run_socket_worker(
server_start_instant, server_start_instant,
config.cleaning.max_connection_idle, config.cleaning.max_connection_idle,
), ),
peer_id: None,
announced_info_hashes: Default::default(), announced_info_hashes: Default::default(),
ip_version, ip_version,
}); });
@ -180,26 +179,24 @@ pub async fn run_socket_worker(
// Tell swarm workers to remove peer // Tell swarm workers to remove peer
if let Some(reference) = opt_reference { if let Some(reference) = opt_reference {
if let Some(peer_id) = reference.peer_id { for (info_hash, peer_id) in reference.announced_info_hashes {
for info_hash in reference.announced_info_hashes { let message = SwarmControlMessage::ConnectionClosed {
let message = SwarmControlMessage::ConnectionClosed { info_hash,
info_hash, peer_id,
peer_id, ip_version: reference.ip_version,
ip_version: reference.ip_version, };
};
let consumer_index = let consumer_index =
calculate_in_message_consumer_index(&config, info_hash); calculate_in_message_consumer_index(&config, info_hash);
// Only fails when receiver is closed // Only fails when receiver is closed
control_message_senders control_message_senders
.send_to( .send_to(
consumer_index, consumer_index,
message message
) )
.await .await
.unwrap(); .unwrap();
}
} }
} }
}), tq_regular) }), tq_regular)
@ -499,26 +496,31 @@ impl<S: futures::AsyncRead + futures::AsyncWrite + Unpin> ConnectionReader<S> {
})?; })?;
// Store peer id / check if stored peer id matches // Store peer id / check if stored peer id matches
match &mut connection_reference.peer_id { match connection_reference
Some(peer_id) if *peer_id != announce_request.peer_id => { .announced_info_hashes
self.send_error_response( .entry(announce_request.info_hash)
"Only one peer id can be used per connection".into(), {
Some(ErrorResponseAction::Announce), Entry::Occupied(entry) => {
Some(info_hash), if *entry.get() != announce_request.peer_id {
) // Drop Rc borrow before awaiting
.await?; drop(connection_slab);
return Err(anyhow::anyhow!("Peer used more than one PeerId"));
self.send_error_response(
"Only one peer id can be used per torrent".into(),
Some(ErrorResponseAction::Announce),
Some(info_hash),
)
.await?;
return Err(anyhow::anyhow!(
"Peer used more than one PeerId for a single torrent"
));
}
} }
Some(_) => (), Entry::Vacant(entry) => {
opt_peer_id @ None => { entry.insert(announce_request.peer_id);
*opt_peer_id = Some(announce_request.peer_id);
} }
} }
// Remember info hash for later
connection_reference
.announced_info_hashes
.insert(announce_request.info_hash);
} }
let in_message = InMessage::AnnounceRequest(announce_request); let in_message = InMessage::AnnounceRequest(announce_request);