udp: integration: add access list tests

This commit is contained in:
Joakim Frostegård 2023-08-27 19:04:43 +02:00
parent b2f2ecf5ef
commit 10cd6f9a38
3 changed files with 128 additions and 2 deletions

31
Cargo.lock generated
View file

@ -249,6 +249,7 @@ dependencies = [
"signal-hook", "signal-hook",
"slab", "slab",
"socket2 0.5.3", "socket2 0.5.3",
"tempfile",
"time", "time",
"tinytemplate", "tinytemplate",
] ]
@ -978,6 +979,12 @@ dependencies = [
"instant", "instant",
] ]
[[package]]
name = "fastrand"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764"
[[package]] [[package]]
name = "flate2" name = "flate2"
version = "1.0.27" version = "1.0.27"
@ -1079,7 +1086,7 @@ version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce"
dependencies = [ dependencies = [
"fastrand", "fastrand 1.9.0",
"futures-core", "futures-core",
"futures-io", "futures-io",
"memchr", "memchr",
@ -2203,6 +2210,15 @@ dependencies = [
"num_cpus", "num_cpus",
] ]
[[package]]
name = "redox_syscall"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
dependencies = [
"bitflags 1.3.2",
]
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.9.3" version = "1.9.3"
@ -2579,6 +2595,19 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "tempfile"
version = "3.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef"
dependencies = [
"cfg-if",
"fastrand 2.0.0",
"redox_syscall",
"rustix",
"windows-sys 0.48.0",
]
[[package]] [[package]]
name = "textwrap" name = "textwrap"
version = "0.16.0" version = "0.16.0"

View file

@ -55,5 +55,7 @@ time = { version = "0.3", features = ["formatting"] }
tinytemplate = "1" tinytemplate = "1"
[dev-dependencies] [dev-dependencies]
hex = "0.4"
tempfile = "3"
quickcheck = "1" quickcheck = "1"
quickcheck_macros = "1" quickcheck_macros = "1"

View file

@ -1,11 +1,13 @@
use std::{ use std::{
collections::{hash_map::RandomState, HashSet}, collections::{hash_map::RandomState, HashSet},
io::{Cursor, ErrorKind}, fs::File,
io::{Cursor, ErrorKind, Write},
net::{Ipv4Addr, SocketAddr, SocketAddrV4, UdpSocket}, net::{Ipv4Addr, SocketAddr, SocketAddrV4, UdpSocket},
time::Duration, time::Duration,
}; };
use anyhow::Context; use anyhow::Context;
use aquatic_common::access_list::AccessListMode;
use aquatic_udp::{common::BUFFER_SIZE, config::Config}; use aquatic_udp::{common::BUFFER_SIZE, config::Config};
use aquatic_udp_protocol::{ use aquatic_udp_protocol::{
common::PeerId, AnnounceEvent, AnnounceRequest, ConnectRequest, ConnectionId, InfoHash, common::PeerId, AnnounceEvent, AnnounceRequest, ConnectRequest, ConnectionId, InfoHash,
@ -157,6 +159,99 @@ fn test_announce_with_invalid_connection_id() -> anyhow::Result<()> {
} }
} }
#[test]
fn test_access_list_deny() -> anyhow::Result<()> {
const TRACKER_PORT: u16 = 40_113;
let deny = InfoHash([0; 20]);
let allow = InfoHash([1; 20]);
test_access_list(TRACKER_PORT, allow, deny, deny, AccessListMode::Deny)?;
Ok(())
}
#[test]
fn test_access_list_allow() -> anyhow::Result<()> {
const TRACKER_PORT: u16 = 40_114;
let allow = InfoHash([0; 20]);
let deny = InfoHash([1; 20]);
test_access_list(TRACKER_PORT, allow, deny, allow, AccessListMode::Allow)?;
Ok(())
}
fn test_access_list(
tracker_port: u16,
info_hash_success: InfoHash,
info_hash_fail: InfoHash,
info_hash_in_list: InfoHash,
mode: AccessListMode,
) -> anyhow::Result<()> {
let access_list_dir = tempfile::tempdir().with_context(|| "get temporary directory")?;
let access_list_path = access_list_dir.path().join("access-list.txt");
let mut access_list_file =
File::create(&access_list_path).with_context(|| "create access list file")?;
writeln!(
access_list_file,
"{}",
hex::encode_upper(info_hash_in_list.0)
)
.with_context(|| "write to access list file")?;
let mut config = Config::default();
config.network.address.set_port(tracker_port);
config.access_list.mode = mode;
config.access_list.path = access_list_path;
run_tracker(config);
let tracker_addr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::LOCALHOST, tracker_port));
let peer_addr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::LOCALHOST, 0));
let socket = UdpSocket::bind(peer_addr)?;
socket.set_read_timeout(Some(Duration::from_secs(1)))?;
let connection_id = connect(&socket, tracker_addr).with_context(|| "connect")?;
let response = announce(
&socket,
tracker_addr,
connection_id,
1,
info_hash_fail,
10,
false,
)
.with_context(|| "announce")?;
assert!(
matches!(response, Response::Error(_)),
"response should be error but is {:?}",
response
);
let response = announce(
&socket,
tracker_addr,
connection_id,
1,
info_hash_success,
10,
false,
)
.with_context(|| "announce")?;
assert!(matches!(response, Response::AnnounceIpv4(_)));
Ok(())
}
// FIXME: should ideally try different ports and use sync primitives to find // FIXME: should ideally try different ports and use sync primitives to find
// out if tracker was successfully started // out if tracker was successfully started
fn run_tracker(config: Config) { fn run_tracker(config: Config) {