From: Pekka Riikonen Date: Thu, 14 Feb 2002 20:43:59 +0000 (+0000) Subject: updates. X-Git-Tag: silc.client.0.8.1~63 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=b90b880b27009f7c3964cb5968488bee31ca4b95 updates. --- diff --git a/CHANGES b/CHANGES index 3a5df357..9fadd907 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,27 @@ +Thu Feb 14 22:03:58 EET 2002 Pekka Riikonen + + * Added new configuration options and blocks: + keepalive_secs, reconnect_count, reconnect_interval, + reconnect_interval_max, reconnect_keep_trying and + require_reverser_lookup. Added ConnectionParam block, and + implemented the connection parameters when connecting as + initiator and when accepting connections as responder. + + Added CONFIG_IS_DOUBLE macro in config file parsing, to check + whether given configuration value has been given already. + + Affected files silcd/serverconfig.[c], server.[c]. + + * Splitted the doc/example_silcd.conf.in. Separated the crypto + algorithm parts and created new file silcalgs.conf, that + is now included from the example_silcd.conf.in. + + * Optimized the silc_server_connect_to_router_second to take + the connection configuration object from the SilcServerConnection + object instead of finding it during the connecting phase. + Added the configuration object to SilcServerConnection struct. + Affected files silcd/server_internal.h, server.c. + Thu Feb 14 16:02:26 CET 2002 Pekka Riikonen * Add the client on channel after it was resolved at the diff --git a/Makefile.am.pre b/Makefile.am.pre index 6bf3d2e3..3d5f5456 100644 --- a/Makefile.am.pre +++ b/Makefile.am.pre @@ -83,7 +83,9 @@ examples-install: etc-install: -@if test '!' -f $(etcdir)/silcd.conf ; then \ $(INSTALL_DATA) $(srcdir)/doc/example_silcd.conf \ - $(etcdir)/silcd.conf; \ + $(etcdir)/silcd.conf; \ + $(INSTALL_DATA) $(srcdir)/doc/silcalgs.conf \ + $(etcdir)/silcalgs.conf; \ chmod go= $(etcdir)/silcd.conf; \ fi -@if test '!' -f $(etcdir)/silc.conf ; then \ diff --git a/TODO b/TODO index 7e307c9d..69330dec 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,9 @@ TODO/bugs in Irssi SILC client ============================== + o When autoconnect="yes" is set in silc.conf the irssi complains about + unknown chat protocol. + o Rewrite the notify handling in the new Irssi SILC client. o /cumode for unknown nick does not give any error message. diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 32287521..3f8cd46f 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -93,8 +93,6 @@ void silc_server_free(SilcServer server) silc_dlist_uninit(server->sim); #endif - silc_free(server->params); - if (server->pending_commands) silc_dlist_uninit(server->pending_commands); @@ -130,15 +128,8 @@ int silc_server_init(SilcServer server) server->public_key = server->config->server_info->public_key; server->private_key = server->config->server_info->private_key; - /* XXX After server is made as Silc Server Library this can be given - as argument, for now this is hard coded */ - server->params = silc_calloc(1, sizeof(*server->params)); - server->params->retry_count = SILC_SERVER_RETRY_COUNT; - server->params->retry_interval_min = SILC_SERVER_RETRY_INTERVAL_MIN; - server->params->retry_interval_max = SILC_SERVER_RETRY_INTERVAL_MAX; - server->params->retry_keep_trying = FALSE; - server->params->protocol_timeout = 60; - server->params->require_reverse_mapping = FALSE; + /* Set default to configuration parameters */ + silc_server_config_set_defaults(server); /* Register all configured ciphers, PKCS and hash functions. */ if (!silc_server_config_register_ciphers(server)) @@ -223,7 +214,7 @@ int silc_server_init(SilcServer server) and port. */ if (!silc_net_check_local_by_sock(sock[i], &newsocket->hostname, &newsocket->ip)) { - if ((server->params->require_reverse_mapping && !newsocket->hostname) || + if ((server->config->require_reverse_lookup && !newsocket->hostname) || !newsocket->ip) { SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s", newsocket->hostname ? newsocket->hostname : @@ -555,11 +546,10 @@ void silc_server_start_key_exchange(SilcServer server, is not executed within set limit. */ proto_ctx->timeout_task = silc_schedule_task_add(server->schedule, sock, - silc_server_timeout_remote, - server, server->params->protocol_timeout, - server->params->protocol_timeout_usec, - SILC_TASK_TIMEOUT, - SILC_TASK_PRI_LOW); + silc_server_timeout_remote, + server, 60, 0, /* XXX hardcoded */ + SILC_TASK_TIMEOUT, + SILC_TASK_PRI_LOW); /* Register the connection for network input and output. This sets that scheduler will listen for incoming packets for this connection @@ -583,24 +573,27 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_retry) { SilcServerConnection sconn = (SilcServerConnection)context; SilcServer server = sconn->server; + SilcServerConfigSectionConnectionParam *param; + + param = (sconn->param ? sconn->param : &server->config->param); SILC_LOG_INFO(("Retrying connecting to a router")); /* Calculate next timeout */ if (sconn->retry_count >= 1) { sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER; - if (sconn->retry_timeout > SILC_SERVER_RETRY_INTERVAL_MAX) - sconn->retry_timeout = SILC_SERVER_RETRY_INTERVAL_MAX; + if (sconn->retry_timeout > param->reconnect_interval_max) + sconn->retry_timeout = param->reconnect_interval_max; } else { - sconn->retry_timeout = server->params->retry_interval_min; + sconn->retry_timeout = param->reconnect_interval; } sconn->retry_count++; sconn->retry_timeout = sconn->retry_timeout + silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER; /* If we've reached max retry count, give up. */ - if (sconn->retry_count > server->params->retry_count && - server->params->retry_keep_trying == FALSE) { + if (sconn->retry_count > param->reconnect_count && + param->reconnect_keep_trying == FALSE) { SILC_LOG_ERROR(("Could not connect to router, giving up")); silc_free(sconn->remote_host); silc_free(sconn); @@ -609,8 +602,7 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_retry) /* Wait one before retrying */ silc_schedule_task_add(server->schedule, fd, silc_server_connect_router, - context, sconn->retry_timeout, - server->params->retry_interval_min_usec, + context, sconn->retry_timeout, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL); } @@ -626,7 +618,7 @@ SILC_TASK_CALLBACK(silc_server_connect_router) (sconn->backup ? "backup router" : "router"), sconn->remote_host, sconn->remote_port)); - server->router_connect = time(0); + server->router_connect = time(NULL); /* Connect to remote host */ sock = silc_net_create_connection(server->config->server_info->server_ip, @@ -692,6 +684,9 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router) if (!server->router_conn && !sconn->backup) server->router_conn = sconn; + sconn->conn = ptr; + sconn->param = ptr->param; + silc_schedule_task_add(server->schedule, fd, silc_server_connect_router, (void *)sconn, 0, 1, SILC_TASK_TIMEOUT, @@ -786,8 +781,12 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_second) /* Resolve the authentication method used in this connection. Check if we find a match from user configured connections */ - conn = silc_server_config_find_router_conn(server, sock->hostname, - sock->port); + if (!sconn->conn) + conn = silc_server_config_find_router_conn(server, sock->hostname, + sock->port); + else + conn = sconn->conn; + if (conn) { /* Match found. Use the configured authentication method */ if (conn->passphrase) { @@ -841,14 +840,13 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_second) silc_server_connect_to_router_final); /* Register timeout task. If the protocol is not executed inside - this timelimit the connection will be terminated. Currently - this is 15 seconds and is hard coded limit (XXX). */ + this timelimit the connection will be terminated. */ proto_ctx->timeout_task = silc_schedule_task_add(server->schedule, sock->sock, - silc_server_timeout_remote, - (void *)server, 15, 0, - SILC_TASK_TIMEOUT, - SILC_TASK_PRI_LOW); + silc_server_timeout_remote, + (void *)server, 15, 0, /* XXX hardcoded */ + SILC_TASK_TIMEOUT, + SILC_TASK_PRI_LOW); /* Run the protocol */ silc_protocol_execute(sock->protocol, server->schedule, 0, 0); @@ -871,6 +869,7 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final) unsigned char *id_string; uint32 id_len; SilcIDListData idata; + SilcServerConfigSectionConnectionParam *param; SILC_LOG_DEBUG(("Start")); @@ -949,12 +948,14 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final) idata = (SilcIDListData)sock->user_data; idata->status |= SILC_IDLIST_STATUS_REGISTERED; + param = (sconn->param ? sconn->param : &server->config->param); + /* Perform keepalive. The `hb_context' will be freed automatically when finally calling the silc_socket_free function. XXX hardcoded timeout!! */ hb_context = silc_calloc(1, sizeof(*hb_context)); hb_context->server = server; - silc_socket_set_heartbeat(sock, 300, hb_context, + silc_socket_set_heartbeat(sock, param->keepalive_secs, hb_context, silc_server_perform_heartbeat, server->schedule); @@ -1037,7 +1038,7 @@ silc_server_accept_new_connection_lookup(SilcSocketConnection sock, /* Check whether we could resolve both IP and FQDN. */ if (!sock->ip || (!strcmp(sock->ip, sock->hostname) && - server->params->require_reverse_mapping)) { + server->config->require_reverse_lookup)) { SILC_LOG_ERROR(("IP/DNS lookup failed %s", sock->hostname ? sock->hostname : sock->ip ? sock->ip : "")); @@ -1120,12 +1121,12 @@ silc_server_accept_new_connection_lookup(SilcSocketConnection sock, /* Register a timeout task that will be executed if the connector will not start the key exchange protocol within 60 seconds. For - now, this is a hard coded limit. After 60 secs the connection will + now, this is a hard coded limit. After the timeout the connection will be closed if the key exchange protocol has not been started. */ proto_ctx->timeout_task = silc_schedule_task_add(server->schedule, sock->sock, silc_server_timeout_remote, - context, 60, 0, + context, 60, 0, /* XXX hardcoded */ SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW); } @@ -1269,12 +1270,11 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_second) silc_server_accept_new_connection_final); /* Register timeout task. If the protocol is not executed inside - this timelimit the connection will be terminated. Currently - this is 60 seconds and is hard coded limit (XXX). */ + this timelimit the connection will be terminated. */ proto_ctx->timeout_task = silc_schedule_task_add(server->schedule, sock->sock, silc_server_timeout_remote, - (void *)server, 60, 0, + (void *)server, 60, 0, /* XXX hardcoded */ SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW); } @@ -1293,6 +1293,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) SilcServerHBContext hb_context; SilcUnknownEntry entry = (SilcUnknownEntry)sock->user_data; void *id_entry; + uint32 hearbeat_timeout = SILC_SERVER_KEEPALIVE; SILC_LOG_DEBUG(("Start")); @@ -1321,6 +1322,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) case SILC_SOCKET_TYPE_CLIENT: { SilcClientEntry client; + SilcServerConfigSectionClient *conn = ctx->cconfig; SILC_LOG_DEBUG(("Remote host is client")); SILC_LOG_INFO(("Connection from %s (%s) is client", sock->hostname, @@ -1347,6 +1349,12 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) if (server->server_type == SILC_ROUTER) server->stat.cell_clients++; + /* Get connection parameters */ + if (conn->param) { + if (conn->param->keepalive_secs) + hearbeat_timeout = conn->param->keepalive_secs; + } + id_entry = (void *)client; break; } @@ -1354,18 +1362,43 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) case SILC_SOCKET_TYPE_ROUTER: { SilcServerEntry new_server; - /* XXX FIXME: Now server and router has different table, so this is probably broken. */ - SilcServerConfigSectionRouter *conn = - ctx->conn_type == SILC_SOCKET_TYPE_SERVER ? - ctx->sconfig : ctx->rconfig; + bool initiator = FALSE; + bool backup_local = FALSE; + bool backup_router = FALSE; + char *backup_replace_ip = NULL; + uint16 backup_replace_port = 0; + SilcServerConfigSectionServer *sconn = ctx->sconfig; + SilcServerConfigSectionRouter *rconn = ctx->rconfig; + + if (ctx->conn_type == SILC_SOCKET_TYPE_ROUTER && rconn) { + initiator = rconn->initiator; + backup_local = rconn->backup_local; + backup_router = rconn->backup_router; + backup_replace_ip = rconn->backup_replace_ip; + backup_replace_port = rconn->backup_replace_port; + + if (rconn->param) { + if (rconn->param->keepalive_secs) + hearbeat_timeout = rconn->param->keepalive_secs; + } + } + + if (ctx->conn_type == SILC_SOCKET_TYPE_SERVER && sconn) { + backup_router = sconn->backup_router; + + if (sconn->param) { + if (sconn->param->keepalive_secs) + hearbeat_timeout = sconn->param->keepalive_secs; + } + } SILC_LOG_DEBUG(("Remote host is %s", ctx->conn_type == SILC_SOCKET_TYPE_SERVER ? - "server" : (conn->backup_router ? + "server" : (backup_router ? "backup router" : "router"))); SILC_LOG_INFO(("Connection from %s (%s) is %s", sock->hostname, sock->ip, ctx->conn_type == SILC_SOCKET_TYPE_SERVER ? - "server" : (conn->backup_router ? + "server" : (backup_router ? "backup router" : "router"))); /* Add the server into server cache. The server name and Server ID @@ -1374,7 +1407,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) are router. */ new_server = silc_idlist_add_server((ctx->conn_type == SILC_SOCKET_TYPE_SERVER ? - server->local_list : (conn->backup_router ? + server->local_list : (backup_router ? server->local_list : server->global_list)), NULL, @@ -1382,7 +1415,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) SILC_SERVER : SILC_ROUTER), NULL, (ctx->conn_type == SILC_SOCKET_TYPE_SERVER ? - server->id_entry : (conn->backup_router ? + server->id_entry : (backup_router ? server->id_entry : NULL)), sock); if (!new_server) { @@ -1406,12 +1439,12 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) /* If the incoming connection is router and marked as backup router then add it to be one of our backups */ - if (ctx->conn_type == SILC_SOCKET_TYPE_ROUTER && conn->backup_router) { - silc_server_backup_add(server, new_server, conn->backup_replace_ip, - conn->backup_replace_port, conn->backup_local); + if (ctx->conn_type == SILC_SOCKET_TYPE_ROUTER && backup_router) { + silc_server_backup_add(server, new_server, backup_replace_ip, + backup_replace_port, backup_local); /* Change it back to SERVER type since that's what it really is. */ - if (conn->backup_local) + if (backup_local) ctx->conn_type = SILC_SOCKET_TYPE_SERVER; new_server->server_type = SILC_BACKUP_ROUTER; @@ -1420,8 +1453,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) /* Check whether this connection is to be our primary router connection if we do not already have the primary route. */ if (server->standalone && ctx->conn_type == SILC_SOCKET_TYPE_ROUTER) { - if (silc_server_config_is_primary_route(server) && - !conn->initiator) + if (silc_server_config_is_primary_route(server) && !initiator) break; SILC_LOG_DEBUG(("We are not standalone server anymore")); @@ -1452,11 +1484,10 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) SILC_LOG_DEBUG(("New connection authenticated")); /* Perform keepalive. The `hb_context' will be freed automatically - when finally calling the silc_socket_free function. XXX hardcoded - timeout!! */ + when finally calling the silc_socket_free function. */ hb_context = silc_calloc(1, sizeof(*hb_context)); hb_context->server = server; - silc_socket_set_heartbeat(sock, 400, hb_context, + silc_socket_set_heartbeat(sock, hearbeat_timeout, hb_context, silc_server_perform_heartbeat, server->schedule); @@ -2219,6 +2250,7 @@ void silc_server_create_connection(SilcServer server, sconn->remote_host = strdup(remote_host); sconn->remote_port = port; sconn->no_reconnect = TRUE; + sconn->param = &server->config->param; silc_schedule_task_add(server->schedule, 0, silc_server_connect_router, diff --git a/apps/silcd/server.h b/apps/silcd/server.h index 65ab966e..afff2b97 100644 --- a/apps/silcd/server.h +++ b/apps/silcd/server.h @@ -29,47 +29,6 @@ typedef struct SilcServerStruct *SilcServer; /* Forward declaration of backup server context */ typedef struct SilcServerBackupStruct *SilcServerBackup; -#define SILC_SERVER_MAX_CONNECTIONS 1000 - -/* General definitions */ - -/* SILC port */ -#define SILC_PORT 768; - -/* Server and router. Used internally by the code. */ -#define SILC_SERVER 0 -#define SILC_ROUTER 1 -#define SILC_BACKUP_ROUTER 2 - -/* Connection retry timeout. We implement exponential backoff algorithm - in connection retry. The interval of timeout grows when retry count - grows. */ -#define SILC_SERVER_RETRY_COUNT 7 /* Max retry count */ -#define SILC_SERVER_RETRY_MULTIPLIER 2 /* Interval growth */ -#define SILC_SERVER_RETRY_RANDOMIZER 2 /* timeout += rnd % 2 */ -#define SILC_SERVER_RETRY_INTERVAL_MIN 10 /* Min retry timeout */ -#define SILC_SERVER_RETRY_INTERVAL_MAX 600 /* Max generated timeout */ - -/* - Silc Server Params. - - Structure to hold various default parameters for server that can be - given before running the server. - -*/ -typedef struct { - uint32 retry_count; - uint32 retry_interval_min; - uint32 retry_interval_min_usec; - uint32 retry_interval_max; - char retry_keep_trying; - - uint32 protocol_timeout; - uint32 protocol_timeout_usec; - - char require_reverse_mapping; -} *SilcServerParams; - /* Callback function that is called after the key exchange and connection authentication protocols has been completed with a remote router. The `server_entry' is the remote router entry. */ @@ -77,6 +36,7 @@ typedef void (*SilcServerConnectRouterCallback)(SilcServer server, SilcServerEntry server_entry, void *context); +/* Connection structure used when connection to remote */ typedef struct { SilcSocketConnection sock; @@ -87,7 +47,11 @@ typedef struct { char *backup_replace_ip; int backup_replace_port; bool no_reconnect; - + + /* Connection configuration (maybe NULL), and connection params */ + void *conn; + void *param; + /* Current connection retry info */ uint32 retry_count; uint32 retry_timeout; @@ -99,6 +63,31 @@ typedef struct { void *callback_context; } *SilcServerConnection; +#define SILC_SERVER_MAX_CONNECTIONS 1000 + +/* General definitions */ + +/* SILC port */ +#define SILC_PORT 768; + +/* Server and router. Used internally by the code. */ +#define SILC_SERVER 0 +#define SILC_ROUTER 1 +#define SILC_BACKUP_ROUTER 2 + +/* Default parameter values */ + +/* Connection retry timeout. We implement exponential backoff algorithm + in connection retry. The interval of timeout grows when retry count + grows. */ +#define SILC_SERVER_RETRY_COUNT 7 /* Max retry count */ +#define SILC_SERVER_RETRY_MULTIPLIER 2 /* Interval growth */ +#define SILC_SERVER_RETRY_RANDOMIZER 2 /* timeout += rnd % 2 */ +#define SILC_SERVER_RETRY_INTERVAL_MIN 10 /* Min retry timeout */ +#define SILC_SERVER_RETRY_INTERVAL_MAX 600 /* Max generated timeout */ + +#define SILC_SERVER_KEEPALIVE 300 /* Heartbeat interval */ + /* Macros */ /* This macro is used to send notify messages with formatted string. The diff --git a/apps/silcd/server_internal.h b/apps/silcd/server_internal.h index 41df9ab8..423e37e6 100644 --- a/apps/silcd/server_internal.h +++ b/apps/silcd/server_internal.h @@ -121,9 +121,6 @@ struct SilcServerStruct { /* Pending command queue */ SilcDList pending_commands; - /* Default parameteres for server */ - SilcServerParams params; - #ifdef SILC_SIM /* SIM (SILC Module) list */ SilcDList sim; diff --git a/apps/silcd/serverconfig.c b/apps/silcd/serverconfig.c index f34616bf..16866fd2 100644 --- a/apps/silcd/serverconfig.c +++ b/apps/silcd/serverconfig.c @@ -50,6 +50,30 @@ __type__ *di = (__type__ *) tmp; \ tmp = (void *) di->next; +/* Set EDOUBLE error value and bail out if necessary */ +#define CONFIG_IS_DOUBLE(x) \ + if ((x)) { \ + got_errno = SILC_CONFIG_EDOUBLE; \ + goto got_err; \ + } + +/* Find connection parameters by the parameter block name. */ +static SilcServerConfigSectionConnectionParam * +my_find_param(SilcServerConfig config, const char *name) +{ + SilcServerConfigSectionConnectionParam *param; + + if (!name) + return NULL; + + for (param = config->conn_params; param; param = param->next) { + if (!strcasecmp(param->name, name)) + return param; + } + + return NULL; +} + /* free an authdata according to its auth method */ static void my_free_authdata(char *passphrase, void *public_key) { @@ -95,21 +119,40 @@ static bool my_parse_authdata(SilcAuthMethod auth_meth, char *p, uint32 line, SILC_CONFIG_CALLBACK(fetch_generic) { SilcServerConfig config = (SilcServerConfig) context; + int got_errno = 0; if (!strcmp(name, "module_path")) { - if (config->module_path) - return SILC_CONFIG_EDOUBLE; - - /* dup it only if non-empty, otherwise point it to NULL */ + CONFIG_IS_DOUBLE(config->module_path); config->module_path = (*(char *)val ? strdup((char *) val) : NULL); } else if (!strcmp(name, "prefer_passphrase_auth")) { config->prefer_passphrase_auth = *(bool *)val; } + else if (!strcmp(name, "require_reverse_lookup")) { + config->require_reverse_lookup = *(bool *)val; + } + else if (!strcmp(name, "keepalive_secs")) { + config->param.keepalive_secs = *(uint32 *)val; + } + else if (!strcmp(name, "reconnect_count")) { + config->param.reconnect_count = *(uint32 *)val; + } + else if (!strcmp(name, "reconnect_interval")) { + config->param.reconnect_interval = *(uint32 *)val; + } + else if (!strcmp(name, "reconnect_interval_max")) { + config->param.reconnect_interval_max = *(uint32 *)val; + } + else if (!strcmp(name, "reconnect_keep_trying")) { + config->param.reconnect_keep_trying = *(bool *)val; + } else return SILC_CONFIG_EINTERNAL; return SILC_CONFIG_OK; + + got_err: + return got_errno; } SILC_CONFIG_CALLBACK(fetch_cipher) @@ -139,18 +182,19 @@ SILC_CONFIG_CALLBACK(fetch_cipher) /* Identify and save this value */ if (!strcmp(name, "name")) { - if (tmp->name) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; } + CONFIG_IS_DOUBLE(tmp->name); tmp->name = strdup((char *) val); } - else if (!strcmp(name, "module")) { /* can be empty */ - if (tmp->module) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; } - /* dup it only if non-empty, otherwise point it to NULL */ + else if (!strcmp(name, "module")) { + CONFIG_IS_DOUBLE(tmp->module); tmp->module = (*(char *)val ? strdup((char *) val) : NULL); } - else if (!strcmp(name, "keylength")) + else if (!strcmp(name, "keylength")) { tmp->key_length = *(uint32 *)val; - else if (!strcmp(name, "blocklength")) + } + else if (!strcmp(name, "blocklength")) { tmp->block_length = *(uint32 *)val; + } else return SILC_CONFIG_EINTERNAL; return SILC_CONFIG_OK; @@ -182,6 +226,7 @@ SILC_CONFIG_CALLBACK(fetch_hash) config->tmp = NULL; return SILC_CONFIG_OK; } + /* if there isn't a temporary struct alloc one */ if (!tmp) { config->tmp = silc_calloc(1, sizeof(*findtmp)); @@ -190,18 +235,19 @@ SILC_CONFIG_CALLBACK(fetch_hash) /* Identify and save this value */ if (!strcmp(name, "name")) { - if (tmp->name) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; } + CONFIG_IS_DOUBLE(tmp->name); tmp->name = strdup((char *) val); } - else if (!strcmp(name, "module")) { /* can be empty */ - if (tmp->module) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; } - /* dup it only if non-empty, otherwise point it to NULL */ + else if (!strcmp(name, "module")) { + CONFIG_IS_DOUBLE(tmp->module); tmp->module = (*(char *)val ? strdup((char *) val) : NULL); } - else if (!strcmp(name, "blocklength")) + else if (!strcmp(name, "blocklength")) { tmp->block_length = *(int *)val; - else if (!strcmp(name, "digestlength")) + } + else if (!strcmp(name, "digestlength")) { tmp->digest_length = *(int *)val; + } else return SILC_CONFIG_EINTERNAL; return SILC_CONFIG_OK; @@ -241,15 +287,16 @@ SILC_CONFIG_CALLBACK(fetch_hmac) /* Identify and save this value */ if (!strcmp(name, "name")) { - if (tmp->name) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; } + CONFIG_IS_DOUBLE(tmp->name); tmp->name = strdup((char *) val); } else if (!strcmp(name, "hash")) { - if (tmp->hash) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; } + CONFIG_IS_DOUBLE(tmp->hash); tmp->hash = strdup((char *) val); } - else if (!strcmp(name, "maclength")) + else if (!strcmp(name, "maclength")) { tmp->mac_length = *(int *)val; + } else return SILC_CONFIG_EINTERNAL; return SILC_CONFIG_OK; @@ -289,7 +336,7 @@ SILC_CONFIG_CALLBACK(fetch_pkcs) /* Identify and save this value */ if (!strcmp(name, "name")) { - if (tmp->name) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; } + CONFIG_IS_DOUBLE(tmp->name); tmp->name = strdup((char *) val); } else @@ -307,23 +354,23 @@ SILC_CONFIG_CALLBACK(fetch_serverinfo) { SilcServerConfig config = (SilcServerConfig) context; SilcServerConfigSectionServerInfo *server_info = config->server_info; + int got_errno = 0; /* if there isn't the struct alloc it */ - if (!server_info) { + if (!server_info) config->server_info = server_info = (SilcServerConfigSectionServerInfo *) silc_calloc(1, sizeof(*server_info)); - } if (type == SILC_CONFIG_ARG_BLOCK) { /* check for mandatory inputs */ return SILC_CONFIG_OK; } if (!strcmp(name, "hostname")) { - if (server_info->server_name) return SILC_CONFIG_EDOUBLE; + CONFIG_IS_DOUBLE(server_info->server_name); server_info->server_name = strdup((char *) val); } else if (!strcmp(name, "ip")) { - if (server_info->server_ip) return SILC_CONFIG_EDOUBLE; + CONFIG_IS_DOUBLE(server_info->server_ip); server_info->server_ip = strdup((char *) val); } else if (!strcmp(name, "port")) { @@ -335,35 +382,35 @@ SILC_CONFIG_CALLBACK(fetch_serverinfo) server_info->port = (uint16) port; } else if (!strcmp(name, "servertype")) { - if (server_info->server_type) return SILC_CONFIG_EDOUBLE; + CONFIG_IS_DOUBLE(server_info->server_type); server_info->server_type = strdup((char *) val); } else if (!strcmp(name, "admin")) { - if (server_info->admin) return SILC_CONFIG_EDOUBLE; + CONFIG_IS_DOUBLE(server_info->admin); server_info->admin = strdup((char *) val); } else if (!strcmp(name, "adminemail")) { - if (server_info->email) return SILC_CONFIG_EDOUBLE; + CONFIG_IS_DOUBLE(server_info->email); server_info->email = strdup((char *) val); } else if (!strcmp(name, "location")) { - if (server_info->location) return SILC_CONFIG_EDOUBLE; + CONFIG_IS_DOUBLE(server_info->location); server_info->location = strdup((char *) val); } else if (!strcmp(name, "user")) { - if (server_info->user) return SILC_CONFIG_EDOUBLE; + CONFIG_IS_DOUBLE(server_info->user); server_info->user = strdup((char *) val); } else if (!strcmp(name, "group")) { - if (server_info->group) return SILC_CONFIG_EDOUBLE; + CONFIG_IS_DOUBLE(server_info->group); server_info->group = strdup((char *) val); } else if (!strcmp(name, "motdfile")) { - if (server_info->motd_file) return SILC_CONFIG_EDOUBLE; + CONFIG_IS_DOUBLE(server_info->motd_file); server_info->motd_file = strdup((char *) val); } else if (!strcmp(name, "pidfile")) { - if (server_info->pid_file) return SILC_CONFIG_EDOUBLE; + CONFIG_IS_DOUBLE(server_info->pid_file); server_info->pid_file = strdup((char *) val); } else if (!strcmp(name, "publickey")) { @@ -395,6 +442,9 @@ SILC_CONFIG_CALLBACK(fetch_serverinfo) else return SILC_CONFIG_EINTERNAL; return SILC_CONFIG_OK; + + got_err: + return got_errno; } SILC_CONFIG_CALLBACK(fetch_logging) @@ -458,6 +508,59 @@ SILC_CONFIG_CALLBACK(fetch_logging) return got_errno; } +SILC_CONFIG_CALLBACK(fetch_connparam) +{ + SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionConnectionParam); + + SERVER_CONFIG_DEBUG(("Received CONNPARAM type=%d name=\"%s\" (val=%x)", + type, name, context)); + + if (type == SILC_CONFIG_ARG_BLOCK) { + if (!tmp) + return SILC_CONFIG_OK; + + SILC_SERVER_CONFIG_LIST_APPENDTMP(config->conn_params); + config->tmp = NULL; + return SILC_CONFIG_OK; + } + + /* if there isn't a temporary struct alloc one */ + if (!tmp) { + config->tmp = silc_calloc(1, sizeof(*findtmp)); + tmp = (SilcServerConfigSectionConnectionParam *) config->tmp; + } + + if (!strcmp(name, "name")) { + CONFIG_IS_DOUBLE(tmp->name); + tmp->name = (*(char *)val ? strdup((char *) val) : NULL); + } + else if (!strcmp(name, "keepalive_secs")) { + tmp->keepalive_secs = *(uint32 *)val; + } + else if (!strcmp(name, "reconnect_count")) { + tmp->reconnect_count = *(uint32 *)val; + } + else if (!strcmp(name, "reconnect_interval")) { + tmp->reconnect_interval = *(uint32 *)val; + } + else if (!strcmp(name, "reconnect_interval_max")) { + tmp->reconnect_interval_max = *(uint32 *)val; + } + else if (!strcmp(name, "reconnect_keep_trying")) { + tmp->reconnect_keep_trying = *(bool *)val; + } + else + return SILC_CONFIG_EINTERNAL; + + return SILC_CONFIG_OK; + + got_err: + silc_free(tmp->name); + silc_free(tmp); + config->tmp = NULL; + return got_errno; +} + SILC_CONFIG_CALLBACK(fetch_client) { SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionClient); @@ -469,6 +572,18 @@ SILC_CONFIG_CALLBACK(fetch_client) if (!tmp) /* empty sub-block? */ return SILC_CONFIG_OK; + /* Find connection parameter block */ + if (tmp->param_name) { + tmp->param = my_find_param(config, tmp->param_name); + if (!tmp->param) { + fprintf(stderr, "Unknown ConnectionParam: %s\n", tmp->param_name); + silc_free(tmp->param_name); + got_errno = SILC_CONFIG_ESILENT; + goto got_err; + } + silc_free(tmp->param_name); + } + SILC_SERVER_CONFIG_LIST_APPENDTMP(config->clients); config->tmp = NULL; return SILC_CONFIG_OK; @@ -481,8 +596,8 @@ SILC_CONFIG_CALLBACK(fetch_client) } /* Identify and save this value */ - if (!strcmp(name, "host")) { /* any host (*) accepted */ - if (tmp->host) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; } + if (!strcmp(name, "host")) { + CONFIG_IS_DOUBLE(tmp->host); tmp->host = (*(char *)val ? strdup((char *) val) : NULL); } else if (!strcmp(name, "passphrase")) { @@ -504,13 +619,14 @@ SILC_CONFIG_CALLBACK(fetch_client) int port = *(int *)val; if ((port <= 0) || (port > 65535)) { fprintf(stderr, "Invalid port number!\n"); - got_errno = SILC_CONFIG_ESILENT; goto got_err; + got_errno = SILC_CONFIG_ESILENT; + goto got_err; } tmp->port = (uint16) port; } - /* FIXME: Improvement: use a direct class struct pointer instead of num */ - else if (!strcmp(name, "class")) { - /* XXX do nothing */ + else if (!strcmp(name, "param")) { + CONFIG_IS_DOUBLE(tmp->param_name); + tmp->param_name = (*(char *)val ? strdup((char *) val) : NULL); } else return SILC_CONFIG_EINTERNAL; @@ -548,16 +664,16 @@ SILC_CONFIG_CALLBACK(fetch_admin) } /* Identify and save this value */ - if (!strcmp(name, "host")) { /* any host (*) accepted */ - if (tmp->host) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; } + if (!strcmp(name, "host")) { + CONFIG_IS_DOUBLE(tmp->host); tmp->host = (*(char *)val ? strdup((char *) val) : NULL); } else if (!strcmp(name, "user")) { - if (tmp->user) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; } + CONFIG_IS_DOUBLE(tmp->user); tmp->user = (*(char *)val ? strdup((char *) val) : NULL); } else if (!strcmp(name, "nick")) { - if (tmp->nick) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; } + CONFIG_IS_DOUBLE(tmp->nick); tmp->nick = (*(char *)val ? strdup((char *) val) : NULL); } else if (!strcmp(name, "passphrase")) { @@ -614,8 +730,8 @@ SILC_CONFIG_CALLBACK(fetch_deny) } /* Identify and save this value */ - if (!strcmp(name, "host")) { /* any host (*) accepted */ - if (tmp->host) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; } + if (!strcmp(name, "host")) { + CONFIG_IS_DOUBLE(tmp->host); tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*")); } else if (!strcmp(name, "port")) { @@ -627,7 +743,7 @@ SILC_CONFIG_CALLBACK(fetch_deny) tmp->port = (uint16) port; } else if (!strcmp(name, "reason")) { - if (tmp->reason) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; } + CONFIG_IS_DOUBLE(tmp->reason); tmp->reason = strdup((char *) val); } else @@ -654,6 +770,18 @@ SILC_CONFIG_CALLBACK(fetch_server) if (!tmp) /* empty sub-block? */ return SILC_CONFIG_OK; + /* Find connection parameter block */ + if (tmp->param_name) { + tmp->param = my_find_param(config, tmp->param_name); + if (!tmp->param) { + fprintf(stderr, "Unknown ConnectionParam: %s\n", tmp->param_name); + silc_free(tmp->param_name); + got_errno = SILC_CONFIG_ESILENT; + goto got_err; + } + silc_free(tmp->param_name); + } + /* the temporary struct is ok, append it to the list */ SILC_SERVER_CONFIG_LIST_APPENDTMP(config->servers); config->tmp = NULL; @@ -667,8 +795,8 @@ SILC_CONFIG_CALLBACK(fetch_server) } /* Identify and save this value */ - if (!strcmp(name, "host")) { /* any host (*) accepted */ - if (tmp->host) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; } + if (!strcmp(name, "host")) { + CONFIG_IS_DOUBLE(tmp->host); tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*")); } else if (!strcmp(name, "passphrase")) { @@ -687,12 +815,12 @@ SILC_CONFIG_CALLBACK(fetch_server) } } else if (!strcmp(name, "versionid")) { - if (tmp->version) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; } + CONFIG_IS_DOUBLE(tmp->version); tmp->version = strdup((char *) val); } - /* FIXME: Improvement: use a direct class struct pointer instead of num */ - else if (!strcmp(name, "class")) { - /* XXX do nothing */ + else if (!strcmp(name, "param")) { + CONFIG_IS_DOUBLE(tmp->param_name); + tmp->param_name = (*(char *)val ? strdup((char *) val) : NULL); } else if (!strcmp(name, "backup")) { tmp->backup_router = *(bool *)val; @@ -722,6 +850,18 @@ SILC_CONFIG_CALLBACK(fetch_router) if (!tmp) /* empty sub-block? */ return SILC_CONFIG_OK; + /* Find connection parameter block */ + if (tmp->param_name) { + tmp->param = my_find_param(config, tmp->param_name); + if (!tmp->param) { + fprintf(stderr, "Unknown ConnectionParam: %s\n", tmp->param_name); + silc_free(tmp->param_name); + got_errno = SILC_CONFIG_ESILENT; + goto got_err; + } + silc_free(tmp->param_name); + } + /* the temporary struct is ok, append it to the list */ SILC_SERVER_CONFIG_LIST_APPENDTMP(config->routers); config->tmp = NULL; @@ -736,7 +876,7 @@ SILC_CONFIG_CALLBACK(fetch_router) /* Identify and save this value */ if (!strcmp(name, "host")) { - if (tmp->host) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; } + CONFIG_IS_DOUBLE(tmp->host); tmp->host = strdup((char *) val); } else if (!strcmp(name, "port")) { @@ -763,18 +903,20 @@ SILC_CONFIG_CALLBACK(fetch_router) } } else if (!strcmp(name, "versionid")) { - if (tmp->version) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; } + CONFIG_IS_DOUBLE(tmp->version); tmp->version = strdup((char *) val); } - /* FIXME: Improvement: use a direct class struct pointer instead of num */ - else if (!strcmp(name, "class")) { - /* XXX do nothing */ + else if (!strcmp(name, "param")) { + CONFIG_IS_DOUBLE(tmp->param_name); + tmp->param_name = (*(char *)val ? strdup((char *) val) : NULL); } - else if (!strcmp(name, "initiator")) + else if (!strcmp(name, "initiator")) { tmp->initiator = *(bool *)val; + } else if (!strcmp(name, "backuphost")) { - if (tmp->backup_replace_ip) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; } - tmp->backup_replace_ip = (*(char *)val ? strdup((char *) val) : strdup("*")); + CONFIG_IS_DOUBLE(tmp->backup_replace_ip); + tmp->backup_replace_ip = (*(char *)val ? strdup((char *) val) : + strdup("*")); } else return SILC_CONFIG_EINTERNAL; @@ -793,8 +935,14 @@ SILC_CONFIG_CALLBACK(fetch_router) /* known config options tables */ static const SilcConfigTable table_general[] = { - { "module_path", SILC_CONFIG_ARG_STRE, fetch_generic, NULL }, - { "prefer_passphrase_auth", SILC_CONFIG_ARG_STRE, fetch_generic, NULL }, + { "module_path", SILC_CONFIG_ARG_STRE, fetch_generic, NULL }, + { "prefer_passphrase_auth", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL }, + { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL }, + { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL }, + { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_generic, NULL }, + { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_generic, NULL }, + { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL }, + { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL }, { 0, 0, 0, 0 } }; @@ -860,21 +1008,23 @@ static const SilcConfigTable table_logging[] = { { 0, 0, 0, 0 } }; -/* still unsupported -static const SilcConfigTable table_class[] = { - { "name", SILC_CONFIG_ARG_STR, fetch_class, NULL }, - { "ping", SILC_CONFIG_ARG_INT, fetch_class, NULL }, - { "connect", SILC_CONFIG_ARG_INT, fetch_class, NULL }, - { "links", SILC_CONFIG_ARG_INT, fetch_class, NULL }, +static const SilcConfigTable table_connparam[] = { + { "name", SILC_CONFIG_ARG_STR, fetch_connparam, NULL }, + { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL }, + { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_connparam, NULL }, + { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_connparam, NULL }, + { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_connparam, NULL }, + { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL }, + { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL }, { 0, 0, 0, 0 } -}; */ +}; static const SilcConfigTable table_client[] = { { "host", SILC_CONFIG_ARG_STRE, fetch_client, NULL }, { "passphrase", SILC_CONFIG_ARG_STR, fetch_client, NULL }, { "publickey", SILC_CONFIG_ARG_STR, fetch_client, NULL }, { "port", SILC_CONFIG_ARG_INT, fetch_client, NULL }, - { "class", SILC_CONFIG_ARG_STR, fetch_client, NULL }, + { "param", SILC_CONFIG_ARG_STR, fetch_client, NULL }, { 0, 0, 0, 0 } }; @@ -885,7 +1035,7 @@ static const SilcConfigTable table_admin[] = { { "passphrase", SILC_CONFIG_ARG_STR, fetch_admin, NULL }, { "publickey", SILC_CONFIG_ARG_STR, fetch_admin, NULL }, { "port", SILC_CONFIG_ARG_INT, fetch_admin, NULL }, - { "class", SILC_CONFIG_ARG_STR, fetch_admin, NULL }, + { "param", SILC_CONFIG_ARG_STR, fetch_admin, NULL }, { 0, 0, 0, 0 } }; @@ -901,7 +1051,7 @@ static const SilcConfigTable table_serverconn[] = { { "passphrase", SILC_CONFIG_ARG_STR, fetch_server, NULL }, { "publickey", SILC_CONFIG_ARG_STR, fetch_server, NULL }, { "versionid", SILC_CONFIG_ARG_STR, fetch_server, NULL }, - { "class", SILC_CONFIG_ARG_STR, fetch_server, NULL }, + { "param", SILC_CONFIG_ARG_STR, fetch_server, NULL }, { "backup", SILC_CONFIG_ARG_TOGGLE, fetch_server, NULL }, { 0, 0, 0, 0 } }; @@ -912,7 +1062,7 @@ static const SilcConfigTable table_routerconn[] = { { "passphrase", SILC_CONFIG_ARG_STR, fetch_router, NULL }, { "publickey", SILC_CONFIG_ARG_STR, fetch_router, NULL }, { "versionid", SILC_CONFIG_ARG_STR, fetch_router, NULL }, - { "class", SILC_CONFIG_ARG_STR, fetch_router, NULL }, + { "param", SILC_CONFIG_ARG_STR, fetch_router, NULL }, { "initiator", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL }, { "backuphost", SILC_CONFIG_ARG_STRE, fetch_router, NULL }, { "backupport", SILC_CONFIG_ARG_INT, fetch_router, NULL }, @@ -921,19 +1071,19 @@ static const SilcConfigTable table_routerconn[] = { }; static const SilcConfigTable table_main[] = { - { "general", SILC_CONFIG_ARG_BLOCK, NULL, table_general }, - { "cipher", SILC_CONFIG_ARG_BLOCK, fetch_cipher, table_cipher }, - { "hash", SILC_CONFIG_ARG_BLOCK, fetch_hash, table_hash }, - { "hmac", SILC_CONFIG_ARG_BLOCK, fetch_hmac, table_hmac }, - { "pkcs", SILC_CONFIG_ARG_BLOCK, fetch_pkcs, table_pkcs }, + { "general", SILC_CONFIG_ARG_BLOCK, NULL, table_general }, + { "cipher", SILC_CONFIG_ARG_BLOCK, fetch_cipher, table_cipher }, + { "hash", SILC_CONFIG_ARG_BLOCK, fetch_hash, table_hash }, + { "hmac", SILC_CONFIG_ARG_BLOCK, fetch_hmac, table_hmac }, + { "pkcs", SILC_CONFIG_ARG_BLOCK, fetch_pkcs, table_pkcs }, { "serverinfo", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo }, - { "logging", SILC_CONFIG_ARG_BLOCK, NULL, table_logging }, -/*{ "class", SILC_CONFIG_ARG_BLOCK, fetch_class, table_class }, */ - { "client", SILC_CONFIG_ARG_BLOCK, fetch_client, table_client }, - { "admin", SILC_CONFIG_ARG_BLOCK, fetch_admin, table_admin }, - { "deny", SILC_CONFIG_ARG_BLOCK, fetch_deny, table_deny }, - { "serverconnection", SILC_CONFIG_ARG_BLOCK, fetch_server, table_serverconn }, - { "routerconnection", SILC_CONFIG_ARG_BLOCK, fetch_router, table_routerconn }, + { "logging", SILC_CONFIG_ARG_BLOCK, NULL, table_logging }, + { "connectionparam", SILC_CONFIG_ARG_BLOCK, fetch_connparam, table_connparam }, + { "client", SILC_CONFIG_ARG_BLOCK, fetch_client, table_client }, + { "admin", SILC_CONFIG_ARG_BLOCK, fetch_admin, table_admin }, + { "deny", SILC_CONFIG_ARG_BLOCK, fetch_deny, table_deny }, + { "serverconnection", SILC_CONFIG_ARG_BLOCK, fetch_server, table_serverconn }, + { "routerconnection", SILC_CONFIG_ARG_BLOCK, fetch_router, table_routerconn }, { 0, 0, 0, 0 } }; @@ -1532,3 +1682,26 @@ silc_server_config_get_primary_router(SilcServer server) return NULL; } + +/* Set default values to stuff that was not configured. */ + +bool silc_server_config_set_defaults(SilcServer server) +{ + SilcServerConfig config = server->config; + + config->param.keepalive_secs = (config->param.keepalive_secs ? + config->param.keepalive_secs : + SILC_SERVER_KEEPALIVE); + config->param.reconnect_count = (config->param.reconnect_count ? + config->param.reconnect_count : + SILC_SERVER_RETRY_COUNT); + config->param.reconnect_interval = (config->param.reconnect_interval ? + config->param.reconnect_interval : + SILC_SERVER_RETRY_INTERVAL_MIN); + config->param.reconnect_interval_max = + (config->param.reconnect_interval_max ? + config->param.reconnect_interval_max : + SILC_SERVER_RETRY_INTERVAL_MAX); + + return TRUE; +} diff --git a/apps/silcd/serverconfig.h b/apps/silcd/serverconfig.h index 858abcf6..2a37bb94 100644 --- a/apps/silcd/serverconfig.h +++ b/apps/silcd/serverconfig.h @@ -70,14 +70,20 @@ typedef struct SilcServerConfigSectionLoggingStruct { uint32 maxsize; } SilcServerConfigSectionLogging; -/* Holds all configured connection classes */ -/* typedef struct SilcServerConfigSectionClassStruct { - uint32 class; - uint32 ping_freq; +/* Connection parameters */ +typedef struct SilcServerConfigSectionConnectionParam { + char *name; + uint32 keepalive_secs; + uint32 reconnect_count; + uint32 reconnect_interval; + uint32 reconnect_interval_max; + bool reconnect_keep_trying; + /* uint32 connect_freq; uint32 max_links; - struct SilcServerConfigSectionClassStruct *next; -} SilcServerConfigSectionClass; */ + */ + struct SilcServerConfigSectionConnectionParam *next; +} SilcServerConfigSectionConnectionParam; /* Holds all client authentication data from config file */ typedef struct SilcServerConfigSectionClientStruct { @@ -86,7 +92,8 @@ typedef struct SilcServerConfigSectionClientStruct { uint32 passphrase_len; void *publickey; uint16 port; - uint32 class; + char *param_name; + SilcServerConfigSectionConnectionParam *param; struct SilcServerConfigSectionClientStruct *next; } SilcServerConfigSectionClient; @@ -116,7 +123,8 @@ typedef struct SilcServerConfigSectionServerStruct { uint32 passphrase_len; void *publickey; char *version; - uint32 class; + char *param_name; + SilcServerConfigSectionConnectionParam *param; bool backup_router; struct SilcServerConfigSectionServerStruct *next; } SilcServerConfigSectionServer; @@ -129,7 +137,8 @@ typedef struct SilcServerConfigSectionRouterStruct { void *publickey; uint16 port; char *version; - uint32 class; + char *param_name; + SilcServerConfigSectionConnectionParam *param; bool initiator; bool backup_router; char *backup_replace_ip; @@ -141,9 +150,15 @@ typedef struct SilcServerConfigSectionRouterStruct { /* define the SilcServerConfig object */ typedef struct { void *tmp; + + /* The General section */ char *module_path; bool prefer_passphrase_auth; + bool require_reverse_lookup; + /* XXX Still think whether to actually have params in general... -Pekka */ + SilcServerConfigSectionConnectionParam param; + /* Other configuration sections */ SilcServerConfigSectionCipher *cipher; SilcServerConfigSectionHash *hash; SilcServerConfigSectionHmac *hmac; @@ -153,7 +168,7 @@ typedef struct { SilcServerConfigSectionLogging *logging_errors; SilcServerConfigSectionLogging *logging_fatals; SilcServerConfigSectionServerInfo *server_info; -/*SilcServerConfigSectionClass *conn_class; */ + SilcServerConfigSectionConnectionParam *conn_params; SilcServerConfigSectionClient *clients; SilcServerConfigSectionAdmin *admins; SilcServerConfigSectionDeny *denied; @@ -189,5 +204,6 @@ silc_server_config_find_router_conn(SilcServer server, char *host, int port); bool silc_server_config_is_primary_route(SilcServer server); SilcServerConfigSectionRouter * silc_server_config_get_primary_router(SilcServer server); +bool silc_server_config_set_defaults(SilcServer server); #endif /* !SERVERCONFIG_H */ diff --git a/doc/Makefile.am.pre b/doc/Makefile.am.pre index d61ac41b..9f210b67 100644 --- a/doc/Makefile.am.pre +++ b/doc/Makefile.am.pre @@ -91,4 +91,5 @@ EXTRA_DIST = \ CodingStyle \ FAQ \ example_silcd.conf \ + silcalgs.conf \ draft-riikonen*.txt $(SILC_EXTRA_DIST) diff --git a/doc/example_silcd.conf.in b/doc/example_silcd.conf.in index 86501409..ce9c2e98 100644 --- a/doc/example_silcd.conf.in +++ b/doc/example_silcd.conf.in @@ -1,135 +1,69 @@ # +# silcd.conf +# # Example configuration file. Note that this attempts to present various # configuration possibilities and may not actually give any sensible # configuration. For real life example see the examples/ directory. # +# +# Include global algorithms from the "silcalgs.conf" file. This file +# defines ciphers, hash functions, HMACs and PKCS algorithms that can +# be used. +# +Include "@ETCDIR@/silcalgs.conf"; + # # General configuration options # +# These defines the default behaviour of the server. Most of these values +# can be overridden with ConnectionParam, which can be defined independently +# for different connections. +# General { - # This is the default path where to search modules - # You can comment it out to use builtin modules globally. + # This is the default path where to search modules. If omitted + # built-in modules will be used. Built-in modules will also be + # used if a module file cannot be located. module_path = "@MODULESDIR@"; # If both passphrase and public key authentication is set for a # connection the public key authentication is the preferred one # to use. Set this to `true' to prefer passphrase authentication # over public key authentication in these cases. - # - # prefer_passphrase_auth = true; -}; + #prefer_passphrase_auth = true; -# -# Configured ciphers -# -# The "Module" option can be either absolute or relative to the "ModulePath" -# option. -# If commented out forces using of built-in modules. -# -cipher { - name = "aes-256-cbc"; - module = "aes.sim.so"; - keylength = 32; - blocklength = 16; -}; -cipher { - name = "aes-192-cbc"; - module = "aes.sim.so"; - keylength = 24; - blocklength = 16; -}; -cipher { - name = "aes-128-cbc"; - module = "aes.sim.so"; - keylength = 16; - blocklength = 16; -}; -cipher { - name = "twofish-256-cbc"; - module = "twofish.sim.so"; - keylength = 32; - blocklength = 16; -}; -cipher { - name = "twofish-192-cbc"; - module = "twofish.sim.so"; - keylength = 24; - blocklength = 16; -}; -cipher { - name = "twofish-128-cbc"; - module = "twofish.sim.so"; - keylength = 16; - blocklength = 16; -}; -cipher { - name = "mars-256-cbc"; - module = "mars.sim.so"; - keylength = 32; - blocklength = 16; -}; -cipher { - name = "mars-192-cbc"; - module = "mars.sim.so"; - keylength = 24; - blocklength = 16; -}; -cipher { - name = "mars-128-cbc"; - module = "mars.sim.so"; - keylength = 16; - blocklength = 16; -}; -cipher { - name = "none"; - module = "none.sim.so"; -}; + # Set this to true if you the server to require fully qualified + # domain names (FQDN) for incoming connections. + #require_reverse_lookup = false; -# -# Configured hash functions -# -hash { - name = "sha1"; - blocklength = 64; - digestlength = 20; -}; -hash { - name = "md5"; - blocklength = 64; - digestlength = 16; -}; + # Default keepalive frequency (seconds). This can be overridden + # with ConnectionParam. + keepalive_secs = 300; -# -# Configured HMAC functions. The hash function used in the HMAC must -# be configured in the hash section. -# -hmac { - name = "hmac-sha1-96"; - hash = "sha1"; - maclength = 12; -}; -hmac { - name = "hmac-md5-96"; - hash = "md5"; - maclength = 12; -}; -hmac { - name = "hmac-sha1"; - hash = "sha1"; - maclength = 20; -}; -hmac { - name = "hmac-md5"; - hash = "md5"; - maclength = 16; + # Default reconnection parameters defines how the server reconnect + # to the remote if the connection was lost. The reconnection phase + # use so called exponential backoff algorithm; The reconnect + # interval grows when reconnect count grows. Next example will + # attempt to reconnect after 10 seconds of disconnect, and the + # interval grows up to 600 seconds or until 7 times was attempted + # to reconnect. + # + # reconnect_count - how many times reconnect is attempted + # reconnect_interval - how often reconnect it performed (seconds) + # reconnect_interval_max - maximum interval for reconnect, the + # server never waits longer than this to + # reconnect (seconds). + # reconnect_keep_trying - whether to keep trying even after + # reconnect_count is reached (the interval + # will be reconnect_interval_max). + # + # These can be overridden with ConnectionParam. + reconnect_count = 7; + reconnect_interval = 10; + reconnect_interval_max = 600; + reconnect_keep_trying = true; }; -# -# Configured PKCS -# -PKCS { name = "rsa"; }; - # # Server information # @@ -234,33 +168,76 @@ Logging { }; # -# Connection classes (UNSUPPORTED) +# Connection Parameters # -# This section is used to define connection classes. These can be -# used to optimize the server and the connections. +# This section defined connection parameters. It is possible to use +# specific parameters in different connections, and to define different +# parameters to different connections. The parameters can define how the +# connection is handled and how the session is managed. If connection +# parameters are not used in connections the default values will apply +# (or values defined in General section). You can have multiple +# ConnectionParams blocks defined. # -#Class { -# Name = "norm"; -# Ping = 100; -# Connect = 100; -# Links = 100; -#}; +ConnectionParam { + # unique name. The name is used to reference to this parameter + # block from the connections. + name = "normal"; + + # Keepalive frequency (seconds). + keepalive_secs = 300; + + # Reconnection parameters defines how the server reconnects to + # the remote if the connection was lost. The reconnection phase + # use so called exponential backoff algorithm; The reconnect + # interval grows when reconnect count grows. Next example will + # attempt to reconnect after 10 seconds of disconnect, and the + # interval grows up to 600 seconds or until 7 times was attempted + # to reconnect. + # + # reconnect_count - how many times reconnect is attempted + # reconnect_interval - how often reconnect it performed (seconds) + # reconnect_interval_max - maximum interval for reconnect, the + # server never waits longer than this to + # reconnect (seconds). + # reconnect_keep_trying - whether to keep trying even after + # reconnect_count is reached (the interval + # will be reconnect_interval_max). + reconnect_count = 7; + reconnect_interval = 10; + reconnect_interval_max = 600; + reconnect_keep_trying = true; + + #TODO: + #key_exchange_rekey - rekey timeout + #key_exchange_pfs - rekey PFS + #key_exchange_mutual_auth - SKE mutual auth + + #connections_max - max incoming connection + #connections_interval - incoming connection interval limit ? +}; # # Configured client connections. # -# All fields except Class are optional. Omitted fields are assumed -# to be generic (e.g. if the "Host" field is omitted all hosts will match -# this client class). +# The "host" defines the incoming IP address or hostname of the client. +# If it is omitted all hosts will match this client connection. The +# "param" is optional and can be used to set specific connection parameters +# for this connection. # -#Client { -# Host = "127.0.0.1"; -# Port = 706; -# Class = "local"; -#}; -Client { - Port = 706; - Class = "norm"; +# The authentication data is specified by Passphrase and/or Publickey. +# If both are provided then both password and public key based authentication +# is allowed. If the Publickey is used it includes the file path to the +# public key file. If none of them is provided then authentication is not +# required. +# +# Next example connection will match to all incoming client connections, +# and no authentication is required +# +Client { + #host = ""; + #passphrase = "secret"; + #publickey = "/path/to/the/public.key"; + param = "normal"; }; # @@ -283,24 +260,6 @@ Admin { # Publickey = "/path/to/the/public.key"; }; -# -# Denied connections -# -# These connections are denied to connect to our server. -# -# The "Reason" field is mandatory, while the "Host" and "Port" fields can be -# omitted to match everything. -# -#Deny { -# Host = "10.2.1.99"; -# Port = 706; -# Reason = "Go away spammer"; -#}; -#Deny { -# Host = "10.3.*"; -# Reason = "You are not welcome."; -#}; - # # Configured server connections. # @@ -324,7 +283,7 @@ ServerConnection { Passphrase = "verysecret"; # Publickey = "/path/to/the/public.key"; VersionID = 1; - Class = "norm"; + Param = "normal"; Backup = false; }; @@ -359,9 +318,27 @@ RouterConnection { Passphrase = "verysecret"; # Publickey = "/path/to/the/public.key"; VersionID = 1; - Class = "norm"; + Param = "normal"; Initiator = true; #BackupHost = "10.2.1.6"; #BackupPort = 706; #LocalBackup = true; }; + +# +# Denied connections +# +# These connections are denied to connect to our server. +# +# The "Reason" field is mandatory, while the "Host" and "Port" fields can be +# omitted to match everything. +# +#Deny { +# Host = "10.2.1.99"; +# Port = 706; +# Reason = "Go away spammer"; +#}; +#Deny { +# Host = "10.3.*"; +# Reason = "You are not welcome."; +#}; diff --git a/doc/silcalgs.conf b/doc/silcalgs.conf new file mode 100644 index 00000000..a0fb89bb --- /dev/null +++ b/doc/silcalgs.conf @@ -0,0 +1,123 @@ +# +# Algorithms +# +# This file defines ciphers, hash functions, HMACs and PKCS algorithms that +# can be used. This file can be included into different configuration files. +# +# You should not change the contents of this file unless you know what you +# are doing. +# + +# +# Configured ciphers +# +# The "name" is unique name to the cipher. The "module" option can be either +# absolute or relative to the "module_path", and it defines where the cipher +# module is found. If omitted the built-in cipher is used. The "keylength" +# defines the length of the key (bytes), and the "blocklength" defines the +# block size of the cipher (bytes). +# +cipher { + name = "aes-256-cbc"; + module = "aes.sim.so"; + keylength = 32; + blocklength = 16; +}; +cipher { + name = "aes-192-cbc"; + module = "aes.sim.so"; + keylength = 24; + blocklength = 16; +}; +cipher { + name = "aes-128-cbc"; + module = "aes.sim.so"; + keylength = 16; + blocklength = 16; +}; +cipher { + name = "twofish-256-cbc"; + module = "twofish.sim.so"; + keylength = 32; + blocklength = 16; +}; +cipher { + name = "twofish-192-cbc"; + module = "twofish.sim.so"; + keylength = 24; + blocklength = 16; +}; +cipher { + name = "twofish-128-cbc"; + module = "twofish.sim.so"; + keylength = 16; + blocklength = 16; +}; +cipher { + name = "mars-256-cbc"; + module = "mars.sim.so"; + keylength = 32; + blocklength = 16; +}; +cipher { + name = "mars-192-cbc"; + module = "mars.sim.so"; + keylength = 24; + blocklength = 16; +}; +cipher { + name = "mars-128-cbc"; + module = "mars.sim.so"; + keylength = 16; + blocklength = 16; +}; +cipher { + name = "none"; + module = "none.sim.so"; +}; + +# +# Configured hash functions +# +hash { + name = "sha1"; + blocklength = 64; + digestlength = 20; +}; +hash { + name = "md5"; + blocklength = 64; + digestlength = 16; +}; + +# +# Configured HMAC functions. The hash function used in the HMAC must +# be configured in the hash section. +# +hmac { + name = "hmac-sha1-96"; + hash = "sha1"; + maclength = 12; +}; +hmac { + name = "hmac-md5-96"; + hash = "md5"; + maclength = 12; +}; +hmac { + name = "hmac-sha1"; + hash = "sha1"; + maclength = 20; +}; +hmac { + name = "hmac-md5"; + hash = "md5"; + maclength = 16; +}; + +# +# Configured PKCS +# +PKCS { + name = "rsa"; +};