X-Git-Url: https://git.teslayout.com/public/public/public/?a=blobdiff_plain;f=include%2Fanna%2Fdiameter.comm%2FEngine.hpp;h=6a7d133c7e83764f0053a0f548bca4cf7c06060b;hb=dfc80ebaae97088df3188399b014652b4cf48dea;hp=8ec27574539dcb7006853bda9b6f4036042dbcc7;hpb=ea14381cada0d7173fd19eaaf781f82eb714325e;p=anna.git diff --git a/include/anna/diameter.comm/Engine.hpp b/include/anna/diameter.comm/Engine.hpp index 8ec2757..6a7d133 100644 --- a/include/anna/diameter.comm/Engine.hpp +++ b/include/anna/diameter.comm/Engine.hpp @@ -12,12 +12,14 @@ // STL #include +#include #include #include #include #include +#include #include #include #include @@ -47,9 +49,13 @@ namespace codec { class Engine; } -namespace comm { +namespace stack { +class Dictionary; +} +namespace comm { +class Response; class Entity; class Server; class LocalServer; @@ -95,65 +101,43 @@ class Engine : public anna::app::Component { public: /** - * Sets the base protocol codec engine used internally - * - * @param baseProtocolCodecEngine This will be used internally during invokation of @readCEA, @readDPA and @readDWA on servers, - * and also used during base protocol messages tracing (if debug traces are enabled). You could provide NULL but you must be - * sure that neither of the former situations are going to happen or an exception will be thrown. It is recommended to register - * a codec engine pointed to a base protocol stack (you can use the files 'avps_ietf.xml' and 'commands_baseProtocol.xml' - * located on ANNA suite project under 'source/diameter/stack/setups', or perhaps you can create your own dictionary from - * file or directly with the dictionay creation API. Even you can use a greater dictionary (application dictionary), the - * only condition is that must contain the resources to build base protocol messages. You could provide this in engine constructor, - * but don't forget it. - */ - void setBaseProtocolCodecEngine(codec::Engine *baseProtocolCodecEngine) throw() { a_baseProtocolCodecEngine = baseProtocolCodecEngine; } - - /** - * Gets the base protocol codec engine used internally - * - * @see setBaseProtocolCodecEngine - */ - codec::Engine * getBaseProtocolCodecEngine() const throw() { return a_baseProtocolCodecEngine; } - - /** - Diameter application node realm name (used to be the site domain name). + Diameter application node origin realm - @param name Diameter application node realm name. Used in order to configure the Origin-Realm for outgoing messages. + @param originRealmName Used to configure the Origin-Realm for outgoing messages. If not configured or empty string provided, host domainname will be set. */ - void setRealm(const std::string & name) throw(); - + void setOriginRealmName(const std::string & originRealmName) throw(); /** - Gets the configured diameter application node realm name. + Diameter application origin host - @return Diameter application node realm name. + @param originHostName Used to configure the Origin-Host for outgoing messages. + If not configured or empty string provided, hostname (system name) will be set. */ - const std::string & getRealm() const throw() { return a_realm; } - + void setOriginHostName(const std::string & originHostName) throw(); /** - Diameter application host name as solved by #anna::functions::getHostname() + Gets the configured diameter application node origin realm - @param name Host name. Used in order to configure the Origin-Host for outgoing messages. - If not configured or empty string provided, hostname (system name) will be set. + @return Diameter application node origin realm */ - void setHost(const std::string & name) throw(); - + const std::string & getOriginRealmName() const throw() { return a_originRealm; } /** - Gets the configured diameter application host name. + Gets the configured diameter application origin host - @return Diameter application host name. + @return Diameter application node origin host */ - const std::string & getHost() const throw() { return a_host; } + const std::string & getOriginHostName() const throw() { return a_originHost; } /** * Propagate auto recovery configuration to entities within engine. Recovery period is configured at - * #anna::comm::Communicator::setRecoveryTime. All the client client-sessions created throught #createEntity, - * will be created based on the engine auto-recovery value (enable by default). But you could access entities, - * servers or client-sessions independently to change this behaviour. + * #anna::comm::Communicator::setRecoveryTime (5 seconds by default). All the client client-sessions + * created throught #createEntity, will be created based on the engine auto-recovery value (enabled + * by default). + * You could access entities, servers or client-sessions independently to use this method, but recovery + * time should be updated through communicator and will apply for new created connections. * * @param autoRecovery Auto recovery indicator. True by default. */ @@ -591,12 +575,20 @@ public: */ virtual void readDPA(anna::DataBlock &dpa, const anna::DataBlock & dpr) throw(); + /** + * Sets optional CEA from file, when default is not enough + * + * @param &ceaPathfile Path file for the CEA xml message provided + */ + void setCEA(const std::string &ceaPathfile) throw() { a_ceaPathfile = ceaPathfile; } + /** * Class user should implement this method in order to define Capabilities-Exchange-Answer for received CER over server socket. * Origin-Host and Origin-Realm are configured at comm::Engine with hostname and FQDN (Fully Qualified Domain Name). * Default implementation imply CEA with DIAMETER_SUCCESS Result-Code, and own domain node parameters, but application should * analyze the CER message in order to accept it or not (with apropiate non-success Result-Code). - * Any other implementation is responsible to build a valid CEA diameter message: + * If @setCEA was invoked, a message from file is used instead of default implementation. + * Any other implementation is responsible to build a valid CEA diameter message, even ignoring a possible cea from file when @setCEA is used: * * If one peer sends a CER message to another Peer and receiver does not have support for * @@ -632,6 +624,19 @@ public: */ virtual void readDWA(anna::DataBlock &dwa, const anna::DataBlock & dwr) throw(); + /** + * DRA basics: CER information is gathered on every server session managed by the diameter comm engine. You could send the message to a + * specific realm, and optionally you could restrict a host inside it. This is common for requests (answers are normally sent through + * the same source server session where the request was received). Exception will be thrown if not found an available server session + * for the Destination-Realm and/or Destination-Host provided + * + * @param destinationRealm If empty, NULL is returned, because is nonsense to specify a host out of realm context + * @param destinationHost If empty, no restriction is applied within the target realm node. Random delivery is applied for the available server sessions + * + * @return transactional response reference, or NULL if answer is sent + */ + const Response* sendRealmHost(const Message* message, const std::string &destinationRealm, const std::string &destinationHost = "") throw(anna::RuntimeException); + /** Reset engine statistics. At the moment, only diameter servers processing time is observed. @@ -653,17 +658,15 @@ protected: Constructor. @param className Component class name - @param baseProtocolCodecEngine This will be used internally during invokation of @readCEA, @readDPA and @readDWA on servers, - and also used during base protocol messages tracing (if debug traces are enabled). You could provide NULL but you must be - sure that neither of the former situations are going to happen or an exception will be thrown. It is recommended to register - a codec engine pointed to a base protocol stack (you can use the files 'avps_ietf.xml' and 'commands_baseProtocol.xml' - located on ANNA suite project under 'source/diameter/stack/setups', or perhaps you can create your own dictionary from - file or directly with the dictionay creation API. Even you can use a greater dictionary (application dictionary), the - only condition is that must contain the resources to build base protocol messages. You could use @setBaseProtocolCodecEngine - to set this reference later; don't forget it. + @param baseProtocolDictionary This will be used internally when calling \@readCEA, \@readDPA and \@readDWA on + servers, and also used during base protocol messages tracing (if debug traces are enabled). You could provide + NULL, but you must be sure that neither of the former situations are going to happen or an exception will be + thrown (using setClientCERandDWR with DataBlock arguments, expects externally encoded messages and could help). + It is recommended to set a base protocol dictionary loading 'source/diameter/stack/setups' dictionaries (for + example 'avps_ietf.xml' plus 'commands_baseProtocol.xml'), or using the dictionary creation API. The dictionary + could also be an application stack, the only condition is containing the resources to build base protocol messages. */ - Engine(const char *className, codec::Engine *baseProtocolCodecEngine); - + Engine(const char *className, const stack::Dictionary *baseProtocolDictionary); // INTERNAL CREATORS AND CLOSE METHODS Server *createServer(Entity*, const socket_t&) throw(anna::RuntimeException); @@ -711,15 +714,21 @@ protected: */ virtual void releaseLocalServer(LocalServer*) throw() {;} - + // Gets the base protocol codec engine used internally. + // This engine is initializaed on constructor with the base protocol dictionary. + // The reason to not reuse any other codec engine from the application is to have this one isolated with no interference + // regarding configuration changes (validation depth/mode, fix mode, etc.). + // + // @return Pointer to the internal base protocol codec engine + codec::Engine *getBaseProtocolCodecEngine() const throw() { return const_cast(&a_baseProtocolCodecEngine); } private: // Internal use: tracing and readCEA/DPA/DWA - codec::Engine *a_baseProtocolCodecEngine; + codec::Engine a_baseProtocolCodecEngine; - std::string a_realm; - std::string a_host; + std::string a_originRealm; + std::string a_originHost; bool a_autoBind; int a_numberOfClientSessionsPerServer; @@ -730,6 +739,7 @@ private: anna::Millisecond a_watchdogPeriod; // // ServerSessions messages: + std::string a_ceaPathfile; // path file to optional CEA (diameter local server configuration) // anna::DataBlock a_cea; // anna::DataBlock a_dwa; @@ -756,13 +766,13 @@ private: // Integrity: void checkEntityCollision(const socket_v &) throw(anna::RuntimeException); + void assertBaseProtocolHealth() throw(anna::RuntimeException); // checks the dictionary ////////////////////////// // CLIENT FUNCTIONALITY // ////////////////////////// - //typedef int clientSession_key; // exclusiveHash('ADDR:PORT|id') typedef std::string clientSession_key; // 'ADDR:PORT|id' typedef std::map clientSession_container; typedef clientSession_container::value_type clientSession_value_type; @@ -794,7 +804,6 @@ private: const_server_iterator server_end() const throw() { return a_servers.end(); } static const Server* server(const_server_iterator ii) throw() { return ii->second; } - //typedef int entity_key; // exclusiveHash('IP1:PORT1 IP2:PORT2 IP3:PORT3 ...') typedef std::string entity_key; // 'ADDR1:PORT1 ADDR2:PORT2 ADDR3:PORT3 ...' entity_key getEntityKey(const socket_v &) const throw(); entity_key getEntityKey(const std::string & addr1, int port1, const std::string & addr2, int port2) const throw(); @@ -830,10 +839,22 @@ private: const_localServer_iterator localServer_end() const throw() { return a_localServers.end(); } static const LocalServer* localServer(const_localServer_iterator ii) throw() { return ii->second; } - // Server sessions are managed within LocalServer (not at engine) due to dynamic cration nature - + // Server sessions are managed within LocalServer (not at engine) due to dynamic creation nature + // Here we maintain the Destination-Realm / Destination-Host maps for DRA basics: + typedef std::vector server_sessions_vector_t; + typedef server_sessions_vector_t::const_iterator server_sessions_it_t; + typedef server_sessions_vector_t::iterator server_sessions_nc_it_t; + typedef std::map dh_server_sessions_map_t; + typedef dh_server_sessions_map_t::const_iterator dh_server_sessions_it_t; + typedef dh_server_sessions_map_t::iterator dh_server_sessions_nc_it_t; + typedef std::map dr_dh_server_sessions_map_t; + typedef dr_dh_server_sessions_map_t::const_iterator dr_dh_server_sessions_it_t; + typedef dr_dh_server_sessions_map_t::iterator dr_dh_server_sessions_nc_it_t; + dr_dh_server_sessions_map_t a_dr_dh_server_sessions; + void manageDrDhServerSession(ServerSession *ss, bool register_or_desregister) throw(); friend class Session; + friend class ClientSession; friend class ServerSession; friend class ServerSocket; friend class Server;