As a technical support engineer, I would need to send multiple spam samples through our product for detection rate. I initially used a bash script to send the samples through via telnet command. The drawback was that the processing was sequential (slow). I was already thinking of how to use threading to send the samples through in large batches which finishes the job a lot faster and at the same time enables me to tune the performance of our product when handling multiple connections. Finally, after a great deal of procastrination, I finally hacked together a perl script to do the job, after googling and modifying some ther perl scripts. I used the script from http://pentestit.com/2009/05/20/source-code-perl-multithreaded-scanner-webdavenabled-servers/ as basis for my script.
#!/usr/bin/perl -w
$|++;
use strict;
use 5.008;
use threads;
use threads::shared;
use Thread::Queue;
use Net::SMTP;
our $thrnum:shared=100;
our $q:shared;
our @threads;
sub smtp_send {
my $target='192.168.50.135';
my $filename;
my $line;
my @message;
my $dir = shift;
if ($dir =~ m/\/$/) { } else { $dir = $dir."/";};
$filename = shift;
# print "Opening connection to target : ".$target."\n";
# print "Filename: ".$dir.$filename."\n";
$filename=$dir.$filename;
open FILE, $filename or die $!;
@message=
close FILE;
if (my $smtp = Net::SMTP->new($target,Hello=>'peters.eatsc.ts',Timeout=>30,Debug=>0)) {;
$smtp->mail('test@test.bng');
$smtp->to('peters@eatsc.ts');
$smtp->data(@message);
$smtp->quit;
} else {
die;
};
}
sub main {
my $dir;
my $spamfile;
my $running;
$q = new Thread::Queue;
$dir = shift;
opendir (DH, $dir);
while (defined ($spamfile=readdir(DH))) {
unless ($spamfile =~ /^.{1,2}$/) {
$q->enqueue($spamfile);
}
}
closedir(DH);
while (1){
@threads = threads->list;
if ($q->pending > 0) {
# print "Pending items: ".$q->pending." \n";
if ($#threads <= $thrnum+1) {
threads->new(\&spam_send,$dir,$q->dequeue);
# print "Adding new thread ".$#threads." \n";
} else {
foreach $running(@threads) {
$running->join;
# print "Freeing thread: ".$#threads." \n";
};
};
} else {
if ($#threads >= 0) {
foreach $running(@threads) {
$running->join;
# print "Freeing thread: ".$#threads." \n";
};
exit;
};
};
# print "\nThread count:" .$#threads;
}
&main($ARGV[0]); #input directory name as command-line parameter.
I will be recoding this script in python and ruby to check which one will run faster (not that I expect that there will be a huge change in performance, but a programming exercise for me).
