1 /*
2  * Copyright (C) 2012 Smile Communications, jason.penton@smilecoms.com
3  * Copyright (C) 2012 Smile Communications, richard.good@smilecoms.com
4  *
5  * The initial version of this code was written by Dragos Vingarzan
6  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
7  * Fruanhofer Institute. It was and still is maintained in a separate
8  * branch of the original SER. We are therefore migrating it to
9  * Kamailio/SR and look forward to maintaining it from here on out.
10  * 2011/2012 Smile Communications, Pty. Ltd.
11  * ported/maintained/improved by
12  * Jason Penton (jason(dot)penton(at)smilecoms.com and
13  * Richard Good (richard(dot)good(at)smilecoms.com) as part of an
14  * effort to add full IMS support to Kamailio/SR using a new and
15  * improved architecture
16  *
17  * NB: Alot of this code was originally part of OpenIMSCore,
18  * FhG Fokus.
19  * Copyright (C) 2004-2006 FhG Fokus
20  * Thanks for great work! This is an effort to
21  * break apart the various CSCF functions into logically separate
22  * components. We hope this will drive wider use. We also feel
23  * that in this way the architecture is more complete and thereby easier
24  * to manage in the Kamailio/SR environment
25  *
26  * This file is part of Kamailio, a free SIP server.
27  *
28  * Kamailio is free software; you can redistribute it and/or modify
29  * it under the terms of the GNU General Public License as published by
30  * the Free Software Foundation; either version 2 of the License, or
31  * (at your option) any later version
32  *
33  * Kamailio is distributed in the hope that it will be useful,
34  * but WITHOUT ANY WARRANTY; without even the implied warranty of
35  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
36  * GNU General Public License for more details.
37  *
38  * You should have received a copy of the GNU General Public License
39  * along with this program; if not, write to the Free Software
40  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
41  *
42  */
43 
44 #ifndef __DIAMETER_SESSION_H
45 #define __DIAMETER_SESSION_H
46 
47 
48 //#include "diameter_api.h"
49 #include "utils.h"
50 #include "diameter.h"
51 
52 extern unsigned int debug_heavy;
53 
54 /** Function for callback on session events: timeout, etc. */
55 typedef void (AAASessionCallback_f)(int event, void *session);
56 
57 /** Types of sessions */
58 typedef enum {
59 	UNKNOWN_SESSION			= 0,
60 
61 	AUTH_CLIENT_STATELESS	= 1,
62 	AUTH_SERVER_STATELESS	= 2,
63 	AUTH_CLIENT_STATEFULL	= 3,
64 	AUTH_SERVER_STATEFULL	= 4,
65 
66 	ACCT_CLIENT_STATELESS	= 5,
67 	ACCT_CLIENT_STATEFUL	= 6,
68 	ACCT_SERVER_STATELESS	= 7,
69 	ACCT_SERVER_STATEFULL	= 8,
70 
71 	ACCT_CC_CLIENT			= 9,		/**< Credit Control Client - RFC (4006) */
72 
73 } cdp_session_type_t;
74 
75 /** auth session states */
76 typedef enum {
77 	AUTH_ST_IDLE,
78 	AUTH_ST_PENDING,
79 	AUTH_ST_OPEN,
80 	AUTH_ST_DISCON
81 } cdp_auth_state;
82 
83 /** auth session event */
84 typedef enum {
85 	AUTH_EV_START						=0,
86 	AUTH_EV_SEND_REQ 					=1,
87 	AUTH_EV_SEND_ANS					=2,
88 	AUTH_EV_SEND_ANS_SUCCESS			=3,
89 	AUTH_EV_SEND_ANS_UNSUCCESS			=4,
90 	AUTH_EV_RECV_ASR					=5,
91 	AUTH_EV_RECV_REQ					=6,
92 	AUTH_EV_RECV_ANS					=7,
93 	AUTH_EV_RECV_ANS_SUCCESS			=8,
94 	AUTH_EV_RECV_ANS_UNSUCCESS			=9,
95 	AUTH_EV_SEND_ASR					=10,
96 	AUTH_EV_SEND_ASA_SUCCESS			=11,
97 	AUTH_EV_SEND_ASA_UNSUCCESS			=12,
98 	AUTH_EV_SEND_STA					=13,
99 	AUTH_EV_RECV_ASA					=14,
100 	AUTH_EV_RECV_ASA_SUCCESS			=15,
101 	AUTH_EV_RECV_ASA_UNSUCCESS			=16,
102 	AUTH_EV_RECV_STA					=17,
103 	AUTH_EV_RECV_STR					=18,
104 	AUTH_EV_SESSION_LIFETIME_TIMEOUT	=19,
105 	AUTH_EV_SESSION_GRACE_TIMEOUT		=20,
106 	AUTH_EV_SESSION_TIMEOUT				=21,
107 	AUTH_EV_SERVICE_TERMINATED			=22,
108 	AUTH_EV_SESSION_CREATED				=23,
109 	AUTH_EV_SESSION_MODIFIED			=24,
110 	AUTH_EV_SESSION_DROP				=25,
111 } cdp_auth_event;
112 
113 /** Accounting states definition */
114 typedef enum {
115 	AUTH_CLASS_UNKNOWN              = 0,
116 	AUTH_CLASS_RXREG                = 1,
117 	AUTH_CLASS_RXMEDIA              = 2
118 } cdp_auth_session_class_t;
119 
120 /** structure for auth session */
121 typedef struct _cdp_auth_session_t {
122 	cdp_auth_state state;           /**< current state */
123 	cdp_auth_session_class_t class; /**< useful to know if this is Rx reg or Rx media for example */
124 	time_t timeout;			/**< absolute time for session timeout  -1 means forever */
125 	time_t lifetime;		/**< absolute time for auth lifetime -1 means forever */
126 	time_t grace_period;            /**< grace_period in seconds 	*/
127 	unsigned int last_requested_lifetime;   /**< the following 3 timers are used to store what we are */
128 	unsigned int last_requested_timeout;    /**<requesitng in a request, if the answer does not have anything */
129 	unsigned int last_requested_grace;      /**<different then we will use these values */
130 
131 	void* generic_data;
132 } cdp_auth_session_t;
133 
134 /** Accounting states definition */
135 typedef enum {
136 	ACC_ST_IDLE			= 0,	/**< Idle */
137 	ACC_ST_PENDING_S	= 1,	/**< Pending Session */
138 	ACC_ST_PENDING_E	= 2,	/**< Pending Event */
139 	ACC_ST_PENDING_B	= 3,	/**< Pending Buffered */
140 	ACC_ST_OPEN	  		= 4,	/**< Open */
141 	ACC_ST_PENDING_I	= 5,	/**< Pending Interim */
142 	ACC_ST_PENDING_L	= 6		/**< PendingL - sent accounting stop */
143 } cdp_acc_state_t;
144 
145 /** Accounting events definition */
146 typedef enum {
147 	ACC_EV_START					= 101,	/**< Client or device "requests access" (SIP session establishment) */
148 	ACC_EV_EVENT					= 102,	/**< Client or device requests a one-time service (e.g. SIP MESSAGE) */
149 	ACC_EV_BUFFEREDSTART			= 103,	/**< Records in storage */
150 	ACC_EV_RCV_SUC_ACA_START		= 104,	/**< Successful accounting start answer received */
151 	ACC_EV_SNDFAIL					= 105,	/**< Failure to send */
152 	ACC_EV_RCV_FAILED_ACA_START		= 106,	/**< Failed accounting start answer received */
153 	ACC_EV_STOP						= 107,	/**< User service terminated */
154 	ACC_EV_INTERIM					= 108,	/**< Interim interval elapses */
155 	ACC_EV_RCV_SUC_ACA_INTERIM		= 109,	/**< Successful accounting interim answer received */
156 	ACC_EV_RCV_FAILED_ACA_INTERIM	= 110,	/**< Failed accounting interim answer received */
157 	ACC_EV_RCV_SUC_ACA_EVENT		= 111,	/**< Successful accounting event answer received */
158 	ACC_EV_RCV_FAILED_ACA_EVENT		= 112,	/**< Failed accounting event answer received */
159 	ACC_EV_RCV_SUC_ACA_STOP			= 113,	/**< Successful accounting stop answer received */
160 	ACC_EV_RCV_FAILED_ACA_STOP		= 114,	/**< Failed accounting stop answer received */
161 } cdp_acc_event_t;
162 
163 /** Credit Control states - RFC 4006 */
164 typedef enum {
165 	ACC_CC_ST_IDLE		= 0, 	/**< Idle */
166 	ACC_CC_ST_PENDING_I	= 1,	/**< Pending Initial Answer */
167 	ACC_CC_ST_PENDING_U	= 2,	/**< Pending Interim/Update Answer */
168 	ACC_CC_ST_PENDING_T	= 3,	/**< Pending Terminate Answer */
169 	ACC_CC_ST_OPEN		= 4,	/**< Open */
170 	ACC_CC_ST_DISCON	= 5,	/**< Disconnected, ie. end of session */
171 } cdp_cc_acc_state_t;
172 
173 /** Credit Control events - RFC 4006 */
174 typedef enum {
175 	ACC_CC_EV_SESSION_START				= 0, 		/**< Client or device requests access to service */
176 	ACC_CC_EV_SEND_REQ					= 1,		/**< Sent initial request on session CCR */
177 	ACC_CC_EV_RECV_ANS					= 2,		/**< Received a response message */
178 	ACC_CC_EV_RECV_ANS_SUCCESS 			= 3,		/**< CCA = success */
179 	ACC_CC_EV_RECV_ANS_UNSUCCESS 		= 4,		/**< CCA = failure */
180 	ACC_CC_EV_SESSION_CREATED 			= 5,		/**< used for callbacks - new CC session created */
181 	ACC_CC_EV_SESSION_TIMEOUT			= 6,		/**< CC Session timeout */
182 	ACC_CC_EV_RSVN_WARNING				= 7,		/**< Reservation is about to expire */
183 	ACC_CC_EV_SESSION_TERMINATED		= 8,
184 	ACC_CC_EV_SESSION_MODIFIED			= 9,
185 	ACC_CC_EV_SESSION_STALE				= 10,		/**< Session is being removed from memory after stale expiry */
186 } cdp_cc_acc_event_t;
187 
188 /** Credit Control Session types - RFC 4006 */
189 typedef enum {
190 	ACC_CC_TYPE_EVENT		= 0, 	/**< Immediate Event Charge (IEC - see TS32.299 6.3.2.1)*/
191 	ACC_CC_TYPE_SESSION		= 1, 	/**< Session-based charging (SCUR/ECUR - see TS32.299 6.3.2.1)*/
192 } cdp_cc_acc_type_t;
193 
194 /** Credit Control Failure Handling */
195 typedef enum {
196 	ACC_CC_CCFH_UNKNOWN				= 0,
197 	ACC_CC_CCFH_CONTINUE 			= 1,
198 	ACC_CC_CCFH_TERMINATE			= 2,
199 	ACC_CC_CCFH_RETRY_AND_TERMINATE	= 3,
200 } cdp_cc_acc_ccfh_t;
201 
202 /** Credit Control Final Unit Action */
203 typedef enum {
204 	ACC_CC_FUI_UNKNOWN				= 0,
205 	ACC_CC_FUI_TERMINATE			= 1,
206 } cdp_cc_acc_fua_t;
207 
208 /** Structure for accounting sessions */
209 typedef struct _acc_session {
210 	cdp_acc_state_t state;					/**< current state */
211 	str dlgid;       						/**< application-level identifier, combines application session (e.g. SIP dialog) or event with diameter accounting session */
212 	unsigned int acct_record_number; 		/**< number of last accounting record within this session */
213 	time_t aii;	 							/**< expiration of Acct-Interim-Interval (seconds) */
214 	time_t timeout;							/**< session timeout (seconds) */
215 	void* generic_data;
216 } cdp_acc_session_t;
217 
218 /** Structure for credit control accounting sessions (RFC 4006)*/
219 typedef struct _cc_acc_session {
220 	cdp_cc_acc_state_t state;				/**< current state */
221 	time_t discon_time;						/**< the time we went into DISCON state. we use this to cleanup dead sessions*/
222 	cdp_cc_acc_type_t type;					/**< type of CC, event or session (each have a different state machine - see RFC 4006 */
223 	cdp_cc_acc_ccfh_t ccfh;					/**< credit control failure handling type set for this session */
224 	//	cdp_cc_acc_fua_t fua;					/**< final unit action */
225 	int fua;								/**< TODO: clean this up */
226 	unsigned int acct_record_number; 		/**< number of last accounting record within this session */
227 	time_t timeout;							/**< session timeout (seconds) - this is to prevent idle sessions from 'hanging' around */
228 	time_t charging_start_time;				/**< the time the session started to charge */
229 	time_t last_reservation_request_time;	/**< the last time we requested reservation for the current granted units */
230 	int reserved_units;						/**< current number of granted units */
231 	int reserved_units_validity_time;		/**< number of seconds current granted units valid for */
232 
233 	void* generic_data;
234 } cdp_cc_acc_session_t;
235 
236 /** Structure for session identification */
237 typedef struct _cdp_session_t {
238 	unsigned int hash;
239 	str id;                             /**< session-ID as string */
240 	unsigned int application_id;		/**< specific application id associated with this session */
241 	unsigned int vendor_id;				/**< specific vendor id for this session */
242 	cdp_session_type_t type;
243 	str dest_host, dest_realm; 			/*the destination host and realm, used only for auth, for the moment*/
244 	str sticky_peer_fqdn;                           /*peer that we would like to stick for for this session*/
245 	int sticky_peer_fqdn_buflen;                     /*length of buffer available for sticky peer*/
246 	union {
247 		cdp_auth_session_t auth;
248 		cdp_acc_session_t acc;
249 		cdp_cc_acc_session_t cc_acc;
250 		void *generic_data;
251 	} u;
252 
253 	AAASessionCallback_f *cb;			/**< session callback function */
254 
255 	struct _cdp_session_t *next,*prev;
256 } cdp_session_t;
257 
258 /** Session list structure */
259 typedef struct _cdp_session_list_t {
260 	gen_lock_t *lock;				/**< lock for list operations */
261 	cdp_session_t *head,*tail;		/**< first, last sessions in the list */
262 } cdp_session_list_t;
263 
264 int cdp_sessions_init(int hash_size);
265 int cdp_sessions_destroy();
266 void cdp_sessions_log();
267 int cdp_sessions_timer(time_t now, void* ptr);
268 
269 void cdp_session_cleanup(cdp_session_t* s, AAAMessage* msg);	/**< Session cleanup for all session types */
270 
271 
272 cdp_session_t* cdp_get_session(str id);
273 cdp_session_t* cdp_new_session(str id,cdp_session_type_t type); //this function is needed in the peerstatemachine
274 
275 void cdp_add_session(cdp_session_t *x);
276 cdp_session_t* cdp_new_auth_session(str id,int is_client,int is_statefull);
277 cdp_session_t* cdp_new_cc_acc_session(str id, int is_statefull);	//new redit control acct session
278 
279 /*           API Exported */
280 typedef cdp_session_t AAASession;
281 
282 AAASession* AAACreateSession(void *generic_data);
283 typedef AAASession* (*AAACreateSession_f)(void *generic_data);
284 
285 AAASession* AAAMakeSession(int app_id,int type,str session_id);
286 typedef AAASession* (*AAAMakeSession_f)(int app_id,int type,str session_id);
287 
288 AAASession* AAAGetSession(str id);
289 typedef AAASession* (*AAAGetSession_f)(str id);
290 
291 void AAADropSession(AAASession *s);
292 typedef void (*AAADropSession_f)(AAASession *s);
293 
294 void AAASessionsUnlock(unsigned int hash);
295 typedef void (*AAASessionsUnlock_f) (unsigned int hash);
296 
297 void AAASessionsLock(unsigned int hash);
298 typedef void (*AAASessionsLock_f) (unsigned int hash);
299 
300 AAASession* AAACreateClientAuthSession(int is_statefull,AAASessionCallback_f *cb,void *generic_data);
301 typedef AAASession* (*AAACreateClientAuthSession_f)(int is_statefull,AAASessionCallback_f *cb,void *generic_data);
302 
303 AAASession* AAACreateServerAuthSession(AAAMessage *msg,int is_statefull,AAASessionCallback_f *cb,void *generic_data);
304 typedef AAASession* (*AAACreateServerAuthSession_f)(AAAMessage *msg,int is_statefull,AAASessionCallback_f *cb,void *generic_data);
305 
306 AAASession* AAAGetAuthSession(str id);
307 typedef AAASession* (*AAAGetAuthSession_f)(str id);
308 
309 void AAADropAuthSession(AAASession *s);
310 typedef void (*AAADropAuthSession_f)(AAASession *s);
311 
312 void AAATerminateAuthSession(AAASession *s);
313 typedef void (*AAATerminateAuthSession_f)(AAASession *s);
314 
315 AAASession* AAAGetCCAccSession(str id);
316 typedef AAASession* (*AAAGetCCAccSession_f)(str id);
317 
318 AAASession* AAACreateAccSession(void *generic_data);
319 void AAADropAccSession(AAASession *s);
320 
321 AAASession* AAACreateCCAccSession(AAASessionCallback_f *cb, int is_session, void *generic_data);	/*create CreditControl accounting session*/
322 typedef AAASession* (*AAACreateCCAccSession_f)(AAASessionCallback_f *cb, int is_session, void *generic_data);
323 
324 int AAAStartChargingCCAccSession(AAASession *s);
325 typedef int (*AAAStartChargingCCAccSession_f)(AAASession *s);
326 
327 void AAADropCCAccSession(AAASession *s);		/*drop CreditControl accounting session*/
328 typedef void (*AAADropCCAccSession_f)(AAASession *s);
329 
330 void AAATerminateCCAccSession(AAASession *s);
331 typedef void (*AAATerminateCCAccSession_f)(AAASession *s);
332 
333 #endif
334