X-Git-Url: https://git.teslayout.com/public/public/public/?a=blobdiff_plain;f=source%2Fdiameter.comm%2FEngine.cpp;h=3a7f84305c44d74df891e0d5b12ddff7ae5a2791;hb=ea14381cada0d7173fd19eaaf781f82eb714325e;hp=266b57a9ab4c96fdacc61346127cc5c3b977b3c7;hpb=39033fd99e58e994a5e98c1060dcc79e0d81f9c9;p=anna.git diff --git a/source/diameter.comm/Engine.cpp b/source/diameter.comm/Engine.cpp index 266b57a..3a7f843 100644 --- a/source/diameter.comm/Engine.cpp +++ b/source/diameter.comm/Engine.cpp @@ -1,37 +1,9 @@ -// ANNA - Anna is Not Nothingness Anymore -// -// (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo -// -// http://redmine.teslayout.com/projects/anna-suite -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Authors: eduardo.ramos.testillano@gmail.com -// cisco.tierra@gmail.com +// ANNA - Anna is Not Nothingness Anymore // +// // +// (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo // +// // +// See project site at http://redmine.teslayout.com/projects/anna-suite // +// See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE // #include @@ -65,8 +37,9 @@ using namespace std; using namespace anna::diameter::comm; -Engine::Engine() : - anna::app::Component(getClassName()), +Engine::Engine(const char *className, codec::Engine *baseProtocolCodecEngine) : + anna::app::Component(className), + a_baseProtocolCodecEngine(baseProtocolCodecEngine), a_autoBind(true), a_availableForEntities(false), a_availableForLocalServers(false), @@ -76,8 +49,7 @@ Engine::Engine() : // a_dwa(true), a_watchdogPeriod(ClientSession::DefaultWatchdogPeriod), a_maxConnectionDelay(anna::comm::ClientSocket::DefaultMaxConnectionDelay /* 200 ms*/), - a_numberOfClientSessionsPerServer(1), - a_freezeEndToEndOnSending(false) { + a_numberOfClientSessionsPerServer(1) { anna::diameter::sccs::activate(); a_realm = anna::functions::getDomainname(); a_host = anna::functions::getHostname(); @@ -89,7 +61,7 @@ ClientSession* Engine::allocateClientSession() throw() { return a_clientSessions void Engine::releaseClientSession(ClientSession *clientSession) throw() { a_clientSessionsRecycler.release(clientSession); } -void Engine::setCERandDWR(const anna::DataBlock & cer, const anna::DataBlock & dwr) throw(anna::RuntimeException) { +void Engine::setClientCERandDWR(const anna::DataBlock & cer, const anna::DataBlock & dwr) throw(anna::RuntimeException) { if(codec::functions::getCommandId(cer) != helpers::base::COMMANDID__Capabilities_Exchange_Request) { throw anna::RuntimeException("The message provided as 'CER' is not a Capabilities-Exchange-Request", ANNA_FILE_LOCATION); } @@ -102,18 +74,86 @@ void Engine::setCERandDWR(const anna::DataBlock & cer, const anna::DataBlock & d a_dwr = dwr; } -//void Engine::setCEAandDWA(const anna::DataBlock & cea, const anna::DataBlock & dwa) throw(anna::RuntimeException) { -// if (codec::functions::getCommandId(cea) != helpers::base::COMMANDID__Capabilities_Exchange_Answer) { -// throw anna::RuntimeException("The message provided as 'CEA' is not a Capabilities-Exchange-Answer", ANNA_FILE_LOCATION); -// } -// -// if (codec::functions::getCommandId(dwa) != helpers::base::COMMANDID__Device_Watchdog_Answer) { -// throw anna::RuntimeException("The message provided as 'DWA' is not a Device-Watchdog-Answer", ANNA_FILE_LOCATION); -// } -// -// a_cea = cea; -// a_dwa = dwa; -//} +void Engine::setClientCERandDWR(const std::string & cer, const std::string & dwr) throw(anna::RuntimeException) { + + // Check for base protocol codec engine: + if (!getBaseProtocolCodecEngine()) + throw anna::RuntimeException("Use diameter::comm::Engine::setBaseProtocolCodecEngine() to allow base protocol messages encoding, or use setClientCERandDWR(const anna::DataBlock & cer, const anna::DataBlock & dwr) which expect externally encoded messages", ANNA_FILE_LOCATION); + + // Build CER + // ::= < Diameter Header: 257, REQ > + // { Origin-Host } 264 diameterIdentity + // { Origin-Realm } 296 idem + // 1* { Host-IP-Address } 257, address + // { Vendor-Id } 266 Unsigned32 + // { Product-Name } 269 UTF8String + // [Origin-State-Id] 278 Unsigned32 + // * [ Supported-Vendor-Id ] 265 Unsigned32 + // * [ Auth-Application-Id ] 258 Unsigned32 + // * [Acct-Application-Id] 259 Unsigned32 + anna::diameter::codec::Message diameterCER(getBaseProtocolCodecEngine()); + int applicationId = 0 /*anna::diameter::helpers::APPID__3GPP_Rx*/; // Unsigned32 + std::string OH = getHost(); + std::string OR = getRealm(); + std::string hostIP = anna::functions::getHostnameIP(); // Address + int vendorId = anna::diameter::helpers::VENDORID__tgpp; // Unsigned32 + std::string productName = "ANNA Diameter Client"; // UTF8String + bool encodeDefault = false; + + if (cer != "") { + try { + diameterCER.loadXML(cer); + } catch(anna::RuntimeException &ex) { + //ex.trace(); + encodeDefault = true; + LOGWARNING(anna::Logger::warning("CER file not found or unable to parse. Encoding harcoded default version ...", ANNA_FILE_LOCATION)); + } + } + else { + encodeDefault = true; + } + + if(encodeDefault) { + diameterCER.setId(anna::diameter::helpers::base::COMMANDID__Capabilities_Exchange_Request); + diameterCER.setApplicationId(applicationId); + diameterCER.addAvp(anna::diameter::helpers::base::AVPID__Origin_Host)->getDiameterIdentity()->setValue(OH); + diameterCER.addAvp(anna::diameter::helpers::base::AVPID__Origin_Realm)->getDiameterIdentity()->setValue(OR); + diameterCER.addAvp(anna::diameter::helpers::base::AVPID__Host_IP_Address)->getAddress()->fromPrintableString(hostIP.c_str()); // supported by Address class, anyway is better to provide "1|" + diameterCER.addAvp(anna::diameter::helpers::base::AVPID__Vendor_Id)->getUnsigned32()->setValue(vendorId); + diameterCER.addAvp(anna::diameter::helpers::base::AVPID__Product_Name)->getUTF8String()->setValue(productName); + diameterCER.addAvp(anna::diameter::helpers::base::AVPID__Auth_Application_Id)->getUnsigned32()->setValue(applicationId); + } + + // Build DWR + // ::= < Diameter Header: 280, REQ > + // { Origin-Host } + // { Origin-Realm } + anna::diameter::codec::Message diameterDWR(getBaseProtocolCodecEngine()); + encodeDefault = false; + + if (dwr != "") { + try { + diameterDWR.loadXML(dwr); + } catch(anna::RuntimeException &ex) { + //ex.trace(); + encodeDefault = true; + LOGWARNING(anna::Logger::warning("DWR file not found or unable to parse. Encoding harcoded default version ...", ANNA_FILE_LOCATION)); + } + } + else { + encodeDefault = true; + } + + if(encodeDefault) { + diameterDWR.setId(anna::diameter::helpers::base::COMMANDID__Device_Watchdog_Request); + diameterDWR.setApplicationId(applicationId); + diameterDWR.addAvp(anna::diameter::helpers::base::AVPID__Origin_Host)->getDiameterIdentity()->setValue(OH); + diameterDWR.addAvp(anna::diameter::helpers::base::AVPID__Origin_Realm)->getDiameterIdentity()->setValue(OR); + } + + // Assignment for internal encoded versions: + setClientCERandDWR(diameterCER.code(), diameterDWR.code()); +} void Engine::setWatchdogPeriod(const anna::Millisecond & wp) throw(anna::RuntimeException) { if(wp < ClientSession::DefaultWatchdogPeriod) { @@ -254,7 +294,7 @@ throw(anna::RuntimeException) { result->a_engine = this; result->initializeStatisticConcepts(); - for(register int k = 0; k < a_numberOfClientSessionsPerServer; k++) + for(int k = 0; k < a_numberOfClientSessionsPerServer; k++) result->addClientSession(k); a_servers.insert(server_value_type(socket, result)); @@ -289,7 +329,7 @@ throw(anna::RuntimeException) { result->setWatchdogPeriod(a_watchdogPeriod); result->a_parent = server; result->a_socketId = socketId; - result->initializeSequences(); // después de asignar el server y el socketId (*) + result->initializeSequences(); // despu�s de asignar el server y el socketId (*) // (*) Las secuencias se basan en la semilla: srand(::time(NULL) + anna::functions::exclusiveHash(anna::functions::asString("%s:%d|%d", getAddress().c_str(), getPort(), a_socketId))); result->a_engine = this; clientSession_key key = ClientSession::getKey(server->getAddress(), server->getPort(), socketId); @@ -968,10 +1008,10 @@ void Engine::readDPA(anna::DataBlock &dpa, const anna::DataBlock & dpr) throw() // [Error-Message].................................(281,0) // *[Failed-AVP]....................................(279,0) try { - anna::diameter::codec::Message diameterDPA; - anna::diameter::codec::Avp avpRC; - anna::diameter::codec::Avp avpOH; - anna::diameter::codec::Avp avpOR; + anna::diameter::codec::Message diameterDPA(getBaseProtocolCodecEngine()); + anna::diameter::codec::Avp avpRC(getBaseProtocolCodecEngine()); + anna::diameter::codec::Avp avpOH(getBaseProtocolCodecEngine()); + anna::diameter::codec::Avp avpOR(getBaseProtocolCodecEngine()); // Message header diameterDPA.setId(anna::diameter::helpers::base::COMMANDID__Disconnect_Peer_Answer); diameterDPA.setVersion(1); @@ -996,7 +1036,10 @@ void Engine::readDPA(anna::DataBlock &dpa, const anna::DataBlock & dpr) throw() // Encode dpa = diameterDPA.code(); } catch(anna::RuntimeException &ex) { - ex.trace(); + std::string msg = ex.getText(); + msg += " | Use diameter::comm::Engine::setBaseProtocolCodecEngine() to allow internal base protocol messages encoding (unable to answer with DPA)"; + anna::Logger::error(msg, ANNA_FILE_LOCATION); + //throw anna::RuntimeException(msg, ANNA_FILE_LOCATION); } } @@ -1022,10 +1065,10 @@ void Engine::readCEA(anna::DataBlock &cea, const anna::DataBlock & cer) throw() // [Firmware-Revision].............................(267,0) // *[AVP]...........................................(0,0) try { - anna::diameter::codec::Message diameterCEA; - anna::diameter::codec::Avp avpRC; - anna::diameter::codec::Avp avpOH; - anna::diameter::codec::Avp avpOR; + anna::diameter::codec::Message diameterCEA(getBaseProtocolCodecEngine()); + anna::diameter::codec::Avp avpRC(getBaseProtocolCodecEngine()); + anna::diameter::codec::Avp avpOH(getBaseProtocolCodecEngine()); + anna::diameter::codec::Avp avpOR(getBaseProtocolCodecEngine()); // Message header diameterCEA.setId(anna::diameter::helpers::base::COMMANDID__Capabilities_Exchange_Answer); diameterCEA.setVersion(1); @@ -1059,7 +1102,10 @@ void Engine::readCEA(anna::DataBlock &cea, const anna::DataBlock & cer) throw() // Encode cea = diameterCEA.code(); } catch(anna::RuntimeException &ex) { - ex.trace(); + std::string msg = ex.getText(); + msg += " | Use diameter::comm::Engine::setBaseProtocolCodecEngine() to allow internal base protocol messages encoding (unable to answer with CEA)"; + anna::Logger::error(msg, ANNA_FILE_LOCATION); + //throw anna::RuntimeException(msg, ANNA_FILE_LOCATION); } } @@ -1075,10 +1121,10 @@ void Engine::readDWA(anna::DataBlock &dwa, const anna::DataBlock & dwr) throw() // *[Failed-AVP]....................................(279,0) // [Origin-State-Id]...............................(278,0) try { - anna::diameter::codec::Message diameterDWA; - anna::diameter::codec::Avp avpRC; - anna::diameter::codec::Avp avpOH; - anna::diameter::codec::Avp avpOR; + anna::diameter::codec::Message diameterDWA(getBaseProtocolCodecEngine()); + anna::diameter::codec::Avp avpRC(getBaseProtocolCodecEngine()); + anna::diameter::codec::Avp avpOH(getBaseProtocolCodecEngine()); + anna::diameter::codec::Avp avpOR(getBaseProtocolCodecEngine()); // Message header diameterDWA.setId(anna::diameter::helpers::base::COMMANDID__Device_Watchdog_Answer); diameterDWA.setVersion(1); @@ -1103,7 +1149,10 @@ void Engine::readDWA(anna::DataBlock &dwa, const anna::DataBlock & dwr) throw() // Encode dwa = diameterDWA.code(); } catch(anna::RuntimeException &ex) { - ex.trace(); + std::string msg = ex.getText(); + msg += " | Use diameter::comm::Engine::setBaseProtocolCodecEngine() to allow internal base protocol messages encoding (unable to answer with DWA)"; + anna::Logger::error(msg, ANNA_FILE_LOCATION); + //throw anna::RuntimeException(msg, ANNA_FILE_LOCATION); } } @@ -1115,4 +1164,12 @@ void Engine::resetStatistics() throw() { localServer(it)->resetStatistics(); } +void Engine::do_initialize() throw(RuntimeException) { + LOGMETHOD(anna::TraceMethod tttm("diameter::comm::Engine", "do_initialize", ANNA_FILE_LOCATION)); + LOGDEBUG(anna::Logger::debug("Nothing special done on component initialization", ANNA_FILE_LOCATION)); +} +void Engine::lazyInitialize() throw(RuntimeException) { + LOGMETHOD(anna::TraceMethod tttm("diameter::comm::Engine", "lazyInitialize", ANNA_FILE_LOCATION)); + anna::app::Component::initialize(); // this will invoke do_initialize +}