aboutsummaryrefslogtreecommitdiffstats
path: root/src/libcharon/sa/trap_manager.c
diff options
context:
space:
mode:
authorMartin Willi <martin@revosec.ch>2013-06-19 16:31:06 +0200
committerMartin Willi <martin@revosec.ch>2013-06-19 16:31:06 +0200
commit4f88ad669a2a5d65bd7e6d60896df14246f58a5e (patch)
tree809157a900b51683a63a3f33fc8d7a0ad7a0eec5 /src/libcharon/sa/trap_manager.c
parentde2debf8e0759c974c734cacab9549451eceb236 (diff)
parenta7bc0bf4a6c091637e81eec0c268e5947f5c1e21 (diff)
downloadstrongswan-4f88ad669a2a5d65bd7e6d60896df14246f58a5e.tar.bz2
strongswan-4f88ad669a2a5d65bd7e6d60896df14246f58a5e.tar.xz
Merge branch 'consistent-reqid'
Checks if a trap policy exists when installing a CHILD_SA as responder, reuse that reqid and keeping the trap untouched. This makes auto=route on both sides more reliable. In addition, we no prevent to refcount an existing policy if the reqid differs; this should not happen anymore. We now can properly reject new CHILD_SAs in such conflicts, instead of silently breaking an existing policy.
Diffstat (limited to 'src/libcharon/sa/trap_manager.c')
-rw-r--r--src/libcharon/sa/trap_manager.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/src/libcharon/sa/trap_manager.c b/src/libcharon/sa/trap_manager.c
index 6c0ae19c7..ab638ff3e 100644
--- a/src/libcharon/sa/trap_manager.c
+++ b/src/libcharon/sa/trap_manager.c
@@ -109,6 +109,7 @@ METHOD(trap_manager_t, install, u_int32_t,
0, ike_cfg->get_other_port(ike_cfg));
if (!other || other->is_anyaddr(other))
{
+ DESTROY_IF(other);
DBG1(DBG_CFG, "installing trap failed, remote address unknown");
return 0;
}
@@ -141,6 +142,8 @@ METHOD(trap_manager_t, install, u_int32_t,
}
}
enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
+
if (found)
{ /* config might have changed so update everything */
DBG1(DBG_CFG, "updating already routed CHILD_SA '%s'",
@@ -179,10 +182,11 @@ METHOD(trap_manager_t, install, u_int32_t,
.child_sa = child_sa,
.peer_cfg = peer->get_ref(peer),
);
+ this->lock->write_lock(this->lock);
this->traps->insert_last(this->traps, entry);
+ this->lock->unlock(this->lock);
reqid = child_sa->get_reqid(child_sa);
}
- this->lock->unlock(this->lock);
if (status != SUCCESS)
{
@@ -251,6 +255,31 @@ METHOD(trap_manager_t, create_enumerator, enumerator_t*,
(void*)this->lock->unlock);
}
+METHOD(trap_manager_t, find_reqid, u_int32_t,
+ private_trap_manager_t *this, child_cfg_t *child)
+{
+ enumerator_t *enumerator;
+ child_cfg_t *current;
+ entry_t *entry;
+ u_int32_t reqid = 0;
+
+ this->lock->read_lock(this->lock);
+ enumerator = this->traps->create_enumerator(this->traps);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ current = entry->child_sa->get_config(entry->child_sa);
+ if (streq(current->get_name(current), child->get_name(child)))
+ {
+ reqid = entry->child_sa->get_reqid(entry->child_sa);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
+
+ return reqid;
+}
+
METHOD(trap_manager_t, acquire, void,
private_trap_manager_t *this, u_int32_t reqid,
traffic_selector_t *src, traffic_selector_t *dst)
@@ -319,8 +348,7 @@ METHOD(trap_manager_t, acquire, void,
}
else
{
- charon->ike_sa_manager->checkin_and_destroy(
- charon->ike_sa_manager, ike_sa);
+ ike_sa->destroy(ike_sa);
}
}
peer->destroy(peer);
@@ -417,6 +445,7 @@ trap_manager_t *trap_manager_create(void)
.install = _install,
.uninstall = _uninstall,
.create_enumerator = _create_enumerator,
+ .find_reqid = _find_reqid,
.acquire = _acquire,
.flush = _flush,
.destroy = _destroy,
@@ -435,4 +464,3 @@ trap_manager_t *trap_manager_create(void)
return &this->public;
}
-