res_pjsip_registrar.c 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359
  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_pjproject</depend>
  21. <depend>res_pjsip</depend>
  22. <support_level>core</support_level>
  23. ***/
  24. #include "asterisk.h"
  25. #include <signal.h>
  26. #include <pjsip.h>
  27. #include <pjsip_ua.h>
  28. #include "asterisk/res_pjsip.h"
  29. #include "asterisk/module.h"
  30. #include "asterisk/paths.h"
  31. #include "asterisk/test.h"
  32. #include "asterisk/taskprocessor.h"
  33. #include "asterisk/manager.h"
  34. #include "asterisk/named_locks.h"
  35. #include "asterisk/res_pjproject.h"
  36. #include "res_pjsip/include/res_pjsip_private.h"
  37. /*** DOCUMENTATION
  38. <manager name="PJSIPShowRegistrationsInbound" language="en_US">
  39. <synopsis>
  40. Lists PJSIP inbound registrations.
  41. </synopsis>
  42. <syntax />
  43. <description>
  44. <para>
  45. In response, <literal>InboundRegistrationDetail</literal> events showing configuration
  46. and status information are raised for all contacts, static or dynamic. Once all events
  47. are completed an <literal>InboundRegistrationDetailComplete</literal> is issued.
  48. </para>
  49. <warning><para>
  50. This command just dumps all coonfigured AORs with contacts, even if the contact
  51. is a permanent one. To really get just inbound registrations, use
  52. <literal>PJSIPShowRegistrationInboundContactStatuses</literal>.
  53. </para>
  54. </warning>
  55. </description>
  56. <see-also>
  57. <ref type="manager" module="res_pjsip_registrar">PJSIPShowRegistrationInboundContactStatuses</ref>
  58. </see-also>
  59. </manager>
  60. <manager name="PJSIPShowRegistrationInboundContactStatuses" language="en_US">
  61. <synopsis>
  62. Lists ContactStatuses for PJSIP inbound registrations.
  63. </synopsis>
  64. <syntax />
  65. <description>
  66. <para>
  67. In response, <literal>ContactStatusDetail</literal> events showing status information
  68. are raised for each inbound registration (dynamic contact) object. Once all events
  69. are completed a <literal>ContactStatusDetailComplete</literal> event is issued.
  70. </para>
  71. </description>
  72. </manager>
  73. ***/
  74. static int pj_max_hostname = PJ_MAX_HOSTNAME;
  75. static int pjsip_max_url_size = PJSIP_MAX_URL_SIZE;
  76. /*! \brief Internal function which returns the expiration time for a contact */
  77. static int registrar_get_expiration(const struct ast_sip_aor *aor, const pjsip_contact_hdr *contact, const pjsip_rx_data *rdata)
  78. {
  79. pjsip_expires_hdr *expires;
  80. int expiration = aor->default_expiration;
  81. if (contact && contact->expires != -1) {
  82. /* Expiration was provided with the contact itself */
  83. expiration = contact->expires;
  84. } else if ((expires = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL))) {
  85. /* Expiration was provided using the Expires header */
  86. expiration = expires->ivalue;
  87. }
  88. /* If the value has explicitly been set to 0, do not enforce */
  89. if (!expiration) {
  90. return expiration;
  91. }
  92. /* Enforce the range that we will allow for expiration */
  93. if (expiration < aor->minimum_expiration) {
  94. expiration = aor->minimum_expiration;
  95. } else if (expiration > aor->maximum_expiration) {
  96. expiration = aor->maximum_expiration;
  97. }
  98. return expiration;
  99. }
  100. /*! \brief Structure used for finding contact */
  101. struct registrar_contact_details {
  102. /*! \brief Pool used for parsing URI */
  103. pj_pool_t *pool;
  104. /*! \brief URI being looked for */
  105. pjsip_sip_uri *uri;
  106. };
  107. /*! \brief Callback function for finding a contact */
  108. static int registrar_find_contact(void *obj, void *arg, int flags)
  109. {
  110. struct ast_sip_contact *contact = obj;
  111. const struct registrar_contact_details *details = arg;
  112. pjsip_uri *contact_uri;
  113. if (ast_tvzero(contact->expiration_time)) {
  114. return 0;
  115. }
  116. contact_uri = pjsip_parse_uri(details->pool, (char*)contact->uri, strlen(contact->uri), 0);
  117. return (pjsip_uri_cmp(PJSIP_URI_IN_CONTACT_HDR, details->uri, contact_uri) == PJ_SUCCESS) ? CMP_MATCH : 0;
  118. }
  119. /*! \brief Internal function which validates provided Contact headers to confirm that they are acceptable, and returns number of contacts */
  120. static int registrar_validate_contacts(const pjsip_rx_data *rdata, pj_pool_t *pool, struct ao2_container *contacts,
  121. struct ast_sip_aor *aor, int permanent, int *added, int *updated, int *deleted)
  122. {
  123. pjsip_contact_hdr *previous = NULL;
  124. pjsip_contact_hdr *contact = (pjsip_contact_hdr *)&rdata->msg_info.msg->hdr;
  125. struct registrar_contact_details details = {
  126. .pool = pool,
  127. };
  128. for (; (contact = (pjsip_contact_hdr *) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, contact->next)); pj_pool_reset(pool)) {
  129. int expiration = registrar_get_expiration(aor, contact, rdata);
  130. struct ast_sip_contact *existing;
  131. char contact_uri[pjsip_max_url_size];
  132. if (contact->star) {
  133. /* The expiration MUST be 0 when a '*' contact is used and there must be no other contact */
  134. if (expiration != 0 || previous) {
  135. return -1;
  136. }
  137. /* Count all contacts to delete */
  138. *deleted = ao2_container_count(contacts) - permanent;
  139. previous = contact;
  140. continue;
  141. } else if (previous && previous->star) {
  142. /* If there is a previous contact and it is a '*' this is a deal breaker */
  143. return -1;
  144. }
  145. previous = contact;
  146. if (!PJSIP_URI_SCHEME_IS_SIP(contact->uri) && !PJSIP_URI_SCHEME_IS_SIPS(contact->uri)) {
  147. continue;
  148. }
  149. details.uri = pjsip_uri_get_uri(contact->uri);
  150. /* pjsip_uri_print returns -1 if there's not enough room in the buffer */
  151. if (pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, details.uri, contact_uri, sizeof(contact_uri)) < 0) {
  152. /* If the total length of the uri is greater than pjproject can handle, go no further */
  153. return -1;
  154. }
  155. if (details.uri->host.slen >= pj_max_hostname) {
  156. /* If the length of the hostname is greater than pjproject can handle, go no further */
  157. return -1;
  158. }
  159. /* Determine if this is an add, update, or delete for policy enforcement purposes */
  160. existing = ao2_callback(contacts, 0, registrar_find_contact, &details);
  161. ao2_cleanup(existing);
  162. if (!existing) {
  163. if (expiration) {
  164. ++*added;
  165. }
  166. } else if (expiration) {
  167. ++*updated;
  168. } else {
  169. ++*deleted;
  170. }
  171. }
  172. return 0;
  173. }
  174. /*! \brief Internal function used to delete a contact from an AOR */
  175. static int registrar_delete_contact(void *obj, void *arg, int flags)
  176. {
  177. struct ast_sip_contact *contact = obj;
  178. const char *aor_name = arg;
  179. /* Permanent contacts can't be deleted */
  180. if (ast_tvzero(contact->expiration_time)) {
  181. return 0;
  182. }
  183. ast_sip_location_delete_contact(contact);
  184. if (!ast_strlen_zero(aor_name)) {
  185. ast_verb(3, "Removed contact '%s' from AOR '%s' due to request\n", contact->uri, aor_name);
  186. ast_test_suite_event_notify("AOR_CONTACT_REMOVED",
  187. "Contact: %s\r\n"
  188. "AOR: %s\r\n"
  189. "UserAgent: %s",
  190. contact->uri,
  191. aor_name,
  192. contact->user_agent);
  193. }
  194. return CMP_MATCH;
  195. }
  196. /*! \brief Internal function which adds a contact to a response */
  197. static int registrar_add_contact(void *obj, void *arg, int flags)
  198. {
  199. struct ast_sip_contact *contact = obj;
  200. pjsip_tx_data *tdata = arg;
  201. pjsip_contact_hdr *hdr = pjsip_contact_hdr_create(tdata->pool);
  202. pj_str_t uri;
  203. pj_strdup2_with_null(tdata->pool, &uri, contact->uri);
  204. hdr->uri = pjsip_parse_uri(tdata->pool, uri.ptr, uri.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
  205. hdr->expires = ast_tvdiff_ms(contact->expiration_time, ast_tvnow()) / 1000;
  206. pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hdr);
  207. return 0;
  208. }
  209. /*! \brief Helper function which adds a Date header to a response */
  210. static void registrar_add_date_header(pjsip_tx_data *tdata)
  211. {
  212. char date[256];
  213. struct tm tm;
  214. time_t t = time(NULL);
  215. gmtime_r(&t, &tm);
  216. strftime(date, sizeof(date), "%a, %d %b %Y %T GMT", &tm);
  217. ast_sip_add_header(tdata, "Date", date);
  218. }
  219. static const pj_str_t path_hdr_name = { "Path", 4 };
  220. static int build_path_data(pjsip_rx_data *rdata, struct ast_str **path_str)
  221. {
  222. pjsip_generic_string_hdr *path_hdr = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &path_hdr_name, NULL);
  223. if (!path_hdr) {
  224. return 0;
  225. }
  226. *path_str = ast_str_create(64);
  227. if (!*path_str) {
  228. return -1;
  229. }
  230. ast_str_set(path_str, 0, "%.*s", (int)path_hdr->hvalue.slen, path_hdr->hvalue.ptr);
  231. while ((path_hdr = (pjsip_generic_string_hdr *) pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &path_hdr_name, path_hdr->next))) {
  232. ast_str_append(path_str, 0, ",%.*s", (int)path_hdr->hvalue.slen, path_hdr->hvalue.ptr);
  233. }
  234. return 0;
  235. }
  236. static int registrar_validate_path(pjsip_rx_data *rdata, struct ast_sip_aor *aor, struct ast_str **path_str)
  237. {
  238. const pj_str_t path_supported_name = { "path", 4 };
  239. pjsip_supported_hdr *supported_hdr;
  240. int i;
  241. if (!aor->support_path) {
  242. return 0;
  243. }
  244. if (build_path_data(rdata, path_str)) {
  245. return -1;
  246. }
  247. if (!*path_str) {
  248. return 0;
  249. }
  250. supported_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_SUPPORTED, NULL);
  251. if (!supported_hdr) {
  252. return -1;
  253. }
  254. /* Find advertised path support */
  255. for (i = 0; i < supported_hdr->count; i++) {
  256. if (!pj_stricmp(&supported_hdr->values[i], &path_supported_name)) {
  257. return 0;
  258. }
  259. }
  260. /* Path header present, but support not advertised */
  261. return -1;
  262. }
  263. /*! Transport monitor for incoming REGISTER contacts */
  264. struct contact_transport_monitor {
  265. /*!
  266. * \brief Sorcery contact name to remove on transport shutdown
  267. * \note Stored after aor_name in space reserved when struct allocated.
  268. */
  269. char *contact_name;
  270. /*! Indicates that the monitor is in the process of removing a contact */
  271. int removing;
  272. /*! AOR name the contact is associated */
  273. char aor_name[0];
  274. };
  275. static int contact_transport_monitor_matcher(void *a, void *b)
  276. {
  277. struct contact_transport_monitor *ma = a;
  278. struct contact_transport_monitor *mb = b;
  279. return strcmp(ma->aor_name, mb->aor_name) == 0
  280. && strcmp(ma->contact_name, mb->contact_name) == 0;
  281. }
  282. static int register_contact_transport_remove_cb(void *data)
  283. {
  284. struct contact_transport_monitor *monitor = data;
  285. struct ast_sip_contact *contact;
  286. struct ast_named_lock *lock;
  287. lock = ast_named_lock_get(AST_NAMED_LOCK_TYPE_MUTEX, "aor", monitor->aor_name);
  288. if (!lock) {
  289. ao2_lock(monitor);
  290. monitor->removing = 0;
  291. ao2_unlock(monitor);
  292. ao2_ref(monitor, -1);
  293. return 0;
  294. }
  295. ao2_lock(lock);
  296. contact = ast_sip_location_retrieve_contact(monitor->contact_name);
  297. if (contact) {
  298. ast_sip_location_delete_contact(contact);
  299. ast_verb(3, "Removed contact '%s' from AOR '%s' due to transport shutdown\n",
  300. contact->uri, monitor->aor_name);
  301. ast_test_suite_event_notify("AOR_CONTACT_REMOVED",
  302. "Contact: %s\r\n"
  303. "AOR: %s\r\n"
  304. "UserAgent: %s",
  305. contact->uri,
  306. monitor->aor_name,
  307. contact->user_agent);
  308. ao2_ref(contact, -1);
  309. }
  310. ao2_unlock(lock);
  311. ast_named_lock_put(lock);
  312. ao2_ref(monitor, -1);
  313. return 0;
  314. }
  315. /*!
  316. * \internal
  317. * \brief The reliable transport we registered as a contact has shutdown.
  318. *
  319. * \param data What contact needs to be removed.
  320. *
  321. * \note Normally executed by the pjsip monitor thread.
  322. *
  323. * \return Nothing
  324. */
  325. static void register_contact_transport_shutdown_cb(void *data)
  326. {
  327. struct contact_transport_monitor *monitor = data;
  328. /*
  329. * It's possible for this shutdown handler to get called multiple times for the
  330. * same monitor from different threads. Only one of the calls needs to do the
  331. * actual removing of the contact, so if one is currently removing then any
  332. * subsequent calls can skip.
  333. */
  334. ao2_lock(monitor);
  335. if (monitor->removing) {
  336. ao2_unlock(monitor);
  337. return;
  338. }
  339. monitor->removing = 1;
  340. /*
  341. * Push off to a default serializer. This is in case sorcery
  342. * does database accesses for contacts. Database accesses may
  343. * not be on this machine. We don't want to tie up the pjsip
  344. * monitor thread with potentially long access times.
  345. */
  346. ao2_ref(monitor, +1);
  347. if (ast_sip_push_task(NULL, register_contact_transport_remove_cb, monitor)) {
  348. monitor->removing = 0;
  349. ao2_ref(monitor, -1);
  350. }
  351. ao2_unlock(monitor);
  352. }
  353. AST_VECTOR(excess_contact_vector, struct ast_sip_contact *);
  354. static int vec_contact_cmp(struct ast_sip_contact *left, struct ast_sip_contact *right)
  355. {
  356. struct ast_sip_contact *left_contact = left;
  357. struct ast_sip_contact *right_contact = right;
  358. /* Sort from soonest to expire to last to expire */
  359. return ast_tvcmp(left_contact->expiration_time, right_contact->expiration_time);
  360. }
  361. static int vec_contact_add(void *obj, void *arg, int flags)
  362. {
  363. struct ast_sip_contact *contact = obj;
  364. struct excess_contact_vector *contact_vec = arg;
  365. /*
  366. * Performance wise, an insertion sort is fine because we
  367. * shouldn't need to remove more than a handful of contacts.
  368. * I expect we'll typically be removing only one contact.
  369. */
  370. AST_VECTOR_ADD_SORTED(contact_vec, contact, vec_contact_cmp);
  371. if (AST_VECTOR_SIZE(contact_vec) == AST_VECTOR_MAX_SIZE(contact_vec)) {
  372. /*
  373. * We added a contact over the number we need to remove.
  374. * Remove the longest to expire contact from the vector
  375. * which is the last element in the vector. It may be
  376. * the one we just added or the one we just added pushed
  377. * out an earlier contact from removal consideration.
  378. */
  379. --AST_VECTOR_SIZE(contact_vec);
  380. }
  381. return 0;
  382. }
  383. /*!
  384. * \internal
  385. * \brief Remove excess existing contacts that expire the soonest.
  386. * \since 13.18.0
  387. *
  388. * \param contacts Container of unmodified contacts that could remove.
  389. * \param to_remove Maximum number of contacts to remove.
  390. *
  391. * \return Nothing
  392. */
  393. static void remove_excess_contacts(struct ao2_container *contacts, struct ao2_container *response_contacts,
  394. unsigned int to_remove)
  395. {
  396. struct excess_contact_vector contact_vec;
  397. /*
  398. * Create a sorted vector to hold the to_remove soonest to
  399. * expire contacts. The vector has an extra space to
  400. * temporarily hold the longest to expire contact that we
  401. * won't remove.
  402. */
  403. if (AST_VECTOR_INIT(&contact_vec, to_remove + 1)) {
  404. return;
  405. }
  406. ao2_callback(contacts, OBJ_NODATA | OBJ_MULTIPLE, vec_contact_add, &contact_vec);
  407. /*
  408. * The vector should always be populated with the number
  409. * of contacts we need to remove. Just in case, we will
  410. * remove all contacts in the vector even if the contacts
  411. * container had fewer contacts than there should be.
  412. */
  413. ast_assert(AST_VECTOR_SIZE(&contact_vec) == to_remove);
  414. to_remove = AST_VECTOR_SIZE(&contact_vec);
  415. /* Remove the excess contacts that expire the soonest */
  416. while (to_remove--) {
  417. struct ast_sip_contact *contact;
  418. contact = AST_VECTOR_GET(&contact_vec, to_remove);
  419. ast_sip_location_delete_contact(contact);
  420. ast_verb(3, "Removed contact '%s' from AOR '%s' due to remove_existing\n",
  421. contact->uri, contact->aor);
  422. ast_test_suite_event_notify("AOR_CONTACT_REMOVED",
  423. "Contact: %s\r\n"
  424. "AOR: %s\r\n"
  425. "UserAgent: %s",
  426. contact->uri,
  427. contact->aor,
  428. contact->user_agent);
  429. ao2_unlink(response_contacts, contact);
  430. }
  431. AST_VECTOR_FREE(&contact_vec);
  432. }
  433. /*! \brief Callback function which adds non-permanent contacts to a container */
  434. static int registrar_add_non_permanent(void *obj, void *arg, int flags)
  435. {
  436. struct ast_sip_contact *contact = obj;
  437. struct ao2_container *container = arg;
  438. if (ast_tvzero(contact->expiration_time)) {
  439. return 0;
  440. }
  441. ao2_link(container, contact);
  442. return 0;
  443. }
  444. struct aor_core_response {
  445. /*! Tx data to use for statefull response. NULL for stateless response. */
  446. pjsip_tx_data *tdata;
  447. /*! SIP response code to send in stateless response */
  448. int code;
  449. };
  450. static void register_aor_core(pjsip_rx_data *rdata,
  451. struct ast_sip_endpoint *endpoint,
  452. struct ast_sip_aor *aor,
  453. const char *aor_name,
  454. struct ao2_container *contacts,
  455. struct aor_core_response *response)
  456. {
  457. static const pj_str_t USER_AGENT = { "User-Agent", 10 };
  458. int added = 0;
  459. int updated = 0;
  460. int deleted = 0;
  461. int permanent = 0;
  462. int contact_count;
  463. struct ao2_container *existing_contacts = NULL;
  464. pjsip_contact_hdr *contact_hdr = (pjsip_contact_hdr *)&rdata->msg_info.msg->hdr;
  465. struct registrar_contact_details details = { 0, };
  466. pjsip_tx_data *tdata;
  467. RAII_VAR(struct ast_str *, path_str, NULL, ast_free);
  468. struct ast_sip_contact *response_contact;
  469. char *user_agent = NULL;
  470. pjsip_user_agent_hdr *user_agent_hdr;
  471. pjsip_expires_hdr *expires_hdr;
  472. pjsip_via_hdr *via_hdr;
  473. pjsip_via_hdr *via_hdr_last;
  474. char *via_addr = NULL;
  475. int via_port = 0;
  476. pjsip_cid_hdr *call_id_hdr;
  477. char *call_id = NULL;
  478. size_t alloc_size;
  479. /* We create a single pool and use it throughout this function where we need one */
  480. details.pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(),
  481. "Contact Comparison", 1024, 256);
  482. if (!details.pool) {
  483. response->code = 500;
  484. return;
  485. }
  486. /* If there are any permanent contacts configured on the AOR we need to take them
  487. * into account when counting contacts.
  488. */
  489. if (aor->permanent_contacts) {
  490. permanent = ao2_container_count(aor->permanent_contacts);
  491. }
  492. if (registrar_validate_contacts(rdata, details.pool, contacts, aor, permanent, &added, &updated, &deleted)) {
  493. /* The provided Contact headers do not conform to the specification */
  494. ast_sip_report_failed_acl(endpoint, rdata, "registrar_invalid_contacts_provided");
  495. ast_log(LOG_WARNING, "Failed to validate contacts in REGISTER request from '%s'\n",
  496. ast_sorcery_object_get_id(endpoint));
  497. response->code = 400;
  498. pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
  499. return;
  500. }
  501. if (registrar_validate_path(rdata, aor, &path_str)) {
  502. /* Ensure that intervening proxies did not make invalid modifications to the request */
  503. ast_log(LOG_WARNING, "Invalid modifications made to REGISTER request from '%s' by intervening proxy\n",
  504. ast_sorcery_object_get_id(endpoint));
  505. response->code = 420;
  506. pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
  507. return;
  508. }
  509. if (aor->remove_existing) {
  510. /* Cumulative number of contacts affected by this registration */
  511. contact_count = MAX(updated + added - deleted, 0);
  512. /* We need to keep track of only existing contacts so we can later
  513. * remove them if need be.
  514. */
  515. existing_contacts = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0,
  516. NULL, ast_sorcery_object_id_compare);
  517. if (!existing_contacts) {
  518. response->code = 500;
  519. pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
  520. return;
  521. }
  522. ao2_callback(contacts, OBJ_NODATA, registrar_add_non_permanent, existing_contacts);
  523. } else {
  524. /* Total contacts after this registration */
  525. contact_count = ao2_container_count(contacts) - permanent + added - deleted;
  526. }
  527. if (contact_count > aor->max_contacts) {
  528. /* Enforce the maximum number of contacts */
  529. ast_sip_report_failed_acl(endpoint, rdata, "registrar_attempt_exceeds_maximum_configured_contacts");
  530. ast_log(LOG_WARNING, "Registration attempt from endpoint '%s' to AOR '%s' will exceed max contacts of %u\n",
  531. ast_sorcery_object_get_id(endpoint), aor_name, aor->max_contacts);
  532. response->code = 403;
  533. pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
  534. ao2_cleanup(existing_contacts);
  535. return;
  536. }
  537. user_agent_hdr = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &USER_AGENT, NULL);
  538. if (user_agent_hdr) {
  539. alloc_size = pj_strlen(&user_agent_hdr->hvalue) + 1;
  540. user_agent = ast_alloca(alloc_size);
  541. ast_copy_pj_str(user_agent, &user_agent_hdr->hvalue, alloc_size);
  542. }
  543. /* Find the first Via header */
  544. via_hdr = via_hdr_last = (pjsip_via_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_VIA, NULL);
  545. if (via_hdr) {
  546. /* Find the last Via header */
  547. while ( (via_hdr = (pjsip_via_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg,
  548. PJSIP_H_VIA, via_hdr->next)) != NULL) {
  549. via_hdr_last = via_hdr;
  550. }
  551. alloc_size = pj_strlen(&via_hdr_last->sent_by.host) + 1;
  552. via_addr = ast_alloca(alloc_size);
  553. ast_copy_pj_str(via_addr, &via_hdr_last->sent_by.host, alloc_size);
  554. via_port=via_hdr_last->sent_by.port;
  555. }
  556. call_id_hdr = (pjsip_cid_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CALL_ID, NULL);
  557. if (call_id_hdr) {
  558. alloc_size = pj_strlen(&call_id_hdr->id) + 1;
  559. call_id = ast_alloca(alloc_size);
  560. ast_copy_pj_str(call_id, &call_id_hdr->id, alloc_size);
  561. }
  562. /* Iterate each provided Contact header and add, update, or delete */
  563. for (; (contact_hdr = (pjsip_contact_hdr *) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, contact_hdr->next)); pj_pool_reset(details.pool)) {
  564. int expiration;
  565. char contact_uri[pjsip_max_url_size];
  566. RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup);
  567. if (contact_hdr->star) {
  568. /* A star means to unregister everything, so do so for the possible contacts */
  569. ao2_callback(contacts, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE,
  570. registrar_delete_contact, (void *)aor_name);
  571. /* If we are keeping track of existing contacts for removal then, well, there is
  572. * absolutely nothing left so no need to try to remove any.
  573. */
  574. if (existing_contacts) {
  575. ao2_ref(existing_contacts, -1);
  576. existing_contacts = NULL;
  577. }
  578. break;
  579. }
  580. if (!PJSIP_URI_SCHEME_IS_SIP(contact_hdr->uri) && !PJSIP_URI_SCHEME_IS_SIPS(contact_hdr->uri)) {
  581. /* This registrar only currently supports sip: and sips: URI schemes */
  582. continue;
  583. }
  584. expiration = registrar_get_expiration(aor, contact_hdr, rdata);
  585. details.uri = pjsip_uri_get_uri(contact_hdr->uri);
  586. pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, details.uri, contact_uri, sizeof(contact_uri));
  587. contact = ao2_callback(contacts, OBJ_UNLINK, registrar_find_contact, &details);
  588. /* If a contact was returned and we need to keep track of existing contacts then it
  589. * should be removed.
  590. */
  591. if (contact && existing_contacts) {
  592. ao2_unlink(existing_contacts, contact);
  593. }
  594. if (!contact) {
  595. int prune_on_boot;
  596. /* If they are actually trying to delete a contact that does not exist... be forgiving */
  597. if (!expiration) {
  598. ast_verb(3, "Attempted to remove non-existent contact '%s' from AOR '%s' by request\n",
  599. contact_uri, aor_name);
  600. continue;
  601. }
  602. prune_on_boot = !ast_sip_will_uri_survive_restart(details.uri, endpoint, rdata);
  603. contact = ast_sip_location_create_contact(aor, contact_uri,
  604. ast_tvadd(ast_tvnow(), ast_samp2tv(expiration, 1)),
  605. path_str ? ast_str_buffer(path_str) : NULL,
  606. user_agent, via_addr, via_port, call_id, prune_on_boot, endpoint);
  607. if (!contact) {
  608. ast_log(LOG_ERROR, "Unable to bind contact '%s' to AOR '%s'\n",
  609. contact_uri, aor_name);
  610. continue;
  611. }
  612. if (prune_on_boot) {
  613. const char *contact_name;
  614. struct contact_transport_monitor *monitor;
  615. /*
  616. * Monitor the transport in case it gets disconnected because
  617. * the contact won't be valid anymore if that happens.
  618. */
  619. contact_name = ast_sorcery_object_get_id(contact);
  620. monitor = ao2_alloc(sizeof(*monitor) + 2 + strlen(aor_name)
  621. + strlen(contact_name), NULL);
  622. if (monitor) {
  623. strcpy(monitor->aor_name, aor_name);/* Safe */
  624. monitor->contact_name = monitor->aor_name + strlen(aor_name) + 1;
  625. strcpy(monitor->contact_name, contact_name);/* Safe */
  626. ast_sip_transport_monitor_register(rdata->tp_info.transport,
  627. register_contact_transport_shutdown_cb, monitor);
  628. ao2_ref(monitor, -1);
  629. }
  630. }
  631. ast_verb(3, "Added contact '%s' to AOR '%s' with expiration of %d seconds\n",
  632. contact_uri, aor_name, expiration);
  633. ast_test_suite_event_notify("AOR_CONTACT_ADDED",
  634. "Contact: %s\r\n"
  635. "AOR: %s\r\n"
  636. "Expiration: %d\r\n"
  637. "UserAgent: %s",
  638. contact_uri,
  639. aor_name,
  640. expiration,
  641. user_agent);
  642. ao2_link(contacts, contact);
  643. } else if (expiration) {
  644. struct ast_sip_contact *contact_update;
  645. contact_update = ast_sorcery_copy(ast_sip_get_sorcery(), contact);
  646. if (!contact_update) {
  647. ast_log(LOG_ERROR, "Failed to update contact '%s' expiration time to %d seconds.\n",
  648. contact->uri, expiration);
  649. continue;
  650. }
  651. contact_update->expiration_time = ast_tvadd(ast_tvnow(), ast_samp2tv(expiration, 1));
  652. contact_update->qualify_frequency = aor->qualify_frequency;
  653. contact_update->authenticate_qualify = aor->authenticate_qualify;
  654. if (path_str) {
  655. ast_string_field_set(contact_update, path, ast_str_buffer(path_str));
  656. }
  657. if (user_agent) {
  658. ast_string_field_set(contact_update, user_agent, user_agent);
  659. }
  660. if (!ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) {
  661. ast_string_field_set(contact_update, reg_server, ast_config_AST_SYSTEM_NAME);
  662. }
  663. if (ast_sip_location_update_contact(contact_update)) {
  664. ast_log(LOG_ERROR, "Failed to update contact '%s' expiration time to %d seconds.\n",
  665. contact->uri, expiration);
  666. ast_sip_location_delete_contact(contact);
  667. continue;
  668. }
  669. ast_debug(3, "Refreshed contact '%s' on AOR '%s' with new expiration of %d seconds\n",
  670. contact_uri, aor_name, expiration);
  671. ast_test_suite_event_notify("AOR_CONTACT_REFRESHED",
  672. "Contact: %s\r\n"
  673. "AOR: %s\r\n"
  674. "Expiration: %d\r\n"
  675. "UserAgent: %s",
  676. contact_uri,
  677. aor_name,
  678. expiration,
  679. contact_update->user_agent);
  680. ao2_link(contacts, contact_update);
  681. ao2_cleanup(contact_update);
  682. } else {
  683. if (contact->prune_on_boot) {
  684. struct contact_transport_monitor *monitor;
  685. const char *contact_name =
  686. ast_sorcery_object_get_id(contact);
  687. monitor = ast_alloca(sizeof(*monitor) + 2 + strlen(aor_name)
  688. + strlen(contact_name));
  689. strcpy(monitor->aor_name, aor_name);/* Safe */
  690. monitor->contact_name = monitor->aor_name + strlen(aor_name) + 1;
  691. strcpy(monitor->contact_name, contact_name);/* Safe */
  692. ast_sip_transport_monitor_unregister(rdata->tp_info.transport,
  693. register_contact_transport_shutdown_cb, monitor, contact_transport_monitor_matcher);
  694. }
  695. /* We want to report the user agent that was actually in the removed contact */
  696. ast_sip_location_delete_contact(contact);
  697. ast_verb(3, "Removed contact '%s' from AOR '%s' due to request\n", contact_uri, aor_name);
  698. ast_test_suite_event_notify("AOR_CONTACT_REMOVED",
  699. "Contact: %s\r\n"
  700. "AOR: %s\r\n"
  701. "UserAgent: %s",
  702. contact_uri,
  703. aor_name,
  704. contact->user_agent);
  705. }
  706. }
  707. pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
  708. /*
  709. * If the AOR is configured to remove any contacts over max_contacts
  710. * that have not been updated/added/deleted as a result of this
  711. * REGISTER do so.
  712. *
  713. * The existing contacts container holds all contacts that were not
  714. * involved in this REGISTER.
  715. * The contacts container holds the current contacts of the AOR.
  716. */
  717. if (aor->remove_existing && existing_contacts) {
  718. /* Total contacts after this registration */
  719. contact_count = ao2_container_count(existing_contacts) + updated + added;
  720. if (contact_count > aor->max_contacts) {
  721. /* Remove excess existing contacts that expire the soonest */
  722. remove_excess_contacts(existing_contacts, contacts, contact_count - aor->max_contacts);
  723. }
  724. ao2_ref(existing_contacts, -1);
  725. }
  726. response_contact = ao2_callback(contacts, 0, NULL, NULL);
  727. /* Send a response containing all of the contacts (including static) that are present on this AOR */
  728. if (ast_sip_create_response(rdata, 200, response_contact, &tdata) != PJ_SUCCESS) {
  729. ao2_cleanup(response_contact);
  730. ao2_cleanup(contacts);
  731. response->code = 500;
  732. return;
  733. }
  734. ao2_cleanup(response_contact);
  735. /* Add the date header to the response, some UAs use this to set their date and time */
  736. registrar_add_date_header(tdata);
  737. ao2_callback(contacts, 0, registrar_add_contact, tdata);
  738. if ((expires_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL))) {
  739. expires_hdr = pjsip_expires_hdr_create(tdata->pool, registrar_get_expiration(aor, NULL, rdata));
  740. pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)expires_hdr);
  741. }
  742. response->tdata = tdata;
  743. }
  744. static int register_aor(pjsip_rx_data *rdata,
  745. struct ast_sip_endpoint *endpoint,
  746. struct ast_sip_aor *aor,
  747. const char *aor_name)
  748. {
  749. struct aor_core_response response = {
  750. .code = 500,
  751. };
  752. struct ao2_container *contacts = NULL;
  753. struct ast_named_lock *lock;
  754. lock = ast_named_lock_get(AST_NAMED_LOCK_TYPE_MUTEX, "aor", aor_name);
  755. if (!lock) {
  756. pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(),
  757. rdata, response.code, NULL, NULL, NULL);
  758. return PJ_TRUE;
  759. }
  760. ao2_lock(lock);
  761. contacts = ast_sip_location_retrieve_aor_contacts_nolock(aor);
  762. if (!contacts) {
  763. ao2_unlock(lock);
  764. ast_named_lock_put(lock);
  765. pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(),
  766. rdata, response.code, NULL, NULL, NULL);
  767. return PJ_TRUE;
  768. }
  769. register_aor_core(rdata, endpoint, aor, aor_name, contacts, &response);
  770. ao2_cleanup(contacts);
  771. ao2_unlock(lock);
  772. ast_named_lock_put(lock);
  773. /* Now send the REGISTER response to the peer */
  774. if (response.tdata) {
  775. ast_sip_send_stateful_response(rdata, response.tdata, endpoint);
  776. } else {
  777. pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(),
  778. rdata, response.code, NULL, NULL, NULL);
  779. }
  780. return PJ_TRUE;
  781. }
  782. static int match_aor(const char *aor_name, const char *id)
  783. {
  784. if (ast_strlen_zero(aor_name)) {
  785. return 0;
  786. }
  787. if (!strcmp(aor_name, id)) {
  788. ast_debug(3, "Matched id '%s' to aor '%s'\n", id, aor_name);
  789. return 1;
  790. }
  791. return 0;
  792. }
  793. static char *find_aor_name(const char *username, const char *domain, const char *aors)
  794. {
  795. char *configured_aors;
  796. char *aors_buf;
  797. char *aor_name;
  798. char *id_domain;
  799. struct ast_sip_domain_alias *alias;
  800. id_domain = ast_alloca(strlen(username) + strlen(domain) + 2);
  801. sprintf(id_domain, "%s@%s", username, domain);
  802. aors_buf = ast_strdupa(aors);
  803. /* Look for exact match on username@domain */
  804. configured_aors = aors_buf;
  805. while ((aor_name = ast_strip(strsep(&configured_aors, ",")))) {
  806. if (match_aor(aor_name, id_domain)) {
  807. return ast_strdup(aor_name);
  808. }
  809. }
  810. /* If there's a domain alias, look for exact match on username@domain_alias */
  811. alias = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "domain_alias", domain);
  812. if (alias) {
  813. char *id_domain_alias = ast_alloca(strlen(username) + strlen(alias->domain) + 2);
  814. sprintf(id_domain, "%s@%s", username, alias->domain);
  815. ao2_cleanup(alias);
  816. configured_aors = strcpy(aors_buf, aors);/* Safe */
  817. while ((aor_name = ast_strip(strsep(&configured_aors, ",")))) {
  818. if (match_aor(aor_name, id_domain_alias)) {
  819. return ast_strdup(aor_name);
  820. }
  821. }
  822. }
  823. if (ast_strlen_zero(username)) {
  824. /* No username, no match */
  825. return NULL;
  826. }
  827. /* Look for exact match on username only */
  828. configured_aors = strcpy(aors_buf, aors);/* Safe */
  829. while ((aor_name = ast_strip(strsep(&configured_aors, ",")))) {
  830. if (match_aor(aor_name, username)) {
  831. return ast_strdup(aor_name);
  832. }
  833. }
  834. return NULL;
  835. }
  836. static struct ast_sip_aor *find_registrar_aor(struct pjsip_rx_data *rdata, struct ast_sip_endpoint *endpoint)
  837. {
  838. struct ast_sip_aor *aor = NULL;
  839. char *aor_name = NULL;
  840. char *domain_name;
  841. char *username = NULL;
  842. int i;
  843. for (i = 0; i < AST_VECTOR_SIZE(&endpoint->ident_method_order); ++i) {
  844. pjsip_sip_uri *uri;
  845. pjsip_authorization_hdr *header = NULL;
  846. switch (AST_VECTOR_GET(&endpoint->ident_method_order, i)) {
  847. case AST_SIP_ENDPOINT_IDENTIFY_BY_USERNAME:
  848. uri = pjsip_uri_get_uri(rdata->msg_info.to->uri);
  849. domain_name = ast_alloca(uri->host.slen + 1);
  850. ast_copy_pj_str(domain_name, &uri->host, uri->host.slen + 1);
  851. username = ast_alloca(uri->user.slen + 1);
  852. ast_copy_pj_str(username, &uri->user, uri->user.slen + 1);
  853. /*
  854. * We may want to match without any user options getting
  855. * in the way.
  856. */
  857. AST_SIP_USER_OPTIONS_TRUNCATE_CHECK(username);
  858. aor_name = find_aor_name(username, domain_name, endpoint->aors);
  859. if (aor_name) {
  860. ast_debug(3, "Matched aor '%s' by To username\n", aor_name);
  861. }
  862. break;
  863. case AST_SIP_ENDPOINT_IDENTIFY_BY_AUTH_USERNAME:
  864. while ((header = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_AUTHORIZATION,
  865. header ? header->next : NULL))) {
  866. if (header && !pj_stricmp2(&header->scheme, "digest")) {
  867. username = ast_alloca(header->credential.digest.username.slen + 1);
  868. ast_copy_pj_str(username, &header->credential.digest.username, header->credential.digest.username.slen + 1);
  869. domain_name = ast_alloca(header->credential.digest.realm.slen + 1);
  870. ast_copy_pj_str(domain_name, &header->credential.digest.realm, header->credential.digest.realm.slen + 1);
  871. aor_name = find_aor_name(username, domain_name, endpoint->aors);
  872. if (aor_name) {
  873. ast_debug(3, "Matched aor '%s' by Authentication username\n", aor_name);
  874. break;
  875. }
  876. }
  877. }
  878. break;
  879. default:
  880. continue;
  881. }
  882. if (aor_name) {
  883. break;
  884. }
  885. }
  886. if (ast_strlen_zero(aor_name) || !(aor = ast_sip_location_retrieve_aor(aor_name))) {
  887. /* The provided AOR name was not found (be it within the configuration or sorcery itself) */
  888. pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 404, NULL, NULL, NULL);
  889. ast_sip_report_req_no_support(endpoint, rdata, "registrar_requested_aor_not_found");
  890. ast_log(LOG_WARNING, "AOR '%s' not found for endpoint '%s'\n",
  891. username ?: "", ast_sorcery_object_get_id(endpoint));
  892. }
  893. ast_free(aor_name);
  894. return aor;
  895. }
  896. static pj_bool_t registrar_on_rx_request(struct pjsip_rx_data *rdata)
  897. {
  898. RAII_VAR(struct ast_sip_endpoint *, endpoint,
  899. ast_pjsip_rdata_get_endpoint(rdata), ao2_cleanup);
  900. struct ast_sip_aor *aor;
  901. const char *aor_name;
  902. if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_register_method) || !endpoint) {
  903. return PJ_FALSE;
  904. }
  905. if (ast_strlen_zero(endpoint->aors)) {
  906. /* Short circuit early if the endpoint has no AORs configured on it, which means no registration possible */
  907. pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
  908. ast_sip_report_failed_acl(endpoint, rdata, "registrar_attempt_without_configured_aors");
  909. ast_log(LOG_WARNING, "Endpoint '%s' has no configured AORs\n", ast_sorcery_object_get_id(endpoint));
  910. return PJ_TRUE;
  911. }
  912. if (!PJSIP_URI_SCHEME_IS_SIP(rdata->msg_info.to->uri) && !PJSIP_URI_SCHEME_IS_SIPS(rdata->msg_info.to->uri)) {
  913. pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 416, NULL, NULL, NULL);
  914. ast_sip_report_failed_acl(endpoint, rdata, "registrar_invalid_uri_in_to_received");
  915. ast_log(LOG_WARNING, "Endpoint '%s' attempted to register to an AOR with a non-SIP URI\n", ast_sorcery_object_get_id(endpoint));
  916. return PJ_TRUE;
  917. }
  918. aor = find_registrar_aor(rdata, endpoint);
  919. if (!aor) {
  920. /* We've already responded about not finding an AOR. */
  921. return PJ_TRUE;
  922. }
  923. aor_name = ast_sorcery_object_get_id(aor);
  924. if (!aor->max_contacts) {
  925. /* Registration is not permitted for this AOR */
  926. pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
  927. ast_sip_report_req_no_support(endpoint, rdata, "registrar_attempt_without_registration_permitted");
  928. ast_log(LOG_WARNING, "AOR '%s' has no configured max_contacts. Endpoint '%s' unable to register\n",
  929. aor_name, ast_sorcery_object_get_id(endpoint));
  930. } else {
  931. register_aor(rdata, endpoint, aor, aor_name);
  932. }
  933. ao2_ref(aor, -1);
  934. return PJ_TRUE;
  935. }
  936. /* function pointer to callback needs to be within the module
  937. in order to avoid problems with an undefined symbol */
  938. static int sip_contact_to_str(void *acp, void *arg, int flags)
  939. {
  940. return ast_sip_contact_to_str(acp, arg, flags);
  941. }
  942. static int ami_registrations_aor(void *obj, void *arg, int flags)
  943. {
  944. struct ast_sip_aor *aor = obj;
  945. struct ast_sip_ami *ami = arg;
  946. int *count = ami->arg;
  947. RAII_VAR(struct ast_str *, buf,
  948. ast_sip_create_ami_event("InboundRegistrationDetail", ami), ast_free);
  949. if (!buf) {
  950. return -1;
  951. }
  952. ast_sip_sorcery_object_to_ami(aor, &buf);
  953. ast_str_append(&buf, 0, "Contacts: ");
  954. ast_sip_for_each_contact(aor, sip_contact_to_str, &buf);
  955. ast_str_append(&buf, 0, "\r\n");
  956. astman_append(ami->s, "%s\r\n", ast_str_buffer(buf));
  957. (*count)++;
  958. return 0;
  959. }
  960. static int ami_registrations_endpoint(void *obj, void *arg, int flags)
  961. {
  962. struct ast_sip_endpoint *endpoint = obj;
  963. return ast_sip_for_each_aor(
  964. endpoint->aors, ami_registrations_aor, arg);
  965. }
  966. static int ami_registrations_endpoints(void *arg)
  967. {
  968. RAII_VAR(struct ao2_container *, endpoints,
  969. ast_sip_get_endpoints(), ao2_cleanup);
  970. if (!endpoints) {
  971. return 0;
  972. }
  973. ao2_callback(endpoints, OBJ_NODATA, ami_registrations_endpoint, arg);
  974. return 0;
  975. }
  976. static int ami_show_registrations(struct mansession *s, const struct message *m)
  977. {
  978. int count = 0;
  979. struct ast_sip_ami ami = { .s = s, .m = m, .arg = &count, .action_id = astman_get_header(m, "ActionID"), };
  980. astman_send_listack(s, m, "Following are Events for each Inbound "
  981. "registration", "start");
  982. ami_registrations_endpoints(&ami);
  983. astman_send_list_complete_start(s, m, "InboundRegistrationDetailComplete", count);
  984. astman_send_list_complete_end(s);
  985. return 0;
  986. }
  987. static int ami_show_registration_contact_statuses(struct mansession *s, const struct message *m)
  988. {
  989. int count = 0;
  990. struct ast_sip_ami ami = { .s = s, .m = m, .arg = NULL, .action_id = astman_get_header(m, "ActionID"), };
  991. struct ao2_container *contacts = ast_sorcery_retrieve_by_fields(
  992. ast_sip_get_sorcery(), "contact", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
  993. struct ao2_iterator i;
  994. struct ast_sip_contact *contact;
  995. astman_send_listack(s, m, "Following are ContactStatusEvents for each Inbound "
  996. "registration", "start");
  997. if (contacts) {
  998. i = ao2_iterator_init(contacts, 0);
  999. while ((contact = ao2_iterator_next(&i))) {
  1000. struct ast_sip_contact_wrapper wrapper;
  1001. wrapper.aor_id = (char *)contact->aor;
  1002. wrapper.contact = contact;
  1003. wrapper.contact_id = (char *)ast_sorcery_object_get_id(contact);
  1004. ast_sip_format_contact_ami(&wrapper, &ami, 0);
  1005. count++;
  1006. ao2_ref(contact, -1);
  1007. }
  1008. ao2_iterator_destroy(&i);
  1009. ao2_ref(contacts, -1);
  1010. }
  1011. astman_send_list_complete_start(s, m, "ContactStatusDetailComplete", count);
  1012. astman_send_list_complete_end(s);
  1013. return 0;
  1014. }
  1015. #define AMI_SHOW_REGISTRATION_CONTACT_STATUSES "PJSIPShowRegistrationInboundContactStatuses"
  1016. #define AMI_SHOW_REGISTRATIONS "PJSIPShowRegistrationsInbound"
  1017. static pjsip_module registrar_module = {
  1018. .name = { "Registrar", 9 },
  1019. .id = -1,
  1020. .priority = PJSIP_MOD_PRIORITY_APPLICATION,
  1021. .on_rx_request = registrar_on_rx_request,
  1022. };
  1023. /*! \brief Thread keeping things alive */
  1024. static pthread_t check_thread = AST_PTHREADT_NULL;
  1025. /*! \brief The global interval at which to check for contact expiration */
  1026. static unsigned int check_interval;
  1027. /*! \brief Callback function which deletes a contact */
  1028. static int expire_contact(void *obj, void *arg, int flags)
  1029. {
  1030. struct ast_sip_contact *contact = obj;
  1031. struct ast_named_lock *lock;
  1032. lock = ast_named_lock_get(AST_NAMED_LOCK_TYPE_MUTEX, "aor", contact->aor);
  1033. if (!lock) {
  1034. return 0;
  1035. }
  1036. /*
  1037. * We need to check the expiration again with the aor lock held
  1038. * in case another thread is attempting to renew the contact.
  1039. */
  1040. ao2_lock(lock);
  1041. if (ast_tvdiff_ms(ast_tvnow(), contact->expiration_time) > 0) {
  1042. if (contact->prune_on_boot) {
  1043. struct contact_transport_monitor *monitor;
  1044. const char *contact_name = ast_sorcery_object_get_id(contact);
  1045. monitor = ast_alloca(sizeof(*monitor) + 2 + strlen(contact->aor)
  1046. + strlen(contact_name));
  1047. strcpy(monitor->aor_name, contact->aor);/* Safe */
  1048. monitor->contact_name = monitor->aor_name + strlen(contact->aor) + 1;
  1049. strcpy(monitor->contact_name, contact_name);/* Safe */
  1050. ast_sip_transport_monitor_unregister_all(register_contact_transport_shutdown_cb,
  1051. monitor, contact_transport_monitor_matcher);
  1052. }
  1053. ast_sip_location_delete_contact(contact);
  1054. }
  1055. ao2_unlock(lock);
  1056. ast_named_lock_put(lock);
  1057. return 0;
  1058. }
  1059. static void *check_expiration_thread(void *data)
  1060. {
  1061. struct ao2_container *contacts;
  1062. struct ast_variable *var;
  1063. char *time = alloca(64);
  1064. while (check_interval) {
  1065. sleep(check_interval);
  1066. sprintf(time, "%ld", ast_tvnow().tv_sec);
  1067. var = ast_variable_new("expiration_time <=", time, "");
  1068. ast_debug(4, "Woke up at %s Interval: %d\n", time, check_interval);
  1069. contacts = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "contact",
  1070. AST_RETRIEVE_FLAG_MULTIPLE, var);
  1071. ast_variables_destroy(var);
  1072. if (contacts) {
  1073. ast_debug(3, "Expiring %d contacts\n", ao2_container_count(contacts));
  1074. ao2_callback(contacts, OBJ_NODATA, expire_contact, NULL);
  1075. ao2_ref(contacts, -1);
  1076. }
  1077. }
  1078. return NULL;
  1079. }
  1080. static void expiration_global_loaded(const char *object_type)
  1081. {
  1082. check_interval = ast_sip_get_contact_expiration_check_interval();
  1083. /* Observer calls are serialized so this is safe without it's own lock */
  1084. if (check_interval) {
  1085. if (check_thread == AST_PTHREADT_NULL) {
  1086. if (ast_pthread_create_background(&check_thread, NULL, check_expiration_thread, NULL)) {
  1087. ast_log(LOG_ERROR, "Could not create thread for checking contact expiration.\n");
  1088. return;
  1089. }
  1090. ast_debug(3, "Interval = %d, starting thread\n", check_interval);
  1091. }
  1092. } else {
  1093. if (check_thread != AST_PTHREADT_NULL) {
  1094. pthread_kill(check_thread, SIGURG);
  1095. pthread_join(check_thread, NULL);
  1096. check_thread = AST_PTHREADT_NULL;
  1097. ast_debug(3, "Interval = 0, shutting thread down\n");
  1098. }
  1099. }
  1100. }
  1101. /*! \brief Observer which is used to update our interval when the global setting changes */
  1102. static struct ast_sorcery_observer expiration_global_observer = {
  1103. .loaded = expiration_global_loaded,
  1104. };
  1105. static int load_module(void)
  1106. {
  1107. const pj_str_t STR_REGISTER = { "REGISTER", 8 };
  1108. CHECK_PJPROJECT_MODULE_LOADED();
  1109. ast_pjproject_get_buildopt("PJ_MAX_HOSTNAME", "%d", &pj_max_hostname);
  1110. /* As of pjproject 2.4.5, PJSIP_MAX_URL_SIZE isn't exposed yet but we try anyway. */
  1111. ast_pjproject_get_buildopt("PJSIP_MAX_URL_SIZE", "%d", &pjsip_max_url_size);
  1112. CHECK_PJSIP_MODULE_LOADED();
  1113. if (ast_sip_register_service(&registrar_module)) {
  1114. return AST_MODULE_LOAD_DECLINE;
  1115. }
  1116. if (pjsip_endpt_add_capability(ast_sip_get_pjsip_endpoint(), NULL, PJSIP_H_ALLOW, NULL, 1, &STR_REGISTER) != PJ_SUCCESS) {
  1117. ast_sip_unregister_service(&registrar_module);
  1118. return AST_MODULE_LOAD_DECLINE;
  1119. }
  1120. ast_manager_register_xml(AMI_SHOW_REGISTRATIONS, EVENT_FLAG_SYSTEM,
  1121. ami_show_registrations);
  1122. ast_manager_register_xml(AMI_SHOW_REGISTRATION_CONTACT_STATUSES, EVENT_FLAG_SYSTEM,
  1123. ami_show_registration_contact_statuses);
  1124. ast_sorcery_observer_add(ast_sip_get_sorcery(), "global", &expiration_global_observer);
  1125. ast_sorcery_reload_object(ast_sip_get_sorcery(), "global");
  1126. return AST_MODULE_LOAD_SUCCESS;
  1127. }
  1128. static int unload_module(void)
  1129. {
  1130. if (check_thread != AST_PTHREADT_NULL) {
  1131. check_interval = 0;
  1132. pthread_kill(check_thread, SIGURG);
  1133. pthread_join(check_thread, NULL);
  1134. check_thread = AST_PTHREADT_NULL;
  1135. }
  1136. ast_sorcery_observer_remove(ast_sip_get_sorcery(), "global", &expiration_global_observer);
  1137. ast_manager_unregister(AMI_SHOW_REGISTRATIONS);
  1138. ast_manager_unregister(AMI_SHOW_REGISTRATION_CONTACT_STATUSES);
  1139. ast_sip_unregister_service(&registrar_module);
  1140. ast_sip_transport_monitor_unregister_all(register_contact_transport_shutdown_cb, NULL, NULL);
  1141. return 0;
  1142. }
  1143. AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Registrar Support",
  1144. .support_level = AST_MODULE_SUPPORT_CORE,
  1145. .load = load_module,
  1146. .unload = unload_module,
  1147. .load_pri = AST_MODPRI_CHANNEL_DEPEND - 3,
  1148. );