diff options
author | Andreas Baumann <abaumann@yahoo.com> | 2009-04-05 11:50:00 +0200 |
---|---|---|
committer | Andreas Baumann <abaumann@yahoo.com> | 2009-04-05 11:50:00 +0200 |
commit | de4618540ea7665e01d2fd8b60edf3c2cdde5e34 (patch) | |
tree | 60a3f2995e844728693fe2b8a8a255ce70464316 /tests/network | |
parent | 54a4cb25f54ea65440c1bb5d07d30acac684f73c (diff) | |
download | wolfbones-de4618540ea7665e01d2fd8b60edf3c2cdde5e34.tar.gz wolfbones-de4618540ea7665e01d2fd8b60edf3c2cdde5e34.tar.bz2 |
more tests about asynchonous connects and aligned sockaddr unions
Diffstat (limited to 'tests/network')
-rw-r--r-- | tests/network/test1.c | 45 |
1 files changed, 41 insertions, 4 deletions
diff --git a/tests/network/test1.c b/tests/network/test1.c index 3f8c8a5..93ff240 100644 --- a/tests/network/test1.c +++ b/tests/network/test1.c @@ -4,7 +4,7 @@ * no connection). */ -#include "port/netdb.h" /* for getaddrinfo */ +#include "port/netdb.h" /* for getaddrinfo, getnameinfo */ #include "port/stdlib.h" /* for EXIT_XXX */ #include "port/stdio.h" /* for fprintf */ #include "port/string.h" /* for memset */ @@ -59,13 +59,21 @@ static char *fd_set_to_string( fd_set *fd, int min_fd, int max_fd, char *buf, si #define max(a,b) ((a) < (b) ? (b) : (a)) -static bool terminate = false; +static volatile bool terminate = false; static void term_handler( int sig ) { WOLF_UNUSED( sig ); terminate = true; } +/* helper union to avoid anti-aliasing warnings in old network functions like getpeername */ +union sockaddr_union { + struct sockaddr_storage storage; + struct sockaddr_in in; + struct sockaddr_in6 in6; + struct sockaddr addr; +}; + int main( int argc, char *argv[] ) { char *host; char *service; @@ -93,6 +101,10 @@ int main( int argc, char *argv[] ) { fd_set read_set; fd_set write_set; struct timeval timeout; + socklen_t peer_addr_len; + union sockaddr_union peer_addr; + char peer_hostname[NI_MAXHOST] = ""; + char peer_service[NI_MAXSERV] = ""; if( argc != 3 ) { fprintf( stderr, "usage: test1 <host> <port>\n" ); @@ -136,12 +148,17 @@ int main( int argc, char *argv[] ) { goto FAIL; } - /* connect asynchronously */ + /* connect asynchronously, from now on no matter what happens (for instance an + * interrupt by a signal) the kernel tries to establish the connection! So we + * don't have to go back into a connect.. + */ res = connect( fd, result->ai_addr, result->ai_addrlen ); if( res < 0 ) { if( errno == EINPROGRESS ) { /* this is ok, being connected, we loop later in a select */ fprintf( stderr, "connecting in progress..\n" ); + } else if( errno == EINTR ) { + /* interrupted, no problem, the connection goes on anyway */ } else { (void)close( fd ); fprintf( stderr, "connect failed: %s (%d)\n", strerror( errno ), errno ); @@ -205,7 +222,27 @@ CONNECT_SELECT_AGAIN: } CONNECTED: - fprintf( stderr, "Connected to %s, port %s\n", host, service ); + /* determine the address of the other end of the connection */ + peer_addr_len = sizeof( peer_addr ); + res = getsockname( fd, &peer_addr.addr, &peer_addr_len ); + if( res < 0 ) { + (void)close( fd ); + fprintf( stderr, "getsockname failed: %s (%d)\n", strerror( errno ), errno ); + goto FAIL; + } + res = getnameinfo( &peer_addr.addr, peer_addr_len, + peer_hostname, NI_MAXHOST, + peer_service, NI_MAXSERV, + NI_NUMERICSERV | NI_NUMERICHOST ); + if( res < 0 ) { + (void)close( fd ); + fprintf( stderr, "getnameinfo failed: %s (%d)\n", + gai_strerror( error ), error ); + goto FAIL; + } + + fprintf( stderr, "Connected to %s, port %s (peer: %s, %s)\n", host, service, + peer_hostname, peer_service ); if( !wolf_network_sock_nonblocking( STDIN_FILENO ) ) { (void)close( fd ); |