From de7a4916e9e7786bd4bf95b9d6722dd0701993fd Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Thu, 17 Jan 2002 19:23:35 +0000 Subject: [PATCH] updates. --- CHANGES | 34 ++++++++++++++++++++++ TODO | 2 ++ apps/silcd/command.c | 40 ++++++++++++++------------ apps/silcd/packet_receive.c | 6 ++-- apps/silcd/server.c | 22 +++++++++++--- apps/silcd/server.h | 3 +- apps/silcd/server_util.c | 16 ++++++++--- lib/silcutil/silcsockconn.h | 18 ++++++++++++ lib/silcutil/unix/silcunixsockconn.c | 20 +++++++++++++ lib/silcutil/win32/silcwin32sockconn.c | 11 +++++++ 10 files changed, 143 insertions(+), 29 deletions(-) diff --git a/CHANGES b/CHANGES index 6e9082d6..4073d897 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,37 @@ +Thu Jan 17 18:59:11 EET 2002 Pekka Riikonen + + * Do not save client history information in SERVER_SIGNOFF. + Fixes the bug in normal server that it does not detect + the client becoming valid after the server becomes back + online. Affected file silcd/server_util.c. + + * Added `sock_error' field into the SilcSocketConnection + context. When error occurs during socket operation (read + or write) the error is saved. Added also new function + silc_socket_get_error to return human readable socket error + message. Affected files are lib/silcutil/silcsockconn.[ch], + lib/silcutil/unix/silcunixsockconn.c, and + lib/silcutil/win32/silcwin32sockconn.c. + + * The server now prints the socket error message in the + signoff for client. Affected file silcd/server.c. + + * Fixed the `created' channel information sending from router + to server in JOIN command. Checks now whether the channel + really was created or not and set it according that. + + Fixed the JOIN command to use the client entry's current + ID during the joining procedure instead of the one it sent + in the command (it is checked though), since it can change + between the packet processing and command processing, and + would just case unnecessary pain in the client end. Affected + file silcd/command.c. + + * Fixed a channel key payload sending to use correct channel + ID when the server was forced to change the channel's ID by + router. Router sent the key payload with the old Channel ID. + Affected file silcd/packet_receive.c. + Wed Jan 16 22:26:30 EET 2002 Pekka Riikonen * Call silc_server_save_channel_key only if the key payload diff --git a/TODO b/TODO index d9c9313e..44841077 100644 --- a/TODO +++ b/TODO @@ -65,6 +65,8 @@ TODO/bugs In SILC Client Library TODO/bugs In SILC Server ======================== + o Topic notifications seem to go double times occasionally to a channel. + o Backup router related issues o Channel user mode changes are notified unnecessarely when diff --git a/apps/silcd/command.c b/apps/silcd/command.c index c4bad1ac..0f5fe4f2 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -2429,6 +2429,7 @@ SILC_SERVER_CMD_FUNC(invite) tmp = silc_argument_get_arg_type(cmd->args, 2, &len); if (tmp) { char invite[512]; + bool resolve; dest_id = silc_id_payload_parse_id(tmp, len); if (!dest_id) { @@ -2438,11 +2439,12 @@ SILC_SERVER_CMD_FUNC(invite) } /* Get the client entry */ - dest = silc_server_get_client_resolve(server, dest_id); + dest = silc_server_get_client_resolve(server, dest_id, &resolve); if (!dest) { - if (server->server_type != SILC_SERVER) { - silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE, - SILC_STATUS_ERR_NO_SUCH_CLIENT_ID); + if (server->server_type != SILC_SERVER || !resolve) { + silc_server_command_send_status_reply( + cmd, SILC_COMMAND_INVITE, + SILC_STATUS_ERR_NO_SUCH_CLIENT_ID); goto out; } @@ -2981,6 +2983,7 @@ static void silc_server_command_join_channel(SilcServer server, uint16 ident = silc_command_get_ident(cmd->payload); char check[512], check2[512]; bool founder = FALSE; + bool resolve; SILC_LOG_DEBUG(("Start")); @@ -2991,11 +2994,18 @@ static void silc_server_command_join_channel(SilcServer server, if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) { client = (SilcClientEntry)sock->user_data; } else { - client = silc_server_get_client_resolve(server, client_id); + client = silc_server_get_client_resolve(server, client_id, &resolve); if (!client) { if (cmd->pending) goto out; + if (!resolve) { + silc_server_command_send_status_reply( + cmd, SILC_COMMAND_JOIN, + SILC_STATUS_ERR_NOT_ENOUGH_PARAMS); + goto out; + } + /* The client info is being resolved. Reprocess this packet after receiving the reply to the query. */ silc_server_command_pending(server, SILC_COMMAND_WHOIS, @@ -3316,16 +3326,8 @@ SILC_SERVER_CMD_FUNC(join) channel_name, NULL); if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) { - /* If this is coming from client the Client ID in the command packet must - be same as the client's ID. */ - if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) { - SilcClientEntry entry = (SilcClientEntry)cmd->sock->user_data; - if (!SILC_ID_CLIENT_COMPARE(entry->id, client_id)) { - silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN, - SILC_STATUS_ERR_NOT_ENOUGH_PARAMS); - goto out; - } - } + SilcClientEntry entry = (SilcClientEntry)cmd->sock->user_data; + client_id = silc_id_dup(entry->id, SILC_ID_CLIENT); if (!channel || channel->disabled) { /* Channel not found */ @@ -3336,8 +3338,9 @@ SILC_SERVER_CMD_FUNC(join) channel = silc_server_create_new_channel(server, server->id, cipher, hmac, channel_name, TRUE); if (!channel) { - silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN, - SILC_STATUS_ERR_UNKNOWN_ALGORITHM); + silc_server_command_send_status_reply( + cmd, SILC_COMMAND_JOIN, + SILC_STATUS_ERR_UNKNOWN_ALGORITHM); goto out; } @@ -3443,7 +3446,8 @@ SILC_SERVER_CMD_FUNC(join) create_key = FALSE; /* Router returned the key already */ } - if (silc_command_get(reply->payload) == SILC_COMMAND_WHOIS) + if (silc_command_get(reply->payload) == SILC_COMMAND_WHOIS && + !silc_hash_table_count(channel->user_list)) created = TRUE; } diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index ae4f909c..a4bedaef 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -2231,6 +2231,8 @@ void silc_server_new_channel(SilcServer server, channel->mode = silc_channel_get_mode(payload); /* Send the new channel key to the server */ + id = silc_id_id2str(channel->id, SILC_ID_CHANNEL); + id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL); chk = silc_channel_key_payload_encode(id_len, id, strlen(channel->channel_key-> cipher->name), @@ -2277,8 +2279,8 @@ void silc_server_new_channel(SilcServer server, /* Send to the channel */ silc_server_send_channel_key(server, sock, channel, FALSE); id = silc_id_id2str(channel->id, SILC_ID_CHANNEL); - id_len = SILC_ID_CHANNEL_LEN; - + id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL); + /* Send to the server */ chk = silc_channel_key_payload_encode(id_len, id, strlen(channel->channel_key-> diff --git a/apps/silcd/server.c b/apps/silcd/server.c index e65b4eaf..64c837a1 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -1564,9 +1564,13 @@ SILC_TASK_CALLBACK(silc_server_packet_process) SILC_LOG_DEBUG(("Premature EOF from connection %d", sock->sock)); SILC_SET_DISCONNECTING(sock); - if (sock->user_data) - silc_server_free_sock_user_data(server, sock, NULL); - else if (server->router_conn && server->router_conn->sock == sock && + if (sock->user_data) { + char tmp[128]; + if (silc_socket_get_error(sock, tmp, sizeof(tmp) - 1)) + silc_server_free_sock_user_data(server, sock, tmp); + else + silc_server_free_sock_user_data(server, sock, NULL); + } else if (server->router_conn && server->router_conn->sock == sock && !server->router && server->standalone) silc_schedule_task_add(server->schedule, 0, silc_server_connect_to_router, @@ -3711,6 +3715,8 @@ void silc_server_save_users_on_channel(SilcServer server, SilcIDCacheEntry cache; bool global; + SILC_LOG_DEBUG(("Start")); + for (i = 0; i < user_count; i++) { /* Client ID */ SILC_GET16_MSB(idp_len, user_list->data + 2); @@ -3916,10 +3922,14 @@ SilcBuffer silc_server_get_client_channel_list(SilcServer server, it using WHOIS command. */ SilcClientEntry silc_server_get_client_resolve(SilcServer server, - SilcClientID *client_id) + SilcClientID *client_id, + bool *resolved) { SilcClientEntry client; + if (resolved) + *resolved = FALSE; + client = silc_idlist_find_client_by_id(server->local_list, client_id, TRUE, NULL); if (!client) { @@ -3949,6 +3959,10 @@ SilcClientEntry silc_server_get_client_resolve(SilcServer server, buffer->data, buffer->len, FALSE); silc_buffer_free(idp); silc_buffer_free(buffer); + + if (resolved) + *resolved = TRUE; + return NULL; } diff --git a/apps/silcd/server.h b/apps/silcd/server.h index 58113779..6590f602 100644 --- a/apps/silcd/server.h +++ b/apps/silcd/server.h @@ -224,6 +224,7 @@ SilcSocketConnection silc_server_get_client_route(SilcServer server, SilcBuffer silc_server_get_client_channel_list(SilcServer server, SilcClientEntry client); SilcClientEntry silc_server_get_client_resolve(SilcServer server, - SilcClientID *client_id); + SilcClientID *client_id, + bool *resolved); #endif diff --git a/apps/silcd/server_util.c b/apps/silcd/server_util.c index f090ff1d..c41c8bcf 100644 --- a/apps/silcd/server_util.c +++ b/apps/silcd/server_util.c @@ -212,8 +212,12 @@ bool silc_server_remove_clients_by_server(SilcServer server, /* Remove the client entry */ silc_server_remove_clients_channels(server, NULL, client, channels); - client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED; - id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF; + if (!server_signoff) { + client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED; + id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF; + } else { + silc_idlist_del_client(server->local_list, client); + } server->stat.clients--; if (server->server_type == SILC_ROUTER) server->stat.cell_clients--; @@ -268,8 +272,12 @@ bool silc_server_remove_clients_by_server(SilcServer server, /* Remove the client entry */ silc_server_remove_clients_channels(server, NULL, client, channels); - client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED; - id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF; + if (!server_signoff) { + client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED; + id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF; + } else { + silc_idlist_del_client(server->global_list, client); + } server->stat.clients--; if (server->server_type == SILC_ROUTER) server->stat.cell_clients--; diff --git a/lib/silcutil/silcsockconn.h b/lib/silcutil/silcsockconn.h index f2e15e3c..a7c23d5a 100644 --- a/lib/silcutil/silcsockconn.h +++ b/lib/silcutil/silcsockconn.h @@ -179,6 +179,7 @@ struct SilcSocketConnectionStruct { void *user_data; SilcProtocol protocol; uint32 flags; + uint8 sock_error; int users; char *hostname; @@ -313,6 +314,23 @@ int silc_socket_read(SilcSocketConnection sock); ***/ int silc_socket_write(SilcSocketConnection sock); +/****f* silcutil/SilcSocketConnectionAPI/silc_socket_get_error + * + * SYNOPSIS + * + * bool silc_socket_get_error(SilcSocketConnection sock, char *error, + * uint32 error_len); + * + * DESCRIPTION + * + * Returns human readable error message into the `error' buffer if + * the socket is int error status. Returns TRUE if error message was + * written into the buffer and FALSE if there is not socket error. + * + ***/ +bool silc_socket_get_error(SilcSocketConnection sock, char *error, + uint32 error_len); + /****f* silcutil/SilcSocketConnectionAPI/SilcSocketConnectionHBCb * * SYNOPSIS diff --git a/lib/silcutil/unix/silcunixsockconn.c b/lib/silcutil/unix/silcunixsockconn.c index 3120e8ef..a4c6c684 100644 --- a/lib/silcutil/unix/silcunixsockconn.c +++ b/lib/silcutil/unix/silcunixsockconn.c @@ -46,6 +46,7 @@ int silc_socket_write(SilcSocketConnection sock) return -2; } SILC_LOG_DEBUG(("Cannot write to socket: %s", strerror(errno))); + sock->sock_error = errno; return -1; } @@ -81,6 +82,7 @@ int silc_socket_read(SilcSocketConnection sock) return -2; } SILC_LOG_DEBUG(("Cannot read from socket: %d:%s", fd, strerror(errno))); + sock->sock_error = errno; return -1; } @@ -103,3 +105,21 @@ int silc_socket_read(SilcSocketConnection sock) return len; } + +/* Returns human readable socket error message */ + +bool silc_socket_get_error(SilcSocketConnection sock, char *error, + uint32 error_len) +{ + char *err; + + if (!sock->sock_error) + return FALSE; + + err = strerror(sock->sock_error); + if (strlen(err) > error_len) + return FALSE; + + memset(error, 0, error_len); + memcpy(error, err, strlen(err)); +} diff --git a/lib/silcutil/win32/silcwin32sockconn.c b/lib/silcutil/win32/silcwin32sockconn.c index 7f604c0c..c63a77ea 100644 --- a/lib/silcutil/win32/silcwin32sockconn.c +++ b/lib/silcutil/win32/silcwin32sockconn.c @@ -47,6 +47,7 @@ int silc_socket_write(SilcSocketConnection sock) return -2; } SILC_LOG_ERROR(("Cannot write to socket: %d", (int)fd)); + sock->sock_error = err; return -1; } @@ -94,6 +95,7 @@ int silc_socket_read(SilcSocketConnection sock) return -2; } SILC_LOG_ERROR(("Cannot read from socket: %d", (int)fd)); + sock->sock_error = err; return -1; } @@ -116,3 +118,12 @@ int silc_socket_read(SilcSocketConnection sock) return len; } + +/* Returns human readable socket error message */ + +bool silc_socket_get_error(SilcSocketConnection sock, char *error, + uint32 error_len) +{ + /* XXX TODO */ + return FALSE; +} -- 2.24.0