buggy code
authorLaurent Mazet <laurent.mazet@thalesgroup.com>
Fri, 12 May 2023 16:31:51 +0000 (18:31 +0200)
committerLaurent Mazet <laurent.mazet@thalesgroup.com>
Fri, 12 May 2023 16:31:51 +0000 (18:31 +0200)
server.c
webserver.c

index 711f472072027be472342aa4f51b78beba70a1d9..10517ca72b32ece41ace52565c2146e2ac8cc851 100644 (file)
--- a/server.c
+++ b/server.c
@@ -37,7 +37,9 @@ typedef int socket_t;
 
 /* constants */
 
+#define BACKLOG 5
 #define BUFFER_SIZE 4096
+#define TIMEOUT 100000
 
 /* macros */
 
@@ -68,10 +70,10 @@ socket_t open_listening_socket (int port)
     VERBOSE (DEBUG, fprintf (stdout, "Binding socket\n"));
     int rc = bind (sock, (struct sockaddr *)&addr, sizeof (addr));
     if (rc == SOCKET_ERROR) {
-        VERBOSE (ERROR, fprintf (stderr, "error: %d\n", ERRNO));
+        VERBOSE (ERROR, fprintf (stderr, "error: bind %d\n", ERRNO));
         rc = closesocket (sock);
         if (rc == SOCKET_ERROR) {
-            VERBOSE (ERROR, fprintf (stderr, "error: %d\n", ERRNO));
+            VERBOSE (ERROR, fprintf (stderr, "error: close %d\n", ERRNO));
         }
         return -1;
     }
@@ -83,10 +85,20 @@ socket_t open_listening_socket (int port)
     int val = 1;
     rc = setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof (val));
     if (rc < 0) {
-        VERBOSE (ERROR, fprintf (stderr, "%s\n", "setsockopt/TCP_NODELAY"));
+        VERBOSE (ERROR, fprintf (stderr, "error: %s\n", "setsockopt/TCP_NODELAY"));
         closesocket (sock);
         if (rc == SOCKET_ERROR) {
-            VERBOSE (ERROR, fprintf (stderr, "error: %d\n", ERRNO));
+            VERBOSE (ERROR, fprintf (stderr, "error: close %d\n", ERRNO));
+        }
+        return -1;
+    }
+
+    rc = listen (sock, BACKLOG);
+    if (rc < 0) {
+        VERBOSE (ERROR, fprintf (stderr, "error: %s\n", "listen"));
+        closesocket (sock);
+        if (rc == SOCKET_ERROR) {
+            VERBOSE (ERROR, fprintf (stderr, "error: close %d\n", ERRNO));
         }
         return -1;
     }
@@ -106,6 +118,61 @@ void close_listening_socket (socket_t sock)
 #endif
 }
 
-/* vim: set ts=4 sw=4 et: */
+/* accept incomming connection */
+
+int accept_incoming_connection (socket_t sock)
+{
+    int connection = accept (sock, NULL, 0);
+    if (connection < 0) {
+        return connection;
+    }
+
+#ifndef _WIN32 /* POSIX */
+    fcntl (connection, F_SETFL, O_NONBLOCK);
+#endif
+    int val = 1;
+    rc = setsockopt (connection, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof (val));
+    if (rc < 0) {
+        VERBOSE (ERROR, fprintf (stderr, "error: %s\n", "setsockopt/TCP_NODELAY"));
+        closesocket (connection);
+        if (rc == SOCKET_ERROR) {
+            VERBOSE (ERROR, fprintf (stderr, "error: close %d\n", ERRNO));
+        }
+        return -1;
+    }
+
+    return connection;
+}
+
+/* receive data */
+int receive_data (socket_t sock, unsigned char data, int maxlen)
+{
+
+    /* timeout management */
+    fd_set rfds;
+    struct timeval tv = { 0, TIMEOUT };
+    FD_ZERO (&rfds);
+    FD_SET (sock, &rfds);
+
+    int retval = select (sock + 1, &rfds, NULL, NULL, &tv);
+    if (retval != 1)
+        return retval; /* 0 or SOCKET_ERROR */
+
+    /* read from socket */
+    int len = read (sock, data, maxlen);
+
+    if (rc = 0) { /* sock closed */
+        return 0;
+    } else if ((rc < 0) && (ERRNO != EAGAIN)) { /* error */
+        return -1;
+    } else if (rc > 0) {
+        return len;
+    }
+
+    /* do we retry ? */
+
+    return -2;
+}
+
 
 /* vim: set ts=4 sw=4 et: */
index 825b847f728e9f3aec82dc5db4e352559404ee3e..9861836fc5abcdcff7b1649f27cc8003e93ae2b5 100644 (file)
@@ -105,9 +105,50 @@ int main (int argc, char *argv[])
         VERBOSE (ERROR, fprintf (stderr, "Can't open listening socket\n"));
         return 1;
     }
-
     VERBOSE (INFO, fprintf (stdout, "Listening socket on port %d\n", port));
-    sleep (20);
+
+    /* main loop */
+    while (1) {
+        int connection = accept_incoming_connection (sock);
+        if ((connection < 0) && (errno == EAGAIN)) {
+            accept_nonblock_ok = 1;
+        }
+        if (connection < 0) {
+            sleep (1);
+            continue;
+        }
+
+        VERBOSE (DEBUG, fprintf (stdout, "Server connected, waiting for data\n"));
+
+        while (1) {
+            unsigned char data[BUFFER_SIZE] = {0};
+            int len = 0;
+
+            len = receive_data (connection, data, size (data));
+            if (len == 0) {
+                // nonblocking connection
+                sleep (1);
+                continue;
+            }
+            if (len < 0) {
+                VERBOSE (WARNING, fprintf (stdout, "Connection closed by peer\n"));
+                close_connection (connection);
+                break;
+            }
+
+            // processing
+            
+            len = send_data (connection, data, size (data));
+            if (len < 0) {
+                VERBOSE (WARNING, fprintf (stdout, "Connection closed by peer\n"));
+                close_connection (connection);
+                break;
+            }
+
+            /* sleep so that we go trhough remaining data in receive buffer */
+            usleep (1e5);
+        }
+    }
 
     VERBOSE (DEBUG, fprintf (stdout, "Closing socket\n"));
     close_listening_socket (sock);