X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=apps%2Fsilcd%2Fserverid.c;fp=apps%2Fsilcd%2Fserverid.c;h=fb29b468412e6f2b828f4949aacd2b222385094e;hb=1ad1d027c752dc4193dbacb9192f92de293c9453;hp=12cebb6a57ec3d0ebe26ea4dbd73f36c28b651ec;hpb=f1e6186de53c2a54a76191915211eb1ae6a7acf6;p=silc.git diff --git a/apps/silcd/serverid.c b/apps/silcd/serverid.c index 12cebb6a..fb29b468 100644 --- a/apps/silcd/serverid.c +++ b/apps/silcd/serverid.c @@ -20,6 +20,7 @@ /* $Id$ */ #include "serverincludes.h" +#include "server_internal.h" /* Creates a Server ID. Newly created Server ID is returned to the new_id argument. */ @@ -53,13 +54,19 @@ void silc_id_create_server_id(int sock, SilcRng rng, SilcServerID **new_id) 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")); @@ -74,14 +81,42 @@ void silc_id_create_client_id(SilcServerID *server_id, SilcRng rng, (*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)); @@ -92,5 +127,26 @@ void silc_id_create_channel_id(SilcServerID *router_id, SilcRng rng, (*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; }