res_pjsip: Create human friendly serializer names.
[asterisk/asterisk.git] / res / res_pjsip_registrar.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * Joshua Colp <jcolp@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*** MODULEINFO
20         <depend>pjproject</depend>
21         <depend>res_pjsip</depend>
22         <support_level>core</support_level>
23  ***/
24
25 #include "asterisk.h"
26
27 #include <pjsip.h>
28 #include <pjsip_ua.h>
29
30 #include "asterisk/res_pjsip.h"
31 #include "asterisk/module.h"
32 #include "asterisk/test.h"
33 #include "asterisk/taskprocessor.h"
34 #include "asterisk/manager.h"
35 #include "res_pjsip/include/res_pjsip_private.h"
36
37 /*** DOCUMENTATION
38         <manager name="PJSIPShowRegistrationsInbound" language="en_US">
39                 <synopsis>
40                         Lists PJSIP inbound registrations.
41                 </synopsis>
42                 <syntax />
43                 <description>
44                         <para>
45                         In response <literal>InboundRegistrationDetail</literal> events showing configuration and status
46                         information are raised for each inbound registration object.  As well as <literal>AuthDetail</literal>
47                         events for each associated auth object.  Once all events are completed an
48                         <literal>InboundRegistrationDetailComplete</literal> is issued.
49                         </para>
50                 </description>
51         </manager>
52  ***/
53
54 /*! \brief Internal function which returns the expiration time for a contact */
55 static int registrar_get_expiration(const struct ast_sip_aor *aor, const pjsip_contact_hdr *contact, const pjsip_rx_data *rdata)
56 {
57         pjsip_expires_hdr *expires;
58         int expiration = aor->default_expiration;
59
60         if (contact && contact->expires != -1) {
61                 /* Expiration was provided with the contact itself */
62                 expiration = contact->expires;
63         } else if ((expires = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL))) {
64                 /* Expiration was provided using the Expires header */
65                 expiration = expires->ivalue;
66         }
67
68         /* If the value has explicitly been set to 0, do not enforce */
69         if (!expiration) {
70                 return expiration;
71         }
72
73         /* Enforce the range that we will allow for expiration */
74         if (expiration < aor->minimum_expiration) {
75                 expiration = aor->minimum_expiration;
76         } else if (expiration > aor->maximum_expiration) {
77                 expiration = aor->maximum_expiration;
78         }
79
80         return expiration;
81 }
82
83 /*! \brief Structure used for finding contact */
84 struct registrar_contact_details {
85         /*! \brief Pool used for parsing URI */
86         pj_pool_t *pool;
87         /*! \brief URI being looked for */
88         pjsip_uri *uri;
89 };
90
91 /*! \brief Callback function for finding a contact */
92 static int registrar_find_contact(void *obj, void *arg, int flags)
93 {
94         struct ast_sip_contact *contact = obj;
95         const struct registrar_contact_details *details = arg;
96         pjsip_uri *contact_uri = pjsip_parse_uri(details->pool, (char*)contact->uri, strlen(contact->uri), 0);
97
98         return (pjsip_uri_cmp(PJSIP_URI_IN_CONTACT_HDR, details->uri, contact_uri) == PJ_SUCCESS) ? CMP_MATCH | CMP_STOP : 0;
99 }
100
101 /*! \brief Internal function which validates provided Contact headers to confirm that they are acceptable, and returns number of contacts */
102 static int registrar_validate_contacts(const pjsip_rx_data *rdata, struct ao2_container *contacts, struct ast_sip_aor *aor, int *added, int *updated, int *deleted)
103 {
104         pjsip_contact_hdr *previous = NULL, *contact = (pjsip_contact_hdr *)&rdata->msg_info.msg->hdr;
105         struct registrar_contact_details details = {
106                 .pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "Contact Comparison", 256, 256),
107         };
108
109         if (!details.pool) {
110                 return -1;
111         }
112
113         while ((contact = (pjsip_contact_hdr *) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, contact->next))) {
114                 int expiration = registrar_get_expiration(aor, contact, rdata);
115                 RAII_VAR(struct ast_sip_contact *, existing, NULL, ao2_cleanup);
116
117                 if (contact->star) {
118                         /* The expiration MUST be 0 when a '*' contact is used and there must be no other contact */
119                         if ((expiration != 0) || previous) {
120                                 pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
121                                 return -1;
122                         }
123                         continue;
124                 } else if (previous && previous->star) {
125                         /* If there is a previous contact and it is a '*' this is a deal breaker */
126                         pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
127                         return -1;
128                 }
129                 previous = contact;
130
131                 if (!PJSIP_URI_SCHEME_IS_SIP(contact->uri) && !PJSIP_URI_SCHEME_IS_SIPS(contact->uri)) {
132                         continue;
133                 }
134
135                 details.uri = pjsip_uri_get_uri(contact->uri);
136
137                 /* Determine if this is an add, update, or delete for policy enforcement purposes */
138                 if (!(existing = ao2_callback(contacts, 0, registrar_find_contact, &details))) {
139                         if (expiration) {
140                                 (*added)++;
141                         }
142                 } else if (expiration) {
143                         (*updated)++;
144                 } else {
145                         (*deleted)++;
146                 }
147         }
148
149         /* The provided contacts are acceptable, huzzah! */
150         pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
151         return 0;
152 }
153
154 /*! \brief Callback function which prunes static contacts */
155 static int registrar_prune_static(void *obj, void *arg, int flags)
156 {
157         struct ast_sip_contact *contact = obj;
158
159         return ast_tvzero(contact->expiration_time) ? CMP_MATCH : 0;
160 }
161
162 /*! \brief Internal function used to delete a contact from an AOR */
163 static int registrar_delete_contact(void *obj, void *arg, int flags)
164 {
165         struct ast_sip_contact *contact = obj;
166         const char *aor_name = arg;
167
168         ast_sip_location_delete_contact(contact);
169         if (!ast_strlen_zero(aor_name)) {
170                 ast_verb(3, "Removed contact '%s' from AOR '%s' due to request\n", contact->uri, aor_name);
171                 ast_test_suite_event_notify("AOR_CONTACT_REMOVED",
172                                 "Contact: %s\r\n"
173                                 "AOR: %s\r\n"
174                                 "UserAgent: %s",
175                                 contact->uri,
176                                 aor_name,
177                                 contact->user_agent);
178         }
179
180         return 0;
181 }
182
183 /*! \brief Internal function which adds a contact to a response */
184 static int registrar_add_contact(void *obj, void *arg, int flags)
185 {
186         struct ast_sip_contact *contact = obj;
187         pjsip_tx_data *tdata = arg;
188         pjsip_contact_hdr *hdr = pjsip_contact_hdr_create(tdata->pool);
189         pj_str_t uri;
190
191         pj_strdup2_with_null(tdata->pool, &uri, contact->uri);
192         hdr->uri = pjsip_parse_uri(tdata->pool, uri.ptr, uri.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
193         hdr->expires = ast_tvdiff_ms(contact->expiration_time, ast_tvnow()) / 1000;
194
195         pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hdr);
196
197         return 0;
198 }
199
200 /*! \brief Helper function which adds a Date header to a response */
201 static void registrar_add_date_header(pjsip_tx_data *tdata)
202 {
203         char date[256];
204         struct tm tm;
205         time_t t = time(NULL);
206
207         gmtime_r(&t, &tm);
208         strftime(date, sizeof(date), "%a, %d %b %Y %T GMT", &tm);
209
210         ast_sip_add_header(tdata, "Date", date);
211 }
212
213 #define SERIALIZER_BUCKETS 59
214
215 static struct ao2_container *serializers;
216
217 /*! \brief Serializer with associated aor key */
218 struct serializer {
219         /* Serializer to distribute tasks to */
220         struct ast_taskprocessor *serializer;
221         /* The name of the aor to associate with the serializer */
222         char aor_name[0];
223 };
224
225 static void serializer_destroy(void *obj)
226 {
227         struct serializer *ser = obj;
228
229         ast_taskprocessor_unreference(ser->serializer);
230 }
231
232 static struct serializer *serializer_create(const char *aor_name)
233 {
234         char tps_name[AST_TASKPROCESSOR_MAX_NAME + 1];
235         size_t size = strlen(aor_name) + 1;
236         struct serializer *ser = ao2_alloc(
237                 sizeof(*ser) + size, serializer_destroy);
238
239         if (!ser) {
240                 return NULL;
241         }
242
243         /* Create name with seq number appended. */
244         ast_taskprocessor_build_name(tps_name, sizeof(tps_name), "pjsip/aor/%s",
245                 aor_name);
246
247         if (!(ser->serializer = ast_sip_create_serializer(tps_name))) {
248                 ao2_ref(ser, -1);
249                 return NULL;
250         }
251
252         strcpy(ser->aor_name, aor_name);
253         return ser;
254 }
255
256 static struct serializer *serializer_find_or_create(const char *aor_name)
257 {
258         struct serializer *ser = ao2_find(serializers, aor_name, OBJ_SEARCH_KEY);
259
260         if (ser) {
261                 return ser;
262         }
263
264         if (!(ser = serializer_create(aor_name))) {
265                 return NULL;
266         }
267
268         ao2_link(serializers, ser);
269         return ser;
270 }
271
272 static int serializer_hash(const void *obj, const int flags)
273 {
274         const struct serializer *object;
275         const char *key;
276
277         switch (flags & OBJ_SEARCH_MASK) {
278         case OBJ_SEARCH_KEY:
279                 key = obj;
280                 return ast_str_hash(key);
281         case OBJ_SEARCH_OBJECT:
282                 object = obj;
283                 return ast_str_hash(object->aor_name);
284         default:
285                 /* Hash can only work on something with a full key. */
286                 ast_assert(0);
287                 return 0;
288         }
289 }
290
291 static int serializer_cmp(void *obj_left, void *obj_right, int flags)
292 {
293         const struct serializer *object_left = obj_left;
294         const struct serializer *object_right = obj_right;
295         const char *right_key = obj_right;
296         int cmp;
297
298         switch (flags & OBJ_SEARCH_MASK) {
299         case OBJ_SEARCH_OBJECT:
300                 right_key = object_right->aor_name;
301                 /* Fall through */
302         case OBJ_SEARCH_KEY:
303                 cmp = strcmp(object_left->aor_name, right_key);
304                 break;
305         case OBJ_SEARCH_PARTIAL_KEY:
306                 /*
307                  * We could also use a partial key struct containing a length
308                  * so strlen() does not get called for every comparison instead.
309                  */
310                 cmp = strncmp(object_left->aor_name, right_key, strlen(right_key));
311                 break;
312         default:
313                 cmp = 0;
314                 break;
315         }
316
317         return cmp ? 0 : CMP_MATCH;
318 }
319
320 struct rx_task_data {
321         pjsip_rx_data *rdata;
322         struct ast_sip_endpoint *endpoint;
323         struct ast_sip_aor *aor;
324 };
325
326 static void rx_task_data_destroy(void *obj)
327 {
328         struct rx_task_data *task_data = obj;
329
330         pjsip_rx_data_free_cloned(task_data->rdata);
331         ao2_cleanup(task_data->endpoint);
332         ao2_cleanup(task_data->aor);
333 }
334
335 static struct rx_task_data *rx_task_data_create(pjsip_rx_data *rdata,
336                                                 struct ast_sip_endpoint *endpoint,
337                                                 struct ast_sip_aor *aor)
338 {
339         struct rx_task_data *task_data = ao2_alloc(
340                 sizeof(*task_data), rx_task_data_destroy);
341
342         if (!task_data) {
343                 return NULL;
344         }
345
346         pjsip_rx_data_clone(rdata, 0, &task_data->rdata);
347
348         task_data->endpoint = endpoint;
349         ao2_ref(task_data->endpoint, +1);
350
351         task_data->aor = aor;
352         ao2_ref(task_data->aor, +1);
353
354         return task_data;
355 }
356
357 static const pj_str_t path_hdr_name = { "Path", 4 };
358
359 static int build_path_data(struct rx_task_data *task_data, struct ast_str **path_str)
360 {
361         pjsip_generic_string_hdr *path_hdr = pjsip_msg_find_hdr_by_name(task_data->rdata->msg_info.msg, &path_hdr_name, NULL);
362
363         if (!path_hdr) {
364                 return 0;
365         }
366
367         *path_str = ast_str_create(64);
368         if (!path_str) {
369                 return -1;
370         }
371
372         ast_str_set(path_str, 0, "%.*s", (int)path_hdr->hvalue.slen, path_hdr->hvalue.ptr);
373
374         while ((path_hdr = (pjsip_generic_string_hdr *) pjsip_msg_find_hdr_by_name(task_data->rdata->msg_info.msg, &path_hdr_name, path_hdr->next))) {
375                 ast_str_append(path_str, 0, ",%.*s", (int)path_hdr->hvalue.slen, path_hdr->hvalue.ptr);
376         }
377
378         return 0;
379 }
380
381 static int registrar_validate_path(struct rx_task_data *task_data, struct ast_str **path_str)
382 {
383         const pj_str_t path_supported_name = { "path", 4 };
384         pjsip_supported_hdr *supported_hdr;
385         int i;
386
387         if (!task_data->aor->support_path) {
388                 return 0;
389         }
390
391         if (build_path_data(task_data, path_str)) {
392                 return -1;
393         }
394
395         if (!*path_str) {
396                 return 0;
397         }
398
399         supported_hdr = pjsip_msg_find_hdr(task_data->rdata->msg_info.msg, PJSIP_H_SUPPORTED, NULL);
400         if (!supported_hdr) {
401                 return -1;
402         }
403
404         /* Find advertised path support */
405         for (i = 0; i < supported_hdr->count; i++) {
406                 if (!pj_stricmp(&supported_hdr->values[i], &path_supported_name)) {
407                         return 0;
408                 }
409         }
410
411         /* Path header present, but support not advertised */
412         return -1;
413 }
414
415 static int rx_task(void *data)
416 {
417         static const pj_str_t USER_AGENT = { "User-Agent", 10 };
418
419         RAII_VAR(struct rx_task_data *, task_data, data, ao2_cleanup);
420         RAII_VAR(struct ao2_container *, contacts, NULL, ao2_cleanup);
421
422         int added = 0, updated = 0, deleted = 0;
423         pjsip_contact_hdr *contact_hdr = NULL;
424         struct registrar_contact_details details = { 0, };
425         pjsip_tx_data *tdata;
426         const char *aor_name = ast_sorcery_object_get_id(task_data->aor);
427         RAII_VAR(struct ast_str *, path_str, NULL, ast_free);
428         struct ast_sip_contact *response_contact;
429         char *user_agent = NULL;
430         pjsip_user_agent_hdr *user_agent_hdr;
431         pjsip_expires_hdr *expires_hdr;
432
433         /* Retrieve the current contacts, we'll need to know whether to update or not */
434         contacts = ast_sip_location_retrieve_aor_contacts(task_data->aor);
435
436         /* So we don't count static contacts against max_contacts we prune them out from the container */
437         ao2_callback(contacts, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, registrar_prune_static, NULL);
438
439         if (registrar_validate_contacts(task_data->rdata, contacts, task_data->aor, &added, &updated, &deleted)) {
440                 /* The provided Contact headers do not conform to the specification */
441                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), task_data->rdata, 400, NULL, NULL, NULL);
442                 ast_sip_report_failed_acl(task_data->endpoint, task_data->rdata, "registrar_invalid_contacts_provided");
443                 ast_log(LOG_WARNING, "Failed to validate contacts in REGISTER request from '%s'\n",
444                                 ast_sorcery_object_get_id(task_data->endpoint));
445                 return PJ_TRUE;
446         }
447
448         if (registrar_validate_path(task_data, &path_str)) {
449                 /* Ensure that intervening proxies did not make invalid modifications to the request */
450                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), task_data->rdata, 420, NULL, NULL, NULL);
451                 ast_log(LOG_WARNING, "Invalid modifications made to REGISTER request from '%s' by intervening proxy\n",
452                                 ast_sorcery_object_get_id(task_data->endpoint));
453                 return PJ_TRUE;
454         }
455
456         if ((MAX(added - deleted, 0) + (!task_data->aor->remove_existing ? ao2_container_count(contacts) : 0)) > task_data->aor->max_contacts) {
457                 /* Enforce the maximum number of contacts */
458                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), task_data->rdata, 403, NULL, NULL, NULL);
459                 ast_sip_report_failed_acl(task_data->endpoint, task_data->rdata, "registrar_attempt_exceeds_maximum_configured_contacts");
460                 ast_log(LOG_WARNING, "Registration attempt from endpoint '%s' to AOR '%s' will exceed max contacts of %u\n",
461                                 ast_sorcery_object_get_id(task_data->endpoint), ast_sorcery_object_get_id(task_data->aor), task_data->aor->max_contacts);
462                 return PJ_TRUE;
463         }
464
465         if (!(details.pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "Contact Comparison", 256, 256))) {
466                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), task_data->rdata, 500, NULL, NULL, NULL);
467                 return PJ_TRUE;
468         }
469
470         user_agent_hdr = pjsip_msg_find_hdr_by_name(task_data->rdata->msg_info.msg, &USER_AGENT, NULL);
471         if (user_agent_hdr) {
472                 size_t alloc_size = pj_strlen(&user_agent_hdr->hvalue) + 1;
473                 user_agent = ast_alloca(alloc_size);
474                 ast_copy_pj_str(user_agent, &user_agent_hdr->hvalue, alloc_size);
475         }
476
477         /* Iterate each provided Contact header and add, update, or delete */
478         while ((contact_hdr = pjsip_msg_find_hdr(task_data->rdata->msg_info.msg, PJSIP_H_CONTACT, contact_hdr ? contact_hdr->next : NULL))) {
479                 int expiration;
480                 char contact_uri[PJSIP_MAX_URL_SIZE];
481                 RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup);
482
483                 if (contact_hdr->star) {
484                         /* A star means to unregister everything, so do so for the possible contacts */
485                         ao2_callback(contacts, OBJ_NODATA | OBJ_MULTIPLE, registrar_delete_contact, (void *)aor_name);
486                         break;
487                 }
488
489                 if (!PJSIP_URI_SCHEME_IS_SIP(contact_hdr->uri) && !PJSIP_URI_SCHEME_IS_SIPS(contact_hdr->uri)) {
490                         /* This registrar only currently supports sip: and sips: URI schemes */
491                         continue;
492                 }
493
494                 expiration = registrar_get_expiration(task_data->aor, contact_hdr, task_data->rdata);
495                 details.uri = pjsip_uri_get_uri(contact_hdr->uri);
496                 pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, details.uri, contact_uri, sizeof(contact_uri));
497
498                 if (!(contact = ao2_callback(contacts, OBJ_UNLINK, registrar_find_contact, &details))) {
499                         /* If they are actually trying to delete a contact that does not exist... be forgiving */
500                         if (!expiration) {
501                                 ast_verb(3, "Attempted to remove non-existent contact '%s' from AOR '%s' by request\n",
502                                         contact_uri, aor_name);
503                                 continue;
504                         }
505
506                         if (ast_sip_location_add_contact(task_data->aor, contact_uri, ast_tvadd(ast_tvnow(),
507                                 ast_samp2tv(expiration, 1)), path_str ? ast_str_buffer(path_str) : NULL,
508                                         user_agent, task_data->endpoint)) {
509                                 ast_log(LOG_ERROR, "Unable to bind contact '%s' to AOR '%s'\n",
510                                                 contact_uri, aor_name);
511                                 continue;
512                         }
513
514                         ast_verb(3, "Added contact '%s' to AOR '%s' with expiration of %d seconds\n",
515                                 contact_uri, aor_name, expiration);
516                         ast_test_suite_event_notify("AOR_CONTACT_ADDED",
517                                         "Contact: %s\r\n"
518                                         "AOR: %s\r\n"
519                                         "Expiration: %d\r\n"
520                                         "UserAgent: %s",
521                                         contact_uri,
522                                         aor_name,
523                                         expiration,
524                                         user_agent);
525                 } else if (expiration) {
526                         struct ast_sip_contact *contact_update;
527
528                         contact_update = ast_sorcery_copy(ast_sip_get_sorcery(), contact);
529                         if (!contact_update) {
530                                 ast_log(LOG_ERROR, "Failed to update contact '%s' expiration time to %d seconds.\n",
531                                         contact->uri, expiration);
532                                 continue;
533                         }
534
535                         contact_update->expiration_time = ast_tvadd(ast_tvnow(), ast_samp2tv(expiration, 1));
536                         contact_update->qualify_frequency = task_data->aor->qualify_frequency;
537                         contact_update->authenticate_qualify = task_data->aor->authenticate_qualify;
538                         if (path_str) {
539                                 ast_string_field_set(contact_update, path, ast_str_buffer(path_str));
540                         }
541                         if (user_agent) {
542                                 ast_string_field_set(contact_update, user_agent, user_agent);
543                         }
544
545                         if (ast_sip_location_update_contact(contact_update)) {
546                                 ast_log(LOG_ERROR, "Failed to update contact '%s' expiration time to %d seconds.\n",
547                                         contact->uri, expiration);
548                                 ast_sorcery_delete(ast_sip_get_sorcery(), contact);
549                                 continue;
550                         }
551                         ast_debug(3, "Refreshed contact '%s' on AOR '%s' with new expiration of %d seconds\n",
552                                 contact_uri, aor_name, expiration);
553                         ast_test_suite_event_notify("AOR_CONTACT_REFRESHED",
554                                         "Contact: %s\r\n"
555                                         "AOR: %s\r\n"
556                                         "Expiration: %d\r\n"
557                                         "UserAgent: %s",
558                                         contact_uri,
559                                         aor_name,
560                                         expiration,
561                                         contact_update->user_agent);
562                         ao2_cleanup(contact_update);
563                 } else {
564                         /* We want to report the user agent that was actually in the removed contact */
565                         user_agent = ast_strdupa(contact->user_agent);
566                         ast_sip_location_delete_contact(contact);
567                         ast_verb(3, "Removed contact '%s' from AOR '%s' due to request\n", contact_uri, aor_name);
568                         ast_test_suite_event_notify("AOR_CONTACT_REMOVED",
569                                         "Contact: %s\r\n"
570                                         "AOR: %s\r\n"
571                                         "UserAgent: %s",
572                                         contact_uri,
573                                         aor_name,
574                                         user_agent);
575                 }
576         }
577
578         pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
579
580         /* If the AOR is configured to remove any existing contacts that have not been updated/added as a result of this REGISTER
581          * do so
582          */
583         if (task_data->aor->remove_existing) {
584                 ao2_callback(contacts, OBJ_NODATA | OBJ_MULTIPLE, registrar_delete_contact, NULL);
585         }
586
587         /* Update the contacts as things will probably have changed */
588         ao2_cleanup(contacts);
589
590         contacts = ast_sip_location_retrieve_aor_contacts(task_data->aor);
591         response_contact = ao2_callback(contacts, 0, NULL, NULL);
592
593         /* Send a response containing all of the contacts (including static) that are present on this AOR */
594         if (ast_sip_create_response(task_data->rdata, 200, response_contact, &tdata) != PJ_SUCCESS) {
595                 ao2_cleanup(response_contact);
596                 return PJ_TRUE;
597         }
598         ao2_cleanup(response_contact);
599
600         /* Add the date header to the response, some UAs use this to set their date and time */
601         registrar_add_date_header(tdata);
602
603         ao2_callback(contacts, 0, registrar_add_contact, tdata);
604
605         if ((expires_hdr = pjsip_msg_find_hdr(task_data->rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL))) {
606                 expires_hdr = pjsip_expires_hdr_create(tdata->pool, registrar_get_expiration(task_data->aor, NULL, task_data->rdata));
607                 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)expires_hdr);
608         }
609
610         ast_sip_send_stateful_response(task_data->rdata, tdata, task_data->endpoint);
611
612         return PJ_TRUE;
613 }
614
615 static pj_bool_t registrar_on_rx_request(struct pjsip_rx_data *rdata)
616 {
617         RAII_VAR(struct serializer *, ser, NULL, ao2_cleanup);
618         struct rx_task_data *task_data;
619
620         RAII_VAR(struct ast_sip_endpoint *, endpoint,
621                  ast_pjsip_rdata_get_endpoint(rdata), ao2_cleanup);
622         RAII_VAR(struct ast_sip_aor *, aor, NULL, ao2_cleanup);
623         pjsip_sip_uri *uri;
624         char *domain_name;
625         char *configured_aors, *aor_name;
626         RAII_VAR(struct ast_str *, id, NULL, ast_free);
627
628         if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_register_method) || !endpoint) {
629                 return PJ_FALSE;
630         }
631
632         if (ast_strlen_zero(endpoint->aors)) {
633                 /* Short circuit early if the endpoint has no AORs configured on it, which means no registration possible */
634                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
635                 ast_sip_report_failed_acl(endpoint, rdata, "registrar_attempt_without_configured_aors");
636                 ast_log(LOG_WARNING, "Endpoint '%s' has no configured AORs\n", ast_sorcery_object_get_id(endpoint));
637                 return PJ_TRUE;
638         }
639
640         if (!PJSIP_URI_SCHEME_IS_SIP(rdata->msg_info.to->uri) && !PJSIP_URI_SCHEME_IS_SIPS(rdata->msg_info.to->uri)) {
641                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 416, NULL, NULL, NULL);
642                 ast_sip_report_failed_acl(endpoint, rdata, "registrar_invalid_uri_in_to_received");
643                 ast_log(LOG_WARNING, "Endpoint '%s' attempted to register to an AOR with a non-SIP URI\n", ast_sorcery_object_get_id(endpoint));
644                 return PJ_TRUE;
645         }
646
647         uri = pjsip_uri_get_uri(rdata->msg_info.to->uri);
648         domain_name = ast_alloca(uri->host.slen + 1);
649         ast_copy_pj_str(domain_name, &uri->host, uri->host.slen + 1);
650
651         configured_aors = ast_strdupa(endpoint->aors);
652
653         /* Iterate the configured AORs to see if the user or the user+domain match */
654         while ((aor_name = strsep(&configured_aors, ","))) {
655                 struct ast_sip_domain_alias *alias = NULL;
656
657                 if (!pj_strcmp2(&uri->user, aor_name)) {
658                         break;
659                 }
660
661                 if (!id && !(id = ast_str_create(uri->user.slen + uri->host.slen + 2))) {
662                         return PJ_TRUE;
663                 }
664
665                 ast_str_set(&id, 0, "%.*s@", (int)uri->user.slen, uri->user.ptr);
666                 if ((alias = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "domain_alias", domain_name))) {
667                         ast_str_append(&id, 0, "%s", alias->domain);
668                         ao2_cleanup(alias);
669                 } else {
670                         ast_str_append(&id, 0, "%s", domain_name);
671                 }
672
673                 if (!strcmp(aor_name, ast_str_buffer(id))) {
674                         ast_free(id);
675                         break;
676                 }
677         }
678
679         if (ast_strlen_zero(aor_name) || !(aor = ast_sip_location_retrieve_aor(aor_name))) {
680                 /* The provided AOR name was not found (be it within the configuration or sorcery itself) */
681                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 404, NULL, NULL, NULL);
682                 ast_sip_report_req_no_support(endpoint, rdata, "registrar_requested_aor_not_found");
683                 ast_log(LOG_WARNING, "AOR '%.*s' not found for endpoint '%s'\n", (int)uri->user.slen, uri->user.ptr, ast_sorcery_object_get_id(endpoint));
684                 return PJ_TRUE;
685         }
686
687         if (!aor->max_contacts) {
688                 /* Registration is not permitted for this AOR */
689                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
690                 ast_sip_report_req_no_support(endpoint, rdata, "registrar_attempt_without_registration_permitted");
691                 ast_log(LOG_WARNING, "AOR '%s' has no configured max_contacts. Endpoint '%s' unable to register\n",
692                                 ast_sorcery_object_get_id(aor), ast_sorcery_object_get_id(endpoint));
693                 return PJ_TRUE;
694         }
695
696         if (!(ser = serializer_find_or_create(aor_name))) {
697                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
698                 ast_sip_report_mem_limit(endpoint, rdata);
699                 ast_log(LOG_WARNING, "Endpoint '%s' unable to register on AOR '%s' - could not get serializer\n",
700                         ast_sorcery_object_get_id(endpoint), ast_sorcery_object_get_id(aor));
701                 return PJ_TRUE;
702         }
703
704         if (!(task_data = rx_task_data_create(rdata, endpoint, aor))) {
705                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
706                 ast_sip_report_mem_limit(endpoint, rdata);
707                 ast_log(LOG_WARNING, "Endpoint '%s' unable to register on AOR '%s' - could not create rx_task_data\n",
708                         ast_sorcery_object_get_id(endpoint), ast_sorcery_object_get_id(aor));
709                 return PJ_TRUE;
710         }
711
712         if (ast_sip_push_task(ser->serializer, rx_task, task_data)) {
713                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
714                 ast_sip_report_mem_limit(endpoint, rdata);
715                 ast_log(LOG_WARNING, "Endpoint '%s' unable to register on AOR '%s' - could not serialize task\n",
716                         ast_sorcery_object_get_id(endpoint), ast_sorcery_object_get_id(aor));
717                 ao2_ref(task_data, -1);
718         }
719         return PJ_TRUE;
720 }
721
722 /* function pointer to callback needs to be within the module
723    in order to avoid problems with an undefined symbol */
724 static int sip_contact_to_str(void *acp, void *arg, int flags)
725 {
726         return ast_sip_contact_to_str(acp, arg, flags);
727 }
728
729 static int ami_registrations_aor(void *obj, void *arg, int flags)
730 {
731         struct ast_sip_aor *aor = obj;
732         struct ast_sip_ami *ami = arg;
733         int *count = ami->arg;
734         RAII_VAR(struct ast_str *, buf,
735                  ast_sip_create_ami_event("InboundRegistrationDetail", ami), ast_free);
736
737         if (!buf) {
738                 return -1;
739         }
740
741         ast_sip_sorcery_object_to_ami(aor, &buf);
742         ast_str_append(&buf, 0, "Contacts: ");
743         ast_sip_for_each_contact(aor, sip_contact_to_str, &buf);
744         ast_str_append(&buf, 0, "\r\n");
745
746         astman_append(ami->s, "%s\r\n", ast_str_buffer(buf));
747         (*count)++;
748         return 0;
749 }
750
751 static int ami_registrations_endpoint(void *obj, void *arg, int flags)
752 {
753         struct ast_sip_endpoint *endpoint = obj;
754         return ast_sip_for_each_aor(
755                 endpoint->aors, ami_registrations_aor, arg);
756 }
757
758 static int ami_registrations_endpoints(void *arg)
759 {
760         RAII_VAR(struct ao2_container *, endpoints,
761                  ast_sip_get_endpoints(), ao2_cleanup);
762
763         if (!endpoints) {
764                 return 0;
765         }
766
767         ao2_callback(endpoints, OBJ_NODATA, ami_registrations_endpoint, arg);
768         return 0;
769 }
770
771 static int ami_show_registrations(struct mansession *s, const struct message *m)
772 {
773         int count = 0;
774         struct ast_sip_ami ami = { .s = s, .m = m, .arg = &count, .action_id = astman_get_header(m, "ActionID"), };
775
776         astman_send_listack(s, m, "Following are Events for each Inbound registration",
777                 "start");
778
779         ami_registrations_endpoints(&ami);
780
781         astman_send_list_complete_start(s, m, "InboundRegistrationDetailComplete", count);
782         astman_send_list_complete_end(s);
783         return 0;
784 }
785
786 #define AMI_SHOW_REGISTRATIONS "PJSIPShowRegistrationsInbound"
787
788 static pjsip_module registrar_module = {
789         .name = { "Registrar", 9 },
790         .id = -1,
791         .priority = PJSIP_MOD_PRIORITY_APPLICATION,
792         .on_rx_request = registrar_on_rx_request,
793 };
794
795 static int load_module(void)
796 {
797         const pj_str_t STR_REGISTER = { "REGISTER", 8 };
798
799         CHECK_PJSIP_MODULE_LOADED();
800
801         if (!(serializers = ao2_container_alloc(
802                       SERIALIZER_BUCKETS, serializer_hash, serializer_cmp))) {
803                 return AST_MODULE_LOAD_DECLINE;
804         }
805
806         if (ast_sip_register_service(&registrar_module)) {
807                 return AST_MODULE_LOAD_DECLINE;
808         }
809
810         if (pjsip_endpt_add_capability(ast_sip_get_pjsip_endpoint(), NULL, PJSIP_H_ALLOW, NULL, 1, &STR_REGISTER) != PJ_SUCCESS) {
811                 ast_sip_unregister_service(&registrar_module);
812                 return AST_MODULE_LOAD_DECLINE;
813         }
814
815         ast_manager_register_xml(AMI_SHOW_REGISTRATIONS, EVENT_FLAG_SYSTEM,
816                                  ami_show_registrations);
817
818         return AST_MODULE_LOAD_SUCCESS;
819 }
820
821 static int unload_module(void)
822 {
823         ast_manager_unregister(AMI_SHOW_REGISTRATIONS);
824         ast_sip_unregister_service(&registrar_module);
825
826         ao2_cleanup(serializers);
827         return 0;
828 }
829
830 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Registrar Support",
831         .support_level = AST_MODULE_SUPPORT_CORE,
832         .load = load_module,
833         .unload = unload_module,
834         .load_pri = AST_MODPRI_APP_DEPEND,
835 );