Code Comments

Programming Forum and web based access to our favorite programming groups.
For Programmers: Free Programming Magazines | New: Database administration forum
Registration is free! Edit your profileCalendarFind other membersFrequently Asked QuestionsSearch -> 
Post New Thread











Thread
Author

Timeout of detached threads to prevent DOS Attack
Hi,

i wrote a prethreading server deamon that also reuse finished threads.
However I have a problem with possibel DOS attacks.
$fh is the

my $STATUS       = '';
my %STATUSTIME   = 0;
my $ACCEPT_LOCK  = '';
my %STATUS       = ();
my $DONE         = 0;
share(%STATUS);
share(%STATUSTIME);
share($ACCEPT_LOCK);

$SIG{INT} = $SIG{TERM} = sub { $DONE++ };
$SIG{ALRM} = sub {};

#MAIN Webserver with Multithreading
print "Binding socket on $ip_listen Port $port_listen\n";
#Bind Socket

my $socket = IO::Socket::INET->new( LocalPort => $port_listen,
LocalAddr => $ip_listen,
Listen    => 100,
Reuse     => 1 ) or die "Can't
create listen socket: $!";
my $SOCKIN = IO::Select->new($socket);

launch_thread($socket) for (1..$PRETHREAD);  # launch threads

while (!$DONE) {
lock %STATUS;
cond_wait %STATUS;
warn join(' ', map {"$_=>$STATUS{$_}"} keys %STATUS),"\n" if DEBUG;
my @idle = sort {$a <=> $b} grep {$STATUS{$_} eq 'idle'} keys %STATUS;
my @busy = sort {$a <=> $b} grep {$STATUS{$_} eq 'busy'} keys %STATUS;
if (@idle < $LO_WATER_MARK) {
launch_thread($socket) for (0..$LO_WATER_MARK-@idle-1);     # bring
the number up
} elsif (@idle > $HI_WATER_MARK) {
my @goners = @idle[0..@idle - $HI_WATER_MARK - 1];   # kill the
oldest ones
status($_ => 'goner') foreach @goners;
warn "decomissioning @goners\n" if DEBUG;
}
if (scalar(@busy) > $threadsmaxbusy) {
$threadsmaxbusy=scalar(@busy);
}
}
warn "Server will terminate when last thread has finished...\n" if DEBUG;
status($_ => 'goner') foreach keys %STATUS;
exit 0;

sub do_thread {
my $socket = shift;
my $cycles = $MAX_REQUEST;
my $tid = threads->self->tid;
my $c;
warn "Thread $tid: starting\n" if DEBUG;
threads->self->detach;        # don't save thread status info
$SIG{__DIE__} =  sub {&status($tid=>undef);close $c;};
status($tid => 'idle');
while (status($tid) ne 'goner' && $cycles > 0) {
next unless $SOCKIN->can_read(1);
{
lock $ACCEPT_LOCK;
next unless $c = $socket->accept();

}
$cycles--;
status($tid => 'busy');
$STATUSTIME{$tid}=time;
warn "Thread $tid: handling connection\n" if DEBUG;
new_connection($c);
close $c;
status($tid => 'idle');
}
warn "Thread $tid done\n" if DEBUG;
status($tid=>undef);
exit 1;
}

sub status {
my $tid = shift;
lock %STATUS;
return $STATUS{$tid} unless @_;
my $status = shift;
if ($status) {
$STATUS{$tid} = $status
unless defined $STATUS{$tid} and $STATUS{$tid} eq 'goner';
} else {
delete $STATUS{$tid};
delete $STATUSTIME{$tid};
}
cond_broadcast %STATUS;
}

