5 Authors: Giovanni Giacobbi <giovanni@giacobbi.net>
6 Pekka Riikonen <priikone@silcnet.org>
8 Copyright (C) 1997 - 2014 Pekka Riikonen
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; version 2 of the License.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
22 #include "serverincludes.h"
23 #include "server_internal.h"
27 #define SERVER_CONFIG_DEBUG(fmt) SILC_LOG_DEBUG(fmt)
29 #define SERVER_CONFIG_DEBUG(fmt)
32 /* auto-declare needed variables for the common list parsing */
33 #define SILC_SERVER_CONFIG_SECTION_INIT(__type__) \
34 SilcServerConfig config = (SilcServerConfig) context; \
35 __type__ *findtmp, *tmp = (__type__ *) config->tmp; \
38 /* allocate the tmp field for fetching data */
39 #define SILC_SERVER_CONFIG_ALLOCTMP(__type__) \
41 config->tmp = silc_calloc(1, sizeof(*findtmp)); \
42 tmp = (__type__ *) config->tmp; \
45 /* append the tmp field to the specified list */
46 #define SILC_SERVER_CONFIG_LIST_APPENDTMP(__list__) \
50 for (findtmp = __list__; findtmp->next; findtmp = findtmp->next); \
51 findtmp->next = tmp; \
54 /* loops all elements in a list and provides a di struct pointer of the
55 * specified type containing the current element */
56 #define SILC_SERVER_CONFIG_LIST_DESTROY(__type__, __list__) \
57 for (tmp = (void *) __list__; tmp;) { \
58 __type__ *di = (__type__ *) tmp; \
59 tmp = (void *) di->next;
61 /* Set EDOUBLE error value and bail out if necessary */
62 #define CONFIG_IS_DOUBLE(__x__) \
64 got_errno = SILC_CONFIG_EDOUBLE; \
68 /* Free the authentication fields in the specified struct
69 * Expands to two instructions */
70 #define CONFIG_FREE_AUTH(__section__) \
71 silc_free(__section__->passphrase);
73 /* Set default values to those parameters that have not been defined */
75 my_set_param_defaults(SilcServerConfigConnParams *params,
76 SilcServerConfigConnParams *defaults)
78 #define SET_PARAM_DEFAULT(p, d) params->p = \
79 (params->p ? params->p : (defaults && defaults->p ? defaults->p : d))
81 SET_PARAM_DEFAULT(connections_max, SILC_SERVER_MAX_CONNECTIONS);
82 SET_PARAM_DEFAULT(connections_max_per_host,
83 SILC_SERVER_MAX_CONNECTIONS_SINGLE);
84 SET_PARAM_DEFAULT(keepalive_secs, SILC_SERVER_KEEPALIVE);
85 SET_PARAM_DEFAULT(reconnect_count, SILC_SERVER_RETRY_COUNT);
86 SET_PARAM_DEFAULT(reconnect_interval, SILC_SERVER_RETRY_INTERVAL_MIN);
87 SET_PARAM_DEFAULT(reconnect_interval_max, SILC_SERVER_RETRY_INTERVAL_MAX);
88 SET_PARAM_DEFAULT(key_exchange_rekey, SILC_SERVER_REKEY);
89 SET_PARAM_DEFAULT(qos_rate_limit, SILC_SERVER_QOS_RATE_LIMIT);
90 SET_PARAM_DEFAULT(qos_bytes_limit, SILC_SERVER_QOS_BYTES_LIMIT);
91 SET_PARAM_DEFAULT(qos_limit_sec, SILC_SERVER_QOS_LIMIT_SEC);
92 SET_PARAM_DEFAULT(qos_limit_usec, SILC_SERVER_QOS_LIMIT_USEC);
93 SET_PARAM_DEFAULT(chlimit, SILC_SERVER_CH_JOIN_LIMIT);
95 #undef SET_PARAM_DEFAULT
98 /* Find connection parameters by the parameter block name. */
99 static SilcServerConfigConnParams *
100 my_find_param(SilcServerConfig config, const char *name)
102 SilcServerConfigConnParams *param;
104 for (param = config->conn_params; param; param = param->next) {
105 if (!strcasecmp(param->name, name))
109 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
110 "Cannot find Params \"%s\".", name));
115 /* SKR find callbcak */
117 static void my_find_callback(SilcSKR skr, SilcSKRFind find,
118 SilcSKRStatus status, SilcDList keys,
121 SilcSKRStatus *s = context;
125 silc_dlist_uninit(keys);
127 silc_skr_find_free(find);
130 /* parse an authdata according to its auth method */
131 static SilcBool my_parse_authdata(SilcAuthMethod auth_meth, const char *p,
132 void **auth_data, SilcUInt32 *auth_data_len,
133 SilcSKRKeyUsage usage, void *key_context)
135 if (auth_meth == SILC_AUTH_PASSWORD) {
136 /* p is a plain text password */
137 if (auth_data && auth_data_len) {
138 if (!silc_utf8_valid(p, strlen(p))) {
139 *auth_data_len = silc_utf8_encoded_len(p, strlen(p),
141 *auth_data = silc_calloc(*auth_data_len, sizeof(unsigned char));
142 silc_utf8_encode(p, strlen(p), SILC_STRING_LOCALE, *auth_data,
145 *auth_data = (void *) strdup(p);
146 *auth_data_len = (SilcUInt32) strlen(p);
149 } else if (auth_meth == SILC_AUTH_PUBLIC_KEY) {
150 /* p is a public key file name */
151 SilcPublicKey public_key;
152 SilcSKR skr = *auth_data;
154 SilcSKRStatus status = SILC_SKR_NOT_FOUND;
156 if (!silc_pkcs_load_public_key(p, &public_key)) {
157 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
158 "Could not load public key file!"));
162 find = silc_skr_find_alloc();
163 silc_skr_find_set_public_key(find, public_key);
164 silc_skr_find_set_usage(find, usage);
166 silc_skr_find_set_context(find, SILC_32_TO_PTR(usage));
167 silc_skr_find(skr, NULL, find, my_find_callback, &status);
168 if (status == SILC_SKR_OK) {
169 /* Already added, ignore error */
170 silc_pkcs_public_key_free(public_key);
174 /* Add the public key to repository */
175 status = silc_skr_add_public_key(skr, public_key, usage,
176 key_context ? key_context :
177 (void *)usage, NULL);
178 if (status != SILC_SKR_OK) {
179 SILC_SERVER_LOG_ERROR(("Error while adding public key \"%s\"", p));
187 static int my_parse_publickeydir(const char *dirname, void **auth_data,
188 SilcSKRKeyUsage usage)
191 struct dirent *get_file;
194 if (!(dp = opendir(dirname))) {
195 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
196 "Could not open directory \"%s\"", dirname));
200 /* errors are not considered fatal */
201 while ((get_file = readdir(dp))) {
202 const char *filename = get_file->d_name;
204 int dirname_len = strlen(dirname), filename_len = strlen(filename);
205 struct stat check_file;
207 /* Ignore "." and "..", and take files only with ".pub" suffix. */
208 if (!strcmp(filename, ".") || !strcmp(filename, "..") ||
209 (filename_len < 5) || strcmp(filename + filename_len - 4, ".pub"))
212 memset(buf, 0, sizeof(buf));
213 snprintf(buf, sizeof(buf) - 1, "%s%s%s", dirname,
214 (dirname[dirname_len - 1] == '/' ? "" : "/"), filename);
216 if (stat(buf, &check_file) < 0) {
217 SILC_SERVER_LOG_ERROR(("Error stating file %s: %s", buf,
219 } else if (S_ISREG(check_file.st_mode)) {
220 if (my_parse_authdata(SILC_AUTH_PUBLIC_KEY, buf, auth_data, NULL,
226 SILC_LOG_DEBUG(("Tried to load %d public keys in \"%s\"", total, dirname));
232 SILC_CONFIG_CALLBACK(fetch_generic)
234 SilcServerConfig config = (SilcServerConfig) context;
237 if (!strcmp(name, "prefer_passphrase_auth")) {
238 config->prefer_passphrase_auth = *(SilcBool *)val;
240 else if (!strcmp(name, "require_reverse_lookup")) {
241 config->require_reverse_lookup = *(SilcBool *)val;
243 else if (!strcmp(name, "connections_max")) {
244 config->param.connections_max = (SilcUInt32) *(int *)val;
246 else if (!strcmp(name, "connections_max_per_host")) {
247 config->param.connections_max_per_host = (SilcUInt32) *(int *)val;
249 else if (!strcmp(name, "keepalive_secs")) {
250 config->param.keepalive_secs = (SilcUInt32) *(int *)val;
252 else if (!strcmp(name, "reconnect_count")) {
253 config->param.reconnect_count = (SilcUInt32) *(int *)val;
255 else if (!strcmp(name, "reconnect_interval")) {
256 config->param.reconnect_interval = (SilcUInt32) *(int *)val;
258 else if (!strcmp(name, "reconnect_interval_max")) {
259 config->param.reconnect_interval_max = (SilcUInt32) *(int *)val;
261 else if (!strcmp(name, "reconnect_keep_trying")) {
262 config->param.reconnect_keep_trying = *(SilcBool *)val;
264 else if (!strcmp(name, "key_exchange_rekey")) {
265 config->param.key_exchange_rekey = (SilcUInt32) *(int *)val;
267 else if (!strcmp(name, "key_exchange_pfs")) {
268 config->param.key_exchange_pfs = *(SilcBool *)val;
270 else if (!strcmp(name, "channel_rekey_secs")) {
271 config->channel_rekey_secs = (SilcUInt32) *(int *)val;
273 else if (!strcmp(name, "key_exchange_timeout")) {
274 config->key_exchange_timeout = (SilcUInt32) *(int *)val;
276 else if (!strcmp(name, "conn_auth_timeout")) {
277 config->conn_auth_timeout = (SilcUInt32) *(int *)val;
279 else if (!strcmp(name, "version_protocol")) {
280 CONFIG_IS_DOUBLE(config->param.version_protocol);
281 config->param.version_protocol =
282 (*(char *)val ? strdup((char *) val) : NULL);
284 else if (!strcmp(name, "version_software")) {
285 CONFIG_IS_DOUBLE(config->param.version_software);
286 config->param.version_software =
287 (*(char *)val ? strdup((char *) val) : NULL);
289 else if (!strcmp(name, "version_software_vendor")) {
290 CONFIG_IS_DOUBLE(config->param.version_software_vendor);;
291 config->param.version_software_vendor =
292 (*(char *)val ? strdup((char *) val) : NULL);
294 else if (!strcmp(name, "detach_disabled")) {
295 config->detach_disabled = *(SilcBool *)val;
297 else if (!strcmp(name, "detach_timeout")) {
298 config->detach_timeout = (SilcUInt32) *(int *)val;
300 else if (!strcmp(name, "qos")) {
301 config->param.qos = *(SilcBool *)val;
303 else if (!strcmp(name, "qos_rate_limit")) {
304 config->param.qos_rate_limit = *(SilcUInt32 *)val;
306 else if (!strcmp(name, "qos_bytes_limit")) {
307 config->param.qos_bytes_limit = *(SilcUInt32 *)val;
309 else if (!strcmp(name, "qos_limit_sec")) {
310 config->param.qos_limit_sec = *(SilcUInt32 *)val;
312 else if (!strcmp(name, "qos_limit_usec")) {
313 config->param.qos_limit_usec = *(SilcUInt32 *)val;
315 else if (!strcmp(name, "channel_join_limit")) {
316 config->param.chlimit = *(SilcUInt32 *)val;
318 else if (!strcmp(name, "debug_string")) {
319 CONFIG_IS_DOUBLE(config->debug_string);
320 config->debug_string = (*(char *)val ? strdup((char *) val) : NULL);
322 else if (!strcmp(name, "http_server")) {
323 config->httpd = *(SilcBool *)val;
325 else if (!strcmp(name, "http_server_ip")) {
326 CONFIG_IS_DOUBLE(config->httpd_ip);
327 config->httpd_ip = (*(char *)val ? strdup((char *) val) : NULL);
329 else if (!strcmp(name, "http_server_port")) {
330 int port = *(int *)val;
331 if ((port <= 0) || (port > 65535)) {
332 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
333 "Invalid port number!"));
334 got_errno = SILC_CONFIG_EPRINTLINE;
337 config->httpd_port = (SilcUInt16)port;
339 else if (!strcmp(name, "dynamic_server")) {
340 config->dynamic_server = *(SilcBool *)val;
342 else if (!strcmp(name, "local_channels")) {
343 config->local_channels = *(SilcBool *)val;
346 return SILC_CONFIG_EINTERNAL;
348 return SILC_CONFIG_OK;
354 SILC_CONFIG_CALLBACK(fetch_cipher)
356 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigCipher);
358 SERVER_CONFIG_DEBUG(("Received CIPHER type=%d name=\"%s\" (val=%x)",
359 type, name, context));
360 if (type == SILC_CONFIG_ARG_BLOCK) {
361 /* check the temporary struct's fields */
362 if (!tmp) /* discard empty sub-blocks */
363 return SILC_CONFIG_OK;
365 got_errno = SILC_CONFIG_EMISSFIELDS;
369 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->cipher);
371 return SILC_CONFIG_OK;
373 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigCipher);
375 /* Identify and save this value */
376 if (!strcmp(name, "name")) {
377 CONFIG_IS_DOUBLE(tmp->name);
378 tmp->name = strdup((char *) val);
380 else if (!strcmp(name, "keylength")) {
381 tmp->key_length = *(SilcUInt32 *)val;
383 else if (!strcmp(name, "blocklength")) {
384 tmp->block_length = *(SilcUInt32 *)val;
387 return SILC_CONFIG_EINTERNAL;
388 return SILC_CONFIG_OK;
391 silc_free(tmp->name);
397 SILC_CONFIG_CALLBACK(fetch_hash)
399 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigHash);
401 SERVER_CONFIG_DEBUG(("Received HASH type=%d name=%s (val=%x)",
402 type, name, context));
403 if (type == SILC_CONFIG_ARG_BLOCK) {
404 /* check the temporary struct's fields */
405 if (!tmp) /* discard empty sub-blocks */
406 return SILC_CONFIG_OK;
407 if (!tmp->name || (tmp->block_length == 0) || (tmp->digest_length == 0)) {
408 got_errno = SILC_CONFIG_EMISSFIELDS;
412 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hash);
414 return SILC_CONFIG_OK;
416 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigHash);
418 /* Identify and save this value */
419 if (!strcmp(name, "name")) {
420 CONFIG_IS_DOUBLE(tmp->name);
421 tmp->name = strdup((char *) val);
423 else if (!strcmp(name, "blocklength")) {
424 tmp->block_length = *(int *)val;
426 else if (!strcmp(name, "digestlength")) {
427 tmp->digest_length = *(int *)val;
430 return SILC_CONFIG_EINTERNAL;
431 return SILC_CONFIG_OK;
434 silc_free(tmp->name);
440 SILC_CONFIG_CALLBACK(fetch_hmac)
442 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigHmac);
444 SERVER_CONFIG_DEBUG(("Received HMAC type=%d name=\"%s\" (val=%x)",
445 type, name, context));
446 if (type == SILC_CONFIG_ARG_BLOCK) {
447 /* check the temporary struct's fields */
448 if (!tmp) /* discard empty sub-blocks */
449 return SILC_CONFIG_OK;
450 if (!tmp->name || !tmp->hash || (tmp->mac_length == 0)) {
451 got_errno = SILC_CONFIG_EMISSFIELDS;
455 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hmac);
457 return SILC_CONFIG_OK;
459 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigHmac);
461 /* Identify and save this value */
462 if (!strcmp(name, "name")) {
463 CONFIG_IS_DOUBLE(tmp->name);
464 tmp->name = strdup((char *) val);
466 else if (!strcmp(name, "hash")) {
467 CONFIG_IS_DOUBLE(tmp->hash);
468 tmp->hash = strdup((char *) val);
470 else if (!strcmp(name, "maclength")) {
471 tmp->mac_length = *(int *)val;
474 return SILC_CONFIG_EINTERNAL;
475 return SILC_CONFIG_OK;
478 silc_free(tmp->name);
479 silc_free(tmp->hash);
485 SILC_CONFIG_CALLBACK(fetch_pkcs)
487 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigPkcs);
489 SERVER_CONFIG_DEBUG(("Received PKCS type=%d name=\"%s\" (val=%x)",
490 type, name, context));
491 if (type == SILC_CONFIG_ARG_BLOCK) {
492 /* Check the temporary struct's fields */
493 if (!tmp) /* discard empty sub-blocks */
494 return SILC_CONFIG_OK;
496 got_errno = SILC_CONFIG_EMISSFIELDS;
500 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->pkcs);
502 return SILC_CONFIG_OK;
504 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigPkcs);
506 /* Identify and save this value */
507 if (!strcmp(name, "name")) {
508 CONFIG_IS_DOUBLE(tmp->name);
509 tmp->name = strdup((char *) val);
512 return SILC_CONFIG_EINTERNAL;
513 return SILC_CONFIG_OK;
516 silc_free(tmp->name);
522 SILC_CONFIG_CALLBACK(fetch_serverinfo)
524 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServerInfoInterface);
525 SilcServerConfigServerInfo *server_info = config->server_info;
527 SERVER_CONFIG_DEBUG(("Received SERVERINFO type=%d name=\"%s\" (val=%x)",
528 type, name, context));
530 /* If there isn't the main struct alloc it */
532 config->server_info = server_info = (SilcServerConfigServerInfo *)
533 silc_calloc(1, sizeof(*server_info));
535 if (type == SILC_CONFIG_ARG_BLOCK) {
536 if (!strcmp(name, "primary")) {
537 if (server_info->primary) {
538 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
539 "Double primary specification."));
540 got_errno = SILC_CONFIG_EPRINTLINE;
543 CONFIG_IS_DOUBLE(server_info->primary);
545 /* now check the temporary struct, don't accept empty block and
546 make sure all fields are there */
547 if (!tmp || !tmp->server_ip || !tmp->port) {
548 got_errno = SILC_CONFIG_EMISSFIELDS;
551 server_info->primary = tmp;
553 return SILC_CONFIG_OK;
554 } else if (!strcmp(name, "secondary")) {
556 return SILC_CONFIG_OK;
557 if (!tmp || !tmp->server_ip || !tmp->port) {
558 got_errno = SILC_CONFIG_EMISSFIELDS;
561 SILC_SERVER_CONFIG_LIST_APPENDTMP(server_info->secondary);
563 return SILC_CONFIG_OK;
564 } else if (!server_info->public_key || !server_info->private_key) {
565 got_errno = SILC_CONFIG_EMISSFIELDS;
568 return SILC_CONFIG_OK;
570 if (!strcmp(name, "hostname")) {
571 CONFIG_IS_DOUBLE(server_info->server_name);
572 server_info->server_name = strdup((char *) val);
574 else if (!strcmp(name, "ip")) {
575 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
576 CONFIG_IS_DOUBLE(tmp->server_ip);
577 tmp->server_ip = strdup((char *) val);
579 else if (!strcmp(name, "public_ip")) {
580 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
581 CONFIG_IS_DOUBLE(tmp->public_ip);
582 tmp->public_ip = strdup((char *) val);
584 else if (!strcmp(name, "port")) {
585 int port = *(int *)val;
586 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
587 if ((port <= 0) || (port > 65535)) {
588 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
589 "Invalid port number!"));
590 got_errno = SILC_CONFIG_EPRINTLINE;
593 tmp->port = (SilcUInt16) port;
595 else if (!strcmp(name, "servertype")) {
596 CONFIG_IS_DOUBLE(server_info->server_type);
597 server_info->server_type = strdup((char *) val);
599 else if (!strcmp(name, "admin")) {
600 CONFIG_IS_DOUBLE(server_info->admin);
601 server_info->admin = strdup((char *) val);
603 else if (!strcmp(name, "adminemail")) {
604 CONFIG_IS_DOUBLE(server_info->email);
605 server_info->email = strdup((char *) val);
607 else if (!strcmp(name, "location")) {
608 CONFIG_IS_DOUBLE(server_info->location);
609 server_info->location = strdup((char *) val);
611 else if (!strcmp(name, "user")) {
612 CONFIG_IS_DOUBLE(server_info->user);
613 server_info->user = strdup((char *) val);
615 else if (!strcmp(name, "group")) {
616 CONFIG_IS_DOUBLE(server_info->group);
617 server_info->group = strdup((char *) val);
619 else if (!strcmp(name, "motdfile")) {
620 CONFIG_IS_DOUBLE(server_info->motd_file);
621 server_info->motd_file = strdup((char *) val);
623 else if (!strcmp(name, "pidfile")) {
624 CONFIG_IS_DOUBLE(server_info->pid_file);
625 server_info->pid_file = strdup((char *) val);
627 else if (!strcmp(name, "publickey")) {
628 char *file_tmp = (char *) val;
629 CONFIG_IS_DOUBLE(server_info->public_key);
631 /* Try to load specified file, if fail stop config parsing */
632 if (!silc_pkcs_load_public_key(file_tmp, &server_info->public_key)) {
633 SILC_SERVER_LOG_ERROR(("Error: Could not load public key file."));
634 return SILC_CONFIG_EPRINTLINE;
637 else if (!strcmp(name, "privatekey")) {
639 char *file_tmp = (char *) val;
640 CONFIG_IS_DOUBLE(server_info->private_key);
642 /* Check the private key file permissions. */
643 if ((stat(file_tmp, &st)) != -1) {
644 if (((st.st_mode & 0777) != 0600) &&
645 ((st.st_mode & 0777) != 0640)) {
646 SILC_SERVER_LOG_ERROR(("Wrong permissions in private key "
647 "file \"%s\". The permissions must be "
648 "0600 or 0640.", file_tmp));
649 return SILC_CONFIG_ESILENT;
653 /* Try to load specified file, if fail stop config parsing */
654 if (!silc_pkcs_load_private_key(file_tmp, "", 0,
655 &server_info->private_key)) {
656 SILC_SERVER_LOG_ERROR(("Error: Could not load private key file."));
657 return SILC_CONFIG_EPRINTLINE;
660 /* Warn if key length is < 4096 (some versions created 4095 bit keys). */
661 if (silc_pkcs_private_key_get_len(server_info->private_key) < 4095) {
663 "warning: Your server private key %s length is under 4096 bits. "
664 "It is recommended to use at least 4096 bits. Consider "
665 "generating a new server key pair.\n", file_tmp);
669 return SILC_CONFIG_EINTERNAL;
670 return SILC_CONFIG_OK;
673 /* Here we need to check if tmp exists because this function handles
674 * misc data (multiple fields and single-only fields) */
676 silc_free(tmp->server_ip);
683 SILC_CONFIG_CALLBACK(fetch_logging)
685 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigLogging);
687 if (!strcmp(name, "timestamp")) {
688 config->logging_timestamp = *(SilcBool *)val;
690 else if (!strcmp(name, "quicklogs")) {
691 config->logging_quick = *(SilcBool *)val;
693 else if (!strcmp(name, "flushdelay")) {
694 int flushdelay = *(int *)val;
695 if (flushdelay < 2) { /* this value was taken from silclog.h (min delay) */
696 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
697 "Invalid flushdelay value, use quicklogs if you "
698 "want real-time logging."));
699 return SILC_CONFIG_EPRINTLINE;
701 config->logging_flushdelay = (long) flushdelay;
704 /* The following istances happens only in Logging's sub-blocks, a match
705 for the sub-block name means that you should store the filename/maxsize
706 temporary struct to the proper logging channel.
707 If we get a match for "file" or "maxsize" this means that we are inside
708 a sub-sub-block and it is safe to alloc a new tmp. */
709 #define FETCH_LOGGING_CHAN(__chan__, __member__) \
710 else if (!strcmp(name, __chan__)) { \
711 if (!tmp) return SILC_CONFIG_OK; \
713 got_errno = SILC_CONFIG_EMISSFIELDS; goto got_err; \
715 config->__member__ = tmp; \
716 config->tmp = NULL; \
718 FETCH_LOGGING_CHAN("info", logging_info)
719 FETCH_LOGGING_CHAN("warnings", logging_warnings)
720 FETCH_LOGGING_CHAN("errors", logging_errors)
721 FETCH_LOGGING_CHAN("fatals", logging_fatals)
722 #undef FETCH_LOGGING_CHAN
723 else if (!strcmp(name, "file")) {
724 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigLogging);
725 CONFIG_IS_DOUBLE(tmp->file);
726 tmp->file = strdup((char *) val);
728 else if (!strcmp(name, "size")) {
730 config->tmp = silc_calloc(1, sizeof(*tmp));
731 tmp = (SilcServerConfigLogging *) config->tmp;
733 tmp->maxsize = *(SilcUInt32 *) val;
736 return SILC_CONFIG_EINTERNAL;
737 return SILC_CONFIG_OK;
740 silc_free(tmp->file);
746 SILC_CONFIG_CALLBACK(fetch_connparam)
748 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigConnParams);
750 SERVER_CONFIG_DEBUG(("Received CONNPARAM type=%d name=\"%s\" (val=%x)",
751 type, name, context));
752 if (type == SILC_CONFIG_ARG_BLOCK) {
753 /* check the temporary struct's fields */
754 if (!tmp) /* discard empty sub-blocks */
755 return SILC_CONFIG_OK;
757 got_errno = SILC_CONFIG_EMISSFIELDS;
761 my_set_param_defaults(tmp, &config->param);
763 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->conn_params);
765 return SILC_CONFIG_OK;
768 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigConnParams);
769 tmp->reconnect_keep_trying = TRUE;
772 if (!strcmp(name, "name")) {
773 CONFIG_IS_DOUBLE(tmp->name);
774 tmp->name = (*(char *)val ? strdup((char *) val) : NULL);
776 else if (!strcmp(name, "connections_max")) {
777 tmp->connections_max = *(SilcUInt32 *)val;
779 else if (!strcmp(name, "connections_max_per_host")) {
780 tmp->connections_max_per_host = *(SilcUInt32 *)val;
782 else if (!strcmp(name, "keepalive_secs")) {
783 tmp->keepalive_secs = *(SilcUInt32 *)val;
785 else if (!strcmp(name, "reconnect_count")) {
786 tmp->reconnect_count = *(SilcUInt32 *)val;
788 else if (!strcmp(name, "reconnect_interval")) {
789 tmp->reconnect_interval = *(SilcUInt32 *)val;
791 else if (!strcmp(name, "reconnect_interval_max")) {
792 tmp->reconnect_interval_max = *(SilcUInt32 *)val;
794 else if (!strcmp(name, "reconnect_keep_trying")) {
795 tmp->reconnect_keep_trying = *(SilcBool *)val;
797 else if (!strcmp(name, "key_exchange_rekey")) {
798 tmp->key_exchange_rekey = *(SilcUInt32 *)val;
800 else if (!strcmp(name, "key_exchange_pfs")) {
801 tmp->key_exchange_pfs = *(SilcBool *)val;
803 else if (!strcmp(name, "version_protocol")) {
804 CONFIG_IS_DOUBLE(tmp->version_protocol);
805 tmp->version_protocol = (*(char *)val ? strdup((char *) val) : NULL);
807 else if (!strcmp(name, "version_software")) {
808 CONFIG_IS_DOUBLE(tmp->version_software);
809 tmp->version_software = (*(char *)val ? strdup((char *) val) : NULL);
811 else if (!strcmp(name, "version_software_vendor")) {
812 CONFIG_IS_DOUBLE(tmp->version_software_vendor);;
813 tmp->version_software_vendor =
814 (*(char *)val ? strdup((char *) val) : NULL);
816 else if (!strcmp(name, "anonymous")) {
817 tmp->anonymous = *(SilcBool *)val;
819 else if (!strcmp(name, "qos")) {
820 tmp->qos = *(SilcBool *)val;
822 else if (!strcmp(name, "qos_rate_limit")) {
823 tmp->qos_rate_limit = *(SilcUInt32 *)val;
825 else if (!strcmp(name, "qos_bytes_limit")) {
826 tmp->qos_bytes_limit = *(SilcUInt32 *)val;
828 else if (!strcmp(name, "qos_limit_sec")) {
829 tmp->qos_limit_sec = *(SilcUInt32 *)val;
831 else if (!strcmp(name, "qos_limit_usec")) {
832 tmp->qos_limit_usec = *(SilcUInt32 *)val;
835 return SILC_CONFIG_EINTERNAL;
837 return SILC_CONFIG_OK;
840 silc_free(tmp->name);
846 SILC_CONFIG_CALLBACK(fetch_client)
848 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigClient);
850 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
851 type, name, context));
853 /* Alloc before block checking, because empty sub-blocks are welcome here */
854 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigClient);
856 if (type == SILC_CONFIG_ARG_BLOCK) {
857 /* empty sub-blocks are welcome */
858 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->clients);
860 return SILC_CONFIG_OK;
863 /* Identify and save this value */
864 if (!strcmp(name, "host")) {
865 CONFIG_IS_DOUBLE(tmp->host);
866 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
868 else if (!strcmp(name, "passphrase")) {
869 CONFIG_IS_DOUBLE(tmp->passphrase);
870 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
871 (void *)&tmp->passphrase,
872 &tmp->passphrase_len, 0, NULL)) {
873 got_errno = SILC_CONFIG_EPRINTLINE;
877 else if (!strcmp(name, "publickey")) {
878 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
879 (void *)&config->server->repository, NULL,
880 SILC_SKR_USAGE_AUTH |
881 SILC_SKR_USAGE_KEY_AGREEMENT, NULL)) {
882 got_errno = SILC_CONFIG_EPRINTLINE;
885 tmp->publickeys = TRUE;
887 else if (!strcmp(name, "publickeydir")) {
888 if (my_parse_publickeydir((char *) val,
889 (void *)&config->server->repository,
890 SILC_SKR_USAGE_AUTH |
891 SILC_SKR_USAGE_KEY_AGREEMENT) < 0) {
892 got_errno = SILC_CONFIG_EPRINTLINE;
895 tmp->publickeys = TRUE;
897 else if (!strcmp(name, "params")) {
898 CONFIG_IS_DOUBLE(tmp->param);
899 tmp->param = my_find_param(config, (char *) val);
900 if (!tmp->param) { /* error message already output */
901 got_errno = SILC_CONFIG_EPRINTLINE;
906 return SILC_CONFIG_EINTERNAL;
907 return SILC_CONFIG_OK;
910 silc_free(tmp->host);
911 CONFIG_FREE_AUTH(tmp);
917 SILC_CONFIG_CALLBACK(fetch_admin)
919 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigAdmin);
921 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
922 type, name, context));
923 if (type == SILC_CONFIG_ARG_BLOCK) {
924 /* check the temporary struct's fields */
925 if (!tmp) /* discard empty sub-blocks */
926 return SILC_CONFIG_OK;
928 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->admins);
930 return SILC_CONFIG_OK;
932 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigAdmin);
934 /* Identify and save this value */
935 if (!strcmp(name, "host")) {
936 CONFIG_IS_DOUBLE(tmp->host);
937 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
939 else if (!strcmp(name, "user")) {
940 CONFIG_IS_DOUBLE(tmp->user);
941 tmp->user = (*(char *)val ? strdup((char *) val) : NULL);
943 else if (!strcmp(name, "nick")) {
944 CONFIG_IS_DOUBLE(tmp->nick);
945 tmp->nick = (*(char *)val ? strdup((char *) val) : NULL);
947 else if (!strcmp(name, "passphrase")) {
948 CONFIG_IS_DOUBLE(tmp->passphrase);
949 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
950 (void *)&tmp->passphrase,
951 &tmp->passphrase_len, 0, NULL)) {
952 got_errno = SILC_CONFIG_EPRINTLINE;
956 else if (!strcmp(name, "publickey")) {
957 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
958 (void *)&config->server->repository, NULL,
959 SILC_SKR_USAGE_SERVICE_AUTHORIZATION, tmp)) {
960 got_errno = SILC_CONFIG_EPRINTLINE;
963 tmp->publickeys = TRUE;
966 return SILC_CONFIG_EINTERNAL;
967 return SILC_CONFIG_OK;
970 silc_free(tmp->host);
971 silc_free(tmp->user);
972 silc_free(tmp->nick);
973 CONFIG_FREE_AUTH(tmp);
979 SILC_CONFIG_CALLBACK(fetch_deny)
981 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigDeny);
983 SERVER_CONFIG_DEBUG(("Received DENY type=%d name=\"%s\" (val=%x)",
984 type, name, context));
985 if (type == SILC_CONFIG_ARG_BLOCK) {
986 /* check the temporary struct's fields */
987 if (!tmp) /* discard empty sub-blocks */
988 return SILC_CONFIG_OK;
990 got_errno = SILC_CONFIG_EMISSFIELDS;
994 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->denied);
996 return SILC_CONFIG_OK;
998 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigDeny);
1000 /* Identify and save this value */
1001 if (!strcmp(name, "host")) {
1002 CONFIG_IS_DOUBLE(tmp->host);
1003 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
1005 else if (!strcmp(name, "reason")) {
1006 CONFIG_IS_DOUBLE(tmp->reason);
1007 tmp->reason = strdup((char *) val);
1010 return SILC_CONFIG_EINTERNAL;
1011 return SILC_CONFIG_OK;
1014 silc_free(tmp->host);
1015 silc_free(tmp->reason);
1021 SILC_CONFIG_CALLBACK(fetch_server)
1023 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServer);
1025 SERVER_CONFIG_DEBUG(("Received SERVER type=%d name=\"%s\" (val=%x)",
1026 type, name, context));
1027 if (type == SILC_CONFIG_ARG_BLOCK) {
1028 /* check the temporary struct's fields */
1029 if (!tmp) /* discard empty sub-blocks */
1030 return SILC_CONFIG_OK;
1032 got_errno = SILC_CONFIG_EMISSFIELDS;
1036 /* the temporary struct is ok, append it to the list */
1037 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->servers);
1039 return SILC_CONFIG_OK;
1041 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServer);
1043 /* Identify and save this value */
1044 if (!strcmp(name, "host")) {
1045 CONFIG_IS_DOUBLE(tmp->host);
1046 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
1048 else if (!strcmp(name, "passphrase")) {
1049 CONFIG_IS_DOUBLE(tmp->passphrase);
1050 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
1051 (void *)&tmp->passphrase,
1052 &tmp->passphrase_len, 0, NULL)) {
1053 got_errno = SILC_CONFIG_EPRINTLINE;
1057 else if (!strcmp(name, "publickey")) {
1058 CONFIG_IS_DOUBLE(tmp->publickeys);
1059 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
1060 (void *)&config->server->repository, NULL,
1061 SILC_SKR_USAGE_AUTH |
1062 SILC_SKR_USAGE_KEY_AGREEMENT, NULL)) {
1063 got_errno = SILC_CONFIG_EPRINTLINE;
1066 tmp->publickeys = TRUE;
1068 else if (!strcmp(name, "params")) {
1069 CONFIG_IS_DOUBLE(tmp->param);
1070 tmp->param = my_find_param(config, (char *) val);
1071 if (!tmp->param) { /* error message already output */
1072 got_errno = SILC_CONFIG_EPRINTLINE;
1076 else if (!strcmp(name, "backup")) {
1077 tmp->backup_router = *(SilcBool *)val;
1080 return SILC_CONFIG_EINTERNAL;
1082 return SILC_CONFIG_OK;
1085 silc_free(tmp->host);
1086 CONFIG_FREE_AUTH(tmp);
1092 SILC_CONFIG_CALLBACK(fetch_router)
1094 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigRouter);
1096 SERVER_CONFIG_DEBUG(("Received ROUTER type=%d name=\"%s\" (val=%x)",
1097 type, name, context));
1098 if (type == SILC_CONFIG_ARG_BLOCK) {
1099 if (!tmp) /* discard empty sub-blocks */
1100 return SILC_CONFIG_OK;
1102 got_errno = SILC_CONFIG_EMISSFIELDS;
1106 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->routers);
1108 return SILC_CONFIG_OK;
1110 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigRouter);
1112 /* Identify and save this value */
1113 if (!strcmp(name, "host")) {
1114 CONFIG_IS_DOUBLE(tmp->host);
1115 tmp->host = strdup((char *) val);
1117 else if (!strcmp(name, "port")) {
1118 int port = *(int *)val;
1119 if ((port <= 0) || (port > 65535)) {
1120 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
1121 "Invalid port number!"));
1122 got_errno = SILC_CONFIG_EPRINTLINE;
1125 tmp->port = (SilcUInt16) port;
1127 else if (!strcmp(name, "passphrase")) {
1128 CONFIG_IS_DOUBLE(tmp->passphrase);
1129 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
1130 (void *)&tmp->passphrase,
1131 &tmp->passphrase_len, 0, NULL)) {
1132 got_errno = SILC_CONFIG_EPRINTLINE;
1136 else if (!strcmp(name, "publickey")) {
1137 CONFIG_IS_DOUBLE(tmp->publickeys);
1138 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
1139 (void *)&config->server->repository, NULL,
1140 SILC_SKR_USAGE_AUTH |
1141 SILC_SKR_USAGE_KEY_AGREEMENT, NULL)) {
1142 got_errno = SILC_CONFIG_EPRINTLINE;
1145 tmp->publickeys = TRUE;
1147 else if (!strcmp(name, "params")) {
1148 CONFIG_IS_DOUBLE(tmp->param);
1149 tmp->param = my_find_param(config, (char *) val);
1150 if (!tmp->param) { /* error message already output */
1151 got_errno = SILC_CONFIG_EPRINTLINE;
1155 else if (!strcmp(name, "initiator")) {
1156 tmp->initiator = *(SilcBool *)val;
1158 else if (!strcmp(name, "backuphost")) {
1159 CONFIG_IS_DOUBLE(tmp->backup_replace_ip);
1160 tmp->backup_replace_ip = (*(char *)val ? strdup((char *) val) :
1162 tmp->backup_router = TRUE;
1164 else if (!strcmp(name, "backupport")) {
1165 int port = *(int *)val;
1166 if ((port <= 0) || (port > 65535)) {
1167 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
1168 "Invalid port number!"));
1169 got_errno = SILC_CONFIG_EPRINTLINE;
1172 tmp->backup_replace_port = (SilcUInt16) port;
1174 else if (!strcmp(name, "backuplocal")) {
1175 tmp->backup_local = *(SilcBool *)val;
1177 else if (!strcmp(name, "dynamic_connection")) {
1178 tmp->dynamic_connection = *(SilcBool *)val;
1181 return SILC_CONFIG_EINTERNAL;
1183 return SILC_CONFIG_OK;
1186 silc_free(tmp->host);
1187 silc_free(tmp->backup_replace_ip);
1188 CONFIG_FREE_AUTH(tmp);
1194 /* known config options tables */
1195 static const SilcConfigTable table_general[] = {
1196 { "prefer_passphrase_auth", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1197 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1198 { "connections_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1199 { "connections_max_per_host", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1200 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1201 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1202 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1203 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1204 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1205 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1206 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1207 { "channel_rekey_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1208 { "key_exchange_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1209 { "conn_auth_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1210 { "version_protocol", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1211 { "version_software", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1212 { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1213 { "detach_disabled", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1214 { "detach_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1215 { "qos", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1216 { "qos_rate_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1217 { "qos_bytes_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1218 { "qos_limit_sec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1219 { "qos_limit_usec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1220 { "channel_join_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1221 { "debug_string", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1222 { "http_server", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1223 { "http_server_ip", SILC_CONFIG_ARG_STRE, fetch_generic, NULL },
1224 { "http_server_port", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1225 { "dynamic_server", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1226 { "local_channels", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1230 static const SilcConfigTable table_cipher[] = {
1231 { "name", SILC_CONFIG_ARG_STR, fetch_cipher, NULL },
1232 { "keylength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1233 { "blocklength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1237 static const SilcConfigTable table_hash[] = {
1238 { "name", SILC_CONFIG_ARG_STR, fetch_hash, NULL },
1239 { "blocklength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1240 { "digestlength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1244 static const SilcConfigTable table_hmac[] = {
1245 { "name", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1246 { "hash", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1247 { "maclength", SILC_CONFIG_ARG_INT, fetch_hmac, NULL },
1251 static const SilcConfigTable table_pkcs[] = {
1252 { "name", SILC_CONFIG_ARG_STR, fetch_pkcs, NULL },
1256 static const SilcConfigTable table_serverinfo_c[] = {
1257 { "ip", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1258 { "public_ip", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1259 { "port", SILC_CONFIG_ARG_INT, fetch_serverinfo, NULL},
1263 static const SilcConfigTable table_serverinfo[] = {
1264 { "hostname", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1265 { "primary", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo_c},
1266 { "secondary", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo_c},
1267 { "servertype", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1268 { "location", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1269 { "admin", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1270 { "adminemail", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1271 { "user", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1272 { "group", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1273 { "publickey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1274 { "privatekey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1275 { "motdfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1276 { "pidfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1280 static const SilcConfigTable table_logging_c[] = {
1281 { "file", SILC_CONFIG_ARG_STR, fetch_logging, NULL },
1282 { "size", SILC_CONFIG_ARG_SIZE, fetch_logging, NULL },
1283 /*{ "quicklog", SILC_CONFIG_ARG_NONE, fetch_logging, NULL }, */
1287 static const SilcConfigTable table_logging[] = {
1288 { "timestamp", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1289 { "quicklogs", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1290 { "flushdelay", SILC_CONFIG_ARG_INT, fetch_logging, NULL },
1291 { "info", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1292 { "warnings", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1293 { "errors", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1294 { "fatals", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1298 static const SilcConfigTable table_connparam[] = {
1299 { "name", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1300 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1301 { "connections_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1302 { "connections_max_per_host",SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1303 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1304 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1305 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1306 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1307 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1308 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1309 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1310 { "version_protocol", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1311 { "version_software", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1312 { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1313 { "anonymous", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1314 { "qos", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1315 { "qos_rate_limit", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1316 { "qos_bytes_limit", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1317 { "qos_limit_sec", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1318 { "qos_limit_usec", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1322 static const SilcConfigTable table_client[] = {
1323 { "host", SILC_CONFIG_ARG_STRE, fetch_client, NULL },
1324 { "passphrase", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1325 { "publickey", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1326 { "publickeydir", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1327 { "params", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1331 static const SilcConfigTable table_admin[] = {
1332 { "host", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1333 { "user", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1334 { "nick", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1335 { "passphrase", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1336 { "publickey", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1337 { "port", SILC_CONFIG_ARG_INT, fetch_admin, NULL },
1338 { "params", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1342 static const SilcConfigTable table_deny[] = {
1343 { "host", SILC_CONFIG_ARG_STRE, fetch_deny, NULL },
1344 { "reason", SILC_CONFIG_ARG_STR, fetch_deny, NULL },
1348 static const SilcConfigTable table_serverconn[] = {
1349 { "host", SILC_CONFIG_ARG_STRE, fetch_server, NULL },
1350 { "passphrase", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1351 { "publickey", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1352 { "params", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1353 { "backup", SILC_CONFIG_ARG_TOGGLE, fetch_server, NULL },
1357 static const SilcConfigTable table_routerconn[] = {
1358 { "host", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1359 { "port", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1360 { "passphrase", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1361 { "publickey", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1362 { "params", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1363 { "initiator", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1364 { "backuphost", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1365 { "backupport", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1366 { "backuplocal", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1367 { "dynamic_connection", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1371 static const SilcConfigTable table_main[] = {
1372 { "cipher", SILC_CONFIG_ARG_BLOCK, fetch_cipher, table_cipher },
1373 { "hash", SILC_CONFIG_ARG_BLOCK, fetch_hash, table_hash },
1374 { "hmac", SILC_CONFIG_ARG_BLOCK, fetch_hmac, table_hmac },
1375 { "pkcs", SILC_CONFIG_ARG_BLOCK, fetch_pkcs, table_pkcs },
1376 { "general", SILC_CONFIG_ARG_BLOCK, NULL, table_general },
1377 { "serverinfo", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo },
1378 { "logging", SILC_CONFIG_ARG_BLOCK, NULL, table_logging },
1379 { "connectionparams", SILC_CONFIG_ARG_BLOCK, fetch_connparam, table_connparam },
1380 { "client", SILC_CONFIG_ARG_BLOCK, fetch_client, table_client },
1381 { "admin", SILC_CONFIG_ARG_BLOCK, fetch_admin, table_admin },
1382 { "deny", SILC_CONFIG_ARG_BLOCK, fetch_deny, table_deny },
1383 { "serverconnection", SILC_CONFIG_ARG_BLOCK, fetch_server, table_serverconn },
1384 { "routerconnection", SILC_CONFIG_ARG_BLOCK, fetch_router, table_routerconn },
1388 /* Set default values to stuff that was not configured. */
1390 static void silc_server_config_set_defaults(SilcServerConfig config)
1392 my_set_param_defaults(&config->param, NULL);
1394 config->channel_rekey_secs = (config->channel_rekey_secs ?
1395 config->channel_rekey_secs :
1396 SILC_SERVER_CHANNEL_REKEY);
1397 config->key_exchange_timeout = (config->key_exchange_timeout ?
1398 config->key_exchange_timeout :
1399 SILC_SERVER_SKE_TIMEOUT);
1400 config->conn_auth_timeout = (config->conn_auth_timeout ?
1401 config->conn_auth_timeout :
1402 SILC_SERVER_CONNAUTH_TIMEOUT);
1405 /* Check for correctness of the configuration */
1407 static SilcBool silc_server_config_check(SilcServerConfig config)
1409 SilcBool ret = TRUE;
1410 SilcServerConfigServer *s;
1411 SilcServerConfigRouter *r;
1414 /* ServerConfig is mandatory */
1415 if (!config->server_info) {
1416 SILC_SERVER_LOG_ERROR(("\nError: Missing mandatory block `ServerInfo'"));
1420 if (!config->server_info->public_key ||
1421 !config->server_info->private_key) {
1422 SILC_SERVER_LOG_ERROR(("\nError: Server keypair is missing"));
1426 if (!config->server_info->primary) {
1427 SILC_SERVER_LOG_ERROR(("\nError: Missing mandatory block `Primary' "
1428 "in `ServerInfo'"));
1432 if (!config->server_info->primary->server_ip) {
1433 SILC_SERVER_LOG_ERROR(("\nError: Missing mandatory field `Ip' "
1434 "in `Primary' in `ServerInfo'"));
1438 /* RouterConnection sanity checks */
1440 if (config->routers && config->routers->backup_router == TRUE &&
1442 SILC_SERVER_LOG_ERROR((
1443 "\nError: First RouterConnection block must be primary router "
1444 "connection. You have marked it incorrectly as backup router."));
1447 if (config->routers && config->routers->backup_router == TRUE &&
1448 !config->servers && !config->routers->next) {
1449 SILC_SERVER_LOG_ERROR((
1450 "\nError: You have configured backup router but not primary router. "
1451 "If backup router is configured also primary router must be "
1456 /* Backup router sanity checks */
1458 for (r = config->routers; r; r = r->next) {
1459 if (r->backup_router && !strcmp(r->host, r->backup_replace_ip)) {
1460 SILC_SERVER_LOG_ERROR((
1461 "\nError: Backup router connection incorrectly configured to use "
1462 "primary and backup router as same host `%s'. They must not be "
1463 "same host.", r->host));
1467 if (r->initiator == FALSE && r->port != 0) {
1468 SILC_SERVER_LOG_WARNING(("\nWarning: Initiator is FALSE and Port is "
1469 "specified. Ignoring Port value."));
1474 /* ServerConnection sanity checks */
1476 for (s = config->servers; s; s = s->next) {
1477 if (s->backup_router) {
1483 for (s = config->servers; s; s = s->next) {
1484 if (!s->backup_router) {
1485 SILC_SERVER_LOG_ERROR((
1486 "\nError: Your server is backup router but not all ServerConnection "
1487 "blocks were marked as backup connections. They all must be "
1488 "marked as backup connections."));
1498 /* Allocates a new configuration object, opens configuration file and
1499 parses it. The parsed data is returned to the newly allocated
1500 configuration object. The SilcServerConfig must be freed by calling
1501 the silc_server_config_destroy function. */
1503 SilcServerConfig silc_server_config_alloc(const char *filename,
1506 SilcServerConfig config_new;
1507 SilcConfigEntity ent;
1508 SilcConfigFile *file;
1510 SILC_LOG_DEBUG(("Loading config data from `%s'", filename));
1512 /* alloc a config object */
1513 config_new = silc_calloc(1, sizeof(*config_new));
1517 /* general config defaults */
1518 config_new->refcount = 1;
1519 config_new->logging_timestamp = TRUE;
1520 config_new->param.reconnect_keep_trying = TRUE;
1521 config_new->server = server;
1523 /* obtain a config file object */
1524 file = silc_config_open(filename);
1526 SILC_SERVER_LOG_ERROR(("\nError: can't open config file `%s'",
1531 /* obtain a SilcConfig entity, we can use it to start the parsing */
1532 ent = silc_config_init(file);
1534 /* load the known configuration options, give our empty object as context */
1535 silc_config_register_table(ent, table_main, (void *) config_new);
1537 /* enter the main parsing loop. When this returns, we have the parsing
1538 * result and the object filled (or partially, in case of errors). */
1539 ret = silc_config_main(ent);
1540 SILC_LOG_DEBUG(("Parser returned [ret=%d]: %s", ret,
1541 silc_config_strerror(ret)));
1543 /* Check if the parser returned errors */
1545 /* handle this special error return which asks to quietly return */
1546 if (ret != SILC_CONFIG_ESILENT) {
1547 char *linebuf, *filename = silc_config_get_filename(file);
1548 SilcUInt32 line = silc_config_get_line(file);
1549 if (ret != SILC_CONFIG_EPRINTLINE)
1550 SILC_SERVER_LOG_ERROR(("Error while parsing config file: %s.",
1551 silc_config_strerror(ret)));
1552 linebuf = silc_config_read_line(file, line);
1554 SILC_SERVER_LOG_ERROR((" file %s line %u: %s\n", filename,
1559 silc_server_config_destroy(config_new);
1560 silc_config_close(file);
1564 /* close (destroy) the file object */
1565 silc_config_close(file);
1567 /* Check the configuration */
1568 if (!silc_server_config_check(config_new)) {
1569 silc_server_config_destroy(config_new);
1573 /* Set default to configuration parameters */
1574 silc_server_config_set_defaults(config_new);
1579 /* Increments the reference counter of a config object */
1581 void silc_server_config_ref(SilcServerConfigRef *ref, SilcServerConfig config,
1586 ref->config = config;
1587 ref->ref_ptr = ref_ptr;
1588 SILC_LOG_DEBUG(("Referencing config [%p] refcnt %d->%d", config,
1589 config->refcount - 1, config->refcount));
1593 /* Decrements the reference counter of a config object. If the counter
1594 reaches 0, the config object is destroyed. */
1596 void silc_server_config_unref(SilcServerConfigRef *ref)
1599 silc_server_config_destroy(ref->config);
1602 /* Destroy a config object with all his children lists */
1604 void silc_server_config_destroy(SilcServerConfig config)
1609 SILC_LOG_DEBUG(("Unreferencing config [%p] refcnt %d->%d", config,
1610 config->refcount + 1, config->refcount));
1611 if (config->refcount > 0)
1614 SILC_LOG_DEBUG(("Freeing config context"));
1616 /* Destroy general config stuff */
1617 silc_free(config->debug_string);
1618 silc_free(config->param.version_protocol);
1619 silc_free(config->param.version_software);
1620 silc_free(config->param.version_software_vendor);
1621 silc_free(config->httpd_ip);
1623 /* Destroy Logging channels */
1624 if (config->logging_info)
1625 silc_free(config->logging_info->file);
1626 if (config->logging_warnings)
1627 silc_free(config->logging_warnings->file);
1628 if (config->logging_errors)
1629 silc_free(config->logging_errors->file);
1630 if (config->logging_fatals)
1631 silc_free(config->logging_fatals->file);
1632 silc_free(config->logging_info);
1633 silc_free(config->logging_warnings);
1634 silc_free(config->logging_errors);
1635 silc_free(config->logging_fatals);
1637 /* Destroy the ServerInfo struct */
1638 if (config->server_info) {
1639 register SilcServerConfigServerInfo *si = config->server_info;
1640 silc_free(si->server_name);
1642 silc_free(si->primary->server_ip);
1643 silc_free(si->primary);
1645 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServerInfoInterface,
1647 silc_free(di->server_ip);
1650 silc_free(si->server_type);
1651 silc_free(si->location);
1652 silc_free(si->admin);
1653 silc_free(si->email);
1654 silc_free(si->user);
1655 silc_free(si->group);
1656 silc_free(si->motd_file);
1657 silc_free(si->pid_file);
1659 silc_pkcs_public_key_free(si->public_key);
1660 if (si->private_key)
1661 silc_pkcs_private_key_free(si->private_key);
1665 /* Now let's destroy the lists */
1667 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigCipher,
1669 silc_free(di->name);
1672 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHash, config->hash)
1673 silc_free(di->name);
1676 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHmac, config->hmac)
1677 silc_free(di->name);
1678 silc_free(di->hash);
1681 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigPkcs, config->pkcs)
1682 silc_free(di->name);
1685 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigConnParams,
1686 config->conn_params)
1687 silc_free(di->name);
1688 silc_free(di->version_protocol);
1689 silc_free(di->version_software);
1690 silc_free(di->version_software_vendor);
1693 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigClient, config->clients)
1694 silc_free(di->host);
1695 CONFIG_FREE_AUTH(di);
1698 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigAdmin, config->admins)
1699 silc_free(di->host);
1700 silc_free(di->user);
1701 silc_free(di->nick);
1702 CONFIG_FREE_AUTH(di);
1705 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigDeny, config->denied)
1706 silc_free(di->host);
1707 silc_free(di->reason);
1710 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServer,
1712 silc_free(di->host);
1713 CONFIG_FREE_AUTH(di);
1716 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigRouter,
1718 silc_free(di->host);
1719 silc_free(di->backup_replace_ip);
1720 CONFIG_FREE_AUTH(di);
1724 memset(config, 'F', sizeof(*config));
1728 /* Registers configured ciphers. These can then be allocated by the
1729 server when needed. */
1731 SilcBool silc_server_config_register_ciphers(SilcServer server)
1733 SilcServerConfig config = server->config;
1734 SilcServerConfigCipher *cipher = config->cipher;
1735 char *module_path = config->module_path;
1737 SILC_LOG_DEBUG(("Registering configured ciphers"));
1739 if (!cipher) /* any cipher in the config file? */
1743 /* if there isn't a module_path OR there isn't a module sim name try to
1744 * use buil-in functions */
1745 if (!module_path || !cipher->module) {
1747 for (i = 0; silc_default_ciphers[i].name; i++)
1748 if (!strcmp(silc_default_ciphers[i].name, cipher->name)) {
1749 silc_cipher_register((SilcCipherObject *)&silc_default_ciphers[i]);
1752 if (!silc_cipher_is_supported(cipher->name)) {
1753 SILC_LOG_ERROR(("Unknown cipher `%s'", cipher->name));
1754 silc_server_stop(server);
1758 cipher = cipher->next;
1764 /* Registers configured hash functions. These can then be allocated by the
1765 server when needed. */
1767 SilcBool silc_server_config_register_hashfuncs(SilcServer server)
1769 SilcServerConfig config = server->config;
1770 SilcServerConfigHash *hash = config->hash;
1771 char *module_path = config->module_path;
1773 SILC_LOG_DEBUG(("Registering configured hash functions"));
1775 if (!hash) /* any hash func in the config file? */
1779 /* if there isn't a module_path OR there isn't a module sim name try to
1780 * use buil-in functions */
1781 if (!module_path || !hash->module) {
1783 for (i = 0; silc_default_hash[i].name; i++)
1784 if (!strcmp(silc_default_hash[i].name, hash->name)) {
1785 silc_hash_register((SilcHashObject *)&silc_default_hash[i]);
1788 if (!silc_hash_is_supported(hash->name)) {
1789 SILC_LOG_ERROR(("Unknown hash funtion `%s'", hash->name));
1790 silc_server_stop(server);
1800 /* Registers configure HMACs. These can then be allocated by the server
1803 SilcBool silc_server_config_register_hmacs(SilcServer server)
1805 SilcServerConfig config = server->config;
1806 SilcServerConfigHmac *hmac = config->hmac;
1808 SILC_LOG_DEBUG(("Registering configured HMACs"));
1814 SilcHmacObject hmac_obj;
1815 if (!silc_hash_is_supported(hmac->hash)) {
1816 SILC_LOG_ERROR(("Unknown hash function `%s'", hmac->hash));
1817 silc_server_stop(server);
1821 /* Register the HMAC */
1822 memset(&hmac_obj, 0, sizeof(hmac_obj));
1823 hmac_obj.name = hmac->name;
1824 hmac_obj.len = hmac->mac_length;
1825 silc_hmac_register(&hmac_obj);
1833 /* Registers configured PKCS's. */
1835 SilcBool silc_server_config_register_pkcs(SilcServer server)
1840 /* Sets log files where log messages are saved by the server logger. */
1842 void silc_server_config_setlogfiles(SilcServer server)
1844 SilcServerConfig config = server->config;
1845 SilcServerConfigLogging *this;
1847 SILC_LOG_DEBUG(("Setting configured log file names and options"));
1849 silc_log_timestamp(config->logging_timestamp);
1850 silc_log_quick(config->logging_quick);
1851 silc_log_flushdelay(config->logging_flushdelay ?
1852 config->logging_flushdelay :
1853 SILC_SERVER_LOG_FLUSH_DELAY);
1855 if ((this = config->logging_fatals))
1856 silc_log_set_file(SILC_LOG_FATAL, this->file, this->maxsize,
1858 if ((this = config->logging_errors))
1859 silc_log_set_file(SILC_LOG_ERROR, this->file, this->maxsize,
1861 if ((this = config->logging_warnings))
1862 silc_log_set_file(SILC_LOG_WARNING, this->file, this->maxsize,
1864 if ((this = config->logging_info))
1865 silc_log_set_file(SILC_LOG_INFO, this->file, this->maxsize,
1869 /* Returns client authentication information from configuration file by host
1872 SilcServerConfigClient *
1873 silc_server_config_find_client(SilcServer server, char *host)
1875 SilcServerConfig config = server->config;
1876 SilcServerConfigClient *client;
1878 if (!config || !host)
1881 for (client = config->clients; client; client = client->next) {
1882 if (client->host && !silc_string_match(client->host, host))
1887 /* if none matched, then client is already NULL */
1891 /* Returns admin connection configuration by host, username and/or
1894 SilcServerConfigAdmin *
1895 silc_server_config_find_admin(SilcServer server, char *host, char *user,
1898 SilcServerConfig config = server->config;
1899 SilcServerConfigAdmin *admin;
1901 /* make sure we have a value for the matching parameters */
1909 for (admin = config->admins; admin; admin = admin->next) {
1910 if (admin->host && !silc_string_match(admin->host, host))
1912 if (admin->user && !silc_string_match(admin->user, user))
1914 if (admin->nick && !silc_string_match(admin->nick, nick))
1916 /* no checks failed -> this entry matches */
1920 /* if none matched, then admin is already NULL */
1924 /* Returns the denied connection configuration entry by host. */
1926 SilcServerConfigDeny *
1927 silc_server_config_find_denied(SilcServer server, char *host)
1929 SilcServerConfig config = server->config;
1930 SilcServerConfigDeny *deny;
1932 /* make sure we have a value for the matching parameters */
1933 if (!config || !host)
1936 for (deny = config->denied; deny; deny = deny->next) {
1937 if (deny->host && !silc_string_match(deny->host, host))
1942 /* if none matched, then deny is already NULL */
1946 /* Returns server connection info from server configuartion by host
1949 SilcServerConfigServer *
1950 silc_server_config_find_server_conn(SilcServer server, char *host)
1952 SilcServerConfig config = server->config;
1953 SilcServerConfigServer *serv = NULL;
1958 if (!config->servers)
1961 for (serv = config->servers; serv; serv = serv->next) {
1962 if (!silc_string_match(serv->host, host))
1970 /* Returns router connection info from server configuration by
1971 host (name or ip). */
1973 SilcServerConfigRouter *
1974 silc_server_config_find_router_conn(SilcServer server, char *host, int port)
1976 SilcServerConfig config = server->config;
1977 SilcServerConfigRouter *serv = NULL;
1982 if (!config->routers)
1985 for (serv = config->routers; serv; serv = serv->next) {
1986 if (!silc_string_match(serv->host, host))
1988 if (port && serv->port && serv->port != port)
1996 /* Find backup router connection by host (name or ip) */
1998 SilcServerConfigRouter *
1999 silc_server_config_find_backup_conn(SilcServer server, char *host)
2001 SilcServerConfig config = server->config;
2002 SilcServerConfigRouter *serv = NULL;
2007 if (!config->routers)
2010 for (serv = config->routers; serv; serv = serv->next) {
2011 if (!serv->backup_router)
2013 if (!silc_string_match(serv->host, host))
2021 /* Returns TRUE if configuration for a router connection that we are
2022 initiating exists. */
2024 SilcBool silc_server_config_is_primary_route(SilcServer server)
2026 SilcServerConfig config = server->config;
2027 SilcServerConfigRouter *serv = NULL;
2029 SilcBool found = FALSE;
2031 serv = config->routers;
2032 for (i = 0; serv; i++) {
2033 if (serv->initiator == TRUE && serv->backup_router == FALSE) {
2044 /* Returns our primary connection configuration or NULL if we do not
2045 have primary router configured. */
2047 SilcServerConfigRouter *
2048 silc_server_config_get_primary_router(SilcServer server)
2050 SilcServerConfig config = server->config;
2051 SilcServerConfigRouter *serv = NULL;
2054 serv = config->routers;
2055 for (i = 0; serv; i++) {
2056 if (serv->initiator == TRUE && serv->backup_router == FALSE)
2064 /* If we have backup router configured that is going to replace us this
2065 function returns it. */
2067 SilcServerConfigRouter *
2068 silc_server_config_get_backup_router(SilcServer server)
2070 SilcServerConfig config = server->config;
2071 SilcServerConfigRouter *serv = NULL;
2074 if (server->server_type != SILC_ROUTER)
2077 serv = config->routers;
2078 for (i = 0; serv; i++) {
2079 if (serv->initiator == FALSE && serv->backup_router == TRUE &&
2080 serv->backup_local == TRUE &&
2081 !strcmp(server->config->server_info->primary->server_ip,
2082 serv->backup_replace_ip) &&
2083 server->config->server_info->primary->port ==
2084 serv->backup_replace_port)