encoding/payloads/vendor_id_payload.h encoding/payloads/proposal_substructure.c encoding/payloads/payload.c \
encoding/parser.h encoding/message.c encoding/generator.c encoding/message.h encoding/generator.h \
encoding/parser.c daemon.c daemon.h network/packet.c \
-network/interfaces.c network/interfaces.h network/socket.c network/packet.h network/socket.h queues/jobs/job.h queues/jobs/job.c \
+network/socket.c network/packet.h network/socket.h queues/jobs/job.h queues/jobs/job.c \
queues/jobs/delete_established_ike_sa_job.c queues/jobs/retransmit_request_job.h queues/jobs/initiate_job.h \
queues/jobs/incoming_packet_job.c queues/jobs/delete_half_open_ike_sa_job.c \
queues/jobs/delete_established_ike_sa_job.h queues/jobs/delete_half_open_ike_sa_job.h \
this->public.configuration = configuration_create();
this->public.socket = socket_create(IKEV2_UDP_PORT, IKEV2_NATT_PORT);
- this->public.interfaces = interfaces_create(IKEV2_UDP_PORT);
this->public.ike_sa_manager = ike_sa_manager_create();
this->public.job_queue = job_queue_create();
this->public.event_queue = event_queue_create();
/* destruction is a non trivial task, we need to follow
* a strict order to prevent threading issues!
* Kill active threads first, except the sender, as
- * the killed IKE_SA want to send delete messages.
+ * the killed IKE_SA want to send delete messages.
*/
- if (this->public.receiver != NULL)
- { /* we don't want to receive anything... */
- this->public.receiver->destroy(this->public.receiver);
- }
- if (this->public.stroke != NULL)
- { /* ignore all incoming user requests */
- this->public.stroke->destroy(this->public.stroke);
- }
- if (this->public.scheduler != NULL)
- { /* stop scheduing jobs */
- this->public.scheduler->destroy(this->public.scheduler);
- }
- if (this->public.thread_pool != NULL)
- { /* stop processing jobs */
- this->public.thread_pool->destroy(this->public.thread_pool);
- }
- if (this->public.ike_sa_manager != NULL)
- { /* shut down manager with all IKE SAs */
- this->public.ike_sa_manager->destroy(this->public.ike_sa_manager);
- }
- if (this->public.kernel_interface != NULL)
- { /* all child SAs should be down now, so kill kernel interface */
- this->public.kernel_interface->destroy(this->public.kernel_interface);
- }
+ /* we don't want to receive anything anymore... */
+ DESTROY_IF(this->public.receiver);
+ /* ignore all incoming user requests */
+ DESTROY_IF(this->public.stroke);
+ /* stop scheduing jobs */
+ DESTROY_IF(this->public.scheduler);
+ /* stop processing jobs */
+ DESTROY_IF(this->public.thread_pool);
+ /* shut down manager with all IKE SAs */
+ DESTROY_IF(this->public.ike_sa_manager);
+ /* all child SAs should be down now, so kill kernel interface */
+ DESTROY_IF(this->public.kernel_interface);
/* destroy other infrastructure */
- if (this->public.job_queue != NULL)
- {
- this->public.job_queue->destroy(this->public.job_queue);
- }
- if (this->public.event_queue != NULL)
- {
- this->public.event_queue->destroy(this->public.event_queue);
- }
- if (this->public.interfaces != NULL)
- {
- this->public.interfaces->destroy(this->public.interfaces);
- }
- if (this->public.configuration != NULL)
- {
- this->public.configuration->destroy(this->public.configuration);
- }
- if (this->public.credentials != NULL)
- {
- this->public.credentials->destroy(this->public.credentials);
- }
- if (this->public.connections != NULL)
- {
- this->public.connections->destroy(this->public.connections);
- }
- if (this->public.policies != NULL)
- {
- this->public.policies->destroy(this->public.policies);
- }
+ DESTROY_IF(this->public.job_queue);
+ DESTROY_IF(this->public.event_queue);
+ DESTROY_IF(this->public.configuration);
+ DESTROY_IF(this->public.credentials);
+ DESTROY_IF(this->public.connections);
+ DESTROY_IF(this->public.policies);
/* we hope the sender could send the outstanding deletes, but
* we shut down here at any cost */
- if (this->public.sender != NULL)
- {
- this->public.sender->destroy(this->public.sender);
- }
- if (this->public.send_queue != NULL)
- {
- this->public.send_queue->destroy(this->public.send_queue);
- }
- if (this->public.socket != NULL)
- {
- this->public.socket->destroy(this->public.socket);
- }
+ DESTROY_IF(this->public.sender);
+ DESTROY_IF(this->public.send_queue);
+ DESTROY_IF(this->public.socket);
free(this);
}
/* NULL members for clean destruction */
this->public.socket = NULL;
- this->public.interfaces = NULL;
this->public.ike_sa_manager = NULL;
this->public.job_queue = NULL;
this->public.event_queue = NULL;
private_daemon_t *private_charon;
FILE *pid_file;
struct stat stb;
+ linked_list_t *list;
+ host_t *host;
/* handle arguments */
for (;;)
fclose(pid_file);
}
+ /* log socket info */
+ list = charon->socket->create_local_address_list(charon->socket);
+ private_charon->logger->log(private_charon->logger, CONTROL,
+ "listening on %d addresses:",
+ list->get_count(list));
+ while (list->remove_first(list, (void**)&host) == SUCCESS)
+ {
+ private_charon->logger->log(private_charon->logger, CONTROL,
+ " %s", host->get_string(host));
+ host->destroy(host);
+
+ }
+ list->destroy(list);
+
/* run daemon */
private_charon->run(private_charon);
#include <threads/thread_pool.h>
#include <threads/stroke_interface.h>
#include <network/socket.h>
-#include <network/interfaces.h>
#include <sa/ike_sa_manager.h>
#include <queues/send_queue.h>
#include <queues/job_queue.h>
socket_t *socket;
/**
- * A interfaces_t instance.
- */
- interfaces_t *interfaces;
-
- /**
* A send_queue_t instance.
*/
send_queue_t *send_queue;
--- /dev/null
+#!/bin/bash
+make install || exit
+ipsec start --nofork &
+sleep 1
+gdb /usr/local/libexec/ipsec/charon `cat /var/run/charon.pid`
+ipsec stop
*((u_int64_t*)this->spi.ptr) = proposal->get_spi(proposal);
}
break;
+ default:
+ break;
}
this->proposal_number = 0;
this->protocol_id = proposal->get_protocol(proposal);
+++ /dev/null
-/**
- * @file interfaces.c
- *
- * @brief Implementation of interfaces_t.
- *
- */
-
-/*
- * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
- * 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 <net/if.h>
-#include <ifaddrs.h>
-#include <string.h>
-
-#include "interfaces.h"
-
-typedef struct private_interfaces_t private_interfaces_t;
-
-/**
- * Private data of an interfaces_t object.
- */
-struct private_interfaces_t {
-
- /**
- * Public part of a interfaces_t object.
- */
- interfaces_t public;
-
- /**
- * port that gets added to the host_t obbjects
- */
- u_int16_t port;
-
- /**
- * list of addresses
- */
- linked_list_t *addresses;
-};
-
-/**
- * Implements interfaces_t.create_address_iterator
- */
-static iterator_t* create_address_iterator(private_interfaces_t *this)
-{
- return this->addresses->create_iterator(this->addresses, TRUE);
-}
-
-/**
- * Implements interfaces_t.is_local_address
- */
-static bool is_local_address(private_interfaces_t *this, host_t *host)
-{
- iterator_t *iterator;
- host_t *lhost;
-
- if (host->is_anyaddr(host))
- {
- return FALSE;
- }
-
- iterator = this->addresses->create_iterator(this->addresses, TRUE);
- while (iterator->iterate(iterator, (void**)&lhost))
- {
- if (host->get_family(host) == lhost->get_family(lhost) &&
- streq(host->get_string(host), lhost->get_string(lhost)))
- {
- iterator->destroy(iterator);
- return TRUE;
- }
- }
-
- iterator->destroy(iterator);
- return FALSE;
-}
-
-/**
- * Implements interfaces_t.destroy.
- */
-static void destroy(private_interfaces_t *this)
-{
- host_t *host;
- while (this->addresses->remove_last(this->addresses, (void**)&host) == SUCCESS)
- {
- host->destroy(host);
- }
- this->addresses->destroy(this->addresses);
- free(this);
-}
-
-static status_t initialize(private_interfaces_t *this)
-{
- struct ifaddrs *list;
- struct ifaddrs *cur;
- host_t *host;
-
- if (getifaddrs(&list) < 0)
- {
- return FAILED;
- }
-
- for (cur = list; cur != NULL; cur = cur->ifa_next)
- {
- if (!(cur->ifa_flags & IFF_UP))
- continue;
-
- if (cur->ifa_addr == NULL || cur->ifa_addr->sa_family != AF_INET)
- continue;
-
- host = host_create_from_sockaddr(cur->ifa_addr);
- if (host) {
- host->set_port(host, this->port);
- this->addresses->insert_last(this->addresses, (void*) host);
- }
- }
-
- freeifaddrs(list);
- return SUCCESS;
-}
-
-/*
- * Documented in header
- */
-interfaces_t *interfaces_create(u_int16_t port)
-{
- private_interfaces_t *this = malloc_thing(private_interfaces_t);
-
- this->port = port;
-
- this->public.create_address_iterator = (iterator_t* (*) (interfaces_t*)) create_address_iterator;
- this->public.is_local_address = (bool (*) (interfaces_t*, host_t*)) is_local_address;
- this->public.destroy = (void (*) (interfaces_t*)) destroy;
-
- this->addresses = linked_list_create();
-
- if (initialize(this) != SUCCESS)
- {
- destroy(this);
- return NULL;
- }
-
- return &this->public;
-}
+++ /dev/null
-/**
- * @file interfaces.h
- *
- * @brief Interface of interfaces_t.
- *
- */
-
-/*
- * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
- * 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.
- */
-
-#ifndef INTERFACES_H_
-#define INTERFACES_H_
-
-#include <utils/linked_list.h>
-#include <utils/host.h>
-
-typedef struct interfaces_t interfaces_t;
-
-/**
- * @brief Provides methods to enumerate local interfaces
- *
- * @b Constructors:
- * - interfaces_create()
- *
- * @todo Handle changes in interface list.
- *
- * @ingroup network
- */
-struct interfaces_t {
-
- /**
- * @brief Get an iterator over addresses of local interfaces
- *
- * @param this calling object
- * @return iterator over host_t objects
- */
- iterator_t* (*create_address_iterator) (interfaces_t *this);
-
- /**
- * @brief Check if address is associated with a local interface
- *
- * @param this calling object
- * @param host address to set as destination
- * @return TRUE if address is associated with a local interface, FALSE otherwise
- */
- bool (*is_local_address) (interfaces_t *this, host_t *host);
-
- /**
- * @brief Destroy the object, freeing contained data.
- *
- * @param this object to destroy
- */
- void (*destroy) (interfaces_t *ifaces);
-};
-
-/**
- * @brief Create an object of type interfaces_t
- *
- * @param port the port that gets added to the addresses
- *
- * @return interfaces_t object
- *
- * @ingroup network
- */
-interfaces_t *interfaces_create(u_int16_t port);
-
-
-#endif /* INTERFACES_H_ */
#include <netinet/udp.h>
#include <linux/ipsec.h>
#include <linux/filter.h>
+#include <net/if.h>
+#include <ifaddrs.h>
#include "socket.h"
* logger for this socket
*/
logger_t *logger;
-
- /**
- * Setup a send socket
- *
- * @param this calling object
- * @param port the port
- * @param send_fd returns the file descriptor of this new socket
- */
- status_t (*setup_send_socket) (private_socket_t *this, u_int16_t port, int *send_fd);
-
- /**
- * Initialize
- *
- * @param this calling object
- */
- status_t (*initialize) (private_socket_t *this);
};
/**
}
/**
+ * implements socket_t.is_local_address
+ */
+static bool is_local_address(private_socket_t *this, host_t *host)
+{
+ struct ifaddrs *list;
+ struct ifaddrs *cur;
+ bool found = FALSE;
+
+ if (getifaddrs(&list) < 0)
+ {
+ return FALSE;
+ }
+
+ for (cur = list; cur != NULL; cur = cur->ifa_next)
+ {
+ if (!(cur->ifa_flags & IFF_UP))
+ {
+ /* ignore interface which are down */
+ continue;
+ }
+
+ if (cur->ifa_addr == NULL ||
+ cur->ifa_addr->sa_family != host->get_family(host))
+ {
+ /* no match in family */
+ continue;
+ }
+
+ switch (cur->ifa_addr->sa_family)
+ {
+ case AF_INET:
+ {
+ struct sockaddr_in *listed, *requested;
+ listed = (struct sockaddr_in*)cur->ifa_addr;
+ requested = (struct sockaddr_in*)host->get_sockaddr(host);
+ if (listed->sin_addr.s_addr == requested->sin_addr.s_addr)
+ {
+ found = TRUE;
+ }
+ break;
+ }
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *listed, *requested;
+ listed = (struct sockaddr_in6*)cur->ifa_addr;
+ requested = (struct sockaddr_in6*)host->get_sockaddr(host);
+ if (memcmp(&listed->sin6_addr, &requested->sin6_addr,
+ sizeof(listed->sin6_addr)) == 0)
+ {
+ found = TRUE;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (found)
+ {
+ break;
+ }
+ }
+ freeifaddrs(list);
+ return found;
+}
+
+
+/**
+ * implements socket_t.create_local_address_list
+ */
+static linked_list_t* create_local_address_list(private_socket_t *this)
+{
+ struct ifaddrs *list;
+ struct ifaddrs *cur;
+ host_t *host;
+ linked_list_t *result = linked_list_create();
+
+ if (getifaddrs(&list) < 0)
+ {
+ return result;
+ }
+
+ for (cur = list; cur != NULL; cur = cur->ifa_next)
+ {
+ if (!(cur->ifa_flags & IFF_UP))
+ {
+ /* ignore interface which are down */
+ continue;
+ }
+
+ host = host_create_from_sockaddr(cur->ifa_addr);
+ if (host)
+ {
+ /* address supported, add to list */
+ result->insert_last(result, host);
+ }
+ }
+ freeifaddrs(list);
+ return result;
+}
+
+/**
* setup a send socket on a specified port
*/
static status_t setup_send_socket(private_socket_t *this, u_int16_t port, int *send_fd)
}
/* setup the send sockets */
- if (this->setup_send_socket(this, this->port, &this->send_fd) != SUCCESS)
+ if (setup_send_socket(this, this->port, &this->send_fd) != SUCCESS)
{
this->logger->log(this->logger, ERROR, "unable to setup send socket on port %d!", this->port);
return FAILED;
}
- if (this->setup_send_socket(this, this->natt_port, &this->natt_fd) != SUCCESS)
+ if (setup_send_socket(this, this->natt_port, &this->natt_fd) != SUCCESS)
{
this->logger->log(this->logger, ERROR, "unable to setup send socket on port %d!", this->natt_port);
return FAILED;
{
private_socket_t *this = malloc_thing(private_socket_t);
- /* private functions */
- this->initialize = (status_t(*)(private_socket_t*))initialize;
- this->setup_send_socket = (status_t(*)(private_socket_t*,u_int16_t, int*))setup_send_socket;
-
/* public functions */
this->public.send = (status_t(*)(socket_t*, packet_t*))sender;
this->public.receive = (status_t(*)(socket_t*, packet_t**))receiver;
+ this->public.is_local_address = (bool(*)(socket_t*, host_t*))is_local_address;
+ this->public.create_local_address_list = (linked_list_t*(*)(socket_t*))create_local_address_list;
this->public.destroy = (void(*)(socket_t*)) destroy;
this->logger = logger_manager->get_logger(logger_manager, SOCKET);
this->port = port;
this->natt_port = natt_port;
- if (this->initialize(this) != SUCCESS)
+ if (initialize(this) != SUCCESS)
{
free(this);
charon->kill(charon, "could not init socket!");
#include <types.h>
#include <network/packet.h>
+#include <utils/host.h>
+#include <utils/linked_list.h>
/**
*
* @todo add IPv6 support
*
- * @todo We currently use multiple sockets for historic reasons. With the
- * new RAW socket mechanism, we could use just one socket and filter
- * addresses in userspace (or via linux socket filter). This would allow
- * realtime interface/address management in a easy way...
- *
* @ingroup network
*/
struct socket_t {
+
/**
* @brief Receive a packet.
*
* Reads a packet from the socket and sets source/dest
* appropriately.
*
- * @param sock socket_t object to work on
+ * @param this socket_t object to work on
* @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 *sock, packet_t **packet);
+ status_t (*receive) (socket_t *this, packet_t **packet);
/**
* @brief Send a packet.
* Packet is sent using default routing mechanisms, thus the
* source address in packet is ignored.
*
- * @param sock socket_t object to work on
+ * @param this socket_t object to work on
* @param packet[out] packet_t to send
* @return
* - SUCCESS when packet successfully sent
* - FAILED when unable to send
*/
- status_t (*send) (socket_t *sock, packet_t *packet);
+ status_t (*send) (socket_t *this, packet_t *packet);
+
+ /**
+ * @brief Check if an address is an address of this host.
+ *
+ * @param this socket_t object to work on
+ * @param host address to check
+ * @return TRUE if local address, FALSE otherwise
+ */
+ bool (*is_local_address) (socket_t *this, host_t *host);
+
+ /**
+ * @brief Create a list of hosts with all local addresses.
+ *
+ * @param this socket_t object to work on
+ * @return list with host_t objects
+ */
+ linked_list_t *(*create_local_address_list) (socket_t *this);
/**
* @brief Destroy sockets.
*
* close sockets and destroy socket_t object
*
- * @param sock socket_t to destroy
+ * @param this socket_t to destroy
*/
- void (*destroy) (socket_t *sock);
+ void (*destroy) (socket_t *this);
};
/**
#include "child_sa.h"
+#include <string.h>
+
#include <daemon.h>
{ /* build NAT_DETECTION notifys */
notify_payload_t *notify;
- iterator_t *iterator;
+ linked_list_t *list;
host_t *host;
/* N(NAT_DETECTION_SOURCE_IP)+ */
- iterator = charon->interfaces->create_address_iterator(charon->interfaces);
- while (iterator->iterate(iterator, (void**)&host))
+ list = charon->socket->create_local_address_list(charon->socket);
+ while (list->remove_first(list, (void**)&host) == SUCCESS)
{
notify = build_natd_payload(this, NAT_DETECTION_SOURCE_IP, host);
+ host->destroy(host);
request->add_payload(request, (payload_t*)notify);
}
- iterator->destroy(iterator);
+ list->destroy(list);
/* N(NAT_DETECTION_DESTINATION_IP) */
notify = build_natd_payload(this, NAT_DETECTION_DESTINATION_IP, other);
return;
}
- if (charon->interfaces->is_local_address(charon->interfaces, other_host))
+ if (charon->socket->is_local_address(charon->socket, other_host))
{
stroke_end_t tmp_end;
host_t *tmp_host;
msg->add_conn.me = msg->add_conn.other;
msg->add_conn.other = tmp_end;
}
- else if (!charon->interfaces->is_local_address(charon->interfaces, my_host))
+ else if (!charon->socket->is_local_address(charon->socket, my_host))
{
this->stroke_logger->log(this->stroke_logger, ERROR, "left nor right host is our side, aborting");
goto destroy_hosts;
*/
static void stroke_status(private_stroke_t *this, stroke_msg_t *msg)
{
+ linked_list_t *list;
+ host_t *host;
+
+ list = charon->socket->create_local_address_list(charon->socket);
+ this->logger->log(this->logger, CONTROL|LEVEL1,
+ "listening on %d addresses:",
+ list->get_count(list));
+ while (list->remove_first(list, (void**)&host) == SUCCESS)
+ {
+ this->logger->log(this->logger, CONTROL|LEVEL1,
+ " %s", host->get_string(host));
+ host->destroy(host);
+
+ }
+ list->destroy(list);
+
if (msg->status.name)
{
pop_string(msg, &(msg->status.name));