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 #include "../../core/str.h"
45 #include "../../core/socket_info.h"
46 #include "../../core/parser/parse_allow.h"
47 #include "../../core/parser/parse_methods.h"
48 #include "../../core/parser/msg_parser.h"
49 #include "../../core/parser/parse_to.h"
50 #include "../../core/parser/parse_uri.h"
51 #include "../../core/dprint.h"
52 #include "../../core/trim.h"
53 #include "../../core/ut.h"
54 #include "../../core/qvalue.h"
55 #include "../../core/dset.h"
56 #include "../../core/mod_fix.h"
57 #include "../../core/strutils.h"
58 #include "../../core/counters.h"
59
60 #ifdef USE_TCP
61 #include "../../core/tcp_server.h"
62 #endif
63
64 #include "../ims_usrloc_scscf/usrloc.h"
65 #include "common.h"
66 #include "sip_msg.h"
67 #include "rerrno.h"
68 #include "reply.h"
69 #include "ims_registrar_scscf_mod.h"
70 #include "regtime.h"
71 #include "path.h"
72 #include "save.h"
73 #include "config.h"
74 #include "server_assignment.h"
75 #include "userdata_parser.h"
76 #include "../../lib/ims/ims_getters.h"
77 #include "registrar_notify.h"
78
79 #include "cxdx_sar.h"
80
81 extern struct tm_binds tmb;
82 extern int store_data_on_dereg; /**< should we store SAR user data on de-registration */
83
84 extern int ue_unsubscribe_on_dereg;
85 extern int user_data_always;
86
87 /* \brief
88 * Return randomized expires between expires-range% and expires.
89 * RFC allows only value less or equal to the one provided by UAC.
90 */
randomize_expires(int expires,int range)91 static inline int randomize_expires(int expires, int range) {
92 /* if no range is given just return expires */
93 if (range == 0) return expires;
94
95 int range_min = expires - (float) range / 100 * expires;
96
97 return range_min + (float) (kam_rand() % 100) / 100 * (expires - range_min);
98 }
99
100 /*! \brief
101 * Calculate absolute expires value per contact as follows:
102 * 1) If the contact has expires value, use the value. If it
103 * is not zero, add actual time to it
104 * 2) If the contact has no expires parameter, use expires
105 * header field in the same way
106 * 3) If the message contained no expires header field, use
107 * the default value
108 */
calc_contact_expires(contact_t * c,int expires_hdr,int sos_reg)109 static inline int calc_contact_expires(contact_t *c, int expires_hdr, int sos_reg) {
110 int r = 0;
111 if(c && c->expires)
112 str2int(&(c->expires->body), (unsigned int*) &r);
113 else if (expires_hdr >= 0)
114 r = expires_hdr;
115 else {
116 r = (sos_reg > 0) ? default_registrar_cfg.em_default_expires : default_registrar_cfg.default_expires;
117 goto end;
118 }
119 if (!sos_reg && r < default_registrar_cfg.min_expires) {
120 r = default_registrar_cfg.min_expires;
121 goto end;
122 }
123 if (sos_reg && r < default_registrar_cfg.em_min_expires) {
124 r = default_registrar_cfg.em_min_expires;
125 goto end;
126 }
127 if (!sos_reg && r > default_registrar_cfg.max_expires) {
128 r = default_registrar_cfg.max_expires;
129 goto end;
130 }
131 if (sos_reg && r > default_registrar_cfg.em_max_expires) {
132 r = default_registrar_cfg.em_min_expires;
133 goto end;
134 }
135 end:
136 r = randomize_expires(r, default_registrar_cfg.default_expires_range);
137 LM_DBG("Calculated expires for contact is %d\n", r);
138 return time(NULL) + r;
139 }
140
141 /*! \brief
142 * Process request that contained a star, in that case,
143 * we will remove all bindings with the given impu
144 * from the usrloc and return 200 OK response
145 */
star(udomain_t * _d,str * _a)146 static inline int star(udomain_t* _d, str* _a) {
147 impurecord_t* r;
148
149 ul.lock_udomain(_d, _a);
150
151 if (ul.delete_impurecord(_d, _a, 0) != 0) {
152 LM_ERR("failed to remove record from usrloc\n");
153
154 /* Delete failed, try to get corresponding
155 * record structure and send back all existing
156 * contacts
157 */
158 rerrno = R_UL_DEL_R;
159
160 if (ul.get_impurecord(_d, _a, &r) == 0) {
161 contact_for_header_t** contact_header = 0;
162 build_contact(r, contact_header, 0);
163 free_contact_buf(*contact_header);
164 ul.unlock_udomain(_d, _a);
165 }
166 return -1;
167 }
168 ul.unlock_udomain(_d, _a);
169 return 0;
170 }
171
172 /*! \brief
173 */
get_sock_hdr(struct sip_msg * msg)174 static struct socket_info *get_sock_hdr(struct sip_msg *msg) {
175 struct socket_info *sock;
176 struct hdr_field *hf;
177 str socks;
178 str hosts;
179 int port;
180 int proto;
181 char c;
182
183 if (parse_headers(msg, HDR_EOH_F, 0) == -1) {
184 LM_ERR("failed to parse message\n");
185 return 0;
186 }
187
188 for (hf = msg->headers; hf; hf = hf->next) {
189 if (cmp_hdrname_str(&hf->name, &sock_hdr_name) == 0)
190 break;
191 }
192
193 /* hdr found? */
194 if (hf == 0)
195 return 0;
196
197 trim_len(socks.len, socks.s, hf->body);
198 if (socks.len == 0)
199 return 0;
200
201 /*FIXME: This is a hack */
202 c = socks.s[socks.len];
203 socks.s[socks.len] = '\0';
204 if (parse_phostport(socks.s, &hosts.s, &hosts.len, &port, &proto) != 0) {
205 socks.s[socks.len] = c;
206 LM_ERR("bad socket <%.*s> in \n",
207 socks.len, socks.s);
208 return 0;
209 }
210 socks.s[socks.len] = c;
211 sock = grep_sock_info(&hosts, (unsigned short) port,
212 (unsigned short) proto);
213 if (sock == 0) {
214 LM_ERR("non-local socket <%.*s>\n", socks.len, socks.s);
215 return 0;
216 }
217
218 LM_DBG("%d:<%.*s>:%d -> p=%p\n", proto, socks.len, socks.s, port_no, sock);
219
220 return sock;
221 }
222
223 /*! \brief
224 * Fills the common part (for all contacts) of the info structure
225 */
pack_ci(struct sip_msg * _m,contact_t * _c,unsigned int _e,unsigned int _f)226 static inline ucontact_info_t* pack_ci(struct sip_msg* _m, contact_t* _c, unsigned int _e, unsigned int _f) {
227 static ucontact_info_t ci;
228 static str no_ua = str_init("n/a");
229 static str callid;
230 static str path_received = {0, 0};
231 static str path;
232 static str received = {0, 0};
233 static int received_found;
234 static unsigned int allowed, allow_parsed;
235 static struct sip_msg *m = 0;
236 int_str val;
237
238 if (_m != 0) {
239 memset(&ci, 0, sizeof (ucontact_info_t));
240
241 /* Get callid of the message */
242 callid = _m->callid->body;
243 trim_trailing(&callid);
244 if (callid.len > CALLID_MAX_SIZE) {
245 rerrno = R_CALLID_LEN;
246 LM_ERR("callid too long\n");
247 goto error;
248 }
249 ci.callid = &callid;
250
251 /* Get CSeq number of the message */
252 if (str2int(&get_cseq(_m)->number, (unsigned int*) &ci.cseq) < 0) {
253 rerrno = R_INV_CSEQ;
254 LM_ERR("failed to convert cseq number\n");
255 goto error;
256 }
257
258 /* set received socket */
259 if (_m->flags & sock_flag) {
260 ci.sock = get_sock_hdr(_m);
261 if (ci.sock == 0)
262 ci.sock = _m->rcv.bind_address;
263 } else {
264 ci.sock = _m->rcv.bind_address;
265 }
266
267 /* additional info from message */
268 if (parse_headers(_m, HDR_USERAGENT_F, 0) != -1 && _m->user_agent
269 && _m->user_agent->body.len > 0 && _m->user_agent->body.len < MAX_UA_SIZE) {
270 ci.user_agent = &_m->user_agent->body;
271 } else {
272 ci.user_agent = &no_ua;
273 }
274
275 /* extract Path headers */
276 if (path_enabled) {
277 if (build_path_vector(_m, &path, &path_received) < 0) {
278 rerrno = R_PARSE_PATH;
279 goto error;
280 }
281 if (path.len && path.s) {
282 ci.path = &path;
283 if (path_mode != PATH_MODE_OFF) {
284 /* save in msg too for reply */
285 if (set_path_vector(_m, &path) < 0) {
286 rerrno = R_PARSE_PATH;
287 goto error;
288 }
289 }
290 }
291 }
292
293 if (_c->params) {
294 ci.params = _c->params;
295 }
296
297 /* set flags */
298 ci.flags = _f;
299 getbflagsval(0, &ci.cflags);
300
301 /* get received */
302 if (path_received.len && path_received.s) {
303 ci.cflags |= ul.nat_flag;
304 ci.received = path_received;
305 }
306
307 allow_parsed = 0; /* not parsed yet */
308 received_found = 0; /* not found yet */
309 m = _m; /* remember the message */
310 }
311
312 if (_c != 0) {
313 /* Calculate q value of the contact */
314 if (calc_contact_q(_c->q, &ci.q) < 0) {
315 rerrno = R_INV_Q;
316 LM_ERR("failed to calculate q\n");
317 goto error;
318 }
319
320 /* set expire time */
321 ci.expires = _e;
322
323 /* Get methods of contact */
324 if (_c->methods) {
325 if (parse_methods(&(_c->methods->body), &ci.methods) < 0) {
326 rerrno = R_PARSE;
327 LM_ERR("failed to parse contact methods\n");
328 goto error;
329 }
330 } else {
331 /* check on Allow hdr */
332 if (allow_parsed == 0) {
333 if (m && parse_allow(m) != -1) {
334 allowed = get_allow_methods(m);
335 } else {
336 allowed = ALL_METHODS;
337 }
338 allow_parsed = 1;
339 }
340 ci.methods = allowed;
341 }
342
343 /* get received */
344 if (ci.received.len == 0) {
345 if (_c->received) {
346 ci.received = _c->received->body;
347 } else {
348 if (received_found == 0) {
349 memset(&val, 0, sizeof (int_str));
350 if (rcv_avp_name.n != 0
351 && search_first_avp(rcv_avp_type, rcv_avp_name,
352 &val, 0) && val.s.len > 0) {
353 if (val.s.len > RECEIVED_MAX_SIZE) {
354 rerrno = R_CONTACT_LEN;
355 LM_ERR("received too long\n");
356 goto error;
357 }
358 received = val.s;
359 } else {
360 received.s = 0;
361 received.len = 0;
362 }
363 received_found = 1;
364 }
365 ci.received = received;
366 }
367 }
368
369 }
370
371 return &ci;
372 error:
373 return 0;
374 }
375
376 /**
377 * Deallocates memory used by a subscription.
378 * \note Must be called with the lock got to avoid races
379 * @param s - the ims_subscription to free
380 */
free_ims_subscription_data(ims_subscription * s)381 void free_ims_subscription_data(ims_subscription *s) {
382 int i, j, k;
383 if (!s)
384 return;
385 /* lock_get(s->lock); - must be called with the lock got */
386 for (i = 0; i < s->service_profiles_cnt; i++) {
387 for (j = 0; j < s->service_profiles[i].public_identities_cnt; j++) {
388 if (s->service_profiles[i].public_identities[j].public_identity.s)
389 shm_free(
390 s->service_profiles[i].public_identities[j].public_identity.s);
391 if (s->service_profiles[i].public_identities[j].wildcarded_psi.s)
392 shm_free(
393 s->service_profiles[i].public_identities[j].wildcarded_psi.s);
394
395 }
396 if (s->service_profiles[i].public_identities)
397 shm_free(s->service_profiles[i].public_identities);
398
399 for (j = 0; j < s->service_profiles[i].filter_criteria_cnt; j++) {
400 if (s->service_profiles[i].filter_criteria[j].trigger_point) {
401 for (k = 0;
402 k
403 < s->service_profiles[i].filter_criteria[j].trigger_point->spt_cnt;
404 k++) {
405 switch (s->service_profiles[i].filter_criteria[j].trigger_point->spt[k].type) {
406 case IFC_REQUEST_URI:
407 if (s->service_profiles[i].filter_criteria[j].trigger_point->spt[k].request_uri.s)
408 shm_free(
409 s->service_profiles[i].filter_criteria[j].trigger_point->spt[k].request_uri.s);
410 break;
411 case IFC_METHOD:
412 if (s->service_profiles[i].filter_criteria[j].trigger_point->spt[k].method.s)
413 shm_free(
414 s->service_profiles[i].filter_criteria[j].trigger_point->spt[k].method.s);
415 break;
416 case IFC_SIP_HEADER:
417 if (s->service_profiles[i].filter_criteria[j].trigger_point->spt[k].sip_header.header.s)
418 shm_free(
419 s->service_profiles[i].filter_criteria[j].trigger_point->spt[k].sip_header.header.s);
420 if (s->service_profiles[i].filter_criteria[j].trigger_point->spt[k].sip_header.content.s)
421 shm_free(
422 s->service_profiles[i].filter_criteria[j].trigger_point->spt[k].sip_header.content.s);
423 break;
424 case IFC_SESSION_CASE:
425 break;
426 case IFC_SESSION_DESC:
427 if (s->service_profiles[i].filter_criteria[j].trigger_point->spt[k].session_desc.line.s)
428 shm_free(
429 s->service_profiles[i].filter_criteria[j].trigger_point->spt[k].session_desc.line.s);
430 if (s->service_profiles[i].filter_criteria[j].trigger_point->spt[k].session_desc.content.s)
431 shm_free(
432 s->service_profiles[i].filter_criteria[j].trigger_point->spt[k].session_desc.content.s);
433 break;
434
435 }
436 }
437 if (s->service_profiles[i].filter_criteria[j].trigger_point->spt)
438 shm_free(
439 s->service_profiles[i].filter_criteria[j].trigger_point->spt);
440 shm_free(
441 s->service_profiles[i].filter_criteria[j].trigger_point);
442 }
443 if (s->service_profiles[i].filter_criteria[j].application_server.server_name.s)
444 shm_free(
445 s->service_profiles[i].filter_criteria[j].application_server.server_name.s);
446 if (s->service_profiles[i].filter_criteria[j].application_server.service_info.s)
447 shm_free(
448 s->service_profiles[i].filter_criteria[j].application_server.service_info.s);
449 if (s->service_profiles[i].filter_criteria[j].profile_part_indicator)
450 shm_free(
451 s->service_profiles[i].filter_criteria[j].profile_part_indicator);
452 }
453 if (s->service_profiles[i].filter_criteria)
454 shm_free(s->service_profiles[i].filter_criteria);
455
456 if (s->service_profiles[i].cn_service_auth)
457 shm_free(s->service_profiles[i].cn_service_auth);
458
459 if (s->service_profiles[i].shared_ifc_set)
460 shm_free(s->service_profiles[i].shared_ifc_set);
461 }
462 if (s->service_profiles)
463 shm_free(s->service_profiles);
464 if (s->private_identity.s)
465 shm_free(s->private_identity.s);
466 ul.unlock_subscription(s);
467 #ifdef EXTRA_DEBUG
468 LM_DBG("SUBSCRIPTION LOCK %p destroyed\n", s->lock);
469 #endif
470 lock_destroy(s->lock);
471 lock_dealloc(s->lock);
472 shm_free(s);
473
474 }
475
476 /** Check if an impu record exists.
477 * 1. must be in registered state (impurecord)
478 * 2. must have at least one valid contact
479 */
is_impu_registered(udomain_t * _d,str * public_identity)480 static inline int is_impu_registered(udomain_t* _d, str* public_identity) {
481 int res, ret = 1;
482 impurecord_t* impu;
483
484 ul.lock_udomain(_d, public_identity);
485 res = ul.get_impurecord(_d, public_identity, &impu);
486 if (res != 0) {
487 ul.unlock_udomain(_d, public_identity);
488 return 0;
489 } else {
490 //check reg status
491 if (impu->reg_state != IMPU_REGISTERED) {
492 LM_DBG("IMPU <%.*s> is not currently registered\n", public_identity->len, public_identity->s);
493 ret = 0;
494 }
495
496 //check valid contacts
497 if ((impu->linked_contacts.numcontacts <= 0) || (impu->linked_contacts.head == 0)) {
498 LM_DBG("IMPU <%.*s> has no valid contacts\n", public_identity->len, public_identity->s);
499 ret = 0;
500 }
501 ul.unlock_udomain(_d, public_identity);
502 }
503 return ret;
504 }
505
506 /**
507 * update the contacts for a public identity. Make sure you have the lock on the domain before calling this
508 * returns 0 on success, -1 on failure
509 */
update_contacts_helper(struct sip_msg * msg,impurecord_t * impu_rec,int assignment_type,int expires_hdr)510 static inline int update_contacts_helper(struct sip_msg* msg, impurecord_t* impu_rec, int assignment_type, int expires_hdr) {
511 struct hdr_field* h;
512 contact_t* chi; //contact header information
513 ucontact_info_t* ci; //ucontact info
514 qvalue_t qvalue;
515 int sos = 0, expires;
516 struct ucontact* ucontact;
517 int result, sl;
518
519 LM_DBG("updating the contacts for IMPU <%.*s>\n", impu_rec->public_identity.len, impu_rec->public_identity.s);
520
521 switch (assignment_type) {
522
523 case AVP_IMS_SAR_USER_DEREGISTRATION:
524 LM_DBG("update_contacts_helper: doing de-reg\n");
525 break;
526
527 case AVP_IMS_SAR_REGISTRATION:
528 case AVP_IMS_SAR_RE_REGISTRATION:
529 for (h = msg->contact; h; h = h->next) {
530 if (h->type == HDR_CONTACT_T && h->parsed) {
531
532 for (chi = ((contact_body_t*) h->parsed)->contacts; chi; chi =
533 chi->next) {
534 if (calc_contact_q(chi->q, &qvalue) != 0) {
535 LM_ERR("error on <%.*s>\n", chi->uri.len, chi->uri.s);
536 goto error;
537 }
538 sos = cscf_get_sos_uri_param(chi->uri);
539 if (sos < 0) {
540 LM_ERR("Error trying to determine if this is a sos contact <%.*s>\n", chi->uri.len, chi->uri.s);
541 goto error;
542 }
543 expires = calc_contact_expires(chi, expires_hdr, sos);
544 //TODO: this next line will fail if the expires is in the main body and not the contact body //FIXED
545 LM_DBG("Need to update contact: <%.*s>: "
546 "q_value [%d],"
547 "sos: [%d],"
548 "expires [%ld]\n", chi->uri.len, chi->uri.s, qvalue, sos, expires - time(NULL));
549
550 LM_DBG("packing contact information\n");
551 if ((ci = pack_ci(msg, chi, expires, 0)) == 0) {
552 LM_ERR("Failed to extract contact info\n");
553 goto error;
554 }
555
556 LM_DBG("adding/updating contact based on prior existence\n");
557 //stick the contacts into usrloc
558 //ul.lock_contact_slot(&chi->uri);
559 result = ul.get_ucontact(&chi->uri, ci->callid,
560 ci->path, ci->cseq, &ucontact);
561 if (result != 0) { //get_contact returns with lock
562 LM_DBG("inserting new contact\n");
563 if (ul.insert_ucontact(impu_rec, &chi->uri, ci,
564 &ucontact) != 0) {
565 LM_ERR("Error inserting contact <%.*s>\n", chi->uri.len, chi->uri.s);
566 // ul.unlock_contact_slot(&chi->uri);
567 goto error;
568 }
569 } else {
570 LM_DBG("Contact already exists - updating - it's currently in state [%d]\n", ucontact->state);
571 sl = ucontact->sl;
572 ul.lock_contact_slot_i(sl);
573 if (ucontact->state != CONTACT_VALID) {
574 LM_WARN("contact is not in state valid - this is a race between dereg and reg/re-reg");
575 ucontact->state = CONTACT_VALID; //TODO this should prob move into the contact info structure - ie pass state into update
576 }
577 if (ul.update_ucontact(impu_rec, ucontact, ci) != 0) {
578 LM_ERR("Error updating contact <%.*s>\n", chi->uri.len, chi->uri.s);
579 ul.unlock_contact_slot_i(sl);
580 ul.release_ucontact(ucontact);
581 // ul.unlock_contact_slot(&chi->uri);
582 goto error;
583 }
584 ul.unlock_contact_slot_i(sl);
585 ul.release_ucontact(ucontact);
586 }
587 // ul.unlock_contact_slot(&chi->uri);
588 }
589 }
590 }
591 break;
592 }
593
594 return 0;
595
596 error:
597 return -1;
598 }
599
600 /*NB remember to lock udomain prior to calling this*/
unregister_contact(contact_t * chi,contact_state_t state)601 static inline int unregister_contact(contact_t* chi, contact_state_t state) {
602 struct ucontact* ucontact;
603 str callid = {0, 0};
604 str path = {0, 0};
605
606
607 // if (_impu_rec) {
608 // LM_DBG("already have impurecord....\n");
609 // impu_rec = _impu_rec;
610 // } else {
611 // if (ul.get_impurecord(_d, public_identity, &impu_rec) != 0) {
612 // LM_ERR("Error, no public identity exists for <%.*s>\n", public_identity->len, public_identity->s);
613 // goto error;
614 // }
615 // }
616
617 if (ul.get_ucontact(&chi->uri, &callid, &path, 0/*cseq*/, &ucontact) != 0) {
618 LM_DBG("Can't unregister contact that does not exist <%.*s>\n", chi->uri.len, chi->uri.s);
619 // ul.unlock_udomain(_d, public_identity);
620 goto error;
621 }
622
623 get_act_time();
624 if (ucontact->state == CONTACT_DELETED) {
625 LM_DBG("Contact is not valid (expired/deleted).... ignoring\n");
626 ul.release_ucontact(ucontact);
627 return 0;
628 }
629
630 //Richard added this - fix to remove subscribes that have presentity and watcher uri same as a contact aor that is being removed
631 //When UEs explicitly dereg - they don't unsubscribe, so we remove subscriptions for them
632 //only do this if ue_unsubscribe_on_dereg is set to 0
633 // if (!ue_unsubscribe_on_dereg) {
634 // s = impu_rec->shead;
635 // LM_DBG("Checking if there is a subscription to this IMPU that has same watcher contact as this contact");
636 // while (s) {
637 //
638 // LM_DBG("Subscription for this impurecord: watcher uri [%.*s] presentity uri [%.*s] watcher contact [%.*s] ", s->watcher_uri.len, s->watcher_uri.s,
639 // s->presentity_uri.len, s->presentity_uri.s, s->watcher_contact.len, s->watcher_contact.s);
640 // LM_DBG("Contact to be removed [%.*s] ", ucontact->c.len, ucontact->c.s);
641 // if (contact_port_ip_match(&s->watcher_contact, &ucontact->c)) {
642 // //if ((s->watcher_contact.len == ucontact->c.len) && (strncasecmp(s->watcher_contact.s, ucontact->c.s, ucontact->c.len) == 0)) {
643 // LM_DBG("This contact has a subscription to its own status - so going to delete the subscription");
644 // ul.external_delete_subscriber(s, _d, 0 /*domain is locked*/);
645 // }
646 // s = s->next;
647 // }
648 // }
649
650 // if (ul.delete_ucontact(impu_rec, ucontact) != 0) {
651 ul.lock_contact_slot_i(ucontact->sl);
652 ucontact->state = state;
653 // notify_subscribers(impu_rec);
654 // ucontact->state = CONTACT_DELETED;
655 // if (ul.unlink_contact_from_impu(impu_rec, ucontact, 1, 1/*explicit dereg of contact*/) != 0) {
656 // LM_ERR("Failed to delete ucontact <%.*s>\n", chi->uri.len, chi->uri.s);
657 // }
658 ul.unlock_contact_slot_i(ucontact->sl);
659 ul.release_ucontact(ucontact);
660 // LM_DBG("Contact unlinked successfully <%.*s>\n", chi->uri.len, chi->uri.s);
661 // ul.unlock_udomain(_d, public_identity);
662 return 0;
663
664 error:
665 return -1;
666 }
667
668 /**
669 * Get the number of valid contacts for an impu. Ie contacts not expired and not in deleted or delete_pending state
670 * @param impu
671 * @return
672 */
get_number_of_valid_contacts(impurecord_t * impu)673 int get_number_of_valid_contacts(impurecord_t* impu) {
674 int ret = 0;
675 impu_contact_t *impucontact;
676 get_act_time();
677
678 impucontact = impu->linked_contacts.head;
679 while (impucontact) {
680 if (impucontact->contact) {
681 if VALID_CONTACT(impucontact->contact, act_time)
682 ret++;
683 } else {
684 //if we hit a null ref then we are at the end of the list.
685 return ret;
686 }
687 impucontact = impucontact->next;
688 }
689
690 return ret;
691 }
692
store_explicit_dereg_contact(struct sip_msg * msg,str ** explicit_dereg_contact,int * num_explicit_dereg_contact)693 int store_explicit_dereg_contact(struct sip_msg* msg, str ** explicit_dereg_contact, int *num_explicit_dereg_contact) {
694 int bytes_needed_explicit_dereg_contact = 0;
695 int len_num_explicit_dereg_contact = 0;
696 struct hdr_field* h;
697 contact_t* chi; //contact header information
698
699 LM_DBG("This is an explicit deregistration so we need to store the contact URI to send out NOTIFY\n");
700
701 //get lengths
702 for (h = msg->contact; h; h = h->next) {
703 if (h->type == HDR_CONTACT_T && h->parsed) {
704 for (chi = ((contact_body_t*) h->parsed)->contacts; chi; chi = chi->next) {
705 LM_DBG("URI [%.*s] len [%d]\n", chi->uri.len, chi->uri.s, chi->uri.len);
706 (*num_explicit_dereg_contact)++;
707 bytes_needed_explicit_dereg_contact += chi->uri.len;
708 LM_DBG("URI [%.*s] and current bytes needed [%d]\n", chi->uri.len, chi->uri.s, bytes_needed_explicit_dereg_contact);
709
710 }
711 }
712 }
713
714 LM_DBG("We have [%d] explicit contacts of total length [%d] to store\n", (*num_explicit_dereg_contact), bytes_needed_explicit_dereg_contact);
715
716 //now load data
717
718 len_num_explicit_dereg_contact = (sizeof (str)*(*num_explicit_dereg_contact)) + bytes_needed_explicit_dereg_contact;
719
720 *explicit_dereg_contact = (str*) shm_malloc(len_num_explicit_dereg_contact);
721 memset(*explicit_dereg_contact, 0, len_num_explicit_dereg_contact);
722
723 char* ptr = (char*) (*explicit_dereg_contact + *num_explicit_dereg_contact);
724
725 int count = 0;
726 //populate data
727 for (h = msg->contact; h; h = h->next) {
728 if (h->type == HDR_CONTACT_T && h->parsed) {
729 for (chi = ((contact_body_t*) h->parsed)->contacts; chi; chi = chi->next) {
730 LM_DBG("Adding [%.*s] to list of explicit contacts that have been de-reged\n", chi->uri.len, chi->uri.s);
731 (*explicit_dereg_contact)[count].s = ptr;
732 memcpy(ptr, chi->uri.s, chi->uri.len);
733 (*explicit_dereg_contact)[count].len = chi->uri.len;
734 ptr += chi->uri.len;
735 count++;
736 }
737 }
738 }
739
740 if (ptr != ((char*) *explicit_dereg_contact + len_num_explicit_dereg_contact)) {
741 LM_CRIT("buffer overflow\n");
742 return -1;
743 }
744
745 return 1;
746 }
747
748 /**
749 *
750 * @param msg
751 * @param _d
752 * @param public_identity
753 * @param assignment_type
754 * @param s
755 * @param ccf1
756 * @param ccf2
757 * @param ecf1
758 * @param ecf2
759 * @param contact_header
760 * @return 1 - success(contacts left) - unregistered contacts and remaining contacts in contact buffer for reply message
761 * 2 - success(no contacts left)
762 * <=0 - on failure
763 */
764
update_contacts(struct sip_msg * msg,udomain_t * _d,str * public_identity,int assignment_type,ims_subscription ** s,str * ccf1,str * ccf2,str * ecf1,str * ecf2,contact_for_header_t ** contact_header)765 int update_contacts(struct sip_msg* msg, udomain_t* _d,
766 str* public_identity, int assignment_type, ims_subscription** s,
767 str* ccf1, str* ccf2, str* ecf1, str* ecf2, contact_for_header_t** contact_header) {
768 int reg_state, i, j, k;
769 ims_public_identity* pi = 0;
770 impurecord_t* impu_rec, *tmp_impu_rec;
771 int expires_hdr = -1; //by default registration doesn't expire
772 struct hdr_field* h;
773 contact_t* chi; //contact header information
774 qvalue_t qvalue;
775 int sos = 0;
776 ims_subscription* subscription = 0;
777 int first_unbarred_impu = 1; //this is used to flag the IMPU as anchor for implicit set
778 int is_primary_impu = 0;
779 int ret = 1;
780
781 int num_explicit_dereg_contact = 0;
782 str *explicit_dereg_contact = 0;
783
784 if (msg) {
785 expires_hdr = cscf_get_expires_hdr(msg, 0); //get the expires from the main body of the sip message (global)
786 }
787
788 switch (assignment_type) {
789 case AVP_IMS_SAR_REGISTRATION:
790 LM_DBG("updating contacts in REGISTRATION state\n");
791 reg_state = IMS_USER_REGISTERED;
792 if (!s) {
793 LM_ERR("no userdata supplied for AVP_IMS_SAR_REGISTRATION\n");
794 goto error;
795 }
796
797 for (i = 0; i < (*s)->service_profiles_cnt; i++) {
798 for (j = 0; j < (*s)->service_profiles[i].public_identities_cnt; j++) {
799 pi = &((*s)->service_profiles[i].public_identities[j]);
800 ul.lock_udomain(_d, &pi->public_identity);
801 if (first_unbarred_impu && !pi->barring) {
802 is_primary_impu = 1;
803 first_unbarred_impu = 0;
804 } else {
805 is_primary_impu = 0;
806 }
807 if (ul.update_impurecord(_d, &pi->public_identity, 0, reg_state, -1 /*do not change send sar on delete */,
808 pi->barring, is_primary_impu, s, ccf1, ccf2, ecf1, ecf2, &impu_rec) != 0) {
809 LM_ERR("Unable to update impurecord for <%.*s>\n", pi->public_identity.len, pi->public_identity.s);
810 ul.unlock_udomain(_d, &pi->public_identity);
811 goto error;
812 }
813 //here we can do something with impu_rec if we want but we must unlock when done
814 //lets update the contacts
815 if (update_contacts_helper(msg, impu_rec, assignment_type, expires_hdr) != 0) {
816 LM_ERR("Failed trying to update contacts\n");
817 ul.unlock_udomain(_d, &pi->public_identity);
818 goto error;
819 }
820 ul.unlock_udomain(_d, &pi->public_identity);
821 }
822 }
823 //if we were successful up to this point, then we need to copy the contacts from main impu record (asserted IMPU) into the register response
824 ul.lock_udomain(_d, public_identity);
825 if (ul.get_impurecord(_d, public_identity, &impu_rec) != 0) {
826 LM_ERR("Error, we should have a record after registraion\n");
827 ul.unlock_udomain(_d, public_identity);
828 goto error;
829 }
830 //now build the contact buffer to be include in the reply message and unlock
831 build_contact(impu_rec, contact_header, 0);
832 build_p_associated_uri(*s);
833
834
835 for (h = msg->contact; h; h = h->next) {
836 if (h->type == HDR_CONTACT_T && h->parsed) {
837 for (chi = ((contact_body_t*) h->parsed)->contacts; chi; chi = chi->next) {
838 event_reg(0, impu_rec, IMS_REGISTRAR_CONTACT_REGISTERED, 0, 0, &chi->uri, 0, 0);
839 }
840 }
841 }
842
843
844 ul.unlock_udomain(_d, public_identity);
845 break;
846 case AVP_IMS_SAR_RE_REGISTRATION:
847 /* first update all the implicit IMPU based on the existing IMPUs subscription
848 * then, once done with the implicits, update the explicit with the new subscription data
849 */
850 LM_DBG("updating contacts in RE-REGISTRATION state\n");
851 reg_state = IMS_USER_REGISTERED;
852 ul.lock_udomain(_d, public_identity);
853 if (ul.get_impurecord(_d, public_identity, &impu_rec) != 0) {
854 LM_ERR("No IMPU record fond for re-registration...aborting\n");
855 ul.unlock_udomain(_d, public_identity);
856 goto error;
857 }
858
859 if (update_contacts_helper(msg, impu_rec, assignment_type, expires_hdr) != 0) { //update the contacts for the explicit IMPU
860 LM_ERR("Failed trying to update contacts for re-registration\n");
861 ul.unlock_udomain(_d, public_identity);
862 goto error;
863 }
864 //build the contact buffer for the exact registered contact for reply on explicit IMPU
865 build_contact(impu_rec, contact_header, msg);
866 build_p_associated_uri(impu_rec->s);
867
868 subscription = impu_rec->s;
869 if (!subscription) {
870 LM_ERR("No subscriber info associated with <%.*s>, not doing any implicit re-registrations\n", impu_rec->public_identity.len, impu_rec->public_identity.s);
871 //update the new subscription infor for the explicit IMPU
872 if (ul.update_impurecord(_d, public_identity, 0, reg_state, -1 /*do not change send sar on delete */, 0 /*this is explicit so barring must be 0*/, 0, s, ccf1, ccf2,
873 ecf1, ecf2, &impu_rec) != 0) {
874 LM_ERR("Unable to update explicit impurecord for <%.*s>\n", public_identity->len, public_identity->s);
875 }
876 build_contact(impu_rec, contact_header, msg);
877 ul.unlock_udomain(_d, public_identity);
878 break;
879 }
880
881 ul.lock_subscription(subscription);
882 subscription->ref_count++;
883 LM_DBG("ref count after add is now %d\n", subscription->ref_count);
884 ul.unlock_subscription(subscription);
885 ul.unlock_udomain(_d, public_identity);
886
887 //now update the implicit set
888 for (i = 0; i < subscription->service_profiles_cnt; i++) {
889 for (j = 0; j < subscription->service_profiles[i].public_identities_cnt; j++) {
890 pi = &(subscription->service_profiles[i].public_identities[j]);
891
892 if (memcmp(public_identity->s, pi->public_identity.s, public_identity->len) == 0) { //we don't need to update the explicit IMPU
893 LM_DBG("Ignoring explicit identity <%.*s>, updating later.....\n", public_identity->len, public_identity->s);
894 continue;
895 }
896 ul.lock_udomain(_d, &pi->public_identity);
897
898 //update the implicit IMPU with the new data
899 if (ul.update_impurecord(_d, &pi->public_identity, 0,
900 reg_state, -1 /*do not change send sar on delete */, pi->barring, 0, s, ccf1, ccf2, ecf1, ecf2,
901 &impu_rec) != 0) {
902 LM_ERR("Unable to update implicit impurecord for <%.*s>.... continuing\n", pi->public_identity.len, pi->public_identity.s);
903 ul.unlock_udomain(_d, &pi->public_identity);
904 continue;
905 }
906
907 //update the contacts for the explicit IMPU
908 if (update_contacts_helper(msg, impu_rec, assignment_type, expires_hdr) != 0) {
909 LM_ERR("Failed trying to update contacts for re-registration of implicit IMPU <%.*s>.......continuing\n", pi->public_identity.len, pi->public_identity.s);
910 ul.unlock_udomain(_d, &pi->public_identity);
911 continue;
912 }
913 ul.unlock_udomain(_d, &pi->public_identity);
914 }
915 }
916 ul.lock_subscription(subscription);
917 subscription->ref_count--;
918 LM_DBG("ref count after sub is now %d\n", subscription->ref_count);
919 ul.unlock_subscription(subscription);
920
921 ul.lock_udomain(_d, public_identity);
922 //finally we update the explicit IMPU record with the new data
923 if (ul.update_impurecord(_d, public_identity, 0, reg_state, -1 /*do not change send sar on delete */, 0 /*this is explicit so barring must be 0*/, 0, s, ccf1, ccf2, ecf1, ecf2, &impu_rec) != 0) {
924 LM_ERR("Unable to update explicit impurecord for <%.*s>\n", public_identity->len, public_identity->s);
925 }
926
927 for (h = msg->contact; h; h = h->next) {
928 if (h->type == HDR_CONTACT_T && h->parsed) {
929 for (chi = ((contact_body_t*) h->parsed)->contacts; chi; chi = chi->next) {
930 event_reg(0, impu_rec, IMS_REGISTRAR_CONTACT_REGISTERED, 0, 0, &chi->uri, 0, 0);
931 }
932 }
933 }
934
935 ul.unlock_udomain(_d, public_identity);
936 break;
937 case AVP_IMS_SAR_USER_DEREGISTRATION:
938 /*TODO: if its not a star lets find all the contact records and remove them*/
939 //first we update the state of the contact/s
940 for (h = msg->contact; h; h = h->next) {
941 if (h->type == HDR_CONTACT_T && h->parsed) {
942 for (chi = ((contact_body_t*) h->parsed)->contacts; chi; chi = chi->next) {
943 if (calc_contact_q(chi->q, &qvalue) != 0) {
944 LM_ERR("error on <%.*s>\n", chi->uri.len, chi->uri.s);
945 goto error;
946 }
947 sos = cscf_get_sos_uri_param(chi->uri);
948 if (sos < 0) {
949 LM_ERR("Error trying to determine if this is a sos contact <%.*s>\n", chi->uri.len, chi->uri.s);
950 goto error;
951 }
952 calc_contact_expires(chi, expires_hdr, sos);
953 if (unregister_contact(chi, CONTACT_DELETE_PENDING) != 0) {
954 LM_DBG("Unable to remove contact <%.*s\n", chi->uri.len, chi->uri.s);
955
956 }
957 //add this contact to the successful unregistered in the 200OK so the PCSCF can also see what is de-registered
958 build_expired_contact(chi, contact_header);
959 }
960 }
961 }
962
963 if (store_explicit_dereg_contact(msg, &explicit_dereg_contact, &num_explicit_dereg_contact) == -1) {
964 LM_ERR("Error trying to store explicit dereg contacts\n");
965 goto error;
966 }
967
968 for (k = 0; k < num_explicit_dereg_contact; k++) {
969 LM_DBG("Stored explicit contact to dereg: [%.*s]\n", (explicit_dereg_contact)[k].len, (explicit_dereg_contact)[k].s);
970 }
971
972 //now, we get the subscription
973 ul.lock_udomain(_d, public_identity);
974 if (ul.get_impurecord(_d, public_identity, &impu_rec) != 0) {
975 LM_DBG("Error retrieving impu record on explicit de-reg nothing we can do from here on... aborting..\n");
976 ul.unlock_udomain(_d, public_identity);
977 goto error;
978 }
979 int num_contacts = get_number_of_valid_contacts(impu_rec);
980 if (num_contacts > 0) {
981 LM_DBG("contacts still available\n");
982 //TODO: add all other remaining contacts to reply message (contacts still registered for this IMPU)
983 ret = 1;
984 } else {
985 LM_DBG("no more contacts available\n");
986 ret = 2;
987 }
988 ims_subscription* subscription = impu_rec->s;
989
990 if (!subscription) {
991 LM_WARN("subscription is null..... continuing without de-registering implicit set\n");
992 } else {
993 ul.lock_subscription(subscription);
994 subscription->ref_count++; //this is so we can de-reg the implicit set just now without holding the lock on the current IMPU
995 ul.unlock_subscription(subscription);
996 }
997
998 ul.unlock_udomain(_d, public_identity);
999
1000 if (subscription) {
1001 for (i = 0; i < subscription->service_profiles_cnt; i++) {
1002 for (j = 0; j < subscription->service_profiles[i].public_identities_cnt; j++) {
1003 pi = &(subscription->service_profiles[i].public_identities[j]);
1004 // if (memcmp(public_identity->s, pi->public_identity.s, public_identity->len) == 0) { //we don't need to update the explicit IMPU
1005 // LM_DBG("Ignoring explicit identity <%.*s>, already de-reg/updated\n", public_identity->len, public_identity->s);
1006 // continue;
1007 // }
1008 ul.lock_udomain(_d, &pi->public_identity);
1009 if (ul.get_impurecord(_d, &pi->public_identity, &tmp_impu_rec) != 0) {
1010 LM_ERR("Can't find IMPU for implicit de-registration update....continuing\n");
1011 ul.unlock_udomain(_d, &pi->public_identity);
1012 continue;
1013 }
1014 LM_DBG("Implicit deregistration of IMPU <%.*s>\n", pi->public_identity.len, pi->public_identity.s);
1015 //TODO_LATEST: need to add back the following functionality
1016 // if (!ue_unsubscribe_on_dereg) {
1017 // subscriber = tmp_impu_rec->shead;
1018 // LM_DBG("Checking if there is a subscription to this IMPU that has same watcher contact as this contact");
1019 // while (s) {
1020 //
1021 // LM_DBG("Subscription for this impurecord: watcher uri [%.*s] presentity uri [%.*s] watcher contact [%.*s] ", subscriber->watcher_uri.len, subscriber->watcher_uri.s,
1022 // subscriber->presentity_uri.len, subscriber->presentity_uri.s, subscriber->watcher_contact.len, subscriber->watcher_contact.s);
1023 // LM_DBG("Contact to be removed [%.*s] ", ucontact->c.len, ucontact->c.s);
1024 // if (contact_port_ip_match(&subscriber->watcher_contact, &ucontact->c)) {
1025 // //if ((s->watcher_contact.len == ucontact->c.len) && (strncasecmp(s->watcher_contact.s, ucontact->c.s, ucontact->c.len) == 0)) {
1026 // LM_DBG("This contact has a subscription to its own status - so going to delete the subscription");
1027 // ul.external_delete_subscriber(subscriber, _d, 0 /*domain is locked*/);
1028 // }
1029 // s = s->next;
1030 // }
1031 // }
1032 notify_subscribers(tmp_impu_rec, (str*) explicit_dereg_contact, num_explicit_dereg_contact, IMS_REGISTRAR_CONTACT_UNREGISTERED);
1033
1034 for (h = msg->contact; h; h = h->next) {
1035 if (h->type == HDR_CONTACT_T && h->parsed) {
1036 for (chi = ((contact_body_t*) h->parsed)->contacts; chi; chi = chi->next) {
1037 if (calc_contact_q(chi->q, &qvalue) != 0) {
1038 LM_ERR("error on <%.*s>\n", chi->uri.len, chi->uri.s);
1039 ul.unlock_udomain(_d, &pi->public_identity);
1040 LM_ERR("no q value of implicit de-reg....continuing\n");
1041 continue;
1042 }
1043 sos = cscf_get_sos_uri_param(chi->uri);
1044 if (sos < 0) {
1045 LM_ERR("Error trying to determine if this is a sos contact <%.*s>\n", chi->uri.len, chi->uri.s);
1046 ul.unlock_udomain(_d, public_identity);
1047 goto error;
1048 }
1049 calc_contact_expires(chi, expires_hdr, sos);
1050 if (unregister_contact(chi, CONTACT_DELETED) != 0) {
1051 LM_ERR("Unable to remove contact <%.*s>\n", chi->uri.len, chi->uri.s);
1052
1053 }
1054 }
1055 }
1056 }
1057 /*now lets see if we still have any contacts left to decide on return value*/
1058 int num_valid_contacts = get_number_of_valid_contacts(tmp_impu_rec);
1059 if (num_valid_contacts)
1060 LM_DBG("contacts still available after implicit dereg for IMPU: <%.*s>\n", pi->public_identity.len, pi->public_identity.s);
1061 else {
1062 LM_DBG("no contacts left after implicit dereg for IMPU: <%.*s>\n", pi->public_identity.len, pi->public_identity.s);
1063 LM_DBG("Updating impu record to not send SAR on delete as this is explicit dereg");
1064 reg_state = IMS_USER_REGISTERED; //keep reg_state as it is
1065 if (ul.update_impurecord(_d, 0/*&pi->public_identity*/, tmp_impu_rec, reg_state, 0 /*do not send sar on delete */, -1 /*do not change barring*/, 0, 0, 0, 0, 0, 0, &tmp_impu_rec) != 0) {
1066 LM_ERR("Unable to update explicit impurecord for <%.*s>\n", pi->public_identity.len, pi->public_identity.s);
1067 }
1068 }
1069
1070 ul.unlock_udomain(_d, &pi->public_identity);
1071 }
1072 }
1073 ul.lock_subscription(subscription);
1074 subscription->ref_count--;
1075 ul.unlock_subscription(subscription);
1076 }
1077
1078 //TODO: clean here too - maybe do earlier with the lock on the domain already held...
1079 if (ret == 2) {
1080 LM_DBG("no contacts left after explicit dereg for IMPU: <%.*s>\n", public_identity->len, public_identity->s);
1081 LM_DBG("Updating impu record to not send SAR on delete as this is explicit dereg");
1082 reg_state = IMS_USER_REGISTERED; //keep reg_state as it is
1083 ul.lock_udomain(_d, public_identity);
1084 if (ul.update_impurecord(_d, public_identity, 0, reg_state, 0 /*do not send sar on delete */, -1 /*do not change barring*/, 0, 0, 0, 0, 0, 0, &tmp_impu_rec) != 0) {
1085 LM_ERR("Unable to update explicit impurecord for <%.*s>\n", public_identity->len, public_identity->s);
1086 }
1087 ul.unlock_udomain(_d, public_identity);
1088 }
1089 break;
1090
1091 case AVP_IMS_SAR_UNREGISTERED_USER:
1092 LM_DBG("updating contacts for UNREGISTERED_USER state\n");
1093 reg_state = IMS_USER_UNREGISTERED;
1094 for (i = 0; i < (*s)->service_profiles_cnt; i++)
1095 for (j = 0; j < (*s)->service_profiles[i].public_identities_cnt;
1096 j++) {
1097 pi = &((*s)->service_profiles[i].public_identities[j]);
1098 ul.lock_udomain(_d, &pi->public_identity);
1099 if (ul.update_impurecord(_d, &pi->public_identity, 0, reg_state, -1 /*do not change send sar on delete */,
1100 pi->barring, 0, s, ccf1, ccf2, ecf1, ecf2, &impu_rec)
1101 != 0) {
1102 LM_ERR("Unable to update impurecord for <%.*s>\n", pi->public_identity.len, pi->public_identity.s);
1103 ul.unlock_udomain(_d, &pi->public_identity);
1104 goto error;
1105 }
1106 ul.unlock_udomain(_d, &pi->public_identity);
1107 }
1108 //if we were successful up to this point, then we need to copy the contacts from main impu record (asserted IMPU) into the register response
1109 break;
1110 default:
1111 LM_ERR("unimplemented assignment_type when trying to update contacts\n");
1112 }
1113
1114 if (explicit_dereg_contact) {
1115 shm_free(explicit_dereg_contact);
1116 }
1117
1118
1119 return ret;
1120
1121 error:
1122 return -1;
1123
1124 }
1125
assign_server_unreg(struct sip_msg * _m,char * str1,str * direction,char * route)1126 int assign_server_unreg(struct sip_msg* _m, char* str1, str* direction, char* route) {
1127 str private_identity = {0, 0}, public_identity = {0, 0};
1128 int assignment_type = AVP_IMS_SAR_NO_ASSIGNMENT;
1129 int data_available = AVP_IMS_SAR_USER_DATA_NOT_AVAILABLE;
1130 int require_user_data = 1;
1131 rerrno = R_FINE;
1132 tm_cell_t *t = 0;
1133 str route_name;
1134
1135 saved_transaction_t* saved_t;
1136 cfg_action_t* cfg_action;
1137
1138 udomain_t* _d = (udomain_t*) str1;
1139
1140 if (fixup_get_svalue(_m, (gparam_t*) route, &route_name) != 0) {
1141 LM_ERR("no async route block for assign_server_unreg\n");
1142 return -1;
1143 }
1144
1145 LM_DBG("Looking for route block [%.*s]\n", route_name.len, route_name.s);
1146 int ri = route_get(&main_rt, route_name.s);
1147 if (ri < 0) {
1148 LM_ERR("unable to find route block [%.*s]\n", route_name.len, route_name.s);
1149 return -1;
1150 }
1151 cfg_action = main_rt.rlist[ri];
1152 if (cfg_action == NULL) {
1153 LM_ERR("empty action lists in route block [%.*s]\n", route_name.len, route_name.s);
1154 return -1;
1155 }
1156
1157 LM_DBG("Assigning unregistered user for direction [%.*s]\n", direction->len, direction->s);
1158
1159 enum cscf_dialog_direction dir = cscf_get_dialog_direction(direction->s);
1160 switch (dir) {
1161 case CSCF_MOBILE_ORIGINATING:
1162 public_identity = cscf_get_asserted_identity(_m, 0);
1163 break;
1164 case CSCF_MOBILE_TERMINATING:
1165 public_identity = cscf_get_public_identity_from_requri(_m);
1166 break;
1167 default:
1168 LM_ERR("Bad dialog direction [%.*s]\n", direction->len, direction->s);
1169 rerrno = R_SAR_FAILED;
1170 goto error;
1171 }
1172
1173 if (!public_identity.s || public_identity.len <= 0) {
1174 LM_ERR("No public identity\n");
1175 rerrno = R_SAR_FAILED;
1176 goto error;
1177 }
1178
1179 assignment_type = AVP_IMS_SAR_UNREGISTERED_USER;
1180 data_available = AVP_IMS_SAR_USER_DATA_NOT_AVAILABLE; //TODO: check this
1181
1182
1183 //before we send lets suspend the transaction
1184 t = tmb.t_gett();
1185 if (t == NULL || t == T_UNDEFINED) {
1186 if (tmb.t_newtran(_m) < 0) {
1187 LM_ERR("cannot create the transaction for SAR async\n");
1188 rerrno = R_SAR_FAILED;
1189 goto error;
1190 }
1191 t = tmb.t_gett();
1192 if (t == NULL || t == T_UNDEFINED) {
1193 LM_ERR("cannot lookup the transaction\n");
1194 rerrno = R_SAR_FAILED;
1195 goto error;
1196 }
1197 }
1198
1199 saved_t = shm_malloc(sizeof (saved_transaction_t));
1200 if (!saved_t) {
1201 LM_ERR("no more memory trying to save transaction state\n");
1202 rerrno = R_SAR_FAILED;
1203 goto error;
1204
1205 }
1206 memset(saved_t, 0, sizeof (saved_transaction_t));
1207 saved_t->act = cfg_action;
1208
1209 saved_t->expires = 1; //not a dereg as this is server_assign_unreg
1210 saved_t->require_user_data = require_user_data;
1211 saved_t->sar_assignment_type = assignment_type;
1212 saved_t->domain = (udomain_t*) _d;
1213
1214 saved_t->contact_header = 0;
1215
1216 LM_DBG("Setting default AVP return code used for async callbacks to default as ERROR \n");
1217 create_return_code(CSCF_RETURN_ERROR);
1218
1219 LM_DBG("Suspending SIP TM transaction\n");
1220 if (tmb.t_suspend(_m, &saved_t->tindex, &saved_t->tlabel) != 0) {
1221 LM_ERR("failed to suspend the TM processing\n");
1222 free_saved_transaction_data(saved_t);
1223 rerrno = R_SAR_FAILED;
1224 goto error;
1225 }
1226
1227 if (scscf_assign_server(_m, public_identity, private_identity, assignment_type, data_available, saved_t) != 0) {
1228 LM_ERR("ERR:I_MAR: Error sending SAR or SAR time-out\n");
1229 tmb.t_cancel_suspend(saved_t->tindex, saved_t->tlabel);
1230 free_saved_transaction_data(saved_t);
1231 rerrno = R_SAR_FAILED;
1232 goto error;
1233 }
1234
1235 if (public_identity.s && dir == CSCF_MOBILE_TERMINATING)
1236 shm_free(public_identity.s); // shm_malloc in cscf_get_public_identity_from_requri
1237
1238 return CSCF_RETURN_BREAK;
1239
1240
1241 error:
1242 update_stat(rejected_registrations, 1);
1243 if ((is_route_type(REQUEST_ROUTE)) && (reg_send_reply(_m, 0) < 0))
1244 return CSCF_RETURN_ERROR;
1245 return CSCF_RETURN_BREAK;
1246
1247
1248 }
1249
1250 /*!\brief
1251 * Process REGISTER request and save it's contacts
1252 * 1. ensure request
1253 * 2. get impu, impi,realm,expiry,etc
1254 * 3. check expiry
1255 * 4. do SAR (reg,re-reg,dereg and no contacts left)
1256 * 5. update usrloc based on SAR results
1257 */
1258 //int save(struct sip_msg* msg, udomain_t* _d) {
1259
save(struct sip_msg * msg,char * str1,char * route)1260 int save(struct sip_msg* msg, char* str1, char *route) {
1261 int expires;
1262 int require_user_data = 0;
1263 int data_available;
1264 contact_t* c;
1265 int st;
1266 str public_identity, private_identity, realm;
1267 int sar_assignment_type = AVP_IMS_SAR_NO_ASSIGNMENT;
1268 str route_name;
1269
1270 udomain_t* _d = (udomain_t*) str1;
1271
1272 rerrno = R_FINE;
1273 get_act_time();
1274
1275 tm_cell_t *t = 0;
1276
1277 saved_transaction_t* saved_t;
1278 cfg_action_t* cfg_action;
1279
1280 contact_for_header_t* contact_header = 0;
1281
1282 if (fixup_get_svalue(msg, (gparam_t*) route, &route_name) != 0) {
1283 LM_ERR("no async route block for assign_server_unreg\n");
1284 return -1;
1285 }
1286
1287 LM_DBG("Looking for route block [%.*s]\n", route_name.len, route_name.s);
1288 int ri = route_get(&main_rt, route_name.s);
1289 if (ri < 0) {
1290 LM_ERR("unable to find route block [%.*s]\n", route_name.len, route_name.s);
1291 return -1;
1292 }
1293 cfg_action = main_rt.rlist[ri];
1294 if (cfg_action == NULL) {
1295 LM_ERR("empty action lists in route block [%.*s]\n", route_name.len, route_name.s);
1296 return -1;
1297 }
1298
1299 //check which route block we are in - if not request then we fail out.
1300 if (!is_route_type(REQUEST_ROUTE)) {
1301 LM_ERR("Should only be called in REQUEST route\n");
1302 rerrno = R_SAR_FAILED;
1303 goto error;
1304 }
1305
1306 /* check and see that all the required headers are available and can be parsed */
1307 if (parse_message_for_register(msg) < 0) {
1308 LM_ERR("Unable to parse register message correctly\n");
1309 rerrno = R_SAR_FAILED;
1310 goto error;
1311 }
1312 /** check we have valid contacts according to IMS spec. */
1313 if (check_contacts(msg, &st) > 0) {
1314 LM_ERR("contacts not valid for REGISTER\n");
1315 rerrno = R_SAR_FAILED;
1316 goto error;
1317 }
1318
1319 /* get IMPU,IMPI,realm,expires */
1320 public_identity = cscf_get_public_identity(msg);
1321 if (public_identity.len <= 0 || !public_identity.s) {
1322 LM_ERR("failed to extract Address Of Record\n");
1323 rerrno = R_SAR_FAILED;
1324 goto error;
1325 }
1326 realm = cscf_get_realm_from_uri(public_identity);
1327 if (realm.len <= 0 || !realm.s) {
1328 LM_ERR("can't get realm\n");
1329 rerrno = R_SAR_FAILED;
1330 goto error;
1331 }
1332
1333 private_identity = cscf_get_private_identity(msg, realm);
1334 if (private_identity.len <= 0 || !private_identity.s) {
1335 LM_ERR("cant get private identity\n");
1336 }
1337
1338 expires = cscf_get_max_expires(msg, 0); //check all contacts for max expires
1339 if (expires != 0) { //if <0 then no expires was found in which case we treat as reg/re-reg with default expires.
1340 if (is_impu_registered(_d, &public_identity)) {
1341 LM_DBG("preparing for SAR assignment for RE-REGISTRATION <%.*s>\n", public_identity.len, public_identity.s);
1342 sar_assignment_type = AVP_IMS_SAR_RE_REGISTRATION;
1343 } else {
1344 LM_DBG("preparing for SAR assignment for new REGISTRATION <%.*s>\n", public_identity.len, public_identity.s);
1345 sar_assignment_type = AVP_IMS_SAR_REGISTRATION;
1346 require_user_data = 1;
1347 }
1348 } else {//de-reg
1349 if (store_data_on_dereg) {
1350 LM_DBG("preparing for SAR assignment for DE-REGISTRATION with storage <%.*s>\n", public_identity.len, public_identity.s);
1351 sar_assignment_type = AVP_IMS_SAR_USER_DEREGISTRATION_STORE_SERVER_NAME;
1352 } else {
1353 LM_DBG("preparing for SAR assignment for DE-REGISTRATION <%.*s>\n", public_identity.len, public_identity.s);
1354 sar_assignment_type = AVP_IMS_SAR_USER_DEREGISTRATION;
1355 }
1356
1357 c = get_first_contact(msg);
1358 if (!c && !st) { //no contacts found - no need to do anything
1359 LM_ERR("no contacts found for de-registration and no star\n");
1360 rerrno = R_SAR_FAILED;
1361 goto error;
1362 }
1363
1364 //if we get here there are contacts to deregister, BUT we only send a SAR if there are no contacts (valid) left.
1365 if (!st) { //if it is a star then we delete all contacts and send a SAR
1366 //unregister the requested contacts, if none left at the end then send a SAR, otherwise return successfully
1367 LM_DBG("need to unregister contacts\n");
1368 //lets update the contacts - we need to know if all were deleted or not for the public identity
1369 int res = update_contacts(msg, _d, &public_identity, sar_assignment_type, 0, 0, 0, 0, 0, &contact_header);
1370 if (res <= 0) {
1371 LM_DBG("Error processing REGISTER for de-registration\n");
1372 free_contact_buf(contact_header);
1373 rerrno = R_SAR_FAILED;
1374 goto error;
1375 } else if (res == 2) {
1376 //send sar
1377 LM_DBG("no contacts left after explicit de-registration, doing SAR\n");
1378 } else { //res=1
1379 //still contacts left so return success
1380 LM_DBG("contacts still available after deregister.... not doing SAR\n");
1381 //we must send the de reged contacts in this! so we only free the contact header after sending
1382 //free_contact_buf(contact_header);
1383 rerrno = R_FINE;
1384 goto no_sar;
1385 }
1386 }
1387 }
1388
1389 if (!user_data_always) {
1390 if (require_user_data)
1391 data_available = AVP_IMS_SAR_USER_DATA_NOT_AVAILABLE;
1392 else
1393 data_available = AVP_IMS_SAR_USER_DATA_ALREADY_AVAILABLE;
1394 } else {
1395 data_available = AVP_IMS_SAR_USER_DATA_NOT_AVAILABLE;
1396 }
1397
1398 //before we send lets suspend the transaction
1399 t = tmb.t_gett();
1400 if (t == NULL || t == T_UNDEFINED) {
1401 if (tmb.t_newtran(msg) < 0) {
1402 LM_ERR("cannot create the transaction for SAR async\n");
1403 rerrno = R_SAR_FAILED;
1404 goto error;
1405 }
1406 t = tmb.t_gett();
1407 if (t == NULL || t == T_UNDEFINED) {
1408 LM_ERR("cannot lookup the transaction\n");
1409 rerrno = R_SAR_FAILED;
1410 goto error;
1411 }
1412 }
1413
1414 saved_t = shm_malloc(sizeof (saved_transaction_t));
1415 if (!saved_t) {
1416 LM_ERR("no more memory trying to save transaction state\n");
1417 free_contact_buf(contact_header);
1418 rerrno = R_SAR_FAILED;
1419 goto error;
1420
1421 }
1422 memset(saved_t, 0, sizeof (saved_transaction_t));
1423 saved_t->act = cfg_action;
1424
1425 //this is not server assign unreg - this is a save
1426 saved_t->expires = expires;
1427 saved_t->require_user_data = require_user_data;
1428 saved_t->sar_assignment_type = sar_assignment_type;
1429
1430 saved_t->domain = _d;
1431
1432 saved_t->public_identity.s = (char*) shm_malloc(public_identity.len + 1);
1433 if (!saved_t->public_identity.s) {
1434 LM_ERR("no more memory trying to save transaction state : callid\n");
1435 shm_free(saved_t);
1436 free_contact_buf(contact_header);
1437 rerrno = R_SAR_FAILED;
1438 goto error;
1439 }
1440 memset(saved_t->public_identity.s, 0, public_identity.len + 1);
1441 memcpy(saved_t->public_identity.s, public_identity.s, public_identity.len);
1442 saved_t->public_identity.len = public_identity.len;
1443
1444 saved_t->contact_header = contact_header;
1445
1446 create_return_code(CSCF_RETURN_ERROR);
1447
1448 LM_DBG("Suspending SIP TM transaction with index [%d] and label [%d]\n", saved_t->tindex, saved_t->tlabel);
1449 if (tmb.t_suspend(msg, &saved_t->tindex, &saved_t->tlabel) != 0) {
1450 LM_ERR("failed to suspend the TM processing\n");
1451 free_saved_transaction_data(saved_t);
1452 rerrno = R_SAR_FAILED;
1453 goto error;
1454 }
1455
1456 if (scscf_assign_server(msg, public_identity, private_identity, sar_assignment_type, data_available, saved_t) != 0) {
1457 LM_ERR("ERR:I_MAR: Error sending SAR or SAR time-out\n");
1458 tmb.t_cancel_suspend(saved_t->tindex, saved_t->tlabel);
1459 free_saved_transaction_data(saved_t);
1460 rerrno = R_SAR_FAILED;
1461 goto error;
1462 }
1463
1464 return CSCF_RETURN_BREAK;
1465
1466 no_sar:
1467
1468 update_stat(accepted_registrations, 1);
1469
1470 //we must send the de reged contacts in this! so we only free the contact header after sending
1471 /* Only send reply upon request, not upon reply */
1472 if ((is_route_type(REQUEST_ROUTE)) && (reg_send_reply(msg, contact_header) < 0)) {
1473 free_contact_buf(contact_header);
1474 return CSCF_RETURN_ERROR;
1475 }
1476 free_contact_buf(contact_header);
1477 return CSCF_RETURN_BREAK;
1478
1479 error:
1480 update_stat(rejected_registrations, 1);
1481 if ((is_route_type(REQUEST_ROUTE)) && (reg_send_reply(msg, contact_header) < 0))
1482 return CSCF_RETURN_ERROR;
1483 return CSCF_RETURN_BREAK;
1484
1485 }
1486
unregister(struct sip_msg * _m,char * _d,char * _uri)1487 int unregister(struct sip_msg* _m, char* _d, char* _uri) {
1488 str aor = {0, 0};
1489 str uri = {0, 0};
1490
1491 if (fixup_get_svalue(_m, (gparam_p) _uri, &uri) != 0 || uri.len <= 0) {
1492 LM_ERR("invalid uri parameter\n");
1493 return -1;
1494 }
1495
1496 if (extract_aor(&uri, &aor) < 0) {
1497 LM_ERR("failed to extract Address Of Record\n");
1498 return -1;
1499 }
1500
1501 if (star((udomain_t*) _d, &aor) < 0) {
1502 LM_ERR("error unregistering user [%.*s]\n", aor.len, aor.s);
1503 return -1;
1504 }
1505 return 1;
1506 }
1507
1508