summaryrefslogtreecommitdiff
path: root/src/charon/sa/tasks/ike_natd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon/sa/tasks/ike_natd.c')
-rw-r--r--src/charon/sa/tasks/ike_natd.c45
1 files changed, 35 insertions, 10 deletions
diff --git a/src/charon/sa/tasks/ike_natd.c b/src/charon/sa/tasks/ike_natd.c
index 69e5bac26..9e62fcbdf 100644
--- a/src/charon/sa/tasks/ike_natd.c
+++ b/src/charon/sa/tasks/ike_natd.c
@@ -13,7 +13,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * $Id: ike_natd.c 3806 2008-04-15 05:56:35Z martin $
+ * $Id: ike_natd.c 4386 2008-10-08 08:23:46Z martin $
*/
#include "ike_natd.h"
@@ -72,6 +72,11 @@ struct private_ike_natd_t {
* Have we found a matching destination address NAT hash?
*/
bool dst_matched;
+
+ /**
+ * whether NAT mappings for our NATed address has changed
+ */
+ bool mapping_changed;
};
@@ -192,15 +197,24 @@ static void process_payloads(private_ike_natd_t *this, message_t *message)
case NAT_DETECTION_DESTINATION_IP:
{
this->dst_seen = TRUE;
+ hash = notify->get_notification_data(notify);
if (!this->dst_matched)
{
- hash = notify->get_notification_data(notify);
DBG3(DBG_IKE, "received dst_hash %B", &hash);
if (chunk_equals(hash, dst_hash))
{
this->dst_matched = TRUE;
}
}
+ /* RFC4555 says we should also compare against IKE_SA_INIT
+ * NATD payloads, but this does not work: We are running
+ * there at port 500, but use 4500 afterwards... */
+ if (message->get_exchange_type(message) == INFORMATIONAL &&
+ this->initiator && !this->dst_matched)
+ {
+ this->mapping_changed = this->ike_sa->has_mapping_changed(
+ this->ike_sa, hash);
+ }
break;
}
case NAT_DETECTION_SOURCE_IP:
@@ -300,7 +314,7 @@ static status_t process_i(private_ike_natd_t *this, message_t *message)
static status_t build_i(private_ike_natd_t *this, message_t *message)
{
notify_payload_t *notify;
- iterator_t *iterator;
+ enumerator_t *enumerator;
host_t *host;
if (this->hasher == NULL)
@@ -327,9 +341,8 @@ static status_t build_i(private_ike_natd_t *this, message_t *message)
}
else
{
- host = charon->kernel_interface->get_source_addr(
- charon->kernel_interface,
- this->ike_sa->get_other_host(this->ike_sa));
+ host = charon->kernel_interface->get_source_addr(charon->kernel_interface,
+ this->ike_sa->get_other_host(this->ike_sa), NULL);
if (host)
{ /* 2. */
host->set_port(host, IKEV2_UDP_PORT);
@@ -339,14 +352,14 @@ static status_t build_i(private_ike_natd_t *this, message_t *message)
}
else
{ /* 3. */
- iterator = charon->kernel_interface->create_address_iterator(
- charon->kernel_interface);
- while (iterator->iterate(iterator, (void**)&host))
+ enumerator = charon->kernel_interface->create_address_enumerator(
+ charon->kernel_interface, FALSE, FALSE);
+ while (enumerator->enumerate(enumerator, (void**)&host))
{
notify = build_natd_payload(this, NAT_DETECTION_SOURCE_IP, host);
message->add_payload(message, (payload_t*)notify);
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
}
return NEED_MORE;
@@ -415,6 +428,15 @@ static void migrate(private_ike_natd_t *this, ike_sa_t *ike_sa)
this->dst_seen = FALSE;
this->src_matched = FALSE;
this->dst_matched = FALSE;
+ this->mapping_changed = FALSE;
+}
+
+/**
+ * Implementation of ike_natd_t.has_mapping_changed
+ */
+static bool has_mapping_changed(private_ike_natd_t *this)
+{
+ return this->mapping_changed;
}
/**
@@ -448,6 +470,8 @@ ike_natd_t *ike_natd_create(ike_sa_t *ike_sa, bool initiator)
this->public.task.process = (status_t(*)(task_t*,message_t*))process_r;
}
+ this->public.has_mapping_changed = (bool(*)(ike_natd_t*))has_mapping_changed;
+
this->ike_sa = ike_sa;
this->initiator = initiator;
this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
@@ -455,6 +479,7 @@ ike_natd_t *ike_natd_create(ike_sa_t *ike_sa, bool initiator)
this->dst_seen = FALSE;
this->src_matched = FALSE;
this->dst_matched = FALSE;
+ this->mapping_changed = FALSE;
return &this->public;
}