From 8b5be79d8330dcd9497af227b1360d6674914412 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Tue, 23 May 2006 13:25:57 +0000 Subject: [PATCH] - show connection templates in status & statusall - don't complain on termination of IKEv1 connections --- .../config/connections/connection_store.h | 18 ++++++ .../connections/local_connection_store.c | 37 ++++++++++++ src/charon/sa/child_sa.c | 4 +- src/charon/sa/ike_sa.c | 4 +- src/charon/sa/ike_sa_manager.c | 2 + src/charon/threads/stroke_interface.c | 58 ++++++++++++++----- 6 files changed, 106 insertions(+), 17 deletions(-) diff --git a/src/charon/config/connections/connection_store.h b/src/charon/config/connections/connection_store.h index 41fd58e42..acdfa5430 100755 --- a/src/charon/config/connections/connection_store.h +++ b/src/charon/config/connections/connection_store.h @@ -25,6 +25,7 @@ #include #include +#include typedef struct connection_store_t connection_store_t; @@ -101,6 +102,23 @@ struct connection_store_t { */ status_t (*add_connection) (connection_store_t *this, connection_t *connection); + /** + * @brief Log the connections stored in the store. + * + * Depending on the implementation of the store, the store + * logs various information to the specified logger. + * If logger is NULL, the internal logger is used, if name is + * NULL, all connections are logged + * + * @param this calling object + * @param logger logger to use for the log, or NULL + * @param name name of the connection, or NULL + * @return + * - SUCCESS, or + * - FAILED + */ + void (*log_connections) (connection_store_t *this, logger_t *logger, char *name); + /** * @brief Destroys a connection_store_t object. * diff --git a/src/charon/config/connections/local_connection_store.c b/src/charon/config/connections/local_connection_store.c index a7e4d18f1..e7a93414c 100644 --- a/src/charon/config/connections/local_connection_store.c +++ b/src/charon/config/connections/local_connection_store.c @@ -207,6 +207,42 @@ static status_t add_connection(private_local_connection_store_t *this, connectio return SUCCESS; } +/** + * Implementation of connection_store_t.log_connections. + */ +void log_connections(private_local_connection_store_t *this, logger_t *logger, char *name) +{ + iterator_t *iterator; + connection_t *current, *found = NULL; + + if (logger == NULL) + { + logger = this->logger; + } + + logger->log(logger, CONTROL, "templates:"); + + iterator = this->connections->create_iterator(this->connections, TRUE); + while (iterator->has_next(iterator)) + { + iterator->current(iterator, (void**)¤t); + if (!name || strcmp(name, current->get_name(current)) == 0) + { + identification_t *my_id, *other_id; + host_t *my_host, *other_host; + my_id = current->get_my_id(current); + other_id = current->get_other_id(current); + my_host = current->get_my_host(current); + other_host = current->get_other_host(current); + logger->log(logger, CONTROL, " \"%s\": %s[%s]...%s[%s]", + current->get_name(current), + my_host->get_address(my_host), my_id->get_string(my_id), + other_host->get_address(other_host), other_id->get_string(other_id)); + } + } + iterator->destroy(iterator); +} + /** * Implementation of connection_store_t.destroy. */ @@ -233,6 +269,7 @@ local_connection_store_t * local_connection_store_create(void) this->public.connection_store.get_connection_by_ids = (connection_t*(*)(connection_store_t*,identification_t*,identification_t*))get_connection_by_ids; this->public.connection_store.get_connection_by_name = (connection_t*(*)(connection_store_t*,char*))get_connection_by_name; this->public.connection_store.add_connection = (status_t(*)(connection_store_t*,connection_t*))add_connection; + this->public.connection_store.log_connections = (void(*)(connection_store_t*,logger_t*,char*))log_connections; this->public.connection_store.destroy = (void(*)(connection_store_t*))destroy; /* private variables */ diff --git a/src/charon/sa/child_sa.c b/src/charon/sa/child_sa.c index 90cd0014a..5bb895e7f 100644 --- a/src/charon/sa/child_sa.c +++ b/src/charon/sa/child_sa.c @@ -479,7 +479,7 @@ static void log_status(private_child_sa_t *this, logger_t *logger, char* name) { logger = this->logger; } - logger->log(logger, CONTROL|LEVEL1, "\"%s\": protected with ESP (0x%x/0x%x), AH (0x%x,0x%x):", + logger->log(logger, CONTROL|LEVEL1, " \"%s\": protected with ESP (0x%x/0x%x), AH (0x%x,0x%x):", name, htonl(this->my_esp_spi), htonl(this->other_esp_spi), htonl(this->my_ah_spi), htonl(this->other_ah_spi)); @@ -499,7 +499,7 @@ static void log_status(private_child_sa_t *this, logger_t *logger, char* name) snprintf(proto_buf, sizeof(proto_buf), "<%d>", policy->upper_proto); } } - logger->log(logger, CONTROL, "\"%s\": %s/%d==%s==%s/%d", + logger->log(logger, CONTROL, " \"%s\": %s/%d==%s==%s/%d", name, policy->my_net->get_address(policy->my_net), policy->my_net_mask, proto_name, diff --git a/src/charon/sa/ike_sa.c b/src/charon/sa/ike_sa.c index c012ce82b..8bc03d141 100644 --- a/src/charon/sa/ike_sa.c +++ b/src/charon/sa/ike_sa.c @@ -944,12 +944,12 @@ static void log_status(private_ike_sa_t *this, logger_t *logger, char *name) { logger = this->logger; } - logger->log(logger, CONTROL|LEVEL1, "\"%s\": IKE_SA in state %s, SPIs: 0x%.16llx 0x%.16llx", + logger->log(logger, CONTROL|LEVEL1, " \"%s\": IKE_SA in state %s, SPIs: 0x%.16llx 0x%.16llx", name, mapping_find(ike_sa_state_m, this->current_state->get_state(this->current_state)), this->ike_sa_id->get_initiator_spi(this->ike_sa_id), this->ike_sa_id->get_responder_spi(this->ike_sa_id)); - logger->log(logger, CONTROL, "\"%s\": %s[%s]...%s[%s]", + logger->log(logger, CONTROL, " \"%s\": %s[%s]...%s[%s]", name, my_host->get_address(my_host), my_id->get_string(my_id), diff --git a/src/charon/sa/ike_sa_manager.c b/src/charon/sa/ike_sa_manager.c index 475898e26..2d53ba15b 100644 --- a/src/charon/sa/ike_sa_manager.c +++ b/src/charon/sa/ike_sa_manager.c @@ -610,6 +610,8 @@ static void log_status(private_ike_sa_manager_t* this, logger_t* logger, char* n { iterator_t *iterator; + logger->log(logger, CONTROL, "instances:"); + pthread_mutex_lock(&(this->mutex)); iterator = this->ike_sa_list->create_iterator(this->ike_sa_list, TRUE); diff --git a/src/charon/threads/stroke_interface.c b/src/charon/threads/stroke_interface.c index 57c5f4ded..9d9fb36b3 100755 --- a/src/charon/threads/stroke_interface.c +++ b/src/charon/threads/stroke_interface.c @@ -329,7 +329,7 @@ static void stroke_initiate(private_stroke_t *this, stroke_msg_t *msg) { this->stroke_logger->log(this->stroke_logger, ERROR, "no connection named \"%s\"", msg->initiate.name); } - /* only initiate if it is an ikev2 connection */ + /* only initiate if it is an IKEv2 connection, ignore IKEv1 */ else if (connection->is_ikev2(connection)) { job = initiate_ike_sa_job_create(connection); @@ -345,24 +345,55 @@ static void stroke_terminate(private_stroke_t *this, stroke_msg_t *msg) linked_list_t *ike_sas; iterator_t *iterator; int instances = 0; + connection_t *conn; pop_string(msg, &(msg->terminate.name)); this->logger->log(this->logger, CONTROL, "received stroke: terminate \"%s\"", msg->terminate.name); - ike_sas = charon->ike_sa_manager->get_ike_sa_list_by_name(charon->ike_sa_manager, msg->terminate.name); - - iterator = ike_sas->create_iterator(ike_sas, TRUE); - while (iterator->has_next(iterator)) + /* we have to do tricky tricks to give the most comprehensive output to the user. + * There are different cases: + * 1. Connection is available, but IKEv1: + * => just ignore it, let pluto print it + * 2. Connection is not available, but instances of a deleted connection template: + * => terminate them, and print their termination + * 3. Connection is not available, and and no instances are there: + * => show error about bad connection name + * 4. An IKEv2 connection is available, and may contain instances: + * => terminate and print, simple + */ + conn = charon->connections->get_connection_by_name(charon->connections, msg->terminate.name); + if (conn == NULL || conn->is_ikev2(conn)) { - ike_sa_id_t *ike_sa_id; - iterator->current(iterator, (void**)&ike_sa_id); - charon->ike_sa_manager->delete(charon->ike_sa_manager, ike_sa_id); - ike_sa_id->destroy(ike_sa_id); - instances++; + ike_sas = charon->ike_sa_manager->get_ike_sa_list_by_name(charon->ike_sa_manager, msg->terminate.name); + + iterator = ike_sas->create_iterator(ike_sas, TRUE); + while (iterator->has_next(iterator)) + { + ike_sa_id_t *ike_sa_id; + iterator->current(iterator, (void**)&ike_sa_id); + charon->ike_sa_manager->delete(charon->ike_sa_manager, ike_sa_id); + ike_sa_id->destroy(ike_sa_id); + instances++; + } + iterator->destroy(iterator); + ike_sas->destroy(ike_sas); + if (conn == NULL && instances == 0) + { + this->stroke_logger->log(this->stroke_logger, CONTROL, + "no connection named \"%s\"", + msg->terminate.name); + } + else + { + this->stroke_logger->log(this->stroke_logger, CONTROL, + "terminated %d instances of \"%s\"", + instances, msg->terminate.name); + } + } + if (conn) + { + conn->destroy(conn); } - iterator->destroy(iterator); - ike_sas->destroy(ike_sas); - this->stroke_logger->log(this->stroke_logger, CONTROL, "terminated %d instances of %s", instances, msg->terminate.name); } /** @@ -374,6 +405,7 @@ static void stroke_status(private_stroke_t *this, stroke_msg_t *msg) { pop_string(msg, &(msg->status.name)); } + charon->connections->log_connections(charon->connections, this->stroke_logger, msg->status.name); charon->ike_sa_manager->log_status(charon->ike_sa_manager, this->stroke_logger, msg->status.name); }