ok
authorMartin Willi <martin@strongswan.org>
Wed, 23 Nov 2005 10:11:50 +0000 (10:11 -0000)
committerMartin Willi <martin@strongswan.org>
Wed, 23 Nov 2005 10:11:50 +0000 (10:11 -0000)
22 files changed:
Source/charon/configuration_manager.c [deleted file]
Source/charon/configuration_manager.h [deleted file]
Source/charon/daemon.c
Source/charon/encoding/message.c
Source/charon/encoding/message.h
Source/charon/globals.h
Source/charon/ike_sa.c [deleted file]
Source/charon/ike_sa.h [deleted file]
Source/charon/ike_sa_id.c [deleted file]
Source/charon/ike_sa_id.h [deleted file]
Source/charon/ike_sa_manager.c [deleted file]
Source/charon/ike_sa_manager.h [deleted file]
Source/charon/queues/jobs/delete_ike_sa_job.h
Source/charon/sa/ike_sa.c [new file with mode: 0644]
Source/charon/sa/ike_sa.h [new file with mode: 0644]
Source/charon/sa/ike_sa_id.c [new file with mode: 0644]
Source/charon/sa/ike_sa_id.h [new file with mode: 0644]
Source/charon/sa/ike_sa_manager.c [new file with mode: 0644]
Source/charon/sa/ike_sa_manager.h [new file with mode: 0644]
Source/charon/testcases/ike_sa_id_test.c
Source/charon/testcases/ike_sa_manager_test.c
Source/charon/testcases/ike_sa_test.c

diff --git a/Source/charon/configuration_manager.c b/Source/charon/configuration_manager.c
deleted file mode 100644 (file)
index 3b1488c..0000000
+++ /dev/null
@@ -1,484 +0,0 @@
-/**
- * @file configuration.c
- * 
- * @brief Configuration class used to store IKE_SA-configurations.
- * 
- * Object of this type represents the configuration for all IKE_SA's and their child_sa's.
- * 
- */
-
-/*
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stdlib.h>
-
-#include "configuration_manager.h"
-
-#include <types.h>
-#include <globals.h>
-#include <utils/allocator.h>
-#include <encoding/payloads/nonce_payload.h>
-#include <encoding/payloads/proposal_substructure.h>
-#include <encoding/payloads/ke_payload.h>
-#include <encoding/payloads/transform_attribute.h>
-
-/**
- * Private data of an configuration_t object
- */
-typedef struct private_configuration_manager_s private_configuration_manager_t;
-
-struct private_configuration_manager_s {
-
-       /**
-        * Public part
-        */
-       configuration_manager_t public;
-
-       /**
-        * Assigned logger object 
-        */
-       logger_t *logger;
-};
-
-/**
- * Implements function configuration_manager_t.get_remote_host.
- */
-static status_t get_remote_host(private_configuration_manager_t *this, char *name, host_t **host)
-{
-       /*
-        * For testing purposes, hard coded host informations for two configurations are returned.
-        * 
-        * Further improvements could store them in a linked list or hash table.
-        */
-
-       host_t *remote;
-       status_t status = SUCCESS;
-       
-       if (strcmp(name, "pinflb30") == 0)
-       {
-               remote = host_create(AF_INET, "152.96.193.130", 500);
-       }
-       else if (strcmp(name, "pinflb31") == 0)
-       {
-               remote = host_create(AF_INET, "152.96.193.131", 500);
-       }
-       else
-       {
-               status = NOT_FOUND;
-       }
-       if ((status != NOT_FOUND) && (remote == NULL))
-       {
-               return OUT_OF_RES;      
-       }
-
-       *host = remote;
-       return status;
-}
-
-/**
- * Implements function configuration_manager_t.get_local_host.
- */
-static status_t get_local_host(private_configuration_manager_t *this, char *name, host_t **host)
-{
-       /*
-        * For testing purposes, only the default route is returned for each configuration.
-        * 
-        * Further improvements could store different local host informations in a linked list or hash table.
-        */
-       host_t *local;
-       local = host_create(AF_INET, "0.0.0.0", 0);
-       if (local == NULL)
-       {
-               return OUT_OF_RES;      
-       }
-       *host = local;
-       return SUCCESS;
-}
-
-/**
- * Implements function configuration_manager_t.get_dh_group_number.
- */
-static status_t get_dh_group_number(private_configuration_manager_t *this,char *name, u_int16_t *dh_group_number, u_int16_t priority)
-{
-       /* Currently only two dh_group_numbers are supported for each configuration*/
-       
-       if (priority == 1)
-       {
-               *dh_group_number = MODP_1024_BIT;
-       }
-       else
-       {
-               *dh_group_number = MODP_768_BIT;
-       }
-       return SUCCESS;
-}
-
-/**
- * Implements function configuration_manager_t.get_proposals_for_host.
- */
-static status_t get_proposals_for_host(private_configuration_manager_t *this, host_t *host, linked_list_iterator_t *iterator)
-{
-       /* 
-        * Currently the following hard coded proposal is created and returned for all hosts:
-        * - ENCR_AES_CBC 128Bit
-        * - PRF_HMAC_MD5 128Bit
-        * - AUTH_HMAC_MD5_96 128Bit
-        * - MODP_1024_BIT
-        */
-       proposal_substructure_t *proposal;
-       transform_substructure_t *transform;
-       transform_attribute_t *attribute;
-       status_t status;
-       
-       proposal = proposal_substructure_create();
-       if (proposal == NULL)
-       {
-               return OUT_OF_RES;
-       }
-       
-       proposal->set_proposal_number(proposal, 1);
-       proposal->set_protocol_id(proposal, 1);
-       
-       /* 
-        * Encryption Algorithm 
-        */
-       transform = transform_substructure_create();
-       if (transform == NULL)
-       {
-               proposal->destroy(proposal);
-               return OUT_OF_RES;
-       }
-       status = proposal->add_transform_substructure(proposal, transform);
-       if (status != SUCCESS)
-       {
-               proposal->destroy(proposal);
-               return OUT_OF_RES;
-       }
-       transform->set_transform_type(transform, ENCRYPTION_ALGORITHM);
-       transform->set_transform_id(transform, ENCR_AES_CBC);
-       
-       attribute = transform_attribute_create();
-       if (attribute == NULL)
-       {
-               proposal->destroy(proposal);
-               return OUT_OF_RES;
-       }
-       status = transform->add_transform_attribute(transform, attribute);
-       if (status != SUCCESS)
-       {
-               proposal->destroy(proposal);
-               return OUT_OF_RES;
-       }
-       attribute->set_attribute_type(attribute, KEY_LENGTH);
-       attribute->set_value(attribute, 16);
-       
-       /* 
-        * Pseudo-random Function
-        */
-       transform = transform_substructure_create();
-       if (transform == NULL)
-       {
-               proposal->destroy(proposal);
-               return OUT_OF_RES;
-       }
-       status = proposal->add_transform_substructure(proposal, transform);
-       if (status != SUCCESS)
-       {
-               proposal->destroy(proposal);
-               return OUT_OF_RES;
-       }
-       transform->set_transform_type(transform, PSEUDO_RANDOM_FUNCTION);
-       transform->set_transform_id(transform, PRF_HMAC_MD5);
-       
-       attribute = transform_attribute_create();
-       if (attribute == NULL)
-       {               
-               proposal->destroy(proposal);
-               return OUT_OF_RES;
-       }
-       status = transform->add_transform_attribute(transform, attribute);
-       if (status != SUCCESS)
-       {
-               proposal->destroy(proposal);
-               return OUT_OF_RES;
-       }
-       attribute->set_attribute_type(attribute, KEY_LENGTH);
-       attribute->set_value(attribute, 16);
-
-       
-       /* 
-        * Integrity Algorithm 
-        */
-       transform = transform_substructure_create();
-       if (transform == NULL)
-       {
-               proposal->destroy(proposal);
-               return OUT_OF_RES;
-       }
-       status = proposal->add_transform_substructure(proposal, transform);
-       if (status != SUCCESS)
-       {
-               proposal->destroy(proposal);
-               return OUT_OF_RES;
-       }
-       transform->set_transform_type(transform, INTEGRITIY_ALGORITHM);
-       transform->set_transform_id(transform, AUTH_HMAC_MD5_96);
-       
-       attribute = transform_attribute_create();
-       if (attribute == NULL)
-       {               
-               proposal->destroy(proposal);
-               return OUT_OF_RES;
-       }
-       status = transform->add_transform_attribute(transform, attribute);
-       if (status != SUCCESS)
-       {
-               proposal->destroy(proposal);
-               return OUT_OF_RES;
-       }
-       attribute->set_attribute_type(attribute, KEY_LENGTH);
-       attribute->set_value(attribute, 16);
-       
-       
-    /* 
-     * Diffie-Hellman Group 
-     */
-       transform = transform_substructure_create();
-       if (transform == NULL)
-       {
-               proposal->destroy(proposal);
-               return OUT_OF_RES;
-       }
-       status = proposal->add_transform_substructure(proposal, transform);
-       if (status != SUCCESS)
-       {
-               proposal->destroy(proposal);
-               return OUT_OF_RES;
-       }
-       transform->set_transform_type(transform, DIFFIE_HELLMAN_GROUP);
-       transform->set_transform_id(transform, MODP_1024_BIT);
-       
-       iterator->insert_after(iterator, (void*)proposal);
-       
-       return SUCCESS;
-}
-       
-/**
- * Implements function configuration_manager_t.select_proposals_for_host.
- */
-static status_t select_proposals_for_host(private_configuration_manager_t *this, host_t *host, linked_list_iterator_t *in, linked_list_iterator_t *out)
-{
-       /* Currently the first suggested proposal is selected, cloned and then returned*/
-       status_t status;
-       proposal_substructure_t *first_suggested_proposal;
-       proposal_substructure_t *selected_proposal;
-       
-       this->logger->log(this->logger,CONTROL | MORE, "Going to select first suggested proposal");
-       if (!in->has_next(in))
-       {
-               this->logger->log(this->logger,ERROR | MORE, "No proposal suggested");
-               /* no suggested proposal! */
-               return FAILED;
-       }
-       
-       status = in->current(in,(void **) &first_suggested_proposal);
-       if (status != SUCCESS)
-       {
-               this->logger->log(this->logger,ERROR, "Fatal error: could not get first proposal from iterator");
-               return status;  
-       }
-       status = first_suggested_proposal->clone(first_suggested_proposal,&selected_proposal);
-       if (status != SUCCESS)
-       {
-               this->logger->log(this->logger,ERROR, "Fatal error: could not clone proposal");
-               /* could not clone proposal */
-               return status;  
-       }
-       
-       status = out->insert_after(out,selected_proposal);
-       if (status != SUCCESS)
-       {
-               this->logger->log(this->logger,ERROR, "Fatal error: could not insert selected proposal in out iterator");
-       }       
-       return status;
-}
-
-/**
- * Implements function configuration_manager_t.get_transforms_for_host_and_proposals.
- */
-static status_t get_transforms_for_host_and_proposals (private_configuration_manager_t *this, host_t *host, linked_list_iterator_t *proposals,encryption_algorithm_t *encryption_algorithm,pseudo_random_function_t *pseudo_random_function, integrity_algorithm_t *integrity_algorithm)
-{
-       /*
-        * Currently the given proposals are not checked if they are valid for specific host!
-        * 
-        * The first proposal is taken and the appropriate transform objects are created (only if they are supported)
-        */
-
-       encryption_algorithm_t          selected_encryption_algorithm = ENCR_UNDEFINED;
-       pseudo_random_function_t                selected_pseudo_random_function = PRF_UNDEFINED;
-       integrity_algorithm_t           selected_integrity_algorithm = AUTH_UNDEFINED;
-       proposal_substructure_t *proposal;
-       linked_list_iterator_t *transforms;
-       status_t status;
-
-       this->logger->log(this->logger,ERROR, "Going to get transforms for given proposal");
-
-       if (!proposals->has_next(proposals))
-       {
-               this->logger->log(this->logger,ERROR | MORE, "No proposal available");
-               return FAILED;
-       }
-       
-       status = proposals->current(proposals,(void **) &(proposal));
-       if (status != SUCCESS)
-       {
-               this->logger->log(this->logger,ERROR, "Fatal error: could not get first proposal from iterator");
-               return status;  
-       }
-       
-       status = proposal->create_transform_substructure_iterator(proposal,&transforms,TRUE);
-       if (status != SUCCESS)
-       {
-               this->logger->log(this->logger,ERROR, "Fatal error: could not create iterator of transforms");
-               return status;  
-       }
-       
-       while (transforms->has_next(transforms))
-       {
-               transform_substructure_t *current_transform;
-               transform_type_t transform_type;
-               u_int16_t transform_id;
-               
-               status = transforms->current(transforms,(void **) &(current_transform));
-               if (status != SUCCESS)
-               {
-                       this->logger->log(this->logger,ERROR, "Fatal error: could not get current transform substructure object");
-                       transforms->destroy(transforms);        
-                       return status;  
-               }
-               
-               transform_type = current_transform->get_transform_type(current_transform);
-               transform_id = current_transform->get_transform_id(current_transform);
-               
-               this->logger->log(this->logger,CONTROL | MOST, "Going to process transform of type %s",mapping_find(transform_type_m,transform_type));
-               switch (transform_type)
-               {
-                       case ENCRYPTION_ALGORITHM:
-                       {
-                               this->logger->log(this->logger,CONTROL | MORE, "Encryption algorithm: %s",mapping_find(encryption_algorithm_m,transform_id));   
-                               selected_encryption_algorithm = transform_id;
-                               break;
-                       }
-                       case     PSEUDO_RANDOM_FUNCTION:
-                       {
-                               this->logger->log(this->logger,CONTROL | MORE, "Create transform object for PRF of type %s",mapping_find(pseudo_random_function_m,transform_id));
-                               selected_pseudo_random_function = transform_id;
-                               break;
-                       }
-                       case INTEGRITIY_ALGORITHM:
-                       {
-                               this->logger->log(this->logger,CONTROL | MORE, "Integrity algorithm: %s",mapping_find(integrity_algorithm_m,transform_id));
-                               selected_integrity_algorithm = transform_id;
-                               break;
-                       }
-                       case DIFFIE_HELLMAN_GROUP:
-                       {
-                               this->logger->log(this->logger,CONTROL | MORE, "DH Group: %s",mapping_find(diffie_hellman_group_m,transform_id));
-                               break;
-                       }
-                       default:
-                       {
-                               this->logger->log(this->logger,ERROR  | MORE, "Transform type not supported!");
-                               transforms->destroy(transforms);        
-                               return FAILED;
-                       }       
-               }
-       }
-       
-       transforms->destroy(transforms);
-
-       *encryption_algorithm = selected_encryption_algorithm;
-       *pseudo_random_function = selected_pseudo_random_function;
-       *integrity_algorithm = selected_integrity_algorithm;
-       return SUCCESS;
-}
-
-/**
- * Implements function configuration_manager_t.is_dh_group_allowed_for_host.
- */
-static status_t is_dh_group_allowed_for_host(private_configuration_manager_t *this, host_t *host, diffie_hellman_group_t group, bool *allowed)
-{
-       /*
-        * Only the two DH groups 768 and 1024 are supported for each configuration
-        */
-       
-       if (group == MODP_768_BIT || group == MODP_1024_BIT)
-       {
-               *allowed = TRUE;                
-       }
-       *allowed = FALSE;
-       
-       this->logger->log(this->logger,CONTROL | MORE, "DH group %s is %s",mapping_find(diffie_hellman_group_m, group),(allowed)? "allowed" : "not allowed");
-       return SUCCESS;
-}
-
-
-/**
- * Implements function destroy of configuration_t.
- * See #configuration_s.destroy for description.
- */
-static status_t destroy(private_configuration_manager_t *this)
-{
-       this->logger->log(this->logger,CONTROL | MORE, "Going to destroy configuration manager ");
-       
-       this->logger->log(this->logger,CONTROL | MOST, "Destroy assigned logger");
-       global_logger_manager->destroy_logger(global_logger_manager,this->logger);
-       allocator_free(this);
-       return SUCCESS;
-}
-
-/*
- * Described in header-file
- */
-configuration_manager_t *configuration_manager_create()
-{
-       private_configuration_manager_t *this = allocator_alloc_thing(private_configuration_manager_t);
-       
-       if (this == NULL)
-       {
-               return NULL;
-       }
-
-       /* public functions */
-       this->public.destroy = (status_t(*)(configuration_manager_t*))destroy;
-       this->public.get_remote_host = (status_t(*)(configuration_manager_t*,char*,host_t**))get_remote_host;
-       this->public.get_local_host = (status_t(*)(configuration_manager_t*,char*,host_t**))get_local_host;
-       this->public.get_dh_group_number = (status_t(*)(configuration_manager_t*,char*,u_int16_t *, u_int16_t))get_dh_group_number;
-       this->public.get_proposals_for_host = (status_t(*)(configuration_manager_t*,host_t*,linked_list_iterator_t*))get_proposals_for_host;
-       this->public.select_proposals_for_host = (status_t(*)(configuration_manager_t*,host_t*,linked_list_iterator_t*,linked_list_iterator_t*))select_proposals_for_host;
-       this->public.get_transforms_for_host_and_proposals =  (status_t (*) (configuration_manager_t *, host_t *, linked_list_iterator_t *,encryption_algorithm_t *,pseudo_random_function_t *, integrity_algorithm_t *)) get_transforms_for_host_and_proposals;
-       this->public.is_dh_group_allowed_for_host = (status_t(*)(configuration_manager_t*,host_t*,diffie_hellman_group_t,bool*)) is_dh_group_allowed_for_host;
-
-       /* private variables */
-       this->logger = global_logger_manager->create_logger(global_logger_manager,CONFIGURATION_MANAGER,NULL);
-
-       if (this->logger == NULL)
-       {
-               allocator_free(this);
-               return NULL;
-       }
-
-       return (&this->public);
-}
diff --git a/Source/charon/configuration_manager.h b/Source/charon/configuration_manager.h
deleted file mode 100644 (file)
index b192c0c..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-/**
- * @file configuration_manager.h
- * 
- * @brief Manages all configuration aspects of the daemon.
- *  
- */
-
-/*
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef CONFIGURATION_MANAGER_H_
-#define CONFIGURATION_MANAGER_H_
-
-#include <types.h>
-#include <utils/linked_list.h>
-#include <utils/host.h>
-#include <encoding/payloads/transform_substructure.h>
-#include <transforms/prfs/prf.h>
-#include <transforms/signers/signer.h>
-#include <transforms/crypters/crypter.h>
-
-/**
- * @brief Manages all configuration aspects of the daemon.
- * 
- * Currently the configuration manager class does not store specific configurations.
- * It is expected, that in future different configurations are stored in a linked list 
- * or a hash map and are managed by this class.
- * 
- */
-typedef struct configuration_manager_s configuration_manager_t;
-
-struct configuration_manager_s { 
-       
-       /**
-        * Gets the remote host information for a specific configuration name.
-        * 
-        * A host information consist of IP address and UDP port.
-        * 
-        * @param this  calling object
-        * @param name  name of the configuration
-        * @param host  remote host information gets stored at this location
-        * 
-        * @return              
-        *                              - OUT_OF_RES
-        *                              - NOT_FOUND
-        *                              - SUCCESS
-        */
-       status_t (*get_remote_host) (configuration_manager_t *this, char *name, host_t **host);
-
-       /**
-        * Gets the local host information for a specific configuration name
-        * 
-        * A host information consist of IP address and UDP port.
-        * 
-        * @param this  calling object
-        * @param name  name of the configuration
-        * @param host  local host information gets stored at this location
-        * 
-        * @return              
-        *                              - OUT_OF_RES
-        *                              - NOT_FOUND (not yet implemented)
-        *                              - SUCCESS
-        */
-       status_t (*get_local_host) (configuration_manager_t *this, char *name, host_t **host);
-       
-       /**
-        * Returns the DH group number to use when initiating a connection.
-        * 
-        * To make sure that different group numbers are supported in case 
-        * a group number is not supported by other peer, a priority has to get defined.
-        * 
-        * 
-        * @param this                          calling object
-        * @param name                          name of the configuration
-        * @param dh_group_number       the DH group number gets stored at this location
-        * @param priority                      priority to use for selection of DH group number.
-        *                                                      Highest priority is 1. All higher values have lower
-        *                                                      priority.
-        * 
-        * @return              
-        *                                                      - FAILED (not yet implemented)
-        *                                                      - NOT_FOUND (not yet implemented)
-        *                                                      - SUCCESS
-        */
-       status_t (*get_dh_group_number) (configuration_manager_t *this, char *name, u_int16_t *dh_group_number, u_int16_t priority);
-       
-       /**
-        * Returns the proposals which should be used to initiate a connection with a specific
-        * host.
-        * 
-        * The proposals of type proposal_substructure_t * are returned over the given iterator 
-        * and have to be destroyed by the caller.
-        * 
-        * 
-        * @param this                          calling object
-        * @param host                          host information used to find the correct proposals
-        * @param list                          iterator where the proposals are written to
-        * 
-        * @return              
-        *                                                      - OUT_OF_RES
-        *                                                      - NOT_FOUND (not yet implemented)
-        *                                                      - SUCCESS
-        */
-       status_t (*get_proposals_for_host) (configuration_manager_t *this, host_t *host, linked_list_iterator_t *list);
-       
-       /**
-        * Checks the suggested proposals passed as iterator in and selects one proposal to be sent as selection
-        * of this proposals.
-        * 
-        * Currently there is no check implemented. The first suggested proposal is cloned and then as selected returned.
-        * 
-        * 
-        * @param this                          calling object
-        * @param host                          host information used to find the correct proposals
-        * @param in                                    iterator with suggested proposals of type proposal_substructure_t *
-        * @param out                           The selected proposals of type proposal_substructure_t * are written to this iterator
-        * 
-        * @return              
-        *                                                      - OUT_OF_RES
-        *                                                      - FAILED
-        *                                                      - NOT_FOUND (not yet implemented)
-        *                                                      - SUCCESS
-        */
-       status_t (*select_proposals_for_host) (configuration_manager_t *this, host_t *host, linked_list_iterator_t *in, linked_list_iterator_t *out);
-       
-       /**
-        * Returns the transforms of type crypter_t, signer_t and prf_t as specified in given proposal.
-        * 
-        * 
-        * @param this                                                  calling object
-        * @param host                                                  host information
-        * @param proposals                                             iterator with selected proposals
-        * @param[out] encryption_algorithm             
-        * @param[out] pseudo_random_function   
-        * @param[out] integrity_algorithm              
-        * 
-        * @return              
-        *                                                                              - OUT_OF_RES
-        *                                                                              - FAILED
-        *                                                                              - NOT_FOUND (not yet implemented)
-        *                                                                              - SUCCESS
-        */
-       status_t (*get_transforms_for_host_and_proposals) (configuration_manager_t *this, host_t *host, linked_list_iterator_t *proposals,encryption_algorithm_t *encryption_algorithm,pseudo_random_function_t *pseudo_random_function, integrity_algorithm_t *integrity_algorithm);
-       
-       /**
-        * Checks if a given dh_group number is allowed for a specific host
-        * 
-        * 
-        * @param this                          calling object
-        * @param host                          host information
-        * @param group                         DH group number to check if allowed
-        * @param[out] allowed          will be set to TRUE if group number is allowed, FALSE otherwise
-        * 
-        * @return              
-        *                                                      - FAILED
-        *                                                      - NOT_FOUND (not yet implemented)
-        *                                                      - SUCCESS
-        */
-       status_t (*is_dh_group_allowed_for_host) (configuration_manager_t *this, host_t *host, diffie_hellman_group_t group, bool *allowed);
-       
-       /**
-        * Destroys configuration manager
-        * 
-        * 
-        * @param this                          calling object
-        * @return              
-        *                                                      - SUCCESS
-        */
-       status_t (*destroy) (configuration_manager_t *this);
-};
-
-/**
- * Creates the mighty configuration manager
- * 
- * @return 
- *                     - pointer to created manager object if succeeded
- *                     - NULL if memory allocation failed
- */
-configuration_manager_t *configuration_manager_create();
-
-#endif /*CONFIGURATION_MANAGER_H_*/
index d856a5d..3eef8d6 100644 (file)
@@ -28,7 +28,7 @@
 
 
 #include <types.h>
