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