res_pjsip_sips_contact.c 2.8 KB

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