f653ee59bef5d428fdb6a1b73f70ce4d1bf5ec66
[anna.git] / 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   /**
137    * Sets CER and DWR diameter messages to be used over created client-sessions
138    *
139    * @param cer Capabilities-Exchange-Request message (encoded) for the client-sessions bind.
140    * @param dwr Device-Watchdog-Request message (encoded) for the client-sessions keep-alive.
141    */
142   void setCERandDWR(const anna::DataBlock & cer, const anna::DataBlock & dwr) noexcept(false);
143
144   // Internal
145   void bind() noexcept(false);
146
147   /* virtual */const Response* send(const Message* message) noexcept(false);
148   /* 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)
149
150   /**
151      Deny resource for delivery restriction
152   */
153   void hide() { a_hidden = true; }
154
155   /**
156      Allow resource for delivery permission
157   */
158   void show() { a_hidden = false; }
159
160   /**
161      Returns true when client session resource is hidden for application messages delivery
162   */
163   bool hidden() const { return a_hidden; }
164
165   /**
166      Returns true when client session resource is shown for application messages delivery
167   */
168   bool shown() const { return !a_hidden; }
169
170
171   /**
172      Class string representation
173      \return String with relevant information for this instance.
174   */
175   /* virtual */std::string asString() const ;
176
177
178   /**
179      Class xml representation
180      \param parent Parent XML node on which hold this instance information.
181      \return XML document with relevant information for this instance.
182   */
183   /* virtual */anna::xml::Node* asXML(anna::xml::Node* parent) const ;
184
185
186 private:
187
188   // Receiver factory
189   ReceiverFactoryImpl<ClientSession, ClientSessionReceiver> a_receiverFactory;
190
191   // Parent information
192   Server *a_parent;
193
194   // ClientSession messages:
195   Message a_cer;
196   Message a_dwr;
197
198   // Connectivity
199   bool a_autoRecovery;
200
201   // Server
202   anna::comm::Server *a_server;
203
204   // Watchdog control:
205   struct WatchdogState {
206     enum _v {
207       TimerStopped,           // Until CEA (bound state), timer is stopped
208       WaitingTimerExpiration, // DWA has been received and we wait for next expiration to send DWR
209       WaitingDWA              // DWR has been sent, but DWA hasn't been received yet
210     };
211   };
212   WatchdogState::_v a_watchdogState;
213   void setWatchdogState(WatchdogState::_v wState) ;
214
215   /* virtual */void expire(anna::timex::Engine *timeController) noexcept(false);
216   void setWatchdogPeriod(const anna::Millisecond & watchdogPeriod) ;
217
218   /*virtual*/ void timerStopped() ;
219   /*virtual*/ void timerStarted() ;
220
221
222   // Activity:
223   /* virtual */void updateIncomingActivityTime() ;
224   /* virtual */void updateOutgoingActivityTime() ;
225   void countSendings(const diameter::CommandId & cid, unsigned int aid, bool ok) ;
226
227   // Handlers:
228   /**
229      Handler about event break connection from diameter server over this client-session.
230
231      When notified, ANNA.diameter.comm generates an diameter::comm::ClientSession::eventResponse for every request with pending answers.
232   */
233   void eventPeerShutdown() ;
234
235   /**
236      Handler about a request retransmission over the session.
237
238      \param request Message retransmitted
239   */
240   void eventRequestRetransmission(Message *request) ;
241
242   /**
243      Handler for diameter server (client-session) responses
244
245      \param response Answer container object for corresponding diameter request
246   */
247   void eventResponse(const Response& response) noexcept(false);
248
249   /**
250      Handler for diameter server (client-session) requests
251
252      \param request Request data block object for corresponding diameter reception
253   */
254   void eventRequest(const anna::DataBlock& request) noexcept(false);
255   //void eventRequest(const Message& request) noexcept(false);
256
257   /**
258      Handler for diameter server (client-session) responses out of context
259
260      \param response Answer data block object without context match
261   */
262   void eventUnknownResponse(const anna::DataBlock& response) noexcept(false);
263
264   /**
265      Handler for diameter server (client-session) Disconnect-Peer-Answer messages
266
267      \param response Answer data block object without context match
268   */
269   void eventDPA(const anna::DataBlock& response) noexcept(false);
270
271
272
273   /**
274   * Handlers for receptions
275   */
276   /* virtual */void receive(const anna::comm::Message& message) noexcept(false);
277   /* virtual */void finalize() ;
278   void recover() ;
279
280   /* virtual */void expireResponse(Response*) ;
281   /* virtual */void setState(State::_v state) ;
282
283   void sendDWAToServer(const anna::DataBlock& dwrDB) noexcept(false); // non-usual behaviour, but DWR could be received from server
284
285   // helpers
286   static const char* asText(const WatchdogState::_v) ;
287
288
289   friend class Server;
290   friend class Engine;
291   friend class ClientSessionReceiver;
292 };
293
294 }
295 }
296 }
297
298 #endif
299