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