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