Fix local server for multiple applications
[anna.git] / include / anna / diameter.comm / ClientSession.hpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
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 //
7
8
9 #ifndef anna_diameter_comm_ClientSession_hpp
10 #define anna_diameter_comm_ClientSession_hpp
11
12
13 // STL
14 #include <string>
15
16 #include <anna/core/util/SortedVector.hpp>
17 #include <anna/core/util/Millisecond.hpp>
18 #include <anna/core/RuntimeException.hpp>
19
20 #include <anna/diameter.comm/Session.hpp>
21 #include <anna/diameter/defines.hpp>
22 #include <anna/diameter.comm/Message.hpp>
23 #include <anna/diameter.comm/ClientSessionReceiver.hpp>
24 #include <anna/diameter.comm/ReceiverFactoryImpl.hpp>
25
26
27 namespace anna {
28 class DataBlock;
29 namespace timex {
30 class Engine;
31 }
32
33 namespace comm {
34 class Server;
35 }
36 }
37
38
39 namespace anna {
40
41 namespace diameter {
42
43 namespace comm {
44
45 class Server;
46
47
48 /**
49    Modela la conexion realizada contra un servidor diameter.
50 */
51 class ClientSession : public Session {
52
53   // Helper:
54   static std::string getKey(const std::string & addr, int port, int socketId) {
55     return (anna::functions::asString("%s:%d|%d", addr.c_str(), port, socketId));
56   }
57
58   bool a_hidden; // hide resource for restricted delivery over servers/entities
59
60
61 public:
62
63   ClientSession();
64
65
66   /* virtual */void initialize() ;
67
68   /**
69    * Default watchdog period for the diameter client-session health.
70    */
71   static const anna::Millisecond DefaultWatchdogPeriod;
72
73   /**
74      Client session key: <address ip or hostname>:<remote port>|<socket id: 0..N-1>
75   */
76   std::string getKey() const { return ClientSession::getKey(getAddress(), getPort(), getSocketId()); }
77
78   /**
79      Diameter server address (IPv4 or hostname)
80      \return Diameter server address
81   */
82   /* virtual */const std::string& getAddress() const ;
83
84   /**
85      Diameter server listen port
86      \return Diameter server listen port
87   */
88   /* virtual */int getPort() const ;
89
90   /**
91      Diameter parent server.
92      \return Diameter parent server.
93   */
94   const Server *getParent() const { return a_parent; }
95
96   /**
97      Diameter server created at diameter::comm::Engine::createClientSession.
98      \return Diameter server
99   */
100   anna::comm::Server * getServer() { return a_server; }
101
102   /**
103      Disables server resource (avoid the use of the server)
104   */
105   void disable() { a_server->disable(); }
106
107   /**
108      Sets auto recovery indicator. When a connection is lost, by default it will be recovered automatically.
109      \param autoRecovery Auto recovery indicator. TRue by default.
110   */
111   void setAutoRecovery(bool autoRecovery = true) { a_autoRecovery = autoRecovery; a_server->setAutoRecovery(autoRecovery); }
112
113   /**
114      Gets the auto recovery indicator for the client connection (client-session).
115
116      @return Auto recovery indicator.
117   */
118   bool getAutoRecovery() const { return a_autoRecovery; }
119
120   /**
121      Sets the milliseconds wait to achieve a client connection to server by mean connect primitive.
122      This allow to perform specific configurations (some servers could be slower than others).
123      Changes will be taken into account on the next connect operation.
124
125      \param maxConnectionDelay Milliseconds wait to get connection
126   */
127   void setMaxConnectionDelay(const anna::Millisecond & maxConnectionDelay) { a_server->setMaxConnectionDelay(maxConnectionDelay); }
128
129   /**
130      Gets the milliseconds wait to achieve a client connection to server by mean connect primitive.
131
132      \return Milliseconds wait to get connection
133   */
134   const anna::Millisecond & getMaxConnectionDelay() { return a_server->getMaxConnectionDelay(); }
135
136   // Internal
137   void bind() noexcept(false);
138
139   /* virtual */const Response* send(const Message* message) noexcept(false);
140   /* virtual */bool unbind(bool forceDisconnect /* se usa en timer, para el actionTimer del tipo SessionUnbind, etc. */ = false) noexcept(false); // returns true if done at call time (no pendings or ignore pendings, except Disconnecting state by mean DPR/DPA)
141
142   /**
143      Deny resource for delivery restriction
144   */
145   void hide() { a_hidden = true; }
146
147   /**
148      Allow resource for delivery permission
149   */
150   void show() { a_hidden = false; }
151
152   /**
153      Returns true when client session resource is hidden for application messages delivery
154   */
155   bool hidden() const { return a_hidden; }
156
157   /**
158      Returns true when client session resource is shown for application messages delivery
159   */
160   bool shown() const { return !a_hidden; }
161
162
163   /**
164      Class string representation
165      \return String with relevant information for this instance.
166   */
167   /* virtual */std::string asString() const ;
168
169
170   /**
171      Class xml representation
172      \param parent Parent XML node on which hold this instance information.
173      \return XML document with relevant information for this instance.
174   */
175   /* virtual */anna::xml::Node* asXML(anna::xml::Node* parent) const ;
176
177
178 private:
179
180   // Receiver factory
181   ReceiverFactoryImpl<ClientSession, ClientSessionReceiver> a_receiverFactory;
182
183   // Parent information
184   Server *a_parent;
185
186   // ClientSession messages:
187   Engine *a_engine; // it is unique for a client session (not in server session, which have one per origin host)
188   Message a_cer;
189   Message a_dwr;
190
191   // Connectivity
192   bool a_autoRecovery;
193
194   // Server
195   anna::comm::Server *a_server;
196
197   // Watchdog control:
198   struct WatchdogState {
199     enum _v {
200       TimerStopped,           // Until CEA (bound state), timer is stopped
201       WaitingTimerExpiration, // DWA has been received and we wait for next expiration to send DWR
202       WaitingDWA              // DWR has been sent, but DWA hasn't been received yet
203     };
204   };
205   WatchdogState::_v a_watchdogState;
206   void setWatchdogState(WatchdogState::_v wState) ;
207
208   /* virtual */void expire(anna::timex::Engine *timeController) noexcept(false);
209   void setWatchdogPeriod(const anna::Millisecond & watchdogPeriod) ;
210
211   /*virtual*/ void timerStopped() ;
212   /*virtual*/ void timerStarted() ;
213
214
215   // Activity:
216   /* virtual */void updateIncomingActivityTime() ;
217   /* virtual */void updateOutgoingActivityTime() ;
218   void countSendings(const diameter::CommandId & cid, unsigned int aid, bool ok) ;
219
220   // Handlers:
221   /**
222      Handler about event break connection from diameter server over this client-session.
223
224      When notified, ANNA.diameter.comm generates an diameter::comm::ClientSession::eventResponse for every request with pending answers.
225   */
226   void eventPeerShutdown() ;
227
228   /**
229      Handler about a request retransmission over the session.
230
231      \param request Message retransmitted
232   */
233   void eventRequestRetransmission(Message *request) ;
234
235   /**
236      Handler for diameter server (client-session) responses
237
238      \param response Answer container object for corresponding diameter request
239      \param myNode Own origin host
240   */
241   void eventResponse(const Response& response, const anna::diameter::comm::OriginHost *myNode) noexcept(false);
242
243   /**
244      Handler for diameter server (client-session) requests
245
246      \param request Request data block object for corresponding diameter reception
247      \param myNode Own origin host
248   */
249   void eventRequest(const anna::DataBlock& request, const anna::diameter::comm::OriginHost *myNode) noexcept(false);
250   //void eventRequest(const Message& request) noexcept(false);
251
252   /**
253      Handler for diameter server (client-session) responses out of context
254
255      \param response Answer data block object without context match
256      \param myNode Own origin host
257   */
258   void eventUnknownResponse(const anna::DataBlock& response, const anna::diameter::comm::OriginHost *myNode) noexcept(false);
259
260   /**
261      Handler for diameter server (client-session) Disconnect-Peer-Answer messages
262
263      \param response Answer data block object without context match
264      \param myNode Own origin host
265   */
266   void eventDPA(const anna::DataBlock& response, const anna::diameter::comm::OriginHost *myNode) noexcept(false);
267
268
269
270   /**
271   * Handlers for receptions
272   */
273   /* virtual */void receive(const anna::comm::Message& message) noexcept(false);
274   /* virtual */void finalize() ;
275   void recover() ;
276
277   /* virtual */void expireResponse(Response*) ;
278   /* virtual */void setState(State::_v state) ;
279
280   void sendDWAToServer(const anna::DataBlock& dwrDB) noexcept(false); // non-usual behaviour, but DWR could be received from server
281
282   // helpers
283   static const char* asText(const WatchdogState::_v) ;
284
285
286   friend class Server;
287   friend class Engine;
288   friend class ClientSessionReceiver;
289 };
290
291 }
292 }
293 }
294
295 #endif
296