diff --git a/configure.ac b/configure.ac index e6a5f32d..5ba6fcce 100644 --- a/configure.ac +++ b/configure.ac @@ -1,290 +1,291 @@ # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ([2.63]) AC_INIT([kronosnetd], [0.1], [fabbione@kronosnet.org]) +AC_USE_SYSTEM_EXTENSIONS AM_INIT_AUTOMAKE([1.11.1 dist-bzip2 dist-xz color-tests -Wno-portability]) 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]) 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 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_CC AM_PROG_CC_C_O 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]) ## 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="$@" 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([rt], [clock_gettime]) PKG_CHECK_MODULES([nss],[nss]) 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 # Checks for header files. AC_CHECK_HEADERS([fcntl.h]) AC_CHECK_HEADERS([stdlib.h]) AC_CHECK_HEADERS([string.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]) # Checks for typedefs, structures, and compiler characteristics. AC_TYPE_SIZE_T AC_TYPE_PID_T AC_TYPE_SSIZE_T AC_TYPE_UINT8_T AC_TYPE_UINT16_T AC_TYPE_UINT32_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]) # PAM check 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])]) # 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([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]) AC_SUBST([DEFAULT_CONFIG_DIR]) 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 shadow missing-prototypes missing-declarations strict-prototypes declaration-after-statement pointer-arith write-strings cast-align bad-function-cast missing-format-attribute format=2 format-security format-nonliteral no-long-long unsigned-char gnu89-inline no-strict-aliasing error address cpp enum-compare overflow parentheses sequence-point switch uninitialized unused-but-set-variable unused-function unused-result unused-value unused-variable " 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" AC_CONFIG_FILES([ Makefile libtap/Makefile libtap/libtap.pc kronosnetd/Makefile libknet/Makefile libknet/libknet.pc docs/Makefile tests/Makefile ]) AC_OUTPUT diff --git a/tests/ping_test.c b/tests/ping_test.c index 41591787..4b5df55c 100644 --- a/tests/ping_test.c +++ b/tests/ping_test.c @@ -1,211 +1,211 @@ #include "config.h" #include #include #include #include #include #include #include #include "libknet.h" static int knet_sock[2]; static knet_handle_t knet_h; static in_port_t tok_inport(char *str) { int value = atoi(str); if ((value < 0) || (value > UINT16_MAX)) return 0; return (in_port_t) value; } static int tok_inaddrport(char *str, struct sockaddr_in *addr) { char *strhost, *strport, *tmp = NULL; strhost = strtok_r(str, ":", &tmp); strport = strtok_r(NULL, ":", &tmp); if (strport == NULL) addr->sin_port = htons(KNET_RING_DEFPORT); else addr->sin_port = htons(tok_inport(strport)); return inet_aton(strhost, &addr->sin_addr); } static void print_usage(char *name) { printf("usage: %s [:] [:port] [...]\n", name); printf("example: %s 0.0.0.0 192.168.0.2\n", name); } static void argv_to_hosts(int argc, char *argv[]) { int err, i; struct sockaddr_in *address; struct knet_host *host; struct knet_listener *listener; listener = malloc(sizeof(struct knet_listener)); if (listener == NULL) { printf("Unable to create listener\n"); exit(EXIT_FAILURE); } memset(listener, 0, sizeof(struct knet_listener)); address = (struct sockaddr_in *) &listener->address; address->sin_family = AF_INET; err = tok_inaddrport(argv[1], address); if (err < 0) { printf("Unable to convert ip address: %s\n", argv[1]); exit(EXIT_FAILURE); } err = knet_listener_add(knet_h, listener); if (err != 0) { printf("Unable to start knet listener\n"); exit(EXIT_FAILURE); } for (i = 2; i < argc; i++) { if (knet_host_add(knet_h, i - 1) != 0) { printf("Unable to add new knet_host\n"); exit(EXIT_FAILURE); } knet_host_get(knet_h, i - 1, &host); host->link[0].sock = listener->sock; host->link[0].address.ss_family = AF_INET; knet_link_timeout(&host->link[0], 1000, 5000, 2048); host->link[0].ready = 1; err = tok_inaddrport(argv[i], (struct sockaddr_in *) &host->link[0].address); if (err < 0) { printf("Unable to convert ip address: %s", argv[i]); exit(EXIT_FAILURE); } knet_host_release(knet_h, &host); } } /* Testing the latency/timeout: * # tc qdisc add dev lo root handle 1:0 netem delay 1s limit 1000 * # tc -d qdisc show dev lo * # tc qdisc del dev lo root */ static int print_link(knet_handle_t khandle, struct knet_host *host, struct knet_host_search *data) { int i; for (i = 0; i < KNET_MAX_LINK; i++) { if (host->link[i].ready != 1) continue; - printf("host %p, link %p latency is %llums, status: %s\n", + printf("host %p, link %p latency is %llu microsecs, status: %s\n", host, &host->link[i], host->link[i].latency, (host->link[i].enabled == 0) ? "disabled" : "enabled"); } return KNET_HOST_FOREACH_NEXT; } static void sigint_handler(int signum) { int err; printf("Cleaning up...\n"); if (knet_h != NULL) { err = knet_handle_free(knet_h); if (err != 0) { printf("Unable to cleanup before exit\n"); exit(EXIT_FAILURE); } } exit(EXIT_SUCCESS); } int main(int argc, char *argv[]) { char buff[1024]; size_t len; fd_set rfds; struct timeval tv; struct knet_host_search print_search; if (argc < 3) { print_usage(argv[0]); exit(EXIT_FAILURE); } if (socketpair(AF_UNIX, SOCK_STREAM, IPPROTO_IP, knet_sock) != 0) { printf("Unable to create socket\n"); exit(EXIT_FAILURE); } knet_h = NULL; if (signal(SIGINT, sigint_handler) == SIG_ERR) { printf("Unable to configure SIGINT handler\n"); exit(EXIT_FAILURE); } if ((knet_h = knet_handle_new(knet_sock[0], 1)) == NULL) { printf("Unable to create new knet_handle_t\n"); exit(EXIT_FAILURE); } argv_to_hosts(argc, argv); knet_handle_setfwd(knet_h, 1); while (1) { knet_host_foreach(knet_h, print_link, &print_search); printf("Sending 'Hello World!' frame\n"); write(knet_sock[1], "Hello World!", 13); tv.tv_sec = 5; tv.tv_usec = 0; select_loop: FD_ZERO(&rfds); FD_SET(knet_sock[1], &rfds); len = select(FD_SETSIZE, &rfds, NULL, NULL, &tv); /* uncomment this to replicate the one-message problem */ /* usleep(500000); */ if (len < 0) { printf("Unable select over knet_handle_t\n"); exit(EXIT_FAILURE); } else if (FD_ISSET(knet_sock[1], &rfds)) { len = read(knet_sock[1], buff, sizeof(buff)); printf("Received data (%zu bytes): '%s'\n", len, buff); } if ((tv.tv_sec > 0) || (tv.tv_usec > 0)) goto select_loop; } /* FIXME: allocated hosts should be free'd */ return 0; }