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;
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);
164 silc_skr_find_set_context(find, key_context ? key_context : (void *)usage);
165 silc_skr_find(skr, NULL, find, my_find_callback, &status);
166 if (status == SILC_SKR_ALREADY_EXIST) {
167 silc_pkcs_public_key_free(public_key);
168 SILC_SERVER_LOG_WARNING(("Warning: public key file \"%s\" already "
169 "configured, ignoring this key", p));
170 return TRUE; /* non fatal error */
173 /* Add the public key to repository */
174 if (silc_skr_add_public_key(skr, public_key, usage,
175 key_context ? key_context : (void *)usage,
176 NULL) != SILC_SKR_OK) {
177 SILC_SERVER_LOG_ERROR(("Error while adding public key \"%s\"", p));
185 static SilcBool my_parse_publickeydir(const char *dirname, void **auth_data,
186 SilcSKRKeyUsage usage)
189 struct dirent *get_file;
192 if (!(dp = opendir(dirname))) {
193 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
194 "Could not open directory \"%s\"", dirname));
198 /* errors are not considered fatal */
199 while ((get_file = readdir(dp))) {
200 const char *filename = get_file->d_name;
202 int dirname_len = strlen(dirname), filename_len = strlen(filename);
203 struct stat check_file;
205 /* Ignore "." and "..", and take files only with ".pub" suffix. */
206 if (!strcmp(filename, ".") || !strcmp(filename, "..") ||
207 (filename_len < 5) || strcmp(filename + filename_len - 4, ".pub"))
210 memset(buf, 0, sizeof(buf));
211 snprintf(buf, sizeof(buf) - 1, "%s%s%s", dirname,
212 (dirname[dirname_len - 1] == '/' ? "" : "/"), filename);
214 if (stat(buf, &check_file) < 0) {
215 SILC_SERVER_LOG_ERROR(("Error stating file %s: %s", buf,
217 } else if (S_ISREG(check_file.st_mode)) {
218 my_parse_authdata(SILC_AUTH_PUBLIC_KEY, buf, auth_data, NULL,
224 SILC_LOG_DEBUG(("Tried to load %d public keys in \"%s\"", total, dirname));
230 SILC_CONFIG_CALLBACK(fetch_generic)
232 SilcServerConfig config = (SilcServerConfig) context;
235 if (!strcmp(name, "module_path")) {
236 CONFIG_IS_DOUBLE(config->module_path);
237 config->module_path = (*(char *)val ? strdup((char *) val) : NULL);
239 else if (!strcmp(name, "prefer_passphrase_auth")) {
240 config->prefer_passphrase_auth = *(SilcBool *)val;
242 else if (!strcmp(name, "require_reverse_lookup")) {
243 config->require_reverse_lookup = *(SilcBool *)val;
245 else if (!strcmp(name, "connections_max")) {
246 config->param.connections_max = (SilcUInt32) *(int *)val;
248 else if (!strcmp(name, "connections_max_per_host")) {
249 config->param.connections_max_per_host = (SilcUInt32) *(int *)val;
251 else if (!strcmp(name, "keepalive_secs")) {
252 config->param.keepalive_secs = (SilcUInt32) *(int *)val;
254 else if (!strcmp(name, "reconnect_count")) {
255 config->param.reconnect_count = (SilcUInt32) *(int *)val;
257 else if (!strcmp(name, "reconnect_interval")) {
258 config->param.reconnect_interval = (SilcUInt32) *(int *)val;
260 else if (!strcmp(name, "reconnect_interval_max")) {
261 config->param.reconnect_interval_max = (SilcUInt32) *(int *)val;
263 else if (!strcmp(name, "reconnect_keep_trying")) {
264 config->param.reconnect_keep_trying = *(SilcBool *)val;
266 else if (!strcmp(name, "key_exchange_rekey")) {
267 config->param.key_exchange_rekey = (SilcUInt32) *(int *)val;
269 else if (!strcmp(name, "key_exchange_pfs")) {
270 config->param.key_exchange_pfs = *(SilcBool *)val;
272 else if (!strcmp(name, "channel_rekey_secs")) {
273 config->channel_rekey_secs = (SilcUInt32) *(int *)val;
275 else if (!strcmp(name, "key_exchange_timeout")) {
276 config->key_exchange_timeout = (SilcUInt32) *(int *)val;
278 else if (!strcmp(name, "conn_auth_timeout")) {
279 config->conn_auth_timeout = (SilcUInt32) *(int *)val;
281 else if (!strcmp(name, "version_protocol")) {
282 CONFIG_IS_DOUBLE(config->param.version_protocol);
283 config->param.version_protocol =
284 (*(char *)val ? strdup((char *) val) : NULL);
286 else if (!strcmp(name, "version_software")) {
287 CONFIG_IS_DOUBLE(config->param.version_software);
288 config->param.version_software =
289 (*(char *)val ? strdup((char *) val) : NULL);
291 else if (!strcmp(name, "version_software_vendor")) {
292 CONFIG_IS_DOUBLE(config->param.version_software_vendor);;
293 config->param.version_software_vendor =
294 (*(char *)val ? strdup((char *) val) : NULL);
296 else if (!strcmp(name, "detach_disabled")) {
297 config->detach_disabled = *(SilcBool *)val;
299 else if (!strcmp(name, "detach_timeout")) {
300 config->detach_timeout = (SilcUInt32) *(int *)val;
302 else if (!strcmp(name, "qos")) {
303 config->param.qos = *(SilcBool *)val;
305 else if (!strcmp(name, "qos_rate_limit")) {
306 config->param.qos_rate_limit = *(SilcUInt32 *)val;
308 else if (!strcmp(name, "qos_bytes_limit")) {
309 config->param.qos_bytes_limit = *(SilcUInt32 *)val;
311 else if (!strcmp(name, "qos_limit_sec")) {
312 config->param.qos_limit_sec = *(SilcUInt32 *)val;
314 else if (!strcmp(name, "qos_limit_usec")) {
315 config->param.qos_limit_usec = *(SilcUInt32 *)val;
317 else if (!strcmp(name, "channel_join_limit")) {
318 config->param.chlimit = *(SilcUInt32 *)val;
320 else if (!strcmp(name, "debug_string")) {
321 CONFIG_IS_DOUBLE(config->debug_string);
322 config->debug_string = (*(char *)val ? strdup((char *) val) : NULL);
324 else if (!strcmp(name, "http_server")) {
325 config->httpd = *(SilcBool *)val;
327 else if (!strcmp(name, "http_server_ip")) {
328 CONFIG_IS_DOUBLE(config->httpd_ip);
329 config->httpd_ip = (*(char *)val ? strdup((char *) val) : NULL);
331 else if (!strcmp(name, "http_server_port")) {
332 int port = *(int *)val;
333 if ((port <= 0) || (port > 65535)) {
334 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
335 "Invalid port number!"));
336 got_errno = SILC_CONFIG_EPRINTLINE;
339 config->httpd_port = (SilcUInt16)port;
341 else if (!strcmp(name, "open_server")) {
342 config->open_server = *(SilcBool *)val;
344 else if (!strcmp(name, "local_channels")) {
345 config->local_channels = *(SilcBool *)val;
348 return SILC_CONFIG_EINTERNAL;
350 return SILC_CONFIG_OK;
356 SILC_CONFIG_CALLBACK(fetch_cipher)
358 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigCipher);
360 SERVER_CONFIG_DEBUG(("Received CIPHER type=%d name=\"%s\" (val=%x)",
361 type, name, context));
362 if (type == SILC_CONFIG_ARG_BLOCK) {
363 /* check the temporary struct's fields */
364 if (!tmp) /* discard empty sub-blocks */
365 return SILC_CONFIG_OK;
367 got_errno = SILC_CONFIG_EMISSFIELDS;
371 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->cipher);
373 return SILC_CONFIG_OK;
375 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigCipher);
377 /* Identify and save this value */
378 if (!strcmp(name, "name")) {
379 CONFIG_IS_DOUBLE(tmp->name);
380 tmp->name = strdup((char *) val);
382 else if (!strcmp(name, "module")) {
383 CONFIG_IS_DOUBLE(tmp->module);
384 tmp->module = (*(char *)val ? strdup((char *) val) : NULL);
386 else if (!strcmp(name, "keylength")) {
387 tmp->key_length = *(SilcUInt32 *)val;
389 else if (!strcmp(name, "blocklength")) {
390 tmp->block_length = *(SilcUInt32 *)val;
393 return SILC_CONFIG_EINTERNAL;
394 return SILC_CONFIG_OK;
397 silc_free(tmp->name);
398 silc_free(tmp->module);
404 SILC_CONFIG_CALLBACK(fetch_hash)
406 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigHash);
408 SERVER_CONFIG_DEBUG(("Received HASH type=%d name=%s (val=%x)",
409 type, name, context));
410 if (type == SILC_CONFIG_ARG_BLOCK) {
411 /* check the temporary struct's fields */
412 if (!tmp) /* discard empty sub-blocks */
413 return SILC_CONFIG_OK;
414 if (!tmp->name || (tmp->block_length == 0) || (tmp->digest_length == 0)) {
415 got_errno = SILC_CONFIG_EMISSFIELDS;
419 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hash);
421 return SILC_CONFIG_OK;
423 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigHash);
425 /* Identify and save this value */
426 if (!strcmp(name, "name")) {
427 CONFIG_IS_DOUBLE(tmp->name);
428 tmp->name = strdup((char *) val);
430 else if (!strcmp(name, "module")) {
431 CONFIG_IS_DOUBLE(tmp->module);
432 tmp->module = (*(char *)val ? strdup((char *) val) : NULL);
434 else if (!strcmp(name, "blocklength")) {
435 tmp->block_length = *(int *)val;
437 else if (!strcmp(name, "digestlength")) {
438 tmp->digest_length = *(int *)val;
441 return SILC_CONFIG_EINTERNAL;
442 return SILC_CONFIG_OK;
445 silc_free(tmp->name);
446 silc_free(tmp->module);
452 SILC_CONFIG_CALLBACK(fetch_hmac)
454 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigHmac);
456 SERVER_CONFIG_DEBUG(("Received HMAC type=%d name=\"%s\" (val=%x)",
457 type, name, context));
458 if (type == SILC_CONFIG_ARG_BLOCK) {
459 /* check the temporary struct's fields */
460 if (!tmp) /* discard empty sub-blocks */
461 return SILC_CONFIG_OK;
462 if (!tmp->name || !tmp->hash || (tmp->mac_length == 0)) {
463 got_errno = SILC_CONFIG_EMISSFIELDS;
467 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hmac);
469 return SILC_CONFIG_OK;
471 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigHmac);
473 /* Identify and save this value */
474 if (!strcmp(name, "name")) {
475 CONFIG_IS_DOUBLE(tmp->name);
476 tmp->name = strdup((char *) val);
478 else if (!strcmp(name, "hash")) {
479 CONFIG_IS_DOUBLE(tmp->hash);
480 tmp->hash = strdup((char *) val);
482 else if (!strcmp(name, "maclength")) {
483 tmp->mac_length = *(int *)val;
486 return SILC_CONFIG_EINTERNAL;
487 return SILC_CONFIG_OK;
490 silc_free(tmp->name);
491 silc_free(tmp->hash);
497 SILC_CONFIG_CALLBACK(fetch_pkcs)
499 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigPkcs);
501 SERVER_CONFIG_DEBUG(("Received PKCS type=%d name=\"%s\" (val=%x)",
502 type, name, context));
503 if (type == SILC_CONFIG_ARG_BLOCK) {
504 /* Check the temporary struct's fields */
505 if (!tmp) /* discard empty sub-blocks */
506 return SILC_CONFIG_OK;
508 got_errno = SILC_CONFIG_EMISSFIELDS;
512 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->pkcs);
514 return SILC_CONFIG_OK;
516 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigPkcs);
518 /* Identify and save this value */
519 if (!strcmp(name, "name")) {
520 CONFIG_IS_DOUBLE(tmp->name);
521 tmp->name = strdup((char *) val);
524 return SILC_CONFIG_EINTERNAL;
525 return SILC_CONFIG_OK;
528 silc_free(tmp->name);
534 SILC_CONFIG_CALLBACK(fetch_serverinfo)
536 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServerInfoInterface);
537 SilcServerConfigServerInfo *server_info = config->server_info;
539 SERVER_CONFIG_DEBUG(("Received SERVERINFO type=%d name=\"%s\" (val=%x)",
540 type, name, context));
542 /* If there isn't the main struct alloc it */
544 config->server_info = server_info = (SilcServerConfigServerInfo *)
545 silc_calloc(1, sizeof(*server_info));
547 if (type == SILC_CONFIG_ARG_BLOCK) {
548 if (!strcmp(name, "primary")) {
549 if (server_info->primary) {
550 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
551 "Double primary specification."));
552 got_errno = SILC_CONFIG_EPRINTLINE;
555 CONFIG_IS_DOUBLE(server_info->primary);
557 /* now check the temporary struct, don't accept empty block and
558 make sure all fields are there */
559 if (!tmp || !tmp->server_ip || !tmp->port) {
560 got_errno = SILC_CONFIG_EMISSFIELDS;
563 server_info->primary = tmp;
565 return SILC_CONFIG_OK;
566 } else if (!strcmp(name, "secondary")) {
568 return SILC_CONFIG_OK;
569 if (!tmp || !tmp->server_ip || !tmp->port) {
570 got_errno = SILC_CONFIG_EMISSFIELDS;
573 SILC_SERVER_CONFIG_LIST_APPENDTMP(server_info->secondary);
575 return SILC_CONFIG_OK;
576 } else if (!server_info->public_key || !server_info->private_key) {
577 got_errno = SILC_CONFIG_EMISSFIELDS;
580 return SILC_CONFIG_OK;
582 if (!strcmp(name, "hostname")) {
583 CONFIG_IS_DOUBLE(server_info->server_name);
584 server_info->server_name = strdup((char *) val);
586 else if (!strcmp(name, "ip")) {
587 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
588 CONFIG_IS_DOUBLE(tmp->server_ip);
589 tmp->server_ip = strdup((char *) val);
591 else if (!strcmp(name, "public_ip")) {
592 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
593 CONFIG_IS_DOUBLE(tmp->public_ip);
594 tmp->public_ip = strdup((char *) val);
596 else if (!strcmp(name, "port")) {
597 int port = *(int *)val;
598 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
599 if ((port <= 0) || (port > 65535)) {
600 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
601 "Invalid port number!"));
602 got_errno = SILC_CONFIG_EPRINTLINE;
605 tmp->port = (SilcUInt16) port;
607 else if (!strcmp(name, "servertype")) {
608 CONFIG_IS_DOUBLE(server_info->server_type);
609 server_info->server_type = strdup((char *) val);
611 else if (!strcmp(name, "admin")) {
612 CONFIG_IS_DOUBLE(server_info->admin);
613 server_info->admin = strdup((char *) val);
615 else if (!strcmp(name, "adminemail")) {
616 CONFIG_IS_DOUBLE(server_info->email);
617 server_info->email = strdup((char *) val);
619 else if (!strcmp(name, "location")) {
620 CONFIG_IS_DOUBLE(server_info->location);
621 server_info->location = strdup((char *) val);
623 else if (!strcmp(name, "user")) {
624 CONFIG_IS_DOUBLE(server_info->user);
625 server_info->user = strdup((char *) val);
627 else if (!strcmp(name, "group")) {
628 CONFIG_IS_DOUBLE(server_info->group);
629 server_info->group = strdup((char *) val);
631 else if (!strcmp(name, "motdfile")) {
632 CONFIG_IS_DOUBLE(server_info->motd_file);
633 server_info->motd_file = strdup((char *) val);
635 else if (!strcmp(name, "pidfile")) {
636 CONFIG_IS_DOUBLE(server_info->pid_file);
637 server_info->pid_file = strdup((char *) val);
639 else if (!strcmp(name, "publickey")) {
640 char *file_tmp = (char *) val;
641 CONFIG_IS_DOUBLE(server_info->public_key);
643 /* Try to load specified file, if fail stop config parsing */
644 if (!silc_pkcs_load_public_key(file_tmp, &server_info->public_key)) {
645 SILC_SERVER_LOG_ERROR(("Error: Could not load public key file."));
646 return SILC_CONFIG_EPRINTLINE;
649 else if (!strcmp(name, "privatekey")) {
651 char *file_tmp = (char *) val;
652 CONFIG_IS_DOUBLE(server_info->private_key);
654 /* Check the private key file permissions. */
655 if ((stat(file_tmp, &st)) != -1) {
656 if ((st.st_mode & 0777) != 0600) {
657 SILC_SERVER_LOG_ERROR(("Wrong permissions in private key "
658 "file \"%s\". The permissions must be "
660 return SILC_CONFIG_ESILENT;
664 /* Try to load specified file, if fail stop config parsing */
665 if (!silc_pkcs_load_private_key(file_tmp, "", 0,
666 &server_info->private_key)) {
667 SILC_SERVER_LOG_ERROR(("Error: Could not load private key file."));
668 return SILC_CONFIG_EPRINTLINE;
672 return SILC_CONFIG_EINTERNAL;
673 return SILC_CONFIG_OK;
676 /* Here we need to check if tmp exists because this function handles
677 * misc data (multiple fields and single-only fields) */
679 silc_free(tmp->server_ip);
686 SILC_CONFIG_CALLBACK(fetch_logging)
688 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigLogging);
690 if (!strcmp(name, "timestamp")) {
691 config->logging_timestamp = *(SilcBool *)val;
693 else if (!strcmp(name, "quicklogs")) {
694 config->logging_quick = *(SilcBool *)val;
696 else if (!strcmp(name, "flushdelay")) {
697 int flushdelay = *(int *)val;
698 if (flushdelay < 2) { /* this value was taken from silclog.h (min delay) */
699 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
700 "Invalid flushdelay value, use quicklogs if you "
701 "want real-time logging."));
702 return SILC_CONFIG_EPRINTLINE;
704 config->logging_flushdelay = (long) flushdelay;
707 /* The following istances happens only in Logging's sub-blocks, a match
708 for the sub-block name means that you should store the filename/maxsize
709 temporary struct to the proper logging channel.
710 If we get a match for "file" or "maxsize" this means that we are inside
711 a sub-sub-block and it is safe to alloc a new tmp. */
712 #define FETCH_LOGGING_CHAN(__chan__, __member__) \
713 else if (!strcmp(name, __chan__)) { \
714 if (!tmp) return SILC_CONFIG_OK; \
716 got_errno = SILC_CONFIG_EMISSFIELDS; goto got_err; \
718 config->__member__ = tmp; \
719 config->tmp = NULL; \
721 FETCH_LOGGING_CHAN("info", logging_info)
722 FETCH_LOGGING_CHAN("warnings", logging_warnings)
723 FETCH_LOGGING_CHAN("errors", logging_errors)
724 FETCH_LOGGING_CHAN("fatals", logging_fatals)
725 #undef FETCH_LOGGING_CHAN
726 else if (!strcmp(name, "file")) {
727 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigLogging);
728 CONFIG_IS_DOUBLE(tmp->file);
729 tmp->file = strdup((char *) val);
731 else if (!strcmp(name, "size")) {
733 config->tmp = silc_calloc(1, sizeof(*tmp));
734 tmp = (SilcServerConfigLogging *) config->tmp;
736 tmp->maxsize = *(SilcUInt32 *) val;
739 return SILC_CONFIG_EINTERNAL;
740 return SILC_CONFIG_OK;
743 silc_free(tmp->file);
749 SILC_CONFIG_CALLBACK(fetch_connparam)
751 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigConnParams);
753 SERVER_CONFIG_DEBUG(("Received CONNPARAM type=%d name=\"%s\" (val=%x)",
754 type, name, context));
755 if (type == SILC_CONFIG_ARG_BLOCK) {
756 /* check the temporary struct's fields */
757 if (!tmp) /* discard empty sub-blocks */
758 return SILC_CONFIG_OK;
760 got_errno = SILC_CONFIG_EMISSFIELDS;
764 my_set_param_defaults(tmp, &config->param);
766 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->conn_params);
768 return SILC_CONFIG_OK;
771 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigConnParams);
772 tmp->reconnect_keep_trying = TRUE;
775 if (!strcmp(name, "name")) {
776 CONFIG_IS_DOUBLE(tmp->name);
777 tmp->name = (*(char *)val ? strdup((char *) val) : NULL);
779 else if (!strcmp(name, "connections_max")) {
780 tmp->connections_max = *(SilcUInt32 *)val;
782 else if (!strcmp(name, "connections_max_per_host")) {
783 tmp->connections_max_per_host = *(SilcUInt32 *)val;
785 else if (!strcmp(name, "keepalive_secs")) {
786 tmp->keepalive_secs = *(SilcUInt32 *)val;
788 else if (!strcmp(name, "reconnect_count")) {
789 tmp->reconnect_count = *(SilcUInt32 *)val;
791 else if (!strcmp(name, "reconnect_interval")) {
792 tmp->reconnect_interval = *(SilcUInt32 *)val;
794 else if (!strcmp(name, "reconnect_interval_max")) {
795 tmp->reconnect_interval_max = *(SilcUInt32 *)val;
797 else if (!strcmp(name, "reconnect_keep_trying")) {
798 tmp->reconnect_keep_trying = *(SilcBool *)val;
800 else if (!strcmp(name, "key_exchange_rekey")) {
801 tmp->key_exchange_rekey = *(SilcUInt32 *)val;
803 else if (!strcmp(name, "key_exchange_pfs")) {
804 tmp->key_exchange_pfs = *(SilcBool *)val;
806 else if (!strcmp(name, "version_protocol")) {
807 CONFIG_IS_DOUBLE(tmp->version_protocol);
808 tmp->version_protocol = (*(char *)val ? strdup((char *) val) : NULL);
810 else if (!strcmp(name, "version_software")) {
811 CONFIG_IS_DOUBLE(tmp->version_software);
812 tmp->version_software = (*(char *)val ? strdup((char *) val) : NULL);
814 else if (!strcmp(name, "version_software_vendor")) {
815 CONFIG_IS_DOUBLE(tmp->version_software_vendor);;
816 tmp->version_software_vendor =
817 (*(char *)val ? strdup((char *) val) : NULL);
819 else if (!strcmp(name, "anonymous")) {
820 tmp->anonymous = *(SilcBool *)val;
822 else if (!strcmp(name, "qos")) {
823 tmp->qos = *(SilcBool *)val;
825 else if (!strcmp(name, "qos_rate_limit")) {
826 tmp->qos_rate_limit = *(SilcUInt32 *)val;
828 else if (!strcmp(name, "qos_bytes_limit")) {
829 tmp->qos_bytes_limit = *(SilcUInt32 *)val;
831 else if (!strcmp(name, "qos_limit_sec")) {
832 tmp->qos_limit_sec = *(SilcUInt32 *)val;
834 else if (!strcmp(name, "qos_limit_usec")) {
835 tmp->qos_limit_usec = *(SilcUInt32 *)val;
838 return SILC_CONFIG_EINTERNAL;
840 return SILC_CONFIG_OK;
843 silc_free(tmp->name);
849 SILC_CONFIG_CALLBACK(fetch_client)
851 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigClient);
853 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
854 type, name, context));
856 /* Alloc before block checking, because empty sub-blocks are welcome here */
857 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigClient);
859 if (type == SILC_CONFIG_ARG_BLOCK) {
860 /* empty sub-blocks are welcome */
861 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->clients);
863 return SILC_CONFIG_OK;
866 /* Identify and save this value */
867 if (!strcmp(name, "host")) {
868 CONFIG_IS_DOUBLE(tmp->host);
869 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
871 else if (!strcmp(name, "passphrase")) {
872 CONFIG_IS_DOUBLE(tmp->passphrase);
873 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
874 (void *)&tmp->passphrase,
875 &tmp->passphrase_len, 0, NULL)) {
876 got_errno = SILC_CONFIG_EPRINTLINE;
880 else if (!strcmp(name, "publickey")) {
881 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
882 (void *)&config->server->repository, NULL,
883 SILC_SKR_USAGE_KEY_AGREEMENT, NULL)) {
884 got_errno = SILC_CONFIG_EPRINTLINE;
888 else if (!strcmp(name, "publickeydir")) {
889 if (!my_parse_publickeydir((char *) val,
890 (void *)&config->server->repository,
891 SILC_SKR_USAGE_KEY_AGREEMENT)) {
892 got_errno = SILC_CONFIG_EPRINTLINE;
896 else if (!strcmp(name, "params")) {
897 CONFIG_IS_DOUBLE(tmp->param);
898 tmp->param = my_find_param(config, (char *) val);
899 if (!tmp->param) { /* error message already output */
900 got_errno = SILC_CONFIG_EPRINTLINE;
905 return SILC_CONFIG_EINTERNAL;
906 return SILC_CONFIG_OK;
909 silc_free(tmp->host);
910 CONFIG_FREE_AUTH(tmp);
916 SILC_CONFIG_CALLBACK(fetch_admin)
918 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigAdmin);
920 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
921 type, name, context));
922 if (type == SILC_CONFIG_ARG_BLOCK) {
923 /* check the temporary struct's fields */
924 if (!tmp) /* discard empty sub-blocks */
925 return SILC_CONFIG_OK;
927 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->admins);
929 return SILC_CONFIG_OK;
931 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigAdmin);
933 /* Identify and save this value */
934 if (!strcmp(name, "host")) {
935 CONFIG_IS_DOUBLE(tmp->host);
936 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
938 else if (!strcmp(name, "user")) {
939 CONFIG_IS_DOUBLE(tmp->user);
940 tmp->user = (*(char *)val ? strdup((char *) val) : NULL);
942 else if (!strcmp(name, "nick")) {
943 CONFIG_IS_DOUBLE(tmp->nick);
944 tmp->nick = (*(char *)val ? strdup((char *) val) : NULL);
946 else if (!strcmp(name, "passphrase")) {
947 CONFIG_IS_DOUBLE(tmp->passphrase);
948 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
949 (void *)&tmp->passphrase,
950 &tmp->passphrase_len, 0, NULL)) {
951 got_errno = SILC_CONFIG_EPRINTLINE;
955 else if (!strcmp(name, "publickey")) {
956 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
957 (void *)&config->server->repository, NULL,
958 SILC_SKR_USAGE_SERVICE_AUTHORIZATION, tmp)) {
959 got_errno = SILC_CONFIG_EPRINTLINE;
964 return SILC_CONFIG_EINTERNAL;
965 return SILC_CONFIG_OK;
968 silc_free(tmp->host);
969 silc_free(tmp->user);
970 silc_free(tmp->nick);
971 CONFIG_FREE_AUTH(tmp);
977 SILC_CONFIG_CALLBACK(fetch_deny)
979 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigDeny);
981 SERVER_CONFIG_DEBUG(("Received DENY type=%d name=\"%s\" (val=%x)",
982 type, name, context));
983 if (type == SILC_CONFIG_ARG_BLOCK) {
984 /* check the temporary struct's fields */
985 if (!tmp) /* discard empty sub-blocks */
986 return SILC_CONFIG_OK;
988 got_errno = SILC_CONFIG_EMISSFIELDS;
992 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->denied);
994 return SILC_CONFIG_OK;
996 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigDeny);
998 /* Identify and save this value */
999 if (!strcmp(name, "host")) {
1000 CONFIG_IS_DOUBLE(tmp->host);
1001 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
1003 else if (!strcmp(name, "reason")) {
1004 CONFIG_IS_DOUBLE(tmp->reason);
1005 tmp->reason = strdup((char *) val);
1008 return SILC_CONFIG_EINTERNAL;
1009 return SILC_CONFIG_OK;
1012 silc_free(tmp->host);
1013 silc_free(tmp->reason);
1019 SILC_CONFIG_CALLBACK(fetch_server)
1021 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServer);
1023 SERVER_CONFIG_DEBUG(("Received SERVER type=%d name=\"%s\" (val=%x)",
1024 type, name, context));
1025 if (type == SILC_CONFIG_ARG_BLOCK) {
1026 /* check the temporary struct's fields */
1027 if (!tmp) /* discard empty sub-blocks */
1028 return SILC_CONFIG_OK;
1030 got_errno = SILC_CONFIG_EMISSFIELDS;
1034 /* the temporary struct is ok, append it to the list */
1035 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->servers);
1037 return SILC_CONFIG_OK;
1039 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServer);
1041 /* Identify and save this value */
1042 if (!strcmp(name, "host")) {
1043 CONFIG_IS_DOUBLE(tmp->host);
1044 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
1046 else if (!strcmp(name, "passphrase")) {
1047 CONFIG_IS_DOUBLE(tmp->passphrase);
1048 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
1049 (void *)&tmp->passphrase,
1050 &tmp->passphrase_len, 0, NULL)) {
1051 got_errno = SILC_CONFIG_EPRINTLINE;
1055 else if (!strcmp(name, "publickey")) {
1056 CONFIG_IS_DOUBLE(tmp->publickeys);
1057 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
1058 (void *)&config->server->repository, NULL,
1059 SILC_SKR_USAGE_KEY_AGREEMENT, NULL)) {
1060 got_errno = SILC_CONFIG_EPRINTLINE;
1064 else if (!strcmp(name, "params")) {
1065 CONFIG_IS_DOUBLE(tmp->param);
1066 tmp->param = my_find_param(config, (char *) val);
1067 if (!tmp->param) { /* error message already output */
1068 got_errno = SILC_CONFIG_EPRINTLINE;
1072 else if (!strcmp(name, "backup")) {
1073 tmp->backup_router = *(SilcBool *)val;
1076 return SILC_CONFIG_EINTERNAL;
1078 return SILC_CONFIG_OK;
1081 silc_free(tmp->host);
1082 CONFIG_FREE_AUTH(tmp);
1088 SILC_CONFIG_CALLBACK(fetch_router)
1090 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigRouter);
1092 SERVER_CONFIG_DEBUG(("Received ROUTER type=%d name=\"%s\" (val=%x)",
1093 type, name, context));
1094 if (type == SILC_CONFIG_ARG_BLOCK) {
1095 if (!tmp) /* discard empty sub-blocks */
1096 return SILC_CONFIG_OK;
1098 got_errno = SILC_CONFIG_EMISSFIELDS;
1102 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->routers);
1104 return SILC_CONFIG_OK;
1106 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigRouter);
1108 /* Identify and save this value */
1109 if (!strcmp(name, "host")) {
1110 CONFIG_IS_DOUBLE(tmp->host);
1111 tmp->host = strdup((char *) val);
1113 else if (!strcmp(name, "port")) {
1114 int port = *(int *)val;
1115 if ((port <= 0) || (port > 65535)) {
1116 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
1117 "Invalid port number!"));
1118 got_errno = SILC_CONFIG_EPRINTLINE;
1121 tmp->port = (SilcUInt16) port;
1123 else if (!strcmp(name, "passphrase")) {
1124 CONFIG_IS_DOUBLE(tmp->passphrase);
1125 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
1126 (void *)&tmp->passphrase,
1127 &tmp->passphrase_len, 0, NULL)) {
1128 got_errno = SILC_CONFIG_EPRINTLINE;
1132 else if (!strcmp(name, "publickey")) {
1133 CONFIG_IS_DOUBLE(tmp->publickeys);
1134 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
1135 (void *)&config->server->repository, NULL,
1136 SILC_SKR_USAGE_KEY_AGREEMENT, NULL)) {
1137 got_errno = SILC_CONFIG_EPRINTLINE;
1141 else if (!strcmp(name, "params")) {
1142 CONFIG_IS_DOUBLE(tmp->param);
1143 tmp->param = my_find_param(config, (char *) val);
1144 if (!tmp->param) { /* error message already output */
1145 got_errno = SILC_CONFIG_EPRINTLINE;
1149 else if (!strcmp(name, "initiator")) {
1150 tmp->initiator = *(SilcBool *)val;
1152 else if (!strcmp(name, "backuphost")) {
1153 CONFIG_IS_DOUBLE(tmp->backup_replace_ip);
1154 tmp->backup_replace_ip = (*(char *)val ? strdup((char *) val) :
1156 tmp->backup_router = TRUE;
1158 else if (!strcmp(name, "backupport")) {
1159 int port = *(int *)val;
1160 if ((port <= 0) || (port > 65535)) {
1161 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
1162 "Invalid port number!"));
1163 got_errno = SILC_CONFIG_EPRINTLINE;
1166 tmp->backup_replace_port = (SilcUInt16) port;
1168 else if (!strcmp(name, "backuplocal")) {
1169 tmp->backup_local = *(SilcBool *)val;
1171 else if (!strcmp(name, "dynamic_connection")) {
1172 tmp->dynamic_connection = *(SilcBool *)val;
1175 return SILC_CONFIG_EINTERNAL;
1177 return SILC_CONFIG_OK;
1180 silc_free(tmp->host);
1181 silc_free(tmp->backup_replace_ip);
1182 CONFIG_FREE_AUTH(tmp);
1188 /* known config options tables */
1189 static const SilcConfigTable table_general[] = {
1190 { "module_path", SILC_CONFIG_ARG_STRE, fetch_generic, NULL },
1191 { "prefer_passphrase_auth", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1192 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1193 { "connections_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1194 { "connections_max_per_host", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1195 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1196 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1197 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1198 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1199 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1200 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1201 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1202 { "channel_rekey_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1203 { "key_exchange_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1204 { "conn_auth_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1205 { "version_protocol", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1206 { "version_software", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1207 { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1208 { "detach_disabled", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1209 { "detach_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1210 { "qos", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1211 { "qos_rate_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1212 { "qos_bytes_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1213 { "qos_limit_sec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1214 { "qos_limit_usec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1215 { "channel_join_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1216 { "debug_string", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1217 { "http_server", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1218 { "http_server_ip", SILC_CONFIG_ARG_STRE, fetch_generic, NULL },
1219 { "http_server_port", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1220 { "open_server", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1221 { "local_channels", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1225 static const SilcConfigTable table_cipher[] = {
1226 { "name", SILC_CONFIG_ARG_STR, fetch_cipher, NULL },
1227 { "module", SILC_CONFIG_ARG_STRE, fetch_cipher, NULL },
1228 { "keylength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1229 { "blocklength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1233 static const SilcConfigTable table_hash[] = {
1234 { "name", SILC_CONFIG_ARG_STR, fetch_hash, NULL },
1235 { "module", SILC_CONFIG_ARG_STRE, fetch_hash, NULL },
1236 { "blocklength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1237 { "digestlength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1241 static const SilcConfigTable table_hmac[] = {
1242 { "name", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1243 { "hash", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1244 { "maclength", SILC_CONFIG_ARG_INT, fetch_hmac, NULL },
1248 static const SilcConfigTable table_pkcs[] = {
1249 { "name", SILC_CONFIG_ARG_STR, fetch_pkcs, NULL },
1253 static const SilcConfigTable table_serverinfo_c[] = {
1254 { "ip", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1255 { "public_ip", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1256 { "port", SILC_CONFIG_ARG_INT, fetch_serverinfo, NULL},
1260 static const SilcConfigTable table_serverinfo[] = {
1261 { "hostname", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1262 { "primary", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo_c},
1263 { "secondary", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo_c},
1264 { "servertype", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1265 { "location", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1266 { "admin", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1267 { "adminemail", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1268 { "user", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1269 { "group", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1270 { "publickey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1271 { "privatekey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1272 { "motdfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1273 { "pidfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1277 static const SilcConfigTable table_logging_c[] = {
1278 { "file", SILC_CONFIG_ARG_STR, fetch_logging, NULL },
1279 { "size", SILC_CONFIG_ARG_SIZE, fetch_logging, NULL },
1280 /*{ "quicklog", SILC_CONFIG_ARG_NONE, fetch_logging, NULL }, */
1284 static const SilcConfigTable table_logging[] = {
1285 { "timestamp", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1286 { "quicklogs", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1287 { "flushdelay", SILC_CONFIG_ARG_INT, fetch_logging, NULL },
1288 { "info", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1289 { "warnings", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1290 { "errors", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1291 { "fatals", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1295 static const SilcConfigTable table_connparam[] = {
1296 { "name", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1297 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1298 { "connections_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1299 { "connections_max_per_host",SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1300 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1301 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1302 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1303 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1304 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1305 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1306 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1307 { "version_protocol", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1308 { "version_software", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1309 { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1310 { "anonymous", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1311 { "qos", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1312 { "qos_rate_limit", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1313 { "qos_bytes_limit", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1314 { "qos_limit_sec", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1315 { "qos_limit_usec", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1319 static const SilcConfigTable table_client[] = {
1320 { "host", SILC_CONFIG_ARG_STRE, fetch_client, NULL },
1321 { "passphrase", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1322 { "publickey", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1323 { "publickeydir", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1324 { "params", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1328 static const SilcConfigTable table_admin[] = {
1329 { "host", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1330 { "user", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1331 { "nick", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1332 { "passphrase", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1333 { "publickey", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1334 { "port", SILC_CONFIG_ARG_INT, fetch_admin, NULL },
1335 { "params", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1339 static const SilcConfigTable table_deny[] = {
1340 { "host", SILC_CONFIG_ARG_STRE, fetch_deny, NULL },
1341 { "reason", SILC_CONFIG_ARG_STR, fetch_deny, NULL },
1345 static const SilcConfigTable table_serverconn[] = {
1346 { "host", SILC_CONFIG_ARG_STRE, fetch_server, NULL },
1347 { "passphrase", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1348 { "publickey", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1349 { "params", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1350 { "backup", SILC_CONFIG_ARG_TOGGLE, fetch_server, NULL },
1354 static const SilcConfigTable table_routerconn[] = {
1355 { "host", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1356 { "port", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1357 { "passphrase", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1358 { "publickey", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1359 { "params", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1360 { "initiator", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1361 { "backuphost", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1362 { "backupport", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1363 { "backuplocal", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1364 { "dynamic_connection", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1368 static const SilcConfigTable table_main[] = {
1369 { "cipher", SILC_CONFIG_ARG_BLOCK, fetch_cipher, table_cipher },
1370 { "hash", SILC_CONFIG_ARG_BLOCK, fetch_hash, table_hash },
1371 { "hmac", SILC_CONFIG_ARG_BLOCK, fetch_hmac, table_hmac },
1372 { "pkcs", SILC_CONFIG_ARG_BLOCK, fetch_pkcs, table_pkcs },
1373 { "general", SILC_CONFIG_ARG_BLOCK, NULL, table_general },
1374 { "serverinfo", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo },
1375 { "logging", SILC_CONFIG_ARG_BLOCK, NULL, table_logging },
1376 { "connectionparams", SILC_CONFIG_ARG_BLOCK, fetch_connparam, table_connparam },
1377 { "client", SILC_CONFIG_ARG_BLOCK, fetch_client, table_client },
1378 { "admin", SILC_CONFIG_ARG_BLOCK, fetch_admin, table_admin },
1379 { "deny", SILC_CONFIG_ARG_BLOCK, fetch_deny, table_deny },
1380 { "serverconnection", SILC_CONFIG_ARG_BLOCK, fetch_server, table_serverconn },
1381 { "routerconnection", SILC_CONFIG_ARG_BLOCK, fetch_router, table_routerconn },
1385 /* Set default values to stuff that was not configured. */
1387 static void silc_server_config_set_defaults(SilcServerConfig config)
1389 my_set_param_defaults(&config->param, NULL);
1391 config->channel_rekey_secs = (config->channel_rekey_secs ?
1392 config->channel_rekey_secs :
1393 SILC_SERVER_CHANNEL_REKEY);
1394 config->key_exchange_timeout = (config->key_exchange_timeout ?
1395 config->key_exchange_timeout :
1396 SILC_SERVER_SKE_TIMEOUT);
1397 config->conn_auth_timeout = (config->conn_auth_timeout ?
1398 config->conn_auth_timeout :
1399 SILC_SERVER_CONNAUTH_TIMEOUT);
1402 /* Check for correctness of the configuration */
1404 static SilcBool silc_server_config_check(SilcServerConfig config)
1406 SilcBool ret = TRUE;
1407 SilcServerConfigServer *s;
1408 SilcServerConfigRouter *r;
1411 /* ServerConfig is mandatory */
1412 if (!config->server_info) {
1413 SILC_SERVER_LOG_ERROR(("\nError: Missing mandatory block `ServerInfo'"));
1417 /* RouterConnection sanity checks */
1419 if (config->routers && config->routers->backup_router == TRUE &&
1421 SILC_SERVER_LOG_ERROR((
1422 "\nError: First RouterConnection block must be primary router "
1423 "connection. You have marked it incorrectly as backup router."));
1427 if (config->routers && config->routers->initiator == FALSE &&
1428 config->routers->backup_router == FALSE) {
1429 SILC_SERVER_LOG_ERROR((
1430 "\nError: First RouterConnection block must be primary router "
1431 "connection and it must be marked as Initiator."));
1435 if (config->routers && config->routers->backup_router == TRUE &&
1436 !config->servers && !config->routers->next) {
1437 SILC_SERVER_LOG_ERROR((
1438 "\nError: You have configured backup router but not primary router. "
1439 "If backup router is configured also primary router must be "
1444 /* Backup router sanity checks */
1446 for (r = config->routers; r; r = r->next) {
1447 if (r->backup_router && !strcmp(r->host, r->backup_replace_ip)) {
1448 SILC_SERVER_LOG_ERROR((
1449 "\nError: Backup router connection incorrectly configured to use "
1450 "primary and backup router as same host `%s'. They must not be "
1451 "same host.", r->host));
1455 if (r->initiator == FALSE && r->port != 0) {
1456 SILC_SERVER_LOG_WARNING(("\nWarning: Initiator is FALSE and Port is "
1457 "specified. Ignoring Port value."));
1462 /* ServerConnection sanity checks */
1464 for (s = config->servers; s; s = s->next) {
1465 if (s->backup_router) {
1471 for (s = config->servers; s; s = s->next) {
1472 if (!s->backup_router) {
1473 SILC_SERVER_LOG_ERROR((
1474 "\nError: Your server is backup router but not all ServerConnection "
1475 "blocks were marked as backup connections. They all must be "
1476 "marked as backup connections."));
1486 /* Allocates a new configuration object, opens configuration file and
1487 parses it. The parsed data is returned to the newly allocated
1488 configuration object. The SilcServerConfig must be freed by calling
1489 the silc_server_config_destroy function. */
1491 SilcServerConfig silc_server_config_alloc(const char *filename,
1494 SilcServerConfig config_new;
1495 SilcConfigEntity ent;
1496 SilcConfigFile *file;
1498 SILC_LOG_DEBUG(("Loading config data from `%s'", filename));
1500 /* alloc a config object */
1501 config_new = silc_calloc(1, sizeof(*config_new));
1505 /* general config defaults */
1506 config_new->refcount = 1;
1507 config_new->logging_timestamp = TRUE;
1508 config_new->param.reconnect_keep_trying = TRUE;
1509 config_new->server = server;
1511 /* obtain a config file object */
1512 file = silc_config_open(filename);
1514 SILC_SERVER_LOG_ERROR(("\nError: can't open config file `%s'",
1519 /* obtain a SilcConfig entity, we can use it to start the parsing */
1520 ent = silc_config_init(file);
1522 /* load the known configuration options, give our empty object as context */
1523 silc_config_register_table(ent, table_main, (void *) config_new);
1525 /* enter the main parsing loop. When this returns, we have the parsing
1526 * result and the object filled (or partially, in case of errors). */
1527 ret = silc_config_main(ent);
1528 SILC_LOG_DEBUG(("Parser returned [ret=%d]: %s", ret,
1529 silc_config_strerror(ret)));
1531 /* Check if the parser returned errors */
1533 /* handle this special error return which asks to quietly return */
1534 if (ret != SILC_CONFIG_ESILENT) {
1535 char *linebuf, *filename = silc_config_get_filename(file);
1536 SilcUInt32 line = silc_config_get_line(file);
1537 if (ret != SILC_CONFIG_EPRINTLINE)
1538 SILC_SERVER_LOG_ERROR(("Error while parsing config file: %s.",
1539 silc_config_strerror(ret)));
1540 linebuf = silc_config_read_line(file, line);
1542 SILC_SERVER_LOG_ERROR((" file %s line %lu: %s\n", filename,
1547 silc_server_config_destroy(config_new);
1548 silc_config_close(file);
1552 /* close (destroy) the file object */
1553 silc_config_close(file);
1555 /* Check the configuration */
1556 if (!silc_server_config_check(config_new)) {
1557 silc_server_config_destroy(config_new);
1561 /* Set default to configuration parameters */
1562 silc_server_config_set_defaults(config_new);
1567 /* Increments the reference counter of a config object */
1569 void silc_server_config_ref(SilcServerConfigRef *ref, SilcServerConfig config,
1574 ref->config = config;
1575 ref->ref_ptr = ref_ptr;
1576 SILC_LOG_DEBUG(("Referencing config [%p] refcnt %d->%d", config,
1577 config->refcount - 1, config->refcount));
1581 /* Decrements the reference counter of a config object. If the counter
1582 reaches 0, the config object is destroyed. */
1584 void silc_server_config_unref(SilcServerConfigRef *ref)
1587 silc_server_config_destroy(ref->config);
1590 /* Destroy a config object with all his children lists */
1592 void silc_server_config_destroy(SilcServerConfig config)
1597 SILC_LOG_DEBUG(("Unreferencing config [%p] refcnt %d->%d", config,
1598 config->refcount + 1, config->refcount));
1599 if (config->refcount > 0)
1602 SILC_LOG_DEBUG(("Freeing config context"));
1604 /* Destroy general config stuff */
1605 silc_free(config->module_path);
1606 silc_free(config->debug_string);
1607 silc_free(config->param.version_protocol);
1608 silc_free(config->param.version_software);
1609 silc_free(config->param.version_software_vendor);
1610 silc_free(config->httpd_ip);
1612 /* Destroy Logging channels */
1613 if (config->logging_info)
1614 silc_free(config->logging_info->file);
1615 if (config->logging_warnings)
1616 silc_free(config->logging_warnings->file);
1617 if (config->logging_errors)
1618 silc_free(config->logging_errors->file);
1619 if (config->logging_fatals)
1620 silc_free(config->logging_fatals->file);
1621 silc_free(config->logging_info);
1622 silc_free(config->logging_warnings);
1623 silc_free(config->logging_errors);
1624 silc_free(config->logging_fatals);
1626 /* Destroy the ServerInfo struct */
1627 if (config->server_info) {
1628 register SilcServerConfigServerInfo *si = config->server_info;
1629 silc_free(si->server_name);
1631 silc_free(si->primary->server_ip);
1632 silc_free(si->primary);
1634 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServerInfoInterface,
1636 silc_free(di->server_ip);
1639 silc_free(si->server_type);
1640 silc_free(si->location);
1641 silc_free(si->admin);
1642 silc_free(si->email);
1643 silc_free(si->user);
1644 silc_free(si->group);
1645 silc_free(si->motd_file);
1646 silc_free(si->pid_file);
1648 silc_pkcs_public_key_free(si->public_key);
1649 if (si->private_key)
1650 silc_pkcs_private_key_free(si->private_key);
1654 /* Now let's destroy the lists */
1656 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigCipher,
1658 silc_free(di->name);
1659 silc_free(di->module);
1662 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHash, config->hash)
1663 silc_free(di->name);
1664 silc_free(di->module);
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_compare(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_compare(admin->host, host))
1903 if (admin->user && !silc_string_compare(admin->user, user))
1905 if (admin->nick && !silc_string_compare(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_compare(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_compare(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_compare(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_compare(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)