1 /*
2  *
3  * Copyright (C) 2012 Smile Communications, jason.penton@smilecoms.com
4  * Copyright (C) 2012 Smile Communications, richard.good@smilecoms.com
5  *
6  * The initial version of this code was written by Dragos Vingarzan
7  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
8  * Fruanhofer Institute. It was and still is maintained in a separate
9  * branch of the original SER. We are therefore migrating it to
10  * Kamailio/SR and look forward to maintaining it from here on out.
11  * 2011/2012 Smile Communications, Pty. Ltd.
12  * ported/maintained/improved by
13  * Jason Penton (jason(dot)penton(at)smilecoms.com and
14  * Richard Good (richard(dot)good(at)smilecoms.com) as part of an
15  * effort to add full IMS support to Kamailio/SR using a new and
16  * improved architecture
17  *
18  * NB: Alot of this code was originally part of OpenIMSCore,
19  * FhG Fokus.
20  * Copyright (C) 2004-2006 FhG Fokus
21  * Thanks for great work! This is an effort to
22  * break apart the various CSCF functions into logically separate
23  * components. We hope this will drive wider use. We also feel
24  * that in this way the architecture is more complete and thereby easier
25  * to manage in the Kamailio/SR environment
26  *
27  * This file is part of Kamailio, a free SIP server.
28  *
29  * Kamailio is free software; you can redistribute it and/or modify
30  * it under the terms of the GNU General Public License as published by
31  * the Free Software Foundation; either version 2 of the License, or
32  * (at your option) any later version
33  *
34  * Kamailio is distributed in the hope that it will be useful,
35  * but WITHOUT ANY WARRANTY; without even the implied warranty of
36  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
37  * GNU General Public License for more details.
38  *
39  * You should have received a copy of the GNU General Public License
40  * along with this program; if not, write to the Free Software
41  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
42  *
43  */
44 
45 #ifndef USRLOC_H
46 #define USRLOC_H
47 
48 #include <time.h>
49 #include "../../core/counters.h"
50 #include "ul_callback.h"
51 #include "../../core/qvalue.h"
52 #include "../../core/str.h"
53 #include "../../modules/tm/dlg.h"
54 #include "../cdp/diameter_ims_code_avp.h"
55 
56 #define NO_DB         0
57 #define WRITE_THROUGH 1
58 #define WRITE_BACK    2		//not implemented yet
59 #define DB_ONLY	      3		//not implemented yet
60 
61 #define SEARCH_NORMAL 0
62 #define SEARCH_RECEIVED 1
63 
64 #define ALIAS        "alias="
65 #define ALIAS_LEN (sizeof(ALIAS) - 1)
66 
67 #define RINSTANCE   "rinstance="
68 #define RINSTANCE_LEN (sizeof(RINSTANCE) - 1)
69 
70 #define VALID_CONTACT(c, t)   ((c->expires>t) || (c->expires==0))
71 
72 #define SEARCH_SERVICE_ROUTES 1<<0      /* bitmap of extra search functionality when searching for contacts */
73 
74 struct hslot; /*!< Hash table slot */
75 struct socket_info;
76 
77 int get_alias_host_from_contact(str *contact_uri_params, str *alias_host);
78 
79 struct udomain {
80     str* name; /*!< Domain name (NULL terminated) */
81     int size; /*!< Hash table size */
82     struct hslot* table; /*!< Hash table - array of collision slots */
83     /* statistics */
84     stat_var *contacts; /*!< no of registered contacts */
85     stat_var *expired; /*!< no of expires */
86 };
87 typedef struct udomain udomain_t;
88 
89 /** Public Identity Structure */
90 typedef struct {
91     char barring; /**< Barring state									*/
92     str public_identity; /**< Public Identity string							*/
93     str wildcarded_psi; /** if exists is the wildcarded psi					*/
94 } ims_public_identity;
95 
96 /** TLS SA Information */
97 typedef struct tls {
98     unsigned short port_tls; /**< Port UE TLS						*/
99     unsigned long session_hash;
100 } tls_t;
101 
102 /** IPSec SA Information */
103 typedef struct ipsec {
104     unsigned int spi_uc; /**< SPI Client to use					*/
105     unsigned int spi_us; /**< SPI Server to use					*/
106     unsigned int spi_pc; /**< SPI Client to use					*/
107     unsigned int spi_ps; /**< SPI Server to use					*/
108     unsigned short port_uc; /**< Port UE Client						*/
109     unsigned short port_us; /**< Port UE Server						*/
110     unsigned short port_pc; /**< Port Proxy Client		*/
111     unsigned short port_ps; /**< Port Proxy Server      */
112 
113     str ealg; /**< Cypher Algorithm - ESP				*/
114     str r_ealg; /**< received Cypher Algorithm - ESP	*/
115     str ck; /**< Cypher Key							*/
116     str alg; /**< Integrity Algorithm - AH			*/
117     str r_alg; /**<received Integrity Algorithm - AH	*/
118     str ik; /**< Integrity Key						*/
119     str prot; /**< Protocol (ah/esp) */
120     str mod; /**< Mode (transport/tunnel) */
121 } ipsec_t;
122 
123 typedef enum sec_type {
124     SECURITY_NONE = 0,
125     SECURITY_IPSEC = 1,
126     SECURITY_TLS = 2,
127 } security_type;
128 
129 typedef struct security {
130     str sec_header; /**< Security Header value 				*/
131     security_type type; /**< Type of security in use			*/
132 
133     union {
134         ipsec_t *ipsec; /**< IPSec SA information, if any		*/
135         tls_t *tls; /**< TLS SA information, if any		*/
136     } data;
137     float q;
138 } security_t;
139 
140 typedef struct udomain_head {
141     str* name;
142 } udomain_head_t;
143 
144 /* public identity structure. To be associated with a contact */
145 typedef struct ppublic {
146     str public_identity; /**< Public identity */
147     char is_default; /**< is this the default identity for the contact */
148     struct ppublic* next;
149     struct ppublic* prev;
150 } ppublic_t;
151 
152 /** Enumeration for public identity Registration States */
153 enum pcontact_reg_states {
154     PCONTACT_ANY = 0,
155     PCONTACT_NOT_REGISTERED = 1<<0, /**< User not-registered, no profile stored	*/
156     PCONTACT_REGISTERED = 1<<1, /**< User registered						*/
157     PCONTACT_REG_PENDING = 1<<2, /**< User not-registered, profile stored	*/
158     PCONTACT_REG_PENDING_AAR = 1<<3, /**< User not-registered, profile stored, AAR sent	*/
159     PCONTACT_DEREGISTERED = 1<<4,
160     PCONTACT_DEREG_PENDING_PUBLISH = 1<<5
161 };
162 
reg_state_to_string(enum pcontact_reg_states reg_state)163 static inline char* reg_state_to_string(enum pcontact_reg_states reg_state) {
164     switch (reg_state) {
165         case PCONTACT_NOT_REGISTERED:
166             return "not registered";
167         case PCONTACT_REGISTERED:
168             return "registered";
169         case PCONTACT_REG_PENDING:
170             return "registration pending";
171         case PCONTACT_DEREGISTERED:
172             return "unregistered";
173         case PCONTACT_DEREG_PENDING_PUBLISH:
174             return "deregistration pending, publish sent";
175         case PCONTACT_REG_PENDING_AAR:
176             return "registration pending, aar sent";
177         default:
178             return "unknown";
179     }
180 }
181 
182 typedef struct pcontact_info {
183     unsigned short searchflag; /*!search flag - what to search on */
184     unsigned short extra_search_criteria;
185     str aor; /* contact uri */
186     str via_host;
187     unsigned short via_port;
188     unsigned short via_prot;
189     str received_host;
190     unsigned short received_port;
191     unsigned short received_proto; /*!< from transport */
192     str* path;
193     time_t expires;
194     str* callid;
195     str* public_ids;
196     int num_public_ids;
197     str* service_routes;
198     int num_service_routes;
199     str* rx_regsession_id;
200     enum pcontact_reg_states reg_state;
201 } pcontact_info_t;
202 
203 /*! \brief
204  * Basic hash table element
205  */
206 typedef struct pcontact {
207     unsigned int aorhash; /*!< Hash over address of record */
208     unsigned int sl; /*!< slot number */
209     struct hslot* slot; /*!< Collision slot in the hash table array we belong to */
210     str* domain; /*!< Pointer to domain we belong to (null terminated string) */
211     str aor; /*!< Address of record */
212     str rinstance;
213     str contact_host; /*!< host part of contact */
214     str contact_user; /*!< user part of contact */
215     unsigned short contact_port; /*!< port part of contact */
216     str callid; /*!< Call-ID */
217     str received_host; /*!< host part of src address where register came from */
218     unsigned short received_port; /*!< port register was received from */
219     unsigned short received_proto;
220     /*!< from transport */;
221     str via_host;
222     unsigned short via_port;
223     unsigned short via_proto;
224     str path; /*!< Path header */
225     str rx_session_id; /*!< Rx Session ID for registration Rx AF session - not used if not using diameter_rx */
226     enum pcontact_reg_states reg_state; /*!< Reg state of contact */
227     time_t expires; /*!< expires time for contact */
228     str* service_routes; /*!< Array of service routes */
229     unsigned short num_service_routes; /*!< Number of service routes */
230     security_t *security; /**< Security-Client Information		*/
231     security_t *security_temp; /**< Security-Client Information (temp)	*/
232     ppublic_t* head; /*!< list of associated public identities */
233     ppublic_t* tail;
234     struct socket_info *sock; /*!< received socket */
235     struct ulcb_head_list cbs; /*!< contact callback list */
236     struct pcontact* prev; /*!< Next item in the hash entry */
237     struct pcontact* next; /*!< Previous item in the hash entry */
238 } pcontact_t;
239 
240 typedef int (*get_pcontact_t)(struct udomain* _d, pcontact_info_t* contact_info, struct pcontact** _c);
241 
242 typedef int (*assert_identity_t)(struct udomain* _d, str * _host, unsigned short _port, unsigned short _proto, str * _identity);
243 
244 typedef int (*insert_pcontact_t)(struct udomain* _d, str* _aor, struct pcontact_info* ci, struct pcontact** _c);
245 typedef int (*delete_pcontact_t)(struct udomain* _d, struct pcontact* _c);
246 typedef int (*unreg_pending_contacts_cb_t)(struct udomain* _d, struct pcontact* _c, int type);
247 typedef int (*update_pcontact_t)(struct udomain* _d, struct pcontact_info* ci, struct pcontact* _c);
248 typedef int (*update_rx_regsession_t)(struct udomain* _d, str* session_id, struct pcontact* _c);
249 
250 typedef void (*lock_udomain_t)(struct udomain* _d, str *via_host, unsigned short via_port, unsigned short via_proto);
251 typedef void (*unlock_udomain_t)(struct udomain* _d, str *via_host, unsigned short via_port, unsigned short via_proto);
252 typedef int (*register_udomain_t)(const char* _n, struct udomain** _d);
253 typedef int (*get_udomain_t)(const char* _n, udomain_t** _d);
254 typedef int (*get_all_ucontacts_t)(void* buf, int len, unsigned int flags, unsigned int part_idx, unsigned int part_max);
255 
256 /*security related API signatures */
257 typedef int (*update_security_t)(struct udomain* _d, security_type _t, security_t* _s, struct pcontact* _c);
258 typedef int (*update_temp_security_t)(struct udomain* _d, security_type _t, security_t* _s, struct pcontact* _c);
259 
260 /* statistic APIs */
261 typedef unsigned long(*get_number_of_contacts_t)();
262 
263 /*! usrloc API export structure */
264 typedef struct usrloc_api {
265     int use_domain; /*! use_domain module parameter */
266     int db_mode; /*! db_mode module parameter */
267 
268     register_udomain_t register_udomain;
269     get_udomain_t get_udomain;
270     lock_udomain_t lock_udomain;
271     unlock_udomain_t unlock_udomain;
272 
273     insert_pcontact_t insert_pcontact;
274     delete_pcontact_t delete_pcontact;
275     unreg_pending_contacts_cb_t unreg_pending_contacts_cb;
276     get_pcontact_t get_pcontact;
277     assert_identity_t assert_identity;
278 
279     update_pcontact_t update_pcontact;
280     update_rx_regsession_t update_rx_regsession;
281     get_all_ucontacts_t get_all_ucontacts;
282 
283     update_security_t update_security;
284     update_temp_security_t update_temp_security;
285 
286     register_ulcb_t register_ulcb;
287 
288 	get_number_of_contacts_t get_number_of_contacts;
289 } usrloc_api_t;
290 
291 /*! usrloc API export bind function */
292 typedef int (*bind_usrloc_t)(usrloc_api_t* api);
293 
294 #endif
295