[strongSwan-dev] [PATCH 1/2] Add reference counting to child_sa
Thomas Egerer
thomas.egerer at secunet.com
Fri May 14 17:28:42 CEST 2010
---
src/libcharon/sa/child_sa.c | 95
++++++++++++++++++++++++++-----------------
src/libcharon/sa/child_sa.h | 11 +++++
2 files changed, 68 insertions(+), 38 deletions(-)
diff --git a/src/libcharon/sa/child_sa.c b/src/libcharon/sa/child_sa.c
index 8fd2a8c..8b125d9 100644
--- a/src/libcharon/sa/child_sa.c
+++ b/src/libcharon/sa/child_sa.c
@@ -156,6 +156,11 @@ struct private_child_sa_t {
* last number of outbound bytes
*/
u_int64_t other_usebytes;
+
+ /**
+ * Number of references hold by others to this child_sa
+ */
+ refcount_t refcount;
};
/**
@@ -833,62 +838,74 @@ static status_t update(private_child_sa_t *this,
host_t *me, host_t *other,
}
/**
+ * Implementation of child_sa_t.get_ref.
+ */
+static child_sa_t* get_ref(private_child_sa_t *this)
+{
+ ref_get(&this->refcount);
+ return &this->public;
+}
+
+/**
* Implementation of child_sa_t.destroy.
*/
static void destroy(private_child_sa_t *this)
{
- enumerator_t *enumerator;
- traffic_selector_t *my_ts, *other_ts;
- bool unrouted = (this->state == CHILD_ROUTED);
+ if (ref_put(&this->refcount))
+ {
+ enumerator_t *enumerator;
+ traffic_selector_t *my_ts, *other_ts;
+ bool unrouted = (this->state == CHILD_ROUTED);
- set_state(this, CHILD_DESTROYING);
+ set_state(this, CHILD_DESTROYING);
- /* delete SAs in the kernel, if they are set up */
- if (this->my_spi)
- {
- /* if CHILD was not established, use PROTO_ESP used during alloc_spi().
- * TODO: For AH support, we have to store protocol specific SPI.s */
- if (this->protocol == PROTO_NONE)
+ /* delete SAs in the kernel, if they are set up */
+ if (this->my_spi)
{
- this->protocol = PROTO_ESP;
- }
- charon->kernel_interface->del_sa(charon->kernel_interface,
+ /* if CHILD was not established, use PROTO_ESP used during alloc_spi().
+ * TODO: For AH support, we have to store protocol specific SPI.s */
+ if (this->protocol == PROTO_NONE)
+ {
+ this->protocol = PROTO_ESP;
+ }
+ charon->kernel_interface->del_sa(charon->kernel_interface,
this->other_addr, this->my_addr, this->my_spi,
this->protocol, this->my_cpi);
- }
- if (this->other_spi)
- {
- charon->kernel_interface->del_sa(charon->kernel_interface,
+ }
+ if (this->other_spi)
+ {
+ charon->kernel_interface->del_sa(charon->kernel_interface,
this->my_addr, this->other_addr, this->other_spi,
this->protocol, this->other_cpi);
- }
+ }
- if (this->config->install_policy(this->config))
- {
- /* delete all policies in the kernel */
- enumerator = create_policy_enumerator(this);
- while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
+ if (this->config->install_policy(this->config))
{
- charon->kernel_interface->del_policy(charon->kernel_interface,
- my_ts, other_ts, POLICY_OUT, unrouted);
- charon->kernel_interface->del_policy(charon->kernel_interface,
- other_ts, my_ts, POLICY_IN, unrouted);
- if (this->mode != MODE_TRANSPORT)
+ /* delete all policies in the kernel */
+ enumerator = create_policy_enumerator(this);
+ while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
{
charon->kernel_interface->del_policy(charon->kernel_interface,
- other_ts, my_ts, POLICY_FWD, unrouted);
+ my_ts, other_ts, POLICY_OUT, unrouted);
+ charon->kernel_interface->del_policy(charon->kernel_interface,
+ other_ts, my_ts, POLICY_IN, unrouted);
+ if (this->mode != MODE_TRANSPORT)
+ {
+ charon->kernel_interface->del_policy(charon->kernel_interface,
+ other_ts, my_ts, POLICY_FWD, unrouted);
+ }
}
+ enumerator->destroy(enumerator);
}
- enumerator->destroy(enumerator);
- }
- this->my_ts->destroy_offset(this->my_ts, offsetof(traffic_selector_t,
destroy));
- this->other_ts->destroy_offset(this->other_ts,
offsetof(traffic_selector_t, destroy));
- this->my_addr->destroy(this->my_addr);
- this->other_addr->destroy(this->other_addr);
- DESTROY_IF(this->proposal);
- this->config->destroy(this->config);
- free(this);
+ this->my_ts->destroy_offset(this->my_ts, offsetof(traffic_selector_t,
destroy));
+ this->other_ts->destroy_offset(this->other_ts,
offsetof(traffic_selector_t, destroy));
+ this->my_addr->destroy(this->my_addr);
+ this->other_addr->destroy(this->other_addr);
+ DESTROY_IF(this->proposal);
+ this->config->destroy(this->config);
+ free(this);
+ }
}
/*
@@ -926,6 +943,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
this->public.add_policies = (status_t (*)(child_sa_t*,
linked_list_t*,linked_list_t*))add_policies;
this->public.get_traffic_selectors =
(linked_list_t*(*)(child_sa_t*,bool))get_traffic_selectors;
this->public.create_policy_enumerator =
(enumerator_t*(*)(child_sa_t*))create_policy_enumerator;
+ this->public.get_ref = (child_sa_t *(*)(child_sa_t *))get_ref;
this->public.destroy = (void(*)(child_sa_t*))destroy;
/* private data */
@@ -950,6 +968,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
this->rekey_time = 0;
this->expire_time = 0;
this->config = config;
+ this->refcount = 1;
config->get_ref(config);
this->reqid = config->get_reqid(config);
if (!this->reqid)
diff --git a/src/libcharon/sa/child_sa.h b/src/libcharon/sa/child_sa.h
index e6c6035..31702c8 100644
--- a/src/libcharon/sa/child_sa.h
+++ b/src/libcharon/sa/child_sa.h
@@ -315,8 +315,19 @@ struct child_sa_t {
*/
status_t (*update)(child_sa_t *this, host_t *me, host_t *other,
host_t *vip, bool encap);
+
+ /**
+ * Increase the reference count.
+ *
+ * @return reference to this
+ */
+ child_sa_t* (*get_ref) (child_sa_t *this);
+
/**
* Destroys a child_sa.
+ *
+ * Decrements the internal reference counter and
+ * destroys the child_sa when it reaches zero.
*/
void (*destroy) (child_sa_t *this);
};
--
1.7.0.2
More information about the Dev
mailing list