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