1 /* $OpenBSD: frontend.c,v 1.18 2019/03/24 17:55:58 florian Exp $ */ 2 3 /* 4 * Copyright (c) 2018 Florian Obser <florian@openbsd.org> 5 * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> 6 * Copyright (c) 2004 Esben Norby <norby@openbsd.org> 7 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> 8 * 9 * Permission to use, copy, modify, and distribute this software for any 10 * purpose with or without fee is hereby granted, provided that the above 11 * copyright notice and this permission notice appear in all copies. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20 */ 21 22 #include <sys/types.h> 23 #include <sys/queue.h> 24 #include <sys/socket.h> 25 #include <sys/syslog.h> 26 #include <sys/uio.h> 27 28 #include <netinet/in.h> 29 #include <net/if.h> 30 #include <net/route.h> 31 32 #include <errno.h> 33 #include <event.h> 34 #include <imsg.h> 35 #include <netdb.h> 36 #include <pwd.h> 37 #include <signal.h> 38 #include <stdint.h> 39 #include <stdio.h> 40 #include <stdlib.h> 41 #include <string.h> 42 #include <time.h> 43 #include <unistd.h> 44 45 #include "libunbound/config.h" 46 #include "libunbound/sldns/pkthdr.h" 47 #include "libunbound/sldns/sbuffer.h" 48 #include "libunbound/sldns/str2wire.h" 49 #include "libunbound/sldns/wire2str.h" 50 51 #include "log.h" 52 #include "unwind.h" 53 #include "frontend.h" 54 #include "control.h" 55 56 #define ROUTE_SOCKET_BUF_SIZE 16384 57 58 struct udp_ev { 59 struct event ev; 60 uint8_t query[65536]; 61 struct msghdr rcvmhdr; 62 struct iovec rcviov[1]; 63 struct sockaddr_storage from; 64 } udp4ev, udp6ev; 65 66 struct pending_query { 67 TAILQ_ENTRY(pending_query) entry; 68 struct sockaddr_storage from; 69 uint8_t *query; 70 ssize_t len; 71 uint64_t imsg_id; 72 int fd; 73 int bogus; 74 }; 75 76 TAILQ_HEAD(, pending_query) pending_queries; 77 78 __dead void frontend_shutdown(void); 79 void frontend_sig_handler(int, short, void *); 80 void frontend_startup(void); 81 void udp_receive(int, short, void *); 82 void send_answer(struct pending_query *, uint8_t *, 83 ssize_t); 84 void route_receive(int, short, void *); 85 void handle_route_message(struct rt_msghdr *, 86 struct sockaddr **); 87 void get_rtaddrs(int, struct sockaddr *, 88 struct sockaddr **); 89 void rtmget_default(void); 90 struct pending_query *find_pending_query(uint64_t); 91 void parse_dhcp_lease(int); 92 void parse_trust_anchor(struct trust_anchor_head *, int); 93 void send_trust_anchors(struct trust_anchor_head *); 94 void write_trust_anchors(struct trust_anchor_head *, int); 95 96 struct uw_conf *frontend_conf; 97 struct imsgev *iev_main; 98 struct imsgev *iev_resolver; 99 struct imsgev *iev_captiveportal; 100 struct event ev_route; 101 int udp4sock = -1, udp6sock = -1, routesock = -1; 102 int ta_fd = -1; 103 104 static struct trust_anchor_head built_in_trust_anchors; 105 static struct trust_anchor_head trust_anchors, new_trust_anchors; 106 107 void 108 frontend_sig_handler(int sig, short event, void *bula) 109 { 110 /* 111 * Normal signal handler rules don't apply because libevent 112 * decouples for us. 113 */ 114 115 switch (sig) { 116 case SIGINT: 117 case SIGTERM: 118 frontend_shutdown(); 119 default: 120 fatalx("unexpected signal"); 121 } 122 } 123 124 void 125 frontend(int debug, int verbose) 126 { 127 struct event ev_sigint, ev_sigterm; 128 struct passwd *pw; 129 size_t rcvcmsglen, sndcmsgbuflen; 130 uint8_t *rcvcmsgbuf; 131 uint8_t *sndcmsgbuf = NULL; 132 133 frontend_conf = config_new_empty(); 134 control_state.fd = -1; 135 136 log_init(debug, LOG_DAEMON); 137 log_setverbose(verbose); 138 139 if ((pw = getpwnam(UNWIND_USER)) == NULL) 140 fatal("getpwnam"); 141 142 if (chroot(pw->pw_dir) == -1) 143 fatal("chroot"); 144 if (chdir("/") == -1) 145 fatal("chdir(\"/\")"); 146 147 uw_process = PROC_FRONTEND; 148 setproctitle("%s", log_procnames[uw_process]); 149 log_procinit(log_procnames[uw_process]); 150 151 if (setgroups(1, &pw->pw_gid) || 152 setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || 153 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) 154 fatal("can't drop privileges"); 155 156 if (pledge("stdio unix recvfd", NULL) == -1) 157 fatal("pledge"); 158 159 event_init(); 160 161 /* Setup signal handler. */ 162 signal_set(&ev_sigint, SIGINT, frontend_sig_handler, NULL); 163 signal_set(&ev_sigterm, SIGTERM, frontend_sig_handler, NULL); 164 signal_add(&ev_sigint, NULL); 165 signal_add(&ev_sigterm, NULL); 166 signal(SIGPIPE, SIG_IGN); 167 signal(SIGHUP, SIG_IGN); 168 169 /* Setup pipe and event handler to the parent process. */ 170 if ((iev_main = malloc(sizeof(struct imsgev))) == NULL) 171 fatal(NULL); 172 imsg_init(&iev_main->ibuf, 3); 173 iev_main->handler = frontend_dispatch_main; 174 iev_main->events = EV_READ; 175 event_set(&iev_main->ev, iev_main->ibuf.fd, iev_main->events, 176 iev_main->handler, iev_main); 177 event_add(&iev_main->ev, NULL); 178 179 rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + 180 CMSG_SPACE(sizeof(int)); 181 if((rcvcmsgbuf = malloc(rcvcmsglen)) == NULL) 182 fatal("malloc"); 183 184 udp4ev.rcviov[0].iov_base = (caddr_t)udp4ev.query; 185 udp4ev.rcviov[0].iov_len = sizeof(udp4ev.query); 186 udp4ev.rcvmhdr.msg_name = (caddr_t)&udp4ev.from; 187 udp4ev.rcvmhdr.msg_namelen = sizeof(udp4ev.from); 188 udp4ev.rcvmhdr.msg_iov = udp4ev.rcviov; 189 udp4ev.rcvmhdr.msg_iovlen = 1; 190 191 udp6ev.rcviov[0].iov_base = (caddr_t)udp6ev.query; 192 udp6ev.rcviov[0].iov_len = sizeof(udp6ev.query); 193 udp6ev.rcvmhdr.msg_name = (caddr_t)&udp6ev.from; 194 udp6ev.rcvmhdr.msg_namelen = sizeof(udp6ev.from); 195 udp6ev.rcvmhdr.msg_iov = udp6ev.rcviov; 196 udp6ev.rcvmhdr.msg_iovlen = 1; 197 198 sndcmsgbuflen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + 199 CMSG_SPACE(sizeof(int)); 200 if ((sndcmsgbuf = malloc(sndcmsgbuflen)) == NULL) 201 fatal("%s", __func__); 202 203 TAILQ_INIT(&pending_queries); 204 205 TAILQ_INIT(&built_in_trust_anchors); 206 TAILQ_INIT(&trust_anchors); 207 TAILQ_INIT(&new_trust_anchors); 208 209 add_new_ta(&built_in_trust_anchors, KSK2017); 210 211 event_dispatch(); 212 213 frontend_shutdown(); 214 } 215 216 __dead void 217 frontend_shutdown(void) 218 { 219 /* Close pipes. */ 220 msgbuf_write(&iev_resolver->ibuf.w); 221 msgbuf_clear(&iev_resolver->ibuf.w); 222 close(iev_resolver->ibuf.fd); 223 msgbuf_write(&iev_captiveportal->ibuf.w); 224 msgbuf_clear(&iev_captiveportal->ibuf.w); 225 close(iev_captiveportal->ibuf.fd); 226 msgbuf_write(&iev_main->ibuf.w); 227 msgbuf_clear(&iev_main->ibuf.w); 228 close(iev_main->ibuf.fd); 229 230 config_clear(frontend_conf); 231 232 free(iev_resolver); 233 free(iev_captiveportal); 234 free(iev_main); 235 236 log_info("frontend exiting"); 237 exit(0); 238 } 239 240 int 241 frontend_imsg_compose_main(int type, pid_t pid, void *data, uint16_t datalen) 242 { 243 return (imsg_compose_event(iev_main, type, 0, pid, -1, data, datalen)); 244 } 245 246 int 247 frontend_imsg_compose_resolver(int type, pid_t pid, void *data, 248 uint16_t datalen) 249 { 250 return (imsg_compose_event(iev_resolver, type, 0, pid, -1, data, 251 datalen)); 252 } 253 254 int 255 frontend_imsg_compose_captiveportal(int type, pid_t pid, void *data, 256 uint16_t datalen) 257 { 258 return (imsg_compose_event(iev_captiveportal, type, 0, pid, -1, data, 259 datalen)); 260 } 261 262 void 263 frontend_dispatch_main(int fd, short event, void *bula) 264 { 265 static struct uw_conf *nconf; 266 struct uw_forwarder *uw_forwarder; 267 struct imsg imsg; 268 struct imsgev *iev = bula; 269 struct imsgbuf *ibuf = &iev->ibuf; 270 int n, shut = 0; 271 272 if (event & EV_READ) { 273 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) 274 fatal("imsg_read error"); 275 if (n == 0) /* Connection closed. */ 276 shut = 1; 277 } 278 if (event & EV_WRITE) { 279 if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN) 280 fatal("msgbuf_write"); 281 if (n == 0) /* Connection closed. */ 282 shut = 1; 283 } 284 285 for (;;) { 286 if ((n = imsg_get(ibuf, &imsg)) == -1) 287 fatal("%s: imsg_get error", __func__); 288 if (n == 0) /* No more messages. */ 289 break; 290 291 switch (imsg.hdr.type) { 292 case IMSG_SOCKET_IPC_RESOLVER: 293 /* 294 * Setup pipe and event handler to the resolver 295 * process. 296 */ 297 if (iev_resolver) { 298 fatalx("%s: received unexpected imsg fd " 299 "to frontend", __func__); 300 break; 301 } 302 if ((fd = imsg.fd) == -1) { 303 fatalx("%s: expected to receive imsg fd to " 304 "frontend but didn't receive any", 305 __func__); 306 break; 307 } 308 309 iev_resolver = malloc(sizeof(struct imsgev)); 310 if (iev_resolver == NULL) 311 fatal(NULL); 312 313 imsg_init(&iev_resolver->ibuf, fd); 314 iev_resolver->handler = frontend_dispatch_resolver; 315 iev_resolver->events = EV_READ; 316 317 event_set(&iev_resolver->ev, iev_resolver->ibuf.fd, 318 iev_resolver->events, iev_resolver->handler, 319 iev_resolver); 320 event_add(&iev_resolver->ev, NULL); 321 break; 322 case IMSG_SOCKET_IPC_CAPTIVEPORTAL: 323 /* 324 * Setup pipe and event handler to the captiveportal 325 * process. 326 */ 327 if (iev_captiveportal) { 328 fatalx("%s: received unexpected imsg fd " 329 "to frontend", __func__); 330 break; 331 } 332 if ((fd = imsg.fd) == -1) { 333 fatalx("%s: expected to receive imsg fd to " 334 "frontend but didn't receive any", 335 __func__); 336 break; 337 } 338 339 iev_captiveportal = malloc(sizeof(struct imsgev)); 340 if (iev_captiveportal == NULL) 341 fatal(NULL); 342 343 imsg_init(&iev_captiveportal->ibuf, fd); 344 iev_captiveportal->handler = 345 frontend_dispatch_captiveportal; 346 iev_captiveportal->events = EV_READ; 347 348 event_set(&iev_captiveportal->ev, 349 iev_captiveportal->ibuf.fd, 350 iev_captiveportal->events, 351 iev_captiveportal->handler, iev_captiveportal); 352 event_add(&iev_captiveportal->ev, NULL); 353 break; 354 case IMSG_RECONF_CONF: 355 if (nconf != NULL) 356 fatalx("%s: IMSG_RECONF_CONF already in " 357 "progress", __func__); 358 if (IMSG_DATA_SIZE(imsg) != sizeof(struct uw_conf)) 359 fatalx("%s: IMSG_RECONF_CONF wrong length: %lu", 360 __func__, IMSG_DATA_SIZE(imsg)); 361 if ((nconf = malloc(sizeof(struct uw_conf))) == NULL) 362 fatal(NULL); 363 memcpy(nconf, imsg.data, sizeof(struct uw_conf)); 364 nconf->captive_portal_host = NULL; 365 nconf->captive_portal_path = NULL; 366 nconf->captive_portal_expected_response = NULL; 367 SIMPLEQ_INIT(&nconf->uw_forwarder_list); 368 SIMPLEQ_INIT(&nconf->uw_dot_forwarder_list); 369 break; 370 case IMSG_RECONF_CAPTIVE_PORTAL_HOST: 371 /* make sure this is a string */ 372 ((char *)imsg.data)[IMSG_DATA_SIZE(imsg) - 1] = '\0'; 373 if ((nconf->captive_portal_host = strdup(imsg.data)) == 374 NULL) 375 fatal("%s: strdup", __func__); 376 break; 377 case IMSG_RECONF_CAPTIVE_PORTAL_PATH: 378 /* make sure this is a string */ 379 ((char *)imsg.data)[IMSG_DATA_SIZE(imsg) - 1] = '\0'; 380 if ((nconf->captive_portal_path = strdup(imsg.data)) == 381 NULL) 382 fatal("%s: strdup", __func__); 383 break; 384 case IMSG_RECONF_CAPTIVE_PORTAL_EXPECTED_RESPONSE: 385 /* make sure this is a string */ 386 ((char *)imsg.data)[IMSG_DATA_SIZE(imsg) - 1] = '\0'; 387 if ((nconf->captive_portal_expected_response = 388 strdup(imsg.data)) == NULL) 389 fatal("%s: strdup", __func__); 390 break; 391 case IMSG_RECONF_FORWARDER: 392 if (IMSG_DATA_SIZE(imsg) != sizeof(struct uw_forwarder)) 393 fatalx("%s: IMSG_RECONF_FORWARDER wrong length:" 394 " %lu", __func__, IMSG_DATA_SIZE(imsg)); 395 if ((uw_forwarder = malloc(sizeof(struct 396 uw_forwarder))) == NULL) 397 fatal(NULL); 398 memcpy(uw_forwarder, imsg.data, sizeof(struct 399 uw_forwarder)); 400 SIMPLEQ_INSERT_TAIL(&nconf->uw_forwarder_list, 401 uw_forwarder, entry); 402 break; 403 case IMSG_RECONF_DOT_FORWARDER: 404 if (IMSG_DATA_SIZE(imsg) != sizeof(struct uw_forwarder)) 405 fatalx("%s: IMSG_RECONF_DOT_FORWARDER wrong " 406 "length: %lu", __func__, 407 IMSG_DATA_SIZE(imsg)); 408 if ((uw_forwarder = malloc(sizeof(struct 409 uw_forwarder))) == NULL) 410 fatal(NULL); 411 memcpy(uw_forwarder, imsg.data, sizeof(struct 412 uw_forwarder)); 413 SIMPLEQ_INSERT_TAIL(&nconf->uw_dot_forwarder_list, 414 uw_forwarder, entry); 415 break; 416 case IMSG_RECONF_END: 417 if (nconf == NULL) 418 fatalx("%s: IMSG_RECONF_END without " 419 "IMSG_RECONF_CONF", __func__); 420 merge_config(frontend_conf, nconf); 421 nconf = NULL; 422 break; 423 case IMSG_UDP6SOCK: 424 if (udp6sock != -1) 425 fatalx("%s: received unexpected udp6sock", 426 __func__); 427 if ((udp6sock = imsg.fd) == -1) 428 fatalx("%s: expected to receive imsg " 429 "UDP6 fd but didn't receive any", __func__); 430 event_set(&udp6ev.ev, udp6sock, EV_READ | EV_PERSIST, 431 udp_receive, &udp6ev); 432 event_add(&udp6ev.ev, NULL); 433 break; 434 case IMSG_UDP4SOCK: 435 if (udp4sock != -1) 436 fatalx("%s: received unexpected udp4sock", 437 __func__); 438 if ((udp4sock = imsg.fd) == -1) 439 fatalx("%s: expected to receive imsg " 440 "UDP4 fd but didn't receive any", __func__); 441 event_set(&udp4ev.ev, udp4sock, EV_READ | EV_PERSIST, 442 udp_receive, &udp4ev); 443 event_add(&udp4ev.ev, NULL); 444 break; 445 case IMSG_ROUTESOCK: 446 if (routesock != -1) 447 fatalx("%s: received unexpected routesock", 448 __func__); 449 if ((fd = imsg.fd) == -1) 450 fatalx("%s: expected to receive imsg " 451 "routesocket fd but didn't receive any", 452 __func__); 453 routesock = fd; 454 event_set(&ev_route, fd, EV_READ | EV_PERSIST, 455 route_receive, NULL); 456 break; 457 case IMSG_STARTUP: 458 frontend_startup(); 459 break; 460 case IMSG_CONTROLFD: 461 if (control_state.fd != -1) 462 fatalx("%s: received unexpected controlsock", 463 __func__); 464 if ((fd = imsg.fd) == -1) 465 fatalx("%s: expected to receive imsg control " 466 "fd but didn't receive any", __func__); 467 control_state.fd = fd; 468 /* Listen on control socket. */ 469 TAILQ_INIT(&ctl_conns); 470 control_listen(); 471 break; 472 case IMSG_LEASEFD: 473 if ((fd = imsg.fd) == -1) 474 fatalx("%s: expected to receive imsg dhcp " 475 "lease fd but didn't receive any", __func__); 476 parse_dhcp_lease(fd); 477 break; 478 case IMSG_TAFD: 479 if ((ta_fd = imsg.fd) != -1) 480 parse_trust_anchor(&trust_anchors, ta_fd); 481 if (!TAILQ_EMPTY(&trust_anchors)) 482 send_trust_anchors(&trust_anchors); 483 else 484 send_trust_anchors(&built_in_trust_anchors); 485 break; 486 default: 487 log_debug("%s: error handling imsg %d", __func__, 488 imsg.hdr.type); 489 break; 490 } 491 imsg_free(&imsg); 492 } 493 if (!shut) 494 imsg_event_add(iev); 495 else { 496 /* This pipe is dead. Remove its event handler. */ 497 event_del(&iev->ev); 498 event_loopexit(NULL); 499 } 500 } 501 502 void 503 frontend_dispatch_resolver(int fd, short event, void *bula) 504 { 505 static struct pending_query *pq; 506 struct imsgev *iev = bula; 507 struct imsgbuf *ibuf = &iev->ibuf; 508 struct imsg imsg; 509 struct query_imsg *query_imsg; 510 int n, shut = 0, chg; 511 512 if (event & EV_READ) { 513 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) 514 fatal("imsg_read error"); 515 if (n == 0) /* Connection closed. */ 516 shut = 1; 517 } 518 if (event & EV_WRITE) { 519 if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN) 520 fatal("msgbuf_write"); 521 if (n == 0) /* Connection closed. */ 522 shut = 1; 523 } 524 525 for (;;) { 526 if ((n = imsg_get(ibuf, &imsg)) == -1) 527 fatal("%s: imsg_get error", __func__); 528 if (n == 0) /* No more messages. */ 529 break; 530 531 switch (imsg.hdr.type) { 532 case IMSG_ANSWER_HEADER: 533 if (IMSG_DATA_SIZE(imsg) != sizeof(*query_imsg)) 534 fatalx("%s: IMSG_ANSWER_HEADER wrong length: " 535 "%lu", __func__, IMSG_DATA_SIZE(imsg)); 536 query_imsg = (struct query_imsg *)imsg.data; 537 if ((pq = find_pending_query(query_imsg->id)) == 538 NULL) { 539 log_warnx("cannot find pending query %llu", 540 query_imsg->id); 541 break; 542 } 543 if (query_imsg->err) { 544 send_answer(pq, NULL, 0); 545 pq = NULL; 546 break; 547 } 548 pq->bogus = query_imsg->bogus; 549 break; 550 case IMSG_ANSWER: 551 if (pq == NULL) 552 fatalx("IMSG_ANSWER without HEADER"); 553 send_answer(pq, imsg.data, IMSG_DATA_SIZE(imsg)); 554 break; 555 case IMSG_RESOLVER_DOWN: 556 log_debug("%s: IMSG_RESOLVER_DOWN", __func__); 557 if (udp4sock != -1) { 558 event_del(&udp4ev.ev); 559 close(udp4sock); 560 udp4sock = -1; 561 } 562 if (udp6sock != -1) { 563 event_del(&udp6ev.ev); 564 close(udp6sock); 565 udp6sock = -1; 566 } 567 break; 568 case IMSG_RESOLVER_UP: 569 log_debug("%s: IMSG_RESOLVER_UP", __func__); 570 frontend_imsg_compose_main(IMSG_OPEN_PORTS, 0, NULL, 0); 571 break; 572 case IMSG_CTL_RESOLVER_INFO: 573 case IMSG_CTL_CAPTIVEPORTAL_INFO: 574 case IMSG_CTL_RESOLVER_WHY_BOGUS: 575 case IMSG_CTL_RESOLVER_HISTOGRAM: 576 case IMSG_CTL_END: 577 control_imsg_relay(&imsg); 578 break; 579 case IMSG_NEW_TA: 580 /* make sure this is a string */ 581 ((char *)imsg.data)[IMSG_DATA_SIZE(imsg) - 1] = '\0'; 582 add_new_ta(&new_trust_anchors, imsg.data); 583 break; 584 case IMSG_NEW_TAS_ABORT: 585 log_debug("%s: IMSG_NEW_TAS_ABORT", __func__); 586 free_tas(&new_trust_anchors); 587 break; 588 case IMSG_NEW_TAS_DONE: 589 chg = merge_tas(&new_trust_anchors, &trust_anchors); 590 log_debug("%s: IMSG_NEW_TAS_DONE: change: %d", 591 __func__, chg); 592 if (chg) { 593 send_trust_anchors(&trust_anchors); 594 } 595 /* 596 * always write trust anchors, the modify date on 597 * the file is an indication when we made progress 598 */ 599 if (ta_fd != -1) 600 write_trust_anchors(&trust_anchors, ta_fd); 601 break; 602 default: 603 log_debug("%s: error handling imsg %d", __func__, 604 imsg.hdr.type); 605 break; 606 } 607 imsg_free(&imsg); 608 } 609 if (!shut) 610 imsg_event_add(iev); 611 else { 612 /* This pipe is dead. Remove its event handler. */ 613 event_del(&iev->ev); 614 event_loopexit(NULL); 615 } 616 } 617 618 void 619 frontend_dispatch_captiveportal(int fd, short event, void *bula) 620 { 621 struct imsgev *iev = bula; 622 struct imsgbuf *ibuf = &iev->ibuf; 623 struct imsg imsg; 624 int n, shut = 0; 625 626 if (event & EV_READ) { 627 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) 628 fatal("imsg_read error"); 629 if (n == 0) /* Connection closed. */ 630 shut = 1; 631 } 632 if (event & EV_WRITE) { 633 if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN) 634 fatal("msgbuf_write"); 635 if (n == 0) /* Connection closed. */ 636 shut = 1; 637 } 638 639 for (;;) { 640 if ((n = imsg_get(ibuf, &imsg)) == -1) 641 fatal("%s: imsg_get error", __func__); 642 if (n == 0) /* No more messages. */ 643 break; 644 645 switch (imsg.hdr.type) { 646 default: 647 log_debug("%s: error handling imsg %d", __func__, 648 imsg.hdr.type); 649 break; 650 } 651 imsg_free(&imsg); 652 } 653 if (!shut) 654 imsg_event_add(iev); 655 else { 656 /* This pipe is dead. Remove its event handler. */ 657 event_del(&iev->ev); 658 event_loopexit(NULL); 659 } 660 } 661 662 void 663 frontend_startup(void) 664 { 665 if (!event_initialized(&ev_route)) 666 fatalx("%s: did not receive a route socket from the main " 667 "process", __func__); 668 669 event_add(&ev_route, NULL); 670 671 frontend_imsg_compose_main(IMSG_STARTUP_DONE, 0, NULL, 0); 672 rtmget_default(); 673 } 674 675 void 676 udp_receive(int fd, short events, void *arg) 677 { 678 struct udp_ev *udpev = (struct udp_ev *)arg; 679 struct pending_query *pq; 680 struct query_imsg *query_imsg; 681 ssize_t len, rem_len, buf_len; 682 uint16_t qdcount, ancount, nscount, arcount, t, c; 683 uint8_t *queryp; 684 char *str_from, *str, buf[1024], *bufp; 685 686 if ((len = recvmsg(fd, &udpev->rcvmhdr, 0)) < 0) { 687 log_warn("recvmsg"); 688 return; 689 } 690 691 bufp = buf; 692 buf_len = sizeof(buf); 693 694 str_from = ip_port((struct sockaddr *)&udpev->from); 695 696 if (len < LDNS_HEADER_SIZE) { 697 log_warnx("bad query: too short, from: %s", str_from); 698 return; 699 } 700 701 qdcount = LDNS_QDCOUNT(udpev->query); 702 ancount = LDNS_ANCOUNT(udpev->query); 703 nscount = LDNS_NSCOUNT(udpev->query); 704 arcount = LDNS_ARCOUNT(udpev->query); 705 706 if (qdcount != 1 && ancount != 0 && nscount != 0 && arcount != 0) { 707 log_warnx("invalid query from %s, qdcount: %d, ancount: %d " 708 "nscount: %d, arcount: %d", str_from, qdcount, ancount, 709 nscount, arcount); 710 return; 711 } 712 713 log_debug("query from %s", str_from); 714 if ((str = sldns_wire2str_pkt(udpev->query, len)) != NULL) { 715 log_debug("%s", str); 716 free(str); 717 } 718 719 queryp = udpev->query; 720 rem_len = len; 721 722 queryp += LDNS_HEADER_SIZE; 723 rem_len -= LDNS_HEADER_SIZE; 724 725 sldns_wire2str_dname_scan(&queryp, &rem_len, &bufp, &buf_len, 726 udpev->query, len); 727 728 if (rem_len < 4) { 729 log_warnx("malformed query"); 730 return; 731 } 732 733 t = sldns_read_uint16(queryp); 734 c = sldns_read_uint16(queryp+2); 735 queryp += 4; 736 rem_len -= 4; 737 738 if ((pq = malloc(sizeof(*pq))) == NULL) { 739 log_warn(NULL); 740 return; 741 } 742 743 if ((pq->query = malloc(len)) == NULL) { 744 log_warn(NULL); 745 free(pq); 746 return; 747 } 748 749 do { 750 arc4random_buf(&pq->imsg_id, sizeof(pq->imsg_id)); 751 } while(find_pending_query(pq->imsg_id) != NULL); 752 753 memcpy(pq->query, udpev->query, len); 754 pq->len = len; 755 pq->from = udpev->from; 756 pq->fd = fd; 757 758 if ((query_imsg = calloc(1, sizeof(*query_imsg))) == NULL) { 759 log_warn(NULL); 760 return; 761 } 762 763 if (strlcpy(query_imsg->qname, buf, sizeof(query_imsg->qname)) >= 764 sizeof(buf)) { 765 log_warnx("qname too long"); 766 free(query_imsg); 767 /* XXX SERVFAIL */ 768 free(pq->query); 769 free(pq); 770 return; 771 } 772 query_imsg->id = pq->imsg_id; 773 query_imsg->t = t; 774 query_imsg->c = c; 775 776 if (frontend_imsg_compose_resolver(IMSG_QUERY, 0, query_imsg, 777 sizeof(*query_imsg)) != -1) { 778 TAILQ_INSERT_TAIL(&pending_queries, pq, entry); 779 } else { 780 free(query_imsg); 781 /* XXX SERVFAIL */ 782 free(pq->query); 783 free(pq); 784 } 785 } 786 787 void 788 send_answer(struct pending_query *pq, uint8_t *answer, ssize_t len) 789 { 790 log_debug("result for %s", ip_port((struct sockaddr*)&pq->from)); 791 792 if (answer == NULL) { 793 answer = pq->query; 794 len = pq->len; 795 796 LDNS_QR_SET(answer); 797 LDNS_RA_SET(answer); 798 LDNS_RCODE_SET(answer, LDNS_RCODE_SERVFAIL); 799 } else { 800 if (pq->bogus) { 801 if(LDNS_CD_WIRE(pq->query)) { 802 LDNS_ID_SET(answer, LDNS_ID_WIRE(pq->query)); 803 LDNS_CD_SET(answer); 804 } else { 805 answer = pq->query; 806 len = pq->len; 807 808 LDNS_QR_SET(answer); 809 LDNS_RA_SET(answer); 810 LDNS_RCODE_SET(answer, LDNS_RCODE_SERVFAIL); 811 } 812 } else { 813 LDNS_ID_SET(answer, LDNS_ID_WIRE(pq->query)); 814 } 815 } 816 817 if(sendto(pq->fd, answer, len, 0, (struct sockaddr *)&pq->from, 818 pq->from.ss_len) == -1) 819 log_warn("sendto"); 820 821 TAILQ_REMOVE(&pending_queries, pq, entry); 822 free(pq->query); 823 free(pq); 824 } 825 826 char* 827 ip_port(struct sockaddr *sa) 828 { 829 static char hbuf[NI_MAXHOST], buf[NI_MAXHOST]; 830 831 if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), NULL, 0, 832 NI_NUMERICHOST) != 0) { 833 snprintf(buf, sizeof(buf), "%s", "(unknown)"); 834 return buf; 835 } 836 837 if (sa->sa_family == AF_INET6) 838 snprintf(buf, sizeof(buf), "[%s]:%d", hbuf, ntohs( 839 ((struct sockaddr_in6 *)sa)->sin6_port)); 840 if (sa->sa_family == AF_INET) 841 snprintf(buf, sizeof(buf), "[%s]:%d", hbuf, ntohs( 842 ((struct sockaddr_in *)sa)->sin_port)); 843 844 return buf; 845 } 846 847 struct pending_query* 848 find_pending_query(uint64_t id) 849 { 850 struct pending_query *pq; 851 852 TAILQ_FOREACH(pq, &pending_queries, entry) 853 if (pq->imsg_id == id) 854 return pq; 855 return NULL; 856 } 857 858 void 859 route_receive(int fd, short events, void *arg) 860 { 861 static uint8_t *buf; 862 863 struct rt_msghdr *rtm; 864 struct sockaddr *sa, *rti_info[RTAX_MAX]; 865 ssize_t n; 866 867 if (buf == NULL) { 868 buf = malloc(ROUTE_SOCKET_BUF_SIZE); 869 if (buf == NULL) 870 fatal("malloc"); 871 } 872 rtm = (struct rt_msghdr *)buf; 873 if ((n = read(fd, buf, ROUTE_SOCKET_BUF_SIZE)) == -1) { 874 if (errno == EAGAIN || errno == EINTR) 875 return; 876 log_warn("dispatch_rtmsg: read error"); 877 return; 878 } 879 880 if (n == 0) 881 fatal("routing socket closed"); 882 883 if (n < (ssize_t)sizeof(rtm->rtm_msglen) || n < rtm->rtm_msglen) { 884 log_warnx("partial rtm of %zd in buffer", n); 885 return; 886 } 887 888 if (rtm->rtm_version != RTM_VERSION) 889 return; 890 891 sa = (struct sockaddr *)(buf + rtm->rtm_hdrlen); 892 get_rtaddrs(rtm->rtm_addrs, sa, rti_info); 893 894 handle_route_message(rtm, rti_info); 895 } 896 897 #define ROUNDUP(a) \ 898 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) 899 900 void 901 get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info) 902 { 903 int i; 904 905 for (i = 0; i < RTAX_MAX; i++) { 906 if (addrs & (1 << i)) { 907 rti_info[i] = sa; 908 sa = (struct sockaddr *)((char *)(sa) + 909 ROUNDUP(sa->sa_len)); 910 } else 911 rti_info[i] = NULL; 912 } 913 } 914 915 void 916 handle_route_message(struct rt_msghdr *rtm, struct sockaddr **rti_info) 917 { 918 char buf[IF_NAMESIZE], *bufp; 919 920 switch (rtm->rtm_type) { 921 case RTM_GET: 922 if (rtm->rtm_errno != 0) 923 break; 924 if (!(rtm->rtm_flags & RTF_UP)) 925 break; 926 if (!(rtm->rtm_addrs & RTA_DST)) 927 break; 928 if (rti_info[RTAX_DST]->sa_family != AF_INET) 929 break; 930 if (((struct sockaddr_in *)rti_info[RTAX_DST])->sin_addr. 931 s_addr != INADDR_ANY) 932 break; 933 if (!(rtm->rtm_addrs & RTA_NETMASK)) 934 break; 935 if (rti_info[RTAX_NETMASK]->sa_family != AF_INET) 936 break; 937 if (((struct sockaddr_in *)rti_info[RTAX_NETMASK])->sin_addr. 938 s_addr != INADDR_ANY) 939 break; 940 941 frontend_imsg_compose_main(IMSG_OPEN_DHCP_LEASE, 0, 942 &rtm->rtm_index, sizeof(rtm->rtm_index)); 943 944 bufp = if_indextoname(rtm->rtm_index, buf); 945 if (bufp) 946 log_debug("default route is on %s", buf); 947 948 break; 949 case RTM_IFINFO: 950 frontend_imsg_compose_resolver(IMSG_RECHECK_RESOLVERS, 0, NULL, 951 0); 952 break; 953 default: 954 break; 955 } 956 } 957 958 void 959 rtmget_default(void) 960 { 961 static int rtm_seq; 962 struct rt_msghdr rtm; 963 struct sockaddr_in sin; 964 struct iovec iov[5]; 965 long pad = 0; 966 int iovcnt = 0, padlen; 967 968 memset(&sin, 0, sizeof(sin)); 969 sin.sin_family = AF_INET; 970 sin.sin_len = sizeof(sin); 971 972 memset(&rtm, 0, sizeof(rtm)); 973 974 rtm.rtm_version = RTM_VERSION; 975 rtm.rtm_type = RTM_GET; 976 rtm.rtm_msglen = sizeof(rtm); 977 rtm.rtm_tableid = 0; /* XXX imsg->rdomain; */ 978 rtm.rtm_seq = ++rtm_seq; 979 rtm.rtm_addrs = RTA_DST | RTA_NETMASK; 980 981 iov[iovcnt].iov_base = &rtm; 982 iov[iovcnt++].iov_len = sizeof(rtm); 983 984 /* dst */ 985 iov[iovcnt].iov_base = &sin; 986 iov[iovcnt++].iov_len = sizeof(sin); 987 rtm.rtm_msglen += sizeof(sin); 988 padlen = ROUNDUP(sizeof(sin)) - sizeof(sin); 989 if (padlen > 0) { 990 iov[iovcnt].iov_base = &pad; 991 iov[iovcnt++].iov_len = padlen; 992 rtm.rtm_msglen += padlen; 993 } 994 995 /* mask */ 996 iov[iovcnt].iov_base = &sin; 997 iov[iovcnt++].iov_len = sizeof(sin); 998 rtm.rtm_msglen += sizeof(sin); 999 padlen = ROUNDUP(sizeof(sin)) - sizeof(sin); 1000 if (padlen > 0) { 1001 iov[iovcnt].iov_base = &pad; 1002 iov[iovcnt++].iov_len = padlen; 1003 rtm.rtm_msglen += padlen; 1004 } 1005 1006 if (writev(routesock, iov, iovcnt) == -1) 1007 log_warn("failed to send route message"); 1008 } 1009 1010 void 1011 parse_dhcp_lease(int fd) 1012 { 1013 FILE *f; 1014 char *line = NULL, *cur_ns = NULL, *ns = NULL; 1015 size_t linesize = 0; 1016 ssize_t linelen; 1017 time_t epoch = 0, lease_time = 0, now; 1018 char **tok, *toks[4], *p; 1019 1020 if((f = fdopen(fd, "r")) == NULL) { 1021 log_warn("cannot read dhcp lease"); 1022 close(fd); 1023 return; 1024 } 1025 1026 now = time(NULL); 1027 1028 while ((linelen = getline(&line, &linesize, f)) != -1) { 1029 for (tok = toks; tok < &toks[3] && (*tok = strsep(&line, " \t")) 1030 != NULL;) { 1031 if (**tok != '\0') 1032 tok++; 1033 } 1034 *tok = NULL; 1035 if (strcmp(toks[0], "option") == 0) { 1036 if (strcmp(toks[1], "domain-name-servers") == 0) { 1037 if((p = strchr(toks[2], ';')) != NULL) { 1038 *p='\0'; 1039 cur_ns = strdup(toks[2]); 1040 } 1041 } 1042 if (strcmp(toks[1], "dhcp-lease-time") == 0) { 1043 if((p = strchr(toks[2], ';')) != NULL) { 1044 *p='\0'; 1045 lease_time = strtonum(toks[2], 0, 1046 INT64_MAX, NULL); 1047 } 1048 } 1049 } else if (strcmp(toks[0], "epoch") == 0) { 1050 if((p = strchr(toks[1], ';')) != NULL) { 1051 *p='\0'; 1052 epoch = strtonum(toks[1], 0, 1053 INT64_MAX, NULL); 1054 } 1055 } 1056 else if (*toks[0] == '}') { 1057 if (epoch + lease_time > now ) { 1058 free(ns); 1059 ns = cur_ns; 1060 } else /* expired lease */ 1061 free(cur_ns); 1062 } 1063 } 1064 free(line); 1065 1066 if (ferror(f)) 1067 log_warn("getline"); 1068 fclose(f); 1069 1070 if (ns != NULL) { 1071 log_debug("%s: ns: %s", __func__, ns); 1072 frontend_imsg_compose_resolver(IMSG_FORWARDER, 0, ns, 1073 strlen(ns) + 1); 1074 } 1075 } 1076 1077 1078 void 1079 add_new_ta(struct trust_anchor_head *tah, char *val) 1080 { 1081 struct trust_anchor *ta, *i; 1082 int cmp; 1083 1084 if ((ta = malloc(sizeof(*ta))) == NULL) 1085 fatal("%s", __func__); 1086 if ((ta->ta = strdup(val)) == NULL) 1087 fatal("%s", __func__); 1088 1089 /* keep the list sorted to prevent churn if the order changes in DNS */ 1090 TAILQ_FOREACH(i, tah, entry) { 1091 cmp = strcmp(i->ta, ta->ta); 1092 if ( cmp == 0) { 1093 /* duplicate */ 1094 free(ta->ta); 1095 free(ta); 1096 return; 1097 } else if (cmp > 0) { 1098 TAILQ_INSERT_BEFORE(i, ta, entry); 1099 return; 1100 } 1101 } 1102 TAILQ_INSERT_TAIL(tah, ta, entry); 1103 } 1104 1105 void 1106 free_tas(struct trust_anchor_head *tah) 1107 { 1108 struct trust_anchor *ta; 1109 1110 while ((ta = TAILQ_FIRST(tah))) { 1111 TAILQ_REMOVE(tah, ta, entry); 1112 free(ta->ta); 1113 free(ta); 1114 } 1115 } 1116 1117 int 1118 merge_tas(struct trust_anchor_head *newh, struct trust_anchor_head *oldh) 1119 { 1120 struct trust_anchor *i, *j; 1121 int chg = 0; 1122 1123 j = TAILQ_FIRST(oldh); 1124 1125 TAILQ_FOREACH(i, newh, entry) { 1126 if (j == NULL || strcmp(i->ta, j->ta) != 0) { 1127 chg = 1; 1128 break; 1129 } 1130 j = TAILQ_NEXT(j, entry); 1131 } 1132 if (j != NULL) 1133 chg = 1; 1134 1135 if (chg) { 1136 free_tas(oldh); 1137 while((i = TAILQ_FIRST(newh)) != NULL) { 1138 TAILQ_REMOVE(newh, i, entry); 1139 TAILQ_INSERT_TAIL(oldh, i, entry); 1140 } 1141 } else { 1142 free_tas(newh); 1143 } 1144 return (chg); 1145 } 1146 1147 void 1148 parse_trust_anchor(struct trust_anchor_head *tah, int fd) 1149 { 1150 size_t len, dname_len; 1151 ssize_t n, sz; 1152 uint8_t rr[LDNS_RR_BUF_SIZE]; 1153 char *str, *p, buf[512], *line; 1154 1155 sz = 0; 1156 str = NULL; 1157 1158 while ((n = read(fd, buf, sizeof(buf))) > 0) { 1159 p = recallocarray(str, sz, sz + n, 1); 1160 if (p == NULL) { 1161 log_warn("%s", __func__); 1162 goto out; 1163 } 1164 str = p; 1165 memcpy(str + sz, buf, n); 1166 sz += n; 1167 } 1168 1169 if (n == -1) { 1170 log_warn("%s", __func__); 1171 goto out; 1172 } 1173 1174 /* make it a string */ 1175 p = recallocarray(str, sz, sz + 1, 1); 1176 if (p == NULL) { 1177 log_warn("%s", __func__); 1178 goto out; 1179 } 1180 str = p; 1181 sz++; 1182 1183 len = sizeof(rr); 1184 1185 while ((line = strsep(&str, "\n")) != NULL) { 1186 if (sldns_str2wire_rr_buf(line, rr, &len, &dname_len, 1187 ROOT_DNSKEY_TTL, NULL, 0, NULL, 0) != 0) 1188 continue; 1189 if (sldns_wirerr_get_type(rr, len, dname_len) == 1190 LDNS_RR_TYPE_DNSKEY) 1191 add_new_ta(tah, line); 1192 } 1193 1194 out: 1195 free(str); 1196 return; 1197 } 1198 1199 void 1200 send_trust_anchors(struct trust_anchor_head *tah) 1201 { 1202 struct trust_anchor *ta; 1203 1204 TAILQ_FOREACH(ta, tah, entry) 1205 frontend_imsg_compose_resolver(IMSG_NEW_TA, 0, ta->ta, 1206 strlen(ta->ta) + 1); 1207 frontend_imsg_compose_resolver(IMSG_NEW_TAS_DONE, 0, NULL, 0); 1208 } 1209 1210 void 1211 write_trust_anchors(struct trust_anchor_head *tah, int fd) 1212 { 1213 struct trust_anchor *ta; 1214 size_t len = 0; 1215 ssize_t n; 1216 char *str; 1217 1218 log_debug("%s", __func__); 1219 1220 if (lseek(fd, 0, SEEK_SET) == -1) { 1221 log_warn("%s", __func__); 1222 goto out; 1223 } 1224 1225 TAILQ_FOREACH(ta, tah, entry) { 1226 if ((n = asprintf(&str, "%s\n", ta->ta)) == -1) { 1227 log_warn("%s", __func__); 1228 len = 0; 1229 goto out; 1230 } 1231 len += n; 1232 if (write(fd, str, n) != n) { 1233 log_warn("%s", __func__); 1234 free(str); 1235 len = 0; 1236 goto out; 1237 } 1238 free(str); 1239 } 1240 out: 1241 ftruncate(fd, len); 1242 fsync(fd); 1243 } 1244