/* server_st_packet.c Author: Pekka Riikonen Copyright (C) 1997 - 2006 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_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_EVENT_SIGNAL(&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_EVENT_SIGNAL(&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_EVENT_SIGNAL(&ac->wait_register); return SILC_FSM_FINISH; }