1 /*
2
3 server.c
4
5 Author: Pekka Riikonen <priikone@silcnet.org>
6
7 Copyright (C) 1997 - 2005 Pekka Riikonen
8
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.
12
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.
17
18 */
19 /*
20 * This is the actual SILC server than handles everything relating to
21 * servicing the SILC connections. This is also a SILC router as a router
22 * is also normal server.
23 */
24 /* $Id: server.c,v 1.347 2005/04/23 13:32:24 priikone Exp $ */
25
26 #include "serverincludes.h"
27 #include "server_internal.h"
28
29 /* Static prototypes */
30 SILC_TASK_CALLBACK(silc_server_rehash_close_connection);
31 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry);
32 SILC_TASK_CALLBACK(silc_server_connect_router);
33 SILC_TASK_CALLBACK(silc_server_connect_to_router_second);
34 SILC_TASK_CALLBACK(silc_server_connect_to_router_final);
35 SILC_TASK_CALLBACK(silc_server_accept_new_connection);
36 SILC_TASK_CALLBACK(silc_server_accept_new_connection_second);
37 SILC_TASK_CALLBACK(silc_server_accept_new_connection_final);
38 SILC_TASK_CALLBACK(silc_server_packet_process);
39 SILC_TASK_CALLBACK(silc_server_packet_parse_real);
40 SILC_TASK_CALLBACK(silc_server_close_connection_final);
41 SILC_TASK_CALLBACK(silc_server_free_client_data_timeout);
42 SILC_TASK_CALLBACK(silc_server_timeout_remote);
43 SILC_TASK_CALLBACK(silc_server_channel_key_rekey);
44 SILC_TASK_CALLBACK(silc_server_get_stats);
45 SILC_TASK_CALLBACK(silc_server_connect_router);
46
47 /* Allocates a new SILC server object. This has to be done before the server
48 can be used. After allocation one must call silc_server_init to initialize
49 the server. The new allocated server object is returned to the new_server
50 argument. */
51
52 int silc_server_alloc(SilcServer *new_server)
53 {
54 SilcServer server;
55
56 SILC_LOG_DEBUG(("Allocating new server object"));
57
58 server = silc_calloc(1, sizeof(*server));
59 server->server_type = SILC_SERVER;
60 server->standalone = TRUE;
61 server->local_list = silc_calloc(1, sizeof(*server->local_list));
62 server->global_list = silc_calloc(1, sizeof(*server->global_list));
63 server->pending_commands = silc_dlist_init();
64 #ifdef SILC_SIM
65 server->sim = silc_dlist_init();
66 #endif
67
68 *new_server = server;
69
70 return TRUE;
71 }
72
73 /* Free's the SILC server object. This is called at the very end before
74 the program ends. */
75
76 void silc_server_free(SilcServer server)
77 {
78 SilcIDCacheList list;
79 SilcIDCacheEntry cache;
80
81 if (!server)
82 return;
83
84 #ifdef SILC_SIM
85 {
86 SilcSim sim;
87 silc_dlist_start(server->sim);
88 while ((sim = silc_dlist_get(server->sim)) != SILC_LIST_END) {
89 silc_dlist_del(server->sim, sim);
90 silc_sim_close(sim);
91 silc_sim_free(sim);
92 }
93 silc_dlist_uninit(server->sim);
94 }
95 #endif
96
97 silc_server_backup_free(server);
98 silc_server_config_unref(&server->config_ref);
99 if (server->rng)
100 silc_rng_free(server->rng);
101 if (server->pkcs)
102 silc_pkcs_free(server->pkcs);
103 if (server->public_key)
104 silc_pkcs_public_key_free(server->public_key);
105 if (server->private_key)
106 silc_pkcs_private_key_free(server->private_key);
107 if (server->pending_commands)
108 silc_dlist_uninit(server->pending_commands);
109 if (server->id_entry)
110 silc_idlist_del_server(server->local_list, server->id_entry);
111
112 /* Delete all channels */
113 list = NULL;
114 if (silc_idcache_get_all(server->local_list->channels, &list) &&
115 silc_idcache_list_first(list, &cache)) {
116 silc_idlist_del_channel(server->local_list, cache->context);
117 while (silc_idcache_list_next(list, &cache))
118 silc_idlist_del_channel(server->local_list, cache->context);
119 }
120 if (list)
121 silc_idcache_list_free(list);
122 list = NULL;
123 if (silc_idcache_get_all(server->global_list->channels, &list) &&
124 silc_idcache_list_first(list, &cache)) {
125 silc_idlist_del_channel(server->global_list, cache->context);
126 while (silc_idcache_list_next(list, &cache))
127 silc_idlist_del_channel(server->global_list, cache->context);
128 }
129 if (list)
130 silc_idcache_list_free(list);
131
132 if (server->pk_hash)
133 silc_hash_table_free(server->pk_hash);
134
135 /* Delete all clients */
136 list = NULL;
137 if (silc_idcache_get_all(server->local_list->clients, &list) &&
138 silc_idcache_list_first(list, &cache)) {
139 silc_idlist_del_client(server->local_list, cache->context);
140 while (silc_idcache_list_next(list, &cache))
141 silc_idlist_del_client(server->local_list, cache->context);
142 }
143 if (list)
144 silc_idcache_list_free(list);
145 list = NULL;
146 if (silc_idcache_get_all(server->global_list->clients, &list) &&
147 silc_idcache_list_first(list, &cache)) {
148 silc_idlist_del_client(server->global_list, cache->context);
149 while (silc_idcache_list_next(list, &cache))
150 silc_idlist_del_client(server->global_list, cache->context);
151 }
152 if (list)
153 silc_idcache_list_free(list);
154
155
156 /* Delete all servers */
157 list = NULL;
158 if (silc_idcache_get_all(server->local_list->servers, &list) &&
159 silc_idcache_list_first(list, &cache)) {
160 silc_idlist_del_server(server->local_list, cache->context);
161 while (silc_idcache_list_next(list, &cache))
162 silc_idlist_del_server(server->local_list, cache->context);
163 }
164 if (list)
165 silc_idcache_list_free(list);
166 list = NULL;
167 if (silc_idcache_get_all(server->global_list->servers, &list) &&
168 silc_idcache_list_first(list, &cache)) {
169 silc_idlist_del_server(server->global_list, cache->context);
170 while (silc_idcache_list_next(list, &cache))
171 silc_idlist_del_server(server->global_list, cache->context);
172 }
173 if (list)
174 silc_idcache_list_free(list);
175
176 silc_idcache_free(server->local_list->clients);
177 silc_idcache_free(server->local_list->servers);
178 silc_idcache_free(server->local_list->channels);
179 silc_idcache_free(server->global_list->clients);
180 silc_idcache_free(server->global_list->servers);
181 silc_idcache_free(server->global_list->channels);
182 silc_hash_table_free(server->watcher_list);
183 silc_hash_table_free(server->watcher_list_pk);
184
185 silc_hash_free(server->md5hash);
186 silc_hash_free(server->sha1hash);
187 silc_hmac_unregister_all();
188 silc_hash_unregister_all();
189 silc_cipher_unregister_all();
190 silc_pkcs_unregister_all();
191
192 silc_free(server->local_list);
193 silc_free(server->global_list);
194 silc_free(server->server_name);
195 silc_free(server->id_string);
196 silc_free(server->purge_i);
197 silc_free(server->purge_g);
198 silc_free(server);
199 }
200
201 /* Creates a new server listener. */
202
203 static bool silc_server_listen(SilcServer server, const char *server_ip,
204 SilcUInt16 port, int *sock)
205 {
206 *sock = silc_net_create_server(port, server_ip);
207 if (*sock < 0) {
208 SILC_SERVER_LOG_ERROR(("Could not create server listener: %s on %hu",
209 server_ip, port));
210 return FALSE;
211 }
212 return TRUE;
213 }
214
215 /* Adds a secondary listener. */
216
217 bool silc_server_init_secondary(SilcServer server)
218 {
219 int sock = 0, sock_list[server->config->param.connections_max];
220 SilcSocketConnection newsocket = NULL;
221 SilcServerConfigServerInfoInterface *interface;
222
223 for (interface = server->config->server_info->secondary; interface;
224 interface = interface->next, sock++) {
225
226 if (!silc_server_listen(server,
227 interface->server_ip, interface->port, &sock_list[sock]))
228 goto err;
229
230 /* Set socket to non-blocking mode */
231 silc_net_set_socket_nonblock(sock_list[sock]);
232
233 /* Add ourselves also to the socket table. The entry allocated above
234 is sent as argument for fast referencing in the future. */
235 silc_socket_alloc(sock_list[sock],
236 SILC_SOCKET_TYPE_SERVER, NULL, &newsocket);
237 server->sockets[sock_list[sock]] = newsocket;
238 SILC_SET_LISTENER(newsocket);
239
240 /* Perform name and address lookups to resolve the listenning address
241 and port. */
242 if (!silc_net_check_local_by_sock(sock_list[sock], &newsocket->hostname,
243 &newsocket->ip)) {
244 if ((server->config->require_reverse_lookup && !newsocket->hostname) ||
245 !newsocket->ip) {
246 SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s",
247 newsocket->hostname ? newsocket->hostname :
248 newsocket->ip ? newsocket->ip : ""));
249 server->stat.conn_failures++;
250 goto err;
251 }
252 if (!newsocket->hostname)
253 newsocket->hostname = strdup(newsocket->ip);
254 }
255 newsocket->port = silc_net_get_local_port(sock);
256
257 newsocket->user_data = (void *)server->id_entry;
258 silc_schedule_task_add(server->schedule, sock_list[sock],
259 silc_server_accept_new_connection,
260 (void *)server, 0, 0,
261 SILC_TASK_FD,
262 SILC_TASK_PRI_NORMAL);
263 }
264
265 return TRUE;
266
267 err:
268 do silc_net_close_server(sock_list[sock--]); while (sock >= 0);
269 return FALSE;
270 }
271
272 /* Initializes the entire SILC server. This is called always before running
273 the server. This is called only once at the initialization of the program.
274 This binds the server to its listenning port. After this function returns
275 one should call silc_server_run to start the server. This returns TRUE
276 when everything is ok to run the server. Configuration file must be
277 read and parsed before calling this. */
278
279 bool silc_server_init(SilcServer server)
280 {
281 int sock = -1;
282 SilcServerID *id;
283 SilcServerEntry id_entry;
284 SilcIDListPurge purge;
285 SilcSocketConnection newsocket = NULL;
286
287 SILC_LOG_DEBUG(("Initializing server"));
288
289 server->starttime = time(NULL);
290
291 /* Take config object for us */
292 silc_server_config_ref(&server->config_ref, server->config,
293 server->config);
294
295 #ifdef SILC_DEBUG
296 /* Set debugging on if configured */
297 if (server->config->debug_string) {
298 silc_debug = TRUE;
299 silc_log_set_debug_string(server->config->debug_string);
300 }
301 #endif /* SILC_DEBUG */
302
303 /* Steal public and private key from the config object */
304 server->public_key = server->config->server_info->public_key;
305 server->private_key = server->config->server_info->private_key;
306 server->config->server_info->public_key = NULL;
307 server->config->server_info->private_key = NULL;
308
309 /* Register all configured ciphers, PKCS and hash functions. */
310 if (!silc_server_config_register_ciphers(server))
311 silc_cipher_register_default();
312 if (!silc_server_config_register_pkcs(server))
313 silc_pkcs_register_default();
314 if (!silc_server_config_register_hashfuncs(server))
315 silc_hash_register_default();
316 if (!silc_server_config_register_hmacs(server))
317 silc_hmac_register_default();
318
319 /* Initialize random number generator for the server. */
320 server->rng = silc_rng_alloc();
321 silc_rng_init(server->rng);
322 silc_rng_global_init(server->rng);
323
324 /* Initialize hash functions for server to use */
325 silc_hash_alloc("md5", &server->md5hash);
326 silc_hash_alloc("sha1", &server->sha1hash);
327
328 /* Allocate PKCS context for local public and private keys */
329 if (!silc_pkcs_alloc(server->public_key->name, &server->pkcs))
330 goto err;
331 silc_pkcs_public_key_set(server->pkcs, server->public_key);
332 silc_pkcs_private_key_set(server->pkcs, server->private_key);
333
334 /* Initialize the scheduler */
335 server->schedule = silc_schedule_init(server->config->param.connections_max,
336 server);
337 if (!server->schedule)
338 goto err;
339
340 /* First, register log files configuration for error output */
341 silc_server_config_setlogfiles(server);
342
343 /* Initialize ID caches */
344 server->local_list->clients =
345 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
346 server, FALSE, TRUE);
347 server->local_list->servers =
348 silc_idcache_alloc(0, SILC_ID_SERVER, NULL, NULL, FALSE, TRUE);
349 server->local_list->channels =
350 silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL, NULL, FALSE, TRUE);
351
352 /* These are allocated for normal server as well as these hold some
353 global information that the server has fetched from its router. For
354 router these are used as they are supposed to be used on router. */
355 server->global_list->clients =
356 silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
357 server, FALSE, TRUE);
358 server->global_list->servers =
359 silc_idcache_alloc(0, SILC_ID_SERVER, NULL, NULL, FALSE, TRUE);
360 server->global_list->channels =
361 silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL, NULL, FALSE, TRUE);
362
363 /* Init watcher lists */
364 server->watcher_list =
365 silc_hash_table_alloc(1, silc_hash_client_id_hash, NULL,
366 silc_hash_data_compare, (void *)CLIENTID_HASH_LEN,
367 NULL, NULL, TRUE);
368 if (!server->watcher_list)
369 goto err;
370 server->watcher_list_pk =
371 silc_hash_table_alloc(1, silc_hash_public_key, NULL,
372 silc_hash_public_key_compare, NULL,
373 NULL, NULL, TRUE);
374 if (!server->watcher_list_pk)
375 goto err;
376
377 /* Init public key list */
378 server->pk_hash =
379 silc_hash_table_alloc(0, silc_hash_public_key, NULL,
380 silc_hash_public_key_compare, NULL,
381 NULL, NULL, TRUE);
382
383 if (!server->pk_hash)
384 goto err;
385
386 /* Create a listening server */
387 if (!silc_server_listen(server,
388 server->config->server_info->primary == NULL ? NULL :
389 server->config->server_info->primary->server_ip,
390 server->config->server_info->primary == NULL ? 0 :
391 server->config->server_info->primary->port,
392 &sock))
393 goto err;
394
395 /* Set socket to non-blocking mode */
396 silc_net_set_socket_nonblock(sock);
397 server->sock = sock;
398
399 /* Allocate the entire socket list that is used in server. Eventually
400 all connections will have entry in this table (it is a table of
401 pointers to the actual object that is allocated individually
402 later). */
403 server->sockets = silc_calloc(server->config->param.connections_max,
404 sizeof(*server->sockets));
405 if (!server->sockets)
406 goto err;
407
408 /* Add ourselves also to the socket table. The entry allocated above
409 is sent as argument for fast referencing in the future. */
410 silc_socket_alloc(sock, SILC_SOCKET_TYPE_SERVER, NULL, &newsocket);
411 server->sockets[sock] = newsocket;
412 SILC_SET_LISTENER(newsocket);
413
414 /* Perform name and address lookups to resolve the listenning address
415 and port. */
416 if (!silc_net_check_local_by_sock(sock, &newsocket->hostname,
417 &newsocket->ip)) {
418 if ((server->config->require_reverse_lookup && !newsocket->hostname) ||
419 !newsocket->ip) {
420 SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s",
421 newsocket->hostname ? newsocket->hostname :
422 newsocket->ip ? newsocket->ip : ""));
423 server->stat.conn_failures++;
424 goto err;
425 }
426 if (!newsocket->hostname)
427 newsocket->hostname = strdup(newsocket->ip);
428 }
429 newsocket->port = silc_net_get_local_port(sock);
430
431 /* Create a Server ID for the server. */
432 silc_id_create_server_id(newsocket->ip, newsocket->port, server->rng, &id);
433 if (!id)
434 goto err;
435
436 server->id = id;
437 server->id_string = silc_id_id2str(id, SILC_ID_SERVER);
438 server->id_string_len = silc_id_get_len(id, SILC_ID_SERVER);
439 server->server_name = server->config->server_info->server_name;
440 server->config->server_info->server_name = NULL;
441
442 /* Add ourselves to the server list. We don't have a router yet
443 beacuse we haven't established a route yet. It will be done later.
444 For now, NULL is sent as router. This allocates new entry to
445 the ID list. */
446 id_entry =
447 silc_idlist_add_server(server->local_list, strdup(server->server_name),
448 server->server_type, server->id, NULL, NULL);
449 if (!id_entry) {
450 SILC_LOG_ERROR(("Could not add ourselves to cache"));
451 goto err;
452 }
453 id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
454
455 /* Put the allocated socket pointer also to the entry allocated above
456 for fast back-referencing to the socket list. */
457 newsocket->user_data = (void *)id_entry;
458 id_entry->connection = (void *)newsocket;
459 server->id_entry = id_entry;
460
461 /* Register protocols */
462 silc_server_protocols_register();
463
464 /* Create connections to configured routers. */
465 silc_server_create_connections(server);
466
467 /* Add listener task to the scheduler. This task receives new connections
468 to the server. This task remains on the queue until the end of the
469 program. */
470 silc_schedule_task_add(server->schedule, sock,
471 silc_server_accept_new_connection,
472 (void *)server, 0, 0,
473 SILC_TASK_FD,
474 SILC_TASK_PRI_NORMAL);
475
476 if (silc_server_init_secondary(server) == FALSE)
477 goto err;
478
479 server->listenning = TRUE;
480
481 /* If server connections has been configured then we must be router as
482 normal server cannot have server connections, only router connections. */
483 if (server->config->servers) {
484 SilcServerConfigServer *ptr = server->config->servers;
485
486 server->server_type = SILC_ROUTER;
487 while (ptr) {
488 if (ptr->backup_router) {
489 server->server_type = SILC_BACKUP_ROUTER;
490 server->backup_router = TRUE;
491 server->id_entry->server_type = SILC_BACKUP_ROUTER;
492 break;
493 }
494 ptr = ptr->next;
495 }
496 }
497
498 /* Register the ID Cache purge task. This periodically purges the ID cache
499 and removes the expired cache entries. */
500
501 /* Clients local list */
502 server->purge_i = purge = silc_calloc(1, sizeof(*purge));
503 purge->cache = server->local_list->clients;
504 purge->timeout = 600;
505 silc_schedule_task_add(server->schedule, 0, silc_idlist_purge,
506 (void *)purge, purge->timeout, 0,
507 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
508
509 /* Clients global list */
510 server->purge_g = purge = silc_calloc(1, sizeof(*purge));
511 purge->cache = server->global_list->clients;
512 purge->timeout = 300;
513 silc_schedule_task_add(server->schedule, 0, silc_idlist_purge,
514 (void *)purge, purge->timeout, 0,
515 SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
516
517 /* If we are normal server we'll retrieve network statisticial information
518 once in a while from the router. */
519 if (server->server_type != SILC_ROUTER)
520 silc_schedule_task_add(server->schedule, 0, silc_server_get_stats,
521 server, 10, 0, SILC_TASK_TIMEOUT,
522 SILC_TASK_PRI_LOW);
523
524 if (server->server_type == SILC_ROUTER)
525 server->stat.routers++;
526
527 SILC_LOG_DEBUG(("Server initialized"));
528
529 /* We are done here, return succesfully */
530 return TRUE;
531
532 err:
533 silc_server_config_unref(&server->config_ref);
534 silc_net_close_server(sock);
535 return FALSE;
536 }
537
538 /* Task callback to close a socket connection after rehash */
539
540 SILC_TASK_CALLBACK(silc_server_rehash_close_connection)
541 {
542 SilcServer server = context;
543 SilcSocketConnection sock = server->sockets[fd];
544
545 if (!sock)
546 return;
547
548 SILC_LOG_INFO(("Connection %s:%d [%s] is unconfigured",
549 sock->hostname, sock->port,
550 (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
551 sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
552 sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
553 "Router")));
554 silc_schedule_task_del_by_context(server->schedule, sock);
555 silc_server_disconnect_remote(server, sock,
556 SILC_STATUS_ERR_BANNED_FROM_SERVER,
557 "This connection is removed from "
558 "configuration");
559 if (sock->user_data)
560 silc_server_free_sock_user_data(server, sock, NULL);
561 }
562
563 /* This function basically reads the config file again and switches the config
564 object pointed by the server object. After that, we have to fix various
565 things such as the server_name and the listening ports.
566 Keep in mind that we no longer have the root privileges at this point. */
567
568 bool silc_server_rehash(SilcServer server)
569 {
570 SilcServerConfig newconfig;
571
572 SILC_LOG_INFO(("Rehashing server"));
573
574 /* Reset the logging system */
575 silc_log_quick = TRUE;
576 silc_log_flush_all();
577
578 /* Start the main rehash phase (read again the config file) */
579 newconfig = silc_server_config_alloc(server->config_file);
580 if (!newconfig) {
581 SILC_LOG_ERROR(("Rehash FAILED."));
582 return FALSE;
583 }
584
585 /* Reinit scheduler if necessary */
586 if (newconfig->param.connections_max > server->config->param.connections_max)
587 if (!silc_schedule_reinit(server->schedule,
588 newconfig->param.connections_max))
589 return FALSE;
590
591 /* Fix the server_name field */
592 if (strcmp(server->server_name, newconfig->server_info->server_name)) {
593 silc_free(server->server_name);
594
595 /* Check server name */
596 server->server_name =
597 silc_identifier_check(newconfig->server_info->server_name,
598 strlen(newconfig->server_info->server_name),
599 SILC_STRING_LOCALE, 256, NULL);
600 if (!server->server_name) {
601 SILC_LOG_ERROR(("Malformed server name string '%s'",
602 server->config->server_info->server_name));
603 return FALSE;
604 }
605
606 /* Update the idcache list with a fresh pointer */
607 silc_free(server->id_entry->server_name);
608 server->id_entry->server_name = strdup(server->server_name);
609 if (!silc_idcache_del_by_context(server->local_list->servers,
610 server->id_entry))
611 return FALSE;
612 if (!silc_idcache_add(server->local_list->servers,
613 strdup(server->id_entry->server_name),
614 server->id_entry->id, server->id_entry, 0, NULL))
615 return FALSE;
616 }
617
618 /* Set logging */
619 silc_server_config_setlogfiles(server);
620
621 /* Change new key pair if necessary */
622 if (newconfig->server_info->public_key &&
623 !silc_pkcs_public_key_compare(server->public_key,
624 newconfig->server_info->public_key)) {
625 silc_pkcs_public_key_free(server->public_key);
626 silc_pkcs_private_key_free(server->private_key);
627 server->public_key = newconfig->server_info->public_key;
628 server->private_key = newconfig->server_info->private_key;
629 newconfig->server_info->public_key = NULL;
630 newconfig->server_info->private_key = NULL;
631
632 /* Allocate PKCS context for local public and private keys */
633 silc_pkcs_free(server->pkcs);
634 if (!silc_pkcs_alloc(server->public_key->name, &server->pkcs))
635 return FALSE;
636 silc_pkcs_public_key_set(server->pkcs, server->public_key);
637 silc_pkcs_private_key_set(server->pkcs, server->private_key);
638 }
639
640 /* Check for unconfigured server and router connections and close
641 connections that were unconfigured. */
642
643 if (server->config->routers) {
644 SilcServerConfigRouter *ptr;
645 SilcServerConfigRouter *newptr;
646 bool found;
647
648 for (ptr = server->config->routers; ptr; ptr = ptr->next) {
649 found = FALSE;
650
651 /* Check whether new config has this one too */
652 for (newptr = newconfig->routers; newptr; newptr = newptr->next) {
653 if (silc_string_compare(newptr->host, ptr->host) &&
654 newptr->port == ptr->port &&
655 newptr->initiator == ptr->initiator) {
656 found = TRUE;
657 break;
658 }
659 }
660
661 if (!found && ptr->host) {
662 /* Remove this connection */
663 SilcSocketConnection sock;
664 sock = silc_server_find_socket_by_host(server, SILC_SOCKET_TYPE_ROUTER,
665 ptr->host, ptr->port);
666 if (sock && !SILC_IS_LISTENER(sock))
667 silc_schedule_task_add(server->schedule, sock->sock,
668 silc_server_rehash_close_connection,
669 server, 0, 1, SILC_TASK_TIMEOUT,
670 SILC_TASK_PRI_NORMAL);
671 }
672 }
673 }
674
675 if (server->config->servers) {
676 SilcServerConfigServer *ptr;
677 SilcServerConfigServer *newptr;
678 bool found;
679
680 for (ptr = server->config->servers; ptr; ptr = ptr->next) {
681 found = FALSE;
682
683 /* Check whether new config has this one too */
684 for (newptr = newconfig->servers; newptr; newptr = newptr->next) {
685 if (silc_string_compare(newptr->host, ptr->host)) {
686 found = TRUE;
687 break;
688 }
689 }
690
691 if (!found && ptr->host) {
692 /* Remove this connection */
693 SilcSocketConnection sock;
694 sock = silc_server_find_socket_by_host(server, SILC_SOCKET_TYPE_SERVER,
695 ptr->host, 0);
696 if (sock && !SILC_IS_LISTENER(sock))
697 silc_schedule_task_add(server->schedule, sock->sock,
698 silc_server_rehash_close_connection,
699 server, 0, 1, SILC_TASK_TIMEOUT,
700 SILC_TASK_PRI_NORMAL);
701 }
702 }
703 }
704
705 if (server->config->clients) {
706 SilcServerConfigClient *ptr;
707 SilcServerConfigClient *newptr;
708 bool found;
709
710 for (ptr = server->config->clients; ptr; ptr = ptr->next) {
711 found = FALSE;
712
713 /* Check whether new config has this one too */
714 for (newptr = newconfig->clients; newptr; newptr = newptr->next) {
715 if (silc_string_compare(newptr->host, ptr->host)) {
716 found = TRUE;
717 break;
718 }
719 }
720
721 if (!found && ptr->host) {
722 /* Remove this connection */
723 SilcSocketConnection sock;
724 sock = silc_server_find_socket_by_host(server, SILC_SOCKET_TYPE_CLIENT,
725 ptr->host, 0);
726 if (sock)
727 silc_schedule_task_add(server->schedule, sock->sock,
728 silc_server_rehash_close_connection,
729 server, 0, 1, SILC_TASK_TIMEOUT,
730 SILC_TASK_PRI_NORMAL);
731 }
732 }
733 }
734
735 /* Create connections after rehash */
736 silc_server_create_connections(server);
737
738 /* Check whether our router status has changed */
739 if (newconfig->servers) {
740 SilcServerConfigServer *ptr = newconfig->servers;
741
742 server->server_type = SILC_ROUTER;
743 while (ptr) {
744 if (ptr->backup_router) {
745 server->server_type = SILC_BACKUP_ROUTER;
746 server->backup_router = TRUE;
747 server->id_entry->server_type = SILC_BACKUP_ROUTER;
748 break;
749 }
750 ptr = ptr->next;
751 }
752 }
753
754 /* Our old config is gone now. We'll unreference our reference made in
755 silc_server_init and then destroy it since we are destroying it
756 underneath the application (layer which called silc_server_init). */
757 silc_server_config_unref(&server->config_ref);
758 silc_server_config_destroy(server->config);
759
760 /* Take new config context */
761 server->config = newconfig;
762 silc_server_config_ref(&server->config_ref, server->config, server->config);
763
764 #ifdef SILC_DEBUG
765 /* Set debugging on if configured */
766 if (server->config->debug_string) {
767 silc_debug = TRUE;
768 silc_log_set_debug_string(server->config->debug_string);
769 }
770 #endif /* SILC_DEBUG */
771
772 SILC_LOG_DEBUG(("Server rehashed"));
773
774 return TRUE;
775 }
776
777 /* The heart of the server. This runs the scheduler thus runs the server.
778 When this returns the server has been stopped and the program will
779 be terminated. */
780
781 void silc_server_run(SilcServer server)
782 {
783 SILC_LOG_INFO(("SILC Server started"));
784
785 /* Start the scheduler, the heart of the SILC server. When this returns
786 the program will be terminated. */
787 silc_schedule(server->schedule);
788 }
789
790 /* Stops the SILC server. This function is used to shutdown the server.
791 This is usually called after the scheduler has returned. After stopping
792 the server one should call silc_server_free. */
793
794 void silc_server_stop(SilcServer server)
795 {
796 SILC_LOG_INFO(("SILC Server shutting down"));
797
798 if (server->schedule) {
799 int i;
800
801 server->server_shutdown = TRUE;
802
803 /* Close all connections */
804 for (i = 0; i < server->config->param.connections_max; i++) {
805 if (!server->sockets[i])
806 continue;
807 if (!SILC_IS_LISTENER(server->sockets[i])) {
808 SilcSocketConnection sock = server->sockets[i];
809 SilcIDListData idata = sock->user_data;
810
811 if (idata)
812 idata->status &= ~SILC_IDLIST_STATUS_DISABLED;
813
814 silc_schedule_task_del_by_context(server->schedule,
815 server->sockets[i]);
816 silc_schedule_task_del_by_fd(server->schedule,
817 server->sockets[i]->sock);
818 silc_server_disconnect_remote(server, server->sockets[i],
819 SILC_STATUS_OK,
820 "Server is shutting down");
821 if (server->sockets[i]) {
822 if (sock->user_data)
823 silc_server_free_sock_user_data(server, sock,
824 "Server is shutting down");
825 silc_socket_free(sock);
826 }
827 } else {
828 silc_socket_free(server->sockets[i]);
829 server->sockets[i] = NULL;
830 server->stat.conn_num--;
831 }
832 }
833
834 /* We are not connected to network anymore */
835 server->standalone = TRUE;
836
837 silc_schedule_stop(server->schedule);
838 silc_schedule_uninit(server->schedule);
839 server->schedule = NULL;
840
841 silc_free(server->sockets);
842 server->sockets = NULL;
843 }
844
845 silc_server_protocols_unregister();
846
847 SILC_LOG_DEBUG(("Server stopped"));
848 }
849
850 /* Function that is called when the network connection to a router has
851 been established. This will continue with the key exchange protocol
852 with the remote router. */
853
854 void silc_server_start_key_exchange(SilcServer server,
855 SilcServerConnection sconn,
856 int sock)
857 {
858 SilcSocketConnection newsocket;
859 SilcProtocol protocol;
860 SilcServerKEInternalContext *proto_ctx;
861 SilcServerConfigRouter *conn =
862 (SilcServerConfigRouter *) sconn->conn.ref_ptr;
863 void *context;
864
865 /* Cancel any possible retry timeouts */
866 silc_schedule_task_del_by_callback(server->schedule,
867 silc_server_connect_to_router_retry);
868
869 /* Set socket options */
870 silc_net_set_socket_nonblock(sock);
871 silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
872
873 /* Create socket connection for the connection. Even though we
874 know that we are connecting to a router we will mark the socket
875 to be unknown connection until we have executed authentication
876 protocol. */
877 silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, NULL, &newsocket);
878 server->sockets[sock] = newsocket;
879 newsocket->hostname = strdup(sconn->remote_host);
880 newsocket->ip = strdup(sconn->remote_host);
881 newsocket->port = sconn->remote_port;
882 sconn->sock = newsocket;
883
884 /* Allocate internal protocol context. This is sent as context
885 to the protocol. */
886 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
887 proto_ctx->server = (void *)server;
888 proto_ctx->context = (void *)sconn;
889 proto_ctx->sock = newsocket;
890 proto_ctx->rng = server->rng;
891 proto_ctx->responder = FALSE;
892
893 /* Set Key Exchange flags from configuration, but fall back to global
894 settings too. */
895 SILC_GET_SKE_FLAGS(conn, proto_ctx);
896 if (server->config->param.key_exchange_pfs)
897 proto_ctx->flags |= SILC_SKE_SP_FLAG_PFS;
898
899 /* Perform key exchange protocol. silc_server_connect_to_router_second
900 will be called after the protocol is finished. */
901 silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
902 &protocol, proto_ctx,
903 silc_server_connect_to_router_second);
904 newsocket->protocol = protocol;
905
906 /* Register a timeout task that will be executed if the protocol
907 is not executed within set limit. */
908 proto_ctx->timeout_task =
909 silc_schedule_task_add(server->schedule, sock,
910 silc_server_timeout_remote,
911 server, server->config->key_exchange_timeout, 0,
912 SILC_TASK_TIMEOUT,
913 SILC_TASK_PRI_LOW);
914
915 /* Register the connection for network input and output. This sets
916 that scheduler will listen for incoming packets for this connection
917 and sets that outgoing packets may be sent to this connection as
918 well. However, this doesn't set the scheduler for outgoing traffic,
919 it will be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
920 later when outgoing data is available. */
921 context = (void *)server;
922 SILC_REGISTER_CONNECTION_FOR_IO(sock);
923
924 /* Run the protocol */
925 silc_protocol_execute(protocol, server->schedule, 0, 0);
926 }
927
928 /* Timeout callback that will be called to retry connecting to remote
929 router. This is used by both normal and router server. This will wait
930 before retrying the connecting. The timeout is generated by exponential
931 backoff algorithm. */
932
933 SILC_TASK_CALLBACK(silc_server_connect_to_router_retry)
934 {
935 SilcServer server = app_context;
936 SilcServerConnection sconn = (SilcServerConnection)context;
937 SilcServerConfigRouter *conn = sconn->conn.ref_ptr;
938 SilcServerConfigConnParams *param =
939 (conn->param ? conn->param : &server->config->param);
940
941 /* Don't retry if we are shutting down. */
942 if (server->server_shutdown) {
943 silc_server_config_unref(&sconn->conn);
944 silc_free(sconn->remote_host);
945 silc_free(sconn->backup_replace_ip);
946 silc_free(sconn);
947 return;
948 }
949
950 SILC_LOG_INFO(("Retrying connecting to a router"));
951
952 /* Calculate next timeout */
953 if (sconn->retry_count >= 1) {
954 sconn->retry_timeout = sconn->retry_timeout * SILC_SERVER_RETRY_MULTIPLIER;
955 if (sconn->retry_timeout > param->reconnect_interval_max)
956 sconn->retry_timeout = param->reconnect_interval_max;
957 } else {
958 sconn->retry_timeout = param->reconnect_interval;
959 }
960 sconn->retry_count++;
961 sconn->retry_timeout = sconn->retry_timeout +
962 (silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER);
963
964 /* If we've reached max retry count, give up. */
965 if ((sconn->retry_count > param->reconnect_count) &&
966 !param->reconnect_keep_trying) {
967 SILC_LOG_ERROR(("Could not connect to router, giving up"));
968 silc_server_config_unref(&sconn->conn);
969 silc_free(sconn->remote_host);
970 silc_free(sconn->backup_replace_ip);
971 silc_free(sconn);
972 return;
973 }
974
975 SILC_LOG_DEBUG(("Retrying connecting to a router in %d seconds",
976 sconn->retry_timeout));
977
978 /* We will lookup a fresh pointer later */
979 silc_server_config_unref(&sconn->conn);
980
981 /* Wait one before retrying */
982 silc_schedule_task_add(server->schedule, 0, silc_server_connect_router,
983 context, sconn->retry_timeout, 0,
984 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
985 }
986
987 /* Callback for async connection to remote router */
988
989 SILC_TASK_CALLBACK(silc_server_connection_established)
990 {
991 SilcServer server = app_context;
992 SilcServerConnection sconn = (SilcServerConnection)context;
993 int sock = fd;
994 int opt = EINVAL, optlen = sizeof(opt), ret;
995
996 ret = silc_net_get_socket_opt(sock, SOL_SOCKET, SO_ERROR, &opt, &optlen);
997
998 silc_schedule_task_del_by_fd(server->schedule, sock);
999 silc_schedule_unset_listen_fd(server->schedule, sock);
1000
1001 if (ret != 0 || opt != 0) {
1002 SILC_LOG_ERROR(("Could not connect to router %s:%d: %s",
1003 sconn->remote_host, sconn->remote_port, strerror(opt)));
1004 silc_net_close_connection(sock);
1005 if (!sconn->no_reconnect) {
1006 silc_schedule_task_add(server->schedule, 0,
1007 silc_server_connect_to_router_retry,
1008 context, 1, 0, SILC_TASK_TIMEOUT,
1009 SILC_TASK_PRI_NORMAL);
1010 } else {
1011 silc_server_config_unref(&sconn->conn);
1012 silc_free(sconn->remote_host);
1013 silc_free(sconn->backup_replace_ip);
1014 silc_free(sconn);
1015 }
1016 return;
1017 }
1018
1019 SILC_LOG_DEBUG(("Connection to router %s:%d established", sconn->remote_host,
1020 sconn->remote_port));
1021
1022 /* Continue with key exchange protocol */
1023 silc_server_start_key_exchange(server, sconn, sock);
1024 }
1025
1026 /* Generic routine to use connect to a router. */
1027
1028 SILC_TASK_CALLBACK(silc_server_connect_router)
1029 {
1030 SilcServer server = app_context;
1031