#ifndef SESSION_H #define SESSION_H #include #include #include #include #include #include "director.h" #include "session_common.h" // don't want this here! #include "dispatchers.h" #define MAX_BUFFER 256 /* The Session: */ class Session : public std::enable_shared_from_this { public: Session(boost::asio::ip::tcp::socket socket, boost::asio::io_service &io_service, std::string hostname, std::string port, bool server_telnet_); ~Session(); void start(void); const std::string &get_prompt(void); void set_prompt(const std::string &prompt); void to_client(const std::string &message, bool log = true); void to_server(const std::string &message, const std::string &source); void to_server(const std::string &message); /* DispatchSettings save_settings(void); void restore_settings(const DispatchSettings &ss); */ // The session line parsing needs show_client // these move to Director // bool show_client = true; bool talk_direct = true; bool server_telnet; void post(notifyFunc nf); private: Director director; void on_server_line(const std::string &line, const std::string &raw_line); void on_server_prompt(const std::string &prompt, const std::string &raw_prompt); void parse_auth(void); void on_connect(const boost::system::error_code error); void server_read(void); void on_resolve(const boost::system::error_code error, const boost::asio::ip::tcp::resolver::results_type results); void client_read(void); void client_input(const std::string &input); void on_shutdown(boost::system::error_code ec); void split_lines(std::string line); void process_lines(std::string &received); private: /* Move to director -? StringFunc SL_parser; void SL_cimline(const std::string &line); void SL_thiefline(const std::string &line); void SL_sectorline(const std::string &line); void SL_portline(const std::string &line); void SL_warpline(const std::string &line); */ void set_prompt_timer(void); void reset_prompt_timer(void); void on_prompt_timeout(const boost::system::error_code error); void stayin_alive(const boost::system::error_code error); void start_keepin_alive(void); int time_ms; int keepalive_secs; // Move this to director. This controls if the "keep alive" fires or not. bool active = false; /* Move to director. MainDispatch main; void proxy_activate(void); void proxy_deactivate(void); // std::stack director; bool active = false; */ /** * The client's socket */ boost::asio::ip::tcp::socket socket_; boost::asio::io_service &io_service_; boost::asio::ip::tcp::resolver resolver_; /** * The server's socket */ boost::asio::ip::tcp::socket server_; /** * The time that we'll use to fire off the "prompt" event. * * The idea being that we'd receive chars, processing lines. * And if we have something in server_prompt start the timer. * If we receive more, process lines, if !server_prompt.empty() * reset the timer. * * If the timer fires (and isn't aborted), fire off the prompt. * * I'm not so sure about this -- because this adds delay to the * proxy. [It might be better to just fire off "some" text, and * have it ignored, rather then adding a delay.] Or, this might * not matter at all, I'm thinking milliseconds here! */ boost::asio::high_resolution_timer prompt_timer_; /** * Keep connection alive, don't timeout. * * This gets set by to_server config[keepalive], and sends a * space ' ' if we haven't sent anything to the server in that * many seconds. */ boost::asio::high_resolution_timer keep_alive_; /** * What characters have been received from the server, * that weren't \n terminated? * * This needs to be reset/cleared if there's a \r (carriage return). */ std::string server_prompt; /** * The client read buffer. * * This is too big, we don't get that many characters from the client. * */ char read_buffer[MAX_BUFFER]; /** * The server read buffer. */ char server_buffer[MAX_BUFFER]; /** * The rlogin information received from the client. * * We check this, and if it isn't valid, we spoof some rlogin * connection. */ std::string rlogin_auth; /** * The username passed in via rlogin. We need this so we know what * name we need to store the data under. */ std::string rlogin_name; std::string host; std::string port; char game = 0; /** * Are we connected to the server? * * Don't shutdown the server socket if we aren't connected. */ bool connected = false; }; /* maybe move the resolver part to the server, so I don't need io_service? I'm not sure what the socket connection part is going to need just yet, so I probably won't move that just yet. [NNY!] */ class Server { public: Server(boost::asio::io_service &io_service, const boost::asio::ip::tcp::endpoint &endpoint, const std::string &host, const std::string &port, bool server_telnet_); ~Server(); private: void do_accept(void); void on_signal(const boost::system::error_code &ec, int signal); bool server_telnet; boost::asio::io_service &io_service_; boost::asio::ip::tcp::acceptor acceptor_; boost::asio::signal_set signal_; bool keep_accepting; /** * The host to connect to (from config) */ std::string host_; /** * The port to connect to (from config) * */ std::string port_; }; #endif