]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
Moved socket and socket-raw implementations to plugins
authorMartin Willi <martin@revosec.ch>
Mon, 22 Feb 2010 13:56:35 +0000 (14:56 +0100)
committerMartin Willi <martin@revosec.ch>
Fri, 26 Feb 2010 10:44:32 +0000 (11:44 +0100)
17 files changed:
configure.in
src/charon/Makefile.am
src/charon/daemon.c
src/charon/daemon.h
src/charon/network/socket.h
src/charon/network/socket_manager.c [new file with mode: 0644]
src/charon/network/socket_manager.h [new file with mode: 0644]
src/charon/plugins/socket_default/Makefile.am [new file with mode: 0644]
src/charon/plugins/socket_default/socket_default_plugin.c [new file with mode: 0644]
src/charon/plugins/socket_default/socket_default_plugin.h [new file with mode: 0644]
src/charon/plugins/socket_default/socket_default_socket.c [moved from src/charon/network/socket.c with 90% similarity]
src/charon/plugins/socket_default/socket_default_socket.h [new file with mode: 0644]
src/charon/plugins/socket_raw/Makefile.am [new file with mode: 0644]
src/charon/plugins/socket_raw/socket_raw_plugin.c [new file with mode: 0644]
src/charon/plugins/socket_raw/socket_raw_plugin.h [new file with mode: 0644]
src/charon/plugins/socket_raw/socket_raw_socket.c [moved from src/charon/network/socket-raw.c with 88% similarity]
src/charon/plugins/socket_raw/socket_raw_socket.h [new file with mode: 0644]

index e3eccd97703a3d3680d0d20780445d0c85efd8da..7c489595481e97639ea6015e3b9d87bb16b7f51d 100644 (file)
@@ -114,6 +114,8 @@ ARG_DISBL_SET([kernel-netlink], [disable the netlink kernel interface.])
 ARG_ENABL_SET([kernel-pfkey],   [enable the PF_KEY kernel interface.])
 ARG_ENABL_SET([kernel-pfroute], [enable the PF_ROUTE kernel interface.])
 ARG_ENABL_SET([kernel-klips],   [enable the KLIPS kernel interface.])
+ARG_DISBL_SET([socket-default], [disable default socket implementation for charon.])
+ARG_ENABL_SET([socket-raw],     [enable raw socket implementation of charon, enforced if pluto is enabled])
 ARG_ENABL_SET([nat-transport],  [enable NAT traversal with IPsec transport mode in pluto.])
 ARG_DISBL_SET([vendor-id],      [disable the sending of the strongSwan vendor ID in pluto.])
 ARG_DISBL_SET([xauth-vid],      [disable the sending of the XAUTH vendor ID.])
@@ -234,6 +236,14 @@ if test x$medcli = xtrue; then
        mediation=true
 fi
 
+if test x$pluto = xtrue; then
+       if test x$socket_raw = xfalse; then
+               AC_MSG_NOTICE([Enforcing --enable-socket-raw/--disable-socket-default, as pluto is enabled])
+               socket_default=false
+               socket_raw=true
+       fi
+fi
+
 dnl ===========================================
 dnl  check required libraries and header files
 dnl ===========================================
@@ -800,6 +810,8 @@ AM_CONDITIONAL(USE_KERNEL_NETLINK, test x$kernel_netlink = xtrue)
 AM_CONDITIONAL(USE_KERNEL_PFKEY, test x$kernel_pfkey = xtrue)
 AM_CONDITIONAL(USE_KERNEL_PFROUTE, test x$kernel_pfroute = xtrue)
 AM_CONDITIONAL(USE_KERNEL_KLIPS, test x$kernel_klips = xtrue)
+AM_CONDITIONAL(USE_SOCKET_DEFAULT, test x$socket_default = xtrue)
+AM_CONDITIONAL(USE_SOCKET_RAW, test x$socket_raw = xtrue)
 
 dnl other options
 dnl =============
