res_pjsip_nat.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2013, Digium, Inc.
  5. *
  6. * Joshua Colp <jcolp@digium.com>
  7. *
  8. * See http://www.asterisk.org for more information about
  9. * the Asterisk project. Please do not directly contact
  10. * any of the maintainers of this project for assistance;
  11. * the project provides a web site, mailing lists and IRC
  12. * channels for your use.
  13. *
  14. * This program is free software, distributed under the terms of
  15. * the GNU General Public License Version 2. See the LICENSE file
  16. * at the top of the source tree.
  17. */
  18. /*** 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 <pjsip_ua.h>
  26. #include "asterisk/res_pjsip.h"
  27. #include "asterisk/res_pjsip_session.h"
  28. #include "asterisk/module.h"
  29. #include "asterisk/acl.h"
  30. static void rewrite_uri(pjsip_rx_data *rdata, pjsip_sip_uri *uri)
  31. {
  32. pj_cstr(&uri->host, rdata->pkt_info.src_name);
  33. uri->port = rdata->pkt_info.src_port;
  34. if (!strcasecmp("WSS", rdata->tp_info.transport->type_name)) {
  35. /* WSS is special, we don't want to overwrite the URI at all as it needs to be ws */
  36. } else if (strcasecmp("udp", rdata->tp_info.transport->type_name)) {
  37. uri->transport_param = pj_str(rdata->tp_info.transport->type_name);
  38. } else {
  39. uri->transport_param.slen = 0;
  40. }
  41. }
  42. /*
  43. * Update the Record-Route headers in the request or response and in the dialog
  44. * object if exists.
  45. *
  46. * When NAT is in use, the address of the next hop in the SIP may be incorrect.
  47. * To address this asterisk uses two strategies in parallel:
  48. * 1. intercept the messages at the transaction level and rewrite the
  49. * messages before arriving at the dialog layer
  50. * 2. after the application processing, update the dialog object with the
  51. * correct information
  52. *
  53. * The first strategy has a limitation that the SIP message may not have all
  54. * the information required to determine if the next hop is in the route set
  55. * or in the contact. Causing risk that asterisk will update the Contact on
  56. * receipt of an in-dialog message despite there being a route set saved in
  57. * the dialog.
  58. *
  59. * The second strategy has a limitation that not all UAC layers have interfaces
  60. * available to invoke this module after dialog creation. (pjsip_sesion does
  61. * but pjsip_pubsub does not), thus this strategy can't update the dialog in
  62. * all cases needed.
  63. *
  64. * The ideal solution would be to implement an "incomming_request" event
  65. * in pubsub module that can then pass the dialog object to this module
  66. * on SUBSCRIBE, this module then should add itself as a listener to the dialog
  67. * for the subsequent requests and responses & then be able to properly update
  68. * the dialog object for all required events.
  69. */
  70. static int rewrite_route_set(pjsip_rx_data *rdata, pjsip_dialog *dlg)
  71. {
  72. pjsip_rr_hdr *rr = NULL;
  73. pjsip_sip_uri *uri;
  74. int res = -1;
  75. int ignore_rr = 0;
  76. int pubsub = 0;
  77. if (rdata->msg_info.msg->type == PJSIP_RESPONSE_MSG) {
  78. pjsip_hdr *iter;
  79. for (iter = rdata->msg_info.msg->hdr.prev; iter != &rdata->msg_info.msg->hdr; iter = iter->prev) {
  80. if (iter->type == PJSIP_H_RECORD_ROUTE) {
  81. rr = (pjsip_rr_hdr *)iter;
  82. break;
  83. }
  84. }
  85. } else if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_register_method)) {
  86. rr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_RECORD_ROUTE, NULL);
  87. } else {
  88. /**
  89. * Record-Route header has no meaning in REGISTER requests
  90. * and should be ignored
  91. */
  92. ignore_rr = 1;
  93. }
  94. if (!pjsip_method_cmp(&rdata->msg_info.cseq->method, &pjsip_subscribe_method) ||
  95. !pjsip_method_cmp(&rdata->msg_info.cseq->method, &pjsip_notify_method)) {
  96. /**
  97. * There is currently no good way to get the dlg object for a pubsub dialog
  98. * so we will just look at the rr & contact of the current message and
  99. * hope for the best
  100. */
  101. pubsub = 1;
  102. }
  103. if (rr) {
  104. uri = pjsip_uri_get_uri(&rr->name_addr);
  105. rewrite_uri(rdata, uri);
  106. res = 0;
  107. }
  108. if (dlg && !pj_list_empty(&dlg->route_set) && !dlg->route_set_frozen) {
  109. pjsip_routing_hdr *route = dlg->route_set.next;
  110. uri = pjsip_uri_get_uri(&route->name_addr);
  111. rewrite_uri(rdata, uri);
  112. res = 0;
  113. }
  114. if (!dlg && !rr && !ignore_rr && !pubsub && rdata->msg_info.to->tag.slen){
  115. /**
  116. * Even if this message doesn't have any route headers
  117. * the dialog may, so wait until a later invocation that
  118. * has a dialog reference to make sure there isn't a
  119. * previously saved routset in the dialog before deciding
  120. * the contact needs to be modified
  121. */
  122. res = 0;
  123. }
  124. return res;
  125. }
  126. static int rewrite_contact(pjsip_rx_data *rdata, pjsip_dialog *dlg)
  127. {
  128. pjsip_contact_hdr *contact;
  129. contact = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL);
  130. if (contact && !contact->star && (PJSIP_URI_SCHEME_IS_SIP(contact->uri) || PJSIP_URI_SCHEME_IS_SIPS(contact->uri))) {
  131. pjsip_sip_uri *uri = pjsip_uri_get_uri(contact->uri);
  132. rewrite_uri(rdata, uri);
  133. if (dlg && pj_list_empty(&dlg->route_set) && (!dlg->remote.contact
  134. || pjsip_uri_cmp(PJSIP_URI_IN_REQ_URI, dlg->remote.contact->uri, contact->uri))) {
  135. dlg->remote.contact = (pjsip_contact_hdr*)pjsip_hdr_clone(dlg->pool, contact);
  136. dlg->target = dlg->remote.contact->uri;
  137. }
  138. return 0;
  139. }
  140. return -1;
  141. }
  142. static pj_bool_t handle_rx_message(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
  143. {
  144. pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata);
  145. if (!endpoint) {
  146. return PJ_FALSE;
  147. }
  148. if (endpoint->nat.rewrite_contact) {
  149. /* rewrite_contact is intended to ensure we send requests/responses to
  150. * a routeable address when NAT is involved. The URI that dictates where
  151. * we send requests/responses can be determined either by Record-Route
  152. * headers or by the Contact header if no Record-Route headers are present.
  153. * We therefore will attempt to rewrite a Record-Route header first, and if
  154. * none are present, we fall back to rewriting the Contact header instead.
  155. */
  156. if (rewrite_route_set(rdata, dlg)) {
  157. rewrite_contact(rdata, dlg);
  158. }
  159. }
  160. if (endpoint->nat.force_rport) {
  161. rdata->msg_info.via->rport_param = rdata->pkt_info.src_port;
  162. }
  163. return PJ_FALSE;
  164. }
  165. static pj_bool_t nat_on_rx_message(pjsip_rx_data *rdata)
  166. {
  167. pj_bool_t res;
  168. struct ast_sip_endpoint *endpoint;
  169. endpoint = ast_pjsip_rdata_get_endpoint(rdata);
  170. res = handle_rx_message(endpoint, rdata);
  171. ao2_cleanup(endpoint);
  172. return res;
  173. }
  174. /*! \brief Structure which contains information about a transport */
  175. struct request_transport_details {
  176. /*! \brief Type of transport */
  177. enum ast_transport type;
  178. /*! \brief Potential pointer to the transport itself, if UDP */
  179. pjsip_transport *transport;
  180. /*! \brief Potential pointer to the transport factory itself, if TCP/TLS */
  181. pjsip_tpfactory *factory;
  182. /*! \brief Local address for transport */
  183. pj_str_t local_address;
  184. /*! \brief Local port for transport */
  185. int local_port;
  186. };
  187. /*! \brief Callback function for finding the transport the request is going out on */
  188. static int find_transport_state_in_use(void *obj, void *arg, int flags)
  189. {
  190. struct ast_sip_transport_state *transport_state = obj;
  191. struct request_transport_details *details = arg;
  192. /* If an explicit transport or factory matches then this is what is in use, if we are unavailable
  193. * to compare based on that we make sure that the type is the same and the source IP address/port are the same
  194. */
  195. if (transport_state && ((details->transport && details->transport == transport_state->transport) ||
  196. (details->factory && details->factory == transport_state->factory) ||
  197. ((details->type == transport_state->type) && (transport_state->factory) &&
  198. !pj_strcmp(&transport_state->factory->addr_name.host, &details->local_address) &&
  199. transport_state->factory->addr_name.port == details->local_port))) {
  200. return CMP_MATCH;
  201. }
  202. return 0;
  203. }
  204. /*! \brief Helper function which returns the SIP URI of a Contact header */
  205. static pjsip_sip_uri *nat_get_contact_sip_uri(pjsip_tx_data *tdata)
  206. {
  207. pjsip_contact_hdr *contact = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CONTACT, NULL);
  208. if (!contact || (!PJSIP_URI_SCHEME_IS_SIP(contact->uri) && !PJSIP_URI_SCHEME_IS_SIPS(contact->uri))) {
  209. return NULL;
  210. }
  211. return pjsip_uri_get_uri(contact->uri);
  212. }
  213. /*! \brief Structure which contains hook details */
  214. struct nat_hook_details {
  215. /*! \brief Outgoing message itself */
  216. pjsip_tx_data *tdata;
  217. /*! \brief Chosen transport */
  218. struct ast_sip_transport *transport;
  219. };
  220. /*! \brief Callback function for invoking hooks */
  221. static int nat_invoke_hook(void *obj, void *arg, int flags)
  222. {
  223. struct ast_sip_nat_hook *hook = obj;
  224. struct nat_hook_details *details = arg;
  225. if (hook->outgoing_external_message) {
  226. hook->outgoing_external_message(details->tdata, details->transport);
  227. }
  228. return 0;
  229. }
  230. static pj_status_t nat_on_tx_message(pjsip_tx_data *tdata)
  231. {
  232. RAII_VAR(struct ao2_container *, transport_states, NULL, ao2_cleanup);
  233. RAII_VAR(struct ast_sip_transport *, transport, NULL, ao2_cleanup);
  234. RAII_VAR(struct ast_sip_transport_state *, transport_state, NULL, ao2_cleanup);
  235. struct request_transport_details details = { 0, };
  236. pjsip_via_hdr *via = NULL;
  237. struct ast_sockaddr addr = { { 0, } };
  238. pjsip_sip_uri *uri = NULL;
  239. RAII_VAR(struct ao2_container *, hooks, NULL, ao2_cleanup);
  240. /* If a transport selector is in use we know the transport or factory, so explicitly find it */
  241. if (tdata->tp_sel.type == PJSIP_TPSELECTOR_TRANSPORT) {
  242. details.transport = tdata->tp_sel.u.transport;
  243. } else if (tdata->tp_sel.type == PJSIP_TPSELECTOR_LISTENER) {
  244. details.factory = tdata->tp_sel.u.listener;
  245. } else if (tdata->tp_info.transport->key.type == PJSIP_TRANSPORT_UDP || tdata->tp_info.transport->key.type == PJSIP_TRANSPORT_UDP6) {
  246. /* Connectionless uses the same transport for all requests */
  247. details.type = AST_TRANSPORT_UDP;
  248. details.transport = tdata->tp_info.transport;
  249. } else {
  250. if (tdata->tp_info.transport->key.type == PJSIP_TRANSPORT_TCP) {
  251. details.type = AST_TRANSPORT_TCP;
  252. } else if (tdata->tp_info.transport->key.type == PJSIP_TRANSPORT_TLS) {
  253. details.type = AST_TRANSPORT_TLS;
  254. } else {
  255. /* Unknown transport type, we can't map and thus can't apply NAT changes */
  256. return PJ_SUCCESS;
  257. }
  258. if ((uri = nat_get_contact_sip_uri(tdata))) {
  259. details.local_address = uri->host;
  260. details.local_port = uri->port;
  261. } else if ((tdata->msg->type == PJSIP_REQUEST_MSG) &&
  262. (via = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL))) {
  263. details.local_address = via->sent_by.host;
  264. details.local_port = via->sent_by.port;
  265. } else {
  266. return PJ_SUCCESS;
  267. }
  268. if (!details.local_port) {
  269. details.local_port = (details.type == AST_TRANSPORT_TLS) ? 5061 : 5060;
  270. }
  271. }
  272. if (!(transport_states = ast_sip_get_transport_states())) {
  273. return PJ_SUCCESS;
  274. }
  275. if (!(transport_state = ao2_callback(transport_states, 0, find_transport_state_in_use, &details))) {
  276. return PJ_SUCCESS;
  277. }
  278. if (!(transport = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport", transport_state->id))) {
  279. return PJ_SUCCESS;
  280. }
  281. if (transport_state->localnet) {
  282. ast_sockaddr_parse(&addr, tdata->tp_info.dst_name, PARSE_PORT_FORBID);
  283. ast_sockaddr_set_port(&addr, tdata->tp_info.dst_port);
  284. /* See if where we are sending this request is local or not, and if not that we can get a Contact URI to modify */
  285. if (ast_sip_transport_is_local(transport_state, &addr)) {
  286. ast_debug(5, "Request is being sent to local address, skipping NAT manipulation\n");
  287. return PJ_SUCCESS;
  288. }
  289. }
  290. if (!ast_sockaddr_isnull(&transport_state->external_signaling_address)) {
  291. /* Update the contact header with the external address */
  292. if (uri || (uri = nat_get_contact_sip_uri(tdata))) {
  293. pj_strdup2(tdata->pool, &uri->host, ast_sockaddr_stringify_host(&transport_state->external_signaling_address));
  294. if (transport->external_signaling_port) {
  295. uri->port = transport->external_signaling_port;
  296. ast_debug(4, "Re-wrote Contact URI port to %d\n", uri->port);
  297. }
  298. }
  299. /* Update the via header if relevant */
  300. if ((tdata->msg->type == PJSIP_REQUEST_MSG) && (via || (via = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL)))) {
  301. pj_strdup2(tdata->pool, &via->sent_by.host, ast_sockaddr_stringify_host(&transport_state->external_signaling_address));
  302. if (transport->external_signaling_port) {
  303. via->sent_by.port = transport->external_signaling_port;
  304. }
  305. }
  306. }
  307. /* Invoke any additional hooks that may be registered */
  308. if ((hooks = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "nat_hook", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL))) {
  309. struct nat_hook_details hook_details = {
  310. .tdata = tdata,
  311. .transport = transport,
  312. };
  313. ao2_callback(hooks, 0, nat_invoke_hook, &hook_details);
  314. }
  315. return PJ_SUCCESS;
  316. }
  317. static pjsip_module nat_module = {
  318. .name = { "NAT", 3 },
  319. .id = -1,
  320. .priority = PJSIP_MOD_PRIORITY_TSX_LAYER - 2,
  321. .on_rx_request = nat_on_rx_message,
  322. .on_rx_response = nat_on_rx_message,
  323. .on_tx_request = nat_on_tx_message,
  324. .on_tx_response = nat_on_tx_message,
  325. };
  326. /*! \brief Function called when an INVITE goes out */
  327. static int nat_incoming_invite_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
  328. {
  329. if (session->inv_session->state == PJSIP_INV_STATE_INCOMING) {
  330. pjsip_dlg_add_usage(session->inv_session->dlg, &nat_module, NULL);
  331. }
  332. return 0;
  333. }
  334. /*! \brief Function called when an INVITE response comes in */
  335. static void nat_incoming_invite_response(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
  336. {
  337. handle_rx_message(session->endpoint, rdata);
  338. }
  339. /*! \brief Function called when an INVITE comes in */
  340. static void nat_outgoing_invite_request(struct ast_sip_session *session, struct pjsip_tx_data *tdata)
  341. {
  342. if (session->inv_session->state == PJSIP_INV_STATE_NULL) {
  343. pjsip_dlg_add_usage(session->inv_session->dlg, &nat_module, NULL);
  344. }
  345. }
  346. /*! \brief Supplement for adding NAT functionality to dialog */
  347. static struct ast_sip_session_supplement nat_supplement = {
  348. .method = "INVITE",
  349. .priority = AST_SIP_SUPPLEMENT_PRIORITY_FIRST + 1,
  350. .incoming_request = nat_incoming_invite_request,
  351. .outgoing_request = nat_outgoing_invite_request,
  352. .incoming_response = nat_incoming_invite_response,
  353. };
  354. static int unload_module(void)
  355. {
  356. ast_sip_session_unregister_supplement(&nat_supplement);
  357. ast_sip_unregister_service(&nat_module);
  358. return 0;
  359. }
  360. static int load_module(void)
  361. {
  362. CHECK_PJSIP_SESSION_MODULE_LOADED();
  363. if (ast_sip_register_service(&nat_module)) {
  364. ast_log(LOG_ERROR, "Could not register NAT module for incoming and outgoing requests\n");
  365. return AST_MODULE_LOAD_DECLINE;
  366. }
  367. if (ast_sip_session_register_supplement(&nat_supplement)) {
  368. ast_log(LOG_ERROR, "Could not register NAT session supplement for incoming and outgoing INVITE requests\n");
  369. unload_module();
  370. return AST_MODULE_LOAD_DECLINE;
  371. }
  372. return AST_MODULE_LOAD_SUCCESS;
  373. }
  374. AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP NAT Support",
  375. .support_level = AST_MODULE_SUPPORT_CORE,
  376. .load = load_module,
  377. .unload = unload_module,
  378. .load_pri = AST_MODPRI_APP_DEPEND,
  379. );