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"
26 /* Return next available command identifier. */
28 SilcUInt16 silc_server_cmd_ident(SilcServer server)
32 silc_mutex_lock(server->lock);
33 cmd_ident = ++server->cmd_ident;
34 silc_mutex_unlock(server->lock);
41 SilcBool silc_server_check_watcher_list(SilcServer server,
42 SilcClientEntry client,
44 SilcNotifyType notify)
49 /* This function is used to send the notify packets and motd to the
50 incoming client connection. */
52 void silc_server_send_welcome(SilcServerAccept ac, SilcClientEntry client)
54 SilcServer server = ac->thread->server;
55 SilcPacketStream stream = client->stream;
57 SILC_LOG_DEBUG(("Send welcome notifys"));
59 /* Send some nice info to the client */
60 SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
61 ("Welcome to the SILC Network %s",
63 SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
64 ("Your host is %s, running version %s",
65 server->server_name, SILC_DIST_VERSION_STRING));
67 if (server->server_type == SILC_ROUTER) {
68 SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
69 ("There are %d clients, %d servers and %d "
70 "routers in SILC Network",
71 server->stat.clients, server->stat.servers,
72 server->stat.routers));
74 if (server->stat.clients && server->stat.servers + 1)
75 SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
76 ("There are %d clients, %d servers and %d "
77 "routers in SILC Network",
78 server->stat.clients, server->stat.servers,
79 (server->standalone ? 0 :
80 !server->stat.routers ? 1 :
81 server->stat.routers)));
84 if (server->stat.cell_clients && server->stat.cell_servers + 1)
85 SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
86 ("There are %d clients on %d servers in our cell",
87 server->stat.cell_clients,
88 server->stat.cell_servers));
89 if (server->server_type == SILC_ROUTER) {
90 SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
91 ("I have %d clients, %d channels, %d servers and "
93 server->stat.my_clients,
94 server->stat.my_channels,
95 server->stat.my_servers,
96 server->stat.my_routers));
98 SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
99 ("I have %d clients and %d channels formed",
100 server->stat.my_clients,
101 server->stat.my_channels));
104 if (server->stat.server_ops || server->stat.router_ops)
105 SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
106 ("There are %d server operators and %d router "
108 server->stat.server_ops,
109 server->stat.router_ops));
110 if (server->stat.my_router_ops + server->stat.my_server_ops)
111 SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
112 ("I have %d operators online",
113 server->stat.my_router_ops +
114 server->stat.my_server_ops));
116 SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
117 ("Your connection is secured with %s cipher, "
118 "key length %d bits",
119 silc_cipher_get_name(ac->prop->cipher),
120 silc_cipher_get_key_len(ac->prop->cipher)));
121 SILC_SERVER_SEND_NOTIFY(server, stream, SILC_NOTIFY_TYPE_NONE,
122 ("Your current nickname is %s",
126 silc_server_send_motd(server, stream);
129 /* Creates new Client ID. */
131 SilcBool silc_server_create_client_id(SilcServer server, char *nickname,
132 SilcClientID *new_id)
134 unsigned char hash[16];
135 SilcBool finding = FALSE;
137 SILC_LOG_DEBUG(("Creating new Client ID"));
139 /* Create hash of the nickname (it's already checked as valid identifier
141 silc_hash_make(server->md5hash, nickname, strlen(nickname), hash);
144 memset(new_id, 0, sizeof(*new_id));
145 memcpy(new_id->ip.data, server->id.ip.data, server->id.ip.data_len);
146 new_id->ip.data_len = server->id.ip.data_len;
147 new_id->rnd = silc_rng_get_byte(server->rng);
148 memcpy(new_id->hash, hash, CLIENTID_HASH_LEN);
150 /* Assure that the ID does not exist already */
152 if (!silc_server_find_client_by_id(server, new_id, FALSE, NULL))
155 /* The ID exists, start increasing the rnd from 0 until we find a
156 ID that does not exist. If we wrap and it still exists then we
157 will return FALSE and the caller must send some other nickname
158 since this cannot be used anymore. */
161 if (finding && new_id->rnd == 0)
170 SILC_LOG_DEBUG(("New ID (%s)", silc_id_render(new_id, SILC_ID_CLIENT)));
175 /* Creates a Server ID. */
177 SilcBool silc_server_create_server_id(SilcServer server,
178 const char *ip, SilcUInt16 port,
179 SilcServerID *new_id)
181 SILC_LOG_DEBUG(("Creating new Server ID"));
188 if (!silc_net_addr2bin(ip, new_id->ip.data, sizeof(new_id->ip.data)))
191 new_id->ip.data_len = silc_net_is_ip4(ip) ? 4 : 16;
192 new_id->port = SILC_SWAB_16(port);
193 new_id->rnd = silc_rng_get_rn16(server->rng);
195 SILC_LOG_DEBUG(("New ID (%s)", silc_id_render(new_id, SILC_ID_SERVER)));
200 /* Checks whether the `server_id' is valid. It must be based to the
201 IP address provided in the `remote' socket connection. */
203 SilcBool silc_server_check_server_id(const char *ip_address,
204 SilcServerID *server_id)
206 unsigned char ip[16];
208 if (!silc_net_addr2bin(ip_address, ip, sizeof(ip)))
211 if (silc_net_is_ip4(ip_address)) {
212 if (!memcmp(server_id->ip.data, ip, 4))
215 if (!memcmp(server_id->ip.data, ip, 16))