From: Pekka Riikonen Date: Wed, 19 Jun 2002 19:41:52 +0000 (+0000) Subject: Fixed topic annoucning, server signoff handling, added -D option, X-Git-Tag: silc.client.0.9.3~12 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=ea35a2214bc62cbdb314cd28f389fd78fe3a31e0 Fixed topic annoucning, server signoff handling, added -D option, better debugging. For rest see CHANGES. --- diff --git a/CHANGES b/CHANGES index a6e6ce1a..8d0ca8c7 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,37 @@ +Wed Jun 19 17:46:31 EEST 2002 Pekka Riikonen + + * Save the channel passphrase when received succesful JOIN + command reply from router, on normal server. Otherwise + joinig +a channels from normal server is not possible. + Affected file silcd/command.c. + + * Fixed a bug in TOPIC_SET notify handling. The notifier + may be other than client too, like server or channel. + It expected it to always be only client and ignored the + notify. Affected file silcd/packet_recieve.c. + + * Removed some (unnecessary) debug printing from + lib/silccore/silcid.c and lib/silccore/silcargument.c. + + * Do not force CMODE_CHANGE when server is announcing new + channel. + + Router announces stuff only after server reannounces channel + after CHANNEL_CHANGE notify. + + These fixes optimizes the announcing procedure, and perhaps + fixes some problems too. Affected file silcd/packet_receive.c. + + * Fixed SERVER_SIGNOFF sending to local clients. It was + totally broken and sent the notify to all local clients, + instead of only to those that was on same channel as the + signing off clients. Affected file silcd/server_util.c. + + * Added -D option to server. It can be used to give debug + level. The levels are from 0 - 99, and are predefined for + smooth server debugging. (see silcd.c for the predefined + levels). Affected file silcd/server.c. + Wed Jun 19 16:01:51 EEST 2002 Pekka Riikonen * Fixed a bug in Irssi SILC client to close the connection diff --git a/apps/silcd/command.c b/apps/silcd/command.c index 50d620a2..116de4fd 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -3683,6 +3683,18 @@ SILC_SERVER_CMD_FUNC(join) SILC_GET32_MSB(created, tmp); if (silc_argument_get_arg_type(reply->args, 7, NULL)) create_key = FALSE; /* Router returned the key already */ + + if (silc_command_get_status(reply->payload, NULL, NULL) && + channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) { + /* Save channel passphrase, if user provided it successfully */ + unsigned char *pa; + SilcUInt32 pa_len; + pa = silc_argument_get_arg_type(reply->args, 3, &pa_len); + if (pa) { + silc_free(channel->passphrase); + channel->passphrase = silc_memdup(pa, pa_len); + } + } } if (silc_command_get(reply->payload) == SILC_COMMAND_WHOIS && diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index 1c71e7e6..ac06a7d2 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -368,22 +368,24 @@ void silc_server_notify(SilcServer server, tmp = silc_argument_get_arg_type(args, 1, &tmp_len); if (!tmp) goto out; - client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL); + client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type); if (!client_id) goto out; /* Get client entry */ - client = silc_idlist_find_client_by_id(server->global_list, - client_id, TRUE, &cache); - if (!client) { - client = silc_idlist_find_client_by_id(server->local_list, + if (id_type == SILC_ID_CLIENT) { + client = silc_idlist_find_client_by_id(server->global_list, client_id, TRUE, &cache); if (!client) { - silc_free(client_id); - goto out; + client = silc_idlist_find_client_by_id(server->local_list, + client_id, TRUE, &cache); + if (!client) { + silc_free(client_id); + goto out; + } } + silc_free(client_id); } - silc_free(client_id); /* Get the topic */ tmp = silc_argument_get_arg_type(args, 2, &tmp_len); @@ -414,14 +416,16 @@ void silc_server_notify(SilcServer server, if (channel->topic && !strcmp(channel->topic, tmp)) goto out; - /* Get user's channel entry and check that topic set is allowed. */ - if (!silc_server_client_on_channel(client, channel, &chl)) - goto out; - if (channel->mode & SILC_CHANNEL_MODE_TOPIC && - !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) && - !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) { - SILC_LOG_DEBUG(("Topic change is not allowed")); - goto out; + if (client) { + /* Get user's channel entry and check that topic set is allowed. */ + if (!silc_server_client_on_channel(client, channel, &chl)) + goto out; + if (channel->mode & SILC_CHANNEL_MODE_TOPIC && + !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) && + !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) { + SILC_LOG_DEBUG(("Topic change is not allowed")); + goto out; + } } /* Change the topic */ @@ -1098,7 +1102,7 @@ void silc_server_notify(SilcServer server, silc_server_send_notify_topic_set(server, sock, server->server_type == SILC_ROUTER ? TRUE : FALSE, channel, - channel->id, SILC_ID_CHANNEL, + server->id, SILC_ID_SERVER, channel->topic); } } @@ -2806,8 +2810,14 @@ void silc_server_new_channel(SilcServer server, SILC_LOG_DEBUG(("Forcing the server to change Channel ID")); silc_server_send_notify_channel_change(server, sock, FALSE, channel_id, channel->id); + + /* Wait that server re-announces this channel */ + return; } +#if 0 /* Lets expect that server send CMODE_CHANGE notify anyway to + (attempt) force mode change, and may very well get it. */ + /* If the mode is different from what we have then enforce the mode change. */ mode = silc_channel_get_mode(payload); @@ -2820,6 +2830,7 @@ void silc_server_new_channel(SilcServer server, channel->passphrase, channel->founder_key); } +#endif /* Create new key for the channel and send it to the server and everybody else possibly on the channel. */ @@ -2881,6 +2892,13 @@ void silc_server_new_channel(SilcServer server, users_modes->len, FALSE); silc_buffer_free(users_modes); } + if (channel->topic) { + silc_server_send_notify_topic_set(server, sock, + server->server_type == SILC_ROUTER ? + TRUE : FALSE, channel, + server->id, SILC_ID_SERVER, + channel->topic); + } } } diff --git a/apps/silcd/packet_send.c b/apps/silcd/packet_send.c index 737da431..2d41ebcc 100644 --- a/apps/silcd/packet_send.c +++ b/apps/silcd/packet_send.c @@ -387,8 +387,7 @@ void silc_server_packet_route(SilcServer server, clients (for server locally connected, and for router local cell). */ void silc_server_packet_send_clients(SilcServer server, - SilcClientEntry *clients, - SilcUInt32 clients_count, + SilcHashTable clients, SilcPacketType type, SilcPacketFlags flags, bool route, @@ -397,18 +396,18 @@ void silc_server_packet_send_clients(SilcServer server, bool force_send) { SilcSocketConnection sock = NULL; + SilcHashTableList htl; SilcClientEntry client = NULL; SilcServerEntry *routed = NULL; SilcUInt32 routed_count = 0; bool gone = FALSE; - int i, k; + int k; SILC_LOG_DEBUG(("Sending packet to list of clients")); /* Send to all clients in table */ - for (i = 0; i < clients_count; i++) { - client = clients[i]; - + silc_hash_table_list(clients, &htl); + while (silc_hash_table_get(&htl, NULL, (void **)&client)) { /* If client has router set it is not locally connected client and we will route the message to the router set in the client. Though, send locally connected server in all cases. */ @@ -453,7 +452,7 @@ void silc_server_packet_send_clients(SilcServer server, client->id, SILC_ID_CLIENT, data, data_len, force_send); } - + silc_hash_table_list_reset(&htl); silc_free(routed); } @@ -590,7 +589,7 @@ void silc_server_packet_send_to_channel(SilcServer server, /* Send the message to clients on the channel's client list. */ silc_hash_table_list(channel->user_list, &htl); - while (silc_hash_table_get(&htl, NULL, (void *)&chl)) { + while (silc_hash_table_get(&htl, NULL, (void **)&chl)) { client = chl->client; if (!client) continue; @@ -788,7 +787,7 @@ void silc_server_packet_relay_to_channel(SilcServer server, /* Send the message to clients on the channel's client list. */ silc_hash_table_list(channel->user_list, &htl); - while (silc_hash_table_get(&htl, NULL, (void *)&chl)) { + while (silc_hash_table_get(&htl, NULL, (void **)&chl)) { client = chl->client; if (!client || client == sender_entry) continue; @@ -940,7 +939,7 @@ void silc_server_packet_send_local_channel(SilcServer server, /* Send the message to clients on the channel's client list. */ silc_hash_table_list(channel->user_list, &htl); - while (silc_hash_table_get(&htl, NULL, (void *)&chl)) { + while (silc_hash_table_get(&htl, NULL, (void **)&chl)) { if (chl->client && !chl->client->router) { sock = (SilcSocketConnection)chl->client->connection; @@ -1532,12 +1531,12 @@ void silc_server_send_notify_on_channels(SilcServer server, packetdata.src_id_type = SILC_ID_SERVER; silc_hash_table_list(client->channels, &htl); - while (silc_hash_table_get(&htl, NULL, (void *)&chl)) { + while (silc_hash_table_get(&htl, NULL, (void **)&chl)) { channel = chl->channel; /* Send the message to all clients on the channel's client list. */ silc_hash_table_list(channel->user_list, &htl2); - while (silc_hash_table_get(&htl2, NULL, (void *)&chl2)) { + while (silc_hash_table_get(&htl2, NULL, (void **)&chl2)) { c = chl2->client; if (sender && c == sender) diff --git a/apps/silcd/packet_send.h b/apps/silcd/packet_send.h index 8e8ca9c9..ca0779e9 100644 --- a/apps/silcd/packet_send.h +++ b/apps/silcd/packet_send.h @@ -60,8 +60,7 @@ void silc_server_packet_route(SilcServer server, SilcSocketConnection sock, SilcPacketContext *packet); void silc_server_packet_send_clients(SilcServer server, - SilcClientEntry *clients, - SilcUInt32 clients_count, + SilcHashTable clients, SilcPacketType type, SilcPacketFlags flags, bool route, diff --git a/apps/silcd/protocol.c b/apps/silcd/protocol.c index 75eb86ed..06922c36 100644 --- a/apps/silcd/protocol.c +++ b/apps/silcd/protocol.c @@ -170,15 +170,16 @@ silc_server_protocol_ke_verify_key(SilcSKE ske, (SilcServerKEInternalContext *)protocol->context; SilcServer server = (SilcServer)ctx->server; - SILC_LOG_DEBUG(("Start")); - - if (silc_verify_public_key_internal(server, ctx->sock, - (ctx->responder == FALSE ? - SILC_SOCKET_TYPE_ROUTER: - ctx->sconfig.ref_ptr ? SILC_SOCKET_TYPE_SERVER : - ctx->rconfig.ref_ptr ? SILC_SOCKET_TYPE_ROUTER : - SILC_SOCKET_TYPE_CLIENT), - pk_data, pk_len, pk_type)) + SILC_LOG_DEBUG(("Verifying received public key")); + + if (silc_verify_public_key_internal( + server, ctx->sock, + (ctx->responder == FALSE ? + SILC_SOCKET_TYPE_ROUTER: + ctx->sconfig.ref_ptr ? SILC_SOCKET_TYPE_SERVER : + ctx->rconfig.ref_ptr ? SILC_SOCKET_TYPE_ROUTER : + SILC_SOCKET_TYPE_CLIENT), + pk_data, pk_len, pk_type)) completion(ske, SILC_SKE_STATUS_OK, completion_context); else completion(ske, SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY, @@ -219,7 +220,7 @@ int silc_server_protocol_ke_set_keys(SilcServer server, SilcUnknownEntry conn_data; SilcIDListData idata; - SILC_LOG_DEBUG(("Setting new key into use")); + SILC_LOG_DEBUG(("Setting new keys into use")); conn_data = silc_calloc(1, sizeof(*conn_data)); idata = (SilcIDListData)conn_data; @@ -373,8 +374,6 @@ static void silc_server_protocol_ke_continue(SilcSKE ske, void *context) (SilcServerKEInternalContext *)protocol->context; SilcServer server = (SilcServer)ctx->server; - SILC_LOG_DEBUG(("Start")); - if (ske->status != SILC_SKE_STATUS_OK) { SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol", silc_ske_map_status(ske->status))); @@ -387,6 +386,7 @@ static void silc_server_protocol_ke_continue(SilcSKE ske, void *context) /* Send Ok to the other end. We will end the protocol as responder sends Ok to us when we will take the new keys into use. */ if (ctx->responder == FALSE) { + SILC_LOG_DEBUG(("Ending key exchange protocol")); silc_ske_end(ctx->ske); /* End the protocol on the next round */ @@ -414,12 +414,10 @@ SILC_TASK_CALLBACK(silc_server_protocol_key_exchange) SilcServer server = (SilcServer)ctx->server; SilcSKEStatus status = SILC_SKE_STATUS_OK; - SILC_LOG_DEBUG(("Start")); - if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN) protocol->state = SILC_PROTOCOL_STATE_START; - SILC_LOG_DEBUG(("State=%d", protocol->state)); + SILC_LOG_DEBUG(("Current protocol state %d", protocol->state)); switch(protocol->state) { case SILC_PROTOCOL_STATE_START: @@ -440,12 +438,15 @@ SILC_TASK_CALLBACK(silc_server_protocol_key_exchange) if (ctx->responder == TRUE) { /* Start the key exchange by processing the received security properties packet from initiator. */ + SILC_LOG_DEBUG(("Process security property list (KE)")); status = silc_ske_responder_start(ske, ctx->rng, ctx->sock, silc_version_string, ctx->packet->buffer, ctx->flags); } else { SilcSKEStartPayload *start_payload; + SILC_LOG_DEBUG(("Send security property list (KE)")); + /* Assemble security properties. */ silc_ske_assemble_security_properties(ske, ctx->flags, silc_version_string, @@ -483,12 +484,14 @@ SILC_TASK_CALLBACK(silc_server_protocol_key_exchange) */ if (ctx->responder == TRUE) { /* Sends the selected security properties to the initiator. */ + SILC_LOG_DEBUG(("Send security property list reply (KE)")); status = silc_ske_responder_phase_1(ctx->ske); } else { /* Call Phase-1 function. This processes the Key Exchange Start paylaod reply we just got from the responder. The callback function will receive the processed payload where we will save it. */ + SILC_LOG_DEBUG(("Process security property list reply (KE)")); status = silc_ske_initiator_phase_1(ctx->ske, ctx->packet->buffer); } @@ -521,11 +524,13 @@ SILC_TASK_CALLBACK(silc_server_protocol_key_exchange) the initiator. This also creates our parts of the Diffie Hellman algorithm. The silc_server_protocol_ke_continue will be called after the public key has been verified. */ + SILC_LOG_DEBUG(("Process KE1 packet")); status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer); } else { /* Call the Phase-2 function. This creates Diffie Hellman key exchange parameters and sends our public part inside Key Exhange 1 Payload to the responder. */ + SILC_LOG_DEBUG(("Send KE1 packet")); status = silc_ske_initiator_phase_2(ctx->ske, server->public_key, server->private_key, @@ -555,6 +560,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_key_exchange) if (ctx->responder == TRUE) { /* This creates the key exchange material and sends our public parts to the initiator inside Key Exchange 2 Payload. */ + SILC_LOG_DEBUG(("Process KE2 packet")); status = silc_ske_responder_finish(ctx->ske, server->public_key, server->private_key, @@ -566,6 +572,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_key_exchange) /* Finish the protocol. This verifies the Key Exchange 2 payload sent by responder. The silc_server_protocol_ke_continue will be called after the public key has been verified. */ + SILC_LOG_DEBUG(("Send KE2 packet")); status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer); } @@ -593,6 +600,8 @@ SILC_TASK_CALLBACK(silc_server_protocol_key_exchange) int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher); int hash_len = silc_hash_len(ctx->ske->prop->hash); + SILC_LOG_DEBUG(("Process computed key material")); + /* Process the key material */ keymat = silc_calloc(1, sizeof(*keymat)); status = silc_ske_process_key_material(ctx->ske, 16, key_len, hash_len, @@ -610,8 +619,10 @@ SILC_TASK_CALLBACK(silc_server_protocol_key_exchange) /* Send Ok to the other end if we are responder. If we are initiator we have sent this already. */ - if (ctx->responder == TRUE) + if (ctx->responder == TRUE) { + SILC_LOG_DEBUG(("Ending key exchange protocol")); silc_ske_end(ctx->ske); + } /* Unregister the timeout task since the protocol has ended. This was the timeout task to be executed if the protocol is @@ -777,6 +788,8 @@ silc_server_get_public_key_auth(SilcServer server, return TRUE; } + SILC_LOG_ERROR(("Error computing signature")); + silc_free(*auth_data); silc_buffer_free(auth); return FALSE; @@ -834,6 +847,8 @@ silc_server_get_authentication(SilcServerConnAuthInternalContext *ctx, remote_auth_len, ske); } + SILC_LOG_DEBUG(("Authentication %s", result ? "successful" : "failed")); + return result; } @@ -848,12 +863,10 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth) (SilcServerConnAuthInternalContext *)protocol->context; SilcServer server = (SilcServer)ctx->server; - SILC_LOG_DEBUG(("Start")); - if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN) protocol->state = SILC_PROTOCOL_STATE_START; - SILC_LOG_DEBUG(("State=%d", protocol->state)); + SILC_LOG_DEBUG(("Current protocol state %d", protocol->state)); switch(protocol->state) { case SILC_PROTOCOL_STATE_START: @@ -1319,12 +1332,10 @@ SILC_TASK_CALLBACK(silc_server_protocol_rekey) SilcIDListData idata = (SilcIDListData)ctx->sock->user_data; SilcSKEStatus status; - SILC_LOG_DEBUG(("Start")); - if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN) protocol->state = SILC_PROTOCOL_STATE_START; - SILC_LOG_DEBUG(("State=%d", protocol->state)); + SILC_LOG_DEBUG(("Current protocol state %d", protocol->state)); switch(protocol->state) { case SILC_PROTOCOL_STATE_START: diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 9631e5f0..4ec15a82 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -1217,8 +1217,6 @@ silc_server_accept_new_connection_lookup(SilcSocketConnection sock, context = (void *)server; - SILC_LOG_DEBUG(("Start")); - /* Check whether we could resolve both IP and FQDN. */ if (!sock->ip || (!strcmp(sock->ip, sock->hostname) && server->config->require_reverse_lookup)) { @@ -1319,6 +1317,7 @@ silc_server_accept_new_connection_lookup(SilcSocketConnection sock, initiator of the protocol thus we will wait for initiation from there before we start the protocol. */ server->stat.auth_attempts++; + SILC_LOG_DEBUG(("Starting key exchange protocol")); silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE, &sock->protocol, proto_ctx, silc_server_accept_new_connection_second); @@ -1404,6 +1403,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_second) if ((protocol->state == SILC_PROTOCOL_STATE_ERROR) || (protocol->state == SILC_PROTOCOL_STATE_FAILURE)) { /* Error occured during protocol */ + SILC_LOG_DEBUG(("Error key exchange protocol")); silc_protocol_free(protocol); sock->protocol = NULL; silc_ske_free_key_material(ctx->keymat); @@ -1436,6 +1436,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_second) ctx->ske->prop->hmac, ctx->ske->prop->group, ctx->responder)) { + SILC_LOG_ERROR(("Error setting key material in use")); silc_protocol_free(protocol); sock->protocol = NULL; silc_ske_free_key_material(ctx->keymat); @@ -1481,6 +1482,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_second) but we won't start it yet. We will be receiving party of this protocol thus we will wait that connecting party will make their first move. */ + SILC_LOG_DEBUG(("Starting connection authentication protocol")); silc_protocol_alloc(SILC_PROTOCOL_SERVER_CONNECTION_AUTH, &sock->protocol, proto_ctx, silc_server_accept_new_connection_final); @@ -1512,11 +1514,10 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) void *id_entry; SilcUInt32 hearbeat_timeout = server->config->param.keepalive_secs; - SILC_LOG_DEBUG(("Start")); - if (protocol->state == SILC_PROTOCOL_STATE_ERROR || protocol->state == SILC_PROTOCOL_STATE_FAILURE) { /* Error occured during protocol */ + SILC_LOG_DEBUG(("Error during authentication protocol")); silc_protocol_free(protocol); sock->protocol = NULL; if (ctx->packet) @@ -1548,6 +1549,11 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) if (!silc_server_connection_allowed(server, sock, ctx->conn_type, &server->config->param, conn->param, ctx->ske)) { + SILC_LOG_INFO(("Connection %s (%s) is not allowed", sock->hostname, + sock->ip)); + silc_server_disconnect_remote(server, sock, + SILC_STATUS_ERR_BANNED_FROM_SERVER, + NULL); server->stat.auth_failures++; goto out; } @@ -1602,6 +1608,11 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) &server->config->param, rconn ? rconn->param : NULL, ctx->ske)) { + SILC_LOG_INFO(("Connection %s (%s) is not allowed", sock->hostname, + sock->ip)); + silc_server_disconnect_remote(server, sock, + SILC_STATUS_ERR_BANNED_FROM_SERVER, + NULL); server->stat.auth_failures++; goto out; } @@ -1626,6 +1637,11 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) &server->config->param, sconn ? sconn->param : NULL, ctx->ske)) { + SILC_LOG_INFO(("Connection %s (%s) is not allowed", sock->hostname, + sock->ip)); + silc_server_disconnect_remote(server, sock, + SILC_STATUS_ERR_BANNED_FROM_SERVER, + NULL); server->stat.auth_failures++; goto out; } @@ -1769,17 +1785,19 @@ SILC_TASK_CALLBACK(silc_server_packet_process) SilcUInt32 sequence = 0; int ret; - if (!sock) + if (!sock) { + SILC_LOG_DEBUG(("Unknown socket connection")); return; - - SILC_LOG_DEBUG(("Processing packet")); + } /* Packet sending */ if (type == SILC_TASK_WRITE) { /* Do not send data to disconnected connection */ - if (SILC_IS_DISCONNECTED(sock)) + if (SILC_IS_DISCONNECTED(sock)) { + SILC_LOG_DEBUG(("Disconnected socket connection, cannot send")); return; + } server->stat.packets_sent++; @@ -1911,7 +1929,7 @@ SILC_TASK_CALLBACK(silc_server_packet_parse_real) SilcIDListData idata = (SilcIDListData)sock->user_data; int ret; - SILC_LOG_DEBUG(("Start")); + SILC_LOG_DEBUG(("Parsing packet")); /* Parse the packet */ if (parse_ctx->normal) @@ -2061,8 +2079,6 @@ void silc_server_packet_parse_type(SilcServer server, SilcPacketType type = packet->type; SilcIDListData idata = (SilcIDListData)sock->user_data; - SILC_LOG_DEBUG(("Parsing packet type %d", type)); - /* Parse the packet type */ switch (type) { case SILC_PACKET_DISCONNECT: @@ -2510,7 +2526,6 @@ void silc_server_packet_parse_type(SilcServer server, SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type)); break; } - } /* Creates connection to a remote router. */ diff --git a/apps/silcd/server_util.c b/apps/silcd/server_util.c index e7bff221..c041ffb0 100644 --- a/apps/silcd/server_util.c +++ b/apps/silcd/server_util.c @@ -28,14 +28,16 @@ extern char *server_version; keys are regnerated. This is called only by the function silc_server_remove_clients_by_server. */ -static void silc_server_remove_clients_channels(SilcServer server, - SilcSocketConnection sock, - SilcClientEntry client, - SilcHashTable channels) +static void +silc_server_remove_clients_channels(SilcServer server, + SilcServerEntry server_entry, + SilcHashTable clients, + SilcClientEntry client, + SilcHashTable channels) { SilcChannelEntry channel; - SilcChannelClientEntry chl; - SilcHashTableList htl; + SilcChannelClientEntry chl, chl2; + SilcHashTableList htl, htl2; SilcBuffer clidp; SILC_LOG_DEBUG(("Start")); @@ -43,6 +45,9 @@ static void silc_server_remove_clients_channels(SilcServer server, if (!client || !client->id) return; + if (silc_hash_table_find(clients, client, NULL, NULL)) + silc_hash_table_del(clients, client); + clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT); /* Remove the client from all channels. The client is removed from @@ -94,6 +99,21 @@ static void silc_server_remove_clients_channels(SilcServer server, continue; } + /* Mark other local clients to the table of clients whom will receive + the SERVER_SIGNOFF notify. */ + silc_hash_table_list(channel->user_list, &htl2); + while (silc_hash_table_get(&htl2, NULL, (void **)&chl2)) { + SilcClientEntry c = chl2->client; + if (!c) + continue; + + /* Add client to table, if it's not from the signoff server */ + if (c->router != server_entry && + !silc_hash_table_find(clients, c, NULL, NULL)) + silc_hash_table_add(clients, c, c); + } + silc_hash_table_list_reset(&htl2); + /* Add the channel to the the channels list to regenerate the channel key */ if (!silc_hash_table_find(channels, channel, NULL, NULL)) @@ -117,13 +137,11 @@ bool silc_server_remove_clients_by_server(SilcServer server, SilcIDCacheEntry id_cache = NULL; SilcClientEntry client = NULL; SilcBuffer idp; - SilcClientEntry *clients = NULL; - SilcUInt32 clients_c = 0; unsigned char **argv = NULL; SilcUInt32 *argv_lens = NULL, *argv_types = NULL, argc = 0; SilcHashTableList htl; SilcChannelEntry channel; - SilcHashTable channels; + SilcHashTable channels, clients; int i; SILC_LOG_DEBUG(("Start")); @@ -133,6 +151,8 @@ bool silc_server_remove_clients_by_server(SilcServer server, from the channels. */ channels = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, NULL, NULL, NULL, TRUE); + clients = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, NULL, + NULL, NULL, TRUE); if (server_signoff) { idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER); @@ -160,13 +180,6 @@ bool silc_server_remove_clients_by_server(SilcServer server, } if (client->router != entry) { - if (server_signoff) { - clients = silc_realloc(clients, - sizeof(*clients) * (clients_c + 1)); - clients[clients_c] = client; - clients_c++; - } - if (!silc_idcache_list_next(list, &id_cache)) break; else @@ -196,7 +209,8 @@ bool silc_server_remove_clients_by_server(SilcServer server, SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR); /* Remove the client entry */ - silc_server_remove_clients_channels(server, NULL, client, channels); + silc_server_remove_clients_channels(server, entry, clients, + client, channels); if (!server_signoff) { client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED; id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF; @@ -226,13 +240,6 @@ bool silc_server_remove_clients_by_server(SilcServer server, } if (client->router != entry) { - if (server_signoff && client->connection) { - clients = silc_realloc(clients, - sizeof(*clients) * (clients_c + 1)); - clients[clients_c] = client; - clients_c++; - } - if (!silc_idcache_list_next(list, &id_cache)) break; else @@ -262,7 +269,8 @@ bool silc_server_remove_clients_by_server(SilcServer server, SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR); /* Remove the client entry */ - silc_server_remove_clients_channels(server, NULL, client, channels); + silc_server_remove_clients_channels(server, entry, clients, + client, channels); if (!server_signoff) { client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED; id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF; @@ -295,17 +303,18 @@ bool silc_server_remove_clients_by_server(SilcServer server, silc_buffer_free(args); } + + /* Send to local clients. We also send the list of client ID's that is to be removed for those servers that would like to use that list. */ args = silc_argument_payload_encode(argc, argv, argv_lens, argv_types); not = silc_notify_payload_encode_args(SILC_NOTIFY_TYPE_SERVER_SIGNOFF, argc, args); - silc_server_packet_send_clients(server, clients, clients_c, + silc_server_packet_send_clients(server, clients, SILC_PACKET_NOTIFY, 0, FALSE, not->data, not->len, FALSE); - silc_free(clients); silc_buffer_free(args); silc_buffer_free(not); for (i = 0; i < argc; i++) @@ -313,6 +322,7 @@ bool silc_server_remove_clients_by_server(SilcServer server, silc_free(argv); silc_free(argv_lens); silc_free(argv_types); + silc_hash_table_free(clients); } /* We must now re-generate the channel key for all channels that had diff --git a/apps/silcd/silcd.c b/apps/silcd/silcd.c index c1a5277e..4b49cafa 100644 --- a/apps/silcd/silcd.c +++ b/apps/silcd/silcd.c @@ -45,6 +45,7 @@ static struct option long_opts[] = { "config-file", 1, NULL, 'f' }, { "passphrase", 1, NULL, 'p' }, { "debug", 2, NULL, 'd' }, + { "debug-level", 1, NULL, 'D' }, { "hexdump", 0, NULL, 'x' }, { "help", 0, NULL, 'h' }, { "foreground", 0, NULL, 'F' }, @@ -75,6 +76,7 @@ static void silc_usage(void) " Generic Options:\n" " -f --config-file=FILE Alternate configuration file\n" " -d --debug=string Enable debugging (Implies --foreground)\n" +" -D --debug-level=level Enable debugging (Implies --foreground)\n" " -x --hexdump Enable hexdumps (Implies --debug)\n" " -h --help Display this message\n" " -F --foreground Dont fork\n" @@ -310,6 +312,80 @@ SILC_TASK_CALLBACK(dump_stats) fclose(fdd); } +typedef struct { + int level; + const char *string; +} DebugLevel; + +static DebugLevel debug_levels[] = { + /* Basic stuff from silcd/ */ + { 5, "silc_server_*" }, + + /* All from silcd/ */ + { 10, "*silcd*,*serverid*,silc_server_*,*idlist*" }, + + /* All from silcd/ and basic stuff from libs */ + { 15, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*,*silcske*" }, + + /* All from silcd/ and more stuff from libs */ + { 20, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*," + "*silcpacket*,*ske*,*silcrng*" }, + + /* All from silcd/ and even more stuff from libs */ + { 25, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*," + "*silcpacket*,*ske*,*silcrng*,*command*,*channel*,*private*,*notify*" }, + + /* All from silcd/ and even more stuff from libs + all from silccore */ + { 30, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*," + "*silcpacket*,*ske*,*silcrng*,*command*,*channel*,*private*,*notify*" + "*silcid*,*argument*" }, + + /* All from silcd/, all from silccore, silccrypt and silcmath */ + { 35, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*," + "*silcpacket*,*ske*,*silcrng*,*command*,*channel*,*private*,*notify*" + "*silcid*,*argument*,*pkcs*,*hmac*,*hash*,*cipher*,silc_math*" }, + + /* All from silcd/, all from silccore, silccrypt and silcmath + stuff + from silcutil */ + { 40, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*," + "*silcpacket*,*ske*,*silcrng*,*command*,*channel*,*private*,*notify*" + "*silcid*,*argument*,*pkcs*,*hmac*,*hash*,*cipher*,silc_math*,*sim*" + "*sockconn*" }, + + /* All from silcd/, all from silccore, silccrypt and silcmath + more stuff + from silcutil */ + { 45, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*," + "*silcpacket*,*ske*,*silcrng*,*command*,*channel*,*private*,*notify*" + "*silcid*,*argument*,*pkcs*,*hmac*,*hash*,*cipher*,silc_math*,*sim*" + "*sockconn*,*net*" }, + + /* All from silcd/, all from silccore, silccrypt and silcmath + more stuff + from silcutil */ + { 50, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*," + "*silcpacket*,*ske*,*silcrng*,*command*,*channel*,*private*,*notify*" + "*silcid*,*argument*,*pkcs*,*hmac*,*hash*,*cipher*,silc_math*,*sim*" + "*sockconn*,*net*,*log*,*config*" }, + + /* All */ + { 90, "*" }, + + { -1, NULL }, +}; + +static void silc_get_debug_level(int level) +{ + int i; + + if (level < 0) + return; + + for (i = 0; debug_levels[i].string; i++) + if (level <= debug_levels[i].level) { + silc_log_set_debug_string(debug_levels[i].string); + break; + } +} + /* This function should not be called directly but throught the wrapper macro SILC_SERVER_LOG_STDERR() */ @@ -333,7 +409,7 @@ int main(int argc, char **argv) /* Parse command line arguments */ if (argc > 1) { - while ((opt = getopt_long(argc, argv, "f:p:d:xhFVC:", + while ((opt = getopt_long(argc, argv, "f:p:d:D:xhFVC:", long_opts, &option_index)) != EOF) { switch(opt) { case 'h': @@ -352,8 +428,21 @@ int main(int argc, char **argv) silc_debug = TRUE; if (optarg) silc_log_set_debug_string(optarg); - foreground = TRUE; /* implied */ - silc_log_quick = TRUE; /* implied */ + foreground = TRUE; /* implied */ + silc_log_quick = TRUE; /* implied */ +#else + fprintf(stderr, + "Run-time debugging is not enabled. To enable it recompile\n" + "the server with --enable-debug configuration option.\n"); +#endif + break; + case 'D': +#ifdef SILC_DEBUG + silc_debug = TRUE; + if (optarg) + silc_get_debug_level(atoi(optarg)); + foreground = TRUE; /* implied */ + silc_log_quick = TRUE; /* implied */ #else fprintf(stderr, "Run-time debugging is not enabled. To enable it recompile\n" diff --git a/lib/silccore/silcargument.c b/lib/silccore/silcargument.c index dd470a37..2b69f80b 100644 --- a/lib/silccore/silcargument.c +++ b/lib/silccore/silcargument.c @@ -50,8 +50,6 @@ SilcArgumentPayload silc_argument_payload_parse(const unsigned char *payload, SilcUInt32 pull_len = 0; int i = 0, ret; - SILC_LOG_DEBUG(("Parsing argument payload")); - silc_buffer_set(&buffer, (unsigned char *)payload, payload_len); newp = silc_calloc(1, sizeof(*newp)); if (!newp) @@ -95,8 +93,10 @@ SilcArgumentPayload silc_argument_payload_parse(const unsigned char *payload, pull_len += 3 + p_len; } - if (buffer.len != 0) + if (buffer.len != 0) { + SILC_LOG_DEBUG(("Malformed argument payload")); goto err; + } newp->argc = argc; newp->pos = 0; @@ -106,6 +106,7 @@ SilcArgumentPayload silc_argument_payload_parse(const unsigned char *payload, return newp; err: + SILC_LOG_DEBUG(("Error parsing argument payload")); if (i) for (ret = 0; ret < i; ret++) silc_free(newp->argv[ret]); @@ -129,8 +130,6 @@ SilcBuffer silc_argument_payload_encode(SilcUInt32 argc, SilcUInt32 len; int i; - SILC_LOG_DEBUG(("Encoding Argument payload")); - len = 0; for (i = 0; i < argc; i++) len += 3 + argv_lens[i]; @@ -163,8 +162,6 @@ SilcBuffer silc_argument_payload_encode_payload(SilcArgumentPayload payload) SilcUInt32 len; int i; - SILC_LOG_DEBUG(("Encoding Argument payload")); - len = 0; for (i = 0; i < payload->argc; i++) len += 3 + payload->argv_lens[i]; diff --git a/lib/silccore/silcid.c b/lib/silccore/silcid.c index 6e892c08..ee2b1edb 100644 --- a/lib/silccore/silcid.c +++ b/lib/silccore/silcid.c @@ -48,8 +48,6 @@ SilcIDPayload silc_id_payload_parse(const unsigned char *payload, SilcIDPayload newp; int ret; - SILC_LOG_DEBUG(("Parsing ID payload")); - silc_buffer_set(&buffer, (unsigned char *)payload, payload_len); newp = silc_calloc(1, sizeof(*newp)); if (!newp) @@ -81,6 +79,7 @@ SilcIDPayload silc_id_payload_parse(const unsigned char *payload, return newp; err: + SILC_LOG_DEBUG(("Error parsing ID payload")); silc_free(newp); return NULL; } @@ -103,21 +102,21 @@ void *silc_id_payload_parse_id(const unsigned char *data, SilcUInt32 len, SILC_STR_UI_SHORT(&idlen), SILC_STR_END); if (ret == -1) - return NULL; + goto err; if (type > SILC_ID_CHANNEL) - return NULL; + goto err; silc_buffer_pull(&buffer, 4); if (idlen > buffer.len || idlen > SILC_PACKET_MAX_ID_LEN) - return NULL; + goto err; ret = silc_buffer_unformat(&buffer, SILC_STR_UI_XNSTRING(&id_data, idlen), SILC_STR_END); if (ret == -1) - return NULL; + goto err; id = silc_id_str2id(id_data, idlen, type); @@ -125,6 +124,10 @@ void *silc_id_payload_parse_id(const unsigned char *data, SilcUInt32 len, *ret_type = type; return id; + + err: + SILC_LOG_DEBUG(("Error parsing ID payload")); + return NULL; } /* Encodes ID Payload */ @@ -148,10 +151,6 @@ SilcBuffer silc_id_payload_encode_data(const unsigned char *id, { SilcBuffer buffer; - SILC_LOG_DEBUG(("Encoding %s ID payload", - type == SILC_ID_CLIENT ? "Client" : - type == SILC_ID_SERVER ? "Server" : "Channel")); - buffer = silc_buffer_alloc_size(4 + id_len); if (!buffer) return NULL; diff --git a/lib/silcutil/Makefile.am b/lib/silcutil/Makefile.am index b91e5c5d..eeea6a09 100644 --- a/lib/silcutil/Makefile.am +++ b/lib/silcutil/Makefile.am @@ -35,9 +35,18 @@ endif endif endif +if SILC_DIST_TOOLKIT +SILC_DIST_SOURCE = stacktrace.c +SILC_DIST_HEADERS = stacktrace.h +else +SILC_DIST_SOURCE = +SILC_DIST_HEADERS = +endif + noinst_LIBRARIES = libsilcutil.a libsilcutil_a_SOURCES = \ + $(SILC_DIST_SOURCE) \ silcbuffmt.c \ silcconfig.c \ silclog.c \ @@ -49,11 +58,11 @@ libsilcutil_a_SOURCES = \ silcutil.c \ silchashtable.c \ silcsockconn.c \ - silcprotocol.c \ - stacktrace.c + silcprotocol.c if SILC_DIST_TOOLKIT include_HEADERS = \ + $(SILC_DIST_SOURCE) \ silcbuffer.h \ silcbuffmt.h \ silcconfig.h \ diff --git a/lib/silcutil/silclog.c b/lib/silcutil/silclog.c index 176c3eb7..4a70cbc5 100644 --- a/lib/silcutil/silclog.c +++ b/lib/silcutil/silclog.c @@ -497,6 +497,7 @@ void silc_log_set_debug_string(const char *debug_string) len = strlen(string); if (len >= sizeof(silc_log_debug_string)) len = sizeof(silc_log_debug_string) - 1; + memset(silc_log_debug_string, 0, sizeof(silc_log_debug_string)); strncpy(silc_log_debug_string, string, len); silc_free(string); } diff --git a/lib/silcutil/silcmemory.h b/lib/silcutil/silcmemory.h index 233f3894..6c213f7a 100644 --- a/lib/silcutil/silcmemory.h +++ b/lib/silcutil/silcmemory.h @@ -120,6 +120,10 @@ void silc_free(void *ptr); void *silc_memdup(const void *ptr, size_t size); #else +#ifndef SILC_DIST_TOOLKIT +#error "The stack trace is not supported in this distribution" +#endif + #include "stacktrace.h" #endif /* SILC_STACKTRACE */