aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2010-10-15 17:24:23 +0200
committerTobias Brunner <tobias@strongswan.org>2010-10-15 17:30:21 +0200
commitfa208494319efd0bc48fa63bfff9dac9bef84a55 (patch)
treecd20dae44e8f03eec2d505400830db0b84a7d656 /src
parent4de8398f931e1777c685710c87ad412bcf6715c4 (diff)
downloadstrongswan-fa208494319efd0bc48fa63bfff9dac9bef84a55.tar.bz2
strongswan-fa208494319efd0bc48fa63bfff9dac9bef84a55.tar.xz
Deferred instantiation of socket implmentations until registration.
Instantiating the implementations on plugin load was problematic in case multiple socket plugins were loaded. Now, the first one registered is instantiated.
Diffstat (limited to 'src')
-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);
};
/**