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