diff options
Diffstat (limited to 'src/charon/sa/tasks/ike_natd.c')
-rw-r--r-- | src/charon/sa/tasks/ike_natd.c | 45 |
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; } |