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