ddos/server.c
author Markus Bröker <mbroeker@largo.dyndns.tv>
Thu, 16 Apr 2009 12:50:28 +0200
changeset 66 2b4f786d9073
parent 10 f19f44e2e863
child 68 d549894aa6a9
permissions -rw-r--r--
Common Makefile Style NAME += OBJECT committer: Markus Bröker <mbroeker@largo.homelinux.org>

/**
 * test/demos/ddos/server.c
 * Copyright (C) 2008 Markus Broeker
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <signal.h>

int set_limit (int);

int main (int argc, char **argv)
{
    char message[81];
    int server_socket;
    int client_socket;
    struct sockaddr_in sa;
    struct sockaddr_in ca;
    socklen_t size;
    int len;
    int status;
    pid_t pid;
    pid_t parent_pid;

    server_socket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (server_socket == -1) {
        perror ("socket");
        return EXIT_FAILURE;
    }

    sa.sin_family = AF_INET;
    sa.sin_port = htons (4000);
    sa.sin_addr.s_addr = INADDR_ANY;

    size = sizeof (sa);

    status = bind (server_socket, (struct sockaddr *)&sa, size);
    if (status != 0) {
        perror ("BIND");
        return EXIT_FAILURE;
    }

    status = listen (server_socket, 10);
    if (status != 0) {
        perror ("LISTEN");
        return EXIT_FAILURE;
    }

    int links = 0;

    parent_pid = getpid ();

    /*
     * Child quits immediately, father mustn't wait
     */
    signal (SIGCHLD, SIG_IGN);

    if (set_limit (500) != 0) {
        printf ("Cannot limit the process limit\n");
        return EXIT_FAILURE;
    }

    for (;;) {
        size = sizeof (ca);
        client_socket = accept (server_socket, (struct sockaddr *)&sa, (socklen_t *) & size);

        printf ("PARENT PID = %d\n", parent_pid);

        pid = fork ();
        switch (pid) {
        case 0:                /* Child */
            close (server_socket);
            if ((len = read (client_socket, message, 80)) == -1)
                break;
            message[len] = 0;

            len = write (client_socket, "Please wait...\r\n", 17);
            sleep (10);

            printf ("DELETING LINK [%04d] %04d\n", getpid (), links--);
            shutdown (client_socket, SHUT_RDWR);
            close (client_socket);
            return 1;
        case -1:
            perror ("Fork Error");
            close (client_socket);
            /*
             * server is still alive and will continue
             * * when resources are available
             */
            break;
        default:               /* PID > 0 */
            close (client_socket);
            printf ("Starting LINK [%04d] %04d\n", pid, links++);
        }
    }

    return close (server_socket);
}