Asterisk - The Open Source Telephony Project GIT-master-20e40a9
Loading...
Searching...
No Matches
res_pjsip.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2013, Digium, Inc.
5 *
6 * Mark Michelson <mmichelson@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#include "asterisk.h"
20
21#include <pjsip.h>
22/* Needed for SUBSCRIBE, NOTIFY, and PUBLISH method definitions */
23#include <pjsip_simple.h>
24#include <pjsip/sip_transaction.h>
25#include <pj/timer.h>
26#include <pjlib.h>
27#include <pjmedia/errno.h>
28
29#include "asterisk/res_pjsip.h"
30#include "asterisk/strings.h"
31#include "pjsip/sip_parser.h"
34#include "asterisk/logger.h"
35#include "asterisk/lock.h"
36#include "asterisk/utils.h"
37#include "asterisk/astobj2.h"
38#include "asterisk/module.h"
39#include "asterisk/serializer.h"
40#include "asterisk/threadpool.h"
42#include "asterisk/uuid.h"
43#include "asterisk/sorcery.h"
44#include "asterisk/file.h"
45#include "asterisk/causes.h"
46#include "asterisk/cli.h"
47#include "asterisk/callerid.h"
49#include "asterisk/test.h"
52#include "asterisk/utf8.h"
53#include "asterisk/acl.h"
54
55/*** MODULEINFO
56 <depend>pjproject</depend>
57 <depend>res_pjproject</depend>
58 <depend>res_sorcery_config</depend>
59 <depend>res_sorcery_memory</depend>
60 <depend>res_sorcery_astdb</depend>
61 <use type="module">res_statsd</use>
62 <use type="module">res_geolocation</use>
63 <support_level>core</support_level>
64 ***/
65
66#define MOD_DATA_CONTACT "contact"
67
68/*! Number of serializers in pool if one not supplied. */
69#define SERIALIZER_POOL_SIZE 8
70
71/*! Pool of serializers to use if not supplied. */
73
74static pjsip_endpoint *ast_pjsip_endpoint;
75
77
78/*! Local host address for IPv4 */
79static pj_sockaddr host_ip_ipv4;
80
81/*! Local host address for IPv4 (string form) */
82static char host_ip_ipv4_string[PJ_INET6_ADDRSTRLEN];
83
84/*! Local host address for IPv6 */
85static pj_sockaddr host_ip_ipv6;
86
87/*! Local host address for IPv6 (string form) */
88static char host_ip_ipv6_string[PJ_INET6_ADDRSTRLEN];
89
90void ast_sip_add_date_header(pjsip_tx_data *tdata)
91{
92 char date[256];
93 struct tm tm;
94 time_t t = time(NULL);
95
96 gmtime_r(&t, &tm);
97 strftime(date, sizeof(date), "%a, %d %b %Y %T GMT", &tm);
98
99 ast_sip_add_header(tdata, "Date", date);
100}
101
102static int register_service(void *data)
103{
104 pjsip_module **module = data;
105 if (!ast_pjsip_endpoint) {
106 ast_log(LOG_ERROR, "There is no PJSIP endpoint. Unable to register services\n");
107 return -1;
108 }
109 if (pjsip_endpt_register_module(ast_pjsip_endpoint, *module) != PJ_SUCCESS) {
110 ast_log(LOG_ERROR, "Unable to register module %.*s\n", (int) pj_strlen(&(*module)->name), pj_strbuf(&(*module)->name));
111 return -1;
112 }
113 ast_debug(1, "Registered SIP service %.*s (%p)\n", (int) pj_strlen(&(*module)->name), pj_strbuf(&(*module)->name), *module);
114 return 0;
115}
116
117int ast_sip_register_service(pjsip_module *module)
118{
120}
121
122static int unregister_service(void *data)
123{
124 pjsip_module **module = data;
125 if (!ast_pjsip_endpoint) {
126 return -1;
127 }
128 pjsip_endpt_unregister_module(ast_pjsip_endpoint, *module);
129 ast_debug(1, "Unregistered SIP service %.*s\n", (int) pj_strlen(&(*module)->name), pj_strbuf(&(*module)->name));
130 return 0;
131}
132
133void ast_sip_unregister_service(pjsip_module *module)
134{
136}
137
139
141{
143 ast_log(LOG_WARNING, "Authenticator %p is already registered. Cannot register a new one\n", registered_authenticator);
144 return -1;
145 }
147 ast_debug(1, "Registered SIP authenticator module %p\n", auth);
148
149 return 0;
150}
151
153{
154 if (registered_authenticator != auth) {
155 ast_log(LOG_WARNING, "Trying to unregister authenticator %p but authenticator %p registered\n",
157 return;
158 }
160 ast_debug(1, "Unregistered SIP authenticator %p\n", auth);
161}
162
163int ast_sip_requires_authentication(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
164{
166 && !pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_options_method)) {
167 ast_debug(3, "Skipping OPTIONS authentication due to endpoint configuration\n");
168 return 0;
169 }
170
172 ast_log(LOG_WARNING, "No SIP authenticator registered. Assuming authentication is not required\n");
173 return 0;
174 }
175
176 return registered_authenticator->requires_authentication(endpoint, rdata);
177}
178
180 pjsip_rx_data *rdata, pjsip_tx_data *tdata)
181{
183 ast_log(LOG_WARNING, "No SIP authenticator registered. Assuming authentication is successful\n");
185 }
186 return registered_authenticator->check_authentication(endpoint, rdata, tdata);
187}
188
190
192{
194 ast_log(LOG_WARNING, "Outbound authenticator %p is already registered. Cannot register a new one\n", registered_outbound_authenticator);
195 return -1;
196 }
198 ast_debug(1, "Registered SIP outbound authenticator module %p\n", auth);
199
200 return 0;
201}
202
204{
206 ast_log(LOG_WARNING, "Trying to unregister outbound authenticator %p but outbound authenticator %p registered\n",
208 return;
209 }
211 ast_debug(1, "Unregistered SIP outbound authenticator %p\n", auth);
212}
213
214int ast_sip_create_request_with_auth(const struct ast_sip_auth_vector *auths, pjsip_rx_data *challenge,
215 pjsip_tx_data *old_request, pjsip_tx_data **new_request)
216{
218 ast_log(LOG_WARNING, "No SIP outbound authenticator registered. Cannot respond to authentication challenge\n");
219 return -1;
220 }
221 return registered_outbound_authenticator->create_request_with_auth(auths, challenge, old_request, new_request);
222}
223
230
232
234 const char *name)
235{
236 char *prev, *current, *identifier_order;
237 struct endpoint_identifier_list *iter, *id_list_item;
239
240 id_list_item = ast_calloc(1, sizeof(*id_list_item));
241 if (!id_list_item) {
242 ast_log(LOG_ERROR, "Unable to add endpoint identifier. Out of memory.\n");
243 return -1;
244 }
245 id_list_item->identifier = identifier;
246 id_list_item->name = name;
247
248 ast_debug(1, "Register endpoint identifier %s(%p)\n", name ?: "", identifier);
249
250 if (ast_strlen_zero(name)) {
251 /* if an identifier has no name then place in front */
253 return 0;
254 }
255
256 /* see if the name of the identifier is in the global endpoint_identifier_order list */
257 identifier_order = prev = current = ast_sip_get_endpoint_identifier_order();
258
259 if (ast_strlen_zero(identifier_order)) {
260 id_list_item->priority = UINT_MAX;
262 ast_free(identifier_order);
263 return 0;
264 }
265
266 id_list_item->priority = 0;
267 while ((current = strchr(current, ','))) {
268 ++id_list_item->priority;
269 if (!strncmp(prev, name, current - prev)
270 && strlen(name) == current - prev) {
271 break;
272 }
273 prev = ++current;
274 }
275
276 if (!current) {
277 /* check to see if it is the only or last item */
278 if (!strcmp(prev, name)) {
279 ++id_list_item->priority;
280 } else {
281 id_list_item->priority = UINT_MAX;
282 }
283 }
284
285 if (id_list_item->priority == UINT_MAX || AST_RWLIST_EMPTY(&endpoint_identifiers)) {
286 /* if not in the endpoint_identifier_order list then consider it less in
287 priority and add it to the end */
289 ast_free(identifier_order);
290 return 0;
291 }
292
294 if (id_list_item->priority < iter->priority) {
296 break;
297 }
298
299 if (!AST_RWLIST_NEXT(iter, list)) {
301 break;
302 }
303 }
305
306 ast_free(identifier_order);
307 return 0;
308}
309
314
329
330struct ast_sip_endpoint *ast_sip_identify_endpoint(pjsip_rx_data *rdata)
331{
332 struct endpoint_identifier_list *iter;
333 struct ast_sip_endpoint *endpoint = NULL;
337 endpoint = iter->identifier->identify_endpoint(rdata);
338 if (endpoint) {
339 break;
340 }
341 }
342 return endpoint;
343}
344
345char *ast_sip_rdata_get_header_value(pjsip_rx_data *rdata, const pj_str_t str)
346{
347 pjsip_generic_string_hdr *hdr;
348 pj_str_t hdr_val;
349
350 hdr = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str, NULL);
351 if (!hdr) {
352 return NULL;
353 }
354
355 pj_strdup_with_null(rdata->tp_info.pool, &hdr_val, &hdr->hvalue);
356
357 return hdr_val.ptr;
358}
359
360static int do_cli_dump_endpt(void *v_a)
361{
362 struct ast_cli_args *a = v_a;
363
365 pjsip_endpt_dump(ast_sip_get_pjsip_endpoint(), a->argc == 4 ? PJ_TRUE : PJ_FALSE);
367
368 return 0;
369}
370
371static char *cli_dump_endpt(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
372{
373 switch (cmd) {
374 case CLI_INIT:
375#ifdef AST_DEVMODE
376 e->command = "pjsip dump endpt [details]";
377 e->usage =
378 "Usage: pjsip dump endpt [details]\n"
379 " Dump the res_pjsip endpt internals.\n"
380 "\n"
381 "Warning: PJPROJECT documents that the function used by this\n"
382 "CLI command may cause a crash when asking for details because\n"
383 "it tries to access all active memory pools.\n";
384#else
385 /*
386 * In non-developer mode we will not document or make easily accessible
387 * the details option even though it is still available. The user has
388 * to know it exists to use it. Presumably they would also be aware of
389 * the potential crash warning.
390 */
391 e->command = "pjsip dump endpt";
392 e->usage =
393 "Usage: pjsip dump endpt\n"
394 " Dump the res_pjsip endpt internals.\n";
395#endif /* AST_DEVMODE */
396 return NULL;
397 case CLI_GENERATE:
398 return NULL;
399 }
400
401 if (4 < a->argc
402 || (a->argc == 4 && strcasecmp(a->argv[3], "details"))) {
403 return CLI_SHOWUSAGE;
404 }
405
407
408 return CLI_SUCCESS;
409}
410
411static char *cli_show_endpoint_identifiers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
412{
413#define ENDPOINT_IDENTIFIER_FORMAT "%-20.20s\n"
414 struct endpoint_identifier_list *iter;
415
416 switch (cmd) {
417 case CLI_INIT:
418 e->command = "pjsip show identifiers";
419 e->usage = "Usage: pjsip show identifiers\n"
420 " List all registered endpoint identifiers\n";
421 return NULL;
422 case CLI_GENERATE:
423 return NULL;
424 }
425
426 if (a->argc != 3) {
427 return CLI_SHOWUSAGE;
428 }
429
430 ast_cli(a->fd, ENDPOINT_IDENTIFIER_FORMAT, "Identifier Names:");
431 {
435 iter->name ? iter->name : "name not specified");
436 }
437 }
438 return CLI_SUCCESS;
439#undef ENDPOINT_IDENTIFIER_FORMAT
440}
441
442static char *cli_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
443{
444 struct ast_sip_cli_context context;
445
446 switch (cmd) {
447 case CLI_INIT:
448 e->command = "pjsip show settings";
449 e->usage = "Usage: pjsip show settings\n"
450 " Show global and system configuration options\n";
451 return NULL;
452 case CLI_GENERATE:
453 return NULL;
454 }
455
456 context.output_buffer = ast_str_create(256);
457 if (!context.output_buffer) {
458 ast_cli(a->fd, "Could not allocate output buffer.\n");
459 return CLI_FAILURE;
460 }
461
462 if (sip_cli_print_global(&context) || sip_cli_print_system(&context)) {
463 ast_free(context.output_buffer);
464 ast_cli(a->fd, "Error retrieving settings.\n");
465 return CLI_FAILURE;
466 }
467
468 ast_cli(a->fd, "%s", ast_str_buffer(context.output_buffer));
469 ast_free(context.output_buffer);
470 return CLI_SUCCESS;
471}
472
473static struct ast_cli_entry cli_commands[] = {
474 AST_CLI_DEFINE(cli_dump_endpt, "Dump the res_pjsip endpt internals"),
475 AST_CLI_DEFINE(cli_show_settings, "Show global and system configuration options"),
476 AST_CLI_DEFINE(cli_show_endpoint_identifiers, "List registered endpoint identifiers")
477};
478
480
486
500
502 struct ast_sip_ami *ami, int *count)
503{
504 int res = 0;
507 *count = 0;
509 if (i->format_ami && ((res = i->format_ami(endpoint, ami)) < 0)) {
510 return res;
511 }
512
513 if (!res) {
514 (*count)++;
515 }
516 }
517 return 0;
518}
519
520pjsip_endpoint *ast_sip_get_pjsip_endpoint(void)
521{
522 return ast_pjsip_endpoint;
523}
524
525int ast_sip_will_uri_survive_restart(pjsip_sip_uri *uri, struct ast_sip_endpoint *endpoint,
526 pjsip_rx_data *rdata)
527{
528 pj_str_t host_name;
529 int result = 1;
530
531 /* Determine if the contact cannot survive a restart/boot. */
532 if (uri->port == rdata->pkt_info.src_port
533 && !pj_strcmp(&uri->host,
534 pj_cstr(&host_name, rdata->pkt_info.src_name))
535 /* We have already checked if the URI scheme is sip: or sips: */
536 && PJSIP_TRANSPORT_IS_RELIABLE(rdata->tp_info.transport)) {
537 pj_str_t type_name;
538
539 /* Determine the transport parameter value */
540 if (!strcasecmp("WSS", rdata->tp_info.transport->type_name)) {
541 /* WSS is special, as it needs to be ws. */
542 pj_cstr(&type_name, "ws");
543 } else {
544 pj_cstr(&type_name, rdata->tp_info.transport->type_name);
545 }
546
547 if (!pj_stricmp(&uri->transport_param, &type_name)
548 && (endpoint->nat.rewrite_contact
549 /* Websockets are always rewritten */
550 || !pj_stricmp(&uri->transport_param,
551 pj_cstr(&type_name, "ws")))) {
552 /*
553 * The contact was rewritten to the reliable transport's
554 * source address. Disconnecting the transport for any
555 * reason invalidates the contact.
556 */
557 result = 0;
558 }
559 }
560
561 return result;
562}
563
564pjsip_sip_uri *ast_sip_get_contact_sip_uri(pjsip_tx_data *tdata)
565{
566 pjsip_contact_hdr *contact = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CONTACT, NULL);
567
568 if (!contact || (!PJSIP_URI_SCHEME_IS_SIP(contact->uri) && !PJSIP_URI_SCHEME_IS_SIPS(contact->uri))) {
569 return NULL;
570 }
571
572 return pjsip_uri_get_uri(contact->uri);
573}
574
575/*! \brief Callback function for finding the transport the request is going out on */
576static int find_transport_state_in_use(void *obj, void *arg, int flags)
577{
578 struct ast_sip_transport_state *transport_state = obj;
579 struct ast_sip_request_transport_details *details = arg;
580
581 /* If an explicit transport or factory matches then this is what is in use, if we are unavailable
582 * to compare based on that we make sure that the type is the same and the source IP address/port are the same
583 */
584 if (transport_state && ((details->transport && details->transport == transport_state->transport) ||
585 (details->factory && details->factory == transport_state->factory) ||
586 ((details->type == transport_state->type) && (transport_state->factory) &&
587 !pj_strcmp(&transport_state->factory->addr_name.host, &details->local_address) &&
588 transport_state->factory->addr_name.port == details->local_port))) {
589 return CMP_MATCH | CMP_STOP;
590 }
591
592 return 0;
593}
594
604
605int ast_sip_rewrite_uri_to_local(pjsip_sip_uri *uri, pjsip_tx_data *tdata) {
607 RAII_VAR(struct ast_sip_transport_state *, transport_state, NULL, ao2_cleanup);
608 struct ast_sip_request_transport_details details = { 0, };
609 pjsip_sip_uri *tmp_uri;
610 pjsip_dialog *dlg;
611 struct ast_sockaddr addr = { { 0, } };
612
613 if ((tmp_uri = ast_sip_get_contact_sip_uri(tdata))) {
614 pj_strdup(tdata->pool, &uri->host, &tmp_uri->host);
615 uri->port = tmp_uri->port;
616 } else if ((dlg = pjsip_tdata_get_dlg(tdata))
617 && (tmp_uri = pjsip_uri_get_uri(dlg->local.info->uri))
618 && (PJSIP_URI_SCHEME_IS_SIP(tmp_uri) || PJSIP_URI_SCHEME_IS_SIPS(tmp_uri))) {
619 pj_strdup(tdata->pool, &uri->host, &tmp_uri->host);
620 uri->port = tmp_uri->port;
621 }
622
623 if (ast_sip_set_request_transport_details(&details, tdata, 1)
624 || !(transport_state = ast_sip_find_transport_state_in_use(&details))
625 || !(transport = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport", transport_state->id))) {
626 return 0;
627 }
628
629 if (transport_state->localnet) {
630 ast_sockaddr_parse(&addr, tdata->tp_info.dst_name, PARSE_PORT_FORBID);
631 ast_sockaddr_set_port(&addr, tdata->tp_info.dst_port);
632 if (ast_sip_transport_is_local(transport_state, &addr)) {
633 return 0;
634 }
635 }
636
637 if (!ast_sockaddr_isnull(&transport_state->external_signaling_address)) {
638 pj_strdup2(tdata->pool, &uri->host, ast_sockaddr_stringify_host(&transport_state->external_signaling_address));
639 }
640
641 if (transport->external_signaling_port) {
642 uri->port = transport->external_signaling_port;
643 }
644
645 return 0;
646}
647
649 int use_ipv6) {
650 pjsip_sip_uri *uri;
651 pjsip_via_hdr *via;
652 long transport_type;
653
654 if (!details || !tdata) {
655 return -1;
656 }
657
658 /* If IPv6 should be considered, un-set Bit 7 to make TCP6 equal to TCP and TLS6 equal to TLS */
659 transport_type = use_ipv6 ? tdata->tp_info.transport->key.type & ~(PJSIP_TRANSPORT_IPV6)
660 : tdata->tp_info.transport->key.type;
661
662 if (tdata->tp_sel.type == PJSIP_TPSELECTOR_TRANSPORT) {
663 details->transport = tdata->tp_sel.u.transport;
664 } else if (tdata->tp_sel.type == PJSIP_TPSELECTOR_LISTENER) {
665 details->factory = tdata->tp_sel.u.listener;
666 } else if (transport_type == PJSIP_TRANSPORT_UDP || transport_type == PJSIP_TRANSPORT_UDP6) {
667 /* Connectionless uses the same transport for all requests */
668 details->type = AST_TRANSPORT_UDP;
669 details->transport = tdata->tp_info.transport;
670 } else {
671 if (transport_type == PJSIP_TRANSPORT_TCP) {
672 details->type = AST_TRANSPORT_TCP;
673 } else if (transport_type == PJSIP_TRANSPORT_TLS) {
674 details->type = AST_TRANSPORT_TLS;
675 } else {
676 /* Unknown transport type, we can't map. */
677 return -1;
678 }
679
680 if ((uri = ast_sip_get_contact_sip_uri(tdata))) {
681 details->local_address = uri->host;
682 details->local_port = uri->port;
683 } else if ((tdata->msg->type == PJSIP_REQUEST_MSG) &&
684 (via = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL))) {
685 details->local_address = via->sent_by.host;
686 details->local_port = via->sent_by.port;
687 } else {
688 return -1;
689 }
690
691 if (!details->local_port) {
692 details->local_port = (details->type == AST_TRANSPORT_TLS) ? 5061 : 5060;
693 }
694 }
695 return 0;
696}
697
699 pjsip_sip_uri *sip_uri, char *buf, size_t buf_len)
700{
701 char *host = NULL;
702 static const pj_str_t x_name = { AST_SIP_X_AST_TXP, AST_SIP_X_AST_TXP_LEN };
703 pjsip_param *x_transport;
704
705 if (!ast_strlen_zero(endpoint->transport)) {
706 ast_copy_string(buf, endpoint->transport, buf_len);
707 return 0;
708 }
709
710 x_transport = pjsip_param_find(&sip_uri->other_param, &x_name);
711 if (!x_transport) {
712 return -1;
713 }
714
715 /* Only use x_transport if the uri host is an ip (4 or 6) address */
716 host = ast_alloca(sip_uri->host.slen + 1);
717 ast_copy_pj_str(host, &sip_uri->host, sip_uri->host.slen + 1);
719 return -1;
720 }
721
722 ast_copy_pj_str(buf, &x_transport->value, buf_len);
723
724 return 0;
725}
726
727int ast_sip_dlg_set_transport(const struct ast_sip_endpoint *endpoint, pjsip_dialog *dlg,
728 pjsip_tpselector *selector)
729{
730 pjsip_sip_uri *uri;
731 pjsip_tpselector sel = { .type = PJSIP_TPSELECTOR_NONE, };
732
733 uri = pjsip_uri_get_uri(dlg->target);
734 if (!selector) {
735 selector = &sel;
736 }
737
738 ast_sip_set_tpselector_from_ep_or_uri(endpoint, uri, selector);
739
740 pjsip_dlg_set_transport(dlg, selector);
741
742 if (selector == &sel) {
744 }
745
746 return 0;
747}
748
749static int sip_dialog_create_from(pj_pool_t *pool, pj_str_t *from, const char *user,
750 const char *domain, const pj_str_t *target, pjsip_tpselector *selector)
751{
752 pj_str_t tmp, local_addr;
753 pjsip_uri *uri;
754 pjsip_sip_uri *sip_uri;
755 pjsip_transport_type_e type;
756 int local_port;
757 char default_user[PJSIP_MAX_URL_SIZE];
758
759 if (ast_strlen_zero(user)) {
760 ast_sip_get_default_from_user(default_user, sizeof(default_user));
761 user = default_user;
762 }
763
764 /* Parse the provided target URI so we can determine what transport it will end up using */
765 pj_strdup_with_null(pool, &tmp, target);
766
767 if (!(uri = pjsip_parse_uri(pool, tmp.ptr, tmp.slen, 0)) ||
768 (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri))) {
769 return -1;
770 }
771
772 sip_uri = pjsip_uri_get_uri(uri);
773
774 /* Determine the transport type to use */
775 type = pjsip_transport_get_type_from_name(&sip_uri->transport_param);
776 if (PJSIP_URI_SCHEME_IS_SIPS(sip_uri)) {
777 if (type == PJSIP_TRANSPORT_UNSPECIFIED
778 || !(pjsip_transport_get_flag_from_type(type) & PJSIP_TRANSPORT_SECURE)) {
779 type = PJSIP_TRANSPORT_TLS;
780 }
781 } else if (!sip_uri->transport_param.slen) {
782 type = PJSIP_TRANSPORT_UDP;
783 } else if (type == PJSIP_TRANSPORT_UNSPECIFIED) {
784 return -1;
785 }
786
787 /* If the host is IPv6 turn the transport into an IPv6 version */
788 if (pj_strchr(&sip_uri->host, ':')) {
789 type |= PJSIP_TRANSPORT_IPV6;
790 }
791
792 /* In multidomain scenario, username may contain @ with domain info */
793 if (!ast_sip_get_disable_multi_domain() && strchr(user, '@')) {
794 from->ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
795 from->slen = pj_ansi_snprintf(from->ptr, PJSIP_MAX_URL_SIZE,
796 "<sip:%s%s%s>",
797 user,
798 (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? ";transport=" : "",
799 (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? pjsip_transport_get_type_name(type) : "");
800 return 0;
801 }
802
803 if (!ast_strlen_zero(domain)) {
804 from->ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
805 from->slen = pj_ansi_snprintf(from->ptr, PJSIP_MAX_URL_SIZE,
806 "<sip:%s@%s%s%s>",
807 user,
808 domain,
809 (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? ";transport=" : "",
810 (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? pjsip_transport_get_type_name(type) : "");
811 return 0;
812 }
813
814 /* Get the local bound address for the transport that will be used when communicating with the provided URI */
815 if (pjsip_tpmgr_find_local_addr(pjsip_endpt_get_tpmgr(ast_sip_get_pjsip_endpoint()), pool, type, selector,
816 &local_addr, &local_port) != PJ_SUCCESS) {
817
818 /* If no local address can be retrieved using the transport manager use the host one */
819 pj_strdup(pool, &local_addr, pj_gethostname());
820 local_port = pjsip_transport_get_default_port_for_type(PJSIP_TRANSPORT_UDP);
821 }
822
823 /* If IPv6 was specified in the transport, set the proper type */
824 if (pj_strchr(&local_addr, ':')) {
825 type |= PJSIP_TRANSPORT_IPV6;
826 }
827
828 from->ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
829 from->slen = pj_ansi_snprintf(from->ptr, PJSIP_MAX_URL_SIZE,
830 "<sip:%s@%s%.*s%s:%d%s%s>",
831 user,
832 (type & PJSIP_TRANSPORT_IPV6) ? "[" : "",
833 (int)local_addr.slen,
834 local_addr.ptr,
835 (type & PJSIP_TRANSPORT_IPV6) ? "]" : "",
836 local_port,
837 (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? ";transport=" : "",
838 (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? pjsip_transport_get_type_name(type) : "");
839
840 return 0;
841}
842
843int ast_sip_set_tpselector_from_transport(const struct ast_sip_transport *transport, pjsip_tpselector *selector)
844{
845 int res = 0;
846 struct ast_sip_transport_state *transport_state;
847
849 if (!transport_state) {
850 ast_log(LOG_ERROR, "Unable to retrieve PJSIP transport state for '%s'\n",
852 return -1;
853 }
854
855 /* Only flows maintain dynamic state which needs protection */
856 if (transport_state->flow) {
857 ao2_lock(transport_state);
858 }
859
860 if (transport_state->transport) {
861 selector->type = PJSIP_TPSELECTOR_TRANSPORT;
862 selector->u.transport = transport_state->transport;
863 pjsip_transport_add_ref(selector->u.transport);
864 } else if (transport_state->factory) {
865 selector->type = PJSIP_TPSELECTOR_LISTENER;
866 selector->u.listener = transport_state->factory;
867 } else if (transport->type == AST_TRANSPORT_WS || transport->type == AST_TRANSPORT_WSS) {
868 /* The WebSocket transport has no factory as it can not create outgoing connections, so
869 * even if an endpoint is locked to a WebSocket transport we let the PJSIP logic
870 * find the existing connection if available and use it.
871 */
872 } else if (transport->flow) {
873 /* This is a child of another transport, so we need to establish a new connection */
874#ifdef HAVE_PJSIP_TRANSPORT_DISABLE_CONNECTION_REUSE
875 selector->disable_connection_reuse = PJ_TRUE;
876#else
877 ast_log(LOG_WARNING, "Connection reuse could not be disabled on transport '%s' as support is not available\n",
879#endif
880 } else {
881 res = -1;
882 }
883
884 if (transport_state->flow) {
885 ao2_unlock(transport_state);
886 }
887
888 ao2_ref(transport_state, -1);
889
890 return res;
891}
892
893int ast_sip_set_tpselector_from_transport_name(const char *transport_name, pjsip_tpselector *selector)
894{
896
897 if (ast_strlen_zero(transport_name)) {
898 return 0;
899 }
900
901 transport = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport", transport_name);
902 if (!transport) {
903 ast_log(LOG_ERROR, "Unable to retrieve PJSIP transport '%s'\n",
904 transport_name);
905 return -1;
906 }
907
909}
910
912 pjsip_sip_uri *sip_uri, pjsip_tpselector *selector)
913{
914 char transport_name[128];
915
916 if (ast_sip_get_transport_name(endpoint, sip_uri, transport_name, sizeof(transport_name))) {
917 return 0;
918 }
919
920 return ast_sip_set_tpselector_from_transport_name(transport_name, selector);
921}
922
923void ast_sip_tpselector_unref(pjsip_tpselector *selector)
924{
925 if (selector->type == PJSIP_TPSELECTOR_TRANSPORT && selector->u.transport) {
926 pjsip_transport_dec_ref(selector->u.transport);
927 }
928}
929
930void ast_sip_add_usereqphone(const struct ast_sip_endpoint *endpoint, pj_pool_t *pool, pjsip_uri *uri)
931{
932 pjsip_sip_uri *sip_uri;
933 int i = 0;
934 static const pj_str_t STR_PHONE = { "phone", 5 };
935
936 if (!endpoint || !endpoint->usereqphone || (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri))) {
937 return;
938 }
939
940 sip_uri = pjsip_uri_get_uri(uri);
941
942 if (!pj_strlen(&sip_uri->user)) {
943 return;
944 }
945
946 if (pj_strbuf(&sip_uri->user)[0] == '+') {
947 i = 1;
948 }
949
950 /* Test URI user against allowed characters in AST_DIGIT_ANY */
951 for (; i < pj_strlen(&sip_uri->user); i++) {
952 if (!strchr(AST_DIGIT_ANY, pj_strbuf(&sip_uri->user)[i])) {
953 break;
954 }
955 }
956
957 if (i < pj_strlen(&sip_uri->user)) {
958 return;
959 }
960
961 sip_uri->user_param = STR_PHONE;
962}
963
964pjsip_dialog *ast_sip_create_dialog_uac(const struct ast_sip_endpoint *endpoint,
965 const char *uri, const char *request_user)
966{
967 char enclosed_uri[PJSIP_MAX_URL_SIZE];
968 pj_str_t local_uri = { "sip:temp@temp", 13 }, remote_uri, target_uri;
969 pj_status_t res;
970 pjsip_dialog *dlg = NULL;
971 const char *outbound_proxy = endpoint->outbound_proxy;
972 pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
973 static const pj_str_t HCONTACT = { "Contact", 7 };
974
975 if (!ast_begins_with(uri, "<")) {
976 snprintf(enclosed_uri, sizeof(enclosed_uri), "<%s>", uri);
977 } else {
978 snprintf(enclosed_uri, sizeof(enclosed_uri), "%s", uri);
979 }
980 pj_cstr(&remote_uri, enclosed_uri);
981
982 pj_cstr(&target_uri, uri);
983
984 res = pjsip_dlg_create_uac(pjsip_ua_instance(), &local_uri, NULL, &remote_uri, &target_uri, &dlg);
985 if (res == PJ_SUCCESS && !(PJSIP_URI_SCHEME_IS_SIP(dlg->target) || PJSIP_URI_SCHEME_IS_SIPS(dlg->target))) {
986 /* dlg->target is a pjsip_other_uri, but it's assumed to be a
987 * pjsip_sip_uri below. Fail fast. */
988 res = PJSIP_EINVALIDURI;
989 pjsip_dlg_terminate(dlg);
990 }
991 if (res != PJ_SUCCESS) {
992 if (res == PJSIP_EINVALIDURI) {
994 "Endpoint '%s': Could not create dialog to invalid URI '%s'. Is endpoint registered and reachable?\n",
995 ast_sorcery_object_get_id(endpoint), uri);
996 }
997 return NULL;
998 }
999
1000 /* We have to temporarily bump up the sess_count here so the dialog is not prematurely destroyed */
1001 dlg->sess_count++;
1002
1003 ast_sip_dlg_set_transport(endpoint, dlg, &selector);
1004
1005 if (sip_dialog_create_from(dlg->pool, &local_uri, endpoint->fromuser, endpoint->fromdomain, &remote_uri, &selector)) {
1006 dlg->sess_count--;
1007 pjsip_dlg_terminate(dlg);
1008 ast_sip_tpselector_unref(&selector);
1009 return NULL;
1010 }
1011
1012 ast_sip_tpselector_unref(&selector);
1013
1014 /* Update the dialog with the new local URI, we do it afterwards so we can use the dialog pool for construction */
1015 pj_strdup_with_null(dlg->pool, &dlg->local.info_str, &local_uri);
1016 dlg->local.info->uri = pjsip_parse_uri(dlg->pool, dlg->local.info_str.ptr, dlg->local.info_str.slen, 0);
1017 if (!dlg->local.info->uri) {
1019 "Could not parse URI '%s' for endpoint '%s'\n",
1020 dlg->local.info_str.ptr, ast_sorcery_object_get_id(endpoint));
1021 dlg->sess_count--;
1022 pjsip_dlg_terminate(dlg);
1023 return NULL;
1024 }
1025
1026 dlg->local.contact = pjsip_parse_hdr(dlg->pool, &HCONTACT, local_uri.ptr, local_uri.slen, NULL);
1027
1028 if (!ast_strlen_zero(endpoint->contact_user)) {
1029 pjsip_sip_uri *sip_uri;
1030
1031 sip_uri = pjsip_uri_get_uri(dlg->local.contact->uri);
1032 pj_strdup2(dlg->pool, &sip_uri->user, endpoint->contact_user);
1033 }
1034
1035 /* If a request user has been specified and we are permitted to change it, do so */
1036 if (!ast_strlen_zero(request_user)) {
1037 pjsip_sip_uri *sip_uri;
1038
1039 if (PJSIP_URI_SCHEME_IS_SIP(dlg->target) || PJSIP_URI_SCHEME_IS_SIPS(dlg->target)) {
1040 sip_uri = pjsip_uri_get_uri(dlg->target);
1041 pj_strdup2(dlg->pool, &sip_uri->user, request_user);
1042 }
1043 if (PJSIP_URI_SCHEME_IS_SIP(dlg->remote.info->uri) || PJSIP_URI_SCHEME_IS_SIPS(dlg->remote.info->uri)) {
1044 sip_uri = pjsip_uri_get_uri(dlg->remote.info->uri);
1045 pj_strdup2(dlg->pool, &sip_uri->user, request_user);
1046 }
1047 }
1048
1049 /* Add the user=phone parameter if applicable */
1050 ast_sip_add_usereqphone(endpoint, dlg->pool, dlg->target);
1051 ast_sip_add_usereqphone(endpoint, dlg->pool, dlg->remote.info->uri);
1052 ast_sip_add_usereqphone(endpoint, dlg->pool, dlg->local.info->uri);
1053
1054 if (!ast_strlen_zero(outbound_proxy)) {
1055 pjsip_route_hdr route_set, *route;
1056 static const pj_str_t ROUTE_HNAME = { "Route", 5 };
1057 pj_str_t tmp;
1058
1059 pj_list_init(&route_set);
1060
1061 pj_strdup2_with_null(dlg->pool, &tmp, outbound_proxy);
1062 if (!(route = pjsip_parse_hdr(dlg->pool, &ROUTE_HNAME, tmp.ptr, tmp.slen, NULL))) {
1063 ast_log(LOG_ERROR, "Could not create dialog to endpoint '%s' as outbound proxy URI '%s' is not valid\n",
1064 ast_sorcery_object_get_id(endpoint), outbound_proxy);
1065 dlg->sess_count--;
1066 pjsip_dlg_terminate(dlg);
1067 return NULL;
1068 }
1069 pj_list_insert_nodes_before(&route_set, route);
1070
1071 pjsip_dlg_set_route_set(dlg, &route_set);
1072 }
1073
1074 dlg->sess_count--;
1075
1076 return dlg;
1077}
1078
1079/*!
1080 * \brief Determine if a SIPS Contact header is required.
1081 *
1082 * This uses the guideline provided in RFC 3261 Section 12.1.1 to
1083 * determine if the Contact header must be a sips: URI.
1084 *
1085 * \param rdata The incoming dialog-starting request
1086 * \retval 0 SIPS not required
1087 * \retval 1 SIPS required
1088 */
1089static int uas_use_sips_contact(pjsip_rx_data *rdata)
1090{
1091 pjsip_rr_hdr *record_route;
1092
1093 if (PJSIP_URI_SCHEME_IS_SIPS(rdata->msg_info.msg->line.req.uri)) {
1094 return 1;
1095 }
1096
1097 record_route = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_RECORD_ROUTE, NULL);
1098 if (record_route) {
1099 if (PJSIP_URI_SCHEME_IS_SIPS(&record_route->name_addr)) {
1100 return 1;
1101 }
1102 } else {
1103 pjsip_contact_hdr *contact;
1104
1105 contact = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL);
1106 ast_assert(contact != NULL);
1107 if (PJSIP_URI_SCHEME_IS_SIPS(contact->uri)) {
1108 return 1;
1109 }
1110 }
1111
1112 return 0;
1113}
1114
1115typedef pj_status_t (*create_dlg_uac)(pjsip_user_agent *ua, pjsip_rx_data *rdata,
1116 const pj_str_t *contact, pjsip_dialog **p_dlg);
1117
1118static pjsip_dialog *create_dialog_uas(const struct ast_sip_endpoint *endpoint,
1119 pjsip_rx_data *rdata, pj_status_t *status, create_dlg_uac create_fun)
1120{
1121 pjsip_dialog *dlg;
1122 pj_str_t contact;
1123 pjsip_transport_type_e type = rdata->tp_info.transport->key.type;
1124 pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
1125 pjsip_transport *transport;
1126 pjsip_contact_hdr *contact_hdr;
1127
1129
1130 contact_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL);
1131 if (!contact_hdr || ast_sip_set_tpselector_from_ep_or_uri(endpoint, pjsip_uri_get_uri(contact_hdr->uri),
1132 &selector)) {
1133 return NULL;
1134 }
1135
1136 transport = rdata->tp_info.transport;
1137 if (selector.type == PJSIP_TPSELECTOR_TRANSPORT) {
1138 transport = selector.u.transport;
1139 }
1140 type = transport->key.type;
1141
1142 contact.ptr = pj_pool_alloc(rdata->tp_info.pool, PJSIP_MAX_URL_SIZE);
1143 contact.slen = pj_ansi_snprintf(contact.ptr, PJSIP_MAX_URL_SIZE,
1144 "<%s:%s%s%s%.*s%s:%d%s%s>",
1145 uas_use_sips_contact(rdata) ? "sips" : "sip",
1146 S_OR(endpoint->contact_user, ""),
1147 (!ast_strlen_zero(endpoint->contact_user)) ? "@" : "",
1148 (type & PJSIP_TRANSPORT_IPV6) ? "[" : "",
1149 (int)transport->local_name.host.slen,
1150 transport->local_name.host.ptr,
1151 (type & PJSIP_TRANSPORT_IPV6) ? "]" : "",
1152 transport->local_name.port,
1153 (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? ";transport=" : "",
1154 (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? pjsip_transport_get_type_name(type) : "");
1155
1156 *status = create_fun(pjsip_ua_instance(), rdata, &contact, &dlg);
1157 if (*status != PJ_SUCCESS) {
1158 char err[PJ_ERR_MSG_SIZE];
1159
1160 pj_strerror(*status, err, sizeof(err));
1161 ast_log(LOG_ERROR, "Could not create dialog with endpoint %s. %s\n",
1162 ast_sorcery_object_get_id(endpoint), err);
1163 ast_sip_tpselector_unref(&selector);
1164 return NULL;
1165 }
1166
1167 dlg->sess_count++;
1168 pjsip_dlg_set_transport(dlg, &selector);
1169 dlg->sess_count--;
1170
1171 ast_sip_tpselector_unref(&selector);
1172
1173 return dlg;
1174}
1175
1176pjsip_dialog *ast_sip_create_dialog_uas(const struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pj_status_t *status)
1177{
1178#ifdef HAVE_PJSIP_DLG_CREATE_UAS_AND_INC_LOCK
1179 pjsip_dialog *dlg;
1180
1181 dlg = create_dialog_uas(endpoint, rdata, status, pjsip_dlg_create_uas_and_inc_lock);
1182 if (dlg) {
1183 pjsip_dlg_dec_lock(dlg);
1184 }
1185
1186 return dlg;
1187#else
1188 return create_dialog_uas(endpoint, rdata, status, pjsip_dlg_create_uas);
1189#endif
1190}
1191
1192pjsip_dialog *ast_sip_create_dialog_uas_locked(const struct ast_sip_endpoint *endpoint,
1193 pjsip_rx_data *rdata, pj_status_t *status)
1194{
1195#ifdef HAVE_PJSIP_DLG_CREATE_UAS_AND_INC_LOCK
1196 return create_dialog_uas(endpoint, rdata, status, pjsip_dlg_create_uas_and_inc_lock);
1197#else
1198 /*
1199 * This is put here in order to be compatible with older versions of pjproject.
1200 * Best we can do in this case is immediately lock after getting the dialog.
1201 * However, that does leave a "gap" between creating and locking.
1202 */
1203 pjsip_dialog *dlg;
1204
1205 dlg = create_dialog_uas(endpoint, rdata, status, pjsip_dlg_create_uas);
1206 if (dlg) {
1207 pjsip_dlg_inc_lock(dlg);
1208 }
1209
1210 return dlg;
1211#endif
1212 }
1213
1214int ast_sip_create_rdata_with_contact(pjsip_rx_data *rdata, char *packet, const char *src_name, int src_port,
1215 char *transport_type, const char *local_name, int local_port, const char *contact)
1216{
1217 pj_str_t tmp;
1218
1219 /*
1220 * Initialize the error list in case there is a parse error
1221 * in the given packet.
1222 */
1223 pj_list_init(&rdata->msg_info.parse_err);
1224
1225 rdata->tp_info.transport = PJ_POOL_ZALLOC_T(rdata->tp_info.pool, pjsip_transport);
1226 if (!rdata->tp_info.transport) {
1227 return -1;
1228 }
1229
1230 ast_copy_string(rdata->pkt_info.packet, packet, sizeof(rdata->pkt_info.packet));
1231 ast_copy_string(rdata->pkt_info.src_name, src_name, sizeof(rdata->pkt_info.src_name));
1232 rdata->pkt_info.src_port = src_port;
1233 pj_sockaddr_parse(pj_AF_UNSPEC(), 0, pj_cstr(&tmp, src_name), &rdata->pkt_info.src_addr);
1234 pj_sockaddr_set_port(&rdata->pkt_info.src_addr, src_port);
1235
1236 pjsip_parse_rdata(packet, strlen(packet), rdata);
1237 if (!rdata->msg_info.msg || !pj_list_empty(&rdata->msg_info.parse_err)) {
1238 return -1;
1239 }
1240
1241 if (!ast_strlen_zero(contact)) {
1242 pjsip_contact_hdr *contact_hdr;
1243
1244 contact_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL);
1245 if (contact_hdr) {
1246 contact_hdr->uri = pjsip_parse_uri(rdata->tp_info.pool, (char *)contact,
1247 strlen(contact), PJSIP_PARSE_URI_AS_NAMEADDR);
1248 if (!contact_hdr->uri) {
1249 ast_log(LOG_WARNING, "Unable to parse contact URI from '%s'.\n", contact);
1250 return -1;
1251 }
1252 }
1253 }
1254
1255 pj_strdup2(rdata->tp_info.pool, &rdata->msg_info.via->recvd_param, rdata->pkt_info.src_name);
1256 rdata->msg_info.via->rport_param = -1;
1257
1258 rdata->tp_info.transport->key.type = pjsip_transport_get_type_from_name(pj_cstr(&tmp, transport_type));
1259 rdata->tp_info.transport->type_name = transport_type;
1260 pj_strdup2(rdata->tp_info.pool, &rdata->tp_info.transport->local_name.host, local_name);
1261 rdata->tp_info.transport->local_name.port = local_port;
1262
1263 return 0;
1264}
1265
1266int ast_sip_create_rdata(pjsip_rx_data *rdata, char *packet, const char *src_name, int src_port,
1267 char *transport_type, const char *local_name, int local_port)
1268{
1269 return ast_sip_create_rdata_with_contact(rdata, packet, src_name, src_port, transport_type,
1270 local_name, local_port, NULL);
1271}
1272
1273/* PJSIP doesn't know about the INFO method, so we have to define it ourselves */
1274static const pjsip_method info_method = {PJSIP_OTHER_METHOD, {"INFO", 4} };
1275static const pjsip_method message_method = {PJSIP_OTHER_METHOD, {"MESSAGE", 7} };
1276static const pjsip_method refer_method = {PJSIP_OTHER_METHOD, {"REFER", 5} };
1277
1278static struct {
1279 const char *method;
1280 const pjsip_method *pmethod;
1281} methods [] = {
1282 { "INVITE", &pjsip_invite_method },
1283 { "CANCEL", &pjsip_cancel_method },
1284 { "ACK", &pjsip_ack_method },
1285 { "BYE", &pjsip_bye_method },
1286 { "REGISTER", &pjsip_register_method },
1287 { "OPTIONS", &pjsip_options_method },
1288 { "SUBSCRIBE", &pjsip_subscribe_method },
1289 { "NOTIFY", &pjsip_notify_method },
1290 { "PUBLISH", &pjsip_publish_method },
1291 { "INFO", &info_method },
1292 { "MESSAGE", &message_method },
1293 { "REFER", &refer_method },
1295
1296static const pjsip_method *get_pjsip_method(const char *method)
1297{
1298 int i;
1299 for (i = 0; i < ARRAY_LEN(methods); ++i) {
1300 if (!strcmp(method, methods[i].method)) {
1301 return methods[i].pmethod;
1302 }
1303 }
1304 return NULL;
1305}
1306
1307static int create_in_dialog_request(const pjsip_method *method, struct pjsip_dialog *dlg, pjsip_tx_data **tdata)
1308{
1309 if (pjsip_dlg_create_request(dlg, method, -1, tdata) != PJ_SUCCESS) {
1310 ast_log(LOG_WARNING, "Unable to create in-dialog request.\n");
1311 return -1;
1312 }
1313
1314 return 0;
1315}
1316
1317static pj_bool_t supplement_on_rx_request(pjsip_rx_data *rdata);
1318static pjsip_module supplement_module = {
1319 .name = { "Out of dialog supplement hook", 29 },
1320 .id = -1,
1321 .priority = PJSIP_MOD_PRIORITY_APPLICATION - 1,
1322 .on_rx_request = supplement_on_rx_request,
1323};
1324
1325static int create_out_of_dialog_request(const pjsip_method *method, struct ast_sip_endpoint *endpoint,
1326 const char *uri, struct ast_sip_contact *provided_contact, pjsip_tx_data **tdata)
1327{
1328 RAII_VAR(struct ast_sip_contact *, contact, ao2_bump(provided_contact), ao2_cleanup);
1329 pj_str_t remote_uri;
1330 pj_str_t from;
1331 pj_pool_t *pool;
1332 pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
1333 pjsip_uri *sip_uri;
1334 const char *fromuser;
1335
1336 if (ast_strlen_zero(uri)) {
1337 if (!endpoint && (!contact || ast_strlen_zero(contact->uri))) {
1338 ast_log(LOG_ERROR, "An endpoint and/or uri must be specified\n");
1339 return -1;
1340 }
1341
1342 if (!contact) {
1344 }
1345 if (!contact || ast_strlen_zero(contact->uri)) {
1346 ast_log(LOG_WARNING, "Unable to retrieve contact for endpoint %s\n",
1347 ast_sorcery_object_get_id(endpoint));
1348 return -1;
1349 }
1350
1351 pj_cstr(&remote_uri, contact->uri);
1352 } else {
1353 pj_cstr(&remote_uri, uri);
1354 }
1355
1356 pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "Outbound request", 256, 256);
1357
1358 if (!pool) {
1359 ast_log(LOG_ERROR, "Unable to create PJLIB memory pool\n");
1360 return -1;
1361 }
1362
1363 sip_uri = pjsip_parse_uri(pool, remote_uri.ptr, remote_uri.slen, 0);
1364 if (!sip_uri || (!PJSIP_URI_SCHEME_IS_SIP(sip_uri) && !PJSIP_URI_SCHEME_IS_SIPS(sip_uri))) {
1365 ast_log(LOG_ERROR, "Unable to create outbound %.*s request to endpoint %s as URI '%s' is not valid\n",
1366 (int) pj_strlen(&method->name), pj_strbuf(&method->name),
1367 endpoint ? ast_sorcery_object_get_id(endpoint) : "<none>",
1368 pj_strbuf(&remote_uri));
1369 pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
1370 return -1;
1371 }
1372
1373 ast_sip_set_tpselector_from_ep_or_uri(endpoint, pjsip_uri_get_uri(sip_uri), &selector);
1374
1375 fromuser = endpoint ? (!ast_strlen_zero(endpoint->fromuser) ? endpoint->fromuser : ast_sorcery_object_get_id(endpoint)) : NULL;
1376 if (sip_dialog_create_from(pool, &from, fromuser,
1377 endpoint ? endpoint->fromdomain : NULL, &remote_uri, &selector)) {
1378 ast_log(LOG_ERROR, "Unable to create From header for %.*s request to endpoint %s\n",
1379 (int) pj_strlen(&method->name), pj_strbuf(&method->name),
1380 endpoint ? ast_sorcery_object_get_id(endpoint) : "<none>");
1381 pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
1382 ast_sip_tpselector_unref(&selector);
1383 return -1;
1384 }
1385
1386 if (pjsip_endpt_create_request(ast_sip_get_pjsip_endpoint(), method, &remote_uri,
1387 &from, &remote_uri, &from, NULL, -1, NULL, tdata) != PJ_SUCCESS) {
1388 ast_log(LOG_ERROR, "Unable to create outbound %.*s request to endpoint %s\n",
1389 (int) pj_strlen(&method->name), pj_strbuf(&method->name),
1390 endpoint ? ast_sorcery_object_get_id(endpoint) : "<none>");
1391 pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
1392 ast_sip_tpselector_unref(&selector);
1393 return -1;
1394 }
1395
1396 pjsip_tx_data_set_transport(*tdata, &selector);
1397
1398 ast_sip_tpselector_unref(&selector);
1399
1400 if (endpoint && !ast_strlen_zero(endpoint->contact_user)){
1401 pjsip_contact_hdr *contact_hdr;
1402 pjsip_sip_uri *contact_uri;
1403 static const pj_str_t HCONTACT = { "Contact", 7 };
1404 static const pj_str_t HCONTACTSHORT = { "m", 1 };
1405
1406 contact_hdr = pjsip_msg_find_hdr_by_names((*tdata)->msg, &HCONTACT, &HCONTACTSHORT, NULL);
1407 if (contact_hdr) {
1408 contact_uri = pjsip_uri_get_uri(contact_hdr->uri);
1409 pj_strdup2((*tdata)->pool, &contact_uri->user, endpoint->contact_user);
1410 }
1411 }
1412
1413 /* Add the user=phone parameter if applicable */
1414 ast_sip_add_usereqphone(endpoint, (*tdata)->pool, (*tdata)->msg->line.req.uri);
1415
1416 /* If an outbound proxy is specified on the endpoint apply it to this request */
1417 if (endpoint && !ast_strlen_zero(endpoint->outbound_proxy) &&
1418 ast_sip_set_outbound_proxy((*tdata), endpoint->outbound_proxy)) {
1419 ast_log(LOG_ERROR, "Unable to apply outbound proxy on request %.*s to endpoint %s as outbound proxy URI '%s' is not valid\n",
1420 (int) pj_strlen(&method->name), pj_strbuf(&method->name), ast_sorcery_object_get_id(endpoint),
1421 endpoint->outbound_proxy);
1422 pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
1423 return -1;
1424 }
1425
1426 ast_sip_mod_data_set((*tdata)->pool, (*tdata)->mod_data, supplement_module.id, MOD_DATA_CONTACT, ao2_bump(contact));
1427
1428 /* We can release this pool since request creation copied all the necessary
1429 * data into the outbound request's pool
1430 */
1431 pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
1432 return 0;
1433}
1434
1435int ast_sip_create_request(const char *method, struct pjsip_dialog *dlg,
1436 struct ast_sip_endpoint *endpoint, const char *uri,
1437 struct ast_sip_contact *contact, pjsip_tx_data **tdata)
1438{
1439 const pjsip_method *pmethod = get_pjsip_method(method);
1440
1441 if (!pmethod) {
1442 ast_log(LOG_WARNING, "Unknown method '%s'. Cannot send request\n", method);
1443 return -1;
1444 }
1445
1446 if (dlg) {
1447 return create_in_dialog_request(pmethod, dlg, tdata);
1448 } else {
1449 ast_assert(endpoint != NULL);
1450 return create_out_of_dialog_request(pmethod, endpoint, uri, contact, tdata);
1451 }
1452}
1453
1455
1457{
1458 struct ast_sip_supplement *iter;
1459 int inserted = 0;
1461
1463 if (iter->priority > supplement->priority) {
1465 inserted = 1;
1466 break;
1467 }
1468 }
1470
1471 if (!inserted) {
1473 }
1474}
1475
1477{
1478 struct ast_sip_supplement *iter;
1480
1482 if (supplement == iter) {
1484 break;
1485 }
1486 }
1488}
1489
1490static int send_in_dialog_request(pjsip_tx_data *tdata, struct pjsip_dialog *dlg)
1491{
1492 if (pjsip_dlg_send_request(dlg, tdata, -1, NULL) != PJ_SUCCESS) {
1493 ast_log(LOG_WARNING, "Unable to send in-dialog request.\n");
1494 return -1;
1495 }
1496 return 0;
1497}
1498
1499static pj_bool_t does_method_match(const pj_str_t *message_method, const char *supplement_method)
1500{
1501 pj_str_t method;
1502
1503 if (ast_strlen_zero(supplement_method)) {
1504 return PJ_TRUE;
1505 }
1506
1507 pj_cstr(&method, supplement_method);
1508
1509 return pj_stristr(&method, message_method) ? PJ_TRUE : PJ_FALSE;
1510}
1511
1512#define TIMER_INACTIVE 0
1513#define TIMEOUT_TIMER2 5
1514
1515/*! \brief Structure to hold information about an outbound request */
1517 /*! The endpoint associated with this request */
1519 /*! Information to be provided to the callback upon receipt of a response */
1520 void *token;
1521 /*! The callback to be called upon receipt of a response */
1522 void (*callback)(void *token, pjsip_event *e);
1523 /*! Number of challenges received. */
1524 unsigned int challenge_count;
1525};
1526
1527static void send_request_data_destroy(void *obj)
1528{
1529 struct send_request_data *req_data = obj;
1530
1531 ao2_cleanup(req_data->endpoint);
1532}
1533
1535 void *token, void (*callback)(void *token, pjsip_event *e))
1536{
1537 struct send_request_data *req_data;
1538
1539 req_data = ao2_alloc_options(sizeof(*req_data), send_request_data_destroy,
1541 if (!req_data) {
1542 return NULL;
1543 }
1544
1545 req_data->endpoint = ao2_bump(endpoint);
1546 req_data->token = token;
1547 req_data->callback = callback;
1548
1549 return req_data;
1550}
1551
1553 /*! Information to be provided to the callback upon receipt of a response */
1554 void *token;
1555 /*! The callback to be called upon receipt of a response */
1556 void (*callback)(void *token, pjsip_event *e);
1557 /*! Non-zero when the callback is called. */
1558 unsigned int cb_called;
1559 /*! Non-zero if endpt_send_request_cb() was called. */
1560 unsigned int send_cb_called;
1561 /*! Timeout timer. */
1562 pj_timer_entry *timeout_timer;
1563 /*! Original timeout. */
1564 pj_int32_t timeout;
1565 /*! The transmit data. */
1566 pjsip_tx_data *tdata;
1567};
1568
1569/*! \internal This function gets called by pjsip when the transaction ends,
1570 * even if it timed out. The lock prevents a race condition if both the pjsip
1571 * transaction timer and our own timer expire simultaneously.
1572 */
1573static void endpt_send_request_cb(void *token, pjsip_event *e)
1574{
1575 struct send_request_wrapper *req_wrapper = token;
1576 unsigned int cb_called;
1577
1578 /*
1579 * Needed because we cannot otherwise tell if this callback was
1580 * called when pjsip_endpt_send_request() returns error.
1581 */
1582 req_wrapper->send_cb_called = 1;
1583
1584 if (e->body.tsx_state.type == PJSIP_EVENT_TIMER) {
1585 ast_debug(2, "%p: PJSIP tsx timer expired\n", req_wrapper);
1586
1587 if (req_wrapper->timeout_timer
1588 && req_wrapper->timeout_timer->id != TIMEOUT_TIMER2) {
1589 ast_debug(3, "%p: Timeout already handled\n", req_wrapper);
1590 ao2_ref(req_wrapper, -1);
1591 return;
1592 }
1593 } else {
1594 ast_debug(2, "%p: PJSIP tsx response received\n", req_wrapper);
1595 }
1596
1597 ao2_lock(req_wrapper);
1598
1599 /* It's possible that our own timer was already processing while
1600 * we were waiting on the lock so check the timer id. If it's
1601 * still TIMER2 then we still need to process.
1602 */
1603 if (req_wrapper->timeout_timer
1604 && req_wrapper->timeout_timer->id == TIMEOUT_TIMER2) {
1605 int timers_cancelled = 0;
1606
1607 ast_debug(3, "%p: Cancelling timer\n", req_wrapper);
1608
1609 timers_cancelled = pj_timer_heap_cancel_if_active(
1610 pjsip_endpt_get_timer_heap(ast_sip_get_pjsip_endpoint()),
1611 req_wrapper->timeout_timer, TIMER_INACTIVE);
1612 if (timers_cancelled > 0) {
1613 /* If the timer was cancelled the callback will never run so
1614 * clean up its reference to the wrapper.
1615 */
1616 ast_debug(3, "%p: Timer cancelled\n", req_wrapper);
1617 ao2_ref(req_wrapper, -1);
1618 } else {
1619 /*
1620 * If it wasn't cancelled, it MAY be in the callback already
1621 * waiting on the lock. When we release the lock, it will
1622 * now know not to proceed.
1623 */
1624 ast_debug(3, "%p: Timer already expired\n", req_wrapper);
1625 }
1626 }
1627
1628 cb_called = req_wrapper->cb_called;
1629 req_wrapper->cb_called = 1;
1630 ao2_unlock(req_wrapper);
1631
1632 /* It's possible that our own timer expired and called the callbacks
1633 * so no need to call them again.
1634 */
1635 if (!cb_called && req_wrapper->callback) {
1636 req_wrapper->callback(req_wrapper->token, e);
1637 ast_debug(2, "%p: Callbacks executed\n", req_wrapper);
1638 }
1639
1640 ao2_ref(req_wrapper, -1);
1641}
1642
1643/*! \internal This function gets called by our own timer when it expires.
1644 * If the timer is cancelled however, the function does NOT get called.
1645 * The lock prevents a race condition if both the pjsip transaction timer
1646 * and our own timer expire simultaneously.
1647 */
1648static void send_request_timer_callback(pj_timer_heap_t *theap, pj_timer_entry *entry)
1649{
1650 struct send_request_wrapper *req_wrapper = entry->user_data;
1651 unsigned int cb_called;
1652
1653 ast_debug(2, "%p: Internal tsx timer expired after %d msec\n",
1654 req_wrapper, req_wrapper->timeout);
1655
1656 ao2_lock(req_wrapper);
1657 /*
1658 * If the id is not TIMEOUT_TIMER2 then the timer was cancelled
1659 * before we got the lock or it was already handled so just clean up.
1660 */
1661 if (entry->id != TIMEOUT_TIMER2) {
1662 ao2_unlock(req_wrapper);
1663 ast_debug(3, "%p: Timeout already handled\n", req_wrapper);
1664 ao2_ref(req_wrapper, -1);
1665 return;
1666 }
1667 entry->id = TIMER_INACTIVE;
1668
1669 ast_debug(3, "%p: Timer handled here\n", req_wrapper);
1670
1671 cb_called = req_wrapper->cb_called;
1672 req_wrapper->cb_called = 1;
1673 ao2_unlock(req_wrapper);
1674
1675 if (!cb_called && req_wrapper->callback) {
1676 pjsip_event event;
1677
1678 PJSIP_EVENT_INIT_TX_MSG(event, req_wrapper->tdata);
1679 event.body.tsx_state.type = PJSIP_EVENT_TIMER;
1680
1681 req_wrapper->callback(req_wrapper->token, &event);
1682 ast_debug(2, "%p: Callbacks executed\n", req_wrapper);
1683 }
1684
1685 ao2_ref(req_wrapper, -1);
1686}
1687
1689{
1690 struct send_request_wrapper *req_wrapper = obj;
1691
1692 pjsip_tx_data_dec_ref(req_wrapper->tdata);
1693 ast_debug(2, "%p: wrapper destroyed\n", req_wrapper);
1694}
1695
1696static pj_status_t endpt_send_request(struct ast_sip_endpoint *endpoint,
1697 pjsip_tx_data *tdata, pj_int32_t timeout, void *token, pjsip_endpt_send_callback cb)
1698{
1699 struct send_request_wrapper *req_wrapper;
1700 pj_status_t ret_val;
1701 pjsip_endpoint *endpt = ast_sip_get_pjsip_endpoint();
1702
1703 if (!cb && token) {
1704 /* Silly. Without a callback we cannot do anything with token. */
1705 pjsip_tx_data_dec_ref(tdata);
1706 return PJ_EINVAL;
1707 }
1708
1709 /* Create wrapper to detect if the callback was actually called on an error. */
1710 req_wrapper = ao2_alloc(sizeof(*req_wrapper), send_request_wrapper_destructor);
1711 if (!req_wrapper) {
1712 pjsip_tx_data_dec_ref(tdata);
1713 return PJ_ENOMEM;
1714 }
1715
1716 ast_debug(2, "%p: Wrapper created\n", req_wrapper);
1717
1718 req_wrapper->token = token;
1719 req_wrapper->callback = cb;
1720 req_wrapper->timeout = timeout;
1721 req_wrapper->timeout_timer = NULL;
1722 req_wrapper->tdata = tdata;
1723 /* Add a reference to tdata. The wrapper destructor cleans it up. */
1724 pjsip_tx_data_add_ref(tdata);
1725
1726 if (timeout > 0) {
1727 pj_time_val timeout_timer_val = { timeout / 1000, timeout % 1000 };
1728
1729 req_wrapper->timeout_timer = PJ_POOL_ALLOC_T(tdata->pool, pj_timer_entry);
1730
1731 ast_debug(2, "%p: Set timer to %d msec\n", req_wrapper, timeout);
1732
1733 pj_timer_entry_init(req_wrapper->timeout_timer, TIMEOUT_TIMER2,
1734 req_wrapper, send_request_timer_callback);
1735
1736 /* We need to insure that the wrapper and tdata are available if/when the
1737 * timer callback is executed.
1738 */
1739 ao2_ref(req_wrapper, +1);
1740 ret_val = pj_timer_heap_schedule(pjsip_endpt_get_timer_heap(endpt),
1741 req_wrapper->timeout_timer, &timeout_timer_val);
1742 if (ret_val != PJ_SUCCESS) {
1744 "Failed to set timer. Not sending %.*s request to endpoint %s.\n",
1745 (int) pj_strlen(&tdata->msg->line.req.method.name),
1746 pj_strbuf(&tdata->msg->line.req.method.name),
1747 endpoint ? ast_sorcery_object_get_id(endpoint) : "<unknown>");
1748 ao2_t_ref(req_wrapper, -2, "Drop timer and routine ref");
1749 pjsip_tx_data_dec_ref(tdata);
1750 return ret_val;
1751 }
1752 }
1753
1754 /* We need to insure that the wrapper and tdata are available when the
1755 * transaction callback is executed.
1756 */
1757 ao2_ref(req_wrapper, +1);
1758 ret_val = pjsip_endpt_send_request(endpt, tdata, -1, req_wrapper, endpt_send_request_cb);
1759 if (ret_val != PJ_SUCCESS) {
1760 char errmsg[PJ_ERR_MSG_SIZE];
1761
1762 if (!req_wrapper->send_cb_called) {
1763 /* endpt_send_request_cb is not expected to ever be called now. */
1764 ao2_ref(req_wrapper, -1);
1765 }
1766
1767 /* Complain of failure to send the request. */
1768 pj_strerror(ret_val, errmsg, sizeof(errmsg));
1769 ast_log(LOG_ERROR, "Error %d '%s' sending %.*s request to endpoint %s\n",
1770 (int) ret_val, errmsg, (int) pj_strlen(&tdata->msg->line.req.method.name),
1771 pj_strbuf(&tdata->msg->line.req.method.name),
1772 endpoint ? ast_sorcery_object_get_id(endpoint) : "<unknown>");
1773
1774 if (timeout > 0) {
1775 int timers_cancelled;
1776
1777 ao2_lock(req_wrapper);
1778 timers_cancelled = pj_timer_heap_cancel_if_active(
1779 pjsip_endpt_get_timer_heap(endpt),
1780 req_wrapper->timeout_timer, TIMER_INACTIVE);
1781 if (timers_cancelled > 0) {
1782 ao2_ref(req_wrapper, -1);
1783 }
1784
1785 /* Was the callback called? */
1786 if (req_wrapper->cb_called) {
1787 /*
1788 * Yes so we cannot report any error. The callback
1789 * has already freed any resources associated with
1790 * token.
1791 */
1792 ret_val = PJ_SUCCESS;
1793 } else {
1794 /*
1795 * No so we claim it is called so our caller can free
1796 * any resources associated with token because of
1797 * failure.
1798 */
1799 req_wrapper->cb_called = 1;
1800 }
1801 ao2_unlock(req_wrapper);
1802 } else if (req_wrapper->cb_called) {
1803 /*
1804 * We cannot report any error. The callback has
1805 * already freed any resources associated with
1806 * token.
1807 */
1808 ret_val = PJ_SUCCESS;
1809 }
1810 }
1811
1812 ao2_ref(req_wrapper, -1);
1813 return ret_val;
1814}
1815
1817{
1818 pjsip_via_hdr *via;
1819
1820 if (!tdata || !tdata->dest_info.addr.count
1821 || (tdata->dest_info.cur_addr == tdata->dest_info.addr.count - 1)) {
1822 /* No more addresses to try */
1823 return 0;
1824 }
1825
1826 /* Try next address */
1827 ++tdata->dest_info.cur_addr;
1828
1829 via = (pjsip_via_hdr*)pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);
1830 via->branch_param.slen = 0;
1831
1832 pjsip_tx_data_invalidate_msg(tdata);
1833
1834 return 1;
1835}
1836
1837static void send_request_cb(void *token, pjsip_event *e);
1838
1839static int check_request_status(struct send_request_data *req_data, pjsip_event *e)
1840{
1841 struct ast_sip_endpoint *endpoint;
1842 pjsip_transaction *tsx;
1843 pjsip_tx_data *tdata;
1844 int res = 0;
1845
1846 if (!(endpoint = ao2_bump(req_data->endpoint))) {
1847 return 0;
1848 }
1849
1850 tsx = e->body.tsx_state.tsx;
1851
1852 switch (tsx->status_code) {
1853 case 401:
1854 case 407:
1855 /* Resend the request with a challenge response if we are challenged. */
1856 res = ++req_data->challenge_count < MAX_RX_CHALLENGES /* Not in a challenge loop */
1858 e->body.tsx_state.src.rdata, tsx->last_tx, &tdata);
1859 break;
1860 case 408:
1861 case 503:
1862 if ((res = ast_sip_failover_request(tsx->last_tx))) {
1863 tdata = tsx->last_tx;
1864 /*
1865 * Bump the ref since it will be on a new transaction and
1866 * we don't want it to go away along with the old transaction.
1867 */
1868 pjsip_tx_data_add_ref(tdata);
1869 }
1870 break;
1871 }
1872
1873 if (res) {
1874 res = endpt_send_request(endpoint, tdata, -1,
1875 req_data, send_request_cb) == PJ_SUCCESS;
1876 }
1877
1878 ao2_ref(endpoint, -1);
1879 return res;
1880}
1881
1882static void send_request_cb(void *token, pjsip_event *e)
1883{
1884 struct send_request_data *req_data = token;
1885 pjsip_rx_data *challenge;
1886 struct ast_sip_supplement *supplement;
1887
1888 if (e->type == PJSIP_EVENT_TSX_STATE) {
1889 switch(e->body.tsx_state.type) {
1890 case PJSIP_EVENT_TRANSPORT_ERROR:
1891 case PJSIP_EVENT_TIMER:
1892 /*
1893 * Check the request status on transport error or timeout. A transport
1894 * error can occur when a TCP socket closes and that can be the result
1895 * of a 503. Also we may need to failover on a timeout (408).
1896 */
1897 if (check_request_status(req_data, e)) {
1898 return;
1899 }
1900 break;
1901 case PJSIP_EVENT_RX_MSG:
1902 challenge = e->body.tsx_state.src.rdata;
1903
1904 /*
1905 * Call any supplements that want to know about a response
1906 * with any received data.
1907 */
1909 AST_LIST_TRAVERSE(&supplements, supplement, next) {
1910 if (supplement->incoming_response
1911 && does_method_match(&challenge->msg_info.cseq->method.name,
1912 supplement->method)) {
1913 supplement->incoming_response(req_data->endpoint, challenge);
1914 }
1915 }
1917
1918 if (check_request_status(req_data, e)) {
1919 /*
1920 * Request with challenge response or failover sent.
1921 * Passed our req_data ref to the new request.
1922 */
1923 return;
1924 }
1925 break;
1926 default:
1927 ast_log(LOG_ERROR, "Unexpected PJSIP event %u\n", e->body.tsx_state.type);
1928 break;
1929 }
1930 }
1931
1932 if (req_data->callback) {
1933 req_data->callback(req_data->token, e);
1934 }
1935 ao2_ref(req_data, -1);
1936}
1937
1938int ast_sip_send_out_of_dialog_request(pjsip_tx_data *tdata,
1939 struct ast_sip_endpoint *endpoint, int timeout, void *token,
1940 void (*callback)(void *token, pjsip_event *e))
1941{
1942 struct ast_sip_supplement *supplement;
1943 struct send_request_data *req_data;
1944 struct ast_sip_contact *contact;
1945
1946 req_data = send_request_data_alloc(endpoint, token, callback);
1947 if (!req_data) {
1948 pjsip_tx_data_dec_ref(tdata);
1949 return -1;
1950 }
1951
1952 if (endpoint) {
1954 }
1955
1956 contact = ast_sip_mod_data_get(tdata->mod_data, supplement_module.id, MOD_DATA_CONTACT);
1957
1959 AST_LIST_TRAVERSE(&supplements, supplement, next) {
1960 if (supplement->outgoing_request
1961 && does_method_match(&tdata->msg->line.req.method.name, supplement->method)) {
1962 supplement->outgoing_request(endpoint, contact, tdata);
1963 }
1964 }
1966
1967 ast_sip_mod_data_set(tdata->pool, tdata->mod_data, supplement_module.id, MOD_DATA_CONTACT, NULL);
1968 ao2_cleanup(contact);
1969
1970 if (endpt_send_request(endpoint, tdata, timeout, req_data, send_request_cb)
1971 != PJ_SUCCESS) {
1972 ao2_cleanup(req_data);
1973 return -1;
1974 }
1975
1976 return 0;
1977}
1978
1979int ast_sip_send_request(pjsip_tx_data *tdata, struct pjsip_dialog *dlg,
1980 struct ast_sip_endpoint *endpoint, void *token,
1981 void (*callback)(void *token, pjsip_event *e))
1982{
1983 ast_assert(tdata->msg->type == PJSIP_REQUEST_MSG);
1984
1985 if (dlg) {
1986 return send_in_dialog_request(tdata, dlg);
1987 } else {
1988 return ast_sip_send_out_of_dialog_request(tdata, endpoint, -1, token, callback);
1989 }
1990}
1991
1992int ast_sip_set_outbound_proxy(pjsip_tx_data *tdata, const char *proxy)
1993{
1994 pjsip_route_hdr *route;
1995 static const pj_str_t ROUTE_HNAME = { "Route", 5 };
1996 pj_str_t tmp;
1997
1998 pj_strdup2_with_null(tdata->pool, &tmp, proxy);
1999 if (!(route = pjsip_parse_hdr(tdata->pool, &ROUTE_HNAME, tmp.ptr, tmp.slen, NULL))) {
2000 return -1;
2001 }
2002
2003 pj_list_insert_nodes_before(&tdata->msg->hdr, (pjsip_hdr*)route);
2004
2005 return 0;
2006}
2007
2008int ast_sip_add_header(pjsip_tx_data *tdata, const char *name, const char *value)
2009{
2010 pj_str_t hdr_name;
2011 pj_str_t hdr_value;
2012 pjsip_generic_string_hdr *hdr;
2013
2014 pj_cstr(&hdr_name, name);
2015 pj_cstr(&hdr_value, value);
2016
2017 hdr = pjsip_generic_string_hdr_create(tdata->pool, &hdr_name, &hdr_value);
2018
2019 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *) hdr);
2020 return 0;
2021}
2022
2023pjsip_generic_string_hdr *ast_sip_add_header2(pjsip_tx_data *tdata,
2024 const char *name, const char *value)
2025{
2026 pj_str_t hdr_name;
2027 pj_str_t hdr_value;
2028 pjsip_generic_string_hdr *hdr;
2029
2030 pj_cstr(&hdr_name, name);
2031 pj_cstr(&hdr_value, value);
2032
2033 hdr = pjsip_generic_string_hdr_create(tdata->pool, &hdr_name, &hdr_value);
2034
2035 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *) hdr);
2036 return hdr;
2037}
2038
2039static pjsip_msg_body *ast_body_to_pjsip_body(pj_pool_t *pool, const struct ast_sip_body *body)
2040{
2041 pj_str_t type;
2042 pj_str_t subtype;
2043 pj_str_t body_text;
2044
2045 pj_cstr(&type, body->type);
2046 pj_cstr(&subtype, body->subtype);
2047 pj_cstr(&body_text, body->body_text);
2048
2049 return pjsip_msg_body_create(pool, &type, &subtype, &body_text);
2050}
2051
2052int ast_sip_add_body(pjsip_tx_data *tdata, const struct ast_sip_body *body)
2053{
2054 pjsip_msg_body *pjsip_body = ast_body_to_pjsip_body(tdata->pool, body);
2055 tdata->msg->body = pjsip_body;
2056 return 0;
2057}
2058
2059int ast_sip_add_body_multipart(pjsip_tx_data *tdata, const struct ast_sip_body *bodies[], int num_bodies)
2060{
2061 int i;
2062 /* NULL for type and subtype automatically creates "multipart/mixed" */
2063 pjsip_msg_body *body = pjsip_multipart_create(tdata->pool, NULL, NULL);
2064
2065 for (i = 0; i < num_bodies; ++i) {
2066 pjsip_multipart_part *part = pjsip_multipart_create_part(tdata->pool);
2067 part->body = ast_body_to_pjsip_body(tdata->pool, bodies[i]);
2068 pjsip_multipart_add_part(tdata->pool, body, part);
2069 }
2070
2071 tdata->msg->body = body;
2072 return 0;
2073}
2074
2075int ast_sip_append_body(pjsip_tx_data *tdata, const char *body_text)
2076{
2077 size_t combined_size = strlen(body_text) + tdata->msg->body->len;
2078 struct ast_str *body_buffer = ast_str_alloca(combined_size);
2079
2080 ast_str_set(&body_buffer, 0, "%.*s%s", (int) tdata->msg->body->len, (char *) tdata->msg->body->data, body_text);
2081
2082 tdata->msg->body->data = pj_pool_alloc(tdata->pool, combined_size);
2083 pj_memcpy(tdata->msg->body->data, ast_str_buffer(body_buffer), combined_size);
2084 tdata->msg->body->len = combined_size;
2085
2086 return 0;
2087}
2088
2093
2098
2099#undef ast_sip_push_task
2100int ast_sip_push_task(struct ast_taskprocessor *serializer, int (*sip_task)(void *), void *task_data);
2101
2102int __ast_sip_push_task(struct ast_taskprocessor *serializer, int (*sip_task)(void *), void *task_data,
2103 const char *file, int line, const char *function)
2104{
2105 if (!serializer) {
2107 }
2108
2109 return __ast_taskprocessor_push(serializer, sip_task, task_data, file, line, function);
2110}
2111
2112/* ABI compatibility: Provide actual function symbol for external modules */
2113int ast_sip_push_task(struct ast_taskprocessor *serializer, int (*sip_task)(void *), void *task_data)
2114{
2115 return __ast_sip_push_task(serializer, sip_task, task_data, NULL, 0, NULL);
2116}
2117
2118/* ABI compatibility: Provide actual function symbols for wait functions */
2119#undef ast_sip_push_task_wait_servant
2120int ast_sip_push_task_wait_servant(struct ast_taskprocessor *serializer, int (*sip_task)(void *), void *task_data);
2121
2122int ast_sip_push_task_wait_servant(struct ast_taskprocessor *serializer, int (*sip_task)(void *), void *task_data)
2123{
2125}
2126
2127#undef ast_sip_push_task_synchronous
2128int ast_sip_push_task_synchronous(struct ast_taskprocessor *serializer, int (*sip_task)(void *), void *task_data);
2129
2130int ast_sip_push_task_synchronous(struct ast_taskprocessor *serializer, int (*sip_task)(void *), void *task_data)
2131{
2133}
2134
2135#undef ast_sip_push_task_wait_serializer
2136int ast_sip_push_task_wait_serializer(struct ast_taskprocessor *serializer, int (*sip_task)(void *), void *task_data);
2137
2139{
2141}
2142
2143struct sync_task_data {
2146 int complete;
2147 int fail;
2148 int (*task)(void *);
2149 void *task_data;
2150};
2151
2152static int sync_task(void *data)
2153{
2154 struct sync_task_data *std = data;
2155 int ret;
2156
2157 std->fail = std->task(std->task_data);
2158
2159 /*
2160 * Once we unlock std->lock after signaling, we cannot access
2161 * std again. The thread waiting within ast_sip_push_task_wait()
2162 * is free to continue and release its local variable (std).
2163 */
2164 ast_mutex_lock(&std->lock);
2165 std->complete = 1;
2166 ast_cond_signal(&std->cond);
2167 ret = std->fail;
2168 ast_mutex_unlock(&std->lock);
2169 return ret;
2170}
2171
2172static int __ast_sip_push_task_wait(struct ast_taskprocessor *serializer, int (*sip_task)(void *), void *task_data,
2173 const char *file, int line, const char *function)
2174{
2175 /* This method is an onion */
2176 struct sync_task_data std;
2177
2178 memset(&std, 0, sizeof(std));
2179 ast_mutex_init(&std.lock);
2180 ast_cond_init(&std.cond, NULL);
2181 std.task = sip_task;
2182 std.task_data = task_data;
2183
2184 if (__ast_sip_push_task(serializer, sync_task, &std, file, line, function)) {
2185 ast_mutex_destroy(&std.lock);
2186 ast_cond_destroy(&std.cond);
2187 return -1;
2188 }
2189
2190 ast_mutex_lock(&std.lock);
2191 while (!std.complete) {
2192 ast_cond_wait(&std.cond, &std.lock);
2193 }
2194 ast_mutex_unlock(&std.lock);
2195
2196 ast_mutex_destroy(&std.lock);
2197 ast_cond_destroy(&std.cond);
2198 return std.fail;
2199}
2200
2202 const char *file, int line, const char *function)
2203{
2205 return sip_task(task_data);
2206 }
2207
2208 return __ast_sip_push_task_wait(serializer, sip_task, task_data, file, line, function);
2209}
2210
2211int __ast_sip_push_task_synchronous(struct ast_taskprocessor *serializer, int (*sip_task)(void *), void *task_data,
2212 const char *file, int line, const char *function)
2213{
2214 return __ast_sip_push_task_wait_servant(serializer, sip_task, task_data, file, line, function);
2215}
2216
2218 const char *file, int line, const char *function)
2219{
2220 if (!serializer) {
2221 /* Caller doesn't care which PJSIP serializer the task executes under. */
2223 if (!serializer) {
2224 /* No serializer picked to execute the task */
2225 return -1;
2226 }
2227 }
2229 /*
2230 * We are the requested serializer so we must execute
2231 * the task now or deadlock waiting on ourself to
2232 * execute it.
2233 */
2234 return sip_task(task_data);
2235 }
2236
2237 return __ast_sip_push_task_wait(serializer, sip_task, task_data, file, line, function);
2238}
2239
2240void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
2241{
2242 size_t chars_to_copy = MIN(size - 1, pj_strlen(src));
2243 memcpy(dest, pj_strbuf(src), chars_to_copy);
2244 dest[chars_to_copy] = '\0';
2245}
2246
2247int ast_copy_pj_str2(char **dest, const pj_str_t *src)
2248{
2249 int res = ast_asprintf(dest, "%.*s", (int)pj_strlen(src), pj_strbuf(src));
2250
2251 if (res < 0) {
2252 *dest = NULL;
2253 }
2254
2255 return res;
2256}
2257
2258int ast_sip_are_media_types_equal(pjsip_media_type *a, pjsip_media_type *b)
2259{
2260 int rc = 0;
2261 if (a != NULL && b != NULL) {
2262 rc = pjsip_media_type_cmp(a, b, 0) ? 0 : 1;
2263 }
2264 return rc;
2265}
2266
2267int ast_sip_is_media_type_in(pjsip_media_type *a, ...)
2268{
2269 int rc = 0;
2270 pjsip_media_type *b = NULL;
2271 va_list ap;
2272
2273 ast_assert(a != NULL);
2274 va_start(ap, a);
2275
2276 while ((b = va_arg(ap, pjsip_media_type *)) != (pjsip_media_type *)SENTINEL) {
2277 if (pjsip_media_type_cmp(a, b, 0) == 0) {
2278 rc = 1;
2279 break;
2280 }
2281 }
2282 va_end(ap);
2283
2284 return rc;
2285}
2286
2287int ast_sip_is_content_type(pjsip_media_type *content_type, char *type, char *subtype)
2288{
2289 pjsip_media_type compare;
2290
2291 if (!content_type) {
2292 return 0;
2293 }
2294
2295 pjsip_media_type_init2(&compare, type, subtype);
2296
2297 return pjsip_media_type_cmp(content_type, &compare, 0) ? 0 : -1;
2298}
2299
2300pj_caching_pool caching_pool;
2301pj_pool_t *memory_pool;
2302pj_thread_t *monitor_thread;
2304
2305static void *monitor_thread_exec(void *endpt)
2306{
2307 while (monitor_continue) {
2308 const pj_time_val delay = {0, 10};
2309 pjsip_endpt_handle_events(ast_pjsip_endpoint, &delay);
2310 }
2311 return NULL;
2312}
2313
2314static void stop_monitor_thread(void)
2315{
2316 monitor_continue = 0;
2317 pj_thread_join(monitor_thread);
2318}
2319
2320AST_THREADSTORAGE(pj_thread_storage);
2321AST_THREADSTORAGE(servant_id_storage);
2322#define SIP_SERVANT_ID 0x5E2F1D
2323
2324static void sip_thread_start(void)
2325{
2326 pj_thread_desc *desc;
2327 pj_thread_t *thread;
2328 uint32_t *servant_id;
2329
2330 servant_id = ast_threadstorage_get(&servant_id_storage, sizeof(*servant_id));
2331 if (!servant_id) {
2332 ast_log(LOG_ERROR, "Could not set SIP servant ID in thread-local storage.\n");
2333 return;
2334 }
2335 *servant_id = SIP_SERVANT_ID;
2336
2337 desc = ast_threadstorage_get(&pj_thread_storage, sizeof(pj_thread_desc));
2338 if (!desc) {
2339 ast_log(LOG_ERROR, "Could not get thread desc from thread-local storage. Expect awful things to occur\n");
2340 return;
2341 }
2342 pj_bzero(*desc, sizeof(*desc));
2343
2344 if (pj_thread_register("Asterisk Thread", *desc, &thread) != PJ_SUCCESS) {
2345 ast_log(LOG_ERROR, "Couldn't register thread with PJLIB.\n");
2346 }
2347}
2348
2350{
2351 uint32_t *servant_id;
2352
2353 if (monitor_thread &&
2354 pthread_self() == *(pthread_t *)pj_thread_get_os_handle(monitor_thread)) {
2355 return 1;
2356 }
2357
2358 servant_id = ast_threadstorage_get(&servant_id_storage, sizeof(*servant_id));
2359 if (!servant_id) {
2360 return 0;
2361 }
2362
2363 return *servant_id == SIP_SERVANT_ID;
2364}
2365
2366void *ast_sip_dict_get(void *ht, const char *key)
2367{
2368 unsigned int hval = 0;
2369
2370 if (!ht) {
2371 return NULL;
2372 }
2373
2374 return pj_hash_get(ht, key, PJ_HASH_KEY_STRING, &hval);
2375}
2376
2377void *ast_sip_dict_set(pj_pool_t* pool, void *ht,
2378 const char *key, void *val)
2379{
2380 if (!ht) {
2381 ht = pj_hash_create(pool, 11);
2382 }
2383
2384 pj_hash_set(pool, ht, key, PJ_HASH_KEY_STRING, 0, val);
2385
2386 return ht;
2387}
2388
2389static pj_bool_t supplement_on_rx_request(pjsip_rx_data *rdata)
2390{
2391 struct ast_sip_supplement *supplement;
2392
2393 if (pjsip_rdata_get_dlg(rdata)) {
2394 return PJ_FALSE;
2395 }
2396
2398 AST_LIST_TRAVERSE(&supplements, supplement, next) {
2399 if (supplement->incoming_request
2400 && does_method_match(&rdata->msg_info.msg->line.req.method.name, supplement->method)) {
2401 struct ast_sip_endpoint *endpoint;
2402
2403 endpoint = ast_pjsip_rdata_get_endpoint(rdata);
2404 supplement->incoming_request(endpoint, rdata);
2405 ao2_cleanup(endpoint);
2406 }
2407 }
2409
2410 return PJ_FALSE;
2411}
2412
2413static void supplement_outgoing_response(pjsip_tx_data *tdata, struct ast_sip_endpoint *sip_endpoint)
2414{
2415 struct ast_sip_supplement *supplement;
2416 pjsip_cseq_hdr *cseq = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ, NULL);
2417 struct ast_sip_contact *contact = ast_sip_mod_data_get(tdata->mod_data, supplement_module.id, MOD_DATA_CONTACT);
2418
2419 if (sip_endpoint) {
2420 ast_sip_message_apply_transport(sip_endpoint->transport, tdata);
2421 }
2422
2424 AST_LIST_TRAVERSE(&supplements, supplement, next) {
2425 if (supplement->outgoing_response && does_method_match(&cseq->method.name, supplement->method)) {
2426 supplement->outgoing_response(sip_endpoint, contact, tdata);
2427 }
2428 }
2430
2431 ast_sip_mod_data_set(tdata->pool, tdata->mod_data, supplement_module.id, MOD_DATA_CONTACT, NULL);
2432 ao2_cleanup(contact);
2433}
2434
2435int ast_sip_send_response(pjsip_response_addr *res_addr, pjsip_tx_data *tdata, struct ast_sip_endpoint *sip_endpoint)
2436{
2437 pj_status_t status;
2438
2439 supplement_outgoing_response(tdata, sip_endpoint);
2440 status = pjsip_endpt_send_response(ast_sip_get_pjsip_endpoint(), res_addr, tdata, NULL, NULL);
2441 if (status != PJ_SUCCESS) {
2442 pjsip_tx_data_dec_ref(tdata);
2443 }
2444
2445 return status == PJ_SUCCESS ? 0 : -1;
2446}
2447
2448static void pool_destroy_callback(void *arg)
2449{
2450 pj_pool_t *pool = (pj_pool_t *)arg;
2451 pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
2452}
2453
2454static void clean_contact_from_tdata(pjsip_tx_data *tdata)
2455{
2456 struct ast_sip_contact *contact;
2457 contact = ast_sip_mod_data_get(tdata->mod_data, supplement_module.id, MOD_DATA_CONTACT);
2458 ao2_cleanup(contact);
2459 ast_sip_mod_data_set(tdata->pool, tdata->mod_data, supplement_module.id, MOD_DATA_CONTACT, NULL);
2460 pjsip_tx_data_dec_ref(tdata);
2461}
2462
2463int ast_sip_send_stateful_response(pjsip_rx_data *rdata, pjsip_tx_data *tdata, struct ast_sip_endpoint *sip_endpoint)
2464{
2465 pjsip_transaction *tsx;
2466 pj_grp_lock_t *tsx_glock;
2467 pj_pool_t *pool;
2468
2469 /* Create and initialize global lock pool */
2470 pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "stateful response", PJSIP_POOL_TSX_LEN, PJSIP_POOL_TSX_INC);
2471 if (!pool){
2472 /* ast_sip_create_response bumps the refcount of the contact and adds it to the tdata.
2473 * We'll leak that reference if we don't get rid of it here.
2474 */
2476 return -1;
2477 }
2478 /* Create with handler so that we can release the pool once the glock derefs out */
2479 if(pj_grp_lock_create_w_handler(pool, NULL, pool, &pool_destroy_callback, &tsx_glock) != PJ_SUCCESS) {
2481 pool_destroy_callback((void *) pool);
2482 return -1;
2483 }
2484 /* We need an additional reference as the qualify thread may destroy this out
2485 * from under us. Add it now before it gets added to the tsx. */
2486 pj_grp_lock_add_ref(tsx_glock);
2487
2488 if (pjsip_tsx_create_uas2(NULL, rdata, tsx_glock, &tsx) != PJ_SUCCESS) {
2490 pj_grp_lock_dec_ref(tsx_glock);
2491 return -1;
2492 }
2493
2494 pjsip_tsx_recv_msg(tsx, rdata);
2495 supplement_outgoing_response(tdata, sip_endpoint);
2496
2497 if (pjsip_tsx_send_msg(tsx, tdata) != PJ_SUCCESS) {
2498 pj_grp_lock_dec_ref(tsx_glock);
2499 pjsip_tx_data_dec_ref(tdata);
2500 return -1;
2501 }
2502
2503 pj_grp_lock_dec_ref(tsx_glock);
2504 return 0;
2505}
2506
2507int ast_sip_create_response(const pjsip_rx_data *rdata, int st_code,
2508 struct ast_sip_contact *contact, pjsip_tx_data **tdata)
2509{
2510 int res = pjsip_endpt_create_response(ast_sip_get_pjsip_endpoint(), rdata, st_code, NULL, tdata);
2511
2512 if (!res) {
2513 ast_sip_mod_data_set((*tdata)->pool, (*tdata)->mod_data, supplement_module.id, MOD_DATA_CONTACT, ao2_bump(contact));
2514 }
2515
2516 return res;
2517}
2518
2519int ast_sip_get_host_ip(int af, pj_sockaddr *addr)
2520{
2521 if (af == pj_AF_INET() && !ast_strlen_zero(host_ip_ipv4_string)) {
2522 pj_sockaddr_copy_addr(addr, &host_ip_ipv4);
2523 return 0;
2524 } else if (af == pj_AF_INET6() && !ast_strlen_zero(host_ip_ipv6_string)) {
2525 pj_sockaddr_copy_addr(addr, &host_ip_ipv6);
2526 return 0;
2527 }
2528
2529 return -1;
2530}
2531
2533{
2534 if (af == pj_AF_INET()) {
2535 return host_ip_ipv4_string;
2536 } else if (af == pj_AF_INET6()) {
2537 return host_ip_ipv6_string;
2538 }
2539
2540 return NULL;
2541}
2542
2544 char *buf, size_t buf_len)
2545{
2546 switch (dtmf) {
2547 case AST_SIP_DTMF_NONE:
2548 ast_copy_string(buf, "none", buf_len);
2549 break;
2551 ast_copy_string(buf, "rfc4733", buf_len);
2552 break;
2554 ast_copy_string(buf, "inband", buf_len);
2555 break;
2556 case AST_SIP_DTMF_INFO:
2557 ast_copy_string(buf, "info", buf_len);
2558 break;
2559 case AST_SIP_DTMF_AUTO:
2560 ast_copy_string(buf, "auto", buf_len);
2561 break;
2563 ast_copy_string(buf, "auto_info", buf_len);
2564 break;
2565 default:
2566 buf[0] = '\0';
2567 return -1;
2568 }
2569 return 0;
2570}
2571
2572int ast_sip_str_to_dtmf(const char * dtmf_mode)
2573{
2574 int result = -1;
2575
2576 if (!strcasecmp(dtmf_mode, "info")) {
2578 } else if (!strcasecmp(dtmf_mode, "rfc4733")) {
2580 } else if (!strcasecmp(dtmf_mode, "inband")) {
2582 } else if (!strcasecmp(dtmf_mode, "none")) {
2584 } else if (!strcasecmp(dtmf_mode, "auto")) {
2586 } else if (!strcasecmp(dtmf_mode, "auto_info")) {
2588 }
2589
2590 return result;
2591}
2592
2594{
2595 const char *value;
2596
2597 if (ast_sip_call_codec_pref_test(pref, LOCAL) && ast_sip_call_codec_pref_test(pref, INTERSECT) && ast_sip_call_codec_pref_test(pref, ALL)) {
2598 value = "local";
2599 } else if (ast_sip_call_codec_pref_test(pref, LOCAL) && ast_sip_call_codec_pref_test(pref, UNION) && ast_sip_call_codec_pref_test(pref, ALL)) {
2600 value = "local_merge";
2601 } else if (ast_sip_call_codec_pref_test(pref, LOCAL) && ast_sip_call_codec_pref_test(pref, INTERSECT) && ast_sip_call_codec_pref_test(pref, FIRST)) {
2602 value = "local_first";
2603 } else if (ast_sip_call_codec_pref_test(pref, REMOTE) && ast_sip_call_codec_pref_test(pref, INTERSECT) && ast_sip_call_codec_pref_test(pref, ALL)) {
2604 value = "remote";
2605 } else if (ast_sip_call_codec_pref_test(pref, REMOTE) && ast_sip_call_codec_pref_test(pref, UNION) && ast_sip_call_codec_pref_test(pref, ALL)) {
2606 value = "remote_merge";
2607 } else if (ast_sip_call_codec_pref_test(pref, REMOTE) && ast_sip_call_codec_pref_test(pref, UNION) && ast_sip_call_codec_pref_test(pref, FIRST)) {
2608 value = "remote_first";
2609 } else {
2610 value = "unknown";
2611 }
2612
2613 return value;
2614}
2615
2616int ast_sip_call_codec_str_to_pref(struct ast_flags *pref, const char *pref_str, int is_outgoing)
2617{
2618 pref->flags = 0;
2619
2620 if (strcmp(pref_str, "local") == 0) {
2622 } else if (is_outgoing && strcmp(pref_str, "local_merge") == 0) {
2624 } else if (strcmp(pref_str, "local_first") == 0) {
2626 } else if (strcmp(pref_str, "remote") == 0) {
2628 } else if (is_outgoing && strcmp(pref_str, "remote_merge") == 0) {
2630 } else if (strcmp(pref_str, "remote_first") == 0) {
2632 } else {
2633 return -1;
2634 }
2635
2636 return 0;
2637}
2638
2639/*!
2640 * \internal
2641 * \brief Set an ast_party_id name and number based on an identity header.
2642 * \param hdr From, P-Asserted-Identity, or Remote-Party-ID header on incoming message
2643 * \param[out] id The ID to set data on
2644 */
2645static void set_id_from_hdr(pjsip_fromto_hdr *hdr, struct ast_party_id *id)
2646{
2647 char cid_name[AST_CHANNEL_NAME];
2648 char cid_num[AST_CHANNEL_NAME];
2649 size_t cid_name_size = AST_CHANNEL_NAME;
2650 pjsip_name_addr *id_name_addr = (pjsip_name_addr *) hdr->uri;
2651 char *semi;
2653
2654 ast_copy_pj_str(cid_num, ast_sip_pjsip_uri_get_username(hdr->uri), sizeof(cid_num));
2655 /* Always truncate caller-id number at a semicolon. */
2656 semi = strchr(cid_num, ';');
2657 if (semi) {
2658 /*
2659 * We need to be able to handle URI's looking like
2660 * "sip:1235557890;phone-context=national@x.x.x.x;user=phone"
2661 *
2662 * Where the uri->user field will result in:
2663 * "1235557890;phone-context=national"
2664 *
2665 * People don't care about anything after the semicolon
2666 * showing up on their displays even though the RFC
2667 * allows the semicolon.
2668 */
2669 *semi = '\0';
2670 }
2671
2672 /*
2673 * It's safe to pass a NULL or empty string as the source.
2674 * The result will be an empty string assuming the destination
2675 * size was at least 1.
2676 */
2677 result = ast_utf8_replace_invalid_chars(cid_name, &cid_name_size,
2678 id_name_addr->display.ptr, id_name_addr->display.slen);
2679
2681 ast_log(LOG_WARNING, "CallerID Name '" PJSTR_PRINTF_SPEC
2682 "' for number '%s' has invalid UTF-8 characters which "
2683 "were replaced",
2684 PJSTR_PRINTF_VAR(id_name_addr->display), cid_num);
2685 }
2686
2687 ast_free(id->name.str);
2688 id->name.str = ast_strdup(cid_name);
2689 if (!ast_strlen_zero(cid_name)) {
2690 id->name.valid = 1;
2691 }
2692 ast_free(id->number.str);
2693 id->number.str = ast_strdup(cid_num);
2694 if (!ast_strlen_zero(cid_num)) {
2695 id->number.valid = 1;
2696 }
2697}
2698
2699/*!
2700 * \internal
2701 * \brief Get a P-Asserted-Identity or Remote-Party-ID header from an incoming message
2702 *
2703 * This function will parse the header as if it were a From header. This allows for us
2704 * to easily manipulate the URI, as well as add, modify, or remove parameters from the
2705 * header
2706 *
2707 * \param rdata The incoming message
2708 * \param header_name The name of the ID header to find
2709 * \retval NULL No ID header present or unable to parse ID header
2710 * \retval non-NULL The parsed ID header
2711 */
2712static pjsip_fromto_hdr *get_id_header(pjsip_rx_data *rdata, const pj_str_t *header_name)
2713{
2714 static const pj_str_t from = { "From", 4 };
2715 pj_str_t header_content;
2716 pjsip_fromto_hdr *parsed_hdr;
2717 pjsip_generic_string_hdr *ident = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg,
2718 header_name, NULL);
2719 int parsed_len;
2720
2721 if (!ident) {
2722 return NULL;
2723 }
2724
2725 pj_strdup_with_null(rdata->tp_info.pool, &header_content, &ident->hvalue);
2726
2727 parsed_hdr = pjsip_parse_hdr(rdata->tp_info.pool, &from, header_content.ptr,
2728 pj_strlen(&header_content), &parsed_len);
2729
2730 if (!parsed_hdr) {
2731 return NULL;
2732 }
2733
2734 return parsed_hdr;
2735}
2736
2737/*!
2738 * \internal
2739 * \brief Set an ast_party_id structure based on data in a P-Asserted-Identity header
2740 *
2741 * This makes use of \ref set_id_from_hdr for setting name and number. It uses
2742 * the contents of a Privacy header in order to set presentation information.
2743 *
2744 * \param rdata The incoming message
2745 * \param[out] id The ID to set
2746 * \retval 0 Successfully set the party ID
2747 * \retval non-zero Could not set the party ID
2748 */
2749static int set_id_from_pai(pjsip_rx_data *rdata, struct ast_party_id *id)
2750{
2751 static const pj_str_t pai_str = { "P-Asserted-Identity", 19 };
2752 static const pj_str_t privacy_str = { "Privacy", 7 };
2753 pjsip_fromto_hdr *pai_hdr = get_id_header(rdata, &pai_str);
2754 pjsip_generic_string_hdr *privacy;
2755
2756 if (!pai_hdr) {
2757 return -1;
2758 }
2759
2760 set_id_from_hdr(pai_hdr, id);
2761
2762 if (!id->number.valid) {
2763 return -1;
2764 }
2765
2766 privacy = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &privacy_str, NULL);
2767 if (!privacy || !pj_stricmp2(&privacy->hvalue, "none")) {
2768 id->number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
2769 id->name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
2770 } else {
2771 id->number.presentation = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
2772 id->name.presentation = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
2773 }
2774
2775 return 0;
2776}
2777
2778/*!
2779 * \internal
2780 * \brief Set an ast_party_id structure based on data in a Remote-Party-ID header
2781 *
2782 * This makes use of \ref set_id_from_hdr for setting name and number. It uses
2783 * the privacy and screen parameters in order to set presentation information.
2784 *
2785 * \param rdata The incoming message
2786 * \param[out] id The ID to set
2787 * \retval 0 Succesfully set the party ID
2788 * \retval non-zero Could not set the party ID
2789 */
2790static int set_id_from_rpid(pjsip_rx_data *rdata, struct ast_party_id *id)
2791{
2792 static const pj_str_t rpid_str = { "Remote-Party-ID", 15 };
2793 static const pj_str_t privacy_str = { "privacy", 7 };
2794 static const pj_str_t screen_str = { "screen", 6 };
2795 pjsip_fromto_hdr *rpid_hdr = get_id_header(rdata, &rpid_str);
2796 pjsip_param *screen;
2797 pjsip_param *privacy;
2798
2799 if (!rpid_hdr) {
2800 return -1;
2801 }
2802
2803 set_id_from_hdr(rpid_hdr, id);
2804
2805 if (!id->number.valid) {
2806 return -1;
2807 }
2808
2809 privacy = pjsip_param_find(&rpid_hdr->other_param, &privacy_str);
2810 screen = pjsip_param_find(&rpid_hdr->other_param, &screen_str);
2811 if (privacy && !pj_stricmp2(&privacy->value, "full")) {
2812 id->number.presentation = AST_PRES_RESTRICTED;
2813 id->name.presentation = AST_PRES_RESTRICTED;
2814 } else {
2815 id->number.presentation = AST_PRES_ALLOWED;
2816 id->name.presentation = AST_PRES_ALLOWED;
2817 }
2818 if (screen && !pj_stricmp2(&screen->value, "yes")) {
2819 id->number.presentation |= AST_PRES_USER_NUMBER_PASSED_SCREEN;
2820 id->name.presentation |= AST_PRES_USER_NUMBER_PASSED_SCREEN;
2821 } else {
2822 id->number.presentation |= AST_PRES_USER_NUMBER_UNSCREENED;
2823 id->name.presentation |= AST_PRES_USER_NUMBER_UNSCREENED;
2824 }
2825
2826 return 0;
2827}
2828
2829/*!
2830 * \internal
2831 * \brief Set an ast_party_id structure based on data in a From
2832 *
2833 * This makes use of \ref set_id_from_hdr for setting name and number. It uses
2834 * no information from the message in order to set privacy. It relies on endpoint
2835 * configuration for privacy information.
2836 *
2837 * \param rdata The incoming message
2838 * \param[out] id The ID to set
2839 * \retval 0 Succesfully set the party ID
2840 * \retval non-zero Could not set the party ID
2841 */
2842static int set_id_from_from(struct pjsip_rx_data *rdata, struct ast_party_id *id)
2843{
2844 pjsip_fromto_hdr *from = pjsip_msg_find_hdr(rdata->msg_info.msg,
2845 PJSIP_H_FROM, rdata->msg_info.msg->hdr.next);
2846
2847 if (!from) {
2848 /* This had better not happen */
2849 return -1;
2850 }
2851
2852 set_id_from_hdr(from, id);
2853
2854 if (!id->number.valid) {
2855 return -1;
2856 }
2857
2858 return 0;
2859}
2860
2861int ast_sip_set_id_connected_line(struct pjsip_rx_data *rdata, struct ast_party_id *id)
2862{
2863 return !set_id_from_pai(rdata, id) || !set_id_from_rpid(rdata, id) ? 0 : -1;
2864}
2865
2866int ast_sip_set_id_from_invite(struct pjsip_rx_data *rdata, struct ast_party_id *id, struct ast_party_id *default_id, int trust_inbound)
2867{
2868 if (trust_inbound && (!set_id_from_pai(rdata, id) || !set_id_from_rpid(rdata, id))) {
2869 /* Trusted: Check PAI and RPID */
2870 ast_free(id->tag);
2871 id->tag = ast_strdup(default_id->tag);
2872 return 0;
2873 }
2874 /* Not trusted: check the endpoint config or use From. */
2875 ast_party_id_copy(id, default_id);
2876 if (!default_id->number.valid) {
2877 set_id_from_from(rdata, id);
2878 }
2879 return 0;
2880}
2881
2882/*!
2883 * \brief Set name and number information on an identity header.
2884 *
2885 * \param pool Memory pool to use for string duplication
2886 * \param id_hdr A From, P-Asserted-Identity, or Remote-Party-ID header to modify
2887 * \param id The identity information to apply to the header
2888 */
2889void ast_sip_modify_id_header(pj_pool_t *pool, pjsip_fromto_hdr *id_hdr, const struct ast_party_id *id)
2890{
2891 pjsip_name_addr *id_name_addr;
2892 pjsip_sip_uri *id_uri;
2893
2894 id_name_addr = (pjsip_name_addr *) id_hdr->uri;
2895 id_uri = pjsip_uri_get_uri(id_name_addr->uri);
2896
2897 if (id->name.valid) {
2898 if (!ast_strlen_zero(id->name.str)) {
2899 int name_buf_len = strlen(id->name.str) * 2 + 1;
2900 char *name_buf = ast_alloca(name_buf_len);
2901
2902 ast_escape_quoted(id->name.str, name_buf, name_buf_len);
2903 pj_strdup2(pool, &id_name_addr->display, name_buf);
2904 } else {
2905 pj_strdup2(pool, &id_name_addr->display, NULL);
2906 }
2907 }
2908
2909 if (id->number.valid) {
2910 pj_strdup2(pool, &id_uri->user, id->number.str);
2911 }
2912}
2913
2914/*!
2915 * \brief Find a contact and insert a "user@" into its URI.
2916 *
2917 * \param to Original destination (for error messages only)
2918 * \param endpoint_name Endpoint name (for error messages only)
2919 * \param aors Command separated list of AORs
2920 * \param user The user to insert in the contact URI
2921 * \param uri Pointer to buffer in which to return the URI. Must be freed by caller.
2922 *
2923 * \return 0 Success
2924 * \return -1 Fail
2925 *
2926 * \note If the contact URI found for the endpoint already has a user in
2927 * its URI, it will be replaced by the user passed as an argument to this function.
2928 */
2929static int insert_user_in_contact_uri(const char *to, const char *endpoint_name, const char *aors,
2930 const char *user, char **uri)
2931{
2932 RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup);
2933 pj_pool_t *pool;
2934 pjsip_name_addr *name_addr;
2935 pjsip_sip_uri *sip_uri;
2936 int err = 0;
2937
2939 if (!contact) {
2940 ast_log(LOG_WARNING, "Dest: '%s'. Couldn't find contact for endpoint '%s'\n",
2941 to, endpoint_name);
2942 return -1;
2943 }
2944
2945 pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "uri-user-insert", 128, 128);
2946 if (!pool) {
2947 ast_log(LOG_WARNING, "Failed to allocate ParseUri endpoint pool.\n");
2948 return -1;
2949 }
2950
2951 name_addr = (pjsip_name_addr *) pjsip_parse_uri(pool, (char*)contact->uri, strlen(contact->uri), PJSIP_PARSE_URI_AS_NAMEADDR);
2952 if (!name_addr || (!PJSIP_URI_SCHEME_IS_SIP(name_addr->uri) && !PJSIP_URI_SCHEME_IS_SIPS(name_addr->uri))) {
2953 ast_log(LOG_WARNING, "Failed to parse URI '%s'\n", contact->uri);
2954 err = -1;
2955 goto out;
2956 }
2957
2958 ast_debug(3, "Dest: '%s' User: '%s' Endpoint: '%s' ContactURI: '%s'\n", to, user, endpoint_name, contact->uri);
2959
2960 sip_uri = pjsip_uri_get_uri(name_addr->uri);
2961 pj_strset2(&sip_uri->user, (char*)user);
2962
2963 *uri = ast_malloc(PJSIP_MAX_URL_SIZE);
2964 if (!(*uri)) {
2965 err = -1;
2966 goto out;
2967 }
2968 pjsip_uri_print(PJSIP_URI_IN_REQ_URI, name_addr, *uri, PJSIP_MAX_URL_SIZE);
2969
2970out:
2971 pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
2972
2973 return err;
2974}
2975
2976/*!
2977 * \internal
2978 * \brief Get endpoint and URI when the destination is only a single token
2979 *
2980 * "destination" could be one of the following:
2981 * \verbatim
2982 endpoint_name
2983 hostname
2984 * \endverbatim
2985 *
2986 * \param to
2987 * \param destination
2988 * \param get_default_outbound If nonzero, try to retrieve the default
2989 * outbound endpoint if no endpoint was found.
2990 * Otherwise, return NULL if no endpoint was found.
2991 * \param uri Pointer to URI variable. Must be freed by caller - even if the return value is NULL!
2992 * \return endpoint
2993 */
2994static struct ast_sip_endpoint *handle_single_token(const char *to, char *destination, int get_default_outbound, char **uri) {
2995 RAII_VAR(struct ast_sip_contact*, contact, NULL, ao2_cleanup);
2996 char *endpoint_name = NULL;
2997 struct ast_sip_endpoint *endpoint = NULL;
2998
2999 /*
3000 * If "destination" is just one token, it could be an endpoint name
3001 * or a hostname without a scheme.
3002 */
3003
3004 endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", destination);
3005 if (!endpoint) {
3006 /*
3007 * We can only assume it's a hostname.
3008 */
3009 char *temp_uri = ast_malloc(strlen(destination) + strlen("sip:") + 1);
3010 if (!temp_uri) {
3011 goto failure;
3012 }
3013 sprintf(temp_uri, "sip:%s", destination);
3014 *uri = temp_uri;
3015 if (get_default_outbound) {
3017 }
3018 ast_debug(3, "Dest: '%s' Didn't find endpoint so adding scheme and using URI '%s'%s\n",
3019 to, *uri, get_default_outbound ? " with default endpoint" : "");
3020 return endpoint;
3021 }
3022
3023 /*
3024 * It's an endpoint
3025 */
3026
3027 endpoint_name = destination;
3029 if (!contact) {
3030 ast_log(LOG_WARNING, "Dest: '%s'. Found endpoint '%s' but didn't find an aor/contact for it\n",
3031 to, endpoint_name);
3032 ao2_cleanup(endpoint);
3033 goto failure;
3034 }
3035
3036 *uri = ast_strdup(contact->uri);
3037 if (!(*uri)) {
3038 ao2_cleanup(endpoint);
3039 goto failure;
3040 }
3041
3042 ast_debug(3, "Dest: '%s' Found endpoint '%s' and found contact with URI '%s'\n",
3043 to, endpoint_name, *uri);
3044 return endpoint;
3045
3046failure:
3047 *uri = NULL;
3048 return NULL;
3049}
3050
3051/*!
3052 * \internal
3053 * \brief Get endpoint and URI when the destination contained a '/'
3054 *
3055 * "to" could be one of the following:
3056 * \verbatim
3057 endpoint/aor
3058 endpoint/<sip[s]:host>
3059 endpoint/<sip[s]:user@host>
3060 endpoint/"Bob" <sip[s]:host>
3061 endpoint/"Bob" <sip[s]:user@host>
3062 endpoint/sip[s]:host
3063 endpoint/sip[s]:user@host
3064 endpoint/host
3065 endpoint/user@host
3066 * \endverbatim
3067 *
3068 * \param to Destination
3069 * \param uri Pointer to URI variable. Must be freed by caller - even if the return value is NULL!
3070 * \param destination, slash, atsign, scheme
3071 * \return endpoint
3072 */
3073static struct ast_sip_endpoint *handle_slash(const char *to, char *destination, char **uri,
3074 char *slash, char *atsign, char *scheme)
3075{
3076 char *endpoint_name = NULL;
3077 struct ast_sip_endpoint *endpoint = NULL;
3078 struct ast_sip_contact *contact = NULL;
3079 char *user = NULL;
3080 char *afterslash = slash + 1;
3081 struct ast_sip_aor *aor;
3082
3083 if (ast_begins_with(destination, "PJSIP/")) {
3084 ast_debug(3, "Dest: '%s' Dialplan format'\n", to);
3085 /*
3086 * This has to be the form PJSIP/user@endpoint
3087 */
3088 if (!atsign || strchr(afterslash, '/')) {
3089 /*
3090 * If there's no "user@" or there's a slash somewhere after
3091 * "PJSIP/" then we go no further.
3092 */
3094 "Dest: '%s'. Destinations beginning with 'PJSIP/' must be in the form of 'PJSIP/user@endpoint'\n",
3095 to);
3096 goto failure;
3097 }
3098 *atsign = '\0';
3099 user = afterslash;
3100 endpoint_name = atsign + 1;
3101 ast_debug(3, "Dest: '%s' User: '%s' Endpoint: '%s'\n", to, user, endpoint_name);
3102 } else {
3103 /*
3104 * Either...
3105 * endpoint/aor
3106 * endpoint/uri
3107 */
3108 *slash = '\0';
3109 endpoint_name = destination;
3110 ast_debug(3, "Dest: '%s' Endpoint: '%s'\n", to, endpoint_name);
3111 }
3112
3113 endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", endpoint_name);
3114 if (!endpoint) {
3115 ast_log(LOG_WARNING, "Dest: '%s'. Didn't find endpoint with name '%s'\n",
3116 to, endpoint_name);
3117 goto failure;
3118 }
3119
3120 if (scheme) {
3121 /*
3122 * If we found a scheme, then everything after the slash MUST be a URI.
3123 * We don't need to do any further modification.
3124 */
3125 *uri = ast_strdup(afterslash);
3126 if (!(*uri)) {
3127 goto failure;
3128 }
3129 ast_debug(3, "Dest: '%s' Found endpoint '%s' and found URI '%s' after '/'\n",
3130 to, endpoint_name, *uri);
3131 return endpoint;
3132 }
3133
3134 if (user) {
3135 /*
3136 * This has to be the form PJSIP/user@endpoint
3137 */
3138 int rc;
3139
3140 /*
3141 * Set the return URI to be the endpoint's contact URI with the user
3142 * portion set to the user that was specified before the endpoint name.
3143 */
3144 rc = insert_user_in_contact_uri(to, endpoint_name, endpoint->aors, user, uri);
3145 if (rc != 0) {
3146 /*
3147 * insert_user_in_contact_uri prints the warning message.
3148 */
3149 goto failure;
3150 }
3151 ast_debug(3, "Dest: '%s' User: '%s' Endpoint: '%s' URI: '%s'\n", to, user,
3152 endpoint_name, *uri);
3153
3154 return endpoint;
3155 }
3156
3157 /*
3158 * We're now left with two possibilities...
3159 * endpoint/aor
3160 * endpoint/uri-without-scheme
3161 */
3162 aor = ast_sip_location_retrieve_aor(afterslash);
3163 if (!aor) {
3164 /*
3165 * It's probably a URI without a scheme but we don't have a way to tell
3166 * for sure. We're going to assume it is and prepend it with a scheme.
3167 */
3168 *uri = ast_malloc(strlen(afterslash) + strlen("sip:") + 1);
3169 if (!(*uri)) {
3170 goto failure;
3171 }
3172 sprintf(*uri, "sip:%s", afterslash);
3173 ast_debug(3, "Dest: '%s' Found endpoint '%s' but didn't find aor after '/' so using URI '%s'\n",
3174 to, endpoint_name, *uri);
3175 return endpoint;
3176 }
3177
3178 /*
3179 * Only one possibility left... There was an aor name after the slash.
3180 */
3181 ast_debug(3, "Dest: '%s' Found endpoint '%s' and found aor '%s' after '/'\n",
3182 to, endpoint_name, ast_sorcery_object_get_id(aor));
3183
3185 if (!contact) {
3186 ast_log(LOG_WARNING, "Dest: '%s'. Found endpoint '%s' but didn't find contact for aor '%s'\n",
3187 to, endpoint_name, ast_sorcery_object_get_id(aor));
3188 ao2_cleanup(aor);
3189 goto failure;
3190 }
3191
3192 *uri = ast_strdup(contact->uri);
3193 ao2_cleanup(contact);
3194 ao2_cleanup(aor);
3195 if (!(*uri)) {
3196 goto failure;
3197 }
3198
3199 ast_debug(3, "Dest: '%s' Found endpoint '%s' and found contact with URI '%s' for aor '%s'\n",
3200 to, endpoint_name, *uri, ast_sorcery_object_get_id(aor));
3201
3202 return endpoint;
3203
3204failure:
3205 ao2_cleanup(endpoint);
3206 *uri = NULL;
3207 return NULL;
3208}
3209
3210/*!
3211 * \internal
3212 * \brief Get endpoint and URI when the destination contained a '@' but no '/' or scheme
3213 *
3214 * "to" could be one of the following:
3215 * \verbatim
3216 <sip[s]:user@host>
3217 "Bob" <sip[s]:user@host>
3218 sip[s]:user@host
3219 user@host
3220 * \endverbatim
3221 *
3222 * \param to Destination
3223 * \param uri Pointer to URI variable. Must be freed by caller - even if the return value is NULL!
3224 * \param destination, slash, atsign, scheme
3225 * \param get_default_outbound If nonzero, try to retrieve the default
3226 * outbound endpoint if no endpoint was found.
3227 * Otherwise, return NULL if no endpoint was found.
3228 * \return endpoint
3229 */
3230static struct ast_sip_endpoint *handle_atsign(const char *to, char *destination, char **uri,
3231 char *slash, char *atsign, char *scheme, int get_default_outbound)
3232{
3233 char *endpoint_name = NULL;
3234 struct ast_sip_endpoint *endpoint = NULL;
3235 struct ast_sip_contact *contact = NULL;
3236 char *afterat = atsign + 1;
3237
3238 *atsign = '\0';
3239 endpoint_name = destination;
3240
3241 /* Apparently there may be ';<user_options>' after the endpoint name ??? */
3244 if (!endpoint) {
3245 /*
3246 * It's probably a uri with a user but without a scheme but we don't have a way to tell.
3247 * We're going to assume it is and prepend it with a scheme.
3248 */
3249 *uri = ast_malloc(strlen(to) + strlen("sip:") + 1);
3250 if (!(*uri)) {
3251 goto failure;
3252 }
3253 sprintf(*uri, "sip:%s", to);
3254 if (get_default_outbound) {
3256 }
3257 ast_debug(3, "Dest: '%s' Didn't find endpoint before the '@' so using URI '%s'%s\n",
3258 to, *uri, get_default_outbound ? " with default endpoint" : "");
3259 return endpoint;
3260 }
3261
3262 /*
3263 * OK, it's an endpoint and a domain (which we ignore)
3264 */
3266 if (!contact) {
3267 ast_log(LOG_WARNING, "Dest: '%s'. Found endpoint '%s' but didn't find contact\n",
3268 to, endpoint_name);
3269 goto failure;
3270 }
3271
3272 *uri = ast_strdup(contact->uri);
3273 ao2_cleanup(contact);
3274 if (!(*uri)) {
3275 goto failure;
3276 }
3277 ast_debug(3, "Dest: '%s' Found endpoint '%s' and found contact with URI '%s' (discarding domain %s)\n",
3278 to, endpoint_name, *uri, afterat);
3279
3280 return endpoint;
3281
3282failure:
3284 *uri = NULL;
3285 return NULL;
3286}
3287
3288struct ast_sip_endpoint *ast_sip_get_endpoint(const char *to, int get_default_outbound, char **uri)
3289{
3290 char *destination;
3291 char *slash = NULL;
3292 char *atsign = NULL;
3293 char *scheme = NULL;
3294 struct ast_sip_endpoint *endpoint = NULL;
3295
3296 destination = ast_strdupa(to);
3297
3298 slash = strchr(destination, '/');
3299 atsign = strchr(destination, '@');
3300 scheme = S_OR(strstr(destination, "sip:"), strstr(destination, "sips:"));
3301
3302 if (!slash && !atsign && !scheme) {
3303 /*
3304 * If there's only a single token, it can be either...
3305 * endpoint
3306 * host
3307 */
3308 return handle_single_token(to, destination, get_default_outbound, uri);
3309 }
3310
3311 if (slash) {
3312 /*
3313 * If there's a '/', then the form must be one of the following...
3314 * PJSIP/user@endpoint
3315 * endpoint/aor
3316 * endpoint/uri
3317 */
3318 return handle_slash(to, destination, uri, slash, atsign, scheme);
3319 }
3320
3321 if (atsign && !scheme) {
3322 /*
3323 * If there's an '@' but no scheme then it's either following an endpoint name
3324 * and being followed by a domain name (which we discard).
3325 * OR is's a user@host uri without a scheme. It's probably the latter but because
3326 * endpoint@domain looks just like user@host, we'll test for endpoint first.
3327 */
3328 return handle_atsign(to, destination, uri, slash, atsign, scheme, get_default_outbound);
3329 }
3330
3331 /*
3332 * If all else fails, we assume it's a URI or just a hostname.
3333 */
3334 if (scheme) {
3335 *uri = ast_strdup(destination);
3336 if (!(*uri)) {
3337 goto failure;
3338 }
3339 ast_debug(3, "Dest: '%s' Didn't find an endpoint but did find a scheme so using URI '%s'%s\n",
3340 to, *uri, get_default_outbound ? " with default endpoint" : "");
3341 } else {
3342 *uri = ast_malloc(strlen(destination) + strlen("sip:") + 1);
3343 if (!(*uri)) {
3344 goto failure;
3345 }
3346 sprintf(*uri, "sip:%s", destination);
3347 ast_debug(3, "Dest: '%s' Didn't find an endpoint and didn't find scheme so adding scheme and using URI '%s'%s\n",
3348 to, *uri, get_default_outbound ? " with default endpoint" : "");
3349 }
3350 if (get_default_outbound) {
3352 }
3353
3354 return endpoint;
3355
3356failure:
3357 ao2_cleanup(endpoint);
3358 *uri = NULL;
3359 return NULL;
3360}
3361
3362int ast_sip_update_to_uri(pjsip_tx_data *tdata, const char *to)
3363{
3364 pjsip_name_addr *parsed_name_addr;
3365 pjsip_sip_uri *sip_uri;
3366 pjsip_name_addr *tdata_name_addr;
3367 pjsip_sip_uri *tdata_sip_uri;
3368 pjsip_to_hdr *to_hdr;
3369 char *buf = NULL;
3370#define DEBUG_BUF_SIZE 256
3371
3372 parsed_name_addr = (pjsip_name_addr *) pjsip_parse_uri(tdata->pool, (char*)to, strlen(to),
3373 PJSIP_PARSE_URI_AS_NAMEADDR);
3374
3375 if (!parsed_name_addr || (!PJSIP_URI_SCHEME_IS_SIP(parsed_name_addr->uri)
3376 && !PJSIP_URI_SCHEME_IS_SIPS(parsed_name_addr->uri))) {
3377 ast_log(LOG_WARNING, "To address '%s' is not a valid SIP/SIPS URI\n", to);
3378 return -1;
3379 }
3380
3381 sip_uri = pjsip_uri_get_uri(parsed_name_addr->uri);
3382 if (DEBUG_ATLEAST(3)) {
3384 pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, sip_uri, buf, DEBUG_BUF_SIZE);
3385 ast_debug(3, "Parsed To: %.*s %s\n", (int)parsed_name_addr->display.slen,
3386 parsed_name_addr->display.ptr, buf);
3387 }
3388
3389 to_hdr = PJSIP_MSG_TO_HDR(tdata->msg);
3390 tdata_name_addr = to_hdr ? (pjsip_name_addr *) to_hdr->uri : NULL;
3391 if (!tdata_name_addr || (!PJSIP_URI_SCHEME_IS_SIP(tdata_name_addr->uri)
3392 && !PJSIP_URI_SCHEME_IS_SIPS(tdata_name_addr->uri))) {
3393 /* Highly unlikely but we have to check */
3394 ast_log(LOG_WARNING, "tdata To address '%s' is not a valid SIP/SIPS URI\n", to);
3395 return -1;
3396 }
3397
3398 tdata_sip_uri = pjsip_uri_get_uri(tdata_name_addr->uri);
3399 if (DEBUG_ATLEAST(3)) {
3400 buf[0] = '\0';
3401 pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, tdata_sip_uri, buf, DEBUG_BUF_SIZE);
3402 ast_debug(3, "Original tdata To: %.*s %s\n", (int)tdata_name_addr->display.slen,
3403 tdata_name_addr->display.ptr, buf);
3404 }
3405
3406 /* Replace the uri */
3407 pjsip_sip_uri_assign(tdata->pool, tdata_sip_uri, sip_uri);
3408 /* The display name isn't part of the URI so we need to replace it separately */
3409 pj_strdup(tdata->pool, &tdata_name_addr->display, &parsed_name_addr->display);
3410
3411 if (DEBUG_ATLEAST(3)) {
3412 buf[0] = '\0';
3413 pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, tdata_sip_uri, buf, 256);
3414 ast_debug(3, "New tdata To: %.*s %s\n", (int)tdata_name_addr->display.slen,
3415 tdata_name_addr->display.ptr, buf);
3416 }
3417
3418 return 0;
3419#undef DEBUG_BUF_SIZE
3420}
3421
3422int ast_sip_update_from(pjsip_tx_data *tdata, char *from)
3423{
3424 pjsip_name_addr *name_addr;
3425 pjsip_sip_uri *uri;
3426 pjsip_name_addr *parsed_name_addr;
3427 pjsip_from_hdr *from_hdr;
3428
3429 if (ast_strlen_zero(from)) {
3430 return 0;
3431 }
3432
3433 from_hdr = PJSIP_MSG_FROM_HDR(tdata->msg);
3434 if (!from_hdr) {
3435 return -1;
3436 }
3437 name_addr = (pjsip_name_addr *) from_hdr->uri;
3438 uri = pjsip_uri_get_uri(name_addr);
3439
3440 parsed_name_addr = (pjsip_name_addr *) pjsip_parse_uri(tdata->pool, from,
3441 strlen(from), PJSIP_PARSE_URI_AS_NAMEADDR);
3442 if (parsed_name_addr) {
3443 pjsip_sip_uri *parsed_uri;
3444
3445 if (!PJSIP_URI_SCHEME_IS_SIP(parsed_name_addr->uri)
3446 && !PJSIP_URI_SCHEME_IS_SIPS(parsed_name_addr->uri)) {
3447 ast_log(LOG_WARNING, "From address '%s' is not a valid SIP/SIPS URI\n", from);
3448 return -1;
3449 }
3450
3451 parsed_uri = pjsip_uri_get_uri(parsed_name_addr->uri);
3452
3453 if (pj_strlen(&parsed_name_addr->display)) {
3454 pj_strdup(tdata->pool, &name_addr->display, &parsed_name_addr->display);
3455 }
3456
3457 /* Unlike the To header, we only want to replace the user, host and port */
3458 pj_strdup(tdata->pool, &uri->user, &parsed_uri->user);
3459 pj_strdup(tdata->pool, &uri->host, &parsed_uri->host);
3460 uri->port = parsed_uri->port;
3461
3462 return 0;
3463 } else {
3464 /* assume it is 'user[@domain]' format */
3465 char *domain = strchr(from, '@');
3466
3467 if (domain) {
3468 pj_str_t pj_from;
3469
3470 pj_strset3(&pj_from, from, domain);
3471 pj_strdup(tdata->pool, &uri->user, &pj_from);
3472
3473 pj_strdup2(tdata->pool, &uri->host, domain + 1);
3474 } else {
3475 pj_strdup2(tdata->pool, &uri->user, from);
3476 }
3477
3478 return 0;
3479 }
3480
3481 return -1;
3482}
3483
3484static void remove_request_headers(pjsip_endpoint *endpt)
3485{
3486 const pjsip_hdr *request_headers = pjsip_endpt_get_request_headers(endpt);
3487 pjsip_hdr *iter = request_headers->next;
3488
3489 while (iter != request_headers) {
3490 pjsip_hdr *to_erase = iter;
3491 iter = iter->next;
3492 pj_list_erase(to_erase);
3493 }
3494}
3495
3500
3502{
3503 return sip_threadpool;
3504}
3505
3506int ast_sip_is_uri_sip_sips(pjsip_uri *uri)
3507{
3508 return (PJSIP_URI_SCHEME_IS_SIP(uri) || PJSIP_URI_SCHEME_IS_SIPS(uri));
3509}
3510
3511int ast_sip_is_allowed_uri(pjsip_uri *uri)
3512{
3513 return (ast_sip_is_uri_sip_sips(uri) || PJSIP_URI_SCHEME_IS_TEL(uri));
3514}
3515
3516const pj_str_t *ast_sip_pjsip_uri_get_username(pjsip_uri *uri)
3517{
3518 if (ast_sip_is_uri_sip_sips(uri)) {
3519 pjsip_sip_uri *sip_uri = pjsip_uri_get_uri(uri);
3520 if (!sip_uri) {
3521 return &AST_PJ_STR_EMPTY;
3522 }
3523 return &sip_uri->user;
3524 } else if (PJSIP_URI_SCHEME_IS_TEL(uri)) {
3525 pjsip_tel_uri *tel_uri = pjsip_uri_get_uri(uri);
3526 if (!tel_uri) {
3527 return &AST_PJ_STR_EMPTY;
3528 }
3529 return &tel_uri->number;
3530 }
3531
3532 return &AST_PJ_STR_EMPTY;
3533}
3534
3535const pj_str_t *ast_sip_pjsip_uri_get_hostname(pjsip_uri *uri)
3536{
3537 if (ast_sip_is_uri_sip_sips(uri)) {
3538 pjsip_sip_uri *sip_uri = pjsip_uri_get_uri(uri);
3539 if (!sip_uri) {
3540 return &AST_PJ_STR_EMPTY;
3541 }
3542 return &sip_uri->host;
3543 } else if (PJSIP_URI_SCHEME_IS_TEL(uri)) {
3544 return &AST_PJ_STR_EMPTY;
3545 }
3546
3547 return &AST_PJ_STR_EMPTY;
3548}
3549
3550struct pjsip_param *ast_sip_pjsip_uri_get_other_param(pjsip_uri *uri, const pj_str_t *param_str)
3551{
3552 if (ast_sip_is_uri_sip_sips(uri)) {
3553 pjsip_sip_uri *sip_uri = pjsip_uri_get_uri(uri);
3554 if (!sip_uri) {
3555 return NULL;
3556 }
3557 return pjsip_param_find(&sip_uri->other_param, param_str);
3558 } else if (PJSIP_URI_SCHEME_IS_TEL(uri)) {
3559 pjsip_tel_uri *tel_uri = pjsip_uri_get_uri(uri);
3560 if (!tel_uri) {
3561 return NULL;
3562 }
3563 return pjsip_param_find(&tel_uri->other_param, param_str);
3564 }
3565
3566 return NULL;
3567}
3568
3569/*! \brief Convert SIP hangup causes to Asterisk hangup causes */
3570const int ast_sip_hangup_sip2cause(int cause)
3571{
3572 /* Possible values taken from causes.h */
3573
3574 switch(cause) {
3575 case 401: /* Unauthorized */
3577 case 403: /* Not found */
3579 case 404: /* Not found */
3580 return AST_CAUSE_UNALLOCATED;
3581 case 405: /* Method not allowed */
3583 case 407: /* Proxy authentication required */
3585 case 408: /* No reaction */
3587 case 409: /* Conflict */
3589 case 410: /* Gone */
3591 case 411: /* Length required */
3593 case 413: /* Request entity too large */
3595 case 414: /* Request URI too large */
3597 case 415: /* Unsupported media type */
3599 case 420: /* Bad extension */
3601 case 480: /* No answer */
3602 return AST_CAUSE_NO_ANSWER;
3603 case 481: /* No answer */
3605 case 482: /* Loop detected */
3607 case 483: /* Too many hops */
3608 return AST_CAUSE_NO_ANSWER;
3609 case 484: /* Address incomplete */
3611 case 485: /* Ambiguous */
3612 return AST_CAUSE_UNALLOCATED;
3613 case 486: /* Busy everywhere */
3614 return AST_CAUSE_BUSY;
3615 case 487: /* Request terminated */
3617 case 488: /* No codecs approved */
3619 case 491: /* Request pending */
3621 case 493: /* Undecipherable */
3623 case 500: /* Server internal failure */
3624 return AST_CAUSE_FAILURE;
3625 case 501: /* Call rejected */
3627 case 502:
3629 case 503: /* Service unavailable */
3630 return AST_CAUSE_CONGESTION;
3631 case 504: /* Gateway timeout */
3633 case 505: /* SIP version not supported */
3635 case 600: /* Busy everywhere */
3636 return AST_CAUSE_USER_BUSY;
3637 case 603: /* Decline */
3639 case 604: /* Does not exist anywhere */
3640 return AST_CAUSE_UNALLOCATED;
3641 case 606: /* Not acceptable */
3643 default:
3644 if (cause < 500 && cause >= 400) {
3645 /* 4xx class error that is unknown - someting wrong with our request */
3647 } else if (cause < 600 && cause >= 500) {
3648 /* 5xx class error - problem in the remote end */
3649 return AST_CAUSE_CONGESTION;
3650 } else if (cause < 700 && cause >= 600) {
3651 /* 6xx - global errors in the 4xx class */
3653 }
3654 return AST_CAUSE_NORMAL;
3655 }
3656 /* Never reached */
3657 return 0;
3658}
3659
3661 int code;
3662 const char *long_name;
3663 const char *short_name;
3664};
3665
3666/*
3667 * This map was generated from sip_msg.h with
3668 *
3669 * sed -n -r -e 's/^\s+(PJSIP_SC_([^ =]+))\s*=\s*[0-9]+,/{ \1, "\1", "\2" },/gp' \
3670 * third-party/pjproject/source/pjsip/include/pjsip/sip_msg.h
3671 *
3672 */
3673static const struct response_code_map rc_map[] = {
3674 { PJSIP_SC_NULL, "PJSIP_SC_NULL", "NULL" },
3675 { PJSIP_SC_TRYING, "PJSIP_SC_TRYING", "TRYING" },
3676 { PJSIP_SC_RINGING, "PJSIP_SC_RINGING", "RINGING" },
3677 { PJSIP_SC_CALL_BEING_FORWARDED, "PJSIP_SC_CALL_BEING_FORWARDED", "CALL_BEING_FORWARDED" },
3678 { PJSIP_SC_QUEUED, "PJSIP_SC_QUEUED", "QUEUED" },
3679 { PJSIP_SC_PROGRESS, "PJSIP_SC_PROGRESS", "PROGRESS" },
3680 { PJSIP_SC_EARLY_DIALOG_TERMINATED, "PJSIP_SC_EARLY_DIALOG_TERMINATED", "EARLY_DIALOG_TERMINATED" },
3681 { PJSIP_SC_OK, "PJSIP_SC_OK", "OK" },
3682 { PJSIP_SC_ACCEPTED, "PJSIP_SC_ACCEPTED", "ACCEPTED" },
3683 { PJSIP_SC_NO_NOTIFICATION, "PJSIP_SC_NO_NOTIFICATION", "NO_NOTIFICATION" },
3684 { PJSIP_SC_MULTIPLE_CHOICES, "PJSIP_SC_MULTIPLE_CHOICES", "MULTIPLE_CHOICES" },
3685 { PJSIP_SC_MOVED_PERMANENTLY, "PJSIP_SC_MOVED_PERMANENTLY", "MOVED_PERMANENTLY" },
3686 { PJSIP_SC_MOVED_TEMPORARILY, "PJSIP_SC_MOVED_TEMPORARILY", "MOVED_TEMPORARILY" },
3687 { PJSIP_SC_USE_PROXY, "PJSIP_SC_USE_PROXY", "USE_PROXY" },
3688 { PJSIP_SC_ALTERNATIVE_SERVICE, "PJSIP_SC_ALTERNATIVE_SERVICE", "ALTERNATIVE_SERVICE" },
3689 { PJSIP_SC_BAD_REQUEST, "PJSIP_SC_BAD_REQUEST", "BAD_REQUEST" },
3690 { PJSIP_SC_UNAUTHORIZED, "PJSIP_SC_UNAUTHORIZED", "UNAUTHORIZED" },
3691 { PJSIP_SC_PAYMENT_REQUIRED, "PJSIP_SC_PAYMENT_REQUIRED", "PAYMENT_REQUIRED" },
3692 { PJSIP_SC_FORBIDDEN, "PJSIP_SC_FORBIDDEN", "FORBIDDEN" },
3693 { PJSIP_SC_NOT_FOUND, "PJSIP_SC_NOT_FOUND", "NOT_FOUND" },
3694 { PJSIP_SC_METHOD_NOT_ALLOWED, "PJSIP_SC_METHOD_NOT_ALLOWED", "METHOD_NOT_ALLOWED" },
3695 { PJSIP_SC_NOT_ACCEPTABLE, "PJSIP_SC_NOT_ACCEPTABLE", "NOT_ACCEPTABLE" },
3696 { PJSIP_SC_PROXY_AUTHENTICATION_REQUIRED, "PJSIP_SC_PROXY_AUTHENTICATION_REQUIRED", "PROXY_AUTHENTICATION_REQUIRED" },
3697 { PJSIP_SC_REQUEST_TIMEOUT, "PJSIP_SC_REQUEST_TIMEOUT", "REQUEST_TIMEOUT" },
3698 { PJSIP_SC_CONFLICT, "PJSIP_SC_CONFLICT", "CONFLICT" },
3699 { PJSIP_SC_GONE, "PJSIP_SC_GONE", "GONE" },
3700 { PJSIP_SC_LENGTH_REQUIRED, "PJSIP_SC_LENGTH_REQUIRED", "LENGTH_REQUIRED" },
3701 { PJSIP_SC_CONDITIONAL_REQUEST_FAILED, "PJSIP_SC_CONDITIONAL_REQUEST_FAILED", "CONDITIONAL_REQUEST_FAILED" },
3702 { PJSIP_SC_REQUEST_ENTITY_TOO_LARGE, "PJSIP_SC_REQUEST_ENTITY_TOO_LARGE", "REQUEST_ENTITY_TOO_LARGE" },
3703 { PJSIP_SC_REQUEST_URI_TOO_LONG, "PJSIP_SC_REQUEST_URI_TOO_LONG", "REQUEST_URI_TOO_LONG" },
3704 { PJSIP_SC_UNSUPPORTED_MEDIA_TYPE, "PJSIP_SC_UNSUPPORTED_MEDIA_TYPE", "UNSUPPORTED_MEDIA_TYPE" },
3705 { PJSIP_SC_UNSUPPORTED_URI_SCHEME, "PJSIP_SC_UNSUPPORTED_URI_SCHEME", "UNSUPPORTED_URI_SCHEME" },
3706 { PJSIP_SC_UNKNOWN_RESOURCE_PRIORITY, "PJSIP_SC_UNKNOWN_RESOURCE_PRIORITY", "UNKNOWN_RESOURCE_PRIORITY" },
3707 { PJSIP_SC_BAD_EXTENSION, "PJSIP_SC_BAD_EXTENSION", "BAD_EXTENSION" },
3708 { PJSIP_SC_EXTENSION_REQUIRED, "PJSIP_SC_EXTENSION_REQUIRED", "EXTENSION_REQUIRED" },
3709 { PJSIP_SC_SESSION_TIMER_TOO_SMALL, "PJSIP_SC_SESSION_TIMER_TOO_SMALL", "SESSION_TIMER_TOO_SMALL" },
3710 { PJSIP_SC_INTERVAL_TOO_BRIEF, "PJSIP_SC_INTERVAL_TOO_BRIEF", "INTERVAL_TOO_BRIEF" },
3711 { PJSIP_SC_BAD_LOCATION_INFORMATION, "PJSIP_SC_BAD_LOCATION_INFORMATION", "BAD_LOCATION_INFORMATION" },
3712 { PJSIP_SC_USE_IDENTITY_HEADER, "PJSIP_SC_USE_IDENTITY_HEADER", "USE_IDENTITY_HEADER" },
3713 { PJSIP_SC_PROVIDE_REFERRER_HEADER, "PJSIP_SC_PROVIDE_REFERRER_HEADER", "PROVIDE_REFERRER_HEADER" },
3714 { PJSIP_SC_FLOW_FAILED, "PJSIP_SC_FLOW_FAILED", "FLOW_FAILED" },
3715 { PJSIP_SC_ANONIMITY_DISALLOWED, "PJSIP_SC_ANONIMITY_DISALLOWED", "ANONIMITY_DISALLOWED" },
3716 { PJSIP_SC_BAD_IDENTITY_INFO, "PJSIP_SC_BAD_IDENTITY_INFO", "BAD_IDENTITY_INFO" },
3717 { PJSIP_SC_UNSUPPORTED_CERTIFICATE, "PJSIP_SC_UNSUPPORTED_CERTIFICATE", "UNSUPPORTED_CERTIFICATE" },
3718 { PJSIP_SC_INVALID_IDENTITY_HEADER, "PJSIP_SC_INVALID_IDENTITY_HEADER", "INVALID_IDENTITY_HEADER" },
3719 { PJSIP_SC_FIRST_HOP_LACKS_OUTBOUND_SUPPORT, "PJSIP_SC_FIRST_HOP_LACKS_OUTBOUND_SUPPORT", "FIRST_HOP_LACKS_OUTBOUND_SUPPORT" },
3720 { PJSIP_SC_MAX_BREADTH_EXCEEDED, "PJSIP_SC_MAX_BREADTH_EXCEEDED", "MAX_BREADTH_EXCEEDED" },
3721 { PJSIP_SC_BAD_INFO_PACKAGE, "PJSIP_SC_BAD_INFO_PACKAGE", "BAD_INFO_PACKAGE" },
3722 { PJSIP_SC_CONSENT_NEEDED, "PJSIP_SC_CONSENT_NEEDED", "CONSENT_NEEDED" },
3723 { PJSIP_SC_TEMPORARILY_UNAVAILABLE, "PJSIP_SC_TEMPORARILY_UNAVAILABLE", "TEMPORARILY_UNAVAILABLE" },
3724 { PJSIP_SC_CALL_TSX_DOES_NOT_EXIST, "PJSIP_SC_CALL_TSX_DOES_NOT_EXIST", "CALL_TSX_DOES_NOT_EXIST" },
3725 { PJSIP_SC_LOOP_DETECTED, "PJSIP_SC_LOOP_DETECTED", "LOOP_DETECTED" },
3726 { PJSIP_SC_TOO_MANY_HOPS, "PJSIP_SC_TOO_MANY_HOPS", "TOO_MANY_HOPS" },
3727 { PJSIP_SC_ADDRESS_INCOMPLETE, "PJSIP_SC_ADDRESS_INCOMPLETE", "ADDRESS_INCOMPLETE" },
3728 { PJSIP_SC_BUSY_HERE, "PJSIP_SC_BUSY_HERE", "BUSY_HERE" },
3729 { PJSIP_SC_REQUEST_TERMINATED, "PJSIP_SC_REQUEST_TERMINATED", "REQUEST_TERMINATED" },
3730 { PJSIP_SC_NOT_ACCEPTABLE_HERE, "PJSIP_SC_NOT_ACCEPTABLE_HERE", "NOT_ACCEPTABLE_HERE" },
3731 { PJSIP_SC_BAD_EVENT, "PJSIP_SC_BAD_EVENT", "BAD_EVENT" },
3732 { PJSIP_SC_REQUEST_UPDATED, "PJSIP_SC_REQUEST_UPDATED", "REQUEST_UPDATED" },
3733 { PJSIP_SC_REQUEST_PENDING, "PJSIP_SC_REQUEST_PENDING", "REQUEST_PENDING" },
3734 { PJSIP_SC_UNDECIPHERABLE, "PJSIP_SC_UNDECIPHERABLE", "UNDECIPHERABLE" },
3735 { PJSIP_SC_SECURITY_AGREEMENT_NEEDED, "PJSIP_SC_SECURITY_AGREEMENT_NEEDED", "SECURITY_AGREEMENT_NEEDED" },
3736 { PJSIP_SC_INTERNAL_SERVER_ERROR, "PJSIP_SC_INTERNAL_SERVER_ERROR", "INTERNAL_SERVER_ERROR" },
3737 { PJSIP_SC_NOT_IMPLEMENTED, "PJSIP_SC_NOT_IMPLEMENTED", "NOT_IMPLEMENTED" },
3738 { PJSIP_SC_BAD_GATEWAY, "PJSIP_SC_BAD_GATEWAY", "BAD_GATEWAY" },
3739 { PJSIP_SC_SERVICE_UNAVAILABLE, "PJSIP_SC_SERVICE_UNAVAILABLE", "SERVICE_UNAVAILABLE" },
3740 { PJSIP_SC_SERVER_TIMEOUT, "PJSIP_SC_SERVER_TIMEOUT", "SERVER_TIMEOUT" },
3741 { PJSIP_SC_VERSION_NOT_SUPPORTED, "PJSIP_SC_VERSION_NOT_SUPPORTED", "VERSION_NOT_SUPPORTED" },
3742 { PJSIP_SC_MESSAGE_TOO_LARGE, "PJSIP_SC_MESSAGE_TOO_LARGE", "MESSAGE_TOO_LARGE" },
3743 { PJSIP_SC_PUSH_NOTIFICATION_SERVICE_NOT_SUPPORTED, "PJSIP_SC_PUSH_NOTIFICATION_SERVICE_NOT_SUPPORTED", "PUSH_NOTIFICATION_SERVICE_NOT_SUPPORTED" },
3744 { PJSIP_SC_PRECONDITION_FAILURE, "PJSIP_SC_PRECONDITION_FAILURE", "PRECONDITION_FAILURE" },
3745 { PJSIP_SC_BUSY_EVERYWHERE, "PJSIP_SC_BUSY_EVERYWHERE", "BUSY_EVERYWHERE" },
3746 { PJSIP_SC_DECLINE, "PJSIP_SC_DECLINE", "DECLINE" },
3747 { PJSIP_SC_DOES_NOT_EXIST_ANYWHERE, "PJSIP_SC_DOES_NOT_EXIST_ANYWHERE", "DOES_NOT_EXIST_ANYWHERE" },
3748 { PJSIP_SC_NOT_ACCEPTABLE_ANYWHERE, "PJSIP_SC_NOT_ACCEPTABLE_ANYWHERE", "NOT_ACCEPTABLE_ANYWHERE" },
3749 { PJSIP_SC_UNWANTED, "PJSIP_SC_UNWANTED", "UNWANTED" },
3750 { PJSIP_SC_REJECTED, "PJSIP_SC_REJECTED", "REJECTED" },
3751};
3752
3753int ast_sip_str2rc(const char *name)
3754{
3755 int i;
3756
3757 if (ast_strlen_zero(name)) {
3758 return -1;
3759 }
3760
3761 for (i = 0; i < ARRAY_LEN(rc_map); i++) {
3762 if (strcasecmp(rc_map[i].short_name, name) == 0 ||
3763 strcasecmp(rc_map[i].long_name, name) == 0) {
3764 return rc_map[i].code;
3765 }
3766 }
3767
3768 return -1;
3769}
3770
3771
3772#ifdef TEST_FRAMEWORK
3773AST_TEST_DEFINE(xml_sanitization_end_null)
3774{
3775 char sanitized[8];
3776
3777 switch (cmd) {
3778 case TEST_INIT:
3779 info->name = "xml_sanitization_end_null";
3780 info->category = "/res/res_pjsip/";
3781 info->summary = "Ensure XML sanitization works as expected with a long string";
3782 info->description = "This test sanitizes a string which exceeds the output\n"
3783 "buffer size. Once done the string is confirmed to be NULL terminated.";
3784 return AST_TEST_NOT_RUN;
3785 case TEST_EXECUTE:
3786 break;
3787 }
3788
3789 ast_sip_sanitize_xml("aaaaaaaaaaaa", sanitized, sizeof(sanitized));
3790 if (sanitized[7] != '\0') {
3791 ast_test_status_update(test, "Sanitized XML string is not null-terminated when it should be\n");
3792 return AST_TEST_FAIL;
3793 }
3794
3795 return AST_TEST_PASS;
3796}
3797
3798AST_TEST_DEFINE(xml_sanitization_exceeds_buffer)
3799{
3800 char sanitized[8];
3801
3802 switch (cmd) {
3803 case TEST_INIT:
3804 info->name = "xml_sanitization_exceeds_buffer";
3805 info->category = "/res/res_pjsip/";
3806 info->summary = "Ensure XML sanitization does not exceed buffer when output won't fit";
3807 info->description = "This test sanitizes a string which before sanitization would\n"
3808 "fit within the output buffer. After sanitization, however, the string would\n"
3809 "exceed the buffer. Once done the string is confirmed to be NULL terminated.";
3810 return AST_TEST_NOT_RUN;
3811 case TEST_EXECUTE:
3812 break;
3813 }
3814
3815 ast_sip_sanitize_xml("<><><>&", sanitized, sizeof(sanitized));
3816 if (sanitized[7] != '\0') {
3817 ast_test_status_update(test, "Sanitized XML string is not null-terminated when it should be\n");
3818 return AST_TEST_FAIL;
3819 }
3820
3821 return AST_TEST_PASS;
3822}
3823#endif
3824
3825/*!
3826 * \internal
3827 * \brief Reload configuration within a PJSIP thread
3828 */
3836
3837static int unload_pjsip(void *data)
3838{
3839 /*
3840 * These calls need the pjsip endpoint and serializer to clean up.
3841 * If they're not set, then there's nothing to clean up anyway.
3842 */
3853 }
3854
3855 if (monitor_thread) {
3858 }
3859
3860 if (memory_pool) {
3861 /* This mimics the behavior of pj_pool_safe_release
3862 * which was introduced in pjproject 2.6.
3863 */
3864 pj_pool_t *temp_pool = memory_pool;
3865
3866 memory_pool = NULL;
3867 pj_pool_release(temp_pool);
3868 }
3869
3871
3872 if (caching_pool.lock) {
3874 }
3875
3876 pj_shutdown();
3877
3878 return 0;
3879}
3880
3881static int load_pjsip(void)
3882{
3883 const unsigned int flags = 0; /* no port, no brackets */
3884 pj_status_t status;
3885
3886 /* The third parameter is just copied from
3887 * example code from PJLIB. This can be adjusted
3888 * if necessary.
3889 */
3891 if (pjsip_endpt_create(&caching_pool.factory, "SIP", &ast_pjsip_endpoint) != PJ_SUCCESS) {
3892 ast_log(LOG_ERROR, "Failed to create PJSIP endpoint structure. Aborting load\n");
3893 goto error;
3894 }
3895
3896 /* PJSIP will automatically try to add a Max-Forwards header. Since we want to control that,
3897 * we need to stop PJSIP from doing it automatically
3898 */
3900
3901 memory_pool = pj_pool_create(&caching_pool.factory, "SIP", 1024, 1024, NULL);
3902 if (!memory_pool) {
3903 ast_log(LOG_ERROR, "Failed to create memory pool for SIP. Aborting load\n");
3904 goto error;
3905 }
3906
3907 if (!pj_gethostip(pj_AF_INET(), &host_ip_ipv4)) {
3908 pj_sockaddr_print(&host_ip_ipv4, host_ip_ipv4_string, sizeof(host_ip_ipv4_string), flags);
3909 ast_verb(3, "Local IPv4 address determined to be: %s\n", host_ip_ipv4_string);
3910 }
3911
3912 if (!pj_gethostip(pj_AF_INET6(), &host_ip_ipv6)) {
3913 pj_sockaddr_print(&host_ip_ipv6, host_ip_ipv6_string, sizeof(host_ip_ipv6_string), flags);
3914 ast_verb(3, "Local IPv6 address determined to be: %s\n", host_ip_ipv6_string);
3915 }
3916
3917 pjsip_tsx_layer_init_module(ast_pjsip_endpoint);
3918 pjsip_ua_init_module(ast_pjsip_endpoint, NULL);
3919
3920 monitor_continue = 1;
3921 status = pj_thread_create(memory_pool, "SIP", (pj_thread_proc *) &monitor_thread_exec,
3922 NULL, PJ_THREAD_DEFAULT_STACK_SIZE * 2, 0, &monitor_thread);
3923 if (status != PJ_SUCCESS) {
3924 ast_log(LOG_ERROR, "Failed to start SIP monitor thread. Aborting load\n");
3925 goto error;
3926 }
3927
3929
3930error:
3932}
3933
3934/*
3935 * This is a place holder function to ensure that pjmedia_strerr() is at
3936 * least directly referenced by this module to ensure that the loader
3937 * linker will link to the function. If a module only indirectly
3938 * references a function from another module, such as a callback parameter
3939 * to a function, the loader linker has been known to miss the link.
3940 */
3941void never_called_res_pjsip(void);
3943{
3944 pjmedia_strerror(0, NULL, 0);
3945}
3946
3947/* Definitions of media types declared "extern" in res_pjsip.h */
3960
3961static int load_module(void)
3962{
3964
3965 /* pjproject and config_system need to be initialized before all else */
3966 if (pj_init() != PJ_SUCCESS) {
3968 }
3969
3970 if (pjlib_util_init() != PJ_SUCCESS) {
3971 goto error;
3972 }
3973
3974 /* Register PJMEDIA error codes for SDP parsing errors */
3975 if (pj_register_strerror(PJMEDIA_ERRNO_START, PJ_ERRNO_SPACE_SIZE, pjmedia_strerror)
3976 != PJ_SUCCESS) {
3977 ast_log(LOG_WARNING, "Failed to register pjmedia error codes. Codes will not be decoded.\n");
3978 }
3979
3980 /* Initialize common media types */
3981 pjsip_media_type_init2(&pjsip_media_type_application_json, "application", "json");
3982 pjsip_media_type_init2(&pjsip_media_type_application_media_control_xml, "application", "media_control+xml");
3983 pjsip_media_type_init2(&pjsip_media_type_application_pidf_xml, "application", "pidf+xml");
3984 pjsip_media_type_init2(&pjsip_media_type_application_xpidf_xml, "application", "xpidf+xml");
3985 pjsip_media_type_init2(&pjsip_media_type_application_cpim_xpidf_xml, "application", "cpim-xpidf+xml");
3986 pjsip_media_type_init2(&pjsip_media_type_application_rlmi_xml, "application", "rlmi+xml");
3987 pjsip_media_type_init2(&pjsip_media_type_application_sdp, "application", "sdp");
3988 pjsip_media_type_init2(&pjsip_media_type_application_simple_message_summary, "application", "simple-message-summary");
3989 pjsip_media_type_init2(&pjsip_media_type_multipart_alternative, "multipart", "alternative");
3990 pjsip_media_type_init2(&pjsip_media_type_multipart_mixed, "multipart", "mixed");
3991 pjsip_media_type_init2(&pjsip_media_type_multipart_related, "multipart", "related");
3992 pjsip_media_type_init2(&pjsip_media_type_text_plain, "text", "plain");
3993
3994
3996 ast_log(LOG_ERROR, "Failed to initialize SIP 'system' configuration section. Aborting load\n");
3997 goto error;
3998 }
3999
4000 /* The serializer needs threadpool and threadpool needs pjproject to be initialized so it's next */
4002 options.thread_start = sip_thread_start;
4004 if (!sip_threadpool) {
4005 goto error;
4006 }
4007
4009 "pjsip/default", SERIALIZER_POOL_SIZE, sip_threadpool, -1);
4010 if (!sip_serializer_pool) {
4011 ast_log(LOG_ERROR, "Failed to create SIP serializer pool. Aborting load\n");
4012 goto error;
4013 }
4014
4016 ast_log(LOG_ERROR, "Failed to start scheduler. Aborting load\n");
4017 goto error;
4018 }
4019
4020 /* Now load all the pjproject infrastructure. */
4021 if (load_pjsip()) {
4022 goto error;
4023 }
4024
4026 ast_log(LOG_ERROR, "Failed to initialize SIP transport monitor. Aborting load\n");
4027 goto error;
4028 }
4029
4032
4034 ast_log(LOG_ERROR, "Failed to pre-initialize OPTIONS handling. Aborting load\n");
4035 goto error;
4036 }
4037
4039 ast_log(LOG_ERROR, "Failed to initialize SIP configuration. Aborting load\n");
4040 goto error;
4041 }
4042
4045
4047 ast_log(LOG_ERROR, "Failed to initialize SIP transport management. Aborting load\n");
4048 goto error;
4049 }
4050
4052 ast_log(LOG_ERROR, "Failed to register distributor module. Aborting load\n");
4053 goto error;
4054 }
4055
4057 ast_log(LOG_ERROR, "Failed to initialize supplement hooks. Aborting load\n");
4058 goto error;
4059 }
4060
4062 ast_log(LOG_ERROR, "Failed to initialize OPTIONS handling. Aborting load\n");
4063 goto error;
4064 }
4065
4066 /*
4067 * It is OK to prune the contacts now that
4068 * ast_res_pjsip_init_options_handling() has added the contact observer
4069 * of res/res_pjsip/pjsip_options.c to sorcery (to ensure that any
4070 * pruned contacts are removed from this module's data structure).
4071 */
4073
4075 ast_log(LOG_ERROR, "Failed to initialize message IP updating. Aborting load\n");
4076 goto error;
4077 }
4078
4080
4081 AST_TEST_REGISTER(xml_sanitization_end_null);
4082 AST_TEST_REGISTER(xml_sanitization_exceeds_buffer);
4083
4085
4086error:
4088
4089 /* These functions all check for NULLs and are safe to call at any time */
4093
4095}
4096
4097static int reload_module(void)
4098{
4099 /*
4100 * We must wait for the reload to complete so multiple
4101 * reloads cannot happen at the same time.
4102 */
4104 ast_log(LOG_WARNING, "Failed to reload PJSIP\n");
4105 return -1;
4106 }
4107
4108 return 0;
4109}
4110
4111static int unload_module(void)
4112{
4113 AST_TEST_UNREGISTER(xml_sanitization_end_null);
4114 AST_TEST_UNREGISTER(xml_sanitization_exceeds_buffer);
4116
4117 /* The thread this is called from cannot call PJSIP/PJLIB functions,
4118 * so we have to push the work to the threadpool to handle
4119 */
4124
4125 return 0;
4126}
4127
4129 .support_level = AST_MODULE_SUPPORT_CORE,
4130 .load = load_module,
4131 .unload = unload_module,
4133 .load_pri = AST_MODPRI_CHANNEL_DEPEND - 5,
4134 .requires = "dnsmgr,res_pjproject,res_sorcery_config,res_sorcery_memory,res_sorcery_astdb",
4135 .optional_modules = "res_geolocation,res_statsd",
Access Control of various sorts.
void ast_cli_unregister_multiple(void)
Definition ael_main.c:408
static int compare(const char *text, const char *template)
jack_status_t status
Definition app_jack.c:149
const char * str
Definition app_jack.c:150
enum queue_result id
Definition app_queue.c:1771
pthread_t thread
Definition app_sla.c:335
ast_mutex_t lock
Definition app_sla.c:337
Asterisk main include file. File version handling, generic pbx functions.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition astmm.h:288
#define ast_free(a)
Definition astmm.h:180
#define ast_strdup(str)
A wrapper for strdup()
Definition astmm.h:241
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition astmm.h:298
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition astmm.h:267
#define ast_calloc(num, len)
A wrapper for calloc()
Definition astmm.h:202
#define ast_malloc(len)
A wrapper for malloc()
Definition astmm.h:191
#define ast_log
Definition astobj2.c:42
#define ao2_t_ref(o, delta, tag)
Definition astobj2.h:460
@ CMP_MATCH
Definition astobj2.h:1027
@ CMP_STOP
Definition astobj2.h:1028
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition astobj2.h:367
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition astobj2.h:1693
#define ao2_cleanup(obj)
Definition astobj2.h:1934
#define ao2_unlock(a)
Definition astobj2.h:729
#define ao2_lock(a)
Definition astobj2.h:717
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition astobj2.h:459
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition astobj2.h:404
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition astobj2.h:480
#define ao2_alloc(data_size, destructor_fn)
Definition astobj2.h:409
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
#define AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED
Definition callerid.h:449
#define AST_PRES_USER_NUMBER_UNSCREENED
Definition callerid.h:426
#define AST_PRES_USER_NUMBER_PASSED_SCREEN
Definition callerid.h:427
#define AST_PRES_RESTRICTED
Definition callerid.h:433
#define AST_PRES_ALLOWED
Definition callerid.h:432
#define AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED
Definition callerid.h:437
Internal Asterisk hangup causes.
#define AST_CAUSE_CONGESTION
Definition causes.h:153
#define AST_CAUSE_UNALLOCATED
Definition causes.h:98
#define AST_CAUSE_INTERWORKING
Definition causes.h:146
#define AST_CAUSE_NUMBER_CHANGED
Definition causes.h:112
#define AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
Definition causes.h:130
#define AST_CAUSE_INVALID_NUMBER_FORMAT
Definition causes.h:116
#define AST_CAUSE_FAILURE
Definition causes.h:150
#define AST_CAUSE_DESTINATION_OUT_OF_ORDER
Definition causes.h:115
#define AST_CAUSE_NO_USER_RESPONSE
Definition causes.h:108
#define AST_CAUSE_NORMAL_TEMPORARY_FAILURE
Definition causes.h:122
#define AST_CAUSE_NORMAL
Definition causes.h:151
#define AST_CAUSE_CALL_REJECTED
Definition causes.h:111
#define AST_CAUSE_FACILITY_REJECTED
Definition causes.h:117
#define AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE
Definition causes.h:143
#define AST_CAUSE_NO_ROUTE_DESTINATION
Definition causes.h:100
#define AST_CAUSE_BUSY
Definition causes.h:149
#define AST_CAUSE_NO_ANSWER
Definition causes.h:109
#define AST_CAUSE_USER_BUSY
Definition causes.h:107
static const char desc[]
Definition cdr_radius.c:84
static PGresult * result
Definition cel_pgsql.c:84
static const char type[]
#define AST_CHANNEL_NAME
Definition channel.h:173
void ast_party_id_copy(struct ast_party_id *dest, const struct ast_party_id *src)
Copy the source party id information to the destination party id.
Definition channel.c:1751
size_t current
static struct ast_channel * callback(struct ast_channelstorage_instance *driver, ao2_callback_data_fn *cb_fn, void *arg, void *data, int ao2_flags, int rdlock)
Standard Command Line Interface.
#define CLI_SHOWUSAGE
Definition cli.h:45
#define CLI_SUCCESS
Definition cli.h:44
#define AST_CLI_DEFINE(fn, txt,...)
Definition cli.h:197
void ast_cli(int fd, const char *fmt,...)
Definition clicompat.c:6
@ CLI_INIT
Definition cli.h:152
@ CLI_GENERATE
Definition cli.h:153
#define CLI_FAILURE
Definition cli.h:46
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition cli.h:265
#define SENTINEL
Definition compiler.h:87
int sip_cli_print_global(struct ast_sip_cli_context *context)
void ast_sip_destroy_system(void)
int sip_cli_print_system(struct ast_sip_cli_context *context)
int ast_sip_initialize_system(void)
void ast_sip_initialize_dns(void)
void sip_get_threadpool_options(struct ast_threadpool_options *threadpool_options)
static struct ao2_container * transport_states
char buf[BUFSIZE]
Definition eagi_proxy.c:66
Generic File Format Support. Should be included by clients of the file handling routines....
#define AST_DIGIT_ANY
Definition file.h:48
static const char name[]
Definition format_mp3.c:68
int __ast_sip_push_task_synchronous(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data, const char *file, int line, const char *function)
Push a task to SIP servants and wait for it to complete.
Definition res_pjsip.c:2211
#define ast_sip_push_task(serializer, sip_task, task_data)
Definition res_pjsip.h:2082
#define ast_sip_push_task_synchronous(serializer, sip_task, task_data)
Definition res_pjsip.h:2130
int __ast_sip_push_task_wait_servant(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data, const char *file, int line, const char *function)
Push a task to SIP servants and wait for it to complete.
Definition res_pjsip.c:2201
struct ast_taskprocessor * ast_sip_create_serializer(const char *name)
Create a new serializer for SIP tasks.
Definition res_pjsip.c:2094
struct ast_taskprocessor * ast_sip_create_serializer_group(const char *name, struct ast_serializer_shutdown_group *shutdown_group)
Create a new serializer for SIP tasks.
Definition res_pjsip.c:2089
#define ast_sip_push_task_wait_serializer(serializer, sip_task, task_data)
Definition res_pjsip.h:2177
int ast_sip_thread_is_servant(void)
Determine if the current thread is a SIP servant thread.
Definition res_pjsip.c:2349
#define ast_sip_push_task_wait_servant(serializer, sip_task, task_data)
Definition res_pjsip.h:2121
int __ast_sip_push_task_wait_serializer(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data, const char *file, int line, const char *function)
Push a task to the serializer and wait for it to complete.
Definition res_pjsip.c:2217
int __ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data, const char *file, int line, const char *function)
Pushes a task to SIP servants.
Definition res_pjsip.c:2102
Support for logging to various files, console and syslog Configuration in file logger....
#define DEBUG_ATLEAST(level)
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_ERROR
#define ast_verb(level,...)
#define LOG_WARNING
A set of macros to manage forward-linked lists.
#define AST_RWLIST_EMPTY
#define AST_RWLIST_REMOVE_CURRENT
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition linkedlists.h:78
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition linkedlists.h:52
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_RWLIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a read/write list of specified type, statically initialized.
#define AST_RWLIST_INSERT_AFTER
#define AST_RWLIST_NEXT
#define AST_RWLIST_TRAVERSE_SAFE_END
#define AST_RWLIST_TRAVERSE
#define AST_RWLIST_INSERT_HEAD
#define AST_RWLIST_INSERT_TAIL
#define AST_RWLIST_ENTRY
#define AST_RWLIST_INSERT_BEFORE_CURRENT
Asterisk locking-related definitions:
#define ast_cond_destroy(cond)
Definition lock.h:209
#define ast_cond_wait(cond, mutex)
Definition lock.h:212
#define ast_cond_init(cond, attr)
Definition lock.h:208
#define ast_mutex_init(pmutex)
Definition lock.h:193
#define ast_mutex_unlock(a)
Definition lock.h:197
#define SCOPED_LOCK(varname, lock, lockfunc, unlockfunc)
Scoped Locks.
Definition lock.h:590
pthread_cond_t ast_cond_t
Definition lock.h:185
#define ast_mutex_destroy(a)
Definition lock.h:195
#define ast_mutex_lock(a)
Definition lock.h:196
#define ast_cond_signal(cond)
Definition lock.h:210
Asterisk module definitions.
@ AST_MODFLAG_LOAD_ORDER
Definition module.h:331
@ AST_MODFLAG_GLOBAL_SYMBOLS
Definition module.h:330
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
Definition module.h:557
@ AST_MODPRI_CHANNEL_DEPEND
Definition module.h:340
@ AST_MODULE_SUPPORT_CORE
Definition module.h:121
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition module.h:46
@ AST_MODULE_LOAD_SUCCESS
Definition module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition module.h:78
static char * ast_sockaddr_stringify_host(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only, suitable for a URL (with brack...
Definition netsock2.h:327
@ AST_TRANSPORT_WSS
Definition netsock2.h:64
@ AST_TRANSPORT_WS
Definition netsock2.h:63
@ AST_TRANSPORT_UDP
Definition netsock2.h:60
@ AST_TRANSPORT_TLS
Definition netsock2.h:62
@ AST_TRANSPORT_TCP
Definition netsock2.h:61
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition netsock2.c:230
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized,...
Definition netsock2.h:127
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition netsock2.h:532
static struct header_list request_headers
static struct ast_serializer_shutdown_group * shutdown_group
Shutdown group for options serializers.
static int reload(void)
void ast_pjproject_log_intercept_begin(int fd)
Begin PJPROJECT log interception for CLI output.
void ast_pjproject_log_intercept_end(void)
End PJPROJECT log interception for CLI output.
void ast_pjproject_caching_pool_destroy(pj_caching_pool *cp)
Destroy caching pool factory and all cached pools.
void ast_pjproject_caching_pool_init(pj_caching_pool *cp, const pj_pool_factory_policy *policy, pj_size_t max_capacity)
Initialize the caching pool factory.
static const pjsip_method refer_method
Definition res_pjsip.c:1276
static pjsip_endpoint * ast_pjsip_endpoint
Definition res_pjsip.c:74
void ast_sip_unregister_supplement(struct ast_sip_supplement *supplement)
Unregister a an supplement to SIP out of dialog processing.
Definition res_pjsip.c:1476
static pj_sockaddr host_ip_ipv4
Definition res_pjsip.c:79
int ast_sip_is_media_type_in(pjsip_media_type *a,...)
Check if a media type is in a list of others.
Definition res_pjsip.c:2267
struct ast_sip_endpoint * ast_sip_get_endpoint(const char *to, int get_default_outbound, char **uri)
Retrieves an endpoint and URI from the "to" string.
Definition res_pjsip.c:3288
void ast_sip_add_usereqphone(const struct ast_sip_endpoint *endpoint, pj_pool_t *pool, pjsip_uri *uri)
Add 'user=phone' parameter to URI if enabled and user is a phone number.
Definition res_pjsip.c:930
static int unload_pjsip(void *data)
Definition res_pjsip.c:3837
static void supplement_outgoing_response(pjsip_tx_data *tdata, struct ast_sip_endpoint *sip_endpoint)
Definition res_pjsip.c:2413
struct pjsip_param * ast_sip_pjsip_uri_get_other_param(pjsip_uri *uri, const pj_str_t *param_str)
Find an 'other' SIP/SIPS URI parameter by name.
Definition res_pjsip.c:3550
const pj_str_t * ast_sip_pjsip_uri_get_username(pjsip_uri *uri)
Get the user portion of the pjsip_uri.
Definition res_pjsip.c:3516
static const pjsip_method info_method
Definition res_pjsip.c:1274
void ast_sip_unregister_service(pjsip_module *module)
Definition res_pjsip.c:133
const char * ast_sip_get_host_ip_string(int af)
Retrieve the local host address in string form.
Definition res_pjsip.c:2532
pj_status_t(* create_dlg_uac)(pjsip_user_agent *ua, pjsip_rx_data *rdata, const pj_str_t *contact, pjsip_dialog **p_dlg)
Definition res_pjsip.c:1115
static struct ast_sip_outbound_authenticator * registered_outbound_authenticator
Definition res_pjsip.c:189
pjsip_media_type pjsip_media_type_application_media_control_xml
Definition res_pjsip.c:3949
static struct ast_cli_entry cli_commands[]
Definition res_pjsip.c:473
static int create_in_dialog_request(const pjsip_method *method, struct pjsip_dialog *dlg, pjsip_tx_data **tdata)
Definition res_pjsip.c:1307
int ast_sip_call_codec_str_to_pref(struct ast_flags *pref, const char *pref_str, int is_outgoing)
Convert a call codec preference string to preference flags.
Definition res_pjsip.c:2616
char * ast_sip_rdata_get_header_value(pjsip_rx_data *rdata, const pj_str_t str)
Get a specific header value from rdata.
Definition res_pjsip.c:345
pjsip_dialog * ast_sip_create_dialog_uas(const struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pj_status_t *status)
General purpose method for creating a UAS dialog with an endpoint.
Definition res_pjsip.c:1176
pjsip_media_type pjsip_media_type_application_json
Definition res_pjsip.c:3948
static char * cli_dump_endpt(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition res_pjsip.c:371
int ast_sip_requires_authentication(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
Determine if an incoming request requires authentication.
Definition res_pjsip.c:163
static struct send_request_data * send_request_data_alloc(struct ast_sip_endpoint *endpoint, void *token, void(*callback)(void *token, pjsip_event *e))
Definition res_pjsip.c:1534
int ast_sip_send_response(pjsip_response_addr *res_addr, pjsip_tx_data *tdata, struct ast_sip_endpoint *sip_endpoint)
Send a response to an out of dialog request.
Definition res_pjsip.c:2435
pjsip_generic_string_hdr * ast_sip_add_header2(pjsip_tx_data *tdata, const char *name, const char *value)
Add a header to an outbound SIP message, returning a pointer to the header.
Definition res_pjsip.c:2023
int ast_copy_pj_str2(char **dest, const pj_str_t *src)
Create and copy a pj_str_t into a standard character buffer.
Definition res_pjsip.c:2247
int ast_sip_get_host_ip(int af, pj_sockaddr *addr)
Retrieve the local host address in IP form.
Definition res_pjsip.c:2519
int ast_sip_register_service(pjsip_module *module)
Register a SIP service in Asterisk.
Definition res_pjsip.c:117
static const pjsip_method * get_pjsip_method(const char *method)
Definition res_pjsip.c:1296
static int create_out_of_dialog_request(const pjsip_method *method, struct ast_sip_endpoint *endpoint, const char *uri, struct ast_sip_contact *provided_contact, pjsip_tx_data **tdata)
Definition res_pjsip.c:1325
static void send_request_timer_callback(pj_timer_heap_t *theap, pj_timer_entry *entry)
Definition res_pjsip.c:1648
static struct @487 methods[]
static int reload_configuration_task(void *obj)
Definition res_pjsip.c:3829
int ast_sip_is_allowed_uri(pjsip_uri *uri)
Check whether a pjsip_uri is allowed or not.
Definition res_pjsip.c:3511
#define MOD_DATA_CONTACT
Definition res_pjsip.c:66
int ast_sip_register_outbound_authenticator(struct ast_sip_outbound_authenticator *auth)
Register an outbound SIP authenticator.
Definition res_pjsip.c:191
static struct ast_sip_endpoint * handle_slash(const char *to, char *destination, char **uri, char *slash, char *atsign, char *scheme)
Definition res_pjsip.c:3073
static struct ast_sip_endpoint * handle_single_token(const char *to, char *destination, int get_default_outbound, char **uri)
Definition res_pjsip.c:2994
static void send_request_wrapper_destructor(void *obj)
Definition res_pjsip.c:1688
static pjsip_fromto_hdr * get_id_header(pjsip_rx_data *rdata, const pj_str_t *header_name)
Definition res_pjsip.c:2712
static int unregister_service(void *data)
Definition res_pjsip.c:122
static void send_request_data_destroy(void *obj)
Definition res_pjsip.c:1527
static int uas_use_sips_contact(pjsip_rx_data *rdata)
Determine if a SIPS Contact header is required.
Definition res_pjsip.c:1089
const int ast_sip_hangup_sip2cause(int cause)
Convert SIP hangup causes to Asterisk hangup causes.
Definition res_pjsip.c:3570
pj_pool_t * memory_pool
Definition res_pjsip.c:2301
int ast_sip_rewrite_uri_to_local(pjsip_sip_uri *uri, pjsip_tx_data *tdata)
Replace domain and port of SIP URI to point to (external) signaling address of this Asterisk instance...
Definition res_pjsip.c:605
int ast_sip_set_id_connected_line(struct pjsip_rx_data *rdata, struct ast_party_id *id)
Set the ID for a connected line update.
Definition res_pjsip.c:2861
pjsip_media_type pjsip_media_type_application_sdp
Definition res_pjsip.c:3955
void ast_sip_register_supplement(struct ast_sip_supplement *supplement)
Register a supplement to SIP out of dialog processing.
Definition res_pjsip.c:1456
void ast_sip_add_date_header(pjsip_tx_data *tdata)
Adds a Date header to the tdata, formatted like: Date: Wed, 01 Jan 2021 14:53:01 GMT.
Definition res_pjsip.c:90
pjsip_media_type pjsip_media_type_text_plain
Definition res_pjsip.c:3959
pj_thread_t * monitor_thread
Definition res_pjsip.c:2302
void ast_sip_unregister_outbound_authenticator(struct ast_sip_outbound_authenticator *auth)
Unregister an outbound SIP authenticator.
Definition res_pjsip.c:203
int ast_sip_set_id_from_invite(struct pjsip_rx_data *rdata, struct ast_party_id *id, struct ast_party_id *default_id, int trust_inbound)
Set the ID from an INVITE.
Definition res_pjsip.c:2866
pjsip_media_type pjsip_media_type_application_pidf_xml
Definition res_pjsip.c:3950
int ast_sip_create_rdata(pjsip_rx_data *rdata, char *packet, const char *src_name, int src_port, char *transport_type, const char *local_name, int local_port)
General purpose method for creating an rdata structure using specific information.
Definition res_pjsip.c:1266
enum ast_sip_check_auth_result ast_sip_check_authentication(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pjsip_tx_data *tdata)
Method to determine authentication status of an incoming request.
Definition res_pjsip.c:179
#define SIP_SERVANT_ID
Definition res_pjsip.c:2322
pjsip_endpoint * ast_sip_get_pjsip_endpoint(void)
Get a pointer to the PJSIP endpoint.
Definition res_pjsip.c:520
int ast_sip_register_endpoint_identifier(struct ast_sip_endpoint_identifier *identifier)
Register a SIP endpoint identifier.
Definition res_pjsip.c:310
static void send_request_cb(void *token, pjsip_event *e)
Definition res_pjsip.c:1882
void * ast_sip_dict_get(void *ht, const char *key)
Retrieves the value associated with the given key.
Definition res_pjsip.c:2366
int ast_sip_update_from(pjsip_tx_data *tdata, char *from)
Overwrite fields in the outbound 'From' header.
Definition res_pjsip.c:3422
static const pjsip_method message_method
Definition res_pjsip.c:1275
int ast_sip_format_endpoint_ami(struct ast_sip_endpoint *endpoint, struct ast_sip_ami *ami, int *count)
Formats the endpoint and sends over AMI.
Definition res_pjsip.c:501
int ast_sip_dtmf_to_str(const enum ast_sip_dtmf_mode dtmf, char *buf, size_t buf_len)
Convert the DTMF mode enum value into a string.
Definition res_pjsip.c:2543
int ast_sip_str2rc(const char *name)
Convert name to SIP response code.
Definition res_pjsip.c:3753
static struct ast_threadpool * sip_threadpool
Definition res_pjsip.c:76
int ast_sip_set_tpselector_from_transport(const struct ast_sip_transport *transport, pjsip_tpselector *selector)
Sets pjsip_tpselector from ast_sip_transport.
Definition res_pjsip.c:843
int ast_sip_is_uri_sip_sips(pjsip_uri *uri)
Check whether a pjsip_uri is SIP/SIPS or not.
Definition res_pjsip.c:3506
int ast_sip_set_tpselector_from_ep_or_uri(const struct ast_sip_endpoint *endpoint, pjsip_sip_uri *sip_uri, pjsip_tpselector *selector)
Sets pjsip_tpselector from an endpoint or uri.
Definition res_pjsip.c:911
#define DEBUG_BUF_SIZE
static int check_request_status(struct send_request_data *req_data, pjsip_event *e)
Definition res_pjsip.c:1839
static void sip_thread_start(void)
Definition res_pjsip.c:2324
static char * cli_show_endpoint_identifiers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition res_pjsip.c:411
static void clean_contact_from_tdata(pjsip_tx_data *tdata)
Definition res_pjsip.c:2454
void ast_sip_unregister_endpoint_identifier(struct ast_sip_endpoint_identifier *identifier)
Unregister a SIP endpoint identifier.
Definition res_pjsip.c:315
static int reload_module(void)
Definition res_pjsip.c:4097
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
Copy a pj_str_t into a standard character buffer.
Definition res_pjsip.c:2240
static int send_in_dialog_request(pjsip_tx_data *tdata, struct pjsip_dialog *dlg)
Definition res_pjsip.c:1490
static int insert_user_in_contact_uri(const char *to, const char *endpoint_name, const char *aors, const char *user, char **uri)
Find a contact and insert a "user@" into its URI.
Definition res_pjsip.c:2929
#define SERIALIZER_POOL_SIZE
Definition res_pjsip.c:69
const char * ast_sip_call_codec_pref_to_str(struct ast_flags pref)
Convert the call codec preference flags to a string.
Definition res_pjsip.c:2593
struct ast_sip_endpoint * ast_sip_identify_endpoint(pjsip_rx_data *rdata)
Determine the endpoint that has sent a SIP message.
Definition res_pjsip.c:330
int ast_sip_send_out_of_dialog_request(pjsip_tx_data *tdata, struct ast_sip_endpoint *endpoint, int timeout, void *token, void(*callback)(void *token, pjsip_event *e))
General purpose method for sending an Out-Of-Dialog SIP request.
Definition res_pjsip.c:1938
static struct ast_sip_endpoint * handle_atsign(const char *to, char *destination, char **uri, char *slash, char *atsign, char *scheme, int get_default_outbound)
Definition res_pjsip.c:3230
pjsip_dialog * ast_sip_create_dialog_uas_locked(const struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pj_status_t *status)
General purpose method for creating a UAS dialog with an endpoint.
Definition res_pjsip.c:1192
pjsip_media_type pjsip_media_type_application_simple_message_summary
Definition res_pjsip.c:3954
struct ast_sip_transport_state * ast_sip_find_transport_state_in_use(struct ast_sip_request_transport_details *details)
Returns the transport state currently in use based on request transport details.
Definition res_pjsip.c:595
static char host_ip_ipv6_string[PJ_INET6_ADDRSTRLEN]
Definition res_pjsip.c:88
int ast_sip_dlg_set_transport(const struct ast_sip_endpoint *endpoint, pjsip_dialog *dlg, pjsip_tpselector *selector)
Set the transport on a dialog.
Definition res_pjsip.c:727
static pj_sockaddr host_ip_ipv6
Definition res_pjsip.c:85
pjsip_dialog * ast_sip_create_dialog_uac(const struct ast_sip_endpoint *endpoint, const char *uri, const char *request_user)
General purpose method for creating a UAC dialog with an endpoint.
Definition res_pjsip.c:964
const char * method
Definition res_pjsip.c:1279
static pj_status_t endpt_send_request(struct ast_sip_endpoint *endpoint, pjsip_tx_data *tdata, pj_int32_t timeout, void *token, pjsip_endpt_send_callback cb)
Definition res_pjsip.c:1696
void ast_sip_unregister_authenticator(struct ast_sip_authenticator *auth)
Unregister a SIP authenticator.
Definition res_pjsip.c:152
int ast_sip_send_request(pjsip_tx_data *tdata, struct pjsip_dialog *dlg, struct ast_sip_endpoint *endpoint, void *token, void(*callback)(void *token, pjsip_event *e))
General purpose method for sending a SIP request.
Definition res_pjsip.c:1979
long ast_sip_threadpool_queue_size(void)
Return the size of the SIP threadpool's task queue.
Definition res_pjsip.c:3496
int ast_sip_set_request_transport_details(struct ast_sip_request_transport_details *details, pjsip_tx_data *tdata, int use_ipv6)
Sets request transport details based on tdata.
Definition res_pjsip.c:648
static pj_bool_t supplement_on_rx_request(pjsip_rx_data *rdata)
Definition res_pjsip.c:2389
static pjsip_msg_body * ast_body_to_pjsip_body(pj_pool_t *pool, const struct ast_sip_body *body)
Definition res_pjsip.c:2039
void ast_sip_register_endpoint_formatter(struct ast_sip_endpoint_formatter *obj)
Register an endpoint formatter.
Definition res_pjsip.c:481
int ast_sip_add_body(pjsip_tx_data *tdata, const struct ast_sip_body *body)
Add a body to an outbound SIP message.
Definition res_pjsip.c:2052
void * ast_sip_dict_set(pj_pool_t *pool, void *ht, const char *key, void *val)
Set the value for the given key.
Definition res_pjsip.c:2377
int ast_sip_are_media_types_equal(pjsip_media_type *a, pjsip_media_type *b)
Compare pjsip media types.
Definition res_pjsip.c:2258
void ast_sip_tpselector_unref(pjsip_tpselector *selector)
Unreference a pjsip_tpselector.
Definition res_pjsip.c:923
void never_called_res_pjsip(void)
Definition res_pjsip.c:3942
int ast_sip_get_transport_name(const struct ast_sip_endpoint *endpoint, pjsip_sip_uri *sip_uri, char *buf, size_t buf_len)
Get the transport name from an endpoint or request uri.
Definition res_pjsip.c:698
static int set_id_from_from(struct pjsip_rx_data *rdata, struct ast_party_id *id)
Definition res_pjsip.c:2842
void ast_sip_unregister_endpoint_formatter(struct ast_sip_endpoint_formatter *obj)
Unregister an endpoint formatter.
Definition res_pjsip.c:487
static void * monitor_thread_exec(void *endpt)
Definition res_pjsip.c:2305
static char * cli_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition res_pjsip.c:442
int ast_sip_register_authenticator(struct ast_sip_authenticator *auth)
Register a SIP authenticator.
Definition res_pjsip.c:140
int ast_sip_create_rdata_with_contact(pjsip_rx_data *rdata, char *packet, const char *src_name, int src_port, char *transport_type, const char *local_name, int local_port, const char *contact)
General purpose method for creating an rdata structure using specific information.
Definition res_pjsip.c:1214
int ast_sip_add_body_multipart(pjsip_tx_data *tdata, const struct ast_sip_body *bodies[], int num_bodies)
Add a multipart body to an outbound SIP message.
Definition res_pjsip.c:2059
static pjsip_dialog * create_dialog_uas(const struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pj_status_t *status, create_dlg_uac create_fun)
Definition res_pjsip.c:1118
pjsip_media_type pjsip_media_type_application_rlmi_xml
Definition res_pjsip.c:3953
static int monitor_continue
Definition res_pjsip.c:2303
static const struct response_code_map rc_map[]
Definition res_pjsip.c:3673
static void remove_request_headers(pjsip_endpoint *endpt)
Definition res_pjsip.c:3484
int ast_sip_update_to_uri(pjsip_tx_data *tdata, const char *to)
Replace the To URI in the tdata with the supplied one.
Definition res_pjsip.c:3362
pjsip_media_type pjsip_media_type_multipart_mixed
Definition res_pjsip.c:3957
static int register_service(void *data)
Definition res_pjsip.c:102
pjsip_media_type pjsip_media_type_application_xpidf_xml
Definition res_pjsip.c:3951
static int load_module(void)
Definition res_pjsip.c:3961
int ast_sip_set_outbound_proxy(pjsip_tx_data *tdata, const char *proxy)
Set the outbound proxy for an outbound SIP message.
Definition res_pjsip.c:1992
static struct ast_sip_authenticator * registered_authenticator
Definition res_pjsip.c:138
struct ast_threadpool * ast_sip_threadpool(void)
Retrieve the SIP threadpool object.
Definition res_pjsip.c:3501
int ast_sip_will_uri_survive_restart(pjsip_sip_uri *uri, struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
Definition res_pjsip.c:525
int ast_sip_register_endpoint_identifier_with_name(struct ast_sip_endpoint_identifier *identifier, const char *name)
Register a SIP endpoint identifier with a name.
Definition res_pjsip.c:233
pjsip_media_type pjsip_media_type_multipart_alternative
Definition res_pjsip.c:3956
int ast_sip_set_tpselector_from_transport_name(const char *transport_name, pjsip_tpselector *selector)
Sets pjsip_tpselector from ast_sip_transport.
Definition res_pjsip.c:893
int ast_sip_create_request(const char *method, struct pjsip_dialog *dlg, struct ast_sip_endpoint *endpoint, const char *uri, struct ast_sip_contact *contact, pjsip_tx_data **tdata)
General purpose method for creating a SIP request.
Definition res_pjsip.c:1435
pj_caching_pool caching_pool
Definition res_pjsip.c:2300
static int find_transport_state_in_use(void *obj, void *arg, int flags)
Callback function for finding the transport the request is going out on.
Definition res_pjsip.c:576
static void endpt_send_request_cb(void *token, pjsip_event *e)
Definition res_pjsip.c:1573
const pjsip_method * pmethod
Definition res_pjsip.c:1280
int ast_sip_str_to_dtmf(const char *dtmf_mode)
Convert the DTMF mode name into an enum.
Definition res_pjsip.c:2572
static int do_cli_dump_endpt(void *v_a)
Definition res_pjsip.c:360
int ast_sip_add_header(pjsip_tx_data *tdata, const char *name, const char *value)
Add a header to an outbound SIP message.
Definition res_pjsip.c:2008
static int unload_module(void)
Definition res_pjsip.c:4111
const pj_str_t * ast_sip_pjsip_uri_get_hostname(pjsip_uri *uri)
Get the host portion of the pjsip_uri.
Definition res_pjsip.c:3535
static pjsip_module supplement_module
Definition res_pjsip.c:1318
static void pool_destroy_callback(void *arg)
Definition res_pjsip.c:2448
static char host_ip_ipv4_string[PJ_INET6_ADDRSTRLEN]
Definition res_pjsip.c:82
static int load_pjsip(void)
Definition res_pjsip.c:3881
static pj_bool_t does_method_match(const pj_str_t *message_method, const char *supplement_method)
Definition res_pjsip.c:1499
int ast_sip_send_stateful_response(pjsip_rx_data *rdata, pjsip_tx_data *tdata, struct ast_sip_endpoint *sip_endpoint)
Send a stateful response to an out of dialog request.
Definition res_pjsip.c:2463
int ast_sip_is_content_type(pjsip_media_type *content_type, char *type, char *subtype)
Checks if the given content type matches type/subtype.
Definition res_pjsip.c:2287
#define TIMER_INACTIVE
Definition res_pjsip.c:1512
int ast_sip_append_body(pjsip_tx_data *tdata, const char *body_text)
Append body data to a SIP message.
Definition res_pjsip.c:2075
static int set_id_from_pai(pjsip_rx_data *rdata, struct ast_party_id *id)
Definition res_pjsip.c:2749
#define TIMEOUT_TIMER2
Definition res_pjsip.c:1513
#define ENDPOINT_IDENTIFIER_FORMAT
int ast_sip_create_request_with_auth(const struct ast_sip_auth_vector *auths, pjsip_rx_data *challenge, pjsip_tx_data *old_request, pjsip_tx_data **new_request)
Create a response to an authentication challenge.
Definition res_pjsip.c:214
static int __ast_sip_push_task_wait(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data, const char *file, int line, const char *function)
Definition res_pjsip.c:2172
pjsip_media_type pjsip_media_type_application_cpim_xpidf_xml
Definition res_pjsip.c:3952
static void set_id_from_hdr(pjsip_fromto_hdr *hdr, struct ast_party_id *id)
Definition res_pjsip.c:2645
static int set_id_from_rpid(pjsip_rx_data *rdata, struct ast_party_id *id)
Definition res_pjsip.c:2790
static void stop_monitor_thread(void)
Definition res_pjsip.c:2314
pjsip_sip_uri * ast_sip_get_contact_sip_uri(pjsip_tx_data *tdata)
Return the SIP URI of the Contact header.
Definition res_pjsip.c:564
static int sync_task(void *data)
Definition res_pjsip.c:2152
pjsip_media_type pjsip_media_type_multipart_related
Definition res_pjsip.c:3958
static struct ast_serializer_pool * sip_serializer_pool
Definition res_pjsip.c:72
int ast_sip_failover_request(pjsip_tx_data *tdata)
Set a request to use the next value in the list of resolved addresses.
Definition res_pjsip.c:1816
static int sip_dialog_create_from(pj_pool_t *pool, pj_str_t *from, const char *user, const char *domain, const pj_str_t *target, pjsip_tpselector *selector)
Definition res_pjsip.c:749
void ast_sip_modify_id_header(pj_pool_t *pool, pjsip_fromto_hdr *id_hdr, const struct ast_party_id *id)
Set name and number information on an identity header.
Definition res_pjsip.c:2889
int ast_sip_create_response(const pjsip_rx_data *rdata, int st_code, struct ast_sip_contact *contact, pjsip_tx_data **tdata)
General purpose method for creating a SIP response.
Definition res_pjsip.c:2507
char * ast_sip_get_endpoint_identifier_order(void)
Retrieve the global endpoint_identifier_order setting.
struct ast_sip_contact * ast_sip_location_retrieve_contact_from_aor_list(const char *aor_list)
Retrieve the first bound contact from a list of AORs.
Definition location.c:304
struct ao2_container * ast_sip_get_transport_states(void)
Retrieves all transport states.
struct ast_sip_aor * ast_sip_location_retrieve_aor(const char *aor_name)
Retrieve a named AOR.
Definition location.c:147
#define ast_sip_call_codec_pref_test(__param, __codec_pref)
Returns true if the preference is set in the parameter.
Definition res_pjsip.h:787
void ast_sip_message_apply_transport(const char *transport_name, pjsip_tx_data *tdata)
Apply the configuration for a transport to an outgoing message.
#define AST_SIP_X_AST_TXP
Definition res_pjsip.h:1170
#define AST_SIP_USER_OPTIONS_TRUNCATE_CHECK(str)
Truncate the URI user field options string if enabled.
Definition res_pjsip.h:3517
struct ast_sip_endpoint * ast_pjsip_rdata_get_endpoint(pjsip_rx_data *rdata)
Get the looked-up endpoint on an out-of dialog request or response.
struct ast_sip_endpoint * ast_sip_default_outbound_endpoint(void)
Retrieve the default outbound endpoint.
#define ast_sip_mod_data_set(pool, mod_data, id, key, val)
Utilizing a mod_data array for a given id, set the value associated with the given key.
Definition res_pjsip.h:3112
unsigned int ast_sip_get_disable_multi_domain(void)
Retrieve the system setting 'disable multi domain'.
ast_sip_dtmf_mode
DTMF modes for SIP endpoints.
Definition res_pjsip.h:545
@ AST_SIP_DTMF_NONE
Definition res_pjsip.h:547
@ AST_SIP_DTMF_AUTO_INFO
Definition res_pjsip.h:558
@ AST_SIP_DTMF_AUTO
Definition res_pjsip.h:556
@ AST_SIP_DTMF_INBAND
Definition res_pjsip.h:552
@ AST_SIP_DTMF_INFO
Definition res_pjsip.h:554
@ AST_SIP_DTMF_RFC_4733
Definition res_pjsip.h:550
static const pj_str_t AST_PJ_STR_EMPTY
Definition res_pjsip.h:112
#define ast_sip_mod_data_get(mod_data, id, key)
Using the dictionary stored in mod_data array at a given id, retrieve the value associated with the g...
Definition res_pjsip.h:3080
struct ast_sip_transport_state * ast_sip_get_transport_state(const char *transport_id)
Retrieve transport state.
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
#define MAX_RX_CHALLENGES
Definition res_pjsip.h:108
ast_sip_check_auth_result
Possible returns from ast_sip_check_authentication.
Definition res_pjsip.h:1321
@ AST_SIP_AUTHENTICATION_SUCCESS
Definition res_pjsip.h:1325
@ AST_SIP_CALL_CODEC_PREF_ALL
Definition res_pjsip.h:767
@ AST_SIP_CALL_CODEC_PREF_LOCAL
Definition res_pjsip.h:773
@ AST_SIP_CALL_CODEC_PREF_REMOTE
Definition res_pjsip.h:775
@ AST_SIP_CALL_CODEC_PREF_UNION
Definition res_pjsip.h:763
@ AST_SIP_CALL_CODEC_PREF_FIRST
Definition res_pjsip.h:769
@ AST_SIP_CALL_CODEC_PREF_INTERSECT
Definition res_pjsip.h:761
#define AST_SIP_X_AST_TXP_LEN
Definition res_pjsip.h:1171
#define PJSTR_PRINTF_VAR(_v)
Definition res_pjsip.h:72
void ast_sip_get_default_from_user(char *from_user, size_t size)
Retrieve the global default from user.
struct ast_sip_contact * ast_sip_location_retrieve_first_aor_contact(const struct ast_sip_aor *aor)
Retrieve the first bound contact for an AOR.
Definition location.c:194
void ast_sip_location_prune_boot_contacts(void)
Prune the prune_on_boot contacts.
Definition location.c:470
#define ast_sip_transport_is_local(transport_state, addr)
Definition res_pjsip.h:213
#define PJSTR_PRINTF_SPEC
Definition res_pjsip.h:71
static void challenge(const char *endpoint_id, struct ast_sip_auth *auth, pjsip_tx_data *tdata, const pjsip_rx_data *rdata, int is_stale, const pjsip_auth_algorithm *algorithm)
Send a WWW-Authenticate challenge.
void ast_sip_sanitize_xml(const char *input, char *output, size_t len)
Replace offensive XML characters with XML entities.
int ast_sip_initialize_scheduler(void)
Initialize scheduler.
int ast_res_pjsip_preinit_options_handling(void)
int ast_sip_initialize_transport_management(void)
void ast_sip_initialize_resolver(void)
int ast_res_pjsip_init_options_handling(int reload)
int ast_sip_initialize_distributor(void)
int ast_res_pjsip_reload_configuration(void)
int ast_sip_destroy_scheduler(void)
void ast_sip_initialize_global_headers(void)
void ast_res_pjsip_cleanup_options_handling(void)
void ast_sip_destroy_transport_management(void)
int ast_sip_initialize_transport_events(void)
void ast_sip_destroy_distributor(void)
int ast_res_pjsip_initialize_configuration(void)
void ast_sip_destroy_global_headers(void)
void ast_res_pjsip_destroy_configuration(void)
int ast_res_pjsip_init_message_filter(void)
void ast_sip_destroy_transport_events(void)
void ast_res_pjsip_cleanup_message_filter(void)
const pjsip_method pjsip_publish_method
Defined method for PUBLISH.
#define NULL
Definition resample.c:96
struct ast_taskprocessor * ast_serializer_pool_get(struct ast_serializer_pool *pool)
Retrieve a serializer from the pool.
Definition serializer.c:175
struct ast_serializer_pool * ast_serializer_pool_create(const char *name, unsigned int size, struct ast_threadpool *threadpool, int timeout)
Create a serializer pool.
Definition serializer.c:78
int ast_serializer_pool_destroy(struct ast_serializer_pool *pool)
Destroy the serializer pool.
Definition serializer.c:41
Sorcery Data Access Layer API.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition sorcery.c:2381
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
Definition sorcery.c:1917
String manipulation functions.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition strings.h:80
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition strings.h:65
#define ast_str_alloca(init_len)
Definition strings.h:848
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition strings.h:659
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition strings.h:1113
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition strings.h:761
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition strings.h:425
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Checks whether a string begins with another.
Definition strings.h:97
Generic container type.
descriptor for a cli entry.
Definition cli.h:171
struct ast_cli_entry * next
Definition cli.h:189
char * command
Definition cli.h:186
const char * usage
Definition cli.h:177
Structure used to handle boolean flags.
Definition utils.h:220
unsigned int flags
Definition utils.h:221
Structure for mutex and tracking information.
Definition lock.h:142
Information needed to identify an endpoint in a call.
Definition channel.h:340
char * tag
User-set "tag".
Definition channel.h:356
struct ast_party_number number
Subscriber phone number.
Definition channel.h:344
unsigned char valid
TRUE if the number information is valid/present.
Definition channel.h:299
AMI variable container.
Definition res_pjsip.h:3213
A SIP address of record.
Definition res_pjsip.h:478
An interchangeable way of handling digest authentication for SIP.
Definition res_pjsip.h:1366
enum ast_sip_check_auth_result(* check_authentication)(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pjsip_tx_data *tdata)
Check that an incoming request passes authentication.
Definition res_pjsip.h:1381
int(* requires_authentication)(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
Check if a request requires authentication See ast_sip_requires_authentication for more details.
Definition res_pjsip.h:1371
SIP body description.
Definition res_pjsip.h:2457
const char * type
Definition res_pjsip.h:2459
const char * body_text
Definition res_pjsip.h:2463
const char * subtype
Definition res_pjsip.h:2461
CLI Formatter Context passed to all formatters.
Contact associated with an address of record.
Definition res_pjsip.h:390
const ast_string_field uri
Definition res_pjsip.h:412
struct ast_sip_endpoint * endpoint
Definition res_pjsip.h:422
const ast_string_field endpoint_name
Definition res_pjsip.h:412
An entity responsible formatting endpoint information.
Definition res_pjsip.h:3239
struct ast_sip_endpoint_formatter * next
Definition res_pjsip.h:3245
int(* format_ami)(const struct ast_sip_endpoint *endpoint, struct ast_sip_ami *ami)
Callback used to format endpoint information over AMI.
Definition res_pjsip.h:3243
An entity responsible for identifying the source of a SIP message.
Definition res_pjsip.h:1409
struct ast_sip_endpoint *(* identify_endpoint)(pjsip_rx_data *rdata)
Callback used to identify the source of a message. See ast_sip_identify_endpoint for more details.
Definition res_pjsip.h:1414
An entity with which Asterisk communicates.
Definition res_pjsip.h:1051
struct ast_sip_auth_vector outbound_auths
Definition res_pjsip.h:1098
const ast_string_field transport
Definition res_pjsip.h:1080
const ast_string_field aors
Definition res_pjsip.h:1080
const ast_string_field outbound_proxy
Definition res_pjsip.h:1080
const ast_string_field fromdomain
Definition res_pjsip.h:1080
unsigned int allow_unauthenticated_options
Definition res_pjsip.h:1152
unsigned int usereqphone
Definition res_pjsip.h:1120
const ast_string_field fromuser
Definition res_pjsip.h:1080
struct ast_sip_endpoint_nat_configuration nat
Definition res_pjsip.h:1088
struct ast_sip_endpoint_info_configuration info
Definition res_pjsip.h:1092
an interchangeable way of responding to authentication challenges
Definition res_pjsip.h:1391
int(* create_request_with_auth)(const struct ast_sip_auth_vector *auths, struct pjsip_rx_data *challenge, struct pjsip_tx_data *old_request, struct pjsip_tx_data **new_request)
Create a new request with authentication credentials.
Definition res_pjsip.h:1402
Structure which contains information about a transport.
Definition res_pjsip.h:335
int local_port
Local port for transport.
Definition res_pjsip.h:345
pjsip_transport * transport
Potential pointer to the transport itself, if UDP.
Definition res_pjsip.h:339
enum ast_transport type
Type of transport.
Definition res_pjsip.h:337
pjsip_tpfactory * factory
Potential pointer to the transport factory itself, if TCP/TLS.
Definition res_pjsip.h:341
pj_str_t local_address
Local address for transport.
Definition res_pjsip.h:343
A supplement to SIP message processing.
Definition res_pjsip.h:3364
void(* outgoing_request)(struct ast_sip_endpoint *endpoint, struct ast_sip_contact *contact, struct pjsip_tx_data *tdata)
Called on an outgoing SIP request This method is always called from a SIP servant thread.
Definition res_pjsip.h:3407
int(* incoming_request)(struct ast_sip_endpoint *endpoint, struct pjsip_rx_data *rdata)
Called on incoming SIP request This method can indicate a failure in processing in its return....
Definition res_pjsip.h:3386
void(* outgoing_response)(struct ast_sip_endpoint *endpoint, struct ast_sip_contact *contact, struct pjsip_tx_data *tdata)
Called on an outgoing SIP response This method is always called from a SIP servant thread.
Definition res_pjsip.h:3412
void(* incoming_response)(struct ast_sip_endpoint *endpoint, struct pjsip_rx_data *rdata)
Called on an incoming SIP response This method is always called from a SIP servant thread.
Definition res_pjsip.h:3402
const char * method
Definition res_pjsip.h:3366
enum ast_sip_supplement_priority priority
Definition res_pjsip.h:3368
struct ast_sip_supplement * next
Definition res_pjsip.h:3414
Structure for SIP transport information.
Definition res_pjsip.h:117
struct pjsip_tpfactory * factory
Transport factory.
Definition res_pjsip.h:121
enum ast_transport type
Definition res_pjsip.h:131
struct pjsip_transport * transport
Transport itself.
Definition res_pjsip.h:119
Transport to bind to.
Definition res_pjsip.h:219
Socket address structure.
Definition netsock2.h:97
Support for dynamic strings.
Definition strings.h:623
A ast_taskprocessor structure is a singleton by name.
An opaque threadpool structure.
Definition threadpool.c:36
struct ast_sip_endpoint_identifier * identifier
Definition res_pjsip.c:227
struct endpoint_identifier_list::@488 list
const char * short_name
Definition res_pjsip.c:3663
const char * long_name
Definition res_pjsip.c:3662
Structure to hold information about an outbound request.
Definition res_pjsip.c:1516
struct ast_sip_endpoint * endpoint
Definition res_pjsip.c:1518
unsigned int challenge_count
Definition res_pjsip.c:1524
void(* callback)(void *token, pjsip_event *e)
Definition res_pjsip.c:1522
unsigned int send_cb_called
Definition res_pjsip.c:1560
pjsip_tx_data * tdata
Definition res_pjsip.c:1566
unsigned int cb_called
Definition res_pjsip.c:1558
pj_timer_entry * timeout_timer
Definition res_pjsip.c:1562
void(* callback)(void *token, pjsip_event *e)
Definition res_pjsip.c:1556
ast_cond_t cond
Definition stasis.c:1343
int(* task)(void *)
Definition res_pjsip.c:2148
void * task_data
Definition stasis.c:1345
ast_mutex_t lock
Definition stasis.c:1342
userdata associated with baseline taskprocessor test
structure to hold users read from phoneprov_users.conf
int value
Definition syslog.c:37
An API for managing task processing threads that can be shared across modules.
int ast_taskprocessor_is_task(struct ast_taskprocessor *tps)
Am I the given taskprocessor's current task.
int __ast_taskprocessor_push(struct ast_taskprocessor *tps, int(*task_exe)(void *datap), void *datap, const char *file, int line, const char *function) attribute_warn_unused_result
Push a task into the specified taskprocessor queue and signal the taskprocessor thread.
Test Framework API.
@ TEST_INIT
Definition test.h:200
@ TEST_EXECUTE
Definition test.h:201
#define AST_TEST_REGISTER(cb)
Definition test.h:127
#define ast_test_status_update(a, b, c...)
Definition test.h:129
#define AST_TEST_UNREGISTER(cb)
Definition test.h:128
#define AST_TEST_DEFINE(hdr)
Definition test.h:126
@ AST_TEST_PASS
Definition test.h:195
@ AST_TEST_FAIL
Definition test.h:196
@ AST_TEST_NOT_RUN
Definition test.h:194
static struct test_options options
static struct test_val b
static struct test_val a
void ast_threadpool_shutdown(struct ast_threadpool *pool)
Shut down a threadpool and destroy it.
Definition threadpool.c:977
long ast_threadpool_queue_size(struct ast_threadpool *pool)
Return the size of the threadpool's task queue.
struct ast_taskprocessor * ast_threadpool_serializer_group(const char *name, struct ast_threadpool *pool, struct ast_serializer_shutdown_group *shutdown_group)
Serialized execution of tasks within a ast_threadpool.
struct ast_threadpool * ast_threadpool_create(const char *name, struct ast_threadpool_listener *listener, const struct ast_threadpool_options *options)
Create a new threadpool.
Definition threadpool.c:915
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
UTF-8 information and validation functions.
ast_utf8_replace_result
Definition utf8.h:70
@ AST_UTF8_REPLACE_VALID
Source contained fully valid UTF-8.
Definition utf8.h:76
enum ast_utf8_replace_result ast_utf8_replace_invalid_chars(char *dst, size_t *dst_size, const char *src, size_t src_len)
Copy a string safely replacing any invalid UTF-8 sequences.
Definition utf8.c:173
FILE * out
Definition utils/frame.c:33
int error(const char *format,...)
Utility functions.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition utils.h:981
#define ast_assert(a)
Definition utils.h:779
#define MIN(a, b)
Definition utils.h:252
char * ast_escape_quoted(const char *string, char *outbuf, int buflen)
Escape characters found in a quoted string.
Definition utils.c:817
#define ast_set_flag(p, flag)
Definition utils.h:71
#define ARRAY_LEN(a)
Definition utils.h:706
Universally unique identifier support.