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 int 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 if (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, "prefer_passphrase_auth")) {
237 config->prefer_passphrase_auth = *(SilcBool *)val;
239 else if (!strcmp(name, "require_reverse_lookup")) {
240 config->require_reverse_lookup = *(SilcBool *)val;
242 else if (!strcmp(name, "connections_max")) {
243 config->param.connections_max = (SilcUInt32) *(int *)val;
245 else if (!strcmp(name, "connections_max_per_host")) {
246 config->param.connections_max_per_host = (SilcUInt32) *(int *)val;
248 else if (!strcmp(name, "keepalive_secs")) {
249 config->param.keepalive_secs = (SilcUInt32) *(int *)val;
251 else if (!strcmp(name, "reconnect_count")) {
252 config->param.reconnect_count = (SilcUInt32) *(int *)val;
254 else if (!strcmp(name, "reconnect_interval")) {
255 config->param.reconnect_interval = (SilcUInt32) *(int *)val;
257 else if (!strcmp(name, "reconnect_interval_max")) {
258 config->param.reconnect_interval_max = (SilcUInt32) *(int *)val;
260 else if (!strcmp(name, "reconnect_keep_trying")) {
261 config->param.reconnect_keep_trying = *(SilcBool *)val;
263 else if (!strcmp(name, "key_exchange_rekey")) {
264 config->param.key_exchange_rekey = (SilcUInt32) *(int *)val;
266 else if (!strcmp(name, "key_exchange_pfs")) {
267 config->param.key_exchange_pfs = *(SilcBool *)val;
269 else if (!strcmp(name, "channel_rekey_secs")) {
270 config->channel_rekey_secs = (SilcUInt32) *(int *)val;
272 else if (!strcmp(name, "key_exchange_timeout")) {
273 config->key_exchange_timeout = (SilcUInt32) *(int *)val;
275 else if (!strcmp(name, "conn_auth_timeout")) {
276 config->conn_auth_timeout = (SilcUInt32) *(int *)val;
278 else if (!strcmp(name, "version_protocol")) {
279 CONFIG_IS_DOUBLE(config->param.version_protocol);
280 config->param.version_protocol =
281 (*(char *)val ? strdup((char *) val) : NULL);
283 else if (!strcmp(name, "version_software")) {
284 CONFIG_IS_DOUBLE(config->param.version_software);
285 config->param.version_software =
286 (*(char *)val ? strdup((char *) val) : NULL);
288 else if (!strcmp(name, "version_software_vendor")) {
289 CONFIG_IS_DOUBLE(config->param.version_software_vendor);;
290 config->param.version_software_vendor =
291 (*(char *)val ? strdup((char *) val) : NULL);
293 else if (!strcmp(name, "detach_disabled")) {
294 config->detach_disabled = *(SilcBool *)val;
296 else if (!strcmp(name, "detach_timeout")) {
297 config->detach_timeout = (SilcUInt32) *(int *)val;
299 else if (!strcmp(name, "qos")) {
300 config->param.qos = *(SilcBool *)val;
302 else if (!strcmp(name, "qos_rate_limit")) {
303 config->param.qos_rate_limit = *(SilcUInt32 *)val;
305 else if (!strcmp(name, "qos_bytes_limit")) {
306 config->param.qos_bytes_limit = *(SilcUInt32 *)val;
308 else if (!strcmp(name, "qos_limit_sec")) {
309 config->param.qos_limit_sec = *(SilcUInt32 *)val;
311 else if (!strcmp(name, "qos_limit_usec")) {
312 config->param.qos_limit_usec = *(SilcUInt32 *)val;
314 else if (!strcmp(name, "channel_join_limit")) {
315 config->param.chlimit = *(SilcUInt32 *)val;
317 else if (!strcmp(name, "debug_string")) {
318 CONFIG_IS_DOUBLE(config->debug_string);
319 config->debug_string = (*(char *)val ? strdup((char *) val) : NULL);
321 else if (!strcmp(name, "http_server")) {
322 config->httpd = *(SilcBool *)val;
324 else if (!strcmp(name, "http_server_ip")) {
325 CONFIG_IS_DOUBLE(config->httpd_ip);
326 config->httpd_ip = (*(char *)val ? strdup((char *) val) : NULL);
328 else if (!strcmp(name, "http_server_port")) {
329 int port = *(int *)val;
330 if ((port <= 0) || (port > 65535)) {
331 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
332 "Invalid port number!"));
333 got_errno = SILC_CONFIG_EPRINTLINE;
336 config->httpd_port = (SilcUInt16)port;
338 else if (!strcmp(name, "dynamic_server")) {
339 config->dynamic_server = *(SilcBool *)val;
341 else if (!strcmp(name, "local_channels")) {
342 config->local_channels = *(SilcBool *)val;
345 return SILC_CONFIG_EINTERNAL;
347 return SILC_CONFIG_OK;
353 SILC_CONFIG_CALLBACK(fetch_cipher)
355 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigCipher);
357 SERVER_CONFIG_DEBUG(("Received CIPHER type=%d name=\"%s\" (val=%x)",
358 type, name, context));
359 if (type == SILC_CONFIG_ARG_BLOCK) {
360 /* check the temporary struct's fields */
361 if (!tmp) /* discard empty sub-blocks */
362 return SILC_CONFIG_OK;
364 got_errno = SILC_CONFIG_EMISSFIELDS;
368 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->cipher);
370 return SILC_CONFIG_OK;
372 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigCipher);
374 /* Identify and save this value */
375 if (!strcmp(name, "name")) {
376 CONFIG_IS_DOUBLE(tmp->name);
377 tmp->name = strdup((char *) val);
379 else if (!strcmp(name, "keylength")) {
380 tmp->key_length = *(SilcUInt32 *)val;
382 else if (!strcmp(name, "blocklength")) {
383 tmp->block_length = *(SilcUInt32 *)val;
386 return SILC_CONFIG_EINTERNAL;
387 return SILC_CONFIG_OK;
390 silc_free(tmp->name);
396 SILC_CONFIG_CALLBACK(fetch_hash)
398 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigHash);
400 SERVER_CONFIG_DEBUG(("Received HASH type=%d name=%s (val=%x)",
401 type, name, context));
402 if (type == SILC_CONFIG_ARG_BLOCK) {
403 /* check the temporary struct's fields */
404 if (!tmp) /* discard empty sub-blocks */
405 return SILC_CONFIG_OK;
406 if (!tmp->name || (tmp->block_length == 0) || (tmp->digest_length == 0)) {
407 got_errno = SILC_CONFIG_EMISSFIELDS;
411 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hash);
413 return SILC_CONFIG_OK;
415 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigHash);
417 /* Identify and save this value */
418 if (!strcmp(name, "name")) {
419 CONFIG_IS_DOUBLE(tmp->name);
420 tmp->name = strdup((char *) val);
422 else if (!strcmp(name, "blocklength")) {
423 tmp->block_length = *(int *)val;
425 else if (!strcmp(name, "digestlength")) {
426 tmp->digest_length = *(int *)val;
429 return SILC_CONFIG_EINTERNAL;
430 return SILC_CONFIG_OK;
433 silc_free(tmp->name);
439 SILC_CONFIG_CALLBACK(fetch_hmac)
441 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigHmac);
443 SERVER_CONFIG_DEBUG(("Received HMAC type=%d name=\"%s\" (val=%x)",
444 type, name, context));
445 if (type == SILC_CONFIG_ARG_BLOCK) {
446 /* check the temporary struct's fields */
447 if (!tmp) /* discard empty sub-blocks */
448 return SILC_CONFIG_OK;
449 if (!tmp->name || !tmp->hash || (tmp->mac_length == 0)) {
450 got_errno = SILC_CONFIG_EMISSFIELDS;
454 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hmac);
456 return SILC_CONFIG_OK;
458 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigHmac);
460 /* Identify and save this value */
461 if (!strcmp(name, "name")) {
462 CONFIG_IS_DOUBLE(tmp->name);
463 tmp->name = strdup((char *) val);
465 else if (!strcmp(name, "hash")) {
466 CONFIG_IS_DOUBLE(tmp->hash);
467 tmp->hash = strdup((char *) val);
469 else if (!strcmp(name, "maclength")) {
470 tmp->mac_length = *(int *)val;
473 return SILC_CONFIG_EINTERNAL;
474 return SILC_CONFIG_OK;
477 silc_free(tmp->name);
478 silc_free(tmp->hash);
484 SILC_CONFIG_CALLBACK(fetch_pkcs)
486 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigPkcs);
488 SERVER_CONFIG_DEBUG(("Received PKCS type=%d name=\"%s\" (val=%x)",
489 type, name, context));
490 if (type == SILC_CONFIG_ARG_BLOCK) {
491 /* Check the temporary struct's fields */
492 if (!tmp) /* discard empty sub-blocks */
493 return SILC_CONFIG_OK;
495 got_errno = SILC_CONFIG_EMISSFIELDS;
499 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->pkcs);
501 return SILC_CONFIG_OK;
503 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigPkcs);
505 /* Identify and save this value */
506 if (!strcmp(name, "name")) {
507 CONFIG_IS_DOUBLE(tmp->name);
508 tmp->name = strdup((char *) val);
511 return SILC_CONFIG_EINTERNAL;
512 return SILC_CONFIG_OK;
515 silc_free(tmp->name);
521 SILC_CONFIG_CALLBACK(fetch_serverinfo)
523 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServerInfoInterface);
524 SilcServerConfigServerInfo *server_info = config->server_info;
526 SERVER_CONFIG_DEBUG(("Received SERVERINFO type=%d name=\"%s\" (val=%x)",
527 type, name, context));
529 /* If there isn't the main struct alloc it */
531 config->server_info = server_info = (SilcServerConfigServerInfo *)
532 silc_calloc(1, sizeof(*server_info));
534 if (type == SILC_CONFIG_ARG_BLOCK) {
535 if (!strcmp(name, "primary")) {
536 if (server_info->primary) {
537 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
538 "Double primary specification."));
539 got_errno = SILC_CONFIG_EPRINTLINE;
542 CONFIG_IS_DOUBLE(server_info->primary);
544 /* now check the temporary struct, don't accept empty block and
545 make sure all fields are there */
546 if (!tmp || !tmp->server_ip || !tmp->port) {
547 got_errno = SILC_CONFIG_EMISSFIELDS;
550 server_info->primary = tmp;
552 return SILC_CONFIG_OK;
553 } else if (!strcmp(name, "secondary")) {
555 return SILC_CONFIG_OK;
556 if (!tmp || !tmp->server_ip || !tmp->port) {
557 got_errno = SILC_CONFIG_EMISSFIELDS;
560 SILC_SERVER_CONFIG_LIST_APPENDTMP(server_info->secondary);
562 return SILC_CONFIG_OK;
563 } else if (!server_info->public_key || !server_info->private_key) {
564 got_errno = SILC_CONFIG_EMISSFIELDS;
567 return SILC_CONFIG_OK;
569 if (!strcmp(name, "hostname")) {
570 CONFIG_IS_DOUBLE(server_info->server_name);
571 server_info->server_name = strdup((char *) val);
573 else if (!strcmp(name, "ip")) {
574 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
575 CONFIG_IS_DOUBLE(tmp->server_ip);
576 tmp->server_ip = strdup((char *) val);
578 else if (!strcmp(name, "public_ip")) {
579 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
580 CONFIG_IS_DOUBLE(tmp->public_ip);
581 tmp->public_ip = strdup((char *) val);
583 else if (!strcmp(name, "port")) {
584 int port = *(int *)val;
585 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
586 if ((port <= 0) || (port > 65535)) {
587 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
588 "Invalid port number!"));
589 got_errno = SILC_CONFIG_EPRINTLINE;
592 tmp->port = (SilcUInt16) port;
594 else if (!strcmp(name, "servertype")) {
595 CONFIG_IS_DOUBLE(server_info->server_type);
596 server_info->server_type = strdup((char *) val);
598 else if (!strcmp(name, "admin")) {
599 CONFIG_IS_DOUBLE(server_info->admin);
600 server_info->admin = strdup((char *) val);
602 else if (!strcmp(name, "adminemail")) {
603 CONFIG_IS_DOUBLE(server_info->email);
604 server_info->email = strdup((char *) val);
606 else if (!strcmp(name, "location")) {
607 CONFIG_IS_DOUBLE(server_info->location);
608 server_info->location = strdup((char *) val);
610 else if (!strcmp(name, "user")) {
611 CONFIG_IS_DOUBLE(server_info->user);
612 server_info->user = strdup((char *) val);
614 else if (!strcmp(name, "group")) {
615 CONFIG_IS_DOUBLE(server_info->group);
616 server_info->group = strdup((char *) val);
618 else if (!strcmp(name, "motdfile")) {
619 CONFIG_IS_DOUBLE(server_info->motd_file);
620 server_info->motd_file = strdup((char *) val);
622 else if (!strcmp(name, "pidfile")) {
623 CONFIG_IS_DOUBLE(server_info->pid_file);
624 server_info->pid_file = strdup((char *) val);
626 else if (!strcmp(name, "publickey")) {
627 char *file_tmp = (char *) val;
628 CONFIG_IS_DOUBLE(server_info->public_key);
630 /* Try to load specified file, if fail stop config parsing */
631 if (!silc_pkcs_load_public_key(file_tmp, &server_info->public_key)) {
632 SILC_SERVER_LOG_ERROR(("Error: Could not load public key file."));
633 return SILC_CONFIG_EPRINTLINE;
636 else if (!strcmp(name, "privatekey")) {
638 char *file_tmp = (char *) val;
639 CONFIG_IS_DOUBLE(server_info->private_key);
641 /* Check the private key file permissions. */
642 if ((stat(file_tmp, &st)) != -1) {
643 if (((st.st_mode & 0777) != 0600) &&
644 ((st.st_mode & 0777) != 0640)) {
645 SILC_SERVER_LOG_ERROR(("Wrong permissions in private key "
646 "file \"%s\". The permissions must be "
647 "0600 or 0640.", file_tmp));
648 return SILC_CONFIG_ESILENT;
652 /* Try to load specified file, if fail stop config parsing */
653 if (!silc_pkcs_load_private_key(file_tmp, "", 0,
654 &server_info->private_key)) {
655 SILC_SERVER_LOG_ERROR(("Error: Could not load private key file."));
656 return SILC_CONFIG_EPRINTLINE;
660 return SILC_CONFIG_EINTERNAL;
661 return SILC_CONFIG_OK;
664 /* Here we need to check if tmp exists because this function handles
665 * misc data (multiple fields and single-only fields) */
667 silc_free(tmp->server_ip);
674 SILC_CONFIG_CALLBACK(fetch_logging)
676 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigLogging);
678 if (!strcmp(name, "timestamp")) {
679 config->logging_timestamp = *(SilcBool *)val;
681 else if (!strcmp(name, "quicklogs")) {
682 config->logging_quick = *(SilcBool *)val;
684 else if (!strcmp(name, "flushdelay")) {
685 int flushdelay = *(int *)val;
686 if (flushdelay < 2) { /* this value was taken from silclog.h (min delay) */
687 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
688 "Invalid flushdelay value, use quicklogs if you "
689 "want real-time logging."));
690 return SILC_CONFIG_EPRINTLINE;
692 config->logging_flushdelay = (long) flushdelay;
695 /* The following istances happens only in Logging's sub-blocks, a match
696 for the sub-block name means that you should store the filename/maxsize
697 temporary struct to the proper logging channel.
698 If we get a match for "file" or "maxsize" this means that we are inside
699 a sub-sub-block and it is safe to alloc a new tmp. */
700 #define FETCH_LOGGING_CHAN(__chan__, __member__) \
701 else if (!strcmp(name, __chan__)) { \
702 if (!tmp) return SILC_CONFIG_OK; \
704 got_errno = SILC_CONFIG_EMISSFIELDS; goto got_err; \
706 config->__member__ = tmp; \
707 config->tmp = NULL; \
709 FETCH_LOGGING_CHAN("info", logging_info)
710 FETCH_LOGGING_CHAN("warnings", logging_warnings)
711 FETCH_LOGGING_CHAN("errors", logging_errors)
712 FETCH_LOGGING_CHAN("fatals", logging_fatals)
713 #undef FETCH_LOGGING_CHAN
714 else if (!strcmp(name, "file")) {
715 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigLogging);
716 CONFIG_IS_DOUBLE(tmp->file);
717 tmp->file = strdup((char *) val);
719 else if (!strcmp(name, "size")) {
721 config->tmp = silc_calloc(1, sizeof(*tmp));
722 tmp = (SilcServerConfigLogging *) config->tmp;
724 tmp->maxsize = *(SilcUInt32 *) val;
727 return SILC_CONFIG_EINTERNAL;
728 return SILC_CONFIG_OK;
731 silc_free(tmp->file);
737 SILC_CONFIG_CALLBACK(fetch_connparam)
739 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigConnParams);
741 SERVER_CONFIG_DEBUG(("Received CONNPARAM type=%d name=\"%s\" (val=%x)",
742 type, name, context));
743 if (type == SILC_CONFIG_ARG_BLOCK) {
744 /* check the temporary struct's fields */
745 if (!tmp) /* discard empty sub-blocks */
746 return SILC_CONFIG_OK;
748 got_errno = SILC_CONFIG_EMISSFIELDS;
752 my_set_param_defaults(tmp, &config->param);
754 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->conn_params);
756 return SILC_CONFIG_OK;
759 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigConnParams);
760 tmp->reconnect_keep_trying = TRUE;
763 if (!strcmp(name, "name")) {
764 CONFIG_IS_DOUBLE(tmp->name);
765 tmp->name = (*(char *)val ? strdup((char *) val) : NULL);
767 else if (!strcmp(name, "connections_max")) {
768 tmp->connections_max = *(SilcUInt32 *)val;
770 else if (!strcmp(name, "connections_max_per_host")) {
771 tmp->connections_max_per_host = *(SilcUInt32 *)val;
773 else if (!strcmp(name, "keepalive_secs")) {
774 tmp->keepalive_secs = *(SilcUInt32 *)val;
776 else if (!strcmp(name, "reconnect_count")) {
777 tmp->reconnect_count = *(SilcUInt32 *)val;
779 else if (!strcmp(name, "reconnect_interval")) {
780 tmp->reconnect_interval = *(SilcUInt32 *)val;
782 else if (!strcmp(name, "reconnect_interval_max")) {
783 tmp->reconnect_interval_max = *(SilcUInt32 *)val;
785 else if (!strcmp(name, "reconnect_keep_trying")) {
786 tmp->reconnect_keep_trying = *(SilcBool *)val;
788 else if (!strcmp(name, "key_exchange_rekey")) {
789 tmp->key_exchange_rekey = *(SilcUInt32 *)val;
791 else if (!strcmp(name, "key_exchange_pfs")) {
792 tmp->key_exchange_pfs = *(SilcBool *)val;
794 else if (!strcmp(name, "version_protocol")) {
795 CONFIG_IS_DOUBLE(tmp->version_protocol);
796 tmp->version_protocol = (*(char *)val ? strdup((char *) val) : NULL);
798 else if (!strcmp(name, "version_software")) {
799 CONFIG_IS_DOUBLE(tmp->version_software);
800 tmp->version_software = (*(char *)val ? strdup((char *) val) : NULL);
802 else if (!strcmp(name, "version_software_vendor")) {
803 CONFIG_IS_DOUBLE(tmp->version_software_vendor);;
804 tmp->version_software_vendor =
805 (*(char *)val ? strdup((char *) val) : NULL);
807 else if (!strcmp(name, "anonymous")) {
808 tmp->anonymous = *(SilcBool *)val;
810 else if (!strcmp(name, "qos")) {
811 tmp->qos = *(SilcBool *)val;
813 else if (!strcmp(name, "qos_rate_limit")) {
814 tmp->qos_rate_limit = *(SilcUInt32 *)val;
816 else if (!strcmp(name, "qos_bytes_limit")) {
817 tmp->qos_bytes_limit = *(SilcUInt32 *)val;
819 else if (!strcmp(name, "qos_limit_sec")) {
820 tmp->qos_limit_sec = *(SilcUInt32 *)val;
822 else if (!strcmp(name, "qos_limit_usec")) {
823 tmp->qos_limit_usec = *(SilcUInt32 *)val;
826 return SILC_CONFIG_EINTERNAL;
828 return SILC_CONFIG_OK;
831 silc_free(tmp->name);
837 SILC_CONFIG_CALLBACK(fetch_client)
839 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigClient);
841 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
842 type, name, context));
844 /* Alloc before block checking, because empty sub-blocks are welcome here */
845 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigClient);
847 if (type == SILC_CONFIG_ARG_BLOCK) {
848 /* empty sub-blocks are welcome */
849 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->clients);
851 return SILC_CONFIG_OK;
854 /* Identify and save this value */
855 if (!strcmp(name, "host")) {
856 CONFIG_IS_DOUBLE(tmp->host);
857 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
859 else if (!strcmp(name, "passphrase")) {
860 CONFIG_IS_DOUBLE(tmp->passphrase);
861 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
862 (void *)&tmp->passphrase,
863 &tmp->passphrase_len, 0, NULL)) {
864 got_errno = SILC_CONFIG_EPRINTLINE;
868 else if (!strcmp(name, "publickey")) {
869 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
870 (void *)&config->server->repository, NULL,
871 SILC_SKR_USAGE_AUTH |
872 SILC_SKR_USAGE_KEY_AGREEMENT, NULL)) {
873 got_errno = SILC_CONFIG_EPRINTLINE;
876 tmp->publickeys = TRUE;
878 else if (!strcmp(name, "publickeydir")) {
879 if (my_parse_publickeydir((char *) val,
880 (void *)&config->server->repository,
881 SILC_SKR_USAGE_AUTH |
882 SILC_SKR_USAGE_KEY_AGREEMENT) < 0) {
883 got_errno = SILC_CONFIG_EPRINTLINE;
886 tmp->publickeys = TRUE;
888 else if (!strcmp(name, "params")) {
889 CONFIG_IS_DOUBLE(tmp->param);
890 tmp->param = my_find_param(config, (char *) val);
891 if (!tmp->param) { /* error message already output */
892 got_errno = SILC_CONFIG_EPRINTLINE;
897 return SILC_CONFIG_EINTERNAL;
898 return SILC_CONFIG_OK;
901 silc_free(tmp->host);
902 CONFIG_FREE_AUTH(tmp);
908 SILC_CONFIG_CALLBACK(fetch_admin)
910 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigAdmin);
912 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
913 type, name, context));
914 if (type == SILC_CONFIG_ARG_BLOCK) {
915 /* check the temporary struct's fields */
916 if (!tmp) /* discard empty sub-blocks */
917 return SILC_CONFIG_OK;
919 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->admins);
921 return SILC_CONFIG_OK;
923 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigAdmin);
925 /* Identify and save this value */
926 if (!strcmp(name, "host")) {
927 CONFIG_IS_DOUBLE(tmp->host);
928 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
930 else if (!strcmp(name, "user")) {
931 CONFIG_IS_DOUBLE(tmp->user);
932 tmp->user = (*(char *)val ? strdup((char *) val) : NULL);
934 else if (!strcmp(name, "nick")) {
935 CONFIG_IS_DOUBLE(tmp->nick);
936 tmp->nick = (*(char *)val ? strdup((char *) val) : NULL);
938 else if (!strcmp(name, "passphrase")) {
939 CONFIG_IS_DOUBLE(tmp->passphrase);
940 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
941 (void *)&tmp->passphrase,
942 &tmp->passphrase_len, 0, NULL)) {
943 got_errno = SILC_CONFIG_EPRINTLINE;
947 else if (!strcmp(name, "publickey")) {
948 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
949 (void *)&config->server->repository, NULL,
950 SILC_SKR_USAGE_SERVICE_AUTHORIZATION, tmp)) {
951 got_errno = SILC_CONFIG_EPRINTLINE;
954 tmp->publickeys = TRUE;
957 return SILC_CONFIG_EINTERNAL;
958 return SILC_CONFIG_OK;
961 silc_free(tmp->host);
962 silc_free(tmp->user);
963 silc_free(tmp->nick);
964 CONFIG_FREE_AUTH(tmp);
970 SILC_CONFIG_CALLBACK(fetch_deny)
972 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigDeny);
974 SERVER_CONFIG_DEBUG(("Received DENY type=%d name=\"%s\" (val=%x)",
975 type, name, context));
976 if (type == SILC_CONFIG_ARG_BLOCK) {
977 /* check the temporary struct's fields */
978 if (!tmp) /* discard empty sub-blocks */
979 return SILC_CONFIG_OK;
981 got_errno = SILC_CONFIG_EMISSFIELDS;
985 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->denied);
987 return SILC_CONFIG_OK;
989 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigDeny);
991 /* Identify and save this value */
992 if (!strcmp(name, "host")) {
993 CONFIG_IS_DOUBLE(tmp->host);
994 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
996 else if (!strcmp(name, "reason")) {
997 CONFIG_IS_DOUBLE(tmp->reason);
998 tmp->reason = strdup((char *) val);
1001 return SILC_CONFIG_EINTERNAL;
1002 return SILC_CONFIG_OK;
1005 silc_free(tmp->host);
1006 silc_free(tmp->reason);
1012 SILC_CONFIG_CALLBACK(fetch_server)
1014 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServer);
1016 SERVER_CONFIG_DEBUG(("Received SERVER type=%d name=\"%s\" (val=%x)",
1017 type, name, context));
1018 if (type == SILC_CONFIG_ARG_BLOCK) {
1019 /* check the temporary struct's fields */
1020 if (!tmp) /* discard empty sub-blocks */
1021 return SILC_CONFIG_OK;
1023 got_errno = SILC_CONFIG_EMISSFIELDS;
1027 /* the temporary struct is ok, append it to the list */
1028 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->servers);
1030 return SILC_CONFIG_OK;
1032 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServer);
1034 /* Identify and save this value */
1035 if (!strcmp(name, "host")) {
1036 CONFIG_IS_DOUBLE(tmp->host);
1037 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
1039 else if (!strcmp(name, "passphrase")) {
1040 CONFIG_IS_DOUBLE(tmp->passphrase);
1041 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
1042 (void *)&tmp->passphrase,
1043 &tmp->passphrase_len, 0, NULL)) {
1044 got_errno = SILC_CONFIG_EPRINTLINE;
1048 else if (!strcmp(name, "publickey")) {
1049 CONFIG_IS_DOUBLE(tmp->publickeys);
1050 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
1051 (void *)&config->server->repository, NULL,
1052 SILC_SKR_USAGE_AUTH |
1053 SILC_SKR_USAGE_KEY_AGREEMENT, NULL)) {
1054 got_errno = SILC_CONFIG_EPRINTLINE;
1057 tmp->publickeys = TRUE;
1059 else if (!strcmp(name, "params")) {
1060 CONFIG_IS_DOUBLE(tmp->param);
1061 tmp->param = my_find_param(config, (char *) val);
1062 if (!tmp->param) { /* error message already output */
1063 got_errno = SILC_CONFIG_EPRINTLINE;
1067 else if (!strcmp(name, "backup")) {
1068 tmp->backup_router = *(SilcBool *)val;
1071 return SILC_CONFIG_EINTERNAL;
1073 return SILC_CONFIG_OK;
1076 silc_free(tmp->host);
1077 CONFIG_FREE_AUTH(tmp);
1083 SILC_CONFIG_CALLBACK(fetch_router)
1085 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigRouter);
1087 SERVER_CONFIG_DEBUG(("Received ROUTER type=%d name=\"%s\" (val=%x)",
1088 type, name, context));
1089 if (type == SILC_CONFIG_ARG_BLOCK) {
1090 if (!tmp) /* discard empty sub-blocks */
1091 return SILC_CONFIG_OK;
1093 got_errno = SILC_CONFIG_EMISSFIELDS;
1097 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->routers);
1099 return SILC_CONFIG_OK;
1101 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigRouter);
1103 /* Identify and save this value */
1104 if (!strcmp(name, "host")) {
1105 CONFIG_IS_DOUBLE(tmp->host);
1106 tmp->host = strdup((char *) val);
1108 else if (!strcmp(name, "port")) {
1109 int port = *(int *)val;
1110 if ((port <= 0) || (port > 65535)) {
1111 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
1112 "Invalid port number!"));
1113 got_errno = SILC_CONFIG_EPRINTLINE;
1116 tmp->port = (SilcUInt16) port;
1118 else if (!strcmp(name, "passphrase")) {
1119 CONFIG_IS_DOUBLE(tmp->passphrase);
1120 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
1121 (void *)&tmp->passphrase,
1122 &tmp->passphrase_len, 0, NULL)) {
1123 got_errno = SILC_CONFIG_EPRINTLINE;
1127 else if (!strcmp(name, "publickey")) {
1128 CONFIG_IS_DOUBLE(tmp->publickeys);
1129 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
1130 (void *)&config->server->repository, NULL,
1131 SILC_SKR_USAGE_AUTH |
1132 SILC_SKR_USAGE_KEY_AGREEMENT, NULL)) {
1133 got_errno = SILC_CONFIG_EPRINTLINE;
1136 tmp->publickeys = TRUE;
1138 else if (!strcmp(name, "params")) {
1139 CONFIG_IS_DOUBLE(tmp->param);
1140 tmp->param = my_find_param(config, (char *) val);
1141 if (!tmp->param) { /* error message already output */
1142 got_errno = SILC_CONFIG_EPRINTLINE;
1146 else if (!strcmp(name, "initiator")) {
1147 tmp->initiator = *(SilcBool *)val;
1149 else if (!strcmp(name, "backuphost")) {
1150 CONFIG_IS_DOUBLE(tmp->backup_replace_ip);
1151 tmp->backup_replace_ip = (*(char *)val ? strdup((char *) val) :
1153 tmp->backup_router = TRUE;
1155 else if (!strcmp(name, "backupport")) {
1156 int port = *(int *)val;
1157 if ((port <= 0) || (port > 65535)) {
1158 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
1159 "Invalid port number!"));
1160 got_errno = SILC_CONFIG_EPRINTLINE;
1163 tmp->backup_replace_port = (SilcUInt16) port;
1165 else if (!strcmp(name, "backuplocal")) {
1166 tmp->backup_local = *(SilcBool *)val;
1168 else if (!strcmp(name, "dynamic_connection")) {
1169 tmp->dynamic_connection = *(SilcBool *)val;
1172 return SILC_CONFIG_EINTERNAL;
1174 return SILC_CONFIG_OK;
1177 silc_free(tmp->host);
1178 silc_free(tmp->backup_replace_ip);
1179 CONFIG_FREE_AUTH(tmp);
1185 /* known config options tables */
1186 static const SilcConfigTable table_general[] = {
1187 { "prefer_passphrase_auth", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1188 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1189 { "connections_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1190 { "connections_max_per_host", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1191 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1192 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1193 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1194 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1195 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1196 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1197 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1198 { "channel_rekey_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1199 { "key_exchange_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1200 { "conn_auth_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1201 { "version_protocol", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1202 { "version_software", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1203 { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1204 { "detach_disabled", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1205 { "detach_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1206 { "qos", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1207 { "qos_rate_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1208 { "qos_bytes_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1209 { "qos_limit_sec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1210 { "qos_limit_usec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1211 { "channel_join_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1212 { "debug_string", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1213 { "http_server", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1214 { "http_server_ip", SILC_CONFIG_ARG_STRE, fetch_generic, NULL },
1215 { "http_server_port", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1216 { "dynamic_server", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1217 { "local_channels", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1221 static const SilcConfigTable table_cipher[] = {
1222 { "name", SILC_CONFIG_ARG_STR, fetch_cipher, NULL },
1223 { "keylength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1224 { "blocklength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1228 static const SilcConfigTable table_hash[] = {
1229 { "name", SILC_CONFIG_ARG_STR, fetch_hash, NULL },
1230 { "blocklength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1231 { "digestlength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1235 static const SilcConfigTable table_hmac[] = {
1236 { "name", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1237 { "hash", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1238 { "maclength", SILC_CONFIG_ARG_INT, fetch_hmac, NULL },
1242 static const SilcConfigTable table_pkcs[] = {
1243 { "name", SILC_CONFIG_ARG_STR, fetch_pkcs, NULL },
1247 static const SilcConfigTable table_serverinfo_c[] = {
1248 { "ip", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1249 { "public_ip", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1250 { "port", SILC_CONFIG_ARG_INT, fetch_serverinfo, NULL},
1254 static const SilcConfigTable table_serverinfo[] = {
1255 { "hostname", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1256 { "primary", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo_c},
1257 { "secondary", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo_c},
1258 { "servertype", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1259 { "location", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1260 { "admin", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1261 { "adminemail", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1262 { "user", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1263 { "group", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1264 { "publickey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1265 { "privatekey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1266 { "motdfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1267 { "pidfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1271 static const SilcConfigTable table_logging_c[] = {
1272 { "file", SILC_CONFIG_ARG_STR, fetch_logging, NULL },
1273 { "size", SILC_CONFIG_ARG_SIZE, fetch_logging, NULL },
1274 /*{ "quicklog", SILC_CONFIG_ARG_NONE, fetch_logging, NULL }, */
1278 static const SilcConfigTable table_logging[] = {
1279 { "timestamp", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1280 { "quicklogs", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1281 { "flushdelay", SILC_CONFIG_ARG_INT, fetch_logging, NULL },
1282 { "info", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1283 { "warnings", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1284 { "errors", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1285 { "fatals", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1289 static const SilcConfigTable table_connparam[] = {
1290 { "name", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1291 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1292 { "connections_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1293 { "connections_max_per_host",SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1294 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1295 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1296 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1297 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1298 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1299 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1300 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1301 { "version_protocol", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1302 { "version_software", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1303 { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1304 { "anonymous", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1305 { "qos", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1306 { "qos_rate_limit", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1307 { "qos_bytes_limit", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1308 { "qos_limit_sec", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1309 { "qos_limit_usec", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1313 static const SilcConfigTable table_client[] = {
1314 { "host", SILC_CONFIG_ARG_STRE, fetch_client, NULL },
1315 { "passphrase", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1316 { "publickey", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1317 { "publickeydir", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1318 { "params", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1322 static const SilcConfigTable table_admin[] = {
1323 { "host", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1324 { "user", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1325 { "nick", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1326 { "passphrase", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1327 { "publickey", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1328 { "port", SILC_CONFIG_ARG_INT, fetch_admin, NULL },
1329 { "params", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1333 static const SilcConfigTable table_deny[] = {
1334 { "host", SILC_CONFIG_ARG_STRE, fetch_deny, NULL },
1335 { "reason", SILC_CONFIG_ARG_STR, fetch_deny, NULL },
1339 static const SilcConfigTable table_serverconn[] = {
1340 { "host", SILC_CONFIG_ARG_STRE, fetch_server, NULL },
1341 { "passphrase", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1342 { "publickey", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1343 { "params", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1344 { "backup", SILC_CONFIG_ARG_TOGGLE, fetch_server, NULL },
1348 static const SilcConfigTable table_routerconn[] = {
1349 { "host", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1350 { "port", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1351 { "passphrase", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1352 { "publickey", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1353 { "params", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1354 { "initiator", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1355 { "backuphost", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1356 { "backupport", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1357 { "backuplocal", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1358 { "dynamic_connection", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1362 static const SilcConfigTable table_main[] = {
1363 { "cipher", SILC_CONFIG_ARG_BLOCK, fetch_cipher, table_cipher },
1364 { "hash", SILC_CONFIG_ARG_BLOCK, fetch_hash, table_hash },
1365 { "hmac", SILC_CONFIG_ARG_BLOCK, fetch_hmac, table_hmac },
1366 { "pkcs", SILC_CONFIG_ARG_BLOCK, fetch_pkcs, table_pkcs },
1367 { "general", SILC_CONFIG_ARG_BLOCK, NULL, table_general },
1368 { "serverinfo", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo },
1369 { "logging", SILC_CONFIG_ARG_BLOCK, NULL, table_logging },
1370 { "connectionparams", SILC_CONFIG_ARG_BLOCK, fetch_connparam, table_connparam },
1371 { "client", SILC_CONFIG_ARG_BLOCK, fetch_client, table_client },
1372 { "admin", SILC_CONFIG_ARG_BLOCK, fetch_admin, table_admin },
1373 { "deny", SILC_CONFIG_ARG_BLOCK, fetch_deny, table_deny },
1374 { "serverconnection", SILC_CONFIG_ARG_BLOCK, fetch_server, table_serverconn },
1375 { "routerconnection", SILC_CONFIG_ARG_BLOCK, fetch_router, table_routerconn },
1379 /* Set default values to stuff that was not configured. */
1381 static void silc_server_config_set_defaults(SilcServerConfig config)
1383 my_set_param_defaults(&config->param, NULL);
1385 config->channel_rekey_secs = (config->channel_rekey_secs ?
1386 config->channel_rekey_secs :
1387 SILC_SERVER_CHANNEL_REKEY);
1388 config->key_exchange_timeout = (config->key_exchange_timeout ?
1389 config->key_exchange_timeout :
1390 SILC_SERVER_SKE_TIMEOUT);
1391 config->conn_auth_timeout = (config->conn_auth_timeout ?
1392 config->conn_auth_timeout :
1393 SILC_SERVER_CONNAUTH_TIMEOUT);
1396 /* Check for correctness of the configuration */
1398 static SilcBool silc_server_config_check(SilcServerConfig config)
1400 SilcBool ret = TRUE;
1401 SilcServerConfigServer *s;
1402 SilcServerConfigRouter *r;
1405 /* ServerConfig is mandatory */
1406 if (!config->server_info) {
1407 SILC_SERVER_LOG_ERROR(("\nError: Missing mandatory block `ServerInfo'"));
1411 if (!config->server_info->public_key ||
1412 !config->server_info->private_key) {
1413 SILC_SERVER_LOG_ERROR(("\nError: Server keypair is missing"));
1417 if (!config->server_info->primary) {
1418 SILC_SERVER_LOG_ERROR(("\nError: Missing mandatory block `Primary' "
1419 "in `ServerInfo'"));
1423 if (!config->server_info->primary->server_ip) {
1424 SILC_SERVER_LOG_ERROR(("\nError: Missing mandatory field `Ip' "
1425 "in `Primary' in `ServerInfo'"));
1429 /* RouterConnection sanity checks */
1431 if (config->routers && config->routers->backup_router == TRUE &&
1433 SILC_SERVER_LOG_ERROR((
1434 "\nError: First RouterConnection block must be primary router "
1435 "connection. You have marked it incorrectly as backup router."));
1438 if (config->routers && config->routers->backup_router == TRUE &&
1439 !config->servers && !config->routers->next) {
1440 SILC_SERVER_LOG_ERROR((
1441 "\nError: You have configured backup router but not primary router. "
1442 "If backup router is configured also primary router must be "
1447 /* Backup router sanity checks */
1449 for (r = config->routers; r; r = r->next) {
1450 if (r->backup_router && !strcmp(r->host, r->backup_replace_ip)) {
1451 SILC_SERVER_LOG_ERROR((
1452 "\nError: Backup router connection incorrectly configured to use "
1453 "primary and backup router as same host `%s'. They must not be "
1454 "same host.", r->host));
1458 if (r->initiator == FALSE && r->port != 0) {
1459 SILC_SERVER_LOG_WARNING(("\nWarning: Initiator is FALSE and Port is "
1460 "specified. Ignoring Port value."));
1465 /* ServerConnection sanity checks */
1467 for (s = config->servers; s; s = s->next) {
1468 if (s->backup_router) {
1474 for (s = config->servers; s; s = s->next) {
1475 if (!s->backup_router) {
1476 SILC_SERVER_LOG_ERROR((
1477 "\nError: Your server is backup router but not all ServerConnection "
1478 "blocks were marked as backup connections. They all must be "
1479 "marked as backup connections."));
1489 /* Allocates a new configuration object, opens configuration file and
1490 parses it. The parsed data is returned to the newly allocated
1491 configuration object. The SilcServerConfig must be freed by calling
1492 the silc_server_config_destroy function. */
1494 SilcServerConfig silc_server_config_alloc(const char *filename,
1497 SilcServerConfig config_new;
1498 SilcConfigEntity ent;
1499 SilcConfigFile *file;
1501 SILC_LOG_DEBUG(("Loading config data from `%s'", filename));
1503 /* alloc a config object */
1504 config_new = silc_calloc(1, sizeof(*config_new));
1508 /* general config defaults */
1509 config_new->refcount = 1;
1510 config_new->logging_timestamp = TRUE;
1511 config_new->param.reconnect_keep_trying = TRUE;
1512 config_new->server = server;
1514 /* obtain a config file object */
1515 file = silc_config_open(filename);
1517 SILC_SERVER_LOG_ERROR(("\nError: can't open config file `%s'",
1522 /* obtain a SilcConfig entity, we can use it to start the parsing */
1523 ent = silc_config_init(file);
1525 /* load the known configuration options, give our empty object as context */
1526 silc_config_register_table(ent, table_main, (void *) config_new);
1528 /* enter the main parsing loop. When this returns, we have the parsing
1529 * result and the object filled (or partially, in case of errors). */
1530 ret = silc_config_main(ent);
1531 SILC_LOG_DEBUG(("Parser returned [ret=%d]: %s", ret,
1532 silc_config_strerror(ret)));
1534 /* Check if the parser returned errors */
1536 /* handle this special error return which asks to quietly return */
1537 if (ret != SILC_CONFIG_ESILENT) {
1538 char *linebuf, *filename = silc_config_get_filename(file);
1539 SilcUInt32 line = silc_config_get_line(file);
1540 if (ret != SILC_CONFIG_EPRINTLINE)
1541 SILC_SERVER_LOG_ERROR(("Error while parsing config file: %s.",
1542 silc_config_strerror(ret)));
1543 linebuf = silc_config_read_line(file, line);
1545 SILC_SERVER_LOG_ERROR((" file %s line %u: %s\n", filename,
1550 silc_server_config_destroy(config_new);
1551 silc_config_close(file);
1555 /* close (destroy) the file object */
1556 silc_config_close(file);
1558 /* Check the configuration */
1559 if (!silc_server_config_check(config_new)) {
1560 silc_server_config_destroy(config_new);
1564 /* Set default to configuration parameters */
1565 silc_server_config_set_defaults(config_new);
1570 /* Increments the reference counter of a config object */
1572 void silc_server_config_ref(SilcServerConfigRef *ref, SilcServerConfig config,
1577 ref->config = config;
1578 ref->ref_ptr = ref_ptr;
1579 SILC_LOG_DEBUG(("Referencing config [%p] refcnt %d->%d", config,
1580 config->refcount - 1, config->refcount));
1584 /* Decrements the reference counter of a config object. If the counter
1585 reaches 0, the config object is destroyed. */
1587 void silc_server_config_unref(SilcServerConfigRef *ref)
1590 silc_server_config_destroy(ref->config);
1593 /* Destroy a config object with all his children lists */
1595 void silc_server_config_destroy(SilcServerConfig config)
1600 SILC_LOG_DEBUG(("Unreferencing config [%p] refcnt %d->%d", config,
1601 config->refcount + 1, config->refcount));
1602 if (config->refcount > 0)
1605 SILC_LOG_DEBUG(("Freeing config context"));
1607 /* Destroy general config stuff */
1608 silc_free(config->debug_string);
1609 silc_free(config->param.version_protocol);
1610 silc_free(config->param.version_software);
1611 silc_free(config->param.version_software_vendor);
1612 silc_free(config->httpd_ip);
1614 /* Destroy Logging channels */
1615 if (config->logging_info)
1616 silc_free(config->logging_info->file);
1617 if (config->logging_warnings)
1618 silc_free(config->logging_warnings->file);
1619 if (config->logging_errors)
1620 silc_free(config->logging_errors->file);
1621 if (config->logging_fatals)
1622 silc_free(config->logging_fatals->file);
1623 silc_free(config->logging_info);
1624 silc_free(config->logging_warnings);
1625 silc_free(config->logging_errors);
1626 silc_free(config->logging_fatals);
1628 /* Destroy the ServerInfo struct */
1629 if (config->server_info) {
1630 register SilcServerConfigServerInfo *si = config->server_info;
1631 silc_free(si->server_name);
1633 silc_free(si->primary->server_ip);
1634 silc_free(si->primary);
1636 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServerInfoInterface,
1638 silc_free(di->server_ip);
1641 silc_free(si->server_type);
1642 silc_free(si->location);
1643 silc_free(si->admin);
1644 silc_free(si->email);
1645 silc_free(si->user);
1646 silc_free(si->group);
1647 silc_free(si->motd_file);
1648 silc_free(si->pid_file);
1650 silc_pkcs_public_key_free(si->public_key);
1651 if (si->private_key)
1652 silc_pkcs_private_key_free(si->private_key);
1656 /* Now let's destroy the lists */
1658 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigCipher,
1660 silc_free(di->name);
1663 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHash, config->hash)
1664 silc_free(di->name);
1667 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHmac, config->hmac)
1668 silc_free(di->name);
1669 silc_free(di->hash);
1672 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigPkcs, config->pkcs)
1673 silc_free(di->name);
1676 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigConnParams,
1677 config->conn_params)
1678 silc_free(di->name);
1679 silc_free(di->version_protocol);
1680 silc_free(di->version_software);
1681 silc_free(di->version_software_vendor);
1684 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigClient, config->clients)
1685 silc_free(di->host);
1686 CONFIG_FREE_AUTH(di);
1689 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigAdmin, config->admins)
1690 silc_free(di->host);
1691 silc_free(di->user);
1692 silc_free(di->nick);
1693 CONFIG_FREE_AUTH(di);
1696 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigDeny, config->denied)
1697 silc_free(di->host);
1698 silc_free(di->reason);
1701 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServer,
1703 silc_free(di->host);
1704 CONFIG_FREE_AUTH(di);
1707 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigRouter,
1709 silc_free(di->host);
1710 silc_free(di->backup_replace_ip);
1711 CONFIG_FREE_AUTH(di);
1715 memset(config, 'F', sizeof(*config));
1719 /* Registers configured ciphers. These can then be allocated by the
1720 server when needed. */
1722 SilcBool silc_server_config_register_ciphers(SilcServer server)
1724 SilcServerConfig config = server->config;
1725 SilcServerConfigCipher *cipher = config->cipher;
1726 char *module_path = config->module_path;
1728 SILC_LOG_DEBUG(("Registering configured ciphers"));
1730 if (!cipher) /* any cipher in the config file? */
1734 /* if there isn't a module_path OR there isn't a module sim name try to
1735 * use buil-in functions */
1736 if (!module_path || !cipher->module) {
1738 for (i = 0; silc_default_ciphers[i].name; i++)
1739 if (!strcmp(silc_default_ciphers[i].name, cipher->name)) {
1740 silc_cipher_register((SilcCipherObject *)&silc_default_ciphers[i]);
1743 if (!silc_cipher_is_supported(cipher->name)) {
1744 SILC_LOG_ERROR(("Unknown cipher `%s'", cipher->name));
1745 silc_server_stop(server);
1749 cipher = cipher->next;
1755 /* Registers configured hash functions. These can then be allocated by the
1756 server when needed. */
1758 SilcBool silc_server_config_register_hashfuncs(SilcServer server)
1760 SilcServerConfig config = server->config;
1761 SilcServerConfigHash *hash = config->hash;
1762 char *module_path = config->module_path;
1764 SILC_LOG_DEBUG(("Registering configured hash functions"));
1766 if (!hash) /* any hash func in the config file? */
1770 /* if there isn't a module_path OR there isn't a module sim name try to
1771 * use buil-in functions */
1772 if (!module_path || !hash->module) {
1774 for (i = 0; silc_default_hash[i].name; i++)
1775 if (!strcmp(silc_default_hash[i].name, hash->name)) {
1776 silc_hash_register((SilcHashObject *)&silc_default_hash[i]);
1779 if (!silc_hash_is_supported(hash->name)) {
1780 SILC_LOG_ERROR(("Unknown hash funtion `%s'", hash->name));
1781 silc_server_stop(server);
1791 /* Registers configure HMACs. These can then be allocated by the server
1794 SilcBool silc_server_config_register_hmacs(SilcServer server)
1796 SilcServerConfig config = server->config;
1797 SilcServerConfigHmac *hmac = config->hmac;
1799 SILC_LOG_DEBUG(("Registering configured HMACs"));
1805 SilcHmacObject hmac_obj;
1806 if (!silc_hash_is_supported(hmac->hash)) {
1807 SILC_LOG_ERROR(("Unknown hash function `%s'", hmac->hash));
1808 silc_server_stop(server);
1812 /* Register the HMAC */
1813 memset(&hmac_obj, 0, sizeof(hmac_obj));
1814 hmac_obj.name = hmac->name;
1815 hmac_obj.len = hmac->mac_length;
1816 silc_hmac_register(&hmac_obj);
1824 /* Registers configured PKCS's. */
1826 SilcBool silc_server_config_register_pkcs(SilcServer server)
1831 /* Sets log files where log messages are saved by the server logger. */
1833 void silc_server_config_setlogfiles(SilcServer server)
1835 SilcServerConfig config = server->config;
1836 SilcServerConfigLogging *this;
1838 SILC_LOG_DEBUG(("Setting configured log file names and options"));
1840 silc_log_timestamp(config->logging_timestamp);
1841 silc_log_quick(config->logging_quick);
1842 silc_log_flushdelay(config->logging_flushdelay ?
1843 config->logging_flushdelay :
1844 SILC_SERVER_LOG_FLUSH_DELAY);
1846 if ((this = config->logging_fatals))
1847 silc_log_set_file(SILC_LOG_FATAL, this->file, this->maxsize,
1849 if ((this = config->logging_errors))
1850 silc_log_set_file(SILC_LOG_ERROR, this->file, this->maxsize,
1852 if ((this = config->logging_warnings))
1853 silc_log_set_file(SILC_LOG_WARNING, this->file, this->maxsize,
1855 if ((this = config->logging_info))
1856 silc_log_set_file(SILC_LOG_INFO, this->file, this->maxsize,
1860 /* Returns client authentication information from configuration file by host
1863 SilcServerConfigClient *
1864 silc_server_config_find_client(SilcServer server, char *host)
1866 SilcServerConfig config = server->config;
1867 SilcServerConfigClient *client;
1869 if (!config || !host)
1872 for (client = config->clients; client; client = client->next) {
1873 if (client->host && !silc_string_match(client->host, host))
1878 /* if none matched, then client is already NULL */
1882 /* Returns admin connection configuration by host, username and/or
1885 SilcServerConfigAdmin *
1886 silc_server_config_find_admin(SilcServer server, char *host, char *user,
1889 SilcServerConfig config = server->config;
1890 SilcServerConfigAdmin *admin;
1892 /* make sure we have a value for the matching parameters */
1900 for (admin = config->admins; admin; admin = admin->next) {
1901 if (admin->host && !silc_string_match(admin->host, host))
1903 if (admin->user && !silc_string_match(admin->user, user))
1905 if (admin->nick && !silc_string_match(admin->nick, nick))
1907 /* no checks failed -> this entry matches */
1911 /* if none matched, then admin is already NULL */
1915 /* Returns the denied connection configuration entry by host. */
1917 SilcServerConfigDeny *
1918 silc_server_config_find_denied(SilcServer server, char *host)
1920 SilcServerConfig config = server->config;
1921 SilcServerConfigDeny *deny;
1923 /* make sure we have a value for the matching parameters */
1924 if (!config || !host)
1927 for (deny = config->denied; deny; deny = deny->next) {
1928 if (deny->host && !silc_string_match(deny->host, host))
1933 /* if none matched, then deny is already NULL */
1937 /* Returns server connection info from server configuartion by host
1940 SilcServerConfigServer *
1941 silc_server_config_find_server_conn(SilcServer server, char *host)
1943 SilcServerConfig config = server->config;
1944 SilcServerConfigServer *serv = NULL;
1949 if (!config->servers)
1952 for (serv = config->servers; serv; serv = serv->next) {
1953 if (!silc_string_match(serv->host, host))
1961 /* Returns router connection info from server configuration by
1962 host (name or ip). */
1964 SilcServerConfigRouter *
1965 silc_server_config_find_router_conn(SilcServer server, char *host, int port)
1967 SilcServerConfig config = server->config;
1968 SilcServerConfigRouter *serv = NULL;
1973 if (!config->routers)
1976 for (serv = config->routers; serv; serv = serv->next) {
1977 if (!silc_string_match(serv->host, host))
1979 if (port && serv->port && serv->port != port)
1987 /* Find backup router connection by host (name or ip) */
1989 SilcServerConfigRouter *
1990 silc_server_config_find_backup_conn(SilcServer server, char *host)
1992 SilcServerConfig config = server->config;
1993 SilcServerConfigRouter *serv = NULL;
1998 if (!config->routers)
2001 for (serv = config->routers; serv; serv = serv->next) {
2002 if (!serv->backup_router)
2004 if (!silc_string_match(serv->host, host))
2012 /* Returns TRUE if configuration for a router connection that we are
2013 initiating exists. */
2015 SilcBool silc_server_config_is_primary_route(SilcServer server)
2017 SilcServerConfig config = server->config;
2018 SilcServerConfigRouter *serv = NULL;
2020 SilcBool found = FALSE;
2022 serv = config->routers;
2023 for (i = 0; serv; i++) {
2024 if (serv->initiator == TRUE && serv->backup_router == FALSE) {
2035 /* Returns our primary connection configuration or NULL if we do not
2036 have primary router configured. */
2038 SilcServerConfigRouter *
2039 silc_server_config_get_primary_router(SilcServer server)
2041 SilcServerConfig config = server->config;
2042 SilcServerConfigRouter *serv = NULL;
2045 serv = config->routers;
2046 for (i = 0; serv; i++) {
2047 if (serv->initiator == TRUE && serv->backup_router == FALSE)
2055 /* If we have backup router configured that is going to replace us this
2056 function returns it. */
2058 SilcServerConfigRouter *
2059 silc_server_config_get_backup_router(SilcServer server)
2061 SilcServerConfig config = server->config;
2062 SilcServerConfigRouter *serv = NULL;
2065 if (server->server_type != SILC_ROUTER)
2068 serv = config->routers;
2069 for (i = 0; serv; i++) {
2070 if (serv->initiator == FALSE && serv->backup_router == TRUE &&
2071 serv->backup_local == TRUE &&
2072 !strcmp(server->config->server_info->primary->server_ip,
2073 serv->backup_replace_ip) &&
2074 server->config->server_info->primary->port ==
2075 serv->backup_replace_port)