aboutsummaryrefslogtreecommitdiffstats
path: root/src/charon/config
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon/config')
-rwxr-xr-xsrc/charon/config/configuration.c50
-rwxr-xr-xsrc/charon/config/configuration.h12
-rw-r--r--src/charon/config/policies/policy.c63
-rw-r--r--src/charon/config/policies/policy.h24
-rw-r--r--src/charon/config/traffic_selector.c25
-rw-r--r--src/charon/config/traffic_selector.h30
6 files changed, 136 insertions, 68 deletions
diff --git a/src/charon/config/configuration.c b/src/charon/config/configuration.c
index 39fc4d922..f43afdaa4 100755
--- a/src/charon/config/configuration.c
+++ b/src/charon/config/configuration.c
@@ -33,25 +33,11 @@
#define HALF_OPEN_IKE_SA_TIMEOUT 30000
/**
- * The retransmission algorithm uses a multiple sequences.
- * Each sequence contains multiple retransmits. Those retransmits
- * are sent using a exponential backoff algorithm. The sequences
- * are retried with linear timings:
+ * Retransmission uses a backoff algorithm. The timeout is calculated using
+ * TIMEOUT * (BASE ** try).
+ * When try reaches TRIES, retransmission is given up.
*
- * <------sequence---------><------sequence---------><------sequence--------->
- *
- * T-R---R-----R---------R--R-R---R-----R---------R--R-R---R-----R---------R--X
- *
- * T = first transmit
- * R = retransmit
- * X = giving up, peer is dead
- *
- * if (retransmit >= TRIES * sequences)
- * => abort
- * TIMEOUT * (BASE ** (try % TRIES))
- *
- * Using an initial TIMEOUT of 4s, a BASE of 1.8, 5 TRIES
- * per sequnce and 3 sequences, this gives us:
+ * Using an initial TIMEOUT of 4s, a BASE of 1.8, and 5 TRIES gives us:
*
* | relative | absolute
* ---------------------------------------------------------
@@ -61,22 +47,8 @@
* 4s * (1.8 ** (3 % 5)) = 23s 47s
* 4s * (1.8 ** (4 % 5)) = 42s 89s
* 4s * (1.8 ** (5 % 5)) = 76s 165s
- * 4s * (1.8 ** (6 % 5)) = 4s 169s
- * 4s * (1.8 ** (7 % 5)) = 7s 176s
- * 4s * (1.8 ** (8 % 5)) = 13s 189s
- * 4s * (1.8 ** (9 % 5)) = 23s 212s
- * 4s * (1.8 ** (10 % 5)) = 42s 254s
- * 4s * (1.8 ** (11 % 5)) = 76s 330s
- * 4s * (1.8 ** (12 % 5)) = 4s 334
- * 4s * (1.8 ** (13 % 5)) = 7s 341s
- * 4s * (1.8 ** (14 % 5)) = 13s 354s
- * 4s * (1.8 ** (15 % 5)) = 23s 377s
- * 4s * (1.8 ** (16 % 5)) = 42s 419s
- * 4s * (1.8 ** (17 % 5)) = 76s 495s
*
- * If the configuration uses 1 sequence, the peer is considered dead
- * after 2min 45s when no reply comes in. If it uses 3 sequences, after
- * 8min 15s the DPD action is executed...
+ * The peer is considered dead after 2min 45s when no reply comes in.
*/
/**
@@ -119,17 +91,15 @@ struct private_configuration_t {
* Implementation of configuration_t.get_retransmit_timeout.
*/
static u_int32_t get_retransmit_timeout (private_configuration_t *this,
- u_int32_t retransmit_count,
- u_int32_t max_sequences)
+ u_int32_t retransmit_count)
{
- if (max_sequences != 0 &&
- retransmit_count >= RETRANSMIT_TRIES * max_sequences)
+ if (retransmit_count > RETRANSMIT_TRIES)
{
/* give up */
return 0;
}
- return (u_int32_t)(RETRANSMIT_TIMEOUT *
- pow(RETRANSMIT_BASE, retransmit_count % RETRANSMIT_TRIES));
+ return (u_int32_t)
+ (RETRANSMIT_TIMEOUT * pow(RETRANSMIT_BASE, retransmit_count));
}
/**
@@ -165,7 +135,7 @@ configuration_t *configuration_create()
/* public functions */
this->public.destroy = (void(*)(configuration_t*))destroy;
- this->public.get_retransmit_timeout = (u_int32_t (*) (configuration_t*,u_int32_t,u_int32_t))get_retransmit_timeout;
+ this->public.get_retransmit_timeout = (u_int32_t (*) (configuration_t*,u_int32_t))get_retransmit_timeout;
this->public.get_half_open_ike_sa_timeout = (u_int32_t (*) (configuration_t*)) get_half_open_ike_sa_timeout;
this->public.get_keepalive_interval = (u_int32_t (*) (configuration_t*)) get_keepalive_interval;
diff --git a/src/charon/config/configuration.h b/src/charon/config/configuration.h
index 2bb0b106e..77d1fd85d 100755
--- a/src/charon/config/configuration.h
+++ b/src/charon/config/configuration.h
@@ -40,19 +40,15 @@ struct configuration_t {
/**
* @brief Returns the retransmit timeout.
*
- * A return value of zero means the request should not be retransmitted again.
- * The retransmission algorithm uses sequences of retransmits, in which
- * every sequence contains exponential delayed retransmits. These
- * sequences are compareable to the keyingtries mechanism used in pluto.
+ * A return value of zero means the request should not be
+ * retransmitted again.
*
* @param this calling object
* @param retransmitted number of times a message was retransmitted so far
- * @param max_sequences maximum number of retransmission sequences to allow
- * @return time in milliseconds, when to schedule next retransmit
+ * @return time in milliseconds, when to do next retransmit
*/
u_int32_t (*get_retransmit_timeout) (configuration_t *this,
- u_int32_t retransmitted,
- u_int32_t max_sequences);
+ u_int32_t retransmitted);
/**
* @brief Returns the timeout for an half open IKE_SA in ms.
diff --git a/src/charon/config/policies/policy.c b/src/charon/config/policies/policy.c
index e68a8ad2b..fa23955fb 100644
--- a/src/charon/config/policies/policy.c
+++ b/src/charon/config/policies/policy.c
@@ -79,6 +79,16 @@ struct private_policy_t {
identification_t *other_id;
/**
+ * virtual IP to use locally
+ */
+ host_t *my_virtual_ip;
+
+ /**
+ * virtual IP to use remotly
+ */
+ host_t *other_virtual_ip;
+
+ /**
* Method to use for own authentication data
*/
auth_method_t auth_method;
@@ -209,7 +219,8 @@ static eap_type_t get_eap_type(private_policy_t *this)
/**
* Get traffic selectors, with wildcard-address update
*/
-static linked_list_t *get_traffic_selectors(private_policy_t *this, linked_list_t *list, host_t *host)
+static linked_list_t *get_traffic_selectors(private_policy_t *this,
+ linked_list_t *list, host_t *host)
{
iterator_t *iterator;
traffic_selector_t *current;
@@ -222,7 +233,10 @@ static linked_list_t *get_traffic_selectors(private_policy_t *this, linked_list_
/* we make a copy of the TS, this allows us to update wildcard
* addresses in it. We won't pollute the shared policy. */
current = current->clone(current);
- current->update_address_range(current, host);
+ if (host)
+ {
+ current->update_address_range(current, host);
+ }
result->insert_last(result, (void*)current);
}
@@ -269,7 +283,10 @@ static linked_list_t *select_traffic_selectors(private_policy_t *this,
/* we make a copy of the TS, this allows us to update wildcard
* addresses in it. We won't pollute the shared policy. */
stored_ts = stored_ts->clone(stored_ts);
- stored_ts->update_address_range(stored_ts, host);
+ if (host)
+ {
+ stored_ts->update_address_range(stored_ts, host);
+ }
supplied_iter->reset(supplied_iter);
/* iterate over all supplied traffic selectors */
@@ -457,6 +474,30 @@ static mode_t get_mode(private_policy_t *this)
}
/**
+ * Implementation of policy_t.get_virtual_ip.
+ */
+static host_t* get_virtual_ip(private_policy_t *this, host_t *suggestion)
+{
+ if (suggestion == NULL)
+ {
+ if (this->my_virtual_ip)
+ {
+ return this->my_virtual_ip->clone(this->my_virtual_ip);
+ }
+ return NULL;
+ }
+ if (this->other_virtual_ip)
+ {
+ return this->other_virtual_ip->clone(this->other_virtual_ip);
+ }
+ if (suggestion->is_anyaddr(suggestion))
+ {
+ return NULL;
+ }
+ return suggestion->clone(suggestion);
+}
+
+/**
* Implements policy_t.get_ref.
*/
static void get_ref(private_policy_t *this)
@@ -477,14 +518,8 @@ static void destroy(private_policy_t *this)
this->other_ts->destroy_offset(this->other_ts, offsetof(traffic_selector_t, destroy));
/* delete certification authorities */
- if (this->my_ca)
- {
- this->my_ca->destroy(this->my_ca);
- }
- if (this->other_ca)
- {
- this->other_ca->destroy(this->other_ca);
- }
+ DESTROY_IF(this->my_ca);
+ DESTROY_IF(this->other_ca);
/* delete updown script */
if (this->updown)
@@ -495,6 +530,8 @@ static void destroy(private_policy_t *this)
/* delete ids */
this->my_id->destroy(this->my_id);
this->other_id->destroy(this->other_id);
+ DESTROY_IF(this->my_virtual_ip);
+ DESTROY_IF(this->other_virtual_ip);
free(this->name);
free(this);
@@ -505,6 +542,7 @@ static void destroy(private_policy_t *this)
* Described in header-file
*/
policy_t *policy_create(char *name, identification_t *my_id, identification_t *other_id,
+ host_t *my_virtual_ip, host_t *other_virtual_ip,
auth_method_t auth_method, eap_type_t eap_type,
u_int32_t hard_lifetime, u_int32_t soft_lifetime,
u_int32_t jitter, char *updown, bool hostaccess,
@@ -536,6 +574,7 @@ policy_t *policy_create(char *name, identification_t *my_id, identification_t *o
this->public.get_soft_lifetime = (u_int32_t (*) (policy_t *))get_soft_lifetime;
this->public.get_hard_lifetime = (u_int32_t (*) (policy_t *))get_hard_lifetime;
this->public.get_mode = (mode_t (*) (policy_t *))get_mode;
+ this->public.get_virtual_ip = (host_t* (*)(policy_t*,host_t*))get_virtual_ip;
this->public.get_ref = (void (*) (policy_t*))get_ref;
this->public.destroy = (void (*) (policy_t*))destroy;
@@ -543,6 +582,8 @@ policy_t *policy_create(char *name, identification_t *my_id, identification_t *o
this->name = strdup(name);
this->my_id = my_id;
this->other_id = other_id;
+ this->my_virtual_ip = my_virtual_ip;
+ this->other_virtual_ip = other_virtual_ip;
this->auth_method = auth_method;
this->eap_type = eap_type;
this->hard_lifetime = hard_lifetime;
diff --git a/src/charon/config/policies/policy.h b/src/charon/config/policies/policy.h
index a2d9ae8d0..d8916b29e 100644
--- a/src/charon/config/policies/policy.h
+++ b/src/charon/config/policies/policy.h
@@ -329,6 +329,25 @@ struct policy_t {
mode_t (*get_mode) (policy_t *this);
/**
+ * @brief Get a virtual IP for the local or the remote host.
+ *
+ * By supplying NULL as IP, an IP for the local host is requested. It
+ * may be %any or specific.
+ * By supplying %any as host, an IP from the pool is selected to be
+ * served to the peer.
+ * If a specified host is supplied, it is checked if this address
+ * is acceptable to serve to the peer. If so, it is returned. Otherwise,
+ * an alternative IP is returned.
+ * In any mode, this call may return NULL indicating virtual IP should
+ * not be used.
+ *
+ * @param this policy
+ * @param suggestion NULL, %any or specific, see description
+ * @return clone of an IP to use, or NULL
+ */
+ host_t* (*get_virtual_ip) (policy_t *this, host_t *suggestion);
+
+ /**
* @brief Get a new reference.
*
* Get a new reference to this policy by increasing
@@ -356,6 +375,8 @@ struct policy_t {
* @brief Create a configuration object for IKE_AUTH and later.
*
* name-string gets cloned, ID's not.
+ * Virtual IPs are used if they are != NULL. A %any host means the virtual
+ * IP should be obtained from the other peer.
* Lifetimes are in seconds. To prevent to peers to start rekeying at the
* same time, a jitter may be specified. Rekeying of an SA starts at
* (soft_lifetime - random(0, jitter)). After a successful rekeying,
@@ -366,6 +387,8 @@ struct policy_t {
* @param name name of the policy
* @param my_id identification_t for ourselves
* @param other_id identification_t for the remote guy
+ * @param my_virtual_ip virtual IP for local host, or NULL
+ * @param other_virtual_ip virtual IP for remote host, or NULL
* @param auth_method Authentication method to use for our(!) auth data
* @param eap_type EAP type to use for peer authentication
* @param hard_lifetime lifetime before deleting an SA
@@ -381,6 +404,7 @@ struct policy_t {
*/
policy_t *policy_create(char *name,
identification_t *my_id, identification_t *other_id,
+ host_t *my_virtual_ip, host_t *other_virtual_ip,
auth_method_t auth_method, eap_type_t eap_type,
u_int32_t hard_lifetime, u_int32_t soft_lifetime,
u_int32_t jitter, char *updown, bool hostaccess,
diff --git a/src/charon/config/traffic_selector.c b/src/charon/config/traffic_selector.c
index 2afeb5e48..519c90f77 100644
--- a/src/charon/config/traffic_selector.c
+++ b/src/charon/config/traffic_selector.c
@@ -6,6 +6,7 @@
*/
/*
+ * Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -494,6 +495,26 @@ static void update_address_range(private_traffic_selector_t *this, host_t *host)
}
/**
+ * Implements traffic_selector_t.includes.
+ */
+static bool includes(private_traffic_selector_t *this, host_t *host)
+{
+ chunk_t addr;
+ int family = host->get_family(host);
+
+ if ((family == AF_INET && this->type == TS_IPV4_ADDR_RANGE) ||
+ (family == AF_INET6 && this->type == TS_IPV6_ADDR_RANGE))
+ {
+ addr = host->get_address(host);
+
+ return memcmp(this->from, addr.ptr, addr.len) <= 0 &&
+ memcmp(this->to, addr.ptr, addr.len) >= 0;
+ }
+
+ return FALSE;
+}
+
+/**
* Implements traffic_selector_t.clone.
*/
static traffic_selector_t *clone_(private_traffic_selector_t *this)
@@ -698,6 +719,7 @@ static private_traffic_selector_t *traffic_selector_create(u_int8_t protocol, ts
this->public.get_type = (ts_type_t(*)(traffic_selector_t*))get_type;
this->public.get_protocol = (u_int8_t(*)(traffic_selector_t*))get_protocol;
this->public.is_host = (bool(*)(traffic_selector_t*,host_t*))is_host;
+ this->public.includes = (bool(*)(traffic_selector_t*,host_t*))includes;
this->public.update_address_range = (void(*)(traffic_selector_t*,host_t*))update_address_range;
this->public.clone = (traffic_selector_t*(*)(traffic_selector_t*))clone_;
this->public.destroy = (void(*)(traffic_selector_t*))destroy;
@@ -709,3 +731,6 @@ static private_traffic_selector_t *traffic_selector_create(u_int8_t protocol, ts
return this;
}
+
+/* vim: set ts=4 sw=4 noet: */
+
diff --git a/src/charon/config/traffic_selector.h b/src/charon/config/traffic_selector.h
index 5d1ccaf2f..7728ba307 100644
--- a/src/charon/config/traffic_selector.h
+++ b/src/charon/config/traffic_selector.h
@@ -6,6 +6,7 @@
*/
/*
+ * Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -105,7 +106,7 @@ struct traffic_selector_t {
*
* Chunk is in network order gets allocated.
*
- * @param this calling object
+ * @param this called object
* @return chunk containing the address
*/
chunk_t (*get_from_address) (traffic_selector_t *this);
@@ -115,7 +116,7 @@ struct traffic_selector_t {
*
* Chunk is in network order gets allocated.
*
- * @param this calling object
+ * @param this called object
* @return chunk containing the address
*/
chunk_t (*get_to_address) (traffic_selector_t *this);
@@ -126,7 +127,7 @@ struct traffic_selector_t {
* Port is in host order, since the parser converts it.
* Size depends on protocol.
*
- * @param this calling object
+ * @param this called object
* @return port
*/
u_int16_t (*get_from_port) (traffic_selector_t *this);
@@ -137,7 +138,7 @@ struct traffic_selector_t {
* Port is in host order, since the parser converts it.
* Size depends on protocol.
*
- * @param this calling object
+ * @param this called object
* @return port
*/
u_int16_t (*get_to_port) (traffic_selector_t *this);
@@ -145,7 +146,7 @@ struct traffic_selector_t {
/**
* @brief Get the type of the traffic selector.
*
- * @param this calling obect
+ * @param this called object
* @return ts_type_t specifying the type
*/
ts_type_t (*get_type) (traffic_selector_t *this);
@@ -153,7 +154,7 @@ struct traffic_selector_t {
/**
* @brief Get the protocol id of this ts.
*
- * @param this calling obect
+ * @param this called object
* @return protocol id
*/
u_int8_t (*get_protocol) (traffic_selector_t *this);
@@ -167,7 +168,7 @@ struct traffic_selector_t {
* If host is NULL, the traffic selector is checked if it is a single host,
* but not a specific one.
*
- * @param this calling obect
+ * @param this called object
* @param host host_t specifying the address range
*/
bool (*is_host) (traffic_selector_t *this, host_t* host);
@@ -180,7 +181,7 @@ struct traffic_selector_t {
* starts from the supplied address and also ends there
* (which means it is a one-host-address-range ;-).
*
- * @param this calling obect
+ * @param this called object
* @param host host_t specifying the address range
*/
void (*update_address_range) (traffic_selector_t *this, host_t* host);
@@ -193,11 +194,19 @@ struct traffic_selector_t {
* @return pointer to a string.
*/
bool (*equals) (traffic_selector_t *this, traffic_selector_t *other);
+
+ /**
+ * @brief Check if a specific host is included in the address range of this traffic selector.
+ *
+ * @param this called object
+ * @param host the host to check
+ */
+ bool (*includes) (traffic_selector_t *this, host_t *host);
/**
* @brief Destroys the ts object
*
- * @param this calling object
+ * @param this called object
*/
void (*destroy) (traffic_selector_t *this);
};
@@ -269,3 +278,6 @@ traffic_selector_t *traffic_selector_create_from_subnet(
u_int8_t protocol, u_int16_t port);
#endif /* TRAFFIC_SELECTOR_H_ */
+
+/* vim: set ts=4 sw=4 noet: */
+