@@ -894,6 +906,8 @@ AC_OUTPUT(
        src/charon/plugins/kernel_pfkey/Makefile
        src/charon/plugins/kernel_pfroute/Makefile
        src/charon/plugins/kernel_klips/Makefile
+       src/charon/plugins/socket_default/Makefile
+       src/charon/plugins/socket_raw/Makefile
        src/charon/plugins/smp/Makefile
        src/charon/plugins/sql/Makefile
        src/charon/plugins/medsrv/Makefile
index 0a021402c678c967be5d6962e059a3aa0346e20f..000515bb7c1fbe61fab56849601368b1a1a1b7c5 100644 (file)
@@ -45,7 +45,7 @@ kernel/kernel_net.h \
 network/packet.c network/packet.h \
 network/receiver.c network/receiver.h \
 network/sender.c network/sender.h \
-network/socket.h \
+network/socket_manager.c network/socket_manager.h network/socket.h \
 processing/jobs/job.h \
 processing/jobs/acquire_job.c processing/jobs/acquire_job.h \
 processing/jobs/callback_job.c processing/jobs/callback_job.h \
@@ -109,13 +109,6 @@ charon_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lm $(PTHREADL
 # compile options
 #################
 
-# Use RAW socket if pluto gets built
-if USE_PLUTO
-  charon_SOURCES += network/socket-raw.c
-else
-  charon_SOURCES += network/socket.c
-endif
-
 if USE_ME
   charon_SOURCES += encoding/payloads/endpoint_notify.c encoding/payloads/endpoint_notify.h \
     processing/jobs/initiate_mediation_job.c processing/jobs/initiate_mediation_job.h \
@@ -161,6 +154,16 @@ if USE_KERNEL_NETLINK
   PLUGINS += kernel-netlink
 endif
 
+if USE_SOCKET_DEFAULT
+  SUBDIRS += plugins/socket_default
+  PLUGINS += socket-default
+endif
+
+if USE_SOCKET_RAW
+  SUBDIRS += plugins/socket_raw
+  PLUGINS += socket-raw
+endif
+
 if USE_STROKE
   SUBDIRS += plugins/stroke
   PLUGINS += stroke
index e71225fd114f3e6f28189c85a00b19a88753832b..abaab7e03174d442627f115fda446af81f109444 100644 (file)
@@ -185,6 +185,7 @@ static void destroy(private_daemon_t *this)
        {
                this->public.ike_sa_manager->flush(this->public.ike_sa_manager);
        }
+       DESTROY_IF(this->public.receiver);
        /* unload plugins to release threads */
        lib->plugins->unload(lib->plugins);
 #ifdef CAPABILITIES
@@ -204,7 +205,6 @@ static void destroy(private_daemon_t *this)
        DESTROY_IF(this->public.backends);
        DESTROY_IF(this->public.credentials);
        DESTROY_IF(this->public.sender);
-       DESTROY_IF(this->public.receiver);
        DESTROY_IF(this->public.socket);
        /* wait until all threads are gone */
        DESTROY_IF(this->public.processor);
@@ -494,7 +494,7 @@ static bool initialize(private_daemon_t *this, bool syslog, level_t levels[])
        this->public.sim = sim_manager_create();
        this->public.backends = backend_manager_create();
        this->public.kernel_interface = kernel_interface_create();
-       this->public.socket = socket_create();
+       this->public.socket = socket_manager_create();
        this->public.traps = trap_manager_create();
 
        /* load plugins, further infrastructure may need it */
index cb5946d5df77d9dbe436651bdb245af0f0913866..c0a449e611948f6ef72ef9cd9b40418dbe3c8aa9 100644 (file)
@@ -148,7 +148,7 @@ typedef struct daemon_t daemon_t;
 
 #include <network/sender.h>
 #include <network/receiver.h>
-#include <network/socket.h>
+#include <network/socket_manager.h>
 #include <processing/scheduler.h>
 #include <processing/processor.h>
 #include <kernel/kernel_interface.h>
@@ -200,9 +200,9 @@ typedef struct daemon_t daemon_t;
 struct daemon_t {
 
        /**
-        * A socket_t instance.
+        * Socket manager instance
         */
-       socket_t *socket;
+       socket_manager_t *socket;
 
        /**
         * A ike_sa_manager_t instance.
index 83bb9d4c94695bc867540f5b487c51d695554ec2..798d3411abd5dfa5c39e12f2ab146288952b5dfd 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
- * Copyright (C) 2005-2008 Martin Willi
+ * Copyright (C) 2005-2010 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
@@ -27,29 +27,10 @@ typedef struct socket_t socket_t;
 
 #include <library.h>
 #include <network/packet.h>
-#include <utils/host.h>
 #include <utils/enumerator.h>
 
 /**
- * Maximum size of a packet.
- *
- * 3000 Bytes should be sufficient, see IKEv2 RFC. However, to run our
- * multi-CA test with 2 intermediate CAs, we increase that to 5000 bytes.
- */
-#define MAX_PACKET 5000
-
-/**
- * Abstraction of all sockets (IPv4/IPv6 send/receive).
- *
- * All available sockets are bound and the receive function
- * reads from them. There are actually two implementations:
- * The first uses raw sockets to allow binding of other daemons (pluto) to
- * UDP/500. An installed "Linux socket filter" filters out all non-IKEv2
- * traffic and handles just IKEv2 messages. An other daemon (pluto) must
- * handle all traffic separately, e.g. ignore IKEv2 traffic, since charon
- * handles that.
- * The other implementation uses normal sockets and is built if
- * --disable-pluto is given to the configure script.
+ * Socket interface definition.
  */
 struct socket_t {
 
@@ -85,18 +66,6 @@ struct socket_t {
         * @return                              enumerator over (int fd, int family, int port)
         */
        enumerator_t *(*create_enumerator) (socket_t *this);
-
-       /**
-        * Destroy socket.
-        */
-       void (*destroy) (socket_t *this);
 };
 
-/**
- * Create a socket_t, which binds multiple sockets.
- *
- * @return                             socket_t object
- */
-socket_t *socket_create();
-
 #endif /** SOCKET_H_ @}*/
diff --git a/src/charon/network/socket_manager.c b/src/charon/network/socket_manager.c
new file mode 100644 (file)
index 0000000..5bd9356
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * 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 "socket_manager.h"
+
+#include <daemon.h>
+#include <threading/thread.h>
+#include <threading/rwlock.h>
+#include <utils/linked_list.h>
+
+typedef struct private_socket_manager_t private_socket_manager_t;
+
+/**
+ * Private data of an socket_manager_t object.
+ */
+struct private_socket_manager_t {
+
+       /**
+        * Public socket_manager_t interface.
+        */
+       socket_manager_t public;
+
+       /**
+        * List of registered socket
+        */
+       linked_list_t *sockets;
+
+       /**
+        * Lock for sockets list
+        */
+       rwlock_t *lock;
+};
+
+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)
+       {
+               DBG1(DBG_NET, "no socket implementation registered, receiving failed");
+               this->lock->unlock(this->lock);
+               return NOT_SUPPORTED;
+       }
+       /* 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);
+       thread_cleanup_pop(TRUE);
+       return status;
+}
+
+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)
+       {
+               DBG1(DBG_NET, "no socket implementation registered, sending failed");
+               this->lock->unlock(this->lock);
+               return NOT_SUPPORTED;
+       }
+       status = socket->send(socket, packet);
+       this->lock->unlock(this->lock);
+       return status;
+}
+
+METHOD(socket_manager_t, create_enumerator, enumerator_t*,
+       private_socket_manager_t *this)
+{
+       socket_t *socket;
+
+       this->lock->read_lock(this->lock);
+       if (this->sockets->get_first(this->sockets, (void**)&socket) != SUCCESS)
+       {
+               this->lock->unlock(this->lock);
+               return enumerator_create_empty();
+       }
+       return enumerator_create_cleaner(socket->create_enumerator(socket),
+                                                                        (void*)this->lock->unlock, this->lock);
+}
+
+METHOD(socket_manager_t, add_socket, void,
+       private_socket_manager_t *this, socket_t *socket)
+{
+       this->lock->write_lock(this->lock);
+       this->sockets->insert_last(this->sockets, socket);
+       this->lock->unlock(this->lock);
+}
+
+METHOD(socket_manager_t, remove_socket, void,
+       private_socket_manager_t *this, socket_t *socket)
+{
+       this->lock->write_lock(this->lock);
+       this->sockets->remove(this->sockets, socket, NULL);
+       this->lock->unlock(this->lock);
+}
+
+METHOD(socket_manager_t, destroy, void,
+       private_socket_manager_t *this)
+{
+       this->sockets->destroy(this->sockets);
+       this->lock->destroy(this->lock);
+       free(this);
+}
+
+/**
+ * See header
+ */
+socket_manager_t *socket_manager_create()
+{
+       private_socket_manager_t *this;
+
+       INIT(this,
+               .public = {
+                       .send = _sender,
+                       .receive = _receiver,
+                       .create_enumerator = _create_enumerator,
+                       .add_socket = _add_socket,
+                       .remove_socket = _remove_socket,
+                       .destroy = _destroy,
+               },
+               .sockets = linked_list_create(),
+               .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+       );
+
+       return &this->public;
+}
+
diff --git a/src/charon/network/socket_manager.h b/src/charon/network/socket_manager.h
new file mode 100644 (file)
index 0000000..da38f56
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * 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.
+ */
+
+/**
+ * @defgroup socket_manager socket_manager
+ * @{ @ingroup network
+ */
+
+#ifndef SOCKET_MANAGER_H_
+#define SOCKET_MANAGER_H_
+
+#include <network/socket.h>
+
+typedef struct socket_manager_t socket_manager_t;
+
+/**
+ * Handle pluggable socket implementations and send/receive packets through it.
+ */
+struct socket_manager_t {
+
+       /**
+        * Receive a packet using the registered socket.
+        *
+        * @param packet                allocated packet that has been received
+        * @return
+        *                                              - SUCCESS when packet successfully received
+        *                                              - FAILED when unable to receive
+        */
+       status_t (*receive) (socket_manager_t *this, packet_t **packet);
+
+       /**
+        * Send a packet using the registered socket.
+        *
+        * @param packet                packet to send out
+        * @return
+        *                                              - SUCCESS when packet successfully sent
+        *                                              - FAILED when unable to send
+        */
+       status_t (*send) (socket_manager_t *this, packet_t *packet);
+
+       /**
+        * Enumerate all underlying socket file descriptors of the active socket.
+        *
+        * @return                              enumerator over (int fd, int family, int port)
+        */
+       enumerator_t *(*create_enumerator) (socket_manager_t *this);
+
+       /**
+        * Register a socket implementation.
+        */
+       void (*add_socket)(socket_manager_t *this, socket_t *socket);
+
+       /**
+        * Unregister a registered socket implementation.
+        */
+       void (*remove_socket)(socket_manager_t *this, socket_t *socket);
+
+       /**
+        * Destroy a socket_manager_t.
+        */
+       void (*destroy)(socket_manager_t *this);
+};
+
+/**
+ * Create a socket_manager instance.
+ */
+socket_manager_t *socket_manager_create();
+
+#endif /** SOCKET_MANAGER_H_ @}*/
diff --git a/src/charon/plugins/socket_default/Makefile.am b/src/charon/plugins/socket_default/Makefile.am
new file mode 100644 (file)
index 0000000..bf7bf05
--- /dev/null
@@ -0,0 +1,11 @@
+
+INCLUDES = -I${linux_headers} -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-socket-default.la
+
+libstrongswan_socket_default_la_SOURCES = \
+       socket_default_plugin.h socket_default_plugin.c \
+       socket_default_socket.h socket_default_socket.c
+libstrongswan_socket_default_la_LDFLAGS = -module -avoid-version
diff --git a/src/charon/plugins/socket_default/socket_default_plugin.c b/src/charon/plugins/socket_default/socket_default_plugin.c
new file mode 100644 (file)
index 0000000..4f455b4
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * 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 "socket_default_plugin.h"
+
+#include "socket_default_socket.h"
+
+#include <daemon.h>
+
+typedef struct private_socket_default_plugin_t private_socket_default_plugin_t;
+
+/**
+ * Private data of socket plugin
+ */
+struct private_socket_default_plugin_t {
+
+       /**
+        * Implements plugin interface
+        */
+       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);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+       private_socket_default_plugin_t *this;
+
+       INIT(this,
+               .public.plugin.destroy = _destroy,
+               .socket = socket_default_socket_create(),
+       );
+
+       if (!this->socket)
+       {
+               free(this);
+               return NULL;
+       }
+       charon->socket->add_socket(charon->socket, &this->socket->socket);
+
+       return &this->public.plugin;
+}
+
diff --git a/src/charon/plugins/socket_default/socket_default_plugin.h b/src/charon/plugins/socket_default/socket_default_plugin.h
new file mode 100644 (file)
index 0000000..af98bb5
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * 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.
+ */
+
+/**
+ * @defgroup socket_default socket_default
+ * @ingroup cplugins
+ *
+ * @defgroup socket_default_plugin socket_default_plugin
+ * @{ @ingroup socket_default
+ */
+
+#ifndef SOCKET_DEFAULT_PLUGIN_H_
+#define SOCKET_DEFAULT_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct socket_default_plugin_t socket_default_plugin_t;
+
+/**
+ * Default socket implementation plugin.
+ */
+struct socket_default_plugin_t {
+
+       /**
+        * implements plugin interface
+        */
+       plugin_t plugin;
+};
+
+/**
+ * Create a socket_default_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /** SOCKET_DEFAULT_PLUGIN_H_ @}*/
similarity index 90%
rename from src/charon/network/socket.c
rename to src/charon/plugins/socket_default/socket_default_socket.c
index 81f860b151e725d9d6653ad7a937ec28593ff36b..d69f30975037666bc0317187b4a5b956ec7a262b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2006-2009 Tobias Brunner
  * Copyright (C) 2006 Daniel Roethlisberger
- * Copyright (C) 2005-2007 Martin Willi
+ * Copyright (C) 2005-2010 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
@@ -23,6 +23,8 @@
 #define __EXTENSIONS__
 #endif
 
+#include "socket_default_socket.h"
+
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <string.h>
 #include <sys/sysctl.h>
 #endif
 
-#include "socket.h"
-
 #include <daemon.h>
 #include <threading/thread.h>
 
+/* Maximum size of a packet */
+#define MAX_PACKET 5000
+
 /* length of non-esp marker */
 #define MARKER_LEN sizeof(u_int32_t)
 
 static const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
 #endif
 
-typedef struct private_socket_t private_socket_t;
+typedef struct private_socket_default_socket_t private_socket_default_socket_t;
 
 /**
  * Private data of an socket_t object
  */
-struct private_socket_t {
+struct private_socket_default_socket_t {
+
        /**
         * public functions
         */
-       socket_t public;
+       socket_default_socket_t public;
 
        /**
         * IPv4 socket (500)
@@ -114,10 +118,8 @@ struct private_socket_t {
        int ipv6_natt;
 };
 
-/**
- * implementation of socket_t.receive
- */
-static status_t receiver(private_socket_t *this, packet_t **packet)
+METHOD(socket_t, receiver, status_t,
+       private_socket_default_socket_t *this, packet_t **packet)
 {
        char buffer[MAX_PACKET];
        chunk_t data;
@@ -304,10 +306,8 @@ static status_t receiver(private_socket_t *this, packet_t **packet)
        return SUCCESS;
 }
 
-/**
- * implementation of socket_t.send
- */
-status_t sender(private_socket_t *this, packet_t *packet)
+METHOD(socket_t, sender, status_t,
+       private_socket_default_socket_t *this, packet_t *packet)
 {
        int sport, skt, family;
        ssize_t bytes_sent;
@@ -446,7 +446,8 @@ status_t sender(private_socket_t *this, packet_t *packet)
 /**
  * open a socket to send and receive packets
  */
-static int open_socket(private_socket_t *this, int family, u_int16_t port)
+static int open_socket(private_socket_default_socket_t *this,
+                                          int family, u_int16_t port)
 {
        int on = TRUE;
        struct sockaddr_storage addr;
@@ -541,7 +542,7 @@ typedef struct {
        /** implements enumerator_t */
        enumerator_t public;
        /** sockets we enumerate */
-       private_socket_t *socket;
+       private_socket_default_socket_t *socket;
        /** counter */
        int index;
 } socket_enumerator_t;
@@ -556,10 +557,14 @@ static bool enumerate(socket_enumerator_t *this, int *fd, int *family, int *port
                int family;
                int port;
        } sockets[] = {
-               { offsetof(private_socket_t, ipv4), AF_INET, IKEV2_UDP_PORT },
-               { offsetof(private_socket_t, ipv6), AF_INET6, IKEV2_UDP_PORT },
-               { offsetof(private_socket_t, ipv4_natt), AF_INET, IKEV2_NATT_PORT },
-               { offsetof(private_socket_t, ipv6_natt), AF_INET6, IKEV2_NATT_PORT }
+               { offsetof(private_socket_default_socket_t, ipv4),
+                       AF_INET, IKEV2_UDP_PORT },
+               { offsetof(private_socket_default_socket_t, ipv6),
+                       AF_INET6, IKEV2_UDP_PORT },
+               { offsetof(private_socket_default_socket_t, ipv4_natt),
+                       AF_INET, IKEV2_NATT_PORT },
+               { offsetof(private_socket_default_socket_t, ipv6_natt),
+                       AF_INET6, IKEV2_NATT_PORT }
        };
 
        while(++this->index < countof(sockets))
@@ -577,10 +582,8 @@ static bool enumerate(socket_enumerator_t *this, int *fd, int *family, int *port
        return FALSE;
 }
 
-/**
- * implementation of socket_t.create_enumerator
- */
-static enumerator_t *create_enumerator(private_socket_t *this)
+METHOD(socket_t, create_enumerator, enumerator_t*,
+       private_socket_default_socket_t *this)
 {
        socket_enumerator_t *enumerator;
 
@@ -592,10 +595,8 @@ static enumerator_t *create_enumerator(private_socket_t *this)
        return &enumerator->public;
 }
 
-/**
- * implementation of socket_t.destroy
- */
-static void destroy(private_socket_t *this)
+METHOD(socket_default_socket_t, destroy, void,
+       private_socket_default_socket_t *this)
 {
        if (this->ipv4)
        {
@@ -619,20 +620,20 @@ static void destroy(private_socket_t *this)
 /*
  * See header for description
  */
-socket_t *socket_create()
+socket_default_socket_t *socket_default_socket_create()
 {
-       private_socket_t *this = malloc_thing(private_socket_t);
-
-       /* public functions */
-       this->public.send = (status_t(*)(socket_t*, packet_t*))sender;
-       this->public.receive = (status_t(*)(socket_t*, packet_t**))receiver;
-       this->public.create_enumerator = (enumerator_t*(*)(socket_t*))create_enumerator;
-       this->public.destroy = (void(*)(socket_t*)) destroy;
-
-       this->ipv4 = 0;
-       this->ipv6 = 0;
-       this->ipv4_natt = 0;
-       this->ipv6_natt = 0;
+       private_socket_default_socket_t *this;
+
+       INIT(this,
+               .public = {
+                       .socket = {
+                               .send = _sender,
+                               .receive = _receiver,
+                               .create_enumerator = _create_enumerator,
+                       },
+                       .destroy = _destroy,
+               },
+       );
 
 #ifdef __APPLE__
        {
@@ -678,8 +679,8 @@ socket_t *socket_create()
        {
                DBG1(DBG_NET, "could not create any sockets");
                destroy(this);
-               charon->kill(charon, "socket initialization failed");
+               return NULL;
        }
-       return (socket_t*)this;
+       return &this->public;
 }
 
diff --git a/src/charon/plugins/socket_default/socket_default_socket.h b/src/charon/plugins/socket_default/socket_default_socket.h
new file mode 100644 (file)
index 0000000..7550166
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * 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.
+ */
+
+/**
+ * @defgroup socket_default_socket socket_default_socket
+ * @{ @ingroup socket_default
+ */
+
+#ifndef SOCKET_DEFAULT_SOCKET_H_
+#define SOCKET_DEFAULT_SOCKET_H_
+
+typedef struct socket_default_socket_t socket_default_socket_t;
+
+#include <network/socket.h>
+
+/**
+ * Default socket, binds to port 500/4500 using any IPv4/IPv6 address.
+ */
+struct socket_default_socket_t {
+
+       /**
+        * Implements the socket_t interface.
+        */
+       socket_t socket;
+
+       /**
+        * Destroy a socket_default_socket_t.
+        */
+       void (*destroy)(socket_default_socket_t *this);
+};
+
+/**
+ * Create a socket_default_socket instance.
+ */
+socket_default_socket_t *socket_default_socket_create();
+
+#endif /** SOCKET_DEFAULT_SOCKET_H_ @}*/
diff --git a/src/charon/plugins/socket_raw/Makefile.am b/src/charon/plugins/socket_raw/Makefile.am
new file mode 100644 (file)
index 0000000..e9a342a
--- /dev/null
@@ -0,0 +1,11 @@
+
+INCLUDES = -I${linux_headers} -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-socket-raw.la
+
+libstrongswan_socket_raw_la_SOURCES = \
+       socket_raw_plugin.h socket_raw_plugin.c \
+       socket_raw_socket.h socket_raw_socket.c
+libstrongswan_socket_raw_la_LDFLAGS = -module -avoid-version
diff --git a/src/charon/plugins/socket_raw/socket_raw_plugin.c b/src/charon/plugins/socket_raw/socket_raw_plugin.c
new file mode 100644 (file)
index 0000000..76eb71f
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * 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 "socket_raw_plugin.h"
+
+#include "socket_raw_socket.h"
+
+#include <daemon.h>
+
+typedef struct private_socket_raw_plugin_t private_socket_raw_plugin_t;
+
+/**
+ * Private data of socket plugin
+ */
+struct private_socket_raw_plugin_t {
+
+       /**
+        * Implements plugin interface
+        */
+       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);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+       private_socket_raw_plugin_t *this;
+
+       INIT(this,
+               .public.plugin.destroy = _destroy,
+               .socket = socket_raw_socket_create(),
+       );
+
+       if (!this->socket)
+       {
+               free(this);
+               return NULL;
+       }
+       charon->socket->add_socket(charon->socket, &this->socket->socket);
+
+       return &this->public.plugin;
+}
+
diff --git a/src/charon/plugins/socket_raw/socket_raw_plugin.h b/src/charon/plugins/socket_raw/socket_raw_plugin.h
new file mode 100644 (file)
index 0000000..1a295f8
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * 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.
+ */
+
+/**
+ * @defgroup socket_raw socket_raw
+ * @ingroup cplugins
+ *
+ * @defgroup socket_raw_plugin socket_raw_plugin
+ * @{ @ingroup socket_raw
+ */
+
+#ifndef SOCKET_RAW_PLUGIN_H_
+#define SOCKET_RAW_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct socket_raw_plugin_t socket_raw_plugin_t;
+
+/**
+ * RAW socket implementation plugin.
+ */
+struct socket_raw_plugin_t {
+
+       /**
+        * implements plugin interface
+        */
+       plugin_t plugin;
+};
+
+/**
+ * Create a socket_raw_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /** SOCKET_RAW_PLUGIN_H_ @}*/
similarity index 88%
rename from src/charon/network/socket-raw.c
rename to src/charon/plugins/socket_raw/socket_raw_socket.c
index 6cc0463b20465f1685e0d4d3686747ce7d336a4b..78358568c9a754ec6f6401b3bd43f4b1e84d3b2f 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
- * Copyright (C) 2005-2008 Martin Willi
+ * Copyright (C) 2005-2010 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
@@ -18,6 +18,8 @@
 /* for struct in6_pktinfo */
 #define _GNU_SOURCE
 
+#include "socket_raw_socket.h"
+
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <string.h>
 #include <linux/filter.h>
 #include <net/if.h>
 
-#include "socket.h"
-
 #include <daemon.h>
 #include <threading/thread.h>
 
+/* Maximum size of a packet */
+#define MAX_PACKET 5000
+
 /* constants for packet handling */
 #define IP_LEN sizeof(struct iphdr)
 #define IP6_LEN sizeof(struct ip6_hdr)
 #define IPV6_2292PKTINFO 2
 #endif /*IPV6_2292PKTINFO*/
 
-typedef struct private_socket_t private_socket_t;
+typedef struct private_socket_raw_socket_t private_socket_raw_socket_t;
 
 /**
  * Private data of an socket_t object
  */
-struct private_socket_t{
+struct private_socket_raw_socket_t {
+
        /**
         * public functions
         */
-        socket_t public;
-
-        /**
-         * regular port
-         */
-        int port;
-
-        /**
-         * port used for nat-t
-         */
-        int natt_port;
-
-        /**
-         * raw receiver socket for IPv4
-         */
-        int recv4;
-
-        /**
-         * raw receiver socket for IPv6
-         */
-        int recv6;
-
-        /**
-         * send socket on regular port for IPv4
-         */
-        int send4;
-
-        /**
-         * send socket on regular port for IPv6
-         */
-        int send6;
-
-        /**
-         * send socket on nat-t port for IPv4
-         */
-        int send4_natt;
-
-        /**
-         * send socket on nat-t port for IPv6
-         */
-        int send6_natt;
+        socket_raw_socket_t public;
+
+       /**
+        * regular port
+        */
+       int port;
+
+       /**
+        * port used for nat-t
+        */
+       int natt_port;
+
+       /**
+        * raw receiver socket for IPv4
+        */
+       int recv4;
+
+       /**
+        * raw receiver socket for IPv6
+        */
+       int recv6;
+
+       /**
+        * send socket on regular port for IPv4
+        */
+       int send4;
+
+       /**
+        * send socket on regular port for IPv6
+        */
+       int send6;
+
+       /**
+        * send socket on nat-t port for IPv4
+        */
+       int send4_natt;
+
+       /**
+        * send socket on nat-t port for IPv6
+        */
+       int send6_natt;
 };
 
-/**
- * implementation of socket_t.receive
- */
-static status_t receiver(private_socket_t *this, packet_t **packet)
+METHOD(socket_t, receiver, status_t,
+       private_socket_raw_socket_t *this, packet_t **packet)
 {
        char buffer[MAX_PACKET];
        chunk_t data;
@@ -296,10 +298,8 @@ static status_t receiver(private_socket_t *this, packet_t **packet)
        return SUCCESS;
 }
 
-/**
- * implementation of socket_t.send
- */
-status_t sender(private_socket_t *this, packet_t *packet)
+METHOD(socket_t, sender, status_t,
+       private_socket_raw_socket_t *this, packet_t *packet)
 {
        int sport, skt, family;
        ssize_t bytes_sent;
@@ -423,7 +423,8 @@ status_t sender(private_socket_t *this, packet_t *packet)
 /**
  * open a socket to send packets
  */
-static int open_send_socket(private_socket_t *this, int family, u_int16_t port)
+static int open_send_socket(private_socket_raw_socket_t *this,
+                                                       int family, u_int16_t port)
 {
        int on = TRUE;
        int type = UDP_ENCAP_ESPINUDP;
@@ -497,7 +498,7 @@ static int open_send_socket(private_socket_t *this, int family, u_int16_t port)
 /**
  * open a socket to receive packets
  */
-static int open_recv_socket(private_socket_t *this, int family)
+static int open_recv_socket(private_socket_raw_socket_t *this, int family)
 {
        int skt;
        int on = TRUE;
@@ -599,7 +600,7 @@ typedef struct {
        /** implements enumerator_t */
        enumerator_t public;
        /** sockets we enumerate */
-       private_socket_t *socket;
+       private_socket_raw_socket_t *socket;
        /** counter */
        int index;
 } socket_enumerator_t;
@@ -614,12 +615,12 @@ static bool enumerate(socket_enumerator_t *this, int *fd, int *family, int *port
                int family;
                int port;
        } sockets[] = {
-               { offsetof(private_socket_t, recv4), AF_INET, IKEV2_UDP_PORT },
-               { offsetof(private_socket_t, recv6), AF_INET6, IKEV2_UDP_PORT },
-               { offsetof(private_socket_t, send4), AF_INET, IKEV2_UDP_PORT },
-               { offsetof(private_socket_t, send6), AF_INET6, IKEV2_UDP_PORT },
-               { offsetof(private_socket_t, send4_natt), AF_INET, IKEV2_NATT_PORT },
-               { offsetof(private_socket_t, send6_natt), AF_INET6, IKEV2_NATT_PORT }
+               { offsetof(private_socket_raw_socket_t, recv4), AF_INET, IKEV2_UDP_PORT },
+               { offsetof(private_socket_raw_socket_t, recv6), AF_INET6, IKEV2_UDP_PORT },
+               { offsetof(private_socket_raw_socket_t, send4), AF_INET, IKEV2_UDP_PORT },
+               { offsetof(private_socket_raw_socket_t, send6), AF_INET6, IKEV2_UDP_PORT },
+               { offsetof(private_socket_raw_socket_t, send4_natt), AF_INET, IKEV2_NATT_PORT },
+               { offsetof(private_socket_raw_socket_t, send6_natt), AF_INET6, IKEV2_NATT_PORT }
        };
 
        while(++this->index < countof(sockets))
@@ -637,10 +638,8 @@ static bool enumerate(socket_enumerator_t *this, int *fd, int *family, int *port
        return FALSE;
 }
 
-/**
- * implementation of socket_t.create_enumerator
- */
-static enumerator_t *create_enumerator(private_socket_t *this)
+METHOD(socket_t, create_enumerator, enumerator_t*,
+       private_socket_raw_socket_t *this)
 {
        socket_enumerator_t *enumerator;
 
@@ -652,10 +651,8 @@ static enumerator_t *create_enumerator(private_socket_t *this)
        return &enumerator->public;
 }
 
-/**
- * implementation of socket_t.destroy
- */
-static void destroy(private_socket_t *this)
+METHOD(socket_raw_socket_t, destroy, void,
+       private_socket_raw_socket_t *this)
 {
        if (this->recv4)
        {
@@ -687,22 +684,20 @@ static void destroy(private_socket_t *this)
 /*
  * See header for description
  */
-socket_t *socket_create()
+socket_raw_socket_t *socket_raw_socket_create()
 {
-       private_socket_t *this = malloc_thing(private_socket_t);
-
-       /* public functions */
-       this->public.send = (status_t(*)(socket_t*, packet_t*))sender;
-       this->public.receive = (status_t(*)(socket_t*, packet_t**))receiver;
-       this->public.create_enumerator = (enumerator_t*(*)(socket_t*))create_enumerator;
-       this->public.destroy = (void(*)(socket_t*)) destroy;
-
-       this->recv4 = 0;
-       this->recv6 = 0;
-       this->send4 = 0;
-       this->send6 = 0;
-       this->send4_natt = 0;
-       this->send6_natt = 0;
+       private_socket_raw_socket_t *this;
+
+       INIT(this,
+               .public = {
+                       .socket = {
+                               .send = _sender,
+                               .receive = _receiver,
+                               .create_enumerator = _create_enumerator,
+                       },
+                       .destroy = _destroy,
+               },
+       );
 
        this->recv4 = open_recv_socket(this, AF_INET);
        if (this->recv4 == 0)
@@ -754,8 +749,8 @@ socket_t *socket_create()
        {
                DBG1(DBG_NET, "could not create any sockets");
                destroy(this);
-               charon->kill(charon, "socket initialization failed");
+               return NULL;
        }
 
-       return (socket_t*)this;
+       return &this->public;
 }
diff --git a/src/charon/plugins/socket_raw/socket_raw_socket.h b/src/charon/plugins/socket_raw/socket_raw_socket.h
new file mode 100644 (file)
index 0000000..94cf666
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * 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.
+ */
+
+/**
+ * @defgroup socket_raw_socket socket_raw_socket
+ * @{ @ingroup socket_raw
+ */
+
+#ifndef SOCKET_RAW_SOCKET_H_
+#define SOCKET_RAW_SOCKET_H_
+
+typedef struct socket_raw_socket_t socket_raw_socket_t;
+
+#include <network/socket.h>
+
+/**
+ * Raw socket, binds to port 500/4500 using any IPv4/IPv6 address.
+ *
+ * This imeplementation uses raw sockets to allow binding of other daemons
+ * (pluto) to UDP/500/4500. An installed "Linux socket filter" filters out
+ * all non-IKEv2 traffic and handles just IKEv2 messages. An other daemon
+ * must handle all traffic separately, e.g. ignore IKEv2 traffic, since charon
+ * handles that.
+ */
+struct socket_raw_socket_t {
+
+       /**
+        * Implements the socket_t interface.
+        */
+       socket_t socket;
+
+       /**
+        * Destroy a socket_raw_socket_t.
+        */
+       void (*destroy)(socket_raw_socket_t *this);
+};
+
+/**
+ * Create a socket_raw_socket instance.
+ */
+socket_raw_socket_t *socket_raw_socket_create();
+
+#endif /** SOCKET_RAW_SOCKET_H_ @}*/