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