sub new_connection {
my $fh = shift;
my $ip = "";
my $port = "";
my $iaddr = "";
my $return = eval(($port, $iaddr) = sockaddr_in(getpeername($fh)));
if ($return) {
$ip=inet_ntoa($iaddr);
binmode $fh;
my $doexit = 0;
my %req;
$req{HEADER}={};

my $request_line = <$fh>; <== Here is the problem
....

if i write a simple cgi-script

use IO::Socket;
my $socket = new IO::Socket::INET( PeerAddr => $deamonserver, PeerPort
=> 80, Proto => 'tcp', );
if ($socket)   {
my $counter=0;
while (1) {
sleep 1;
$counter++;
print "$counter\n";
}
close($socket);
}
The server will never break out the thread

With forking servers I used to do it with ALRM signal,
but this doesn't work with threads.

Any solution?

I am searching arround the net now for more than one w,
and didn't didn't find any solution.
Neither socket timeout works nor any signal handler modul I tired.

Thank you for helping

Report this thread to moderator Post Follow-up to this message
Old Post
Stefan Donoval
04-06-08 04:33 AM


Re: Timeout of detached threads to prevent DOS Attack
Sie schrieben:

Hi i found how to solve that problem.
The solution is non blocking sockets.

However, thank you anyways.
I would appreciate if someone has a better solution.
But I guess there isn't one, since it seems impossible
to implement a alarm signal inti threads, and nor
cancle a detached thread.

> Hi,
>
> i wrote a prethreading server deamon that also reuse finished threads.
> However I have a problem with possibel DOS attacks.
> $fh is the
>
> my $STATUS       = '';
> my %STATUSTIME   = 0;
> my $ACCEPT_LOCK  = '';
> my %STATUS       = ();
> my $DONE         = 0;
> share(%STATUS);
> share(%STATUSTIME);
> share($ACCEPT_LOCK);
>
> $SIG{INT} = $SIG{TERM} = sub { $DONE++ };
> $SIG{ALRM} = sub {};
>
> #MAIN Webserver with Multithreading
> print "Binding socket on $ip_listen Port $port_listen\n";
> #Bind Socket
>
> my $socket = IO::Socket::INET->new( LocalPort => $port_listen,
>                                     LocalAddr => $ip_listen,
>                                     Listen    => 100,
>                                     Reuse     => 1 ) or die "Can't
> create listen socket: $!";
> my $SOCKIN = IO::Select->new($socket);
>
> launch_thread($socket) for (1..$PRETHREAD);  # launch threads
>
> while (!$DONE) {
>   lock %STATUS;
>   cond_wait %STATUS;
>   warn join(' ', map {"$_=>$STATUS{$_}"} keys %STATUS),"\n" if DEBUG;
>   my @idle = sort {$a <=> $b} grep {$STATUS{$_} eq 'idle'} keys %STATUS;
>   my @busy = sort {$a <=> $b} grep {$STATUS{$_} eq 'busy'} keys %STATUS;
>   if (@idle < $LO_WATER_MARK) {
>     launch_thread($socket) for (0..$LO_WATER_MARK-@idle-1);     # bring
> the number up
>   } elsif (@idle > $HI_WATER_MARK) {
>     my @goners = @idle[0..@idle - $HI_WATER_MARK - 1];   # kill the
> oldest ones
>     status($_ => 'goner') foreach @goners;
>     warn "decomissioning @goners\n" if DEBUG;
>   }
>   if (scalar(@busy) > $threadsmaxbusy) {
>     $threadsmaxbusy=scalar(@busy);
>   }
> }
> warn "Server will terminate when last thread has finished...\n" if DEBUG;
> status($_ => 'goner') foreach keys %STATUS;
> exit 0;
>
> sub do_thread {
>   my $socket = shift;
>   my $cycles = $MAX_REQUEST;
>   my $tid = threads->self->tid;
>   my $c;
>   warn "Thread $tid: starting\n" if DEBUG;
>   threads->self->detach;        # don't save thread status info
>   $SIG{__DIE__} =  sub {&status($tid=>undef);close $c;};
>   status($tid => 'idle');
>   while (status($tid) ne 'goner' && $cycles > 0) {
>     next unless $SOCKIN->can_read(1);
>     {
>       lock $ACCEPT_LOCK;
>       next unless $c = $socket->accept();
>
>     }
>     $cycles--;
>     status($tid => 'busy');
>     $STATUSTIME{$tid}=time;
>     warn "Thread $tid: handling connection\n" if DEBUG;
>     new_connection($c);
>     close $c;
>     status($tid => 'idle');
>   }
>   warn "Thread $tid done\n" if DEBUG;
>   status($tid=>undef);
>   exit 1;
> }
>
> sub status {
>   my $tid = shift;
>   lock %STATUS;
>   return $STATUS{$tid} unless @_;
>   my $status = shift;
>   if ($status) {
>     $STATUS{$tid} = $status
>       unless defined $STATUS{$tid} and $STATUS{$tid} eq 'goner';
>   } else {
>     delete $STATUS{$tid};
>     delete $STATUSTIME{$tid};
>   }
>   cond_broadcast %STATUS;
> }
>
> sub new_connection {
>     my $fh = shift;
>     my $ip = "";
>     my $port = "";
>     my $iaddr = "";
>   my $return = eval(($port, $iaddr) = sockaddr_in(getpeername($fh)));
>   if ($return) {
>     $ip=inet_ntoa($iaddr);
>       binmode $fh;
>       my $doexit = 0;
>       my %req;
>       $req{HEADER}={};
>
>       my $request_line = <$fh>; <== Here is the problem
> ....
>
> if i write a simple cgi-script
>
> use IO::Socket;
> my $socket = new IO::Socket::INET( PeerAddr => $deamonserver, PeerPort
> => 80, Proto => 'tcp', );
> if ($socket)   {
>   my $counter=0;
>   while (1) {
>     sleep 1;
>     $counter++;
>     print "$counter\n";
>   }
>   close($socket);
> }
> The server will never break out the thread
>
> With forking servers I used to do it with ALRM signal,
> but this doesn't work with threads.
>
> Any solution?
>
> I am searching arround the net now for more than one w,
> and didn't didn't find any solution.
> Neither socket timeout works nor any signal handler modul I tired.
>
> Thank you for helping

Report this thread to moderator Post Follow-up to this message
Old Post
Stefan Donoval
04-07-08 02:26 AM


Sponsored Links




Last Thread Next Thread Next
Search this forum -> 
Post New Thread

ithreads archive

Show a Printable Version Send to friend Email This Page to Someone! subscribe to this thread Receive updates to this thread
Computer Consultants
Programming Jobs
Visual Basic Controls
SQL Server Programming
Webservices
Java Security
Visual Studio
C# Programming
Visual J++
Software engineering
Open source Software
Perl Programming
PHP Programming
ASP Programming
ASP .NET Programming
Visual Basic Programming
Windows Scripting Host
Java Programming
Java Help
Java Beans
VBScript
Cobol
MAC Applications
Unix Programming
Forum Jump:
All times are GMT. The time now is 08:40 PM.

 
Free MCSE Braindumps | Real Estate Topics

Programming forum archive

Copyrights CodeComments.com 2004 - 2006

Powered by vBulletin Copyright 2000-2006 Jelsoft Enterprises Limited.