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