use crate::action_factory::{ActionTrait, ActionData};
use log::*;
use simple_error::*;
use std::net::{TcpStream, SocketAddr};
use std::time::Duration;
use native_tls::{TlsConnectorBuilder,TlsConnector};
use std::str::FromStr;
use std::ops::Sub;
pub struct ActionTcp {
task:ActionData
}
impl ActionTcp {
fn executor_tcp(&mut self) {
let task_conf = &self.task.task_action;
let sockAddr = SocketAddr::from_str(task_conf.target.as_str()).unwrap();
let startTime = chrono::Utc::now().time();
let r = TcpStream::connect_timeout(&sockAddr,
Duration::from_millis(task_conf.timeout as u64));
match r {
Ok(stream) => {
if task_conf.output_result {
info!("tcp {} connect success,time:{}ms...",task_conf.target,(chrono::Utc::now().time() - startTime).num_milliseconds());
}
self.task.do_recover();
}
Err(e) => {
error!("tcp {} connect error:{}",task_conf.target,e);
self.task.do_failed();
}
}
}
fn executor_tcpTls(&mut self) {
let task_conf = &self.task.task_action;
let mut r = TlsConnector::builder();
if task_conf.skip_tls_check {
r.danger_accept_invalid_certs(true).
danger_accept_invalid_hostnames(true);
}
let tHost = task_conf.target.split(":").collect::<Vec<&str>>();
if tHost.len() < 2 {
error!("target format error! {}",task_conf.target);
return;
}
let tHost = tHost[0];
let startTime = chrono::Utc::now().time();
let connector = r.build().unwrap();
let sockAddr = SocketAddr::from_str(task_conf.target.as_str()).unwrap();
let rt = TcpStream::connect_timeout(&sockAddr,
Duration::from_millis(task_conf.timeout as u64));
match rt {
Ok(stream) => {
let mut stream = connector.connect(tHost,stream);
match stream {
Ok(r) => {
if task_conf.output_result {
info!("tcp tls {} connect success,time:{}ms...",task_conf.target,(chrono::Utc::now().time() - startTime).num_milliseconds());
}
self.task.do_recover();
}
Err(e) => {
error!("tcp tls connect error:{}",e);
self.task.do_failed();
}
}
}
Err(e) => {
error!("tcp tls {} connect error:{}",task_conf.target,e);
self.task.do_failed();
}
}
}
}
impl ActionTrait for ActionTcp {
fn id(&self) -> i32 {
self.task.id
}
fn name(&self) -> &str {
self.task.name.as_str()
}
fn append_data(&mut self, data: ActionData) {
self.task = data;
}
fn executor(&mut self) {
info!("start tcp or tcp_tls action:{} id:{}...",self.task.id,self.task.name);
let task_conf = &self.task.task_action;
match task_conf.atype.as_str() {
"tcp" => {
self.executor_tcp();
},
"tcp_tls" => {
self.executor_tcpTls();
}
_ => {}
}
}
}
pub fn new_tcp(data: ActionData) -> ActionTcp {
ActionTcp { task:data }
}