/* $Id$ */
#include "serverincludes.h"
+#include "server_internal.h"
/* Creates a Server ID. Newly created Server ID is returned to the
new_id argument. */
SILC_LOG_DEBUG(("New ID (%s)", silc_id_render(*new_id, SILC_ID_SERVER)));
}
-/* Creates Client ID */
+/* Creates Client ID. This assures that there are no collisions in the
+ created Client IDs. If the collision would occur (meaning that there
+ are 2^8 occurences of the `nickname' this will return FALSE, and the
+ caller must recall the function with different nickname. If this returns
+ TRUE the new ID was created successfully. */
-void silc_id_create_client_id(SilcServerID *server_id, SilcRng rng,
+bool silc_id_create_client_id(SilcServer server,
+ SilcServerID *server_id, SilcRng rng,
SilcHash md5hash, char *nickname,
SilcClientID **new_id)
{
unsigned char hash[16];
+ bool finding = FALSE;
SILC_LOG_DEBUG(("Creating new Client ID"));
(*new_id)->rnd = silc_rng_get_byte(rng);
memcpy((*new_id)->hash, hash, CLIENTID_HASH_LEN);
+ /* Assure that the ID does not exist already */
+ while (1) {
+ if (!silc_idlist_find_client_by_id(server->local_list,
+ *new_id, FALSE, NULL))
+ if (!silc_idlist_find_client_by_id(server->global_list,
+ *new_id, FALSE, NULL))
+ break;
+
+ /* The ID exists, start increasing the rnd from 0 until we find a
+ ID that does not exist. If we wrap and it still exists then we
+ will return FALSE and the caller must send some other nickname
+ since this cannot be used anymore. */
+ (*new_id)->rnd++;
+
+ if (finding && (*new_id)->rnd == 0)
+ return FALSE;
+
+ if (!finding) {
+ (*new_id)->rnd = 0;
+ finding = TRUE;
+ }
+ }
+
SILC_LOG_DEBUG(("New ID (%s)", silc_id_render(*new_id, SILC_ID_CLIENT)));
+
+ return TRUE;
}
/* Creates Channel ID */
-void silc_id_create_channel_id(SilcServerID *router_id, SilcRng rng,
+bool silc_id_create_channel_id(SilcServer server,
+ SilcServerID *router_id, SilcRng rng,
SilcChannelID **new_id)
{
+ bool finding = TRUE;
+
SILC_LOG_DEBUG(("Creating new Channel ID"));
*new_id = silc_calloc(1, sizeof(**new_id));
(*new_id)->port = router_id->port;
(*new_id)->rnd = silc_rng_get_rn16(rng);
+ /* Assure that the ID does not exist already */
+ while (1) {
+ if (!silc_idlist_find_channel_by_id(server->local_list,
+ *new_id, NULL))
+ if (!silc_idlist_find_channel_by_id(server->global_list,
+ *new_id, NULL))
+ break;
+
+ (*new_id)->rnd++;
+
+ if (finding && (*new_id)->rnd == 0)
+ return FALSE;
+
+ if (!finding) {
+ (*new_id)->rnd = 0;
+ finding = TRUE;
+ }
+ }
+
SILC_LOG_DEBUG(("New ID (%s)", silc_id_render(*new_id, SILC_ID_CHANNEL)));
+
+ return TRUE;
}