1 /*
2  * ProFTPD - FTP server testsuite
3  * Copyright (c) 2014-2021 The ProFTPD Project team
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18  *
19  * As a special exemption, The ProFTPD Project team and other respective
20  * copyright holders give permission to link this program with OpenSSL, and
21  * distribute the resulting executable, without including the source code for
22  * OpenSSL in the source distribution.
23  */
24 
25 /* Inet API tests */
26 
27 #include "tests.h"
28 
29 static pool *p = NULL;
30 
31 /* Use Google's DNS resolvers by default. */
32 static const char *dns_resolver = "8.8.8.8";
33 
set_up(void)34 static void set_up(void) {
35   const char *use_resolver = NULL;
36 
37   if (p == NULL) {
38     p = permanent_pool = make_sub_pool(NULL);
39   }
40 
41   init_netaddr();
42   init_netio();
43   init_inet();
44 
45   use_resolver = getenv("PR_USE_DNS_RESOLVER");
46   if (use_resolver != NULL) {
47     dns_resolver = use_resolver;
48   }
49 
50   if (getenv("TEST_VERBOSE") != NULL) {
51     pr_trace_set_levels("inet", 1, 20);
52   }
53 
54   pr_inet_set_default_family(p, AF_INET);
55 }
56 
tear_down(void)57 static void tear_down(void) {
58   if (getenv("TEST_VERBOSE") != NULL) {
59     pr_trace_set_levels("inet", 0, 0);
60   }
61 
62   pr_inet_set_default_family(p, 0);
63   pr_inet_clear();
64 
65   if (p) {
66     destroy_pool(p);
67     p = permanent_pool = NULL;
68   }
69 }
70 
devnull_fd(void)71 static int devnull_fd(void) {
72   int fd;
73 
74   fd = open("/dev/null", O_RDWR);
75   if (fd < 0) {
76     fprintf(stderr, "Error opening /dev/null: %s\n", strerror(errno));
77     return -1;
78   }
79 
80   return fd;
81 }
82 
83 /* Tests */
84 
START_TEST(inet_family_test)85 START_TEST (inet_family_test) {
86   int res;
87 
88   pr_inet_set_default_family(p, 0);
89 
90   res = pr_inet_set_default_family(p, AF_INET);
91   fail_unless(res == 0, "Expected previous family 0, got %d", res);
92 
93   res = pr_inet_set_default_family(p, 0);
94   fail_unless(res == AF_INET, "Expected previous family %d, got %d", AF_INET,
95     res);
96 
97   /* Restore the default family to AF_INET, for other tests. */
98   pr_inet_set_default_family(p, AF_INET);
99 }
100 END_TEST
101 
START_TEST(inet_create_conn_test)102 START_TEST (inet_create_conn_test) {
103   int sockfd = -2, port = INPORT_ANY;
104   conn_t *conn, *conn2;
105 
106   conn = pr_inet_create_conn(NULL, sockfd, NULL, port, FALSE);
107   fail_unless(conn == NULL, "Failed to handle null arguments");
108   fail_unless(errno == EINVAL,
109     "Failed to set errno to EINVAL (%d), got '%s' (%d)", EINVAL,
110     strerror(errno), errno);
111 
112   conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
113   fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));
114   fail_unless(conn->listen_fd == sockfd, "Expected listen_fd %d, got %d",
115     sockfd, conn->listen_fd);
116   pr_inet_close(p, conn);
117 
118   sockfd = -1;
119   conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
120   fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));
121   fail_unless(conn->listen_fd != sockfd,
122     "Expected listen_fd other than %d, got %d",
123     sockfd, conn->listen_fd);
124 
125   /* Create another conn, with the same port, make sure it fails. */
126   conn2 = pr_inet_create_conn(p, sockfd, NULL, conn->local_port, FALSE);
127   if (conn2 == NULL) {
128     fail_unless(errno == EADDRINUSE, "Expected EADDRINUSE (%d), got %s (%d)",
129       EADDRINUSE, strerror(errno), errno);
130     pr_inet_close(p, conn2);
131   }
132 
133   pr_inet_close(p, conn);
134 }
135 END_TEST
136 
START_TEST(inet_create_conn_portrange_test)137 START_TEST (inet_create_conn_portrange_test) {
138   conn_t *conn;
139 
140   conn = pr_inet_create_conn_portrange(NULL, NULL, -1, -1);
141   fail_unless(conn == NULL, "Failed to handle negative ports");
142   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
143     strerror(errno), errno);
144 
145   conn = pr_inet_create_conn_portrange(NULL, NULL, 10, 1);
146   fail_unless(conn == NULL, "Failed to handle bad ports");
147   fail_unless(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
148     strerror(errno), errno);
149 
150   conn = pr_inet_create_conn_portrange(p, NULL, 49152, 65534);
151   fail_unless(conn != NULL, "Failed to create conn in portrange: %s",
152     strerror(errno));
153   pr_inet_lingering_close(p, conn, 0L);
154 }
155 END_TEST
156 
START_TEST(inet_copy_conn_test)157 START_TEST (inet_copy_conn_test) {
158   int fd = -1, sockfd = -1, port = INPORT_ANY;
159   conn_t *conn, *conn2;
160   const char *name;
161 
162   conn = pr_inet_copy_conn(NULL, NULL);
163   fail_unless(conn == NULL, "Failed to handle null arguments");
164   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
165     strerror(errno), errno);
166 
167   conn = pr_inet_copy_conn(p, NULL);
168   fail_unless(conn == NULL, "Failed to handle null conn argument");
169   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
170     strerror(errno), errno);
171 
172   conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
173   fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));
174 
175   conn2 = pr_inet_copy_conn(p, conn);
176   fail_unless(conn2 != NULL, "Failed to copy conn: %s", strerror(errno));
177 
178   pr_inet_close(p, conn);
179   pr_inet_close(p, conn2);
180 
181   conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
182   fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));
183 
184   name = "127.0.0.1";
185   conn->remote_addr = pr_netaddr_get_addr(p, name, NULL);
186   fail_unless(conn->remote_addr != NULL, "Failed to resolve '%s': %s",
187     name, strerror(errno));
188   conn->remote_name = pstrdup(p, name);
189   conn->instrm = pr_netio_open(p, PR_NETIO_STRM_CTRL, fd, PR_NETIO_IO_RD);
190   fail_unless(conn->instrm != NULL, "Failed to open ctrl reading stream: %s",
191     strerror(errno));
192   conn->outstrm = pr_netio_open(p, PR_NETIO_STRM_CTRL, fd, PR_NETIO_IO_WR);
193   fail_unless(conn->instrm != NULL, "Failed to open ctrl writing stream: %s",
194     strerror(errno));
195 
196   conn2 = pr_inet_copy_conn(p, conn);
197   fail_unless(conn2 != NULL, "Failed to copy conn: %s", strerror(errno));
198 
199   mark_point();
200   pr_inet_lingering_close(NULL, NULL, 0L);
201 
202   pr_inet_lingering_close(p, conn, 0L);
203   pr_inet_close(p, conn2);
204 
205   conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
206   fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));
207 
208   conn->instrm = pr_netio_open(p, PR_NETIO_STRM_CTRL, fd, PR_NETIO_IO_RD);
209   fail_unless(conn->instrm != NULL, "Failed to open ctrl reading stream: %s",
210     strerror(errno));
211   conn->outstrm = pr_netio_open(p, PR_NETIO_STRM_CTRL, fd, PR_NETIO_IO_WR);
212   fail_unless(conn->instrm != NULL, "Failed to open ctrl writing stream: %s",
213     strerror(errno));
214 
215   mark_point();
216   pr_inet_lingering_abort(NULL, NULL, 0L);
217 
218   pr_inet_lingering_abort(p, conn, 0L);
219 }
220 END_TEST
221 
START_TEST(inet_set_async_test)222 START_TEST (inet_set_async_test) {
223   int fd, sockfd = -1, port = INPORT_ANY, res;
224   conn_t *conn;
225 
226   res = pr_inet_set_async(NULL, NULL);
227   fail_unless(res < 0, "Failed to handle null arguments");
228   fail_unless(errno == EINVAL, "Expected errno EINVAL (%d), got '%s' (%d)",
229     EINVAL, strerror(errno), errno);
230 
231   conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
232   fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));
233 
234   res = pr_inet_set_async(p, conn);
235   fail_unless(res == 0, "Failed to set conn %p async: %s", conn,
236     strerror(errno));
237 
238   fd = conn->rfd;
239   conn->rfd = 77;
240   res = pr_inet_set_async(p, conn);
241   fail_unless(res == 0, "Failed to set conn %p async: %s", conn,
242     strerror(errno));
243   conn->rfd = fd;
244 
245   fd = conn->wfd;
246   conn->wfd = 78;
247   res = pr_inet_set_async(p, conn);
248   fail_unless(res == 0, "Failed to set conn %p async: %s", conn,
249     strerror(errno));
250   conn->wfd = fd;
251 
252   fd = conn->listen_fd;
253   conn->listen_fd = 79;
254   res = pr_inet_set_async(p, conn);
255   fail_unless(res == 0, "Failed to set conn %p async: %s", conn,
256     strerror(errno));
257   conn->listen_fd = fd;
258 
259   pr_inet_close(p, conn);
260 }
261 END_TEST
262 
START_TEST(inet_set_block_test)263 START_TEST (inet_set_block_test) {
264   int sockfd = -1, port = INPORT_ANY, res;
265   conn_t *conn;
266 
267   res = pr_inet_set_block(NULL, NULL);
268   fail_unless(res < 0, "Failed to handle null arguments");
269   fail_unless(errno == EINVAL, "Expected errno EINVAL (%d), got '%s' (%d)",
270     EINVAL, strerror(errno), errno);
271 
272   res = pr_inet_set_nonblock(NULL, NULL);
273   fail_unless(res < 0, "Failed to handle null arguments");
274   fail_unless(errno == EINVAL, "Expected errno EINVAL (%d), got '%s' (%d)",
275     EINVAL, strerror(errno), errno);
276 
277   conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
278   fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));
279 
280   res = pr_inet_set_nonblock(p, conn);
281   fail_unless(res < 0, "Failed to handle bad socket");
282   fail_unless(errno == EBADF, "Expected EBADF (%d), got %s (%d)", EBADF,
283     strerror(errno), errno);
284 
285   res = pr_inet_set_block(p, conn);
286   fail_unless(res < 0, "Failed to handle bad socket");
287   fail_unless(errno == EBADF, "Expected EBADF (%d), got %s (%d)", EBADF,
288     strerror(errno), errno);
289 
290   pr_inet_close(p, conn);
291 }
292 END_TEST
293 
START_TEST(inet_set_proto_cork_test)294 START_TEST (inet_set_proto_cork_test) {
295   int res, sockfd = -1;
296 
297   res = pr_inet_set_proto_cork(sockfd, TRUE);
298   fail_unless(res < 0, "Failed to handle bad socket descriptor");
299   fail_unless(errno == EBADF,
300     "Failed to set errno to EBADF (%d), got '%s' (%d)", EBADF, strerror(errno),
301     errno);
302 }
303 END_TEST
304 
START_TEST(inet_set_proto_nodelay_test)305 START_TEST (inet_set_proto_nodelay_test) {
306   int fd, sockfd = -1, port = INPORT_ANY, res;
307   conn_t *conn;
308 
309   res = pr_inet_set_proto_nodelay(NULL, NULL, 1);
310   fail_unless(res < 0, "Failed to handle null arguments");
311   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
312     strerror(errno), errno);
313 
314   conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
315   fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));
316 
317   res = pr_inet_set_proto_nodelay(p, conn, 1);
318   fail_unless(res == 0, "Failed to enable nodelay: %s", strerror(errno));
319 
320   res = pr_inet_set_proto_nodelay(p, conn, 0);
321   fail_unless(res == 0, "Failed to disable nodelay: %s", strerror(errno));
322 
323   fd = conn->rfd;
324   conn->rfd = 8;
325   res = pr_inet_set_proto_nodelay(p, conn, 0);
326   fail_unless(res == 0, "Failed to disable nodelay: %s", strerror(errno));
327   conn->rfd = fd;
328 
329   fd = conn->rfd;
330   conn->rfd = -2;
331   res = pr_inet_set_proto_nodelay(p, conn, 0);
332   fail_unless(res == 0, "Failed to disable nodelay: %s", strerror(errno));
333   conn->rfd = fd;
334 
335   fd = conn->wfd;
336   conn->rfd = 9;
337   res = pr_inet_set_proto_nodelay(p, conn, 0);
338   fail_unless(res == 0, "Failed to disable nodelay: %s", strerror(errno));
339   conn->wfd = fd;
340 
341   fd = conn->wfd;
342   conn->rfd = -3;
343   res = pr_inet_set_proto_nodelay(p, conn, 0);
344   fail_unless(res == 0, "Failed to disable nodelay: %s", strerror(errno));
345   conn->wfd = fd;
346 
347   pr_inet_close(p, conn);
348 }
349 END_TEST
350 
START_TEST(inet_set_proto_opts_test)351 START_TEST (inet_set_proto_opts_test) {
352   int fd, sockfd = -1, port = INPORT_ANY, res;
353   conn_t *conn;
354 
355   mark_point();
356   res = pr_inet_set_proto_opts(NULL, NULL, 1, 1, 1, 1);
357   fail_unless(res < 0, "Failed to handle null arguments");
358   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
359     strerror(errno), errno);
360 
361   conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
362   fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));
363 
364   mark_point();
365   res = pr_inet_set_proto_opts(p, conn, 1, 1, 1, 1);
366   fail_unless(res == 0, "Failed to set proto opts: %s", strerror(errno));
367 
368   mark_point();
369   fd = conn->rfd;
370   conn->rfd = 8;
371   res = pr_inet_set_proto_opts(p, conn, 1, 1, 1, 1);
372   fail_unless(res == 0, "Failed to set proto opts: %s", strerror(errno));
373   conn->rfd = fd;
374 
375   mark_point();
376   fd = conn->wfd;
377   conn->wfd = 9;
378   res = pr_inet_set_proto_opts(p, conn, 1, 1, 1, 1);
379   fail_unless(res == 0, "Failed to set proto opts: %s", strerror(errno));
380   conn->wfd = fd;
381 
382   mark_point();
383   fd = conn->listen_fd;
384   conn->listen_fd = 10;
385   res = pr_inet_set_proto_opts(p, conn, 1, 1, 1, 1);
386   fail_unless(res == 0, "Failed to set proto opts: %s", strerror(errno));
387   conn->listen_fd = fd;
388 
389   pr_inet_close(p, conn);
390 }
391 END_TEST
392 
START_TEST(inet_set_proto_opts_ipv6_test)393 START_TEST (inet_set_proto_opts_ipv6_test) {
394 #ifdef PR_USE_IPV6
395   int fd, sockfd = -1, port = INPORT_ANY, res;
396   conn_t *conn;
397   unsigned char use_ipv6;
398 
399   use_ipv6 = pr_netaddr_use_ipv6();
400 
401   pr_netaddr_enable_ipv6();
402   pr_inet_set_default_family(p, AF_INET6);
403 
404   conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
405   fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));
406 
407   mark_point();
408   res = pr_inet_set_proto_opts(p, conn, 1, 1, 1, 1);
409   fail_unless(res == 0, "Failed to set proto opts: %s", strerror(errno));
410 
411   mark_point();
412   fd = conn->rfd;
413   conn->rfd = 8;
414   res = pr_inet_set_proto_opts(p, conn, 1, 1, 1, 1);
415   fail_unless(res == 0, "Failed to set proto opts: %s", strerror(errno));
416   conn->rfd = fd;
417 
418   mark_point();
419   fd = conn->wfd;
420   conn->wfd = 9;
421   res = pr_inet_set_proto_opts(p, conn, 1, 1, 1, 1);
422   fail_unless(res == 0, "Failed to set proto opts: %s", strerror(errno));
423   conn->wfd = fd;
424 
425   mark_point();
426   fd = conn->listen_fd;
427   conn->listen_fd = 10;
428   res = pr_inet_set_proto_opts(p, conn, 1, 1, 1, 1);
429   fail_unless(res == 0, "Failed to set proto opts: %s", strerror(errno));
430   conn->listen_fd = fd;
431 
432   pr_inet_close(p, conn);
433 
434   pr_inet_set_default_family(p, AF_INET);
435   if (use_ipv6 == FALSE) {
436     pr_netaddr_disable_ipv6();
437   }
438 #endif /* PR_USE_IPV6 */
439 }
440 END_TEST
441 
START_TEST(inet_set_socket_opts_test)442 START_TEST (inet_set_socket_opts_test) {
443   int sockfd = -1, port = INPORT_ANY, res;
444   conn_t *conn;
445   struct tcp_keepalive keepalive;
446 
447   res = pr_inet_set_socket_opts(NULL, NULL, 1, 2, NULL);
448   fail_unless(res < 0, "Failed to handle null arguments");
449   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
450     strerror(errno), errno);
451 
452   conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
453   fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));
454 
455   res = pr_inet_set_socket_opts(p, conn, 1, 2, NULL);
456   fail_unless(res == 0, "Failed to set socket opts: %s", strerror(errno));
457 
458   res = pr_inet_set_socket_opts(p, conn, INT_MAX, INT_MAX, NULL);
459   fail_unless(res == 0, "Failed to set socket opts: %s", strerror(errno));
460 
461   keepalive.keepalive_enabled = 1;
462   keepalive.keepalive_idle = 1;
463   keepalive.keepalive_count = 2;
464   keepalive.keepalive_intvl = 3;
465   res = pr_inet_set_socket_opts(p, conn, 1, 2, &keepalive);
466   fail_unless(res == 0, "Failed to set socket opts: %s", strerror(errno));
467 
468   pr_inet_close(p, conn);
469 }
470 END_TEST
471 
START_TEST(inet_set_socket_opts2_test)472 START_TEST (inet_set_socket_opts2_test) {
473   int fd, sockfd, port = INPORT_ANY, res;
474   conn_t *conn;
475   struct tcp_keepalive keepalive;
476 
477   mark_point();
478   res = pr_inet_set_socket_opts2(NULL, NULL, 1, 2, NULL, -1);
479   fail_unless(res < 0, "Failed to handle null arguments");
480   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
481     strerror(errno), errno);
482 
483   conn = pr_inet_create_conn(p, -1, NULL, port, FALSE);
484   fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));
485 
486   mark_point();
487   res = pr_inet_set_socket_opts2(p, conn, 1, 2, NULL, -1);
488   fail_unless(res == 0, "Failed to set socket opts: %s", strerror(errno));
489 
490   mark_point();
491   res = pr_inet_set_socket_opts2(p, conn, INT_MAX, INT_MAX, NULL, 0);
492   fail_unless(res == 0, "Failed to set socket opts: %s", strerror(errno));
493 
494   keepalive.keepalive_enabled = 1;
495   keepalive.keepalive_idle = 1;
496   keepalive.keepalive_count = 2;
497   keepalive.keepalive_intvl = 3;
498   res = pr_inet_set_socket_opts2(p, conn, 1, 2, &keepalive, 1);
499   fail_unless(res == 0, "Failed to set socket opts: %s", strerror(errno));
500 
501   mark_point();
502   sockfd = devnull_fd();
503   if (sockfd < 0) {
504     return;
505   }
506 
507   fd = conn->listen_fd;
508   conn->listen_fd = sockfd;
509   res = pr_inet_set_socket_opts2(p, conn, 1, 2, &keepalive, 1);
510   fail_unless(res == 0, "Failed to set socket opts: %s", strerror(errno));
511   conn->listen_fd = fd;
512 
513   (void) close(sockfd);
514   pr_inet_close(p, conn);
515 }
516 END_TEST
517 
START_TEST(inet_listen_test)518 START_TEST (inet_listen_test) {
519   int fd, mode, sockfd = -1, port = INPORT_ANY, res;
520   conn_t *conn;
521 
522   res = pr_inet_listen(NULL, NULL, 5, 0);
523   fail_unless(res < 0, "Failed to handle null arguments");
524   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
525     strerror(errno), errno);
526 
527   res = pr_inet_resetlisten(NULL, NULL);
528   fail_unless(res < 0, "Failed to handle null arguments");
529   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
530     strerror(errno), errno);
531 
532   conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
533   fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));
534 
535   fd = conn->listen_fd;
536   conn->listen_fd = 777;
537   res = pr_inet_listen(p, conn, 5, 0);
538   fail_unless(res < 0, "Succeeded in listening on conn unexpectedly");
539   fail_unless(errno == EBADF, "Expected EBADF (%d), got %s (%d)", EBADF,
540     strerror(errno), errno);
541 
542   mode = conn->mode;
543   res = pr_inet_resetlisten(p, conn);
544   fail_unless(res < 0, "Succeeded in resetting listening on conn unexpectedly");
545   fail_unless(errno == EBADF, "Expected EBADF (%d), got %s (%d)", EBADF,
546     strerror(errno), errno);
547 
548   conn->listen_fd = fd;
549   conn->mode = mode;
550 
551   res = pr_inet_listen(p, conn, 5, 0);
552   fail_unless(res == 0, "Failed to listen on conn: %s", strerror(errno));
553 
554   res = pr_inet_resetlisten(p, conn);
555   fail_unless(res == 0, "Failed to reset listen mode: %s", strerror(errno));
556 
557   res = pr_inet_listen(p, conn, 5, 0);
558   fail_unless(res < 0, "Failed to handle already-listening socket");
559   fail_unless(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
560     strerror(errno), errno);
561 
562   pr_inet_close(p, conn);
563 }
564 END_TEST
565 
START_TEST(inet_connect_ipv4_test)566 START_TEST (inet_connect_ipv4_test) {
567   int sockfd = -1, port = INPORT_ANY, res;
568   conn_t *conn;
569   const pr_netaddr_t *addr;
570 
571   res = pr_inet_connect(NULL, NULL, NULL, port);
572   fail_unless(res < 0, "Failed to handle null arguments");
573   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
574     strerror(errno), errno);
575 
576   conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
577   fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));
578 
579   res = pr_inet_connect(p, conn, NULL, 180);
580   fail_unless(res < 0, "Failed to handle null address");
581   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
582     strerror(errno), errno);
583 
584   mark_point();
585   addr = pr_netaddr_get_addr(p, "127.0.0.1", NULL);
586   fail_unless(addr != NULL, "Failed to resolve '127.0.0.1': %s",
587     strerror(errno));
588 
589   /* On CirrusCI VMs, attempting to connect causes test timeouts. */
590   if (getenv("CIRRUS_CLONE_DEPTH") != NULL) {
591     return;
592   }
593 
594   mark_point();
595   res = pr_inet_connect(p, conn, addr, 180);
596   fail_unless(res < 0, "Connected to 127.0.0.1#180 unexpectedly");
597   fail_unless(errno == ECONNREFUSED, "Expected ECONNREFUSED (%d), got %s (%d)",
598     ECONNREFUSED, strerror(errno), errno);
599 
600 #if defined(PR_USE_NETWORK_TESTS)
601   addr = pr_netaddr_get_addr(p, dns_resolver, NULL);
602   fail_unless(addr != NULL, "Failed to resolve '%s': %s", dns_resolver,
603     strerror(errno));
604 
605   res = pr_inet_connect(p, conn, addr, 53);
606   if (res < 0) {
607     /* Note: We get EINVAL here because the socket already tried (and failed)
608      * to connect to a different address.  Interestingly, trying to connect(2)
609      * using that same fd to a different address yields EINVAL.
610      */
611     fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
612       strerror(errno), errno);
613   }
614   pr_inet_close(p, conn);
615 
616   conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
617   fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));
618 
619   res = pr_inet_connect(p, conn, addr, 53);
620   fail_if(res < 0, "Failed to connect to %s#53: %s", dns_resolver,
621     strerror(errno));
622 
623   res = pr_inet_connect(p, conn, addr, 53);
624   fail_unless(res < 0, "Failed to connect to %s#53: %s", dns_resolver,
625     strerror(errno));
626   fail_unless(errno == EISCONN, "Expected EISCONN (%d), got %s (%d)",
627     EISCONN, strerror(errno), errno);
628   pr_inet_close(p, conn);
629 #endif
630 }
631 END_TEST
632 
START_TEST(inet_connect_ipv6_test)633 START_TEST (inet_connect_ipv6_test) {
634 #ifdef PR_USE_IPV6
635   int sockfd = -1, port = INPORT_ANY, res;
636   conn_t *conn;
637   const pr_netaddr_t *addr;
638   unsigned char use_ipv6;
639 
640   use_ipv6 = pr_netaddr_use_ipv6();
641 
642   pr_netaddr_enable_ipv6();
643   pr_inet_set_default_family(p, AF_INET6);
644 
645   conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
646   fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));
647 
648   mark_point();
649   addr = pr_netaddr_get_addr(p, "::1", NULL);
650   fail_unless(addr != NULL, "Failed to resolve '::1': %s",
651     strerror(errno));
652 
653   /* On CirrusCI VMs, attempting to connect causes test timeouts. */
654   if (getenv("CIRRUS_CLONE_DEPTH") != NULL) {
655     return;
656   }
657 
658   mark_point();
659   res = pr_inet_connect(p, conn, addr, 180);
660   fail_unless(res < 0, "Connected to ::1#180 unexpectedly");
661   fail_unless(errno == ECONNREFUSED || errno == ENETUNREACH || errno == EADDRNOTAVAIL,
662     "Expected ECONNREFUSED (%d), ENETUNREACH (%d), or EADDRNOTAVAIL (%d), got %s (%d)",
663     ECONNREFUSED, ENETUNREACH, EADDRNOTAVAIL, strerror(errno), errno);
664 
665 #if defined(PR_USE_NETWORK_TESTS)
666   /* Try connecting to Google's DNS server. */
667 
668   addr = pr_netaddr_get_addr(p, "2001:4860:4860::8888", NULL);
669   fail_unless(addr != NULL, "Failed to resolve '2001:4860:4860::8888': %s",
670     strerror(errno));
671 
672   res = pr_inet_connect(p, conn, addr, 53);
673   if (res < 0) {
674     /* Note: We get EINVAL here because the socket already tried (and failed)
675      * to connect to a different address.  Interestingly, trying to connect(2)
676      * using that same fd to a different address yields EINVAL.
677      */
678     fail_unless(errno == EINVAL || errno == ENETUNREACH || errno == EADDRNOTAVAIL,
679       "Expected EINVAL (%d), ENETUNREACH (%d) or EADDRNOTAVAIL (%d), got %s (%d)",
680       EINVAL, ENETUNREACH, EADDRNOTAVAIL, strerror(errno), errno);
681   }
682   pr_inet_close(p, conn);
683 
684   conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
685   fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));
686 
687   res = pr_inet_connect(p, conn, addr, 53);
688   if (res < 0) {
689     /* This could be expected, e.g. if there's no route. */
690     fail_unless(errno == EHOSTUNREACH || errno == ENETUNREACH || errno == EADDRNOTAVAIL,
691       "Expected EHOSTUNREACH (%d) or ENETUNREACH (%d) or EADDRNOTAVAIL (%d), got %s (%d)",
692       EHOSTUNREACH, ENETUNREACH, EADDRNOTAVAIL, strerror(errno), errno);
693   }
694 
695   res = pr_inet_connect(p, conn, addr, 53);
696   fail_unless(res < 0, "Failed to connect to 2001:4860:4860::8888#53: %s",
697     strerror(errno));
698   fail_unless(errno == EISCONN || errno == EHOSTUNREACH || errno == ENETUNREACH || errno == EADDRNOTAVAIL,
699     "Expected EISCONN (%d) or EHOSTUNREACH (%d) or ENETUNREACH (%d) or EADDRNOTAVAIL (%d), got %s (%d)", EISCONN, EHOSTUNREACH, ENETUNREACH, EADDRNOTAVAIL, strerror(errno), errno);
700   pr_inet_close(p, conn);
701 #endif
702 
703   pr_inet_set_default_family(p, AF_INET);
704 
705   if (use_ipv6 == FALSE) {
706     pr_netaddr_disable_ipv6();
707   }
708 #endif /* PR_USE_IPV6 */
709 }
710 END_TEST
711 
START_TEST(inet_connect_nowait_test)712 START_TEST (inet_connect_nowait_test) {
713   int sockfd = -1, port = INPORT_ANY, res;
714   conn_t *conn;
715   const pr_netaddr_t *addr;
716 
717   res = pr_inet_connect_nowait(NULL, NULL, NULL, port);
718   fail_unless(res < 0, "Failed to handle null arguments");
719   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
720     strerror(errno), errno);
721 
722   conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
723   fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));
724 
725   res = pr_inet_connect_nowait(p, conn, NULL, 180);
726   fail_unless(res < 0, "Failed to handle null address");
727   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
728     strerror(errno), errno);
729 
730   addr = pr_netaddr_get_addr(p, "127.0.0.1", NULL);
731   fail_unless(addr != NULL, "Failed to resolve '127.0.0.1': %s",
732     strerror(errno));
733 
734   res = pr_inet_connect_nowait(p, conn, addr, 180);
735   fail_unless(res != -1, "Connected to 127.0.0.1#180 unexpectedly");
736 
737 #if defined(PR_USE_NETWORK_TESTS)
738   /* Try connecting to Google's DNS server. */
739 
740   addr = pr_netaddr_get_addr(p, dns_resolver, NULL);
741   fail_unless(addr != NULL, "Failed to resolve '%s': %s", dns_resolver,
742     strerror(errno));
743 
744   res = pr_inet_connect_nowait(p, conn, addr, 53);
745   if (res < 0 &&
746       errno != ECONNREFUSED &&
747       errno != EBADF) {
748     fail_unless(res != -1, "Failed to connect to %s#53: %s", dns_resolver,
749       strerror(errno));
750   }
751 
752   pr_inet_close(p, conn);
753 #endif
754 
755   /* Restore the default family to AF_INET, for other tests. */
756   pr_inet_set_default_family(p, AF_INET);
757 }
758 END_TEST
759 
START_TEST(inet_accept_test)760 START_TEST (inet_accept_test) {
761   conn_t *conn;
762 
763   conn = pr_inet_accept(NULL, NULL, NULL, 0, 2, FALSE);
764   fail_unless(conn == NULL, "Failed to handle null arguments");
765   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
766     strerror(errno), errno);
767 }
768 END_TEST
769 
START_TEST(inet_accept_nowait_test)770 START_TEST (inet_accept_nowait_test) {
771   int sockfd = -1, port = INPORT_ANY, res;
772   conn_t *conn;
773 
774   res = pr_inet_accept_nowait(NULL, NULL);
775   fail_unless(res < 0, "Failed to handle null arguments");
776   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
777     strerror(errno), errno);
778 
779   conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
780   fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));
781 
782   res = pr_inet_accept_nowait(p, conn);
783   fail_unless(res < 0, "Accepted connection unexpectedly");
784   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
785     strerror(errno), errno);
786 
787   pr_inet_close(p, conn);
788 }
789 END_TEST
790 
START_TEST(inet_conn_info_test)791 START_TEST (inet_conn_info_test) {
792   int sockfd = -1, port = INPORT_ANY, res;
793   conn_t *conn;
794 
795   res = pr_inet_get_conn_info(NULL, -1);
796   fail_unless(res < 0, "Failed to handle null arguments");
797   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
798     strerror(errno), errno);
799 
800   conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
801   fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));
802 
803   res = pr_inet_get_conn_info(conn, -1);
804   fail_unless(res < 0, "Failed to handle bad file descriptor");
805   fail_unless(errno == EBADF, "Expected EBADF (%d), got %s (%d)", EBADF,
806     strerror(errno), errno);
807 
808   res = pr_inet_get_conn_info(conn, 1);
809   fail_unless(res < 0, "Failed to handle bad file descriptor");
810   fail_unless(errno == ENOTSOCK, "Expected ENOTSOCK (%d), got %s (%d)",
811     ENOTSOCK, strerror(errno), errno);
812 
813   pr_inet_close(p, conn);
814 }
815 END_TEST
816 
START_TEST(inet_openrw_test)817 START_TEST (inet_openrw_test) {
818   int sockfd = -1, port = INPORT_ANY;
819   conn_t *conn, *res;
820   const pr_netaddr_t *addr;
821 
822   res = pr_inet_openrw(NULL, NULL, NULL, PR_NETIO_STRM_CTRL, -1, -1, -1, FALSE);
823   fail_unless(res == NULL, "Failed to handle null arguments");
824   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
825     strerror(errno), errno);
826 
827   conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
828   fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));
829 
830   res = pr_inet_openrw(p, conn, NULL, PR_NETIO_STRM_CTRL, -1, -1, -1, FALSE);
831   fail_unless(res == NULL, "Opened rw conn unexpectedly");
832   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
833     strerror(errno), errno);
834 
835   addr = pr_netaddr_get_addr(p, "127.0.0.1", NULL);
836   fail_unless(addr != NULL, "Failed to resolve 127.0.0.1: %s", strerror(errno));
837 
838   res = pr_inet_openrw(p, conn, addr, PR_NETIO_STRM_CTRL, -1, -1, -1, FALSE);
839   fail_unless(res != NULL, "Failed to open rw conn: %s", strerror(errno));
840   (void) pr_inet_close(p, res);
841 
842   res = pr_inet_openrw(p, conn, addr, PR_NETIO_STRM_CTRL, -1, -1, -1, TRUE);
843   fail_unless(res != NULL, "Failed to open rw conn: %s", strerror(errno));
844 }
845 END_TEST
846 
START_TEST(inet_generate_socket_event_test)847 START_TEST (inet_generate_socket_event_test) {
848   int res;
849   const char *name;
850   server_rec *s;
851 
852   res = pr_inet_generate_socket_event(NULL, NULL, NULL, -1);
853   fail_unless(res < 0, "Failed to handle null arguments");
854   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
855     strerror(errno), errno);
856 
857   name = "foo.bar";
858   res = pr_inet_generate_socket_event(name, NULL, NULL, -1);
859   fail_unless(res < 0, "Failed to handle null server_rec");
860   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
861     strerror(errno), errno);
862 
863   s = pcalloc(p, sizeof(server_rec));
864   res = pr_inet_generate_socket_event(name, s, NULL, -1);
865   fail_unless(res < 0, "Failed to handle null address");
866   fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
867     strerror(errno), errno);
868 }
869 END_TEST
870 
tests_get_inet_suite(void)871 Suite *tests_get_inet_suite(void) {
872   Suite *suite;
873   TCase *testcase;
874 
875   suite = suite_create("inet");
876 
877   testcase = tcase_create("base");
878   tcase_add_checked_fixture(testcase, set_up, tear_down);
879 
880   tcase_add_test(testcase, inet_family_test);
881   tcase_add_test(testcase, inet_create_conn_test);
882   tcase_add_test(testcase, inet_create_conn_portrange_test);
883   tcase_add_test(testcase, inet_copy_conn_test);
884   tcase_add_test(testcase, inet_set_async_test);
885   tcase_add_test(testcase, inet_set_block_test);
886   tcase_add_test(testcase, inet_set_proto_cork_test);
887   tcase_add_test(testcase, inet_set_proto_nodelay_test);
888   tcase_add_test(testcase, inet_set_proto_opts_test);
889   tcase_add_test(testcase, inet_set_proto_opts_ipv6_test);
890   tcase_add_test(testcase, inet_set_socket_opts_test);
891   tcase_add_test(testcase, inet_set_socket_opts2_test);
892   tcase_add_test(testcase, inet_listen_test);
893   tcase_add_test(testcase, inet_connect_ipv4_test);
894   tcase_add_test(testcase, inet_connect_ipv6_test);
895   tcase_add_test(testcase, inet_connect_nowait_test);
896   tcase_add_test(testcase, inet_accept_test);
897   tcase_add_test(testcase, inet_accept_nowait_test);
898   tcase_add_test(testcase, inet_conn_info_test);
899   tcase_add_test(testcase, inet_openrw_test);
900   tcase_add_test(testcase, inet_generate_socket_event_test);
901 
902   suite_add_tcase(suite, testcase);
903   return suite;
904 }
905