X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=apps%2Fsilcd%2Fserverid.c;h=3f2c65914e37cb678f0ac783fd9a4c8de57fc762;hb=a818c5b5411bbc4436d1c5f011236985c96bb787;hp=26f010cb5db046d80cb19d435f5c84165bafac2f;hpb=62f89b2886bbe9df82d9b2fdabfe707509d9e0fc;p=silc.git diff --git a/apps/silcd/serverid.c b/apps/silcd/serverid.c index 26f010cb..3f2c6591 100644 --- a/apps/silcd/serverid.c +++ b/apps/silcd/serverid.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 1997 - 2000 Pekka Riikonen + Copyright (C) 1997 - 2001 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,89 +17,128 @@ GNU General Public License for more details. */ -/* - * $Id$ - * $Log$ - * Revision 1.1 2000/06/27 11:36:56 priikone - * Initial revision - * - * - */ +/* $Id$ */ #include "serverincludes.h" +#include "server_internal.h" /* Creates a Server ID. Newly created Server ID is returned to the new_id argument. */ -void silc_id_create_server_id(int sock, SilcRng rng, SilcServerID **new_id) +void silc_id_create_server_id(const char *ip, SilcUInt16 port, SilcRng rng, + SilcServerID **new_id) { - struct sockaddr_in server; - int rval, len; - SILC_LOG_DEBUG(("Creating new Server ID")); *new_id = silc_calloc(1, sizeof(**new_id)); - if (*new_id == NULL) { - SILC_LOG_ERROR(("Could not allocate new Server ID")); - return; - } - /* Get IP address */ - len = sizeof(server); - rval = getsockname(sock, (struct sockaddr *)&server, &len); - if (rval < 0) { - SILC_LOG_ERROR(("Could not get IP address: %s", strerror(errno))); + /* Create the ID */ + + if (!silc_net_addr2bin(ip, (*new_id)->ip.data, + sizeof((*new_id)->ip.data))) { silc_free(*new_id); *new_id = NULL; return; } - /* Create the ID */ - (*new_id)->ip = server.sin_addr; - (*new_id)->port = server.sin_port; + (*new_id)->ip.data_len = silc_net_is_ip4(ip) ? 4 : 16; + (*new_id)->port = htons(port); (*new_id)->rnd = silc_rng_get_rn16(rng); + + 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 = silc_calloc(1, sizeof(**new_id)); - if (*new_id == NULL) { - SILC_LOG_ERROR(("Could not allocate new Client ID")); - return; - } /* Create hash of the nickanem */ silc_hash_make(md5hash, nickname, strlen(nickname), hash); /* Create the ID */ - (*new_id)->ip.s_addr = server_id->ip.s_addr; + memcpy((*new_id)->ip.data, server_id->ip.data, server_id->ip.data_len); + (*new_id)->ip.data_len = server_id->ip.data_len; (*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)); - if (*new_id == NULL) { - SILC_LOG_ERROR(("Could not allocate new Channel ID")); - return; - } /* Create the ID */ - (*new_id)->ip.s_addr = router_id->ip.s_addr; + memcpy((*new_id)->ip.data, router_id->ip.data, router_id->ip.data_len); + (*new_id)->ip.data_len = router_id->ip.data_len; (*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)) + 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; }