55 * found in the LICENSE file.
66 */
77
8+ #define _GNU_SOURCE
9+
10+ #include <assert.h>
811#include <arpa/inet.h>
912#include <sys/socket.h>
1013#include <assert.h>
1114#include <errno.h>
1215#include <netdb.h>
16+ #include <stdbool.h>
1317#include <stdio.h>
1418#include <stdlib.h>
1519#include <string.h>
16- #ifdef __EMSCRIPTEN__
17- #include <emscripten.h>
18- #endif
20+ #include <netdb.h>
21+
22+ void print_sockaddr (struct sockaddr_in * sa4 , int socktype , int counter ) {
23+ printf ("addr[%d] v4: (socktype=%d family=%d) %s:%d\n" , counter , socktype , sa4 -> sin_family , inet_ntoa (sa4 -> sin_addr ), ntohs (sa4 -> sin_port ));
24+ }
25+
26+ void print_sockaddr6 (struct sockaddr_in6 * sa6 , int socktype , int counter ) {
27+ char buf [1024 ];
28+ printf ("addr[%d] v6: (socktype=%d family=%d) %s:%d\n" , counter , socktype , sa6 -> sin6_family , inet_ntop (sa6 -> sin6_family , & sa6 -> sin6_addr , buf , sizeof (buf )), ntohs (sa6 -> sin6_port ));
29+ }
30+
31+ void print_addrinfo_next (struct addrinfo * info , int counter ) {
32+ if (info -> ai_family == AF_INET ) {
33+ print_sockaddr (((struct sockaddr_in * )info -> ai_addr ), info -> ai_socktype , counter );
34+ } else if (info -> ai_family == AF_INET6 ) {
35+ print_sockaddr6 (((struct sockaddr_in6 * )info -> ai_addr ), info -> ai_socktype , counter );
36+ } else {
37+ assert (false);
38+ }
39+ if (info -> ai_next ) {
40+ print_addrinfo_next (info -> ai_next , counter + 1 );
41+ }
42+ }
43+
44+ void print_addrinfo (struct addrinfo * info ) {
45+ print_addrinfo_next (info , 0 );
46+ }
47+
48+ #define CHECK_ERR (code , expected ) \
49+ do { \
50+ const char* err = gai_strerror(code); \
51+ printf("%s -> %s\n", #code, err); \
52+ assert(strcmp(err, expected) == 0); \
53+ } while (0)
1954
2055int main () {
2156 struct addrinfo hints ;
@@ -24,9 +59,15 @@ int main() {
2459 struct sockaddr_in6 * sa6 ;
2560 int err ;
2661
62+ char buf [1024 ];
63+ printf ("in6addr_loopback: %s\n" , inet_ntop (AF_INET6 , & in6addr_loopback , buf , sizeof (buf )));
64+
2765 // no name or service
2866 //err = getaddrinfo(NULL, NULL, NULL, &servinfo);
29- // XXX musl follows the spec precisely, and it does not allow both to be NULL, despite documenting EAI_NONAME as the right result for that case assert(err == EAI_NONAME);
67+
68+ // XXX musl follows the spec precisely, and it does not allow both to be NULL,
69+ // despite documenting EAI_NONAME as the right result for that case
70+ // assert(err == EAI_NONAME);
3071
3172 // invalid socket type
3273 memset (& hints , 0 , sizeof (hints ));
@@ -63,6 +104,7 @@ int main() {
63104 hints .ai_socktype = SOCK_STREAM ;
64105 err = getaddrinfo (NULL , "80" , & hints , & servinfo );
65106 assert (!err );
107+ print_addrinfo (servinfo );
66108 sa4 = ((struct sockaddr_in * )servinfo -> ai_addr );
67109 assert (servinfo -> ai_family == AF_INET );
68110 assert (servinfo -> ai_socktype == SOCK_STREAM );
@@ -77,9 +119,13 @@ int main() {
77119 err = getaddrinfo (NULL , "81" , & hints , & servinfo );
78120 assert (!err );
79121 sa6 = ((struct sockaddr_in6 * )servinfo -> ai_addr );
122+ print_addrinfo (servinfo );
80123 assert (servinfo -> ai_family == AF_INET6 );
81124 assert (servinfo -> ai_socktype == SOCK_STREAM );
82- memcmp (& sa6 -> sin6_addr , & in6addr_loopback , sizeof (in6addr_loopback ));
125+ #ifndef __EMSCRIPTEN__
126+ // TODO(sbc): This assert currently fails under emscripten, but should not
127+ assert (memcmp (& sa6 -> sin6_addr , & in6addr_loopback , sizeof (in6addr_loopback )) == 0 );
128+ #endif
83129 assert (sa6 -> sin6_port == ntohs (81 ));
84130 freeaddrinfo (servinfo );
85131
@@ -91,6 +137,7 @@ int main() {
91137 err = getaddrinfo (NULL , "82" , & hints , & servinfo );
92138 assert (!err );
93139 sa4 = ((struct sockaddr_in * )servinfo -> ai_addr );
140+ print_addrinfo (servinfo );
94141 assert (servinfo -> ai_family == AF_INET );
95142 assert (servinfo -> ai_socktype == SOCK_STREAM );
96143 assert (* (uint32_t * )& (sa4 -> sin_addr ) == 0 );
@@ -104,6 +151,7 @@ int main() {
104151 err = getaddrinfo ("1.2.3.4" , "83" , & hints , & servinfo );
105152 assert (!err );
106153 sa4 = ((struct sockaddr_in * )servinfo -> ai_addr );
154+ print_addrinfo (servinfo );
107155 assert (servinfo -> ai_family == AF_INET );
108156 assert (servinfo -> ai_socktype == SOCK_DGRAM );
109157 assert (* (uint32_t * )& (sa4 -> sin_addr ) == 67305985 );
@@ -118,6 +166,7 @@ int main() {
118166 err = getaddrinfo ("1.2.3.4" , "84" , & hints , & servinfo );
119167 assert (!err );
120168 sa6 = ((struct sockaddr_in6 * )servinfo -> ai_addr );
169+ print_addrinfo (servinfo );
121170 assert (servinfo -> ai_family == AF_INET6 );
122171 assert (servinfo -> ai_socktype == SOCK_STREAM );
123172 assert (* ((uint32_t * )& (sa6 -> sin6_addr )+ 2 ) == htonl (0xffff ));
@@ -143,6 +192,7 @@ int main() {
143192 err = getaddrinfo ("2001:0db8:85a3:0042:1000:8a2e:0370:7334" , "86" , & hints , & servinfo );
144193 assert (!err );
145194 sa6 = ((struct sockaddr_in6 * )servinfo -> ai_addr );
195+ print_addrinfo (servinfo );
146196 assert (servinfo -> ai_family == AF_INET6 );
147197 assert (servinfo -> ai_socktype == SOCK_DGRAM );
148198 assert (* ((uint32_t * )& (sa6 -> sin6_addr )+ 0 ) == -1207107296 );
@@ -178,6 +228,7 @@ int main() {
178228 err = getaddrinfo ("www.mozilla.org" , "89" , & hints , & servinfo );
179229 assert (!err );
180230 sa4 = ((struct sockaddr_in * )servinfo -> ai_addr );
231+ print_addrinfo (servinfo );
181232 assert (servinfo -> ai_family == AF_INET );
182233 assert (servinfo -> ai_socktype == SOCK_STREAM );
183234 assert (sa4 -> sin_port == ntohs (89 ));
@@ -187,9 +238,10 @@ int main() {
187238 memset (& hints , 0 , sizeof (hints ));
188239 hints .ai_family = AF_INET6 ;
189240 hints .ai_socktype = SOCK_STREAM ;
190- err = getaddrinfo ("www.mozilla.org " , "90" , & hints , & servinfo );
241+ err = getaddrinfo ("www.google.com " , "90" , & hints , & servinfo );
191242 assert (!err );
192243 sa6 = ((struct sockaddr_in6 * )servinfo -> ai_addr );
244+ print_addrinfo (servinfo );
193245 assert (servinfo -> ai_family == AF_INET6 );
194246 assert (servinfo -> ai_socktype == SOCK_STREAM );
195247 assert (* ((uint32_t * )& (sa6 -> sin6_addr )+ 0 ) != 0 ||
@@ -210,52 +262,55 @@ int main() {
210262 // test numeric host
211263 err = getaddrinfo ("1.2.3.4" , "85" , NULL , & servinfo );
212264 assert (!err );
265+ print_addrinfo (servinfo );
213266 sa4 = ((struct sockaddr_in * )servinfo -> ai_addr );
214267 assert (servinfo -> ai_family == AF_INET );
215268 assert (servinfo -> ai_socktype == SOCK_STREAM );
216269 assert (servinfo -> ai_protocol == IPPROTO_TCP );
217270 assert (sa4 -> sin_port == ntohs (85 ));
218- assert (servinfo -> ai_next == NULL );
219271 freeaddrinfo (servinfo );
220272
221273 // test non-numeric host
222274 err = getaddrinfo ("www.mozilla.org" , "89" , NULL , & servinfo );
223275 assert (!err );
276+ print_addrinfo (servinfo );
224277 sa4 = ((struct sockaddr_in * )servinfo -> ai_addr );
225278 assert (servinfo -> ai_family == AF_INET );
226279 assert (servinfo -> ai_socktype == SOCK_STREAM );
227280 assert (servinfo -> ai_protocol == IPPROTO_TCP );
228281 assert (sa4 -> sin_port == ntohs (89 ));
229- assert (servinfo -> ai_next == NULL );
230282 freeaddrinfo (servinfo );
231283
232284 // test loopback resolution
233- err = getaddrinfo (NULL , "80" , NULL , & servinfo );
285+ hints .ai_family = AF_INET ;
286+ err = getaddrinfo (NULL , "80" , & hints , & servinfo );
234287 assert (!err );
288+ print_addrinfo (servinfo );
235289 sa4 = ((struct sockaddr_in * )servinfo -> ai_addr );
236290 assert (servinfo -> ai_family == AF_INET );
237291 assert (servinfo -> ai_socktype == SOCK_STREAM );
238292 assert (servinfo -> ai_protocol == IPPROTO_TCP );
239293 assert (sa4 -> sin_port == ntohs (80 ));
240- assert (servinfo -> ai_next == NULL );
241294 freeaddrinfo (servinfo );
242295
296+ #ifdef __EMSCRIPTEN__
243297 // test gai_strerror
244- assert (strcmp (gai_strerror (0 ), "Unknown error" ) == 0 );
245- assert (strcmp (gai_strerror (EAI_BADFLAGS ), "Invalid flags" ) == 0 );
246- assert (strcmp (gai_strerror (EAI_NONAME ), "Name does not resolve" ) == 0 );
247- assert (strcmp (gai_strerror (EAI_AGAIN ), "Try again" ) == 0 );
248- assert (strcmp (gai_strerror (EAI_FAIL ), "Non-recoverable error" ) == 0 );
249- assert (strcmp (gai_strerror (EAI_FAMILY ), "Unrecognized address family or invalid length" ) == 0 );
250- assert (strcmp (gai_strerror (EAI_SOCKTYPE ), "Unrecognized socket type" ) == 0 );
251- assert (strcmp (gai_strerror (EAI_SERVICE ), "Unrecognized service" ) == 0 );
252- assert (strcmp (gai_strerror (EAI_MEMORY ), "Out of memory" ) == 0 );
253- assert (strcmp (gai_strerror (EAI_SYSTEM ), "System error" ) == 0 );
254- assert (strcmp (gai_strerror (EAI_OVERFLOW ), "Overflow" ) == 0 );
255- assert (strcmp (gai_strerror (EAI_NODATA ), "Name has no usable address" ) == 0 );
256- assert (strcmp (gai_strerror (-9 ), "Unknown error" ) == 0 );
257- assert (strcmp (gai_strerror (-13 ), "Unknown error" ) == 0 );
258- assert (strcmp (gai_strerror (-100 ), "Unknown error" ) == 0 );
298+ CHECK_ERR (0 , "Unknown error" );
299+ CHECK_ERR (EAI_BADFLAGS , "Invalid flags" );
300+ CHECK_ERR (EAI_NONAME , "Name does not resolve" );
301+ CHECK_ERR (EAI_AGAIN , "Try again" );
302+ CHECK_ERR (EAI_FAIL , "Non-recoverable error" );
303+ CHECK_ERR (EAI_FAMILY , "Unrecognized address family or invalid length" );
304+ CHECK_ERR (EAI_SOCKTYPE , "Unrecognized socket type" );
305+ CHECK_ERR (EAI_SERVICE , "Unrecognized service" );
306+ CHECK_ERR (EAI_MEMORY , "Out of memory" );
307+ CHECK_ERR (EAI_SYSTEM , "System error" );
308+ CHECK_ERR (EAI_OVERFLOW , "Overflow" );
309+ CHECK_ERR (EAI_NODATA , "Name has no usable address" );
310+ CHECK_ERR (-9 , "Unknown error" );
311+ CHECK_ERR (-13 , "Unknown error" );
312+ CHECK_ERR (-100 , "Unknown error" );
313+ #endif
259314
260315 puts ("success" );
261316
0 commit comments