Asterisk - The Open Source Telephony Project  21.4.1
pjsip_distributor.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * Mark Michelson <mmichelson@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 #include "asterisk.h"
20 
21 #include <pjsip.h>
22 
23 #include "asterisk/res_pjsip.h"
24 #include "asterisk/acl.h"
25 #include "include/res_pjsip_private.h"
26 #include "asterisk/taskprocessor.h"
27 #include "asterisk/threadpool.h"
28 #include "asterisk/res_pjsip_cli.h"
29 
30 static int distribute(void *data);
31 static pj_bool_t distributor(pjsip_rx_data *rdata);
32 static pj_status_t record_serializer(pjsip_tx_data *tdata);
33 
34 static pjsip_module distributor_mod = {
35  .name = {"Request Distributor", 19},
36  .priority = PJSIP_MOD_PRIORITY_TSX_LAYER - 6,
37  .on_tx_request = record_serializer,
38  .on_rx_request = distributor,
39  .on_rx_response = distributor,
40 };
41 
42 struct ast_sched_context *prune_context;
43 
44 #define DEFAULT_SUSPECTS_BUCKETS 53
45 
46 static struct ao2_container *unidentified_requests;
47 static unsigned int unidentified_count;
48 static unsigned int unidentified_period;
49 static unsigned int unidentified_prune_interval;
50 static int using_auth_username;
51 static enum ast_sip_taskprocessor_overload_trigger overload_trigger;
52 
54  struct timeval first_seen;
55  int count;
56  char src_name[];
57 };
58 
59 /*! Number of serializers in pool if one not otherwise known. (Best if prime number) */
60 #define DISTRIBUTOR_POOL_SIZE 31
61 
62 /*! Pool of serializers to use if not supplied. */
63 static struct ast_taskprocessor *distributor_pool[DISTRIBUTOR_POOL_SIZE];
64 
65 /*!
66  * \internal
67  * \brief Record the task's serializer name on the tdata structure.
68  * \since 14.0.0
69  *
70  * \param tdata The outgoing message.
71  *
72  * \retval PJ_SUCCESS.
73  */
74 static pj_status_t record_serializer(pjsip_tx_data *tdata)
75 {
77 
78  serializer = ast_threadpool_serializer_get_current();
79  if (serializer) {
80  const char *name;
81 
82  name = ast_taskprocessor_name(serializer);
83  if (!ast_strlen_zero(name)
84  && (!tdata->mod_data[distributor_mod.id]
85  || strcmp(tdata->mod_data[distributor_mod.id], name))) {
86  char *tdata_name;
87 
88  /* The serializer in use changed. */
89  tdata_name = pj_pool_alloc(tdata->pool, strlen(name) + 1);
90  strcpy(tdata_name, name);/* Safe */
91 
92  tdata->mod_data[distributor_mod.id] = tdata_name;
93  }
94  }
95 
96  return PJ_SUCCESS;
97 }
98 
99 /*!
100  * \internal
101  * \brief Find the request tdata to get the serializer it used.
102  * \since 14.0.0
103  *
104  * \param rdata The incoming message.
105  *
106  * \retval serializer on success.
107  * \retval NULL on error or could not find the serializer.
108  */
109 static struct ast_taskprocessor *find_request_serializer(pjsip_rx_data *rdata)
110 {
111  struct ast_taskprocessor *serializer = NULL;
112  pj_str_t tsx_key;
113  pjsip_transaction *tsx;
114 
115  pjsip_tsx_create_key(rdata->tp_info.pool, &tsx_key, PJSIP_ROLE_UAC,
116  &rdata->msg_info.cseq->method, rdata);
117 
118  tsx = pjsip_tsx_layer_find_tsx(&tsx_key, PJ_TRUE);
119  if (!tsx) {
120  ast_debug(1, "Could not find transaction for %s.\n",
121  pjsip_rx_data_get_info(rdata));
122  return NULL;
123  }
124  ast_debug(3, "Found transaction %s for %s.\n",
125  tsx->obj_name, pjsip_rx_data_get_info(rdata));
126 
127  if (tsx->last_tx) {
128  const char *serializer_name;
129 
130  serializer_name = tsx->last_tx->mod_data[distributor_mod.id];
131  if (!ast_strlen_zero(serializer_name)) {
132  serializer = ast_taskprocessor_get(serializer_name, TPS_REF_IF_EXISTS);
133  if (serializer) {
134  ast_debug(3, "Found serializer %s on transaction %s\n",
135  serializer_name, tsx->obj_name);
136  }
137  }
138  }
139 
140 #ifdef HAVE_PJ_TRANSACTION_GRP_LOCK
141  pj_grp_lock_release(tsx->grp_lock);
142 #else
143  pj_mutex_unlock(tsx->mutex);
144 #endif
145 
146  return serializer;
147 }
148 
149 /*! Dialog-specific information the distributor uses */
151  /*! dialog_associations ao2 container key */
152  pjsip_dialog *dlg;
153  /*! Serializer to distribute tasks to for this dialog */
155  /*! Endpoint associated with this dialog */
157 };
158 
159 #define DIALOG_ASSOCIATIONS_BUCKETS 251
160 
161 static struct ao2_container *dialog_associations;
162 
163 /*!
164  * \internal
165  * \brief Compute a hash value on an arbitrary buffer.
166  * \since 13.17.0
167  *
168  * \param[in] pos The buffer to add to the hash
169  * \param[in] len The buffer length to add to the hash
170  * \param[in] hash The hash value to add to
171  *
172  * \details
173  * This version of the function is for when you need to compute a
174  * hash of more than one buffer.
175  *
176  * This famous hash algorithm was written by Dan Bernstein and is
177  * commonly used.
178  *
179  * \sa http://www.cse.yorku.ca/~oz/hash.html
180  */
181 static int buf_hash_add(const char *pos, size_t len, int hash)
182 {
183  while (len--) {
184  hash = hash * 33 ^ *pos++;
185  }
186 
187  return hash;
188 }
189 
190 /*!
191  * \internal
192  * \brief Compute a hash value on an arbitrary buffer.
193  * \since 13.17.0
194  *
195  * \param[in] pos The buffer to add to the hash
196  * \param[in] len The buffer length to add to the hash
197  *
198  * \details
199  * This version of the function is for when you need to compute a
200  * hash of more than one buffer.
201  *
202  * This famous hash algorithm was written by Dan Bernstein and is
203  * commonly used.
204  *
205  * \sa http://www.cse.yorku.ca/~oz/hash.html
206  */
207 static int buf_hash(const char *pos, size_t len)
208 {
209  return buf_hash_add(pos, len, 5381);
210 }
211 
212 static int dialog_associations_hash(const void *obj, int flags)
213 {
214  const struct distributor_dialog_data *object;
215  union {
216  const pjsip_dialog *dlg;
217  const char buf[sizeof(pjsip_dialog *)];
218  } key;
219 
220  switch (flags & OBJ_SEARCH_MASK) {
221  case OBJ_SEARCH_KEY:
222  key.dlg = obj;
223  break;
224  case OBJ_SEARCH_OBJECT:
225  object = obj;
226  key.dlg = object->dlg;
227  break;
228  default:
229  /* Hash can only work on something with a full key. */
230  ast_assert(0);
231  return 0;
232  }
233  return ast_str_hash_restrict(buf_hash(key.buf, sizeof(key.buf)));
234 }
235 
236 static int dialog_associations_cmp(void *obj, void *arg, int flags)
237 {
238  const struct distributor_dialog_data *object_left = obj;
239  const struct distributor_dialog_data *object_right = arg;
240  const pjsip_dialog *right_key = arg;
241  int cmp = 0;
242 
243  switch (flags & OBJ_SEARCH_MASK) {
244  case OBJ_SEARCH_OBJECT:
245  right_key = object_right->dlg;
246  /* Fall through */
247  case OBJ_SEARCH_KEY:
248  if (object_left->dlg == right_key) {
249  cmp = CMP_MATCH;
250  }
251  break;
253  /* There is no such thing for this container. */
254  ast_assert(0);
255  break;
256  default:
257  cmp = 0;
258  break;
259  }
260  return cmp;
261 }
262 
263 void ast_sip_dialog_set_serializer(pjsip_dialog *dlg, struct ast_taskprocessor *serializer)
264 {
265  struct distributor_dialog_data *dist;
266 
267  ao2_wrlock(dialog_associations);
268  dist = ao2_find(dialog_associations, dlg, OBJ_SEARCH_KEY | OBJ_NOLOCK);
269  if (!dist) {
270  if (serializer) {
271  dist = ao2_alloc(sizeof(*dist), NULL);
272  if (dist) {
273  dist->dlg = dlg;
274  dist->serializer = serializer;
275  ao2_link_flags(dialog_associations, dist, OBJ_NOLOCK);
276  ao2_ref(dist, -1);
277  }
278  }
279  } else {
280  ao2_lock(dist);
281  dist->serializer = serializer;
282  if (!dist->serializer && !dist->endpoint) {
283  ao2_unlink_flags(dialog_associations, dist, OBJ_NOLOCK);
284  }
285  ao2_unlock(dist);
286  ao2_ref(dist, -1);
287  }
288  ao2_unlock(dialog_associations);
289 }
290 
292 {
293  struct distributor_dialog_data *dist;
294 
295  ao2_wrlock(dialog_associations);
296  dist = ao2_find(dialog_associations, dlg, OBJ_SEARCH_KEY | OBJ_NOLOCK);
297  if (!dist) {
298  if (endpoint) {
299  dist = ao2_alloc(sizeof(*dist), NULL);
300  if (dist) {
301  dist->dlg = dlg;
302  dist->endpoint = endpoint;
303  ao2_link_flags(dialog_associations, dist, OBJ_NOLOCK);
304  ao2_ref(dist, -1);
305  }
306  }
307  } else {
308  ao2_lock(dist);
309  dist->endpoint = endpoint;
310  if (!dist->serializer && !dist->endpoint) {
311  ao2_unlink_flags(dialog_associations, dist, OBJ_NOLOCK);
312  }
313  ao2_unlock(dist);
314  ao2_ref(dist, -1);
315  }
316  ao2_unlock(dialog_associations);
317 }
318 
320 {
321  struct distributor_dialog_data *dist;
322  struct ast_sip_endpoint *endpoint;
323 
324  dist = ao2_find(dialog_associations, dlg, OBJ_SEARCH_KEY);
325  if (dist) {
326  ao2_lock(dist);
327  endpoint = ao2_bump(dist->endpoint);
328  ao2_unlock(dist);
329  ao2_ref(dist, -1);
330  } else {
331  endpoint = NULL;
332  }
333  return endpoint;
334 }
335 
336 static pjsip_dialog *find_dialog(pjsip_rx_data *rdata)
337 {
338  pj_str_t tsx_key;
339  pjsip_transaction *tsx;
340  pjsip_dialog *dlg;
341  pj_str_t *local_tag;
342  pj_str_t *remote_tag;
343 
344  if (!rdata->msg_info.msg) {
345  return NULL;
346  }
347 
348  if (rdata->msg_info.msg->type == PJSIP_REQUEST_MSG) {
349  local_tag = &rdata->msg_info.to->tag;
350  remote_tag = &rdata->msg_info.from->tag;
351  } else {
352  local_tag = &rdata->msg_info.from->tag;
353  remote_tag = &rdata->msg_info.to->tag;
354  }
355 
356  /* We can only call the convenient method for
357  * 1) responses
358  * 2) non-CANCEL requests
359  * 3) CANCEL requests with a to-tag
360  */
361  if (rdata->msg_info.msg->type == PJSIP_RESPONSE_MSG ||
362  pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_cancel_method) ||
363  rdata->msg_info.to->tag.slen != 0) {
364  dlg = pjsip_ua_find_dialog(&rdata->msg_info.cid->id, local_tag,
365  remote_tag, PJ_FALSE);
366  if (dlg) {
367  return dlg;
368  }
369  }
370 
371  /*
372  * There may still be a matching dialog if this is
373  * 1) an incoming CANCEL request without a to-tag
374  * 2) an incoming response to a dialog-creating request.
375  */
376  if (rdata->msg_info.msg->type == PJSIP_REQUEST_MSG) {
377  /* CANCEL requests will need to match the INVITE we initially received. Any
378  * other request type will either have been matched already or is not in
379  * dialog
380  */
381  pjsip_tsx_create_key(rdata->tp_info.pool, &tsx_key, PJSIP_ROLE_UAS,
382  pjsip_get_invite_method(), rdata);
383  } else {
384  pjsip_tsx_create_key(rdata->tp_info.pool, &tsx_key, PJSIP_ROLE_UAC,
385  &rdata->msg_info.cseq->method, rdata);
386  }
387 
388  tsx = pjsip_tsx_layer_find_tsx(&tsx_key, PJ_TRUE);
389  if (!tsx) {
390  ast_debug(3, "Could not find matching transaction for %s\n",
391  pjsip_rx_data_get_info(rdata));
392  return NULL;
393  }
394 
395  dlg = pjsip_tsx_get_dlg(tsx);
396 
397 #ifdef HAVE_PJ_TRANSACTION_GRP_LOCK
398  pj_grp_lock_release(tsx->grp_lock);
399 #else
400  pj_mutex_unlock(tsx->mutex);
401 #endif
402 
403  return dlg;
404 }
405 
406 /*!
407  * \internal
408  * \brief Compute a hash value on a pjlib string
409  * \since 13.10.0
410  *
411  * \param[in] str The pjlib string to add to the hash
412  * \param[in] hash The hash value to add to
413  *
414  * \details
415  * This version of the function is for when you need to compute a
416  * string hash of more than one string.
417  *
418  * This famous hash algorithm was written by Dan Bernstein and is
419  * commonly used.
420  *
421  * \sa http://www.cse.yorku.ca/~oz/hash.html
422  */
423 static int pjstr_hash_add(pj_str_t *str, int hash)
424 {
425  return buf_hash_add(pj_strbuf(str), pj_strlen(str), hash);
426 }
427 
428 /*!
429  * \internal
430  * \brief Compute a hash value on a pjlib string
431  * \since 13.10.0
432  *
433  * \param[in] str The pjlib string to hash
434  *
435  * This famous hash algorithm was written by Dan Bernstein and is
436  * commonly used.
437  *
438  * http://www.cse.yorku.ca/~oz/hash.html
439  */
440 static int pjstr_hash(pj_str_t *str)
441 {
442  return pjstr_hash_add(str, 5381);
443 }
444 
446 {
447  int hash;
448  pj_str_t *remote_tag;
449  struct ast_taskprocessor *serializer;
450 
451  if (!rdata->msg_info.msg) {
452  return NULL;
453  }
454 
455  if (rdata->msg_info.msg->type == PJSIP_REQUEST_MSG) {
456  remote_tag = &rdata->msg_info.from->tag;
457  } else {
458  remote_tag = &rdata->msg_info.to->tag;
459  }
460 
461  /* Compute the hash from the SIP message call-id and remote-tag */
462  hash = pjstr_hash(&rdata->msg_info.cid->id);
463  hash = pjstr_hash_add(remote_tag, hash);
464  hash = ast_str_hash_restrict(hash);
465 
466  serializer = ao2_bump(distributor_pool[hash % ARRAY_LEN(distributor_pool)]);
467  if (serializer) {
468  ast_debug(3, "Calculated serializer %s to use for %s\n",
469  ast_taskprocessor_name(serializer), pjsip_rx_data_get_info(rdata));
470  }
471  return serializer;
472 }
473 
474 static pj_bool_t endpoint_lookup(pjsip_rx_data *rdata);
475 
476 static pjsip_module endpoint_mod = {
477  .name = {"Endpoint Identifier", 19},
478  .priority = PJSIP_MOD_PRIORITY_TSX_LAYER - 3,
479  .on_rx_request = endpoint_lookup,
480 };
481 
482 static pj_bool_t distributor(pjsip_rx_data *rdata)
483 {
484  pjsip_dialog *dlg;
485  struct distributor_dialog_data *dist = NULL;
486  struct ast_taskprocessor *serializer = NULL;
487  pjsip_rx_data *clone;
488 
489  if (!ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED)) {
490  /*
491  * Ignore everything until we are fully booted. Let the
492  * peer retransmit messages until we are ready.
493  */
494  return PJ_TRUE;
495  }
496 
497  dlg = find_dialog(rdata);
498  if (dlg) {
499  ast_debug(3, "Searching for serializer associated with dialog %s for %s\n",
500  dlg->obj_name, pjsip_rx_data_get_info(rdata));
501  dist = ao2_find(dialog_associations, dlg, OBJ_SEARCH_KEY);
502  if (dist) {
503  ao2_lock(dist);
504  serializer = ao2_bump(dist->serializer);
505  ao2_unlock(dist);
506  if (serializer) {
507  ast_debug(3, "Found serializer %s associated with dialog %s\n",
508  ast_taskprocessor_name(serializer), dlg->obj_name);
509  }
510  }
511  }
512 
513  if (serializer) {
514  /* We have a serializer so we know where to send the message. */
515  } else if (rdata->msg_info.msg->type == PJSIP_RESPONSE_MSG) {
516  ast_debug(3, "No dialog serializer for %s. Using request transaction as basis.\n",
517  pjsip_rx_data_get_info(rdata));
518  serializer = find_request_serializer(rdata);
519  if (!serializer) {
520  /*
521  * Pick a serializer for the unmatched response.
522  * We couldn't determine what serializer originally
523  * sent the request or the serializer is gone.
524  */
525  serializer = ast_sip_get_distributor_serializer(rdata);
526  }
527  } else if (!pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_cancel_method)
528  || !pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_bye_method)) {
529  /* We have a BYE or CANCEL request without a serializer. */
530  pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata,
531  PJSIP_SC_CALL_TSX_DOES_NOT_EXIST, NULL, NULL, NULL);
532  ao2_cleanup(dist);
533  return PJ_TRUE;
534  } else {
535  if ((overload_trigger == TASKPROCESSOR_OVERLOAD_TRIGGER_GLOBAL &&
537  || (overload_trigger == TASKPROCESSOR_OVERLOAD_TRIGGER_PJSIP_ONLY &&
539  /*
540  * When taskprocessors get backed up, there is a good chance that
541  * we are being overloaded and need to defer adding new work to
542  * the system. To defer the work we will ignore the request and
543  * rely on the peer's transport layer to retransmit the message.
544  * We usually work off the overload within a few seconds.
545  * If transport is non-UDP we send a 503 response instead.
546  */
547  switch (rdata->tp_info.transport->key.type) {
548  case PJSIP_TRANSPORT_UDP6:
549  case PJSIP_TRANSPORT_UDP:
550  ast_debug(3, "Taskprocessor overload alert: Ignoring '%s'.\n",
551  pjsip_rx_data_get_info(rdata));
552  break;
553  default:
554  ast_debug(3, "Taskprocessor overload on non-udp transport. Received:'%s'. "
555  "Responding with a 503.\n", pjsip_rx_data_get_info(rdata));
556  pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata,
557  PJSIP_SC_SERVICE_UNAVAILABLE, NULL, NULL, NULL);
558  break;
559  }
560  ao2_cleanup(dist);
561  return PJ_TRUE;
562  }
563 
564  /* Pick a serializer for the out-of-dialog request. */
565  serializer = ast_sip_get_distributor_serializer(rdata);
566  }
567 
568  if (pjsip_rx_data_clone(rdata, 0, &clone) != PJ_SUCCESS) {
569  ast_taskprocessor_unreference(serializer);
570  ao2_cleanup(dist);
571  return PJ_TRUE;
572  }
573 
574  if (dist) {
575  ao2_lock(dist);
576  clone->endpt_info.mod_data[endpoint_mod.id] = ao2_bump(dist->endpoint);
577  ao2_unlock(dist);
578  ao2_cleanup(dist);
579  }
580 
581  if (ast_sip_push_task(serializer, distribute, clone)) {
582  ao2_cleanup(clone->endpt_info.mod_data[endpoint_mod.id]);
583  pjsip_rx_data_free_cloned(clone);
584  }
585 
586  ast_taskprocessor_unreference(serializer);
587 
588  return PJ_TRUE;
589 }
590 
591 static struct ast_sip_auth *alloc_artificial_auth(char *default_realm)
592 {
593  struct ast_sip_auth *fake_auth;
594 
595  fake_auth = ast_sorcery_alloc(ast_sip_get_sorcery(), SIP_SORCERY_AUTH_TYPE,
596  "artificial");
597  if (!fake_auth) {
598  return NULL;
599  }
600 
601  ast_string_field_set(fake_auth, realm, default_realm);
602  ast_string_field_set(fake_auth, auth_user, "");
603  ast_string_field_set(fake_auth, auth_pass, "");
604  fake_auth->type = AST_SIP_AUTH_TYPE_ARTIFICIAL;
605 
606  return fake_auth;
607 }
608 
609 static AO2_GLOBAL_OBJ_STATIC(artificial_auth);
610 
611 static int create_artificial_auth(void)
612 {
613  char default_realm[AST_SIP_AUTH_MAX_REALM_LENGTH + 1];
614  struct ast_sip_auth *fake_auth;
615 
616  ast_sip_get_default_realm(default_realm, sizeof(default_realm));
617  fake_auth = alloc_artificial_auth(default_realm);
618  if (!fake_auth) {
619  ast_log(LOG_ERROR, "Unable to create artificial auth\n");
620  return -1;
621  }
622 
623  ao2_global_obj_replace_unref(artificial_auth, fake_auth);
624  ao2_ref(fake_auth, -1);
625  return 0;
626 }
627 
628 struct ast_sip_auth *ast_sip_get_artificial_auth(void)
629 {
630  return ao2_global_obj_ref(artificial_auth);
631 }
632 
633 static struct ast_sip_endpoint *artificial_endpoint = NULL;
634 
635 static int create_artificial_endpoint(void)
636 {
637  artificial_endpoint = ast_sorcery_alloc(ast_sip_get_sorcery(), "endpoint", NULL);
638  if (!artificial_endpoint) {
639  return -1;
640  }
641 
642  AST_VECTOR_INIT(&artificial_endpoint->inbound_auths, 1);
643  /* Pushing a bogus value into the vector will ensure that
644  * the proper size of the vector is returned. This value is
645  * not actually used anywhere
646  */
647  AST_VECTOR_APPEND(&artificial_endpoint->inbound_auths, ast_strdup("artificial-auth"));
648  return 0;
649 }
650 
651 struct ast_sip_endpoint *ast_sip_get_artificial_endpoint(void)
652 {
653  ao2_ref(artificial_endpoint, +1);
654  return artificial_endpoint;
655 }
656 
657 static void log_failed_request(pjsip_rx_data *rdata, char *msg, unsigned int count, unsigned int period)
658 {
659  char from_buf[PJSIP_MAX_URL_SIZE];
660  char callid_buf[PJSIP_MAX_URL_SIZE];
661  char method_buf[PJSIP_MAX_URL_SIZE];
662  char src_addr_buf[AST_SOCKADDR_BUFLEN];
663  pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, rdata->msg_info.from->uri, from_buf, PJSIP_MAX_URL_SIZE);
664  ast_copy_pj_str(callid_buf, &rdata->msg_info.cid->id, PJSIP_MAX_URL_SIZE);
665  ast_copy_pj_str(method_buf, &rdata->msg_info.msg->line.req.method.name, PJSIP_MAX_URL_SIZE);
666  if (count) {
667  ast_log(LOG_NOTICE, "Request '%s' from '%s' failed for '%s' (callid: %s) - %s"
668  " after %u tries in %.3f ms\n",
669  method_buf, from_buf,
670  pj_sockaddr_print(&rdata->pkt_info.src_addr, src_addr_buf, sizeof(src_addr_buf), 3),
671  callid_buf, msg, count, period / 1000.0);
672  } else {
673  ast_log(LOG_NOTICE, "Request '%s' from '%s' failed for '%s' (callid: %s) - %s\n",
674  method_buf, from_buf,
675  pj_sockaddr_print(&rdata->pkt_info.src_addr, src_addr_buf, sizeof(src_addr_buf), 3),
676  callid_buf, msg);
677  }
678 }
679 
680 static void check_endpoint(pjsip_rx_data *rdata, struct unidentified_request *unid,
681  const char *name)
682 {
683  int64_t ms = ast_tvdiff_ms(ast_tvnow(), unid->first_seen);
684 
685  ao2_wrlock(unid);
686  unid->count++;
687 
688  if (ms < (unidentified_period * 1000) && unid->count >= unidentified_count) {
689  log_failed_request(rdata, "No matching endpoint found", unid->count, ms);
690  ast_sip_report_invalid_endpoint(name, rdata);
691  }
692  ao2_unlock(unid);
693 }
694 
695 static int apply_endpoint_acl(pjsip_rx_data *rdata, struct ast_sip_endpoint *endpoint);
696 static int apply_endpoint_contact_acl(pjsip_rx_data *rdata, struct ast_sip_endpoint *endpoint);
697 
698 static void apply_acls(pjsip_rx_data *rdata)
699 {
700  struct ast_sip_endpoint *endpoint;
701 
702  /* Is the endpoint allowed with the source or contact address? */
703  endpoint = rdata->endpt_info.mod_data[endpoint_mod.id];
704  if (endpoint != artificial_endpoint
705  && (apply_endpoint_acl(rdata, endpoint)
706  || apply_endpoint_contact_acl(rdata, endpoint))) {
707  ast_debug(1, "Endpoint '%s' not allowed by ACL\n",
708  ast_sorcery_object_get_id(endpoint));
709 
710  /* Replace the rdata endpoint with the artificial endpoint. */
711  ao2_replace(rdata->endpt_info.mod_data[endpoint_mod.id], artificial_endpoint);
712  }
713 }
714 
715 static pj_bool_t endpoint_lookup(pjsip_rx_data *rdata)
716 {
717  struct ast_sip_endpoint *endpoint;
718  struct unidentified_request *unid;
719  int is_ack = rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD;
720 
721  endpoint = rdata->endpt_info.mod_data[endpoint_mod.id];
722  if (endpoint) {
723  /*
724  * ao2_find with OBJ_UNLINK always write locks the container before even searching
725  * for the object. Since the majority case is that the object won't be found, do
726  * the find without OBJ_UNLINK to prevent the unnecessary write lock, then unlink
727  * if needed.
728  */
729  unid = ao2_find(unidentified_requests, rdata->pkt_info.src_name, OBJ_SEARCH_KEY);
730  if (unid) {
731  ao2_unlink(unidentified_requests, unid);
732  ao2_ref(unid, -1);
733  }
734  apply_acls(rdata);
735  return PJ_FALSE;
736  }
737 
738  endpoint = ast_sip_identify_endpoint(rdata);
739  if (endpoint) {
740  unid = ao2_find(unidentified_requests, rdata->pkt_info.src_name, OBJ_SEARCH_KEY);
741  if (unid) {
742  ao2_unlink(unidentified_requests, unid);
743  ao2_ref(unid, -1);
744  }
745  }
746 
747  if (!endpoint) {
748  /* always use an artificial endpoint - per discussion no reason
749  to have "alwaysauthreject" as an option. It is felt using it
750  was a bug fix and it is not needed since we are not worried about
751  breaking old stuff and we really don't want to enable the discovery
752  of SIP accounts */
753  endpoint = ast_sip_get_artificial_endpoint();
754  }
755 
756  /* endpoint ref held by mod_data[] */
757  rdata->endpt_info.mod_data[endpoint_mod.id] = endpoint;
758 
759  if (endpoint == artificial_endpoint && !is_ack) {
760  char name[AST_UUID_STR_LEN] = "";
761  pjsip_uri *from = rdata->msg_info.from->uri;
762 
763  if (ast_sip_is_allowed_uri(from)) {
764  ast_copy_pj_str(name, ast_sip_pjsip_uri_get_username(from), sizeof(name));
765  }
766 
767  unid = ao2_find(unidentified_requests, rdata->pkt_info.src_name, OBJ_SEARCH_KEY);
768  if (unid) {
769  check_endpoint(rdata, unid, name);
770  ao2_ref(unid, -1);
771  } else if (using_auth_username) {
772  ao2_wrlock(unidentified_requests);
773  /* Checking again with the write lock held allows us to eliminate the DUPS_REPLACE and sort_fn */
774  unid = ao2_find(unidentified_requests, rdata->pkt_info.src_name,
776  if (unid) {
777  check_endpoint(rdata, unid, name);
778  } else {
779  unid = ao2_alloc_options(sizeof(*unid) + strlen(rdata->pkt_info.src_name) + 1,
781  if (!unid) {
782  ao2_unlock(unidentified_requests);
783  pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
784  return PJ_TRUE;
785  }
786  strcpy(unid->src_name, rdata->pkt_info.src_name); /* Safe */
787  unid->first_seen = ast_tvnow();
788  unid->count = 1;
789  ao2_link_flags(unidentified_requests, unid, OBJ_NOLOCK);
790  }
791  ao2_ref(unid, -1);
792  ao2_unlock(unidentified_requests);
793  } else {
794  log_failed_request(rdata, "No matching endpoint found", 0, 0);
795  ast_sip_report_invalid_endpoint(name, rdata);
796  }
797  }
798 
799  apply_acls(rdata);
800  return PJ_FALSE;
801 }
802 
803 static int apply_endpoint_acl(pjsip_rx_data *rdata, struct ast_sip_endpoint *endpoint)
804 {
805  struct ast_sockaddr addr;
806 
807  if (ast_acl_list_is_empty(endpoint->acl)) {
808  return 0;
809  }
810 
811  memset(&addr, 0, sizeof(addr));
812  ast_sockaddr_parse(&addr, rdata->pkt_info.src_name, PARSE_PORT_FORBID);
813  ast_sockaddr_set_port(&addr, rdata->pkt_info.src_port);
814 
815  if (ast_apply_acl(endpoint->acl, &addr, "SIP ACL: ") != AST_SENSE_ALLOW) {
816  log_failed_request(rdata, "Not match Endpoint ACL", 0, 0);
817  ast_sip_report_failed_acl(endpoint, rdata, "not_match_endpoint_acl");
818  return 1;
819  }
820  return 0;
821 }
822 
823 static int extract_contact_addr(pjsip_contact_hdr *contact, struct ast_sockaddr **addrs)
824 {
825  pjsip_sip_uri *sip_uri;
826  char host[256];
827 
828  if (!contact || contact->star) {
829  *addrs = NULL;
830  return 0;
831  }
832 
833  if (!PJSIP_URI_SCHEME_IS_SIP(contact->uri) && !PJSIP_URI_SCHEME_IS_SIPS(contact->uri)) {
834  *addrs = NULL;
835  return 0;
836  }
837  sip_uri = pjsip_uri_get_uri(contact->uri);
838  ast_copy_pj_str(host, &sip_uri->host, sizeof(host));
839  return ast_sockaddr_resolve(addrs, host, PARSE_PORT_FORBID, AST_AF_UNSPEC);
840 }
841 
842 static int apply_endpoint_contact_acl(pjsip_rx_data *rdata, struct ast_sip_endpoint *endpoint)
843 {
844  int num_contact_addrs;
845  int forbidden = 0;
846  struct ast_sockaddr *contact_addrs;
847  int i;
848  pjsip_contact_hdr *contact = (pjsip_contact_hdr *)&rdata->msg_info.msg->hdr;
849 
850  if (ast_acl_list_is_empty(endpoint->contact_acl)) {
851  return 0;
852  }
853 
854  while ((contact = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, contact->next))) {
855  num_contact_addrs = extract_contact_addr(contact, &contact_addrs);
856  if (num_contact_addrs <= 0) {
857  continue;
858  }
859  for (i = 0; i < num_contact_addrs; ++i) {
860  if (ast_apply_acl(endpoint->contact_acl, &contact_addrs[i], "SIP Contact ACL: ") != AST_SENSE_ALLOW) {
861  log_failed_request(rdata, "Not match Endpoint Contact ACL", 0, 0);
862  ast_sip_report_failed_acl(endpoint, rdata, "not_match_endpoint_contact_acl");
863  forbidden = 1;
864  break;
865  }
866  }
867  ast_free(contact_addrs);
868  if (forbidden) {
869  /* No use checking other contacts if we already have failed ACL check */
870  break;
871  }
872  }
873 
874  return forbidden;
875 }
876 
877 static pj_bool_t authenticate(pjsip_rx_data *rdata)
878 {
879  RAII_VAR(struct ast_sip_endpoint *, endpoint, ast_pjsip_rdata_get_endpoint(rdata), ao2_cleanup);
880  int is_ack = rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD;
881 
882  ast_assert(endpoint != NULL);
883 
884  if (is_ack) {
885  return PJ_FALSE;
886  }
887 
888  if (ast_sip_requires_authentication(endpoint, rdata)) {
889  pjsip_tx_data *tdata;
890  struct unidentified_request *unid;
891 
892  pjsip_endpt_create_response(ast_sip_get_pjsip_endpoint(), rdata, 401, NULL, &tdata);
893  switch (ast_sip_check_authentication(endpoint, rdata, tdata)) {
894  case AST_SIP_AUTHENTICATION_CHALLENGE:
895  /* Send the 401 we created for them */
896  ast_sip_report_auth_challenge_sent(endpoint, rdata, tdata);
897  if (pjsip_endpt_send_response2(ast_sip_get_pjsip_endpoint(), rdata, tdata, NULL, NULL) != PJ_SUCCESS) {
898  pjsip_tx_data_dec_ref(tdata);
899  }
900  return PJ_TRUE;
901  case AST_SIP_AUTHENTICATION_SUCCESS:
902  /* See note in endpoint_lookup about not holding an unnecessary write lock */
903  unid = ao2_find(unidentified_requests, rdata->pkt_info.src_name, OBJ_SEARCH_KEY);
904  if (unid) {
905  ao2_unlink(unidentified_requests, unid);
906  ao2_ref(unid, -1);
907  }
908  ast_sip_report_auth_success(endpoint, rdata);
909  break;
910  case AST_SIP_AUTHENTICATION_FAILED:
911  log_failed_request(rdata, "Failed to authenticate", 0, 0);
913  if (pjsip_endpt_send_response2(ast_sip_get_pjsip_endpoint(), rdata, tdata, NULL, NULL) != PJ_SUCCESS) {
914  pjsip_tx_data_dec_ref(tdata);
915  }
916  return PJ_TRUE;
917  case AST_SIP_AUTHENTICATION_ERROR:
918  log_failed_request(rdata, "Error to authenticate", 0, 0);
920  pjsip_tx_data_dec_ref(tdata);
921  pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
922  return PJ_TRUE;
923  }
924  pjsip_tx_data_dec_ref(tdata);
925  } else if (endpoint == artificial_endpoint) {
926  /* Uh. Oh. The artificial endpoint couldn't challenge so block the request. */
927  pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
928  return PJ_TRUE;
929  }
930 
931  return PJ_FALSE;
932 }
933 
934 static pjsip_module auth_mod = {
935  .name = {"Request Authenticator", 21},
936  .priority = PJSIP_MOD_PRIORITY_APPLICATION - 2,
937  .on_rx_request = authenticate,
938 };
939 
940 static int distribute(void *data)
941 {
942  static pjsip_process_rdata_param param = {
943  .start_mod = &distributor_mod,
944  .idx_after_start = 1,
945  };
946  pj_bool_t handled = PJ_FALSE;
947  pjsip_rx_data *rdata = data;
948  int is_request = rdata->msg_info.msg->type == PJSIP_REQUEST_MSG;
949  int is_ack = is_request ? rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD : 0;
950  struct ast_sip_endpoint *endpoint;
951 
952  pjsip_endpt_process_rx_data(ast_sip_get_pjsip_endpoint(), rdata, &param, &handled);
953  if (!handled && is_request && !is_ack) {
954  pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 501, NULL, NULL, NULL);
955  }
956 
957  /* The endpoint_mod stores an endpoint reference in the mod_data of rdata. This
958  * is the only appropriate spot to actually decrement the reference.
959  */
960  endpoint = rdata->endpt_info.mod_data[endpoint_mod.id];
961  ao2_cleanup(endpoint);
962  pjsip_rx_data_free_cloned(rdata);
963  return 0;
964 }
965 
966 struct ast_sip_endpoint *ast_pjsip_rdata_get_endpoint(pjsip_rx_data *rdata)
967 {
968  struct ast_sip_endpoint *endpoint = rdata->endpt_info.mod_data[endpoint_mod.id];
969  if (endpoint) {
970  ao2_ref(endpoint, +1);
971  }
972  return endpoint;
973 }
974 
975 static int suspects_sort(const void *obj, const void *arg, int flags)
976 {
977  const struct unidentified_request *object_left = obj;
978  const struct unidentified_request *object_right = arg;
979  const char *right_key = arg;
980  int cmp;
981 
982  switch (flags & OBJ_SEARCH_MASK) {
983  case OBJ_SEARCH_OBJECT:
984  right_key = object_right->src_name;
985  /* Fall through */
986  case OBJ_SEARCH_KEY:
987  cmp = strcmp(object_left->src_name, right_key);
988  break;
990  cmp = strncmp(object_left->src_name, right_key, strlen(right_key));
991  break;
992  default:
993  cmp = 0;
994  break;
995  }
996  return cmp;
997 }
998 
999 static int suspects_compare(void *obj, void *arg, int flags)
1000 {
1001  const struct unidentified_request *object_left = obj;
1002  const struct unidentified_request *object_right = arg;
1003  const char *right_key = arg;
1004  int cmp = 0;
1005 
1006  switch (flags & OBJ_SEARCH_MASK) {
1007  case OBJ_SEARCH_OBJECT:
1008  right_key = object_right->src_name;
1009  /* Fall through */
1010  case OBJ_SEARCH_KEY:
1011  if (strcmp(object_left->src_name, right_key) == 0) {
1012  cmp = CMP_MATCH;
1013  }
1014  break;
1016  if (strncmp(object_left->src_name, right_key, strlen(right_key)) == 0) {
1017  cmp = CMP_MATCH;
1018  }
1019  break;
1020  default:
1021  cmp = 0;
1022  break;
1023  }
1024  return cmp;
1025 }
1026 
1027 static int suspects_hash(const void *obj, int flags)
1028 {
1029  const struct unidentified_request *object;
1030  const char *key;
1031 
1032  switch (flags & OBJ_SEARCH_MASK) {
1033  case OBJ_SEARCH_KEY:
1034  key = obj;
1035  break;
1036  case OBJ_SEARCH_OBJECT:
1037  object = obj;
1038  key = object->src_name;
1039  break;
1040  default:
1041  /* Hash can only work on something with a full key. */
1042  ast_assert(0);
1043  return 0;
1044  }
1045  return ast_str_hash(key);
1046 }
1047 
1048 static struct ao2_container *cli_unid_get_container(const char *regex)
1049 {
1050  struct ao2_container *s_container;
1051 
1053  suspects_sort, suspects_compare);
1054  if (!s_container) {
1055  return NULL;
1056  }
1057 
1058  if (ao2_container_dup(s_container, unidentified_requests, 0)) {
1059  ao2_ref(s_container, -1);
1060  return NULL;
1061  }
1062 
1063  return s_container;
1064 }
1065 
1066 static int cli_unid_iterate(void *container, ao2_callback_fn callback, void *args)
1067 {
1068  ao2_callback(container, 0, callback, args);
1069 
1070  return 0;
1071 }
1072 
1073 static void *cli_unid_retrieve_by_id(const char *id)
1074 {
1075  return ao2_find(unidentified_requests, id, OBJ_SEARCH_KEY);
1076 }
1077 
1078 static const char *cli_unid_get_id(const void *obj)
1079 {
1080  const struct unidentified_request *unid = obj;
1081 
1082  return unid->src_name;
1083 }
1084 
1085 static int cli_unid_print_header(void *obj, void *arg, int flags)
1086 {
1087  struct ast_sip_cli_context *context = arg;
1088  RAII_VAR(struct ast_sip_cli_formatter_entry *, formatter_entry, NULL, ao2_cleanup);
1089 
1090  int indent = CLI_INDENT_TO_SPACES(context->indent_level);
1091  int filler = CLI_LAST_TABSTOP - indent - 7;
1092 
1093  ast_assert(context->output_buffer != NULL);
1094 
1095  ast_str_append(&context->output_buffer, 0,
1096  "%*s: <IP Address%*.*s> <Count> <Age(sec)>\n",
1097  indent, "Request", filler, filler, CLI_HEADER_FILLER);
1098 
1099  return 0;
1100 }
1101 
1102 static int cli_unid_print_body(void *obj, void *arg, int flags)
1103 {
1104  struct unidentified_request *unid = obj;
1105  struct ast_sip_cli_context *context = arg;
1106  int indent;
1107  int flexwidth;
1108  int64_t ms = ast_tvdiff_ms(ast_tvnow(), unid->first_seen);
1109 
1110  ast_assert(context->output_buffer != NULL);
1111 
1112  indent = CLI_INDENT_TO_SPACES(context->indent_level);
1113  flexwidth = CLI_LAST_TABSTOP - 4;
1114 
1115  ast_str_append(&context->output_buffer, 0, "%*s: %-*.*s %7d %10.3f\n",
1116  indent,
1117  "Request",
1118  flexwidth, flexwidth,
1119  unid->src_name, unid->count, ms / 1000.0);
1120 
1121  return 0;
1122 }
1123 
1124 static struct ast_cli_entry cli_commands[] = {
1125  AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "Show PJSIP Unidentified Requests",
1126  .command = "pjsip show unidentified_requests",
1127  .usage = "Usage: pjsip show unidentified_requests\n"
1128  " Show the PJSIP Unidentified Requests\n"),
1129 };
1130 
1131 struct ast_sip_cli_formatter_entry *unid_formatter;
1132 
1133 static int expire_requests(void *object, void *arg, int flags)
1134 {
1135  struct unidentified_request *unid = object;
1136  int *maxage = arg;
1137  int64_t ms = ast_tvdiff_ms(ast_tvnow(), unid->first_seen);
1138 
1139  if (ms > (*maxage) * 2 * 1000) {
1140  return CMP_MATCH;
1141  }
1142 
1143  return 0;
1144 }
1145 
1146 static int prune_task(const void *data)
1147 {
1148  unsigned int maxage;
1149 
1150  ast_sip_get_unidentified_request_thresholds(&unidentified_count, &unidentified_period, &unidentified_prune_interval);
1151  maxage = unidentified_period * 2;
1152  ao2_callback(unidentified_requests, OBJ_MULTIPLE | OBJ_NODATA | OBJ_UNLINK, expire_requests, &maxage);
1153 
1154  return unidentified_prune_interval * 1000;
1155 }
1156 
1157 static int clean_task(const void *data)
1158 {
1159  return 0;
1160 }
1161 
1162 static void global_loaded(const char *object_type)
1163 {
1164  char default_realm[AST_SIP_AUTH_MAX_REALM_LENGTH + 1];
1165  struct ast_sip_auth *fake_auth;
1166  char *identifier_order;
1167 
1168  /* Update using_auth_username */
1169  identifier_order = ast_sip_get_endpoint_identifier_order();
1170  if (identifier_order) {
1171  char *identify_method;
1172  char *io_copy = ast_strdupa(identifier_order);
1173  int new_using = 0;
1174 
1175  ast_free(identifier_order);
1176  while ((identify_method = ast_strip(strsep(&io_copy, ",")))) {
1177  if (!strcmp(identify_method, "auth_username")) {
1178  new_using = 1;
1179  break;
1180  }
1181  }
1182  using_auth_username = new_using;
1183  }
1184 
1185  /* Update default_realm of artificial_auth */
1186  ast_sip_get_default_realm(default_realm, sizeof(default_realm));
1187  fake_auth = ast_sip_get_artificial_auth();
1188  if (!fake_auth || strcmp(fake_auth->realm, default_realm)) {
1189  ao2_cleanup(fake_auth);
1190 
1191  fake_auth = alloc_artificial_auth(default_realm);
1192  if (fake_auth) {
1193  ao2_global_obj_replace_unref(artificial_auth, fake_auth);
1194  }
1195  }
1196  ao2_cleanup(fake_auth);
1197 
1198  ast_sip_get_unidentified_request_thresholds(&unidentified_count, &unidentified_period, &unidentified_prune_interval);
1199 
1200  overload_trigger = ast_sip_get_taskprocessor_overload_trigger();
1201 
1202  /* Clean out the old task, if any */
1203  ast_sched_clean_by_callback(prune_context, prune_task, clean_task);
1204  /* Have to do something with the return value to shut up the stupid compiler. */
1205  if (ast_sched_add_variable(prune_context, unidentified_prune_interval * 1000, prune_task, NULL, 1) < 0) {
1206  return;
1207  }
1208 }
1209 
1210 /*! \brief Observer which is used to update our interval and default_realm when the global setting changes */
1211 static struct ast_sorcery_observer global_observer = {
1212  .loaded = global_loaded,
1213 };
1214 
1215 /*!
1216  * \internal
1217  * \brief Shutdown the serializers in the distributor pool.
1218  * \since 13.10.0
1219  */
1220 static void distributor_pool_shutdown(void)
1221 {
1222  int idx;
1223 
1224  for (idx = 0; idx < ARRAY_LEN(distributor_pool); ++idx) {
1225  ast_taskprocessor_unreference(distributor_pool[idx]);
1226  distributor_pool[idx] = NULL;
1227  }
1228 }
1229 
1230 /*!
1231  * \internal
1232  * \brief Setup the serializers in the distributor pool.
1233  * \since 13.10.0
1234  *
1235  * \retval 0 on success.
1236  * \retval -1 on error.
1237  */
1238 static int distributor_pool_setup(void)
1239 {
1240  char tps_name[AST_TASKPROCESSOR_MAX_NAME + 1];
1241  int idx;
1242 
1243  for (idx = 0; idx < ARRAY_LEN(distributor_pool); ++idx) {
1244  /* Create name with seq number appended. */
1245  ast_taskprocessor_build_name(tps_name, sizeof(tps_name), "pjsip/distributor");
1246 
1247  distributor_pool[idx] = ast_sip_create_serializer(tps_name);
1248  if (!distributor_pool[idx]) {
1249  return -1;
1250  }
1251  }
1252  return 0;
1253 }
1254 
1255 int ast_sip_initialize_distributor(void)
1256 {
1257  unidentified_requests = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_RWLOCK, 0,
1258  DEFAULT_SUSPECTS_BUCKETS, suspects_hash, NULL, suspects_compare);
1259  if (!unidentified_requests) {
1260  return -1;
1261  }
1262 
1263  dialog_associations = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_RWLOCK, 0,
1264  DIALOG_ASSOCIATIONS_BUCKETS, dialog_associations_hash, NULL,
1265  dialog_associations_cmp);
1266  if (!dialog_associations) {
1267  ast_sip_destroy_distributor();
1268  return -1;
1269  }
1270 
1271  if (distributor_pool_setup()) {
1272  ast_sip_destroy_distributor();
1273  return -1;
1274  }
1275 
1276  prune_context = ast_sched_context_create();
1277  if (!prune_context) {
1278  ast_sip_destroy_distributor();
1279  return -1;
1280  }
1281 
1282  if (ast_sched_start_thread(prune_context)) {
1283  ast_sip_destroy_distributor();
1284  return -1;
1285  }
1286 
1287  ast_sorcery_observer_add(ast_sip_get_sorcery(), "global", &global_observer);
1288  ast_sorcery_reload_object(ast_sip_get_sorcery(), "global");
1289 
1290  if (create_artificial_endpoint() || create_artificial_auth()) {
1291  ast_sip_destroy_distributor();
1292  return -1;
1293  }
1294 
1295  if (ast_sip_register_service(&distributor_mod)) {
1296  ast_sip_destroy_distributor();
1297  return -1;
1298  }
1299  if (ast_sip_register_service(&endpoint_mod)) {
1300  ast_sip_destroy_distributor();
1301  return -1;
1302  }
1303  if (ast_sip_register_service(&auth_mod)) {
1304  ast_sip_destroy_distributor();
1305  return -1;
1306  }
1307 
1308  unid_formatter = ao2_alloc_options(sizeof(struct ast_sip_cli_formatter_entry), NULL,
1310  if (!unid_formatter) {
1311  ast_sip_destroy_distributor();
1312  ast_log(LOG_ERROR, "Unable to allocate memory for unid_formatter\n");
1313  return -1;
1314  }
1315  unid_formatter->name = "unidentified_request";
1316  unid_formatter->print_header = cli_unid_print_header;
1317  unid_formatter->print_body = cli_unid_print_body;
1318  unid_formatter->get_container = cli_unid_get_container;
1319  unid_formatter->iterate = cli_unid_iterate;
1320  unid_formatter->get_id = cli_unid_get_id;
1321  unid_formatter->retrieve_by_id = cli_unid_retrieve_by_id;
1322  ast_sip_register_cli_formatter(unid_formatter);
1323 
1324  ast_cli_register_multiple(cli_commands, ARRAY_LEN(cli_commands));
1325 
1326  return 0;
1327 }
1328 
1329 void ast_sip_destroy_distributor(void)
1330 {
1331  ast_cli_unregister_multiple(cli_commands, ARRAY_LEN(cli_commands));
1332  ast_sip_unregister_cli_formatter(unid_formatter);
1333 
1334  ast_sip_unregister_service(&auth_mod);
1335  ast_sip_unregister_service(&endpoint_mod);
1336  ast_sip_unregister_service(&distributor_mod);
1337 
1338  ao2_global_obj_release(artificial_auth);
1339  ao2_cleanup(artificial_endpoint);
1340 
1341  ast_sorcery_observer_remove(ast_sip_get_sorcery(), "global", &global_observer);
1342 
1343  if (prune_context) {
1344  ast_sched_context_destroy(prune_context);
1345  }
1346 
1347  distributor_pool_shutdown();
1348 
1349  ao2_cleanup(dialog_associations);
1350  ao2_cleanup(unidentified_requests);
1351 }
int ast_sched_start_thread(struct ast_sched_context *con)
Start a thread for processing scheduler entries.
Definition: sched.c:197
void ast_sip_report_auth_failed_challenge_response(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
Send a security event notification for when a challenge response has failed.
struct ast_str * output_buffer
Definition: res_pjsip_cli.h:36
struct ao2_container *(* get_container)(const char *regex)
Definition: res_pjsip_cli.h:64
void ast_sched_clean_by_callback(struct ast_sched_context *con, ast_sched_cb match, ast_sched_cb cleanup_cb)
Clean all scheduled events with matching callback.
Definition: sched.c:409
void ast_taskprocessor_build_name(char *buf, unsigned int size, const char *format,...)
Build a taskprocessor name with a sequence number on the end.
Asterisk main include file. File version handling, generic pbx functions.
char name[0]
Friendly name of the taskprocessor. Subsystem is appended after the name's NULL terminator.
Definition: taskprocessor.c:97
CLI Formatter Registry Entry.
Definition: res_pjsip_cli.h:52
int( ao2_callback_fn)(void *obj, void *arg, int flags)
Type of a generic callback function.
Definition: astobj2.h:1226
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1101
void ast_sip_report_auth_success(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
Send a security event notification for when authentication succeeds.
void ast_sip_dialog_set_serializer(pjsip_dialog *dlg, struct ast_taskprocessor *serializer)
Set a serializer on a SIP dialog so requests and responses are automatically serialized.
descriptor for a cli entry.
Definition: cli.h:171
#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
struct ast_taskprocessor * ast_taskprocessor_get(const char *name, enum ast_tps_options create)
Get a reference to a taskprocessor with the specified name and create the taskprocessor if necessary...
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Definition: astobj2.h:1327
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
void ast_sip_dialog_set_endpoint(pjsip_dialog *dlg, struct ast_sip_endpoint *endpoint)
Set an endpoint on a SIP dialog so in-dialog requests do not undergo endpoint lookup.
Assume that the ao2_container is already locked.
Definition: astobj2.h:1063
int ast_sched_add_variable(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data, int variable) attribute_warn_unused_result
Adds a scheduled event with rescheduling support.
Definition: sched.c:526
int(* iterate)(void *container, ao2_callback_fn callback, void *args)
Definition: res_pjsip_cli.h:66
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
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
const char * ast_taskprocessor_name(struct ast_taskprocessor *tps)
Return the name of the taskprocessor singleton.
#define ao2_link_flags(container, obj, flags)
Add an object to a container.
Definition: astobj2.h:1554
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
CLI Formatter Context passed to all formatters.
Definition: res_pjsip_cli.h:34
#define AST_TASKPROCESSOR_MAX_NAME
Suggested maximum taskprocessor name length (less null terminator).
Definition: taskprocessor.h:61
Socket address structure.
Definition: netsock2.h:97
void ast_sip_report_auth_challenge_sent(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pjsip_tx_data *tdata)
Send a security event notification for when an authentication challenge is sent.
struct ast_acl_list * acl
Definition: res_pjsip.h:1020
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
Definition: astobj2.h:1116
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
struct ast_acl_list * contact_acl
Definition: res_pjsip.h:1022
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
Access Control of various sorts.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
struct ast_sip_endpoint * ast_sip_dialog_get_endpoint(pjsip_dialog *dlg)
Get the endpoint associated with this dialog.
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:223
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2317
void *(* retrieve_by_id)(const char *id)
Definition: res_pjsip_cli.h:68
struct ao2_container * container
Definition: res_fax.c:501
#define ast_debug(level,...)
Log a DEBUG message.
struct ast_sip_endpoint * endpoint
An entity with which Asterisk communicates.
Definition: res_pjsip.h:949
enum ast_acl_sense ast_apply_acl(struct ast_acl_list *acl_list, const struct ast_sockaddr *addr, const char *purpose)
Apply a set of rules to a given IP address.
Definition: acl.c:799
int ast_acl_list_is_empty(struct ast_acl_list *acl_list)
Determines if an ACL is empty or if it contains entries.
Definition: acl.c:540
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
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
Definition: sched.c:238
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
Definition: astobj2.h:1303
struct ast_sip_auth_vector inbound_auths
Definition: res_pjsip.h:992
#define ao2_unlink(container, obj)
Remove an object from a container.
Definition: astobj2.h:1578
int ao2_container_dup(struct ao2_container *dest, struct ao2_container *src, enum search_flags flags)
Copy all object references in the src container into the dest container.
const ast_string_field realm
Definition: res_pjsip.h:581
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:532
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
Interface for a sorcery object type observer.
Definition: sorcery.h:332
#define ao2_global_obj_release(holder)
Release the ao2 object held in the global holder.
Definition: astobj2.h:859
unsigned int ast_taskprocessor_get_subsystem_alert(const char *subsystem)
Get the current taskprocessor high water alert count by subsystem.
struct ast_taskprocessor * ast_sip_create_serializer(const char *name)
Create a new serializer for SIP tasks.
Definition: res_pjsip.c:2094
struct ast_taskprocessor * ast_sip_get_distributor_serializer(pjsip_rx_data *rdata)
Determine the distributor serializer for the SIP message.
void * ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, const char *id)
Allocate an object.
Definition: sorcery.c:1744
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.
char * command
Definition: cli.h:186
const ast_string_field auth_pass
Definition: res_pjsip.h:585
struct ast_taskprocessor * serializer
enum ast_sip_auth_type type
Definition: res_pjsip.h:597
An API for managing task processing threads that can be shared across modules.
const char *(* get_id)(const void *obj)
Definition: res_pjsip_cli.h:70
void(* loaded)(const char *object_type)
Callback for when an object type is loaded/reloaded.
Definition: sorcery.h:343
const char * usage
Definition: cli.h:177
return a reference to a taskprocessor ONLY if it already exists
Definition: taskprocessor.h:78
#define ao2_global_obj_replace_unref(holder, obj)
Replace an ao2 object in the global holder, throwing away any old object.
Definition: astobj2.h:901
The arg parameter is an object of the same type.
Definition: astobj2.h:1087
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
A ast_taskprocessor structure is a singleton by name.
Definition: taskprocessor.c:69
#define ao2_replace(dst, src)
Replace one object reference with another cleaning up the original.
Definition: astobj2.h:501
static force_inline int attribute_pure ast_str_hash_restrict(unsigned int hash)
Restrict hash value range.
Definition: strings.h:1246
void * ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
Unreference the specified taskprocessor and its reference count will decrement.
unsigned int ast_taskprocessor_alert_get(void)
Get the current taskprocessor high water alert count.
#define ao2_unlink_flags(container, obj, flags)
Remove an object from a container.
Definition: astobj2.h:1600
ao2_callback_fn * print_header
Definition: res_pjsip_cli.h:60
void ast_sip_report_invalid_endpoint(const char *name, pjsip_rx_data *rdata)
Send a security event notification for when an invalid endpoint is requested.
Generic container type.
Search option field mask.
Definition: astobj2.h:1072
ao2_callback_fn * print_body
Definition: res_pjsip_cli.h:62
#define AO2_GLOBAL_OBJ_STATIC(name)
Define a global object holder to be used to hold an ao2 object, statically initialized.
Definition: astobj2.h:847
const char * name
Definition: res_pjsip_cli.h:58
#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
const ast_string_field auth_user
Definition: res_pjsip.h:583
void ast_sched_context_destroy(struct ast_sched_context *c)
destroys a schedule context
Definition: sched.c:271
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
int ast_sockaddr_resolve(struct ast_sockaddr **addrs, const char *str, int flags, int family)
Parses a string with an IPv4 or IPv6 address and place results into an array.
Definition: netsock2.c:280
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1259
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521