Merge "Fix misname 'res_external_mwi' to 'res_mwi_external' in comments."
[asterisk/asterisk.git] / res / res_pjsip_registrar.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * Joshua Colp <jcolp@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*** MODULEINFO
20         <depend>pjproject</depend>
21         <depend>res_pjproject</depend>
22         <depend>res_pjsip</depend>
23         <support_level>core</support_level>
24  ***/
25
26 #include "asterisk.h"
27
28 #include <signal.h>
29 #include <pjsip.h>
30 #include <pjsip_ua.h>
31
32 #include "asterisk/res_pjsip.h"
33 #include "asterisk/module.h"
34 #include "asterisk/paths.h"
35 #include "asterisk/test.h"
36 #include "asterisk/taskprocessor.h"
37 #include "asterisk/manager.h"
38 #include "asterisk/named_locks.h"
39 #include "asterisk/res_pjproject.h"
40 #include "res_pjsip/include/res_pjsip_private.h"
41
42 /*** DOCUMENTATION
43         <manager name="PJSIPShowRegistrationsInbound" language="en_US">
44                 <synopsis>
45                         Lists PJSIP inbound registrations.
46                 </synopsis>
47                 <syntax />
48                 <description>
49                         <para>
50                         In response, <literal>InboundRegistrationDetail</literal> events showing configuration
51                         and status information are raised for all contacts, static or dynamic.  Once all events
52                         are completed an <literal>InboundRegistrationDetailComplete</literal> is issued.
53                         </para>
54                         <warning><para>
55                                 This command just dumps all coonfigured AORs with contacts, even if the contact
56                                 is a permanent one.  To really get just inbound registrations, use
57                                 <literal>PJSIPShowRegistrationInboundContactStatuses</literal>.
58                         </para>
59                         </warning>
60                 </description>
61                 <see-also>
62                         <ref type="manager" module="res_pjsip_registrar">PJSIPShowRegistrationInboundContactStatuses</ref>
63                 </see-also>
64         </manager>
65         <manager name="PJSIPShowRegistrationInboundContactStatuses" language="en_US">
66                 <synopsis>
67                         Lists ContactStatuses for PJSIP inbound registrations.
68                 </synopsis>
69                 <syntax />
70                 <description>
71                         <para>
72                         In response, <literal>ContactStatusDetail</literal> events showing status information
73                         are raised for each inbound registration (dynamic contact) object.  Once all events
74                         are completed a <literal>ContactStatusDetailComplete</literal> event is issued.
75                         </para>
76                 </description>
77         </manager>
78  ***/
79
80 static int pj_max_hostname = PJ_MAX_HOSTNAME;
81 static int pjsip_max_url_size = PJSIP_MAX_URL_SIZE;
82
83 /*! \brief Internal function which returns the expiration time for a contact */
84 static int registrar_get_expiration(const struct ast_sip_aor *aor, const pjsip_contact_hdr *contact, const pjsip_rx_data *rdata)
85 {
86         pjsip_expires_hdr *expires;
87         int expiration = aor->default_expiration;
88
89         if (contact && contact->expires != -1) {
90                 /* Expiration was provided with the contact itself */
91                 expiration = contact->expires;
92         } else if ((expires = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL))) {
93                 /* Expiration was provided using the Expires header */
94                 expiration = expires->ivalue;
95         }
96
97         /* If the value has explicitly been set to 0, do not enforce */
98         if (!expiration) {
99                 return expiration;
100         }
101
102         /* Enforce the range that we will allow for expiration */
103         if (expiration < aor->minimum_expiration) {
104                 expiration = aor->minimum_expiration;
105         } else if (expiration > aor->maximum_expiration) {
106                 expiration = aor->maximum_expiration;
107         }
108
109         return expiration;
110 }
111
112 /*! \brief Structure used for finding contact */
113 struct registrar_contact_details {
114         /*! \brief Pool used for parsing URI */
115         pj_pool_t *pool;
116         /*! \brief URI being looked for */
117         pjsip_sip_uri *uri;
118 };
119
120 /*! \brief Callback function for finding a contact */
121 static int registrar_find_contact(void *obj, void *arg, int flags)
122 {
123         struct ast_sip_contact *contact = obj;
124         const struct registrar_contact_details *details = arg;
125         pjsip_uri *contact_uri;
126
127         if (ast_tvzero(contact->expiration_time)) {
128                 return 0;
129         }
130
131         contact_uri = pjsip_parse_uri(details->pool, (char*)contact->uri, strlen(contact->uri), 0);
132         if (!contact_uri) {
133                 ast_log(LOG_WARNING, "Unable to parse contact URI from '%s'.\n", contact->uri);
134                 return 0;
135         }
136
137         return (pjsip_uri_cmp(PJSIP_URI_IN_CONTACT_HDR, details->uri, contact_uri) == PJ_SUCCESS) ? CMP_MATCH : 0;
138 }
139
140 /*! \brief Internal function which validates provided Contact headers to confirm that they are acceptable, and returns number of contacts */
141 static int registrar_validate_contacts(const pjsip_rx_data *rdata, pj_pool_t *pool, struct ao2_container *contacts,
142         struct ast_sip_aor *aor, int permanent, int *added, int *updated, int *deleted)
143 {
144         pjsip_contact_hdr *previous = NULL;
145         pjsip_contact_hdr *contact = (pjsip_contact_hdr *)&rdata->msg_info.msg->hdr;
146         struct registrar_contact_details details = {
147                 .pool = pool,
148         };
149
150         for (; (contact = (pjsip_contact_hdr *) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, contact->next)); pj_pool_reset(pool)) {
151                 int expiration = registrar_get_expiration(aor, contact, rdata);
152                 struct ast_sip_contact *existing;
153                 char contact_uri[pjsip_max_url_size];
154
155                 if (contact->star) {
156                         /* The expiration MUST be 0 when a '*' contact is used and there must be no other contact */
157                         if (expiration != 0 || previous) {
158                                 return -1;
159                         }
160                         /* Count all contacts to delete */
161                         *deleted = ao2_container_count(contacts) - permanent;
162                         previous = contact;
163                         continue;
164                 } else if (previous && previous->star) {
165                         /* If there is a previous contact and it is a '*' this is a deal breaker */
166                         return -1;
167                 }
168                 previous = contact;
169
170                 if (!PJSIP_URI_SCHEME_IS_SIP(contact->uri) && !PJSIP_URI_SCHEME_IS_SIPS(contact->uri)) {
171                         continue;
172                 }
173
174                 details.uri = pjsip_uri_get_uri(contact->uri);
175
176                 /* pjsip_uri_print returns -1 if there's not enough room in the buffer */
177                 if (pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, details.uri, contact_uri, sizeof(contact_uri)) < 0) {
178                         /* If the total length of the uri is greater than pjproject can handle, go no further */
179                         return -1;
180                 }
181
182                 if (details.uri->host.slen >= pj_max_hostname) {
183                         /* If the length of the hostname is greater than pjproject can handle, go no further */
184                         return -1;
185                 }
186
187                 /* Determine if this is an add, update, or delete for policy enforcement purposes */
188                 existing = ao2_callback(contacts, 0, registrar_find_contact, &details);
189                 ao2_cleanup(existing);
190                 if (!existing) {
191                         if (expiration) {
192                                 ++*added;
193                         }
194                 } else if (expiration) {
195                         ++*updated;
196                 } else {
197                         ++*deleted;
198                 }
199         }
200
201         return 0;
202 }
203
204 enum contact_delete_type {
205         CONTACT_DELETE_ERROR,
206         CONTACT_DELETE_EXISTING,
207         CONTACT_DELETE_EXPIRE,
208         CONTACT_DELETE_REQUEST,
209         CONTACT_DELETE_SHUTDOWN,
210 };
211
212 static int registrar_contact_delete(enum contact_delete_type type, pjsip_transport *transport,
213         struct ast_sip_contact *contact, const char *aor_name);
214
215 /*! \brief Internal function used to delete a contact from an AOR */
216 static int registrar_delete_contact(void *obj, void *arg, int flags)
217 {
218         return registrar_contact_delete(
219                 CONTACT_DELETE_REQUEST, NULL, obj, arg) ? 0 : CMP_MATCH;
220 }
221
222 /*! \brief Internal function which adds a contact to a response */
223 static int registrar_add_contact(void *obj, void *arg, int flags)
224 {
225         struct ast_sip_contact *contact = obj;
226         pjsip_tx_data *tdata = arg;
227         pjsip_contact_hdr *hdr = pjsip_contact_hdr_create(tdata->pool);
228         pj_str_t uri;
229
230         pj_strdup2_with_null(tdata->pool, &uri, contact->uri);
231         hdr->uri = pjsip_parse_uri(tdata->pool, uri.ptr, uri.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
232         hdr->expires = ast_tvdiff_ms(contact->expiration_time, ast_tvnow()) / 1000;
233
234         pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hdr);
235
236         return 0;
237 }
238
239 /*! \brief Helper function which adds a Date header to a response */
240 static void registrar_add_date_header(pjsip_tx_data *tdata)
241 {
242         char date[256];
243         struct tm tm;
244         time_t t = time(NULL);
245
246         gmtime_r(&t, &tm);
247         strftime(date, sizeof(date), "%a, %d %b %Y %T GMT", &tm);
248
249         ast_sip_add_header(tdata, "Date", date);
250 }
251
252 static const pj_str_t path_hdr_name = { "Path", 4 };
253
254 static int build_path_data(pjsip_rx_data *rdata, struct ast_str **path_str)
255 {
256         pjsip_generic_string_hdr *path_hdr = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &path_hdr_name, NULL);
257
258         if (!path_hdr) {
259                 return 0;
260         }
261
262         *path_str = ast_str_create(64);
263         if (!*path_str) {
264                 return -1;
265         }
266
267         ast_str_set(path_str, 0, "%.*s", (int)path_hdr->hvalue.slen, path_hdr->hvalue.ptr);
268
269         while ((path_hdr = (pjsip_generic_string_hdr *) pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &path_hdr_name, path_hdr->next))) {
270                 ast_str_append(path_str, 0, ",%.*s", (int)path_hdr->hvalue.slen, path_hdr->hvalue.ptr);
271         }
272
273         return 0;
274 }
275
276 static int registrar_validate_path(pjsip_rx_data *rdata, struct ast_sip_aor *aor, struct ast_str **path_str)
277 {
278         const pj_str_t path_supported_name = { "path", 4 };
279         pjsip_supported_hdr *supported_hdr;
280         int i;
281
282         if (!aor->support_path) {
283                 return 0;
284         }
285
286         if (build_path_data(rdata, path_str)) {
287                 return -1;
288         }
289
290         if (!*path_str) {
291                 return 0;
292         }
293
294         supported_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_SUPPORTED, NULL);
295         if (!supported_hdr) {
296                 return -1;
297         }
298
299         /* Find advertised path support */
300         for (i = 0; i < supported_hdr->count; i++) {
301                 if (!pj_stricmp(&supported_hdr->values[i], &path_supported_name)) {
302                         return 0;
303                 }
304         }
305
306         /* Path header present, but support not advertised */
307         return -1;
308 }
309
310 /*! Transport monitor for incoming REGISTER contacts */
311 struct contact_transport_monitor {
312         /*!
313          * \brief Sorcery contact name to remove on transport shutdown
314          * \note Stored after aor_name in space reserved when struct allocated.
315          */
316         char *contact_name;
317         /*! Indicates that the monitor is in the process of removing a contact */
318         int removing;
319         /*! AOR name the contact is associated */
320         char aor_name[0];
321 };
322
323 static int contact_transport_monitor_matcher(void *a, void *b)
324 {
325         struct contact_transport_monitor *ma = a;
326         struct contact_transport_monitor *mb = b;
327
328         return strcmp(ma->aor_name, mb->aor_name) == 0
329                 && strcmp(ma->contact_name, mb->contact_name) == 0;
330 }
331
332 static int register_contact_transport_remove_cb(void *data)
333 {
334         struct contact_transport_monitor *monitor = data;
335         struct ast_sip_contact *contact;
336         struct ast_sip_aor *aor;
337
338         aor = ast_sip_location_retrieve_aor(monitor->aor_name);
339         if (!aor) {
340                 ao2_lock(monitor);
341                 monitor->removing = 0;
342                 ao2_unlock(monitor);
343                 ao2_ref(monitor, -1);
344                 return 0;
345         }
346
347         ao2_lock(aor);
348
349         contact = ast_sip_location_retrieve_contact(monitor->contact_name);
350         if (contact) {
351                 registrar_contact_delete(CONTACT_DELETE_SHUTDOWN, NULL, contact, monitor->aor_name);
352                 ao2_ref(contact, -1);
353         }
354         ao2_unlock(aor);
355         ao2_ref(aor, -1);
356
357         ao2_ref(monitor, -1);
358         return 0;
359 }
360
361 /*!
362  * \internal
363  * \brief The reliable transport we registered as a contact has shutdown.
364  *
365  * \param data What contact needs to be removed.
366  *
367  * \note Normally executed by the pjsip monitor thread.
368  *
369  * \return Nothing
370  */
371 static void register_contact_transport_shutdown_cb(void *data)
372 {
373         struct contact_transport_monitor *monitor = data;
374
375         /*
376          * It's possible for this shutdown handler to get called multiple times for the
377          * same monitor from different threads. Only one of the calls needs to do the
378          * actual removing of the contact, so if one is currently removing then any
379          * subsequent calls can skip.
380          */
381         ao2_lock(monitor);
382         if (monitor->removing) {
383                 ao2_unlock(monitor);
384                 return;
385         }
386
387         monitor->removing = 1;
388
389         /*
390          * Push off to a default serializer.  This is in case sorcery
391          * does database accesses for contacts.  Database accesses may
392          * not be on this machine.  We don't want to tie up the pjsip
393          * monitor thread with potentially long access times.
394          */
395         ao2_ref(monitor, +1);
396         if (ast_sip_push_task(NULL, register_contact_transport_remove_cb, monitor)) {
397                 monitor->removing = 0;
398                 ao2_ref(monitor, -1);
399         }
400
401         ao2_unlock(monitor);
402 }
403
404
405 static int registrar_contact_delete(enum contact_delete_type type, pjsip_transport *transport,
406         struct ast_sip_contact *contact, const char *aor_name)
407 {
408         int aor_size;
409
410         /* Permanent contacts can't be deleted */
411         if (ast_tvzero(contact->expiration_time)) {
412                 return -1;
413         }
414
415         aor_size = aor_name ? strlen(aor_name) : 0;
416         if (contact->prune_on_boot && type != CONTACT_DELETE_SHUTDOWN && aor_size) {
417                 const char *contact_name = ast_sorcery_object_get_id(contact);
418                 struct contact_transport_monitor *monitor = ast_alloca(
419                         sizeof(*monitor) + 2 + aor_size + strlen(contact_name));
420
421                 strcpy(monitor->aor_name, aor_name); /* Safe */
422                 monitor->contact_name = monitor->aor_name + aor_size + 1;
423                 strcpy(monitor->contact_name, contact_name); /* Safe */
424
425                 if (transport) {
426                         ast_sip_transport_monitor_unregister(transport,
427                                 register_contact_transport_shutdown_cb, monitor,
428                                 contact_transport_monitor_matcher);
429                 } else {
430                         /*
431                          * If a specific transport is not supplied then unregister the matching
432                          * monitor from all reliable transports.
433                          */
434                         ast_sip_transport_monitor_unregister_all(register_contact_transport_shutdown_cb,
435                                 monitor, contact_transport_monitor_matcher);
436                 }
437         }
438
439         ast_sip_location_delete_contact(contact);
440
441         if (aor_size) {
442                 if (VERBOSITY_ATLEAST(3)) {
443                         const char *reason = "none";
444
445                         switch (type) {
446                         case CONTACT_DELETE_ERROR:
447                                 reason = "registration failure";
448                                 break;
449                         case CONTACT_DELETE_EXISTING:
450                                 reason = "remove existing";
451                                 break;
452                         case CONTACT_DELETE_EXPIRE:
453                                 reason = "expiration";
454                                 break;
455                         case CONTACT_DELETE_REQUEST:
456                                 reason = "request";
457                                 break;
458                         case CONTACT_DELETE_SHUTDOWN:
459                                 reason = "shutdown";
460                                 break;
461                         }
462
463                         ast_verb(3, "Removed contact '%s' from AOR '%s' due to %s\n",
464                                          contact->uri, aor_name, reason);
465                 }
466
467                 ast_test_suite_event_notify("AOR_CONTACT_REMOVED",
468                                 "Contact: %s\r\n"
469                                 "AOR: %s\r\n"
470                                 "UserAgent: %s",
471                                 contact->uri,
472                                 aor_name,
473                                 contact->user_agent);
474         }
475
476         return 0;
477 }
478
479 AST_VECTOR(excess_contact_vector, struct ast_sip_contact *);
480
481 static int vec_contact_cmp(struct ast_sip_contact *left, struct ast_sip_contact *right)
482 {
483         struct ast_sip_contact *left_contact = left;
484         struct ast_sip_contact *right_contact = right;
485
486         /* Sort from soonest to expire to last to expire */
487         return ast_tvcmp(left_contact->expiration_time, right_contact->expiration_time);
488 }
489
490 static int vec_contact_add(void *obj, void *arg, int flags)
491 {
492         struct ast_sip_contact *contact = obj;
493         struct excess_contact_vector *contact_vec = arg;
494
495         /*
496          * Performance wise, an insertion sort is fine because we
497          * shouldn't need to remove more than a handful of contacts.
498          * I expect we'll typically be removing only one contact.
499          */
500         AST_VECTOR_ADD_SORTED(contact_vec, contact, vec_contact_cmp);
501         if (AST_VECTOR_SIZE(contact_vec) == AST_VECTOR_MAX_SIZE(contact_vec)) {
502                 /*
503                  * We added a contact over the number we need to remove.
504                  * Remove the longest to expire contact from the vector
505                  * which is the last element in the vector.  It may be
506                  * the one we just added or the one we just added pushed
507                  * out an earlier contact from removal consideration.
508                  */
509                 --AST_VECTOR_SIZE(contact_vec);
510         }
511         return 0;
512 }
513
514 /*!
515  * \internal
516  * \brief Remove excess existing contacts that expire the soonest.
517  * \since 13.18.0
518  *
519  * \param contacts Container of unmodified contacts that could remove.
520  * \param to_remove Maximum number of contacts to remove.
521  *
522  * \return Nothing
523  */
524 static void remove_excess_contacts(struct ao2_container *contacts, struct ao2_container *response_contacts,
525         unsigned int to_remove)
526 {
527         struct excess_contact_vector contact_vec;
528
529         /*
530          * Create a sorted vector to hold the to_remove soonest to
531          * expire contacts.  The vector has an extra space to
532          * temporarily hold the longest to expire contact that we
533          * won't remove.
534          */
535         if (AST_VECTOR_INIT(&contact_vec, to_remove + 1)) {
536                 return;
537         }
538         ao2_callback(contacts, OBJ_NODATA | OBJ_MULTIPLE, vec_contact_add, &contact_vec);
539
540         /*
541          * The vector should always be populated with the number
542          * of contacts we need to remove.  Just in case, we will
543          * remove all contacts in the vector even if the contacts
544          * container had fewer contacts than there should be.
545          */
546         ast_assert(AST_VECTOR_SIZE(&contact_vec) == to_remove);
547         to_remove = AST_VECTOR_SIZE(&contact_vec);
548
549         /* Remove the excess contacts that expire the soonest */
550         while (to_remove--) {
551                 struct ast_sip_contact *contact;
552
553                 contact = AST_VECTOR_GET(&contact_vec, to_remove);
554
555                 registrar_contact_delete(CONTACT_DELETE_EXISTING, NULL, contact, contact->aor);
556
557                 ao2_unlink(response_contacts, contact);
558         }
559
560         AST_VECTOR_FREE(&contact_vec);
561 }
562
563 /*! \brief Callback function which adds non-permanent contacts to a container */
564 static int registrar_add_non_permanent(void *obj, void *arg, int flags)
565 {
566         struct ast_sip_contact *contact = obj;
567         struct ao2_container *container = arg;
568
569         if (ast_tvzero(contact->expiration_time)) {
570                 return 0;
571         }
572
573         ao2_link(container, contact);
574
575         return 0;
576 }
577
578 struct aor_core_response {
579         /*! Tx data to use for statefull response.  NULL for stateless response. */
580         pjsip_tx_data *tdata;
581         /*! SIP response code to send in stateless response */
582         int code;
583 };
584
585 static void register_aor_core(pjsip_rx_data *rdata,
586         struct ast_sip_endpoint *endpoint,
587         struct ast_sip_aor *aor,
588         const char *aor_name,
589         struct ao2_container *contacts,
590         struct aor_core_response *response)
591 {
592         static const pj_str_t USER_AGENT = { "User-Agent", 10 };
593
594         int added = 0;
595         int updated = 0;
596         int deleted = 0;
597         int permanent = 0;
598         int contact_count;
599         struct ao2_container *existing_contacts = NULL;
600         pjsip_contact_hdr *contact_hdr = (pjsip_contact_hdr *)&rdata->msg_info.msg->hdr;
601         struct registrar_contact_details details = { 0, };
602         pjsip_tx_data *tdata;
603         RAII_VAR(struct ast_str *, path_str, NULL, ast_free);
604         struct ast_sip_contact *response_contact;
605         char *user_agent = NULL;
606         pjsip_user_agent_hdr *user_agent_hdr;
607         pjsip_expires_hdr *expires_hdr;
608         pjsip_via_hdr *via_hdr;
609         pjsip_via_hdr *via_hdr_last;
610         char *via_addr = NULL;
611         int via_port = 0;
612         pjsip_cid_hdr *call_id_hdr;
613         char *call_id = NULL;
614         size_t alloc_size;
615
616         /* We create a single pool and use it throughout this function where we need one */
617         details.pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(),
618                 "Contact Comparison", 1024, 256);
619         if (!details.pool) {
620                 response->code = 500;
621                 return;
622         }
623
624         /* If there are any permanent contacts configured on the AOR we need to take them
625          * into account when counting contacts.
626          */
627         if (aor->permanent_contacts) {
628                 permanent = ao2_container_count(aor->permanent_contacts);
629         }
630
631         if (registrar_validate_contacts(rdata, details.pool, contacts, aor, permanent, &added, &updated, &deleted)) {
632                 /* The provided Contact headers do not conform to the specification */
633                 ast_sip_report_failed_acl(endpoint, rdata, "registrar_invalid_contacts_provided");
634                 ast_log(LOG_WARNING, "Failed to validate contacts in REGISTER request from '%s'\n",
635                                 ast_sorcery_object_get_id(endpoint));
636                 response->code = 400;
637                 pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
638                 return;
639         }
640
641         if (registrar_validate_path(rdata, aor, &path_str)) {
642                 /* Ensure that intervening proxies did not make invalid modifications to the request */
643                 ast_log(LOG_WARNING, "Invalid modifications made to REGISTER request from '%s' by intervening proxy\n",
644                                 ast_sorcery_object_get_id(endpoint));
645                 response->code = 420;
646                 pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
647                 return;
648         }
649
650         if (aor->remove_existing) {
651                 /* Cumulative number of contacts affected by this registration */
652                 contact_count = MAX(updated + added - deleted,  0);
653
654                 /* We need to keep track of only existing contacts so we can later
655                  * remove them if need be.
656                  */
657                 existing_contacts = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0,
658                         NULL, ast_sorcery_object_id_compare);
659                 if (!existing_contacts) {
660                         response->code = 500;
661                         pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
662                         return;
663                 }
664
665                 ao2_callback(contacts, OBJ_NODATA, registrar_add_non_permanent, existing_contacts);
666         } else {
667                 /* Total contacts after this registration */
668                 contact_count = ao2_container_count(contacts) - permanent + added - deleted;
669         }
670         if (contact_count > aor->max_contacts) {
671                 /* Enforce the maximum number of contacts */
672                 ast_sip_report_failed_acl(endpoint, rdata, "registrar_attempt_exceeds_maximum_configured_contacts");
673                 ast_log(LOG_WARNING, "Registration attempt from endpoint '%s' to AOR '%s' will exceed max contacts of %u\n",
674                                 ast_sorcery_object_get_id(endpoint), aor_name, aor->max_contacts);
675                 response->code = 403;
676                 pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
677                 ao2_cleanup(existing_contacts);
678                 return;
679         }
680
681         user_agent_hdr = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &USER_AGENT, NULL);
682         if (user_agent_hdr) {
683                 alloc_size = pj_strlen(&user_agent_hdr->hvalue) + 1;
684                 user_agent = ast_alloca(alloc_size);
685                 ast_copy_pj_str(user_agent, &user_agent_hdr->hvalue, alloc_size);
686         }
687
688         /* Find the first Via header */
689         via_hdr = via_hdr_last = (pjsip_via_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_VIA, NULL);
690         if (via_hdr) {
691                 /* Find the last Via header */
692                 while ( (via_hdr = (pjsip_via_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg,
693                                 PJSIP_H_VIA, via_hdr->next)) != NULL) {
694                         via_hdr_last = via_hdr;
695                 }
696                 alloc_size = pj_strlen(&via_hdr_last->sent_by.host) + 1;
697                 via_addr = ast_alloca(alloc_size);
698                 ast_copy_pj_str(via_addr, &via_hdr_last->sent_by.host, alloc_size);
699                 via_port=via_hdr_last->sent_by.port;
700         }
701
702         call_id_hdr = (pjsip_cid_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CALL_ID, NULL);
703         if (call_id_hdr) {
704                 alloc_size = pj_strlen(&call_id_hdr->id) + 1;
705                 call_id = ast_alloca(alloc_size);
706                 ast_copy_pj_str(call_id, &call_id_hdr->id, alloc_size);
707         }
708
709         /* Iterate each provided Contact header and add, update, or delete */
710         for (; (contact_hdr = (pjsip_contact_hdr *) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, contact_hdr->next)); pj_pool_reset(details.pool)) {
711                 int expiration;
712                 char contact_uri[pjsip_max_url_size];
713                 RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup);
714
715                 if (contact_hdr->star) {
716                         /* A star means to unregister everything, so do so for the possible contacts */
717                         ao2_callback(contacts, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE,
718                                 registrar_delete_contact, (void *)aor_name);
719                         /* If we are keeping track of existing contacts for removal then, well, there is
720                          * absolutely nothing left so no need to try to remove any.
721                          */
722                         if (existing_contacts) {
723                                 ao2_ref(existing_contacts, -1);
724                                 existing_contacts = NULL;
725                         }
726                         break;
727                 }
728
729                 if (!PJSIP_URI_SCHEME_IS_SIP(contact_hdr->uri) && !PJSIP_URI_SCHEME_IS_SIPS(contact_hdr->uri)) {
730                         /* This registrar only currently supports sip: and sips: URI schemes */
731                         continue;
732                 }
733
734                 expiration = registrar_get_expiration(aor, contact_hdr, rdata);
735                 details.uri = pjsip_uri_get_uri(contact_hdr->uri);
736                 pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, details.uri, contact_uri, sizeof(contact_uri));
737
738                 contact = ao2_callback(contacts, OBJ_UNLINK, registrar_find_contact, &details);
739
740                 /* If a contact was returned and we need to keep track of existing contacts then it
741                  * should be removed.
742                  */
743                 if (contact && existing_contacts) {
744                         ao2_unlink(existing_contacts, contact);
745                 }
746
747                 if (!contact) {
748                         int prune_on_boot;
749
750                         /* If they are actually trying to delete a contact that does not exist... be forgiving */
751                         if (!expiration) {
752                                 ast_verb(3, "Attempted to remove non-existent contact '%s' from AOR '%s' by request\n",
753                                         contact_uri, aor_name);
754                                 continue;
755                         }
756
757                         prune_on_boot = !ast_sip_will_uri_survive_restart(details.uri, endpoint, rdata);
758
759                         contact = ast_sip_location_create_contact(aor, contact_uri,
760                                 ast_tvadd(ast_tvnow(), ast_samp2tv(expiration, 1)),
761                                 path_str ? ast_str_buffer(path_str) : NULL,
762                                 user_agent, via_addr, via_port, call_id, prune_on_boot, endpoint);
763                         if (!contact) {
764                                 ast_log(LOG_ERROR, "Unable to bind contact '%s' to AOR '%s'\n",
765                                         contact_uri, aor_name);
766                                 continue;
767                         }
768
769                         if (prune_on_boot) {
770                                 const char *contact_name;
771                                 struct contact_transport_monitor *monitor;
772
773                                 /*
774                                  * Monitor the transport in case it gets disconnected because
775                                  * the contact won't be valid anymore if that happens.
776                                  */
777                                 contact_name = ast_sorcery_object_get_id(contact);
778                                 monitor = ao2_alloc(sizeof(*monitor) + 2 + strlen(aor_name)
779                                         + strlen(contact_name), NULL);
780                                 if (monitor) {
781                                         strcpy(monitor->aor_name, aor_name);/* Safe */
782                                         monitor->contact_name = monitor->aor_name + strlen(aor_name) + 1;
783                                         strcpy(monitor->contact_name, contact_name);/* Safe */
784
785                                         ast_sip_transport_monitor_register_replace(rdata->tp_info.transport,
786                                                 register_contact_transport_shutdown_cb, monitor, contact_transport_monitor_matcher);
787                                         ao2_ref(monitor, -1);
788                                 }
789                         }
790
791                         ast_verb(3, "Added contact '%s' to AOR '%s' with expiration of %d seconds\n",
792                                 contact_uri, aor_name, expiration);
793                         ast_test_suite_event_notify("AOR_CONTACT_ADDED",
794                                         "Contact: %s\r\n"
795                                         "AOR: %s\r\n"
796                                         "Expiration: %d\r\n"
797                                         "UserAgent: %s",
798                                         contact_uri,
799                                         aor_name,
800                                         expiration,
801                                         user_agent);
802
803                         ao2_link(contacts, contact);
804                 } else if (expiration) {
805                         struct ast_sip_contact *contact_update;
806
807                         contact_update = ast_sorcery_copy(ast_sip_get_sorcery(), contact);
808                         if (!contact_update) {
809                                 ast_log(LOG_ERROR, "Failed to update contact '%s' expiration time to %d seconds.\n",
810                                         contact->uri, expiration);
811                                 continue;
812                         }
813
814                         contact_update->expiration_time = ast_tvadd(ast_tvnow(), ast_samp2tv(expiration, 1));
815                         contact_update->qualify_frequency = aor->qualify_frequency;
816                         contact_update->authenticate_qualify = aor->authenticate_qualify;
817                         if (path_str) {
818                                 ast_string_field_set(contact_update, path, ast_str_buffer(path_str));
819                         }
820                         if (user_agent) {
821                                 ast_string_field_set(contact_update, user_agent, user_agent);
822                         }
823                         if (!ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) {
824                                 ast_string_field_set(contact_update, reg_server, ast_config_AST_SYSTEM_NAME);
825                         }
826
827                         if (ast_sip_location_update_contact(contact_update)) {
828                                 ast_log(LOG_ERROR, "Failed to update contact '%s' expiration time to %d seconds.\n",
829                                         contact->uri, expiration);
830                                 registrar_contact_delete(CONTACT_DELETE_ERROR, rdata->tp_info.transport,
831                                         contact, aor_name);
832                                 continue;
833                         }
834                         ast_debug(3, "Refreshed contact '%s' on AOR '%s' with new expiration of %d seconds\n",
835                                 contact_uri, aor_name, expiration);
836                         ast_test_suite_event_notify("AOR_CONTACT_REFRESHED",
837                                         "Contact: %s\r\n"
838                                         "AOR: %s\r\n"
839                                         "Expiration: %d\r\n"
840                                         "UserAgent: %s",
841                                         contact_uri,
842                                         aor_name,
843                                         expiration,
844                                         contact_update->user_agent);
845                         ao2_link(contacts, contact_update);
846                         ao2_cleanup(contact_update);
847                 } else {
848                         registrar_contact_delete(CONTACT_DELETE_REQUEST, rdata->tp_info.transport,
849                                         contact, aor_name);
850                 }
851         }
852
853         pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
854
855         /*
856          * If the AOR is configured to remove any contacts over max_contacts
857          * that have not been updated/added/deleted as a result of this
858          * REGISTER do so.
859          *
860          * The existing contacts container holds all contacts that were not
861          * involved in this REGISTER.
862          * The contacts container holds the current contacts of the AOR.
863          */
864         if (aor->remove_existing && existing_contacts) {
865                 /* Total contacts after this registration */
866                 contact_count = ao2_container_count(existing_contacts) + updated + added;
867                 if (contact_count > aor->max_contacts) {
868                         /* Remove excess existing contacts that expire the soonest */
869                         remove_excess_contacts(existing_contacts, contacts, contact_count - aor->max_contacts);
870                 }
871                 ao2_ref(existing_contacts, -1);
872         }
873
874         response_contact = ao2_callback(contacts, 0, NULL, NULL);
875
876         /* Send a response containing all of the contacts (including static) that are present on this AOR */
877         if (ast_sip_create_response(rdata, 200, response_contact, &tdata) != PJ_SUCCESS) {
878                 ao2_cleanup(response_contact);
879                 ao2_cleanup(contacts);
880                 response->code = 500;
881                 return;
882         }
883         ao2_cleanup(response_contact);
884
885         /* Add the date header to the response, some UAs use this to set their date and time */
886         registrar_add_date_header(tdata);
887
888         ao2_callback(contacts, 0, registrar_add_contact, tdata);
889
890         if ((expires_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL))) {
891                 expires_hdr = pjsip_expires_hdr_create(tdata->pool, registrar_get_expiration(aor, NULL, rdata));
892                 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)expires_hdr);
893         }
894
895         response->tdata = tdata;
896 }
897
898 static int register_aor(pjsip_rx_data *rdata,
899         struct ast_sip_endpoint *endpoint,
900         struct ast_sip_aor *aor,
901         const char *aor_name)
902 {
903         struct aor_core_response response = {
904                 .code = 500,
905         };
906         struct ao2_container *contacts = NULL;
907
908         ao2_lock(aor);
909         contacts = ast_sip_location_retrieve_aor_contacts_nolock(aor);
910         if (!contacts) {
911                 ao2_unlock(aor);
912                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(),
913                         rdata, response.code, NULL, NULL, NULL);
914                 return PJ_TRUE;
915         }
916
917         register_aor_core(rdata, endpoint, aor, aor_name, contacts, &response);
918         ao2_cleanup(contacts);
919         ao2_unlock(aor);
920
921         /* Now send the REGISTER response to the peer */
922         if (response.tdata) {
923                 ast_sip_send_stateful_response(rdata, response.tdata, endpoint);
924         } else {
925                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(),
926                         rdata, response.code, NULL, NULL, NULL);
927         }
928         return PJ_TRUE;
929 }
930
931 static int match_aor(const char *aor_name, const char *id)
932 {
933         if (ast_strlen_zero(aor_name)) {
934                 return 0;
935         }
936
937         if (!strcmp(aor_name, id)) {
938                 ast_debug(3, "Matched id '%s' to aor '%s'\n", id, aor_name);
939                 return 1;
940         }
941
942         return 0;
943 }
944
945 static char *find_aor_name(const char *username, const char *domain, const char *aors)
946 {
947         char *configured_aors;
948         char *aors_buf;
949         char *aor_name;
950         char *id_domain;
951         struct ast_sip_domain_alias *alias;
952
953         id_domain = ast_alloca(strlen(username) + strlen(domain) + 2);
954         sprintf(id_domain, "%s@%s", username, domain);
955
956         aors_buf = ast_strdupa(aors);
957
958         /* Look for exact match on username@domain */
959         configured_aors = aors_buf;
960         while ((aor_name = ast_strip(strsep(&configured_aors, ",")))) {
961                 if (match_aor(aor_name, id_domain)) {
962                         return ast_strdup(aor_name);
963                 }
964         }
965
966         /* If there's a domain alias, look for exact match on username@domain_alias */
967         alias = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "domain_alias", domain);
968         if (alias) {
969                 char *id_domain_alias = ast_alloca(strlen(username) + strlen(alias->domain) + 2);
970
971                 sprintf(id_domain, "%s@%s", username, alias->domain);
972                 ao2_cleanup(alias);
973
974                 configured_aors = strcpy(aors_buf, aors);/* Safe */
975                 while ((aor_name = ast_strip(strsep(&configured_aors, ",")))) {
976                         if (match_aor(aor_name, id_domain_alias)) {
977                                 return ast_strdup(aor_name);
978                         }
979                 }
980         }
981
982         if (ast_strlen_zero(username)) {
983                 /* No username, no match */
984                 return NULL;
985         }
986
987         /* Look for exact match on username only */
988         configured_aors = strcpy(aors_buf, aors);/* Safe */
989         while ((aor_name = ast_strip(strsep(&configured_aors, ",")))) {
990                 if (match_aor(aor_name, username)) {
991                         return ast_strdup(aor_name);
992                 }
993         }
994
995         return NULL;
996 }
997
998 static struct ast_sip_aor *find_registrar_aor(struct pjsip_rx_data *rdata, struct ast_sip_endpoint *endpoint)
999 {
1000         struct ast_sip_aor *aor = NULL;
1001         char *aor_name = NULL;
1002         char *domain_name;
1003         char *username = NULL;
1004         int i;
1005
1006         for (i = 0; i < AST_VECTOR_SIZE(&endpoint->ident_method_order); ++i) {
1007                 pjsip_sip_uri *uri;
1008                 pjsip_authorization_hdr *header = NULL;
1009
1010                 switch (AST_VECTOR_GET(&endpoint->ident_method_order, i)) {
1011                 case AST_SIP_ENDPOINT_IDENTIFY_BY_USERNAME:
1012                         uri = pjsip_uri_get_uri(rdata->msg_info.to->uri);
1013
1014                         domain_name = ast_alloca(uri->host.slen + 1);
1015                         ast_copy_pj_str(domain_name, &uri->host, uri->host.slen + 1);
1016                         username = ast_alloca(uri->user.slen + 1);
1017                         ast_copy_pj_str(username, &uri->user, uri->user.slen + 1);
1018
1019                         /*
1020                          * We may want to match without any user options getting
1021                          * in the way.
1022                          */
1023                         AST_SIP_USER_OPTIONS_TRUNCATE_CHECK(username);
1024
1025                         aor_name = find_aor_name(username, domain_name, endpoint->aors);
1026                         if (aor_name) {
1027                                 ast_debug(3, "Matched aor '%s' by To username\n", aor_name);
1028                         }
1029                         break;
1030                 case AST_SIP_ENDPOINT_IDENTIFY_BY_AUTH_USERNAME:
1031                         while ((header = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_AUTHORIZATION,
1032                                 header ? header->next : NULL))) {
1033                                 if (header && !pj_stricmp2(&header->scheme, "digest")) {
1034                                         username = ast_alloca(header->credential.digest.username.slen + 1);
1035                                         ast_copy_pj_str(username, &header->credential.digest.username, header->credential.digest.username.slen + 1);
1036                                         domain_name = ast_alloca(header->credential.digest.realm.slen + 1);
1037                                         ast_copy_pj_str(domain_name, &header->credential.digest.realm, header->credential.digest.realm.slen + 1);
1038
1039                                         aor_name = find_aor_name(username, domain_name, endpoint->aors);
1040                                         if (aor_name) {
1041                                                 ast_debug(3, "Matched aor '%s' by Authentication username\n", aor_name);
1042                                                 break;
1043                                         }
1044                                 }
1045                         }
1046                         break;
1047                 default:
1048                         continue;
1049                 }
1050
1051                 if (aor_name) {
1052                         break;
1053                 }
1054         }
1055
1056         if (ast_strlen_zero(aor_name) || !(aor = ast_sip_location_retrieve_aor(aor_name))) {
1057                 /* The provided AOR name was not found (be it within the configuration or sorcery itself) */
1058                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 404, NULL, NULL, NULL);
1059                 ast_sip_report_req_no_support(endpoint, rdata, "registrar_requested_aor_not_found");
1060                 ast_log(LOG_WARNING, "AOR '%s' not found for endpoint '%s'\n",
1061                         username ?: "", ast_sorcery_object_get_id(endpoint));
1062         }
1063         ast_free(aor_name);
1064         return aor;
1065 }
1066
1067 static pj_bool_t registrar_on_rx_request(struct pjsip_rx_data *rdata)
1068 {
1069         RAII_VAR(struct ast_sip_endpoint *, endpoint,
1070                  ast_pjsip_rdata_get_endpoint(rdata), ao2_cleanup);
1071         struct ast_sip_aor *aor;
1072         const char *aor_name;
1073
1074         if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_register_method) || !endpoint) {
1075                 return PJ_FALSE;
1076         }
1077
1078         if (ast_strlen_zero(endpoint->aors)) {
1079                 /* Short circuit early if the endpoint has no AORs configured on it, which means no registration possible */
1080                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
1081                 ast_sip_report_failed_acl(endpoint, rdata, "registrar_attempt_without_configured_aors");
1082                 ast_log(LOG_WARNING, "Endpoint '%s' has no configured AORs\n", ast_sorcery_object_get_id(endpoint));
1083                 return PJ_TRUE;
1084         }
1085
1086         if (!PJSIP_URI_SCHEME_IS_SIP(rdata->msg_info.to->uri) && !PJSIP_URI_SCHEME_IS_SIPS(rdata->msg_info.to->uri)) {
1087                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 416, NULL, NULL, NULL);
1088                 ast_sip_report_failed_acl(endpoint, rdata, "registrar_invalid_uri_in_to_received");
1089                 ast_log(LOG_WARNING, "Endpoint '%s' attempted to register to an AOR with a non-SIP URI\n", ast_sorcery_object_get_id(endpoint));
1090                 return PJ_TRUE;
1091         }
1092
1093         aor = find_registrar_aor(rdata, endpoint);
1094         if (!aor) {
1095                 /* We've already responded about not finding an AOR. */
1096                 return PJ_TRUE;
1097         }
1098
1099         aor_name = ast_sorcery_object_get_id(aor);
1100
1101         if (!aor->max_contacts) {
1102                 /* Registration is not permitted for this AOR */
1103                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
1104                 ast_sip_report_req_no_support(endpoint, rdata, "registrar_attempt_without_registration_permitted");
1105                 ast_log(LOG_WARNING, "AOR '%s' has no configured max_contacts. Endpoint '%s' unable to register\n",
1106                         aor_name, ast_sorcery_object_get_id(endpoint));
1107         } else {
1108                 register_aor(rdata, endpoint, aor, aor_name);
1109         }
1110         ao2_ref(aor, -1);
1111         return PJ_TRUE;
1112 }
1113
1114 /* function pointer to callback needs to be within the module
1115    in order to avoid problems with an undefined symbol */
1116 static int sip_contact_to_str(void *acp, void *arg, int flags)
1117 {
1118         return ast_sip_contact_to_str(acp, arg, flags);
1119 }
1120
1121 static int ami_registrations_aor(void *obj, void *arg, int flags)
1122 {
1123         struct ast_sip_aor *aor = obj;
1124         struct ast_sip_ami *ami = arg;
1125         int *count = ami->arg;
1126         RAII_VAR(struct ast_str *, buf,
1127                  ast_sip_create_ami_event("InboundRegistrationDetail", ami), ast_free);
1128
1129         if (!buf) {
1130                 return -1;
1131         }
1132
1133         ast_sip_sorcery_object_to_ami(aor, &buf);
1134         ast_str_append(&buf, 0, "Contacts: ");
1135         ast_sip_for_each_contact(aor, sip_contact_to_str, &buf);
1136         ast_str_append(&buf, 0, "\r\n");
1137
1138         astman_append(ami->s, "%s\r\n", ast_str_buffer(buf));
1139         (*count)++;
1140         return 0;
1141 }
1142
1143 static int ami_registrations_endpoint(void *obj, void *arg, int flags)
1144 {
1145         struct ast_sip_endpoint *endpoint = obj;
1146         return ast_sip_for_each_aor(
1147                 endpoint->aors, ami_registrations_aor, arg);
1148 }
1149
1150 static int ami_registrations_endpoints(void *arg)
1151 {
1152         RAII_VAR(struct ao2_container *, endpoints,
1153                  ast_sip_get_endpoints(), ao2_cleanup);
1154
1155         if (!endpoints) {
1156                 return 0;
1157         }
1158
1159         ao2_callback(endpoints, OBJ_NODATA, ami_registrations_endpoint, arg);
1160         return 0;
1161 }
1162
1163 static int ami_show_registrations(struct mansession *s, const struct message *m)
1164 {
1165         int count = 0;
1166         struct ast_sip_ami ami = { .s = s, .m = m, .arg = &count, .action_id = astman_get_header(m, "ActionID"), };
1167
1168         astman_send_listack(s, m, "Following are Events for each Inbound registration",
1169                 "start");
1170
1171         ami_registrations_endpoints(&ami);
1172
1173         astman_send_list_complete_start(s, m, "InboundRegistrationDetailComplete", count);
1174         astman_send_list_complete_end(s);
1175         return 0;
1176 }
1177
1178 static int ami_show_registration_contact_statuses(struct mansession *s, const struct message *m)
1179 {
1180         int count = 0;
1181         struct ast_sip_ami ami = { .s = s, .m = m, .arg = NULL, .action_id = astman_get_header(m, "ActionID"), };
1182         struct ao2_container *contacts = ast_sorcery_retrieve_by_fields(
1183                 ast_sip_get_sorcery(), "contact", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
1184         struct ao2_iterator i;
1185         struct ast_sip_contact *contact;
1186
1187         astman_send_listack(s, m, "Following are ContactStatusEvents for each Inbound "
1188                             "registration", "start");
1189
1190         if (contacts) {
1191                 i = ao2_iterator_init(contacts, 0);
1192                 while ((contact = ao2_iterator_next(&i))) {
1193                         struct ast_sip_contact_wrapper wrapper;
1194
1195                         wrapper.aor_id = (char *)contact->aor;
1196                         wrapper.contact = contact;
1197                         wrapper.contact_id = (char *)ast_sorcery_object_get_id(contact);
1198
1199                         ast_sip_format_contact_ami(&wrapper, &ami, 0);
1200                         count++;
1201
1202                         ao2_ref(contact, -1);
1203                 }
1204                 ao2_iterator_destroy(&i);
1205                 ao2_ref(contacts, -1);
1206         }
1207
1208         astman_send_list_complete_start(s, m, "ContactStatusDetailComplete", count);
1209         astman_send_list_complete_end(s);
1210         return 0;
1211 }
1212
1213 #define AMI_SHOW_REGISTRATION_CONTACT_STATUSES "PJSIPShowRegistrationInboundContactStatuses"
1214 #define AMI_SHOW_REGISTRATIONS "PJSIPShowRegistrationsInbound"
1215
1216 static pjsip_module registrar_module = {
1217         .name = { "Registrar", 9 },
1218         .id = -1,
1219         .priority = PJSIP_MOD_PRIORITY_APPLICATION,
1220         .on_rx_request = registrar_on_rx_request,
1221 };
1222
1223 /*! \brief Thread keeping things alive */
1224 static pthread_t check_thread = AST_PTHREADT_NULL;
1225
1226 /*! \brief The global interval at which to check for contact expiration */
1227 static unsigned int check_interval;
1228
1229 /*! \brief Callback function which deletes a contact */
1230 static int expire_contact(void *obj, void *arg, int flags)
1231 {
1232         struct ast_sip_contact *contact = obj;
1233         struct ast_named_lock *lock;
1234
1235         lock = ast_named_lock_get(AST_NAMED_LOCK_TYPE_MUTEX, "aor", contact->aor);
1236         if (!lock) {
1237                 return 0;
1238         }
1239
1240         /*
1241          * We need to check the expiration again with the aor lock held
1242          * in case another thread is attempting to renew the contact.
1243          */
1244         ao2_lock(lock);
1245         if (ast_tvdiff_ms(ast_tvnow(), contact->expiration_time) > 0) {
1246                 registrar_contact_delete(CONTACT_DELETE_EXPIRE, NULL, contact, contact->aor);
1247         }
1248         ao2_unlock(lock);
1249         ast_named_lock_put(lock);
1250
1251         return 0;
1252 }
1253
1254 static void *check_expiration_thread(void *data)
1255 {
1256         struct ao2_container *contacts;
1257         struct ast_variable *var;
1258         char *time = alloca(64);
1259
1260         while (check_interval) {
1261                 sleep(check_interval);
1262
1263                 sprintf(time, "%ld", ast_tvnow().tv_sec);
1264                 var = ast_variable_new("expiration_time <=", time, "");
1265
1266                 ast_debug(4, "Woke up at %s  Interval: %d\n", time, check_interval);
1267
1268                 contacts = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "contact",
1269                         AST_RETRIEVE_FLAG_MULTIPLE, var);
1270
1271                 ast_variables_destroy(var);
1272                 if (contacts) {
1273                         ast_debug(3, "Expiring %d contacts\n", ao2_container_count(contacts));
1274                         ao2_callback(contacts, OBJ_NODATA, expire_contact, NULL);
1275                         ao2_ref(contacts, -1);
1276                 }
1277         }
1278
1279         return NULL;
1280 }
1281
1282 static void expiration_global_loaded(const char *object_type)
1283 {
1284         check_interval = ast_sip_get_contact_expiration_check_interval();
1285
1286         /* Observer calls are serialized so this is safe without it's own lock */
1287         if (check_interval) {
1288                 if (check_thread == AST_PTHREADT_NULL) {
1289                         if (ast_pthread_create_background(&check_thread, NULL, check_expiration_thread, NULL)) {
1290                                 ast_log(LOG_ERROR, "Could not create thread for checking contact expiration.\n");
1291                                 return;
1292                         }
1293                         ast_debug(3, "Interval = %d, starting thread\n", check_interval);
1294                 }
1295         } else {
1296                 if (check_thread != AST_PTHREADT_NULL) {
1297                         pthread_kill(check_thread, SIGURG);
1298                         pthread_join(check_thread, NULL);
1299                         check_thread = AST_PTHREADT_NULL;
1300                         ast_debug(3, "Interval = 0, shutting thread down\n");
1301                 }
1302         }
1303 }
1304
1305 /*! \brief Observer which is used to update our interval when the global setting changes */
1306 static struct ast_sorcery_observer expiration_global_observer = {
1307         .loaded = expiration_global_loaded,
1308 };
1309
1310 static int load_module(void)
1311 {
1312         const pj_str_t STR_REGISTER = { "REGISTER", 8 };
1313
1314         ast_pjproject_get_buildopt("PJ_MAX_HOSTNAME", "%d", &pj_max_hostname);
1315         /* As of pjproject 2.4.5, PJSIP_MAX_URL_SIZE isn't exposed yet but we try anyway. */
1316         ast_pjproject_get_buildopt("PJSIP_MAX_URL_SIZE", "%d", &pjsip_max_url_size);
1317
1318         if (ast_sip_register_service(&registrar_module)) {
1319                 return AST_MODULE_LOAD_DECLINE;
1320         }
1321
1322         if (pjsip_endpt_add_capability(ast_sip_get_pjsip_endpoint(), NULL, PJSIP_H_ALLOW, NULL, 1, &STR_REGISTER) != PJ_SUCCESS) {
1323                 ast_sip_unregister_service(&registrar_module);
1324                 return AST_MODULE_LOAD_DECLINE;
1325         }
1326
1327         ast_manager_register_xml(AMI_SHOW_REGISTRATIONS, EVENT_FLAG_SYSTEM,
1328                                  ami_show_registrations);
1329         ast_manager_register_xml(AMI_SHOW_REGISTRATION_CONTACT_STATUSES, EVENT_FLAG_SYSTEM,
1330                                  ami_show_registration_contact_statuses);
1331
1332         ast_sorcery_observer_add(ast_sip_get_sorcery(), "global", &expiration_global_observer);
1333         ast_sorcery_reload_object(ast_sip_get_sorcery(), "global");
1334
1335         return AST_MODULE_LOAD_SUCCESS;
1336 }
1337
1338 static int unload_module(void)
1339 {
1340         if (check_thread != AST_PTHREADT_NULL) {
1341                 check_interval = 0;
1342                 pthread_kill(check_thread, SIGURG);
1343                 pthread_join(check_thread, NULL);
1344
1345                 check_thread = AST_PTHREADT_NULL;
1346         }
1347
1348         ast_sorcery_observer_remove(ast_sip_get_sorcery(), "global", &expiration_global_observer);
1349
1350         ast_manager_unregister(AMI_SHOW_REGISTRATIONS);
1351         ast_manager_unregister(AMI_SHOW_REGISTRATION_CONTACT_STATUSES);
1352         ast_sip_unregister_service(&registrar_module);
1353         ast_sip_transport_monitor_unregister_all(register_contact_transport_shutdown_cb, NULL, NULL);
1354         return 0;
1355 }
1356
1357 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Registrar Support",
1358         .support_level = AST_MODULE_SUPPORT_CORE,
1359         .load = load_module,
1360         .unload = unload_module,
1361         .load_pri = AST_MODPRI_CHANNEL_DEPEND - 3,
1362         .requires = "res_pjproject,res_pjsip",
1363 );