ircproxy The Ultimate Cyborg |
#include <ClientSession.h>
This class represents a client session: from that a client successfully connects to the application's listen socket, until the connection is closed or lost again.
Definition at line 45 of file ClientSession.h.
Public Types | |
typedef std::map< std::string, boost::shared_ptr< Target > , IRC_less > | private_targets_type |
The type of the map with the private targets that the client has joined. | |
typedef target_hold_map_type | joined_channels_type |
The type of M_joined_channels. | |
Public Member Functions | |
ClientSession (void) | |
Default constructor. | |
~ClientSession () | |
Destructor. | |
void | fatal_error (char const *error_msg) |
A fatal error occured. Calling this function will terminate the ClientSession. | |
void | new_client_nick_received (std::string const &nick) |
Called from Identity::new_client_message_received for NICK messages. | |
std::string const & | client_in_nick (void) const |
Returns the last NICK as received from the client in this session. | |
std::string const & | client_out_nick (void) const |
FIXME. | |
void | process_message (ClientMessageIn const &msg) |
Decode message msg. | |
void | queue_message (ClientMessageIn const &msg) |
Queue message msg. | |
void | start_queuing_messages (void) |
Start queuing messages. | |
void | stop_queuing_messages (DestructEventType const &) |
Stop queuing messages. | |
void | add_private_target (boost::shared_ptr< Target > const &target) |
Add target to the private targets list. | |
void | del_private_target (std::string const &target_name) |
Remove target_name from the private targets list. | |
private_targets_type & | private_targets (void) |
Return reference to map with private targets. | |
private_targets_type const & | private_targets (void) const |
Return const reference to map with private targets. | |
joined_channels_type & | joined_channels (void) |
Return reference to map with known channels. | |
joined_channels_type const & | joined_channels (void) const |
Return const reference to map with known channels. | |
void | create_private_target (std::string const &target_name, Network &network) |
Check if target already exists, if not, create it and add it to our private targets map. | |
void | queue_msg (MessageOut const &msgout) |
Send an output message to this session. | |
void | queue_msg_as_is (ServerMessageIn const &msg) |
Pass message msg on to the client with default priority, without changing anything. | |
void | queue_msg_me_as_is (ServerMessageIn const &msg) |
Pass message msg on to the client with default priority, changing only the target: my nick. | |
void | serversession_lost (void) |
This function is called from ServerSession::session_lost(). | |
boost::shared_ptr< Nick > | get_nick (std::string const &nick_name, bool create=false) |
Get or create a Nick for nick_name. | |
Public Attributes | |
UserAnswerEventServer | user_answer_event_server |
The UserAnswer event server. | |
DestructEventServer | destruct_event_server |
The DestructEvent event server. | |
Protected Member Functions | |
virtual void | new_message_received (ClientMessageIn const &) |
Incoming event from ClientSessionInput. | |
Private Attributes | |
std::string | M_in_nick |
The last NICK as received from the client in this session. | |
bool | M_queue_messages |
Set if messages need to be queued instead of processed. | |
std::deque< ClientMessageIn > | M_msg_queue |
The message queue. | |
bool | M_first_nick |
Set before the first NICK message is received from the client. | |
private_targets_type | M_private_targets |
Map with private targets that the client has joined. | |
joined_channels_type | M_joined_channels |
Clientside lookup map for channels joined by this identity. |
typedef std::map<std::string, boost::shared_ptr<Target>, IRC_less> ClientSession::private_targets_type |
The type of the map with the private targets that the client has joined.
Definition at line 49 of file ClientSession.h.
ClientSession::ClientSession | ( | void | ) | [inline] |
Default constructor.
Definition at line 67 of file ClientSession.h.
References debug::channels::dc::objects.
00067 : event_client_ct(), M_queue_messages(false), M_first_nick(true) 00068 { Dout(dc::objects, "Constructing ClientSession() " << *this); }
ClientSession::~ClientSession | ( | ) |
Destructor.
Definition at line 182 of file ClientSession.cc.
References destruct_event_server, IdentityReference::has_identity(), IdentityReference::identity(), debug::channels::dc::objects, Identity::reset_client_session(), and user_answer_event_server.
00183 { 00184 Dout(dc::objects, "Destructing ClientSession " << *this); 00185 if (has_identity()) 00186 identity().reset_client_session(this); 00187 // First erase pending UserAnswer requests. 00188 user_answer_event_server.destroy_requests(); 00189 // Then trigger the destruct event. 00190 destruct_event_server.trigger(DestructEventType()); 00191 // Finally cancel all other event requests for this object. 00192 cancel_all_requests(); 00193 }
void ClientSession::fatal_error | ( | char const * | error_msg | ) |
A fatal error occured. Calling this function will terminate the ClientSession.
Definition at line 172 of file ClientSession.cc.
References DoutEntering.
Referenced by new_message_received(), and process_message().
00173 { 00174 DoutEntering(dc::debug, "ClientSession::fatal_error(\"" << error_msg << "\")"); 00175 if (!must_be_removed()) // Only write one error at a time. 00176 *this << "ERROR :" << error_msg << "\r\n"; 00177 // The next method sets 'must_be_removed()' to true, 00178 // flushes the error and deletes this object (non-blocking). 00179 del(); 00180 }
void ClientSession::new_client_nick_received | ( | std::string const & | nick | ) |
Called from Identity::new_client_message_received for NICK messages.
Definition at line 247 of file ClientSession.cc.
References Identity::authentication(), default_priority(), IdentityReference::identity(), M_first_nick, M_in_nick, Identity::mynick(), ServerSession::queue_msg(), Authentication::received_nick(), ServerSession::send_nick_write_event(), and Identity::server_session().
Referenced by Identity::new_client_message_received().
00248 { 00249 M_in_nick = nick; 00250 if (!M_first_nick) 00251 { 00252 // Client tries to change nick name. 00253 PseudoMessageOut pseudo_msg(default_priority(keys::NICK)); 00254 pseudo_msg.writeEventRequest(identity().server_session(), &ServerSession::send_nick_write_event, M_in_nick); 00255 identity().server_session().queue_msg(pseudo_msg); 00256 } 00257 else 00258 { 00259 identity().mynick()->set_in_nick(*this, M_in_nick); // Initialize out client-side nick name. 00260 identity().authentication().received_nick(); 00261 } 00262 M_first_nick = false; 00263 }
std::string const& ClientSession::client_in_nick | ( | void | ) | const [inline] |
Returns the last NICK as received from the client in this session.
Definition at line 80 of file ClientSession.h.
References M_in_nick.
Referenced by QuestionTarget::new_client_message_received().
00080 { return M_in_nick; }
std::string const& ClientSession::client_out_nick | ( | void | ) | const [inline] |
FIXME.
Definition at line 83 of file ClientSession.h.
References M_in_nick.
Referenced by QuestionTarget::create_channel_and_ask_question(), PrivateTarget::do_names_output(), PrivateTarget::handle_command(), PrivateTarget::new_client_message_received(), ServerSession::new_message_received(), and Identity::notice_target().
00083 { return M_in_nick; }
void ClientSession::process_message | ( | ClientMessageIn const & | msg | ) |
Decode message msg.
Definition at line 121 of file ClientSession.cc.
References edragon::caught(), DoutEntering, fatal_error(), IdentityReference::identity(), Identity::new_client_message_received(), and FatalError::what().
Referenced by new_message_received(), and stop_queuing_messages().
00122 { 00123 DoutEntering(dc::debug, "ClientSession::process_message(" << msg << ")"); 00124 try 00125 { 00126 identity().new_client_message_received(msg); 00127 } 00128 catch (FatalError& error) 00129 { 00130 Debug(edragon::caught(error)); 00131 fatal_error(error.what()); 00132 return; 00133 } 00134 }
void ClientSession::queue_message | ( | ClientMessageIn const & | msg | ) |
Queue message msg.
Definition at line 151 of file ClientSession.cc.
References DoutEntering, and M_msg_queue.
Referenced by new_message_received().
00152 { 00153 DoutEntering(dc::debug, "ClientSession::queue_message(" << msg << ")"); 00154 M_msg_queue.push_front(msg); 00155 }
void ClientSession::start_queuing_messages | ( | void | ) |
Start queuing messages.
Definition at line 136 of file ClientSession.cc.
References M_queue_messages.
Referenced by new_message_received().
00137 { 00138 M_queue_messages = true; 00139 }
void ClientSession::stop_queuing_messages | ( | DestructEventType const & | ) |
Stop queuing messages.
Definition at line 141 of file ClientSession.cc.
References M_msg_queue, M_queue_messages, and process_message().
Referenced by new_message_received().
00142 { 00143 while (!M_msg_queue.empty()) 00144 { 00145 process_message(M_msg_queue.back()); 00146 M_msg_queue.pop_back(); 00147 } 00148 M_queue_messages = false; 00149 }
void ClientSession::add_private_target | ( | boost::shared_ptr< Target > const & | target | ) |
Add target to the private targets list.
Definition at line 196 of file ClientSession.cc.
References ASSERT, and M_private_targets.
Referenced by Identity::notice_target().
00197 { 00198 #if defined(DEBUG) || defined(CWDEBUG) 00199 std::pair<private_targets_type::iterator, bool> result = 00200 #endif 00201 M_private_targets.insert(private_targets_type::value_type(target->in_name(*this), target)); 00202 ASSERT(result.second); 00203 }
void ClientSession::del_private_target | ( | std::string const & | target_name | ) |
Remove target_name from the private targets list.
Definition at line 206 of file ClientSession.cc.
References ASSERT, and M_private_targets.
Referenced by ServerConnection::do_connect(), and PrivateTarget::new_client_message_received().
00207 { 00208 private_targets_type::iterator iter = M_private_targets.find(target_name); 00209 ASSERT(iter != M_private_targets.end()); 00210 M_private_targets.erase(iter); 00211 }
private_targets_type& ClientSession::private_targets | ( | void | ) | [inline] |
Return reference to map with private targets.
Definition at line 101 of file ClientSession.h.
References M_private_targets.
Referenced by Target::clientside_get_channel(), get_nick(), Identity::new_client_message_received(), and Identity::notice_target().
00101 { return M_private_targets; }
private_targets_type const& ClientSession::private_targets | ( | void | ) | const [inline] |
Return const reference to map with private targets.
Definition at line 104 of file ClientSession.h.
References M_private_targets.
00104 { return M_private_targets; }
joined_channels_type& ClientSession::joined_channels | ( | void | ) | [inline] |
Return reference to map with known channels.
Definition at line 107 of file ClientSession.h.
References M_joined_channels.
Referenced by Target::add_channel(), Target::clientside_get_channel(), Channel::new_client_message_received(), ServerSession::send_rejoins(), serversession_lost(), Target::sub_channel(), and Identity::~Identity().
00107 { return M_joined_channels; }
joined_channels_type const& ClientSession::joined_channels | ( | void | ) | const [inline] |
Return const reference to map with known channels.
Definition at line 110 of file ClientSession.h.
References M_joined_channels.
00110 { return M_joined_channels; }
void ClientSession::create_private_target | ( | std::string const & | target_name, | |
Network & | network | |||
) |
Check if target already exists, if not, create it and add it to our private targets map.
Create a new target target_name and add it to the private targets map, unless it already exists.
Definition at line 214 of file ClientSession.cc.
References ASSERT, DoutEntering, IdentityReference::identity(), is_channel(), is_nick(), Network::is_private(), and M_private_targets.
Referenced by QuestionTarget::create_channel_and_ask_question().
00215 { 00216 DoutEntering(dc::debug, "ClientSession::create_private_target(\"" << target_name << "\", " << network << ')'); 00217 ASSERT(network.is_private()); 00218 private_targets_type::iterator iter = M_private_targets.find(target_name); 00219 if (iter == M_private_targets.end()) 00220 { 00221 Dout(dc::debug, "Not found. Creating new private target."); 00222 if (is_channel(target_name)) 00223 { 00224 boost::shared_ptr<Target> new_target(NEW(Channel(identity(), target_name, network, 0))); 00225 M_private_targets.insert(private_targets_type::value_type(target_name, new_target)); 00226 } 00227 else 00228 { 00229 ASSERT(is_nick(target_name)); 00230 boost::shared_ptr<Target> new_target(NEW(Nick(*this, target_name, network))); 00231 M_private_targets.insert(private_targets_type::value_type(target_name, new_target)); 00232 } 00233 } 00234 #ifdef CWDEBUG 00235 else 00236 Dout(dc::debug, "Found: " << *iter); 00237 #endif 00238 }
void ClientSession::queue_msg | ( | MessageOut const & | msgout | ) |
Send an output message to this session.
Definition at line 240 of file ClientSession.cc.
References DoutEntering, and MessageOut::write_to().
Referenced by Identity::new_client_message_received(), ServerSession::new_message_received(), Identity::new_server_message_received(), Channel::new_server_message_received(), queue_msg_as_is(), and queue_msg_me_as_is().
00241 { 00242 DoutEntering(dc::debug, "ClientSession::queue_msg(" << msgout << ")"); 00243 // No need to queue anything (yet?), just send it to the client. 00244 msgout.write_to(*this); 00245 }
void ClientSession::queue_msg_as_is | ( | ServerMessageIn const & | msg | ) |
Pass message msg on to the client with default priority, without changing anything.
Definition at line 157 of file ClientSession.cc.
References default_priority(), MessageIn::key(), MessageIn::params(), and queue_msg().
00158 { 00159 Prefix prefix(msg); 00160 MessageOut msgout(default_priority(msg.key())); 00161 queue_msg(msgout << prefix << msg.key() << msg.params(0)); 00162 }
void ClientSession::queue_msg_me_as_is | ( | ServerMessageIn const & | msg | ) |
Pass message msg on to the client with default priority, changing only the target: my nick.
Definition at line 164 of file ClientSession.cc.
References ASSERT, default_priority(), IdentityReference::identity(), MessageIn::key(), Identity::mynick(), MessageIn::param(), MessageIn::params(), queue_msg(), and ServerMessageIn::server_session().
Referenced by ServerSession::new_message_received().
00165 { 00166 ASSERT(msg.param(0) == identity().mynick()->in_name(msg.server_session())); 00167 Prefix prefix(msg); 00168 MessageOut msgout(default_priority(msg.key())); 00169 queue_msg(msgout << prefix << msg.key() << identity().mynick() << msg.params(1)); 00170 }
void ClientSession::serversession_lost | ( | void | ) |
This function is called from ServerSession::session_lost().
Definition at line 265 of file ClientSession.cc.
References Identity::do_quit(), IdentityReference::identity(), and joined_channels().
Referenced by ServerConnection::session_lost().
00266 { 00267 // Run over all channels that we're on. 00268 for (joined_channels_type::iterator channel_iter = joined_channels().begin(); channel_iter != joined_channels().end(); ++channel_iter) 00269 { 00270 boost::shared_ptr<Channel> const& channel(boost::static_pointer_cast<Channel>(channel_iter->second)); 00271 // Run over all members. 00272 for (Channel::members_type::iterator member_iter = channel->members().begin(); member_iter != channel->members().end();) 00273 { 00274 // QUIT all members except myself. 00275 boost::shared_ptr<Nick> const& nick((member_iter++)->second.get_nick()); 00276 if (!nick->is_me()) 00277 identity().do_quit(nick, "ircproxy lost connection"); 00278 } 00279 } 00280 }
boost::shared_ptr< Nick > ClientSession::get_nick | ( | std::string const & | nick_name, | |
bool | create = false | |||
) |
Get or create a Nick for nick_name.
Definition at line 282 of file ClientSession.cc.
References ASSERT, is_nick(), private_targets(), and THROW_EXCEPTION.
Referenced by Identity::new_client_message_received().
00283 { 00284 ASSERT(is_nick(nick_name)); 00285 00286 // First search in the map with private targets. 00287 private_targets_type::const_iterator priv_iter = private_targets().find(nick_name); 00288 if (priv_iter != private_targets().end()) 00289 return boost::static_pointer_cast<Nick>(priv_iter->second); 00290 00291 // FIXME 00292 00293 THROW_EXCEPTION(unknown_target(), "There is no client side nick \"" << nick_name << "\" on ClientSession " << *this); 00294 }
void ClientSession::new_message_received | ( | ClientMessageIn const & | msg | ) | [protected, virtual] |
Incoming event from ClientSessionInput.
Definition at line 37 of file ClientSession.cc.
References destruct_event_server, DoutEntering, fatal_error(), IdentityReference::has_identity(), IdentityReference::identity(), MessageIn::key(), M_queue_messages, MessageIn::param(), process_message(), queue_message(), Identity::set_client_session(), Identity::set_hostname(), IdentityReference::set_identity(), start_queuing_messages(), and stop_queuing_messages().
00038 { 00039 #ifdef CWDEBUG 00040 // Suppress all debug output related to PING messages. 00041 bool suppress_debug_output = 00042 (msg.key() == keys::PING && Application::instance().suppress_ping()) || 00043 (msg.key() == keys::WHO && Application::instance().suppress_who()); 00044 Debug(if (suppress_debug_output) libcw_do.off()); 00045 #endif 00046 00047 DoutEntering(dc::debug, "ClientSession::new_message_received(" << msg << ")"); 00048 if (must_be_removed()) 00049 { 00050 Dout(dc::debug, "Do nothing, ClientSession is marked for removal."); 00051 // Turn debug output on again, if it was suppressed. 00052 Debug(if (suppress_debug_output) libcw_do.on()); 00053 // Skip message. 00054 return; 00055 } 00056 if (!has_identity()) 00057 { 00058 if (msg.key() != keys::PASS) 00059 { 00060 // Turn debug output on again, if it was suppressed. 00061 Debug(if (suppress_debug_output) libcw_do.on()); 00062 Dout(dc::notice, "Received non-PASS message from client without Identity (" << msg << ')'); 00063 // Error. The first message from a client must ALWAYS be a PASS. 00064 fatal_error("Send PASS first."); 00065 return; 00066 } 00067 Dout(dc::debug, "Received PASS: " << msg); 00068 std::string password(msg.param(0)); 00069 if (password.empty()) 00070 { 00071 fatal_error("Empty password."); 00072 return; 00073 } 00074 else 00075 { 00076 // Find or create Identity. 00077 identities_type::iterator iter = Application::instance().identities().find(password); 00078 if (iter == Application::instance().identities().end()) 00079 { 00080 // Create new Identity. 00081 Identity identity(password); 00082 set_identity(&Application::instance().identities(). 00083 insert(std::pair<std::string, Identity>(password, identity)).first->second); 00084 Dout(dc::debug, "Created a new Identity."); 00085 } 00086 else 00087 { 00088 set_identity(&iter->second); 00089 // If the identity already has another ClientSession, kill that. 00090 if (identity().has_client_session()) 00091 { 00092 ClientSession& old_client_session(identity().client_session()); 00093 std::ostringstream error_msg; 00094 error_msg << "Received new client connection from " << old_client_session.remote_ip(); 00095 old_client_session.fatal_error(error_msg.str().c_str()); 00096 // Wait till the old session is actually destructed before processing 00097 // messages from this connection. 00098 start_queuing_messages(); 00099 // Request stop_queuing_messages to be called when old_client_session is destructed. 00100 old_client_session.destruct_event_server(*this, &ClientSession::stop_queuing_messages); 00101 } 00102 } 00103 identity().set_client_session(this); 00104 if (identity().hostname() != unknown_hostname) 00105 { 00106 std::ostringstream buf; 00107 buf << remote_ip(); 00108 identity().set_hostname(buf.str()); 00109 } 00110 } 00111 } 00112 if (!M_queue_messages) 00113 process_message(msg); 00114 else 00115 queue_message(msg); 00116 00117 // Turn debug output on again, if it was suppressed. 00118 Debug(if (suppress_debug_output) libcw_do.on()); 00119 }
std::string ClientSession::M_in_nick [private] |
The last NICK as received from the client in this session.
Definition at line 54 of file ClientSession.h.
Referenced by client_in_nick(), client_out_nick(), and new_client_nick_received().
bool ClientSession::M_queue_messages [private] |
Set if messages need to be queued instead of processed.
Definition at line 55 of file ClientSession.h.
Referenced by new_message_received(), start_queuing_messages(), and stop_queuing_messages().
std::deque<ClientMessageIn> ClientSession::M_msg_queue [private] |
The message queue.
Definition at line 56 of file ClientSession.h.
Referenced by queue_message(), and stop_queuing_messages().
bool ClientSession::M_first_nick [private] |
Set before the first NICK message is received from the client.
Definition at line 57 of file ClientSession.h.
Referenced by new_client_nick_received().
Map with private targets that the client has joined.
Definition at line 58 of file ClientSession.h.
Referenced by add_private_target(), create_private_target(), del_private_target(), and private_targets().
Clientside lookup map for channels joined by this identity.
Definition at line 59 of file ClientSession.h.
Referenced by joined_channels().
The UserAnswer event server.
Definition at line 62 of file ClientSession.h.
Referenced by ServerConnection::connect(), ServerSession::found_network_name(), QuestionTarget::new_client_message_received(), Identity::received_network_domain_answer(), and ~ClientSession().
The DestructEvent event server.
Definition at line 63 of file ClientSession.h.
Referenced by new_message_received(), and ~ClientSession().
Copyright © 2005-2007 Carlo Wood. All rights reserved. |
---|