听说3月1日 GitHub 被DDoS攻击了,好像挺严重的。
来看看怎么使用mc攻击~
mc 首先通过cmd line指定UDP端口,然后初始化libevent实例,初始化线程,
int main (int argc, char **argv) {
...
settings_init();
...
while (-1 != (c = getopt(argc, argv,
...
"U:" /* UDP port number to listen on */
...
case 'U':
settings.udpport = atoi(optarg);
udp_specified = true;
break;
...
))) {
...
if (tcp_specified && !udp_specified) {
settings.udpport = settings.port;
} else if (udp_specified && !tcp_specified) {
settings.port = settings.udpport;
}
...
main_base = event_init();
...
thread_init(settings.num_threads, main_base);
...
/* create unix mode sockets after dropping privileges */
if (settings.socketpath != NULL) {
errno = 0;
if (server_socket_unix(settings.socketpath,settings.access)) {
vperror("failed to listen on UNIX socket: %s", settings.socketpath);
exit(EX_OSERR);
}
}
/* create the listening socket, bind it, and init */
if (settings.socketpath == NULL) {
...
// TCP
errno = 0;
if (settings.port && server_sockets(settings.port, tcp_transport,
portnumber_file)) {
vperror("failed to listen on TCP port %d", settings.port);
exit(EX_OSERR);
}
/*
* initialization order: first create the listening sockets
* (may need root on low ports), then drop root if needed,
* then daemonise if needed, then init libevent (in some cases
* descriptors created by libevent wouldn't survive forking).
*/
/* create the UDP listening socket and bind it */
errno = 0;
if (settings.udpport && server_sockets(settings.udpport, udp_transport,
portnumber_file)) {
vperror("failed to listen on UDP port %d", settings.udpport);
exit(EX_OSERR);
}
...
/* enter the event loop */
if (event_base_loop(main_base, 0) != 0) {
retval = EXIT_FAILURE;
}
...
}
在此之前初始化了一些设置,可以看到默认端口是11211,有4个worker线程。
static void settings_init(void) {
...
settings.port = 11211;
settings.udpport = 11211;
/* By default this string should be NULL for getaddrinfo() */
settings.inter = NULL;
settings.maxbytes = 64 * 1024 * 1024; /* default is 64MB */
...
settings.chunk_size = 48; /* space for a modest key and value */
settings.num_threads = 4; /* N workers */
...
}
可以检查一下:
$ echo "stats settings" | nc localhost 11211
STAT maxbytes 67108864
STAT maxconns 1024
STAT tcpport 11211
STAT udpport 11211
STAT inter NULL
...
STAT chunk_size 48
STAT num_threads 4
...
END
随后线程初始化,main_base 是分发任务的主线程,创建管道用于libevent通知。主要调用了setup_thread初始化线程信息数据结构,最后创建并初始化线程,代码段都是 worker_libevent。
void thread_init(int nthreads, struct event_base *main_base) {
...
threads = calloc(nthreads, sizeof(LIBEVENT_THREAD));
if (! threads) {
perror("Can't allocate thread descriptors");
exit(1);
}
dispatcher_thread.base = main_base;
dispatcher_thread.thread_id = pthread_self();
for (i =