From 576cb107328b42105563ca8235c7a0d39c0607a0 Mon Sep 17 00:00:00 2001 From: toddouska Date: Wed, 10 Apr 2013 17:09:53 -0700 Subject: [PATCH 1/3] fix port 0 hack for unit tests with ipv6 --- cyassl/test.h | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/cyassl/test.h b/cyassl/test.h index bd4e41583..b675b413e 100644 --- a/cyassl/test.h +++ b/cyassl/test.h @@ -487,11 +487,15 @@ static INLINE void tcp_listen(SOCKET_T* sockfd, int* port, int useAnyAddr, err_sys("tcp listen failed"); } #if defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API) - if (*port == 0) - { + if (*port == 0) { socklen_t len = sizeof(addr); - if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) - *port = ntohs(addr.sin_port); + if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) { + #ifndef TEST_IPV6 + *port = ntohs(addr.sin_port); + #else + *port = ntohs(addr.sin6_port); + #endif + } } #endif } @@ -541,11 +545,15 @@ static INLINE void udp_accept(SOCKET_T* sockfd, int* clientfd, int useAnyAddr, err_sys("tcp bind failed"); #if defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API) - if (port == 0) - { + if (port == 0) { socklen_t len = sizeof(addr); - if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) - port = ntohs(addr.sin_port); + if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) { + #ifndef TEST_IPV6 + port = ntohs(addr.sin_port); + #else + port = ntohs(addr.sin6_port); + #endif + } } #endif From b5c43d8ad48179e3d42288ba35503ce09a93ecb6 Mon Sep 17 00:00:00 2001 From: toddouska Date: Thu, 11 Apr 2013 10:12:15 -0700 Subject: [PATCH 2/3] don't default to loopback only for ipv6 tests, if inet_pton available allow lookups --- configure.ac | 1 + cyassl/test.h | 41 ++++++++++++++++++++++++++++------------- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/configure.ac b/configure.ac index 62d8b6209..69fcbb446 100644 --- a/configure.ac +++ b/configure.ac @@ -60,6 +60,7 @@ m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) AX_CXX_COMPILER_VERSION AC_CHECK_FUNCS([gethostbyname]) +AC_CHECK_FUNCS([inet_pton]) AC_CHECK_FUNCS([gettimeofday]) AC_CHECK_FUNCS([inet_ntoa]) AC_CHECK_FUNCS([memset]) diff --git a/cyassl/test.h b/cyassl/test.h index b675b413e..d7137035c 100644 --- a/cyassl/test.h +++ b/cyassl/test.h @@ -163,7 +163,11 @@ void start_thread(THREAD_FUNC, func_args*, THREAD_TYPE*); void join_thread(THREAD_TYPE); /* yaSSL */ -static const char* const yasslIP = "127.0.0.1"; +#ifndef TEST_IPV6 + static const char* const yasslIP = "127.0.0.1"; +#else + static const char* const yasslIP = "::1"; +#endif static const word16 yasslPort = 11111; @@ -331,39 +335,50 @@ static INLINE void showPeer(CYASSL* ssl) static INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer, word16 port) { -#ifndef TEST_IPV6 - const char* host = peer; + int useLookup = 0; + (void)useLookup; + memset(addr, 0, sizeof(SOCKADDR_IN_T)); + +#ifndef TEST_IPV6 /* peer could be in human readable form */ if (peer != INADDR_ANY && isalpha((int)peer[0])) { struct hostent* entry = gethostbyname(peer); if (entry) { - struct sockaddr_in tmp; - memset(&tmp, 0, sizeof(struct sockaddr_in)); - memcpy(&tmp.sin_addr.s_addr, entry->h_addr_list[0], + memcpy(&addr->sin_addr.s_addr, entry->h_addr_list[0], entry->h_length); - host = inet_ntoa(tmp.sin_addr); + useLookup = 1; } else err_sys("no entry for host"); } #endif - memset(addr, 0, sizeof(SOCKADDR_IN_T)); #ifndef TEST_IPV6 addr->sin_family = AF_INET_V; addr->sin_port = htons(port); - if (host == INADDR_ANY) + if (peer == INADDR_ANY) addr->sin_addr.s_addr = INADDR_ANY; - else - addr->sin_addr.s_addr = inet_addr(host); + else { + if (!useLookup) + addr->sin_addr.s_addr = inet_addr(peer); + } #else - (void)peer; addr->sin6_family = AF_INET_V; addr->sin6_port = htons(port); - addr->sin6_addr = in6addr_loopback; + if (peer == INADDR_ANY) + addr->sin6_addr = in6addr_any; + else { + #ifdef HAVE_INET_PTON + if (inet_pton(AF_INET_V, peer, &addr->sin6_addr) != 1) + err_sys("ipv6 lookup failed"); + #else + printf("no ipv6 inet_pton, loopback only tests/examples\n"); + addr->sin6_addr = in6addr_loopback; + #endif + } #endif } From 12f00a7accb1782492c2bdae18b53dd1e15894ae Mon Sep 17 00:00:00 2001 From: toddouska Date: Thu, 11 Apr 2013 12:30:09 -0700 Subject: [PATCH 3/3] change ipv6 tests to use getaddrinfo for better scope id % handling, inet_pton doesn't always work depending on system --- configure.ac | 2 +- cyassl/test.h | 37 ++++++++++++++++++++++++-------- examples/client/client.c | 4 ++-- examples/echoclient/echoclient.c | 2 +- 4 files changed, 32 insertions(+), 13 deletions(-) diff --git a/configure.ac b/configure.ac index 69fcbb446..40548857d 100644 --- a/configure.ac +++ b/configure.ac @@ -60,7 +60,7 @@ m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) AX_CXX_COMPILER_VERSION AC_CHECK_FUNCS([gethostbyname]) -AC_CHECK_FUNCS([inet_pton]) +AC_CHECK_FUNCS([getaddrinfo]) AC_CHECK_FUNCS([gettimeofday]) AC_CHECK_FUNCS([inet_ntoa]) AC_CHECK_FUNCS([memset]) diff --git a/cyassl/test.h b/cyassl/test.h index d7137035c..94a556b65 100644 --- a/cyassl/test.h +++ b/cyassl/test.h @@ -332,11 +332,12 @@ static INLINE void showPeer(CYASSL* ssl) } -static INLINE void build_addr(SOCKADDR_IN_T* addr, - const char* peer, word16 port) +static INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer, + word16 port, int udp) { int useLookup = 0; (void)useLookup; + (void)udp; memset(addr, 0, sizeof(SOCKADDR_IN_T)); @@ -371,11 +372,29 @@ static INLINE void build_addr(SOCKADDR_IN_T* addr, if (peer == INADDR_ANY) addr->sin6_addr = in6addr_any; else { - #ifdef HAVE_INET_PTON - if (inet_pton(AF_INET_V, peer, &addr->sin6_addr) != 1) - err_sys("ipv6 lookup failed"); + #ifdef HAVE_GETADDRINFO + struct addrinfo hints; + struct addrinfo* answer = NULL; + int ret; + char strPort[80]; + + memset(&hints, 0, sizeof(hints)); + + hints.ai_family = AF_INET_V; + hints.ai_socktype = udp ? SOCK_DGRAM : SOCK_STREAM; + hints.ai_protocol = udp ? IPPROTO_UDP : IPPROTO_TCP; + + snprintf(strPort, sizeof(strPort), "%d", port); + strPort[79] = '\0'; + + ret = getaddrinfo(peer, strPort, &hints, &answer); + if (ret < 0 || answer == NULL) + err_sys("getaddrinfo failed"); + + memcpy(addr, answer->ai_addr, answer->ai_addrlen); + freeaddrinfo(answer); #else - printf("no ipv6 inet_pton, loopback only tests/examples\n"); + printf("no ipv6 getaddrinfo, loopback only tests/examples\n"); addr->sin6_addr = in6addr_loopback; #endif } @@ -424,7 +443,7 @@ static INLINE void tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port, int udp) { SOCKADDR_IN_T addr; - build_addr(&addr, ip, port); + build_addr(&addr, ip, port, udp); tcp_socket(sockfd, udp); if (!udp) { @@ -482,7 +501,7 @@ static INLINE void tcp_listen(SOCKET_T* sockfd, int* port, int useAnyAddr, /* don't use INADDR_ANY by default, firewall may block, make user switch on */ - build_addr(&addr, (useAnyAddr ? INADDR_ANY : yasslIP), *port); + build_addr(&addr, (useAnyAddr ? INADDR_ANY : yasslIP), *port, udp); tcp_socket(sockfd, udp); #ifndef USE_WINDOWS_API @@ -542,7 +561,7 @@ static INLINE void udp_accept(SOCKET_T* sockfd, int* clientfd, int useAnyAddr, SOCKADDR_IN_T addr; (void)args; - build_addr(&addr, (useAnyAddr ? INADDR_ANY : yasslIP), port); + build_addr(&addr, (useAnyAddr ? INADDR_ANY : yasslIP), port, 1); tcp_socket(sockfd, 1); diff --git a/examples/client/client.c b/examples/client/client.c index b223e20ed..4b0a0470d 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -439,7 +439,7 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args) err_sys("unable to get SSL object"); if (doDTLS) { SOCKADDR_IN_T addr; - build_addr(&addr, host, port); + build_addr(&addr, host, port, 1); CyaSSL_dtls_set_peer(ssl, &addr, sizeof(addr)); tcp_socket(&sockfd, 1); } @@ -538,7 +538,7 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args) #else sleep(1); #endif - build_addr(&addr, host, port); + build_addr(&addr, host, port, 1); CyaSSL_dtls_set_peer(sslResume, &addr, sizeof(addr)); tcp_socket(&sockfd, 1); } diff --git a/examples/echoclient/echoclient.c b/examples/echoclient/echoclient.c index ec5fad42f..95ccb529c 100644 --- a/examples/echoclient/echoclient.c +++ b/examples/echoclient/echoclient.c @@ -135,7 +135,7 @@ void echoclient_test(void* args) if (doDTLS) { SOCKADDR_IN_T addr; - build_addr(&addr, yasslIP, port); + build_addr(&addr, yasslIP, port, 1); CyaSSL_dtls_set_peer(ssl, &addr, sizeof(addr)); tcp_socket(&sockfd, 1); }