res_pjsip: AMI commands and events.
[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/module.h"
32 #include "asterisk/taskprocessor.h"
33 #include "asterisk/cli.h"
34 #include "asterisk/stasis_system.h"
35 #include "res_pjsip/include/res_pjsip_private.h"
36
37 /*** DOCUMENTATION
38         <configInfo name="res_pjsip_outbound_registration" language="en_US">
39                 <synopsis>SIP resource for outbound registrations</synopsis>
40                 <description><para>
41                         <emphasis>Outbound Registration</emphasis>
42                         </para>
43                         <para>This module allows <literal>res_pjsip</literal> to register to other SIP servers.</para>
44                 </description>
45                 <configFile name="pjsip.conf">
46                         <configObject name="registration">
47                                 <synopsis>The configuration for outbound registration</synopsis>
48                                 <description><para>
49                                         Registration is <emphasis>COMPLETELY</emphasis> separate from the rest of
50                                         <literal>pjsip.conf</literal>. A minimal configuration consists of
51                                         setting a <literal>server_uri</literal> and a <literal>client_uri</literal>.
52                                 </para></description>
53                                 <configOption name="auth_rejection_permanent" default="yes">
54                                         <synopsis>Determines whether failed authentication challenges are treated
55                                         as permanent failures.</synopsis>
56                                         <description><para>If this option is enabled and an authentication challenge fails,
57                                         registration will not be attempted again until the configuration is reloaded.</para></description>
58                                 </configOption>
59                                 <configOption name="client_uri">
60                                         <synopsis>Client SIP URI used when attemping outbound registration</synopsis>
61                                         <description><para>
62                                                 This is the address-of-record for the outbound registration (i.e. the URI in
63                                                 the To header of the REGISTER).</para>
64                                                 <para>For registration with an ITSP, the client SIP URI may need to consist of
65                                                 an account name or number and the provider's hostname for their registrar, e.g.
66                                                 client_uri=1234567890@example.com. This may differ between providers.</para>
67                                                 <para>For registration to generic registrars, the client SIP URI will depend
68                                                 on networking specifics and configuration of the registrar.
69                                         </para></description>
70                                 </configOption>
71                                 <configOption name="contact_user">
72                                         <synopsis>Contact User to use in request</synopsis>
73                                 </configOption>
74                                 <configOption name="expiration" default="3600">
75                                         <synopsis>Expiration time for registrations in seconds</synopsis>
76                                 </configOption>
77                                 <configOption name="max_retries" default="10">
78                                         <synopsis>Maximum number of registration attempts.</synopsis>
79                                 </configOption>
80                                 <configOption name="outbound_auth" default="">
81                                         <synopsis>Authentication object to be used for outbound registrations.</synopsis>
82                                 </configOption>
83                                 <configOption name="outbound_proxy" default="">
84                                         <synopsis>Outbound Proxy used to send registrations</synopsis>
85                                 </configOption>
86                                 <configOption name="retry_interval" default="60">
87                                         <synopsis>Interval in seconds between retries if outbound registration is unsuccessful</synopsis>
88                                 </configOption>
89                                 <configOption name="forbidden_retry_interval" default="0">
90                                         <synopsis>Interval used when receiving a 403 Forbidden response.</synopsis>
91                                         <description><para>
92                                                 If a 403 Forbidden is received, chan_pjsip will wait
93                                                 <replaceable>forbidden_retry_interval</replaceable> seconds before
94                                                 attempting registration again. If 0 is specified, chan_pjsip will not
95                                                 retry after receiving a 403 Forbidden response. Setting this to a non-zero
96                                                 value goes against a "SHOULD NOT" in RFC3261, but can be used to work around
97                                                 buggy registrars.
98                                         </para></description>
99                                 </configOption>
100                                 <configOption name="server_uri">
101                                         <synopsis>SIP URI of the server to register against</synopsis>
102                                         <description><para>
103                                                 This is the URI at which to find the registrar to send the outbound REGISTER. This URI
104                                                 is used as the request URI of the outbound REGISTER request from Asterisk.</para>
105                                                 <para>For registration with an ITSP, the setting may often be just the domain of
106                                                 the registrar, e.g. sip:sip.example.com.
107                                         </para></description>
108                                 </configOption>
109                                 <configOption name="transport">
110                                         <synopsis>Transport used for outbound authentication</synopsis>
111                                         <description>
112                                                 <note><para>A <replaceable>transport</replaceable> configured in
113                                                 <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>
114                                         </description>
115                                 </configOption>
116                                 <configOption name="type">
117                                         <synopsis>Must be of type 'registration'.</synopsis>
118                                 </configOption>
119                         </configObject>
120                 </configFile>
121         </configInfo>
122         <manager name="PJSIPUnregister" language="en_US">
123                 <synopsis>
124                         Unregister an outbound registration.
125                 </synopsis>
126                 <syntax>
127                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
128                         <parameter name="Registration" required="true">
129                                 <para>The outbound registration to unregister.</para>
130                         </parameter>
131                 </syntax>
132         </manager>
133         <manager name="PJSIPShowRegistrationsOutbound" language="en_US">
134                 <synopsis>
135                         Lists PJSIP outbound registrations.
136                 </synopsis>
137                 <syntax />
138                 <description>
139                         <para>
140                         In response <literal>OutboundRegistrationDetail</literal> events showing configuration and status
141                         information are raised for each outbound registration object. <literal>AuthDetail</literal>
142                         events are raised for each associated auth object as well.  Once all events are completed an
143                         <literal>OutboundRegistrationDetailComplete</literal> is issued.
144                         </para>
145                 </description>
146         </manager>
147  ***/
148
149 /*! \brief Amount of buffer time (in seconds) before expiration that we re-register at */
150 #define REREGISTER_BUFFER_TIME 10
151
152 /*! \brief Various states that an outbound registration may be in */
153 enum sip_outbound_registration_status {
154         /*! \brief Currently unregistered */
155         SIP_REGISTRATION_UNREGISTERED = 0,
156         /*! \brief Registered, yay! */
157         SIP_REGISTRATION_REGISTERED,
158         /*! \brief Registration was rejected, but response was temporal */
159         SIP_REGISTRATION_REJECTED_TEMPORARY,
160         /*! \brief Registration was rejected, permanently */
161         SIP_REGISTRATION_REJECTED_PERMANENT,
162         /*! \brief Registration has been stopped */
163         SIP_REGISTRATION_STOPPED,
164 };
165
166 static const char *sip_outbound_registration_status_str[] = {
167         [SIP_REGISTRATION_UNREGISTERED] = "Unregistered",
168         [SIP_REGISTRATION_REGISTERED] = "Registered",
169         [SIP_REGISTRATION_REJECTED_TEMPORARY] = "Rejected",
170         [SIP_REGISTRATION_REJECTED_PERMANENT] = "Rejected",
171         [SIP_REGISTRATION_STOPPED] = "Stopped",
172 };
173
174 /*! \brief Outbound registration client state information (persists for lifetime of regc) */
175 struct sip_outbound_registration_client_state {
176         /*! \brief Current status of this registration */
177         enum sip_outbound_registration_status status;
178         /*! \brief Outbound registration client */
179         pjsip_regc *client;
180         /*! \brief Timer entry for retrying on temporal responses */
181         pj_timer_entry timer;
182         /*! \brief Current number of retries */
183         unsigned int retries;
184         /*! \brief Maximum number of retries permitted */
185         unsigned int max_retries;
186         /*! \brief Interval at which retries should occur for temporal responses */
187         unsigned int retry_interval;
188         /*! \brief Interval at which retries should occur for permanent responses */
189         unsigned int forbidden_retry_interval;
190         /*! \brief Treat authentication challenges that we cannot handle as permanent failures */
191         unsigned int auth_rejection_permanent;
192         /*! \brief Serializer for stuff and things */
193         struct ast_taskprocessor *serializer;
194         /*! \brief Configured authentication credentials */
195         struct ast_sip_auth_array outbound_auths;
196         /*! \brief Number of configured auths */
197         size_t num_outbound_auths;
198         /*! \brief Registration should be destroyed after completion of transaction */
199         unsigned int destroy:1;
200 };
201
202 /*! \brief Outbound registration state information (persists for lifetime that registration should exist) */
203 struct sip_outbound_registration_state {
204         /*! \brief Client state information */
205         struct sip_outbound_registration_client_state *client_state;
206 };
207
208 /*! \brief Outbound registration information */
209 struct sip_outbound_registration {
210         /*! \brief Sorcery object details */
211         SORCERY_OBJECT(details);
212         /*! \brief Stringfields */
213         AST_DECLARE_STRING_FIELDS(
214                 /*! \brief URI for the registrar */
215                 AST_STRING_FIELD(server_uri);
216                 /*! \brief URI for the AOR */
217                 AST_STRING_FIELD(client_uri);
218                 /*! \brief Optional user for contact header */
219                 AST_STRING_FIELD(contact_user);
220                 /*! \brief Explicit transport to use for registration */
221                 AST_STRING_FIELD(transport);
222                 /*! \brief Outbound proxy to use */
223                 AST_STRING_FIELD(outbound_proxy);
224         );
225         /*! \brief Requested expiration time */
226         unsigned int expiration;
227         /*! \brief Interval at which retries should occur for temporal responses */
228         unsigned int retry_interval;
229         /*! \brief Interval at which retries should occur for permanent responses */
230         unsigned int forbidden_retry_interval;
231         /*! \brief Treat authentication challenges that we cannot handle as permanent failures */
232         unsigned int auth_rejection_permanent;
233         /*! \brief Maximum number of retries permitted */
234         unsigned int max_retries;
235         /*! \brief Outbound registration state */
236         struct sip_outbound_registration_state *state;
237         /*! \brief Configured authentication credentials */
238         struct ast_sip_auth_array outbound_auths;
239         /*! \brief Number of configured auths */
240         size_t num_outbound_auths;
241 };
242
243 /*! \brief Helper function which cancels the timer on a client */
244 static void cancel_registration(struct sip_outbound_registration_client_state *client_state)
245 {
246         if (pj_timer_heap_cancel(pjsip_endpt_get_timer_heap(ast_sip_get_pjsip_endpoint()), &client_state->timer)) {
247                 /* The timer was successfully cancelled, drop the refcount of client_state */
248                 ao2_ref(client_state, -1);
249         }
250 }
251
252 /*! \brief Callback function for registering */
253 static int handle_client_registration(void *data)
254 {
255         RAII_VAR(struct sip_outbound_registration_client_state *, client_state, data, ao2_cleanup);
256         pjsip_tx_data *tdata;
257         pjsip_regc_info info;
258         char server_uri[PJSIP_MAX_URL_SIZE], client_uri[PJSIP_MAX_URL_SIZE];
259
260         cancel_registration(client_state);
261
262         if ((client_state->status == SIP_REGISTRATION_STOPPED) ||
263                 (pjsip_regc_register(client_state->client, PJ_FALSE, &tdata) != PJ_SUCCESS)) {
264                 return 0;
265         }
266
267         pjsip_regc_get_info(client_state->client, &info);
268         ast_copy_pj_str(server_uri, &info.server_uri, sizeof(server_uri));
269         ast_copy_pj_str(client_uri, &info.client_uri, sizeof(client_uri));
270         ast_debug(3, "REGISTER attempt %d to '%s' with client '%s'\n",
271                   client_state->retries + 1, server_uri, client_uri);
272
273         /* Due to the registration the callback may now get called, so bump the ref count */
274         ao2_ref(client_state, +1);
275         if (pjsip_regc_send(client_state->client, tdata) != PJ_SUCCESS) {
276                 ao2_ref(client_state, -1);
277         }
278
279         return 0;
280 }
281
282 /*! \brief Timer callback function, used just for registrations */
283 static void sip_outbound_registration_timer_cb(pj_timer_heap_t *timer_heap, struct pj_timer_entry *entry)
284 {
285         struct sip_outbound_registration_client_state *client_state = entry->user_data;
286
287         ao2_ref(client_state, +1);
288         if (ast_sip_push_task(client_state->serializer, handle_client_registration, client_state)) {
289                 ast_log(LOG_WARNING, "Failed to pass outbound registration to threadpool\n");
290                 ao2_ref(client_state, -1);
291         }
292
293         entry->id = 0;
294 }
295
296 /*! \brief Helper function which sets up the timer to re-register in a specific amount of time */
297 static void schedule_registration(struct sip_outbound_registration_client_state *client_state, unsigned int seconds)
298 {
299         pj_time_val delay = { .sec = seconds, };
300
301         cancel_registration(client_state);
302
303         ao2_ref(client_state, +1);
304         if (pjsip_endpt_schedule_timer(ast_sip_get_pjsip_endpoint(), &client_state->timer, &delay) != PJ_SUCCESS) {
305                 ast_log(LOG_WARNING, "Failed to pass timed registration to scheduler\n");
306                 ao2_ref(client_state, -1);
307         }
308 }
309
310 /*! \brief Callback function for unregistering (potentially) and destroying state */
311 static int handle_client_state_destruction(void *data)
312 {
313         RAII_VAR(struct sip_outbound_registration_client_state *, client_state, data, ao2_cleanup);
314         pjsip_regc_info info;
315
316         cancel_registration(client_state);
317
318         pjsip_regc_get_info(client_state->client, &info);
319
320         if (info.is_busy == PJ_TRUE) {
321                 /* If a client transaction is in progress we defer until it is complete */
322                 client_state->destroy = 1;
323                 return 0;
324         }
325
326         if (client_state->status != SIP_REGISTRATION_UNREGISTERED && client_state->status != SIP_REGISTRATION_REJECTED_PERMANENT) {
327                 pjsip_tx_data *tdata;
328
329                 if (pjsip_regc_unregister(client_state->client, &tdata) == PJ_SUCCESS) {
330                         pjsip_regc_send(client_state->client, tdata);
331                 }
332         }
333
334         pjsip_regc_destroy(client_state->client);
335
336         client_state->status = SIP_REGISTRATION_STOPPED;
337         ast_sip_auth_array_destroy(&client_state->outbound_auths);
338
339         return 0;
340 }
341
342 /*! \brief Structure for registration response */
343 struct registration_response {
344         /*! \brief Response code for the registration attempt */
345         int code;
346         /*! \brief Expiration time for registration */
347         int expiration;
348         /*! \brief Retry-After value */
349         int retry_after;
350         /*! \brief Outbound registration client state */
351         struct sip_outbound_registration_client_state *client_state;
352         /*! \brief The response message */
353         pjsip_rx_data *rdata;
354         /*! \brief The response transaction */
355         pjsip_transaction *tsx;
356 };
357
358 /*! \brief Registration response structure destructor */
359 static void registration_response_destroy(void *obj)
360 {
361         struct registration_response *response = obj;
362
363         if (response->rdata) {
364                 pjsip_rx_data_free_cloned(response->rdata);
365         }
366
367         ao2_cleanup(response->client_state);
368 }
369
370 /* \brief Helper funtion which determines if a response code is temporal or not */
371 static int sip_outbound_registration_is_temporal(unsigned int code,
372                 struct sip_outbound_registration_client_state *client_state)
373 {
374         /* Shamelessly taken from pjsua */
375         if (code == PJSIP_SC_REQUEST_TIMEOUT ||
376                 code == PJSIP_SC_INTERNAL_SERVER_ERROR ||
377                 code == PJSIP_SC_BAD_GATEWAY ||
378                 code == PJSIP_SC_SERVICE_UNAVAILABLE ||
379                 code == PJSIP_SC_SERVER_TIMEOUT ||
380                 ((code == PJSIP_SC_UNAUTHORIZED ||
381                   code == PJSIP_SC_PROXY_AUTHENTICATION_REQUIRED) &&
382                  !client_state->auth_rejection_permanent) ||
383                 PJSIP_IS_STATUS_IN_CLASS(code, 600)) {
384                 return 1;
385         } else {
386                 return 0;
387         }
388 }
389
390 static void schedule_retry(struct registration_response *response, unsigned int interval,
391                            const char *server_uri, const char *client_uri)
392 {
393         response->client_state->status = SIP_REGISTRATION_REJECTED_TEMPORARY;
394         schedule_registration(response->client_state, interval);
395
396         if (response->rdata) {
397                 ast_log(LOG_WARNING, "Temporal response '%d' received from '%s' on "
398                         "registration attempt to '%s', retrying in '%d'\n",
399                         response->code, server_uri, client_uri, interval);
400         } else {
401                 ast_log(LOG_WARNING, "No response received from '%s' on "
402                         "registration attempt to '%s', retrying in '%d'\n",
403                         server_uri, client_uri, interval);
404         }
405 }
406
407 /*! \brief Callback function for handling a response to a registration attempt */
408 static int handle_registration_response(void *data)
409 {
410         RAII_VAR(struct registration_response *, response, data, ao2_cleanup);
411         pjsip_regc_info info;
412         char server_uri[PJSIP_MAX_URL_SIZE], client_uri[PJSIP_MAX_URL_SIZE];
413
414         if (response->client_state->status == SIP_REGISTRATION_STOPPED) {
415                 return 0;
416         }
417
418         pjsip_regc_get_info(response->client_state->client, &info);
419         ast_copy_pj_str(server_uri, &info.server_uri, sizeof(server_uri));
420         ast_copy_pj_str(client_uri, &info.client_uri, sizeof(client_uri));
421
422         if (response->code == 401 || response->code == 407) {
423                 pjsip_tx_data *tdata;
424                 if (!ast_sip_create_request_with_auth(&response->client_state->outbound_auths,
425                                 response->rdata, response->tsx, &tdata)) {
426                         ao2_ref(response->client_state, +1);
427                         if (pjsip_regc_send(response->client_state->client, tdata) != PJ_SUCCESS) {
428                                 ao2_cleanup(response->client_state);
429                         }
430                         return 0;
431                 }
432                 /* Otherwise, fall through so the failure is processed appropriately */
433         }
434
435         if (PJSIP_IS_STATUS_IN_CLASS(response->code, 200)) {
436                 /* If the registration went fine simply reschedule registration for the future */
437                 ast_debug(1, "Outbound registration to '%s' with client '%s' successful\n", server_uri, client_uri);
438                 response->client_state->status = SIP_REGISTRATION_REGISTERED;
439                 response->client_state->retries = 0;
440                 schedule_registration(response->client_state, response->expiration - REREGISTER_BUFFER_TIME);
441         } else if (response->retry_after) {
442                 /* If we have been instructed to retry after a period of time, schedule it as such */
443                 schedule_retry(response, response->retry_after, server_uri, client_uri);
444         } else if (response->client_state->retry_interval && sip_outbound_registration_is_temporal(response->code, response->client_state)) {
445                 if (response->client_state->retries == response->client_state->max_retries) {
446                         /* If we received enough temporal responses to exceed our maximum give up permanently */
447                         response->client_state->status = SIP_REGISTRATION_REJECTED_PERMANENT;
448                         ast_log(LOG_WARNING, "Maximum retries reached when attempting outbound registration to '%s' with client '%s', stopping registration attempt\n",
449                                 server_uri, client_uri);
450                 } else {
451                         /* On the other hand if we can still try some more do so */
452                         response->client_state->retries++;
453                         schedule_retry(response, response->client_state->retry_interval, server_uri, client_uri);
454                 }
455         } else {
456                 if (response->code == 403
457                         && response->client_state->forbidden_retry_interval
458                         && response->client_state->retries < response->client_state->max_retries) {
459                         /* A forbidden response retry interval is configured and there are retries remaining */
460                         response->client_state->status = SIP_REGISTRATION_REJECTED_TEMPORARY;
461                         response->client_state->retries++;
462                         schedule_registration(response->client_state, response->client_state->forbidden_retry_interval);
463                         ast_log(LOG_WARNING, "403 Forbidden fatal response received from '%s' on registration attempt to '%s', retrying in '%d' seconds\n",
464                                 server_uri, client_uri, response->client_state->forbidden_retry_interval);
465                 } else {
466                         /* Finally if there's no hope of registering give up */
467                         response->client_state->status = SIP_REGISTRATION_REJECTED_PERMANENT;
468                         if (response->rdata) {
469                                 ast_log(LOG_WARNING, "Fatal response '%d' received from '%s' on registration attempt to '%s', stopping outbound registration\n",
470                                         response->code, server_uri, client_uri);
471                         } else {
472                                 ast_log(LOG_WARNING, "Fatal registration attempt to '%s', stopping outbound registration\n", client_uri);
473                         }
474                 }
475         }
476
477         ast_system_publish_registry("PJSIP", client_uri, server_uri, sip_outbound_registration_status_str[response->client_state->status], NULL);
478
479         /* If deferred destruction is in use see if we need to destroy now */
480         if (response->client_state->destroy) {
481                 handle_client_state_destruction(response->client_state);
482         }
483
484         return 0;
485 }
486
487 /*! \brief Callback function for outbound registration client */
488 static void sip_outbound_registration_response_cb(struct pjsip_regc_cbparam *param)
489 {
490         RAII_VAR(struct sip_outbound_registration_client_state *, client_state, param->token, ao2_cleanup);
491         struct registration_response *response = ao2_alloc(sizeof(*response), registration_response_destroy);
492
493         response->code = param->code;
494         response->expiration = param->expiration;
495         response->client_state = client_state;
496         ao2_ref(response->client_state, +1);
497
498         if (param->rdata) {
499                 struct pjsip_retry_after_hdr *retry_after = pjsip_msg_find_hdr(param->rdata->msg_info.msg, PJSIP_H_RETRY_AFTER, NULL);
500
501                 response->retry_after = retry_after ? retry_after->ivalue : 0;
502                 response->tsx = pjsip_rdata_get_tsx(param->rdata);
503                 pjsip_rx_data_clone(param->rdata, 0, &response->rdata);
504         }
505
506         if (ast_sip_push_task(client_state->serializer, handle_registration_response, response)) {
507                 ast_log(LOG_WARNING, "Failed to pass incoming registration response to threadpool\n");
508                 ao2_cleanup(response);
509         }
510 }
511
512 /*! \brief Destructor function for registration state */
513 static void sip_outbound_registration_state_destroy(void *obj)
514 {
515         struct sip_outbound_registration_state *state = obj;
516
517         if (!state->client_state) {
518                 return;
519         }
520
521         if (state->client_state->serializer && ast_sip_push_task(state->client_state->serializer, handle_client_state_destruction, state->client_state)) {
522                 ast_log(LOG_WARNING, "Failed to pass outbound registration client destruction to threadpool\n");
523                 ao2_ref(state->client_state, -1);
524         }
525 }
526
527 /*! \brief Destructor function for client registration state */
528 static void sip_outbound_registration_client_state_destroy(void *obj)
529 {
530         struct sip_outbound_registration_client_state *client_state = obj;
531
532         ast_taskprocessor_unreference(client_state->serializer);
533 }
534
535 /*! \brief Allocator function for registration state */
536 static struct sip_outbound_registration_state *sip_outbound_registration_state_alloc(void)
537 {
538         struct sip_outbound_registration_state *state = ao2_alloc(sizeof(*state), sip_outbound_registration_state_destroy);
539
540         if (!state || !(state->client_state = ao2_alloc(sizeof(*state->client_state), sip_outbound_registration_client_state_destroy))) {
541                 ao2_cleanup(state);
542                 return NULL;
543         }
544
545         if ((pjsip_regc_create(ast_sip_get_pjsip_endpoint(), state->client_state, sip_outbound_registration_response_cb, &state->client_state->client) != PJ_SUCCESS) ||
546                 !(state->client_state->serializer = ast_sip_create_serializer())) {
547                 /* This is on purpose, normal operation will have it be deallocated within the serializer */
548                 pjsip_regc_destroy(state->client_state->client);
549                 ao2_cleanup(state->client_state);
550                 ao2_cleanup(state);
551                 return NULL;
552         }
553
554         state->client_state->status = SIP_REGISTRATION_UNREGISTERED;
555         state->client_state->timer.user_data = state->client_state;
556         state->client_state->timer.cb = sip_outbound_registration_timer_cb;
557
558         return state;
559 }
560
561 /*! \brief Destructor function for registration information */
562 static void sip_outbound_registration_destroy(void *obj)
563 {
564         struct sip_outbound_registration *registration = obj;
565
566         ao2_cleanup(registration->state);
567         ast_sip_auth_array_destroy(&registration->outbound_auths);
568
569         ast_string_field_free_memory(registration);
570 }
571
572 /*! \brief Allocator function for registration information */
573 static void *sip_outbound_registration_alloc(const char *name)
574 {
575         struct sip_outbound_registration *registration = ast_sorcery_generic_alloc(sizeof(*registration), sip_outbound_registration_destroy);
576
577         if (!registration || ast_string_field_init(registration, 256)) {
578                 ao2_cleanup(registration);
579                 return NULL;
580         }
581
582         return registration;
583 }
584
585 /*! \brief Helper function which populates a pj_str_t with a contact header */
586 static int sip_dialog_create_contact(pj_pool_t *pool, pj_str_t *contact, const char *user, const pj_str_t *target, pjsip_tpselector *selector)
587 {
588         pj_str_t tmp, local_addr;
589         pjsip_uri *uri;
590         pjsip_sip_uri *sip_uri;
591         pjsip_transport_type_e type = PJSIP_TRANSPORT_UNSPECIFIED;
592         int local_port;
593
594         pj_strdup_with_null(pool, &tmp, target);
595
596         if (!(uri = pjsip_parse_uri(pool, tmp.ptr, tmp.slen, 0)) ||
597             (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri))) {
598                 return -1;
599         }
600
601         sip_uri = pjsip_uri_get_uri(uri);
602
603         if (PJSIP_URI_SCHEME_IS_SIPS(sip_uri)) {
604                 type = PJSIP_TRANSPORT_TLS;
605         } else if (!sip_uri->transport_param.slen) {
606                 type = PJSIP_TRANSPORT_UDP;
607         } else {
608                 type = pjsip_transport_get_type_from_name(&sip_uri->transport_param);
609         }
610
611         if (type == PJSIP_TRANSPORT_UNSPECIFIED) {
612                 return -1;
613         }
614
615         if (pj_strchr(&sip_uri->host, ':')) {
616                 type = (pjsip_transport_type_e)(((int)type) + PJSIP_TRANSPORT_IPV6);
617         }
618
619         if (pjsip_tpmgr_find_local_addr(pjsip_endpt_get_tpmgr(ast_sip_get_pjsip_endpoint()), pool, type, selector,
620                                                               &local_addr, &local_port) != PJ_SUCCESS) {
621                 return -1;
622         }
623
624         if (!pj_strchr(&sip_uri->host, ':') && pj_strchr(&local_addr, ':')) {
625                 type = (pjsip_transport_type_e)(((int)type) + PJSIP_TRANSPORT_IPV6);
626         }
627
628         contact->ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
629         contact->slen = pj_ansi_snprintf(contact->ptr, PJSIP_MAX_URL_SIZE,
630                                       "<%s:%s@%s%.*s%s:%d%s%s>",
631                                       (pjsip_transport_get_flag_from_type(type) & PJSIP_TRANSPORT_SECURE) ? "sips" : "sip",
632                                       user,
633                                       (type & PJSIP_TRANSPORT_IPV6) ? "[" : "",
634                                       (int)local_addr.slen,
635                                       local_addr.ptr,
636                                       (type & PJSIP_TRANSPORT_IPV6) ? "]" : "",
637                                       local_port,
638                                       (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? ";transport=" : "",
639                                       (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? pjsip_transport_get_type_name(type) : "");
640
641         return 0;
642 }
643
644 /*!
645  * \internal
646  * \brief Check if a registration can be reused
647  *
648  * This checks if the existing outbound registration's configuration differs from a newly-applied
649  * outbound registration to see if the applied one.
650  *
651  * \param existing The pre-existing outbound registration
652  * \param applied The newly-created registration
653  */
654 static int can_reuse_registration(struct sip_outbound_registration *existing, struct sip_outbound_registration *applied)
655 {
656         int i;
657
658         if (strcmp(existing->server_uri, applied->server_uri) || strcmp(existing->client_uri, applied->client_uri) ||
659                 strcmp(existing->transport, applied->transport) || strcmp(existing->contact_user, applied->contact_user) ||
660                 strcmp(existing->outbound_proxy, applied->outbound_proxy) || existing->num_outbound_auths != applied->num_outbound_auths ||
661                 existing->auth_rejection_permanent != applied->auth_rejection_permanent) {
662                 return 0;
663         }
664
665         for (i = 0; i < existing->num_outbound_auths; ++i) {
666                 if (strcmp(existing->outbound_auths.names[i], applied->outbound_auths.names[i])) {
667                         return 0;
668                 }
669         }
670
671         return 1;
672 }
673
674 /*! \brief Helper function that allocates a pjsip registration client and configures it */
675 static int sip_outbound_registration_regc_alloc(void *data)
676 {
677         struct sip_outbound_registration *registration = data;
678         pj_str_t server_uri, client_uri, contact_uri;
679         pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
680
681         if (!ast_strlen_zero(registration->transport)) {
682                 RAII_VAR(struct ast_sip_transport *, transport, ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport", registration->transport), ao2_cleanup);
683
684                 if (!transport || !transport->state) {
685                         ast_log(LOG_ERROR, "Unable to retrieve PJSIP transport '%s' "
686                                 " for outbound registration", registration->transport);
687                         return -1;
688                 }
689
690                 if (transport->state->transport) {
691                         selector.type = PJSIP_TPSELECTOR_TRANSPORT;
692                         selector.u.transport = transport->state->transport;
693                 } else if (transport->state->factory) {
694                         selector.type = PJSIP_TPSELECTOR_LISTENER;
695                         selector.u.listener = transport->state->factory;
696                 } else {
697                         return -1;
698                 }
699         }
700
701         pjsip_regc_set_transport(registration->state->client_state->client, &selector);
702
703         if (!ast_strlen_zero(registration->outbound_proxy)) {
704                 pjsip_route_hdr route_set, *route;
705                 static const pj_str_t ROUTE_HNAME = { "Route", 5 };
706                 pj_str_t tmp;
707
708                 pj_list_init(&route_set);
709
710                 pj_strdup2_with_null(pjsip_regc_get_pool(registration->state->client_state->client), &tmp, registration->outbound_proxy);
711                 if (!(route = pjsip_parse_hdr(pjsip_regc_get_pool(registration->state->client_state->client), &ROUTE_HNAME, tmp.ptr, tmp.slen, NULL))) {
712                         return -1;
713                 }
714                 pj_list_push_back(&route_set, route);
715
716                 pjsip_regc_set_route_set(registration->state->client_state->client, &route_set);
717         }
718
719         pj_cstr(&server_uri, registration->server_uri);
720
721         if (sip_dialog_create_contact(pjsip_regc_get_pool(registration->state->client_state->client), &contact_uri, S_OR(registration->contact_user, "s"), &server_uri, &selector)) {
722                 return -1;
723         }
724
725         pj_cstr(&client_uri, registration->client_uri);
726
727         if (pjsip_regc_init(registration->state->client_state->client, &server_uri, &client_uri, &client_uri, 1, &contact_uri, registration->expiration) != PJ_SUCCESS) {
728                 return -1;
729         }
730
731         return 0;
732 }
733
734 /*! \brief Apply function which finds or allocates a state structure */
735 static int sip_outbound_registration_apply(const struct ast_sorcery *sorcery, void *obj)
736 {
737         RAII_VAR(struct sip_outbound_registration *, existing, ast_sorcery_retrieve_by_id(sorcery, "registration", ast_sorcery_object_get_id(obj)), ao2_cleanup);
738         struct sip_outbound_registration *applied = obj;
739
740         if (!existing) {
741                 /* If no existing registration exists we can just start fresh easily */
742                 applied->state = sip_outbound_registration_state_alloc();
743         } else {
744                 /* If there is an existing registration things are more complicated, we can immediately reuse this state if most stuff remains unchanged */
745                 if (can_reuse_registration(existing, applied)) {
746                         applied->state = existing->state;
747                         ao2_ref(applied->state, +1);
748                         return 0;
749                 }
750                 applied->state = sip_outbound_registration_state_alloc();
751         }
752
753         if (!applied->state) {
754                 return -1;
755         }
756
757         return ast_sip_push_task_synchronous(NULL, sip_outbound_registration_regc_alloc, applied);
758 }
759
760 /*! \brief Helper function which performs a single registration */
761 static int sip_outbound_registration_perform(void *data)
762 {
763         RAII_VAR(struct sip_outbound_registration *, registration, data, ao2_cleanup);
764         size_t i;
765
766         /* Just in case the client state is being reused for this registration, free the auth information */
767         ast_sip_auth_array_destroy(&registration->state->client_state->outbound_auths);
768
769         registration->state->client_state->outbound_auths.names = ast_calloc(registration->outbound_auths.num, sizeof(char *));
770         for (i = 0; i < registration->outbound_auths.num; ++i) {
771                 registration->state->client_state->outbound_auths.names[i] = ast_strdup(registration->outbound_auths.names[i]);
772         }
773         registration->state->client_state->outbound_auths.num = registration->outbound_auths.num;
774         registration->state->client_state->retry_interval = registration->retry_interval;
775         registration->state->client_state->forbidden_retry_interval = registration->forbidden_retry_interval;
776         registration->state->client_state->max_retries = registration->max_retries;
777         registration->state->client_state->retries = 0;
778
779         pjsip_regc_update_expires(registration->state->client_state->client, registration->expiration);
780
781         schedule_registration(registration->state->client_state, (ast_random() % 10) + 1);
782
783         return 0;
784 }
785
786 /*! \brief Helper function which performs all registrations */
787 static void sip_outbound_registration_perform_all(void)
788 {
789         RAII_VAR(struct ao2_container *, registrations, ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "registration", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL), ao2_cleanup);
790         struct ao2_iterator i;
791         struct sip_outbound_registration *registration;
792
793         if (!registrations) {
794                 return;
795         }
796
797         i = ao2_iterator_init(registrations, 0);
798         while ((registration = ao2_iterator_next(&i))) {
799                 if (ast_sip_push_task(registration->state->client_state->serializer, sip_outbound_registration_perform, registration)) {
800                         ast_log(LOG_ERROR, "Failed to perform outbound registration on '%s'\n", ast_sorcery_object_get_id(registration));
801                         ao2_ref(registration, -1);
802                 }
803         }
804         ao2_iterator_destroy(&i);
805 }
806
807 static int outbound_auth_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
808 {
809         struct sip_outbound_registration *registration = obj;
810
811         return ast_sip_auth_array_init(&registration->outbound_auths, var->value);
812 }
813
814 static int outbound_auths_to_str(const void *obj, const intptr_t *args, char **buf)
815 {
816         const struct sip_outbound_registration *registration = obj;
817         return ast_sip_auths_to_str(&registration->outbound_auths, buf);
818 }
819
820 static struct sip_outbound_registration *retrieve_registration(const char *registration_name)
821 {
822         return ast_sorcery_retrieve_by_id(
823                 ast_sip_get_sorcery(),
824                 "registration",
825                 registration_name);
826 }
827
828 static int unregister_task(void *obj)
829 {
830         RAII_VAR(struct sip_outbound_registration*, registration, obj, ao2_cleanup);
831         struct pjsip_regc *client = registration->state->client_state->client;
832         pjsip_tx_data *tdata;
833
834         if (pjsip_regc_unregister(client, &tdata) != PJ_SUCCESS) {
835                 return 0;
836         }
837
838         ao2_ref(registration->state->client_state, +1);
839         if (pjsip_regc_send(client, tdata) != PJ_SUCCESS) {
840                 ao2_cleanup(registration->state->client_state);
841         }
842
843         return 0;
844 }
845
846 static int queue_unregister(struct sip_outbound_registration *registration)
847 {
848         ao2_ref(registration, +1);
849         if (ast_sip_push_task(registration->state->client_state->serializer, unregister_task, registration)) {
850                 ao2_cleanup(registration);
851                 return -1;
852         }
853         return 0;
854 }
855
856 static char *cli_complete_registration(const char *line, const char *word,
857 int pos, int state)
858 {
859         char *result = NULL;
860         int wordlen;
861         int which = 0;
862         struct sip_outbound_registration *registration;
863         RAII_VAR(struct ao2_container *, registrations, NULL, ao2_cleanup);
864         struct ao2_iterator i;
865
866         if (pos != 3) {
867                 return NULL;
868         }
869
870         wordlen = strlen(word);
871         registrations = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "registration",
872                 AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
873         if (!registrations) {
874                 return NULL;
875         }
876
877         i = ao2_iterator_init(registrations, 0);
878         while ((registration = ao2_iterator_next(&i))) {
879                 const char *name = ast_sorcery_object_get_id(registration);
880                 if (!strncasecmp(word, name, wordlen) && ++which > state) {
881                         result = ast_strdup(name);
882                 }
883
884                 ao2_cleanup(registration);
885                 if (result) {
886                         break;
887                 }
888         }
889         ao2_iterator_destroy(&i);
890         return result;
891 }
892
893 static char *cli_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
894 {
895         RAII_VAR(struct sip_outbound_registration *, registration, NULL, ao2_cleanup);
896         const char *registration_name;
897
898         switch (cmd) {
899         case CLI_INIT:
900                 e->command = "pjsip send unregister";
901                 e->usage =
902                         "Usage: pjsip send unregister <registration>\n"
903                         "       Send a SIP REGISTER request to the specified outbound "
904                         "registration with an expiration of 0. This will cause the contact "
905                         "added by this registration to be removed on the remote system.\n";
906                 return NULL;
907         case CLI_GENERATE:
908                 return cli_complete_registration(a->line, a->word, a->pos, a->n);
909         }
910
911         if (a->argc != 4) {
912                 return CLI_SHOWUSAGE;
913         }
914
915         registration_name = a->argv[3];
916
917         registration = retrieve_registration(registration_name);
918         if (!registration) {
919                 ast_cli(a->fd, "Unable to retrieve registration %s\n", registration_name);
920                 return CLI_FAILURE;
921         }
922
923         if (queue_unregister(registration)) {
924                 ast_cli(a->fd, "Failed to queue unregistration");
925                 return 0;
926         }
927
928         return CLI_SUCCESS;
929 }
930
931 static int ami_unregister(struct mansession *s, const struct message *m)
932 {
933         const char *registration_name = astman_get_header(m, "Registration");
934         RAII_VAR(struct sip_outbound_registration *, registration, NULL, ao2_cleanup);
935
936         if (ast_strlen_zero(registration_name)) {
937                 astman_send_error(s, m, "Registration parameter missing.");
938                 return 0;
939         }
940
941         registration = retrieve_registration(registration_name);
942         if (!registration) {
943                 astman_send_error(s, m, "Unable to retrieve registration entry\n");
944                 return 0;
945         }
946
947
948         if (queue_unregister(registration)) {
949                 astman_send_ack(s, m, "Failed to queue unregistration");
950                 return 0;
951         }
952
953         astman_send_ack(s, m, "Unregistration sent");
954         return 0;
955 }
956
957 static struct ast_cli_entry cli_outbound_registration[] = {
958         AST_CLI_DEFINE(cli_unregister, "Send a REGISTER request to an outbound registration target with a expiration of 0")
959 };
960
961 struct sip_ami_outbound {
962         struct ast_sip_ami *ami;
963         int registered;
964         int not_registered;
965         struct sip_outbound_registration *registration;
966 };
967
968 static int ami_outbound_registration_task(void *obj)
969 {
970         struct sip_ami_outbound *ami = obj;
971         RAII_VAR(struct ast_str *, buf,
972                  ast_sip_create_ami_event("OutboundRegistrationDetail", ami->ami), ast_free);
973
974         if (!buf) {
975                 return -1;
976         }
977
978         ast_sip_sorcery_object_to_ami(ami->registration, &buf);
979
980         if (ami->registration->state) {
981                 pjsip_regc_info info;
982                 if (ami->registration->state->client_state->status ==
983                     SIP_REGISTRATION_REGISTERED) {
984                         ++ami->registered;
985                 } else {
986                         ++ami->not_registered;
987                 }
988
989                 ast_str_append(&buf, 0, "Status: %s%s",
990                                sip_outbound_registration_status_str[
991                                        ami->registration->state->client_state->status], "\r\n");
992
993                 pjsip_regc_get_info(ami->registration->state->client_state->client, &info);
994                 ast_str_append(&buf, 0, "NextReg: %d%s", info.next_reg, "\r\n");
995         }
996
997         astman_append(ami->ami->s, "%s\r\n", ast_str_buffer(buf));
998         return ast_sip_format_auths_ami(&ami->registration->outbound_auths, ami->ami);
999 }
1000
1001 static int ami_outbound_registration_detail(void *obj, void *arg, int flags)
1002 {
1003         struct sip_ami_outbound *ami = arg;
1004
1005         ami->registration = obj;
1006         return ast_sip_push_task_synchronous(
1007                 NULL, ami_outbound_registration_task, ami);
1008 }
1009
1010 static int ami_show_outbound_registrations(struct mansession *s,
1011                                            const struct message *m)
1012 {
1013         struct ast_sip_ami ami = { s = s, m = m };
1014         struct sip_ami_outbound ami_outbound = { .ami = &ami };
1015         RAII_VAR(struct ao2_container *, regs, ast_sorcery_retrieve_by_fields(
1016                          ast_sip_get_sorcery(), "registration", AST_RETRIEVE_FLAG_MULTIPLE |
1017                          AST_RETRIEVE_FLAG_ALL, NULL), ao2_cleanup);
1018
1019         if (!regs) {
1020                 astman_send_error(s, m, "Unable to retreive "
1021                                   "outbound registrations\n");
1022                 return -1;
1023         }
1024
1025         astman_send_listack(s, m, "Following are Events for each Outbound "
1026                             "registration", "start");
1027
1028         ao2_callback(regs, OBJ_NODATA, ami_outbound_registration_detail, &ami_outbound);
1029
1030         astman_append(s,
1031                       "Event: OutboundRegistrationDetailComplete\r\n"
1032                       "EventList: Complete\r\n"
1033                       "Registered: %d\r\n"
1034                       "NotRegistered: %d\r\n\r\n",
1035                       ami_outbound.registered,
1036                       ami_outbound.not_registered);
1037         return 0;
1038 }
1039
1040 static int load_module(void)
1041 {
1042         ast_sorcery_apply_default(ast_sip_get_sorcery(), "registration", "config", "pjsip.conf,criteria=type=registration");
1043
1044         if (ast_sorcery_object_register(ast_sip_get_sorcery(), "registration", sip_outbound_registration_alloc, NULL, sip_outbound_registration_apply)) {
1045                 return AST_MODULE_LOAD_DECLINE;
1046         }
1047
1048         ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "type", "", OPT_NOOP_T, 0, 0);
1049         ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "server_uri", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct sip_outbound_registration, server_uri));
1050         ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "client_uri", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct sip_outbound_registration, client_uri));
1051         ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "contact_user", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct sip_outbound_registration, contact_user));
1052         ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "transport", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct sip_outbound_registration, transport));
1053         ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "outbound_proxy", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct sip_outbound_registration, outbound_proxy));
1054         ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "expiration", "3600", OPT_UINT_T, 0, FLDSET(struct sip_outbound_registration, expiration));
1055         ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "retry_interval", "60", OPT_UINT_T, 0, FLDSET(struct sip_outbound_registration, retry_interval));
1056         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));
1057         ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "max_retries", "10", OPT_UINT_T, 0, FLDSET(struct sip_outbound_registration, max_retries));
1058         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));
1059         ast_sorcery_object_field_register_custom(ast_sip_get_sorcery(), "registration", "outbound_auth", "", outbound_auth_handler, outbound_auths_to_str, 0, 0);
1060         ast_sorcery_reload_object(ast_sip_get_sorcery(), "registration");
1061         sip_outbound_registration_perform_all();
1062
1063         ast_cli_register_multiple(cli_outbound_registration, ARRAY_LEN(cli_outbound_registration));
1064         ast_manager_register_xml("PJSIPUnregister", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, ami_unregister);
1065         ast_manager_register_xml("PJSIPShowRegistrationsOutbound", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING,ami_show_outbound_registrations);
1066         return AST_MODULE_LOAD_SUCCESS;
1067 }
1068
1069 static int reload_module(void)
1070 {
1071         ast_sorcery_reload_object(ast_sip_get_sorcery(), "registration");
1072         sip_outbound_registration_perform_all();
1073         return 0;
1074 }
1075
1076 static int unload_module(void)
1077 {
1078         ast_cli_unregister_multiple(cli_outbound_registration, ARRAY_LEN(cli_outbound_registration));
1079         ast_manager_unregister("PJSIPShowRegistrationsOutbound");
1080         ast_manager_unregister("PJSIPUnregister");
1081         return 0;
1082 }
1083
1084 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Outbound Registration Support",
1085                 .load = load_module,
1086                 .reload = reload_module,
1087                 .unload = unload_module,
1088                 .load_pri = AST_MODPRI_APP_DEPEND,
1089                );