This commit is contained in:
parent
53c405b7a6
commit
dd430b1b2c
@ -47,4 +47,3 @@ jobs:
|
||||
|
||||
- name: Build
|
||||
run: cargo build --release
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
15
src/http.rs
15
src/http.rs
@ -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(())
|
||||
}
|
||||
|
||||
|
@ -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(());
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
11
src/tcp.rs
11
src/tcp.rs
@ -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(())
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user