Asterisk - The Open Source Telephony Project  21.4.1
res_pjsip_outbound_registration.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * Joshua Colp <jcolp@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 /*** MODULEINFO
20  <depend>pjproject</depend>
21  <depend>res_pjsip</depend>
22  <use type="module">res_statsd</use>
23  <support_level>core</support_level>
24  ***/
25 
26 #include "asterisk.h"
27 
28 #include <pjsip.h>
29 #include <pjsip_ua.h>
30 
31 #include "asterisk/res_pjsip.h"
32 #include "asterisk/res_pjsip_cli.h"
33 #include "asterisk/module.h"
34 #include "asterisk/taskprocessor.h"
35 #include "asterisk/cli.h"
36 #include "asterisk/stasis_system.h"
37 #include "asterisk/threadstorage.h"
38 #include "asterisk/threadpool.h"
39 #include "asterisk/statsd.h"
40 #include "res_pjsip/include/res_pjsip_private.h"
41 #include "asterisk/vector.h"
42 #include "asterisk/pbx.h"
43 
44 /*** DOCUMENTATION
45  <configInfo name="res_pjsip_outbound_registration" language="en_US">
46  <synopsis>SIP resource for outbound registrations</synopsis>
47  <description><para>
48  <emphasis>Outbound Registration</emphasis>
49  </para>
50  <para>This module allows <literal>res_pjsip</literal> to register to other SIP servers.</para>
51  </description>
52  <configFile name="pjsip.conf">
53  <configObject name="registration">
54  <synopsis>The configuration for outbound registration</synopsis>
55  <description><para>
56  Registration is <emphasis>COMPLETELY</emphasis> separate from the rest of
57  <literal>pjsip.conf</literal>. A minimal configuration consists of
58  setting a <literal>server_uri</literal> and a <literal>client_uri</literal>.
59  </para></description>
60  <configOption name="auth_rejection_permanent" default="yes">
61  <synopsis>Determines whether failed authentication challenges are treated
62  as permanent failures.</synopsis>
63  <description><para>If this option is enabled and an authentication challenge fails,
64  registration will not be attempted again until the configuration is reloaded.</para></description>
65  </configOption>
66  <configOption name="client_uri">
67  <synopsis>Client SIP URI used when attemping outbound registration</synopsis>
68  <description><para>
69  This is the address-of-record for the outbound registration (i.e. the URI in
70  the To header of the REGISTER).</para>
71  <para>For registration with an ITSP, the client SIP URI may need to consist of
72  an account name or number and the provider's hostname for their registrar, e.g.
73  client_uri=1234567890@example.com. This may differ between providers.</para>
74  <para>For registration to generic registrars, the client SIP URI will depend
75  on networking specifics and configuration of the registrar.
76  </para></description>
77  </configOption>
78  <configOption name="contact_user" default="s">
79  <synopsis>Contact User to use in request. If this value is not set, this defaults to 's'</synopsis>
80  </configOption>
81  <configOption name="contact_header_params">
82  <synopsis>Header parameters to place in the Contact header</synopsis>
83  </configOption>
84  <configOption name="expiration" default="3600">
85  <synopsis>Expiration time for registrations in seconds</synopsis>
86  </configOption>
87  <configOption name="max_retries" default="10">
88  <synopsis>Maximum number of registration attempts.</synopsis>
89  <description><para>
90  This sets the maximum number of registration attempts that are made before
91  stopping any further attempts. If set to 0 then upon failure no further attempts
92  are made.
93  </para></description>
94  </configOption>
95  <configOption name="security_negotiation" default="no">
96  <synopsis>The kind of security agreement negotiation to use. Currently, only mediasec is supported.</synopsis>
97  <description>
98  <enumlist>
99  <enum name="no" />
100  <enum name="mediasec" />
101  </enumlist>
102  </description>
103  </configOption>
104  <configOption name="security_mechanisms">
105  <synopsis>List of security mechanisms supported.</synopsis>
106  <description><para>
107  This is a comma-delimited list of security mechanisms to use. Each security mechanism
108  must be in the form defined by RFC 3329 section 2.2.
109  </para></description>
110  </configOption>
111  <configOption name="outbound_auth" default="">
112  <synopsis>Authentication object(s) to be used for outbound registrations.</synopsis>
113  <description><para>
114  This is a comma-delimited list of <replaceable>auth</replaceable>
115  sections defined in <filename>pjsip.conf</filename> used to respond
116  to outbound authentication challenges.</para>
117  <note><para>
118  Using the same auth section for inbound and outbound
119  authentication is not recommended. There is a difference in
120  meaning for an empty realm setting between inbound and outbound
121  authentication uses. See the auth realm description for details.
122  </para></note>
123  </description>
124  </configOption>
125  <configOption name="outbound_proxy" default="">
126  <synopsis>Full SIP URI of the outbound proxy used to send registrations</synopsis>
127  </configOption>
128  <configOption name="max_random_initial_delay" default="10">
129  <synopsis>Maximum interval in seconds for which an initial registration may be randomly delayed</synopsis>
130  <description>
131  <para>By default, registrations are randomly delayed by a small amount to prevent
132  too many registrations from being made simultaneously.</para>
133  <para>Depending on your system usage, it may be desirable to set this to a smaller
134  or larger value to have fine grained control over the size of this random delay.</para>
135  </description>
136  </configOption>
137  <configOption name="retry_interval" default="60">
138  <synopsis>Interval in seconds between retries if outbound registration is unsuccessful</synopsis>
139  </configOption>
140  <configOption name="forbidden_retry_interval" default="0">
141  <synopsis>Interval used when receiving a 403 Forbidden response.</synopsis>
142  <description><para>
143  If a 403 Forbidden is received, chan_pjsip will wait
144  <replaceable>forbidden_retry_interval</replaceable> seconds before
145  attempting registration again. If 0 is specified, chan_pjsip will not
146  retry after receiving a 403 Forbidden response. Setting this to a non-zero
147  value goes against a "SHOULD NOT" in RFC3261, but can be used to work around
148  buggy registrars.
149  </para></description>
150  </configOption>
151  <configOption name="fatal_retry_interval" default="0">
152  <synopsis>Interval used when receiving a Fatal response.</synopsis>
153  <description><para>
154  If a fatal response is received, chan_pjsip will wait
155  <replaceable>fatal_retry_interval</replaceable> seconds before
156  attempting registration again. If 0 is specified, chan_pjsip will not
157  retry after receiving a fatal (non-temporary 4xx, 5xx, 6xx) response.
158  Setting this to a non-zero value may go against a "SHOULD NOT" in RFC3261,
159  but can be used to work around buggy registrars.</para>
160  <note><para>if also set the <replaceable>forbidden_retry_interval</replaceable>
161  takes precedence over this one when a 403 is received.
162  Also, if <replaceable>auth_rejection_permanent</replaceable> equals 'yes' then
163  a 401 and 407 become subject to this retry interval.</para></note>
164  </description>
165  </configOption>
166  <configOption name="server_uri">
167  <synopsis>SIP URI of the server to register against</synopsis>
168  <description><para>
169  This is the URI at which to find the registrar to send the outbound REGISTER. This URI
170  is used as the request URI of the outbound REGISTER request from Asterisk.</para>
171  <para>For registration with an ITSP, the setting may often be just the domain of
172  the registrar, e.g. sip:sip.example.com.
173  </para></description>
174  </configOption>
175  <configOption name="transport">
176  <synopsis>Transport used for outbound authentication</synopsis>
177  <description>
178  <note><para>A <replaceable>transport</replaceable> configured in
179  <literal>pjsip.conf</literal>. As with other <literal>res_pjsip</literal> modules, this will use the first available transport of the appropriate type if unconfigured.</para></note>
180  </description>
181  </configOption>
182  <configOption name="line">
183  <synopsis>Whether to add a 'line' parameter to the Contact for inbound call matching</synopsis>
184  <description><para>
185  When enabled this option will cause a 'line' parameter to be added to the Contact
186  header placed into the outgoing registration request. If the remote server sends a call
187  this line parameter will be used to establish a relationship to the outbound registration,
188  ultimately causing the configured endpoint to be used.
189  </para></description>
190  </configOption>
191  <configOption name="endpoint">
192  <synopsis>Endpoint to use for incoming related calls</synopsis>
193  <description><para>
194  When line support is enabled this configured endpoint name is used for incoming calls
195  that are related to the outbound registration.
196  </para></description>
197  </configOption>
198  <configOption name="type">
199  <synopsis>Must be of type 'registration'.</synopsis>
200  </configOption>
201  <configOption name="support_path">
202  <synopsis>Enables advertising SIP Path support for outbound REGISTER requests.</synopsis>
203  <description><para>
204  When this option is enabled, outbound REGISTER requests will advertise
205  support for Path headers so that intervening proxies can add to the Path
206  header as necessary.
207  </para></description>
208  </configOption>
209  <configOption name="support_outbound">
210  <synopsis>Enables advertising SIP Outbound support (RFC5626) for outbound REGISTER requests.</synopsis>
211  </configOption>
212  <configOption name="user_agent">
213  <synopsis>Overrides the User-Agent header that should be used for outbound REGISTER requests.</synopsis>
214  </configOption>
215  </configObject>
216  </configFile>
217  </configInfo>
218  <manager name="PJSIPUnregister" language="en_US">
219  <synopsis>
220  Unregister an outbound registration.
221  </synopsis>
222  <syntax>
223  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
224  <parameter name="Registration" required="true">
225  <para>The outbound registration to unregister or '*all' to unregister them all.</para>
226  </parameter>
227  </syntax>
228  <description>
229  <para>
230  Unregisters the specified (or all) outbound registration(s) and stops future registration attempts.
231  Call PJSIPRegister to start registration and schedule re-registrations according to configuration.
232  </para>
233  </description>
234  </manager>
235  <manager name="PJSIPRegister" language="en_US">
236  <synopsis>
237  Register an outbound registration.
238  </synopsis>
239  <syntax>
240  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
241  <parameter name="Registration" required="true">
242  <para>The outbound registration to register or '*all' to register them all.</para>
243  </parameter>
244  </syntax>
245  <description>
246  <para>
247  Unregisters the specified (or all) outbound registration(s) then starts registration and schedules re-registrations
248  according to configuration.
249  </para>
250  </description>
251  </manager>
252  <manager name="PJSIPShowRegistrationsOutbound" language="en_US">
253  <synopsis>
254  Lists PJSIP outbound registrations.
255  </synopsis>
256  <syntax />
257  <description>
258  <para>
259  In response <literal>OutboundRegistrationDetail</literal> events showing configuration and status
260  information are raised for each outbound registration object. <literal>AuthDetail</literal>
261  events are raised for each associated auth object as well. Once all events are completed an
262  <literal>OutboundRegistrationDetailComplete</literal> is issued.
263  </para>
264  </description>
265  </manager>
266  ***/
267 
268 /* forward declarations */
269 static int set_outbound_initial_authentication_credentials(pjsip_regc *regc,
270  const struct ast_sip_auth_vector *auth_vector);
271 
272 /*! \brief Some thread local storage used to determine if the running thread invoked the callback */
273 AST_THREADSTORAGE(register_callback_invoked);
274 
275 /*! \brief Amount of buffer time (in seconds) before expiration that we re-register at */
276 #define REREGISTER_BUFFER_TIME 10
277 
278 /*! \brief Size of the buffer for creating a unique string for the line */
279 #define LINE_PARAMETER_SIZE 8
280 
281 /*! \brief Various states that an outbound registration may be in */
282 enum sip_outbound_registration_status {
283  /*! \brief Currently unregistered */
284  SIP_REGISTRATION_UNREGISTERED = 0,
285  /*! \brief Registered, yay! */
286  SIP_REGISTRATION_REGISTERED,
287  /*! \brief Registration was rejected, but response was temporal */
288  SIP_REGISTRATION_REJECTED_TEMPORARY,
289  /*! \brief Registration was rejected, permanently */
290  SIP_REGISTRATION_REJECTED_PERMANENT,
291  /*! \brief Registration is stopping. */
292  SIP_REGISTRATION_STOPPING,
293  /*! \brief Registration has been stopped */
294  SIP_REGISTRATION_STOPPED,
295 };
296 
297 /*!
298  * \internal
299  * \brief Convert the internal registration state to an external status string.
300  * \since 13.5.0
301  *
302  * \param state Current outbound registration state.
303  *
304  * \return External registration status string.
305  */
306 static const char *sip_outbound_registration_status_str(enum sip_outbound_registration_status state)
307 {
308  const char *str;
309 
310  str = "Unregistered";
311  switch (state) {
312  case SIP_REGISTRATION_STOPPING:
313  case SIP_REGISTRATION_STOPPED:
314  case SIP_REGISTRATION_UNREGISTERED:
315  break;
316  case SIP_REGISTRATION_REGISTERED:
317  str = "Registered";
318  break;
319  case SIP_REGISTRATION_REJECTED_TEMPORARY:
320  case SIP_REGISTRATION_REJECTED_PERMANENT:
321  str = "Rejected";
322  break;
323  }
324  return str;
325 }
326 
327 /*! \brief Outbound registration information */
329  /*! \brief Sorcery object details */
330  SORCERY_OBJECT(details);
331  /*! \brief Stringfields */
333  /*! \brief URI for the registrar */
335  /*! \brief URI for the AOR */
337  /*! \brief Optional user for contact header */
339  /*! \brief Optional header parameters for contact */
341  /*! \brief Explicit transport to use for registration */
343  /*! \brief Outbound proxy to use */
345  /*! \brief Endpoint to use for related incoming calls */
347  /*! \brief User-Agent to use when sending the REGISTER */
349  );
350  /*! \brief Requested expiration time */
351  unsigned int expiration;
352  /*! \brief Maximum random initial delay interval for initial registrations */
354  /*! \brief Interval at which retries should occur for temporal responses */
355  unsigned int retry_interval;
356  /*! \brief Interval at which retries should occur for permanent responses */
358  /*! \brief Interval at which retries should occur for all permanent responses */
359  unsigned int fatal_retry_interval;
360  /*! \brief Treat authentication challenges that we cannot handle as permanent failures */
362  /*! \brief Maximum number of retries permitted */
363  unsigned int max_retries;
364  /*! \brief Whether to add a line parameter to the outbound Contact or not */
365  unsigned int line;
366  /*! \brief Type of security negotiation to use (RFC 3329). */
367  enum ast_sip_security_negotiation security_negotiation;
368  /*! \brief Client security mechanisms (RFC 3329). */
370  /*! \brief Configured authentication credentials */
372  /*! \brief Whether Path support is enabled */
373  unsigned int support_path;
374  /*! \brief Whether Outbound support is enabled */
375  unsigned int support_outbound;
376 };
377 
378 /*! \brief Outbound registration client state information (persists for lifetime of regc) */
380  /*! \brief Current state of this registration */
381  enum sip_outbound_registration_status status;
382  /*!
383  * \brief Outbound registration client
384  * \note May only be accessed within the serializer thread
385  * because it might get destroyed and set to NULL for
386  * module unload.
387  */
388  pjsip_regc *client;
389  /*!
390  * \brief Last tdata sent
391  * We need the original tdata to resend a request on auth failure
392  * or timeout. On an auth failure, we use the original tdata
393  * to initialize the new tdata for the authorized response. On a timeout
394  * we need it to skip failed SRV entries if any.
395  */
396  pjsip_tx_data *last_tdata;
397  /*! \brief Timer entry for retrying on temporal responses */
398  pj_timer_entry timer;
399  /*! \brief Optional line parameter placed into Contact */
400  char line[LINE_PARAMETER_SIZE];
401  /*! \brief Current number of retries */
402  unsigned int retries;
403  /*! \brief Maximum number of retries permitted */
404  unsigned int max_retries;
405  /*! \brief Interval at which retries should occur for temporal responses */
406  unsigned int retry_interval;
407  /*! \brief Interval at which retries should occur for permanent responses */
409  /*! \brief Interval at which retries should occur for all permanent responses */
410  unsigned int fatal_retry_interval;
411  /*! \brief Treat authentication challenges that we cannot handle as permanent failures */
413  /*! \brief Determines whether SIP Path support should be advertised */
414  unsigned int support_path;
415  /*! \brief Determines whether SIP Outbound support should be advertised */
416  unsigned int support_outbound;
417  /*! \brief Type of security negotiation to use (RFC 3329). */
418  enum ast_sip_security_negotiation security_negotiation;
419  /*! \brief Client security mechanisms (RFC 3329). */
421  /*! \brief Security mechanisms of the peer (RFC 3329). */
423  /*! CSeq number of last sent auth request. */
424  unsigned int auth_cseq;
425  /*! \brief Serializer for stuff and things */
427  /*! \brief Configured authentication credentials */
429  /*! \brief Registration should be destroyed after completion of transaction */
430  unsigned int destroy:1;
431  /*! \brief Non-zero if we have attempted sending a REGISTER with authentication */
432  unsigned int auth_attempted:1;
433  /*! \brief Status code of last response if we have tried to register before */
435  /*! \brief The name of the transport to be used for the registration */
437  /*! \brief The name of the registration sorcery object */
439  /*! \brief Expected time of registration lapse/expiration */
440  unsigned int registration_expires;
441  /*! \brief The value for the User-Agent header sent in requests */
442  char *user_agent;
443 };
444 
445 /*! \brief Outbound registration state information (persists for lifetime that registration should exist) */
447  /*! \brief Outbound registration configuration object */
449  /*! \brief Client state information */
451 };
452 
453 /*! Time needs to be long enough for a transaction to timeout if nothing replies. */
454 #define MAX_UNLOAD_TIMEOUT_TIME 35 /* Seconds */
455 
456 /*! Shutdown group to monitor sip_outbound_registration_client_state serializers. */
457 static struct ast_serializer_shutdown_group *shutdown_group;
458 
459 /*! \brief Default number of state container buckets */
460 #define DEFAULT_STATE_BUCKETS 53
461 static AO2_GLOBAL_OBJ_STATIC(current_states);
462 
463 /*! subscription id for network change events */
465 
466 /*! \brief hashing function for state objects */
467 static int registration_state_hash(const void *obj, const int flags)
468 {
469  const struct sip_outbound_registration_state *object;
470  const char *key;
471 
472  switch (flags & OBJ_SEARCH_MASK) {
473  case OBJ_SEARCH_KEY:
474  key = obj;
475  break;
476  case OBJ_SEARCH_OBJECT:
477  object = obj;
479  break;
480  default:
481  ast_assert(0);
482  return 0;
483  }
484  return ast_str_hash(key);
485 }
486 
487 /*! \brief comparator function for state objects */
488 static int registration_state_cmp(void *obj, void *arg, int flags)
489 {
490  const struct sip_outbound_registration_state *object_left = obj;
491  const struct sip_outbound_registration_state *object_right = arg;
492  const char *right_key = arg;
493  int cmp;
494 
495  switch (flags & OBJ_SEARCH_MASK) {
496  case OBJ_SEARCH_OBJECT:
497  right_key = ast_sorcery_object_get_id(object_right->registration);
498  /* Fall through */
499  case OBJ_SEARCH_KEY:
500  cmp = strcmp(ast_sorcery_object_get_id(object_left->registration), right_key);
501  break;
503  /* Not supported by container. */
504  ast_assert(0);
505  return 0;
506  default:
507  cmp = 0;
508  break;
509  }
510  if (cmp) {
511  return 0;
512  }
513  return CMP_MATCH;
514 }
515 
516 static struct sip_outbound_registration_state *get_state(const char *id)
517 {
518  struct sip_outbound_registration_state *state = NULL;
519  struct ao2_container *states;
520 
521  states = ao2_global_obj_ref(current_states);
522  if (states) {
523  state = ao2_find(states, id, OBJ_SEARCH_KEY);
524  ao2_ref(states, -1);
525  }
526  return state;
527 }
528 
529 static struct ao2_container *get_registrations(void)
530 {
532  ast_sip_get_sorcery(), "registration",
534 
535  return registrations;
536 }
537 
538 /*! \brief Callback function for matching an outbound registration based on line */
539 static int line_identify_relationship(void *obj, void *arg, int flags)
540 {
541  struct sip_outbound_registration_state *state = obj;
542  pjsip_param *line = arg;
543 
544  return !pj_strcmp2(&line->value, state->client_state->line) ? CMP_MATCH : 0;
545 }
546 
547 static struct pjsip_param *get_uri_option_line(const void *uri)
548 {
549  static const pj_str_t LINE_STR = { "line", 4 };
550 
551  return ast_sip_pjsip_uri_get_other_param((pjsip_uri *)uri, &LINE_STR);
552 }
553 
554 /*! \brief Endpoint identifier which uses the 'line' parameter to establish a relationship to an outgoing registration */
555 static struct ast_sip_endpoint *line_identify(pjsip_rx_data *rdata)
556 {
557  pjsip_param *line;
558  RAII_VAR(struct ao2_container *, states, NULL, ao2_cleanup);
559  RAII_VAR(struct sip_outbound_registration_state *, state, NULL, ao2_cleanup);
560 
561  if (!(line = get_uri_option_line(rdata->msg_info.to->uri))
562  && !(line = get_uri_option_line(rdata->msg_info.msg->line.req.uri))) {
563  return NULL;
564  }
565 
566  states = ao2_global_obj_ref(current_states);
567  if (!states) {
568  return NULL;
569  }
570 
571  state = ao2_callback(states, 0, line_identify_relationship, line);
572  if (!state || ast_strlen_zero(state->registration->endpoint)) {
573  return NULL;
574  }
575 
576  ast_debug(3, "Determined relationship to outbound registration '%s' based on line '%s', using configured endpoint '%s'\n",
578 
579  return ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", state->registration->endpoint);
580 }
581 
582 static struct ast_sip_endpoint_identifier line_identifier = {
583  .identify_endpoint = line_identify,
584 };
585 
586 /*! \brief Helper function which cancels the timer on a client */
587 static void cancel_registration(struct sip_outbound_registration_client_state *client_state)
588 {
589  if (pj_timer_heap_cancel_if_active(pjsip_endpt_get_timer_heap(ast_sip_get_pjsip_endpoint()),
590  &client_state->timer, client_state->timer.id)) {
591  /* The timer was successfully cancelled, drop the refcount of client_state */
592  ao2_ref(client_state, -1);
593  }
594 }
595 
596 static pj_str_t PATH_NAME = { "path", 4 };
597 static pj_str_t OUTBOUND_NAME = { "outbound", 8 };
598 
599 AST_VECTOR(pjsip_generic_string_hdr_vector, pjsip_generic_string_hdr *);
600 
601 /*!
602  * \internal
603  * \brief Callback function which finds a contact whose contact_status has security mechanisms.
604  *
605  * \param obj Pointer to the ast_sip_contact.
606  * \param arg Pointer-pointer to a contact_status that will be set to the contact_status found by this function.
607  * \param flags Flags used by the ao2_callback function.
608  *
609  * \note The refcount of the found contact_status must be decremented by the caller.
610  */
611 static int contact_has_security_mechanisms(void *obj, void *arg, int flags)
612 {
613  struct ast_sip_contact *contact = obj;
614  struct ast_sip_contact_status **ret = arg;
615  struct ast_sip_contact_status *contact_status = ast_sip_get_contact_status(contact);
616 
617  if (!contact_status) {
618  return -1;
619  }
620  if (!AST_VECTOR_SIZE(&contact_status->security_mechanisms)) {
621  ao2_cleanup(contact_status);
622  return -1;
623  }
624  *ret = contact_status;
625  return 0;
626 }
627 
628 static int contact_add_security_headers_to_status(void *obj, void *arg, int flags)
629 {
630  struct ast_sip_contact *contact = obj;
631  struct pjsip_generic_string_hdr_vector *header_vector = arg;
632  struct ast_sip_contact_status *contact_status = ast_sip_get_contact_status(contact);
633 
634  if (!contact_status) {
635  return -1;
636  }
637  if (AST_VECTOR_SIZE(&contact_status->security_mechanisms)) {
638  goto out;
639  }
640 
641  ao2_lock(contact_status);
643  ao2_unlock(contact_status);
644 
645 out:
646  ao2_cleanup(contact_status);
647  return 0;
648 }
649 
650 /*! \brief Adds security negotiation mechanisms of outbound registration client state as Security headers to tdata. */
651 static void add_security_headers(struct sip_outbound_registration_client_state *client_state,
652  pjsip_tx_data *tdata)
653 {
654  int add_sec_client_header = 0;
655  struct sip_outbound_registration *reg = NULL;
656  struct ast_sip_endpoint *endpt = NULL;
657  struct ao2_container *contact_container;
658  struct ast_sip_contact_status *contact_status = NULL;
659  struct ast_sip_security_mechanism_vector *sec_mechs = NULL;
660  static const pj_str_t security_verify = { "Security-Verify", 15 };
661  static const pj_str_t security_client = { "Security-Client", 15 };
662 
663  if (client_state->security_negotiation != AST_SIP_SECURITY_NEG_MEDIASEC) {
664  return;
665  }
666 
667  /* Get contact status through registration -> endpoint name -> aor -> contact (if set) */
668  if ((reg = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "registration", client_state->registration_name))
669  && !ast_strlen_zero(reg->endpoint) && (endpt = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", reg->endpoint))
670  && (contact_container = ast_sip_location_retrieve_contacts_from_aor_list(endpt->aors))) {
671  /* Retrieve all contacts associated with aors from this endpoint
672  * and find the first one that has security mechanisms.
673  */
674  ao2_callback(contact_container, 0, contact_has_security_mechanisms, &contact_status);
675  if (contact_status) {
676  ao2_lock(contact_status);
677  sec_mechs = &contact_status->security_mechanisms;
678  }
679  ao2_cleanup(contact_container);
680  }
681  /* Use client_state->server_security_mechanisms if contact_status does not exist. */
682  if (!contact_status && AST_VECTOR_SIZE(&client_state->server_security_mechanisms)) {
683  sec_mechs = &client_state->server_security_mechanisms;
684  }
685  if (client_state->status == SIP_REGISTRATION_REJECTED_TEMPORARY || client_state->auth_attempted) {
686  if (sec_mechs != NULL && pjsip_msg_find_hdr_by_name(tdata->msg, &security_verify, NULL) == NULL) {
687  ast_sip_add_security_headers(sec_mechs, "Security-Verify", 0, tdata);
688  }
689  if (client_state->last_status_code == 494) {
690  ast_sip_remove_headers_by_name_and_value(tdata->msg, &security_client, NULL);
691  } else {
692  /* necessary if a retry occures */
693  add_sec_client_header = (pjsip_msg_find_hdr_by_name(tdata->msg, &security_client, NULL) == NULL) ? 1 : 0;
694  }
695  } else {
696  ast_sip_add_security_headers(&client_state->security_mechanisms, "Security-Client", 0, tdata);
697  }
698 
699  if (add_sec_client_header) {
700  ast_sip_add_security_headers(&client_state->security_mechanisms, "Security-Client", 0, tdata);
701  }
702 
703  /* Cleanup */
704  if (contact_status) {
705  ao2_unlock(contact_status);
706  ao2_cleanup(contact_status);
707  }
708  ao2_cleanup(endpt);
709  ao2_cleanup(reg);
710 }
711 
712 /*! \brief Helper function which sends a message and cleans up, if needed, on failure */
713 static pj_status_t registration_client_send(struct sip_outbound_registration_client_state *client_state,
714  pjsip_tx_data *tdata)
715 {
716  pj_status_t status;
717  int *callback_invoked;
718  pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
719 
720  callback_invoked = ast_threadstorage_get(&register_callback_invoked, sizeof(int));
721  if (!callback_invoked) {
722  pjsip_tx_data_dec_ref(tdata);
723  return PJ_ENOMEM;
724  }
725  *callback_invoked = 0;
726 
727  /* Due to the message going out the callback may now be invoked, so bump the count */
728  ao2_ref(client_state, +1);
729  /*
730  * We also bump tdata in expectation of saving it to client_state->last_tdata.
731  * We have to do it BEFORE pjsip_regc_send because if it succeeds, it decrements
732  * the ref count on its own.
733  */
734  pjsip_tx_data_add_ref(tdata);
735 
736  /* Add Security-Verify or Security-Client headers */
737  add_security_headers(client_state, tdata);
738 
739  /*
740  * Replace the User-Agent header if a different one should be used
741  */
742  if (!ast_strlen_zero(client_state->user_agent)) {
743  static const pj_str_t user_agent_str = { "User-Agent", 10 };
744  pjsip_generic_string_hdr *default_user_agent_hdr;
745  pjsip_generic_string_hdr *user_agent_hdr;
746  pj_str_t user_agent_val;
747  default_user_agent_hdr = pjsip_msg_find_hdr_by_name(tdata->msg, &user_agent_str, NULL);
748  user_agent_val = pj_str(client_state->user_agent);
749  user_agent_hdr = pjsip_generic_string_hdr_create(tdata->pool, &user_agent_str, &user_agent_val);
750  if (!user_agent_hdr) {
751  ast_log(LOG_ERROR, "Could not add custom User-Agent to outbound registration %s, sending REGISTER request with non-custom header\n", client_state->registration_name);
752  } else {
753  if (default_user_agent_hdr) {
754  pj_list_erase(default_user_agent_hdr);
755  }
756  pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *)user_agent_hdr);
757  }
758  }
759 
760  /*
761  * Set the transport in case transports were reloaded.
762  * When pjproject removes the extraneous error messages produced,
763  * we can check status and only set the transport and resend if there was an error
764  */
765  ast_sip_set_tpselector_from_transport_name(client_state->transport_name, &selector);
766  pjsip_regc_set_transport(client_state->client, &selector);
767  ast_sip_tpselector_unref(&selector);
768 
769  status = pjsip_regc_send(client_state->client, tdata);
770 
771  /*
772  * If the attempt to send the message failed and the callback was not invoked we need to
773  * drop the references we just added
774  */
775  if ((status != PJ_SUCCESS) && !(*callback_invoked)) {
776  pjsip_tx_data_dec_ref(tdata);
777  ao2_ref(client_state, -1);
778  return status;
779  }
780 
781  /*
782  * Decref the old last_data before replacing it.
783  * BTW, it's quite possible that last_data == tdata
784  * if we're trying successive servers in an SRV set.
785  */
786  if (client_state->last_tdata) {
787  pjsip_tx_data_dec_ref(client_state->last_tdata);
788  }
789  client_state->last_tdata = tdata;
790 
791  return status;
792 }
793 
794 /*! \brief Helper function to add string to Supported header */
795 static int add_to_supported_header(pjsip_tx_data *tdata, pj_str_t *name)
796 {
797  pjsip_supported_hdr *hdr;
798  int i;
799 
800  hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_SUPPORTED, NULL);
801  if (!hdr) {
802  /* insert a new Supported header */
803  hdr = pjsip_supported_hdr_create(tdata->pool);
804  if (!hdr) {
805  pjsip_tx_data_dec_ref(tdata);
806  return 0;
807  }
808 
809  pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *)hdr);
810  }
811 
812  /* Don't add the value if it's already there */
813  for (i = 0; i < hdr->count; ++i) {
814  if (pj_stricmp(&hdr->values[i], name) == 0) {
815  return 1;
816  }
817  }
818 
819  if (hdr->count >= PJSIP_GENERIC_ARRAY_MAX_COUNT) {
820  return 0;
821  }
822 
823  /* add on to the existing Supported header */
824  pj_strassign(&hdr->values[hdr->count++], name);
825 
826  return 1;
827 }
828 
829 /*! \brief Helper function to add configured supported headers */
830 static int add_configured_supported_headers(struct sip_outbound_registration_client_state *client_state, pjsip_tx_data *tdata)
831 {
832  if (client_state->support_path) {
833  if (!add_to_supported_header(tdata, &PATH_NAME)) {
834  return 0;
835  }
836  }
837 
838  if (client_state->support_outbound) {
839  if (!add_to_supported_header(tdata, &OUTBOUND_NAME)) {
840  return 0;
841  }
842  }
843 
844  return 1;
845 }
846 
847 /*! \brief Callback function for registering */
848 static int handle_client_registration(void *data)
849 {
850  RAII_VAR(struct sip_outbound_registration_client_state *, client_state, data, ao2_cleanup);
851  pjsip_tx_data *tdata;
852 
853  if (set_outbound_initial_authentication_credentials(client_state->client, &client_state->outbound_auths)) {
854  ast_log(LOG_WARNING, "Failed to set initial authentication credentials\n");
855  }
856 
857  if (client_state->status == SIP_REGISTRATION_STOPPED
858  || pjsip_regc_register(client_state->client, PJ_FALSE, &tdata) != PJ_SUCCESS) {
859  return 0;
860  }
861 
862  if (DEBUG_ATLEAST(1)) {
863  pjsip_regc_info info;
864 
865  pjsip_regc_get_info(client_state->client, &info);
866  ast_log(LOG_DEBUG, "Outbound REGISTER attempt %u to '%.*s' with client '%.*s'\n",
867  client_state->retries + 1,
868  (int) info.server_uri.slen, info.server_uri.ptr,
869  (int) info.client_uri.slen, info.client_uri.ptr);
870  }
871 
872  if (!add_configured_supported_headers(client_state, tdata)) {
873  ast_log(LOG_WARNING, "Failed to set supported headers\n");
874  return -1;
875  }
876 
877  registration_client_send(client_state, tdata);
878 
879  return 0;
880 }
881 
882 /*! \brief Timer callback function, used just for registrations */
883 static void sip_outbound_registration_timer_cb(pj_timer_heap_t *timer_heap, struct pj_timer_entry *entry)
884 {
885  struct sip_outbound_registration_client_state *client_state = entry->user_data;
886 
887  entry->id = 0;
888 
889  /*
890  * Transfer client_state reference to serializer task so the
891  * nominal path will not dec the client_state ref in this
892  * pjproject callback thread.
893  */
894  if (ast_sip_push_task(client_state->serializer, handle_client_registration, client_state)) {
895  ast_log(LOG_WARNING, "Scheduled outbound registration could not be executed.\n");
896  ao2_ref(client_state, -1);
897  }
898 }
899 
900 /*! \brief Helper function which sets up the timer to re-register in a specific amount of time */
901 static void schedule_registration(struct sip_outbound_registration_client_state *client_state, unsigned int seconds)
902 {
903  pj_time_val delay = { .sec = seconds, };
904  pjsip_regc_info info;
905 
906  cancel_registration(client_state);
907 
908  pjsip_regc_get_info(client_state->client, &info);
909  ast_debug(1, "Scheduling outbound registration to server '%.*s' from client '%.*s' in %d seconds\n",
910  (int) info.server_uri.slen, info.server_uri.ptr,
911  (int) info.client_uri.slen, info.client_uri.ptr,
912  seconds);
913 
914  ao2_ref(client_state, +1);
915  if (pjsip_endpt_schedule_timer(ast_sip_get_pjsip_endpoint(), &client_state->timer, &delay) != PJ_SUCCESS) {
916  ast_log(LOG_WARNING, "Failed to schedule registration to server '%.*s' from client '%.*s'\n",
917  (int) info.server_uri.slen, info.server_uri.ptr,
918  (int) info.client_uri.slen, info.client_uri.ptr);
919  ao2_ref(client_state, -1);
920  }
921  client_state->registration_expires = ((int) time(NULL)) + seconds;
922 }
923 
924 static void update_client_state_status(struct sip_outbound_registration_client_state *client_state, enum sip_outbound_registration_status status)
925 {
926  const char *status_old;
927  const char *status_new;
928 
929  if (client_state->status == status) {
930  /* Status state did not change at all. */
931  return;
932  }
933 
934  status_old = sip_outbound_registration_status_str(client_state->status);
935  status_new = sip_outbound_registration_status_str(status);
936  client_state->status = status;
937 
938  if (!strcmp(status_old, status_new)) {
939  /*
940  * The internal status state may have changed but the status
941  * state we tell the world did not change at all.
942  */
943  return;
944  }
945 
946  ast_statsd_log_string_va("PJSIP.registrations.state.%s", AST_STATSD_GAUGE, "-1", 1.0,
947  status_old);
948  ast_statsd_log_string_va("PJSIP.registrations.state.%s", AST_STATSD_GAUGE, "+1", 1.0,
949  status_new);
950 }
951 
952 /*! \brief Callback function for unregistering (potentially) and destroying state */
953 static int handle_client_state_destruction(void *data)
954 {
955  struct sip_outbound_registration_client_state *client_state = data;
956 
957  cancel_registration(client_state);
958 
959  if (client_state->client) {
960  pjsip_regc_info info;
961  pjsip_tx_data *tdata;
962 
963  pjsip_regc_get_info(client_state->client, &info);
964 
965  if (info.is_busy == PJ_TRUE) {
966  /* If a client transaction is in progress we defer until it is complete */
967  ast_debug(1,
968  "Registration transaction is busy with server '%.*s' from client '%.*s'.\n",
969  (int) info.server_uri.slen, info.server_uri.ptr,
970  (int) info.client_uri.slen, info.client_uri.ptr);
971  client_state->destroy = 1;
972  ao2_ref(client_state, -1);
973  return 0;
974  }
975 
976  switch (client_state->status) {
977  case SIP_REGISTRATION_UNREGISTERED:
978  break;
979  case SIP_REGISTRATION_REGISTERED:
980  ast_debug(1,
981  "Trying to unregister with server '%.*s' from client '%.*s' before destruction.\n",
982  (int) info.server_uri.slen, info.server_uri.ptr,
983  (int) info.client_uri.slen, info.client_uri.ptr);
984 
985  update_client_state_status(client_state, SIP_REGISTRATION_STOPPING);
986  client_state->destroy = 1;
987  if (pjsip_regc_unregister(client_state->client, &tdata) == PJ_SUCCESS
988  && add_configured_supported_headers(client_state, tdata)
989  && registration_client_send(client_state, tdata) == PJ_SUCCESS) {
990  ao2_ref(client_state, -1);
991  return 0;
992  }
993  break;
994  case SIP_REGISTRATION_REJECTED_TEMPORARY:
995  case SIP_REGISTRATION_REJECTED_PERMANENT:
996  case SIP_REGISTRATION_STOPPING:
997  case SIP_REGISTRATION_STOPPED:
998  break;
999  }
1000 
1001  pjsip_regc_destroy(client_state->client);
1002  client_state->client = NULL;
1003  }
1004 
1005  update_client_state_status(client_state, SIP_REGISTRATION_STOPPED);
1006  ast_sip_auth_vector_destroy(&client_state->outbound_auths);
1009  ao2_ref(client_state, -1);
1010 
1011  return 0;
1012 }
1013 
1014 /*! \brief Structure for registration response */
1016  /*! \brief Response code for the registration attempt */
1017  int code;
1018  /*! \brief Expiration time for registration */
1020  /*! \brief Retry-After value */
1022  /*! \brief Outbound registration client state */
1024  /*! \brief The response message */
1025  pjsip_rx_data *rdata;
1026  /*! \brief Request for which the response was received */
1027  pjsip_tx_data *old_request;
1028  /*! \brief Key for the reliable transport in use */
1029  char transport_key[IP6ADDR_COLON_PORT_BUFLEN];
1030 };
1031 
1032 /*! \brief Registration response structure destructor */
1033 static void registration_response_destroy(void *obj)
1034 {
1035  struct registration_response *response = obj;
1036 
1037  if (response->rdata) {
1038  pjsip_rx_data_free_cloned(response->rdata);
1039  }
1040 
1041  if (response->old_request) {
1042  pjsip_tx_data_dec_ref(response->old_request);
1043  }
1044 
1045  ao2_cleanup(response->client_state);
1046 }
1047 
1048 /*! \brief Helper function which determines if a response code is temporal or not */
1049 static int sip_outbound_registration_is_temporal(unsigned int code,
1050  struct sip_outbound_registration_client_state *client_state)
1051 {
1052  /* Shamelessly taken from pjsua */
1053  if (code == PJSIP_SC_REQUEST_TIMEOUT ||
1054  code == PJSIP_SC_INTERNAL_SERVER_ERROR ||
1055  code == PJSIP_SC_BAD_GATEWAY ||
1056  code == PJSIP_SC_SERVICE_UNAVAILABLE ||
1057  code == PJSIP_SC_SERVER_TIMEOUT ||
1058  ((code == PJSIP_SC_UNAUTHORIZED ||
1059  code == PJSIP_SC_PROXY_AUTHENTICATION_REQUIRED) &&
1060  !client_state->auth_rejection_permanent) ||
1061  PJSIP_IS_STATUS_IN_CLASS(code, 600)) {
1062  return 1;
1063  } else {
1064  return 0;
1065  }
1066 }
1067 
1068 static void schedule_retry(struct registration_response *response, unsigned int interval,
1069  const char *server_uri, const char *client_uri)
1070 {
1071  update_client_state_status(response->client_state, SIP_REGISTRATION_REJECTED_TEMPORARY);
1072  schedule_registration(response->client_state, interval);
1073 
1074  if (response->rdata) {
1075  ast_log(LOG_WARNING, "Temporal response '%d' received from '%s' on "
1076  "registration attempt to '%s', retrying in '%u'\n",
1077  response->code, server_uri, client_uri, interval);
1078  } else {
1079  ast_log(LOG_WARNING, "No response received from '%s' on "
1080  "registration attempt to '%s', retrying in '%u'\n",
1081  server_uri, client_uri, interval);
1082  }
1083 }
1084 
1085 static int reregister_immediately_cb(void *obj)
1086 {
1087  struct sip_outbound_registration_state *state = obj;
1088 
1089  if (state->client_state->status != SIP_REGISTRATION_REGISTERED) {
1090  ao2_ref(state, -1);
1091  return 0;
1092  }
1093 
1094  if (DEBUG_ATLEAST(1)) {
1095  pjsip_regc_info info;
1096 
1097  pjsip_regc_get_info(state->client_state->client, &info);
1098  ast_log(LOG_DEBUG,
1099  "Outbound registration transport to server '%.*s' from client '%.*s' shutdown\n",
1100  (int) info.server_uri.slen, info.server_uri.ptr,
1101  (int) info.client_uri.slen, info.client_uri.ptr);
1102  }
1103 
1104  cancel_registration(state->client_state);
1105 
1106  ao2_ref(state->client_state, +1);
1107  handle_client_registration(state->client_state);
1108 
1109  ao2_ref(state, -1);
1110  return 0;
1111 }
1112 
1113 /*!
1114  * \internal
1115  * \brief The reliable transport we registered using has shutdown.
1116  * \since 13.18.0
1117  *
1118  * \param obj What is needed to initiate a reregister attempt.
1119  *
1120  * \note Normally executed by the pjsip monitor thread.
1121  */
1122 static void registration_transport_shutdown_cb(void *obj)
1123 {
1124  const char *registration_name = obj;
1125  struct sip_outbound_registration_state *state;
1126 
1127  state = get_state(registration_name);
1128  if (!state) {
1129  /* Registration no longer exists or shutting down. */
1130  return;
1131  }
1132  if (ast_sip_push_task(state->client_state->serializer, reregister_immediately_cb, state)) {
1133  ao2_ref(state, -1);
1134  }
1135 }
1136 
1137 static int monitor_matcher(void *a, void *b)
1138 {
1139  char *ma = a;
1140  char *mb = b;
1141 
1142  return strcmp(ma, mb) == 0;
1143 }
1144 
1145 static void registration_transport_monitor_setup(const char *transport_key, const char *registration_name)
1146 {
1147  char *monitor;
1148 
1149  monitor = ao2_alloc_options(strlen(registration_name) + 1, NULL,
1151  if (!monitor) {
1152  return;
1153  }
1154  strcpy(monitor, registration_name);/* Safe */
1155 
1156  /*
1157  * We'll ignore if the transport has already been shutdown before we
1158  * register the monitor. We might get into a message spamming infinite
1159  * loop of registration, shutdown, reregistration...
1160  */
1161  ast_sip_transport_monitor_register_replace_key(transport_key, registration_transport_shutdown_cb,
1162  monitor, monitor_matcher);
1163  ao2_ref(monitor, -1);
1164 }
1165 
1166 static void save_response_fields_to_transport(struct registration_response *response)
1167 {
1168  static const pj_str_t associated_uri_str = { "P-Associated-URI", 16 };
1169  static const pj_str_t service_route_str = { "Service-Route", 13 };
1170  pjsip_hdr *header = NULL;
1171  pjsip_msg *msg = response->rdata->msg_info.msg;
1172  struct ast_sip_service_route_vector *service_routes = NULL;
1173 
1174  /* If no transport is specified then we can't update any */
1175  if (ast_strlen_zero(response->client_state->transport_name)) {
1176  return;
1177  }
1178 
1179  ast_sip_transport_state_set_transport(response->client_state->transport_name, response->rdata->tp_info.transport);
1180 
1181  while ((header = pjsip_msg_find_hdr_by_name(msg, &service_route_str, header ? header->next : NULL))) {
1182  char *service_route;
1183  size_t size;
1184 
1185  /* The below code takes the approach that if we can't store all service routes then we
1186  * store none at all. This gives a predictable failure condition instead of storing a
1187  * partial list and having partial route headers.
1188  */
1189  size = pj_strlen(&((pjsip_generic_string_hdr*)header)->hvalue) + 1;
1190  service_route = ast_malloc(size);
1191  if (!service_route) {
1192  if (service_routes) {
1193  ast_sip_service_route_vector_destroy(service_routes);
1194  service_routes = NULL;
1195  }
1196  break;
1197  }
1198 
1199  ast_copy_pj_str(service_route, &((pjsip_generic_string_hdr*)header)->hvalue, size);
1200 
1201  if (!service_routes) {
1202  service_routes = ast_sip_service_route_vector_alloc();
1203  if (!service_routes) {
1204  ast_free(service_route);
1205  break;
1206  }
1207  }
1208 
1209  if (AST_VECTOR_APPEND(service_routes, service_route)) {
1210  ast_free(service_route);
1211  ast_sip_service_route_vector_destroy(service_routes);
1212  service_routes = NULL;
1213  break;
1214  }
1215  }
1216 
1217  /* If any service routes were handled then store them on the transport */
1218  if (service_routes) {
1219  ast_sip_transport_state_set_service_routes(response->client_state->transport_name, service_routes);
1220  }
1221 
1222  /* If an associated URI is present in the response we need to use it on any outgoing
1223  * traffic on the transport.
1224  */
1225  header = pjsip_msg_find_hdr_by_name(msg, &associated_uri_str, NULL);
1226  if (header) {
1227  char value[pj_strlen(&((pjsip_generic_string_hdr*)header)->hvalue) + 1];
1228 
1229  ast_copy_pj_str(value, &((pjsip_generic_string_hdr*)header)->hvalue, sizeof(value));
1230  ast_sip_transport_state_set_preferred_identity(response->client_state->transport_name, value);
1231  }
1232 }
1233 
1234 
1235 /*! \brief Callback function for handling a response to a registration attempt */
1236 static int handle_registration_response(void *data)
1237 {
1238  struct registration_response *response = data;
1239  pjsip_regc_info info;
1240  char server_uri[PJSIP_MAX_URL_SIZE];
1241  char client_uri[PJSIP_MAX_URL_SIZE];
1242 
1243  if (response->client_state->status == SIP_REGISTRATION_STOPPED) {
1244  ao2_ref(response, -1);
1245  return 0;
1246  }
1247 
1248  pjsip_regc_get_info(response->client_state->client, &info);
1249  ast_copy_pj_str(server_uri, &info.server_uri, sizeof(server_uri));
1250  ast_copy_pj_str(client_uri, &info.client_uri, sizeof(client_uri));
1251  response->client_state->last_status_code = response->code;
1252 
1253  ast_debug(1, "Processing REGISTER response %d from server '%s' for client '%s'\n",
1254  response->code, server_uri, client_uri);
1255 
1256  if (response->code == 408 || response->code == 503) {
1257  if ((ast_sip_failover_request(response->old_request))) {
1258  int res = registration_client_send(response->client_state, response->old_request);
1259  /* The tdata ref was stolen */
1260  response->old_request = NULL;
1261  if (res == PJ_SUCCESS) {
1262  ao2_ref(response, -1);
1263  return 0;
1264  }
1265  }
1266  } else if ((response->code == 401 || response->code == 407 || response->code == 494)
1267  && (!response->client_state->auth_attempted
1268  || response->rdata->msg_info.cseq->cseq != response->client_state->auth_cseq)) {
1269  int res;
1270  pjsip_cseq_hdr *cseq_hdr;
1271  pjsip_tx_data *tdata;
1272 
1273  if (response->client_state->security_negotiation == AST_SIP_SECURITY_NEG_MEDIASEC) {
1274  struct sip_outbound_registration *reg = NULL;
1275  struct ast_sip_endpoint *endpt = NULL;
1276  struct ao2_container *contact_container = NULL;
1277  pjsip_generic_string_hdr *header;
1278  struct pjsip_generic_string_hdr_vector header_vector;
1279  static const pj_str_t security_server = { "Security-Server", 15 };
1280 
1281  if ((reg = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "registration",
1282  response->client_state->registration_name)) && reg->endpoint &&
1283  (endpt = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", reg->endpoint))) {
1284  /* Retrieve all contacts associated with aors from this endpoint (if set). */
1285  contact_container = ast_sip_location_retrieve_contacts_from_aor_list(endpt->aors);
1286  }
1287  /* Add server list of security mechanism to client_state and contact status if exists. */
1288  AST_VECTOR_INIT(&header_vector, 1);
1289  header = pjsip_msg_find_hdr_by_name(response->rdata->msg_info.msg, &security_server, NULL);
1290  for (; header;
1291  header = pjsip_msg_find_hdr_by_name(response->rdata->msg_info.msg, &security_server, header->next)) {
1292  AST_VECTOR_APPEND(&header_vector, header);
1294  }
1295  if (contact_container) {
1296  /* Add server security mechanisms to contact status of all associated contacts to be able to send correct
1297  * Security-Verify headers on subsequent non-REGISTER requests through this outbound registration.
1298  */
1299  ao2_callback(contact_container, OBJ_NODATA, contact_add_security_headers_to_status, &header_vector);
1300  ao2_cleanup(contact_container);
1301  }
1302  AST_VECTOR_FREE(&header_vector);
1303  ao2_cleanup(endpt);
1304  ao2_cleanup(reg);
1305  }
1306 
1307  if (response->code == 494) {
1308  update_client_state_status(response->client_state, SIP_REGISTRATION_REJECTED_TEMPORARY);
1309  response->client_state->retries++;
1310  schedule_registration(response->client_state, 0);
1311  ao2_ref(response, -1);
1312  return 0;
1313  } else if (!ast_sip_create_request_with_auth(&response->client_state->outbound_auths,
1314  response->rdata, response->old_request, &tdata)) {
1315  response->client_state->auth_attempted = 1;
1316  ast_debug(1, "Sending authenticated REGISTER to server '%s' from client '%s'\n",
1317  server_uri, client_uri);
1318  pjsip_tx_data_add_ref(tdata);
1319 
1320  res = registration_client_send(response->client_state, tdata);
1321 
1322  /* Save the cseq that actually got sent. */
1323  cseq_hdr = (pjsip_cseq_hdr *) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ,
1324  NULL);
1325  response->client_state->auth_cseq = cseq_hdr->cseq;
1326  pjsip_tx_data_dec_ref(tdata);
1327  if (res == PJ_SUCCESS) {
1328  ao2_ref(response, -1);
1329  return 0;
1330  }
1331  } else {
1332  ast_log(LOG_WARNING, "Failed to create authenticated REGISTER request to server '%s' from client '%s'\n",
1333  server_uri, client_uri);
1334  }
1335  /* Otherwise, fall through so the failure is processed appropriately */
1336  }
1337 
1338  response->client_state->auth_attempted = 0;
1339 
1340  if (PJSIP_IS_STATUS_IN_CLASS(response->code, 200)) {
1341  /* Check if this is in regards to registering or unregistering */
1342  if (response->expiration) {
1343  int next_registration_round;
1344 
1345  /* If the registration went fine simply reschedule registration for the future */
1346  ast_debug(1, "Outbound registration to '%s' with client '%s' successful\n", server_uri, client_uri);
1347  update_client_state_status(response->client_state, SIP_REGISTRATION_REGISTERED);
1348  response->client_state->retries = 0;
1349  next_registration_round = response->expiration - REREGISTER_BUFFER_TIME;
1350  if (next_registration_round < 0) {
1351  /* Re-register immediately. */
1352  next_registration_round = 0;
1353  }
1354  schedule_registration(response->client_state, next_registration_round);
1355 
1356  /* See if we should monitor for transport shutdown */
1357  if (PJSIP_TRANSPORT_IS_RELIABLE(response->rdata->tp_info.transport)) {
1358  registration_transport_monitor_setup(response->transport_key,
1359  response->client_state->registration_name);
1360  }
1361  } else {
1362  ast_debug(1, "Outbound unregistration to '%s' with client '%s' successful\n", server_uri, client_uri);
1363  update_client_state_status(response->client_state, SIP_REGISTRATION_UNREGISTERED);
1364  if (PJSIP_TRANSPORT_IS_RELIABLE(response->rdata->tp_info.transport)) {
1366  registration_transport_shutdown_cb, response->client_state->registration_name,
1367  monitor_matcher);
1368  }
1369  }
1370 
1371  save_response_fields_to_transport(response);
1372  } else if (response->client_state->destroy) {
1373  /* We need to deal with the pending destruction instead. */
1374  } else if (response->retry_after) {
1375  /* If we have been instructed to retry after a period of time, schedule it as such */
1376  schedule_retry(response, response->retry_after, server_uri, client_uri);
1377  } else if (response->client_state->retry_interval
1378  && sip_outbound_registration_is_temporal(response->code, response->client_state)) {
1379  if (response->client_state->retries == response->client_state->max_retries) {
1380  /* If we received enough temporal responses to exceed our maximum give up permanently */
1381  update_client_state_status(response->client_state, SIP_REGISTRATION_REJECTED_PERMANENT);
1382  ast_log(LOG_WARNING, "Maximum retries reached when attempting outbound registration to '%s' with client '%s', stopping registration attempt\n",
1383  server_uri, client_uri);
1384  } else {
1385  /* On the other hand if we can still try some more do so */
1386  response->client_state->retries++;
1387  schedule_retry(response, response->client_state->retry_interval, server_uri, client_uri);
1388  }
1389  } else {
1390  if (response->code == 403
1392  && response->client_state->retries < response->client_state->max_retries) {
1393  /* A forbidden response retry interval is configured and there are retries remaining */
1394  update_client_state_status(response->client_state, SIP_REGISTRATION_REJECTED_TEMPORARY);
1395  response->client_state->retries++;
1396  schedule_registration(response->client_state, response->client_state->forbidden_retry_interval);
1397  ast_log(LOG_WARNING, "403 Forbidden fatal response received from '%s' on registration attempt to '%s', retrying in '%u' seconds\n",
1398  server_uri, client_uri, response->client_state->forbidden_retry_interval);
1399  } else if (response->client_state->fatal_retry_interval
1400  && response->client_state->retries < response->client_state->max_retries) {
1401  /* Some kind of fatal failure response received, so retry according to configured interval */
1402  update_client_state_status(response->client_state, SIP_REGISTRATION_REJECTED_TEMPORARY);
1403  response->client_state->retries++;
1404  schedule_registration(response->client_state, response->client_state->fatal_retry_interval);
1405  ast_log(LOG_WARNING, "'%d' fatal response received from '%s' on registration attempt to '%s', retrying in '%u' seconds\n",
1406  response->code, server_uri, client_uri, response->client_state->fatal_retry_interval);
1407  } else {
1408  /* Finally if there's no hope of registering give up */
1409  update_client_state_status(response->client_state, SIP_REGISTRATION_REJECTED_PERMANENT);
1410  if (response->rdata) {
1411  ast_log(LOG_WARNING, "Fatal response '%d' received from '%s' on registration attempt to '%s', stopping outbound registration\n",
1412  response->code, server_uri, client_uri);
1413  } else {
1414  ast_log(LOG_WARNING, "Fatal registration attempt to '%s', stopping outbound registration\n", client_uri);
1415  }
1416  }
1417  }
1418 
1419  ast_system_publish_registry("PJSIP", client_uri, server_uri,
1420  sip_outbound_registration_status_str(response->client_state->status), NULL);
1421 
1422  if (response->client_state->destroy) {
1423  /* We have a pending deferred destruction to complete now. */
1424  ao2_ref(response->client_state, +1);
1425  handle_client_state_destruction(response->client_state);
1426  }
1427 
1428  ao2_ref(response, -1);
1429  return 0;
1430 }
1431 
1432 /*! \brief Callback function for outbound registration client */
1433 static void sip_outbound_registration_response_cb(struct pjsip_regc_cbparam *param)
1434 {
1435  struct sip_outbound_registration_client_state *client_state = param->token;
1436  struct registration_response *response;
1437  int *callback_invoked;
1438 
1439  callback_invoked = ast_threadstorage_get(&register_callback_invoked, sizeof(int));
1440 
1441  ast_assert(callback_invoked != NULL);
1442  ast_assert(client_state != NULL);
1443 
1444  *callback_invoked = 1;
1445 
1446  response = ao2_alloc(sizeof(*response), registration_response_destroy);
1447  if (!response) {
1448  ao2_ref(client_state, -1);
1449  return;
1450  }
1451  response->code = param->code;
1452  response->expiration = param->expiration;
1453  /*
1454  * Transfer client_state reference to response so the
1455  * nominal path will not dec the client_state ref in this
1456  * pjproject callback thread.
1457  */
1458  response->client_state = client_state;
1459 
1460  ast_debug(1, "Received REGISTER response %d(%.*s)\n",
1461  param->code, (int) param->reason.slen, param->reason.ptr);
1462 
1463  if (param->rdata) {
1464  struct pjsip_retry_after_hdr *retry_after;
1465  pjsip_transaction *tsx;
1466 
1467  retry_after = pjsip_msg_find_hdr(param->rdata->msg_info.msg, PJSIP_H_RETRY_AFTER,
1468  NULL);
1469  response->retry_after = retry_after ? retry_after->ivalue : 0;
1470 
1471  /*
1472  * If we got a response from the server, we have to use the tdata
1473  * from the transaction, not the tdata saved when we sent the
1474  * request. If we use the saved tdata, we won't process responses
1475  * like 423 Interval Too Brief correctly and we'll wind up sending
1476  * the bad Expires value again.
1477  */
1478  pjsip_tx_data_dec_ref(client_state->last_tdata);
1479 
1480  tsx = pjsip_rdata_get_tsx(param->rdata);
1481  response->old_request = tsx->last_tx;
1482  pjsip_tx_data_add_ref(response->old_request);
1483  pjsip_rx_data_clone(param->rdata, 0, &response->rdata);
1484  AST_SIP_MAKE_REMOTE_IPADDR_PORT_STR(param->rdata->tp_info.transport,
1485  response->transport_key);
1486 
1487  } else {
1488  /* old_request steals the reference */
1489  response->old_request = client_state->last_tdata;
1490  }
1491  client_state->last_tdata = NULL;
1492 
1493  /*
1494  * Transfer response reference to serializer task so the
1495  * nominal path will not dec the response ref in this
1496  * pjproject callback thread.
1497  */
1498  if (ast_sip_push_task(client_state->serializer, handle_registration_response, response)) {
1499  ast_log(LOG_WARNING, "Failed to pass incoming registration response to threadpool\n");
1500  ao2_cleanup(response);
1501  }
1502 }
1503 
1504 /*! \brief Destructor function for registration state */
1505 static void sip_outbound_registration_state_destroy(void *obj)
1506 {
1507  struct sip_outbound_registration_state *state = obj;
1508 
1509  ast_debug(3, "Destroying registration state for registration to server '%s' from client '%s'\n",
1510  state->registration ? state->registration->server_uri : "",
1511  state->registration ? state->registration->client_uri : "");
1512  ao2_cleanup(state->registration);
1513 
1514  if (!state->client_state) {
1515  /* Nothing to do */
1516  } else if (!state->client_state->serializer) {
1517  ao2_ref(state->client_state, -1);
1518  } else if (ast_sip_push_task(state->client_state->serializer,
1519  handle_client_state_destruction, state->client_state)) {
1520  ast_log(LOG_WARNING, "Failed to pass outbound registration client destruction to threadpool\n");
1521  ao2_ref(state->client_state, -1);
1522  }
1523 }
1524 
1525 /*! \brief Destructor function for client registration state */
1526 static void sip_outbound_registration_client_state_destroy(void *obj)
1527 {
1528  struct sip_outbound_registration_client_state *client_state = obj;
1529 
1530  ast_statsd_log_string("PJSIP.registrations.count", AST_STATSD_GAUGE, "-1", 1.0);
1531  ast_statsd_log_string_va("PJSIP.registrations.state.%s", AST_STATSD_GAUGE, "-1", 1.0,
1532  sip_outbound_registration_status_str(client_state->status));
1533 
1535  ast_free(client_state->transport_name);
1536  ast_free(client_state->registration_name);
1537  ast_free(client_state->user_agent);
1538  if (client_state->last_tdata) {
1539  pjsip_tx_data_dec_ref(client_state->last_tdata);
1540  }
1541 }
1542 
1543 /*! \brief Allocator function for registration state */
1544 static struct sip_outbound_registration_state *sip_outbound_registration_state_alloc(struct sip_outbound_registration *registration)
1545 {
1546  struct sip_outbound_registration_state *state;
1547  char tps_name[AST_TASKPROCESSOR_MAX_NAME + 1];
1548 
1549  state = ao2_alloc(sizeof(*state), sip_outbound_registration_state_destroy);
1550  if (!state) {
1551  return NULL;
1552  }
1553  state->client_state = ao2_alloc(sizeof(*state->client_state),
1554  sip_outbound_registration_client_state_destroy);
1555  if (!state->client_state) {
1556  ao2_cleanup(state);
1557  return NULL;
1558  }
1559 
1560  state->client_state->status = SIP_REGISTRATION_UNREGISTERED;
1561  pj_timer_entry_init(&state->client_state->timer, 0, state->client_state,
1562  sip_outbound_registration_timer_cb);
1563  state->client_state->transport_name = ast_strdup(registration->transport);
1565  ast_strdup(ast_sorcery_object_get_id(registration));
1566  state->client_state->user_agent = ast_strdup(registration->user_agent);
1567 
1568  ast_statsd_log_string("PJSIP.registrations.count", AST_STATSD_GAUGE, "+1", 1.0);
1569  ast_statsd_log_string_va("PJSIP.registrations.state.%s", AST_STATSD_GAUGE, "+1", 1.0,
1570  sip_outbound_registration_status_str(state->client_state->status));
1571 
1572  if (!state->client_state->transport_name
1573  || !state->client_state->registration_name) {
1574  ao2_cleanup(state);
1575  return NULL;
1576  }
1577 
1578  /* Create name with seq number appended. */
1579  ast_taskprocessor_build_name(tps_name, sizeof(tps_name), "pjsip/outreg/%s",
1580  ast_sorcery_object_get_id(registration));
1581 
1583  shutdown_group);
1584  if (!state->client_state->serializer) {
1585  ao2_cleanup(state);
1586  return NULL;
1587  }
1588 
1589  state->registration = ao2_bump(registration);
1590  return state;
1591 }
1592 
1593 /*! \brief Destructor function for registration information */
1594 static void sip_outbound_registration_destroy(void *obj)
1595 {
1596  struct sip_outbound_registration *registration = obj;
1597 
1598  ast_sip_auth_vector_destroy(&registration->outbound_auths);
1600 
1601  ast_string_field_free_memory(registration);
1602 }
1603 
1604 /*! \brief Allocator function for registration information */
1605 static void *sip_outbound_registration_alloc(const char *name)
1606 {
1607  struct sip_outbound_registration *registration;
1608 
1609  registration = ast_sorcery_generic_alloc(sizeof(*registration),
1610  sip_outbound_registration_destroy);
1611  if (!registration || ast_string_field_init(registration, 256)) {
1612  ao2_cleanup(registration);
1613  return NULL;
1614  }
1615 
1616  return registration;
1617 }
1618 
1619 /*! \brief Helper function which populates a pj_str_t with a contact header */
1620 static int sip_dialog_create_contact(pj_pool_t *pool, pj_str_t *contact, const char *user,
1621  const pj_str_t *target, pjsip_tpselector *selector, const char *line, const char *header_params)
1622 {
1623  pj_str_t tmp, local_addr;
1624  pjsip_uri *uri;
1625  pjsip_sip_uri *sip_uri;
1626  pjsip_transport_type_e type;
1627  int local_port;
1628 
1629  pj_strdup_with_null(pool, &tmp, target);
1630 
1631  if (!(uri = pjsip_parse_uri(pool, tmp.ptr, tmp.slen, 0)) ||
1632  (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri))) {
1633  return -1;
1634  }
1635 
1636  sip_uri = pjsip_uri_get_uri(uri);
1637 
1638  type = pjsip_transport_get_type_from_name(&sip_uri->transport_param);
1639  if (PJSIP_URI_SCHEME_IS_SIPS(sip_uri)) {
1640  if (type == PJSIP_TRANSPORT_UNSPECIFIED
1641  || !(pjsip_transport_get_flag_from_type(type) & PJSIP_TRANSPORT_SECURE)) {
1642  type = PJSIP_TRANSPORT_TLS;
1643  }
1644  } else if (!sip_uri->transport_param.slen) {
1645  type = PJSIP_TRANSPORT_UDP;
1646  } else if (type == PJSIP_TRANSPORT_UNSPECIFIED) {
1647  return -1;
1648  }
1649 
1650  if (pj_strchr(&sip_uri->host, ':')) {
1651  type |= PJSIP_TRANSPORT_IPV6;
1652  }
1653 
1654  if (pjsip_tpmgr_find_local_addr(pjsip_endpt_get_tpmgr(ast_sip_get_pjsip_endpoint()),
1655  pool, type, selector, &local_addr, &local_port) != PJ_SUCCESS) {
1656  return -1;
1657  }
1658 
1659  if (!pj_strchr(&sip_uri->host, ':') && pj_strchr(&local_addr, ':')) {
1660  type |= PJSIP_TRANSPORT_IPV6;
1661  }
1662 
1663  contact->ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
1664  contact->slen = pj_ansi_snprintf(contact->ptr, PJSIP_MAX_URL_SIZE,
1665  "<%s:%s@%s%.*s%s:%d%s%s%s%s>%s%s",
1666  ((pjsip_transport_get_flag_from_type(type) & PJSIP_TRANSPORT_SECURE) && PJSIP_URI_SCHEME_IS_SIPS(uri)) ? "sips" : "sip",
1667  user,
1668  (type & PJSIP_TRANSPORT_IPV6) ? "[" : "",
1669  (int)local_addr.slen,
1670  local_addr.ptr,
1671  (type & PJSIP_TRANSPORT_IPV6) ? "]" : "",
1672  local_port,
1673  (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? ";transport=" : "",
1674  (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? pjsip_transport_get_type_name(type) : "",
1675  !ast_strlen_zero(line) ? ";line=" : "",
1676  S_OR(line, ""),
1677  !ast_strlen_zero(header_params) ? ";" : "",
1678  S_OR(header_params, ""));
1679 
1680  return 0;
1681 }
1682 
1683 /*!
1684  * \internal
1685  * \brief Check if a registration can be reused
1686  *
1687  * This checks if the existing outbound registration's configuration differs from a newly-applied
1688  * outbound registration to see if the applied one.
1689  *
1690  * \param existing The pre-existing outbound registration
1691  * \param applied The newly-created registration
1692  */
1693 static int can_reuse_registration(struct sip_outbound_registration *existing,
1694  struct sip_outbound_registration *applied)
1695 {
1696  int rc = 1;
1697  struct ast_sorcery *sorcery = ast_sip_get_sorcery();
1698  struct ast_variable *ve = ast_sorcery_objectset_create(sorcery, existing);
1699  struct ast_variable *va = ast_sorcery_objectset_create(sorcery, applied);
1700  struct ast_variable *vc = NULL;
1701 
1702  if (ast_sorcery_changeset_create(ve, va, &vc) || vc != NULL) {
1703  rc = 0;
1704  ast_debug(4, "Registration '%s' changed. Can't re-use.\n", ast_sorcery_object_get_id(existing));
1705  } else {
1706  ast_debug(4, "Registration '%s' didn't change. Can re-use\n", ast_sorcery_object_get_id(existing));
1707  }
1708 
1712 
1713  return rc;
1714 }
1715 
1716 /*! \brief Get google oauth2 access token using refresh token */
1717 static const char *fetch_google_access_token(const struct ast_sip_auth *auth)
1718 {
1719  char *cmd = NULL;
1720  const char *token;
1721  const char *url = "https://www.googleapis.com/oauth2/v3/token";
1722  char buf[4096];
1723  int res;
1724  struct ast_json_error error;
1725  struct ast_json *json;
1726 
1727  /* set timeout to be shorter than default 180s (also checks func_curl is available) */
1728  if (ast_func_write(NULL, "CURLOPT(conntimeout)", "10")) {
1729  ast_log(LOG_ERROR, "CURL is unavailable. This is required for Google OAuth 2.0 authentication. Please ensure it is loaded.\n");
1730  return NULL;
1731  }
1732 
1733  res = ast_asprintf(&cmd,
1734  "CURL(%s,client_id=%s&client_secret=%s&refresh_token=%s&grant_type=refresh_token)",
1735  url, auth->oauth_clientid, auth->oauth_secret, auth->refresh_token);
1736  if (res < 0) {
1737  return NULL;
1738  }
1739 
1740  ast_debug(2, "Performing Google OAuth 2.0 authentication using command: %s\n", cmd);
1741 
1742  buf[0] = '\0';
1743  res = ast_func_read(NULL, cmd, buf, sizeof(buf));
1744  ast_free(cmd);
1745  if (res) {
1746  ast_log(LOG_ERROR, "Could not retrieve Google OAuth 2.0 authentication\n");
1747  return NULL;
1748  }
1749 
1750  ast_debug(2, "Google OAuth 2.0 authentication returned: %s\n", buf);
1751 
1752  json = ast_json_load_string(buf, &error);
1753  if (!json) {
1754  ast_log(LOG_ERROR, "Could not parse Google OAuth 2.0 authentication: %d(%d) %s: '%s'\n",
1755  error.line, error.column, error.text, buf);
1756  return NULL;
1757  }
1758 
1759  token = ast_json_string_get(ast_json_object_get(json, "access_token"));
1760  if (!token) {
1761  ast_log(LOG_ERROR, "Could not find Google OAuth 2.0 access_token in: '%s'\n",
1762  buf);
1763  }
1764  token = ast_strdup(token);
1765  ast_json_unref(json);
1766  return token;
1767 }
1768 
1769 /*!
1770  * \internal
1771  * \brief Set pjsip registration context with any authentication credentials that need to be
1772  * sent in the initial registration request
1773  *
1774  * \param regc The pjsip registration context
1775  * \param auth_vector The vector of configured authentication credentials
1776  */
1777 static int set_outbound_initial_authentication_credentials(pjsip_regc *regc,
1778  const struct ast_sip_auth_vector *auth_vector)
1779 {
1780  size_t auth_size = AST_VECTOR_SIZE(auth_vector);
1781  struct ast_sip_auth *auths[auth_size];
1782  const char *access_token;
1783  pjsip_cred_info auth_creds[1];
1784  pjsip_auth_clt_pref prefs;
1785  int res = 0;
1786  int idx;
1787 
1788  memset(auths, 0, sizeof(auths));
1789  if (ast_sip_retrieve_auths(auth_vector, auths)) {
1790  res = -1;
1791  goto cleanup;
1792  }
1793 
1794  for (idx = 0; idx < auth_size; ++idx) {
1795  switch (auths[idx]->type) {
1796  case AST_SIP_AUTH_TYPE_GOOGLE_OAUTH:
1797  pj_cstr(&auth_creds[0].username, auths[idx]->auth_user);
1798  pj_cstr(&auth_creds[0].scheme, "Bearer");
1799  pj_cstr(&auth_creds[0].realm, auths[idx]->realm);
1800  ast_debug(2, "Obtaining Google OAuth access token\n");
1801  access_token = fetch_google_access_token(auths[idx]);
1802  if (!access_token) {
1803  ast_log(LOG_WARNING, "Obtaining Google OAuth access token failed\n");
1804  access_token = auths[idx]->auth_pass;
1805  res = -1;
1806  }
1807  ast_debug(2, "Setting data to '%s'\n", access_token);
1808 
1809  pj_cstr(&auth_creds[0].data, access_token);
1810  auth_creds[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
1811 
1812  pjsip_regc_set_credentials(regc, 1, auth_creds);
1813 
1814  /* for oauth, send auth without waiting for unauthorized response */
1815  prefs.initial_auth = PJ_TRUE;
1816  pj_cstr(&prefs.algorithm, "oauth");
1817  pjsip_regc_set_prefs(regc, &prefs);
1818 
1819  if (access_token != auths[idx]->auth_pass) {
1820  ast_free((char *) access_token);
1821  }
1822  break;
1823  default:
1824  /* other cases handled after receiving auth rejection */
1825  break;
1826  }
1827  }
1828 
1829 cleanup:
1830  ast_sip_cleanup_auths(auths, auth_size);
1831  return res;
1832 }
1833 
1834 /*! \brief Helper function that allocates a pjsip registration client and configures it */
1835 static int sip_outbound_registration_regc_alloc(void *data)
1836 {
1837  struct sip_outbound_registration_state *state = data;
1838  RAII_VAR(struct sip_outbound_registration *, registration,
1839  ao2_bump(state->registration), ao2_cleanup);
1840  pj_pool_t *pool;
1841  pj_str_t tmp;
1842  pjsip_uri *uri;
1843  pj_str_t server_uri, client_uri, contact_uri;
1844  pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
1845 
1846  pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "URI Validation", 256, 256);
1847  if (!pool) {
1848  ast_log(LOG_ERROR, "Could not create pool for URI validation on outbound registration '%s'\n",
1849  ast_sorcery_object_get_id(registration));
1850  return -1;
1851  }
1852 
1853  pj_strdup2_with_null(pool, &tmp, registration->server_uri);
1854  uri = pjsip_parse_uri(pool, tmp.ptr, tmp.slen, 0);
1855  if (!uri) {
1856  ast_log(LOG_ERROR, "Invalid server URI '%s' specified on outbound registration '%s'\n",
1857  registration->server_uri, ast_sorcery_object_get_id(registration));
1858  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
1859  return -1;
1860  }
1861 
1862  pj_strdup2_with_null(pool, &tmp, registration->client_uri);
1863  uri = pjsip_parse_uri(pool, tmp.ptr, tmp.slen, 0);
1864  if (!uri) {
1865  ast_log(LOG_ERROR, "Invalid client URI '%s' specified on outbound registration '%s'\n",
1866  registration->client_uri, ast_sorcery_object_get_id(registration));
1867  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
1868  return -1;
1869  }
1870 
1871  pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
1872 
1873  ast_assert(state->client_state->client == NULL);
1874  if (pjsip_regc_create(ast_sip_get_pjsip_endpoint(), state->client_state,
1875  sip_outbound_registration_response_cb,
1876  &state->client_state->client) != PJ_SUCCESS) {
1877  return -1;
1878  }
1879 
1880  ast_sip_set_tpselector_from_transport_name(registration->transport, &selector);
1881  pjsip_regc_set_transport(state->client_state->client, &selector);
1882 
1883  if (!ast_strlen_zero(registration->outbound_proxy)) {
1884  pjsip_route_hdr route_set, *route;
1885  static const pj_str_t ROUTE_HNAME = { "Route", 5 };
1886  pj_str_t tmp;
1887 
1888  pj_list_init(&route_set);
1889 
1890  pj_strdup2_with_null(pjsip_regc_get_pool(state->client_state->client), &tmp,
1891  registration->outbound_proxy);
1892  route = pjsip_parse_hdr(pjsip_regc_get_pool(state->client_state->client),
1893  &ROUTE_HNAME, tmp.ptr, tmp.slen, NULL);
1894  if (!route) {
1895  ast_sip_tpselector_unref(&selector);
1896  return -1;
1897  }
1898  pj_list_insert_nodes_before(&route_set, route);
1899 
1900  pjsip_regc_set_route_set(state->client_state->client, &route_set);
1901  }
1902 
1903  if (state->registration->line) {
1904  ast_generate_random_string(state->client_state->line, sizeof(state->client_state->line));
1905  }
1906 
1907  pj_cstr(&server_uri, registration->server_uri);
1908 
1909  if (sip_dialog_create_contact(pjsip_regc_get_pool(state->client_state->client),
1910  &contact_uri, S_OR(registration->contact_user, "s"), &server_uri, &selector,
1911  state->client_state->line, registration->contact_header_params)) {
1912  ast_sip_tpselector_unref(&selector);
1913  return -1;
1914  }
1915 
1916  ast_sip_tpselector_unref(&selector);
1917 
1918  pj_cstr(&client_uri, registration->client_uri);
1919  if (pjsip_regc_init(state->client_state->client, &server_uri, &client_uri,
1920  &client_uri, 1, &contact_uri, registration->expiration) != PJ_SUCCESS) {
1921  return -1;
1922  }
1923 
1924  return 0;
1925 }
1926 
1927 /*! \brief Helper function which performs a single registration */
1928 static int sip_outbound_registration_perform(void *data)
1929 {
1930  struct sip_outbound_registration_state *state = data;
1931  struct sip_outbound_registration *registration = ao2_bump(state->registration);
1932  size_t i;
1933  int max_delay;
1934 
1935  /* Just in case the client state is being reused for this registration, free the auth information */
1936  ast_sip_auth_vector_destroy(&state->client_state->outbound_auths);
1939 
1941  for (i = 0; i < AST_VECTOR_SIZE(&registration->outbound_auths); ++i) {
1942  char *name = ast_strdup(AST_VECTOR_GET(&registration->outbound_auths, i));
1943 
1944  if (name && AST_VECTOR_APPEND(&state->client_state->outbound_auths, name)) {
1945  ast_free(name);
1946  }
1947  }
1949  &registration->security_mechanisms);
1950  state->client_state->retry_interval = registration->retry_interval;
1952  state->client_state->fatal_retry_interval = registration->fatal_retry_interval;
1953  state->client_state->max_retries = registration->max_retries;
1954  state->client_state->retries = 0;
1955  state->client_state->support_path = registration->support_path;
1956  state->client_state->support_outbound = registration->support_outbound;
1957  state->client_state->security_negotiation = registration->security_negotiation;
1959  max_delay = registration->max_random_initial_delay;
1960 
1961  pjsip_regc_update_expires(state->client_state->client, registration->expiration);
1962 
1963  /* n mod 0 is undefined, so don't let that happen */
1964  schedule_registration(state->client_state, (max_delay ? ast_random() % max_delay : 0) + 1);
1965 
1966  ao2_ref(registration, -1);
1967  ao2_ref(state, -1);
1968  return 0;
1969 }
1970 
1971 /*! \brief Apply function which finds or allocates a state structure */
1972 static int sip_outbound_registration_apply(const struct ast_sorcery *sorcery, void *obj)
1973 {
1974  RAII_VAR(struct ao2_container *, states, ao2_global_obj_ref(current_states), ao2_cleanup);
1975  RAII_VAR(struct sip_outbound_registration_state *, state, NULL, ao2_cleanup);
1976  RAII_VAR(struct sip_outbound_registration_state *, new_state, NULL, ao2_cleanup);
1977  struct sip_outbound_registration *applied = obj;
1978 
1979  if (!states) {
1980  /* Global container has gone. Likely shutting down. */
1981  return -1;
1982  }
1983  state = ao2_find(states, ast_sorcery_object_get_id(applied), OBJ_SEARCH_KEY);
1984 
1985  ast_debug(4, "Applying configuration to outbound registration '%s'\n", ast_sorcery_object_get_id(applied));
1986 
1987  if (ast_strlen_zero(applied->server_uri)) {
1988  ast_log(LOG_ERROR, "No server URI specified on outbound registration '%s'\n",
1989  ast_sorcery_object_get_id(applied));
1990  return -1;
1991  } else if (ast_sip_validate_uri_length(applied->server_uri)) {
1992  ast_log(LOG_ERROR, "Server URI or hostname length exceeds pjproject limit or is not a sip(s) uri: '%s'\n",
1993  ast_sorcery_object_get_id(applied));
1994  return -1;
1995  } else if (ast_strlen_zero(applied->client_uri)) {
1996  ast_log(LOG_ERROR, "No client URI specified on outbound registration '%s'\n",
1997  ast_sorcery_object_get_id(applied));
1998  return -1;
1999  } else if (ast_sip_validate_uri_length(applied->client_uri)) {
2000  ast_log(LOG_ERROR, "Client URI or hostname length exceeds pjproject limit or is not a sip(s) uri: '%s'\n",
2001  ast_sorcery_object_get_id(applied));
2002  return -1;
2003  } else if (applied->line && ast_strlen_zero(applied->endpoint)) {
2004  ast_log(LOG_ERROR, "Line support has been enabled on outbound registration '%s' without providing an endpoint\n",
2005  ast_sorcery_object_get_id(applied));
2006  return -1;
2007  } else if (!ast_strlen_zero(applied->endpoint) && !applied->line) {
2008  ast_log(LOG_ERROR, "An endpoint has been specified on outbound registration '%s' without enabling line support\n",
2009  ast_sorcery_object_get_id(applied));
2010  return -1;
2011  }
2012 
2013  if (state && can_reuse_registration(state->registration, applied)) {
2014  ast_debug(4,
2015  "No change between old configuration and new configuration on outbound registration '%s'. Using previous state\n",
2016  ast_sorcery_object_get_id(applied));
2017 
2018  /*
2019  * This is OK to replace without relinking the state in the
2020  * current_states container since state->registration and
2021  * applied have the same key.
2022  */
2023  ao2_lock(states);
2024  ao2_replace(state->registration, applied);
2025  ao2_unlock(states);
2026  return 0;
2027  }
2028 
2029  if (!(new_state = sip_outbound_registration_state_alloc(applied))) {
2030  return -1;
2031  }
2032 
2033  if (ast_sip_push_task_wait_serializer(new_state->client_state->serializer,
2034  sip_outbound_registration_regc_alloc, new_state)) {
2035  return -1;
2036  }
2037 
2038  if (ast_sip_push_task(new_state->client_state->serializer,
2039  sip_outbound_registration_perform, ao2_bump(new_state))) {
2040  ast_log(LOG_ERROR, "Failed to perform outbound registration on '%s'\n",
2041  ast_sorcery_object_get_id(new_state->registration));
2042  ao2_ref(new_state, -1);
2043  return -1;
2044  }
2045 
2046  ao2_lock(states);
2047  if (state) {
2048  ao2_unlink(states, state);
2049  }
2050  ao2_link(states, new_state);
2051  ao2_unlock(states);
2052 
2053  return 0;
2054 }
2055 
2056 static int security_mechanism_to_str(const void *obj, const intptr_t *args, char **buf)
2057 {
2058  const struct sip_outbound_registration *registration = obj;
2059 
2060  return ast_sip_security_mechanisms_to_str(&registration->security_mechanisms, 0, buf);
2061 }
2062 
2063 static const char *security_negotiation_map[] = {
2064  [AST_SIP_SECURITY_NEG_NONE] = "no",
2065  [AST_SIP_SECURITY_NEG_MEDIASEC] = "mediasec",
2066 };
2067 
2068 static int security_negotiation_to_str(const void *obj, const intptr_t *args, char **buf)
2069 {
2070  const struct sip_outbound_registration *registration = obj;
2071  if (ARRAY_IN_BOUNDS(registration->security_negotiation, security_negotiation_map)) {
2072  *buf = ast_strdup(security_negotiation_map[registration->security_negotiation]);
2073  }
2074  return 0;
2075 }
2076 
2077 static int security_mechanisms_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
2078 {
2079  struct sip_outbound_registration *registration = obj;
2080 
2082 }
2083 
2084 static int security_negotiation_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
2085 {
2086  struct sip_outbound_registration *registration = obj;
2087 
2088  return ast_sip_set_security_negotiation(&registration->security_negotiation, var->value);
2089 }
2090 
2091 static int outbound_auth_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
2092 {
2093  struct sip_outbound_registration *registration = obj;
2094 
2095  return ast_sip_auth_vector_init(&registration->outbound_auths, var->value);
2096 }
2097 
2098 static int outbound_auths_to_str(const void *obj, const intptr_t *args, char **buf)
2099 {
2100  const struct sip_outbound_registration *registration = obj;
2101 
2102  return ast_sip_auths_to_str(&registration->outbound_auths, buf);
2103 }
2104 
2105 static int outbound_auths_to_var_list(const void *obj, struct ast_variable **fields)
2106 {
2107  const struct sip_outbound_registration *registration = obj;
2108  int i;
2109  struct ast_variable *head = NULL;
2110 
2111  for (i = 0; i < AST_VECTOR_SIZE(&registration->outbound_auths) ; i++) {
2112  ast_variable_list_append(&head, ast_variable_new("outbound_auth",
2113  AST_VECTOR_GET(&registration->outbound_auths, i), ""));
2114  }
2115 
2116  if (head) {
2117  *fields = head;
2118  }
2119 
2120  return 0;
2121 }
2122 
2123 static int unregister_task(void *obj)
2124 {
2125  struct sip_outbound_registration_state *state = obj;
2126  struct pjsip_regc *client = state->client_state->client;
2127  pjsip_tx_data *tdata;
2128  pjsip_regc_info info;
2129 
2130  pjsip_regc_get_info(client, &info);
2131  ast_debug(1, "Unregistering contacts with server '%s' from client '%s'\n",
2132  state->registration->server_uri, state->registration->client_uri);
2133 
2134  cancel_registration(state->client_state);
2135 
2136  if (pjsip_regc_unregister(client, &tdata) == PJ_SUCCESS
2137  && add_configured_supported_headers(state->client_state, tdata)) {
2138  registration_client_send(state->client_state, tdata);
2139  }
2140 
2141  ao2_ref(state, -1);
2142  return 0;
2143 }
2144 
2145 static int queue_unregister(struct sip_outbound_registration_state *state)
2146 {
2147  ao2_ref(state, +1);
2148  if (ast_sip_push_task(state->client_state->serializer, unregister_task, state)) {
2149  ao2_ref(state, -1);
2150  return -1;
2151  }
2152 
2153  return 0;
2154 }
2155 
2156 static int queue_register(struct sip_outbound_registration_state *state)
2157 {
2158  ao2_ref(state, +1);
2159  if (ast_sip_push_task(state->client_state->serializer, sip_outbound_registration_perform, state)) {
2160  ao2_ref(state, -1);
2161  return -1;
2162  }
2163 
2164  return 0;
2165 }
2166 
2167 static void unregister_all(void)
2168 {
2169  struct ao2_container *states;
2170 
2171  states = ao2_global_obj_ref(current_states);
2172  if (!states) {
2173  return;
2174  }
2175 
2176  /* Clean out all the states and let sorcery handle recreating the registrations */
2177  ao2_callback(states, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL);
2178  ao2_ref(states, -1);
2179 }
2180 
2181 static void reregister_all(void)
2182 {
2183  unregister_all();
2184  ast_sorcery_load_object(ast_sip_get_sorcery(), "registration");
2185 }
2186 
2187 static char *cli_complete_registration(const char *line, const char *word,
2188  int pos, int state)
2189 {
2190  char *result = NULL;
2191  int wordlen;
2192  int which = 0;
2193  struct sip_outbound_registration *registration;
2194  struct ao2_container *registrations;
2195  struct ao2_iterator i;
2196 
2197  if (pos != 3) {
2198  return NULL;
2199  }
2200 
2201  wordlen = strlen(word);
2202  if (wordlen == 0 && ++which > state) {
2203  return ast_strdup("*all");
2204  }
2205 
2206  registrations = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "registration",
2208  if (!registrations) {
2209  return NULL;
2210  }
2211 
2212  i = ao2_iterator_init(registrations, 0);
2213  while ((registration = ao2_iterator_next(&i))) {
2214  const char *name = ast_sorcery_object_get_id(registration);
2215 
2216  if (!strncasecmp(word, name, wordlen) && ++which > state) {
2217  result = ast_strdup(name);
2218  }
2219 
2220  ao2_ref(registration, -1);
2221  if (result) {
2222  break;
2223  }
2224  }
2226 
2227  ao2_ref(registrations, -1);
2228  return result;
2229 }
2230 
2231 static char *cli_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2232 {
2233  struct sip_outbound_registration_state *state;
2234  const char *registration_name;
2235 
2236  switch (cmd) {
2237  case CLI_INIT:
2238  e->command = "pjsip send unregister";
2239  e->usage =
2240  "Usage: pjsip send unregister <registration> | *all\n"
2241  " Unregisters the specified (or all) outbound registration(s) "
2242  "and stops future registration attempts.\n";
2243  return NULL;
2244  case CLI_GENERATE:
2245  return cli_complete_registration(a->line, a->word, a->pos, a->n);
2246  }
2247 
2248  if (a->argc != 4) {
2249  return CLI_SHOWUSAGE;
2250  }
2251 
2252  registration_name = a->argv[3];
2253 
2254  if (strcmp(registration_name, "*all") == 0) {
2255  unregister_all();
2256  ast_cli(a->fd, "Unregister all queued\n");
2257  return CLI_SUCCESS;
2258  }
2259 
2260  state = get_state(registration_name);
2261  if (!state) {
2262  ast_cli(a->fd, "Unable to retrieve registration %s\n", registration_name);
2263  return CLI_FAILURE;
2264  }
2265 
2266  if (queue_unregister(state)) {
2267  ast_cli(a->fd, "Failed to queue unregistration\n");
2268  }
2269 
2270  ao2_ref(state, -1);
2271  return CLI_SUCCESS;
2272 }
2273 
2274 static char *cli_register(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2275 {
2276  struct sip_outbound_registration_state *state;
2277  const char *registration_name;
2278 
2279  switch (cmd) {
2280  case CLI_INIT:
2281  e->command = "pjsip send register";
2282  e->usage =
2283  "Usage: pjsip send register <registration> | *all \n"
2284  " Unregisters the specified (or all) outbound "
2285  "registration(s) then starts registration(s) and schedules re-registrations.\n";
2286  return NULL;
2287  case CLI_GENERATE:
2288  return cli_complete_registration(a->line, a->word, a->pos, a->n);
2289  }
2290 
2291  if (a->argc != 4) {
2292  return CLI_SHOWUSAGE;
2293  }
2294 
2295  registration_name = a->argv[3];
2296 
2297  if (strcmp(registration_name, "*all") == 0) {
2298  reregister_all();
2299  ast_cli(a->fd, "Re-register all queued\n");
2300  return CLI_SUCCESS;
2301  }
2302 
2303  state = get_state(registration_name);
2304  if (!state) {
2305  ast_cli(a->fd, "Unable to retrieve registration %s\n", registration_name);
2306  return CLI_FAILURE;
2307  }
2308 
2309  /* We need to serialize the unregister and register so they need
2310  * to be queued as separate tasks.
2311  */
2312  if (queue_unregister(state)) {
2313  ast_cli(a->fd, "Failed to queue unregistration\n");
2314  } else if (queue_register(state)) {
2315  ast_cli(a->fd, "Failed to queue registration\n");
2316  }
2317 
2318  ao2_ref(state, -1);
2319  return CLI_SUCCESS;
2320 }
2321 
2322 static int ami_unregister(struct mansession *s, const struct message *m)
2323 {
2324  const char *registration_name = astman_get_header(m, "Registration");
2325  struct sip_outbound_registration_state *state;
2326 
2327  if (ast_strlen_zero(registration_name)) {
2328  astman_send_error(s, m, "Registration parameter missing.");
2329  return 0;
2330  }
2331 
2332  if (strcmp(registration_name, "*all") == 0) {
2333  unregister_all();
2334  astman_send_ack(s, m, "Unregistrations queued.");
2335  return 0;
2336  }
2337 
2338  state = get_state(registration_name);
2339  if (!state) {
2340  astman_send_error(s, m, "Unable to retrieve registration entry\n");
2341  return 0;
2342  }
2343 
2344  if (queue_unregister(state)) {
2345  astman_send_ack(s, m, "Failed to queue unregistration");
2346  } else {
2347  astman_send_ack(s, m, "Unregistration sent");
2348  }
2349 
2350  ao2_ref(state, -1);
2351  return 0;
2352 }
2353 
2354 static int ami_register(struct mansession *s, const struct message *m)
2355 {
2356  const char *registration_name = astman_get_header(m, "Registration");
2357  struct sip_outbound_registration_state *state;
2358 
2359  if (ast_strlen_zero(registration_name)) {
2360  astman_send_error(s, m, "Registration parameter missing.");
2361  return 0;
2362  }
2363 
2364  if (strcmp(registration_name, "*all") == 0) {
2365  reregister_all();
2366  astman_send_ack(s, m, "Reregistrations queued.");
2367  return 0;
2368  }
2369 
2370  state = get_state(registration_name);
2371  if (!state) {
2372  astman_send_error(s, m, "Unable to retrieve registration entry\n");
2373  return 0;
2374  }
2375 
2376  /* We need to serialize the unregister and register so they need
2377  * to be queued as separate tasks.
2378  */
2379  if (queue_unregister(state)) {
2380  astman_send_ack(s, m, "Failed to queue unregistration");
2381  } else if (queue_register(state)) {
2382  astman_send_ack(s, m, "Failed to queue unregistration");
2383  } else {
2384  astman_send_ack(s, m, "Reregistration sent");
2385  }
2386 
2387  ao2_ref(state, -1);
2388  return 0;
2389 }
2390 
2392  struct ast_sip_ami *ami;
2393  int registered;
2394  int not_registered;
2395  struct sip_outbound_registration *registration;
2396 };
2397 
2398 static int ami_outbound_registration_task(void *obj)
2399 {
2400  struct sip_ami_outbound *ami = obj;
2401  struct ast_str *buf;
2402  struct sip_outbound_registration_state *state;
2403 
2404  buf = ast_sip_create_ami_event("OutboundRegistrationDetail", ami->ami);
2405  if (!buf) {
2406  return -1;
2407  }
2408 
2409  ast_sip_sorcery_object_to_ami(ami->registration, &buf);
2410 
2411  if ((state = get_state(ast_sorcery_object_get_id(ami->registration)))) {
2412  pjsip_regc_info info;
2413 
2414  if (state->client_state->status == SIP_REGISTRATION_REGISTERED) {
2415  ++ami->registered;
2416  } else {
2417  ++ami->not_registered;
2418  }
2419 
2420  ast_str_append(&buf, 0, "Status: %s\r\n",
2421  sip_outbound_registration_status_str(state->client_state->status));
2422 
2423  pjsip_regc_get_info(state->client_state->client, &info);
2424  ast_str_append(&buf, 0, "NextReg: %d\r\n", info.next_reg);
2425  ao2_ref(state, -1);
2426  }
2427 
2428  astman_append(ami->ami->s, "%s\r\n", ast_str_buffer(buf));
2429  ast_free(buf);
2430 
2431  return ast_sip_format_auths_ami(&ami->registration->outbound_auths, ami->ami);
2432 }
2433 
2434 static int ami_outbound_registration_detail(void *obj, void *arg, int flags)
2435 {
2436  struct sip_ami_outbound *ami = arg;
2437 
2438  ami->registration = obj;
2439  return ast_sip_push_task_wait_servant(NULL, ami_outbound_registration_task, ami);
2440 }
2441 
2442 static int ami_show_outbound_registrations(struct mansession *s,
2443  const struct message *m)
2444 {
2445  struct ast_sip_ami ami = { .s = s, .m = m, .action_id = astman_get_header(m, "ActionID"), };
2446  struct sip_ami_outbound ami_outbound = { .ami = &ami };
2447  struct ao2_container *regs;
2448 
2449  regs = get_registrations();
2450  if (!regs) {
2451  astman_send_error(s, m, "Unable to retrieve "
2452  "outbound registrations\n");
2453  return -1;
2454  }
2455 
2456  astman_send_listack(s, m, "Following are Events for each Outbound registration",
2457  "start");
2458 
2459  ao2_callback(regs, OBJ_NODATA, ami_outbound_registration_detail, &ami_outbound);
2460 
2461  astman_send_list_complete_start(s, m, "OutboundRegistrationDetailComplete",
2462  ami_outbound.registered + ami_outbound.not_registered);
2463  astman_append(s,
2464  "Registered: %d\r\n"
2465  "NotRegistered: %d\r\n",
2466  ami_outbound.registered,
2467  ami_outbound.not_registered);
2469 
2470  ao2_ref(regs, -1);
2471  return 0;
2472 }
2473 
2474 static struct ao2_container *cli_get_container(const char *regex)
2475 {
2476  RAII_VAR(struct ao2_container *, container, NULL, ao2_cleanup);
2477  struct ao2_container *s_container;
2478 
2479  container = ast_sorcery_retrieve_by_regex(ast_sip_get_sorcery(), "registration", regex);
2480  if (!container) {
2481  return NULL;
2482  }
2483 
2486  if (!s_container) {
2487  return NULL;
2488  }
2489 
2490  if (ao2_container_dup(s_container, container, 0)) {
2491  ao2_ref(s_container, -1);
2492  return NULL;
2493  }
2494 
2495  return s_container;
2496 }
2497 
2498 static int cli_iterator(void *container, ao2_callback_fn callback, void *args)
2499 {
2500  ao2_callback(container, OBJ_NODATA, callback, args);
2501 
2502  return 0;
2503 }
2504 
2505 static void *cli_retrieve_by_id(const char *id)
2506 {
2507  struct ao2_container *states;
2508  void *obj = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "registration", id);
2509 
2510  if (!obj) {
2511  /* if the object no longer exists then remove its state */
2512  states = ao2_global_obj_ref(current_states);
2513  if (states) {
2514  ao2_find(states, id, OBJ_SEARCH_KEY | OBJ_UNLINK | OBJ_NODATA);
2515  ao2_ref(states, -1);
2516  }
2517  }
2518 
2519  return obj;
2520 }
2521 
2522 static int cli_print_header(void *obj, void *arg, int flags)
2523 {
2524  struct ast_sip_cli_context *context = arg;
2525 
2526  ast_assert(context->output_buffer != NULL);
2527 
2528  ast_str_append(&context->output_buffer, 0,
2529  " <Registration/ServerURI..............................> <Auth....................> <Status.......>\n");
2530 
2531  return 0;
2532 }
2533 
2534 static int cli_print_body(void *obj, void *arg, int flags)
2535 {
2536  struct sip_outbound_registration *registration = obj;
2537  struct ast_sip_cli_context *context = arg;
2538  const char *id = ast_sorcery_object_get_id(registration);
2539  struct sip_outbound_registration_state *state = get_state(id);
2540  int expsecs;
2541 #define REGISTRATION_URI_FIELD_LEN 53
2542 
2543  ast_assert(context->output_buffer != NULL);
2544  expsecs = state ? state->client_state->registration_expires - ((int) time(NULL)) : 0;
2545 
2546  ast_str_append(&context->output_buffer, 0, " %-s/%-*.*s %-26s %-16s %s%d%s\n",
2547  id,
2548  (int) (REGISTRATION_URI_FIELD_LEN - strlen(id)),
2549  (int) (REGISTRATION_URI_FIELD_LEN - strlen(id)),
2550  registration->server_uri,
2551  AST_VECTOR_SIZE(&registration->outbound_auths)
2552  ? AST_VECTOR_GET(&registration->outbound_auths, 0)
2553  : "n/a",
2554  (state ? sip_outbound_registration_status_str(state->client_state->status) : "Unregistered"),
2555  state ? " (exp. " : "", abs(expsecs), state ? (expsecs < 0 ? "s ago)" : "s)") : "");
2556  ao2_cleanup(state);
2557 
2558  if (context->show_details
2559  || (context->show_details_only_level_0 && context->indent_level == 0)) {
2560  ast_str_append(&context->output_buffer, 0, "\n");
2561  ast_sip_cli_print_sorcery_objectset(registration, context, 0);
2562  }
2563 
2564  return 0;
2565 }
2566 
2567 /*
2568  * A function pointer to callback needs to be within the
2569  * module in order to avoid problems with an undefined
2570  * symbol when the module is loaded.
2571  */
2572 static char *my_cli_traverse_objects(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2573 {
2574  return ast_sip_cli_traverse_objects(e, cmd, a);
2575 }
2576 
2577 static struct ast_cli_entry cli_outbound_registration[] = {
2578  AST_CLI_DEFINE(cli_unregister, "Unregisters outbound registration target"),
2579  AST_CLI_DEFINE(cli_register, "Registers an outbound registration target"),
2580  AST_CLI_DEFINE(my_cli_traverse_objects, "List PJSIP Registrations",
2581  .command = "pjsip list registrations",
2582  .usage = "Usage: pjsip list registrations [ like <pattern> ]\n"
2583  " List the configured PJSIP Registrations\n"
2584  " Optional regular expression pattern is used to filter the list.\n"),
2585  AST_CLI_DEFINE(my_cli_traverse_objects, "Show PJSIP Registrations",
2586  .command = "pjsip show registrations",
2587  .usage = "Usage: pjsip show registrations [ like <pattern> ]\n"
2588  " Show the configured PJSIP Registrations\n"
2589  " Optional regular expression pattern is used to filter the list.\n"),
2590  AST_CLI_DEFINE(my_cli_traverse_objects, "Show PJSIP Registration",
2591  .command = "pjsip show registration",
2592  .usage = "Usage: pjsip show registration <id>\n"
2593  " Show the configured PJSIP Registration\n"),
2594 };
2595 
2596 static struct ast_sip_cli_formatter_entry *cli_formatter;
2597 
2598 static void auth_observer(const char *type)
2599 {
2600  struct sip_outbound_registration *registration;
2601  struct sip_outbound_registration_state *state;
2602  struct ao2_container *regs;
2603  const char *registration_id;
2604  struct ao2_iterator i;
2605 
2606  ast_debug(4, "Auths updated. Checking for any outbound registrations that are in permanent rejected state so they can be retried\n");
2607 
2608  regs = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "registration",
2610  if (!regs || ao2_container_count(regs) == 0) {
2611  ao2_cleanup(regs);
2612  return;
2613  }
2614 
2615  i = ao2_iterator_init(regs, 0);
2616  for (; (registration = ao2_iterator_next(&i)); ao2_ref(registration, -1)) {
2617  registration_id = ast_sorcery_object_get_id(registration);
2618  state = get_state(registration_id);
2619  if (state && state->client_state->status == SIP_REGISTRATION_REJECTED_PERMANENT) {
2620  ast_debug(4, "Trying outbound registration '%s' again\n", registration_id);
2621 
2623  sip_outbound_registration_perform, ao2_bump(state))) {
2624  ast_log(LOG_ERROR, "Failed to perform outbound registration on '%s'\n", registration_id);
2625  ao2_ref(state, -1);
2626  }
2627  }
2628  ao2_cleanup(state);
2629  }
2631  ao2_cleanup(regs);
2632 }
2633 
2634 static const struct ast_sorcery_observer observer_callbacks_auth = {
2635  .loaded = auth_observer,
2636 };
2637 
2638 static int check_state(void *obj, void *arg, int flags)
2639 {
2640  struct sip_outbound_registration_state *state = obj;
2641  struct sip_outbound_registration *registration;
2642 
2643  registration = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "registration",
2645  if (!registration) {
2646  /* This is a dead registration */
2647  return CMP_MATCH;
2648  }
2649 
2650  ao2_ref(registration, -1);
2651  return 0;
2652 }
2653 
2654 /*!
2655  * \internal
2656  * \brief Observer to purge dead registration states.
2657  *
2658  * \param name Module name owning the sorcery instance.
2659  * \param sorcery Instance being observed.
2660  * \param object_type Name of object being observed.
2661  * \param reloaded Non-zero if the object is being reloaded.
2662  */
2663 static void registration_loaded_observer(const char *name, const struct ast_sorcery *sorcery, const char *object_type, int reloaded)
2664 {
2665  struct ao2_container *states;
2666 
2667  if (strcmp(object_type, "registration")) {
2668  /* Not interested */
2669  return;
2670  }
2671 
2672  states = ao2_global_obj_ref(current_states);
2673  if (!states) {
2674  /* Global container has gone. Likely shutting down. */
2675  return;
2676  }
2677 
2678  /*
2679  * Refresh the current configured registrations. We don't need to hold
2680  * onto the objects, as the apply handler will cause their states to
2681  * be created appropriately.
2682  */
2683  ao2_cleanup(get_registrations());
2684 
2685  /* Now to purge dead registrations. */
2686  ao2_callback(states, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, check_state, NULL);
2687  ao2_ref(states, -1);
2688 }
2689 
2690 static const struct ast_sorcery_instance_observer observer_callbacks_registrations = {
2691  .object_type_loaded = registration_loaded_observer,
2692 };
2693 
2694 static void registration_deleted_observer(const void *obj)
2695 {
2696  const struct sip_outbound_registration *registration = obj;
2697  struct ao2_container *states;
2698 
2699  states = ao2_global_obj_ref(current_states);
2700  if (!states) {
2701  /* Global container has gone. Likely shutting down. */
2702  return;
2703  }
2704 
2705  ao2_find(states, ast_sorcery_object_get_id(registration), OBJ_UNLINK | OBJ_NODATA | OBJ_SEARCH_KEY);
2706 
2707  ao2_ref(states, -1);
2708 }
2709 
2710 static const struct ast_sorcery_observer registration_observer = {
2711  .deleted = registration_deleted_observer,
2712 };
2713 
2714 static void network_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
2715 {
2716  /* This callback is only concerned with network change messages from the system topic. */
2717  if (stasis_message_type(message) != ast_network_change_type()) {
2718  return;
2719  }
2720  ast_debug(3, "Received network change event\n");
2721 
2722  reregister_all();
2723 }
2724 
2725 static int unload_module(void)
2726 {
2727  int remaining;
2728 
2729  network_change_sub = stasis_unsubscribe_and_join(network_change_sub);
2730 
2731  ast_manager_unregister("PJSIPShowRegistrationsOutbound");
2732  ast_manager_unregister("PJSIPUnregister");
2733  ast_manager_unregister("PJSIPRegister");
2734 
2735  ast_cli_unregister_multiple(cli_outbound_registration, ARRAY_LEN(cli_outbound_registration));
2736  ast_sip_unregister_cli_formatter(cli_formatter);
2737  cli_formatter = NULL;
2738 
2739  ast_sip_unregister_endpoint_identifier(&line_identifier);
2740 
2741  ast_sorcery_observer_remove(ast_sip_get_sorcery(), "auth", &observer_callbacks_auth);
2742  ast_sorcery_instance_observer_remove(ast_sip_get_sorcery(), &observer_callbacks_registrations);
2743 
2744  ast_sorcery_object_unregister(ast_sip_get_sorcery(), "registration");
2745 
2746  ao2_global_obj_release(current_states);
2747 
2748  ast_sip_transport_monitor_unregister_all(registration_transport_shutdown_cb, NULL, NULL);
2749 
2750  /* Wait for registration serializers to get destroyed. */
2751  ast_debug(2, "Waiting for registration transactions to complete for unload.\n");
2752  remaining = ast_serializer_shutdown_group_join(shutdown_group, MAX_UNLOAD_TIMEOUT_TIME);
2753  if (remaining) {
2754  /*
2755  * NOTE: We probably have a sip_outbound_registration_client_state
2756  * ref leak if the remaining count cannot reach zero after a few
2757  * minutes of trying to unload.
2758  */
2759  ast_log(LOG_WARNING, "Unload incomplete. Could not stop %d outbound registrations. Try again later.\n",
2760  remaining);
2761  return -1;
2762  }
2763 
2764  ast_debug(2, "Successful shutdown.\n");
2765 
2766  ao2_cleanup(shutdown_group);
2767  shutdown_group = NULL;
2768 
2769  return 0;
2770 }
2771 
2772 static int load_module(void)
2773 {
2774  struct ao2_container *new_states;
2775 
2776  shutdown_group = ast_serializer_shutdown_group_alloc();
2777  if (!shutdown_group) {
2778  return AST_MODULE_LOAD_DECLINE;
2779  }
2780 
2781  /* Create outbound registration states container. */
2783  DEFAULT_STATE_BUCKETS, registration_state_hash, NULL, registration_state_cmp);
2784  if (!new_states) {
2785  ast_log(LOG_ERROR, "Unable to allocate registration states container\n");
2786  unload_module();
2787  return AST_MODULE_LOAD_DECLINE;
2788  }
2789  ao2_global_obj_replace_unref(current_states, new_states);
2790  ao2_ref(new_states, -1);
2791 
2792  /*
2793  * Register sorcery object descriptions.
2794  */
2795  ast_sorcery_apply_config(ast_sip_get_sorcery(), "res_pjsip_outbound_registration");
2796  ast_sorcery_apply_default(ast_sip_get_sorcery(), "registration", "config", "pjsip.conf,criteria=type=registration");
2797 
2798  if (ast_sorcery_object_register(ast_sip_get_sorcery(), "registration", sip_outbound_registration_alloc, NULL, sip_outbound_registration_apply)) {
2799  unload_module();
2800  return AST_MODULE_LOAD_DECLINE;
2801  }
2802 
2803  ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "type", "", OPT_NOOP_T, 0, 0);
2804  ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "server_uri", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct sip_outbound_registration, server_uri));
2805  ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "client_uri", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct sip_outbound_registration, client_uri));
2806  ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "contact_user", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct sip_outbound_registration, contact_user));
2807  ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "contact_header_params", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct sip_outbound_registration, contact_header_params));
2808  ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "transport", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct sip_outbound_registration, transport));
2809  ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "outbound_proxy", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct sip_outbound_registration, outbound_proxy));
2810  ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "expiration", "3600", OPT_UINT_T, 0, FLDSET(struct sip_outbound_registration, expiration));
2811  ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "max_random_initial_delay", "10", OPT_UINT_T, 0, FLDSET(struct sip_outbound_registration, max_random_initial_delay));
2812  ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "retry_interval", "60", OPT_UINT_T, 0, FLDSET(struct sip_outbound_registration, retry_interval));
2813  ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "forbidden_retry_interval", "0", OPT_UINT_T, 0, FLDSET(struct sip_outbound_registration, forbidden_retry_interval));
2814  ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "fatal_retry_interval", "0", OPT_UINT_T, 0, FLDSET(struct sip_outbound_registration, fatal_retry_interval));
2815  ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "max_retries", "10", OPT_UINT_T, 0, FLDSET(struct sip_outbound_registration, max_retries));
2816  ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "auth_rejection_permanent", "yes", OPT_BOOL_T, 1, FLDSET(struct sip_outbound_registration, auth_rejection_permanent));
2817  ast_sorcery_object_field_register_custom(ast_sip_get_sorcery(), "registration", "outbound_auth", "", outbound_auth_handler, outbound_auths_to_str, outbound_auths_to_var_list, 0, 0);
2818  ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "support_path", "no", OPT_BOOL_T, 1, FLDSET(struct sip_outbound_registration, support_path));
2819  ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "support_outbound", "no", OPT_YESNO_T, 1, FLDSET(struct sip_outbound_registration, support_outbound));
2820  ast_sorcery_object_field_register_custom(ast_sip_get_sorcery(), "registration", "security_negotiation", "no", security_negotiation_handler, security_negotiation_to_str, NULL, 0, 0);
2821  ast_sorcery_object_field_register_custom(ast_sip_get_sorcery(), "registration", "security_mechanisms", "", security_mechanisms_handler, security_mechanism_to_str, NULL, 0, 0);
2822  ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "line", "no", OPT_BOOL_T, 1, FLDSET(struct sip_outbound_registration, line));
2823  ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "endpoint", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct sip_outbound_registration, endpoint));
2824  ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "user_agent", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct sip_outbound_registration, user_agent));
2825 
2826  /*
2827  * Register sorcery observers.
2828  */
2829  if (ast_sorcery_instance_observer_add(ast_sip_get_sorcery(),
2830  &observer_callbacks_registrations)
2831  || ast_sorcery_observer_add(ast_sip_get_sorcery(), "auth",
2832  &observer_callbacks_auth)
2833  || ast_sorcery_observer_add(ast_sip_get_sorcery(), "registration",
2834  &registration_observer)) {
2835  ast_log(LOG_ERROR, "Unable to register observers.\n");
2836  unload_module();
2837  return AST_MODULE_LOAD_DECLINE;
2838  }
2839 
2840  /* Register how this module identifies endpoints. */
2841  ast_sip_register_endpoint_identifier(&line_identifier);
2842 
2843  /* Register CLI commands. */
2844  cli_formatter = ao2_alloc(sizeof(struct ast_sip_cli_formatter_entry), NULL);
2845  if (!cli_formatter) {
2846  ast_log(LOG_ERROR, "Unable to allocate memory for cli formatter\n");
2847  unload_module();
2848  return AST_MODULE_LOAD_DECLINE;
2849  }
2850  cli_formatter->name = "registration";
2851  cli_formatter->print_header = cli_print_header;
2852  cli_formatter->print_body = cli_print_body;
2853  cli_formatter->get_container = cli_get_container;
2854  cli_formatter->iterate = cli_iterator;
2855  cli_formatter->get_id = ast_sorcery_object_get_id;
2856  cli_formatter->retrieve_by_id = cli_retrieve_by_id;
2857  ast_sip_register_cli_formatter(cli_formatter);
2858  ast_cli_register_multiple(cli_outbound_registration, ARRAY_LEN(cli_outbound_registration));
2859 
2860  /* Register AMI actions. */
2861  ast_manager_register_xml("PJSIPUnregister", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, ami_unregister);
2862  ast_manager_register_xml("PJSIPRegister", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, ami_register);
2863  ast_manager_register_xml("PJSIPShowRegistrationsOutbound", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, ami_show_outbound_registrations);
2864 
2865  /* Clear any previous statsd gauges in case we weren't shutdown cleanly */
2866  ast_statsd_log("PJSIP.registrations.count", AST_STATSD_GAUGE, 0);
2867  ast_statsd_log("PJSIP.registrations.state.Registered", AST_STATSD_GAUGE, 0);
2868  ast_statsd_log("PJSIP.registrations.state.Unregistered", AST_STATSD_GAUGE, 0);
2869  ast_statsd_log("PJSIP.registrations.state.Rejected", AST_STATSD_GAUGE, 0);
2870 
2871  /* Load configuration objects */
2872  ast_sorcery_load_object(ast_sip_get_sorcery(), "registration");
2873 
2874  network_change_sub = stasis_subscribe(ast_system_topic(),
2875  network_change_stasis_cb, NULL);
2876  stasis_subscription_accept_message_type(network_change_sub, ast_network_change_type());
2878 
2879  return AST_MODULE_LOAD_SUCCESS;
2880 }
2881 
2882 static int reload_module(void)
2883 {
2884  ast_sorcery_reload_object(ast_sip_get_sorcery(), "registration");
2885  return 0;
2886 }
2887 
2888 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Outbound Registration Support",
2889  .support_level = AST_MODULE_SUPPORT_CORE,
2890  .load = load_module,
2891  .reload = reload_module,
2892  .unload = unload_module,
2893  .load_pri = AST_MODPRI_APP_DEPEND,
2894  .requires = "res_pjsip",
2895  .optional_modules = "res_statsd",
2896 );
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
struct ast_str * output_buffer
Definition: res_pjsip_cli.h:36
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
Definition: threadstorage.h:86
unsigned int support_path
Whether Path support is enabled.
struct ao2_container *(* get_container)(const char *regex)
Definition: res_pjsip_cli.h:64
#define ARRAY_IN_BOUNDS(v, a)
Checks to see if value is within the bounds of the given array.
Definition: utils.h:687
int last_status_code
Status code of last response if we have tried to register before.
unsigned int auth_attempted
Non-zero if we have attempted sending a REGISTER with authentication.
int ast_func_read(struct ast_channel *chan, const char *function, char *workspace, size_t len)
executes a read operation on a function
void ast_taskprocessor_build_name(char *buf, unsigned int size, const char *format,...)
Build a taskprocessor name with a sequence number on the end.
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.
struct ast_sip_security_mechanism_vector security_mechanisms
Client security mechanisms (RFC 3329).
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
struct stasis_topic * ast_system_topic(void)
A Stasis Message Bus API topic which publishes messages regarding system changes. ...
CLI Formatter Registry Entry.
Definition: res_pjsip_cli.h:52
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
void(* deleted)(const void *object)
Callback for when an object is deleted.
Definition: sorcery.h:340
int( ao2_callback_fn)(void *obj, void *arg, int flags)
Type of a generic callback function.
Definition: astobj2.h:1226
unsigned int max_retries
Maximum number of retries permitted.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262
const ast_string_field oauth_secret
Definition: res_pjsip.h:593
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
int ast_sip_security_mechanism_vector_init(struct ast_sip_security_mechanism_vector *security_mechanisms, const char *value)
Initialize security mechanism vector from string of security mechanisms.
int ast_sorcery_instance_observer_add(struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
Add an observer to a sorcery instance.
Definition: sorcery.c:520
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1101
struct ast_sip_security_mechanism_vector server_security_mechanisms
Security mechanisms of the peer (RFC 3329).
unsigned int support_outbound
Determines whether SIP Outbound support should be advertised.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
const struct message * m
Definition: res_pjsip.h:3035
pjsip_tx_data * old_request
Request for which the response was received.
struct ast_sip_security_mechanism_vector security_mechanisms
Definition: res_pjsip.h:466
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
descriptor for a cli entry.
Definition: cli.h:171
enum sip_outbound_registration_status status
Current state of this registration.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
#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
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.
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
struct ast_sip_security_mechanism_vector security_mechanisms
Client security mechanisms (RFC 3329).
const ast_string_field client_uri
URI for the AOR.
Perform no matching, return all objects.
Definition: sorcery.h:123
unsigned int forbidden_retry_interval
Interval at which retries should occur for permanent responses.
static struct stasis_subscription * network_change_sub
Definition: chan_iax2.c:327
int ast_sorcery_object_id_compare(void *obj, void *arg, int flags)
ao2 object comparator based on sorcery id.
Definition: sorcery.c:2464
pj_timer_entry timer
Timer entry for retrying on temporal responses.
Full structure for sorcery.
Definition: sorcery.c:230
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
int(* iterate)(void *container, ao2_callback_fn callback, void *args)
Definition: res_pjsip_cli.h:66
Type for a default handler that should do nothing.
int stasis_subscription_set_filter(struct stasis_subscription *subscription, enum stasis_subscription_message_filter filter)
Set the message type filtering level on a subscription.
Definition: stasis.c:1077
const ast_string_field server_uri
URI for the registrar.
Outbound registration state information (persists for lifetime that registration should exist) ...
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
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
unsigned int expiration
Requested expiration time.
#define AST_DECLARE_STRING_FIELDS(field_list)
Declare the fields needed in a structure.
Definition: stringfields.h:341
Return all matching objects.
Definition: sorcery.h:120
struct ast_json * ast_json_load_string(const char *input, struct ast_json_error *error)
Parse null terminated string into a JSON object or array.
Definition: json.c:567
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3421
Outbound registration client state information (persists for lifetime of regc)
char * user_agent
The value for the User-Agent header sent in requests.
char transport_key[IP6ADDR_COLON_PORT_BUFLEN]
Key for the reliable transport in use.
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
struct ast_sip_endpoint *(* identify_endpoint)(pjsip_rx_data *rdata)
Callback used to identify the source of a message. See ast_sip_identify_endpoint for more details...
Definition: res_pjsip.h:1279
void ast_sip_transport_monitor_unregister_key(const char *transport_key, ast_transport_monitor_shutdown_cb cb, void *data, ast_transport_monitor_data_matcher matches)
Unregister a reliable transport shutdown monitor.
CLI Formatter Context passed to all formatters.
Definition: res_pjsip_cli.h:34
Definitions to aid in the use of thread local storage.
void ast_sorcery_load_object(const struct ast_sorcery *sorcery, const char *type)
Inform any wizards of a specific object type to load persistent objects.
Definition: sorcery.c:1393
int ast_sip_security_mechanisms_to_str(const struct ast_sip_security_mechanism_vector *security_mechanisms, int add_qvalue, char **buf)
Writes the security mechanisms of an endpoint into a buffer as a string and returns the buffer...
#define AST_TASKPROCESSOR_MAX_NAME
Suggested maximum taskprocessor name length (less null terminator).
Definition: taskprocessor.h:61
int ast_sip_push_task_wait_servant(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Push a task to SIP servants and wait for it to complete.
Definition: res_pjsip.c:2165
char line[LINE_PARAMETER_SIZE]
Optional line parameter placed into Contact.
Structure for registration response.
unsigned int max_retries
Maximum number of retries permitted.
JSON parsing error information.
Definition: json.h:887
void ast_sip_security_mechanisms_vector_copy(struct ast_sip_security_mechanism_vector *dst, const struct ast_sip_security_mechanism_vector *src)
Duplicate a security mechanism.
unsigned int support_outbound
Whether Outbound support is enabled.
const ast_string_field contact_user
Optional user for contact header.
struct ao2_container * ast_sorcery_retrieve_by_regex(const struct ast_sorcery *sorcery, const char *type, const char *regex)
Retrieve multiple objects using a regular expression on their id.
Definition: sorcery.c:1954
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:267
const ast_string_field oauth_clientid
Definition: res_pjsip.h:591
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
int ast_sip_add_security_headers(struct ast_sip_security_mechanism_vector *security_mechanisms, const char *header_name, int add_qval, pjsip_tx_data *tdata)
Add security headers to transmission data.
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
unsigned int retry_interval
Interval at which retries should occur for temporal responses.
Type for default option handler for bools (ast_true/ast_false)
struct sip_outbound_registration_client_state * client_state
Client state information.
#define ast_sorcery_object_field_register_custom(sorcery, type, name, default_val, config_handler, sorcery_handler, multiple_handler, flags,...)
Register a field within an object with custom handlers.
Definition: sorcery.h:1005
static void cleanup(void)
Clean up any old apps that we don't need any more.
Definition: res_stasis.c:327
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
Definition: astobj2.h:1116
struct ast_sip_auth_vector outbound_auths
Configured authentication credentials.
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
unsigned int forbidden_retry_interval
Interval at which retries should occur for permanent responses.
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
const ast_string_field outbound_proxy
Outbound proxy to use.
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:3475
void ast_sip_remove_headers_by_name_and_value(pjsip_msg *msg, const pj_str_t *hdr_name, const char *value)
Removes all headers of a specific name and value from a pjsip_msg.
int ast_sorcery_object_unregister(struct ast_sorcery *sorcery, const char *type)
Unregister an object type.
Definition: sorcery.c:1061
Type for default option handler for unsigned integers.
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
Interface for the sorcery instance observer.
Definition: sorcery.h:237
int ast_sip_push_task_wait_serializer(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Push a task to the serializer and wait for it to complete.
Definition: res_pjsip.c:2179
void ast_system_publish_registry(const char *channeltype, const char *username, const char *domain, const char *status, const char *cause)
Publish a channel driver outgoing registration message.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define AST_STRING_FIELD(name)
Declare a string field.
Definition: stringfields.h:303
const ast_string_field user_agent
User-Agent to use when sending the REGISTER.
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
int ast_sorcery_object_id_sort(const void *obj, const void *arg, int flags)
ao2 object sorter based on sorcery id.
Definition: sorcery.c:2440
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
unsigned int support_path
Determines whether SIP Path support should be advertised.
const ast_string_field transport
Explicit transport to use for registration.
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
Definition: json.c:283
pjsip_tx_data * last_tdata
Last tdata sent We need the original tdata to resend a request on auth failure or timeout...
struct mansession * s
Definition: res_pjsip.h:3033
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
struct ao2_container * container
Definition: res_fax.c:501
struct ast_taskprocessor * ast_sip_create_serializer_group(const char *name, struct ast_serializer_shutdown_group *shutdown_group)
Create a new serializer for SIP tasks.
Definition: res_pjsip.c:2089
#define ast_debug(level,...)
Log a DEBUG message.
#define AST_VECTOR(name, type)
Define a vector structure.
Definition: vector.h:44
char * registration_name
The name of the registration sorcery object.
An entity with which Asterisk communicates.
Definition: res_pjsip.h:949
#define ast_sorcery_object_register(sorcery, type, alloc, transform, apply)
Register an object type.
Definition: sorcery.h:837
Core PBX routines and definitions.
void ast_sorcery_instance_observer_remove(struct ast_sorcery *sorcery, const struct ast_sorcery_instance_observer *callbacks)
Remove an observer from a sorcery instance.
Definition: sorcery.c:537
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 sip_outbound_registration * registration
Outbound registration configuration object.
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:8057
int code
Response code for the registration attempt.
Outbound registration information.
#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
int expiration
Expiration time for registration.
Support for dynamic strings.
Definition: strings.h:623
#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
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
Type for default option handler for bools (ast_true/ast_false)
char * ast_generate_random_string(char *buf, size_t size)
Create a pseudo-random string of a fixed length.
Definition: strings.c:226
Contact associated with an address of record.
Definition: res_pjsip.h:392
SORCERY_OBJECT(details)
Sorcery object details.
enum ast_transport_monitor_reg ast_sip_transport_monitor_register_replace_key(const char *transport_key, 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.
#define ast_sorcery_objectset_create(sorcery, object)
Create an object set (KVP list) for an object.
Definition: sorcery.h:1137
unsigned int auth_rejection_permanent
Treat authentication challenges that we cannot handle as permanent failures.
struct ast_taskprocessor * serializer
Serializer for stuff and things.
char * command
Definition: cli.h:186
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.
const ast_string_field auth_pass
Definition: res_pjsip.h:585
#define STRFLDSET(type,...)
Convert a struct and a list of stringfield fields to an argument list of field offsets.
struct stasis_subscription * stasis_unsubscribe_and_join(struct stasis_subscription *subscription)
Cancel a subscription, blocking until the last message is processed.
Definition: stasis.c:1134
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
Vector container support.
An API for managing task processing threads that can be shared across modules.
An entity responsible for identifying the source of a SIP message.
Definition: res_pjsip.h:1274
const char *(* get_id)(const void *obj)
Definition: res_pjsip_cli.h:70
structure to hold users read from users.conf
const ast_string_field refresh_token
Definition: res_pjsip.h:589
void(* loaded)(const char *object_type)
Callback for when an object type is loaded/reloaded.
Definition: sorcery.h:343
unsigned int max_random_initial_delay
Maximum random initial delay interval for initial registrations.
char * transport_name
The name of the transport to be used for the registration.
const char * usage
Definition: cli.h:177
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
#define ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, flags,...)
Register a field within an object.
Definition: sorcery.h:955
enum ast_sip_security_negotiation security_negotiation
Type of security negotiation to use (RFC 3329).
#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
unsigned int retry_interval
Interval at which retries should occur for temporal responses.
The arg parameter is an object of the same type.
Definition: astobj2.h:1087
void(* object_type_loaded)(const char *name, const struct ast_sorcery *sorcery, const char *object_type, int reloaded)
Callback after any object_type is loaded/reloaded.
Definition: sorcery.h:260
unsigned int retries
Current number of retries.
#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
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
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
int ast_sorcery_changeset_create(const struct ast_variable *original, const struct ast_variable *modified, struct ast_variable **changes)
Create a changeset given two object sets.
Definition: sorcery.c:1663
struct ast_sip_auth_vector outbound_auths
Configured authentication credentials.
const ast_string_field endpoint
Endpoint to use for related incoming calls.
Standard Command Line Interface.
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:407
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:80
void * ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
Unreference the specified taskprocessor and its reference count will decrement.
struct sip_outbound_registration_client_state * client_state
Outbound registration client state.
unsigned int auth_rejection_permanent
Treat authentication challenges that we cannot handle as permanent failures.
int stasis_subscription_accept_message_type(struct stasis_subscription *subscription, const struct stasis_message_type *type)
Indicate to a subscription that we are interested in a message type.
Definition: stasis.c:1023
Abstract JSON element (object, array, string, int, ...).
Type for default option handler for stringfields.
unsigned int registration_expires
Expected time of registration lapse/expiration.
ao2_callback_fn * print_header
Definition: res_pjsip_cli.h:60
Definition: search.h:40
unsigned int fatal_retry_interval
Interval at which retries should occur for all permanent responses.
unsigned int fatal_retry_interval
Interval at which retries should occur for all permanent responses.
unsigned int destroy
Registration should be destroyed after completion of transaction.
Generic container type.
Search option field mask.
Definition: astobj2.h:1072
void * ast_sorcery_generic_alloc(size_t size, ao2_destructor_fn destructor)
Allocate a generic sorcery capable object.
Definition: sorcery.c:1728
static pj_timer_heap_t * timer_heap
Global timer heap.
void ast_sip_header_to_security_mechanism(const pjsip_generic_string_hdr *hdr, struct ast_sip_security_mechanism_vector *security_mechanisms)
Append to security mechanism vector from SIP header.
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
ao2_callback_fn * print_body
Definition: res_pjsip_cli.h:62
void ast_sip_security_mechanisms_vector_destroy(struct ast_sip_security_mechanism_vector *security_mechanisms)
Free contents of a security mechanism vector.
#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
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3389
Asterisk module definitions.
const char * name
Definition: res_pjsip_cli.h:58
const ast_string_field contact_header_params
Optional header parameters for contact.
#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
int ast_func_write(struct ast_channel *chan, const char *function, const char *value)
executes a write operation on a function
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374
pjsip_rx_data * rdata
The response message.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
const ast_string_field auth_user
Definition: res_pjsip.h:583
#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_VECTOR_CALLBACK_VOID(vec, callback,...)
Execute a callback on every element in a vector disregarding callback return.
Definition: vector.h:862
pjsip_regc * client
Outbound registration client.
enum ast_sip_security_negotiation security_negotiation
Type of security negotiation to use (RFC 3329).
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1259
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
unsigned show_details_only_level_0
Definition: res_pjsip_cli.h:46
unsigned int line
Whether to add a line parameter to the outbound Contact or not.
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532