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