stresser/
main.rs

1#![doc = include_str!("../README.md")]
2#![deny(
3    rustdoc::broken_intra_doc_links,
4    rustdoc::private_intra_doc_links,
5    rustdoc::missing_crate_level_docs,
6    rustdoc::invalid_codeblock_attributes,
7    rustdoc::invalid_rust_codeblocks,
8    rustdoc::bare_urls,
9    rustdoc::invalid_html_tags
10)]
11#![warn(
12    trivial_casts,
13    trivial_numeric_casts,
14    unused_lifetimes,
15    unused_import_braces,
16    clippy::dbg_macro
17)]
18
19use core::time::Duration;
20use std::net::ToSocketAddrs;
21use std::sync::Arc;
22
23use args::StresserArgs;
24use clap::Parser;
25use stresser::{make_session, SessionParams};
26use tokio::sync::Semaphore;
27
28mod args;
29pub mod stresser;
30
31#[tokio::main]
32async fn main() {
33    let args = StresserArgs::parse();
34
35    let target_addr = args.target_host.to_socket_addrs().unwrap().next().unwrap();
36
37    let mut session_index: usize = 0;
38
39    let sema = Arc::new(Semaphore::new(args.sessions_count));
40
41    while let Ok(perm) = sema.clone().acquire_owned().await {
42        let session_name = format!("{}{}", args.name_prefix, session_index);
43
44        tokio::spawn(async move {
45            let params = SessionParams {
46                socket_addr: target_addr,
47                session_name: session_name.as_str(),
48                read_buffer_size: args.read_buffer_size,
49            };
50
51            if let Err(err) = make_session(&params).await {
52                eprintln!("Session {session_name} interrupted with error: {err}")
53            };
54
55            drop(perm);
56        });
57
58        session_index += 1;
59
60        tokio::time::sleep(Duration::from_millis(args.spawn_cooldown)).await;
61    }
62}