-#include <ike_sa_manager.h>
+#include <sa/ike_sa_manager.h>
 #include <threads/sender.h>
 #include <threads/receiver.h>
 #include <threads/scheduler.h>
index d32126e..5a6501d 100644 (file)
@@ -26,7 +26,7 @@
 
 #include <types.h>
 #include <globals.h>
-#include <ike_sa_id.h>
+#include <sa/ike_sa_id.h>
 #include <encoding/generator.h>
 #include <encoding/parser.h>
 #include <utils/linked_list.h>
index 960be94..1061604 100644 (file)
@@ -24,7 +24,7 @@
 #define MESSAGE_H_
 
 #include <types.h>
-#include <ike_sa_id.h>
+#include <sa/ike_sa_id.h>
 #include <network/packet.h>
 #include <encoding/payloads/ike_header.h>
 #include <utils/linked_list.h>
index d3cfb08..39dc841 100644 (file)
 #ifndef GLOBALS_H_
 #define GLOBALS_H_
 
-#include <ike_sa_manager.h>
+#include <sa/ike_sa_manager.h>
 #include <queues/send_queue.h>
 #include <queues/job_queue.h>
 #include <network/socket.h>
 #include <queues/event_queue.h>
 #include <utils/logger_manager.h>
-#include <configuration_manager.h>
+#include <config/configuration_manager.h>
 
 
 extern socket_t *global_socket;
