5 Author: Giovanni Giacobbi <giovanni@giacobbi.net>
7 Copyright (C) 1997 - 2007 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
21 #include "serverincludes.h"
22 #include "server_internal.h"
26 #define SERVER_CONFIG_DEBUG(fmt) SILC_LOG_DEBUG(fmt)
28 #define SERVER_CONFIG_DEBUG(fmt)
31 /* auto-declare needed variables for the common list parsing */
32 #define SILC_SERVER_CONFIG_SECTION_INIT(__type__) \
33 SilcServerConfig config = (SilcServerConfig) context; \
34 __type__ *findtmp, *tmp = (__type__ *) config->tmp; \
37 /* allocate the tmp field for fetching data */
38 #define SILC_SERVER_CONFIG_ALLOCTMP(__type__) \
40 config->tmp = silc_calloc(1, sizeof(*findtmp)); \
41 tmp = (__type__ *) config->tmp; \
44 /* append the tmp field to the specified list */
45 #define SILC_SERVER_CONFIG_LIST_APPENDTMP(__list__) \
49 for (findtmp = __list__; findtmp->next; findtmp = findtmp->next); \
50 findtmp->next = tmp; \
53 /* loops all elements in a list and provides a di struct pointer of the
54 * specified type containing the current element */
55 #define SILC_SERVER_CONFIG_LIST_DESTROY(__type__, __list__) \
56 for (tmp = (void *) __list__; tmp;) { \
57 __type__ *di = (__type__ *) tmp; \
58 tmp = (void *) di->next;
60 /* Set EDOUBLE error value and bail out if necessary */
61 #define CONFIG_IS_DOUBLE(__x__) \
63 got_errno = SILC_CONFIG_EDOUBLE; \
67 /* Free the authentication fields in the specified struct
68 * Expands to two instructions */
69 #define CONFIG_FREE_AUTH(__section__) \
70 silc_free(__section__->passphrase);
72 /* Set default values to those parameters that have not been defined */
74 my_set_param_defaults(SilcServerConfigConnParams *params,
75 SilcServerConfigConnParams *defaults)
77 #define SET_PARAM_DEFAULT(p, d) params->p = \
78 (params->p ? params->p : (defaults && defaults->p ? defaults->p : d))
80 SET_PARAM_DEFAULT(connections_max, SILC_SERVER_MAX_CONNECTIONS);
81 SET_PARAM_DEFAULT(connections_max_per_host,
82 SILC_SERVER_MAX_CONNECTIONS_SINGLE);
83 SET_PARAM_DEFAULT(keepalive_secs, SILC_SERVER_KEEPALIVE);
84 SET_PARAM_DEFAULT(reconnect_count, SILC_SERVER_RETRY_COUNT);
85 SET_PARAM_DEFAULT(reconnect_interval, SILC_SERVER_RETRY_INTERVAL_MIN);
86 SET_PARAM_DEFAULT(reconnect_interval_max, SILC_SERVER_RETRY_INTERVAL_MAX);
87 SET_PARAM_DEFAULT(key_exchange_rekey, SILC_SERVER_REKEY);
88 SET_PARAM_DEFAULT(qos_rate_limit, SILC_SERVER_QOS_RATE_LIMIT);
89 SET_PARAM_DEFAULT(qos_bytes_limit, SILC_SERVER_QOS_BYTES_LIMIT);
90 SET_PARAM_DEFAULT(qos_limit_sec, SILC_SERVER_QOS_LIMIT_SEC);
91 SET_PARAM_DEFAULT(qos_limit_usec, SILC_SERVER_QOS_LIMIT_USEC);
92 SET_PARAM_DEFAULT(chlimit, SILC_SERVER_CH_JOIN_LIMIT);
94 #undef SET_PARAM_DEFAULT
97 /* Find connection parameters by the parameter block name. */
98 static SilcServerConfigConnParams *
99 my_find_param(SilcServerConfig config, const char *name)
101 SilcServerConfigConnParams *param;
103 for (param = config->conn_params; param; param = param->next) {
104 if (!strcasecmp(param->name, name))
108 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
109 "Cannot find Params \"%s\".", name));
114 /* SKR find callbcak */
116 static void my_find_callback(SilcSKR skr, SilcSKRFind find,
117 SilcSKRStatus status, SilcDList keys,
120 SilcSKRStatus *s = context;
124 silc_dlist_uninit(keys);
126 silc_skr_find_free(find);
129 /* parse an authdata according to its auth method */
130 static SilcBool my_parse_authdata(SilcAuthMethod auth_meth, const char *p,
131 void **auth_data, SilcUInt32 *auth_data_len,
132 SilcSKRKeyUsage usage, void *key_context)
134 if (auth_meth == SILC_AUTH_PASSWORD) {
135 /* p is a plain text password */
136 if (auth_data && auth_data_len) {
137 if (!silc_utf8_valid(p, strlen(p))) {
138 *auth_data_len = silc_utf8_encoded_len(p, strlen(p),
140 *auth_data = silc_calloc(*auth_data_len, sizeof(unsigned char));
141 silc_utf8_encode(p, strlen(p), SILC_STRING_LOCALE, *auth_data,
144 *auth_data = (void *) strdup(p);
145 *auth_data_len = (SilcUInt32) strlen(p);
148 } else if (auth_meth == SILC_AUTH_PUBLIC_KEY) {
149 /* p is a public key file name */
150 SilcPublicKey public_key;
151 SilcSKR skr = *auth_data;
153 SilcSKRStatus status = SILC_SKR_NOT_FOUND;
155 if (!silc_pkcs_load_public_key(p, &public_key)) {
156 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
157 "Could not load public key file!"));
161 find = silc_skr_find_alloc();
162 silc_skr_find_set_public_key(find, public_key);
163 silc_skr_find_set_usage(find, usage);
165 silc_skr_find_set_context(find, SILC_32_TO_PTR(usage));
166 silc_skr_find(skr, NULL, find, my_find_callback, &status);
167 if (status == SILC_SKR_OK) {
168 /* Already added, ignore error */
169 silc_pkcs_public_key_free(public_key);
173 /* Add the public key to repository */
174 status = silc_skr_add_public_key(skr, public_key, usage,
175 key_context ? key_context :
176 (void *)usage, NULL);
177 if (status != SILC_SKR_OK) {
178 SILC_SERVER_LOG_ERROR(("Error while adding public key \"%s\"", p));
186 static SilcBool my_parse_publickeydir(const char *dirname, void **auth_data,
187 SilcSKRKeyUsage usage)
190 struct dirent *get_file;
193 if (!(dp = opendir(dirname))) {
194 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
195 "Could not open directory \"%s\"", dirname));
199 /* errors are not considered fatal */
200 while ((get_file = readdir(dp))) {
201 const char *filename = get_file->d_name;
203 int dirname_len = strlen(dirname), filename_len = strlen(filename);
204 struct stat check_file;
206 /* Ignore "." and "..", and take files only with ".pub" suffix. */
207 if (!strcmp(filename, ".") || !strcmp(filename, "..") ||
208 (filename_len < 5) || strcmp(filename + filename_len - 4, ".pub"))
211 memset(buf, 0, sizeof(buf));
212 snprintf(buf, sizeof(buf) - 1, "%s%s%s", dirname,
213 (dirname[dirname_len - 1] == '/' ? "" : "/"), filename);
215 if (stat(buf, &check_file) < 0) {
216 SILC_SERVER_LOG_ERROR(("Error stating file %s: %s", buf,
218 } else if (S_ISREG(check_file.st_mode)) {
219 my_parse_authdata(SILC_AUTH_PUBLIC_KEY, buf, auth_data, NULL,
225 SILC_LOG_DEBUG(("Tried to load %d public keys in \"%s\"", total, dirname));
231 SILC_CONFIG_CALLBACK(fetch_generic)
233 SilcServerConfig config = (SilcServerConfig) context;
236 if (!strcmp(name, "module_path")) {
237 CONFIG_IS_DOUBLE(config->module_path);
238 config->module_path = (*(char *)val ? strdup((char *) val) : NULL);
240 else if (!strcmp(name, "prefer_passphrase_auth")) {
241 config->prefer_passphrase_auth = *(SilcBool *)val;
243 else if (!strcmp(name, "require_reverse_lookup")) {
244 config->require_reverse_lookup = *(SilcBool *)val;
246 else if (!strcmp(name, "connections_max")) {
247 config->param.connections_max = (SilcUInt32) *(int *)val;
249 else if (!strcmp(name, "connections_max_per_host")) {
250 config->param.connections_max_per_host = (SilcUInt32) *(int *)val;
252 else if (!strcmp(name, "keepalive_secs")) {
253 config->param.keepalive_secs = (SilcUInt32) *(int *)val;
255 else if (!strcmp(name, "reconnect_count")) {
256 config->param.reconnect_count = (SilcUInt32) *(int *)val;
258 else if (!strcmp(name, "reconnect_interval")) {
259 config->param.reconnect_interval = (SilcUInt32) *(int *)val;
261 else if (!strcmp(name, "reconnect_interval_max")) {
262 config->param.reconnect_interval_max = (SilcUInt32) *(int *)val;
264 else if (!strcmp(name, "reconnect_keep_trying")) {
265 config->param.reconnect_keep_trying = *(SilcBool *)val;
267 else if (!strcmp(name, "key_exchange_rekey")) {
268 config->param.key_exchange_rekey = (SilcUInt32) *(int *)val;
270 else if (!strcmp(name, "key_exchange_pfs")) {
271 config->param.key_exchange_pfs = *(SilcBool *)val;
273 else if (!strcmp(name, "channel_rekey_secs")) {
274 config->channel_rekey_secs = (SilcUInt32) *(int *)val;
276 else if (!strcmp(name, "key_exchange_timeout")) {
277 config->key_exchange_timeout = (SilcUInt32) *(int *)val;
279 else if (!strcmp(name, "conn_auth_timeout")) {
280 config->conn_auth_timeout = (SilcUInt32) *(int *)val;
282 else if (!strcmp(name, "version_protocol")) {
283 CONFIG_IS_DOUBLE(config->param.version_protocol);
284 config->param.version_protocol =
285 (*(char *)val ? strdup((char *) val) : NULL);
287 else if (!strcmp(name, "version_software")) {
288 CONFIG_IS_DOUBLE(config->param.version_software);
289 config->param.version_software =
290 (*(char *)val ? strdup((char *) val) : NULL);
292 else if (!strcmp(name, "version_software_vendor")) {
293 CONFIG_IS_DOUBLE(config->param.version_software_vendor);;
294 config->param.version_software_vendor =
295 (*(char *)val ? strdup((char *) val) : NULL);
297 else if (!strcmp(name, "detach_disabled")) {
298 config->detach_disabled = *(SilcBool *)val;
300 else if (!strcmp(name, "detach_timeout")) {
301 config->detach_timeout = (SilcUInt32) *(int *)val;
303 else if (!strcmp(name, "qos")) {
304 config->param.qos = *(SilcBool *)val;
306 else if (!strcmp(name, "qos_rate_limit")) {
307 config->param.qos_rate_limit = *(SilcUInt32 *)val;
309 else if (!strcmp(name, "qos_bytes_limit")) {
310 config->param.qos_bytes_limit = *(SilcUInt32 *)val;
312 else if (!strcmp(name, "qos_limit_sec")) {
313 config->param.qos_limit_sec = *(SilcUInt32 *)val;
315 else if (!strcmp(name, "qos_limit_usec")) {
316 config->param.qos_limit_usec = *(SilcUInt32 *)val;
318 else if (!strcmp(name, "channel_join_limit")) {
319 config->param.chlimit = *(SilcUInt32 *)val;
321 else if (!strcmp(name, "debug_string")) {
322 CONFIG_IS_DOUBLE(config->debug_string);
323 config->debug_string = (*(char *)val ? strdup((char *) val) : NULL);
325 else if (!strcmp(name, "http_server")) {
326 config->httpd = *(SilcBool *)val;
328 else if (!strcmp(name, "http_server_ip")) {
329 CONFIG_IS_DOUBLE(config->httpd_ip);
330 config->httpd_ip = (*(char *)val ? strdup((char *) val) : NULL);
332 else if (!strcmp(name, "http_server_port")) {
333 int port = *(int *)val;
334 if ((port <= 0) || (port > 65535)) {
335 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
336 "Invalid port number!"));
337 got_errno = SILC_CONFIG_EPRINTLINE;
340 config->httpd_port = (SilcUInt16)port;
342 else if (!strcmp(name, "dynamic_server")) {
343 config->dynamic_server = *(SilcBool *)val;
345 else if (!strcmp(name, "local_channels")) {
346 config->local_channels = *(SilcBool *)val;
349 return SILC_CONFIG_EINTERNAL;
351 return SILC_CONFIG_OK;
357 SILC_CONFIG_CALLBACK(fetch_cipher)
359 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigCipher);
361 SERVER_CONFIG_DEBUG(("Received CIPHER type=%d name=\"%s\" (val=%x)",
362 type, name, context));
363 if (type == SILC_CONFIG_ARG_BLOCK) {
364 /* check the temporary struct's fields */
365 if (!tmp) /* discard empty sub-blocks */
366 return SILC_CONFIG_OK;
368 got_errno = SILC_CONFIG_EMISSFIELDS;
372 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->cipher);
374 return SILC_CONFIG_OK;
376 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigCipher);
378 /* Identify and save this value */
379 if (!strcmp(name, "name")) {
380 CONFIG_IS_DOUBLE(tmp->name);
381 tmp->name = strdup((char *) val);
383 else if (!strcmp(name, "module")) {
384 CONFIG_IS_DOUBLE(tmp->module);
385 tmp->module = (*(char *)val ? strdup((char *) val) : NULL);
387 else if (!strcmp(name, "keylength")) {
388 tmp->key_length = *(SilcUInt32 *)val;
390 else if (!strcmp(name, "blocklength")) {
391 tmp->block_length = *(SilcUInt32 *)val;
394 return SILC_CONFIG_EINTERNAL;
395 return SILC_CONFIG_OK;
398 silc_free(tmp->name);
399 silc_free(tmp->module);
405 SILC_CONFIG_CALLBACK(fetch_hash)
407 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigHash);
409 SERVER_CONFIG_DEBUG(("Received HASH type=%d name=%s (val=%x)",
410 type, name, context));
411 if (type == SILC_CONFIG_ARG_BLOCK) {
412 /* check the temporary struct's fields */
413 if (!tmp) /* discard empty sub-blocks */
414 return SILC_CONFIG_OK;
415 if (!tmp->name || (tmp->block_length == 0) || (tmp->digest_length == 0)) {
416 got_errno = SILC_CONFIG_EMISSFIELDS;
420 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hash);
422 return SILC_CONFIG_OK;
424 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigHash);
426 /* Identify and save this value */
427 if (!strcmp(name, "name")) {
428 CONFIG_IS_DOUBLE(tmp->name);
429 tmp->name = strdup((char *) val);
431 else if (!strcmp(name, "module")) {
432 CONFIG_IS_DOUBLE(tmp->module);
433 tmp->module = (*(char *)val ? strdup((char *) val) : NULL);
435 else if (!strcmp(name, "blocklength")) {
436 tmp->block_length = *(int *)val;
438 else if (!strcmp(name, "digestlength")) {
439 tmp->digest_length = *(int *)val;
442 return SILC_CONFIG_EINTERNAL;
443 return SILC_CONFIG_OK;
446 silc_free(tmp->name);
447 silc_free(tmp->module);
453 SILC_CONFIG_CALLBACK(fetch_hmac)
455 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigHmac);
457 SERVER_CONFIG_DEBUG(("Received HMAC type=%d name=\"%s\" (val=%x)",
458 type, name, context));
459 if (type == SILC_CONFIG_ARG_BLOCK) {
460 /* check the temporary struct's fields */
461 if (!tmp) /* discard empty sub-blocks */
462 return SILC_CONFIG_OK;
463 if (!tmp->name || !tmp->hash || (tmp->mac_length == 0)) {
464 got_errno = SILC_CONFIG_EMISSFIELDS;
468 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hmac);
470 return SILC_CONFIG_OK;
472 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigHmac);
474 /* Identify and save this value */
475 if (!strcmp(name, "name")) {
476 CONFIG_IS_DOUBLE(tmp->name);
477 tmp->name = strdup((char *) val);
479 else if (!strcmp(name, "hash")) {
480 CONFIG_IS_DOUBLE(tmp->hash);
481 tmp->hash = strdup((char *) val);
483 else if (!strcmp(name, "maclength")) {
484 tmp->mac_length = *(int *)val;
487 return SILC_CONFIG_EINTERNAL;
488 return SILC_CONFIG_OK;
491 silc_free(tmp->name);
492 silc_free(tmp->hash);
498 SILC_CONFIG_CALLBACK(fetch_pkcs)
500 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigPkcs);
502 SERVER_CONFIG_DEBUG(("Received PKCS type=%d name=\"%s\" (val=%x)",
503 type, name, context));
504 if (type == SILC_CONFIG_ARG_BLOCK) {
505 /* Check the temporary struct's fields */
506 if (!tmp) /* discard empty sub-blocks */
507 return SILC_CONFIG_OK;
509 got_errno = SILC_CONFIG_EMISSFIELDS;
513 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->pkcs);
515 return SILC_CONFIG_OK;
517 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigPkcs);
519 /* Identify and save this value */
520 if (!strcmp(name, "name")) {
521 CONFIG_IS_DOUBLE(tmp->name);
522 tmp->name = strdup((char *) val);
525 return SILC_CONFIG_EINTERNAL;
526 return SILC_CONFIG_OK;
529 silc_free(tmp->name);
535 SILC_CONFIG_CALLBACK(fetch_serverinfo)
537 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServerInfoInterface);
538 SilcServerConfigServerInfo *server_info = config->server_info;
540 SERVER_CONFIG_DEBUG(("Received SERVERINFO type=%d name=\"%s\" (val=%x)",
541 type, name, context));
543 /* If there isn't the main struct alloc it */
545 config->server_info = server_info = (SilcServerConfigServerInfo *)
546 silc_calloc(1, sizeof(*server_info));
548 if (type == SILC_CONFIG_ARG_BLOCK) {
549 if (!strcmp(name, "primary")) {
550 if (server_info->primary) {
551 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
552 "Double primary specification."));
553 got_errno = SILC_CONFIG_EPRINTLINE;
556 CONFIG_IS_DOUBLE(server_info->primary);
558 /* now check the temporary struct, don't accept empty block and
559 make sure all fields are there */
560 if (!tmp || !tmp->server_ip || !tmp->port) {
561 got_errno = SILC_CONFIG_EMISSFIELDS;
564 server_info->primary = tmp;
566 return SILC_CONFIG_OK;
567 } else if (!strcmp(name, "secondary")) {
569 return SILC_CONFIG_OK;
570 if (!tmp || !tmp->server_ip || !tmp->port) {
571 got_errno = SILC_CONFIG_EMISSFIELDS;
574 SILC_SERVER_CONFIG_LIST_APPENDTMP(server_info->secondary);
576 return SILC_CONFIG_OK;
577 } else if (!server_info->public_key || !server_info->private_key) {
578 got_errno = SILC_CONFIG_EMISSFIELDS;
581 return SILC_CONFIG_OK;
583 if (!strcmp(name, "hostname")) {
584 CONFIG_IS_DOUBLE(server_info->server_name);
585 server_info->server_name = strdup((char *) val);
587 else if (!strcmp(name, "ip")) {
588 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
589 CONFIG_IS_DOUBLE(tmp->server_ip);
590 tmp->server_ip = strdup((char *) val);
592 else if (!strcmp(name, "public_ip")) {
593 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
594 CONFIG_IS_DOUBLE(tmp->public_ip);
595 tmp->public_ip = strdup((char *) val);
597 else if (!strcmp(name, "port")) {
598 int port = *(int *)val;
599 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
600 if ((port <= 0) || (port > 65535)) {
601 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
602 "Invalid port number!"));
603 got_errno = SILC_CONFIG_EPRINTLINE;
606 tmp->port = (SilcUInt16) port;
608 else if (!strcmp(name, "servertype")) {
609 CONFIG_IS_DOUBLE(server_info->server_type);
610 server_info->server_type = strdup((char *) val);
612 else if (!strcmp(name, "admin")) {
613 CONFIG_IS_DOUBLE(server_info->admin);
614 server_info->admin = strdup((char *) val);
616 else if (!strcmp(name, "adminemail")) {
617 CONFIG_IS_DOUBLE(server_info->email);
618 server_info->email = strdup((char *) val);
620 else if (!strcmp(name, "location")) {
621 CONFIG_IS_DOUBLE(server_info->location);
622 server_info->location = strdup((char *) val);
624 else if (!strcmp(name, "user")) {
625 CONFIG_IS_DOUBLE(server_info->user);
626 server_info->user = strdup((char *) val);
628 else if (!strcmp(name, "group")) {
629 CONFIG_IS_DOUBLE(server_info->group);
630 server_info->group = strdup((char *) val);
632 else if (!strcmp(name, "motdfile")) {
633 CONFIG_IS_DOUBLE(server_info->motd_file);
634 server_info->motd_file = strdup((char *) val);
636 else if (!strcmp(name, "pidfile")) {
637 CONFIG_IS_DOUBLE(server_info->pid_file);
638 server_info->pid_file = strdup((char *) val);
640 else if (!strcmp(name, "publickey")) {
641 char *file_tmp = (char *) val;
642 CONFIG_IS_DOUBLE(server_info->public_key);
644 /* Try to load specified file, if fail stop config parsing */
645 if (!silc_pkcs_load_public_key(file_tmp, &server_info->public_key)) {
646 SILC_SERVER_LOG_ERROR(("Error: Could not load public key file."));
647 return SILC_CONFIG_EPRINTLINE;
650 else if (!strcmp(name, "privatekey")) {
652 char *file_tmp = (char *) val;
653 CONFIG_IS_DOUBLE(server_info->private_key);
655 /* Check the private key file permissions. */
656 if ((stat(file_tmp, &st)) != -1) {
657 if ((st.st_mode & 0777) != 0600) {
658 SILC_SERVER_LOG_ERROR(("Wrong permissions in private key "
659 "file \"%s\". The permissions must be "
661 return SILC_CONFIG_ESILENT;
665 /* Try to load specified file, if fail stop config parsing */
666 if (!silc_pkcs_load_private_key(file_tmp, "", 0,
667 &server_info->private_key)) {
668 SILC_SERVER_LOG_ERROR(("Error: Could not load private key file."));
669 return SILC_CONFIG_EPRINTLINE;
673 return SILC_CONFIG_EINTERNAL;
674 return SILC_CONFIG_OK;
677 /* Here we need to check if tmp exists because this function handles
678 * misc data (multiple fields and single-only fields) */
680 silc_free(tmp->server_ip);
687 SILC_CONFIG_CALLBACK(fetch_logging)
689 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigLogging);
691 if (!strcmp(name, "timestamp")) {
692 config->logging_timestamp = *(SilcBool *)val;
694 else if (!strcmp(name, "quicklogs")) {
695 config->logging_quick = *(SilcBool *)val;
697 else if (!strcmp(name, "flushdelay")) {
698 int flushdelay = *(int *)val;
699 if (flushdelay < 2) { /* this value was taken from silclog.h (min delay) */
700 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
701 "Invalid flushdelay value, use quicklogs if you "
702 "want real-time logging."));
703 return SILC_CONFIG_EPRINTLINE;
705 config->logging_flushdelay = (long) flushdelay;
708 /* The following istances happens only in Logging's sub-blocks, a match
709 for the sub-block name means that you should store the filename/maxsize
710 temporary struct to the proper logging channel.
711 If we get a match for "file" or "maxsize" this means that we are inside
712 a sub-sub-block and it is safe to alloc a new tmp. */
713 #define FETCH_LOGGING_CHAN(__chan__, __member__) \
714 else if (!strcmp(name, __chan__)) { \
715 if (!tmp) return SILC_CONFIG_OK; \
717 got_errno = SILC_CONFIG_EMISSFIELDS; goto got_err; \
719 config->__member__ = tmp; \
720 config->tmp = NULL; \
722 FETCH_LOGGING_CHAN("info", logging_info)
723 FETCH_LOGGING_CHAN("warnings", logging_warnings)
724 FETCH_LOGGING_CHAN("errors", logging_errors)
725 FETCH_LOGGING_CHAN("fatals", logging_fatals)
726 #undef FETCH_LOGGING_CHAN
727 else if (!strcmp(name, "file")) {
728 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigLogging);
729 CONFIG_IS_DOUBLE(tmp->file);
730 tmp->file = strdup((char *) val);
732 else if (!strcmp(name, "size")) {
734 config->tmp = silc_calloc(1, sizeof(*tmp));
735 tmp = (SilcServerConfigLogging *) config->tmp;
737 tmp->maxsize = *(SilcUInt32 *) val;
740 return SILC_CONFIG_EINTERNAL;
741 return SILC_CONFIG_OK;
744 silc_free(tmp->file);
750 SILC_CONFIG_CALLBACK(fetch_connparam)
752 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigConnParams);
754 SERVER_CONFIG_DEBUG(("Received CONNPARAM type=%d name=\"%s\" (val=%x)",
755 type, name, context));
756 if (type == SILC_CONFIG_ARG_BLOCK) {
757 /* check the temporary struct's fields */
758 if (!tmp) /* discard empty sub-blocks */
759 return SILC_CONFIG_OK;
761 got_errno = SILC_CONFIG_EMISSFIELDS;
765 my_set_param_defaults(tmp, &config->param);
767 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->conn_params);
769 return SILC_CONFIG_OK;
772 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigConnParams);
773 tmp->reconnect_keep_trying = TRUE;
776 if (!strcmp(name, "name")) {
777 CONFIG_IS_DOUBLE(tmp->name);
778 tmp->name = (*(char *)val ? strdup((char *) val) : NULL);
780 else if (!strcmp(name, "connections_max")) {
781 tmp->connections_max = *(SilcUInt32 *)val;
783 else if (!strcmp(name, "connections_max_per_host")) {
784 tmp->connections_max_per_host = *(SilcUInt32 *)val;
786 else if (!strcmp(name, "keepalive_secs")) {
787 tmp->keepalive_secs = *(SilcUInt32 *)val;
789 else if (!strcmp(name, "reconnect_count")) {
790 tmp->reconnect_count = *(SilcUInt32 *)val;
792 else if (!strcmp(name, "reconnect_interval")) {
793 tmp->reconnect_interval = *(SilcUInt32 *)val;
795 else if (!strcmp(name, "reconnect_interval_max")) {
796 tmp->reconnect_interval_max = *(SilcUInt32 *)val;
798 else if (!strcmp(name, "reconnect_keep_trying")) {
799 tmp->reconnect_keep_trying = *(SilcBool *)val;
801 else if (!strcmp(name, "key_exchange_rekey")) {
802 tmp->key_exchange_rekey = *(SilcUInt32 *)val;
804 else if (!strcmp(name, "key_exchange_pfs")) {
805 tmp->key_exchange_pfs = *(SilcBool *)val;
807 else if (!strcmp(name, "version_protocol")) {
808 CONFIG_IS_DOUBLE(tmp->version_protocol);
809 tmp->version_protocol = (*(char *)val ? strdup((char *) val) : NULL);
811 else if (!strcmp(name, "version_software")) {
812 CONFIG_IS_DOUBLE(tmp->version_software);
813 tmp->version_software = (*(char *)val ? strdup((char *) val) : NULL);
815 else if (!strcmp(name, "version_software_vendor")) {
816 CONFIG_IS_DOUBLE(tmp->version_software_vendor);;
817 tmp->version_software_vendor =
818 (*(char *)val ? strdup((char *) val) : NULL);
820 else if (!strcmp(name, "anonymous")) {
821 tmp->anonymous = *(SilcBool *)val;
823 else if (!strcmp(name, "qos")) {
824 tmp->qos = *(SilcBool *)val;
826 else if (!strcmp(name, "qos_rate_limit")) {
827 tmp->qos_rate_limit = *(SilcUInt32 *)val;
829 else if (!strcmp(name, "qos_bytes_limit")) {
830 tmp->qos_bytes_limit = *(SilcUInt32 *)val;
832 else if (!strcmp(name, "qos_limit_sec")) {
833 tmp->qos_limit_sec = *(SilcUInt32 *)val;
835 else if (!strcmp(name, "qos_limit_usec")) {
836 tmp->qos_limit_usec = *(SilcUInt32 *)val;
839 return SILC_CONFIG_EINTERNAL;
841 return SILC_CONFIG_OK;
844 silc_free(tmp->name);
850 SILC_CONFIG_CALLBACK(fetch_client)
852 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigClient);
854 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
855 type, name, context));
857 /* Alloc before block checking, because empty sub-blocks are welcome here */
858 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigClient);
860 if (type == SILC_CONFIG_ARG_BLOCK) {
861 /* empty sub-blocks are welcome */
862 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->clients);
864 return SILC_CONFIG_OK;
867 /* Identify and save this value */
868 if (!strcmp(name, "host")) {
869 CONFIG_IS_DOUBLE(tmp->host);
870 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
872 else if (!strcmp(name, "passphrase")) {
873 CONFIG_IS_DOUBLE(tmp->passphrase);
874 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
875 (void *)&tmp->passphrase,
876 &tmp->passphrase_len, 0, NULL)) {
877 got_errno = SILC_CONFIG_EPRINTLINE;
881 else if (!strcmp(name, "publickey")) {
882 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
883 (void *)&config->server->repository, NULL,
884 SILC_SKR_USAGE_KEY_AGREEMENT, NULL)) {
885 got_errno = SILC_CONFIG_EPRINTLINE;
889 else if (!strcmp(name, "publickeydir")) {
890 if (!my_parse_publickeydir((char *) val,
891 (void *)&config->server->repository,
892 SILC_SKR_USAGE_KEY_AGREEMENT)) {
893 got_errno = SILC_CONFIG_EPRINTLINE;
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;
965 return SILC_CONFIG_EINTERNAL;
966 return SILC_CONFIG_OK;
969 silc_free(tmp->host);
970 silc_free(tmp->user);
971 silc_free(tmp->nick);
972 CONFIG_FREE_AUTH(tmp);
978 SILC_CONFIG_CALLBACK(fetch_deny)
980 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigDeny);
982 SERVER_CONFIG_DEBUG(("Received DENY type=%d name=\"%s\" (val=%x)",
983 type, name, context));
984 if (type == SILC_CONFIG_ARG_BLOCK) {
985 /* check the temporary struct's fields */
986 if (!tmp) /* discard empty sub-blocks */
987 return SILC_CONFIG_OK;
989 got_errno = SILC_CONFIG_EMISSFIELDS;
993 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->denied);
995 return SILC_CONFIG_OK;
997 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigDeny);
999 /* Identify and save this value */
1000 if (!strcmp(name, "host")) {
1001 CONFIG_IS_DOUBLE(tmp->host);
1002 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
1004 else if (!strcmp(name, "reason")) {
1005 CONFIG_IS_DOUBLE(tmp->reason);
1006 tmp->reason = strdup((char *) val);
1009 return SILC_CONFIG_EINTERNAL;
1010 return SILC_CONFIG_OK;
1013 silc_free(tmp->host);
1014 silc_free(tmp->reason);
1020 SILC_CONFIG_CALLBACK(fetch_server)
1022 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServer);
1024 SERVER_CONFIG_DEBUG(("Received SERVER type=%d name=\"%s\" (val=%x)",
1025 type, name, context));
1026 if (type == SILC_CONFIG_ARG_BLOCK) {
1027 /* check the temporary struct's fields */
1028 if (!tmp) /* discard empty sub-blocks */
1029 return SILC_CONFIG_OK;
1031 got_errno = SILC_CONFIG_EMISSFIELDS;
1035 /* the temporary struct is ok, append it to the list */
1036 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->servers);
1038 return SILC_CONFIG_OK;
1040 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServer);
1042 /* Identify and save this value */
1043 if (!strcmp(name, "host")) {
1044 CONFIG_IS_DOUBLE(tmp->host);
1045 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
1047 else if (!strcmp(name, "passphrase")) {
1048 CONFIG_IS_DOUBLE(tmp->passphrase);
1049 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
1050 (void *)&tmp->passphrase,
1051 &tmp->passphrase_len, 0, NULL)) {
1052 got_errno = SILC_CONFIG_EPRINTLINE;
1056 else if (!strcmp(name, "publickey")) {
1057 CONFIG_IS_DOUBLE(tmp->publickeys);
1058 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
1059 (void *)&config->server->repository, NULL,
1060 SILC_SKR_USAGE_KEY_AGREEMENT, NULL)) {
1061 got_errno = SILC_CONFIG_EPRINTLINE;
1065 else if (!strcmp(name, "params")) {
1066 CONFIG_IS_DOUBLE(tmp->param);
1067 tmp->param = my_find_param(config, (char *) val);
1068 if (!tmp->param) { /* error message already output */
1069 got_errno = SILC_CONFIG_EPRINTLINE;
1073 else if (!strcmp(name, "backup")) {
1074 tmp->backup_router = *(SilcBool *)val;
1077 return SILC_CONFIG_EINTERNAL;
1079 return SILC_CONFIG_OK;
1082 silc_free(tmp->host);
1083 CONFIG_FREE_AUTH(tmp);
1089 SILC_CONFIG_CALLBACK(fetch_router)
1091 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigRouter);
1093 SERVER_CONFIG_DEBUG(("Received ROUTER type=%d name=\"%s\" (val=%x)",
1094 type, name, context));
1095 if (type == SILC_CONFIG_ARG_BLOCK) {
1096 if (!tmp) /* discard empty sub-blocks */
1097 return SILC_CONFIG_OK;
1099 got_errno = SILC_CONFIG_EMISSFIELDS;
1103 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->routers);
1105 return SILC_CONFIG_OK;
1107 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigRouter);
1109 /* Identify and save this value */
1110 if (!strcmp(name, "host")) {
1111 CONFIG_IS_DOUBLE(tmp->host);
1112 tmp->host = strdup((char *) val);
1114 else if (!strcmp(name, "port")) {
1115 int port = *(int *)val;
1116 if ((port <= 0) || (port > 65535)) {
1117 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
1118 "Invalid port number!"));
1119 got_errno = SILC_CONFIG_EPRINTLINE;
1122 tmp->port = (SilcUInt16) port;
1124 else if (!strcmp(name, "passphrase")) {
1125 CONFIG_IS_DOUBLE(tmp->passphrase);
1126 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
1127 (void *)&tmp->passphrase,
1128 &tmp->passphrase_len, 0, NULL)) {
1129 got_errno = SILC_CONFIG_EPRINTLINE;
1133 else if (!strcmp(name, "publickey")) {
1134 CONFIG_IS_DOUBLE(tmp->publickeys);
1135 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
1136 (void *)&config->server->repository, NULL,
1137 SILC_SKR_USAGE_KEY_AGREEMENT, NULL)) {
1138 got_errno = SILC_CONFIG_EPRINTLINE;
1142 else if (!strcmp(name, "params")) {
1143 CONFIG_IS_DOUBLE(tmp->param);
1144 tmp->param = my_find_param(config, (char *) val);
1145 if (!tmp->param) { /* error message already output */
1146 got_errno = SILC_CONFIG_EPRINTLINE;
1150 else if (!strcmp(name, "initiator")) {
1151 tmp->initiator = *(SilcBool *)val;
1153 else if (!strcmp(name, "backuphost")) {
1154 CONFIG_IS_DOUBLE(tmp->backup_replace_ip);
1155 tmp->backup_replace_ip = (*(char *)val ? strdup((char *) val) :
1157 tmp->backup_router = TRUE;
1159 else if (!strcmp(name, "backupport")) {
1160 int port = *(int *)val;
1161 if ((port <= 0) || (port > 65535)) {
1162 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
1163 "Invalid port number!"));
1164 got_errno = SILC_CONFIG_EPRINTLINE;
1167 tmp->backup_replace_port = (SilcUInt16) port;
1169 else if (!strcmp(name, "backuplocal")) {
1170 tmp->backup_local = *(SilcBool *)val;
1172 else if (!strcmp(name, "dynamic_connection")) {
1173 tmp->dynamic_connection = *(SilcBool *)val;
1176 return SILC_CONFIG_EINTERNAL;
1178 return SILC_CONFIG_OK;
1181 silc_free(tmp->host);
1182 silc_free(tmp->backup_replace_ip);
1183 CONFIG_FREE_AUTH(tmp);
1189 /* known config options tables */
1190 static const SilcConfigTable table_general[] = {
1191 { "module_path", SILC_CONFIG_ARG_STRE, fetch_generic, NULL },
1192 { "prefer_passphrase_auth", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1193 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1194 { "connections_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1195 { "connections_max_per_host", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1196 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1197 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1198 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1199 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1200 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1201 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1202 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1203 { "channel_rekey_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1204 { "key_exchange_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1205 { "conn_auth_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1206 { "version_protocol", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1207 { "version_software", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1208 { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1209 { "detach_disabled", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1210 { "detach_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1211 { "qos", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1212 { "qos_rate_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1213 { "qos_bytes_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1214 { "qos_limit_sec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1215 { "qos_limit_usec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1216 { "channel_join_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1217 { "debug_string", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1218 { "http_server", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1219 { "http_server_ip", SILC_CONFIG_ARG_STRE, fetch_generic, NULL },
1220 { "http_server_port", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1221 { "dynamic_server", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1222 { "local_channels", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1226 static const SilcConfigTable table_cipher[] = {
1227 { "name", SILC_CONFIG_ARG_STR, fetch_cipher, NULL },
1228 { "module", SILC_CONFIG_ARG_STRE, fetch_cipher, NULL },
1229 { "keylength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1230 { "blocklength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1234 static const SilcConfigTable table_hash[] = {
1235 { "name", SILC_CONFIG_ARG_STR, fetch_hash, NULL },
1236 { "module", SILC_CONFIG_ARG_STRE, fetch_hash, NULL },
1237 { "blocklength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1238 { "digestlength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1242 static const SilcConfigTable table_hmac[] = {
1243 { "name", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1244 { "hash", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1245 { "maclength", SILC_CONFIG_ARG_INT, fetch_hmac, NULL },
1249 static const SilcConfigTable table_pkcs[] = {
1250 { "name", SILC_CONFIG_ARG_STR, fetch_pkcs, NULL },
1254 static const SilcConfigTable table_serverinfo_c[] = {
1255 { "ip", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1256 { "public_ip", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1257 { "port", SILC_CONFIG_ARG_INT, fetch_serverinfo, NULL},
1261 static const SilcConfigTable table_serverinfo[] = {
1262 { "hostname", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1263 { "primary", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo_c},
1264 { "secondary", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo_c},
1265 { "servertype", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1266 { "location", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1267 { "admin", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1268 { "adminemail", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1269 { "user", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1270 { "group", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1271 { "publickey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1272 { "privatekey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1273 { "motdfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1274 { "pidfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1278 static const SilcConfigTable table_logging_c[] = {
1279 { "file", SILC_CONFIG_ARG_STR, fetch_logging, NULL },
1280 { "size", SILC_CONFIG_ARG_SIZE, fetch_logging, NULL },
1281 /*{ "quicklog", SILC_CONFIG_ARG_NONE, fetch_logging, NULL }, */
1285 static const SilcConfigTable table_logging[] = {
1286 { "timestamp", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1287 { "quicklogs", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1288 { "flushdelay", SILC_CONFIG_ARG_INT, fetch_logging, NULL },
1289 { "info", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1290 { "warnings", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1291 { "errors", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1292 { "fatals", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1296 static const SilcConfigTable table_connparam[] = {
1297 { "name", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1298 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1299 { "connections_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1300 { "connections_max_per_host",SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1301 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1302 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1303 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1304 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1305 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1306 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1307 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1308 { "version_protocol", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1309 { "version_software", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1310 { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1311 { "anonymous", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1312 { "qos", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1313 { "qos_rate_limit", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1314 { "qos_bytes_limit", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1315 { "qos_limit_sec", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1316 { "qos_limit_usec", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1320 static const SilcConfigTable table_client[] = {
1321 { "host", SILC_CONFIG_ARG_STRE, fetch_client, NULL },
1322 { "passphrase", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1323 { "publickey", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1324 { "publickeydir", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1325 { "params", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1329 static const SilcConfigTable table_admin[] = {
1330 { "host", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1331 { "user", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1332 { "nick", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1333 { "passphrase", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1334 { "publickey", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1335 { "port", SILC_CONFIG_ARG_INT, fetch_admin, NULL },
1336 { "params", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1340 static const SilcConfigTable table_deny[] = {
1341 { "host", SILC_CONFIG_ARG_STRE, fetch_deny, NULL },
1342 { "reason", SILC_CONFIG_ARG_STR, fetch_deny, NULL },
1346 static const SilcConfigTable table_serverconn[] = {
1347 { "host", SILC_CONFIG_ARG_STRE, fetch_server, NULL },
1348 { "passphrase", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1349 { "publickey", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1350 { "params", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1351 { "backup", SILC_CONFIG_ARG_TOGGLE, fetch_server, NULL },
1355 static const SilcConfigTable table_routerconn[] = {
1356 { "host", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1357 { "port", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1358 { "passphrase", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1359 { "publickey", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1360 { "params", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1361 { "initiator", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1362 { "backuphost", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1363 { "backupport", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1364 { "backuplocal", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1365 { "dynamic_connection", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1369 static const SilcConfigTable table_main[] = {
1370 { "cipher", SILC_CONFIG_ARG_BLOCK, fetch_cipher, table_cipher },
1371 { "hash", SILC_CONFIG_ARG_BLOCK, fetch_hash, table_hash },
1372 { "hmac", SILC_CONFIG_ARG_BLOCK, fetch_hmac, table_hmac },
1373 { "pkcs", SILC_CONFIG_ARG_BLOCK, fetch_pkcs, table_pkcs },
1374 { "general", SILC_CONFIG_ARG_BLOCK, NULL, table_general },
1375 { "serverinfo", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo },
1376 { "logging", SILC_CONFIG_ARG_BLOCK, NULL, table_logging },
1377 { "connectionparams", SILC_CONFIG_ARG_BLOCK, fetch_connparam, table_connparam },
1378 { "client", SILC_CONFIG_ARG_BLOCK, fetch_client, table_client },
1379 { "admin", SILC_CONFIG_ARG_BLOCK, fetch_admin, table_admin },
1380 { "deny", SILC_CONFIG_ARG_BLOCK, fetch_deny, table_deny },
1381 { "serverconnection", SILC_CONFIG_ARG_BLOCK, fetch_server, table_serverconn },
1382 { "routerconnection", SILC_CONFIG_ARG_BLOCK, fetch_router, table_routerconn },
1386 /* Set default values to stuff that was not configured. */
1388 static void silc_server_config_set_defaults(SilcServerConfig config)
1390 my_set_param_defaults(&config->param, NULL);
1392 config->channel_rekey_secs = (config->channel_rekey_secs ?
1393 config->channel_rekey_secs :
1394 SILC_SERVER_CHANNEL_REKEY);
1395 config->key_exchange_timeout = (config->key_exchange_timeout ?
1396 config->key_exchange_timeout :
1397 SILC_SERVER_SKE_TIMEOUT);
1398 config->conn_auth_timeout = (config->conn_auth_timeout ?
1399 config->conn_auth_timeout :
1400 SILC_SERVER_CONNAUTH_TIMEOUT);
1403 /* Check for correctness of the configuration */
1405 static SilcBool silc_server_config_check(SilcServerConfig config)
1407 SilcBool ret = TRUE;
1408 SilcServerConfigServer *s;
1409 SilcServerConfigRouter *r;
1412 /* ServerConfig is mandatory */
1413 if (!config->server_info) {
1414 SILC_SERVER_LOG_ERROR(("\nError: Missing mandatory block `ServerInfo'"));
1418 if (!config->server_info->public_key ||
1419 !config->server_info->private_key) {
1420 SILC_SERVER_LOG_ERROR(("\nError: Server keypair is missing"));
1424 if (!config->server_info->primary) {
1425 SILC_SERVER_LOG_ERROR(("\nError: Missing mandatory block `Primary' "
1426 "in `ServerInfo'"));
1430 if (!config->server_info->primary->server_ip) {
1431 SILC_SERVER_LOG_ERROR(("\nError: Missing mandatory field `Ip' "
1432 "in `Primary' in `ServerInfo'"));
1436 /* RouterConnection sanity checks */
1438 if (config->routers && config->routers->backup_router == TRUE &&
1440 SILC_SERVER_LOG_ERROR((
1441 "\nError: First RouterConnection block must be primary router "
1442 "connection. You have marked it incorrectly as backup router."));
1445 if (config->routers && config->routers->backup_router == TRUE &&
1446 !config->servers && !config->routers->next) {
1447 SILC_SERVER_LOG_ERROR((
1448 "\nError: You have configured backup router but not primary router. "
1449 "If backup router is configured also primary router must be "
1454 /* Backup router sanity checks */
1456 for (r = config->routers; r; r = r->next) {
1457 if (r->backup_router && !strcmp(r->host, r->backup_replace_ip)) {
1458 SILC_SERVER_LOG_ERROR((
1459 "\nError: Backup router connection incorrectly configured to use "
1460 "primary and backup router as same host `%s'. They must not be "
1461 "same host.", r->host));
1465 if (r->initiator == FALSE && r->port != 0) {
1466 SILC_SERVER_LOG_WARNING(("\nWarning: Initiator is FALSE and Port is "
1467 "specified. Ignoring Port value."));
1472 /* ServerConnection sanity checks */
1474 for (s = config->servers; s; s = s->next) {
1475 if (s->backup_router) {
1481 for (s = config->servers; s; s = s->next) {
1482 if (!s->backup_router) {
1483 SILC_SERVER_LOG_ERROR((
1484 "\nError: Your server is backup router but not all ServerConnection "
1485 "blocks were marked as backup connections. They all must be "
1486 "marked as backup connections."));
1496 /* Allocates a new configuration object, opens configuration file and
1497 parses it. The parsed data is returned to the newly allocated
1498 configuration object. The SilcServerConfig must be freed by calling
1499 the silc_server_config_destroy function. */
1501 SilcServerConfig silc_server_config_alloc(const char *filename,
1504 SilcServerConfig config_new;
1505 SilcConfigEntity ent;
1506 SilcConfigFile *file;
1508 SILC_LOG_DEBUG(("Loading config data from `%s'", filename));
1510 /* alloc a config object */
1511 config_new = silc_calloc(1, sizeof(*config_new));
1515 /* general config defaults */
1516 config_new->refcount = 1;
1517 config_new->logging_timestamp = TRUE;
1518 config_new->param.reconnect_keep_trying = TRUE;
1519 config_new->server = server;
1521 /* obtain a config file object */
1522 file = silc_config_open(filename);
1524 SILC_SERVER_LOG_ERROR(("\nError: can't open config file `%s'",
1529 /* obtain a SilcConfig entity, we can use it to start the parsing */
1530 ent = silc_config_init(file);
1532 /* load the known configuration options, give our empty object as context */
1533 silc_config_register_table(ent, table_main, (void *) config_new);
1535 /* enter the main parsing loop. When this returns, we have the parsing
1536 * result and the object filled (or partially, in case of errors). */
1537 ret = silc_config_main(ent);
1538 SILC_LOG_DEBUG(("Parser returned [ret=%d]: %s", ret,
1539 silc_config_strerror(ret)));
1541 /* Check if the parser returned errors */
1543 /* handle this special error return which asks to quietly return */
1544 if (ret != SILC_CONFIG_ESILENT) {
1545 char *linebuf, *filename = silc_config_get_filename(file);
1546 SilcUInt32 line = silc_config_get_line(file);
1547 if (ret != SILC_CONFIG_EPRINTLINE)
1548 SILC_SERVER_LOG_ERROR(("Error while parsing config file: %s.",
1549 silc_config_strerror(ret)));
1550 linebuf = silc_config_read_line(file, line);
1552 SILC_SERVER_LOG_ERROR((" file %s line %lu: %s\n", filename,
1557 silc_server_config_destroy(config_new);
1558 silc_config_close(file);
1562 /* close (destroy) the file object */
1563 silc_config_close(file);
1565 /* Check the configuration */
1566 if (!silc_server_config_check(config_new)) {
1567 silc_server_config_destroy(config_new);
1571 /* Set default to configuration parameters */
1572 silc_server_config_set_defaults(config_new);
1577 /* Increments the reference counter of a config object */
1579 void silc_server_config_ref(SilcServerConfigRef *ref, SilcServerConfig config,
1584 ref->config = config;
1585 ref->ref_ptr = ref_ptr;
1586 SILC_LOG_DEBUG(("Referencing config [%p] refcnt %d->%d", config,
1587 config->refcount - 1, config->refcount));
1591 /* Decrements the reference counter of a config object. If the counter
1592 reaches 0, the config object is destroyed. */
1594 void silc_server_config_unref(SilcServerConfigRef *ref)
1597 silc_server_config_destroy(ref->config);
1600 /* Destroy a config object with all his children lists */
1602 void silc_server_config_destroy(SilcServerConfig config)
1607 SILC_LOG_DEBUG(("Unreferencing config [%p] refcnt %d->%d", config,
1608 config->refcount + 1, config->refcount));
1609 if (config->refcount > 0)
1612 SILC_LOG_DEBUG(("Freeing config context"));
1614 /* Destroy general config stuff */
1615 silc_free(config->module_path);
1616 silc_free(config->debug_string);
1617 silc_free(config->param.version_protocol);
1618 silc_free(config->param.version_software);
1619 silc_free(config->param.version_software_vendor);
1620 silc_free(config->httpd_ip);
1622 /* Destroy Logging channels */
1623 if (config->logging_info)
1624 silc_free(config->logging_info->file);
1625 if (config->logging_warnings)
1626 silc_free(config->logging_warnings->file);
1627 if (config->logging_errors)
1628 silc_free(config->logging_errors->file);
1629 if (config->logging_fatals)
1630 silc_free(config->logging_fatals->file);
1631 silc_free(config->logging_info);
1632 silc_free(config->logging_warnings);
1633 silc_free(config->logging_errors);
1634 silc_free(config->logging_fatals);
1636 /* Destroy the ServerInfo struct */
1637 if (config->server_info) {
1638 register SilcServerConfigServerInfo *si = config->server_info;
1639 silc_free(si->server_name);
1641 silc_free(si->primary->server_ip);
1642 silc_free(si->primary);
1644 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServerInfoInterface,
1646 silc_free(di->server_ip);
1649 silc_free(si->server_type);
1650 silc_free(si->location);
1651 silc_free(si->admin);
1652 silc_free(si->email);
1653 silc_free(si->user);
1654 silc_free(si->group);
1655 silc_free(si->motd_file);
1656 silc_free(si->pid_file);
1658 silc_pkcs_public_key_free(si->public_key);
1659 if (si->private_key)
1660 silc_pkcs_private_key_free(si->private_key);
1664 /* Now let's destroy the lists */
1666 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigCipher,
1668 silc_free(di->name);
1669 silc_free(di->module);
1672 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHash, config->hash)
1673 silc_free(di->name);
1674 silc_free(di->module);
1677 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHmac, config->hmac)
1678 silc_free(di->name);
1679 silc_free(di->hash);
1682 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigPkcs, config->pkcs)
1683 silc_free(di->name);
1686 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigConnParams,
1687 config->conn_params)
1688 silc_free(di->name);
1689 silc_free(di->version_protocol);
1690 silc_free(di->version_software);
1691 silc_free(di->version_software_vendor);
1694 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigClient, config->clients)
1695 silc_free(di->host);
1696 CONFIG_FREE_AUTH(di);
1699 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigAdmin, config->admins)
1700 silc_free(di->host);
1701 silc_free(di->user);
1702 silc_free(di->nick);
1703 CONFIG_FREE_AUTH(di);
1706 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigDeny, config->denied)
1707 silc_free(di->host);
1708 silc_free(di->reason);
1711 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServer,
1713 silc_free(di->host);
1714 CONFIG_FREE_AUTH(di);
1717 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigRouter,
1719 silc_free(di->host);
1720 silc_free(di->backup_replace_ip);
1721 CONFIG_FREE_AUTH(di);
1725 memset(config, 'F', sizeof(*config));
1729 /* Registers configured ciphers. These can then be allocated by the
1730 server when needed. */
1732 SilcBool silc_server_config_register_ciphers(SilcServer server)
1734 SilcServerConfig config = server->config;
1735 SilcServerConfigCipher *cipher = config->cipher;
1736 char *module_path = config->module_path;
1738 SILC_LOG_DEBUG(("Registering configured ciphers"));
1740 if (!cipher) /* any cipher in the config file? */
1744 /* if there isn't a module_path OR there isn't a module sim name try to
1745 * use buil-in functions */
1746 if (!module_path || !cipher->module) {
1748 for (i = 0; silc_default_ciphers[i].name; i++)
1749 if (!strcmp(silc_default_ciphers[i].name, cipher->name)) {
1750 silc_cipher_register((SilcCipherObject *)&silc_default_ciphers[i]);
1753 if (!silc_cipher_is_supported(cipher->name)) {
1754 SILC_LOG_ERROR(("Unknown cipher `%s'", cipher->name));
1755 silc_server_stop(server);
1759 cipher = cipher->next;
1765 /* Registers configured hash functions. These can then be allocated by the
1766 server when needed. */
1768 SilcBool silc_server_config_register_hashfuncs(SilcServer server)
1770 SilcServerConfig config = server->config;
1771 SilcServerConfigHash *hash = config->hash;
1772 char *module_path = config->module_path;
1774 SILC_LOG_DEBUG(("Registering configured hash functions"));
1776 if (!hash) /* any hash func in the config file? */
1780 /* if there isn't a module_path OR there isn't a module sim name try to
1781 * use buil-in functions */
1782 if (!module_path || !hash->module) {
1784 for (i = 0; silc_default_hash[i].name; i++)
1785 if (!strcmp(silc_default_hash[i].name, hash->name)) {
1786 silc_hash_register((SilcHashObject *)&silc_default_hash[i]);
1789 if (!silc_hash_is_supported(hash->name)) {
1790 SILC_LOG_ERROR(("Unknown hash funtion `%s'", hash->name));
1791 silc_server_stop(server);
1801 /* Registers configure HMACs. These can then be allocated by the server
1804 SilcBool silc_server_config_register_hmacs(SilcServer server)
1806 SilcServerConfig config = server->config;
1807 SilcServerConfigHmac *hmac = config->hmac;
1809 SILC_LOG_DEBUG(("Registering configured HMACs"));
1815 SilcHmacObject hmac_obj;
1816 if (!silc_hash_is_supported(hmac->hash)) {
1817 SILC_LOG_ERROR(("Unknown hash function `%s'", hmac->hash));
1818 silc_server_stop(server);
1822 /* Register the HMAC */
1823 memset(&hmac_obj, 0, sizeof(hmac_obj));
1824 hmac_obj.name = hmac->name;
1825 hmac_obj.len = hmac->mac_length;
1826 silc_hmac_register(&hmac_obj);
1834 /* Registers configured PKCS's. */
1836 SilcBool silc_server_config_register_pkcs(SilcServer server)
1841 /* Sets log files where log messages are saved by the server logger. */
1843 void silc_server_config_setlogfiles(SilcServer server)
1845 SilcServerConfig config = server->config;
1846 SilcServerConfigLogging *this;
1848 SILC_LOG_DEBUG(("Setting configured log file names and options"));
1850 silc_log_timestamp(config->logging_timestamp);
1851 silc_log_quick(config->logging_quick);
1852 silc_log_flushdelay(config->logging_flushdelay ?
1853 config->logging_flushdelay :
1854 SILC_SERVER_LOG_FLUSH_DELAY);
1856 if ((this = config->logging_fatals))
1857 silc_log_set_file(SILC_LOG_FATAL, this->file, this->maxsize,
1859 if ((this = config->logging_errors))
1860 silc_log_set_file(SILC_LOG_ERROR, this->file, this->maxsize,
1862 if ((this = config->logging_warnings))
1863 silc_log_set_file(SILC_LOG_WARNING, this->file, this->maxsize,
1865 if ((this = config->logging_info))
1866 silc_log_set_file(SILC_LOG_INFO, this->file, this->maxsize,
1870 /* Returns client authentication information from configuration file by host
1873 SilcServerConfigClient *
1874 silc_server_config_find_client(SilcServer server, char *host)
1876 SilcServerConfig config = server->config;
1877 SilcServerConfigClient *client;
1879 if (!config || !host)
1882 for (client = config->clients; client; client = client->next) {
1883 if (client->host && !silc_string_compare(client->host, host))
1888 /* if none matched, then client is already NULL */
1892 /* Returns admin connection configuration by host, username and/or
1895 SilcServerConfigAdmin *
1896 silc_server_config_find_admin(SilcServer server, char *host, char *user,
1899 SilcServerConfig config = server->config;
1900 SilcServerConfigAdmin *admin;
1902 /* make sure we have a value for the matching parameters */
1910 for (admin = config->admins; admin; admin = admin->next) {
1911 if (admin->host && !silc_string_compare(admin->host, host))
1913 if (admin->user && !silc_string_compare(admin->user, user))
1915 if (admin->nick && !silc_string_compare(admin->nick, nick))
1917 /* no checks failed -> this entry matches */
1921 /* if none matched, then admin is already NULL */
1925 /* Returns the denied connection configuration entry by host. */
1927 SilcServerConfigDeny *
1928 silc_server_config_find_denied(SilcServer server, char *host)
1930 SilcServerConfig config = server->config;
1931 SilcServerConfigDeny *deny;
1933 /* make sure we have a value for the matching parameters */
1934 if (!config || !host)
1937 for (deny = config->denied; deny; deny = deny->next) {
1938 if (deny->host && !silc_string_compare(deny->host, host))
1943 /* if none matched, then deny is already NULL */
1947 /* Returns server connection info from server configuartion by host
1950 SilcServerConfigServer *
1951 silc_server_config_find_server_conn(SilcServer server, char *host)
1953 SilcServerConfig config = server->config;
1954 SilcServerConfigServer *serv = NULL;
1959 if (!config->servers)
1962 for (serv = config->servers; serv; serv = serv->next) {
1963 if (!silc_string_compare(serv->host, host))
1971 /* Returns router connection info from server configuration by
1972 host (name or ip). */
1974 SilcServerConfigRouter *
1975 silc_server_config_find_router_conn(SilcServer server, char *host, int port)
1977 SilcServerConfig config = server->config;
1978 SilcServerConfigRouter *serv = NULL;
1983 if (!config->routers)
1986 for (serv = config->routers; serv; serv = serv->next) {
1987 if (!silc_string_compare(serv->host, host))
1989 if (port && serv->port && serv->port != port)
1997 /* Find backup router connection by host (name or ip) */
1999 SilcServerConfigRouter *
2000 silc_server_config_find_backup_conn(SilcServer server, char *host)
2002 SilcServerConfig config = server->config;
2003 SilcServerConfigRouter *serv = NULL;
2008 if (!config->routers)
2011 for (serv = config->routers; serv; serv = serv->next) {
2012 if (!serv->backup_router)
2014 if (!silc_string_compare(serv->host, host))
2022 /* Returns TRUE if configuration for a router connection that we are
2023 initiating exists. */
2025 SilcBool silc_server_config_is_primary_route(SilcServer server)
2027 SilcServerConfig config = server->config;
2028 SilcServerConfigRouter *serv = NULL;
2030 SilcBool found = FALSE;
2032 serv = config->routers;
2033 for (i = 0; serv; i++) {
2034 if (serv->initiator == TRUE && serv->backup_router == FALSE) {
2045 /* Returns our primary connection configuration or NULL if we do not
2046 have primary router configured. */
2048 SilcServerConfigRouter *
2049 silc_server_config_get_primary_router(SilcServer server)
2051 SilcServerConfig config = server->config;
2052 SilcServerConfigRouter *serv = NULL;
2055 serv = config->routers;
2056 for (i = 0; serv; i++) {
2057 if (serv->initiator == TRUE && serv->backup_router == FALSE)
2065 /* If we have backup router configured that is going to replace us this
2066 function returns it. */
2068 SilcServerConfigRouter *
2069 silc_server_config_get_backup_router(SilcServer server)
2071 SilcServerConfig config = server->config;
2072 SilcServerConfigRouter *serv = NULL;
2075 if (server->server_type != SILC_ROUTER)
2078 serv = config->routers;
2079 for (i = 0; serv; i++) {
2080 if (serv->initiator == FALSE && serv->backup_router == TRUE &&
2081 serv->backup_local == TRUE &&
2082 !strcmp(server->config->server_info->primary->server_ip,
2083 serv->backup_replace_ip) &&
2084 server->config->server_info->primary->port ==
2085 serv->backup_replace_port)