Prettier resultsé
All checks were successful
Rust-build / build (push) Successful in 2m19s

This commit is contained in:
Justine Pelletreau 2023-07-22 18:56:21 +02:00
parent 53c405b7a6
commit dd430b1b2c
6 changed files with 82 additions and 40 deletions

View File

@ -47,4 +47,3 @@ jobs:
- name: Build
run: cargo build --release

View File

@ -4,7 +4,6 @@ Portnut is a port stressing / scanning multithreaded utility. It can handle raw
# TODO
* Make a distributed version that allows stressing from multiple computers at the same time
* When TCP stress testing, show results for each port.
* Return more stats (low 1%, high 1%)
* Automated releases

View File

@ -5,12 +5,6 @@ use std::sync::mpsc;
use crate::results::*;
fn print_results(res: Vec<StressResult>) {
let myres = ListOfResults { results: res };
myres.show_ratio();
println!("\tMean answer time : {:?}", myres.get_mean_time());
}
pub fn http_stress(url: String, interval: Duration, sleep: Duration, threads: u32) -> std::io::Result<()> {
let mut handles = vec![];
@ -18,7 +12,7 @@ pub fn http_stress(url: String, interval: Duration, sleep: Duration, threads: u3
println!("Threads starting their {:?} run...", interval);
for i in 0..=threads {
for _i in 0..=threads {
let add = url.clone();
let end_time = Instant::now() + interval;
let wait = sleep.clone();
@ -35,12 +29,12 @@ pub fn http_stress(url: String, interval: Duration, sleep: Duration, threads: u3
let time = Instant::now() - b4;
match resp {
Ok(_) => {
let myres = StressResult { time: time, thread: i, ok: true };
let myres = StressResult { time: time, ok: true, rtype: ResType::Http };
let _ = tx2.send(myres);
//println!("Got an answer for {} in {:?} in thread {}", add, time, i);
},
Err(_) => {
let myres = StressResult { time: time, thread: i, ok: false };
let myres = StressResult { time: time, ok: false, rtype: ResType::Http };
let _ = tx2.send(myres);
//println!("No answer for {} after {:?} in thread {}", add, time, i);
},
@ -63,7 +57,8 @@ pub fn http_stress(url: String, interval: Duration, sleep: Duration, threads: u3
for r in rx.try_iter() {
res.push(r);
}
print_results(res);
let lres = ListOfResults { results: res, restype: ResType::Http };
lres.show_info();
Ok(())
}

View File

@ -37,14 +37,17 @@ fn main() -> std::io::Result<()> {
match args.mode.as_str() {
"tcpstress" => {
println!("===== TCP STRESS TEST =====");
tcp_stress(payload, address, timeout, duration, ports, threads)?;
return Ok(());
}
"tcpscan" => {
println!("===== TCP SCAN =====");
tcp_scan(address, timeout, sleep, ports)?;
return Ok(());
}
"httpstress" => {
println!("===== HTTP STRESS TEST =====");
http_stress(address, duration, sleep, threads)?;
return Ok(());
}

View File

@ -1,34 +1,32 @@
use std::time::Duration;
///Is implemented for Stress test results.
pub trait IsAResult {
///A way to return the ratio of hits to nohits (eg: "45% of our requests were answered" or
///smth)
fn show_ratio(&self);
///Return the mean hit time as a Duration
fn get_mean_time(&self) -> Duration;
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct StressResult {
///How long did it take
pub time: Duration,
///What thread are we from
pub thread: u32,
///Did we get an answer
pub ok: bool,
pub rtype: ResType,
}
#[derive(Debug, Clone)]
pub enum ResType {
Tcp(u32),
Http,
}
#[derive(Debug, Clone)]
pub struct ListOfResults {
pub results: Vec<StressResult>,
pub restype: ResType,
}
impl IsAResult for ListOfResults {
fn show_ratio(&self) {
impl ListOfResults {
fn compute_ratio(&self) {
let mut ok: u64 = 0;
let mut nok: u64 = 0;
for r in &self.results {
for r in self.results.clone() {
if r.ok == true {
*&mut ok += 1;
} else {
@ -39,10 +37,60 @@ impl IsAResult for ListOfResults {
println!("TOTAL {}\n\tOK {}\n\tNOK {}", compute, ok, nok);
if compute < 1 { compute = 1; }
compute = ok * 100 / compute;
println!("\tGot {}% of OK", compute );
println!("Got {}% of OK\n", compute );
}
fn get_mean_time(&self) -> Duration {
///Get the different TCP ports from the results
fn get_ports(&self) -> Vec<u32> {
let mut ports = vec![];
for r in &self.results {
match r.rtype {
ResType::Tcp(p) => {
if !ports.contains(&p) {
ports.push(p);
}
},
ResType::Http => (),
}
}
ports
}
///Show info, by port if we are in TCP mode
pub fn show_info(&self) {
println!("\n===== RESULTS =====");
match &self.restype {
ResType::Tcp(_) => {
let ports = self.get_ports();
for port in ports {
let mut results = Vec::new();
for res in &self.results {
match res.rtype {
ResType::Tcp(v) => {
if v == port { *&mut results.push(res.clone()); }
},
_ => (),
}
}
let list = ListOfResults { results: results, restype: ResType::Tcp(1) };
println!("=====> PORT {}", port);
list.show_mean_time();
list.compute_ratio();
}
},
ResType::Http => {
self.show_mean_time();
self.compute_ratio();
},
}
}
fn show_mean_time(&self) {
let mut total: u128 = 0;
let mut acc: u128 = 0;
@ -54,13 +102,10 @@ impl IsAResult for ListOfResults {
}
if total == 0 { total += 1 };
let restime = acc / total;
Duration::from_millis(restime.try_into().unwrap())
println!("Average response time : {:?}", Duration::from_millis(restime.try_into().unwrap()));
}
}
pub fn print_results(res: Vec<StressResult>) {
let myres = ListOfResults { results: res };
myres.show_ratio();
println!("\tMean answer time : {:?}", myres.get_mean_time());
}

View File

@ -50,7 +50,6 @@ pub fn tcp_stress(payload: String, address: String, timeout: Duration, interval:
let (tx, rx) = mpsc::channel();
for port in ports {
tcp_scan(address.clone(), timeout, Duration::from_millis(100), vec![port])?;
let mut threads_left = threads;
let tx2 = tx.clone();
@ -87,7 +86,7 @@ pub fn tcp_stress(payload: String, address: String, timeout: Duration, interval:
}
let time = Instant::now() - b4;
let myres = StressResult { time: time, thread: port.clone(), ok: true };
let myres = StressResult { time: time, ok: true, rtype: ResType::Tcp(port.clone()) };
let _ = tx3.send(myres);
//Sleeping
@ -96,7 +95,7 @@ pub fn tcp_stress(payload: String, address: String, timeout: Duration, interval:
},
Err(_) => {
let time = Instant::now() - b4;
let myres = StressResult { time: time, thread: port.clone(), ok: false };
let myres = StressResult { time: time, ok: false, rtype: ResType::Tcp(port.clone()) };
let _ = tx3.send(myres);
}
}
@ -107,7 +106,7 @@ pub fn tcp_stress(payload: String, address: String, timeout: Duration, interval:
}
}
drop(tx);
println!("\nStressing {} using {} concurrent threads per port for {:?} \n", address, threads, interval);
println!("Stressing {} using {} concurrent threads per port for {:?} \n", address, threads, interval);
for handle in handles {
let _ = handle.join();
@ -117,7 +116,9 @@ pub fn tcp_stress(payload: String, address: String, timeout: Duration, interval:
for r in rx.try_iter() {
res.push(r);
}
print_results(res);
let listofres = ListOfResults { results: res, restype: ResType::Tcp(1) };
listofres.show_info();
Ok(())
}