diff --git a/Source/charon/ike_sa.c b/Source/charon/ike_sa.c
deleted file mode 100644 (file)
index bd16692..0000000
+++ /dev/null
@@ -1,574 +0,0 @@
-/**
- * @file ike_sa.c
- *
- * @brief Class ike_sa_t. An object of this type is managed by an
- * ike_sa_manager_t object and represents an IKE_SA
- *
- */
-
-/*
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include "ike_sa.h"
-
-#include <types.h>
-#include <globals.h>
-#include <definitions.h>
-#include <utils/allocator.h>
-#include <utils/linked_list.h>
-#include <utils/logger_manager.h>
-#include <utils/randomizer.h>
-#include <transforms/diffie_hellman.h>
-#include <transforms/prf_plus.h>
-#include <encoding/payloads/sa_payload.h>
-#include <encoding/payloads/nonce_payload.h>
-#include <encoding/payloads/ke_payload.h>
-#include <encoding/payloads/transform_substructure.h>
-#include <encoding/payloads/transform_attribute.h>
-#include <states/initiator_init.h>
-#include <states/responder_init.h>
-
-
-
-
-/**
- * @brief implements function process_message of protected_ike_sa_t
- */
-static status_t process_message (protected_ike_sa_t *this, message_t *message)
-{      
-       u_int32_t message_id;
-       exchange_type_t exchange_type;
-       bool is_request;
-       status_t status;
-       state_t *new_state;
-       
-       /* we must process each request or response from remote host */
-
-       /* find out type of message (request or response) */
-       is_request = message->get_request(message);
-       exchange_type = message->get_exchange_type(message);
-
-       this->logger->log(this->logger, CONTROL|MORE, "Process %s message of exchange type %s",(is_request) ? "REQUEST" : "RESPONSE",mapping_find(exchange_type_m,exchange_type));
-
-       message_id = message->get_message_id(message);
-
-       /* 
-        * It has to be checked, if the message has to be resent cause of lost packets!
-        */
-       if (is_request && ( message_id == (this->message_id_in - 1)))
-       {
-               /* message can be resent ! */
-               this->logger->log(this->logger, CONTROL|MORE, "Resent message detected. Send stored reply");
-               return (this->resend_last_reply(this));
-       }
-       
-       /* Now, the message id is checked for request AND reply */
-       if (is_request)
-       {
-               /* In a request, the message has to be this->message_id_in (other case is already handled) */
-               if (message_id != this->message_id_in)
-               {
-                       this->logger->log(this->logger, ERROR | MORE, "Message request with message id %d received, but %d expected",message_id,this->message_id_in);
-                       return FAILED;
-               }
-       }
-       else
-       {
-               /* In a reply, the message has to be this->message_id_out -1 cause it is the reply to the last sent message*/
-               if (message_id != (this->message_id_out - 1))
-               {
-                       this->logger->log(this->logger, ERROR | MORE, "Message reply with message id %d received, but %d expected",message_id,this->message_id_in);
-                       return FAILED;
-               }
-       }
-       
-       /* now the message is processed by the current state object */
-       status = this->current_state->process_message(this->current_state,message,&new_state);
-
-       if (status == SUCCESS)
-       {
-               this->current_state = new_state;
-       }
-       return status;
-}
-
-/**
- * @brief Implements function build_message of protected_ike_sa_t.
- */
-static status_t build_message(protected_ike_sa_t *this, exchange_type_t type, bool request, message_t **message)
-{
-       status_t status;
-       message_t *new_message; 
-       host_t *source, *destination;
-
-       this    ->logger->log(this->logger, CONTROL|MORE, "build empty message");       
-       new_message = message_create(); 
-       if (new_message == NULL)
-       {
-               this->logger->log(this->logger, ERROR, "Fatal error: could not create empty message object");   
-               return OUT_OF_RES;
-       }
-       
-       status  = this->me.host->clone(this->me.host, &source);
-       if (status != SUCCESS)
-       {
-               this->logger->log(this->logger, ERROR, "Fatal error: could not clone my host information");
-               new_message->destroy(new_message);
-               return status;  
-       }
-       status = this->other.host->clone(this->other.host, &destination);       
-       if (status != SUCCESS)
-       {
-               this->logger->log(this->logger, ERROR, "Fatal error: could not clone other host information");
-               source->destroy(source);
-               new_message->destroy(new_message);
-               return status;  
-       }
-       
-       new_message->set_source(new_message, source);
-       new_message->set_destination(new_message, destination);
-       
-       new_message->set_exchange_type(new_message, type);
-       new_message->set_request(new_message, request);
-       
-       new_message->set_message_id(new_message, (request) ? this->message_id_out : this->message_id_in);
-
-       status = new_message->set_ike_sa_id(new_message, this->ike_sa_id);
-       if (status != SUCCESS)
-       {
-               this->logger->log(this->logger, ERROR, "Fatal error: could not set ike_sa_id of message");
-               new_message->destroy(new_message);
-               return status;
-       }
-       
-       *message = new_message;
-       
-       return SUCCESS;
-}
-
-/**
- * @brief implements function process_configuration of protected_ike_sa_t
- */
-static status_t initialize_connection(protected_ike_sa_t *this, char *name)
-{
-       /* work is done in state object of type INITIATOR_INIT */
-       initiator_init_t *current_state;
-       status_t status;
-       state_t *new_state;
-       
-       if (this->current_state->get_state(this->current_state) != INITIATOR_INIT)
-       {
-               return FAILED;
-       }
-       
-       current_state = (initiator_init_t *) this->current_state;
-       
-       status = current_state->initiate_connection(current_state,name,&new_state);
-       
-       if (status == SUCCESS)
-       {
-               this->current_state = new_state;
-       }
-       else
-       {
-               this->create_delete_job(this);
-       }
-       return status;
-}
-
-/**
- * @brief implements function protected_ike_sa_t.get_id
- */
-static ike_sa_id_t* get_id(protected_ike_sa_t *this)
-{
-       return this->ike_sa_id;
-}
-
-static status_t compute_secrets (protected_ike_sa_t *this,chunk_t dh_shared_secret,chunk_t initiator_nonce, chunk_t responder_nonce)
-{
-       chunk_t concatenated_nonces;
-       chunk_t skeyseed;
-       chunk_t prf_plus_seed;
-       status_t status;
-       u_int64_t initiator_spi;
-       u_int64_t responder_spi;
-       prf_plus_t *prf_plus;
-       chunk_t secrets_raw;
-
-       /*
-        * TODO check length for specific prf's 
-        */
-       concatenated_nonces.len = (initiator_nonce.len + responder_nonce.len);
-       concatenated_nonces.ptr = allocator_alloc(concatenated_nonces.len);
-       if (concatenated_nonces.ptr == NULL)
-       {
-               this->logger->log(this->logger, ERROR, "Fatal errror: Could not allocate memory for concatenated nonces");
-               return FAILED;
-       }
-       /* first is initiator */
-       memcpy(concatenated_nonces.ptr,initiator_nonce.ptr,initiator_nonce.len);
-       /* second is responder */
-       memcpy(concatenated_nonces.ptr + initiator_nonce.len,responder_nonce.ptr,responder_nonce.len);
-
-       this->logger->log_chunk(this->logger, RAW, "Nonce data", &concatenated_nonces);
-
-
-       /* status of set_key is not checked */
-       status = this->prf->set_key(this->prf,concatenated_nonces);
-
-       status = this->prf->allocate_bytes(this->prf,dh_shared_secret,&skeyseed);
-       if (status != SUCCESS)
-       {
-               allocator_free_chunk(concatenated_nonces);
-               this->logger->log(this->logger, ERROR, "Fatal errror: Could not allocate bytes for skeyseed");
-               return status;
-       }
-       allocator_free_chunk(concatenated_nonces);
-
-       prf_plus_seed.len = (initiator_nonce.len + responder_nonce.len + 16);
-       prf_plus_seed.ptr = allocator_alloc(prf_plus_seed.len);
-       if (prf_plus_seed.ptr == NULL)
-       {
-               this->logger->log(this->logger, ERROR, "Fatal errror: Could not allocate memory for prf+ seed");
-               allocator_free_chunk(skeyseed);
-               return FAILED;
-       }
-       
-       /* first is initiator */
-       memcpy(prf_plus_seed.ptr,initiator_nonce.ptr,initiator_nonce.len);
-       /* second is responder */
-       memcpy(prf_plus_seed.ptr + initiator_nonce.len,responder_nonce.ptr,responder_nonce.len);
-       /* third is initiator spi */
-       initiator_spi = this->ike_sa_id->get_initiator_spi(this->ike_sa_id);
-       memcpy(prf_plus_seed.ptr + initiator_nonce.len + responder_nonce.len,&initiator_spi,8);
-       /* fourth is responder spi */
-       responder_spi = this->ike_sa_id->get_responder_spi(this->ike_sa_id);
-       memcpy(prf_plus_seed.ptr + initiator_nonce.len + responder_nonce.len + 8,&responder_spi,8);
-       
-       this->logger->log_chunk(this->logger, PRIVATE, "Keyseed", &skeyseed);
-       this->logger->log_chunk(this->logger, PRIVATE, "PRF+ Seed", &prf_plus_seed);
-
-       this->logger->log(this->logger, CONTROL | MOST, "Set new key of prf object");
-       status = this->prf->set_key(this->prf,skeyseed);
-       allocator_free_chunk(skeyseed);
-       if (status != SUCCESS)
-       {
-               this->logger->log(this->logger, ERROR, "Fatal errror: Could not allocate memory for prf+ seed");
-               allocator_free_chunk(prf_plus_seed);
-               return FAILED;
-       }
-       
-       this->logger->log(this->logger, CONTROL | MOST, "Create new prf+ object");
-       prf_plus = prf_plus_create(this->prf, prf_plus_seed);
-       allocator_free_chunk(prf_plus_seed);
-       if (prf_plus == NULL)
-       {
-               this->logger->log(this->logger, ERROR, "Fatal errror: prf+ object could not be created");
-               return FAILED;
-       }
-       
-       prf_plus->allocate_bytes(prf_plus,100,&secrets_raw);
-       
-       this->logger->log_chunk(this->logger, PRIVATE, "Secrets", &secrets_raw);
-       
-       allocator_free_chunk(secrets_raw);
-       
-       prf_plus->destroy(prf_plus);
-
-       return SUCCESS;
-}
-
-/**
- * @brief implements function resend_last_reply of protected_ike_sa_t
- */
-status_t resend_last_reply (protected_ike_sa_t *this)
-{
-       packet_t *packet;
-       status_t status;
-       
-       status = this->last_responded_message->generate(this->last_responded_message, &packet);
-       if (status != SUCCESS)
-       {
-               this->logger->log(this->logger, ERROR, "Could not generate message to resent");
-               return status;
-       }
-       
-       status = global_send_queue->add(global_send_queue, packet);
-       if (status != SUCCESS)
-       {
-               this->logger->log(this->logger, ERROR, "Could not add packet to send queue");
-               packet->destroy(packet);
-               return status;
-       }               
-       return SUCCESS;
-}
-
-status_t create_delete_job (protected_ike_sa_t *this)
-{
-       job_t *delete_job;
-       status_t status;
-
-       this->logger->log(this->logger, CONTROL | MORE, "Going to create job to delete this IKE_SA");
-
-       delete_job = (job_t *) delete_ike_sa_job_create(this->ike_sa_id);
-       if (delete_job == NULL)
-       {
-               this->logger->log(this->logger, ERROR, "Job to delete IKE SA could not be created");
-               return FAILED;
-       }
-       
-       status = global_job_queue->add(global_job_queue,delete_job);
-       if (status != SUCCESS)
-       {
-               this->logger->log(this->logger, ERROR, "%s Job to delete IKE SA could not be added to job queue",mapping_find(status_m,status));
-               delete_job->destroy_all(delete_job);
-               return status;
-       }
-       return SUCCESS;
-}
-
-/**
- * @brief implements function destroy of protected_ike_sa_t
- */
-static status_t destroy (protected_ike_sa_t *this)
-{
-       
-       this->logger->log(this->logger, CONTROL | MORE, "Going to destroy IKE_SA");
-
-       /* destroy child sa's */
-       this->logger->log(this->logger, CONTROL | MOST, "Destroy all child_sa's");
-       while (this->child_sas->get_count(this->child_sas) > 0)
-       {
-               void *child_sa;
-               if (this->child_sas->remove_first(this->child_sas,&child_sa) != SUCCESS)
-               {
-                       break;
-               }
-               /* destroy child sa */
-       }
-       this->child_sas->destroy(this->child_sas);
-
-       this->logger->log(this->logger, CONTROL | MOST, "Destroy secrets");
-       if (this->secrets.d_key.ptr != NULL)
-       {
-               allocator_free(this->secrets.d_key.ptr);
-       }
-       if (this->secrets.ai_key.ptr != NULL)
-       {
-               allocator_free(this->secrets.ai_key.ptr);
-       }
-       if (this->secrets.ar_key.ptr != NULL)
-       {
-               allocator_free(this->secrets.ar_key.ptr);
-       }
-       if (this->secrets.ei_key.ptr != NULL)
-       {
-               allocator_free(this->secrets.ei_key.ptr);
-       }
-       if (this->secrets.er_key.ptr != NULL)
-       {
-               allocator_free(this->secrets.er_key.ptr);
-       }
-       if (this->secrets.pi_key.ptr != NULL)
-       {
-               allocator_free(this->secrets.pi_key.ptr);
-       }
-       if (this->secrets.pr_key.ptr != NULL)
-       {
-               allocator_free(this->secrets.pr_key.ptr);
-       }
-       
-       if (    this->crypter_initiator != NULL)
-       {
-               this->logger->log(this->logger, CONTROL | MOST, "Destroy initiator crypter");
-               this->crypter_initiator->destroy(this->crypter_initiator);
-       }
-       
-       if (    this->crypter_responder != NULL)
-       {
-               this->logger->log(this->logger, CONTROL | MOST, "Destroy responder crypter");
-               this->crypter_responder->destroy(this->crypter_responder);
-       }
-       
-       if (    this->signer_initiator != NULL)
-       {
-               this->logger->log(this->logger, CONTROL | MOST, "Destroy initiator signer");
-               this->signer_initiator->destroy(this->signer_initiator);
-       }
-
-       if (this->signer_responder != NULL)
-       {
-               this->logger->log(this->logger, CONTROL | MOST, "Destroy responder signer");
-               this->signer_responder->destroy(this->signer_responder);
-       }
-       
-       if (this->prf != NULL)
-       {
-               this->logger->log(this->logger, CONTROL | MOST, "Destroy prf");
-               this->prf->destroy(this->prf);
-       }
-       
-       /* destroy ike_sa_id */
-       this->logger->log(this->logger, CONTROL | MOST, "Destroy assigned ike_sa_id");
-       this->ike_sa_id->destroy(this->ike_sa_id);
-
-       /* destroy stored requested message */
-       if (this->last_requested_message != NULL)
-       {
-               this->logger->log(this->logger, CONTROL | MOST, "Destroy last requested message");
-               this->last_requested_message->destroy(this->last_requested_message);
-       }
-       
-       /* destroy stored responded messages */
-       if (this->last_responded_message != NULL)
-       {
-               this->logger->log(this->logger, CONTROL | MOST, "Destroy last responded message");
-               this->last_responded_message->destroy(this->last_responded_message);
-       }
-       
-       this->logger->log(this->logger, CONTROL | MOST, "Destroy randomizer");
-       this->randomizer->destroy(this->randomizer);
-
-       if (this->me.host != NULL)
-       {
-               this->logger->log(this->logger, CONTROL | MOST, "Destroy host informations of me");
-               this->me.host->destroy(this->me.host);
-       }
-       
-       if (this->other.host != NULL)
-       {
-               this->logger->log(this->logger, CONTROL | MOST, "Destroy host informations of other");
-               this->other.host->destroy(this->other.host);
-       }
-       
-       this->logger->log(this->logger, CONTROL | MOST, "Destroy current state object");
-       this->current_state->destroy(this->current_state);
-       
-       this->logger->log(this->logger, CONTROL | MOST, "Destroy logger of IKE_SA");
-       
-       global_logger_manager->destroy_logger(global_logger_manager, this->logger);
-
-       allocator_free(this);
-       return SUCCESS;
-}
-
-/*
- * Described in Header
- */
-ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
-{
-       protected_ike_sa_t *this = allocator_alloc_thing(protected_ike_sa_t);
-       if (this == NULL)
-       {
-               return NULL;
-       }
-
-       /* Public functions */
-       this->public.process_message = (status_t(*)(ike_sa_t*, message_t*)) process_message;
-       this->public.initialize_connection = (status_t(*)(ike_sa_t*, char*)) initialize_connection;
-       this->public.get_id = (ike_sa_id_t*(*)(ike_sa_t*)) get_id;
-       this->public.destroy = (status_t(*)(ike_sa_t*))destroy;
-       
-       /* private functions */
-       this->build_message = build_message;
-       this->resend_last_reply = resend_last_reply;
-       this->create_delete_job = create_delete_job;
-       this->compute_secrets = compute_secrets;
-
-       /* initialize private fields */
-       this->logger = global_logger_manager->create_logger(global_logger_manager, IKE_SA, NULL);
-       if (this->logger ==  NULL)
-       {
-               allocator_free(this);
-       }
-       
-       if (ike_sa_id->clone(ike_sa_id,&(this->ike_sa_id)) != SUCCESS)
-       {
-               this->logger->log(this->logger, ERROR, "Fatal error: Could not clone ike_sa_id");
-               global_logger_manager->destroy_logger(global_logger_manager,this->logger);
-               allocator_free(this);
-               return NULL;
-       }
-       this->child_sas = linked_list_create();
-       if (this->child_sas == NULL)
-       {
-               this->logger->log(this->logger, ERROR, "Fatal error: Could not create list for child_sa's");
-               this->ike_sa_id->destroy(this->ike_sa_id);
-               global_logger_manager->destroy_logger(global_logger_manager,this->logger);
-               allocator_free(this);
-               return NULL;
-       }
-       this->randomizer = randomizer_create();
-       if (this->randomizer == NULL)
-       {
-               this->logger->log(this->logger, ERROR, "Fatal error: Could not create list for child_sa's");
-               this->child_sas->destroy(this->child_sas);
-               this->ike_sa_id->destroy(this->ike_sa_id);
-               global_logger_manager->destroy_logger(global_logger_manager,this->logger);
-               allocator_free(this);
-       }
-       
-       this->me.host = NULL;
-       this->other.host = NULL;
-       this->last_requested_message = NULL;
-       this->last_responded_message = NULL;
-       this->message_id_out = 0;
-       this->message_id_in = 0;
-       this->secrets.d_key.ptr = NULL;
-       this->secrets.d_key.len = 0;
-       this->secrets.ai_key.ptr = NULL;
-       this->secrets.ai_key.len = 0;
-       this->secrets.ar_key.ptr = NULL;
-       this->secrets.ar_key.len = 0;
-       this->secrets.ei_key.ptr = NULL;        
-       this->secrets.ei_key.len = 0;
-       this->secrets.er_key.ptr = NULL;
-       this->secrets.er_key.len = 0;
-       this->secrets.pi_key.ptr = NULL;
-       this->secrets.pi_key.len = 0;
-       this->secrets.pr_key.ptr = NULL;
-       this->secrets.pr_key.len = 0;
-       this->crypter_initiator = NULL;
-       this->crypter_responder = NULL;
-       this->signer_initiator = NULL;
-       this->signer_responder = NULL;
-       this->prf = NULL;
-       
-
-
-
-       /* at creation time, IKE_SA is in a initiator state */
-       if (ike_sa_id->is_initiator(ike_sa_id))
-       {
-               this->current_state = (state_t *) initiator_init_create(this);
-       }
-       else
-       {
-               this->current_state = (state_t *) responder_init_create(this);
-       }
-       
-       if (this->current_state == NULL)
-       {
-               this->logger->log(this->logger, ERROR, "Fatal error: Could not create state object");
-               this->child_sas->destroy(this->child_sas);
-               this->ike_sa_id->destroy(this->ike_sa_id);
-               global_logger_manager->destroy_logger(global_logger_manager,this->logger);
-               this->randomizer->destroy(this->randomizer);
-               allocator_free(this);
-       }
-
-
-       return &(this->public);
-}
diff --git a/Source/charon/ike_sa.h b/Source/charon/ike_sa.h
deleted file mode 100644 (file)
index 5faddc4..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-/**
- * @file ike_sa.h
- *
- * @brief Class ike_sa_t. An object of this type is managed by an
- * ike_sa_manager_t object and represents an IKE_SA
- *
- */
-
-/*
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef IKE_SA_H_
-#define IKE_SA_H_
-
-#include <types.h>
-#include <encoding/message.h>
-#include <ike_sa_id.h>
-#include <utils/logger.h>
-#include <utils/randomizer.h>
-#include <states/state.h>
-#include <transforms/prfs/prf.h>
-#include <transforms/crypters/crypter.h>
-#include <transforms/signers/signer.h>
-
-
-
-/**
- * Nonce size in bytes of all sent nonces
- */
-#define NONCE_SIZE 16
-
-/**
- * @brief This class is used to represent an IKE_SA
- *
- */
-typedef struct ike_sa_s ike_sa_t;
-
-struct ike_sa_s {
-
-       /**
-        * @brief Processes a incoming IKEv2-Message of type message_t
-        *
-        * @param this ike_sa_t object object
-        * @param[in] message message_t object to process
-        * @return SUCCESSFUL if succeeded, FAILED otherwise
-        */
-       status_t (*process_message) (ike_sa_t *this,message_t *message);
-
-       /**
-        * Initiate a new connection with given configuration name
-        * 
-        * @param this                  calling object
-        * @param name                  name of the configuration
-        * @return                              TODO
-        */
-       status_t (*initialize_connection) (ike_sa_t *this, char *name);
-
-       /**
-        * @brief Get the id of the SA
-        *
-        * @param this ike_sa_t-message_t object object
-        * @return ike_sa's ike_sa_id_t
-        */
-       ike_sa_id_t* (*get_id) (ike_sa_t *this);
-
-       /**
-        * @brief Destroys a ike_sa_t object
-        *
-        * @param this ike_sa_t object
-        * @return SUCCESSFUL if succeeded, FAILED otherwise
-        */
-       status_t (*destroy) (ike_sa_t *this);
-};
-
-/**
- * Protected data of an ike_sa_t object
- */
-typedef struct protected_ike_sa_s protected_ike_sa_t;
-
-struct protected_ike_sa_s {
-
-       /**
-        * Public part of a ike_sa_t object
-        */
-       ike_sa_t public;
-       
-       /**
-        * Builds an empty IKEv2-Message and fills in default informations.
-        * 
-        * Depending on the type of message (request or response), the message id is 
-        * either message_id_out or message_id_in.
-        * 
-        * Used in every state.
-        * 
-        * @param this          calling object
-        * @param type          exchange type of new message
-        * @param request       TRUE, if message has to be a request
-        * @param message       new message is stored at this location
-        * @return                      
-        *                                      - SUCCESS
-        *                                      - OUT_OF_RES
-        */
-       status_t (*build_message) (protected_ike_sa_t *this, exchange_type_t type, bool request, message_t **message);
-
-       /**
-        * Initiate a new connection with given configuration name
-        * 
-        * @param this                          calling object
-        * @param dh_shared_secret      shared secret of diffie hellman exchange
-        * @param initiator_nonce       nonce of initiator
-        * @param responder_nonce       nonce of responder
-        * @return                                      TODO
-        */
-       status_t (*compute_secrets) (protected_ike_sa_t *this,chunk_t dh_shared_secret,chunk_t initiator_nonce, chunk_t responder_nonce);
-
-       /**
-        * Creates a job to delete the given IKE_SA
-        */
-       status_t (*create_delete_job) (protected_ike_sa_t *this);
-
-       /**
-        * Resends the last sent reply
-        */
-       status_t (*resend_last_reply) (protected_ike_sa_t *this);
-       
-       
-       /* protected values */
-       
-       /**
-        * Identifier for the current IKE_SA
-        */
-       ike_sa_id_t *ike_sa_id;
-
-       /**
-        * Linked List containing the child sa's of the current IKE_SA
-        */
-       linked_list_t *child_sas;
-
-       /**
-        * Current state of the IKE_SA
-        */
-       state_t *current_state;
-       
-       /**
-        * this SA's source for random data
-        */
-       randomizer_t *randomizer;
-       
-       /**
-        * contains the last responded message
-        * 
-        */
-       message_t *last_responded_message;
-
-       /**
-        * contains the last requested message
-        * 
-        */
-       message_t *last_requested_message;
-       
-       /**
-        * Informations of this host
-        */
-       struct {
-               host_t *host;
-       } me;
-
-       /**
-        * Informations of the other host
-        */     
-       struct {
-               host_t *host;
-       } other;
-       
-       /**
-        * Crypter object for initiator
-        */
-       crypter_t *crypter_initiator;
-       
-       /**
-        * Crypter object for responder
-        */
-       crypter_t *crypter_responder;
-       
-       /**
-        * Signer object for initiator
-        */
-       signer_t *signer_initiator;
-       
-       /**
-        * Signer object for responder
-        */
-       signer_t *signer_responder;
-       
-       /**
-        * prf function
-        */
-       prf_t *prf;
-       
-       
-       
-       /**
-        * Shared secrets
-        */
-       struct {
-               /**
-                * Key used for deriving other keys
-                */
-               chunk_t d_key;
-               
-               /**
-                * Key for authenticate (initiator)
-                */
-               chunk_t ai_key;
-               
-               /**
-                * Key for authenticate (responder)
-                */
-               chunk_t ar_key;
-
-               /**
-                * Key for encryption (initiator)
-                */
-               chunk_t ei_key; 
-
-               /**
-                * Key for encryption (responder)
-                */
-               chunk_t er_key; 
-
-               /**
-                * Key for generating auth payload (initiator)
-                */
-               chunk_t pi_key; 
-
-               /**
-                * Key for generating auth payload (responder)
-                */
-               chunk_t pr_key; 
-
-       } secrets;
-
-       /**
-        * next message id to receive
-        */
-       u_int32_t message_id_in;
-       
-       /**
-        * next message id to send
-        */
-       u_int32_t message_id_out;
-       
-       /**
-        * a logger for this IKE_SA
-        */
-       logger_t *logger;
-};
-
-
-
-/**
- * Creates an ike_sa_t object with a specific ike_sa_id_t object
- *
- * @param[in] ike_sa_id ike_sa_id_t object to associate with new IKE_SA.
- *                                             The object is internal getting cloned
- *                                             and so has to be destroyed by the caller.
- *
- * @warning the Content of internal ike_sa_id_t object can change over time
- *                     e.g. when a IKE_SA_INIT has been finished
- *
- * @return created ike_sa_t object
- */
-ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id);
-
-#endif /*IKE_SA_H_*/
diff --git a/Source/charon/ike_sa_id.c b/Source/charon/ike_sa_id.c
deleted file mode 100644 (file)
index 52b1a9c..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-/**
- * @file ike_sa_id.c
- *
- * @brief Class for identification of an IKE_SA
- *
- */
-
-/*
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "ike_sa_id.h"
-
-#include <types.h>
-#include <utils/allocator.h>
-
-/**
- * Private data of an ike_sa_id object
- */
-typedef struct private_ike_sa_id_s private_ike_sa_id_t;
-
-struct private_ike_sa_id_s {
-       /**
-        * Public part of a ike_sa_id object
-        */
-       ike_sa_id_t public;
-
-
-       /* Private values */
-
-        /**
-         * SPI of Initiator
-         */
-       u_int64_t initiator_spi;
-
-        /**
-         * SPI of Responder
-         */
-       u_int64_t responder_spi;
-
-       /**
-        * Role for specific IKE_SA
-        */
-       bool is_initiator_flag;
-
-};
-
-
-/**
- * @brief implements function set_responder_spi of ike_sa_id_t
- */
-static status_t set_responder_spi (private_ike_sa_id_t *this, u_int64_t responder_spi)
-{
-       this->responder_spi = responder_spi;
-       return SUCCESS;
-}
-
-static status_t set_initiator_spi(private_ike_sa_id_t *this, u_int64_t initiator_spi)
-{
-       this->initiator_spi = initiator_spi;
-       return SUCCESS;
-}
-
-/**
- * @brief implements ike_sa_id_t.get_initiator_spi
- */
-static u_int64_t get_initiator_spi (private_ike_sa_id_t *this)
-{
-       return this->initiator_spi;
-}
-
-/**
- * @brief implements ike_sa_id_t.get_responder_spi
- */
-static u_int64_t get_responder_spi (private_ike_sa_id_t *this)
-{
-       return this->responder_spi;
-}
-
-/**
- * @brief implements function equals of ike_sa_id_t
- */
-static status_t equals (private_ike_sa_id_t *this,private_ike_sa_id_t *other, bool *are_equal)
-{
-       if ((this == NULL)||(other == NULL))
-       {
-               return FAILED;
-       }
-       if ((this->is_initiator_flag == other->is_initiator_flag) &&
-               (this->initiator_spi == other->initiator_spi) &&
-               (this->responder_spi == other->responder_spi))
-
-       {
-               /* private_ike_sa_id's are equal */
-               *are_equal = TRUE;
-       }
-       else
-       {
-               /* private_ike_sa_id's are not equal */
-               *are_equal = FALSE;
-       }
-
-       return SUCCESS;
-}
-
-/**
- * @brief implements function replace_values of ike_sa_id_t
- */
-status_t replace_values (private_ike_sa_id_t *this, private_ike_sa_id_t *other)
-{
-       if ((this == NULL) || (other == NULL))
-       {
-               return FAILED;
-       }
-
-       this->initiator_spi = other->initiator_spi;
-       this->responder_spi = other->responder_spi;
-       this->is_initiator_flag = other->is_initiator_flag;
-
-       return SUCCESS;
-}
-
-
-/**
- * @brief implements ike_sa_id_t.is_initiator
- */
-static bool is_initiator(private_ike_sa_id_t *this)
-{
-       return this->is_initiator_flag;
-}
-
-/**
- * @brief implements ike_sa_id_t.switch_initiator
- */
-static bool switch_initiator(private_ike_sa_id_t *this)
-{
-       if (this->is_initiator_flag)
-       {
-               this->is_initiator_flag = FALSE;
-       }
-       else
-       {
-               this->is_initiator_flag = TRUE; 
-       }
-       return this->is_initiator_flag;
-}
-
-
-/**
- * @brief implements function clone of ike_sa_id_t
- */
-static status_t clone (private_ike_sa_id_t *this, ike_sa_id_t **clone_of_this)
-{
-       *clone_of_this = ike_sa_id_create(this->initiator_spi, this->responder_spi, this->is_initiator_flag);
-
-       return (*clone_of_this == NULL) ? OUT_OF_RES : SUCCESS;
-}
-
-/**
- * @brief implements function destroy of ike_sa_id_t
- */
-static status_t destroy (private_ike_sa_id_t *this)
-{
-       allocator_free(this);
-       return SUCCESS;
-}
-
-/*
- * Described in Header-File
- */
-ike_sa_id_t * ike_sa_id_create(u_int64_t initiator_spi, u_int64_t responder_spi, bool is_initiator_flag)
-{
-       private_ike_sa_id_t *this = allocator_alloc_thing(private_ike_sa_id_t);
-       if (this == NULL)
-       {
-               return NULL;
-       }
-
-       /* Public functions */
-       this->public.set_responder_spi = (status_t(*)(ike_sa_id_t*,u_int64_t)) set_responder_spi;
-       this->public.set_initiator_spi = (status_t(*)(ike_sa_id_t*,u_int64_t)) set_initiator_spi;
-       this->public.get_responder_spi = (u_int64_t(*)(ike_sa_id_t*)) get_responder_spi;
-       this->public.get_initiator_spi = (u_int64_t(*)(ike_sa_id_t*)) get_initiator_spi;
-       this->public.equals = (status_t(*)(ike_sa_id_t*,ike_sa_id_t*,bool*)) equals;
-       this->public.replace_values = (status_t(*)(ike_sa_id_t*,ike_sa_id_t*)) replace_values;
-
-       this->public.is_initiator = (bool(*)(ike_sa_id_t*)) is_initiator;
-       this->public.switch_initiator = (bool(*)(ike_sa_id_t*)) switch_initiator;
-
-       this->public.clone = (status_t(*)(ike_sa_id_t*,ike_sa_id_t**)) clone;
-       this->public.destroy = (status_t(*)(ike_sa_id_t*))destroy;
-
-       /* private data */
-       this->initiator_spi = initiator_spi;
-       this->responder_spi = responder_spi;
-       this->is_initiator_flag = is_initiator_flag;
-
-       return (&this->public);
-}
diff --git a/Source/charon/ike_sa_id.h b/Source/charon/ike_sa_id.h
deleted file mode 100644 (file)
index f7e0e65..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/**
- * @file ike_sa_id.h
- *
- * @brief Class for identification of an IKE_SA
- *
- */
-
-/*
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-
-#ifndef IKE_SA_ID_H_
-#define IKE_SA_ID_H_
-
-#include "types.h"
-
-/**
- * @brief This class is used to identify an IKE_SA.
- *
- * An IKE_SA is identified by its initiator and responder spi's.
- * Additionaly it contains the role of the actual running IKEv2-Daemon
- * for the specific IKE_SA.
- */
-typedef struct ike_sa_id_s ike_sa_id_t;
-
-struct ike_sa_id_s {
-
-       /**
-        * @brief Sets the SPI of the responder.
-        *
-        * This function is called when a request or reply of a IKE_SA_INIT is received.
-        *
-        * @param this ike_sa_id_t object
-        * @param responder_spi SPI of responder to set
-        * @return SUCCESSFUL in any case
-        */
-       status_t (*set_responder_spi) (ike_sa_id_t *this, u_int64_t responder_spi);
-
-       /**
-        * @brief Sets the SPI of the initiator.
-        *
-        *
-        * @param this ike_sa_id_t object
-        * @param initiator_spi SPI to set
-        * @return SUCCESSFUL in any case
-        */
-       status_t (*set_initiator_spi) (ike_sa_id_t *this, u_int64_t initiator_spi);
-
-       /**
-        * @brief Returns the initiator spi
-        *
-        * @param this ike_sa_id_t object
-        * @return spi of the initiator
-        */
-       u_int64_t (*get_initiator_spi) (ike_sa_id_t *this);
-
-       /**
-        * @brief Returns the responder spi
-        *
-        * @param this ike_sa_id_t object
-        * @return spi of the responder
-        */
-       u_int64_t (*get_responder_spi) (ike_sa_id_t *this);
-
-       /**
-        * @brief Check if two ike_sa_ids are equal
-        *
-        * @param this ike_sa_id_t object
-        * @param other ike_sa_id object to check if equal
-        * @param are_equal is set to TRUE, if given ike_sa_ids are equal, FALSE otherwise
-        * @return SUCCESSFUL if succeeded, FAILED otherwise
-        */
-       status_t (*equals) (ike_sa_id_t *this,ike_sa_id_t *other, bool *are_equal);
-
-       /**
-        * @brief Replace the values of a given ike_sa_id_t object with values
-        * from another ike_sa_id_t object
-        *
-        * @param this ike_sa_id_t object
-        * @param other ike_sa_id_t object which values will be taken
-        * @return SUCCESSFUL if succeeded, FAILED otherwise
-        */
-       status_t (*replace_values) (ike_sa_id_t *this, ike_sa_id_t *other);
-
-       /**
-        * @brief gets the initiator flag
-        *
-        * @param this ike_sa_id_t object
-        * @return TRUE if we are the original initator
-        */
-       bool (*is_initiator) (ike_sa_id_t *this);
-
-       /**
-        * @brief switches the initiator flag
-        * 
-        * @param this ike_sa_id_t object
-        * @return TRUE if we are the original initator after switch
-        */
-       bool (*switch_initiator) (ike_sa_id_t *this);
-
-       /**
-        * @brief Clones a given ike_sa_id_t object
-        *
-        * @param this ike_sa_id_t object
-        * @param clone_of_this ike_sa_id_t object which will be created
-        * @return SUCCESSFUL if succeeded, FAILED otherwise
-        */
-       status_t (*clone) (ike_sa_id_t *this,ike_sa_id_t **clone_of_this);
-
-       /**
-        * @brief Destroys a ike_sa_id_tobject
-        *
-        * @param this ike_sa_id_t object
-        * @return SUCCESSFUL if succeeded, FAILED otherwise
-        */
-       status_t (*destroy) (ike_sa_id_t *this);
-};
-
-/**
- * Creates an ike_sa_id_t object with specific spi's and defined role
- *
- * @warning The initiator SPI and role is not changeable after initiating a ike_sa_id object
- */
-
-ike_sa_id_t * ike_sa_id_create(u_int64_t initiator_spi, u_int64_t responder_spi, bool is_initiaor);
-
-#endif /*IKE_SA_ID_H_*/
diff --git a/Source/charon/ike_sa_manager.c b/Source/charon/ike_sa_manager.c
deleted file mode 100644 (file)
index ed60e6d..0000000
+++ /dev/null
@@ -1,790 +0,0 @@
-/**
- * @file ike_sa_manager.c
- *
- * @brief Central point for managing IKE-SAs (creation, locking, deleting...)
- *
- */
-
-/*
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <pthread.h>
-#include <string.h>
-
-#include "ike_sa_manager.h"
-
-#include <globals.h>
-#include <ike_sa_id.h>
-#include <utils/allocator.h>
-#include <utils/logger.h>
-#include <utils/logger_manager.h>
-#include <utils/linked_list.h>
-
-/**
- * @brief An entry in the linked list, contains IKE_SA, locking and lookup data.
- */
-typedef struct ike_sa_entry_s ike_sa_entry_t;
-struct ike_sa_entry_s {
-       /**
-        * destructor, also destroys ike_sa
-        */
-       status_t (*destroy) (ike_sa_entry_t *this);
-       /**
-        * Number of threads waiting for this ike_sa
-        */
-       int waiting_threads;
-       /**
-        * condvar where threads can wait until it's free again
-        */
-       pthread_cond_t condvar;
-       /**
-        * is this ike_sa currently checked out?
-        */
-       bool checked_out;
-       /**
-        * Does this SA drives out new threads?
-        */
-       bool driveout_new_threads;
-       /**
-        * Does this SA drives out waiting threads?
-        */
-       bool driveout_waiting_threads;
-       /**
-        * identifiaction of ike_sa (SPIs)
-        */
-       ike_sa_id_t *ike_sa_id;
-       /**
-        * the contained ike_sa
-        */
-       ike_sa_t *ike_sa;
-};
-
-/**
- * @see ike_sa_entry_t.destroy
- */
-static status_t ike_sa_entry_destroy(ike_sa_entry_t *this)
-{
-       /* also destroy IKE SA */
-       this->ike_sa->destroy(this->ike_sa);
-       this->ike_sa_id->destroy(this->ike_sa_id);
-       allocator_free(this);
-       return SUCCESS;
-}
-
-/**
- * @brief creates a new entry for the ike_sa list
- *
- * This constructor additionaly creates a new and empty SA
- *
- * @param ike_sa_id            the associated ike_sa_id_t, will be cloned
- * @return                             created entry, with ike_sa and ike_sa_id
- */
-static ike_sa_entry_t *ike_sa_entry_create(ike_sa_id_t *ike_sa_id)
-{
-       ike_sa_entry_t *this = allocator_alloc_thing(ike_sa_entry_t);
-
-       if (this == NULL)
-       {
-               return NULL;
-       }
-
-       /* destroy function */
-       this->destroy = ike_sa_entry_destroy;
-       
-       this->waiting_threads = 0;
-       pthread_cond_init(&(this->condvar), NULL);
-       
-       /* we set checkout flag when we really give it out */
-       this->checked_out = FALSE;
-       this->driveout_new_threads = FALSE;
-       this->driveout_waiting_threads = FALSE;
-       
-       /* ike_sa_id is always cloned */
-       ike_sa_id->clone(ike_sa_id, &(this->ike_sa_id));
-       if (this->ike_sa_id == NULL)
-       {
-               allocator_free(this);   
-               return NULL;
-       }
-       
-       /* create new ike_sa */
-       this->ike_sa = ike_sa_create(ike_sa_id);
-       if (this->ike_sa == NULL)
-       {
-               this->ike_sa_id->destroy(this->ike_sa_id);
-               allocator_free(this);   
-               return NULL;
-               
-       }
-       return this;
-}
-
-/**
- * Additional private members to ike_sa_manager_t
- */
-typedef struct private_ike_sa_manager_s private_ike_sa_manager_t;
-struct private_ike_sa_manager_s {
-       /**
-        * Public members
-        */
-        ike_sa_manager_t public;
-
-       /**
-        * @brief get next spi
-        *
-        * we give out SPIs incremental
-        *
-        * @param this                  the ike_sa_manager
-        * @param spi[out]              spi will be written here
-        * @return                              SUCCESS or,
-        *                                              OUT_OF_RES when we already served 2^64 SPIs ;-)
-        */
-        status_t (*get_next_spi) (private_ike_sa_manager_t *this, u_int64_t *spi);
-
-       /**
-        * @brief find the ike_sa_entry in the list by SPIs
-        *
-        * This function simply iterates over the linked list. A hash-table
-        * would be more efficient when storing a lot of IKE_SAs...
-        *
-        * @param this                  the ike_sa_manager containing the list
-        * @param ike_sa_id             id of the ike_sa, containing SPIs
-        * @param entry[out]    pointer to set to the found entry
-        * @return                              
-        *                                              - SUCCESS when found,
-        *                                              - NOT_FOUND when no such ike_sa_id in list
-        *                                              - OUT_OF_RES
-        */
-        status_t (*get_entry_by_id) (private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id, ike_sa_entry_t **entry);
-
-        /**
-        * @brief find the ike_sa_entry in the list by pointer to SA.
-        *
-        * This function simply iterates over the linked list. A hash-table
-        * would be more efficient when storing a lot of IKE_SAs...
-        *
-        * @param this                  the ike_sa_manager containing the list
-        * @param ike_sa                        pointer to the ike_sa
-        * @param entry[out]            pointer to set to the found entry
-        * @return                              
-        *                                              - SUCCESS when found,
-        *                                              - NOT_FOUND when no such ike_sa_id in list
-        *                                              - OUT_OF_RES
-        */
-        status_t (*get_entry_by_sa) (private_ike_sa_manager_t *this, ike_sa_t *ike_sa, ike_sa_entry_t **entry);
-        
-        /**
-         * @brief delete an entry from the linked list
-         *
-         * @param this         the ike_sa_manager containing the list
-         * @param entry                entry to delete
-         * @return                             
-         *                                     - SUCCESS when found,
-         *                                     - NOT_FOUND when no such ike_sa_id in list
-         */
-        status_t (*delete_entry) (private_ike_sa_manager_t *this, ike_sa_entry_t *entry);
-
-        /**
-         * lock for exclusivly accessing the manager
-         */
-        pthread_mutex_t mutex;
-
-        /**
-         * Logger used for this IKE SA Manager
-         */
-        logger_t *logger;
-
-        /**
-         * Linked list with entries for the ike_sa
-         */
-        linked_list_t *ike_sa_list;
-        
-        /**
-         * Next SPI, needed for incremental creation of SPIs
-         */
-        u_int64_t next_spi;
-};
-
-
-/**
- * @see private_ike_sa_manager_t.get_entry_by_id
- */
-static status_t get_entry_by_id(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id, ike_sa_entry_t **entry)
-{
-       linked_list_t *list = this->ike_sa_list;
-       linked_list_iterator_t *iterator;
-       status_t status;
-       
-       /* create iterator over list of ike_sa's */
-       status = list->create_iterator(list, &iterator, TRUE);
-       if (status != SUCCESS)
-       {
-               this->logger->log(this->logger,ERROR,"Fatal Error: could not create iterator: %s",mapping_find(status_m,status));
-               /* out of res */
-               return status;
-       }
-       
-       /* default status */
-       status = NOT_FOUND;
-       
-       
-       while (iterator->has_next(iterator))
-       {
-               ike_sa_entry_t *current;
-               bool are_equal = FALSE;
-               
-               iterator->current(iterator, (void**)&current);
-               if (current->ike_sa_id->get_responder_spi(current->ike_sa_id) == 0) {
-                       /* seems to be a half ready ike_sa */
-                       if ((current->ike_sa_id->get_initiator_spi(current->ike_sa_id) == ike_sa_id->get_initiator_spi(ike_sa_id))
-                               && (ike_sa_id->is_initiator(ike_sa_id) == current->ike_sa_id->is_initiator(current->ike_sa_id)))
-                       {
-                               this->logger->log(this->logger,CONTROL | MOST,"Found entry by initiator spi %d",ike_sa_id->get_initiator_spi(ike_sa_id));
-                               *entry = current;
-                               status = SUCCESS;
-                               break;
-                       }
-               }
-               current->ike_sa_id->equals(current->ike_sa_id, ike_sa_id, &are_equal);
-               if (are_equal)
-               {
-                       this->logger->log(this->logger,CONTROL | MOST,"Found entry by full ID");
-                       *entry = current;
-                       status = SUCCESS;
-                       break;
-               }
-       }
-       
-       iterator->destroy(iterator);
-       return status;
-}
-
-/**
- * @see private_ike_sa_manager_t.get_entry_by_sa
- */
-static status_t get_entry_by_sa(private_ike_sa_manager_t *this, ike_sa_t *ike_sa, ike_sa_entry_t **entry)
-{
-       linked_list_t *list = this->ike_sa_list;
-       linked_list_iterator_t *iterator;
-       status_t status;
-       
-       status = list->create_iterator(list, &iterator, TRUE);
-       if (status != SUCCESS)
-       {
-               this->logger->log(this->logger,ERROR,"Fatal Error: could not create iterator: %s",mapping_find(status_m,status));
-               return status;
-       }
-       
-       /* default status */
-       status = NOT_FOUND;
-       
-       while (iterator->has_next(iterator))
-       {
-               ike_sa_entry_t *current;
-               iterator->current(iterator, (void**)&current);
-               /* only pointers are compared */
-               if (current->ike_sa == ike_sa)
-               {
-                       this->logger->log(this->logger,CONTROL | MOST,"Found entry by pointer");
-                       *entry = current;
-                       status = SUCCESS;
-                       break;
-               }
-       }
-       iterator->destroy(iterator);
-       return status;
-}
-
-/**
- * @see private_ike_sa_manager_s.delete_entry
- */
-static status_t delete_entry(private_ike_sa_manager_t *this, ike_sa_entry_t *entry)
-{
-       linked_list_t *list = this->ike_sa_list;
-       linked_list_iterator_t *iterator;
-       status_t status;
-       
-       status = list->create_iterator(list, &iterator, TRUE);
-       
-       if (status != SUCCESS)
-       {
-               this->logger->log(this->logger,ERROR,"Fatal Error: could not create iterator: %s",mapping_find(status_m,status));
-               return status;
-       }
-
-       status = NOT_FOUND;     
-       
-       while (iterator->has_next(iterator))
-       {
-               ike_sa_entry_t *current;
-               iterator->current(iterator, (void**)&current);
-               if (current == entry) 
-               {
-                       this->logger->log(this->logger,CONTROL | MOST,"Found entry by pointer. Going to delete it.");
-                       list->remove(list, iterator);
-                       entry->destroy(entry);
-                       status = SUCCESS;
-                       break;
-               }
-       }
-       iterator->destroy(iterator);
-       return status;  
-}
-
-
-/**
- * @see private_ike_sa_manager_t.get_next_spi
- */
-static status_t get_next_spi(private_ike_sa_manager_t *this, u_int64_t *spi)
-{
-       this->next_spi++;
-       if (this->next_spi == 0) {
-               /* our software ran so incredible stable, we have no more
-                * SPIs to give away :-/.  */
-               this->logger->log(this->logger,CONTROL | MOST,"No more SPI values available. WOW!");
-               return OUT_OF_RES;
-       }
-       *spi = this->next_spi;
-       return SUCCESS;
-}
-
-/**
- * @see ike_sa_manager_s.checkout_ike_sa
- */
-static status_t checkout(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id, ike_sa_t **ike_sa)
-{
-       bool responder_spi_set;
-       bool initiator_spi_set;
-       status_t retval;
-
-       /* each access is locked */
-       pthread_mutex_lock(&(this->mutex));
-
-       responder_spi_set = (FALSE != ike_sa_id->get_responder_spi(ike_sa_id));
-       initiator_spi_set = (FALSE != ike_sa_id->get_initiator_spi(ike_sa_id));
-
-       if (initiator_spi_set && responder_spi_set)
-       {
-               /* we SHOULD have an IKE_SA for these SPIs in the list,
-                * if not, we can't handle the request...
-                */
-                ike_sa_entry_t *entry;
-                /* look for the entry */
-                if (this->get_entry_by_id(this, ike_sa_id, &entry) == SUCCESS)
-                {
-                       /* can we give this ike_sa out to new requesters?*/
-                       if (entry->driveout_new_threads)
-                       {
-                               this->logger->log(this->logger,CONTROL|MORE,"Drive out new thread for existing IKE_SA");
-                               /* no we can't */
-                               retval = NOT_FOUND;
-                       }
-                       else
-                       {
-                               /* is this IKE_SA already checked out ?? 
-                                * are we welcome to get this SA ? */
-                               while (entry->checked_out && !entry->driveout_waiting_threads)  
-                               { 
-                                       /* so wait until we can get it for us.
-                                        * we register us as waiting.
-                                        */
-                                       entry->waiting_threads++;
-                                       pthread_cond_wait(&(entry->condvar), &(this->mutex));
-                                       entry->waiting_threads--;
-                               }
-                               
-                               /* hm, a deletion request forbids us to get this SA, go home */
-                               if (entry->driveout_waiting_threads)
-                               {
-                                       /* we must signal here, others are interested that we leave */
-                                       pthread_cond_signal(&(entry->condvar));
-                                       this->logger->log(this->logger,CONTROL|MORE,"Drive out waiting thread for existing IKE_SA");
-                                       retval = NOT_FOUND;
-                               }
-                               else
-                               {
-                                       this->logger->log(this->logger,CONTROL|MOST,"IKE SA successfully checked out");
-                                       /* ok, this IKE_SA is finally ours */
-                                       entry->checked_out = TRUE;
-                                       *ike_sa = entry->ike_sa;
-                                       /* DON'T use return, we must unlock the mutex! */
-                                       retval = SUCCESS; 
-                               }
-                       }
-                }
-                else
-                {
-                       this->logger->log(this->logger,ERROR | MORE,"IKE SA not stored in known IKE_SA list");
-                       /* looks like there is no such IKE_SA, better luck next time... */
-                       /* DON'T use return, we must unlock the mutex! */
-                       retval = NOT_FOUND;
-                }
-       }
-       else if (initiator_spi_set && !responder_spi_set)
-       {
-               /* an IKE_SA_INIT from an another endpoint,
-                * he is the initiator.
-                * For simplicity, we do NOT check for retransmitted
-                * IKE_SA_INIT-Requests here, so EVERY single IKE_SA_INIT-
-                * Request (even a retransmitted one) will result in a
-                * IKE_SA. This could be improved...
-                */
-               u_int64_t responder_spi;
-               ike_sa_entry_t *new_ike_sa_entry;
-               
-
-               /* set SPIs, we are the responder */
-               retval = this->get_next_spi(this, &responder_spi);
-
-               if (retval == SUCCESS)
-               { /* next SPI could be created */
-                       
-                       /* we also set arguments spi, so its still valid */
-                       ike_sa_id->set_responder_spi(ike_sa_id, responder_spi);
-                       
-                       /* create entry */
-                       new_ike_sa_entry = ike_sa_entry_create(ike_sa_id);
-                       if (new_ike_sa_entry != NULL)
-                       { 
-                               retval = this->ike_sa_list->insert_last(this->ike_sa_list, new_ike_sa_entry);
-                               if (retval == SUCCESS)
-                               {
-                                       /* check ike_sa out */
-                                       this->logger->log(this->logger,CONTROL | MORE ,"IKE_SA added to list of known IKE_SA's");
-                                       new_ike_sa_entry->checked_out = TRUE;
-                                       *ike_sa = new_ike_sa_entry->ike_sa;
-                       
-                                        /* DON'T use return, we must unlock the mutex! */
-                               }
-                               else
-                               {
-                                       /* ike_sa_entry could not be added to list*/
-                                       this->logger->log(this->logger,ERROR,"Fatal error: ike_sa_entry could not be added to list");
-                               }                       
-                       }
-                       else
-                       {
-                               /* new ike_sa_entry could not be created */
-                               this->logger->log(this->logger,ERROR,"Fatal error: ike_sa_entry could not be created");                 
-                       }
-               }
-               else
-               { /* next SPI could not be created */
-                       this->logger->log(this->logger,ERROR,"Fatal error: Next SPI could not be created");
-               }
-               
-       }
-       else if (!initiator_spi_set && !responder_spi_set)
-       {
-               /* creation of an IKE_SA from local site,
-                * we are the initiator!
-                */
-               u_int64_t initiator_spi;
-               ike_sa_entry_t *new_ike_sa_entry;
-               
-               retval = this->get_next_spi(this, &initiator_spi);
-               if (retval == SUCCESS)
-               {
-                       /* we also set arguments SPI, so its still valid */
-                       ike_sa_id->set_initiator_spi(ike_sa_id, initiator_spi);
-
-                       /* create entry */
-                       new_ike_sa_entry = ike_sa_entry_create(ike_sa_id);
-                       if (new_ike_sa_entry != NULL)
-                       { 
-                               retval = this->ike_sa_list->insert_last(this->ike_sa_list, new_ike_sa_entry);
-
-                               if (retval == SUCCESS)
-                               {
-                                       /* check ike_sa out */
-                                       this->logger->log(this->logger,CONTROL | MORE ,"New IKE_SA created and added to list of known IKE_SA's");
-                                       new_ike_sa_entry->checked_out = TRUE;
-                                       *ike_sa = new_ike_sa_entry->ike_sa;
-                       
-                                       /* DON'T use return, we must unlock the mutex! */
-                               }
-                               else
-                               {
-                                       /* ike_sa_entry could not be added to list*/
-                                       this->logger->log(this->logger,ERROR,"Fatal error: ike_sa_entry could not be added to list");
-                               }               
-                       }
-                       else
-                       {
-                               /* new ike_sa_entry could not be created */
-                               this->logger->log(this->logger,ERROR,"Fatal error: ike_sa_entry could not be created"); 
-                       }
-               }
-               else
-               {
-                       /* next SPI could not be created */
-                       this->logger->log(this->logger,ERROR,"Fatal error: Next SPI could not be created");
-               }
-
-
-       }
-       else
-       {
-               /* responder set, initiator not: here is something seriously wrong! */
-               this->logger->log(this->logger,ERROR | MORE,"Invalid IKE_SA SPI's");
-               /* DON'T use return, we must unlock the mutex! */
-               retval = INVALID_ARG;
-       }
-
-       pthread_mutex_unlock(&(this->mutex));
-       /* OK, unlocked... */
-       return retval;
-}
-
-/**
- * Implements ike_sa_manager_t-function checkin.
- * @see ike_sa_manager_t.checkin.
- */
-static status_t checkin(private_ike_sa_manager_t *this, ike_sa_t *ike_sa)
-{
-       /* to check the SA back in, we look for the pointer of the ike_sa
-        * in all entries.
-        * We can't search by SPI's since the MAY have changed (e.g. on reception
-        * of a IKE_SA_INIT response). Updating of the SPI MAY be necessary...
-        */
-       status_t retval;
-       ike_sa_entry_t *entry;
-       
-       pthread_mutex_lock(&(this->mutex));
-
-       /* look for the entry */
-       if (this->get_entry_by_sa(this, ike_sa, &entry) == SUCCESS)
-       {
-               /* ike_sa_id must be updated */
-               entry->ike_sa_id->replace_values(entry->ike_sa_id, ike_sa->get_id(ike_sa));
-               /* signal waiting threads */
-               entry->checked_out = FALSE;
-               this->logger->log(this->logger,CONTROL | MORE,"Checkin of IKE_SA successful.");
-               pthread_cond_signal(&(entry->condvar));
-               retval = SUCCESS;
-       }
-       else
-       {
-               this->logger->log(this->logger,ERROR,"Fatal Error: Tried to checkin nonexisting IKE_SA");
-               /* this SA is no more, this REALLY should not happen */
-               retval = NOT_FOUND;
-       }
-       pthread_mutex_unlock(&(this->mutex));
-       return retval;
-}
-
-
-/**
- * Implements ike_sa_manager_t-function checkin_and_delete.
- * @see ike_sa_manager_t.checkin_and_delete.
- */
-static status_t checkin_and_delete(private_ike_sa_manager_t *this, ike_sa_t *ike_sa)
-{
-       /* deletion is a bit complex, we must garant that no thread is waiting for
-        * this SA.
-        * We take this SA from the list, and start signaling while threads
-        * are in the condvar.
-        */
-       ike_sa_entry_t *entry;
-       status_t retval;
-
-       pthread_mutex_lock(&(this->mutex));
-
-       if (this->get_entry_by_sa(this, ike_sa, &entry) == SUCCESS)
-       {
-               /* mark it, so now new threads can acquire this SA */
-               entry->driveout_new_threads = TRUE;
-               /* additionaly, drive out waiting threads */
-               entry->driveout_waiting_threads = TRUE;
-
-               /* wait until all workers have done their work */
-               while (entry->waiting_threads > 0)
-               {
-                       /* let the other threads do some work*/
-                       pthread_cond_signal(&(entry->condvar));
-                       /* and the nice thing, they will wake us again when their work is done */
-                       pthread_cond_wait(&(entry->condvar), &(this->mutex));
-               }
-               /* ok, we are alone now, no threads waiting in the entry's condvar */
-               this->delete_entry(this, entry);
-               this->logger->log(this->logger,CONTROL | MORE,"Checkin and delete of IKE_SA successful");
-               retval = SUCCESS;
-       }
-       else
-       {
-               this->logger->log(this->logger,ERROR,"Fatal Error: Tried to checkin and delete nonexisting IKE_SA");
-               retval = NOT_FOUND;
-       }
-
-       pthread_mutex_unlock(&(this->mutex));
-       return retval;
-}
-
-/**
- * Implements ike_sa_manager_t-function delete.
- * @see ike_sa_manager_t.delete.
- */
-static status_t delete(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id)
-{
-       /* deletion is a bit complex, we must garant that no thread is waiting for
-        * this SA.
-        * We take this SA from the list, and start signaling while threads
-        * are in the condvar.
-        */
-       ike_sa_entry_t *entry;
-       status_t retval;
-
-       pthread_mutex_lock(&(this->mutex));
-
-       if (this->get_entry_by_id(this, ike_sa_id, &entry) == SUCCESS)
-       {
-               /* mark it, so now new threads can acquire this SA */
-               entry->driveout_new_threads = TRUE;
-
-               /* wait until all workers have done their work */
-               while (entry->waiting_threads)
-               {
-                       /* wake up all */
-                       pthread_cond_signal(&(entry->condvar));
-                       /* and the nice thing, they will wake us again when their work is done */
-                       pthread_cond_wait(&(entry->condvar), &(this->mutex));
-               }
-               /* ok, we are alone now, no threads waiting in the entry's condvar */
-               this->delete_entry(this, entry);
-               this->logger->log(this->logger,CONTROL | MORE,"Delete of IKE_SA successful");
-               retval = SUCCESS;
-       }
-       else
-       {
-               this->logger->log(this->logger,ERROR,"Fatal Error: Tried to delete nonexisting IKE_SA");
-               retval = NOT_FOUND;
-       }
-
-       pthread_mutex_unlock(&(this->mutex));
-       return retval;
-}
-
-/**
- * Implements ike_sa_manager_t-function destroy.
- * @see ike_sa_manager_t.destroy.
- */
-static status_t destroy(private_ike_sa_manager_t *this)
-{
-       /* destroy all list entries */
-       linked_list_t *list = this->ike_sa_list;
-       linked_list_iterator_t *iterator;
-       status_t status;
-       ike_sa_entry_t *entry;
-       
-       pthread_mutex_lock(&(this->mutex));
-       
-       this->logger->log(this->logger,CONTROL | MORE,"Going to destroy IKE_SA manager and all managed IKE_SA's");
-       
-       /* Step 1: drive out all waiting threads  */
-       status = list->create_iterator(list, &iterator, TRUE);
-       
-       if (status != SUCCESS)
-       {
-               this->logger->log(this->logger,ERROR,"Fatal Error: Create of iterator while destroying IKE_SA-Manager failed");
-               return FAILED;
-       }
-
-       this->logger->log(this->logger,CONTROL | MOST,"Set driveout flags for all stored IKE_SA's");
-       while (iterator->has_next(iterator))
-       {
-               iterator->current(iterator, (void**)&entry);
-               /* do not accept new threads, drive out waiting threads */
-               entry->driveout_new_threads = TRUE;
-               entry->driveout_waiting_threads = TRUE; 
-       }
-
-       this->logger->log(this->logger,CONTROL | MOST,"Wait for all threads to leave IKE_SA's");
-       /* Step 2: wait until all are gone */
-       iterator->reset(iterator);
-       while (iterator->has_next(iterator))
-       {
-               iterator->current(iterator, (void**)&entry);
-               while (entry->waiting_threads)
-               {
-                       /* wake up all */
-                       pthread_cond_signal(&(entry->condvar));
-                       /* go sleeping until they are gone */
-                       pthread_cond_wait(&(entry->condvar), &(this->mutex));           
-               }
-       }
-       this->logger->log(this->logger,CONTROL | MOST,"Delete all IKE_SA's");
-       /* Step 3: delete all entries */
-       iterator->destroy(iterator);
-
-       while (list->get_count(list) > 0)
-       {
-               list->get_first(list, (void**)&entry);
-               this->delete_entry(this, entry);
-       }
-       list->destroy(list);
-       this->logger->log(this->logger,CONTROL | MOST,"IKE_SA's deleted");
-       pthread_mutex_unlock(&(this->mutex));
-
-       /* destroy logger at end */
-       global_logger_manager->destroy_logger(global_logger_manager,this->logger);
-
-       allocator_free(this);
-       
-       return SUCCESS;
-}
-
-/*
- * Described in header
- */
-ike_sa_manager_t *ike_sa_manager_create()
-{
-       private_ike_sa_manager_t *this = allocator_alloc_thing(private_ike_sa_manager_t);
-
-       /* assign public functions */
-       this->public.destroy = (status_t(*)(ike_sa_manager_t*))destroy;
-       this->public.checkout = (status_t(*)(ike_sa_manager_t*, ike_sa_id_t *sa_id, ike_sa_t **sa))checkout;
-       this->public.checkin = (status_t(*)(ike_sa_manager_t*, ike_sa_t *sa))checkin;
-       this->public.delete = (status_t(*)(ike_sa_manager_t*, ike_sa_id_t *sa_id))delete;
-       this->public.checkin_and_delete = (status_t(*)(ike_sa_manager_t*, ike_sa_t *ike_sa))checkin_and_delete;
-
-       /* initialize private functions */
-       this->get_next_spi = get_next_spi;
-       this->get_entry_by_sa = get_entry_by_sa;
-       this->get_entry_by_id = get_entry_by_id;
-       this->delete_entry = delete_entry;
-
-       /* initialize private variables */
-       this->logger = global_logger_manager->create_logger(global_logger_manager,IKE_SA_MANAGER,NULL);
-       if (this->logger == NULL)
-       {
-               allocator_free(this);
-               return NULL;
-       }
-       
-       this->ike_sa_list = linked_list_create();
-       if (this->ike_sa_list == NULL)
-       {
-               this->logger->log(this->logger,ERROR,"Fatal error: Failed to create list for managed IKE_SA");
-               global_logger_manager->destroy_logger(global_logger_manager,this->logger);
-               allocator_free(this);
-               return NULL;
-       }
-
-       pthread_mutex_init(&(this->mutex), NULL);
-
-       this->next_spi = 0;
-
-       return (ike_sa_manager_t*)this;
-}
diff --git a/Source/charon/ike_sa_manager.h b/Source/charon/ike_sa_manager.h
deleted file mode 100644 (file)
index 71ac33b..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/**
- * @file ike_sa_manager.h
- * 
- * @brief Central point for managing IKE-SAs (creation, locking, deleting...)
- * 
- */
-
-/*
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef IKE_SA_MANAGER_H_
-#define IKE_SA_MANAGER_H_
-
-#include <types.h>
-#include <ike_sa.h>
-
-
-/**
- * @brief The IKE_SA-Manager manages the IKE_SAs ;-). 
- * 
- * To avoid access from multiple threads, IKE_SAs must be checked out from
- * the manager, and checked back in after usage. 
- * The manager also handles deletion of SAs.
- * 
- * @todo checking of double-checkouts from the same threads would be nice.
- * This could be by comparing thread-ids via pthread_self()...
- * 
- */
-typedef struct ike_sa_manager_s ike_sa_manager_t;
-struct ike_sa_manager_s {
-       /**
-        * @brief Checkout an IKE_SA, create it when necesarry
-        * 
-        * Checks out a SA by its ID. An SA will be created, when:
-        * - Responder SPI is not set (when received an IKE_SA_INIT from initiator)
-        * - Both SPIs are not set (for initiating IKE_SA_INIT)
-        * Management of SPIs is the managers job, he will set it.
-        * This function blocks until SA is available for checkout.
-        * 
-        * @warning checking out two times without checking in will
-        * result in a deadlock!
-        * 
-        * @param ike_sa_manager        the manager object
-        * @param ike_sa_id[in/out]     the SA identifier, will be updated
-        * @param ike_sa[out]           checked out SA
-        * @returns                                     
-        *                                                      - SUCCESS if checkout successful
-        *                                                      - NOT_FOUND when no such SA is available
-        *                                                      - OUT_OF_RES
-        */
-       status_t (*checkout) (ike_sa_manager_t* ike_sa_manager, ike_sa_id_t *sa_id, ike_sa_t **ike_sa);
-       /**
-        * @brief Checkin the SA after usage
-        * 
-        * @warning the SA pointer MUST NOT be used after checkin! The SA must be checked
-        * out again!
-        *  
-        * @param ike_sa_manager        the manager object
-        * @param ike_sa_id[in/out]     the SA identifier, will be updated
-        * @param ike_sa[out]           checked out SA
-        * @returns                             SUCCESS if checked in
-        *                                                      NOT_FOUND when not found (shouldn't happen!)
-        */
-       status_t (*checkin) (ike_sa_manager_t* ike_sa_manager, ike_sa_t *ike_sa);
-       /**
-        * @brief delete a SA, wich was not checked out
-        * 
-        * @warning do not use this when the SA is already checked out, this will
-        * deadlock!
-        *  
-        * @param ike_sa_manager        the manager object
-        * @param ike_sa_id[in/out]     the SA identifier
-        * @returns                             SUCCESS if found
-        *                                                      NOT_FOUND when no such SA is available
-        */
-       status_t (*delete) (ike_sa_manager_t* ike_sa_manager, ike_sa_id_t *ike_sa_id);
-       /**
-        * @brief delete a checked out SA
-        *  
-        * @param ike_sa_manager        the manager object
-        * @param ike_sa                        SA to delete
-        * @returns                             SUCCESS if found
-        *                                                      NOT_FOUND when no such SA is available
-        */
-       status_t (*checkin_and_delete) (ike_sa_manager_t* ike_sa_manager, ike_sa_t *ike_sa);
-       
-       /**
-        * @brief Destroys the manager with all associated SAs
-        * 
-        * Threads will be driven out, so all SAs can be deleted cleanly
-        * 
-        * @param ike_sa_manager the manager object
-        * @returns SUCCESS if succeeded, FAILED otherwise
-        */
-       status_t (*destroy) (ike_sa_manager_t *ike_sa_manager);
-};
-
-/**
- * @brief Create a manager
- * 
- * @returns the manager
- */
-ike_sa_manager_t *ike_sa_manager_create();
-
-#endif /*IKE_SA_MANAGER_H_*/
index dd6ad88..fe7c03f 100644 (file)
@@ -24,7 +24,7 @@
 #define DELETE_IKE_SA_JOB_H_
 
 #include <types.h>
