]> git.ipfire.org Git - thirdparty/bird.git/blob - sysdep/unix/io.c
Merge branch 'master' into int-new
[thirdparty/bird.git] / sysdep / unix / io.c
1 /*
2 * BIRD Internet Routing Daemon -- Unix I/O
3 *
4 * (c) 1998--2004 Martin Mares <mj@ucw.cz>
5 * (c) 2004 Ondrej Filip <feela@network.cz>
6 *
7 * Can be freely distributed and used under the terms of the GNU GPL.
8 */
9
10 /* Unfortunately, some glibc versions hide parts of RFC 3542 API
11 if _GNU_SOURCE is not defined. */
12 #ifndef _GNU_SOURCE
13 #define _GNU_SOURCE
14 #endif
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <time.h>
19 #include <sys/time.h>
20 #include <sys/types.h>
21 #include <sys/socket.h>
22 #include <sys/uio.h>
23 #include <sys/un.h>
24 #include <poll.h>
25 #include <unistd.h>
26 #include <fcntl.h>
27 #include <errno.h>
28 #include <net/if.h>
29 #include <netinet/in.h>
30 #include <netinet/tcp.h>
31 #include <netinet/udp.h>
32 #include <netinet/icmp6.h>
33
34 #include "nest/bird.h"
35 #include "lib/lists.h"
36 #include "lib/resource.h"
37 #include "lib/socket.h"
38 #include "lib/event.h"
39 #include "lib/timer.h"
40 #include "lib/string.h"
41 #include "nest/iface.h"
42 #include "conf/conf.h"
43
44 #include "sysdep/unix/unix.h"
45 #include CONFIG_INCLUDE_SYSIO_H
46
47 /* Maximum number of calls of tx handler for one socket in one
48 * poll iteration. Should be small enough to not monopolize CPU by
49 * one protocol instance.
50 */
51 #define MAX_STEPS 4
52
53 /* Maximum number of calls of rx handler for all sockets in one poll
54 iteration. RX callbacks are often much more costly so we limit
55 this to gen small latencies */
56 #define MAX_RX_STEPS 4
57
58 /*
59 * Tracked Files
60 */
61
62 struct rfile {
63 resource r;
64 FILE *f;
65 };
66
67 static void
68 rf_free(resource *r)
69 {
70 struct rfile *a = (struct rfile *) r;
71
72 fclose(a->f);
73 }
74
75 static void
76 rf_dump(resource *r)
77 {
78 struct rfile *a = (struct rfile *) r;
79
80 debug("(FILE *%p)\n", a->f);
81 }
82
83 static struct resclass rf_class = {
84 "FILE",
85 sizeof(struct rfile),
86 rf_free,
87 rf_dump,
88 NULL,
89 NULL
90 };
91
92 void *
93 tracked_fopen(pool *p, char *name, char *mode)
94 {
95 FILE *f = fopen(name, mode);
96
97 if (f)
98 {
99 struct rfile *r = ralloc(p, &rf_class);
100 r->f = f;
101 }
102 return f;
103 }
104
105
106 /*
107 * Time clock
108 */
109
110 btime boot_time;
111
112 void
113 times_init(struct timeloop *loop)
114 {
115 struct timespec ts;
116 int rv;
117
118 rv = clock_gettime(CLOCK_MONOTONIC, &ts);
119 if (rv < 0)
120 die("Monotonic clock is missing");
121
122 if ((ts.tv_sec < 0) || (((s64) ts.tv_sec) > ((s64) 1 << 40)))
123 log(L_WARN "Monotonic clock is crazy");
124
125 loop->last_time = ts.tv_sec S + ts.tv_nsec NS;
126 loop->real_time = 0;
127 }
128
129 void
130 times_update(struct timeloop *loop)
131 {
132 struct timespec ts;
133 int rv;
134
135 rv = clock_gettime(CLOCK_MONOTONIC, &ts);
136 if (rv < 0)
137 die("clock_gettime: %m");
138
139 btime new_time = ts.tv_sec S + ts.tv_nsec NS;
140
141 if (new_time < loop->last_time)
142 log(L_ERR "Monotonic clock is broken");
143
144 loop->last_time = new_time;
145 loop->real_time = 0;
146 }
147
148 void
149 times_update_real_time(struct timeloop *loop)
150 {
151 struct timespec ts;
152 int rv;
153
154 rv = clock_gettime(CLOCK_REALTIME, &ts);
155 if (rv < 0)
156 die("clock_gettime: %m");
157
158 loop->real_time = ts.tv_sec S + ts.tv_nsec NS;
159 }
160
161
162 /**
163 * DOC: Sockets
164 *
165 * Socket resources represent network connections. Their data structure (&socket)
166 * contains a lot of fields defining the exact type of the socket, the local and
167 * remote addresses and ports, pointers to socket buffers and finally pointers to
168 * hook functions to be called when new data have arrived to the receive buffer
169 * (@rx_hook), when the contents of the transmit buffer have been transmitted
170 * (@tx_hook) and when an error or connection close occurs (@err_hook).
171 *
172 * Freeing of sockets from inside socket hooks is perfectly safe.
173 */
174
175 #ifndef SOL_IP
176 #define SOL_IP IPPROTO_IP
177 #endif
178
179 #ifndef SOL_IPV6
180 #define SOL_IPV6 IPPROTO_IPV6
181 #endif
182
183 #ifndef SOL_ICMPV6
184 #define SOL_ICMPV6 IPPROTO_ICMPV6
185 #endif
186
187
188 /*
189 * Sockaddr helper functions
190 */
191
192 static inline int UNUSED sockaddr_length(int af)
193 { return (af == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6); }
194
195 static inline void
196 sockaddr_fill4(struct sockaddr_in *sa, ip_addr a, uint port)
197 {
198 memset(sa, 0, sizeof(struct sockaddr_in));
199 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
200 sa->sin_len = sizeof(struct sockaddr_in);
201 #endif
202 sa->sin_family = AF_INET;
203 sa->sin_port = htons(port);
204 sa->sin_addr = ipa_to_in4(a);
205 }
206
207 static inline void
208 sockaddr_fill6(struct sockaddr_in6 *sa, ip_addr a, struct iface *ifa, uint port)
209 {
210 memset(sa, 0, sizeof(struct sockaddr_in6));
211 #ifdef SIN6_LEN
212 sa->sin6_len = sizeof(struct sockaddr_in6);
213 #endif
214 sa->sin6_family = AF_INET6;
215 sa->sin6_port = htons(port);
216 sa->sin6_flowinfo = 0;
217 sa->sin6_addr = ipa_to_in6(a);
218
219 if (ifa && ipa_is_link_local(a))
220 sa->sin6_scope_id = ifa->index;
221 }
222
223 void
224 sockaddr_fill(sockaddr *sa, int af, ip_addr a, struct iface *ifa, uint port)
225 {
226 if (af == AF_INET)
227 sockaddr_fill4((struct sockaddr_in *) sa, a, port);
228 else if (af == AF_INET6)
229 sockaddr_fill6((struct sockaddr_in6 *) sa, a, ifa, port);
230 else
231 bug("Unknown AF");
232 }
233
234 static inline void
235 sockaddr_read4(struct sockaddr_in *sa, ip_addr *a, uint *port)
236 {
237 *port = ntohs(sa->sin_port);
238 *a = ipa_from_in4(sa->sin_addr);
239 }
240
241 static inline void
242 sockaddr_read6(struct sockaddr_in6 *sa, ip_addr *a, struct iface **ifa, uint *port)
243 {
244 *port = ntohs(sa->sin6_port);
245 *a = ipa_from_in6(sa->sin6_addr);
246
247 if (ifa && ipa_is_link_local(*a))
248 *ifa = if_find_by_index(sa->sin6_scope_id);
249 }
250
251 int
252 sockaddr_read(sockaddr *sa, int af, ip_addr *a, struct iface **ifa, uint *port)
253 {
254 if (sa->sa.sa_family != af)
255 goto fail;
256
257 if (af == AF_INET)
258 sockaddr_read4((struct sockaddr_in *) sa, a, port);
259 else if (af == AF_INET6)
260 sockaddr_read6((struct sockaddr_in6 *) sa, a, ifa, port);
261 else
262 goto fail;
263
264 return 0;
265
266 fail:
267 *a = IPA_NONE;
268 *port = 0;
269 return -1;
270 }
271
272
273 /*
274 * IPv6 multicast syscalls
275 */
276
277 /* Fortunately standardized in RFC 3493 */
278
279 #define INIT_MREQ6(maddr,ifa) \
280 { .ipv6mr_multiaddr = ipa_to_in6(maddr), .ipv6mr_interface = ifa->index }
281
282 static inline int
283 sk_setup_multicast6(sock *s)
284 {
285 int index = s->iface->index;
286 int ttl = s->ttl;
287 int n = 0;
288
289 if (setsockopt(s->fd, SOL_IPV6, IPV6_MULTICAST_IF, &index, sizeof(index)) < 0)
290 ERR("IPV6_MULTICAST_IF");
291
292 if (setsockopt(s->fd, SOL_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl)) < 0)
293 ERR("IPV6_MULTICAST_HOPS");
294
295 if (setsockopt(s->fd, SOL_IPV6, IPV6_MULTICAST_LOOP, &n, sizeof(n)) < 0)
296 ERR("IPV6_MULTICAST_LOOP");
297
298 return 0;
299 }
300
301 static inline int
302 sk_join_group6(sock *s, ip_addr maddr)
303 {
304 struct ipv6_mreq mr = INIT_MREQ6(maddr, s->iface);
305
306 if (setsockopt(s->fd, SOL_IPV6, IPV6_JOIN_GROUP, &mr, sizeof(mr)) < 0)
307 ERR("IPV6_JOIN_GROUP");
308
309 return 0;
310 }
311
312 static inline int
313 sk_leave_group6(sock *s, ip_addr maddr)
314 {
315 struct ipv6_mreq mr = INIT_MREQ6(maddr, s->iface);
316
317 if (setsockopt(s->fd, SOL_IPV6, IPV6_LEAVE_GROUP, &mr, sizeof(mr)) < 0)
318 ERR("IPV6_LEAVE_GROUP");
319
320 return 0;
321 }
322
323
324 /*
325 * IPv6 packet control messages
326 */
327
328 /* Also standardized, in RFC 3542 */
329
330 /*
331 * RFC 2292 uses IPV6_PKTINFO for both the socket option and the cmsg
332 * type, RFC 3542 changed the socket option to IPV6_RECVPKTINFO. If we
333 * don't have IPV6_RECVPKTINFO we suppose the OS implements the older
334 * RFC and we use IPV6_PKTINFO.
335 */
336 #ifndef IPV6_RECVPKTINFO
337 #define IPV6_RECVPKTINFO IPV6_PKTINFO
338 #endif
339 /*
340 * Same goes for IPV6_HOPLIMIT -> IPV6_RECVHOPLIMIT.
341 */
342 #ifndef IPV6_RECVHOPLIMIT
343 #define IPV6_RECVHOPLIMIT IPV6_HOPLIMIT
344 #endif
345
346
347 #define CMSG6_SPACE_PKTINFO CMSG_SPACE(sizeof(struct in6_pktinfo))
348 #define CMSG6_SPACE_TTL CMSG_SPACE(sizeof(int))
349
350 static inline int
351 sk_request_cmsg6_pktinfo(sock *s)
352 {
353 int y = 1;
354
355 if (setsockopt(s->fd, SOL_IPV6, IPV6_RECVPKTINFO, &y, sizeof(y)) < 0)
356 ERR("IPV6_RECVPKTINFO");
357
358 return 0;
359 }
360
361 static inline int
362 sk_request_cmsg6_ttl(sock *s)
363 {
364 int y = 1;
365
366 if (setsockopt(s->fd, SOL_IPV6, IPV6_RECVHOPLIMIT, &y, sizeof(y)) < 0)
367 ERR("IPV6_RECVHOPLIMIT");
368
369 return 0;
370 }
371
372 static inline void
373 sk_process_cmsg6_pktinfo(sock *s, struct cmsghdr *cm)
374 {
375 if (cm->cmsg_type == IPV6_PKTINFO)
376 {
377 struct in6_pktinfo *pi = (struct in6_pktinfo *) CMSG_DATA(cm);
378 s->laddr = ipa_from_in6(pi->ipi6_addr);
379 s->lifindex = pi->ipi6_ifindex;
380 }
381 }
382
383 static inline void
384 sk_process_cmsg6_ttl(sock *s, struct cmsghdr *cm)
385 {
386 if (cm->cmsg_type == IPV6_HOPLIMIT)
387 s->rcv_ttl = * (int *) CMSG_DATA(cm);
388 }
389
390 static inline void
391 sk_prepare_cmsgs6(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
392 {
393 struct cmsghdr *cm;
394 struct in6_pktinfo *pi;
395 int controllen = 0;
396
397 msg->msg_control = cbuf;
398 msg->msg_controllen = cbuflen;
399
400 cm = CMSG_FIRSTHDR(msg);
401 cm->cmsg_level = SOL_IPV6;
402 cm->cmsg_type = IPV6_PKTINFO;
403 cm->cmsg_len = CMSG_LEN(sizeof(*pi));
404 controllen += CMSG_SPACE(sizeof(*pi));
405
406 pi = (struct in6_pktinfo *) CMSG_DATA(cm);
407 pi->ipi6_ifindex = s->iface ? s->iface->index : 0;
408 pi->ipi6_addr = ipa_to_in6(s->saddr);
409
410 msg->msg_controllen = controllen;
411 }
412
413
414 /*
415 * Miscellaneous socket syscalls
416 */
417
418 static inline int
419 sk_set_ttl4(sock *s, int ttl)
420 {
421 if (setsockopt(s->fd, SOL_IP, IP_TTL, &ttl, sizeof(ttl)) < 0)
422 ERR("IP_TTL");
423
424 return 0;
425 }
426
427 static inline int
428 sk_set_ttl6(sock *s, int ttl)
429 {
430 if (setsockopt(s->fd, SOL_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl)) < 0)
431 ERR("IPV6_UNICAST_HOPS");
432
433 return 0;
434 }
435
436 static inline int
437 sk_set_tos4(sock *s, int tos)
438 {
439 if (setsockopt(s->fd, SOL_IP, IP_TOS, &tos, sizeof(tos)) < 0)
440 ERR("IP_TOS");
441
442 return 0;
443 }
444
445 static inline int
446 sk_set_tos6(sock *s, int tos)
447 {
448 if (setsockopt(s->fd, SOL_IPV6, IPV6_TCLASS, &tos, sizeof(tos)) < 0)
449 ERR("IPV6_TCLASS");
450
451 return 0;
452 }
453
454 static inline int
455 sk_set_high_port(sock *s UNUSED)
456 {
457 /* Port range setting is optional, ignore it if not supported */
458
459 #ifdef IP_PORTRANGE
460 if (sk_is_ipv4(s))
461 {
462 int range = IP_PORTRANGE_HIGH;
463 if (setsockopt(s->fd, SOL_IP, IP_PORTRANGE, &range, sizeof(range)) < 0)
464 ERR("IP_PORTRANGE");
465 }
466 #endif
467
468 #ifdef IPV6_PORTRANGE
469 if (sk_is_ipv6(s))
470 {
471 int range = IPV6_PORTRANGE_HIGH;
472 if (setsockopt(s->fd, SOL_IPV6, IPV6_PORTRANGE, &range, sizeof(range)) < 0)
473 ERR("IPV6_PORTRANGE");
474 }
475 #endif
476
477 return 0;
478 }
479
480 static inline byte *
481 sk_skip_ip_header(byte *pkt, int *len)
482 {
483 if ((*len < 20) || ((*pkt & 0xf0) != 0x40))
484 return NULL;
485
486 int hlen = (*pkt & 0x0f) * 4;
487 if ((hlen < 20) || (hlen > *len))
488 return NULL;
489
490 *len -= hlen;
491 return pkt + hlen;
492 }
493
494 byte *
495 sk_rx_buffer(sock *s, int *len)
496 {
497 if (sk_is_ipv4(s) && (s->type == SK_IP))
498 return sk_skip_ip_header(s->rbuf, len);
499 else
500 return s->rbuf;
501 }
502
503
504 /*
505 * Public socket functions
506 */
507
508 /**
509 * sk_setup_multicast - enable multicast for given socket
510 * @s: socket
511 *
512 * Prepare transmission of multicast packets for given datagram socket.
513 * The socket must have defined @iface.
514 *
515 * Result: 0 for success, -1 for an error.
516 */
517
518 int
519 sk_setup_multicast(sock *s)
520 {
521 ASSERT(s->iface);
522
523 if (sk_is_ipv4(s))
524 return sk_setup_multicast4(s);
525 else
526 return sk_setup_multicast6(s);
527 }
528
529 /**
530 * sk_join_group - join multicast group for given socket
531 * @s: socket
532 * @maddr: multicast address
533 *
534 * Join multicast group for given datagram socket and associated interface.
535 * The socket must have defined @iface.
536 *
537 * Result: 0 for success, -1 for an error.
538 */
539
540 int
541 sk_join_group(sock *s, ip_addr maddr)
542 {
543 if (sk_is_ipv4(s))
544 return sk_join_group4(s, maddr);
545 else
546 return sk_join_group6(s, maddr);
547 }
548
549 /**
550 * sk_leave_group - leave multicast group for given socket
551 * @s: socket
552 * @maddr: multicast address
553 *
554 * Leave multicast group for given datagram socket and associated interface.
555 * The socket must have defined @iface.
556 *
557 * Result: 0 for success, -1 for an error.
558 */
559
560 int
561 sk_leave_group(sock *s, ip_addr maddr)
562 {
563 if (sk_is_ipv4(s))
564 return sk_leave_group4(s, maddr);
565 else
566 return sk_leave_group6(s, maddr);
567 }
568
569 /**
570 * sk_setup_broadcast - enable broadcast for given socket
571 * @s: socket
572 *
573 * Allow reception and transmission of broadcast packets for given datagram
574 * socket. The socket must have defined @iface. For transmission, packets should
575 * be send to @brd address of @iface.
576 *
577 * Result: 0 for success, -1 for an error.
578 */
579
580 int
581 sk_setup_broadcast(sock *s)
582 {
583 int y = 1;
584
585 if (setsockopt(s->fd, SOL_SOCKET, SO_BROADCAST, &y, sizeof(y)) < 0)
586 ERR("SO_BROADCAST");
587
588 return 0;
589 }
590
591 /**
592 * sk_set_ttl - set transmit TTL for given socket
593 * @s: socket
594 * @ttl: TTL value
595 *
596 * Set TTL for already opened connections when TTL was not set before. Useful
597 * for accepted connections when different ones should have different TTL.
598 *
599 * Result: 0 for success, -1 for an error.
600 */
601
602 int
603 sk_set_ttl(sock *s, int ttl)
604 {
605 s->ttl = ttl;
606
607 if (sk_is_ipv4(s))
608 return sk_set_ttl4(s, ttl);
609 else
610 return sk_set_ttl6(s, ttl);
611 }
612
613 /**
614 * sk_set_min_ttl - set minimal accepted TTL for given socket
615 * @s: socket
616 * @ttl: TTL value
617 *
618 * Set minimal accepted TTL for given socket. Can be used for TTL security.
619 * implementations.
620 *
621 * Result: 0 for success, -1 for an error.
622 */
623
624 int
625 sk_set_min_ttl(sock *s, int ttl)
626 {
627 if (sk_is_ipv4(s))
628 return sk_set_min_ttl4(s, ttl);
629 else
630 return sk_set_min_ttl6(s, ttl);
631 }
632
633 #if 0
634 /**
635 * sk_set_md5_auth - add / remove MD5 security association for given socket
636 * @s: socket
637 * @local: IP address of local side
638 * @remote: IP address of remote side
639 * @ifa: Interface for link-local IP address
640 * @passwd: Password used for MD5 authentication
641 * @setkey: Update also system SA/SP database
642 *
643 * In TCP MD5 handling code in kernel, there is a set of security associations
644 * used for choosing password and other authentication parameters according to
645 * the local and remote address. This function is useful for listening socket,
646 * for active sockets it may be enough to set s->password field.
647 *
648 * When called with passwd != NULL, the new pair is added,
649 * When called with passwd == NULL, the existing pair is removed.
650 *
651 * Note that while in Linux, the MD5 SAs are specific to socket, in BSD they are
652 * stored in global SA/SP database (but the behavior also must be enabled on
653 * per-socket basis). In case of multiple sockets to the same neighbor, the
654 * socket-specific state must be configured for each socket while global state
655 * just once per src-dst pair. The @setkey argument controls whether the global
656 * state (SA/SP database) is also updated.
657 *
658 * Result: 0 for success, -1 for an error.
659 */
660
661 int
662 sk_set_md5_auth(sock *s, ip_addr local, ip_addr remote, struct iface *ifa, char *passwd, int setkey)
663 { DUMMY; }
664 #endif
665
666 /**
667 * sk_set_ipv6_checksum - specify IPv6 checksum offset for given socket
668 * @s: socket
669 * @offset: offset
670 *
671 * Specify IPv6 checksum field offset for given raw IPv6 socket. After that, the
672 * kernel will automatically fill it for outgoing packets and check it for
673 * incoming packets. Should not be used on ICMPv6 sockets, where the position is
674 * known to the kernel.
675 *
676 * Result: 0 for success, -1 for an error.
677 */
678
679 int
680 sk_set_ipv6_checksum(sock *s, int offset)
681 {
682 if (setsockopt(s->fd, SOL_IPV6, IPV6_CHECKSUM, &offset, sizeof(offset)) < 0)
683 ERR("IPV6_CHECKSUM");
684
685 return 0;
686 }
687
688 int
689 sk_set_icmp6_filter(sock *s, int p1, int p2)
690 {
691 /* a bit of lame interface, but it is here only for Radv */
692 struct icmp6_filter f;
693
694 ICMP6_FILTER_SETBLOCKALL(&f);
695 ICMP6_FILTER_SETPASS(p1, &f);
696 ICMP6_FILTER_SETPASS(p2, &f);
697
698 if (setsockopt(s->fd, SOL_ICMPV6, ICMP6_FILTER, &f, sizeof(f)) < 0)
699 ERR("ICMP6_FILTER");
700
701 return 0;
702 }
703
704 void
705 sk_log_error(sock *s, const char *p)
706 {
707 log(L_ERR "%s: Socket error: %s%#m", p, s->err);
708 }
709
710
711 /*
712 * Actual struct birdsock code
713 */
714
715 static list sock_list;
716 static struct birdsock *current_sock;
717 static struct birdsock *stored_sock;
718
719 static inline sock *
720 sk_next(sock *s)
721 {
722 if (!s->n.next->next)
723 return NULL;
724 else
725 return SKIP_BACK(sock, n, s->n.next);
726 }
727
728 static void
729 sk_alloc_bufs(sock *s)
730 {
731 if (!s->rbuf && s->rbsize)
732 s->rbuf = s->rbuf_alloc = xmalloc(s->rbsize);
733 s->rpos = s->rbuf;
734 if (!s->tbuf && s->tbsize)
735 s->tbuf = s->tbuf_alloc = xmalloc(s->tbsize);
736 s->tpos = s->ttx = s->tbuf;
737 }
738
739 static void
740 sk_free_bufs(sock *s)
741 {
742 if (s->rbuf_alloc)
743 {
744 xfree(s->rbuf_alloc);
745 s->rbuf = s->rbuf_alloc = NULL;
746 }
747 if (s->tbuf_alloc)
748 {
749 xfree(s->tbuf_alloc);
750 s->tbuf = s->tbuf_alloc = NULL;
751 }
752 }
753
754 #ifdef HAVE_LIBSSH
755 static void
756 sk_ssh_free(sock *s)
757 {
758 struct ssh_sock *ssh = s->ssh;
759
760 if (s->ssh == NULL)
761 return;
762
763 s->ssh = NULL;
764
765 if (ssh->channel)
766 {
767 if (ssh_channel_is_open(ssh->channel))
768 ssh_channel_close(ssh->channel);
769 ssh_channel_free(ssh->channel);
770 ssh->channel = NULL;
771 }
772
773 if (ssh->session)
774 {
775 ssh_disconnect(ssh->session);
776 ssh_free(ssh->session);
777 ssh->session = NULL;
778 }
779 }
780 #endif
781
782 static void
783 sk_free(resource *r)
784 {
785 sock *s = (sock *) r;
786
787 sk_free_bufs(s);
788
789 #ifdef HAVE_LIBSSH
790 if (s->type == SK_SSH || s->type == SK_SSH_ACTIVE)
791 sk_ssh_free(s);
792 #endif
793
794 if (s->fd < 0)
795 return;
796
797 /* FIXME: we should call sk_stop() for SKF_THREAD sockets */
798 if (!(s->flags & SKF_THREAD))
799 {
800 if (s == current_sock)
801 current_sock = sk_next(s);
802 if (s == stored_sock)
803 stored_sock = sk_next(s);
804 rem_node(&s->n);
805 }
806
807 if (s->type != SK_SSH && s->type != SK_SSH_ACTIVE)
808 close(s->fd);
809
810 s->fd = -1;
811 }
812
813 void
814 sk_set_rbsize(sock *s, uint val)
815 {
816 ASSERT(s->rbuf_alloc == s->rbuf);
817
818 if (s->rbsize == val)
819 return;
820
821 s->rbsize = val;
822 xfree(s->rbuf_alloc);
823 s->rbuf_alloc = xmalloc(val);
824 s->rpos = s->rbuf = s->rbuf_alloc;
825 }
826
827 void
828 sk_set_tbsize(sock *s, uint val)
829 {
830 ASSERT(s->tbuf_alloc == s->tbuf);
831
832 if (s->tbsize == val)
833 return;
834
835 byte *old_tbuf = s->tbuf;
836
837 s->tbsize = val;
838 s->tbuf = s->tbuf_alloc = xrealloc(s->tbuf_alloc, val);
839 s->tpos = s->tbuf + (s->tpos - old_tbuf);
840 s->ttx = s->tbuf + (s->ttx - old_tbuf);
841 }
842
843 void
844 sk_set_tbuf(sock *s, void *tbuf)
845 {
846 s->tbuf = tbuf ?: s->tbuf_alloc;
847 s->ttx = s->tpos = s->tbuf;
848 }
849
850 void
851 sk_reallocate(sock *s)
852 {
853 sk_free_bufs(s);
854 sk_alloc_bufs(s);
855 }
856
857 static void
858 sk_dump(resource *r)
859 {
860 sock *s = (sock *) r;
861 static char *sk_type_names[] = { "TCP<", "TCP>", "TCP", "UDP", NULL, "IP", NULL, "MAGIC", "UNIX<", "UNIX", "SSH>", "SSH", "DEL!" };
862
863 debug("(%s, ud=%p, sa=%I, sp=%d, da=%I, dp=%d, tos=%d, ttl=%d, if=%s)\n",
864 sk_type_names[s->type],
865 s->data,
866 s->saddr,
867 s->sport,
868 s->daddr,
869 s->dport,
870 s->tos,
871 s->ttl,
872 s->iface ? s->iface->name : "none");
873 }
874
875 static struct resclass sk_class = {
876 "Socket",
877 sizeof(sock),
878 sk_free,
879 sk_dump,
880 NULL,
881 NULL
882 };
883
884 /**
885 * sk_new - create a socket
886 * @p: pool
887 *
888 * This function creates a new socket resource. If you want to use it,
889 * you need to fill in all the required fields of the structure and
890 * call sk_open() to do the actual opening of the socket.
891 *
892 * The real function name is sock_new(), sk_new() is a macro wrapper
893 * to avoid collision with OpenSSL.
894 */
895 sock *
896 sock_new(pool *p)
897 {
898 sock *s = ralloc(p, &sk_class);
899 s->pool = p;
900 // s->saddr = s->daddr = IPA_NONE;
901 s->tos = s->priority = s->ttl = -1;
902 s->fd = -1;
903 return s;
904 }
905
906 static int
907 sk_setup(sock *s)
908 {
909 int y = 1;
910 int fd = s->fd;
911
912 if (s->type == SK_SSH_ACTIVE)
913 return 0;
914
915 if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
916 ERR("O_NONBLOCK");
917
918 if (!s->af)
919 return 0;
920
921 if (ipa_nonzero(s->saddr) && !(s->flags & SKF_BIND))
922 s->flags |= SKF_PKTINFO;
923
924 #ifdef CONFIG_USE_HDRINCL
925 if (sk_is_ipv4(s) && (s->type == SK_IP) && (s->flags & SKF_PKTINFO))
926 {
927 s->flags &= ~SKF_PKTINFO;
928 s->flags |= SKF_HDRINCL;
929 if (setsockopt(fd, SOL_IP, IP_HDRINCL, &y, sizeof(y)) < 0)
930 ERR("IP_HDRINCL");
931 }
932 #endif
933
934 if (s->vrf && !s->iface)
935 {
936 /* Bind socket to associated VRF interface.
937 This is Linux-specific, but so is SO_BINDTODEVICE. */
938 #ifdef SO_BINDTODEVICE
939 struct ifreq ifr = {};
940 strcpy(ifr.ifr_name, s->vrf->name);
941 if (setsockopt(s->fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) < 0)
942 ERR("SO_BINDTODEVICE");
943 #endif
944 }
945
946 if (s->iface)
947 {
948 #ifdef SO_BINDTODEVICE
949 struct ifreq ifr = {};
950 strcpy(ifr.ifr_name, s->iface->name);
951 if (setsockopt(s->fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) < 0)
952 ERR("SO_BINDTODEVICE");
953 #endif
954
955 #ifdef CONFIG_UNIX_DONTROUTE
956 if (setsockopt(s->fd, SOL_SOCKET, SO_DONTROUTE, &y, sizeof(y)) < 0)
957 ERR("SO_DONTROUTE");
958 #endif
959 }
960
961 if (sk_is_ipv4(s))
962 {
963 if (s->flags & SKF_LADDR_RX)
964 if (sk_request_cmsg4_pktinfo(s) < 0)
965 return -1;
966
967 if (s->flags & SKF_TTL_RX)
968 if (sk_request_cmsg4_ttl(s) < 0)
969 return -1;
970
971 if ((s->type == SK_UDP) || (s->type == SK_IP))
972 if (sk_disable_mtu_disc4(s) < 0)
973 return -1;
974
975 if (s->ttl >= 0)
976 if (sk_set_ttl4(s, s->ttl) < 0)
977 return -1;
978
979 if (s->tos >= 0)
980 if (sk_set_tos4(s, s->tos) < 0)
981 return -1;
982 }
983
984 if (sk_is_ipv6(s))
985 {
986 if ((s->type == SK_TCP_PASSIVE) || (s->type == SK_TCP_ACTIVE) || (s->type == SK_UDP))
987 if (setsockopt(fd, SOL_IPV6, IPV6_V6ONLY, &y, sizeof(y)) < 0)
988 ERR("IPV6_V6ONLY");
989
990 if (s->flags & SKF_LADDR_RX)
991 if (sk_request_cmsg6_pktinfo(s) < 0)
992 return -1;
993
994 if (s->flags & SKF_TTL_RX)
995 if (sk_request_cmsg6_ttl(s) < 0)
996 return -1;
997
998 if ((s->type == SK_UDP) || (s->type == SK_IP))
999 if (sk_disable_mtu_disc6(s) < 0)
1000 return -1;
1001
1002 if (s->ttl >= 0)
1003 if (sk_set_ttl6(s, s->ttl) < 0)
1004 return -1;
1005
1006 if (s->tos >= 0)
1007 if (sk_set_tos6(s, s->tos) < 0)
1008 return -1;
1009 }
1010
1011 /* Must be after sk_set_tos4() as setting ToS on Linux also mangles priority */
1012 if (s->priority >= 0)
1013 if (sk_set_priority(s, s->priority) < 0)
1014 return -1;
1015
1016 return 0;
1017 }
1018
1019 static void
1020 sk_insert(sock *s)
1021 {
1022 add_tail(&sock_list, &s->n);
1023 }
1024
1025 static void
1026 sk_tcp_connected(sock *s)
1027 {
1028 sockaddr sa;
1029 int sa_len = sizeof(sa);
1030
1031 if ((getsockname(s->fd, &sa.sa, &sa_len) < 0) ||
1032 (sockaddr_read(&sa, s->af, &s->saddr, &s->iface, &s->sport) < 0))
1033 log(L_WARN "SOCK: Cannot get local IP address for TCP>");
1034
1035 s->type = SK_TCP;
1036 sk_alloc_bufs(s);
1037 s->tx_hook(s);
1038 }
1039
1040 #ifdef HAVE_LIBSSH
1041 static void
1042 sk_ssh_connected(sock *s)
1043 {
1044 sk_alloc_bufs(s);
1045 s->type = SK_SSH;
1046 s->tx_hook(s);
1047 }
1048 #endif
1049
1050 static int
1051 sk_passive_connected(sock *s, int type)
1052 {
1053 sockaddr loc_sa, rem_sa;
1054 int loc_sa_len = sizeof(loc_sa);
1055 int rem_sa_len = sizeof(rem_sa);
1056
1057 int fd = accept(s->fd, ((type == SK_TCP) ? &rem_sa.sa : NULL), &rem_sa_len);
1058 if (fd < 0)
1059 {
1060 if ((errno != EINTR) && (errno != EAGAIN))
1061 s->err_hook(s, errno);
1062 return 0;
1063 }
1064
1065 sock *t = sk_new(s->pool);
1066 t->type = type;
1067 t->af = s->af;
1068 t->fd = fd;
1069 t->ttl = s->ttl;
1070 t->tos = s->tos;
1071 t->rbsize = s->rbsize;
1072 t->tbsize = s->tbsize;
1073
1074 if (type == SK_TCP)
1075 {
1076 if ((getsockname(fd, &loc_sa.sa, &loc_sa_len) < 0) ||
1077 (sockaddr_read(&loc_sa, s->af, &t->saddr, &t->iface, &t->sport) < 0))
1078 log(L_WARN "SOCK: Cannot get local IP address for TCP<");
1079
1080 if (sockaddr_read(&rem_sa, s->af, &t->daddr, &t->iface, &t->dport) < 0)
1081 log(L_WARN "SOCK: Cannot get remote IP address for TCP<");
1082 }
1083
1084 if (sk_setup(t) < 0)
1085 {
1086 /* FIXME: Call err_hook instead ? */
1087 log(L_ERR "SOCK: Incoming connection: %s%#m", t->err);
1088
1089 /* FIXME: handle it better in rfree() */
1090 close(t->fd);
1091 t->fd = -1;
1092 rfree(t);
1093 return 1;
1094 }
1095
1096 sk_insert(t);
1097 sk_alloc_bufs(t);
1098 s->rx_hook(t, 0);
1099 return 1;
1100 }
1101
1102 #ifdef HAVE_LIBSSH
1103 /*
1104 * Return SSH_OK or SSH_AGAIN or SSH_ERROR
1105 */
1106 static int
1107 sk_ssh_connect(sock *s)
1108 {
1109 s->fd = ssh_get_fd(s->ssh->session);
1110
1111 /* Big fall thru automata */
1112 switch (s->ssh->state)
1113 {
1114 case SK_SSH_CONNECT:
1115 {
1116 switch (ssh_connect(s->ssh->session))
1117 {
1118 case SSH_AGAIN:
1119 /* A quick look into libSSH shows that ssh_get_fd() should return non-(-1)
1120 * after SSH_AGAIN is returned by ssh_connect(). This is however nowhere
1121 * documented but our code relies on that.
1122 */
1123 return SSH_AGAIN;
1124
1125 case SSH_OK:
1126 break;
1127
1128 default:
1129 return SSH_ERROR;
1130 }
1131 }
1132
1133 case SK_SSH_SERVER_KNOWN:
1134 {
1135 s->ssh->state = SK_SSH_SERVER_KNOWN;
1136
1137 if (s->ssh->server_hostkey_path)
1138 {
1139 int server_identity_is_ok = 1;
1140
1141 /* Check server identity */
1142 switch (ssh_is_server_known(s->ssh->session))
1143 {
1144 #define LOG_WARN_ABOUT_SSH_SERVER_VALIDATION(s,msg,args...) log(L_WARN "SSH Identity %s@%s:%u: " msg, (s)->ssh->username, (s)->host, (s)->dport, ## args);
1145 case SSH_SERVER_KNOWN_OK:
1146 /* The server is known and has not changed. */
1147 break;
1148
1149 case SSH_SERVER_NOT_KNOWN:
1150 LOG_WARN_ABOUT_SSH_SERVER_VALIDATION(s, "The server is unknown, its public key was not found in the known host file %s", s->ssh->server_hostkey_path);
1151 break;
1152
1153 case SSH_SERVER_KNOWN_CHANGED:
1154 LOG_WARN_ABOUT_SSH_SERVER_VALIDATION(s, "The server key has changed. Either you are under attack or the administrator changed the key.");
1155 server_identity_is_ok = 0;
1156 break;
1157
1158 case SSH_SERVER_FILE_NOT_FOUND:
1159 LOG_WARN_ABOUT_SSH_SERVER_VALIDATION(s, "The known host file %s does not exist", s->ssh->server_hostkey_path);
1160 server_identity_is_ok = 0;
1161 break;
1162
1163 case SSH_SERVER_ERROR:
1164 LOG_WARN_ABOUT_SSH_SERVER_VALIDATION(s, "Some error happened");
1165 server_identity_is_ok = 0;
1166 break;
1167
1168 case SSH_SERVER_FOUND_OTHER:
1169 LOG_WARN_ABOUT_SSH_SERVER_VALIDATION(s, "The server gave use a key of a type while we had an other type recorded. " \
1170 "It is a possible attack.");
1171 server_identity_is_ok = 0;
1172 break;
1173 }
1174
1175 if (!server_identity_is_ok)
1176 return SSH_ERROR;
1177 }
1178 }
1179
1180 case SK_SSH_USERAUTH:
1181 {
1182 s->ssh->state = SK_SSH_USERAUTH;
1183 switch (ssh_userauth_publickey_auto(s->ssh->session, NULL, NULL))
1184 {
1185 case SSH_AUTH_AGAIN:
1186 return SSH_AGAIN;
1187
1188 case SSH_AUTH_SUCCESS:
1189 break;
1190
1191 default:
1192 return SSH_ERROR;
1193 }
1194 }
1195
1196 case SK_SSH_CHANNEL:
1197 {
1198 s->ssh->state = SK_SSH_CHANNEL;
1199 s->ssh->channel = ssh_channel_new(s->ssh->session);
1200 if (s->ssh->channel == NULL)
1201 return SSH_ERROR;
1202 }
1203
1204 case SK_SSH_SESSION:
1205 {
1206 s->ssh->state = SK_SSH_SESSION;
1207 switch (ssh_channel_open_session(s->ssh->channel))
1208 {
1209 case SSH_AGAIN:
1210 return SSH_AGAIN;
1211
1212 case SSH_OK:
1213 break;
1214
1215 default:
1216 return SSH_ERROR;
1217 }
1218 }
1219
1220 case SK_SSH_SUBSYSTEM:
1221 {
1222 s->ssh->state = SK_SSH_SUBSYSTEM;
1223 if (s->ssh->subsystem)
1224 {
1225 switch (ssh_channel_request_subsystem(s->ssh->channel, s->ssh->subsystem))
1226 {
1227 case SSH_AGAIN:
1228 return SSH_AGAIN;
1229
1230 case SSH_OK:
1231 break;
1232
1233 default:
1234 return SSH_ERROR;
1235 }
1236 }
1237 }
1238
1239 case SK_SSH_ESTABLISHED:
1240 s->ssh->state = SK_SSH_ESTABLISHED;
1241 }
1242
1243 return SSH_OK;
1244 }
1245
1246 /*
1247 * Return file descriptor number if success
1248 * Return -1 if failed
1249 */
1250 static int
1251 sk_open_ssh(sock *s)
1252 {
1253 if (!s->ssh)
1254 bug("sk_open() sock->ssh is not allocated");
1255
1256 ssh_session sess = ssh_new();
1257 if (sess == NULL)
1258 ERR2("Cannot create a ssh session");
1259 s->ssh->session = sess;
1260
1261 const int verbosity = SSH_LOG_NOLOG;
1262 ssh_options_set(sess, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
1263 ssh_options_set(sess, SSH_OPTIONS_HOST, s->host);
1264 ssh_options_set(sess, SSH_OPTIONS_PORT, &(s->dport));
1265 /* TODO: Add SSH_OPTIONS_BINDADDR */
1266 ssh_options_set(sess, SSH_OPTIONS_USER, s->ssh->username);
1267
1268 if (s->ssh->server_hostkey_path)
1269 ssh_options_set(sess, SSH_OPTIONS_KNOWNHOSTS, s->ssh->server_hostkey_path);
1270
1271 if (s->ssh->client_privkey_path)
1272 ssh_options_set(sess, SSH_OPTIONS_IDENTITY, s->ssh->client_privkey_path);
1273
1274 ssh_set_blocking(sess, 0);
1275
1276 switch (sk_ssh_connect(s))
1277 {
1278 case SSH_AGAIN:
1279 break;
1280
1281 case SSH_OK:
1282 sk_ssh_connected(s);
1283 break;
1284
1285 case SSH_ERROR:
1286 ERR2(ssh_get_error(sess));
1287 break;
1288 }
1289
1290 return ssh_get_fd(sess);
1291
1292 err:
1293 return -1;
1294 }
1295 #endif
1296
1297 /**
1298 * sk_open - open a socket
1299 * @s: socket
1300 *
1301 * This function takes a socket resource created by sk_new() and
1302 * initialized by the user and binds a corresponding network connection
1303 * to it.
1304 *
1305 * Result: 0 for success, -1 for an error.
1306 */
1307 int
1308 sk_open(sock *s)
1309 {
1310 int af = AF_UNSPEC;
1311 int fd = -1;
1312 int do_bind = 0;
1313 int bind_port = 0;
1314 ip_addr bind_addr = IPA_NONE;
1315 sockaddr sa;
1316
1317 if (s->type <= SK_IP)
1318 {
1319 /*
1320 * For TCP/IP sockets, Address family (IPv4 or IPv6) can be specified either
1321 * explicitly (SK_IPV4 or SK_IPV6) or implicitly (based on saddr, daddr).
1322 * But the specifications have to be consistent.
1323 */
1324
1325 switch (s->subtype)
1326 {
1327 case 0:
1328 ASSERT(ipa_zero(s->saddr) || ipa_zero(s->daddr) ||
1329 (ipa_is_ip4(s->saddr) == ipa_is_ip4(s->daddr)));
1330 af = (ipa_is_ip4(s->saddr) || ipa_is_ip4(s->daddr)) ? AF_INET : AF_INET6;
1331 break;
1332
1333 case SK_IPV4:
1334 ASSERT(ipa_zero(s->saddr) || ipa_is_ip4(s->saddr));
1335 ASSERT(ipa_zero(s->daddr) || ipa_is_ip4(s->daddr));
1336 af = AF_INET;
1337 break;
1338
1339 case SK_IPV6:
1340 ASSERT(ipa_zero(s->saddr) || !ipa_is_ip4(s->saddr));
1341 ASSERT(ipa_zero(s->daddr) || !ipa_is_ip4(s->daddr));
1342 af = AF_INET6;
1343 break;
1344
1345 default:
1346 bug("Invalid subtype %d", s->subtype);
1347 }
1348 }
1349
1350 switch (s->type)
1351 {
1352 case SK_TCP_ACTIVE:
1353 s->ttx = ""; /* Force s->ttx != s->tpos */
1354 /* Fall thru */
1355 case SK_TCP_PASSIVE:
1356 fd = socket(af, SOCK_STREAM, IPPROTO_TCP);
1357 bind_port = s->sport;
1358 bind_addr = s->saddr;
1359 do_bind = bind_port || ipa_nonzero(bind_addr);
1360 break;
1361
1362 #ifdef HAVE_LIBSSH
1363 case SK_SSH_ACTIVE:
1364 s->ttx = ""; /* Force s->ttx != s->tpos */
1365 fd = sk_open_ssh(s);
1366 break;
1367 #endif
1368
1369 case SK_UDP:
1370 fd = socket(af, SOCK_DGRAM, IPPROTO_UDP);
1371 bind_port = s->sport;
1372 bind_addr = (s->flags & SKF_BIND) ? s->saddr : IPA_NONE;
1373 do_bind = 1;
1374 break;
1375
1376 case SK_IP:
1377 fd = socket(af, SOCK_RAW, s->dport);
1378 bind_port = 0;
1379 bind_addr = (s->flags & SKF_BIND) ? s->saddr : IPA_NONE;
1380 do_bind = ipa_nonzero(bind_addr);
1381 break;
1382
1383 case SK_MAGIC:
1384 af = 0;
1385 fd = s->fd;
1386 break;
1387
1388 default:
1389 bug("sk_open() called for invalid sock type %d", s->type);
1390 }
1391
1392 if (fd < 0)
1393 ERR("socket");
1394
1395 s->af = af;
1396 s->fd = fd;
1397
1398 if (sk_setup(s) < 0)
1399 goto err;
1400
1401 if (do_bind)
1402 {
1403 if (bind_port)
1404 {
1405 int y = 1;
1406
1407 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &y, sizeof(y)) < 0)
1408 ERR2("SO_REUSEADDR");
1409
1410 #ifdef CONFIG_NO_IFACE_BIND
1411 /* Workaround missing ability to bind to an iface */
1412 if ((s->type == SK_UDP) && s->iface && ipa_zero(bind_addr))
1413 {
1414 if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &y, sizeof(y)) < 0)
1415 ERR2("SO_REUSEPORT");
1416 }
1417 #endif
1418 }
1419 else
1420 if (s->flags & SKF_HIGH_PORT)
1421 if (sk_set_high_port(s) < 0)
1422 log(L_WARN "Socket error: %s%#m", s->err);
1423
1424 sockaddr_fill(&sa, s->af, bind_addr, s->iface, bind_port);
1425 if (bind(fd, &sa.sa, SA_LEN(sa)) < 0)
1426 ERR2("bind");
1427 }
1428
1429 if (s->password)
1430 if (sk_set_md5_auth(s, s->saddr, s->daddr, s->iface, s->password, 0) < 0)
1431 goto err;
1432
1433 switch (s->type)
1434 {
1435 case SK_TCP_ACTIVE:
1436 sockaddr_fill(&sa, s->af, s->daddr, s->iface, s->dport);
1437 if (connect(fd, &sa.sa, SA_LEN(sa)) >= 0)
1438 sk_tcp_connected(s);
1439 else if (errno != EINTR && errno != EAGAIN && errno != EINPROGRESS &&
1440 errno != ECONNREFUSED && errno != EHOSTUNREACH && errno != ENETUNREACH)
1441 ERR2("connect");
1442 break;
1443
1444 case SK_TCP_PASSIVE:
1445 if (listen(fd, 8) < 0)
1446 ERR2("listen");
1447 break;
1448
1449 case SK_SSH_ACTIVE:
1450 case SK_MAGIC:
1451 break;
1452
1453 default:
1454 sk_alloc_bufs(s);
1455 }
1456
1457 if (!(s->flags & SKF_THREAD))
1458 sk_insert(s);
1459
1460 return 0;
1461
1462 err:
1463 close(fd);
1464 s->fd = -1;
1465 return -1;
1466 }
1467
1468 int
1469 sk_open_unix(sock *s, char *name)
1470 {
1471 struct sockaddr_un sa;
1472 int fd;
1473
1474 /* We are sloppy during error (leak fd and not set s->err), but we die anyway */
1475
1476 fd = socket(AF_UNIX, SOCK_STREAM, 0);
1477 if (fd < 0)
1478 return -1;
1479
1480 if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
1481 return -1;
1482
1483 /* Path length checked in test_old_bird() */
1484 sa.sun_family = AF_UNIX;
1485 strcpy(sa.sun_path, name);
1486
1487 if (bind(fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) < 0)
1488 return -1;
1489
1490 if (listen(fd, 8) < 0)
1491 return -1;
1492
1493 s->fd = fd;
1494 sk_insert(s);
1495 return 0;
1496 }
1497
1498
1499 #define CMSG_RX_SPACE MAX(CMSG4_SPACE_PKTINFO+CMSG4_SPACE_TTL, \
1500 CMSG6_SPACE_PKTINFO+CMSG6_SPACE_TTL)
1501 #define CMSG_TX_SPACE MAX(CMSG4_SPACE_PKTINFO,CMSG6_SPACE_PKTINFO)
1502
1503 static void
1504 sk_prepare_cmsgs(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
1505 {
1506 if (sk_is_ipv4(s))
1507 sk_prepare_cmsgs4(s, msg, cbuf, cbuflen);
1508 else
1509 sk_prepare_cmsgs6(s, msg, cbuf, cbuflen);
1510 }
1511
1512 static void
1513 sk_process_cmsgs(sock *s, struct msghdr *msg)
1514 {
1515 struct cmsghdr *cm;
1516
1517 s->laddr = IPA_NONE;
1518 s->lifindex = 0;
1519 s->rcv_ttl = -1;
1520
1521 for (cm = CMSG_FIRSTHDR(msg); cm != NULL; cm = CMSG_NXTHDR(msg, cm))
1522 {
1523 if ((cm->cmsg_level == SOL_IP) && sk_is_ipv4(s))
1524 {
1525 sk_process_cmsg4_pktinfo(s, cm);
1526 sk_process_cmsg4_ttl(s, cm);
1527 }
1528
1529 if ((cm->cmsg_level == SOL_IPV6) && sk_is_ipv6(s))
1530 {
1531 sk_process_cmsg6_pktinfo(s, cm);
1532 sk_process_cmsg6_ttl(s, cm);
1533 }
1534 }
1535 }
1536
1537
1538 static inline int
1539 sk_sendmsg(sock *s)
1540 {
1541 struct iovec iov = {s->tbuf, s->tpos - s->tbuf};
1542 byte cmsg_buf[CMSG_TX_SPACE];
1543 sockaddr dst;
1544
1545 sockaddr_fill(&dst, s->af, s->daddr, s->iface, s->dport);
1546
1547 struct msghdr msg = {
1548 .msg_name = &dst.sa,
1549 .msg_namelen = SA_LEN(dst),
1550 .msg_iov = &iov,
1551 .msg_iovlen = 1
1552 };
1553
1554 #ifdef CONFIG_USE_HDRINCL
1555 byte hdr[20];
1556 struct iovec iov2[2] = { {hdr, 20}, iov };
1557
1558 if (s->flags & SKF_HDRINCL)
1559 {
1560 sk_prepare_ip_header(s, hdr, iov.iov_len);
1561 msg.msg_iov = iov2;
1562 msg.msg_iovlen = 2;
1563 }
1564 #endif
1565
1566 if (s->flags & SKF_PKTINFO)
1567 sk_prepare_cmsgs(s, &msg, cmsg_buf, sizeof(cmsg_buf));
1568
1569 return sendmsg(s->fd, &msg, 0);
1570 }
1571
1572 static inline int
1573 sk_recvmsg(sock *s)
1574 {
1575 struct iovec iov = {s->rbuf, s->rbsize};
1576 byte cmsg_buf[CMSG_RX_SPACE];
1577 sockaddr src;
1578
1579 struct msghdr msg = {
1580 .msg_name = &src.sa,
1581 .msg_namelen = sizeof(src), // XXXX ??
1582 .msg_iov = &iov,
1583 .msg_iovlen = 1,
1584 .msg_control = cmsg_buf,
1585 .msg_controllen = sizeof(cmsg_buf),
1586 .msg_flags = 0
1587 };
1588
1589 int rv = recvmsg(s->fd, &msg, 0);
1590 if (rv < 0)
1591 return rv;
1592
1593 //ifdef IPV4
1594 // if (cf_type == SK_IP)
1595 // rv = ipv4_skip_header(pbuf, rv);
1596 //endif
1597
1598 sockaddr_read(&src, s->af, &s->faddr, NULL, &s->fport);
1599 sk_process_cmsgs(s, &msg);
1600
1601 if (msg.msg_flags & MSG_TRUNC)
1602 s->flags |= SKF_TRUNCATED;
1603 else
1604 s->flags &= ~SKF_TRUNCATED;
1605
1606 return rv;
1607 }
1608
1609
1610 static inline void reset_tx_buffer(sock *s) { s->ttx = s->tpos = s->tbuf; }
1611
1612 static int
1613 sk_maybe_write(sock *s)
1614 {
1615 int e;
1616
1617 switch (s->type)
1618 {
1619 case SK_TCP:
1620 case SK_MAGIC:
1621 case SK_UNIX:
1622 while (s->ttx != s->tpos)
1623 {
1624 e = write(s->fd, s->ttx, s->tpos - s->ttx);
1625
1626 if (e < 0)
1627 {
1628 if (errno != EINTR && errno != EAGAIN)
1629 {
1630 reset_tx_buffer(s);
1631 /* EPIPE is just a connection close notification during TX */
1632 s->err_hook(s, (errno != EPIPE) ? errno : 0);
1633 return -1;
1634 }
1635 return 0;
1636 }
1637 s->ttx += e;
1638 }
1639 reset_tx_buffer(s);
1640 return 1;
1641
1642 #ifdef HAVE_LIBSSH
1643 case SK_SSH:
1644 while (s->ttx != s->tpos)
1645 {
1646 e = ssh_channel_write(s->ssh->channel, s->ttx, s->tpos - s->ttx);
1647
1648 if (e < 0)
1649 {
1650 s->err = ssh_get_error(s->ssh->session);
1651 s->err_hook(s, ssh_get_error_code(s->ssh->session));
1652
1653 reset_tx_buffer(s);
1654 /* EPIPE is just a connection close notification during TX */
1655 s->err_hook(s, (errno != EPIPE) ? errno : 0);
1656 return -1;
1657 }
1658 s->ttx += e;
1659 }
1660 reset_tx_buffer(s);
1661 return 1;
1662 #endif
1663
1664 case SK_UDP:
1665 case SK_IP:
1666 {
1667 if (s->tbuf == s->tpos)
1668 return 1;
1669
1670 e = sk_sendmsg(s);
1671
1672 if (e < 0)
1673 {
1674 if (errno != EINTR && errno != EAGAIN)
1675 {
1676 reset_tx_buffer(s);
1677 s->err_hook(s, errno);
1678 return -1;
1679 }
1680
1681 if (!s->tx_hook)
1682 reset_tx_buffer(s);
1683 return 0;
1684 }
1685 reset_tx_buffer(s);
1686 return 1;
1687 }
1688
1689 default:
1690 bug("sk_maybe_write: unknown socket type %d", s->type);
1691 }
1692 }
1693
1694 int
1695 sk_rx_ready(sock *s)
1696 {
1697 int rv;
1698 struct pollfd pfd = { .fd = s->fd };
1699 pfd.events |= POLLIN;
1700
1701 redo:
1702 rv = poll(&pfd, 1, 0);
1703
1704 if ((rv < 0) && (errno == EINTR || errno == EAGAIN))
1705 goto redo;
1706
1707 return rv;
1708 }
1709
1710 /**
1711 * sk_send - send data to a socket
1712 * @s: socket
1713 * @len: number of bytes to send
1714 *
1715 * This function sends @len bytes of data prepared in the
1716 * transmit buffer of the socket @s to the network connection.
1717 * If the packet can be sent immediately, it does so and returns
1718 * 1, else it queues the packet for later processing, returns 0
1719 * and calls the @tx_hook of the socket when the tranmission
1720 * takes place.
1721 */
1722 int
1723 sk_send(sock *s, unsigned len)
1724 {
1725 s->ttx = s->tbuf;
1726 s->tpos = s->tbuf + len;
1727 return sk_maybe_write(s);
1728 }
1729
1730 /**
1731 * sk_send_to - send data to a specific destination
1732 * @s: socket
1733 * @len: number of bytes to send
1734 * @addr: IP address to send the packet to
1735 * @port: port to send the packet to
1736 *
1737 * This is a sk_send() replacement for connection-less packet sockets
1738 * which allows destination of the packet to be chosen dynamically.
1739 * Raw IP sockets should use 0 for @port.
1740 */
1741 int
1742 sk_send_to(sock *s, unsigned len, ip_addr addr, unsigned port)
1743 {
1744 s->daddr = addr;
1745 if (port)
1746 s->dport = port;
1747
1748 s->ttx = s->tbuf;
1749 s->tpos = s->tbuf + len;
1750 return sk_maybe_write(s);
1751 }
1752
1753 /*
1754 int
1755 sk_send_full(sock *s, unsigned len, struct iface *ifa,
1756 ip_addr saddr, ip_addr daddr, unsigned dport)
1757 {
1758 s->iface = ifa;
1759 s->saddr = saddr;
1760 s->daddr = daddr;
1761 s->dport = dport;
1762 s->ttx = s->tbuf;
1763 s->tpos = s->tbuf + len;
1764 return sk_maybe_write(s);
1765 }
1766 */
1767
1768 static void
1769 call_rx_hook(sock *s, int size)
1770 {
1771 if (s->rx_hook(s, size))
1772 {
1773 /* We need to be careful since the socket could have been deleted by the hook */
1774 if (current_sock == s)
1775 s->rpos = s->rbuf;
1776 }
1777 }
1778
1779 #ifdef HAVE_LIBSSH
1780 static int
1781 sk_read_ssh(sock *s)
1782 {
1783 ssh_channel rchans[2] = { s->ssh->channel, NULL };
1784 struct timeval timev = { 1, 0 };
1785
1786 if (ssh_channel_select(rchans, NULL, NULL, &timev) == SSH_EINTR)
1787 return 1; /* Try again */
1788
1789 if (ssh_channel_is_eof(s->ssh->channel) != 0)
1790 {
1791 /* The remote side is closing the connection */
1792 s->err_hook(s, 0);
1793 return 0;
1794 }
1795
1796 if (rchans[0] == NULL)
1797 return 0; /* No data is available on the socket */
1798
1799 const uint used_bytes = s->rpos - s->rbuf;
1800 const int read_bytes = ssh_channel_read_nonblocking(s->ssh->channel, s->rpos, s->rbsize - used_bytes, 0);
1801 if (read_bytes > 0)
1802 {
1803 /* Received data */
1804 s->rpos += read_bytes;
1805 call_rx_hook(s, used_bytes + read_bytes);
1806 return 1;
1807 }
1808 else if (read_bytes == 0)
1809 {
1810 if (ssh_channel_is_eof(s->ssh->channel) != 0)
1811 {
1812 /* The remote side is closing the connection */
1813 s->err_hook(s, 0);
1814 }
1815 }
1816 else
1817 {
1818 s->err = ssh_get_error(s->ssh->session);
1819 s->err_hook(s, ssh_get_error_code(s->ssh->session));
1820 }
1821
1822 return 0; /* No data is available on the socket */
1823 }
1824 #endif
1825
1826 /* sk_read() and sk_write() are called from BFD's event loop */
1827
1828 int
1829 sk_read(sock *s, int revents)
1830 {
1831 switch (s->type)
1832 {
1833 case SK_TCP_PASSIVE:
1834 return sk_passive_connected(s, SK_TCP);
1835
1836 case SK_UNIX_PASSIVE:
1837 return sk_passive_connected(s, SK_UNIX);
1838
1839 case SK_TCP:
1840 case SK_UNIX:
1841 {
1842 int c = read(s->fd, s->rpos, s->rbuf + s->rbsize - s->rpos);
1843
1844 if (c < 0)
1845 {
1846 if (errno != EINTR && errno != EAGAIN)
1847 s->err_hook(s, errno);
1848 else if (errno == EAGAIN && !(revents & POLLIN))
1849 {
1850 log(L_ERR "Got EAGAIN from read when revents=%x (without POLLIN)", revents);
1851 s->err_hook(s, 0);
1852 }
1853 }
1854 else if (!c)
1855 s->err_hook(s, 0);
1856 else
1857 {
1858 s->rpos += c;
1859 call_rx_hook(s, s->rpos - s->rbuf);
1860 return 1;
1861 }
1862 return 0;
1863 }
1864
1865 #ifdef HAVE_LIBSSH
1866 case SK_SSH:
1867 return sk_read_ssh(s);
1868 #endif
1869
1870 case SK_MAGIC:
1871 return s->rx_hook(s, 0);
1872
1873 default:
1874 {
1875 int e = sk_recvmsg(s);
1876
1877 if (e < 0)
1878 {
1879 if (errno != EINTR && errno != EAGAIN)
1880 s->err_hook(s, errno);
1881 return 0;
1882 }
1883
1884 s->rpos = s->rbuf + e;
1885 s->rx_hook(s, e);
1886 return 1;
1887 }
1888 }
1889 }
1890
1891 int
1892 sk_write(sock *s)
1893 {
1894 switch (s->type)
1895 {
1896 case SK_TCP_ACTIVE:
1897 {
1898 sockaddr sa;
1899 sockaddr_fill(&sa, s->af, s->daddr, s->iface, s->dport);
1900
1901 if (connect(s->fd, &sa.sa, SA_LEN(sa)) >= 0 || errno == EISCONN)
1902 sk_tcp_connected(s);
1903 else if (errno != EINTR && errno != EAGAIN && errno != EINPROGRESS)
1904 s->err_hook(s, errno);
1905 return 0;
1906 }
1907
1908 #ifdef HAVE_LIBSSH
1909 case SK_SSH_ACTIVE:
1910 {
1911 switch (sk_ssh_connect(s))
1912 {
1913 case SSH_OK:
1914 sk_ssh_connected(s);
1915 break;
1916
1917 case SSH_AGAIN:
1918 return 1;
1919
1920 case SSH_ERROR:
1921 s->err = ssh_get_error(s->ssh->session);
1922 s->err_hook(s, ssh_get_error_code(s->ssh->session));
1923 break;
1924 }
1925 return 0;
1926 }
1927 #endif
1928
1929 default:
1930 if (s->ttx != s->tpos && sk_maybe_write(s) > 0)
1931 {
1932 if (s->tx_hook)
1933 s->tx_hook(s);
1934 return 1;
1935 }
1936 return 0;
1937 }
1938 }
1939
1940 int sk_is_ipv4(sock *s)
1941 { return s->af == AF_INET; }
1942
1943 int sk_is_ipv6(sock *s)
1944 { return s->af == AF_INET6; }
1945
1946 void
1947 sk_err(sock *s, int revents)
1948 {
1949 int se = 0, sse = sizeof(se);
1950 if ((s->type != SK_MAGIC) && (revents & POLLERR))
1951 if (getsockopt(s->fd, SOL_SOCKET, SO_ERROR, &se, &sse) < 0)
1952 {
1953 log(L_ERR "IO: Socket error: SO_ERROR: %m");
1954 se = 0;
1955 }
1956
1957 s->err_hook(s, se);
1958 }
1959
1960 void
1961 sk_dump_all(void)
1962 {
1963 node *n;
1964 sock *s;
1965
1966 debug("Open sockets:\n");
1967 WALK_LIST(n, sock_list)
1968 {
1969 s = SKIP_BACK(sock, n, n);
1970 debug("%p ", s);
1971 sk_dump(&s->r);
1972 }
1973 debug("\n");
1974 }
1975
1976
1977 /*
1978 * Internal event log and watchdog
1979 */
1980
1981 #define EVENT_LOG_LENGTH 32
1982
1983 struct event_log_entry
1984 {
1985 void *hook;
1986 void *data;
1987 btime timestamp;
1988 btime duration;
1989 };
1990
1991 static struct event_log_entry event_log[EVENT_LOG_LENGTH];
1992 static struct event_log_entry *event_open;
1993 static int event_log_pos, event_log_num, watchdog_active;
1994 static btime last_time;
1995 static btime loop_time;
1996
1997 static void
1998 io_update_time(void)
1999 {
2000 struct timespec ts;
2001 int rv;
2002
2003 /*
2004 * This is third time-tracking procedure (after update_times() above and
2005 * times_update() in BFD), dedicated to internal event log and latency
2006 * tracking. Hopefully, we consolidate these sometimes.
2007 */
2008
2009 rv = clock_gettime(CLOCK_MONOTONIC, &ts);
2010 if (rv < 0)
2011 die("clock_gettime: %m");
2012
2013 last_time = ts.tv_sec S + ts.tv_nsec NS;
2014
2015 if (event_open)
2016 {
2017 event_open->duration = last_time - event_open->timestamp;
2018
2019 if (event_open->duration > config->latency_limit)
2020 log(L_WARN "Event 0x%p 0x%p took %d ms",
2021 event_open->hook, event_open->data, (int) (event_open->duration TO_MS));
2022
2023 event_open = NULL;
2024 }
2025 }
2026
2027 /**
2028 * io_log_event - mark approaching event into event log
2029 * @hook: event hook address
2030 * @data: event data address
2031 *
2032 * Store info (hook, data, timestamp) about the following internal event into
2033 * a circular event log (@event_log). When latency tracking is enabled, the log
2034 * entry is kept open (in @event_open) so the duration can be filled later.
2035 */
2036 void
2037 io_log_event(void *hook, void *data)
2038 {
2039 if (config->latency_debug)
2040 io_update_time();
2041
2042 struct event_log_entry *en = event_log + event_log_pos;
2043
2044 en->hook = hook;
2045 en->data = data;
2046 en->timestamp = last_time;
2047 en->duration = 0;
2048
2049 event_log_num++;
2050 event_log_pos++;
2051 event_log_pos %= EVENT_LOG_LENGTH;
2052
2053 event_open = config->latency_debug ? en : NULL;
2054 }
2055
2056 static inline void
2057 io_close_event(void)
2058 {
2059 if (event_open)
2060 io_update_time();
2061 }
2062
2063 void
2064 io_log_dump(void)
2065 {
2066 int i;
2067
2068 log(L_DEBUG "Event log:");
2069 for (i = 0; i < EVENT_LOG_LENGTH; i++)
2070 {
2071 struct event_log_entry *en = event_log + (event_log_pos + i) % EVENT_LOG_LENGTH;
2072 if (en->hook)
2073 log(L_DEBUG " Event 0x%p 0x%p at %8d for %d ms", en->hook, en->data,
2074 (int) ((last_time - en->timestamp) TO_MS), (int) (en->duration TO_MS));
2075 }
2076 }
2077
2078 void
2079 watchdog_sigalrm(int sig UNUSED)
2080 {
2081 /* Update last_time and duration, but skip latency check */
2082 config->latency_limit = 0xffffffff;
2083 io_update_time();
2084
2085 /* We want core dump */
2086 abort();
2087 }
2088
2089 static inline void
2090 watchdog_start1(void)
2091 {
2092 io_update_time();
2093
2094 loop_time = last_time;
2095 }
2096
2097 static inline void
2098 watchdog_start(void)
2099 {
2100 io_update_time();
2101
2102 loop_time = last_time;
2103 event_log_num = 0;
2104
2105 if (config->watchdog_timeout)
2106 {
2107 alarm(config->watchdog_timeout);
2108 watchdog_active = 1;
2109 }
2110 }
2111
2112 static inline void
2113 watchdog_stop(void)
2114 {
2115 io_update_time();
2116
2117 if (watchdog_active)
2118 {
2119 alarm(0);
2120 watchdog_active = 0;
2121 }
2122
2123 btime duration = last_time - loop_time;
2124 if (duration > config->watchdog_warning)
2125 log(L_WARN "I/O loop cycle took %d ms for %d events",
2126 (int) (duration TO_MS), event_log_num);
2127 }
2128
2129
2130 /*
2131 * Main I/O Loop
2132 */
2133
2134 volatile int async_config_flag; /* Asynchronous reconfiguration/dump scheduled */
2135 volatile int async_dump_flag;
2136 volatile int async_shutdown_flag;
2137
2138 void
2139 io_init(void)
2140 {
2141 init_list(&sock_list);
2142 init_list(&global_event_list);
2143 krt_io_init();
2144 // XXX init_times();
2145 // XXX update_times();
2146 boot_time = current_time();
2147 srandom((uint) (current_real_time() TO_S));
2148 }
2149
2150 static int short_loops = 0;
2151 #define SHORT_LOOP_MAX 10
2152
2153 void
2154 io_loop(void)
2155 {
2156 int poll_tout, timeout;
2157 int nfds, events, pout;
2158 timer *t;
2159 sock *s;
2160 node *n;
2161 int fdmax = 256;
2162 struct pollfd *pfd = xmalloc(fdmax * sizeof(struct pollfd));
2163
2164 watchdog_start1();
2165 for(;;)
2166 {
2167 times_update(&main_timeloop);
2168 events = ev_run_list(&global_event_list);
2169 timers_fire(&main_timeloop);
2170 io_close_event();
2171
2172 // FIXME
2173 poll_tout = (events ? 0 : 3000); /* Time in milliseconds */
2174 if (t = timers_first(&main_timeloop))
2175 {
2176 times_update(&main_timeloop);
2177 timeout = (tm_remains(t) TO_MS) + 1;
2178 poll_tout = MIN(poll_tout, timeout);
2179 }
2180
2181 nfds = 0;
2182 WALK_LIST(n, sock_list)
2183 {
2184 pfd[nfds] = (struct pollfd) { .fd = -1 }; /* everything other set to 0 by this */
2185 s = SKIP_BACK(sock, n, n);
2186 if (s->rx_hook)
2187 {
2188 pfd[nfds].fd = s->fd;
2189 pfd[nfds].events |= POLLIN;
2190 }
2191 if (s->tx_hook && s->ttx != s->tpos)
2192 {
2193 pfd[nfds].fd = s->fd;
2194 pfd[nfds].events |= POLLOUT;
2195 }
2196 if (pfd[nfds].fd != -1)
2197 {
2198 s->index = nfds;
2199 nfds++;
2200 }
2201 else
2202 s->index = -1;
2203
2204 if (nfds >= fdmax)
2205 {
2206 fdmax *= 2;
2207 pfd = xrealloc(pfd, fdmax * sizeof(struct pollfd));
2208 }
2209 }
2210
2211 /*
2212 * Yes, this is racy. But even if the signal comes before this test
2213 * and entering poll(), it gets caught on the next timer tick.
2214 */
2215
2216 if (async_config_flag)
2217 {
2218 io_log_event(async_config, NULL);
2219 async_config();
2220 async_config_flag = 0;
2221 continue;
2222 }
2223 if (async_dump_flag)
2224 {
2225 io_log_event(async_dump, NULL);
2226 async_dump();
2227 async_dump_flag = 0;
2228 continue;
2229 }
2230 if (async_shutdown_flag)
2231 {
2232 io_log_event(async_shutdown, NULL);
2233 async_shutdown();
2234 async_shutdown_flag = 0;
2235 continue;
2236 }
2237
2238 /* And finally enter poll() to find active sockets */
2239 watchdog_stop();
2240 pout = poll(pfd, nfds, poll_tout);
2241 watchdog_start();
2242
2243 if (pout < 0)
2244 {
2245 if (errno == EINTR || errno == EAGAIN)
2246 continue;
2247 die("poll: %m");
2248 }
2249 if (pout)
2250 {
2251 times_update(&main_timeloop);
2252
2253 /* guaranteed to be non-empty */
2254 current_sock = SKIP_BACK(sock, n, HEAD(sock_list));
2255
2256 while (current_sock)
2257 {
2258 sock *s = current_sock;
2259 if (s->index == -1)
2260 {
2261 current_sock = sk_next(s);
2262 goto next;
2263 }
2264
2265 int e;
2266 int steps;
2267
2268 steps = MAX_STEPS;
2269 if (s->fast_rx && (pfd[s->index].revents & POLLIN) && s->rx_hook)
2270 do
2271 {
2272 steps--;
2273 io_log_event(s->rx_hook, s->data);
2274 e = sk_read(s, pfd[s->index].revents);
2275 if (s != current_sock)
2276 goto next;
2277 }
2278 while (e && s->rx_hook && steps);
2279
2280 steps = MAX_STEPS;
2281 if (pfd[s->index].revents & POLLOUT)
2282 do
2283 {
2284 steps--;
2285 io_log_event(s->tx_hook, s->data);
2286 e = sk_write(s);
2287 if (s != current_sock)
2288 goto next;
2289 }
2290 while (e && steps);
2291
2292 current_sock = sk_next(s);
2293 next: ;
2294 }
2295
2296 short_loops++;
2297 if (events && (short_loops < SHORT_LOOP_MAX))
2298 continue;
2299 short_loops = 0;
2300
2301 int count = 0;
2302 current_sock = stored_sock;
2303 if (current_sock == NULL)
2304 current_sock = SKIP_BACK(sock, n, HEAD(sock_list));
2305
2306 while (current_sock && count < MAX_RX_STEPS)
2307 {
2308 sock *s = current_sock;
2309 if (s->index == -1)
2310 {
2311 current_sock = sk_next(s);
2312 goto next2;
2313 }
2314
2315 if (!s->fast_rx && (pfd[s->index].revents & POLLIN) && s->rx_hook)
2316 {
2317 count++;
2318 io_log_event(s->rx_hook, s->data);
2319 sk_read(s, pfd[s->index].revents);
2320 if (s != current_sock)
2321 goto next2;
2322 }
2323
2324 if (pfd[s->index].revents & (POLLHUP | POLLERR))
2325 {
2326 sk_err(s, pfd[s->index].revents);
2327 if (s != current_sock)
2328 goto next2;
2329 }
2330
2331 current_sock = sk_next(s);
2332 next2: ;
2333 }
2334
2335
2336 stored_sock = current_sock;
2337 }
2338 }
2339 }
2340
2341 void
2342 test_old_bird(char *path)
2343 {
2344 int fd;
2345 struct sockaddr_un sa;
2346
2347 fd = socket(AF_UNIX, SOCK_STREAM, 0);
2348 if (fd < 0)
2349 die("Cannot create socket: %m");
2350 if (strlen(path) >= sizeof(sa.sun_path))
2351 die("Socket path too long");
2352 bzero(&sa, sizeof(sa));
2353 sa.sun_family = AF_UNIX;
2354 strcpy(sa.sun_path, path);
2355 if (connect(fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) == 0)
2356 die("I found another BIRD running.");
2357 close(fd);
2358 }