X-Git-Url: http://git.silcnet.org/gitweb/?p=runtime.git;a=blobdiff_plain;f=apps%2Fsilcd%2Fserver.c;h=7453f5f5d1bcb8c832aefaebf41b5d6da0ddb1d2;hp=fd57d9d410cb2773f1b346222169454b220e7998;hb=da798b47cf2734868609f6563b73386335fa1f76;hpb=5d34c3610c4c8f45f4f40859bc09b9239dc5427d diff --git a/apps/silcd/server.c b/apps/silcd/server.c index fd57d9d4..7453f5f5 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 1997 - 2007 Pekka Riikonen + Copyright (C) 1997 - 2008 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 @@ -269,6 +269,9 @@ static void silc_server_packet_error(SilcPacketEngine engine, SILC_CONNTYPE_STRING(idata->conn_type), silc_packet_error_string(error))); + if (!silc_packet_stream_is_valid(stream)) + return; + silc_schedule_task_add_timeout(server->schedule, silc_server_packet_error_timeout, stream, 0, 0); @@ -1354,6 +1357,7 @@ silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success, SILC_STATUS_ERR_AUTH_FAILED, NULL); if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); + silc_server_free_sock_user_data(server, sconn->sock, NULL); silc_server_connection_free(sconn); return; } @@ -1380,6 +1384,7 @@ silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success, SILC_STATUS_ERR_RESOURCE_LIMIT, NULL); if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); + silc_server_free_sock_user_data(server, sconn->sock, NULL); silc_server_connection_free(sconn); silc_free(entry); return; @@ -1410,6 +1415,7 @@ silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success, SILC_STATUS_ERR_RESOURCE_LIMIT, NULL); if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); + silc_server_free_sock_user_data(server, sconn->sock, NULL); silc_server_connection_free(sconn); silc_free(entry); return; @@ -1449,6 +1455,7 @@ silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success, SILC_STATUS_ERR_RESOURCE_LIMIT, NULL); if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); + silc_server_free_sock_user_data(server, sconn->sock, NULL); silc_server_connection_free(sconn); silc_free(entry); return; @@ -1532,6 +1539,7 @@ silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success, SILC_STATUS_ERR_AUTH_FAILED, NULL); if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); + silc_server_free_sock_user_data(server, sconn->sock, NULL); silc_server_connection_free(sconn); silc_free(entry); return; @@ -1599,6 +1607,7 @@ static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status, SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL); if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); + silc_server_free_sock_user_data(server, sconn->sock, NULL); silc_server_connection_free(sconn); return; } @@ -1617,6 +1626,7 @@ static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status, SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL); if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); + silc_server_free_sock_user_data(server, sconn->sock, NULL); silc_server_connection_free(sconn); return; } @@ -1636,6 +1646,7 @@ static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status, SILC_STATUS_ERR_RESOURCE_LIMIT, NULL); if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); + silc_server_free_sock_user_data(server, sconn->sock, NULL); silc_server_connection_free(sconn); return; } @@ -2144,6 +2155,7 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, server->stat.auth_failures++; silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL); + silc_server_free_sock_user_data(server, sock, NULL); goto out; } @@ -2182,6 +2194,7 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, SILC_STATUS_ERR_PERM_DENIED, "We do not have connection to backup " "router established, try later"); + silc_server_free_sock_user_data(server, sock, NULL); server->stat.auth_failures++; /* From here on, wait 20 seconds for the backup router to appear. */ @@ -2206,6 +2219,7 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, server->stat.auth_failures++; silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_AUTH_FAILED, NULL); + silc_server_free_sock_user_data(server, sock, NULL); goto out; } entry->data.status |= SILC_IDLIST_STATUS_LOCAL; @@ -2272,6 +2286,7 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, SILC_STATUS_ERR_PERM_DENIED, "We do not have connection to primary " "router established, try later"); + silc_server_free_sock_user_data(server, sock, NULL); server->stat.auth_failures++; goto out; } @@ -2359,6 +2374,7 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, SILC_STATUS_ERR_PERM_DENIED, "We do not have connection to backup " "router established, try later"); + silc_server_free_sock_user_data(server, sock, NULL); server->stat.auth_failures++; /* From here on, wait 20 seconds for the backup router to appear. */ @@ -2399,6 +2415,7 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, SILC_LOG_ERROR(("Could not add new server to cache")); silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_AUTH_FAILED, NULL); + silc_server_free_sock_user_data(server, sock, NULL); server->stat.auth_failures++; goto out; } @@ -2522,6 +2539,7 @@ silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status, silc_ske_free(ske); silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL); + silc_server_free_sock_user_data(server, sock, NULL); return; } @@ -2534,6 +2552,7 @@ silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status, silc_ske_free(ske); silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL); + silc_server_free_sock_user_data(server, sock, NULL); return; } silc_packet_set_keys(sock, send_key, receive_key, hmac_send, @@ -2556,6 +2575,7 @@ silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status, silc_ske_free(ske); silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_RESOURCE_LIMIT, NULL); + silc_server_free_sock_user_data(server, sock, NULL); return; } @@ -2634,6 +2654,7 @@ static void silc_server_accept_new_connection(SilcNetStatus status, silc_server_disconnect_remote(server, packet_stream, SILC_STATUS_ERR_BANNED_FROM_SERVER, deny->reason); + silc_server_free_sock_user_data(server, packet_stream, NULL); return; } @@ -2652,6 +2673,7 @@ static void silc_server_accept_new_connection(SilcNetStatus status, server->stat.conn_failures++; silc_server_disconnect_remote(server, packet_stream, SILC_STATUS_ERR_BANNED_FROM_SERVER, NULL); + silc_server_free_sock_user_data(server, packet_stream, NULL); return; } @@ -2661,6 +2683,7 @@ static void silc_server_accept_new_connection(SilcNetStatus status, server->stat.conn_failures++; silc_server_disconnect_remote(server, packet_stream, SILC_STATUS_ERR_RESOURCE_LIMIT, NULL); + silc_server_free_sock_user_data(server, packet_stream, NULL); return; } entry->hostname = hostname; @@ -2696,6 +2719,7 @@ static void silc_server_accept_new_connection(SilcNetStatus status, server->stat.conn_failures++; silc_server_disconnect_remote(server, packet_stream, SILC_STATUS_ERR_RESOURCE_LIMIT, NULL); + silc_server_free_sock_user_data(server, packet_stream, NULL); return; } silc_ske_set_callbacks(ske, silc_server_verify_key, @@ -2845,7 +2869,7 @@ static void silc_server_rekey(SilcServer server, SilcPacketStream sock, SILC_TASK_CALLBACK(silc_server_close_connection_final) { - silc_packet_stream_destroy(context); + silc_packet_stream_unref(context); } /* Closes connection to socket connection */ @@ -2858,6 +2882,9 @@ void silc_server_close_connection(SilcServer server, const char *hostname; SilcUInt16 port; + if (!silc_packet_stream_is_valid(sock)) + return; + memset(tmp, 0, sizeof(tmp)); // silc_socket_get_error(sock, tmp, sizeof(tmp)); silc_socket_stream_get_info(silc_packet_stream_get_stream(sock), @@ -2873,6 +2900,11 @@ void silc_server_close_connection(SilcServer server, idata->sconn = NULL; } + /* Take a reference and then destroy the stream. The last reference + is released later in a timeout callback. */ + silc_packet_stream_ref(sock); + silc_packet_stream_destroy(sock); + /* Close connection with timeout */ server->stat.conn_num--; silc_schedule_task_del_by_all(server->schedule, 0, @@ -2964,8 +2996,10 @@ void silc_server_free_client_data(SilcServer server, SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR); silc_schedule_task_del_by_context(server->schedule, client); - if (client->data.sconn) + if (client->data.sconn) { silc_server_connection_free(client->data.sconn); + client->data.sconn = NULL; + } /* We will not delete the client entry right away. We will take it into history (for WHOWAS command) for 5 minutes, unless we're @@ -3002,7 +3036,7 @@ void silc_server_free_sock_user_data(SilcServer server, if (!idata) return; - silc_schedule_task_del_by_context(server->schedule, sock); + // silc_schedule_task_del_by_context(server->schedule, sock); /* Cancel active protocols */ if (idata) { @@ -4124,6 +4158,7 @@ void silc_server_announce_get_inviteban(SilcServer server, { SilcBuffer list, idp, idp2, tmp2; SilcUInt32 type; + void *ptype; SilcHashTableList htl; const unsigned char a[1] = { 0x03 }; @@ -4135,9 +4170,10 @@ void silc_server_announce_get_inviteban(SilcServer server, type = silc_hash_table_count(channel->invite_list); SILC_PUT16_MSB(type, list->data); silc_hash_table_list(channel->invite_list, &htl); - while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) - list = silc_argument_payload_encode_one(list, tmp2->data, silc_buffer_len(tmp2), - type); + while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) + list = silc_argument_payload_encode_one(list, tmp2->data, + silc_buffer_len(tmp2), + SILC_PTR_TO_32(ptype)); silc_hash_table_list_reset(&htl); idp2 = silc_id_payload_encode(server->id, SILC_ID_SERVER); @@ -4159,9 +4195,10 @@ void silc_server_announce_get_inviteban(SilcServer server, type = silc_hash_table_count(channel->ban_list); SILC_PUT16_MSB(type, list->data); silc_hash_table_list(channel->ban_list, &htl); - while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) - list = silc_argument_payload_encode_one(list, tmp2->data, silc_buffer_len(tmp2), - type); + while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) + list = silc_argument_payload_encode_one(list, tmp2->data, + silc_buffer_len(tmp2), + SILC_PTR_TO_32(ptype)); silc_hash_table_list_reset(&htl); *ban =