Page MenuHomeClusterLabs Projects

No OneTemporary

diff --git a/build-aux/knet_valgrind_memcheck.supp b/build-aux/knet_valgrind_memcheck.supp
index e69de29b..9e195651 100644
--- a/build-aux/knet_valgrind_memcheck.supp
+++ b/build-aux/knet_valgrind_memcheck.supp
@@ -0,0 +1,446 @@
+{
+ lzma internal stuff
+ Memcheck:Cond
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+ fun:clone
+}
+{
+ lzma internal stuff
+ Memcheck:Value8
+ fun:lzma_stream_header_encode
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+ fun:clone
+}
+{
+ lzma internal stuff
+ Memcheck:Cond
+ fun:lzma_crc32
+ fun:lzma_stream_header_encode
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+ fun:clone
+}
+{
+ lzma internal stuff
+ Memcheck:Value8
+ fun:lzma_crc32
+ fun:lzma_stream_header_encode
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+ fun:clone
+}
+{
+ lzma internal stuff
+ Memcheck:Cond
+ obj:/usr/lib64/liblzma.so.5.2.2
+ fun:lzma_block_buffer_encode
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+ fun:clone
+}
+{
+ lzma internal stuff
+ Memcheck:Value8
+ fun:lzma_block_header_encode
+ obj:/usr/lib64/liblzma.so.5.2.2
+ fun:lzma_block_buffer_encode
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+ fun:clone
+}
+{
+ lzma internal stuff
+ Memcheck:Cond
+ obj:/usr/lib64/liblzma.so.5.2.2
+ obj:/usr/lib64/liblzma.so.5.2.2
+ fun:lzma_block_buffer_encode
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+ fun:clone
+}
+{
+ lzma internal stuff
+ Memcheck:Cond
+ obj:/usr/lib64/liblzma.so.5.2.2
+ obj:/usr/lib64/liblzma.so.5.2.2
+ obj:/usr/lib64/liblzma.so.5.2.2
+ fun:lzma_block_buffer_encode
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+ fun:clone
+}
+{
+ lzma internal stuff
+ Memcheck:Value8
+ obj:/usr/lib64/liblzma.so.5.2.2
+ obj:/usr/lib64/liblzma.so.5.2.2
+ obj:/usr/lib64/liblzma.so.5.2.2
+ fun:lzma_block_buffer_encode
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+ fun:clone
+}
+{
+ lzma internal stuff
+ Memcheck:Cond
+ fun:is_overlap
+ fun:memcpy@@GLIBC_2.14
+ obj:/usr/lib64/liblzma.so.5.2.2
+ obj:/usr/lib64/liblzma.so.5.2.2
+ obj:/usr/lib64/liblzma.so.5.2.2
+ obj:/usr/lib64/liblzma.so.5.2.2
+ fun:lzma_block_buffer_encode
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+}
+{
+ lzma internal stuff
+ Memcheck:Cond
+ fun:memcpy@@GLIBC_2.14
+ obj:/usr/lib64/liblzma.so.5.2.2
+ obj:/usr/lib64/liblzma.so.5.2.2
+ obj:/usr/lib64/liblzma.so.5.2.2
+ obj:/usr/lib64/liblzma.so.5.2.2
+ fun:lzma_block_buffer_encode
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+}
+{
+ lzma internal stuff
+ Memcheck:Value8
+ fun:memcpy@@GLIBC_2.14
+ obj:/usr/lib64/liblzma.so.5.2.2
+ obj:/usr/lib64/liblzma.so.5.2.2
+ obj:/usr/lib64/liblzma.so.5.2.2
+ obj:/usr/lib64/liblzma.so.5.2.2
+ fun:lzma_block_buffer_encode
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+}
+{
+ lzma internal stuff
+ Memcheck:Value8
+ fun:lzma_vli_encode
+ fun:lzma_filter_flags_encode
+ fun:lzma_block_header_encode
+ obj:/usr/lib64/liblzma.so.5.2.2
+ fun:lzma_block_buffer_encode
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+ fun:clone
+}
+{
+ lzma internal stuff
+ Memcheck:Value8
+ obj:/usr/lib64/liblzma.so.5.2.2
+ fun:lzma_filter_flags_encode
+ fun:lzma_block_header_encode
+ obj:/usr/lib64/liblzma.so.5.2.2
+ fun:lzma_block_buffer_encode
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+ fun:clone
+}
+{
+ lzma internal stuff
+ Memcheck:Cond
+ fun:memset
+ fun:lzma_block_header_encode
+ obj:/usr/lib64/liblzma.so.5.2.2
+ fun:lzma_block_buffer_encode
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+ fun:clone
+}
+{
+ lzma internal stuff
+ Memcheck:Value8
+ fun:memset
+ fun:lzma_block_header_encode
+ obj:/usr/lib64/liblzma.so.5.2.2
+ fun:lzma_block_buffer_encode
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+ fun:clone
+}
+{
+ lzma internal stuff
+ Memcheck:Cond
+ fun:lzma_block_unpadded_size
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+ fun:clone
+}
+{
+ lzma internal stuff
+ Memcheck:Cond
+ fun:lzma_index_append
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+ fun:clone
+}
+{
+ lzma internal stuff
+ Memcheck:Cond
+ fun:lzma_vli_size
+ fun:lzma_index_append
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+ fun:clone
+}
+{
+ lzma internal stuff
+ Memcheck:Cond
+ fun:lzma_index_buffer_encode
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+ fun:clone
+}
+{
+ lzma internal stuff
+ Memcheck:Cond
+ obj:/usr/lib64/liblzma.so.5.2.2
+ fun:lzma_index_buffer_encode
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+ fun:clone
+}
+{
+ lzma internal stuff
+ Memcheck:Value8
+ obj:/usr/lib64/liblzma.so.5.2.2
+ fun:lzma_index_buffer_encode
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+ fun:clone
+}
+{
+ lzma internal stuff
+ Memcheck:Cond
+ fun:lzma_vli_encode
+ obj:/usr/lib64/liblzma.so.5.2.2
+ fun:lzma_index_buffer_encode
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+ fun:clone
+}
+{
+ lzma internal stuff
+ Memcheck:Value8
+ fun:lzma_vli_encode
+ obj:/usr/lib64/liblzma.so.5.2.2
+ fun:lzma_index_buffer_encode
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+ fun:clone
+}
+{
+ lzma internal stuff
+ Memcheck:Cond
+ fun:lzma_crc32
+ obj:/usr/lib64/liblzma.so.5.2.2
+ fun:lzma_index_buffer_encode
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+ fun:clone
+}
+{
+ lzma internal stuff
+ Memcheck:Value8
+ fun:lzma_crc32
+ obj:/usr/lib64/liblzma.so.5.2.2
+ fun:lzma_index_buffer_encode
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+ fun:clone
+}
+{
+ lzma internal stuff
+ Memcheck:Value8
+ fun:lzma_stream_footer_encode
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+ fun:clone
+}
+{
+ lzma internal stuff
+ Memcheck:Value8
+ fun:lzma_crc32
+ fun:lzma_stream_footer_encode
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+ fun:clone
+}
+{
+ lzma internal stuff
+ Memcheck:Cond
+ fun:lzma_crc32
+ fun:lzma_stream_footer_encode
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+ fun:clone
+}
+{
+ lzma internal stuff
+ Memcheck:Cond
+ obj:/usr/lib64/liblzma.so.5.2.2
+ obj:/usr/lib64/liblzma.so.5.2.2
+ obj:/usr/lib64/liblzma.so.5.2.2
+ obj:/usr/lib64/liblzma.so.5.2.2
+ fun:lzma_block_buffer_encode
+ fun:lzma_stream_buffer_encode
+ fun:lzma_easy_buffer_encode
+ fun:lzma_compress
+ fun:_parse_recv_from_sock
+ fun:_handle_send_to_links
+ fun:_handle_send_to_links_thread
+ fun:start_thread
+}
+
diff --git a/configure.ac b/configure.ac
index bd764c6c..42fae6a9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,420 +1,421 @@
#
# Copyright (C) 2010-2015 Red Hat, Inc. All rights reserved.
#
# Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
# Federico Simoncelli <fsimon@kronosnet.org>
#
# This software licensed under GPL-2.0+, LGPL-2.0+
#
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
#
AC_PREREQ([2.63])
AC_INIT([kronosnet],
m4_esyscmd([build-aux/git-version-gen .tarball-version]),
[devel@lists.kronosnet.org])
AC_USE_SYSTEM_EXTENSIONS
AM_INIT_AUTOMAKE([1.11.1 dist-bzip2 dist-xz color-tests -Wno-portability subdir-objects])
LT_PREREQ([2.2.6])
LT_INIT
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR([kronosnetd/main.c])
AC_CONFIG_HEADERS([config.h])
AC_CANONICAL_HOST
AC_PROG_LIBTOOL
AC_LANG([C])
systemddir=${prefix}/lib/systemd/system
if test "$prefix" = "NONE"; then
prefix="/usr"
if test "$localstatedir" = "\${prefix}/var"; then
localstatedir="/var"
fi
if test "$sysconfdir" = "\${prefix}/etc"; then
sysconfdir="/etc"
fi
if test "$systemddir" = "NONE/lib/systemd/system"; then
systemddir=/lib/systemd/system
fi
if test "$libdir" = "\${exec_prefix}/lib"; then
if test -e /usr/lib64; then
libdir="/usr/lib64"
else
libdir="/usr/lib"
fi
fi
fi
# Checks for programs.
if ! ${MAKE-make} --version /cannot/make/this >/dev/null 2>&1; then
AC_MSG_ERROR(["you don't seem to have GNU make; it is required"])
fi
AC_PROG_AWK
AC_PROG_GREP
AC_PROG_SED
AC_PROG_CPP
AC_PROG_CC
AC_PROG_CC_C99
if test "x$ac_cv_prog_cc_c99" = "xno"; then
AC_MSG_ERROR(["C99 support is required"])
fi
AC_PROG_LN_S
AC_PROG_INSTALL
AC_PROG_MAKE_SET
AC_PROG_CXX
AC_PROG_RANLIB
AC_CHECK_PROGS([PUBLICAN], [publican], [:])
AC_CHECK_PROGS([PKGCONFIG], [pkg-config])
AC_ARG_ENABLE([poc],
[ --disable-poc : avoid building poc code ],,
[ enable_poc="yes" ])
AM_CONDITIONAL([BUILD_POC], [test x$enable_poc = xyes])
AC_ARG_ENABLE([kronosnetd],
[ --enable-kronosnetd : Kronosnetd support ],,
[ enable_kronosnetd="no" ])
AM_CONDITIONAL([BUILD_KRONOSNETD], [test x$enable_kronosnetd = xyes])
AC_ARG_ENABLE([libtap],
[ --enable-libtap : libtap support ],,
[ enable_libtap="no" ])
if test "x$enable_kronosnetd" = xyes; then
enable_libtap=yes
fi
AM_CONDITIONAL([BUILD_LIBTAP], [test x$enable_libtap = xyes])
AC_ARG_ENABLE([libknet-sctp],
[ --disable-libknet-sctp : avoid libknet SCTP support ],,
[ enable_libknet_sctp="yes" ])
## local helper functions
# this function checks if CC support options passed as
# args. Global CFLAGS are ignored during this test.
cc_supports_flag() {
saveCPPFLAGS="$CPPFLAGS"
CPPFLAGS="$@"
if echo $CC | grep -q clang; then
CPPFLAGS="-Werror $CPPFLAGS"
fi
AC_MSG_CHECKING([whether $CC supports "$@"])
AC_PREPROC_IFELSE([AC_LANG_PROGRAM([])],
[RC=0; AC_MSG_RESULT([yes])],
[RC=1; AC_MSG_RESULT([no])])
CPPFLAGS="$saveCPPFLAGS"
return $RC
}
# helper macro to check libs without adding them to LIBS
check_lib_no_libs() {
lib_no_libs_arg1=$1
shift
lib_no_libs_arg2=$1
shift
lib_no_libs_args=$@
AC_CHECK_LIB([$lib_no_libs_arg1],
[$lib_no_libs_arg2],,,
[$lib_no_libs_args])
LIBS=$ac_check_lib_save_LIBS
}
# Checks for C features
AC_C_INLINE
# Checks for libraries.
AC_CHECK_LIB([pthread], [pthread_create])
AC_CHECK_LIB([m], [ceil])
AC_CHECK_LIB([rt], [clock_gettime])
# crypto libraries checks
PKG_CHECK_MODULES([nss],[nss])
# compress libraries checks
# zlib is cheap because it's pulled in by nss
PKG_CHECK_MODULES([zlib], [zlib])
PKG_CHECK_MODULES([liblz4], [liblz4])
+PKG_CHECK_MODULES([liblzma], [liblzma])
AC_CHECK_HEADERS([lzo/lzo1x.h], [AC_CHECK_LIB([lzo2], [lzo1x_decompress_safe])], [AC_MSG_ERROR(["missing required lzo/lzo1x.h header"])])
# Checks for header files.
AC_CHECK_HEADERS([fcntl.h])
AC_CHECK_HEADERS([stdlib.h])
AC_CHECK_HEADERS([string.h])
AC_CHECK_HEADERS([strings.h])
AC_CHECK_HEADERS([sys/ioctl.h])
AC_CHECK_HEADERS([syslog.h])
AC_CHECK_HEADERS([unistd.h])
AC_CHECK_HEADERS([netinet/in.h])
AC_CHECK_HEADERS([sys/socket.h])
AC_CHECK_HEADERS([arpa/inet.h])
AC_CHECK_HEADERS([netdb.h])
AC_CHECK_HEADERS([limits.h])
AC_CHECK_HEADERS([stdint.h])
AC_CHECK_HEADERS([sys/epoll.h])
if test "x$enable_libknet_sctp" = xyes; then
AC_CHECK_HEADERS([netinet/sctp.h],, [AC_MSG_ERROR(["missing required SCTP headers"])])
fi
# Checks for typedefs, structures, and compiler characteristics.
AC_C_INLINE
AC_TYPE_SIZE_T
AC_TYPE_PID_T
AC_TYPE_SSIZE_T
AC_TYPE_UINT8_T
AC_TYPE_UINT16_T
AC_TYPE_UINT32_T
AC_TYPE_UINT64_T
AC_TYPE_INT32_T
# Checks for library functions.
AC_FUNC_ALLOCA
AC_FUNC_FORK
AC_FUNC_MALLOC
AC_FUNC_REALLOC
AC_CHECK_FUNCS([memset])
AC_CHECK_FUNCS([strdup])
AC_CHECK_FUNCS([strerror])
AC_CHECK_FUNCS([dup2])
AC_CHECK_FUNCS([select])
AC_CHECK_FUNCS([socket])
AC_CHECK_FUNCS([inet_ntoa])
AC_CHECK_FUNCS([memmove])
AC_CHECK_FUNCS([strchr])
AC_CHECK_FUNCS([atexit])
AC_CHECK_FUNCS([ftruncate])
AC_CHECK_FUNCS([strrchr])
AC_CHECK_FUNCS([strstr])
AC_CHECK_FUNCS([clock_gettime])
AC_CHECK_FUNCS([strcasecmp])
AC_CHECK_FUNCS([kevent])
# if neither sys/epoll.h nor kevent are present, we should fail.
if test "x$ac_cv_header_sys_epoll_h" = xno && test "x$ac_cv_func_kevent" = xno; then
AC_MSG_ERROR([Both epoll and kevent unavailable on this OS])
fi
if test "x$ac_cv_header_sys_epoll_h" = xyes && test "x$ac_cv_func_kevent" = xyes; then
AC_MSG_ERROR([Both epoll and kevent available on this OS, please contact the maintainers to fix the code])
fi
# checks (for kronosnetd)
if test "x$enable_kronosnetd" = xyes; then
AC_CHECK_HEADERS([security/pam_appl.h],
[AC_CHECK_LIB([pam], [pam_start])],
[AC_MSG_ERROR([Unable to find LinuxPAM devel files])])
AC_CHECK_HEADERS([security/pam_misc.h],
[AC_CHECK_LIB([pam_misc], [misc_conv])],
[AC_MSG_ERROR([Unable to find LinuxPAM MISC devel files])])
PKG_CHECK_MODULES([libqb], [libqb])
AC_CHECK_LIB([qb], [qb_log_thread_priority_set],
[have_qb_log_thread_priority_set="yes"],
[have_qb_log_thread_priority_set="no"])
if test "x${have_qb_log_thread_priority_set}" = xyes; then
AC_DEFINE_UNQUOTED([HAVE_QB_LOG_THREAD_PRIORITY_SET], [1], [have qb_log_thread_priority_set])
fi
fi
# local options
AC_ARG_ENABLE([debug],
[ --enable-debug enable debug build. ],
[ default="no" ])
AC_ARG_ENABLE([publicandocs],
[ --enable-publicandocs enable docs build. ],
[ default="no" ])
AC_ARG_WITH([initdefaultdir],
[ --with-initdefaultdir : path to /etc/sysconfig/.. or /etc/default dir. ],
[ INITDEFAULTDIR="$withval" ],
[ INITDEFAULTDIR="$sysconfdir/default" ])
AC_ARG_WITH([initddir],
[ --with-initddir=DIR : path to init script directory. ],
[ INITDDIR="$withval" ],
[ INITDDIR="$sysconfdir/init.d" ])
AC_ARG_WITH([systemddir],
[ --with-systemddir=DIR : path to systemd unit files directory. ],
[ SYSTEMDDIR="$withval" ],
[ SYSTEMDDIR="$systemddir" ])
AC_ARG_WITH([syslogfacility],
[ --with-syslogfacility=FACILITY
default syslog facility. ],
[ SYSLOGFACILITY="$withval" ],
[ SYSLOGFACILITY="LOG_DAEMON" ])
AC_ARG_WITH([sysloglevel],
[ --with-sysloglevel=LEVEL
default syslog level. ],
[ SYSLOGLEVEL="$withval" ],
[ SYSLOGLEVEL="LOG_INFO" ])
AC_ARG_WITH([defaultadmgroup],
[ --with-defaultadmgroup=GROUP
define PAM group. Users part of this group will be
allowed to configure kronosnet. Others will only
receive read-only rights. ],
[ DEFAULTADMGROUP="$withval" ],
[ DEFAULTADMGROUP="kronosnetadm" ])
## random vars
LOGDIR=${localstatedir}/log/
RUNDIR=${localstatedir}/run/
DEFAULT_CONFIG_DIR=${sysconfdir}/kronosnet
## do subst
AM_CONDITIONAL([BUILD_DOCS], [test "x${enable_publicandocs}" = xyes])
AM_CONDITIONAL([DEBUG], [test "x${enable_debug}" = xyes])
AC_SUBST([DEFAULT_CONFIG_DIR])
AC_SUBST([INITDEFAULTDIR])
AC_SUBST([INITDDIR])
AC_SUBST([SYSTEMDDIR])
AC_SUBST([LOGDIR])
AC_SUBST([DEFAULTADMGROUP])
AC_DEFINE_UNQUOTED([DEFAULT_CONFIG_DIR],
["$(eval echo ${DEFAULT_CONFIG_DIR})"],
[Default config directory])
AC_DEFINE_UNQUOTED([DEFAULT_CONFIG_FILE],
["$(eval echo ${DEFAULT_CONFIG_DIR}/kronosnetd.conf)"],
[Default config file])
AC_DEFINE_UNQUOTED([LOGDIR],
["$(eval echo ${LOGDIR})"],
[Default logging directory])
AC_DEFINE_UNQUOTED([DEFAULT_LOG_FILE],
["$(eval echo ${LOGDIR}/kronosnetd.log)"],
[Default log file])
AC_DEFINE_UNQUOTED([RUNDIR],
["$(eval echo ${RUNDIR})"],
[Default run directory])
AC_DEFINE_UNQUOTED([SYSLOGFACILITY],
[$(eval echo ${SYSLOGFACILITY})],
[Default syslog facility])
AC_DEFINE_UNQUOTED([SYSLOGLEVEL],
[$(eval echo ${SYSLOGLEVEL})],
[Default syslog level])
AC_DEFINE_UNQUOTED([DEFAULTADMGROUP],
["$(eval echo ${DEFAULTADMGROUP})"],
[Default admin group])
## *FLAGS handling
ENV_CFLAGS="$CFLAGS"
ENV_CPPFLAGS="$CPPFLAGS"
ENV_LDFLAGS="$LDFLAGS"
# debug build stuff
if test "x${enable_debug}" = xyes; then
AC_DEFINE_UNQUOTED([DEBUG], [1], [Compiling Debugging code])
OPT_CFLAGS="-O0"
else
OPT_CFLAGS="-O3"
fi
# gdb flags
if test "x${GCC}" = xyes; then
GDB_FLAGS="-ggdb3"
else
GDB_FLAGS="-g"
fi
# extra warnings
EXTRA_WARNINGS=""
WARNLIST="
all
extra
unused
shadow
missing-prototypes
missing-declarations
suggest-attribute=noreturn
suggest-attribute=format
strict-prototypes
declaration-after-statement
pointer-arith
write-strings
cast-align
bad-function-cast
missing-format-attribute
float-equal
format=2
format-signedness
format-security
format-nonliteral
no-long-long
unsigned-char
gnu89-inline
no-strict-aliasing
error
address
cpp
overflow
parentheses
sequence-point
switch
shift-overflow=2
overlength-strings
retundent-decls
init-self
uninitialized
unused-but-set-variable
unused-function
unused-result
unused-value
unused-variable
unknown-pragmas
no-unused-parameter
"
for j in $WARNLIST; do
if cc_supports_flag -W$j; then
EXTRA_WARNINGS="$EXTRA_WARNINGS -W$j";
fi
done
CFLAGS="$ENV_CFLAGS $lt_prog_compiler_pic $OPT_CFLAGS $GDB_FLAGS \
$EXTRA_WARNINGS $WERROR_CFLAGS"
CPPFLAGS="$ENV_CPPFLAGS"
LDFLAGS="$ENV_LDFLAGS $lt_prog_compiler_pic -Wl,--as-needed"
AC_CONFIG_FILES([
Makefile
init/Makefile
libtap/Makefile
libtap/libtap.pc
kronosnetd/Makefile
kronosnetd/kronosnetd.logrotate
libknet/Makefile
libknet/libknet.pc
libknet/tests/Makefile
docs/Makefile
poc-code/Makefile
poc-code/iov-hash/Makefile
poc-code/access-list/Makefile
])
AC_OUTPUT
diff --git a/debian/control b/debian/control
index c9800b03..f9452ca7 100644
--- a/debian/control
+++ b/debian/control
@@ -1,67 +1,67 @@
Source: kronosnet
Priority: extra
Maintainer: Fabio M. Di Nitto <fabbione@kronosnet.org>
-Build-Depends: debhelper (>= 7.0.50~), autotools-dev, libqb-dev (>= 0.14.3), libnss3-dev, libnspr4-dev, pkg-config, libpam-dev, zlib1g-dev, liblz4-dev, liblzo2-dev
+Build-Depends: debhelper (>= 7.0.50~), autotools-dev, libqb-dev (>= 0.14.3), libnss3-dev, libnspr4-dev, pkg-config, libpam-dev, zlib1g-dev, liblz4-dev, liblzo2-dev, liblzma-dev
Standards-Version: 3.8.4
Section: admin
Package: kronosnetd
Section: admin
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: Multipoint-to-Multipoint VPN daemon
The kronosnet daemon is a bridge between kronosnet switching engine
and kernel network tap devices, to create and administer a
distributed LAN over multipoint-to-multipoint VPNs.
The daemon does a poor attempt to provide a configure UI similar
to other known network devices/tools (Cisco, quagga).
Beside looking horrific, it allows runtime changes and
reconfiguration of the kronosnet(s) without daemon reload
or service disruption.
.
This package contains the kronosnet daemon and utils.
Package: libtap0
Section: libs
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: Simple userland wrapper around kernel tap devices
This is an over-engineered commodity library to manage a pool
of tap devices and provides the basic
pre-up.d/up.d/down.d/post-down.d infrastructure.
.
This package contains libraries that should be used by libtap clients.
Package: libtap-dev
Section: libdevel
Architecture: any
Depends: libtap0 (= ${binary:Version}), ${misc:Depends}
Description: Simple userland wrapper around kernel tap devices (developer files)
This is an over-engineered commodity library to manage a pool
of tap devices and provides the basic
pre-up.d/up.d/down.d/post-down.d infrastructure.
.
This package contains header files required to build clients for libtap clients.
Package: libknet0
Section: libs
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: kronosnet core switching implementation
The whole kronosnet core is implemented in this library.
Please refer to the not-yet-existing documentation for further
information.
.
This package contains libraries that should be used by libknet clients.
Package: libknet-dev
Section: libdevel
Architecture: any
Depends: libknet0 (= ${binary:Version}), ${misc:Depends}
Description: kronosnet core switching implementation (developer files)
The whole kronosnet core is implemented in this library.
Please refer to the not-yet-existing documentation for further
information.
.
This package contains header files required to build clients for
libknet clients.
diff --git a/kronosnet.spec.in b/kronosnet.spec.in
index a71b63a4..e3043282 100644
--- a/kronosnet.spec.in
+++ b/kronosnet.spec.in
@@ -1,254 +1,254 @@
###############################################################################
###############################################################################
##
## Copyright (C) 2010-2015 Red Hat, Inc. All rights reserved.
##
## This copyrighted material is made available to anyone wishing to use,
## modify, copy, or redistribute it subject to the terms and conditions
## of the GNU General Public License v.2 or higher
##
###############################################################################
###############################################################################
# keep around ready for later user
%global alphatag @alphatag@
%global numcomm @numcomm@
%global dirty @dirty@
# set defaults from ./configure invokation
%@kronosnetd@ kronosnetd
%@libtap@ libtap
%if %{with libtap}
%global buildlibtap 1
%endif
%if %{with kronosnetd}
%global buildlibtap 1
%global buildkronosnetd 1
%endif
# main (empty) package
# http://www.rpm.org/max-rpm/s1-rpm-subpack-spec-file-changes.html
Name: kronosnet
Summary: Multipoint-to-Multipoint VPN daemon
Version: @version@
Release: 1%{?numcomm:.%{numcomm}}%{?alphatag:.%{alphatag}}%{?dirty:.%{dirty}}%{?dist}
License: GPLv2+ and LGPLv2+
Group: System Environment/Base
URL: https://github.com/fabbione/kronosnet/
Source0: https://github.com/fabbione/kronosnet/archive/%{name}-%{version}%{?numcomm:.%{numcomm}}%{?alphatag:-%{alphatag}}%{?dirty:-%{dirty}}.tar.gz
## Setup/build bits
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
# Build dependencies
BuildRequires: nss-devel lksctp-tools-devel
-BuildRequires: zlib-devel lz4-devel lzo-devel
+BuildRequires: zlib-devel lz4-devel lzo-devel xz-devel
%if %{defined buildkronosnetd}
BuildRequires: libqb-devel pam-devel
%endif
%prep
%setup -q -n %{name}-%{version}%{?numcomm:.%{numcomm}}%{?alphatag:-%{alphatag}}%{?dirty:-%{dirty}}
%build
%{configure} --disable-poc \
%if %{defined buildkronosnetd}
--enable-kronosnetd \
%endif
%if %{defined buildlibtap}
--enable-libtap \
%endif
--with-initdefaultdir=%{_sysconfdir}/sysconfig/ \
%if %{defined _unitdir}
--with-systemddir=%{_unitdir}
%else
--with-initddir=%{_sysconfdir}/rc.d/init.d/
%endif
make %{_smp_mflags}
%install
rm -rf %{buildroot}
make install DESTDIR=%{buildroot}
# tree cleanup
# remove static libraries
find %{buildroot} -name "*.a" -exec rm {} \;
# remove libtools leftovers
find %{buildroot} -name "*.la" -exec rm {} \;
# handle systemd vs init script
%if %{defined _unitdir}
# remove init scripts
rm -rf %{buildroot}/etc/init.d
%else
# remove systemd specific bits
find %{buildroot} -name "*.service" -exec rm {} \;
%endif
# remove docs
rm -rf %{buildroot}/usr/share/doc/kronosnet
%clean
rm -rf %{buildroot}
# main empty package
%description
kronosnet source
%if %{defined buildkronosnetd}
## Runtime and subpackages section
%package -n kronosnetd
Group: System Environment/Base
Summary: Multipoint-to-Multipoint VPN daemon
%if %{defined _unitdir}
# Needed for systemd unit
Requires(post): systemd-sysv
Requires(post): systemd-units
Requires(preun): systemd-units
Requires(postun): systemd-units
%else
Requires(post): chkconfig
Requires(preun): chkconfig, initscripts
%endif
Requires(post): shadow-utils
Requires(preun): shadow-utils
Requires: pam, /etc/pam.d/passwd
%description -n kronosnetd
The kronosnet daemon is a bridge between kronosnet switching engine
and kernel network tap devices, to create and administer a
distributed LAN over multipoint-to-multipoint VPNs.
The daemon does a poor attempt to provide a configure UI similar
to other known network devices/tools (Cisco, quagga).
Beside looking horrific, it allows runtime changes and
reconfiguration of the kronosnet(s) without daemon reload
or service disruption.
%post -n kronosnetd
%if %{defined _unitdir}
%if 0%{?systemd_post:1}
%systemd_post kronosnetd.service
%else
/bin/systemctl daemon-reload >/dev/null 2>&1 || :
%endif
%else
/sbin/chkconfig --add kronosnetd
%endif
/usr/sbin/groupadd --force --system @defaultadmgroup@
%preun -n kronosnetd
%if %{defined _unitdir}
%if 0%{?systemd_preun:1}
%systemd_preun kronosnetd.service
%else
if [ "$1" -eq 0 ]; then
/bin/systemctl --no-reload disable kronosnetd.service
/bin/systemctl stop kronosnetd.service >/dev/null 2>&1
fi
%endif
%else
if [ "$1" = 0 ]; then
/sbin/service kronosnetd stop >/dev/null 2>&1
/sbin/chkconfig --del kronosnetd
fi
%endif
%files -n kronosnetd
%defattr(-,root,root,-)
%doc COPYING.* COPYRIGHT
%dir %{_sysconfdir}/kronosnet
%dir %{_sysconfdir}/kronosnet/*
%config(noreplace) %{_sysconfdir}/sysconfig/kronosnetd
%config(noreplace) %{_sysconfdir}/pam.d/kronosnetd
%config(noreplace) %{_sysconfdir}/logrotate.d/kronosnetd
%if %{defined _unitdir}
%{_unitdir}/kronosnetd.service
%else
%config(noreplace) %{_sysconfdir}/rc.d/init.d/kronosnetd
%endif
%{_sbindir}/*
%{_mandir}/man8/*
%endif
%if %{defined buildlibtap}
%package -n libtap0
Group: System Environment/Libraries
Summary: Simple userland wrapper around kernel tap devices
%description -n libtap0
This is an over-engineered commodity library to manage a pool
of tap devices and provides the basic
pre-up.d/up.d/down.d/post-down.d infrastructure.
%files -n libtap0
%defattr(-,root,root,-)
%doc COPYING.* COPYRIGHT
%{_libdir}/libtap.so.*
%post -n libtap0 -p /sbin/ldconfig
%postun -n libtap0 -p /sbin/ldconfig
%package -n libtap0-devel
Group: Development/Libraries
Summary: Simple userland wrapper around kernel tap devices (developer files)
Requires: libtap0 = %{version}-%{release}
Requires: pkgconfig
%description -n libtap0-devel
This is an over-engineered commodity library to manage a pool
of tap devices and provides the basic
pre-up.d/up.d/down.d/post-down.d infrastructure.
%files -n libtap0-devel
%defattr(-,root,root,-)
%doc COPYING.* COPYRIGHT
%{_libdir}/libtap.so
%{_includedir}/libtap.h
%{_libdir}/pkgconfig/libtap.pc
%endif
%package -n libknet0
Group: System Environment/Libraries
Summary: Kronosnet core switching implementation
%description -n libknet0
The whole kronosnet core is implemented in this library.
Please refer to the not-yet-existing documentation for further
information.
%files -n libknet0
%defattr(-,root,root,-)
%doc COPYING.* COPYRIGHT
%{_libdir}/libknet.so.*
%post -n libknet0 -p /sbin/ldconfig
%postun -n libknet0 -p /sbin/ldconfig
%package -n libknet0-devel
Group: Development/Libraries
Summary: Kronosnet core switching implementation (developer files)
Requires: libknet0 = %{version}-%{release}
Requires: pkgconfig
%description -n libknet0-devel
The whole kronosnet core is implemented in this library.
Please refer to the not-yet-existing documentation for further
information.
%files -n libknet0-devel
%defattr(-,root,root,-)
%doc COPYING.* COPYRIGHT
%{_libdir}/libknet.so
%{_includedir}/libknet.h
%{_libdir}/pkgconfig/libknet.pc
%changelog
* @date@ Autotools generated version <nobody@nowhere.org> - @version@-1-@numcomm@.@alphatag@.@dirty@
- These aren't the droids you're looking for.
diff --git a/libknet/Makefile.am b/libknet/Makefile.am
index b3e9d2e2..d80d3619 100644
--- a/libknet/Makefile.am
+++ b/libknet/Makefile.am
@@ -1,92 +1,94 @@
#
# Copyright (C) 2010-2015 Red Hat, Inc. All rights reserved.
#
# Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
# Federico Simoncelli <fsimon@kronosnet.org>
#
# This software licensed under GPL-2.0+, LGPL-2.0+
#
MAINTAINERCLEANFILES = Makefile.in
include $(top_srcdir)/build-aux/check.mk
SYMFILE = libknet_exported_syms
EXTRA_DIST = $(SYMFILE)
SUBDIRS = . tests
libversion = 0:0:0
# override global LIBS that pulls in lots of craft we don't need here
LIBS =
sources = \
common.c \
compat.c \
compress.c \
compress_zlib.c \
compress_lz4.c \
compress_lzo2.c \
+ compress_lzma.c \
crypto.c \
handle.c \
host.c \
link.c \
logging.c \
netutils.c \
nsscrypto.c \
threads_common.c \
threads_dsthandler.c \
threads_heartbeat.c \
threads_pmtud.c \
threads_rx.c \
threads_tx.c \
transport_udp.c \
transport_sctp.c \
transport_loopback.c \
transport_common.c
include_HEADERS = libknet.h
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libknet.pc
noinst_HEADERS = \
common.h \
compat.h \
compress.h \
compress_zlib.h \
compress_lz4.h \
compress_lzo2.h \
+ compress_lzma.h \
crypto.h \
host.h \
internals.h \
link.h \
logging.h \
netutils.h \
nsscrypto.h \
onwire.h \
threads_common.h \
threads_dsthandler.h \
threads_heartbeat.h \
threads_pmtud.h \
threads_rx.h \
threads_tx.h \
transports.h
lib_LTLIBRARIES = libknet.la
libknet_la_SOURCES = $(sources)
-libknet_la_CFLAGS = $(nss_CFLAGS) $(zlib_CFLAGS) $(liblz4_CFLAGS)
+libknet_la_CFLAGS = $(nss_CFLAGS) $(zlib_CFLAGS) $(liblz4_CFLAGS) $(liblzma_CFLAGS)
EXTRA_libknet_la_DEPENDENCIES = $(SYMFILE)
libknet_la_LDFLAGS = -Wl,--version-script=$(srcdir)/$(SYMFILE) \
--export-dynamic \
-version-number $(libversion)
-libknet_la_LIBADD = $(nss_LIBS) $(zlib_LIBS) $(liblz4_LIBS) -llzo2 \
+libknet_la_LIBADD = $(nss_LIBS) $(zlib_LIBS) $(liblz4_LIBS) -llzo2 $(liblzma_LIBS) \
-lrt -lpthread -lm
diff --git a/libknet/compress.c b/libknet/compress.c
index b3b01767..8d0dd740 100644
--- a/libknet/compress.c
+++ b/libknet/compress.c
@@ -1,175 +1,177 @@
/*
* Copyright (C) 2010-2017 Red Hat, Inc. All rights reserved.
*
* Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
*
* This software licensed under GPL-2.0+, LGPL-2.0+
*/
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "internals.h"
#include "compress.h"
#include "logging.h"
#include "compress_zlib.h"
#include "compress_lz4.h"
#include "compress_lzo2.h"
+#include "compress_lzma.h"
/*
* internal module switch data
*/
/*
* DO NOT CHANGE ORDER HERE OR ONWIRE COMPATIBILITY
* WILL BREAK!
*
* always add before the last NULL/NULL/NULL.
*/
compress_model_t compress_modules_cmds[] = {
{ "none", NULL, NULL, NULL, NULL, NULL },
{ "zlib", NULL, NULL, zlib_val_level, zlib_compress, zlib_decompress },
{ "lz4", NULL, NULL, lz4_val_level, lz4_compress, lz4_decompress },
{ "lz4hc", NULL, NULL, lz4hc_val_level, lz4hc_compress, lz4_decompress },
{ "lzo2", lzo2_init, lzo2_fini, lzo2_val_level, lzo2_compress, lzo2_decompress },
+ { "lzma", NULL, NULL, lzma_val_level, lzma_compress, lzma_decompress },
{ NULL, NULL, NULL, NULL, NULL, NULL },
};
/*
* used exclusively by the test suite (see api_knet_send_compress)
*/
const char *get_model_by_idx(int idx)
{
return compress_modules_cmds[idx].model_name;
}
static int get_model(const char *model)
{
int idx = 0;
while (compress_modules_cmds[idx].model_name != NULL) {
if (!strcmp(compress_modules_cmds[idx].model_name, model))
return idx;
idx++;
}
return -1;
}
static int get_max_model(void)
{
int idx = 0;
while (compress_modules_cmds[idx].model_name != NULL) {
idx++;
}
return idx - 1;
}
static int val_level(
knet_handle_t knet_h,
int compress_model,
int compress_level)
{
return compress_modules_cmds[compress_model].val_level(knet_h, compress_level);
}
int compress_init(
knet_handle_t knet_h,
struct knet_handle_compress_cfg *knet_handle_compress_cfg)
{
int cmp_model, idx = 0;
knet_h->compress_max_model = get_max_model();
if (knet_h->compress_max_model > KNET_MAX_COMPRESS_METHODS) {
log_err(knet_h, KNET_SUB_COMPRESS, "Too many compress methods supported by compress.c. Please complain to knet developers to fix internals.h KNET_MAX_COMPRESS_METHODS define!");
errno = EINVAL;
return -1;
}
if (!knet_handle_compress_cfg) {
while (compress_modules_cmds[idx].model_name != NULL) {
if (compress_modules_cmds[idx].init != NULL) {
if (compress_modules_cmds[idx].init(knet_h, idx) < 0) {
log_err(knet_h, KNET_SUB_COMPRESS, "Failed to initialize %s library", compress_modules_cmds[idx].model_name);
errno = EINVAL;
return -1;
}
}
idx++;
}
return 0;
}
log_debug(knet_h, KNET_SUB_COMPRESS,
"Initizializing compress module [%s/%d/%u]",
knet_handle_compress_cfg->compress_model, knet_handle_compress_cfg->compress_level, knet_handle_compress_cfg->compress_threshold);
cmp_model = get_model(knet_handle_compress_cfg->compress_model);
if (cmp_model < 0) {
log_err(knet_h, KNET_SUB_COMPRESS, "compress model %s not supported", knet_handle_compress_cfg->compress_model);
errno = EINVAL;
return -1;
}
if (cmp_model > 0) {
if (val_level(knet_h, cmp_model, knet_handle_compress_cfg->compress_level) < 0) {
log_err(knet_h, KNET_SUB_COMPRESS, "compress level %d not supported for model %s",
knet_handle_compress_cfg->compress_level, knet_handle_compress_cfg->compress_model);
errno = EINVAL;
return -1;
}
if (knet_handle_compress_cfg->compress_threshold > KNET_MAX_PACKET_SIZE) {
log_err(knet_h, KNET_SUB_COMPRESS, "compress threshold cannot be higher than KNET_MAX_PACKET_SIZE (%d).",
KNET_MAX_PACKET_SIZE);
errno = EINVAL;
return -1;
}
if (knet_handle_compress_cfg->compress_threshold == 0) {
knet_h->compress_threshold = KNET_COMPRESS_THRESHOLD;
log_debug(knet_h, KNET_SUB_COMPRESS, "resetting compression threshold to default (%d)", KNET_COMPRESS_THRESHOLD);
} else {
knet_h->compress_threshold = knet_handle_compress_cfg->compress_threshold;
}
}
knet_h->compress_model = cmp_model;
knet_h->compress_level = knet_handle_compress_cfg->compress_level;
return 0;
}
void compress_fini(
knet_handle_t knet_h)
{
int idx = 0;
while ((compress_modules_cmds[idx].model_name != NULL) && (idx < KNET_MAX_COMPRESS_METHODS)) {
if (compress_modules_cmds[idx].fini != NULL) {
compress_modules_cmds[idx].fini(knet_h, idx);
}
idx++;
}
return;
}
int compress(
knet_handle_t knet_h,
const unsigned char *buf_in,
const ssize_t buf_in_len,
unsigned char *buf_out,
ssize_t *buf_out_len)
{
return compress_modules_cmds[knet_h->compress_model].compress(knet_h, buf_in, buf_in_len, buf_out, buf_out_len);
}
int decompress(
knet_handle_t knet_h,
int compress_model,
const unsigned char *buf_in,
const ssize_t buf_in_len,
unsigned char *buf_out,
ssize_t *buf_out_len)
{
return compress_modules_cmds[compress_model].decompress(knet_h, buf_in, buf_in_len, buf_out, buf_out_len);
}
diff --git a/libknet/compress_lzma.c b/libknet/compress_lzma.c
new file mode 100644
index 00000000..c9ec40bc
--- /dev/null
+++ b/libknet/compress_lzma.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2010-2017 Red Hat, Inc. All rights reserved.
+ *
+ * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ *
+ * This software licensed under GPL-2.0+, LGPL-2.0+
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <lzma.h>
+
+#include "internals.h"
+#include "compress_lzma.h"
+#include "logging.h"
+
+int lzma_val_level(
+ knet_handle_t knet_h,
+ int compress_level)
+{
+ if ((compress_level < 0) || (compress_level > 9)) {
+ log_err(knet_h, KNET_SUB_LZMACOMP, "lzma unsupported compression preset %d (accepted values from 0 to 9)", compress_level);
+ errno = EINVAL;
+ return -1;
+ }
+
+ return 0;
+}
+
+int lzma_compress(
+ knet_handle_t knet_h,
+ const unsigned char *buf_in,
+ const ssize_t buf_in_len,
+ unsigned char *buf_out,
+ ssize_t *buf_out_len)
+{
+ int err = 0;
+ int savederrno = 0;
+ size_t out_pos = 0;
+ lzma_ret ret = 0;
+
+ ret = lzma_easy_buffer_encode(knet_h->compress_level, LZMA_CHECK_NONE, NULL,
+ (const uint8_t *)buf_in, buf_in_len,
+ (uint8_t *)buf_out, &out_pos, KNET_DATABUFSIZE_COMPRESS);
+
+ switch(ret) {
+ case LZMA_OK:
+ *buf_out_len = out_pos;
+ break;
+ case LZMA_MEM_ERROR:
+ log_err(knet_h, KNET_SUB_LZMACOMP, "lzma compress memory allocation failed");
+ savederrno = ENOMEM;
+ err = -1;
+ break;
+ case LZMA_MEMLIMIT_ERROR:
+ log_err(knet_h, KNET_SUB_LZMACOMP, "lzma compress requires higher memory boundaries (see lzma_memlimit_set)");
+ savederrno = ENOMEM;
+ err = -1;
+ break;
+ case LZMA_PROG_ERROR:
+ log_err(knet_h, KNET_SUB_LZMACOMP, "lzma compress has been called with incorrect options");
+ savederrno = EINVAL;
+ err = -1;
+ break;
+ default:
+ log_err(knet_h, KNET_SUB_LZMACOMP, "lzma compress unknown error %u", ret);
+ savederrno = EINVAL;
+ err = -1;
+ break;
+ }
+
+ errno = savederrno;
+ return err;
+}
+
+int lzma_decompress(
+ knet_handle_t knet_h,
+ const unsigned char *buf_in,
+ const ssize_t buf_in_len,
+ unsigned char *buf_out,
+ ssize_t *buf_out_len)
+{
+ int err = 0;
+ int savederrno = 0;
+ uint64_t memlimit = UINT64_MAX; /* disable lzma internal memlimit check */
+ size_t out_pos = 0, in_pos = 0;
+ lzma_ret ret = 0;
+
+ ret = lzma_stream_buffer_decode(&memlimit, 0, NULL,
+ (const uint8_t *)buf_in, &in_pos, buf_in_len,
+ (uint8_t *)buf_out, &out_pos, KNET_DATABUFSIZE_COMPRESS);
+
+ switch(ret) {
+ case LZMA_OK:
+ *buf_out_len = out_pos;
+ break;
+ case LZMA_MEM_ERROR:
+ log_err(knet_h, KNET_SUB_LZMACOMP, "lzma decompress memory allocation failed");
+ savederrno = ENOMEM;
+ err = -1;
+ break;
+ case LZMA_MEMLIMIT_ERROR:
+ log_err(knet_h, KNET_SUB_LZMACOMP, "lzma decompress requires higher memory boundaries (see lzma_memlimit_set)");
+ savederrno = ENOMEM;
+ err = -1;
+ break;
+ case LZMA_DATA_ERROR:
+ case LZMA_FORMAT_ERROR:
+ log_err(knet_h, KNET_SUB_LZMACOMP, "lzma decompress invalid data received");
+ savederrno = EINVAL;
+ err = -1;
+ break;
+ case LZMA_PROG_ERROR:
+ log_err(knet_h, KNET_SUB_LZMACOMP, "lzma decompress has been called with incorrect options");
+ savederrno = EINVAL;
+ err = -1;
+ break;
+ default:
+ log_err(knet_h, KNET_SUB_LZMACOMP, "lzma decompress unknown error %u", ret);
+ savederrno = EINVAL;
+ err = -1;
+ break;
+ }
+
+ errno = savederrno;
+ return err;
+}
diff --git a/libknet/compress_lzma.h b/libknet/compress_lzma.h
new file mode 100644
index 00000000..c820a432
--- /dev/null
+++ b/libknet/compress_lzma.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2010-2017 Red Hat, Inc. All rights reserved.
+ *
+ * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ *
+ * This software licensed under GPL-2.0+, LGPL-2.0+
+ */
+
+#ifndef __KNET_COMPRESS_LZMA_H__
+#define __KNET_COMPRESS_LZMA_H__
+
+#include "internals.h"
+
+int lzma_val_level(
+ knet_handle_t knet_h,
+ int compress_level);
+
+int lzma_compress(
+ knet_handle_t knet_h,
+ const unsigned char *buf_in,
+ const ssize_t buf_in_len,
+ unsigned char *buf_out,
+ ssize_t *buf_out_len);
+
+int lzma_decompress(
+ knet_handle_t knet_h,
+ const unsigned char *buf_in,
+ const ssize_t buf_in_len,
+ unsigned char *buf_out,
+ ssize_t *buf_out_len);
+
+#endif
diff --git a/libknet/libknet.h b/libknet/libknet.h
index 0f002835..ac20abb0 100644
--- a/libknet/libknet.h
+++ b/libknet/libknet.h
@@ -1,1656 +1,1657 @@
/*
* Copyright (C) 2010-2015 Red Hat, Inc. All rights reserved.
*
* Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
* Federico Simoncelli <fsimon@kronosnet.org>
*
* This software licensed under GPL-2.0+, LGPL-2.0+
*/
#ifndef __LIBKNET_H__
#define __LIBKNET_H__
#include <stdint.h>
#include <time.h>
#include <netinet/in.h>
/*
* libknet limits
*/
/*
* Maximum number of hosts
*/
typedef uint16_t knet_node_id_t;
#define KNET_MAX_HOST 65536
/*
* Maximum number of links between 2 hosts
*/
#define KNET_MAX_LINK 8
/*
* Maximum packet size that should be written to datafd
* see knet_handle_new for details
*/
#define KNET_MAX_PACKET_SIZE 65536
/*
* Buffers used for pretty logging
* host is used to store both ip addresses and hostnames
*/
#define KNET_MAX_HOST_LEN 256
#define KNET_MAX_PORT_LEN 6
/*
* Some notifications can be generated either on TX or RX
*/
#define KNET_NOTIFY_TX 0
#define KNET_NOTIFY_RX 1
/*
* Link flags
*/
/*
* Where possible, set traffic priority to high.
* On Linux this sets the TOS to INTERACTIVE (6),
* see tc-prio(8) for more infomation
*/
#define KNET_LINK_FLAG_TRAFFICHIPRIO (1ULL << 0)
typedef struct knet_handle *knet_handle_t;
/*
* Handle structs/API calls
*/
/*
* knet_handle_new
*
* host_id - Each host in a knet is identified with a unique
* ID. when creating a new handle local host_id
* must be specified (0 to UINT16T_MAX are all valid).
* It is the user's responsibility to check that the value
* is unique, or bad things might happen.
*
* log_fd - Write file descriptor. If set to a value > 0, it will be used
* to write log packets (see below) from libknet to the application.
* Setting to 0 will disable logging from libknet.
* It is possible to enable logging at any given time (see logging API
* below).
* Make sure to either read from this filedescriptor properly and/or
* mark it O_NONBLOCK, otherwise if the fd becomes full, libknet could
* block.
*
* default_log_level -
* If logfd is specified, it will initialize all subsystems to log
* at default_log_level value. (see logging API below)
*
* on success, a new knet_handle_t is returned.
* on failure, NULL is returned and errno is set.
*/
knet_handle_t knet_handle_new(knet_node_id_t host_id,
int log_fd,
uint8_t default_log_level);
/*
* knet_handle_free
*
* knet_h - pointer to knet_handle_t
*
* Destroy a knet handle, free all resources
*
* knet_handle_free returns:
*
* 0 on success
* -1 on error and errno is set.
*/
int knet_handle_free(knet_handle_t knet_h);
/*
* knet_handle_enable_sock_notify
*
* knet_h - pointer to knet_handle_t
*
* sock_notify_fn_private_data
* void pointer to data that can be used to identify
* the callback.
*
* sock_notify_fn
* A callback function that is invoked every time
* a socket in the datafd pool will report an error (-1)
* or an end of read (0) (see socket.7).
* This function MUST NEVER block or add substantial delays.
* The callback is invoked in an internal unlocked area
* to allow calls to knet_handle_add_datafd/knet_handle_remove_datafd
* to swap/replace the bad fd.
* if both err and errno are 0, it means that the socket
* has received a 0 byte packet (EOF?).
* The callback function must either remove the fd from knet
* (by calling knet_handle_remove_fd()) or dup a new fd in its place.
* Failure to do this can cause problems.
*
* knet_handle_enable_sock_notify returns:
*
* 0 on success
* -1 on error and errno is set.
*/
int knet_handle_enable_sock_notify(knet_handle_t knet_h,
void *sock_notify_fn_private_data,
void (*sock_notify_fn) (
void *private_data,
int datafd,
int8_t channel,
uint8_t tx_rx,
int error,
int errorno)); /* sorry! can't call it errno ;) */
/*
* knet_handle_add_datafd
*
* IMPORTANT: In order to add datafd to knet, knet_handle_enable_sock_notify
* _MUST_ be set and be able to handle both errors (-1) and
* 0 bytes read / write from the provided datafd.
* On read error (< 0) from datafd, the socket is automatically
* removed from polling to avoid spinning on dead sockets.
* It is safe to call knet_handle_remove_datafd even on sockets
* that have been removed.
*
* knet_h - pointer to knet_handle_t
*
* *datafd - read/write file descriptor.
* knet will read data here to send to the other hosts
* and will write data received from the network.
* Each data packet can be of max size KNET_MAX_PACKET_SIZE!
* Applications using knet_send/knet_recv will receive a
* proper error if the packet size is not within boundaries.
* Applications using their own functions to write to the
* datafd should NOT write more than KNET_MAX_PACKET_SIZE.
*
* Please refer to handle.c on how to set up a socketpair.
*
* datafd can be 0, and knet_handle_add_datafd will create a properly
* populated socket pair the same way as ping_test, or a value
* higher than 0. A negative number will return an error.
* On exit knet_handle_free will take care to cleanup the
* socketpair only if they have been created by knet_handle_add_datafd.
*
* It is possible to pass either sockets or normal fds.
* User provided datafd will be marked as non-blocking and close-on-exit.
*
* *channel - This value has the same effect of VLAN tagging.
* A negative value will auto-allocate a channel.
* Setting a value between 0 and 31 will try to allocate that
* specific channel (unless already in use).
*
* It is possible to add up to 32 datafds but be aware that each
* one of them must have a receiving end on the other host.
*
* Example:
* hostA channel 0 will be delivered to datafd on hostB channel 0
* hostA channel 1 to hostB channel 1.
*
* Each channel must have a unique file descriptor.
*
* If your application could have 2 channels on one host and one
* channel on another host, then you can use dst_host_filter
* to manipulate channel values on TX and RX.
*
* knet_handle_add_datafd returns:
*
* 0 on success
* *datafd will be populated with a socket if the original value was 0
* or if a specific fd was set, the value is untouched.
* *channel will be populated with a channel number if the original value
* was negative or the value is untouched if a specific channel
* was requested.
*
* -1 on error and errno is set.
* *datafd and *channel are untouched or empty.
*/
#define KNET_DATAFD_MAX 32
int knet_handle_add_datafd(knet_handle_t knet_h, int *datafd, int8_t *channel);
/*
* knet_handle_remove_datafd
*
* knet_h - pointer to knet_handle_t
*
* datafd - file descriptor to remove.
* NOTE that if the socket/fd was created by knet_handle_add_datafd,
* the socket will be closed by libknet.
*
* knet_handle_remove_datafd returns:
*
* 0 on success
*
* -1 on error and errno is set.
*/
int knet_handle_remove_datafd(knet_handle_t knet_h, int datafd);
/*
* knet_handle_get_channel
*
* knet_h - pointer to knet_handle_t
*
* datafd - get the channel associated to this datafd
*
* *channel - will contain the result
*
* knet_handle_get_channel returns:
*
* 0 on success
* and *channel will contain the result
*
* -1 on error and errno is set.
* and *channel content is meaningless
*/
int knet_handle_get_channel(knet_handle_t knet_h, const int datafd, int8_t *channel);
/*
* knet_handle_get_datafd
*
* knet_h - pointer to knet_handle_t
*
* channel - get the datafd associated to this channel
*
* *datafd - will contain the result
*
* knet_handle_get_datafd returns:
*
* 0 on success
* and *datafd will contain the results
*
* -1 on error and errno is set.
* and *datafd content is meaningless
*/
int knet_handle_get_datafd(knet_handle_t knet_h, const int8_t channel, int *datafd);
/*
* knet_recv
*
* knet_h - pointer to knet_handle_t
*
* buff - pointer to buffer to store the received data
*
* buff_len - buffer lenght
*
* knet_recv is a commodity function to wrap iovec operations
* around a socket. It returns a call to readv(2).
*/
ssize_t knet_recv(knet_handle_t knet_h,
char *buff,
const size_t buff_len,
const int8_t channel);
/*
* knet_send
*
* knet_h - pointer to knet_handle_t
*
* buff - pointer to the buffer of data to send
*
* buff_len - length of data to send
*
* knet_send is a commodity function to wrap iovec operations
* around a socket. It returns a call to writev(2).
*/
ssize_t knet_send(knet_handle_t knet_h,
const char *buff,
const size_t buff_len,
const int8_t channel);
/*
* knet_send_sync
*
* knet_h - pointer to knet_handle_t
*
* buff - pointer to the buffer of data to send
*
* buff_len - length of data to send
*
* channel - data channel to use (see knet_handle_add_datafd)
*
* All knet RX/TX operations are async for performance reasons.
* There are applications that might need a sync version of data
* transmission and receive errors in case of failure to deliver
* to another host.
* knet_send_sync bypasses the whole TX async layer and delivers
* data directly to the link layer, and returns errors accordingly.
* knet_send_sync allows to send only one packet to one host at
* a time. It does NOT support multiple destinations or multicast
* packets. Decision is still based on dst_host_filter_fn.
*
* knet_send_sync returns 0 on success and -1 on error.
*
* In addition to normal sendmmsg errors, knet_send_sync can fail
* due to:
*
* ECANCELED - data forward is disabled
* EFAULT - dst_host_filter fatal error
* EINVAL - dst_host_filter did not provide
* dst_host_ids_entries on unicast pckts
* E2BIG - dst_host_filter did return more than one
* dst_host_ids_entries on unicast pckts
* ENOMSG - received unknown message type
* EHOSTDOWN - unicast pckt cannot be delivered because
* dest host is not connected yet
* ECHILD - crypto failed
* EAGAIN - sendmmsg was unable to send all messages and
* there was no progress during retry
*/
int knet_send_sync(knet_handle_t knet_h,
const char *buff,
const size_t buff_len,
const int8_t channel);
/*
* knet_handle_enable_filter
*
* knet_h - pointer to knet_handle_t
*
* dst_host_filter_fn_private_data
* void pointer to data that can be used to identify
* the callback.
*
* dst_host_filter_fn -
* is a callback function that is invoked every time
* a packet hits datafd (see knet_handle_new).
* the function allows users to tell libknet where the
* packet has to be delivered.
*
* const unsigned char *outdata - is a pointer to the
* current packet
* ssize_t outdata_len - lenght of the above data
* uint8_t tx_rx - filter is called on tx or rx
* (see defines below)
* knet_node_id_t this_host_id - host_id processing the packet
* knet_node_id_t src_host_id - host_id that generated the
* packet
* knet_node_id_t *dst_host_ids - array of KNET_MAX_HOST knet_node_id_t
* where to store the destinations
* size_t *dst_host_ids_entries - number of hosts to send the message
*
* dst_host_filter_fn should return
* -1 on error, packet is discarded.
* 0 packet is unicast and should be sent to dst_host_ids and there are
* dst_host_ids_entries in the buffer.
* 1 packet is broadcast/multicast and is sent all hosts.
* contents of dst_host_ids and dst_host_ids_entries are ignored.
* (see also kronosnetd/etherfilter.* for an example that filters based
* on ether protocol)
*
* knet_handle_enable_filter returns:
*
* 0 on success
* -1 on error and errno is set.
*/
int knet_handle_enable_filter(knet_handle_t knet_h,
void *dst_host_filter_fn_private_data,
int (*dst_host_filter_fn) (
void *private_data,
const unsigned char *outdata,
ssize_t outdata_len,
uint8_t tx_rx,
knet_node_id_t this_host_id,
knet_node_id_t src_host_id,
int8_t *channel,
knet_node_id_t *dst_host_ids,
size_t *dst_host_ids_entries));
/*
* knet_handle_setfwd
*
* knet_h - pointer to knet_handle_t
*
* enable - set to 1 to allow data forwarding, 0 to disable data forwarding.
*
* knet_handle_setfwd returns:
*
* 0 on success
* -1 on error and errno is set.
*
* By default data forwarding is off and no traffic will pass through knet until
* it is set on.
*/
int knet_handle_setfwd(knet_handle_t knet_h, unsigned int enabled);
/*
* knet_handle_pmtud_setfreq
*
* knet_h - pointer to knet_handle_t
*
* interval - define the interval in seconds between PMTUd scans
* range from 1 to 86400 (24h)
*
* knet_handle_pmtud_setfreq returns:
*
* 0 on success
* -1 on error and errno is set.
*
* default interval is 60.
*/
#define KNET_PMTUD_DEFAULT_INTERVAL 60
int knet_handle_pmtud_setfreq(knet_handle_t knet_h, unsigned int interval);
/*
* knet_handle_pmtud_getfreq
*
* knet_h - pointer to knet_handle_t
*
* interval - pointer where to store the current interval value
*
* knet_handle_pmtud_setfreq returns:
*
* 0 on success
* -1 on error and errno is set.
*/
int knet_handle_pmtud_getfreq(knet_handle_t knet_h, unsigned int *interval);
/*
* knet_handle_enable_pmtud_notify
*
* knet_h - pointer to knet_handle_t
*
* pmtud_notify_fn_private_data
* void pointer to data that can be used to identify
* the callback.
*
* pmtud_notify_fn
* is a callback function that is invoked every time
* a path MTU size change is detected.
* The function allows libknet to notify the user
* of data MTU, that's the max value that can be send
* onwire without fragmentation. The data MTU will always
* be lower than real link MTU because it accounts for
* protocol overhead, knet packet header and (if configured)
* crypto overhead,
* This function MUST NEVER block or add substantial delays.
*
* knet_handle_enable_pmtud_notify returns:
*
* 0 on success
* -1 on error and errno is set.
*/
int knet_handle_enable_pmtud_notify(knet_handle_t knet_h,
void *pmtud_notify_fn_private_data,
void (*pmtud_notify_fn) (
void *private_data,
unsigned int data_mtu));
/*
* knet_handle_pmtud_get
*
* knet_h - pointer to knet_handle_t
*
* data_mtu - pointer where to store data_mtu (see above)
*
* knet_handle_pmtud_get returns:
*
* 0 on success
* -1 on error and errno is set.
*/
int knet_handle_pmtud_get(knet_handle_t knet_h,
unsigned int *data_mtu);
/*
* knet_handle_crypto
*
* knet_h - pointer to knet_handle_t
*
* knet_handle_crypto_cfg -
* pointer to a knet_handle_crypto_cfg structure
*
* crypto_model should contain the model name.
* Currently only "nss" is supported.
* Setting to "none" will disable crypto.
*
* crypto_cipher_type
* should contain the cipher algo name.
* It can be set to "none" to disable
* encryption.
* Currently supported by "nss" model:
* "3des", "aes128", "aes192" and "aes256".
*
* crypto_hash_type
* should contain the hashing algo name.
* It can be set to "none" to disable
* hashing.
* Currently supported by "nss" model:
* "md5", "sha1", "sha256", "sha384" and "sha512".
*
* private_key will contain the private shared key.
* It has to be at least KNET_MIN_KEY_LEN long.
*
* private_key_len
* length of the provided private_key.
*
* Implementation notes/current limitations:
* - enabling crypto, will increase latency as packets have
* to processed.
* - enabling crypto might reduce the overall throughtput
* due to crypto data overhead.
* - re-keying is not implemented yet.
* - private/public key encryption/hashing is not currently
* planned.
* - crypto key must be the same for all hosts in the same
* knet instance.
* - it is safe to call knet_handle_crypto multiple times at runtime.
* The last config will be used.
* IMPORTANT: a call to knet_handle_crypto can fail due to:
* 1) failure to obtain locking
* 2) errors to initializing the crypto level.
* This can happen even in subsequent calls to knet_handle_crypto.
* A failure in crypto init, might leave your traffic unencrypted!
* It's best to stop data forwarding (see above), change crypto config,
* start forward again.
*
* knet_handle_crypto returns:
*
* 0 on success
* -1 on error and errno is set.
* -2 on crypto subsystem initialization error. No errno is provided at the moment (yet).
*/
#define KNET_MIN_KEY_LEN 256
#define KNET_MAX_KEY_LEN 4096
struct knet_handle_crypto_cfg {
char crypto_model[16];
char crypto_cipher_type[16];
char crypto_hash_type[16];
unsigned char private_key[KNET_MAX_KEY_LEN];
unsigned int private_key_len;
};
int knet_handle_crypto(knet_handle_t knet_h,
struct knet_handle_crypto_cfg *knet_handle_crypto_cfg);
/*
* knet_handle_compress
*
* knet_h - pointer to knet_handle_t
*
* knet_handle_compress_cfg -
* pointer to a knet_handle_compress_cfg structure
*
* compress_model should contain the mode name.
* Currently only "zlib" and "lz4" are supported.
* Setting to "none" will disable compress.
*
* compress_threshold
* tells the transmission thread to NOT compress
* any packets that are smaller than the value
* indicated. Default 100 bytes.
* Set to 0 to reset to the default.
* Set to 1 to compress everything.
* Max accepted value is KNET_MAX_PACKET_SIZE.
*
* compress_level some compression libraries allows tuning of compression
* parameters.
* For example zlib value ranges from 0 to 9 where 0 is no
* compression and 9 is max compression.
* This value is passed pristine to the compression library.
* zlib: 0 (no compression), 1 (minimal) .. 9 (max compression).
* lz4: 1 (max compression)... 9 (fastest compression).
* lz4hc: 1 (min compression) ... LZ4HC_MAX_CLEVEL (16) or LZ4HC_CLEVEL_MAX (12)
* depends on the installed version of lz4hc. libknet can detects the max
* value and will print an appropriate warning.
* lzo2: accepts only some specific values depending on the
* requested algorithm:
* 1 : lzo1x_1_compress (default)
* 11 : lzo1x_1_11_compress
* 12 : lzo1x_1_12_compress
* 15 : lzo1x_1_15_compress
* 999: lzo1x_999_compress
* every other values will use default
* Please refere to the library man pages
* on how to be set this value, as it is passed
* unmodified to the compression algorithm where supported.
*
* Implementation notes:
* - it is possible to enable/disable compression at any time.
* - nodes can be using different compression algorithm at any time.
* - knet does NOT implement compression algorithm directly. it relies
* on external libraries for this functionality. Please read
* the libraries man pages to figure out which algorithm/compression
* level is best for the data you are planning to transmit.
*
* knet_handle_compress returns:
*
* 0 on success
* -1 on error and errno is set. EINVAL means that either the model or the
* level are not supported.
*/
#define KNET_COMPRESS_THRESHOLD 100
struct knet_handle_compress_cfg {
char compress_model[16];
uint32_t compress_threshold;
int compress_level;
};
int knet_handle_compress(knet_handle_t knet_h,
struct knet_handle_compress_cfg *knet_handle_compress_cfg);
/*
* host structs/API calls
*/
/*
* knet_host_add
*
* knet_h - pointer to knet_handle_t
*
* host_id - each host in a knet is identified with a unique ID
* (see also knet_handle_new documentation above)
*
* knet_host_add returns:
*
* 0 on success
* -1 on error and errno is set.
*/
int knet_host_add(knet_handle_t knet_h, knet_node_id_t host_id);
/*
* knet_host_remove
*
* knet_h - pointer to knet_handle_t
*
* host_id - each host in a knet is identified with a unique ID
* (see also knet_handle_new documentation above)
*
* knet_host_remove returns:
*
* 0 on success
* -1 on error and errno is set.
*/
int knet_host_remove(knet_handle_t knet_h, knet_node_id_t host_id);
/*
* knet_host_set_name
*
* knet_h - pointer to knet_handle_t
*
* host_id - see above
*
* name - this name will be used for pretty logging and eventually
* search for hosts (see also get_name and get_id below).
* Only up to KNET_MAX_HOST_LEN - 1 bytes will be accepted and
* name has to be unique for each host.
*
* knet_host_set_name returns:
*
* 0 on success
* -1 on error and errno is set.
*/
int knet_host_set_name(knet_handle_t knet_h, knet_node_id_t host_id,
const char *name);
/*
* knet_host_get_name_by_host_id
*
* knet_h - pointer to knet_handle_t
*
* host_id - see above
*
* name - pointer to a preallocated buffer of at least size KNET_MAX_HOST_LEN
* where the current host name will be stored
* (as set by knet_host_set_name or default by knet_host_add)
*
* knet_host_get_name_by_host_id returns:
*
* 0 on success
* -1 on error and errno is set (name is left untouched)
*/
int knet_host_get_name_by_host_id(knet_handle_t knet_h, knet_node_id_t host_id,
char *name);
/*
* knet_host_get_id_by_host_name
*
* knet_h - pointer to knet_handle_t
*
* name - name to lookup, max len KNET_MAX_HOST_LEN
*
* host_id - where to store the result
*
* knet_host_get_id_by_host_name returns:
*
* 0 on success
* -1 on error and errno is set.
*/
int knet_host_get_id_by_host_name(knet_handle_t knet_h, const char *name,
knet_node_id_t *host_id);
/*
* knet_host_get_host_list
*
* knet_h - pointer to knet_handle_t
*
* host_ids - array of at lest KNET_MAX_HOST size
*
* host_ids_entries -
* number of entries writted in host_ids
*
* knet_host_get_host_list returns:
*
* 0 on success
* -1 on error and errno is set.
*/
int knet_host_get_host_list(knet_handle_t knet_h,
knet_node_id_t *host_ids, size_t *host_ids_entries);
/*
* define switching policies
*/
#define KNET_LINK_POLICY_PASSIVE 0
#define KNET_LINK_POLICY_ACTIVE 1
#define KNET_LINK_POLICY_RR 2
/*
* knet_host_set_policy
*
* knet_h - pointer to knet_handle_t
*
* host_id - see above
*
* policy - there are currently 3 kind of simple switching policies
* as defined above, based on link configuration.
* KNET_LINK_POLICY_PASSIVE - the active link with the lowest
* priority will be used.
* if one or more active links share
* the same priority, the one with
* lowest link_id will be used.
*
* KNET_LINK_POLICY_ACTIVE - all active links will be used
* simultaneously to send traffic.
* link priority is ignored.
*
* KNET_LINK_POLICY_RR - round-robin policy, every packet
* will be send on a different active
* link.
*
* knet_host_set_policy returns:
*
* 0 on success
* -1 on error and errno is set.
*/
int knet_host_set_policy(knet_handle_t knet_h, knet_node_id_t host_id,
uint8_t policy);
/*
* knet_host_get_policy
*
* knet_h - pointer to knet_handle_t
*
* host_id - see above
*
* policy - will contain the current configured switching policy.
* Default is passive when creating a new host.
*
* knet_host_get_policy returns:
*
* 0 on success
* -1 on error and errno is set.
*/
int knet_host_get_policy(knet_handle_t knet_h, knet_node_id_t host_id,
uint8_t *policy);
/*
* knet_host_enable_status_change_notify
*
* knet_h - pointer to knet_handle_t
*
* host_status_change_notify_fn_private_data
* void pointer to data that can be used to identify
* the callback.
*
* host_status_change_notify_fn
* is a callback function that is invoked every time
* there is a change in the host status.
* host status is identified by:
* - reachable, this host can send/receive data to/from host_id
* - remote, 0 if the host_id is connected locally or 1 if
* the there is one or more knet host(s) in between.
* NOTE: re-switching is NOT currently implemented,
* but this is ready for future and can avoid
* an API/ABI breakage later on.
* - external, 0 if the host_id is configured locally or 1 if
* it has been added from remote nodes config.
* NOTE: dynamic topology is NOT currently implemented,
* but this is ready for future and can avoid
* an API/ABI breakage later on.
* This function MUST NEVER block or add substantial delays.
*
* knet_host_status_change_notify returns:
*
* 0 on success
* -1 on error and errno is set.
*/
int knet_host_enable_status_change_notify(knet_handle_t knet_h,
void *host_status_change_notify_fn_private_data,
void (*host_status_change_notify_fn) (
void *private_data,
knet_node_id_t host_id,
uint8_t reachable,
uint8_t remote,
uint8_t external));
/*
* define host status structure for quick lookup
* struct is in flux as more stats will be added soon
*
* reachable host_id can be seen either directly connected
* or via another host_id
*
* remote 0 = node is connected locally, 1 is visible via
* via another host_id
*
* external 0 = node is configured/known locally,
* 1 host_id has been received via another host_id
*/
struct knet_host_status {
uint8_t reachable;
uint8_t remote;
uint8_t external;
/* add host statistics */
};
/*
* knet_host_status_get
*
* knet_h - pointer to knet_handle_t
*
* status - pointer to knet_host_status struct (see above)
*
* knet_handle_pmtud_get returns:
*
* 0 on success
* -1 on error and errno is set.
*/
int knet_host_get_status(knet_handle_t knet_h, knet_node_id_t host_id,
struct knet_host_status *status);
/*
* link structs/API calls
*
* every host allocated/managed by knet_host_* has
* KNET_MAX_LINK structures to define the network
* paths that connect 2 hosts.
*
* Each link is identified by a link_id that has a
* values between 0 and KNET_MAX_LINK - 1.
*
* KNOWN LIMITATIONS:
*
* - let's assume the scenario where two hosts are connected
* with any number of links. link_id must match on both sides.
* If host_id 0 link_id 0 is configured to connect IP1 to IP2 and
* host_id 0 link_id 1 is configured to connect IP3 to IP4,
* host_id 1 link_id 0 _must_ connect IP2 to IP1 and likewise
* host_id 1 link_id 1 _must_ connect IP4 to IP3.
* We might be able to lift this restriction in future, by using
* other data to determine src/dst link_id, but for now, deal with it.
*/
/*
* commodity functions to convert strings to sockaddr and viceversa
*/
/*
* knet_strtoaddr
*
* host - IPaddr/hostname to convert
* be aware only the first IP address will be returned
* in case a hostname resolves to multiple IP
*
* port - port to connect to
*
* ss - sockaddr_storage where to store the converted data
*
* sslen - len of the sockaddr_storage
*
* knet_strtoaddr returns same error codes as getaddrinfo
*
*/
int knet_strtoaddr(const char *host, const char *port,
struct sockaddr_storage *ss, socklen_t sslen);
/*
* knet_addrtostr
*
* ss - sockaddr_storage to convert
*
* sslen - len of the sockaddr_storage
*
* host - IPaddr/hostname where to store data
* (recommended size: KNET_MAX_HOST_LEN)
*
* port - port buffer where to store data
* (recommended size: KNET_MAX_PORT_LEN)
*
* knet_strtoaddr returns same error codes as getnameinfo
*/
int knet_addrtostr(const struct sockaddr_storage *ss, socklen_t sslen,
char *addr_buf, size_t addr_buf_size,
char *port_buf, size_t port_buf_size);
/*
* knet_handle_get_transport_list
*
* knet_h - pointer to knet_handle_t
*
* transport_list - an array of struct transport_info that must be
* at least of size struct transport_info * KNET_MAX_TRANSPORTS
*
* transport_list_entries - pointer to a size_t where to store how many transports
* are available in this build of libknet.
*
* knet_handle_get_transport_list returns:
*
* 0 on success
* -1 on error and errno is set.
*/
#define KNET_TRANSPORT_LOOPBACK 0
#define KNET_TRANSPORT_UDP 1
#define KNET_TRANSPORT_SCTP 2
#define KNET_MAX_TRANSPORTS 3
/*
* The Loopback transport is only valid for connections to localhost, the host
* with the same node_id specified in knet_handle_new(). Only one link of this
* type is allowed. Data sent down a LOOPBACK link will be copied directly from
* the knet send datafd to the knet receive datafd so the application must be set
* up to take data from that socket at least as often as it is sent or deadlocks
* could occur. If used, a LOOPBACK link must be the only link configured to the
* local host.
*/
struct transport_info {
const char *name; /* UDP/SCTP/etc... */
uint8_t id; /* value that can be used for link_set_config */
uint8_t properties; /* currently unused */
};
int knet_handle_get_transport_list(knet_handle_t knet_h,
struct transport_info *transport_list, size_t *transport_list_entries);
/*
* knet_handle_get_transport_name_by_id
*
* knet_h - pointer to knet_handle_t
*
* transport - one of the above KNET_TRANSPORT_xxx constants
*
* knet_handle_get_transport_name_by_id returns:
*
* pointer to the name on success or
* NULL on error and errno is set.
*/
const char *knet_handle_get_transport_name_by_id(knet_handle_t knet_h, uint8_t transport);
/*
* knet_handle_get_transport_id_by_name
*
* knet_h - pointer to knet_handle_t
*
* name - transport name (UDP/SCTP/etc)
*
* knet_handle_get_transport_name_by_id returns:
*
* KNET_MAX_TRANSPORTS on error and errno is set accordingly
* KNET_TRANSPORT_xxx on success.
*/
uint8_t knet_handle_get_transport_id_by_name(knet_handle_t knet_h, const char *name);
/*
* knet_handle_set_transport_reconnect_interval
*
* knet_h - pointer to knet_handle_t
*
* msecs - milliseconds
*
* knet_handle_set_transport_reconnect_interval returns:
*
* 0 on success
* -1 on error and errno is set.
*/
#define KNET_TRANSPORT_DEFAULT_RECONNECT_INTERVAL 1000
int knet_handle_set_transport_reconnect_interval(knet_handle_t knet_h, uint32_t msecs);
/*
* knet_handle_get_transport_reconnect_interval
*
* knet_h - pointer to knet_handle_t
*
* msecs - milliseconds
*
* knet_handle_get_transport_reconnect_interval returns:
*
* 0 on success
* -1 on error and errno is set.
*/
int knet_handle_get_transport_reconnect_interval(knet_handle_t knet_h, uint32_t *msecs);
/*
* knet_link_set_config
*
* knet_h - pointer to knet_handle_t
*
* host_id - see above
*
* link_id - see above
*
* transport - one of the above KNET_TRANSPORT_xxx constants
*
* src_addr - sockaddr_storage that can be either IPv4 or IPv6
*
* dst_addr - sockaddr_storage that can be either IPv4 or IPv6
* this can be null if we don't know the incoming
* IP address/port and the link will remain quiet
* till the node on the other end will initiate a
* connection
*
* flags - KNET_LINK_FLAG_*
*
* knet_link_set_config returns:
*
* 0 on success
* -1 on error and errno is set.
*/
int knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
uint8_t transport,
struct sockaddr_storage *src_addr,
struct sockaddr_storage *dst_addr,
uint64_t flags);
/*
* knet_link_get_config
*
* knet_h - pointer to knet_handle_t
*
* host_id - see above
*
* link_id - see above
*
* transport - see above
*
* src_addr - sockaddr_storage that can be either IPv4 or IPv6
*
* dst_addr - sockaddr_storage that can be either IPv4 or IPv6
*
* dynamic - 0 if dst_addr is static or 1 if dst_addr is dynamic.
* In case of 1, dst_addr can be NULL and it will be left
* untouched.
*
* flags - KNET_LINK_FLAG_*
*
* knet_link_get_config returns:
*
* 0 on success.
* -1 on error and errno is set.
*/
int knet_link_get_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
uint8_t *transport,
struct sockaddr_storage *src_addr,
struct sockaddr_storage *dst_addr,
uint8_t *dynamic,
uint64_t *flags);
/*
* knet_link_clear_config
*
* knet_h - pointer to knet_handle_t
*
* host_id - see above
*
* link_id - see above
*
* knet_link_clear_config returns:
*
* 0 on success.
* -1 on error and errno is set.
*/
int knet_link_clear_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id);
/*
* knet_link_set_enable
*
* knet_h - pointer to knet_handle_t
*
* host_id - see above
*
* link_id - see above
*
* enabled - 0 disable the link, 1 enable the link
*
* knet_link_set_enable returns:
*
* 0 on success
* -1 on error and errno is set.
*/
int knet_link_set_enable(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
unsigned int enabled);
/*
* knet_link_get_enable
*
* knet_h - pointer to knet_handle_t
*
* host_id - see above
*
* link_id - see above
*
* enabled - 0 disable the link, 1 enable the link
*
* knet_link_get_enable returns:
*
* 0 on success
* -1 on error and errno is set.
*/
int knet_link_get_enable(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
unsigned int *enabled);
/*
* knet_link_set_ping_timers
*
* knet_h - pointer to knet_handle_t
*
* host_id - see above
*
* link_id - see above
*
* interval - specify the ping interval
*
* timeout - if no pong is received within this time,
* the link is declared dead
*
* precision - how many values of latency are used to calculate
* the average link latency (see also get_status below)
*
* knet_link_set_ping_timers returns:
*
* 0 on success
* -1 on error and errno is set.
*/
#define KNET_LINK_DEFAULT_PING_INTERVAL 1000 /* 1 second */
#define KNET_LINK_DEFAULT_PING_TIMEOUT 2000 /* 2 seconds */
#define KNET_LINK_DEFAULT_PING_PRECISION 2048 /* samples */
int knet_link_set_ping_timers(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
time_t interval, time_t timeout, unsigned int precision);
/*
* knet_link_get_ping_timers
*
* knet_h - pointer to knet_handle_t
*
* host_id - see above
*
* link_id - see above
*
* interval - ping intervall
*
* timeout - if no pong is received within this time,
* the link is declared dead
*
* precision - how many values of latency are used to calculate
* the average link latency (see also get_status below)
*
* knet_link_get_ping_timers returns:
*
* 0 on success
* -1 on error and errno is set.
*/
int knet_link_get_ping_timers(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
time_t *interval, time_t *timeout, unsigned int *precision);
/*
* knet_link_set_pong_count
*
* knet_h - pointer to knet_handle_t
*
* host_id - see above
*
* link_id - see above
*
* pong_count - how many valid ping/pongs before a link is marked UP.
* default: 5, value should be > 0
*
* knet_link_set_pong_count returns:
*
* 0 on success
* -1 on error and errno is set.
*/
#define KNET_LINK_DEFAULT_PONG_COUNT 5
int knet_link_set_pong_count(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
uint8_t pong_count);
/*
* knet_link_get_pong_count
*
* knet_h - pointer to knet_handle_t
*
* host_id - see above
*
* link_id - see above
*
* pong_count - see above
*
* knet_link_get_pong_count returns:
*
* 0 on success
* -1 on error and errno is set.
*/
int knet_link_get_pong_count(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
uint8_t *pong_count);
/*
* knet_link_set_priority
*
* knet_h - pointer to knet_handle_t
*
* host_id - see above
*
* link_id - see above
*
* priority - specify the switching priority for this link
* see also knet_host_set_policy
*
* knet_link_set_priority returns:
*
* 0 on success
* -1 on error and errno is set.
*/
int knet_link_set_priority(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
uint8_t priority);
/*
* knet_link_get_priority
*
* knet_h - pointer to knet_handle_t
*
* host_id - see above
*
* link_id - see above
*
* priority - gather the switching priority for this link
* see also knet_host_set_policy
*
* knet_link_get_priority returns:
*
* 0 on success
* -1 on error and errno is set.
*/
int knet_link_get_priority(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
uint8_t *priority);
/*
* knet_link_get_link_list
*
* knet_h - pointer to knet_handle_t
*
* link_ids - array of at lest KNET_MAX_LINK size
* with the list of configured links for a certain host.
*
* link_ids_entries -
* number of entries contained in link_ids
*
* knet_link_get_link_list returns:
*
* 0 on success
* -1 on error and errno is set.
*/
int knet_link_get_link_list(knet_handle_t knet_h, knet_node_id_t host_id,
uint8_t *link_ids, size_t *link_ids_entries);
/*
* define link status structure for quick lookup
*
* src/dst_{ipaddr,port} strings are filled by
* getnameinfo(3) when configuring the link.
* if the link is dynamic (see knet_link_set_config)
* dst_ipaddr/port will contain ipaddr/port of the currently
* connected peer or "Unknown" if it was not possible
* to determine the ipaddr/port at runtime.
*
* enabled see also knet_link_set/get_enable.
*
* connected the link is connected to a peer and ping/pong traffic
* is flowing.
*
* dynconnected the link has dynamic ip on the other end, and
* we can see the other host is sending pings to us.
*
* latency average latency of this link
* see also knet_link_set/get_timeout.
*
* pong_last if the link is down, this value tells us how long
* ago this link was active. A value of 0 means that the link
* has never been active.
*
* knet_link_stats structure that contains details statistics for the link
*/
#define MAX_LINK_EVENTS 16
struct knet_link_stats {
/* onwire values */
uint64_t tx_data_packets;
uint64_t rx_data_packets;
uint64_t tx_data_bytes;
uint64_t rx_data_bytes;
uint64_t rx_ping_packets;
uint64_t tx_ping_packets;
uint64_t rx_ping_bytes;
uint64_t tx_ping_bytes;
uint64_t rx_pong_packets;
uint64_t tx_pong_packets;
uint64_t rx_pong_bytes;
uint64_t tx_pong_bytes;
uint64_t rx_pmtu_packets;
uint64_t tx_pmtu_packets;
uint64_t rx_pmtu_bytes;
uint64_t tx_pmtu_bytes;
/* Only filled in when requested */
uint64_t tx_total_packets;
uint64_t rx_total_packets;
uint64_t tx_total_bytes;
uint64_t rx_total_bytes;
uint64_t tx_total_errors;
uint64_t tx_total_retries;
uint32_t tx_pmtu_errors;
uint32_t tx_pmtu_retries;
uint32_t tx_ping_errors;
uint32_t tx_ping_retries;
uint32_t tx_pong_errors;
uint32_t tx_pong_retries;
uint32_t tx_data_errors;
uint32_t tx_data_retries;
/* measured in usecs */
uint32_t latency_min;
uint32_t latency_max;
uint32_t latency_ave;
uint32_t latency_samples;
/* how many times the link has been going up/down */
uint32_t down_count;
uint32_t up_count;
/*
* circular buffer of time_t structs collecting the history
* of up/down events on this link.
* the index indicates current/last event.
* it is safe to walk back the history by decreasing the index
*/
time_t last_up_times[MAX_LINK_EVENTS];
time_t last_down_times[MAX_LINK_EVENTS];
int8_t last_up_time_index;
int8_t last_down_time_index;
/* Always add new stats at the end */
};
struct knet_link_status {
size_t size; /* For ABI checking */
char src_ipaddr[KNET_MAX_HOST_LEN];
char src_port[KNET_MAX_PORT_LEN];
char dst_ipaddr[KNET_MAX_HOST_LEN];
char dst_port[KNET_MAX_PORT_LEN];
uint8_t enabled; /* link is configured and admin enabled for traffic */
uint8_t connected; /* link is connected for data (local view) */
uint8_t dynconnected; /* link has been activated by remote dynip */
unsigned long long latency; /* average latency computed by fix/exp */
struct timespec pong_last;
unsigned int mtu; /* current detected MTU on this link */
unsigned int proto_overhead; /* contains the size of the IP protocol, knet headers and
* crypto headers (if configured). This value is filled in
* ONLY after the first PMTUd run on that given link,
* and can change if link configuration or crypto configuration
* changes at runtime.
* WARNING: in general mtu + proto_overhead might or might
* not match the output of ifconfig mtu due to crypto
* requirements to pad packets to some specific boundaries. */
/* Link statistics */
struct knet_link_stats stats;
};
/*
* knet_link_get_status
*
* knet_h - pointer to knet_handle_t
*
* host_id - see above
*
* link_id - see above
*
* status - pointer to knet_link_status struct (see above)
*
* struct_size - max size of knet_link_status - allows library to
* add fields without ABI change. Returned structure
* will be truncated to this length and .size member
* indicates the full size.
*
* knet_link_get_status returns:
*
* 0 on success
* -1 on error and errno is set.
*/
int knet_link_get_status(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
struct knet_link_status *status, size_t struct_size);
/*
* logging structs/API calls
*/
/*
* libknet is composed of several subsystems. In order
* to easily distinguish log messages coming from different
* places, each subsystem has its own ID.
*
* 0-19 config/management
* 20-39 internal threads
* 40-59 transports
* 60-69 crypto implementations
*/
#define KNET_SUB_COMMON 0 /* common.c */
#define KNET_SUB_HANDLE 1 /* handle.c alloc/dealloc config changes */
#define KNET_SUB_HOST 2 /* host add/del/modify */
#define KNET_SUB_LISTENER 3 /* listeners add/del/modify... */
#define KNET_SUB_LINK 4 /* link add/del/modify */
#define KNET_SUB_TRANSPORT 5 /* Transport common */
#define KNET_SUB_CRYPTO 6 /* crypto.c config generic layer */
#define KNET_SUB_COMPRESS 7 /* compress.c config generic layer */
#define KNET_SUB_FILTER 19 /* allocated for users to log from dst_filter */
#define KNET_SUB_DSTCACHE 20 /* switching thread (destination cache handling) */
#define KNET_SUB_HEARTBEAT 21 /* heartbeat thread */
#define KNET_SUB_PMTUD 22 /* Path MTU Discovery thread */
#define KNET_SUB_TX 23 /* send to link thread */
#define KNET_SUB_RX 24 /* recv from link thread */
#define KNET_SUB_TRANSP_BASE 40 /* Base log level for transports */
#define KNET_SUB_TRANSP_LOOPBACK (KNET_SUB_TRANSP_BASE + KNET_TRANSPORT_LOOPBACK)
#define KNET_SUB_TRANSP_UDP (KNET_SUB_TRANSP_BASE + KNET_TRANSPORT_UDP)
#define KNET_SUB_TRANSP_SCTP (KNET_SUB_TRANSP_BASE + KNET_TRANSPORT_SCTP)
#define KNET_SUB_NSSCRYPTO 60 /* nsscrypto.c */
#define KNET_SUB_ZLIBCOMP 70 /* compress_zlib.c */
#define KNET_SUB_LZ4COMP 71 /* compress_lz4.c */
#define KNET_SUB_LZ4HCCOMP 72 /* compress_lz4.c */
#define KNET_SUB_LZO2COMP 73 /* compress_lzo.c */
+#define KNET_SUB_LZMACOMP 74 /* compress_lzma.c */
#define KNET_SUB_UNKNOWN 254
#define KNET_MAX_SUBSYSTEMS KNET_SUB_UNKNOWN + 1
/*
* Convert between subsystem IDs and names
*/
/*
* knet_log_get_subsystem_name
*
* return internal name of the subsystem or "common"
*/
const char *knet_log_get_subsystem_name(uint8_t subsystem);
/*
* knet_log_get_subsystem_id
*
* return internal ID of the subsystem or KNET_SUB_COMMON
*/
uint8_t knet_log_get_subsystem_id(const char *name);
/*
* 4 log levels are enough for everybody
*/
#define KNET_LOG_ERR 0 /* unrecoverable errors/conditions */
#define KNET_LOG_WARN 1 /* recoverable errors/conditions */
#define KNET_LOG_INFO 2 /* info, link up/down, config changes.. */
#define KNET_LOG_DEBUG 3
/*
* Convert between log level values and names
*/
/*
* knet_log_get_loglevel_name
*
* return internal name of the log level or "ERROR" for unknown values
*/
const char *knet_log_get_loglevel_name(uint8_t level);
/*
* knet_log_get_loglevel_id
*
* return internal log level ID or KNET_LOG_ERR for invalid names
*/
uint8_t knet_log_get_loglevel_id(const char *name);
/*
* every log message is composed by a text message (including a trailing \n)
* and message level/subsystem IDs.
* In order to make debugging easier it is possible to send those packets
* straight to stdout/stderr (see knet_bench.c stdout option).
*/
#define KNET_MAX_LOG_MSG_SIZE 256
struct knet_log_msg {
char msg[KNET_MAX_LOG_MSG_SIZE - (sizeof(uint8_t)*2)];
uint8_t subsystem; /* KNET_SUB_* */
uint8_t msglevel; /* KNET_LOG_* */
};
/*
* knet_log_set_log_level
*
* knet_h - same as above
*
* subsystem - same as above
*
* level - same as above
*
* knet_log_set_loglevel allows fine control of log levels by subsystem.
* See also knet_handle_new for defaults.
*
* knet_log_set_loglevel returns:
*
* 0 on success
* -1 on error and errno is set.
*/
int knet_log_set_loglevel(knet_handle_t knet_h, uint8_t subsystem,
uint8_t level);
/*
* knet_log_get_log_level
*
* knet_h - same as above
*
* subsystem - same as above
*
* level - same as above
*
* knet_log_get_loglevel returns:
*
* 0 on success
* -1 on error and errno is set.
*/
int knet_log_get_loglevel(knet_handle_t knet_h, uint8_t subsystem,
uint8_t *level);
#endif
diff --git a/libknet/logging.c b/libknet/logging.c
index 4a44608b..529df6c4 100644
--- a/libknet/logging.c
+++ b/libknet/logging.c
@@ -1,253 +1,254 @@
/*
* Copyright (C) 2010-2015 Red Hat, Inc. All rights reserved.
*
* Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
*
* This software licensed under GPL-2.0+, LGPL-2.0+
*/
#include "config.h"
#include <strings.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <stdarg.h>
#include <errno.h>
#include <stdio.h>
#include "internals.h"
#include "logging.h"
struct pretty_names {
const char *name;
uint8_t val;
};
static struct pretty_names subsystem_names[] =
{
{ "common", KNET_SUB_COMMON },
{ "handle", KNET_SUB_HANDLE },
{ "host", KNET_SUB_HOST },
{ "listener", KNET_SUB_LISTENER },
{ "link", KNET_SUB_LINK },
{ "transport", KNET_SUB_TRANSPORT },
{ "crypto", KNET_SUB_CRYPTO },
{ "compress", KNET_SUB_COMPRESS },
{ "filter", KNET_SUB_FILTER },
{ "dstcache", KNET_SUB_DSTCACHE },
{ "heartbeat", KNET_SUB_HEARTBEAT },
{ "pmtud", KNET_SUB_PMTUD },
{ "tx", KNET_SUB_TX },
{ "rx", KNET_SUB_RX },
{ "loopback", KNET_SUB_TRANSP_LOOPBACK },
{ "udp", KNET_SUB_TRANSP_UDP },
{ "sctp", KNET_SUB_TRANSP_SCTP },
{ "nsscrypto", KNET_SUB_NSSCRYPTO },
{ "zlibcomp", KNET_SUB_ZLIBCOMP },
{ "lz4comp", KNET_SUB_LZ4COMP },
{ "lz4hccomp", KNET_SUB_LZ4HCCOMP },
{ "lzo2comp", KNET_SUB_LZO2COMP },
+ { "lzmacomp", KNET_SUB_LZMACOMP },
{ "unknown", KNET_SUB_UNKNOWN } /* unknown MUST always be last in this array */
};
const char *knet_log_get_subsystem_name(uint8_t subsystem)
{
unsigned int i;
for (i = 0; i < KNET_MAX_SUBSYSTEMS; i++) {
if (subsystem_names[i].val == KNET_SUB_UNKNOWN) {
break;
}
if (subsystem_names[i].val == subsystem) {
return subsystem_names[i].name;
}
}
return "unknown";
}
uint8_t knet_log_get_subsystem_id(const char *name)
{
unsigned int i;
for (i = 0; i < KNET_MAX_SUBSYSTEMS; i++) {
if (subsystem_names[i].val == KNET_SUB_UNKNOWN) {
break;
}
if (strcasecmp(name, subsystem_names[i].name) == 0) {
return subsystem_names[i].val;
}
}
return KNET_SUB_UNKNOWN;
}
static int is_valid_subsystem(uint8_t subsystem)
{
unsigned int i;
for (i = 0; i < KNET_MAX_SUBSYSTEMS; i++) {
if ((subsystem != KNET_SUB_UNKNOWN) &&
(subsystem_names[i].val == KNET_SUB_UNKNOWN)) {
break;
}
if (subsystem_names[i].val == subsystem) {
return 0;
}
}
return -1;
}
static struct pretty_names loglevel_names[] =
{
{ "ERROR", KNET_LOG_ERR },
{ "WARNING", KNET_LOG_WARN },
{ "info", KNET_LOG_INFO },
{ "debug", KNET_LOG_DEBUG }
};
const char *knet_log_get_loglevel_name(uint8_t level)
{
unsigned int i;
for (i = 0; i <= KNET_LOG_DEBUG; i++) {
if (loglevel_names[i].val == level) {
return loglevel_names[i].name;
}
}
return "ERROR";
}
uint8_t knet_log_get_loglevel_id(const char *name)
{
unsigned int i;
for (i = 0; i <= KNET_LOG_DEBUG; i++) {
if (strcasecmp(name, loglevel_names[i].name) == 0) {
return loglevel_names[i].val;
}
}
return KNET_LOG_ERR;
}
int knet_log_set_loglevel(knet_handle_t knet_h, uint8_t subsystem,
uint8_t level)
{
int savederrno = 0;
if (!knet_h) {
errno = EINVAL;
return -1;
}
if (is_valid_subsystem(subsystem) < 0) {
errno = EINVAL;
return -1;
}
if (level > KNET_LOG_DEBUG) {
errno = EINVAL;
return -1;
}
savederrno = pthread_rwlock_wrlock(&knet_h->global_rwlock);
if (savederrno) {
log_err(knet_h, subsystem, "Unable to get write lock: %s",
strerror(savederrno));
errno = savederrno;
return -1;
}
knet_h->log_levels[subsystem] = level;
pthread_rwlock_unlock(&knet_h->global_rwlock);
return 0;
}
int knet_log_get_loglevel(knet_handle_t knet_h, uint8_t subsystem,
uint8_t *level)
{
int savederrno = 0;
if (!knet_h) {
errno = EINVAL;
return -1;
}
if (is_valid_subsystem(subsystem) < 0) {
errno = EINVAL;
return -1;
}
if (!level) {
errno = EINVAL;
return -1;
}
savederrno = pthread_rwlock_rdlock(&knet_h->global_rwlock);
if (savederrno) {
log_err(knet_h, subsystem, "Unable to get write lock: %s",
strerror(savederrno));
errno = savederrno;
return -1;
}
*level = knet_h->log_levels[subsystem];
pthread_rwlock_unlock(&knet_h->global_rwlock);
return 0;
}
void log_msg(knet_handle_t knet_h, uint8_t subsystem, uint8_t msglevel,
const char *fmt, ...)
{
va_list ap;
struct knet_log_msg msg;
size_t byte_cnt = 0;
int len, err;
if ((!knet_h) ||
(subsystem == KNET_MAX_SUBSYSTEMS) ||
(msglevel > knet_h->log_levels[subsystem]))
return;
/*
* most logging calls will take place with locking in place.
* if we get an EINVAL and locking is initialized, then
* we are getting a real error and we need to stop
*/
err = pthread_rwlock_tryrdlock(&knet_h->global_rwlock);
if ((err == EAGAIN) && (knet_h->lock_init_done))
return;
if (knet_h->logfd <= 0)
goto out_unlock;
memset(&msg, 0, sizeof(struct knet_log_msg));
msg.subsystem = subsystem;
msg.msglevel = msglevel;
va_start(ap, fmt);
vsnprintf(msg.msg, sizeof(msg.msg) - 2, fmt, ap);
va_end(ap);
len = strlen(msg.msg);
msg.msg[len+1] = '\n';
while (byte_cnt < sizeof(struct knet_log_msg)) {
len = write(knet_h->logfd, &msg, sizeof(struct knet_log_msg) - byte_cnt);
if (len <= 0) {
goto out_unlock;
}
byte_cnt += len;
}
out_unlock:
/*
* unlock only if we are holding the lock
*/
if (!err)
pthread_rwlock_unlock(&knet_h->global_rwlock);
return;
}
diff --git a/libknet/tests/api-check.mk b/libknet/tests/api-check.mk
index 225b651b..9b6389f3 100644
--- a/libknet/tests/api-check.mk
+++ b/libknet/tests/api-check.mk
@@ -1,236 +1,237 @@
#
# Copyright (C) 2016 Red Hat, Inc. All rights reserved.
#
# Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
#
# This software licensed under GPL-2.0+, LGPL-2.0+
#
api_checks = \
api_knet_handle_new_test \
api_knet_handle_free_test \
api_knet_handle_compress_test \
api_knet_handle_crypto_test \
api_knet_handle_setfwd_test \
api_knet_handle_enable_filter_test \
api_knet_handle_enable_sock_notify_test \
api_knet_handle_add_datafd_test \
api_knet_handle_remove_datafd_test \
api_knet_handle_get_channel_test \
api_knet_handle_get_datafd_test \
api_knet_handle_get_transport_list_test \
api_knet_handle_get_transport_name_by_id_test \
api_knet_handle_get_transport_id_by_name_test \
api_knet_handle_set_transport_reconnect_interval_test \
api_knet_handle_get_transport_reconnect_interval_test \
api_knet_recv_test \
api_knet_send_test \
api_knet_send_compress_test \
api_knet_send_sync_test \
api_knet_send_loopback_test \
api_knet_handle_pmtud_setfreq_test \
api_knet_handle_pmtud_getfreq_test \
api_knet_handle_enable_pmtud_notify_test \
api_knet_handle_pmtud_get_test \
api_knet_host_add_test \
api_knet_host_remove_test \
api_knet_host_set_name_test \
api_knet_host_get_name_by_host_id_test \
api_knet_host_get_id_by_host_name_test \
api_knet_host_get_host_list_test \
api_knet_host_set_policy_test \
api_knet_host_get_policy_test \
api_knet_host_get_status_test \
api_knet_host_enable_status_change_notify_test \
api_knet_log_get_subsystem_name_test \
api_knet_log_get_subsystem_id_test \
api_knet_log_get_loglevel_name_test \
api_knet_log_get_loglevel_id_test \
api_knet_log_set_loglevel_test \
api_knet_log_get_loglevel_test \
api_knet_strtoaddr_test \
api_knet_addrtostr_test \
api_knet_link_set_config_test \
api_knet_link_clear_config_test \
api_knet_link_get_config_test \
api_knet_link_set_ping_timers_test \
api_knet_link_get_ping_timers_test \
api_knet_link_set_pong_count_test \
api_knet_link_get_pong_count_test \
api_knet_link_set_priority_test \
api_knet_link_get_priority_test \
api_knet_link_set_enable_test \
api_knet_link_get_enable_test \
api_knet_link_get_link_list_test \
api_knet_link_get_status_test
api_knet_handle_new_test_SOURCES = api_knet_handle_new.c \
test-common.c
api_knet_handle_free_test_SOURCES = api_knet_handle_free.c \
test-common.c
api_knet_handle_compress_test_SOURCES = api_knet_handle_compress.c \
test-common.c
api_knet_handle_crypto_test_SOURCES = api_knet_handle_crypto.c \
test-common.c
api_knet_handle_setfwd_test_SOURCES = api_knet_handle_setfwd.c \
test-common.c
api_knet_handle_enable_filter_test_SOURCES = api_knet_handle_enable_filter.c \
test-common.c
api_knet_handle_enable_sock_notify_test_SOURCES = api_knet_handle_enable_sock_notify.c \
test-common.c
api_knet_handle_add_datafd_test_SOURCES = api_knet_handle_add_datafd.c \
test-common.c
api_knet_handle_remove_datafd_test_SOURCES = api_knet_handle_remove_datafd.c \
test-common.c
api_knet_handle_get_channel_test_SOURCES = api_knet_handle_get_channel.c \
test-common.c
api_knet_handle_get_datafd_test_SOURCES = api_knet_handle_get_datafd.c \
test-common.c
api_knet_handle_get_transport_list_test_SOURCES = api_knet_handle_get_transport_list.c \
test-common.c
api_knet_handle_get_transport_name_by_id_test_SOURCES = api_knet_handle_get_transport_name_by_id.c \
test-common.c
api_knet_handle_get_transport_id_by_name_test_SOURCES = api_knet_handle_get_transport_id_by_name.c \
test-common.c
api_knet_handle_set_transport_reconnect_interval_test_SOURCES = api_knet_handle_set_transport_reconnect_interval.c \
test-common.c
api_knet_handle_get_transport_reconnect_interval_test_SOURCES = api_knet_handle_get_transport_reconnect_interval.c \
test-common.c
api_knet_recv_test_SOURCES = api_knet_recv.c \
test-common.c
api_knet_send_test_SOURCES = api_knet_send.c \
test-common.c
api_knet_send_compress_test_SOURCES = api_knet_send_compress.c \
../compress.c \
../logging.c \
../compress_zlib.c \
../compress_lz4.c \
../compress_lzo2.c \
+ ../compress_lzma.c \
test-common.c
api_knet_send_loopback_test_SOURCES = api_knet_send_loopback.c \
test-common.c
api_knet_send_sync_test_SOURCES = api_knet_send_sync.c \
test-common.c
api_knet_handle_pmtud_setfreq_test_SOURCES = api_knet_handle_pmtud_setfreq.c \
test-common.c
api_knet_handle_pmtud_getfreq_test_SOURCES = api_knet_handle_pmtud_getfreq.c \
test-common.c
api_knet_handle_enable_pmtud_notify_test_SOURCES = api_knet_handle_enable_pmtud_notify.c \
test-common.c
api_knet_handle_pmtud_get_test_SOURCES = api_knet_handle_pmtud_get.c \
test-common.c
api_knet_host_add_test_SOURCES = api_knet_host_add.c \
test-common.c
api_knet_host_remove_test_SOURCES = api_knet_host_remove.c \
test-common.c
api_knet_host_set_name_test_SOURCES = api_knet_host_set_name.c \
test-common.c
api_knet_host_get_name_by_host_id_test_SOURCES = api_knet_host_get_name_by_host_id.c \
test-common.c
api_knet_host_get_id_by_host_name_test_SOURCES = api_knet_host_get_id_by_host_name.c \
test-common.c
api_knet_host_get_host_list_test_SOURCES = api_knet_host_get_host_list.c \
test-common.c
api_knet_host_set_policy_test_SOURCES = api_knet_host_set_policy.c \
test-common.c
api_knet_host_get_policy_test_SOURCES = api_knet_host_get_policy.c \
test-common.c
api_knet_host_get_status_test_SOURCES = api_knet_host_get_status.c \
test-common.c
api_knet_host_enable_status_change_notify_test_SOURCES = api_knet_host_enable_status_change_notify.c \
test-common.c
api_knet_log_get_subsystem_name_test_SOURCES = api_knet_log_get_subsystem_name.c \
test-common.c
api_knet_log_get_subsystem_id_test_SOURCES = api_knet_log_get_subsystem_id.c \
test-common.c
api_knet_log_get_loglevel_name_test_SOURCES = api_knet_log_get_loglevel_name.c \
test-common.c
api_knet_log_get_loglevel_id_test_SOURCES = api_knet_log_get_loglevel_id.c \
test-common.c
api_knet_log_set_loglevel_test_SOURCES = api_knet_log_set_loglevel.c \
test-common.c
api_knet_log_get_loglevel_test_SOURCES = api_knet_log_get_loglevel.c \
test-common.c
api_knet_strtoaddr_test_SOURCES = api_knet_strtoaddr.c
api_knet_addrtostr_test_SOURCES = api_knet_addrtostr.c
api_knet_link_set_config_test_SOURCES = api_knet_link_set_config.c \
test-common.c
api_knet_link_clear_config_test_SOURCES = api_knet_link_clear_config.c \
test-common.c
api_knet_link_get_config_test_SOURCES = api_knet_link_get_config.c \
test-common.c
api_knet_link_set_ping_timers_test_SOURCES = api_knet_link_set_ping_timers.c \
test-common.c
api_knet_link_get_ping_timers_test_SOURCES = api_knet_link_get_ping_timers.c \
test-common.c
api_knet_link_set_pong_count_test_SOURCES = api_knet_link_set_pong_count.c \
test-common.c
api_knet_link_get_pong_count_test_SOURCES = api_knet_link_get_pong_count.c \
test-common.c
api_knet_link_set_priority_test_SOURCES = api_knet_link_set_priority.c \
test-common.c
api_knet_link_get_priority_test_SOURCES = api_knet_link_get_priority.c \
test-common.c
api_knet_link_set_enable_test_SOURCES = api_knet_link_set_enable.c \
test-common.c
api_knet_link_get_enable_test_SOURCES = api_knet_link_get_enable.c \
test-common.c
api_knet_link_get_link_list_test_SOURCES = api_knet_link_get_link_list.c \
test-common.c
api_knet_link_get_status_test_SOURCES = api_knet_link_get_status.c \
test-common.c

File Metadata

Mime Type
text/x-diff
Expires
Mon, Apr 21, 2:19 PM (1 d, 15 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1664910
Default Alt Text
(106 KB)

Event Timeline