From: Laurent Mazet Date: Fri, 12 May 2023 16:31:51 +0000 (+0200) Subject: buggy code X-Git-Url: https://secure.softndesign.org/git/?a=commitdiff_plain;h=04a2223db2463c9c66c7f5eb24aab0d8da3dfa16;p=webserver.git buggy code --- diff --git a/server.c b/server.c index 711f472..10517ca 100644 --- 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: */ diff --git a/webserver.c b/webserver.c index 825b847..9861836 100644 --- a/webserver.c +++ b/webserver.c @@ -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);