Asterisk - The Open Source Telephony Project  21.4.1
res_pjsip_registrar.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * Joshua Colp <jcolp@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 /*** MODULEINFO
20  <depend>pjproject</depend>
21  <depend>res_pjproject</depend>
22  <depend>res_pjsip</depend>
23  <support_level>core</support_level>
24  ***/
25 
26 #include "asterisk.h"
27 
28 #include <signal.h>
29 #include <pjsip.h>
30 #include <pjsip_ua.h>
31 
32 #include "asterisk/res_pjsip.h"
33 #include "asterisk/module.h"
34 #include "asterisk/paths.h"
35 #include "asterisk/test.h"
36 #include "asterisk/taskprocessor.h"
37 #include "asterisk/manager.h"
38 #include "asterisk/named_locks.h"
39 #include "asterisk/res_pjproject.h"
40 #include "res_pjsip/include/res_pjsip_private.h"
41 
42 /*** DOCUMENTATION
43  <manager name="PJSIPShowRegistrationsInbound" language="en_US">
44  <synopsis>
45  Lists PJSIP inbound registrations.
46  </synopsis>
47  <syntax />
48  <description>
49  <para>
50  In response, <literal>InboundRegistrationDetail</literal> events showing configuration
51  and status information are raised for all contacts, static or dynamic. Once all events
52  are completed an <literal>InboundRegistrationDetailComplete</literal> is issued.
53  </para>
54  <warning><para>
55  This command just dumps all coonfigured AORs with contacts, even if the contact
56  is a permanent one. To really get just inbound registrations, use
57  <literal>PJSIPShowRegistrationInboundContactStatuses</literal>.
58  </para>
59  </warning>
60  </description>
61  <see-also>
62  <ref type="manager" module="res_pjsip_registrar">PJSIPShowRegistrationInboundContactStatuses</ref>
63  </see-also>
64  </manager>
65  <manager name="PJSIPShowRegistrationInboundContactStatuses" language="en_US">
66  <synopsis>
67  Lists ContactStatuses for PJSIP inbound registrations.
68  </synopsis>
69  <syntax />
70  <description>
71  <para>
72  In response, <literal>ContactStatusDetail</literal> events showing status information
73  are raised for each inbound registration (dynamic contact) object. Once all events
74  are completed a <literal>ContactStatusDetailComplete</literal> event is issued.
75  </para>
76  </description>
77  </manager>
78  ***/
79 
80 static int pj_max_hostname = PJ_MAX_HOSTNAME;
81 static int pjsip_max_url_size = PJSIP_MAX_URL_SIZE;
82 
83 /*! \brief Internal function which returns the expiration time for a contact */
84 static unsigned int registrar_get_expiration(const struct ast_sip_aor *aor, const pjsip_contact_hdr *contact, const pjsip_rx_data *rdata)
85 {
86  pjsip_expires_hdr *expires;
87  unsigned int expiration = aor->default_expiration;
88 
89  if (contact && contact->expires != PJSIP_EXPIRES_NOT_SPECIFIED) {
90  /* Expiration was provided with the contact itself */
91  expiration = contact->expires;
92  } else if ((expires = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL))) {
93  /* Expiration was provided using the Expires header */
94  expiration = expires->ivalue;
95  }
96 
97  /* If the value has explicitly been set to 0, do not enforce */
98  if (!expiration) {
99  return expiration;
100  }
101 
102  /* Enforce the range that we will allow for expiration */
103  if (expiration < aor->minimum_expiration) {
104  expiration = aor->minimum_expiration;
105  } else if (expiration > aor->maximum_expiration) {
106  expiration = aor->maximum_expiration;
107  }
108 
109  return expiration;
110 }
111 
112 /*! \brief Structure used for finding contact */
114  /*! \brief Pool used for parsing URI */
115  pj_pool_t *pool;
116  /*! \brief URI being looked for */
117  pjsip_sip_uri *uri;
118 };
119 
120 /*! \brief Callback function for finding a contact */
121 static int registrar_find_contact(void *obj, void *arg, int flags)
122 {
123  struct ast_sip_contact *contact = obj;
124  const struct registrar_contact_details *details = arg;
125  pjsip_uri *contact_uri;
126 
127  if (ast_tvzero(contact->expiration_time)) {
128  return 0;
129  }
130 
131  contact_uri = pjsip_parse_uri(details->pool, (char*)contact->uri, strlen(contact->uri), 0);
132  if (!contact_uri) {
133  ast_log(LOG_WARNING, "Unable to parse contact URI from '%s'.\n", contact->uri);
134  return 0;
135  }
136 
137  return (pjsip_uri_cmp(PJSIP_URI_IN_CONTACT_HDR, details->uri, contact_uri) == PJ_SUCCESS) ? CMP_MATCH : 0;
138 }
139 
140 /*! \brief Internal function which validates provided Contact headers to confirm that they are acceptable, and returns number of contacts */
141 static int registrar_validate_contacts(const pjsip_rx_data *rdata, pj_pool_t *pool, struct ao2_container *contacts,
142  struct ast_sip_aor *aor, int permanent, int *added, int *updated, int *deleted)
143 {
144  pjsip_contact_hdr *previous = NULL;
145  pjsip_contact_hdr *contact = (pjsip_contact_hdr *)&rdata->msg_info.msg->hdr;
146  struct registrar_contact_details details = {
147  .pool = pool,
148  };
149 
150  for (; (contact = (pjsip_contact_hdr *) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, contact->next)); pj_pool_reset(pool)) {
151  unsigned int expiration = registrar_get_expiration(aor, contact, rdata);
152  struct ast_sip_contact *existing;
153  char contact_uri[pjsip_max_url_size];
154 
155  if (contact->star) {
156  /* The expiration MUST be 0 when a '*' contact is used and there must be no other contact */
157  if (expiration != 0 || previous) {
158  return -1;
159  }
160  /* Count all contacts to delete */
161  *deleted = ao2_container_count(contacts) - permanent;
162  previous = contact;
163  continue;
164  } else if (previous && previous->star) {
165  /* If there is a previous contact and it is a '*' this is a deal breaker */
166  return -1;
167  }
168  previous = contact;
169 
170  if (!PJSIP_URI_SCHEME_IS_SIP(contact->uri) && !PJSIP_URI_SCHEME_IS_SIPS(contact->uri)) {
171  continue;
172  }
173 
174  details.uri = pjsip_uri_get_uri(contact->uri);
175 
176  /* pjsip_uri_print returns -1 if there's not enough room in the buffer */
177  if (pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, details.uri, contact_uri, sizeof(contact_uri)) < 0) {
178  /* If the total length of the uri is greater than pjproject can handle, go no further */
179  return -1;
180  }
181 
182  if (details.uri->host.slen >= pj_max_hostname) {
183  /* If the length of the hostname is greater than pjproject can handle, go no further */
184  return -1;
185  }
186 
187  /* Determine if this is an add, update, or delete for policy enforcement purposes */
188  existing = ao2_callback(contacts, 0, registrar_find_contact, &details);
189  ao2_cleanup(existing);
190  if (!existing) {
191  if (expiration) {
192  ++*added;
193  }
194  } else if (expiration) {
195  ++*updated;
196  } else {
197  ++*deleted;
198  }
199  }
200 
201  return 0;
202 }
203 
204 enum contact_delete_type {
205  CONTACT_DELETE_ERROR,
206  CONTACT_DELETE_EXISTING,
207  CONTACT_DELETE_UNAVAILABLE,
208  CONTACT_DELETE_EXPIRE,
209  CONTACT_DELETE_REQUEST,
210  CONTACT_DELETE_SHUTDOWN,
211 };
212 
213 static int registrar_contact_delete(enum contact_delete_type type, pjsip_transport *transport,
214  struct ast_sip_contact *contact, const char *aor_name);
215 
216 /*! \brief Internal function used to delete a contact from an AOR */
217 static int registrar_delete_contact(void *obj, void *arg, int flags)
218 {
219  return registrar_contact_delete(
220  CONTACT_DELETE_REQUEST, NULL, obj, arg) ? 0 : CMP_MATCH;
221 }
222 
223 /*! \brief Internal function which adds a contact to a response */
224 static int registrar_add_contact(void *obj, void *arg, int flags)
225 {
226  struct ast_sip_contact *contact = obj;
227  pjsip_tx_data *tdata = arg;
228  pj_str_t uri;
229  pjsip_uri *parsed;
230 
231  pj_strdup2_with_null(tdata->pool, &uri, contact->uri);
232  parsed = pjsip_parse_uri(tdata->pool, uri.ptr, uri.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
233 
234  if (parsed && (PJSIP_URI_SCHEME_IS_SIP(parsed) || PJSIP_URI_SCHEME_IS_SIPS(parsed))) {
235  pjsip_contact_hdr *hdr = pjsip_contact_hdr_create(tdata->pool);
236  hdr->uri = parsed;
237  if (!ast_tvzero(contact->expiration_time)) {
238  hdr->expires = ast_tvdiff_ms(contact->expiration_time, ast_tvnow()) / 1000;
239  } else {
240  hdr->expires = PJSIP_EXPIRES_NOT_SPECIFIED;
241  }
242  pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *) hdr);
243  } else {
244  ast_log(LOG_WARNING, "Skipping invalid Contact URI \"%.*s\" for AOR %s\n",
245  (int) uri.slen, uri.ptr, contact->aor);
246  }
247 
248  return 0;
249 }
250 
251 static const pj_str_t path_hdr_name = { "Path", 4 };
252 
253 static int build_path_data(pjsip_rx_data *rdata, struct ast_str **path_str)
254 {
255  pjsip_generic_string_hdr *path_hdr = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &path_hdr_name, NULL);
256 
257  if (!path_hdr) {
258  return 0;
259  }
260 
261  *path_str = ast_str_create(64);
262  if (!*path_str) {
263  return -1;
264  }
265 
266  ast_str_set(path_str, 0, "%.*s", (int)path_hdr->hvalue.slen, path_hdr->hvalue.ptr);
267 
268  while ((path_hdr = (pjsip_generic_string_hdr *) pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &path_hdr_name, path_hdr->next))) {
269  ast_str_append(path_str, 0, ",%.*s", (int)path_hdr->hvalue.slen, path_hdr->hvalue.ptr);
270  }
271 
272  return 0;
273 }
274 
275 static int registrar_validate_path(pjsip_rx_data *rdata, struct ast_sip_aor *aor, struct ast_str **path_str)
276 {
277  const pj_str_t path_supported_name = { "path", 4 };
278  pjsip_supported_hdr *supported_hdr;
279  int i;
280 
281  if (!aor->support_path) {
282  return 0;
283  }
284 
285  if (build_path_data(rdata, path_str)) {
286  return -1;
287  }
288 
289  if (!*path_str) {
290  return 0;
291  }
292 
293  supported_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_SUPPORTED, NULL);
294  if (!supported_hdr) {
295  return -1;
296  }
297 
298  /* Find advertised path support */
299  for (i = 0; i < supported_hdr->count; i++) {
300  if (!pj_stricmp(&supported_hdr->values[i], &path_supported_name)) {
301  return 0;
302  }
303  }
304 
305  /* Path header present, but support not advertised */
306  return -1;
307 }
308 
309 /*! Transport monitor for incoming REGISTER contacts */
311  /*!
312  * \brief Sorcery contact name to remove on transport shutdown
313  * \note Stored after aor_name in space reserved when struct allocated.
314  */
316  /*! Indicates that the monitor is in the process of removing a contact */
317  int removing;
318  /*! AOR name the contact is associated */
319  char aor_name[0];
320 };
321 
322 static int contact_transport_monitor_matcher(void *a, void *b)
323 {
324  struct contact_transport_monitor *ma = a;
325  struct contact_transport_monitor *mb = b;
326 
327  return strcmp(ma->aor_name, mb->aor_name) == 0
328  && strcmp(ma->contact_name, mb->contact_name) == 0;
329 }
330 
331 static int register_contact_transport_remove_cb(void *data)
332 {
333  struct contact_transport_monitor *monitor = data;
334  struct ast_sip_contact *contact;
335  struct ast_sip_aor *aor;
336 
337  aor = ast_sip_location_retrieve_aor(monitor->aor_name);
338  if (!aor) {
339  ao2_lock(monitor);
340  monitor->removing = 0;
341  ao2_unlock(monitor);
342  ao2_ref(monitor, -1);
343  return 0;
344  }
345 
346  ao2_lock(aor);
347 
348  contact = ast_sip_location_retrieve_contact(monitor->contact_name);
349  if (contact) {
350  registrar_contact_delete(CONTACT_DELETE_SHUTDOWN, NULL, contact, monitor->aor_name);
351  ao2_ref(contact, -1);
352  }
353  ao2_unlock(aor);
354  ao2_ref(aor, -1);
355 
356  ao2_ref(monitor, -1);
357  return 0;
358 }
359 
360 /*!
361  * \internal
362  * \brief The reliable transport we registered as a contact has shutdown.
363  *
364  * \param data What contact needs to be removed.
365  *
366  * \note Normally executed by the pjsip monitor thread.
367  */
368 static void register_contact_transport_shutdown_cb(void *data)
369 {
370  struct contact_transport_monitor *monitor = data;
371 
372  /*
373  * It's possible for this shutdown handler to get called multiple times for the
374  * same monitor from different threads. Only one of the calls needs to do the
375  * actual removing of the contact, so if one is currently removing then any
376  * subsequent calls can skip.
377  */
378  ao2_lock(monitor);
379  if (monitor->removing) {
380  ao2_unlock(monitor);
381  return;
382  }
383 
384  monitor->removing = 1;
385 
386  /*
387  * Push off to a default serializer. This is in case sorcery
388  * does database accesses for contacts. Database accesses may
389  * not be on this machine. We don't want to tie up the pjsip
390  * monitor thread with potentially long access times.
391  */
392  ao2_ref(monitor, +1);
393  if (ast_sip_push_task(NULL, register_contact_transport_remove_cb, monitor)) {
394  monitor->removing = 0;
395  ao2_ref(monitor, -1);
396  }
397 
398  ao2_unlock(monitor);
399 }
400 
401 
402 static int registrar_contact_delete(enum contact_delete_type type, pjsip_transport *transport,
403  struct ast_sip_contact *contact, const char *aor_name)
404 {
405  int aor_size;
406 
407  /* Permanent contacts can't be deleted */
408  if (ast_tvzero(contact->expiration_time)) {
409  return -1;
410  }
411 
412  aor_size = aor_name ? strlen(aor_name) : 0;
413  if (contact->prune_on_boot && type != CONTACT_DELETE_SHUTDOWN && aor_size) {
414  const char *contact_name = ast_sorcery_object_get_id(contact);
415  size_t contact_name_len = strlen(contact_name) + 1;
416  struct contact_transport_monitor *monitor = ast_alloca(
417  sizeof(*monitor) + 1 + aor_size + contact_name_len);
418 
419  strcpy(monitor->aor_name, aor_name); /* Safe */
420  monitor->contact_name = monitor->aor_name + aor_size + 1;
421  ast_copy_string(monitor->contact_name, contact_name, contact_name_len); /* Safe */
422 
423  if (transport) {
425  register_contact_transport_shutdown_cb, monitor,
426  contact_transport_monitor_matcher);
427  } else {
428  /*
429  * If a specific transport is not supplied then unregister the matching
430  * monitor from all reliable transports.
431  */
432  ast_sip_transport_monitor_unregister_all(register_contact_transport_shutdown_cb,
433  monitor, contact_transport_monitor_matcher);
434  }
435  }
436 
437  ast_sip_location_delete_contact(contact);
438 
439  if (aor_size) {
440  if (VERBOSITY_ATLEAST(3)) {
441  const char *reason = "none";
442 
443  switch (type) {
444  case CONTACT_DELETE_ERROR:
445  reason = "registration failure";
446  break;
447  case CONTACT_DELETE_EXISTING:
448  reason = "remove existing";
449  break;
450  case CONTACT_DELETE_UNAVAILABLE:
451  reason = "remove unavailable";
452  break;
453  case CONTACT_DELETE_EXPIRE:
454  reason = "expiration";
455  break;
456  case CONTACT_DELETE_REQUEST:
457  reason = "request";
458  break;
459  case CONTACT_DELETE_SHUTDOWN:
460  reason = "shutdown";
461  break;
462  }
463 
464  ast_verb(3, "Removed contact '%s' from AOR '%s' due to %s\n",
465  contact->uri, aor_name, reason);
466  }
467 
468  ast_test_suite_event_notify("AOR_CONTACT_REMOVED",
469  "Contact: %s\r\n"
470  "AOR: %s\r\n"
471  "UserAgent: %s",
472  contact->uri,
473  aor_name,
474  contact->user_agent);
475  }
476 
477  return 0;
478 }
479 
481 
482 static int vec_contact_cmp(struct ast_sip_contact *left, struct ast_sip_contact *right)
483 {
484  struct ast_sip_contact *left_contact = left;
485  struct ast_sip_contact *right_contact = right;
486 
487  /* Sort from soonest to expire to last to expire */
488  int time_sorted = ast_tvcmp(left_contact->expiration_time, right_contact->expiration_time);
489 
490  struct ast_sip_aor *aor = ast_sip_location_retrieve_aor(left_contact->aor);
491  struct ast_sip_contact_status *left_status;
492  struct ast_sip_contact_status *right_status;
493  int remove_unavailable = 0;
494  int left_unreachable;
495  int right_unreachable;
496 
497  if (aor) {
498  remove_unavailable = aor->remove_unavailable;
499  ao2_ref(aor, -1);
500  }
501 
502  if (!remove_unavailable) {
503  return time_sorted;
504  }
505 
506  /* Get contact status if available */
507  left_status = ast_sip_get_contact_status(left_contact);
508  if (!left_status) {
509  return time_sorted;
510  }
511 
512  right_status = ast_sip_get_contact_status(right_contact);
513  if (!right_status) {
514  ao2_ref(left_status, -1);
515  return time_sorted;
516  }
517 
518  left_unreachable = (left_status->status == UNAVAILABLE);
519  right_unreachable = (right_status->status == UNAVAILABLE);
520  ao2_ref(left_status, -1);
521  ao2_ref(right_status, -1);
522  if (left_unreachable != right_unreachable) {
523  /* Set unavailable contact to top of vector */
524  if (left_unreachable) return -1;
525  if (right_unreachable) return 1;
526  }
527 
528  /* Either both available or both unavailable */
529  return time_sorted;
530 }
531 
532 static int vec_contact_add(void *obj, void *arg, int flags)
533 {
534  struct ast_sip_contact *contact = obj;
535  struct excess_contact_vector *contact_vec = arg;
536 
537  /*
538  * Performance wise, an insertion sort is fine because we
539  * shouldn't need to remove more than a handful of contacts.
540  * I expect we'll typically be removing only one contact.
541  */
542  AST_VECTOR_ADD_SORTED(contact_vec, contact, vec_contact_cmp);
543  if (AST_VECTOR_SIZE(contact_vec) == AST_VECTOR_MAX_SIZE(contact_vec)) {
544  /*
545  * We added a contact over the number we need to remove.
546  * Remove the longest to expire contact from the vector
547  * which is the last element in the vector. It may be
548  * the one we just added or the one we just added pushed
549  * out an earlier contact from removal consideration.
550  */
551  --AST_VECTOR_SIZE(contact_vec);
552  }
553  return 0;
554 }
555 
556 /*!
557  * \internal
558  * \brief Remove excess existing contacts that are unavailable or expire soonest.
559  * \since 13.18.0
560  *
561  * \param contacts Container of unmodified contacts that could remove.
562  * \param to_remove Maximum number of contacts to remove.
563  * \param response_contacts, remove_existing
564  */
565 static void remove_excess_contacts(struct ao2_container *contacts, struct ao2_container *response_contacts,
566  unsigned int to_remove, unsigned int remove_existing)
567 {
568  struct excess_contact_vector contact_vec;
569 
570  /*
571  * Create a sorted vector to hold the to_remove soonest to
572  * expire contacts. The vector has an extra space to
573  * temporarily hold the longest to expire contact that we
574  * won't remove.
575  */
576  if (AST_VECTOR_INIT(&contact_vec, to_remove + 1)) {
577  return;
578  }
579  ao2_callback(contacts, OBJ_NODATA | OBJ_MULTIPLE, vec_contact_add, &contact_vec);
580 
581  /*
582  * The vector should always be populated with the number
583  * of contacts we need to remove. Just in case, we will
584  * remove all contacts in the vector even if the contacts
585  * container had fewer contacts than there should be.
586  */
587  ast_assert(AST_VECTOR_SIZE(&contact_vec) == to_remove);
588  to_remove = AST_VECTOR_SIZE(&contact_vec);
589 
590  /* Remove the excess contacts that are unavailable or expire the soonest */
591  while (to_remove--) {
592  struct ast_sip_contact *contact;
593 
594  contact = AST_VECTOR_GET(&contact_vec, to_remove);
595 
596  if (!remove_existing) {
597  registrar_contact_delete(CONTACT_DELETE_UNAVAILABLE, NULL, contact, contact->aor);
598  } else {
599  registrar_contact_delete(CONTACT_DELETE_EXISTING, NULL, contact, contact->aor);
600  }
601 
602  ao2_unlink(response_contacts, contact);
603  }
604 
605  AST_VECTOR_FREE(&contact_vec);
606 }
607 
608 /*! \brief Callback function which adds non-permanent contacts to a container */
609 static int registrar_add_non_permanent(void *obj, void *arg, int flags)
610 {
611  struct ast_sip_contact *contact = obj;
612  struct ao2_container *container = arg;
613 
614  if (ast_tvzero(contact->expiration_time)) {
615  return 0;
616  }
617 
618  ao2_link(container, contact);
619 
620  return 0;
621 }
622 
623 /*! \brief Internal callback function which adds any contact which is unreachable */
624 static int registrar_add_unreachable(void *obj, void *arg, int flags)
625 {
626  struct ast_sip_contact *contact = obj;
627  struct ao2_container *container = arg;
629  int unreachable;
630 
631  status = ast_sip_get_contact_status(contact);
632  if (!status) {
633  return 0;
634  }
635 
636  unreachable = (status->status == UNAVAILABLE);
637  ao2_ref(status, -1);
638 
639  if (unreachable) {
640  ao2_link(container, contact);
641  }
642 
643  return 0;
644 }
645 
647  /*! Tx data to use for statefull response. NULL for stateless response. */
648  pjsip_tx_data *tdata;
649  /*! SIP response code to send in stateless response */
650  int code;
651 };
652 
653 static void register_aor_core(pjsip_rx_data *rdata,
654  struct ast_sip_endpoint *endpoint,
655  struct ast_sip_aor *aor,
656  const char *aor_name,
657  struct ao2_container *contacts,
658  struct aor_core_response *response)
659 {
660  static const pj_str_t USER_AGENT = { "User-Agent", 10 };
661 
662  int added = 0;
663  int updated = 0;
664  int deleted = 0;
665  int permanent = 0;
666  int contact_count;
667  struct ao2_container *existing_contacts = NULL;
668  struct ao2_container *unavail_contacts = NULL;
669  pjsip_contact_hdr *contact_hdr = (pjsip_contact_hdr *)&rdata->msg_info.msg->hdr;
670  struct registrar_contact_details details = { 0, };
671  pjsip_tx_data *tdata;
672  RAII_VAR(struct ast_str *, path_str, NULL, ast_free);
673  struct ast_sip_contact *response_contact;
674  char *user_agent = NULL;
675  pjsip_user_agent_hdr *user_agent_hdr;
676  pjsip_expires_hdr *expires_hdr;
677  pjsip_via_hdr *via_hdr;
678  pjsip_via_hdr *via_hdr_last;
679  char *via_addr = NULL;
680  int via_port = 0;
681  pjsip_cid_hdr *call_id_hdr;
682  char *call_id = NULL;
683  size_t alloc_size;
684 
685  /* We create a single pool and use it throughout this function where we need one */
686  details.pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(),
687  "Contact Comparison", 1024, 256);
688  if (!details.pool) {
689  response->code = 500;
690  return;
691  }
692 
693  /* If there are any permanent contacts configured on the AOR we need to take them
694  * into account when counting contacts.
695  */
696  if (aor->permanent_contacts) {
697  permanent = ao2_container_count(aor->permanent_contacts);
698  }
699 
700  if (registrar_validate_contacts(rdata, details.pool, contacts, aor, permanent, &added, &updated, &deleted)) {
701  /* The provided Contact headers do not conform to the specification */
702  ast_sip_report_failed_acl(endpoint, rdata, "registrar_invalid_contacts_provided");
703  ast_log(LOG_WARNING, "Failed to validate contacts in REGISTER request from '%s'\n",
705  response->code = 400;
706  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
707  return;
708  }
709 
710  if (registrar_validate_path(rdata, aor, &path_str)) {
711  /* Ensure that intervening proxies did not make invalid modifications to the request */
712  ast_log(LOG_WARNING, "Invalid modifications made to REGISTER request from '%s' by intervening proxy\n",
714  response->code = 420;
715  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
716  return;
717  }
718 
719  if (aor->remove_existing) {
720  /* Cumulative number of contacts affected by this registration */
721  contact_count = MAX(updated + added - deleted, 0);
722 
723  /* We need to keep track of only existing contacts so we can later
724  * remove them if need be.
725  */
728  if (!existing_contacts) {
729  response->code = 500;
730  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
731  return;
732  }
733 
734  ao2_callback(contacts, OBJ_NODATA, registrar_add_non_permanent, existing_contacts);
735  } else {
736  /* Total contacts after this registration */
737  contact_count = ao2_container_count(contacts) - permanent + added - deleted;
738  }
739 
740  if (contact_count > aor->max_contacts && aor->remove_unavailable) {
741  /* Get unavailable contact total */
742  int unavail_count = 0;
743 
746  if (!unavail_contacts) {
747  response->code = 500;
748  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
749  return;
750  }
751  ao2_callback(contacts, OBJ_NODATA, registrar_add_unreachable, unavail_contacts);
752  if (unavail_contacts) {
753  unavail_count = ao2_container_count(unavail_contacts);
754  }
755 
756  /* Check to see if removing unavailable contacts will help */
757  if (contact_count - unavail_count <= aor->max_contacts) {
758  /* Remove any unavailable contacts */
759  remove_excess_contacts(unavail_contacts, contacts, contact_count - aor->max_contacts, aor->remove_existing);
760  ao2_cleanup(unavail_contacts);
761  /* We're only here if !aor->remove_existing so this count is correct */
762  contact_count = ao2_container_count(contacts) - permanent + added - deleted;
763  }
764  }
765 
766  if (contact_count > aor->max_contacts) {
767  /* Enforce the maximum number of contacts */
768  ast_sip_report_failed_acl(endpoint, rdata, "registrar_attempt_exceeds_maximum_configured_contacts");
769  ast_log(LOG_WARNING, "Registration attempt from endpoint '%s' (%s:%d) to AOR '%s' will exceed max contacts of %u\n",
770  ast_sorcery_object_get_id(endpoint), rdata->pkt_info.src_name, rdata->pkt_info.src_port,
771  aor_name, aor->max_contacts);
772  response->code = 403;
773  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
774  ao2_cleanup(existing_contacts);
775  return;
776  }
777 
778  user_agent_hdr = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &USER_AGENT, NULL);
779  if (user_agent_hdr) {
780  alloc_size = pj_strlen(&user_agent_hdr->hvalue) + 1;
781  user_agent = ast_alloca(alloc_size);
782  ast_copy_pj_str(user_agent, &user_agent_hdr->hvalue, alloc_size);
783  }
784 
785  /* Find the first Via header */
786  via_hdr = via_hdr_last = (pjsip_via_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_VIA, NULL);
787  if (via_hdr) {
788  /* Find the last Via header */
789  while ( (via_hdr = (pjsip_via_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg,
790  PJSIP_H_VIA, via_hdr->next)) != NULL) {
791  via_hdr_last = via_hdr;
792  }
793  alloc_size = pj_strlen(&via_hdr_last->sent_by.host) + 1;
794  via_addr = ast_alloca(alloc_size);
795  ast_copy_pj_str(via_addr, &via_hdr_last->sent_by.host, alloc_size);
796  via_port=via_hdr_last->sent_by.port;
797  }
798 
799  call_id_hdr = (pjsip_cid_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CALL_ID, NULL);
800  if (call_id_hdr) {
801  alloc_size = pj_strlen(&call_id_hdr->id) + 1;
802  call_id = ast_alloca(alloc_size);
803  ast_copy_pj_str(call_id, &call_id_hdr->id, alloc_size);
804  }
805 
806  /* Iterate each provided Contact header and add, update, or delete */
807  for (; (contact_hdr = (pjsip_contact_hdr *) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, contact_hdr->next)); pj_pool_reset(details.pool)) {
808  int expiration;
809  char contact_uri[pjsip_max_url_size];
810  RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup);
811 
812  if (contact_hdr->star) {
813  /* A star means to unregister everything, so do so for the possible contacts */
815  registrar_delete_contact, (void *)aor_name);
816  /* If we are keeping track of existing contacts for removal then, well, there is
817  * absolutely nothing left so no need to try to remove any.
818  */
819  if (existing_contacts) {
820  ao2_ref(existing_contacts, -1);
821  existing_contacts = NULL;
822  }
823  break;
824  }
825 
826  if (!PJSIP_URI_SCHEME_IS_SIP(contact_hdr->uri) && !PJSIP_URI_SCHEME_IS_SIPS(contact_hdr->uri)) {
827  /* This registrar only currently supports sip: and sips: URI schemes */
828  continue;
829  }
830 
831  expiration = registrar_get_expiration(aor, contact_hdr, rdata);
832  details.uri = pjsip_uri_get_uri(contact_hdr->uri);
833  pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, details.uri, contact_uri, sizeof(contact_uri));
834 
835  contact = ao2_callback(contacts, OBJ_UNLINK, registrar_find_contact, &details);
836 
837  /* If a contact was returned and we need to keep track of existing contacts then it
838  * should be removed.
839  */
840  if (contact && existing_contacts) {
841  ao2_unlink(existing_contacts, contact);
842  }
843 
844  if (!contact) {
845  int prune_on_boot;
846 
847  /* If they are actually trying to delete a contact that does not exist... be forgiving */
848  if (!expiration) {
849  ast_verb(3, "Attempted to remove non-existent contact '%s' from AOR '%s' by request\n",
850  contact_uri, aor_name);
851  continue;
852  }
853 
854  prune_on_boot = !ast_sip_will_uri_survive_restart(details.uri, endpoint, rdata);
855 
856  contact = ast_sip_location_create_contact(aor, contact_uri,
857  ast_tvadd(ast_tvnow(), ast_samp2tv(expiration, 1)),
858  path_str ? ast_str_buffer(path_str) : NULL,
859  user_agent, via_addr, via_port, call_id, prune_on_boot, endpoint);
860  if (!contact) {
861  ast_log(LOG_ERROR, "Unable to bind contact '%s' to AOR '%s'\n",
862  contact_uri, aor_name);
863  continue;
864  }
865 
866  if (prune_on_boot) {
867  size_t contact_name_len;
868  const char *contact_name;
869  struct contact_transport_monitor *monitor;
870 
871  /*
872  * Monitor the transport in case it gets disconnected because
873  * the contact won't be valid anymore if that happens.
874  */
875  contact_name = ast_sorcery_object_get_id(contact);
876  contact_name_len = strlen(contact_name) + 1;
877  monitor = ao2_alloc(sizeof(*monitor) + 1 + strlen(aor_name)
878  + contact_name_len, NULL);
879  if (monitor) {
880  strcpy(monitor->aor_name, aor_name);/* Safe */
881  monitor->contact_name = monitor->aor_name + strlen(aor_name) + 1;
882  ast_copy_string(monitor->contact_name, contact_name, contact_name_len);/* Safe */
883 
884  ast_sip_transport_monitor_register_replace(rdata->tp_info.transport,
885  register_contact_transport_shutdown_cb, monitor, contact_transport_monitor_matcher);
886  ao2_ref(monitor, -1);
887  }
888  }
889 
890  ast_verb(3, "Added contact '%s' to AOR '%s' with expiration of %d seconds\n",
891  contact_uri, aor_name, expiration);
892  ast_test_suite_event_notify("AOR_CONTACT_ADDED",
893  "Contact: %s\r\n"
894  "AOR: %s\r\n"
895  "Expiration: %d\r\n"
896  "UserAgent: %s",
897  contact_uri,
898  aor_name,
899  expiration,
900  user_agent);
901 
902  ao2_link(contacts, contact);
903  } else if (expiration) {
904  struct ast_sip_contact *contact_update;
905 
906  contact_update = ast_sorcery_copy(ast_sip_get_sorcery(), contact);
907  if (!contact_update) {
908  ast_log(LOG_ERROR, "Failed to update contact '%s' expiration time to %d seconds.\n",
909  contact->uri, expiration);
910  continue;
911  }
912 
913  contact_update->expiration_time = ast_tvadd(ast_tvnow(), ast_samp2tv(expiration, 1));
914  contact_update->qualify_frequency = aor->qualify_frequency;
915  contact_update->authenticate_qualify = aor->authenticate_qualify;
916  if (path_str) {
917  ast_string_field_set(contact_update, path, ast_str_buffer(path_str));
918  }
919  if (user_agent) {
920  ast_string_field_set(contact_update, user_agent, user_agent);
921  }
922  if (!ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) {
923  ast_string_field_set(contact_update, reg_server, ast_config_AST_SYSTEM_NAME);
924  }
925 
926  if (ast_sip_location_update_contact(contact_update)) {
927  ast_log(LOG_ERROR, "Failed to update contact '%s' expiration time to %d seconds.\n",
928  contact->uri, expiration);
929  registrar_contact_delete(CONTACT_DELETE_ERROR, rdata->tp_info.transport,
930  contact, aor_name);
931  continue;
932  }
933  ast_debug(3, "Refreshed contact '%s' on AOR '%s' with new expiration of %d seconds\n",
934  contact_uri, aor_name, expiration);
935  ast_test_suite_event_notify("AOR_CONTACT_REFRESHED",
936  "Contact: %s\r\n"
937  "AOR: %s\r\n"
938  "Expiration: %d\r\n"
939  "UserAgent: %s",
940  contact_uri,
941  aor_name,
942  expiration,
943  contact_update->user_agent);
944  ao2_link(contacts, contact_update);
945  ao2_cleanup(contact_update);
946  } else {
947  registrar_contact_delete(CONTACT_DELETE_REQUEST, rdata->tp_info.transport,
948  contact, aor_name);
949  }
950  }
951 
952  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
953 
954  /*
955  * If the AOR is configured to remove any contacts over max_contacts
956  * that have not been updated/added/deleted as a result of this
957  * REGISTER do so.
958  *
959  * The existing contacts container holds all contacts that were not
960  * involved in this REGISTER.
961  * The contacts container holds the current contacts of the AOR.
962  */
963  if (aor->remove_existing && existing_contacts) {
964  /* Total contacts after this registration */
965  contact_count = ao2_container_count(existing_contacts) + updated + added;
966  if (contact_count > aor->max_contacts) {
967  /* Remove excess existing contacts that are unavailable or expire soonest */
968  remove_excess_contacts(existing_contacts, contacts, contact_count - aor->max_contacts,
969  aor->remove_existing);
970  }
971  ao2_ref(existing_contacts, -1);
972  }
973 
974  response_contact = ao2_callback(contacts, 0, NULL, NULL);
975 
976  /* Send a response containing all of the contacts (including static) that are present on this AOR */
977  if (ast_sip_create_response(rdata, 200, response_contact, &tdata) != PJ_SUCCESS) {
978  ao2_cleanup(response_contact);
979  ao2_cleanup(contacts);
980  response->code = 500;
981  return;
982  }
983  ao2_cleanup(response_contact);
984 
985  /* Add the date header to the response, some UAs use this to set their date and time */
986  ast_sip_add_date_header(tdata);
987 
988  ao2_callback(contacts, 0, registrar_add_contact, tdata);
989 
990  if ((expires_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL))) {
991  expires_hdr = pjsip_expires_hdr_create(tdata->pool, registrar_get_expiration(aor, NULL, rdata));
992  pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)expires_hdr);
993  }
994 
995  response->tdata = tdata;
996 }
997 
998 static int register_aor(pjsip_rx_data *rdata,
999  struct ast_sip_endpoint *endpoint,
1000  struct ast_sip_aor *aor,
1001  const char *aor_name)
1002 {
1003  struct aor_core_response response = {
1004  .code = 500,
1005  };
1006  struct ao2_container *contacts = NULL;
1007 
1008  ao2_lock(aor);
1009  contacts = ast_sip_location_retrieve_aor_contacts_nolock(aor);
1010  if (!contacts) {
1011  ao2_unlock(aor);
1012  pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(),
1013  rdata, response.code, NULL, NULL, NULL);
1014  return PJ_TRUE;
1015  }
1016 
1017  register_aor_core(rdata, endpoint, aor, aor_name, contacts, &response);
1018  ao2_cleanup(contacts);
1019  ao2_unlock(aor);
1020 
1021  /* Now send the REGISTER response to the peer */
1022  if (response.tdata) {
1023  ast_sip_send_stateful_response(rdata, response.tdata, endpoint);
1024  } else {
1025  pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(),
1026  rdata, response.code, NULL, NULL, NULL);
1027  }
1028  return PJ_TRUE;
1029 }
1030 
1031 static int match_aor(const char *aor_name, const char *id)
1032 {
1033  if (ast_strlen_zero(aor_name)) {
1034  return 0;
1035  }
1036 
1037  if (!strcmp(aor_name, id)) {
1038  ast_debug(3, "Matched id '%s' to aor '%s'\n", id, aor_name);
1039  return 1;
1040  }
1041 
1042  return 0;
1043 }
1044 
1045 static char *find_aor_name(const pj_str_t *pj_username, const pj_str_t *pj_domain, const char *aors)
1046 {
1047  char *configured_aors;
1048  char *aors_buf;
1049  char *aor_name;
1050  char *id_domain;
1051  char *username, *domain;
1052  struct ast_sip_domain_alias *alias;
1053 
1054  /* Turn these into C style strings for convenience */
1055  username = ast_alloca(pj_strlen(pj_username) + 1);
1056  ast_copy_pj_str(username, pj_username, pj_strlen(pj_username) + 1);
1057  domain = ast_alloca(pj_strlen(pj_domain) + 1);
1058  ast_copy_pj_str(domain, pj_domain, pj_strlen(pj_domain) + 1);
1059 
1060  id_domain = ast_alloca(strlen(username) + strlen(domain) + 2);
1061  sprintf(id_domain, "%s@%s", username, domain);
1062 
1063  aors_buf = ast_strdupa(aors);
1064 
1065  /* Look for exact match on username@domain */
1066  configured_aors = aors_buf;
1067  while ((aor_name = ast_strip(strsep(&configured_aors, ",")))) {
1068  if (match_aor(aor_name, id_domain)) {
1069  return ast_strdup(aor_name);
1070  }
1071  }
1072 
1073  /* If there's a domain alias, look for exact match on username@domain_alias */
1074  alias = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "domain_alias", domain);
1075  if (alias) {
1076  char *id_domain_alias = ast_alloca(strlen(username) + strlen(alias->domain) + 2);
1077 
1078  sprintf(id_domain_alias, "%s@%s", username, alias->domain);
1079  ao2_cleanup(alias);
1080 
1081  configured_aors = strcpy(aors_buf, aors);/* Safe */
1082  while ((aor_name = ast_strip(strsep(&configured_aors, ",")))) {
1083  if (match_aor(aor_name, id_domain_alias)) {
1084  return ast_strdup(aor_name);
1085  }
1086  }
1087  }
1088 
1089  if (ast_strlen_zero(username)) {
1090  /* No username, no match */
1091  return NULL;
1092  }
1093 
1094  /* Look for exact match on username only */
1095  configured_aors = strcpy(aors_buf, aors);/* Safe */
1096  while ((aor_name = ast_strip(strsep(&configured_aors, ",")))) {
1097  if (match_aor(aor_name, username)) {
1098  return ast_strdup(aor_name);
1099  }
1100  }
1101 
1102  return NULL;
1103 }
1104 
1105 static struct ast_sip_aor *find_registrar_aor(struct pjsip_rx_data *rdata, struct ast_sip_endpoint *endpoint)
1106 {
1107  struct ast_sip_aor *aor = NULL;
1108  char *aor_name = NULL;
1109  int i;
1110 
1111  for (i = 0; i < AST_VECTOR_SIZE(&endpoint->ident_method_order); ++i) {
1112  pj_str_t username;
1113  pjsip_sip_uri *uri;
1114  pjsip_authorization_hdr *header = NULL;
1115 
1116  switch (AST_VECTOR_GET(&endpoint->ident_method_order, i)) {
1117  case AST_SIP_ENDPOINT_IDENTIFY_BY_USERNAME:
1118  uri = pjsip_uri_get_uri(rdata->msg_info.to->uri);
1119 
1120  pj_strassign(&username, &uri->user);
1121 
1122  /*
1123  * We may want to match without any user options getting
1124  * in the way.
1125  *
1126  * Logic adapted from AST_SIP_USER_OPTIONS_TRUNCATE_CHECK for pj_str_t.
1127  */
1128  if (ast_sip_get_ignore_uri_user_options()) {
1129  pj_ssize_t semi = pj_strcspn2(&username, ";");
1130  if (semi < pj_strlen(&username)) {
1131  username.slen = semi;
1132  }
1133  }
1134 
1135  aor_name = find_aor_name(&username, &uri->host, endpoint->aors);
1136  if (aor_name) {
1137  ast_debug(3, "Matched aor '%s' by To username\n", aor_name);
1138  }
1139  break;
1140  case AST_SIP_ENDPOINT_IDENTIFY_BY_AUTH_USERNAME:
1141  while ((header = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_AUTHORIZATION,
1142  header ? header->next : NULL))) {
1143  if (header && !pj_stricmp2(&header->scheme, "digest")) {
1144  aor_name = find_aor_name(&header->credential.digest.username,
1145  &header->credential.digest.realm, endpoint->aors);
1146  if (aor_name) {
1147  ast_debug(3, "Matched aor '%s' by Authentication username\n", aor_name);
1148  break;
1149  }
1150  }
1151  }
1152  break;
1153  default:
1154  continue;
1155  }
1156 
1157  if (aor_name) {
1158  break;
1159  }
1160  }
1161 
1162  if (ast_strlen_zero(aor_name) || !(aor = ast_sip_location_retrieve_aor(aor_name))) {
1163  /* The provided AOR name was not found (be it within the configuration or sorcery itself) */
1164  pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 404, NULL, NULL, NULL);
1165  ast_sip_report_req_no_support(endpoint, rdata, "registrar_requested_aor_not_found");
1166  ast_log(LOG_WARNING, "AOR '%s' not found for endpoint '%s' (%s:%d)\n",
1167  aor_name ?: "", ast_sorcery_object_get_id(endpoint),
1168  rdata->pkt_info.src_name, rdata->pkt_info.src_port);
1169  }
1170  ast_free(aor_name);
1171  return aor;
1172 }
1173 
1174 static pj_bool_t registrar_on_rx_request(struct pjsip_rx_data *rdata)
1175 {
1176  RAII_VAR(struct ast_sip_endpoint *, endpoint,
1177  ast_pjsip_rdata_get_endpoint(rdata), ao2_cleanup);
1178  struct ast_sip_aor *aor;
1179  const char *aor_name;
1180 
1181  if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_register_method) || !endpoint) {
1182  return PJ_FALSE;
1183  }
1184 
1185  if (ast_strlen_zero(endpoint->aors)) {
1186  /* Short circuit early if the endpoint has no AORs configured on it, which means no registration possible */
1187  pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
1188  ast_sip_report_failed_acl(endpoint, rdata, "registrar_attempt_without_configured_aors");
1189  ast_log(LOG_WARNING, "Endpoint '%s' (%s:%d) has no configured AORs\n", ast_sorcery_object_get_id(endpoint),
1190  rdata->pkt_info.src_name, rdata->pkt_info.src_port);
1191  return PJ_TRUE;
1192  }
1193 
1194  if (!PJSIP_URI_SCHEME_IS_SIP(rdata->msg_info.to->uri) && !PJSIP_URI_SCHEME_IS_SIPS(rdata->msg_info.to->uri)) {
1195  pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 416, NULL, NULL, NULL);
1196  ast_sip_report_failed_acl(endpoint, rdata, "registrar_invalid_uri_in_to_received");
1197  ast_log(LOG_WARNING, "Endpoint '%s' (%s:%d) attempted to register to an AOR with a non-SIP URI\n", ast_sorcery_object_get_id(endpoint),
1198  rdata->pkt_info.src_name, rdata->pkt_info.src_port);
1199  return PJ_TRUE;
1200  }
1201 
1202  aor = find_registrar_aor(rdata, endpoint);
1203  if (!aor) {
1204  /* We've already responded about not finding an AOR. */
1205  return PJ_TRUE;
1206  }
1207 
1208  aor_name = ast_sorcery_object_get_id(aor);
1209 
1210  if (!aor->max_contacts) {
1211  /* Registration is not permitted for this AOR */
1212  pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
1213  ast_sip_report_req_no_support(endpoint, rdata, "registrar_attempt_without_registration_permitted");
1214  ast_log(LOG_WARNING, "AOR '%s' has no configured max_contacts. Endpoint '%s' (%s:%d) unable to register\n",
1215  aor_name, ast_sorcery_object_get_id(endpoint),
1216  rdata->pkt_info.src_name, rdata->pkt_info.src_port);
1217  } else {
1218  register_aor(rdata, endpoint, aor, aor_name);
1219  }
1220  ao2_ref(aor, -1);
1221  return PJ_TRUE;
1222 }
1223 
1224 /* function pointer to callback needs to be within the module
1225  in order to avoid problems with an undefined symbol */
1226 static int sip_contact_to_str(void *acp, void *arg, int flags)
1227 {
1228  return ast_sip_contact_to_str(acp, arg, flags);
1229 }
1230 
1231 static int ami_registrations_aor(void *obj, void *arg, int flags)
1232 {
1233  struct ast_sip_aor *aor = obj;
1234  struct ast_sip_ami *ami = arg;
1235  int *count = ami->arg;
1236  RAII_VAR(struct ast_str *, buf,
1237  ast_sip_create_ami_event("InboundRegistrationDetail", ami), ast_free);
1238 
1239  if (!buf) {
1240  return -1;
1241  }
1242 
1243  ast_sip_sorcery_object_to_ami(aor, &buf);
1244  ast_str_append(&buf, 0, "Contacts: ");
1245  ast_sip_for_each_contact(aor, sip_contact_to_str, &buf);
1246  ast_str_append(&buf, 0, "\r\n");
1247 
1248  astman_append(ami->s, "%s\r\n", ast_str_buffer(buf));
1249  (*count)++;
1250  return 0;
1251 }
1252 
1253 static int ami_registrations_endpoint(void *obj, void *arg, int flags)
1254 {
1255  struct ast_sip_endpoint *endpoint = obj;
1256  return ast_sip_for_each_aor(
1257  endpoint->aors, ami_registrations_aor, arg);
1258 }
1259 
1260 static int ami_registrations_endpoints(void *arg)
1261 {
1262  RAII_VAR(struct ao2_container *, endpoints,
1263  ast_sip_get_endpoints(), ao2_cleanup);
1264 
1265  if (!endpoints) {
1266  return 0;
1267  }
1268 
1269  ao2_callback(endpoints, OBJ_NODATA, ami_registrations_endpoint, arg);
1270  return 0;
1271 }
1272 
1273 static int ami_show_registrations(struct mansession *s, const struct message *m)
1274 {
1275  int count = 0;
1276  struct ast_sip_ami ami = { .s = s, .m = m, .arg = &count, .action_id = astman_get_header(m, "ActionID"), };
1277 
1278  astman_send_listack(s, m, "Following are Events for each Inbound registration",
1279  "start");
1280 
1281  ami_registrations_endpoints(&ami);
1282 
1283  astman_send_list_complete_start(s, m, "InboundRegistrationDetailComplete", count);
1285  return 0;
1286 }
1287 
1288 static int ami_show_registration_contact_statuses(struct mansession *s, const struct message *m)
1289 {
1290  int count = 0;
1291  struct ast_sip_ami ami = { .s = s, .m = m, .arg = NULL, .action_id = astman_get_header(m, "ActionID"), };
1292  struct ao2_container *contacts = ast_sorcery_retrieve_by_fields(
1293  ast_sip_get_sorcery(), "contact", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
1294  struct ao2_iterator i;
1295  struct ast_sip_contact *contact;
1296 
1297  astman_send_listack(s, m, "Following are ContactStatusEvents for each Inbound "
1298  "registration", "start");
1299 
1300  if (contacts) {
1301  i = ao2_iterator_init(contacts, 0);
1302  while ((contact = ao2_iterator_next(&i))) {
1303  struct ast_sip_contact_wrapper wrapper;
1304 
1305  wrapper.aor_id = (char *)contact->aor;
1306  wrapper.contact = contact;
1307  wrapper.contact_id = (char *)ast_sorcery_object_get_id(contact);
1308 
1309  ast_sip_format_contact_ami(&wrapper, &ami, 0);
1310  count++;
1311 
1312  ao2_ref(contact, -1);
1313  }
1315  ao2_ref(contacts, -1);
1316  }
1317 
1318  astman_send_list_complete_start(s, m, "ContactStatusDetailComplete", count);
1320  return 0;
1321 }
1322 
1323 #define AMI_SHOW_REGISTRATION_CONTACT_STATUSES "PJSIPShowRegistrationInboundContactStatuses"
1324 #define AMI_SHOW_REGISTRATIONS "PJSIPShowRegistrationsInbound"
1325 
1326 static pjsip_module registrar_module = {
1327  .name = { "Registrar", 9 },
1328  .id = -1,
1329  .priority = PJSIP_MOD_PRIORITY_APPLICATION,
1330  .on_rx_request = registrar_on_rx_request,
1331 };
1332 
1333 /*! \brief Thread keeping things alive */
1334 static pthread_t check_thread = AST_PTHREADT_NULL;
1335 
1336 /*! \brief The global interval at which to check for contact expiration */
1337 static unsigned int check_interval;
1338 
1339 /*! \brief Callback function which deletes a contact */
1340 static int expire_contact(void *obj, void *arg, int flags)
1341 {
1342  struct ast_sip_contact *contact = obj;
1343  struct ast_named_lock *lock;
1344 
1345  lock = ast_named_lock_get(AST_NAMED_LOCK_TYPE_MUTEX, "aor", contact->aor);
1346  if (!lock) {
1347  return 0;
1348  }
1349 
1350  /*
1351  * We need to check the expiration again with the aor lock held
1352  * in case another thread is attempting to renew the contact.
1353  */
1354  ao2_lock(lock);
1355  if (ast_tvdiff_ms(ast_tvnow(), contact->expiration_time) > 0) {
1356  registrar_contact_delete(CONTACT_DELETE_EXPIRE, NULL, contact, contact->aor);
1357  }
1358  ao2_unlock(lock);
1359  ast_named_lock_put(lock);
1360 
1361  return 0;
1362 }
1363 
1364 static void *check_expiration_thread(void *data)
1365 {
1366  struct ao2_container *contacts;
1367  struct ast_variable *var;
1368  char time[AST_TIME_T_LEN];
1369 
1370  while (check_interval) {
1371  sleep(check_interval);
1372 
1373  ast_time_t_to_string(ast_tvnow().tv_sec, time, sizeof(time));
1374 
1375  var = ast_variable_new("expiration_time <=", time, "");
1376 
1377  ast_debug(4, "Woke up at %s Interval: %d\n", time, check_interval);
1378 
1379  contacts = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "contact",
1381 
1382  ast_variables_destroy(var);
1383  if (contacts) {
1384  ast_debug(3, "Expiring %d contacts\n", ao2_container_count(contacts));
1385  ao2_callback(contacts, OBJ_NODATA, expire_contact, NULL);
1386  ao2_ref(contacts, -1);
1387  }
1388  }
1389 
1390  return NULL;
1391 }
1392 
1393 static void expiration_global_loaded(const char *object_type)
1394 {
1395  check_interval = ast_sip_get_contact_expiration_check_interval();
1396 
1397  /* Observer calls are serialized so this is safe without it's own lock */
1398  if (check_interval) {
1399  if (check_thread == AST_PTHREADT_NULL) {
1400  if (ast_pthread_create_background(&check_thread, NULL, check_expiration_thread, NULL)) {
1401  ast_log(LOG_ERROR, "Could not create thread for checking contact expiration.\n");
1402  return;
1403  }
1404  ast_debug(3, "Interval = %d, starting thread\n", check_interval);
1405  }
1406  } else {
1407  if (check_thread != AST_PTHREADT_NULL) {
1408  pthread_kill(check_thread, SIGURG);
1409  pthread_join(check_thread, NULL);
1410  check_thread = AST_PTHREADT_NULL;
1411  ast_debug(3, "Interval = 0, shutting thread down\n");
1412  }
1413  }
1414 }
1415 
1416 /*! \brief Observer which is used to update our interval when the global setting changes */
1417 static struct ast_sorcery_observer expiration_global_observer = {
1418  .loaded = expiration_global_loaded,
1419 };
1420 
1421 static int load_module(void)
1422 {
1423  const pj_str_t STR_REGISTER = { "REGISTER", 8 };
1424 
1425  ast_pjproject_get_buildopt("PJ_MAX_HOSTNAME", "%d", &pj_max_hostname);
1426  /* As of pjproject 2.4.5, PJSIP_MAX_URL_SIZE isn't exposed yet but we try anyway. */
1427  ast_pjproject_get_buildopt("PJSIP_MAX_URL_SIZE", "%d", &pjsip_max_url_size);
1428 
1429  if (ast_sip_register_service(&registrar_module)) {
1430  return AST_MODULE_LOAD_DECLINE;
1431  }
1432 
1433  if (pjsip_endpt_add_capability(ast_sip_get_pjsip_endpoint(), NULL, PJSIP_H_ALLOW, NULL, 1, &STR_REGISTER) != PJ_SUCCESS) {
1434  ast_sip_unregister_service(&registrar_module);
1435  return AST_MODULE_LOAD_DECLINE;
1436  }
1437 
1438  ast_manager_register_xml(AMI_SHOW_REGISTRATIONS, EVENT_FLAG_SYSTEM,
1439  ami_show_registrations);
1440  ast_manager_register_xml(AMI_SHOW_REGISTRATION_CONTACT_STATUSES, EVENT_FLAG_SYSTEM,
1441  ami_show_registration_contact_statuses);
1442 
1443  ast_sorcery_observer_add(ast_sip_get_sorcery(), "global", &expiration_global_observer);
1444  ast_sorcery_reload_object(ast_sip_get_sorcery(), "global");
1445 
1446  return AST_MODULE_LOAD_SUCCESS;
1447 }
1448 
1449 static int unload_module(void)
1450 {
1451  if (check_thread != AST_PTHREADT_NULL) {
1452  check_interval = 0;
1453  pthread_kill(check_thread, SIGURG);
1454  pthread_join(check_thread, NULL);
1455 
1456  check_thread = AST_PTHREADT_NULL;
1457  }
1458 
1459  ast_sorcery_observer_remove(ast_sip_get_sorcery(), "global", &expiration_global_observer);
1460 
1461  ast_manager_unregister(AMI_SHOW_REGISTRATIONS);
1462  ast_manager_unregister(AMI_SHOW_REGISTRATION_CONTACT_STATUSES);
1463  ast_sip_unregister_service(&registrar_module);
1464  ast_sip_transport_monitor_unregister_all(register_contact_transport_shutdown_cb, NULL, NULL);
1465  return 0;
1466 }
1467 
1468 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Registrar Support",
1469  .support_level = AST_MODULE_SUPPORT_CORE,
1470  .load = load_module,
1471  .unload = unload_module,
1472  .load_pri = AST_MODPRI_CHANNEL_DEPEND - 3,
1473  .requires = "res_pjproject,res_pjsip",
1474 );
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
int authenticate_qualify
Definition: res_pjsip.h:420
#define AST_VECTOR_ADD_SORTED(vec, elem, cmp)
Add an element into a sorted vector.
Definition: vector.h:371
A contact's status.
Definition: res_pjsip.h:451
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3310
Asterisk main include file. File version handling, generic pbx functions.
A SIP address of record.
Definition: res_pjsip.h:478
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262
const ast_string_field call_id
Definition: res_pjsip.h:414
const ast_string_field user_agent
Definition: res_pjsip.h:414
const ast_string_field path
Definition: res_pjsip.h:414
unsigned int remove_existing
Definition: res_pjsip.h:498
int ast_time_t_to_string(time_t time, char *buf, size_t length)
Converts to a string representation of a time_t as decimal seconds since the epoch. Returns -1 on failure, zero otherwise.
Definition: time.c:152
const struct message * m
Definition: res_pjsip.h:3035
unsigned int max_contacts
Definition: res_pjsip.h:496
void astman_send_list_complete_start(struct mansession *s, const struct message *m, const char *event_name, int count)
Start the list complete event.
Definition: manager.c:3467
const ast_string_field via_addr
Definition: res_pjsip.h:414
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
pjsip_tx_data * tdata
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
Definition: astobj2.h:1693
void * arg
Definition: res_pjsip.h:3039
AMI variable container.
Definition: res_pjsip.h:3031
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Definition: astobj2.h:1327
Structure for variables, used for configurations and for channel variables.
static pj_pool_t * pool
Global memory pool for configuration and timers.
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:117
Test Framework API.
Perform no matching, return all objects.
Definition: sorcery.h:123
int ast_sorcery_object_id_compare(void *obj, void *arg, int flags)
ao2 object comparator based on sorcery id.
Definition: sorcery.c:2464
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139
unsigned int qualify_frequency
Definition: res_pjsip.h:418
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
Return all matching objects.
Definition: sorcery.h:120
void ast_sip_report_req_no_support(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, const char *req_type)
Send a security event notification for when a request is not supported.
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:107
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
const ast_string_field reg_server
Definition: res_pjsip.h:414
pjsip_sip_uri * uri
URI being looked for.
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition: manager.c:3050
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
Definition: sorcery.c:1853
struct ast_sip_endpoint * endpoint
Definition: res_pjsip.h:424
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1113
unsigned int qualify_frequency
Definition: res_pjsip.h:492
unsigned int remove_unavailable
Definition: res_pjsip.h:508
struct ast_sip_identify_by_vector ident_method_order
Definition: res_pjsip.h:1000
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
ast_mutex_t lock
A wrapper for contact that adds the aor_id and a consistent contact id. Used by ast_sip_for_each_cont...
Definition: res_pjsip.h:515
Asterisk file paths, configured in asterisk.conf.
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:3475
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:223
In case you didn't read that giant block of text above the mansession_session struct, the mansession is named this solely to keep the API the same in Asterisk. This structure really represents data that is different from Manager action to Manager action. The mansession_session pointer contained within points to session-specific data.
Definition: manager.c:1785
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
Definition: time.h:282
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2317
struct mansession * s
Definition: res_pjsip.h:3033
struct ao2_container * container
Definition: res_fax.c:501
int ast_pjproject_get_buildopt(char *option, char *format_string,...)
Retrieve a pjproject build option.
#define ast_debug(level,...)
Log a DEBUG message.
#define AST_VECTOR(name, type)
Define a vector structure.
Definition: vector.h:44
char * contact_name
Sorcery contact name to remove on transport shutdown.
An entity with which Asterisk communicates.
Definition: res_pjsip.h:949
unsigned int support_path
Definition: res_pjsip.h:502
Named Locks.
enum ast_transport_monitor_reg ast_sip_transport_monitor_register_replace(pjsip_transport *transport, ast_transport_monitor_shutdown_cb cb, void *ao2_data, ast_transport_monitor_data_matcher matches)
Register a reliable transport shutdown monitor callback replacing any duplicate.
int ast_sorcery_observer_add(const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks)
Add an observer to a specific object type.
Definition: sorcery.c:2391
enum ast_sip_contact_status_type status
Definition: res_pjsip.h:468
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:189
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:288
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:8057
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
int ast_tvcmp(struct timeval _a, struct timeval _b)
Compress two struct timeval instances returning -1, 0, 1 if the first arg is smaller, equal or greater to the second.
Definition: time.h:137
Support for dynamic strings.
Definition: strings.h:623
#define ao2_unlink(container, obj)
Remove an object from a container.
Definition: astobj2.h:1578
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
Definition: res_pjsip.c:2099
pj_pool_t * pool
Pool used for parsing URI.
Interface for a sorcery object type observer.
Definition: sorcery.h:332
Contact associated with an address of record.
Definition: res_pjsip.h:392
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2282
void ast_sip_report_failed_acl(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, const char *name)
Send a security event notification for when an ACL check fails.
static struct stasis_rest_handlers endpoints
REST handler for /api-docs/endpoints.json.
struct timeval expiration_time
Definition: res_pjsip.h:416
void ast_sip_transport_monitor_unregister_all(ast_transport_monitor_shutdown_cb cb, void *data, ast_transport_monitor_data_matcher matches)
Unregister a transport shutdown monitor from all reliable transports.
struct ao2_container * permanent_contacts
Definition: res_pjsip.h:500
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
void ast_sip_transport_monitor_unregister(pjsip_transport *transport, ast_transport_monitor_shutdown_cb cb, void *data, ast_transport_monitor_data_matcher matches)
Unregister a reliable transport shutdown monitor.
An API for managing task processing threads that can be shared across modules.
void(* loaded)(const char *object_type)
Callback for when an object type is loaded/reloaded.
Definition: sorcery.h:343
void * ast_sorcery_retrieve_by_fields(const struct ast_sorcery *sorcery, const char *type, unsigned int flags, struct ast_variable *fields)
Retrieve an object or multiple objects using specific fields.
Definition: sorcery.c:1897
const ast_string_field aor
Definition: res_pjsip.h:414
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:680
void ast_sorcery_observer_remove(const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks)
Remove an observer from a specific object type.
Definition: sorcery.c:2423
const ast_string_field domain
Definition: res_pjsip.h:323
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
void * ast_sorcery_copy(const struct ast_sorcery *sorcery, const void *object)
Create a copy of an object.
Definition: sorcery.c:1778
Structure used for finding contact.
int authenticate_qualify
Definition: res_pjsip.h:494
Generic container type.
const ast_string_field aors
Definition: res_pjsip.h:958
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:191
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
const ast_string_field uri
Definition: res_pjsip.h:414
Asterisk module definitions.
unsigned int minimum_expiration
Definition: res_pjsip.h:486
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
unsigned int default_expiration
Definition: res_pjsip.h:490
unsigned int maximum_expiration
Definition: res_pjsip.h:488
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
void ast_sorcery_reload_object(const struct ast_sorcery *sorcery, const char *type)
Inform any wizards of a specific object type to reload persistent objects.
Definition: sorcery.c:1442
#define ast_named_lock_get(lock_type, keyspace, key)
Geta named lock handle.
Definition: named_locks.h:83
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
#define ast_named_lock_put(lock)
Put a named lock handle away.
Definition: named_locks.h:93
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager transaction to begin a list.
Definition: manager.c:3431
#define AST_VECTOR_MAX_SIZE(vec)
Get the maximum number of elements the vector can currently hold.
Definition: vector.h:617
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532