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