ddos/server.c
changeset 157 e8fbd0653fda
parent 77 49e0babccb23
child 159 44823a881da1
--- a/ddos/server.c
+++ b/ddos/server.c
@@ -7,50 +7,88 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
+#include <netdb.h>
 #include <arpa/inet.h>
 #include <sys/types.h>
 #include <signal.h>
 
+#define MAXLEN 80
+
 int set_proc_limit (int);
 
+int server_write (int client_socket, char *s)
+{
+    return write (client_socket, s, strlen (s));
+}
+
+int server_init (char *port)
+{
+    int server_socket, status;
+    struct addrinfo hints;
+    struct addrinfo *result, *rp;
+
+    int yes = 1;
+
+    memset (&hints, 0, sizeof (hints));
+    hints.ai_family = AF_UNSPEC;
+    hints.ai_socktype = SOCK_STREAM;
+    hints.ai_flags = AI_PASSIVE;
+
+    if (getaddrinfo (NULL, "4000", &hints, &result) < 0) {
+        perror ("GETADDRINFO");
+        return -1;
+    }
+
+    server_socket = -1;
+    for (rp = result; rp != NULL; rp = rp->ai_next) {
+        if ((server_socket = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol)) < 0) {
+            perror ("SOCKET");
+            continue;
+        }
+
+        if (setsockopt (server_socket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof (int)) == -1) {
+            perror ("setsockopt");
+            return -1;
+        }
+
+        if ((bind (server_socket, rp->ai_addr, rp->ai_addrlen)) == -1) {
+            perror ("BIND");
+            close (server_socket);
+            server_socket = -1;
+        } else {
+            printf ("bound to an %s socket\n", (rp->ai_family == AF_INET6) ? "IPv6" : "IPv4");
+        }
+    }
+
+    status = listen (server_socket, 10);
+
+    if (status != 0) {
+        perror ("LISTEN");
+        return -1;
+    }
+
+    if (result != NULL)
+        freeaddrinfo (result);
+
+    return server_socket;
+}
+
 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;
+
+    char message[MAXLEN + 1];
     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");
+    if ((server_socket = server_init ("4000")) < 0)
         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;
 
@@ -67,8 +105,7 @@
     }
 
     for (;;) {
-        size = sizeof (ca);
-        client_socket = accept (server_socket, (struct sockaddr *)&sa, (socklen_t *) & size);
+        client_socket = accept (server_socket, NULL, NULL);
 
         printf ("PARENT PID = %d\n", parent_pid);
 
@@ -76,11 +113,11 @@
         switch (pid) {
         case 0:                /* Child */
             close (server_socket);
-            if ((len = read (client_socket, message, 80)) == -1)
+            if ((len = read (client_socket, message, MAXLEN)) == -1)
                 break;
-            message[len] = 0;
+            message[len] = '\0';
 
-            len = write (client_socket, "Please wait...\r\n", 17);
+            len = server_write (client_socket, "Please wait...\r\n");
             sleep (10);
 
             printf ("DELETING LINK [%04d] %04d\n", getpid (), links--);
@@ -91,8 +128,7 @@
             perror ("Fork Error");
             close (client_socket);
             /*
-             * server is still alive and will continue
-             * * when resources are available
+             * server is still alive and will continue when resources are available
              */
             break;
         default:               /* PID > 0 */