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 /* RouterConnection sanity checks */
1420 if (config->routers && config->routers->backup_router == TRUE &&
1422 SILC_SERVER_LOG_ERROR((
1423 "\nError: First RouterConnection block must be primary router "
1424 "connection. You have marked it incorrectly as backup router."));
1428 if (config->routers && config->routers->initiator == FALSE &&
1429 config->routers->backup_router == FALSE) {
1430 SILC_SERVER_LOG_ERROR((
1431 "\nError: First RouterConnection block must be primary router "
1432 "connection and it must be marked as Initiator."));
1436 if (config->routers && config->routers->backup_router == TRUE &&
1437 !config->servers && !config->routers->next) {
1438 SILC_SERVER_LOG_ERROR((
1439 "\nError: You have configured backup router but not primary router. "
1440 "If backup router is configured also primary router must be "
1445 /* Backup router sanity checks */
1447 for (r = config->routers; r; r = r->next) {
1448 if (r->backup_router && !strcmp(r->host, r->backup_replace_ip)) {
1449 SILC_SERVER_LOG_ERROR((
1450 "\nError: Backup router connection incorrectly configured to use "
1451 "primary and backup router as same host `%s'. They must not be "
1452 "same host.", r->host));
1456 if (r->initiator == FALSE && r->port != 0) {
1457 SILC_SERVER_LOG_WARNING(("\nWarning: Initiator is FALSE and Port is "
1458 "specified. Ignoring Port value."));
1463 /* ServerConnection sanity checks */
1465 for (s = config->servers; s; s = s->next) {
1466 if (s->backup_router) {
1472 for (s = config->servers; s; s = s->next) {
1473 if (!s->backup_router) {
1474 SILC_SERVER_LOG_ERROR((
1475 "\nError: Your server is backup router but not all ServerConnection "
1476 "blocks were marked as backup connections. They all must be "
1477 "marked as backup connections."));
1487 /* Allocates a new configuration object, opens configuration file and
1488 parses it. The parsed data is returned to the newly allocated
1489 configuration object. The SilcServerConfig must be freed by calling
1490 the silc_server_config_destroy function. */
1492 SilcServerConfig silc_server_config_alloc(const char *filename,
1495 SilcServerConfig config_new;
1496 SilcConfigEntity ent;
1497 SilcConfigFile *file;
1499 SILC_LOG_DEBUG(("Loading config data from `%s'", filename));
1501 /* alloc a config object */
1502 config_new = silc_calloc(1, sizeof(*config_new));
1506 /* general config defaults */
1507 config_new->refcount = 1;
1508 config_new->logging_timestamp = TRUE;
1509 config_new->param.reconnect_keep_trying = TRUE;
1510 config_new->server = server;
1512 /* obtain a config file object */
1513 file = silc_config_open(filename);
1515 SILC_SERVER_LOG_ERROR(("\nError: can't open config file `%s'",
1520 /* obtain a SilcConfig entity, we can use it to start the parsing */
1521 ent = silc_config_init(file);
1523 /* load the known configuration options, give our empty object as context */
1524 silc_config_register_table(ent, table_main, (void *) config_new);
1526 /* enter the main parsing loop. When this returns, we have the parsing
1527 * result and the object filled (or partially, in case of errors). */
1528 ret = silc_config_main(ent);
1529 SILC_LOG_DEBUG(("Parser returned [ret=%d]: %s", ret,
1530 silc_config_strerror(ret)));
1532 /* Check if the parser returned errors */
1534 /* handle this special error return which asks to quietly return */
1535 if (ret != SILC_CONFIG_ESILENT) {
1536 char *linebuf, *filename = silc_config_get_filename(file);
1537 SilcUInt32 line = silc_config_get_line(file);
1538 if (ret != SILC_CONFIG_EPRINTLINE)
1539 SILC_SERVER_LOG_ERROR(("Error while parsing config file: %s.",
1540 silc_config_strerror(ret)));
1541 linebuf = silc_config_read_line(file, line);
1543 SILC_SERVER_LOG_ERROR((" file %s line %lu: %s\n", filename,
1548 silc_server_config_destroy(config_new);
1549 silc_config_close(file);
1553 /* close (destroy) the file object */
1554 silc_config_close(file);
1556 /* Check the configuration */
1557 if (!silc_server_config_check(config_new)) {
1558 silc_server_config_destroy(config_new);
1562 /* Set default to configuration parameters */
1563 silc_server_config_set_defaults(config_new);
1568 /* Increments the reference counter of a config object */
1570 void silc_server_config_ref(SilcServerConfigRef *ref, SilcServerConfig config,
1575 ref->config = config;
1576 ref->ref_ptr = ref_ptr;
1577 SILC_LOG_DEBUG(("Referencing config [%p] refcnt %d->%d", config,
1578 config->refcount - 1, config->refcount));
1582 /* Decrements the reference counter of a config object. If the counter
1583 reaches 0, the config object is destroyed. */
1585 void silc_server_config_unref(SilcServerConfigRef *ref)
1588 silc_server_config_destroy(ref->config);
1591 /* Destroy a config object with all his children lists */
1593 void silc_server_config_destroy(SilcServerConfig config)
1598 SILC_LOG_DEBUG(("Unreferencing config [%p] refcnt %d->%d", config,
1599 config->refcount + 1, config->refcount));
1600 if (config->refcount > 0)
1603 SILC_LOG_DEBUG(("Freeing config context"));
1605 /* Destroy general config stuff */
1606 silc_free(config->module_path);
1607 silc_free(config->debug_string);
1608 silc_free(config->param.version_protocol);
1609 silc_free(config->param.version_software);
1610 silc_free(config->param.version_software_vendor);
1611 silc_free(config->httpd_ip);
1613 /* Destroy Logging channels */
1614 if (config->logging_info)
1615 silc_free(config->logging_info->file);
1616 if (config->logging_warnings)
1617 silc_free(config->logging_warnings->file);
1618 if (config->logging_errors)
1619 silc_free(config->logging_errors->file);
1620 if (config->logging_fatals)
1621 silc_free(config->logging_fatals->file);
1622 silc_free(config->logging_info);
1623 silc_free(config->logging_warnings);
1624 silc_free(config->logging_errors);
1625 silc_free(config->logging_fatals);
1627 /* Destroy the ServerInfo struct */
1628 if (config->server_info) {
1629 register SilcServerConfigServerInfo *si = config->server_info;
1630 silc_free(si->server_name);
1632 silc_free(si->primary->server_ip);
1633 silc_free(si->primary);
1635 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServerInfoInterface,
1637 silc_free(di->server_ip);
1640 silc_free(si->server_type);
1641 silc_free(si->location);
1642 silc_free(si->admin);
1643 silc_free(si->email);
1644 silc_free(si->user);
1645 silc_free(si->group);
1646 silc_free(si->motd_file);
1647 silc_free(si->pid_file);
1649 silc_pkcs_public_key_free(si->public_key);
1650 if (si->private_key)
1651 silc_pkcs_private_key_free(si->private_key);
1655 /* Now let's destroy the lists */
1657 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigCipher,
1659 silc_free(di->name);
1660 silc_free(di->module);
1663 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHash, config->hash)
1664 silc_free(di->name);
1665 silc_free(di->module);
1668 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHmac, config->hmac)
1669 silc_free(di->name);
1670 silc_free(di->hash);
1673 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigPkcs, config->pkcs)
1674 silc_free(di->name);
1677 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigConnParams,
1678 config->conn_params)
1679 silc_free(di->name);
1680 silc_free(di->version_protocol);
1681 silc_free(di->version_software);
1682 silc_free(di->version_software_vendor);
1685 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigClient, config->clients)
1686 silc_free(di->host);
1687 CONFIG_FREE_AUTH(di);
1690 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigAdmin, config->admins)
1691 silc_free(di->host);
1692 silc_free(di->user);
1693 silc_free(di->nick);
1694 CONFIG_FREE_AUTH(di);
1697 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigDeny, config->denied)
1698 silc_free(di->host);
1699 silc_free(di->reason);
1702 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServer,
1704 silc_free(di->host);
1705 CONFIG_FREE_AUTH(di);
1708 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigRouter,
1710 silc_free(di->host);
1711 silc_free(di->backup_replace_ip);
1712 CONFIG_FREE_AUTH(di);
1716 memset(config, 'F', sizeof(*config));
1720 /* Registers configured ciphers. These can then be allocated by the
1721 server when needed. */
1723 SilcBool silc_server_config_register_ciphers(SilcServer server)
1725 SilcServerConfig config = server->config;
1726 SilcServerConfigCipher *cipher = config->cipher;
1727 char *module_path = config->module_path;
1729 SILC_LOG_DEBUG(("Registering configured ciphers"));
1731 if (!cipher) /* any cipher in the config file? */
1735 /* if there isn't a module_path OR there isn't a module sim name try to
1736 * use buil-in functions */
1737 if (!module_path || !cipher->module) {
1739 for (i = 0; silc_default_ciphers[i].name; i++)
1740 if (!strcmp(silc_default_ciphers[i].name, cipher->name)) {
1741 silc_cipher_register((SilcCipherObject *)&silc_default_ciphers[i]);
1744 if (!silc_cipher_is_supported(cipher->name)) {
1745 SILC_LOG_ERROR(("Unknown cipher `%s'", cipher->name));
1746 silc_server_stop(server);
1750 cipher = cipher->next;
1756 /* Registers configured hash functions. These can then be allocated by the
1757 server when needed. */
1759 SilcBool silc_server_config_register_hashfuncs(SilcServer server)
1761 SilcServerConfig config = server->config;
1762 SilcServerConfigHash *hash = config->hash;
1763 char *module_path = config->module_path;
1765 SILC_LOG_DEBUG(("Registering configured hash functions"));
1767 if (!hash) /* any hash func in the config file? */
1771 /* if there isn't a module_path OR there isn't a module sim name try to
1772 * use buil-in functions */
1773 if (!module_path || !hash->module) {
1775 for (i = 0; silc_default_hash[i].name; i++)
1776 if (!strcmp(silc_default_hash[i].name, hash->name)) {
1777 silc_hash_register((SilcHashObject *)&silc_default_hash[i]);
1780 if (!silc_hash_is_supported(hash->name)) {
1781 SILC_LOG_ERROR(("Unknown hash funtion `%s'", hash->name));
1782 silc_server_stop(server);
1792 /* Registers configure HMACs. These can then be allocated by the server
1795 SilcBool silc_server_config_register_hmacs(SilcServer server)
1797 SilcServerConfig config = server->config;
1798 SilcServerConfigHmac *hmac = config->hmac;
1800 SILC_LOG_DEBUG(("Registering configured HMACs"));
1806 SilcHmacObject hmac_obj;
1807 if (!silc_hash_is_supported(hmac->hash)) {
1808 SILC_LOG_ERROR(("Unknown hash function `%s'", hmac->hash));
1809 silc_server_stop(server);
1813 /* Register the HMAC */
1814 memset(&hmac_obj, 0, sizeof(hmac_obj));
1815 hmac_obj.name = hmac->name;
1816 hmac_obj.len = hmac->mac_length;
1817 silc_hmac_register(&hmac_obj);
1825 /* Registers configured PKCS's. */
1827 SilcBool silc_server_config_register_pkcs(SilcServer server)
1832 /* Sets log files where log messages are saved by the server logger. */
1834 void silc_server_config_setlogfiles(SilcServer server)
1836 SilcServerConfig config = server->config;
1837 SilcServerConfigLogging *this;
1839 SILC_LOG_DEBUG(("Setting configured log file names and options"));
1841 silc_log_timestamp(config->logging_timestamp);
1842 silc_log_quick(config->logging_quick);
1843 silc_log_flushdelay(config->logging_flushdelay ?
1844 config->logging_flushdelay :
1845 SILC_SERVER_LOG_FLUSH_DELAY);
1847 if ((this = config->logging_fatals))
1848 silc_log_set_file(SILC_LOG_FATAL, this->file, this->maxsize,
1850 if ((this = config->logging_errors))
1851 silc_log_set_file(SILC_LOG_ERROR, this->file, this->maxsize,
1853 if ((this = config->logging_warnings))
1854 silc_log_set_file(SILC_LOG_WARNING, this->file, this->maxsize,
1856 if ((this = config->logging_info))
1857 silc_log_set_file(SILC_LOG_INFO, this->file, this->maxsize,
1861 /* Returns client authentication information from configuration file by host
1864 SilcServerConfigClient *
1865 silc_server_config_find_client(SilcServer server, char *host)
1867 SilcServerConfig config = server->config;
1868 SilcServerConfigClient *client;
1870 if (!config || !host)
1873 for (client = config->clients; client; client = client->next) {
1874 if (client->host && !silc_string_compare(client->host, host))
1879 /* if none matched, then client is already NULL */
1883 /* Returns admin connection configuration by host, username and/or
1886 SilcServerConfigAdmin *
1887 silc_server_config_find_admin(SilcServer server, char *host, char *user,
1890 SilcServerConfig config = server->config;
1891 SilcServerConfigAdmin *admin;
1893 /* make sure we have a value for the matching parameters */
1901 for (admin = config->admins; admin; admin = admin->next) {
1902 if (admin->host && !silc_string_compare(admin->host, host))
1904 if (admin->user && !silc_string_compare(admin->user, user))
1906 if (admin->nick && !silc_string_compare(admin->nick, nick))
1908 /* no checks failed -> this entry matches */
1912 /* if none matched, then admin is already NULL */
1916 /* Returns the denied connection configuration entry by host. */
1918 SilcServerConfigDeny *
1919 silc_server_config_find_denied(SilcServer server, char *host)
1921 SilcServerConfig config = server->config;
1922 SilcServerConfigDeny *deny;
1924 /* make sure we have a value for the matching parameters */
1925 if (!config || !host)
1928 for (deny = config->denied; deny; deny = deny->next) {
1929 if (deny->host && !silc_string_compare(deny->host, host))
1934 /* if none matched, then deny is already NULL */
1938 /* Returns server connection info from server configuartion by host
1941 SilcServerConfigServer *
1942 silc_server_config_find_server_conn(SilcServer server, char *host)
1944 SilcServerConfig config = server->config;
1945 SilcServerConfigServer *serv = NULL;
1950 if (!config->servers)
1953 for (serv = config->servers; serv; serv = serv->next) {
1954 if (!silc_string_compare(serv->host, host))
1962 /* Returns router connection info from server configuration by
1963 host (name or ip). */
1965 SilcServerConfigRouter *
1966 silc_server_config_find_router_conn(SilcServer server, char *host, int port)
1968 SilcServerConfig config = server->config;
1969 SilcServerConfigRouter *serv = NULL;
1974 if (!config->routers)
1977 for (serv = config->routers; serv; serv = serv->next) {
1978 if (!silc_string_compare(serv->host, host))
1980 if (port && serv->port && serv->port != port)
1988 /* Find backup router connection by host (name or ip) */
1990 SilcServerConfigRouter *
1991 silc_server_config_find_backup_conn(SilcServer server, char *host)
1993 SilcServerConfig config = server->config;
1994 SilcServerConfigRouter *serv = NULL;
1999 if (!config->routers)
2002 for (serv = config->routers; serv; serv = serv->next) {
2003 if (!serv->backup_router)
2005 if (!silc_string_compare(serv->host, host))
2013 /* Returns TRUE if configuration for a router connection that we are
2014 initiating exists. */
2016 SilcBool silc_server_config_is_primary_route(SilcServer server)
2018 SilcServerConfig config = server->config;
2019 SilcServerConfigRouter *serv = NULL;
2021 SilcBool found = FALSE;
2023 serv = config->routers;
2024 for (i = 0; serv; i++) {
2025 if (serv->initiator == TRUE && serv->backup_router == FALSE) {
2036 /* Returns our primary connection configuration or NULL if we do not
2037 have primary router configured. */
2039 SilcServerConfigRouter *
2040 silc_server_config_get_primary_router(SilcServer server)
2042 SilcServerConfig config = server->config;
2043 SilcServerConfigRouter *serv = NULL;
2046 serv = config->routers;
2047 for (i = 0; serv; i++) {
2048 if (serv->initiator == TRUE && serv->backup_router == FALSE)
2056 /* If we have backup router configured that is going to replace us this
2057 function returns it. */
2059 SilcServerConfigRouter *
2060 silc_server_config_get_backup_router(SilcServer server)
2062 SilcServerConfig config = server->config;
2063 SilcServerConfigRouter *serv = NULL;
2066 if (server->server_type != SILC_ROUTER)
2069 serv = config->routers;
2070 for (i = 0; serv; i++) {
2071 if (serv->initiator == FALSE && serv->backup_router == TRUE &&
2072 serv->backup_local == TRUE &&
2073 !strcmp(server->config->server_info->primary->server_ip,
2074 serv->backup_replace_ip) &&
2075 server->config->server_info->primary->port ==
2076 serv->backup_replace_port)