diff options
Diffstat (limited to 'src/charon/config')
-rwxr-xr-x | src/charon/config/configuration.c | 50 | ||||
-rwxr-xr-x | src/charon/config/configuration.h | 12 | ||||
-rw-r--r-- | src/charon/config/policies/policy.c | 63 | ||||
-rw-r--r-- | src/charon/config/policies/policy.h | 24 | ||||
-rw-r--r-- | src/charon/config/traffic_selector.c | 25 | ||||
-rw-r--r-- | src/charon/config/traffic_selector.h | 30 |
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: */ + |