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