Merge "ari: Implement 'debug all' and request/response logging"
[asterisk/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         <support_level>core</support_level>
23  ***/
24
25 #include "asterisk.h"
26
27 #include <pjsip.h>
28 #include <pjsip_ua.h>
29
30 #include "asterisk/res_pjsip.h"
31 #include "asterisk/res_pjsip_cli.h"
32 #include "asterisk/module.h"
33 #include "asterisk/taskprocessor.h"
34 #include "asterisk/cli.h"
35 #include "asterisk/stasis_system.h"
36 #include "asterisk/threadstorage.h"
37 #include "asterisk/threadpool.h"
38 #include "asterisk/statsd.h"
39 #include "res_pjsip/include/res_pjsip_private.h"
40
41 /*** DOCUMENTATION
42         <configInfo name="res_pjsip_outbound_registration" language="en_US">
43                 <synopsis>SIP resource for outbound registrations</synopsis>
44                 <description><para>
45                         <emphasis>Outbound Registration</emphasis>
46                         </para>
47                         <para>This module allows <literal>res_pjsip</literal> to register to other SIP servers.</para>
48                 </description>
49                 <configFile name="pjsip.conf">
50                         <configObject name="registration">
51                                 <synopsis>The configuration for outbound registration</synopsis>
52                                 <description><para>
53                                         Registration is <emphasis>COMPLETELY</emphasis> separate from the rest of
54                                         <literal>pjsip.conf</literal>. A minimal configuration consists of
55                                         setting a <literal>server_uri</literal> and a <literal>client_uri</literal>.
56                                 </para></description>
57                                 <configOption name="auth_rejection_permanent" default="yes">
58                                         <synopsis>Determines whether failed authentication challenges are treated
59                                         as permanent failures.</synopsis>
60                                         <description><para>If this option is enabled and an authentication challenge fails,
61                                         registration will not be attempted again until the configuration is reloaded.</para></description>
62                                 </configOption>
63                                 <configOption name="client_uri">
64                                         <synopsis>Client SIP URI used when attemping outbound registration</synopsis>
65                                         <description><para>
66                                                 This is the address-of-record for the outbound registration (i.e. the URI in
67                                                 the To header of the REGISTER).</para>
68                                                 <para>For registration with an ITSP, the client SIP URI may need to consist of
69                                                 an account name or number and the provider's hostname for their registrar, e.g.
70                                                 client_uri=1234567890@example.com. This may differ between providers.</para>
71                                                 <para>For registration to generic registrars, the client SIP URI will depend
72                                                 on networking specifics and configuration of the registrar.
73                                         </para></description>
74                                 </configOption>
75                                 <configOption name="contact_user">
76                                         <synopsis>Contact User to use in request</synopsis>
77                                 </configOption>
78                                 <configOption name="expiration" default="3600">
79                                         <synopsis>Expiration time for registrations in seconds</synopsis>
80                                 </configOption>
81                                 <configOption name="max_retries" default="10">
82                                         <synopsis>Maximum number of registration attempts.</synopsis>
83                                 </configOption>
84                                 <configOption name="outbound_auth" default="">
85                                         <synopsis>Authentication object to be used for outbound registrations.</synopsis>
86                                 </configOption>
87                                 <configOption name="outbound_proxy" default="">
88                                         <synopsis>Outbound Proxy used to send registrations</synopsis>
89                                 </configOption>
90                                 <configOption name="retry_interval" default="60">
91                                         <synopsis>Interval in seconds between retries if outbound registration is unsuccessful</synopsis>
92                                 </configOption>
93                                 <configOption name="forbidden_retry_interval" default="0">
94                                         <synopsis>Interval used when receiving a 403 Forbidden response.</synopsis>
95                                         <description><para>
96                                                 If a 403 Forbidden is received, chan_pjsip will wait
97                                                 <replaceable>forbidden_retry_interval</replaceable> seconds before
98                                                 attempting registration again. If 0 is specified, chan_pjsip will not
99                                                 retry after receiving a 403 Forbidden response. Setting this to a non-zero
100                                                 value goes against a "SHOULD NOT" in RFC3261, but can be used to work around
101                                                 buggy registrars.
102                                         </para></description>
103                                 </configOption>
104                                 <configOption name="fatal_retry_interval" default="0">
105                                         <synopsis>Interval used when receiving a Fatal response.</synopsis>
106                                         <description><para>
107                                                 If a fatal response is received, chan_pjsip will wait
108                                                 <replaceable>fatal_retry_interval</replaceable> seconds before
109                                                 attempting registration again. If 0 is specified, chan_pjsip will not
110                                                 retry after receiving a fatal (non-temporary 4xx, 5xx, 6xx) response.
111                                                 Setting this to a non-zero value may go against a "SHOULD NOT" in RFC3261,
112                                                 but can be used to work around buggy registrars.</para>
113                                                 <note><para>if also set the <replaceable>forbidden_retry_interval</replaceable>
114                                                 takes precedence over this one when a 403 is received.
115                                                 Also, if <replaceable>auth_rejection_permanent</replaceable> equals 'yes' then
116                                                 a 401 and 407 become subject to this retry interval.</para></note>
117                                         </description>
118                                 </configOption>
119                                 <configOption name="server_uri">
120                                         <synopsis>SIP URI of the server to register against</synopsis>
121                                         <description><para>
122                                                 This is the URI at which to find the registrar to send the outbound REGISTER. This URI
123                                                 is used as the request URI of the outbound REGISTER request from Asterisk.</para>
124                                                 <para>For registration with an ITSP, the setting may often be just the domain of
125                                                 the registrar, e.g. sip:sip.example.com.
126                                         </para></description>
127                                 </configOption>
128                                 <configOption name="transport">
129                                         <synopsis>Transport used for outbound authentication</synopsis>
130                                         <description>
131                                                 <note><para>A <replaceable>transport</replaceable> configured in
132                                                 <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>
133                                         </description>
134                                 </configOption>
135                                 <configOption name="line">
136                                         <synopsis>Whether to add a 'line' parameter to the Contact for inbound call matching</synopsis>
137                                         <description><para>
138                                                 When enabled this option will cause a 'line' parameter to be added to the Contact
139                                                 header placed into the outgoing registration request. If the remote server sends a call
140                                                 this line parameter will be used to establish a relationship to the outbound registration,
141                                                 ultimately causing the configured endpoint to be used.
142                                         </para></description>
143                                 </configOption>
144                                 <configOption name="endpoint">
145                                         <synopsis>Endpoint to use for incoming related calls</synopsis>
146                                         <description><para>
147                                                 When line support is enabled this configured endpoint name is used for incoming calls
148                                                 that are related to the outbound registration.
149                                         </para></description>
150                                 </configOption>
151                                 <configOption name="type">
152                                         <synopsis>Must be of type 'registration'.</synopsis>
153                                 </configOption>
154                                 <configOption name="support_path">
155                                         <synopsis>Enables Path support for outbound REGISTER requests.</synopsis>
156                                         <description><para>
157                                                 When this option is enabled, outbound REGISTER requests will advertise
158                                                 support for Path headers so that intervening proxies can add to the Path
159                                                 header as necessary.
160                                         </para></description>
161                                 </configOption>
162                         </configObject>
163                 </configFile>
164         </configInfo>
165         <manager name="PJSIPUnregister" language="en_US">
166                 <synopsis>
167                         Unregister an outbound registration.
168                 </synopsis>
169                 <syntax>
170                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
171                         <parameter name="Registration" required="true">
172                                 <para>The outbound registration to unregister.</para>
173                         </parameter>
174                 </syntax>
175                 <description>
176                         <para>
177                         Unregisters the specified outbound registration and stops future registration attempts.
178                         Call PJSIPRegister to start registration and schedule re-registrations according to configuration.
179             </para>
180                 </description>
181         </manager>
182         <manager name="PJSIPRegister" language="en_US">
183                 <synopsis>
184                         Register an outbound registration.
185                 </synopsis>
186                 <syntax>
187                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
188                         <parameter name="Registration" required="true">
189                                 <para>The outbound registration to register.</para>
190                         </parameter>
191                 </syntax>
192                 <description>
193                         <para>
194                         Unregisters the specified outbound registration then starts registration and schedules re-registrations
195                         according to configuration.
196                         future registrations.
197             </para>
198                 </description>
199         </manager>
200         <manager name="PJSIPShowRegistrationsOutbound" language="en_US">
201                 <synopsis>
202                         Lists PJSIP outbound registrations.
203                 </synopsis>
204                 <syntax />
205                 <description>
206                         <para>
207                         In response <literal>OutboundRegistrationDetail</literal> events showing configuration and status
208                         information are raised for each outbound registration object. <literal>AuthDetail</literal>
209                         events are raised for each associated auth object as well.  Once all events are completed an
210                         <literal>OutboundRegistrationDetailComplete</literal> is issued.
211                         </para>
212                 </description>
213         </manager>
214  ***/
215
216 /*! \brief Some thread local storage used to determine if the running thread invoked the callback */
217 AST_THREADSTORAGE(register_callback_invoked);
218
219 /*! \brief Amount of buffer time (in seconds) before expiration that we re-register at */
220 #define REREGISTER_BUFFER_TIME 10
221
222 /*! \brief Size of the buffer for creating a unique string for the line */
223 #define LINE_PARAMETER_SIZE 8
224
225 /*! \brief Various states that an outbound registration may be in */
226 enum sip_outbound_registration_status {
227         /*! \brief Currently unregistered */
228         SIP_REGISTRATION_UNREGISTERED = 0,
229         /*! \brief Registered, yay! */
230         SIP_REGISTRATION_REGISTERED,
231         /*! \brief Registration was rejected, but response was temporal */
232         SIP_REGISTRATION_REJECTED_TEMPORARY,
233         /*! \brief Registration was rejected, permanently */
234         SIP_REGISTRATION_REJECTED_PERMANENT,
235         /*! \brief Registration is stopping. */
236         SIP_REGISTRATION_STOPPING,
237         /*! \brief Registration has been stopped */
238         SIP_REGISTRATION_STOPPED,
239 };
240
241 /*!
242  * \internal
243  * \brief Convert the internal registration state to an external status string.
244  * \since 13.5.0
245  *
246  * \param state Current outbound registration state.
247  *
248  * \return External registration status string.
249  */
250 static const char *sip_outbound_registration_status_str(enum sip_outbound_registration_status state)
251 {
252         const char *str;
253
254         str = "Unregistered";
255         switch (state) {
256         case SIP_REGISTRATION_STOPPING:
257         case SIP_REGISTRATION_STOPPED:
258         case SIP_REGISTRATION_UNREGISTERED:
259                 break;
260         case SIP_REGISTRATION_REGISTERED:
261                 str = "Registered";
262                 break;
263         case SIP_REGISTRATION_REJECTED_TEMPORARY:
264         case SIP_REGISTRATION_REJECTED_PERMANENT:
265                 str = "Rejected";
266                 break;
267         }
268         return str;
269 }
270
271 /*! \brief Outbound registration information */
272 struct sip_outbound_registration {
273         /*! \brief Sorcery object details */
274         SORCERY_OBJECT(details);
275         /*! \brief Stringfields */
276         AST_DECLARE_STRING_FIELDS(
277                 /*! \brief URI for the registrar */
278                 AST_STRING_FIELD(server_uri);
279                 /*! \brief URI for the AOR */
280                 AST_STRING_FIELD(client_uri);
281                 /*! \brief Optional user for contact header */
282                 AST_STRING_FIELD(contact_user);
283                 /*! \brief Explicit transport to use for registration */
284                 AST_STRING_FIELD(transport);
285                 /*! \brief Outbound proxy to use */
286                 AST_STRING_FIELD(outbound_proxy);
287                 /*! \brief Endpoint to use for related incoming calls */
288                 AST_STRING_FIELD(endpoint);
289         );
290         /*! \brief Requested expiration time */
291         unsigned int expiration;
292         /*! \brief Interval at which retries should occur for temporal responses */
293         unsigned int retry_interval;
294         /*! \brief Interval at which retries should occur for permanent responses */
295         unsigned int forbidden_retry_interval;
296         /*! \brief Interval at which retries should occur for all permanent responses */
297         unsigned int fatal_retry_interval;
298         /*! \brief Treat authentication challenges that we cannot handle as permanent failures */
299         unsigned int auth_rejection_permanent;
300         /*! \brief Maximum number of retries permitted */
301         unsigned int max_retries;
302         /*! \brief Whether to add a line parameter to the outbound Contact or not */
303         unsigned int line;
304         /*! \brief Configured authentication credentials */
305         struct ast_sip_auth_vector outbound_auths;
306         /*! \brief Whether Path support is enabled */
307         unsigned int support_path;
308 };
309
310 /*! \brief Outbound registration client state information (persists for lifetime of regc) */
311 struct sip_outbound_registration_client_state {
312         /*! \brief Current state of this registration */
313         enum sip_outbound_registration_status status;
314         /*!
315          * \brief Outbound registration client
316          * \note May only be accessed within the serializer thread
317          * because it might get destroyed and set to NULL for
318          * module unload.
319          */
320         pjsip_regc *client;
321         /*! \brief Timer entry for retrying on temporal responses */
322         pj_timer_entry timer;
323         /*! \brief Optional line parameter placed into Contact */
324         char line[LINE_PARAMETER_SIZE];
325         /*! \brief Current number of retries */
326         unsigned int retries;
327         /*! \brief Maximum number of retries permitted */
328         unsigned int max_retries;
329         /*! \brief Interval at which retries should occur for temporal responses */
330         unsigned int retry_interval;
331         /*! \brief Interval at which retries should occur for permanent responses */
332         unsigned int forbidden_retry_interval;
333         /*! \brief Interval at which retries should occur for all permanent responses */
334         unsigned int fatal_retry_interval;
335         /*! \brief Treat authentication challenges that we cannot handle as permanent failures */
336         unsigned int auth_rejection_permanent;
337         /*! \brief Determines whether SIP Path support should be advertised */
338         unsigned int support_path;
339         /*! CSeq number of last sent auth request. */
340         unsigned int auth_cseq;
341         /*! \brief Serializer for stuff and things */
342         struct ast_taskprocessor *serializer;
343         /*! \brief Configured authentication credentials */
344         struct ast_sip_auth_vector outbound_auths;
345         /*! \brief Registration should be destroyed after completion of transaction */
346         unsigned int destroy:1;
347         /*! \brief Non-zero if we have attempted sending a REGISTER with authentication */
348         unsigned int auth_attempted:1;
349         /*! \brief The name of the transport to be used for the registration */
350         char *transport_name;
351 };
352
353 /*! \brief Outbound registration state information (persists for lifetime that registration should exist) */
354 struct sip_outbound_registration_state {
355         /*! \brief Outbound registration configuration object */
356         struct sip_outbound_registration *registration;
357         /*! \brief Client state information */
358         struct sip_outbound_registration_client_state *client_state;
359 };
360
361 /*! Time needs to be long enough for a transaction to timeout if nothing replies. */
362 #define MAX_UNLOAD_TIMEOUT_TIME         35      /* Seconds */
363
364 /*! Shutdown group to monitor sip_outbound_registration_client_state serializers. */
365 static struct ast_serializer_shutdown_group *shutdown_group;
366
367 /*! \brief Default number of state container buckets */
368 #define DEFAULT_STATE_BUCKETS 53
369 static AO2_GLOBAL_OBJ_STATIC(current_states);
370
371 /*! \brief hashing function for state objects */
372 static int registration_state_hash(const void *obj, const int flags)
373 {
374         const struct sip_outbound_registration_state *object;
375         const char *key;
376
377         switch (flags & OBJ_SEARCH_MASK) {
378         case OBJ_SEARCH_KEY:
379                 key = obj;
380                 break;
381         case OBJ_SEARCH_OBJECT:
382                 object = obj;
383                 key = ast_sorcery_object_get_id(object->registration);
384                 break;
385         default:
386                 ast_assert(0);
387                 return 0;
388         }
389         return ast_str_hash(key);
390 }
391
392 /*! \brief comparator function for state objects */
393 static int registration_state_cmp(void *obj, void *arg, int flags)
394 {
395         const struct sip_outbound_registration_state *object_left = obj;
396         const struct sip_outbound_registration_state *object_right = arg;
397         const char *right_key = arg;
398         int cmp;
399
400         switch (flags & OBJ_SEARCH_MASK) {
401         case OBJ_SEARCH_OBJECT:
402                 right_key = ast_sorcery_object_get_id(object_right->registration);
403                 /* Fall through */
404         case OBJ_SEARCH_KEY:
405                 cmp = strcmp(ast_sorcery_object_get_id(object_left->registration), right_key);
406                 break;
407         case OBJ_SEARCH_PARTIAL_KEY:
408                 /* Not supported by container. */
409                 ast_assert(0);
410                 return 0;
411         default:
412                 cmp = 0;
413                 break;
414         }
415         if (cmp) {
416                 return 0;
417         }
418         return CMP_MATCH;
419 }
420
421 static struct sip_outbound_registration_state *get_state(const char *id)
422 {
423         struct sip_outbound_registration_state *state = NULL;
424         struct ao2_container *states;
425
426         states = ao2_global_obj_ref(current_states);
427         if (states) {
428                 state = ao2_find(states, id, OBJ_SEARCH_KEY);
429                 ao2_ref(states, -1);
430         }
431         return state;
432 }
433
434 static struct ao2_container *get_registrations(void)
435 {
436         struct ao2_container *registrations = ast_sorcery_retrieve_by_fields(
437                 ast_sip_get_sorcery(), "registration",
438                 AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
439
440         return registrations;
441 }
442
443 /*! \brief Callback function for matching an outbound registration based on line */
444 static int line_identify_relationship(void *obj, void *arg, int flags)
445 {
446         struct sip_outbound_registration_state *state = obj;
447         pjsip_param *line = arg;
448
449         return !pj_strcmp2(&line->value, state->client_state->line) ? CMP_MATCH | CMP_STOP : 0;
450 }
451
452 static struct pjsip_param *get_uri_option_line(const void *uri)
453 {
454         pjsip_sip_uri *pjuri;
455         static const pj_str_t LINE_STR = { "line", 4 };
456
457         if (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri)) {
458                 return NULL;
459         }
460         pjuri = pjsip_uri_get_uri(uri);
461         return pjsip_param_find(&pjuri->other_param, &LINE_STR);
462 }
463
464 /*! \brief Endpoint identifier which uses the 'line' parameter to establish a relationship to an outgoing registration */
465 static struct ast_sip_endpoint *line_identify(pjsip_rx_data *rdata)
466 {
467         pjsip_param *line;
468         RAII_VAR(struct ao2_container *, states, NULL, ao2_cleanup);
469         RAII_VAR(struct sip_outbound_registration_state *, state, NULL, ao2_cleanup);
470
471         if (!(line = get_uri_option_line(rdata->msg_info.to->uri))
472                 && !(line = get_uri_option_line(rdata->msg_info.msg->line.req.uri))) {
473                 return NULL;
474         }
475
476         states = ao2_global_obj_ref(current_states);
477         if (!states) {
478                 return NULL;
479         }
480
481         state = ao2_callback(states, 0, line_identify_relationship, line);
482         if (!state || ast_strlen_zero(state->registration->endpoint)) {
483                 return NULL;
484         }
485
486         ast_debug(3, "Determined relationship to outbound registration '%s' based on line '%s', using configured endpoint '%s'\n",
487                 ast_sorcery_object_get_id(state->registration), state->client_state->line, state->registration->endpoint);
488
489         return ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", state->registration->endpoint);
490 }
491
492 static struct ast_sip_endpoint_identifier line_identifier = {
493         .identify_endpoint = line_identify,
494 };
495
496 /*! \brief Helper function which cancels the timer on a client */
497 static void cancel_registration(struct sip_outbound_registration_client_state *client_state)
498 {
499         if (pj_timer_heap_cancel(pjsip_endpt_get_timer_heap(ast_sip_get_pjsip_endpoint()), &client_state->timer)) {
500                 /* The timer was successfully cancelled, drop the refcount of client_state */
501                 ao2_ref(client_state, -1);
502         }
503 }
504
505 static pj_str_t PATH_NAME = { "path", 4 };
506
507 /*! \brief Helper function which sends a message and cleans up, if needed, on failure */
508 static pj_status_t registration_client_send(struct sip_outbound_registration_client_state *client_state,
509         pjsip_tx_data *tdata)
510 {
511         pj_status_t status;
512         int *callback_invoked;
513         pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
514
515         callback_invoked = ast_threadstorage_get(&register_callback_invoked, sizeof(int));
516         if (!callback_invoked) {
517                 pjsip_tx_data_dec_ref(tdata);
518                 return PJ_ENOMEM;
519         }
520         *callback_invoked = 0;
521
522         /* Due to the message going out the callback may now be invoked, so bump the count */
523         ao2_ref(client_state, +1);
524         /*
525          * Set the transport in case transports were reloaded.
526          * When pjproject removes the extraneous error messages produced,
527          * we can check status and only set the transport and resend if there was an error
528          */
529         ast_sip_set_tpselector_from_transport_name(client_state->transport_name, &selector);
530         pjsip_regc_set_transport(client_state->client, &selector);
531         status = pjsip_regc_send(client_state->client, tdata);
532
533         /* If the attempt to send the message failed and the callback was not invoked we need to
534          * drop the reference we just added
535          */
536         if ((status != PJ_SUCCESS) && !(*callback_invoked)) {
537                 ao2_ref(client_state, -1);
538         }
539
540         return status;
541 }
542
543 /*! \brief Callback function for registering */
544 static int handle_client_registration(void *data)
545 {
546         RAII_VAR(struct sip_outbound_registration_client_state *, client_state, data, ao2_cleanup);
547         pjsip_tx_data *tdata;
548         pjsip_regc_info info;
549         char server_uri[PJSIP_MAX_URL_SIZE];
550         char client_uri[PJSIP_MAX_URL_SIZE];
551
552         if (client_state->status == SIP_REGISTRATION_STOPPED
553                 || pjsip_regc_register(client_state->client, PJ_FALSE, &tdata) != PJ_SUCCESS) {
554                 return 0;
555         }
556
557         pjsip_regc_get_info(client_state->client, &info);
558         ast_copy_pj_str(server_uri, &info.server_uri, sizeof(server_uri));
559         ast_copy_pj_str(client_uri, &info.client_uri, sizeof(client_uri));
560         ast_debug(1, "Outbound REGISTER attempt %u to '%s' with client '%s'\n",
561                 client_state->retries + 1, server_uri, client_uri);
562
563         if (client_state->support_path) {
564                 pjsip_supported_hdr *hdr;
565
566                 hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_SUPPORTED, NULL);
567                 if (!hdr) {
568                         /* insert a new Supported header */
569                         hdr = pjsip_supported_hdr_create(tdata->pool);
570                         if (!hdr) {
571                                 pjsip_tx_data_dec_ref(tdata);
572                                 return -1;
573                         }
574
575                         pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *)hdr);
576                 }
577
578                 /* add on to the existing Supported header */
579                 pj_strassign(&hdr->values[hdr->count++], &PATH_NAME);
580         }
581
582         registration_client_send(client_state, tdata);
583
584         return 0;
585 }
586
587 /*! \brief Timer callback function, used just for registrations */
588 static void sip_outbound_registration_timer_cb(pj_timer_heap_t *timer_heap, struct pj_timer_entry *entry)
589 {
590         struct sip_outbound_registration_client_state *client_state = entry->user_data;
591
592         entry->id = 0;
593
594         /*
595          * Transfer client_state reference to serializer task so the
596          * nominal path will not dec the client_state ref in this
597          * pjproject callback thread.
598          */
599         if (ast_sip_push_task(client_state->serializer, handle_client_registration, client_state)) {
600                 ast_log(LOG_WARNING, "Scheduled outbound registration could not be executed.\n");
601                 ao2_ref(client_state, -1);
602         }
603 }
604
605 /*! \brief Helper function which sets up the timer to re-register in a specific amount of time */
606 static void schedule_registration(struct sip_outbound_registration_client_state *client_state, unsigned int seconds)
607 {
608         pj_time_val delay = { .sec = seconds, };
609         pjsip_regc_info info;
610
611         cancel_registration(client_state);
612
613         pjsip_regc_get_info(client_state->client, &info);
614         ast_debug(1, "Scheduling outbound registration to server '%.*s' from client '%.*s' in %d seconds\n",
615                         (int) info.server_uri.slen, info.server_uri.ptr,
616                         (int) info.client_uri.slen, info.client_uri.ptr,
617                         seconds);
618
619         ao2_ref(client_state, +1);
620         if (pjsip_endpt_schedule_timer(ast_sip_get_pjsip_endpoint(), &client_state->timer, &delay) != PJ_SUCCESS) {
621                 ast_log(LOG_WARNING, "Failed to schedule registration to server '%.*s' from client '%.*s'\n",
622                                 (int) info.server_uri.slen, info.server_uri.ptr,
623                                 (int) info.client_uri.slen, info.client_uri.ptr);
624                 ao2_ref(client_state, -1);
625         }
626 }
627
628 static void update_client_state_status(struct sip_outbound_registration_client_state *client_state, enum sip_outbound_registration_status status)
629 {
630         const char *status_old;
631         const char *status_new;
632
633         if (client_state->status == status) {
634                 /* Status state did not change at all. */
635                 return;
636         }
637
638         status_old = sip_outbound_registration_status_str(client_state->status);
639         status_new = sip_outbound_registration_status_str(status);
640         client_state->status = status;
641
642         if (!strcmp(status_old, status_new)) {
643                 /*
644                  * The internal status state may have changed but the status
645                  * state we tell the world did not change at all.
646                  */
647                 return;
648         }
649
650         ast_statsd_log_string_va("PJSIP.registrations.state.%s", AST_STATSD_GAUGE, "-1", 1.0,
651                 status_old);
652         ast_statsd_log_string_va("PJSIP.registrations.state.%s", AST_STATSD_GAUGE, "+1", 1.0,
653                 status_new);
654 }
655
656 /*! \brief Callback function for unregistering (potentially) and destroying state */
657 static int handle_client_state_destruction(void *data)
658 {
659         struct sip_outbound_registration_client_state *client_state = data;
660
661         cancel_registration(client_state);
662
663         if (client_state->client) {
664                 pjsip_regc_info info;
665                 pjsip_tx_data *tdata;
666
667                 pjsip_regc_get_info(client_state->client, &info);
668
669                 if (info.is_busy == PJ_TRUE) {
670                         /* If a client transaction is in progress we defer until it is complete */
671                         ast_debug(1,
672                                 "Registration transaction is busy with server '%.*s' from client '%.*s'.\n",
673                                 (int) info.server_uri.slen, info.server_uri.ptr,
674                                 (int) info.client_uri.slen, info.client_uri.ptr);
675                         client_state->destroy = 1;
676                         ao2_ref(client_state, -1);
677                         return 0;
678                 }
679
680                 switch (client_state->status) {
681                 case SIP_REGISTRATION_UNREGISTERED:
682                         break;
683                 case SIP_REGISTRATION_REGISTERED:
684                         ast_debug(1,
685                                 "Trying to unregister with server '%.*s' from client '%.*s' before destruction.\n",
686                                 (int) info.server_uri.slen, info.server_uri.ptr,
687                                 (int) info.client_uri.slen, info.client_uri.ptr);
688
689                         update_client_state_status(client_state, SIP_REGISTRATION_STOPPING);
690                         client_state->destroy = 1;
691                         if (pjsip_regc_unregister(client_state->client, &tdata) == PJ_SUCCESS
692                                 && registration_client_send(client_state, tdata) == PJ_SUCCESS) {
693                                 ao2_ref(client_state, -1);
694                                 return 0;
695                         }
696                         break;
697                 case SIP_REGISTRATION_REJECTED_TEMPORARY:
698                 case SIP_REGISTRATION_REJECTED_PERMANENT:
699                 case SIP_REGISTRATION_STOPPING:
700                 case SIP_REGISTRATION_STOPPED:
701                         break;
702                 }
703
704                 pjsip_regc_destroy(client_state->client);
705                 client_state->client = NULL;
706         }
707
708         update_client_state_status(client_state, SIP_REGISTRATION_STOPPED);
709         ast_sip_auth_vector_destroy(&client_state->outbound_auths);
710         ao2_ref(client_state, -1);
711
712         return 0;
713 }
714
715 /*! \brief Structure for registration response */
716 struct registration_response {
717         /*! \brief Response code for the registration attempt */
718         int code;
719         /*! \brief Expiration time for registration */
720         int expiration;
721         /*! \brief Retry-After value */
722         int retry_after;
723         /*! \brief Outbound registration client state */
724         struct sip_outbound_registration_client_state *client_state;
725         /*! \brief The response message */
726         pjsip_rx_data *rdata;
727         /*! \brief Request for which the response was received */
728         pjsip_tx_data *old_request;
729 };
730
731 /*! \brief Registration response structure destructor */
732 static void registration_response_destroy(void *obj)
733 {
734         struct registration_response *response = obj;
735
736         if (response->rdata) {
737                 pjsip_rx_data_free_cloned(response->rdata);
738         }
739
740         if (response->old_request) {
741                 pjsip_tx_data_dec_ref(response->old_request);
742         }
743
744         ao2_cleanup(response->client_state);
745 }
746
747 /*! \brief Helper function which determines if a response code is temporal or not */
748 static int sip_outbound_registration_is_temporal(unsigned int code,
749                 struct sip_outbound_registration_client_state *client_state)
750 {
751         /* Shamelessly taken from pjsua */
752         if (code == PJSIP_SC_REQUEST_TIMEOUT ||
753                 code == PJSIP_SC_INTERNAL_SERVER_ERROR ||
754                 code == PJSIP_SC_BAD_GATEWAY ||
755                 code == PJSIP_SC_SERVICE_UNAVAILABLE ||
756                 code == PJSIP_SC_SERVER_TIMEOUT ||
757                 ((code == PJSIP_SC_UNAUTHORIZED ||
758                   code == PJSIP_SC_PROXY_AUTHENTICATION_REQUIRED) &&
759                  !client_state->auth_rejection_permanent) ||
760                 PJSIP_IS_STATUS_IN_CLASS(code, 600)) {
761                 return 1;
762         } else {
763                 return 0;
764         }
765 }
766
767 static void schedule_retry(struct registration_response *response, unsigned int interval,
768                            const char *server_uri, const char *client_uri)
769 {
770         update_client_state_status(response->client_state, SIP_REGISTRATION_REJECTED_TEMPORARY);
771         schedule_registration(response->client_state, interval);
772
773         if (response->rdata) {
774                 ast_log(LOG_WARNING, "Temporal response '%d' received from '%s' on "
775                         "registration attempt to '%s', retrying in '%u'\n",
776                         response->code, server_uri, client_uri, interval);
777         } else {
778                 ast_log(LOG_WARNING, "No response received from '%s' on "
779                         "registration attempt to '%s', retrying in '%u'\n",
780                         server_uri, client_uri, interval);
781         }
782 }
783
784 /*! \brief Callback function for handling a response to a registration attempt */
785 static int handle_registration_response(void *data)
786 {
787         struct registration_response *response = data;
788         pjsip_regc_info info;
789         char server_uri[PJSIP_MAX_URL_SIZE];
790         char client_uri[PJSIP_MAX_URL_SIZE];
791
792         if (response->client_state->status == SIP_REGISTRATION_STOPPED) {
793                 ao2_ref(response, -1);
794                 return 0;
795         }
796
797         pjsip_regc_get_info(response->client_state->client, &info);
798         ast_copy_pj_str(server_uri, &info.server_uri, sizeof(server_uri));
799         ast_copy_pj_str(client_uri, &info.client_uri, sizeof(client_uri));
800
801         ast_debug(1, "Processing REGISTER response %d from server '%s' for client '%s'\n",
802                         response->code, server_uri, client_uri);
803
804         if ((response->code == 401 || response->code == 407)
805                 && (!response->client_state->auth_attempted
806                         || response->rdata->msg_info.cseq->cseq != response->client_state->auth_cseq)) {
807                 int res;
808                 pjsip_cseq_hdr *cseq_hdr;
809                 pjsip_tx_data *tdata;
810
811                 if (!ast_sip_create_request_with_auth(&response->client_state->outbound_auths,
812                                 response->rdata, response->old_request, &tdata)) {
813                         response->client_state->auth_attempted = 1;
814                         ast_debug(1, "Sending authenticated REGISTER to server '%s' from client '%s'\n",
815                                         server_uri, client_uri);
816                         pjsip_tx_data_add_ref(tdata);
817                         res = registration_client_send(response->client_state, tdata);
818
819                         /* Save the cseq that actually got sent. */
820                         cseq_hdr = (pjsip_cseq_hdr *) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ,
821                                 NULL);
822                         response->client_state->auth_cseq = cseq_hdr->cseq;
823                         pjsip_tx_data_dec_ref(tdata);
824                         if (res == PJ_SUCCESS) {
825                                 ao2_ref(response, -1);
826                                 return 0;
827                         }
828                 } else {
829                         ast_log(LOG_WARNING, "Failed to create authenticated REGISTER request to server '%s' from client '%s'\n",
830                                         server_uri, client_uri);
831                 }
832                 /* Otherwise, fall through so the failure is processed appropriately */
833         }
834
835         response->client_state->auth_attempted = 0;
836
837         if (PJSIP_IS_STATUS_IN_CLASS(response->code, 200)) {
838                 /* Check if this is in regards to registering or unregistering */
839                 if (response->expiration) {
840                         int next_registration_round;
841
842                         /* If the registration went fine simply reschedule registration for the future */
843                         ast_debug(1, "Outbound registration to '%s' with client '%s' successful\n", server_uri, client_uri);
844                         update_client_state_status(response->client_state, SIP_REGISTRATION_REGISTERED);
845                         response->client_state->retries = 0;
846                         next_registration_round = response->expiration - REREGISTER_BUFFER_TIME;
847                         if (next_registration_round < 0) {
848                                 /* Re-register immediately. */
849                                 next_registration_round = 0;
850                         }
851                         schedule_registration(response->client_state, next_registration_round);
852                 } else {
853                         ast_debug(1, "Outbound unregistration to '%s' with client '%s' successful\n", server_uri, client_uri);
854                         update_client_state_status(response->client_state, SIP_REGISTRATION_UNREGISTERED);
855                 }
856         } else if (response->client_state->destroy) {
857                 /* We need to deal with the pending destruction instead. */
858         } else if (response->retry_after) {
859                 /* If we have been instructed to retry after a period of time, schedule it as such */
860                 schedule_retry(response, response->retry_after, server_uri, client_uri);
861         } else if (response->client_state->retry_interval
862                 && sip_outbound_registration_is_temporal(response->code, response->client_state)) {
863                 if (response->client_state->retries == response->client_state->max_retries) {
864                         /* If we received enough temporal responses to exceed our maximum give up permanently */
865                         update_client_state_status(response->client_state, SIP_REGISTRATION_REJECTED_PERMANENT);
866                         ast_log(LOG_WARNING, "Maximum retries reached when attempting outbound registration to '%s' with client '%s', stopping registration attempt\n",
867                                 server_uri, client_uri);
868                 } else {
869                         /* On the other hand if we can still try some more do so */
870                         response->client_state->retries++;
871                         schedule_retry(response, response->client_state->retry_interval, server_uri, client_uri);
872                 }
873         } else {
874                 if (response->code == 403
875                         && response->client_state->forbidden_retry_interval
876                         && response->client_state->retries < response->client_state->max_retries) {
877                         /* A forbidden response retry interval is configured and there are retries remaining */
878                         update_client_state_status(response->client_state, SIP_REGISTRATION_REJECTED_TEMPORARY);
879                         response->client_state->retries++;
880                         schedule_registration(response->client_state, response->client_state->forbidden_retry_interval);
881                         ast_log(LOG_WARNING, "403 Forbidden fatal response received from '%s' on registration attempt to '%s', retrying in '%u' seconds\n",
882                                 server_uri, client_uri, response->client_state->forbidden_retry_interval);
883                 } else if (response->client_state->fatal_retry_interval
884                            && response->client_state->retries < response->client_state->max_retries) {
885                         /* Some kind of fatal failure response received, so retry according to configured interval */
886                         update_client_state_status(response->client_state, SIP_REGISTRATION_REJECTED_TEMPORARY);
887                         response->client_state->retries++;
888                         schedule_registration(response->client_state, response->client_state->fatal_retry_interval);
889                         ast_log(LOG_WARNING, "'%d' fatal response received from '%s' on registration attempt to '%s', retrying in '%u' seconds\n",
890                                 response->code, server_uri, client_uri, response->client_state->fatal_retry_interval);
891                 } else {
892                         /* Finally if there's no hope of registering give up */
893                         update_client_state_status(response->client_state, SIP_REGISTRATION_REJECTED_PERMANENT);
894                         if (response->rdata) {
895                                 ast_log(LOG_WARNING, "Fatal response '%d' received from '%s' on registration attempt to '%s', stopping outbound registration\n",
896                                         response->code, server_uri, client_uri);
897                         } else {
898                                 ast_log(LOG_WARNING, "Fatal registration attempt to '%s', stopping outbound registration\n", client_uri);
899                         }
900                 }
901         }
902
903         ast_system_publish_registry("PJSIP", client_uri, server_uri,
904                 sip_outbound_registration_status_str(response->client_state->status), NULL);
905
906         if (response->client_state->destroy) {
907                 /* We have a pending deferred destruction to complete now. */
908                 ao2_ref(response->client_state, +1);
909                 handle_client_state_destruction(response->client_state);
910         }
911
912         ao2_ref(response, -1);
913         return 0;
914 }
915
916 /*! \brief Callback function for outbound registration client */
917 static void sip_outbound_registration_response_cb(struct pjsip_regc_cbparam *param)
918 {
919         struct sip_outbound_registration_client_state *client_state = param->token;
920         struct registration_response *response;
921         int *callback_invoked;
922
923         callback_invoked = ast_threadstorage_get(&register_callback_invoked, sizeof(int));
924
925         ast_assert(callback_invoked != NULL);
926         ast_assert(client_state != NULL);
927
928         *callback_invoked = 1;
929
930         response = ao2_alloc(sizeof(*response), registration_response_destroy);
931         if (!response) {
932                 ao2_ref(client_state, -1);
933                 return;
934         }
935         response->code = param->code;
936         response->expiration = param->expiration;
937         /*
938          * Transfer client_state reference to response so the
939          * nominal path will not dec the client_state ref in this
940          * pjproject callback thread.
941          */
942         response->client_state = client_state;
943
944         ast_debug(1, "Received REGISTER response %d(%.*s)\n",
945                 param->code, (int) param->reason.slen, param->reason.ptr);
946
947         if (param->rdata) {
948                 struct pjsip_retry_after_hdr *retry_after;
949                 pjsip_transaction *tsx;
950
951                 retry_after = pjsip_msg_find_hdr(param->rdata->msg_info.msg, PJSIP_H_RETRY_AFTER,
952                         NULL);
953                 response->retry_after = retry_after ? retry_after->ivalue : 0;
954                 tsx = pjsip_rdata_get_tsx(param->rdata);
955                 response->old_request = tsx->last_tx;
956                 pjsip_tx_data_add_ref(response->old_request);
957                 pjsip_rx_data_clone(param->rdata, 0, &response->rdata);
958         }
959
960         /*
961          * Transfer response reference to serializer task so the
962          * nominal path will not dec the response ref in this
963          * pjproject callback thread.
964          */
965         if (ast_sip_push_task(client_state->serializer, handle_registration_response, response)) {
966                 ast_log(LOG_WARNING, "Failed to pass incoming registration response to threadpool\n");
967                 ao2_cleanup(response);
968         }
969 }
970
971 /*! \brief Destructor function for registration state */
972 static void sip_outbound_registration_state_destroy(void *obj)
973 {
974         struct sip_outbound_registration_state *state = obj;
975
976         ast_debug(3, "Destroying registration state for registration to server '%s' from client '%s'\n",
977                         state->registration->server_uri, state->registration->client_uri);
978         ao2_cleanup(state->registration);
979
980         if (!state->client_state) {
981                 /* Nothing to do */
982         } else if (!state->client_state->serializer) {
983                 ao2_ref(state->client_state, -1);
984         } else if (ast_sip_push_task(state->client_state->serializer,
985                 handle_client_state_destruction, state->client_state)) {
986                 ast_log(LOG_WARNING, "Failed to pass outbound registration client destruction to threadpool\n");
987                 ao2_ref(state->client_state, -1);
988         }
989 }
990
991 /*! \brief Destructor function for client registration state */
992 static void sip_outbound_registration_client_state_destroy(void *obj)
993 {
994         struct sip_outbound_registration_client_state *client_state = obj;
995
996         ast_free(client_state->transport_name);
997         ast_statsd_log_string("PJSIP.registrations.count", AST_STATSD_GAUGE, "-1", 1.0);
998         ast_statsd_log_string_va("PJSIP.registrations.state.%s", AST_STATSD_GAUGE, "-1", 1.0,
999                 sip_outbound_registration_status_str(client_state->status));
1000
1001         ast_taskprocessor_unreference(client_state->serializer);
1002 }
1003
1004 /*! \brief Allocator function for registration state */
1005 static struct sip_outbound_registration_state *sip_outbound_registration_state_alloc(struct sip_outbound_registration *registration)
1006 {
1007         struct sip_outbound_registration_state *state;
1008         char tps_name[AST_TASKPROCESSOR_MAX_NAME + 1];
1009
1010         state = ao2_alloc(sizeof(*state), sip_outbound_registration_state_destroy);
1011         if (!state) {
1012                 return NULL;
1013         }
1014         state->client_state = ao2_alloc(sizeof(*state->client_state),
1015                 sip_outbound_registration_client_state_destroy);
1016         if (!state->client_state) {
1017                 ao2_cleanup(state);
1018                 return NULL;
1019         }
1020
1021         /* Create name with seq number appended. */
1022         ast_taskprocessor_build_name(tps_name, sizeof(tps_name), "pjsip/outreg/%s",
1023                 ast_sorcery_object_get_id(registration));
1024
1025         state->client_state->serializer = ast_sip_create_serializer_group(tps_name,
1026                 shutdown_group);
1027         if (!state->client_state->serializer) {
1028                 ao2_cleanup(state);
1029                 return NULL;
1030         }
1031         state->client_state->status = SIP_REGISTRATION_UNREGISTERED;
1032         state->client_state->timer.user_data = state->client_state;
1033         state->client_state->timer.cb = sip_outbound_registration_timer_cb;
1034         state->client_state->transport_name = ast_strdup(registration->transport);
1035
1036         ast_statsd_log_string("PJSIP.registrations.count", AST_STATSD_GAUGE, "+1", 1.0);
1037         ast_statsd_log_string_va("PJSIP.registrations.state.%s", AST_STATSD_GAUGE, "+1", 1.0,
1038                 sip_outbound_registration_status_str(state->client_state->status));
1039
1040         state->registration = ao2_bump(registration);
1041         return state;
1042 }
1043
1044 /*! \brief Destructor function for registration information */
1045 static void sip_outbound_registration_destroy(void *obj)
1046 {
1047         struct sip_outbound_registration *registration = obj;
1048
1049         ast_sip_auth_vector_destroy(&registration->outbound_auths);
1050
1051         ast_string_field_free_memory(registration);
1052 }
1053
1054 /*! \brief Allocator function for registration information */
1055 static void *sip_outbound_registration_alloc(const char *name)
1056 {
1057         struct sip_outbound_registration *registration;
1058
1059         registration = ast_sorcery_generic_alloc(sizeof(*registration),
1060                 sip_outbound_registration_destroy);
1061         if (!registration || ast_string_field_init(registration, 256)) {
1062                 ao2_cleanup(registration);
1063                 return NULL;
1064         }
1065
1066         return registration;
1067 }
1068
1069 /*! \brief Helper function which populates a pj_str_t with a contact header */
1070 static int sip_dialog_create_contact(pj_pool_t *pool, pj_str_t *contact, const char *user,
1071         const pj_str_t *target, pjsip_tpselector *selector, const char *line)
1072 {
1073         pj_str_t tmp, local_addr;
1074         pjsip_uri *uri;
1075         pjsip_sip_uri *sip_uri;
1076         pjsip_transport_type_e type = PJSIP_TRANSPORT_UNSPECIFIED;
1077         int local_port;
1078
1079         pj_strdup_with_null(pool, &tmp, target);
1080
1081         if (!(uri = pjsip_parse_uri(pool, tmp.ptr, tmp.slen, 0)) ||
1082             (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri))) {
1083                 return -1;
1084         }
1085
1086         sip_uri = pjsip_uri_get_uri(uri);
1087
1088         if (PJSIP_URI_SCHEME_IS_SIPS(sip_uri)) {
1089                 type = PJSIP_TRANSPORT_TLS;
1090         } else if (!sip_uri->transport_param.slen) {
1091                 type = PJSIP_TRANSPORT_UDP;
1092         } else {
1093                 type = pjsip_transport_get_type_from_name(&sip_uri->transport_param);
1094         }
1095
1096         if (type == PJSIP_TRANSPORT_UNSPECIFIED) {
1097                 return -1;
1098         }
1099
1100         if (pj_strchr(&sip_uri->host, ':')) {
1101                 type = (pjsip_transport_type_e)(((int)type) + PJSIP_TRANSPORT_IPV6);
1102         }
1103
1104         if (pjsip_tpmgr_find_local_addr(pjsip_endpt_get_tpmgr(ast_sip_get_pjsip_endpoint()),
1105                 pool, type, selector, &local_addr, &local_port) != PJ_SUCCESS) {
1106                 return -1;
1107         }
1108
1109         if (!pj_strchr(&sip_uri->host, ':') && pj_strchr(&local_addr, ':')) {
1110                 type = (pjsip_transport_type_e)(((int)type) + PJSIP_TRANSPORT_IPV6);
1111         }
1112
1113         contact->ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
1114         contact->slen = pj_ansi_snprintf(contact->ptr, PJSIP_MAX_URL_SIZE,
1115                 "<%s:%s@%s%.*s%s:%d%s%s%s%s>",
1116                 ((pjsip_transport_get_flag_from_type(type) & PJSIP_TRANSPORT_SECURE) && PJSIP_URI_SCHEME_IS_SIPS(uri)) ? "sips" : "sip",
1117                 user,
1118                 (type & PJSIP_TRANSPORT_IPV6) ? "[" : "",
1119                 (int)local_addr.slen,
1120                 local_addr.ptr,
1121                 (type & PJSIP_TRANSPORT_IPV6) ? "]" : "",
1122                 local_port,
1123                 (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? ";transport=" : "",
1124                 (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? pjsip_transport_get_type_name(type) : "",
1125                 !ast_strlen_zero(line) ? ";line=" : "",
1126                 S_OR(line, ""));
1127
1128         return 0;
1129 }
1130
1131 /*!
1132  * \internal
1133  * \brief Check if a registration can be reused
1134  *
1135  * This checks if the existing outbound registration's configuration differs from a newly-applied
1136  * outbound registration to see if the applied one.
1137  *
1138  * \param existing The pre-existing outbound registration
1139  * \param applied The newly-created registration
1140  */
1141 static int can_reuse_registration(struct sip_outbound_registration *existing,
1142         struct sip_outbound_registration *applied)
1143 {
1144         int rc = 1;
1145         struct ast_sorcery *sorcery = ast_sip_get_sorcery();
1146         struct ast_variable *ve = ast_sorcery_objectset_create(sorcery, existing);
1147         struct ast_variable *va = ast_sorcery_objectset_create(sorcery, applied);
1148         struct ast_variable *vc = NULL;
1149
1150         if (ast_sorcery_changeset_create(ve, va, &vc) || vc != NULL) {
1151                 rc = 0;
1152                 ast_debug(4, "Registration '%s' changed.  Can't re-use.\n", ast_sorcery_object_get_id(existing));
1153         } else {
1154                 ast_debug(4, "Registration '%s' didn't change.  Can re-use\n", ast_sorcery_object_get_id(existing));
1155         }
1156
1157         ast_variables_destroy(ve);
1158         ast_variables_destroy(va);
1159         ast_variables_destroy(vc);
1160
1161         return rc;
1162 }
1163
1164 /*! \brief Helper function that allocates a pjsip registration client and configures it */
1165 static int sip_outbound_registration_regc_alloc(void *data)
1166 {
1167         struct sip_outbound_registration_state *state = data;
1168         RAII_VAR(struct sip_outbound_registration *, registration,
1169                  ao2_bump(state->registration), ao2_cleanup);
1170         pj_pool_t *pool;
1171         pj_str_t tmp;
1172         pjsip_uri *uri;
1173         pj_str_t server_uri, client_uri, contact_uri;
1174         pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
1175
1176         pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "URI Validation", 256, 256);
1177         if (!pool) {
1178                 ast_log(LOG_ERROR, "Could not create pool for URI validation on outbound registration '%s'\n",
1179                         ast_sorcery_object_get_id(registration));
1180                 return -1;
1181         }
1182
1183         pj_strdup2_with_null(pool, &tmp, registration->server_uri);
1184         uri = pjsip_parse_uri(pool, tmp.ptr, tmp.slen, 0);
1185         if (!uri) {
1186                 ast_log(LOG_ERROR, "Invalid server URI '%s' specified on outbound registration '%s'\n",
1187                         registration->server_uri, ast_sorcery_object_get_id(registration));
1188                 pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
1189                 return -1;
1190         }
1191
1192         pj_strdup2_with_null(pool, &tmp, registration->client_uri);
1193         uri = pjsip_parse_uri(pool, tmp.ptr, tmp.slen, 0);
1194         if (!uri) {
1195                 ast_log(LOG_ERROR, "Invalid client URI '%s' specified on outbound registration '%s'\n",
1196                         registration->client_uri, ast_sorcery_object_get_id(registration));
1197                 pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
1198                 return -1;
1199         }
1200
1201         pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
1202
1203
1204         ast_assert(state->client_state->client == NULL);
1205         if (pjsip_regc_create(ast_sip_get_pjsip_endpoint(), state->client_state,
1206                         sip_outbound_registration_response_cb,
1207                         &state->client_state->client) != PJ_SUCCESS) {
1208                 return -1;
1209         }
1210
1211         ast_sip_set_tpselector_from_transport_name(registration->transport, &selector);
1212         pjsip_regc_set_transport(state->client_state->client, &selector);
1213
1214         if (!ast_strlen_zero(registration->outbound_proxy)) {
1215                 pjsip_route_hdr route_set, *route;
1216                 static const pj_str_t ROUTE_HNAME = { "Route", 5 };
1217                 pj_str_t tmp;
1218
1219                 pj_list_init(&route_set);
1220
1221                 pj_strdup2_with_null(pjsip_regc_get_pool(state->client_state->client), &tmp,
1222                         registration->outbound_proxy);
1223                 route = pjsip_parse_hdr(pjsip_regc_get_pool(state->client_state->client),
1224                         &ROUTE_HNAME, tmp.ptr, tmp.slen, NULL);
1225                 if (!route) {
1226                         return -1;
1227                 }
1228                 pj_list_insert_nodes_before(&route_set, route);
1229
1230                 pjsip_regc_set_route_set(state->client_state->client, &route_set);
1231         }
1232
1233         if (state->registration->line) {
1234                 ast_generate_random_string(state->client_state->line, sizeof(state->client_state->line));
1235         }
1236
1237         pj_cstr(&server_uri, registration->server_uri);
1238
1239
1240         if (sip_dialog_create_contact(pjsip_regc_get_pool(state->client_state->client),
1241                 &contact_uri, S_OR(registration->contact_user, "s"), &server_uri, &selector,
1242                 state->client_state->line)) {
1243                 return -1;
1244         }
1245
1246         pj_cstr(&client_uri, registration->client_uri);
1247         if (pjsip_regc_init(state->client_state->client, &server_uri, &client_uri,
1248                 &client_uri, 1, &contact_uri, registration->expiration) != PJ_SUCCESS) {
1249                 return -1;
1250         }
1251
1252         return 0;
1253 }
1254
1255 /*! \brief Helper function which performs a single registration */
1256 static int sip_outbound_registration_perform(void *data)
1257 {
1258         struct sip_outbound_registration_state *state = data;
1259         struct sip_outbound_registration *registration = ao2_bump(state->registration);
1260         size_t i;
1261
1262         /* Just in case the client state is being reused for this registration, free the auth information */
1263         ast_sip_auth_vector_destroy(&state->client_state->outbound_auths);
1264
1265         AST_VECTOR_INIT(&state->client_state->outbound_auths, AST_VECTOR_SIZE(&registration->outbound_auths));
1266         for (i = 0; i < AST_VECTOR_SIZE(&registration->outbound_auths); ++i) {
1267                 const char *name = ast_strdup(AST_VECTOR_GET(&registration->outbound_auths, i));
1268
1269                 if (name) {
1270                         AST_VECTOR_APPEND(&state->client_state->outbound_auths, name);
1271                 }
1272         }
1273         state->client_state->retry_interval = registration->retry_interval;
1274         state->client_state->forbidden_retry_interval = registration->forbidden_retry_interval;
1275         state->client_state->fatal_retry_interval = registration->fatal_retry_interval;
1276         state->client_state->max_retries = registration->max_retries;
1277         state->client_state->retries = 0;
1278         state->client_state->support_path = registration->support_path;
1279         state->client_state->auth_rejection_permanent = registration->auth_rejection_permanent;
1280
1281         pjsip_regc_update_expires(state->client_state->client, registration->expiration);
1282
1283         schedule_registration(state->client_state, (ast_random() % 10) + 1);
1284
1285         ao2_ref(registration, -1);
1286         ao2_ref(state, -1);
1287         return 0;
1288 }
1289
1290 /*! \brief Apply function which finds or allocates a state structure */
1291 static int sip_outbound_registration_apply(const struct ast_sorcery *sorcery, void *obj)
1292 {
1293         RAII_VAR(struct ao2_container *, states, ao2_global_obj_ref(current_states), ao2_cleanup);
1294         RAII_VAR(struct sip_outbound_registration_state *, state, NULL, ao2_cleanup);
1295         RAII_VAR(struct sip_outbound_registration_state *, new_state, NULL, ao2_cleanup);
1296         struct sip_outbound_registration *applied = obj;
1297
1298         if (!states) {
1299                 /* Global container has gone.  Likely shutting down. */
1300                 return -1;
1301         }
1302         state = ao2_find(states, ast_sorcery_object_get_id(applied), OBJ_SEARCH_KEY);
1303
1304         ast_debug(4, "Applying configuration to outbound registration '%s'\n", ast_sorcery_object_get_id(applied));
1305
1306         if (ast_strlen_zero(applied->server_uri)) {
1307                 ast_log(LOG_ERROR, "No server URI specified on outbound registration '%s'\n",
1308                         ast_sorcery_object_get_id(applied));
1309                 return -1;
1310         } else if (ast_sip_validate_uri_length(applied->server_uri)) {
1311                         ast_log(LOG_ERROR, "Server URI or hostname length exceeds pjpropject limit '%s'\n",
1312                                 ast_sorcery_object_get_id(applied));
1313                         return -1;
1314         } else if (ast_strlen_zero(applied->client_uri)) {
1315                 ast_log(LOG_ERROR, "No client URI specified on outbound registration '%s'\n",
1316                         ast_sorcery_object_get_id(applied));
1317                 return -1;
1318         } else if (ast_sip_validate_uri_length(applied->client_uri)) {
1319                         ast_log(LOG_ERROR, "Client URI or hostname length exceeds pjpropject limit '%s'\n",
1320                                 ast_sorcery_object_get_id(applied));
1321                         return -1;
1322         } else if (applied->line && ast_strlen_zero(applied->endpoint)) {
1323                 ast_log(LOG_ERROR, "Line support has been enabled on outbound registration '%s' without providing an endpoint\n",
1324                         ast_sorcery_object_get_id(applied));
1325                 return -1;
1326         } else if (!ast_strlen_zero(applied->endpoint) && !applied->line) {
1327                 ast_log(LOG_ERROR, "An endpoint has been specified on outbound registration '%s' without enabling line support\n",
1328                         ast_sorcery_object_get_id(applied));
1329                 return -1;
1330         }
1331
1332         if (state && can_reuse_registration(state->registration, applied)) {
1333                 ast_debug(4,
1334                         "No change between old configuration and new configuration on outbound registration '%s'. Using previous state\n",
1335                         ast_sorcery_object_get_id(applied));
1336
1337                 /*
1338                  * This is OK to replace without relinking the state in the
1339                  * current_states container since state->registration and
1340                  * applied have the same key.
1341                  */
1342                 ao2_lock(states);
1343                 ao2_replace(state->registration, applied);
1344                 ao2_unlock(states);
1345                 return 0;
1346         }
1347
1348         if (!(new_state = sip_outbound_registration_state_alloc(applied))) {
1349                 return -1;
1350         }
1351
1352         if (ast_sip_push_task_synchronous(new_state->client_state->serializer,
1353                 sip_outbound_registration_regc_alloc, new_state)) {
1354                 return -1;
1355         }
1356
1357         if (ast_sip_push_task(new_state->client_state->serializer,
1358                               sip_outbound_registration_perform, ao2_bump(new_state))) {
1359                 ast_log(LOG_ERROR, "Failed to perform outbound registration on '%s'\n",
1360                         ast_sorcery_object_get_id(new_state->registration));
1361                 ao2_ref(new_state, -1);
1362                 return -1;
1363         }
1364
1365         ao2_lock(states);
1366         if (state) {
1367                 ao2_unlink(states, state);
1368         }
1369         ao2_link(states, new_state);
1370         ao2_unlock(states);
1371
1372         return 0;
1373 }
1374
1375 static int outbound_auth_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
1376 {
1377         struct sip_outbound_registration *registration = obj;
1378
1379         return ast_sip_auth_vector_init(&registration->outbound_auths, var->value);
1380 }
1381
1382 static int outbound_auths_to_str(const void *obj, const intptr_t *args, char **buf)
1383 {
1384         const struct sip_outbound_registration *registration = obj;
1385
1386         return ast_sip_auths_to_str(&registration->outbound_auths, buf);
1387 }
1388
1389 static int outbound_auths_to_var_list(const void *obj, struct ast_variable **fields)
1390 {
1391         const struct sip_outbound_registration *registration = obj;
1392         int i;
1393         struct ast_variable *head = NULL;
1394
1395         for (i = 0; i < AST_VECTOR_SIZE(&registration->outbound_auths) ; i++) {
1396                 ast_variable_list_append(&head, ast_variable_new("outbound_auth",
1397                         AST_VECTOR_GET(&registration->outbound_auths, i), ""));
1398         }
1399
1400         if (head) {
1401                 *fields = head;
1402         }
1403
1404         return 0;
1405 }
1406
1407 static int unregister_task(void *obj)
1408 {
1409         struct sip_outbound_registration_state *state = obj;
1410         struct pjsip_regc *client = state->client_state->client;
1411         pjsip_tx_data *tdata;
1412         pjsip_regc_info info;
1413
1414         pjsip_regc_get_info(client, &info);
1415         ast_debug(1, "Unregistering contacts with server '%s' from client '%s'\n",
1416                 state->registration->server_uri, state->registration->client_uri);
1417
1418         cancel_registration(state->client_state);
1419
1420         if (pjsip_regc_unregister(client, &tdata) == PJ_SUCCESS) {
1421                 registration_client_send(state->client_state, tdata);
1422         }
1423
1424         ao2_ref(state, -1);
1425         return 0;
1426 }
1427
1428 static int queue_unregister(struct sip_outbound_registration_state *state)
1429 {
1430         ao2_ref(state, +1);
1431         if (ast_sip_push_task(state->client_state->serializer, unregister_task, state)) {
1432                 ao2_ref(state, -1);
1433                 return -1;
1434         }
1435
1436         return 0;
1437 }
1438
1439 static int queue_register(struct sip_outbound_registration_state *state)
1440 {
1441         ao2_ref(state, +1);
1442         if (ast_sip_push_task(state->client_state->serializer, sip_outbound_registration_perform, state)) {
1443                 ao2_ref(state, -1);
1444                 return -1;
1445         }
1446
1447         return 0;
1448 }
1449
1450 static char *cli_complete_registration(const char *line, const char *word,
1451                                        int pos, int state)
1452 {
1453         char *result = NULL;
1454         int wordlen;
1455         int which = 0;
1456         struct sip_outbound_registration *registration;
1457         struct ao2_container *registrations;
1458         struct ao2_iterator i;
1459
1460         if (pos != 3) {
1461                 return NULL;
1462         }
1463
1464         wordlen = strlen(word);
1465         registrations = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "registration",
1466                 AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
1467         if (!registrations) {
1468                 return NULL;
1469         }
1470
1471         i = ao2_iterator_init(registrations, 0);
1472         while ((registration = ao2_iterator_next(&i))) {
1473                 const char *name = ast_sorcery_object_get_id(registration);
1474
1475                 if (!strncasecmp(word, name, wordlen) && ++which > state) {
1476                         result = ast_strdup(name);
1477                 }
1478
1479                 ao2_ref(registration, -1);
1480                 if (result) {
1481                         break;
1482                 }
1483         }
1484         ao2_iterator_destroy(&i);
1485
1486         ao2_ref(registrations, -1);
1487         return result;
1488 }
1489
1490 static char *cli_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1491 {
1492         struct sip_outbound_registration_state *state;
1493         const char *registration_name;
1494
1495         switch (cmd) {
1496         case CLI_INIT:
1497                 e->command = "pjsip send unregister";
1498                 e->usage =
1499                         "Usage: pjsip send unregister <registration>\n"
1500                         "       Unregisters the specified outbound registration and stops future registration attempts.\n";
1501                 return NULL;
1502         case CLI_GENERATE:
1503                 return cli_complete_registration(a->line, a->word, a->pos, a->n);
1504         }
1505
1506         if (a->argc != 4) {
1507                 return CLI_SHOWUSAGE;
1508         }
1509
1510         registration_name = a->argv[3];
1511
1512         state = get_state(registration_name);
1513         if (!state) {
1514                 ast_cli(a->fd, "Unable to retrieve registration %s\n", registration_name);
1515                 return CLI_FAILURE;
1516         }
1517
1518         if (queue_unregister(state)) {
1519                 ast_cli(a->fd, "Failed to queue unregistration\n");
1520         }
1521
1522         ao2_ref(state, -1);
1523         return CLI_SUCCESS;
1524 }
1525
1526 static char *cli_register(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1527 {
1528         struct sip_outbound_registration_state *state;
1529         const char *registration_name;
1530
1531         switch (cmd) {
1532         case CLI_INIT:
1533                 e->command = "pjsip send register";
1534                 e->usage =
1535                         "Usage: pjsip send register <registration>\n"
1536                         "       Unregisters the specified outbound "
1537                         "registration then re-registers and re-schedules it.\n";
1538                 return NULL;
1539         case CLI_GENERATE:
1540                 return cli_complete_registration(a->line, a->word, a->pos, a->n);
1541         }
1542
1543         if (a->argc != 4) {
1544                 return CLI_SHOWUSAGE;
1545         }
1546
1547         registration_name = a->argv[3];
1548
1549         state = get_state(registration_name);
1550         if (!state) {
1551                 ast_cli(a->fd, "Unable to retrieve registration %s\n", registration_name);
1552                 return CLI_FAILURE;
1553         }
1554
1555         /* We need to serialize the unregister and register so they need
1556          * to be queued as separate tasks.
1557          */
1558         if (queue_unregister(state)) {
1559                 ast_cli(a->fd, "Failed to queue unregistration\n");
1560         } else if (queue_register(state)) {
1561                 ast_cli(a->fd, "Failed to queue registration\n");
1562         }
1563
1564         ao2_ref(state, -1);
1565         return CLI_SUCCESS;
1566 }
1567
1568 static int ami_unregister(struct mansession *s, const struct message *m)
1569 {
1570         const char *registration_name = astman_get_header(m, "Registration");
1571         struct sip_outbound_registration_state *state;
1572
1573         if (ast_strlen_zero(registration_name)) {
1574                 astman_send_error(s, m, "Registration parameter missing.");
1575                 return 0;
1576         }
1577
1578         state = get_state(registration_name);
1579         if (!state) {
1580                 astman_send_error(s, m, "Unable to retrieve registration entry\n");
1581                 return 0;
1582         }
1583
1584         if (queue_unregister(state)) {
1585                 astman_send_ack(s, m, "Failed to queue unregistration");
1586         } else {
1587                 astman_send_ack(s, m, "Unregistration sent");
1588         }
1589
1590         ao2_ref(state, -1);
1591         return 0;
1592 }
1593
1594 static int ami_register(struct mansession *s, const struct message *m)
1595 {
1596         const char *registration_name = astman_get_header(m, "Registration");
1597         struct sip_outbound_registration_state *state;
1598
1599         if (ast_strlen_zero(registration_name)) {
1600                 astman_send_error(s, m, "Registration parameter missing.");
1601                 return 0;
1602         }
1603
1604         state = get_state(registration_name);
1605         if (!state) {
1606                 astman_send_error(s, m, "Unable to retrieve registration entry\n");
1607                 return 0;
1608         }
1609
1610         /* We need to serialize the unregister and register so they need
1611          * to be queued as separate tasks.
1612          */
1613         if (queue_unregister(state)) {
1614                 astman_send_ack(s, m, "Failed to queue unregistration");
1615         } else if (queue_register(state)) {
1616                 astman_send_ack(s, m, "Failed to queue unregistration");
1617         } else {
1618                 astman_send_ack(s, m, "Reregistration sent");
1619         }
1620
1621         ao2_ref(state, -1);
1622         return 0;
1623 }
1624
1625 struct sip_ami_outbound {
1626         struct ast_sip_ami *ami;
1627         int registered;
1628         int not_registered;
1629         struct sip_outbound_registration *registration;
1630 };
1631
1632 static int ami_outbound_registration_task(void *obj)
1633 {
1634         struct sip_ami_outbound *ami = obj;
1635         struct ast_str *buf;
1636         struct sip_outbound_registration_state *state;
1637
1638         buf = ast_sip_create_ami_event("OutboundRegistrationDetail", ami->ami);
1639         if (!buf) {
1640                 return -1;
1641         }
1642
1643         ast_sip_sorcery_object_to_ami(ami->registration, &buf);
1644
1645         if ((state = get_state(ast_sorcery_object_get_id(ami->registration)))) {
1646                 pjsip_regc_info info;
1647
1648                 if (state->client_state->status == SIP_REGISTRATION_REGISTERED) {
1649                         ++ami->registered;
1650                 } else {
1651                         ++ami->not_registered;
1652                 }
1653
1654                 ast_str_append(&buf, 0, "Status: %s\r\n",
1655                         sip_outbound_registration_status_str(state->client_state->status));
1656
1657                 pjsip_regc_get_info(state->client_state->client, &info);
1658                 ast_str_append(&buf, 0, "NextReg: %d\r\n", info.next_reg);
1659                 ao2_ref(state, -1);
1660         }
1661
1662         astman_append(ami->ami->s, "%s\r\n", ast_str_buffer(buf));
1663         ast_free(buf);
1664
1665         return ast_sip_format_auths_ami(&ami->registration->outbound_auths, ami->ami);
1666 }
1667
1668 static int ami_outbound_registration_detail(void *obj, void *arg, int flags)
1669 {
1670         struct sip_ami_outbound *ami = arg;
1671
1672         ami->registration = obj;
1673         return ast_sip_push_task_synchronous(
1674                 NULL, ami_outbound_registration_task, ami);
1675 }
1676
1677 static int ami_show_outbound_registrations(struct mansession *s,
1678                                            const struct message *m)
1679 {
1680         struct ast_sip_ami ami = { .s = s, .m = m, .action_id = astman_get_header(m, "ActionID"), };
1681         struct sip_ami_outbound ami_outbound = { .ami = &ami };
1682         struct ao2_container *regs;
1683
1684         regs = get_registrations();
1685         if (!regs) {
1686                 astman_send_error(s, m, "Unable to retrieve "
1687                                   "outbound registrations\n");
1688                 return -1;
1689         }
1690
1691         astman_send_listack(s, m, "Following are Events for each Outbound registration",
1692                 "start");
1693
1694         ao2_callback(regs, OBJ_NODATA, ami_outbound_registration_detail, &ami_outbound);
1695
1696         astman_send_list_complete_start(s, m, "OutboundRegistrationDetailComplete",
1697                 ami_outbound.registered + ami_outbound.not_registered);
1698         astman_append(s,
1699                 "Registered: %d\r\n"
1700                 "NotRegistered: %d\r\n",
1701                 ami_outbound.registered,
1702                 ami_outbound.not_registered);
1703         astman_send_list_complete_end(s);
1704
1705         ao2_ref(regs, -1);
1706         return 0;
1707 }
1708
1709 static struct ao2_container *cli_get_container(const char *regex)
1710 {
1711         RAII_VAR(struct ao2_container *, container, NULL, ao2_cleanup);
1712         struct ao2_container *s_container;
1713
1714         container = ast_sorcery_retrieve_by_regex(ast_sip_get_sorcery(), "registration", regex);
1715         if (!container) {
1716                 return NULL;
1717         }
1718
1719         s_container = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0,
1720                 ast_sorcery_object_id_sort, ast_sorcery_object_id_compare);
1721         if (!s_container) {
1722                 return NULL;
1723         }
1724
1725         if (ao2_container_dup(s_container, container, 0)) {
1726                 ao2_ref(s_container, -1);
1727                 return NULL;
1728         }
1729
1730         return s_container;
1731 }
1732
1733 static int cli_iterator(void *container, ao2_callback_fn callback, void *args)
1734 {
1735         ao2_callback(container, OBJ_NODATA, callback, args);
1736
1737         return 0;
1738 }
1739
1740 static void *cli_retrieve_by_id(const char *id)
1741 {
1742         struct ao2_container *states;
1743         void *obj = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "registration", id);
1744
1745         if (!obj) {
1746                 /* if the object no longer exists then remove its state  */
1747                 states = ao2_global_obj_ref(current_states);
1748                 if (states) {
1749                         ao2_find(states, id, OBJ_SEARCH_KEY | OBJ_UNLINK | OBJ_NODATA);
1750                         ao2_ref(states, -1);
1751                 }
1752         }
1753
1754         return obj;
1755 }
1756
1757 static int cli_print_header(void *obj, void *arg, int flags)
1758 {
1759         struct ast_sip_cli_context *context = arg;
1760
1761         ast_assert(context->output_buffer != NULL);
1762
1763         ast_str_append(&context->output_buffer, 0,
1764                 " <Registration/ServerURI..............................>  <Auth..........>  <Status.......>\n");
1765
1766         return 0;
1767 }
1768
1769 static int cli_print_body(void *obj, void *arg, int flags)
1770 {
1771         struct sip_outbound_registration *registration = obj;
1772         struct ast_sip_cli_context *context = arg;
1773         const char *id = ast_sorcery_object_get_id(registration);
1774         struct sip_outbound_registration_state *state = get_state(id);
1775 #define REGISTRATION_URI_FIELD_LEN      53
1776
1777         ast_assert(context->output_buffer != NULL);
1778
1779         if (!state) {
1780                 return 0;
1781         }
1782
1783         ast_str_append(&context->output_buffer, 0, " %-s/%-*.*s  %-16s  %-16s\n",
1784                 id,
1785                 (int) (REGISTRATION_URI_FIELD_LEN - strlen(id)),
1786                 (int) (REGISTRATION_URI_FIELD_LEN - strlen(id)),
1787                 registration->server_uri,
1788                 AST_VECTOR_SIZE(&registration->outbound_auths)
1789                         ? AST_VECTOR_GET(&registration->outbound_auths, 0)
1790                         : "n/a",
1791                 sip_outbound_registration_status_str(state->client_state->status));
1792         ao2_ref(state, -1);
1793
1794         if (context->show_details
1795                 || (context->show_details_only_level_0 && context->indent_level == 0)) {
1796                 ast_str_append(&context->output_buffer, 0, "\n");
1797                 ast_sip_cli_print_sorcery_objectset(registration, context, 0);
1798         }
1799
1800         return 0;
1801 }
1802
1803 /*
1804  * A function pointer to callback needs to be within the
1805  * module in order to avoid problems with an undefined
1806  * symbol when the module is loaded.
1807  */
1808 static char *my_cli_traverse_objects(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1809 {
1810         return ast_sip_cli_traverse_objects(e, cmd, a);
1811 }
1812
1813 static struct ast_cli_entry cli_outbound_registration[] = {
1814         AST_CLI_DEFINE(cli_unregister, "Unregisters outbound registration target"),
1815         AST_CLI_DEFINE(cli_register, "Registers an outbound registration target"),
1816         AST_CLI_DEFINE(my_cli_traverse_objects, "List PJSIP Registrations",
1817                 .command = "pjsip list registrations",
1818                 .usage = "Usage: pjsip list registrations [ like <pattern> ]\n"
1819                                 "       List the configured PJSIP Registrations\n"
1820                                 "       Optional regular expression pattern is used to filter the list.\n"),
1821         AST_CLI_DEFINE(my_cli_traverse_objects, "Show PJSIP Registrations",
1822                 .command = "pjsip show registrations",
1823                 .usage = "Usage: pjsip show registrations [ like <pattern> ]\n"
1824                                 "       Show the configured PJSIP Registrations\n"
1825                                 "       Optional regular expression pattern is used to filter the list.\n"),
1826         AST_CLI_DEFINE(my_cli_traverse_objects, "Show PJSIP Registration",
1827                 .command = "pjsip show registration",
1828                 .usage = "Usage: pjsip show registration <id>\n"
1829                                  "       Show the configured PJSIP Registration\n"),
1830 };
1831
1832 static struct ast_sip_cli_formatter_entry *cli_formatter;
1833
1834 static void auth_observer(const char *type)
1835 {
1836         struct sip_outbound_registration *registration;
1837         struct sip_outbound_registration_state *state;
1838         struct ao2_container *regs;
1839         const char *registration_id;
1840         struct ao2_iterator i;
1841
1842         ast_debug(4, "Auths updated. Checking for any outbound registrations that are in permanent rejected state so they can be retried\n");
1843
1844         regs = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "registration",
1845                 AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
1846         if (!regs || ao2_container_count(regs) == 0) {
1847                 ao2_cleanup(regs);
1848                 return;
1849         }
1850
1851         i = ao2_iterator_init(regs, 0);
1852         for (; (registration = ao2_iterator_next(&i)); ao2_ref(registration, -1)) {
1853                 registration_id = ast_sorcery_object_get_id(registration);
1854                 state = get_state(registration_id);
1855                 if (state && state->client_state->status == SIP_REGISTRATION_REJECTED_PERMANENT) {
1856                         ast_debug(4, "Trying outbound registration '%s' again\n", registration_id);
1857
1858                         if (ast_sip_push_task(state->client_state->serializer,
1859                                               sip_outbound_registration_perform, ao2_bump(state))) {
1860                                 ast_log(LOG_ERROR, "Failed to perform outbound registration on '%s'\n", registration_id);
1861                                 ao2_ref(state, -1);
1862                         }
1863                 }
1864                 ao2_cleanup(state);
1865         }
1866         ao2_iterator_destroy(&i);
1867         ao2_cleanup(regs);
1868 }
1869
1870 static const struct ast_sorcery_observer observer_callbacks_auth = {
1871         .loaded = auth_observer,
1872 };
1873
1874 static int check_state(void *obj, void *arg, int flags)
1875 {
1876         struct sip_outbound_registration_state *state = obj;
1877         struct sip_outbound_registration *registration;
1878
1879         registration = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "registration",
1880                 ast_sorcery_object_get_id(state->registration));
1881         if (!registration) {
1882                 /* This is a dead registration */
1883                 return CMP_MATCH;
1884         }
1885
1886         ao2_ref(registration, -1);
1887         return 0;
1888 }
1889
1890 /*!
1891  * \internal
1892  * \brief Observer to purge dead registration states.
1893  *
1894  * \param name Module name owning the sorcery instance.
1895  * \param sorcery Instance being observed.
1896  * \param object_type Name of object being observed.
1897  * \param reloaded Non-zero if the object is being reloaded.
1898  *
1899  * \return Nothing
1900  */
1901 static void registration_loaded_observer(const char *name, const struct ast_sorcery *sorcery, const char *object_type, int reloaded)
1902 {
1903         struct ao2_container *states;
1904
1905         if (strcmp(object_type, "registration")) {
1906                 /* Not interested */
1907                 return;
1908         }
1909
1910         states = ao2_global_obj_ref(current_states);
1911         if (!states) {
1912                 /* Global container has gone.  Likely shutting down. */
1913                 return;
1914         }
1915
1916         /*
1917          * Refresh the current configured registrations. We don't need to hold
1918          * onto the objects, as the apply handler will cause their states to
1919          * be created appropriately.
1920          */
1921         ao2_cleanup(get_registrations());
1922
1923         /* Now to purge dead registrations. */
1924         ao2_callback(states, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, check_state, NULL);
1925         ao2_ref(states, -1);
1926 }
1927
1928 static const struct ast_sorcery_instance_observer observer_callbacks_registrations = {
1929         .object_type_loaded = registration_loaded_observer,
1930 };
1931
1932 static void registration_deleted_observer(const void *obj)
1933 {
1934         const struct sip_outbound_registration *registration = obj;
1935         struct ao2_container *states;
1936
1937         states = ao2_global_obj_ref(current_states);
1938         if (!states) {
1939                 /* Global container has gone.  Likely shutting down. */
1940                 return;
1941         }
1942
1943         ao2_find(states, ast_sorcery_object_get_id(registration), OBJ_UNLINK | OBJ_NODATA | OBJ_SEARCH_KEY);
1944
1945         ao2_ref(states, -1);
1946 }
1947
1948 static const struct ast_sorcery_observer registration_observer = {
1949         .deleted = registration_deleted_observer,
1950 };
1951
1952 static int unload_module(void)
1953 {
1954         int remaining;
1955
1956         ast_manager_unregister("PJSIPShowRegistrationsOutbound");
1957         ast_manager_unregister("PJSIPUnregister");
1958         ast_manager_unregister("PJSIPRegister");
1959
1960         ast_cli_unregister_multiple(cli_outbound_registration, ARRAY_LEN(cli_outbound_registration));
1961         ast_sip_unregister_cli_formatter(cli_formatter);
1962         cli_formatter = NULL;
1963
1964         ast_sip_unregister_endpoint_identifier(&line_identifier);
1965
1966         ast_sorcery_observer_remove(ast_sip_get_sorcery(), "auth", &observer_callbacks_auth);
1967         ast_sorcery_instance_observer_remove(ast_sip_get_sorcery(), &observer_callbacks_registrations);
1968
1969         ast_sorcery_object_unregister(ast_sip_get_sorcery(), "registration");
1970
1971         ao2_global_obj_release(current_states);
1972
1973         /* Wait for registration serializers to get destroyed. */
1974         ast_debug(2, "Waiting for registration transactions to complete for unload.\n");
1975         remaining = ast_serializer_shutdown_group_join(shutdown_group, MAX_UNLOAD_TIMEOUT_TIME);
1976         if (remaining) {
1977                 /*
1978                  * NOTE: We probably have a sip_outbound_registration_client_state
1979                  * ref leak if the remaining count cannot reach zero after a few
1980                  * minutes of trying to unload.
1981                  */
1982                 ast_log(LOG_WARNING, "Unload incomplete.  Could not stop %d outbound registrations.  Try again later.\n",
1983                         remaining);
1984                 return -1;
1985         }
1986
1987         ast_debug(2, "Successful shutdown.\n");
1988
1989         ao2_cleanup(shutdown_group);
1990         shutdown_group = NULL;
1991
1992         return 0;
1993 }
1994
1995 static int load_module(void)
1996 {
1997         struct ao2_container *new_states;
1998
1999         CHECK_PJSIP_MODULE_LOADED();
2000
2001         shutdown_group = ast_serializer_shutdown_group_alloc();
2002         if (!shutdown_group) {
2003                 return AST_MODULE_LOAD_FAILURE;
2004         }
2005
2006         /* Create outbound registration states container. */
2007         new_states = ao2_container_alloc(DEFAULT_STATE_BUCKETS,
2008                 registration_state_hash, registration_state_cmp);
2009         if (!new_states) {
2010                 ast_log(LOG_ERROR, "Unable to allocate registration states container\n");
2011                 unload_module();
2012                 return AST_MODULE_LOAD_FAILURE;
2013         }
2014         ao2_global_obj_replace_unref(current_states, new_states);
2015         ao2_ref(new_states, -1);
2016
2017         /*
2018          * Register sorcery object descriptions.
2019          */
2020         ast_sorcery_apply_config(ast_sip_get_sorcery(), "res_pjsip_outbound_registration");
2021         ast_sorcery_apply_default(ast_sip_get_sorcery(), "registration", "config", "pjsip.conf,criteria=type=registration");
2022
2023         if (ast_sorcery_object_register(ast_sip_get_sorcery(), "registration", sip_outbound_registration_alloc, NULL, sip_outbound_registration_apply)) {
2024                 unload_module();
2025                 return AST_MODULE_LOAD_DECLINE;
2026         }
2027
2028         ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "type", "", OPT_NOOP_T, 0, 0);
2029         ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "server_uri", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct sip_outbound_registration, server_uri));
2030         ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "client_uri", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct sip_outbound_registration, client_uri));
2031         ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "contact_user", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct sip_outbound_registration, contact_user));
2032         ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "transport", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct sip_outbound_registration, transport));
2033         ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "outbound_proxy", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct sip_outbound_registration, outbound_proxy));
2034         ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "expiration", "3600", OPT_UINT_T, 0, FLDSET(struct sip_outbound_registration, expiration));
2035         ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "retry_interval", "60", OPT_UINT_T, 0, FLDSET(struct sip_outbound_registration, retry_interval));
2036         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));
2037         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));
2038         ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "max_retries", "10", OPT_UINT_T, 0, FLDSET(struct sip_outbound_registration, max_retries));
2039         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));
2040         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);
2041         ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "support_path", "no", OPT_BOOL_T, 1, FLDSET(struct sip_outbound_registration, support_path));
2042         ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "line", "no", OPT_BOOL_T, 1, FLDSET(struct sip_outbound_registration, line));
2043         ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "endpoint", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct sip_outbound_registration, endpoint));
2044
2045         /*
2046          * Register sorcery observers.
2047          */
2048         if (ast_sorcery_instance_observer_add(ast_sip_get_sorcery(),
2049                 &observer_callbacks_registrations)
2050                 || ast_sorcery_observer_add(ast_sip_get_sorcery(), "auth",
2051                         &observer_callbacks_auth)
2052                 || ast_sorcery_observer_add(ast_sip_get_sorcery(), "registration",
2053                         &registration_observer)) {
2054                 ast_log(LOG_ERROR, "Unable to register observers.\n");
2055                 unload_module();
2056                 return AST_MODULE_LOAD_FAILURE;
2057         }
2058
2059         /* Register how this module identifies endpoints. */
2060         ast_sip_register_endpoint_identifier(&line_identifier);
2061
2062         /* Register CLI commands. */
2063         cli_formatter = ao2_alloc(sizeof(struct ast_sip_cli_formatter_entry), NULL);
2064         if (!cli_formatter) {
2065                 ast_log(LOG_ERROR, "Unable to allocate memory for cli formatter\n");
2066                 unload_module();
2067                 return AST_MODULE_LOAD_FAILURE;
2068         }
2069         cli_formatter->name = "registration";
2070         cli_formatter->print_header = cli_print_header;
2071         cli_formatter->print_body = cli_print_body;
2072         cli_formatter->get_container = cli_get_container;
2073         cli_formatter->iterate = cli_iterator;
2074         cli_formatter->get_id = ast_sorcery_object_get_id;
2075         cli_formatter->retrieve_by_id = cli_retrieve_by_id;
2076         ast_sip_register_cli_formatter(cli_formatter);
2077         ast_cli_register_multiple(cli_outbound_registration, ARRAY_LEN(cli_outbound_registration));
2078
2079         /* Register AMI actions. */
2080         ast_manager_register_xml("PJSIPUnregister", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, ami_unregister);
2081         ast_manager_register_xml("PJSIPRegister", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, ami_register);
2082         ast_manager_register_xml("PJSIPShowRegistrationsOutbound", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, ami_show_outbound_registrations);
2083
2084         /* Clear any previous statsd gauges in case we weren't shutdown cleanly */
2085         ast_statsd_log("PJSIP.registrations.count", AST_STATSD_GAUGE, 0);
2086         ast_statsd_log("PJSIP.registrations.state.Registered", AST_STATSD_GAUGE, 0);
2087         ast_statsd_log("PJSIP.registrations.state.Unregistered", AST_STATSD_GAUGE, 0);
2088         ast_statsd_log("PJSIP.registrations.state.Rejected", AST_STATSD_GAUGE, 0);
2089
2090         /* Load configuration objects */
2091         ast_sorcery_load_object(ast_sip_get_sorcery(), "registration");
2092
2093         return AST_MODULE_LOAD_SUCCESS;
2094 }
2095
2096 static int reload_module(void)
2097 {
2098         ast_sorcery_reload_object(ast_sip_get_sorcery(), "registration");
2099         return 0;
2100 }
2101
2102 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Outbound Registration Support",
2103         .support_level = AST_MODULE_SUPPORT_CORE,
2104         .load = load_module,
2105         .reload = reload_module,
2106         .unload = unload_module,
2107         .load_pri = AST_MODPRI_APP_DEPEND,
2108 );