--- /dev/null
+/*
+
+ server_st_packet.c
+
+ Author: Pekka Riikonen <priikone@silcnet.org>
+
+ Copyright (C) 1997 - 2005 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
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+*/
+
+#include "silc.h"
+#include "silcserver.h"
+#include "server_internal.h"
+
+/************************** Types and definitions ***************************/
+
+
+/************************ Static utility functions **************************/
+
+
+/***************************** Packet received ******************************/
+
+SILC_FSM_STATE(silc_server_st_packet_disconnect)
+{
+ SilcPacket packet = fsm_context;
+ SilcEntryData data = silc_packet_get_context(packet->stream);
+
+ return SILC_FSM_FINISH;
+}
+
+SILC_FSM_STATE(silc_server_st_packet_channel_message)
+{
+#if 0
+ /*
+ * Received channel message. Channel messages are special packets
+ * (although probably most common ones) thus they are handled
+ * specially.
+ */
+ if (packet->flags & SILC_PACKET_FLAG_LIST)
+ break;
+ idata->last_receive = time(NULL);
+ silc_server_channel_message(server, sock, packet);
+#endif
+
+ return SILC_FSM_FINISH;
+}
+
+SILC_FSM_STATE(silc_server_st_packet_channel_key)
+{
+#if 0
+ /*
+ * Received key for channel. As channels are created by the router
+ * the keys are as well. We will distribute the key to all of our
+ * locally connected clients on the particular channel. Router
+ * never receives this channel and thus is ignored.
+ */
+ if (packet->flags & SILC_PACKET_FLAG_LIST)
+ break;
+ silc_server_channel_key(server, sock, packet);
+#endif
+
+ return SILC_FSM_FINISH;
+}
+
+SILC_FSM_STATE(silc_server_st_packet_private_message)
+{
+#if 0
+ /*
+ * Received private message packet. The packet is coming from either
+ * client or server.
+ */
+ if (packet->flags & SILC_PACKET_FLAG_LIST)
+ break;
+ idata->last_receive = time(NULL);
+ silc_server_private_message(server, sock, packet);
+#endif
+
+ return SILC_FSM_FINISH;
+}
+
+SILC_FSM_STATE(silc_server_st_packet_private_message_key)
+{
+#if 0
+ /*
+ * Private message key packet.
+ */
+ if (packet->flags & SILC_PACKET_FLAG_LIST)
+ break;
+ silc_server_private_message_key(server, sock, packet);
+#endif
+
+ return SILC_FSM_FINISH;
+}
+
+SILC_FSM_STATE(silc_server_st_packet_new_id)
+{
+#if 0
+ /*
+ * Received New ID packet. This includes some new ID that has been
+ * created. It may be for client, server or channel. This is the way
+ * to distribute information about new registered entities in the
+ * SILC network.
+ */
+ if (packet->flags & SILC_PACKET_FLAG_LIST)
+ silc_server_new_id_list(server, sock, packet);
+ else
+ silc_server_new_id(server, sock, packet);
+#endif
+
+ return SILC_FSM_FINISH;
+}
+
+SILC_FSM_STATE(silc_server_st_packet_new_channel)
+{
+#if 0
+ /*
+ * Received new channel packet. Information about new channel in the
+ * network are distributed using this packet.
+ */
+ if (packet->flags & SILC_PACKET_FLAG_LIST)
+ silc_server_new_channel_list(server, sock, packet);
+ else
+ silc_server_new_channel(server, sock, packet);
+#endif
+
+ return SILC_FSM_FINISH;
+}
+
+SILC_FSM_STATE(silc_server_st_packet_key_agreement)
+{
+#if 0
+ if (packet->flags & SILC_PACKET_FLAG_LIST)
+ break;
+ silc_server_key_agreement(server, sock, packet);
+#endif
+
+ return SILC_FSM_FINISH;
+}
+
+SILC_FSM_STATE(silc_server_st_packet_ftp)
+{
+#if 0
+ /* FTP packet */
+ if (packet->flags & SILC_PACKET_FLAG_LIST)
+ break;
+ silc_server_ftp(server, sock, packet);
+#endif
+
+ return SILC_FSM_FINISH;
+}
+
+SILC_FSM_STATE(silc_server_st_packet_resume_router)
+{
+#if 0
+ /* Resume router packet received. This packet is received for backup
+ router resuming protocol. */
+ if (packet->flags & SILC_PACKET_FLAG_LIST)
+ break;
+ silc_server_backup_resume_router(server, sock, packet);
+#endif
+
+ return SILC_FSM_FINISH;
+}
+
+SILC_FSM_STATE(silc_server_st_packet_received)
+{
+ SilcServerThread thread = fsm_context;
+ SilcPacket packet = state_context;
+
+ SILC_LOG_DEBUG(("Received %s packet [flags %d]",
+ silc_get_packet_name(packet->type), packet->flags));
+
+ /* Parse the packet type */
+ switch (packet->type) {
+ case SILC_PACKET_CHANNEL_MESSAGE:
+ /** Packet CHANNEL_MESSAGE */
+ if (packet->flags & SILC_PACKET_FLAG_LIST)
+ break;
+ silc_fsm_next(fsm, silc_server_st_packet_channel_message);
+ return SILC_FSM_CONTINUE;
+ break;
+
+ case SILC_PACKET_PRIVATE_MESSAGE:
+ /** Packet PRIVATE_MESSAGE */
+ if (packet->flags & SILC_PACKET_FLAG_LIST)
+ break;
+ silc_fsm_next(fsm, silc_server_st_packet_private_message);
+ return SILC_FSM_CONTINUE;
+ break;
+
+ case SILC_PACKET_NOTIFY:
+ /** Packet NOTIFY */
+ silc_fsm_next(fsm, silc_server_st_packet_notify);
+ return SILC_FSM_CONTINUE;
+ break;
+
+ case SILC_PACKET_COMMAND:
+ /** Packet COMMAND */
+ if (packet->flags & SILC_PACKET_FLAG_LIST)
+ break;
+ silc_fsm_next(fsm, silc_server_st_packet_command);
+ return SILC_FSM_CONTINUE;
+ break;
+
+ case SILC_PACKET_COMMAND_REPLY:
+ /** Packet COMMAND_REPLY */
+ if (packet->flags & SILC_PACKET_FLAG_LIST)
+ break;
+ silc_fsm_next(fsm, silc_server_st_packet_command_reply);
+ return SILC_FSM_CONTINUE;
+ break;
+
+ case SILC_PACKET_CHANNEL_KEY:
+ /** Packet CHANNEL_KEY */
+ if (packet->flags & SILC_PACKET_FLAG_LIST)
+ break;
+ silc_fsm_next(fsm, silc_server_st_packet_channel_key);
+ return SILC_FSM_CONTINUE;
+ break;
+
+ case SILC_PACKET_NEW_ID:
+ /** Packet NEW_ID */
+ silc_fsm_next(fsm, silc_server_st_packet_new_id);
+ return SILC_FSM_CONTINUE;
+ break;
+
+ case SILC_PACKET_NEW_CLIENT:
+ /** Packet NEW_CLIENT */
+ if (packet->flags & SILC_PACKET_FLAG_LIST)
+ break;
+ silc_fsm_next(fsm, silc_server_st_packet_new_client);
+ return SILC_FSM_CONTINUE;
+ break;
+
+ case SILC_PACKET_NEW_SERVER:
+ /** Packet NEW_SERVER */
+ if (packet->flags & SILC_PACKET_FLAG_LIST)
+ break;
+ silc_fsm_next(fsm, silc_server_st_packet_new_server);
+ return SILC_FSM_CONTINUE;
+ break;
+
+ case SILC_PACKET_NEW_CHANNEL:
+ /** Packet NEW_CHANNEL */
+ silc_fsm_next(fsm, silc_server_st_packet_new_channel);
+ return SILC_FSM_CONTINUE;
+ break;
+
+ case SILC_PACKET_KEY_AGREEMENT:
+ /** Packet KEY_AGREEMENT */
+ if (packet->flags & SILC_PACKET_FLAG_LIST)
+ break;
+ silc_fsm_next(fsm, silc_server_st_packet_key_agreement);
+ return SILC_FSM_CONTINUE;
+ break;
+
+ case SILC_PACKET_FTP:
+ /** Packet FTP */
+ if (packet->flags & SILC_PACKET_FLAG_LIST)
+ break;
+ silc_fsm_next(fsm, silc_server_st_packet_ftp);
+ return SILC_FSM_CONTINUE;
+ break;
+
+ case SILC_PACKET_RESUME_CLIENT:
+ /** Packet RESUME_CLIENT */
+ if (packet->flags & SILC_PACKET_FLAG_LIST)
+ break;
+ silc_fsm_next(fsm, silc_server_st_packet_resume_client);
+ return SILC_FSM_CONTINUE;
+ break;
+
+ case SILC_PACKET_RESUME_ROUTER:
+ /** Packet RESUME_ROUTER */
+ if (packet->flags & SILC_PACKET_FLAG_LIST)
+ break;
+ silc_fsm_next(fsm, silc_server_st_packet_resume_router);
+ return SILC_FSM_CONTINUE;
+ break;
+
+ case SILC_PACKET_DISCONNECT:
+ /** Packet DISCONNECT */
+ if (packet->flags & SILC_PACKET_FLAG_LIST)
+ break;
+ silc_fsm_next(fsm, silc_server_st_packet_disconnect);
+ return SILC_FSM_CONTINUE;
+ break;
+
+ case SILC_PACKET_PRIVATE_MESSAGE_KEY:
+ /** Packet PRIVATE_MESSAGE */
+ if (packet->flags & SILC_PACKET_FLAG_LIST)
+ break;
+ silc_fsm_next(fsm, silc_server_st_packet_private_message_key);
+ return SILC_FSM_CONTINUE;
+ break;
+
+ case SILC_PACKET_CONNECTION_AUTH_REQUEST:
+ /** Packet CONNECTION_AUTH_REQUEST */
+ if (packet->flags & SILC_PACKET_FLAG_LIST)
+ break;
+ silc_fsm_next(fsm, silc_server_st_packet_connection_auth_request);
+ return SILC_FSM_CONTINUE;
+ break;
+
+ case SILC_PACKET_HEARTBEAT:
+ case SILC_PACKET_SUCCESS:
+ case SILC_PACKET_FAILURE:
+ case SILC_PACKET_REJECT:
+ case SILC_PACKET_KEY_EXCHANGE:
+ case SILC_PACKET_KEY_EXCHANGE_1:
+ case SILC_PACKET_KEY_EXCHANGE_2:
+ case SILC_PACKET_REKEY:
+ case SILC_PACKET_REKEY_DONE:
+ case SILC_PACKET_CONNECTION_AUTH:
+ case SILC_PACKET_CONNECTION_AUTH_REQUEST:
+ /* Not handled */
+ break;
+
+ default:
+ SILC_LOG_ERROR(("Unsupported packet type %d", packet->type));
+ break;
+ }
+
+ silc_packet_free(packet);
+ return SILC_FSM_FINISH;
+}
+
+/* Received NEW_CLIENT packet, used to register client to SILC network. */
+
+SILC_FSM_STATE(silc_server_st_packet_new_client)
+{
+ SilcServerThread thread = fsm_context;
+ SilcPacket packet = state_context;
+ SilcServerAccept ac = silc_packet_get_context(packet->stream);
+
+ if (!ac || ac->register_packet) {
+ silc_packet_free(packet);
+ return SILC_FSM_FINISH;
+ }
+
+ /* Signal that client registers to network */
+ ac->register_packet = packet;
+ SILC_FSM_SEMA_POST(&ac->wait_register);
+
+ return SILC_FSM_FINISH;
+}
+
+/* Received NEW_SERVER packet, used to register server to SILC network. */
+
+SILC_FSM_STATE(silc_server_st_packet_new_server)
+{
+ SilcServerThread thread = fsm_context;
+ SilcPacket packet = state_context;
+ SilcServerAccept ac = silc_packet_get_context(packet->stream);
+
+ if (!ac || ac->register_packet) {
+ silc_packet_free(packet);
+ return SILC_FSM_FINISH;
+ }
+
+ /* Signal that server registers to network */
+ ac->register_packet = packet;
+ SILC_FSM_SEMA_POST(&ac->wait_register);
+
+ return SILC_FSM_FINISH;
+}
+
+/* Received RESUME_CLIENT packet, used to resume detached session. */
+
+SILC_FSM_STATE(silc_server_st_packet_resume_client)
+{
+ SilcServerThread thread = fsm_context;
+ SilcPacket packet = state_context;
+ SilcServerAccept ac = silc_packet_get_context(packet->stream);
+
+ if (!ac || ac->register_packet) {
+ silc_packet_free(packet);
+ return SILC_FSM_FINISH;
+ }
+
+ /* Signal that client resumes session */
+ ac->register_packet = packet;
+ SILC_FSM_SEMA_POST(&ac->wait_register);
+
+ return SILC_FSM_FINISH;
+}