aboutsummaryrefslogtreecommitdiff
path: root/tests/sockets/test_getaddrinfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/sockets/test_getaddrinfo.c')
-rw-r--r--tests/sockets/test_getaddrinfo.c197
1 files changed, 197 insertions, 0 deletions
diff --git a/tests/sockets/test_getaddrinfo.c b/tests/sockets/test_getaddrinfo.c
new file mode 100644
index 00000000..717a9ae7
--- /dev/null
+++ b/tests/sockets/test_getaddrinfo.c
@@ -0,0 +1,197 @@
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <assert.h>
+#include <errno.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if EMSCRIPTEN
+#include <emscripten.h>
+#endif
+
+int main() {
+ struct addrinfo hints;
+ struct addrinfo *servinfo;
+ struct sockaddr_in *sa4;
+ struct sockaddr_in6 *sa6;
+ int err;
+
+ // no name or service
+ err = getaddrinfo(NULL, NULL, NULL, &servinfo);
+ assert(err == EAI_NONAME);
+
+ // invalid socket type
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = 9999;
+ err = getaddrinfo("www.mozilla.org", "80", &hints, &servinfo);
+#ifdef __APPLE__
+ assert(err == EAI_BADHINTS);
+#else
+ assert(err == EAI_SOCKTYPE);
+#endif
+
+ // invalid family
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNIX;
+ hints.ai_socktype = SOCK_STREAM;
+ err = getaddrinfo("www.mozilla.org", "80", &hints, &servinfo);
+ assert(err == EAI_FAMILY);
+
+ // invalid service
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_STREAM;
+ err = getaddrinfo("www.mozilla.org", "foobar", &hints, &servinfo);
+#ifdef __APPLE__
+ assert(err == EAI_NONAME);
+#else
+ assert(err == EAI_SERVICE);
+#endif
+
+ // test loopback resolution (ipv4)
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_STREAM;
+ err = getaddrinfo(NULL, "80", &hints, &servinfo);
+ assert(!err);
+ sa4 = ((struct sockaddr_in*)servinfo->ai_addr);
+ assert(servinfo->ai_family == AF_INET);
+ assert(servinfo->ai_socktype == SOCK_STREAM);
+ assert(*(uint32_t*)&(sa4->sin_addr) == ntohl(INADDR_LOOPBACK));
+ assert(sa4->sin_port == ntohs(80));
+ freeaddrinfo(servinfo);
+
+ // test loopback resolution (ipv6)
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET6;
+ hints.ai_socktype = SOCK_STREAM;
+ err = getaddrinfo(NULL, "81", &hints, &servinfo);
+ assert(!err);
+ sa6 = ((struct sockaddr_in6*)servinfo->ai_addr);
+ assert(servinfo->ai_family == AF_INET6);
+ assert(servinfo->ai_socktype == SOCK_STREAM);
+ memcmp(&sa6->sin6_addr, &in6addr_loopback, sizeof(in6addr_loopback));
+ assert(sa6->sin6_port == ntohs(81));
+ freeaddrinfo(servinfo);
+
+ // test bind preparation
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_PASSIVE;
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_STREAM;
+ err = getaddrinfo(NULL, "82", &hints, &servinfo);
+ assert(!err);
+ sa4 = ((struct sockaddr_in*)servinfo->ai_addr);
+ assert(servinfo->ai_family == AF_INET);
+ assert(servinfo->ai_socktype == SOCK_STREAM);
+ assert(*(uint32_t*)&(sa4->sin_addr) == 0);
+ assert(sa4->sin_port == ntohs(82));
+ freeaddrinfo(servinfo);
+
+ // test numeric address (ipv4)
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_DGRAM;
+ err = getaddrinfo("1.2.3.4", "83", &hints, &servinfo);
+ assert(!err);
+ sa4 = ((struct sockaddr_in*)servinfo->ai_addr);
+ assert(servinfo->ai_family == AF_INET);
+ assert(servinfo->ai_socktype == SOCK_DGRAM);
+ assert(*(uint32_t*)&(sa4->sin_addr) == 67305985);
+ assert(sa4->sin_port == ntohs(83));
+ freeaddrinfo(servinfo);
+
+ // test numeric address (ipv4 address specified as ipv6 with AI_V4MAPPED)
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_V4MAPPED;
+ hints.ai_family = AF_INET6;
+ hints.ai_socktype = SOCK_STREAM;
+ err = getaddrinfo("1.2.3.4", "84", &hints, &servinfo);
+ assert(!err);
+ sa6 = ((struct sockaddr_in6*)servinfo->ai_addr);
+ assert(servinfo->ai_family == AF_INET6);
+ assert(servinfo->ai_socktype == SOCK_STREAM);
+ assert(*((uint32_t*)&(sa6->sin6_addr)+2) == htonl(0xffff));
+ assert(*((uint32_t*)&(sa6->sin6_addr)+3) == 67305985);
+ assert(sa6->sin6_port == ntohs(84));
+ freeaddrinfo(servinfo);
+
+ // test numeric address (ipv4 address specified as ipv6 without AI_V4MAPPED)
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET6;
+ hints.ai_socktype = SOCK_STREAM;
+ err = getaddrinfo("1.2.3.4", "85", &hints, &servinfo);
+#ifdef __linux__
+ assert(err == -9 /* EAI_ADDRFAMILY */);
+#else
+ assert(err == EAI_NONAME);
+#endif
+
+ // test numeric address (ipv6)
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET6;
+ hints.ai_socktype = SOCK_DGRAM;
+ err = getaddrinfo("2001:0db8:85a3:0042:1000:8a2e:0370:7334", "86", &hints, &servinfo);
+ assert(!err);
+ sa6 = ((struct sockaddr_in6*)servinfo->ai_addr);
+ assert(servinfo->ai_family == AF_INET6);
+ assert(servinfo->ai_socktype == SOCK_DGRAM);
+ assert(*((uint32_t*)&(sa6->sin6_addr)+0) == -1207107296);
+ assert(*((uint32_t*)&(sa6->sin6_addr)+1) == 1107338117);
+ assert(*((uint32_t*)&(sa6->sin6_addr)+2) == 780795920);
+ assert(*((uint32_t*)&(sa6->sin6_addr)+3) == 879980547);
+ assert(sa6->sin6_port == ntohs(86));
+ freeaddrinfo(servinfo);
+
+ // test numeric address (ipv6 address specified as ipv4)
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_STREAM;
+ err = getaddrinfo("2001:0db8:85a3:0042:1000:8a2e:0370:7334", "87", &hints, &servinfo);
+#ifdef __linux__
+ assert(err == -9 /* EAI_ADDRFAMILY */);
+#else
+ assert(err == EAI_NONAME);
+#endif
+
+ // test non-numeric host with AI_NUMERICHOST
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_NUMERICHOST;
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_STREAM;
+ err = getaddrinfo("www.mozilla.org", "88", &hints, &servinfo);
+ assert(err == EAI_NONAME);
+
+ // test non-numeric host with AF_INET
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_STREAM;
+ err = getaddrinfo("www.mozilla.org", "89", &hints, &servinfo);
+ assert(!err);
+ sa4 = ((struct sockaddr_in*)servinfo->ai_addr);
+ assert(servinfo->ai_family == AF_INET);
+ assert(servinfo->ai_socktype == SOCK_STREAM);
+ assert(sa4->sin_port == ntohs(89));
+
+ // test non-numeric host with AF_INET6
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET6;
+ hints.ai_socktype = SOCK_STREAM;
+ err = getaddrinfo("www.mozilla.org", "90", &hints, &servinfo);
+ assert(!err);
+ sa6 = ((struct sockaddr_in6*)servinfo->ai_addr);
+ assert(servinfo->ai_family == AF_INET6);
+ assert(servinfo->ai_socktype == SOCK_STREAM);
+ assert(*((uint32_t*)&(sa6->sin6_addr)+0) != 0 ||
+ *((uint32_t*)&(sa6->sin6_addr)+1) != 0 ||
+ *((uint32_t*)&(sa6->sin6_addr)+2) != 0 ||
+ *((uint32_t*)&(sa6->sin6_addr)+3) != 0);
+ assert(sa6->sin6_port == ntohs(90));
+
+ puts("success");
+
+ return EXIT_SUCCESS;
+}
+