Fix local server for multiple applications
[anna.git] / include / anna / diameter.comm / Session.hpp
index e3a8081..de7e569 100644 (file)
@@ -1,37 +1,9 @@
-// ANNA - Anna is Not Nothingness 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 //
 
 
 #ifndef anna_diameter_comm_Session_hpp
@@ -73,6 +45,7 @@ namespace comm {
 class Timer;
 class Engine;
 class Response;
+class OriginHost;
 
 
 
@@ -115,16 +88,16 @@ public:
 
 
       // Cierre de iniciativa local:
-      // 1. Envio DPR al PCRF y me pongo en estado 'WaitingDPA'. En este estado no habrá keep-alive DWR/DWA.
+      // 1. Envio DPR al PCRF y me pongo en estado 'WaitingDPA'. En este estado no habr keep-alive DWR/DWA.
       // 2. No dejo pasar nuevas peticiones (BLOCK-SEND).
       // 3. Cierro al recibir el DPA.
       // 4. Si expira el DPA, tambien cierro.
       WaitingDPA, /**< After requesting DPR to server, send is blocked over the session: when DPA arrives (or answer expires) the session is closed */
 
       // Cierre de iniciativa remota:
-      // 1. Recibo DPR del PCRF y me pongo en estado 'Disconnecting'. En este estado no habrá keep-alive DWR/DWA.
+      // 1. Recibo DPR del PCRF y me pongo en estado 'Disconnecting'. En este estado no habr keep-alive DWR/DWA.
       // 2. No dejo pasar nuevas peticiones (BLOCK-SEND).
-      // 3. Espero cursar las peticiones pendientes (a más tardar, será una expiracion Tx desde la recepcion del DPR).
+      // 3. Espero cursar las peticiones pendientes (a m�s tardar, ser� una expiracion Tx desde la recepcion del DPR).
       // 4. Envio DPA y activo un temporizador de cierre local (2*Tx) como proteccion (por si el servidor no cierra).
       Disconnecting, /**< After receiving DPR from server, send is blocked over the session: when no pending requests, DPA is sent to the server who will close connection */
 
@@ -137,7 +110,7 @@ public:
      Session state.
      \return State for this session.
   */
-  State::_v getState() const throw() { return a_state; }
+  State::_v getState() const { return a_state; }
 
   /**
    * Defines behaviour on 'Disconnecting' state, about #unbind action (ignore/wait pending answers)
@@ -148,13 +121,13 @@ public:
    * Sets behaviour on 'Disconnecting' state, about #unbind action (ignore/wait pending answers).
    * \param onDisconnect Behaviour on 'Disconnecting' state, about #unbind action (ignore/wait pending answers).
    */
-  void setOnDisconnect(const OnDisconnect::_v onDisconnect)  throw() { a_onDisconnect = onDisconnect; }
+  void setOnDisconnect(const OnDisconnect::_v onDisconnect)  { a_onDisconnect = onDisconnect; }
 
   /**
    * Returns behaviour on 'Disconnecting' state, about #unbind action (ignore/wait pending answers).
    * \return behaviour on 'Disconnecting' state, about #unbind action (ignore/wait pending answers).
    */
-  OnDisconnect::_v getOnDisconnect() const throw() { return a_onDisconnect; }
+  OnDisconnect::_v getOnDisconnect() const { return a_onDisconnect; }
 
 
 
@@ -162,32 +135,32 @@ public:
      Diameter server address, ip or hostname (remote for client-session, local for server-session).
      \return Diameter server address (remote for client-session, local for server-session).
   */
-  virtual const std::string& getAddress() const throw() = 0;
+  virtual const std::string& getAddress() const  = 0;
 
   /**
      Diameter server listen port (remote for client-session, local for server-session).
      \return Diameter server listen port (remote for client-session, local for server-session).
   */
-  virtual int getPort() const throw() = 0;
+  virtual int getPort() const  = 0;
 
   /**
      Socket id.
      \return Socket id.
   */
-  int getSocketId() const throw() { return a_socketId; }
+  int getSocketId() const { return a_socketId; }
 
   /**
      Returns the next hop-by-hop which will be used over the diameter session to send a message
      It is recommended to fix the message with this value (or store along with the message),
      for application context identification purposes
   */
-  const HopByHop & getNextHopByHop() const throw() { return a_nextHopByHop; }
+  const HopByHop & getNextHopByHop() const { return a_nextHopByHop; }
 
   /** Returns the next end-to-end which will be used over the diameter session to send a message
       It is recommended to fix the message with this value (or store along with the message),
       for application context identification purposes
   */
-  const EndToEnd & getNextEndToEnd() const throw() { return a_nextEndToEnd; }
+  const EndToEnd & getNextEndToEnd() const { return a_nextEndToEnd; }
 
 
   /**
@@ -197,20 +170,20 @@ public:
 
      Timers are internally managed and automatically activated.
   */
-  void setClassCodeTimeout(const ClassCode::_v v, const anna::Millisecond & millisecond) throw() { a_timeouts [v] = millisecond;  }
+  void setClassCodeTimeout(const ClassCode::_v v, const anna::Millisecond & millisecond) { a_timeouts [v] = millisecond;  }
 
   /**
    * Timeout configured for class code \em v requests.
    * \return Timeout configured for class code \em v requests.
    */
-  anna::Millisecond getClassCodeTimeout(const ClassCode::_v v) const throw() { return a_timeouts [v]; }
+  anna::Millisecond getClassCodeTimeout(const ClassCode::_v v) const { return a_timeouts [v]; }
 
 
   /**
      Returns \em true when diameter server is connected (application level) \em false in other case.
      \return \em true when diameter server is connected (application level) \em false in other case.
   */
-  bool isBound() const throw() { return a_state == State::Bound; }
+  bool isBound() const { return a_state == State::Bound; }
 
 
 // Envia el mensaje recibido como parametro al servidor con el que estamos conectados mediante esta
@@ -218,19 +191,19 @@ public:
 //
 // En caso de enviar una peticion se activara automaticamente un temporizador. Si este llegara a caducar
 // se cancelara la busqueda y se invocara al metodo Session::eventResponse indicado que se ha producido
-// un error de temporización. La duracion del temporizador sera la establecida por
+// un error de temporizacin. La duracion del temporizador sera la establecida por
 // diameter::comm::TimerManager::setTimeout o el valor defecto.
 //
 // \param message Mensaje a enviar al servidor diameter con el que estamos conectados.
 // @return Diameter response reference asociated to a request. NULL if answer sent.
 // \warning Solo se podra hacer uso de este metodo cuando el metodo #isBound devuelva \em true.
-  virtual const Response* send(const Message* message) throw(anna::RuntimeException) = 0;
-  const Response* send(const Message& message) throw(anna::RuntimeException) { return send(&message); }
+  virtual const Response* send(const Message* message) noexcept(false) = 0;
+  const Response* send(const Message& message) noexcept(false) { return send(&message); }
 
 // Desconecta del extremo remoto
-// Se notifica la terminación de cada una de las peticiones pendientes invocando al método Session::eventResponse
-// \warning Después de invocar a este método habría que volver a iniciar una sesion.
-  virtual bool unbind(bool forceDisconnect /* se usa en timer, para el actionTimer del tipo SessionUnbind, etc. */ = false) throw(anna::RuntimeException) = 0;
+// Se notifica la terminaci�n de cada una de las peticiones pendientes invocando al m�todo Session::eventResponse
+// \warning Despu�s de invocar a este m�todo habr�a que volver a iniciar una sesion.
+  virtual bool unbind(bool forceDisconnect /* se usa en timer, para el actionTimer del tipo SessionUnbind, etc. */ = false) noexcept(false) = 0;
   // returns true if done at call time (no pendings or ignore pendings, except Disconnecting state by mean DPR/DPA)
 
 
@@ -239,21 +212,21 @@ public:
 
      @return Last incoming activity timestamp.
   */
-  const anna::Millisecond & getLastIncomingActivityTime() const throw() { return a_lastIncomingActivityTime; }
+  const anna::Millisecond & getLastIncomingActivityTime() const { return a_lastIncomingActivityTime; }
 
   /**
      Gets the timestamp for last outgoing activity over the session.
 
      @return Last outgoing activity timestamp.
   */
-  const anna::Millisecond & getLastOutgoingActivityTime() const throw() { return a_lastOutgoingActivityTime; }
+  const anna::Millisecond & getLastOutgoingActivityTime() const { return a_lastOutgoingActivityTime; }
 
   /**
      Gets the number of requests messages over-the-air.
 
      @return OTA messages.
   */
-  int getOTARequests() const throw() { return a_responses.size(); }
+  int getOTARequests() const { return a_responses.size(); }
 
 
   /**
@@ -261,7 +234,7 @@ public:
 
      @return Idle state.
   */
-  bool idle() const throw() { return (getOTARequests() == 0); }
+  bool idle() const { return (getOTARequests() == 0); }
 
 
   /**
@@ -275,13 +248,13 @@ public:
 
      @defer Delayed notification for orphan request due to transport failures
   */
-  void notifyOrphansOnExpiration(bool defer = true) throw() { a_notifyOrphansOnExpiration = defer; }
+  void notifyOrphansOnExpiration(bool defer = true) { a_notifyOrphansOnExpiration = defer; }
 
   /**
      Class string representation
      \return String with relevant information for this instance.
   */
-  virtual std::string asString() const throw();
+  virtual std::string asString() const ;
 
 
   /**
@@ -289,13 +262,10 @@ public:
      \param parent Parent XML node on which hold this instance information.
      \return XML document with relevant information for this instance.
   */
-  virtual anna::xml::Node* asXML(anna::xml::Node* parent) const throw();
+  virtual anna::xml::Node* asXML(anna::xml::Node* parent) const ;
 
 protected:
 
-  // Auxiliary messages:
-  Message a_dpr;
-
   // Internal, traces, etc.
   const char *a_className;
 
@@ -303,19 +273,18 @@ protected:
   int a_socketId; // multiple connection functionality
   State::_v a_state;
   OnDisconnect::_v a_onDisconnect;
-  Engine *a_engine;
   anna::diameter::comm::Timer *a_actionTimer;
 
   // Sequencing
   HopByHop a_nextHopByHop;
   EndToEnd a_nextEndToEnd;
-  virtual void initialize() throw();
-  void initializeSequences() throw(); // debe invocarse despues de haber asignado el a_parent
-  void generateNextSequences() throw() { a_nextHopByHop++; a_nextEndToEnd++; }
+  virtual void initialize() ;
+  void initializeSequences() ; // debe invocarse despues de haber asignado el a_parent
+  void generateNextSequences() { a_nextHopByHop++; a_nextEndToEnd++; }
 
   // Context Responses
   struct SortById {
-    static HopByHop value(const Response*) throw();
+    static HopByHop value(const Response*) ;
   };
   typedef anna::SortedVector <Response, SortById, HopByHop> response_container;
   typedef response_container::iterator response_iterator;
@@ -323,27 +292,27 @@ protected:
   response_container a_responses;
   bool a_notifyOrphansOnExpiration;
 
-  void response_add(Response* response) throw();
-  void response_erase(Response* response) throw();
-  Response* response_find(const HopByHop hopByHop) throw(anna::RuntimeException);
+  void response_add(Response* response) ;
+  void response_erase(Response* response) ;
+  Response* response_find(const HopByHop hopByHop) noexcept(false);
 
-  response_iterator response_begin() throw() { return a_responses.begin(); }
-  response_iterator response_end() throw() { return a_responses.end(); }
-  static Response* response(response_iterator ii) throw() { return response_container::data(ii); }
+  response_iterator response_begin() { return a_responses.begin(); }
+  response_iterator response_end() { return a_responses.end(); }
+  static Response* response(response_iterator ii) { return response_container::data(ii); }
 
-  const_response_iterator response_begin() const throw() { return a_responses.begin(); }
-  const_response_iterator response_end() const throw() { return a_responses.end(); }
-  static const Response* response(const_response_iterator ii) throw() { return response_container::data(ii); }
+  const_response_iterator response_begin() const { return a_responses.begin(); }
+  const_response_iterator response_end() const { return a_responses.end(); }
+  static const Response* response(const_response_iterator ii) { return response_container::data(ii); }
 
   // Activity
   anna::timex::Engine* a_timeController;
   anna::Millisecond a_lastIncomingActivityTime;   // last unix timestamp (in milliseconds) when message reception was managed over the session
   anna::Millisecond a_lastOutgoingActivityTime;   // last unix timestamp (in milliseconds) when message sending was managed over the session
-  virtual void updateIncomingActivityTime() throw();
-  virtual void updateOutgoingActivityTime() throw();
+  virtual void updateIncomingActivityTime() ;
+  virtual void updateOutgoingActivityTime() ;
 
   // Self-timer expiration handler
-  virtual void expire(anna::timex::Engine *timeController) throw(anna::RuntimeException) {;}
+  virtual void expire(anna::timex::Engine *timeController) noexcept(false) {;}
 
   // Timming:
   anna::Millisecond a_timeouts [ClassCode::Max];
@@ -354,40 +323,58 @@ protected:
 
      When notified, ANNA.diameter.comm generates an diameter::comm::ClientSession::eventResponse for every request with pending answers.
   */
-  virtual void eventPeerShutdown() throw() = 0;
+  virtual void eventPeerShutdown()  = 0;
+
+  /**
+     Handler about a request retransmission over the session.
+
+     \param request Message retransmitted
+  */
+  virtual void eventRequestRetransmission(Message *request)  = 0;
 
   /**
      Handler for diameter session responses
 
      \param response Answer data block object for corresponding diameter request
+     \param myNode Own origin host
   */
-  virtual void eventResponse(const Response& response) throw(anna::RuntimeException) = 0;
+  virtual void eventResponse(const Response& response, const anna::diameter::comm::OriginHost *myNode) noexcept(false) = 0;
 
   /**
      Handler for diameter session requests
 
      \param request Request container object for corresponding diameter reception
+     \param myNode Own origin host
   */
-  virtual void eventRequest(const anna::DataBlock& request) throw(anna::RuntimeException) = 0;
-  //void eventRequest(const Message& request) throw(anna::RuntimeException);
+  virtual void eventRequest(const anna::DataBlock& request, const anna::diameter::comm::OriginHost *myNode) noexcept(false) = 0;
+  //void eventRequest(const Message& request) noexcept(false);
 
 
   /**
      Handler for diameter session responses out of context
 
      \param response Answer data block object without context match
+     \param myNode Own origin host
+  */
+  virtual void eventUnknownResponse(const anna::DataBlock& response, const anna::diameter::comm::OriginHost *myNode) noexcept(false) = 0;
+
+  /**
+     Handler for diameter session Disconnect-Peer-Answer messages
+
+     \param response Answer data block object without context match
+     \param myNode Own origin host
   */
-  virtual void eventUnknownResponse(const anna::DataBlock& response) throw(anna::RuntimeException) = 0;
+  virtual void eventDPA(const anna::DataBlock& response, const anna::diameter::comm::OriginHost *myNode) noexcept(false) = 0;
 
 
 
   /**
   * Handlers
   */
-  virtual void receive(const anna::comm::Message& message) throw(anna::RuntimeException) = 0;
+  virtual void receive(const anna::comm::Message& message) noexcept(false) = 0;
 //PROTOCOL ERRORS
-//The errors at the protocol level are reported in response messages that contain the \93E\94 bit and the error code in the AVP result-Code (various errors having been produced only the first one of them is reported). Examples of these errors are:
-//An unrecognized AVP with the \93M\94 bit is received.
+//The errors at the protocol level are reported in response messages that contain the �E� bit and the error code in the AVP result-Code (various errors having been produced only the first one of them is reported). Examples of these errors are:
+//An unrecognized AVP with the �M� bit is received.
 //An AVP is received with an unrecognized value (in the AVP failed-AVP indicates the attribute that the error caused).
 //An mandatory AVP is not received.
 //Length of operation incorrect.
@@ -399,31 +386,30 @@ protected:
 
 
 
-  virtual void finalize() throw(); // invoked from ClientSessionReceiver::eventBreakConnection()
+  virtual void finalize() ; // invoked from ClientSessionReceiver::eventBreakConnection()
 
 
-  virtual void expireResponse(Response*) throw();
-  void sendDPA() throw(anna::RuntimeException);
-  void activateActionTimer(const anna::diameter::comm::Timer::Type::_v type) throw();
-  void cancelActionTimer() throw();
-  void activateTimer() throw(); // Session timer
-  void cancelTimer() throw(); // Session timer
-  virtual void timerStopped() throw() {;}
-  virtual void timerStarted() throw() {;}
+  virtual void expireResponse(Response*) ;
+  void sendDPA(const Engine *commEngine, const anna::DataBlock &dprDataBlock) noexcept(false);
+  void activateActionTimer(const anna::diameter::comm::Timer::Type::_v type) ;
+  void cancelActionTimer() ;
+  void activateTimer() ; // Session timer
+  void cancelTimer() ; // Session timer
+  virtual void timerStopped() {;}
+  virtual void timerStarted() {;}
 
 
-  virtual void setState(State::_v state) throw();
+  virtual void setState(State::_v state) ;
 
   //anna::diameter::comm::Timer *getActionTimer() const { return (a_actionTimer); }
 
 
   // helpers
-  static const char* asText(const State::_v) throw();
-  static const char* asText(const OnDisconnect::_v) throw();
+  static const char* asText(const State::_v) ;
+  static const char* asText(const OnDisconnect::_v) ;
 
 
   friend class anna::diameter::comm::Timer;
-  friend class Engine;
   friend class Response;
 };