1 /*- 2 * Copyright (c) 2012 The FreeBSD Foundation 3 * All rights reserved. 4 * 5 * This software was developed by Edward Tomasz Napierala under sponsorship 6 * from the FreeBSD Foundation. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 */ 30 31 #include <sys/cdefs.h> 32 __FBSDID("$FreeBSD$"); 33 34 #include <sys/types.h> 35 #include <sys/time.h> 36 #include <sys/socket.h> 37 #include <sys/wait.h> 38 #include <netinet/in.h> 39 #include <arpa/inet.h> 40 #include <assert.h> 41 #include <ctype.h> 42 #include <errno.h> 43 #include <netdb.h> 44 #include <signal.h> 45 #include <stdbool.h> 46 #include <stdio.h> 47 #include <stdint.h> 48 #include <stdlib.h> 49 #include <string.h> 50 #include <unistd.h> 51 52 #include "ctld.h" 53 #include "isns.h" 54 55 bool proxy_mode = false; 56 57 static volatile bool sighup_received = false; 58 static volatile bool sigterm_received = false; 59 static volatile bool sigalrm_received = false; 60 61 static int nchildren = 0; 62 63 static void 64 usage(void) 65 { 66 67 fprintf(stderr, "usage: ctld [-d][-f config-file]\n"); 68 exit(1); 69 } 70 71 char * 72 checked_strdup(const char *s) 73 { 74 char *c; 75 76 c = strdup(s); 77 if (c == NULL) 78 log_err(1, "strdup"); 79 return (c); 80 } 81 82 struct conf * 83 conf_new(void) 84 { 85 struct conf *conf; 86 87 conf = calloc(1, sizeof(*conf)); 88 if (conf == NULL) 89 log_err(1, "calloc"); 90 TAILQ_INIT(&conf->conf_targets); 91 TAILQ_INIT(&conf->conf_auth_groups); 92 TAILQ_INIT(&conf->conf_portal_groups); 93 TAILQ_INIT(&conf->conf_isns); 94 95 conf->conf_isns_period = 900; 96 conf->conf_isns_timeout = 5; 97 conf->conf_debug = 0; 98 conf->conf_timeout = 60; 99 conf->conf_maxproc = 30; 100 101 return (conf); 102 } 103 104 void 105 conf_delete(struct conf *conf) 106 { 107 struct target *targ, *tmp; 108 struct auth_group *ag, *cagtmp; 109 struct portal_group *pg, *cpgtmp; 110 struct isns *is, *istmp; 111 112 assert(conf->conf_pidfh == NULL); 113 114 TAILQ_FOREACH_SAFE(targ, &conf->conf_targets, t_next, tmp) 115 target_delete(targ); 116 TAILQ_FOREACH_SAFE(ag, &conf->conf_auth_groups, ag_next, cagtmp) 117 auth_group_delete(ag); 118 TAILQ_FOREACH_SAFE(pg, &conf->conf_portal_groups, pg_next, cpgtmp) 119 portal_group_delete(pg); 120 TAILQ_FOREACH_SAFE(is, &conf->conf_isns, i_next, istmp) 121 isns_delete(is); 122 free(conf->conf_pidfile_path); 123 free(conf); 124 } 125 126 static struct auth * 127 auth_new(struct auth_group *ag) 128 { 129 struct auth *auth; 130 131 auth = calloc(1, sizeof(*auth)); 132 if (auth == NULL) 133 log_err(1, "calloc"); 134 auth->a_auth_group = ag; 135 TAILQ_INSERT_TAIL(&ag->ag_auths, auth, a_next); 136 return (auth); 137 } 138 139 static void 140 auth_delete(struct auth *auth) 141 { 142 TAILQ_REMOVE(&auth->a_auth_group->ag_auths, auth, a_next); 143 144 free(auth->a_user); 145 free(auth->a_secret); 146 free(auth->a_mutual_user); 147 free(auth->a_mutual_secret); 148 free(auth); 149 } 150 151 const struct auth * 152 auth_find(const struct auth_group *ag, const char *user) 153 { 154 const struct auth *auth; 155 156 TAILQ_FOREACH(auth, &ag->ag_auths, a_next) { 157 if (strcmp(auth->a_user, user) == 0) 158 return (auth); 159 } 160 161 return (NULL); 162 } 163 164 static void 165 auth_check_secret_length(struct auth *auth) 166 { 167 size_t len; 168 169 len = strlen(auth->a_secret); 170 if (len > 16) { 171 if (auth->a_auth_group->ag_name != NULL) 172 log_warnx("secret for user \"%s\", auth-group \"%s\", " 173 "is too long; it should be at most 16 characters " 174 "long", auth->a_user, auth->a_auth_group->ag_name); 175 else 176 log_warnx("secret for user \"%s\", target \"%s\", " 177 "is too long; it should be at most 16 characters " 178 "long", auth->a_user, 179 auth->a_auth_group->ag_target->t_name); 180 } 181 if (len < 12) { 182 if (auth->a_auth_group->ag_name != NULL) 183 log_warnx("secret for user \"%s\", auth-group \"%s\", " 184 "is too short; it should be at least 12 characters " 185 "long", auth->a_user, 186 auth->a_auth_group->ag_name); 187 else 188 log_warnx("secret for user \"%s\", target \"%s\", " 189 "is too short; it should be at least 16 characters " 190 "long", auth->a_user, 191 auth->a_auth_group->ag_target->t_name); 192 } 193 194 if (auth->a_mutual_secret != NULL) { 195 len = strlen(auth->a_secret); 196 if (len > 16) { 197 if (auth->a_auth_group->ag_name != NULL) 198 log_warnx("mutual secret for user \"%s\", " 199 "auth-group \"%s\", is too long; it should " 200 "be at most 16 characters long", 201 auth->a_user, auth->a_auth_group->ag_name); 202 else 203 log_warnx("mutual secret for user \"%s\", " 204 "target \"%s\", is too long; it should " 205 "be at most 16 characters long", 206 auth->a_user, 207 auth->a_auth_group->ag_target->t_name); 208 } 209 if (len < 12) { 210 if (auth->a_auth_group->ag_name != NULL) 211 log_warnx("mutual secret for user \"%s\", " 212 "auth-group \"%s\", is too short; it " 213 "should be at least 12 characters long", 214 auth->a_user, auth->a_auth_group->ag_name); 215 else 216 log_warnx("mutual secret for user \"%s\", " 217 "target \"%s\", is too short; it should be " 218 "at least 16 characters long", 219 auth->a_user, 220 auth->a_auth_group->ag_target->t_name); 221 } 222 } 223 } 224 225 const struct auth * 226 auth_new_chap(struct auth_group *ag, const char *user, 227 const char *secret) 228 { 229 struct auth *auth; 230 231 if (ag->ag_type == AG_TYPE_UNKNOWN) 232 ag->ag_type = AG_TYPE_CHAP; 233 if (ag->ag_type != AG_TYPE_CHAP) { 234 if (ag->ag_name != NULL) 235 log_warnx("cannot mix \"chap\" authentication with " 236 "other types for auth-group \"%s\"", ag->ag_name); 237 else 238 log_warnx("cannot mix \"chap\" authentication with " 239 "other types for target \"%s\"", 240 ag->ag_target->t_name); 241 return (NULL); 242 } 243 244 auth = auth_new(ag); 245 auth->a_user = checked_strdup(user); 246 auth->a_secret = checked_strdup(secret); 247 248 auth_check_secret_length(auth); 249 250 return (auth); 251 } 252 253 const struct auth * 254 auth_new_chap_mutual(struct auth_group *ag, const char *user, 255 const char *secret, const char *user2, const char *secret2) 256 { 257 struct auth *auth; 258 259 if (ag->ag_type == AG_TYPE_UNKNOWN) 260 ag->ag_type = AG_TYPE_CHAP_MUTUAL; 261 if (ag->ag_type != AG_TYPE_CHAP_MUTUAL) { 262 if (ag->ag_name != NULL) 263 log_warnx("cannot mix \"chap-mutual\" authentication " 264 "with other types for auth-group \"%s\"", 265 ag->ag_name); 266 else 267 log_warnx("cannot mix \"chap-mutual\" authentication " 268 "with other types for target \"%s\"", 269 ag->ag_target->t_name); 270 return (NULL); 271 } 272 273 auth = auth_new(ag); 274 auth->a_user = checked_strdup(user); 275 auth->a_secret = checked_strdup(secret); 276 auth->a_mutual_user = checked_strdup(user2); 277 auth->a_mutual_secret = checked_strdup(secret2); 278 279 auth_check_secret_length(auth); 280 281 return (auth); 282 } 283 284 const struct auth_name * 285 auth_name_new(struct auth_group *ag, const char *name) 286 { 287 struct auth_name *an; 288 289 an = calloc(1, sizeof(*an)); 290 if (an == NULL) 291 log_err(1, "calloc"); 292 an->an_auth_group = ag; 293 an->an_initator_name = checked_strdup(name); 294 TAILQ_INSERT_TAIL(&ag->ag_names, an, an_next); 295 return (an); 296 } 297 298 static void 299 auth_name_delete(struct auth_name *an) 300 { 301 TAILQ_REMOVE(&an->an_auth_group->ag_names, an, an_next); 302 303 free(an->an_initator_name); 304 free(an); 305 } 306 307 bool 308 auth_name_defined(const struct auth_group *ag) 309 { 310 if (TAILQ_EMPTY(&ag->ag_names)) 311 return (false); 312 return (true); 313 } 314 315 const struct auth_name * 316 auth_name_find(const struct auth_group *ag, const char *name) 317 { 318 const struct auth_name *auth_name; 319 320 TAILQ_FOREACH(auth_name, &ag->ag_names, an_next) { 321 if (strcmp(auth_name->an_initator_name, name) == 0) 322 return (auth_name); 323 } 324 325 return (NULL); 326 } 327 328 int 329 auth_name_check(const struct auth_group *ag, const char *initiator_name) 330 { 331 if (!auth_name_defined(ag)) 332 return (0); 333 334 if (auth_name_find(ag, initiator_name) == NULL) 335 return (1); 336 337 return (0); 338 } 339 340 const struct auth_portal * 341 auth_portal_new(struct auth_group *ag, const char *portal) 342 { 343 struct auth_portal *ap; 344 char *net, *mask, *str, *tmp; 345 int len, dm, m; 346 347 ap = calloc(1, sizeof(*ap)); 348 if (ap == NULL) 349 log_err(1, "calloc"); 350 ap->ap_auth_group = ag; 351 ap->ap_initator_portal = checked_strdup(portal); 352 mask = str = checked_strdup(portal); 353 net = strsep(&mask, "/"); 354 if (net[0] == '[') 355 net++; 356 len = strlen(net); 357 if (len == 0) 358 goto error; 359 if (net[len - 1] == ']') 360 net[len - 1] = 0; 361 if (strchr(net, ':') != NULL) { 362 struct sockaddr_in6 *sin6 = 363 (struct sockaddr_in6 *)&ap->ap_sa; 364 365 sin6->sin6_len = sizeof(*sin6); 366 sin6->sin6_family = AF_INET6; 367 if (inet_pton(AF_INET6, net, &sin6->sin6_addr) <= 0) 368 goto error; 369 dm = 128; 370 } else { 371 struct sockaddr_in *sin = 372 (struct sockaddr_in *)&ap->ap_sa; 373 374 sin->sin_len = sizeof(*sin); 375 sin->sin_family = AF_INET; 376 if (inet_pton(AF_INET, net, &sin->sin_addr) <= 0) 377 goto error; 378 dm = 32; 379 } 380 if (mask != NULL) { 381 m = strtol(mask, &tmp, 0); 382 if (m < 0 || m > dm || tmp[0] != 0) 383 goto error; 384 } else 385 m = dm; 386 ap->ap_mask = m; 387 free(str); 388 TAILQ_INSERT_TAIL(&ag->ag_portals, ap, ap_next); 389 return (ap); 390 391 error: 392 log_errx(1, "Incorrect initiator portal '%s'", portal); 393 return (NULL); 394 } 395 396 static void 397 auth_portal_delete(struct auth_portal *ap) 398 { 399 TAILQ_REMOVE(&ap->ap_auth_group->ag_portals, ap, ap_next); 400 401 free(ap->ap_initator_portal); 402 free(ap); 403 } 404 405 bool 406 auth_portal_defined(const struct auth_group *ag) 407 { 408 if (TAILQ_EMPTY(&ag->ag_portals)) 409 return (false); 410 return (true); 411 } 412 413 const struct auth_portal * 414 auth_portal_find(const struct auth_group *ag, const struct sockaddr_storage *ss) 415 { 416 const struct auth_portal *ap; 417 const uint8_t *a, *b; 418 int i; 419 uint8_t bmask; 420 421 TAILQ_FOREACH(ap, &ag->ag_portals, ap_next) { 422 if (ap->ap_sa.ss_family != ss->ss_family) 423 continue; 424 if (ss->ss_family == AF_INET) { 425 a = (const uint8_t *) 426 &((const struct sockaddr_in *)ss)->sin_addr; 427 b = (const uint8_t *) 428 &((const struct sockaddr_in *)&ap->ap_sa)->sin_addr; 429 } else { 430 a = (const uint8_t *) 431 &((const struct sockaddr_in6 *)ss)->sin6_addr; 432 b = (const uint8_t *) 433 &((const struct sockaddr_in6 *)&ap->ap_sa)->sin6_addr; 434 } 435 for (i = 0; i < ap->ap_mask / 8; i++) { 436 if (a[i] != b[i]) 437 goto next; 438 } 439 if (ap->ap_mask % 8) { 440 bmask = 0xff << (8 - (ap->ap_mask % 8)); 441 if ((a[i] & bmask) != (b[i] & bmask)) 442 goto next; 443 } 444 return (ap); 445 next: 446 ; 447 } 448 449 return (NULL); 450 } 451 452 int 453 auth_portal_check(const struct auth_group *ag, const struct sockaddr_storage *sa) 454 { 455 456 if (!auth_portal_defined(ag)) 457 return (0); 458 459 if (auth_portal_find(ag, sa) == NULL) 460 return (1); 461 462 return (0); 463 } 464 465 struct auth_group * 466 auth_group_new(struct conf *conf, const char *name) 467 { 468 struct auth_group *ag; 469 470 if (name != NULL) { 471 ag = auth_group_find(conf, name); 472 if (ag != NULL) { 473 log_warnx("duplicated auth-group \"%s\"", name); 474 return (NULL); 475 } 476 } 477 478 ag = calloc(1, sizeof(*ag)); 479 if (ag == NULL) 480 log_err(1, "calloc"); 481 if (name != NULL) 482 ag->ag_name = checked_strdup(name); 483 TAILQ_INIT(&ag->ag_auths); 484 TAILQ_INIT(&ag->ag_names); 485 TAILQ_INIT(&ag->ag_portals); 486 ag->ag_conf = conf; 487 TAILQ_INSERT_TAIL(&conf->conf_auth_groups, ag, ag_next); 488 489 return (ag); 490 } 491 492 void 493 auth_group_delete(struct auth_group *ag) 494 { 495 struct auth *auth, *auth_tmp; 496 struct auth_name *auth_name, *auth_name_tmp; 497 struct auth_portal *auth_portal, *auth_portal_tmp; 498 499 TAILQ_REMOVE(&ag->ag_conf->conf_auth_groups, ag, ag_next); 500 501 TAILQ_FOREACH_SAFE(auth, &ag->ag_auths, a_next, auth_tmp) 502 auth_delete(auth); 503 TAILQ_FOREACH_SAFE(auth_name, &ag->ag_names, an_next, auth_name_tmp) 504 auth_name_delete(auth_name); 505 TAILQ_FOREACH_SAFE(auth_portal, &ag->ag_portals, ap_next, 506 auth_portal_tmp) 507 auth_portal_delete(auth_portal); 508 free(ag->ag_name); 509 free(ag); 510 } 511 512 struct auth_group * 513 auth_group_find(const struct conf *conf, const char *name) 514 { 515 struct auth_group *ag; 516 517 TAILQ_FOREACH(ag, &conf->conf_auth_groups, ag_next) { 518 if (ag->ag_name != NULL && strcmp(ag->ag_name, name) == 0) 519 return (ag); 520 } 521 522 return (NULL); 523 } 524 525 int 526 auth_group_set_type(struct auth_group *ag, const char *str) 527 { 528 int type; 529 530 if (strcmp(str, "none") == 0) { 531 type = AG_TYPE_NO_AUTHENTICATION; 532 } else if (strcmp(str, "deny") == 0) { 533 type = AG_TYPE_DENY; 534 } else if (strcmp(str, "chap") == 0) { 535 type = AG_TYPE_CHAP; 536 } else if (strcmp(str, "chap-mutual") == 0) { 537 type = AG_TYPE_CHAP_MUTUAL; 538 } else { 539 if (ag->ag_name != NULL) 540 log_warnx("invalid auth-type \"%s\" for auth-group " 541 "\"%s\"", str, ag->ag_name); 542 else 543 log_warnx("invalid auth-type \"%s\" for target " 544 "\"%s\"", str, ag->ag_target->t_name); 545 return (1); 546 } 547 548 if (ag->ag_type != AG_TYPE_UNKNOWN && ag->ag_type != type) { 549 if (ag->ag_name != NULL) { 550 log_warnx("cannot set auth-type to \"%s\" for " 551 "auth-group \"%s\"; already has a different " 552 "type", str, ag->ag_name); 553 } else { 554 log_warnx("cannot set auth-type to \"%s\" for target " 555 "\"%s\"; already has a different type", 556 str, ag->ag_target->t_name); 557 } 558 return (1); 559 } 560 561 ag->ag_type = type; 562 563 return (0); 564 } 565 566 static struct portal * 567 portal_new(struct portal_group *pg) 568 { 569 struct portal *portal; 570 571 portal = calloc(1, sizeof(*portal)); 572 if (portal == NULL) 573 log_err(1, "calloc"); 574 TAILQ_INIT(&portal->p_targets); 575 portal->p_portal_group = pg; 576 TAILQ_INSERT_TAIL(&pg->pg_portals, portal, p_next); 577 return (portal); 578 } 579 580 static void 581 portal_delete(struct portal *portal) 582 { 583 584 TAILQ_REMOVE(&portal->p_portal_group->pg_portals, portal, p_next); 585 if (portal->p_ai != NULL) 586 freeaddrinfo(portal->p_ai); 587 free(portal->p_listen); 588 free(portal); 589 } 590 591 struct portal_group * 592 portal_group_new(struct conf *conf, const char *name) 593 { 594 struct portal_group *pg; 595 596 pg = portal_group_find(conf, name); 597 if (pg != NULL) { 598 log_warnx("duplicated portal-group \"%s\"", name); 599 return (NULL); 600 } 601 602 pg = calloc(1, sizeof(*pg)); 603 if (pg == NULL) 604 log_err(1, "calloc"); 605 pg->pg_name = checked_strdup(name); 606 TAILQ_INIT(&pg->pg_portals); 607 pg->pg_conf = conf; 608 conf->conf_last_portal_group_tag++; 609 pg->pg_tag = conf->conf_last_portal_group_tag; 610 TAILQ_INSERT_TAIL(&conf->conf_portal_groups, pg, pg_next); 611 612 return (pg); 613 } 614 615 void 616 portal_group_delete(struct portal_group *pg) 617 { 618 struct portal *portal, *tmp; 619 620 TAILQ_REMOVE(&pg->pg_conf->conf_portal_groups, pg, pg_next); 621 622 TAILQ_FOREACH_SAFE(portal, &pg->pg_portals, p_next, tmp) 623 portal_delete(portal); 624 free(pg->pg_name); 625 free(pg->pg_redirection); 626 free(pg); 627 } 628 629 struct portal_group * 630 portal_group_find(const struct conf *conf, const char *name) 631 { 632 struct portal_group *pg; 633 634 TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) { 635 if (strcmp(pg->pg_name, name) == 0) 636 return (pg); 637 } 638 639 return (NULL); 640 } 641 642 static int 643 parse_addr_port(char *arg, const char *def_port, struct addrinfo **ai) 644 { 645 struct addrinfo hints; 646 char *addr, *ch; 647 const char *port; 648 int error, colons = 0; 649 650 if (arg[0] == '[') { 651 /* 652 * IPv6 address in square brackets, perhaps with port. 653 */ 654 arg++; 655 addr = strsep(&arg, "]"); 656 if (arg == NULL) 657 return (1); 658 if (arg[0] == '\0') { 659 port = def_port; 660 } else if (arg[0] == ':') { 661 port = arg + 1; 662 } else 663 return (1); 664 } else { 665 /* 666 * Either IPv6 address without brackets - and without 667 * a port - or IPv4 address. Just count the colons. 668 */ 669 for (ch = arg; *ch != '\0'; ch++) { 670 if (*ch == ':') 671 colons++; 672 } 673 if (colons > 1) { 674 addr = arg; 675 port = def_port; 676 } else { 677 addr = strsep(&arg, ":"); 678 if (arg == NULL) 679 port = def_port; 680 else 681 port = arg; 682 } 683 } 684 685 memset(&hints, 0, sizeof(hints)); 686 hints.ai_family = PF_UNSPEC; 687 hints.ai_socktype = SOCK_STREAM; 688 hints.ai_flags = AI_PASSIVE; 689 error = getaddrinfo(addr, port, &hints, ai); 690 if (error != 0) 691 return (1); 692 return (0); 693 } 694 695 int 696 portal_group_add_listen(struct portal_group *pg, const char *value, bool iser) 697 { 698 struct portal *portal; 699 700 portal = portal_new(pg); 701 portal->p_listen = checked_strdup(value); 702 portal->p_iser = iser; 703 704 if (parse_addr_port(portal->p_listen, "3260", &portal->p_ai)) { 705 log_warnx("invalid listen address %s", portal->p_listen); 706 portal_delete(portal); 707 return (1); 708 } 709 710 /* 711 * XXX: getaddrinfo(3) may return multiple addresses; we should turn 712 * those into multiple portals. 713 */ 714 715 return (0); 716 } 717 718 int 719 isns_new(struct conf *conf, const char *addr) 720 { 721 struct isns *isns; 722 723 isns = calloc(1, sizeof(*isns)); 724 if (isns == NULL) 725 log_err(1, "calloc"); 726 isns->i_conf = conf; 727 TAILQ_INSERT_TAIL(&conf->conf_isns, isns, i_next); 728 isns->i_addr = checked_strdup(addr); 729 730 if (parse_addr_port(isns->i_addr, "3205", &isns->i_ai)) { 731 log_warnx("invalid iSNS address %s", isns->i_addr); 732 isns_delete(isns); 733 return (1); 734 } 735 736 /* 737 * XXX: getaddrinfo(3) may return multiple addresses; we should turn 738 * those into multiple servers. 739 */ 740 741 return (0); 742 } 743 744 void 745 isns_delete(struct isns *isns) 746 { 747 748 TAILQ_REMOVE(&isns->i_conf->conf_isns, isns, i_next); 749 free(isns->i_addr); 750 if (isns->i_ai != NULL) 751 freeaddrinfo(isns->i_ai); 752 free(isns); 753 } 754 755 static int 756 isns_do_connect(struct isns *isns) 757 { 758 int s; 759 760 s = socket(isns->i_ai->ai_family, isns->i_ai->ai_socktype, 761 isns->i_ai->ai_protocol); 762 if (s < 0) { 763 log_warn("socket(2) failed for %s", isns->i_addr); 764 return (-1); 765 } 766 if (connect(s, isns->i_ai->ai_addr, isns->i_ai->ai_addrlen)) { 767 log_warn("connect(2) failed for %s", isns->i_addr); 768 close(s); 769 return (-1); 770 } 771 return(s); 772 } 773 774 static int 775 isns_do_register(struct isns *isns, int s, const char *hostname) 776 { 777 struct conf *conf = isns->i_conf; 778 struct target *target; 779 struct portal *portal; 780 struct portal_group *pg; 781 struct isns_req *req; 782 int res = 0; 783 uint32_t error; 784 785 req = isns_req_create(ISNS_FUNC_DEVATTRREG, ISNS_FLAG_CLIENT); 786 isns_req_add_str(req, 32, TAILQ_FIRST(&conf->conf_targets)->t_name); 787 isns_req_add_delim(req); 788 isns_req_add_str(req, 1, hostname); 789 isns_req_add_32(req, 2, 2); /* 2 -- iSCSI */ 790 isns_req_add_32(req, 6, conf->conf_isns_period); 791 TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) { 792 if (pg->pg_unassigned) 793 continue; 794 TAILQ_FOREACH(portal, &pg->pg_portals, p_next) { 795 isns_req_add_addr(req, 16, portal->p_ai); 796 isns_req_add_port(req, 17, portal->p_ai); 797 } 798 } 799 TAILQ_FOREACH(target, &conf->conf_targets, t_next) { 800 isns_req_add_str(req, 32, target->t_name); 801 isns_req_add_32(req, 33, 1); /* 1 -- Target*/ 802 if (target->t_alias != NULL) 803 isns_req_add_str(req, 34, target->t_alias); 804 pg = target->t_portal_group; 805 isns_req_add_32(req, 51, pg->pg_tag); 806 TAILQ_FOREACH(portal, &pg->pg_portals, p_next) { 807 isns_req_add_addr(req, 49, portal->p_ai); 808 isns_req_add_port(req, 50, portal->p_ai); 809 } 810 } 811 res = isns_req_send(s, req); 812 if (res < 0) { 813 log_warn("send(2) failed for %s", isns->i_addr); 814 goto quit; 815 } 816 res = isns_req_receive(s, req); 817 if (res < 0) { 818 log_warn("receive(2) failed for %s", isns->i_addr); 819 goto quit; 820 } 821 error = isns_req_get_status(req); 822 if (error != 0) { 823 log_warnx("iSNS register error %d for %s", error, isns->i_addr); 824 res = -1; 825 } 826 quit: 827 isns_req_free(req); 828 return (res); 829 } 830 831 static int 832 isns_do_check(struct isns *isns, int s, const char *hostname) 833 { 834 struct conf *conf = isns->i_conf; 835 struct isns_req *req; 836 int res = 0; 837 uint32_t error; 838 839 req = isns_req_create(ISNS_FUNC_DEVATTRQRY, ISNS_FLAG_CLIENT); 840 isns_req_add_str(req, 32, TAILQ_FIRST(&conf->conf_targets)->t_name); 841 isns_req_add_str(req, 1, hostname); 842 isns_req_add_delim(req); 843 isns_req_add(req, 2, 0, NULL); 844 res = isns_req_send(s, req); 845 if (res < 0) { 846 log_warn("send(2) failed for %s", isns->i_addr); 847 goto quit; 848 } 849 res = isns_req_receive(s, req); 850 if (res < 0) { 851 log_warn("receive(2) failed for %s", isns->i_addr); 852 goto quit; 853 } 854 error = isns_req_get_status(req); 855 if (error != 0) { 856 log_warnx("iSNS check error %d for %s", error, isns->i_addr); 857 res = -1; 858 } 859 quit: 860 isns_req_free(req); 861 return (res); 862 } 863 864 static int 865 isns_do_deregister(struct isns *isns, int s, const char *hostname) 866 { 867 struct conf *conf = isns->i_conf; 868 struct isns_req *req; 869 int res = 0; 870 uint32_t error; 871 872 req = isns_req_create(ISNS_FUNC_DEVDEREG, ISNS_FLAG_CLIENT); 873 isns_req_add_str(req, 32, TAILQ_FIRST(&conf->conf_targets)->t_name); 874 isns_req_add_delim(req); 875 isns_req_add_str(req, 1, hostname); 876 res = isns_req_send(s, req); 877 if (res < 0) { 878 log_warn("send(2) failed for %s", isns->i_addr); 879 goto quit; 880 } 881 res = isns_req_receive(s, req); 882 if (res < 0) { 883 log_warn("receive(2) failed for %s", isns->i_addr); 884 goto quit; 885 } 886 error = isns_req_get_status(req); 887 if (error != 0) { 888 log_warnx("iSNS deregister error %d for %s", error, isns->i_addr); 889 res = -1; 890 } 891 quit: 892 isns_req_free(req); 893 return (res); 894 } 895 896 void 897 isns_register(struct isns *isns, struct isns *oldisns) 898 { 899 struct conf *conf = isns->i_conf; 900 int s; 901 char hostname[256]; 902 903 if (TAILQ_EMPTY(&conf->conf_targets) || 904 TAILQ_EMPTY(&conf->conf_portal_groups)) 905 return; 906 set_timeout(conf->conf_isns_timeout, false); 907 s = isns_do_connect(isns); 908 if (s < 0) { 909 set_timeout(0, false); 910 return; 911 } 912 gethostname(hostname, sizeof(hostname)); 913 914 if (oldisns == NULL || TAILQ_EMPTY(&oldisns->i_conf->conf_targets)) 915 oldisns = isns; 916 isns_do_deregister(oldisns, s, hostname); 917 isns_do_register(isns, s, hostname); 918 close(s); 919 set_timeout(0, false); 920 } 921 922 void 923 isns_check(struct isns *isns) 924 { 925 struct conf *conf = isns->i_conf; 926 int s, res; 927 char hostname[256]; 928 929 if (TAILQ_EMPTY(&conf->conf_targets) || 930 TAILQ_EMPTY(&conf->conf_portal_groups)) 931 return; 932 set_timeout(conf->conf_isns_timeout, false); 933 s = isns_do_connect(isns); 934 if (s < 0) { 935 set_timeout(0, false); 936 return; 937 } 938 gethostname(hostname, sizeof(hostname)); 939 940 res = isns_do_check(isns, s, hostname); 941 if (res < 0) { 942 isns_do_deregister(isns, s, hostname); 943 isns_do_register(isns, s, hostname); 944 } 945 close(s); 946 set_timeout(0, false); 947 } 948 949 void 950 isns_deregister(struct isns *isns) 951 { 952 struct conf *conf = isns->i_conf; 953 int s; 954 char hostname[256]; 955 956 if (TAILQ_EMPTY(&conf->conf_targets) || 957 TAILQ_EMPTY(&conf->conf_portal_groups)) 958 return; 959 set_timeout(conf->conf_isns_timeout, false); 960 s = isns_do_connect(isns); 961 if (s < 0) 962 return; 963 gethostname(hostname, sizeof(hostname)); 964 965 isns_do_deregister(isns, s, hostname); 966 close(s); 967 set_timeout(0, false); 968 } 969 970 int 971 portal_group_set_filter(struct portal_group *pg, const char *str) 972 { 973 int filter; 974 975 if (strcmp(str, "none") == 0) { 976 filter = PG_FILTER_NONE; 977 } else if (strcmp(str, "portal") == 0) { 978 filter = PG_FILTER_PORTAL; 979 } else if (strcmp(str, "portal-name") == 0) { 980 filter = PG_FILTER_PORTAL_NAME; 981 } else if (strcmp(str, "portal-name-auth") == 0) { 982 filter = PG_FILTER_PORTAL_NAME_AUTH; 983 } else { 984 log_warnx("invalid discovery-filter \"%s\" for portal-group " 985 "\"%s\"; valid values are \"none\", \"portal\", " 986 "\"portal-name\", and \"portal-name-auth\"", 987 str, pg->pg_name); 988 return (1); 989 } 990 991 if (pg->pg_discovery_filter != PG_FILTER_UNKNOWN && 992 pg->pg_discovery_filter != filter) { 993 log_warnx("cannot set discovery-filter to \"%s\" for " 994 "portal-group \"%s\"; already has a different " 995 "value", str, pg->pg_name); 996 return (1); 997 } 998 999 pg->pg_discovery_filter = filter; 1000 1001 return (0); 1002 } 1003 1004 int 1005 portal_group_set_redirection(struct portal_group *pg, const char *addr) 1006 { 1007 1008 if (pg->pg_redirection != NULL) { 1009 log_warnx("cannot set redirection to \"%s\" for " 1010 "portal-group \"%s\"; already defined", 1011 addr, pg->pg_name); 1012 return (1); 1013 } 1014 1015 pg->pg_redirection = checked_strdup(addr); 1016 1017 return (0); 1018 } 1019 1020 static bool 1021 valid_hex(const char ch) 1022 { 1023 switch (ch) { 1024 case '0': 1025 case '1': 1026 case '2': 1027 case '3': 1028 case '4': 1029 case '5': 1030 case '6': 1031 case '7': 1032 case '8': 1033 case '9': 1034 case 'a': 1035 case 'A': 1036 case 'b': 1037 case 'B': 1038 case 'c': 1039 case 'C': 1040 case 'd': 1041 case 'D': 1042 case 'e': 1043 case 'E': 1044 case 'f': 1045 case 'F': 1046 return (true); 1047 default: 1048 return (false); 1049 } 1050 } 1051 1052 bool 1053 valid_iscsi_name(const char *name) 1054 { 1055 int i; 1056 1057 if (strlen(name) >= MAX_NAME_LEN) { 1058 log_warnx("overlong name for target \"%s\"; max length allowed " 1059 "by iSCSI specification is %d characters", 1060 name, MAX_NAME_LEN); 1061 return (false); 1062 } 1063 1064 /* 1065 * In the cases below, we don't return an error, just in case the admin 1066 * was right, and we're wrong. 1067 */ 1068 if (strncasecmp(name, "iqn.", strlen("iqn.")) == 0) { 1069 for (i = strlen("iqn."); name[i] != '\0'; i++) { 1070 /* 1071 * XXX: We should verify UTF-8 normalisation, as defined 1072 * by 3.2.6.2: iSCSI Name Encoding. 1073 */ 1074 if (isalnum(name[i])) 1075 continue; 1076 if (name[i] == '-' || name[i] == '.' || name[i] == ':') 1077 continue; 1078 log_warnx("invalid character \"%c\" in target name " 1079 "\"%s\"; allowed characters are letters, digits, " 1080 "'-', '.', and ':'", name[i], name); 1081 break; 1082 } 1083 /* 1084 * XXX: Check more stuff: valid date and a valid reversed domain. 1085 */ 1086 } else if (strncasecmp(name, "eui.", strlen("eui.")) == 0) { 1087 if (strlen(name) != strlen("eui.") + 16) 1088 log_warnx("invalid target name \"%s\"; the \"eui.\" " 1089 "should be followed by exactly 16 hexadecimal " 1090 "digits", name); 1091 for (i = strlen("eui."); name[i] != '\0'; i++) { 1092 if (!valid_hex(name[i])) { 1093 log_warnx("invalid character \"%c\" in target " 1094 "name \"%s\"; allowed characters are 1-9 " 1095 "and A-F", name[i], name); 1096 break; 1097 } 1098 } 1099 } else if (strncasecmp(name, "naa.", strlen("naa.")) == 0) { 1100 if (strlen(name) > strlen("naa.") + 32) 1101 log_warnx("invalid target name \"%s\"; the \"naa.\" " 1102 "should be followed by at most 32 hexadecimal " 1103 "digits", name); 1104 for (i = strlen("naa."); name[i] != '\0'; i++) { 1105 if (!valid_hex(name[i])) { 1106 log_warnx("invalid character \"%c\" in target " 1107 "name \"%s\"; allowed characters are 1-9 " 1108 "and A-F", name[i], name); 1109 break; 1110 } 1111 } 1112 } else { 1113 log_warnx("invalid target name \"%s\"; should start with " 1114 "either \".iqn\", \"eui.\", or \"naa.\"", 1115 name); 1116 } 1117 return (true); 1118 } 1119 1120 struct target * 1121 target_new(struct conf *conf, const char *name) 1122 { 1123 struct target *targ; 1124 int i, len; 1125 1126 targ = target_find(conf, name); 1127 if (targ != NULL) { 1128 log_warnx("duplicated target \"%s\"", name); 1129 return (NULL); 1130 } 1131 if (valid_iscsi_name(name) == false) { 1132 log_warnx("target name \"%s\" is invalid", name); 1133 return (NULL); 1134 } 1135 targ = calloc(1, sizeof(*targ)); 1136 if (targ == NULL) 1137 log_err(1, "calloc"); 1138 targ->t_name = checked_strdup(name); 1139 1140 /* 1141 * RFC 3722 requires us to normalize the name to lowercase. 1142 */ 1143 len = strlen(name); 1144 for (i = 0; i < len; i++) 1145 targ->t_name[i] = tolower(targ->t_name[i]); 1146 1147 TAILQ_INIT(&targ->t_luns); 1148 targ->t_conf = conf; 1149 TAILQ_INSERT_TAIL(&conf->conf_targets, targ, t_next); 1150 1151 return (targ); 1152 } 1153 1154 void 1155 target_delete(struct target *targ) 1156 { 1157 struct lun *lun, *tmp; 1158 1159 TAILQ_REMOVE(&targ->t_conf->conf_targets, targ, t_next); 1160 1161 TAILQ_FOREACH_SAFE(lun, &targ->t_luns, l_next, tmp) 1162 lun_delete(lun); 1163 free(targ->t_name); 1164 free(targ->t_redirection); 1165 free(targ); 1166 } 1167 1168 struct target * 1169 target_find(struct conf *conf, const char *name) 1170 { 1171 struct target *targ; 1172 1173 TAILQ_FOREACH(targ, &conf->conf_targets, t_next) { 1174 if (strcasecmp(targ->t_name, name) == 0) 1175 return (targ); 1176 } 1177 1178 return (NULL); 1179 } 1180 1181 int 1182 target_set_redirection(struct target *target, const char *addr) 1183 { 1184 1185 if (target->t_redirection != NULL) { 1186 log_warnx("cannot set redirection to \"%s\" for " 1187 "target \"%s\"; already defined", 1188 addr, target->t_name); 1189 return (1); 1190 } 1191 1192 target->t_redirection = checked_strdup(addr); 1193 1194 return (0); 1195 } 1196 1197 struct lun * 1198 lun_new(struct target *targ, int lun_id) 1199 { 1200 struct lun *lun; 1201 1202 lun = lun_find(targ, lun_id); 1203 if (lun != NULL) { 1204 log_warnx("duplicated lun %d for target \"%s\"", 1205 lun_id, targ->t_name); 1206 return (NULL); 1207 } 1208 1209 lun = calloc(1, sizeof(*lun)); 1210 if (lun == NULL) 1211 log_err(1, "calloc"); 1212 lun->l_lun = lun_id; 1213 TAILQ_INIT(&lun->l_options); 1214 lun->l_target = targ; 1215 TAILQ_INSERT_TAIL(&targ->t_luns, lun, l_next); 1216 1217 return (lun); 1218 } 1219 1220 void 1221 lun_delete(struct lun *lun) 1222 { 1223 struct lun_option *lo, *tmp; 1224 1225 TAILQ_REMOVE(&lun->l_target->t_luns, lun, l_next); 1226 1227 TAILQ_FOREACH_SAFE(lo, &lun->l_options, lo_next, tmp) 1228 lun_option_delete(lo); 1229 free(lun->l_backend); 1230 free(lun->l_device_id); 1231 free(lun->l_path); 1232 free(lun->l_serial); 1233 free(lun); 1234 } 1235 1236 struct lun * 1237 lun_find(const struct target *targ, int lun_id) 1238 { 1239 struct lun *lun; 1240 1241 TAILQ_FOREACH(lun, &targ->t_luns, l_next) { 1242 if (lun->l_lun == lun_id) 1243 return (lun); 1244 } 1245 1246 return (NULL); 1247 } 1248 1249 void 1250 lun_set_backend(struct lun *lun, const char *value) 1251 { 1252 free(lun->l_backend); 1253 lun->l_backend = checked_strdup(value); 1254 } 1255 1256 void 1257 lun_set_blocksize(struct lun *lun, size_t value) 1258 { 1259 1260 lun->l_blocksize = value; 1261 } 1262 1263 void 1264 lun_set_device_id(struct lun *lun, const char *value) 1265 { 1266 free(lun->l_device_id); 1267 lun->l_device_id = checked_strdup(value); 1268 } 1269 1270 void 1271 lun_set_path(struct lun *lun, const char *value) 1272 { 1273 free(lun->l_path); 1274 lun->l_path = checked_strdup(value); 1275 } 1276 1277 void 1278 lun_set_serial(struct lun *lun, const char *value) 1279 { 1280 free(lun->l_serial); 1281 lun->l_serial = checked_strdup(value); 1282 } 1283 1284 void 1285 lun_set_size(struct lun *lun, size_t value) 1286 { 1287 1288 lun->l_size = value; 1289 } 1290 1291 void 1292 lun_set_ctl_lun(struct lun *lun, uint32_t value) 1293 { 1294 1295 lun->l_ctl_lun = value; 1296 } 1297 1298 struct lun_option * 1299 lun_option_new(struct lun *lun, const char *name, const char *value) 1300 { 1301 struct lun_option *lo; 1302 1303 lo = lun_option_find(lun, name); 1304 if (lo != NULL) { 1305 log_warnx("duplicated lun option %s for lun %d, target \"%s\"", 1306 name, lun->l_lun, lun->l_target->t_name); 1307 return (NULL); 1308 } 1309 1310 lo = calloc(1, sizeof(*lo)); 1311 if (lo == NULL) 1312 log_err(1, "calloc"); 1313 lo->lo_name = checked_strdup(name); 1314 lo->lo_value = checked_strdup(value); 1315 lo->lo_lun = lun; 1316 TAILQ_INSERT_TAIL(&lun->l_options, lo, lo_next); 1317 1318 return (lo); 1319 } 1320 1321 void 1322 lun_option_delete(struct lun_option *lo) 1323 { 1324 1325 TAILQ_REMOVE(&lo->lo_lun->l_options, lo, lo_next); 1326 1327 free(lo->lo_name); 1328 free(lo->lo_value); 1329 free(lo); 1330 } 1331 1332 struct lun_option * 1333 lun_option_find(const struct lun *lun, const char *name) 1334 { 1335 struct lun_option *lo; 1336 1337 TAILQ_FOREACH(lo, &lun->l_options, lo_next) { 1338 if (strcmp(lo->lo_name, name) == 0) 1339 return (lo); 1340 } 1341 1342 return (NULL); 1343 } 1344 1345 void 1346 lun_option_set(struct lun_option *lo, const char *value) 1347 { 1348 1349 free(lo->lo_value); 1350 lo->lo_value = checked_strdup(value); 1351 } 1352 1353 static struct connection * 1354 connection_new(struct portal *portal, int fd, const char *host, 1355 const struct sockaddr *client_sa) 1356 { 1357 struct connection *conn; 1358 1359 conn = calloc(1, sizeof(*conn)); 1360 if (conn == NULL) 1361 log_err(1, "calloc"); 1362 conn->conn_portal = portal; 1363 conn->conn_socket = fd; 1364 conn->conn_initiator_addr = checked_strdup(host); 1365 memcpy(&conn->conn_initiator_sa, client_sa, client_sa->sa_len); 1366 1367 /* 1368 * Default values, from RFC 3720, section 12. 1369 */ 1370 conn->conn_max_data_segment_length = 8192; 1371 conn->conn_max_burst_length = 262144; 1372 conn->conn_immediate_data = true; 1373 1374 return (conn); 1375 } 1376 1377 #if 0 1378 static void 1379 conf_print(struct conf *conf) 1380 { 1381 struct auth_group *ag; 1382 struct auth *auth; 1383 struct auth_name *auth_name; 1384 struct auth_portal *auth_portal; 1385 struct portal_group *pg; 1386 struct portal *portal; 1387 struct target *targ; 1388 struct lun *lun; 1389 struct lun_option *lo; 1390 1391 TAILQ_FOREACH(ag, &conf->conf_auth_groups, ag_next) { 1392 fprintf(stderr, "auth-group %s {\n", ag->ag_name); 1393 TAILQ_FOREACH(auth, &ag->ag_auths, a_next) 1394 fprintf(stderr, "\t chap-mutual %s %s %s %s\n", 1395 auth->a_user, auth->a_secret, 1396 auth->a_mutual_user, auth->a_mutual_secret); 1397 TAILQ_FOREACH(auth_name, &ag->ag_names, an_next) 1398 fprintf(stderr, "\t initiator-name %s\n", 1399 auth_name->an_initator_name); 1400 TAILQ_FOREACH(auth_portal, &ag->ag_portals, an_next) 1401 fprintf(stderr, "\t initiator-portal %s\n", 1402 auth_portal->an_initator_portal); 1403 fprintf(stderr, "}\n"); 1404 } 1405 TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) { 1406 fprintf(stderr, "portal-group %s {\n", pg->pg_name); 1407 TAILQ_FOREACH(portal, &pg->pg_portals, p_next) 1408 fprintf(stderr, "\t listen %s\n", portal->p_listen); 1409 fprintf(stderr, "}\n"); 1410 } 1411 TAILQ_FOREACH(targ, &conf->conf_targets, t_next) { 1412 fprintf(stderr, "target %s {\n", targ->t_name); 1413 if (targ->t_alias != NULL) 1414 fprintf(stderr, "\t alias %s\n", targ->t_alias); 1415 TAILQ_FOREACH(lun, &targ->t_luns, l_next) { 1416 fprintf(stderr, "\tlun %d {\n", lun->l_lun); 1417 fprintf(stderr, "\t\tpath %s\n", lun->l_path); 1418 TAILQ_FOREACH(lo, &lun->l_options, lo_next) 1419 fprintf(stderr, "\t\toption %s %s\n", 1420 lo->lo_name, lo->lo_value); 1421 fprintf(stderr, "\t}\n"); 1422 } 1423 fprintf(stderr, "}\n"); 1424 } 1425 } 1426 #endif 1427 1428 static int 1429 conf_verify_lun(struct lun *lun) 1430 { 1431 const struct lun *lun2; 1432 const struct target *targ2; 1433 1434 if (lun->l_backend == NULL) 1435 lun_set_backend(lun, "block"); 1436 if (strcmp(lun->l_backend, "block") == 0) { 1437 if (lun->l_path == NULL) { 1438 log_warnx("missing path for lun %d, target \"%s\"", 1439 lun->l_lun, lun->l_target->t_name); 1440 return (1); 1441 } 1442 } else if (strcmp(lun->l_backend, "ramdisk") == 0) { 1443 if (lun->l_size == 0) { 1444 log_warnx("missing size for ramdisk-backed lun %d, " 1445 "target \"%s\"", lun->l_lun, lun->l_target->t_name); 1446 return (1); 1447 } 1448 if (lun->l_path != NULL) { 1449 log_warnx("path must not be specified " 1450 "for ramdisk-backed lun %d, target \"%s\"", 1451 lun->l_lun, lun->l_target->t_name); 1452 return (1); 1453 } 1454 } 1455 if (lun->l_lun < 0 || lun->l_lun > 255) { 1456 log_warnx("invalid lun number for lun %d, target \"%s\"; " 1457 "must be between 0 and 255", lun->l_lun, 1458 lun->l_target->t_name); 1459 return (1); 1460 } 1461 if (lun->l_blocksize == 0) { 1462 lun_set_blocksize(lun, DEFAULT_BLOCKSIZE); 1463 } else if (lun->l_blocksize < 0) { 1464 log_warnx("invalid blocksize for lun %d, target \"%s\"; " 1465 "must be larger than 0", lun->l_lun, lun->l_target->t_name); 1466 return (1); 1467 } 1468 if (lun->l_size != 0 && lun->l_size % lun->l_blocksize != 0) { 1469 log_warnx("invalid size for lun %d, target \"%s\"; " 1470 "must be multiple of blocksize", lun->l_lun, 1471 lun->l_target->t_name); 1472 return (1); 1473 } 1474 TAILQ_FOREACH(targ2, &lun->l_target->t_conf->conf_targets, t_next) { 1475 TAILQ_FOREACH(lun2, &targ2->t_luns, l_next) { 1476 if (lun == lun2) 1477 continue; 1478 if (lun->l_path != NULL && lun2->l_path != NULL && 1479 strcmp(lun->l_path, lun2->l_path) == 0) { 1480 log_debugx("WARNING: path \"%s\" duplicated " 1481 "between lun %d, target \"%s\", and " 1482 "lun %d, target \"%s\"", lun->l_path, 1483 lun->l_lun, lun->l_target->t_name, 1484 lun2->l_lun, lun2->l_target->t_name); 1485 } 1486 } 1487 } 1488 1489 return (0); 1490 } 1491 1492 int 1493 conf_verify(struct conf *conf) 1494 { 1495 struct auth_group *ag; 1496 struct portal_group *pg; 1497 struct target *targ; 1498 struct lun *lun; 1499 bool found; 1500 int error; 1501 1502 if (conf->conf_pidfile_path == NULL) 1503 conf->conf_pidfile_path = checked_strdup(DEFAULT_PIDFILE); 1504 1505 TAILQ_FOREACH(targ, &conf->conf_targets, t_next) { 1506 if (targ->t_auth_group == NULL) { 1507 targ->t_auth_group = auth_group_find(conf, 1508 "default"); 1509 assert(targ->t_auth_group != NULL); 1510 } 1511 if (targ->t_portal_group == NULL) { 1512 targ->t_portal_group = portal_group_find(conf, 1513 "default"); 1514 assert(targ->t_portal_group != NULL); 1515 } 1516 found = false; 1517 TAILQ_FOREACH(lun, &targ->t_luns, l_next) { 1518 error = conf_verify_lun(lun); 1519 if (error != 0) 1520 return (error); 1521 found = true; 1522 } 1523 if (!found && targ->t_redirection == NULL) { 1524 log_warnx("no LUNs defined for target \"%s\"", 1525 targ->t_name); 1526 } 1527 if (found && targ->t_redirection != NULL) { 1528 log_debugx("target \"%s\" contains luns, " 1529 " but configured for redirection", 1530 targ->t_name); 1531 } 1532 } 1533 TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) { 1534 assert(pg->pg_name != NULL); 1535 if (pg->pg_discovery_auth_group == NULL) { 1536 pg->pg_discovery_auth_group = 1537 auth_group_find(conf, "default"); 1538 assert(pg->pg_discovery_auth_group != NULL); 1539 } 1540 1541 if (pg->pg_discovery_filter == PG_FILTER_UNKNOWN) 1542 pg->pg_discovery_filter = PG_FILTER_NONE; 1543 1544 TAILQ_FOREACH(targ, &conf->conf_targets, t_next) { 1545 if (targ->t_portal_group == pg) 1546 break; 1547 } 1548 if (pg->pg_redirection != NULL) { 1549 if (targ != NULL) { 1550 log_debugx("portal-group \"%s\" assigned " 1551 "to target \"%s\", but configured " 1552 "for redirection", 1553 pg->pg_name, targ->t_name); 1554 } 1555 pg->pg_unassigned = false; 1556 } else if (targ != NULL) { 1557 pg->pg_unassigned = false; 1558 } else { 1559 if (strcmp(pg->pg_name, "default") != 0) 1560 log_warnx("portal-group \"%s\" not assigned " 1561 "to any target", pg->pg_name); 1562 pg->pg_unassigned = true; 1563 } 1564 } 1565 TAILQ_FOREACH(ag, &conf->conf_auth_groups, ag_next) { 1566 if (ag->ag_name == NULL) 1567 assert(ag->ag_target != NULL); 1568 else 1569 assert(ag->ag_target == NULL); 1570 1571 found = false; 1572 TAILQ_FOREACH(targ, &conf->conf_targets, t_next) { 1573 if (targ->t_auth_group == ag) { 1574 found = true; 1575 break; 1576 } 1577 } 1578 TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) { 1579 if (pg->pg_discovery_auth_group == ag) { 1580 found = true; 1581 break; 1582 } 1583 } 1584 if (!found && ag->ag_name != NULL && 1585 strcmp(ag->ag_name, "default") != 0 && 1586 strcmp(ag->ag_name, "no-authentication") != 0 && 1587 strcmp(ag->ag_name, "no-access") != 0) { 1588 log_warnx("auth-group \"%s\" not assigned " 1589 "to any target", ag->ag_name); 1590 } 1591 } 1592 1593 return (0); 1594 } 1595 1596 static int 1597 conf_apply(struct conf *oldconf, struct conf *newconf) 1598 { 1599 struct target *oldtarg, *newtarg, *tmptarg; 1600 struct lun *oldlun, *newlun, *tmplun; 1601 struct portal_group *oldpg, *newpg; 1602 struct portal *oldp, *newp; 1603 struct isns *oldns, *newns; 1604 pid_t otherpid; 1605 int changed, cumulated_error = 0, error; 1606 int one = 1; 1607 1608 if (oldconf->conf_debug != newconf->conf_debug) { 1609 log_debugx("changing debug level to %d", newconf->conf_debug); 1610 log_init(newconf->conf_debug); 1611 } 1612 1613 if (oldconf->conf_pidfh != NULL) { 1614 assert(oldconf->conf_pidfile_path != NULL); 1615 if (newconf->conf_pidfile_path != NULL && 1616 strcmp(oldconf->conf_pidfile_path, 1617 newconf->conf_pidfile_path) == 0) { 1618 newconf->conf_pidfh = oldconf->conf_pidfh; 1619 oldconf->conf_pidfh = NULL; 1620 } else { 1621 log_debugx("removing pidfile %s", 1622 oldconf->conf_pidfile_path); 1623 pidfile_remove(oldconf->conf_pidfh); 1624 oldconf->conf_pidfh = NULL; 1625 } 1626 } 1627 1628 if (newconf->conf_pidfh == NULL && newconf->conf_pidfile_path != NULL) { 1629 log_debugx("opening pidfile %s", newconf->conf_pidfile_path); 1630 newconf->conf_pidfh = 1631 pidfile_open(newconf->conf_pidfile_path, 0600, &otherpid); 1632 if (newconf->conf_pidfh == NULL) { 1633 if (errno == EEXIST) 1634 log_errx(1, "daemon already running, pid: %jd.", 1635 (intmax_t)otherpid); 1636 log_err(1, "cannot open or create pidfile \"%s\"", 1637 newconf->conf_pidfile_path); 1638 } 1639 } 1640 1641 /* Deregister on removed iSNS servers. */ 1642 TAILQ_FOREACH(oldns, &oldconf->conf_isns, i_next) { 1643 TAILQ_FOREACH(newns, &newconf->conf_isns, i_next) { 1644 if (strcmp(oldns->i_addr, newns->i_addr) == 0) 1645 break; 1646 } 1647 if (newns == NULL) 1648 isns_deregister(oldns); 1649 } 1650 1651 /* 1652 * XXX: If target or lun removal fails, we should somehow "move" 1653 * the old lun or target into newconf, so that subsequent 1654 * conf_apply() would try to remove them again. That would 1655 * be somewhat hairy, though, and lun deletion failures don't 1656 * really happen, so leave it as it is for now. 1657 */ 1658 TAILQ_FOREACH_SAFE(oldtarg, &oldconf->conf_targets, t_next, tmptarg) { 1659 /* 1660 * First, remove any targets present in the old configuration 1661 * and missing in the new one. 1662 */ 1663 newtarg = target_find(newconf, oldtarg->t_name); 1664 if (newtarg == NULL) { 1665 TAILQ_FOREACH_SAFE(oldlun, &oldtarg->t_luns, l_next, 1666 tmplun) { 1667 log_debugx("target %s not found in new " 1668 "configuration; removing its lun %d, " 1669 "backed by CTL lun %d", 1670 oldtarg->t_name, oldlun->l_lun, 1671 oldlun->l_ctl_lun); 1672 error = kernel_lun_remove(oldlun); 1673 if (error != 0) { 1674 log_warnx("failed to remove lun %d, " 1675 "target %s, CTL lun %d", 1676 oldlun->l_lun, oldtarg->t_name, 1677 oldlun->l_ctl_lun); 1678 cumulated_error++; 1679 } 1680 } 1681 kernel_port_remove(oldtarg); 1682 continue; 1683 } 1684 1685 /* 1686 * Second, remove any LUNs present in the old target 1687 * and missing in the new one. 1688 */ 1689 TAILQ_FOREACH_SAFE(oldlun, &oldtarg->t_luns, l_next, tmplun) { 1690 newlun = lun_find(newtarg, oldlun->l_lun); 1691 if (newlun == NULL) { 1692 log_debugx("lun %d, target %s, CTL lun %d " 1693 "not found in new configuration; " 1694 "removing", oldlun->l_lun, oldtarg->t_name, 1695 oldlun->l_ctl_lun); 1696 error = kernel_lun_remove(oldlun); 1697 if (error != 0) { 1698 log_warnx("failed to remove lun %d, " 1699 "target %s, CTL lun %d", 1700 oldlun->l_lun, oldtarg->t_name, 1701 oldlun->l_ctl_lun); 1702 cumulated_error++; 1703 } 1704 continue; 1705 } 1706 1707 /* 1708 * Also remove the LUNs changed by more than size. 1709 */ 1710 changed = 0; 1711 assert(oldlun->l_backend != NULL); 1712 assert(newlun->l_backend != NULL); 1713 if (strcmp(newlun->l_backend, oldlun->l_backend) != 0) { 1714 log_debugx("backend for lun %d, target %s, " 1715 "CTL lun %d changed; removing", 1716 oldlun->l_lun, oldtarg->t_name, 1717 oldlun->l_ctl_lun); 1718 changed = 1; 1719 } 1720 if (oldlun->l_blocksize != newlun->l_blocksize) { 1721 log_debugx("blocksize for lun %d, target %s, " 1722 "CTL lun %d changed; removing", 1723 oldlun->l_lun, oldtarg->t_name, 1724 oldlun->l_ctl_lun); 1725 changed = 1; 1726 } 1727 if (newlun->l_device_id != NULL && 1728 (oldlun->l_device_id == NULL || 1729 strcmp(oldlun->l_device_id, newlun->l_device_id) != 1730 0)) { 1731 log_debugx("device-id for lun %d, target %s, " 1732 "CTL lun %d changed; removing", 1733 oldlun->l_lun, oldtarg->t_name, 1734 oldlun->l_ctl_lun); 1735 changed = 1; 1736 } 1737 if (newlun->l_path != NULL && 1738 (oldlun->l_path == NULL || 1739 strcmp(oldlun->l_path, newlun->l_path) != 0)) { 1740 log_debugx("path for lun %d, target %s, " 1741 "CTL lun %d, changed; removing", 1742 oldlun->l_lun, oldtarg->t_name, 1743 oldlun->l_ctl_lun); 1744 changed = 1; 1745 } 1746 if (newlun->l_serial != NULL && 1747 (oldlun->l_serial == NULL || 1748 strcmp(oldlun->l_serial, newlun->l_serial) != 0)) { 1749 log_debugx("serial for lun %d, target %s, " 1750 "CTL lun %d changed; removing", 1751 oldlun->l_lun, oldtarg->t_name, 1752 oldlun->l_ctl_lun); 1753 changed = 1; 1754 } 1755 if (changed) { 1756 error = kernel_lun_remove(oldlun); 1757 if (error != 0) { 1758 log_warnx("failed to remove lun %d, " 1759 "target %s, CTL lun %d", 1760 oldlun->l_lun, oldtarg->t_name, 1761 oldlun->l_ctl_lun); 1762 cumulated_error++; 1763 } 1764 lun_delete(oldlun); 1765 continue; 1766 } 1767 1768 lun_set_ctl_lun(newlun, oldlun->l_ctl_lun); 1769 } 1770 } 1771 1772 /* 1773 * Now add new targets or modify existing ones. 1774 */ 1775 TAILQ_FOREACH(newtarg, &newconf->conf_targets, t_next) { 1776 oldtarg = target_find(oldconf, newtarg->t_name); 1777 1778 TAILQ_FOREACH_SAFE(newlun, &newtarg->t_luns, l_next, tmplun) { 1779 if (oldtarg != NULL) { 1780 oldlun = lun_find(oldtarg, newlun->l_lun); 1781 if (oldlun != NULL) { 1782 if (newlun->l_size != oldlun->l_size || 1783 newlun->l_size == 0) { 1784 log_debugx("resizing lun %d, " 1785 "target %s, CTL lun %d", 1786 newlun->l_lun, 1787 newtarg->t_name, 1788 newlun->l_ctl_lun); 1789 error = 1790 kernel_lun_resize(newlun); 1791 if (error != 0) { 1792 log_warnx("failed to " 1793 "resize lun %d, " 1794 "target %s, " 1795 "CTL lun %d", 1796 newlun->l_lun, 1797 newtarg->t_name, 1798 newlun->l_lun); 1799 cumulated_error++; 1800 } 1801 } 1802 continue; 1803 } 1804 } 1805 log_debugx("adding lun %d, target %s", 1806 newlun->l_lun, newtarg->t_name); 1807 error = kernel_lun_add(newlun); 1808 if (error != 0) { 1809 log_warnx("failed to add lun %d, target %s", 1810 newlun->l_lun, newtarg->t_name); 1811 lun_delete(newlun); 1812 cumulated_error++; 1813 } 1814 } 1815 if (oldtarg == NULL) 1816 kernel_port_add(newtarg); 1817 } 1818 1819 /* 1820 * Go through the new portals, opening the sockets as neccessary. 1821 */ 1822 TAILQ_FOREACH(newpg, &newconf->conf_portal_groups, pg_next) { 1823 if (newpg->pg_unassigned) { 1824 log_debugx("not listening on portal-group \"%s\", " 1825 "not assigned to any target", 1826 newpg->pg_name); 1827 continue; 1828 } 1829 TAILQ_FOREACH(newp, &newpg->pg_portals, p_next) { 1830 /* 1831 * Try to find already open portal and reuse 1832 * the listening socket. We don't care about 1833 * what portal or portal group that was, what 1834 * matters is the listening address. 1835 */ 1836 TAILQ_FOREACH(oldpg, &oldconf->conf_portal_groups, 1837 pg_next) { 1838 TAILQ_FOREACH(oldp, &oldpg->pg_portals, 1839 p_next) { 1840 if (strcmp(newp->p_listen, 1841 oldp->p_listen) == 0 && 1842 oldp->p_socket > 0) { 1843 newp->p_socket = 1844 oldp->p_socket; 1845 oldp->p_socket = 0; 1846 break; 1847 } 1848 } 1849 } 1850 if (newp->p_socket > 0) { 1851 /* 1852 * We're done with this portal. 1853 */ 1854 continue; 1855 } 1856 1857 #ifdef ICL_KERNEL_PROXY 1858 if (proxy_mode) { 1859 newpg->pg_conf->conf_portal_id++; 1860 newp->p_id = newpg->pg_conf->conf_portal_id; 1861 log_debugx("listening on %s, portal-group " 1862 "\"%s\", portal id %d, using ICL proxy", 1863 newp->p_listen, newpg->pg_name, newp->p_id); 1864 kernel_listen(newp->p_ai, newp->p_iser, 1865 newp->p_id); 1866 continue; 1867 } 1868 #endif 1869 assert(proxy_mode == false); 1870 assert(newp->p_iser == false); 1871 1872 log_debugx("listening on %s, portal-group \"%s\"", 1873 newp->p_listen, newpg->pg_name); 1874 newp->p_socket = socket(newp->p_ai->ai_family, 1875 newp->p_ai->ai_socktype, 1876 newp->p_ai->ai_protocol); 1877 if (newp->p_socket < 0) { 1878 log_warn("socket(2) failed for %s", 1879 newp->p_listen); 1880 cumulated_error++; 1881 continue; 1882 } 1883 error = setsockopt(newp->p_socket, SOL_SOCKET, 1884 SO_REUSEADDR, &one, sizeof(one)); 1885 if (error != 0) { 1886 log_warn("setsockopt(SO_REUSEADDR) failed " 1887 "for %s", newp->p_listen); 1888 close(newp->p_socket); 1889 newp->p_socket = 0; 1890 cumulated_error++; 1891 continue; 1892 } 1893 error = bind(newp->p_socket, newp->p_ai->ai_addr, 1894 newp->p_ai->ai_addrlen); 1895 if (error != 0) { 1896 log_warn("bind(2) failed for %s", 1897 newp->p_listen); 1898 close(newp->p_socket); 1899 newp->p_socket = 0; 1900 cumulated_error++; 1901 continue; 1902 } 1903 error = listen(newp->p_socket, -1); 1904 if (error != 0) { 1905 log_warn("listen(2) failed for %s", 1906 newp->p_listen); 1907 close(newp->p_socket); 1908 newp->p_socket = 0; 1909 cumulated_error++; 1910 continue; 1911 } 1912 } 1913 } 1914 1915 /* 1916 * Go through the no longer used sockets, closing them. 1917 */ 1918 TAILQ_FOREACH(oldpg, &oldconf->conf_portal_groups, pg_next) { 1919 TAILQ_FOREACH(oldp, &oldpg->pg_portals, p_next) { 1920 if (oldp->p_socket <= 0) 1921 continue; 1922 log_debugx("closing socket for %s, portal-group \"%s\"", 1923 oldp->p_listen, oldpg->pg_name); 1924 close(oldp->p_socket); 1925 oldp->p_socket = 0; 1926 } 1927 } 1928 1929 /* (Re-)Register on remaining/new iSNS servers. */ 1930 TAILQ_FOREACH(newns, &newconf->conf_isns, i_next) { 1931 TAILQ_FOREACH(oldns, &oldconf->conf_isns, i_next) { 1932 if (strcmp(oldns->i_addr, newns->i_addr) == 0) 1933 break; 1934 } 1935 isns_register(newns, oldns); 1936 } 1937 1938 /* Schedule iSNS update */ 1939 if (!TAILQ_EMPTY(&newconf->conf_isns)) 1940 set_timeout((newconf->conf_isns_period + 2) / 3, false); 1941 1942 return (cumulated_error); 1943 } 1944 1945 bool 1946 timed_out(void) 1947 { 1948 1949 return (sigalrm_received); 1950 } 1951 1952 static void 1953 sigalrm_handler_fatal(int dummy __unused) 1954 { 1955 /* 1956 * It would be easiest to just log an error and exit. We can't 1957 * do this, though, because log_errx() is not signal safe, since 1958 * it calls syslog(3). Instead, set a flag checked by pdu_send() 1959 * and pdu_receive(), to call log_errx() there. Should they fail 1960 * to notice, we'll exit here one second later. 1961 */ 1962 if (sigalrm_received) { 1963 /* 1964 * Oh well. Just give up and quit. 1965 */ 1966 _exit(2); 1967 } 1968 1969 sigalrm_received = true; 1970 } 1971 1972 static void 1973 sigalrm_handler(int dummy __unused) 1974 { 1975 1976 sigalrm_received = true; 1977 } 1978 1979 void 1980 set_timeout(int timeout, int fatal) 1981 { 1982 struct sigaction sa; 1983 struct itimerval itv; 1984 int error; 1985 1986 if (timeout <= 0) { 1987 log_debugx("session timeout disabled"); 1988 bzero(&itv, sizeof(itv)); 1989 error = setitimer(ITIMER_REAL, &itv, NULL); 1990 if (error != 0) 1991 log_err(1, "setitimer"); 1992 sigalrm_received = false; 1993 return; 1994 } 1995 1996 sigalrm_received = false; 1997 bzero(&sa, sizeof(sa)); 1998 if (fatal) 1999 sa.sa_handler = sigalrm_handler_fatal; 2000 else 2001 sa.sa_handler = sigalrm_handler; 2002 sigfillset(&sa.sa_mask); 2003 error = sigaction(SIGALRM, &sa, NULL); 2004 if (error != 0) 2005 log_err(1, "sigaction"); 2006 2007 /* 2008 * First SIGALRM will arive after conf_timeout seconds. 2009 * If we do nothing, another one will arrive a second later. 2010 */ 2011 log_debugx("setting session timeout to %d seconds", timeout); 2012 bzero(&itv, sizeof(itv)); 2013 itv.it_interval.tv_sec = 1; 2014 itv.it_value.tv_sec = timeout; 2015 error = setitimer(ITIMER_REAL, &itv, NULL); 2016 if (error != 0) 2017 log_err(1, "setitimer"); 2018 } 2019 2020 static int 2021 wait_for_children(bool block) 2022 { 2023 pid_t pid; 2024 int status; 2025 int num = 0; 2026 2027 for (;;) { 2028 /* 2029 * If "block" is true, wait for at least one process. 2030 */ 2031 if (block && num == 0) 2032 pid = wait4(-1, &status, 0, NULL); 2033 else 2034 pid = wait4(-1, &status, WNOHANG, NULL); 2035 if (pid <= 0) 2036 break; 2037 if (WIFSIGNALED(status)) { 2038 log_warnx("child process %d terminated with signal %d", 2039 pid, WTERMSIG(status)); 2040 } else if (WEXITSTATUS(status) != 0) { 2041 log_warnx("child process %d terminated with exit status %d", 2042 pid, WEXITSTATUS(status)); 2043 } else { 2044 log_debugx("child process %d terminated gracefully", pid); 2045 } 2046 num++; 2047 } 2048 2049 return (num); 2050 } 2051 2052 static void 2053 handle_connection(struct portal *portal, int fd, 2054 const struct sockaddr *client_sa, bool dont_fork) 2055 { 2056 struct connection *conn; 2057 int error; 2058 pid_t pid; 2059 char host[NI_MAXHOST + 1]; 2060 struct conf *conf; 2061 2062 conf = portal->p_portal_group->pg_conf; 2063 2064 if (dont_fork) { 2065 log_debugx("incoming connection; not forking due to -d flag"); 2066 } else { 2067 nchildren -= wait_for_children(false); 2068 assert(nchildren >= 0); 2069 2070 while (conf->conf_maxproc > 0 && nchildren >= conf->conf_maxproc) { 2071 log_debugx("maxproc limit of %d child processes hit; " 2072 "waiting for child process to exit", conf->conf_maxproc); 2073 nchildren -= wait_for_children(true); 2074 assert(nchildren >= 0); 2075 } 2076 log_debugx("incoming connection; forking child process #%d", 2077 nchildren); 2078 nchildren++; 2079 pid = fork(); 2080 if (pid < 0) 2081 log_err(1, "fork"); 2082 if (pid > 0) { 2083 close(fd); 2084 return; 2085 } 2086 } 2087 pidfile_close(conf->conf_pidfh); 2088 2089 error = getnameinfo(client_sa, client_sa->sa_len, 2090 host, sizeof(host), NULL, 0, NI_NUMERICHOST); 2091 if (error != 0) 2092 log_errx(1, "getnameinfo: %s", gai_strerror(error)); 2093 2094 log_debugx("accepted connection from %s; portal group \"%s\"", 2095 host, portal->p_portal_group->pg_name); 2096 log_set_peer_addr(host); 2097 setproctitle("%s", host); 2098 2099 conn = connection_new(portal, fd, host, client_sa); 2100 set_timeout(conf->conf_timeout, true); 2101 kernel_capsicate(); 2102 login(conn); 2103 if (conn->conn_session_type == CONN_SESSION_TYPE_NORMAL) { 2104 kernel_handoff(conn); 2105 log_debugx("connection handed off to the kernel"); 2106 } else { 2107 assert(conn->conn_session_type == CONN_SESSION_TYPE_DISCOVERY); 2108 discovery(conn); 2109 } 2110 log_debugx("nothing more to do; exiting"); 2111 exit(0); 2112 } 2113 2114 static int 2115 fd_add(int fd, fd_set *fdset, int nfds) 2116 { 2117 2118 /* 2119 * Skip sockets which we failed to bind. 2120 */ 2121 if (fd <= 0) 2122 return (nfds); 2123 2124 FD_SET(fd, fdset); 2125 if (fd > nfds) 2126 nfds = fd; 2127 return (nfds); 2128 } 2129 2130 static void 2131 main_loop(struct conf *conf, bool dont_fork) 2132 { 2133 struct portal_group *pg; 2134 struct portal *portal; 2135 struct sockaddr_storage client_sa; 2136 socklen_t client_salen; 2137 #ifdef ICL_KERNEL_PROXY 2138 int connection_id; 2139 int portal_id; 2140 #endif 2141 fd_set fdset; 2142 int error, nfds, client_fd; 2143 2144 pidfile_write(conf->conf_pidfh); 2145 2146 for (;;) { 2147 if (sighup_received || sigterm_received || timed_out()) 2148 return; 2149 2150 #ifdef ICL_KERNEL_PROXY 2151 if (proxy_mode) { 2152 client_salen = sizeof(client_sa); 2153 kernel_accept(&connection_id, &portal_id, 2154 (struct sockaddr *)&client_sa, &client_salen); 2155 assert(client_salen >= client_sa.ss_len); 2156 2157 log_debugx("incoming connection, id %d, portal id %d", 2158 connection_id, portal_id); 2159 TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) { 2160 TAILQ_FOREACH(portal, &pg->pg_portals, p_next) { 2161 if (portal->p_id == portal_id) { 2162 goto found; 2163 } 2164 } 2165 } 2166 2167 log_errx(1, "kernel returned invalid portal_id %d", 2168 portal_id); 2169 2170 found: 2171 handle_connection(portal, connection_id, 2172 (struct sockaddr *)&client_sa, dont_fork); 2173 } else { 2174 #endif 2175 assert(proxy_mode == false); 2176 2177 FD_ZERO(&fdset); 2178 nfds = 0; 2179 TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) { 2180 TAILQ_FOREACH(portal, &pg->pg_portals, p_next) 2181 nfds = fd_add(portal->p_socket, &fdset, nfds); 2182 } 2183 error = select(nfds + 1, &fdset, NULL, NULL, NULL); 2184 if (error <= 0) { 2185 if (errno == EINTR) 2186 return; 2187 log_err(1, "select"); 2188 } 2189 TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) { 2190 TAILQ_FOREACH(portal, &pg->pg_portals, p_next) { 2191 if (!FD_ISSET(portal->p_socket, &fdset)) 2192 continue; 2193 client_salen = sizeof(client_sa); 2194 client_fd = accept(portal->p_socket, 2195 (struct sockaddr *)&client_sa, 2196 &client_salen); 2197 if (client_fd < 0) 2198 log_err(1, "accept"); 2199 assert(client_salen >= client_sa.ss_len); 2200 2201 handle_connection(portal, client_fd, 2202 (struct sockaddr *)&client_sa, 2203 dont_fork); 2204 break; 2205 } 2206 } 2207 #ifdef ICL_KERNEL_PROXY 2208 } 2209 #endif 2210 } 2211 } 2212 2213 static void 2214 sighup_handler(int dummy __unused) 2215 { 2216 2217 sighup_received = true; 2218 } 2219 2220 static void 2221 sigterm_handler(int dummy __unused) 2222 { 2223 2224 sigterm_received = true; 2225 } 2226 2227 static void 2228 sigchld_handler(int dummy __unused) 2229 { 2230 2231 /* 2232 * The only purpose of this handler is to make SIGCHLD 2233 * interrupt the ISCSIDWAIT ioctl(2), so we can call 2234 * wait_for_children(). 2235 */ 2236 } 2237 2238 static void 2239 register_signals(void) 2240 { 2241 struct sigaction sa; 2242 int error; 2243 2244 bzero(&sa, sizeof(sa)); 2245 sa.sa_handler = sighup_handler; 2246 sigfillset(&sa.sa_mask); 2247 error = sigaction(SIGHUP, &sa, NULL); 2248 if (error != 0) 2249 log_err(1, "sigaction"); 2250 2251 sa.sa_handler = sigterm_handler; 2252 error = sigaction(SIGTERM, &sa, NULL); 2253 if (error != 0) 2254 log_err(1, "sigaction"); 2255 2256 sa.sa_handler = sigterm_handler; 2257 error = sigaction(SIGINT, &sa, NULL); 2258 if (error != 0) 2259 log_err(1, "sigaction"); 2260 2261 sa.sa_handler = sigchld_handler; 2262 error = sigaction(SIGCHLD, &sa, NULL); 2263 if (error != 0) 2264 log_err(1, "sigaction"); 2265 } 2266 2267 int 2268 main(int argc, char **argv) 2269 { 2270 struct conf *oldconf, *newconf, *tmpconf; 2271 struct isns *newns; 2272 const char *config_path = DEFAULT_CONFIG_PATH; 2273 int debug = 0, ch, error; 2274 bool dont_daemonize = false; 2275 2276 while ((ch = getopt(argc, argv, "df:R")) != -1) { 2277 switch (ch) { 2278 case 'd': 2279 dont_daemonize = true; 2280 debug++; 2281 break; 2282 case 'f': 2283 config_path = optarg; 2284 break; 2285 case 'R': 2286 #ifndef ICL_KERNEL_PROXY 2287 log_errx(1, "ctld(8) compiled without ICL_KERNEL_PROXY " 2288 "does not support iSER protocol"); 2289 #endif 2290 proxy_mode = true; 2291 break; 2292 case '?': 2293 default: 2294 usage(); 2295 } 2296 } 2297 argc -= optind; 2298 if (argc != 0) 2299 usage(); 2300 2301 log_init(debug); 2302 kernel_init(); 2303 2304 oldconf = conf_new_from_kernel(); 2305 newconf = conf_new_from_file(config_path); 2306 if (newconf == NULL) 2307 log_errx(1, "configuration error; exiting"); 2308 if (debug > 0) { 2309 oldconf->conf_debug = debug; 2310 newconf->conf_debug = debug; 2311 } 2312 2313 error = conf_apply(oldconf, newconf); 2314 if (error != 0) 2315 log_errx(1, "failed to apply configuration; exiting"); 2316 2317 conf_delete(oldconf); 2318 oldconf = NULL; 2319 2320 register_signals(); 2321 2322 if (dont_daemonize == false) { 2323 log_debugx("daemonizing"); 2324 if (daemon(0, 0) == -1) { 2325 log_warn("cannot daemonize"); 2326 pidfile_remove(newconf->conf_pidfh); 2327 exit(1); 2328 } 2329 } 2330 2331 /* Schedule iSNS update */ 2332 if (!TAILQ_EMPTY(&newconf->conf_isns)) 2333 set_timeout((newconf->conf_isns_period + 2) / 3, false); 2334 2335 for (;;) { 2336 main_loop(newconf, dont_daemonize); 2337 if (sighup_received) { 2338 sighup_received = false; 2339 log_debugx("received SIGHUP, reloading configuration"); 2340 tmpconf = conf_new_from_file(config_path); 2341 if (tmpconf == NULL) { 2342 log_warnx("configuration error, " 2343 "continuing with old configuration"); 2344 } else { 2345 if (debug > 0) 2346 tmpconf->conf_debug = debug; 2347 oldconf = newconf; 2348 newconf = tmpconf; 2349 error = conf_apply(oldconf, newconf); 2350 if (error != 0) 2351 log_warnx("failed to reload " 2352 "configuration"); 2353 conf_delete(oldconf); 2354 oldconf = NULL; 2355 } 2356 } else if (sigterm_received) { 2357 log_debugx("exiting on signal; " 2358 "reloading empty configuration"); 2359 2360 log_debugx("disabling CTL iSCSI port " 2361 "and terminating all connections"); 2362 2363 oldconf = newconf; 2364 newconf = conf_new(); 2365 if (debug > 0) 2366 newconf->conf_debug = debug; 2367 error = conf_apply(oldconf, newconf); 2368 if (error != 0) 2369 log_warnx("failed to apply configuration"); 2370 conf_delete(oldconf); 2371 oldconf = NULL; 2372 2373 log_warnx("exiting on signal"); 2374 exit(0); 2375 } else { 2376 nchildren -= wait_for_children(false); 2377 assert(nchildren >= 0); 2378 if (timed_out()) { 2379 set_timeout(0, false); 2380 TAILQ_FOREACH(newns, &newconf->conf_isns, i_next) 2381 isns_check(newns); 2382 /* Schedule iSNS update */ 2383 if (!TAILQ_EMPTY(&newconf->conf_isns)) { 2384 set_timeout((newconf->conf_isns_period 2385 + 2) / 3, 2386 false); 2387 } 2388 } 2389 } 2390 } 2391 /* NOTREACHED */ 2392 } 2393