From: Pekka Riikonen Date: Thu, 12 Apr 2001 14:28:26 +0000 (+0000) Subject: updates. X-Git-Tag: SILC.0.1~21 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=1780fdaeca19a2c8bea90ab8eabcd6c081a30ee6 updates. --- diff --git a/CHANGES b/CHANGES index c08ef09a..13b650f7 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,12 @@ +Thu Apr 12 14:42:51 EEST 2001 Pekka Riikonen + + * If re-key protocol is active then process the incoming packets + synchronously since we must assure that icoming packets encrypted + with the old key is processed before the new keys is set to + use. This is true other packets than for REKEY packets. + Affected file silcd/server.c. The same was done to client library + as well, affected file lib/silcclient/client.c. + Thu Apr 12 12:01:52 EEST 2001 Pekka Riikonen * Fixed bug in client and server to accept the force send if diff --git a/apps/silc/silc.c b/apps/silc/silc.c index 0ff3e1ed..f4a188d6 100644 --- a/apps/silc/silc.c +++ b/apps/silc/silc.c @@ -577,6 +577,13 @@ static void silc_client_process_message(SilcClientInternal app) (*cmd->cb)(ctx); } else { + if (app->conn->current_channel) + silc_client_send_channel_message(app->client, + app->conn, + app->conn->current_channel, NULL, + 0, "HALOO", 5, TRUE); + +#if 0 /* Normal message to a channel */ if (len && app->conn && app->conn->current_channel && app->conn->current_channel->on_channel == TRUE) { @@ -586,6 +593,7 @@ static void silc_client_process_message(SilcClientInternal app) app->conn->current_channel, NULL, 0, data, strlen(data), TRUE); } +#endif } out: diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index 1855c27c..c5ed42a8 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -2060,5 +2060,5 @@ void silc_server_rekey(SilcServer server, if (proto_ctx->pfs == FALSE) /* Run the protocol */ - protocol->execute(server->timeout_queue, 0, protocol, sock->sock, 0, 0); + protocol->execute(server->timeout_queue, 0, protocol, sock->sock, 0, 1); } diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 8ff37570..aea2f4c6 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -884,12 +884,12 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final) timeout!! */ hb_context = silc_calloc(1, sizeof(*hb_context)); hb_context->server = server; - silc_socket_set_heartbeat(sock, 600, hb_context, + silc_socket_set_heartbeat(sock, 30, hb_context, silc_server_perform_heartbeat, server->timeout_queue); /* Register re-key timeout */ - idata->rekey->timeout = 3600; /* XXX hardcoded */ + idata->rekey->timeout = 60; /* XXX hardcoded */ idata->rekey->context = (void *)server; silc_task_register(server->timeout_queue, sock->sock, silc_server_rekey_callback, @@ -1259,7 +1259,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) timeout!! */ hb_context = silc_calloc(1, sizeof(*hb_context)); hb_context->server = server; - silc_socket_set_heartbeat(sock, 600, hb_context, + silc_socket_set_heartbeat(sock, 30, hb_context, silc_server_perform_heartbeat, server->timeout_queue); @@ -1422,7 +1422,7 @@ static int silc_server_packet_decrypt_check(SilcPacketType packet_type, return FALSE; } - + /* Parses whole packet, received earlier. */ SILC_TASK_CALLBACK(silc_server_packet_parse_real) @@ -1524,21 +1524,37 @@ void silc_server_packet_parse(SilcPacketParserContext *parser_context) break; case SILC_SOCKET_TYPE_CLIENT: /* Parse the packet with timeout (unless protocol is active) */ - silc_task_register(server->timeout_queue, sock->sock, - silc_server_packet_parse_real, - (void *)parser_context, 0, - (sock->protocol ? 1 : 100000), - SILC_TASK_TIMEOUT, - SILC_TASK_PRI_NORMAL); + + /* If REKEY protocol is active we must proccess the packets synchronously + since we must assure that incoming packets that are encrypted with + the old key is processed before the new keys is set to use. */ + if (SILC_SERVER_IS_REKEY(sock)) + silc_server_packet_parse_real(server->timeout_queue, SILC_TASK_READ, + (void *)parser_context, sock->sock); + else + silc_task_register(server->timeout_queue, sock->sock, + silc_server_packet_parse_real, + (void *)parser_context, 0, + (sock->protocol ? 1 : 100000), + SILC_TASK_TIMEOUT, + SILC_TASK_PRI_NORMAL); break; case SILC_SOCKET_TYPE_SERVER: case SILC_SOCKET_TYPE_ROUTER: /* Packets from servers are parsed as soon as possible */ - silc_task_register(server->timeout_queue, sock->sock, - silc_server_packet_parse_real, - (void *)parser_context, 0, 1, - SILC_TASK_TIMEOUT, - SILC_TASK_PRI_NORMAL); + + /* If REKEY protocol is active we must proccess the packets synchronously + since we must assure that incoming packets that are encrypted with + the old key is processed before the new keys is set to use. */ + if (SILC_SERVER_IS_REKEY(sock)) + silc_server_packet_parse_real(server->timeout_queue, SILC_TASK_READ, + (void *)parser_context, sock->sock); + else + silc_task_register(server->timeout_queue, sock->sock, + silc_server_packet_parse_real, + (void *)parser_context, 0, 1, + SILC_TASK_TIMEOUT, + SILC_TASK_PRI_NORMAL); break; default: return; @@ -1744,7 +1760,7 @@ void silc_server_packet_parse_type(SilcServer server, /* Let the protocol handle the packet */ sock->protocol->execute(server->timeout_queue, 0, - sock->protocol, sock->sock, 0, 0); + sock->protocol, sock->sock, 0, 1); } else { SilcServerKEInternalContext *proto_ctx = (SilcServerKEInternalContext *)sock->protocol->context; @@ -1790,7 +1806,7 @@ void silc_server_packet_parse_type(SilcServer server, /* Let the protocol handle the packet */ sock->protocol->execute(server->timeout_queue, 0, - sock->protocol, sock->sock, 0, 0); + sock->protocol, sock->sock, 0, 1); } else { SilcServerKEInternalContext *proto_ctx = (SilcServerKEInternalContext *)sock->protocol->context; @@ -1956,9 +1972,14 @@ void silc_server_packet_parse_type(SilcServer server, proto_ctx->packet = silc_packet_context_dup(packet); /* Let the protocol handle the packet */ - sock->protocol->execute(server->timeout_queue, 0, - sock->protocol, sock->sock, - 0, 100000); + if (proto_ctx->responder == FALSE) + sock->protocol->execute(server->timeout_queue, 0, + sock->protocol, sock->sock, + 0, 0); + else + sock->protocol->execute(server->timeout_queue, 0, + sock->protocol, sock->sock, + 0, 100000); } else { SILC_LOG_ERROR(("Received Re-key done packet but no re-key " "protocol active, packet dropped.")); @@ -2811,7 +2832,7 @@ SILC_TASK_CALLBACK(silc_server_channel_key_rekey) silc_task_register(server->timeout_queue, 0, silc_server_channel_key_rekey, - (void *)rekey, 3600, 0, + (void *)rekey, 30, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL); } @@ -2882,7 +2903,7 @@ void silc_server_create_channel_key(SilcServer server, silc_server_channel_key_rekey); silc_task_register(server->timeout_queue, 0, silc_server_channel_key_rekey, - (void *)channel->rekey, 3600, 0, + (void *)channel->rekey, 30, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL); } @@ -2987,7 +3008,7 @@ SilcChannelEntry silc_server_save_channel_key(SilcServer server, silc_server_channel_key_rekey); silc_task_register(server->timeout_queue, 0, silc_server_channel_key_rekey, - (void *)channel->rekey, 3600, 0, + (void *)channel->rekey, 30, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL); } diff --git a/lib/silcclient/client.c b/lib/silcclient/client.c index b0498639..bf7e71f7 100644 --- a/lib/silcclient/client.c +++ b/lib/silcclient/client.c @@ -557,7 +557,7 @@ SILC_TASK_CALLBACK(silc_client_connect_to_server_final) conn->remote_id_data_len = SILC_ID_SERVER_LEN; /* Register re-key timeout */ - conn->rekey->timeout = 60; /* XXX hardcoded */ + conn->rekey->timeout = 30; /* XXX hardcoded */ conn->rekey->context = (void *)client; silc_task_register(client->timeout_queue, conn->sock->sock, silc_client_rekey_callback, @@ -636,7 +636,7 @@ SILC_TASK_CALLBACK_GLOBAL(silc_client_packet_process) silc_buffer_push(sock->outbuf, sock->outbuf->data - sock->outbuf->head); - ret = silc_client_packet_send_real(client, sock, TRUE, TRUE); + ret = silc_client_packet_send_real(client, sock, TRUE, FALSE); /* If returned -2 could not write to connection now, will do it later. */ @@ -776,13 +776,22 @@ void silc_client_packet_parse(SilcPacketParserContext *parser_context) SilcClient client = (SilcClient)parser_context->context; /* Parse the packet */ - silc_task_register(client->timeout_queue, parser_context->sock->sock, - silc_client_packet_parse_real, - (void *)parser_context, 0, 1, - SILC_TASK_TIMEOUT, - SILC_TASK_PRI_NORMAL); + + /* If REKEY protocol is active we must proccess the packets synchronously + since we must assure that incoming packets that are encrypted with + the old key is processed before the new keys is set to use. */ + if (SILC_CLIENT_IS_REKEY(parser_context->sock)) + silc_client_packet_parse_real(client->timeout_queue, SILC_TASK_READ, + (void *)parser_context, + parser_context->sock->sock); + else + silc_task_register(client->timeout_queue, parser_context->sock->sock, + silc_client_packet_parse_real, + (void *)parser_context, 0, 1, + SILC_TASK_TIMEOUT, + SILC_TASK_PRI_NORMAL); } - + /* Parses the packet type and calls what ever routines the packet type requires. This is done for all incoming packets. */ @@ -1029,10 +1038,15 @@ void silc_client_packet_parse_type(SilcClient client, silc_packet_context_free(proto_ctx->packet); proto_ctx->packet = silc_packet_context_dup(packet); - + /* Let the protocol handle the packet */ - sock->protocol->execute(client->timeout_queue, 0, - sock->protocol, sock->sock, 0, 100000); + if (proto_ctx->responder == FALSE) + sock->protocol->execute(client->timeout_queue, 0, + sock->protocol, sock->sock, 0, 0); + else + /* Let the protocol handle the packet */ + sock->protocol->execute(client->timeout_queue, 0, + sock->protocol, sock->sock, 0, 100000); } else { SILC_LOG_ERROR(("Received Re-key done packet but no re-key " "protocol active, packet dropped.")); @@ -1133,6 +1147,103 @@ void silc_client_packet_send(SilcClient client, silc_client_packet_send_real(client, sock, force_send, FALSE); } +void silc_client_packet_send_flush(SilcClient client, + SilcSocketConnection sock, + SilcPacketType type, + void *dst_id, + SilcIdType dst_id_type, + SilcCipher cipher, + SilcHmac hmac, + unsigned char *data, + uint32 data_len) +{ + SilcPacketContext packetdata; + + /* First flush the packet queue. */ + + if (sock->outbuf->data - sock->outbuf->head) + silc_buffer_push(sock->outbuf, + sock->outbuf->data - sock->outbuf->head); + + silc_client_packet_send_real(client, sock, TRUE, TRUE); + + /* The packet has been sent and now it is time to set the connection + back to only for input. When there is again some outgoing data + available for this connection it will be set for output as well. + This call clears the output setting and sets it only for input. */ + SILC_CLIENT_SET_CONNECTION_FOR_INPUT(sock->sock); + SILC_UNSET_OUTBUF_PENDING(sock); + silc_buffer_clear(sock->outbuf); + + SILC_LOG_DEBUG(("Sending packet, type %d", type)); + + /* Get data used in the packet sending, keys and stuff */ + if ((!cipher || !hmac || !dst_id) && sock->user_data) { + if (!cipher && ((SilcClientConnection)sock->user_data)->send_key) + cipher = ((SilcClientConnection)sock->user_data)->send_key; + + if (!hmac && ((SilcClientConnection)sock->user_data)->hmac) + hmac = ((SilcClientConnection)sock->user_data)->hmac; + + if (!dst_id && ((SilcClientConnection)sock->user_data)->remote_id) { + dst_id = ((SilcClientConnection)sock->user_data)->remote_id; + dst_id_type = SILC_ID_SERVER; + } + } + + /* Set the packet context pointers */ + packetdata.flags = 0; + packetdata.type = type; + if (sock->user_data && + ((SilcClientConnection)sock->user_data)->local_id_data) + packetdata.src_id = ((SilcClientConnection)sock->user_data)->local_id_data; + else + packetdata.src_id = silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char)); + packetdata.src_id_len = SILC_ID_CLIENT_LEN; + packetdata.src_id_type = SILC_ID_CLIENT; + if (dst_id) { + packetdata.dst_id = silc_id_id2str(dst_id, dst_id_type); + packetdata.dst_id_len = silc_id_get_len(dst_id_type); + packetdata.dst_id_type = dst_id_type; + } else { + packetdata.dst_id = NULL; + packetdata.dst_id_len = 0; + packetdata.dst_id_type = SILC_ID_NONE; + } + packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN + + packetdata.src_id_len + packetdata.dst_id_len; + packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen); + + /* Prepare outgoing data buffer for packet sending */ + silc_packet_send_prepare(sock, + SILC_PACKET_HEADER_LEN + + packetdata.src_id_len + + packetdata.dst_id_len, + packetdata.padlen, + data_len); + + SILC_LOG_DEBUG(("Putting data to outgoing buffer, len %d", data_len)); + + packetdata.buffer = sock->outbuf; + + /* Put the data to the buffer */ + if (data && data_len) + silc_buffer_put(sock->outbuf, data, data_len); + + /* Create the outgoing packet */ + silc_packet_assemble(&packetdata); + + /* Encrypt the packet */ + if (cipher) + silc_packet_encrypt(cipher, hmac, sock->outbuf, sock->outbuf->len); + + SILC_LOG_HEXDUMP(("Packet, len %d", sock->outbuf->len), + sock->outbuf->data, sock->outbuf->len); + + /* Now actually send the packet */ + silc_client_packet_send_real(client, sock, TRUE, TRUE); +} + /* Closes connection to remote end. Free's all allocated data except for some information such as nickname etc. that are valid at all time. If the `sock' is NULL then the conn->sock will be used. If `sock' is diff --git a/lib/silcclient/client.h b/lib/silcclient/client.h index 4730a65a..d9e856f5 100644 --- a/lib/silcclient/client.h +++ b/lib/silcclient/client.h @@ -294,4 +294,14 @@ void silc_client_notify_by_server(SilcClient client, void silc_client_private_message(SilcClient client, SilcSocketConnection sock, SilcPacketContext *packet); + +void silc_client_packet_send_flush(SilcClient client, + SilcSocketConnection sock, + SilcPacketType type, + void *dst_id, + SilcIdType dst_id_type, + SilcCipher cipher, + SilcHmac hmac, + unsigned char *data, + uint32 data_len); #endif diff --git a/lib/silcclient/protocol.c b/lib/silcclient/protocol.c index 801a5b95..a6ced2c0 100644 --- a/lib/silcclient/protocol.c +++ b/lib/silcclient/protocol.c @@ -741,8 +741,8 @@ silc_client_protocol_rekey_send_packet(SilcSKE ske, SilcClient client = (SilcClient)ctx->client; /* Send the packet immediately */ - silc_client_packet_send(client, ctx->sock, type, NULL, 0, NULL, NULL, - packet->data, packet->len, FALSE); + silc_client_packet_send_flush(client, ctx->sock, type, NULL, 0, NULL, NULL, + packet->data, packet->len); } /* Performs re-key as defined in the SILC protocol specification. */ @@ -815,9 +815,9 @@ SILC_TASK_CALLBACK(silc_client_protocol_rekey) */ /* Send the REKEY_DONE to indicate we will take new keys into use */ - silc_client_packet_send(client, ctx->sock, - SILC_PACKET_REKEY_DONE, - NULL, 0, NULL, NULL, NULL, 0, FALSE); + silc_client_packet_send_flush(client, ctx->sock, + SILC_PACKET_REKEY_DONE, + NULL, 0, NULL, NULL, NULL, 0); /* The protocol ends in next stage. */ protocol->state = SILC_PROTOCOL_STATE_END; @@ -829,8 +829,8 @@ SILC_TASK_CALLBACK(silc_client_protocol_rekey) */ /* Start the re-key by sending the REKEY packet */ - silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY, - NULL, 0, NULL, NULL, NULL, 0, FALSE); + silc_client_packet_send_flush(client, ctx->sock, SILC_PACKET_REKEY, + NULL, 0, NULL, NULL, NULL, 0); if (ctx->pfs == TRUE) { /* @@ -867,9 +867,9 @@ SILC_TASK_CALLBACK(silc_client_protocol_rekey) /* Send the REKEY_DONE to indicate we will take new keys into use now. */ - silc_client_packet_send(client, ctx->sock, - SILC_PACKET_REKEY_DONE, - NULL, 0, NULL, NULL, NULL, 0, FALSE); + silc_client_packet_send_flush(client, ctx->sock, + SILC_PACKET_REKEY_DONE, + NULL, 0, NULL, NULL, NULL, 0); /* The protocol ends in next stage. */ protocol->state = SILC_PROTOCOL_STATE_END; @@ -932,8 +932,8 @@ SILC_TASK_CALLBACK(silc_client_protocol_rekey) /* Send the REKEY_DONE to indicate we will take new keys into use now. */ - silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY_DONE, - NULL, 0, NULL, NULL, NULL, 0, FALSE); + silc_client_packet_send_flush(client, ctx->sock, SILC_PACKET_REKEY_DONE, + NULL, 0, NULL, NULL, NULL, 0); /* The protocol ends in next stage. */ protocol->state = SILC_PROTOCOL_STATE_END; diff --git a/lib/silccore/silcpacket.c b/lib/silccore/silcpacket.c index 80be09c4..1708226e 100644 --- a/lib/silccore/silcpacket.c +++ b/lib/silccore/silcpacket.c @@ -479,6 +479,7 @@ static int silc_packet_check_mac(SilcHmac hmac, SilcBuffer buffer) /* Compare the HMAC's (buffer->tail has the packet's HMAC) */ if (memcmp(mac, buffer->tail, mac_len)) { SILC_LOG_ERROR(("MAC failed")); + assert(FALSE); return FALSE; }