Merge authors: Diego Biurrun (diego-biurrun) goetz <goetz@goetz> Miika Komu (miika-iki) Stefan Götz (stefan.goetz) ------------------------------------------------------------ revno: 5013 [merge] committer: Andrius Bentkus <andrius.bentkus@xxxxxxxxxxxxxx> branch nick: hipfw-modules timestamp: Mon 2010-11-15 18:08:02 +0100 message: Merged trunk. removed: lib/modularization/ added: firewall/file_buffer.c firewall/file_buffer.h firewall/file_buffer_inline.h firewall/line_parser.c firewall/line_parser.h firewall/line_parser_inline.h firewall/mem_area.h test/check_firewall.c test/firewall/ test/firewall/file_buffer.c test/firewall/line_parser.c test/firewall/port_bindings.c test/fw_port_bindings_performance.c renamed: firewall/cache_port.c => firewall/port_bindings.c firewall/cache_port.h => firewall/port_bindings.h lib/core/lmod.c => lib/core/modularization.c lib/core/lmod.h => lib/core/modularization.h modified: .bzrignore COPYING Makefile.am configure.ac firewall/cache.c firewall/esp_prot_conntrack.c firewall/firewall.c firewall/lsi.c hipd/esp_prot_light_update.h hipd/hiprelay.c hipd/init.c hipd/maintenance.c hipd/pkt_handling.c hipd/registration.c hipd/user.c lib/core/builder.c lib/core/debug.h lib/core/hashchain_store.c lib/core/icomm.h lib/core/options.c lib/core/prefix.c lib/core/state.h lib/tool/pk.c modules/heartbeat/hipd/heartbeat.c modules/update/hipd/update.c packaging/openwrt/package/Makefile tools/hipl_autobuild.sh firewall/port_bindings.c firewall/port_bindings.h lib/core/modularization.c lib/core/modularization.h -- lp:~toxedvirus/hipl/hipfw-modules https://code.launchpad.net/~toxedvirus/hipl/hipfw-modules Your team HIPL core team is subscribed to branch lp:~toxedvirus/hipl/hipfw-modules. To unsubscribe from this branch go to https://code.launchpad.net/~toxedvirus/hipl/hipfw-modules/+edit-subscription
=== modified file '.bzrignore' --- .bzrignore 2010-11-09 14:18:47 +0000 +++ .bzrignore 2010-11-15 17:08:02 +0000 @@ -48,6 +48,7 @@ test/auth_performance test/certteststub test/dh_performance +test/fw_port_bindings_performance test/hc_performance tools/hipconf tools/hipdnskeyparse === modified file 'COPYING' --- COPYING 2010-08-18 13:12:07 +0000 +++ COPYING 2010-11-10 08:25:44 +0000 @@ -19,9 +19,11 @@ and have their own licensing conditions (GPL): * firewall/user_ipsec_esp.c - * tools/hipdnsproxy/DNS * lib/tool +(Note that tools/hipdnsproxy/DNS is from the pydns project and is covered +by the standard Python License) + MIT (Expat) License =================== === modified file 'Makefile.am' --- Makefile.am 2010-11-09 14:18:47 +0000 +++ Makefile.am 2010-11-15 17:08:02 +0000 @@ -1,3 +1,26 @@ +# Copyright (c) 2010 Aalto University and RWTH Aachen University. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. + ACLOCAL_AMFLAGS = -I m4 HIPL_HEADER_LIST = $(wildcard $(addprefix $(srcdir)/,firewall/*.h hipd/*.h lib/*/*.h modules/*/*/*.h)) @@ -33,6 +56,11 @@ endif +### test programs ### +noinst_PROGRAMS = test/fw_port_bindings_performance + + + ### libraries ### lib_LTLIBRARIES = lib/core/libhipcore.la @@ -42,17 +70,23 @@ check_PROGRAMS = if HIP_UNITTESTS -TESTS += check_lib_core -check_PROGRAMS += check_lib_core +TESTS += check_firewall \ + check_lib_core +check_PROGRAMS += check_firewall \ + check_lib_core endif ### source declarations ### -test_auth_performance_SOURCES = test/auth_performance.c -test_certteststub_SOURCES = test/certteststub.c -test_dh_performance_SOURCES = test/dh_performance.c -test_hc_performance_SOURCES = test/hc_performance.c +test_auth_performance_SOURCES = test/auth_performance.c +test_certteststub_SOURCES = test/certteststub.c +test_dh_performance_SOURCES = test/dh_performance.c +test_fw_port_bindings_performance_SOURCES = test/fw_port_bindings_performance.c \ + firewall/file_buffer.c \ + firewall/line_parser.c \ + firewall/port_bindings.c +test_hc_performance_SOURCES = test/hc_performance.c tools_hipconf_SOURCES = tools/hipconf.c tools_pisacert_SOURCES = tools/pisacert.c @@ -97,18 +131,20 @@ endif firewall_hipfw_SOURCES = firewall/cache.c \ - firewall/cache_port.c \ firewall/conntrack.c \ firewall/dlist.c \ firewall/esp_prot_api.c \ firewall/esp_prot_config.c \ firewall/esp_prot_conntrack.c \ firewall/esp_prot_fw_msg.c \ + firewall/file_buffer.c \ firewall/firewall.c \ firewall/firewall_control.c \ firewall/helpers.c \ firewall/hslist.c \ + firewall/line_parser.c \ firewall/lsi.c \ + firewall/port_bindings.c \ firewall/reinject.c \ firewall/rule_management.c \ firewall/sysopp.c \ @@ -142,9 +178,9 @@ lib/core/hostsfiles.c \ lib/core/keylen.c \ lib/core/linkedlist.c \ - lib/core/lmod.c \ lib/core/message.c \ lib/core/options.c \ + lib/core/modularization.c \ lib/core/prefix.c \ lib/core/solve.c \ lib/core/statistics.c \ @@ -160,6 +196,16 @@ lib_core_libhipcore_la_SOURCES += lib/core/performance.c endif + +check_lib_core_SOURCES = test/check_lib_core.c \ + test/lib/core/hit.c \ + test/lib/core/straddr.c + +check_firewall_SOURCES = test/check_firewall.c \ + test/firewall/file_buffer.c \ + test/firewall/line_parser.c \ + test/firewall/port_bindings.c + # Initialize LDADD lists empty, because modules might add entries to LDADD. The # module LDADDs need to be included before the standard LDADDs, because modules # can depend on the core code. @@ -175,15 +221,17 @@ ### library dependencies ### -check_lib_core_LDADD = lib/core/libhipcore.la -firewall_hipfw_LDADD += lib/core/libhipcore.la -hipd_hipd_LDADD += lib/core/libhipcore.la -test_auth_performance_LDADD = lib/core/libhipcore.la -test_certteststub_LDADD = lib/core/libhipcore.la -test_dh_performance_LDADD = lib/core/libhipcore.la -test_hc_performance_LDADD = lib/core/libhipcore.la -tools_hipconf_LDADD += lib/core/libhipcore.la -tools_pisacert_LDADD = lib/core/libhipcore.la +check_lib_core_LDADD = lib/core/libhipcore.la +check_firewall_LDADD = lib/core/libhipcore.la +firewall_hipfw_LDADD += lib/core/libhipcore.la +hipd_hipd_LDADD += lib/core/libhipcore.la +test_auth_performance_LDADD = lib/core/libhipcore.la +test_certteststub_LDADD = lib/core/libhipcore.la +test_dh_performance_LDADD = lib/core/libhipcore.la +test_fw_port_bindings_performance_LDADD = lib/core/libhipcore.la +test_hc_performance_LDADD = lib/core/libhipcore.la +tools_hipconf_LDADD += lib/core/libhipcore.la +tools_pisacert_LDADD = lib/core/libhipcore.la dist_sbin_SCRIPTS = tools/hipdnskeyparse/hipdnskeyparse \ tools/hipdnsproxy/hipdnsproxy \ === modified file 'configure.ac' --- configure.ac 2010-11-09 14:18:47 +0000 +++ configure.ac 2010-11-15 17:08:02 +0000 @@ -1,3 +1,26 @@ +# Copyright (c) 2010 Aalto University and RWTH Aachen University. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. + AC_PREREQ([2.53]) AC_INIT([HIP for Linux], [1.0.6], [hipl-users@xxxxxxxxxxxxx], [hipl]) AC_CONFIG_HEADERS([config.h]) @@ -12,11 +35,13 @@ AC_DEFINE_UNQUOTED(HIPL_CONFIGURATION, "$@") AH_TEMPLATE(HIPL_CONFIGURATION, [options passed to configure]) -# Checks for programs. + +# program checks + AC_PROG_CC AC_PROG_INSTALL # AC_PROG_LIBTOOL() could be replaced with LT_INIT(disable-shared) but -# OpenWRT (Mar 2010) is running too old version of libtool +# OpenWrt (Mar 2010) is running too old version of libtool # LT_INIT(disable-shared) AC_PROG_LIBTOOL(disable-shared) @@ -28,22 +53,27 @@ # Enable silent rules only when available (automake 1.11 or later). m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) -# Check for python for build-system and tools directory -AM_PATH_PYTHON([2.4.3],, [AC_MSG_ERROR([min. required python version not found])]) - -# Checks for libraries. -AC_CHECK_LIB(crypto, DSA_generate_key,, AC_MSG_ERROR(openssl lib not found)) -# Check for ec crypto in openssl +# Check for Python for build-system and tools directory +AM_PATH_PYTHON([2.4.3],, [AC_MSG_ERROR([Minimum required Python version not found.])]) + + + +# library checks + +AC_CHECK_LIB(crypto, DSA_generate_key,, AC_MSG_ERROR(OpenSSL not found.)) +# Check for ellyptic curve crypto in OpenSSL. AC_CHECK_FUNC(EC_KEY_new, AC_DEFINE(HAVE_EC_CRYPTO) - AH_TEMPLATE(HAVE_EC_CRYPTO, [Defined to 1 if ec is enabled.]),) + AH_TEMPLATE(HAVE_EC_CRYPTO, [Defined to 1 if elliptic curve crypto is enabled.])) # We need the math lib in the registration extension. -AC_CHECK_LIB(m, pow,, AC_MSG_ERROR(Math lib not found)) +AC_CHECK_LIB(m, pow,, AC_MSG_ERROR(Math library not found.)) # The unit tests depend on 'check' (http://check.sourceforge.net/) AC_CHECK_LIB(check, suite_create,, - AC_MSG_WARN(libcheck (http://check.sourceforge.net/) not found: HIPL unit tests are not available),) + AC_MSG_WARN(libcheck (http://check.sourceforge.net/) not found: unit tests not available)) AM_CONDITIONAL(HIP_UNITTESTS, test x"$ac_cv_lib_check_suite_create" = xyes) + + # If no --prefix option is passed to configure, $prefix is empty. But we want # to expand $sysconfdir, which defaults to ${prefix}/etc. So set $prefix. if test "x$prefix" = "xNONE"; then @@ -73,9 +103,6 @@ AH_TEMPLATE(HIPL_CONFIG_FILE, [default config file location]) -AC_ARG_WITH(nomodules, - AS_HELP_STRING([--with-nomodules=list], - [comma-separated list of disabled modules])) # Set default AM_CFLAGS for the complete project. AC_SUBST(AM_CFLAGS, "-std=c99 -Wall -Wextra -Werror") @@ -91,9 +118,13 @@ # Set the preprocessor flags for the entire project AC_SUBST(AM_CPPFLAGS, "-D_POSIX_C_SOURCE=200112L -D_XOPEN_SOURCE=500") + + +# configure options + AC_ARG_ENABLE(firewall, AS_HELP_STRING([--enable-firewall], - [HIP enabled firewall daemon (default is YES)]), + [HIP firewall daemon (default is YES)]), [ac_cv_use_firewall=$enableval], [ac_cv_use_firewall=yes]) AC_CACHE_CHECK([whether to use firewall], @@ -110,7 +141,7 @@ AC_ARG_ENABLE(rvs, AS_HELP_STRING([--enable-rvs], - [HIP Rendezvous Extensions (default is YES)]), + [HIP Rendezvous extensions (default is YES)]), [ac_cv_use_rvs=$enableval], [ac_cv_use_rvs=yes]) AC_CACHE_CHECK([whether to use RVS], @@ -180,7 +211,7 @@ AC_ARG_ENABLE(performance, AS_HELP_STRING([--enable-performance], - [Performace measurement support (default is NO)]), + [Performance measurement support (default is NO)]), [ac_cv_use_performance=$enableval], [ac_cv_use_performance=no]) AC_CACHE_CHECK([whether to use performance measurement], @@ -193,18 +224,10 @@ fi AM_CONDITIONAL(HIP_PERFORMANCE, test x"$ac_cv_use_performance" = x"yes") -AC_ARG_ENABLE(demo, - AS_HELP_STRING([--enable-demo], - [Demo output (default is NO)]), - [ac_cv_use_demo=$enableval], - [ac_cv_use_demo=no]) -AC_CACHE_CHECK([whether to print output for demos], - [ac_cv_use_demo], - [ac_cv_use_demo=no]) -if test x"$ac_cv_use_demo" = x"yes"; then - AC_DEFINE(CONFIG_HIP_DEMO) - AH_TEMPLATE(CONFIG_HIP_DEMO, [Defined to 1 if demo is enabled.]) -fi +AC_ARG_WITH(nomodules, + AS_HELP_STRING([--with-nomodules=list], + [comma-separated list of disabled modules])) + # Parse modules directory @@ -212,7 +235,7 @@ echo "+-----------------------------------------------"; echo "| processing modules..."; echo "|"; -$PYTHON ${srcdir}/process_modules.py -s "${srcdir}" -d "${with_nomodules}" -m "modules/" +$PYTHON "${srcdir}/process_modules.py" -s "${srcdir}" -d "${with_nomodules}" -m "modules/" if [[ "$?" != "0" ]]; then echo "configure: error: Module processing failed" exit 1 @@ -221,6 +244,8 @@ echo "+-----------------------------------------------" echo "" + + AC_CONFIG_FILES([ Makefile doc/Doxyfile doc/HOWTO.xml tools/nsupdate.pl tools/hipdnsproxy/hipdnsproxy ]) AC_OUTPUT === modified file 'firewall/cache.c' --- firewall/cache.c 2010-10-15 15:29:14 +0000 +++ firewall/cache.c 2010-11-12 15:49:05 +0000 @@ -174,7 +174,7 @@ * @param local local identifier or locator (optional) * @param peer peer identifier or locator * @param type whether the parameters are HITs, LSIs or IPs - * @param query_daemon whether to query the demon for HA information + * @param query_daemon whether to query the daemon for HA information * if no entry is found in the cache * @return the entry on match, NULL otherwise */ === modified file 'firewall/esp_prot_conntrack.c' --- firewall/esp_prot_conntrack.c 2010-10-15 15:29:14 +0000 +++ firewall/esp_prot_conntrack.c 2010-11-15 13:38:47 +0000 @@ -111,7 +111,7 @@ long i; if (cache_item) { - anchor_item = (struct esp_anchor_item *) cache_item; + anchor_item = cache_item; for (i = 0; i < num_parallel_hchains; i++) { if (anchor_item->active_anchors[i]) { @@ -399,8 +399,7 @@ } // delete cached item from the list - HIP_IFEL(!(anchor_item = (struct esp_anchor_item *) - hip_ll_del(&esp_tuple->anchor_cache, + HIP_IFEL(!(anchor_item = hip_ll_del(&esp_tuple->anchor_cache, element_index, NULL)), -1, "failed to remove anchor_item from list\n"); free(anchor_item); === added file 'firewall/file_buffer.c' --- firewall/file_buffer.c 1970-01-01 00:00:00 +0000 +++ firewall/file_buffer.c 2010-11-12 17:49:42 +0000 @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2010 Aalto University and RWTH Aachen University. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * @file + * @author Stefan Goetz <stefan.goetz@xxxxxxxxxxxxxxxxx> + */ + +#include <errno.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "lib/core/debug.h" +#include "file_buffer.h" + +/** + * Always allocate this many more bytes for the memory buffer than is needed + * the actual file contents. + * This avoids having to re-allocate the buffer for very small increases in the + * file size. + */ +static const unsigned int HIP_FB_HEADROOM = 4096; + +/** + * Allocate at most this many bytes, i.e., the maximum supported file size. + * This is an arbitrary number used for sanity checking. + */ +static const unsigned long HIP_FB_MAX_SIZE = 1024 * 1024 * 1024; + +/** + * (Re-)allocates the file buffer so that it can hold a complete copy of its + * file in memory. + * After the function completes successfully, the memory area associated with + * the file buffer points to an allocated region of memory that is at least as + * large as the size of the file buffer's file at the time of invocation. + * The contents of the memory area are undefined. + * + * If the size of a file cannot be determined (lseek() does not work on proc + * files), the buffer size is increased incrementally. + * + * @param fb the file buffer to use. + * @return If the function completes successfully, it returns 0. + * If fb is NULL, -1 is returned. + * If internal errors occur, other negative values are returned. + */ +static int hip_fb_resize(struct hip_file_buffer *const fb) +{ + int err = 0; + + if (fb) { + off_t file_size = 0; + + free(fb->ma.start); + fb->ma.start = NULL; + + /* First, we try to determine the current file size for the new buffer size. + * If that fails (it does, e.g., for proc files), we just increase the + * current buffer size. */ + errno = 0; + file_size = lseek(fb->fd, 0, SEEK_END); + if (file_size != -1 || EINVAL == errno) { + if (file_size != -1) { + fb->buffer_size = file_size + HIP_FB_HEADROOM; // add a little head room + } else if (EINVAL == errno) { + if (fb->buffer_size < HIP_FB_HEADROOM) { + fb->buffer_size = HIP_FB_HEADROOM; + } else { + fb->buffer_size *= 2; + } + } + + // fb->buffer_size is now adjusted, but maybe not positive or very large? + if (fb->buffer_size > 0 && fb->buffer_size <= HIP_FB_MAX_SIZE) { + // fb->buffer_size is now the size we want to allocate + fb->ma.start = malloc(fb->buffer_size); + if (fb->ma.start) { + return 0; + } else { + HIP_ERROR("Allocating %d bytes of memory for file data failed\n", + fb->buffer_size); + err = -4; + } + } else { + HIP_ERROR("The file buffer size %d is too large to be supported\n"); + err = -3; + } + } else { + HIP_ERROR("Determining file size via lseek() failed: %s\n", strerror(errno)); + err = -2; + } + fb->buffer_size = 0; + } else { + err = -1; + } + + return err; +} + +/** + * Initializes a file buffer that holds the specified file. + * + * A file buffer is used to load and hold the contents of a file in + * memory (for simplified access or improved performance). + * The memory buffer is allocated so that the whole file fits in it. + * Any changes to the memory buffer are not written back to the file and remain + * local to the memory buffer. + * Note that this is useful primarily with files that cannot be mapped into + * memory via mmap(), such as files in /proc. + * For regular files, using mmap() is vastly more efficient. + * + * This function allocates resources, in particular memory, for the returned + * object. + * To free these resources and to avoid memory leaks, it is imperative to call + * hip_fb_delete() when the object created here is no longer used. + * + * @param fb a pointer to a valid, allocated instance of struct hip_file_buffer. + * Upon successful completion, the function writes file-specific context data + * to the location referenced by fb. + * @param file_name the name of the file to open and load into memory. + * @return a 0 if the file could be opened and successfully buffered. + * -1 is returned if fb is NULL or if file_name is NULL. + * -2 is returned if the specified file cannot be opened for reading. + * -3 is returned if an internal error occurs. + */ +int hip_fb_create(struct hip_file_buffer *const fb, + const char *const file_name) +{ + int err = 0; + + if (fb && file_name) { + memset(fb, 0, sizeof(*fb)); // set all fields to 0/NULL + fb->fd = open(file_name, O_RDONLY); + if (fb->fd != -1) { + if (hip_fb_reload(fb) == 0) { + return 0; + } else { + err = -3; + } + } else { + HIP_ERROR("Opening the file %s for reading via open() failed with the error %s\n", + file_name, strerror(errno)); + err = -2; + } + hip_fb_delete(fb); + } else { + err = -1; + } + + return err; +} + +/** + * De-allocates the resources associated with a file buffer object in + * hip_fb_create(). + * This function does not de-allocated the memory pointed to by fb. + * After calling this function, the result of calling any other hip_fb_...() + * function on the file buffer fb is undefined. + * + * @param fb the file buffer to delete. If fb is NULL, this function has no + * effect. + */ +void hip_fb_delete(struct hip_file_buffer *const fb) +{ + if (fb) { + if (fb->fd != -1) { + close(fb->fd); + fb->fd = -1; + } + free(fb->ma.start); + fb->ma.start = NULL; + fb->ma.end = NULL; + } +} + +/** + * Make modifications to the file since the last invocation of hip_fb_create() or + * hip_fb_reload() visible in the buffer. + * + * @warning + * Note that this function may change the start and end pointers in the memory + * area returned by hip_fb_get_mem_area()! + * + * @param fb the file buffer to use. + * @return 0 when the function completes successfully. + * If fb is NULL, -1 is returned. + * If an internal error occurs, -2 is returned. + */ +int hip_fb_reload(struct hip_file_buffer *const fb) +{ + if (!fb) { + return -1; + } + + while (1) { + ssize_t bytes; + off_t seek_offset; + + // can we re-read the whole file into the memory buffer? + seek_offset = lseek(fb->fd, 0, SEEK_SET); + if (-1 == seek_offset) { + HIP_ERROR("Resetting the read position on file descriptor %d via lseek() failed with the error %s\n", + fb->fd, errno, strerror(errno)); + break; + } + + bytes = read(fb->fd, fb->ma.start, fb->buffer_size); + if (bytes == -1) { + HIP_ERROR("Reading the contents of the file descriptor %d via read() into a memory buffer of size %d failed with the error %s\n", + fb->fd, fb->buffer_size, strerror(errno)); + break; + } else if ((size_t)bytes == fb->buffer_size) { + // we can't fit the file into the memory buffer -> resize it + if (hip_fb_resize(fb) == 0) { + // successful resize -> retry reading + continue; + } else { + // error resizing -> return error + break; + } + } else { + // successfully read the file contents into the buffer + fb->ma.end = fb->ma.start + bytes; + return 0; + } + } + + fb->ma.end = NULL; + + return -2; +} === added file 'firewall/file_buffer.h' --- firewall/file_buffer.h 1970-01-01 00:00:00 +0000 +++ firewall/file_buffer.h 2010-11-12 17:49:42 +0000 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2010 Aalto University and RWTH Aachen University. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * @file + * @author Stefan Goetz <stefan.goetz@xxxxxxxxxxxxxxxxx> + */ + +#ifndef HIP_FIREWALL_FILE_BUFFER_H +#define HIP_FIREWALL_FILE_BUFFER_H + +#include "mem_area.h" + +struct hip_file_buffer; + +int hip_fb_create(struct hip_file_buffer *const fb, + const char *const file_name); +void hip_fb_delete(struct hip_file_buffer *const fb); +static inline const struct hip_mem_area *hip_fb_get_mem_area(const struct hip_file_buffer *const fb); +int hip_fb_reload(struct hip_file_buffer *const fb); + +#include "firewall/file_buffer_inline.h" + +#endif /* HIP_FIREWALL_FILE_BUFFER_H */ === added file 'firewall/file_buffer_inline.h' --- firewall/file_buffer_inline.h 1970-01-01 00:00:00 +0000 +++ firewall/file_buffer_inline.h 2010-11-12 17:49:42 +0000 @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2010 Aalto University and RWTH Aachen University. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * @file + * @author Stefan Goetz <stefan.goetz@xxxxxxxxxxxxxxxxx> + */ + +#ifndef HIP_FIREWALL_FILE_BUFFER_INLINE_H +#define HIP_FIREWALL_FILE_BUFFER_INLINE_H + +/* On the one hand, the contents of this file are part of the public interface + * and thus only their declaration should go into the public header file. + * On the other hand, these functions should be inlineable so their definitions + * have to appear in a header file. + * To achieve inlineability and still hide the implementation, we use this + * secondary header file that is not part of the public interface. */ +#ifndef HIP_FIREWALL_FILE_BUFFER_H +#error This file must not be included directly because it contains implementation details. It may only be included by file_buffer.h. +#endif + +#include <sys/types.h> +#include <stddef.h> + +#include "mem_area.h" + +/** + * A file buffer object represents an open file and its associated memory + * buffer. + */ +struct hip_file_buffer { + /** + * The memory area holding the file contents. + * Its start field points to the first byte of file data and the beginning + * of the allocated memory buffer. + * Its end field points to the last byte of file data + 1. + */ + struct hip_mem_area ma; + /* + * The number of bytes in the allocated buffer that ma.start points to. + * buffer_size is equal to or greater than (ma.end - ma.start). + */ + size_t buffer_size; + /* + * The file descriptor for the file backing the buffer. + */ + int fd; +}; + +/** + * Retrieve the memory area in which the file contents are stored. + * + * There is a 1:1 relationship between the passed in fb object and the returned + * pointer. + * That is, calling this function on the same fb object will always return the + * same struct hip_mem_area pointer. + * Thus, you may assume that the returned struct hip_mem_area pointer has the + * same life time as its associated struct hip_file_buffer object. + * However, hip_fb_reload() may change the start and end address in the + * returned struct hip_mem_area object! + * + * @param fb the file buffer object holding the memory area to retrieve. + * @return a pointer to the struct hip_mem_area object associated with the + * given file buffer object. + * If the passed in file buffer pointer is invalid, this function returns + * NULL. + */ +static inline const struct hip_mem_area *hip_fb_get_mem_area(const struct hip_file_buffer *const fb) +{ + if (fb) { + return &fb->ma; + } + return NULL; +} + +#endif /* HIP_FIREWALL_FILE_BUFFER_INLINE_H */ === modified file 'firewall/firewall.c' --- firewall/firewall.c 2010-11-09 13:04:44 +0000 +++ firewall/firewall.c 2010-11-15 17:08:02 +0000 @@ -74,7 +74,6 @@ #include "lib/core/filemanip.h" #include "lib/core/hip_udp.h" #include "lib/core/ife.h" -#include "lib/core/lmod.h" #include "lib/core/message.h" #include "lib/core/options.h" #include "lib/core/performance.h" @@ -85,7 +84,6 @@ #include "modules/firewall_modules.h" #include "config.h" #include "cache.h" -#include "cache_port.h" #include "common_types.h" #include "conntrack.h" #include "esp_prot_api.h" @@ -96,6 +94,7 @@ #include "lsi.h" #include "midauth.h" #include "pisa.h" +#include "port_bindings.h" #include "reinject.h" #include "rule_management.h" #include "user_ipsec_api.h" @@ -640,7 +639,7 @@ // Initializing local cache database hip_firewall_cache_init_hldb(); // Initializing local port cache database - hip_firewall_port_cache_init_hldb(); + hip_port_bindings_init(true); /* Initialize raw sockets for packet reinjection */ hip_firewall_init_raw_sockets(); @@ -768,7 +767,7 @@ } hip_firewall_cache_delete_hldb(1); - hip_firewall_port_cache_uninit_hldb(); + hip_port_bindings_uninit(); hip_fw_uninit_system_based_opp_mode(); hip_fw_flush_iptables(); /* rules have to be removed first, otherwise HIP packets won't pass through === added file 'firewall/line_parser.c' --- firewall/line_parser.c 1970-01-01 00:00:00 +0000 +++ firewall/line_parser.c 2010-11-12 17:49:42 +0000 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2010 Aalto University and RWTH Aachen University. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * @file + * @author Stefan Goetz <stefan.goetz@xxxxxxxxxxxxxxxxx> + */ + +#include <stdlib.h> + +#include "file_buffer.h" +#include "line_parser.h" + +/** + * Initializes a parser that iterates over the lines of a given memory area. + * + * A line parser object is used to linearly iterate over the lines in a memory + * area that holds text. + * The memory area contents are not modified and the returned line pointers are + * terminated by newline characters, not null characters. + * + * When this function returns successfully, hip_lp_first() can be called + * immediately to start parsing. + * This function allocates resources, in particular memory, for the returned + * object. + * To free these resources and to avoid memory leaks, it is imperative to call + * hip_lp_delete() when the object created here is no longer used. + * + * @param lp a pointer to a valid, allocated instance of struct hip_line_parser. + * Upon successful completion, the function writes parser-specific context + * data to the location referenced by lp. + * @param ma the memory area to interpret as text and to parse by lines. + * @return 0 if the line parser lp was successfully initialized. + * This function return -1 if lp is NULL or if ma is NULL. + */ +int hip_lp_create(struct hip_line_parser *const lp, + const struct hip_mem_area *const ma) +{ + if (lp && ma) { + lp->ma = ma; + lp->cur = NULL; + return 0; + } + + return -1; +} + +/** + * Releases the resources allocated for a line parser object in + * hip_lp_create(). + * This does not include the memory pointed to by lp or the struct hip_mem_area + * object this parser was created with or the memory backing that memory area). + * + * @param lp the line parser object to delete. + * If lp is NULL, calling this function has no effect. + */ +void hip_lp_delete(struct hip_line_parser *const lp) +{ + if (lp) { + lp->ma = NULL; + lp->cur = NULL; + } +} === added file 'firewall/line_parser.h' --- firewall/line_parser.h 1970-01-01 00:00:00 +0000 +++ firewall/line_parser.h 2010-11-12 17:49:42 +0000 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2010 Aalto University and RWTH Aachen University. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * @file + * @author Stefan Goetz <stefan.goetz@xxxxxxxxxxxxxxxxx> + */ + +#ifndef HIP_FIREWALL_LINE_PARSER_H +#define HIP_FIREWALL_LINE_PARSER_H + +#include "mem_area.h" + +struct hip_line_parser; + +int hip_lp_create(struct hip_line_parser *const lp, + const struct hip_mem_area *const ma); +void hip_lp_delete(struct hip_line_parser *const lp); +static inline char *hip_lp_first(struct hip_line_parser *const lp); +static inline char *hip_lp_next(struct hip_line_parser *const lp); + +#include "firewall/line_parser_inline.h" + +#endif /* HIP_FIREWALL_LINE_PARSER_H */ === added file 'firewall/line_parser_inline.h' --- firewall/line_parser_inline.h 1970-01-01 00:00:00 +0000 +++ firewall/line_parser_inline.h 2010-11-12 17:49:42 +0000 @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2010 Aalto University and RWTH Aachen University. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * @file + * @author Stefan Goetz <stefan.goetz@xxxxxxxxxxxxxxxxx> + */ + +#ifndef HIP_FIREWALL_LINE_PARSER_INLINE_H +#define HIP_FIREWALL_LINE_PARSER_INLINE_H + +/* On the one hand, the contents of this file are part of the public interface + * and thus only their declaration should go into the public header file. + * On the other hand, these functions should be inlineable so their definitions + * have to appear in a header file. + * To achieve inlineability and still hide the implementation, we use this + * secondary header file that is not part of the public interface. */ +#ifndef HIP_FIREWALL_LINE_PARSER_H +#error This file must not be included directly because it contains implementation details. It may only be included by line_parser.h. +#endif + +#include <string.h> + +#include "lib/core/debug.h" +#include "file_buffer.h" + +/** + * Represents the parsing state on a memory area object. + */ +struct hip_line_parser { + /** + * The memory area this parser operates on. + */ + const struct hip_mem_area *ma; + /** + * The current parsing position. + * If NULL, hip_lp_first() needs to be called. + * If != NULL, points to the start of line in the memory buffer. + */ + char *cur; +}; + +/** + * Start a new parsing pass with a line parser and return the first line in the + * buffer. + * The buffer is not modified and the line is terminated by a newline + * character (not a null character). + * + * A parsing pass consists of starting it via hip_lp_first() and iterating over + * the lines in the file via hip_lp_next() until it returns NULL. + * + * @param lp the line parser to use. + * @return a pointer to the first line in the file or NULL if no line is + * available. + */ +static inline char *hip_lp_first(struct hip_line_parser *const lp) +{ + if (!lp || + !lp->ma) { + return NULL; + } + + lp->cur = lp->ma->start; + + return lp->cur; +} + +/** + * Get the next line in a parsing pass with a line parser. + * + * Each invocation of this function returns a pointer to consecutive lines in + * the buffer to parse. + * After the last line has been reached, NULL is returned. + * In that case, parsing can restart by calling hip_lp_first(). + * + * @param lp the line parser parser to use. + * @return a pointer to a line in the buffer or NULL if there are no more lines + * available. + */ +static inline char *hip_lp_next(struct hip_line_parser *const lp) +{ + size_t remaining; + + if (!lp || + !lp->cur || + !lp->ma || + !lp->ma->start || + !lp->ma->end || + lp->cur < lp->ma->start || + lp->cur >= lp->ma->end) { + return NULL; + } + + remaining = lp->ma->end - lp->cur; + lp->cur = memchr(lp->cur, '\n', remaining); + + // given the rest of the parsing code, we should always find a \n, but + // let's check to be sure + if (lp->cur) { + // cur should not point to the new-line character but to the next one: + lp->cur += 1; + // is there text on the line here or are we at the end? + if (lp->cur >= lp->ma->end) { + lp->cur = NULL; + } + } + + return lp->cur; +} + +#endif /* HIP_FIREWALL_LINE_PARSER_INLINE_H */ === modified file 'firewall/lsi.c' --- firewall/lsi.c 2010-10-15 15:29:14 +0000 +++ firewall/lsi.c 2010-10-24 22:20:24 +0000 @@ -64,7 +64,7 @@ #include "lib/core/prefix.h" #include "lib/core/protodefs.h" #include "cache.h" -#include "cache_port.h" +#include "port_bindings.h" #include "firewall.h" #include "lsi.h" #include "reinject.h" @@ -316,11 +316,9 @@ int verdict = 1; int ip_hdr_size = 0; int portDest = 0; - int process_as_lsi = 0; fw_cache_hl_t *entry = NULL; - const struct firewall_port_cache_hl *port_cache_entry = NULL; + enum hip_port_binding port_binding = HIP_PORT_INFO_UNKNOWN; const struct ip6_hdr *ip6_hdr = NULL; - char proto[PROTO_STRING_MAX]; struct in6_addr src_addr, dst_addr; ip6_hdr = (const struct ip6_hdr *) m->payload; @@ -329,11 +327,9 @@ switch (ip6_hdr->ip6_nxt) { case IPPROTO_UDP: portDest = ((const struct udphdr *) ((m->payload) + ip_hdr_size))->dest; - strcpy(proto, "udp6"); break; case IPPROTO_TCP: portDest = ((const struct tcphdr *) ((m->payload) + ip_hdr_size))->dest; - strcpy(proto, "tcp6"); break; case IPPROTO_ICMPV6: HIP_DEBUG("ICMPv6 packet\n"); @@ -343,50 +339,45 @@ break; } - /* port caching */ - port_cache_entry = hip_firewall_port_cache_db_match(portDest, - ip6_hdr->ip6_nxt); + port_binding = hip_port_bindings_get(ip6_hdr->ip6_nxt, + portDest); - if (port_cache_entry && - (port_cache_entry->traffic_type == - FIREWALL_PORT_CACHE_IPV6_TRAFFIC)) { + if (port_binding == HIP_PORT_INFO_IPV6BOUND) { + HIP_DEBUG("Port %d is bound to an IPv6 address -> accepting packet\n", portDest); verdict = 1; - HIP_DEBUG("Cached port, accepting\n"); - goto out_err; - } + } else if (port_binding == HIP_PORT_INFO_IPV6UNBOUND) { + HIP_DEBUG("Port %d is unbound or bound to an IPv4 address -> looking up in cache\n", portDest); + HIP_IFEL(!(entry = hip_firewall_cache_db_match(ip_dst, ip_src, + FW_CACHE_HIT, 1)), + -1, "Failed to obtain from cache\n"); - if (lsi_support) { /* Currently preferring LSIs over opp. connections */ - process_as_lsi = 1; - } - - HIP_IFEL(!(entry = hip_firewall_cache_db_match(ip_dst, ip_src, - FW_CACHE_HIT, 1)), - -1, "Failed to obtain from cache\n"); - - if (process_as_lsi) { - HIP_DEBUG("Trying lsi transformation\n"); - HIP_DEBUG_LSI("lsi_our: ", &entry->lsi_our); - HIP_DEBUG_LSI("lsi_peer: ", &entry->lsi_peer); - IPV4_TO_IPV6_MAP(&entry->lsi_our, &dst_addr); - IPV4_TO_IPV6_MAP(&entry->lsi_peer, &src_addr); - HIP_IFEL(hip_reinject_packet(&src_addr, &dst_addr, m, 6, 1), -1, - "Failed to reinject with LSIs\n"); - HIP_DEBUG("Successful LSI transformation.\n"); - - if (ip6_hdr->ip6_nxt == IPPROTO_ICMPV6) { - verdict = 1; /* broadcast: dst may be ipv4 or ipv6 */ + if (lsi_support) { + HIP_DEBUG("Trying lsi transformation\n"); + HIP_DEBUG_LSI("lsi_our: ", &entry->lsi_our); + HIP_DEBUG_LSI("lsi_peer: ", &entry->lsi_peer); + IPV4_TO_IPV6_MAP(&entry->lsi_our, &dst_addr); + IPV4_TO_IPV6_MAP(&entry->lsi_peer, &src_addr); + HIP_IFEL(hip_reinject_packet(&src_addr, &dst_addr, m, 6, 1), -1, + "Failed to reinject with LSIs\n"); + HIP_DEBUG("Successful LSI transformation.\n"); + + if (ip6_hdr->ip6_nxt == IPPROTO_ICMPV6) { + verdict = 1; /* broadcast: dst may be ipv4 or ipv6 */ + } else { + verdict = 0; /* drop original */ + } } else { - verdict = 0; /* drop original */ + HIP_DEBUG("Trying sys opp transformation\n"); + HIP_DEBUG_IN6ADDR("ip_src: ", &entry->ip_peer); + HIP_DEBUG_IN6ADDR("ip_dst: ", &entry->ip_our); + HIP_IFEL(hip_reinject_packet(&entry->ip_peer, &entry->ip_our, m, 6, 1), + -1, "Failed to reinject with IP addrs\n"); + HIP_DEBUG("Successfull sysopp transformation. Drop orig\n"); + verdict = 0; } } else { - HIP_DEBUG("Trying sys opp transformation\n"); - HIP_DEBUG_IN6ADDR("ip_src: ", &entry->ip_peer); - HIP_DEBUG_IN6ADDR("ip_dst: ", &entry->ip_our); - HIP_IFEL(hip_reinject_packet(&entry->ip_peer, &entry->ip_our, m, 6, 1), - -1, "Failed to reinject with IP addrs\n"); - HIP_DEBUG("Successfull sysopp transformation. Drop orig\n"); - verdict = 0; + HIP_DIE("hip_port_bindings_get() returned unknown return value %d\n", port_binding); } out_err: === added file 'firewall/mem_area.h' --- firewall/mem_area.h 1970-01-01 00:00:00 +0000 +++ firewall/mem_area.h 2010-11-12 17:49:42 +0000 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2010 Aalto University and RWTH Aachen University. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * @file + * @author Stefan Goetz <stefan.goetz@xxxxxxxxxxxxxxxxx> + */ + +#ifndef HIP_FIREWALL_MEM_AREA_H +#define HIP_FIREWALL_MEM_AREA_H + +/** + * A range of memory with a defined start and end. + * + * This structure is useful where the information is needed about a specific + * memory area, e.g., for a file loaded into memory. + */ +struct hip_mem_area { + char *start; + char *end; +}; + +#endif === renamed file 'firewall/cache_port.c' => 'firewall/port_bindings.c' --- firewall/cache_port.c 2010-10-15 15:29:14 +0000 +++ firewall/port_bindings.c 2010-11-12 17:49:42 +0000 @@ -25,277 +25,465 @@ /** * @file - * Cache TCP and UDP port information for incoming HIP-related connections for - * LSIs. When hipfw sees an incoming HIT-based connection, it needs to figure out if - * it needs to be translated to LSI or not. LSI translation is done only when there is - * no IPv6 application bound the corresponding TCP or UDP port. The port information - * can be read from /proc but consumes time. To avoid this overhead, hipfw caches - * the port information after the first read. Notice that cache is static and hipfw - * must be restarted if there are changes in the port numbers. This is described in - * more detail in <a - * href="http://hipl.hiit.fi/hipl/thesis_teresa_finez.pdf";>T. Finez, - * Backwards Compatibility Experimentation with Host Identity Protocol - * and Legacy Software and Networks , final project, December 2008</a>. - * - * @brief Cache TCP and UDP port numbers for inbound HIP-related connections to optimize LSI translation - * - * @author Miika Komu <miika@xxxxxx> + * @brief Look up whether a port corresponds to a local bound socket, which influences LSI handling. + * + * @author Miika Komu <miika@xxxxxx>, Stefan Goetz <stefan.goetz@xxxxxxxxxxxxxxxxx> */ -#include <stdio.h> +#include <netinet/in.h> +#include <errno.h> +#include <signal.h> #include <stdint.h> +#include <stdlib.h> #include <string.h> -#include <netinet/in.h> +#include <time.h> +#include <unistd.h> -#include "lib/core/builder.h" +#include "lib/core/common.h" #include "lib/core/debug.h" -#include "lib/core/hashtable.h" -#include "lib/core/icomm.h" -#include "lib/core/list.h" -#include "lib/core/prefix.h" -#include "lib/tool/lutil.h" -#include "cache.h" -#include "cache_port.h" - - -static HIP_HASHTABLE *firewall_port_cache_db = NULL; - -/** - * Check from the proc file system whether a local port is attached - * to an IPv4 or IPv6 address. This is required to determine whether - * incoming packets should be diverted to an LSI. - * - * @param port_dest the port number of the socket - * @param *proto protocol type - * @return 1 if it finds the required socket, 0 otherwise - * - * @note this is used only from the firewall, so move this there - */ -static int hip_get_proto_info(in_port_t port_dest, char *proto) -{ - FILE *fd = NULL; - char line[500], sub_string_addr_hex[8], path[11 + sizeof(proto)]; - char *fqdn_str = NULL, *separator = NULL, *sub_string_port_hex = NULL; - int lineno = 0, index_addr_port = 0, exists = 0, result; - uint32_t result_addr; - struct in_addr addr; - List list; - - if (!proto) { - return 0; - } - - if (!strcmp(proto, "tcp6") || !strcmp(proto, "tcp")) { - index_addr_port = 15; - } else if (!strcmp(proto, "udp6") || !strcmp(proto, "udp")) { - index_addr_port = 10; - } else { - return 0; - } - - strcpy(path, "/proc/net/"); - strcat(path, proto); - fd = fopen(path, "r"); - - initlist(&list); - while (fd && getwithoutnewline(line, 500, fd) != NULL && !exists) { - lineno++; - - destroy(&list); - initlist(&list); - - if (lineno == 1 || strlen(line) <= 1) { - continue; - } - - extractsubstrings(line, &list); - - fqdn_str = getitem(&list, index_addr_port); - if (fqdn_str) { - separator = strrchr(fqdn_str, ':'); - } - - if (!separator) { - continue; - } - - sub_string_port_hex = strtok(separator, ":"); - sscanf(sub_string_port_hex, "%X", &result); - HIP_DEBUG("Result %i\n", result); - HIP_DEBUG("port dest %i\n", port_dest); - if (result == port_dest) { - strncpy(sub_string_addr_hex, fqdn_str, 8); - sscanf(sub_string_addr_hex, "%X", &result_addr); - addr.s_addr = result_addr; - if (IS_LSI32(addr.s_addr)) { - exists = 2; - break; - } else { - exists = 1; - break; - } - } - } /* end of while */ - if (fd) { - fclose(fd); - } - destroy(&list); - - return exists; -} - -/** - * add a default entry in the firewall port cache. - * - * @param key the hash key (a string consisting of concatenation of the port, an underscore and the protocol) - * @param value the value for the hash key (LSI mode value) - * - * @return zero on success or non-zero on failure - */ -static int hip_port_cache_add_new_entry(const char *key, int value) -{ - struct firewall_port_cache_hl *new_entry = NULL; +#include "lib/core/ife.h" +#include "line_parser.h" +#include "port_bindings.h" + +/** + * The number of seconds after which hip_port_bindings_trigger_reload() is + * called periodically. + * The smaller this number, the more up-to-date information is returned by + * hip_port_bindings_get(). + * At the same time, a small interval also causes the somewhat expensive + * hip_port_bindings_reload() to be called more frequently. + */ +const unsigned int INVALIDATION_INTERVAL = 1; + +/** + * Indicates whether the caches should be invalidated. + * This is periodically set to 1 by a timer and reset the next time a lookup is + * performed. + */ +volatile sig_atomic_t cache_invalidation_flag = 1; + +/** + * Pointer to the port bindings cache. + * + * The cache is a two-dimensional array. + * The first dimension is the transport protocol for which a port can be bound + * (supported are TCP and UDP). + * The second dimension is the port number itself. + * The value is a uint8_t representation of an enum hip_port_binding value + */ +static uint8_t *cache = NULL; + +static const unsigned int CACHE_SIZE_PROTOS = 2; +static const unsigned int CACHE_SIZE_PORTS = 1 << (sizeof(in_port_t) * 8); +static unsigned int cache_size_entries = 0; +static unsigned int cache_size_bytes = 0; + +/** + * Allocate and initializes the cache resources. + * If this function has not been called first, the results of calling + * cache_get() and cache_set() are undefined. + * + * @return 0 if the function completes successfully. + * If the memory for the cache could not be allocated, this function returns + * -1. + */ +static int init_cache(void) +{ + HIP_ASSERT(!cache); + + cache_size_entries = CACHE_SIZE_PROTOS * CACHE_SIZE_PORTS; + cache_size_bytes = cache_size_entries * sizeof(*cache); + + // check that the conversion used in the cache from enum hip_port_binding + // to uint8_t is consistent + HIP_ASSERT(HIP_PORT_INFO_IPV6UNBOUND == (enum hip_port_binding)(uint8_t)HIP_PORT_INFO_IPV6UNBOUND); + HIP_ASSERT(HIP_PORT_INFO_IPV6BOUND == (enum hip_port_binding)(uint8_t)HIP_PORT_INFO_IPV6BOUND); + + /* We zero the cache on allocation assuming that HIP_PORT_INFO_UNKNOWN + is 0 and thus the whole cache initially has that value. */ + HIP_ASSERT((uint8_t)HIP_PORT_INFO_UNKNOWN == 0); + cache = calloc(1, cache_size_bytes); + if (cache) { + return 0; + } else { + HIP_ERROR("Allocating the port bindings cache failed\n"); + return -1; + } +} + +/** + * Release the cache resources. + * After calling this function, the results of calling cache_get() and + * cache_set() are undefined. + */ +static void uninit_cache(void) +{ + free(cache); + cache = NULL; +} + +/** + * Determines the index of a cache entry. + * The cache array should only be indexed via this function. + * + * The flat cache entry index can be used to access the cache as a + * one-dimensional array. + * Using it is not strictly necessary because it would be possible and more + * beautiful to behold to access the cache as a two-dimensional array, but the + * one-dimensional flat index determined here can also be used for bounds + * checking. + * + * @param protocol the protocol the specified port belongs to. + * The value is the same as used in the IPv4 'protocol' and the IPv6 'Next + * Header' fields. + * The only supported values are 6 for TCP and 17 for UDP. + * @param port the port in host byte order to get the port binding for. + * Valid values range from 0 to 2^16-1. + * @return the index of the cache entry for @a protocol and @a port. + */ +static inline unsigned int get_cache_index(const uint8_t protocol, + const uint16_t port) +{ + unsigned int index = 0; + unsigned int protocol_offset = 0; + + // determine the offset into the first (protocol) dimension + if (IPPROTO_TCP == protocol) { + protocol_offset = 0; + } else if (IPPROTO_UDP == protocol) { + protocol_offset = 1; + } else { + HIP_DIE("Invalid protocol"); + } + + // calculate the index + index = (protocol_offset * CACHE_SIZE_PORTS) + port; + + return index; +} + +/** + * Cache binding state on the port of a given protocol. + * + * This function is called after looking up port binding status from the /proc + * file system. + * After it has been called, a call to hip_firewall_port_cache_set() with the + * same protocol and port returns the previously set port binding. + * + * @param protocol the protocol the specified port belongs to. + * The value is the same as used in the IPv4 'protocol' and the IPv6 'Next + * Header' fields. + * The only supported values are 6 for TCP and 17 for UDP. + * @param port the port in host byte order to set the port binding for. + * Valid values range from 0 to 2^16-1. + * @param binding the binding to store in the cache. + */ +static void set_cache_entry(const uint8_t protocol, + const uint16_t port, + const enum hip_port_binding binding) +{ + // fail gracefully if the cache is not allocated + if (cache) { + // calculate index of cache entry + const unsigned int index = get_cache_index(protocol, port); + + // convert the port binding to the cache storage type + const uint8_t value = (uint8_t)binding; + + cache[index] = value; + } +} + +/** + * Retrieve port binding for a given protocol from the cache. + * + * Looking up the port binding from the /proc file systems is relatively + * expensive. + * Thus, we use this cache to speed up the lookup. + * + * This function is called before looking up the port binding from the /proc + * file system. + * + * @param protocol the protocol the specified port belongs to. + * The value is the same as used in the IPv4 'protocol' and the IPv6 'Next + * Header' fields. + * The only supported values are 6 for TCP and 17 for UDP. + * @param port the port in host byte order to set the port binding for. + * Valid values range from 0 to 2^16-1. + * @return If the port binding was previously stored, it is returned. + * If the port binding was not previously stored or the cache is not + * available, HIP_PORT_INFO_UNKNOWN is returned. + */ +static enum hip_port_binding get_cache_entry(const uint8_t protocol, + const uint16_t port) +{ + enum hip_port_binding binding = HIP_PORT_INFO_UNKNOWN; + + // fail gracefully if cache is not available + if (cache) { + const unsigned int index = get_cache_index(protocol, port); + + binding = (enum hip_port_binding)cache[index]; + } + + return binding; +} + +/** + * Invalidate all cache entries. + * + * After calling this function, all valid invocations of get_cache_entry() + * return HIP_PORT_INFO_UNKNOWN. + */ +static void invalidate_cache(void) +{ + if (cache) { + memset(cache, HIP_PORT_INFO_UNKNOWN, cache_size_bytes); + } +} + + + + + + +static struct hip_file_buffer tcp6_file; +static struct hip_file_buffer udp6_file; + +/** + * Handles ALRM signals and triggers caches to be reloaded. + * After this function has been called, the next call to + * hip_port_bindings_get() calls hip_port_bindings_reload() to invalidate the + * port and the file caches before performing a port lookup. + * This tries to strike a balance between the cost of + * hip_port_bindings_reload() and the freshness of the lookup information + * returned by hip_port_bindings_get(). + * This function is called every INVALIDATION_INTERVAL seconds. + */ +static void hip_port_bindings_trigger_reload(UNUSED const int sig) +{ + cache_invalidation_flag = 1; +} + +/** + * Load the latest information from /proc. + * This consists of handling two separate caching layers: + * a) re-reading the file contents in the tcp6/udp6 file buffer objects and + * b) invalidating the lookup cache. + * On the one hand, this operation should ideally be called for every call to + * hip_port_bindings_get() to retrieve up-to-date information from /proc + * about which ports are bound. + * On the other hand, this operation is about 300 times more expensive than + * parsing the /proc file and even more expensive compared to a cache lookup. + * hip_port_bindings_trigger_reload() tries to balance this conflict. + * After calling this function, the cache is empty and the file buffers contain + * the up-to-date file contents from /proc. + * + * @todo TODO efficiency could be increased by narrowing this down from + * reloading the files and invalidating the caches of all protocols to + * individual protocols. + * + * @return If this function completes successfully, it returns 0. + * If one of the proc files could not be reloaded from the file system, this + * function returns -1. + */ +static int hip_port_bindings_reload(void) +{ int err = 0; - HIP_DEBUG("\n"); - new_entry = (struct firewall_port_cache_hl *) (hip_cache_create_hl_entry()); - memcpy(new_entry->port_and_protocol, key, strlen(key)); - new_entry->traffic_type = value; - hip_ht_add(firewall_port_cache_db, new_entry); - - return err; + invalidate_cache(); + + err = hip_fb_reload(&tcp6_file); + err |= hip_fb_reload(&udp6_file); + + return (err == 0) ? 0 : -1; } /** - * Search in the port cache database. The key composed of port and protocol - * - * @param port the TCP or UDP port to search for - * @param proto the protocol (IPPROTO_UDP, IPPROTO_TCP or IPPROTO_ICMPV6) - * - * @return the cache entry if found or NULL otherwise + * Look up the port binding from the proc file system. + * + * @param protocol protocol type + * @param port the port number of the socket + * @return the traffic type associated with the given port. */ -struct firewall_port_cache_hl *hip_firewall_port_cache_db_match(in_port_t port, - int proto) +static enum hip_port_binding hip_port_bindings_get_from_proc(const uint8_t protocol, + const uint16_t port) { - struct firewall_port_cache_hl *found_entry = NULL; - char key[FIREWALL_PORT_CACHE_KEY_LENGTH]; - char protocol[10], proto_for_bind[10]; - int bindto = FIREWALL_PORT_CACHE_IPV4_TRAFFIC; //3 - default to ipv4, non-LSI traffic - - memset(protocol, 0, sizeof(protocol)); - memset(proto_for_bind, 0, sizeof(proto_for_bind)); - memset(key, 0, sizeof(key)); - - switch (proto) { + const unsigned int PORT_STR_OFFSET = 39; + const unsigned int PORT_STR_LEN = 4; + enum hip_port_binding result = HIP_PORT_INFO_IPV6UNBOUND; + const struct hip_mem_area *ma; + char *line; + // the files /proc/net/{udp,tcp}6 are line-based and the line number of the + // port to look up is not known in advance + // -> use a parser that lets us iterate over the lines in the files + struct hip_line_parser lp; + + switch (protocol) { + case IPPROTO_TCP: + ma = hip_fb_get_mem_area(&tcp6_file); + break; case IPPROTO_UDP: - strcpy(protocol, "udp"); - strcpy(proto_for_bind, "udp6"); - break; - case IPPROTO_TCP: - strcpy(protocol, "tcp"); - strcpy(proto_for_bind, "tcp6"); - break; - case IPPROTO_ICMPV6: - strcpy(protocol, "icmp"); - break; - default: - goto out_err; - break; - } - - //assemble the key - sprintf(key, "%i", (int) port); - memcpy(key + strlen(key), "_", 1); - memcpy(key + strlen(key), protocol, strlen(protocol)); - - found_entry = hip_ht_find(firewall_port_cache_db, key); - - if (proto == IPPROTO_ICMPV6) { - goto out_err; - } - - if (!found_entry) { - bindto = hip_get_proto_info(ntohs(port), proto_for_bind); - hip_port_cache_add_new_entry(key, bindto); - found_entry = hip_ht_find(firewall_port_cache_db, key); - } else { - HIP_DEBUG("Matched port using hash\n"); - } + ma = hip_fb_get_mem_area(&udp6_file); + break; + } + hip_lp_create(&lp, ma); + + // Note that here we blindly parse whatever is in the file buffer. + // This may not be up-to-date compared to the actual /proc file. + // We rely on someone else calling hip_port_bindings_reload() to + // reload the file contents for us so that we return some at least roughly + // up-to-date information. + line = hip_lp_first(&lp); + + // the first line only contains headers, no port information, skip it + line = hip_lp_next(&lp); + + // is the current line valid and is it long enough to hold a port binding? + while (line && ma->end > (line + PORT_STR_OFFSET + PORT_STR_LEN)) { + const unsigned int PORT_BASE_HEX = 16; + unsigned long proc_port = 0; + // note that strtoul() is about 10 times faster than sscanf(). + errno = 0; + proc_port = strtoul(line + PORT_STR_OFFSET, NULL, PORT_BASE_HEX); + if (0 == errno) { + if (proc_port == port) { + result = HIP_PORT_INFO_IPV6BOUND; + break; + } + } else { + HIP_ERROR("Unable to parse port number in line '%.*s' from /proc/net/%s6, errno = %d\n", + PORT_STR_OFFSET + PORT_STR_LEN, line, + IPPROTO_TCP == protocol ? "tcp" : "udp", errno); + } + line = hip_lp_next(&lp); + } + + hip_lp_delete(&lp); + return result; +} + +/** + * Initialize the port binding lookup and allocate any necessary resources. + * + * @param enable_cache if not 0, use an internal cache that is consulted on + * lookups in favor of parsing the /proc file. + * If this lookup cache is not enabled, every lookup results in parsing the + * proc file. + * Note however, that the /proc file itself is cached in memory and only + * reloaded at a certain interval. + * Within this interval, hip_port_bindings_get() might return a different + * port binding status than the one in the actual /proc file. + * @return 0 if the function completes successfully. + * If enable_cache is true but the cache could not be allocated or initialized + * this function returns -1. + * If one of the /proc files could not be opened or buffered in memory + * successfully, this function returns -2. + */ +int hip_port_bindings_init(const bool enable_cache) +{ + int err; + + // The cache is built such that it can be disabled just by not initializing + // it here. + if (enable_cache) { + HIP_IFEL(init_cache() != 0, -1, + "Initializing the port bindings cache failed\n") + } + + HIP_IFEL(hip_fb_create(&tcp6_file, "/proc/net/tcp6") != 0, -2, + "Buffering tcp6 proc file in memory failed\n"); + HIP_IFEL(hip_fb_create(&udp6_file, "/proc/net/udp6") != 0, -2, + "Buffering udp6 proc file in memory failed\n"); + + return 0; out_err: - return found_entry; -} - -/** - * Generate the hash information that is used to index the table - * - * @param ptr pointer to the hit used to assemble the hash - * - * @return hash value - */ -static unsigned long hip_firewall_port_hash_key(const void *ptr) -{ - const char *key; - uint8_t hash[HIP_AH_SHA_LEN]; - - key = (const char *) - &((const struct firewall_port_cache_hl *) ptr)->port_and_protocol; - hip_build_digest(HIP_DIGEST_SHA1, key, sizeof(*key), hash); - return *((unsigned long *) hash); -} - -/** - * Compare two keys for the hashtable - * - * Note that when this function is called, the hashes of the two hash table - * entries provided as arguments are known to be equal. - * The point of this function is to allow the hash table to determine whether - * the entries (or rather the part used to calculate the hash) themselves are - * equal or whether they are different and this is just a hash collision. - * - * @param ptr1 pointer to the first key - * @param ptr2 pointer to the second key - * - * @return 0 if keys identical, otherwise != 0 - */ -static int hip_firewall_match_port_cache_key(const void *ptr1, const void *ptr2) -{ - return strncmp((const char *)ptr1, (const char *)ptr2, FIREWALL_PORT_CACHE_KEY_LENGTH); -} - -/** - * Initialize port cache database - * - */ -void hip_firewall_port_cache_init_hldb(void) -{ - firewall_port_cache_db = hip_ht_init(hip_firewall_port_hash_key, - hip_firewall_match_port_cache_key); -} - -/** - * Initialize port cache database - * - */ -void hip_firewall_port_cache_uninit_hldb(void) -{ - int i; - struct firewall_port_cache_hl *this = NULL; - hip_list_t *item = NULL; - hip_list_t *tmp = NULL; - - HIP_DEBUG("Start hldb delete\n"); - HIP_LOCK_HT(&firewall_port_cache_db); - - list_for_each_safe(item, tmp, firewall_port_cache_db, i) - { - HIP_DEBUG("xx\n"); - this = (struct firewall_port_cache_hl *) list_entry(item); - hip_ht_delete(firewall_port_cache_db, this); - free(this); - HIP_DEBUG("yy\n"); + hip_port_bindings_uninit(); + return err; +} + +/** + * Release any resources allocated for port binding lookups. + */ +void hip_port_bindings_uninit(void) +{ + hip_fb_delete(&tcp6_file); + hip_fb_delete(&udp6_file); + + uninit_cache(); +} + +/** + * Determine whether the given port is bound under the given protocol to an + * IPv6 address on the local host. + * + * For example, on a system with a running IPv6-capable web server, this + * function returns HIP_PORT_INFO_IPV6BOUND. + * If there is no web server or it only supports (or binds to) IPv4 addresses, + * this function returns HIP_PORT_INFO_IPV6UNBOUND. + * + * Note that due to internal caching, hip_port_bindings_get() might return for + * a certain caching interval a different port binding status than the one + * reported in the actual /proc file (see hip_port_bindings_trigger_reload()). + * + * The binary test/fw_port_bindings_performance benchmarks the elements that + * influence the performance of the hip_port_bindings_* code. + * Please have a look at the numbers it generates when changing this code under + * performance aspects. + * + * @param protocol the protocol to check the port binding for. + * The values are equivalent to those found in the 'Protocol' field of the + * IPv4 header and the 'Next Header' field of the IPv6 header. + * The only supported values are those for TCP (6) and UDP (17). + * @param port the port to look up. + * The value is expected in network byte order, as it is found in protocol + * headers. + * @return HIP_PORT_INFO_IPV6BOUND if the given port is bound under the given + * protocol to an IPv6 address. + * HIP_PORT_INFO_IPV6UNBOUND if it is not. + */ +enum hip_port_binding hip_port_bindings_get(const uint8_t protocol, + const in_port_t port) +{ + enum hip_port_binding binding = HIP_PORT_INFO_IPV6UNBOUND; + + // check input parameters + if (IPPROTO_TCP == protocol || + IPPROTO_UDP == protocol) { + const uint16_t port_hbo = ntohs(port); + + // Make sure we return (sort of) up-to-date information. + // This is the one potentially slow operation here. + // The others (hip_port_bindings_get_from_proc() and the cache access + // functions) are (intended to be) very fast. + if (cache_invalidation_flag) { + // prevent further cache invalidation + cache_invalidation_flag = 0; + // invalidate all caches and reload the /proc-file contents + hip_port_bindings_reload(); + // start a timer that sets cache_invalidation_flag back to 1 + signal(SIGALRM, hip_port_bindings_trigger_reload); + alarm(INVALIDATION_INTERVAL); + } + + // check the cache before checking /proc + // note that the cache might be switched off (see + // hip_port_bindings_init()) or was just invalidated by + // hip_port_bindings_reload() + binding = get_cache_entry(protocol, port_hbo); + + if (HIP_PORT_INFO_UNKNOWN == binding) { + binding = hip_port_bindings_get_from_proc(protocol, port_hbo); + set_cache_entry(protocol, port_hbo, binding); + } + } else { + HIP_ERROR("Protocol %d not supported\n", protocol); } - HIP_UNLOCK_HT(&firewall_port_cache_db); - hip_ht_uninit(firewall_port_cache_db); - HIP_DEBUG("End hldbdb delete\n"); + + // check return value + HIP_ASSERT(HIP_PORT_INFO_IPV6UNBOUND == binding || + HIP_PORT_INFO_IPV6BOUND == binding); + + return binding; } === renamed file 'firewall/cache_port.h' => 'firewall/port_bindings.h' --- firewall/cache_port.h 2010-10-15 15:29:14 +0000 +++ firewall/port_bindings.h 2010-11-12 17:49:42 +0000 @@ -23,16 +23,51 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef HIP_FIREWALL_CACHE_PORT_H -#define HIP_FIREWALL_CACHE_PORT_H +/** + * @file + * The port binding says whether a port is locally bound to an IPv6 + * application or not. + * This allows the firewall to determine whether an incoming HIT-based packet + * is meant to go to a local IPv6 port or not. + * If not, the packet needs to be converted to IPv4 and sent to an LSI. + * More details can be found in <a + * href="http://hipl.hiit.fi/hipl/thesis_teresa_finez.pdf";>T. Finez, + * Backwards Compatibility Experimentation with Host Identity Protocol + * and Legacy Software and Networks , final project, December 2008</a>. + * + * @author Miika Komu <miika@xxxxxx>, Stefan Goetz <stefan.goetz@xxxxxxxxxxxxxxxxx> + */ + +#ifndef HIP_FIREWALL_PORT_BINDINGS_H +#define HIP_FIREWALL_PORT_BINDINGS_H #include <netinet/in.h> - -#include "lib/core/icomm.h" - -void hip_firewall_port_cache_init_hldb(void); -struct firewall_port_cache_hl *hip_firewall_port_cache_db_match(in_port_t port, - int proto); -void hip_firewall_port_cache_uninit_hldb(void); - -#endif /* HIP_CACHE_H */ +#include <stdbool.h> + +/** + * The binding state of a particular TCP or UDP port under IPv6 on the local + * host. + */ +enum hip_port_binding { + /** + * It is not known which network protocol the port is bound under. + */ + HIP_PORT_INFO_UNKNOWN = 0, + /** + * The port is not bound to an IPv6 address (but potentially to an + * IPv4 address). + */ + HIP_PORT_INFO_IPV6UNBOUND, + /** + * The port is bound to an IPv6 address (and potentially to an IPv4 + * address) + */ + HIP_PORT_INFO_IPV6BOUND, +}; + +int hip_port_bindings_init(const bool enable_cache); +void hip_port_bindings_uninit(void); +enum hip_port_binding hip_port_bindings_get(const uint8_t proto, + const in_port_t port); + +#endif /* HIP_FIREWALL_PORT_BINDINGS_H */ === modified file 'hipd/esp_prot_light_update.h' --- hipd/esp_prot_light_update.h 2010-10-20 16:11:23 +0000 +++ hipd/esp_prot_light_update.h 2010-11-15 17:08:02 +0000 @@ -36,8 +36,8 @@ #ifndef HIP_HIPD_ESP_PROT_LIGHT_UPDATE_H #define HIP_HIPD_ESP_PROT_LIGHT_UPDATE_H -#include "lib/core/lmod.h" #include "lib/core/protodefs.h" +#include "lib/core/modularization.h" int esp_prot_send_light_update(hip_ha_t *entry, const int anchor_offset[], === modified file 'hipd/hiprelay.c' --- hipd/hiprelay.c 2010-10-20 03:38:26 +0000 +++ hipd/hiprelay.c 2010-11-15 13:39:24 +0000 @@ -69,7 +69,7 @@ * * <pre> * hip_relrec_t dummy, *fetch_record = NULL; - * memcpy((char *)&(dummy.hit_r), hit, sizeof(hit)); + * memcpy(&dummy.hit_r, hit, sizeof(hit)); * fetch_record = hip_relht_get(&dummy); * if (fetch_record != NULL) { * // Do something with the record. @@ -79,7 +79,7 @@ * <li>Deleting a relay record. A dummy record can be used: * <pre> * hip_relrec_t dummy; - * memcpy((char *) &(dummy.hit_r), hit, sizeof(hit)); + * memcpy(&dummy.hit_r, hit, sizeof(hit)); * hip_relht_rec_free(&dummy); * </pre> * </li> === modified file 'hipd/init.c' --- hipd/init.c 2010-11-09 13:04:44 +0000 +++ hipd/init.c 2010-11-15 17:08:02 +0000 @@ -62,7 +62,6 @@ #include "lib/core/hostsfiles.h" #include "lib/core/ife.h" #include "lib/tool/nlink.h" -#include "lib/core/lmod.h" #include "lib/core/performance.h" #include "lib/core/straddr.h" #include "lib/tool/xfrmapi.h" === modified file 'hipd/maintenance.c' --- hipd/maintenance.c 2010-10-20 16:11:23 +0000 +++ hipd/maintenance.c 2010-11-15 17:08:02 +0000 @@ -49,8 +49,8 @@ #include "lib/core/hip_udp.h" #include "lib/core/ife.h" #include "lib/core/linkedlist.h" -#include "lib/core/lmod.h" #include "lib/core/protodefs.h" +#include "lib/core/modularization.h" #include "config.h" #include "accessor.h" #include "close.h" === modified file 'hipd/pkt_handling.c' --- hipd/pkt_handling.c 2010-10-20 16:11:23 +0000 +++ hipd/pkt_handling.c 2010-11-15 17:08:02 +0000 @@ -34,9 +34,9 @@ #include "lib/core/ife.h" #include "lib/core/linkedlist.h" -#include "lib/core/lmod.h" #include "lib/core/protodefs.h" #include "lib/core/state.h" +#include "lib/core/modularization.h" #include "pkt_handling.h" === modified file 'hipd/registration.c' --- hipd/registration.c 2010-10-27 11:11:20 +0000 +++ hipd/registration.c 2010-11-15 12:40:48 +0000 @@ -522,10 +522,8 @@ if (new_record != NULL) { free(new_record); } - refused_requests[*refused_count] = - reg_types[i]; - failure_types[*refused_count] = - HIP_REG_TRANSIENT_CONDITIONS; + refused_requests[*refused_count] = reg_types[i]; + failure_types[*refused_count] = HIP_REG_TRANSIENT_CONDITIONS; (*refused_count)++; HIP_ERROR("Unable to store new relay " \ "record. Registration " \ === modified file 'hipd/user.c' --- hipd/user.c 2010-10-20 16:11:23 +0000 +++ hipd/user.c 2010-11-15 17:08:02 +0000 @@ -65,9 +65,9 @@ #include "lib/core/icomm.h" #include "lib/core/ife.h" #include "lib/core/linkedlist.h" -#include "lib/core/lmod.h" #include "lib/core/prefix.h" #include "lib/core/protodefs.h" +#include "lib/core/modularization.h" #include "lib/tool/nlink.h" #include "config.h" #include "accessor.h" === modified file 'lib/core/builder.c' --- lib/core/builder.c 2010-10-18 20:24:43 +0000 +++ lib/core/builder.c 2010-11-15 12:40:48 +0000 @@ -3757,7 +3757,7 @@ hostname, dsa_key_rr); - out_err: +out_err: if (dsa_key_rr) { free(dsa_key_rr); @@ -3815,7 +3815,7 @@ hostname, rsa_key_rr); - out_err: +out_err: if (rsa_key_rr) { free(rsa_key_rr); === modified file 'lib/core/debug.h' --- lib/core/debug.h 2010-10-15 15:29:14 +0000 +++ lib/core/debug.h 2010-11-12 15:50:17 +0000 @@ -261,11 +261,6 @@ #define HIP_DEBUG_GL(debug_group, debug_level, ...) do {} while (0) #endif -#ifdef CONFIG_HIP_DEMO -#define HIP_DEMO(...) printf(__VA_ARGS__); -#else -#define HIP_DEMO(...) do {} while (0) -#endif /* @} */ /* Debug groups define groups of debug messages which belong to the === modified file 'lib/core/hashchain_store.c' --- lib/core/hashchain_store.c 2010-10-18 17:44:31 +0000 +++ lib/core/hashchain_store.c 2010-11-15 13:38:47 +0000 @@ -48,7 +48,7 @@ */ static void hcstore_free_hchain(void *hchain) { - hchain_free((hash_chain_t *) hchain); + hchain_free(hchain); } /** helper function to free a hash tree @@ -57,7 +57,7 @@ */ static void hcstore_free_htree(void *htree) { - htree_free((hash_tree_t *) htree); + htree_free(htree); } /** initializes a new hash item store === modified file 'lib/core/icomm.h' --- lib/core/icomm.h 2010-10-15 15:29:14 +0000 +++ lib/core/icomm.h 2010-10-15 22:56:42 +0000 @@ -197,18 +197,4 @@ #define FLUSH_HA_INFO_DB 1 - -/****** FIREWALL ******/ - -/*----Firewall cache----*/ -/*Values for the port cache of the firewall*/ -#define FIREWALL_PORT_CACHE_IPV6_TRAFFIC 1 -#define FIREWALL_PORT_CACHE_IPV4_TRAFFIC 3 -#define FIREWALL_PORT_CACHE_KEY_LENGTH 20 - -struct firewall_port_cache_hl { - char port_and_protocol[FIREWALL_PORT_CACHE_KEY_LENGTH]; //key - int traffic_type; //value -}; - #endif /* HIP_LIB_CORE_ICOMM_H */ === renamed file 'lib/core/lmod.c' => 'lib/core/modularization.c' --- lib/core/lmod.c 2010-11-09 14:18:47 +0000 +++ lib/core/modularization.c 2010-11-15 17:08:02 +0000 @@ -25,7 +25,7 @@ /** * @file - * @brief The main source file for libmodularization (lmod). + * @brief Allow modularized features that can be enabled as required. * * @author Tim Just <tim.just@xxxxxxxxxxxxxx> */ @@ -34,8 +34,8 @@ #include <stdlib.h> #include <string.h> +#include "modularization.h" #include "modules/modules.h" -#include "lmod.h" #include "debug.h" #include "ife.h" @@ -492,9 +492,9 @@ */ static void lmod_free_packet_entry(void *entry) { - struct packet_type *packte_type_entry = entry; - free(packte_type_entry->identifier); - free(packte_type_entry); + struct packet_type *packet_type_entry = entry; + free(packet_type_entry->identifier); + free(packet_type_entry); } /** === renamed file 'lib/core/lmod.h' => 'lib/core/modularization.h' --- lib/core/lmod.h 2010-10-20 16:11:23 +0000 +++ lib/core/modularization.h 2010-11-15 17:08:02 +0000 @@ -27,8 +27,9 @@ * @file * @author Tim Just <tim.just@xxxxxxxxxxxxxx> */ -#ifndef HIP_LIB_CORE_LMOD_H -#define HIP_LIB_CORE_LMOD_H + +#ifndef HIP_LIB_CORE_MODULARIZATION_H +#define HIP_LIB_CORE_MODULARIZATION_H #include <stdint.h> @@ -75,4 +76,4 @@ int hip_lmod_load_modules(const struct module_info *const modules, const unsigned int size); -#endif /* HIP_LIB_CORE_LMOD_H */ +#endif /* HIP_LIB_CORE_MODULARIZATION_H */ === modified file 'lib/core/options.c' --- lib/core/options.c 2010-11-09 13:36:03 +0000 +++ lib/core/options.c 2010-11-15 17:08:02 +0000 @@ -54,9 +54,9 @@ #include <stdlib.h> #include <string.h> -#include "lmod.h" #include "common.h" #include "options.h" +#include "modularization.h" #include "modules/modules.h" #include "lib/core/linkedlist.h" === modified file 'lib/core/prefix.c' --- lib/core/prefix.c 2010-10-18 17:44:31 +0000 +++ lib/core/prefix.c 2010-11-15 13:39:24 +0000 @@ -383,24 +383,22 @@ int ipv4_addr_cmp(const struct in_addr *a1, const struct in_addr *a2) { - return memcmp((const char *) a1, (const char *) a2, - sizeof(struct in_addr)); + return memcmp(a1, a2, sizeof(struct in_addr)); } void ipv4_addr_copy(struct in_addr *a1, const struct in_addr *a2) { - memcpy((char *) a1, (const char *) a2, sizeof(struct in_addr)); + memcpy(a1, a2, sizeof(struct in_addr)); } int ipv6_addr_cmp(const struct in6_addr *a1, const struct in6_addr *a2) { - return memcmp((const char *) a1, (const char *) a2, - sizeof(struct in6_addr)); + return memcmp(a1, a2, sizeof(struct in6_addr)); } void ipv6_addr_copy(struct in6_addr *a1, const struct in6_addr *a2) { - memcpy((char *) a1, (const char *) a2, sizeof(struct in6_addr)); + memcpy(a1, a2, sizeof(struct in6_addr)); } int ipv6_addr_any(const struct in6_addr *a) { === modified file 'lib/core/state.h' --- lib/core/state.h 2010-10-20 16:11:23 +0000 +++ lib/core/state.h 2010-11-15 17:08:02 +0000 @@ -40,7 +40,7 @@ #include "hipd/cookie.h" #include "config.h" #include "hashtable.h" -#include "lmod.h" +#include "modularization.h" #include "protodefs.h" #include "statistics.h" === removed directory 'lib/modularization' === modified file 'lib/tool/pk.c' --- lib/tool/pk.c 2010-08-19 09:32:20 +0000 +++ lib/tool/pk.c 2010-11-15 13:38:47 +0000 @@ -41,7 +41,7 @@ */ int hip_rsa_sign(void *priv_key, struct hip_common *msg) { - RSA *rsa = (RSA *) priv_key; + RSA *rsa = priv_key; uint8_t sha1_digest[HIP_AH_SHA_LEN]; uint8_t *signature = NULL; int err = 0, len; === modified file 'modules/heartbeat/hipd/heartbeat.c' --- modules/heartbeat/hipd/heartbeat.c 2010-10-20 00:28:19 +0000 +++ modules/heartbeat/hipd/heartbeat.c 2010-11-15 17:08:02 +0000 @@ -81,11 +81,11 @@ #include "lib/core/debug.h" #include "lib/core/icomm.h" #include "lib/core/ife.h" -#include "lib/core/lmod.h" #include "lib/core/prefix.h" #include "lib/core/protodefs.h" #include "lib/core/statistics.h" #include "lib/core/straddr.h" +#include "lib/core/modularization.h" #include "lib/tool/nlink.h" #include "heartbeat.h" === modified file 'modules/update/hipd/update.c' --- modules/update/hipd/update.c 2010-10-20 00:28:19 +0000 +++ modules/update/hipd/update.c 2010-11-15 17:08:02 +0000 @@ -56,12 +56,12 @@ #include "lib/core/hashtable.h" #include "lib/core/hip_udp.h" #include "lib/core/ife.h" -#include "lib/core/lmod.h" #include "lib/core/list.h" #include "lib/core/performance.h" #include "lib/core/prefix.h" #include "lib/core/protodefs.h" #include "lib/core/solve.h" +#include "lib/core/modularization.h" #include "update_legacy.h" #include "update.h" === modified file 'packaging/openwrt/package/Makefile' --- packaging/openwrt/package/Makefile 2010-10-29 11:31:40 +0000 +++ packaging/openwrt/package/Makefile 2010-11-12 16:31:19 +0000 @@ -97,7 +97,6 @@ $(INSTALL_DATA) ./files/hipl.modules $(1)/etc/modules.d/35-hipl $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libhipcore.so* $(1)/usr/lib/ - $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libmod.so* $(1)/usr/lib/ $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libhipheartbeat.so* $(1)/usr/lib/ $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libhiphbupdate.so* $(1)/usr/lib/ $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libhipupdate.so* $(1)/usr/lib/ === added file 'test/check_firewall.c' --- test/check_firewall.c 1970-01-01 00:00:00 +0000 +++ test/check_firewall.c 2010-11-12 17:49:42 +0000 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2010 Aalto University and RWTH Aachen University. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <check.h> +#include <stdlib.h> + +/* Import test suite functions from their respective C files via forward + * declarations. + * Since each test C file exports only one such function which is only used + * right here, a dedicated header file for each of them adds unnecessary file + * clutter in this particular case of unit tests. + * Do not adopt this HFAS (header-file-avoidance-scheme) (TM) in HIPL production + * code as header files are generally a good idea, just not here. */ +extern Suite *firewall_file_buffer(void); +extern Suite *firewall_line_parser(void); +extern Suite *firewall_port_bindings(void); + +int main(void) +{ + int number_failed; + SRunner *sr = srunner_create(firewall_file_buffer()); + srunner_add_suite(sr, firewall_line_parser()); + srunner_add_suite(sr, firewall_port_bindings()); + + srunner_run_all(sr, CK_NORMAL); + number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} === added directory 'test/firewall' === added file 'test/firewall/file_buffer.c' --- test/firewall/file_buffer.c 1970-01-01 00:00:00 +0000 +++ test/firewall/file_buffer.c 2010-11-12 17:49:42 +0000 @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2010 Aalto University and RWTH Aachen University. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <assert.h> +#include <check.h> +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#include "firewall/file_buffer.h" +#include "firewall/file_buffer.c" + +// these tests do not clean up after themselves because they assume that +// check runs them in dedicated processes so the OS does the cleanup + +START_TEST(test_hip_fb_create_valid) +{ + struct hip_file_buffer fb; + + fail_unless(hip_fb_create(&fb, "/etc/fstab") == 0, + "Opening the file '/etc/fstab' failed - does it exist?"); +} +END_TEST + +START_TEST(test_hip_fb_create_null_buffer) +{ + fail_unless(hip_fb_create(NULL, "/etc/fstab") == -1, NULL); +} +END_TEST + +START_TEST(test_hip_fb_create_null_file_name) +{ + struct hip_file_buffer fb; + + fail_unless(hip_fb_create(&fb, NULL) == -1, NULL); +} +END_TEST + +START_TEST(test_hip_fb_create_missing_file) +{ + struct hip_file_buffer fb; + + fail_unless(hip_fb_create(&fb, + "XhUp8vH5sbye3izn25XbY3EVu9VcAsNC42WOCVYxAkMXiFo7cuh4Zsp2jHgfJ2OsBUTamYDuSyB9oSuAYEfBJA6EaEXBpNCp2l88Zo2yaWaLw6pB5mh61dlBDQZjaqlS") == -2, + NULL); +} +END_TEST + +START_TEST(test_hip_fb_create_check_file_integrity) +{ + struct hip_file_buffer fb; + const struct hip_mem_area *ma = NULL; + int fd = -1; + const char FILE_NAME_PATTERN[] = "XXXXXX"; + char file_name[sizeof(FILE_NAME_PATTERN)]; + const char file_contents[] = "yfuCedywwPTVUJ0ego5HPQ34hCJgaDAElU3qDTniiRme0bdmjpo1YId9PX9Kkffsi1HOzzwBvnGikMuxJ5bSv8xRSUmBLsv31tfmvdcUDkTzzjoJErKCxnTRsccJdJYc4Y3o7P2dDkHFAokEY5lz79dEbUmfpKmdWuEx4Ory17tDoe2S30l1yhlDUnHF3Hg6FLELMymJDMDologVjohganwYN6j0p9zJfnOwm9pPzzqoEsNoNALA3XwNBG40jMOBb9KaulcHCS56fieRsakxmSUw9T5iM3T5Bn37FhBnMDfEu1AJ3SkTwNw2vrcCDYpN3zl2isC3lTfkRnMDmrTkBfwx9MZuxaPI8jqebZfXrFvl6Oc8TFdaLlUARshG0Ci0UUEa5QiwbCOKjcC1tc2IztYzGpOghvv4rBA7B5B7TGH4VJZJXekRx46xlnEvlw5qKzfDAKeFmeM0L5ym9zRzXmv9HYOD8krkLD2ubMQnaLL6d3LU0qI9NaQsi2PM2A1FIswVlQ5EtGpjf7l35pWsCEE08r7efzBjtYAtvytyzFmxI7mGd4pf9xWlmJJ8OFM6PAEwvSnJN0jEJIxaRZUMH93DfHGW3w2sQpFu3FyHzfzweQma2wf1dD7BjHYHJTXb3gsYqaNG8yweoJQ4RUtAMiEkal6HxzRgQYb87g7ESzuKCp1XjDXh3k0Rtsezjrd957rHO2F2xttHSP3GqBhsdTzTVgVEdPLiFj7G3iBol7t0I3QGbEcX2AkxoCkQGV1cRfRvxeuctnGpDczBM0gHjTcHScqhBfOpCmAzhFa9NNc0GNiihL37DJ3mgzwAw7qh49zbtgP0YqRWUNkHJgukisldvCFiHucXaRWc21AvdyIpYmIRN4gKfhPfBEKCdrX6Ykjxxq5lqnnitL00Ib3Am8gOaChB8r8FffiZ91PUvN5vMSZIc32fVQpAFw296GcXJZbVraJh4sHAONFMpNtoYj56YWDcKOwAHXiCFd58jlqHftot44DKk4dOSrORFeAUfu58zpbxoUu2LmqtORlp3AjRh5cHv1bjzpE6dRE09ksNTdrvdxyD2zdN4755gIGeIqMzO11gnwRQ6y19lFc9RI5TmFcEyVHpgKWvUEUAKqOMHc1Er6X8fX22awM1Ex7IF5DHpVTVPBGX4m6NUWu9JmUz2oEBOpU1ik5rXfp7aea1wwz1KS3IwdEHf4VMFVA2CAQ9cS3jrBYVb6Rm18uhDTAyAv9l0ZgBHR6c5s2Rnh6THT7WAGJ8Scf95OKQVNk8WEEagM5th09E07Cd4RYtck52alL7VfWSpaBgPgrDgSnjRf4419Qvbkbvbl0GnSNyXUPRR63eS9ZzWtq2gn0HnAz8mJoBMSgU6Lky5hoEgloDM1cpJgcxtFqLYsS2BII94BkDtb8tPUyOwGT6KfLOHy77Mx61eBHkLEM3dIjpOdwTA2YNZ5wK6vpUtUVsadoFKYMMQvnFFhc7kzilSNZPs5nvM6VzyUtrAP2FQvHCl1A6fHP9clmeWTEYqqYZO1D8LUKlhUCv2TYuqkSekP8pjmv4NYXA5IvWsbSigxyWpa15AmFg0f1GajKen6zHE9Yj88VW1GRAAjtohVsC1XrHRLfuRn1FDjxlMVZR2eRI9TTuWPy2sT93TyfsBwZNhdJ36d5CCj9aAdI1L2UI7qCunqVnC5ALnUTejRR8vJNswDOzU6sdI1op6sUSSUAtUshsoFANcvC6bLMGZyick4ckzrepnAGYWWutyqg7dJXwmsGJYCummuk6ppEixnWYs2N7IeaK0O0NXa4GXOgz4mGdUsDYD0kDsmNHjsHgzXDpLGoe76dQdfGZLbgaKWj0t2XaoMHEjTtPn4b4YAYD2XkOPh47s53EoIBUqBW7fmmPFwaEKO7voSGWJS20H9Ojjy0YQvSi5UiBMItJt8XwaH8a3QZSvp1XwwF0eUdjFWLmYN4UU9DM9hiDBfQwbuu6n5TDS9a9wpTDCwDJmOYwi04rGIUw9pKNHyCiZljZXe4cG35tduR6cISrEIEmYE3XU33LtvkMgDE4JaShmPIWEwMl4ahqIKFq42pLYEByRSWsEhw348VlUkN23Xjxi7q0TR0NWYIbWLa1NWlq4iu3J1j6DmtyqXrYKwMhhCnT7RVSZvoZi6pPyIsKSyC9cmd5aciPoPbHjXgUZTSBperj4JGPvRkwZuga6jh5yPdq5e2AEKEFarK9JcE7ohY29m411j7U9QpMzjkOocmTG2vKD077hRjdX4mmbK4Rj4fTWAVzjor2E9mYcjHIPjLPTzhmmawvIQ5sSH3ESezGm0FGqmnD5LNdIl94dlYQKVWKrjbi7QfJieOOOrXm0tNtNvRghx4DM4j988x1WSB8ppRb9M0KB4HHeEd5vvuEd8ERk3Tz6MvktPPlNvQIbwlE9GXFd46Id5ysCCHw9Qrplaf4CPul2jvuRkEMqYZZ6IZ9qiniJNDNHDcDejRafCKb0r8fDv7lUmyqCaxgKa4XqPYHqg2227wZQ8dM3FBUGPuJUyRnkuGxq5K9s56IPETosvzcEVGMhmlGFHoG4fBZBJxX32h0x0P5fksKM0mx8bN2ncezrFSQZMg1NbqMTWGCoVnA1tcvLQJtAXznlTBoeg5pYLhrS7ImK52pjEZNygJDjndeXHfTtJmZpinYnMnImkuw2yFHzC2erq43fMZVBofE3mjekzyekXRV4RhdxRFQeMAVmCKcbfL3Xo8sthxHFAQaPPmMUgWtNuRlb3SVjkZXWfIPTqBodsDL1AbS80fF91oDNCKUEZCEg0jFceiku3y63AIh3mCvgrpr2uF26t37ayx8aD9l2fzhS7gJniCl4qP4DgD7LtJBVVym4IwatvGM4hv3xaBOhjj8MOrA4cKUUh1BGEIIFE2Zs54TGlPAMt5zmOQlSWqrtqYPPpKBTaBlNOGmzu4CnQTUnHwK6OxczFFPPhBc3jXvSgn3RSzwjhlbf8nCaLHumKylknCKwitVNBNXhFCwGKU1nTNENt601AelsaplzbtjrI8j0sM3xGrsHiG8tM9Nf7lJDRbFlIKqXRcWAzhdD90em4swjzYCstTMOHFu9yh1M2Pj2BNuu9BIkkMb0n0NijwKWaggRNjTk98FsOeZpFrpPxuPSyeR8b2lW52Pik7r6BroNuTz6SvOyB7x2h5hHYLs7JATMlyZarWTWryPMJpd8217JuFDS6cJO1A1knzS3JKpM5C9UM2JGcZ5c3eR9ZXFmE1GbJSgNnPnzjHaXpbWXqglWM9OpIXIP9HQd75yk0jVa9b9HM3zvVtNKKtyNEpjS3MJYWvVhrzgNp1XL2qksEgAUUIcWEmUCOaT3PIt6SZVlOI8Ygj15IdzJgkwSCLZU8YeVmRxW0xRIti6AZbmtYOxoBFo0yVf7IyeexFtSkRc781FRwm3cihqPcNvcy0Hm4FINfzrzocbLA5TbOr3zIl3eNBKbQa2vxziGLOdyRlH33P3fyHADcpzzxciQ0xqcNGJyIzZu0GqqOwdp3nkjld6PV6FZHHS6zgYBHlTJNXntTAY51XRNVzWecyo2jMiVx4E94LeuerxTzl78Vtz2pC1McnsS8IRWkJ80VyHudAGxbh6U630iMnzKwdWTwzco2RJCoIqFIQRerolJtXIPlZxE4CchHG6r09MXIWAnSUjq3UvdfBp0NLgqln727sDcFKjQ4vmLfWrW6CyJLXs3p40yi5VId6JW3jUwu7o6DhotLW5WXjIJks2lLuAETYxgG2kEhxcCPBkry6UvfNnWarPhauNrQmS5hrCodMTnhhshmIJLx7NZWaKMw77sfxnM5pzdeJzwu81YEGEPVpW4qgovGXnMq7Qx7UrNceDSCiizL0XAORmKj4yQbq9AW35gf5VgZIuCwUdkG6FJqlipss1DBh8HfbxtWCfiGiPzb3P7Ua2oGLXpFWgXZucfVGffr93DjouvVYqste1kBLvxuoAJHVqAC0auC9cheh717MKUQkGUavqu7sNAWvKv0AhBddxzwkPIXBRYW6uoyhS7YY5tSoNYW9jFYAMfm9k53jzqyS8fZ3dhh8Qkf7PLXlhEqZ7R276Psdd"; + size_t bytes_written = 0; + + strncpy(file_name, FILE_NAME_PATTERN, sizeof(file_name)); + + // create a file and write well-known data into it + fd = mkstemp(file_name); + assert(fd != -1); + bytes_written = write(fd, file_contents, sizeof(file_contents)); + assert(sizeof(file_contents) == bytes_written); + close(fd); + + fail_unless(hip_fb_create(&fb, file_name) == 0, NULL); + fail_unless((ma = hip_fb_get_mem_area(&fb)) != NULL, NULL); + fail_unless((ma->end - ma->start) == sizeof(file_contents)); + fail_unless(memcmp(ma->start, file_contents, sizeof(file_contents)) == 0, + NULL); + + fd = open(file_name, O_RDWR | O_APPEND); + assert(fd != -1); + bytes_written = write(fd, file_contents, sizeof(file_contents)); + assert(sizeof(file_contents) == bytes_written); + close(fd); + + fail_unless(hip_fb_reload(&fb) == 0, NULL); + fail_unless(ma == hip_fb_get_mem_area(&fb), NULL); + fail_unless((ma->end - ma->start) == sizeof(file_contents) * 2); + fail_unless(memcmp(ma->start, file_contents, sizeof(file_contents)) == 0, + NULL); + fail_unless(memcmp(ma->start + sizeof(file_contents), file_contents, + sizeof(file_contents)) == 0, NULL); + + remove(file_name); +} +END_TEST + +START_TEST(test_hip_fb_delete_valid) +{ + struct hip_file_buffer fb; + int err = 0; + + err = hip_fb_create(&fb, "/etc/fstab"); + assert(0 == err); + hip_fb_delete(&fb); +} +END_TEST + +START_TEST(test_hip_fb_delete_null_fb) +{ + hip_fb_delete(NULL); +} +END_TEST + +START_TEST(test_hip_fb_reload_null_fb) +{ + fail_unless(hip_fb_reload(NULL) == -1, NULL); +} +END_TEST + +// For unknown reasons, this file does not compile without the following, +// seemingly useless forward declaration +Suite *firewall_file_buffer(void); + +Suite *firewall_file_buffer(void) +{ + Suite *s = suite_create("firewall/file_buffer"); + + TCase *tc_core = tcase_create("Core"); + tcase_add_test(tc_core, test_hip_fb_create_valid); + tcase_add_test(tc_core, test_hip_fb_create_null_buffer); + tcase_add_test(tc_core, test_hip_fb_create_null_file_name); + tcase_add_test(tc_core, test_hip_fb_create_missing_file); + tcase_add_test(tc_core, test_hip_fb_create_check_file_integrity); + tcase_add_test(tc_core, test_hip_fb_delete_valid); + tcase_add_test(tc_core, test_hip_fb_delete_null_fb); + tcase_add_test(tc_core, test_hip_fb_reload_null_fb); + suite_add_tcase(s, tc_core); + + return s; +} === added file 'test/firewall/line_parser.c' --- test/firewall/line_parser.c 1970-01-01 00:00:00 +0000 +++ test/firewall/line_parser.c 2010-11-12 17:49:42 +0000 @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2010 Aalto University and RWTH Aachen University. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <assert.h> +#include <check.h> + +#include "firewall/line_parser.h" +#include "firewall/line_parser.c" + +// four lines, each 50 characters long (including \n) +char data[] = "I'm not knocking your want to carry that home \n\ +Took it with you when you moved and got it broke \n\ +Found the pieces we counted them all alone \n\ +Didn't add up forgot to carry a zero "; +// four pointers to the beginning of the lines +char *const lines[4] = { + data, + data + 50, + data + 100, + data + 150 +}; +// the memory area describing data +const struct hip_mem_area ma = { data, data + sizeof(data) }; + +// these tests do not clean up after themselves because they assume that +// check runs them in dedicated processes so the OS does the cleanup +START_TEST(test_hip_lp_create_valid) +{ + struct hip_line_parser lp; + + fail_unless(hip_lp_create(&lp, &ma) == 0, NULL); +} +END_TEST + +START_TEST(test_hip_lp_create_null_lp) +{ + fail_unless(hip_lp_create(NULL, &ma) == -1, NULL); +} +END_TEST + +START_TEST(test_hip_lp_create_null_ma) +{ + struct hip_line_parser lp; + + fail_unless(hip_lp_create(&lp, NULL) == -1, NULL); +} +END_TEST + +START_TEST(test_hip_lp_delete_valid) +{ + struct hip_line_parser lp; + int err = 0; + + err = hip_lp_create(&lp, &ma); + assert(0 == err); + hip_lp_delete(&lp); +} +END_TEST + +START_TEST(test_hip_lp_delete_null_lp) +{ + hip_lp_delete(NULL); +} +END_TEST + +START_TEST(test_hip_lp_first_valid) +{ + struct hip_line_parser lp; + int err = 0; + + err = hip_lp_create(&lp, &ma); + assert(0 == err); + fail_unless(hip_lp_first(&lp) == lines[0], NULL); +} +END_TEST + +START_TEST(test_hip_lp_first_null_lp) +{ + fail_unless(hip_lp_first(NULL) == NULL, NULL); +} +END_TEST + +START_TEST(test_hip_lp_next_valid) +{ + struct hip_line_parser lp; + int err = 0; + char *first = NULL; + + err = hip_lp_create(&lp, &ma); + assert(0 == err); + first = hip_lp_first(&lp); + assert(first == lines[0]); + + fail_unless(hip_lp_next(&lp) == lines[1], NULL); + fail_unless(hip_lp_next(&lp) == lines[2], NULL); + fail_unless(hip_lp_next(&lp) == lines[3], NULL); + fail_unless(hip_lp_next(&lp) == NULL, NULL); +} +END_TEST + +START_TEST(test_hip_lp_next_null_lp) +{ + fail_unless(hip_lp_next(NULL) == NULL, NULL); +} +END_TEST + +// For unknown reasons, this file does not compile without the following, +// seemingly useless forward declaration +Suite *firewall_line_parser(void); + +Suite *firewall_line_parser(void) +{ + Suite *s = suite_create("firewall/line_parser"); + + TCase *tc_core = tcase_create("Core"); + tcase_add_test(tc_core, test_hip_lp_create_valid); + tcase_add_test(tc_core, test_hip_lp_create_null_lp); + tcase_add_test(tc_core, test_hip_lp_create_null_ma); + tcase_add_test(tc_core, test_hip_lp_delete_valid); + tcase_add_test(tc_core, test_hip_lp_delete_null_lp); + tcase_add_test(tc_core, test_hip_lp_first_valid); + tcase_add_test(tc_core, test_hip_lp_first_null_lp); + tcase_add_test(tc_core, test_hip_lp_next_valid); + tcase_add_test(tc_core, test_hip_lp_next_null_lp); + suite_add_tcase(s, tc_core); + + return s; +} === added file 'test/firewall/port_bindings.c' --- test/firewall/port_bindings.c 1970-01-01 00:00:00 +0000 +++ test/firewall/port_bindings.c 2010-11-12 17:49:42 +0000 @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2010 Aalto University and RWTH Aachen University. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <netinet/in.h> +#include <assert.h> +#include <check.h> +#include <stdio.h> + +#include "firewall/port_bindings.h" +#include "firewall/port_bindings.c" + +// these tests do not clean up after themselves because they assume that +// check runs them in dedicated processes so the OS does the cleanup. +START_TEST(test_hip_port_bindings_init_with_cache) +{ + fail_unless(hip_port_bindings_init(true) == 0, NULL); +} +END_TEST + +START_TEST(test_hip_port_bindings_init_without_cache) +{ + fail_unless(hip_port_bindings_init(false) == 0, NULL); +} +END_TEST + +START_TEST(test_hip_port_bindings_uninit_with_cache) +{ + int err = 0; + + err = hip_port_bindings_init(true); + assert(0 == err); + + hip_port_bindings_uninit(); +} +END_TEST + +START_TEST(test_hip_port_bindings_uninit_without_cache) +{ + int err = 0; + + err = hip_port_bindings_init(false); + assert(0 == err); + + hip_port_bindings_uninit(); +} +END_TEST + +static void test_hip_port_bindings_get(const bool enable_cache) +{ + int err = 0; + enum hip_port_binding binding; + + err = hip_port_bindings_init(enable_cache); + assert(0 == err); + + binding = hip_port_bindings_get(IPPROTO_TCP, htons(631)); + fail_unless(HIP_PORT_INFO_IPV6UNBOUND == binding || + HIP_PORT_INFO_IPV6BOUND == binding, NULL); + if (HIP_PORT_INFO_IPV6UNBOUND == binding) { + printf("hip_port_bindings_get() reports your CUPS port 631 to not be bound under IPv6.\n" + " This is only correct if you do not have CUPS installed or deliberately disabled\n" + " IPv6 support.\n"); + } else { + printf("hip_port_bindings_get() reports your CUPS port 631 to be bound under IPv6. This\n" + " is only correct if you have CUPS running and IPv6 support enabled.\n"); + } +} + +START_TEST(test_hip_port_bindings_get_with_cache) +{ + test_hip_port_bindings_get(true); +} +END_TEST + +START_TEST(test_hip_port_bindings_get_without_cache) +{ + test_hip_port_bindings_get(false); +} +END_TEST + +// For unknown reasons, this file does not compile without the following, +// seemingly useless forward declaration +Suite *firewall_port_bindings(void); + +Suite *firewall_port_bindings(void) +{ + Suite *s = suite_create("firewall/port_bindings"); + + TCase *tc_core = tcase_create("Core"); + tcase_add_test(tc_core, test_hip_port_bindings_init_with_cache); + tcase_add_test(tc_core, test_hip_port_bindings_init_without_cache); + tcase_add_test(tc_core, test_hip_port_bindings_uninit_with_cache); + tcase_add_test(tc_core, test_hip_port_bindings_uninit_without_cache); + tcase_add_test(tc_core, test_hip_port_bindings_get_with_cache); + tcase_add_test(tc_core, test_hip_port_bindings_get_without_cache); + suite_add_tcase(s, tc_core); + + return s; +} === added file 'test/fw_port_bindings_performance.c' --- test/fw_port_bindings_performance.c 1970-01-01 00:00:00 +0000 +++ test/fw_port_bindings_performance.c 2010-11-12 17:49:42 +0000 @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2010 Aalto University and RWTH Aachen University. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * @file + * @author Stefan Goetz <stefan.goetz@xxxxxxxxxxxxxxxxx> + */ + +#include <assert.h> +#include <stdio.h> +#include <time.h> + +#include "firewall/file_buffer.h" +#include "firewall/line_parser.h" +#include "firewall/port_bindings.h" + +static double time_clock(const unsigned int iterations) +{ + clock_t start, end, tmp; + unsigned int i; + + start = clock(); + for (i = 0; i < iterations; i += 1) { + tmp = clock(); + } + end = clock(); + + return (((double) (end - start)) / CLOCKS_PER_SEC) / iterations; +} + +static double time_hip_fb_create_delete(const unsigned int iterations, + const char *file_name) +{ + clock_t start, end; + unsigned int i; + struct hip_file_buffer fb; + + start = clock(); + for (i = 0; i < iterations; i += 1) { + if (hip_fb_create(&fb, file_name) == 0) { + hip_fb_delete(&fb); + } + } + end = clock(); + + return (((double) (end - start)) / CLOCKS_PER_SEC) / iterations; +} + +static double time_hip_fb_reload(const unsigned int iterations, + const char *file_name) +{ + clock_t start, end; + unsigned int i; + struct hip_file_buffer fb; + int err; + + err = hip_fb_create(&fb, file_name); + assert(0 == err); + + start = clock(); + for (i = 0; i < iterations; i += 1) { + err = hip_fb_reload(&fb); + assert(err == 0); + } + end = clock(); + + hip_fb_delete(&fb); + + return (((double) (end - start)) / CLOCKS_PER_SEC) / iterations; +} + +static double time_hip_lp_create_delete(const unsigned int iterations) +{ + clock_t start, end; + unsigned int i; + struct hip_mem_area ma = { 0, 0 }; + struct hip_line_parser lp; + + start = clock(); + for (i = 0; i < iterations; i += 1) { + if (hip_lp_create(&lp, &ma) == 0) { + hip_lp_delete(&lp); + } + } + end = clock(); + + return (((double) (end - start)) / CLOCKS_PER_SEC) / iterations; +} + +static double time_hip_lp_first(const unsigned int iterations) +{ + clock_t start, end; + unsigned int i; + struct hip_line_parser lp; + char *line; + struct hip_mem_area ma = { 0, 0 }; + int err; + + err = hip_lp_create(&lp, &ma); + assert(0 == err); + + start = clock(); + for (i = 0; i < iterations; i += 1) { + line = hip_lp_first(&lp); + } + end = clock(); + + hip_lp_delete(&lp); + + return (((double) (end - start)) / CLOCKS_PER_SEC) / iterations; +} + +static double time_hip_lp_next(const unsigned int iterations, + const char *file_name) +{ + clock_t start, end; + unsigned int i; + struct hip_file_buffer fb; + struct hip_line_parser lp; + char *line; + int err; + + err = hip_fb_create(&fb, file_name); + assert(0 == err); + err = hip_lp_create(&lp, hip_fb_get_mem_area(&fb)); + assert(0 == err); + line = hip_lp_first(&lp); + assert(line != NULL); + + start = clock(); + for (i = 0; i < iterations; i += 1) { + line = hip_lp_next(&lp); + } + end = clock(); + + hip_lp_delete(&lp); + hip_fb_delete(&fb); + + return (((double) (end - start)) / CLOCKS_PER_SEC) / iterations; +} + +static double time_hip_lp_parse_file(const unsigned int iterations, + const char *file_name) +{ + clock_t start, end; + unsigned int i; + struct hip_file_buffer fb; + struct hip_line_parser lp; + char *line; + int err; + + err = hip_fb_create(&fb, file_name); + assert(0 == err); + err = hip_lp_create(&lp, hip_fb_get_mem_area(&fb)); + assert(0 == err); + + start = clock(); + for (i = 0; i < iterations; i += 1) { + line = hip_lp_first(&lp); + while (line != NULL) { + line = hip_lp_next(&lp); + } + } + end = clock(); + + hip_lp_delete(&lp); + hip_fb_delete(&fb); + + return (((double) (end - start)) / CLOCKS_PER_SEC) / iterations; +} + +static double time_hip_port_binding_create_delete(const unsigned int iterations, + const bool enable_cache) +{ + clock_t start, end; + unsigned int i; + + start = clock(); + for (i = 0; i < iterations; i += 1) { + hip_port_bindings_init(enable_cache); + hip_port_bindings_uninit(); + } + end = clock(); + + return (((double) (end - start)) / CLOCKS_PER_SEC) / iterations; +} + +static double time_hip_port_bindings_get(const unsigned int iterations, + const uint8_t proto, + const in_port_t port, + const bool enable_cache) +{ + clock_t start, end; + unsigned int i; + enum hip_port_binding pi; + + hip_port_bindings_init(enable_cache); + + start = clock(); + for (i = 0; i < iterations; i += 1) { + pi = hip_port_bindings_get(proto, port); + } + end = clock(); + + hip_port_bindings_uninit(); + + return (((double) (end - start)) / CLOCKS_PER_SEC) / iterations; +} + +int main(void) +{ + const unsigned int iterations = 10000; + const char *file_name = "/proc/net/tcp6"; + const uint8_t proto = 6; + const in_port_t port = 0xFFFF; + bool enable_cache = false; + + printf("Testing clock reading used for benchmarks:\n" + " - call clock()\n" + " ==> time_clock(%d): %fs\n\n", iterations, + time_clock(iterations)); + + printf("Testing file buffer allocation and de-allocation:\n" + " - call hip_fb_create() to\n" + " - zero the file buffer object\n" + " - open the file\n" + " - call hip_fb_reload() to\n" + " - allocate a memory buffer for the file data (if new fb object)\n" + " - read the file data into the memory buffer\n" + " - call hip_fb_delete() to\n" + " - de-allocate the file buffer object\n" + " ==> time_hip_fb_create_delete(%d, %s): %fs\n\n", iterations, + file_name, time_hip_fb_create_delete(iterations, file_name)); + + printf("Testing file buffer file access:\n" + " - call hip_fb_reload() to\n" + " - allocate a memory buffer for the file data (if new fb object)\n" + " - read the file data into the memory buffer\n" + " ==> time_hip_fb_reload(%d, %s): %fs\n\n", iterations, file_name, + time_hip_fb_reload(iterations, file_name)); + + printf("Testing line parser allocation and de-allocation:\n" + " - call hip_lp_create() to\n" + " - allocate a line parser object\n" + " - call hip_fb_create() (s.a.)\n" + " - call hip_lp_delete() to\n" + " - de-allocate the line parser object\n" + " ==> time_hip_lp_create_delete(%d): %fs\n\n", iterations, + time_hip_lp_create_delete(iterations)); + + printf("Testing line parser parsing function:\n" + " - call hip_lp_first() to\n" + " - retrieve a pointer to the beginning of the file\n" + " ==> time_hip_lp_first(%d): %fs\n\n", iterations, + time_hip_lp_first(iterations)); + + printf("Testing line parser parsing function:\n" + " - call hip_lp_next() to\n" + " - search for the next line\n" + " - retrieve a pointer to the beginning of the line\n" + " ==> time_hip_lp_next(%d, %s): %fs\n\n", iterations, file_name, + time_hip_lp_next(iterations, file_name)); + + printf("Testing line parser whole file parsing:\n" + " - call hip_lp_first() (s.a.)\n" + " - call hip_lp_next() (s.a.) until the end of the file\n" + " ==> time_hip_lp_parse_file(%d, %s): %fs\n\n", iterations, file_name, + time_hip_lp_parse_file(iterations, file_name)); + + printf("Testing port binding allocation and de-allocation without cache:\n" + " - call hip_port_bindings_init() to\n" + " - create tcp6 and udp6 line parser objects\n" + " - call hip_port_bindings_uninit() to\n" + " - delete tcp6 and udp6 line parser objects\n" + " ==> time_hip_port_binding_create_delete(%d, %d): %fs\n\n", + iterations, enable_cache, + time_hip_port_binding_create_delete(iterations, enable_cache)); + + printf("Testing port binding parsing without cache:\n" + " - call hip_port_bindings_get() to\n" + " - parse proc file\n" + " ==> time_hip_port_bindings_get(%d, %d, 0x%X, %d): %fs\n\n", + iterations, proto, port, enable_cache, + time_hip_port_bindings_get(iterations, proto, port, enable_cache)); + + enable_cache = true; + printf("Testing port binding allocation and de-allocation with cache:\n" + " - call hip_port_bindings_init() to\n" + " - allocate and zero cache\n" + " - create tcp6 and udp6 line parser objects\n" + " - call hip_port_bindings_uninit() to\n" + " - delete tcp6 and udp6 line parser objects\n" + " - de-allocate cache\n" + " ==> time_hip_port_binding_create_delete(%d, %d): %fs\n\n", + iterations, enable_cache, + time_hip_port_binding_create_delete(iterations, enable_cache)); + + printf("Testing port binding parsing with cache:\n" + " - call hip_port_bindings_get() to\n" + " - check cache for port binding\n" + " - parse proc file if no cache entry\n" + " ==> time_hip_port_bindings_get(%d, %d, 0x%X, %d): %fs\n\n", + iterations, proto, port, enable_cache, + time_hip_port_bindings_get(iterations, proto, port, enable_cache)); + + return 0; +} === modified file 'tools/hipl_autobuild.sh' --- tools/hipl_autobuild.sh 2010-11-05 08:46:43 +0000 +++ tools/hipl_autobuild.sh 2010-11-12 15:50:17 +0000 @@ -143,10 +143,10 @@ run_program "make -j check" # PISA configuration -compile --enable-firewall --disable-rvs --disable-opportunistic --disable-profiling --enable-debug --enable-midauth --disable-performance --disable-demo +compile --enable-firewall --disable-rvs --disable-opportunistic --disable-profiling --enable-debug --enable-midauth --disable-performance # Max compile coverage configuration -FEATURES_ALL="--enable-firewall --enable-rvs --enable-opportunistic --enable-profiling --disable-debug --enable-midauth --enable-performance --enable-demo" +FEATURES_ALL="--enable-firewall --enable-rvs --enable-opportunistic --enable-profiling --disable-debug --enable-midauth --enable-performance" compile $FEATURES_ALL # Max compile coverage configuration without optimization