diff options
Diffstat (limited to 'src/charon/network')
-rw-r--r-- | src/charon/network/sender.c | 49 | ||||
-rw-r--r-- | src/charon/network/socket-raw.c | 136 | ||||
-rw-r--r-- | src/charon/network/socket.c | 109 | ||||
-rw-r--r-- | src/charon/network/socket.h | 24 |
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); |