f2439c4e807374ce2b2561fd9a2ab7eaa731eeb7
[asterisk/asterisk.git] / res / res_pjsip / pjsip_options.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2018, Digium, Inc.
5  *
6  * Joshua Colp <jcolp@digium.com>
7  * Richard Mudgett <rmudgett@digium.com>
8  *
9  * See http://www.asterisk.org for more information about
10  * the Asterisk project. Please do not directly contact
11  * any of the maintainers of this project for assistance;
12  * the project provides a web site, mailing lists and IRC
13  * channels for your use.
14  *
15  * This program is free software, distributed under the terms of
16  * the GNU General Public License Version 2. See the LICENSE file
17  * at the top of the source tree.
18  */
19
20 #include "asterisk.h"
21
22 #include <pjsip.h>
23 #include <pjsip_ua.h>
24 #include <pjlib.h>
25
26 #include "asterisk/res_pjsip.h"
27 #include "asterisk/channel.h"
28 #include "asterisk/pbx.h"
29 #include "asterisk/astobj2.h"
30 #include "asterisk/cli.h"
31 #include "asterisk/time.h"
32 #include "asterisk/test.h"
33 #include "asterisk/statsd.h"
34 #include "include/res_pjsip_private.h"
35 #include "asterisk/taskprocessor.h"
36 #include "asterisk/threadpool.h"
37
38 /*
39  * This implementation for OPTIONS support is based around the idea
40  * that realistically an AOR generally has very few contacts and is
41  * referenced by only a few endpoints. While it is perfectly fine for
42  * use in opposite scenarios it works best in the above case. It is
43  * also not shy to keeping state but it is reactive to outside changes
44  * so it can be updated.
45  *
46  * The lowest level object in here is a contact and its associated
47  * contact status. The result of an OPTIONS request to a contact is
48  * reflected in the contact status. The scheduling of these OPTIONS
49  * request is driven by the AOR. The AOR periodicially (according to
50  * configuration) sends OPTIONS requests out to any contacts
51  * associated with it. Contacts themselves are not individually
52  * scheduled. Contacts can be added or deleted as appropriate with no
53  * requirement to reschedule.
54  *
55  * The next level object up is the AOR itself. The result of a contact
56  * status change is fed into it and the result composited with all
57  * other contacts. This may result in the AOR itself changing state
58  * (it can be either AVAILABLE or UNAVAILABLE).
59  *
60  * The highest level object up is the endpoint state compositor (ESC).
61  * The result of AOR state changes is fed into it and the result
62  * composited with all other referenced AORs. This may result in the
63  * endpoint itself changing state (it can be either ONLINE or
64  * OFFLINE).  If this occurs the permanent endpoint is updated to
65  * reflect it.
66  *
67  * The threading model errs on the side of a world where things are
68  * not constantly changing. That is: A world where AORs and endpoints
69  * are not being constantly added/removed. This more closely mirrors
70  * the usage of the vast majority of people. This scenario can still
71  * be done but it may not be applied immediately.
72  *
73  * Manipulation of which AORs, endpoint state compositors, and
74  * contacts exist is done within a single serializer. This ensures
75  * that no matter the source threads order is preserved and you won't
76  * get into a weird situation where things are referencing other
77  * things that should have already been destroyed.
78  *
79  * Operations which impact the state of an AOR are done within a
80  * serializer that is specific to the AOR. This includes the result of
81  * a contact status change. This change is queued and executed on the
82  * AOR serializer afterwards.
83  *
84  * Operations which impact an endpoint state compositor are protected
85  * by a lock. This is done as the endpoint state compositor usage is
86  * minimal and the overhead of using a serializer and queueing things
87  * is not warranted.
88  *
89  * AORs which do not have a qualify frequency are also kept in here
90  * but do not require the same criteria as qualified AORs to be
91  * considered available. In their case as long as at least 1 contact
92  * is configured on the AOR (or added to it by registration) it is
93  * considered available.
94  */
95
96 #define DEFAULT_LANGUAGE "en"
97 #define DEFAULT_ENCODING "text/plain"
98
99 /*! \brief These are the number of buckets to store AORs in */
100 #ifdef LOW_MEMORY
101 #define AOR_BUCKETS 61
102 #else
103 #define AOR_BUCKETS 1567
104 #endif
105
106 /*! \brief These are the number of contact status buckets */
107 #ifdef LOW_MEMORY
108 #define CONTACT_STATUS_BUCKETS 61
109 #else
110 #define CONTACT_STATUS_BUCKETS 1567
111 #endif
112
113 /*! \brief These are the number of buckets (per AOR) to use to store contacts */
114 #define CONTACT_BUCKETS 13
115
116 /*! \brief These are the number of buckets to store endpoint state compositors */
117 #define ENDPOINT_STATE_COMPOSITOR_BUCKETS 13
118
119 /*! \brief The initial vector size for the endpoint state compositors on an AOR */
120 #define ENDPOINT_STATE_COMPOSITOR_INITIAL_SIZE 1
121
122 /*! \brief These are the number of buckets (per endpoint state compositor) to use to store AOR statuses */
123 #define AOR_STATUS_BUCKETS 3
124
125 /*! \brief Maximum wait time to join the below shutdown group */
126 #define MAX_UNLOAD_TIMEOUT_TIME         10      /* Seconds */
127
128 /*! \brief Shutdown group for options serializers */
129 static struct ast_serializer_shutdown_group *shutdown_group;
130
131 /*!
132  * \brief Structure which contains status information for an AOR feeding an endpoint state compositor
133  */
134 struct sip_options_endpoint_aor_status {
135         /*! \brief The last contributed available status of the named AOR (1 if available, 0 if not available) */
136         char available;
137         /*! \brief The name of the AOR */
138         char name[0];
139 };
140
141 /*!
142  * \brief Structure which contains composites information for endpoint state
143  */
144 struct sip_options_endpoint_state_compositor {
145         /*! \brief The last contributed available status of the AORs feeding this compositor */
146         struct ao2_container *aor_statuses;
147         /*!
148          * \brief Non-zero if the compositor is in normal operation. i.e. Not being setup/reconfigured.
149          *
150          * \details
151          * The aor layer can only update its aor_statuses record when not active.
152          * When active the aor layer can update its aor_statuses record, calculate the new
153          * number of available aors, determine if the endpoint compositor changed state,
154          * and report it.
155          */
156         char active;
157         /*! \brief The name of the endpoint */
158         char name[0];
159 };
160
161 /*!
162  * \brief Structure which contains an AOR and contacts for qualifying purposes
163  */
164 struct sip_options_aor {
165         /*! \brief The scheduler task for this AOR */
166         struct ast_sip_sched_task *sched_task;
167         /*! \brief The serializer for this AOR */
168         struct ast_taskprocessor *serializer;
169         /*! \brief All contacts associated with this AOR */
170         struct ao2_container *contacts;
171         /*!
172          * \brief Only dynamic contacts associated with this AOR
173          * \note Used to speed up applying AOR configuration by
174          * minimizing wild card sorcery access.
175          */
176         struct ao2_container *dynamic_contacts;
177         /*! \brief The endpoint state compositors we are feeding, a reference is held to each */
178         AST_VECTOR(, struct sip_options_endpoint_state_compositor *) compositors;
179         /*! \brief The number of available contacts on this AOR */
180         unsigned int available;
181         /*! \brief Frequency to send OPTIONS requests to AOR contacts. 0 is disabled. */
182         unsigned int qualify_frequency;
183         /*! If true authenticate the qualify challenge response if needed */
184         int authenticate_qualify;
185         /*! \brief Qualify timeout. 0 is diabled. */
186         double qualify_timeout;
187         /*! \brief The name of the AOR */
188         char name[0];
189 };
190
191 /*!
192  * \internal
193  * \brief Container of active SIP AORs for qualifying
194  */
195 static struct ao2_container *sip_options_aors;
196
197 /*!
198  * \internal
199  * \brief Container of contact statuses
200  */
201 static struct ao2_container *sip_options_contact_statuses;
202
203 /*!
204  * \internal
205  * \brief Container of endpoint state compositors
206  */
207 static struct ao2_container *sip_options_endpoint_state_compositors;
208
209 /*!
210  * \internal
211  * \brief Serializer for AOR, endpoint state compositor, and contact existence management
212  */
213 static struct ast_taskprocessor *management_serializer;
214
215 static pj_status_t send_options_response(pjsip_rx_data *rdata, int code)
216 {
217         pjsip_endpoint *endpt = ast_sip_get_pjsip_endpoint();
218         pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata);
219         pjsip_transaction *trans = pjsip_rdata_get_tsx(rdata);
220         pjsip_tx_data *tdata;
221         const pjsip_hdr *hdr;
222         pj_status_t status;
223
224         /* Make the response object */
225         status = ast_sip_create_response(rdata, code, NULL, &tdata);
226         if (status != PJ_SUCCESS) {
227                 ast_log(LOG_ERROR, "Unable to create response (%d)\n", status);
228                 return status;
229         }
230
231         /* Add appropriate headers */
232         if ((hdr = pjsip_endpt_get_capability(endpt, PJSIP_H_ACCEPT, NULL))) {
233                 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)pjsip_hdr_clone(tdata->pool, hdr));
234         }
235         if ((hdr = pjsip_endpt_get_capability(endpt, PJSIP_H_ALLOW, NULL))) {
236                 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)pjsip_hdr_clone(tdata->pool, hdr));
237         }
238         if ((hdr = pjsip_endpt_get_capability(endpt, PJSIP_H_SUPPORTED, NULL))) {
239                 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)pjsip_hdr_clone(tdata->pool, hdr));
240         }
241
242         /*
243          * XXX TODO: pjsip doesn't care a lot about either of these headers -
244          * while it provides specific methods to create them, they are defined
245          * to be the standard string header creation. We never did add them
246          * in chan_sip, although RFC 3261 says they SHOULD. Hard coded here.
247          */
248         ast_sip_add_header(tdata, "Accept-Encoding", DEFAULT_ENCODING);
249         ast_sip_add_header(tdata, "Accept-Language", DEFAULT_LANGUAGE);
250
251         if (dlg && trans) {
252                 status = pjsip_dlg_send_response(dlg, trans, tdata);
253         } else {
254                 struct ast_sip_endpoint *endpoint;
255
256                 endpoint = ast_pjsip_rdata_get_endpoint(rdata);
257                 status = ast_sip_send_stateful_response(rdata, tdata, endpoint);
258                 ao2_cleanup(endpoint);
259         }
260
261         if (status != PJ_SUCCESS) {
262                 ast_log(LOG_ERROR, "Unable to send response (%d)\n", status);
263         }
264
265         return status;
266 }
267
268 static pj_bool_t options_on_rx_request(pjsip_rx_data *rdata)
269 {
270         RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
271         pjsip_uri *ruri;
272         pjsip_sip_uri *sip_ruri;
273         char exten[AST_MAX_EXTENSION];
274
275         if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_options_method)) {
276                 return PJ_FALSE;
277         }
278
279         if (!(endpoint = ast_pjsip_rdata_get_endpoint(rdata))) {
280                 return PJ_FALSE;
281         }
282
283         ruri = rdata->msg_info.msg->line.req.uri;
284         if (!PJSIP_URI_SCHEME_IS_SIP(ruri) && !PJSIP_URI_SCHEME_IS_SIPS(ruri)) {
285                 send_options_response(rdata, 416);
286                 return PJ_TRUE;
287         }
288
289         sip_ruri = pjsip_uri_get_uri(ruri);
290         ast_copy_pj_str(exten, &sip_ruri->user, sizeof(exten));
291
292         /*
293          * We may want to match in the dialplan without any user
294          * options getting in the way.
295          */
296         AST_SIP_USER_OPTIONS_TRUNCATE_CHECK(exten);
297
298         if (ast_shutting_down()) {
299                 /*
300                  * Not taking any new calls at this time.
301                  * Likely a server availability OPTIONS poll.
302                  */
303                 send_options_response(rdata, 503);
304         } else if (!ast_strlen_zero(exten)
305                 && !ast_exists_extension(NULL, endpoint->context, exten, 1, NULL)) {
306                 send_options_response(rdata, 404);
307         } else {
308                 send_options_response(rdata, 200);
309         }
310         return PJ_TRUE;
311 }
312
313 static pjsip_module options_module = {
314         .name = {"Options Module", 14},
315         .id = -1,
316         .priority = PJSIP_MOD_PRIORITY_APPLICATION,
317         .on_rx_request = options_on_rx_request,
318 };
319
320 static const char *status_map[] = {
321         [UNAVAILABLE] = "Unreachable",
322         [AVAILABLE] = "Reachable",
323         [UNKNOWN] = "Unknown",
324         [CREATED] = "NonQualified",
325         [REMOVED] = "Removed",
326 };
327
328 static const char *short_status_map[] = {
329         [UNAVAILABLE] = "Unavail",
330         [AVAILABLE] = "Avail",
331         [UNKNOWN] = "Unknown",
332         [CREATED] = "NonQual",
333         [REMOVED] = "Removed",
334 };
335
336 const char *ast_sip_get_contact_status_label(const enum ast_sip_contact_status_type status)
337 {
338         ast_assert(0 <= status && status < ARRAY_LEN(status_map));
339         return status_map[status];
340 }
341
342 const char *ast_sip_get_contact_short_status_label(const enum ast_sip_contact_status_type status)
343 {
344         ast_assert(0 <= status && status < ARRAY_LEN(short_status_map));
345         return short_status_map[status];
346 }
347
348 /*! \brief Destructor for contact statuses */
349 static void sip_contact_status_dtor(void *obj)
350 {
351         struct ast_sip_contact_status *contact_status = obj;
352
353         ast_string_field_free_memory(contact_status);
354 }
355
356 static struct ast_sip_contact_status *sip_contact_status_alloc(const char *name)
357 {
358         struct ast_sip_contact_status *contact_status;
359         size_t size = sizeof(*contact_status) + strlen(name) + 1;
360
361         contact_status = ao2_alloc_options(size, sip_contact_status_dtor,
362                 AO2_ALLOC_OPT_LOCK_NOLOCK);
363         if (!contact_status) {
364                 return NULL;
365         }
366         if (ast_string_field_init(contact_status, 256)) {
367                 ao2_ref(contact_status, -1);
368                 return NULL;
369         }
370         strcpy(contact_status->name, name); /* SAFE */
371         return contact_status;
372 }
373
374 static struct ast_sip_contact_status *sip_contact_status_copy(const struct ast_sip_contact_status *src)
375 {
376         struct ast_sip_contact_status *dst;
377
378         dst = sip_contact_status_alloc(src->name);
379         if (!dst) {
380                 return NULL;
381         }
382
383         if (ast_string_fields_copy(dst, src)) {
384                 ao2_ref(dst, -1);
385                 return NULL;
386         }
387         dst->rtt = src->rtt;
388         dst->status = src->status;
389         dst->last_status = src->last_status;
390         return dst;
391 }
392
393 /*! \brief Hashing function for contact statuses */
394 AO2_STRING_FIELD_HASH_FN(ast_sip_contact_status, name);
395
396 /*! \brief Sort function for contact statuses */
397 AO2_STRING_FIELD_SORT_FN(ast_sip_contact_status, name);
398
399 /*! \brief Comparator function for contact statuses */
400 AO2_STRING_FIELD_CMP_FN(ast_sip_contact_status, name);
401
402 /*! \brief Helper function to allocate a contact statuses container */
403 static struct ao2_container *sip_options_contact_statuses_alloc(void)
404 {
405         /*
406          * Replace duplicate objects so we can update the immutable
407          * contact status objects by simply linking in a new object.
408          */
409         return ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_MUTEX,
410                 AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE, CONTACT_STATUS_BUCKETS,
411                 ast_sip_contact_status_hash_fn, ast_sip_contact_status_sort_fn,
412                 ast_sip_contact_status_cmp_fn);
413 }
414
415 /*! \brief Function which publishes a contact status update to all interested endpoints */
416 static void sip_options_publish_contact_state(const struct sip_options_aor *aor_options,
417         const struct ast_sip_contact_status *contact_status)
418 {
419         int i;
420
421         for (i = 0; i < AST_VECTOR_SIZE(&aor_options->compositors); ++i) {
422                 const struct sip_options_endpoint_state_compositor *endpoint_state_compositor;
423
424                 endpoint_state_compositor = AST_VECTOR_GET(&aor_options->compositors, i);
425                 ast_sip_persistent_endpoint_publish_contact_state(endpoint_state_compositor->name,
426                         contact_status);
427         }
428 }
429
430 /*!
431  * \brief Task to notify endpoints of a contact status change
432  * \note Run by management_serializer
433  */
434 static int contact_status_publish_update_task(void *obj)
435 {
436         struct ast_sip_contact_status *contact_status = obj;
437         struct sip_options_aor *aor_options;
438
439         aor_options = ao2_find(sip_options_aors, contact_status->aor, OBJ_SEARCH_KEY);
440         if (aor_options) {
441                 sip_options_publish_contact_state(aor_options, contact_status);
442                 ao2_ref(aor_options, -1);
443         }
444         ao2_ref(contact_status, -1);
445
446         return 0;
447 }
448
449 static void sip_options_contact_status_update(struct ast_sip_contact_status *contact_status)
450 {
451         struct ast_taskprocessor *mgmt_serializer = management_serializer;
452
453         if (mgmt_serializer) {
454                 ao2_ref(contact_status, +1);
455                 if (ast_sip_push_task(mgmt_serializer, contact_status_publish_update_task,
456                         contact_status)) {
457                         ao2_ref(contact_status, -1);
458                 }
459         }
460 }
461
462 struct ast_sip_contact_status *ast_res_pjsip_find_or_create_contact_status(const struct ast_sip_contact *contact)
463 {
464         struct ast_sip_contact_status *contact_status;
465         int res;
466
467         /*
468          * At startup a contact status can be retrieved when static contacts
469          * are themselves being setup.  This happens before we are fully setup.
470          * Since we don't actually trigger qualify or anything as a result it
471          * is safe to do so.  They'll just get back a contact status that will
472          * be updated later.  At this time they only care that the contact
473          * status gets created for the static contact anyway.
474          */
475         if (!sip_options_contact_statuses) {
476                 /*
477                  * We haven't been pre-initialized or we are shutting down.
478                  * Neither situation should happen.
479                  */
480                 ast_assert(0);
481                 return NULL;
482         }
483
484         ao2_lock(sip_options_contact_statuses);
485
486         /* If contact status for this contact already exists just return it */
487         contact_status = ao2_find(sip_options_contact_statuses,
488                 ast_sorcery_object_get_id(contact), OBJ_SEARCH_KEY | OBJ_NOLOCK);
489         if (contact_status) {
490                 ao2_unlock(sip_options_contact_statuses);
491                 return contact_status;
492         }
493
494         /* Otherwise we have to create and store a new contact status */
495         contact_status = sip_contact_status_alloc(ast_sorcery_object_get_id(contact));
496         if (!contact_status) {
497                 ao2_unlock(sip_options_contact_statuses);
498                 return NULL;
499         }
500
501         contact_status->rtt = 0;
502         contact_status->status = CREATED;
503         contact_status->last_status = CREATED;
504         res = ast_string_field_set(contact_status, uri, contact->uri);
505         res |= ast_string_field_set(contact_status, aor, contact->aor);
506         if (res) {
507                 ao2_unlock(sip_options_contact_statuses);
508                 ao2_ref(contact_status, -1);
509                 return NULL;
510         }
511
512         ao2_link_flags(sip_options_contact_statuses, contact_status, OBJ_NOLOCK);
513         ao2_unlock(sip_options_contact_statuses);
514
515         ast_statsd_log_string_va("PJSIP.contacts.states.%s", AST_STATSD_GAUGE,
516                 "+1", 1.0, ast_sip_get_contact_status_label(contact_status->status));
517
518         sip_options_contact_status_update(contact_status);
519
520         return contact_status;
521 }
522
523 struct ast_sip_contact_status *ast_sip_get_contact_status(const struct ast_sip_contact *contact)
524 {
525         return ao2_find(sip_options_contact_statuses, ast_sorcery_object_get_id(contact),
526                 OBJ_SEARCH_KEY);
527 }
528
529 /*! \brief Hashing function for OPTIONS AORs */
530 AO2_STRING_FIELD_HASH_FN(sip_options_aor, name);
531
532 /*! \brief Comparator function for SIP OPTIONS AORs */
533 AO2_STRING_FIELD_CMP_FN(sip_options_aor, name);
534
535 /*! \brief Hashing function for endpoint state compositors */
536 AO2_STRING_FIELD_HASH_FN(sip_options_endpoint_state_compositor, name);
537
538 /*! \brief Comparator function for endpoint state compositors */
539 AO2_STRING_FIELD_CMP_FN(sip_options_endpoint_state_compositor, name);
540
541 /*! \brief Structure used to contain information for an OPTIONS callback */
542 struct sip_options_contact_callback_data {
543         /*! \brief The contact we qualified */
544         struct ast_sip_contact *contact;
545         /*! \brief The AOR options */
546         struct sip_options_aor *aor_options;
547         /*! \brief The time at which this OPTIONS attempt was started */
548         struct timeval rtt_start;
549         /*! \brief The new status of the contact */
550         enum ast_sip_contact_status_type status;
551 };
552
553 /*!
554  * \brief Return the current state of an endpoint state compositor
555  * \pre The endpoint_state_compositor lock must be held.
556  */
557 static enum ast_endpoint_state sip_options_get_endpoint_state_compositor_state(
558         const struct sip_options_endpoint_state_compositor *endpoint_state_compositor)
559 {
560         struct ao2_iterator it_aor_statuses;
561         struct sip_options_endpoint_aor_status *aor_status;
562         enum ast_endpoint_state state = AST_ENDPOINT_OFFLINE;
563
564         it_aor_statuses = ao2_iterator_init(endpoint_state_compositor->aor_statuses, 0);
565         for (; (aor_status = ao2_iterator_next(&it_aor_statuses)); ao2_ref(aor_status, -1)) {
566                 if (aor_status->available) {
567                         state = AST_ENDPOINT_ONLINE;
568                         ao2_ref(aor_status, -1);
569                         break;
570                 }
571         }
572         ao2_iterator_destroy(&it_aor_statuses);
573
574         return state;
575 }
576
577 /*!
578  * \brief Update the AOR status on an endpoint state compositor
579  * \pre The endpoint_state_compositor lock must be held.
580  */
581 static void sip_options_update_endpoint_state_compositor_aor(struct sip_options_endpoint_state_compositor *endpoint_state_compositor,
582         const char *name, enum ast_sip_contact_status_type status)
583 {
584         struct sip_options_endpoint_aor_status *aor_status;
585         enum ast_endpoint_state endpoint_state;
586
587         aor_status = ao2_find(endpoint_state_compositor->aor_statuses, name,
588                 OBJ_SEARCH_KEY | OBJ_NOLOCK);
589         if (!aor_status) {
590                 /* The AOR status doesn't exist already so we don't need to go any further */
591                 if (status == REMOVED) {
592                         return;
593                 }
594
595                 aor_status = ao2_alloc_options(sizeof(*aor_status) + strlen(name) + 1, NULL,
596                         AO2_ALLOC_OPT_LOCK_NOLOCK);
597                 if (!aor_status) {
598                         return;
599                 }
600
601                 strcpy(aor_status->name, name); /* SAFE */
602                 ao2_link(endpoint_state_compositor->aor_statuses, aor_status);
603         }
604
605         if (status == REMOVED) {
606                 /*
607                  * If the AOR is being removed then remove its AOR status
608                  * from the endpoint compositor.
609                  */
610                 ao2_unlink(endpoint_state_compositor->aor_statuses, aor_status);
611         } else {
612                 aor_status->available = (status == AVAILABLE ? 1 : 0);
613         }
614         ao2_ref(aor_status, -1);
615
616         if (!endpoint_state_compositor->active) {
617                 return;
618         }
619
620         /* If this AOR is available then the endpoint itself has to be online */
621         if (status == AVAILABLE) {
622                 ast_debug(3, "Endpoint state compositor '%s' is online as AOR '%s' is available\n",
623                         endpoint_state_compositor->name, name);
624                 endpoint_state = AST_ENDPOINT_ONLINE;
625         } else {
626                 endpoint_state =
627                         sip_options_get_endpoint_state_compositor_state(endpoint_state_compositor);
628         }
629
630         ast_sip_persistent_endpoint_update_state(endpoint_state_compositor->name,
631                 endpoint_state);
632 }
633
634 /*! \brief Function which notifies endpoint state compositors of a state change of an AOR */
635 static void sip_options_notify_endpoint_state_compositors(struct sip_options_aor *aor_options,
636         enum ast_sip_contact_status_type status)
637 {
638         int i;
639
640         /* Iterate through the associated endpoint state compositors updating them */
641         for (i = 0; i < AST_VECTOR_SIZE(&aor_options->compositors); ++i) {
642                 struct sip_options_endpoint_state_compositor *endpoint_state_compositor;
643
644                 endpoint_state_compositor = AST_VECTOR_GET(&aor_options->compositors, i);
645
646                 ao2_lock(endpoint_state_compositor);
647                 sip_options_update_endpoint_state_compositor_aor(endpoint_state_compositor,
648                         aor_options->name, status);
649                 ao2_unlock(endpoint_state_compositor);
650         }
651
652         if (status == REMOVED) {
653                 AST_VECTOR_RESET(&aor_options->compositors, ao2_cleanup);
654         }
655 }
656
657 /*!
658  * \brief Task to notify an AOR of a contact status change
659  * \note Run by aor_options->serializer
660  */
661 static int sip_options_contact_status_notify_task(void *obj)
662 {
663         struct sip_options_contact_callback_data *contact_callback_data = obj;
664         struct ast_sip_contact *contact;
665         struct ast_sip_contact_status *cs_old;
666         struct ast_sip_contact_status *cs_new;
667
668         /*
669          * Determine if this is a late arriving notification, as it is
670          * possible that we get a callback from PJSIP giving us contact
671          * status but in the mean time said contact has been removed
672          * from the controlling AOR.
673          */
674
675         if (!contact_callback_data->aor_options->qualify_frequency) {
676                 /* Contact qualify response is late */
677                 ao2_ref(contact_callback_data, -1);
678                 return 0;
679         }
680
681         contact = ao2_find(contact_callback_data->aor_options->contacts,
682                 contact_callback_data->contact, OBJ_SEARCH_OBJECT);
683         if (!contact) {
684                 /* Contact qualify response is late */
685                 ao2_ref(contact_callback_data, -1);
686                 return 0;
687         }
688         ao2_ref(contact, -1);
689
690         cs_old = ao2_find(sip_options_contact_statuses,
691                 ast_sorcery_object_get_id(contact_callback_data->contact), OBJ_SEARCH_KEY);
692         if (!cs_old) {
693                 /* Contact qualify response is late */
694                 ao2_ref(contact_callback_data, -1);
695                 return 0;
696         }
697
698         /* Update the contact specific status information */
699         cs_new = sip_contact_status_copy(cs_old);
700         ao2_ref(cs_old, -1);
701         if (!cs_new) {
702                 ao2_ref(contact_callback_data, -1);
703                 return 0;
704         }
705         cs_new->last_status = cs_new->status;
706         cs_new->status = contact_callback_data->status;
707         cs_new->rtt =
708                 cs_new->status == AVAILABLE
709                         ? ast_tvdiff_us(ast_tvnow(), contact_callback_data->rtt_start)
710                         : 0;
711         ao2_link(sip_options_contact_statuses, cs_new);
712
713         /*
714          * If the status has changed then notify the endpoint state compositors
715          * and publish our events.
716          */
717         if (cs_new->last_status != cs_new->status) {
718                 if (cs_new->status == AVAILABLE) {
719                         /* If this is the first available contact then the AOR has become available */
720                         ++contact_callback_data->aor_options->available;
721                         if (contact_callback_data->aor_options->available == 1) {
722                                 sip_options_notify_endpoint_state_compositors(
723                                         contact_callback_data->aor_options, AVAILABLE);
724                         }
725                 } else if (cs_new->last_status == AVAILABLE) {
726                         ast_assert(cs_new->status == UNAVAILABLE);
727
728                         /* If there are no more available contacts then this AOR is unavailable */
729                         --contact_callback_data->aor_options->available;
730                         if (!contact_callback_data->aor_options->available) {
731                                 sip_options_notify_endpoint_state_compositors(
732                                         contact_callback_data->aor_options, UNAVAILABLE);
733                         }
734                 }
735
736                 ast_verb(3, "Contact %s/%s is now %s.  RTT: %.3f msec\n",
737                         cs_new->aor,
738                         cs_new->uri,
739                         ast_sip_get_contact_status_label(cs_new->status),
740                         cs_new->rtt / 1000.0);
741
742                 ast_statsd_log_string_va("PJSIP.contacts.states.%s", AST_STATSD_GAUGE,
743                         "-1", 1.0, ast_sip_get_contact_status_label(cs_new->last_status));
744                 ast_statsd_log_string_va("PJSIP.contacts.states.%s", AST_STATSD_GAUGE,
745                         "+1", 1.0, ast_sip_get_contact_status_label(cs_new->status));
746
747                 sip_options_contact_status_update(cs_new);
748
749                 ast_test_suite_event_notify("AOR_CONTACT_UPDATE",
750                         "Contact: %s\r\n"
751                         "Status: %s",
752                         cs_new->name,
753                         ast_sip_get_contact_status_label(cs_new->status));
754         } else {
755                 ast_debug(3, "Contact %s/%s status didn't change: %s, RTT: %.3f msec\n",
756                         cs_new->aor,
757                         cs_new->uri,
758                         ast_sip_get_contact_status_label(cs_new->status),
759                         cs_new->rtt / 1000.0);
760         }
761
762         ast_statsd_log_full_va("PJSIP.contacts.%s.rtt", AST_STATSD_TIMER,
763                 cs_new->status != AVAILABLE ? -1 : cs_new->rtt / 1000,
764                 1.0,
765                 cs_new->name);
766
767         ast_test_suite_event_notify("AOR_CONTACT_QUALIFY_RESULT",
768                 "Contact: %s\r\n"
769                 "Status: %s\r\n"
770                 "RTT: %" PRId64,
771                 cs_new->name,
772                 ast_sip_get_contact_status_label(cs_new->status),
773                 cs_new->rtt);
774
775         ast_debug(3, "AOR '%s' now has %d available contacts\n",
776                 contact_callback_data->aor_options->name,
777                 contact_callback_data->aor_options->available);
778
779         ao2_ref(cs_new, -1);
780         ao2_ref(contact_callback_data, -1);
781
782         return 0;
783 }
784
785 /*! \brief Callback for when we get a result from a SIP OPTIONS request (a response or a timeout) */
786 static void qualify_contact_cb(void *token, pjsip_event *e)
787 {
788         struct sip_options_contact_callback_data *contact_callback_data = token;
789         enum ast_sip_contact_status_type status;
790
791         switch(e->body.tsx_state.type) {
792         default:
793                 ast_log(LOG_ERROR, "Unexpected PJSIP event %u\n", e->body.tsx_state.type);
794                 /* Fall through */
795         case PJSIP_EVENT_TRANSPORT_ERROR:
796         case PJSIP_EVENT_TIMER:
797                 status = UNAVAILABLE;
798                 break;
799         case PJSIP_EVENT_RX_MSG:
800                 status = AVAILABLE;
801                 break;
802         }
803
804         /* Update the callback data with the new status, this will get handled in the AOR serializer */
805         contact_callback_data->status = status;
806
807         if (ast_sip_push_task(contact_callback_data->aor_options->serializer,
808                 sip_options_contact_status_notify_task, contact_callback_data)) {
809                 ast_log(LOG_NOTICE, "Unable to queue contact status update for '%s' on AOR '%s', state will be incorrect\n",
810                         ast_sorcery_object_get_id(contact_callback_data->contact),
811                         contact_callback_data->aor_options->name);
812                 ao2_ref(contact_callback_data, -1);
813         }
814
815         /* The task inherited our reference so we don't unreference here */
816 }
817
818 /*! \brief Destructor for contact callback data */
819 static void sip_options_contact_callback_data_dtor(void *obj)
820 {
821         struct sip_options_contact_callback_data *contact_callback_data = obj;
822
823         ao2_cleanup(contact_callback_data->contact);
824         ao2_cleanup(contact_callback_data->aor_options);
825 }
826
827 /*! \brief Contact callback data allocator */
828 static struct sip_options_contact_callback_data *sip_options_contact_callback_data_alloc(
829         struct ast_sip_contact *contact, struct sip_options_aor *aor_options)
830 {
831         struct sip_options_contact_callback_data *contact_callback_data;
832
833         contact_callback_data = ao2_alloc_options(sizeof(*contact_callback_data),
834                 sip_options_contact_callback_data_dtor, AO2_ALLOC_OPT_LOCK_NOLOCK);
835         if (!contact_callback_data) {
836                 return NULL;
837         }
838
839         contact_callback_data->contact = ao2_bump(contact);
840         contact_callback_data->aor_options = ao2_bump(aor_options);
841         contact_callback_data->rtt_start = ast_tvnow();
842
843         return contact_callback_data;
844 }
845
846 /*! \brief Send a SIP OPTIONS request for a contact */
847 static int sip_options_qualify_contact(void *obj, void *arg, int flags)
848 {
849         struct ast_sip_contact *contact = obj;
850         struct sip_options_aor *aor_options = arg;
851         RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
852         pjsip_tx_data *tdata;
853         struct ast_sip_contact_status *contact_status;
854         struct sip_options_contact_callback_data *contact_callback_data;
855
856         ast_debug(3, "Qualifying contact '%s' on AOR '%s'\n",
857                 ast_sorcery_object_get_id(contact), aor_options->name);
858
859         if (!ast_strlen_zero(contact->endpoint_name)) {
860                 endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint",
861                         contact->endpoint_name);
862         }
863         if (!endpoint && AST_VECTOR_SIZE(&aor_options->compositors)) {
864                 struct sip_options_endpoint_state_compositor *endpoint_state_compositor;
865
866                 endpoint_state_compositor = AST_VECTOR_GET(&aor_options->compositors, 0);
867                 endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint",
868                         endpoint_state_compositor->name);
869         }
870         if (!endpoint) {
871                 ast_debug(3, "Could not find an endpoint to qualify contact '%s' on AOR '%s'\n",
872                         ast_sorcery_object_get_id(contact), aor_options->name);
873                 return 0;
874         }
875
876         if (ast_sip_create_request("OPTIONS", NULL, endpoint, NULL, contact, &tdata)) {
877                 ast_log(LOG_ERROR, "Unable to create request to qualify contact %s on AOR %s\n",
878                         contact->uri, aor_options->name);
879                 return 0;
880         }
881
882         /* If an outbound proxy is specified set it on this request */
883         if (!ast_strlen_zero(contact->outbound_proxy) &&
884                 ast_sip_set_outbound_proxy(tdata, contact->outbound_proxy)) {
885                 ast_log(LOG_ERROR, "Unable to apply outbound proxy on request to qualify contact %s\n",
886                         contact->uri);
887                 pjsip_tx_data_dec_ref(tdata);
888                 return 0;
889         }
890
891         contact_status = ast_res_pjsip_find_or_create_contact_status(contact);
892         if (!contact_status) {
893                 ast_log(LOG_ERROR, "Unable to retrieve contact status information for contact %s on AOR %s\n",
894                         contact->uri, aor_options->name);
895                 pjsip_tx_data_dec_ref(tdata);
896                 return 0;
897         }
898         ao2_ref(contact_status, -1);
899
900         contact_callback_data = sip_options_contact_callback_data_alloc(contact, aor_options);
901         if (!contact_callback_data) {
902                 ast_log(LOG_ERROR, "Unable to create object to contain callback data for contact %s on AOR %s\n",
903                         contact->uri, aor_options->name);
904                 pjsip_tx_data_dec_ref(tdata);
905                 return 0;
906         }
907
908         if (ast_sip_send_out_of_dialog_request(tdata, endpoint,
909                 (int)(aor_options->qualify_timeout * 1000), contact_callback_data,
910                 qualify_contact_cb)) {
911                 ast_log(LOG_ERROR, "Unable to send request to qualify contact %s on AOR %s\n",
912                         contact->uri, aor_options->name);
913                 ao2_ref(contact_callback_data, -1);
914         }
915
916         return 0;
917 }
918
919 /*!
920  * \brief Task to qualify contacts of an AOR
921  * \note Run by aor_options->serializer
922  */
923 static int sip_options_qualify_aor(void *obj)
924 {
925         struct sip_options_aor *aor_options = obj;
926
927         ast_debug(3, "Qualifying all contacts on AOR '%s'\n", aor_options->name);
928
929         /* Attempt to send an OPTIONS request to every contact on this AOR */
930         ao2_callback(aor_options->contacts, OBJ_NODATA, sip_options_qualify_contact,
931                 (struct sip_options_aor *) aor_options);
932
933         /* Always reschedule to the frequency we should go */
934         return aor_options->qualify_frequency * 1000;
935 }
936
937 /*! \brief Forward declaration of this helpful function */
938 static int sip_options_remove_contact(void *obj, void *arg, int flags);
939
940 /*! \brief Destructor function for SIP OPTIONS AORs */
941 static void sip_options_aor_dtor(void *obj)
942 {
943         struct sip_options_aor *aor_options = obj;
944
945         /*
946          * Any contacts are unreachable since the AOR is being destroyed
947          * so remove their contact status
948          */
949         if (aor_options->contacts) {
950                 ao2_callback(aor_options->contacts, OBJ_NODATA | OBJ_UNLINK,
951                         sip_options_remove_contact, aor_options);
952                 ao2_ref(aor_options->contacts, -1);
953         }
954         ao2_cleanup(aor_options->dynamic_contacts);
955
956         ast_taskprocessor_unreference(aor_options->serializer);
957
958         ast_assert(AST_VECTOR_SIZE(&aor_options->compositors) == 0);
959         AST_VECTOR_FREE(&aor_options->compositors);
960 }
961
962 /*! \brief Allocator for AOR OPTIONS */
963 static struct sip_options_aor *sip_options_aor_alloc(struct ast_sip_aor *aor)
964 {
965         struct sip_options_aor *aor_options;
966         char tps_name[AST_TASKPROCESSOR_MAX_NAME + 1];
967
968         aor_options = ao2_alloc_options(sizeof(*aor_options) + strlen(ast_sorcery_object_get_id(aor)) + 1,
969                 sip_options_aor_dtor, AO2_ALLOC_OPT_LOCK_NOLOCK);
970         if (!aor_options) {
971                 return NULL;
972         }
973
974         strcpy(aor_options->name, ast_sorcery_object_get_id(aor)); /* SAFE */
975
976         ast_taskprocessor_build_name(tps_name, sizeof(tps_name), "pjsip/options/%s",
977                 ast_sorcery_object_get_id(aor));
978         aor_options->serializer = ast_sip_create_serializer_group(tps_name,
979                 shutdown_group);
980         if (!aor_options->serializer) {
981                 ao2_ref(aor_options, -1);
982                 return NULL;
983         }
984
985         if (AST_VECTOR_INIT(&aor_options->compositors, ENDPOINT_STATE_COMPOSITOR_INITIAL_SIZE)) {
986                 ao2_ref(aor_options, -1);
987                 return NULL;
988         }
989
990         aor_options->contacts = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_NOLOCK,
991                 AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, CONTACT_BUCKETS, ast_sorcery_object_id_hash,
992                 ast_sorcery_object_id_sort, ast_sorcery_object_id_compare);
993         if (!aor_options->contacts) {
994                 ao2_ref(aor_options, -1);
995                 return NULL;
996         }
997
998         aor_options->dynamic_contacts = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_NOLOCK,
999                 AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, CONTACT_BUCKETS, ast_sorcery_object_id_hash,
1000                 ast_sorcery_object_id_sort, ast_sorcery_object_id_compare);
1001         if (!aor_options->dynamic_contacts) {
1002                 ao2_ref(aor_options, -1);
1003                 return NULL;
1004         }
1005
1006         return aor_options;
1007 }
1008
1009 /*! \brief Remove contact status for a hint */
1010 static void sip_options_remove_contact_status(struct sip_options_aor *aor_options,
1011         struct ast_sip_contact *contact)
1012 {
1013         struct ast_sip_contact_status *cs_new;
1014         struct ast_sip_contact_status *cs_old;
1015
1016         cs_old = ao2_find(sip_options_contact_statuses, ast_sorcery_object_get_id(contact),
1017                 OBJ_SEARCH_KEY | OBJ_UNLINK);
1018         if (!cs_old) {
1019                 ast_debug(3, "Attempted to remove contact status for '%s' but it does not exist\n",
1020                         ast_sorcery_object_get_id(contact));
1021                 return;
1022         }
1023
1024         ast_verb(2, "Contact %s/%s has been deleted\n", contact->aor, contact->uri);
1025
1026         /* Update the contact status to reflect its new state */
1027         cs_new = sip_contact_status_copy(cs_old);
1028         if (!cs_new) {
1029                 /*
1030                  * We'll have to violate the immutable property because we
1031                  * couldn't create a new one to modify and we are deleting
1032                  * the contact status anyway.
1033                  */
1034                 cs_new = cs_old;
1035         } else {
1036                 ao2_ref(cs_old, -1);
1037         }
1038         cs_new->last_status = cs_new->status;
1039         cs_new->status = REMOVED;
1040         cs_new->rtt = 0;
1041
1042         ast_statsd_log_string_va("PJSIP.contacts.states.%s", AST_STATSD_GAUGE,
1043                 "-1", 1.0, ast_sip_get_contact_status_label(cs_new->last_status));
1044         ast_statsd_log_string_va("PJSIP.contacts.states.%s", AST_STATSD_GAUGE,
1045                 "+1", 1.0, ast_sip_get_contact_status_label(cs_new->status));
1046
1047         sip_options_contact_status_update(cs_new);
1048
1049         /*
1050          * The only time we need to update the AOR is if this contact was
1051          * available and qualify is in use, otherwise we can just stop
1052          * early.
1053          */
1054         if (!aor_options->qualify_frequency || cs_new->last_status != AVAILABLE) {
1055                 ao2_ref(cs_new, -1);
1056                 return;
1057         }
1058
1059         --aor_options->available;
1060         if (!aor_options->available) {
1061                 sip_options_notify_endpoint_state_compositors(aor_options, UNAVAILABLE);
1062         }
1063
1064         ast_debug(3, "AOR '%s' now has %d available contacts\n", aor_options->name,
1065                 aor_options->available);
1066
1067         ao2_ref(cs_new, -1);
1068 }
1069
1070 /*! \brief Task data for AOR creation or updating */
1071 struct sip_options_synchronize_aor_task_data {
1072         /*! \brief The AOR options for this AOR */
1073         struct sip_options_aor *aor_options;
1074         /*! \brief The AOR which contains the new configuraton */
1075         struct ast_sip_aor *aor;
1076         /*! \brief Optional container of existing AOR s*/
1077         struct ao2_container *existing;
1078         /*! \brief Whether this AOR is being added */
1079         int added;
1080 };
1081
1082 /*! \brief Callback function to remove a contact and its contact status from an AOR */
1083 static int sip_options_remove_contact(void *obj, void *arg, int flags)
1084 {
1085         struct ast_sip_contact *contact = obj;
1086         struct sip_options_aor *aor_options = arg;
1087
1088         sip_options_remove_contact_status(aor_options, contact);
1089
1090         return CMP_MATCH;
1091 }
1092
1093 /*! \brief Determine an initial time for scheduling AOR qualifying */
1094 static int sip_options_determine_initial_qualify_time(int qualify_frequency)
1095 {
1096         int initial_interval;
1097         int max_time = ast_sip_get_max_initial_qualify_time();
1098
1099         if (max_time && max_time < qualify_frequency) {
1100                 initial_interval = max_time;
1101         } else {
1102                 initial_interval = qualify_frequency;
1103         }
1104
1105         initial_interval = (int)((initial_interval * 1000) * ast_random_double());
1106         return 0 < initial_interval ? initial_interval : 1;
1107 }
1108
1109 /*! \brief Set the contact status for a contact */
1110 static void sip_options_set_contact_status(struct ast_sip_contact_status *contact_status,
1111         enum ast_sip_contact_status_type status)
1112 {
1113         struct ast_sip_contact_status *cs_new;
1114
1115         /* Update the contact specific status information */
1116         cs_new = sip_contact_status_copy(contact_status);
1117         if (!cs_new) {
1118                 return;
1119         }
1120         cs_new->last_status = cs_new->status;
1121         cs_new->status = status;
1122
1123         /*
1124          * We need to always set the RTT to zero because we haven't completed
1125          * an OPTIONS ping so RTT is unknown.  If the OPTIONS ping were still
1126          * running it will be refreshed on the next go round anyway.
1127          */
1128         cs_new->rtt = 0;
1129
1130         ao2_link(sip_options_contact_statuses, cs_new);
1131
1132         if (cs_new->status != cs_new->last_status) {
1133                 ast_verb(3, "Contact %s/%s is now %s.\n",
1134                         cs_new->aor, cs_new->uri,
1135                         ast_sip_get_contact_status_label(cs_new->status));
1136
1137                 ast_statsd_log_string_va("PJSIP.contacts.states.%s", AST_STATSD_GAUGE,
1138                         "-1", 1.0, ast_sip_get_contact_status_label(cs_new->last_status));
1139                 ast_statsd_log_string_va("PJSIP.contacts.states.%s", AST_STATSD_GAUGE,
1140                         "+1", 1.0, ast_sip_get_contact_status_label(cs_new->status));
1141
1142                 sip_options_contact_status_update(cs_new);
1143
1144                 ast_test_suite_event_notify("AOR_CONTACT_UPDATE",
1145                         "Contact: %s\r\n"
1146                         "Status: %s",
1147                         cs_new->name,
1148                         ast_sip_get_contact_status_label(cs_new->status));
1149         }
1150         ao2_ref(cs_new, -1);
1151 }
1152
1153 /*! \brief Transition the contact status to unqualified mode */
1154 static int sip_options_set_contact_status_unqualified(void *obj, void *arg, int flags)
1155 {
1156         struct ast_sip_contact *contact = obj;
1157         struct ast_sip_contact_status *contact_status;
1158
1159         contact_status = ast_res_pjsip_find_or_create_contact_status(contact);
1160         if (!contact_status) {
1161                 return 0;
1162         }
1163
1164         switch (contact_status->status) {
1165         case AVAILABLE:
1166         case UNAVAILABLE:
1167         case UNKNOWN:
1168                 sip_options_set_contact_status(contact_status, CREATED);
1169                 break;
1170         case CREATED:
1171         case REMOVED:
1172                 break;
1173         }
1174
1175         ao2_ref(contact_status, -1);
1176
1177         return 0;
1178 }
1179
1180 /*! \brief Transition the contact status to qualified mode */
1181 static int sip_options_set_contact_status_qualified(void *obj, void *arg, int flags)
1182 {
1183         struct ast_sip_contact *contact = obj;
1184         struct ast_sip_contact_status *contact_status;
1185
1186         contact_status = ast_res_pjsip_find_or_create_contact_status(contact);
1187         if (!contact_status) {
1188                 return 0;
1189         }
1190
1191         switch (contact_status->status) {
1192         case AVAILABLE:
1193                 sip_options_set_contact_status(contact_status, UNAVAILABLE);
1194                 break;
1195         case UNAVAILABLE:
1196         case UNKNOWN:
1197         case CREATED:
1198         case REMOVED:
1199                 break;
1200         }
1201
1202         ao2_ref(contact_status, -1);
1203
1204         return 0;
1205 }
1206
1207 /*! \brief Count AVAILABLE qualified contacts. */
1208 static int sip_options_contact_status_available_count(void *obj, void *arg, int flags)
1209 {
1210         struct ast_sip_contact *contact = obj;
1211         unsigned int *available = arg;
1212         struct ast_sip_contact_status *contact_status;
1213
1214         contact_status = ast_res_pjsip_find_or_create_contact_status(contact);
1215         if (!contact_status) {
1216                 return 0;
1217         }
1218
1219         /* Count qualified available contacts. */
1220         switch (contact_status->status) {
1221         case AVAILABLE:
1222                 ++*available;
1223                 break;
1224         case UNAVAILABLE:
1225         case UNKNOWN:
1226         case CREATED:
1227         case REMOVED:
1228                 break;
1229         }
1230
1231         ao2_ref(contact_status, -1);
1232
1233         return 0;
1234 }
1235
1236 /*!
1237  * \brief Function which applies configuration to an AOR options structure
1238  * \note Run by aor_options->serializer (or management_serializer on aor_options creation)
1239  */
1240 static void sip_options_apply_aor_configuration(struct sip_options_aor *aor_options,
1241         struct ast_sip_aor *aor, int is_new)
1242 {
1243         struct ao2_container *existing_contacts;
1244         struct ast_sip_contact *contact;
1245         struct ao2_iterator iter;
1246
1247         ast_debug(3, "Configuring AOR '%s' with current state of configuration and world\n",
1248                 aor_options->name);
1249
1250         /*
1251          * Permanent contacts, since we receive no notification that they
1252          * are gone, follow the same approach as AORs.  We create a copy
1253          * of the existing container and any reused contacts are removed
1254          * from it.  Any contacts remaining in the container after
1255          * processing no longer exist so we need to remove their state.
1256          */
1257         existing_contacts = ao2_container_clone(aor_options->contacts, 0);
1258         if (!existing_contacts) {
1259                 ast_log(LOG_WARNING, "Synchronization of AOR '%s' failed for qualify, retaining existing state\n",
1260                         aor_options->name);
1261                 return;
1262         }
1263
1264         ao2_callback(aor_options->contacts, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE,
1265                 NULL, NULL);
1266
1267         /* Process permanent contacts */
1268         if (aor->permanent_contacts) {
1269                 iter = ao2_iterator_init(aor->permanent_contacts, 0);
1270                 for (; (contact = ao2_iterator_next(&iter)); ao2_ref(contact, -1)) {
1271                         ao2_find(existing_contacts, ast_sorcery_object_get_id(contact),
1272                                 OBJ_NODATA | OBJ_UNLINK | OBJ_SEARCH_KEY);
1273                         ao2_link(aor_options->contacts, contact);
1274                 }
1275                 ao2_iterator_destroy(&iter);
1276         }
1277
1278         /*
1279          * If this is newly added we need to see if there are any
1280          * existing dynamic contacts to add.  Ones that are added
1281          * after creation will occur as a result of the contact
1282          * observer creation callback.
1283          */
1284         if (is_new) {
1285                 size_t prefix_len = strlen(ast_sorcery_object_get_id(aor)) + sizeof(";@") - 1;
1286                 char prefix[prefix_len + 1];
1287                 struct ao2_container *contacts;
1288
1289                 sprintf(prefix, "%s;@", ast_sorcery_object_get_id(aor)); /* Safe */
1290                 contacts = ast_sorcery_retrieve_by_prefix(ast_sip_get_sorcery(), "contact",
1291                         prefix, prefix_len);
1292                 if (contacts) {
1293                         ao2_container_dup(aor_options->dynamic_contacts, contacts, 0);
1294                         ao2_ref(contacts, -1);
1295                 }
1296         }
1297
1298         /* Process dynamic contacts */
1299         iter = ao2_iterator_init(aor_options->dynamic_contacts, 0);
1300         for (; (contact = ao2_iterator_next(&iter)); ao2_ref(contact, -1)) {
1301                 ao2_find(existing_contacts, ast_sorcery_object_get_id(contact),
1302                         OBJ_NODATA | OBJ_UNLINK | OBJ_SEARCH_KEY);
1303                 ao2_link(aor_options->contacts, contact);
1304         }
1305         ao2_iterator_destroy(&iter);
1306
1307         /* Any contacts left no longer exist, so raise events and make them disappear */
1308         ao2_callback(existing_contacts, OBJ_NODATA | OBJ_UNLINK,
1309                 sip_options_remove_contact, aor_options);
1310         ao2_ref(existing_contacts, -1);
1311
1312         /*
1313          * Update the available count if we transition between qualified
1314          * and unqualified.  In the qualified case we need to start with
1315          * 0 available as the qualify process will take care of it.  In
1316          * the unqualified case it is based on the number of contacts
1317          * present.
1318          */
1319         if (!aor->qualify_frequency) {
1320                 ao2_callback(aor_options->contacts, OBJ_NODATA,
1321                         sip_options_set_contact_status_unqualified, NULL);
1322                 aor_options->available = ao2_container_count(aor_options->contacts);
1323                 ast_debug(3, "AOR '%s' is unqualified, number of available contacts is therefore '%d'\n",
1324                         aor_options->name, aor_options->available);
1325         } else if (!aor_options->qualify_frequency) {
1326                 ao2_callback(aor_options->contacts, OBJ_NODATA,
1327                         sip_options_set_contact_status_qualified, NULL);
1328                 aor_options->available = 0;
1329                 ast_debug(3, "AOR '%s' has transitioned from unqualified to qualified, reset available contacts to 0\n",
1330                         aor_options->name);
1331         } else {
1332                 /*
1333                 * Count the number of AVAILABLE qualified contacts to ensure
1334                 * the count is in sync with reality.
1335                 */
1336                 aor_options->available = 0;
1337                 ao2_callback(aor_options->contacts, OBJ_NODATA,
1338                         sip_options_contact_status_available_count, &aor_options->available);
1339         }
1340
1341         aor_options->authenticate_qualify = aor->authenticate_qualify;
1342         aor_options->qualify_timeout = aor->qualify_timeout;
1343
1344         /*
1345          * If we need to stop or start the scheduled callback then do so.
1346          * This occurs due to the following:
1347          * 1. The qualify frequency has changed
1348          * 2. Contacts were added when previously there were none
1349          * 3. There are no contacts but previously there were some
1350          */
1351         if (aor_options->qualify_frequency != aor->qualify_frequency
1352                 || (!aor_options->sched_task && ao2_container_count(aor_options->contacts))
1353                 || (aor_options->sched_task && !ao2_container_count(aor_options->contacts))) {
1354                 if (aor_options->sched_task) {
1355                         ast_sip_sched_task_cancel(aor_options->sched_task);
1356                         ao2_ref(aor_options->sched_task, -1);
1357                         aor_options->sched_task = NULL;
1358                 }
1359
1360                 /* If there is still a qualify frequency then schedule this */
1361                 aor_options->qualify_frequency = aor->qualify_frequency;
1362                 if (aor_options->qualify_frequency
1363                         && ao2_container_count(aor_options->contacts)) {
1364                         aor_options->sched_task = ast_sip_schedule_task(aor_options->serializer,
1365                                 sip_options_determine_initial_qualify_time(aor_options->qualify_frequency),
1366                                 sip_options_qualify_aor, ast_taskprocessor_name(aor_options->serializer),
1367                                 aor_options, AST_SIP_SCHED_TASK_VARIABLE | AST_SIP_SCHED_TASK_DATA_AO2);
1368                         if (!aor_options->sched_task) {
1369                                 ast_log(LOG_ERROR, "Unable to schedule qualify for contacts of AOR '%s'\n",
1370                                         aor_options->name);
1371                         }
1372                 }
1373         }
1374
1375         ast_debug(3, "AOR '%s' now has %d available contacts\n", aor_options->name,
1376                 aor_options->available);
1377 }
1378
1379 /*!
1380  * \brief Task to synchronize an AOR with our local state
1381  * \note Run by aor_options->serializer (or management_serializer on aor_options creation)
1382  */
1383 static int sip_options_synchronize_aor_task(void *obj)
1384 {
1385         struct sip_options_synchronize_aor_task_data *task_data = obj;
1386         int i;
1387
1388         ast_debug(3, "Synchronizing AOR '%s' with current state of configuration and world\n",
1389                 task_data->aor_options->name);
1390
1391         sip_options_apply_aor_configuration(task_data->aor_options, task_data->aor,
1392                 task_data->added);
1393
1394         /*
1395          * Endpoint state compositors are removed in this operation but not
1396          * added.  To reduce the amount of work done they are done later.  In
1397          * the mean time things can still qualify and once an endpoint state
1398          * compositor is added to the AOR it will be updated with the current
1399          * state.
1400          */
1401         for (i = 0; i < AST_VECTOR_SIZE(&task_data->aor_options->compositors); ++i) {
1402                 struct sip_options_endpoint_state_compositor *endpoint_state_compositor;
1403
1404                 endpoint_state_compositor = AST_VECTOR_GET(&task_data->aor_options->compositors, i);
1405
1406                 ao2_lock(endpoint_state_compositor);
1407                 endpoint_state_compositor->active = 0;
1408                 sip_options_update_endpoint_state_compositor_aor(endpoint_state_compositor,
1409                         task_data->aor_options->name, REMOVED);
1410                 ao2_unlock(endpoint_state_compositor);
1411         }
1412         AST_VECTOR_RESET(&task_data->aor_options->compositors, ao2_cleanup);
1413
1414         return 0;
1415 }
1416
1417 /*!
1418  * \brief Synchronize an AOR with our local state
1419  * \note Run by management_serializer
1420  */
1421 static int sip_options_synchronize_aor(void *obj, void *arg, int flags)
1422 {
1423         struct sip_options_synchronize_aor_task_data task_data = {
1424                 .aor = obj,
1425                 .existing = arg,
1426         };
1427
1428         task_data.aor_options = ao2_find(sip_options_aors,
1429                 ast_sorcery_object_get_id(task_data.aor), OBJ_SEARCH_KEY);
1430         if (!task_data.aor_options) {
1431                 task_data.aor_options = sip_options_aor_alloc(task_data.aor);
1432                 if (!task_data.aor_options) {
1433                         return 0;
1434                 }
1435
1436                 task_data.added = 1;
1437
1438                 /* Nothing is aware of this AOR yet so we can just update it in this thread */
1439                 sip_options_synchronize_aor_task(&task_data);
1440                 ao2_link(sip_options_aors, task_data.aor_options);
1441         } else {
1442                 /* This AOR already exists so we have to do manipulation in its serializer */
1443                 ast_sip_push_task_wait_serializer(task_data.aor_options->serializer,
1444                         sip_options_synchronize_aor_task, &task_data);
1445         }
1446
1447         ao2_ref(task_data.aor_options, -1);
1448
1449         if (task_data.existing) {
1450                 ao2_find(task_data.existing, ast_sorcery_object_get_id(task_data.aor),
1451                         OBJ_SEARCH_KEY | OBJ_UNLINK | OBJ_NODATA);
1452         }
1453
1454         return 0;
1455 }
1456
1457 /*! \brief Destructor for endpoint state compositors */
1458 static void sip_options_endpoint_state_compositor_dtor(void *obj)
1459 {
1460         struct sip_options_endpoint_state_compositor *endpoint_state_compositor = obj;
1461
1462         ao2_cleanup(endpoint_state_compositor->aor_statuses);
1463 }
1464
1465 /*! \brief Hashing function for endpoint AOR status */
1466 AO2_STRING_FIELD_HASH_FN(sip_options_endpoint_aor_status, name);
1467
1468 /*! \brief Comparator function for endpoint AOR status */
1469 AO2_STRING_FIELD_CMP_FN(sip_options_endpoint_aor_status, name);
1470
1471 /*! \brief Find (or create) an endpoint state compositor */
1472 static struct sip_options_endpoint_state_compositor *sip_options_endpoint_state_compositor_find_or_alloc(const struct ast_sip_endpoint *endpoint)
1473 {
1474         struct sip_options_endpoint_state_compositor *endpoint_state_compositor;
1475
1476         ao2_lock(sip_options_endpoint_state_compositors);
1477         endpoint_state_compositor = ao2_find(sip_options_endpoint_state_compositors,
1478                 ast_sorcery_object_get_id(endpoint), OBJ_SEARCH_KEY | OBJ_NOLOCK);
1479         if (endpoint_state_compositor) {
1480                 ao2_unlock(sip_options_endpoint_state_compositors);
1481                 return endpoint_state_compositor;
1482         }
1483
1484         endpoint_state_compositor = ao2_alloc(sizeof(*endpoint_state_compositor)
1485                 + strlen(ast_sorcery_object_get_id(endpoint)) + 1,
1486                 sip_options_endpoint_state_compositor_dtor);
1487         if (!endpoint_state_compositor) {
1488                 ao2_unlock(sip_options_endpoint_state_compositors);
1489                 return NULL;
1490         }
1491
1492         /*
1493          * NOTE: The endpoint_state_compositor->aor_statuses container is
1494          * externally protected by the endpoint_state_compositor lock.
1495          */
1496         endpoint_state_compositor->aor_statuses = ao2_container_alloc_hash(
1497                 AO2_ALLOC_OPT_LOCK_NOLOCK, 0, AOR_STATUS_BUCKETS,
1498                 sip_options_endpoint_aor_status_hash_fn, NULL,
1499                 sip_options_endpoint_aor_status_cmp_fn);
1500         if (!endpoint_state_compositor->aor_statuses) {
1501                 ao2_unlock(sip_options_endpoint_state_compositors);
1502                 ao2_ref(endpoint_state_compositor, -1);
1503                 return NULL;
1504         }
1505
1506         strcpy(endpoint_state_compositor->name, ast_sorcery_object_get_id(endpoint)); /* SAFE */
1507
1508         ao2_link_flags(sip_options_endpoint_state_compositors, endpoint_state_compositor,
1509                 OBJ_NOLOCK);
1510         ao2_unlock(sip_options_endpoint_state_compositors);
1511
1512         return endpoint_state_compositor;
1513 }
1514
1515 /*! \brief Task details for adding an AOR to an endpoint state compositor */
1516 struct sip_options_endpoint_compositor_task_data {
1517         /*! \brief The AOR options that the endpoint state compositor should be added to */
1518         struct sip_options_aor *aor_options;
1519         /*! \brief The endpoint state compositor */
1520         struct sip_options_endpoint_state_compositor *endpoint_state_compositor;
1521 };
1522
1523 /*!
1524  * \brief Task which adds an AOR to an endpoint state compositor
1525  * \note Run by aor_options->serializer
1526  */
1527 static int sip_options_endpoint_compositor_add_task(void *obj)
1528 {
1529         struct sip_options_endpoint_compositor_task_data *task_data = obj;
1530
1531         ast_debug(3, "Adding endpoint compositor '%s' to AOR '%s'\n",
1532                 task_data->endpoint_state_compositor->name, task_data->aor_options->name);
1533
1534         ao2_ref(task_data->endpoint_state_compositor, +1);
1535         if (AST_VECTOR_APPEND(&task_data->aor_options->compositors,
1536                 task_data->endpoint_state_compositor)) {
1537                 /* Failed to add so no need to update the endpoint status.  Nothing changed. */
1538                 ao2_ref(task_data->endpoint_state_compositor, -1);
1539                 return 0;
1540         }
1541
1542         ao2_lock(task_data->endpoint_state_compositor);
1543         sip_options_update_endpoint_state_compositor_aor(task_data->endpoint_state_compositor,
1544                 task_data->aor_options->name,
1545                 task_data->aor_options->available ? AVAILABLE : UNAVAILABLE);
1546         ao2_unlock(task_data->endpoint_state_compositor);
1547
1548         return 0;
1549 }
1550
1551 /*!
1552  * \brief Task which adds removes an AOR from an endpoint state compositor
1553  * \note Run by aor_options->serializer
1554  */
1555 static int sip_options_endpoint_compositor_remove_task(void *obj)
1556 {
1557         struct sip_options_endpoint_compositor_task_data *task_data = obj;
1558         int i;
1559
1560         ast_debug(3, "Removing endpoint compositor '%s' from AOR '%s'\n",
1561                 task_data->endpoint_state_compositor->name,
1562                 task_data->aor_options->name);
1563
1564         for (i = 0; i < AST_VECTOR_SIZE(&task_data->aor_options->compositors); ++i) {
1565                 struct sip_options_endpoint_state_compositor *endpoint_state_compositor;
1566
1567                 endpoint_state_compositor = AST_VECTOR_GET(&task_data->aor_options->compositors, i);
1568                 if (endpoint_state_compositor != task_data->endpoint_state_compositor) {
1569                         continue;
1570                 }
1571
1572                 AST_VECTOR_REMOVE(&task_data->aor_options->compositors, i, 0);
1573                 ao2_ref(endpoint_state_compositor, -1);
1574                 break;
1575         }
1576
1577         return 0;
1578 }
1579
1580 /*!
1581  * \brief Synchronize an endpoint with our local state
1582  * \note Run by management_serializer
1583  */
1584 static int sip_options_synchronize_endpoint(void *obj, void *arg, int flags)
1585 {
1586         struct ast_sip_endpoint *endpoint = obj;
1587         struct ast_sip_aor *aor = arg;
1588         char *aors;
1589         char *aor_name;
1590         struct sip_options_endpoint_compositor_task_data task_data = { NULL, };
1591
1592         if (ast_strlen_zero(endpoint->aors)) {
1593                 /* There are no AORs, so really... who the heck knows */
1594                 ast_debug(3, "Endpoint '%s' is not interested in any AORs so not creating endpoint state compositor\n",
1595                         ast_sorcery_object_get_id(endpoint));
1596                 return 0;
1597         }
1598
1599         ast_debug(3, "Synchronizing endpoint '%s' with AORs '%s'\n",
1600                 ast_sorcery_object_get_id(endpoint), endpoint->aors);
1601
1602         aors = ast_strdupa(endpoint->aors);
1603         while ((aor_name = ast_strip(strsep(&aors, ",")))) {
1604                 if (ast_strlen_zero(aor_name)) {
1605                         continue;
1606                 }
1607                 if (aor && strcasecmp(ast_sorcery_object_get_id(aor), aor_name)) {
1608                         ast_debug(3, "Filtered AOR '%s' on endpoint '%s' as we are looking for '%s'\n",
1609                                 aor_name, ast_sorcery_object_get_id(endpoint),
1610                                 ast_sorcery_object_get_id(aor));
1611                         continue;
1612                 }
1613
1614                 task_data.aor_options = ao2_find(sip_options_aors, aor_name, OBJ_SEARCH_KEY);
1615                 if (!task_data.aor_options) {
1616                         /*
1617                          * They have referenced an invalid AOR. If that's all they've
1618                          * done we will set them to offline at the end.
1619                          */
1620                         ast_debug(3, "Endpoint '%s' referenced invalid AOR '%s'\n",
1621                                 ast_sorcery_object_get_id(endpoint), aor_name);
1622                         continue;
1623                 }
1624
1625                 if (!task_data.endpoint_state_compositor) {
1626                         /*
1627                          * We create an endpoint state compositor only after we know
1628                          * for sure we need it.
1629                          */
1630                         task_data.endpoint_state_compositor =
1631                                 sip_options_endpoint_state_compositor_find_or_alloc(endpoint);
1632                         if (!task_data.endpoint_state_compositor) {
1633                                 ast_log(LOG_WARNING,
1634                                         "Could not create endpoint state compositor for '%s', endpoint state will be incorrect\n",
1635                                         ast_sorcery_object_get_id(endpoint));
1636                                 ao2_ref(task_data.aor_options, -1);
1637                                 ast_sip_persistent_endpoint_update_state(ast_sorcery_object_get_id(endpoint),
1638                                         AST_ENDPOINT_OFFLINE);
1639                                 return 0;
1640                         }
1641                 }
1642
1643                 /* We use a synchronous task so that we don't flood the system */
1644                 ast_sip_push_task_wait_serializer(task_data.aor_options->serializer,
1645                         sip_options_endpoint_compositor_add_task, &task_data);
1646
1647                 ao2_ref(task_data.aor_options, -1);
1648
1649                 /*
1650                  * If we filtered on a specific AOR name then the endpoint can
1651                  * only reference it once so break early.
1652                  */
1653                 if (aor) {
1654                         break;
1655                 }
1656         }
1657
1658         if (task_data.endpoint_state_compositor) {
1659                 /*
1660                  * If an endpoint state compositor is present determine the current state
1661                  * of the endpoint and update it.
1662                  */
1663                 ao2_lock(task_data.endpoint_state_compositor);
1664                 task_data.endpoint_state_compositor->active = 1;
1665                 ast_sip_persistent_endpoint_update_state(ast_sorcery_object_get_id(endpoint),
1666                         sip_options_get_endpoint_state_compositor_state(task_data.endpoint_state_compositor));
1667                 ao2_unlock(task_data.endpoint_state_compositor);
1668
1669                 ao2_ref(task_data.endpoint_state_compositor, -1);
1670         } else {
1671                 /* If there is none then they may have referenced an invalid AOR or none at all */
1672                 ast_debug(3, "Endpoint '%s' has no AORs feeding it, setting it to offline state as default\n",
1673                         ast_sorcery_object_get_id(endpoint));
1674                 ast_sip_persistent_endpoint_update_state(ast_sorcery_object_get_id(endpoint),
1675                         AST_ENDPOINT_OFFLINE);
1676         }
1677
1678         return 0;
1679 }
1680
1681 /*!
1682  * \brief Task which removes an AOR from all of the ESCs it is reporting to
1683  * \note Run by aor_options->serializer
1684  */
1685 static int sip_options_aor_remove_task(void *obj)
1686 {
1687         struct sip_options_aor *aor_options = obj;
1688
1689         sip_options_notify_endpoint_state_compositors(aor_options, REMOVED);
1690
1691         if (aor_options->sched_task) {
1692                 ast_sip_sched_task_cancel(aor_options->sched_task);
1693                 ao2_ref(aor_options->sched_task, -1);
1694                 aor_options->sched_task = NULL;
1695         }
1696
1697         return 0;
1698 }
1699
1700 /*!
1701  * \brief Callback which removes any unused AORs that remained after reloading
1702  * \note Run by management_serializer
1703  */
1704 static int sip_options_unused_aor(void *obj, void *arg, int flags)
1705 {
1706         struct sip_options_aor *aor_options = obj;
1707
1708         ast_debug(3, "AOR '%s' is no longer configured, removing it\n", aor_options->name);
1709
1710         ast_sip_push_task_wait_serializer(aor_options->serializer, sip_options_aor_remove_task,
1711                 aor_options);
1712         ao2_unlink(sip_options_aors, aor_options);
1713
1714         return CMP_MATCH;
1715 }
1716
1717 /*!
1718  * \brief Callback function used to unlink and remove event state compositors that have no AORs feeding them
1719  * \note Run by management_serializer
1720  */
1721 static int sip_options_unused_endpoint_state_compositor(void *obj, void *arg, int flags)
1722 {
1723         struct sip_options_endpoint_state_compositor *endpoint_state_compositor = obj;
1724
1725         if (ao2_container_count(endpoint_state_compositor->aor_statuses)) {
1726                 return 0;
1727         }
1728
1729         /* No AORs are feeding this endpoint state compositor */
1730         ast_sip_persistent_endpoint_update_state(endpoint_state_compositor->name,
1731                 AST_ENDPOINT_OFFLINE);
1732
1733         return CMP_MATCH;
1734 }
1735
1736 /*! \brief Structure which contains information required to synchronize */
1737 struct sip_options_synchronize_task_data {
1738         /*! \brief Whether this is a reload or not */
1739         int reload;
1740 };
1741
1742 /*!
1743  * \brief Task to synchronize our local container of AORs and endpoint state compositors with the current configuration
1744  * \note Run by management_serializer
1745  */
1746 static int sip_options_synchronize_task(void *obj)
1747 {
1748         struct sip_options_synchronize_task_data *task_data = obj;
1749         struct ao2_container *existing = NULL;
1750         struct ao2_container *objects;
1751
1752         /*
1753          * When reloading we keep track of the existing AORs so we can
1754          * terminate old ones that are no longer referenced or used.
1755          */
1756         if (task_data->reload) {
1757                 existing = ao2_container_clone(sip_options_aors, 0);
1758                 if (!existing) {
1759                         return 0;
1760                 }
1761         }
1762
1763         objects = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "aor",
1764                 AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
1765         if (objects) {
1766                 /* Go through the returned AORs and synchronize with our local state */
1767                 ao2_callback(objects, OBJ_NODATA, sip_options_synchronize_aor, existing);
1768                 ao2_ref(objects, -1);
1769         }
1770
1771         /*
1772          * Any AORs remaining in existing are no longer referenced by
1773          * the current container of AORs we retrieved, so remove them.
1774          */
1775         if (existing) {
1776                 ao2_callback(existing, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK,
1777                         sip_options_unused_aor, NULL);
1778                 ao2_ref(existing, -1);
1779         }
1780
1781         objects = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "endpoint",
1782                 AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
1783         if (objects) {
1784                 /* Go through the provided endpoints and update AORs */
1785                 ao2_callback(objects, OBJ_NODATA, sip_options_synchronize_endpoint, NULL);
1786                 ao2_ref(objects, -1);
1787         }
1788
1789         /*
1790          * All endpoint state compositors that don't have any AORs
1791          * feeding them information can be removed.  If they end
1792          * up getting needed later they'll just be recreated.
1793          */
1794         ao2_callback(sip_options_endpoint_state_compositors,
1795                 OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK,
1796                 sip_options_unused_endpoint_state_compositor, NULL);
1797
1798         return 0;
1799 }
1800
1801 /*! \brief Synchronize our local container of AORs and endpoint state compositors with the current configuration */
1802 static void sip_options_synchronize(int reload)
1803 {
1804         struct sip_options_synchronize_task_data task_data = {
1805                 .reload = reload,
1806         };
1807
1808         ast_sip_push_task_wait_serializer(management_serializer, sip_options_synchronize_task,
1809                 &task_data);
1810 }
1811
1812 /*!
1813  * \brief Unlink AORs feeding the endpoint status compositor
1814  * \note Run by management_serializer
1815  */
1816 static void sip_options_endpoint_unlink_aor_feeders(struct ast_sip_endpoint *endpoint,
1817         struct sip_options_endpoint_state_compositor *endpoint_state_compositor)
1818 {
1819         struct ao2_iterator it_aor_statuses;
1820         struct sip_options_endpoint_aor_status *aor_status;
1821         struct sip_options_endpoint_compositor_task_data task_data = {
1822                 .endpoint_state_compositor = endpoint_state_compositor,
1823         };
1824
1825         ao2_lock(endpoint_state_compositor);
1826         endpoint_state_compositor->active = 0;
1827
1828         /* Unlink AOR feeders pointing to endpoint */
1829         it_aor_statuses = ao2_iterator_init(endpoint_state_compositor->aor_statuses, 0);
1830         for (; (aor_status = ao2_iterator_next(&it_aor_statuses)); ao2_ref(aor_status, -1)) {
1831                 task_data.aor_options = ao2_find(sip_options_aors, aor_status->name,
1832                         OBJ_SEARCH_KEY);
1833                 if (!task_data.aor_options) {
1834                         continue;
1835                 }
1836
1837                 ast_debug(3, "Removing endpoint state compositor '%s' from AOR '%s'\n",
1838                         ast_sorcery_object_get_id(endpoint), aor_status->name);
1839                 ao2_unlock(endpoint_state_compositor);
1840                 ast_sip_push_task_wait_serializer(task_data.aor_options->serializer,
1841                         sip_options_endpoint_compositor_remove_task, &task_data);
1842                 ao2_lock(endpoint_state_compositor);
1843                 ao2_ref(task_data.aor_options, -1);
1844         }
1845         ao2_iterator_destroy(&it_aor_statuses);
1846
1847         /*
1848          * We do not need to remove the AOR feeder status memory from the
1849          * aor_statuses container.  The endpoint_state_compositor is about
1850          * to die and do it for us.
1851          */
1852
1853         ao2_unlock(endpoint_state_compositor);
1854 }
1855
1856 /*!
1857  * \brief Task to delete an endpoint from the known universe
1858  * \note Run by management_serializer
1859  */
1860 static int sip_options_endpoint_observer_deleted_task(void *obj)
1861 {
1862         struct ast_sip_endpoint *endpoint = obj;
1863         struct sip_options_endpoint_state_compositor *endpoint_state_compositor;
1864
1865         endpoint_state_compositor = ao2_find(sip_options_endpoint_state_compositors,
1866                 ast_sorcery_object_get_id(endpoint), OBJ_SEARCH_KEY | OBJ_UNLINK);
1867         if (!endpoint_state_compositor) {
1868                 return 0;
1869         }
1870
1871         ast_debug(3, "Endpoint '%s' has been deleted, removing endpoint state compositor from AORs\n",
1872                 ast_sorcery_object_get_id(endpoint));
1873         sip_options_endpoint_unlink_aor_feeders(endpoint, endpoint_state_compositor);
1874         ao2_ref(endpoint_state_compositor, -1);
1875
1876         return 0;
1877 }
1878
1879 /*! \brief Observer callback invoked on endpoint deletion */
1880 static void endpoint_observer_deleted(const void *obj)
1881 {
1882         ast_sip_push_task_wait_serializer(management_serializer,
1883                 sip_options_endpoint_observer_deleted_task, (void *) obj);
1884 }
1885
1886 /*!
1887  * \brief Task to synchronize the endpoint
1888  * \note Run by management_serializer
1889  */
1890 static int sip_options_endpoint_observer_modified_task(void *obj)
1891 {
1892         struct ast_sip_endpoint *endpoint = obj;
1893         struct sip_options_endpoint_state_compositor *endpoint_state_compositor;
1894
1895         ast_debug(3, "Endpoint '%s' has been created or modified, updating state\n",
1896                 ast_sorcery_object_get_id(endpoint));
1897
1898         endpoint_state_compositor = ao2_find(sip_options_endpoint_state_compositors,
1899                 ast_sorcery_object_get_id(endpoint), OBJ_SEARCH_KEY | OBJ_UNLINK);
1900         if (endpoint_state_compositor) {
1901                 /* Unlink the AORs currently feeding the endpoint. */
1902                 sip_options_endpoint_unlink_aor_feeders(endpoint, endpoint_state_compositor);
1903                 ao2_ref(endpoint_state_compositor, -1);
1904         }
1905
1906         /* Connect the AORs that now feed the endpoint. */
1907         sip_options_synchronize_endpoint(endpoint, NULL, 0);
1908         return 0;
1909 }
1910
1911 /*! \brief Observer callback invoked on endpoint creation or modification */
1912 static void endpoint_observer_modified(const void *obj)
1913 {
1914         ast_sip_push_task_wait_serializer(management_serializer,
1915                 sip_options_endpoint_observer_modified_task, (void *)obj);
1916 }
1917
1918 /*! \brief Observer callbacks for endpoints */
1919 static const struct ast_sorcery_observer endpoint_observer_callbacks = {
1920         .created = endpoint_observer_modified,
1921         .updated = endpoint_observer_modified,
1922         .deleted = endpoint_observer_deleted,
1923 };
1924
1925 /*!
1926  * \brief Task to synchronize an AOR with our local state
1927  * \note Run by aor_options->serializer
1928  */
1929 static int sip_options_update_aor_task(void *obj)
1930 {
1931         struct sip_options_synchronize_aor_task_data *task_data = obj;
1932         int available = task_data->aor_options->available;
1933
1934         ast_debug(3, "Individually updating AOR '%s' with current state of configuration and world\n",
1935                 task_data->aor_options->name);
1936
1937         sip_options_apply_aor_configuration(task_data->aor_options, task_data->aor,
1938                 task_data->added);
1939
1940         if (!available && task_data->aor_options->available) {
1941                 ast_debug(3, "After modifying AOR '%s' it has now become available\n",
1942                         task_data->aor_options->name);
1943                 sip_options_notify_endpoint_state_compositors(task_data->aor_options, AVAILABLE);
1944         } else if (available && !task_data->aor_options->available) {
1945                 ast_debug(3, "After modifying AOR '%s' it has become unavailable\n",
1946                         task_data->aor_options->name);
1947                 sip_options_notify_endpoint_state_compositors(task_data->aor_options, UNAVAILABLE);
1948         }
1949
1950         return 0;
1951 }
1952
1953 /*!
1954  * \brief Task to synchronize the AOR
1955  * \note Run by management_serializer
1956  */
1957 static int sip_options_aor_observer_modified_task(void *obj)
1958 {
1959         struct ast_sip_aor *aor = obj;
1960         struct sip_options_aor *aor_options;
1961
1962         aor_options = ao2_find(sip_options_aors, ast_sorcery_object_get_id(aor),
1963                 OBJ_SEARCH_KEY);
1964         if (!aor_options) {
1965                 struct ao2_container *endpoints;
1966
1967                 aor_options = sip_options_aor_alloc(aor);
1968                 if (!aor_options) {
1969                         return 0;
1970                 }
1971
1972                 /*
1973                  * This is a newly added AOR and we need to establish any
1974                  * endpoint state compositors that may reference only the
1975                  * AOR.  If these need to be updated later then they'll
1976                  * be done by modifying the endpoint or issuing a reload.
1977                  */
1978                 sip_options_apply_aor_configuration(aor_options, aor, 1);
1979                 ao2_link(sip_options_aors, aor_options);
1980
1981                 /*
1982                  * Using LIKE doesn't seem to work very well with non-realtime so we
1983                  * fetch everything right now and do a filter on our side.
1984                  */
1985                 endpoints = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(),
1986                         "endpoint", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
1987                 if (endpoints) {
1988                         ao2_callback(endpoints, OBJ_NODATA, sip_options_synchronize_endpoint, aor);
1989                         ao2_ref(endpoints, -1);
1990                 }
1991         } else {
1992                 struct sip_options_synchronize_aor_task_data task_data = {
1993                         .aor_options = aor_options,
1994                         .aor = aor,
1995                 };
1996
1997                 /*
1998                  * If this AOR was modified we have to do our work in its serializer
1999                  * instead of this thread to ensure that things aren't modified by
2000                  * multiple threads.
2001                  */
2002                 ast_sip_push_task_wait_serializer(aor_options->serializer,
2003                         sip_options_update_aor_task, &task_data);
2004         }
2005
2006         ao2_ref(aor_options, -1);
2007
2008         return 0;
2009 }
2010
2011 /*! \brief Observer callback invoked on AOR creation or modification */
2012 static void aor_observer_modified(const void *obj)
2013 {
2014         ast_sip_push_task_wait_serializer(management_serializer,
2015                 sip_options_aor_observer_modified_task, (void *) obj);
2016 }
2017
2018 /*!
2019  * \brief Task to delete an AOR from the known universe
2020  * \note Run by management_serializer
2021  */
2022 static int sip_options_aor_observer_deleted_task(void *obj)
2023 {
2024         struct ast_sip_aor *aor = obj;
2025         struct sip_options_aor *aor_options;
2026
2027         aor_options = ao2_find(sip_options_aors, ast_sorcery_object_get_id(aor),
2028                 OBJ_SEARCH_KEY | OBJ_UNLINK);
2029         if (!aor_options) {
2030                 return 0;
2031         }
2032
2033         ast_debug(3, "AOR '%s' has been deleted, removing it\n", aor_options->name);
2034
2035         ast_sip_push_task_wait_serializer(aor_options->serializer, sip_options_aor_remove_task,
2036                 aor_options);
2037         ao2_ref(aor_options, -1);
2038
2039         return 0;
2040 }
2041
2042 /*! \brief Observer callback invoked on AOR deletion */
2043 static void aor_observer_deleted(const void *obj)
2044 {
2045         ast_sip_push_task_wait_serializer(management_serializer,
2046                 sip_options_aor_observer_deleted_task, (void *) obj);
2047 }
2048
2049 /*! \brief Observer callbacks for AORs */
2050 static const struct ast_sorcery_observer aor_observer_callbacks = {
2051         .created = aor_observer_modified,
2052         .updated = aor_observer_modified,
2053         .deleted = aor_observer_deleted,
2054 };
2055
2056 /*! \brief Task details for adding an AOR to an endpoint state compositor */
2057 struct sip_options_contact_observer_task_data {
2058         /*! \brief The AOR options that the contact is referring to */
2059         struct sip_options_aor *aor_options;
2060         /*! \brief The contact itself */
2061         struct ast_sip_contact *contact;
2062 };
2063
2064
2065 /*!
2066  * \brief Check if the contact qualify options are different than local aor qualify options
2067  */
2068 static int has_qualify_changed (const struct ast_sip_contact *contact, const struct sip_options_aor *aor_options)
2069 {
2070         if (!contact) {
2071             return 0;
2072         }
2073
2074         if (!aor_options) {
2075                 if (contact->qualify_frequency) {
2076                         return 1;
2077                 }
2078         } else if (contact->qualify_frequency != aor_options->qualify_frequency
2079                 || contact->authenticate_qualify != aor_options->authenticate_qualify
2080                 || ((int)(contact->qualify_timeout * 1000)) != ((int)(aor_options->qualify_timeout * 1000))) {
2081                 return 1;
2082         }
2083
2084         return 0;
2085 }
2086
2087 /*!
2088  * \brief Task which adds a dynamic contact to an AOR
2089  * \note Run by aor_options->serializer
2090  */
2091 static int sip_options_contact_add_task(void *obj)
2092 {
2093         struct sip_options_contact_observer_task_data *task_data = obj;
2094         struct ast_sip_contact_status *contact_status;
2095
2096         ao2_link(task_data->aor_options->dynamic_contacts, task_data->contact);
2097         ao2_link(task_data->aor_options->contacts, task_data->contact);
2098
2099         contact_status = ast_res_pjsip_find_or_create_contact_status(task_data->contact);
2100         ao2_cleanup(contact_status);
2101
2102         if (task_data->aor_options->qualify_frequency) {
2103                 /* If this is the first contact we need to schedule up qualification */
2104                 if (ao2_container_count(task_data->aor_options->contacts) == 1) {
2105                         ast_debug(3, "Starting scheduled callback on AOR '%s' for qualifying as there is now a contact on it\n",
2106                                 task_data->aor_options->name);
2107                         /*
2108                          * We immediately schedule the initial qualify so that we get
2109                          * reachable/unreachable as soon as possible.  Realistically
2110                          * since they pretty much just registered they should be
2111                          * reachable.
2112                          */
2113                         if (task_data->aor_options->sched_task) {
2114                                 ast_sip_sched_task_cancel(task_data->aor_options->sched_task);
2115                                 ao2_ref(task_data->aor_options->sched_task, -1);
2116                                 task_data->aor_options->sched_task = NULL;
2117                         }
2118                         task_data->aor_options->sched_task = ast_sip_schedule_task(
2119                                 task_data->aor_options->serializer, 1, sip_options_qualify_aor,
2120                                 ast_taskprocessor_name(task_data->aor_options->serializer),
2121                                 task_data->aor_options,
2122                                 AST_SIP_SCHED_TASK_VARIABLE | AST_SIP_SCHED_TASK_DATA_AO2);
2123                         if (!task_data->aor_options->sched_task) {
2124                                 ast_log(LOG_ERROR, "Unable to schedule qualify for contacts of AOR '%s'\n",
2125                                         task_data->aor_options->name);
2126                         }
2127                 }
2128         } else {
2129                 /*
2130                  * If this was the first contact added to a non-qualified AOR then
2131                  * it should become available.
2132                  */
2133                 task_data->aor_options->available =
2134                         ao2_container_count(task_data->aor_options->contacts);
2135                 if (task_data->aor_options->available == 1) {
2136                         ast_debug(3, "An unqualified contact has been added to AOR '%s' so it is now available\n",
2137                                 task_data->aor_options->name);
2138                         sip_options_notify_endpoint_state_compositors(task_data->aor_options,
2139                                 AVAILABLE);
2140                 }
2141         }
2142
2143         return 0;
2144 }
2145
2146 /*!
2147  * \brief Task to add a dynamic contact to an AOR in its serializer
2148  * \note Run by management_serializer
2149  */
2150 static int sip_options_contact_add_management_task(void *obj)
2151 {
2152         struct sip_options_contact_observer_task_data task_data;
2153
2154         task_data.contact = obj;
2155         task_data.aor_options = ao2_find(sip_options_aors, task_data.contact->aor,
2156                 OBJ_SEARCH_KEY);
2157
2158         if (has_qualify_changed(task_data.contact, task_data.aor_options)) {
2159                 struct ast_sip_aor *aor;
2160
2161                 aor = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "aor",
2162                         task_data.contact->aor);
2163                 if (aor) {
2164                         ast_debug(3, "AOR '%s' qualify options have been modified. Synchronize an AOR local state\n",
2165                                 task_data.contact->aor);
2166                         sip_options_aor_observer_modified_task(aor);
2167                         ao2_ref(aor, -1);
2168                 }
2169         }
2170
2171         if (!task_data.aor_options) {
2172                 return 0;
2173         }
2174
2175         ast_sip_push_task_wait_serializer(task_data.aor_options->serializer,
2176                 sip_options_contact_add_task, &task_data);
2177         ao2_ref(task_data.aor_options, -1);
2178
2179         return 0;
2180 }
2181
2182 /*! \brief Observer callback invoked on contact creation */
2183 static void contact_observer_created(const void *obj)
2184 {
2185         ast_sip_push_task_wait_serializer(management_serializer,
2186                 sip_options_contact_add_management_task, (void *) obj);
2187 }
2188
2189 /*! \brief Observer callback invoked on contact update */
2190 static void contact_observer_updated(const void *obj)
2191 {
2192         const struct ast_sip_contact *contact = obj;
2193         struct sip_options_aor *aor_options = ao2_find(sip_options_aors, contact->aor, OBJ_SEARCH_KEY);
2194
2195         if (has_qualify_changed(contact, aor_options)) {
2196                 struct ast_sip_aor *aor;
2197
2198                 aor = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "aor",
2199                         contact->aor);
2200                 if (aor) {
2201                         ast_debug(3, "AOR '%s' qualify options have been modified. Synchronize an AOR local state\n",
2202                                 contact->aor);
2203                         ast_sip_push_task_wait_serializer(management_serializer,
2204                                 sip_options_aor_observer_modified_task, aor);
2205                         ao2_ref(aor, -1);
2206                 }
2207         }
2208
2209         ao2_cleanup(aor_options);
2210 }
2211
2212 /*!
2213  * \brief Task which deletes a dynamic contact from an AOR
2214  * \note Run by aor_options->serializer
2215  */
2216 static int sip_options_contact_delete_task(void *obj)
2217 {
2218         struct sip_options_contact_observer_task_data *task_data = obj;
2219
2220         ao2_find(task_data->aor_options->dynamic_contacts, task_data->contact,
2221                 OBJ_NODATA | OBJ_UNLINK | OBJ_SEARCH_OBJECT);
2222         ao2_find(task_data->aor_options->contacts, task_data->contact,
2223                 OBJ_NODATA | OBJ_UNLINK | OBJ_SEARCH_OBJECT);
2224
2225         sip_options_remove_contact_status(task_data->aor_options, task_data->contact);
2226
2227         if (task_data->aor_options->qualify_frequency) {
2228                 /* If this is the last contact then we need to stop the scheduled callback */
2229                 if (!ao2_container_count(task_data->aor_options->contacts)) {
2230                         ast_debug(3, "Terminating scheduled callback on AOR '%s' as there are no contacts to qualify\n",
2231                                 task_data->aor_options->name);
2232                         if (task_data->aor_options->sched_task) {
2233                                 ast_sip_sched_task_cancel(task_data->aor_options->sched_task);
2234                                 ao2_ref(task_data->aor_options->sched_task, -1);
2235                                 task_data->aor_options->sched_task = NULL;
2236                         }
2237                 }
2238         } else {
2239                 task_data->aor_options->available =
2240                         ao2_container_count(task_data->aor_options->contacts);
2241                 if (!task_data->aor_options->available) {
2242                         ast_debug(3, "An unqualified contact has been removed from AOR '%s' leaving no remaining contacts\n",
2243                                 task_data->aor_options->name);
2244                         sip_options_notify_endpoint_state_compositors(task_data->aor_options,
2245                                 UNAVAILABLE);
2246                 }
2247         }
2248
2249         return 0;
2250 }
2251
2252 /*!
2253  * \brief Task to delete a contact from an AOR in its serializer
2254  * \note Run by management_serializer
2255  */
2256 static int sip_options_contact_delete_management_task(void *obj)
2257 {
2258         struct sip_options_contact_observer_task_data task_data;
2259
2260         task_data.contact = obj;
2261         task_data.aor_options = ao2_find(sip_options_aors, task_data.contact->aor,
2262                 OBJ_SEARCH_KEY);
2263         if (!task_data.aor_options) {
2264                 /* For contacts that are deleted we don't really care if there is no AOR locally */
2265                 return 0;
2266         }
2267
2268         ast_sip_push_task_wait_serializer(task_data.aor_options->serializer,
2269                 sip_options_contact_delete_task, &task_data);
2270         ao2_ref(task_data.aor_options, -1);
2271
2272         return 0;
2273 }
2274
2275 /*! \brief Observer callback invoked on contact deletion */
2276 static void contact_observer_deleted(const void *obj)
2277 {
2278         ast_sip_push_task_wait_serializer(management_serializer,
2279                 sip_options_contact_delete_management_task, (void *) obj);
2280 }
2281
2282 /*! \brief Observer callbacks for contacts */
2283 static const struct ast_sorcery_observer contact_observer_callbacks = {
2284         .created = contact_observer_created,
2285         .updated = contact_observer_updated,
2286         .deleted = contact_observer_deleted,
2287 };
2288
2289 static char *cli_qualify(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2290 {
2291         RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
2292         const char *endpoint_name;
2293         char *aors;
2294         char *aor_name;
2295
2296         switch (cmd) {
2297         case CLI_INIT:
2298                 e->command = "pjsip qualify";
2299                 e->usage =
2300                         "Usage: pjsip qualify <endpoint>\n"
2301                         "       Send a SIP OPTIONS request to all contacts on the endpoint.\n";
2302                 return NULL;
2303         case CLI_GENERATE:
2304                 return NULL;
2305         }
2306
2307         if (a->argc != 3) {
2308                 return CLI_SHOWUSAGE;
2309         }
2310
2311         endpoint_name = a->argv[2];
2312
2313         endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint",
2314                 endpoint_name);
2315         if (!endpoint) {
2316                 ast_cli(a->fd, "Unable to retrieve endpoint %s\n", endpoint_name);
2317                 return CLI_FAILURE;
2318         }
2319
2320         if (ast_strlen_zero(endpoint->aors)) {
2321                 ast_cli(a->fd, "No AORs configured for endpoint '%s'\n", endpoint_name);
2322                 return CLI_FAILURE;
2323         }
2324
2325         aors = ast_strdupa(endpoint->aors);
2326         while ((aor_name = ast_strip(strsep(&aors, ",")))) {
2327                 struct sip_options_aor *aor_options;
2328
2329                 aor_options = ao2_find(sip_options_aors, aor_name, OBJ_SEARCH_KEY);
2330                 if (!aor_options) {
2331                         continue;
2332                 }
2333
2334                 ast_cli(a->fd, "Qualifying AOR '%s' on endpoint '%s'\n", aor_name, endpoint_name);
2335                 ast_sip_push_task_wait_serializer(aor_options->serializer, sip_options_qualify_aor,
2336                         aor_options);
2337                 ao2_ref(aor_options, -1);
2338         }
2339
2340         return CLI_SUCCESS;
2341 }
2342
2343 static struct ao2_container *get_all_contacts(void)
2344 {
2345         struct ao2_container *contacts;
2346
2347         contacts = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "contact",
2348                         AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
2349
2350         return contacts;
2351 }
2352
2353 static int sip_contact_to_ami(const struct ast_sip_contact *contact,
2354                            struct ast_str **buf)
2355 {
2356         return ast_sip_sorcery_object_to_ami(contact, buf);
2357 }
2358
2359 static int format_ami_contactlist_handler(void *obj, void *arg, int flags)
2360 {
2361         struct ast_sip_contact *contact = obj;
2362         struct ast_sip_ami *ami = arg;
2363         struct ast_str *buf;
2364         struct ast_sip_contact_status *status;
2365
2366         buf = ast_sip_create_ami_event("ContactList", ami);
2367         if (!buf) {
2368                 return CMP_STOP;
2369         }
2370
2371         if (sip_contact_to_ami(contact, &buf)) {
2372                 ast_free(buf);
2373                 return CMP_STOP;
2374         }
2375
2376         /* Add extra info */
2377         status = ast_sip_get_contact_status(contact);
2378         ast_str_append(&buf, 0, "Status: %s\r\n",
2379                 ast_sip_get_contact_status_label(status ? status->status : UNKNOWN));
2380         if (!status || status->status != AVAILABLE) {
2381                 ast_str_append(&buf, 0, "RoundtripUsec: N/A\r\n");
2382         } else {
2383                 ast_str_append(&buf, 0, "RoundtripUsec: %" PRId64 "\r\n", status->rtt);
2384         }
2385         ao2_cleanup(status);
2386
2387         astman_append(ami->s, "%s\r\n", ast_str_buffer(buf));
2388
2389         ami->count++;
2390
2391         ast_free(buf);
2392
2393         return 0;
2394 }
2395
2396 static int ami_show_contacts(struct mansession *s, const struct message *m)
2397 {
2398         struct ast_sip_ami ami = { .s = s, .m = m, .action_id = astman_get_header(m, "ActionID"), };
2399         struct ao2_container *contacts;
2400
2401         contacts = get_all_contacts();
2402         if (!contacts) {
2403                 astman_send_error(s, m, "Could not get Contacts\n");
2404                 return 0;
2405         }
2406
2407         if (!ao2_container_count(contacts)) {
2408                 astman_send_error(s, m, "No Contacts found\n");
2409                 ao2_ref(contacts, -1);
2410                 return 0;
2411         }
2412
2413         astman_send_listack(s, m, "A listing of Contacts follows, presented as ContactList events",
2414                         "start");
2415
2416         ao2_callback(contacts, OBJ_NODATA, format_ami_contactlist_handler, &ami);
2417
2418         astman_send_list_complete_start(s, m, "ContactListComplete", ami.count);
2419         astman_send_list_complete_end(s);
2420
2421         ao2_ref(contacts, -1);
2422
2423         return 0;
2424 }
2425
2426 static char *cli_show_qualify_endpoint(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2427 {
2428         RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
2429         const char *endpoint_name;
2430         char *aors;
2431         char *aor_name;
2432
2433         switch (cmd) {
2434         case CLI_INIT:
2435                 e->command = "pjsip show qualify endpoint";
2436                 e->usage =
2437                         "Usage: pjsip show qualify endpoint <id>\n"
2438                         "       Show the current qualify options for all Aors on the PJSIP endpoint.\n";
2439                 return NULL;
2440         case CLI_GENERATE:
2441                 return NULL;
2442         }
2443
2444         if (a->argc != 5) {
2445                 return CLI_SHOWUSAGE;
2446         }
2447
2448         endpoint_name = a->argv[4];
2449
2450         endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint",
2451                 endpoint_name);
2452         if (!endpoint) {
2453                 ast_cli(a->fd, "Unable to retrieve endpoint %s\n", endpoint_name);
2454                 return CLI_FAILURE;
2455         }
2456
2457         if (ast_strlen_zero(endpoint->aors)) {
2458                 ast_cli(a->fd, "No AORs configured for endpoint '%s'\n", endpoint_name);
2459                 return CLI_FAILURE;
2460         }
2461
2462         aors = ast_strdupa(endpoint->aors);
2463         while ((aor_name = ast_strip(strsep(&aors, ",")))) {
2464                 struct sip_options_aor *aor_options;
2465
2466                 aor_options = ao2_find(sip_options_aors, aor_name, OBJ_SEARCH_KEY);
2467                 if (!aor_options) {
2468                         continue;
2469                 }
2470
2471                 ast_cli(a->fd, " * AOR '%s' on endpoint '%s'\n", aor_name, endpoint_name);
2472                 ast_cli(a->fd, "  Qualify frequency    : %d sec\n", aor_options->qualify_frequency);
2473                 ast_cli(a->fd, "  Qualify timeout      : %d ms\n", (int)(aor_options->qualify_timeout / 1000));
2474                 ast_cli(a->fd, "  Authenticate qualify : %s\n", aor_options->authenticate_qualify?"yes":"no");
2475                 ast_cli(a->fd, "\n");
2476                 ao2_ref(aor_options, -1);
2477         }
2478
2479         return CLI_SUCCESS;
2480 }
2481
2482 static char *cli_show_qualify_aor(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2483 {
2484         struct sip_options_aor *aor_options;
2485         const char *aor_name;
2486
2487         switch (cmd) {
2488         case CLI_INIT:
2489                 e->command = "pjsip show qualify aor";
2490                 e->usage =
2491                         "Usage: pjsip show qualify aor <id>\n"
2492                         "       Show the PJSIP Aor current qualify options.\n";
2493                 return NULL;
2494         case CLI_GENERATE:
2495                 return NULL;
2496         }
2497
2498         if (a->argc != 5) {
2499                 return CLI_SHOWUSAGE;
2500         }
2501
2502         aor_name = a->argv[4];
2503
2504         aor_options = ao2_find(sip_options_aors, aor_name, OBJ_SEARCH_KEY);
2505         if (!aor_options) {
2506                 ast_cli(a->fd, "Unable to retrieve aor '%s' qualify options\n", aor_name);
2507                 return CLI_FAILURE;
2508         }
2509
2510         ast_cli(a->fd, " * AOR '%s'\n", aor_name);
2511         ast_cli(a->fd, "  Qualify frequency    : %d sec\n", aor_options->qualify_frequency);
2512         ast_cli(a->fd, "  Qualify timeout      : %d ms\n", (int)(aor_options->qualify_timeout / 1000));
2513         ast_cli(a->fd, "  Authenticate qualify : %s\n", aor_options->authenticate_qualify?"yes":"no");
2514         ao2_ref(aor_options, -1);
2515
2516         return CLI_SUCCESS;
2517 }
2518
2519 static char *cli_reload_qualify_endpoint(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2520 {
2521         RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
2522         const char *endpoint_name;
2523         char *aors;
2524         char *aor_name;
2525
2526         switch (cmd) {
2527         case CLI_INIT:
2528                 e->command = "pjsip reload qualify endpoint";
2529                 e->usage =
2530                         "Usage: pjsip reload qualify endpoint <id>\n"
2531                         "       Synchronize the qualify options for all Aors on the PJSIP endpoint.\n";
2532                 return NULL;
2533         case CLI_GENERATE:
2534                 return NULL;
2535         }
2536
2537         if (a->argc != 5) {
2538                 return CLI_SHOWUSAGE;
2539         }
2540
2541         endpoint_name = a->argv[4];
2542
2543         endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint",
2544                 endpoint_name);
2545         if (!endpoint) {
2546                 ast_cli(a->fd, "Unable to retrieve endpoint %s\n", endpoint_name);
2547                 return CLI_FAILURE;
2548         }
2549
2550         if (ast_strlen_zero(endpoint->aors)) {
2551                 ast_cli(a->fd, "No AORs configured for endpoint '%s'\n", endpoint_name);
2552                 return CLI_FAILURE;
2553         }
2554
2555         aors = ast_strdupa(endpoint->aors);
2556         while ((aor_name = ast_strip(strsep(&aors, ",")))) {
2557                 struct ast_sip_aor *aor;
2558
2559                 aor = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "aor", aor_name);
2560                 if (!aor) {
2561                         continue;
2562                 }
2563
2564                 ast_cli(a->fd, "Synchronizing AOR '%s' on endpoint '%s'\n", aor_name, endpoint_name);
2565                 ast_sip_push_task_wait_serializer(management_serializer,
2566                         sip_options_aor_observer_modified_task, aor);
2567                 ao2_ref(aor, -1);
2568         }
2569
2570         return CLI_SUCCESS;
2571 }
2572
2573 static char *cli_reload_qualify_aor(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2574 {
2575         struct ast_sip_aor *aor;
2576         const char *aor_name;
2577
2578         switch (cmd) {
2579         case CLI_INIT:
2580                 e->command = "pjsip reload qualify aor";
2581                 e->usage =
2582                         "Usage: pjsip reload qualify aor <id>\n"
2583                         "       Synchronize the PJSIP Aor qualify options.\n";
2584                 return NULL;
2585         case CLI_GENERATE:
2586                 return NULL;
2587         }
2588
2589         if (a->argc != 5) {
2590                 return CLI_SHOWUSAGE;
2591         }
2592
2593         aor_name = a->argv[4];
2594
2595         aor = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "aor", aor_name);
2596         if (!aor) {
2597                 ast_cli(a->fd, "Unable to retrieve aor '%s'\n", aor_name);
2598                 return CLI_FAILURE;
2599         }
2600
2601         ast_cli(a->fd, "Synchronizing AOR '%s'\n", aor_name);
2602         ast_sip_push_task_wait_serializer(management_serializer,
2603                 sip_options_aor_observer_modified_task, aor);
2604         ao2_ref(aor, -1);
2605
2606         return CLI_SUCCESS;
2607 }
2608
2609 static int ami_sip_qualify(struct mansession *s, const struct message *m)
2610 {
2611         const char *endpoint_name = astman_get_header(m, "Endpoint");
2612         RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
2613         char *aors;
2614         char *aor_name;
2615
2616         if (ast_strlen_zero(endpoint_name)) {
2617                 astman_send_error(s, m, "Endpoint parameter missing.");
2618                 return 0;
2619         }
2620
2621         endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint",
2622                 endpoint_name);
2623         if (!endpoint) {
2624                 astman_send_error(s, m, "Unable to retrieve endpoint\n");
2625                 return 0;
2626         }
2627
2628         /* send a qualify for all contacts registered with the endpoint */
2629         if (ast_strlen_zero(endpoint->aors)) {
2630                 astman_send_error(s, m, "No AoRs configured for endpoint\n");
2631                 return 0;
2632         }
2633
2634         aors = ast_strdupa(endpoint->aors);
2635         while ((aor_name = ast_strip(strsep(&aors, ",")))) {
2636                 struct sip_options_aor *aor_options;
2637
2638                 aor_options = ao2_find(sip_options_aors, aor_name, OBJ_SEARCH_KEY);
2639                 if (!aor_options) {
2640                         continue;
2641                 }
2642
2643                 ast_sip_push_task_wait_serializer(aor_options->serializer, sip_options_qualify_aor,
2644                         aor_options);
2645                 ao2_ref(aor_options, -1);
2646         }
2647
2648         astman_send_ack(s, m, "Endpoint found, will qualify");
2649         return 0;
2650 }
2651
2652 static struct ast_cli_entry cli_options[] = {
2653         AST_CLI_DEFINE(cli_qualify, "Send an OPTIONS request to a PJSIP endpoint"),
2654         AST_CLI_DEFINE(cli_show_qualify_endpoint, "Show the current qualify options for all Aors on the PJSIP endpoint"),
2655         AST_CLI_DEFINE(cli_show_qualify_aor, "Show the PJSIP Aor current qualify options"),
2656         AST_CLI_DEFINE(cli_reload_qualify_endpoint, "Synchronize the qualify options for all Aors on the PJSIP endpoint"),
2657         AST_CLI_DEFINE(cli_reload_qualify_aor, "Synchronize the PJSIP Aor qualify options"),
2658 };
2659
2660 int ast_sip_format_contact_ami(void *obj, void *arg, int flags)
2661 {
2662         struct ast_sip_contact_wrapper *wrapper = obj;
2663         struct ast_sip_contact *contact = wrapper->contact;
2664         struct ast_sip_ami *ami = arg;
2665         struct ast_sip_contact_status *status;
2666         struct ast_str *buf;
2667         const struct ast_sip_endpoint *endpoint = ami->arg;
2668
2669         buf = ast_sip_create_ami_event("ContactStatusDetail", ami);
2670         if (!buf) {
2671                 return -1;
2672         }
2673
2674         status = ast_sip_get_contact_status(contact);
2675
2676         ast_str_append(&buf, 0, "AOR: %s\r\n", wrapper->aor_id);
2677         ast_str_append(&buf, 0, "URI: %s\r\n", contact->uri);
2678         ast_str_append(&buf, 0, "UserAgent: %s\r\n", contact->user_agent);
2679         ast_str_append(&buf, 0, "RegExpire: %ld\r\n", contact->expiration_time.tv_sec);
2680         if (!ast_strlen_zero(contact->via_addr)) {
2681                 ast_str_append(&buf, 0, "ViaAddress: %s", contact->via_addr);
2682                 if (contact->via_port) {
2683                         ast_str_append(&buf, 0, ":%d", contact->via_port);
2684                 }
2685                 ast_str_append(&buf, 0, "\r\n");
2686         }
2687         if (!ast_strlen_zero(contact->call_id)) {
2688                 ast_str_append(&buf, 0, "CallID: %s\r\n", contact->call_id);
2689         }
2690         ast_str_append(&buf, 0, "Status: %s\r\n",
2691                 ast_sip_get_contact_status_label(status ? status->status : UNKNOWN));
2692         if (!status || status->status != AVAILABLE) {
2693                 ast_str_append(&buf, 0, "RoundtripUsec: N/A\r\n");
2694         } else {
2695                 ast_str_append(&buf, 0, "RoundtripUsec: %" PRId64 "\r\n", status->rtt);
2696         }
2697         ast_str_append(&buf, 0, "EndpointName: %s\r\n",
2698                 endpoint ? ast_sorcery_object_get_id(endpoint) : S_OR(contact->endpoint_name, ""));
2699
2700         ast_str_append(&buf, 0, "ID: %s\r\n", ast_sorcery_object_get_id(contact));
2701         ast_str_append(&buf, 0, "AuthenticateQualify: %d\r\n", contact->authenticate_qualify);
2702         ast_str_append(&buf, 0, "OutboundProxy: %s\r\n", contact->outbound_proxy);
2703         ast_str_append(&buf, 0, "Path: %s\r\n", contact->path);
2704         ast_str_append(&buf, 0, "QualifyFrequency: %u\r\n", contact->qualify_frequency);
2705         ast_str_append(&buf, 0, "QualifyTimeout: %.3f\r\n", contact->qualify_timeout);
2706
2707         astman_append(ami->s, "%s\r\n", ast_str_buffer(buf));
2708         ami->count++;
2709
2710         ast_free(buf);
2711         ao2_cleanup(status);
2712         return 0;
2713 }
2714
2715 static int format_contact_status_for_aor(void *obj, void *arg, int flags)
2716 {
2717         struct ast_sip_aor *aor = obj;
2718
2719         return ast_sip_for_each_contact(aor, ast_sip_format_contact_ami, arg);
2720 }
2721
2722 static int format_ami_contact_status(const struct ast_sip_endpoint *endpoint,
2723                 struct ast_sip_ami *ami)
2724 {
2725         ami->arg = (void *)endpoint;
2726         return ast_sip_for_each_aor(endpoint->aors, format_contact_status_for_aor, ami);
2727 }
2728
2729 static struct ast_sip_endpoint_formatter contact_status_formatter = {
2730         .format_ami = format_ami_contact_status
2731 };
2732
2733 /*!
2734  * \brief Management task to clean up an AOR
2735  * \note Run by aor_options->serializer
2736  */
2737 static int sip_options_cleanup_aor_task(void *obj)
2738 {
2739         struct sip_options_aor *aor_options = obj;
2740
2741         ast_debug(2, "Cleaning up AOR '%s' for shutdown\n", aor_options->name);
2742
2743         aor_options->qualify_frequency = 0;
2744         if (aor_options->sched_task) {
2745                 ast_sip_sched_task_cancel(aor_options->sched_task);
2746                 ao2_ref(aor_options->sched_task, -1);
2747                 aor_options->sched_task = NULL;
2748         }
2749         AST_VECTOR_RESET(&aor_options->compositors, ao2_cleanup);
2750
2751         return 0;
2752 }
2753
2754 /*!
2755  * \brief Management task to clean up the environment
2756  * \note Run by management_serializer
2757  */
2758 static int sip_options_cleanup_task(void *obj)
2759 {
2760         struct ao2_iterator it_aor;
2761         struct sip_options_aor *aor_options;
2762
2763         if (!sip_options_aors) {
2764                 /* Nothing to do */
2765                 return 0;
2766         }
2767
2768         it_aor = ao2_iterator_init(sip_options_aors, AO2_ITERATOR_UNLINK);
2769         for (; (aor_options = ao2_iterator_next(&it_aor)); ao2_ref(aor_options, -1)) {
2770                 ast_sip_push_task_wait_serializer(aor_options->serializer,
2771                         sip_options_cleanup_aor_task, aor_options);
2772         }
2773         ao2_iterator_destroy(&it_aor);
2774
2775         return 0;
2776 }
2777
2778 void ast_res_pjsip_cleanup_options_handling(void)
2779 {
2780         int remaining;
2781         struct ast_taskprocessor *mgmt_serializer;
2782
2783         ast_cli_unregister_multiple(cli_options, ARRAY_LEN(cli_options));
2784         ast_manager_unregister("PJSIPQualify");
2785         ast_manager_unregister("PJSIPShowContacts");
2786         ast_sip_unregister_endpoint_formatter(&contact_status_formatter);
2787
2788         ast_sorcery_observer_remove(ast_sip_get_sorcery(), "contact",
2789                 &contact_observer_callbacks);
2790         ast_sorcery_observer_remove(ast_sip_get_sorcery(), "aor",
2791                 &aor_observer_callbacks);
2792         ast_sorcery_observer_remove(ast_sip_get_sorcery(), "endpoint",
2793                 &endpoint_observer_callbacks);
2794
2795         mgmt_serializer = management_serializer;
2796         management_serializer = NULL;
2797         if (mgmt_serializer) {
2798                 ast_sip_push_task_wait_serializer(mgmt_serializer, sip_options_cleanup_task, NULL);
2799         }
2800
2801         remaining = ast_serializer_shutdown_group_join(shutdown_group,
2802                 MAX_UNLOAD_TIMEOUT_TIME);
2803         if (remaining) {
2804                 ast_log(LOG_WARNING, "Cleanup incomplete. Could not stop %d AORs.\n",
2805                         remaining);
2806         }
2807         ao2_cleanup(shutdown_group);
2808         shutdown_group = NULL;
2809
2810         if (mgmt_serializer) {
2811                 ast_taskprocessor_unreference(mgmt_serializer);
2812         }
2813
2814         ao2_cleanup(sip_options_aors);
2815         sip_options_aors = NULL;
2816         ao2_cleanup(sip_options_contact_statuses);
2817         sip_options_contact_statuses = NULL;
2818         ao2_cleanup(sip_options_endpoint_state_compositors);
2819         sip_options_endpoint_state_compositors = NULL;
2820
2821         pjsip_endpt_unregister_module(ast_sip_get_pjsip_endpoint(), &options_module);
2822 }
2823
2824 /*!
2825  * \brief Management task to finish setting up the environment.
2826  * \note Run by management_serializer
2827  */
2828 static int sip_options_init_task(void *mgmt_serializer)
2829 {
2830         management_serializer = mgmt_serializer;
2831
2832         shutdown_group = ast_serializer_shutdown_group_alloc();
2833         if (!shutdown_group) {
2834                 return -1;
2835         }
2836
2837         if (ast_sorcery_observer_add(ast_sip_get_sorcery(), "endpoint",
2838                 &endpoint_observer_callbacks)) {
2839                 return -1;
2840         }
2841         if (ast_sorcery_observer_add(ast_sip_get_sorcery(), "aor",
2842                 &aor_observer_callbacks)) {
2843                 return -1;
2844         }
2845         if (ast_sorcery_observer_add(ast_sip_get_sorcery(), "contact",
2846                 &contact_observer_callbacks)) {
2847                 return -1;
2848         }
2849
2850         sip_options_synchronize(0);
2851
2852         return 0;
2853 }
2854
2855 int ast_res_pjsip_preinit_options_handling(void)
2856 {
2857         sip_options_contact_statuses = sip_options_contact_statuses_alloc();
2858         return sip_options_contact_statuses ? 0 : -1;
2859 }
2860
2861 int ast_res_pjsip_init_options_handling(int reload)
2862 {
2863         struct ast_taskprocessor *mgmt_serializer;
2864
2865         static const pj_str_t STR_OPTIONS = { "OPTIONS", 7 };
2866
2867         if (reload) {
2868                 sip_options_synchronize(1);
2869                 return 0;
2870         }
2871
2872         if (pjsip_endpt_register_module(ast_sip_get_pjsip_endpoint(), &options_module)
2873                 != PJ_SUCCESS) {
2874                 return -1;
2875         }
2876
2877         if (pjsip_endpt_add_capability(ast_sip_get_pjsip_endpoint(), NULL, PJSIP_H_ALLOW,
2878                 NULL, 1, &STR_OPTIONS) != PJ_SUCCESS) {
2879                 ast_res_pjsip_cleanup_options_handling();
2880                 return -1;
2881         }
2882
2883         sip_options_aors = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_RWLOCK, 0, AOR_BUCKETS,
2884                 sip_options_aor_hash_fn, NULL, sip_options_aor_cmp_fn);
2885         if (!sip_options_aors) {
2886                 ast_res_pjsip_cleanup_options_handling();
2887                 return -1;
2888         }
2889         sip_options_endpoint_state_compositors =
2890                 ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_RWLOCK, 0,
2891                         ENDPOINT_STATE_COMPOSITOR_BUCKETS,
2892                         sip_options_endpoint_state_compositor_hash_fn, NULL,
2893                         sip_options_endpoint_state_compositor_cmp_fn);
2894         if (!sip_options_endpoint_state_compositors) {
2895                 ast_res_pjsip_cleanup_options_handling();
2896                 return -1;
2897         }
2898
2899         mgmt_serializer = ast_sip_create_serializer("pjsip/options/manage");
2900         if (!mgmt_serializer) {
2901                 ast_res_pjsip_cleanup_options_handling();
2902                 return -1;
2903         }
2904
2905         /*
2906          * Set the water mark levels high because we can get a flood of
2907          * contact status updates from sip_options_synchronize() that
2908          * quickly clears on initial load or reload.
2909          */
2910         ast_taskprocessor_alert_set_levels(mgmt_serializer, -1,
2911                 10 * AST_TASKPROCESSOR_HIGH_WATER_LEVEL);
2912
2913         /*
2914          * We make sure that the environment is completely setup before we allow
2915          * any other threads to post contact_status updates to the
2916          * management_serializer.
2917          */
2918         if (ast_sip_push_task_wait_serializer(mgmt_serializer, sip_options_init_task,
2919                 mgmt_serializer)) {
2920                 /* Set management_serializer in case pushing the task actually failed. */
2921                 management_serializer = mgmt_serializer;
2922                 ast_res_pjsip_cleanup_options_handling();
2923                 return -1;
2924         }
2925
2926         ast_sip_register_endpoint_formatter(&contact_status_formatter);
2927         ast_manager_register_xml("PJSIPQualify", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING,
2928                 ami_sip_qualify);
2929         ast_manager_register_xml("PJSIPShowContacts", EVENT_FLAG_SYSTEM, ami_show_contacts);
2930         ast_cli_register_multiple(cli_options, ARRAY_LEN(cli_options));
2931
2932         return 0;
2933 }