ircproxy The Ultimate Cyborg |
#include <ServerSession.h>
This class represents a server session: from that we successfully connect to a server until the connection is closed or lost again.
Definition at line 47 of file ServerSession.h.
Public Types | |
typedef target_hold_map_type | joined_channels_type |
The type of M_joined_channels. | |
typedef std::map< std::string, boost::shared_ptr< Channel > > | join_pipeline_type |
The type of M_join_pipeline. | |
Public Member Functions | |
ServerSession (Identity &identity, ServerConnection &server_connection) | |
Construct a ServerSession instance for identity identity and server connection server_connection. | |
~ServerSession () | |
Destructor. | |
void | start_authentication (void) |
Called from ServerConnection::do_connect. Takes care of sending PASS/NICK/USER/PONG/MODE. | |
void | set_auth_ping_argument (std::string const &auth_ping_argument) |
Called from ServerConnection::decode_ping with the argument of the first PING. | |
std::string const & | auth_ping_argument (void) const |
Return argument of the first PING. | |
void | construct_network_object (std::string const &network_name, std::string const &domain) |
Create a new network object with name network_name and domain domain (if any). | |
void | detected_network (networks_type::iterator network_iter) |
Initialize network. This function is called as soon as the network we are connected to is known. | |
void | authentication_successful (void) |
Called when the authentication was successful (when receiving the 001 numeric). | |
void | fatal_error (char const *error_msg) |
A fatal error occured. Calling this function will terminate the ServerSession. | |
void | found_network_name (void) |
Called when the name of the Network is known (after numeric 005). | |
MatcherEventServer & | message_event_server (void) |
Return a reference to the event server for incoming messages. | |
MatcherEventServer const & | message_event_server (void) const |
Return a const reference to the event server for incoming messages. | |
NickPair & | nicks (void) |
Server session nick pair. | |
NickPair const & | nicks (void) const |
Server session nick pair. | |
joined_channels_type & | joined_channels (void) |
Return reference to map with joined channels. | |
joined_channels_type const & | joined_channels (void) const |
Return const reference to map with joined channels. | |
UserMode & | user_mode (void) |
Return my user mode. | |
UserMode const & | user_mode (void) const |
Return my user mode. | |
void | queue_msg (MessageOut const &msg) |
Queue message msg. | |
void | queue_msg_as_is (ClientMessageIn const &msg) |
Queue message msg with default priority without changing it. | |
WhoRequest | current_who_request (void) |
Return the first element of M_who_queue. | |
void | pop_who_request (void) |
Pop the first element of M_who_queue. | |
void | send_nick_write_event (PseudoMessageEventType const &, std::string nick) |
A write event of a pseudo NICK message happened. Actually write the NICK message. | |
void | send_who_write_event (PseudoMessageEventType const &event_type, WhoRequest who_request) |
A write event of a pseudo WHO message happened. Actually write the WHO message. | |
void | force_quit (timer_event_type_ct const &) |
Called 1 second after sending a QUIT and the connection still wasn't terminated. | |
ISupport const & | i_support (void) const |
Accessor for M_i_support. | |
ISupport & | i_support (void) |
Accessor for M_i_support. | |
boost::shared_ptr< Channel > | join_pipeline (std::string const &channel_name) |
Return a pointer to the channel in the pipeline, if any. Channel is removed from pipeline. | |
void | set_disconnect_reason (std::string const &disconnect_reason) |
Set the disconnect reason to disconnect_reason. | |
ServerConnection & | server_connection (void) const |
Accessor for underlying server connection object. | |
boost::shared_ptr< Nick > | get_nick (std::string const &nick_name, bool create=false) |
Get or create a Nick for nick_name. | |
Public Attributes | |
Bool | M_detected_network |
True if the network is fully detected. | |
Protected Member Functions | |
virtual void | new_message_received (ServerMessageIn const &) |
Incoming event from ServerSessionInput. | |
virtual void | network_connection_terminated (void) |
A read(2) on the socket returned 0. | |
Private Member Functions | |
void | send_rejoins (void) |
Send a JOIN to the server for every channel we are on. | |
Private Attributes | |
ServerConnection & | M_server_connection |
The owning object. | |
MatcherEventServer | M_message_event_server |
Event server for incoming messages. | |
NickPair | M_server_session_nicks |
Server side nick pair. | |
joined_channels_type | M_joined_channels |
Serverside lookup map for channels joined by this identity. | |
UserMode | M_user_mode |
My user mode. | |
boost::shared_ptr< AuthState > | M_auth_state |
Pointer object with temporary authentication state information. | |
Queue | M_output_queue |
Queue for output messages. | |
std::queue< WhoRequest > | M_who_queue |
Queue storing WHO request messages. | |
ISupport | M_i_support |
Object that stores the numeric 005 information. | |
std::string | M_network_name |
Temporary storage of the network name as decoded from numeric 001, until numeric 005 is received. | |
std::string | M_umodes |
The user modes as received in numeric 004. | |
join_pipeline_type | M_join_pipeline |
Channels for which we sent a JOIN as part of a reconnect. | |
std::string | M_disconnect_reason |
An error message that should be sent to the client if the connection is lost, if any. | |
Static Private Attributes | |
static int | S_server_sessions = 0 |
Total number of server session objects. |
typedef std::map<std::string, boost::shared_ptr<Channel> > ServerSession::join_pipeline_type |
ServerSession::ServerSession | ( | Identity & | identity, | |
ServerConnection & | server_connection | |||
) | [inline] |
Construct a ServerSession instance for identity identity and server connection server_connection.
Definition at line 73 of file ServerSession.h.
References debug::channels::dc::objects, and S_server_sessions.
00073 : 00074 IdentityReference(&identity), M_server_connection(server_connection), 00075 M_server_session_nicks(*this), M_output_queue(server_connection, 0.5, 5, 5), 00076 M_i_support(server_connection) 00077 #ifdef CWDEBUG 00078 , M_detected_network("M_detected_network") 00079 #endif 00080 { 00081 Dout(dc::objects, "Constructing ServerSession(" << identity << ", " << server_connection << ")"); 00082 ++S_server_sessions; 00083 } //! Destructor.
ServerSession::~ServerSession | ( | ) |
Destructor.
Definition at line 334 of file ServerSession.cc.
References M_server_connection, debug::channels::dc::objects, ServerConnection::reconnect(), S_server_sessions, ServerConnection::secondary_connection(), and ServerConnection::session_lost().
00335 { 00336 #ifdef CWDEBUG 00337 debug::SecondaryConnection dummy(M_server_connection.secondary_connection()); 00338 #endif 00339 Dout(dc::objects, "Destructing ServerSession" << *this); 00340 M_server_connection.session_lost(); 00341 cancel_all_requests(); 00342 // Notify the application when the last server session is terminated. 00343 if (--S_server_sessions == 0 && !M_server_connection.reconnect()) 00344 Application::instance().last_server_session_destroyed(); 00345 }
void ServerSession::start_authentication | ( | void | ) |
Called from ServerConnection::do_connect. Takes care of sending PASS/NICK/USER/PONG/MODE.
Definition at line 322 of file ServerSession.cc.
References M_auth_state, and M_server_connection.
Referenced by ServerConnection::do_connect().
00323 { 00324 M_auth_state.reset(NEW(AuthState(M_server_connection))); 00325 }
void ServerSession::set_auth_ping_argument | ( | std::string const & | auth_ping_argument | ) | [inline] |
Called from ServerConnection::decode_ping with the argument of the first PING.
Definition at line 91 of file ServerSession.h.
References M_auth_state.
Referenced by ServerConnection::decode_ping().
00091 { if (M_auth_state.get()) M_auth_state->set_auth_ping_argument(auth_ping_argument); }
std::string const& ServerSession::auth_ping_argument | ( | void | ) | const [inline] |
Return argument of the first PING.
Definition at line 94 of file ServerSession.h.
References ASSERT, and M_auth_state.
Referenced by ServerConnection::send_pong_and_mode().
00094 { ASSERT(M_auth_state.get()); return M_auth_state->auth_ping_argument(); }
void ServerSession::construct_network_object | ( | std::string const & | network_name, | |
std::string const & | domain | |||
) |
Create a new network object with name network_name and domain domain (if any).
Definition at line 442 of file ServerSession.cc.
References detected_network(), IdentityReference::identity(), network_domain_question, and Identity::send_notice().
Referenced by found_network_name(), and Identity::received_network_domain_answer().
00443 { 00444 networks_type& networks = Application::instance().networks(); 00445 networks_type::iterator iter; 00446 std::ostringstream buf; 00447 buf << "Added NEW network: \"" << network_name << "\""; 00448 if (domain.empty()) 00449 { 00450 iter = networks.insert(networks.end(), Network(network_name)); 00451 buf << '.'; 00452 } 00453 else 00454 { 00455 iter = networks.insert(networks.end(), Network(network_name, domain)); 00456 buf << ", with common domain \"" << domain << "\"."; 00457 } 00458 identity().send_notice(buf.str(), network_domain_question); 00459 detected_network(iter); 00460 }
void ServerSession::detected_network | ( | networks_type::iterator | network_iter | ) |
Initialize network. This function is called as soon as the network we are connected to is known.
Definition at line 462 of file ServerSession.cc.
References ASSERT, DoutEntering, ISupport::get(), IdentityReference::identity(), IRCStringCompare(), M_detected_network, M_i_support, M_server_connection, M_umodes, debug::channels::dc::maps, Identity::mynick(), ServerConnection::secondary_connection(), and ServerConnection::server().
Referenced by construct_network_object(), and found_network_name().
00463 { 00464 DoutEntering(dc::debug, "Identity::detected_network(" << *network_iter << ")"); 00465 00466 boost::shared_ptr<Server> current_server(M_server_connection.server()); 00467 00468 Dout(dc::notice, "Current server is " << *current_server.get()); 00469 00470 // Update the current server as we connected successfully. 00471 ASSERT(is_open()); 00472 ASSERT(remote_port() == current_server->port()); 00473 current_server->add_port(current_server->port()); 00474 Dout(dc::notice, "Added remote port " << current_server->port() << " to server " << *current_server.get()); 00475 00476 Dout(dc::debug, "*network_iter is now: " << *network_iter); 00477 00478 // Set the network pointer of the current Server object. 00479 current_server->set_network(&(*network_iter)); 00480 00481 if (!M_server_connection.secondary_connection()) 00482 { 00483 // Set the network pointer in my own Nick object. 00484 identity().mynick()->set_network(&(*network_iter)); 00485 // Make sure my Nick is inserted in the networks targets map. 00486 Dout(dc::maps, "Inserting my nick \"" << identity().mynick()->in_name(*this) << "\" in Network map."); 00487 network_iter->targets().insert(target_lookup_map_type::value_type(identity().mynick()->in_name(*this), identity().mynick())); 00488 ASSERT(network_iter->targets().find(identity().mynick()->in_name(*this)) != network_iter->targets().end()); 00489 } 00490 00491 // Find the current server in the list of known servers for this network. 00492 std::string server_name = current_server->get_irc_name(); 00493 Network::servers_type::iterator server = network_iter->servers().begin(); 00494 while (server != network_iter->servers().end()) 00495 { 00496 if (IRCStringCompare(server_name, (*server)->get_irc_name()) == 0) 00497 break; 00498 ++server; 00499 } 00500 if (server == network_iter->servers().end()) 00501 network_iter->servers().push_back(current_server); 00502 00503 M_detected_network = true; 00504 00505 // Initialize WHO flag table. 00506 std::string prefix; 00507 if (!M_i_support.get("PREFIX", prefix)) 00508 { 00509 prefix = "(ov)@+"; 00510 Dout(dc::warning, "No PREFIX ISUPPORT. Using " << prefix); 00511 } 00512 network_iter->init_who_flag_table(M_umodes, prefix); 00513 }
void ServerSession::authentication_successful | ( | void | ) |
Called when the authentication was successful (when receiving the 001 numeric).
Definition at line 327 of file ServerSession.cc.
References M_auth_state.
Referenced by new_message_received().
00328 { 00329 M_auth_state.reset(); 00330 }
void ServerSession::fatal_error | ( | char const * | error_msg | ) |
A fatal error occured. Calling this function will terminate the ServerSession.
Definition at line 313 of file ServerSession.cc.
00314 { 00315 if (!must_be_removed()) // Only write one error at a time. 00316 *this << "QUIT :Fatal error: " << error_msg << "\r\n"; 00317 // The next method sets 'must_be_removed()' to true, 00318 // flushes the error and deletes this object (non-blocking). 00319 del(); 00320 }
void ServerSession::found_network_name | ( | void | ) |
Called when the name of the Network is known (after numeric 005).
Definition at line 389 of file ServerSession.cc.
References ASSERT, Identity::client_session(), construct_network_object(), detected_network(), ServerConnection::disconnect(), IdentityReference::identity(), IRCStringCompare(), M_network_name, M_server_connection, network_domain_question, Identity::network_name(), Identity::received_network_domain_answer(), Identity::send_notice(), ServerConnection::server(), server_port_question, Identity::set_network_name(), and ClientSession::user_answer_event_server.
Referenced by ISupport::end().
00390 { 00391 Dout(dc::notice, "network = \"" << M_network_name << "\"."); 00392 if (identity().network_name() != unknown_network_name && identity().network_name() != M_network_name) 00393 { 00394 Dout(dc::warning, "Identity " << identity().key() << " was connected to network " << identity().network_name() << 00395 " but now tries to connect to network " << M_network_name << '!'); 00396 std::string notice("Detected a possible network switch (from "); 00397 notice += identity().network_name(); 00398 notice += " to "; 00399 notice += M_network_name; 00400 notice += "). Bailing out!"; 00401 identity().send_notice(notice, server_port_question); 00402 M_server_connection.disconnect(); 00403 return; 00404 } 00405 identity().send_notice("Successfully connected.", server_port_question); 00406 identity().set_network_name(M_network_name); 00407 00408 // Try to find if we already know this network. 00409 networks_type& networks = Application::instance().networks(); 00410 networks_type::iterator iter = networks.begin(); 00411 while (iter != networks.end()) 00412 { 00413 if (IRCStringCompare(iter->name(), M_network_name) == 0) 00414 break; 00415 ++iter; 00416 } 00417 if (iter == networks.end()) 00418 { 00419 std::string server_name = M_server_connection.server()->get_irc_name(); 00420 std::string::size_type pos = server_name.rfind('.'); 00421 ASSERT(pos > 0); 00422 pos = server_name.rfind('.', pos - 1); 00423 if (pos != std::string::npos) 00424 { 00425 std::string domain = server_name.substr(pos + 1); 00426 std::transform(domain.begin(), domain.end(), domain.begin(), ToLower); 00427 std::ostringstream the_question; 00428 the_question << "Does the " << M_network_name << " IRC network use \"" << 00429 domain << "\" as common domain for all servers (type: Yes|No)?"; 00430 identity().client_session().user_answer_event_server 00431 (UserAnswerRequestData(identity().client_session(), network_domain_question, the_question.str()), 00432 identity(), &Identity::received_network_domain_answer, 00433 std::pair<std::string, std::string>(M_network_name, domain)); 00434 } 00435 else 00436 construct_network_object(M_network_name, ""); // No common domain. 00437 } 00438 else 00439 detected_network(iter); 00440 }
MatcherEventServer& ServerSession::message_event_server | ( | void | ) | [inline] |
Return a reference to the event server for incoming messages.
Definition at line 112 of file ServerSession.h.
References M_message_event_server.
Referenced by AuthState::auth_notice_looking_up_hostname(), AuthState::auth_notice_looking_up_ident(), AuthState::AuthState(), and ServerConnection::send_pong_and_mode().
00112 { return M_message_event_server; }
MatcherEventServer const& ServerSession::message_event_server | ( | void | ) | const [inline] |
Return a const reference to the event server for incoming messages.
Definition at line 114 of file ServerSession.h.
References M_message_event_server.
00114 { return M_message_event_server; }
NickPair& ServerSession::nicks | ( | void | ) | [inline] |
Server session nick pair.
Definition at line 117 of file ServerSession.h.
References M_server_session_nicks.
Referenced by Matcher_noarg::match_impl(), new_message_received(), Identity::new_server_message_received(), Authentication::send_authentication(), send_nick_write_event(), and ServerConnection::send_pong_and_mode().
00117 { return M_server_session_nicks; }
NickPair const& ServerSession::nicks | ( | void | ) | const [inline] |
Server session nick pair.
Definition at line 120 of file ServerSession.h.
References M_server_session_nicks.
00120 { return M_server_session_nicks; }
joined_channels_type& ServerSession::joined_channels | ( | void | ) | [inline] |
Return reference to map with joined channels.
Definition at line 123 of file ServerSession.h.
References M_joined_channels.
Referenced by Target::add_channel(), send_rejoins(), Target::serverside_add_channel(), Target::serverside_get_channel(), Target::sub_channel(), and Identity::~Identity().
00123 { return M_joined_channels; }
joined_channels_type const& ServerSession::joined_channels | ( | void | ) | const [inline] |
Return const reference to map with joined channels.
Definition at line 126 of file ServerSession.h.
References M_joined_channels.
00126 { return M_joined_channels; }
UserMode& ServerSession::user_mode | ( | void | ) | [inline] |
Return my user mode.
Definition at line 129 of file ServerSession.h.
References M_user_mode.
Referenced by new_message_received(), and ServerConnection::send_pong_and_mode().
00129 { return M_user_mode; }
UserMode const& ServerSession::user_mode | ( | void | ) | const [inline] |
Return my user mode.
Definition at line 132 of file ServerSession.h.
References M_user_mode.
00132 { return M_user_mode; }
void ServerSession::queue_msg | ( | MessageOut const & | msg | ) | [inline] |
Queue message msg.
Definition at line 135 of file ServerSession.h.
References DoutEntering, M_output_queue, and Queue::queue_msg().
Referenced by ServerConnection::decode_ping(), Identity::new_client_message_received(), Channel::new_client_message_received(), ClientSession::new_client_nick_received(), Channel::new_server_message_received(), queue_msg_as_is(), and send_rejoins().
00135 { DoutEntering(dc::debug, "ServerSession::queue_msg(" << msg << ")"); M_output_queue.queue_msg(msg); }
void ServerSession::queue_msg_as_is | ( | ClientMessageIn const & | msg | ) |
Queue message msg with default priority without changing it.
Definition at line 382 of file ServerSession.cc.
References default_priority(), MessageIn::key(), MessageIn::params(), and queue_msg().
Referenced by Identity::new_client_message_received().
00383 { 00384 Prefix prefix(msg); 00385 MessageOut msgout(default_priority(msg.key())); 00386 queue_msg(msgout << prefix << msg.key() << msg.params(0)); 00387 }
WhoRequest ServerSession::current_who_request | ( | void | ) | [inline] |
Return the first element of M_who_queue.
Definition at line 141 of file ServerSession.h.
References ASSERT, and M_who_queue.
00142 { 00143 ASSERT(!M_who_queue.empty()); 00144 Dout(dc::debug, "ServerSession::current_who_request returns " << M_who_queue.front() << ". Number of items: " << M_who_queue.size()); 00145 return M_who_queue.front(); 00146 }
void ServerSession::pop_who_request | ( | void | ) | [inline] |
Pop the first element of M_who_queue.
Definition at line 149 of file ServerSession.h.
References ASSERT, and M_who_queue.
Referenced by Identity::new_server_message_received().
00150 { 00151 ASSERT(!M_who_queue.empty()); 00152 M_who_queue.pop(); 00153 Dout(dc::debug, "Calling ServerSession::pop_who_request. Remaining number of items: " << M_who_queue.size()); 00154 }
void ServerSession::send_nick_write_event | ( | PseudoMessageEventType const & | , | |
std::string | nick | |||
) | [inline] |
A write event of a pseudo NICK message happened. Actually write the NICK message.
Definition at line 157 of file ServerSession.h.
References nicks(), and NickPair::send_nick().
Referenced by ClientSession::new_client_nick_received().
void ServerSession::send_who_write_event | ( | PseudoMessageEventType const & | event_type, | |
WhoRequest | who_request | |||
) |
A write event of a pseudo WHO message happened. Actually write the WHO message.
Definition at line 347 of file ServerSession.cc.
References ASSERT, DoutEntering, M_who_queue, WhoRequest::mask(), WhoRequest::mask_contains_space(), WhoRequest::mask_is_target(), WhoRequest::mask_target(), WhoRequest::options(), and WhoOptions::str().
Referenced by Identity::new_client_message_received().
00348 { 00349 ASSERT(!debug::secondary_connection); 00350 DoutEntering(dc::debug, "ServerSession::send_who_write_event((PseudoMessageEventType&){" << (void*)&event_type << "), " << who_request << ")"); 00351 // Actually sent the WHO message to the server. 00352 std::string options(who_request.options().str()); 00353 bool has_options = !options.empty(); 00354 if (who_request.mask_contains_space()) 00355 { 00356 if (has_options) 00357 *this << "WHO dummy"; 00358 else 00359 *this << "WHO :" << who_request.mask(); 00360 } 00361 else if (who_request.mask_is_target()) 00362 *this << "WHO " << who_request.mask_target()->out_name(*this); 00363 else 00364 *this << "WHO " << who_request.mask(); 00365 if (has_options) 00366 { 00367 *this << ' ' << options; 00368 if (who_request.mask_contains_space()) 00369 { 00370 *this << " :"; 00371 if (who_request.mask_is_target()) 00372 *this << who_request.mask_target()->out_name(*this); 00373 else 00374 *this << who_request.mask(); 00375 } 00376 } 00377 *this << "\r\n"; 00378 Dout(dc::debug, "Pushing " << who_request << " onto M_who_queue."); 00379 M_who_queue.push(who_request); 00380 }
void ServerSession::force_quit | ( | timer_event_type_ct const & | ) |
Called 1 second after sending a QUIT and the connection still wasn't terminated.
Definition at line 515 of file ServerSession.cc.
References ServerConnection::disconnect(), DoutEntering, and M_server_connection.
00516 { 00517 DoutEntering(dc::debug, "ServerSession::force_quit(" << expired_at.get_expire_time() << ")"); 00518 M_server_connection.disconnect(); 00519 }
ISupport const& ServerSession::i_support | ( | void | ) | const [inline] |
Accessor for M_i_support.
Definition at line 166 of file ServerSession.h.
References M_i_support.
00166 { return M_i_support; }
ISupport& ServerSession::i_support | ( | void | ) | [inline] |
Accessor for M_i_support.
Definition at line 169 of file ServerSession.h.
References M_i_support.
00169 { return M_i_support; }
boost::shared_ptr< Channel > ServerSession::join_pipeline | ( | std::string const & | channel_name | ) |
Return a pointer to the channel in the pipeline, if any. Channel is removed from pipeline.
Definition at line 227 of file ServerSession.cc.
References M_join_pipeline.
Referenced by new_message_received().
00228 { 00229 boost::shared_ptr<Channel> result; 00230 join_pipeline_type::iterator iter = M_join_pipeline.find(channel_name); 00231 if (iter != M_join_pipeline.end()) 00232 { 00233 result = iter->second; 00234 M_join_pipeline.erase(iter); 00235 } 00236 return result; 00237 }
void ServerSession::set_disconnect_reason | ( | std::string const & | disconnect_reason | ) | [inline] |
Set the disconnect reason to disconnect_reason.
Definition at line 175 of file ServerSession.h.
References ASSERT, and M_disconnect_reason.
Referenced by ServerConnection::error_message_received().
00175 { ASSERT(M_disconnect_reason.empty()); M_disconnect_reason = disconnect_reason; }
ServerConnection& ServerSession::server_connection | ( | void | ) | const [inline] |
Accessor for underlying server connection object.
Definition at line 178 of file ServerSession.h.
References M_server_connection.
Referenced by get_nick(), Matcher_noarg::match_impl(), new_message_received(), and Target::serverside_add_channel().
00178 { return M_server_connection; }
boost::shared_ptr< Nick > ServerSession::get_nick | ( | std::string const & | nick_name, | |
bool | create = false | |||
) |
Get or create a Nick for nick_name.
Definition at line 537 of file ServerSession.cc.
References ASSERT, IdentityReference::identity(), is_nick(), Network::is_private(), debug::channels::dc::maps, server_connection(), Network::targets(), and THROW_EXCEPTION.
Referenced by Identity::new_server_message_received().
00538 { 00539 ASSERT(is_nick(nick_name)); 00540 00541 boost::shared_ptr<Nick> new_nick; 00542 // Get the network. 00543 Network& network(identity().server_connection().network()); 00544 ASSERT(!network.is_private()); 00545 // Get the nick, if any, or else create one. 00546 target_lookup_map_type::iterator network_iter = network.targets().find(nick_name); 00547 if (network_iter != network.targets().end()) 00548 new_nick = boost::static_pointer_cast<Nick>(network_iter->second.lock()); 00549 else if (create) 00550 { 00551 Nick* nick = new Nick(*this, nick_name); 00552 AllocTag(nick, nick_name); 00553 new_nick.reset(nick); 00554 Dout(dc::maps, "Inserting " << nick_name << " in Network map."); 00555 #if defined(CWDEBUG) || defined(DEBUG) 00556 std::pair<target_lookup_map_type::iterator, bool> res = 00557 #endif 00558 network.targets().insert(target_lookup_map_type::value_type(nick_name, new_nick)); 00559 ASSERT(res.second); 00560 } 00561 else 00562 THROW_EXCEPTION(unknown_target(), "The identity " << identity().key() << " has no server side nick \"" << nick_name << "\""); 00563 00564 return new_nick; 00565 }
void ServerSession::new_message_received | ( | ServerMessageIn const & | msg | ) | [protected, virtual] |
Incoming event from ServerSessionInput.
Definition at line 32 of file ServerSession.cc.
References ISupport::add(), ASSERT, authentication_successful(), ISupport::begin(), ServerConnection::change_state(), ClientSession::client_out_nick(), Identity::client_session(), ServerConnection::decode_ping(), default_priority(), ServerConnection::disconnect(), DoutEntering, ISupport::end(), ServerConnection::error_message_received(), IdentityReference::identity(), NickPair::in_nick(), MatchRequest::is_match(), join_pipeline(), MessageIn::key(), login_sent, M_i_support, M_join_pipeline, M_message_event_server, M_network_name, M_server_connection, M_server_session_nicks, M_umodes, Identity::mynick(), Identity::new_server_message_received(), UserMode::new_server_message_received(), NickPair::nick_received(), nicks(), MessageIn::param(), MessageIn::params(), MessageIn::params_size(), MessageIn::prefix_str(), ClientSession::queue_msg(), ClientSession::queue_msg_me_as_is(), real_nick_accepted, real_nick_sent, MatchRequest::regexp(), ServerConnection::secondary_connection(), Identity::secondary_server_connection(), NickPair::send_nick(), Identity::send_notice(), send_rejoins(), ServerConnection::server(), server_connection(), server_port_question, ServerMessageIn::server_session(), Target::serverside_add_channel(), Identity::set_hostname(), ServerConnection::state(), Identity::swap_primary_and_secondary_connection(), and user_mode().
00033 { 00034 #ifdef CWDEBUG 00035 // Suppress all debug output related to PING messages. 00036 bool suppress_debug_output = 00037 (msg.key() == keys::PING && Application::instance().suppress_ping()) || 00038 ((msg.key() == 352 || msg.key() == 354 || msg.key() == 315) && Application::instance().suppress_who()); 00039 Debug(if (suppress_debug_output) libcw_do.off()); 00040 #endif 00041 00042 DoutEntering(dc::debug, "ServerSession::new_message_received(" << msg << ")"); 00043 00044 // Trigger message match events. 00045 if (M_message_event_server.trigger(MatcherEventType(msg))) 00046 { 00047 Debug(if (suppress_debug_output) libcw_do.on()); 00048 return; 00049 } 00050 00051 // Decode messages that can happen prior to network detection here. 00052 // Other messages are decoded in default:. 00053 bool pre_network_message = true; // non-Default. 00054 bool fully_processed = true; // No reason to call Identity::new_server_message_received. 00055 switch(msg.key()) 00056 { 00057 case 1: 00058 { 00059 // My own nick name should equal parameter 0. 00060 ASSERT(msg.param(0) == nicks().in_nick()); 00061 ASSERT(M_server_connection.secondary_connection() || msg.param(0) == identity().mynick()->in_name(*this)); 00062 authentication_successful(); 00063 M_server_connection.server()->set_irc_name(msg.prefix_str()); 00064 MatchRequest match_request; 00065 match_request(1).regexp("Welcome to [Tt]he [^ ]* IRC [Nn]etwork", 1); 00066 if (!match_request.is_match(msg)) 00067 { 00068 std::ostringstream buf; 00069 buf << "Unrecognized 001 format [" << msg.param(1) << "]. Bailing out."; 00070 identity().send_notice(buf.str(), server_port_question); 00071 M_server_connection.disconnect(); 00072 } 00073 else 00074 M_network_name.assign(msg.param(1), 15, msg.param(1).find(' ', 16) - 15); 00075 break; 00076 } 00077 case 4: 00078 { 00079 // We can use this numeric to detect the start of a possible sequence of 005 messages. 00080 // See also the call to i_support().end(). 00081 M_i_support.begin(); 00082 // Store the supported user modes. 00083 M_umodes = msg.param(3); 00084 // Store the server version. 00085 M_server_connection.server()->version().set_version(msg.param(2), timerRequest.get_now().tv_sec); 00086 break; 00087 } 00088 case 5: 00089 { 00090 // Decode the params. Param 0 is my nick, param n-1 is "is supported by this server". 00091 for (unsigned int n = 1; n < msg.params_size() - 1; ++n) 00092 M_i_support.add(msg.param(n)); 00093 break; 00094 } 00095 case 251: 00096 { 00097 // This means that all 005 numerics have been received. 00098 M_i_support.end(); 00099 break; 00100 } 00101 case 2: 00102 case 3: 00103 case 252: 00104 case 253: 00105 case 254: 00106 case 255: 00107 case 372: 00108 case 375: 00109 case 376: 00110 break; 00111 default: 00112 { 00113 pre_network_message = false; 00114 // Decode messages that do not only happen once per (re)connect. 00115 switch (msg.key()) 00116 { 00117 using namespace keys; 00118 case ERROR: 00119 M_server_connection.error_message_received(msg); 00120 break; 00121 case PING: // No target 00122 M_server_connection.decode_ping(msg); 00123 break; 00124 case NICK: 00125 { 00126 if (!M_server_session_nicks.nick_received(msg.param(0))) 00127 { 00128 fully_processed = false; 00129 break; 00130 } 00131 // It was my own nick change. 00132 identity().mynick()->serverside_nick_changed_to(msg.server_session(), M_server_session_nicks.in_nick()); 00133 if (!M_server_connection.secondary_connection()) 00134 { 00135 // FIXME: We should only pass nick changes to the client that the client itself requested. 00136 ASSERT(identity().client_session().client_in_nick() == msg.param(0)); 00137 Prefix prefix(msg); 00138 // For now, pass everything on to the client. 00139 MessageOut msgout(default_priority(keys::NICK)); 00140 // FIXME: client_out_nick() should be updated first (is currently equal to client_in_nick, so no change needed now). 00141 identity().client_session().queue_msg(msgout << prefix << keys::NICK << identity().client_session().client_out_nick()); 00142 identity().mynick()->clientside_nick_changed_to(identity().client_session(), identity().client_session().client_out_nick()); 00143 } 00144 if (M_server_connection.state() == real_nick_sent) 00145 { 00146 M_server_connection.change_state(real_nick_sent, real_nick_accepted); 00147 send_rejoins(); 00148 } 00149 break; 00150 } 00151 case MODE: 00152 if (msg.param(0) == nicks().in_nick()) 00153 user_mode().new_server_message_received(msg); 00154 else 00155 fully_processed = false; 00156 break; 00157 case 221: 00158 break; 00159 case 396: // ... is now your hidden host 00160 { 00161 server_connection().change_state(login_sent, real_nick_sent); 00162 // Numeric 396 has the hidden hostname in parameter 1. 00163 identity().set_hostname(msg.param(1)); 00164 if (!server_connection().secondary_connection()) 00165 { 00166 identity().client_session().queue_msg_me_as_is(msg); 00167 nicks().send_nick(identity().client_session().client_in_nick()); 00168 } 00169 else 00170 send_rejoins(); 00171 break; 00172 } 00173 case JOIN: 00174 { 00175 // Handle JOIN's from the pipeline. 00176 boost::shared_ptr<Channel> channel(join_pipeline(msg.param(0))); 00177 if (!channel.get()) 00178 { 00179 // Not in the pipeline. Process normally. 00180 ASSERT(!server_connection().secondary_connection()); 00181 fully_processed = false; 00182 break; 00183 } 00184 Target::serverside_add_channel(*this, channel); 00185 if (!server_connection().secondary_connection()) 00186 channel->reset_received_names(); 00187 else if (M_join_pipeline.empty()) 00188 { 00189 // This was the last join. 00190 // FIXME: switch ServerConnection etc. 00191 identity().swap_primary_and_secondary_connection(); 00192 identity().secondary_server_connection()->disconnect(); 00193 } 00194 break; 00195 } 00196 default: 00197 fully_processed = false; 00198 break; 00199 } 00200 break; 00201 } 00202 } 00203 if (pre_network_message) 00204 { 00205 // Pass message on as-is, only replacing my own nick name at param 0. 00206 Prefix prefix(msg); 00207 MessageOut msgout(default_priority(msg.key())); 00208 identity().client_session().queue_msg(msgout << prefix << msg.key() << identity().client_session().client_out_nick() << msg.params(1)); 00209 } 00210 else if (!fully_processed) 00211 { 00212 if (!M_server_connection.secondary_connection()) 00213 { 00214 // Decode messages other than PING, ERROR, own nick changes. 00215 identity().new_server_message_received(msg); 00216 } 00217 #ifdef CWDEBUG 00218 else 00219 Dout(dc::warning, "IGNORING secondary server message: " << msg); 00220 #endif 00221 } 00222 00223 // Turn debug output on again, if it was suppressed. 00224 Debug(if (suppress_debug_output) libcw_do.on()); 00225 }
void ServerSession::network_connection_terminated | ( | void | ) | [protected, virtual] |
A read(2) on the socket returned 0.
Definition at line 521 of file ServerSession.cc.
References DoutEntering, IdentityReference::identity(), M_disconnect_reason, M_server_connection, ServerConnection::secondary_connection(), Identity::send_notice(), and ServerConnection::server().
00522 { 00523 #ifdef CWDEBUG 00524 debug::SecondaryConnection dummy(M_server_connection.secondary_connection()); 00525 #endif 00526 DoutEntering(dc::debug, "ServerSession::network_connection_terminated()"); 00527 00528 std::string disconnect_reason; 00529 if (M_disconnect_reason.empty()) 00530 disconnect_reason = "EOF from server"; 00531 else 00532 disconnect_reason = M_disconnect_reason; 00533 00534 identity().send_notice("Lost connection with " + M_server_connection.server()->get_irc_name() + ": " + disconnect_reason); 00535 }
void ServerSession::send_rejoins | ( | void | ) | [private] |
Send a JOIN to the server for every channel we are on.
Definition at line 239 of file ServerSession.cc.
References ASSERT, Identity::client_session(), default_priority(), DoutEntering, IdentityReference::identity(), ClientSession::joined_channels(), joined_channels(), M_join_pipeline, and queue_msg().
Referenced by new_message_received().
00240 { 00241 DoutEntering(dc::debug, "ServerSession::send_rejoins()"); 00242 // Sent a JOIN for each channel that the client still thinks it is on. 00243 MessageOut msgout(default_priority(keys::JOIN)); 00244 msgout << keys::JOIN; 00245 size_t total_buffer_size = 8; // "JOIN \r\n\0" 00246 bool first_channel = true; 00247 bool first_key = true; 00248 std::string keys; 00249 // First do all channels that have a key. 00250 for (int with_keys = 1; with_keys >= 0; --with_keys) 00251 { 00252 for (ClientSession::joined_channels_type::iterator iter = identity().client_session().joined_channels().begin(); 00253 iter != identity().client_session().joined_channels().end(); ++iter) 00254 { 00255 boost::shared_ptr<Channel> channel(boost::static_pointer_cast<Channel>(iter->second)); 00256 if (with_keys == channel->has_key()) 00257 { 00258 for(;;) 00259 { 00260 total_buffer_size += 00261 (first_channel ? 0 : 1) + // 1 for comma. 00262 channel->out_name(*this).size() + 00263 (with_keys ? 1 + channel->key().size() : 0); // 1 for space or comma. 00264 if (total_buffer_size <= 512) // We always break out here the first or second time, 00265 break; // because 8 + MAXCHANLEN (~200) + 1 + MAXKEYLEN (23) <= 512. 00266 if (!first_key) 00267 msgout << keys; 00268 queue_msg(msgout); // Send message constructed so far. 00269 msgout << keys::JOIN; // This resets the msgout. 00270 total_buffer_size = 8; 00271 first_channel = true; 00272 first_key = true; 00273 } 00274 if (first_channel) 00275 { 00276 msgout << channel; 00277 first_channel = false; 00278 } 00279 else 00280 { 00281 msgout << JustInTimeCatenate(','); 00282 msgout << JustInTimeCatenate(channel); 00283 } 00284 if (with_keys) 00285 { 00286 if (first_key) 00287 { 00288 keys = channel->key(); 00289 first_key = false; 00290 } 00291 else 00292 { 00293 keys += ','; 00294 keys += channel->key(); 00295 } 00296 } 00297 // Remember that we sent a re-JOIN for this channel. 00298 #if defined(CWDEBUG) || defined(DEBUG) 00299 std::pair<join_pipeline_type::iterator, bool> res = 00300 #endif 00301 M_join_pipeline.insert(join_pipeline_type::value_type(channel->out_name(*this), channel)); 00302 ASSERT(res.second); 00303 } 00304 } 00305 } 00306 // Finish up. 00307 if (!first_key) 00308 msgout << keys; 00309 if (!first_channel) 00310 queue_msg(msgout); 00311 }
The owning object.
Definition at line 53 of file ServerSession.h.
Referenced by detected_network(), force_quit(), found_network_name(), network_connection_terminated(), new_message_received(), server_connection(), start_authentication(), and ~ServerSession().
Event server for incoming messages.
Definition at line 54 of file ServerSession.h.
Referenced by message_event_server(), and new_message_received().
Server side nick pair.
Definition at line 55 of file ServerSession.h.
Referenced by new_message_received(), and nicks().
Serverside lookup map for channels joined by this identity.
Definition at line 56 of file ServerSession.h.
Referenced by joined_channels().
UserMode ServerSession::M_user_mode [private] |
boost::shared_ptr<AuthState> ServerSession::M_auth_state [private] |
Pointer object with temporary authentication state information.
Definition at line 58 of file ServerSession.h.
Referenced by auth_ping_argument(), authentication_successful(), set_auth_ping_argument(), and start_authentication().
Queue ServerSession::M_output_queue [private] |
Queue for output messages.
Definition at line 59 of file ServerSession.h.
Referenced by queue_msg().
std::queue<WhoRequest> ServerSession::M_who_queue [private] |
Queue storing WHO request messages.
Definition at line 60 of file ServerSession.h.
Referenced by current_who_request(), pop_who_request(), and send_who_write_event().
ISupport ServerSession::M_i_support [private] |
Object that stores the numeric 005 information.
Definition at line 61 of file ServerSession.h.
Referenced by detected_network(), i_support(), and new_message_received().
std::string ServerSession::M_network_name [private] |
Temporary storage of the network name as decoded from numeric 001, until numeric 005 is received.
Definition at line 62 of file ServerSession.h.
Referenced by found_network_name(), and new_message_received().
int ServerSession::S_server_sessions = 0 [static, private] |
Total number of server session objects.
Definition at line 63 of file ServerSession.h.
Referenced by ServerSession(), and ~ServerSession().
std::string ServerSession::M_umodes [private] |
The user modes as received in numeric 004.
Definition at line 64 of file ServerSession.h.
Referenced by detected_network(), and new_message_received().
Channels for which we sent a JOIN as part of a reconnect.
Definition at line 65 of file ServerSession.h.
Referenced by join_pipeline(), new_message_received(), and send_rejoins().
std::string ServerSession::M_disconnect_reason [private] |
An error message that should be sent to the client if the connection is lost, if any.
Definition at line 66 of file ServerSession.h.
Referenced by network_connection_terminated(), and set_disconnect_reason().
True if the network is fully detected.
Definition at line 69 of file ServerSession.h.
Referenced by detected_network(), and ServerConnection::send_pong_and_mode().
Copyright © 2005-2007 Carlo Wood. All rights reserved. |
---|