// Execute state machine as long as we have events static void server_client_execute (server_t *self, client_t *client, int event) { client->next_event = event; while (client->next_event) { client->event = client->next_event; client->next_event = 0; switch (client->state) { case start_state: if (client->event == ohai_event) { try_anonymous_access (self, client); client->state = checking_client_state; } else if (client->event == heartbeat_event) { } else if (client->event == expired_event) { terminate_the_client (self, client); } else { // Process all other events fmq_msg_set_id (client->reply, FMQ_MSG_RTFM); fmq_msg_send (&client->reply, client->router); client->reply = fmq_msg_new (0); fmq_msg_set_address (client->reply, client->address); terminate_the_client (self, client); } break; case checking_client_state: if (client->event == friend_event) { fmq_msg_set_id (client->reply, FMQ_MSG_OHAI_OK); fmq_msg_send (&client->reply, client->router); client->reply = fmq_msg_new (0); fmq_msg_set_address (client->reply, client->address); client->state = ready_state; } else if (client->event == foe_event) { fmq_msg_set_id (client->reply, FMQ_MSG_SRSLY); fmq_msg_send (&client->reply, client->router); client->reply = fmq_msg_new (0); fmq_msg_set_address (client->reply, client->address); terminate_the_client (self, client); } else if (client->event == maybe_event) { list_security_mechanisms (self, client); fmq_msg_set_id (client->reply, FMQ_MSG_ORLY); fmq_msg_send (&client->reply, client->router); client->reply = fmq_msg_new (0); fmq_msg_set_address (client->reply, client->address); client->state = challenging_client_state; } else if (client->event == heartbeat_event) { } else if (client->event == expired_event) { terminate_the_client (self, client); } else if (client->event == ohai_event) { try_anonymous_access (self, client); client->state = checking_client_state; } else { // Process all other events fmq_msg_set_id (client->reply, FMQ_MSG_RTFM); fmq_msg_send (&client->reply, client->router); client->reply = fmq_msg_new (0); fmq_msg_set_address (client->reply, client->address); terminate_the_client (self, client); } break; case challenging_client_state: if (client->event == yarly_event) { try_security_mechanism (self, client); client->state = checking_client_state; } else if (client->event == heartbeat_event) { } else if (client->event == expired_event) { terminate_the_client (self, client); } else if (client->event == ohai_event) { try_anonymous_access (self, client); client->state = checking_client_state; } else { // Process all other events fmq_msg_set_id (client->reply, FMQ_MSG_RTFM); fmq_msg_send (&client->reply, client->router); client->reply = fmq_msg_new (0); fmq_msg_set_address (client->reply, client->address); terminate_the_client (self, client); } break; case ready_state: if (client->event == icanhaz_event) { store_client_subscription (self, client); fmq_msg_set_id (client->reply, FMQ_MSG_ICANHAZ_OK); fmq_msg_send (&client->reply, client->router); client->reply = fmq_msg_new (0); fmq_msg_set_address (client->reply, client->address); } else if (client->event == nom_event) { store_client_credit (self, client); get_next_patch_for_client (self, client); client->state = dispatching_state; } else if (client->event == hugz_event) { fmq_msg_set_id (client->reply, FMQ_MSG_HUGZ_OK); fmq_msg_send (&client->reply, client->router); client->reply = fmq_msg_new (0); fmq_msg_set_address (client->reply, client->address); } else if (client->event == kthxbai_event) { terminate_the_client (self, client); } else if (client->event == dispatch_event) { get_next_patch_for_client (self, client); client->state = dispatching_state; } else if (client->event == heartbeat_event) { fmq_msg_set_id (client->reply, FMQ_MSG_HUGZ); fmq_msg_send (&client->reply, client->router); client->reply = fmq_msg_new (0); fmq_msg_set_address (client->reply, client->address); } else if (client->event == expired_event) { terminate_the_client (self, client); } else if (client->event == ohai_event) { try_anonymous_access (self, client); client->state = checking_client_state; } else { // Process all other events fmq_msg_set_id (client->reply, FMQ_MSG_RTFM); fmq_msg_send (&client->reply, client->router); client->reply = fmq_msg_new (0); fmq_msg_set_address (client->reply, client->address); terminate_the_client (self, client); } break; case dispatching_state: if (client->event == send_chunk_event) { fmq_msg_set_id (client->reply, FMQ_MSG_CHEEZBURGER); fmq_msg_send (&client->reply, client->router); client->reply = fmq_msg_new (0); fmq_msg_set_address (client->reply, client->address); get_next_patch_for_client (self, client); } else if (client->event == send_delete_event) { fmq_msg_set_id (client->reply, FMQ_MSG_CHEEZBURGER); fmq_msg_send (&client->reply, client->router); client->reply = fmq_msg_new (0); fmq_msg_set_address (client->reply, client->address); get_next_patch_for_client (self, client); } else if (client->event == next_patch_event) { get_next_patch_for_client (self, client); } else if (client->event == no_credit_event) { client->state = ready_state; } else if (client->event == finished_event) { client->state = ready_state; } else if (client->event == heartbeat_event) { } else if (client->event == expired_event) { terminate_the_client (self, client); } else if (client->event == ohai_event) { try_anonymous_access (self, client); client->state = checking_client_state; } else { // Process all other events fmq_msg_set_id (client->reply, FMQ_MSG_RTFM); fmq_msg_send (&client->reply, client->router); client->reply = fmq_msg_new (0); fmq_msg_set_address (client->reply, client->address); terminate_the_client (self, client); } break; } if (client->next_event == terminate_event) { // Automatically calls client_destroy zhash_delete (self->clients, client->hashkey); break; } } }
static void client_execute (client_t *self, int event) { self->next_event = event; while (self->next_event) { self->event = self->next_event; self->next_event = 0; switch (self->state) { case start_state: if (self->event == ready_event) { fmq_msg_id_set (self->request, FMQ_MSG_OHAI); fmq_msg_send (&self->request, self->dealer); self->request = fmq_msg_new (0); self->state = requesting_access_state; } else if (self->event == srsly_event) { log_access_denied (self); terminate_the_client (self); self->state = start_state; } else if (self->event == rtfm_event) { log_invalid_message (self); terminate_the_client (self); } else { log_protocol_error (self); terminate_the_client (self); } break; case requesting_access_state: if (self->event == orly_event) { try_security_mechanism (self); fmq_msg_id_set (self->request, FMQ_MSG_YARLY); fmq_msg_send (&self->request, self->dealer); self->request = fmq_msg_new (0); self->state = requesting_access_state; } else if (self->event == ohai_ok_event) { connected_to_server (self); get_first_subscription (self); self->state = subscribing_state; } else if (self->event == srsly_event) { log_access_denied (self); terminate_the_client (self); self->state = start_state; } else if (self->event == rtfm_event) { log_invalid_message (self); terminate_the_client (self); } else { log_protocol_error (self); terminate_the_client (self); } break; case subscribing_state: if (self->event == ok_event) { fmq_msg_id_set (self->request, FMQ_MSG_ICANHAZ); fmq_msg_send (&self->request, self->dealer); self->request = fmq_msg_new (0); get_next_subscription (self); self->state = subscribing_state; } else if (self->event == finished_event) { refill_credit_as_needed (self); self->state = ready_state; } else if (self->event == srsly_event) { log_access_denied (self); terminate_the_client (self); self->state = start_state; } else if (self->event == rtfm_event) { log_invalid_message (self); terminate_the_client (self); } else { log_protocol_error (self); terminate_the_client (self); } break; case ready_state: if (self->event == cheezburger_event) { process_the_patch (self); refill_credit_as_needed (self); } else if (self->event == hugz_event) { fmq_msg_id_set (self->request, FMQ_MSG_HUGZ_OK); fmq_msg_send (&self->request, self->dealer); self->request = fmq_msg_new (0); } else if (self->event == subscribe_event) { fmq_msg_id_set (self->request, FMQ_MSG_ICANHAZ); fmq_msg_send (&self->request, self->dealer); self->request = fmq_msg_new (0); } else if (self->event == send_credit_event) { fmq_msg_id_set (self->request, FMQ_MSG_NOM); fmq_msg_send (&self->request, self->dealer); self->request = fmq_msg_new (0); } else if (self->event == icanhaz_ok_event) { } else if (self->event == srsly_event) { log_access_denied (self); terminate_the_client (self); self->state = start_state; } else if (self->event == rtfm_event) { log_invalid_message (self); terminate_the_client (self); } else { log_protocol_error (self); terminate_the_client (self); } break; } if (self->next_event == terminate_event) { self->stopped = true; break; } } }