summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorAndreas Baumann <abaumann@yahoo.com>2009-04-06 13:09:52 +0200
committerAndreas Baumann <abaumann@yahoo.com>2009-04-06 13:09:52 +0200
commitd67a84d6bc200b13b2b8d69c7319f0a1772822c5 (patch)
treeac7353a109588435312439f8ee628afae7c2ee60 /tests
parentf945d8d5fc9e297f76a5046a72b6a135abfd6e39 (diff)
downloadwolfbones-d67a84d6bc200b13b2b8d69c7319f0a1772822c5.tar.gz
wolfbones-d67a84d6bc200b13b2b8d69c7319f0a1772822c5.tar.bz2
also did the echo server test2 in networking, a little bit simplistic
Diffstat (limited to 'tests')
-rw-r--r--tests/network/test2.c351
1 files changed, 108 insertions, 243 deletions
diff --git a/tests/network/test2.c b/tests/network/test2.c
index 5192bb2..3964c93 100644
--- a/tests/network/test2.c
+++ b/tests/network/test2.c
@@ -20,7 +20,8 @@
#define DEBUG 0
-#define ACCEPT_TIMEOUT 5
+#define MAX_ACCEPT_IDLE_TIMEOUT 4
+#define MAX_IDLE_TIMEOUT 10
static bool wolf_network_sock_nonblocking( int fd ) {
int flags;
@@ -33,22 +34,61 @@ static bool wolf_network_sock_nonblocking( int fd ) {
return true;
}
+#if DEBUG
+static char *fd_set_to_string( fd_set *fd, int min_fd, int max_fd, char *buf, size_t buflen ) {
+ int i;
+ size_t j;
+
+ assert( min_fd <= max_fd );
+
+ for( i = min_fd, j = 0; i <= max_fd && j < buflen; i++, j++ ) {
+ if( FD_ISSET( i, fd ) ) {
+ buf[j] = '1';
+ } else {
+ buf[j] = '0';
+ }
+ }
+
+ buf[j] = '\0';
+
+ return buf;
+}
+#endif
+
+#define BUFFER_SIZE 4096
+
+static volatile bool terminate = false;
+
+static void term_handler( int sig ) {
+ WOLF_UNUSED( sig );
+ terminate = true;
+}
+
int main( int argc, char* argv[] ) {
int error;
- int serv_fd;
+ int serv_fd = -1;
int res;
char *host;
char *service;
struct addrinfo hints;
- struct addrinfo *result;
+ struct addrinfo *result = NULL;
wolf_network_sockaddr_union_t client_addr;
socklen_t client_addr_len;
fd_set read_set;
+ fd_set write_set;
struct timeval timeout;
char client_hostname[NI_MAXHOST] = "";
char client_service[NI_MAXSERV] = "";
int on;
- int client_fd;
+ int client_fd = -1;
+ int idle_secs;
+ char buffer[BUFFER_SIZE];
+ size_t fd_to_write;
+ size_t fd_written;
+ size_t total_fd_read;
+ size_t total_fd_written;
+ int count;
+ bool fd_eof;
if( argc != 3 ) {
fprintf( stderr, "usage: test2 <host> <port>\n" );
@@ -63,6 +103,10 @@ int main( int argc, char* argv[] ) {
WSAStartup( MAKEWORD( 2, 2 ), &wsa_data );
#endif
+ signal( SIGTERM, term_handler );
+ signal( SIGINT, term_handler );
+ signal( SIGPIPE, SIG_IGN );
+
/* tell getaddrinfo what we want */
memset( &hints, 0, sizeof( struct addrinfo ) );
hints.ai_flags = AI_PASSIVE;
@@ -100,7 +144,6 @@ int main( int argc, char* argv[] ) {
/* bind server socket */
res = bind( serv_fd, result->ai_addr, result->ai_addrlen );
if( res < 0 ) {
- (void)close( serv_fd );
fprintf( stderr, "bind failed: %s (%d)\n", strerror( errno ), errno );
goto FAIL;
}
@@ -108,14 +151,12 @@ int main( int argc, char* argv[] ) {
/* listen to the socket */
res = listen( serv_fd, 10 );
if( res < 0 ) {
- (void)close( serv_fd );
fprintf( stderr, "listen failed: %s (%d)\n", strerror( errno ), errno );
goto FAIL;
}
/* set socket non-blocking for accepts (Stevens 15.6) */
if( !wolf_network_sock_nonblocking( serv_fd ) ) {
- (void)close( serv_fd );
fprintf( stderr, "set nonblocking failed for server socket: %s (%d)\n", strerror( errno ), errno );
goto FAIL;
}
@@ -127,10 +168,12 @@ FIRST_ACCEPT_AGAIN:
client_addr_len = sizeof( client_addr );
client_fd = accept( serv_fd, &client_addr.addr, &client_addr_len );
if( client_fd < 0 ) {
- if( errno == EAGAIN || errno == EWOULDBLOCK ) {
+ if( errno == EINTR ) {
+ if( terminate ) goto OK;
+ goto FIRST_ACCEPT_AGAIN;
+ } else if( errno == EAGAIN || errno == EWOULDBLOCK ) {
/* as expected, skip */
} else {
- (void)close( serv_fd );
fprintf( stderr, "first non-blocking accept failed: %s (%d)\n", strerror( errno ), errno );
goto FAIL;
}
@@ -142,18 +185,20 @@ FIRST_ACCEPT_AGAIN:
ACCEPT_SELECT_AGAIN:
FD_ZERO( &read_set );
FD_SET( serv_fd, &read_set );
- timeout.tv_sec = ACCEPT_TIMEOUT;
+ timeout.tv_sec = MAX_ACCEPT_IDLE_TIMEOUT;
timeout.tv_usec = 0;
res = select( serv_fd + 1, &read_set, NULL, NULL, &timeout );
if( res < 0 ) {
- if( errno == EINTR || errno == EAGAIN ) {
+ if( errno == EINTR ) {
+ if( terminate ) goto OK;
+ goto ACCEPT_SELECT_AGAIN;
+ } else if( errno == EAGAIN ) {
goto ACCEPT_SELECT_AGAIN;
} else {
/* fatal errors */
fprintf( stderr, "accept/select failed: %s (%d)\n",
strerror( errno ), errno );
- (void)close( serv_fd );
goto FAIL;
}
} else if( res == 0 ) {
@@ -179,13 +224,13 @@ ACCEPT_AGAIN:
client_fd = accept( serv_fd, &client_addr.addr, &client_addr_len );
if( client_fd < 0 ) {
if( errno == EINTR ) {
+ if( terminate ) goto OK;
/* interrupted, again */
goto ACCEPT_AGAIN;
} else if( errno == ECONNABORTED ) {
/* connection run away */
goto FIRST_ACCEPT_AGAIN;
} else {
- (void)close( serv_fd );
fprintf( stderr, "second non-blocking accept failed: %s (%d)\n", strerror( errno ), errno );
goto FAIL;
}
@@ -197,7 +242,6 @@ ACCEPT_AGAIN:
client_service, NI_MAXSERV,
NI_NUMERICSERV | NI_NUMERICHOST );
if( res < 0 ) {
- (void)close( serv_fd );
fprintf( stderr, "getnameinfo failed: %s (%d)\n",
gai_strerror( error ), error );
goto FAIL;
@@ -205,176 +249,48 @@ ACCEPT_AGAIN:
fprintf( stderr, "New connection from %s, port %s\n", client_hostname, client_service );
- (void)close( client_fd );
-
- goto FIRST_ACCEPT_AGAIN;
-
-FAIL:
- freeaddrinfo( result );
-
-#ifdef _WIN32
- WSACleanup( );
-#endif
-
- return EXIT_FAILURE;
-
-//OK:
- freeaddrinfo( result );
-
-#ifdef _WIN32
- WSACleanup( );
-#endif
-
- return EXIT_SUCCESS;
-}
-
-#if 0
-
-#if DEBUG
-static char *fd_set_to_string( fd_set *fd, int min_fd, int max_fd, char *buf, size_t buflen ) {
- int i;
- size_t j;
-
- assert( min_fd <= max_fd );
-
- for( i = min_fd, j = 0; i <= max_fd && j < buflen; i++, j++ ) {
- if( FD_ISSET( i, fd ) ) {
- buf[j] = '1';
- } else {
- buf[j] = '0';
- }
- }
-
- buf[j] = '\0';
-
- return buf;
-}
-#endif
-
-#define MAX_IDLE_TIMEOUT 10
-#define WRITE_BUFFER_SIZE 4096
-#define READ_BUFFER_SIZE 4096
-#define CONNECT_TIMEOUT 2
-
-#define max(a,b) ((a) < (b) ? (b) : (a))
-
-static volatile bool terminate = false;
-
-static void term_handler( int sig ) {
- WOLF_UNUSED( sig );
- terminate = true;
-}
-
-
-int main( int argc, char *argv[] ) {
- int res;
- int idle_secs;
- char read_buffer[READ_BUFFER_SIZE];
- char write_buffer[WRITE_BUFFER_SIZE];
- size_t stdout_to_write;
- size_t stdout_written;
- size_t fd_to_write;
- size_t fd_written;
- size_t total_stdin_read;
- size_t total_fd_read;
- size_t total_fd_written;
- size_t total_stdout_written;
- int count;
- bool stdin_eof;
- bool fd_write_closed;
- bool fd_eof;
-
-CONNECT_SELECT_AGAIN:
- sock_error_len = sizeof( int );
- res = getsockopt( fd, SOL_SOCKET, SO_ERROR, &sock_error, &sock_error_len );
- if( res < 0 ) {
- fprintf( stderr, "getsockopt for connection check failed: %s (%d)\n",
- strerror( errno ), errno );
- (void)close( fd );
- goto FAIL;
- } else {
- if( error == 0 ) {
- goto CONNECTED;
- } else {
- fprintf( stderr, "SO_ERROR is not ok: %s (%d)\n",
- strerror( error ), error );
- (void)close( fd );
- goto FAIL;
- }
- }
- } else {
- fprintf( stderr, "Socket not ready after select\n" );
- (void)close( fd );
- goto FAIL;
- }
- }
-
-CONNECTED:
+ /* handle connection input/output as echo server */
idle_secs = 0;
count = 0;
- stdout_to_write = 0;
- stdout_written = 0;
fd_to_write = 0;
fd_written = 0;
- total_stdin_read = 0;
total_fd_read = 0;
total_fd_written = 0;
- total_stdout_written = 0;
- stdin_eof = false;
- fd_write_closed = false;
fd_eof = false;
- signal( SIGTERM, term_handler );
- signal( SIGINT, term_handler );
- signal( SIGPIPE, SIG_IGN );
-
do {
ssize_t rres;
#if DEBUG
char buf[10];
char buf2[10];
#endif
-
FD_ZERO( &read_set );
FD_ZERO( &write_set );
timeout.tv_sec = 1;
timeout.tv_usec = 0;
-
- /* set up select mask and compute highest file descriptor number */
- max_fd = 0;
- max_fd = max( max_fd, STDIN_FILENO );
- max_fd = max( max_fd, STDOUT_FILENO );
- max_fd = max( max_fd, fd );
-
- if( !stdin_eof && fd_to_write == 0 ) {
- FD_SET( STDIN_FILENO, &read_set );
- }
- if( stdout_to_write > 0 ) {
- FD_SET( STDOUT_FILENO, &write_set );
- }
- if( stdout_to_write == 0 ) {
- FD_SET( fd, &read_set );
+ if( fd_to_write == 0 ) {
+ FD_SET( client_fd, &read_set );
}
if( fd_to_write > 0 ) {
- FD_SET( fd, &write_set );
+ FD_SET( client_fd, &write_set );
}
/* wait for events or timeout */
#if DEBUG
-fprintf( stderr, "select call read_fd: %s write_fd: %s wbuf: %d rbuf: %d stdin_eof: %d fdwcl: %d\n",
- fd_set_to_string( &read_set, 0, max_fd, buf, 10 ),
- fd_set_to_string( &write_set, 0, max_fd, buf2, 10 ),
- fd_to_write, stdout_to_write, stdin_eof, fd_write_closed );
+fprintf( stderr, "select call read_fd: %s write_fd: %s buf: %d eof: %d\n",
+ fd_set_to_string( &read_set, client_fd, client_fd, buf, 10 ),
+ fd_set_to_string( &write_set, client_fd, client_fd, buf2, 10 ),
+ fd_to_write, fd_eof );
#endif
- res = select( max_fd + 1, &read_set, &write_set, NULL, &timeout );
+ res = select( client_fd + 1, &read_set, &write_set, NULL, &timeout );
#if DEBUG
-fprintf( stderr, "select %04d read_fd: %s write_fd: %s wbuf: %d rbuf: %d stdin_eof: %d fdwcl: %d\n",
- res, fd_set_to_string( &read_set, 0, max_fd, buf, 10 ),
- fd_set_to_string( &write_set, 0, max_fd, buf2, 10 ),
- fd_to_write, stdout_to_write, stdin_eof, fd_write_closed );
+fprintf( stderr, "select %04d read_fd: %s write_fd: %s buf: %d eof: %d\n",
+ res, fd_set_to_string( &read_set, client_fd, client_fd, buf, 10 ),
+ fd_set_to_string( &write_set, client_fd, client_fd, buf2, 10 ),
+ fd_to_write, fd_eof );
#endif
if( res < 0 ) {
@@ -384,7 +300,6 @@ fprintf( stderr, "select %04d read_fd: %s write_fd: %s wbuf: %d rbuf: %d stdin_e
/* fatal errors */
fprintf( stderr, "select failed: %s (%d)\n",
strerror( errno ), errno );
- (void)close( fd );
goto FAIL;
}
} else if( res == 0 ) {
@@ -399,39 +314,16 @@ fprintf( stderr, "select %04d read_fd: %s write_fd: %s wbuf: %d rbuf: %d stdin_e
/* something happened */
idle_secs = 0;
- /* empty the socket read buffer to stdout */
- if( FD_ISSET( STDOUT_FILENO, &write_set ) ) {
- assert( stdout_to_write > 0 );
- rres = write( STDOUT_FILENO, read_buffer + stdout_written, stdout_to_write );
- if( rres < 0 ) {
- if( errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR ) {
- /* skip */
- } else {
- fprintf( stderr, "write to stdout failed: %s (%d)\n",
- strerror( errno ), errno );
- (void)close( fd );
- goto FAIL;
- }
- } else {
- assert( rres >= 0 );
- stdout_written += (size_t)rres;
- assert( stdout_to_write >= (size_t)rres );
- stdout_to_write -= (size_t)rres;
- total_stdout_written += (size_t)rres;
- }
- }
-
- /* empty the socket write buffer writing to fd */
- if( FD_ISSET( fd, &write_set ) ) {
+ /* if we have something to write back to the client, do that */
+ if( FD_ISSET( client_fd, &write_set ) ) {
assert( fd_to_write > 0 );
- rres = write( fd, write_buffer + fd_written, fd_to_write );
+ rres = write( client_fd, buffer + fd_written, fd_to_write );
if( rres < 0 ) {
if( errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR ) {
/* skip */
} else {
- fprintf( stderr, "write to socket failed: %s (%d)\n",
+ fprintf( stderr, "write to stdout failed: %s (%d)\n",
strerror( errno ), errno );
- (void)close( fd );
goto FAIL;
}
} else {
@@ -439,101 +331,74 @@ fprintf( stderr, "select %04d read_fd: %s write_fd: %s wbuf: %d rbuf: %d stdin_e
fd_written += (size_t)rres;
assert( fd_to_write >= (size_t)rres );
fd_to_write -= (size_t)rres;
+ fd_written += (size_t)rres;
total_fd_written += (size_t)rres;
}
}
- /* read from socket, fill socket read buffer */
- if( FD_ISSET( fd, &read_set ) ) {
- assert( stdout_to_write == 0 );
- rres = read( fd, read_buffer, READ_BUFFER_SIZE );
+ /* if there is space in the read buffer and something to be read, do so */
+ if( FD_ISSET( client_fd, &read_set ) ) {
+ assert( fd_to_write == 0 );
+ rres = read( client_fd, buffer, BUFFER_SIZE );
if( rres < 0 ) {
if( errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR ) {
/* skip */
} else {
fprintf( stderr, "read from socket failed: %s (%d)\n",
strerror( errno ), errno );
- (void)close( fd );
goto FAIL;
}
} else if( rres == 0 ) {
/* EOF on socket */
- shutdown( fd, SHUT_RD );
+ shutdown( client_fd, SHUT_RD );
fd_eof = true;
#if DEBUG
fprintf( stderr, "EOF on socket\n" );
#endif
} else {
assert( rres > 0 );
- stdout_written = 0;
- stdout_to_write = (size_t)rres;
- total_fd_read += (size_t)rres;
- }
- }
-
- /* read from stdin, fill socket write buffer */
- if( FD_ISSET( STDIN_FILENO, &read_set ) ) {
- assert( fd_to_write == 0 );
- rres = read( STDIN_FILENO, write_buffer, WRITE_BUFFER_SIZE );
- if( rres < 0 ) {
- if( errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR ) {
- /* skip */
- } else {
- fprintf( stderr, "read from stdin failed: %s (%d)\n",
- strerror( errno ), errno );
- (void)close( fd );
- goto FAIL;
- }
- } else if( rres == 0 ) {
- /* EOF on STDIN */
- stdin_eof = true;
- fclose( stdin );
-
-#if DEBUG
- fprintf( stderr, "EOF on stdin\n" );
-#endif
- } else {
- assert( rres > 0 );
fd_written = 0;
fd_to_write = (size_t)rres;
- total_stdin_read += (size_t)rres;
+ total_fd_read += (size_t)rres;
}
}
-
- /* close writing side of the socket if we have emptied
- * the socket write buffer and there is nothing more on
- * the input (stdin)
- */
- if( fd_to_write == 0 && stdin_eof && !fd_write_closed ) {
-#if DEBUG
- fprintf( stderr, "socket SHUT_WR\n" );
-#endif
- shutdown( fd, SHUT_WR );
- fd_write_closed = true;
- }
}
count++;
if( count % 10000 == 0 ) {
- fprintf( stderr, "Transfered nof_selects: %d, stdin: %zd, stdout: %zd, fd-in: %zd, fd-out: %zd\n",
- count, total_stdin_read, total_stdout_written, total_fd_read, total_fd_written );
+ fprintf( stderr, "Transfered nof_selects: %d, fd-in: %zd, fd-out: %zd\n",
+ count, total_fd_read, total_fd_written );
}
- } while( !terminate && !( stdin_eof && fd_eof ) );
+ } while( !terminate && !( fd_eof && fd_to_write == 0 ) );
END:
- fprintf( stderr, "Terminated stdin: %zd, stdout: %zd, fd-in: %zd, fd-out: %zd\n",
- total_stdin_read, total_stdout_written, total_fd_read, total_fd_written );
- res = close( fd );
- if( res < 0 ) {
- fprintf( stderr, "close failed: %s (%d)\n", strerror( errno ), errno );
- goto FAIL;
- }
-
+ fprintf( stderr, "Terminated nof_selects: %d, fd-in: %zd, fd-out: %zd\n",
+ count, total_fd_read, total_fd_written );
+
+ (void)close( client_fd );
+ (void)close( serv_fd );
freeaddrinfo( result );
goto OK;
+FAIL:
-}
+ if( client_fd >= 0 ) (void)close( client_fd );
+ if( serv_fd >= 0 ) (void)close( serv_fd );
+ if( result != NULL ) freeaddrinfo( result );
+
+#ifdef _WIN32
+ WSACleanup( );
+#endif
+
+ return EXIT_FAILURE;
+
+OK:
+
+#ifdef _WIN32
+ WSACleanup( );
#endif
+
+ return EXIT_SUCCESS;
+}