X-Git-Url: https://git.teslayout.com/public/public/public/?a=blobdiff_plain;ds=sidebyside;f=source%2Fdiameter.comm%2FServerSession.cpp;h=ab7ca11102d1c2b643fca2b27a8768494fcdcbb2;hb=refs%2Fheads%2Fmaster;hp=4a146b8e0dda6402efd4e336373c9ac37a278f4d;hpb=30def5757c5b3411f77fff62a163241ecc616337;p=anna.git diff --git a/source/diameter.comm/ServerSession.cpp b/source/diameter.comm/ServerSession.cpp index 4a146b8..ab7ca11 100644 --- a/source/diameter.comm/ServerSession.cpp +++ b/source/diameter.comm/ServerSession.cpp @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include @@ -53,12 +55,10 @@ const anna::Millisecond ServerSession::DefaultAllowedInactivityTime(90000); // I ServerSession::ServerSession() : Session("diameter::comm::ServerSession", "Diameter Inactivity Detection Timer"), - a_receiverFactory(this), - a_cer(ClassCode::Bind), - a_dwr(ClassCode::ApplicationMessage) // not actually needed; Message is application type by default + a_receiverFactory(this) { initialize(); } -void ServerSession::initialize() throw() { +void ServerSession::initialize() { Session::initialize(); a_parent = NULL; a_clientSocket = NULL; @@ -67,21 +67,21 @@ void ServerSession::initialize() throw() { //ServerSession::~ServerSession() {;} -void ServerSession::setClientSocket(anna::comm::ClientSocket *clientSocket) throw() { +void ServerSession::setClientSocket(anna::comm::ClientSocket *clientSocket) { a_clientSocket = clientSocket; a_clientSocket->setReceiverFactory(a_receiverFactory); } -const std::string& ServerSession::getAddress() const throw() { +const std::string& ServerSession::getAddress() const { return a_parent->getKey().first; } -int ServerSession::getPort() const throw() { +int ServerSession::getPort() const { return a_parent->getKey().second; } -const Response* ServerSession::send(const Message* message) throw(anna::RuntimeException) { +const Response* ServerSession::send(const Message* message) noexcept(false) { LOGMETHOD(anna::TraceMethod traceMethod(a_className, "send", ANNA_FILE_LOCATION)); if(!message) @@ -211,22 +211,6 @@ const Response* ServerSession::send(const Message* message) throw(anna::RuntimeE updateOutgoingActivityTime(); // OAM countSendings(cid, aid, true /* send ok */); - // Trace non-application messages: - LOGDEBUG( - - if( (cid == helpers::base::COMMANDID__Device_Watchdog_Request) || - (cid == helpers::base::COMMANDID__Disconnect_Peer_Request)) { - anna::Logger::debug("Sent DataBlock to XML representation:", ANNA_FILE_LOCATION); - try { - anna::diameter::codec::Message msg(a_engine->getBaseProtocolCodecEngine()); msg.decode(message->getBody()); /* decode to be traced */ - } - catch(anna::RuntimeException &ex) { - std::string msg = ex.getText(); - msg += " | Use diameter::comm::Engine::setBaseProtocolCodecEngine() to allow internal base protocol messages full tracing"; - anna::Logger::debug(msg, ANNA_FILE_LOCATION); - } - } - ); // Restore sequences: if(fixed) message_nc->restoreSequencesAfterFix(); // restore to application sequences after fix @@ -260,7 +244,7 @@ const Response* ServerSession::send(const Message* message) throw(anna::RuntimeE -bool ServerSession::unbind(bool forceDisconnect) throw(anna::RuntimeException) { +bool ServerSession::unbind(bool forceDisconnect) noexcept(false) { LOGMETHOD(anna::TraceMethod traceMethod(a_className, "unbind", ANNA_FILE_LOCATION)); if(a_state == State::Closed) @@ -307,12 +291,12 @@ bool ServerSession::unbind(bool forceDisconnect) throw(anna::RuntimeException) { return false; } -void ServerSession::eventPeerShutdown() throw() { +void ServerSession::eventPeerShutdown() { // Inform father server: a_parent->eventPeerShutdown(this); } -void ServerSession::eventRequestRetransmission(Message *request) throw() { +void ServerSession::eventRequestRetransmission(Message *request) { // OAM OamModule &oamModule = OamModule::instantiate(); @@ -323,32 +307,64 @@ void ServerSession::eventRequestRetransmission(Message *request) throw() { a_parent->eventRequestRetransmission(this, request); } -void ServerSession::eventResponse(const Response& response) throw(anna::RuntimeException) { +void ServerSession::eventResponse(const Response& response, const anna::diameter::comm::OriginHost *myNode) noexcept(false) { // Inform father server: - a_parent->eventResponse(response); + a_parent->eventResponse(response, myNode); } -void ServerSession::eventRequest(const anna::DataBlock &request) throw(anna::RuntimeException) { +void ServerSession::eventRequest(const anna::DataBlock &request, const anna::diameter::comm::OriginHost *myNode) noexcept(false) { // Inform father server: - a_parent->eventRequest(this, request); + a_parent->eventRequest(this, request, myNode); } -void ServerSession::eventUnknownResponse(const anna::DataBlock& response) throw(anna::RuntimeException) { +void ServerSession::eventUnknownResponse(const anna::DataBlock& response, const anna::diameter::comm::OriginHost *myNode) noexcept(false) { // Inform father server: - a_parent->eventUnknownResponse(this, response); + a_parent->eventUnknownResponse(this, response, myNode); } -void ServerSession::eventDPA(const anna::DataBlock& response) throw(anna::RuntimeException) { +void ServerSession::eventDPA(const anna::DataBlock& response, const anna::diameter::comm::OriginHost *myNode) noexcept(false) { // Inform father server: - a_parent->eventDPA(this, response); + a_parent->eventDPA(this, response, myNode); +} + + +anna::U32 ServerSession::getAuthApplicationIdFromCER(const anna::DataBlock &cer, bool &found) const { + + anna::U32 result{}; + found = true; + + anna::diameter::codec::Message codecMsg; // codec engine to pre-assigned, but will be inferred from ApplicationId during decoding: + try { codecMsg.decode(cer); } catch(anna::RuntimeException &ex) { ex.trace(); found = false; return result; } + + // Look at first level: + try { + result = codecMsg.getAvp(helpers::base::AVPID__Auth_Application_Id)->getUnsigned32()->getValue(); + } + catch(anna::RuntimeException &ex) { + found = false; + } + + // Look within Vendor-Specific-Application-Id: + if (!found) { + try { + result = codecMsg.getAvp(helpers::base::AVPID__Vendor_Specific_Application_Id)->getAvp(helpers::base::AVPID__Auth_Application_Id)->getUnsigned32()->getValue(); + } + catch(anna::RuntimeException &ex) { + found = false; + } + } + + return result; } //------------------------------------------------------------------------------------------ // Se invoca desde el diameter::comm::Receiver //------------------------------------------------------------------------------------------ void ServerSession::receive(const anna::comm::Message& message) -throw(anna::RuntimeException) { +noexcept(false) { LOGMETHOD(anna::TraceMethod traceMethod(a_className, "receive", ANNA_FILE_LOCATION)); + + // Activity: updateIncomingActivityTime(); activateTimer(); @@ -360,18 +376,6 @@ throw(anna::RuntimeException) { std::string msg = "Received diameter message: "; msg += anna::diameter::functions::commandIdAsPairString(cid); anna::Logger::debug(msg, ANNA_FILE_LOCATION); - - if( (cid == helpers::base::COMMANDID__Capabilities_Exchange_Request) || - (cid.first == helpers::base::COMMANDID__Device_Watchdog_Request.first)) { - try { - anna::diameter::codec::Message dmsg(a_engine->getBaseProtocolCodecEngine()); dmsg.decode(db); /* decode to be traced */ - } - catch(anna::RuntimeException &ex) { - std::string msg = ex.getText(); - msg += " | Use diameter::comm::Engine::setBaseProtocolCodecEngine() to allow internal base protocol messages full tracing"; - anna::Logger::debug(msg, ANNA_FILE_LOCATION); - } - } ); // Main counters: OamModule &oamModule = OamModule::instantiate(); @@ -380,6 +384,16 @@ throw(anna::RuntimeException) { // Statistic (size) a_parent->updateReceivedMessageSizeStatisticConcept(message.getSize(), cid); // only on reception (application could manage sent sizes) + // OriginHostManager (to register remote origin host in order to associate with specific comm engine): + anna::diameter::comm::OriginHostManager &ohm = anna::diameter::comm::OriginHostManager::instantiate(); + + // Extract OriginHost from datablock (db): + std::string remoteOriginHost = anna::diameter::helpers::base::functions::getOriginHost(db); + LOGDEBUG(anna::Logger::debug(anna::functions::asString("REMOTE ORIGIN HOST FOR THE MESSAGE RECEIVED: %s", remoteOriginHost.c_str()), ANNA_FILE_LOCATION)); + + // Now, get the corresponding own origin host for it; in case of CER received, this will be unkonwn: + const anna::diameter::comm::OriginHost *originHost = ohm.getOriginHostForRemoteOriginHost(remoteOriginHost); + if(isRequest) { // Si recibo un request, el message solo tiene fiable el DataBlock. Como por defecto se construye como ApplicationMessage, // el unico caso que no cuadraria seria la recepcion de un CER. Lo que hacemos es NO PROGRESAR NUNCA un CER (*). @@ -390,17 +404,35 @@ throw(anna::RuntimeException) { // Received CER if(cid == helpers::base::COMMANDID__Capabilities_Exchange_Request) { + + // For CERs, we need to extract the Auth-Application-Id: + bool found; + anna::U32 authApplicationId = getAuthApplicationIdFromCER(db, found); + + // Now, sequential search in OriginHostManager for that id: + anna::diameter::comm::OriginHost *originHost = ohm.getOriginHost(authApplicationId); + + if (!originHost) { + LOGWARNING(anna::Logger::warning("DIAMETER_NO_COMMON_APPLICATION with received CER. TODO: send CEA with that result code", ANNA_FILE_LOCATION)); + unbind(true /* always immediate */); + return; + } + + // Map origin host of received CER, to own OriginHost pointer. This will be used in future: DWR, DPR, normal messages + ohm.registerRemoteOriginHost(remoteOriginHost, originHost->getName()); + + + // OAM oamModule.count(OamModule::Counter::CERReceived); if(a_state == State::Bound) { LOGWARNING(anna::Logger::warning("Received another CER over already bound connection. Anyway, will be replied with CEA", ANNA_FILE_LOCATION)); } - a_cer.setBody(db); // Basic DRA: - getParent()->getEngine()->manageDrDhServerSession(this, true /* register */); + originHost->getCommEngine()->manageDrDhServerSession(this, true /* register */); - sendCEA(); + sendCEA(originHost->getCommEngine(), db); //activateTimer(); // Ya se invoca al inicio de este metodo ::receive //bool changes = a_parent->refreshAvailability(); return; // (*) @@ -408,20 +440,23 @@ throw(anna::RuntimeException) { // Received DWR else if(cid == helpers::base::COMMANDID__Device_Watchdog_Request) { oamModule.count(OamModule::Counter::DWRReceived); - a_dwr.setBody(db); - sendDWA(); + + if (!originHost) return; // TODO, responding DWA with result code error + + sendDWA(originHost->getCommEngine(), db); return; // (**) } // Received DPR else if(cid == helpers::base::COMMANDID__Disconnect_Peer_Request) { oamModule.count(OamModule::Counter::DPRReceived); + if (!originHost) return; // TODO, responding DPA with result code error + if(a_state == State::Bound) { - a_dpr.setBody(db); setState(State::Disconnecting); LOGWARNING(anna::Logger::warning("DPR has been received from peer (diameter client)", ANNA_FILE_LOCATION)); // Ignore pending on server sessions: - /*if (getOTARequests() == 0) */sendDPA(); + /*if (getOTARequests() == 0) */sendDPA(originHost->getCommEngine(), db); return; // DPR won't be informed because virtual readDPA is available for this } } @@ -430,7 +465,9 @@ throw(anna::RuntimeException) { // application message counters ApplicationMessageOamModule::instantiate().count(cid.first, -1 /* no result code */, anna::diameter::codec::functions::getApplicationId(db), ApplicationMessageOamModule::Counter::Request_Received_AsServer); - eventRequest(db); + if (!originHost) return; // TODO, responding DWA with result code error + + eventRequest(db, originHost); } catch(anna::RuntimeException& ex) { ex.trace(); } @@ -464,7 +501,8 @@ throw(anna::RuntimeException) { } } - eventDPA(db); + if (originHost) + eventDPA(db, originHost); } else if(cid == helpers::base::COMMANDID__Device_Watchdog_Answer) { // non usual (server should not send DWR's) oamModule.count(OamModule::Counter::DWAReceived); @@ -483,7 +521,8 @@ throw(anna::RuntimeException) { // application message counters ApplicationMessageOamModule::instantiate().count(cid.first, resultCode, anna::diameter::codec::functions::getApplicationId(db), ApplicationMessageOamModule::Counter::Answer_UnknownReceived_AsServer); - eventUnknownResponse(db); + if (originHost) + eventUnknownResponse(db, originHost); string msg(asString()); msg += anna::functions::asString(" | Response received from client, for non registered context (HopByHop: %u)", hopByHop); @@ -534,7 +573,8 @@ throw(anna::RuntimeException) { // application message counters ApplicationMessageOamModule::instantiate().count(cid.first, resultCode, anna::diameter::codec::functions::getApplicationId(db), ApplicationMessageOamModule::Counter::Answer_Received_AsServer); - eventResponse(*response); + if (originHost) + eventResponse(*response, originHost); } catch(anna::RuntimeException& ex) { ex.trace(); @@ -548,7 +588,7 @@ throw(anna::RuntimeException) { unbind(true /* always immediate */); } -void ServerSession::finalize() throw() { +void ServerSession::finalize() { LOGMETHOD(anna::TraceMethod traceMethod(a_className, "finalize", ANNA_FILE_LOCATION)); // Configuration overiddings setOnDisconnect(OnDisconnect::IgnorePendings); @@ -584,11 +624,12 @@ void ServerSession::finalize() throw() { -void ServerSession::sendCEA() -throw(anna::RuntimeException) { +void ServerSession::sendCEA(const Engine *commEngine, const anna::DataBlock &cerDataBlock) +noexcept(false) { LOGMETHOD(anna::TraceMethod traceMethod(a_className, "sendCEA", ANNA_FILE_LOCATION)); + anna::DataBlock cea(true); - a_engine->readCEA(cea, a_cer.getBody()); // Asume that CEA is valid ... + commEngine->readCEA(cea, cerDataBlock); // Asume that CEA is valid ... // If one peer sends a CER message to another Peer and receiver does not have support for // // 1) any common application then it must return the CEA with Result-Code Avp set to DIAMETER_NO_COMMON_APPLICATION @@ -635,11 +676,11 @@ throw(anna::RuntimeException) { } } -void ServerSession::sendDWA() -throw(anna::RuntimeException) { +void ServerSession::sendDWA(const Engine *commEngine, const anna::DataBlock &dwrDataBlock) +noexcept(false) { LOGMETHOD(anna::TraceMethod traceMethod(a_className, "sendDWA", ANNA_FILE_LOCATION)); anna::DataBlock dwa(true); - a_engine->readDWA(dwa, a_dwr.getBody()); // Asume that DWA is valid ... + commEngine->readDWA(dwa, dwrDataBlock); // Asume that DWA is valid ... if(dwa.isEmpty()) throw anna::RuntimeException("This diameter agent defines an empty DWA message. Remote client never will validate this connection health", ANNA_FILE_LOCATION); @@ -654,7 +695,7 @@ throw(anna::RuntimeException) { // Se invoca desde diameter::comm::Timer //------------------------------------------------------------------------- void ServerSession::expireResponse(diameter::comm::Response* response) -throw() { +{ LOGMETHOD(anna::TraceMethod traceMethod(a_className, "expireResponse", ANNA_FILE_LOCATION)); Session::expireResponse(response); // OAM @@ -667,7 +708,7 @@ throw() { } std::string ServerSession::asString() const -throw() { +{ string result = Session::asString(); result += " | Parent Local Server: "; result += anna::functions::socketLiteralAsString(getAddress(), getPort()); @@ -682,7 +723,7 @@ throw() { } anna::xml::Node* ServerSession::asXML(anna::xml::Node* parent) const -throw() { +{ anna::xml::Node* result = Session::asXML(parent); parent->createChild("diameter.comm.ServerSession"); result->createAttribute("ParentLocalServer", anna::functions::socketLiteralAsString(getAddress(), getPort())); @@ -697,7 +738,7 @@ throw() { //------------------------------------------------------------------------------ //------------------------------------------------------ ServerSession::expire() //------------------------------------------------------------------------------ -void ServerSession::expire(anna::timex::Engine *timeController) throw(anna::RuntimeException) { +void ServerSession::expire(anna::timex::Engine *timeController) noexcept(false) { LOGMETHOD(anna::TraceMethod traceMethod(a_className, "expire (inactivity check timer)", ANNA_FILE_LOCATION)); LOGWARNING(anna::Logger::warning("Detecting anomaly (too inactivity time) over server session. Resetting", ANNA_FILE_LOCATION)); // OAM @@ -716,14 +757,14 @@ void ServerSession::expire(anna::timex::Engine *timeController) throw(anna::Runt unbind(true /* always immediate */); // no delegamos en un planning o similar } -void ServerSession::setAllowedInactivityTime(const anna::Millisecond & allowedInactivityTime) throw() { +void ServerSession::setAllowedInactivityTime(const anna::Millisecond & allowedInactivityTime) { setTimeout(allowedInactivityTime); } //------------------------------------------------------------------------------ //---------------------------------- ServerSession::updateIncomingActivityTime() //------------------------------------------------------------------------------ -void ServerSession::updateIncomingActivityTime() throw() { +void ServerSession::updateIncomingActivityTime() { Session::updateIncomingActivityTime(); a_parent->updateIncomingActivityTime(); } @@ -732,7 +773,7 @@ void ServerSession::updateIncomingActivityTime() throw() { //------------------------------------------------------------------------------ //---------------------------------- ServerSession::updateOutgoingActivityTime() //------------------------------------------------------------------------------ -void ServerSession::updateOutgoingActivityTime(void) throw() { +void ServerSession::updateOutgoingActivityTime(void) { Session::updateOutgoingActivityTime(); a_parent->updateOutgoingActivityTime(); } @@ -741,7 +782,7 @@ void ServerSession::updateOutgoingActivityTime(void) throw() { //------------------------------------------------------------------------------ //----------------------------------------------- ServerSession::countSendings() //------------------------------------------------------------------------------ -void ServerSession::countSendings(const diameter::CommandId & cid, unsigned int aid, bool ok)throw() { +void ServerSession::countSendings(const diameter::CommandId & cid, unsigned int aid, bool ok){ OamModule &oamModule = OamModule::instantiate(); ApplicationMessageOamModule &appMsgOamModule = ApplicationMessageOamModule::instantiate();