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