From bca769111fafee76923bbc755287f022c623ea05 Mon Sep 17 00:00:00 2001 From: sakridge Date: Fri, 20 Mar 2020 12:55:38 -0700 Subject: [PATCH] Dos all the things (#8914) * Dos all the things * Use solana-dos for gossip dos test --- Cargo.lock | 15 +++ Cargo.toml | 1 + dos/Cargo.toml | 19 +++ dos/src/main.rs | 115 ++++++++++++++++++ scripts/cargo-install-all.sh | 1 + .../stability-testcases/gossip-dos-test.sh | 12 +- 6 files changed, 157 insertions(+), 6 deletions(-) create mode 100644 dos/Cargo.toml create mode 100644 dos/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 9ee3c1ee6d..523bbca1ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4007,6 +4007,21 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "solana-dos" +version = "1.1.0" +dependencies = [ + "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-core 1.1.0", + "solana-logger 1.1.0", + "solana-net-utils 1.1.0", + "solana-runtime 1.1.0", +] + [[package]] name = "solana-download-utils" version = "1.1.0" diff --git a/Cargo.toml b/Cargo.toml index f2700287ef..9b5be03613 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ members = [ "cli-config", "client", "core", + "dos", "download-utils", "faucet", "perf", diff --git a/dos/Cargo.toml b/dos/Cargo.toml new file mode 100644 index 0000000000..8bfc3fac93 --- /dev/null +++ b/dos/Cargo.toml @@ -0,0 +1,19 @@ +[package] +authors = ["Solana Maintainers "] +edition = "2018" +name = "solana-dos" +version = "1.1.0" +repository = "https://github.com/solana-labs/solana" +license = "Apache-2.0" +homepage = "https://solana.com/" + +[dependencies] +bincode = "1.2.1" +clap = "2.33.0" +log = "0.4.8" +rand = "0.6.5" +rayon = "1.3.0" +solana-core = { path = "../core", version = "1.1.0" } +solana-logger = { path = "../logger", version = "1.1.0" } +solana-net-utils = { path = "../net-utils", version = "1.1.0" } +solana-runtime = { path = "../runtime", version = "1.1.0" } diff --git a/dos/src/main.rs b/dos/src/main.rs new file mode 100644 index 0000000000..84770150cf --- /dev/null +++ b/dos/src/main.rs @@ -0,0 +1,115 @@ +use clap::{value_t, value_t_or_exit, App, Arg}; +use log::*; +use rand::{thread_rng, Rng}; +use solana_core::gossip_service::discover_cluster; +use std::net::{SocketAddr, UdpSocket}; +use std::process::exit; +use std::time::Instant; + +fn main() { + solana_logger::setup(); + let matches = App::new("crate") + .about("about") + .version("version") + .arg( + Arg::with_name("entrypoint") + .long("entrypoint") + .takes_value(true) + .value_name("HOST:PORT") + .help("Gossip entrypoint address. Usually :8001"), + ) + .arg( + Arg::with_name("num_nodes") + .long("num_nodes") + .takes_value(true) + .value_name("NUM") + .help("Number of gossip nodes to look for."), + ) + .arg( + Arg::with_name("mode") + .long("mode") + .takes_value(true) + .value_name("DOS_MODE") + .help( + "Interface to dos.\n\ + Valid values: gossip, tvu, tvu_forwards, tpu,\n\ + tpu_forwards, repair, serve_repair", + ), + ) + .arg( + Arg::with_name("data_size") + .long("data_size") + .takes_value(true) + .value_name("SIZE_BYTES") + .help("Size of packet to dos with."), + ) + .arg( + Arg::with_name("random_data") + .long("random_data") + .takes_value(false) + .help("Use random data for each iteration."), + ) + .get_matches(); + + let mut entrypoint_addr = SocketAddr::from(([127, 0, 0, 1], 8001)); + if let Some(addr) = matches.value_of("entrypoint") { + entrypoint_addr = solana_net_utils::parse_host_port(addr).unwrap_or_else(|e| { + eprintln!("failed to parse entrypoint address: {}", e); + exit(1) + }); + } + let num_nodes = value_t!(matches, "num_nodes", usize).unwrap_or(1); + let data_size = value_t!(matches, "data_size", usize).unwrap_or(128); + let random_data = matches.is_present("random_data"); + + let mode = value_t_or_exit!(matches, "mode", String); + + info!("Finding cluster entry: {:?}", entrypoint_addr); + let (nodes, _archivers) = discover_cluster(&entrypoint_addr, num_nodes).unwrap_or_else(|err| { + eprintln!("Failed to discover {} nodes: {:?}", num_nodes, err); + exit(1); + }); + + info!("done found {} nodes", nodes.len()); + + let mut target = None; + for node in &nodes { + if node.gossip == entrypoint_addr { + target = match mode.as_str() { + "gossip" => Some(node.gossip), + "tvu" => Some(node.tvu), + "tvu_forwards" => Some(node.tvu_forwards), + "tpu" => Some(node.tpu), + "tpu_forwards" => Some(node.tpu_forwards), + "repair" => Some(node.repair), + "serve_repair" => Some(node.serve_repair), + &_ => panic!("Unknown mode"), + }; + break; + } + } + let target = target.expect("should have target"); + + info!("Targetting {}", target); + let socket = UdpSocket::bind("0.0.0.0:0").unwrap(); + let mut data = vec![0u8; data_size]; + thread_rng().fill(&mut data[..]); + let mut last_log = Instant::now(); + let mut count = 0; + let mut error_count = 0; + loop { + if random_data { + thread_rng().fill(&mut data[..]); + } + let res = socket.send_to(&data, target); + count += 1; + if res.is_err() { + error_count += 1; + } + if last_log.elapsed().as_secs() > 5 { + info!("count: {} errors: {}", count, error_count); + last_log = Instant::now(); + count = 0; + } + } +} diff --git a/scripts/cargo-install-all.sh b/scripts/cargo-install-all.sh index 0e35cbae2d..8ecf55b3cc 100755 --- a/scripts/cargo-install-all.sh +++ b/scripts/cargo-install-all.sh @@ -87,6 +87,7 @@ else solana solana-bench-exchange solana-bench-tps + solana-dos solana-faucet solana-gossip solana-install diff --git a/system-test/stability-testcases/gossip-dos-test.sh b/system-test/stability-testcases/gossip-dos-test.sh index 73c082409b..e35c5dace3 100755 --- a/system-test/stability-testcases/gossip-dos-test.sh +++ b/system-test/stability-testcases/gossip-dos-test.sh @@ -37,9 +37,9 @@ solana-gossip spy --gossip-port 8001 > "$logDir"/gossip.log 2>&1 & solanaGossipPid=$! echo "solana-gossip pid: $solanaGossipPid" sleep 5 -dd if=/dev/zero bs=1232 > /dev/udp/127.0.0.1/8001 & -ddPid=$! -echo "dd pid: $ddPid" +solana-dos --mode gossip & +dosPid=$! +echo "solana-dos pid: $dosPid" pass=true @@ -50,8 +50,8 @@ while ((SECONDS < 600)); do pass=false break fi - if ! kill -0 $ddPid; then - echo "dd is no longer running after $SECONDS seconds" + if ! kill -0 $dosPid; then + echo "solana-dos is no longer running after $SECONDS seconds" pass=false break fi @@ -59,7 +59,7 @@ while ((SECONDS < 600)); do done kill $solanaGossipPid || true -kill $ddPid || true +kill $dosPid || true wait || true $pass && echo Pass