1 // ANNA - Anna is Not Nothingness Anymore //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
9 #ifndef anna_diameter_comm_Engine_hpp
10 #define anna_diameter_comm_Engine_hpp
19 #include <anna/app/Component.hpp>
20 #include <anna/core/util/Recycler.hpp>
22 #include <anna/diameter/codec/Engine.hpp>
23 #include <anna/diameter.comm/Server.hpp>
24 #include <anna/diameter.comm/ServerSession.hpp>
25 #include <anna/config/defines.hpp>
26 #include <anna/diameter.comm/ClientSession.hpp>
27 #include <anna/diameter.comm/ServerSession.hpp>
33 //------------------------------------------------------------------------------
34 //---------------------------------------------------------------------- #define
35 //------------------------------------------------------------------------------
64 * General manager for connections to several diameter servers and from diameter clients.
66 * Optimizes creation, finding and releasing of established client-sessions to a certain number of
67 * diameter servers through entities.
68 * Optimizes creation, finding and releasing of established server-sessions from a certain number of
69 * diameter clients through local servers.
71 * Implementation example:
75 * class MyEngine : public diameter::comm::Engine {
80 * anna::Recycler<MyEntity> a_entities;
82 * anna::diameter::comm::Entity* allocateEntity () throw () { return a_entities.create (); }
84 * void releaseEntity (anna::diameter::comm::Entity* entity) throw () {
85 * MyEntity* aux = static_cast <MyEntity*> (entity);
86 * a_entities.release (aux);
90 * anna::diameter::comm::LocalServer* allocateLocalServer () throw () { return a_localServers.create (); }
92 * void releaseLocalServer (anna::diameter::comm::LocalServer* localServer) throw () {
93 * MyLocalServer* aux = static_cast <MyLocalServer*> (localServer);
94 * a_localServers.release (aux);
100 class Engine : public anna::app::Component {
104 Diameter application node origin realm
106 @param originRealmName Used to configure the Origin-Realm for outgoing messages.
107 If not configured or empty string provided, host domainname will be set.
109 void setOriginRealmName(const std::string & originRealmName) throw();
112 Diameter application origin host
114 @param originHostName Used to configure the Origin-Host for outgoing messages.
115 If not configured or empty string provided, hostname (system name) will be set.
117 void setOriginHostName(const std::string & originHostName) throw();
120 Gets the configured diameter application node origin realm
122 @return Diameter application node origin realm
124 const std::string & getOriginRealmName() const throw() { return a_originRealm; }
127 Gets the configured diameter application origin host
129 @return Diameter application node origin host
131 const std::string & getOriginHostName() const throw() { return a_originHost; }
135 * Propagate auto recovery configuration to entities within engine. Recovery period is configured at
136 * #anna::comm::Communicator::setRecoveryTime. All the client client-sessions created throught #createEntity,
137 * will be created based on the engine auto-recovery value (enable by default). But you could access entities,
138 * servers or client-sessions independently to change this behaviour.
140 * @param autoRecovery Auto recovery indicator. True by default.
142 void raiseAutoRecovery(bool autoRecovery = true) throw(anna::RuntimeException);
145 * Returns automatic bind indicator for client-sessions. By default \em true will be used.
146 * \return Value for automatic connection bind.
148 bool getAutoBind() const throw() { return a_autoBind; }
151 * Sets automatic connection bind indicator for client-sessions. If not asigned, it will be \em true.
152 * \param autoBind Value for automatic connection bind.
154 * In order to change bind timer, first client-session must be created without autobind, modify time
155 * parameter and then invoking bind.
157 void setAutoBind(const bool autoBind) throw() { a_autoBind = autoBind; }
160 Sets the milliseconds wait to achieve a client connection to server by mean connect primitive.
161 This is a general value for born client-sessions over engine. Particular configuration could be done
162 through #ClientSession::setMaxConnectionDelay.
164 \param maxConnectionDelay Milliseconds wait to get connection
166 void setMaxConnectionDelay(const anna::Millisecond & maxConnectionDelay) throw() { a_maxConnectionDelay = maxConnectionDelay; }
169 Gets the milliseconds wait to achieve a client connection to server by mean connect primitive.
170 Returns the global engine value, but it could be overwritten through each client session (#ClientSession::setMaxConnectionDelay).
171 Default value is 'anna::comm::ClientSocket::DefaultMaxConnectionDelay'.
173 \return Milliseconds wait to get connection
175 const anna::Millisecond & getMaxConnectionDelay() throw() { return a_maxConnectionDelay; }
178 * Binds engine entities.
180 * @return Returns true if all client-session were successfully bound
182 bool bind() throw(anna::RuntimeException);
185 * Sets CER and DWR diameter messages to be used over created client-sessions.
186 * Its recommended to set this global configuration although it is possible to configure each client-session separately.
188 * @param cer Capabilities-Exchange-Request message (encoded) for the client-sessions bind.
189 * @param dwr Device-Watchdog-Request message (encoded) for the client-sessions keep-alive.
191 void setClientCERandDWR(const anna::DataBlock & cer, const anna::DataBlock & dwr) throw(anna::RuntimeException);
194 * Sets CER and DWR diameter messages to be used over created client-sessions. If empty string is provided for CER and/or DWR, default version will be configured.
195 * Its recommended to set this global configuration although it is possible to configure each client-session separately.
197 * @param cer Capabilities-Exchange-Request xml message path file for the client-sessions bind. If empty string is provided (default), a default version for CER will be encoded.
198 * @param dwr Device-Watchdog-Request xml message path file for the client-sessions keep-alive. If empty string is provided (default), a default version for DWR will be encoded.
200 void setClientCERandDWR(const std::string & cer = "", const std::string & dwr = "") throw(anna::RuntimeException);
203 * Sets the watchdog period (DWR) for client-sessions.
204 * Its recommended to set this global configuration although it is possible to configure each client-session separately.
206 * @param wp Watchdog period.
208 void setWatchdogPeriod(const anna::Millisecond & wp) throw(anna::RuntimeException);
211 * Gets the number of client-sessions per server.
212 * \return numberOfClientSessionsPerServer Number of client-sessions per server.
214 int getNumberOfClientSessionsPerServer() const throw() { return a_numberOfClientSessionsPerServer; }
217 * Sets the number of client-sessions per server.
218 * Its recommended to set this global configuration although it is possible to configure each client-session separately.
219 * \param numberOfClientSessionsPerServer Number of client-sessions per server.
221 void setNumberOfClientSessionsPerServer(int numberOfClientSessionsPerServer) throw() { a_numberOfClientSessionsPerServer = numberOfClientSessionsPerServer; }
225 * Returns client-session instance identified by (address, port, socketId) provided.
227 * \param addr Diameter server address (ip or hostname).
228 * \param port Diameter server port.
229 * @param socketId Diameter server socket id.
230 * \param emode Action when no client-session is found with provided parameters (Throw/Ignore).
232 * \return The client-session instance identified by (address, port, socketId) provided.
234 * \warning If no client-session found, an exception is launched by default.
236 ClientSession* findClientSession(const std::string & addr, int port, int socketId, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) throw(anna::RuntimeException);
240 * Same as #findClientSession, but providing client session key (<address>:<port>|<socket id>)
242 ClientSession* findClientSession(const std::string & key, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) throw(anna::RuntimeException);
246 * Returns server instance identified by pair (address, port) provided.
248 * \param addr Diameter server address (ip or hostname).
249 * \param port Diameter server port.
250 * \param emode Action when no client-session is found with provided parameters (Throw/Ignore).
252 * \return The server instance identified by pair (address, port) provided.
254 * \warning If no server found, an exception is launched by default.
256 Server* findServer(const std::string & addr, int port, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) throw(anna::RuntimeException);
259 * Returns entity instance identified by internal index.
261 * \param socketList Diameter entity servers list.
262 * \param emode Action when no client-session is found with provided parameters (Throw/Ignore).
264 * \return The entity instance identified by id provided.
266 * \warning If no entity found, an exception is launched by default.
268 Entity* findEntity(const socket_v & socketList, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) throw(anna::RuntimeException);
271 * Returns entity instance identified by internal index.
273 * \param addr1 Diameter primary server address (ip or hostname).
274 * \param port1 Diameter primary server port.
275 * \param addr2 Diameter secondary server address (ip or hostname).
276 * \param port2 Diameter secondary server port.
277 * \param emode Action when no client-session is found with provided parameters (Throw/Ignore).
279 * \return The entity instance identified by id provided.
281 * \warning If no entity found, an exception is launched by default.
283 Entity* findEntity(const std::string & addr1, int port1, const std::string & addr2, int port2, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) throw(anna::RuntimeException);
286 * Creates a diameter entity with provided parameters.
288 * Depending on auto-bind configuration, capabilities exchange request will be or won't be performed over the entity client-sessions.
290 * \param socketList Diameter server priority list (priority-ordered) in order to define whole entity.
291 * @param description Optional entity description (empty by default)
293 * \return The entity created or exception when any server (address/port) already exists for another entity.
295 * \warning The entity won't be almost operative until a notification by mean 'ClientSession::eventResponse'
296 * indicates that 'ClassCode::Bind' has been correctly performed for any included client-session.
298 Entity* createEntity(const socket_v & socketList, const std::string & description = "")
299 throw(anna::RuntimeException);
302 * Creates a standard (dual) diameter entity with provided parameters.
304 * Depending on auto-bind configuration, capabilities exchange request will be or won't be performed over the entity client-sessions.
306 * \param addr1 Diameter primary server address (ip or hostname).
307 * \param port1 Diameter primary server port.
308 * \param addr2 Diameter secondary server address (ip or hostname).
309 * \param port2 Diameter secondary server port.
310 * @param description Optional entity description (empty by default)
312 * \return The standard entity created or exception when any server (address/port) already exists for another entity.
314 * \warning The entity won't be almost operative until a notification by mean 'ClientSession::eventResponse'
315 * indicates that 'ClassCode::Bind' has been correctly performed for any included client-session.
317 Entity* createEntity(const std::string & addr1, int port1, const std::string & addr2, int port2, const std::string & description = "")
318 throw(anna::RuntimeException);
322 * Returns local server instance identified by pair (address, port) provided.
324 * @param addr Diameter server socket address (ip or hostname).
325 * @param port Diameter server socket port.
326 * \param emode Action when no local server is found with provided parameters (Throw/Ignore).
328 * \return The local server instance identified by pair (address, port) provided.
330 * \warning If no local server found, an exception is launched by default.
332 LocalServer* findLocalServer(const std::string & addr, int port, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) throw(anna::RuntimeException);
335 * Returns server-session instance identified by INetAddress serialization provided.
337 * @param socketId Hash for Client Socket INetAddress serialization
338 * \param emode Action when no server-session is found with provided parameters (Throw/Ignore).
340 * \return The server-session instance identified by global unique socketId provided.
342 * \warning If no server-session found, an exception is launched by default.
344 ServerSession* findServerSession(int socketId, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) throw(anna::RuntimeException);
347 * Creates a diameter local server with provided parameters.
349 * Server socket address could be an IPv4 or hostname. Default port will be standard 3868 for diameter agents,
350 * but any other could be configured. Socket server could be created with any max accepted connections: zero
351 * value means temporarily disabled and negative values assume no limit (shared bind) for incomming connections.
353 * @param addr Diameter server socket address (ip or hostname).
354 * @param port Diameter server socket port (standard 3868 by default).
355 * @param maxConnections Diameter server max sessions allowed (no limit by default).
356 * @param allowedInactivityTime Max inactivity time for server sessions over the local server before being reset.
357 * @param category Optional socket server category (1 by default).
358 * @param description Optional socket server description (empty by default).
360 * \return The local server created or exception when is already created.
362 LocalServer *createLocalServer(const std::string & addr, int port = Session::DefaultPort, int maxConnections = -1, const anna::Millisecond & allowedInactivityTime = ServerSession::DefaultAllowedInactivityTime, int category = 1, const std::string & description = "")
363 throw(anna::RuntimeException);
367 Close all the engine resources (entities and local servers)
368 Optionally all resources may be freed passing true
370 @param destroy Free all engine entity resources
372 void close(bool destroy = false) throw(anna::RuntimeException) { closeEntities(destroy); closeLocalServers(destroy); }
376 Close all the engine entities (close servers, then close client-sessions within them). Depending on client-session configuration
377 ('OnDisconnect' behaviour), pending answers will be wait (graceful) or ignored (immediate-abrupt close).
378 Optionally all entities resources may be freed passing true; in this case, close is immediately performed:
379 @param destroy Free all engine entity resources
381 void closeEntities(bool destroy = false) throw(anna::RuntimeException);
385 * Close entity servers (then, client-sessions included) and optionally free resources including entity itself.
386 * If entity is null, this operation has no effect.
388 * \param entity Diameter entity to be closed.
389 * \param destroy Deletes entity over the engine and all its resources.
391 void closeEntity(Entity* entity, bool destroy = false) throw(anna::RuntimeException);
395 Close all the engine local server sockets including their children server sessions.
396 Optionally all local server resources may be freed passing true.
398 @param destroy Free all engine local servers resources and server sessions within them.
400 void closeLocalServers(bool destroy = false) throw(anna::RuntimeException);
403 * Close local server socket and its children server sessions.
404 * This is useful when detecting service lost. When service is ready to handle traffic, a new server socket would
405 * be created by mean #LocalServer::enable() and new connections could be accepted.
406 * Optionally local server resources may be freed passing true.
408 * \param localServer Local server to be closed.
409 * \param destroy Deletes local server over engine and all its resources (server sessions within it).
411 void closeLocalServer(LocalServer * localServer, bool destroy = false) throw(anna::RuntimeException);
414 Gets the number of requests messages over-the-air for entities.
416 @return OTA messages.
418 int getOTARequestsForEntities() const throw();
421 Gets the number of requests messages over-the-air for local servers.
423 @return OTA messages.
425 int getOTARequestsForLocalServers() const throw();
428 Gets the number of requests messages over-the-air for entities plus local servers.
430 @return OTA messages.
432 int getOTARequests() const throw() { return (getOTARequestsForEntities() + getOTARequestsForLocalServers()); }
435 Returns idle state (no pending answers) for entities.
439 bool idleForEntities() const throw() { return (getOTARequestsForEntities() == 0); }
442 Returns idle state (no pending answers).
446 bool idleForLocalServers() const throw() { return (getOTARequestsForLocalServers() == 0); }
449 Returns idle state (no pending answers for entities or local servers).
453 bool idle() const throw() { return (getOTARequests() == 0); }
456 Sent a message to all the engine entities.
457 It is used, i.e., in Disconnect-Peer-Request procedure over the engine.
459 \param message Message which is being sent.
461 @return Returns true (success) only when broadcast is success over all the engine entities. If any entity fails,
462 then false is returned. Broadcast try to send all over the resources in spite of any fail.
464 bool broadcastEntities(const Message*message) throw(anna::RuntimeException);
465 bool broadcastEntities(const Message& message) throw(anna::RuntimeException) { return broadcastEntities(&message); }
468 Sent a message through all the engine local servers.
469 It is used, i.e., in Disconnect-Peer-Request procedure over the engine.
471 \param message Message which is being sent.
473 @return Returns true (success) only when broadcast is success over all the engine local servers. If any local server fails,
474 then false is returned. Broadcast try to send all over the resources in spite of any fail.
476 bool broadcastLocalServers(const Message*message) throw(anna::RuntimeException);
477 bool broadcastLocalServers(const Message& message) throw(anna::RuntimeException) { return broadcastLocalServers(&message); }
480 * Class string representation
482 * @return String with class content
484 virtual std::string asString(void) const throw();
487 Class XML representation.
488 \param parent XML node over which we will put instance information.
489 \return XML documentcon with class content.
491 virtual anna::xml::Node* asXML(anna::xml::Node* parent) const throw();
495 When there is not bound server session over the engine, this virtual method will be invoked.
496 Applications must decide to do any other tasks at this idle/isolated situation.
497 Default implementation do nothing.
499 virtual void availabilityLostForLocalServers(Engine *) const throw() {;}
502 When there is any bound server session over the engine, this virtual method will be invoked.
503 Applications must decide to do be ready for incoming traffic.
504 Default implementation do nothing.
506 virtual void availabilityRecoveredForLocalServers(Engine *) const throw() {;}
509 When there is not bound entity over the engine, this virtual method will be invoked.
510 Many applications must change communicator status to Unavailable when no engines are available.
511 Default implementation do nothing.
513 virtual void availabilityLostForEntities(Engine *) const throw() {;}
516 When there is any bound entity over the engine, this virtual method will be invoked.
517 Many applications must recover communicator status to Available when any engine are available.
518 Default implementation do nothing.
520 virtual void availabilityRecoveredForEntities(Engine *) const throw() {;}
523 When there is not bound server-session over the local server, this virtual method will be invoked.
524 Default implementation do nothing.
526 virtual void availabilityLost(LocalServer *) const throw() {;}
529 When there is any bound server-session over the local server, this virtual method will be invoked.
530 Default implementation do nothing.
532 virtual void availabilityRecovered(LocalServer *) const throw() {;}
535 When there is not bound server over the entity, this virtual method will be invoked.
536 Default implementation do nothing.
538 virtual void availabilityLost(Entity *) const throw() {;}
541 When there is any bound server over the entity, this virtual method will be invoked.
542 Default implementation do nothing.
544 virtual void availabilityRecovered(Entity *) const throw() {;}
547 When there is not bound client-session over the server, this virtual method will be invoked.
548 Default implementation do nothing.
550 virtual void availabilityLost(Server *) const throw() {;}
553 When there is any bound client-session over the server, this virtual method will be invoked.
554 Default implementation do nothing.
556 virtual void availabilityRecovered(Server *) const throw() {;}
559 When a subyacent client session is going to be bound, this method is invoked before.
560 Default implementation do nothing.
562 virtual void bindingClientSession(const ClientSession *) const throw() {;}
565 * Class user should implement this method in order to define Disconnect-Peer-Answer for last received DPR.
566 * Origin-Host and Origin-Realm are configured at comm::Engine with hostname and FQDN (Fully Qualified Domain Name).
567 * Default implementation imply DPA with DIAMETER_SUCCESS Result-Code, allowing remote disconnection.
568 * Any other implementation is responsible to build a valid DPA diameter message.
569 * DPR/DPA procedure is disabled with empty definition of this method: no DPA will be sent when DPR is received.
571 * @param dpa DPA datablock passed as reference
572 * @param dpr Corresponding DPR received (sequence values must be taken into account in order to build DPA)
574 virtual void readDPA(anna::DataBlock &dpa, const anna::DataBlock & dpr) throw();
577 * Sets optional CEA from file, when default is not enough
579 * @param &ceaPathfile Path file for the CEA xml message provided
581 void setCEA(const std::string &ceaPathfile) throw() { a_ceaPathfile = ceaPathfile; }
584 * Class user should implement this method in order to define Capabilities-Exchange-Answer for received CER over server socket.
585 * Origin-Host and Origin-Realm are configured at comm::Engine with hostname and FQDN (Fully Qualified Domain Name).
586 * Default implementation imply CEA with DIAMETER_SUCCESS Result-Code, and own domain node parameters, but application should
587 * analyze the CER message in order to accept it or not (with apropiate non-success Result-Code).
588 * If @setCEA was invoked, a message from file is used instead of default implementation.
589 * Any other implementation is responsible to build a valid CEA diameter message, even ignoring a possible cea from file when @setCEA is used:
591 * If one peer sends a CER message to another Peer and receiver does not have support for
593 * 1) any common application then it must return the CEA with Result-Code Avp set to DIAMETER_NO_COMMON_APPLICATION
594 * and should disconnect the transport layer connection (automatically done by diameter::comm module).
595 * 2) no common security mechanism then it must return the CEA with Result-Code Avp set to DIAMETER_NO_COMMON_SECURITY
596 * and should disconnect the transport layer connection (automatically done by diameter::comm module).
597 * 3) if CER is received from any unknown peer then receiver should discard the message, or send the CEA with the
598 * Result-Code Avp set to DIAMETER_UNKNOWN_PEER.
600 * If the local implementation policy permits to receive CER from unknown hosts, a successful CEA MAY be returned,
601 * and the life time of the peer entry in PEER-Table is equal to the lifetime of the transport connection.
602 * If in any case transport connection fails then all the pending transactions destined to the unknown peer can be discarded.
604 * The CER and CEA messages MUST NOT be proxied, redirected or relayed. Since CER/CEA messages can not be proxied, but still
605 * it is possible that proxy will receive a CER message and proxy does not have any peer to handle the application requested
606 * in CER, in this case proxy set the E bit in CEA and set the Result-Code Avp to DIAMETER_UNABLE_TO_DELIVER, sends back to
607 * CER generator peer.
609 * @param cea CEA datablock passed as reference. Empty cea implies to discard CER received.
610 * @param cer Corresponding CER received (sequence values must be taken into account in order to build CEA)
612 virtual void readCEA(anna::DataBlock &cea, const anna::DataBlock & cer) throw();
615 * Class user should implement this method in order to define Device-Watchdog-Answer for received DWR over server socket.
616 * Origin-Host and Origin-Realm are configured at comm::Engine with hostname and FQDN (Fully Qualified Domain Name).
617 * Default implementation imply DWA with DIAMETER_SUCCESS Result-Code, and own domain node parameters.
618 * Any other implementation is responsible to build a valid DWA diameter message.
620 * @param dwa DWA datablock passed as reference
621 * @param dwr Corresponding DWR received (sequence values must be taken into account in order to build DWA)
623 virtual void readDWA(anna::DataBlock &dwa, const anna::DataBlock & dwr) throw();
626 * DRA basics: CER information is gathered on every server session managed by the diameter comm engine. You could send the message to a
627 * specific realm, and optionally you could restrict a host inside it. This is common for requests (answers are normally sent through
628 * the same source server session where the request was received). Exception will be thrown if not found an available server session
629 * for the Destination-Realm and/or Destination-Host provided
631 * @param destinationRealm If empty, NULL is returned, because is nonsense to specify a host out of realm context
632 * @param destinationHost If empty, no restriction is applied within the target realm node. Random delivery is applied for the available server sessions
634 * @return transactional response reference, or NULL if answer is sent
636 const Response* sendRealmHost(const Message* message, const std::string &destinationRealm, const std::string &destinationHost = "") throw(anna::RuntimeException);
639 Reset engine statistics.
640 At the moment, only diameter servers processing time is observed.
642 void resetStatistics() throw();
646 * Engine lazy initialization. Used if the engine is created when application is already running; for example
647 * on dynamic realms registration. At the moment is not actually needed (nothing is done at initialization),
648 * but it is recommended to start the component and set its state as 'running' from the point of view of the
651 void lazyInitialize() throw(RuntimeException);
658 @param className Component class name
659 @param baseProtocolDictionary This will be used internally when calling \@readCEA, \@readDPA and \@readDWA on
660 servers, and also used during base protocol messages tracing (if debug traces are enabled). You could provide
661 NULL, but you must be sure that neither of the former situations are going to happen or an exception will be
662 thrown (using setClientCERandDWR with DataBlock arguments, expects externally encoded messages and could help).
663 It is recommended to set a base protocol dictionary loading 'source/diameter/stack/setups' dictionaries (for
664 example 'avps_ietf.xml' plus 'commands_baseProtocol.xml'), or using the dictionary creation API. The dictionary
665 could also be an application stack, the only condition is containing the resources to build base protocol messages.
667 Engine(const char *className, const stack::Dictionary *baseProtocolDictionary);
669 // INTERNAL CREATORS AND CLOSE METHODS
670 Server *createServer(Entity*, const socket_t&) throw(anna::RuntimeException);
671 void closeServer(Server*, bool) throw(anna::RuntimeException);
672 ClientSession *createClientSession(Server*, int) throw(anna::RuntimeException);
673 void closeClientSession(ClientSession*, bool) throw(anna::RuntimeException);
675 // INTERNAL ALLOCATORS
676 Server* allocateServer() throw();
677 void releaseServer(Server*) throw();
678 ClientSession* allocateClientSession() throw();
679 void releaseClientSession(ClientSession*) throw();
683 Entity allocator method.
685 It is recommended to use anna::Recycler for entities creation/releasing.
689 virtual Entity* allocateEntity() throw() { return NULL; }
693 Invoked to free entities.
696 virtual void releaseEntity(Entity*) throw() {;}
700 Local server allocator method.
702 It is recommended to use anna::Recycler for entities creation/releasing.
706 virtual LocalServer* allocateLocalServer() throw() { return NULL; }
710 Invoked to free local servers.
713 virtual void releaseLocalServer(LocalServer*) throw() {;}
715 // Gets the base protocol codec engine used internally.
716 // This engine is initializaed on constructor with the base protocol dictionary.
717 // The reason to not reuse any other codec engine from the application is to have this one isolated with no interference
718 // regarding configuration changes (validation depth/mode, fix mode, etc.).
720 // @return Pointer to the internal base protocol codec engine
721 codec::Engine *getBaseProtocolCodecEngine() const throw() { return const_cast<codec::Engine *>(&a_baseProtocolCodecEngine); }
725 // Internal use: tracing and readCEA/DPA/DWA
726 codec::Engine a_baseProtocolCodecEngine;
728 std::string a_originRealm;
729 std::string a_originHost;
731 int a_numberOfClientSessionsPerServer;
734 // ClientSessions messages:
735 anna::DataBlock a_cer;
736 anna::DataBlock a_dwr;
737 anna::Millisecond a_watchdogPeriod;
739 // // ServerSessions messages:
740 std::string a_ceaPathfile; // path file to optional CEA (diameter local server configuration)
741 // anna::DataBlock a_cea;
742 // anna::DataBlock a_dwa;
744 // Client connectivity
745 anna::Millisecond a_maxConnectionDelay;
749 bool a_availableForEntities; // any of the entities must be bound
750 void availabilityLostForEntities() throw();
751 void availabilityRecoveredForEntities() throw();
752 bool refreshAvailabilityForEntities() throw(); // return true if change
754 bool a_availableForLocalServers; // any of the local servers must be bound
755 void availabilityLostForLocalServers() throw();
756 void availabilityRecoveredForLocalServers() throw();
757 bool refreshAvailabilityForLocalServers() throw(); // return true if change
759 void eraseDeprecatedIdleEntities() throw();
762 void do_initialize() throw(anna::RuntimeException);
763 void do_stop() throw();
766 void checkEntityCollision(const socket_v &) throw(anna::RuntimeException);
767 void assertBaseProtocolHealth() throw(anna::RuntimeException); // checks the dictionary
770 //////////////////////////
771 // CLIENT FUNCTIONALITY //
772 //////////////////////////
774 typedef std::string clientSession_key; // 'ADDR:PORT|id'
775 typedef std::map <clientSession_key, ClientSession*> clientSession_container;
776 typedef clientSession_container::value_type clientSession_value_type;
777 typedef clientSession_container::iterator clientSession_iterator;
778 typedef clientSession_container::const_iterator const_clientSession_iterator;
779 clientSession_container a_clientSessions;
780 anna::Recycler<ClientSession> a_clientSessionsRecycler;
781 clientSession_iterator clientSession_find(const clientSession_key&) throw();
782 clientSession_iterator clientSession_begin() throw() { return a_clientSessions.begin(); }
783 clientSession_iterator clientSession_end() throw() { return a_clientSessions.end(); }
784 static ClientSession* clientSession(clientSession_iterator ii) throw() { return ii->second; }
785 const_clientSession_iterator clientSession_begin() const throw() { return a_clientSessions.begin(); }
786 const_clientSession_iterator clientSession_end() const throw() { return a_clientSessions.end(); }
787 static const ClientSession* clientSession(const_clientSession_iterator ii) throw() { return ii->second; }
789 typedef socket_t server_key;
790 server_key getServerKey(const std::string & addr, int port) const throw();
791 typedef std::map <server_key, Server*> server_container;
792 typedef server_container::value_type server_value_type;
793 typedef server_container::iterator server_iterator;
794 typedef server_container::const_iterator const_server_iterator;
795 server_container a_servers;
796 anna::Recycler<Server> a_serversRecycler;
797 server_iterator server_find(const server_key&) throw();
798 server_iterator server_begin() throw() { return a_servers.begin(); }
799 server_iterator server_end() throw() { return a_servers.end(); }
800 static Server* server(server_iterator ii) throw() { return ii->second; }
801 const_server_iterator server_begin() const throw() { return a_servers.begin(); }
802 const_server_iterator server_end() const throw() { return a_servers.end(); }
803 static const Server* server(const_server_iterator ii) throw() { return ii->second; }
805 typedef std::string entity_key; // 'ADDR1:PORT1 ADDR2:PORT2 ADDR3:PORT3 ...'
806 entity_key getEntityKey(const socket_v &) const throw();
807 entity_key getEntityKey(const std::string & addr1, int port1, const std::string & addr2, int port2) const throw();
808 typedef std::map <entity_key, Entity*> entity_container;
809 typedef entity_container::value_type entity_value_type;
810 typedef entity_container::iterator entity_iterator;
811 typedef entity_container::const_iterator const_entity_iterator;
812 entity_container a_entities;
813 entity_iterator entity_find(const entity_key&) throw();
814 entity_iterator entity_begin() throw() { return a_entities.begin(); }
815 entity_iterator entity_end() throw() { return a_entities.end(); }
816 static Entity* entity(entity_iterator ii) throw() { return ii->second; }
817 const_entity_iterator entity_begin() const throw() { return a_entities.begin(); }
818 const_entity_iterator entity_end() const throw() { return a_entities.end(); }
819 static const Entity* entity(const_entity_iterator ii) throw() { return ii->second; }
822 //////////////////////////
823 // SERVER FUNCTIONALITY //
824 //////////////////////////
827 typedef std::map <socket_t, LocalServer*> localServer_container;
828 typedef localServer_container::value_type localServer_value_type;
829 typedef localServer_container::iterator localServer_iterator;
830 typedef localServer_container::const_iterator const_localServer_iterator;
831 localServer_container a_localServers;
832 localServer_iterator localServer_find(const socket_t&) throw();
833 localServer_iterator localServer_begin() throw() { return a_localServers.begin(); }
834 localServer_iterator localServer_end() throw() { return a_localServers.end(); }
835 static LocalServer* localServer(localServer_iterator ii) throw() { return ii->second; }
836 const_localServer_iterator localServer_begin() const throw() { return a_localServers.begin(); }
837 const_localServer_iterator localServer_end() const throw() { return a_localServers.end(); }
838 static const LocalServer* localServer(const_localServer_iterator ii) throw() { return ii->second; }
840 // Server sessions are managed within LocalServer (not at engine) due to dynamic creation nature
841 // Here we maintain the Destination-Realm / Destination-Host maps for DRA basics:
842 typedef std::vector<ServerSession*> server_sessions_vector_t;
843 typedef server_sessions_vector_t::const_iterator server_sessions_it_t;
844 typedef server_sessions_vector_t::iterator server_sessions_nc_it_t;
845 typedef std::map <std::string /* Destination-Host */, server_sessions_vector_t> dh_server_sessions_map_t;
846 typedef dh_server_sessions_map_t::const_iterator dh_server_sessions_it_t;
847 typedef dh_server_sessions_map_t::iterator dh_server_sessions_nc_it_t;
848 typedef std::map <std::string /* Destination-Realm */, dh_server_sessions_map_t> dr_dh_server_sessions_map_t;
849 typedef dr_dh_server_sessions_map_t::const_iterator dr_dh_server_sessions_it_t;
850 typedef dr_dh_server_sessions_map_t::iterator dr_dh_server_sessions_nc_it_t;
851 dr_dh_server_sessions_map_t a_dr_dh_server_sessions;
852 void manageDrDhServerSession(ServerSession *ss, bool register_or_desregister) throw();
854 friend class Session;
855 friend class ClientSession;
856 friend class ServerSession;
857 friend class ServerSocket;
860 friend class LocalServer;
861 //friend class Message;