X-Git-Url: https://secure.softndesign.org/git/?a=blobdiff_plain;f=server.c;h=b2a564d9767a23cb73921fa3c51c204125c24ecb;hb=refs%2Fheads%2Fmaster;hp=cc7f4cd2bf50ee432b686483ba18c726121719da;hpb=7a6b7a44a3106604a181873a070a6242133a6d65;p=webserver.git diff --git a/server.c b/server.c index cc7f4cd..b2a564d 100644 --- a/server.c +++ b/server.c @@ -1,8 +1,5 @@ -/* depend: */ -/* cflags: */ -/* linker: color.o debug.o */ - #include +#include #include #include #include @@ -15,8 +12,6 @@ #include #include #include -//#include -//#include #include #endif #include @@ -25,19 +20,14 @@ #include "server.h" -/* compat */ +/* types */ #ifdef _WIN32 /* Windows */ -#define PF_INET AF_INET -#define ERRNO (WSAGetLastError ()) +typedef SOCKET socket_t; #else /* Posix */ -#define closesocket close -#define ERRNO errno -#define SOCKET_ERROR -1 +typedef int socket_t; #endif -/* types */ - /* constants */ #define BACKLOG 5 @@ -46,8 +36,30 @@ /* macros */ +#ifdef _WIN32 /* Windows */ +#define PF_INET AF_INET +#define ERRNO (WSAGetLastError ()) +#else /* Posix */ +#define closesocket close +#define ERRNO errno +#define SOCKET_ERROR -1 +#define INVALID_SOCKET -1 +#endif + /* gobal variables */ +socket_t sock = INVALID_SOCKET; +socket_t conn = INVALID_SOCKET; + +/* stop server */ + +void stop_server (int sig) +{ + VERBOSE (INFO, PRINT ("Signal: %d\n", sig)); + terminate_network_context (); + exit (0); +} + /* init network context */ void init_network_context (void) @@ -55,15 +67,35 @@ void init_network_context (void) #ifdef _WIN32 /* Windows */ WSADATA WSAData; WSAStartup (MAKEWORD(2,0), &WSAData); + assert (INVALID_SOCKET == (socket_t)-1); assert (SOCKET_ERROR == -1); #endif + +#ifndef _WIN32 /* Posix */ + signal (SIGINT, &stop_server); +#endif + signal (SIGABRT, &stop_server); + signal (SIGSEGV, &stop_server); + signal (SIGTERM, &stop_server); } /* terminate network context */ +void _closesocket (socket_t sock) +{ + if (sock != INVALID_SOCKET) { + int rc = closesocket (sock); + if (rc == SOCKET_ERROR) { + VERBOSE (ERROR, PERROR ("error: close %d\n", ERRNO)); + } + } +} + void terminate_network_context (void) { + _closesocket (sock); + _closesocket (conn); #ifdef _WIN32 /* Windows */ WSACleanup (); #endif @@ -71,15 +103,16 @@ void terminate_network_context (void) /* open listening socket */ -socket_t open_listening_socket (int port) +int open_listening_socket (int port) { int val = 1; - VERBOSE (DEBUG, fprintf (stdout, "Opening socket\n")); + VERBOSE (DEBUG, PRINT ("Opening socket\n")); //socket_t sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); - socket_t sock = socket (AF_INET, SOCK_STREAM, 0); - if (sock == INVALID_SOCKET) { - return -1; + _closesocket (sock); + socket_t _sock = socket (AF_INET, SOCK_STREAM, 0); + if (_sock == INVALID_SOCKET) { + return 0; } struct sockaddr_in addr = {0}; @@ -89,119 +122,116 @@ socket_t open_listening_socket (int port) addr.sin_port = htons (port); addr.sin_addr.s_addr = htonl (INADDR_ANY); - VERBOSE (DEBUG, fprintf (stdout, "Binding socket\n")); - //setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof (val)); - int rc = bind (sock, (struct sockaddr *)&addr, sizeof (addr)); + VERBOSE (DEBUG, PRINT ("Binding socket\n")); + //setsockopt (_sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof (val)); + int rc = bind (_sock, (struct sockaddr *)&addr, sizeof (addr)); if (rc == SOCKET_ERROR) { - VERBOSE (ERROR, fprintf (stderr, "error: bind %d\n", ERRNO)); - rc = closesocket (sock); - if (rc == SOCKET_ERROR) { - VERBOSE (ERROR, fprintf (stderr, "error: close %d\n", ERRNO)); - } - return -1; + VERBOSE (ERROR, PERROR ("error: bind %d\n", ERRNO)); + _closesocket (_sock); + return 0; } - VERBOSE (DEBUG, fprintf (stdout, "Configuring socket\n")); + VERBOSE (DEBUG, PRINT ("Configuring socket\n")); #ifndef _WIN32 /* Posix */ - fcntl (sock, F_SETFL, O_NONBLOCK); + fcntl (_sock, F_SETFL, O_NONBLOCK); #endif - rc = setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof (val)); + rc = setsockopt (_sock, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof (val)); if (rc < 0) { - VERBOSE (ERROR, fprintf (stderr, "error: %s\n", "setsockopt/TCP_NODELAY")); - closesocket (sock); - if (rc == SOCKET_ERROR) { - VERBOSE (ERROR, fprintf (stderr, "error: close %d\n", ERRNO)); - } - return -1; + VERBOSE (ERROR, PERROR ("error: %s\n", "setsockopt/TCP_NODELAY")); + _closesocket (_sock); + return 0; } - rc = listen (sock, BACKLOG); + 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; + VERBOSE (ERROR, PERROR ("error: %s\n", "listen")); + _closesocket (_sock); + return 0; } - return sock; + sock = _sock; + + return 1; } /* accept incomming connection */ -socket_t accept_incoming_connection (socket_t sock) +int accept_incoming_connection (void) { - socket_t connection = accept (sock, NULL, 0); - if (connection < 0) { - return INVALID_SOCKET; + if (sock == INVALID_SOCKET) { + VERBOSE (ERROR, PERROR ("Can't accept connection from closed socket\n")); + return 0; + } + + if (conn != INVALID_SOCKET) { + _closesocket (conn); + conn = INVALID_SOCKET; + } + socket_t _conn = accept (sock, NULL, 0); + if (_conn == INVALID_SOCKET) { + return 0; } #ifndef _WIN32 /* POSIX */ - fcntl (connection, F_SETFL, O_NONBLOCK); + fcntl (_conn, F_SETFL, O_NONBLOCK); #endif int val = 1; - int rc = setsockopt (connection, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof (val)); + int rc = setsockopt (_conn, 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 INVALID_SOCKET; + VERBOSE (ERROR, PERROR ("error: %s\n", "setsockopt/TCP_NODELAY")); + _closesocket (_conn); + return 0; } - return connection; + conn = _conn; + + return 1; } -/* close listening socket */ +/* close connection socket */ -void close_socket (socket_t sock) +void close_connection (void) { - int rc = closesocket (sock); - if (rc == SOCKET_ERROR) { - VERBOSE (ERROR, fprintf (stderr, "error: %d\n", ERRNO)); - } + _closesocket (conn); + conn = INVALID_SOCKET; } /* receive data from socket */ -int receive_data (socket_t sock, unsigned char **pdata) +int receive_data (char **pdata) { - unsigned char buffer[BUFFER_SIZE] = {0}; - unsigned char *data = NULL; + char buffer[BUFFER_SIZE] = {0}; + char *data = NULL; int len = 0; + if (conn == INVALID_SOCKET) { + VERBOSE (ERROR, PERROR ("Can't read data from closed socket\n")); + return 0; + } + while (1) { /* timeout management */ fd_set rfds; struct timeval tv = { 0, TIMEOUT }; FD_ZERO (&rfds); - FD_SET (sock, &rfds); + FD_SET (conn, &rfds); - int retval = select (sock + 1, &rfds, NULL, NULL, &tv); + int retval = select (conn + 1, &rfds, NULL, NULL, &tv); if (retval != 1) { /* 0 or SOCKET_ERROR */ break; } /* read from socket */ - int rc = read (sock, buffer, BUFFER_SIZE); + int rc = recv (conn, buffer, BUFFER_SIZE, 0); + VERBOSE (DEBUG, PRINT ("rc: %d\nerrno: %d\n", rc, ERRNO)); - if (rc == 0) { /* sock closed */ + if (rc == 0) { /* sock closed or error */ if (data) { free (data); data = NULL; - len = 0; } - break; - - } else if ((rc < 0) && (ERRNO != EAGAIN)) { /* error */ - if (data) { - free (data); - data = NULL; - } - len = -1; + len = (rc < 0) ? -1 : 0; break; } else if (rc > 0) { @@ -219,18 +249,20 @@ int receive_data (socket_t sock, unsigned char **pdata) /* send data onto socket */ -int send_data (socket_t sock, unsigned char *data, int len) +int send_data (char *data, int len) { int index = 0; + if (conn == INVALID_SOCKET) { + VERBOSE (ERROR, PERROR ("Can't read data from closed socket\n")); + return 0; + } + while (index < len) { - int rc = write (sock, data + index, len - index); + int rc = send (conn, data + index, len - index, 0); - if (rc == 0) { /* sock closed */ - index = 0; - break; - } else if ((rc < 0) && (ERRNO != EAGAIN)) { /* error */ - index = -1; + if (rc <= 0) { /* sock closed or error */ + index = (rc < 0) ? -1 : 0; break; } else if (rc > 0) { index += rc;