-#include <ike_sa_id.h>
+#include <sa/ike_sa_id.h>
 #include <queues/jobs/job.h>
 
 
diff --git a/Source/charon/sa/ike_sa.c b/Source/charon/sa/ike_sa.c
new file mode 100644 (file)
index 0000000..9747391
--- /dev/null
@@ -0,0 +1,574 @@
+/**
+ * @file ike_sa.c
+ *
+ * @brief Class ike_sa_t. An object of this type is managed by an
+ * ike_sa_manager_t object and represents an IKE_SA
+ *
+ */
+
+/*
+ * Copyright (C) 2005 Jan Hutter, Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "ike_sa.h"
+
+#include <types.h>
+#include <globals.h>
+#include <definitions.h>
+#include <utils/allocator.h>
+#include <utils/linked_list.h>
+#include <utils/logger_manager.h>
+#include <utils/randomizer.h>
+#include <transforms/diffie_hellman.h>
+#include <transforms/prf_plus.h>
+#include <encoding/payloads/sa_payload.h>
+#include <encoding/payloads/nonce_payload.h>
+#include <encoding/payloads/ke_payload.h>
+#include <encoding/payloads/transform_substructure.h>
+#include <encoding/payloads/transform_attribute.h>
+#include <sa/states/initiator_init.h>
+#include <sa/states/responder_init.h>
+
+
+
+
+/**
+ * @brief implements function process_message of protected_ike_sa_t
+ */
+static status_t process_message (protected_ike_sa_t *this, message_t *message)
+{      
+       u_int32_t message_id;
+       exchange_type_t exchange_type;
+       bool is_request;
+       status_t status;
+       state_t *new_state;
+       
+       /* we must process each request or response from remote host */
+
+       /* find out type of message (request or response) */
+       is_request = message->get_request(message);
+       exchange_type = message->get_exchange_type(message);
+
+       this->logger->log(this->logger, CONTROL|MORE, "Process %s message of exchange type %s",(is_request) ? "REQUEST" : "RESPONSE",mapping_find(exchange_type_m,exchange_type));
+
+       message_id = message->get_message_id(message);
+
+       /* 
+        * It has to be checked, if the message has to be resent cause of lost packets!
+        */
+       if (is_request && ( message_id == (this->message_id_in - 1)))
+       {
+               /* message can be resent ! */
+               this->logger->log(this->logger, CONTROL|MORE, "Resent message detected. Send stored reply");
+               return (this->resend_last_reply(this));
+       }
+       
+       /* Now, the message id is checked for request AND reply */
+       if (is_request)
+       {
+               /* In a request, the message has to be this->message_id_in (other case is already handled) */
+               if (message_id != this->message_id_in)
+               {
+                       this->logger->log(this->logger, ERROR | MORE, "Message request with message id %d received, but %d expected",message_id,this->message_id_in);
+                       return FAILED;
+               }
+       }
+       else
+       {
+               /* In a reply, the message has to be this->message_id_out -1 cause it is the reply to the last sent message*/
+               if (message_id != (this->message_id_out - 1))
+               {
+                       this->logger->log(this->logger, ERROR | MORE, "Message reply with message id %d received, but %d expected",message_id,this->message_id_in);
+                       return FAILED;
+               }
+       }
+       
+       /* now the message is processed by the current state object */
+       status = this->current_state->process_message(this->current_state,message,&new_state);
+
+       if (status == SUCCESS)
+       {
+               this->current_state = new_state;
+       }
+       return status;
+}
+
+/**
+ * @brief Implements function build_message of protected_ike_sa_t.
+ */
+static status_t build_message(protected_ike_sa_t *this, exchange_type_t type, bool request, message_t **message)
+{
+       status_t status;
+       message_t *new_message; 
+       host_t *source, *destination;
+
+       this    ->logger->log(this->logger, CONTROL|MORE, "build empty message");       
+       new_message = message_create(); 
+       if (new_message == NULL)
+       {
+               this->logger->log(this->logger, ERROR, "Fatal error: could not create empty message object");   
+               return OUT_OF_RES;
+       }
+       
+       status  = this->me.host->clone(this->me.host, &source);
+       if (status != SUCCESS)
+       {
+               this->logger->log(this->logger, ERROR, "Fatal error: could not clone my host information");
+               new_message->destroy(new_message);
+               return status;  
+       }
+       status = this->other.host->clone(this->other.host, &destination);       
+       if (status != SUCCESS)
+       {
+               this->logger->log(this->logger, ERROR, "Fatal error: could not clone other host information");
+               source->destroy(source);
+               new_message->destroy(new_message);
+               return status;  
+       }
+       
+       new_message->set_source(new_message, source);
+       new_message->set_destination(new_message, destination);
+       
+       new_message->set_exchange_type(new_message, type);
+       new_message->set_request(new_message, request);
+       
+       new_message->set_message_id(new_message, (request) ? this->message_id_out : this->message_id_in);
+
+       status = new_message->set_ike_sa_id(new_message, this->ike_sa_id);
+       if (status != SUCCESS)
+       {
+               this->logger->log(this->logger, ERROR, "Fatal error: could not set ike_sa_id of message");
+               new_message->destroy(new_message);
+               return status;
+       }
+       
+       *message = new_message;
+       
+       return SUCCESS;
+}
+
+/**
+ * @brief implements function process_configuration of protected_ike_sa_t
+ */
+static status_t initialize_connection(protected_ike_sa_t *this, char *name)
+{
+       /* work is done in state object of type INITIATOR_INIT */
+       initiator_init_t *current_state;
+       status_t status;
+       state_t *new_state;
+       
+       if (this->current_state->get_state(this->current_state) != INITIATOR_INIT)
+       {
+               return FAILED;
+       }
+       
+       current_state = (initiator_init_t *) this->current_state;
+       
+       status = current_state->initiate_connection(current_state,name,&new_state);
+       
+       if (status == SUCCESS)
+       {
+               this->current_state = new_state;
+       }
+       else
+       {
+               this->create_delete_job(this);
+       }
+       return status;
+}
+
+/**
+ * @brief implements function protected_ike_sa_t.get_id
+ */
+static ike_sa_id_t* get_id(protected_ike_sa_t *this)
+{
+       return this->ike_sa_id;
+}
+
+static status_t compute_secrets (protected_ike_sa_t *this,chunk_t dh_shared_secret,chunk_t initiator_nonce, chunk_t responder_nonce)
+{
+       chunk_t concatenated_nonces;
+       chunk_t skeyseed;
+       chunk_t prf_plus_seed;
+       status_t status;
+       u_int64_t initiator_spi;
+       u_int64_t responder_spi;
+       prf_plus_t *prf_plus;
+       chunk_t secrets_raw;
+
+       /*
+        * TODO check length for specific prf's 
+        */
+       concatenated_nonces.len = (initiator_nonce.len + responder_nonce.len);
+       concatenated_nonces.ptr = allocator_alloc(concatenated_nonces.len);
+       if (concatenated_nonces.ptr == NULL)
+       {
+               this->logger->log(this->logger, ERROR, "Fatal errror: Could not allocate memory for concatenated nonces");
+               return FAILED;
+       }
+       /* first is initiator */
+       memcpy(concatenated_nonces.ptr,initiator_nonce.ptr,initiator_nonce.len);
+       /* second is responder */
+       memcpy(concatenated_nonces.ptr + initiator_nonce.len,responder_nonce.ptr,responder_nonce.len);
+
+       this->logger->log_chunk(this->logger, RAW, "Nonce data", &concatenated_nonces);
+
+
+       /* status of set_key is not checked */
+       status = this->prf->set_key(this->prf,concatenated_nonces);
+
+       status = this->prf->allocate_bytes(this->prf,dh_shared_secret,&skeyseed);
+       if (status != SUCCESS)
+       {
+               allocator_free_chunk(concatenated_nonces);
+               this->logger->log(this->logger, ERROR, "Fatal errror: Could not allocate bytes for skeyseed");
+               return status;
+       }
+       allocator_free_chunk(concatenated_nonces);
+
+       prf_plus_seed.len = (initiator_nonce.len + responder_nonce.len + 16);
+       prf_plus_seed.ptr = allocator_alloc(prf_plus_seed.len);
+       if (prf_plus_seed.ptr == NULL)
+       {
+               this->logger->log(this->logger, ERROR, "Fatal errror: Could not allocate memory for prf+ seed");
+               allocator_free_chunk(skeyseed);
+               return FAILED;
+       }
+       
+       /* first is initiator */
+       memcpy(prf_plus_seed.ptr,initiator_nonce.ptr,initiator_nonce.len);
+       /* second is responder */
+       memcpy(prf_plus_seed.ptr + initiator_nonce.len,responder_nonce.ptr,responder_nonce.len);
+       /* third is initiator spi */
+       initiator_spi = this->ike_sa_id->get_initiator_spi(this->ike_sa_id);
+       memcpy(prf_plus_seed.ptr + initiator_nonce.len + responder_nonce.len,&initiator_spi,8);
+       /* fourth is responder spi */
+       responder_spi = this->ike_sa_id->get_responder_spi(this->ike_sa_id);
+       memcpy(prf_plus_seed.ptr + initiator_nonce.len + responder_nonce.len + 8,&responder_spi,8);
+       
+       this->logger->log_chunk(this->logger, PRIVATE, "Keyseed", &skeyseed);
+       this->logger->log_chunk(this->logger, PRIVATE, "PRF+ Seed", &prf_plus_seed);
+
+       this->logger->log(this->logger, CONTROL | MOST, "Set new key of prf object");
+       status = this->prf->set_key(this->prf,skeyseed);
+       allocator_free_chunk(skeyseed);
+       if (status != SUCCESS)
+       {
+               this->logger->log(this->logger, ERROR, "Fatal errror: Could not allocate memory for prf+ seed");
+               allocator_free_chunk(prf_plus_seed);
+               return FAILED;
+       }
+       
+       this->logger->log(this->logger, CONTROL | MOST, "Create new prf+ object");
+       prf_plus = prf_plus_create(this->prf, prf_plus_seed);
+       allocator_free_chunk(prf_plus_seed);
+       if (prf_plus == NULL)
+       {
+               this->logger->log(this->logger, ERROR, "Fatal errror: prf+ object could not be created");
+               return FAILED;
+       }
+       
+       prf_plus->allocate_bytes(prf_plus,100,&secrets_raw);
+       
+       this->logger->log_chunk(this->logger, PRIVATE, "Secrets", &secrets_raw);
+       
+       allocator_free_chunk(secrets_raw);
+       
+       prf_plus->destroy(prf_plus);
+
+       return SUCCESS;
+}
+
+/**
+ * @brief implements function resend_last_reply of protected_ike_sa_t
+ */
+status_t resend_last_reply (protected_ike_sa_t *this)
+{
+       packet_t *packet;
+       status_t status;
+       
+       status = this->last_responded_message->generate(this->last_responded_message, &packet);
+       if (status != SUCCESS)
+       {
+               this->logger->log(this->logger, ERROR, "Could not generate message to resent");
+               return status;
+       }
+       
+       status = global_send_queue->add(global_send_queue, packet);
+       if (status != SUCCESS)
+       {
+               this->logger->log(this->logger, ERROR, "Could not add packet to send queue");
+               packet->destroy(packet);
+               return status;
+       }               
+       return SUCCESS;
+}
+
+status_t create_delete_job (protected_ike_sa_t *this)
+{
+       job_t *delete_job;
+       status_t status;
+
+       this->logger->log(this->logger, CONTROL | MORE, "Going to create job to delete this IKE_SA");
+
+       delete_job = (job_t *) delete_ike_sa_job_create(this->ike_sa_id);
+       if (delete_job == NULL)
+       {
+               this->logger->log(this->logger, ERROR, "Job to delete IKE SA could not be created");
+               return FAILED;
+       }
+       
+       status = global_job_queue->add(global_job_queue,delete_job);
+       if (status != SUCCESS)
+       {
+               this->logger->log(this->logger, ERROR, "%s Job to delete IKE SA could not be added to job queue",mapping_find(status_m,status));
+               delete_job->destroy_all(delete_job);
+               return status;
+       }
+       return SUCCESS;
+}
+
+/**
+ * @brief implements function destroy of protected_ike_sa_t
+ */
+static status_t destroy (protected_ike_sa_t *this)
+{
+       
+       this->logger->log(this->logger, CONTROL | MORE, "Going to destroy IKE_SA");
+
+       /* destroy child sa's */
+       this->logger->log(this->logger, CONTROL | MOST, "Destroy all child_sa's");
+       while (this->child_sas->get_count(this->child_sas) > 0)
+       {
+               void *child_sa;
+               if (this->child_sas->remove_first(this->child_sas,&child_sa) != SUCCESS)
+               {
+                       break;
+               }
+               /* destroy child sa */
+       }
+       this->child_sas->destroy(this->child_sas);
+
+       this->logger->log(this->logger, CONTROL | MOST, "Destroy secrets");
+       if (this->secrets.d_key.ptr != NULL)
+       {
+               allocator_free(this->secrets.d_key.ptr);
+       }
+       if (this->secrets.ai_key.ptr != NULL)
+       {
+               allocator_free(this->secrets.ai_key.ptr);
+       }
+       if (this->secrets.ar_key.ptr != NULL)
+       {
+               allocator_free(this->secrets.ar_key.ptr);
+       }
+       if (this->secrets.ei_key.ptr != NULL)
+       {
+               allocator_free(this->secrets.ei_key.ptr);
+       }
+       if (this->secrets.er_key.ptr != NULL)
+       {
+               allocator_free(this->secrets.er_key.ptr);
+       }
+       if (this->secrets.pi_key.ptr != NULL)
+       {
+               allocator_free(this->secrets.pi_key.ptr);
+       }
+       if (this->secrets.pr_key.ptr != NULL)
+       {
+               allocator_free(this->secrets.pr_key.ptr);
+       }
+       
+       if (    this->crypter_initiator != NULL)
+       {
+               this->logger->log(this->logger, CONTROL | MOST, "Destroy initiator crypter");
+               this->crypter_initiator->destroy(this->crypter_initiator);
+       }
+       
+       if (    this->crypter_responder != NULL)
+       {
+               this->logger->log(this->logger, CONTROL | MOST, "Destroy responder crypter");
+               this->crypter_responder->destroy(this->crypter_responder);
+       }
+       
+       if (    this->signer_initiator != NULL)
+       {
+               this->logger->log(this->logger, CONTROL | MOST, "Destroy initiator signer");
+               this->signer_initiator->destroy(this->signer_initiator);
+       }
+
+       if (this->signer_responder != NULL)
+       {
+               this->logger->log(this->logger, CONTROL | MOST, "Destroy responder signer");
+               this->signer_responder->destroy(this->signer_responder);
+       }
+       
+       if (this->prf != NULL)
+       {
+               this->logger->log(this->logger, CONTROL | MOST, "Destroy prf");
+               this->prf->destroy(this->prf);
+       }
+       
+       /* destroy ike_sa_id */
+       this->logger->log(this->logger, CONTROL | MOST, "Destroy assigned ike_sa_id");
+       this->ike_sa_id->destroy(this->ike_sa_id);
+
+       /* destroy stored requested message */
+       if (this->last_requested_message != NULL)
+       {
+               this->logger->log(this->logger, CONTROL | MOST, "Destroy last requested message");
+               this->last_requested_message->destroy(this->last_requested_message);
+       }
+       
+       /* destroy stored responded messages */
+       if (this->last_responded_message != NULL)
+       {
+               this->logger->log(this->logger, CONTROL | MOST, "Destroy last responded message");
+               this->last_responded_message->destroy(this->last_responded_message);
+       }
+       
+       this->logger->log(this->logger, CONTROL | MOST, "Destroy randomizer");
+       this->randomizer->destroy(this->randomizer);
+
+       if (this->me.host != NULL)
+       {
+               this->logger->log(this->logger, CONTROL | MOST, "Destroy host informations of me");
+               this->me.host->destroy(this->me.host);
+       }
+       
+       if (this->other.host != NULL)
+       {
+               this->logger->log(this->logger, CONTROL | MOST, "Destroy host informations of other");
+               this->other.host->destroy(this->other.host);
+       }
+       
+       this->logger->log(this->logger, CONTROL | MOST, "Destroy current state object");
+       this->current_state->destroy(this->current_state);
+       
+       this->logger->log(this->logger, CONTROL | MOST, "Destroy logger of IKE_SA");
+       
+       global_logger_manager->destroy_logger(global_logger_manager, this->logger);
+
+       allocator_free(this);
+       return SUCCESS;
+}
+
+/*
+ * Described in Header
+ */
+ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
+{
+       protected_ike_sa_t *this = allocator_alloc_thing(protected_ike_sa_t);
+       if (this == NULL)
+       {
+               return NULL;
+       }
+
+       /* Public functions */
+       this->public.process_message = (status_t(*)(ike_sa_t*, message_t*)) process_message;
+       this->public.initialize_connection = (status_t(*)(ike_sa_t*, char*)) initialize_connection;
+       this->public.get_id = (ike_sa_id_t*(*)(ike_sa_t*)) get_id;
+       this->public.destroy = (status_t(*)(ike_sa_t*))destroy;
+       
+       /* private functions */
+       this->build_message = build_message;
+       this->resend_last_reply = resend_last_reply;
+       this->create_delete_job = create_delete_job;
+       this->compute_secrets = compute_secrets;
+
+       /* initialize private fields */
+       this->logger = global_logger_manager->create_logger(global_logger_manager, IKE_SA, NULL);
+       if (this->logger ==  NULL)
+       {
+               allocator_free(this);
+       }
+       
+       if (ike_sa_id->clone(ike_sa_id,&(this->ike_sa_id)) != SUCCESS)
+       {
+               this->logger->log(this->logger, ERROR, "Fatal error: Could not clone ike_sa_id");
+               global_logger_manager->destroy_logger(global_logger_manager,this->logger);
+               allocator_free(this);
+               return NULL;
+       }
+       this->child_sas = linked_list_create();
+       if (this->child_sas == NULL)
+       {
+               this->logger->log(this->logger, ERROR, "Fatal error: Could not create list for child_sa's");
+               this->ike_sa_id->destroy(this->ike_sa_id);
+               global_logger_manager->destroy_logger(global_logger_manager,this->logger);
+               allocator_free(this);
+               return NULL;
+       }
+       this->randomizer = randomizer_create();
+       if (this->randomizer == NULL)
+       {
+               this->logger->log(this->logger, ERROR, "Fatal error: Could not create list for child_sa's");
+               this->child_sas->destroy(this->child_sas);
+               this->ike_sa_id->destroy(this->ike_sa_id);
+               global_logger_manager->destroy_logger(global_logger_manager,this->logger);
+               allocator_free(this);
+       }
+       
+       this->me.host = NULL;
+       this->other.host = NULL;
+       this->last_requested_message = NULL;
+       this->last_responded_message = NULL;
+       this->message_id_out = 0;
+       this->message_id_in = 0;
+       this->secrets.d_key.ptr = NULL;
+       this->secrets.d_key.len = 0;
+       this->secrets.ai_key.ptr = NULL;
+       this->secrets.ai_key.len = 0;
+       this->secrets.ar_key.ptr = NULL;
+       this->secrets.ar_key.len = 0;
+       this->secrets.ei_key.ptr = NULL;        
+       this->secrets.ei_key.len = 0;
+       this->secrets.er_key.ptr = NULL;
+       this->secrets.er_key.len = 0;
+       this->secrets.pi_key.ptr = NULL;
+       this->secrets.pi_key.len = 0;
+       this->secrets.pr_key.ptr = NULL;
+       this->secrets.pr_key.len = 0;
+       this->crypter_initiator = NULL;
+       this->crypter_responder = NULL;
+       this->signer_initiator = NULL;
+       this->signer_responder = NULL;
+       this->prf = NULL;
+       
+
+
+
+       /* at creation time, IKE_SA is in a initiator state */
+       if (ike_sa_id->is_initiator(ike_sa_id))
+       {
+               this->current_state = (state_t *) initiator_init_create(this);
+       }
+       else
+       {
+               this->current_state = (state_t *) responder_init_create(this);
+       }
+       
+       if (this->current_state == NULL)
+       {
+               this->logger->log(this->logger, ERROR, "Fatal error: Could not create state object");
+               this->child_sas->destroy(this->child_sas);
+               this->ike_sa_id->destroy(this->ike_sa_id);
+               global_logger_manager->destroy_logger(global_logger_manager,this->logger);
+               this->randomizer->destroy(this->randomizer);
+               allocator_free(this);
+       }
+
+
+       return &(this->public);
+}
diff --git a/Source/charon/sa/ike_sa.h b/Source/charon/sa/ike_sa.h
new file mode 100644 (file)
index 0000000..34e95ab
--- /dev/null
@@ -0,0 +1,287 @@
+/**
+ * @file ike_sa.h
+ *
+ * @brief Class ike_sa_t. An object of this type is managed by an
+ * ike_sa_manager_t object and represents an IKE_SA
+ *
+ */
+
+/*
+ * Copyright (C) 2005 Jan Hutter, Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef IKE_SA_H_
+#define IKE_SA_H_
+
+#include <types.h>
+#include <encoding/message.h>
+#include <sa/ike_sa_id.h>
+#include <utils/logger.h>
+#include <utils/randomizer.h>
+#include <sa/states/state.h>
+#include <transforms/prfs/prf.h>
+#include <transforms/crypters/crypter.h>
+#include <transforms/signers/signer.h>
+
+
+
+/**
+ * Nonce size in bytes of all sent nonces
+ */
+#define NONCE_SIZE 16
+
+/**
+ * @brief This class is used to represent an IKE_SA
+ *
+ */
+typedef struct ike_sa_s ike_sa_t;
+
+struct ike_sa_s {
+
+       /**
+        * @brief Processes a incoming IKEv2-Message of type message_t
+        *
+        * @param this ike_sa_t object object
+        * @param[in] message message_t object to process
+        * @return SUCCESSFUL if succeeded, FAILED otherwise
+        */
+       status_t (*process_message) (ike_sa_t *this,message_t *message);
+
+       /**
+        * Initiate a new connection with given configuration name
+        * 
+        * @param this                  calling object
+        * @param name                  name of the configuration
+        * @return                              TODO
+        */
+       status_t (*initialize_connection) (ike_sa_t *this, char *name);
+
+       /**
+        * @brief Get the id of the SA
+        *
+        * @param this ike_sa_t-message_t object object
+        * @return ike_sa's ike_sa_id_t
+        */
+       ike_sa_id_t* (*get_id) (ike_sa_t *this);
+
+       /**
+        * @brief Destroys a ike_sa_t object
+        *
+        * @param this ike_sa_t object
+        * @return SUCCESSFUL if succeeded, FAILED otherwise
+        */
+       status_t (*destroy) (ike_sa_t *this);
+};
+
+/**
+ * Protected data of an ike_sa_t object
+ */
+typedef struct protected_ike_sa_s protected_ike_sa_t;
+
+struct protected_ike_sa_s {
+
+       /**
+        * Public part of a ike_sa_t object
+        */
+       ike_sa_t public;
+       
+       /**
+        * Builds an empty IKEv2-Message and fills in default informations.
+        * 
+        * Depending on the type of message (request or response), the message id is 
+        * either message_id_out or message_id_in.
+        * 
+        * Used in every state.
+        * 
+        * @param this          calling object
+        * @param type          exchange type of new message
+        * @param request       TRUE, if message has to be a request
+        * @param message       new message is stored at this location
+        * @return                      
+        *                                      - SUCCESS
+        *                                      - OUT_OF_RES
+        */
+       status_t (*build_message) (protected_ike_sa_t *this, exchange_type_t type, bool request, message_t **message);
+
+       /**
+        * Initiate a new connection with given configuration name
+        * 
+        * @param this                          calling object
+        * @param dh_shared_secret      shared secret of diffie hellman exchange
+        * @param initiator_nonce       nonce of initiator
+        * @param responder_nonce       nonce of responder
+        * @return                                      TODO
+        */
+       status_t (*compute_secrets) (protected_ike_sa_t *this,chunk_t dh_shared_secret,chunk_t initiator_nonce, chunk_t responder_nonce);
+
+       /**
+        * Creates a job to delete the given IKE_SA
+        */
+       status_t (*create_delete_job) (protected_ike_sa_t *this);
+
+       /**
+        * Resends the last sent reply
+        */
+       status_t (*resend_last_reply) (protected_ike_sa_t *this);
+       
+       
+       /* protected values */
+       
+       /**
+        * Identifier for the current IKE_SA
+        */
+       ike_sa_id_t *ike_sa_id;
+
+       /**
+        * Linked List containing the child sa's of the current IKE_SA
+        */
+       linked_list_t *child_sas;
+
+       /**
+        * Current state of the IKE_SA
+        */
+       state_t *current_state;
+       
+       /**
+        * this SA's source for random data
+        */
+       randomizer_t *randomizer;
+       
+       /**
+        * contains the last responded message
+        * 
+        */
+       message_t *last_responded_message;
+
+       /**
+        * contains the last requested message
+        * 
+        */
+       message_t *last_requested_message;
+       
+       /**
+        * Informations of this host
+        */
+       struct {
+               host_t *host;
+       } me;
+
+       /**
+        * Informations of the other host
+        */     
+       struct {
+               host_t *host;
+       } other;
+       
+       /**
+        * Crypter object for initiator
+        */
+       crypter_t *crypter_initiator;
+       
+       /**
+        * Crypter object for responder
+        */
+       crypter_t *crypter_responder;
+       
+       /**
+        * Signer object for initiator
+        */
+       signer_t *signer_initiator;
+       
+       /**
+        * Signer object for responder
+        */
+       signer_t *signer_responder;
+       
+       /**
+        * prf function
+        */
+       prf_t *prf;
+       
+       
+       
+       /**
+        * Shared secrets
+        */
+       struct {
+               /**
+                * Key used for deriving other keys
+                */
+               chunk_t d_key;
+               
+               /**
+                * Key for authenticate (initiator)
+                */
+               chunk_t ai_key;
+               
+               /**
+                * Key for authenticate (responder)
+                */
+               chunk_t ar_key;
+
+               /**
+                * Key for encryption (initiator)
+                */
+               chunk_t ei_key; 
+
+               /**
+                * Key for encryption (responder)
+                */
+               chunk_t er_key; 
+
+               /**
+                * Key for generating auth payload (initiator)
+                */
+               chunk_t pi_key; 
+
+               /**
+                * Key for generating auth payload (responder)
+                */
+               chunk_t pr_key; 
+
+       } secrets;
+
+       /**
+        * next message id to receive
+        */
+       u_int32_t message_id_in;
+       
+       /**
+        * next message id to send
+        */
+       u_int32_t message_id_out;
+       
+       /**
+        * a logger for this IKE_SA
+        */
+       logger_t *logger;
+};
+
+
+
+/**
+ * Creates an ike_sa_t object with a specific ike_sa_id_t object
+ *
+ * @param[in] ike_sa_id ike_sa_id_t object to associate with new IKE_SA.
+ *                                             The object is internal getting cloned
+ *                                             and so has to be destroyed by the caller.
+ *
+ * @warning the Content of internal ike_sa_id_t object can change over time
+ *                     e.g. when a IKE_SA_INIT has been finished
+ *
+ * @return created ike_sa_t object
+ */
+ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id);
+
+#endif /*IKE_SA_H_*/
diff --git a/Source/charon/sa/ike_sa_id.c b/Source/charon/sa/ike_sa_id.c
new file mode 100644 (file)
index 0000000..52b1a9c
--- /dev/null
@@ -0,0 +1,213 @@
+/**
+ * @file ike_sa_id.c
+ *
+ * @brief Class for identification of an IKE_SA
+ *
+ */
+
+/*
+ * Copyright (C) 2005 Jan Hutter, Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "ike_sa_id.h"
+
+#include <types.h>
+#include <utils/allocator.h>
+
+/**
+ * Private data of an ike_sa_id object
+ */
+typedef struct private_ike_sa_id_s private_ike_sa_id_t;
+
+struct private_ike_sa_id_s {
+       /**
+        * Public part of a ike_sa_id object
+        */
+       ike_sa_id_t public;
+
+
+       /* Private values */
+
+        /**
+         * SPI of Initiator
+         */
+       u_int64_t initiator_spi;
+
+        /**
+         * SPI of Responder
+         */
+       u_int64_t responder_spi;
+
+       /**
+        * Role for specific IKE_SA
+        */
+       bool is_initiator_flag;
+
+};
+
+
+/**
+ * @brief implements function set_responder_spi of ike_sa_id_t
+ */
+static status_t set_responder_spi (private_ike_sa_id_t *this, u_int64_t responder_spi)
+{
+       this->responder_spi = responder_spi;
+       return SUCCESS;
+}
+
+static status_t set_initiator_spi(private_ike_sa_id_t *this, u_int64_t initiator_spi)
+{
+       this->initiator_spi = initiator_spi;
+       return SUCCESS;
+}
+
+/**
+ * @brief implements ike_sa_id_t.get_initiator_spi
+ */
+static u_int64_t get_initiator_spi (private_ike_sa_id_t *this)
+{
+       return this->initiator_spi;
+}
+
+/**
+ * @brief implements ike_sa_id_t.get_responder_spi
+ */
+static u_int64_t get_responder_spi (private_ike_sa_id_t *this)
+{
+       return this->responder_spi;
+}
+
+/**
+ * @brief implements function equals of ike_sa_id_t
+ */
+static status_t equals (private_ike_sa_id_t *this,private_ike_sa_id_t *other, bool *are_equal)
+{
+       if ((this == NULL)||(other == NULL))
+       {
+               return FAILED;
+       }
+       if ((this->is_initiator_flag == other->is_initiator_flag) &&
+               (this->initiator_spi == other->initiator_spi) &&
+               (this->responder_spi == other->responder_spi))
+
+       {
+               /* private_ike_sa_id's are equal */
+               *are_equal = TRUE;
+       }
+       else
+       {
+               /* private_ike_sa_id's are not equal */
+               *are_equal = FALSE;
+       }
+
+       return SUCCESS;
+}
+
+/**
+ * @brief implements function replace_values of ike_sa_id_t
+ */
+status_t replace_values (private_ike_sa_id_t *this, private_ike_sa_id_t *other)
+{
+       if ((this == NULL) || (other == NULL))
+       {
+               return FAILED;
+       }
+
+       this->initiator_spi = other->initiator_spi;
+       this->responder_spi = other->responder_spi;
+       this->is_initiator_flag = other->is_initiator_flag;
+
+       return SUCCESS;
+}
+
+
+/**
+ * @brief implements ike_sa_id_t.is_initiator
+ */
+static bool is_initiator(private_ike_sa_id_t *this)
+{
+       return this->is_initiator_flag;
+}
+
+/**
+ * @brief implements ike_sa_id_t.switch_initiator
+ */
+static bool switch_initiator(private_ike_sa_id_t *this)
+{
+       if (this->is_initiator_flag)
+       {
+               this->is_initiator_flag = FALSE;
+       }
+       else
+       {
+               this->is_initiator_flag = TRUE; 
+       }
+       return this->is_initiator_flag;
+}
+
+
+/**
+ * @brief implements function clone of ike_sa_id_t
+ */
+static status_t clone (private_ike_sa_id_t *this, ike_sa_id_t **clone_of_this)
+{
+       *clone_of_this = ike_sa_id_create(this->initiator_spi, this->responder_spi, this->is_initiator_flag);
+
+       return (*clone_of_this == NULL) ? OUT_OF_RES : SUCCESS;
+}
+
+/**
+ * @brief implements function destroy of ike_sa_id_t
+ */
+static status_t destroy (private_ike_sa_id_t *this)
+{
+       allocator_free(this);
+       return SUCCESS;
+}
+
+/*
+ * Described in Header-File
+ */
+ike_sa_id_t * ike_sa_id_create(u_int64_t initiator_spi, u_int64_t responder_spi, bool is_initiator_flag)
+{
+       private_ike_sa_id_t *this = allocator_alloc_thing(private_ike_sa_id_t);
+       if (this == NULL)
+       {
+               return NULL;
+       }
+
+       /* Public functions */
+       this->public.set_responder_spi = (status_t(*)(ike_sa_id_t*,u_int64_t)) set_responder_spi;
+       this->public.set_initiator_spi = (status_t(*)(ike_sa_id_t*,u_int64_t)) set_initiator_spi;
+       this->public.get_responder_spi = (u_int64_t(*)(ike_sa_id_t*)) get_responder_spi;
+       this->public.get_initiator_spi = (u_int64_t(*)(ike_sa_id_t*)) get_initiator_spi;
+       this->public.equals = (status_t(*)(ike_sa_id_t*,ike_sa_id_t*,bool*)) equals;
+       this->public.replace_values = (status_t(*)(ike_sa_id_t*,ike_sa_id_t*)) replace_values;
+
+       this->public.is_initiator = (bool(*)(ike_sa_id_t*)) is_initiator;
+       this->public.switch_initiator = (bool(*)(ike_sa_id_t*)) switch_initiator;
+
+       this->public.clone = (status_t(*)(ike_sa_id_t*,ike_sa_id_t**)) clone;
+       this->public.destroy = (status_t(*)(ike_sa_id_t*))destroy;
+
+       /* private data */
+       this->initiator_spi = initiator_spi;
+       this->responder_spi = responder_spi;
+       this->is_initiator_flag = is_initiator_flag;
+
+       return (&this->public);
+}
diff --git a/Source/charon/sa/ike_sa_id.h b/Source/charon/sa/ike_sa_id.h
new file mode 100644 (file)
index 0000000..f7e0e65
--- /dev/null
@@ -0,0 +1,139 @@
+/**
+ * @file ike_sa_id.h
+ *
+ * @brief Class for identification of an IKE_SA
+ *
+ */
+
+/*
+ * Copyright (C) 2005 Jan Hutter, Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+
+#ifndef IKE_SA_ID_H_
+#define IKE_SA_ID_H_
+
+#include "types.h"
+
+/**
+ * @brief This class is used to identify an IKE_SA.
+ *
+ * An IKE_SA is identified by its initiator and responder spi's.
+ * Additionaly it contains the role of the actual running IKEv2-Daemon
+ * for the specific IKE_SA.
+ */
+typedef struct ike_sa_id_s ike_sa_id_t;
+
+struct ike_sa_id_s {
+
+       /**
+        * @brief Sets the SPI of the responder.
+        *
+        * This function is called when a request or reply of a IKE_SA_INIT is received.
+        *
+        * @param this ike_sa_id_t object
+        * @param responder_spi SPI of responder to set
+        * @return SUCCESSFUL in any case
+        */
+       status_t (*set_responder_spi) (ike_sa_id_t *this, u_int64_t responder_spi);
+
+       /**
+        * @brief Sets the SPI of the initiator.
+        *
+        *
+        * @param this ike_sa_id_t object
+        * @param initiator_spi SPI to set
+        * @return SUCCESSFUL in any case
+        */
+       status_t (*set_initiator_spi) (ike_sa_id_t *this, u_int64_t initiator_spi);
+
+       /**
+        * @brief Returns the initiator spi
+        *
+        * @param this ike_sa_id_t object
+        * @return spi of the initiator
+        */
+       u_int64_t (*get_initiator_spi) (ike_sa_id_t *this);
+
+       /**
+        * @brief Returns the responder spi
+        *
+        * @param this ike_sa_id_t object
+        * @return spi of the responder
+        */
+       u_int64_t (*get_responder_spi) (ike_sa_id_t *this);
+
+       /**
+        * @brief Check if two ike_sa_ids are equal
+        *
+        * @param this ike_sa_id_t object
+        * @param other ike_sa_id object to check if equal
+        * @param are_equal is set to TRUE, if given ike_sa_ids are equal, FALSE otherwise
+        * @return SUCCESSFUL if succeeded, FAILED otherwise
+        */
+       status_t (*equals) (ike_sa_id_t *this,ike_sa_id_t *other, bool *are_equal);
+
+       /**
+        * @brief Replace the values of a given ike_sa_id_t object with values
+        * from another ike_sa_id_t object
+        *
+        * @param this ike_sa_id_t object
+        * @param other ike_sa_id_t object which values will be taken
+        * @return SUCCESSFUL if succeeded, FAILED otherwise
+        */
+       status_t (*replace_values) (ike_sa_id_t *this, ike_sa_id_t *other);
+
+       /**
+        * @brief gets the initiator flag
+        *
+        * @param this ike_sa_id_t object
+        * @return TRUE if we are the original initator
+        */
+       bool (*is_initiator) (ike_sa_id_t *this);
+
+       /**
+        * @brief switches the initiator flag
+        * 
+        * @param this ike_sa_id_t object
+        * @return TRUE if we are the original initator after switch
+        */
+       bool (*switch_initiator) (ike_sa_id_t *this);
+
+       /**
+        * @brief Clones a given ike_sa_id_t object
+        *
+        * @param this ike_sa_id_t object
+        * @param clone_of_this ike_sa_id_t object which will be created
+        * @return SUCCESSFUL if succeeded, FAILED otherwise
+        */
+       status_t (*clone) (ike_sa_id_t *this,ike_sa_id_t **clone_of_this);
+
+       /**
+        * @brief Destroys a ike_sa_id_tobject
+        *
+        * @param this ike_sa_id_t object
+        * @return SUCCESSFUL if succeeded, FAILED otherwise
+        */
+       status_t (*destroy) (ike_sa_id_t *this);
+};
+
+/**
+ * Creates an ike_sa_id_t object with specific spi's and defined role
+ *
+ * @warning The initiator SPI and role is not changeable after initiating a ike_sa_id object
+ */
+
+ike_sa_id_t * ike_sa_id_create(u_int64_t initiator_spi, u_int64_t responder_spi, bool is_initiaor);
+
+#endif /*IKE_SA_ID_H_*/
diff --git a/Source/charon/sa/ike_sa_manager.c b/Source/charon/sa/ike_sa_manager.c
new file mode 100644 (file)
index 0000000..def7d6d
--- /dev/null
@@ -0,0 +1,790 @@
+/**
+ * @file ike_sa_manager.c
+ *
+ * @brief Central point for managing IKE-SAs (creation, locking, deleting...)
+ *
+ */
+
+/*
+ * Copyright (C) 2005 Jan Hutter, Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include <pthread.h>
+#include <string.h>
+
+#include "ike_sa_manager.h"
+
+#include <globals.h>
+#include <sa/ike_sa_id.h>
+#include <utils/allocator.h>
+#include <utils/logger.h>
+#include <utils/logger_manager.h>
+#include <utils/linked_list.h>
+
+/**
+ * @brief An entry in the linked list, contains IKE_SA, locking and lookup data.
+ */
+typedef struct ike_sa_entry_s ike_sa_entry_t;
+struct ike_sa_entry_s {
+       /**
+        * destructor, also destroys ike_sa
+        */
+       status_t (*destroy) (ike_sa_entry_t *this);
+       /**
+        * Number of threads waiting for this ike_sa
+        */
+       int waiting_threads;
+       /**
+        * condvar where threads can wait until it's free again
+        */
+       pthread_cond_t condvar;
+       /**
+        * is this ike_sa currently checked out?
+        */
+       bool checked_out;
+       /**
+        * Does this SA drives out new threads?
+        */
+       bool driveout_new_threads;
+       /**
+        * Does this SA drives out waiting threads?
+        */
+       bool driveout_waiting_threads;
+       /**
+        * identifiaction of ike_sa (SPIs)
+        */
+       ike_sa_id_t *ike_sa_id;
+       /**
+        * the contained ike_sa
+        */
+       ike_sa_t *ike_sa;
+};
+
+/**
+ * @see ike_sa_entry_t.destroy
+ */
+static status_t ike_sa_entry_destroy(ike_sa_entry_t *this)
+{
+       /* also destroy IKE SA */
+       this->ike_sa->destroy(this->ike_sa);
+       this->ike_sa_id->destroy(this->ike_sa_id);
+       allocator_free(this);
+       return SUCCESS;
+}
+
+/**
+ * @brief creates a new entry for the ike_sa list
+ *
+ * This constructor additionaly creates a new and empty SA
+ *
+ * @param ike_sa_id            the associated ike_sa_id_t, will be cloned
+ * @return                             created entry, with ike_sa and ike_sa_id
+ */
+static ike_sa_entry_t *ike_sa_entry_create(ike_sa_id_t *ike_sa_id)
+{
+       ike_sa_entry_t *this = allocator_alloc_thing(ike_sa_entry_t);
+
+       if (this == NULL)
+       {
+               return NULL;
+       }
+
+       /* destroy function */
+       this->destroy = ike_sa_entry_destroy;
+       
+       this->waiting_threads = 0;
+       pthread_cond_init(&(this->condvar), NULL);
+       
+       /* we set checkout flag when we really give it out */
+       this->checked_out = FALSE;
+       this->driveout_new_threads = FALSE;
+       this->driveout_waiting_threads = FALSE;
+       
+       /* ike_sa_id is always cloned */
+       ike_sa_id->clone(ike_sa_id, &(this->ike_sa_id));
+       if (this->ike_sa_id == NULL)
+       {
+               allocator_free(this);   
+               return NULL;
+       }
+       
+       /* create new ike_sa */
+       this->ike_sa = ike_sa_create(ike_sa_id);
+       if (this->ike_sa == NULL)
+       {
+               this->ike_sa_id->destroy(this->ike_sa_id);
+               allocator_free(this);   
+               return NULL;
+               
+       }
+       return this;
+}
+
+/**
+ * Additional private members to ike_sa_manager_t
+ */
+typedef struct private_ike_sa_manager_s private_ike_sa_manager_t;
+struct private_ike_sa_manager_s {
+       /**
+        * Public members
+        */
+        ike_sa_manager_t public;
+
+       /**
+        * @brief get next spi
+        *
+        * we give out SPIs incremental
+        *
+        * @param this                  the ike_sa_manager
+        * @param spi[out]              spi will be written here
+        * @return                              SUCCESS or,
+        *                                              OUT_OF_RES when we already served 2^64 SPIs ;-)
+        */
+        status_t (*get_next_spi) (private_ike_sa_manager_t *this, u_int64_t *spi);
+
+       /**
+        * @brief find the ike_sa_entry in the list by SPIs
+        *
+        * This function simply iterates over the linked list. A hash-table
+        * would be more efficient when storing a lot of IKE_SAs...
+        *
+        * @param this                  the ike_sa_manager containing the list
+        * @param ike_sa_id             id of the ike_sa, containing SPIs
+        * @param entry[out]    pointer to set to the found entry
+        * @return                              
+        *                                              - SUCCESS when found,
+        *                                              - NOT_FOUND when no such ike_sa_id in list
+        *                                              - OUT_OF_RES
+        */
+        status_t (*get_entry_by_id) (private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id, ike_sa_entry_t **entry);
+
+        /**
+        * @brief find the ike_sa_entry in the list by pointer to SA.
+        *
+        * This function simply iterates over the linked list. A hash-table
+        * would be more efficient when storing a lot of IKE_SAs...
+        *
+        * @param this                  the ike_sa_manager containing the list
+        * @param ike_sa                        pointer to the ike_sa
+        * @param entry[out]            pointer to set to the found entry
+        * @return                              
+        *                                              - SUCCESS when found,
+        *                                              - NOT_FOUND when no such ike_sa_id in list
+        *                                              - OUT_OF_RES
+        */
+        status_t (*get_entry_by_sa) (private_ike_sa_manager_t *this, ike_sa_t *ike_sa, ike_sa_entry_t **entry);
+        
+        /**
+         * @brief delete an entry from the linked list
+         *
+         * @param this         the ike_sa_manager containing the list
+         * @param entry                entry to delete
+         * @return                             
+         *                                     - SUCCESS when found,
+         *                                     - NOT_FOUND when no such ike_sa_id in list
+         */
+        status_t (*delete_entry) (private_ike_sa_manager_t *this, ike_sa_entry_t *entry);
+
+        /**
+         * lock for exclusivly accessing the manager
+         */
+        pthread_mutex_t mutex;
+
+        /**
+         * Logger used for this IKE SA Manager
+         */
+        logger_t *logger;
+
+        /**
+         * Linked list with entries for the ike_sa
+         */
+        linked_list_t *ike_sa_list;
+        
+        /**
+         * Next SPI, needed for incremental creation of SPIs
+         */
+        u_int64_t next_spi;
+};
+
+
+/**
+ * @see private_ike_sa_manager_t.get_entry_by_id
+ */
+static status_t get_entry_by_id(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id, ike_sa_entry_t **entry)
+{
+       linked_list_t *list = this->ike_sa_list;
+       linked_list_iterator_t *iterator;
+       status_t status;
+       
+       /* create iterator over list of ike_sa's */
+       status = list->create_iterator(list, &iterator, TRUE);
+       if (status != SUCCESS)
+       {
+               this->logger->log(this->logger,ERROR,"Fatal Error: could not create iterator: %s",mapping_find(status_m,status));
+               /* out of res */
+               return status;
+       }
+       
+       /* default status */
+       status = NOT_FOUND;
+       
+       
+       while (iterator->has_next(iterator))
+       {
+               ike_sa_entry_t *current;
+               bool are_equal = FALSE;
+               
+               iterator->current(iterator, (void**)&current);
+               if (current->ike_sa_id->get_responder_spi(current->ike_sa_id) == 0) {
+                       /* seems to be a half ready ike_sa */
+                       if ((current->ike_sa_id->get_initiator_spi(current->ike_sa_id) == ike_sa_id->get_initiator_spi(ike_sa_id))
+                               && (ike_sa_id->is_initiator(ike_sa_id) == current->ike_sa_id->is_initiator(current->ike_sa_id)))
+                       {
+                               this->logger->log(this->logger,CONTROL | MOST,"Found entry by initiator spi %d",ike_sa_id->get_initiator_spi(ike_sa_id));
+                               *entry = current;
+                               status = SUCCESS;
+                               break;
+                       }
+               }
+               current->ike_sa_id->equals(current->ike_sa_id, ike_sa_id, &are_equal);
+               if (are_equal)
+               {
+                       this->logger->log(this->logger,CONTROL | MOST,"Found entry by full ID");
+                       *entry = current;
+                       status = SUCCESS;
+                       break;
+               }
+       }
+       
+       iterator->destroy(iterator);
+       return status;
+}
+
+/**
+ * @see private_ike_sa_manager_t.get_entry_by_sa
+ */
+static status_t get_entry_by_sa(private_ike_sa_manager_t *this, ike_sa_t *ike_sa, ike_sa_entry_t **entry)
+{
+       linked_list_t *list = this->ike_sa_list;
+       linked_list_iterator_t *iterator;
+       status_t status;
+       
+       status = list->create_iterator(list, &iterator, TRUE);
+       if (status != SUCCESS)
+       {
+               this->logger->log(this->logger,ERROR,"Fatal Error: could not create iterator: %s",mapping_find(status_m,status));
+               return status;
+       }
+       
+       /* default status */
+       status = NOT_FOUND;
+       
+       while (iterator->has_next(iterator))
+       {
+               ike_sa_entry_t *current;
+               iterator->current(iterator, (void**)&current);
+               /* only pointers are compared */
+               if (current->ike_sa == ike_sa)
+               {
+                       this->logger->log(this->logger,CONTROL | MOST,"Found entry by pointer");
+                       *entry = current;
+                       status = SUCCESS;
+                       break;
+               }
+       }
+       iterator->destroy(iterator);
+       return status;
+}
+
+/**
+ * @see private_ike_sa_manager_s.delete_entry
+ */
+static status_t delete_entry(private_ike_sa_manager_t *this, ike_sa_entry_t *entry)
+{
+       linked_list_t *list = this->ike_sa_list;
+       linked_list_iterator_t *iterator;
+       status_t status;
+       
+       status = list->create_iterator(list, &iterator, TRUE);
+       
+       if (status != SUCCESS)
+       {
+               this->logger->log(this->logger,ERROR,"Fatal Error: could not create iterator: %s",mapping_find(status_m,status));
+               return status;
+       }
+
+       status = NOT_FOUND;     
+       
+       while (iterator->has_next(iterator))
+       {
+               ike_sa_entry_t *current;
+               iterator->current(iterator, (void**)&current);
+               if (current == entry) 
+               {
+                       this->logger->log(this->logger,CONTROL | MOST,"Found entry by pointer. Going to delete it.");
+                       list->remove(list, iterator);
+                       entry->destroy(entry);
+                       status = SUCCESS;
+                       break;
+               }
+       }
+       iterator->destroy(iterator);
+       return status;  
+}
+
+
+/**
+ * @see private_ike_sa_manager_t.get_next_spi
+ */
+static status_t get_next_spi(private_ike_sa_manager_t *this, u_int64_t *spi)
+{
+       this->next_spi++;
+       if (this->next_spi == 0) {
+               /* our software ran so incredible stable, we have no more
+                * SPIs to give away :-/.  */
+               this->logger->log(this->logger,CONTROL | MOST,"No more SPI values available. WOW!");
+               return OUT_OF_RES;
+       }
+       *spi = this->next_spi;
+       return SUCCESS;
+}
+
+/**
+ * @see ike_sa_manager_s.checkout_ike_sa
+ */
+static status_t checkout(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id, ike_sa_t **ike_sa)
+{
+       bool responder_spi_set;
+       bool initiator_spi_set;
+       status_t retval;
+
+       /* each access is locked */
+       pthread_mutex_lock(&(this->mutex));
+
+       responder_spi_set = (FALSE != ike_sa_id->get_responder_spi(ike_sa_id));
+       initiator_spi_set = (FALSE != ike_sa_id->get_initiator_spi(ike_sa_id));
+
+       if (initiator_spi_set && responder_spi_set)
+       {
+               /* we SHOULD have an IKE_SA for these SPIs in the list,
+                * if not, we can't handle the request...
+                */
+                ike_sa_entry_t *entry;
+                /* look for the entry */
+                if (this->get_entry_by_id(this, ike_sa_id, &entry) == SUCCESS)
+                {
+                       /* can we give this ike_sa out to new requesters?*/
+                       if (entry->driveout_new_threads)
+                       {
+                               this->logger->log(this->logger,CONTROL|MORE,"Drive out new thread for existing IKE_SA");
+                               /* no we can't */
+                               retval = NOT_FOUND;
+                       }
+                       else
+                       {
+                               /* is this IKE_SA already checked out ?? 
+                                * are we welcome to get this SA ? */
+                               while (entry->checked_out && !entry->driveout_waiting_threads)  
+                               { 
+                                       /* so wait until we can get it for us.
+                                        * we register us as waiting.
+                                        */
+                                       entry->waiting_threads++;
+                                       pthread_cond_wait(&(entry->condvar), &(this->mutex));
+                                       entry->waiting_threads--;
+                               }
+                               
+                               /* hm, a deletion request forbids us to get this SA, go home */
+                               if (entry->driveout_waiting_threads)
+                               {
+                                       /* we must signal here, others are interested that we leave */
+                                       pthread_cond_signal(&(entry->condvar));
+                                       this->logger->log(this->logger,CONTROL|MORE,"Drive out waiting thread for existing IKE_SA");
+                                       retval = NOT_FOUND;
+                               }
+                               else
+                               {
+                                       this->logger->log(this->logger,CONTROL|MOST,"IKE SA successfully checked out");
+                                       /* ok, this IKE_SA is finally ours */
+                                       entry->checked_out = TRUE;
+                                       *ike_sa = entry->ike_sa;
+                                       /* DON'T use return, we must unlock the mutex! */
+                                       retval = SUCCESS; 
+                               }
+                       }
+                }
+                else
+                {
+                       this->logger->log(this->logger,ERROR | MORE,"IKE SA not stored in known IKE_SA list");
+                       /* looks like there is no such IKE_SA, better luck next time... */
+                       /* DON'T use return, we must unlock the mutex! */
+                       retval = NOT_FOUND;
+                }
+       }
+       else if (initiator_spi_set && !responder_spi_set)
+       {
+               /* an IKE_SA_INIT from an another endpoint,
+                * he is the initiator.
+                * For simplicity, we do NOT check for retransmitted
+                * IKE_SA_INIT-Requests here, so EVERY single IKE_SA_INIT-
+                * Request (even a retransmitted one) will result in a
+                * IKE_SA. This could be improved...
+                */
+               u_int64_t responder_spi;
+               ike_sa_entry_t *new_ike_sa_entry;
+               
+
+               /* set SPIs, we are the responder */
+               retval = this->get_next_spi(this, &responder_spi);
+
+               if (retval == SUCCESS)
+               { /* next SPI could be created */
+                       
+                       /* we also set arguments spi, so its still valid */
+                       ike_sa_id->set_responder_spi(ike_sa_id, responder_spi);
+                       
+                       /* create entry */
+                       new_ike_sa_entry = ike_sa_entry_create(ike_sa_id);
+                       if (new_ike_sa_entry != NULL)
+                       { 
+                               retval = this->ike_sa_list->insert_last(this->ike_sa_list, new_ike_sa_entry);
+                               if (retval == SUCCESS)
+                               {
+                                       /* check ike_sa out */
+                                       this->logger->log(this->logger,CONTROL | MORE ,"IKE_SA added to list of known IKE_SA's");
+                                       new_ike_sa_entry->checked_out = TRUE;
+                                       *ike_sa = new_ike_sa_entry->ike_sa;
+                       
+                                        /* DON'T use return, we must unlock the mutex! */
+                               }
+                               else
+                               {
+                                       /* ike_sa_entry could not be added to list*/
+                                       this->logger->log(this->logger,ERROR,"Fatal error: ike_sa_entry could not be added to list");
+                               }                       
+                       }
+                       else
+                       {
+                               /* new ike_sa_entry could not be created */
+                               this->logger->log(this->logger,ERROR,"Fatal error: ike_sa_entry could not be created");                 
+                       }
+               }
+               else
+               { /* next SPI could not be created */
+                       this->logger->log(this->logger,ERROR,"Fatal error: Next SPI could not be created");
+               }
+               
+       }
+       else if (!initiator_spi_set && !responder_spi_set)
+       {
+               /* creation of an IKE_SA from local site,
+                * we are the initiator!
+                */
+               u_int64_t initiator_spi;
+               ike_sa_entry_t *new_ike_sa_entry;
+               
+               retval = this->get_next_spi(this, &initiator_spi);
+               if (retval == SUCCESS)
+               {
+                       /* we also set arguments SPI, so its still valid */
+                       ike_sa_id->set_initiator_spi(ike_sa_id, initiator_spi);
+
+                       /* create entry */
+                       new_ike_sa_entry = ike_sa_entry_create(ike_sa_id);
+                       if (new_ike_sa_entry != NULL)
+                       { 
+                               retval = this->ike_sa_list->insert_last(this->ike_sa_list, new_ike_sa_entry);
+
+                               if (retval == SUCCESS)
+                               {
+                                       /* check ike_sa out */
+                                       this->logger->log(this->logger,CONTROL | MORE ,"New IKE_SA created and added to list of known IKE_SA's");
+                                       new_ike_sa_entry->checked_out = TRUE;
+                                       *ike_sa = new_ike_sa_entry->ike_sa;
+                       
+                                       /* DON'T use return, we must unlock the mutex! */
+                               }
+                               else
+                               {
+                                       /* ike_sa_entry could not be added to list*/
+                                       this->logger->log(this->logger,ERROR,"Fatal error: ike_sa_entry could not be added to list");
+                               }               
+                       }
+                       else
+                       {
+                               /* new ike_sa_entry could not be created */
+                               this->logger->log(this->logger,ERROR,"Fatal error: ike_sa_entry could not be created"); 
+                       }
+               }
+               else
+               {
+                       /* next SPI could not be created */
+                       this->logger->log(this->logger,ERROR,"Fatal error: Next SPI could not be created");
+               }
+
+
+       }
+       else
+       {
+               /* responder set, initiator not: here is something seriously wrong! */
+               this->logger->log(this->logger,ERROR | MORE,"Invalid IKE_SA SPI's");
+               /* DON'T use return, we must unlock the mutex! */
+               retval = INVALID_ARG;
+       }
+
+       pthread_mutex_unlock(&(this->mutex));
+       /* OK, unlocked... */
+       return retval;
+}
+
+/**
+ * Implements ike_sa_manager_t-function checkin.
+ * @see ike_sa_manager_t.checkin.
+ */
+static status_t checkin(private_ike_sa_manager_t *this, ike_sa_t *ike_sa)
+{
+       /* to check the SA back in, we look for the pointer of the ike_sa
+        * in all entries.
+        * We can't search by SPI's since the MAY have changed (e.g. on reception
+        * of a IKE_SA_INIT response). Updating of the SPI MAY be necessary...
+        */
+       status_t retval;
+       ike_sa_entry_t *entry;
+       
+       pthread_mutex_lock(&(this->mutex));
+
+       /* look for the entry */
+       if (this->get_entry_by_sa(this, ike_sa, &entry) == SUCCESS)
+       {
+               /* ike_sa_id must be updated */
+               entry->ike_sa_id->replace_values(entry->ike_sa_id, ike_sa->get_id(ike_sa));
+               /* signal waiting threads */
+               entry->checked_out = FALSE;
+               this->logger->log(this->logger,CONTROL | MORE,"Checkin of IKE_SA successful.");
+               pthread_cond_signal(&(entry->condvar));
+               retval = SUCCESS;
+       }
+       else
+       {
+               this->logger->log(this->logger,ERROR,"Fatal Error: Tried to checkin nonexisting IKE_SA");
+               /* this SA is no more, this REALLY should not happen */
+               retval = NOT_FOUND;
+       }
+       pthread_mutex_unlock(&(this->mutex));
+       return retval;
+}
+
+
+/**
+ * Implements ike_sa_manager_t-function checkin_and_delete.
+ * @see ike_sa_manager_t.checkin_and_delete.
+ */
+static status_t checkin_and_delete(private_ike_sa_manager_t *this, ike_sa_t *ike_sa)
+{
+       /* deletion is a bit complex, we must garant that no thread is waiting for
+        * this SA.
+        * We take this SA from the list, and start signaling while threads
+        * are in the condvar.
+        */
+       ike_sa_entry_t *entry;
+       status_t retval;
+
+       pthread_mutex_lock(&(this->mutex));
+
+       if (this->get_entry_by_sa(this, ike_sa, &entry) == SUCCESS)
+       {
+               /* mark it, so now new threads can acquire this SA */
+               entry->driveout_new_threads = TRUE;
+               /* additionaly, drive out waiting threads */
+               entry->driveout_waiting_threads = TRUE;
+
+               /* wait until all workers have done their work */
+               while (entry->waiting_threads > 0)
+               {
+                       /* let the other threads do some work*/
+                       pthread_cond_signal(&(entry->condvar));
+                       /* and the nice thing, they will wake us again when their work is done */
+                       pthread_cond_wait(&(entry->condvar), &(this->mutex));
+               }
+               /* ok, we are alone now, no threads waiting in the entry's condvar */
+               this->delete_entry(this, entry);
+               this->logger->log(this->logger,CONTROL | MORE,"Checkin and delete of IKE_SA successful");
+               retval = SUCCESS;
+       }
+       else
+       {
+               this->logger->log(this->logger,ERROR,"Fatal Error: Tried to checkin and delete nonexisting IKE_SA");
+               retval = NOT_FOUND;
+       }
+
+       pthread_mutex_unlock(&(this->mutex));
+       return retval;
+}
+
+/**
+ * Implements ike_sa_manager_t-function delete.
+ * @see ike_sa_manager_t.delete.
+ */
+static status_t delete(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id)
+{
+       /* deletion is a bit complex, we must garant that no thread is waiting for
+        * this SA.
+        * We take this SA from the list, and start signaling while threads
+        * are in the condvar.
+        */
+       ike_sa_entry_t *entry;
+       status_t retval;
+
+       pthread_mutex_lock(&(this->mutex));
+
+       if (this->get_entry_by_id(this, ike_sa_id, &entry) == SUCCESS)
+       {
+               /* mark it, so now new threads can acquire this SA */
+               entry->driveout_new_threads = TRUE;
+
+               /* wait until all workers have done their work */
+               while (entry->waiting_threads)
+               {
+                       /* wake up all */
+                       pthread_cond_signal(&(entry->condvar));
+                       /* and the nice thing, they will wake us again when their work is done */
+                       pthread_cond_wait(&(entry->condvar), &(this->mutex));
+               }
+               /* ok, we are alone now, no threads waiting in the entry's condvar */
+               this->delete_entry(this, entry);
+               this->logger->log(this->logger,CONTROL | MORE,"Delete of IKE_SA successful");
+               retval = SUCCESS;
+       }
+       else
+       {
+               this->logger->log(this->logger,ERROR,"Fatal Error: Tried to delete nonexisting IKE_SA");
+               retval = NOT_FOUND;
+       }
+
+       pthread_mutex_unlock(&(this->mutex));
+       return retval;
+}
+
+/**
+ * Implements ike_sa_manager_t-function destroy.
+ * @see ike_sa_manager_t.destroy.
+ */
+static status_t destroy(private_ike_sa_manager_t *this)
+{
+       /* destroy all list entries */
+       linked_list_t *list = this->ike_sa_list;
+       linked_list_iterator_t *iterator;
+       status_t status;
+       ike_sa_entry_t *entry;
+       
+       pthread_mutex_lock(&(this->mutex));
+       
+       this->logger->log(this->logger,CONTROL | MORE,"Going to destroy IKE_SA manager and all managed IKE_SA's");
+       
+       /* Step 1: drive out all waiting threads  */
+       status = list->create_iterator(list, &iterator, TRUE);
+       
+       if (status != SUCCESS)
+       {
+               this->logger->log(this->logger,ERROR,"Fatal Error: Create of iterator while destroying IKE_SA-Manager failed");
+               return FAILED;
+       }
+
+       this->logger->log(this->logger,CONTROL | MOST,"Set driveout flags for all stored IKE_SA's");
+       while (iterator->has_next(iterator))
+       {
+               iterator->current(iterator, (void**)&entry);
+               /* do not accept new threads, drive out waiting threads */
+               entry->driveout_new_threads = TRUE;
+               entry->driveout_waiting_threads = TRUE; 
+       }
+
+       this->logger->log(this->logger,CONTROL | MOST,"Wait for all threads to leave IKE_SA's");
+       /* Step 2: wait until all are gone */
+       iterator->reset(iterator);
+       while (iterator->has_next(iterator))
+       {
+               iterator->current(iterator, (void**)&entry);
+               while (entry->waiting_threads)
+               {
+                       /* wake up all */
+                       pthread_cond_signal(&(entry->condvar));
+                       /* go sleeping until they are gone */
+                       pthread_cond_wait(&(entry->condvar), &(this->mutex));           
+               }
+       }
+       this->logger->log(this->logger,CONTROL | MOST,"Delete all IKE_SA's");
+       /* Step 3: delete all entries */
+       iterator->destroy(iterator);
+
+       while (list->get_count(list) > 0)
+       {
+               list->get_first(list, (void**)&entry);
+               this->delete_entry(this, entry);
+       }
+       list->destroy(list);
+       this->logger->log(this->logger,CONTROL | MOST,"IKE_SA's deleted");
+       pthread_mutex_unlock(&(this->mutex));
+
+       /* destroy logger at end */
+       global_logger_manager->destroy_logger(global_logger_manager,this->logger);
+
+       allocator_free(this);
+       
+       return SUCCESS;
+}
+
+/*
+ * Described in header
+ */
+ike_sa_manager_t *ike_sa_manager_create()
+{
+       private_ike_sa_manager_t *this = allocator_alloc_thing(private_ike_sa_manager_t);
+
+       /* assign public functions */
+       this->public.destroy = (status_t(*)(ike_sa_manager_t*))destroy;
+       this->public.checkout = (status_t(*)(ike_sa_manager_t*, ike_sa_id_t *sa_id, ike_sa_t **sa))checkout;
+       this->public.checkin = (status_t(*)(ike_sa_manager_t*, ike_sa_t *sa))checkin;
+       this->public.delete = (status_t(*)(ike_sa_manager_t*, ike_sa_id_t *sa_id))delete;
+       this->public.checkin_and_delete = (status_t(*)(ike_sa_manager_t*, ike_sa_t *ike_sa))checkin_and_delete;
+
+       /* initialize private functions */
+       this->get_next_spi = get_next_spi;
+       this->get_entry_by_sa = get_entry_by_sa;
+       this->get_entry_by_id = get_entry_by_id;
+       this->delete_entry = delete_entry;
+
+       /* initialize private variables */
+       this->logger = global_logger_manager->create_logger(global_logger_manager,IKE_SA_MANAGER,NULL);
+       if (this->logger == NULL)
+       {
+               allocator_free(this);
+               return NULL;
+       }
+       
+       this->ike_sa_list = linked_list_create();
+       if (this->ike_sa_list == NULL)
+       {
+               this->logger->log(this->logger,ERROR,"Fatal error: Failed to create list for managed IKE_SA");
+               global_logger_manager->destroy_logger(global_logger_manager,this->logger);
+               allocator_free(this);
+               return NULL;
+       }
+
+       pthread_mutex_init(&(this->mutex), NULL);
+
+       this->next_spi = 0;
+
+       return (ike_sa_manager_t*)this;
+}
diff --git a/Source/charon/sa/ike_sa_manager.h b/Source/charon/sa/ike_sa_manager.h
new file mode 100644 (file)
index 0000000..25d6c4c
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @file ike_sa_manager.h
+ * 
+ * @brief Central point for managing IKE-SAs (creation, locking, deleting...)
+ * 
+ */
+
+/*
+ * Copyright (C) 2005 Jan Hutter, Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef IKE_SA_MANAGER_H_
+#define IKE_SA_MANAGER_H_
+
+#include <types.h>
+#include <sa/ike_sa.h>
+
+
+/**
+ * @brief The IKE_SA-Manager manages the IKE_SAs ;-). 
+ * 
+ * To avoid access from multiple threads, IKE_SAs must be checked out from
+ * the manager, and checked back in after usage. 
+ * The manager also handles deletion of SAs.
+ * 
+ * @todo checking of double-checkouts from the same threads would be nice.
+ * This could be by comparing thread-ids via pthread_self()...
+ * 
+ */
+typedef struct ike_sa_manager_s ike_sa_manager_t;
+struct ike_sa_manager_s {
+       /**
+        * @brief Checkout an IKE_SA, create it when necesarry
+        * 
+        * Checks out a SA by its ID. An SA will be created, when:
+        * - Responder SPI is not set (when received an IKE_SA_INIT from initiator)
+        * - Both SPIs are not set (for initiating IKE_SA_INIT)
+        * Management of SPIs is the managers job, he will set it.
+        * This function blocks until SA is available for checkout.
+        * 
+        * @warning checking out two times without checking in will
+        * result in a deadlock!
+        * 
+        * @param ike_sa_manager        the manager object
+        * @param ike_sa_id[in/out]     the SA identifier, will be updated
+        * @param ike_sa[out]           checked out SA
+        * @returns                                     
+        *                                                      - SUCCESS if checkout successful
+        *                                                      - NOT_FOUND when no such SA is available
+        *                                                      - OUT_OF_RES
+        */
+       status_t (*checkout) (ike_sa_manager_t* ike_sa_manager, ike_sa_id_t *sa_id, ike_sa_t **ike_sa);
+       /**
+        * @brief Checkin the SA after usage
+        * 
+        * @warning the SA pointer MUST NOT be used after checkin! The SA must be checked
+        * out again!
+        *  
+        * @param ike_sa_manager        the manager object
+        * @param ike_sa_id[in/out]     the SA identifier, will be updated
+        * @param ike_sa[out]           checked out SA
+        * @returns                             SUCCESS if checked in
+        *                                                      NOT_FOUND when not found (shouldn't happen!)
+        */
+       status_t (*checkin) (ike_sa_manager_t* ike_sa_manager, ike_sa_t *ike_sa);
+       /**
+        * @brief delete a SA, wich was not checked out
+        * 
+        * @warning do not use this when the SA is already checked out, this will
+        * deadlock!
+        *  
+        * @param ike_sa_manager        the manager object
+        * @param ike_sa_id[in/out]     the SA identifier
+        * @returns                             SUCCESS if found
+        *                                                      NOT_FOUND when no such SA is available
+        */
+       status_t (*delete) (ike_sa_manager_t* ike_sa_manager, ike_sa_id_t *ike_sa_id);
+       /**
+        * @brief delete a checked out SA
+        *  
+        * @param ike_sa_manager        the manager object
+        * @param ike_sa                        SA to delete
+        * @returns                             SUCCESS if found
+        *                                                      NOT_FOUND when no such SA is available
+        */
+       status_t (*checkin_and_delete) (ike_sa_manager_t* ike_sa_manager, ike_sa_t *ike_sa);
+       
+       /**
+        * @brief Destroys the manager with all associated SAs
+        * 
+        * Threads will be driven out, so all SAs can be deleted cleanly
+        * 
+        * @param ike_sa_manager the manager object
+        * @returns SUCCESS if succeeded, FAILED otherwise
+        */
+       status_t (*destroy) (ike_sa_manager_t *ike_sa_manager);
+};
+
+/**
+ * @brief Create a manager
+ * 
+ * @returns the manager
+ */
+ike_sa_manager_t *ike_sa_manager_create();
+
+#endif /*IKE_SA_MANAGER_H_*/
index e0a0e7a..7864c98 100644 (file)
@@ -22,7 +22,7 @@
  
 #include "ike_sa_id_test.h"
 
-#include <ike_sa_id.h>
+#include <sa/ike_sa_id.h>
 
 /* 
  * described in Header-File
index c54f551..df6f034 100644 (file)
@@ -27,7 +27,7 @@
 #include "ike_sa_manager_test.h"
 
 #include <types.h>
-#include <ike_sa_manager.h>
+#include <sa/ike_sa_manager.h>
 
 
 static struct ike_sa_manager_test_struct_s {
index 68c6e84..0d8d9c6 100644 (file)
@@ -24,7 +24,7 @@
 
 #include <types.h>
 #include <encoding/message.h>
-#include <ike_sa.h>
+#include <sa/ike_sa.h>
 
 void test_ike_sa(tester_t *tester)
 {