]> jfr.im git - solanum.git/blob - librb/src/commio.c
check bans and quiets for cmode -n/nonmember PRIVMSG
[solanum.git] / librb / src / commio.c
1 /*
2 * ircd-ratbox: A slightly useful ircd.
3 * commio.c: Network/file related functions
4 *
5 * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
6 * Copyright (C) 1996-2002 Hybrid Development Team
7 * Copyright (C) 2002-2005 ircd-ratbox development team
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
22 * USA
23 *
24 */
25
26 #include <librb_config.h>
27 #include <rb_lib.h>
28 #include <commio-int.h>
29 #include <commio-ssl.h>
30 #include <event-int.h>
31 #include <sys/uio.h>
32 #define HAVE_SSL 1
33
34 #ifndef MSG_NOSIGNAL
35 #define MSG_NOSIGNAL 0
36 #endif
37
38
39 struct timeout_data
40 {
41 rb_fde_t *F;
42 rb_dlink_node node;
43 time_t timeout;
44 PF *timeout_handler;
45 void *timeout_data;
46 };
47
48 rb_dlink_list *rb_fd_table;
49 static rb_bh *fd_heap;
50
51 static rb_dlink_list timeout_list;
52 static rb_dlink_list closed_list;
53
54 struct defer
55 {
56 rb_dlink_node node;
57 void (*fn)(void *);
58 void *data;
59 };
60 static rb_dlink_list defer_list;
61
62 static struct ev_entry *rb_timeout_ev;
63
64
65 static const char *rb_err_str[] = { "Comm OK", "Error during bind()",
66 "Error during DNS lookup", "connect timeout",
67 "Error during connect()",
68 "Comm Error",
69 "Error with SSL"
70 };
71
72 /* Highest FD and number of open FDs .. */
73 static int number_fd = 0;
74 int rb_maxconnections = 0;
75
76 static PF rb_connect_timeout;
77 static PF rb_connect_outcome;
78 static void mangle_mapped_sockaddr(struct sockaddr *in);
79
80 static inline rb_fde_t *
81 add_fd(int fd)
82 {
83 rb_fde_t *F = rb_find_fd(fd);
84
85 /* look up to see if we have it already */
86 if(F != NULL)
87 return F;
88
89 F = rb_bh_alloc(fd_heap);
90 F->fd = fd;
91 rb_dlinkAdd(F, &F->node, &rb_fd_table[rb_hash_fd(fd)]);
92 return (F);
93 }
94
95 static inline void
96 remove_fd(rb_fde_t *F)
97 {
98 if(F == NULL || !IsFDOpen(F))
99 return;
100
101 rb_dlinkMoveNode(&F->node, &rb_fd_table[rb_hash_fd(F->fd)], &closed_list);
102 }
103
104 void
105 rb_close_pending_fds(void)
106 {
107 rb_fde_t *F;
108 rb_dlink_node *ptr, *next;
109 RB_DLINK_FOREACH_SAFE(ptr, next, closed_list.head)
110 {
111 F = ptr->data;
112
113 number_fd--;
114 close(F->fd);
115 rb_dlinkDelete(ptr, &closed_list);
116 rb_bh_free(fd_heap, F);
117 }
118 }
119
120 /* close_all_connections() can be used *before* the system come up! */
121
122 static void
123 rb_close_all(void)
124 {
125 int i;
126
127 /* XXX someone tell me why we care about 4 fd's ? */
128 /* XXX btw, fd 3 is used for profiler ! */
129 for(i = 3; i < rb_maxconnections; ++i)
130 {
131 close(i);
132 }
133 }
134
135 /*
136 * get_sockerr - get the error value from the socket or the current errno
137 *
138 * Get the *real* error from the socket (well try to anyway..).
139 * This may only work when SO_DEBUG is enabled but its worth the
140 * gamble anyway.
141 */
142 int
143 rb_get_sockerr(rb_fde_t *F)
144 {
145 int errtmp;
146 int err = 0;
147 rb_socklen_t len = sizeof(err);
148
149 if(!(F->type & RB_FD_SOCKET))
150 return errno;
151 errtmp = errno;
152
153 #ifdef SO_ERROR
154 if(F != NULL
155 && !getsockopt(rb_get_fd(F), SOL_SOCKET, SO_ERROR, (char *)&err, (rb_socklen_t *) & len))
156 {
157 if(err)
158 errtmp = err;
159 }
160 errno = errtmp;
161 #endif
162 return errtmp;
163 }
164
165 /*
166 * rb_getmaxconnect - return the max number of connections allowed
167 */
168 int
169 rb_getmaxconnect(void)
170 {
171 return (rb_maxconnections);
172 }
173
174 /*
175 * set_sock_buffers - set send and receive buffers for socket
176 *
177 * inputs - fd file descriptor
178 * - size to set
179 * output - returns true (1) if successful, false (0) otherwise
180 * side effects -
181 */
182 int
183 rb_set_buffers(rb_fde_t *F, int size)
184 {
185 if(F == NULL)
186 return 0;
187 if(setsockopt
188 (F->fd, SOL_SOCKET, SO_RCVBUF, (char *)&size, sizeof(size))
189 || setsockopt(F->fd, SOL_SOCKET, SO_SNDBUF, (char *)&size, sizeof(size)))
190 return 0;
191 return 1;
192 }
193
194 /*
195 * set_non_blocking - Set the client connection into non-blocking mode.
196 *
197 * inputs - fd to set into non blocking mode
198 * output - 1 if successful 0 if not
199 * side effects - use POSIX compliant non blocking and
200 * be done with it.
201 */
202 int
203 rb_set_nb(rb_fde_t *F)
204 {
205 int nonb = 0;
206 int res;
207 int fd;
208 if(F == NULL)
209 return 0;
210 fd = F->fd;
211
212 if((res = rb_setup_fd(F)))
213 return res;
214 #ifdef O_NONBLOCK
215 nonb |= O_NONBLOCK;
216 res = fcntl(fd, F_GETFL, 0);
217 if(-1 == res || fcntl(fd, F_SETFL, res | nonb) == -1)
218 return 0;
219 #else
220 nonb = 1;
221 res = 0;
222 if(ioctl(fd, FIONBIO, (char *)&nonb) == -1)
223 return 0;
224 #endif
225
226 return 1;
227 }
228
229 int
230 rb_set_cloexec(rb_fde_t *F)
231 {
232 int res;
233 int fd;
234 if(F == NULL)
235 return 0;
236 fd = F->fd;
237
238 res = fcntl(fd, F_GETFD, NULL);
239 if(res == -1)
240 return 0;
241 if(fcntl(fd, F_SETFD, res | FD_CLOEXEC) == -1)
242 return 0;
243
244 return 1;
245 }
246
247 int
248 rb_clear_cloexec(rb_fde_t *F)
249 {
250 int res;
251 int fd;
252 if(F == NULL)
253 return 0;
254 fd = F->fd;
255
256 res = fcntl(fd, F_GETFD, NULL);
257 if(res == -1)
258 return 0;
259 if(fcntl(fd, F_SETFD, res & ~FD_CLOEXEC) == -1)
260 return 0;
261
262 return 1;
263 }
264
265 /*
266 * rb_settimeout() - set the socket timeout
267 *
268 * Set the timeout for the fd
269 */
270 void
271 rb_settimeout(rb_fde_t *F, time_t timeout, PF * callback, void *cbdata)
272 {
273 struct timeout_data *td;
274
275 if(F == NULL)
276 return;
277
278 lrb_assert(IsFDOpen(F));
279 td = F->timeout;
280 if(callback == NULL) /* user wants to remove */
281 {
282 if(td == NULL)
283 return;
284 rb_dlinkDelete(&td->node, &timeout_list);
285 rb_free(td);
286 F->timeout = NULL;
287 if(rb_dlink_list_length(&timeout_list) == 0)
288 {
289 rb_event_delete(rb_timeout_ev);
290 rb_timeout_ev = NULL;
291 }
292 return;
293 }
294
295 if(F->timeout == NULL)
296 td = F->timeout = rb_malloc(sizeof(struct timeout_data));
297
298 td->F = F;
299 td->timeout = rb_current_time() + timeout;
300 td->timeout_handler = callback;
301 td->timeout_data = cbdata;
302 rb_dlinkAdd(td, &td->node, &timeout_list);
303 if(rb_timeout_ev == NULL)
304 {
305 rb_timeout_ev = rb_event_add("rb_checktimeouts", rb_checktimeouts, NULL, 5);
306 }
307 }
308
309 /*
310 * rb_checktimeouts() - check the socket timeouts
311 *
312 * All this routine does is call the given callback/cbdata, without closing
313 * down the file descriptor. When close handlers have been implemented,
314 * this will happen.
315 */
316 void
317 rb_checktimeouts(void *notused __attribute__((unused)))
318 {
319 rb_dlink_node *ptr, *next;
320 struct timeout_data *td;
321 rb_fde_t *F;
322 PF *hdl;
323 void *data;
324
325 RB_DLINK_FOREACH_SAFE(ptr, next, timeout_list.head)
326 {
327 td = ptr->data;
328 F = td->F;
329 if(F == NULL || !IsFDOpen(F))
330 continue;
331
332 if(td->timeout < rb_current_time())
333 {
334 hdl = td->timeout_handler;
335 data = td->timeout_data;
336 rb_dlinkDelete(&td->node, &timeout_list);
337 F->timeout = NULL;
338 rb_free(td);
339 hdl(F, data);
340 }
341 }
342 }
343
344 static int
345 rb_setsockopt_reuseaddr(rb_fde_t *F)
346 {
347 int opt_one = 1;
348 int ret;
349
350 ret = setsockopt(F->fd, SOL_SOCKET, SO_REUSEADDR, &opt_one, sizeof(opt_one));
351 if (ret) {
352 rb_lib_log("rb_setsockopt_reuseaddr: Cannot set SO_REUSEADDR for FD %d: %s",
353 F->fd, strerror(rb_get_sockerr(F)));
354 return ret;
355 }
356
357 return 0;
358 }
359
360 #ifdef HAVE_LIBSCTP
361 static int
362 rb_setsockopt_sctp(rb_fde_t *F)
363 {
364 int opt_zero = 0;
365 int opt_one = 1;
366 /* workaround for https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/net/sctp?id=299ee123e19889d511092347f5fc14db0f10e3a6 */
367 char *env_mapped = getenv("SCTP_I_WANT_MAPPED_V4_ADDR");
368 int opt_mapped = env_mapped != NULL ? atoi(env_mapped) : opt_zero;
369 int ret;
370 struct sctp_initmsg initmsg;
371 struct sctp_rtoinfo rtoinfo;
372 struct sctp_paddrparams paddrparams;
373 struct sctp_assocparams assocparams;
374
375 ret = setsockopt(F->fd, IPPROTO_SCTP, SCTP_NODELAY, &opt_one, sizeof(opt_one));
376 if (ret) {
377 rb_lib_log("rb_setsockopt_sctp: Cannot set SCTP_NODELAY for fd %d: %s",
378 F->fd, strerror(rb_get_sockerr(F)));
379 return ret;
380 }
381
382 ret = setsockopt(F->fd, IPPROTO_SCTP, SCTP_I_WANT_MAPPED_V4_ADDR, &opt_mapped, sizeof(opt_mapped));
383 if (ret) {
384 rb_lib_log("rb_setsockopt_sctp: Cannot unset SCTP_I_WANT_MAPPED_V4_ADDR for fd %d: %s",
385 F->fd, strerror(rb_get_sockerr(F)));
386 return ret;
387 }
388
389 /* Configure INIT message to specify that we only want one stream */
390 memset(&initmsg, 0, sizeof(initmsg));
391 initmsg.sinit_num_ostreams = 1;
392 initmsg.sinit_max_instreams = 1;
393
394 ret = setsockopt(F->fd, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(initmsg));
395 if (ret) {
396 rb_lib_log("rb_setsockopt_sctp: Cannot set SCTP_INITMSG for fd %d: %s",
397 F->fd, strerror(rb_get_sockerr(F)));
398 return ret;
399 }
400
401 /* Configure RTO values to reduce the maximum timeout */
402 memset(&rtoinfo, 0, sizeof(rtoinfo));
403 rtoinfo.srto_initial = 3000;
404 rtoinfo.srto_min = 1000;
405 rtoinfo.srto_max = 10000;
406
407 ret = setsockopt(F->fd, IPPROTO_SCTP, SCTP_RTOINFO, &rtoinfo, sizeof(rtoinfo));
408 if (ret) {
409 rb_lib_log("rb_setsockopt_sctp: Cannot set SCTP_RTOINFO for fd %d: %s",
410 F->fd, strerror(rb_get_sockerr(F)));
411 return ret;
412 }
413
414 /*
415 * Configure peer address parameters to ensure that we monitor the connection
416 * more often than the default and don't timeout retransmit attempts before
417 * the ping timeout does.
418 *
419 * Each peer address will timeout reachability in about 750s.
420 */
421 memset(&paddrparams, 0, sizeof(paddrparams));
422 paddrparams.spp_assoc_id = 0;
423 memcpy(&paddrparams.spp_address, &in6addr_any, sizeof(in6addr_any));
424 paddrparams.spp_pathmaxrxt = 50;
425 paddrparams.spp_hbinterval = 5000;
426 paddrparams.spp_flags |= SPP_HB_ENABLE;
427
428 ret = setsockopt(F->fd, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, &paddrparams, sizeof(paddrparams));
429 if (ret) {
430 rb_lib_log("rb_setsockopt_sctp: Cannot set SCTP_PEER_ADDR_PARAMS for fd %d: %s",
431 F->fd, strerror(rb_get_sockerr(F)));
432 return ret;
433 }
434
435 /* Configure association parameters for retransmit attempts as above */
436 memset(&assocparams, 0, sizeof(assocparams));
437 assocparams.sasoc_assoc_id = 0;
438 assocparams.sasoc_asocmaxrxt = 50;
439
440 ret = setsockopt(F->fd, IPPROTO_SCTP, SCTP_ASSOCINFO, &assocparams, sizeof(assocparams));
441 if (ret) {
442 rb_lib_log("rb_setsockopt_sctp: Cannot set SCTP_ASSOCINFO for fd %d: %s",
443 F->fd, strerror(rb_get_sockerr(F)));
444 return ret;
445 }
446
447 return 0;
448 }
449 #endif
450
451 int
452 rb_bind(rb_fde_t *F, struct sockaddr *addr)
453 {
454 int ret;
455
456 ret = rb_setsockopt_reuseaddr(F);
457 if (ret)
458 return ret;
459
460 ret = bind(F->fd, addr, GET_SS_LEN(addr));
461 if (ret)
462 return ret;
463
464 return 0;
465 }
466
467 #ifdef HAVE_LIBSCTP
468 static int
469 rb_sctp_bindx_only(rb_fde_t *F, struct sockaddr_storage *addrs, size_t len)
470 {
471 int ret;
472
473 for (size_t i = 0; i < len; i++) {
474 if (GET_SS_FAMILY(&addrs[i]) == AF_UNSPEC)
475 continue;
476
477 ret = sctp_bindx(F->fd, (struct sockaddr *)&addrs[i], 1, SCTP_BINDX_ADD_ADDR);
478 if (ret)
479 return ret;
480 }
481
482 return 0;
483 }
484 #endif
485
486 int
487 rb_sctp_bindx(rb_fde_t *F, struct sockaddr_storage *addrs, size_t len)
488 {
489 #ifdef HAVE_LIBSCTP
490 int ret;
491
492 if ((F->type & RB_FD_SCTP) == 0)
493 return -1;
494
495 ret = rb_setsockopt_reuseaddr(F);
496 if (ret)
497 return ret;
498
499 ret = rb_sctp_bindx_only(F, addrs, len);
500 if (ret)
501 return ret;
502
503 return 0;
504 #else
505 return -1;
506 #endif
507 }
508
509 int
510 rb_inet_get_proto(rb_fde_t *F)
511 {
512 #ifdef HAVE_LIBSCTP
513 if (F->type & RB_FD_SCTP)
514 return IPPROTO_SCTP;
515 #endif
516 return IPPROTO_TCP;
517 }
518
519 static void rb_accept_tryaccept(rb_fde_t *F, void *data __attribute__((unused))) {
520 struct rb_sockaddr_storage st;
521 rb_fde_t *new_F;
522 rb_socklen_t addrlen;
523 int new_fd;
524
525 while(1)
526 {
527 memset(&st, 0, sizeof(st));
528 addrlen = sizeof(st);
529
530 new_fd = accept(F->fd, (struct sockaddr *)&st, &addrlen);
531 if(new_fd < 0)
532 {
533 rb_setselect(F, RB_SELECT_ACCEPT, rb_accept_tryaccept, NULL);
534 return;
535 }
536
537 new_F = rb_open(new_fd, RB_FD_SOCKET | (F->type & RB_FD_INHERIT_TYPES), "Incoming Connection");
538
539 if(new_F == NULL)
540 {
541 rb_lib_log
542 ("rb_accept: new_F == NULL on incoming connection. Closing new_fd == %d",
543 new_fd);
544 close(new_fd);
545 continue;
546 }
547
548 if(rb_unlikely(!rb_set_nb(new_F)))
549 {
550 rb_lib_log("rb_accept: Couldn't set FD %d non blocking!", new_F->fd);
551 rb_close(new_F);
552 }
553
554 mangle_mapped_sockaddr((struct sockaddr *)&st);
555
556 if(F->accept->precb != NULL)
557 {
558 if(!F->accept->precb(new_F, (struct sockaddr *)&st, addrlen, F->accept->data)) /* pre-callback decided to drop it */
559 continue;
560 }
561 #ifdef HAVE_SSL
562 if(F->type & RB_FD_SSL)
563 {
564 rb_ssl_accept_setup(F, new_F, (struct sockaddr *)&st, addrlen);
565 }
566 else
567 #endif /* HAVE_SSL */
568 {
569 F->accept->callback(new_F, RB_OK, (struct sockaddr *)&st, addrlen,
570 F->accept->data);
571 }
572 }
573
574 }
575
576 /* try to accept a TCP connection */
577 void
578 rb_accept_tcp(rb_fde_t *F, ACPRE * precb, ACCB * callback, void *data)
579 {
580 if(F == NULL)
581 return;
582 lrb_assert(callback);
583
584 F->accept = rb_malloc(sizeof(struct acceptdata));
585 F->accept->callback = callback;
586 F->accept->data = data;
587 F->accept->precb = precb;
588 rb_accept_tryaccept(F, NULL);
589 }
590
591 /*
592 * void rb_connect_tcp(int fd, struct sockaddr *dest,
593 * struct sockaddr *clocal,
594 * CNCB *callback, void *data, int timeout)
595 * Input: An fd to connect with, a host and port to connect to,
596 * a local sockaddr to connect from (or NULL to use the
597 * default), a callback, the data to pass into the callback, the
598 * address family.
599 * Output: None.
600 * Side-effects: A non-blocking connection to the host is started, and
601 * if necessary, set up for selection. The callback given
602 * may be called now, or it may be called later.
603 */
604 void
605 rb_connect_tcp(rb_fde_t *F, struct sockaddr *dest,
606 struct sockaddr *clocal, CNCB * callback, void *data, int timeout)
607 {
608 int retval;
609
610 if (F == NULL)
611 return;
612
613 lrb_assert(callback);
614 F->connect = rb_malloc(sizeof(struct conndata));
615 F->connect->callback = callback;
616 F->connect->data = data;
617
618 memcpy(&F->connect->hostaddr, dest, sizeof(F->connect->hostaddr));
619
620 /* Note that we're using a passed sockaddr here. This is because
621 * generally you'll be bind()ing to a sockaddr grabbed from
622 * getsockname(), so this makes things easier.
623 * XXX If NULL is passed as local, we should later on bind() to the
624 * virtual host IP, for completeness.
625 * -- adrian
626 */
627 if((clocal != NULL) && (bind(F->fd, clocal, GET_SS_LEN(clocal)) < 0))
628 {
629 /* Failure, call the callback with RB_ERR_BIND */
630 rb_connect_callback(F, RB_ERR_BIND);
631 /* ... and quit */
632 return;
633 }
634
635 /* We have a valid IP, so we just call tryconnect */
636 /* Make sure we actually set the timeout here .. */
637 rb_settimeout(F, timeout, rb_connect_timeout, NULL);
638
639 retval = connect(F->fd,
640 (struct sockaddr *)&F->connect->hostaddr,
641 GET_SS_LEN(&F->connect->hostaddr));
642 /* Error? */
643 if (retval < 0) {
644 /*
645 * If we get EISCONN, then we've already connect()ed the socket,
646 * which is a good thing.
647 * -- adrian
648 */
649 if (errno == EISCONN) {
650 rb_connect_callback(F, RB_OK);
651 } else if (rb_ignore_errno(errno)) {
652 /* Ignore error? Reschedule */
653 rb_setselect(F, RB_SELECT_CONNECT, rb_connect_outcome, NULL);
654 } else {
655 /* Error? Fail with RB_ERR_CONNECT */
656 rb_connect_callback(F, RB_ERR_CONNECT);
657 }
658 return;
659 }
660 /* If we get here, we've succeeded, so call with RB_OK */
661 rb_connect_callback(F, RB_OK);
662 }
663
664 void
665 rb_connect_sctp(rb_fde_t *F, struct sockaddr_storage *dest, size_t dest_len,
666 struct sockaddr_storage *clocal, size_t clocal_len,
667 CNCB *callback, void *data, int timeout)
668 {
669 #ifdef HAVE_LIBSCTP
670 uint8_t packed_dest[sizeof(struct sockaddr_storage) * dest_len];
671 uint8_t *p = &packed_dest[0];
672 size_t n = 0;
673 int retval;
674
675 if (F == NULL)
676 return;
677
678 lrb_assert(callback);
679 F->connect = rb_malloc(sizeof(struct conndata));
680 F->connect->callback = callback;
681 F->connect->data = data;
682
683 if ((F->type & RB_FD_SCTP) == 0) {
684 rb_connect_callback(F, RB_ERR_CONNECT);
685 return;
686 }
687
688 for (size_t i = 0; i < dest_len; i++) {
689 if (GET_SS_FAMILY(&dest[i]) == AF_INET6) {
690 memcpy(p, &dest[i], sizeof(struct sockaddr_in6));
691 n++;
692 p += sizeof(struct sockaddr_in6);
693 } else if (GET_SS_FAMILY(&dest[i]) == AF_INET) {
694 memcpy(p, &dest[i], sizeof(struct sockaddr_in));
695 n++;
696 p += sizeof(struct sockaddr_in);
697 }
698 }
699 dest_len = n;
700
701 memcpy(&F->connect->hostaddr, &dest[0], sizeof(F->connect->hostaddr));
702
703 if ((clocal_len > 0) && (rb_sctp_bindx_only(F, clocal, clocal_len) < 0)) {
704 /* Failure, call the callback with RB_ERR_BIND */
705 rb_connect_callback(F, RB_ERR_BIND);
706 /* ... and quit */
707 return;
708 }
709
710 rb_settimeout(F, timeout, rb_connect_timeout, NULL);
711
712 retval = sctp_connectx(F->fd, (struct sockaddr *)packed_dest, dest_len, NULL);
713 /* Error? */
714 if (retval < 0) {
715 /*
716 * If we get EISCONN, then we've already connect()ed the socket,
717 * which is a good thing.
718 * -- adrian
719 */
720 if (errno == EISCONN) {
721 rb_connect_callback(F, RB_OK);
722 } else if (rb_ignore_errno(errno)) {
723 /* Ignore error? Reschedule */
724 rb_setselect(F, RB_SELECT_CONNECT, rb_connect_outcome, NULL);
725 } else {
726 /* Error? Fail with RB_ERR_CONNECT */
727 rb_connect_callback(F, RB_ERR_CONNECT);
728 }
729 return;
730 }
731 /* If we get here, we've succeeded, so call with RB_OK */
732 rb_connect_callback(F, RB_OK);
733 #else
734 rb_connect_callback(F, RB_ERR_CONNECT);
735 #endif
736 }
737
738 /*
739 * rb_connect_callback() - call the callback, and continue with life
740 */
741 void
742 rb_connect_callback(rb_fde_t *F, int status)
743 {
744 CNCB *hdl;
745 void *data;
746 int errtmp = errno; /* save errno as rb_settimeout clobbers it sometimes */
747
748 /* This check is gross..but probably necessary */
749 if(F == NULL || F->connect == NULL || F->connect->callback == NULL)
750 return;
751 /* Clear the connect flag + handler */
752 hdl = F->connect->callback;
753 data = F->connect->data;
754 F->connect->callback = NULL;
755
756
757 /* Clear the timeout handler */
758 rb_settimeout(F, 0, NULL, NULL);
759 errno = errtmp;
760 /* Call the handler */
761 hdl(F, status, data);
762 }
763
764
765 /*
766 * rb_connect_timeout() - this gets called when the socket connection
767 * times out. This *only* can be called once connect() is initially
768 * called ..
769 */
770 static void
771 rb_connect_timeout(rb_fde_t *F, void *notused __attribute__((unused)))
772 {
773 /* error! */
774 rb_connect_callback(F, RB_ERR_TIMEOUT);
775 }
776
777 static void
778 rb_connect_outcome(rb_fde_t *F, void *notused __attribute__((unused)))
779 {
780 int retval;
781 int err = 0;
782 socklen_t len = sizeof(err);
783
784 if(F == NULL || F->connect == NULL || F->connect->callback == NULL)
785 return;
786 retval = getsockopt(F->fd, SOL_SOCKET, SO_ERROR, &err, &len);
787 if ((retval >= 0) && (err != 0)) {
788 errno = err;
789 retval = -1;
790 }
791 if (retval < 0) {
792 /* Error? Fail with RB_ERR_CONNECT */
793 rb_connect_callback(F, RB_ERR_CONNECT);
794 return;
795 }
796 /* If we get here, we've succeeded, so call with RB_OK */
797 rb_connect_callback(F, RB_OK);
798 }
799
800
801 int
802 rb_connect_sockaddr(rb_fde_t *F, struct sockaddr *addr, int len)
803 {
804 if(F == NULL)
805 return 0;
806
807 memcpy(addr, &F->connect->hostaddr, len);
808 return 1;
809 }
810
811 /*
812 * rb_error_str() - return an error string for the given error condition
813 */
814 const char *
815 rb_errstr(int error)
816 {
817 if(error < 0 || error >= RB_ERR_MAX)
818 return "Invalid error number!";
819 return rb_err_str[error];
820 }
821
822
823 int
824 rb_socketpair(int family, int sock_type, int proto, rb_fde_t **F1, rb_fde_t **F2, const char *note)
825 {
826 int nfd[2];
827 if(number_fd >= rb_maxconnections)
828 {
829 errno = ENFILE;
830 return -1;
831 }
832
833 if(socketpair(family, sock_type, proto, nfd))
834 return -1;
835
836 *F1 = rb_open(nfd[0], RB_FD_SOCKET, note);
837 *F2 = rb_open(nfd[1], RB_FD_SOCKET, note);
838
839 if(*F1 == NULL)
840 {
841 if(*F2 != NULL)
842 rb_close(*F2);
843 return -1;
844 }
845
846 if(*F2 == NULL)
847 {
848 rb_close(*F1);
849 return -1;
850 }
851
852 /* Set the socket non-blocking, and other wonderful bits */
853 if(rb_unlikely(!rb_set_nb(*F1)))
854 {
855 rb_lib_log("rb_open: Couldn't set FD %d non blocking: %s", nfd[0], strerror(errno));
856 rb_close(*F1);
857 rb_close(*F2);
858 return -1;
859 }
860
861 if(rb_unlikely(!rb_set_nb(*F2)))
862 {
863 rb_lib_log("rb_open: Couldn't set FD %d non blocking: %s", nfd[1], strerror(errno));
864 rb_close(*F1);
865 rb_close(*F2);
866 return -1;
867 }
868
869 return 0;
870 }
871
872
873 int
874 rb_pipe(rb_fde_t **F1, rb_fde_t **F2, const char *desc)
875 {
876 int fd[2];
877 if(number_fd >= rb_maxconnections)
878 {
879 errno = ENFILE;
880 return -1;
881 }
882 if(pipe(fd) == -1)
883 return -1;
884 *F1 = rb_open(fd[0], RB_FD_PIPE, desc);
885 *F2 = rb_open(fd[1], RB_FD_PIPE, desc);
886
887 if(rb_unlikely(!rb_set_nb(*F1)))
888 {
889 rb_lib_log("rb_open: Couldn't set FD %d non blocking: %s", fd[0], strerror(errno));
890 rb_close(*F1);
891 rb_close(*F2);
892 return -1;
893 }
894
895 if(rb_unlikely(!rb_set_nb(*F2)))
896 {
897 rb_lib_log("rb_open: Couldn't set FD %d non blocking: %s", fd[1], strerror(errno));
898 rb_close(*F1);
899 rb_close(*F2);
900 return -1;
901 }
902
903
904 return 0;
905 }
906
907 /*
908 * rb_socket() - open a socket
909 *
910 * This is a highly highly cut down version of squid's rb_open() which
911 * for the most part emulates socket(), *EXCEPT* it fails if we're about
912 * to run out of file descriptors.
913 */
914 rb_fde_t *
915 rb_socket(int family, int sock_type, int proto, const char *note)
916 {
917 rb_fde_t *F;
918 int fd;
919 /* First, make sure we aren't going to run out of file descriptors */
920 if(rb_unlikely(number_fd >= rb_maxconnections))
921 {
922 errno = ENFILE;
923 return NULL;
924 }
925
926 /*
927 * Next, we try to open the socket. We *should* drop the reserved FD
928 * limit if/when we get an error, but we can deal with that later.
929 * XXX !!! -- adrian
930 */
931 fd = socket(family, sock_type, proto);
932 if(rb_unlikely(fd < 0))
933 return NULL; /* errno will be passed through, yay.. */
934
935 /*
936 * Make sure we can take both IPv4 and IPv6 connections
937 * on an AF_INET6 SCTP socket, otherwise keep them separate
938 */
939 if(family == AF_INET6)
940 {
941 #ifdef HAVE_LIBSCTP
942 int v6only = (proto == IPPROTO_SCTP) ? 0 : 1;
943 #else
944 int v6only = 1;
945 #endif
946 if(setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (void *) &v6only, sizeof(v6only)) == -1)
947 {
948 rb_lib_log("rb_socket: Could not set IPV6_V6ONLY option to %d on FD %d: %s",
949 v6only, fd, strerror(errno));
950 close(fd);
951 return NULL;
952 }
953 }
954
955 F = rb_open(fd, RB_FD_SOCKET, note);
956 if(F == NULL)
957 {
958 rb_lib_log("rb_socket: rb_open returns NULL on FD %d: %s, closing fd", fd,
959 strerror(errno));
960 close(fd);
961 return NULL;
962 }
963
964 #ifdef HAVE_LIBSCTP
965 if (proto == IPPROTO_SCTP) {
966 F->type |= RB_FD_SCTP;
967
968 if (rb_setsockopt_sctp(F)) {
969 rb_lib_log("rb_socket: Could not set SCTP socket options on FD %d: %s",
970 fd, strerror(errno));
971 close(fd);
972 return NULL;
973 }
974 }
975 #endif
976
977 /* Set the socket non-blocking, and other wonderful bits */
978 if(rb_unlikely(!rb_set_nb(F)))
979 {
980 rb_lib_log("rb_open: Couldn't set FD %d non blocking: %s", fd, strerror(errno));
981 rb_close(F);
982 return NULL;
983 }
984
985 return F;
986 }
987
988 /*
989 * If a sockaddr_storage is AF_INET6 but is a mapped IPv4
990 * socket manged the sockaddr.
991 */
992 static void
993 mangle_mapped_sockaddr(struct sockaddr *in)
994 {
995 struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)in;
996
997 if(in->sa_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&in6->sin6_addr))
998 {
999 struct sockaddr_in in4;
1000 memset(&in4, 0, sizeof(struct sockaddr_in));
1001 in4.sin_family = AF_INET;
1002 in4.sin_port = in6->sin6_port;
1003 in4.sin_addr.s_addr = ((uint32_t *)&in6->sin6_addr)[3];
1004 memcpy(in, &in4, sizeof(struct sockaddr_in));
1005 }
1006 }
1007
1008 /*
1009 * rb_listen() - listen on a port
1010 */
1011 int
1012 rb_listen(rb_fde_t *F, int backlog, int defer_accept)
1013 {
1014 int result;
1015
1016 F->type = RB_FD_SOCKET | RB_FD_LISTEN | (F->type & RB_FD_INHERIT_TYPES);
1017 result = listen(F->fd, backlog);
1018
1019 #ifdef TCP_DEFER_ACCEPT
1020 if (defer_accept && !result)
1021 {
1022 (void)setsockopt(F->fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &backlog, sizeof(int));
1023 }
1024 #endif
1025 #ifdef SO_ACCEPTFILTER
1026 if (defer_accept && !result)
1027 {
1028 struct accept_filter_arg afa;
1029
1030 memset(&afa, '\0', sizeof afa);
1031 rb_strlcpy(afa.af_name, "dataready", sizeof afa.af_name);
1032 (void)setsockopt(F->fd, SOL_SOCKET, SO_ACCEPTFILTER, &afa,
1033 sizeof afa);
1034 }
1035 #endif
1036
1037 return result;
1038 }
1039
1040 void
1041 rb_fdlist_init(int closeall, int maxfds, size_t heapsize)
1042 {
1043 static int initialized = 0;
1044
1045 if(!initialized)
1046 {
1047 rb_maxconnections = maxfds;
1048 if(closeall)
1049 rb_close_all();
1050 /* Since we're doing this once .. */
1051 initialized = 1;
1052 }
1053 fd_heap = rb_bh_create(sizeof(rb_fde_t), heapsize, "librb_fd_heap");
1054
1055 }
1056
1057
1058 /* Called to open a given filedescriptor */
1059 rb_fde_t *
1060 rb_open(int fd, uint8_t type, const char *desc)
1061 {
1062 rb_fde_t *F;
1063 lrb_assert(fd >= 0);
1064
1065 F = add_fd(fd);
1066
1067 lrb_assert(!IsFDOpen(F));
1068 if(rb_unlikely(IsFDOpen(F)))
1069 {
1070 const char *fdesc;
1071 if(F != NULL && F->desc != NULL)
1072 fdesc = F->desc;
1073 else
1074 fdesc = "NULL";
1075 rb_lib_log("Trying to rb_open an already open FD: %d desc: %s", fd, fdesc);
1076 return NULL;
1077 }
1078 F->fd = fd;
1079 F->type = type;
1080 SetFDOpen(F);
1081
1082 if(desc != NULL)
1083 F->desc = rb_strndup(desc, FD_DESC_SZ);
1084 number_fd++;
1085 return F;
1086 }
1087
1088
1089 /* Called to close a given filedescriptor */
1090 void
1091 rb_close(rb_fde_t *F)
1092 {
1093 int type, fd;
1094
1095 if(F == NULL)
1096 return;
1097
1098 fd = F->fd;
1099 type = F->type;
1100 lrb_assert(IsFDOpen(F));
1101
1102 lrb_assert(!(type & RB_FD_FILE));
1103 if(rb_unlikely(type & RB_FD_FILE))
1104 {
1105 lrb_assert(F->read_handler == NULL);
1106 lrb_assert(F->write_handler == NULL);
1107 }
1108
1109 if (type & RB_FD_LISTEN) {
1110 listen(F->fd, 0);
1111 }
1112
1113 rb_setselect(F, RB_SELECT_WRITE | RB_SELECT_READ, NULL, NULL);
1114 rb_settimeout(F, 0, NULL, NULL);
1115 rb_free(F->accept);
1116 rb_free(F->connect);
1117 rb_free(F->desc);
1118 #ifdef HAVE_SSL
1119 if(type & RB_FD_SSL)
1120 {
1121 rb_ssl_shutdown(F);
1122 }
1123 #endif /* HAVE_SSL */
1124 if(IsFDOpen(F))
1125 {
1126 remove_fd(F);
1127 ClearFDOpen(F);
1128 }
1129
1130 if(type & RB_FD_LISTEN)
1131 shutdown(fd, SHUT_RDWR);
1132 }
1133
1134
1135 /*
1136 * rb_dump_fd() - dump the list of active filedescriptors
1137 */
1138 void
1139 rb_dump_fd(DUMPCB * cb, void *data)
1140 {
1141 static const char *empty = "";
1142 rb_dlink_node *ptr;
1143 rb_dlink_list *bucket;
1144 rb_fde_t *F;
1145 unsigned int i;
1146
1147 for(i = 0; i < RB_FD_HASH_SIZE; i++)
1148 {
1149 bucket = &rb_fd_table[i];
1150
1151 if(rb_dlink_list_length(bucket) <= 0)
1152 continue;
1153
1154 RB_DLINK_FOREACH(ptr, bucket->head)
1155 {
1156 F = ptr->data;
1157 if(F == NULL || !IsFDOpen(F))
1158 continue;
1159
1160 cb(F->fd, F->desc ? F->desc : empty, data);
1161 }
1162 }
1163 }
1164
1165 /*
1166 * rb_note() - set the fd note
1167 *
1168 * Note: must be careful not to overflow rb_fd_table[fd].desc when
1169 * calling.
1170 */
1171 void
1172 rb_note(rb_fde_t *F, const char *string)
1173 {
1174 if(F == NULL)
1175 return;
1176
1177 rb_free(F->desc);
1178 F->desc = rb_strndup(string, FD_DESC_SZ);
1179 }
1180
1181 void
1182 rb_set_type(rb_fde_t *F, uint8_t type)
1183 {
1184 /* if the caller is calling this, lets assume they have a clue */
1185 F->type = type;
1186 return;
1187 }
1188
1189 uint8_t
1190 rb_get_type(rb_fde_t *F)
1191 {
1192 return F->type;
1193 }
1194
1195 int
1196 rb_fd_ssl(rb_fde_t *F)
1197 {
1198 if(F == NULL)
1199 return 0;
1200 if(F->type & RB_FD_SSL)
1201 return 1;
1202 return 0;
1203 }
1204
1205 int
1206 rb_get_fd(rb_fde_t *F)
1207 {
1208 if(F == NULL)
1209 return -1;
1210 return (F->fd);
1211 }
1212
1213 rb_fde_t *
1214 rb_get_fde(int fd)
1215 {
1216 return rb_find_fd(fd);
1217 }
1218
1219 ssize_t
1220 rb_read(rb_fde_t *F, void *buf, int count)
1221 {
1222 ssize_t ret;
1223 if(F == NULL)
1224 return 0;
1225
1226 /* This needs to be *before* RB_FD_SOCKET otherwise you'll process
1227 * an SSL socket as a regular socket
1228 */
1229 #ifdef HAVE_SSL
1230 if(F->type & RB_FD_SSL)
1231 {
1232 return rb_ssl_read(F, buf, count);
1233 }
1234 #endif
1235 if(F->type & RB_FD_SOCKET)
1236 {
1237 ret = recv(F->fd, buf, count, 0);
1238 return ret;
1239 }
1240
1241
1242 /* default case */
1243 return read(F->fd, buf, count);
1244 }
1245
1246
1247 ssize_t
1248 rb_write(rb_fde_t *F, const void *buf, int count)
1249 {
1250 ssize_t ret;
1251 if(F == NULL)
1252 return 0;
1253
1254 #ifdef HAVE_SSL
1255 if(F->type & RB_FD_SSL)
1256 {
1257 return rb_ssl_write(F, buf, count);
1258 }
1259 #endif
1260 if(F->type & RB_FD_SOCKET)
1261 {
1262 ret = send(F->fd, buf, count, MSG_NOSIGNAL);
1263 return ret;
1264 }
1265
1266 return write(F->fd, buf, count);
1267 }
1268
1269 #ifdef HAVE_SSL
1270 static ssize_t
1271 rb_fake_writev(rb_fde_t *F, const struct rb_iovec *vp, size_t vpcount)
1272 {
1273 ssize_t count = 0;
1274
1275 while(vpcount-- > 0)
1276 {
1277 ssize_t written = rb_write(F, vp->iov_base, vp->iov_len);
1278
1279 if(written <= 0)
1280 {
1281 if(count > 0)
1282 return count;
1283 else
1284 return written;
1285 }
1286 count += written;
1287 vp++;
1288 }
1289 return (count);
1290 }
1291 #endif
1292
1293 ssize_t
1294 rb_writev(rb_fde_t *F, struct rb_iovec * vector, int count)
1295 {
1296 if(F == NULL)
1297 {
1298 errno = EBADF;
1299 return -1;
1300 }
1301 #ifdef HAVE_SSL
1302 if(F->type & RB_FD_SSL)
1303 {
1304 return rb_fake_writev(F, vector, count);
1305 }
1306 #endif /* HAVE_SSL */
1307 if(F->type & RB_FD_SOCKET)
1308 {
1309 struct msghdr msg;
1310 memset(&msg, 0, sizeof(msg));
1311 msg.msg_iov = (struct iovec *)vector;
1312 msg.msg_iovlen = count;
1313 return sendmsg(F->fd, &msg, MSG_NOSIGNAL);
1314 }
1315 return writev(F->fd, (struct iovec *)vector, count);
1316
1317 }
1318
1319 /*
1320 * From: Thomas Helvey <tomh@inxpress.net>
1321 */
1322 static const char *IpQuadTab[] = {
1323 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
1324 "10", "11", "12", "13", "14", "15", "16", "17", "18", "19",
1325 "20", "21", "22", "23", "24", "25", "26", "27", "28", "29",
1326 "30", "31", "32", "33", "34", "35", "36", "37", "38", "39",
1327 "40", "41", "42", "43", "44", "45", "46", "47", "48", "49",
1328 "50", "51", "52", "53", "54", "55", "56", "57", "58", "59",
1329 "60", "61", "62", "63", "64", "65", "66", "67", "68", "69",
1330 "70", "71", "72", "73", "74", "75", "76", "77", "78", "79",
1331 "80", "81", "82", "83", "84", "85", "86", "87", "88", "89",
1332 "90", "91", "92", "93", "94", "95", "96", "97", "98", "99",
1333 "100", "101", "102", "103", "104", "105", "106", "107", "108", "109",
1334 "110", "111", "112", "113", "114", "115", "116", "117", "118", "119",
1335 "120", "121", "122", "123", "124", "125", "126", "127", "128", "129",
1336 "130", "131", "132", "133", "134", "135", "136", "137", "138", "139",
1337 "140", "141", "142", "143", "144", "145", "146", "147", "148", "149",
1338 "150", "151", "152", "153", "154", "155", "156", "157", "158", "159",
1339 "160", "161", "162", "163", "164", "165", "166", "167", "168", "169",
1340 "170", "171", "172", "173", "174", "175", "176", "177", "178", "179",
1341 "180", "181", "182", "183", "184", "185", "186", "187", "188", "189",
1342 "190", "191", "192", "193", "194", "195", "196", "197", "198", "199",
1343 "200", "201", "202", "203", "204", "205", "206", "207", "208", "209",
1344 "210", "211", "212", "213", "214", "215", "216", "217", "218", "219",
1345 "220", "221", "222", "223", "224", "225", "226", "227", "228", "229",
1346 "230", "231", "232", "233", "234", "235", "236", "237", "238", "239",
1347 "240", "241", "242", "243", "244", "245", "246", "247", "248", "249",
1348 "250", "251", "252", "253", "254", "255"
1349 };
1350
1351 /*
1352 * inetntoa - in_addr to string
1353 * changed name to remove collision possibility and
1354 * so behaviour is guaranteed to take a pointer arg.
1355 * -avalon 23/11/92
1356 * inet_ntoa -- returned the dotted notation of a given
1357 * internet number
1358 * argv 11/90).
1359 * inet_ntoa -- its broken on some Ultrix/Dynix too. -avalon
1360 */
1361
1362 static const char *
1363 inetntoa(const char *in)
1364 {
1365 static char buf[16];
1366 char *bufptr = buf;
1367 const unsigned char *a = (const unsigned char *)in;
1368 const char *n;
1369
1370 n = IpQuadTab[*a++];
1371 while(*n)
1372 *bufptr++ = *n++;
1373 *bufptr++ = '.';
1374 n = IpQuadTab[*a++];
1375 while(*n)
1376 *bufptr++ = *n++;
1377 *bufptr++ = '.';
1378 n = IpQuadTab[*a++];
1379 while(*n)
1380 *bufptr++ = *n++;
1381 *bufptr++ = '.';
1382 n = IpQuadTab[*a];
1383 while(*n)
1384 *bufptr++ = *n++;
1385 *bufptr = '\0';
1386 return buf;
1387 }
1388
1389 /*
1390 * WARNING: Don't even consider trying to compile this on a system where
1391 * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
1392 */
1393
1394 static const char *inet_ntop4(const unsigned char *src, char *dst, unsigned int size);
1395 static const char *inet_ntop6(const unsigned char *src, char *dst, unsigned int size);
1396
1397 /* const char *
1398 * inet_ntop4(src, dst, size)
1399 * format an IPv4 address
1400 * return:
1401 * `dst' (as a const)
1402 * notes:
1403 * (1) uses no statics
1404 * (2) takes a unsigned char* not an in_addr as input
1405 * author:
1406 * Paul Vixie, 1996.
1407 */
1408 static const char *
1409 inet_ntop4(const unsigned char *src, char *dst, unsigned int size)
1410 {
1411 if(size < 16)
1412 return NULL;
1413 return strcpy(dst, inetntoa((const char *)src));
1414 }
1415
1416 /* const char *
1417 * inet_ntop6(src, dst, size)
1418 * convert IPv6 binary address into presentation (printable) format
1419 * author:
1420 * Paul Vixie, 1996.
1421 */
1422 static const char *
1423 inet_ntop6(const unsigned char *src, char *dst, unsigned int size)
1424 {
1425 /*
1426 * Note that int32_t and int16_t need only be "at least" large enough
1427 * to contain a value of the specified size. On some systems, like
1428 * Crays, there is no such thing as an integer variable with 16 bits.
1429 * Keep this in mind if you think this function should have been coded
1430 * to use pointer overlays. All the world's not a VAX.
1431 */
1432 char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
1433 struct
1434 {
1435 int base, len;
1436 }
1437 best, cur;
1438 unsigned int words[IN6ADDRSZ / INT16SZ];
1439 int i;
1440
1441 /*
1442 * Preprocess:
1443 * Copy the input (bytewise) array into a wordwise array.
1444 * Find the longest run of 0x00's in src[] for :: shorthanding.
1445 */
1446 memset(words, '\0', sizeof words);
1447 for(i = 0; i < IN6ADDRSZ; i += 2)
1448 words[i / 2] = (src[i] << 8) | src[i + 1];
1449 best.base = -1;
1450 best.len = 0;
1451 cur.base = -1;
1452 cur.len = 0;
1453 for(i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
1454 {
1455 if(words[i] == 0)
1456 {
1457 if(cur.base == -1)
1458 cur.base = i, cur.len = 1;
1459 else
1460 cur.len++;
1461 }
1462 else
1463 {
1464 if(cur.base != -1)
1465 {
1466 if(best.base == -1 || cur.len > best.len)
1467 best = cur;
1468 cur.base = -1;
1469 }
1470 }
1471 }
1472 if(cur.base != -1)
1473 {
1474 if(best.base == -1 || cur.len > best.len)
1475 best = cur;
1476 }
1477 if(best.base != -1 && best.len < 2)
1478 best.base = -1;
1479
1480 /*
1481 * Format the result.
1482 */
1483 tp = tmp;
1484 for(i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
1485 {
1486 /* Are we inside the best run of 0x00's? */
1487 if(best.base != -1 && i >= best.base && i < (best.base + best.len))
1488 {
1489 if(i == best.base)
1490 {
1491 if(i == 0)
1492 *tp++ = '0';
1493 *tp++ = ':';
1494 }
1495 continue;
1496 }
1497 /* Are we following an initial run of 0x00s or any real hex? */
1498 if(i != 0)
1499 *tp++ = ':';
1500 /* Is this address an encapsulated IPv4? */
1501 if(i == 6 && best.base == 0 &&
1502 (best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
1503 {
1504 if(!inet_ntop4(src + 12, tp, sizeof tmp - (tp - tmp)))
1505 return (NULL);
1506 tp += strlen(tp);
1507 break;
1508 }
1509 tp += sprintf(tp, "%x", words[i]);
1510 }
1511 /* Was it a trailing run of 0x00's? */
1512 if(best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
1513 *tp++ = ':';
1514 *tp++ = '\0';
1515
1516 /*
1517 * Check for overflow, copy, and we're done.
1518 */
1519
1520 if((unsigned int)(tp - tmp) > size)
1521 {
1522 return (NULL);
1523 }
1524 return memcpy(dst, tmp, tp - tmp);
1525 }
1526
1527 int
1528 rb_inet_pton_sock(const char *src, struct sockaddr_storage *dst)
1529 {
1530 memset(dst, 0, sizeof(*dst));
1531 if(rb_inet_pton(AF_INET, src, &((struct sockaddr_in *)dst)->sin_addr))
1532 {
1533 SET_SS_FAMILY(dst, AF_INET);
1534 SET_SS_PORT(dst, 0);
1535 SET_SS_LEN(dst, sizeof(struct sockaddr_in));
1536 return 1;
1537 }
1538 else if(rb_inet_pton(AF_INET6, src, &((struct sockaddr_in6 *)dst)->sin6_addr))
1539 {
1540 SET_SS_FAMILY(dst, AF_INET6);
1541 SET_SS_PORT(dst, 0);
1542 SET_SS_LEN(dst, sizeof(struct sockaddr_in6));
1543 return 1;
1544 }
1545 return 0;
1546 }
1547
1548 const char *
1549 rb_inet_ntop_sock(struct sockaddr *src, char *dst, unsigned int size)
1550 {
1551 switch (src->sa_family)
1552 {
1553 case AF_INET:
1554 return (rb_inet_ntop(AF_INET, &((struct sockaddr_in *)src)->sin_addr, dst, size));
1555 case AF_INET6:
1556 return (rb_inet_ntop
1557 (AF_INET6, &((struct sockaddr_in6 *)src)->sin6_addr, dst, size));
1558 default:
1559 return NULL;
1560 }
1561 }
1562
1563 /* char *
1564 * rb_inet_ntop(af, src, dst, size)
1565 * convert a network format address to presentation format.
1566 * return:
1567 * pointer to presentation format address (`dst'), or NULL (see errno).
1568 * author:
1569 * Paul Vixie, 1996.
1570 */
1571 const char *
1572 rb_inet_ntop(int af, const void *src, char *dst, unsigned int size)
1573 {
1574 switch (af)
1575 {
1576 case AF_INET:
1577 return (inet_ntop4(src, dst, size));
1578 case AF_INET6:
1579 if(IN6_IS_ADDR_V4MAPPED((const struct in6_addr *)src) ||
1580 IN6_IS_ADDR_V4COMPAT((const struct in6_addr *)src))
1581 return (inet_ntop4
1582 ((const unsigned char *)&((const struct in6_addr *)src)->
1583 s6_addr[12], dst, size));
1584 else
1585 return (inet_ntop6(src, dst, size));
1586 default:
1587 return (NULL);
1588 }
1589 /* NOTREACHED */
1590 }
1591
1592 /*
1593 * WARNING: Don't even consider trying to compile this on a system where
1594 * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
1595 */
1596
1597 /* int
1598 * rb_inet_pton(af, src, dst)
1599 * convert from presentation format (which usually means ASCII printable)
1600 * to network format (which is usually some kind of binary format).
1601 * return:
1602 * 1 if the address was valid for the specified address family
1603 * 0 if the address wasn't valid (`dst' is untouched in this case)
1604 * -1 if some other error occurred (`dst' is untouched in this case, too)
1605 * author:
1606 * Paul Vixie, 1996.
1607 */
1608
1609 /* int
1610 * inet_pton4(src, dst)
1611 * like inet_aton() but without all the hexadecimal and shorthand.
1612 * return:
1613 * 1 if `src' is a valid dotted quad, else 0.
1614 * notice:
1615 * does not touch `dst' unless it's returning 1.
1616 * author:
1617 * Paul Vixie, 1996.
1618 */
1619 static int
1620 inet_pton4(const char *src, unsigned char *dst)
1621 {
1622 int saw_digit, octets, ch;
1623 unsigned char tmp[INADDRSZ], *tp;
1624
1625 saw_digit = 0;
1626 octets = 0;
1627 *(tp = tmp) = 0;
1628 while((ch = *src++) != '\0')
1629 {
1630
1631 if(ch >= '0' && ch <= '9')
1632 {
1633 unsigned int new = *tp * 10 + (ch - '0');
1634
1635 if(new > 255)
1636 return (0);
1637 *tp = new;
1638 if(!saw_digit)
1639 {
1640 if(++octets > 4)
1641 return (0);
1642 saw_digit = 1;
1643 }
1644 }
1645 else if(ch == '.' && saw_digit)
1646 {
1647 if(octets == 4)
1648 return (0);
1649 *++tp = 0;
1650 saw_digit = 0;
1651 }
1652 else
1653 return (0);
1654 }
1655 if(octets < 4)
1656 return (0);
1657 memcpy(dst, tmp, INADDRSZ);
1658 return (1);
1659 }
1660
1661 /* int
1662 * inet_pton6(src, dst)
1663 * convert presentation level address to network order binary form.
1664 * return:
1665 * 1 if `src' is a valid [RFC1884 2.2] address, else 0.
1666 * notice:
1667 * (1) does not touch `dst' unless it's returning 1.
1668 * (2) :: in a full address is silently ignored.
1669 * credit:
1670 * inspired by Mark Andrews.
1671 * author:
1672 * Paul Vixie, 1996.
1673 */
1674
1675 static int
1676 inet_pton6(const char *src, unsigned char *dst)
1677 {
1678 static const char xdigits[] = "0123456789abcdef";
1679 unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
1680 const char *curtok;
1681 int ch, saw_xdigit;
1682 unsigned int val;
1683
1684 tp = memset(tmp, '\0', IN6ADDRSZ);
1685 endp = tp + IN6ADDRSZ;
1686 colonp = NULL;
1687 /* Leading :: requires some special handling. */
1688 if(*src == ':')
1689 if(*++src != ':')
1690 return (0);
1691 curtok = src;
1692 saw_xdigit = 0;
1693 val = 0;
1694 while((ch = tolower((unsigned char)*src++)) != '\0')
1695 {
1696 const char *pch;
1697
1698 pch = strchr(xdigits, ch);
1699 if(pch != NULL)
1700 {
1701 val <<= 4;
1702 val |= (pch - xdigits);
1703 if(val > 0xffff)
1704 return (0);
1705 saw_xdigit = 1;
1706 continue;
1707 }
1708 if(ch == ':')
1709 {
1710 curtok = src;
1711 if(!saw_xdigit)
1712 {
1713 if(colonp)
1714 return (0);
1715 colonp = tp;
1716 continue;
1717 }
1718 else if(*src == '\0')
1719 {
1720 return (0);
1721 }
1722 if(tp + INT16SZ > endp)
1723 return (0);
1724 *tp++ = (unsigned char)(val >> 8) & 0xff;
1725 *tp++ = (unsigned char)val & 0xff;
1726 saw_xdigit = 0;
1727 val = 0;
1728 continue;
1729 }
1730 if(*src != '\0' && ch == '.')
1731 {
1732 if(((tp + INADDRSZ) <= endp) && inet_pton4(curtok, tp) > 0)
1733 {
1734 tp += INADDRSZ;
1735 saw_xdigit = 0;
1736 break; /* '\0' was seen by inet_pton4(). */
1737 }
1738 }
1739 else
1740 continue;
1741 return (0);
1742 }
1743 if(saw_xdigit)
1744 {
1745 if(tp + INT16SZ > endp)
1746 return (0);
1747 *tp++ = (unsigned char)(val >> 8) & 0xff;
1748 *tp++ = (unsigned char)val & 0xff;
1749 }
1750 if(colonp != NULL)
1751 {
1752 /*
1753 * Since some memmove()'s erroneously fail to handle
1754 * overlapping regions, we'll do the shift by hand.
1755 */
1756 const int n = tp - colonp;
1757 int i;
1758
1759 if(tp == endp)
1760 return (0);
1761 for(i = 1; i <= n; i++)
1762 {
1763 endp[-i] = colonp[n - i];
1764 colonp[n - i] = 0;
1765 }
1766 tp = endp;
1767 }
1768 if(tp != endp)
1769 return (0);
1770 memcpy(dst, tmp, IN6ADDRSZ);
1771 return (1);
1772 }
1773
1774 int
1775 rb_inet_pton(int af, const char *src, void *dst)
1776 {
1777 switch (af)
1778 {
1779 case AF_INET:
1780 return (inet_pton4(src, dst));
1781 case AF_INET6:
1782 /* Somebody might have passed as an IPv4 address this is sick but it works */
1783 if(inet_pton4(src, dst))
1784 {
1785 char tmp[HOSTIPLEN];
1786 sprintf(tmp, "::ffff:%s", src);
1787 return (inet_pton6(tmp, dst));
1788 }
1789 else
1790 return (inet_pton6(src, dst));
1791 default:
1792 return (-1);
1793 }
1794 /* NOTREACHED */
1795 }
1796
1797
1798 static void (*setselect_handler) (rb_fde_t *, unsigned int, PF *, void *);
1799 static int (*select_handler) (long);
1800 static int (*setup_fd_handler) (rb_fde_t *);
1801 static int (*io_sched_event) (struct ev_entry *, int);
1802 static void (*io_unsched_event) (struct ev_entry *);
1803 static int (*io_supports_event) (void);
1804 static void (*io_init_event) (void);
1805 static char iotype[25];
1806
1807 const char *
1808 rb_get_iotype(void)
1809 {
1810 return iotype;
1811 }
1812
1813 static int
1814 rb_unsupported_event(void)
1815 {
1816 return 0;
1817 }
1818
1819 static int
1820 try_kqueue(void)
1821 {
1822 if(!rb_init_netio_kqueue())
1823 {
1824 setselect_handler = rb_setselect_kqueue;
1825 select_handler = rb_select_kqueue;
1826 setup_fd_handler = rb_setup_fd_kqueue;
1827 io_sched_event = rb_kqueue_sched_event;
1828 io_unsched_event = rb_kqueue_unsched_event;
1829 io_init_event = rb_kqueue_init_event;
1830 io_supports_event = rb_kqueue_supports_event;
1831 rb_strlcpy(iotype, "kqueue", sizeof(iotype));
1832 return 0;
1833 }
1834 return -1;
1835 }
1836
1837 static int
1838 try_epoll(void)
1839 {
1840 if(!rb_init_netio_epoll())
1841 {
1842 setselect_handler = rb_setselect_epoll;
1843 select_handler = rb_select_epoll;
1844 setup_fd_handler = rb_setup_fd_epoll;
1845 io_sched_event = rb_epoll_sched_event;
1846 io_unsched_event = rb_epoll_unsched_event;
1847 io_supports_event = rb_epoll_supports_event;
1848 io_init_event = rb_epoll_init_event;
1849 rb_strlcpy(iotype, "epoll", sizeof(iotype));
1850 return 0;
1851 }
1852 return -1;
1853 }
1854
1855 static int
1856 try_ports(void)
1857 {
1858 if(!rb_init_netio_ports())
1859 {
1860 setselect_handler = rb_setselect_ports;
1861 select_handler = rb_select_ports;
1862 setup_fd_handler = rb_setup_fd_ports;
1863 io_sched_event = rb_ports_sched_event;
1864 io_unsched_event = rb_ports_unsched_event;
1865 io_init_event = rb_ports_init_event;
1866 io_supports_event = rb_ports_supports_event;
1867 rb_strlcpy(iotype, "ports", sizeof(iotype));
1868 return 0;
1869 }
1870 return -1;
1871 }
1872
1873 static int
1874 try_devpoll(void)
1875 {
1876 if(!rb_init_netio_devpoll())
1877 {
1878 setselect_handler = rb_setselect_devpoll;
1879 select_handler = rb_select_devpoll;
1880 setup_fd_handler = rb_setup_fd_devpoll;
1881 io_sched_event = NULL;
1882 io_unsched_event = NULL;
1883 io_init_event = NULL;
1884 io_supports_event = rb_unsupported_event;
1885 rb_strlcpy(iotype, "devpoll", sizeof(iotype));
1886 return 0;
1887 }
1888 return -1;
1889 }
1890
1891 static int
1892 try_sigio(void)
1893 {
1894 if(!rb_init_netio_sigio())
1895 {
1896 setselect_handler = rb_setselect_sigio;
1897 select_handler = rb_select_sigio;
1898 setup_fd_handler = rb_setup_fd_sigio;
1899 io_sched_event = rb_sigio_sched_event;
1900 io_unsched_event = rb_sigio_unsched_event;
1901 io_supports_event = rb_sigio_supports_event;
1902 io_init_event = rb_sigio_init_event;
1903
1904 rb_strlcpy(iotype, "sigio", sizeof(iotype));
1905 return 0;
1906 }
1907 return -1;
1908 }
1909
1910 static int
1911 try_poll(void)
1912 {
1913 if(!rb_init_netio_poll())
1914 {
1915 setselect_handler = rb_setselect_poll;
1916 select_handler = rb_select_poll;
1917 setup_fd_handler = rb_setup_fd_poll;
1918 io_sched_event = NULL;
1919 io_unsched_event = NULL;
1920 io_init_event = NULL;
1921 io_supports_event = rb_unsupported_event;
1922 rb_strlcpy(iotype, "poll", sizeof(iotype));
1923 return 0;
1924 }
1925 return -1;
1926 }
1927
1928 int
1929 rb_io_sched_event(struct ev_entry *ev, int when)
1930 {
1931 if(ev == NULL || io_supports_event == NULL || io_sched_event == NULL
1932 || !io_supports_event())
1933 return 0;
1934 return io_sched_event(ev, when);
1935 }
1936
1937 void
1938 rb_io_unsched_event(struct ev_entry *ev)
1939 {
1940 if(ev == NULL || io_supports_event == NULL || io_unsched_event == NULL
1941 || !io_supports_event())
1942 return;
1943 io_unsched_event(ev);
1944 }
1945
1946 int
1947 rb_io_supports_event(void)
1948 {
1949 if(io_supports_event == NULL)
1950 return 0;
1951 return io_supports_event();
1952 }
1953
1954 void
1955 rb_io_init_event(void)
1956 {
1957 io_init_event();
1958 rb_event_io_register_all();
1959 }
1960
1961 void
1962 rb_init_netio(void)
1963 {
1964 char *ioenv = getenv("LIBRB_USE_IOTYPE");
1965 rb_fd_table = rb_malloc(RB_FD_HASH_SIZE * sizeof(rb_dlink_list));
1966 rb_init_ssl();
1967
1968 if(ioenv != NULL)
1969 {
1970 if(!strcmp("epoll", ioenv))
1971 {
1972 if(!try_epoll())
1973 return;
1974 }
1975 else if(!strcmp("kqueue", ioenv))
1976 {
1977 if(!try_kqueue())
1978 return;
1979 }
1980 else if(!strcmp("ports", ioenv))
1981 {
1982 if(!try_ports())
1983 return;
1984 }
1985 else if(!strcmp("poll", ioenv))
1986 {
1987 if(!try_poll())
1988 return;
1989 }
1990 else if(!strcmp("devpoll", ioenv))
1991 {
1992 if(!try_devpoll())
1993 return;
1994 }
1995 else if(!strcmp("sigio", ioenv))
1996 {
1997 if(!try_sigio())
1998 return;
1999 }
2000 }
2001
2002 if(!try_kqueue())
2003 return;
2004 if(!try_epoll())
2005 return;
2006 if(!try_ports())
2007 return;
2008 if(!try_devpoll())
2009 return;
2010 if(!try_sigio())
2011 return;
2012 if(!try_poll())
2013 return;
2014
2015 rb_lib_log("rb_init_netio: Could not find any io handlers...giving up");
2016
2017 abort();
2018 }
2019
2020 void
2021 rb_setselect(rb_fde_t *F, unsigned int type, PF * handler, void *client_data)
2022 {
2023 setselect_handler(F, type, handler, client_data);
2024 }
2025
2026 void
2027 rb_defer(void (*fn)(void *), void *data)
2028 {
2029 struct defer *defer = rb_malloc(sizeof *defer);
2030 defer->fn = fn;
2031 defer->data = data;
2032 rb_dlinkAdd(defer, &defer->node, &defer_list);
2033 }
2034
2035 int
2036 rb_select(unsigned long timeout)
2037 {
2038 int ret = select_handler(timeout);
2039 rb_dlink_node *ptr, *next;
2040 RB_DLINK_FOREACH_SAFE(ptr, next, defer_list.head)
2041 {
2042 struct defer *defer = ptr->data;
2043 defer->fn(defer->data);
2044 rb_dlinkDelete(ptr, &defer_list);
2045 rb_free(defer);
2046 }
2047 rb_close_pending_fds();
2048 return ret;
2049 }
2050
2051 int
2052 rb_setup_fd(rb_fde_t *F)
2053 {
2054 rb_set_cloexec(F);
2055 return setup_fd_handler(F);
2056 }
2057
2058
2059 int
2060 rb_ignore_errno(int error)
2061 {
2062 switch (error)
2063 {
2064 #ifdef EINPROGRESS
2065 case EINPROGRESS:
2066 #endif
2067 #if defined EWOULDBLOCK
2068 case EWOULDBLOCK:
2069 #endif
2070 #if defined(EAGAIN) && (EWOULDBLOCK != EAGAIN)
2071 case EAGAIN:
2072 #endif
2073 #ifdef EINTR
2074 case EINTR:
2075 #endif
2076 #ifdef ERESTART
2077 case ERESTART:
2078 #endif
2079 #ifdef ENOBUFS
2080 case ENOBUFS:
2081 #endif
2082 return 1;
2083 default:
2084 break;
2085 }
2086 return 0;
2087 }
2088
2089
2090 int
2091 rb_recv_fd_buf(rb_fde_t *F, void *data, size_t datasize, rb_fde_t **xF, int nfds)
2092 {
2093 struct msghdr msg;
2094 struct cmsghdr *cmsg;
2095 struct iovec iov[1];
2096 struct stat st;
2097 uint8_t stype = RB_FD_UNKNOWN;
2098 const char *desc;
2099 int fd, len, x, rfds;
2100
2101 int control_len = CMSG_SPACE(sizeof(int) * nfds);
2102
2103 iov[0].iov_base = data;
2104 iov[0].iov_len = datasize;
2105
2106 msg.msg_name = NULL;
2107 msg.msg_namelen = 0;
2108 msg.msg_iov = iov;
2109 msg.msg_iovlen = 1;
2110 msg.msg_flags = 0;
2111 cmsg = alloca(control_len);
2112 msg.msg_control = cmsg;
2113 msg.msg_controllen = control_len;
2114
2115 if((len = recvmsg(rb_get_fd(F), &msg, 0)) <= 0)
2116 return len;
2117
2118 if(msg.msg_controllen > 0 && msg.msg_control != NULL
2119 && (cmsg = CMSG_FIRSTHDR(&msg)) != NULL)
2120 {
2121 rfds = ((unsigned char *)cmsg + cmsg->cmsg_len - CMSG_DATA(cmsg)) / sizeof(int);
2122
2123 for(x = 0; x < nfds && x < rfds; x++)
2124 {
2125 fd = ((int *)CMSG_DATA(cmsg))[x];
2126 stype = RB_FD_UNKNOWN;
2127 desc = "remote unknown";
2128 if(!fstat(fd, &st))
2129 {
2130 if(S_ISSOCK(st.st_mode))
2131 {
2132 stype = RB_FD_SOCKET;
2133 desc = "remote socket";
2134 }
2135 else if(S_ISFIFO(st.st_mode))
2136 {
2137 stype = RB_FD_PIPE;
2138 desc = "remote pipe";
2139 }
2140 else if(S_ISREG(st.st_mode))
2141 {
2142 stype = RB_FD_FILE;
2143 desc = "remote file";
2144 }
2145 }
2146 xF[x] = rb_open(fd, stype, desc);
2147 }
2148 }
2149 else
2150 *xF = NULL;
2151 return len;
2152 }
2153
2154
2155 int
2156 rb_send_fd_buf(rb_fde_t *xF, rb_fde_t **F, int count, void *data, size_t datasize, pid_t pid __attribute__((unused)))
2157 {
2158 struct msghdr msg;
2159 struct cmsghdr *cmsg;
2160 struct iovec iov[1];
2161 char empty = '0';
2162
2163 memset(&msg, 0, sizeof(msg));
2164 if(datasize == 0)
2165 {
2166 iov[0].iov_base = &empty;
2167 iov[0].iov_len = 1;
2168 }
2169 else
2170 {
2171 iov[0].iov_base = data;
2172 iov[0].iov_len = datasize;
2173 }
2174 msg.msg_iov = iov;
2175 msg.msg_iovlen = 1;
2176 msg.msg_name = NULL;
2177 msg.msg_namelen = 0;
2178 msg.msg_flags = 0;
2179 msg.msg_control = NULL;
2180 msg.msg_controllen = 0;
2181
2182 if(count > 0)
2183 {
2184 size_t ucount = (size_t)count;
2185 int len = CMSG_SPACE(sizeof(int) * count);
2186 char buf[len];
2187
2188 msg.msg_control = buf;
2189 msg.msg_controllen = len;
2190 cmsg = CMSG_FIRSTHDR(&msg);
2191 cmsg->cmsg_level = SOL_SOCKET;
2192 cmsg->cmsg_type = SCM_RIGHTS;
2193 cmsg->cmsg_len = CMSG_LEN(sizeof(int) * count);
2194
2195 for(size_t i = 0; i < ucount; i++)
2196 {
2197 ((int *)CMSG_DATA(cmsg))[i] = rb_get_fd(F[i]);
2198 }
2199 msg.msg_controllen = cmsg->cmsg_len;
2200 return sendmsg(rb_get_fd(xF), &msg, MSG_NOSIGNAL);
2201 }
2202 return sendmsg(rb_get_fd(xF), &msg, MSG_NOSIGNAL);
2203 }
2204
2205 int
2206 rb_ipv4_from_ipv6(const struct sockaddr_in6 *restrict ip6, struct sockaddr_in *restrict ip4)
2207 {
2208 int i;
2209
2210 if (!memcmp(ip6->sin6_addr.s6_addr, "\x20\x02", 2))
2211 {
2212 /* 6to4 and similar */
2213 memcpy(&ip4->sin_addr, ip6->sin6_addr.s6_addr + 2, 4);
2214 }
2215 else if (!memcmp(ip6->sin6_addr.s6_addr, "\x20\x01\x00\x00", 4))
2216 {
2217 /* Teredo */
2218 for (i = 0; i < 4; i++)
2219 ((uint8_t *)&ip4->sin_addr)[i] = 0xFF ^
2220 ip6->sin6_addr.s6_addr[12 + i];
2221 }
2222 else
2223 return 0;
2224 SET_SS_LEN(ip4, sizeof(struct sockaddr_in));
2225 ip4->sin_family = AF_INET;
2226 ip4->sin_port = 0;
2227 return 1;
2228 }