5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2006 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.
22 #include "silcserver.h"
23 #include "server_internal.h"
25 /* Return next available command identifier. */
27 SilcUInt16 silc_server_cmd_ident(SilcServer server)
31 silc_mutex_lock(server->lock);
32 cmd_ident = ++server->cmd_ident;
33 silc_mutex_unlock(server->lock);
40 SilcBool silc_server_check_watcher_list(SilcServer server,
41 SilcClientEntry client,
43 SilcNotifyType notify)
48 /* This function is used to send the notify packets and motd to the
49 incoming client connection. */
51 void silc_server_send_welcome(SilcServerAccept ac, SilcClientEntry client)
53 SilcServer server = ac->thread->server;
54 SilcPacketStream stream = client->stream;
56 SILC_LOG_DEBUG(("Send welcome notifys"));
58 /* Send some nice info to the client */
59 SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
60 ("Welcome to the SILC Network %s",
62 SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
63 ("Your host is %s, running version %s",
64 server->server_name, SILC_DIST_VERSION_STRING));
66 if (server->server_type == SILC_ROUTER) {
67 SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
68 ("There are %d clients, %d servers and %d "
69 "routers in SILC Network",
70 server->stat.clients, server->stat.servers,
71 server->stat.routers));
73 if (server->stat.clients && server->stat.servers + 1)
74 SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
75 ("There are %d clients, %d servers and %d "
76 "routers in SILC Network",
77 server->stat.clients, server->stat.servers,
78 (server->standalone ? 0 :
79 !server->stat.routers ? 1 :
80 server->stat.routers)));
83 if (server->stat.cell_clients && server->stat.cell_servers + 1)
84 SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
85 ("There are %d clients on %d servers in our cell",
86 server->stat.cell_clients,
87 server->stat.cell_servers));
88 if (server->server_type == SILC_ROUTER) {
89 SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
90 ("I have %d clients, %d channels, %d servers and "
92 server->stat.my_clients,
93 server->stat.my_channels,
94 server->stat.my_servers,
95 server->stat.my_routers));
97 SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
98 ("I have %d clients and %d channels formed",
99 server->stat.my_clients,
100 server->stat.my_channels));
103 if (server->stat.server_ops || server->stat.router_ops)
104 SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
105 ("There are %d server operators and %d router "
107 server->stat.server_ops,
108 server->stat.router_ops));
109 if (server->stat.my_router_ops + server->stat.my_server_ops)
110 SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
111 ("I have %d operators online",
112 server->stat.my_router_ops +
113 server->stat.my_server_ops));
115 SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
116 ("Your connection is secured with %s cipher, "
117 "key length %d bits",
118 silc_cipher_get_name(ac->prop->cipher),
119 silc_cipher_get_key_len(ac->prop->cipher)));
120 SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
121 ("Your current nickname is %s",
125 silc_server_send_motd(server, stream);
128 /* Creates new Client ID. */
130 SilcBool silc_server_create_client_id(SilcServer server, char *nickname,
131 SilcClientID *new_id)
133 unsigned char hash[16];
134 SilcBool finding = FALSE;
136 SILC_LOG_DEBUG(("Creating new Client ID"));
138 /* Create hash of the nickname (it's already checked as valid identifier
140 silc_hash_make(server->md5hash, nickname, strlen(nickname), hash);
143 memset(new_id, 0, sizeof(*new_id));
144 memcpy(new_id->ip.data, server->id.ip.data, server->id.ip.data_len);
145 new_id->ip.data_len = server->id.ip.data_len;
146 new_id->rnd = silc_rng_get_byte(server->rng);
147 memcpy(new_id->hash, hash, CLIENTID_HASH_LEN);
149 /* Assure that the ID does not exist already */
151 if (!silc_server_find_client_by_id(server, new_id, FALSE, NULL))
154 /* The ID exists, start increasing the rnd from 0 until we find a
155 ID that does not exist. If we wrap and it still exists then we
156 will return FALSE and the caller must send some other nickname
157 since this cannot be used anymore. */
160 if (finding && new_id->rnd == 0)
169 SILC_LOG_DEBUG(("New ID (%s)", silc_id_render(new_id, SILC_ID_CLIENT)));
174 /* Creates a Server ID. */
176 SilcBool silc_server_create_server_id(SilcServer server,
177 const char *ip, SilcUInt16 port,
178 SilcServerID *new_id)
180 SILC_LOG_DEBUG(("Creating new Server ID"));
187 if (!silc_net_addr2bin(ip, new_id->ip.data, sizeof(new_id->ip.data)))
190 new_id->ip.data_len = silc_net_is_ip4(ip) ? 4 : 16;
191 new_id->port = SILC_SWAB_16(port);
192 new_id->rnd = silc_rng_get_rn16(server->rng);
194 SILC_LOG_DEBUG(("New ID (%s)", silc_id_render(new_id, SILC_ID_SERVER)));
199 /* Checks whether the `server_id' is valid. It must be based to the
200 IP address provided in the `remote' socket connection. */
202 SilcBool silc_server_check_server_id(const char *ip_address,
203 SilcServerID *server_id)
205 unsigned char ip[16];
207 if (!silc_net_addr2bin(ip_address, ip, sizeof(ip)))
210 if (silc_net_is_ip4(ip_address)) {
211 if (!memcmp(server_id->ip.data, ip, 4))
214 if (!memcmp(server_id->ip.data, ip, 16))