Fix double free in silcd.
[silc.git] / apps / silcd / server_util.c
index 14a1a240c9bfa62fbdeabf70dfbf66500ce332b0..74ce18ba2902866107148517f3f961fe645dd714 100644 (file)
@@ -228,6 +228,8 @@ SilcBool silc_server_remove_clients_by_server(SilcServer server,
        client->mode = 0;
        client->router = NULL;
        client->connection = NULL;
+       client->data.created = silc_time();
+       silc_dlist_del(server->expired_clients, client);
        silc_dlist_add(server->expired_clients, client);
       } else {
        silc_idlist_del_data(client);
@@ -289,6 +291,8 @@ SilcBool silc_server_remove_clients_by_server(SilcServer server,
        client->mode = 0;
        client->router = NULL;
        client->connection = NULL;
+       client->data.created = silc_time();
+       silc_dlist_del(server->expired_clients, client);
        silc_dlist_add(server->expired_clients, client);
       } else {
        silc_idlist_del_data(client);
@@ -1543,8 +1547,17 @@ void silc_server_kill_client(SilcServer server,
   if (remote_client->connection) {
     /* Remove locally conneted client */
     SilcPacketStream sock = remote_client->connection;
+
+    if (sock)
+      silc_packet_stream_ref(sock);
+
     silc_server_free_sock_user_data(server, sock, NULL);
-    silc_server_close_connection(server, sock);
+
+    if (sock) {
+      silc_packet_set_context(sock, NULL);
+      silc_server_close_connection(server, sock);
+      silc_packet_stream_unref(sock);
+    }
   } else {
     /* Update statistics */
     server->stat.clients--;
@@ -1566,6 +1579,7 @@ void silc_server_kill_client(SilcServer server,
     }
 
     /* Remove remote client */
+    silc_dlist_del(server->expired_clients, remote_client);
     silc_idlist_del_data(remote_client);
     if (!silc_idlist_del_client(server->global_list, remote_client)) {
       /* Remove this client from watcher list if it is */