3 * Copyright (c) 2018-2019 Apple Computer, Inc. All rights reserved.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 * Simple event dispatcher for DNS.
20 #define __APPLE_USE_RFC_3542
29 #include <sys/socket.h>
30 #include <netinet/in.h>
31 #include <arpa/inet.h>
33 #include <sys/event.h>
46 #include "srp-crypto.h"
54 subproc_t
*subprocesses
;
62 getipaddr(addr_t
*addr
, const char *p
)
64 if (inet_pton(AF_INET
, p
, &addr
->sin
.sin_addr
)) {
65 addr
->sa
.sa_family
= AF_INET
;
66 #ifndef NOT_HAVE_SA_LEN
67 addr
->sa
.sa_len
= sizeof addr
->sin
;
69 return sizeof addr
->sin
;
70 } else if (inet_pton(AF_INET6
, p
, &addr
->sin6
.sin6_addr
)) {
71 addr
->sa
.sa_family
= AF_INET6
;
72 #ifndef NOT_HAVE_SA_LEN
73 addr
->sa
.sa_len
= sizeof addr
->sin6
;
75 return sizeof addr
->sin6
;
87 now
= (int64_t)tv
.tv_sec
* 1000 + (int64_t)tv
.tv_usec
/ 1000;
92 message_allocate(size_t message_size
)
94 message_t
*message
= (message_t
*)malloc(message_size
+ (sizeof (message_t
)) - (sizeof (dns_wire_t
)));
96 memset(message
, 0, (sizeof (message_t
)) - (sizeof (dns_wire_t
)));
101 message_free(message_t
*message
)
107 comm_free(comm_t
*comm
)
114 message_free(comm
->message
);
115 comm
->message
= NULL
;
122 ioloop_close(io_t
*io
)
133 // Add the new reader to the end of the list if it's not on the list.
134 for (iop
= &ios
; *iop
!= NULL
&& *iop
!= io
; iop
= &((*iop
)->next
))
143 ioloop_add_reader(io_t
*io
, io_callback_t callback
, io_callback_t finalize
)
147 io
->read_callback
= callback
;
148 io
->finalize
= finalize
;
150 io
->want_read
= true;
157 EV_SET(&ev
, io
->sock
, EVFILT_READ
, EV_ADD
| EV_ENABLE
, 0, 0, io
);
158 rv
= kevent(kq
, &ev
, 1, NULL
, 0, NULL
);
160 ERROR("kevent add: %s", strerror(errno
));
167 ioloop_add_writer(io_t
*io
, io_callback_t callback
, io_callback_t finalize
)
171 io
->write_callback
= callback
;
173 io
->want_write
= true;
180 EV_SET(&ev
, io
->sock
, EVFILT_WRITE
, EV_ADD
| EV_ENABLE
, 0, 0, io
);
181 rv
= kevent(kq
, &ev
, 1, NULL
, 0, NULL
);
183 ERROR("kevent add: %s", strerror(errno
));
190 drop_writer(io_t
*io
)
193 io
->want_write
= false;
200 EV_SET(&ev
, io
->sock
, EVFILT_WRITE
, EV_ADD
| EV_DISABLE
, 0, 0, io
);
201 rv
= kevent(kq
, &ev
, 1, NULL
, 0, NULL
);
203 ERROR("kevent add: %s", strerror(errno
));
210 add_remove_wakeup(wakeup_t
*io
, bool remove
)
212 wakeup_t
**p_wakeups
;
214 // Add the new reader to the end of the list if it's not on the list.
215 for (p_wakeups
= &wakeups
; *p_wakeups
!= NULL
&& *p_wakeups
!= io
; p_wakeups
= &((*p_wakeups
)->next
))
218 if (*p_wakeups
!= NULL
) {
219 *p_wakeups
= io
->next
;
223 if (*p_wakeups
== NULL
) {
231 ioloop_add_wake_event(wakeup_t
*wakeup
, void *context
, wakeup_callback_t callback
, int milliseconds
)
233 add_remove_wakeup(wakeup
, false);
234 wakeup
->wakeup_time
= ioloop_timenow() + milliseconds
;
235 wakeup
->wakeup
= callback
;
236 wakeup
->context
= context
;
240 ioloop_cancel_wake_event(wakeup_t
*wakeup
)
242 add_remove_wakeup(wakeup
, true);
243 wakeup
->wakeup_time
= 0;
247 subproc_free(subproc_t
*subproc
)
250 for (i
= 0; i
< subproc
->argc
; i
++) {
251 free(subproc
->argv
[i
]);
259 signal(SIGPIPE
, SIG_IGN
); // because why ever?
263 ERROR("kqueue(): %s", strerror(errno
));
271 ioloop_events(int64_t timeout_when
)
274 wakeup_t
*wakeup
, **p_wakeup
;
276 int64_t now
= ioloop_timenow();
277 int64_t next_event
= timeout_when
;
280 if (ioloop_now
!= 0) {
281 INFO("%lld.%03lld seconds have passed on entry to ioloop_events",
282 (long long)((now
- ioloop_now
) / 1000), (long long)((now
- ioloop_now
) % 1000));
286 // A timeout of zero means don't time out.
287 if (timeout_when
== 0) {
288 next_event
= INT64_MAX
;
290 next_event
= timeout_when
;
295 fd_set reads
, writes
, errors
;
308 if (wakeup
->wakeup_time
!= 0) {
309 // We loop here in case the wakeup callback sets another wakeup--if it does, we check
311 while (wakeup
->wakeup_time
<= ioloop_now
) {
312 wakeup
->wakeup_time
= 0;
313 wakeup
->wakeup(wakeup
->context
);
315 if (wakeup
->wakeup_time
== 0) {
316 // Take the wakeup off the list.
317 *p_wakeup
= wakeup
->next
;
322 if (wakeup
->wakeup_time
< next_event
) {
323 next_event
= wakeup
->wakeup_time
;
331 // If the I/O is dead, finalize or free it.
332 if (io
->sock
== -1) {
345 // INFO("now: %ld io %d wakeup_time %ld next_event %ld", ioloop_now, io->sock, io->wakeup_time, next_event);
347 // If we were given a timeout in the future, or told to wait indefinitely, wait until the next event.
348 if (timeout_when
== 0 || timeout_when
> ioloop_now
) {
349 timeout
= next_event
- ioloop_now
;
350 // Don't choose a time so far in the future that it might overflow some math in the kernel.
351 if (timeout
> IOLOOP_DAY
* 100) {
352 timeout
= IOLOOP_DAY
* 100;
355 tv
.tv_sec
= timeout
/ 1000;
356 tv
.tv_usec
= (timeout
% 1000) * 1000;
359 ts
.tv_sec
= timeout
/ 1000;
360 ts
.tv_nsec
= (timeout
% 1000) * 1000 * 1000;
364 while (subprocesses
!= NULL
) {
367 pid
= waitpid(-1, &status
, WNOHANG
);
371 subproc_t
**sp
, *subproc
;
372 for (sp
= &subprocesses
; (*sp
) != NULL
; sp
= &(*sp
)->next
) {
374 if (subproc
->pid
== pid
) {
375 if (!WIFSTOPPED(status
)) {
378 subproc
->callback(subproc
, status
, NULL
);
379 if (!WIFSTOPPED(status
)) {
380 subproc_free(subproc
);
388 for (io
= ios
; io
; io
= io
->next
) {
389 if (io
->sock
!= -1 && (io
->want_read
|| io
->want_write
)) {
390 if (io
->sock
>= nfds
) {
394 FD_SET(io
->sock
, &reads
);
396 if (io
->want_write
) {
397 FD_SET(io
->sock
, &writes
);
404 INFO("waiting %lld %lld seconds", (long long)tv
.tv_sec
, (long long)tv
.tv_usec
);
405 rv
= select(nfds
, &reads
, &writes
, &errors
, &tv
);
407 ERROR("select: %s", strerror(errno
));
410 now
= ioloop_timenow();
411 INFO("%lld.%03lld seconds passed waiting, got %d events", (long long)((now
- ioloop_now
) / 1000),
412 (long long)((now
- ioloop_now
) % 1000), rv
);
414 for (io
= ios
; io
; io
= io
->next
) {
415 if (io
->sock
!= -1) {
416 if (FD_ISSET(io
->sock
, &reads
)) {
417 io
->read_callback(io
);
418 } else if (FD_ISSET(io
->sock
, &writes
)) {
419 io
->write_callback(io
);
427 struct kevent evs
[KEV_MAX
];
430 INFO("waiting %lld/%lld seconds", (long long)ts
.tv_sec
, (long long)ts
.tv_nsec
);
432 rv
= kevent(kq
, NULL
, 0, evs
, KEV_MAX
, &ts
);
433 now
= ioloop_timenow();
434 INFO("%lld.%03lld seconds passed waiting, got %d events", (long long)((now
- ioloop_now
) / 1000),
435 (long long)((now
- ioloop_now
) % 1000), rv
);
440 if (errno
== EINTR
) {
443 ERROR("kevent poll: %s", strerror(errno
));
447 for (i
= 0; i
< rv
; i
++) {
449 if (evs
[i
].filter
== EVFILT_WRITE
) {
450 io
->write_callback(io
);
451 } else if (evs
[i
].filter
== EVFILT_READ
) {
452 io
->read_callback(io
);
456 } while (rv
== KEV_MAX
);
462 udp_read_callback(io_t
*io
)
464 comm_t
*connection
= (comm_t
*)io
;
469 uint8_t msgbuf
[DNS_MAX_UDP_PAYLOAD
];
474 bufp
.iov_base
= msgbuf
;
475 bufp
.iov_len
= DNS_MAX_UDP_PAYLOAD
;
479 msg
.msg_namelen
= sizeof src
;
480 msg
.msg_control
= cmsgbuf
;
481 msg
.msg_controllen
= sizeof cmsgbuf
;
483 rv
= recvmsg(connection
->io
.sock
, &msg
, 0);
485 ERROR("udp_read_callback: %s", strerror(errno
));
488 message
= message_allocate(rv
);
490 ERROR("udp_read_callback: out of memory");
493 memcpy(&message
->src
, &src
, sizeof src
);
494 message
->length
= rv
;
495 memcpy(&message
->wire
, msgbuf
, rv
);
497 // For UDP, we use the interface index as part of the validation strategy, so go get
498 // the interface index.
499 for (cmh
= CMSG_FIRSTHDR(&msg
); cmh
; cmh
= CMSG_NXTHDR(&msg
, cmh
)) {
500 if (cmh
->cmsg_level
== IPPROTO_IPV6
&& cmh
->cmsg_type
== IPV6_PKTINFO
) {
501 struct in6_pktinfo pktinfo
;
503 memcpy(&pktinfo
, CMSG_DATA(cmh
), sizeof pktinfo
);
504 message
->ifindex
= pktinfo
.ipi6_ifindex
;
506 /* Get the destination address, for use when replying. */
507 message
->local
.sin6
.sin6_family
= AF_INET6
;
508 message
->local
.sin6
.sin6_port
= 0;
509 message
->local
.sin6
.sin6_addr
= pktinfo
.ipi6_addr
;
510 #ifndef NOT_HAVE_SA_LEN
511 message
->local
.sin6
.sin6_len
= sizeof message
->local
;
513 } else if (cmh
->cmsg_level
== IPPROTO_IP
&& cmh
->cmsg_type
== IP_PKTINFO
) {
514 struct in_pktinfo pktinfo
;
516 memcpy(&pktinfo
, CMSG_DATA(cmh
), sizeof pktinfo
);
517 message
->ifindex
= pktinfo
.ipi_ifindex
;
519 message
->local
.sin
.sin_family
= AF_INET
;
520 message
->local
.sin
.sin_port
= 0;
521 message
->local
.sin
.sin_addr
= pktinfo
.ipi_addr
;
522 #ifndef NOT_HAVE_SA_LEN
523 message
->local
.sin
.sin_len
= sizeof message
->local
;
527 connection
->message
= message
;
528 connection
->datagram_callback(connection
);
532 tcp_read_callback(io_t
*context
)
536 comm_t
*connection
= (comm_t
*)context
;
538 if (connection
->message_length_len
< 2) {
539 read_ptr
= connection
->message_length_bytes
;
540 read_len
= 2 - connection
->message_length_len
;
542 read_ptr
= &connection
->buf
[connection
->message_cur
];
543 read_len
= connection
->message_length
- connection
->message_cur
;
546 if (connection
->tls_context
!= NULL
) {
548 rv
= srp_tls_read(connection
, read_ptr
, read_len
);
550 // This isn't an EOF: that's returned as an error status. This just means that
551 // whatever data was available to be read was consumed by the TLS protocol without
552 // producing anything to read at the app layer.
555 ERROR("TLS return that we can't handle.");
556 close(connection
->io
.sock
);
557 connection
->io
.sock
= -1;
558 srp_tls_context_free(connection
);
562 ERROR("tls context with TLS excluded in tcp_read_callback.");
566 rv
= read(connection
->io
.sock
, read_ptr
, read_len
);
569 ERROR("tcp_read_callback: %s", strerror(errno
));
570 close(connection
->io
.sock
);
571 connection
->io
.sock
= -1;
572 // connection->io.finalize() will be called from the io loop.
576 // If we read zero here, the remote endpoint has closed or shutdown the connection. Either case is
577 // effectively the same--if we are sensitive to read events, that means that we are done processing
578 // the previous message.
580 ERROR("tcp_read_callback: remote end (%s) closed connection on %d", connection
->name
, connection
->io
.sock
);
581 close(connection
->io
.sock
);
582 connection
->io
.sock
= -1;
583 // connection->io.finalize() will be called from the io loop.
587 if (connection
->message_length_len
< 2) {
588 connection
->message_length_len
+= rv
;
589 if (connection
->message_length_len
== 2) {
590 connection
->message_length
= (((uint16_t)connection
->message_length_bytes
[0] << 8) |
591 ((uint16_t)connection
->message_length_bytes
[1]));
593 if (connection
->message
== NULL
) {
594 connection
->message
= message_allocate(connection
->message_length
);
595 if (!connection
->message
) {
596 ERROR("udp_read_callback: out of memory");
599 connection
->buf
= (uint8_t *)&connection
->message
->wire
;
600 connection
->message
->length
= connection
->message_length
;
601 memset(&connection
->message
->src
, 0, sizeof connection
->message
->src
);
605 connection
->message_cur
+= rv
;
606 if (connection
->message_cur
== connection
->message_length
) {
607 connection
->message_cur
= 0;
608 connection
->datagram_callback(connection
);
609 // Caller is expected to consume the message, we are immediately ready for the next read.
610 connection
->message_length
= connection
->message_length_len
= 0;
617 tcp_send_response(comm_t
*comm
, message_t
*responding_to
, struct iovec
*iov
, int iov_len
)
620 struct iovec iovec
[4];
623 size_t payload_length
= 0;
626 // We don't anticipate ever needing more than four hunks, but if we get more, handle then?
628 ERROR("tcp_send_response: too many io buffers");
629 close(comm
->io
.sock
);
634 iovec
[0].iov_base
= &lenbuf
[0];
635 iovec
[0].iov_len
= 2;
636 for (i
= 0; i
< iov_len
; i
++) {
637 iovec
[i
+ 1] = iov
[i
];
638 payload_length
+= iov
[i
].iov_len
;
640 lenbuf
[0] = payload_length
/ 256;
641 lenbuf
[1] = payload_length
& 0xff;
645 #define MSG_NOSIGNAL 0
647 if (comm
->tls_context
!= NULL
) {
649 status
= srp_tls_write(comm
, iovec
, iov_len
+ 1);
651 ERROR("TLS context not null with TLS excluded.");
656 memset(&mh
, 0, sizeof mh
);
657 mh
.msg_iov
= &iovec
[0];
658 mh
.msg_iovlen
= iov_len
+ 1;
661 status
= sendmsg(comm
->io
.sock
, &mh
, MSG_NOSIGNAL
);
663 if (status
< 0 || status
!= payload_length
) {
665 ERROR("tcp_send_response: write failed: %s", strerror(errno
));
667 ERROR("tcp_send_response: short write (%zd out of %zu bytes)", status
, payload_length
);
669 close(comm
->io
.sock
);
675 udp_send_message(comm_t
*comm
, addr_t
*source
, addr_t
*dest
, int ifindex
, struct iovec
*iov
, int iov_len
)
678 uint8_t cmsg_buf
[128];
679 struct cmsghdr
*cmsg
;
682 memset(&mh
, 0, sizeof mh
);
684 mh
.msg_iovlen
= iov_len
;
686 mh
.msg_control
= cmsg_buf
;
687 if (source
== NULL
&& ifindex
== 0) {
688 mh
.msg_controllen
= 0;
690 mh
.msg_controllen
= sizeof cmsg_buf
;
691 cmsg
= CMSG_FIRSTHDR(&mh
);
693 if (source
->sa
.sa_family
== AF_INET
) {
694 struct in_pktinfo
*inp
;
695 mh
.msg_namelen
= sizeof (struct sockaddr_in
);
696 mh
.msg_controllen
= CMSG_SPACE(sizeof *inp
);
697 cmsg
->cmsg_level
= IPPROTO_IP
;
698 cmsg
->cmsg_type
= IP_PKTINFO
;
699 cmsg
->cmsg_len
= CMSG_LEN(sizeof *inp
);
700 inp
= (struct in_pktinfo
*)CMSG_DATA(cmsg
);
701 memset(inp
, 0, sizeof *inp
);
702 inp
->ipi_ifindex
= ifindex
;
704 inp
->ipi_spec_dst
= source
->sin
.sin_addr
;
705 inp
->ipi_addr
= source
->sin
.sin_addr
;
707 } else if (source
->sa
.sa_family
== AF_INET6
) {
708 struct in6_pktinfo
*inp
;
709 mh
.msg_namelen
= sizeof (struct sockaddr_in6
);
710 mh
.msg_controllen
= CMSG_SPACE(sizeof *inp
);
711 cmsg
->cmsg_level
= IPPROTO_IPV6
;
712 cmsg
->cmsg_type
= IPV6_PKTINFO
;
713 cmsg
->cmsg_len
= CMSG_LEN(sizeof *inp
);
714 inp
= (struct in6_pktinfo
*)CMSG_DATA(cmsg
);
715 memset(inp
, 0, sizeof *inp
);
716 inp
->ipi6_ifindex
= ifindex
;
718 inp
->ipi6_addr
= source
->sin6
.sin6_addr
;
721 ERROR("udp_send_response: unknown family %d", source
->sa
.sa_family
);
725 status
= sendmsg(comm
->io
.sock
, &mh
, 0);
727 ERROR("udp_send_message: %s", strerror(errno
));
732 udp_send_response(comm_t
*comm
, message_t
*responding_to
, struct iovec
*iov
, int iov_len
)
734 udp_send_message(comm
, &responding_to
->local
, &responding_to
->src
, responding_to
->ifindex
, iov
, iov_len
);
738 udp_send_multicast(comm_t
*comm
, int ifindex
, struct iovec
*iov
, int iov_len
)
740 udp_send_message(comm
, NULL
, &comm
->multicast
, ifindex
, iov
, iov_len
);
744 udp_send_connected_response(comm_t
*comm
, message_t
*responding_to
, struct iovec
*iov
, int iov_len
)
746 int status
= writev(comm
->io
.sock
, iov
, iov_len
);
749 ERROR("udp_send_connected: %s", strerror(errno
));
753 // When a communication is closed, scan the io event list to see if any other ios are referencing this one.
755 comm_finalize(io_t
*io_in
)
757 comm_t
*comm
= (comm_t
*)io_in
;
762 comm_valid(comm_t
*comm
)
764 if (comm
->io
.sock
!= -1) {
771 comm_close(comm_t
*comm
)
773 close(comm
->io
.sock
);
778 listen_callback(io_t
*context
)
780 comm_t
*listener
= (comm_t
*)context
;
783 socklen_t addr_len
= sizeof addr
;
785 char addrbuf
[INET6_ADDRSTRLEN
+ 7];
788 rv
= accept(listener
->io
.sock
, &addr
.sa
, &addr_len
);
790 ERROR("accept: %s", strerror(errno
));
791 close(listener
->io
.sock
);
792 listener
->io
.sock
= -1;
795 inet_ntop(addr
.sa
.sa_family
, (addr
.sa
.sa_family
== AF_INET
796 ? (void *)&addr
.sin
.sin_addr
797 : (void *)&addr
.sin6
.sin6_addr
), addrbuf
, sizeof addrbuf
);
798 addrlen
= strlen(addrbuf
);
799 snprintf(&addrbuf
[addrlen
], (sizeof addrbuf
) - addrlen
, "%%%d",
800 ntohs((addr
.sa
.sa_family
== AF_INET
? addr
.sin
.sin_port
: addr
.sin6
.sin6_port
)));
801 comm
= calloc(1, sizeof *comm
);
802 comm
->name
= strdup(addrbuf
);
804 comm
->io
.container
= comm
;
805 comm
->address
= addr
;
806 comm
->datagram_callback
= listener
->datagram_callback
;
807 comm
->send_response
= tcp_send_response
;
808 comm
->tcp_stream
= true;
810 if (listener
->tls_context
== (tls_context_t
*)-1) {
812 if (!srp_tls_listen_callback(comm
)) {
813 ERROR("TLS setup failed.");
814 close(comm
->io
.sock
);
819 ERROR("TLS context not null in listen_callback when TLS excluded.");
823 if (listener
->connected
) {
824 listener
->connected(comm
);
826 ioloop_add_reader(&comm
->io
, tcp_read_callback
, listener
->connection_finalize
);
830 rv
= setsockopt(comm
->io
.sock
, SOL_SOCKET
, SO_NOSIGPIPE
, &one
, sizeof one
);
832 ERROR("SO_NOSIGPIPE failed: %s", strerror(errno
));
838 ioloop_setup_listener(int family
, bool stream
, bool tls
, uint16_t port
, const char *ip_address
, const char *multicast
,
839 const char *name
, comm_callback_t datagram_callback
,
840 comm_callback_t connected
, comm_callback_t disconnected
,
841 io_callback_t finalize
, io_callback_t connection_finalize
, void *context
)
849 listener
= calloc(1, sizeof *listener
);
850 if (listener
== NULL
) {
853 listener
->io
.container
= listener
;
854 listener
->name
= strdup(name
);
855 if (!listener
->name
) {
859 listener
->io
.sock
= socket(family
, stream
? SOCK_STREAM
: SOCK_DGRAM
, stream
? IPPROTO_TCP
: IPPROTO_UDP
);
860 if (listener
->io
.sock
< 0) {
861 ERROR("Can't get socket: %s", strerror(errno
));
864 rv
= setsockopt(listener
->io
.sock
, SOL_SOCKET
, SO_REUSEADDR
, &true_flag
, sizeof true_flag
);
866 ERROR("SO_REUSEADDR failed: %s", strerror(errno
));
870 rv
= setsockopt(listener
->io
.sock
, SOL_SOCKET
, SO_REUSEPORT
, &true_flag
, sizeof true_flag
);
872 ERROR("SO_REUSEPORT failed: %s", strerror(errno
));
876 if (ip_address
!= NULL
) {
877 sl
= getipaddr(&listener
->address
, ip_address
);
881 if (family
== AF_UNSPEC
) {
882 family
= listener
->address
.sa
.sa_family
;
883 } else if (listener
->address
.sa
.sa_family
!= family
) {
884 ERROR("%s is not a %s address.", ip_address
, family
== AF_INET
? "IPv4" : "IPv6");
889 if (multicast
!= 0) {
891 ERROR("Unable to do non-datagram multicast.");
894 sl
= getipaddr(&listener
->multicast
, multicast
);
898 if (listener
->multicast
.sa
.sa_family
!= family
) {
899 ERROR("multicast address %s from different family than listen address %s.", multicast
, ip_address
);
902 listener
->is_multicast
= true;
904 if (family
== AF_INET
) {
907 im
.imr_multiaddr
= listener
->multicast
.sin
.sin_addr
;
908 im
.imr_interface
.s_addr
= 0;
909 rv
= setsockopt(listener
->io
.sock
, IPPROTO_IP
, IP_ADD_MEMBERSHIP
, &im
, sizeof im
);
911 ERROR("Unable to join %s multicast group: %s", multicast
, strerror(errno
));
914 rv
= setsockopt(listener
->io
.sock
, IPPROTO_IP
, IP_MULTICAST_TTL
, &ttl
, sizeof ttl
);
916 ERROR("Unable to set IP multicast TTL to 255 for %s: %s", multicast
, strerror(errno
));
919 rv
= setsockopt(listener
->io
.sock
, IPPROTO_IP
, IP_TTL
, &ttl
, sizeof ttl
);
921 ERROR("Unable to set IP TTL to 255 for %s: %s", multicast
, strerror(errno
));
924 rv
= setsockopt(listener
->io
.sock
, IPPROTO_IP
, IP_MULTICAST_LOOP
, &false_flag
, sizeof false_flag
);
926 ERROR("Unable to set IP Multcast loopback to false for %s: %s", multicast
, strerror(errno
));
932 im
.ipv6mr_multiaddr
= listener
->multicast
.sin6
.sin6_addr
;
933 im
.ipv6mr_interface
= 0;
934 rv
= setsockopt(listener
->io
.sock
, IPPROTO_IPV6
, IPV6_JOIN_GROUP
, &im
, sizeof im
);
936 ERROR("Unable to join %s multicast group: %s", multicast
, strerror(errno
));
939 rv
= setsockopt(listener
->io
.sock
, IPPROTO_IPV6
, IPV6_MULTICAST_HOPS
, &hops
, sizeof hops
);
941 ERROR("Unable to set IPv6 multicast hops to 255 for %s: %s", multicast
, strerror(errno
));
944 rv
= setsockopt(listener
->io
.sock
, IPPROTO_IPV6
, IPV6_UNICAST_HOPS
, &hops
, sizeof hops
);
946 ERROR("Unable to set IPv6 hops to 255 for %s: %s", multicast
, strerror(errno
));
949 rv
= setsockopt(listener
->io
.sock
, IPPROTO_IPV6
, IPV6_MULTICAST_LOOP
, &false_flag
, sizeof false_flag
);
951 ERROR("Unable to set IPv6 Multcast loopback to false for %s: %s", multicast
, strerror(errno
));
957 if (family
== AF_INET
) {
958 sl
= sizeof listener
->address
.sin
;
959 listener
->address
.sin
.sin_port
= port
? htons(port
) : htons(53);
961 sl
= sizeof listener
->address
.sin6
;
962 listener
->address
.sin6
.sin6_port
= port
? htons(port
) : htons(53);
963 // Don't use a dual-stack socket.
964 rv
= setsockopt(listener
->io
.sock
, IPPROTO_IPV6
, IPV6_V6ONLY
, &true_flag
, sizeof true_flag
);
966 ERROR("Unable to set IPv6-only flag on %s socket for %s",
967 tls
? "TLS" : (stream
? "TCP" : "UDP"), ip_address
== NULL
? "<0>" : ip_address
);
972 listener
->address
.sa
.sa_family
= family
;
973 #ifndef NOT_HAVE_SA_LEN
974 listener
->address
.sa
.sa_len
= sl
;
976 if (bind(listener
->io
.sock
, &listener
->address
.sa
, sl
) < 0) {
977 ERROR("Can't bind to %s#%d/%s%s: %s", ip_address
== NULL
? "<0>" : ip_address
, port
,
978 stream
? "tcp" : "udp", family
== AF_INET
? "v4" : "v6",
981 close(listener
->io
.sock
);
989 ERROR("Asked to do TLS over UDP, which we don't do yet.");
992 listener
->tls_context
= (tls_context_t
*)-1;
994 ERROR("TLS requested when TLS is excluded.");
1000 if (listen(listener
->io
.sock
, 5 /* xxx */) < 0) {
1001 ERROR("Can't listen on %s#%d/%s%s: %s", ip_address
== NULL
? "<0>" : ip_address
, ntohs(port
),
1002 tls
? "tls" : "tcp", family
== AF_INET
? "v4" : "v6",
1006 listener
->connection_finalize
= connection_finalize
;
1007 ioloop_add_reader(&listener
->io
, listen_callback
, finalize
);
1009 rv
= setsockopt(listener
->io
.sock
, family
== AF_INET
? IPPROTO_IP
: IPPROTO_IPV6
,
1010 family
== AF_INET
? IP_PKTINFO
: IPV6_RECVPKTINFO
, &true_flag
, sizeof true_flag
);
1012 ERROR("Can't set %s: %s.", family
== AF_INET
? "IP_PKTINFO" : "IPV6_RECVPKTINFO",
1016 ioloop_add_reader(&listener
->io
, udp_read_callback
, finalize
);
1017 listener
->send_response
= udp_send_response
;
1018 listener
->send_message
= udp_send_message
;
1019 if (listener
->is_multicast
) {
1020 listener
->send_multicast
= udp_send_multicast
;
1023 listener
->datagram_callback
= datagram_callback
;
1024 listener
->connected
= connected
;
1029 connect_callback(io_t
*context
)
1032 socklen_t len
= sizeof result
;
1033 comm_t
*connection
= (comm_t
*)context
;
1035 // If connect failed, indicate that it failed.
1036 if (getsockopt(context
->sock
, SOL_SOCKET
, SO_ERROR
, &result
, &len
) < 0) {
1037 ERROR("connect_callback: unable to get connect error: socket %d: Error %d (%s)",
1038 context
->sock
, result
, strerror(result
));
1039 connection
->disconnected(connection
, result
);
1040 comm_close(connection
);
1044 // If this is a TLS connection, set up TLS.
1045 if (connection
->tls_context
== (tls_context_t
*)-1) {
1047 srp_tls_connect_callback(connection
);
1049 ERROR("connect_callback: tls_context triggered with TLS excluded.");
1050 connection
->disconnected(connection
, 0);
1051 comm_close(connection
);
1056 connection
->send_response
= tcp_send_response
;
1057 connection
->connected(connection
);
1058 drop_writer(&connection
->io
);
1059 ioloop_add_reader(&connection
->io
, tcp_read_callback
, connection
->io
.finalize
);
1062 // Currently we don't do DNS lookups, despite the host identifier being an IP address.
1064 ioloop_connect(addr_t
*NONNULL remote_address
, bool tls
, bool stream
,
1065 comm_callback_t datagram_callback
, comm_callback_t connected
,
1066 disconnect_callback_t disconnected
, io_callback_t finalize
, void *context
)
1070 char buf
[INET6_ADDRSTRLEN
+ 7];
1073 if (!stream
&& (connected
!= NULL
|| disconnected
!= NULL
)) {
1074 ERROR("connected and disconnected callbacks not valid for datagram connections");
1077 if (stream
&& (connected
== NULL
|| disconnected
== NULL
)) {
1078 ERROR("connected and disconnected callbacks are required for stream connections");
1081 connection
= calloc(1, sizeof *connection
);
1082 if (connection
== NULL
) {
1083 ERROR("No memory for connection structure.");
1086 connection
->io
.container
= connection
;
1087 if (inet_ntop(remote_address
->sa
.sa_family
, (remote_address
->sa
.sa_family
== AF_INET
1088 ? (void *)&remote_address
->sin
.sin_addr
1089 : (void *)&remote_address
->sin6
.sin6_addr
), buf
,
1090 INET6_ADDRSTRLEN
) == NULL
) {
1091 ERROR("inet_ntop failed to convert remote address: %s", strerror(errno
));
1095 s
= buf
+ strlen(buf
);
1096 sprintf(s
, "%%%hu", ntohs(remote_address
->sa
.sa_family
== AF_INET
1097 ? remote_address
->sin
.sin_port
1098 : remote_address
->sin6
.sin6_port
));
1099 connection
->name
= strdup(buf
);
1100 if (!connection
->name
) {
1104 connection
->io
.sock
= socket(remote_address
->sa
.sa_family
,
1105 stream
? SOCK_STREAM
: SOCK_DGRAM
, stream
? IPPROTO_TCP
: IPPROTO_UDP
);
1106 if (connection
->io
.sock
< 0) {
1107 ERROR("Can't get socket: %s", strerror(errno
));
1108 comm_free(connection
);
1111 connection
->address
= *remote_address
;
1112 if (fcntl(connection
->io
.sock
, F_SETFL
, O_NONBLOCK
) < 0) {
1113 ERROR("connect_to_host: %s: Can't set O_NONBLOCK: %s", connection
->name
, strerror(errno
));
1114 comm_free(connection
);
1117 #ifdef NOT_HAVE_SA_LEN
1118 sl
= (remote_address
->sa
.sa_family
== AF_INET
1119 ? sizeof remote_address
->sin
1120 : sizeof remote_address
->sin6
);
1122 sl
= remote_address
->sa
.sa_len
;
1124 // Connect to the host
1125 if (connect(connection
->io
.sock
, &connection
->address
.sa
, sl
) < 0) {
1126 if (errno
!= EINPROGRESS
&& errno
!= EAGAIN
) {
1127 ERROR("Can't connect to %s: %s", connection
->name
, strerror(errno
));
1128 comm_free(connection
);
1132 // At this point if we are doing TCP, we do not yet have a connection, but the connection should be in
1133 // progress, and we should get a write select event when the connection succeeds or fails.
1134 // UDP is connectionless, so the connect() call just sets the default destination for send() on
1138 #ifndef TLS_EXCLUDED
1139 connection
->tls_context
= (tls_context_t
*)-1;
1141 ERROR("connect_to_host: tls requested when excluded.");
1142 comm_free(connection
);
1147 connection
->connected
= connected
;
1148 connection
->disconnected
= disconnected
;
1149 connection
->datagram_callback
= datagram_callback
;
1150 connection
->context
= context
;
1152 connection
->send_response
= udp_send_connected_response
;
1153 ioloop_add_reader(&connection
->io
, udp_read_callback
, finalize
);
1155 ioloop_add_writer(&connection
->io
, connect_callback
, finalize
);
1161 typedef struct interface_addr interface_addr_t
;
1162 struct interface_addr
{
1163 interface_addr_t
*next
;
1169 interface_addr_t
*interface_addresses
;
1172 ioloop_map_interface_addresses(void *context
, interface_callback_t callback
)
1174 struct ifaddrs
*ifaddrs
, *ifp
;
1175 interface_addr_t
*kept_ifaddrs
= NULL
, **ki_end
= &kept_ifaddrs
;
1176 interface_addr_t
*new_ifaddrs
= NULL
, **ni_end
= &new_ifaddrs
;
1177 interface_addr_t
**ip
, *nif
;
1178 char *ifname
= NULL
;
1181 if (getifaddrs(&ifaddrs
) < 0) {
1182 ERROR("getifaddrs failed: %s", strerror(errno
));
1186 for (ifp
= ifaddrs
; ifp
; ifp
= ifp
->ifa_next
) {
1187 // Is this an interface address we can use?
1188 if (ifp
->ifa_addr
!= NULL
&& ifp
->ifa_netmask
!= NULL
&&
1189 (ifp
->ifa_addr
->sa_family
== AF_INET
||
1190 ifp
->ifa_addr
->sa_family
== AF_INET6
) &&
1191 (ifp
->ifa_flags
& IFF_UP
) &&
1192 !(ifp
->ifa_flags
& IFF_POINTOPOINT
))
1195 for (ip
= &interface_addresses
; *ip
!= NULL
; ) {
1196 interface_addr_t
*ia
= *ip
;
1197 // Same interface and address?
1198 if (!strcmp(ia
->name
, ifp
->ifa_name
) &&
1199 ifp
->ifa_addr
->sa_family
== ia
->addr
.sa
.sa_family
&&
1200 ((ifp
->ifa_addr
->sa_family
== AF_INET
&&
1201 ((struct sockaddr_in
*)ifp
->ifa_addr
)->sin_addr
.s_addr
== ia
->addr
.sin
.sin_addr
.s_addr
) ||
1202 (ifp
->ifa_addr
->sa_family
== AF_INET6
&&
1203 !memcmp(&((struct sockaddr_in6
*)ifp
->ifa_addr
)->sin6_addr
,
1204 &ia
->addr
.sin6
.sin6_addr
, sizeof ia
->addr
.sin6
.sin6_addr
))) &&
1205 ((ifp
->ifa_netmask
->sa_family
== AF_INET
&&
1206 ((struct sockaddr_in
*)ifp
->ifa_netmask
)->sin_addr
.s_addr
== ia
->mask
.sin
.sin_addr
.s_addr
) ||
1207 (ifp
->ifa_netmask
->sa_family
== AF_INET6
&&
1208 !memcmp(&((struct sockaddr_in6
*)ifp
->ifa_netmask
)->sin6_addr
,
1209 &ia
->mask
.sin6
.sin6_addr
, sizeof ia
->mask
.sin6
.sin6_addr
))))
1219 // If keep is false, this is a new interface.
1221 nif
= calloc(1, strlen(ifp
->ifa_name
) + 1 + sizeof *nif
);
1222 // We don't have a way to fix nif being null; what this means is that we don't detect a new
1223 // interface address.
1225 nif
->name
= (char *)(nif
+ 1);
1226 strcpy(nif
->name
, ifp
->ifa_name
);
1227 if (ifp
->ifa_addr
->sa_family
== AF_INET
) {
1228 nif
->addr
.sin
= *((struct sockaddr_in
*)ifp
->ifa_addr
);
1229 nif
->mask
.sin
= *((struct sockaddr_in
*)ifp
->ifa_netmask
);
1231 nif
->addr
.sin6
= *((struct sockaddr_in6
*)ifp
->ifa_addr
);
1232 nif
->mask
.sin6
= *((struct sockaddr_in6
*)ifp
->ifa_netmask
);
1235 ni_end
= &nif
->next
;
1241 // Report and free deleted interface addresses...
1242 for (nif
= interface_addresses
; nif
; ) {
1243 interface_addr_t
*next
= nif
->next
;
1244 callback(context
, nif
->name
, &nif
->addr
, &nif
->mask
, nif
->index
, interface_address_deleted
);
1249 // Report added interface addresses...
1250 for (nif
= new_ifaddrs
; nif
; nif
= nif
->next
) {
1251 // Get interface index using standard API if AF_LINK didn't work.
1252 if (nif
->index
== 0) {
1253 if (ifindex
!= 0 && ifname
!= NULL
&& !strcmp(ifname
, nif
->name
)) {
1254 nif
->index
= ifindex
;
1257 ifindex
= if_nametoindex(nif
->name
);
1258 nif
->index
= ifindex
;
1259 INFO("Got interface index for " PUB_S_SRP
" the hard way: %d", nif
->name
, nif
->index
);
1262 callback(context
, nif
->name
, &nif
->addr
, &nif
->mask
, nif
->index
, interface_address_added
);
1265 // Restore kept interface addresses and append new addresses to the list.
1266 interface_addresses
= kept_ifaddrs
;
1267 for (ip
= &new_ifaddrs
; *ip
; ip
= &(*ip
)->next
)
1273 // Invoke the specified executable with the specified arguments. Call callback when it exits.
1274 // All failures are reported through the callback.
1276 ioloop_subproc(const char *exepath
, char *NULLABLE
*argv
, int argc
, subproc_callback_t callback
)
1278 subproc_t
*subproc
= calloc(1, sizeof *subproc
);
1282 if (subproc
== NULL
) {
1283 callback(NULL
, 0, "out of memory");
1286 if (argc
> MAX_SUBPROC_ARGS
) {
1287 callback(NULL
, 0, "too many subproc args");
1288 subproc_free(subproc
);
1292 subproc
->argv
[0] = strdup(exepath
);
1293 if (subproc
->argv
[0] == NULL
) {
1294 subproc_free(subproc
);
1298 for (i
= 0; i
< argc
; i
++) {
1299 subproc
->argv
[i
+ 1] = strdup(argv
[i
]);
1300 if (subproc
->argv
[i
+ 1] == NULL
) {
1301 subproc_free(subproc
);
1308 execv(exepath
, subproc
->argv
);
1313 callback(subproc
, 0, strerror(errno
));
1314 subproc_free(subproc
);
1318 subproc
->callback
= callback
;
1320 subproc
->next
= subprocesses
;
1321 subprocesses
= subproc
;
1326 dnssd_txn_callback(io_t
*io
)
1328 dnssd_txn_t
*txn
= (dnssd_txn_t
*)io
;
1329 int status
= DNSServiceProcessResult(txn
->sdref
);
1330 if (status
!= kDNSServiceErr_NoError
) {
1331 if (txn
->close_callback
!= NULL
) {
1332 txn
->close_callback(txn
->context
, status
);
1338 dnssd_txn_finalize(io_t
*io
)
1340 dnssd_txn_t
*txn
= (dnssd_txn_t
*)io
;
1342 if (txn
->finalize_callback
) {
1343 txn
->finalize_callback(txn
->context
);
1348 ioloop_dnssd_txn_add(DNSServiceRef ref
,
1349 dnssd_txn_finalize_callback_t finalize_callback
, dnssd_txn_close_callback_t close_callback
)
1351 dnssd_txn_t
*txn
= calloc(1, sizeof(*txn
));
1355 txn
->io
.sock
= DNSServiceRefSockFD(txn
->sdref
);
1356 txn
->finalize_callback
= finalize_callback
;
1357 txn
->close_callback
= close_callback
;
1358 ioloop_add_reader(&txn
->io
, dnssd_txn_callback
, dnssd_txn_finalize
);
1366 // c-file-style: "bsd"
1367 // c-basic-offset: 4
1369 // indent-tabs-mode: nil