X-Git-Url: https://git.teslayout.com/public/public/public/?a=blobdiff_plain;f=source%2Fdiameter.comm%2FSession.cpp;h=4fb5ab49cb4a2980e0493caf84a28dadfe6b4e42;hb=5a6cba5fde2b2f538a7515f8293cc0a8d9589dfa;hp=da2df67c768701916d4536d04c7fe49b79934a13;hpb=4e12ac57e93c052f716a6305ad8fc099c45899d1;p=anna.git diff --git a/source/diameter.comm/Session.cpp b/source/diameter.comm/Session.cpp index da2df67..4fb5ab4 100644 --- a/source/diameter.comm/Session.cpp +++ b/source/diameter.comm/Session.cpp @@ -1,37 +1,9 @@ -// ANNA - Anna is Not 'N' Anymore -// -// (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo -// -// https://bitbucket.org/testillano/anna -// -// 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 Google Inc. 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 @@ -88,7 +60,7 @@ Session::Session(const char *className, const char *timerName) : anna::timex::Ti initialize(); } -void Session::initialize() throw() { +void Session::initialize() { a_state = State::Closed; a_socketId = 0; a_lastIncomingActivityTime = (anna::Millisecond)0; @@ -102,7 +74,7 @@ void Session::initialize() throw() { //Session::~Session() {;} -void Session::initializeSequences() throw() { +void Session::initializeSequences() { // Sequences // // Hop-by-Hop Identifier @@ -137,13 +109,13 @@ void Session::initializeSequences() throw() { // affect any state that was set when the original request was // processed. Duplicate answer messages that are to be locally // consumed (see Section 6.2) SHOULD be silently discarded. - srand(::time(NULL) + anna::functions::exclusiveHash(anna::functions::asString("%s:%d|%d", getAddress().c_str(), getPort(), a_socketId))); + srand(::time(NULL) + anna::functions::hash(anna::functions::asString("%s:%d|%d", getAddress().c_str(), getPort(), a_socketId).c_str())); a_nextHopByHop = rand(); a_nextEndToEnd = ((::time(NULL) & 0xFFF) << 20) + (rand() & 0xFFFFF); } void Session::sendDPA() -throw(anna::RuntimeException) { +noexcept(false) { LOGMETHOD(anna::TraceMethod traceMethod("anna::diameter::comm::Session", "sendDPA", ANNA_FILE_LOCATION)); anna::DataBlock dpa(true); a_engine->readDPA(dpa, a_dpr.getBody()); // Asume that DPA is valid ... @@ -166,7 +138,7 @@ throw(anna::RuntimeException) { activateActionTimer(anna::diameter::comm::Timer::Type::SessionUnbind); } -void Session::setState(State::_v state) throw() { +void Session::setState(State::_v state) { LOGDEBUG( if(state != a_state) { @@ -181,7 +153,7 @@ void Session::setState(State::_v state) throw() { } -void Session::activateActionTimer(const anna::diameter::comm::Timer::Type::_v type) throw() { +void Session::activateActionTimer(const anna::diameter::comm::Timer::Type::_v type) { LOGMETHOD(anna::TraceMethod traceMethod("anna::diameter::comm::Session", "activateActionTimer", ANNA_FILE_LOCATION)); cancelTimer(); // Session timer @@ -197,7 +169,7 @@ void Session::activateActionTimer(const anna::diameter::comm::Timer::Type::_v ty } -void Session::cancelActionTimer() throw() { +void Session::cancelActionTimer() { LOGMETHOD(anna::TraceMethod traceMethod("anna::diameter::comm::Session", "cancelActionTimer", ANNA_FILE_LOCATION)); if(a_actionTimer) { @@ -216,7 +188,7 @@ void Session::cancelActionTimer() throw() { } -void Session::activateTimer() throw() { +void Session::activateTimer() { LOGMETHOD(anna::TraceMethod traceMethod("anna::diameter::comm::Session", "activateTimer", ANNA_FILE_LOCATION)); cancelActionTimer(); @@ -237,7 +209,7 @@ void Session::activateTimer() throw() { } -void Session::cancelTimer() throw() { +void Session::cancelTimer() { LOGMETHOD(anna::TraceMethod traceMethod("anna::diameter::comm::Session", "cancelTimer", ANNA_FILE_LOCATION)); if(isActive()) { @@ -263,19 +235,23 @@ void Session::cancelTimer() throw() { // Se invoca desde diameter::comm::Timer //------------------------------------------------------------------------- void Session::expireResponse(diameter::comm::Response* response) -throw() { +{ LOGMETHOD(anna::TraceMethod traceMethod("anna::diameter::comm::Session", "expireResponse", ANNA_FILE_LOCATION)); bool doUnbind = false; + bool doRetransmission = false; - // Quitar el OnExpiry: no tiene sentido habiendo keep-alive (DWR) if(response->getClassCode() != ClassCode::Bind) { if(response->getRequest()->getOnExpiry() == Message::OnExpiry::Abandon) { a_onDisconnect = OnDisconnect::IgnorePendings; // Abandon is not graceful doUnbind = true; } + else if(response->getRequest()->getOnExpiry() == Message::OnExpiry::Retransmit) { + doRetransmission = true; + } } else doUnbind = true; // (*) + try { response->setMessage(NULL); eventResponse(*response); @@ -291,19 +267,37 @@ throw() { setState(State::Bound); } + if(doRetransmission) { + diameter::comm::Message *request = const_cast(response->getRequest()); + int retries = request->getRetries(); + if (retries > 0) { + retries--; + request->setRetries(retries); + LOGDEBUG + ( + std::string msg(asString()); + msg += anna::functions::asString(" | Retransmission initiated for request with HopByHop: %u; remaining %d retries", response->getHopByHop(), retries); + anna::Logger::debug(msg, ANNA_FILE_LOCATION); + ); + diameter::codec::functions::setPotentiallyReTransmittedMessageBit(*request); + eventRequestRetransmission(request); + send(request); + } + } + response_erase(response); if(doUnbind) unbind(); } -void Session::finalize() throw() { +void Session::finalize() { LOGMETHOD(anna::TraceMethod traceMethod("anna::diameter::comm::Session", "finalize", ANNA_FILE_LOCATION)); setState(State::Closed); cancelTimer(); // Session timer cancelActionTimer(); // Action timer eventPeerShutdown(); /////////////////////////////////////////////////////////////////////// -// Notificar la finalización de las respuestas pendientes de recibir // +// Notificar la finalizaci�n de las respuestas pendientes de recibir // /////////////////////////////////////////////////////////////////////// // RFC 3588 - 5.5.4. Failover and Failback Procedures // @@ -359,7 +353,7 @@ void Session::finalize() throw() { } void Session::response_add(Response* response) -throw() { +{ a_responses.add(response); response->setSession(this); @@ -371,7 +365,7 @@ throw() { } void Session::response_erase(Response* response) -throw() { +{ a_responses.erase(response); Response::release(response); @@ -383,7 +377,7 @@ throw() { } Response* Session::response_find(const HopByHop hopByHop) -throw(anna::RuntimeException) { +noexcept(false) { diameter::comm::Response* result = a_responses.find(hopByHop); // if (result == NULL) { // string msg(asString()); @@ -395,7 +389,7 @@ throw(anna::RuntimeException) { } std::string Session::asString() const -throw() { +{ string result(a_className); result += " { "; result += anna::timex::Timer::asString(); @@ -426,7 +420,7 @@ throw() { } anna::xml::Node* Session::asXML(anna::xml::Node* parent) const -throw() { +{ //parent = anna::timex::Timer::asXML(parent); anna::xml::Node* result = parent->createChild("diameter.comm.Session"); result->createAttribute("SocketId", anna::functions::asString(a_socketId)); @@ -445,7 +439,6 @@ throw() { // Messages anna::xml::Node* messages = result->createChild("diameter.comm.Messages"); - const Response* response; const Message* message; for(const_response_iterator ii = response_begin(), maxii = response_end(); ii != maxii; ii ++) { @@ -457,13 +450,13 @@ throw() { } const char* Session::asText(const State::_v state) -throw() { +{ static const char* text [] = { "Closed", "WaitingBind", "Bound", "Failover", "Suspect", "WaitingDPA", "Disconnecting", "Closing" }; return text [state]; } const char* Session::asText(const OnDisconnect::_v onDisconnect) -throw() { +{ static const char* text [] = { "IgnorePendings", "WaitPendings" }; return text [onDisconnect]; } @@ -471,7 +464,7 @@ throw() { HopByHop Session::SortById::value(const Response* response) -throw() { +{ return response->getHopByHop(); } @@ -479,7 +472,7 @@ throw() { //------------------------------------------------------------------------------ //---------------------------------------- Session::updateIncomingActivityTime() //------------------------------------------------------------------------------ -void Session::updateIncomingActivityTime() throw() { +void Session::updateIncomingActivityTime() { a_lastIncomingActivityTime = anna::functions::millisecond(); LOGDEBUG ( @@ -493,7 +486,7 @@ void Session::updateIncomingActivityTime() throw() { //------------------------------------------------------------------------------ //---------------------------------------- Session::updateOutgoingActivityTime() //------------------------------------------------------------------------------ -void Session::updateOutgoingActivityTime(void) throw() { +void Session::updateOutgoingActivityTime(void) { a_lastOutgoingActivityTime = anna::functions::millisecond(); LOGDEBUG ( @@ -502,4 +495,3 @@ void Session::updateOutgoingActivityTime(void) throw() { anna::Logger::debug(msg, ANNA_FILE_LOCATION); ); } -