aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libcharon/network/socket.h21
-rw-r--r--src/libcharon/network/socket_manager.c63
-rw-r--r--src/libcharon/network/socket_manager.h14
-rw-r--r--src/libcharon/plugins/socket_default/socket_default_plugin.c19
-rw-r--r--src/libcharon/plugins/socket_default/socket_default_socket.c6
-rw-r--r--src/libcharon/plugins/socket_default/socket_default_socket.h4
-rw-r--r--src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c19
-rw-r--r--src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c6
-rw-r--r--src/libcharon/plugins/socket_raw/socket_raw_plugin.c19
-rw-r--r--src/libcharon/plugins/socket_raw/socket_raw_socket.c7
-rw-r--r--src/libcharon/plugins/socket_raw/socket_raw_socket.h4
11 files changed, 104 insertions, 78 deletions
diff --git a/src/libcharon/network/socket.h b/src/libcharon/network/socket.h
index 5c5a4edfb..51b26920f 100644
--- a/src/libcharon/network/socket.h
+++ b/src/libcharon/network/socket.h
@@ -1,6 +1,7 @@
/*
- * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
+ * Copyright (C) 2006-2010 Tobias Brunner
* Copyright (C) 2005-2010 Martin Willi
+ * Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -30,6 +31,11 @@ typedef struct socket_t socket_t;
#include <utils/enumerator.h>
/**
+ * Constructor prototype for sockets.
+ */
+typedef socket_t *(*socket_constructor_t)();
+
+/**
* Socket interface definition.
*/
struct socket_t {
@@ -42,8 +48,8 @@ struct socket_t {
*
* @param packet pinter gets address from allocated packet_t
* @return
- * - SUCCESS when packet successfully received
- * - FAILED when unable to receive
+ * - SUCCESS when packet successfully received
+ * - FAILED when unable to receive
*/
status_t (*receive) (socket_t *this, packet_t **packet);
@@ -55,10 +61,15 @@ struct socket_t {
*
* @param packet packet_t to send
* @return
- * - SUCCESS when packet successfully sent
- * - FAILED when unable to send
+ * - SUCCESS when packet successfully sent
+ * - FAILED when unable to send
*/
status_t (*send) (socket_t *this, packet_t *packet);
+
+ /**
+ * Destroy a socket implementation.
+ */
+ void (*destroy) (socket_t *this);
};
#endif /** SOCKET_H_ @}*/
diff --git a/src/libcharon/network/socket_manager.c b/src/libcharon/network/socket_manager.c
index 0dbce4b1b..72a454301 100644
--- a/src/libcharon/network/socket_manager.c
+++ b/src/libcharon/network/socket_manager.c
@@ -1,4 +1,6 @@
/*
+ * Copyright (C) 2010 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
* Copyright (C) 2010 Martin Willi
* Copyright (C) 2010 revosec AG
*
@@ -33,11 +35,21 @@ struct private_socket_manager_t {
socket_manager_t public;
/**
- * List of registered socket
+ * List of registered socket constructors
*/
linked_list_t *sockets;
/**
+ * Instantiated socket implementation
+ */
+ socket_t *socket;
+
+ /**
+ * The constructor used to create the current socket
+ */
+ socket_constructor_t create;
+
+ /**
* Lock for sockets list
*/
rwlock_t *lock;
@@ -46,11 +58,9 @@ struct private_socket_manager_t {
METHOD(socket_manager_t, receiver, status_t,
private_socket_manager_t *this, packet_t **packet)
{
- socket_t *socket;
status_t status;
-
this->lock->read_lock(this->lock);
- if (this->sockets->get_first(this->sockets, (void**)&socket) != SUCCESS)
+ if (!this->socket)
{
DBG1(DBG_NET, "no socket implementation registered, receiving failed");
this->lock->unlock(this->lock);
@@ -58,7 +68,7 @@ METHOD(socket_manager_t, receiver, status_t,
}
/* receive is blocking and the thread can be cancelled */
thread_cleanup_push((thread_cleanup_t)this->lock->unlock, this->lock);
- status = socket->receive(socket, packet);
+ status = this->socket->receive(this->socket, packet);
thread_cleanup_pop(TRUE);
return status;
}
@@ -66,40 +76,67 @@ METHOD(socket_manager_t, receiver, status_t,
METHOD(socket_manager_t, sender, status_t,
private_socket_manager_t *this, packet_t *packet)
{
- socket_t *socket;
status_t status;
-
this->lock->read_lock(this->lock);
- if (this->sockets->get_first(this->sockets, (void**)&socket) != SUCCESS)
+ if (!this->socket)
{
DBG1(DBG_NET, "no socket implementation registered, sending failed");
this->lock->unlock(this->lock);
return NOT_SUPPORTED;
}
- status = socket->send(socket, packet);
+ status = this->socket->send(this->socket, packet);
this->lock->unlock(this->lock);
return status;
}
+static void create_socket(private_socket_manager_t *this)
+{
+ socket_constructor_t create;
+ /* remove constructors in order to avoid trying to create broken ones
+ * multiple times */
+ while (this->sockets->remove_first(this->sockets,
+ (void**)&create) == SUCCESS)
+ {
+ this->socket = create();
+ if (this->socket)
+ {
+ this->create = create;
+ break;
+ }
+ }
+}
+
METHOD(socket_manager_t, add_socket, void,
- private_socket_manager_t *this, socket_t *socket)
+ private_socket_manager_t *this, socket_constructor_t create)
{
this->lock->write_lock(this->lock);
- this->sockets->insert_last(this->sockets, socket);
+ this->sockets->insert_last(this->sockets, create);
+ if (!this->socket)
+ {
+ create_socket(this);
+ }
this->lock->unlock(this->lock);
}
METHOD(socket_manager_t, remove_socket, void,
- private_socket_manager_t *this, socket_t *socket)
+ private_socket_manager_t *this, socket_constructor_t create)
{
this->lock->write_lock(this->lock);
- this->sockets->remove(this->sockets, socket, NULL);
+ this->sockets->remove(this->sockets, create, NULL);
+ if (this->create == create)
+ {
+ this->socket->destroy(this->socket);
+ this->socket = NULL;
+ this->create = NULL;
+ create_socket(this);
+ }
this->lock->unlock(this->lock);
}
METHOD(socket_manager_t, destroy, void,
private_socket_manager_t *this)
{
+ DESTROY_IF(this->socket);
this->sockets->destroy(this->sockets);
this->lock->destroy(this->lock);
free(this);
diff --git a/src/libcharon/network/socket_manager.h b/src/libcharon/network/socket_manager.h
index b33d5c71c..94185d21c 100644
--- a/src/libcharon/network/socket_manager.h
+++ b/src/libcharon/network/socket_manager.h
@@ -1,4 +1,6 @@
/*
+ * Copyright (C) 2010 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
* Copyright (C) 2010 Martin Willi
* Copyright (C) 2010 revosec AG
*
@@ -51,14 +53,18 @@ struct socket_manager_t {
status_t (*send) (socket_manager_t *this, packet_t *packet);
/**
- * Register a socket implementation.
+ * Register a socket constructor.
+ *
+ * @param create constructor for the socket
*/
- void (*add_socket)(socket_manager_t *this, socket_t *socket);
+ void (*add_socket)(socket_manager_t *this, socket_constructor_t create);
/**
- * Unregister a registered socket implementation.
+ * Unregister a registered socket constructor.
+ *
+ * @param create constructor for the socket
*/
- void (*remove_socket)(socket_manager_t *this, socket_t *socket);
+ void (*remove_socket)(socket_manager_t *this, socket_constructor_t create);
/**
* Destroy a socket_manager_t.
diff --git a/src/libcharon/plugins/socket_default/socket_default_plugin.c b/src/libcharon/plugins/socket_default/socket_default_plugin.c
index 29549b0b1..b5dea68b6 100644
--- a/src/libcharon/plugins/socket_default/socket_default_plugin.c
+++ b/src/libcharon/plugins/socket_default/socket_default_plugin.c
@@ -1,4 +1,6 @@
/*
+ * Copyright (C) 2010 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
* Copyright (C) 2010 Martin Willi
* Copyright (C) 2010 revosec AG
*
@@ -31,17 +33,13 @@ struct private_socket_default_plugin_t {
*/
socket_default_plugin_t public;
- /**
- * Socket instance.
- */
- socket_default_socket_t *socket;
};
METHOD(plugin_t, destroy, void,
private_socket_default_plugin_t *this)
{
- charon->socket->remove_socket(charon->socket, &this->socket->socket);
- this->socket->destroy(this->socket);
+ charon->socket->remove_socket(charon->socket,
+ (socket_constructor_t)socket_default_socket_create);
free(this);
}
@@ -58,15 +56,10 @@ plugin_t *socket_default_plugin_create()
.destroy = _destroy,
},
},
- .socket = socket_default_socket_create(),
);
- if (!this->socket)
- {
- free(this);
- return NULL;
- }
- charon->socket->add_socket(charon->socket, &this->socket->socket);
+ charon->socket->add_socket(charon->socket,
+ (socket_constructor_t)socket_default_socket_create);
return &this->public.plugin;
}
diff --git a/src/libcharon/plugins/socket_default/socket_default_socket.c b/src/libcharon/plugins/socket_default/socket_default_socket.c
index 983481808..e95646643 100644
--- a/src/libcharon/plugins/socket_default/socket_default_socket.c
+++ b/src/libcharon/plugins/socket_default/socket_default_socket.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2009 Tobias Brunner
+ * Copyright (C) 2006-2010 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2010 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -546,7 +546,7 @@ static int open_socket(private_socket_default_socket_t *this,
return skt;
}
-METHOD(socket_default_socket_t, destroy, void,
+METHOD(socket_t, destroy, void,
private_socket_default_socket_t *this)
{
if (this->ipv4)
@@ -580,8 +580,8 @@ socket_default_socket_t *socket_default_socket_create()
.socket = {
.send = _sender,
.receive = _receiver,
+ .destroy = _destroy,
},
- .destroy = _destroy,
},
.max_packet = lib->settings->get_int(lib->settings,
"charon.max_packet", MAX_PACKET),
diff --git a/src/libcharon/plugins/socket_default/socket_default_socket.h b/src/libcharon/plugins/socket_default/socket_default_socket.h
index 755016662..89aa6f435 100644
--- a/src/libcharon/plugins/socket_default/socket_default_socket.h
+++ b/src/libcharon/plugins/socket_default/socket_default_socket.h
@@ -35,10 +35,6 @@ struct socket_default_socket_t {
*/
socket_t socket;
- /**
- * Destroy a socket_default_socket_t.
- */
- void (*destroy)(socket_default_socket_t *this);
};
/**
diff --git a/src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c b/src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c
index eb3cbb9d6..a6ff14efd 100644
--- a/src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c
+++ b/src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c
@@ -1,4 +1,6 @@
/*
+ * Copyright (C) 2010 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
* Copyright (C) 2010 Martin Willi
* Copyright (C) 2010 revosec AG
*
@@ -31,17 +33,13 @@ struct private_socket_dynamic_plugin_t {
*/
socket_dynamic_plugin_t public;
- /**
- * Socket instance.
- */
- socket_dynamic_socket_t *socket;
};
METHOD(plugin_t, destroy, void,
private_socket_dynamic_plugin_t *this)
{
- charon->socket->remove_socket(charon->socket, &this->socket->socket);
- this->socket->destroy(this->socket);
+ charon->socket->remove_socket(charon->socket,
+ (socket_constructor_t)socket_dynamic_socket_create);
free(this);
}
@@ -58,15 +56,10 @@ plugin_t *socket_dynamic_plugin_create()
.destroy = _destroy,
},
},
- .socket = socket_dynamic_socket_create(),
);
- if (!this->socket)
- {
- free(this);
- return NULL;
- }
- charon->socket->add_socket(charon->socket, &this->socket->socket);
+ charon->socket->add_socket(charon->socket,
+ (socket_constructor_t)socket_dynamic_socket_create);
return &this->public.plugin;
}
diff --git a/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c b/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c
index 861ebfd6f..74dba82cc 100644
--- a/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c
+++ b/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2009 Tobias Brunner
+ * Copyright (C) 2006-2010 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2010 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -572,7 +572,7 @@ METHOD(socket_t, sender, status_t,
return SUCCESS;
}
-METHOD(socket_dynamic_socket_t, destroy, void,
+METHOD(socket_t, destroy, void,
private_socket_dynamic_socket_t *this)
{
enumerator_t *enumerator;
@@ -605,8 +605,8 @@ socket_dynamic_socket_t *socket_dynamic_socket_create()
.socket = {
.send = _sender,
.receive = _receiver,
+ .destroy = _destroy,
},
- .destroy = _destroy,
},
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
.max_packet = lib->settings->get_int(lib->settings,
diff --git a/src/libcharon/plugins/socket_raw/socket_raw_plugin.c b/src/libcharon/plugins/socket_raw/socket_raw_plugin.c
index 5b4c044f6..17a3a8db7 100644
--- a/src/libcharon/plugins/socket_raw/socket_raw_plugin.c
+++ b/src/libcharon/plugins/socket_raw/socket_raw_plugin.c
@@ -1,4 +1,6 @@
/*
+ * Copyright (C) 2010 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
* Copyright (C) 2010 Martin Willi
* Copyright (C) 2010 revosec AG
*
@@ -31,17 +33,13 @@ struct private_socket_raw_plugin_t {
*/
socket_raw_plugin_t public;
- /**
- * Raw socket instance.
- */
- socket_raw_socket_t *socket;
};
METHOD(plugin_t, destroy, void,
private_socket_raw_plugin_t *this)
{
- charon->socket->remove_socket(charon->socket, &this->socket->socket);
- this->socket->destroy(this->socket);
+ charon->socket->remove_socket(charon->socket,
+ (socket_constructor_t)socket_raw_socket_create);
free(this);
}
@@ -58,15 +56,10 @@ plugin_t *socket_raw_plugin_create()
.destroy = _destroy,
},
},
- .socket = socket_raw_socket_create(),
);
- if (!this->socket)
- {
- free(this);
- return NULL;
- }
- charon->socket->add_socket(charon->socket, &this->socket->socket);
+ charon->socket->add_socket(charon->socket,
+ (socket_constructor_t)socket_raw_socket_create);
return &this->public.plugin;
}
diff --git a/src/libcharon/plugins/socket_raw/socket_raw_socket.c b/src/libcharon/plugins/socket_raw/socket_raw_socket.c
index 66bc78526..f6e87a86f 100644
--- a/src/libcharon/plugins/socket_raw/socket_raw_socket.c
+++ b/src/libcharon/plugins/socket_raw/socket_raw_socket.c
@@ -1,6 +1,7 @@
/*
- * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
+ * Copyright (C) 2006-2010 Tobias Brunner
* Copyright (C) 2005-2010 Martin Willi
+ * Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -612,7 +613,7 @@ static int open_recv_socket(private_socket_raw_socket_t *this, int family)
return skt;
}
-METHOD(socket_raw_socket_t, destroy, void,
+METHOD(socket_t, destroy, void,
private_socket_raw_socket_t *this)
{
if (this->recv4)
@@ -654,8 +655,8 @@ socket_raw_socket_t *socket_raw_socket_create()
.socket = {
.send = _sender,
.receive = _receiver,
+ .destroy = _destroy,
},
- .destroy = _destroy,
},
.max_packet = lib->settings->get_int(lib->settings,
"charon.max_packet", MAX_PACKET),
diff --git a/src/libcharon/plugins/socket_raw/socket_raw_socket.h b/src/libcharon/plugins/socket_raw/socket_raw_socket.h
index 94cf666e8..23ff304a8 100644
--- a/src/libcharon/plugins/socket_raw/socket_raw_socket.h
+++ b/src/libcharon/plugins/socket_raw/socket_raw_socket.h
@@ -41,10 +41,6 @@ struct socket_raw_socket_t {
*/
socket_t socket;
- /**
- * Destroy a socket_raw_socket_t.
- */
- void (*destroy)(socket_raw_socket_t *this);
};
/**