summaryrefslogtreecommitdiff
path: root/keyexchange/isakmpd-20041012/transport.c
diff options
context:
space:
mode:
authorOthmar Gsenger <otti@anytun.org>2008-05-25 09:50:42 +0000
committerOthmar Gsenger <otti@anytun.org>2008-05-25 09:50:42 +0000
commit71da41451212389bea25d67bc5da696b6d194bff (patch)
treea3b20decbd8bc9e47640af5fa4b39f731477955a /keyexchange/isakmpd-20041012/transport.c
parentimproved presentation again (diff)
moved keyexchange to http://anytun.org/svn/keyexchange
Diffstat (limited to 'keyexchange/isakmpd-20041012/transport.c')
-rw-r--r--keyexchange/isakmpd-20041012/transport.c431
1 files changed, 0 insertions, 431 deletions
diff --git a/keyexchange/isakmpd-20041012/transport.c b/keyexchange/isakmpd-20041012/transport.c
deleted file mode 100644
index 023e819..0000000
--- a/keyexchange/isakmpd-20041012/transport.c
+++ /dev/null
@@ -1,431 +0,0 @@
-/* $OpenBSD: transport.c,v 1.30 2004/08/08 19:11:06 deraadt Exp $ */
-/* $EOM: transport.c,v 1.43 2000/10/10 12:36:39 provos Exp $ */
-
-/*
- * Copyright (c) 1998, 1999 Niklas Hallqvist. All rights reserved.
- * Copyright (c) 2001, 2004 Håkan Olsson. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * This code was written under funding by Ericsson Radio Systems.
- */
-
-#include <sys/param.h>
-#include <sys/queue.h>
-#include <string.h>
-
-#include "sysdep.h"
-
-#include "conf.h"
-#include "exchange.h"
-#include "log.h"
-#include "message.h"
-#include "sa.h"
-#include "timer.h"
-#include "transport.h"
-#include "virtual.h"
-
-/* If no retransmit limit is given, use this as a default. */
-#define RETRANSMIT_DEFAULT 10
-
-LIST_HEAD(transport_list, transport) transport_list;
-LIST_HEAD(transport_method_list, transport_vtbl) transport_method_list;
-
-/* Call the reinit function of the various transports. */
-void
-transport_reinit(void)
-{
- struct transport_vtbl *method;
-
- for (method = LIST_FIRST(&transport_method_list); method;
- method = LIST_NEXT(method, link))
- if (method->reinit)
- method->reinit();
-}
-
-/* Initialize the transport maintenance module. */
-void
-transport_init(void)
-{
- LIST_INIT(&transport_list);
- LIST_INIT(&transport_method_list);
-}
-
-/* Register another transport T. */
-void
-transport_setup(struct transport *t, int toplevel)
-{
- if (toplevel) {
- /* Only the toplevel (virtual) transport has sendqueues. */
- LOG_DBG((LOG_TRANSPORT, 70,
- "transport_setup: virtual transport %p", t));
- TAILQ_INIT(&t->sendq);
- TAILQ_INIT(&t->prio_sendq);
- t->refcnt = 0;
- } else {
- /* udp and udp_encap trp goes into the transport list. */
- LOG_DBG((LOG_TRANSPORT, 70,
- "transport_setup: added %p to transport list", t));
- LIST_INSERT_HEAD(&transport_list, t, link);
- t->refcnt = 1;
- }
- t->flags = 0;
-}
-
-/* Add a referer to transport T. */
-void
-transport_reference(struct transport *t)
-{
- t->refcnt++;
- LOG_DBG((LOG_TRANSPORT, 95,
- "transport_reference: transport %p now has %d references", t,
- t->refcnt));
-}
-
-/*
- * Remove a referer from transport T, removing all of T when no referers left.
- */
-void
-transport_release(struct transport *t)
-{
- LOG_DBG((LOG_TRANSPORT, 95,
- "transport_release: transport %p had %d references", t,
- t->refcnt));
- if (--t->refcnt)
- return;
-
- LOG_DBG((LOG_TRANSPORT, 70, "transport_release: freeing %p", t));
- t->vtbl->remove(t);
-}
-
-void
-transport_report(void)
-{
- struct virtual_transport *v;
- struct transport *t;
- struct message *msg;
-
- for (t = LIST_FIRST(&transport_list); t; t = LIST_NEXT(t, link)) {
- LOG_DBG((LOG_REPORT, 0,
- "transport_report: transport %p flags %x refcnt %d", t,
- t->flags, t->refcnt));
-
- /* XXX Report sth on the virtual transport? */
- t->vtbl->report(t);
-
- /*
- * This is the reason message_dump_raw lives outside
- * message.c.
- */
- v = (struct virtual_transport *)t->virtual;
- if ((v->encap_is_active && v->encap == t) ||
- (!v->encap_is_active && v->main == t)) {
- for (msg = TAILQ_FIRST(&t->virtual->prio_sendq); msg;
- msg = TAILQ_NEXT(msg, link))
- message_dump_raw("udp_report(prio)", msg,
- LOG_REPORT);
-
- for (msg = TAILQ_FIRST(&t->virtual->sendq); msg;
- msg = TAILQ_NEXT(msg, link))
- message_dump_raw("udp_report", msg,
- LOG_REPORT);
- }
- }
-}
-
-int
-transport_prio_sendqs_empty(void)
-{
- struct transport *t;
-
- for (t = LIST_FIRST(&transport_list); t; t = LIST_NEXT(t, link))
- if (TAILQ_FIRST(&t->virtual->prio_sendq))
- return 0;
- return 1;
-}
-
-/* Register another transport method T. */
-void
-transport_method_add(struct transport_vtbl *t)
-{
- LIST_INSERT_HEAD(&transport_method_list, t, link);
-}
-
-/* Apply a function FUNC on all registered (non-toplevel) transports. */
-void
-transport_map(void (*func) (struct transport *))
-{
- struct transport *t;
-
- for (t = LIST_FIRST(&transport_list); t; t = LIST_NEXT(t, link))
- (*func) (t);
-}
-
-/*
- * Build up a file descriptor set FDS with all transport descriptors we want
- * to read from. Return the number of file descriptors select(2) needs to
- * check in order to cover the ones we setup in here.
- */
-int
-transport_fd_set(fd_set * fds)
-{
- struct transport *t;
- int n;
- int max = -1;
-
- for (t = LIST_FIRST(&transport_list); t; t = LIST_NEXT(t, link))
- if (t->virtual->flags & TRANSPORT_LISTEN) {
- n = t->vtbl->fd_set(t, fds, 1);
- if (n > max)
- max = n;
-
- LOG_DBG((LOG_TRANSPORT, 95, "transport_fd_set: "
- "transport %p (virtual %p) fd %d", t,
- t->virtual, n));
- }
- return max + 1;
-}
-
-/*
- * Build up a file descriptor set FDS with all the descriptors belonging to
- * transport where messages are queued for transmittal. Return the number
- * of file descriptors select(2) needs to check in order to cover the ones
- * we setup in here.
- */
-int
-transport_pending_wfd_set(fd_set * fds)
-{
- struct transport *t;
- int n;
- int max = -1;
-
- for (t = LIST_FIRST(&transport_list); t; t = LIST_NEXT(t, link)) {
- if (TAILQ_FIRST(&t->virtual->sendq) ||
- TAILQ_FIRST(&t->virtual->prio_sendq)) {
- n = t->vtbl->fd_set(t, fds, 1);
- LOG_DBG((LOG_TRANSPORT, 95,
- "transport_pending_wfd_set: "
- "transport %p (virtual %p) fd %d pending", t,
- t->virtual, n));
- if (n > max)
- max = n;
- }
- }
- return max + 1;
-}
-
-/*
- * For each transport with a file descriptor in FDS, try to get an
- * incoming message and start processing it.
- */
-void
-transport_handle_messages(fd_set *fds)
-{
- struct transport *t;
-
- for (t = LIST_FIRST(&transport_list); t; t = LIST_NEXT(t, link)) {
- if ((t->flags & TRANSPORT_LISTEN) &&
- (*t->vtbl->fd_isset)(t, fds)) {
- (*t->virtual->vtbl->handle_message)(t);
- (*t->vtbl->fd_set)(t, fds, 0);
- }
- }
-}
-
-/*
- * Send the first queued message on the transports found whose file
- * descriptor is in FDS and has messages queued. Remove the fd bit from
- * FDS as soon as one message has been sent on it so other transports
- * sharing the socket won't get service without an intervening select
- * call. Perhaps a fairness strategy should be implemented between
- * such transports. Now early transports in the list will potentially
- * be favoured to later ones sharing the file descriptor.
- */
-void
-transport_send_messages(fd_set * fds)
-{
- struct transport *t, *next;
- struct message *msg;
- struct exchange *exchange;
- struct timeval expiration;
- int expiry, ok_to_drop_message;
-
- /*
- * Reference all transports first so noone will disappear while in
- * use.
- */
- for (t = LIST_FIRST(&transport_list); t; t = LIST_NEXT(t, link))
- transport_reference(t->virtual);
-
- for (t = LIST_FIRST(&transport_list); t; t = LIST_NEXT(t, link)) {
- if ((TAILQ_FIRST(&t->virtual->sendq) ||
- TAILQ_FIRST(&t->virtual->prio_sendq)) &&
- t->vtbl->fd_isset(t, fds)) {
- /* Remove fd bit. */
- t->vtbl->fd_set(t, fds, 0);
-
- /* Prefer a message from the prioritized sendq. */
- if (TAILQ_FIRST(&t->virtual->prio_sendq)) {
- msg = TAILQ_FIRST(&t->virtual->prio_sendq);
- TAILQ_REMOVE(&t->virtual->prio_sendq, msg,
- link);
- } else {
- msg = TAILQ_FIRST(&t->virtual->sendq);
- TAILQ_REMOVE(&t->virtual->sendq, msg, link);
- }
-
- msg->flags &= ~MSG_IN_TRANSIT;
- exchange = msg->exchange;
- exchange->in_transit = 0;
-
- /*
- * We disregard the potential error message here,
- * hoping that the retransmit will go better.
- * XXX Consider a retry/fatal error discriminator.
- */
- t->virtual->vtbl->send_message(msg, 0);
- msg->xmits++;
-
- /*
- * This piece of code has been proven to be quite
- * delicate. Think twice for before altering.
- * Here's an outline:
- *
- * If this message is not the one which finishes an
- * exchange, check if we have reached the number of
- * retransmit before queuing it up for another.
- *
- * If it is a finishing message we still may have to
- * keep it around for an on-demand retransmit when
- * seeing a duplicate of our peer's previous message.
- *
- */
- if ((msg->flags & MSG_LAST) == 0) {
- if (msg->xmits > conf_get_num("General",
- "retransmits", RETRANSMIT_DEFAULT)) {
- log_print("transport_send_messages: "
- "giving up on message %p, "
- "exchange %s", msg,
- exchange->name ? exchange->name :
- "<unnamed>");
- /* Be more verbose here. */
- if (exchange->phase == 1) {
- log_print(
- "transport_send_messages: "
- "either this message did "
- "not reach the other "
- "peer");
- if (exchange->initiator)
- log_print("transport_send_messages: "
- "or the response"
- "message did not "
- "reach us back");
- else
- log_print("transport_send_messages: "
- "or this is an "
- "attempted IKE "
- "scan");
- }
- exchange->last_sent = 0;
-#ifdef notyet
- exchange_free(exchange);
- exchange = 0;
-#endif
- } else {
- gettimeofday(&expiration, 0);
-
- /*
- * XXX Calculate from round trip
- * timings and a backoff func.
- */
- expiry = msg->xmits * 2 + 5;
- expiration.tv_sec += expiry;
- LOG_DBG((LOG_TRANSPORT, 30,
- "transport_send_messages: "
- "message %p scheduled for "
- "retransmission %d in %d secs",
- msg, msg->xmits, expiry));
- if (msg->retrans)
- timer_remove_event(msg->retrans);
- msg->retrans
- = timer_add_event("message_send_expire",
- (void (*) (void *)) message_send_expire,
- msg, &expiration);
- /*
- * If we cannot retransmit, we
- * cannot...
- */
- exchange->last_sent =
- msg->retrans ? msg : 0;
- }
- } else
- exchange->last_sent =
- exchange->last_received ? msg : 0;
-
- /*
- * If this message is not referred to for later
- * retransmission it will be ok for us to drop it
- * after the post-send function. But as the post-send
- * function may remove the exchange, we need to
- * remember this fact here.
- */
- ok_to_drop_message = exchange->last_sent == 0;
-
- /*
- * If this is not a retransmit call post-send
- * functions that allows parallel work to be done
- * while the network and peer does their share of
- * the job. Note that a post-send function may take
- * away the exchange we belong to, but only if no
- * retransmits are possible.
- */
- if (msg->xmits == 1)
- message_post_send(msg);
-
- if (ok_to_drop_message)
- message_free(msg);
- }
- }
-
- for (t = LIST_FIRST(&transport_list); t; t = next) {
- next = LIST_NEXT(t, link);
- transport_release(t->virtual);
- }
-}
-
-/*
- * Textual search after the transport method denoted by NAME, then create
- * a transport connected to the peer with address ADDR, given in a transport-
- * specific string format.
- */
-struct transport *
-transport_create(char *name, char *addr)
-{
- struct transport_vtbl *method;
-
- for (method = LIST_FIRST(&transport_method_list); method;
- method = LIST_NEXT(method, link))
- if (strcmp(method->name, name) == 0)
- return (*method->create) (addr);
- return 0;
-}