1 /* strongSwan IPsec config file parser
2 * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 #include <sys/types.h>
26 #include "../pluto/constants.h"
27 #include "../pluto/defs.h"
34 /* strings containing a colon are interpreted as an IPv6 address */
35 #define ip_version(string) (strchr(string, '.') ? AF_INET : AF_INET6)
37 static const char ike_defaults
[] = "aes128-sha1-modp2048,3des-sha1-modp1536";
38 static const char esp_defaults
[] = "aes128-sha1,3des-sha1";
40 static const char firewall_defaults
[] = "ipsec _updown iptables";
42 static bool daemon_exists(char *daemon
, char *path
)
45 if (stat(path
, &st
) != 0)
47 DBG1(DBG_APP
, "Disabling %sstart option, '%s' not found", daemon
, path
);
53 static void default_values(starter_config_t
*cfg
)
58 memset(cfg
, 0, sizeof(struct starter_config
));
60 /* is there enough space for all seen flags? */
61 assert(KW_SETUP_LAST
- KW_SETUP_FIRST
<
62 sizeof(cfg
->setup
.seen
) * BITS_PER_BYTE
);
63 assert(KW_CONN_LAST
- KW_CONN_FIRST
<
64 sizeof(cfg
->conn_default
.seen
) * BITS_PER_BYTE
);
65 assert(KW_END_LAST
- KW_END_FIRST
<
66 sizeof(cfg
->conn_default
.right
.seen
) * BITS_PER_BYTE
);
67 assert(KW_CA_LAST
- KW_CA_FIRST
<
68 sizeof(cfg
->ca_default
.seen
) * BITS_PER_BYTE
);
70 cfg
->setup
.seen
= LEMPTY
;
71 cfg
->setup
.fragicmp
= TRUE
;
72 cfg
->setup
.hidetos
= TRUE
;
73 cfg
->setup
.uniqueids
= TRUE
;
74 cfg
->setup
.interfaces
= new_list("%defaultroute");
77 cfg
->setup
.charonstart
= TRUE
;
80 cfg
->setup
.plutostart
= TRUE
;
83 cfg
->conn_default
.seen
= LEMPTY
;
84 cfg
->conn_default
.startup
= STARTUP_NO
;
85 cfg
->conn_default
.state
= STATE_IGNORE
;
86 cfg
->conn_default
.policy
= POLICY_ENCRYPT
| POLICY_TUNNEL
| POLICY_PUBKEY
|
87 POLICY_PFS
| POLICY_MOBIKE
;
89 cfg
->conn_default
.ike
= strdupnull(ike_defaults
);
90 cfg
->conn_default
.esp
= strdupnull(esp_defaults
);
91 cfg
->conn_default
.sa_ike_life_seconds
= OAKLEY_ISAKMP_SA_LIFETIME_DEFAULT
;
92 cfg
->conn_default
.sa_ipsec_life_seconds
= PLUTO_SA_LIFE_DURATION_DEFAULT
;
93 cfg
->conn_default
.sa_rekey_margin
= SA_REPLACEMENT_MARGIN_DEFAULT
;
94 cfg
->conn_default
.sa_rekey_fuzz
= SA_REPLACEMENT_FUZZ_DEFAULT
;
95 cfg
->conn_default
.sa_keying_tries
= SA_REPLACEMENT_RETRIES_DEFAULT
;
96 cfg
->conn_default
.addr_family
= AF_INET
;
97 cfg
->conn_default
.tunnel_addr_family
= AF_INET
;
98 cfg
->conn_default
.install_policy
= TRUE
;
99 cfg
->conn_default
.dpd_delay
= 30; /* seconds */
100 cfg
->conn_default
.dpd_timeout
= 150; /* seconds */
102 cfg
->conn_default
.left
.seen
= LEMPTY
;
103 cfg
->conn_default
.right
.seen
= LEMPTY
;
105 cfg
->conn_default
.left
.sendcert
= CERT_SEND_IF_ASKED
;
106 cfg
->conn_default
.right
.sendcert
= CERT_SEND_IF_ASKED
;
108 anyaddr(AF_INET
, &cfg
->conn_default
.left
.addr
);
109 anyaddr(AF_INET
, &cfg
->conn_default
.right
.addr
);
110 cfg
->conn_default
.left
.ikeport
= 500;
111 cfg
->conn_default
.right
.ikeport
= 500;
113 cfg
->ca_default
.seen
= LEMPTY
;
116 #define KW_POLICY_FLAG(sy, sn, fl) \
117 if (streq(kw->value, sy)) { conn->policy |= fl; } \
118 else if (streq(kw->value, sn)) { conn->policy &= ~fl; } \
119 else { DBG1(DBG_APP, "# bad policy value: %s=%s", kw->entry->name, kw->value); cfg->err++; }
121 static void load_setup(starter_config_t
*cfg
, config_parsed_t
*cfgp
)
125 DBG2(DBG_APP
, "Loading config setup");
127 for (kw
= cfgp
->config_setup
; kw
; kw
= kw
->next
)
129 bool assigned
= FALSE
;
131 kw_token_t token
= kw
->entry
->token
;
133 if ((int)token
< KW_SETUP_FIRST
|| token
> KW_SETUP_LAST
)
135 DBG1(DBG_APP
, "# unsupported keyword '%s' in config setup",
141 if (!assign_arg(token
, KW_SETUP_FIRST
, kw
, (char *)cfg
, &assigned
))
143 DBG1(DBG_APP
, " bad argument value in config setup");
149 /* verify the executables are actually available (some distros split
150 * packages but enabled both) */
152 cfg
->setup
.charonstart
= cfg
->setup
.charonstart
&&
153 daemon_exists("charon", CHARON_CMD
);
155 cfg
->setup
.charonstart
= FALSE
;
158 cfg
->setup
.plutostart
= cfg
->setup
.plutostart
&&
159 daemon_exists("pluto", PLUTO_CMD
);
161 cfg
->setup
.plutostart
= FALSE
;
165 static void kw_end(starter_conn_t
*conn
, starter_end_t
*end
, kw_token_t token
,
166 kw_list_t
*kw
, char *conn_name
, starter_config_t
*cfg
)
169 bool assigned
= FALSE
;
170 bool has_port_wildcard
; /* set if port is %any */
172 char *name
= kw
->entry
->name
;
173 char *value
= kw
->value
;
175 if (!assign_arg(token
, KW_END_FIRST
, kw
, (char *)end
, &assigned
))
178 /* post processing of some keywords that were assigned automatically */
184 if (streq(value
, "%any") || streq(value
, "%any4"))
186 anyaddr(conn
->addr_family
, &end
->addr
);
188 else if (streq(value
, "%any6"))
190 conn
->addr_family
= AF_INET6
;
191 anyaddr(conn
->addr_family
, &end
->addr
);
193 else if (streq(value
, "%group"))
197 conn
->policy
|= POLICY_GROUP
| POLICY_TUNNEL
;
198 anyaddr(conn
->addr_family
, &end
->addr
);
199 anyaddr(conn
->tunnel_addr_family
, &any
);
200 end
->has_client
= TRUE
;
204 /* check for allow_any prefix */
207 end
->allow_any
= TRUE
;
210 conn
->addr_family
= ip_version(value
);
211 ugh
= ttoaddr(value
, 0, conn
->addr_family
, &end
->addr
);
214 DBG1(DBG_APP
, "# bad addr: %s=%s [%s]", name
, value
, ugh
);
215 if (streq(ugh
, "does not look numeric and name lookup failed"))
217 end
->dns_failed
= TRUE
;
218 anyaddr(conn
->addr_family
, &end
->addr
);
225 end
->host
= strdupnull(value
);
229 if ((strlen(value
) >= 6 && strncmp(value
,"vhost:",6) == 0)
230 || (strlen(value
) >= 5 && strncmp(value
,"vnet:",5) == 0))
232 /* used by pluto only */
233 end
->has_virt
= TRUE
;
241 end
->has_client
= TRUE
;
242 conn
->tunnel_addr_family
= ip_version(value
);
244 pos
= strchr(value
, ',');
249 ugh
= ttosubnet(value
, len
, ip_version(value
), &net
);
252 DBG1(DBG_APP
, "# bad subnet: %s=%s [%s]", name
, value
, ugh
);
260 DBG1(DBG_APP
, "# natip and sourceip cannot be defined at the same time");
265 if (streq(value
, "%modeconfig") || streq(value
, "%modecfg") ||
266 streq(value
, "%config") || streq(value
, "%cfg"))
268 /* request ip via config payload */
270 end
->sourceip
= NULL
;
271 end
->sourceip_mask
= 1;
274 { /* %poolname, strip %, serve ip requests */
276 end
->sourceip
= strdupnull(value
+1);
277 end
->sourceip_mask
= 0;
287 conn
->tunnel_addr_family
= ip_version(value
);
288 pos
= strchr(value
, '/');
291 { /* CIDR notation, address pool */
292 ugh
= ttosubnet(value
, 0, conn
->tunnel_addr_family
, &net
);
295 DBG1(DBG_APP
, "# bad subnet: %s=%s [%s]", name
, value
, ugh
);
300 end
->sourceip
= strdupnull(value
);
301 end
->sourceip_mask
= atoi(pos
+ 1);
305 ugh
= ttoaddr(value
, 0, conn
->tunnel_addr_family
, &addr
);
308 DBG1(DBG_APP
, "# bad addr: %s=%s [%s]", name
, value
, ugh
);
311 end
->sourceip_mask
= (conn
->tunnel_addr_family
== AF_INET
) ?
315 conn
->policy
|= POLICY_TUNNEL
;
318 if (end
->sendcert
== CERT_YES_SEND
)
320 end
->sendcert
= CERT_ALWAYS_SEND
;
322 else if (end
->sendcert
== CERT_NO_SEND
)
324 end
->sendcert
= CERT_NEVER_SEND
;
334 /* individual processing of keywords that were not assigned automatically */
337 case KW_SUBNETWITHIN
:
341 end
->has_client
= TRUE
;
342 end
->has_client_wildcard
= TRUE
;
343 conn
->tunnel_addr_family
= ip_version(value
);
345 ugh
= ttosubnet(value
, 0, ip_version(value
), &net
);
348 DBG1(DBG_APP
, "# bad subnet: %s=%s [%s]", name
, value
, ugh
);
351 end
->subnet
= strdupnull(value
);
355 ugh
= ttoprotoport(value
, 0, &end
->protocol
, &end
->port
, &has_port_wildcard
);
356 end
->has_port_wildcard
= has_port_wildcard
;
363 DBG1(DBG_APP
, "# natip and sourceip cannot be defined at the same time");
366 conn
->tunnel_addr_family
= ip_version(value
);
367 ugh
= ttoaddr(value
, 0, conn
->tunnel_addr_family
, &addr
);
370 DBG1(DBG_APP
, "# bad addr: %s=%s [%s]", name
, value
, ugh
);
373 end
->sourceip
= strdupnull(value
);
374 end
->has_natip
= TRUE
;
375 conn
->policy
|= POLICY_TUNNEL
;
384 DBG1(DBG_APP
, " bad argument value in conn '%s'", conn_name
);
389 * handles left|right=<FQDN> DNS resolution failure
391 static void handle_dns_failure(const char *label
, starter_end_t
*end
,
392 starter_config_t
*cfg
, starter_conn_t
*conn
)
398 DBG1(DBG_APP
, "# fallback to %s=%%any due to '%%' prefix or %sallowany=yes",
403 /* declare an error */
410 * handles left|rightfirewall and left|rightupdown parameters
412 static void handle_firewall(const char *label
, starter_end_t
*end
,
413 starter_config_t
*cfg
)
415 if (end
->firewall
&& (end
->seen
& LELEM(KW_FIREWALL
- KW_END_FIRST
)))
417 if (end
->updown
!= NULL
)
419 DBG1(DBG_APP
, "# cannot have both %sfirewall and %supdown", label
,
425 end
->updown
= strdupnull(firewall_defaults
);
426 end
->firewall
= FALSE
;
431 static bool handle_mark(char *value
, mark_t
*mark
)
435 pos
= strchr(value
, '/');
439 mark
->mask
= strtoul(pos
+1, &endptr
, 0);
442 DBG1(DBG_APP
, "# invalid mark mask: %s", pos
+1);
448 mark
->mask
= 0xffffffff;
456 mark
->value
= strtoul(value
, &endptr
, 0);
459 DBG1(DBG_APP
, "# invalid mark value: %s", value
);
467 * parse a conn section
469 static void load_conn(starter_conn_t
*conn
, kw_list_t
*kw
, starter_config_t
*cfg
)
471 char *conn_name
= (conn
->name
== NULL
)?
"%default":conn
->name
;
473 for ( ; kw
; kw
= kw
->next
)
475 bool assigned
= FALSE
;
477 kw_token_t token
= kw
->entry
->token
;
479 if (token
>= KW_LEFT_FIRST
&& token
<= KW_LEFT_LAST
)
481 kw_end(conn
, &conn
->left
, token
- KW_LEFT_FIRST
+ KW_END_FIRST
482 , kw
, conn_name
, cfg
);
485 else if (token
>= KW_RIGHT_FIRST
&& token
<= KW_RIGHT_LAST
)
487 kw_end(conn
, &conn
->right
, token
- KW_RIGHT_FIRST
+ KW_END_FIRST
488 , kw
, conn_name
, cfg
);
492 if (token
== KW_AUTO
)
494 token
= KW_CONN_SETUP
;
496 else if (token
== KW_ALSO
)
500 also_t
*also
= malloc_thing(also_t
);
502 also
->name
= strdupnull(kw
->value
);
503 also
->next
= conn
->also
;
506 DBG2(DBG_APP
, " also=%s", kw
->value
);
511 if (token
< KW_CONN_FIRST
|| token
> KW_CONN_LAST
)
513 DBG1(DBG_APP
, "# unsupported keyword '%s' in conn '%s'",
514 kw
->entry
->name
, conn_name
);
519 if (!assign_arg(token
, KW_CONN_FIRST
, kw
, (char *)conn
, &assigned
))
521 DBG1(DBG_APP
, " bad argument value in conn '%s'", conn_name
);
532 conn
->policy
&= ~(POLICY_TUNNEL
| POLICY_SHUNT_MASK
);
533 if (streq(kw
->value
, "tunnel"))
535 conn
->policy
|= POLICY_TUNNEL
;
537 else if (streq(kw
->value
, "beet"))
539 conn
->policy
|= POLICY_BEET
;
541 else if (streq(kw
->value
, "transport_proxy"))
543 conn
->policy
|= POLICY_PROXY
;
545 else if (streq(kw
->value
, "passthrough") || streq(kw
->value
, "pass"))
547 conn
->policy
|= POLICY_SHUNT_PASS
;
549 else if (streq(kw
->value
, "drop"))
551 conn
->policy
|= POLICY_SHUNT_DROP
;
553 else if (streq(kw
->value
, "reject"))
555 conn
->policy
|= POLICY_SHUNT_REJECT
;
557 else if (strcmp(kw
->value
, "transport") != 0)
559 DBG1(DBG_APP
, "# bad policy value: %s=%s", kw
->entry
->name
,
565 KW_POLICY_FLAG("yes", "no", POLICY_PFS
)
568 KW_POLICY_FLAG("yes", "no", POLICY_COMPRESS
)
571 KW_POLICY_FLAG("ah", "esp", POLICY_AUTHENTICATE
)
574 if (!handle_mark(kw
->value
, &conn
->mark_in
))
579 conn
->mark_out
= conn
->mark_in
;
582 if (!handle_mark(kw
->value
, &conn
->mark_in
))
588 if (!handle_mark(kw
->value
, &conn
->mark_out
))
594 if (streq(kw
->value
, "%mtu"))
602 conn
->tfc
= strtoul(kw
->value
, &endptr
, 10);
605 DBG1(DBG_APP
, "# bad integer value: %s=%s", kw
->entry
->name
,
612 if (streq(kw
->value
, "%forever"))
614 conn
->sa_keying_tries
= 0;
620 conn
->sa_keying_tries
= strtoul(kw
->value
, &endptr
, 10);
623 DBG1(DBG_APP
, "# bad integer value: %s=%s", kw
->entry
->name
,
630 KW_POLICY_FLAG("no", "yes", POLICY_DONT_REKEY
)
633 KW_POLICY_FLAG("no", "yes", POLICY_DONT_REAUTH
)
636 KW_POLICY_FLAG("yes", "no", POLICY_MOBIKE
)
639 KW_POLICY_FLAG("yes", "no", POLICY_FORCE_ENCAP
)
642 KW_POLICY_FLAG("push", "pull", POLICY_MODECFG_PUSH
)
645 KW_POLICY_FLAG("server", "client", POLICY_XAUTH_SERVER
)
652 handle_dns_failure("left", &conn
->left
, cfg
, conn
);
653 handle_dns_failure("right", &conn
->right
, cfg
, conn
);
654 handle_firewall("left", &conn
->left
, cfg
);
655 handle_firewall("right", &conn
->right
, cfg
);
659 * initialize a conn object with the default conn
661 static void conn_default(char *name
, starter_conn_t
*conn
, starter_conn_t
*def
)
663 memcpy(conn
, def
, sizeof(starter_conn_t
));
664 conn
->name
= strdupnull(name
);
666 clone_args(KW_CONN_FIRST
, KW_CONN_LAST
, (char *)conn
, (char *)def
);
667 clone_args(KW_END_FIRST
, KW_END_LAST
, (char *)&conn
->left
, (char *)&def
->left
);
668 clone_args(KW_END_FIRST
, KW_END_LAST
, (char *)&conn
->right
, (char *)&def
->right
);
674 static void load_ca(starter_ca_t
*ca
, kw_list_t
*kw
, starter_config_t
*cfg
)
676 char *ca_name
= (ca
->name
== NULL
)?
"%default":ca
->name
;
678 for ( ; kw
; kw
= kw
->next
)
680 bool assigned
= FALSE
;
682 kw_token_t token
= kw
->entry
->token
;
684 if (token
== KW_AUTO
)
688 else if (token
== KW_ALSO
)
692 also_t
*also
= malloc_thing(also_t
);
694 also
->name
= strdupnull(kw
->value
);
695 also
->next
= ca
->also
;
698 DBG2(DBG_APP
, " also=%s", kw
->value
);
703 if (token
< KW_CA_FIRST
|| token
> KW_CA_LAST
)
705 DBG1(DBG_APP
, "# unsupported keyword '%s' in ca '%s'",
706 kw
->entry
->name
, ca_name
);
711 if (!assign_arg(token
, KW_CA_FIRST
, kw
, (char *)ca
, &assigned
))
713 DBG1(DBG_APP
, " bad argument value in ca '%s'", ca_name
);
718 /* treat 'route' and 'start' as 'add' */
719 if (ca
->startup
!= STARTUP_NO
)
720 ca
->startup
= STARTUP_ADD
;
724 * initialize a ca object with the default ca
726 static void ca_default(char *name
, starter_ca_t
*ca
, starter_ca_t
*def
)
728 memcpy(ca
, def
, sizeof(starter_ca_t
));
729 ca
->name
= strdupnull(name
);
731 clone_args(KW_CA_FIRST
, KW_CA_LAST
, (char *)ca
, (char *)def
);
734 static kw_list_t
* find_also_conn(const char* name
, starter_conn_t
*conn
,
735 starter_config_t
*cfg
);
737 static void load_also_conns(starter_conn_t
*conn
, also_t
*also
,
738 starter_config_t
*cfg
)
742 kw_list_t
*kw
= find_also_conn(also
->name
, conn
, cfg
);
746 DBG1(DBG_APP
, " conn '%s' cannot include '%s'", conn
->name
,
751 DBG2(DBG_APP
, "conn '%s' includes '%s'", conn
->name
, also
->name
);
752 /* only load if no error occurred in the first round */
754 load_conn(conn
, kw
, cfg
);
761 * find a conn included by also
763 static kw_list_t
* find_also_conn(const char* name
, starter_conn_t
*conn
,
764 starter_config_t
*cfg
)
766 starter_conn_t
*c
= cfg
->conn_first
;
770 if (streq(name
, c
->name
))
772 if (conn
->visit
== c
->visit
)
774 DBG1(DBG_APP
, "# detected also loop");
778 c
->visit
= conn
->visit
;
779 load_also_conns(conn
, c
->also
, cfg
);
785 DBG1(DBG_APP
, "# also '%s' not found", name
);
790 static kw_list_t
* find_also_ca(const char* name
, starter_ca_t
*ca
,
791 starter_config_t
*cfg
);
793 static void load_also_cas(starter_ca_t
*ca
, also_t
*also
, starter_config_t
*cfg
)
797 kw_list_t
*kw
= find_also_ca(also
->name
, ca
, cfg
);
801 DBG1(DBG_APP
, " ca '%s' cannot include '%s'", ca
->name
,
806 DBG2(DBG_APP
, "ca '%s' includes '%s'", ca
->name
, also
->name
);
807 /* only load if no error occurred in the first round */
809 load_ca(ca
, kw
, cfg
);
816 * find a ca included by also
818 static kw_list_t
* find_also_ca(const char* name
, starter_ca_t
*ca
,
819 starter_config_t
*cfg
)
821 starter_ca_t
*c
= cfg
->ca_first
;
825 if (streq(name
, c
->name
))
827 if (ca
->visit
== c
->visit
)
829 DBG1(DBG_APP
, "# detected also loop");
833 c
->visit
= ca
->visit
;
834 load_also_cas(ca
, c
->also
, cfg
);
840 DBG1(DBG_APP
, "# also '%s' not found", name
);
846 * free the memory used by also_t objects
848 static void free_also(also_t
*head
)
861 * free the memory used by a starter_conn_t object
863 static void confread_free_conn(starter_conn_t
*conn
)
865 free_args(KW_END_FIRST
, KW_END_LAST
, (char *)&conn
->left
);
866 free_args(KW_END_FIRST
, KW_END_LAST
, (char *)&conn
->right
);
867 free_args(KW_CONN_NAME
, KW_CONN_LAST
, (char *)conn
);
868 free_also(conn
->also
);
872 * free the memory used by a starter_ca_t object
875 confread_free_ca(starter_ca_t
*ca
)
877 free_args(KW_CA_NAME
, KW_CA_LAST
, (char *)ca
);
882 * free the memory used by a starter_config_t object
884 void confread_free(starter_config_t
*cfg
)
886 starter_conn_t
*conn
= cfg
->conn_first
;
887 starter_ca_t
*ca
= cfg
->ca_first
;
889 free_args(KW_SETUP_FIRST
, KW_SETUP_LAST
, (char *)cfg
);
891 confread_free_conn(&cfg
->conn_default
);
895 starter_conn_t
*conn_aux
= conn
;
898 confread_free_conn(conn_aux
);
902 confread_free_ca(&cfg
->ca_default
);
906 starter_ca_t
*ca_aux
= ca
;
909 confread_free_ca(ca_aux
);
917 * load and parse an IPsec configuration file
919 starter_config_t
* confread_load(const char *file
)
921 starter_config_t
*cfg
= NULL
;
922 config_parsed_t
*cfgp
;
923 section_list_t
*sconn
, *sca
;
924 starter_conn_t
*conn
;
930 /* load IPSec configuration file */
931 cfgp
= parser_load_conf(file
);
936 cfg
= malloc_thing(starter_config_t
);
938 /* set default values */
941 /* load config setup section */
942 load_setup(cfg
, cfgp
);
944 /* in the first round parse also statements */
945 cfg
->parse_also
= TRUE
;
947 /* find %default ca section */
948 for (sca
= cfgp
->ca_first
; sca
; sca
= sca
->next
)
950 if (streq(sca
->name
, "%default"))
952 DBG2(DBG_APP
, "Loading ca %%default");
953 load_ca(&cfg
->ca_default
, sca
->kw
, cfg
);
957 /* parameters defined in ca %default sections can be overloads */
958 cfg
->ca_default
.seen
= LEMPTY
;
960 /* load other ca sections */
961 for (sca
= cfgp
->ca_first
; sca
; sca
= sca
->next
)
965 /* skip %default ca section */
966 if (streq(sca
->name
, "%default"))
969 DBG2(DBG_APP
, "Loading ca '%s'", sca
->name
);
970 ca
= malloc_thing(starter_ca_t
);
972 ca_default(sca
->name
, ca
, &cfg
->ca_default
);
976 previous_err
= cfg
->err
;
977 load_ca(ca
, ca
->kw
, cfg
);
978 if (cfg
->err
> previous_err
)
980 /* errors occurred - free the ca */
981 confread_free_ca(ca
);
982 cfg
->non_fatal_err
+= cfg
->err
- previous_err
;
983 cfg
->err
= previous_err
;
987 /* success - insert the ca into the chained list */
989 cfg
->ca_last
->next
= ca
;
996 for (ca
= cfg
->ca_first
; ca
; ca
= ca
->next
)
998 also_t
*also
= ca
->also
;
1000 while (also
!= NULL
)
1002 kw_list_t
*kw
= find_also_ca(also
->name
, cfg
->ca_first
, cfg
);
1004 load_ca(ca
, kw
, cfg
);
1008 if (ca
->startup
!= STARTUP_NO
)
1009 ca
->state
= STATE_TO_ADD
;
1012 /* find %default conn sections */
1013 for (sconn
= cfgp
->conn_first
; sconn
; sconn
= sconn
->next
)
1015 if (streq(sconn
->name
, "%default"))
1017 DBG2(DBG_APP
, "Loading conn %%default");
1018 load_conn(&cfg
->conn_default
, sconn
->kw
, cfg
);
1022 /* parameter defined in conn %default sections can be overloaded */
1023 cfg
->conn_default
.seen
= LEMPTY
;
1024 cfg
->conn_default
.right
.seen
= LEMPTY
;
1025 cfg
->conn_default
.left
.seen
= LEMPTY
;
1027 /* load other conn sections */
1028 for (sconn
= cfgp
->conn_first
; sconn
; sconn
= sconn
->next
)
1032 /* skip %default conn section */
1033 if (streq(sconn
->name
, "%default"))
1036 DBG2(DBG_APP
, "Loading conn '%s'", sconn
->name
);
1037 conn
= malloc_thing(starter_conn_t
);
1039 conn_default(sconn
->name
, conn
, &cfg
->conn_default
);
1040 conn
->kw
= sconn
->kw
;
1043 previous_err
= cfg
->err
;
1044 load_conn(conn
, conn
->kw
, cfg
);
1045 if (cfg
->err
> previous_err
)
1047 /* error occurred - free the conn */
1048 confread_free_conn(conn
);
1049 cfg
->non_fatal_err
+= cfg
->err
- previous_err
;
1050 cfg
->err
= previous_err
;
1054 /* success - insert the conn into the chained list */
1056 cfg
->conn_last
->next
= conn
;
1057 cfg
->conn_last
= conn
;
1058 if (!cfg
->conn_first
)
1059 cfg
->conn_first
= conn
;
1063 /* in the second round do not parse also statements */
1064 cfg
->parse_also
= FALSE
;
1066 for (ca
= cfg
->ca_first
; ca
; ca
= ca
->next
)
1068 ca
->visit
= ++visit
;
1069 load_also_cas(ca
, ca
->also
, cfg
);
1071 if (ca
->startup
!= STARTUP_NO
)
1072 ca
->state
= STATE_TO_ADD
;
1075 for (conn
= cfg
->conn_first
; conn
; conn
= conn
->next
)
1077 conn
->visit
= ++visit
;
1078 load_also_conns(conn
, conn
->also
, cfg
);
1080 if (conn
->startup
!= STARTUP_NO
)
1081 conn
->state
= STATE_TO_ADD
;
1084 parser_free_conf(cfgp
);
1086 total_err
= cfg
->err
+ cfg
->non_fatal_err
;
1089 DBG1(DBG_APP
, "### %d parsing error%s (%d fatal) ###",
1090 total_err
, (total_err
> 1)?
"s":"", cfg
->err
);