/* demultiplex incoming IKE messages * Copyright (C) 1997 Angelos D. Keromytis. * Copyright (C) 1998-2002 D. Hugh Redelmeier. * * 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 . * * 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 #include #include #include #include #include #include #include /* only used for belt-and-suspenders select call */ #include /* only used for forensic poll call */ #include #include #include #if defined(IP_RECVERR) && defined(MSG_ERRQUEUE) # include /* for __u8, __u32 */ # include # include /* struct iovec */ #endif #include #include "sysdep.h" #include "constants.h" #include "lswlog.h" #include "defs.h" #include "cookie.h" #include "id.h" #include "x509.h" #include "certs.h" #include "connections.h" /* needs id.h */ #include "state.h" #include "packet.h" #include "md5.h" #include "sha1.h" #include "crypto.h" /* requires sha1.h and md5.h */ #include "ike_alg.h" #include "log.h" #include "demux.h" /* needs packet.h */ /* message digest allocation and deallocation */ static struct msg_digest *md_pool = NULL; /* free_md_pool is only used to avoid leak reports */ void free_md_pool(void) { for (;; ) { struct msg_digest *md = md_pool; if (md == NULL) break; passert(md_pool != md->next); md_pool = md->next; pfree(md); } } struct msg_digest *alloc_md(void) { struct msg_digest *md = md_pool; /* convenient initializer: * - all pointers NULL * - .note = NOTHING_WRONG * - .encrypted = FALSE */ static const struct msg_digest blank_md; if (md == NULL) md = alloc_thing(struct msg_digest, "msg_digest"); else md_pool = md->next; *md = blank_md; md->digest_roof = md->digest; /* note: although there may be multiple msg_digests at once * (due to suspended state transitions), there is a single * global reply_buffer. It will need to be saved and restored. */ init_pbs(&reply_stream, reply_buffer, sizeof(reply_buffer), "reply packet"); return md; } void release_md(struct msg_digest *md) { freeanychunk(md->raw_packet); pfreeany(md->packet_pbs.start); /* make sure we are not creating a loop */ passert(md != md_pool); md->packet_pbs.start = NULL; md->next = md_pool; md_pool = md; } void release_any_md(struct msg_digest **mdp) { if (*mdp != NULL) { release_md(*mdp); *mdp = NULL; } }