build: Update config.guess and config.sub
[asterisk/asterisk.git] / res / res_pjsip_sips_contact.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2015, 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 /*** MODULEINFO
20         <depend>pjproject</depend>
21         <depend>res_pjsip</depend>
22         <support_level>core</support_level>
23  ***/
24
25 #include "asterisk.h"
26
27 #include <pjsip.h>
28
29 #include "asterisk/res_pjsip.h"
30 #include "asterisk/module.h"
31
32 /*!
33  * \brief Upgrade Contact URIs on outgoing SIP requests to SIPS if required.
34  *
35  * The rules being used here are according to RFC 3261 section 8.1.1.8. In
36  * brief, if the request URI is SIPS or the topmost Route header is SIPS,
37  * then the Contact header we send must also be SIPS.
38  */
39 static pj_status_t sips_contact_on_tx_request(pjsip_tx_data *tdata)
40 {
41         pjsip_contact_hdr *contact;
42         pjsip_route_hdr *route;
43         pjsip_sip_uri *contact_uri;
44
45         contact = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CONTACT, NULL);
46         if (!contact) {
47                 return PJ_SUCCESS;
48         }
49
50         contact_uri = pjsip_uri_get_uri(contact->uri);
51         if (PJSIP_URI_SCHEME_IS_SIPS(contact_uri)) {
52                 /* If the Contact header is already SIPS, then we don't need to do anything */
53                 return PJ_SUCCESS;
54         }
55
56         if (PJSIP_URI_SCHEME_IS_SIPS(tdata->msg->line.req.uri)) {
57                 ast_debug(1, "Upgrading contact URI on outgoing SIP request to SIPS due to SIPS Request URI\n");
58                 pjsip_sip_uri_set_secure(contact_uri, PJ_TRUE);
59                 return PJ_SUCCESS;
60         }
61
62         route = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, NULL);
63         if (!route) {
64                 return PJ_SUCCESS;
65         }
66
67         if (!PJSIP_URI_SCHEME_IS_SIPS(&route->name_addr)) {
68                 return PJ_SUCCESS;
69         }
70
71         /* Our Contact header is not a SIPS URI, but our topmost Route header is. */
72         ast_debug(1, "Upgrading contact URI on outgoing SIP request to SIPS due to SIPS Route header\n");
73         pjsip_sip_uri_set_secure(contact_uri, PJ_TRUE);
74
75         return PJ_SUCCESS;
76 }
77
78 static pjsip_module sips_contact_module = {
79         .name = {"SIPS Contact", 12 },
80         .id = -1,
81         .priority = PJSIP_MOD_PRIORITY_TSX_LAYER - 2,
82         .on_tx_request = sips_contact_on_tx_request,
83 };
84
85 static int unload_module(void)
86 {
87         ast_sip_unregister_service(&sips_contact_module);
88         return 0;
89 }
90
91 static int load_module(void)
92 {
93         if (ast_sip_register_service(&sips_contact_module)) {
94                 return AST_MODULE_LOAD_DECLINE;
95         }
96
97         return AST_MODULE_LOAD_SUCCESS;
98 }
99
100 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "UAC SIPS Contact support",
101         .support_level = AST_MODULE_SUPPORT_CORE,
102         .load = load_module,
103         .unload = unload_module,
104         .load_pri = AST_MODPRI_APP_DEPEND,
105         .requires = "res_pjsip",
106 );