rekey_ike_sa_job.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*
  2. * Copyright (C) 2006 Martin Willi
  3. * HSR Hochschule fuer Technik Rapperswil
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License as published by the
  7. * Free Software Foundation; either version 2 of the License, or (at your
  8. * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  12. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  13. * for more details.
  14. */
  15. #include "rekey_ike_sa_job.h"
  16. #include <daemon.h>
  17. typedef struct private_rekey_ike_sa_job_t private_rekey_ike_sa_job_t;
  18. /**
  19. * Private data of an rekey_ike_sa_job_t object.
  20. */
  21. struct private_rekey_ike_sa_job_t {
  22. /**
  23. * Public rekey_ike_sa_job_t interface.
  24. */
  25. rekey_ike_sa_job_t public;
  26. /**
  27. * ID of the IKE_SA to rekey
  28. */
  29. ike_sa_id_t *ike_sa_id;
  30. /**
  31. * force reauthentication of the peer (full IKE_SA setup)
  32. */
  33. bool reauth;
  34. };
  35. METHOD(job_t, destroy, void,
  36. private_rekey_ike_sa_job_t *this)
  37. {
  38. this->ike_sa_id->destroy(this->ike_sa_id);
  39. free(this);
  40. }
  41. /**
  42. * Check if we should delay a reauth, and by how many seconds
  43. */
  44. static uint32_t get_retry_delay(ike_sa_t *ike_sa)
  45. {
  46. enumerator_t *enumerator;
  47. child_sa_t *child_sa;
  48. uint32_t retry = 0;
  49. /* avoid reauth collisions for certain IKE_SA/CHILD_SA states */
  50. if (ike_sa->get_state(ike_sa) != IKE_ESTABLISHED)
  51. {
  52. retry = RETRY_INTERVAL - (random() % RETRY_JITTER);
  53. DBG1(DBG_IKE, "unable to reauthenticate in %N state, delaying for %us",
  54. ike_sa_state_names, ike_sa->get_state(ike_sa), retry);
  55. }
  56. else
  57. {
  58. enumerator = ike_sa->create_child_sa_enumerator(ike_sa);
  59. while (enumerator->enumerate(enumerator, &child_sa))
  60. {
  61. if (child_sa->get_state(child_sa) != CHILD_INSTALLED &&
  62. child_sa->get_state(child_sa) != CHILD_REKEYED)
  63. {
  64. retry = RETRY_INTERVAL - (random() % RETRY_JITTER);
  65. DBG1(DBG_IKE, "unable to reauthenticate in CHILD_SA %N state, "
  66. "delaying for %us", child_sa_state_names,
  67. child_sa->get_state(child_sa), retry);
  68. break;
  69. }
  70. }
  71. enumerator->destroy(enumerator);
  72. }
  73. return retry;
  74. }
  75. METHOD(job_t, execute, job_requeue_t,
  76. private_rekey_ike_sa_job_t *this)
  77. {
  78. ike_sa_t *ike_sa;
  79. status_t status = SUCCESS;
  80. uint32_t retry = 0;
  81. ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
  82. this->ike_sa_id);
  83. if (ike_sa == NULL)
  84. {
  85. DBG2(DBG_JOB, "IKE_SA to rekey not found");
  86. }
  87. else
  88. {
  89. if (this->reauth)
  90. {
  91. retry = get_retry_delay(ike_sa);
  92. if (!retry)
  93. {
  94. status = ike_sa->reauth(ike_sa);
  95. }
  96. }
  97. else
  98. {
  99. status = ike_sa->rekey(ike_sa);
  100. }
  101. if (status == DESTROY_ME)
  102. {
  103. charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
  104. ike_sa);
  105. }
  106. else
  107. {
  108. charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
  109. }
  110. }
  111. if (retry)
  112. {
  113. return JOB_RESCHEDULE(retry);
  114. }
  115. return JOB_REQUEUE_NONE;
  116. }
  117. METHOD(job_t, get_priority, job_priority_t,
  118. private_rekey_ike_sa_job_t *this)
  119. {
  120. return JOB_PRIO_MEDIUM;
  121. }
  122. /*
  123. * Described in header
  124. */
  125. rekey_ike_sa_job_t *rekey_ike_sa_job_create(ike_sa_id_t *ike_sa_id, bool reauth)
  126. {
  127. private_rekey_ike_sa_job_t *this;
  128. INIT(this,
  129. .public = {
  130. .job_interface = {
  131. .execute = _execute,
  132. .get_priority = _get_priority,
  133. .destroy = _destroy,
  134. },
  135. },
  136. .ike_sa_id = ike_sa_id->clone(ike_sa_id),
  137. .reauth = reauth,
  138. );
  139. return &(this->public);
  140. }