1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "testutil.h"
18 #include "testsock.h"
19 #include "apr_thread_proc.h"
20 #include "apr_network_io.h"
21 #include "apr_errno.h"
22 #include "apr_general.h"
23 #include "apr_lib.h"
24 #include "apr_strings.h"
25 #include "apr_poll.h"
26 #define APR_WANT_BYTEFUNC
27 #include "apr_want.h"
28
29 #define UNIX_SOCKET_NAME "/tmp/apr-socket"
30 #define IPV4_SOCKET_NAME "127.0.0.1"
31 static char *socket_name = NULL;
32 static int socket_type = APR_INET;
33
launch_child(abts_case * tc,apr_proc_t * proc,const char * arg1,apr_pool_t * p)34 static void launch_child(abts_case *tc, apr_proc_t *proc, const char *arg1, apr_pool_t *p)
35 {
36 apr_procattr_t *procattr;
37 const char *args[4];
38 apr_status_t rv;
39
40 rv = apr_procattr_create(&procattr, p);
41 APR_ASSERT_SUCCESS(tc, "Couldn't create procattr", rv);
42
43 rv = apr_procattr_io_set(procattr, APR_NO_PIPE, APR_NO_PIPE,
44 APR_NO_PIPE);
45 APR_ASSERT_SUCCESS(tc, "Couldn't set io in procattr", rv);
46
47 rv = apr_procattr_error_check_set(procattr, 1);
48 APR_ASSERT_SUCCESS(tc, "Couldn't set error check in procattr", rv);
49
50 rv = apr_procattr_cmdtype_set(procattr, APR_PROGRAM_ENV);
51 APR_ASSERT_SUCCESS(tc, "Couldn't set copy environment", rv);
52
53 args[0] = "sockchild" EXTENSION;
54 args[1] = arg1;
55 args[2] = socket_name;
56 args[3] = NULL;
57 rv = apr_proc_create(proc, TESTBINPATH "sockchild" EXTENSION, args, NULL,
58 procattr, p);
59 APR_ASSERT_SUCCESS(tc, "Couldn't launch program", rv);
60 }
61
wait_child(abts_case * tc,apr_proc_t * proc)62 static int wait_child(abts_case *tc, apr_proc_t *proc)
63 {
64 int exitcode;
65 apr_exit_why_e why;
66
67 ABTS_ASSERT(tc, "Error waiting for child process",
68 apr_proc_wait(proc, &exitcode, &why, APR_WAIT) == APR_CHILD_DONE);
69
70 ABTS_ASSERT(tc, "child terminated normally", why == APR_PROC_EXIT);
71 return exitcode;
72 }
73
test_addr_info(abts_case * tc,void * data)74 static void test_addr_info(abts_case *tc, void *data)
75 {
76 apr_status_t rv;
77 apr_sockaddr_t *sa;
78 int rc;
79
80 rv = apr_sockaddr_info_get(&sa, NULL, APR_UNSPEC, 80, 0, p);
81 APR_ASSERT_SUCCESS(tc, "Problem generating sockaddr", rv);
82
83 rc = apr_sockaddr_is_wildcard(sa);
84 ABTS_INT_NEQUAL(tc, 0, rc);
85
86 rv = apr_sockaddr_info_get(&sa, "127.0.0.1", APR_UNSPEC, 80, 0, p);
87 APR_ASSERT_SUCCESS(tc, "Problem generating sockaddr", rv);
88 ABTS_STR_EQUAL(tc, "127.0.0.1", sa->hostname);
89
90 rc = apr_sockaddr_is_wildcard(sa);
91 ABTS_INT_EQUAL(tc, 0, rc);
92
93 rv = apr_sockaddr_info_get(&sa, "127.0.0.1", APR_UNSPEC, 0, 0, p);
94 APR_ASSERT_SUCCESS(tc, "Problem generating sockaddr", rv);
95 ABTS_STR_EQUAL(tc, "127.0.0.1", sa->hostname);
96 ABTS_INT_EQUAL(tc, 0, sa->port);
97 ABTS_INT_EQUAL(tc, 0, ntohs(sa->sa.sin.sin_port));
98 }
99
test_addr_copy(abts_case * tc,void * data)100 static void test_addr_copy(abts_case *tc, void *data)
101 {
102 apr_status_t rv;
103 apr_sockaddr_t *sa1, *sa2;
104 int rc;
105 const char *hosts[] = {
106 "127.0.0.1",
107 #if APR_HAVE_IPV6
108 "::1",
109 #endif
110 NULL
111 }, **host = hosts;
112
113 /* Loop up to and including NULL */
114 do {
115 rv = apr_sockaddr_info_get(&sa1, *host, APR_UNSPEC, 80, 0, p);
116 APR_ASSERT_SUCCESS(tc, "Problem generating sockaddr", rv);
117
118 rv = apr_sockaddr_info_copy(&sa2, sa1, p);
119 APR_ASSERT_SUCCESS(tc, "Problem copying sockaddr", rv);
120
121 ABTS_PTR_NOTNULL(tc, sa1);
122 do {
123 ABTS_PTR_NOTNULL(tc, sa2);
124
125 rc = apr_sockaddr_equal(sa2, sa1);
126 ABTS_INT_NEQUAL(tc, 0, rc);
127 ABTS_INT_EQUAL(tc, 80, sa1->port);
128 ABTS_INT_EQUAL(tc, sa2->port, sa1->port);
129 ABTS_INT_EQUAL(tc, 80, ntohs(sa1->sa.sin.sin_port));
130 ABTS_INT_EQUAL(tc, ntohs(sa2->sa.sin.sin_port), ntohs(sa1->sa.sin.sin_port));
131
132 if (*host) {
133 ABTS_PTR_NOTNULL(tc, sa1->hostname);
134 ABTS_PTR_NOTNULL(tc, sa2->hostname);
135 ABTS_STR_EQUAL(tc, *host, sa1->hostname);
136 ABTS_STR_EQUAL(tc, sa1->hostname, sa2->hostname);
137 ABTS_TRUE(tc, sa1->hostname != sa2->hostname);
138 }
139 else {
140 ABTS_PTR_EQUAL(tc, NULL, sa1->hostname);
141 ABTS_PTR_EQUAL(tc, NULL, sa2->hostname);
142 }
143
144 } while ((sa2 = sa2->next, sa1 = sa1->next));
145 ABTS_PTR_EQUAL(tc, NULL, sa2);
146
147 } while (*host++);
148 }
149
test_serv_by_name(abts_case * tc,void * data)150 static void test_serv_by_name(abts_case *tc, void *data)
151 {
152 apr_status_t rv;
153 apr_sockaddr_t *sa;
154
155 rv = apr_sockaddr_info_get(&sa, NULL, APR_UNSPEC, 0, 0, p);
156 APR_ASSERT_SUCCESS(tc, "Problem generating sockaddr", rv);
157
158 rv = apr_getservbyname(sa, "ftp");
159 APR_ASSERT_SUCCESS(tc, "Problem getting ftp service", rv);
160 ABTS_INT_EQUAL(tc, 21, sa->port);
161
162 rv = apr_getservbyname(sa, "complete_and_utter_rubbish");
163 APR_ASSERT_SUCCESS(tc, "Problem getting non-existent service", !rv);
164
165 rv = apr_getservbyname(sa, "telnet");
166 APR_ASSERT_SUCCESS(tc, "Problem getting telnet service", rv);
167 ABTS_INT_EQUAL(tc, 23, sa->port);
168 }
169
setup_socket(abts_case * tc)170 static apr_socket_t *setup_socket(abts_case *tc)
171 {
172 apr_status_t rv;
173 apr_sockaddr_t *sa;
174 apr_socket_t *sock;
175
176 rv = apr_sockaddr_info_get(&sa, socket_name, socket_type, 8021, 0, p);
177 APR_ASSERT_SUCCESS(tc, "Problem generating sockaddr", rv);
178
179 rv = apr_socket_create(&sock, sa->family, SOCK_STREAM, APR_PROTO_TCP, p);
180 APR_ASSERT_SUCCESS(tc, "Problem creating socket", rv);
181
182 rv = apr_socket_opt_set(sock, APR_SO_REUSEADDR, 1);
183 APR_ASSERT_SUCCESS(tc, "Could not set REUSEADDR on socket", rv);
184
185 rv = apr_socket_bind(sock, sa);
186 APR_ASSERT_SUCCESS(tc, "Problem binding to port", rv);
187 if (rv) return NULL;
188
189 rv = apr_socket_listen(sock, 5);
190 APR_ASSERT_SUCCESS(tc, "Problem listening on socket", rv);
191
192 return sock;
193 }
194
test_create_bind_listen(abts_case * tc,void * data)195 static void test_create_bind_listen(abts_case *tc, void *data)
196 {
197 apr_status_t rv;
198 apr_socket_t *sock = setup_socket(tc);
199
200 if (!sock) return;
201
202 rv = apr_socket_close(sock);
203 APR_ASSERT_SUCCESS(tc, "Problem closing socket", rv);
204 }
205
test_send(abts_case * tc,void * data)206 static void test_send(abts_case *tc, void *data)
207 {
208 apr_status_t rv;
209 apr_socket_t *sock;
210 apr_socket_t *sock2;
211 apr_proc_t proc;
212 int protocol;
213 apr_size_t length;
214
215 sock = setup_socket(tc);
216 if (!sock) return;
217
218 launch_child(tc, &proc, "read", p);
219
220 rv = apr_socket_accept(&sock2, sock, p);
221 APR_ASSERT_SUCCESS(tc, "Problem with receiving connection", rv);
222
223 apr_socket_protocol_get(sock2, &protocol);
224 ABTS_INT_EQUAL(tc, APR_PROTO_TCP, protocol);
225
226 length = strlen(DATASTR);
227 apr_socket_send(sock2, DATASTR, &length);
228
229 /* Make sure that the client received the data we sent */
230 ABTS_SIZE_EQUAL(tc, strlen(DATASTR), wait_child(tc, &proc));
231
232 rv = apr_socket_close(sock2);
233 APR_ASSERT_SUCCESS(tc, "Problem closing connected socket", rv);
234 rv = apr_socket_close(sock);
235 APR_ASSERT_SUCCESS(tc, "Problem closing socket", rv);
236 }
237
test_recv(abts_case * tc,void * data)238 static void test_recv(abts_case *tc, void *data)
239 {
240 apr_status_t rv;
241 apr_socket_t *sock;
242 apr_socket_t *sock2;
243 apr_proc_t proc;
244 int protocol;
245 apr_size_t length = STRLEN;
246 char datastr[STRLEN];
247
248 sock = setup_socket(tc);
249 if (!sock) return;
250
251 launch_child(tc, &proc, "write", p);
252
253 rv = apr_socket_accept(&sock2, sock, p);
254 APR_ASSERT_SUCCESS(tc, "Problem with receiving connection", rv);
255
256 apr_socket_protocol_get(sock2, &protocol);
257 ABTS_INT_EQUAL(tc, APR_PROTO_TCP, protocol);
258
259 memset(datastr, 0, STRLEN);
260 apr_socket_recv(sock2, datastr, &length);
261
262 /* Make sure that the server received the data we sent */
263 ABTS_STR_EQUAL(tc, DATASTR, datastr);
264 ABTS_SIZE_EQUAL(tc, strlen(datastr), wait_child(tc, &proc));
265
266 rv = apr_socket_close(sock2);
267 APR_ASSERT_SUCCESS(tc, "Problem closing connected socket", rv);
268 rv = apr_socket_close(sock);
269 APR_ASSERT_SUCCESS(tc, "Problem closing socket", rv);
270 }
271
test_atreadeof(abts_case * tc,void * data)272 static void test_atreadeof(abts_case *tc, void *data)
273 {
274 apr_status_t rv;
275 apr_socket_t *sock;
276 apr_socket_t *sock2;
277 apr_proc_t proc;
278 apr_size_t length = STRLEN;
279 char datastr[STRLEN];
280 int atreadeof = -1;
281
282 sock = setup_socket(tc);
283 if (!sock) return;
284
285 launch_child(tc, &proc, "write", p);
286
287 rv = apr_socket_accept(&sock2, sock, p);
288 APR_ASSERT_SUCCESS(tc, "Problem with receiving connection", rv);
289
290 /* Check that the remote socket is still open */
291 rv = apr_socket_atreadeof(sock2, &atreadeof);
292 APR_ASSERT_SUCCESS(tc, "Determine whether at EOF, #1", rv);
293 ABTS_INT_EQUAL(tc, 0, atreadeof);
294
295 memset(datastr, 0, STRLEN);
296 apr_socket_recv(sock2, datastr, &length);
297
298 /* Make sure that the server received the data we sent */
299 ABTS_STR_EQUAL(tc, DATASTR, datastr);
300 ABTS_SIZE_EQUAL(tc, strlen(datastr), wait_child(tc, &proc));
301
302 /* The child is dead, so should be the remote socket */
303 rv = apr_socket_atreadeof(sock2, &atreadeof);
304 APR_ASSERT_SUCCESS(tc, "Determine whether at EOF, #2", rv);
305 ABTS_INT_EQUAL(tc, 1, atreadeof);
306
307 rv = apr_socket_close(sock2);
308 APR_ASSERT_SUCCESS(tc, "Problem closing connected socket", rv);
309
310 launch_child(tc, &proc, "close", p);
311
312 rv = apr_socket_accept(&sock2, sock, p);
313 APR_ASSERT_SUCCESS(tc, "Problem with receiving connection", rv);
314
315 /* The child closed the socket as soon as it could... */
316 rv = apr_socket_atreadeof(sock2, &atreadeof);
317 APR_ASSERT_SUCCESS(tc, "Determine whether at EOF, #3", rv);
318 if (!atreadeof) { /* ... but perhaps not yet; wait a moment */
319 apr_sleep(apr_time_from_msec(5));
320 rv = apr_socket_atreadeof(sock2, &atreadeof);
321 APR_ASSERT_SUCCESS(tc, "Determine whether at EOF, #4", rv);
322 }
323 ABTS_INT_EQUAL(tc, 1, atreadeof);
324 wait_child(tc, &proc);
325
326 rv = apr_socket_close(sock2);
327 APR_ASSERT_SUCCESS(tc, "Problem closing connected socket", rv);
328
329 rv = apr_socket_close(sock);
330 APR_ASSERT_SUCCESS(tc, "Problem closing socket", rv);
331 }
332
test_timeout(abts_case * tc,void * data)333 static void test_timeout(abts_case *tc, void *data)
334 {
335 apr_status_t rv;
336 apr_socket_t *sock;
337 apr_socket_t *sock2;
338 apr_proc_t proc;
339 int protocol;
340 int exit;
341
342 sock = setup_socket(tc);
343 if (!sock) return;
344
345 launch_child(tc, &proc, "read", p);
346
347 rv = apr_socket_accept(&sock2, sock, p);
348 APR_ASSERT_SUCCESS(tc, "Problem with receiving connection", rv);
349
350 apr_socket_protocol_get(sock2, &protocol);
351 ABTS_INT_EQUAL(tc, APR_PROTO_TCP, protocol);
352
353 exit = wait_child(tc, &proc);
354 ABTS_INT_EQUAL(tc, SOCKET_TIMEOUT, exit);
355
356 /* We didn't write any data, so make sure the child program returns
357 * an error.
358 */
359 rv = apr_socket_close(sock2);
360 APR_ASSERT_SUCCESS(tc, "Problem closing connected socket", rv);
361 rv = apr_socket_close(sock);
362 APR_ASSERT_SUCCESS(tc, "Problem closing socket", rv);
363 }
364
test_print_addr(abts_case * tc,void * data)365 static void test_print_addr(abts_case *tc, void *data)
366 {
367 apr_sockaddr_t *sa;
368 apr_status_t rv;
369 char *s;
370
371 rv = apr_sockaddr_info_get(&sa, "0.0.0.0", APR_INET, 80, 0, p);
372 APR_ASSERT_SUCCESS(tc, "Problem generating sockaddr", rv);
373
374 s = apr_psprintf(p, "foo %pI bar", sa);
375
376 ABTS_STR_EQUAL(tc, "foo 0.0.0.0:80 bar", s);
377
378 #if APR_HAVE_IPV6
379 rv = apr_sockaddr_info_get(&sa, "::ffff:0.0.0.0", APR_INET6, 80, 0, p);
380 APR_ASSERT_SUCCESS(tc, "Problem generating sockaddr", rv);
381 if (rv == APR_SUCCESS)
382 ABTS_TRUE(tc, sa != NULL);
383 if (rv == APR_SUCCESS && sa) {
384 /* sa should now be a v4-mapped IPv6 address. */
385 char buf[128];
386 int rc;
387
388 rc = apr_sockaddr_is_wildcard(sa);
389 ABTS_INT_NEQUAL(tc, 0, rc);
390
391 memset(buf, 'z', sizeof buf);
392
393 APR_ASSERT_SUCCESS(tc, "could not get IP address",
394 apr_sockaddr_ip_getbuf(buf, 22, sa));
395
396 ABTS_STR_EQUAL(tc, "0.0.0.0", buf);
397 }
398 #endif
399 }
400
test_get_addr(abts_case * tc,void * data)401 static void test_get_addr(abts_case *tc, void *data)
402 {
403 apr_status_t rv;
404 apr_socket_t *ld, *sd, *cd;
405 apr_sockaddr_t *sa, *ca;
406 apr_pool_t *subp;
407 char *a, *b;
408
409 APR_ASSERT_SUCCESS(tc, "create subpool", apr_pool_create(&subp, p));
410
411 ld = setup_socket(tc);
412 if (!ld) return;
413
414 APR_ASSERT_SUCCESS(tc,
415 "get local address of bound socket",
416 apr_socket_addr_get(&sa, APR_LOCAL, ld));
417
418 rv = apr_socket_create(&cd, sa->family, SOCK_STREAM,
419 APR_PROTO_TCP, subp);
420 APR_ASSERT_SUCCESS(tc, "create client socket", rv);
421
422 APR_ASSERT_SUCCESS(tc, "enable non-block mode",
423 apr_socket_opt_set(cd, APR_SO_NONBLOCK, 1));
424
425 /* It is valid for a connect() on a socket with NONBLOCK set to
426 * succeed (if the connection can be established synchronously),
427 * but if it does, this test cannot proceed. */
428 rv = apr_socket_connect(cd, sa);
429 if (rv == APR_SUCCESS) {
430 apr_socket_close(ld);
431 apr_socket_close(cd);
432 ABTS_NOT_IMPL(tc, "Cannot test if connect completes "
433 "synchronously");
434 return;
435 }
436
437 if (!APR_STATUS_IS_EINPROGRESS(rv)) {
438 apr_socket_close(ld);
439 apr_socket_close(cd);
440 APR_ASSERT_SUCCESS(tc, "connect to listener", rv);
441 return;
442 }
443
444 APR_ASSERT_SUCCESS(tc, "accept connection",
445 apr_socket_accept(&sd, ld, subp));
446
447 {
448 /* wait for writability */
449 apr_pollfd_t pfd;
450 int n;
451
452 pfd.p = p;
453 pfd.desc_type = APR_POLL_SOCKET;
454 pfd.reqevents = APR_POLLOUT|APR_POLLHUP;
455 pfd.desc.s = cd;
456 pfd.client_data = NULL;
457
458 APR_ASSERT_SUCCESS(tc, "poll for connect completion",
459 apr_poll(&pfd, 1, &n, 5 * APR_USEC_PER_SEC));
460
461 }
462
463 APR_ASSERT_SUCCESS(tc, "get local address of server socket",
464 apr_socket_addr_get(&sa, APR_LOCAL, sd));
465 APR_ASSERT_SUCCESS(tc, "get remote address of client socket",
466 apr_socket_addr_get(&ca, APR_REMOTE, cd));
467
468 /* Test that the pool of the returned sockaddr objects exactly
469 * match the socket. */
470 ABTS_PTR_EQUAL(tc, subp, sa->pool);
471 ABTS_PTR_EQUAL(tc, subp, ca->pool);
472
473 /* Check equivalence. */
474 a = apr_psprintf(p, "%pI fam=%d", sa, sa->family);
475 b = apr_psprintf(p, "%pI fam=%d", ca, ca->family);
476 ABTS_STR_EQUAL(tc, a, b);
477
478 /* Check pool of returned sockaddr, as above. */
479 APR_ASSERT_SUCCESS(tc, "get local address of client socket",
480 apr_socket_addr_get(&sa, APR_LOCAL, cd));
481 APR_ASSERT_SUCCESS(tc, "get remote address of server socket",
482 apr_socket_addr_get(&ca, APR_REMOTE, sd));
483
484 /* Check equivalence. */
485 a = apr_psprintf(p, "%pI fam=%d", sa, sa->family);
486 b = apr_psprintf(p, "%pI fam=%d", ca, ca->family);
487 ABTS_STR_EQUAL(tc, a, b);
488
489 ABTS_PTR_EQUAL(tc, subp, sa->pool);
490 ABTS_PTR_EQUAL(tc, subp, ca->pool);
491
492 apr_socket_close(cd);
493 apr_socket_close(sd);
494 apr_socket_close(ld);
495
496 apr_pool_destroy(subp);
497 }
498
499 /* Make sure that setting a connected socket non-blocking works
500 * when the listening socket was non-blocking.
501 * If APR thinks that non-blocking is inherited but it really
502 * isn't, this testcase will fail.
503 */
test_nonblock_inheritance(abts_case * tc,void * data)504 static void test_nonblock_inheritance(abts_case *tc, void *data)
505 {
506 apr_status_t rv;
507 apr_socket_t *sock;
508 apr_socket_t *sock2;
509 apr_proc_t proc;
510 char buffer[10];
511 apr_size_t length;
512 int tries;
513
514 sock = setup_socket(tc);
515 if (!sock) return;
516
517 rv = apr_socket_opt_set(sock, APR_SO_NONBLOCK, 1);
518 APR_ASSERT_SUCCESS(tc, "Could not make listening socket nonblocking", rv);
519
520 launch_child(tc, &proc, "write_after_delay", p);
521
522 tries = 10;
523 while (tries--) {
524 rv = apr_socket_accept(&sock2, sock, p);
525 if (!APR_STATUS_IS_EAGAIN(rv)) {
526 break;
527 }
528 apr_sleep(apr_time_from_msec(50));
529 }
530 APR_ASSERT_SUCCESS(tc, "Problem with receiving connection", rv);
531
532 rv = apr_socket_opt_set(sock2, APR_SO_NONBLOCK, 1);
533 APR_ASSERT_SUCCESS(tc, "Could not make connected socket nonblocking", rv);
534
535 length = sizeof buffer;
536 rv = apr_socket_recv(sock2, buffer, &length);
537 ABTS_ASSERT(tc, "should have gotten EAGAIN", APR_STATUS_IS_EAGAIN(rv));
538
539 wait_child(tc, &proc);
540
541 rv = apr_socket_close(sock2);
542 APR_ASSERT_SUCCESS(tc, "Problem closing connected socket", rv);
543 rv = apr_socket_close(sock);
544 APR_ASSERT_SUCCESS(tc, "Problem closing socket", rv);
545 }
546
test_freebind(abts_case * tc,void * data)547 static void test_freebind(abts_case *tc, void *data)
548 {
549 #ifdef IP_FREEBIND
550 apr_status_t rv;
551 apr_socket_t *sock;
552 apr_sockaddr_t *sa;
553 apr_int32_t on;
554
555 /* RFC 5737 address */
556 rv = apr_sockaddr_info_get(&sa, "192.0.2.1", APR_INET, 8080, 0, p);
557 APR_ASSERT_SUCCESS(tc, "Problem generating sockaddr", rv);
558
559 rv = apr_socket_create(&sock, sa->family, SOCK_STREAM, APR_PROTO_TCP, p);
560 APR_ASSERT_SUCCESS(tc, "Problem creating socket", rv);
561
562 rv = apr_socket_opt_set(sock, APR_SO_REUSEADDR, 1);
563 APR_ASSERT_SUCCESS(tc, "Could not set REUSEADDR on socket", rv);
564
565 rv = apr_socket_opt_set(sock, APR_SO_FREEBIND, 1);
566 APR_ASSERT_SUCCESS(tc, "Could not enable FREEBIND option", rv);
567
568 rv = apr_socket_opt_get(sock, APR_SO_FREEBIND, &on);
569 APR_ASSERT_SUCCESS(tc, "Could not retrieve FREEBIND option", rv);
570 ABTS_INT_EQUAL(tc, 1, on);
571
572 rv = apr_socket_bind(sock, sa);
573 APR_ASSERT_SUCCESS(tc, "Problem binding to port with FREEBIND", rv);
574
575 rv = apr_socket_close(sock);
576 APR_ASSERT_SUCCESS(tc, "Problem closing socket", rv);
577 #endif
578 }
579
580 #define TEST_ZONE_ADDR "fe80::1"
581
582 #ifdef __linux__
583 /* Reasonable bet that "lo" will exist. */
584 #define TEST_ZONE_NAME "lo"
585 /* ... fill in other platforms here */
586 #endif
587
588 #ifdef TEST_ZONE_NAME
589 #define TEST_ZONE_FULLADDR TEST_ZONE_ADDR "%" TEST_ZONE_NAME
590 #endif
591
test_zone(abts_case * tc,void * data)592 static void test_zone(abts_case *tc, void *data)
593 {
594 #if APR_HAVE_IPV6
595 apr_sockaddr_t *sa;
596 apr_status_t rv;
597 const char *name = NULL;
598 apr_uint32_t id = 0;
599
600 rv = apr_sockaddr_info_get(&sa, "127.0.0.1", APR_INET, 8080, 0, p);
601 APR_ASSERT_SUCCESS(tc, "Problem generating sockaddr", rv);
602
603 /* Fail for an IPv4 address! */
604 ABTS_INT_EQUAL(tc, APR_EBADIP,
605 apr_sockaddr_zone_set(sa, "1"));
606 ABTS_INT_EQUAL(tc, APR_EBADIP,
607 apr_sockaddr_zone_get(sa, &name, &id, p));
608
609 rv = apr_sockaddr_info_get(&sa, "::1", APR_INET6, 8080, 0, p);
610 APR_ASSERT_SUCCESS(tc, "Problem generating sockaddr", rv);
611
612 /* Fail for an address which isn't link-local */
613 ABTS_INT_EQUAL(tc, APR_EBADIP, apr_sockaddr_zone_set(sa, "1"));
614
615 rv = apr_sockaddr_info_get(&sa, TEST_ZONE_ADDR, APR_INET6, 8080, 0, p);
616 APR_ASSERT_SUCCESS(tc, "Problem generating sockaddr", rv);
617
618 ABTS_INT_EQUAL(tc, APR_EBADIP, apr_sockaddr_zone_get(sa, &name, &id, p));
619
620 #ifdef TEST_ZONE_NAME
621 {
622 apr_sockaddr_t *sa2;
623 char buf[50];
624
625 APR_ASSERT_SUCCESS(tc, "Set zone to " TEST_ZONE_NAME,
626 apr_sockaddr_zone_set(sa, TEST_ZONE_NAME));
627
628 APR_ASSERT_SUCCESS(tc, "Get zone",
629 apr_sockaddr_zone_get(sa, NULL, NULL, p));
630
631 APR_ASSERT_SUCCESS(tc, "Get zone",
632 apr_sockaddr_zone_get(sa, &name, &id, p));
633 ABTS_STR_EQUAL(tc, TEST_ZONE_NAME, name);
634 ABTS_INT_NEQUAL(tc, 0, id); /* Only guarantee is that it should be non-zero */
635
636 /* Check string translation. */
637 APR_ASSERT_SUCCESS(tc, "get IP address",
638 apr_sockaddr_ip_getbuf(buf, 50, sa));
639 ABTS_STR_EQUAL(tc, TEST_ZONE_FULLADDR, buf);
640
641 memset(buf, 'A', sizeof buf);
642 ABTS_INT_EQUAL(tc, APR_ENOSPC, apr_sockaddr_ip_getbuf(buf, strlen(TEST_ZONE_ADDR), sa));
643 ABTS_INT_EQUAL(tc, APR_ENOSPC, apr_sockaddr_ip_getbuf(buf, strlen(TEST_ZONE_FULLADDR), sa));
644
645 APR_ASSERT_SUCCESS(tc, "get IP address",
646 apr_sockaddr_ip_getbuf(buf, strlen(TEST_ZONE_FULLADDR) + 1, sa));
647 /* Check for overflow. */
648 ABTS_INT_EQUAL(tc, 'A', buf[strlen(buf) + 1]);
649
650 rv = apr_sockaddr_info_copy(&sa2, sa, p);
651 APR_ASSERT_SUCCESS(tc, "Problem copying sockaddr", rv);
652
653 /* Copy copied zone matches */
654 APR_ASSERT_SUCCESS(tc, "Get zone",
655 apr_sockaddr_zone_get(sa2, &name, &id, p));
656 ABTS_STR_EQUAL(tc, TEST_ZONE_NAME, name);
657 ABTS_INT_NEQUAL(tc, 0, id); /* Only guarantee is that it should be non-zero */
658
659 /* Should match self and copy */
660 ABTS_INT_NEQUAL(tc, 0, apr_sockaddr_equal(sa, sa));
661 ABTS_INT_NEQUAL(tc, 0, apr_sockaddr_equal(sa2, sa2));
662 ABTS_INT_NEQUAL(tc, 0, apr_sockaddr_equal(sa2, sa));
663
664 /* Should not match against copy without zone set. */
665 rv = apr_sockaddr_info_get(&sa2, TEST_ZONE_ADDR, APR_INET6, 8080, 0, p);
666 APR_ASSERT_SUCCESS(tc, "Problem generating sockaddr", rv);
667
668 ABTS_INT_EQUAL(tc, 0, apr_sockaddr_equal(sa2, sa));
669 }
670 #endif /* TEST_ZONE_NAME */
671 #endif /* APR_HAVE_IPV6 */
672 }
673
testsock(abts_suite * suite)674 abts_suite *testsock(abts_suite *suite)
675 {
676 suite = ADD_SUITE(suite)
677 socket_name = IPV4_SOCKET_NAME;
678 abts_run_test(suite, test_addr_info, NULL);
679 abts_run_test(suite, test_addr_copy, NULL);
680 abts_run_test(suite, test_serv_by_name, NULL);
681 abts_run_test(suite, test_create_bind_listen, NULL);
682 abts_run_test(suite, test_send, NULL);
683 abts_run_test(suite, test_recv, NULL);
684 abts_run_test(suite, test_atreadeof, NULL);
685 abts_run_test(suite, test_timeout, NULL);
686 abts_run_test(suite, test_print_addr, NULL);
687 abts_run_test(suite, test_get_addr, NULL);
688 abts_run_test(suite, test_nonblock_inheritance, NULL);
689 abts_run_test(suite, test_freebind, NULL);
690 abts_run_test(suite, test_zone, NULL);
691
692 #if APR_HAVE_SOCKADDR_UN
693 socket_name = UNIX_SOCKET_NAME;
694 socket_type = APR_UNIX;
695 abts_run_test(suite, test_create_bind_listen, NULL);
696 abts_run_test(suite, test_send, NULL);
697 abts_run_test(suite, test_recv, NULL);
698 abts_run_test(suite, test_timeout, NULL);
699 #endif
700 return suite;
701 }
702
703