From: Pekka Riikonen Date: Wed, 26 Jul 2000 07:05:11 +0000 (+0000) Subject: Fixed the server to server (server to router actually) connections X-Git-Tag: SILC.0.1~417 X-Git-Url: http://git.silcnet.org/gitweb/?a=commitdiff_plain;h=d5b0f186b9cdebd32b1d01864b15a3af72b50ae9;p=silc.git Fixed the server to server (server to router actually) connections and made the private message work inside a cell. Added functin silc_server_replace_id. --- diff --git a/apps/silcd/command.c b/apps/silcd/command.c index e3e810ee..419b778a 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -20,6 +20,11 @@ /* * $Id$ * $Log$ + * Revision 1.12 2000/07/26 07:05:11 priikone + * Fixed the server to server (server to router actually) connections + * and made the private message work inside a cell. Added functin + * silc_server_replace_id. + * * Revision 1.11 2000/07/19 07:08:09 priikone * Added version detection support to SKE. * @@ -552,47 +557,44 @@ SILC_SERVER_CMD_FUNC(identify) count = atoi(tmp); } - /* Then, make the query from our local client list */ + /* Find client */ entry = silc_idlist_find_client_by_nickname(server->local_list, nick, NULL); - if (!entry) { - - /* If we are normal server and are connected to a router we will - make global query from the router. */ - if (server->server_type == SILC_SERVER && !server->standalone) { - SilcBuffer buffer = cmd->packet->buffer; - - SILC_LOG_DEBUG(("Requesting identify from router")); - - /* Send IDENTIFY command to our router */ - silc_buffer_push(buffer, buffer->data - buffer->head); - silc_server_packet_forward(server, (SilcSocketConnection) - server->id_entry->router->connection, - buffer->data, buffer->len, TRUE); - goto out; - } + if (!entry) + entry = silc_idlist_find_client_by_hash(server->global_list, + nick, server->md5hash); + + /* If client was not found and if we are normal server and are connected + to a router we will make global query from the router. */ + if (!entry && server->server_type == SILC_SERVER && !server->standalone && + !cmd->pending) { + SilcBuffer buffer = cmd->packet->buffer; - /* If we are router then we will check our global list as well. */ - if (server->server_type == SILC_ROUTER) { - entry = - silc_idlist_find_client_by_nickname(server->global_list, - nick, NULL); - if (!entry) { - silc_server_command_send_status_data(cmd, SILC_COMMAND_IDENTIFY, - SILC_STATUS_ERR_NO_SUCH_NICK, - 3, tmp, strlen(tmp)); - goto out; - } - goto ok; - } + SILC_LOG_DEBUG(("Requesting identify from router")); + + /* Send IDENTIFY command to our router */ + silc_buffer_push(buffer, buffer->data - buffer->head); + silc_server_packet_forward(server, (SilcSocketConnection) + server->id_entry->router->connection, + buffer->data, buffer->len, TRUE); + return; + } + + /* If we are router we have checked our local list by nickname and our + global list by hash so far. It is possible that the client is still not + found and we'll check it from local list by hash. */ + if (!entry && server->server_type == SILC_ROUTER) + entry = silc_idlist_find_client_by_hash(server->local_list, + nick, server->md5hash); + if (!entry) { + /* The client definitely does not exist */ silc_server_command_send_status_data(cmd, SILC_COMMAND_IDENTIFY, SILC_STATUS_ERR_NO_SUCH_NICK, 3, tmp, strlen(tmp)); goto out; } - ok: /* Send IDENTIFY reply */ id_string = silc_id_id2str(entry->id, SILC_ID_CLIENT); tmp = silc_command_get_first_arg(cmd->payload, NULL); @@ -601,7 +603,6 @@ SILC_SERVER_CMD_FUNC(identify) 2, id_string, SILC_ID_CLIENT_LEN, 3, nick, strlen(nick)); -#if 0 if (cmd->packet->flags & SILC_PACKET_FLAG_FORWARDED) { void *id = silc_id_str2id(cmd->packet->src_id, cmd->packet->src_id_type); silc_server_packet_send_dest(server, cmd->sock, @@ -609,11 +610,11 @@ SILC_SERVER_CMD_FUNC(identify) id, cmd->packet->src_id_type, packet->data, packet->len, FALSE); silc_free(id); - } else -#endif + } else { silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0, packet->data, packet->len, FALSE); + } silc_free(id_string); silc_buffer_free(packet); diff --git a/apps/silcd/command_reply.c b/apps/silcd/command_reply.c index b3054fae..08cee1c7 100644 --- a/apps/silcd/command_reply.c +++ b/apps/silcd/command_reply.c @@ -20,6 +20,11 @@ /* * $Id$ * $Log$ + * Revision 1.5 2000/07/26 07:05:11 priikone + * Fixed the server to server (server to router actually) connections + * and made the private message work inside a cell. Added functin + * silc_server_replace_id. + * * Revision 1.4 2000/07/12 05:59:41 priikone * Major rewrite of ID Cache system. Support added for the new * ID cache system. Major rewrite of ID List stuff on server. All @@ -165,24 +170,25 @@ SILC_SERVER_CMD_REPLY_FUNC(identify) /* Process one identify reply */ if (status == SILC_STATUS_OK) { + SilcClientID *client_id; unsigned char *id_data; - char *nickname; + char *nickname, *username; id_data = silc_command_get_arg_type(cmd->payload, 2, NULL); nickname = silc_command_get_arg_type(cmd->payload, 3, NULL); if (!id_data || !nickname) goto out; -#if 0 - /* Allocate client entry */ - client_entry = silc_calloc(1, sizeof(*client_entry)); - client_entry->id = silc_id_str2id(id_data, SILC_ID_CLIENT); - client_entry->nickname = strdup(nickname); + username = silc_command_get_arg_type(cmd->payload, 4, NULL); + + client_id = silc_id_str2id(id_data, SILC_ID_CLIENT); - /* Save received Client ID to ID cache */ - silc_idcache_add(win->client_cache, client_entry->nickname, - SILC_ID_CLIENT, client_entry->id, client_entry, TRUE); -#endif + /* Add the client always to our global list. If normal or router server + ever gets here it means they don't have this client's information + in their cache. */ + silc_idlist_add_client(server->global_list, strdup(nickname), + username, NULL, client_id, NULL, NULL, NULL, + NULL, NULL, NULL, NULL); } if (status == SILC_STATUS_LIST_START) { diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 58633697..cdd1ab2f 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -25,6 +25,11 @@ /* * $Id$ * $Log$ + * Revision 1.12 2000/07/26 07:05:11 priikone + * Fixed the server to server (server to router actually) connections + * and made the private message work inside a cell. Added functin + * silc_server_replace_id. + * * Revision 1.11 2000/07/20 10:17:25 priikone * Added dynamic protocol registering/unregistering support. The * patch was provided by cras. @@ -242,11 +247,14 @@ int silc_server_init(SilcServer server) server->local_list->servers = silc_idcache_alloc(0); server->local_list->channels = silc_idcache_alloc(0); - if (server->server_type == SILC_ROUTER) { - server->global_list->clients = silc_idcache_alloc(0); - server->global_list->servers = silc_idcache_alloc(0); - server->global_list->channels = silc_idcache_alloc(0); - } + /* XXX for now these are allocated for normal server as well as these + hold some global information that the server has fetched from its + router. For router these are used as they are supposed to be used + on router. The XXX can be remoevd later if this is the way we are + going to do this in the normal server as well. */ + server->global_list->clients = silc_idcache_alloc(0); + server->global_list->servers = silc_idcache_alloc(0); + server->global_list->channels = silc_idcache_alloc(0); /* Allocate the entire socket list that is used in server. Eventually all connections will have entry in this table (it is a table of @@ -1506,12 +1514,38 @@ void silc_server_packet_parse_type(SilcServer server, case SILC_PACKET_NEW_SERVER: /* * Received new server packet. This includes Server ID and some other - * information that we may save. This is after server as connected to us. + * information that we may save. This is received after server has + * connected to us. */ SILC_LOG_DEBUG(("New Server packet")); silc_server_new_server(server, sock, packet); break; + case SILC_PACKET_NEW_CHANNEL: + break; + + case SILC_PACKET_NEW_CHANNEL_USER: + break; + + case SILC_PACKET_NEW_CHANNEL_LIST: + break; + + case SILC_PACKET_NEW_CHANNEL_USER_LIST: + break; + + case SILC_PACKET_REPLACE_ID: + /* + * Received replace ID packet. This sends the old ID that is to be + * replaced with the new one included into the packet. Client must not + * send this packet. + */ + SILC_LOG_DEBUG(("Replace ID packet")); + silc_server_replace_id(server, sock, packet); + break; + + case SILC_PACKET_REMOVE_ID: + break; + default: SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type)); break; @@ -2447,9 +2481,15 @@ void silc_server_private_message(SilcServer server, /* If we are router and the client has router then the client is in our cell but not directly connected to us. */ if (server->server_type == SILC_ROUTER && client->router) { + /* We are of course in this case the client's router thus the real + "router" of the client is the server who owns the client. Thus + we will send the packet to that server. */ + router = (SilcServerEntry)dst_sock->user_data; + assert(client->router == server->id_entry); + silc_server_private_message_send_internal(server, dst_sock, - client->router->send_key, - client->router->hmac, + router->send_key, + router->hmac, packet); goto out; } @@ -2789,6 +2829,81 @@ void silc_server_send_replace_id(SilcServer server, silc_buffer_free(packet); } +/* Received packet to replace a ID. This checks that the requested ID + exists and replaces it with the new one. */ + +void silc_server_replace_id(SilcServer server, + SilcSocketConnection sock, + SilcPacketContext *packet) +{ + SilcBuffer buffer = packet->buffer; + unsigned char *old_id = NULL, *new_id = NULL; + SilcIdType old_id_type, new_id_type; + unsigned short old_id_len, new_id_len; + void *id = NULL, *id2 = NULL; + + if (sock->type == SILC_SOCKET_TYPE_CLIENT || + packet->src_id_type == SILC_ID_CLIENT) + return; + + SILC_LOG_DEBUG(("Replacing ID")); + + silc_buffer_unformat(buffer, + SILC_STR_UI_SHORT(&old_id_type), + SILC_STR_UI16_NSTRING_ALLOC(&old_id, &old_id_len), + SILC_STR_UI_SHORT(&new_id_type), + SILC_STR_UI16_NSTRING_ALLOC(&new_id, &new_id_len), + SILC_STR_END); + + if (old_id_type != new_id_type) + goto out; + + if (old_id_len != silc_id_get_len(old_id_type) || + new_id_len != silc_id_get_len(new_id_type)) + goto out; + + id = silc_id_str2id(old_id, old_id_type); + if (!id) + goto out; + + id2 = silc_id_str2id(new_id, new_id_type); + if (!id2) + goto out; + + /* Replace the old ID */ + switch(old_id_type) { + case SILC_ID_CLIENT: + if (silc_idlist_replace_client_id(server->local_list, id, id2) == NULL) + if (server->server_type == SILC_ROUTER) + silc_idlist_replace_client_id(server->global_list, id, id2); + break; + + case SILC_ID_SERVER: + if (silc_idlist_replace_server_id(server->local_list, id, id2) == NULL) + if (server->server_type == SILC_ROUTER) + silc_idlist_replace_server_id(server->global_list, id, id2); + break; + + case SILC_ID_CHANNEL: + /* XXX Hmm... Basically this cannot occur. Channel ID's cannot be + re-generated. */ + silc_free(id2); + break; + + default: + silc_free(id2); + break; + } + + out: + if (id) + silc_free(id); + if (old_id) + silc_free(old_id); + if (new_id) + silc_free(new_id); +} + /* Creates new channel. */ SilcChannelEntry silc_server_new_channel(SilcServer server, @@ -3032,14 +3147,18 @@ void silc_server_new_id(SilcServer server, SilcSocketConnection sock, SilcPacketContext *packet) { SilcBuffer buffer = packet->buffer; + SilcIDList id_list; + SilcServerEntry tmpserver, router; + SilcSocketConnection router_sock; SilcIdType id_type; unsigned char *id_string; - void *id; + void *id, *tmpid; SILC_LOG_DEBUG(("Processing new ID")); if (sock->type == SILC_SOCKET_TYPE_CLIENT || - server->server_type == SILC_SERVER) + server->server_type == SILC_SERVER || + packet->src_id_type != SILC_ID_SERVER) return; silc_buffer_unformat(buffer, @@ -3055,11 +3174,23 @@ void silc_server_new_id(SilcServer server, SilcSocketConnection sock, if (!id) goto out; - /* XXX Do check whether the packet is coming outside the cell or - from someone inside the cell. If outside use global lists otherwise - local lists. */ - /* XXX If using local list set the idlist->connection to the sender's - socket connection as it is used in packet sending */ + /* If the packet is originated from the one who sent it to us we know + that the ID belongs to our cell, unless the sender was router. */ + tmpid = silc_id_str2id(packet->src_id, SILC_ID_SERVER); + tmpserver = (SilcServerEntry)sock->user_data; + + if (!SILC_ID_SERVER_COMPARE(tmpid, tmpserver->id) && + sock->type == SILC_SOCKET_TYPE_SERVER) { + id_list = server->local_list; + router_sock = sock; + router = server->id_entry; + } else { + id_list = server->global_list; + router_sock = (SilcSocketConnection)server->id_entry->router->connection; + router = server->id_entry->router; + } + + silc_free(tmpid); switch(id_type) { case SILC_ID_CLIENT: @@ -3068,9 +3199,9 @@ void silc_server_new_id(SilcServer server, SilcSocketConnection sock, /* Add the client to our local list. We are router and we keep cell specific local database of all clients in the cell. */ - idlist = silc_idlist_add_client(server->local_list, NULL, NULL, NULL, - id, sock->user_data, NULL, NULL, - NULL, NULL, NULL, sock); + idlist = silc_idlist_add_client(id_list, NULL, NULL, NULL, + id, router, NULL, NULL, + NULL, NULL, NULL, router_sock); } break; @@ -3080,17 +3211,17 @@ void silc_server_new_id(SilcServer server, SilcSocketConnection sock, /* Add the server to our local list. We are router and we keep cell specific local database of all servers in the cell. */ - idlist = silc_idlist_add_server(server->local_list, NULL, 0, - id, server->id_entry, NULL, NULL, - NULL, NULL, NULL, sock); + idlist = silc_idlist_add_server(id_list, NULL, 0, + id, router, NULL, NULL, + NULL, NULL, NULL, router_sock); } break; case SILC_ID_CHANNEL: /* Add the channel to our local list. We are router and we keep cell specific local database of all channels in the cell. */ - silc_idlist_add_channel(server->local_list, NULL, 0, id, - server->id_entry, NULL); + silc_idlist_add_channel(id_list, NULL, 0, id, + router, NULL); break; default: diff --git a/apps/silcd/server.h b/apps/silcd/server.h index b080b9f1..c89c4abb 100644 --- a/apps/silcd/server.h +++ b/apps/silcd/server.h @@ -137,6 +137,9 @@ void silc_server_send_replace_id(SilcServer server, unsigned int old_id_len, void *new_id, SilcIdType new_id_type, unsigned int new_id_len); +void silc_server_replace_id(SilcServer server, + SilcSocketConnection sock, + SilcPacketContext *packet); SilcChannelEntry silc_server_new_channel(SilcServer server, SilcServerID *router_id, char *cipher, char *channel_name);