summaryrefslogtreecommitdiff
path: root/src/charon/network
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon/network')
-rw-r--r--src/charon/network/packet.c159
-rw-r--r--src/charon/network/packet.h115
-rw-r--r--src/charon/network/receiver.c389
-rw-r--r--src/charon/network/receiver.h70
-rw-r--r--src/charon/network/sender.c153
-rw-r--r--src/charon/network/sender.h62
-rw-r--r--src/charon/network/socket-raw.c761
-rw-r--r--src/charon/network/socket.c685
-rw-r--r--src/charon/network/socket.h102
9 files changed, 0 insertions, 2496 deletions
diff --git a/src/charon/network/packet.c b/src/charon/network/packet.c
deleted file mode 100644
index 19a62603d..000000000
--- a/src/charon/network/packet.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * 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 "packet.h"
-
-typedef struct private_packet_t private_packet_t;
-
-/**
- * Private data of an packet_t object.
- */
-struct private_packet_t {
-
- /**
- * Public part of a packet_t object.
- */
- packet_t public;
-
- /**
- * source address
- */
- host_t *source;
-
- /**
- * destination address
- */
- host_t *destination;
-
- /**
- * message data
- */
- chunk_t data;
-};
-
-/**
- * Implements packet_t.get_source
- */
-static void set_source(private_packet_t *this, host_t *source)
-{
- DESTROY_IF(this->source);
- this->source = source;
-}
-
-/**
- * Implements packet_t.set_destination
- */
-static void set_destination(private_packet_t *this, host_t *destination)
-{
- DESTROY_IF(this->destination);
- this->destination = destination;
-}
-
-/**
- * Implements packet_t.get_source
- */
-static host_t *get_source(private_packet_t *this)
-{
- return this->source;
-}
-
-/**
- * Implements packet_t.get_destination
- */
-static host_t *get_destination(private_packet_t *this)
-{
- return this->destination;
-}
-
-/**
- * Implements packet_t.get_data
- */
-static chunk_t get_data(private_packet_t *this)
-{
- return this->data;
-}
-
-/**
- * Implements packet_t.set_data
- */
-static void set_data(private_packet_t *this, chunk_t data)
-{
- free(this->data.ptr);
- this->data = data;
-}
-
-/**
- * Implements packet_t.destroy.
- */
-static void destroy(private_packet_t *this)
-{
- if (this->source != NULL)
- {
- this->source->destroy(this->source);
- }
- if (this->destination != NULL)
- {
- this->destination->destroy(this->destination);
- }
- free(this->data.ptr);
- free(this);
-}
-
-/**
- * Implements packet_t.clone.
- */
-static packet_t *clone_(private_packet_t *this)
-{
- private_packet_t *other = (private_packet_t*)packet_create();
-
- if (this->destination != NULL)
- {
- other->destination = this->destination->clone(this->destination);
- }
- if (this->source != NULL)
- {
- other->source = this->source->clone(this->source);
- }
- if (this->data.ptr != NULL)
- {
- other->data.ptr = clalloc(this->data.ptr,this->data.len);
- other->data.len = this->data.len;
- }
- return &(other->public);
-}
-
-/*
- * Documented in header
- */
-packet_t *packet_create(void)
-{
- private_packet_t *this = malloc_thing(private_packet_t);
-
- this->public.set_data = (void(*) (packet_t *,chunk_t)) set_data;
- this->public.get_data = (chunk_t(*) (packet_t *)) get_data;
- this->public.set_source = (void(*) (packet_t *,host_t*)) set_source;
- this->public.get_source = (host_t*(*) (packet_t *)) get_source;
- this->public.set_destination = (void(*) (packet_t *,host_t*)) set_destination;
- this->public.get_destination = (host_t*(*) (packet_t *)) get_destination;
- this->public.clone = (packet_t*(*) (packet_t *))clone_;
- this->public.destroy = (void(*) (packet_t *)) destroy;
-
- this->destination = NULL;
- this->source = NULL;
- this->data = chunk_empty;
-
- return &(this->public);
-}
diff --git a/src/charon/network/packet.h b/src/charon/network/packet.h
deleted file mode 100644
index 18d82c6fc..000000000
--- a/src/charon/network/packet.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * 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 packet packet
- * @{ @ingroup network
- */
-
-#ifndef PACKET_H_
-#define PACKET_H_
-
-typedef struct packet_t packet_t;
-
-#include <library.h>
-#include <utils/host.h>
-
-/**
- * Abstraction of an UDP-Packet, contains data, sender and receiver.
- */
-struct packet_t {
-
- /**
- * Set the source address.
- *
- * Set host_t is now owned by packet_t, it will destroy
- * it if necessary.
- *
- * @param source address to set as source
- */
- void (*set_source) (packet_t *packet, host_t *source);
-
- /**
- * Set the destination address.
- *
- * Set host_t is now owned by packet_t, it will destroy
- * it if necessary.
- *
- * @param source address to set as destination
- */
- void (*set_destination) (packet_t *packet, host_t *destination);
-
- /**
- * Get the source address.
- *
- * Set host_t is still owned by packet_t, clone it
- * if needed.
- *
- * @return source address
- */
- host_t *(*get_source) (packet_t *packet);
-
- /**
- * Get the destination address.
- *
- * Set host_t is still owned by packet_t, clone it
- * if needed.
- *
- * @return destination address
- */
- host_t *(*get_destination) (packet_t *packet);
-
- /**
- * Get the data from the packet.
- *
- * The data pointed by the chunk is still owned
- * by the packet. Clone it if needed.
- *
- * @return chunk containing the data
- */
- chunk_t (*get_data) (packet_t *packet);
-
- /**
- * Set the data in the packet.
- *
- * Supplied chunk data is now owned by the
- * packet. It will free it.
- *
- * @param data chunk with data to set
- */
- void (*set_data) (packet_t *packet, chunk_t data);
-
- /**
- * Clones a packet_t object.
- *
- * @param clone clone of the packet
- */
- packet_t* (*clone) (packet_t *packet);
-
- /**
- * Destroy the packet, freeing contained data.
- */
- void (*destroy) (packet_t *packet);
-};
-
-/**
- * create an empty packet
- *
- * @return packet_t object
- */
-packet_t *packet_create(void);
-
-#endif /** PACKET_H_ @}*/
diff --git a/src/charon/network/receiver.c b/src/charon/network/receiver.c
deleted file mode 100644
index 6cd99439b..000000000
--- a/src/charon/network/receiver.c
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * Copyright (C) 2008 Tobias Brunner
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * 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 <stdlib.h>
-#include <unistd.h>
-
-#include "receiver.h"
-
-#include <daemon.h>
-#include <network/socket.h>
-#include <network/packet.h>
-#include <processing/jobs/job.h>
-#include <processing/jobs/process_message_job.h>
-#include <processing/jobs/callback_job.h>
-#include <crypto/hashers/hasher.h>
-
-/** lifetime of a cookie, in seconds */
-#define COOKIE_LIFETIME 10
-/** how many times to reuse the secret */
-#define COOKIE_REUSE 10000
-/** default value for private_receiver_t.cookie_threshold */
-#define COOKIE_THRESHOLD_DEFAULT 10
-/** default value for private_receiver_t.block_threshold */
-#define BLOCK_THRESHOLD_DEFAULT 5
-/** length of the secret to use for cookie calculation */
-#define SECRET_LENGTH 16
-
-typedef struct private_receiver_t private_receiver_t;
-
-/**
- * Private data of a receiver_t object.
- */
-struct private_receiver_t {
- /**
- * Public part of a receiver_t object.
- */
- receiver_t public;
-
- /**
- * Threads job receiving packets
- */
- callback_job_t *job;
-
- /**
- * current secret to use for cookie calculation
- */
- char secret[SECRET_LENGTH];
-
- /**
- * previous secret used to verify older cookies
- */
- char secret_old[SECRET_LENGTH];
-
- /**
- * how many times we have used "secret" so far
- */
- u_int32_t secret_used;
-
- /**
- * time we did the cookie switch
- */
- u_int32_t secret_switch;
-
- /**
- * time offset to use, hides our system time
- */
- u_int32_t secret_offset;
-
- /**
- * the RNG to use for secret generation
- */
- rng_t *rng;
-
- /**
- * hasher to use for cookie calculation
- */
- hasher_t *hasher;
-
- /**
- * require cookies after this many half open IKE_SAs
- */
- u_int32_t cookie_threshold;
-
- /**
- * how many half open IKE_SAs per peer before blocking
- */
- u_int32_t block_threshold;
-};
-
-/**
- * send a notify back to the sender
- */
-static void send_notify(message_t *request, notify_type_t type, chunk_t data)
-{
- if (request->get_request(request) &&
- request->get_exchange_type(request) == IKE_SA_INIT)
- {
- message_t *response;
- host_t *src, *dst;
- packet_t *packet;
- ike_sa_id_t *ike_sa_id;
-
- response = message_create();
- dst = request->get_source(request);
- src = request->get_destination(request);
- response->set_source(response, src->clone(src));
- response->set_destination(response, dst->clone(dst));
- response->set_exchange_type(response, request->get_exchange_type(request));
- response->set_request(response, FALSE);
- response->set_message_id(response, 0);
- ike_sa_id = request->get_ike_sa_id(request);
- ike_sa_id->switch_initiator(ike_sa_id);
- response->set_ike_sa_id(response, ike_sa_id);
- response->add_notify(response, FALSE, type, data);
- if (response->generate(response, NULL, NULL, &packet) == SUCCESS)
- {
- charon->sender->send(charon->sender, packet);
- response->destroy(response);
- }
- }
-}
-
-/**
- * build a cookie
- */
-static chunk_t cookie_build(private_receiver_t *this, message_t *message,
- u_int32_t t, chunk_t secret)
-{
- u_int64_t spi = message->get_initiator_spi(message);
- host_t *ip = message->get_source(message);
- chunk_t input, hash;
-
- /* COOKIE = t | sha1( IPi | SPIi | t | secret ) */
- input = chunk_cata("cccc", ip->get_address(ip), chunk_from_thing(spi),
- chunk_from_thing(t), secret);
- hash = chunk_alloca(this->hasher->get_hash_size(this->hasher));
- this->hasher->get_hash(this->hasher, input, hash.ptr);
- return chunk_cat("cc", chunk_from_thing(t), hash);
-}
-
-/**
- * verify a received cookie
- */
-static bool cookie_verify(private_receiver_t *this, message_t *message,
- chunk_t cookie)
-{
- u_int32_t t, now;
- chunk_t reference;
- chunk_t secret;
-
- now = time_monotonic(NULL);
- t = *(u_int32_t*)cookie.ptr;
-
- if (cookie.len != sizeof(u_int32_t) +
- this->hasher->get_hash_size(this->hasher) ||
- t < now - this->secret_offset - COOKIE_LIFETIME)
- {
- DBG2(DBG_NET, "received cookie lifetime expired, rejecting");
- return FALSE;
- }
-
- /* check if cookie is derived from old_secret */
- if (t + this->secret_offset > this->secret_switch)
- {
- secret = chunk_from_thing(this->secret);
- }
- else
- {
- secret = chunk_from_thing(this->secret_old);
- }
-
- /* compare own calculation against received */
- reference = cookie_build(this, message, t, secret);
- if (chunk_equals(reference, cookie))
- {
- chunk_free(&reference);
- return TRUE;
- }
- chunk_free(&reference);
- return FALSE;
-}
-
-/**
- * check if cookies are required, and if so, a valid cookie is included
- */
-static bool cookie_required(private_receiver_t *this, message_t *message)
-{
- bool failed = FALSE;
-
- if (charon->ike_sa_manager->get_half_open_count(charon->ike_sa_manager,
- NULL) >= this->cookie_threshold)
- {
- /* check for a cookie. We don't use our parser here and do it
- * quick and dirty for performance reasons.
- * we assume the cookie is the first payload (which is a MUST), and
- * the cookie's SPI length is zero. */
- packet_t *packet = message->get_packet(message);
- chunk_t data = packet->get_data(packet);
- if (data.len <
- IKE_HEADER_LENGTH + NOTIFY_PAYLOAD_HEADER_LENGTH +
- sizeof(u_int32_t) + this->hasher->get_hash_size(this->hasher) ||
- *(data.ptr + 16) != NOTIFY ||
- *(u_int16_t*)(data.ptr + IKE_HEADER_LENGTH + 6) != htons(COOKIE))
- {
- /* no cookie found */
- failed = TRUE;
- }
- else
- {
- data.ptr += IKE_HEADER_LENGTH + NOTIFY_PAYLOAD_HEADER_LENGTH;
- data.len = sizeof(u_int32_t) + this->hasher->get_hash_size(this->hasher);
- if (!cookie_verify(this, message, data))
- {
- DBG2(DBG_NET, "found cookie, but content invalid");
- failed = TRUE;
- }
- }
- packet->destroy(packet);
- }
- return failed;
-}
-
-/**
- * check if peer has to many half open IKE_SAs
- */
-static bool peer_to_aggressive(private_receiver_t *this, message_t *message)
-{
- if (charon->ike_sa_manager->get_half_open_count(charon->ike_sa_manager,
- message->get_source(message)) >= this->block_threshold)
- {
- return TRUE;
- }
- return FALSE;
-}
-
-/**
- * Implementation of receiver_t.receive_packets.
- */
-static job_requeue_t receive_packets(private_receiver_t *this)
-{
- packet_t *packet;
- message_t *message;
- job_t *job;
-
- /* read in a packet */
- if (charon->socket->receive(charon->socket, &packet) != SUCCESS)
- {
- DBG2(DBG_NET, "receiving from socket failed!");
- return JOB_REQUEUE_FAIR;
- }
-
- /* parse message header */
- message = message_create_from_packet(packet);
- if (message->parse_header(message) != SUCCESS)
- {
- DBG1(DBG_NET, "received invalid IKE header from %H - ignored",
- packet->get_source(packet));
- message->destroy(message);
- return JOB_REQUEUE_DIRECT;
- }
-
- /* check IKE major version */
- if (message->get_major_version(message) != IKE_MAJOR_VERSION)
- {
- DBG1(DBG_NET, "received unsupported IKE version %d.%d from %H, "
- "sending INVALID_MAJOR_VERSION", message->get_major_version(message),
- message->get_minor_version(message), packet->get_source(packet));
- send_notify(message, INVALID_MAJOR_VERSION, chunk_empty);
- message->destroy(message);
- return JOB_REQUEUE_DIRECT;
- }
-
- if (message->get_request(message) &&
- message->get_exchange_type(message) == IKE_SA_INIT)
- {
- /* check for cookies */
- if (this->cookie_threshold && cookie_required(this, message))
- {
- u_int32_t now = time_monotonic(NULL);
- chunk_t cookie = cookie_build(this, message, now - this->secret_offset,
- chunk_from_thing(this->secret));
-
- DBG2(DBG_NET, "received packet from: %#H to %#H",
- message->get_source(message),
- message->get_destination(message));
- DBG2(DBG_NET, "sending COOKIE notify to %H",
- message->get_source(message));
- send_notify(message, COOKIE, cookie);
- chunk_free(&cookie);
- if (++this->secret_used > COOKIE_REUSE)
- {
- /* create new cookie */
- DBG1(DBG_NET, "generating new cookie secret after %d uses",
- this->secret_used);
- memcpy(this->secret_old, this->secret, SECRET_LENGTH);
- this->rng->get_bytes(this->rng, SECRET_LENGTH, this->secret);
- this->secret_switch = now;
- this->secret_used = 0;
- }
- message->destroy(message);
- return JOB_REQUEUE_DIRECT;
- }
-
- /* check if peer has not too many IKE_SAs half open */
- if (this->block_threshold && peer_to_aggressive(this, message))
- {
- DBG1(DBG_NET, "ignoring IKE_SA setup from %H, "
- "peer too aggressive", message->get_source(message));
- message->destroy(message);
- return JOB_REQUEUE_DIRECT;
- }
- }
- job = (job_t*)process_message_job_create(message);
- charon->processor->queue_job(charon->processor, job);
- return JOB_REQUEUE_DIRECT;
-}
-
-/**
- * Implementation of receiver_t.destroy.
- */
-static void destroy(private_receiver_t *this)
-{
- this->job->cancel(this->job);
- this->rng->destroy(this->rng);
- this->hasher->destroy(this->hasher);
- free(this);
-}
-
-/*
- * Described in header.
- */
-receiver_t *receiver_create()
-{
- private_receiver_t *this = malloc_thing(private_receiver_t);
- u_int32_t now = time_monotonic(NULL);
-
- this->public.destroy = (void(*)(receiver_t*)) destroy;
-
- this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_PREFERRED);
- if (this->hasher == NULL)
- {
- DBG1(DBG_NET, "creating cookie hasher failed, no hashers supported");
- free(this);
- return NULL;
- }
- this->rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
- if (this->rng == NULL)
- {
- DBG1(DBG_NET, "creating cookie RNG failed, no RNG supported");
- this->hasher->destroy(this->hasher);
- free(this);
- return NULL;
- }
- this->secret_switch = now;
- this->secret_offset = random() % now;
- this->secret_used = 0;
- this->rng->get_bytes(this->rng, SECRET_LENGTH, this->secret);
- memcpy(this->secret_old, this->secret, SECRET_LENGTH);
- this->cookie_threshold = lib->settings->get_int(lib->settings,
- "charon.cookie_threshold", COOKIE_THRESHOLD_DEFAULT);
- this->block_threshold = lib->settings->get_int(lib->settings,
- "charon.block_threshold", BLOCK_THRESHOLD_DEFAULT);
- if (!lib->settings->get_bool(lib->settings, "charon.dos_protection", TRUE))
- {
- this->cookie_threshold = 0;
- this->block_threshold = 0;
- }
-
- this->job = callback_job_create((callback_job_cb_t)receive_packets,
- this, NULL, NULL);
- charon->processor->queue_job(charon->processor, (job_t*)this->job);
-
- return &this->public;
-}
-
diff --git a/src/charon/network/receiver.h b/src/charon/network/receiver.h
deleted file mode 100644
index 690d8dbab..000000000
--- a/src/charon/network/receiver.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2005-2007 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * 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 receiver receiver
- * @{ @ingroup network
- */
-
-#ifndef RECEIVER_H_
-#define RECEIVER_H_
-
-typedef struct receiver_t receiver_t;
-
-#include <library.h>
-#include <utils/host.h>
-
-/**
- * Receives packets from the socket and adds them to the job queue.
- *
- * The receiver starts a thread, wich reads on the blocking socket. A received
- * packet is preparsed and a process_message_job is queued in the job queue.
- *
- * To endure DoS attacks, cookies are enabled when to many IKE_SAs are half
- * open. The calculation of cookies is slightly different from the proposed
- * method in RFC4306. We do not include a nonce, because we think the advantage
- * we gain does not justify the overhead to parse the whole message.
- * Instead of VersionIdOfSecret, we include a timestamp. This allows us to
- * find out wich key was used for cookie creation. Further, we can set a
- * lifetime for the cookie, which allows us to reuse the secret for a longer
- * time.
- * COOKIE = time | sha1( IPi | SPIi | time | secret )
- *
- * The secret is changed after a certain amount of cookies sent. The old
- * secret is stored to allow a clean migration between secret changes.
- *
- * Further, the number of half-initiated IKE_SAs is limited per peer. This
- * mades it impossible for a peer to flood the server with its real IP address.
- */
-struct receiver_t {
-
- /**
- * Destroys a receiver_t object.
- */
- void (*destroy) (receiver_t *receiver);
-};
-
-/**
- * Create a receiver_t object.
- *
- * The receiver thread will start working, get data
- * from the socket and add those packets to the job queue.
- *
- * @return receiver_t object, NULL if initialization fails
- */
-receiver_t * receiver_create(void);
-
-#endif /** RECEIVER_H_ @}*/
diff --git a/src/charon/network/sender.c b/src/charon/network/sender.c
deleted file mode 100644
index 3be5861dd..000000000
--- a/src/charon/network/sender.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * 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 <stdlib.h>
-
-#include "sender.h"
-
-#include <daemon.h>
-#include <network/socket.h>
-#include <processing/jobs/callback_job.h>
-#include <threading/thread.h>
-#include <threading/condvar.h>
-#include <threading/mutex.h>
-
-
-typedef struct private_sender_t private_sender_t;
-
-/**
- * Private data of a sender_t object.
- */
-struct private_sender_t {
- /**
- * Public part of a sender_t object.
- */
- sender_t public;
-
- /**
- * Sender threads job.
- */
- callback_job_t *job;
-
- /**
- * The packets are stored in a linked list
- */
- linked_list_t *list;
-
- /**
- * mutex to synchronize access to list
- */
- mutex_t *mutex;
-
- /**
- * condvar to signal for packets added to list
- */
- condvar_t *got;
-
- /**
- * condvar to signal for packets sent
- */
- condvar_t *sent;
-};
-
-/**
- * implements sender_t.send
- */
-static void send_(private_sender_t *this, packet_t *packet)
-{
- host_t *src, *dst;
-
- src = packet->get_source(packet);
- dst = packet->get_destination(packet);
- DBG1(DBG_NET, "sending packet: from %#H to %#H", src, dst);
-
- this->mutex->lock(this->mutex);
- this->list->insert_last(this->list, packet);
- this->got->signal(this->got);
- this->mutex->unlock(this->mutex);
-}
-
-/**
- * Implementation of private_sender_t.send_packets.
- */
-static job_requeue_t send_packets(private_sender_t * this)
-{
- packet_t *packet;
- bool oldstate;
-
- this->mutex->lock(this->mutex);
- while (this->list->get_count(this->list) == 0)
- {
- /* add cleanup handler, wait for packet, remove cleanup handler */
- thread_cleanup_push((thread_cleanup_t)this->mutex->unlock, this->mutex);
- oldstate = thread_cancelability(TRUE);
-
- this->got->wait(this->got, this->mutex);
-
- thread_cancelability(oldstate);
- thread_cleanup_pop(FALSE);
- }
- this->list->remove_first(this->list, (void**)&packet);
- this->sent->signal(this->sent);
- this->mutex->unlock(this->mutex);
-
- charon->socket->send(charon->socket, packet);
- packet->destroy(packet);
- return JOB_REQUEUE_DIRECT;
-}
-
-/**
- * Implementation of sender_t.destroy.
- */
-static void destroy(private_sender_t *this)
-{
- /* send all packets in the queue */
- this->mutex->lock(this->mutex);
- while (this->list->get_count(this->list))
- {
- this->sent->wait(this->sent, 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);
-}
-
-/*
- * Described in header.
- */
-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();
- this->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
- this->got = condvar_create(CONDVAR_TYPE_DEFAULT);
- this->sent = condvar_create(CONDVAR_TYPE_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/sender.h b/src/charon/network/sender.h
deleted file mode 100644
index f77fadab2..000000000
--- a/src/charon/network/sender.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2005-2007 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * 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 sender sender
- * @{ @ingroup network
- */
-
-#ifndef SENDER_H_
-#define SENDER_H_
-
-typedef struct sender_t sender_t;
-
-#include <library.h>
-#include <network/packet.h>
-
-/**
- * Thread responsible for sending packets over the socket.
- */
-struct sender_t {
-
- /**
- * Send a packet over the network.
- *
- * This function is non blocking and adds the packet to a queue.
- * Whenever the sender thread thinks it's good to send the packet,
- * it'll do so.
- *
- * @param packet packet to send
- */
- void (*send) (sender_t *this, packet_t *packet);
-
- /**
- * Destroys a sender object.
- */
- void (*destroy) (sender_t *this);
-};
-
-/**
- * Create the sender thread.
- *
- * The thread will start to work, getting packets
- * from its queue and sends them out.
- *
- * @return created sender object
- */
-sender_t * sender_create(void);
-
-#endif /** SENDER_H_ @}*/
diff --git a/src/charon/network/socket-raw.c b/src/charon/network/socket-raw.c
deleted file mode 100644
index 6cc0463b2..000000000
--- a/src/charon/network/socket-raw.c
+++ /dev/null
@@ -1,761 +0,0 @@
-/*
- * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
- * Copyright (C) 2005-2008 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * 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.
- */
-
-/* for struct in6_pktinfo */
-#define _GNU_SOURCE
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/ip6.h>
-#include <netinet/udp.h>
-#include <linux/types.h>
-#include <linux/filter.h>
-#include <net/if.h>
-
-#include "socket.h"
-
-#include <daemon.h>
-#include <threading/thread.h>
-
-/* constants for packet handling */
-#define IP_LEN sizeof(struct iphdr)
-#define IP6_LEN sizeof(struct ip6_hdr)
-#define UDP_LEN sizeof(struct udphdr)
-#define MARKER_LEN sizeof(u_int32_t)
-
-/* offsets for packet handling */
-#define IP_PROTO_OFFSET 9
-#define IP6_PROTO_OFFSET 6
-#define IKE_VERSION_OFFSET 17
-#define IKE_LENGTH_OFFSET 24
-
-/* from linux/udp.h */
-#ifndef UDP_ENCAP
-#define UDP_ENCAP 100
-#endif /*UDP_ENCAP*/
-
-#ifndef UDP_ENCAP_ESPINUDP
-#define UDP_ENCAP_ESPINUDP 2
-#endif /*UDP_ENCAP_ESPINUDP*/
-
-/* needed for older kernel headers */
-#ifndef IPV6_2292PKTINFO
-#define IPV6_2292PKTINFO 2
-#endif /*IPV6_2292PKTINFO*/
-
-typedef struct private_socket_t private_socket_t;
-
-/**
- * Private data of an socket_t object
- */
-struct private_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;
-};
-
-/**
- * implementation of socket_t.receive
- */
-static status_t receiver(private_socket_t *this, packet_t **packet)
-{
- char buffer[MAX_PACKET];
- chunk_t data;
- packet_t *pkt;
- struct udphdr *udp;
- host_t *source = NULL, *dest = NULL;
- int bytes_read = 0, data_offset;
- bool oldstate;
- fd_set rfds;
-
- FD_ZERO(&rfds);
-
- if (this->recv4)
- {
- FD_SET(this->recv4, &rfds);
- }
- if (this->recv6)
- {
- FD_SET(this->recv6, &rfds);
- }
-
- DBG2(DBG_NET, "waiting for data on raw sockets");
-
- oldstate = thread_cancelability(TRUE);
- if (select(max(this->recv4, this->recv6) + 1, &rfds, NULL, NULL, NULL) <= 0)
- {
- thread_cancelability(oldstate);
- return FAILED;
- }
- thread_cancelability(oldstate);
-
- if (this->recv4 && FD_ISSET(this->recv4, &rfds))
- {
- /* IPv4 raw sockets return the IP header. We read src/dest
- * information directly from the raw header */
- struct iphdr *ip;
- struct sockaddr_in src, dst;
-
- bytes_read = recv(this->recv4, buffer, MAX_PACKET, 0);
- if (bytes_read < 0)
- {
- DBG1(DBG_NET, "error reading from IPv4 socket: %s", strerror(errno));
- return FAILED;
- }
- DBG3(DBG_NET, "received IPv4 packet %b", buffer, bytes_read);
-
- /* read source/dest from raw IP/UDP header */
- if (bytes_read < IP_LEN + UDP_LEN + MARKER_LEN)
- {
- DBG1(DBG_NET, "received IPv4 packet too short (%d bytes)",
- bytes_read);
- return FAILED;
- }
- ip = (struct iphdr*) buffer;
- udp = (struct udphdr*) (buffer + IP_LEN);
- src.sin_family = AF_INET;
- src.sin_addr.s_addr = ip->saddr;
- src.sin_port = udp->source;
- dst.sin_family = AF_INET;
- dst.sin_addr.s_addr = ip->daddr;
- dst.sin_port = udp->dest;
- source = host_create_from_sockaddr((sockaddr_t*)&src);
- dest = host_create_from_sockaddr((sockaddr_t*)&dst);
-
- pkt = packet_create();
- pkt->set_source(pkt, source);
- pkt->set_destination(pkt, dest);
- DBG2(DBG_NET, "received packet: from %#H to %#H", source, dest);
- data_offset = IP_LEN + UDP_LEN;
- /* remove non esp marker */
- if (dest->get_port(dest) == IKEV2_NATT_PORT)
- {
- data_offset += MARKER_LEN;
- }
- /* fill in packet */
- data.len = bytes_read - data_offset;
- data.ptr = malloc(data.len);
- memcpy(data.ptr, buffer + data_offset, data.len);
- pkt->set_data(pkt, data);
- }
- else if (this->recv6 && FD_ISSET(this->recv6, &rfds))
- {
- /* IPv6 raw sockets return no IP header. We must query
- * src/dest via socket options/ancillary data */
- struct msghdr msg;
- struct cmsghdr *cmsgptr;
- struct sockaddr_in6 src, dst;
- struct iovec iov;
- char ancillary[64];
-
- msg.msg_name = &src;
- msg.msg_namelen = sizeof(src);
- iov.iov_base = buffer;
- iov.iov_len = sizeof(buffer);
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = ancillary;
- msg.msg_controllen = sizeof(ancillary);
- msg.msg_flags = 0;
-
- bytes_read = recvmsg(this->recv6, &msg, 0);
- if (bytes_read < 0)
- {
- DBG1(DBG_NET, "error reading from IPv6 socket: %s", strerror(errno));
- return FAILED;
- }
- DBG3(DBG_NET, "received IPv6 packet %b", buffer, bytes_read);
-
- if (bytes_read < IP_LEN + UDP_LEN + MARKER_LEN)
- {
- DBG3(DBG_NET, "received IPv6 packet too short (%d bytes)",
- bytes_read);
- return FAILED;
- }
-
- /* read ancillary data to get destination address */
- for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL;
- cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
- {
- if (cmsgptr->cmsg_len == 0)
- {
- DBG1(DBG_NET, "error reading IPv6 ancillary data");
- return FAILED;
- }
- if (cmsgptr->cmsg_level == SOL_IPV6 &&
- cmsgptr->cmsg_type == IPV6_2292PKTINFO)
- {
- struct in6_pktinfo *pktinfo;
- pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsgptr);
-
- memset(&dst, 0, sizeof(dst));
- memcpy(&dst.sin6_addr, &pktinfo->ipi6_addr, sizeof(dst.sin6_addr));
- dst.sin6_family = AF_INET6;
- udp = (struct udphdr*) (buffer);
- dst.sin6_port = udp->dest;
- src.sin6_port = udp->source;
- dest = host_create_from_sockaddr((sockaddr_t*)&dst);
- }
- }
- /* ancillary data missing? */
- if (dest == NULL)
- {
- DBG1(DBG_NET, "error reading IPv6 packet header");
- return FAILED;
- }
-
- source = host_create_from_sockaddr((sockaddr_t*)&src);
-
- pkt = packet_create();
- pkt->set_source(pkt, source);
- pkt->set_destination(pkt, dest);
- DBG2(DBG_NET, "received packet: from %#H to %#H", source, dest);
- data_offset = UDP_LEN;
- /* remove non esp marker */
- if (dest->get_port(dest) == IKEV2_NATT_PORT)
- {
- data_offset += MARKER_LEN;
- }
- /* fill in packet */
- data.len = bytes_read - data_offset;
- data.ptr = malloc(data.len);
- memcpy(data.ptr, buffer + data_offset, data.len);
- pkt->set_data(pkt, data);
- }
- else
- {
- /* oops, shouldn't happen */
- return FAILED;
- }
-
- /* return packet */
- *packet = pkt;
- return SUCCESS;
-}
-
-/**
- * implementation of socket_t.send
- */
-status_t sender(private_socket_t *this, packet_t *packet)
-{
- int sport, skt, family;
- ssize_t bytes_sent;
- chunk_t data, marked;
- host_t *src, *dst;
- struct msghdr msg;
- struct cmsghdr *cmsg;
- struct iovec iov;
-
- src = packet->get_source(packet);
- dst = packet->get_destination(packet);
- data = packet->get_data(packet);
-
- DBG2(DBG_NET, "sending packet: from %#H to %#H", src, dst);
-
- /* send data */
- sport = src->get_port(src);
- family = dst->get_family(dst);
- if (sport == IKEV2_UDP_PORT)
- {
- if (family == AF_INET)
- {
- skt = this->send4;
- }
- else
- {
- skt = this->send6;
- }
- }
- else if (sport == IKEV2_NATT_PORT)
- {
- if (family == AF_INET)
- {
- skt = this->send4_natt;
- }
- else
- {
- skt = this->send6_natt;
- }
- /* NAT keepalives without marker */
- if (data.len != 1 || data.ptr[0] != 0xFF)
- {
- /* add non esp marker to packet */
- if (data.len > MAX_PACKET - MARKER_LEN)
- {
- DBG1(DBG_NET, "unable to send packet: it's too big (%d bytes)",
- data.len);
- return FAILED;
- }
- marked = chunk_alloc(data.len + MARKER_LEN);
- memset(marked.ptr, 0, MARKER_LEN);
- memcpy(marked.ptr + MARKER_LEN, data.ptr, data.len);
- /* let the packet do the clean up for us */
- packet->set_data(packet, marked);
- data = marked;
- }
- }
- else
- {
- DBG1(DBG_NET, "unable to locate a send socket for port %d", sport);
- return FAILED;
- }
-
- memset(&msg, 0, sizeof(struct msghdr));
- msg.msg_name = dst->get_sockaddr(dst);;
- msg.msg_namelen = *dst->get_sockaddr_len(dst);
- iov.iov_base = data.ptr;
- iov.iov_len = data.len;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_flags = 0;
-
- if (!src->is_anyaddr(src))
- {
- if (family == AF_INET)
- {
- char buf[CMSG_SPACE(sizeof(struct in_pktinfo))];
- struct in_pktinfo *pktinfo;
- struct sockaddr_in *sin;
-
- msg.msg_control = buf;
- msg.msg_controllen = sizeof(buf);
- cmsg = CMSG_FIRSTHDR(&msg);
- cmsg->cmsg_level = SOL_IP;
- cmsg->cmsg_type = IP_PKTINFO;
- cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
- pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsg);
- memset(pktinfo, 0, sizeof(struct in_pktinfo));
- sin = (struct sockaddr_in*)src->get_sockaddr(src);
- memcpy(&pktinfo->ipi_spec_dst, &sin->sin_addr, sizeof(struct in_addr));
- }
- else
- {
- char buf[CMSG_SPACE(sizeof(struct in6_pktinfo))];
- struct in6_pktinfo *pktinfo;
- struct sockaddr_in6 *sin;
-
- msg.msg_control = buf;
- msg.msg_controllen = sizeof(buf);
- cmsg = CMSG_FIRSTHDR(&msg);
- cmsg->cmsg_level = SOL_IPV6;
- cmsg->cmsg_type = IPV6_2292PKTINFO;
- cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
- pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsg);
- memset(pktinfo, 0, sizeof(struct in6_pktinfo));
- sin = (struct sockaddr_in6*)src->get_sockaddr(src);
- memcpy(&pktinfo->ipi6_addr, &sin->sin6_addr, sizeof(struct in6_addr));
- }
- }
-
- bytes_sent = sendmsg(skt, &msg, 0);
-
- if (bytes_sent != data.len)
- {
- DBG1(DBG_NET, "error writing to socket: %s", strerror(errno));
- return FAILED;
- }
- return SUCCESS;
-}
-
-/**
- * open a socket to send packets
- */
-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;
- int skt;
-
- memset(&addr, 0, sizeof(addr));
- /* precalculate constants depending on address family */
- switch (family)
- {
- case AF_INET:
- {
- struct sockaddr_in *sin = (struct sockaddr_in *)&addr;
- sin->sin_family = AF_INET;
- sin->sin_addr.s_addr = INADDR_ANY;
- sin->sin_port = htons(port);
- sol = SOL_IP;
- break;
- }
- case AF_INET6:
- {
- struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&addr;
- sin6->sin6_family = AF_INET6;
- memcpy(&sin6->sin6_addr, &in6addr_any, sizeof(in6addr_any));
- sin6->sin6_port = htons(port);
- sol = SOL_IPV6;
- break;
- }
- default:
- return 0;
- }
-
- skt = socket(family, SOCK_DGRAM, IPPROTO_UDP);
- if (skt < 0)
- {
- DBG1(DBG_NET, "could not open send socket: %s", strerror(errno));
- return 0;
- }
-
- if (setsockopt(skt, SOL_SOCKET, SO_REUSEADDR, (void*)&on, sizeof(on)) < 0)
- {
- DBG1(DBG_NET, "unable to set SO_REUSEADDR on send socket: %s",
- strerror(errno));
- close(skt);
- return 0;
- }
-
- /* bind the send socket */
- if (bind(skt, (struct sockaddr *)&addr, sizeof(addr)) < 0)
- {
- DBG1(DBG_NET, "unable to bind send socket: %s",
- strerror(errno));
- close(skt);
- return 0;
- }
-
- if (family == AF_INET)
- {
- /* enable UDP decapsulation globally, only for one socket needed */
- if (setsockopt(skt, SOL_UDP, UDP_ENCAP, &type, sizeof(type)) < 0)
- {
- DBG1(DBG_NET, "unable to set UDP_ENCAP: %s; NAT-T may fail",
- strerror(errno));
- }
- }
-
- return skt;
-}
-
-/**
- * open a socket to receive packets
- */
-static int open_recv_socket(private_socket_t *this, int family)
-{
- int skt;
- int on = TRUE;
- u_int proto_offset, ip_len, sol, udp_header, ike_header;
-
- /* precalculate constants depending on address family */
- switch (family)
- {
- case AF_INET:
- proto_offset = IP_PROTO_OFFSET;
- ip_len = IP_LEN;
- sol = SOL_IP;
- break;
- case AF_INET6:
- proto_offset = IP6_PROTO_OFFSET;
- ip_len = 0; /* IPv6 raw sockets contain no IP header */
- sol = SOL_IPV6;
- break;
- default:
- return 0;
- }
- udp_header = ip_len;
- ike_header = ip_len + UDP_LEN;
-
- /* This filter code filters out all non-IKEv2 traffic on
- * a SOCK_RAW IP_PROTP_UDP socket. Handling of other
- * IKE versions is done in pluto.
- */
- struct sock_filter ikev2_filter_code[] =
- {
- /* Destination Port must be either port or natt_port */
- BPF_STMT(BPF_LD+BPF_H+BPF_ABS, udp_header + 2),
- BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IKEV2_UDP_PORT, 1, 0),
- BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IKEV2_NATT_PORT, 5, 12),
- /* port */
- /* IKE version must be 2.0 */
- BPF_STMT(BPF_LD+BPF_B+BPF_ABS, ike_header + IKE_VERSION_OFFSET),
- BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x20, 0, 10),
- /* packet length is length in IKEv2 header + ip header + udp header */
- BPF_STMT(BPF_LD+BPF_W+BPF_ABS, ike_header + IKE_LENGTH_OFFSET),
- BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, ip_len + UDP_LEN),
- BPF_STMT(BPF_RET+BPF_A, 0),
- /* natt_port */
- /* nat-t: check for marker */
- BPF_STMT(BPF_LD+BPF_W+BPF_ABS, ike_header),
- BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 5),
- /* nat-t: IKE version must be 2.0 */
- BPF_STMT(BPF_LD+BPF_B+BPF_ABS, ike_header + MARKER_LEN + IKE_VERSION_OFFSET),
- BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x20, 0, 3),
- /* nat-t: packet length is length in IKEv2 header + ip header + udp header + non esp marker */
- BPF_STMT(BPF_LD+BPF_W+BPF_ABS, ike_header + MARKER_LEN + IKE_LENGTH_OFFSET),
- BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, ip_len + UDP_LEN + MARKER_LEN),
- BPF_STMT(BPF_RET+BPF_A, 0),
- /* packet doesn't match, ignore */
- BPF_STMT(BPF_RET+BPF_K, 0),
- };
-
- /* Filter struct to use with setsockopt */
- struct sock_fprog ikev2_filter = {
- sizeof(ikev2_filter_code) / sizeof(struct sock_filter),
- ikev2_filter_code
- };
-
- /* set up a raw socket */
- skt = socket(family, SOCK_RAW, IPPROTO_UDP);
- if (skt < 0)
- {
- DBG1(DBG_NET, "unable to create raw socket: %s", strerror(errno));
- return 0;
- }
-
- if (setsockopt(skt, SOL_SOCKET, SO_ATTACH_FILTER,
- &ikev2_filter, sizeof(ikev2_filter)) < 0)
- {
- DBG1(DBG_NET, "unable to attach IKEv2 filter to raw socket: %s",
- strerror(errno));
- close(skt);
- return 0;
- }
-
- if (family == AF_INET6 &&
- /* we use IPV6_2292PKTINFO, as IPV6_PKTINFO is defined as
- * 2 or 50 depending on kernel header version */
- setsockopt(skt, sol, IPV6_2292PKTINFO, &on, sizeof(on)) < 0)
- {
- DBG1(DBG_NET, "unable to set IPV6_PKTINFO on raw socket: %s",
- strerror(errno));
- close(skt);
- return 0;
- }
-
- 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 }
- };
-
- 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)
-{
- if (this->recv4)
- {
- close(this->recv4);
- }
- if (this->recv6)
- {
- close(this->recv6);
- }
- if (this->send4)
- {
- close(this->send4);
- }
- if (this->send6)
- {
- close(this->send6);
- }
- if (this->send4_natt)
- {
- close(this->send4_natt);
- }
- if (this->send6_natt)
- {
- close(this->send6_natt);
- }
- free(this);
-}
-
-/*
- * See header for description
- */
-socket_t *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;
-
- this->recv4 = open_recv_socket(this, AF_INET);
- if (this->recv4 == 0)
- {
- DBG1(DBG_NET, "could not open IPv4 receive socket, IPv4 disabled");
- }
- else
- {
- this->send4 = open_send_socket(this, AF_INET, IKEV2_UDP_PORT);
- if (this->send4 == 0)
- {
- DBG1(DBG_NET, "could not open IPv4 send socket, IPv4 disabled");
- close(this->recv4);
- }
- else
- {
- this->send4_natt = open_send_socket(this, AF_INET, IKEV2_NATT_PORT);
- if (this->send4_natt == 0)
- {
- DBG1(DBG_NET, "could not open IPv4 NAT-T send socket");
- }
- }
- }
-
- this->recv6 = open_recv_socket(this, AF_INET6);
- if (this->recv6 == 0)
- {
- DBG1(DBG_NET, "could not open IPv6 receive socket, IPv6 disabled");
- }
- else
- {
- this->send6 = open_send_socket(this, AF_INET6, IKEV2_UDP_PORT);
- if (this->send6 == 0)
- {
- DBG1(DBG_NET, "could not open IPv6 send socket, IPv6 disabled");
- close(this->recv6);
- }
- else
- {
- this->send6_natt = open_send_socket(this, AF_INET6, IKEV2_NATT_PORT);
- if (this->send6_natt == 0)
- {
- DBG1(DBG_NET, "could not open IPv6 NAT-T send socket");
- }
- }
- }
-
- if (!(this->send4 || this->send6) || !(this->recv4 || this->recv6))
- {
- DBG1(DBG_NET, "could not create any sockets");
- destroy(this);
- charon->kill(charon, "socket initialization failed");
- }
-
- return (socket_t*)this;
-}
diff --git a/src/charon/network/socket.c b/src/charon/network/socket.c
deleted file mode 100644
index 81f860b15..000000000
--- a/src/charon/network/socket.c
+++ /dev/null
@@ -1,685 +0,0 @@
-/*
- * Copyright (C) 2006-2009 Tobias Brunner
- * Copyright (C) 2006 Daniel Roethlisberger
- * Copyright (C) 2005-2007 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * 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.
- */
-
-/* for struct in6_pktinfo */
-#define _GNU_SOURCE
-#ifdef __sun
-#define _XPG4_2
-#define __EXTENSIONS__
-#endif
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/udp.h>
-#include <net/if.h>
-#ifdef __APPLE__
-#include <sys/sysctl.h>
-#endif
-
-#include "socket.h"
-
-#include <daemon.h>
-#include <threading/thread.h>
-
-/* length of non-esp marker */
-#define MARKER_LEN sizeof(u_int32_t)
-
-/* from linux/udp.h */
-#ifndef UDP_ENCAP
-#define UDP_ENCAP 100
-#endif /*UDP_ENCAP*/
-
-#ifndef UDP_ENCAP_ESPINUDP
-#define UDP_ENCAP_ESPINUDP 2
-#endif /*UDP_ENCAP_ESPINUDP*/
-
-/* these are not defined on some platforms */
-#ifndef SOL_IP
-#define SOL_IP IPPROTO_IP
-#endif
-#ifndef SOL_IPV6
-#define SOL_IPV6 IPPROTO_IPV6
-#endif
-#ifndef SOL_UDP
-#define SOL_UDP IPPROTO_UDP
-#endif
-
-/* IPV6_RECVPKTINFO is defined in RFC 3542 which obsoletes RFC 2292 that
- * previously defined IPV6_PKTINFO */
-#ifndef IPV6_RECVPKTINFO
-#define IPV6_RECVPKTINFO IPV6_PKTINFO
-#endif
-
-#ifndef IN6ADDR_ANY_INIT
-#define IN6ADDR_ANY_INIT {{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}
-#endif
-
-#ifndef HAVE_IN6ADDR_ANY
-static const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
-#endif
-
-typedef struct private_socket_t private_socket_t;
-
-/**
- * Private data of an socket_t object
- */
-struct private_socket_t {
- /**
- * public functions
- */
- socket_t public;
-
- /**
- * IPv4 socket (500)
- */
- int ipv4;
-
- /**
- * IPv4 socket for NATT (4500)
- */
- int ipv4_natt;
-
- /**
- * IPv6 socket (500)
- */
- int ipv6;
-
- /**
- * IPv6 socket for NATT (4500)
- */
- int ipv6_natt;
-};
-
-/**
- * implementation of socket_t.receive
- */
-static status_t receiver(private_socket_t *this, packet_t **packet)
-{
- char buffer[MAX_PACKET];
- chunk_t data;
- packet_t *pkt;
- host_t *source = NULL, *dest = NULL;
- int bytes_read = 0, data_offset;
- bool oldstate;
-
- fd_set rfds;
- int max_fd = 0, selected = 0;
- u_int16_t port = 0;
-
- FD_ZERO(&rfds);
-
- if (this->ipv4)
- {
- FD_SET(this->ipv4, &rfds);
- }
- if (this->ipv4_natt)
- {
- FD_SET(this->ipv4_natt, &rfds);
- }
- if (this->ipv6)
- {
- FD_SET(this->ipv6, &rfds);
- }
- if (this->ipv6_natt)
- {
- FD_SET(this->ipv6_natt, &rfds);
- }
- max_fd = max(max(this->ipv4, this->ipv4_natt), max(this->ipv6, this->ipv6_natt));
-
- DBG2(DBG_NET, "waiting for data on sockets");
- oldstate = thread_cancelability(TRUE);
- if (select(max_fd + 1, &rfds, NULL, NULL, NULL) <= 0)
- {
- thread_cancelability(oldstate);
- return FAILED;
- }
- thread_cancelability(oldstate);
-
- if (FD_ISSET(this->ipv4, &rfds))
- {
- port = IKEV2_UDP_PORT;
- selected = this->ipv4;
- }
- if (FD_ISSET(this->ipv4_natt, &rfds))
- {
- port = IKEV2_NATT_PORT;
- selected = this->ipv4_natt;
- }
- if (FD_ISSET(this->ipv6, &rfds))
- {
- port = IKEV2_UDP_PORT;
- selected = this->ipv6;
- }
- if (FD_ISSET(this->ipv6_natt, &rfds))
- {
- port = IKEV2_NATT_PORT;
- selected = this->ipv6_natt;
- }
- if (selected)
- {
- struct msghdr msg;
- struct cmsghdr *cmsgptr;
- struct iovec iov;
- char ancillary[64];
- union {
- struct sockaddr_in in4;
- struct sockaddr_in6 in6;
- } src;
-
- msg.msg_name = &src;
- msg.msg_namelen = sizeof(src);
- iov.iov_base = buffer;
- iov.iov_len = sizeof(buffer);
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = ancillary;
- msg.msg_controllen = sizeof(ancillary);
- msg.msg_flags = 0;
- bytes_read = recvmsg(selected, &msg, 0);
- if (bytes_read < 0)
- {
- DBG1(DBG_NET, "error reading socket: %s", strerror(errno));
- return FAILED;
- }
- DBG3(DBG_NET, "received packet %b", buffer, bytes_read);
-
- if (bytes_read < MARKER_LEN)
- {
- DBG3(DBG_NET, "received packet too short (%d bytes)",
- bytes_read);
- return FAILED;
- }
-
- /* read ancillary data to get destination address */
- for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL;
- cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
- {
- if (cmsgptr->cmsg_len == 0)
- {
- DBG1(DBG_NET, "error reading ancillary data");
- return FAILED;
- }
-
-#ifdef HAVE_IN6_PKTINFO
- if (cmsgptr->cmsg_level == SOL_IPV6 &&
- cmsgptr->cmsg_type == IPV6_PKTINFO)
- {
- struct in6_pktinfo *pktinfo;
- pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsgptr);
- struct sockaddr_in6 dst;
-
- memset(&dst, 0, sizeof(dst));
- memcpy(&dst.sin6_addr, &pktinfo->ipi6_addr, sizeof(dst.sin6_addr));
- dst.sin6_family = AF_INET6;
- dst.sin6_port = htons(port);
- dest = host_create_from_sockaddr((sockaddr_t*)&dst);
- }
-#endif /* HAVE_IN6_PKTINFO */
- if (cmsgptr->cmsg_level == SOL_IP &&
-#ifdef IP_PKTINFO
- cmsgptr->cmsg_type == IP_PKTINFO
-#elif defined(IP_RECVDSTADDR)
- cmsgptr->cmsg_type == IP_RECVDSTADDR
-#else
- FALSE
-#endif
- )
- {
- struct in_addr *addr;
- struct sockaddr_in dst;
-
-#ifdef IP_PKTINFO
- struct in_pktinfo *pktinfo;
- pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsgptr);
- addr = &pktinfo->ipi_addr;
-#elif defined(IP_RECVDSTADDR)
- addr = (struct in_addr*)CMSG_DATA(cmsgptr);
-#endif
- memset(&dst, 0, sizeof(dst));
- memcpy(&dst.sin_addr, addr, sizeof(dst.sin_addr));
-
- dst.sin_family = AF_INET;
- dst.sin_port = htons(port);
- dest = host_create_from_sockaddr((sockaddr_t*)&dst);
- }
- if (dest)
- {
- break;
- }
- }
- if (dest == NULL)
- {
- DBG1(DBG_NET, "error reading IP header");
- return FAILED;
- }
- source = host_create_from_sockaddr((sockaddr_t*)&src);
-
- pkt = packet_create();
- pkt->set_source(pkt, source);
- pkt->set_destination(pkt, dest);
- DBG2(DBG_NET, "received packet: from %#H to %#H", source, dest);
- data_offset = 0;
- /* remove non esp marker */
- if (dest->get_port(dest) == IKEV2_NATT_PORT)
- {
- data_offset += MARKER_LEN;
- }
- /* fill in packet */
- data.len = bytes_read - data_offset;
- data.ptr = malloc(data.len);
- memcpy(data.ptr, buffer + data_offset, data.len);
- pkt->set_data(pkt, data);
- }
- else
- {
- /* oops, shouldn't happen */
- return FAILED;
- }
- /* return packet */
- *packet = pkt;
- return SUCCESS;
-}
-
-/**
- * implementation of socket_t.send
- */
-status_t sender(private_socket_t *this, packet_t *packet)
-{
- int sport, skt, family;
- ssize_t bytes_sent;
- chunk_t data, marked;
- host_t *src, *dst;
- struct msghdr msg;
- struct cmsghdr *cmsg;
- struct iovec iov;
-
- src = packet->get_source(packet);
- dst = packet->get_destination(packet);
- data = packet->get_data(packet);
-
- DBG2(DBG_NET, "sending packet: from %#H to %#H", src, dst);
-
- /* send data */
- sport = src->get_port(src);
- family = dst->get_family(dst);
- if (sport == IKEV2_UDP_PORT)
- {
- if (family == AF_INET)
- {
- skt = this->ipv4;
- }
- else
- {
- skt = this->ipv6;
- }
- }
- else if (sport == IKEV2_NATT_PORT)
- {
- if (family == AF_INET)
- {
- skt = this->ipv4_natt;
- }
- else
- {
- skt = this->ipv6_natt;
- }
- /* NAT keepalives without marker */
- if (data.len != 1 || data.ptr[0] != 0xFF)
- {
- /* add non esp marker to packet */
- if (data.len > MAX_PACKET - MARKER_LEN)
- {
- DBG1(DBG_NET, "unable to send packet: it's too big (%d bytes)",
- data.len);
- return FAILED;
- }
- marked = chunk_alloc(data.len + MARKER_LEN);
- memset(marked.ptr, 0, MARKER_LEN);
- memcpy(marked.ptr + MARKER_LEN, data.ptr, data.len);
- /* let the packet do the clean up for us */
- packet->set_data(packet, marked);
- data = marked;
- }
- }
- else
- {
- DBG1(DBG_NET, "unable to locate a send socket for port %d", sport);
- return FAILED;
- }
-
- memset(&msg, 0, sizeof(struct msghdr));
- msg.msg_name = dst->get_sockaddr(dst);;
- msg.msg_namelen = *dst->get_sockaddr_len(dst);
- iov.iov_base = data.ptr;
- iov.iov_len = data.len;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_flags = 0;
-
- if (!src->is_anyaddr(src))
- {
- if (family == AF_INET)
- {
-#if defined(IP_PKTINFO) || defined(IP_SENDSRCADDR)
- struct in_addr *addr;
- struct sockaddr_in *sin;
-#ifdef IP_PKTINFO
- char buf[CMSG_SPACE(sizeof(struct in_pktinfo))];
- struct in_pktinfo *pktinfo;
-#elif defined(IP_SENDSRCADDR)
- char buf[CMSG_SPACE(sizeof(struct in_addr))];
-#endif
- msg.msg_control = buf;
- msg.msg_controllen = sizeof(buf);
- cmsg = CMSG_FIRSTHDR(&msg);
- cmsg->cmsg_level = SOL_IP;
-#ifdef IP_PKTINFO
- cmsg->cmsg_type = IP_PKTINFO;
- cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
- pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsg);
- memset(pktinfo, 0, sizeof(struct in_pktinfo));
- addr = &pktinfo->ipi_spec_dst;
-#elif defined(IP_SENDSRCADDR)
- cmsg->cmsg_type = IP_SENDSRCADDR;
- cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
- addr = (struct in_addr*)CMSG_DATA(cmsg);
-#endif
- sin = (struct sockaddr_in*)src->get_sockaddr(src);
- memcpy(addr, &sin->sin_addr, sizeof(struct in_addr));
-#endif /* IP_PKTINFO || IP_SENDSRCADDR */
- }
-#ifdef HAVE_IN6_PKTINFO
- else
- {
- char buf[CMSG_SPACE(sizeof(struct in6_pktinfo))];
- struct in6_pktinfo *pktinfo;
- struct sockaddr_in6 *sin;
-
- msg.msg_control = buf;
- msg.msg_controllen = sizeof(buf);
- cmsg = CMSG_FIRSTHDR(&msg);
- cmsg->cmsg_level = SOL_IPV6;
- cmsg->cmsg_type = IPV6_PKTINFO;
- cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
- pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsg);
- memset(pktinfo, 0, sizeof(struct in6_pktinfo));
- sin = (struct sockaddr_in6*)src->get_sockaddr(src);
- memcpy(&pktinfo->ipi6_addr, &sin->sin6_addr, sizeof(struct in6_addr));
- }
-#endif /* HAVE_IN6_PKTINFO */
- }
-
- bytes_sent = sendmsg(skt, &msg, 0);
-
- if (bytes_sent != data.len)
- {
- DBG1(DBG_NET, "error writing to socket: %s", strerror(errno));
- return FAILED;
- }
- return SUCCESS;
-}
-
-/**
- * open a socket to send and receive packets
- */
-static int open_socket(private_socket_t *this, int family, u_int16_t port)
-{
- int on = TRUE;
- struct sockaddr_storage addr;
- socklen_t addrlen;
- u_int sol, pktinfo = 0;
- int skt;
-
- memset(&addr, 0, sizeof(addr));
- /* precalculate constants depending on address family */
- switch (family)
- {
- case AF_INET:
- {
- struct sockaddr_in *sin = (struct sockaddr_in *)&addr;
- sin->sin_family = AF_INET;
- sin->sin_addr.s_addr = INADDR_ANY;
- sin->sin_port = htons(port);
- addrlen = sizeof(struct sockaddr_in);
- sol = SOL_IP;
-#ifdef IP_PKTINFO
- pktinfo = IP_PKTINFO;
-#elif defined(IP_RECVDSTADDR)
- pktinfo = IP_RECVDSTADDR;
-#endif
- break;
- }
- case AF_INET6:
- {
- struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&addr;
- sin6->sin6_family = AF_INET6;
- memcpy(&sin6->sin6_addr, &in6addr_any, sizeof(in6addr_any));
- sin6->sin6_port = htons(port);
- addrlen = sizeof(struct sockaddr_in6);
- sol = SOL_IPV6;
- pktinfo = IPV6_RECVPKTINFO;
- break;
- }
- default:
- return 0;
- }
-
- skt = socket(family, SOCK_DGRAM, IPPROTO_UDP);
- if (skt < 0)
- {
- DBG1(DBG_NET, "could not open socket: %s", strerror(errno));
- return 0;
- }
- if (setsockopt(skt, SOL_SOCKET, SO_REUSEADDR, (void*)&on, sizeof(on)) < 0)
- {
- DBG1(DBG_NET, "unable to set SO_REUSEADDR on socket: %s", strerror(errno));
- close(skt);
- return 0;
- }
-
- /* bind the socket */
- if (bind(skt, (struct sockaddr *)&addr, addrlen) < 0)
- {
- DBG1(DBG_NET, "unable to bind socket: %s", strerror(errno));
- close(skt);
- return 0;
- }
-
- /* get additional packet info on receive */
- if (pktinfo > 0)
- {
- if (setsockopt(skt, sol, pktinfo, &on, sizeof(on)) < 0)
- {
- DBG1(DBG_NET, "unable to set IP_PKTINFO on socket: %s", strerror(errno));
- close(skt);
- return 0;
- }
- }
-
-#ifndef __APPLE__
- {
- /* enable UDP decapsulation globally, only for one socket needed */
- int type = UDP_ENCAP_ESPINUDP;
- if (family == AF_INET && port == IKEV2_NATT_PORT &&
- setsockopt(skt, SOL_UDP, UDP_ENCAP, &type, sizeof(type)) < 0)
- {
- DBG1(DBG_NET, "unable to set UDP_ENCAP: %s", strerror(errno));
- }
- }
-#endif
- 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, 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)
-{
- if (this->ipv4)
- {
- close(this->ipv4);
- }
- if (this->ipv4_natt)
- {
- close(this->ipv4_natt);
- }
- if (this->ipv6)
- {
- close(this->ipv6);
- }
- if (this->ipv6_natt)
- {
- close(this->ipv6_natt);
- }
- free(this);
-}
-
-/*
- * See header for description
- */
-socket_t *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;
-
-#ifdef __APPLE__
- {
- int natt_port = IKEV2_NATT_PORT;
- if (sysctlbyname("net.inet.ipsec.esp_port", NULL, NULL, &natt_port,
- sizeof(natt_port)) != 0)
- {
- DBG1(DBG_NET, "could not set net.inet.ipsec.esp_port to %d: %s",
- natt_port, strerror(errno));
- }
- }
-#endif
-
- this->ipv4 = open_socket(this, AF_INET, IKEV2_UDP_PORT);
- if (this->ipv4 == 0)
- {
- DBG1(DBG_NET, "could not open IPv4 socket, IPv4 disabled");
- }
- else
- {
- this->ipv4_natt = open_socket(this, AF_INET, IKEV2_NATT_PORT);
- if (this->ipv4_natt == 0)
- {
- DBG1(DBG_NET, "could not open IPv4 NAT-T socket");
- }
- }
-
- this->ipv6 = open_socket(this, AF_INET6, IKEV2_UDP_PORT);
- if (this->ipv6 == 0)
- {
- DBG1(DBG_NET, "could not open IPv6 socket, IPv6 disabled");
- }
- else
- {
- this->ipv6_natt = open_socket(this, AF_INET6, IKEV2_NATT_PORT);
- if (this->ipv6_natt == 0)
- {
- DBG1(DBG_NET, "could not open IPv6 NAT-T socket");
- }
- }
-
- if (!this->ipv4 && !this->ipv6)
- {
- DBG1(DBG_NET, "could not create any sockets");
- destroy(this);
- charon->kill(charon, "socket initialization failed");
- }
- return (socket_t*)this;
-}
-
diff --git a/src/charon/network/socket.h b/src/charon/network/socket.h
deleted file mode 100644
index 83bb9d4c9..000000000
--- a/src/charon/network/socket.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
- * Copyright (C) 2005-2008 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * 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 socket
- * @{ @ingroup network
- */
-
-#ifndef SOCKET_H_
-#define SOCKET_H_
-
-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.
- */
-struct socket_t {
-
- /**
- * Receive a packet.
- *
- * Reads a packet from the socket and sets source/dest
- * appropriately.
- *
- * @param packet pinter gets address from allocated packet_t
- * @return
- * - SUCCESS when packet successfully received
- * - FAILED when unable to receive
- */
- status_t (*receive) (socket_t *this, packet_t **packet);
-
- /**
- * Send a packet.
- *
- * Sends a packet to the net using source and destination addresses of
- * the packet.
- *
- * @param packet packet_t to send
- * @return
- * - SUCCESS when packet successfully sent
- * - FAILED when unable to send
- */
- 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);
-};
-
-/**
- * Create a socket_t, which binds multiple sockets.
- *
- * @return socket_t object
- */
-socket_t *socket_create();
-
-#endif /** SOCKET_H_ @}*/