mirror of
https://github.com/YGGverse/aquatic.git
synced 2026-03-31 17:55:36 +00:00
Merge pull request #4 from greatest-ape/ws-file-transfer-ci
Add CI for WebTorrent file transfer, upgrade dependencies
This commit is contained in:
commit
c2e47d6fab
11 changed files with 147 additions and 52 deletions
|
|
@ -1,5 +1,5 @@
|
|||
# Container image that runs your code
|
||||
FROM rust:latest
|
||||
FROM rust:bullseye
|
||||
|
||||
# Copies your code file from your action repository to the filesystem path `/` of the container
|
||||
COPY entrypoint.sh /entrypoint.sh
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
name: 'test-transfer-http-udp'
|
||||
description: 'test aquatic http and udp file transfer'
|
||||
name: 'test-transfer'
|
||||
description: 'test aquatic file transfer'
|
||||
outputs:
|
||||
http_ipv4:
|
||||
description: 'HTTP IPv4 status'
|
||||
|
|
@ -7,6 +7,8 @@ outputs:
|
|||
description: 'HTTP IPv4 over TLS status'
|
||||
udp_ipv4:
|
||||
description: 'UDP IPv4 status'
|
||||
wss_ipv4:
|
||||
description: 'WSS IPv4 status'
|
||||
runs:
|
||||
using: 'docker'
|
||||
image: 'Dockerfile'
|
||||
|
|
@ -1,10 +1,15 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Test that file transfers work with aquatic_http (with and without TLS)
|
||||
# and aquatic_udp.
|
||||
# aquatic_udp and experimentally aquatic_ws (with TLS).
|
||||
#
|
||||
# IPv6 is unfortunately disabled by default in Docker
|
||||
# (see sysctl net.ipv6.conf.lo.disable_ipv6)
|
||||
#
|
||||
# When testing locally, use:
|
||||
# 1. docker build -t aquatic ./path/to/Dockerfile
|
||||
# 2. docker run aquatic
|
||||
# 3. On failure, run `docker rmi aquatic -f` and go back to step 1
|
||||
|
||||
set -e
|
||||
|
||||
|
|
@ -17,9 +22,14 @@ else
|
|||
fi
|
||||
|
||||
$SUDO apt-get update
|
||||
$SUDO apt-get install -y cmake libssl-dev screen rtorrent mktorrent ssl-cert ca-certificates
|
||||
$SUDO apt-get install -y cmake libssl-dev screen rtorrent mktorrent ssl-cert ca-certificates curl golang
|
||||
|
||||
rtorrent -h
|
||||
git clone https://github.com/anacrolix/torrent.git gotorrent
|
||||
cd gotorrent
|
||||
git checkout 16176b762e4a840fc5dfe3b1dfd2d6fa853b68d7
|
||||
go build -o $HOME/gotorrent ./cmd/torrent
|
||||
cd ..
|
||||
file $HOME/gotorrent
|
||||
|
||||
# Clone repository if necessary, go to repository directory
|
||||
|
||||
|
|
@ -70,6 +80,16 @@ echo "[network]
|
|||
address = '127.0.0.1:3000'" > udp.toml
|
||||
./target/debug/aquatic udp -c udp.toml > "$HOME/udp.log" 2>&1 &
|
||||
|
||||
echo "log_level = 'trace'
|
||||
|
||||
[network]
|
||||
address = '127.0.0.1:3002'
|
||||
use_tls = true
|
||||
tls_pkcs12_path = './identity.pfx'
|
||||
tls_pkcs12_password = 'p'
|
||||
" > ws.toml
|
||||
./target/debug/aquatic ws -c ws.toml > "$HOME/wss.log" 2>&1 &
|
||||
|
||||
# Setup directories
|
||||
|
||||
cd "$HOME"
|
||||
|
|
@ -83,25 +103,37 @@ mkdir torrents
|
|||
echo "http-test-ipv4" > seed/http-test-ipv4
|
||||
echo "tls-test-ipv4" > seed/tls-test-ipv4
|
||||
echo "udp-test-ipv4" > seed/udp-test-ipv4
|
||||
echo "wss-test-ipv4" > seed/wss-test-ipv4
|
||||
|
||||
mktorrent -p -o "torrents/http-ipv4.torrent" -a "http://127.0.0.1:3000/announce" "seed/http-test-ipv4"
|
||||
mktorrent -p -o "torrents/tls-ipv4.torrent" -a "https://example.com:3001/announce" "seed/tls-test-ipv4"
|
||||
mktorrent -p -o "torrents/udp-ipv4.torrent" -a "udp://127.0.0.1:3000" "seed/udp-test-ipv4"
|
||||
mktorrent -p -o "torrents/wss-ipv4.torrent" -a "wss://example.com:3002" "seed/wss-test-ipv4"
|
||||
|
||||
cp -r torrents torrents-seed
|
||||
cp -r torrents torrents-leech
|
||||
|
||||
# Start seeding client
|
||||
# Setup wss seeding client
|
||||
|
||||
echo "Starting seeding wss client"
|
||||
cd seed
|
||||
GOPPROF=http GODEBUG=x509ignoreCN=0 $HOME/gotorrent download --dht=false --tcppeers=false --utppeers=false --pex=false --stats --seed ../torrents/wss-ipv4.torrent > "$HOME/wss-seed.log" 2>&1 &
|
||||
cd ..
|
||||
|
||||
# Start seeding rtorrent client
|
||||
|
||||
echo "directory.default.set = $HOME/seed
|
||||
schedule2 = watch_directory,5,5,load.start=$HOME/torrents-seed/*.torrent" > ~/.rtorrent.rc
|
||||
|
||||
echo "Starting seeding client"
|
||||
echo "Starting seeding rtorrent client"
|
||||
screen -dmS rtorrent-seed rtorrent
|
||||
|
||||
sleep 10 # Give seeding rtorrent time to load its config file
|
||||
# Give seeding clients time to load config files etc
|
||||
|
||||
# Start leeching client
|
||||
echo "Waiting for a while"
|
||||
sleep 30
|
||||
|
||||
# Start leeching clients
|
||||
|
||||
echo "directory.default.set = $HOME/leech
|
||||
schedule2 = watch_directory,5,5,load.start=$HOME/torrents-leech/*.torrent" > ~/.rtorrent.rc
|
||||
|
|
@ -109,35 +141,58 @@ schedule2 = watch_directory,5,5,load.start=$HOME/torrents-leech/*.torrent" > ~/.
|
|||
echo "Starting leeching client.."
|
||||
screen -dmS rtorrent-leech rtorrent
|
||||
|
||||
echo "Starting leeching wss client"
|
||||
cd leech
|
||||
GOPPROF=http GODEBUG=x509ignoreCN=0 $HOME/gotorrent download --dht=false --tcppeers=false --utppeers=false --pex=false --stats --addr ":43000" ../torrents/wss-ipv4.torrent > "$HOME/wss-leech.log" 2>&1 &
|
||||
cd ..
|
||||
|
||||
# Check for completion
|
||||
|
||||
HTTP_IPv4="Failed"
|
||||
TLS_IPv4="Failed"
|
||||
UDP_IPv4="Failed"
|
||||
WSS_IPv4="Failed"
|
||||
|
||||
i="0"
|
||||
|
||||
echo "Watching for finished files.."
|
||||
|
||||
while [ $i -lt 300 ]
|
||||
while [ $i -lt 60 ]
|
||||
do
|
||||
if test -f "leech/http-test-ipv4"; then
|
||||
if grep -q "http-test-ipv4" "leech/http-test-ipv4"; then
|
||||
HTTP_IPv4="Ok"
|
||||
if [ "$HTTP_IPv4" != "Ok" ]; then
|
||||
HTTP_IPv4="Ok"
|
||||
echo "HTTP_IPv4 is Ok"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if test -f "leech/tls-test-ipv4"; then
|
||||
if grep -q "tls-test-ipv4" "leech/tls-test-ipv4"; then
|
||||
TLS_IPv4="Ok"
|
||||
if [ "$TLS_IPv4" != "Ok" ]; then
|
||||
TLS_IPv4="Ok"
|
||||
echo "TLS_IPv4 is Ok"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if test -f "leech/udp-test-ipv4"; then
|
||||
if grep -q "udp-test-ipv4" "leech/udp-test-ipv4"; then
|
||||
UDP_IPv4="Ok"
|
||||
if [ "$UDP_IPv4" != "Ok" ]; then
|
||||
UDP_IPv4="Ok"
|
||||
echo "UDP_IPv4 is Ok"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if test -f "leech/wss-test-ipv4"; then
|
||||
if grep -q "wss-test-ipv4" "leech/wss-test-ipv4"; then
|
||||
if [ "$WSS_IPv4" != "Ok" ]; then
|
||||
WSS_IPv4="Ok"
|
||||
echo "WSS_IPv4 is Ok"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$HTTP_IPv4" = "Ok" ] && [ "$TLS_IPv4" = "Ok" ] && [ "$UDP_IPv4" = "Ok" ]; then
|
||||
if [ "$HTTP_IPv4" = "Ok" ] && [ "$TLS_IPv4" = "Ok" ] && [ "$UDP_IPv4" = "Ok" ] && [ "$WSS_IPv4" = "Ok" ]; then
|
||||
break
|
||||
fi
|
||||
|
||||
|
|
@ -151,25 +206,51 @@ echo "Waited for $i seconds"
|
|||
echo "::set-output name=http_ipv4::$HTTP_IPv4"
|
||||
echo "::set-output name=http_tls_ipv4::$TLS_IPv4"
|
||||
echo "::set-output name=udp_ipv4::$UDP_IPv4"
|
||||
echo "::set-output name=wss_ipv4::$WSS_IPv4"
|
||||
|
||||
echo ""
|
||||
echo "# --- HTTP log --- #"
|
||||
cat "http.log"
|
||||
|
||||
sleep 1
|
||||
|
||||
echo ""
|
||||
echo "# --- HTTP over TLS log --- #"
|
||||
cat "tls.log"
|
||||
|
||||
sleep 1
|
||||
|
||||
echo ""
|
||||
echo "# --- UDP log --- #"
|
||||
cat "udp.log"
|
||||
|
||||
sleep 1
|
||||
|
||||
echo ""
|
||||
echo "# --- WSS tracker log --- #"
|
||||
cat "wss.log"
|
||||
|
||||
sleep 1
|
||||
|
||||
echo ""
|
||||
echo "# --- WSS seed log --- #"
|
||||
cat "wss-seed.log"
|
||||
|
||||
sleep 1
|
||||
|
||||
echo ""
|
||||
echo "# --- WSS leech log --- #"
|
||||
cat "wss-leech.log"
|
||||
|
||||
sleep 1
|
||||
|
||||
echo ""
|
||||
echo "# --- Test results --- #"
|
||||
echo "HTTP (IPv4): $HTTP_IPv4"
|
||||
echo "HTTP over TLS (IPv4): $TLS_IPv4"
|
||||
echo "UDP (IPv4): $UDP_IPv4"
|
||||
echo "WSS (IPv4): $WSS_IPv4"
|
||||
|
||||
if [ "$HTTP_IPv4" != "Ok" ] || [ "$TLS_IPv4" != "Ok" ] || [ "$UDP_IPv4" != "Ok" ]; then
|
||||
if [ "$HTTP_IPv4" != "Ok" ] || [ "$TLS_IPv4" != "Ok" ] || [ "$UDP_IPv4" != "Ok" ] || [ "$WSS_IPv4" != "Ok" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
name: "Test HTTP and UDP file transfer"
|
||||
name: "Test HTTP, UDP and WSS file transfer"
|
||||
|
||||
on:
|
||||
push:
|
||||
|
|
@ -9,10 +9,10 @@ on:
|
|||
jobs:
|
||||
test-transfer-http:
|
||||
runs-on: ubuntu-latest
|
||||
name: "Test BitTorrent file transfer over HTTP (with and without TLS) and UDP"
|
||||
name: "Test BitTorrent file transfer over HTTP (with and without TLS), UDP and WSS"
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Test file transfers
|
||||
uses: ./.github/actions/test-transfer-http-udp
|
||||
id: test_transfer_udp_http
|
||||
uses: ./.github/actions/test-transfer
|
||||
id: test_transfer
|
||||
19
Cargo.lock
generated
19
Cargo.lock
generated
|
|
@ -337,9 +337,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.1"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2da1976d75adbe5fbc88130ecd119529cf1cc6a93ae1546d8696ee66f0d21af1"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
|
|
@ -792,15 +792,6 @@ dependencies = [
|
|||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "input_buffer"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f97967975f448f1a7ddb12b0bc41069d09ed6a1c161a92687e057325db35d413"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.10"
|
||||
|
|
@ -1675,18 +1666,16 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tungstenite"
|
||||
version = "0.13.0"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fe8dada8c1a3aeca77d6b51a4f1314e0f4b8e438b7b1b71e3ddaca8080e4093"
|
||||
checksum = "983d40747bce878d2fb67d910dcb8bd3eca2b2358540c3cc1b98c027407a3ae3"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"byteorder",
|
||||
"bytes",
|
||||
"http",
|
||||
"httparse",
|
||||
"input_buffer",
|
||||
"log",
|
||||
"native-tls",
|
||||
"rand",
|
||||
"sha-1",
|
||||
"thiserror",
|
||||
|
|
|
|||
16
README.md
16
README.md
|
|
@ -17,10 +17,12 @@ Distributed under Apache 2.0 license (details in `LICENSE` file.)
|
|||
## Technical overview of tracker design
|
||||
|
||||
One or more socket workers open sockets, read and parse requests from peers and
|
||||
send them through channels to request workers. They in turn go through the
|
||||
requests, update internal state as appropriate and generate responses, which
|
||||
are sent back to the socket workers, which serialize them and send them to
|
||||
peers. This design means little waiting for locks on internal state occurs,
|
||||
send them through channels to request workers. The request workers go through
|
||||
the requests, update shared internal tracker state as appropriate and generate
|
||||
responses that are sent back to the socket workers. The responses are then
|
||||
serialized and sent back to the peers.
|
||||
|
||||
This design means little waiting for locks on internal state occurs,
|
||||
while network work can be efficiently distributed over multiple threads,
|
||||
making use of SO_REUSEPORT setting.
|
||||
|
||||
|
|
@ -149,11 +151,7 @@ exceptions:
|
|||
For information about running over TLS, please refer to the TLS subsection
|
||||
of the `aquatic_http` section above.
|
||||
|
||||
`aquatic_ws` is experimental software. Connections are established
|
||||
successfully when using `aquatic_ws_load_test`, but so far, I haven't been able
|
||||
to implement CI for testing if aquatic_ws works as the tracker for a full
|
||||
file transfer session between two real-world clients. One reason for this
|
||||
is the general lack of high-quality WebTorrent clients.
|
||||
`aquatic_ws` is experimental software.
|
||||
|
||||
## Load testing
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ privdrop = "0.5"
|
|||
rand = { version = "0.8", features = ["small_rng"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
socket2 = { version = "0.4.1", features = ["all"] }
|
||||
tungstenite = "0.13"
|
||||
tungstenite = "0.15"
|
||||
|
||||
[dev-dependencies]
|
||||
quickcheck = "1.0"
|
||||
|
|
|
|||
|
|
@ -118,6 +118,8 @@ pub fn handle_announce_requests(
|
|||
}
|
||||
}
|
||||
|
||||
::log::trace!("received request from {:?}", request_sender_meta);
|
||||
|
||||
// Insert/update/remove peer who sent this request
|
||||
{
|
||||
let peer_status = PeerStatus::from_event_and_bytes_left(
|
||||
|
|
@ -187,6 +189,10 @@ pub fn handle_announce_requests(
|
|||
offer_receiver.connection_meta,
|
||||
OutMessage::Offer(middleman_offer),
|
||||
);
|
||||
::log::trace!(
|
||||
"sent middleman offer to {:?}",
|
||||
offer_receiver.connection_meta
|
||||
);
|
||||
wake_socket_workers[offer_receiver.connection_meta.worker_index] = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -208,6 +214,10 @@ pub fn handle_announce_requests(
|
|||
answer_receiver.connection_meta,
|
||||
OutMessage::Answer(middleman_answer),
|
||||
);
|
||||
::log::trace!(
|
||||
"sent middleman answer to {:?}",
|
||||
answer_receiver.connection_meta
|
||||
);
|
||||
wake_socket_workers[answer_receiver.connection_meta.worker_index] = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use mio::{Poll, Token};
|
|||
use native_tls::{MidHandshakeTlsStream, TlsAcceptor, TlsStream};
|
||||
use tungstenite::handshake::{server::NoCallback, HandshakeError, MidHandshake};
|
||||
use tungstenite::protocol::WebSocketConfig;
|
||||
use tungstenite::server::ServerHandshake;
|
||||
use tungstenite::ServerHandshake;
|
||||
use tungstenite::WebSocket;
|
||||
|
||||
use crate::common::*;
|
||||
|
|
@ -111,7 +111,7 @@ impl HandshakeMachine {
|
|||
if let Some(tls_acceptor) = opt_tls_acceptor {
|
||||
Self::handle_tls_handshake_result(tls_acceptor.accept(stream))
|
||||
} else {
|
||||
let handshake_result = ::tungstenite::server::accept_with_config(
|
||||
let handshake_result = ::tungstenite::accept_with_config(
|
||||
Stream::TcpStream(stream),
|
||||
Some(ws_config),
|
||||
);
|
||||
|
|
@ -120,7 +120,7 @@ impl HandshakeMachine {
|
|||
}
|
||||
}
|
||||
HandshakeMachine::TlsStream(stream) => {
|
||||
let handshake_result = ::tungstenite::server::accept(Stream::TlsStream(stream));
|
||||
let handshake_result = ::tungstenite::accept(Stream::TlsStream(stream));
|
||||
|
||||
Self::handle_ws_handshake_result(handshake_result)
|
||||
}
|
||||
|
|
@ -138,7 +138,14 @@ impl HandshakeMachine {
|
|||
result: Result<TlsStream<TcpStream>, ::native_tls::HandshakeError<TcpStream>>,
|
||||
) -> (Option<Either<EstablishedWs, Self>>, bool) {
|
||||
match result {
|
||||
Ok(stream) => (Some(Either::Right(Self::TlsStream(stream))), false),
|
||||
Ok(stream) => {
|
||||
::log::trace!(
|
||||
"established tls handshake with peer with addr: {:?}",
|
||||
stream.get_ref().peer_addr()
|
||||
);
|
||||
|
||||
(Some(Either::Right(Self::TlsStream(stream))), false)
|
||||
},
|
||||
Err(native_tls::HandshakeError::WouldBlock(handshake)) => {
|
||||
(Some(Either::Right(Self::TlsMidHandshake(handshake))), true)
|
||||
}
|
||||
|
|
@ -158,7 +165,15 @@ impl HandshakeMachine {
|
|||
Ok(mut ws) => {
|
||||
let peer_addr = ws.get_mut().get_peer_addr();
|
||||
|
||||
let established_ws = EstablishedWs { ws, peer_addr };
|
||||
::log::trace!(
|
||||
"established ws handshake with peer with addr: {:?}",
|
||||
peer_addr
|
||||
);
|
||||
|
||||
let established_ws = EstablishedWs {
|
||||
ws,
|
||||
peer_addr,
|
||||
};
|
||||
|
||||
(Some(Either::Left(established_ws)), false)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ rand_distr = "0.4"
|
|||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
slab = "0.4"
|
||||
tungstenite = "0.13"
|
||||
tungstenite = "0.15"
|
||||
|
||||
[dev-dependencies]
|
||||
quickcheck = "1.0"
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ hashbrown = { version = "0.11.2", features = ["serde"] }
|
|||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
simd-json = { version = "0.4.7", features = ["allow-non-simd"] }
|
||||
tungstenite = "0.13"
|
||||
tungstenite = "0.15"
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = "0.3"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue