summaryrefslogtreecommitdiff
path: root/src/charon/network
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon/network')
-rw-r--r--src/charon/network/sender.c49
-rw-r--r--src/charon/network/socket-raw.c136
-rw-r--r--src/charon/network/socket.c109
-rw-r--r--src/charon/network/socket.h24
4 files changed, 169 insertions, 149 deletions
diff --git a/src/charon/network/sender.c b/src/charon/network/sender.c
index 60a08d0c3..3295ec2df 100644
--- a/src/charon/network/sender.c
+++ b/src/charon/network/sender.c
@@ -13,7 +13,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * $Id: sender.c 3742 2008-04-03 09:19:12Z tobias $
+ * $Id: sender.c 4582 2008-11-05 12:24:36Z martin $
*/
#include <stdlib.h>
@@ -24,6 +24,7 @@
#include <daemon.h>
#include <network/socket.h>
#include <processing/jobs/callback_job.h>
+#include <utils/mutex.h>
typedef struct private_sender_t private_sender_t;
@@ -50,17 +51,17 @@ struct private_sender_t {
/**
* mutex to synchronize access to list
*/
- pthread_mutex_t mutex;
+ mutex_t *mutex;
/**
* condvar to signal for packets added to list
*/
- pthread_cond_t gotone;
+ condvar_t *got;
/**
* condvar to signal for packets sent
*/
- pthread_cond_t sentone;
+ condvar_t *sent;
};
/**
@@ -74,10 +75,10 @@ static void send_(private_sender_t *this, packet_t *packet)
dst = packet->get_destination(packet);
DBG1(DBG_NET, "sending packet: from %#H to %#H", src, dst);
- pthread_mutex_lock(&this->mutex);
+ this->mutex->lock(this->mutex);
this->list->insert_last(this->list, packet);
- pthread_cond_signal(&this->gotone);
- pthread_mutex_unlock(&this->mutex);
+ this->got->signal(this->got);
+ this->mutex->unlock(this->mutex);
}
/**
@@ -88,21 +89,21 @@ static job_requeue_t send_packets(private_sender_t * this)
packet_t *packet;
int oldstate;
- pthread_mutex_lock(&this->mutex);
+ this->mutex->lock(this->mutex);
while (this->list->get_count(this->list) == 0)
{
/* add cleanup handler, wait for packet, remove cleanup handler */
- pthread_cleanup_push((void(*)(void*))pthread_mutex_unlock, (void*)&this->mutex);
+ pthread_cleanup_push((void(*)(void*))this->mutex->unlock, this->mutex);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
- pthread_cond_wait(&this->gotone, &this->mutex);
+ this->got->wait(this->got, this->mutex);
pthread_setcancelstate(oldstate, NULL);
pthread_cleanup_pop(0);
}
this->list->remove_first(this->list, (void**)&packet);
- pthread_cond_signal(&this->sentone);
- pthread_mutex_unlock(&this->mutex);
+ this->sent->signal(this->sent);
+ this->mutex->unlock(this->mutex);
charon->socket->send(charon->socket, packet);
packet->destroy(packet);
@@ -115,15 +116,17 @@ static job_requeue_t send_packets(private_sender_t * this)
static void destroy(private_sender_t *this)
{
/* send all packets in the queue */
- pthread_mutex_lock(&this->mutex);
+ this->mutex->lock(this->mutex);
while (this->list->get_count(this->list))
{
- pthread_cond_wait(&this->sentone, &this->mutex);
+ this->sent->wait(this->sent, this->mutex);
}
- pthread_mutex_unlock(&this->mutex);
- pthread_mutex_destroy(&this->mutex);
+ this->mutex->unlock(this->mutex);
this->job->cancel(this->job);
this->list->destroy(this->list);
+ this->got->destroy(this->got);
+ this->sent->destroy(this->sent);
+ this->mutex->destroy(this->mutex);
free(this);
}
@@ -133,19 +136,19 @@ static void destroy(private_sender_t *this)
sender_t * sender_create()
{
private_sender_t *this = malloc_thing(private_sender_t);
-
+
this->public.send = (void(*)(sender_t*,packet_t*))send_;
this->public.destroy = (void(*)(sender_t*)) destroy;
-
+
this->list = linked_list_create();
- pthread_mutex_init(&this->mutex, NULL);
- pthread_cond_init(&this->gotone, NULL);
- pthread_cond_init(&this->sentone, NULL);
-
+ this->mutex = mutex_create(MUTEX_DEFAULT);
+ this->got = condvar_create(CONDVAR_DEFAULT);
+ this->sent = condvar_create(CONDVAR_DEFAULT);
+
this->job = callback_job_create((callback_job_cb_t)send_packets,
this, NULL, NULL);
charon->processor->queue_job(charon->processor, (job_t*)this->job);
-
+
return &this->public;
}
diff --git a/src/charon/network/socket-raw.c b/src/charon/network/socket-raw.c
index 5d1623ffd..40218f67d 100644
--- a/src/charon/network/socket-raw.c
+++ b/src/charon/network/socket-raw.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2008 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -14,7 +14,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * $Id: socket-raw.c 3870 2008-04-24 13:49:20Z martin $
+ * $Id: socket-raw.c 4646 2008-11-13 07:15:45Z martin $
*/
/* for struct in6_pktinfo */
@@ -33,7 +33,7 @@
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netinet/udp.h>
-#include <linux/ipsec.h>
+#include <linux/types.h>
#include <linux/filter.h>
#include <net/if.h>
@@ -53,11 +53,6 @@
#define IKE_VERSION_OFFSET 17
#define IKE_LENGTH_OFFSET 24
-/* from linux/in.h */
-#ifndef IP_IPSEC_POLICY
-#define IP_IPSEC_POLICY 16
-#endif /*IP_IPSEC_POLICY*/
-
/* from linux/udp.h */
#ifndef UDP_ENCAP
#define UDP_ENCAP 100
@@ -72,11 +67,6 @@
#define IPV6_2292PKTINFO 2
#endif /*IPV6_2292PKTINFO*/
-/* missing on uclibc */
-#ifndef IPV6_IPSEC_POLICY
-#define IPV6_IPSEC_POLICY 34
-#endif /*IPV6_IPSEC_POLICY*/
-
typedef struct private_socket_t private_socket_t;
/**
@@ -440,8 +430,7 @@ static int open_send_socket(private_socket_t *this, int family, u_int16_t port)
int on = TRUE;
int type = UDP_ENCAP_ESPINUDP;
struct sockaddr_storage addr;
- u_int sol, ipsec_policy;
- struct sadb_x_policy policy;
+ u_int sol;
int skt;
memset(&addr, 0, sizeof(addr));
@@ -455,7 +444,6 @@ static int open_send_socket(private_socket_t *this, int family, u_int16_t port)
sin->sin_addr.s_addr = INADDR_ANY;
sin->sin_port = htons(port);
sol = SOL_IP;
- ipsec_policy = IP_IPSEC_POLICY;
break;
}
case AF_INET6:
@@ -465,7 +453,6 @@ static int open_send_socket(private_socket_t *this, int family, u_int16_t port)
memcpy(&sin6->sin6_addr, &in6addr_any, sizeof(in6addr_any));
sin6->sin6_port = htons(port);
sol = SOL_IPV6;
- ipsec_policy = IPV6_IPSEC_POLICY;
break;
}
default:
@@ -487,32 +474,6 @@ static int open_send_socket(private_socket_t *this, int family, u_int16_t port)
return 0;
}
- /* bypass outgoung IKE traffic on send socket */
- memset(&policy, 0, sizeof(policy));
- policy.sadb_x_policy_len = sizeof(policy) / sizeof(u_int64_t);
- policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
- policy.sadb_x_policy_type = IPSEC_POLICY_BYPASS;
- policy.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND;
-
- if (setsockopt(skt, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
- {
- DBG1(DBG_NET, "unable to set IPSEC_POLICY on send socket: %s",
- strerror(errno));
- close(skt);
- return 0;
- }
-
- /* We don't receive packets on the send socket, but we need a INBOUND policy.
- * Otherwise, UDP decapsulation does not work!!! */
- policy.sadb_x_policy_dir = IPSEC_DIR_INBOUND;
- if (setsockopt(skt, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
- {
- DBG1(DBG_NET, "unable to set IPSEC_POLICY on send socket: %s",
- strerror(errno));
- close(skt);
- return 0;
- }
-
/* bind the send socket */
if (bind(skt, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
@@ -542,8 +503,7 @@ static int open_recv_socket(private_socket_t *this, int family)
{
int skt;
int on = TRUE;
- u_int proto_offset, ip_len, sol, ipsec_policy, udp_header, ike_header;
- struct sadb_x_policy policy;
+ u_int proto_offset, ip_len, sol, udp_header, ike_header;
/* precalculate constants depending on address family */
switch (family)
@@ -552,13 +512,11 @@ static int open_recv_socket(private_socket_t *this, int family)
proto_offset = IP_PROTO_OFFSET;
ip_len = IP_LEN;
sol = SOL_IP;
- ipsec_policy = IP_IPSEC_POLICY;
break;
case AF_INET6:
proto_offset = IP6_PROTO_OFFSET;
ip_len = 0; /* IPv6 raw sockets contain no IP header */
sol = SOL_IPV6;
- ipsec_policy = IPV6_IPSEC_POLICY;
break;
default:
return 0;
@@ -633,22 +591,67 @@ static int open_recv_socket(private_socket_t *this, int family)
return 0;
}
- /* bypass incomining IKE traffic on this socket */
- memset(&policy, 0, sizeof(policy));
- policy.sadb_x_policy_len = sizeof(policy) / sizeof(u_int64_t);
- policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
- policy.sadb_x_policy_type = IPSEC_POLICY_BYPASS;
- policy.sadb_x_policy_dir = IPSEC_DIR_INBOUND;
+ return skt;
+}
+
+/**
+ * enumerator for underlying sockets
+ */
+typedef struct {
+ /** implements enumerator_t */
+ enumerator_t public;
+ /** sockets we enumerate */
+ private_socket_t *socket;
+ /** counter */
+ int index;
+} socket_enumerator_t;
+
+/**
+ * enumerate function for socket_enumerator_t
+ */
+static bool enumerate(socket_enumerator_t *this, int *fd, int *family, int *port)
+{
+ static const struct {
+ int fd_offset;
+ 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 }
+ };
- if (setsockopt(skt, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
+ while(++this->index < countof(sockets))
{
- DBG1(DBG_NET, "unable to set IPSEC_POLICY on raw socket: %s",
- strerror(errno));
- close(skt);
- return 0;
+ int sock = *(int*)((char*)this->socket + sockets[this->index].fd_offset);
+ if (!sock)
+ {
+ continue;
+ }
+ *fd = sock;
+ *family = sockets[this->index].family;
+ *port = sockets[this->index].port;
+ return TRUE;
}
-
- return skt;
+ return FALSE;
+}
+
+/**
+ * implementation of socket_t.create_enumerator
+ */
+static enumerator_t *create_enumerator(private_socket_t *this)
+{
+ socket_enumerator_t *enumerator;
+
+ enumerator = malloc_thing(socket_enumerator_t);
+ enumerator->index = -1;
+ enumerator->socket = this;
+ enumerator->public.enumerate = (void*)enumerate;
+ enumerator->public.destroy = (void*)free;
+ return &enumerator->public;
}
/**
@@ -688,12 +691,12 @@ static void destroy(private_socket_t *this)
*/
socket_t *socket_create()
{
- int key;
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;
@@ -703,15 +706,6 @@ socket_t *socket_create()
this->send4_natt = 0;
this->send6_natt = 0;
- /* we open a AF_KEY socket to autoload the af_key module. Otherwise
- * setsockopt(IPSEC_POLICY) won't work. */
- key = socket(AF_KEY, SOCK_RAW, PF_KEY_V2);
- if (key == 0)
- {
- charon->kill(charon, "could not open AF_KEY socket");
- }
- close(key);
-
this->recv4 = open_recv_socket(this, AF_INET);
if (this->recv4 == 0)
{
diff --git a/src/charon/network/socket.c b/src/charon/network/socket.c
index 60ea5f7c8..6be59ef62 100644
--- a/src/charon/network/socket.c
+++ b/src/charon/network/socket.c
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
+ * Copyright (C) 2006-2008 Tobias Brunner
+ * Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -14,7 +15,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * $Id: socket.c 3870 2008-04-24 13:49:20Z martin $
+ * $Id: socket.c 4646 2008-11-13 07:15:45Z martin $
*/
/* for struct in6_pktinfo */
@@ -33,7 +34,7 @@
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netinet/udp.h>
-#include <linux/ipsec.h>
+#include <linux/types.h>
#include <linux/filter.h>
#include <net/if.h>
@@ -44,11 +45,6 @@
/* length of non-esp marker */
#define MARKER_LEN sizeof(u_int32_t)
-/* from linux/in.h */
-#ifndef IP_IPSEC_POLICY
-#define IP_IPSEC_POLICY 16
-#endif /*IP_IPSEC_POLICY*/
-
/* from linux/udp.h */
#ifndef UDP_ENCAP
#define UDP_ENCAP 100
@@ -405,8 +401,7 @@ static int open_socket(private_socket_t *this, int family, u_int16_t port)
int on = TRUE;
int type = UDP_ENCAP_ESPINUDP;
struct sockaddr_storage addr;
- u_int sol, ipsec_policy, pktinfo;
- struct sadb_x_policy policy;
+ u_int sol, pktinfo;
int skt;
memset(&addr, 0, sizeof(addr));
@@ -420,7 +415,6 @@ static int open_socket(private_socket_t *this, int family, u_int16_t port)
sin->sin_addr.s_addr = INADDR_ANY;
sin->sin_port = htons(port);
sol = SOL_IP;
- ipsec_policy = IP_IPSEC_POLICY;
pktinfo = IP_PKTINFO;
break;
}
@@ -431,7 +425,6 @@ static int open_socket(private_socket_t *this, int family, u_int16_t port)
memcpy(&sin6->sin6_addr, &in6addr_any, sizeof(in6addr_any));
sin6->sin6_port = htons(port);
sol = SOL_IPV6;
- ipsec_policy = IPV6_IPSEC_POLICY;
pktinfo = IPV6_2292PKTINFO;
break;
}
@@ -452,29 +445,6 @@ static int open_socket(private_socket_t *this, int family, u_int16_t port)
return 0;
}
- /* bypass IKE traffic on socket */
- memset(&policy, 0, sizeof(policy));
- policy.sadb_x_policy_len = sizeof(policy) / sizeof(u_int64_t);
- policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
- policy.sadb_x_policy_type = IPSEC_POLICY_BYPASS;
-
- policy.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND;
- if (setsockopt(skt, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
- {
- DBG1(DBG_NET, "unable to set IPSEC_POLICY on socket: %s",
- strerror(errno));
- close(skt);
- return 0;
- }
- policy.sadb_x_policy_dir = IPSEC_DIR_INBOUND;
- if (setsockopt(skt, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
- {
- DBG1(DBG_NET, "unable to set IPSEC_POLICY on socket: %s",
- strerror(errno));
- close(skt);
- return 0;
- }
-
/* bind the send socket */
if (bind(skt, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
@@ -501,6 +471,64 @@ static int open_socket(private_socket_t *this, int family, u_int16_t port)
}
/**
+ * enumerator for underlying sockets
+ */
+typedef struct {
+ /** implements enumerator_t */
+ enumerator_t public;
+ /** sockets we enumerate */
+ private_socket_t *socket;
+ /** counter */
+ int index;
+} socket_enumerator_t;
+
+/**
+ * enumerate function for socket_enumerator_t
+ */
+static bool enumerate(socket_enumerator_t *this, int *fd, int *family, int *port)
+{
+ static const struct {
+ int fd_offset;
+ 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 }
+ };
+
+ while(++this->index < countof(sockets))
+ {
+ int sock = *(int*)((char*)this->socket + sockets[this->index].fd_offset);
+ if (!sock)
+ {
+ continue;
+ }
+ *fd = sock;
+ *family = sockets[this->index].family;
+ *port = sockets[this->index].port;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * implementation of socket_t.create_enumerator
+ */
+static enumerator_t *create_enumerator(private_socket_t *this)
+{
+ socket_enumerator_t *enumerator;
+
+ enumerator = malloc_thing(socket_enumerator_t);
+ enumerator->index = -1;
+ enumerator->socket = this;
+ enumerator->public.enumerate = (void*)enumerate;
+ enumerator->public.destroy = (void*)free;
+ return &enumerator->public;
+}
+
+/**
* implementation of socket_t.destroy
*/
static void destroy(private_socket_t *this)
@@ -529,12 +557,12 @@ static void destroy(private_socket_t *this)
*/
socket_t *socket_create()
{
- int key;
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;
@@ -542,15 +570,6 @@ socket_t *socket_create()
this->ipv4_natt = 0;
this->ipv6_natt = 0;
- /* we open a AF_KEY socket to autoload the af_key module. Otherwise
- * setsockopt(IPSEC_POLICY) won't work. */
- key = socket(AF_KEY, SOCK_RAW, PF_KEY_V2);
- if (key == 0)
- {
- charon->kill(charon, "could not open AF_KEY socket");
- }
- close(key);
-
this->ipv4 = open_socket(this, AF_INET, IKEV2_UDP_PORT);
if (this->ipv4 == 0)
{
diff --git a/src/charon/network/socket.h b/src/charon/network/socket.h
index b76a9b0c3..4e967f721 100644
--- a/src/charon/network/socket.h
+++ b/src/charon/network/socket.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2008 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -14,7 +14,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * $Id: socket.h 4355 2008-09-25 07:56:58Z tobias $
+ * $Id: socket.h 4647 2008-11-13 07:48:27Z martin $
*/
/**
@@ -30,15 +30,13 @@ typedef struct socket_t socket_t;
#include <library.h>
#include <network/packet.h>
#include <utils/host.h>
-#include <utils/linked_list.h>
+#include <utils/enumerator.h>
/**
* Maximum size of a packet.
*
- * 3000 Bytes should be sufficient, see IKEv2 RFC. However, we currently
- * do not support HASH_AND_URL certificates, so we require to transmit
- * the full certificates. To run our multi-CA test with 2 intermediate CAs,
- * 5000 bytes is sufficient.
+ * 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
@@ -73,9 +71,8 @@ struct socket_t {
/**
* Send a packet.
*
- * Sends a packet to the net using destination from the packet.
- * Packet is sent using default routing mechanisms, thus the
- * source address in packet is ignored.
+ * Sends a packet to the net using source and destination addresses of
+ * the packet.
*
* @param packet packet_t to send
* @return
@@ -85,6 +82,13 @@ struct socket_t {
status_t (*send) (socket_t *this, packet_t *packet);
/**
+ * Enumerate all underlying socket file descriptors.
+ *
+ * @return enumerator over (int fd, int family, int port)
+ */
+ enumerator_t *(*create_enumerator) (socket_t *this);
+
+ /**
* Destroy socket.
*/
void (*destroy) (socket_t *this);