updates.
[silc.git] / apps / silcd / server.c
index 4265845e253f94c5d8e27e77e958aca050e5a23c..f3d00f16cf7d48dbf1d9777a529cf11331b9cbff 100644 (file)
@@ -2098,30 +2098,32 @@ SILC_TASK_CALLBACK(silc_server_close_connection_final)
 void silc_server_close_connection(SilcServer server,
                                  SilcSocketConnection sock)
 {
+  /* We won't listen for this connection anymore */
+  silc_schedule_unset_listen_fd(server->schedule, sock->sock);
+
+  /* Unregister all tasks */
+  silc_schedule_task_del_by_fd(server->schedule, sock->sock);
+  silc_schedule_task_del_by_fd(server->schedule, sock->sock);
+
+  /* Close the actual connection */
+  silc_net_close_connection(sock->sock);
+  server->sockets[sock->sock] = NULL;
+
   /* If sock->user_data is NULL then we'll check for active protocols
      here since the silc_server_free_sock_user_data has not been called
      for this connection. */
   if (!sock->user_data) {
-    /* If any protocol is active cancel its execution */
+    /* If any protocol is active cancel its execution. It will call
+       the final callback which will finalize the disconnection. */
     if (sock->protocol) {
       silc_protocol_cancel(sock->protocol, server->schedule);
       sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
       silc_protocol_execute_final(sock->protocol, server->schedule);
       sock->protocol = NULL;
+      return;
     }
   }
 
-  /* We won't listen for this connection anymore */
-  silc_schedule_unset_listen_fd(server->schedule, sock->sock);
-
-  /* Unregister all tasks */
-  silc_schedule_task_del_by_fd(server->schedule, sock->sock);
-  silc_schedule_task_del_by_fd(server->schedule, sock->sock);
-
-  /* Close the actual connection */
-  silc_net_close_connection(sock->sock);
-  server->sockets[sock->sock] = NULL;
-
   silc_schedule_task_add(server->schedule, 0, 
                     silc_server_close_connection_final,
                     (void *)sock, 0, 1, SILC_TASK_TIMEOUT,