diff options
-rw-r--r-- | src/charon/config/connections/connection.c | 6 | ||||
-rw-r--r-- | src/charon/config/connections/connection.h | 3 | ||||
-rw-r--r-- | src/charon/config/policies/policy.c | 6 | ||||
-rw-r--r-- | src/charon/config/policies/policy.h | 3 | ||||
-rw-r--r-- | src/charon/daemon.c | 1 | ||||
-rw-r--r-- | src/charon/doc/Todo-list.txt | 2 | ||||
-rw-r--r-- | src/libstrongswan/types.c | 38 | ||||
-rw-r--r-- | src/libstrongswan/types.h | 26 |
8 files changed, 79 insertions, 6 deletions
diff --git a/src/charon/config/connections/connection.c b/src/charon/config/connections/connection.c index 3ecc08a16..281d43d9c 100644 --- a/src/charon/config/connections/connection.c +++ b/src/charon/config/connections/connection.c @@ -63,7 +63,7 @@ struct private_connection_t { /** * Number of references hold by others to this connection */ - u_int refcount; + refcount_t refcount; /** * Name of the connection @@ -326,7 +326,7 @@ static u_int32_t get_hard_lifetime(private_connection_t *this) */ static void get_ref(private_connection_t *this) { - this->refcount++; + ref_get(&this->refcount); } /** @@ -334,7 +334,7 @@ static void get_ref(private_connection_t *this) */ static void destroy(private_connection_t *this) { - if (--this->refcount == 0) + if (ref_put(&this->refcount)) { proposal_t *proposal; diff --git a/src/charon/config/connections/connection.h b/src/charon/config/connections/connection.h index 068dd710b..61ca9cfc0 100644 --- a/src/charon/config/connections/connection.h +++ b/src/charon/config/connections/connection.h @@ -259,6 +259,9 @@ struct connection_t { * * Get a new reference to this connection by increasing * it's internal reference counter. + * Do not call get_ref or any other function until you + * already have a reference. Otherwise the object may get + * destroyed while calling get_ref(), * * @param this calling object */ diff --git a/src/charon/config/policies/policy.c b/src/charon/config/policies/policy.c index 14fa93b4e..49983ade7 100644 --- a/src/charon/config/policies/policy.c +++ b/src/charon/config/policies/policy.c @@ -46,7 +46,7 @@ struct private_policy_t { /** * Number of references hold by others to this policy */ - u_int refcount; + refcount_t refcount; /** * Name of the policy, used to query it @@ -377,7 +377,7 @@ static u_int32_t get_hard_lifetime(private_policy_t *this) */ static void get_ref(private_policy_t *this) { - this->refcount++; + ref_get(&this->refcount); } /** @@ -385,7 +385,7 @@ static void get_ref(private_policy_t *this) */ static void destroy(private_policy_t *this) { - if (--this->refcount == 0) + if (ref_put(&this->refcount)) { proposal_t *proposal; traffic_selector_t *traffic_selector; diff --git a/src/charon/config/policies/policy.h b/src/charon/config/policies/policy.h index 1659a7070..454f69c12 100644 --- a/src/charon/config/policies/policy.h +++ b/src/charon/config/policies/policy.h @@ -227,6 +227,9 @@ struct policy_t { * * Get a new reference to this policy by increasing * it's internal reference counter. + * Do not call get_ref or any other function until you + * already have a reference. Otherwise the object may get + * destroyed while calling get_ref(), * * @param this calling object */ diff --git a/src/charon/daemon.c b/src/charon/daemon.c index 5e4a67a20..a368ee428 100644 --- a/src/charon/daemon.c +++ b/src/charon/daemon.c @@ -32,6 +32,7 @@ #include <execinfo.h> #include <string.h> #include <getopt.h> +#include <errno.h> #include "daemon.h" diff --git a/src/charon/doc/Todo-list.txt b/src/charon/doc/Todo-list.txt index 788a06c54..296820e58 100644 --- a/src/charon/doc/Todo-list.txt +++ b/src/charon/doc/Todo-list.txt @@ -54,6 +54,8 @@ + proper delete messages - notifys on connection setup failure + create child sa message/rekeying +/ IKE_SA rekeying + - handle all simultaneous rekeying/delete/create cases - implement a mechanism against thread exhaustion when a blocked IKE_SA receives a lot of messages diff --git a/src/libstrongswan/types.c b/src/libstrongswan/types.c index b60a604b8..e0337274e 100644 --- a/src/libstrongswan/types.c +++ b/src/libstrongswan/types.c @@ -25,6 +25,7 @@ #include <time.h> #include <stdio.h> #include <stdarg.h> +#include <pthread.h> #include "types.h" @@ -198,6 +199,43 @@ void *clalloc(void * pointer, size_t size) return (data); } +/** + * We use a single mutex for all refcount variables. This + * is not optimal for performance, but the critical section + * is not that long... + * TODO: Consider to include a mutex in each refcount_t variable. + */ +static pthread_mutex_t ref_mutex = PTHREAD_MUTEX_INITIALIZER; + +/** + * Described in header. + * + * TODO: May be implemented with atomic CPU instructions + * instead of a mutex. + */ +void ref_get(refcount_t *ref) +{ + pthread_mutex_lock(&ref_mutex); + (*ref)++; + pthread_mutex_unlock(&ref_mutex); +} + +/** + * Described in header. + * + * TODO: May be implemented with atomic CPU instructions + * instead of a mutex. + */ +bool ref_put(refcount_t *ref) +{ + bool more_refs; + + pthread_mutex_lock(&ref_mutex); + more_refs = --(*ref); + pthread_mutex_unlock(&ref_mutex); + return !more_refs; +} + /* * Names of the months used by timetoa() */ diff --git a/src/libstrongswan/types.h b/src/libstrongswan/types.h index 631e5025b..9874d5bc0 100644 --- a/src/libstrongswan/types.h +++ b/src/libstrongswan/types.h @@ -200,6 +200,32 @@ void chunk_to_hex(char *buf, size_t buflen, chunk_t chunk); */ void *clalloc(void *pointer, size_t size); +/** + * Special type to count references + */ +typedef volatile u_int refcount_t; + +/** + * @brief Get a new reference. + * + * Increments the reference counter atomic. + * + * @param ref pointer to ref counter + */ +void ref_get(refcount_t *ref); + +/** + * @brief Put back a unused reference. + * + * Decrements the reference counter atomic and + * says if more references available. + * + * @param ref pointer to ref counter + * @return TRUE if no more references counted + */ +bool ref_put(refcount_t *ref); + + #define UNDEFINED_TIME 0 #define TIMETOA_BUF 30 |