62640fe4e630af55473fcecfc02b151bfcb17972
[asterisk/asterisk.git] / res / res_pjsip / pjsip_options.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * Matt Jordan <mjordan@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 #include "asterisk.h"
20
21 #include <pjsip.h>
22 #include <pjsip_ua.h>
23 #include <pjlib.h>
24
25 #include "asterisk/res_pjsip.h"
26 #include "asterisk/channel.h"
27 #include "asterisk/pbx.h"
28 #include "asterisk/astobj2.h"
29 #include "asterisk/cli.h"
30 #include "asterisk/time.h"
31 #include "asterisk/test.h"
32 #include "asterisk/statsd.h"
33 #include "include/res_pjsip_private.h"
34
35 #define DEFAULT_LANGUAGE "en"
36 #define DEFAULT_ENCODING "text/plain"
37 #define QUALIFIED_BUCKETS 211
38
39 static const char *status_map [] = {
40         [UNAVAILABLE] = "Unreachable",
41         [AVAILABLE] = "Reachable",
42         [UNKNOWN] = "Unknown",
43         [CREATED] = "Created",
44         [REMOVED] = "Removed",
45         [UPDATED] = "Updated",
46 };
47
48 static const char *short_status_map [] = {
49         [UNAVAILABLE] = "Unavail",
50         [AVAILABLE] = "Avail",
51         [UNKNOWN] = "Unknown",
52         [CREATED] = "Created",
53         [REMOVED] = "Removed",
54         [UPDATED] = "Updated",
55 };
56
57 const char *ast_sip_get_contact_status_label(const enum ast_sip_contact_status_type status)
58 {
59         return status_map[status];
60 }
61
62 const char *ast_sip_get_contact_short_status_label(const enum ast_sip_contact_status_type status)
63 {
64         return short_status_map[status];
65 }
66
67 /*!
68  * \internal
69  * \brief Destroy a ast_sip_contact_status object.
70  */
71 static void contact_status_destroy(void * obj)
72 {
73         struct ast_sip_contact_status *status = obj;
74
75         ast_string_field_free_memory(status);
76 }
77
78 /*!
79  * \internal
80  * \brief Create a ast_sip_contact_status object.
81  */
82 static void *contact_status_alloc(const char *name)
83 {
84         struct ast_sip_contact_status *status = ast_sorcery_generic_alloc(sizeof(*status), contact_status_destroy);
85         char *id = ast_strdupa(name);
86         char *aor = id;
87         char *aor_separator = NULL;
88
89         if (!status) {
90                 ast_log(LOG_ERROR, "Unable to allocate ast_sip_contact_status\n");
91                 return NULL;
92         }
93
94         if (ast_string_field_init(status, 256)) {
95                 ast_log(LOG_ERROR, "Unable to allocate ast_sip_contact_status stringfields\n");
96                 ao2_cleanup(status);
97                 return NULL;
98         }
99
100         /* Dynamic contacts are delimited with ";@" and static ones with "@@" */
101         if ((aor_separator = strstr(id, ";@")) || (aor_separator = strstr(id, "@@"))) {
102                 *aor_separator = '\0';
103         }
104         ast_assert(aor_separator != NULL);
105
106         ast_string_field_set(status, aor, aor);
107         status->status = CREATED;
108
109         return status;
110 }
111
112 AST_MUTEX_DEFINE_STATIC(creation_lock);
113
114 /*!
115  * \brief Retrieve a ast_sip_contact_status object from sorcery creating
116  *        one if not found.
117  */
118 struct ast_sip_contact_status *ast_res_pjsip_find_or_create_contact_status(const struct ast_sip_contact *contact)
119 {
120         struct ast_sip_contact_status *status;
121         SCOPED_MUTEX(lock, &creation_lock);
122
123         status = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), CONTACT_STATUS,
124                 ast_sorcery_object_get_id(contact));
125         if (status) {
126                 return status;
127         }
128
129         status = ast_sorcery_alloc(ast_sip_get_sorcery(), CONTACT_STATUS,
130                 ast_sorcery_object_get_id(contact));
131         if (!status) {
132                 ast_log(LOG_ERROR, "Unable to create ast_sip_contact_status for contact %s/%s\n",
133                         contact->aor, contact->uri);
134                 return NULL;
135         }
136
137         ast_string_field_set(status, uri, contact->uri);
138         status->rtt_start = ast_tv(0, 0);
139         status->rtt = 0;
140
141         if (ast_sorcery_create(ast_sip_get_sorcery(), status)) {
142                 ast_log(LOG_ERROR, "Unable to persist ast_sip_contact_status for contact %s\n",
143                         contact->uri);
144                 ao2_ref(status, -1);
145                 return NULL;
146         }
147
148         ast_statsd_log_string_va("PJSIP.contacts.states.%s", AST_STATSD_GAUGE,
149                 "+1", 1.0, ast_sip_get_contact_status_label(status->status));
150
151         return status;
152 }
153
154 /*!
155  * \internal
156  * \brief Update an ast_sip_contact_status's elements.
157  */
158 static void update_contact_status(const struct ast_sip_contact *contact,
159         enum ast_sip_contact_status_type value)
160 {
161         RAII_VAR(struct ast_sip_contact_status *, status, NULL, ao2_cleanup);
162         RAII_VAR(struct ast_sip_contact_status *, update, NULL, ao2_cleanup);
163
164         status = ast_res_pjsip_find_or_create_contact_status(contact);
165         if (!status) {
166                 ast_log(LOG_ERROR, "Unable to find ast_sip_contact_status for contact %s\n",
167                         contact->uri);
168                 return;
169         }
170
171         update = ast_sorcery_alloc(ast_sip_get_sorcery(), CONTACT_STATUS,
172                 ast_sorcery_object_get_id(status));
173         if (!update) {
174                 ast_log(LOG_ERROR, "Unable to allocate ast_sip_contact_status for contact %s\n",
175                         contact->uri);
176                 return;
177         }
178
179         ast_string_field_set(update, uri, contact->uri);
180         update->last_status = status->status;
181         update->status = value;
182
183         /* if the contact is available calculate the rtt as
184            the diff between the last start time and "now" */
185         update->rtt = update->status == AVAILABLE && status->rtt_start.tv_sec > 0 ?
186                 ast_tvdiff_us(ast_tvnow(), status->rtt_start) : 0;
187         update->rtt_start = ast_tv(0, 0);
188
189         ast_test_suite_event_notify("AOR_CONTACT_QUALIFY_RESULT",
190                 "Contact: %s\r\n"
191                 "Status: %s\r\n"
192                 "RTT: %" PRId64,
193                 ast_sorcery_object_get_id(update),
194                 ast_sip_get_contact_status_label(update->status),
195                 update->rtt);
196
197         if (ast_sorcery_update(ast_sip_get_sorcery(), update)) {
198                 ast_log(LOG_ERROR, "Unable to update ast_sip_contact_status for contact %s\n",
199                         contact->uri);
200         }
201 }
202
203 /*!
204  * \internal
205  * \brief Initialize the start time on a contact status so the round
206  *        trip time can be calculated upon a valid response.
207  */
208 static void init_start_time(const struct ast_sip_contact *contact)
209 {
210         RAII_VAR(struct ast_sip_contact_status *, status, NULL, ao2_cleanup);
211         RAII_VAR(struct ast_sip_contact_status *, update, NULL, ao2_cleanup);
212
213         status = ast_res_pjsip_find_or_create_contact_status(contact);
214         if (!status) {
215                 ast_log(LOG_ERROR, "Unable to find ast_sip_contact_status for contact %s\n",
216                         contact->uri);
217                 return;
218         }
219
220         update = ast_sorcery_alloc(ast_sip_get_sorcery(), CONTACT_STATUS,
221                 ast_sorcery_object_get_id(status));
222         if (!update) {
223                 ast_log(LOG_ERROR, "Unable to copy ast_sip_contact_status for contact %s\n",
224                         contact->uri);
225                 return;
226         }
227
228         ast_string_field_set(status, uri, contact->uri);
229         update->status = status->status;
230         update->last_status = status->last_status;
231         update->rtt = status->rtt;
232         update->rtt_start = ast_tvnow();
233
234         if (ast_sorcery_update(ast_sip_get_sorcery(), update)) {
235                 ast_log(LOG_ERROR, "Unable to update ast_sip_contact_status for contact %s\n",
236                         contact->uri);
237         }
238 }
239
240 /*!
241  * \internal
242  * \brief For an endpoint try to match the given contact->aor.
243  */
244 static int on_endpoint(void *obj, void *arg, int flags)
245 {
246         struct ast_sip_endpoint *endpoint = obj;
247         char *contact_aor = arg;
248         char *aor_name;
249         char *aors;
250
251         if (!arg || ast_strlen_zero(endpoint->aors)) {
252                 return 0;
253         }
254
255         aors = ast_strdupa(endpoint->aors);
256         while ((aor_name = ast_strip(strsep(&aors, ",")))) {
257                 if (!strcmp(contact_aor, aor_name)) {
258                         return CMP_MATCH;
259                 }
260         }
261
262         return 0;
263 }
264
265 /*!
266  * \internal
267  * \brief Find an endpoint associated with the given contact.
268  */
269 static struct ast_sip_endpoint *find_an_endpoint(struct ast_sip_contact *contact)
270 {
271         struct ao2_container *endpoints;
272         struct ast_sip_endpoint *endpoint;
273         struct ast_variable *var;
274         char *aor = ast_alloca(strlen(contact->aor) + 3);
275
276         sprintf(aor, "%%%s%%", contact->aor);
277         var = ast_variable_new("aors LIKE", aor, "");
278         endpoints = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(),
279                 "endpoint", AST_RETRIEVE_FLAG_MULTIPLE, var);
280
281         ast_variables_destroy(var);
282
283         /*
284          * Because aors are a string list, we have to use a pattern match but since a simple
285          * pattern match could return an endpoint that has an aor of "aaabccc" when searching
286          * for "abc", we still have to iterate over them to find an exact aor match.
287          */
288         endpoint = ao2_callback(endpoints, 0, on_endpoint, (char *)contact->aor);
289         ao2_ref(endpoints, -1);
290
291         return endpoint;
292 }
293
294 /*!
295  * \internal
296  * \brief Receive a response to the qualify contact request.
297  */
298 static void qualify_contact_cb(void *token, pjsip_event *e)
299 {
300         struct ast_sip_contact *contact = token;
301
302         switch(e->body.tsx_state.type) {
303         default:
304                 ast_log(LOG_ERROR, "Unexpected PJSIP event %u\n", e->body.tsx_state.type);
305                 /* Fall through */
306         case PJSIP_EVENT_TRANSPORT_ERROR:
307         case PJSIP_EVENT_TIMER:
308                 update_contact_status(contact, UNAVAILABLE);
309                 break;
310         case PJSIP_EVENT_RX_MSG:
311                 update_contact_status(contact, AVAILABLE);
312                 break;
313         }
314         ao2_cleanup(contact);
315 }
316
317 /*!
318  * \internal
319  * \brief Attempt to qualify the contact
320  *
321  * \details Sends a SIP OPTIONS request to the given contact in order to make
322  *         sure that contact is available.
323  */
324 static int qualify_contact(struct ast_sip_endpoint *endpoint, struct ast_sip_contact *contact)
325 {
326         pjsip_tx_data *tdata;
327         RAII_VAR(struct ast_sip_endpoint *, endpoint_local, NULL, ao2_cleanup);
328
329         if (endpoint) {
330                 endpoint_local = ao2_bump(endpoint);
331         } else {
332                 endpoint_local = find_an_endpoint(contact);
333                 if (!endpoint_local) {
334                         ast_log(LOG_ERROR, "Unable to find an endpoint to qualify contact %s\n",
335                                 contact->uri);
336                         return -1;
337                 }
338         }
339
340         if (ast_sip_create_request("OPTIONS", NULL, endpoint_local, NULL, contact, &tdata)) {
341                 ast_log(LOG_ERROR, "Unable to create request to qualify contact %s\n",
342                         contact->uri);
343                 return -1;
344         }
345
346         /* If an outbound proxy is specified set it on this request */
347         if (!ast_strlen_zero(contact->outbound_proxy) &&
348                 ast_sip_set_outbound_proxy(tdata, contact->outbound_proxy)) {
349                 pjsip_tx_data_dec_ref(tdata);
350                 ast_log(LOG_ERROR, "Unable to apply outbound proxy on request to qualify contact %s\n",
351                         contact->uri);
352                 return -1;
353         }
354
355         init_start_time(contact);
356
357         ao2_ref(contact, +1);
358         if (ast_sip_send_out_of_dialog_request(tdata, endpoint_local, (int)(contact->qualify_timeout * 1000), contact, qualify_contact_cb)
359                 != PJ_SUCCESS) {
360                 ast_log(LOG_ERROR, "Unable to send request to qualify contact %s\n",
361                         contact->uri);
362                 update_contact_status(contact, UNAVAILABLE);
363                 ao2_ref(contact, -1);
364                 return -1;
365         }
366
367         return 0;
368 }
369
370 /*!
371  * \internal
372  * \brief Scheduling context for sending QUALIFY request at specified intervals.
373  */
374 static struct ast_sched_context *sched;
375
376 /*!
377  * \internal
378  * \brief Container to hold all actively scheduled qualifies.
379  */
380 static struct ao2_container *sched_qualifies;
381
382 /*!
383  * \internal
384  * \brief Structure to hold qualify contact scheduling information.
385  */
386 struct sched_data {
387         /*! The scheduling id */
388         int id;
389         /*! The the contact being checked */
390         struct ast_sip_contact *contact;
391 };
392
393 /*!
394  * \internal
395  * \brief Destroy the scheduled data and remove from scheduler.
396  */
397 static void sched_data_destructor(void *obj)
398 {
399         struct sched_data *data = obj;
400
401         ao2_cleanup(data->contact);
402 }
403 /*!
404  * \internal
405  * \brief Create the scheduling data object.
406  */
407 static struct sched_data *sched_data_create(struct ast_sip_contact *contact)
408 {
409         struct sched_data *data;
410
411         data = ao2_t_alloc(sizeof(*data), sched_data_destructor, contact->uri);
412         if (!data) {
413                 ast_log(LOG_ERROR, "Unable to create schedule qualify data for contact %s\n",
414                         contact->uri);
415                 return NULL;
416         }
417
418         data->contact = contact;
419         ao2_ref(data->contact, +1);
420
421         return data;
422 }
423
424 /*!
425  * \internal
426  * \brief Send a qualify contact request within a threaded task.
427  */
428 static int qualify_contact_task(void *obj)
429 {
430         struct ast_sip_contact *contact = obj;
431         int res;
432
433         res = qualify_contact(NULL, contact);
434         ao2_ref(contact, -1);
435         return res;
436 }
437
438 /*!
439  * \internal
440  * \brief Send a scheduled qualify contact request.
441  */
442 static int qualify_contact_sched(const void *obj)
443 {
444         struct sched_data *data = (struct sched_data *) obj;
445
446         ao2_ref(data->contact, +1);
447         if (ast_sip_push_task(NULL, qualify_contact_task, data->contact)) {
448                 ao2_ref(data->contact, -1);
449         }
450
451         /*
452          * Always reschedule rather than have a potential race cleaning
453          * up the data object ref between self deletion and an external
454          * deletion.
455          */
456         return data->contact->qualify_frequency * 1000;
457 }
458
459 /*!
460  * \internal
461  * \brief Set up a scheduled qualify contact check.
462  */
463 static void schedule_qualify(struct ast_sip_contact *contact, int initial_interval)
464 {
465         struct sched_data *data;
466
467         data = sched_data_create(contact);
468         if (!data) {
469                 return;
470         }
471
472         ast_assert(contact->qualify_frequency != 0);
473
474         ao2_t_ref(data, +1, "Ref for qualify_contact_sched() scheduler entry");
475         data->id = ast_sched_add_variable(sched, initial_interval,
476                 qualify_contact_sched, data, 1);
477         if (data->id < 0) {
478                 ao2_t_ref(data, -1, "Cleanup failed scheduler add");
479                 ast_log(LOG_ERROR, "Unable to schedule qualify for contact %s\n",
480                         contact->uri);
481         } else if (!ao2_link(sched_qualifies, data)) {
482                 AST_SCHED_DEL_UNREF(sched, data->id,
483                         ao2_t_ref(data, -1, "Cleanup scheduler for failed ao2_link"));
484         }
485         ao2_t_ref(data, -1, "Done setting up scheduler entry");
486 }
487
488 /*!
489  * \internal
490  * \brief Remove the contact from the scheduler.
491  */
492 static void unschedule_qualify(struct ast_sip_contact *contact)
493 {
494         struct sched_data *data;
495
496         data = ao2_find(sched_qualifies, contact, OBJ_UNLINK | OBJ_SEARCH_KEY);
497         if (!data) {
498                 return;
499         }
500
501         AST_SCHED_DEL_UNREF(sched, data->id,
502                 ao2_t_ref(data, -1, "Delete scheduler entry ref"));
503         ao2_t_ref(data, -1, "Done with ao2_find ref");
504 }
505
506 /*!
507  * \internal
508  * \brief Qualify the given contact and set up scheduling if configured.
509  */
510 static void qualify_and_schedule(struct ast_sip_contact *contact)
511 {
512         unschedule_qualify(contact);
513
514         if (contact->qualify_frequency) {
515                 ao2_ref(contact, +1);
516                 if (ast_sip_push_task(NULL, qualify_contact_task, contact)) {
517                         ao2_ref(contact, -1);
518                 }
519
520                 schedule_qualify(contact, contact->qualify_frequency * 1000);
521         } else {
522                 update_contact_status(contact, UNKNOWN);
523         }
524 }
525
526 /*!
527  * \internal
528  * \brief A new contact has been created make sure it is available.
529  */
530 static void contact_created(const void *obj)
531 {
532         qualify_and_schedule((struct ast_sip_contact *) obj);
533 }
534
535 /*!
536  * \internal
537  * \brief A contact has been updated.
538  */
539 static void contact_updated(const void *obj)
540 {
541         update_contact_status((struct ast_sip_contact *) obj, UPDATED);
542         qualify_and_schedule((struct ast_sip_contact *) obj);
543 }
544
545 /*!
546  * \internal
547  * \brief A contact has been deleted remove status tracking.
548  */
549 static void contact_deleted(const void *obj)
550 {
551         struct ast_sip_contact *contact = (struct ast_sip_contact *) obj;
552         struct ast_sip_contact_status *status;
553
554         unschedule_qualify(contact);
555
556         status = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), CONTACT_STATUS,
557                 ast_sorcery_object_get_id(contact));
558         if (!status) {
559                 return;
560         }
561
562         if (ast_sorcery_delete(ast_sip_get_sorcery(), status)) {
563                 ast_log(LOG_ERROR, "Unable to delete ast_sip_contact_status for contact %s\n",
564                         contact->uri);
565         }
566         ao2_ref(status, -1);
567 }
568
569 static const struct ast_sorcery_observer contact_observer = {
570         .created = contact_created,
571         .deleted = contact_deleted,
572         .updated = contact_updated
573 };
574
575 static pj_bool_t options_start(void)
576 {
577         sched = ast_sched_context_create();
578         if (!sched) {
579                 return -1;
580         }
581         if (ast_sched_start_thread(sched)) {
582                 ast_sched_context_destroy(sched);
583                 sched = NULL;
584                 return -1;
585         }
586
587         if (ast_sorcery_observer_add(ast_sip_get_sorcery(), "contact", &contact_observer)) {
588                 ast_log(LOG_WARNING, "Unable to add contact observer\n");
589                 ast_sched_context_destroy(sched);
590                 sched = NULL;
591                 return -1;
592         }
593
594         return PJ_SUCCESS;
595 }
596
597 static int sched_qualifies_empty(void *obj, void *arg, int flags)
598 {
599         ao2_t_ref(obj, -1, "Release ref held by destroyed scheduler context.");
600         return CMP_MATCH;
601 }
602
603 static pj_bool_t options_stop(void)
604 {
605         ast_sorcery_observer_remove(ast_sip_get_sorcery(), "contact", &contact_observer);
606
607         if (sched) {
608                 ast_sched_context_destroy(sched);
609                 sched = NULL;
610         }
611
612         /* Empty the container of scheduling data refs. */
613         ao2_callback(sched_qualifies, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE,
614                 sched_qualifies_empty, NULL);
615
616         return PJ_SUCCESS;
617 }
618
619 static pj_status_t send_options_response(pjsip_rx_data *rdata, int code)
620 {
621         pjsip_endpoint *endpt = ast_sip_get_pjsip_endpoint();
622         pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata);
623         pjsip_transaction *trans = pjsip_rdata_get_tsx(rdata);
624         pjsip_tx_data *tdata;
625         const pjsip_hdr *hdr;
626         pj_status_t status;
627
628         /* Make the response object */
629         if ((status = ast_sip_create_response(rdata, code, NULL, &tdata) != PJ_SUCCESS)) {
630                 ast_log(LOG_ERROR, "Unable to create response (%d)\n", status);
631                 return status;
632         }
633
634         /* Add appropriate headers */
635         if ((hdr = pjsip_endpt_get_capability(endpt, PJSIP_H_ACCEPT, NULL))) {
636                 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)pjsip_hdr_clone(tdata->pool, hdr));
637         }
638         if ((hdr = pjsip_endpt_get_capability(endpt, PJSIP_H_ALLOW, NULL))) {
639                 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)pjsip_hdr_clone(tdata->pool, hdr));
640         }
641         if ((hdr = pjsip_endpt_get_capability(endpt, PJSIP_H_SUPPORTED, NULL))) {
642                 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)pjsip_hdr_clone(tdata->pool, hdr));
643         }
644
645         /*
646          * XXX TODO: pjsip doesn't care a lot about either of these headers -
647          * while it provides specific methods to create them, they are defined
648          * to be the standard string header creation. We never did add them
649          * in chan_sip, although RFC 3261 says they SHOULD. Hard coded here.
650          */
651         ast_sip_add_header(tdata, "Accept-Encoding", DEFAULT_ENCODING);
652         ast_sip_add_header(tdata, "Accept-Language", DEFAULT_LANGUAGE);
653
654         if (dlg && trans) {
655                 status = pjsip_dlg_send_response(dlg, trans, tdata);
656         } else {
657                 struct ast_sip_endpoint *endpoint;
658
659                 endpoint = ast_pjsip_rdata_get_endpoint(rdata);
660                 status = ast_sip_send_stateful_response(rdata, tdata, endpoint);
661                 ao2_cleanup(endpoint);
662         }
663
664         if (status != PJ_SUCCESS) {
665                 ast_log(LOG_ERROR, "Unable to send response (%d)\n", status);
666         }
667
668         return status;
669 }
670
671 static pj_bool_t options_on_rx_request(pjsip_rx_data *rdata)
672 {
673         RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
674         pjsip_uri *ruri;
675         pjsip_sip_uri *sip_ruri;
676         char exten[AST_MAX_EXTENSION];
677
678         if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method,
679                              &pjsip_options_method)) {
680                 return PJ_FALSE;
681         }
682
683         if (!(endpoint = ast_pjsip_rdata_get_endpoint(rdata))) {
684                 return PJ_FALSE;
685         }
686
687         ruri = rdata->msg_info.msg->line.req.uri;
688         if (!PJSIP_URI_SCHEME_IS_SIP(ruri) && !PJSIP_URI_SCHEME_IS_SIPS(ruri)) {
689                 send_options_response(rdata, 416);
690                 return PJ_TRUE;
691         }
692
693         sip_ruri = pjsip_uri_get_uri(ruri);
694         ast_copy_pj_str(exten, &sip_ruri->user, sizeof(exten));
695
696         if (ast_shutting_down()) {
697                 /*
698                  * Not taking any new calls at this time.
699                  * Likely a server availability OPTIONS poll.
700                  */
701                 send_options_response(rdata, 503);
702         } else if (!ast_strlen_zero(exten) && !ast_exists_extension(NULL, endpoint->context, exten, 1, NULL)) {
703                 send_options_response(rdata, 404);
704         } else {
705                 send_options_response(rdata, 200);
706         }
707         return PJ_TRUE;
708 }
709
710 static pjsip_module options_module = {
711         .name = {"Options Module", 14},
712         .id = -1,
713         .priority = PJSIP_MOD_PRIORITY_APPLICATION,
714         .start = options_start,
715         .stop = options_stop,
716         .on_rx_request = options_on_rx_request,
717 };
718
719 /*!
720  * \internal
721  * \brief Send qualify request to the given contact.
722  */
723 static int cli_on_contact(void *obj, void *arg, void *data, int flags)
724 {
725         struct ast_sip_contact *contact = obj;
726         struct ast_sip_endpoint *endpoint = data;
727         int *cli_fd = arg;
728
729         ast_cli(*cli_fd, " contact %s\n", contact->uri);
730         qualify_contact(endpoint, contact);
731         return 0;
732 }
733
734 /*!
735  * \brief Data pushed to threadpool to qualify endpoints from the CLI
736  */
737 struct qualify_data {
738         /*! Endpoint that is being qualified */
739         struct ast_sip_endpoint *endpoint;
740         /*! CLI File descriptor for printing messages */
741         int cli_fd;
742 };
743
744 static struct qualify_data *qualify_data_alloc(struct ast_sip_endpoint *endpoint, int cli_fd)
745 {
746         struct qualify_data *qual_data;
747
748         qual_data = ast_malloc(sizeof(*qual_data));
749         if (!qual_data) {
750                 return NULL;
751         }
752
753         qual_data->endpoint = ao2_bump(endpoint);
754         qual_data->cli_fd = cli_fd;
755         return qual_data;
756 }
757
758 static void qualify_data_destroy(struct qualify_data *qual_data)
759 {
760         ao2_cleanup(qual_data->endpoint);
761         ast_free(qual_data);
762 }
763
764 /*!
765  * \internal
766  * \brief For an endpoint iterate over and qualify all aors/contacts
767  */
768 static int cli_qualify_contacts(void *data)
769 {
770         char *aors;
771         char *aor_name;
772         RAII_VAR(struct qualify_data *, qual_data, data, qualify_data_destroy);
773         struct ast_sip_endpoint *endpoint = qual_data->endpoint;
774         int cli_fd = qual_data->cli_fd;
775         const char *endpoint_name = ast_sorcery_object_get_id(endpoint);
776
777         if (ast_strlen_zero(endpoint->aors)) {
778                 ast_cli(cli_fd, "Endpoint %s has no AoR's configured\n",
779                         endpoint_name);
780                 return 0;
781         }
782
783         aors = ast_strdupa(endpoint->aors);
784         while ((aor_name = ast_strip(strsep(&aors, ",")))) {
785                 struct ast_sip_aor *aor;
786                 struct ao2_container *contacts;
787
788                 aor = ast_sip_location_retrieve_aor(aor_name);
789                 if (!aor) {
790                         continue;
791                 }
792
793                 contacts = ast_sip_location_retrieve_aor_contacts(aor);
794                 if (contacts) {
795                         ast_cli(cli_fd, "Sending qualify to endpoint %s\n", endpoint_name);
796                         ao2_callback_data(contacts, OBJ_NODATA, cli_on_contact, &cli_fd, endpoint);
797                         ao2_ref(contacts, -1);
798                 }
799
800                 ao2_ref(aor, -1);
801         }
802         return 0;
803 }
804
805 static char *cli_qualify(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
806 {
807         RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
808         const char *endpoint_name;
809         struct qualify_data *qual_data;
810
811         switch (cmd) {
812         case CLI_INIT:
813                 e->command = "pjsip qualify";
814                 e->usage =
815                         "Usage: pjsip qualify <endpoint>\n"
816                         "       Send a SIP OPTIONS request to all contacts on the endpoint.\n";
817                 return NULL;
818         case CLI_GENERATE:
819                 return NULL;
820         }
821
822         if (a->argc != 3) {
823                 return CLI_SHOWUSAGE;
824         }
825
826         endpoint_name = a->argv[2];
827
828         if (!(endpoint = ast_sorcery_retrieve_by_id(
829                       ast_sip_get_sorcery(), "endpoint", endpoint_name))) {
830                 ast_cli(a->fd, "Unable to retrieve endpoint %s\n", endpoint_name);
831                 return CLI_FAILURE;
832         }
833
834         qual_data = qualify_data_alloc(endpoint, a->fd);
835         if (!qual_data) {
836                 return CLI_FAILURE;
837         }
838
839         if (ast_sip_push_task(NULL, cli_qualify_contacts, qual_data)) {
840                 qualify_data_destroy(qual_data);
841                 return CLI_FAILURE;
842         }
843
844         return CLI_SUCCESS;
845 }
846
847 /*!
848  * \internal
849  * \brief Send qualify request to the given contact.
850  */
851 static int ami_contact_cb(void *obj, void *arg, int flags)
852 {
853         struct ast_sip_contact *contact = obj;
854
855         ao2_ref(contact, +1);
856         if (ast_sip_push_task(NULL, qualify_contact_task, contact)) {
857                 ao2_ref(contact, -1);
858         }
859         return 0;
860 }
861
862 static int ami_sip_qualify(struct mansession *s, const struct message *m)
863 {
864         const char *endpoint_name = astman_get_header(m, "Endpoint");
865         RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
866         char *aors;
867         char *aor_name;
868
869         if (ast_strlen_zero(endpoint_name)) {
870                 astman_send_error(s, m, "Endpoint parameter missing.");
871                 return 0;
872         }
873
874         endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint",
875                 endpoint_name);
876         if (!endpoint) {
877                 astman_send_error(s, m, "Unable to retrieve endpoint\n");
878                 return 0;
879         }
880
881         /* send a qualify for all contacts registered with the endpoint */
882         if (ast_strlen_zero(endpoint->aors)) {
883                 astman_send_error(s, m, "No AoRs configured for endpoint\n");
884                 return 0;
885         }
886
887         aors = ast_strdupa(endpoint->aors);
888         while ((aor_name = ast_strip(strsep(&aors, ",")))) {
889                 struct ast_sip_aor *aor;
890                 struct ao2_container *contacts;
891
892                 aor = ast_sip_location_retrieve_aor(aor_name);
893                 if (!aor) {
894                         continue;
895                 }
896
897                 contacts = ast_sip_location_retrieve_aor_contacts(aor);
898                 if (contacts) {
899                         ao2_callback(contacts, OBJ_NODATA, ami_contact_cb, NULL);
900                         ao2_ref(contacts, -1);
901                 }
902
903                 ao2_ref(aor, -1);
904         }
905
906         astman_send_ack(s, m, "Endpoint found, will qualify");
907         return 0;
908 }
909
910 static struct ast_cli_entry cli_options[] = {
911         AST_CLI_DEFINE(cli_qualify, "Send an OPTIONS request to a PJSIP endpoint")
912 };
913
914 static int sched_qualifies_hash_fn(const void *obj, int flags)
915 {
916         const struct sched_data *object;
917         const struct ast_sip_contact *key;
918
919         switch (flags & OBJ_SEARCH_MASK) {
920         case OBJ_SEARCH_KEY:
921                 key = obj;
922                 break;
923         case OBJ_SEARCH_OBJECT:
924                 object = obj;
925                 key = object->contact;
926                 break;
927         default:
928                 /* Hash can only work on something with a full key. */
929                 ast_assert(0);
930                 return 0;
931         }
932         return ast_str_hash(ast_sorcery_object_get_id(key));
933 }
934
935 static int sched_qualifies_cmp_fn(void *obj, void *arg, int flags)
936 {
937         const struct sched_data *object_left = obj;
938         const struct sched_data *object_right = arg;
939         struct ast_sip_contact *right_key = arg;
940         int cmp;
941
942         switch (flags & OBJ_SEARCH_MASK) {
943         case OBJ_SEARCH_OBJECT:
944                 right_key = object_right->contact;
945                 /* Fall through */
946         case OBJ_SEARCH_KEY:
947                 cmp = strcmp(ast_sorcery_object_get_id(object_left->contact),
948                         ast_sorcery_object_get_id(right_key));
949                 break;
950         case OBJ_SEARCH_PARTIAL_KEY:
951                 /* Not supported by container. */
952                 ast_assert(0);
953                 return 0;
954         default:
955                 /*
956                  * What arg points to is specific to this traversal callback
957                  * and has no special meaning to astobj2.
958                  */
959                 cmp = 0;
960                 break;
961         }
962         if (cmp) {
963                 return 0;
964         }
965         /*
966          * At this point the traversal callback is identical to a sorted
967          * container.
968          */
969         return CMP_MATCH;
970 }
971
972 static int rtt_start_handler(const struct aco_option *opt,
973         struct ast_variable *var, void *obj)
974 {
975         struct ast_sip_contact_status *status = obj;
976         long int sec, usec;
977
978         if (sscanf(var->value, "%ld.%06ld", &sec, &usec) != 2) {
979                 return -1;
980         }
981
982         status->rtt_start = ast_tv(sec, usec);
983
984         return 0;
985 }
986
987 static int rtt_start_to_str(const void *obj, const intptr_t *args, char **buf)
988 {
989         const struct ast_sip_contact_status *status = obj;
990
991         if (ast_asprintf(buf, "%ld.%06ld", (long)status->rtt_start.tv_sec, (long)status->rtt_start.tv_usec) == -1) {
992                 return -1;
993         }
994
995         return 0;
996 }
997
998 static char status_value_unknown[2];
999 static char status_value_created[2];
1000
1001 int ast_sip_initialize_sorcery_qualify(void)
1002 {
1003         struct ast_sorcery *sorcery = ast_sip_get_sorcery();
1004
1005         /* initialize sorcery ast_sip_contact_status resource */
1006         ast_sorcery_apply_default(sorcery, CONTACT_STATUS, "memory", NULL);
1007
1008         if (ast_sorcery_internal_object_register(sorcery, CONTACT_STATUS,
1009                                         contact_status_alloc, NULL, NULL)) {
1010                 ast_log(LOG_ERROR, "Unable to register ast_sip_contact_status in sorcery\n");
1011                 return -1;
1012         }
1013
1014         snprintf(status_value_unknown, sizeof(status_value_unknown), "%u", UNKNOWN);
1015         ast_sorcery_object_field_register_nodoc(sorcery, CONTACT_STATUS, "last_status",
1016                 status_value_unknown, OPT_UINT_T, 0, FLDSET(struct ast_sip_contact_status, last_status));
1017         snprintf(status_value_created, sizeof(status_value_created), "%u", CREATED);
1018         ast_sorcery_object_field_register_nodoc(sorcery, CONTACT_STATUS, "status",
1019                 status_value_created, OPT_UINT_T, 0, FLDSET(struct ast_sip_contact_status, status));
1020         ast_sorcery_object_field_register_custom_nodoc(sorcery, CONTACT_STATUS, "rtt_start",
1021                 "0.0", rtt_start_handler, rtt_start_to_str, NULL, 0, 0);
1022         ast_sorcery_object_field_register_nodoc(sorcery, CONTACT_STATUS, "rtt",
1023                 "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_contact_status, rtt));
1024
1025         return 0;
1026 }
1027
1028 static void qualify_and_schedule_contact(struct ast_sip_contact *contact)
1029 {
1030         int initial_interval;
1031         int max_time = ast_sip_get_max_initial_qualify_time();
1032
1033         /* Delay initial qualification by a random fraction of the specified interval */
1034         if (max_time && max_time < contact->qualify_frequency) {
1035                 initial_interval = max_time;
1036         } else {
1037                 initial_interval = contact->qualify_frequency;
1038         }
1039
1040         initial_interval = (int)((initial_interval * 1000) * ast_random_double());
1041
1042         unschedule_qualify(contact);
1043         if (contact->qualify_frequency) {
1044                 schedule_qualify(contact, initial_interval);
1045         } else {
1046                 update_contact_status(contact, UNKNOWN);
1047         }
1048 }
1049
1050 static int qualify_and_schedule_cb_with_aor(void *obj, void *arg, int flags)
1051 {
1052         struct ast_sip_contact *contact = obj;
1053         struct ast_sip_aor *aor = arg;
1054
1055         contact->qualify_frequency = aor->qualify_frequency;
1056         contact->qualify_timeout = aor->qualify_timeout;
1057         contact->authenticate_qualify = aor->authenticate_qualify;
1058
1059         qualify_and_schedule_contact(contact);
1060
1061         return 0;
1062 }
1063
1064 static int qualify_and_schedule_cb_without_aor(void *obj, void *arg, int flags)
1065 {
1066         qualify_and_schedule_contact((struct ast_sip_contact *) obj);
1067
1068         return 0;
1069 }
1070
1071 /*!
1072  * \internal
1073  * \brief Qualify and schedule an aor's contacts
1074  *
1075  * \details For the given aor check if it has permanent contacts,
1076  *         qualify all contacts and schedule for checks if configured.
1077  */
1078 static int qualify_and_schedule_all_cb(void *obj, void *arg, int flags)
1079 {
1080         struct ast_sip_aor *aor = obj;
1081         struct ao2_container *contacts;
1082
1083         if (aor->permanent_contacts) {
1084                 contacts = ast_sip_location_retrieve_aor_contacts(aor);
1085                 if (contacts) {
1086                         ao2_callback(contacts, OBJ_NODATA, qualify_and_schedule_cb_with_aor, aor);
1087                         ao2_ref(contacts, -1);
1088                 }
1089         }
1090
1091         return 0;
1092 }
1093
1094 /*!
1095  * \internal
1096  * \brief Unschedule all existing contacts
1097  */
1098 static int unschedule_all_cb(void *obj, void *arg, int flags)
1099 {
1100         struct sched_data *data = obj;
1101
1102         AST_SCHED_DEL_UNREF(sched, data->id, ao2_ref(data, -1));
1103
1104         return CMP_MATCH;
1105 }
1106
1107 static void qualify_and_schedule_all(void)
1108 {
1109         struct ast_variable *var = ast_variable_new("qualify_frequency >", "0", "");
1110         struct ao2_container *aors;
1111         struct ao2_container *contacts;
1112
1113         if (!var) {
1114                 return;
1115         }
1116         aors = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(),
1117                 "aor", AST_RETRIEVE_FLAG_MULTIPLE, var);
1118
1119         ao2_callback(sched_qualifies, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK, unschedule_all_cb, NULL);
1120
1121         if (aors) {
1122                 ao2_callback(aors, OBJ_NODATA, qualify_and_schedule_all_cb, NULL);
1123                 ao2_ref(aors, -1);
1124         }
1125
1126         contacts = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(),
1127                 "contact", AST_RETRIEVE_FLAG_MULTIPLE, var);
1128         if (contacts) {
1129                 ao2_callback(contacts, OBJ_NODATA, qualify_and_schedule_cb_without_aor, NULL);
1130                 ao2_ref(contacts, -1);
1131         }
1132
1133         ast_variables_destroy(var);
1134
1135 }
1136
1137 static int format_contact_status(void *obj, void *arg, int flags)
1138 {
1139         struct ast_sip_contact_wrapper *wrapper = obj;
1140         struct ast_sip_contact *contact = wrapper->contact;
1141         struct ast_sip_ami *ami = arg;
1142         struct ast_sip_contact_status *status;
1143         struct ast_str *buf;
1144         const struct ast_sip_endpoint *endpoint = ami->arg;
1145
1146         buf = ast_sip_create_ami_event("ContactStatusDetail", ami);
1147         if (!buf) {
1148                 return -1;
1149         }
1150
1151         status = ast_sorcery_retrieve_by_id(
1152                 ast_sip_get_sorcery(), CONTACT_STATUS,
1153                 ast_sorcery_object_get_id(contact));
1154
1155         ast_str_append(&buf, 0, "AOR: %s\r\n", wrapper->aor_id);
1156         ast_str_append(&buf, 0, "URI: %s\r\n", contact->uri);
1157         ast_str_append(&buf, 0, "UserAgent: %s\r\n", contact->user_agent);
1158         ast_str_append(&buf, 0, "RegExpire: %ld\r\n", contact->expiration_time.tv_sec);
1159         ast_str_append(&buf, 0, "Status: %s\r\n", ast_sip_get_contact_status_label(status->status));
1160         if (status->status == UNKNOWN) {
1161                 ast_str_append(&buf, 0, "RoundtripUsec: N/A\r\n");
1162         } else {
1163                 ast_str_append(&buf, 0, "RoundtripUsec: %" PRId64 "\r\n", status->rtt);
1164         }
1165         ast_str_append(&buf, 0, "EndpointName: %s\r\n",
1166                         ast_sorcery_object_get_id(endpoint));
1167         astman_append(ami->s, "%s\r\n", ast_str_buffer(buf));
1168         ami->count++;
1169         
1170         ast_free(buf);
1171         ao2_cleanup(status);
1172         return 0;
1173 }
1174
1175 static int format_contact_status_for_aor(void *obj, void *arg, int flags)
1176 {
1177         struct ast_sip_aor *aor = obj;
1178
1179         return ast_sip_for_each_contact(aor, format_contact_status, arg);
1180 }
1181
1182 static int format_ami_contact_status(const struct ast_sip_endpoint *endpoint,
1183                 struct ast_sip_ami *ami)
1184 {
1185         ami->arg = (void *)endpoint;
1186         return ast_sip_for_each_aor(endpoint->aors, format_contact_status_for_aor, ami);
1187 }
1188
1189 static struct ast_sip_endpoint_formatter contact_status_formatter = {
1190         .format_ami = format_ami_contact_status
1191 };
1192
1193 static void aor_observer_modified(const void *obj)
1194 {
1195         struct ast_sip_aor *aor = (void *)obj;
1196         struct ao2_container *contacts;
1197
1198         contacts = ast_sip_location_retrieve_aor_contacts(aor);
1199         if (contacts) {
1200                 ao2_callback(contacts, OBJ_NODATA, qualify_and_schedule_cb_with_aor, aor);
1201                 ao2_ref(contacts, -1);
1202         }
1203 }
1204
1205 static int unschedule_contact_cb(void *obj, void *arg, int flags)
1206 {
1207         unschedule_qualify(obj);
1208
1209         return CMP_MATCH;
1210 }
1211
1212 static void aor_observer_deleted(const void *obj)
1213 {
1214         const struct ast_sip_aor *aor = obj;
1215         struct ao2_container *contacts;
1216
1217         contacts = ast_sip_location_retrieve_aor_contacts(aor);
1218         if (contacts) {
1219                 ao2_callback(contacts, OBJ_NODATA, unschedule_contact_cb, NULL);
1220                 ao2_ref(contacts, -1);
1221         }
1222 }
1223
1224 static const struct ast_sorcery_observer observer_callbacks_options = {
1225         .created = aor_observer_modified,
1226         .updated = aor_observer_modified,
1227         .deleted = aor_observer_deleted
1228 };
1229
1230 int ast_res_pjsip_init_options_handling(int reload)
1231 {
1232         static const pj_str_t STR_OPTIONS = { "OPTIONS", 7 };
1233
1234         if (reload) {
1235                 qualify_and_schedule_all();
1236                 return 0;
1237         }
1238
1239         sched_qualifies = ao2_t_container_alloc(QUALIFIED_BUCKETS,
1240                 sched_qualifies_hash_fn, sched_qualifies_cmp_fn,
1241                 "Create container for scheduled qualifies");
1242         if (!sched_qualifies) {
1243                 return -1;
1244         }
1245
1246         if (pjsip_endpt_register_module(ast_sip_get_pjsip_endpoint(), &options_module) != PJ_SUCCESS) {
1247                 ao2_cleanup(sched_qualifies);
1248                 sched_qualifies = NULL;
1249                 return -1;
1250         }
1251
1252         if (pjsip_endpt_add_capability(ast_sip_get_pjsip_endpoint(), NULL, PJSIP_H_ALLOW,
1253                 NULL, 1, &STR_OPTIONS) != PJ_SUCCESS) {
1254                 pjsip_endpt_unregister_module(ast_sip_get_pjsip_endpoint(), &options_module);
1255                 ao2_cleanup(sched_qualifies);
1256                 sched_qualifies = NULL;
1257                 return -1;
1258         }
1259
1260         if (ast_sorcery_observer_add(ast_sip_get_sorcery(), "aor", &observer_callbacks_options)) {
1261                 pjsip_endpt_unregister_module(ast_sip_get_pjsip_endpoint(), &options_module);
1262                 ao2_cleanup(sched_qualifies);
1263                 sched_qualifies = NULL;
1264                 return -1;
1265         }
1266
1267         internal_sip_register_endpoint_formatter(&contact_status_formatter);
1268         ast_manager_register_xml("PJSIPQualify", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, ami_sip_qualify);
1269         ast_cli_register_multiple(cli_options, ARRAY_LEN(cli_options));
1270
1271         qualify_and_schedule_all();
1272
1273         return 0;
1274 }
1275
1276 void ast_res_pjsip_cleanup_options_handling(void)
1277 {
1278         ast_cli_unregister_multiple(cli_options, ARRAY_LEN(cli_options));
1279         ast_manager_unregister("PJSIPQualify");
1280         internal_sip_unregister_endpoint_formatter(&contact_status_formatter);
1281
1282         ast_sorcery_observer_remove(ast_sip_get_sorcery(), "aor", &observer_callbacks_options);
1283         pjsip_endpt_unregister_module(ast_sip_get_pjsip_endpoint(), &options_module);
1284         ao2_cleanup(sched_qualifies);
1285         sched_qualifies = NULL;
1286 }