gogoc-1_2-RELEASE/0040755000000000000000000000000011346561546012326 5ustar rootrootgogoc-1_2-RELEASE/gogoc-pal/0040755000000000000000000000000011346561541014171 5ustar rootrootgogoc-1_2-RELEASE/gogoc-pal/defs/0040755000000000000000000000000011346561541015112 5ustar rootrootgogoc-1_2-RELEASE/gogoc-pal/defs/pal_criticalsection.def0100644000000000000000000000157611301543026021600 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal_criticalsection.def,v 1.1 2009/11/20 16:38:46 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer definition for critical section functions. ----------------------------------------------------------------------------- */ #ifndef __PAL_CRITICALSECTION_DEF__ #define __PAL_CRITICALSECTION_DEF__ extern sint32_t pal_init_cs ( pal_cs_t* cs ); extern sint32_t pal_enter_cs ( pal_cs_t* cs ); extern sint32_t pal_leave_cs ( pal_cs_t* cs ); extern sint32_t pal_free_cs ( pal_cs_t* cs ); #endif gogoc-1_2-RELEASE/gogoc-pal/defs/pal_getopt.def0100644000000000000000000000141511301543026017713 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal_getopt.def,v 1.1 2009/11/20 16:38:46 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer definition for getopt function. ----------------------------------------------------------------------------- */ #ifndef __PAL_GETOPT_DEF__ #define __PAL_GETOPT_DEF__ extern char* optarg; extern int optind, opterr, optopt, optreset; extern int pal_getopt ( int argc, char * const argv[], const char* optstring ); #endif gogoc-1_2-RELEASE/gogoc-pal/defs/pal_inet.def0100644000000000000000000000126211301543026017350 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal_inet.def,v 1.1 2009/11/20 16:38:46 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer definition for inet functions. ----------------------------------------------------------------------------- */ #ifndef __PAL_INET_DEF__ #define __PAL_INET_DEF__ extern sint32_t pal_inet_pton ( sint32_t af, const char* src, void* dst ); #endif gogoc-1_2-RELEASE/gogoc-pal/defs/pal_process.def0100644000000000000000000000132211301543027020065 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal_process.def,v 1.1 2009/11/20 16:38:47 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer definition for process functions. ----------------------------------------------------------------------------- */ #ifndef __PAL_PROCESS_DEF__ #define __PAL_PROCESS_DEF__ extern sint32_t pal_getpid ( void ); extern sint32_t pal_getppid ( void ); #endif gogoc-1_2-RELEASE/gogoc-pal/defs/pal_socket.def0100644000000000000000000000167011301543027017705 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal_socket.def,v 1.1 2009/11/20 16:38:47 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer definition for socket functions. ----------------------------------------------------------------------------- */ #ifndef __PAL_SOCKET_DEF__ #define __PAL_SOCKET_DEF__ extern pal_socket_t pal_socket ( sint32_t af, sint32_t type, sint32_t proto ); extern sint32_t pal_connect ( pal_socket_t sockfd, const struct sockaddr *serv_addr, sint32_t addrlen ); extern sint32_t pal_shutdown ( pal_socket_t s, sint32_t how ); extern sint32_t pal_closesocket ( pal_socket_t s ); #endif gogoc-1_2-RELEASE/gogoc-pal/defs/pal_stdlib.def0100644000000000000000000000172311301543027017675 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal_stdlib.def,v 1.1 2009/11/20 16:38:47 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer definition for stdlib functions. ----------------------------------------------------------------------------- */ #ifndef __PAL_STDLIB_DEF__ #define __PAL_STDLIB_DEF__ extern void * pal_malloc ( uint32_t size ); extern void pal_free ( void* ptr ); extern sint32_t pal_putenv ( char* envstring ); extern void pal_srandom ( uint32_t seed ); extern sint32_t pal_random ( void ); extern sint32_t pal_system ( const char* string ); #endif gogoc-1_2-RELEASE/gogoc-pal/defs/pal_string.def0100644000000000000000000000322111301543027017715 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal_string.def,v 1.1 2009/11/20 16:38:47 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer definition for string functions. ----------------------------------------------------------------------------- */ #ifndef __PAL_STRING_DEF__ #define __PAL_STRING_DEF__ extern char* pal_strcpy ( char* dest, const char* src ); extern char* pal_strncpy ( char* dest, const char* src, uint32_t n ); extern uint32_t pal_strlen ( const char* s ); extern char* pal_strcat ( char *dest, const char *src ); extern char* pal_strncat ( char *dest, const char *src, uint32_t n ); extern int pal_strcasecmp ( const char* s1, const char* s2 ); extern int pal_strncasecmp ( const char* s1, const char* s2, uint32_t n ); extern int pal_printf ( const char* format, ... ); extern int pal_sprintf ( char* str, const char* format, ... ); extern int pal_snprintf ( char* str, uint32_t size, const char* format, ... ); extern int pal_vsnprintf ( char* str, uint32_t size, const char* format, va_list ap ); extern void* pal_memcpy ( void* dest, const void* src, uint32_t n ); extern char* pal_strdup ( const char* s ); #endif gogoc-1_2-RELEASE/gogoc-pal/defs/pal_syslog.def0100644000000000000000000000153411301543027017734 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal_syslog.def,v 1.1 2009/11/20 16:38:47 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer definition for syslog functions. ----------------------------------------------------------------------------- */ #ifndef __PAL_SYSLOG_DEF__ #define __PAL_SYSLOG_DEF__ extern void pal_openlog ( const char *ident, sint32_t option, sint32_t facility ); extern void pal_syslog ( sint32_t priority, const char *format, ... ); extern void pal_closelog ( void ); #endif gogoc-1_2-RELEASE/gogoc-pal/defs/pal_thread.def0100644000000000000000000000155011301543027017661 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal_thread.def,v 1.1 2009/11/20 16:38:47 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2008 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer definition for thread functions. ----------------------------------------------------------------------------- */ #ifndef __PAL_THREAD_DEF__ #define __PAL_THREAD_DEF__ extern sint32_t pal_thread_create ( pal_thread_t * id, pal_thread_funct funct, void * arg ); extern sint32_t pal_thread_exit ( pal_thread_ret_t ret ); extern sint32_t pal_thread_join ( pal_thread_t id, pal_thread_ret_t * ret ); #endif gogoc-1_2-RELEASE/gogoc-pal/defs/pal_time.def0100644000000000000000000000144011301543027017346 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal_time.def,v 1.1 2009/11/20 16:38:47 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer definition for time functions. ----------------------------------------------------------------------------- */ #ifndef __PAL_TIME_DEF__ #define __PAL_TIME_DEF__ extern sint32_t pal_gettimeofday ( struct timeval * tv ); extern struct tm * pal_localtime ( const time_t *timer ); extern time_t pal_time ( time_t* t ); #endif gogoc-1_2-RELEASE/gogoc-pal/defs/pal_unistd.def0100644000000000000000000000157011301543030017714 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal_unistd.def,v 1.1 2009/11/20 16:38:48 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer definition for unistd functions. ----------------------------------------------------------------------------- */ #ifndef __PAL_UNISTD_DEF__ #define __PAL_UNISTD_DEF__ extern char* pal_getcwd ( char* buf, uint32_t size ); extern sint32_t pal_chdir ( const char* path ); extern void pal_sleep ( const uint32_t usec ); extern sint32_t pal_unlink ( const char* pathname ); #endif gogoc-1_2-RELEASE/gogoc-pal/.cvsignore0100644000000000000000000000000011301065042016136 0ustar rootrootgogoc-1_2-RELEASE/gogoc-pal/Makefile0100644000000000000000000000626111344753206015632 0ustar rootroot# ########################################################################### # # $Id: Makefile,v 1.2 2010/03/07 16:38:30 carl Exp $ # # Copyright (c) 2007 gogo6 Inc. All rights reserved. # # For license information refer to CLIENT-LICENSE.TXT # # Description: GNU Makefile for module library gogoc-pal # (gogoCLIENT Platform Abstraction Layer) # # Author: Charles Nepveu # # Date: October 2007 # # ########################################################################### # PWD :=$(shell pwd) PLATFORM_DIR :=$(PWD)/platform OBJS_DIR :=$(PWD)/objs DEFS_DIR :=$(PWD)/defs OUT_LIB_DIR :=$(PWD)/out_lib OUT_INC_DIR :=$(PWD)/out_inc LIB_NAME :=libgogocpal.a GOGOCPAL_LIB :=${OUT_LIB_DIR}/${LIB_NAME} PLATFORM :=$(shell [ -z "$(platform)" ] && uname | tr "[A-Z]" "[a-z]" || echo "$(platform)" ) SUPPORTED_PLATFORMS=linux netbsd freebsd openbsd darwin sunos gogocpe CC=gcc # Export these variables to sub-makes. export PLATFORM PLATFORM_DIR OBJS_DIR DEFS_DIR OUT_INC_DIR CC DEBUG # # ########################################################################### # .PHONY: platform-check platform-obj platform-lib platform-inc all clean all: platform-check platform-obj platform-lib platform-inc # This makefile target will check the platform. # platform-check: @for plat in ${SUPPORTED_PLATFORMS} ; do \ [ "${PLATFORM}" = "$$plat" ] && platform_ok=xxx || platform_ok=$$platform_ok ; \ done && ([ -z "$$platform_ok" ] && { \ echo ; \ echo "Error: Target platform <${PLATFORM}> is invalid!"; \ echo "Syntax: make platform="; \ echo ; \ echo " where is one of the following:"; \ echo " linux for Linux." ; \ echo " freebsd for FreeBSD." ; \ echo " openbsd for OpenBSD." ; \ echo " netbsd for NetBSD." ; \ echo " darwin for Mac OS X darwin."; \ echo " openwrt for OpenWRT." ; \ echo " sunos for Sun/Solaris." ; \ echo ; \ exit 1;\ } || echo "Setting up PAL for platform ${PLATFORM} ..." ; ) # This makefile target will compile the platform PAL objects. # platform-obj: @echo "Building PAL objects for platform ${PLATFORM} ..." @[ -d ${OBJS_DIR} ] || mkdir -p ${OBJS_DIR} @($(MAKE) -C ${PLATFORM_DIR} platform-obj) || exit 1 @echo ; # This makefile target will create the platform PAL library. # platform-lib: @echo "Creating ${LIB_NAME} PAL library for platform ${PLATFORM} ..." @[ -d ${OUT_LIB_DIR} ] || mkdir -p ${OUT_LIB_DIR} @$(AR) -crusv ${GOGOCPAL_LIB} $(wildcard ${OBJS_DIR}/*) @echo ; # This makefile target will copy the platform includes to out_inc. # platform-inc: @echo "Copying PAL header files for platform ${PLATFORM} ..." @[ -d ${OUT_INC_DIR} ] || mkdir -p ${OUT_INC_DIR} @($(MAKE) -C ${PLATFORM_DIR} platform-inc) || exit 1 @echo ; # # ########################################################################### # clean: @echo ; rm -rf ${OBJS_DIR} rm -rf ${OUT_INC_DIR} rm -rf ${OUT_LIB_DIR} @echo "Clean complete" @echo ; # # ########################################################################### gogoc-1_2-RELEASE/gogoc-pal/README0100644000000000000000000000222311301543025015031 0ustar rootroot$ Id: $ ------------------------------------------------------------------------------ Copyright (c) 2007 gogo6 Inc. All rights reserved. ------------------------------------------------------------------------------ This directory contains the gogoCLIENT Platform Abstraction Layer(PAL). Subdirectories: .\defs\ - Contains the API definitions that the header files for the platform must conform to. .\platform\ - Platform-specific implementation of the GOGOC PAL. .\out_inc\ - Will contain the header files for the platform specified when `make' was invoked. .\out_lib\ - Will contain the built gogoCLIENT Platform Abstraction Layer library. Files: .\Makefile - Makefile to build PAL on UNIX-like platforms. .\build-winpc.cmd - Command script to build PAL on Windows (XP, Vista). .\build-wince.cmd - Command script to build PAL on Windows Embedded. Applications that use this library should modify the CFLAGS to add the following: -I/defs -I/out_inc LDFLAGS: -L/out_lib -lgogocpal gogoc-1_2-RELEASE/gogoc-pal/build-wince.cmd0100644000000000000000000000303611301543026017044 0ustar rootroot@ECHO OFF REM ************************************************************************* REM * $Id: build-wince.cmd,v 1.1 2009/11/20 16:38:46 jasminko Exp $ REM * REM * Batch file used to build the gogoCLIENT PAL. REM * REM * Prerequisites: REM * - Visual Studio 2005 (SP1) REM * - Windows Embedded CE (5 or 6) SDK REM * - DEVENV executable in %PATH% REM * REM * Usage: REM * build-wince [/Release /Debug] REM * REM ************************************************************************* REM Defaults: SET CONFIGURATION=Release SET PLATFORM= SET COMMAND=Build REM Overrides: :ParseArgs IF /I "%~1" == "/?" GOTO Usage IF /I "%~1" == "-h" GOTO Usage IF /I "%~1" == "/Release" SET CONFIGURATION=Release& SHIFT& GOTO ParseArgs IF /I "%~1" == "/Debug" SET CONFIGURATION=Debug& SHIFT& GOTO ParseArgs IF /I "%~1" == "/Clean" SET COMMAND=Clean& SHIFT& GOTO ParseArgs IF "%~1" EQU "" GOTO Done_Args ECHO Unknown command-line switch: %~1 GOTO Usage :Done_Args REM Build the target ECHO Launching build of gogoc-pal solution... ECHO Configuration: COMMAND=%COMMAND% CONFIGURATION=%CONFIGURATION% ECHO. DEVENV platform\wince\gogoc-pal.sln /%COMMAND% "%CONFIGURATION%" IF %ERRORLEVEL% == 0 GOTO build_ok GOTO build_error :Usage ECHO. ECHO Usage: ECHO %0 ^[^/Release^|^/Debug^] ^[^/Clean^] ECHO. ECHO Defaults: ^/Release ECHO. GOTO the_end :build_ok ECHO. ECHO Build of gogoc-pal solution completed successfully. GOTO the_end :build_error ECHO. ECHO Build of gogoc-pal solution FAILED! :the_end gogoc-1_2-RELEASE/gogoc-pal/build-winpc.cmd0100644000000000000000000000400711301543026017056 0ustar rootroot@ECHO OFF REM ************************************************************************* REM * $Id: build-winpc.cmd,v 1.1 2009/11/20 16:38:46 jasminko Exp $ REM * REM * Batch file used to build the gogoCLIENT PAL. REM * REM * Prerequisites: REM * - Visual Studio 2005 (SP1) REM * - Windows Vista RTM SDK (Integrated in VS2005SP1) REM * - DEVENV executable in %PATH% REM * REM * Usage: REM * build-winpc [/Release /HACCESS-Release /Debug /HACCESS-Debug] [/Win32 /x64] REM * REM ************************************************************************* REM Defaults: SET CONFIGURATION=Release SET PLATFORM=Win32 SET COMMAND=Build REM Overrides: :ParseArgs IF /I "%~1" == "/?" GOTO Usage IF /I "%~1" == "-h" GOTO Usage IF /I "%~1" == "/Release" SET CONFIGURATION=Release& SHIFT& GOTO ParseArgs IF /I "%~1" == "/HACCESS-Release" SET CONFIGURATION=HACCESS-Release& SHIFT& GOTO ParseArgs IF /I "%~1" == "/Debug" SET CONFIGURATION=Debug& SHIFT& GOTO ParseArgs IF /I "%~1" == "/HACCESS-Debug" SET CONFIGURATION=HACCESS-Debug& SHIFT& GOTO ParseArgs IF /I "%~1" == "/Win32" SET PLATFORM=Win32& SHIFT& GOTO ParseArgs IF /I "%~1" == "/x64" SET PLATFORM=x64& SHIFT& GOTO ParseArgs IF /I "%~1" == "/Clean" SET COMMAND=Clean& SHIFT& GOTO ParseArgs IF "%~1" EQU "" GOTO Done_Args ECHO Unknown command-line switch: %~1 GOTO Usage :Done_Args REM Build the target ECHO Launching build of gogoc-pal solution... ECHO Configuration: COMMAND=%COMMAND% PLATFORM=%PLATFORM% CONFIGURATION=%CONFIGURATION% ECHO. DEVENV platform\winpc\gogoc-pal.sln /%COMMAND% "%CONFIGURATION%|%PLATFORM%" IF %ERRORLEVEL% == 0 GOTO build_ok GOTO build_error :Usage ECHO. ECHO Usage: ECHO %0 ^[^/Release^|^/HACCESS-Release^|^/Debug^|^/HACCESS-Debug^] ^[^/Win32^|^/x64^] ^[^/Clean^] ECHO. ECHO Defaults: ^/Release ^/Win32 ECHO. GOTO the_end :build_ok ECHO. ECHO Build of gogoc-pal solution completed successfully. GOTO the_end :build_error ECHO. ECHO Build of gogoc-pal solution FAILED! :the_end gogoc-1_2-RELEASE/gogoc-pal/platform/0040755000000000000000000000000011346561546016022 5ustar rootrootgogoc-1_2-RELEASE/gogoc-pal/platform/common/0040755000000000000000000000000011346561541017305 5ustar rootrootgogoc-1_2-RELEASE/gogoc-pal/platform/common/inc/0040755000000000000000000000000011346561541020056 5ustar rootrootgogoc-1_2-RELEASE/gogoc-pal/platform/common/inc/pal.h0100644000000000000000000000173511301543031020767 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal.h,v 1.1 2009/11/20 16:38:49 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer. ----------------------------------------------------------------------------- */ #ifndef __PAL_H__ #define __PAL_H__ #ifdef __cplusplus extern "C" { #endif #include "pal_types.h" #include "pal_version.h" #include "pal_inet.h" #include "pal_socket.h" #include "pal_errno.h" #include "pal_stdarg.h" #include "pal_stdlib.h" #include "pal_getopt.h" #include "pal_string.h" #include "pal_unistd.h" #include "pal_process.h" #include "pal_time.h" #include "pal_criticalsection.h" #include "pal_thread.h" #include "pal_syslog.h" #ifdef __cplusplus } #endif #endif gogoc-1_2-RELEASE/gogoc-pal/platform/common/inc/pal_version.h0100644000000000000000000000125511301543031022531 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal_version.h,v 1.1 2009/11/20 16:38:49 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer version. ----------------------------------------------------------------------------- */ #ifndef __PAL_VERSION_H__ #define __PAL_VERSION_H__ #ifndef PLATFORM #define PLATFORM "Unknown platform" #endif const char* get_pal_version( void ); #endif gogoc-1_2-RELEASE/gogoc-pal/platform/common/src/0040755000000000000000000000000011346561541020074 5ustar rootrootgogoc-1_2-RELEASE/gogoc-pal/platform/common/src/pal_version.c0100644000000000000000000000133311301543031022537 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal_version.c,v 1.1 2009/11/20 16:38:49 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer version info. ----------------------------------------------------------------------------- */ #include "pal_version.h" #define PAL_VER_STRING "gogoCLIENT PAL for " PLATFORM " built on " __DATE__ /* Returns the pal version. */ const char* get_pal_version( void ) { return PAL_VER_STRING; } gogoc-1_2-RELEASE/gogoc-pal/platform/common/Makefile0100644000000000000000000000235411301543030020726 0ustar rootroot# ########################################################################### # # $Id: Makefile,v 1.1 2009/11/20 16:38:48 jasminko Exp $ # # Copyright (c) 2007 gogo6 Inc. All rights reserved. # # For license information refer to CLIENT-LICENSE.TXT # # Description: Makefile for common platforms # # Author: Charles Nepveu # # Date: August 2007 # # ########################################################################### # INC_DIR:=inc SRC_DIR:=src ifdef DEBUG CFLAGS+=-c -g -I${DEFS_DIR} -I${INC_DIR} -DPLATFORM=\"${PLATFORM}\" -D_REENTRANT -DDEBUG ${EXTRA_CFLAGS} else CFLAGS+=-c -O2 -I${DEFS_DIR} -I${INC_DIR} -DPLATFORM=\"${PLATFORM}\" -D_REENTRANT ${EXTRA_CFLAGS} endif OBJS:=$(patsubst ${SRC_DIR}/%.c,${OBJS_DIR}/%.o,$(wildcard ${SRC_DIR}/*.c)) .PHONY: platform-obj platform-inc # # ########################################################################### # platform-obj: ${OBJS} ${OBJS_DIR}/pal_version.o: ${SRC_DIR}/pal_version.c ${INC_DIR}/pal_version.h $(CC) ${CFLAGS} -o $@ ${SRC_DIR}/pal_version.c # # ########################################################################### # platform-inc: @cp -f $(wildcard ${INC_DIR}/*.*) $(OUT_INC_DIR) # # ########################################################################### gogoc-1_2-RELEASE/gogoc-pal/platform/Makefile0100644000000000000000000000340511344753206017453 0ustar rootroot# ########################################################################### # # $Id: Makefile,v 1.2 2010/03/07 16:38:30 carl Exp $ # # Copyright (c) 2007 gogo6 Inc. All rights reserved. # # For license information refer to CLIENT-LICENSE.TXT # # Description: Makefile for module library gogoc-pal # (gogoCLIENT Platform Abstraction Layer) # # Author: Charles Nepveu # # Date: August 2007 # # ########################################################################### # # # Target directory definition. # linux_CDIR=common unix-common freebsd_CDIR=common unix-common openbsd_CDIR=common unix-common netbsd_CDIR=common unix-common netbsd darwin_CDIR=common unix-common sunos_CDIR=common unix-common gogocpe_CDIR=common unix-common # # ########################################################################### # .PHONY: env-check platform-obj platform-inc # This makefile target will check the execution context and environment. # env-check: @[ -n "${PLATFORM}" ] || { echo "Error: Invalid environment." ; exit 1 ; } @[ -n "${PLATFORM_DIR}" ] || { echo "Error: Invalid environment." ; exit 1 ; } @[ -n "${OBJS_DIR}" ] || { echo "Error: Invalid environment." ; exit 1 ; } @[ -n "${DEFS_DIR}" ] || { echo "Error: Invalid environment." ; exit 1 ; } @[ -n "${OUT_INC_DIR}" ] || { echo "Error: Invalid environment." ; exit 1 ; } # This makefile target will compile the platform PAL objects. # platform-obj: env-check @for dir in $(${PLATFORM}_CDIR) ; do \ $(MAKE) -C $$dir platform-obj ; \ done # This makefile target will copy the platform includes to out_inc. # platform-inc: env-check @for dir in $(${PLATFORM}_CDIR) ; do \ $(MAKE) -C $$dir platform-inc ; \ done # # ########################################################################### gogoc-1_2-RELEASE/gogoc-pal/platform/netbsd/0040755000000000000000000000000011346561541017274 5ustar rootrootgogoc-1_2-RELEASE/gogoc-pal/platform/netbsd/inc/0040755000000000000000000000000011346561541020045 5ustar rootrootgogoc-1_2-RELEASE/gogoc-pal/platform/netbsd/inc/pal_unistd.h0100644000000000000000000000170111301543032022336 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal_unistd.h,v 1.1 2009/11/20 16:38:50 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer for unistd. ----------------------------------------------------------------------------- */ #ifndef __PAL_UNISTD_H__ #define __PAL_UNISTD_H__ // unistd API definitions. #include "pal_unistd.def" #include // unistd functions already available in this platform. #undef pal_getcwd #define pal_getcwd getcwd #undef pal_chdir #define pal_chdir chdir #undef pal_unlink #define pal_unlink unlink // unistd functions that need coding. #undef pal_sleep void pal_sleep ( uint32_t ); #endif gogoc-1_2-RELEASE/gogoc-pal/platform/netbsd/src/0040755000000000000000000000000011346561541020063 5ustar rootrootgogoc-1_2-RELEASE/gogoc-pal/platform/netbsd/src/pal_unistd.c0100644000000000000000000000205711301543033022355 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal_unistd.c,v 1.1 2009/11/20 16:38:51 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer for unistd. ----------------------------------------------------------------------------- */ #include "pal_types.h" #include "pal_unistd.h" // -------------------------------------------------------------------------- // The implementation of usleep on NetBSD does not allow a // parameter >= 1000000(1 second) for input. So the sleep time is broken // in a call to sleep for the seconds, and then usleep for the remaining // milliseconds. // void pal_sleep( uint32_t sleep_ms ) { uint32_t seconds = sleep_ms / 1000; uint32_t miliseconds = sleep_ms % 1000; sleep(seconds); usleep(miliseconds * 1000); // microseconds. } gogoc-1_2-RELEASE/gogoc-pal/platform/netbsd/Makefile0100644000000000000000000000252411301543032020716 0ustar rootroot# ########################################################################### # # $Id: Makefile,v 1.1 2009/11/20 16:38:50 jasminko Exp $ # # Copyright (c) 2007 gogo6 Inc. All rights reserved. # # For license information refer to CLIENT-LICENSE.TXT # # Description: Makefile for the netbsd platform # # Author: Charles Nepveu # # Date: August 2007 # # ########################################################################### # INC_DIR:=inc SRC_DIR:=src UNIXCOMMON_INC=../unix-common/inc COMMON_INC=../common/inc ifdef DEBUG CFLAGS+=-c -g -I${DEFS_DIR} -I${INC_DIR} -I${UNIXCOMMON_INC} -I${COMMON_INC} -DPLATFORM=\"${PLATFORM}\" -DDEBUG ${EXTRA_CFLAGS} else CFLAGS+=-c -O2 -I${DEFS_DIR} -I${INC_DIR} -I${UNIXCOMMON_INC} -I${COMMON_INC} -DPLATFORM=\"${PLATFORM}\" ${EXTRA_CFLAGS} endif OBJS:=$(patsubst ${SRC_DIR}/%.c,${OBJS_DIR}/%.o,$(wildcard ${SRC_DIR}/*.c)) .PHONY: platform-obj platform-inc # # ########################################################################### # platform-obj: ${OBJS} ${OBJS_DIR}/pal_unistd.o: ${SRC_DIR}/pal_unistd.c ${INC_DIR}/pal_unistd.h $(CC) ${CFLAGS} -o $@ ${SRC_DIR}/pal_unistd.c # # ########################################################################### # platform-inc: @cp -f $(wildcard ${INC_DIR}/*.*) $(OUT_INC_DIR) # # ########################################################################### gogoc-1_2-RELEASE/gogoc-pal/platform/unix-common/0040755000000000000000000000000011346561541020266 5ustar rootrootgogoc-1_2-RELEASE/gogoc-pal/platform/unix-common/inc/0040755000000000000000000000000011346561541021037 5ustar rootrootgogoc-1_2-RELEASE/gogoc-pal/platform/unix-common/inc/pal_criticalsection.h0100644000000000000000000000210411301543034025201 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal_criticalsection.h,v 1.1 2009/11/20 16:38:52 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer critical section definitions. ----------------------------------------------------------------------------- */ #ifndef __PAL_CRITICALSECTION_H__ #define __PAL_CRITICALSECTION_H__ #include typedef pthread_mutex_t pal_cs_t; // Critical section API definitions. #include "pal_criticalsection.def" // Critical section functions already available in this platform. #undef pal_init_cs #define pal_init_cs(X) pthread_mutex_init(X, NULL) #undef pal_enter_cs #define pal_enter_cs pthread_mutex_lock #undef pal_leave_cs #define pal_leave_cs pthread_mutex_unlock #undef pal_free_cs #define pal_free_cs pthread_mutex_destroy #endif gogoc-1_2-RELEASE/gogoc-pal/platform/unix-common/inc/pal_errno.h0100644000000000000000000000114011301543034023146 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal_errno.h,v 1.1 2009/11/20 16:38:52 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer errno definition. ----------------------------------------------------------------------------- */ #ifndef __PAL_ERRNO_H__ #define __PAL_ERRNO_H__ #include #endif gogoc-1_2-RELEASE/gogoc-pal/platform/unix-common/inc/pal_getopt.h0100644000000000000000000000134411301543034023331 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal_getopt.h,v 1.1 2009/11/20 16:38:52 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer for 'getopt'. ----------------------------------------------------------------------------- */ #ifndef __PAL_GETOPT_H__ #define __PAL_GETOPT_H__ // getopt API definition. #include "pal_getopt.def" // getopt function already available in this platform. #undef pal_getopt #define pal_getopt getopt #endif gogoc-1_2-RELEASE/gogoc-pal/platform/unix-common/inc/pal_inet.h0100644000000000000000000000167711301543034022777 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal_inet.h,v 1.1 2009/11/20 16:38:52 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer for inet. ----------------------------------------------------------------------------- */ #ifndef __PAL_INET_H__ #define __PAL_INET_H__ // inet API definitions. #include "pal_inet.def" #include #include #include #include #include #include #include #include #include // inet functions already available in this platform. #undef pal_inet_pton #define pal_inet_pton inet_pton #endif gogoc-1_2-RELEASE/gogoc-pal/platform/unix-common/inc/pal_process.h0100644000000000000000000000147111301543035023507 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal_process.h,v 1.1 2009/11/20 16:38:53 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer process definitions. ----------------------------------------------------------------------------- */ #ifndef __PAL_PROCESS_H__ #define __PAL_PROCESS_H__ // process API definitions. #include "pal_process.def" #include // process functions already available in this platform. #undef pal_getpid #define pal_getpid getpid #undef pal_getppid #define pal_getppid getppid #endif gogoc-1_2-RELEASE/gogoc-pal/platform/unix-common/inc/pal_socket.h0100644000000000000000000000212511301543035023316 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal_socket.h,v 1.1 2009/11/20 16:38:53 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer for socket. ----------------------------------------------------------------------------- */ #ifndef __PAL_SOCKET_H__ #define __PAL_SOCKET_H__ typedef sint32_t pal_socket_t; // socket API definitions. #include "pal_socket.def" #include // socket shutdown modes. #define PAL_SOCK_SHTDN_BOTH SHUT_RDWR #define PAL_SOCK_SHTDN_READ SHUT_RD #define PAL_SOCK_SHTDN_WRITE SHUT_WR // socket functions already available in this platform. #undef pal_socket #define pal_socket (pal_socket_t)socket #undef pal_connect #define pal_connect connect #undef pal_shutdown #define pal_shutdown shutdown #undef pal_closesocket #define pal_closesocket close #endif gogoc-1_2-RELEASE/gogoc-pal/platform/unix-common/inc/pal_stdarg.h0100644000000000000000000000113611301543035023313 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal_stdarg.h,v 1.1 2009/11/20 16:38:53 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer for stdarg. ----------------------------------------------------------------------------- */ #ifndef __PAL_STDARG_H__ #define __PAL_STDARG_H__ #include #endif gogoc-1_2-RELEASE/gogoc-pal/platform/unix-common/inc/pal_stdlib.h0100644000000000000000000000202611301543035023307 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal_stdlib.h,v 1.1 2009/11/20 16:38:53 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer stdlib definitions. ----------------------------------------------------------------------------- */ #ifndef __PAL_STDLIB_H__ #define __PAL_STDLIB_H__ // stdlib API definitions. #include "pal_stdlib.def" #include #include #include #include // Stdlib functions already available in this platform. #undef pal_free #define pal_free free #undef pal_malloc #define pal_malloc malloc #undef pal_putenv #define pal_putenv putenv #undef pal_srandom #define pal_srandom srand #undef pal_random #define pal_random rand #undef pal_system #define pal_system system #endif gogoc-1_2-RELEASE/gogoc-pal/platform/unix-common/inc/pal_string.h0100644000000000000000000000253511301543035023341 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal_string.h,v 1.1 2009/11/20 16:38:53 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer for string functions. ----------------------------------------------------------------------------- */ #ifndef __PAL_STRING_H__ #define __PAL_STRING_H__ // String API definitions. #include "pal_string.def" #include // String functions already available in this platform. #undef pal_strcpy #define pal_strcpy strcpy #undef pal_strncpy #define pal_strncpy strncpy #undef pal_strlen #define pal_strlen (uint32_t)strlen #undef pal_strcat #define pal_strcat strcat #undef pal_strncat #define pal_strncat strncat #undef pal_printf #define pal_printf printf #undef pal_sprintf #define pal_sprintf sprintf #undef pal_snprintf #define pal_snprintf snprintf #undef pal_vsnprintf #define pal_vsnprintf vsnprintf #undef pal_memcpy #define pal_memcpy memcpy #undef pal_strdup #define pal_strdup strdup #undef pal_strcasecmp #define pal_strcasecmp strcasecmp #undef pal_strncasecmp #define pal_strncasecmp strncasecmp #endif gogoc-1_2-RELEASE/gogoc-pal/platform/unix-common/inc/pal_syslog.h0100644000000000000000000000154311301543035023351 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal_syslog.h,v 1.1 2009/11/20 16:38:53 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer for 'syslog'. ----------------------------------------------------------------------------- */ #ifndef __PAL_SYSLOG_H__ #define __PAL_SYSLOG_H__ // syslog API definition. #include "pal_syslog.def" #include // syslog function already available in this platform. #undef pal_openlog #define pal_openlog openlog #undef pal_syslog #define pal_syslog syslog #undef pal_closelog #define pal_closelog closelog #endif gogoc-1_2-RELEASE/gogoc-pal/platform/unix-common/inc/pal_thread.h0100644000000000000000000000215711301543035023302 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal_thread.h,v 1.1 2009/11/20 16:38:53 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer thread definitions. ----------------------------------------------------------------------------- */ #ifndef __PAL_THREAD_H__ #define __PAL_THREAD_H__ #include #define PAL_THREAD_CALL typedef pthread_t pal_thread_t; typedef void * pal_thread_ret_t; typedef pal_thread_ret_t (*pal_thread_funct)(void *); // Thread API definitions. #include "pal_thread.def" // Thread functions already available in this platform. #undef pal_thread_create #define pal_thread_create(X, Y, Z) pthread_create(X, NULL, Y, Z) #undef pal_thread_exit #define pal_thread_exit pthread_exit #undef pal_thread_join #define pal_thread_join pthread_join #endif gogoc-1_2-RELEASE/gogoc-pal/platform/unix-common/inc/pal_time.h0100644000000000000000000000160311301543035022764 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal_time.h,v 1.1 2009/11/20 16:38:53 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer time definitions. ----------------------------------------------------------------------------- */ #ifndef __PAL_TIME_H__ #define __PAL_TIME_H__ // time API definitions. #include "pal_time.def" #include #include // time functions already available in this platform. #undef pal_gettimeofday #define pal_gettimeofday(X) gettimeofday(X, NULL) #undef pal_localtime #define pal_localtime localtime #undef pal_time #define pal_time time #endif gogoc-1_2-RELEASE/gogoc-pal/platform/unix-common/inc/pal_types.h0100644000000000000000000000206211301543036023173 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal_types.h,v 1.1 2009/11/20 16:38:54 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer for various type definitions. ----------------------------------------------------------------------------- */ #ifndef __PAL_TYPES_H__ #define __PAL_TYPES_H__ // Definitions #undef NULL #define NULL (0) /* Causes conflicts on OpenBSD // Length type definitions typedef unsigned int size_t; typedef signed int ssize_t; */ // Pointer type defintion typedef unsigned int ptr_t; // Integer type definitions typedef unsigned int uint32_t; typedef signed int sint32_t; typedef unsigned short uint16_t; typedef signed short sint16_t; typedef unsigned char uint8_t; typedef signed char sint8_t; #endif gogoc-1_2-RELEASE/gogoc-pal/platform/unix-common/inc/pal_unistd.h0100644000000000000000000000161311301543036023336 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: pal_unistd.h,v 1.1 2009/11/20 16:38:54 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- Platform abstraction layer for unistd. ----------------------------------------------------------------------------- */ #ifndef __PAL_UNISTD_H__ #define __PAL_UNISTD_H__ // unistd API definitions. #include "pal_unistd.def" #include // unistd functions already available in this platform. #undef pal_getcwd #define pal_getcwd getcwd #undef pal_chdir #define pal_chdir chdir #undef pal_sleep #define pal_sleep(x) usleep((x) * 1000) #undef pal_unlink #define pal_unlink unlink #endif gogoc-1_2-RELEASE/gogoc-pal/platform/unix-common/Makefile0100644000000000000000000000225311301543033021710 0ustar rootroot# ########################################################################### # # $Id: Makefile,v 1.1 2009/11/20 16:38:51 jasminko Exp $ # # Copyright (c) 2007 gogo6 Inc. All rights reserved. # # For license information refer to CLIENT-LICENSE.TXT # # Description: Makefile for unix common platforms # # Author: Charles Nepveu # # Date: August 2007 # # ########################################################################### # INC_DIR:=inc SRC_DIR:=src COMMON_INC=../common/inc ifdef DEBUG CFLAGS:=-c -g -I${DEFS_DIR} -I${INC_DIR} -I${COMMON_INC} -DPLATFORM=\"${PLATFORM}\" -D_REENTRANT -DDEBUG ${EXTRA_CFLAGS} else CFLAGS:=-c -O2 -I${DEFS_DIR} -I${INC_DIR} -I${COMMON_INC} -DPLATFORM=\"${PLATFORM}\" -D_REENTRANT ${EXTRA_CFLAGS} endif OBJS:=$(patsubst ${SRC_DIR}/%.c,${OBJS_DIR}/%.o,$(wildcard ${SRC_DIR}/*.c)) .PHONY: platform-obj platform-inc # # ########################################################################### # platform-obj: ${OBJS} # # ########################################################################### # platform-inc: @cp -f $(wildcard ${INC_DIR}/*.*) $(OUT_INC_DIR) # # ########################################################################### gogoc-1_2-RELEASE/gogoc-config/0040755000000000000000000000000011346561546014667 5ustar rootrootgogoc-1_2-RELEASE/gogoc-config/gogocconfig/0040755000000000000000000000000011346561542017147 5ustar rootrootgogoc-1_2-RELEASE/gogoc-config/gogocconfig/config.h0100644000000000000000000000326111301542037020551 0ustar rootroot// ************************************************************************** // $Id: config.h,v 1.1 2009/11/20 16:30:23 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Provides a simple configuration accessor. This class contains means of // applying and cancelling configuration changes. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocconfig_config_h__ #define __gogocconfig_config_h__ #include namespace gogocconfig { // Type definitions. typedef enum { AM_READ, AM_CREATE, AM_RW } t_accessMode; // ------------------------------------------------------------------------ class Config { protected: Parser* m_pParser; // Generic parser object. t_accessMode m_eAccessMode; // Access mode to configuration. string m_sConfigFile; // Configuration file name. protected: // Construction / destruction Config ( const string& aConfigFile, const t_accessMode aEAccessMode ); public: virtual ~Config ( void ); virtual bool LoadConfiguration ( void ); // Load config data virtual bool ApplyConfiguration ( void ); // Save changes virtual bool CancelConfiguration ( void ); // Revert changes virtual bool OverrideConfiguration ( const string& aFileName ); }; } #endif gogoc-1_2-RELEASE/gogoc-config/gogocconfig/gogoc_c_wrapper.h0100644000000000000000000001100311334102266022437 0ustar rootroot/* *********************************************************************** */ /* $Id: gogoc_c_wrapper.h,v 1.2 2010/02/08 21:40:06 jasminko Exp $ */ /* */ /* Copyright (c) 2007 gogo6 Inc. All rights reserved. */ /* */ /* For license information refer to CLIENT-LICENSE.TXT */ /* */ /* Description: */ /* Wraps the gogoCLIENT Configuration subsystem to offer C access. */ /* */ /* Author: Charles Nepveu */ /* */ /* Creation Date: November 2006 */ /* _______________________________________________________________________ */ /* *********************************************************************** */ #ifndef __gogocconfig_gogoc_c_wrapper_h__ #define __gogocconfig_gogoc_c_wrapper_h__ #ifndef TBOOLEAN_DECLARED #define TBOOLEAN_DECLARED /* ----------------------------------------------------------------------- */ /* tBoolean is also declared in the gogoCLIENT. This is to avoid */ /* redefinition. */ /* ----------------------------------------------------------------------- */ #undef FALSE #undef TRUE typedef enum { FALSE=0, TRUE } tBoolean; #endif #ifdef __cplusplus extern "C" { #endif /* ----------------------------------------------------------------------- */ /* Configuration management functions. */ /* ----------------------------------------------------------------------- */ int initialize ( const char* ); void un_initialize ( void ); void get_config_errors ( int*, unsigned int*[] ); int save_config ( void ); /* ----------------------------------------------------------------------- */ /* Configuration accessors. */ /* ----------------------------------------------------------------------- */ void get_user_id ( char** ); void set_user_id ( char * ); void get_passwd ( char** ); void set_passwd ( char * ); void get_server ( char** ); void set_server ( char * ); void get_host_type ( char** ); void get_prefixlen ( int* ); void get_ifprefix ( char** ); void get_dns_server ( char** ); void get_gogoc_dir ( char** ); void get_auth_method ( char** ); void get_auto_retry_connect( tBoolean* ); void get_retry_delay ( int* ); void get_retry_delay_max ( int* ); void get_keepalive ( tBoolean* ); void get_keepalive_interval( int* ); void get_tunnel_mode ( char** ); void get_if_tun_v6v4 ( char** ); void get_if_tun_v6udpv4 ( char** ); void get_if_tun_v4v6 ( char** ); void get_client_v4 ( char** ); void get_client_v6 ( char** ); void get_template ( char** ); void get_proxy_client ( tBoolean* ); void get_broker_list_file ( char** ); void get_last_server_file ( char** ); void get_always_use_last_server( tBoolean* ); void get_log ( const char*, short* ); void get_log_filename ( char** ); void get_log_rotation ( tBoolean* ); void get_log_rotation_sz ( int* ); void get_log_rotation_del ( tBoolean* ); void get_syslog_facility ( char** ); void get_haccess_proxy_enabled( tBoolean* ); void get_haccess_web_enabled ( tBoolean* ); void get_haccess_document_root( char** ); void get_dslite_server ( char** ); void get_dslite_client ( char** ); #ifdef __cplusplus } #endif #endif gogoc-1_2-RELEASE/gogoc-config/gogocconfig/gogocconfig.h0100644000000000000000000001742011334102266021574 0ustar rootroot// ************************************************************************** // $Id: gogocconfig.h,v 1.2 2010/02/08 21:40:06 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Wraps the NAME=VALUE configuration object to offer // gogoCLIENT-oriented configuration data accessors(get/set), along // with validation routines and error handling. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocconfig_gogocconfig_h__ #define __gogocconfig_gogocconfig_h__ #include #include #include using namespace std; namespace gogocconfig { // Type definitions. typedef vector t_errorarray; // ------------------------------------------------------------------------ class GOGOCConfig { private: NameValueConfig* m_pConfig; // The configuration accessor object. string m_sDfltCfgFile; // The default config file name (for LoadDefault()). t_errorarray m_lsValidationErrors; // The list of validation errors(for ValidateConfigData()). bool m_bValid; // A boolean indicating if data can successfully be retrieved or set. public: // Construction / destruction. GOGOCConfig ( void ); virtual ~GOGOCConfig ( void ); // Initialization. void Initialize ( const string& aConfigFile, const t_accessMode aEAccessMode, const string& aDfltCfgFile = "" ); // Load / Cancel / Save / Load defaults. bool Load ( void ); bool Save ( void ); bool CancelChanges ( void ); bool LoadDefaults ( void ); protected: // Validation and error retrieval routines bool ValidateConfigData ( void ); // Used by ::Load() public: bool IsConfigurationValid( void ) { return m_bValid; } const t_errorarray& GetValidationErrors ( void ) { return m_lsValidationErrors; } public: // gogoCLIENT Configuration Data accessors. void Get_UserID ( string& sUserID ) const; void Set_UserID ( const string& sUserID ); void Get_Passwd ( string& sPasswd ) const; void Set_Passwd ( const string& sPasswd ); void Get_Server ( string& sServer ) const; void Set_Server ( const string& sServer ); void Get_HostType ( string& sHostType ) const; void Set_HostType ( const string& sHostType ); void Get_PrefixLen ( string& sPrefixLen ) const; void Set_PrefixLen ( const string& sPrefixLen ); void Get_IfPrefix ( string& sIfPrefix ) const; void Set_IfPrefix ( const string& sIfPrefix ); void Get_DnsServer ( string& sDnsServer ) const; void Set_DnsServer ( const string& sDnsServer ); void Get_gogocDir ( string& sgogocDir ) const; void Set_gogocDir ( const string& sgogocDir ); void Get_AuthMethod ( string& sAuthMethod ) const; void Set_AuthMethod ( const string& sAuthMethod ); void Get_AutoRetryConnect( string& sAutoRetryConnect ) const; void Set_AutoRetryConnect( const string& sAutoRetryConnect ); void Get_RetryDelay ( string& sRetryDelay ) const; void Set_RetryDelay ( const string& sRetryDelay ); void Get_RetryDelayMax ( string& sRetryDelayMax ) const; void Set_RetryDelayMax ( const string& sRetryDelayMax ); void Get_KeepAlive ( string& sKeepAlive ) const; void Set_KeepAlive ( const string& sKeepAlive ); void Get_KeepAliveInterval( string& sKeepAliveInterval ) const; void Set_KeepAliveInterval( const string& sKeepAliveInterval ); void Get_TunnelMode ( string& sTunnelMode ) const; void Set_TunnelMode ( const string& sTunnelMode ); void Get_IfTunV6V4 ( string& sIfTunV6V4 ) const; void Set_IfTunV6V4 ( const string& sIfTunV6V4 ); void Get_IfTunV6UDPV4 ( string& sIfTunV6UDPV4 ) const; void Set_IfTunV6UDPV4 ( const string& sIfTunV6UDPV4 ); void Get_IfTunV4V6 ( string& sIfTunV4V6 ) const; void Set_IfTunV4V6 ( const string& sIfTunV4V6 ); void Get_ClientV4 ( string& sClientV4 ) const; void Set_ClientV4 ( const string& sClientV4 ); void Get_ClientV6 ( string& sClientV6 ) const; void Set_ClientV6 ( const string& sClientV6 ); void Get_Template ( string& sTemplate ) const; void Set_Template ( const string& sTemplate ); void Get_ProxyClient ( string& sProxyClient ) const; void Set_ProxyClient ( const string& sProxyClient ); void Get_BrokerLstFile ( string& sBrokerLstFile ) const; void Set_BrokerLstFile ( const string& sBrokerLstFile ); void Get_LastServFile ( string& sLastServFile ) const; void Set_LastServFile ( const string& sLastServFile ); void Get_AlwaysUseLastSrv( string& sAlwaysUseLastSrv ) const; void Set_AlwaysUseLastSrv( const string& sAlwaysUseLastSrv ); void Set_Log ( const string& sLogDevice, const string& sLogLevel ); void Get_Log ( const string& sLogDevice, string& sLogLevel ) const; void Get_LogFileName ( string& sLogFileName ) const; void Set_LogFileName ( const string& sLogFileName ); void Get_LogRotation ( string& sLogRotation ) const; void Set_LogRotation ( const string& sLogRotation ); void Get_LogRotationSz ( string& sLogRotationSz ) const; void Set_LogRotationSz ( const string& sLogRotationSz ); void Get_LogRotationDel ( string& sLogRotationDel ) const; void Set_LogRotationDel ( const string& sLogRotationDel ); void Get_SysLogFacility ( string& sSysLogFacility ) const; void Set_SysLogFacility ( const string& sSysLogFacility ); void Get_haccessProxyEnabled( string& shaccessProxyEnabled ) const; void Set_haccessProxyEnabled( const string& shaccessProxyEnabled ); void Get_haccessWebEnabled ( string& shaccessWebEnabled ) const; void Set_haccessWebEnabled ( const string& shaccessWebEnabled ); void Get_haccessDocumentRoot( string& shaccessDocumentRoot ) const; void Set_haccessDocumentRoot( const string& shaccessDocumentRoot ); void Get_DSLite_Server ( string& sDSLiteServer ) const; void Set_DSLite_Server ( const string& sDSLiteServer ); void Get_DSLite_Client ( string& sDSLiteClient ) const; void Set_DSLite_Client ( const string& sDSLiteClient ); }; } #endif gogoc-1_2-RELEASE/gogoc-config/gogocconfig/gogocuistrings.h0100644000000000000000000001637511301542040022356 0ustar rootroot/* *********************************************************************** */ /* $Id: gogocuistrings.h,v 1.1 2009/11/20 16:30:24 jasminko Exp $ */ /* */ /* Copyright (c) 2007 gogo6 Inc. All rights reserved. */ /* */ /* For license information refer to CLIENT-LICENSE.TXT */ /* */ /* Description: */ /* Contains the user interface(UI) strings of the gogoCLIENT Configuration */ /* subsystem. */ /* */ /* Author: Charles Nepveu */ /* */ /* Creation Date: November 2006 */ /* _______________________________________________________________________ */ /* *********************************************************************** */ #ifndef __gogocconfig_gogocuistrings_h__ #define __gogocconfig_gogocuistrings_h__ #ifndef ERRORT_DEFINED #define ERRORT_DEFINED typedef signed int error_t; #endif /* ----------------------------------------------------------------------- */ /* gogoCLIENT User Interface string ID definitions. */ /* ----------------------------------------------------------------------- */ #define GOGOC_UIS__NOERROR (error_t)0x00000000 #define GOGOC_UIS__GROUP_NAMEVALUEPARSER (error_t)0x00010000 #define GOGOC_UIS__NMP_OPENFAIL (error_t)0x00010001 #define GOGOC_UIS__NMP_BADCONFIGFILE (error_t)0x00010002 #define GOGOC_UIS__NMP_OPENFAILWRITE (error_t)0x00010003 #define GOGOC_UIS__GROUP_GENERICCONFIG (error_t)0x00020000 #define GOGOC_UIS__CFG_CANNOTLOADWHENCREATE (error_t)0x00020001 #define GOGOC_UIS__CFG_CANNOTAPPLYWHENREAD (error_t)0x00020002 #define GOGOC_UIS__CFG_CANNOTCANCELWHENREAD (error_t)0x00020003 #define GOGOC_UIS__CFG_CANNOTOVERRIDESAMECONTENTS (error_t)0x00020004 #define GOGOC_UIS__CFG_CANNOTOVERRIDEWHENREAD (error_t)0x00020005 #define GOGOC_UIS__GROUP_GOGOCCONFIG (error_t)0x00030000 #define GOGOC_UIS__G6C_INVALIDCONF (error_t)0x00030001 #define GOGOC_UIS__G6C_FAILLOADDFLTCONF (error_t)0x00030002 #define GOGOC_UIS__G6C_SUPPLYPASSWDWHENNOTANON (error_t)0x00030003 #define GOGOC_UIS__G6C_PROXYCINVALIDMODE (error_t)0x00030004 #define GOGOC_UIS__G6C_KAINTERVALINVALID (error_t)0x00030005 #define GOGOC_UIS__G6C_IFTUNV6V4ANDV6UDPV4REQUIRED (error_t)0x00030006 #define GOGOC_UIS__G6C_IFTUNV6V4REQUIRED (error_t)0x00030007 #define GOGOC_UIS__G6C_IFTUNV6UDPV4REQUIRED (error_t)0x00030008 #define GOGOC_UIS__G6C_IFTUNV4V6REQUIRED (error_t)0x00030009 #define GOGOC_UIS__GROUP_GOGOCVALIDATION (error_t)0x00040000 #define GOGOC_UIS__G6V_USERIDTOOLONG (error_t)0x00040001 #define GOGOC_UIS__G6V_USERIDINVALIDCHRS (error_t)0x00040002 #define GOGOC_UIS__G6V_PASSWDTOOLONG (error_t)0x00040003 #define GOGOC_UIS__G6V_SERVERMUSTBESPEC (error_t)0x00040004 #define GOGOC_UIS__G6V_SERVERTOOLONG (error_t)0x00040005 #define GOGOC_UIS__G6V_SERVERINVALIDCHRS (error_t)0x00040006 #define GOGOC_UIS__G6V_HOSTTYPEINVALIDVALUE (error_t)0x00040007 #define GOGOC_UIS__G6V_PREFIXLENINVALIDVALUE (error_t)0x00040008 #define GOGOC_UIS__G6V_IFPREFIXINVALIDCHRS (error_t)0x00040009 #define GOGOC_UIS__G6V_DNSSERVERSTOOLONG (error_t)0x0004000A #define GOGOC_UIS__G6V_DNSSERVERSUNRESOLVABLE (error_t)0x0004000B #define GOGOC_UIS__G6V_GOGOCDIRDOESNTEXIST (error_t)0x0004000C #define GOGOC_UIS__G6V_AUTHMETHODINVALIDVALUE (error_t)0x0004000D #define GOGOC_UIS__G6V_AUTORETRYCONNECTINVALIDVALUE (error_t)0x0004000E #define GOGOC_UIS__G6V_RETRYDELAYINVALIDVALUE (error_t)0x0004000F #define GOGOC_UIS__G6V_KEEPALIVEINVALIDVALUE (error_t)0x00040010 #define GOGOC_UIS__G6V_KEEPALIVEINTERVINVALID (error_t)0x00040011 #define GOGOC_UIS__G6V_TUNNELMODEINVALIDVALUE (error_t)0x00040012 #define GOGOC_UIS__G6V_IFTUNV6V4INVALIDCHRS (error_t)0x00040013 #define GOGOC_UIS__G6V_IFTUNV6UDPV4INVALIDCHRS (error_t)0x00040014 #define GOGOC_UIS__G6V_IFTUNV4V6INVALIDCHRS (error_t)0x00040015 #define GOGOC_UIS__G6V_CLIENTV4INVALIDVALUE (error_t)0x00040016 #define GOGOC_UIS__G6V_CLIENTV6INVALIDVALUE (error_t)0x00040017 #define GOGOC_UIS__G6V_TEMPLATEINVALIDVALUE (error_t)0x00040018 #define GOGOC_UIS__G6V_PROXYCLIENTINVALIDVALUE (error_t)0x00040019 #define GOGOC_UIS__G6V_BROKERLISTTOOLONG (error_t)0x0004001A #define GOGOC_UIS__G6V_BROKERLISTINVALIDCHRS (error_t)0x0004001B #define GOGOC_UIS__G6V_LASTSERVTOOLONG (error_t)0x0004001C #define GOGOC_UIS__G6V_LASTSERVINVALIDCHRS (error_t)0x0004001D #define GOGOC_UIS__G6V_ALWAYSUSERLASTSERVINVALIDVALUE (error_t)0x0004001E #define GOGOC_UIS__G6V_LOGLEVELINVALIDVALUE (error_t)0x0004001F #define GOGOC_UIS__G6V_LOGDEVICEINVALIDVALUE (error_t)0x00040020 #define GOGOC_UIS__G6V_LOGFILENAMETOOLONG (error_t)0x00040021 #define GOGOC_UIS__G6V_LOGFILENAMEINVALIDCHRS (error_t)0x00040022 #define GOGOC_UIS__G6V_LOGROTATIONINVALIDVALUE (error_t)0x00040023 #define GOGOC_UIS__G6V_LOGROTSZINVALIDVALUE (error_t)0x00040024 #define GOGOC_UIS__G6V_SYSLOGFACILITYINVALIDVALUE (error_t)0x00040025 #define GOGOC_UIS__G6V_DNSSERVERSINVALIDCHRS (error_t)0x00040026 #define GOGOC_UIS__G6V_HACCESSPROXYENABLEDINVALIDVALUE (error_t)0x00040027 #define GOGOC_UIS__G6V_HACCESSWEBENABLEDINVALIDVALUE (error_t)0x00040028 #define GOGOC_UIS__G6V_HACCESSDOCROOTDOESNTEXIST (error_t)0x00040029 #define GOGOC_UIS__G6V_HACCESSDOCROOTNOTSPEC (error_t)0x0004002A #define GOGOC_UIS__G6V_HACCESSINCOMPV4V6 (error_t)0x0004002B #define GOGOC_UIS__G6V_PASSWDINVALIDCHRS (error_t)0x0004002C #define GOGOC_UIS__G6V_IFPREFIXMUSTBESPEC (error_t)0x0004002D #define GOGOC_UIS__G6V_LOGROTDELINVALIDVALUE (error_t)0x0004002F #define GOGOC_UIS__G6C_PROXYANDKEEPALIVE (error_t)0x00040030 #define GOGOC_UIS__G6V_RETRYDELAYMAXINVALIDVALUE (error_t)0x00040031 #define GOGOC_UIS__G6V_RETRYDELAYGREATERRETRYDELAYMAX (error_t)0x00040032 /* ----------------------------------------------------------------------- */ /* Get string function. */ /* ----------------------------------------------------------------------- */ #ifdef __cplusplus extern "C" const char* get_ui_string( const error_t id ); #else const char* get_ui_string( const error_t id ); #endif #endif gogoc-1_2-RELEASE/gogoc-config/gogocconfig/gogocvalidation.h0100644000000000000000000001057311334102266022463 0ustar rootroot// ************************************************************************** // $Id: gogocvalidation.h,v 1.2 2010/02/08 21:40:06 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Implements functions to validate contents of gogoCLIENT // configuration data. // When errors are found in the data, the error message relative to the // error can be retrieved with the GetLastError() function. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocconfig_gogocvalidation_h__ #define __gogocconfig_gogocvalidation_h__ #include #include using namespace std; // These DEFINEs are used in other modules as well. #define STR_YES "yes" #define STR_NO "no" #define STR_ANONYMOUS "anonymous" #define STR_PLAIN "plain" #define STR_DIGESTMD5 "digest-md5" #define STR_PASSDSS3DES1 "passdss-3des-1" #define STR_V6V4 "v6v4" #define STR_V6ANYV4 "v6anyv4" #define STR_V6UDPV4 "v6udpv4" #define STR_V4V6 "v4v6" #define STR_DSLITE "dslite" #define STR_ANY "any" #define STR_AUTO "auto" #define STR_LOGDEV_CONSOLE "console" #define STR_LOGDEV_STDERR "stderr" #define STR_LOGDEV_FILE "file" #define STR_LOGDEV_SYSLOG "syslog" #define STR_HOSTTYPE_HOST "host" #define STR_HOSTTYPE_ROUTER "router" #define STR_TEMPL_WINDOWS "windows" #define STR_LOGROTSZ_16K "16" #define STR_LOGROTSZ_32K "32" #define STR_LOGROTSZ_128K "128" #define STR_LOGROTSZ_1024K "1024" namespace gogocconfig { // Error retrieval. const error_t GetLastError( void ); // Validation routines. bool Validate_UserID ( const string& sUserID ); bool Validate_Passwd ( const string& sPasswd ); bool Validate_Server ( const string& sServer ); bool Validate_HostType ( const string& sHostType ); bool Validate_PrefixLen ( const string& sPrefixLen ); bool Validate_IfPrefix ( const string& sIfPrefix ); bool Validate_DnsServer ( const string& sDnsServer ); bool Validate_gogocDir ( const string& sgogocDir ); bool Validate_AuthMethod ( const string& sAuthMethod ); bool Validate_AutoRetryConnect( const string& sAutoRetryConnect ); bool Validate_RetryDelay ( const string& sRetryDelay ); bool Validate_RetryDelayMax ( const string& sRetryDelayMax ); bool Validate_KeepAlive ( const string& sKeepAlive ); bool Validate_KeepAliveInterval( const string& sKeepAliveInterval ); bool Validate_TunnelMode ( const string& sTunnelMode ); bool Validate_IfTunV6V4 ( const string& sIfTunV6V4 ); bool Validate_IfTunV6UDPV4 ( const string& sIfTunV6UDPV4 ); bool Validate_IfTunV4V6 ( const string& sIfTunV4V6 ); bool Validate_ClientV4 ( const string& sClientV4 ); bool Validate_ClientV6 ( const string& sClientV6 ); bool Validate_Template ( const string& sTemplate ); bool Validate_ProxyClient ( const string& sProxyClient ); bool Validate_BrokerLstFile ( const string& sBrokerLstFile ); bool Validate_LastServFile ( const string& sLastServFile ); bool Validate_AlwaysUseLastSrv( const string& sAlwaysUseLastSrv ); bool Validate_LogDevice ( const string& sLogDevice ); bool Validate_LogLevel ( const string& sLogLevel ); bool Validate_LogFileName ( const string& sLogFileName ); bool Validate_LogRotation ( const string& sLogRotation ); bool Validate_LogRotationSz ( const string& sLogRotationSz ); bool Validate_LogRotationDel ( const string& sLogRotationDel ); bool Validate_SysLogFacility ( const string& sSysLogFacility ); bool Validate_haccessProxyEnabled( const string& shaccessProxyEnabled ); bool Validate_haccessWebEnabled ( const string& shaccessWebEnabled ); bool Validate_haccessDocumentRoot( const string& shaccessDocumentRoot ); bool Validate_DSLite ( const string& sDSLite ); } #endif gogoc-1_2-RELEASE/gogoc-config/gogocconfig/haccess_devmap_c_wrap.h0100644000000000000000000000453711301542040023605 0ustar rootroot/* *********************************************************************** */ /* $Id: haccess_devmap_c_wrap.h,v 1.1 2009/11/20 16:30:24 jasminko Exp $ */ /* */ /* Copyright (c) 2007 gogo6 Inc. All rights reserved. */ /* */ /* For license information refer to CLIENT-LICENSE.TXT */ /* */ /* Description: */ /*Wraps the HomeAccess Device Mapping configuration data to offer C access.*/ /* */ /* Author: Charles Nepveu */ /* */ /* Creation Date: Febuary 2007 */ /* _______________________________________________________________________ */ /* *********************************************************************** */ #ifndef __gogocconfig_haccess_devmap_c_wrap_h__ #define __gogocconfig_haccess_devmap_c_wrap_h__ #ifdef __cplusplus extern "C" { #endif // Structure definition to hold HomeAccess device mappings struct __DEVICE_MAPPING; typedef struct __DEVICE_MAPPING { char* szName; char* szAddress; struct __DEVICE_MAPPING* next; } DEVICE_MAPPING, *PDEVICE_MAPPING; /* ----------------------------------------------------------------------- */ /* HomeAccess Device Mapping management functions. */ /* ----------------------------------------------------------------------- */ int init_haccess_devmap ( const char* ); int reload_haccess_devmap ( void ); void uninit_haccess_devmap ( void ); /* ----------------------------------------------------------------------- */ /* HomeAccess Mapping data accessors. */ /* ----------------------------------------------------------------------- */ int get_device_mapping ( PDEVICE_MAPPING* ppDeviceMapping ); void free_device_mapping ( PDEVICE_MAPPING* ppDeviceMapping ); #ifdef __cplusplus } #endif #endif gogoc-1_2-RELEASE/gogoc-config/gogocconfig/haccessdevicemappingconfig.h0100644000000000000000000000476611301542040024644 0ustar rootroot// ************************************************************************** // $Id: haccessdevicemappingconfig.h,v 1.1 2009/11/20 16:30:24 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Wraps the NAME=VALUE configuration object to offer HomeAccess Device Mapping // generic accessors. // // Author: Charles Nepveu // // Creation Date: February 2007 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocconfig_haccessdevicemappingconfig_h__ #define __gogocconfig_haccessdevicemappingconfig_h__ #include #include #include #include using namespace std; namespace gogocconfig { // Type definition. typedef vector t_stringarray; typedef map t_stringmap; // ------------------------------------------------------------------------ class HACCESSDeviceMappingConfig { private: NameValueConfig* m_pConfig; // The configuration accessor object. public: // Construction / destruction. HACCESSDeviceMappingConfig( void ); virtual ~HACCESSDeviceMappingConfig( void ); // Initialization. void Initialize ( const string& aConfigFile, const t_accessMode aEAccessMode ); // Load / Cancel / Save. bool Load ( void ); bool Save ( void ); bool CancelChanges ( void ); // Validation routine. bool ValidateConfig ( void ); // HomeAccess Device Mapping Configuration accessors. bool AddDeviceMapping ( const string& aName, const string& aAddress ); bool DelDeviceMapping ( const string& aName ); bool GetDeviceAddress ( const string& aName, string& aAddress ) const; bool SetDeviceAddress ( const string& aName, const string& aAddress ); bool GetDeviceNameList ( t_stringarray& aNameList ) const; bool GetDeviceList ( t_stringmap& aDeviceMap ) const; private: bool ValidateDeviceName ( const string& aDeviceName ); bool ValidateIPAddress ( const string& aIPAddress ); }; } #endif gogoc-1_2-RELEASE/gogoc-config/gogocconfig/namevalueconfig.h0100644000000000000000000000311511301542040022437 0ustar rootroot// ************************************************************************** // $Id: namevalueconfig.h,v 1.1 2009/11/20 16:30:24 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // This class provides access to the NAME=VALUE configuration data. // Consultation and modification of configuration data is allowed. // This class extends the Config class. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocconfig_namevalueconfig_h__ #define __gogocconfig_namevalueconfig_h__ #include #include using namespace std; namespace gogocconfig { // Type definitions. typedef list stringlist; // ------------------------------------------------------------------------ class NameValueConfig : public Config { public: // Construction / destruction NameValueConfig ( const string& aFileName, const t_accessMode aEAccessMode ); virtual ~NameValueConfig ( void ); // NameValueConfig operations void GetVariableValue ( const string& aName, string& aValue ) const; void SetVariableValue ( const string& aName, const string& aValue ); void RemoveVariable ( const string& aName ); void GetVariableNameList ( stringlist& aList ) const; }; } #endif gogoc-1_2-RELEASE/gogoc-config/gogocconfig/namevalueparser.h0100644000000000000000000000425411301542041022474 0ustar rootroot// ************************************************************************** // $Id: namevalueparser.h,v 1.1 2009/11/20 16:30:25 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Provides a means of parsing NAME=VALUE UNIX-style configuration files. // This class extends the generic Parser class. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocconfig_namevalueparser_h__ #define __gogocconfig_namevalueparser_h__ #include #include #include using namespace std; namespace gogocconfig { // Type definitions. typedef enum { NVP_READ_ALL, NVP_READ_NAMEVALUE } t_eReadMode; typedef enum { NVP_DATA_NV, NVP_DATA_COMMENT, NVP_DATA_EMPTYLINE } t_eDataType; typedef map t_nameValueData; typedef list > t_fullFileData; // ------------------------------------------------------------------------ class NameValueParser : public Parser { protected: t_eReadMode m_eReadMode; // Read mode. t_nameValueData m_NameValue; // Holds the Name=Value data. t_fullFileData m_FullFileData; // Holds the full file data. public: // Construction / destruction NameValueParser ( const t_eReadMode aReadMode = NVP_READ_NAMEVALUE ); virtual ~NameValueParser ( void ); // Overrides virtual bool ReadConfigurationData ( const string& aFilename ); virtual bool WriteConfigurationData( const string& aFilename ); // Public configuration accessor t_nameValueData& GetConfigurationData ( void ) { return m_NameValue; } t_fullFileData& GetFullFileData ( void ) { return m_FullFileData; } protected: virtual void AddEmptyLine ( void ); virtual void AddComment ( const string& aComment ); virtual void AddNameValue ( const string& aName, const string& aValue ); }; } #endif gogoc-1_2-RELEASE/gogoc-config/gogocconfig/parser.h0100644000000000000000000000216311301542041020573 0ustar rootroot// ************************************************************************** // $Id: parser.h,v 1.1 2009/11/20 16:30:25 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Provides a generic means of parsing a file. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocconfig_parser_h__ #define __gogocconfig_parser_h__ #include using namespace std; namespace gogocconfig { // ------------------------------------------------------------------------ class Parser { protected: // Construction / destruction Parser ( void ) {;}; public: virtual ~Parser ( void ) {;}; public: // Pure abstract virtual bool ReadConfigurationData ( const string& aFilename ) = 0; virtual bool WriteConfigurationData( const string& aFilename ) = 0; }; } #endif gogoc-1_2-RELEASE/gogoc-config/.cvsignore0100644000000000000000000000000111301064546016640 0ustar rootroot gogoc-1_2-RELEASE/gogoc-config/Makefile0100644000000000000000000000744711301542037016321 0ustar rootroot# ########################################################################### # # $Id: Makefile,v 1.1 2009/11/20 16:30:23 jasminko Exp $ # # Copyright (c) 2007 gogo6 Inc. All rights reserved. # # For license information refer to CLIENT-LICENSE.TXT # # Author: Charles Nepveu # # ########################################################################### # OBJ_DIR=objs BIN_DIR=bin LIB_DIR=lib INC_DIR=gogocconfig TARGET=$(LIB_DIR)/libgogocconfig.a GOGOCPAL=../gogoc-pal GOGOCPALINC_DIR=$(GOGOCPAL)/out_inc GOGOCPALDEFS_DIR=$(GOGOCPAL)/defs GOGOCPALLIB_DIR=$(GOGOCPAL)/out_lib GOGOCPALLIB=gogocpal CC=gcc CXX=g++ LD=g++ RANLIB=ranlib AR=ar ifdef DEBUG CXXFLAGS=-g -I. -I$(GOGOCPALINC_DIR) -I$(GOGOCPALDEFS_DIR) -Wall -D_REENTRANT -DDEBUG $(HACCESS_DEFINES) $(EXTRA_CXXFLAGS) CFLAGS=-g -I. -I$(GOGOCPALINC_DIR) -I$(GOGOCPALDEFS_DIR) -Wall -D_REENTRANT -DDEBUG $(HACCESS_DEFINES) $(EXTRA_CFLAGS) LDFLAGS=-g -L$(LIB_DIR) -L$(GOGOCPALLIB_DIR) -lgogocconfig -l$(GOGOCPALLIB) $(EXTRA_LDFLAGS) else CXXFLAGS=-O2 -I. -I$(GOGOCPALINC_DIR) -I$(GOGOCPALDEFS_DIR) -Wall -D_REENTRANT -DNDEBUG $(HACCESS_DEFINES) $(EXTRA_CXXFLAGS) CFLAGS=-O2 -I. -I$(GOGOCPALINC_DIR) -I$(GOGOCPALDEFS_DIR) -Wall -D_REENTRANT -DNDEBUG $(HACCESS_DEFINES) $(EXTRA_CFLAGS) LDFLAGS=-O2 -L$(LIB_DIR) -L$(GOGOCPALLIB_DIR) -lgogocconfig -l$(GOGOCPALLIB) $(EXTRA_LDFLAGS) endif .PHONY: all clean test_targets # # all: $(TARGET) $(BIN_DIR) $(OBJ_DIR): mkdir -p $(OBJ_DIR) $(BIN_DIR): mkdir -p $(BIN_DIR) $(LIB_DIR): mkdir -p $(LIB_DIR) OBJS=$(OBJ_DIR)/namevalueparser.o \ $(OBJ_DIR)/config.o \ $(OBJ_DIR)/namevalueconfig.o \ $(OBJ_DIR)/gogocvalidation.o \ $(OBJ_DIR)/gogocconfig.o \ $(OBJ_DIR)/gogoc_c_wrapper.o \ $(OBJ_DIR)/gogocuistrings.o \ $(OBJ_DIR)/haccess_devmap_c_wrap.o \ $(OBJ_DIR)/haccessdevicemappingconfig.o $(OBJ_DIR)/namevalueparser.o: src/namevalueparser.cc $(INC_DIR)/namevalueparser.h $(CXX) $(CXXFLAGS) -c -o $(OBJ_DIR)/namevalueparser.o src/namevalueparser.cc $(OBJ_DIR)/config.o: src/config.cc $(INC_DIR)/config.h $(CXX) $(CXXFLAGS) -c -o $(OBJ_DIR)/config.o src/config.cc $(OBJ_DIR)/namevalueconfig.o: src/namevalueconfig.cc $(INC_DIR)/namevalueconfig.h $(CXX) $(CXXFLAGS) -c -o $(OBJ_DIR)/namevalueconfig.o src/namevalueconfig.cc $(OBJ_DIR)/gogocvalidation.o: src/gogocvalidation.cc $(INC_DIR)/gogocvalidation.h $(CXX) $(CXXFLAGS) -c -o $(OBJ_DIR)/gogocvalidation.o src/gogocvalidation.cc $(OBJ_DIR)/gogocconfig.o: src/gogocconfig.cc $(INC_DIR)/gogocconfig.h $(CXX) $(CXXFLAGS) -c -o $(OBJ_DIR)/gogocconfig.o src/gogocconfig.cc $(OBJ_DIR)/gogoc_c_wrapper.o: src/gogoc_c_wrapper.cc $(INC_DIR)/gogoc_c_wrapper.h $(CXX) $(CXXFLAGS) -c -o $(OBJ_DIR)/gogoc_c_wrapper.o src/gogoc_c_wrapper.cc $(OBJ_DIR)/gogocuistrings.o: src/gogocuistrings.c $(INC_DIR)/gogocuistrings.h $(CC) $(CFLAGS) -c -o $(OBJ_DIR)/gogocuistrings.o src/gogocuistrings.c $(OBJ_DIR)/test_namevalue.o: src/test_namevalue.cc $(CXX) $(CXXFLAGS) -c -o $(OBJ_DIR)/test_namevalue.o src/test_namevalue.cc $(OBJ_DIR)/test_c_wrapper.o: src/test_c_wrapper.c $(CC) $(CFLAGS) -c -o $(OBJ_DIR)/test_c_wrapper.o src/test_c_wrapper.c $(OBJ_DIR)/haccess_devmap_c_wrap.o: src/haccess_devmap_c_wrap.cc $(CXX) $(CXXFLAGS) -c -o $(OBJ_DIR)/haccess_devmap_c_wrap.o src/haccess_devmap_c_wrap.cc $(OBJ_DIR)/haccessdevicemappingconfig.o: src/haccessdevicemappingconfig.cc $(CXX) $(CXXFLAGS) -c -o $(OBJ_DIR)/haccessdevicemappingconfig.o src/haccessdevicemappingconfig.cc test_targets: $(TARGET) $(OBJ_DIR)/test_namevalue.o $(OBJ_DIR)/test_c_wrapper.o $(BIN_DIR) $(LD) -o $(BIN_DIR)/test_namevalue $(OBJ_DIR)/test_namevalue.o $(LDFLAGS) $(LD) -o $(BIN_DIR)/test_c_wrapper $(OBJ_DIR)/test_c_wrapper.o $(LDFLAGS) $(TARGET): $(OBJ_DIR) $(OBJS) $(LIB_DIR) $(AR) cru $(TARGET) $(OBJS) $(RANLIB) $(TARGET) clean: @echo -n "Cleaning up workspace... " @rm -rf $(OBJ_DIR) $(BIN_DIR) $(LIB_DIR) @echo "done." gogoc-1_2-RELEASE/gogoc-config/README0100644000000000000000000000214011301542037015522 0ustar rootroot$ Id: $ ------------------------------------------------------------------------------ Copyright (c) 2007 gogo6 Inc. All rights reserved. ------------------------------------------------------------------------------ This directory contains the gogoCLIENT Configuration Subsystem. Subdirectories: .\gogocconfig\ - Contains the include files of the Configuration Subsystem. .\src\ - Contains the source files of the Configuration Subsystem. .\lib\ - Will contain the built gogoCLIENT Configuration Subsystem library. .\winbuild\ - Visual Studio project directories for winpc and wince. Files: .\Makefile - Makefile to build gogoc-config on UNIX-like platforms. .\build-winpc.cmd - Command script to build gogoc-config on Windows (XP, Vista). .\build-wince.cmd - Command script to build gogoc-config on Windows Embedded. Applications that use this library should modify the CFLAGS to add the following: -I/gogocconfig LDFLAGS: -L/lib -lgogocconfig gogoc-1_2-RELEASE/gogoc-config/build-wince.cmd0100644000000000000000000000307611301542037017542 0ustar rootroot@ECHO OFF REM ************************************************************************* REM * $Id: build-wince.cmd,v 1.1 2009/11/20 16:30:23 jasminko Exp $ REM * REM * Batch file used to build the gogoCLIENT Configuration Subsystem. REM * REM * Prerequisites: REM * - Visual Studio 2005 (SP1) REM * - Windows Embedded CE (5 or 6) SDK REM * - DEVENV executable in %PATH% REM * REM * Usage: REM * build-wince [/Release /Debug] REM * REM ************************************************************************* REM Defaults: SET CONFIGURATION=Release SET PLATFORM= SET COMMAND=Build REM Overrides: :ParseArgs IF /I "%~1" == "/?" GOTO Usage IF /I "%~1" == "-h" GOTO Usage IF /I "%~1" == "/Release" SET CONFIGURATION=Release& SHIFT& GOTO ParseArgs IF /I "%~1" == "/Debug" SET CONFIGURATION=Debug& SHIFT& GOTO ParseArgs IF /I "%~1" == "/Clean" SET COMMAND=Clean& SHIFT& GOTO ParseArgs IF "%~1" EQU "" GOTO Done_Args ECHO Unknown command-line switch: %~1 GOTO Usage :Done_Args REM Build the target ECHO Launching build of gogoc-config solution... ECHO Configuration: COMMAND=%COMMAND% CONFIGURATION=%CONFIGURATION% ECHO. DEVENV winbuild\wince\gogoc-config.sln /%COMMAND% "%CONFIGURATION%" IF %ERRORLEVEL% == 0 GOTO build_ok GOTO build_error :Usage ECHO. ECHO Usage: ECHO %0 ^[^/Release^|^/Debug^] ^[^/Clean^] ECHO. ECHO Defaults: ^/Release ECHO. GOTO the_end :build_ok ECHO. ECHO Build of gogoc-config solution completed successfully. GOTO the_end :build_error ECHO. ECHO Build of gogoc-config solution FAILED! :the_end gogoc-1_2-RELEASE/gogoc-config/build-winpc.cmd0100644000000000000000000000404711301542037017554 0ustar rootroot@ECHO OFF REM ************************************************************************* REM * $Id: build-winpc.cmd,v 1.1 2009/11/20 16:30:23 jasminko Exp $ REM * REM * Batch file used to build the gogoCLIENT Configuration Subsystem. REM * REM * Prerequisites: REM * - Visual Studio 2005 (SP1) REM * - Windows Vista RTM SDK (Integrated in VS2005SP1) REM * - DEVENV executable in %PATH% REM * REM * Usage: REM * build-gogoc [/Release /HACCESS-Release /Debug /HACCESS-Debug] [/Win32 /x64] REM * REM ************************************************************************* REM Defaults: SET CONFIGURATION=Release SET PLATFORM=Win32 SET COMMAND=Build REM Overrides: :ParseArgs IF /I "%~1" == "/?" GOTO Usage IF /I "%~1" == "-h" GOTO Usage IF /I "%~1" == "/Release" SET CONFIGURATION=Release& SHIFT& GOTO ParseArgs IF /I "%~1" == "/HACCESS-Release" SET CONFIGURATION=HACCESS-Release& SHIFT& GOTO ParseArgs IF /I "%~1" == "/Debug" SET CONFIGURATION=Debug& SHIFT& GOTO ParseArgs IF /I "%~1" == "/HACCESS-Debug" SET CONFIGURATION=HACCESS-Debug& SHIFT& GOTO ParseArgs IF /I "%~1" == "/Win32" SET PLATFORM=Win32& SHIFT& GOTO ParseArgs IF /I "%~1" == "/x64" SET PLATFORM=x64& SHIFT& GOTO ParseArgs IF /I "%~1" == "/Clean" SET COMMAND=Clean& SHIFT& GOTO ParseArgs IF "%~1" EQU "" GOTO Done_Args ECHO Unknown command-line switch: %~1 GOTO Usage :Done_Args REM Build the target ECHO Launching build of gogoc-config solution... ECHO Configuration: COMMAND=%COMMAND% PLATFORM=%PLATFORM% CONFIGURATION=%CONFIGURATION% ECHO. DEVENV winbuild\winpc\gogoc-config.sln /%COMMAND% "%CONFIGURATION%|%PLATFORM%" IF %ERRORLEVEL% == 0 GOTO build_ok GOTO build_error :Usage ECHO. ECHO Usage: ECHO %0 ^[^/Release^|^/HACCESS-Release^|^/Debug^|^/HACCESS-Debug^] ^[^/Win32^|^/x64^] ^[^/Clean^] ECHO. ECHO Defaults: ^/Release ^/Win32 ECHO. GOTO the_end :build_ok ECHO. ECHO Build of gogoc-config solution completed successfully. GOTO the_end :build_error ECHO. ECHO Build of gogoc-config solution FAILED! :the_end gogoc-1_2-RELEASE/gogoc-config/src/0040755000000000000000000000000011346561546015456 5ustar rootrootgogoc-1_2-RELEASE/gogoc-config/src/config.cc0100644000000000000000000001434211301542041017207 0ustar rootroot// ************************************************************************** // $Id: config.cc,v 1.1 2009/11/20 16:30:25 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Implementation of the Config class // // Description: // Provides a simple implementation to read configuration data, write or // discard changes done to the configuration data. // NOTE: This class cannot be instantiated directly. It is meant to be // overriden and specialized. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #include #include #include namespace gogocconfig { // -------------------------------------------------------------------------- // Function : Config constructor [PROTECTED] // // Description: // Will initialize a new Config object. // // Arguments: // aConfigFile: string [IN], The configuration file name. // aEAccessMode: enum [IN], Contains the access mode. // // Return values: (N/A) // // Exceptions: (none) // // -------------------------------------------------------------------------- Config::Config( const string& aConfigFile, const t_accessMode aEAccessMode ) : m_pParser(NULL), m_eAccessMode(aEAccessMode), m_sConfigFile(aConfigFile) { } // -------------------------------------------------------------------------- // Function : Config destructor // // Description: // Will destroy the class. // // Arguments: (none) // // Return values: (N/A) // // Exceptions: (none) // // -------------------------------------------------------------------------- Config::~Config( void ) { } // -------------------------------------------------------------------------- // Function : LoadConfiguration // // Description: // Will attempt to load the configuration data from the configuration file. // Operation specifics are delegated to the Parser object. // // Arguments: (none) // // Return values: // true if parser successfully parsed the configuration data, false // otherwise. // // Exceptions: // - When access mode is incoherent with operation. // See Parser::ReadConfigurationData(). // // -------------------------------------------------------------------------- bool Config::LoadConfiguration( void ) { assert( m_pParser != NULL ); // Need to have a parser! // If access mode is CREATE, we're not suposed to load any existing // configuration. if( m_eAccessMode == AM_CREATE ) { throw GOGOC_UIS__CFG_CANNOTLOADWHENCREATE; } // Read configuration. // May throw exception if file doesn't exist. return m_pParser->ReadConfigurationData( m_sConfigFile ); } // -------------------------------------------------------------------------- // Function : ApplyConfiguration // // Description: // Will apply changes made to the configuration data. This is done by the // parser object which will write the changes to the medium. // // Arguments: (none) // // Return values: // true if changes have been saved, false otherwise. // // Exceptions: // See Parser::WriteConfigurationData(). // // -------------------------------------------------------------------------- bool Config::ApplyConfiguration( void ) { assert( m_pParser != NULL ); // Need to have a parser! // If access mode is READ only, we're not suposed to write any existing // configuration data. if( m_eAccessMode == AM_READ ) { throw GOGOC_UIS__CFG_CANNOTAPPLYWHENREAD; } // Apply the changes to disk. return m_pParser->WriteConfigurationData( m_sConfigFile ); } // -------------------------------------------------------------------------- // Function : CancelConfiguration // // Description: // Will cancel any changes made to the configuration data since the last // write operation(apply), if any. This is done by simply re-loading the // configuration from the parser object. // // Arguments: (none) // // Return values: // true if changes have been cancelled, false otherwise. // // Exceptions: // - When access mode is READ only. // See LoadConfiguration(). // // -------------------------------------------------------------------------- bool Config::CancelConfiguration( void ) { assert( m_pParser != NULL ); // Need to have a parser! // If access mode is READ only, we're not suposed to be cancelling changes. if( m_eAccessMode == AM_READ ) { throw GOGOC_UIS__CFG_CANNOTCANCELWHENREAD; } // Cancelling changes is the same as re-loading configuration data. return LoadConfiguration(); } // -------------------------------------------------------------------------- // Function : OverrideConfiguration // // Description: // Will override the current configuration data with the one from the // specified file. Then, the new configuration data will be written to the // current configuration file, thus completing the operation. // // Arguments: // aFileName: string [IN], The alternate configuration file to load, which // will override the current configuration. // // Return values: // true if the current configuration data has been overriden by the data // found in aFileName. // // Exceptions: // - When the specified file is the same as the configuration file. // - When access mode is READ only. // - See Parser::ReadConfigurationData() // - See Parser::WriteConfigurationData() // // -------------------------------------------------------------------------- bool Config::OverrideConfiguration( const string& aFileName ) { assert( m_pParser != NULL ); // Check if we're overriding with the same data from the same file. if( aFileName == m_sConfigFile ) { throw GOGOC_UIS__CFG_CANNOTOVERRIDESAMECONTENTS; } // If access mode is READ only, we're not suposed to be overriding // configuration data. if( m_eAccessMode == AM_READ ) { throw GOGOC_UIS__CFG_CANNOTOVERRIDEWHENREAD; } // Override the configuration data with the one from the specified file. // and apply the configuration to the config file. return m_pParser->ReadConfigurationData( aFileName ) && m_pParser->WriteConfigurationData( m_sConfigFile ); } } gogoc-1_2-RELEASE/gogoc-config/src/gogoc_c_wrapper.cc0100644000000000000000000004142711334102267021116 0ustar rootroot// ************************************************************************** // $Id: gogoc_c_wrapper.cc,v 1.2 2010/02/08 21:40:07 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Wraps the gogoCLIENT Configuration subsystem to offer C access. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #include "pal.h" #include #include #include #include using namespace gogocconfig; // This macro will try{} an operation and clear the value if an error occurs. #define TRY_OR_CLEAR(X) \ try { \ X; \ } catch(...) { \ sValue=""; \ } // The instance holder for the gogoCLIENT Configuration object. static GOGOCConfig* gpConfig = NULL; // -------------------------------------------------------------------------- // Function : initialize // // Description: // Will create a gogoCLIENT configuration object an load the configuration // data. // // Arguments: // szFileName: char* [IN], The name of the configuration file to load. // // Return values: // * 0 on successful initialization, // * -1 means configuration error; use get_config_errors, // * any other positive value means severe error; use get_ui_string for // more details. // // Exceptions: (none) // // -------------------------------------------------------------------------- extern "C" int initialize( const char* szFileName ) { int iRet = 0; // Check if already initialized. if( gpConfig != NULL ) return iRet; try { // Create new instance, initialize... gpConfig = new GOGOCConfig(); gpConfig->Initialize( szFileName, AM_RW ); // ...and load configuration data. iRet = gpConfig->Load() ? 0 : -1; } catch( error_t nErr ) { iRet = nErr; } return iRet; } // -------------------------------------------------------------------------- // Function : un_initialize // // Description: // Will clean-up the gogoCLIENT configuration object. // // Arguments: (none) // // Return values: (none) // // Exceptions: (none) // // -------------------------------------------------------------------------- extern "C" void un_initialize( void ) { if( gpConfig != NULL ) { // Delete instance. delete gpConfig; gpConfig = NULL; } } // -------------------------------------------------------------------------- // Function : save_config // // Description: // saves the configuration // // Arguments: // void // // Return values: // * 0 on successful save, // * -1 on error on save, // * any other positive value means severe error; use get_ui_string for // more details. // // Exceptions: (none) // // -------------------------------------------------------------------------- extern "C" int save_config( void ) { int iRet = 0; try { if( gpConfig != NULL) { // Saves the configuration iRet = gpConfig->Save() ? 0 : -1; } } catch (error_t nErr ) { iRet = nErr; } return iRet; } // -------------------------------------------------------------------------- // Function : get_config_errors // // Description: // Will retrieve the errors from the gogoCLIENT configuration data. // // Arguments: // errc: int* [OUT], Will contain the number of errors in the array. // errv: int*[] [OUT], Will contain the error strings. // // Return values: (none) // // Exceptions: (none) // // -------------------------------------------------------------------------- extern "C" void get_config_errors( int* errc, unsigned int* errv[] ) { assert( gpConfig != NULL ); assert( *errv == NULL ); const t_errorarray& vErr = gpConfig->GetValidationErrors(); int i; // Get the number of items in the vector *errc = (int)vErr.size(); if( *errc > 0 ) { *errv = (unsigned int*)malloc((*errc) * sizeof(unsigned int) ); // Copy the strings to the char* array for(i=0; i<*errc; i++) (*errv)[i] = vErr[i]; } } // -------------------------------------------------------------------------- /* *************************************************************************/ /* gogoCLIENT CONFIGURATION DATA WRAPPERS */ /* *************************************************************************/ // -------------------------------------------------------------------------- // -------------------------------------------------------------------------- extern "C" void get_user_id( char** szUserID ) { string sValue; assert( gpConfig != NULL ); assert( *szUserID == NULL ); TRY_OR_CLEAR( gpConfig->Get_UserID( sValue ) ); *szUserID = pal_strdup( sValue.c_str() ); } // -------------------------------------------------------------------------- extern "C" void set_user_id( char* szUserID ) { string sValue; assert( gpConfig != NULL ); assert( *szUserID == NULL ); sValue = szUserID; TRY_OR_CLEAR( gpConfig->Set_UserID( sValue ) ); } // -------------------------------------------------------------------------- extern "C" void get_passwd( char** szPasswd ) { string sValue; assert( gpConfig != NULL ); assert( *szPasswd == NULL ); TRY_OR_CLEAR( gpConfig->Get_Passwd( sValue ) ); *szPasswd = pal_strdup( sValue.c_str() ); } // -------------------------------------------------------------------------- extern "C" void set_passwd( char* szUserID ) { string sValue; assert( gpConfig != NULL ); assert( *szUserID == NULL ); sValue = szUserID; TRY_OR_CLEAR( gpConfig->Set_Passwd( sValue ) ); } // -------------------------------------------------------------------------- extern "C" void get_server( char** szServer ) { string sValue; assert( gpConfig != NULL ); assert( *szServer == NULL ); TRY_OR_CLEAR( gpConfig->Get_Server( sValue ) ); *szServer = pal_strdup( sValue.c_str() ); } // -------------------------------------------------------------------------- extern "C" void set_server( char* szUserID ) { string sValue; assert( gpConfig != NULL ); assert( *szUserID == NULL ); sValue = szUserID; TRY_OR_CLEAR( gpConfig->Set_Server( sValue ) ); } // -------------------------------------------------------------------------- extern "C" void get_host_type( char** szHostType ) { string sValue; assert( gpConfig != NULL ); assert( *szHostType == NULL ); TRY_OR_CLEAR( gpConfig->Get_HostType( sValue ) ); *szHostType = pal_strdup( sValue.c_str() ); } // -------------------------------------------------------------------------- extern "C" void get_prefixlen( int* piPrefixLen ) { string sValue; assert( gpConfig != NULL ); TRY_OR_CLEAR( gpConfig->Get_PrefixLen( sValue ) ); *piPrefixLen = (int)strtol(sValue.c_str(), (char**)NULL, 10); } // -------------------------------------------------------------------------- extern "C" void get_ifprefix( char** szIfPrefix ) { string sValue; assert( gpConfig != NULL ); assert( *szIfPrefix == NULL ); TRY_OR_CLEAR( gpConfig->Get_IfPrefix( sValue ) ); *szIfPrefix = pal_strdup( sValue.c_str() ); } // -------------------------------------------------------------------------- extern "C" void get_dns_server( char** szDnsServer ) { string sValue; assert( gpConfig != NULL ); assert( *szDnsServer == NULL ); TRY_OR_CLEAR( gpConfig->Get_DnsServer( sValue ) ); *szDnsServer = pal_strdup( sValue.c_str() ); } // -------------------------------------------------------------------------- extern "C" void get_gogoc_dir( char** szgogocDir ) { string sValue; assert( gpConfig != NULL ); assert( *szgogocDir == NULL ); TRY_OR_CLEAR( gpConfig->Get_gogocDir( sValue ) ); *szgogocDir = pal_strdup( sValue.c_str() ); } // -------------------------------------------------------------------------- extern "C" void get_auth_method( char** szAuthMethod ) { string sValue; assert( gpConfig != NULL ); assert( *szAuthMethod == NULL ); TRY_OR_CLEAR( gpConfig->Get_AuthMethod( sValue ) ); *szAuthMethod = pal_strdup( sValue.c_str() ); } // -------------------------------------------------------------------------- extern "C" void get_auto_retry_connect( tBoolean* pbAutoRetryConnect ) { string sValue; assert( gpConfig != NULL ); TRY_OR_CLEAR( gpConfig->Get_AutoRetryConnect( sValue ) ); *pbAutoRetryConnect = (tBoolean)(( pal_strcasecmp( sValue.c_str(), "yes" ) == 0 ) ? TRUE : FALSE); } // -------------------------------------------------------------------------- extern "C" void get_retry_delay( int* piRetryDelay ) { string sValue; assert( gpConfig != NULL ); TRY_OR_CLEAR( gpConfig->Get_RetryDelay( sValue ) ); *piRetryDelay = (int)strtol(sValue.c_str(), (char**)NULL, 10); } // -------------------------------------------------------------------------- extern "C" void get_retry_delay_max( int* piRetryDelayMax ) { string sValue; assert( gpConfig != NULL ); TRY_OR_CLEAR( gpConfig->Get_RetryDelayMax( sValue ) ); *piRetryDelayMax = (int)strtol(sValue.c_str(), (char**)NULL, 10); } // -------------------------------------------------------------------------- extern "C" void get_keepalive( tBoolean* pbKeepAlive ) { string sValue; assert( gpConfig != NULL ); TRY_OR_CLEAR( gpConfig->Get_KeepAlive( sValue ) ); *pbKeepAlive = (tBoolean)(( pal_strcasecmp( sValue.c_str(), "yes" ) == 0 ) ? TRUE : FALSE); } // -------------------------------------------------------------------------- extern "C" void get_keepalive_interval( int* piKaInterval ) { string sValue; assert( gpConfig != NULL ); TRY_OR_CLEAR( gpConfig->Get_KeepAliveInterval( sValue ) ); *piKaInterval = (int)strtol(sValue.c_str(), (char**)NULL, 10); } // -------------------------------------------------------------------------- extern "C" void get_tunnel_mode( char** szTunMode ) { string sValue; assert( gpConfig != NULL ); assert( *szTunMode == NULL ); TRY_OR_CLEAR( gpConfig->Get_TunnelMode( sValue ) ); *szTunMode = pal_strdup( sValue.c_str() ); } // -------------------------------------------------------------------------- extern "C" void get_if_tun_v6v4( char** szIf ) { string sValue; assert( gpConfig != NULL ); assert( *szIf == NULL ); TRY_OR_CLEAR( gpConfig->Get_IfTunV6V4( sValue ) ); *szIf = pal_strdup( sValue.c_str() ); } // -------------------------------------------------------------------------- extern "C" void get_if_tun_v6udpv4( char** szIf ) { string sValue; assert( gpConfig != NULL ); assert( *szIf == NULL ); TRY_OR_CLEAR( gpConfig->Get_IfTunV6UDPV4( sValue ) ); *szIf = pal_strdup( sValue.c_str() ); } // -------------------------------------------------------------------------- extern "C" void get_if_tun_v4v6( char** szIf ) { string sValue; assert( gpConfig != NULL ); assert( *szIf == NULL ); TRY_OR_CLEAR( gpConfig->Get_IfTunV4V6( sValue ) ); *szIf = pal_strdup( sValue.c_str() ); } // -------------------------------------------------------------------------- extern "C" void get_client_v4( char** szClientV4 ) { string sValue; assert( gpConfig != NULL ); assert( *szClientV4 == NULL ); TRY_OR_CLEAR( gpConfig->Get_ClientV4( sValue ) ); *szClientV4 = pal_strdup( sValue.c_str() ); } // -------------------------------------------------------------------------- extern "C" void get_dslite_server( char** szDSLite_Server ) { string sValue; assert( gpConfig != NULL ); assert( *szDSLite_Server == NULL ); TRY_OR_CLEAR( gpConfig->Get_DSLite_Server( sValue ) ); *szDSLite_Server = pal_strdup( sValue.c_str() ); } // -------------------------------------------------------------------------- extern "C" void get_dslite_client( char** szDSLite_Client ) { string sValue; assert( gpConfig != NULL ); assert( *szDSLite_Client == NULL ); TRY_OR_CLEAR( gpConfig->Get_DSLite_Client( sValue ) ); *szDSLite_Client = pal_strdup( sValue.c_str() ); } // -------------------------------------------------------------------------- extern "C" void get_client_v6( char** szClientV6 ) { string sValue; assert( gpConfig != NULL ); assert( *szClientV6 == NULL ); TRY_OR_CLEAR( gpConfig->Get_ClientV6( sValue ) ); *szClientV6 = pal_strdup( sValue.c_str() ); } // -------------------------------------------------------------------------- extern "C" void get_template( char** szTemplate ) { string sValue; assert( gpConfig != NULL ); assert( *szTemplate == NULL ); TRY_OR_CLEAR( gpConfig->Get_Template( sValue ) ); *szTemplate = pal_strdup( sValue.c_str() ); } // -------------------------------------------------------------------------- extern "C" void get_proxy_client( tBoolean* pbProxyClient ) { string sValue; assert( gpConfig != NULL ); TRY_OR_CLEAR( gpConfig->Get_ProxyClient( sValue ) ); *pbProxyClient = (tBoolean)(( pal_strcasecmp( sValue.c_str(), "yes" ) == 0 ) ? TRUE : FALSE); } // -------------------------------------------------------------------------- extern "C" void get_broker_list_file( char** szBrokerFile ) { string sValue; assert( gpConfig != NULL ); assert( *szBrokerFile == NULL ); TRY_OR_CLEAR( gpConfig->Get_BrokerLstFile( sValue ) ); *szBrokerFile = pal_strdup( sValue.c_str() ); } // -------------------------------------------------------------------------- extern "C" void get_last_server_file( char** szLastServFile ) { string sValue; assert( gpConfig != NULL ); assert( *szLastServFile == NULL ); TRY_OR_CLEAR( gpConfig->Get_LastServFile( sValue ) ); *szLastServFile = pal_strdup( sValue.c_str() ); } // -------------------------------------------------------------------------- extern "C" void get_always_use_last_server( tBoolean* pbUseLastServ ) { string sValue; assert( gpConfig != NULL ); TRY_OR_CLEAR( gpConfig->Get_AlwaysUseLastSrv( sValue ) ); *pbUseLastServ = (tBoolean)(( pal_strcasecmp( sValue.c_str(), "yes" ) == 0 ) ? TRUE : FALSE); } // -------------------------------------------------------------------------- extern "C" void get_log( const char* szLogDevice, short* psLevel ) { string sValue; assert( gpConfig != NULL ); TRY_OR_CLEAR( gpConfig->Get_Log( szLogDevice, sValue ) ); *psLevel = (short)strtol(sValue.c_str(), (char**)NULL, 10); } // -------------------------------------------------------------------------- extern "C" void get_log_filename( char** szLogFilename ) { string sValue; assert( gpConfig != NULL ); assert( *szLogFilename == NULL ); TRY_OR_CLEAR( gpConfig->Get_LogFileName( sValue ) ); *szLogFilename = pal_strdup( sValue.c_str() ); } // -------------------------------------------------------------------------- extern "C" void get_log_rotation( tBoolean* pbLogRotation ) { string sValue; assert( gpConfig != NULL ); TRY_OR_CLEAR( gpConfig->Get_LogRotation( sValue ) ); *pbLogRotation = (tBoolean)(( pal_strcasecmp( sValue.c_str(), "yes" ) == 0 ) ? TRUE : FALSE); } // -------------------------------------------------------------------------- extern "C" void get_log_rotation_sz( int* piLogRotSz ) { string sValue; assert( gpConfig != NULL ); TRY_OR_CLEAR( gpConfig->Get_LogRotationSz( sValue ) ); *piLogRotSz = (int)strtol(sValue.c_str(), (char**)NULL, 10); } // -------------------------------------------------------------------------- extern "C" void get_log_rotation_del( tBoolean* pbLogRotDel ) { string sValue; assert( gpConfig != NULL ); TRY_OR_CLEAR( gpConfig->Get_LogRotationDel( sValue ) ); *pbLogRotDel = ( pal_strcasecmp( sValue.c_str(), "yes" ) == 0 ) ? TRUE : FALSE; } // -------------------------------------------------------------------------- extern "C" void get_syslog_facility( char** szSyslog ) { string sValue; assert( gpConfig != NULL ); assert( *szSyslog == NULL ); TRY_OR_CLEAR( gpConfig->Get_SysLogFacility( sValue ) ); *szSyslog = pal_strdup( sValue.c_str() ); } // -------------------------------------------------------------------------- extern "C" void get_haccess_proxy_enabled( tBoolean* pbhaccessProxyEnabled ) { string sValue; assert( gpConfig != NULL ); TRY_OR_CLEAR( gpConfig->Get_haccessProxyEnabled( sValue ) ); *pbhaccessProxyEnabled = (tBoolean)(( pal_strcasecmp( sValue.c_str(), "yes" ) == 0 ) ? TRUE : FALSE); } // -------------------------------------------------------------------------- extern "C" void get_haccess_web_enabled( tBoolean* pbhaccessWebEnabled ) { string sValue; assert( gpConfig != NULL ); TRY_OR_CLEAR( gpConfig->Get_haccessWebEnabled( sValue ) ); *pbhaccessWebEnabled = (tBoolean)(( pal_strcasecmp( sValue.c_str(), "yes" ) == 0 ) ? TRUE : FALSE); } // -------------------------------------------------------------------------- extern "C" void get_haccess_document_root( char** pszhaccessDocRoot ) { string sValue; assert( gpConfig != NULL ); assert( *pszhaccessDocRoot == NULL ); TRY_OR_CLEAR( gpConfig->Get_haccessDocumentRoot( sValue ) ); *pszhaccessDocRoot = pal_strdup( sValue.c_str() ); } gogoc-1_2-RELEASE/gogoc-config/src/gogocconfig.cc0100644000000000000000000011410311334622373020237 0ustar rootroot// ************************************************************************** // $Id: gogocconfig.cc,v 1.3 2010/02/10 21:28:27 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Implementation of the GOGOCConfig class // // Description: // Implementation of the gogoCLIENT configuration data accessors. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #include #include #include #include #include #include // Configuration data variable NAMES #define CFG_STR_USERID "userid" #define CFG_STR_PASSWD "passwd" #define CFG_STR_SERVER "server" #define CFG_STR_DSLITE_SERVER "dslite_server" #define CFG_STR_DSLITE_CLIENT "dslite_client" #define CFG_STR_HOSTTYPE "host_type" #define CFG_STR_PREFIXLEN "prefixlen" #define CFG_STR_IFPREFIX "if_prefix" #define CFG_STR_DNSSERVER "dns_server" #define CFG_STR_GOGOCDIR "gogoc_dir" #define CFG_STR_AUTHMETHOD "auth_method" #define CFG_STR_AUTORETRYCONNECT "auto_retry_connect" #define CFG_STR_RETRYDELAY "retry_delay" #define CFG_STR_RETRYDELAYMAX "retry_delay_max" #define CFG_STR_KEEPALIVE "keepalive" #define CFG_STR_KEEPALIVEINTERVAL "keepalive_interval" #define CFG_STR_TUNNELMODE "tunnel_mode" #define CFG_STR_IFTUNV6V4 "if_tunnel_v6v4" #define CFG_STR_IFTUNV6UDPV4 "if_tunnel_v6udpv4" #define CFG_STR_IFTUNV4V6 "if_tunnel_v4v6" #define CFG_STR_CLIENTV4 "client_v4" #define CFG_STR_CLIENTV6 "client_v6" #define CFG_STR_TEMPLATE "template" #define CFG_STR_PROXYCLIENT "proxy_client" #define CFG_STR_BROKERLIST "broker_list" #define CFG_STR_LASTSERVER "last_server" #define CFG_STR_ALWAYSUSELASTSVR "always_use_same_server" #define CFG_STR_LOG "log" #define CFG_STR_LOGFILENAME "log_filename" #define CFG_STR_LOGROTATION "log_rotation" #define CFG_STR_LOGROTATIONSZ "log_rotation_size" #define CFG_STR_LOGROTATIONDEL "log_rotation_delete" #define CFG_STR_SYSLOGFACILITY "syslog_facility" #define CFG_STR_HACCESSPROXYENABLED "haccess_proxy_enabled" #define CFG_STR_HACCESSWEBENABLED "haccess_web_enabled" #define CFG_STR_HACCESSDOCUMENTROOT "haccess_document_root" // Configuration data DEFAULT VALUES // These values will be pushed to the configuration data if they were not // found in the configuration file. // IMPORTANT !! Make precautions when modifying these values, because they // won't be validated! #define CFG_DFLT_HOSTTYPE "host" #define CFG_DFLT_PREFIXLEN "64" #define CFG_DFLT_IFPREFIX "" #define CFG_DFLT_GOGOCDIR "" #define CFG_DFLT_AUTHMETHOD STR_ANY #define CFG_DFLT_AUTORETRYCONNECT STR_YES #define CFG_DFLT_RETRYDELAY "30" #define CFG_DFLT_RETRYDELAYMAX "300" #define CFG_DFLT_KEEPALIVE STR_YES #define CFG_DFLT_KEEPALIVEINTERVAL "30" #define CFG_DFLT_TUNNELMODE "v6anyv4" #define CFG_DFLT_CLIENTV4 "auto" #define CFG_DFLT_CLIENTV6 "auto" #define CFG_DFLT_PROXYCLIENT STR_NO #define CFG_DFLT_BROKERLIST "tsp-broker-list.txt" #define CFG_DFLT_LASTSERVER "tsp-last-server.txt" #define CFG_DFLT_ALWAYSUSELASTSVR STR_NO #define CFG_DFLT_LOGFILENAME "gogoc.log" #define CFG_DFLT_LOGROTATION STR_YES #define CFG_DFLT_LOGROTATIONSZ "32" #define CFG_DFLT_LOGROTATIONDEL STR_NO #define CFG_DFLT_SYSLOGFACILITY "USER" #define CFG_DFLT_HACCESSPROXYENABLED STR_NO // HACCESS defaults #define CFG_DFLT_HACCESSWEBENABLED STR_NO #define CFG_DFLT_HACCESSDOCUMENTROOT "" #define CFG_DFLT_DSLITE_CLIENT "192.0.0.2" #define CFG_DFLT_DSLITE_SERVER "192.0.0.1" #ifdef WIN32 #define CFG_DFLT_LOGLEVEL_STDERR "0" #define CFG_DFLT_LOGLEVEL_SYSLOG "0" #define CFG_DFLT_LOGLEVEL_CONSOLE "0" #define CFG_DFLT_LOGLEVEL_FILE "1" #else #define CFG_DFLT_LOGLEVEL_STDERR "1" #define CFG_DFLT_LOGLEVEL_SYSLOG "0" #define CFG_DFLT_LOGLEVEL_CONSOLE "0" #define CFG_DFLT_LOGLEVEL_FILE "0" #endif #define CFG_DFLT_LOGLEVEL "1" // When unknown device. // -------------------------------------------------------------------------- // Macro definitions // -------------------------------------------------------------------------- // For configuration data accessors (GET) #define ASSERT_VALID_CONFIG \ assert( m_pConfig != NULL ); \ if( !m_bValid ) \ throw GOGOC_UIS__G6C_INVALIDCONF // For configuration data accessors (SET) #define VERIFY_AND_SET(X,Y) \ if( Validate_##X( s##X ) ) \ m_pConfig->SetVariableValue( Y, s##X ); \ else \ throw GetLastError() // For configuration data validation. #define VALIDATE_LOGERRMSG( X, Y ) \ m_pConfig->GetVariableValue( Y, sValue ); \ if( !Validate_##X( sValue ) ) \ { \ m_lsValidationErrors.push_back( GetLastError() ); \ m_bValid = false; \ } // -------------------------------------------------------------------------- // Function : GetDfltLogLevelForDevice // // Description: // Will return the default log level for the specified log device. // // Arguments: // sLogDevice: string [IN], The log device. // // Return values: // A string representing the default log level for the device. // // Exceptions: (none) // // -------------------------------------------------------------------------- string GetDfltLogLevelForDevice( const string& sLogDevice ) { if( sLogDevice == STR_LOGDEV_CONSOLE ) return CFG_DFLT_LOGLEVEL_CONSOLE; if( sLogDevice == STR_LOGDEV_STDERR ) return CFG_DFLT_LOGLEVEL_STDERR; if( sLogDevice == STR_LOGDEV_FILE ) return CFG_DFLT_LOGLEVEL_FILE; if( sLogDevice == STR_LOGDEV_SYSLOG ) return CFG_DFLT_LOGLEVEL_SYSLOG; // Should assert(false) - here - return CFG_DFLT_LOGLEVEL; } // -------------------------------------------------------------------------- // Replaces the occurence of a string with another. // -------------------------------------------------------------------------- void replace( string& str, const char* s, const char* r ) { assert( strlen(s) == strlen(r) ); string::size_type pos; while( (pos = str.find_first_of(s)) != string::npos ) str.replace( pos, strlen(r), r ); } namespace gogocconfig { // -------------------------------------------------------------------------- // Function : GOGOCConfig constructor // // Description: // Will initialize a new GOGOCConfig object. // // Arguments: (none) // // Return values: (N/A) // // Exceptions: (none) // // -------------------------------------------------------------------------- GOGOCConfig::GOGOCConfig( void ) : m_pConfig(NULL), m_sDfltCfgFile(""), m_bValid(false) { m_lsValidationErrors.clear(); } // -------------------------------------------------------------------------- // Function : GOGOCConfig destructor // // Description: // Will destroy GOGOCConfig object. // // Arguments: (N/A) // // Return values: (N/A) // // Exceptions: (none) // // -------------------------------------------------------------------------- GOGOCConfig::~GOGOCConfig( void ) { // Delete the configuration object, if it was constructed. if( m_pConfig != NULL ) delete m_pConfig; m_pConfig = NULL; } // -------------------------------------------------------------------------- // Function : Initialize // // Description: // Will initialize the configuration object. // // Arguments: // aConfigFile: string [IN], The gogoCLIENT configuration file name. // aEAccessMode: enum [IN], The desired access mode (READ, CREATE, RW) // aDfltCfgFile: string [IN], A configuration file containing defaults. // // Return values: (none) // // Exceptions: (none) // // -------------------------------------------------------------------------- void GOGOCConfig::Initialize( const string& aConfigFile, const t_accessMode aEAccessMode, const string& aDfltCfgFile ) { // Keep the default configuration file, for later use. m_sDfltCfgFile = aDfltCfgFile; // Instantiate the name value configuration parser. m_pConfig = new NameValueConfig( aConfigFile, aEAccessMode ); } // -------------------------------------------------------------------------- // Function : Load // // Description: // Will load the configuration data. // // Arguments: (none) // // Return values: // true if configuration data was successfully loaded from the file, and // the contents are valid. // // Exceptions: // - See Config::LoadConfiguration() // // -------------------------------------------------------------------------- bool GOGOCConfig::Load( void ) { assert( m_pConfig != NULL ); return m_pConfig->LoadConfiguration() && ValidateConfigData(); } // -------------------------------------------------------------------------- // Function : Save // // Description: // Will save the configuration data. // // Arguments: (none) // // Return values: // true if configuration data has been saved to the file. // // Exceptions: // - See Config::ApplyConfiguration() // // -------------------------------------------------------------------------- bool GOGOCConfig::Save( void ) { assert( m_pConfig != NULL ); bool bRetCode = ValidateConfigData() && m_pConfig->ApplyConfiguration(); m_bValid = true; return bRetCode; } // -------------------------------------------------------------------------- // Function : CancelChanges // // Description: // Will cancel the changes made to the configuration data. // // Arguments: (none) // // Return values: // true if changes made to the configuration data were successfully // cancelled, false otherwise. // // Exceptions: // - See Config::CancelConfiguration() // // -------------------------------------------------------------------------- bool GOGOCConfig::CancelChanges( void ) { assert( m_pConfig != NULL ); return m_pConfig->CancelConfiguration(); } // -------------------------------------------------------------------------- // Function : LoadDefaults // // Description: // Will replace the current configuration data with defaults. This default // configuration data is found in a file. The contents of the original // configuration is lost and overwritten. // // Arguments: (none) // // Return values: // true if configuration was overriden with the data from the default file. // // Exceptions: // - If no default configuration file was provided on initialization. // - See Config::OverrideConfiguration() // // -------------------------------------------------------------------------- bool GOGOCConfig::LoadDefaults( void ) { assert( m_pConfig != NULL ); if( m_sDfltCfgFile.size() == 0 ) { throw GOGOC_UIS__G6C_FAILLOADDFLTCONF; } return m_pConfig->OverrideConfiguration( m_sDfltCfgFile ) && ValidateConfigData(); } // -------------------------------------------------------------------------- // Function : ValidateConfigData [PRIVATE] // // Description: // Will run all the validation routines on the configuration data, to // ensure validity. If some data is invalid, the error message is appended // to the class variable `m_lsValidationErrors'. // // Arguments: (none) // // Return values: // true if validation was completely successful, false otherwise. // // Exceptions: (none) // // -------------------------------------------------------------------------- bool GOGOCConfig::ValidateConfigData( void ) { string sValue; // Initialization assert( m_pConfig != NULL ); m_bValid = true; m_lsValidationErrors.clear(); // ------------------------------------------ // Individual configuration data validation. // ------------------------------------------ VALIDATE_LOGERRMSG( UserID, CFG_STR_USERID ); VALIDATE_LOGERRMSG( Passwd, CFG_STR_PASSWD ); VALIDATE_LOGERRMSG( Server, CFG_STR_SERVER ); VALIDATE_LOGERRMSG( DSLite, CFG_STR_DSLITE_SERVER ); VALIDATE_LOGERRMSG( DSLite, CFG_STR_DSLITE_CLIENT ); VALIDATE_LOGERRMSG( HostType, CFG_STR_HOSTTYPE ); VALIDATE_LOGERRMSG( PrefixLen, CFG_STR_PREFIXLEN ); VALIDATE_LOGERRMSG( IfPrefix, CFG_STR_IFPREFIX ); VALIDATE_LOGERRMSG( DnsServer, CFG_STR_DNSSERVER ); VALIDATE_LOGERRMSG( gogocDir, CFG_STR_GOGOCDIR ); VALIDATE_LOGERRMSG( AuthMethod, CFG_STR_AUTHMETHOD ); VALIDATE_LOGERRMSG( RetryDelay, CFG_STR_RETRYDELAY ); VALIDATE_LOGERRMSG( RetryDelayMax, CFG_STR_RETRYDELAYMAX ); VALIDATE_LOGERRMSG( KeepAlive, CFG_STR_KEEPALIVE ); VALIDATE_LOGERRMSG( KeepAliveInterval, CFG_STR_KEEPALIVEINTERVAL ); VALIDATE_LOGERRMSG( TunnelMode, CFG_STR_TUNNELMODE ); VALIDATE_LOGERRMSG( IfTunV6V4, CFG_STR_IFTUNV6V4 ); VALIDATE_LOGERRMSG( IfTunV6UDPV4, CFG_STR_IFTUNV6UDPV4 ); VALIDATE_LOGERRMSG( IfTunV4V6, CFG_STR_IFTUNV4V6 ); VALIDATE_LOGERRMSG( ClientV4, CFG_STR_CLIENTV4 ); VALIDATE_LOGERRMSG( ClientV6, CFG_STR_CLIENTV6 ); VALIDATE_LOGERRMSG( Template, CFG_STR_TEMPLATE ); VALIDATE_LOGERRMSG( ProxyClient, CFG_STR_PROXYCLIENT ); VALIDATE_LOGERRMSG( BrokerLstFile, CFG_STR_BROKERLIST ); VALIDATE_LOGERRMSG( LastServFile, CFG_STR_LASTSERVER ); VALIDATE_LOGERRMSG( AlwaysUseLastSrv, CFG_STR_ALWAYSUSELASTSVR ); VALIDATE_LOGERRMSG( LogLevel, (string)"log_" + STR_LOGDEV_CONSOLE ); VALIDATE_LOGERRMSG( LogLevel, (string)"log_" + STR_LOGDEV_STDERR ); VALIDATE_LOGERRMSG( LogLevel, (string)"log_" + STR_LOGDEV_SYSLOG ); VALIDATE_LOGERRMSG( LogLevel, (string)"log_" + STR_LOGDEV_FILE ); VALIDATE_LOGERRMSG( LogFileName, CFG_STR_LOGFILENAME ); VALIDATE_LOGERRMSG( LogRotation, CFG_STR_LOGROTATION ); VALIDATE_LOGERRMSG( LogRotationSz, CFG_STR_LOGROTATIONSZ ); VALIDATE_LOGERRMSG( LogRotationDel, CFG_STR_LOGROTATIONDEL ); VALIDATE_LOGERRMSG( SysLogFacility, CFG_STR_SYSLOGFACILITY ); VALIDATE_LOGERRMSG( haccessProxyEnabled, CFG_STR_HACCESSPROXYENABLED ); VALIDATE_LOGERRMSG( haccessWebEnabled, CFG_STR_HACCESSWEBENABLED ); VALIDATE_LOGERRMSG( haccessDocumentRoot, CFG_STR_HACCESSDOCUMENTROOT ); // Do not go on if configuration data is invalid. if( !m_bValid ) return m_bValid; // ------------------------------------------------------------------------ // -- Value-dependant cross validation. -- // ------------------------------------------------------------------------ // NOTE: These GETs need to be put in try...catch blocks because they may // raise an 'Invalid configuration' exception. // ------------------------------------------------------------------------ string sValue2; // ------------------------------------------------------ // 1. If authentication mode is NOT anonymous, password // must be supplied. try { Get_AuthMethod( sValue ); Get_Passwd( sValue2 ); if( (sValue != STR_ANONYMOUS) && sValue2.empty() ) { m_lsValidationErrors.push_back( GOGOC_UIS__G6C_SUPPLYPASSWDWHENNOTANON ); m_bValid = false; } } catch(...) { // Catched an invalid configuration exception. m_bValid = false; return m_bValid; } // --------------------------------------------------------------- // 2. If proxy_client is true, tunnel mode must NOT be using UDP. try { Get_ProxyClient( sValue ); Get_TunnelMode( sValue2 ); if( sValue == STR_YES && sValue2 == STR_V6UDPV4 ) { m_lsValidationErrors.push_back( GOGOC_UIS__G6C_PROXYCINVALIDMODE ); m_bValid = false; } } catch(...) { // Catched an invalid configuration exception. m_bValid = false; return m_bValid; } // ----------------------------------------------------------- // 3. If proxy_client is true, keepalives must be turned off. try { Get_ProxyClient( sValue ); Get_KeepAlive( sValue2 ); if( sValue == STR_YES && sValue2 == STR_YES ) { m_lsValidationErrors.push_back( GOGOC_UIS__G6C_PROXYANDKEEPALIVE ); m_bValid = false; } } catch(...) { // Catched an invalid configuration exception. m_bValid = false; return m_bValid; } // --------------------------------------------------------- // 3. If keep-alive is enabled, the interval must not be 0. try { Get_KeepAlive( sValue ); Get_KeepAliveInterval( sValue2 ); if( sValue == STR_YES && strtol(sValue2.c_str(), (char**)NULL, 10) == 0 ) { m_lsValidationErrors.push_back( GOGOC_UIS__G6C_KAINTERVALINVALID ); m_bValid = false; } } catch(...) { // Catched an invalid configuration exception. m_bValid = false; return m_bValid; } // ------------------------------------------------------------------------ // 4. Verify that tunnel interface is provided, depending on tunnel mode. try { // Tunnel mode requested. Get_TunnelMode( sValue ); if( sValue == STR_V6ANYV4 ) { string sValue3; // Must specify the V6V4 and V4UDPV6 interface Get_IfTunV6V4( sValue2 ); Get_IfTunV6UDPV4( sValue3 ); if( sValue2.empty() || sValue3.empty() ) { m_lsValidationErrors.push_back( GOGOC_UIS__G6C_IFTUNV6V4ANDV6UDPV4REQUIRED ); m_bValid = false; } } else if( sValue == STR_V6V4 ) { // Must specify the V6V4 interface Get_IfTunV6V4( sValue2 ); if( sValue2.empty() ) { m_lsValidationErrors.push_back( GOGOC_UIS__G6C_IFTUNV6V4REQUIRED ); m_bValid = false; } } else if( sValue == STR_V6UDPV4 ) { // Must specify the V6UDPV4 interface Get_IfTunV6UDPV4( sValue2 ); if( sValue2.empty() ) { m_lsValidationErrors.push_back( GOGOC_UIS__G6C_IFTUNV6UDPV4REQUIRED ); m_bValid = false; } } else if( sValue == STR_V4V6 ) { // Must specify the V4V6 interface Get_IfTunV4V6( sValue2 ); if( sValue2.empty() ) { m_lsValidationErrors.push_back( GOGOC_UIS__G6C_IFTUNV4V6REQUIRED ); m_bValid = false; } } else assert( false ); // Should never reach here. } catch(...) { // Catched an invalid configuration exception. m_bValid = false; return m_bValid; } // ------------------------------------------------------------- // 5. If host_type is 'router', the if_prefix must be supplied. try { Get_HostType( sValue ); Get_IfPrefix( sValue2 ); if( sValue == STR_HOSTTYPE_ROUTER && sValue2.empty() ) { m_lsValidationErrors.push_back( GOGOC_UIS__G6V_IFPREFIXMUSTBESPEC ); m_bValid = false; } } catch(...) { // Catched an invalid configuration exception. m_bValid = false; return m_bValid; } // ------------------------------------------------------------- // 6. Check that retry_delay <= retry_delay_max. try { long v1, v2; Get_RetryDelay( sValue ); Get_RetryDelayMax( sValue2 ); v1 = atol( sValue.c_str() ); v2 = atol( sValue2.c_str() ); if( v1 > v2 ) { m_lsValidationErrors.push_back( GOGOC_UIS__G6V_RETRYDELAYGREATERRETRYDELAYMAX ); m_bValid = false; } } catch(...) { // Catched an invalid configuration exception. m_bValid = false; return m_bValid; } #ifdef HACCESS // -------------------------------------------------------------- // 7. If HACCESS Web is enabled, the document root cannot be empty. try { Get_haccessWebEnabled( sValue ); Get_haccessDocumentRoot( sValue2 ); if( sValue == STR_YES && sValue2.empty() ) { m_lsValidationErrors.push_back( GOGOC_UIS__G6V_HACCESSDOCROOTNOTSPEC ); m_bValid = false; } } catch(...) { // Catched an invalid configuration exception. m_bValid = false; return m_bValid; } // -------------------------------------------------------------- // 8. If HACCESS is built, the tunnel mode cannot be V4V6. try { Get_TunnelMode( sValue2 ); if( (sValue == STR_YES || sValue2 == STR_YES) && sValue2 == STR_V4V6 ) { m_lsValidationErrors.push_back( GOGOC_UIS__G6V_HACCESSINCOMPV4V6 ); m_bValid = false; } } catch(...) { // Catched an invalid configuration exception. m_bValid = false; return m_bValid; } #endif return m_bValid; } // -------------------------------------------------------------------------- /* *************************************************************************/ /* gogoCLIENT CONFIGURATION DATA ACCESSORS */ /* *************************************************************************/ // -------------------------------------------------------------------------- void GOGOCConfig::Get_UserID( string& sUserID ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_USERID, sUserID ); } void GOGOCConfig::Set_UserID( const string& sUserID ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( UserID, CFG_STR_USERID ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_Passwd( string& sPasswd ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_PASSWD, sPasswd ); } void GOGOCConfig::Set_Passwd( const string& sPasswd ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( Passwd, CFG_STR_PASSWD ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_Server( string& sServer ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_SERVER, sServer ); } void GOGOCConfig::Set_Server( const string& sServer ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( Server, CFG_STR_SERVER ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_HostType( string& sHostType ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_HOSTTYPE, sHostType ); // Push default value, if not present. if( sHostType.size() == 0 ) sHostType = CFG_DFLT_HOSTTYPE; } void GOGOCConfig::Set_HostType( const string& sHostType ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( HostType, CFG_STR_HOSTTYPE ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_PrefixLen( string& sPrefixLen ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_PREFIXLEN, sPrefixLen ); // Push default value, if not present. if( sPrefixLen.size() == 0 ) sPrefixLen = CFG_DFLT_PREFIXLEN; } void GOGOCConfig::Set_PrefixLen( const string& sPrefixLen ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( PrefixLen, CFG_STR_PREFIXLEN ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_IfPrefix( string& sIfPrefix ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_IFPREFIX, sIfPrefix ); // Push default value, if not present. if( sIfPrefix.size() == 0 ) sIfPrefix = CFG_DFLT_IFPREFIX; } void GOGOCConfig::Set_IfPrefix( const string& sIfPrefix ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( IfPrefix, CFG_STR_IFPREFIX ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_DnsServer( string& sDnsServer ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_DNSSERVER, sDnsServer ); } void GOGOCConfig::Set_DnsServer( const string& sDnsServer ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( DnsServer, CFG_STR_DNSSERVER ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_gogocDir( string& sgogocDir ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_GOGOCDIR, sgogocDir ); // Push default value, if not present. if( sgogocDir.size() == 0 ) sgogocDir = CFG_DFLT_GOGOCDIR; } void GOGOCConfig::Set_gogocDir( const string& sgogocDir ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( gogocDir, CFG_STR_GOGOCDIR ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_AuthMethod( string& sAuthMethod ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_AUTHMETHOD, sAuthMethod ); // Push default value, if not present. if( sAuthMethod.size() == 0 ) sAuthMethod = CFG_DFLT_AUTHMETHOD; } void GOGOCConfig::Set_AuthMethod( const string& sAuthMethod ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( AuthMethod, CFG_STR_AUTHMETHOD ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_AutoRetryConnect( string& sAutoRetryConnect ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_AUTORETRYCONNECT, sAutoRetryConnect ); // Push default value, if not present. if( sAutoRetryConnect.size() == 0 ) sAutoRetryConnect = CFG_DFLT_AUTORETRYCONNECT; } void GOGOCConfig::Set_AutoRetryConnect( const string& sAutoRetryConnect ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( AutoRetryConnect, CFG_STR_AUTORETRYCONNECT ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_RetryDelay( string& sRetryDelay ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_RETRYDELAY, sRetryDelay ); // Push default value, if not present. if( sRetryDelay.size() == 0 ) sRetryDelay = CFG_DFLT_RETRYDELAY; } void GOGOCConfig::Set_RetryDelay( const string& sRetryDelay ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( RetryDelay, CFG_STR_RETRYDELAY ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_RetryDelayMax( string& sRetryDelayMax ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_RETRYDELAYMAX, sRetryDelayMax ); // Push default value, if not present. if( sRetryDelayMax.size() == 0 ) sRetryDelayMax = CFG_DFLT_RETRYDELAYMAX; } void GOGOCConfig::Set_RetryDelayMax( const string& sRetryDelayMax ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( RetryDelayMax, CFG_STR_RETRYDELAYMAX ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_KeepAlive( string& sKeepAlive ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_KEEPALIVE, sKeepAlive ); // Push default value, if not present. if( sKeepAlive.size() == 0 ) sKeepAlive = CFG_DFLT_KEEPALIVE; } void GOGOCConfig::Set_KeepAlive( const string& sKeepAlive ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( KeepAlive, CFG_STR_KEEPALIVE ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_KeepAliveInterval( string& sKeepAliveInterval ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_KEEPALIVEINTERVAL, sKeepAliveInterval ); // Push default value, if not present. if( sKeepAliveInterval.size() == 0 ) sKeepAliveInterval = CFG_DFLT_KEEPALIVEINTERVAL; } void GOGOCConfig::Set_KeepAliveInterval( const string& sKeepAliveInterval ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( KeepAliveInterval, CFG_STR_KEEPALIVEINTERVAL ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_TunnelMode( string& sTunnelMode ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_TUNNELMODE, sTunnelMode ); // Push default value, if not present. if( sTunnelMode.size() == 0 ) sTunnelMode = CFG_DFLT_TUNNELMODE; } void GOGOCConfig::Set_TunnelMode( const string& sTunnelMode ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( TunnelMode, CFG_STR_TUNNELMODE ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_IfTunV6V4( string& sIfTunV6V4 ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_IFTUNV6V4, sIfTunV6V4 ); } void GOGOCConfig::Set_IfTunV6V4( const string& sIfTunV6V4 ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( IfTunV6V4, CFG_STR_IFTUNV6V4 ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_IfTunV6UDPV4( string& sIfTunV6UDPV4 ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_IFTUNV6UDPV4, sIfTunV6UDPV4 ); } void GOGOCConfig::Set_IfTunV6UDPV4( const string& sIfTunV6UDPV4 ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( IfTunV6UDPV4, CFG_STR_IFTUNV6UDPV4 ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_IfTunV4V6( string& sIfTunV4V6 ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_IFTUNV4V6, sIfTunV4V6 ); } void GOGOCConfig::Set_IfTunV4V6( const string& sIfTunV4V6 ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( IfTunV4V6, CFG_STR_IFTUNV4V6 ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_DSLite_Server( string& sDSLite ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_DSLITE_SERVER, sDSLite ); // Push default value, if not present. if( sDSLite.size() == 0 ) sDSLite = CFG_DFLT_DSLITE_SERVER; } void GOGOCConfig::Set_DSLite_Server( const string& sDSLite ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( DSLite, CFG_STR_DSLITE_SERVER ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_DSLite_Client( string& sDSLite ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_DSLITE_CLIENT, sDSLite ); // Push default value, if not present. if( sDSLite.size() == 0 ) sDSLite = CFG_DFLT_DSLITE_CLIENT; } void GOGOCConfig::Set_DSLite_Client( const string& sDSLite ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( DSLite, CFG_STR_DSLITE_CLIENT ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_ClientV4( string& sClientV4 ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_CLIENTV4, sClientV4 ); // Push default value, if not present. if( sClientV4.size() == 0 ) sClientV4 = CFG_DFLT_CLIENTV4; } void GOGOCConfig::Set_ClientV4( const string& sClientV4 ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( ClientV4, CFG_STR_CLIENTV4 ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_ClientV6( string& sClientV6 ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_CLIENTV6, sClientV6 ); // Push default value, if not present. if( sClientV6.size() == 0 ) sClientV6 = CFG_DFLT_CLIENTV6; } void GOGOCConfig::Set_ClientV6( const string& sClientV6 ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( ClientV6, CFG_STR_CLIENTV6 ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_Template( string& sTemplate ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_TEMPLATE, sTemplate ); } void GOGOCConfig::Set_Template( const string& sTemplate ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( Template, CFG_STR_TEMPLATE ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_ProxyClient( string& sProxyClient ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_PROXYCLIENT, sProxyClient ); // Push default value, if not present. if( sProxyClient.size() == 0 ) sProxyClient = CFG_DFLT_PROXYCLIENT; } void GOGOCConfig::Set_ProxyClient( const string& sProxyClient ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( ProxyClient, CFG_STR_PROXYCLIENT ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_BrokerLstFile( string& sBrokerLstFile ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_BROKERLIST, sBrokerLstFile ); // Push default value, if not present. if( sBrokerLstFile.size() == 0 ) sBrokerLstFile = CFG_DFLT_BROKERLIST; } void GOGOCConfig::Set_BrokerLstFile( const string& sBrokerLstFile ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( BrokerLstFile, CFG_STR_BROKERLIST ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_LastServFile( string& sLastServFile ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_LASTSERVER, sLastServFile ); // Push default value, if not present. if( sLastServFile.size() == 0 ) sLastServFile = CFG_DFLT_LASTSERVER; } void GOGOCConfig::Set_LastServFile( const string& sLastServFile ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( LastServFile, CFG_STR_LASTSERVER ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_AlwaysUseLastSrv( string& sAlwaysUseLastSrv ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_ALWAYSUSELASTSVR, sAlwaysUseLastSrv ); // Push default value, if not present. if( sAlwaysUseLastSrv.size() == 0 ) sAlwaysUseLastSrv = CFG_DFLT_ALWAYSUSELASTSVR; } void GOGOCConfig::Set_AlwaysUseLastSrv( const string& sAlwaysUseLastSrv ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( AlwaysUseLastSrv, CFG_STR_ALWAYSUSELASTSVR ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_Log( const string& sLogDevice, string& sLogLevel ) const { string sLogRequest; ASSERT_VALID_CONFIG; if( !Validate_LogDevice( sLogDevice ) ) { throw GetLastError(); } sLogRequest = "log_" + sLogDevice; m_pConfig->GetVariableValue( sLogRequest, sLogLevel ); // Push default value, if not present. if( sLogLevel.size() == 0 ) { // Retrieve the default log value for the specified device. sLogLevel = GetDfltLogLevelForDevice( sLogDevice ); } } void GOGOCConfig::Set_Log( const string& sLogDevice, const string& sLogLevel ) { string sLogRequest; ASSERT_VALID_CONFIG; // Check if specified device is within domain values. if( !Validate_LogDevice( sLogDevice ) ) { throw GetLastError(); } // Check if log level is within domain values. if( !Validate_LogLevel( sLogLevel ) ) { throw GetLastError(); } // Set the log level for the device. sLogRequest = "log_" + sLogDevice; m_pConfig->SetVariableValue( sLogRequest, sLogLevel ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_LogFileName( string& sLogFileName ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_LOGFILENAME, sLogFileName ); // Push default value, if not present. if( sLogFileName.size() == 0 ) sLogFileName = CFG_DFLT_LOGFILENAME; } void GOGOCConfig::Set_LogFileName( const string& sLogFileName ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( LogFileName, CFG_STR_LOGFILENAME ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_LogRotation( string& sLogRotation ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_LOGROTATION, sLogRotation ); // Push default value, if not present. if( sLogRotation.size() == 0 ) sLogRotation = CFG_DFLT_LOGROTATION; } void GOGOCConfig::Set_LogRotation( const string& sLogRotation ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( LogRotation, CFG_STR_LOGROTATION ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_LogRotationSz( string& sLogRotationSz ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_LOGROTATIONSZ, sLogRotationSz ); // Push default value, if not present. if( sLogRotationSz.size() == 0 ) sLogRotationSz = CFG_DFLT_LOGROTATIONSZ; } void GOGOCConfig::Set_LogRotationSz( const string& sLogRotationSz ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( LogRotationSz, CFG_STR_LOGROTATIONSZ ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_LogRotationDel( string& sLogRotationDel ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_LOGROTATIONDEL, sLogRotationDel ); // Push default value, if not present. if( sLogRotationDel.size() == 0 ) sLogRotationDel = CFG_DFLT_LOGROTATIONDEL; } void GOGOCConfig::Set_LogRotationDel( const string& sLogRotationDel ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( LogRotationDel, CFG_STR_LOGROTATIONDEL ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_SysLogFacility( string& sSysLogFacility ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_SYSLOGFACILITY, sSysLogFacility ); // Push default value, if not present. if( sSysLogFacility.size() == 0 ) sSysLogFacility = CFG_DFLT_SYSLOGFACILITY; } void GOGOCConfig::Set_SysLogFacility( const string& sSysLogFacility ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( SysLogFacility, CFG_STR_SYSLOGFACILITY ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_haccessProxyEnabled( string& shaccessProxyEnabled ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_HACCESSPROXYENABLED, shaccessProxyEnabled ); // Push default value, if not present. if( shaccessProxyEnabled.size() == 0 ) shaccessProxyEnabled = CFG_DFLT_HACCESSPROXYENABLED; } void GOGOCConfig::Set_haccessProxyEnabled( const string& shaccessProxyEnabled ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( haccessProxyEnabled, CFG_STR_HACCESSPROXYENABLED ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_haccessWebEnabled( string& shaccessWebEnabled ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_HACCESSWEBENABLED, shaccessWebEnabled ); // Push default value, if not present. if( shaccessWebEnabled.size() == 0 ) shaccessWebEnabled = CFG_DFLT_HACCESSWEBENABLED; } void GOGOCConfig::Set_haccessWebEnabled( const string& shaccessWebEnabled ) { ASSERT_VALID_CONFIG; VERIFY_AND_SET( haccessWebEnabled, CFG_STR_HACCESSWEBENABLED ); } // -------------------------------------------------------------------------- void GOGOCConfig::Get_haccessDocumentRoot( string& shaccessDocumentRoot ) const { ASSERT_VALID_CONFIG; m_pConfig->GetVariableValue( CFG_STR_HACCESSDOCUMENTROOT, shaccessDocumentRoot ); // Push default value, if not present. if( shaccessDocumentRoot.size() == 0 ) shaccessDocumentRoot = CFG_DFLT_HACCESSDOCUMENTROOT; replace( shaccessDocumentRoot, "\\", "/" ); } void GOGOCConfig::Set_haccessDocumentRoot( const string& shaccessDocumentRoot ) { ASSERT_VALID_CONFIG; if( Validate_haccessDocumentRoot( shaccessDocumentRoot ) ) { string formatted = shaccessDocumentRoot; replace( formatted, "\\", "/" ); m_pConfig->SetVariableValue( CFG_STR_HACCESSDOCUMENTROOT, formatted ); } else throw GetLastError(); } } // Namespace gogoc-1_2-RELEASE/gogoc-config/src/gogocuistrings.c0100644000000000000000000002401111344751241020652 0ustar rootroot/* *********************************************************************** */ /* $Id: gogocuistrings.c,v 1.2 2010/03/07 16:21:53 carl Exp $ */ /* */ /* Copyright (c) 2007 gogo6 Inc. All rights reserved. */ /* */ /* For license information refer to CLIENT-LICENSE.TXT */ /* */ /* Description: */ /* Offers default UI string for errors and other. */ /* */ /* You may translate the strings herein as you wish. */ /* */ /* Author: Charles Nepveu */ /* */ /* Creation Date: November 2006 */ /* _______________________________________________________________________ */ /* *********************************************************************** */ #include /* Struct containing string IDs with the related string. */ typedef struct { error_t _id; const char* _str; } tgogocUIStrings; static const tgogocUIStrings gogocUIStrings[] = { /* And to start with... The NameValueParser strings */ { GOGOC_UIS__GROUP_NAMEVALUEPARSER, // title "Name=Value Parser Error" }, { GOGOC_UIS__NMP_OPENFAIL, "Failed to open specified file." }, { GOGOC_UIS__NMP_BADCONFIGFILE, "Bad configuration file." }, { GOGOC_UIS__NMP_OPENFAILWRITE, "Failed to open file to write configuration data." }, /* Next... Config strings */ { GOGOC_UIS__GROUP_GENERICCONFIG, // title "Generic Configuration Error" }, { GOGOC_UIS__CFG_CANNOTLOADWHENCREATE, "Cannot load configuration when access mode is CREATE." }, { GOGOC_UIS__CFG_CANNOTAPPLYWHENREAD, "Cannot apply configuration data when access mode is READ." }, { GOGOC_UIS__CFG_CANNOTCANCELWHENREAD, "Cannot cancel configuration changes when access mode is READ."}, { GOGOC_UIS__CFG_CANNOTOVERRIDESAMECONTENTS, "Cannot override configuration data with same contents." }, { GOGOC_UIS__CFG_CANNOTOVERRIDEWHENREAD, "Cannot override configuration data when access mode is READ." }, /* Then... GOGOCConfig strings */ { GOGOC_UIS__GROUP_GOGOCCONFIG, // title "gogoCLIENT Configuration Error" }, { GOGOC_UIS__G6C_INVALIDCONF, "Invalid configuration." }, { GOGOC_UIS__G6C_FAILLOADDFLTCONF, "Failed to load default configuration: No default configuration file"\ " was provided during initialization." }, { GOGOC_UIS__G6C_SUPPLYPASSWDWHENNOTANON, "Must supply password when authentication method is NOT anonymous." }, { GOGOC_UIS__G6C_PROXYCINVALIDMODE, "Proxy client cannot be enabled with tunnel mode v6udpv4." }, { GOGOC_UIS__G6C_KAINTERVALINVALID, "Keep-alive interval cannot be 0 when keep-alive is enabled." }, { GOGOC_UIS__G6C_IFTUNV6V4ANDV6UDPV4REQUIRED, "(if_tunnel_v6v4=,if_tunnel_v6udpv4=)You must provide both V6V4 and "\ "V6UDPV4 interfaces when using V6ANYV4 tunnel mode." }, { GOGOC_UIS__G6C_IFTUNV6V4REQUIRED, "(if_tunnel_v6v4=)You must provide the V6V4 tunnel interface when using"\ " V6V4 tunnel mode." }, { GOGOC_UIS__G6C_IFTUNV6UDPV4REQUIRED, "(if_tunnel_v6udpv4=)You must provide the V6UDPV4 tunnel interface when"\ " using V6UDPV4 tunnel mode." }, { GOGOC_UIS__G6C_IFTUNV4V6REQUIRED, "(if_tunnel_v4v6=)You must provide the V4V6 tunnel interface when using"\ " V4V6 tunnel mode." }, /* The gogoc validation strings */ { GOGOC_UIS__GROUP_GOGOCVALIDATION, // title "gogoCLIENT Validation Error" }, { GOGOC_UIS__G6V_USERIDTOOLONG, "(userid=)User ID must not be longer than 253 characters." }, { GOGOC_UIS__G6V_USERIDINVALIDCHRS, "(userid=)Invalid characters found in user name." }, { GOGOC_UIS__G6V_PASSWDTOOLONG, "(passwd=)Password must not be longer than 128 characters." }, { GOGOC_UIS__G6V_PASSWDINVALIDCHRS, "(passwd=)Invalid characters found in password." }, { GOGOC_UIS__G6V_SERVERMUSTBESPEC, "(server=)A server MUST be specified." }, { GOGOC_UIS__G6V_SERVERTOOLONG, "(server=)Server must not be longer than 1025 characters." }, { GOGOC_UIS__G6V_SERVERINVALIDCHRS, "(server=)Invalid characters found in server string." }, { GOGOC_UIS__G6V_HOSTTYPEINVALIDVALUE, "(host_type=)Host type must be: ." }, { GOGOC_UIS__G6V_PREFIXLENINVALIDVALUE, "(prefixlen=)Prefix length must be between 0 and 128." }, { GOGOC_UIS__G6V_IFPREFIXINVALIDCHRS, "(if_prefix=)Invalid characters found in interface name." }, { GOGOC_UIS__G6V_IFPREFIXMUSTBESPEC, "(if_prefix=)Interface prefix must be supplied when host_type is 'router'." }, { GOGOC_UIS__G6V_DNSSERVERSTOOLONG, "(dns_server=)DNS servers string must not be longer than 1025 characters." }, { GOGOC_UIS__G6V_DNSSERVERSUNRESOLVABLE, "(dns_server=)Failed to resolve one or more DNS servers found in configuration." }, { GOGOC_UIS__G6V_GOGOCDIRDOESNTEXIST, "(gogoc_dir=)The directory does not exist." }, { GOGOC_UIS__G6V_AUTHMETHODINVALIDVALUE, "(auth_method=)Authorization method must be: ." }, { GOGOC_UIS__G6V_AUTORETRYCONNECTINVALIDVALUE, "(retry_connect=)Retry connection must be:" }, { GOGOC_UIS__G6V_RETRYDELAYINVALIDVALUE, "(retry_delay=)Retry delay must be between 0 and 3600." }, { GOGOC_UIS__G6V_KEEPALIVEINVALIDVALUE, "(keepalive=)Keep-alive must be: " }, { GOGOC_UIS__G6V_KEEPALIVEINTERVINVALID, "(keepalive_interval=)Keep-alive interval must be positive." }, { GOGOC_UIS__G6V_TUNNELMODEINVALIDVALUE, "(tunnel_mode=)Tunnel mode must be: " }, { GOGOC_UIS__G6V_IFTUNV6V4INVALIDCHRS, "(if_tunnel_v6v4=)Invalid characters found in interface name." }, { GOGOC_UIS__G6V_IFTUNV6UDPV4INVALIDCHRS, "(if_tunnel_v6udpv4=)Invalid characters found in interface name." }, { GOGOC_UIS__G6V_IFTUNV4V6INVALIDCHRS, "(if_tunnel_v4v6=)Invalid characters found in interface name." }, { GOGOC_UIS__G6V_CLIENTV4INVALIDVALUE, "(client_v4=)Invalid IPv4 address. Address must be: ." }, { GOGOC_UIS__G6V_CLIENTV6INVALIDVALUE, "(client_v6=)IPv6 address must be: ." }, { GOGOC_UIS__G6V_TEMPLATEINVALIDVALUE, "(template=)Template must be: " }, { GOGOC_UIS__G6V_PROXYCLIENTINVALIDVALUE, "(proxy_client=)Proxy client must be: " }, { GOGOC_UIS__G6V_BROKERLISTTOOLONG, "(broker_list=)Broker list filename cannot be greater than 256 characters." }, { GOGOC_UIS__G6V_BROKERLISTINVALIDCHRS, "(broker_list=)Invalid characters found in broker list file name." }, { GOGOC_UIS__G6V_LASTSERVTOOLONG, "(last_server=)Last server filename cannot be greater than 256 characters." }, { GOGOC_UIS__G6V_LASTSERVINVALIDCHRS, "(last_server=)Invalid characters found in last server file name." }, { GOGOC_UIS__G6V_ALWAYSUSERLASTSERVINVALIDVALUE, "(always_use_same_server=)Value must be: " }, { GOGOC_UIS__G6V_LOGLEVELINVALIDVALUE, "(log=)Log level must be between 0 and 3." }, { GOGOC_UIS__G6V_LOGDEVICEINVALIDVALUE, "(log=)Log device must be: " }, { GOGOC_UIS__G6V_LOGFILENAMETOOLONG, "(log_filename=)Log filename cannot be greater than 256 characters." }, { GOGOC_UIS__G6V_LOGFILENAMEINVALIDCHRS, "(log_filename=)Invalid characters found in log file name." }, { GOGOC_UIS__G6V_LOGROTATIONINVALIDVALUE, "(log_rotation=)Log rotation must be: " }, { GOGOC_UIS__G6V_LOGROTSZINVALIDVALUE, "(log_rotation_size=)Log rotation size(in KB) must be: <16|32|128|1024>" }, { GOGOC_UIS__G6V_LOGROTDELINVALIDVALUE, "(log_rotation_delete=)Log rotation deletion must be: " }, { GOGOC_UIS__G6V_SYSLOGFACILITYINVALIDVALUE, "(syslog_facility=)Syslog facility must be: " }, { GOGOC_UIS__G6V_DNSSERVERSINVALIDCHRS, "(dns_server=)One or more DNS server specified contains invalid characters." }, { GOGOC_UIS__G6V_HACCESSPROXYENABLEDINVALIDVALUE, "(haccess_proxy_enabled=)Home Access must be: " }, { GOGOC_UIS__G6V_HACCESSWEBENABLEDINVALIDVALUE, "(haccess_web_enabled=)Home Web must be: " }, { GOGOC_UIS__G6V_HACCESSDOCROOTDOESNTEXIST, "(haccess_document_root=)Home Web document root must exist." }, { GOGOC_UIS__G6V_HACCESSDOCROOTNOTSPEC, "(haccess_document_root=)Must be specified when haccess_web_enabled=yes." }, { GOGOC_UIS__G6V_HACCESSINCOMPV4V6, "(tunnel_mode=)Tunnel mode cannot be V4V6 with Home Access or Home Web." }, { GOGOC_UIS__G6C_PROXYANDKEEPALIVE, "(keepalive=)Keep-alives cannot be turned on when proxy mode is on." }, { GOGOC_UIS__G6V_RETRYDELAYMAXINVALIDVALUE, "(retry_delay_max=)Retry delay max must be between 0 and 3600." }, { GOGOC_UIS__G6V_RETRYDELAYGREATERRETRYDELAYMAX, "(retry_delay_max=)Retry delay max must be greater than retry delay." } }; // -------------------------------------------------------------------------- // Function : get_ui_string // // Description: // Returns the user interface string specified by the id. // // Arguments: // id: int [IN], The string ID. // // Return values: // The UI string. // // Exceptions: (none) // // -------------------------------------------------------------------------- const char* get_ui_string( const error_t id ) { const unsigned int n = sizeof(gogocUIStrings) / sizeof(gogocUIStrings[0]); unsigned int i; for(i=0; i // Definition of valid characters for different strings. #define CFG_SERVER_CHRS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-.:[]" #define CFG_DNS_CHRS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-." #define CFG_FILENAME_CHRS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_./\\" #define CFG_NUMERIC_CHRS "1234567890" // Value limits. #define CFG_MAX_USERID 253 #define CFG_MAX_PASSWD 128 #define CFG_MAX_SERVER 1025 #define CFG_MIN_PREFIXLEN 0 #define CFG_MAX_PREFIXLEN 128 #define CFG_MAX_DNSSERVER 1025 #define CFG_MIN_RETRYDELAY 0 #define CFG_MAX_RETRYDELAY 3600 #define CFG_MIN_RETRYDELAYMAX 0 #define CFG_MAX_RETRYDELAYMAX 3600 #define CFG_MAX_FILENAME_LEN 256 #define CFG_MIN_LOG_LEVEL 0 #define CFG_MAX_LOG_LEVEL 3 // Domain values. static const char* cfgHOSTTYPE_values[] = { STR_HOSTTYPE_HOST, STR_HOSTTYPE_ROUTER }; static const char* cfgAUTHMETHOD_values[] = { STR_ANONYMOUS, STR_ANY, STR_DIGESTMD5, STR_PLAIN, STR_PASSDSS3DES1 }; static const char* cfgAUTORETRYCONNECT_values[] = { STR_YES, STR_NO }; static const char* cfgKEEPALIVE_values[] = { STR_YES, STR_NO }; static const char* cfgTUNNELMODE_values[] = { STR_V6ANYV4, STR_V6V4, STR_V6UDPV4, STR_V4V6, STR_DSLITE }; static const char* cfgTEMPLATE_values[] = { "freebsd","netbsd","linux",STR_TEMPL_WINDOWS,"darwin","cisco","sunos","openbsd","openwrt", "gogocpe" }; static const char* cfgPROXYCLIENT_values[] = { STR_YES, STR_NO }; static const char* cfgALWAYSUSELASTSVR_values[] = { STR_YES, STR_NO }; static const char* cfgLOGDEVICE_values[] = { STR_LOGDEV_CONSOLE,STR_LOGDEV_STDERR,STR_LOGDEV_FILE,STR_LOGDEV_SYSLOG }; static const char* cfgLOGROTATION_values[] = { STR_YES, STR_NO }; static const char* cfgLOGROTATIONSZ_values[] = { STR_LOGROTSZ_16K, STR_LOGROTSZ_32K, STR_LOGROTSZ_128K, STR_LOGROTSZ_1024K }; static const char* cfgLOGROTATIONDEL_values[] = { STR_YES, STR_NO }; static const char* cfgSYSLOGFACILITY_values[] = { "USER","LOCAL0","LOCAL1","LOCAL2","LOCAL3","LOCAL4","LOCAL5","LOCAL6","LOCAL7" }; static const char* cfgHACCESSPROXYENABLED_values[] = { STR_YES, STR_NO }; static const char* cfgHACCESSWEBENABLED_values[] = { STR_YES, STR_NO }; namespace gogocconfig { // global static integer containing the last error. static error_t gssLastError = GOGOC_UIS__NOERROR; // -------------------------------------------------------------------------- // Function : GetLastError // // Description: // Returns the last error set. // // Arguments: (none) // // Return values: // The error number of the last error. See gogocUIstrings.h // // Exceptions: (none) // // -------------------------------------------------------------------------- const error_t GetLastError( void ) { return gssLastError; } // -------------------------------------------------------------------------- // Function : DirExists // // Description: // Helper function to verify if a directory exists. // // Arguments: // aDir: string [IN], The directory name as a string. // // Return values: // true if directory exists, false otherwise. // // Exceptions: (none) // // -------------------------------------------------------------------------- bool DirExists( const string& aDir ) { char buf[2048]; bool bValid = true; // Get and save actual working directory. if( pal_getcwd(buf,2048) ) { // Attempt changing directory. bValid = pal_chdir(aDir.c_str()) == 0; // restore previous working directory. pal_chdir(buf); } return bValid; } // -------------------------------------------------------------------------- // ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ // g o g o C L I E N T // V A L I D A T I O N R O U T I N E S // __________________________________________________________________________ // -------------------------------------------------------------------------- bool Validate_UserID( const string& sUserID ) { // Facultative if( sUserID.size() == 0 ) return true; // Check string length. if( sUserID.size() > CFG_MAX_USERID ) { gssLastError = GOGOC_UIS__G6V_USERIDTOOLONG; return false; } // Check for invalid characters const char* c; for( c = sUserID.c_str(); *c; c++ ) if (*c < ' ' || *c > '~') { gssLastError = GOGOC_UIS__G6V_USERIDINVALIDCHRS; return false; } return true; } // -------------------------------------------------------------------------- bool Validate_Passwd( const string& sPasswd ) { // Facultative if( sPasswd.size() == 0 ) return true; // Check string length. if( sPasswd.size() > CFG_MAX_PASSWD ) { gssLastError = GOGOC_UIS__G6V_PASSWDTOOLONG; return false; } // Check for invalid characters const char* c; for( c = sPasswd.c_str(); *c; c++ ) if (*c < ' ' || *c > '~') { gssLastError = GOGOC_UIS__G6V_PASSWDINVALIDCHRS; return false; } return true; } // -------------------------------------------------------------------------- bool Validate_Server( const string& sServer ) { /* Bug 3882: removed server from config file -> Is now facultative. // NOT facultative if( sServer.size() == 0 ) { gssLastError = GOGOC_UIS__G6V_SERVERMUSTBESPEC; return false; }*/ // Facultative if( sServer.size() == 0 ) return true; // Check string length. if( sServer.size() > CFG_MAX_SERVER ) { gssLastError = GOGOC_UIS__G6V_SERVERTOOLONG; return false; } // check for invalid characters if( sServer.find_first_not_of( CFG_SERVER_CHRS ) != string::npos ) { gssLastError = GOGOC_UIS__G6V_SERVERINVALIDCHRS; return false; } return true; } // -------------------------------------------------------------------------- bool Validate_HostType( const string& sHostType ) { // Facultative if( sHostType.size() == 0 ) return true; // Check against domain values. for(unsigned int i=0; i<(sizeof(cfgHOSTTYPE_values)/sizeof(cfgHOSTTYPE_values[0])); i++) { if( sHostType == cfgHOSTTYPE_values[i] ) return true; } gssLastError = GOGOC_UIS__G6V_HOSTTYPEINVALIDVALUE; return false; } // -------------------------------------------------------------------------- bool Validate_PrefixLen( const string& sPrefixLen ) { // Facultative if( sPrefixLen.size() == 0 ) return true; // Check characters are all numeric. if( sPrefixLen.find_first_not_of( CFG_NUMERIC_CHRS ) != string::npos ) { gssLastError = GOGOC_UIS__G6V_PREFIXLENINVALIDVALUE; return false; } short _PrefixLen = (short)strtol(sPrefixLen.c_str(), (char**)NULL, 10); if( _PrefixLen <= CFG_MIN_PREFIXLEN || _PrefixLen > CFG_MAX_PREFIXLEN ) { gssLastError = GOGOC_UIS__G6V_PREFIXLENINVALIDVALUE; return false; } return true; } // -------------------------------------------------------------------------- bool Validate_IfPrefix( const string& sIfPrefix ) { // Check for invalid characters if( sIfPrefix.find_first_not_of( CFG_FILENAME_CHRS ) != string::npos ) { gssLastError = GOGOC_UIS__G6V_IFPREFIXINVALIDCHRS; return false; } return true; } // -------------------------------------------------------------------------- bool Validate_DnsServer( const string& sDnsServer ) { // Facultative if( sDnsServer.size() == 0 ) return true; // Check string length if( sDnsServer.size() > CFG_MAX_DNSSERVER ) { gssLastError = GOGOC_UIS__G6V_DNSSERVERSTOOLONG; return false; } // Check every server to see if they're all valid. char* szDNSServers; char* szServer; string sServer; szDNSServers = pal_strdup( sDnsServer.c_str() ); for(szServer = strtok(szDNSServers, ":");szServer; szServer=strtok(NULL, ":") ) { sServer = szServer; // check for invalid characters if( sServer.find_first_not_of( CFG_DNS_CHRS ) != string::npos ) { gssLastError = GOGOC_UIS__G6V_DNSSERVERSINVALIDCHRS; free( szDNSServers ); return false; } /* // Attempt to resolve hostname if( gethostbyname(szServer) == NULL ) { gssLastError = GOGOC_UIS__G6V_DNSSERVERSUNRESOLVABLE; free( szDNSServers ); return false; } */ } free( szDNSServers ); return true; } // -------------------------------------------------------------------------- bool Validate_gogocDir( const string& sgogocDir ) { // Facultative if( sgogocDir.size() == 0 ) return true; if( !DirExists(sgogocDir) ) { gssLastError = GOGOC_UIS__G6V_GOGOCDIRDOESNTEXIST; return false; } return true; } // -------------------------------------------------------------------------- bool Validate_AuthMethod( const string& sAuthMethod ) { // Facultative if( sAuthMethod.size() == 0 ) return true; // Check against domain values. for(unsigned int i=0; i<(sizeof(cfgAUTHMETHOD_values)/sizeof(cfgAUTHMETHOD_values[0])); i++) { if( sAuthMethod == cfgAUTHMETHOD_values[i] ) return true; } gssLastError = GOGOC_UIS__G6V_AUTHMETHODINVALIDVALUE; return false; } // -------------------------------------------------------------------------- bool Validate_AutoRetryConnect( const string& sAutoRetryConnect ) { // Facultative if( sAutoRetryConnect.size() == 0 ) return true; // Check against domain values. for(unsigned int i=0; i<(sizeof(cfgAUTORETRYCONNECT_values)/sizeof(cfgAUTORETRYCONNECT_values[0])); i++) { if( sAutoRetryConnect == cfgAUTORETRYCONNECT_values[i] ) return true; } gssLastError = GOGOC_UIS__G6V_AUTORETRYCONNECTINVALIDVALUE; return false; } // -------------------------------------------------------------------------- bool Validate_RetryDelay( const string& sRetryDelay ) { // Facultative if( sRetryDelay.size() == 0 ) return true; // Check characters are all numeric. if( sRetryDelay.find_first_not_of( CFG_NUMERIC_CHRS ) != string::npos ) { gssLastError = GOGOC_UIS__G6V_RETRYDELAYINVALIDVALUE; return false; } long _RetryDelay = strtol(sRetryDelay.c_str(), (char**)NULL, 10); if( _RetryDelay < CFG_MIN_RETRYDELAY || _RetryDelay > CFG_MAX_RETRYDELAY) { gssLastError = GOGOC_UIS__G6V_RETRYDELAYINVALIDVALUE; return false; } return true; } // -------------------------------------------------------------------------- bool Validate_RetryDelayMax( const string& sRetryDelayMax ) { // Facultative if( sRetryDelayMax.size() == 0 ) return true; // Check characters are all numeric. if( sRetryDelayMax.find_first_not_of( CFG_NUMERIC_CHRS ) != string::npos ) { gssLastError = GOGOC_UIS__G6V_RETRYDELAYMAXINVALIDVALUE; return false; } long _RetryDelayMax = strtol(sRetryDelayMax.c_str(), (char**)NULL, 10); if( _RetryDelayMax < CFG_MIN_RETRYDELAYMAX || _RetryDelayMax > CFG_MAX_RETRYDELAYMAX) { gssLastError = GOGOC_UIS__G6V_RETRYDELAYMAXINVALIDVALUE; return false; } return true; } // -------------------------------------------------------------------------- bool Validate_KeepAlive( const string& sKeepAlive ) { // Facultative if( sKeepAlive.size() == 0 ) return true; // Check against domain values. for(unsigned int i=0; i<(sizeof(cfgKEEPALIVE_values)/sizeof(cfgKEEPALIVE_values[0])); i++) { if( sKeepAlive == cfgKEEPALIVE_values[i] ) return true; } gssLastError = GOGOC_UIS__G6V_KEEPALIVEINVALIDVALUE; return false; } // -------------------------------------------------------------------------- bool Validate_KeepAliveInterval( const string& sKeepAliveInterval ) { // Facultative if( sKeepAliveInterval.size() == 0 ) return true; // Check characters are all numeric. if( sKeepAliveInterval.find_first_not_of( CFG_NUMERIC_CHRS ) != string::npos ) { gssLastError = GOGOC_UIS__G6V_KEEPALIVEINTERVINVALID; return false; } long _KAInterval = strtol(sKeepAliveInterval.c_str(), (char**)NULL, 10); if( _KAInterval < 0 ) { gssLastError = GOGOC_UIS__G6V_KEEPALIVEINTERVINVALID; return false; } return true; } // -------------------------------------------------------------------------- bool Validate_TunnelMode( const string& sTunnelMode ) { // Facultative if( sTunnelMode.size() == 0 ) return true; // Check against domain values. for(unsigned int i=0; i<(sizeof(cfgTUNNELMODE_values)/sizeof(cfgTUNNELMODE_values[0])); i++) { if( sTunnelMode == cfgTUNNELMODE_values[i] ) return true; } gssLastError = GOGOC_UIS__G6V_TUNNELMODEINVALIDVALUE; return false; } // -------------------------------------------------------------------------- bool Validate_IfTunV6V4( const string& sIfTunV6V4 ) { // Facultative (checked later with tunnel mode) if( sIfTunV6V4.size() == 0 ) return true; // Check for invalid characters if( sIfTunV6V4.find_first_not_of( CFG_DNS_CHRS ) != string::npos ) { gssLastError = GOGOC_UIS__G6V_IFTUNV6V4INVALIDCHRS; return false; } return true; } // -------------------------------------------------------------------------- bool Validate_IfTunV6UDPV4( const string& sIfTunV6UDPV4 ) { // Facultative (checked later with tunnel mode) if( sIfTunV6UDPV4.size() == 0 ) return true; // Check for invalid characters if( sIfTunV6UDPV4.find_first_not_of( CFG_DNS_CHRS ) != string::npos ) { gssLastError = GOGOC_UIS__G6V_IFTUNV6UDPV4INVALIDCHRS; return false; } return true; } // -------------------------------------------------------------------------- bool Validate_IfTunV4V6( const string& sIfTunV4V6 ) { // Facultative (checked later with tunnel mode) if( sIfTunV4V6.size() == 0 ) return true; // Check for invalid characters if( sIfTunV4V6.find_first_not_of( CFG_DNS_CHRS ) != string::npos ) { gssLastError = GOGOC_UIS__G6V_IFTUNV4V6INVALIDCHRS; return false; } return true; } // -------------------------------------------------------------------------- bool Validate_ClientV4( const string& sClientV4 ) { // Facultative if( sClientV4.size() == 0 ) return true; // If not auto then check if ip address is ok. if( sClientV4 != STR_AUTO ) { struct in_addr address; unsigned long net; net = inet_addr( sClientV4.c_str() ); memcpy(&address, &net, sizeof(net)); if( sClientV4 != inet_ntoa(address) ) { gssLastError = GOGOC_UIS__G6V_CLIENTV4INVALIDVALUE; return false; } } return true; } // -------------------------------------------------------------------------- bool Validate_DSLite( const string& sDSLite ) { // Facultative if( sDSLite.size() == 0 ) return true; { struct in_addr address; unsigned long net; net = inet_addr( sDSLite.c_str() ); memcpy(&address, &net, sizeof(net)); if( sDSLite != inet_ntoa(address) ) { gssLastError = GOGOC_UIS__G6V_CLIENTV4INVALIDVALUE; return false; } } return true; } // -------------------------------------------------------------------------- bool Validate_ClientV6( const string& sClientV6 ) { // Facultative if( sClientV6.size() == 0 ) return true; // If not auto then check if ip address is ok. if( sClientV6 != STR_AUTO ) { struct in6_addr address; if( pal_inet_pton(AF_INET6, sClientV6.c_str(), &address) <= 0 ) { gssLastError = GOGOC_UIS__G6V_CLIENTV6INVALIDVALUE; return false; } } return true; } // -------------------------------------------------------------------------- bool Validate_Template( const string& sTemplate ) { // Check against domain values. for(unsigned int i=0; i<(sizeof(cfgTEMPLATE_values)/sizeof(cfgTEMPLATE_values[0])); i++) { if( sTemplate == cfgTEMPLATE_values[i] ) return true; } gssLastError = GOGOC_UIS__G6V_TEMPLATEINVALIDVALUE; return false; } // -------------------------------------------------------------------------- bool Validate_ProxyClient( const string& sProxyClient ) { // Facultative if( sProxyClient.size() == 0 ) return true; // Check against domain values. for(unsigned int i=0; i<(sizeof(cfgPROXYCLIENT_values)/sizeof(cfgPROXYCLIENT_values[0])); i++) { if( sProxyClient == cfgPROXYCLIENT_values[i] ) return true; } gssLastError = GOGOC_UIS__G6V_PROXYCLIENTINVALIDVALUE; return false; } // -------------------------------------------------------------------------- bool Validate_BrokerLstFile( const string& sBrokerLstFile ) { // Check string length if( sBrokerLstFile.size() > CFG_MAX_FILENAME_LEN ) { gssLastError = GOGOC_UIS__G6V_BROKERLISTTOOLONG; return false; } // Check for invalid characters if( sBrokerLstFile.find_first_not_of( CFG_FILENAME_CHRS ) != string::npos ) { gssLastError = GOGOC_UIS__G6V_BROKERLISTINVALIDCHRS; return false; } return true; } // -------------------------------------------------------------------------- bool Validate_LastServFile( const string& sLastServFile ) { // Check string length if( sLastServFile.size() > CFG_MAX_FILENAME_LEN ) { gssLastError = GOGOC_UIS__G6V_LASTSERVTOOLONG; return false; } // Check for invalid characters if( sLastServFile.find_first_not_of( CFG_FILENAME_CHRS ) != string::npos ) { gssLastError = GOGOC_UIS__G6V_LASTSERVINVALIDCHRS; return false; } return true; } // -------------------------------------------------------------------------- bool Validate_AlwaysUseLastSrv( const string& sAlwaysUseLastSrv ) { // Facultative if( sAlwaysUseLastSrv.size() == 0 ) return true; // Check against domain values. for(unsigned int i=0; i<(sizeof(cfgALWAYSUSELASTSVR_values)/sizeof(cfgALWAYSUSELASTSVR_values[0])); i++) { if( sAlwaysUseLastSrv == cfgALWAYSUSELASTSVR_values[i] ) return true; } gssLastError = GOGOC_UIS__G6V_ALWAYSUSERLASTSERVINVALIDVALUE; return false; } // -------------------------------------------------------------------------- bool Validate_LogDevice( const string& sLogDevice ) { // Not facultative. // Check log device for(unsigned int i=0; i<(sizeof(cfgLOGDEVICE_values)/sizeof(cfgLOGDEVICE_values[0])); i++) { if( sLogDevice == cfgLOGDEVICE_values[i] ) return true; } gssLastError = GOGOC_UIS__G6V_LOGDEVICEINVALIDVALUE; return false; } bool Validate_LogLevel( const string& sLogLevel ) { // Facultative if( sLogLevel.size() == 0 ) return true; // Check log level, if any long _LogLevel = strtol(sLogLevel.c_str(), (char**)NULL, 10); if( _LogLevel < CFG_MIN_LOG_LEVEL || _LogLevel > CFG_MAX_LOG_LEVEL ) { gssLastError = GOGOC_UIS__G6V_LOGLEVELINVALIDVALUE; return false; } return true; } // -------------------------------------------------------------------------- bool Validate_LogFileName( const string& sLogFileName ) { // Check string length if( sLogFileName.size() > CFG_MAX_FILENAME_LEN ) { gssLastError = GOGOC_UIS__G6V_LOGFILENAMETOOLONG; return false; } // Check for invalid characters if( sLogFileName.find_first_not_of( CFG_FILENAME_CHRS ) != string::npos ) { gssLastError = GOGOC_UIS__G6V_LOGFILENAMEINVALIDCHRS; return false; } return true; } // -------------------------------------------------------------------------- bool Validate_LogRotation( const string& sLogRotation ) { // Facultative if( sLogRotation.size() == 0 ) return true; // Check against domain values. for(unsigned int i=0; i<(sizeof(cfgLOGROTATION_values)/sizeof(cfgLOGROTATION_values[0])); i++) { if( sLogRotation == cfgLOGROTATION_values[i] ) return true; } gssLastError = GOGOC_UIS__G6V_LOGROTATIONINVALIDVALUE; return false; } // -------------------------------------------------------------------------- bool Validate_LogRotationSz( const string& sLogRotationSz ) { // Facultative if( sLogRotationSz.size() == 0 ) return true; // Check against domain values. for(unsigned int i=0; i<(sizeof(cfgLOGROTATIONSZ_values)/sizeof(cfgLOGROTATIONSZ_values[0])); i++) { if( sLogRotationSz == cfgLOGROTATIONSZ_values[i] ) return true; } gssLastError = GOGOC_UIS__G6V_LOGROTSZINVALIDVALUE; return false; } // -------------------------------------------------------------------------- bool Validate_LogRotationDel( const string& sLogRotationDel ) { // Facultative if( sLogRotationDel.size() == 0 ) return true; // Check against domain values. for(unsigned int i=0; i<(sizeof(cfgLOGROTATIONDEL_values)/sizeof(cfgLOGROTATIONDEL_values[0])); i++) { if( sLogRotationDel == cfgLOGROTATIONDEL_values[i] ) return true; } gssLastError = GOGOC_UIS__G6V_LOGROTDELINVALIDVALUE; return false; } // -------------------------------------------------------------------------- bool Validate_SysLogFacility( const string& sSysLogFacility ) { // Facultative if( sSysLogFacility.size() == 0 ) return true; // Check against domain values. for(unsigned int i=0; i<(sizeof(cfgSYSLOGFACILITY_values)/sizeof(cfgSYSLOGFACILITY_values[0])); i++) { if( sSysLogFacility == cfgSYSLOGFACILITY_values[i] ) return true; } gssLastError = GOGOC_UIS__G6V_SYSLOGFACILITYINVALIDVALUE; return false; } // -------------------------------------------------------------------------- bool Validate_haccessProxyEnabled( const string& shaccessProxyEnabled ) { // Facultative if( shaccessProxyEnabled.size() == 0 ) return true; // Check against domain values. for(unsigned int i=0; i<(sizeof(cfgHACCESSPROXYENABLED_values)/sizeof(cfgHACCESSPROXYENABLED_values[0])); i++) { if( shaccessProxyEnabled == cfgHACCESSPROXYENABLED_values[i] ) return true; } gssLastError = GOGOC_UIS__G6V_HACCESSPROXYENABLEDINVALIDVALUE; return false; } // -------------------------------------------------------------------------- bool Validate_haccessWebEnabled( const string& shaccessWebEnabled ) { // Facultative if( shaccessWebEnabled.size() == 0 ) return true; // Check against domain values. for(unsigned int i=0; i<(sizeof(cfgHACCESSWEBENABLED_values)/sizeof(cfgHACCESSWEBENABLED_values[0])); i++) { if( shaccessWebEnabled == cfgHACCESSWEBENABLED_values[i] ) return true; } gssLastError = GOGOC_UIS__G6V_HACCESSWEBENABLEDINVALIDVALUE; return false; } // -------------------------------------------------------------------------- bool Validate_haccessDocumentRoot( const string& shaccessDocumentRoot ) { // Facultative if( shaccessDocumentRoot.size() == 0 ) return true; // Check if directory exists. if( !DirExists(shaccessDocumentRoot) ) { gssLastError = GOGOC_UIS__G6V_HACCESSDOCROOTDOESNTEXIST; return false; } return true; } } gogoc-1_2-RELEASE/gogoc-config/src/haccess_devmap_c_wrap.cc0100644000000000000000000001252611301542042022245 0ustar rootroot// ************************************************************************** // $Id: haccess_devmap_c_wrap.cc,v 1.1 2009/11/20 16:30:26 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Wraps the HomeAccess Device Mapping configuration data to offer C access. // // Author: Charles Nepveu // // Creation Date: Febuary 2007 // __________________________________________________________________________ // ************************************************************************** #include "pal.h" #include #include #include #include using namespace gogocconfig; // The instance holder for the HACCESS Device Mapping configuration data object. static HACCESSDeviceMappingConfig* gpConfig = NULL; // -------------------------------------------------------------------------- // Function : init_haccess_devmap // // Description: // Will create a HACCESS Device Mapping configuration object and load the // configuration data. // // Arguments: // szFileName: char* [IN], The name of the configuration file to load. // // Return values: // * 0 on successful initialization, // * -1 means that some mappings were removed because they were invalid. // * any other positive value indicates a severe error and should be // logged using get_ui_string(). // // Exceptions: (none) // // -------------------------------------------------------------------------- extern "C" int init_haccess_devmap( const char* szFileName ) { int iRet = 0; // Check if already initialized. if( gpConfig != NULL ) return iRet; try { // Create new instance, initialize... gpConfig = new HACCESSDeviceMappingConfig(); gpConfig->Initialize( szFileName, AM_READ ); // READ ONLY // ...and load configuration data. iRet = gpConfig->Load() ? 0 : -1; } catch( error_t nErr ) { iRet = nErr; } return iRet; } // -------------------------------------------------------------------------- // Function : reload_haccess_devmap // // Description: // Will reload the HACCESS Device Mapping configuration data. // // Arguments: (none) // // Return values: (none) // // Exceptions: (none) // // -------------------------------------------------------------------------- extern "C" int reload_haccess_devmap( void ) { assert( gpConfig != NULL ); int iRet = 0; try { // Re-load the configuratrion. iRet = gpConfig->Load() ? 0 : -1; } catch( error_t nErr ) { iRet = nErr; } return iRet; } // -------------------------------------------------------------------------- // Function : uninit_haccess_devmap // // Description: // Will clean-up the HACCESS Device Mapping configuration data object. // // Arguments: (none) // // Return values: (none) // // Exceptions: (none) // // -------------------------------------------------------------------------- extern "C" void uninit_haccess_devmap( void ) { if( gpConfig != NULL ) delete gpConfig; gpConfig = NULL; } // -------------------------------------------------------------------------- // Function : get_device_mapping // // Description: // Will create a chained list containing the device mapping found in the // HACCESS Device Mapping File. // // Arguments: // ppMapping: DEVICE_MAPPING double reference. To be filled. // // Return values: // 0 on success, /// any other value indicates an error. // // Exceptions: (none) // // -------------------------------------------------------------------------- extern "C" int get_device_mapping( PDEVICE_MAPPING* ppDeviceMapping ) { assert( gpConfig != NULL ); assert( ppDeviceMapping != NULL ); assert( *ppDeviceMapping == NULL ); // Will be instantiated here. t_stringmap deviceMap; t_stringmap::const_iterator iter; PDEVICE_MAPPING* current = ppDeviceMapping; try { // Get the device mapping list. if( !gpConfig->GetDeviceList( deviceMap ) ) return -1; for( iter=deviceMap.begin(); iter != deviceMap.end(); iter++ ) { if( ((*current) = (PDEVICE_MAPPING) malloc( sizeof(DEVICE_MAPPING) )) != NULL ) { (*current)->szName = pal_strdup( iter->first.c_str() ); (*current)->szAddress = pal_strdup( iter->second.c_str() ); (*current)->next = NULL; } current = &((*current)->next); } } catch( error_t err ) { return (int)err; } return 0; } // -------------------------------------------------------------------------- // Function : get_device_mapping // // Description: // Will free a linked list created by get_device_mapping() // // Arguments: // ppMapping: DEVICE_MAPPING double reference. To be freed. // // Return values: (none) // // Exceptions: (none) // // -------------------------------------------------------------------------- extern "C" void free_device_mapping( PDEVICE_MAPPING* ppDeviceMapping ) { assert( ppDeviceMapping != NULL ); if( (*ppDeviceMapping) != NULL ) // If not end of linked list. { // Recurse. free_device_mapping( &((*ppDeviceMapping)->next) ); assert( (*ppDeviceMapping)->next == NULL ); // Delete this instance. free( (*ppDeviceMapping)->szName ); free( (*ppDeviceMapping)->szAddress ); free( (*ppDeviceMapping) ); (*ppDeviceMapping) = NULL; } } gogoc-1_2-RELEASE/gogoc-config/src/haccessdevicemappingconfig.cc0100644000000000000000000002670611301542042023305 0ustar rootroot// ************************************************************************** // $Id: haccessdevicemappingconfig.cc,v 1.1 2009/11/20 16:30:26 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Implementation of the HACCESSDeviceMappingConfig class // // Description: // Implementation of the HACCESS Device Mapping configuration accessors. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #include #include #include #include #define MAX_DEVICENAME_LEN 64 #define CHRS_DEVICENAME "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-" #define MAX_IPADDR_LEN 40 #define CHRS_IPADDR "abcdefABCDEF0123456789.:" namespace gogocconfig { // -------------------------------------------------------------------------- // Function : HACCESSDeviceMappingConfig constructor // // Description: // Will initialize a new HACCESSDeviceMappingConfig object. // // Arguments: (none) // // Return values: (N/A) // // Exceptions: (none) // // -------------------------------------------------------------------------- HACCESSDeviceMappingConfig::HACCESSDeviceMappingConfig( void ) : m_pConfig(NULL) { } // -------------------------------------------------------------------------- // Function : HACCESSDeviceMappingConfig destructor // // Description: // Will destroy HACCESSDeviceMappingConfig object. // // Arguments: (N/A) // // Return values: (N/A) // // Exceptions: (none) // // -------------------------------------------------------------------------- HACCESSDeviceMappingConfig::~HACCESSDeviceMappingConfig( void ) { // Delete the configuration object, if it was constructed. if( m_pConfig != NULL ) delete m_pConfig; m_pConfig = NULL; } // -------------------------------------------------------------------------- // Function : Initialize // // Description: // Will initialize the configuration object. // // Arguments: // aConfigFile: string [IN], The HACCESS Device Mapping configuration file name. // aEAccessMode: enum [IN], The desired access mode (READ, CREATE, RW) // // Return values: (none) // // Exceptions: (none) // // -------------------------------------------------------------------------- void HACCESSDeviceMappingConfig::Initialize( const string& aConfigFile, const t_accessMode aEAccessMode ) { // If instance was already initialized... if( m_pConfig != NULL) delete m_pConfig; // Instantiate the name value configuration parser. m_pConfig = new NameValueConfig( aConfigFile, aEAccessMode ); } // -------------------------------------------------------------------------- // Function : Load // // Description: // Will load the HACCESS Device Mapping configuration data. // // Arguments: (none) // // Return values: // true if configuration data was successfully loaded from the file. // // Exceptions: // - See Config::LoadConfiguration() // // -------------------------------------------------------------------------- bool HACCESSDeviceMappingConfig::Load( void ) { assert( m_pConfig != NULL ); // Read the configuration file. return m_pConfig->LoadConfiguration() && ValidateConfig(); } // -------------------------------------------------------------------------- // Function : Save // // Description: // Will save the configuration data. // // Arguments: (none) // // Return values: // true if configuration data has been saved to the file. // // Exceptions: // - See Config::ApplyConfiguration() // // -------------------------------------------------------------------------- bool HACCESSDeviceMappingConfig::Save( void ) { assert( m_pConfig != NULL ); return ValidateConfig() && m_pConfig->ApplyConfiguration(); } // -------------------------------------------------------------------------- // Function : CancelChanges // // Description: // Will cancel the changes made to the configuration data. // // Arguments: (none) // // Return values: // true if changes made to the configuration data were successfully // cancelled, false otherwise. // // Exceptions: // - See Config::CancelConfiguration() // // -------------------------------------------------------------------------- bool HACCESSDeviceMappingConfig::CancelChanges( void ) { assert( m_pConfig != NULL ); return m_pConfig->CancelConfiguration(); } // -------------------------------------------------------------------------- // Function : ValidateConfig // // Description: // Will loop thru the device mappings and check if the configuration is // valid. // // Arguments: (none) // // Return values: // true if validation has passed. // // Exceptions: // // -------------------------------------------------------------------------- bool HACCESSDeviceMappingConfig::ValidateConfig( void ) { bool bRetCode = true; t_stringmap mappings; t_stringmap::iterator iter; bRetCode = GetDeviceList( mappings ); for( iter=mappings.begin(); iter != mappings.end(); iter ++ ) { if( !ValidateDeviceName( iter->first ) || !ValidateIPAddress( iter->second ) ) { // Mapping is invalid. Remove it. DelDeviceMapping( iter->first ); bRetCode = false; } } return bRetCode; } // -------------------------------------------------------------------------- // Function : ValidateDeviceName // // Description: // Validates a device name. // // Arguments: (none) // // Return values: // true if validation has passed. // // Exceptions: // // -------------------------------------------------------------------------- bool HACCESSDeviceMappingConfig::ValidateDeviceName( const string& aDeviceName ) { if( aDeviceName.empty() ) return false; if( aDeviceName.length() > MAX_DEVICENAME_LEN ) return false; if( aDeviceName.find_first_not_of( CHRS_DEVICENAME ) != string::npos ) return false; return true; } // -------------------------------------------------------------------------- // Function : ValidateIPAddress // // Description: // Validates an IP address. // // Arguments: (none) // // Return values: // true if validation has passed. // // Exceptions: // // -------------------------------------------------------------------------- bool HACCESSDeviceMappingConfig::ValidateIPAddress( const string& aIPAddress ) { if( aIPAddress.empty() ) return false; if( aIPAddress.length() > MAX_IPADDR_LEN ) return false; if( aIPAddress.find_first_not_of( CHRS_IPADDR ) != string::npos ) return false; // Check if IPv4 or IPv6 address struct in6_addr addressv6; struct in_addr addressv4; unsigned long net; net = inet_addr( aIPAddress.c_str() ); memcpy(&addressv4, &net, sizeof(net)); if( aIPAddress != inet_ntoa(addressv4) && (pal_inet_pton(AF_INET6, aIPAddress.c_str(), &addressv6) <= 0) ) return false; return true; } // -------------------------------------------------------------------------- // Function : AddDeviceMapping // // Description: // Will add a new device mapping to the configuration file. // NOTE: This function will update the address if the device name specified // already exists. // // Arguments: // aName: string [IN], The device name. // aAddress: string[IN], The device (IPv6 or IPv4) address. // // Return values: // true if device mapping has been successfully added (or updated). // // Exceptions: (none) // // -------------------------------------------------------------------------- bool HACCESSDeviceMappingConfig::AddDeviceMapping( const string& aName, const string& aAddress ) { assert( m_pConfig != NULL ); m_pConfig->SetVariableValue( aName, aAddress ); return true; } // -------------------------------------------------------------------------- // Function : DelDeviceMapping // // Description: // Will remove a device mapping from the configuration file. // // Arguments: // aName: string [IN], The device name to remove. // // Return values: // true if device mapping has been successfully removed. // // Exceptions: (none) // // -------------------------------------------------------------------------- bool HACCESSDeviceMappingConfig::DelDeviceMapping( const string& aName ) { assert( m_pConfig != NULL ); m_pConfig->RemoveVariable( aName ); return true; } // -------------------------------------------------------------------------- // Function : GetDeviceAddress // // Description: // Will retrieve the address of the specified device name from the // configuration file. // // Arguments: // aName: string [IN], The device name. // // Return values: // true if address has been successfully retrieved. // // Exceptions: (none) // // -------------------------------------------------------------------------- bool HACCESSDeviceMappingConfig::GetDeviceAddress( const string& aName, string& aAddress ) const { string sAddress; assert( m_pConfig != NULL ); m_pConfig->GetVariableValue( aName, aAddress ); return true; } // -------------------------------------------------------------------------- // Function : SetDeviceAddress // // Description: // Will set(overwrite) the address of the specified device name from the // configuration file. // NOTE: This function will create the mapping if the device name specified // does not exists. // // Arguments: // aName: string [IN], The device name. // aAddress: string[IN], The new device (IPv6 or IPv4) address. // // Return values: // true if mapping has been successfully updated (or created). // // Exceptions: // - When device mapping doesn't exists. // // -------------------------------------------------------------------------- bool HACCESSDeviceMappingConfig::SetDeviceAddress( const string& aName, const string& aAddress ) { assert( m_pConfig != NULL ); m_pConfig->SetVariableValue( aName, aAddress ); return true; } // -------------------------------------------------------------------------- // Function : GetDeviceNameList // // Description: // Will retrieve a list of device names that are present in the HACCESS // Device Mapping configuration file. // // Arguments: (none) // // Return values: // true if device names were successfully enumerated. // // Exceptions: (none) // // -------------------------------------------------------------------------- bool HACCESSDeviceMappingConfig::GetDeviceNameList( t_stringarray& aNameList ) const { stringlist nameList; stringlist::const_iterator iter; m_pConfig->GetVariableNameList( nameList ); for( iter=nameList.begin(); iter != nameList.end() ; iter++ ) aNameList.push_back( *iter ); return true; } // -------------------------------------------------------------------------- // Function : GetDeviceList // // Description: // Will retrieve a list of device names and their associated address that // are present in the HACCESS Device Mapping configuration file. // // Arguments: (none) // // Return values: // true if device mapping was successfully extracted. // // Exceptions: (none) // // -------------------------------------------------------------------------- bool HACCESSDeviceMappingConfig::GetDeviceList( t_stringmap& aDeviceMap ) const { stringlist nameList; stringlist::const_iterator iter; string sValue; m_pConfig->GetVariableNameList( nameList ); for( iter=nameList.begin(); iter != nameList.end() ; iter++ ) { m_pConfig->GetVariableValue( *iter, sValue ); aDeviceMap[ *iter ] = sValue; } return true; } } // Namespace gogoc-1_2-RELEASE/gogoc-config/src/namevalueconfig.cc0100644000000000000000000001373011301542042021106 0ustar rootroot// ************************************************************************** // $Id: namevalueconfig.cc,v 1.1 2009/11/20 16:30:26 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Implementation of the NameValueConfig class // // Description: // Extends the Config class to provide NAME=VALUE variables access. // To perform LOAD, APPLY, CANCEL, OVERRIDE operations, refer to the // Config class. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #include #include #include namespace gogocconfig { // -------------------------------------------------------------------------- // Function : NameValueConfig constructor // // Description: // Will initialize a new NameValueConfig object. // // Arguments: // aFileName: string [IN], The file name of the configuration data. // aEAccessMode: enum [IN], The access mode to the configuration data. // // Return values: (N/A) // // Exceptions: (none) // // -------------------------------------------------------------------------- NameValueConfig::NameValueConfig( const string& aFileName, const t_accessMode aEAccessMode ) : Config( aFileName, aEAccessMode ) { // Create the parser. m_pParser = new NameValueParser( NVP_READ_ALL ); } // -------------------------------------------------------------------------- // Function : NameValueConfig destructor // // Description: // Will destroy the class. // // Arguments: (none) // // Return values: (N/A) // // Exceptions: (none) // // -------------------------------------------------------------------------- NameValueConfig::~NameValueConfig( void ) { assert( m_pParser != NULL ); // Delete the parser object. delete m_pParser; m_pParser = NULL; } // -------------------------------------------------------------------------- // Function : GetVariableValue // // Description: // Will return the value associated with the variable name specified. // This information is fetched from the configuration data. // If the variable name can't be found in the configuration data, an empty // string is returned. // // Arguments: // aName: string [IN], The name of the variable. // aValue: string [OUT], The value associated with the variable name. // // Return values: (none) // // Exceptions: (none) // // -------------------------------------------------------------------------- void NameValueConfig::GetVariableValue( const string& aName, string& aValue ) const { t_nameValueData& nv = ((NameValueParser*)m_pParser)->GetConfigurationData(); t_nameValueData::const_iterator iter; // Clear the value string. aValue=""; // Find the requested variable. iter = nv.find(aName); if( iter != nv.end() ) aValue = iter->second; // retrieve the value. } // -------------------------------------------------------------------------- // Function : SetVariableValue // // Description: // Will set a value associated to the variable name specified. // This operation will change the in-memory configuration data. If the // variable name can't be found in the configuration data, a new variable // is created to hold the value. // NOTE: // To apply the change made, call the Config::ApplyConfiguration() function. // // Arguments: // aName: string [IN], The name of the variable. // aValue: string [IN], The value associated with the variable name. // // Return values: (none) // // Exceptions: (none) // // -------------------------------------------------------------------------- void NameValueConfig::SetVariableValue( const string& aName, const string& aValue ) { t_nameValueData& nv = ((NameValueParser*)m_pParser)->GetConfigurationData(); t_fullFileData& ffd = ((NameValueParser*)m_pParser)->GetFullFileData(); bool bFound = false; t_fullFileData::const_iterator iter; // Insert in full file data, if it wasn't already present. for( iter=ffd.begin(); iter!=ffd.end() && !bFound; iter++ ) bFound = iter->second == aName; if( !bFound ) ffd.push_back( pair(NVP_DATA_NV, aName) ); // Set the value for the name. nv[aName] = aValue; } // -------------------------------------------------------------------------- // Function : RemoveVariable // // Description: // Will remove the variable from the configuration data. This operation // will change the in-memory configuration data. // NOTE: // To apply the change made, call the Config::ApplyConfiguration() function. // // Arguments: // aName: string [IN], The name of the variable. // // Return values: (none) // // Exceptions: (none) // // -------------------------------------------------------------------------- void NameValueConfig::RemoveVariable( const string& aName ) { t_nameValueData& nv = ((NameValueParser*)m_pParser)->GetConfigurationData(); t_fullFileData& ffd = ((NameValueParser*)m_pParser)->GetFullFileData(); ffd.remove( pair(NVP_DATA_NV, aName) ); nv.erase( aName ); } // -------------------------------------------------------------------------- // Function : GetVariableNameList // // Description: // Will retrieve all the variable names from the configuration data. // // Arguments: // aList: list [OUT], Will contain a list of strings, containing // all variable names, from the configuration data. // // Return values: (none) // // Exceptions: (none) // // -------------------------------------------------------------------------- void NameValueConfig::GetVariableNameList( stringlist& aList ) const { t_nameValueData& nv = ((NameValueParser*)m_pParser)->GetConfigurationData(); t_nameValueData::const_iterator iter; // Empty the list first. aList.clear(); // Iterate on every variable name, and store it in the list. for( iter=nv.begin(); iter!=nv.end(); iter++) aList.push_back( iter->first ); } } gogoc-1_2-RELEASE/gogoc-config/src/namevalueparser.cc0100644000000000000000000002355311301542042021141 0ustar rootroot// ************************************************************************** // $Id: namevalueparser.cc,v 1.1 2009/11/20 16:30:26 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Implementation of the NameValueParser class // // Description: // Provides a means of parsing NAME=VALUE UNIX-style configuration files. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #include #include #include #include #include #include #define NV_SEPARATOR "=" // Name=value separator #define NV_COMMENT_START '#' // Comment line #define NV_MAX_LINE_LENGTH 2048 // Maximum line length #define NV_COMMENT_GENERATE "# Generated on: " // Special comment. // -------------------------------------------------------------------------- // Function : trim [LOCAL] // // Description: // Will remove leading and trailing whitespaces from the string. // // Arguments: // s: string [IN], The string to trim. (not modified) // // Return values: // The string `s' without the leading and trailing whitespaces // // Exceptions: (none) // // -------------------------------------------------------------------------- #ifndef NO_STDLIBCXX string trim( const string& s ) { if(s.length() == 0) return s; string::size_type b = s.find_first_not_of(" \t"); string::size_type e = s.find_last_not_of(" \t"); if(b == string::npos) // No non-spaces return ""; return string(s, b, e - b + 1); } #endif namespace gogocconfig { // -------------------------------------------------------------------------- // Function : NameValueParser constructor // // Description: // Will initialize a new NameValueParser object. // // Arguments: // aReadMode: enum [IN, facultative], Contains the read access mode. // // Return values: (N/A) // // Exceptions: (none) // // -------------------------------------------------------------------------- NameValueParser::NameValueParser( const t_eReadMode aReadMode ) : Parser(), m_eReadMode( aReadMode ) { m_NameValue.clear(); m_FullFileData.clear(); } // -------------------------------------------------------------------------- // Function : NameValueParser destructor // // Description: // Will perform clean-up tasks. // // Arguments: (N/A) // // Return values: (N/A) // // Exceptions: (none) // // -------------------------------------------------------------------------- NameValueParser::~NameValueParser( void ) { } // -------------------------------------------------------------------------- // Function : ReadConfigurationData // // Description: // Will read a configuration file, to extract the NAME=VALUE pairs. If read // mode is ALL(NVP_READ_ALL), the entire file will be read, including white // space lines and comments. // // Arguments: // aFilename: string [IN], Configuration data will be read from this file. // // Return values: // true upon successful read operation, false otherwise. // // Exceptions: // - When failed to open the filename provided. // - When a line (that is not a comment nor whitespaces) does not contain // the `=' character. // // -------------------------------------------------------------------------- bool NameValueParser::ReadConfigurationData( const string& aFilename ) { std::ifstream inStream; char buf[NV_MAX_LINE_LENGTH]; char *buffer = buf; char *name, *value; // Initialization. memset(&buf, 0, NV_MAX_LINE_LENGTH); // Open specified file. inStream.open( aFilename.c_str(), std::ios::in ); if( !inStream.is_open() ) { // Open failed. throw GOGOC_UIS__NMP_OPENFAIL; } // Clear the current configuration data, if any. m_NameValue.clear(); m_FullFileData.clear(); // Loop on the entire file until end. while( !inStream.eof() ) { inStream.getline( buffer, NV_MAX_LINE_LENGTH ); // Move to the first non-space character while( *buffer == ' ' ) ++buffer; // Verify if whitespace. if( *buffer == '\0' ) { AddEmptyLine(); continue; } // Verify if comment. if( *buffer == NV_COMMENT_START ) { AddComment( buffer ); continue; } // Extract Name=Value pair if( (name = strtok(buffer, NV_SEPARATOR)) != NULL ) { // Extract value (may be null). value = strtok(NULL, ""); // Get remainder of string. // Store the name value pair. AddNameValue( name, (value == NULL) ? "" : value ); } else { // Line did not contain a "=" separator throw GOGOC_UIS__NMP_BADCONFIGFILE; } } // Close opened handle. inStream.close(); return true; } // -------------------------------------------------------------------------- // Function : WriteConfigurationData // // Description: // Will write the internal configuration to the specified file. If read // mode is ALL(NVP_READ_ALL), the entire file will be overwritten with the // contents of the NAME=VALUE pairs, including comments and white space // lines. // // Arguments: // aFilename: string [IN], Configuration data will be written to this file. // // Return values: // true upon successful write operation, false otherwise. // // Exceptions: // - When failed to open file for read access. // // -------------------------------------------------------------------------- bool NameValueParser::WriteConfigurationData( const string& aFilename ) { std::ofstream outStream; time_t rawtime; struct tm * timeinfo; outStream.open( aFilename.c_str() ); if( !outStream.is_open() ) { // Open failed. throw GOGOC_UIS__NMP_OPENFAILWRITE; } // --------------------------------------------------------- // Format current time for timestamp in configuration file. // --------------------------------------------------------- pal_time( &rawtime ); timeinfo = pal_localtime( &rawtime ); // ------------------------------ // Write the configuration data. // ------------------------------ if( m_eReadMode == NVP_READ_ALL ) { t_fullFileData::iterator iter; t_nameValueData::iterator iterMap; for( iter = m_FullFileData.begin(); iter != m_FullFileData.end(); iter++ ) { // Verify what kind of data: switch( iter->first ) { case NVP_DATA_NV: iterMap = m_NameValue.find( iter->second ); if( iterMap != m_NameValue.end() ) outStream << iter->second << NV_SEPARATOR << iterMap->second << endl; break; case NVP_DATA_COMMENT: if( strncmp( iter->second.c_str(), NV_COMMENT_GENERATE, strlen(NV_COMMENT_GENERATE) ) == 0 ) { outStream << NV_COMMENT_GENERATE << (timeinfo->tm_year+1900) << "/" << (timeinfo->tm_mon+1) << "/" << timeinfo->tm_mday << " " << timeinfo->tm_hour << ":" << timeinfo->tm_min << ":" << timeinfo->tm_sec << endl; } else outStream << iter->second << endl; break; case NVP_DATA_EMPTYLINE: outStream << endl; break; } } } else { t_nameValueData::iterator iter; for(iter = m_NameValue.begin(); iter != m_NameValue.end(); iter++ ) outStream << iter->first << NV_SEPARATOR << iter->second << endl << endl; } // Close opened handle. outStream.close(); return true; } // -------------------------------------------------------------------------- // Function : AddEmptyLine [PROTECTED] // // Description: // Will add an empty line to the configuration file data, only if read mode // is ALL(NVP_READ_ALL). // // Arguments: (none) // // Return values: (none) // // Exceptions: (none) // // -------------------------------------------------------------------------- void NameValueParser::AddEmptyLine( void ) { if( m_eReadMode == NVP_READ_ALL ) m_FullFileData.push_back( pair(NVP_DATA_EMPTYLINE, "") ); } // -------------------------------------------------------------------------- // Function : AddComment [PROTECTED] // // Description: // Will add a comment line to the configuration file data, only if read mode // is ALL(NVP_READ_ALL). // // Arguments: // aComment: string [in], A comment extracted from the configuration file. // // Return values: (none) // // Exceptions: (none) // // -------------------------------------------------------------------------- void NameValueParser::AddComment( const string& aComment ) { assert( aComment.size() != 0 ); if( m_eReadMode == NVP_READ_ALL ) m_FullFileData.push_back( pair(NVP_DATA_COMMENT, aComment) ); } // -------------------------------------------------------------------------- // Function : AddNameValue [PROTECTED] // // Description: // Will add the NAME=VALUE pair in the configuration data. // // Arguments: // aName: string [in], The name // aValue: string [in], the value // // Return values: (none) // // Exceptions: (none) // // -------------------------------------------------------------------------- void NameValueParser::AddNameValue( const string& aName, const string& aValue ) { assert( aName.size() != 0 ); // Remove trailing and leading whitespaces #ifndef NO_STDLIBCXX string name = trim( aName ); string value = trim( aValue ); #else string name = aName; string value = aValue; #endif // The case someone would mischievously put a line like that in the config // file: "=". if( !name.empty() ) { if( m_eReadMode == NVP_READ_ALL ) m_FullFileData.push_back( pair(NVP_DATA_NV, name) ); m_NameValue[name] = value; } } } gogoc-1_2-RELEASE/gogoc-messaging/0040755000000000000000000000000011346561546015377 5ustar rootrootgogoc-1_2-RELEASE/gogoc-messaging/gogocmessaging/0040755000000000000000000000000011346561542020367 5ustar rootrootgogoc-1_2-RELEASE/gogoc-messaging/gogocmessaging/clientmessengerimpl.h0100644000000000000000000000373411301542453024604 0ustar rootroot// ************************************************************************** // $Id: clientmessengerimpl.h,v 1.1 2009/11/20 16:34:51 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // This is the gogoCLIENT implementation of the messenger subsystem. // The naming of the derived class as `server' indicate that the gogoCLIENT // only means that it is the server-side of the messaging subsystem. // (The GUI is the client-side of the messaging subsystem.) // // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocmessaging_clientmessengerimpl_h__ #define __gogocmessaging_clientmessengerimpl_h__ #include #include #include #undef PostMessage namespace gogocmessaging { // ------------------------------------------------------------------------ class ClientMessengerImpl : public ServerMsgSender, public ServerMsgTranslator { private: CommunicationsManager m_CommManager; public: ClientMessengerImpl ( void ); virtual ~ClientMessengerImpl ( void ); // Waits until communication manager is ready. bool WaitReady ( unsigned long ulWaitms=750 ); // Overrides from the ServerMsgTranslator: error_t Recv_StatusInfoRequest( void ); error_t Recv_TunnelInfoRequest( void ); error_t Recv_BrokerListRequest( void ); error_t Recv_HACCESSConfigInfo ( const HACCESSConfigInfo* aHACCESSConfigInfo ); error_t Recv_HACCESSStatusInfoRequest( void ); // Overrides from the ServerMsgSender: void PostMessage ( Message* pMsg ); }; } #endif gogoc-1_2-RELEASE/gogoc-messaging/gogocmessaging/clientmsgdataretriever.h0100644000000000000000000000321311301542453025272 0ustar rootroot// ************************************************************************** // $Id: clientmsgdataretriever.h,v 1.1 2009/11/20 16:34:51 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Defines prototypes used by the messenger to retrieve information on // - status, tunnel and brokers. // Defines a way of freeing the information allocated in the retrievers. // // These functions need to be implemented in the gogoCLIENT. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocmessaging_clientsgdataretriever_h__ #define __gogocmessaging_clientsgdataretriever_h__ #include #include #include // error_t definition & codes. #ifdef __cplusplus extern "C" { #endif error_t RetrieveStatusInfo ( gogocStatusInfo** ppStatusInfo ); error_t RetrieveTunnelInfo ( gogocTunnelInfo** ppTunnelInfo ); error_t RetrieveBrokerList ( gogocBrokerList** ppBrokerList ); error_t RetrieveHACCESSStatusInfo( HACCESSStatusInfo** ppHACCESSStatusInfo ); void FreeStatusInfo ( gogocStatusInfo** ppStatusInfo ); void FreeTunnelInfo ( gogocTunnelInfo** ppTunnelInfo ); void FreeBrokerList ( gogocBrokerList** ppBrokerList ); void FreeHACCESSStatusInfo ( HACCESSStatusInfo** ppHACCESSStatusInfo ); #ifdef __cplusplus } #endif #endif gogoc-1_2-RELEASE/gogoc-messaging/gogocmessaging/clientmsgnotifier.h0100644000000000000000000000207211301542453024252 0ustar rootroot// ************************************************************************** // $Id: clientmsgnotifier.h,v 1.1 2009/11/20 16:34:51 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Defines prototypes used by the messenger to notify the gogoCLIENT // that a message has arrived and requires processing. // // These functions need to be implemented in the gogoCLIENT. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocmessaging_clientmsgnotifier_h__ #define __gogocmessaging_clientmsgnotifier_h__ #include #include // error_t definition & codes. #ifdef __cplusplus extern "C" { #endif error_t NotifyhaccessConfigInfo ( const HACCESSConfigInfo* aHACCESSConfigInfo ); #ifdef __cplusplus } #endif #endif gogoc-1_2-RELEASE/gogoc-messaging/gogocmessaging/clientmsgsender.h0100644000000000000000000000275111301542453023717 0ustar rootroot// ************************************************************************** // $Id: clientmsgsender.h,v 1.1 2009/11/20 16:34:51 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Defines the different messages the gogoCLIENT GUI can send. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocmessaging_clientmsgsender_h__ #define __gogocmessaging_clientmsgsender_h__ #include #include #include #undef PostMessage namespace gogocmessaging { // ------------------------------------------------------------------------ class ClientMsgSender { protected: // Construction / destruction. ClientMsgSender ( void ); public: virtual ~ClientMsgSender ( void ); public: void Send_StatusInfoRequest( void ); void Send_TunnelInfoRequest( void ); void Send_BrokerListRequest( void ); void Send_HACCESSConfigInfo ( const HACCESSConfigInfo* aHACCESSCfgInfo ); void Send_HACCESSStatusInfoRequest( void ); protected: virtual void PostMessage ( Message* pMsg )=0; }; } #endif gogoc-1_2-RELEASE/gogoc-messaging/gogocmessaging/clientmsgtranslator.h0100644000000000000000000000413111301542454024623 0ustar rootroot// ************************************************************************** // $Id: clientmsgtranslator.h,v 1.1 2009/11/20 16:34:52 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Defines the message processing of gogoCLIENT messages destined // for the GUI (which is the client-side). // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocmessaging_clientmsgtranslator_h__ #define __gogocmessaging_clientmsgtranslator_h__ #include #include #include #include namespace gogocmessaging { // ------------------------------------------------------------------------ class ClientMsgTranslator: public MessageProcessor { protected: // Construction / destruction. ClientMsgTranslator ( void ); public: virtual ~ClientMsgTranslator ( void ); protected: // Override from MessageProcessor. error_t ProcessMessage ( Message* pMsg ); // To be implemented by derived classes. virtual error_t Recv_StatusInfo ( const gogocStatusInfo* aStatusInfo )=0; virtual error_t Recv_TunnelInfo ( const gogocTunnelInfo* aTunnelInfo )=0; virtual error_t Recv_BrokerList ( const gogocBrokerList* aBrokerList )=0; virtual error_t Recv_HACCESSStatusInfo ( const HACCESSStatusInfo* aHACCESSStatusInfo )=0; private: // Message data translators. error_t TranslateStatusInfo ( uint8_t* pData, const uint16_t nDataLen ); error_t TranslateTunnelInfo ( uint8_t* pData, const uint16_t nDataLen ); error_t TranslateBrokerList ( uint8_t* pData, const uint16_t nDataLen ); error_t TranslateHACCESSStatusInfo( uint8_t* pData, const uint16_t nDataLen ); }; } #endif gogoc-1_2-RELEASE/gogoc-messaging/gogocmessaging/communicationsmgr.h0100644000000000000000000001130011301542454024256 0ustar rootroot// ************************************************************************** // $Id: communicationsmgr.h,v 1.1 2009/11/20 16:34:52 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Definition the the Communications manager. // This is the main coordinator. The applications will instantiate one // object of this type and register a message processor. Incoming data will // be monitored in a different thread. When incoming data is received from // the IPC communications layer, the communications manager will // deserialize it into a message and dispatch it using the MessageProcessor. // The communications manager will also (in a separate thread) extract // messages from the MessageSender's queue, serialize them and send them // to the IPC communications layer. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocmessaging_communicationsmgr_h__ #define __gogocmessaging_communicationsmgr_h__ #include #include #include #include #include namespace gogocmessaging { // Type definitions. typedef enum { CLIENT_MANAGER, SERVER_MANAGER } tManagerMode; typedef enum { STATE_DISCONNECTED, STATE_PENDINGCONNECTION, STATE_CONNECTED, STATE_FATALERROR } tManagerStatus; class CommunicationsManager; // ------------------------------------------------------------------------ class SenderThread : public ThreadWrapper { private: CommunicationsManager* m_CommMgr; public: // Construction / destruction. SenderThread ( CommunicationsManager* aCommMgr ) : ThreadWrapper(), m_CommMgr(aCommMgr) {}; virtual ~SenderThread ( void ) {}; protected: // Work method. void Work ( void ); }; // ------------------------------------------------------------------------ class ReceiverThread : public ThreadWrapper { private: CommunicationsManager* m_CommMgr; public: // Construction / destruction. ReceiverThread ( CommunicationsManager* aCommMgr ) : ThreadWrapper(), m_CommMgr(aCommMgr) {}; virtual ~ReceiverThread ( void ) {}; protected: // Work method. void Work ( void ); }; // ------------------------------------------------------------------------ class CommunicationsManager : public MessageSender, public ThreadWrapper { public: // Type definitions: struct MANAGER_STATISTICS // Information available. { unsigned int nMsgQueued; unsigned int nMsgSent; unsigned int nMsgProcessed; SERVENT_INFO ServentInfo; }; private: IPCServent* m_IPCServent; // For IPC operations. Servent m_Servent; // For message sending / reception. MessageProcessor* m_MsgProcessor; // For message processing. ReceiverThread* m_ReceiverThread; // Monitors servent for incoming messages. SenderThread* m_SenderThread; // Monitors send queue and sends messages. tManagerMode m_eManagerMode; // Is this instance a Server or client? tManagerStatus m_eManagerStatus; // The current state of the manager. unsigned int m_nMsgSent; // The number of messages sent until now. unsigned int m_nMsgProcessed; // The number of messages received until now. public: // Construction / destruction. CommunicationsManager ( tManagerMode aEMode, MessageProcessor* aProcessor ); virtual ~CommunicationsManager( void ); void GetStatistics ( MANAGER_STATISTICS* aStats ); bool WaitReady ( unsigned long ulWaitms=750 ); // Communications manager status accessors. tManagerStatus GetState ( void ) const; private: void SetState ( const tManagerStatus aState ); // Worker thread function. Monitors service availability. void Work ( void ); // Instance initialization. error_t Initialize ( void ); // Cleans up this instance void _CleanupInstance ( void ); // Friends and family. friend class SenderThread; friend class ReceiverThread; }; } #endif gogoc-1_2-RELEASE/gogoc-messaging/gogocmessaging/debugdefs.h0100644000000000000000000000221311301542454022453 0ustar rootroot// ************************************************************************** // $Id: debugdefs.h,v 1.1 2009/11/20 16:34:52 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Includes required header files to perform debug assertions and // defines compiltation conditionnal macros for debugging. // // This header should only be included in module bodies(*.cc), not in // the interface(*.h). // // * Make sure precompilation symbol NDEBUG is defined when compiling a // release version. // // Author: Charles Nepveu // // Creation Date: December 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocmessaging_debugdefs_h__ #define __gogocmessaging_debugdefs_h__ // The assert header should be included even when compiling with NDEBUG #include #ifndef NDEBUG #include #include using namespace std; #define DBG_PRINT(X) cout << X << endl; #else #define DBG_PRINT(X) #endif #endif gogoc-1_2-RELEASE/gogoc-messaging/gogocmessaging/gogoc_c_wrapper.h0100644000000000000000000000324611301542454023672 0ustar rootroot// ************************************************************************** // $Id: gogoc_c_wrapper.h,v 1.1 2009/11/20 16:34:52 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Provides C access to the gogoCLIENT messenger subsystem. // The C functionnality here is limited to the gogoCLIENT (not the // GUI). // // Author: Charles Nepveu // // Creation Date: December 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocmessaging_gogoc_c_wrapper_h__ #define __gogocmessaging_gogoc_c_wrapper_h__ #include // error_t definition & codes. #include // messaging data. #include // HACCESS messaging data. #ifdef __cplusplus extern "C" { #endif // Initialization of the underlying C++ object. error_t initialize_messaging ( void ); error_t uninitialize_messaging( void ); // Send functions. They don't take arguments because they'll be using // the clientmsgdataretriever functions (See clientmsgdataretriever.h). error_t send_status_info ( void ); error_t send_tunnel_info ( void ); error_t send_broker_list ( void ); error_t send_haccess_status_info ( void ); // Will be declared in: tsp_client.c extern gogocStatusInfo gStatusInfo; extern gogocTunnelInfo gTunnelInfo; extern HACCESSStatusInfo gHACCESSStatusInfo; #ifdef __cplusplus } #endif #endif gogoc-1_2-RELEASE/gogoc-messaging/gogocmessaging/gogocmsgdata.h0100644000000000000000000000764311344752264023207 0ustar rootroot// ************************************************************************** // $Id: gogocmsgdata.h,v 1.2 2010/03/07 16:30:44 carl Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // This include file describes the domain values and data that will be // exchanged between the gogoCLIENT GUI and gogoCLIENT. // // These structures must be defined in C-style for integration // in the gogoCLIENT. // // You may extend the structures to include new data, - BUT - // Remember to do the following: // - Translate the new data. // - Encode then new data. // - *THINK* of backwards compatibility (Maybe crate a new message ID // for the extended structure and preserve functionnality). // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocmessaging_gogocmsgdata_h__ #define __gogocmessaging_gogocmsgdata_h__ #include // gogoCLIENT status information: gogocCliStatus - (Enumeration) // - DISCONNECTEDIDLE: Client is disconnected (idle: No connection attempt) // - DISCONNECTEDERROR: Client is disconnected because of an error. // - DISCONNECTEDNORETRY: Client was connected and will NOT retry. // - DISCONNECTEDHACCESSSETUPERROR: Client was disconnected because of an HACCESS setup error. // - DISCONNECTEDHACCESSEXPOSEDEVICESERROR: Client was disconnected because of an HACCESS device mapping error. // - CONNECTING: Client is negotiating tunnel and setting up. // - CONNECTED: Client is successfully connected. // typedef enum { GOGOC_CLISTAT__DISCONNECTEDIDLE, GOGOC_CLISTAT__DISCONNECTEDNORETRY, GOGOC_CLISTAT__DISCONNECTEDERROR, GOGOC_CLISTAT__DISCONNECTEDHACCESSSETUPERROR, GOGOC_CLISTAT__DISCONNECTEDHACCESSEXPOSEDEVICESERROR, GOGOC_CLISTAT__CONNECTING, GOGOC_CLISTAT__CONNECTED } gogocCliStatus; // gogoCLIENT tunnel types: gogocTunnelType - (Enumeration) // (See application manual if you don't understand these values). typedef enum { TUNTYPE_V6V4, TUNTYPE_V6UDPV4, TUNTYPE_V4V6 } gogocTunnelType; // gogoCLIENT status information: gogocStatusInfo - (Data structure) // - eStatus: The status, as described earlier. // - szStatus: Additionnal information on the status (error, mostly). // typedef struct __STATUS_INFO { gogocCliStatus eStatus; signed int nStatus; } gogocStatusInfo; // gogoCLIENT tunnel information: gogocTunnelInfo - (Data structure) // - szBrokerName: The name of the broker used for tunnel negotiation. // - eTunnelType: Type of tunnel. // - szIPV4AddrLocalEndpoint: Local tunnel endpoint IPv4 address. // - szIPV6AddrLocalEndpoint: Local tunnel endpoint IPv6 address. // - szIPV6AddrDns: DNS IPv6 address. // - szIPV4AddrRemoteEndpoint: Remote tunnel endpoint IPv4 address. // - szIPV6AddrRemoteEndpoint: Remote tunnel endpoint IPv6 address. // - szDelegatedPrefix: The delegated prefix (if routing is enabled). // - szUserDomain: The domain delegated to the used for his prefix. // - tunnelUpTime: c-time at which the tunnel was 'up'. NOT THE UPTIME. // typedef struct __TUNNEL_INFO { char* szBrokerName; gogocTunnelType eTunnelType; char* szIPV4AddrLocalEndpoint; char* szIPV6AddrLocalEndpoint; char* szIPV6AddrDns; char* szIPV4AddrRemoteEndpoint; char* szIPV6AddrRemoteEndpoint; char* szDelegatedPrefix; char* szUserDomain; time_t tunnelUpTime; } gogocTunnelInfo; // gogoCLIENT broker list: gogocBrokerList - (Data structure) // - szBrokerName: Name of the broker. // - next: Next element in the list: NULL if end. // struct __BROKER_LIST; typedef struct __BROKER_LIST { char* szAddress; int nDistance; struct __BROKER_LIST* next; } gogocBrokerList; #endif gogoc-1_2-RELEASE/gogoc-messaging/gogocmessaging/gogocuistrings.h0100644000000000000000000001222511301542454023575 0ustar rootroot/* *********************************************************************** */ /* $Id: gogocuistrings.h,v 1.1 2009/11/20 16:34:52 jasminko Exp $ */ /* */ /* Copyright (c) 2007 gogo6 Inc. All rights reserved. */ /* */ /* For license information refer to CLIENT-LICENSE.TXT */ /* */ /* Description: */ /* Contains the user interface(UI) strings of the Gateway6 Configuration */ /* subsystem. */ /* */ /* Author: Charles Nepveu */ /* */ /* Creation Date: November 2006 */ /* _______________________________________________________________________ */ /* *********************************************************************** */ #ifndef __gogocmessaging_gogocuistrings_h__ #define __gogocmessaging_gogocuistrings_h__ #ifndef ERRORT_DEFINED #define ERRORT_DEFINED typedef signed int error_t; #endif /* ----------------------------------------------------------------------- */ /* gogoCLIENT User Interface string ID definitions. */ /* ----------------------------------------------------------------------- */ #define GOGOCM_UIS__NOERROR (error_t)0x00000000 #define GOGOCM_UIS_WRITEPIPEFAILED (error_t)0x00000001 #define GOGOCM_UIS_PEEKPIPEFAILED (error_t)0x00000002 #define GOGOCM_UIS_READPIPEFAILED (error_t)0x00000003 #define GOGOCM_UIS_PIPESERVERALRDUP (error_t)0x00000004 #define GOGOCM_UIS_FAILCREATESERVERPIPE (error_t)0x00000005 #define GOGOCM_UIS_CLIENTALRDYCONN (error_t)0x00000006 #define GOGOCM_UIS_CLIENTCONNFAILED (error_t)0x00000007 #define GOGOCM_UIS_PIPESVRDISCFAIL (error_t)0x00000008 #define GOGOCM_UIS_FAILCREATECLIENTPIPE (error_t)0x00000009 #define GOGOCM_UIS_PIPECLIDISCFAIL (error_t)0x0000000A #define GOGOCM_UIS_BADPACKET (error_t)0x0000000B #define GOGOCM_UIS_IPCDESYNCHRONIZED (error_t)0x0000000C #define GOGOCM_UIS_PACKETSNOTORDERED (error_t)0x0000000D #define GOGOCM_UIS_READBUFFERTOOSMALL (error_t)0x0000000E #define GOGOCM_UIS_SENDBUFFERTOOBIG (error_t)0x0000000F #define GOGOCM_UIS_IOWAITTIMEOUT (error_t)0x00000010 #define GOGOCM_UIS_MSGPROCDISABLED (error_t)0x00000011 #define GOGOCM_UIS_MESSAGENOTIMPL (error_t)0x00000012 #define GOGOCM_UIS_CWRAPALRDYINIT (error_t)0x00000013 #define GOGOCM_UIS_CWRAPNOTINIT (error_t)0x00000014 // gogoCLIENT errors #define GOGOCM_UIS_ERRUNKNOWN (error_t)0x00000015 #define GOGOCM_UIS_FAILEDBROKERLISTEXTRACTION (error_t)0x00000016 #define GOGOCM_UIS_ERRCFGDATA (error_t)0x00000017 #define GOGOCM_UIS_ERRMEMORYSTARVATION (error_t)0x00000018 #define GOGOCM_UIS_ERRSOCKETIO (error_t)0x00000019 #define GOGOCM_UIS_ERRFAILSOCKETCONNECT (error_t)0x0000001A #define GOGOCM_UIS_EVNTBROKERREDIRECTION (error_t)0x0000001B #define GOGOCM_UIS_ERRBROKERREDIRECTION (error_t)0x0000001C #define GOGOCM_UIS_ERRTSPVERSIONERROR (error_t)0x0000001D #define GOGOCM_UIS_ERRTSPGENERICERROR (error_t)0x0000001E #define GOGOCM_UIS_ERRTUNMODENOTAVAILABLE (error_t)0x0000001F #define GOGOCM_UIS_ERRNOCOMMONAUTHENTICATION (error_t)0x00000020 #define GOGOCM_UIS_ERRAUTHENTICATIONFAILURE (error_t)0x00000021 #define GOGOCM_UIS_ERRBADTUNNELPARAM (error_t)0x00000022 #define GOGOCM_UIS_ERRINTERFACESETUPFAILED (error_t)0x00000023 #define GOGOCM_UIS_ERRKEEPALIVETIMEOUT (error_t)0x00000024 #define GOGOCM_UIS_ERRKEEPALIVEERROR (error_t)0x00000025 #define GOGOCM_UIS_ERRTUNNELIO (error_t)0x00000026 #define GOGOCM_UIS_ERRTUNLEASEEXPIRED (error_t)0x00000027 #define GOGOCM_UIS_ERRHACCESSSETUP (error_t)0x00000028 #define GOGOCM_UIS_ERRHACCESSEXPOSEDEVICES (error_t)0x00000029 #define GOGOCM_UIS_ERRTSPSERVERTOOBUSY (error_t)0x0000002A #define GOGOCM_UIS_ERRINVALSERVERADDR (error_t)0x0000002B /* ----------------------------------------------------------------------- */ /* Get string function. */ /* ----------------------------------------------------------------------- */ #ifdef __cplusplus extern "C" const char* get_mui_string( const error_t id ); #else const char* get_mui_string( const error_t id ); #endif #endif gogoc-1_2-RELEASE/gogoc-messaging/gogocmessaging/guimessengerimpl.h0100644000000000000000000000505311301542454024107 0ustar rootroot// ************************************************************************** // $Id: guimessengerimpl.h,v 1.1 2009/11/20 16:34:52 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // This is the gogoCLIENT GUI implementation of the messenger // subsystem. The naming of the derived class as `client' indicate that // the gogoCLIENT GUI is the client-side of the messaging subsystem. // (The GOGOC service is the server-side of the messaging subsystem.) // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocmessaging_guimessengerimpl_h__ #define __gogocmessaging_guimessengerimpl_h__ #include #include #include #undef PostMessage // Because of stupid windows API PostMessage method namespace gogocmessaging { // ------------------------------------------------------------------------ class GUIMessengerImpl : public ClientMsgSender, public ClientMsgTranslator { public: typedef void (*RecvStatusInfo) ( const gogocStatusInfo* ); typedef void (*RecvTunnelInfo) ( const gogocTunnelInfo* ); typedef void (*RecvBrokerList) ( const gogocBrokerList* ); typedef void (*RecvHACCESSStatusInfo) ( const HACCESSStatusInfo* ); public: // Handling functions. RecvStatusInfo m_RecvStatusInfo; RecvTunnelInfo m_RecvTunnelInfo; RecvBrokerList m_RecvBrokerList; RecvHACCESSStatusInfo m_RecvHACCESSStatusInfo; private: CommunicationsManager m_CommManager; public: GUIMessengerImpl ( void ); virtual ~GUIMessengerImpl ( void ); // Message processing functions. void EnableProcessing ( void ); void DisableProcessing ( void ); // Overrides from the ClientMsgTranslator: error_t Recv_StatusInfo ( const gogocStatusInfo* aStatusInfo ); error_t Recv_TunnelInfo ( const gogocTunnelInfo* aTunnelInfo ); error_t Recv_BrokerList ( const gogocBrokerList* aBrokerList ); error_t Recv_HACCESSStatusInfo ( const HACCESSStatusInfo* aHACCESSStatusInfo ); // Overrides from the ClientMsgSender: void PostMessage ( Message* pMsg ); }; } #endif gogoc-1_2-RELEASE/gogoc-messaging/gogocmessaging/haccessmsgdata.h0100644000000000000000000000755111301542454023507 0ustar rootroot// ************************************************************************** // $Id: haccessmsgdata.h,v 1.1 2009/11/20 16:34:52 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // This include file describes the domain values and data that will be // exchanged between the gogoCLIENT GUI and gogoCLIENT // in the scope of the HACCESS project. // // These structures must be defined in C-style for integration // in the gogoCLIENT. // // You may extend the structures to include new data, - BUT - // Remember to do the following: // - Translate the new data. // - Encode then new data. // - *THINK* of backwards compatibility (Maybe crate a new message ID // for the extended structure and preserve functionnality). // // Author: Charles Nepveu // // Creation Date: February 2007 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocmessaging_haccessmsgdata_h__ #define __gogocmessaging_haccessmsgdata_h__ // HACCESS Configuration Information: HACCESSConfigInfo - (Data Structure) // - haccess_doc_root: WWW document root. // - haccess_proxy_enabled: Boolean value indicating if the proxy part of // HACCESS is enabled. // - haccess_web_enabled: Boolean value indicating if the web part of // HACCESS is enabled. // - haccess_devmap_changed: Boolean value indicating whether the HACCESS device // mappings have been changed. // typedef struct __HACCESS_CONFIG_INFO { char* haccess_doc_root; signed short haccess_proxy_enabled; signed short haccess_web_enabled; signed short haccess_devmap_changed; } HACCESSConfigInfo; // HACCESS Device Mapping Statuses: HACCESSDevMapStts - (Enumeration) // - SUCCESS: Device mapping was successfully pushed to the DDNS server. // - ERROR: Device mapping failed to be pushed to the DDNS server. // - NEW: (GUI ONLY) New device mapping entered by the user. // - MODIFIED: (GUI ONLY) New or existing device mapping modified by user. // - UNKNOWN: (GUI ONLY) Device mapping default status. // See "Appendix A" in HACCESS client integration design document. // typedef enum { HACCESS_DEVMAPSTTS_SUCCESS, HACCESS_DEVMAPSTTS_ERROR, HACCESS_DEVMAPSTTS_NEW, HACCESS_DEVMAPSTTS_MODIFIED, HACCESS_DEVMAPSTTS_UNKNOWN } HACCESSDevMapStts; // gogoCLIENT broker list: gogocBrokerList - (Data structure) // - device_name: Name of the device. // - mapping_status: Status for the device mapping. // - next: Next element in the list: NULL if end. // struct __MAPPING_STATUS; typedef struct __MAPPING_STATUS { char* device_name; HACCESSDevMapStts mapping_status; struct __MAPPING_STATUS* next; } MAPPING_STATUS, *PMAPPING_STATUS; // HACCESS Feature Statuses: HACCESSFeatStts - (Enumeration) // - SUCCESS: HACCESS Feature has started and is functionning correctly. // - ERROR: HACCESS feature is unavailable; an error occured. // See "Appendix A" in HACCESS client integration design document. // typedef enum { HACCESS_FEATSTTS_SUCCESS, HACCESS_FEATSTTS_ERROR } HACCESSFeatStts; // HACCESS Status Information: HACCESSStatusInfo - (Data Structure) // - haccess_proxy_status: Status of the HACCESS proxy. // - haccess_web_status: Status of the HACCESS web server. // - haccess_devmapmod_status: Status of the Device Mapping Module. // - haccess_devmap_status: Linked list of mapping statuses. // typedef struct __HACCESS_STATUS_INFO { HACCESSFeatStts haccess_proxy_status; HACCESSFeatStts haccess_web_status; HACCESSFeatStts haccess_devmapmod_status; PMAPPING_STATUS haccess_devmap_statuses; } HACCESSStatusInfo; #endif gogoc-1_2-RELEASE/gogoc-messaging/gogocmessaging/ipcclient.h0100644000000000000000000000253611301542455022506 0ustar rootroot// ************************************************************************** // $Id: ipcclient.h,v 1.1 2009/11/20 16:34:53 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Defines a generic IPC Client. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocmessaging_ipcclient_h__ #define __gogocmessaging_ipcclient_h__ #include namespace gogocmessaging { // ------------------------------------------------------------------------ class IPCClient : virtual public IPCServent { protected: // Construction / destruction IPCClient ( void ); public: virtual ~IPCClient ( void ); // IPC Servent overrides. virtual error_t Initialize ( void ); // Blocking virtual error_t UnInitialize ( void ); // Blocking virtual bool WaitReady ( unsigned long ulWaitms ); // IPC Client operations. virtual error_t Connect ( void ) = 0; // Blocking virtual error_t Disconnect ( void ) = 0; }; } #endif gogoc-1_2-RELEASE/gogoc-messaging/gogocmessaging/ipcservent.h0100644000000000000000000000444511301542455022717 0ustar rootroot// ************************************************************************** // $Id: ipcservent.h,v 1.1 2009/11/20 16:34:53 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Defines a generic IPC servent. A servent may be a Server or Client. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocmessaging_ipcservent_h__ #define __gogocmessaging_ipcservent_h__ #include #include #include typedef ptr_t* IPC_HANDLE; #define INVALID_IPC_HANDLE ((IPC_HANDLE)-1) namespace gogocmessaging { // ------------------------------------------------------------------------ class IPCServent { protected: IPC_HANDLE m_Handle; // IPC Handle for Connection & IO operations. Semaphore* m_pSemReadyState; // Semaphore released when ready state is reached. protected: // Construction / destruction IPCServent ( void ) : m_Handle(INVALID_IPC_HANDLE), m_pSemReadyState(0) {}; public: virtual ~IPCServent ( void ) { }; // Connection operations. virtual error_t Initialize ( void )=0; // Blocking virtual error_t UnInitialize ( void )=0; // Blocking virtual bool WaitReady ( unsigned long ulWaitms )=0; // IO operations virtual error_t CanRead ( bool& bCanRead ) const = 0; // Non-Blocking virtual error_t CanWrite ( bool& bCanWrite ) const = 0; // Non-Blocking virtual error_t Read ( void* pvReadBuffer, const uint32_t nBufferSize, uint32_t& nRead )=0; // Blocking virtual error_t Write ( const void* pvData, const uint32_t nDataSize, uint32_t& nWritten )=0; // Blocking }; } #endif gogoc-1_2-RELEASE/gogoc-messaging/gogocmessaging/ipcserver.h0100644000000000000000000000267211301542455022537 0ustar rootroot// ************************************************************************** // $Id: ipcserver.h,v 1.1 2009/11/20 16:34:53 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Defines a generic IPC Server. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocmessaging_ipcserver_h__ #define __gogocmessaging_ipcserver_h__ #include namespace gogocmessaging { // ------------------------------------------------------------------------ class IPCServer : virtual public IPCServent { protected: // Construction / destruction IPCServer ( void ); public: virtual ~IPCServer ( void ); // IPC Servent overrides. virtual error_t Initialize ( void ); // Blocking virtual error_t UnInitialize ( void ); // Blocking virtual bool WaitReady ( unsigned long ulWaitms ); // IPC Server operations. virtual error_t CreateConnectionPoint ( void ) = 0; // Non-Blocking virtual error_t AcceptConnection ( void ) = 0; // Blocking virtual error_t CloseConnection ( void ) = 0; // Non-Blocking }; } #endif gogoc-1_2-RELEASE/gogoc-messaging/gogocmessaging/message.h0100644000000000000000000000532211301542455022154 0ustar rootroot// ************************************************************************** // $Id: message.h,v 1.1 2009/11/20 16:34:53 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Defines a gogoCLIENT message for IPC communication. // // Important notice: // ALWAYS USE `CreateMessage' AND `FreeMessage' FUNCTIONS FOR // CONSTRUCTION AND DESTRUCTION. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocmessaging_message_h__ #define __gogocmessaging_message_h__ #include // Undefine Windows Win32 API PostMessage #undef PostMessage // Useful macros #define MSG_HEADER_LEN offsetof(gogocmessaging::Message::__MSG_CONTENTS, _data) #define MSG_MAX_USERDATA (64260 - (MSG_HEADER_LEN)) // Message IDs definition. // Sent from gogoCLIENT GUI - received by gogoCLIENT #define MESSAGEID_REQUEST_STATUSINFO 0x0001 // Request for status info #define MESSAGEID_REQUEST_TUNNELINFO 0x0002 // Request for tunnel info #define MESSAGEID_REQUEST_BROKERLIST 0x0003 // Request for broker list #define MESSAGEID_HACCESSCONFIGINFO 0x0004 // Send HACCESS config info #define MESSAGEID_REQUEST_HACCESSSTATUSINFO 0x0005 // Request for HACCESS status info // Sent from gogoCLIENT - received by gogoCLIENT GUI #define MESSAGEID_STATUSINFO 0x0101 // Status info message #define MESSAGEID_TUNNELINFO 0x0102 // Tunnel info message #define MESSAGEID_BROKERLIST 0x0103 // Broker list message #define MESSAGEID_HACCESSSTATUSINFO 0x0104 // Send HACCESS status info #if defined(WIN32) || defined(WINCE) #pragma warning( disable: 4200 ) #endif namespace gogocmessaging { // ------------------------------------------------------------------------ union Message { public: uint8_t rawdata[0]; struct __MSG_CONTENTS { struct __MSG_HEADER { uint16_t _msgid; uint16_t _datalen; } header; uint8_t _data[0]; } msg; // Gets the size of the data in this class. uint32_t GetRawSize ( void ) const; // Static creator and destructor. static Message* CreateMessage ( const uint16_t aMsgId, const uint32_t aDataLen, const uint8_t* aData ); static void FreeMessage ( Message* pMsg ); static void AssertMessage ( const Message* pMsg ); }; } #if defined(WIN32) || defined(WINCE) #pragma warning( default: 4200 ) #endif #endif gogoc-1_2-RELEASE/gogoc-messaging/gogocmessaging/messageprocessor.h0100644000000000000000000000265411301542455024121 0ustar rootroot// ************************************************************************** // $Id: messageprocessor.h,v 1.1 2009/11/20 16:34:53 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // This component provides a way of processing incoming messages. It is // fully abstracted and forces the applications to implement the // ProcessMessage function. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocmessaging_messageprocessor_h__ #define __gogocmessaging_messageprocessor_h__ #include #include namespace gogocmessaging { // ------------------------------------------------------------------------ class MessageProcessor { public: // Type definition. typedef enum { STATE_DISABLED, STATE_ENABLED } tProcessorState; protected: tProcessorState m_eProcessorState; protected: // Construction / destruction. MessageProcessor ( void ) : m_eProcessorState(STATE_DISABLED) {}; public: virtual ~MessageProcessor ( void ) {}; // Message Processing. virtual error_t ProcessMessage ( Message* pMsg )=0; }; } #endif gogoc-1_2-RELEASE/gogoc-messaging/gogocmessaging/messagesender.h0100644000000000000000000000300011301542455023344 0ustar rootroot// ************************************************************************** // $Id: messagesender.h,v 1.1 2009/11/20 16:34:53 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // This component contains a way of posting messages. The messages are // accumulated into a send queue. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocmessaging_messagesender_h__ #define __gogocmessaging_messagesender_h__ #include #include #include using namespace std; namespace gogocmessaging { // ------------------------------------------------------------------------ class MessageSender { public: // Type definition. typedef enum { STATE_DISABLED, STATE_ENABLED } tSenderState; protected: tSenderState m_eSenderState; std::queue m_SendQueue; Semaphore* m_pSemaphore; // Semaphore on queue. protected: // Construction / destruction. MessageSender ( void ); public: virtual ~MessageSender ( void ); // Offers a means of posting messages. void PostMessage ( Message* pMsg ); protected: void Reset ( void ); }; } #endif gogoc-1_2-RELEASE/gogoc-messaging/gogocmessaging/pipeclient.h0100644000000000000000000000276111301542455022670 0ustar rootroot// ************************************************************************** // $Id: pipeclient.h,v 1.1 2009/11/20 16:34:53 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Defines a specialized IPC Client: The Named pipe client. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocmessaging_pipeclient_h__ #define __gogocmessaging_pipeclient_h__ #include #include #include #include using namespace std; #if defined(WIN32) || defined(WINCE) #pragma warning( disable:4250 ) #endif namespace gogocmessaging { // ------------------------------------------------------------------------ class PipeClient : public IPCClient, public PipeIO { private: IPC_HANDLE m_PipeHandle; string m_PipeName; public: // Construction / destruction PipeClient ( const string& aPipeName ); virtual ~PipeClient ( void ); // IPC Client overrides. virtual error_t Connect ( void ); // Blocking virtual error_t Disconnect ( void ); }; } #if defined(WIN32) || defined(WINCE) #pragma warning( default:4250 ) #endif #endif gogoc-1_2-RELEASE/gogoc-messaging/gogocmessaging/pipeio.h0100644000000000000000000000322711301542455022017 0ustar rootroot// ************************************************************************** // $Id: pipeio.h,v 1.1 2009/11/20 16:34:53 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Defines a specialized way of transferring data using IPC: Pipes! // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocmessaging_pipeio_h__ #define __gogocmessaging_pipeio_h__ #include #include namespace gogocmessaging { // ------------------------------------------------------------------------ class PipeIO : virtual public IPCServent { public: // Construction / destruction PipeIO ( void ); virtual ~PipeIO ( void ); // Overrides from IPC Servent virtual error_t CanRead ( bool &bCanRead ) const; // Non-Blocking virtual error_t CanWrite ( bool &bCanWrite ) const; // Non-Blocking virtual error_t Read ( void* pvReadBuffer, const uint32_t nBufferSize, uint32_t& nRead ); // Blocking virtual error_t Write ( const void* pvData, const uint32_t nDataSize, uint32_t& nWritten ); // Blocking }; } #endif gogoc-1_2-RELEASE/gogoc-messaging/gogocmessaging/pipeserver.h0100644000000000000000000000311711301542456022715 0ustar rootroot// ************************************************************************** // $Id: pipeserver.h,v 1.1 2009/11/20 16:34:54 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Defines a specialized IPC Server: The Named pipe server. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocmessaging_pipeserver_h__ #define __gogocmessaging_pipeserver_h__ #include #include #include #include using namespace std; #if defined(WIN32) || defined(WINCE) #pragma warning( disable:4250 ) #endif namespace gogocmessaging { // ------------------------------------------------------------------------ class PipeServer : public IPCServer, public PipeIO { private: string m_PipeName; bool m_bClientConnected; public: // Construction / destruction PipeServer ( const string& aPipeName ); virtual ~PipeServer ( void ); // IPC Server overrides. virtual error_t CreateConnectionPoint ( void ); // Non-Blocking virtual error_t AcceptConnection ( void ); // Blocking virtual error_t CloseConnection ( void ); // Non-Blocking }; } #if defined(WIN32) || defined(WINCE) #pragma warning( default:4250 ) #endif #endif gogoc-1_2-RELEASE/gogoc-messaging/gogocmessaging/semaphore.h0100644000000000000000000000240611301542456022514 0ustar rootroot// ************************************************************************** // $Id: semaphore.h,v 1.1 2009/11/20 16:34:54 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Semaphore wrapper for Windows & other platforms. // // Author: Charles Nepveu // // Creation Date: December 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocmessaging_semaphore_h__ #define __gogocmessaging_semaphore_h__ #include #if defined(WIN32) || defined(WINCE) typedef ptr_t* sem_t; #else #include #endif namespace gogocmessaging { // ------------------------------------------------------------------------ class Semaphore { protected: sem_t m_Semaphore; // Semaphore *nix struct. public: Semaphore ( unsigned int nMaxCount=1, unsigned int nInitialCount=1 ); ~Semaphore ( void ); int WaitAndLock ( unsigned long ulWaitms=0 ); // Blocking int ReleaseLock ( void ); }; } #endif gogoc-1_2-RELEASE/gogoc-messaging/gogocmessaging/servent.h0100644000000000000000000000553011301542456022220 0ustar rootroot// ************************************************************************** // $Id: servent.h,v 1.1 2009/11/20 16:34:54 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // This component will be used by the messaging layer to communicate // through the IPC. Prior to use the Servent component, an application must // register a IPCServent-derived object. The Initialize method will // initialize the IPCServent component. The SendData and ReceiveData // methods are standard IO routines used to send and receive user data. // The Servent will implement a way of fragmenting user data in several // packets before sending them on the IPC medium. Also, it will be able to // reconstitute the fragmented user data upon reception. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocmessaging_servent_h__ #define __gogocmessaging_servent_h__ #include #include namespace gogocmessaging { typedef unsigned long long counter_t; // Type definitions. typedef struct __SERVENT_INFO { counter_t nTtlBytesRead; counter_t nTtlBytesWritten; } SERVENT_INFO, *PSERVENT_INFO; // ------------------------------------------------------------------------ class Servent { private: IPCServent* m_pIPCServent; // IPC server/client connectivity. counter_t m_nTtlBytesRead; // Bytes received counter. counter_t m_nTtlBytesWritten; // Bytes sent counter. Semaphore* m_pSemIPCMutex; // Mutex for IO operations on IPC. public: // Construction / destruction Servent ( void ); virtual ~Servent ( void ); // Initialization routine. error_t Initialize ( IPCServent* pIPCServent ); bool WaitReady ( unsigned long ulWaitms ); // IO operation routines. error_t ReadData ( void* pvReadBuffer, const uint32_t nBufferSize, uint32_t& nRead ); error_t WriteData ( const void* pvData, const uint32_t nDataSize, uint32_t& nWritten ); error_t CanRead ( bool& bCanRead ); error_t CanWrite ( bool& bCanWrite ); // Object Statistics info. void GetServentInfo ( PSERVENT_INFO pObj ); private: error_t _ReadData ( void* pvReadBuffer, const uint32_t nBufferSize, uint32_t& nRead ); error_t _WriteData ( const void* pvData, const uint32_t nDataSize, uint32_t& nWritten ); }; } #endif gogoc-1_2-RELEASE/gogoc-messaging/gogocmessaging/servermsgsender.h0100644000000000000000000000306011301542456023744 0ustar rootroot// ************************************************************************** // $Id: servermsgsender.h,v 1.1 2009/11/20 16:34:54 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Defines the different messages the gogoCLIENT can send. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocmessaging_servermsgsender_h__ #define __gogocmessaging_servermsgsender_h__ #include #include #include #include #undef PostMessage namespace gogocmessaging { // ------------------------------------------------------------------------ class ServerMsgSender { protected: // Construction / destruction. ServerMsgSender ( void ); public: virtual ~ServerMsgSender ( void ); public: void Send_StatusInfo ( const gogocStatusInfo* aStatusInfo ); void Send_TunnelInfo ( const gogocTunnelInfo* aTunnelInfo ); void Send_BrokerList ( const gogocBrokerList* aBrokerList ); void Send_HACCESSStatusInfo ( const HACCESSStatusInfo* aHACCESSStatusInfo ); protected: virtual void PostMessage ( Message* pMsg )=0; }; } #endif gogoc-1_2-RELEASE/gogoc-messaging/gogocmessaging/servermsgtranslator.h0100644000000000000000000000421111301542456024654 0ustar rootroot// ************************************************************************** // $Id: servermsgtranslator.h,v 1.1 2009/11/20 16:34:54 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Defines the message processing of gogoCLIENT messages destined // for the Client (which is the server-side of the communication). // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocmessaging_servermsgtranslator_h__ #define __gogocmessaging_servermsgtranslator_h__ #include #include #include namespace gogocmessaging { // ------------------------------------------------------------------------ class ServerMsgTranslator: public MessageProcessor { protected: // Construction / destruction. ServerMsgTranslator ( void ); public: virtual ~ServerMsgTranslator ( void ); protected: // Override from MessageProcessor. error_t ProcessMessage ( Message* pMsg ); // To be implemented by derived classes. virtual error_t Recv_StatusInfoRequest( void )=0; virtual error_t Recv_TunnelInfoRequest( void )=0; virtual error_t Recv_BrokerListRequest( void )=0; virtual error_t Recv_HACCESSConfigInfo ( const HACCESSConfigInfo* aHACCESSConfigInfo )=0; virtual error_t Recv_HACCESSStatusInfoRequest( void )=0; private: // Message data translators. error_t TranslateStatusInfoReq( uint8_t* pData, const uint16_t nDataLen ); error_t TranslateTunnelInfoReq( uint8_t* pData, const uint16_t nDataLen ); error_t TranslateBrokerListReq( uint8_t* pData, const uint16_t nDataLen ); error_t TranslateHACCESSConfigInfo( uint8_t* pData, const uint16_t nDataLen ); error_t TranslateHACCESSStatusInfoReq( uint8_t* pData, const uint16_t nDataLen ); }; } #endif gogoc-1_2-RELEASE/gogoc-messaging/gogocmessaging/threadwrapper.h0100644000000000000000000000304111301542456023375 0ustar rootroot// ************************************************************************** // $Id: threadwrapper.h,v 1.1 2009/11/20 16:34:54 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Thread wrapper for Windows & other platforms. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #ifndef __gogocmessaging_threadwrapper_h__ #define __gogocmessaging_threadwrapper_h__ #include typedef ptr_t * thread_t; typedef ptr_t * event_t; #ifndef WINAPI #define WINAPI #endif namespace gogocmessaging { // ------------------------------------------------------------------------ class ThreadWrapper { protected: thread_t m_hThread; // Thread handle. event_t m_hQuitEvent; // Handle for quit event. // Construction / destruction. protected: ThreadWrapper ( void ); public: virtual ~ThreadWrapper ( void ); // Start and stop the thread. bool Run ( void ); bool Stop ( void ); protected: // The work function to be called by Run(). virtual void Work ( void )=0; bool ShouldStop ( void ) const; private: static uint32_t WINAPI ThreadProc ( void* lpvParam ); }; } #endif gogoc-1_2-RELEASE/gogoc-messaging/.cvsignore0100644000000000000000000000000011301065061017340 0ustar rootrootgogoc-1_2-RELEASE/gogoc-messaging/Makefile0100644000000000000000000001070311301542452017017 0ustar rootroot# # $Id: Makefile,v 1.1 2009/11/20 16:34:50 jasminko Exp $ # # Copyright (c) 2007 gogo6 Inc. All rights reserved. # # For license information refer to CLIENT-LICENSE.TXT # # Author: Charles Nepveu # OBJ_DIR=objs BIN_DIR=bin LIB_DIR=lib INC_DIR=gogocmessaging TARGET=$(LIB_DIR)/libgogocmessaging.a GOGOCPAL=../gogoc-pal GOGOCPALINC_DIR=$(GOGOCPAL)/out_inc GOGOCPALDEFS_DIR=$(GOGOCPAL)/defs GOGOCPALLIB_DIR=$(GOGOCPAL)/out_lib GOGOCPALLIB=gogocpal CC=gcc CXX=g++ LD=g++ RANLIB=ranlib AR=ar ifdef DEBUG CXXFLAGS=-g -I. -I$(GOGOCPALINC_DIR) -I$(GOGOCPALDEFS_DIR) -Wall -D_REENTRANT -DDEBUG $(HACCESS_DEFINES) $(EXTRA_CXXFLAGS) CFLAGS=-g -I. -I$(GOGOCPALINC_DIR) -I$(GOGOCPALDEFS_DIR) -Wall -D_REENTRANT -DDEBUG $(HACCESS_DEFINES) $(EXTRA_CFLAGS) LDFLAGS=-g -L$(LIB_DIR) -L$(GOGOCPALLIB_DIR) -lgogocmessaging -l$(GOGOCPALLIB) $(EXTRA_LDFLAGS) else CXXFLAGS=-O2 -I. -I$(GOGOCPALINC_DIR) -I$(GOGOCPALDEFS_DIR) -Wall -D_REENTRANT -DNDEBUG $(HACCESS_DEFINES) $(EXTRA_CXXFLAGS) CFLAGS=-O2 -I. -I$(GOGOCPALINC_DIR) -I$(GOGOCPALDEFS_DIR) -Wall -D_REENTRANT -DNDEBUG $(HACCESS_DEFINES) $(EXTRA_CFLAGS) LDFLAGS=-O2 -L$(LIB_DIR) -L$(GOGOCPALLIB_DIR) -lgogocmessaging -l$(GOGOCPALLIB) $(EXTRA_LDFLAGS) endif .PHONY: all clean test_targets # # all: $(TARGET) $(BIN_DIR) $(OBJ_DIR): mkdir -p $(OBJ_DIR) $(BIN_DIR): mkdir -p $(BIN_DIR) $(LIB_DIR): mkdir -p $(LIB_DIR) OBJS=$(OBJ_DIR)/ipcserver.o \ $(OBJ_DIR)/ipcclient.o \ $(OBJ_DIR)/servent.o \ $(OBJ_DIR)/message.o \ $(OBJ_DIR)/messagesender.o \ $(OBJ_DIR)/communicationsmgr.o \ $(OBJ_DIR)/clientmsgtranslator.o \ $(OBJ_DIR)/clientmsgsender.o \ $(OBJ_DIR)/servermsgtranslator.o \ $(OBJ_DIR)/servermsgsender.o \ $(OBJ_DIR)/clientmessengerimpl.o \ $(OBJ_DIR)/guimessengerimpl.o \ $(OBJ_DIR)/gogoc_c_wrapper.o \ $(OBJ_DIR)/gogocuistrings.o $(OBJ_DIR)/ipcserver.o: src/ipcserver.cc $(CXX) $(CXXFLAGS) -c -o $(OBJ_DIR)/ipcserver.o src/ipcserver.cc $(OBJ_DIR)/ipcclient.o: src/ipcclient.cc $(CXX) $(CXXFLAGS) -c -o $(OBJ_DIR)/ipcclient.o src/ipcclient.cc $(OBJ_DIR)/servent.o: src/servent.cc $(CXX) $(CXXFLAGS) -c -o $(OBJ_DIR)/servent.o src/servent.cc $(OBJ_DIR)/message.o: src/message.cc $(CXX) $(CXXFLAGS) -c -o $(OBJ_DIR)/message.o src/message.cc $(OBJ_DIR)/messagesender.o: src/messagesender.cc $(CXX) $(CXXFLAGS) -c -o $(OBJ_DIR)/messagesender.o src/messagesender.cc $(OBJ_DIR)/communicationsmgr.o: src/communicationsmgr.cc $(CXX) $(CXXFLAGS) -c -o $(OBJ_DIR)/communicationsmgr.o src/communicationsmgr.cc $(OBJ_DIR)/clientmsgtranslator.o: src/clientmsgtranslator.cc $(CXX) $(CXXFLAGS) -c -o $(OBJ_DIR)/clientmsgtranslator.o src/clientmsgtranslator.cc $(OBJ_DIR)/clientmsgsender.o: src/clientmsgsender.cc $(CXX) $(CXXFLAGS) -c -o $(OBJ_DIR)/clientmsgsender.o src/clientmsgsender.cc $(OBJ_DIR)/servermsgtranslator.o: src/servermsgtranslator.cc $(CXX) $(CXXFLAGS) -c -o $(OBJ_DIR)/servermsgtranslator.o src/servermsgtranslator.cc $(OBJ_DIR)/servermsgsender.o: src/servermsgsender.cc $(CXX) $(CXXFLAGS) -c -o $(OBJ_DIR)/servermsgsender.o src/servermsgsender.cc $(OBJ_DIR)/clientmessengerimpl.o: src/clientmessengerimpl.cc $(CXX) $(CXXFLAGS) -c -o $(OBJ_DIR)/clientmessengerimpl.o src/clientmessengerimpl.cc $(OBJ_DIR)/guimessengerimpl.o: src/guimessengerimpl.cc $(CXX) $(CXXFLAGS) -c -o $(OBJ_DIR)/guimessengerimpl.o src/guimessengerimpl.cc $(OBJ_DIR)/gogoc_c_wrapper.o: src/gogoc_c_wrapper.cc $(CXX) $(CXXFLAGS) -c -o $(OBJ_DIR)/gogoc_c_wrapper.o src/gogoc_c_wrapper.cc $(OBJ_DIR)/gogocuistrings.o: src/gogocuistrings.c $(CC) $(CFLAGS) -c -o $(OBJ_DIR)/gogocuistrings.o src/gogocuistrings.c $(OBJ_DIR)/test_ipclayer.o: src/test_ipclayer.cc $(CXX) $(CXXFLAGS) -c -o $(OBJ_DIR)/test_ipclayer.o src/test_ipclayer.cc $(OBJ_DIR)/test_messaginglayer.o: src/test_messaginglayer.cc $(CXX) $(CXXFLAGS) -c -o $(OBJ_DIR)/test_messaginglayer.o src/test_messaginglayer.cc $(OBJ_DIR)/test_gogocemulator.o: src/test_gogocemulator.c $(CC) $(CFLAGS) -c -o $(OBJ_DIR)/test_gogocemulator.o src/test_gogocemulator.c test_targets: $(TARGET) $(OBJ_DIR)/test_ipclayer.o $(OBJ_DIR)/test_messaginglayer.o $(OBJ_DIR)/test_gogocemulator.o $(LD) -o $(BIN_DIR)/test_ipclayer $(OBJ_DIR)/test_ipclayer.o $(LDFLAGS) $(LD) -o $(BIN_DIR)/test_messaginglayer $(OBJ_DIR)/test_messaginglayer.o $(LDFLAGS) $(LD) -o $(BIN_DIR)/test_gogocemulator $(OBJ_DIR)/test_gogocemulator.o $(LDFLAGS} $(TARGET): $(OBJ_DIR) $(OBJS) $(LIB_DIR) $(AR) cru $(TARGET) $(OBJS) $(RANLIB) $(TARGET) clean: @echo -n "Cleaning up workspace... " @rm -rf $(OBJ_DIR) $(BIN_DIR) $(LIB_DIR) @echo "done." gogoc-1_2-RELEASE/gogoc-messaging/README0100644000000000000000000000207111301542452016236 0ustar rootroot$ Id: $ ------------------------------------------------------------------------------ Copyright (c) 2007 gogo6 Inc. All rights reserved. ------------------------------------------------------------------------------ This directory contains the gogoCLIENT Messaging Subsystem. Subdirectories: .\gogocmessaging\ - Contains the include files of the Messaging Subsystem. .\src\ - Contains the source files of the Messaging Subsystem. .\lib\ - Will contain the built gogoCLIENT Messaging Subsystem library. .\winbuild\ - Visual Studio project directories for winpc and wince. Files: .\Makefile - Makefile to build gogoc-messaging on UNIX-like platforms. .\build-winpc.cmd - Command script to build gogoc-messaging on Windows (XP, Vista). .\build-wince.cmd - Command script to build gogoc-messaging on Windows Embedded. Applications that use this library should modify the CFLAGS to add the following: -I/gogocmessaging LDFLAGS: -L/lib -lgogocmessaging gogoc-1_2-RELEASE/gogoc-messaging/build-wince.cmd0100644000000000000000000000310611301542452020245 0ustar rootroot@ECHO OFF REM ************************************************************************* REM * $Id: build-wince.cmd,v 1.1 2009/11/20 16:34:50 jasminko Exp $ REM * REM * Batch file used to build the gogoCLIENT Messaging Subsystem. REM * REM * Prerequisites: REM * - Visual Studio 2005 (SP1) REM * - Windows Embedded CE (5 or 6) SDK REM * - DEVENV executable in %PATH% REM * REM * Usage: REM * build-wince [/Release /Debug] REM * REM ************************************************************************* REM Defaults: SET CONFIGURATION=Release SET PLATFORM= SET COMMAND=Build REM Overrides: :ParseArgs IF /I "%~1" == "/?" GOTO Usage IF /I "%~1" == "-h" GOTO Usage IF /I "%~1" == "/Release" SET CONFIGURATION=Release& SHIFT& GOTO ParseArgs IF /I "%~1" == "/Debug" SET CONFIGURATION=Debug& SHIFT& GOTO ParseArgs IF /I "%~1" == "/Clean" SET COMMAND=Clean& SHIFT& GOTO ParseArgs IF "%~1" EQU "" GOTO Done_Args ECHO Unknown command-line switch: %~1 GOTO Usage :Done_Args REM Build the target ECHO Launching build of gogoc-messaging solution... ECHO Configuration: COMMAND=%COMMAND% CONFIGURATION=%CONFIGURATION% ECHO. DEVENV winbuild\wince\gogoc-messaging.sln /%COMMAND% "%CONFIGURATION%" IF %ERRORLEVEL% == 0 GOTO build_ok GOTO build_error :Usage ECHO. ECHO Usage: ECHO %0 ^[^/Release^|^/Debug^] ^[^/Clean^] ECHO. ECHO Defaults: ^/Release ECHO. GOTO the_end :build_ok ECHO. ECHO Build of gogoc-messaging solution completed successfully. GOTO the_end :build_error ECHO. ECHO Build of gogoc-messaging solution FAILED! :the_end gogoc-1_2-RELEASE/gogoc-messaging/build-winpc.cmd0100644000000000000000000000346511301542453020271 0ustar rootroot@ECHO OFF REM ************************************************************************* REM * $Id: build-winpc.cmd,v 1.1 2009/11/20 16:34:51 jasminko Exp $ REM * REM * Batch file used to build the gogoCLIENT Messaging Subsystem. REM * REM * Prerequisites: REM * - Visual Studio 2005 (SP1) REM * - Windows Vista RTM SDK (Integrated in VS2005SP1) REM * - DEVENV executable in %PATH% REM * REM * Usage: REM * build-gogoc [/Release /Debug] [/Win32 /x64] REM * REM ************************************************************************* REM Defaults: SET CONFIGURATION=Release SET PLATFORM=Win32 SET COMMAND=Build REM Overrides: :ParseArgs IF /I "%~1" == "/?" GOTO Usage IF /I "%~1" == "-h" GOTO Usage IF /I "%~1" == "/Release" SET CONFIGURATION=Release& SHIFT& GOTO ParseArgs IF /I "%~1" == "/Debug" SET CONFIGURATION=Debug& SHIFT& GOTO ParseArgs IF /I "%~1" == "/Win32" SET PLATFORM=Win32& SHIFT& GOTO ParseArgs IF /I "%~1" == "/x64" SET PLATFORM=x64& SHIFT& GOTO ParseArgs IF /I "%~1" == "/Clean" SET COMMAND=Clean& SHIFT& GOTO ParseArgs IF "%~1" EQU "" GOTO Done_Args ECHO Unknown command-line switch: %~1 GOTO Usage :Done_Args REM Build the target ECHO Launching build of gogoc-messaging solution... ECHO Configuration: COMMAND=%COMMAND% PLATFORM=%PLATFORM% CONFIGURATION=%CONFIGURATION% ECHO. DEVENV winbuild\winpc\gogoc-messaging.sln /%COMMAND% "%CONFIGURATION%|%PLATFORM%" IF %ERRORLEVEL% == 0 GOTO build_ok GOTO build_error :Usage ECHO. ECHO Usage: ECHO %0 ^[^/Release^|^/Debug^] ^[^/Win32^|^/x64^] ^[^/Clean^] ECHO. ECHO Defaults: ^/Release ^/Win32 ECHO. GOTO the_end :build_ok ECHO. ECHO Build of gogoc-messaging solution completed successfully. GOTO the_end :build_error ECHO. ECHO Build of gogoc-messaging solution FAILED! :the_end gogoc-1_2-RELEASE/gogoc-messaging/src/0040755000000000000000000000000011346561546016166 5ustar rootrootgogoc-1_2-RELEASE/gogoc-messaging/src/linux/0040755000000000000000000000000011346561542017321 5ustar rootrootgogoc-1_2-RELEASE/gogoc-messaging/src/linux/pipeserver.cc0100644000000000000000000001064411301542461022004 0ustar rootroot// ************************************************************************** // $Id: pipeserver.cc,v 1.1 2009/11/20 16:34:57 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Unix implementation of the PipeServer class. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #include #include #include #include #error THIS MODULE IS NOT FINISHED #define PIPE_MASK 0666 #define SLEEP(X) usleep( X * 1000 ) typedef void (*sig_handler)(int); extern "C" void sigpipe_handler( int whatever ) { } namespace gogocmessaging { // -------------------------------------------------------------------------- // Function : PipeServer constructor // // Description: // Will initialize a new PipeServer object. // // Arguments: // aPipeName: string [IN], The name of the pipe this server will create. // // Return values: (N/A) // // -------------------------------------------------------------------------- PipeServer::PipeServer( const string& aPipeName ) : IPCServer(), PipeIO(), m_PipeName(aPipeName), m_bClientConnected(false) { } // -------------------------------------------------------------------------- // Function : PipeServer destructor // // Description: // Will clean-up space allocated during object lifetime. // // Arguments: (none) // // Return values: (N/A) // // -------------------------------------------------------------------------- PipeServer::~PipeServer( void ) { // Is client still connected ? assert( m_bClientConnected == false ); } // -------------------------------------------------------------------------- // Function : CreateConnectionPoint // // Description: // Will create a NamedPipe server endpoint. // // Arguments: (none) // // Return values: // GOGOCM_UIS__NOERROR: Operation successful. // Any other value is an error. Use GetLastError() for more information. // // -------------------------------------------------------------------------- error_t PipeServer::CreateConnectionPoint( void ) { assert( !m_PipeName.empty() ); // Clear umask so it doesn't interfere with pipe security mask. umask(0); // --------------------------------- // Create the server pipe endpoint. // --------------------------------- int retCode = mknod( m_PipeName.c_str(), S_IFIFO|PIPE_MASK, 0); // Verify returned value. if( retCode != 0 ) { return GOGOCM_UIS_FAILCREATESERVERPIPE; } // Successful operation. return GOGOCM_UIS__NOERROR; } // -------------------------------------------------------------------------- // Function : AcceptConnection // // Description: // Will accept a pipe client connection. // NOTE: THIS FUNCTION IS (big time) BLOCKING!!! // // Arguments: (none) // // Return values: // GOGOCM_UIS__NOERROR: Operation successful. // Any other value is an error. Use GetLastError() for more information. // // -------------------------------------------------------------------------- error_t PipeServer::AcceptConnection( void ) { FILE* hPipe; if( m_bClientConnected ) return GOGOCM_UIS_CLIENTALRDYCONN; // Open the pipe in read - write mode, and block until // a client connects. // hPipe = fopen( m_PipeName.c_str(), "rwb" ); if( hPipe == NULL ) { // Error opening pipe. return GOGOCM_UIS_FAILOPENPIPE; } // Register new handler for SIG_PIPE signal. sig_handler oldpipehandler = signal( SIGPIPE, sigpipe_handler ); if( oldpipehandler == SIG_ERR ) { } while( !m_bClientConnected ) { SLEEP( 30 ); } // Client connection successful return GOGOCM_UIS__NOERROR; } // -------------------------------------------------------------------------- // Function : CloseConnection // // Description: // Will close the server-side pipe instance. // // Arguments: (none) // // Return values: // GOGOCM_UIS__NOERROR: Operation successful. // Any other value is an error. Use GetLastError() for more information. // // -------------------------------------------------------------------------- error_t PipeServer::CloseConnection( void ) { // Mark client as not connected. m_bClientConnected = false; // Server pipe disconnection successful. return GOGOCM_UIS__NOERROR; } } gogoc-1_2-RELEASE/gogoc-messaging/src/linux/semaphore.cc0100644000000000000000000000607111301542461021602 0ustar rootroot// ************************************************************************** // $Id: semaphore.cc,v 1.1 2009/11/20 16:34:57 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // POSIX Semaphore wrapper. Use -lrt link option. // // Author: Charles Nepveu // // Creation Date: December 2006 // __________________________________________________________________________ // ************************************************************************** #include #include #include namespace gogocmessaging { // -------------------------------------------------------------------------- // Function : Semaphore constructor // // Description: // Will initialize a new Semaphore object. // // Arguments: // nCount: int [IN], The initial count of semaphore // // Return values: (N/A) // // Exceptions: (none) // // -------------------------------------------------------------------------- Semaphore::Semaphore( unsigned int nMaxCount, unsigned int nInitialCount ) { assert( nMaxCount >= nInitialCount ); int i; i = sem_init( &m_Semaphore, 0, nMaxCount ); assert( i == 0 ); // Lock a certain count. for( i=nMaxCount-nInitialCount; i>0; i-- ) WaitAndLock(); } // -------------------------------------------------------------------------- // Function : Semaphore destructor // // Description: // Will clean-up space allocated during object lifetime. // // Arguments: (none) // // Return values: (N/A) // // Exceptions: (none) // // -------------------------------------------------------------------------- Semaphore::~Semaphore( void ) { sem_destroy( &m_Semaphore ); } // -------------------------------------------------------------------------- // Function : WaitAndLock // // Description: // Blocks execution until semaphore object is available. // Locks (decrements) semaphore count. // // Arguments: // ulWaitms: long [IN], The time to wait until state is signalled. // If 0, the timeout is infinite. // // Return values: // 0: Successfuly obtained lock on semaphore object // // Exceptions: (none) // // -------------------------------------------------------------------------- int Semaphore::WaitAndLock( unsigned long ulWaitms ) { int retCode = -1; if( ulWaitms > 0 ) { unsigned long wait = 0; do { retCode = sem_trywait( &m_Semaphore ); usleep( 25000 ); wait += 25; } while( retCode != 0 && wait < ulWaitms ); } else retCode = sem_wait( &m_Semaphore ); return retCode; } // -------------------------------------------------------------------------- // Function : ReleaseLock // // Description: // Releases lock on semaphore object (increments semaphore count). // // Arguments: (none) // // Return values: // 0: Successfuly released lock on semaphore object. // // Exceptions: (none) // // -------------------------------------------------------------------------- int Semaphore::ReleaseLock( void ) { return sem_post( &m_Semaphore ); } } // namespace gogoc-1_2-RELEASE/gogoc-messaging/src/linux/threadwrapper.cc0100644000000000000000000001010111301542462022455 0ustar rootroot// ************************************************************************** // $Id: threadwrapper.cc,v 1.1 2009/11/20 16:34:58 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Thread wrapper implementation for unix systems, using pthreads. // // Author: Charles Nepveu // // Creation Date: December 2006 // __________________________________________________________________________ // ************************************************************************** #include #include namespace gogocmessaging { // -------------------------------------------------------------------------- // Function : ThreadWrapper constructor // // Description: // Will initialize a new ThreadWrapper object. // // Arguments: (none) // // Return values: (N/A) // // Exceptions: (none) // // -------------------------------------------------------------------------- ThreadWrapper::ThreadWrapper( void ): #ifdef WIN32 m_hThread(NULL), m_hQuitEvent(NULL) #else m_tID(0), m_bShouldStop(false) #endif { } // -------------------------------------------------------------------------- // Function : ThreadWrapper destructor // // Description: // Will clean-up space allocated during object lifetime. // // Arguments: (none) // // Return values: (N/A) // // Exceptions: (none) // // -------------------------------------------------------------------------- ThreadWrapper::~ThreadWrapper( void ) { } // -------------------------------------------------------------------------- // Function : Run // // Description: // Will start executing the ThreadProc function with this class. // // Arguments: (none) // // Return values: // true if thread execution started normally. // false otherwise. // // Exceptions: (none) // // -------------------------------------------------------------------------- bool ThreadWrapper::Run( void ) { pthread_attr_t attr; int retCode; // Initialize thread attributes if( pthread_attr_init(&attr) != 0 ) return false; // The thread must be joinable. pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); // Launch thread procedure. retCode = pthread_create( &m_tID, &attr, &ThreadWrapper::ThreadProc, (void*)this ); // We don't need the thread creation argument anymore. pthread_attr_destroy(&attr); // Return completion. return retCode == 0; } // -------------------------------------------------------------------------- // Function : Stop // // Description: // Will stop execution of a running thread. // // Arguments: (none) // // Return values: // true if thread execution has stopped. // false otherwise. // // Exceptions: (none) // // -------------------------------------------------------------------------- bool ThreadWrapper::Stop( void ) { m_bShouldStop = true; // Wait for thread to exit. int retCode = pthread_join( m_tID, NULL ); return retCode == 0; } // -------------------------------------------------------------------------- // Function : ShouldStop // // Description: // Verifies if the running thread should exit (called periodically from the // running thread). // // Arguments: (none) // // Return values: // true if thread should terminate // false otherwise. // // Exceptions: (none) // // -------------------------------------------------------------------------- bool ThreadWrapper::ShouldStop( void ) const { return m_bShouldStop; } // -------------------------------------------------------------------------- // Function : ThreadProc [ STATIC ] // // Description: // Will start executing the derived work function. // // Arguments: // lpvParam: void* [IN], this pointer. // // Return values: // true if thread execution started normally. // false otherwise. // // Exceptions: (none) // // -------------------------------------------------------------------------- DWORD WINAPI ThreadWrapper::ThreadProc( void* lpvParam ) { assert( lpvParam != NULL ); // Run the Work function of the object. ((ThreadWrapper*)lpvParam)->Work(); return (DWORD)1; } } gogoc-1_2-RELEASE/gogoc-messaging/src/clientmessengerimpl.cc0100644000000000000000000001553111301542457022537 0ustar rootroot// ************************************************************************** // $Id: clientmessengerimpl.cc,v 1.1 2009/11/20 16:34:55 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Implementation of the ClientMessengerImpl class. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #include #include #include namespace gogocmessaging { // -------------------------------------------------------------------------- // Function : ClientMessengerImpl constructor // // Description: // Will initialize a new ClientMessengerImpl object. // // Arguments: (none) // // Return values: (N/A) // // -------------------------------------------------------------------------- ClientMessengerImpl::ClientMessengerImpl( void ) : ServerMsgSender(), ServerMsgTranslator(), m_CommManager( SERVER_MANAGER, this ) { m_CommManager.Run(); } // -------------------------------------------------------------------------- // Function : ClientMessengerImpl destructor // // Description: // Will clean-up space allocated during object lifetime. // // Arguments: (none) // // Return values: (N/A) // // -------------------------------------------------------------------------- ClientMessengerImpl::~ClientMessengerImpl( void ) { } // -------------------------------------------------------------------------- // Function : Recv_StatusInfoRequest // // Description: // Will wait on the communication manager to get ready. If ready state is // not signalled within XXX miliseconds, this function exits. // // Arguments: // ulWaitms: unsigned long [IN], the time to wait for ready state. // // Return values: // true: communications manager signalled ready state within XX miliseconds /// false: ready state was not signalled within the XX miliseconds. // // -------------------------------------------------------------------------- bool ClientMessengerImpl::WaitReady( unsigned long ulWaitms ) { return m_CommManager.WaitReady( ulWaitms ); } // -------------------------------------------------------------------------- // Function : Recv_StatusInfoRequest // // Description: // Will gather information on the gogoCLIENT status and send it to the // requester. // // Arguments: (none) // // Return values: // GOGOCM_UIS__NOERROR: Indicates success replying to request. // // -------------------------------------------------------------------------- error_t ClientMessengerImpl::Recv_StatusInfoRequest( void ) { gogocStatusInfo* pStatusInfo = NULL; error_t retCode; // Retrieve the status information. (ALLOCATION MADE HERE) retCode = RetrieveStatusInfo( &pStatusInfo ); if( retCode == GOGOCM_UIS__NOERROR ) { // Send the information to the requester. Send_StatusInfo( pStatusInfo ); // Free memory allocated. FreeStatusInfo( &pStatusInfo ); } return retCode; } // -------------------------------------------------------------------------- // Function : Recv_TunnelInfoRequest // // Description: // Will gather information on the tunnel and send it to the requester. // // Arguments: (none) // // Return values: // GOGOCM_UIS__NOERROR: Indicates success replying to request. // // -------------------------------------------------------------------------- error_t ClientMessengerImpl::Recv_TunnelInfoRequest( void ) { gogocTunnelInfo* pTunnelInfo = NULL; error_t retCode; // Retrieve the status information. (ALLOCATION MADE HERE) retCode = RetrieveTunnelInfo( &pTunnelInfo ); if( retCode == GOGOCM_UIS__NOERROR ) { // Send the information to the requester. Send_TunnelInfo( pTunnelInfo ); // Free memory allocated. FreeTunnelInfo( &pTunnelInfo ); } return retCode; } // -------------------------------------------------------------------------- // Function : Recv_BrokerListRequest // // Description: // Will gather the information on the list of brokers, and put it in a list // and sent it to the requester. // // Arguments: (none) // // Return values: // GOGOCM_UIS__NOERROR: Indicates success receiving request. // // -------------------------------------------------------------------------- error_t ClientMessengerImpl::Recv_BrokerListRequest( void ) { gogocBrokerList* pBrokerList = NULL; error_t retCode; // Retrieve the broker list. (ALLOCATION MADE HERE) retCode = RetrieveBrokerList( &pBrokerList ); if( retCode == GOGOCM_UIS__NOERROR ) { // Send the information to the requester. Send_BrokerList( pBrokerList ); // Free memory allocated. FreeBrokerList( &pBrokerList ); } return retCode; } // -------------------------------------------------------------------------- // Function : Recv_HACCESSConfigInfo // // Description: // Will call the C function that is implemented in the GOGOC. // // Arguments: (none) // // Return values: // GOGOCM_UIS__NOERROR: Indicates success receiving message. // // -------------------------------------------------------------------------- error_t ClientMessengerImpl::Recv_HACCESSConfigInfo( const HACCESSConfigInfo* aHACCESSConfigInfo ) { // C++ -> C bridge // This C function is implemented in the gogoCLIENT. return NotifyhaccessConfigInfo( aHACCESSConfigInfo ); } // -------------------------------------------------------------------------- // Function : Recv_HACCESSStatusInfoRequest // // Description: // Will gather information on the HACCESS Status and send it to the requester. // // Arguments: (none) // // Return values: // GOGOCM_UIS__NOERROR: Indicates success replying to request. // // -------------------------------------------------------------------------- error_t ClientMessengerImpl::Recv_HACCESSStatusInfoRequest( void ) { HACCESSStatusInfo* pHACCESSStatusInfo = NULL; error_t retCode; // Retrieve the status information. (ALLOCATION MADE HERE) retCode = RetrieveHACCESSStatusInfo( &pHACCESSStatusInfo ); if( retCode == GOGOCM_UIS__NOERROR ) { // Send the information to the requester. Send_HACCESSStatusInfo( pHACCESSStatusInfo ); // Free memory allocated. FreeHACCESSStatusInfo( &pHACCESSStatusInfo ); } return retCode; } // -------------------------------------------------------------------------- // Function : PostMessage // // Description: // Will post a message to the send queue for sending. // // Arguments: // pMsg: Message* [IN], The message to post. // // Return values: (none) // // -------------------------------------------------------------------------- void ClientMessengerImpl::PostMessage( Message* pMsg ) { MessageSender* pSender = (MessageSender*) &m_CommManager; pSender->PostMessage( pMsg ); } } // namespace gogoc-1_2-RELEASE/gogoc-messaging/src/clientmsgsender.cc0100644000000000000000000001315311301542457021652 0ustar rootroot// ************************************************************************** // $Id: clientmsgsender.cc,v 1.1 2009/11/20 16:34:55 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Implementation of the ClientMsgSender class. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #include #include namespace gogocmessaging { // -------------------------------------------------------------------------- // Function : ClientMsgSender constructor // // Description: // Will initialize a new ClientMsgSender object. // // Arguments: (none) // // Return values: (N/A) // // -------------------------------------------------------------------------- ClientMsgSender::ClientMsgSender( void ) { } // -------------------------------------------------------------------------- // Function : ClientMsgSender destructor // // Description: // Will clean-up space allocated during object lifetime. // // Arguments: (none) // // Return values: (N/A) // // -------------------------------------------------------------------------- ClientMsgSender::~ClientMsgSender( void ) { } // -------------------------------------------------------------------------- // Function : Send_StatusRequest // // Description: // Will post a message for a status info request. // // Arguments: (none) // // Return values: (none) // // -------------------------------------------------------------------------- void ClientMsgSender::Send_StatusInfoRequest( void ) { Message* pMsg; // No need to send data in requests messages. pMsg = Message::CreateMessage( MESSAGEID_REQUEST_STATUSINFO, 0, NULL ); assert( pMsg != NULL ); // Post the message. PostMessage( pMsg ); } // -------------------------------------------------------------------------- // Function : Send_StatusRequest // // Description: // Will post a message for a tunnel info request. // // Arguments: (none) // // Return values: (none) // // -------------------------------------------------------------------------- void ClientMsgSender::Send_TunnelInfoRequest( void ) { Message* pMsg; // No need to send data in requests messages. pMsg = Message::CreateMessage( MESSAGEID_REQUEST_TUNNELINFO, 0, NULL ); assert( pMsg != NULL ); // Post the message. PostMessage( pMsg ); } // -------------------------------------------------------------------------- // Function : Send_StatusRequest // // Description: // Will post a message for a broker list request. // // Arguments: (none) // // Return values: (none) // // -------------------------------------------------------------------------- void ClientMsgSender::Send_BrokerListRequest( void ) { Message* pMsg; // No need to send data in requests messages. pMsg = Message::CreateMessage( MESSAGEID_REQUEST_BROKERLIST, 0, NULL ); assert( pMsg != NULL ); // Post the message. PostMessage( pMsg ); } // -------------------------------------------------------------------------- // Function : Send_StatusRequest // // Description: // Will post a message for a broker list request. // // Arguments: (none) // // Return values: (none) // // -------------------------------------------------------------------------- void ClientMsgSender::Send_HACCESSConfigInfo( const HACCESSConfigInfo* aHACCESSCfgInfo ) { Message* pMsg; uint8_t pData[MSG_MAX_USERDATA]; uint32_t nDataLen = 0; assert( aHACCESSCfgInfo != NULL ); // ---------------------------------------------------- // Insert HACCESS Configuration Info data in the message. // ---------------------------------------------------- // Insert WWW document root. if( aHACCESSCfgInfo->haccess_doc_root ) { memcpy( pData + nDataLen, aHACCESSCfgInfo->haccess_doc_root, strlen(aHACCESSCfgInfo->haccess_doc_root) + 1 ); nDataLen += pal_strlen(aHACCESSCfgInfo->haccess_doc_root) + 1; } else { memset( pData + nDataLen, 0x00, 1 ); ++nDataLen; } // Append proxy enabled. memcpy( pData + nDataLen, (void*)&(aHACCESSCfgInfo->haccess_proxy_enabled), sizeof(aHACCESSCfgInfo->haccess_proxy_enabled) ); nDataLen += sizeof(aHACCESSCfgInfo->haccess_proxy_enabled); // Append web enabled. memcpy( pData + nDataLen, (void*)&(aHACCESSCfgInfo->haccess_web_enabled), sizeof(aHACCESSCfgInfo->haccess_web_enabled) ); nDataLen += sizeof(aHACCESSCfgInfo->haccess_web_enabled); // Append mappings changed. memcpy( pData + nDataLen, (void*)&(aHACCESSCfgInfo->haccess_devmap_changed), sizeof(aHACCESSCfgInfo->haccess_devmap_changed) ); nDataLen += sizeof(aHACCESSCfgInfo->haccess_devmap_changed); assert( nDataLen <= MSG_MAX_USERDATA ); // Buffer overflow has occured. // Create Message. pMsg = Message::CreateMessage( MESSAGEID_HACCESSCONFIGINFO, nDataLen, pData ); assert( pMsg != NULL ); // Post the message. PostMessage( pMsg ); } // -------------------------------------------------------------------------- // Function : Send_HACCESSStatusInfoRequest // // Description: // Will post a message for a HACCESS Status Info request. // // Arguments: (none) // // Return values: (none) // // -------------------------------------------------------------------------- void ClientMsgSender::Send_HACCESSStatusInfoRequest( void ) { Message* pMsg; // No need to send data in requests messages. pMsg = Message::CreateMessage( MESSAGEID_REQUEST_HACCESSSTATUSINFO, 0, NULL ); assert( pMsg != NULL ); // Post the message. PostMessage( pMsg ); } } // namespace gogoc-1_2-RELEASE/gogoc-messaging/src/clientmsgtranslator.cc0100644000000000000000000003316611301542457022571 0ustar rootroot// ************************************************************************** // $Id: clientmsgtranslator.cc,v 1.1 2009/11/20 16:34:55 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Implementation of the ClientMsgTranslator class. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #include #include #include namespace gogocmessaging { // -------------------------------------------------------------------------- // Function : ClientMsgTranslator constructor // // Description: // Will initialize a new ClientMsgTranslator object. // // Arguments: (none) // // Return values: (N/A) // // -------------------------------------------------------------------------- ClientMsgTranslator::ClientMsgTranslator( void ) : MessageProcessor() { // Enable message processing. MessageProcessor::m_eProcessorState = STATE_ENABLED; } // -------------------------------------------------------------------------- // Function : gogocMsgClientReceiver destructor // // Description: // Will clean-up space allocated during object lifetime. // // Arguments: (none) // // Return values: (N/A) // // -------------------------------------------------------------------------- ClientMsgTranslator::~ClientMsgTranslator( void ) { } // -------------------------------------------------------------------------- // Function : ProcessMessage // // Description: // Will verify the message type and call the proper translator. // NOTE: Try not to do any lengthy operations here, because we're executing // in the receiver thread. // // Arguments: // pMsg: Message* [IN], The message to process. // // Return values: // GOGOCM_UIS__NOERROR: Successful operation. // GOGOCM_UIS_MESSAGENOTIMPL: Message not implemented. // GOGOCM_UIS_MSGPROCDISABLED: Message processing is disabled. // // // -------------------------------------------------------------------------- error_t ClientMsgTranslator::ProcessMessage( Message* pMsg ) { error_t retCode; assert( pMsg ); // Process messages only if the message processor is enabled. if( m_eProcessorState == STATE_ENABLED ) { // ------------------------------------- // Verify what kind of message this is. // ------------------------------------- switch( pMsg->msg.header._msgid ) { case MESSAGEID_STATUSINFO: retCode = TranslateStatusInfo( pMsg->msg._data, pMsg->msg.header._datalen ); break; case MESSAGEID_TUNNELINFO: retCode = TranslateTunnelInfo( pMsg->msg._data, pMsg->msg.header._datalen ); break; case MESSAGEID_BROKERLIST: retCode = TranslateBrokerList( pMsg->msg._data, pMsg->msg.header._datalen ); break; case MESSAGEID_HACCESSSTATUSINFO: retCode = TranslateHACCESSStatusInfo( pMsg->msg._data, pMsg->msg.header._datalen ); break; default: retCode = GOGOCM_UIS_MESSAGENOTIMPL; // Unknown / invalid message. break; } } else retCode = GOGOCM_UIS_MSGPROCDISABLED; // Return completion status. return retCode; } // -------------------------------------------------------------------------- // Function : TranslateStatusInfo // // Description: // Will extract the status information from the byte buffer and invoke the // handler. // // Arguments: // pData: uint8_t* [IN], The raw data. // nDataLen: uint16_t [IN], The length of the raw data. // // Return values: // GOGOCM_UIS__NOERROR: Successful operation. // any other value on error. // // -------------------------------------------------------------------------- error_t ClientMsgTranslator::TranslateStatusInfo( uint8_t* pData, const uint16_t nDataLen ) { gogocStatusInfo statusInfo; uint16_t nCursor = 0; error_t retCode; // ---------------------------------------------- // Extract the status info from the byte buffer. // ---------------------------------------------- memcpy( (void*)&(statusInfo.eStatus), (void*)pData, sizeof(gogocCliStatus) ); nCursor += sizeof(gogocCliStatus); // Extract message sent along status info. memcpy( (void*)&(statusInfo.nStatus), (void*)(pData + nCursor), sizeof(statusInfo.nStatus) ); nCursor += sizeof(statusInfo.nStatus); // ----------------------------------------------------------------------- // Sanity check. Verify that the bytes of data we extracted match that of // what was expected. // ----------------------------------------------------------------------- assert( nCursor == nDataLen ); // --------------------------------- // Invoke derived function handler. // --------------------------------- retCode = Recv_StatusInfo( &statusInfo ); // Return completion code. return retCode; } // -------------------------------------------------------------------------- // Function : TranslateTunnelInfo // // Description: // Will extract the tunnel information from the byte buffer and invoke the // handler. // // Arguments: // pData: uint8_t* [IN], The raw data. // nDataLen: uint16_t [IN], The length of the raw data. // // Return values: // GOGOCM_UIS__NOERROR: Successful operation. // any other value on error. // // -------------------------------------------------------------------------- error_t ClientMsgTranslator::TranslateTunnelInfo( uint8_t* pData, const uint16_t nDataLen ) { gogocTunnelInfo tunnelInfo; uint32_t nCursor = 0; error_t retCode; // -- D A T A E X T R A C T I O N -- // Extract broker name from data buffer. tunnelInfo.szBrokerName = pal_strdup( (char*)(pData + nCursor) ); nCursor += pal_strlen( (char*)(pData + nCursor) ) + 1; // Extract tunnel type from data buffer. memcpy( (void*)&(tunnelInfo.eTunnelType), pData + nCursor, sizeof(gogocTunnelType) ); nCursor += sizeof(gogocTunnelType); // Extract Local tunnel endpoint IPv4 address from data buffer. tunnelInfo.szIPV4AddrLocalEndpoint = pal_strdup( (char*)(pData + nCursor) ); nCursor += pal_strlen( (char*)(pData + nCursor) ) + 1; // Extract Local tunnel endpoint IPv6 address from data buffer. tunnelInfo.szIPV6AddrLocalEndpoint = pal_strdup( (char*)(pData + nCursor) ); nCursor += pal_strlen( (char*)(pData + nCursor) ) + 1; // Extract Remote tunnel endpoint IPv4 address from data buffer. tunnelInfo.szIPV4AddrRemoteEndpoint = pal_strdup( (char*)(pData + nCursor) ); nCursor += pal_strlen( (char*)(pData + nCursor) ) + 1; // Extract Remote tunnel endpoint IPv6 address from data buffer. tunnelInfo.szIPV6AddrRemoteEndpoint = pal_strdup( (char*)(pData + nCursor) ); nCursor += pal_strlen( (char*)(pData + nCursor) ) + 1; // Extract The delegated prefix from data buffer. tunnelInfo.szDelegatedPrefix = pal_strdup( (char*)(pData + nCursor) ); nCursor += pal_strlen( (char*)(pData + nCursor) ) + 1; // Extract The delegated user domain from data buffer. tunnelInfo.szUserDomain = pal_strdup( (char*)(pData + nCursor) ); nCursor += pal_strlen( (char*)(pData + nCursor) ) + 1; // Extract tunnel uptime from data buffer. memcpy( (void*)&(tunnelInfo.tunnelUpTime), pData + nCursor, sizeof(time_t) ); nCursor += sizeof(time_t); // ----------------------------------------------------------------------- // Sanity check. Verify that the bytes of data we extracted match that of // what was expected. // ----------------------------------------------------------------------- assert( nCursor == nDataLen ); // --------------------------------- // Invoke derived function handler. // --------------------------------- retCode = Recv_TunnelInfo( &tunnelInfo ); // ----------------------------------------------- // Clean up allocated memory used for extraction. // ----------------------------------------------- free( tunnelInfo.szBrokerName ); free( tunnelInfo.szIPV4AddrLocalEndpoint ); free( tunnelInfo.szIPV6AddrLocalEndpoint ); free( tunnelInfo.szIPV4AddrRemoteEndpoint ); free( tunnelInfo.szIPV6AddrRemoteEndpoint ); free( tunnelInfo.szDelegatedPrefix ); free( tunnelInfo.szUserDomain ); // Return completion code. return retCode; } // -------------------------------------------------------------------------- // Function : TranslateBrokerList // // Description: // Will extract the broker list from the byte buffer and invoke the // handler. // // Arguments: // pData: uint8_t* [IN], The raw data. // nDataLen: uint16_t [IN], The length of the raw data. // // Return values: // GOGOCM_UIS__NOERROR: Successful operation. // any other value on error. // // -------------------------------------------------------------------------- gogocBrokerList* BuildBrokerList( uint8_t* pData, const uint32_t nDataLen, uint32_t& nCursor ) { if( nCursor >= nDataLen ) // End condition. return NULL; gogocBrokerList* pList = new gogocBrokerList; uint32_t nNameLen = pal_strlen( (const char*)pData ) + 1; nCursor += nNameLen; pList->szAddress = pal_strdup( (const char*)pData ); memcpy( (void*)&(pList->nDistance), pData + nCursor, sizeof(int) ); nCursor += sizeof(int); pList->next = BuildBrokerList( pData + nNameLen + sizeof(int), nDataLen, nCursor ); return pList; } // -------------------------------------------------------------------------- error_t ClientMsgTranslator::TranslateBrokerList( uint8_t* pData, const uint16_t nDataLen ) { gogocBrokerList* pList; uint32_t nCursor = 0; error_t retCode; // ------------------------------------------ // Extract broker list from the byte buffer. // ------------------------------------------ pList = BuildBrokerList( pData, nDataLen, nCursor ); // ----------------------------------------------------------------------- // Sanity check. Verify that the bytes of data we extracted match that of // what was expected. // ----------------------------------------------------------------------- assert( nCursor == nDataLen ); // --------------------------------- // Invoke derived function handler. // --------------------------------- retCode = Recv_BrokerList( pList ); // ----------------------------------------------- // Clean up allocated memory used for extraction. // ----------------------------------------------- gogocBrokerList* pListLast = NULL; for(; pList!=NULL; pList = pList->next ) { if( pListLast != NULL ) delete pListLast; free( pList->szAddress ); pListLast = pList; } if( pListLast != NULL ) delete pListLast; // Return completion status. return retCode; } // -------------------------------------------------------------------------- // Function : TranslateHACCESSStatusInfo // // Description: // Will extract the HACCESS Status Info from the byte buffer and invoke the // handler. // // Arguments: // pData: uint8_t* [IN], The raw data. // nDataLen: uint16_t [IN], The length of the raw data. // // Return values: // GOGOCM_UIS__NOERROR: Successful operation. // any other value on error. // // -------------------------------------------------------------------------- PMAPPING_STATUS BuildMappingStatuses( uint8_t* pData, const uint32_t nDataLen, uint32_t& nCursor ) { if( nCursor >= nDataLen ) // End condition. return NULL; PMAPPING_STATUS pMappingStatus = new MAPPING_STATUS; // Extract Device Name pMappingStatus->device_name = pal_strdup( (const char*)pData ); uint32_t nNameLen = pal_strlen( (const char*)pData ) + 1; nCursor += nNameLen; // Extract Device mapping status memcpy( (void*)&(pMappingStatus->mapping_status), pData + nNameLen, sizeof(HACCESSDevMapStts) ); nCursor += sizeof(int); // Extract the next. pMappingStatus->next = BuildMappingStatuses( pData + nNameLen + sizeof(int), nDataLen, nCursor ); return pMappingStatus; } void FreeMappingStatus( PMAPPING_STATUS mapStat ) { if( mapStat != NULL ) { FreeMappingStatus( mapStat->next ); assert( mapStat->device_name != NULL ); delete [] mapStat->device_name; delete mapStat; } } error_t ClientMsgTranslator::TranslateHACCESSStatusInfo( uint8_t* pData, const uint16_t nDataLen ) { HACCESSStatusInfo statusInfo; uint32_t nCursor = 0; error_t retCode; // -- D A T A E X T R A C T I O N -- // Extract the proxy status from data buffer. memcpy( (void*)&(statusInfo.haccess_proxy_status), pData + nCursor, sizeof(HACCESSFeatStts) ); nCursor += sizeof(HACCESSFeatStts); // Extract the web status from data buffer. memcpy( (void*)&(statusInfo.haccess_web_status), pData + nCursor, sizeof(HACCESSFeatStts) ); nCursor += sizeof(HACCESSFeatStts); // Extract the Device Mapping Module status from data buffer. memcpy( (void*)&(statusInfo.haccess_devmapmod_status), pData + nCursor, sizeof(HACCESSFeatStts) ); nCursor += sizeof(HACCESSFeatStts); // Extract the device mapping statuses. Unserialize the linked list. statusInfo.haccess_devmap_statuses = BuildMappingStatuses( pData + nCursor, nDataLen, nCursor ); // ----------------------------------------------------------------------- // Sanity check. Verify that the bytes of data we extracted match that of // what was expected. // ----------------------------------------------------------------------- assert( nCursor == nDataLen ); // --------------------------------- // Invoke derived function handler. // --------------------------------- retCode = Recv_HACCESSStatusInfo( &statusInfo ); // ----------------------------------------------- // Clean up allocated memory used for extraction. // ----------------------------------------------- FreeMappingStatus( statusInfo.haccess_devmap_statuses ); // Return completion code. return retCode; } } // namespace gogoc-1_2-RELEASE/gogoc-messaging/src/communicationsmgr.cc0100644000000000000000000004170611301542457022227 0ustar rootroot// ************************************************************************** // $Id: communicationsmgr.cc,v 1.1 2009/11/20 16:34:55 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Implementation of the CommunicationsManager class, // and the Sender and Receiver worker threads. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #include #include #include #include // -------------------------------------------- // -- GATEWAY6 CLIENT IPC CHANNEL: PIPE NAME -- // -------------------------------------------- #define COMMMGR_PIPE_NAME "\\\\.\\pipe\\gogocmessaging-ipc" #define INITERRORS_THRESHOLD 3 // Number of failed initialization berore giving up. namespace gogocmessaging { // -------------------------------------------------------------------------- // Function : CommunicationsManager constructor // // Description: // Will initialize a new CommunicationsManager object. // // Arguments: // aEMode: enum [IN], The communications manager operation mode. // aProcessor: MessageProcessor* [IN], A message receiver-derived class. // // Return values: (N/A) // // -------------------------------------------------------------------------- CommunicationsManager::CommunicationsManager( tManagerMode aEMode, MessageProcessor* aProcessor ) : MessageSender(), ThreadWrapper(), m_IPCServent( NULL ), m_MsgProcessor( aProcessor ), m_ReceiverThread( NULL ), m_SenderThread( NULL ), m_eManagerMode( aEMode ), m_nMsgSent(0), m_nMsgProcessed(0) { assert( aProcessor != NULL ); SetState( STATE_DISCONNECTED ); } // -------------------------------------------------------------------------- // Function : CommunicationsManager destructor // // Description: // Will stop working threads and clean-up space allocated during object // lifetime. // // Arguments: (none) // // Return values: (N/A) // // -------------------------------------------------------------------------- CommunicationsManager::~CommunicationsManager( void ) { // Stop the worker thread. Stop(); // Clean up instance and stop other threads. _CleanupInstance(); } // -------------------------------------------------------------------------- // Function : Initialize // // Description: // Will create the IPC Servent object depending on manager operation mode // and initialize the Servent object for future IO operations. // The receiver and sender worker threads will be initialized and started. // // Arguments: (none) // // Return values: // GOGOCM_UIS__NOERROR: On successful initialization. // any other error code on error. // // -------------------------------------------------------------------------- error_t CommunicationsManager::Initialize( void ) { error_t retCode; assert( m_eManagerStatus == STATE_PENDINGCONNECTION ); assert( m_IPCServent == NULL ); assert( m_SenderThread == NULL ); assert( m_ReceiverThread == NULL ); // ------------------------------------------------------------- // Create the IPC servent, depending on manager operation mode. // ------------------------------------------------------------- switch( m_eManagerMode ) { case CLIENT_MANAGER: m_IPCServent = new PipeClient( COMMMGR_PIPE_NAME ); break; case SERVER_MANAGER: m_IPCServent = new PipeServer( COMMMGR_PIPE_NAME ); break; } assert( m_IPCServent != NULL ); // --------------------------------------------------------------- // Initialize Servent oject: [ BLOCKING ] // In server mode, il will wait for a client to connect. // In client mode, it will wait for the server to be available. // --------------------------------------------------------------- if( (retCode = m_Servent.Initialize( m_IPCServent )) != 0 ) { DBG_PRINT( "Failed to Initialize server Servent object. Error code: " << setbase(16) << retCode << setbase(10) ); return retCode; } // --------------------------------- // Start the message sender thread. // See SenderThread::Work() // --------------------------------- m_SenderThread = new SenderThread( this ); m_SenderThread->Run(); // --------------------------------- // Start the message receiver thread. // See ReceiverThread::Work() // --------------------------------- m_ReceiverThread = new ReceiverThread( this ); m_ReceiverThread->Run(); return GOGOCM_UIS__NOERROR; } // -------------------------------------------------------------------------- // Function : _CleanupInstance [ PRIVATE ] // // Description: // Will stop working threads and clean-up space allocated during object // lifetime. // // Arguments: (none) // // Return values: (none) // // -------------------------------------------------------------------------- void CommunicationsManager::_CleanupInstance( void ) { // ---------------------------------------- // Stop Sender and Receiver threads first. // ---------------------------------------- if( m_SenderThread != NULL ) { m_SenderThread->Stop(); delete m_SenderThread; m_SenderThread = NULL; } if( m_ReceiverThread != NULL ) { m_ReceiverThread->Stop(); delete m_ReceiverThread; m_ReceiverThread = NULL; } // Deallocate IPC Servent object. if( m_IPCServent != NULL ) { m_IPCServent->UnInitialize(); delete m_IPCServent; m_IPCServent = NULL; } // Empty send queue and reset semaphore on SendQueue. MessageSender::Reset(); } // -------------------------------------------------------------------------- // Function : CommunicationsManager::Work [ THREAD ] // // Description: // This thread will monitor the state of the IPC layer components. // If a layer component should fail (e.g.: broken IPC, disconnection, etc), // a reinitialization will occur to re-establish connection and get back // online. // This function will exit if repetitive errors occurs. // // Arguments: (none) // // Return values: (none) // // -------------------------------------------------------------------------- void CommunicationsManager::Work( void ) { unsigned short nErrorCount=0; error_t retCode; DBG_PRINT( "Communications manager service thread started." ); // ------------------------------------------------ // Communications manager service management loop. // ------------------------------------------------ while( !ShouldStop() && GetState() != STATE_FATALERROR ) { // ------------------------------------------------------- // Check if current manager status is STATE_DISCONNECTED. // ------------------------------------------------------- if( GetState() == STATE_DISCONNECTED ) { // ------------------------------------------------------------ // Clean up IPC layer objects instances and ready for restart. // ------------------------------------------------------------ _CleanupInstance(); // ------------------------------ // Run initialization procedure. // ------------------------------ SetState( STATE_PENDINGCONNECTION ); if( (retCode = Initialize()) == GOGOCM_UIS__NOERROR ) { // Reset error count. nErrorCount = 0; // Successful initialization. SetState( STATE_CONNECTED ); } else { // ----------------------- // Failed initialization. // ----------------------- DBG_PRINT( "Failed Initialization." << endl << "Error code: " << setbase(16) << retCode << setbase(10) ); #ifdef WIN32 DBG_PRINT( "GetLastError() returned: " << GetLastError() ); #endif // Set manager state. if( ++nErrorCount > INITERRORS_THRESHOLD ) { // Maximum retries has been reached. Abandon reconnection. SetState( STATE_FATALERROR ); } else { SetState( STATE_DISCONNECTED ); // Wait 10 seconds before initiating next initialization. pal_sleep( 10000 ); } } } // Sleep for 300 ms before the next status check. pal_sleep( 300 ); } DBG_PRINT( "Communications manager service thread stopped." ); } // -------------------------------------------------------------------------- // Function : WaitReady // // Description: // Will wait `ulWaitms' miliseconds until the Servent object signals the // ready state. // The ready state is usually signalled when the underlying IPC layer // is ready to connect to a peer. // // Arguments: // ulWaitms: long [IN], The number of miliseconds to wait until ready state // is signalled. // // Return values: // true if ready state was signalled before the timeout. // false otherwise. // // -------------------------------------------------------------------------- bool CommunicationsManager::WaitReady( unsigned long ulWaitms ) { return m_Servent.WaitReady( ulWaitms ); } // -------------------------------------------------------------------------- // Function : GetState // // Description: // Will return the current status of the communications manager. // // Arguments: (none) // // Return values: // The state of the communications manager. // // -------------------------------------------------------------------------- tManagerStatus CommunicationsManager::GetState( void ) const { return m_eManagerStatus; } // -------------------------------------------------------------------------- // Function : SetState // // Description: // Will set the new manager status, and enable or disable the // MessageSender's queue. // // Arguments: // aState: manager status [IN], The new manager status. // // Return values: (none) // // -------------------------------------------------------------------------- void CommunicationsManager::SetState( const tManagerStatus aState ) { m_eManagerStatus = aState; // Accept or reject new messages in the send queue. MessageSender::m_eSenderState = ( m_eManagerStatus == STATE_CONNECTED ) ? STATE_ENABLED : STATE_DISABLED; } // -------------------------------------------------------------------------- // Function : GetStatistics // // Description: // Will return the current statistics about this instance. // // Arguments: // aStats: MANAGER_STATISTICS [IN,OUT], An allocated struct that will // contain the stats. // // Return values: (none) // // -------------------------------------------------------------------------- void CommunicationsManager::GetStatistics( MANAGER_STATISTICS* aStats ) { assert( aStats != NULL ); aStats->nMsgQueued = (unsigned int)m_SendQueue.size(); aStats->nMsgSent = m_nMsgSent; aStats->nMsgProcessed = m_nMsgProcessed; m_Servent.GetServentInfo( &(aStats->ServentInfo) ); } // -------------------------------------------------------------------------- // Function : SenderThread::Work [ THREAD ] // // Description: // This worker thread monitors the Communications Manager's send queue. // When a new message is available for sending, this thread will send it // to the other process, through the IPC layer. // // Arguments: (none) // // Return values: (none) // // -------------------------------------------------------------------------- void SenderThread::Work( void ) { Message* pMsg; error_t retCode; uint32_t nBytesSent; bool bCanRead; DBG_PRINT( "Starting Sender thread" ); while( !ShouldStop() ) { // --------------------------------------------------- // Wait for a message to be posted to the send queue. // --------------------------------------------------- if( m_CommMgr->m_pSemaphore->WaitAndLock(25) != 0 ) { // No message was available in 25 miliseconds. continue; } assert( m_CommMgr->m_SendQueue.size() > 0 ); // --------------------------------------------------------------- // Check if we've got enough buffer to send a message. // This is done by verifying if there are no incoming messages. // * Doing otherwise would end up in a race condition between the // sender and receiver threads. // This keeps the Servent receive buffer empty. // --------------------------------------------------------------- if( (retCode = m_CommMgr->m_Servent.CanRead( bCanRead )) != GOGOCM_UIS__NOERROR ) { // An error occured. DBG_PRINT( "IO error. Failed CanRead(). Error code: 0x" << setbase(16) << retCode << setbase(10) ); #ifdef WIN32 DBG_PRINT( "GetLastError() returned: " << GetLastError() ); #endif // Notify communications manager. Exit thread. m_CommMgr->SetState( STATE_DISCONNECTED ); break; } if( bCanRead ) { // Release lock on semaphore because we couldn't process queue message. m_CommMgr->m_pSemaphore->ReleaseLock(); pal_sleep( 20 ); // Wait for message to be read by the receiver thread. continue; } // ---------------------------------------------- // Retrieve message to be sent to the IPC layer. // ---------------------------------------------- pMsg = m_CommMgr->m_SendQueue.front(); assert( pMsg ); // --------------------------- // Send message over the IPC. // --------------------------- retCode = m_CommMgr->m_Servent.WriteData( (void*)pMsg->rawdata, pMsg->GetRawSize(), nBytesSent ); if( retCode != GOGOCM_UIS__NOERROR ) { // An error occured. DBG_PRINT( "Error sending data. Error code: 0x" << setbase(16) << retCode ); #ifdef WIN32 DBG_PRINT( "GetLastError() returned: " << setbase(10) << GetLastError() ); #endif // Notify communications manager. Exit thread. m_CommMgr->SetState( STATE_DISCONNECTED ); break; } // -------------------------------------------- // Verify if message has been sent completely. // -------------------------------------------- if( nBytesSent != pMsg->GetRawSize() ) { // ERROR: DBG_PRINT( "Failed to send all data. Sent " << nBytesSent << " bytes of data!" ); // Notify communications manager. Exit thread. m_CommMgr->SetState( STATE_DISCONNECTED ); break; } else { // Message has been sent successfully. Delete it. Message::FreeMessage( pMsg ); // Remove message from send queue. m_CommMgr->m_SendQueue.pop(); // Update counter. ++(m_CommMgr->m_nMsgSent); } } DBG_PRINT( "Exiting Sender thread" ); } // -------------------------------------------------------------------------- // Function : ReceiverThread::Work [ THREAD ] // // Description: // This worker thread monitors the IPC layer's Servent receive bufer. // If new data (messages) are available for reception, this thread will // extract and send them to the MessageProcessor for further processing. // // Arguments: (none) // // Return values: (none) // // -------------------------------------------------------------------------- void ReceiverThread::Work(void) { uint8_t recvBuffer[64260]; Message* pMsg; uint32_t nMessageLen; error_t retCode; bool bCanRead; DBG_PRINT( "Starting Receiver thread" ); while( !ShouldStop() ) { // ------------------------------------------------------------ // Verify if there are messages to be read from the IPC layer. // ------------------------------------------------------------ if( (retCode = m_CommMgr->m_Servent.CanRead( bCanRead )) != GOGOCM_UIS__NOERROR ) { // An error occured. DBG_PRINT( "IO error. Failed CanRead(). Error code: 0x" << setbase(16) << retCode << setbase(10) ); #ifdef WIN32 DBG_PRINT( "GetLastError() returned: " << GetLastError() ); #endif // Notify communications manager. Exit thread. m_CommMgr->SetState( STATE_DISCONNECTED ); break; } if( !bCanRead ) { pal_sleep( 25 ); // Wait for messages to be available. continue; } // ---------------------------------------------- // Read the incoming message from the IPC layer. // ---------------------------------------------- retCode = m_CommMgr->m_Servent.ReadData( (void*)recvBuffer, sizeof(recvBuffer), nMessageLen ); if( retCode != GOGOCM_UIS__NOERROR ) { // An error occured. DBG_PRINT( "Error sending data. Error code: 0x" << setbase(16) << retCode << setbase(10) ); #ifdef WIN32 DBG_PRINT( "GetLastError() returned: " << GetLastError() ); #endif // Notify communications manager. Exit thread. m_CommMgr->SetState( STATE_DISCONNECTED ); break; } // ------------------------------------------------ // Process the message using the message receiver. // ------------------------------------------------ pMsg = (Message*)recvBuffer; Message::AssertMessage( pMsg ); m_CommMgr->m_MsgProcessor->ProcessMessage( pMsg ); // Update the counter. ++(m_CommMgr->m_nMsgProcessed); } DBG_PRINT( "Exiting Receiver thread" ); } } // namespace gogoc-1_2-RELEASE/gogoc-messaging/src/gogoc_c_wrapper.cc0100644000000000000000000001536311301542457021631 0ustar rootroot// ************************************************************************** // $Id: gogoc_c_wrapper.cc,v 1.1 2009/11/20 16:34:55 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Implementation of the C function wrappers. // // Author: Charles Nepveu // // Creation Date: December 2006 // __________________________________________________________________________ // ************************************************************************** #include #include #include using namespace gogocmessaging; // The unique instance of the gogoCLIENT Messenger implementation object. static ClientMessengerImpl* pMessenger = NULL; // -------------------------------------------------------------------------- // Function : initialize_messaging // // Description: // Will instantiate the gogoCLIENT Messenger Impl object, thus providing // Messenger capabilities to this process. // This implementation ensures that only one messenger object exists at a // time. // // Arguments: (none) // // Return values: // GOGOCM_UIS__NOERROR: Successful completion. // GOGOCM_UIS_CWRAPALRDYINIT: Initialization procedure previously called. // // -------------------------------------------------------------------------- extern "C" error_t initialize_messaging( void ) { if( pMessenger != NULL ) return GOGOCM_UIS_CWRAPALRDYINIT; // Instantiate a new Client Messenger. pMessenger = new ClientMessengerImpl(); // It is preferable to wait until the worker threads of the // client messenger are ready. // -> Wait UP TO 750 miliseconds... pMessenger->WaitReady( 750 ); // Should be done within 1 or 2 ms. return GOGOCM_UIS__NOERROR; } // -------------------------------------------------------------------------- // Function : uninitialize_messaging // // Description: // Will destroy the gogoCLIENT Messenger Impl object, thus stopping // Messenger capabilities to this process. // // Arguments: (none) // // Return values: // GOGOCM_UIS__NOERROR: Successful completion. // GOGOCM_UIS_CWRAPNOTINIT: Messenger object had not been initialized. // // -------------------------------------------------------------------------- extern "C" error_t uninitialize_messaging( void ) { if( pMessenger == NULL ) return GOGOCM_UIS_CWRAPNOTINIT; delete pMessenger; pMessenger = NULL; return GOGOCM_UIS__NOERROR; } // -------------------------------------------------------------------------- // Function : send_status_info // // Description: // Sends status info to the GUI (or whichever client that's connected). // // Arguments: (none) // // Return values: // GOGOCM_UIS__NOERROR: Successful completion. // GOGOCM_UIS_CWRAPNOTINIT: Messenger not initialized. // // -------------------------------------------------------------------------- extern "C" error_t send_status_info( void ) { gogocStatusInfo* pStatusInfo = NULL; error_t retCode = GOGOCM_UIS__NOERROR; // Verify if messenger object has been initialized. if( pMessenger == NULL ) return GOGOCM_UIS_CWRAPNOTINIT; // Callback to the gogoCLIENT process, to gather required information. retCode = RetrieveStatusInfo( &pStatusInfo ); if( retCode == GOGOCM_UIS__NOERROR ) { // Send the tunnel info to the other side. pMessenger->Send_StatusInfo( pStatusInfo ); // Frees the memory used by the StatusInfo object. FreeStatusInfo( &pStatusInfo ); } return retCode; } // -------------------------------------------------------------------------- // Function : send_tunnel_info // // Description: // Sends tunnel info to the GUI (or whichever client that's connected). // // Arguments: (none) // // Return values: // GOGOCM_UIS__NOERROR: Successful completion. // GOGOCM_UIS_CWRAPNOTINIT: Messenger not initialized. // // -------------------------------------------------------------------------- extern "C" error_t send_tunnel_info( void ) { gogocTunnelInfo* pTunnelInfo = NULL; error_t retCode = GOGOCM_UIS__NOERROR; // Verify if messenger object has been initialized. if( pMessenger == NULL ) return GOGOCM_UIS_CWRAPNOTINIT; // Callback to the gogoCLIENT process, to gather required information. retCode = RetrieveTunnelInfo( &pTunnelInfo ); if( retCode == GOGOCM_UIS__NOERROR ) { // Send the tunnel info to the other side. pMessenger->Send_TunnelInfo( pTunnelInfo ); // Frees the memory used by the TunnelInfo object. FreeTunnelInfo( &pTunnelInfo ); } return retCode; } // -------------------------------------------------------------------------- // Function : send_broker_list // // Description: // Sends broker list to the GUI (or whichever client that's connected). // // Arguments: (none) // // Return values: // GOGOCM_UIS__NOERROR: Successful completion. // GOGOCM_UIS_CWRAPNOTINIT: Messenger not initialized. // // -------------------------------------------------------------------------- extern "C" error_t send_broker_list( void ) { gogocBrokerList* pBrokerList = NULL; error_t retCode = GOGOCM_UIS__NOERROR; // Verify if messenger object has been initialized. if( pMessenger == NULL ) return GOGOCM_UIS_CWRAPNOTINIT; // Callback to the gogoCLIENT process, to gather required information. retCode = RetrieveBrokerList( &pBrokerList ); if( retCode == GOGOCM_UIS__NOERROR ) { // Send the broker list to the other side. pMessenger->Send_BrokerList( pBrokerList ); // Frees the memory used by the BrokerList object. FreeBrokerList( &pBrokerList ); } return retCode; } // -------------------------------------------------------------------------- // Function : send_haccess_status_info // // Description: // Sends HACCESS status info to the GUI (or whichever client that's connected). // // Arguments: (none) // // Return values: // GOGOCM_UIS__NOERROR: Successful completion. // GOGOCM_UIS_CWRAPNOTINIT: Messenger not initialized. // // -------------------------------------------------------------------------- extern "C" error_t send_haccess_status_info( void ) { HACCESSStatusInfo* pHACCESSStatusInfo = NULL; error_t retCode = GOGOCM_UIS__NOERROR; // Verify if messenger object has been initialized. if( pMessenger == NULL ) return GOGOCM_UIS_CWRAPNOTINIT; // Callback to the gogoCLIENT process, to gather required information. retCode = RetrieveHACCESSStatusInfo( &pHACCESSStatusInfo ); if( retCode == GOGOCM_UIS__NOERROR ) { // Send the HACCESS status info to the other side. pMessenger->Send_HACCESSStatusInfo( pHACCESSStatusInfo ); // Frees the memory used by the HACCESSStatusInfo object. FreeHACCESSStatusInfo( &pHACCESSStatusInfo ); } return retCode; } gogoc-1_2-RELEASE/gogoc-messaging/src/gogocuistrings.c0100644000000000000000000001454611301542457021376 0ustar rootroot/* *********************************************************************** */ /* $Id: gogocuistrings.c,v 1.1 2009/11/20 16:34:55 jasminko Exp $ */ /* */ /* Copyright (c) 2007 gogo6 Inc. All rights reserved. */ /* */ /* LICENSE NOTICE: You may use and modify this source code only if you */ /* have executed a valid license agreement with gogo6 Inc. granting */ /* you the right to do so, the said license agreement governing such */ /* use and modifications. Copyright or other intellectual property */ /* notices are not to be removed from the source code. */ /* */ /* Description: */ /* Offers default UI string for errors and other. */ /* */ /* You may translate the strings herein as you wish. */ /* */ /* Author: Charles Nepveu */ /* */ /* Creation Date: November 2006 */ /* _______________________________________________________________________ */ /* *********************************************************************** */ #include /* Struct containing string IDs with the related string. */ typedef struct { error_t _id; const char* _str; } tgogocUIStrings; static const tgogocUIStrings gogocUIStrings[] = { { GOGOCM_UIS__NOERROR, "SUCCESS" }, // Should never log this, but... /* PIPE ERRORS */ { GOGOCM_UIS_WRITEPIPEFAILED, "Failed writing on the named pipe." }, { GOGOCM_UIS_PEEKPIPEFAILED, "Failed \"peeking\" IO status on named pipe." }, { GOGOCM_UIS_READPIPEFAILED, "Failed reading on the named pipe." }, { GOGOCM_UIS_PIPESERVERALRDUP, "Pipe server is already up." }, { GOGOCM_UIS_FAILCREATESERVERPIPE, "Failed creation of pipe server." }, { GOGOCM_UIS_CLIENTALRDYCONN, "Pipe client is already connected." }, { GOGOCM_UIS_CLIENTCONNFAILED, "Pipe client connection failed." }, { GOGOCM_UIS_PIPESVRDISCFAIL, "Pipe server disconnection failed." }, { GOGOCM_UIS_FAILCREATECLIENTPIPE, "Failed creation of client pipe." }, { GOGOCM_UIS_PIPECLIDISCFAIL, "Pipe client disconnection failed." }, /* IPC LAYER ERRORS */ { GOGOCM_UIS_BADPACKET, "Invalid/erroneous IPC data packet received." }, { GOGOCM_UIS_IPCDESYNCHRONIZED, "IPC communication desynchronized. Need re-initialization." }, { GOGOCM_UIS_PACKETSNOTORDERED, "ERROR, IPC sequential packet number is not ordered." }, { GOGOCM_UIS_READBUFFERTOOSMALL, "IPC layer internal buffer size too small to read data packet." }, { GOGOCM_UIS_SENDBUFFERTOOBIG, "User message data is too big to be sent through the IPC." }, { GOGOCM_UIS_IOWAITTIMEOUT, "Failed acquiring IO mutex to perform requested IPC operation." }, /* MESSAGING LAYER ERRORS */ { GOGOCM_UIS_MSGPROCDISABLED, "Message processing is disabled. Reception of messages is unavailable." }, { GOGOCM_UIS_MESSAGENOTIMPL, "Unknown message received. Processing for that message is not implemented." }, { GOGOCM_UIS_CWRAPALRDYINIT, "C language wrapper for messaging layer is already initialized." }, { GOGOCM_UIS_CWRAPNOTINIT, "C language wrapper for messaging layer is not implemented call initialize_messaging()." }, /* GATEWAY6 CLIENT ERRORS */ { GOGOCM_UIS_ERRUNKNOWN, "Unknown error." }, { GOGOCM_UIS_FAILEDBROKERLISTEXTRACTION, "Failed redirection broker list extraction." }, { GOGOCM_UIS_ERRCFGDATA, "Configuration data is invalid." }, { GOGOCM_UIS_ERRMEMORYSTARVATION, "Memory allocation error." }, { GOGOCM_UIS_ERRSOCKETIO, "Socket I/O error." }, { GOGOCM_UIS_ERRFAILSOCKETCONNECT, "Socket error, cannot connect." }, { GOGOCM_UIS_EVNTBROKERREDIRECTION, "A redirection has been received from the Gateway6." }, { GOGOCM_UIS_ERRBROKERREDIRECTION, "Redirection error." }, { GOGOCM_UIS_ERRTSPVERSIONERROR, "The Gateway6 is not supporting this TSP protocol version." }, { GOGOCM_UIS_ERRTSPGENERICERROR, "Generic TSP protocol error." }, { GOGOCM_UIS_ERRTUNMODENOTAVAILABLE, "The requested tunnel mode is not available on the Gateway6." }, { GOGOCM_UIS_ERRNOCOMMONAUTHENTICATION, "Authentication method is not supported by the Gateway6." }, { GOGOCM_UIS_ERRAUTHENTICATIONFAILURE, "Authentication failure." }, { GOGOCM_UIS_ERRBADTUNNELPARAM, "Bad tunnel parameters received from the Gateway6." }, { GOGOCM_UIS_ERRINTERFACESETUPFAILED, "Failed to execute tunnel configuration script." }, { GOGOCM_UIS_ERRKEEPALIVETIMEOUT, "A keepalive timeout occurred." }, { GOGOCM_UIS_ERRKEEPALIVEERROR, "A keepalive network error occurred." }, { GOGOCM_UIS_ERRTUNNELIO, "Internal tunnel I/O error." }, { GOGOCM_UIS_ERRTUNLEASEEXPIRED, "The tunnel lease has expired." }, { GOGOCM_UIS_ERRHACCESSSETUP, "The HACCESS setup script did not complete successfully." }, { GOGOCM_UIS_ERRHACCESSEXPOSEDEVICES, "The HACCESS subsystem could not apply the HomeAccess configuration successfully." }, { GOGOCM_UIS_ERRTSPSERVERTOOBUSY, "The Gateway6 is too busy to handle your TSP session. Please retry later." }, { GOGOCM_UIS_ERRINVALSERVERADDR, "The Gateway6 address is invalid." } }; // -------------------------------------------------------------------------- // Function : get_mui_string // // Description: // Returns the user interface string specified by the id. // // Arguments: // id: int [IN], The string ID. // // Return values: // The UI string. // // Exceptions: (none) // // -------------------------------------------------------------------------- const char* get_mui_string( const error_t id ) { const unsigned int n = sizeof(gogocUIStrings) / sizeof(gogocUIStrings[0]); unsigned int i; for(i=0; i #include namespace gogocmessaging { // -------------------------------------------------------------------------- // Function : GUIMessengerImpl constructor // // Description: // Will initialize a new GUIMessengerImpl object. // // Arguments: (none) // // Return values: (N/A) // // -------------------------------------------------------------------------- GUIMessengerImpl::GUIMessengerImpl( void ) : ClientMsgSender(), ClientMsgTranslator(), m_RecvStatusInfo(NULL), m_RecvTunnelInfo(NULL), m_RecvBrokerList(NULL), m_RecvHACCESSStatusInfo(NULL), m_CommManager( CLIENT_MANAGER, this ) { // Message processing is enabled by default in ClientMsgTranslator. m_CommManager.Run(); } // -------------------------------------------------------------------------- // Function : GUIMessengerImpl destructor // // Description: // Will clean-up space allocated during object lifetime. // // Arguments: (none) // // Return values: (N/A) // // -------------------------------------------------------------------------- GUIMessengerImpl::~GUIMessengerImpl( void ) { } // -------------------------------------------------------------------------- // Function : DisableProcessing // // Description: // Will disable message processing. Incoming messages will be dropped. // Useful when you want callbacks to stop being invoked. // NOTE: This does not disable message sending. // // Arguments: (none) // // Return values: (none) // // -------------------------------------------------------------------------- void GUIMessengerImpl::DisableProcessing( void ) { MessageProcessor::m_eProcessorState = STATE_DISABLED; } // -------------------------------------------------------------------------- // Function : EnableProcessing // // Description: // Will enable(resume) message processing. // // Arguments: (none) // // Return values: (none) // // -------------------------------------------------------------------------- void GUIMessengerImpl::EnableProcessing( void ) { MessageProcessor::m_eProcessorState = STATE_ENABLED; } // -------------------------------------------------------------------------- // Function : Recv_StatusInfo // // Description: // Invoked upon reception of a StatusInfo message from the Communications // Manager. The information contains the GOGOClient status. // // Arguments: // aStatusInfo: gogocStatusInfo* [IN], The client status. // // Return values: // GOGOCM_UIS__NOERROR: Indicates success replying to request. // // -------------------------------------------------------------------------- error_t GUIMessengerImpl::Recv_StatusInfo( const gogocStatusInfo* aStatusInfo ) { // Callback the provided function. if( m_RecvStatusInfo != NULL ) (*m_RecvStatusInfo)( aStatusInfo ); return GOGOCM_UIS__NOERROR; } // -------------------------------------------------------------------------- // Function : Recv_TunnelInfo // // Description: // Invoked upon reception of a TunnelInfo message from the Communications // Manager. The information contains the GOGOClient tunnel info. // // Arguments: // aTunnelInfo: gogocTunnelInfo* [IN], The tunnel information. // // Return values: // GOGOCM_UIS__NOERROR: Indicates success replying to request. // // -------------------------------------------------------------------------- error_t GUIMessengerImpl::Recv_TunnelInfo( const gogocTunnelInfo* aTunnelInfo ) { // Callback the provided function. if( m_RecvTunnelInfo != NULL ) (*m_RecvTunnelInfo)(aTunnelInfo); return GOGOCM_UIS__NOERROR; } // -------------------------------------------------------------------------- // Function : Recv_BrokerList // // Description: // Invoked upon reception of a BrokerList message from the Communications // Manager. The information contains the GOGOClient list of brokers. // // Arguments: // aBrokerList: gogocBrokerList* [IN], The list of brokers. // // Return values: // GOGOCM_UIS__NOERROR: Indicates success replying to request. // // -------------------------------------------------------------------------- error_t GUIMessengerImpl::Recv_BrokerList( const gogocBrokerList* aBrokerList ) { // Callback the provided function. if( m_RecvBrokerList != NULL ) (*m_RecvBrokerList)(aBrokerList); return GOGOCM_UIS__NOERROR; } // -------------------------------------------------------------------------- // Function : Recv_HACCESSStatusInfo // // Description: // Invoked upon reception of a BrokerList message from the Communications // Manager. The information contains the statuses of the HACCESS features. // // Arguments: // aBrokerList: aHACCESSStatusInfo* [IN], The HACCESS status information. // // Return values: // GOGOCM_UIS__NOERROR: Indicates success replying to request. // // -------------------------------------------------------------------------- error_t GUIMessengerImpl::Recv_HACCESSStatusInfo( const HACCESSStatusInfo* aHACCESSStatusInfo ) { // Callback the provided function. if( m_RecvHACCESSStatusInfo != NULL ) (*m_RecvHACCESSStatusInfo)(aHACCESSStatusInfo); return GOGOCM_UIS__NOERROR; } // -------------------------------------------------------------------------- // Function : PostMessage // // Description: // Will post a message to the send queue for sending. // // Arguments: // pMsg: Message* [IN], The message to post. // // Return values: (none) // // -------------------------------------------------------------------------- void GUIMessengerImpl::PostMessage( Message* pMsg ) { MessageSender* pSender = (MessageSender*) &m_CommManager; pSender->PostMessage( pMsg ); } } // namespace gogoc-1_2-RELEASE/gogoc-messaging/src/ipcclient.cc0100644000000000000000000000635711301542460020440 0ustar rootroot// ************************************************************************** // $Id: ipcclient.cc,v 1.1 2009/11/20 16:34:56 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Implementation of the IPCClient class. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #include #include #include namespace gogocmessaging { // -------------------------------------------------------------------------- // Function : IPCClient constructor // // Description: // Will initialize a new IPCClient object. // // Arguments: (none) // // Return values: (N/A) // // -------------------------------------------------------------------------- IPCClient::IPCClient( void ) : IPCServent() { // Semaphore is locked initially. m_pSemReadyState = new Semaphore( 1, 0 ); assert( m_pSemReadyState != NULL ); } // -------------------------------------------------------------------------- // Function : IPCClient destructor // // Description: // Will clean-up space allocated during object lifetime. // // Arguments: (none) // // Return values: (N/A) // // -------------------------------------------------------------------------- IPCClient::~IPCClient( void ) { if( m_pSemReadyState != NULL ) { delete m_pSemReadyState; m_pSemReadyState = NULL; } } // -------------------------------------------------------------------------- // Function : Initialize // // Description: // Will initialize the IPC client by connecting to the IPC server. // // Arguments: (none) // // Return values: // See Connect() specialization. // // -------------------------------------------------------------------------- error_t IPCClient::Initialize( void ) { // Signal the ready state before blocking on connect. m_pSemReadyState->ReleaseLock(); return Connect(); } // -------------------------------------------------------------------------- // Function : UnInitialize // // Description: // Will terminate the connection with the IPC server and shut down. // // Arguments: (none) // // Return values: // See Disconnect() specialization. // // -------------------------------------------------------------------------- error_t IPCClient::UnInitialize( void ) { return Disconnect(); } // -------------------------------------------------------------------------- // Function : WaitReady // // Description: // Will wait until the m_pSemReadyState semaphore is released. // The semaphore is released when the client is ready to connect // to the peer IPC server. // // Arguments: // ulWaitms: unsigned long [IN], The timeout for the wait operation. // If 0, the timeout is INFINITE. // // Return values: // Returns true if the semaphore is released before the specified timeout. // // -------------------------------------------------------------------------- bool IPCClient::WaitReady( unsigned long ulWaitms ) { bool bRetVal; if( (bRetVal = m_pSemReadyState->WaitAndLock( ulWaitms ) == 0) ) m_pSemReadyState->ReleaseLock(); return bRetVal; } } gogoc-1_2-RELEASE/gogoc-messaging/src/ipcserver.cc0100644000000000000000000000703511301542460020462 0ustar rootroot// ************************************************************************** // $Id: ipcserver.cc,v 1.1 2009/11/20 16:34:56 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Implementation of the IPCServer class. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #include #include #include namespace gogocmessaging { // -------------------------------------------------------------------------- // Function : IPCServer constructor // // Description: // Will initialize a new IPCServer object. // // Arguments: (none) // // Return values: (N/A) // // -------------------------------------------------------------------------- IPCServer::IPCServer( void ) : IPCServent() { // Semaphore is locked initially. m_pSemReadyState = new Semaphore( 1, 0 ); assert( m_pSemReadyState != NULL ); } // -------------------------------------------------------------------------- // Function : IPCServer destructor // // Description: // Will clean-up space allocated during object lifetime. // // Arguments: (none) // // Return values: (N/A) // // -------------------------------------------------------------------------- IPCServer::~IPCServer( void ) { if( m_pSemReadyState != NULL ) { delete m_pSemReadyState; m_pSemReadyState = NULL; } } // -------------------------------------------------------------------------- // Function : Initialize // // Description: // Will initialize the IPC Server by setting up a connection and waiting // for an IPC client to connect. // // Arguments: (none) // // Return values: // GOGOCM_UIS__NOERROR on success // See CreateConnectionPoint() and AcceptConnection() specializations. // // -------------------------------------------------------------------------- error_t IPCServer::Initialize( void ) { error_t nRetCode; if( (nRetCode = CreateConnectionPoint()) == GOGOCM_UIS__NOERROR ) { // SIGNAL THE READY STATE m_pSemReadyState->ReleaseLock(); return AcceptConnection(); } return nRetCode; } // -------------------------------------------------------------------------- // Function : UnInitialize // // Description: // Will terminate the connection with the IPC client and shut down. // // Arguments: (none) // // Return values: // GOGOCM_UIS__NOERROR on success // See CloseConnection() specialization. // // -------------------------------------------------------------------------- error_t IPCServer::UnInitialize( void ) { return CloseConnection(); } // -------------------------------------------------------------------------- // Function : WaitReady // // Description: // Will wait until the m_pSemReadyState semaphore is released. // The semaphore is released when the server has created the connection // point and is ready to accept incomming connection(s). // // Arguments: // ulWaitms: unsigned long [IN], The timeout for the wait operation. // If 0, the timeout is INFINITE. // // Return values: // Returns true if the semaphore is released before the specified timeout. // // -------------------------------------------------------------------------- bool IPCServer::WaitReady( unsigned long ulWaitms ) { bool bRetVal; if( bRetVal = (m_pSemReadyState->WaitAndLock( ulWaitms ) == 0) ) m_pSemReadyState->ReleaseLock(); return bRetVal; } } gogoc-1_2-RELEASE/gogoc-messaging/src/message.cc0100644000000000000000000000645311301542460020107 0ustar rootroot// ************************************************************************** // $Id: message.cc,v 1.1 2009/11/20 16:34:56 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Implementation of the Message union. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #include #include #include namespace gogocmessaging { // -------------------------------------------------------------------------- // Function : CreateMessage [ STATIC ] // // Description: // Will create a new Message object. // // Arguments: // aMsgId: uint16_t [IN], The message identifier. // aDataLen: uint16_t [IN], The length of data pointed by `aData'. // aData: uint8_t* [IN], The message data. // // Return values: // Pointer to newly created message. NULL is returned on error. // // -------------------------------------------------------------------------- Message* Message::CreateMessage( const uint16_t aMsgId, const uint32_t aDataLen, const uint8_t* aData ) { const uint32_t cnMsgSize = (MSG_HEADER_LEN) + aDataLen; Message* pMsg = NULL; // Only create messages that are within message data length bounds. if( aDataLen < MSG_MAX_USERDATA ) { // Create enough space to copy user data. pMsg = (Message*) new uint8_t[ cnMsgSize ]; assert( pMsg != NULL ); // Set message members. pMsg->msg.header._msgid = aMsgId; pMsg->msg.header._datalen = (uint16_t)aDataLen; memcpy( pMsg->msg._data, aData, aDataLen ); } // return the new message. return pMsg; } // -------------------------------------------------------------------------- // Function : FreeMessage [ static ] // // Description: // Will delete the space used by the message. // // Arguments: // pMsg: Message* [IN,OUT], The message to be deleted. // // Return values: (none) // // -------------------------------------------------------------------------- void Message::FreeMessage( Message* pMsg ) { uint8_t* pBuf = (uint8_t*)pMsg; delete [] pBuf; pMsg = NULL; } // -------------------------------------------------------------------------- // Function : AssertMessage [ static ] // // Description: // Will perform verification on the message content. // // Arguments: // pMsg: Message* [IN], The message to be verified. // // Return values: // // // -------------------------------------------------------------------------- void Message::AssertMessage( const Message* pMsg ) { assert( pMsg->msg.header._datalen <= MSG_MAX_USERDATA ); } // -------------------------------------------------------------------------- // Function : GetRawSize // // Description: // Will return the byte size of the data managed by this class: // - Message header length + user data length. // This is useful to know the amount of bytes to copy from member `rawdata'. // // Arguments: (none) // // Return values: // The size of this class' data. // // -------------------------------------------------------------------------- uint32_t Message::GetRawSize( void ) const { return (MSG_HEADER_LEN) + this->msg.header._datalen; } } gogoc-1_2-RELEASE/gogoc-messaging/src/messagesender.cc0100644000000000000000000000564211301542460021307 0ustar rootroot// ************************************************************************** // $Id: messagesender.cc,v 1.1 2009/11/20 16:34:56 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Implementation of the MessageSender class. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #include #include #define MAX_QUEUE_ITEMS 512 namespace gogocmessaging { // -------------------------------------------------------------------------- // Function : MessageSender constructor // // Description: // Will initialize a new MessageSender object. // // Arguments: (none) // // Return values: (N/A) // // -------------------------------------------------------------------------- MessageSender::MessageSender( void ) : m_eSenderState( STATE_DISABLED ), m_pSemaphore(NULL) { assert( m_SendQueue.empty() ); // Create a semaphore. m_pSemaphore = new Semaphore( MAX_QUEUE_ITEMS, 0 ); assert( m_pSemaphore != NULL ); } // -------------------------------------------------------------------------- // Function : MessageSender destructor // // Description: // Will clean-up space allocated during object lifetime. // // Arguments: (none) // // Return values: (N/A) // // -------------------------------------------------------------------------- MessageSender::~MessageSender( void ) { if( m_pSemaphore != NULL ) { delete m_pSemaphore; m_pSemaphore = NULL; } } // -------------------------------------------------------------------------- // Function : PostMessage // // Description: // Will put the message in the send queue for further processing, only if // the state is enabled. // // Arguments: // pMsg: Message* [IN], The message to post. // // Return values: (none) // // -------------------------------------------------------------------------- void MessageSender::PostMessage( Message* pMsg ) { if( m_eSenderState == STATE_ENABLED && m_SendQueue.size() < MAX_QUEUE_ITEMS ) { m_SendQueue.push( pMsg ); m_pSemaphore->ReleaseLock(); // Increase semaphore count. } } // -------------------------------------------------------------------------- // Function : Reset // // Description: // Resets the MessageSender. Empties send queue and re-initializes the // semaphore object. // // Arguments: // pMsg: Message* [IN], The message to post. // // Return values: (none) // // -------------------------------------------------------------------------- void MessageSender::Reset( void ) { // Empty queue while( !m_SendQueue.empty() ) m_SendQueue.pop(); // Reset semaphore object if( m_pSemaphore != NULL ) delete m_pSemaphore; m_pSemaphore = new Semaphore( MAX_QUEUE_ITEMS, 0 ); } } gogoc-1_2-RELEASE/gogoc-messaging/src/servent.cc0100644000000000000000000006177011301542460020154 0ustar rootroot// ************************************************************************** // $Id: servent.cc,v 1.1 2009/11/20 16:34:56 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Implementation of the Servent class. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #include #include #include #include #define MUTEX_TIMEOUT 15000 // 15 seconds. // -------------------------------------------------------------------------- // Packet: // Packets are the raw data units sent through this IPC implementation. // They are formed up of a header, and the user data. // This implementation keeps the size of individual packets under 1024. // // The maximum of user data transferable is 63 * 1020 = 64260 bytes. // - 63 possible fragments of user data. // - 1020 bytes of user data per packet MAX. // struct PACKET_HEADER // 32 bit packet header. { uint8_t _header : 4; // Packet header: fixed value: 1010 uint8_t _msgtype : 6; // Message type: 0x00 to 0x3F uint8_t _seq : 6; // Sequence number: 0-63 uint8_t _fragseq : 6; // Fragment sequence number: 0-63 uint16_t _datalen :10; // User data length: 0-1023 (1020) }; #if defined(WIN32) || defined(WINCE) #pragma warning( disable: 4200 ) #endif struct PACKET // Maximum length of packet: 1024 bytes. { PACKET_HEADER _header; // 32 bit packet header. uint8_t _data[0]; // Data label. }; #if defined(WIN32) || defined(WINCE) #pragma warning( default: 4200 ) #endif #define PKT_HEADER_FIXEDVALUE 0x0A // Hexa for binary 1010. // Values 0x00-0x1F are RESERVED. #define PKT_MSGTYPE_NONFRAGDATA 0x20 // Non-fragmented data #define PKT_MSGTYPE_FRAGDATAFIRST 0x21 // Data, first fragment #define PKT_MSGTYPE_FRAGDATA 0x22 // Data, fragment #define PKT_MSGTYPE_FRAGDATALAST 0x23 // Data, last fragment // Values 0x24-0x3F for future protocol expansion. // User data max length(2^10): limited by PACKET_HEADER::_datalen #define PKT_USERDATA_MAX 1020 // Maximum user data per packet #define MAX_USERDATA 64260 // Prototypes uint32_t MakePacket( PACKET** ppPkt, const void* pvData, const uint32_t nDataSize, int eMsgType, uint16_t nSeqNum, uint16_t nFragSeqNum ); uint32_t ExtractPacketData( const PACKET* pPkt, uint8_t* pUserData, int* eMsgType, uint16_t* nSeqNum, uint16_t* nFragSeqNum ); void FreePacket( PACKET** pPkt ); void PrintPacket( const PACKET* pPkt ); // DEBUG ONLY. // -------------------------------------------------------------------------- namespace gogocmessaging { // -------------------------------------------------------------------------- // Function : Servent constructor // // Description: // Will initialize a new Servent object. // // Arguments: (none) // // Return values: (N/A) // // -------------------------------------------------------------------------- Servent::Servent( void ) : m_pIPCServent(NULL), m_nTtlBytesRead(0), m_nTtlBytesWritten(0), m_pSemIPCMutex(NULL) { // This mutex is created to serialize IO operations on the IPC Servent. // For thread safety. m_pSemIPCMutex = new Semaphore(); assert( m_pSemIPCMutex != NULL ); } // -------------------------------------------------------------------------- // Function : Servent destructor // // Description: // Will clean-up space allocated during object lifetime. // // Arguments: (none) // // Return values: (N/A) // // -------------------------------------------------------------------------- Servent::~Servent( void ) { if( m_pSemIPCMutex != NULL ) { delete m_pSemIPCMutex; m_pSemIPCMutex = NULL; } } // -------------------------------------------------------------------------- // Function : Initialize // // Description: // Will initialize the IPCServent object referenced passed, and keep a copy // of that object for future use. // // Arguments: (none) // // Return values: // GOGOCM_UIS__NOERROR: Operation successful. // Any other value is an error. // // -------------------------------------------------------------------------- error_t Servent::Initialize( IPCServent* pIPCServent ) { error_t retCode; assert( pIPCServent != NULL ); // Initialize the IPCServent. m_pIPCServent = pIPCServent; if( (retCode = m_pIPCServent->Initialize()) != GOGOCM_UIS__NOERROR ) m_pIPCServent = NULL; // Return initialization return code. return retCode; } // -------------------------------------------------------------------------- // Function : WaitReady [ Run in another thread ] // // Description: // This function will wait `ulWaitms' miliseconds, or until the // IPCServent signals the ready state. // Usually, the IPC Servent signal its ready state when it is ready // to accept connections(IPCServer) or connect to a server(IPCClient). // // Arguments: // ulWaitms: unsigned long [IN], The time in miliseconds to wait for the // ready state to be signalled. // // Return values: // Returns true if the ready state is signalled before the timeout. // // -------------------------------------------------------------------------- bool Servent::WaitReady( unsigned long ulWaitms ) { unsigned long wait = 0; // Wait until the ipc servent is set (see Initialize). while( m_pIPCServent == NULL && ( (wait < ulWaitms) || (ulWaitms==0)) ) { pal_sleep(25); wait += 25; } // Check on it. if( m_pIPCServent != NULL ) return m_pIPCServent->WaitReady( ulWaitms - wait ); return false; } // -------------------------------------------------------------------------- // Function : ReadData // // Description: // Will acquire IO mutex object and perform the read operation. // Increments counter of bytes received. // // Arguments: // GOGOCM_UIS_IOWAITTIMEOUT: Failed acquiring IO mutex. Might be another // thread is doing a lengthy IO operation. Or a bug. // (see _ReadData) // // Return values: // (see _ReadData) // // -------------------------------------------------------------------------- error_t Servent::ReadData( void* pvReadBuffer, const uint32_t nBufferSize, uint32_t& nRead ) { error_t retCode; // --------------------------------------- // Acquire mutex handle for IO operation. // --------------------------------------- if( m_pSemIPCMutex->WaitAndLock( MUTEX_TIMEOUT ) == 0 ) { // Perform IO operation. retCode = _ReadData( pvReadBuffer, nBufferSize, nRead ); // Release mutex. m_pSemIPCMutex->ReleaseLock(); // Add the number of bytes received to the total. m_nTtlBytesRead += ( retCode == GOGOCM_UIS__NOERROR ) ? nRead : 0; } else retCode = GOGOCM_UIS_IOWAITTIMEOUT; return retCode; } // -------------------------------------------------------------------------- // Function : WriteData // // Description: // Will acquire IO mutex object and perform the write operation. // Increments counter of bytes sent. // // Arguments: // (see _WriteData) // // Return values: // GOGOCM_UIS_IOWAITTIMEOUT: Failed acquiring IO mutex. Might be another // thread is doing a lengthy IO operation. Or a bug. // (see _WriteData) // // -------------------------------------------------------------------------- error_t Servent::WriteData( const void* pvData, const uint32_t nDataSize, uint32_t& nWritten ) { error_t retCode; // --------------------------------------- // Acquire mutex handle for IO operation. // --------------------------------------- if( m_pSemIPCMutex->WaitAndLock( MUTEX_TIMEOUT ) == 0 ) { // Perform IO operation. retCode = _WriteData( pvData, nDataSize, nWritten ); // Release mutex. m_pSemIPCMutex->ReleaseLock(); // Add the number of bytes sent to the total. m_nTtlBytesWritten += ( retCode == GOGOCM_UIS__NOERROR ) ? nWritten : 0; } else retCode = GOGOCM_UIS_IOWAITTIMEOUT; return retCode; } // -------------------------------------------------------------------------- // Function : CanRead // // Description: // Will verify if data is available for reception. This indicates that // a ReadData call should not block. // // Arguments: // bCanRead: boolean [OUT], Indicates if we can perform a non-blocking // read operation. // // Return values: // GOGOCM_UIS__NOERROR: Indicates success. // Any other value is an error code. // // -------------------------------------------------------------------------- error_t Servent::CanRead( bool& bCanRead ) { error_t retCode = GOGOCM_UIS__NOERROR; assert( m_pIPCServent ); bCanRead = false; // --------------------------------------- // Acquire mutex handle for IO operation. // --------------------------------------- if( m_pSemIPCMutex->WaitAndLock( MUTEX_TIMEOUT ) == 0 ) { // Delegate to the IPC layer. retCode = m_pIPCServent->CanRead( bCanRead ); // Release mutex. m_pSemIPCMutex->ReleaseLock(); } return retCode; } // -------------------------------------------------------------------------- // Function : CanWrite // // Description: // Will verify if a write operation will block or not. // NOTE: This function may not be reliable. Verify if read buffer is empty // as an alternative. // // Arguments: // bCanWrite: boolean [OUT], Indicates if we can perform a non-blocking // write operation. // // Return values: // GOGOCM_UIS__NOERROR: Indicates success. // Any other value is an error code. // // -------------------------------------------------------------------------- error_t Servent::CanWrite( bool& bCanWrite ) { error_t retCode = GOGOCM_UIS__NOERROR; assert( m_pIPCServent ); bCanWrite = false; // --------------------------------------- // Acquire mutex handle for IO operation. // --------------------------------------- if( m_pSemIPCMutex->WaitAndLock( MUTEX_TIMEOUT ) == 0 ) { // Delegate to the IPC layer. retCode = m_pIPCServent->CanWrite( bCanWrite ); // Release mutex. m_pSemIPCMutex->ReleaseLock(); } return retCode; } #define INVALID_SEQNUM 99 // -------------------------------------------------------------------------- // Function : _ReadData [ PRIVATE ] // // Description: // Will attempt to read data from the IPC. // This function should not block if a Servent::CanRead() has been tested // before invoking this function. // // Arguments: // pvReadBuffer: void* [OUT], The receiving buffer. // nBufferSize: int [IN], The size in bytes allocated for read at the // receive buffer. // nRead: uint32_t [OUT], The number of bytes read from the IPC. // // Return values: // GOGOCM_UIS__NOERROR: Operation successful. // GOGOCM_UIS_BADPACKET: Received bad data. // GOGOCM_UIS_READBUFFERTOOSMALL: not enough buffer size to receive entire message. // GOGOCM_UIS_PACKETSNOTORDERED: Message fragments are disordered. // GOGOCM_UIS_IPCDESYNCHRONIZED: Major error. De-synchronization detected. Re-initiate connection. // // -------------------------------------------------------------------------- error_t Servent::_ReadData( void* pvReadBuffer, const uint32_t nBufferSize, uint32_t& nRead ) { uint32_t nBytesRead; // Number of bytes read from the IPC channel (packet length). uint32_t nDataLen; // User data length extracted from packet. uint16_t nSeqNum, nLastSeqNum; // Message sequence number: 0-63. uint16_t nFragSeqNum, nLastFragSeqNum; // Fragment sequence number: 0-63. int nMessageType = 0; // Message type (see packet info). uint8_t pRecvBuf[offsetof(PACKET, _data) + PKT_USERDATA_MAX];// Buffer for received packet. uint8_t pUDataBuf[PKT_USERDATA_MAX]; // User data extracted from packet. error_t retCode; // Return code. bool bCanRead; // Indicates if read operation will block or not. assert( m_pIPCServent != NULL ); // Initialize local variables. nLastFragSeqNum = nLastSeqNum = INVALID_SEQNUM; nRead = 0; // Reset total message bytes counter. do { // -------------------------------------- // Verify if data is available for read. // -------------------------------------- if( (retCode = m_pIPCServent->CanRead( bCanRead )) != GOGOCM_UIS__NOERROR ) { // Error checking if we can read. return retCode; } if( !bCanRead ) { pal_sleep(33); // Sleep 33 milliseconds. continue; } // Reset number of user data extracted from packet. nDataLen = 0; // ---------------------------------- // Read packet from the IPC channel. // ---------------------------------- retCode = m_pIPCServent->Read( (void*)pRecvBuf, sizeof(pRecvBuf), nBytesRead ); if( retCode == GOGOCM_UIS__NOERROR && nBytesRead > 0 ) { // -------------------------------------------------------------------- // Extract user data from packet, and put it into temporary user data // buffer. // -------------------------------------------------------------------- nDataLen = ExtractPacketData( (PACKET*)pRecvBuf, pUDataBuf, &nMessageType, &nSeqNum, &nFragSeqNum ); if( nDataLen == 0 ) { // Bad packet or invalid data. return GOGOCM_UIS_BADPACKET; } // ---------------------------------------------------- // Verify that message sequence number hasn't changed. // ---------------------------------------------------- if( nLastSeqNum != INVALID_SEQNUM && nSeqNum != nLastSeqNum ) { // Message sequence number change (meaning we've got another message). // This should NOT happen in this logic. // End of earlier message should have been detected before changing // message. // This is a serious error, as this packet data will be lost and // a de-synchronization will now occur forever... return GOGOCM_UIS_IPCDESYNCHRONIZED; } else nLastSeqNum = nSeqNum; // ------------------------------------------------------------ // Verify that message fragment sequence number is sequential. // ------------------------------------------------------------ if( nLastFragSeqNum != INVALID_SEQNUM && nFragSeqNum != (nLastFragSeqNum + 1) ) { // Message fragments are not ordered. // ASSERTION: Pipe IPCs are assumed fifo. If using an IPC // other than pipe, correct this logic to allow // packet fragment re-ordering. return GOGOCM_UIS_PACKETSNOTORDERED; } else nLastFragSeqNum = nFragSeqNum; // -------------------------------------------------------------------- // Verify that user data read won't overflow the provided read buffer. // -------------------------------------------------------------------- if( (nRead + nDataLen) > nBufferSize ) { // User did not provide enough buffer size to receive entire message. return GOGOCM_UIS_READBUFFERTOOSMALL; } // ----------------------------------------- // Append user data to the provided buffer. // ----------------------------------------- memcpy( ((uint8_t*)pvReadBuffer) + nRead, pUDataBuf, nDataLen ); // Increase the number of user data bytes received. nRead += nDataLen; } } while( retCode == GOGOCM_UIS__NOERROR && nMessageType != PKT_MSGTYPE_NONFRAGDATA && nMessageType != PKT_MSGTYPE_FRAGDATALAST ); // Read operation finished. return retCode; } // -------------------------------------------------------------------------- // Function : _WriteData [ PRIVATE ] // // Description: // Will send user data over IPC. // ATTENTION: This function WILL block if the outgoing buffer is full. // It will block until the other side of the pipe has read // enough to free the write buffer. // In this implementation, you should wait until the read buffer // of this end of the pipe is empty, before trying a write // operation. (THREADS) // // Arguments: // pvData: void* [IN], The user data. // nDataSize: int [IN], The size in bytes of the user data. // // Return values: // GOGOCM_UIS__NOERROR: Operation successful. // GOGOCM_UIS_SENDBUFFERTOOBIG: user data is too big. // // -------------------------------------------------------------------------- error_t Servent::_WriteData( const void* pvData, const uint32_t nDataSize, uint32_t& nWritten ) { PACKET* pPkt = NULL; uint32_t nSent; // Number of bytes sent by the Write method. (this includes the packet header). uint32_t nToSend; // Number of bytes that will be sent in the next packet. uint32_t nPacketLen; // Size of packet (user data + header). static uint16_t nSeqNum=0; // Message sequence number: 0-63. uint16_t nFragSeqNum; // Fragment sequence number: 0-63. int nMessageType; // Message type (see packet info). error_t retCode=GOGOCM_UIS__NOERROR; // Return code bool bCanWrite; // Indicates if a read operation is possible. assert( m_pIPCServent != NULL ); // Simple check to verify that user data is not too big. if( nDataSize > MAX_USERDATA ) return GOGOCM_UIS_SENDBUFFERTOOBIG; nWritten = 0; // Reset total number of bytes sent. nFragSeqNum = 0; // Reset fragment sequence number. while( nWritten < nDataSize ) { // ------------------------------------------ // Check if we can write to the IPC channel. // ------------------------------------------ if( (retCode = m_pIPCServent->CanWrite( bCanWrite )) != GOGOCM_UIS__NOERROR ) { // Error checking if we can write. return retCode; } if( !bCanWrite ) { pal_sleep(33); // Sleep 33 milliseconds. continue; } // ------------------------------------------------------ // Compute the size of user data to send in this packet. // ------------------------------------------------------ nToSend = nDataSize - nWritten; if( nToSend > PKT_USERDATA_MAX ) { // Need to fragment data. nToSend = PKT_USERDATA_MAX; nMessageType = (nFragSeqNum==0) ? PKT_MSGTYPE_FRAGDATAFIRST : PKT_MSGTYPE_FRAGDATA; } else nMessageType = (nFragSeqNum==0) ? PKT_MSGTYPE_NONFRAGDATA : PKT_MSGTYPE_FRAGDATALAST; // ---------------------------------------------- // Build the packet (User data + Packet header). // ---------------------------------------------- nPacketLen = MakePacket( &pPkt, (void*)(((uint8_t*)pvData) + nWritten), nToSend, nMessageType, nSeqNum, nFragSeqNum ); assert( pPkt != NULL ); // ------------------------------------ // Send the packet in the IPC channel. // ------------------------------------ retCode = m_pIPCServent->Write( (void*)pPkt, nPacketLen, nSent ); if( retCode != GOGOCM_UIS__NOERROR || nSent != nPacketLen ) { // Error, OR // Failed to send entire data. Might be broken pipe. return retCode; } else nWritten += nToSend; // Add the nToSend. NOT THE nSent (because that one contains packet header length). // ---------------------------------- // Free the allocated packet memory. // ---------------------------------- FreePacket( &pPkt ); // ------------------------------------ // Increment fragment sequence number. // ------------------------------------ if( ++nFragSeqNum > 63 ) { // Cannot send more than 63 packets (i.e.: message fragments). // Should never get here, because of initial check. assert here. assert(false); return GOGOCM_UIS_SENDBUFFERTOOBIG; } } // ---------------------------------- // Increment static message seq num. // ---------------------------------- nSeqNum = (nSeqNum + 1) % 64; // Return last Write retCode. return retCode; } // -------------------------------------------------------------------------- // Function : GetServentInfo // // Description: // This function will fill up the passed SERVENT_INFO with information // on the running Servent object. // // Arguments: // pObj: SERVENT_INFO* [IN,OUT], A SERVENT_INFO object reference. // // Return values: (none) // // -------------------------------------------------------------------------- void Servent::GetServentInfo( PSERVENT_INFO pObj ) { assert( pObj != NULL ); pObj->nTtlBytesRead = m_nTtlBytesRead; pObj->nTtlBytesWritten = m_nTtlBytesWritten; } } // namespace // -------------------------------------------------------------------------- // Function : MakePacket // // Description: // Will create a new packet. // // Arguments: // pPkt: PACKET* [OUT], A new allocated PACKET. // // Return values: // Size of new packet. (HEADER + USER DATA sizes). // // -------------------------------------------------------------------------- uint32_t MakePacket( PACKET** ppPkt, const void* pvData, const uint32_t nDataSize, int eMsgType, uint16_t nSeqNum, uint16_t nFragSeqNum ) { uint32_t nPacketSz; // Sanity checks. assert( nDataSize <= PKT_USERDATA_MAX ); assert( *ppPkt == NULL ); // Compute the size of the packet (Header + user data). nPacketSz = offsetof(PACKET, _data) + nDataSize; *ppPkt = (PACKET*) new uint8_t[nPacketSz]; // Make the packet header (*ppPkt)->_header._header = PKT_HEADER_FIXEDVALUE; (*ppPkt)->_header._msgtype = eMsgType; (*ppPkt)->_header._seq = nSeqNum; (*ppPkt)->_header._fragseq = nFragSeqNum; (*ppPkt)->_header._datalen = (uint16_t)nDataSize; // Copy user data in packet. memcpy( (*ppPkt)->_data, pvData, nDataSize ); // DEBUG: // cout << "Make packet - "; // PrintPacket( *ppPkt ); // Return the total size of packet (header + user data length). return nPacketSz; } // -------------------------------------------------------------------------- // Function : ExtractPacketData // // Description: // Will extract user data from packet, and append it to the buffered // user data. Will make sanity checks before copying. // // Arguments: // pPkt: PACKET* [IN], A PACKET. // pUserData: uint8_t* [IN,OUT], pointer to writeable user data. // // Return values: // size of user data extracted from packet. // // -------------------------------------------------------------------------- uint32_t ExtractPacketData( const PACKET* pPkt, uint8_t* pUserData, int* eMsgType, uint16_t* nSeqNum, uint16_t* nFragSeqNum ) { // DEBUG: // cout << "Extract packet - "; // PrintPacket( pPkt ); // --------------------------------------- // Make sanity checks on received packet. // --------------------------------------- if( pPkt->_header._header != PKT_HEADER_FIXEDVALUE ) { assert(false); return 0; } *eMsgType = pPkt->_header._msgtype; if( *eMsgType < PKT_MSGTYPE_NONFRAGDATA || *eMsgType > PKT_MSGTYPE_FRAGDATALAST ) { assert( false ); return 0; } *nSeqNum = pPkt->_header._seq; if( *nSeqNum > 63 ) { assert( false ); return 0; } *nFragSeqNum = pPkt->_header._fragseq; if( *nFragSeqNum > 63 ) { assert( false ); return 0; } if( pPkt->_header._datalen > PKT_USERDATA_MAX ) { assert( false ); return 0; } // Copy user data from packet to buffered user data. memcpy( (void*)pUserData, pPkt->_data, pPkt->_header._datalen ); // Return the size of the user of data copied to the buffer. return pPkt->_header._datalen; } // -------------------------------------------------------------------------- // Function : FreePacket // // Description: // Will free a packet created by the MakePacket function. // // Arguments: // pPkt: PACKET* [IN], An allocated PACKET. // // Return values: (none) // // -------------------------------------------------------------------------- void FreePacket( PACKET** ppPkt ) { uint8_t* pBytes = (uint8_t*)(*ppPkt); assert( pBytes != NULL ); delete [] pBytes; *ppPkt = NULL; } // -------------------------------------------------------------------------- // Function : PrintPacket [ DEBUG ONLY } // // Description: // Will print a packet header and data. // // Arguments: // pPkt: PACKET* [IN], A valid PACKET. // // Return values: (none) // // -------------------------------------------------------------------------- void PrintPacket( const PACKET* pPkt ) { assert( pPkt != NULL ); DBG_PRINT( "Printing packet..." ); DBG_PRINT( " Header : 0x" << setbase(16) << (uint16_t) pPkt->_header._header ); DBG_PRINT( " Packet type : 0x" << setbase(16) << (uint16_t) pPkt->_header._msgtype ); DBG_PRINT( " Packet Seq num : 0x" << setbase(16) << (uint16_t) pPkt->_header._seq ); DBG_PRINT( " Frag Seq num : 0x" << setbase(16) << (uint16_t) pPkt->_header._fragseq ); DBG_PRINT( " User data len : 0x" << setbase(16) << (uint16_t) pPkt->_header._datalen ); DBG_PRINT( " Message Data : " << pPkt->_data ); } gogoc-1_2-RELEASE/gogoc-messaging/src/servermsgsender.cc0100644000000000000000000002350511301542460021676 0ustar rootroot// ************************************************************************** // $Id: servermsgsender.cc,v 1.1 2009/11/20 16:34:56 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Implementation of the ServerMsgSender class. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #include #include namespace gogocmessaging { // -------------------------------------------------------------------------- // Function : ServerMsgSender constructor // // Description: // Will initialize a new ServerMsgSender object. // // Arguments: (none) // // Return values: (N/A) // // -------------------------------------------------------------------------- ServerMsgSender::ServerMsgSender( void ) { } // -------------------------------------------------------------------------- // Function : ServerMsgSender destructor // // Description: // Will clean-up space allocated during object lifetime. // // Arguments: (none) // // Return values: (N/A) // // -------------------------------------------------------------------------- ServerMsgSender::~ServerMsgSender( void ) { } // -------------------------------------------------------------------------- // Function : Send_StatusInfo // // Description: // Will send information on the status of the gogoCLIENT. // A message is created with the information and posted to the send queue. // // Arguments: // aStatusInfo: gogocStatusInfo* [in], The current state of the gogoCLIENT // client. // // Return values: (none) // // -------------------------------------------------------------------------- void ServerMsgSender::Send_StatusInfo( const gogocStatusInfo* aStatusInfo ) { Message* pMsg; uint8_t pData[MSG_MAX_USERDATA]; unsigned int nDataLen = 0; assert( aStatusInfo != NULL ); // Write client status to data buffer. memcpy( pData, (void*)&(aStatusInfo->eStatus), sizeof(gogocCliStatus) ); nDataLen += sizeof(gogocCliStatus); // Append status code to nStatus. memcpy( pData + nDataLen, (void*)&(aStatusInfo->nStatus), sizeof(aStatusInfo->nStatus) ); nDataLen += sizeof(aStatusInfo->nStatus); assert( nDataLen <= MSG_MAX_USERDATA ); // Buffer overflow has occured. // Create Message pMsg = Message::CreateMessage( MESSAGEID_STATUSINFO, nDataLen, pData ); assert( pMsg != NULL ); // Post the message. PostMessage( pMsg ); } // -------------------------------------------------------------------------- // Function : Send_TunnelInfo // // Description: // Will send information on the established tunnel of the gogoCLIENT. // A message is created with the information and posted to the send queue. // // Arguments: (none) // // Return values: (none) // // -------------------------------------------------------------------------- void ServerMsgSender::Send_TunnelInfo( const gogocTunnelInfo* aTunnelInfo ) { Message* pMsg; uint8_t pData[MSG_MAX_USERDATA]; uint16_t nDataLen = 0; assert( aTunnelInfo != NULL ); // Append broker name to data buffer. if( aTunnelInfo->szBrokerName ) { memcpy( pData + nDataLen, aTunnelInfo->szBrokerName, strlen(aTunnelInfo->szBrokerName) + 1 ); nDataLen += (uint16_t)strlen(aTunnelInfo->szBrokerName) + 1; } else { memset( pData + nDataLen, 0x00, 1 ); ++nDataLen; } // Append tunnel type to data buffer. memcpy( pData + nDataLen, (void*)&(aTunnelInfo->eTunnelType), sizeof(gogocTunnelType) ); nDataLen += sizeof(gogocTunnelType); // Append Local tunnel endpoint IPv4 address to data buffer. if( aTunnelInfo->szIPV4AddrLocalEndpoint ) { memcpy( pData + nDataLen, aTunnelInfo->szIPV4AddrLocalEndpoint, strlen(aTunnelInfo->szIPV4AddrLocalEndpoint) + 1 ); nDataLen += (uint16_t)strlen(aTunnelInfo->szIPV4AddrLocalEndpoint) + 1; } else { memset( pData + nDataLen, 0x00, 1 ); ++nDataLen; } // Append Local tunnel endpoint IPv6 address to data buffer. if( aTunnelInfo->szIPV6AddrLocalEndpoint ) { memcpy( pData + nDataLen, aTunnelInfo->szIPV6AddrLocalEndpoint, strlen(aTunnelInfo->szIPV6AddrLocalEndpoint) + 1 ); nDataLen += (uint16_t)strlen(aTunnelInfo->szIPV6AddrLocalEndpoint) + 1; } else { memset( pData + nDataLen, 0x00, 1 ); ++nDataLen; } // Append Remote tunnel endpoint IPv4 address to data buffer. if( aTunnelInfo->szIPV4AddrRemoteEndpoint ) { memcpy( pData + nDataLen, aTunnelInfo->szIPV4AddrRemoteEndpoint, strlen(aTunnelInfo->szIPV4AddrRemoteEndpoint) + 1 ); nDataLen += (uint16_t)strlen(aTunnelInfo->szIPV4AddrRemoteEndpoint) + 1; } else { memset( pData + nDataLen, 0x00, 1 ); ++nDataLen; } // Append Remote tunnel endpoint IPv6 address to data buffer. if( aTunnelInfo->szIPV6AddrRemoteEndpoint ) { memcpy( pData + nDataLen, aTunnelInfo->szIPV6AddrRemoteEndpoint, strlen(aTunnelInfo->szIPV6AddrRemoteEndpoint) + 1 ); nDataLen += (uint16_t)strlen(aTunnelInfo->szIPV6AddrRemoteEndpoint) + 1; } else { memset( pData + nDataLen, 0x00, 1 ); ++nDataLen; } // Append The delegated prefix to data buffer. if( aTunnelInfo->szDelegatedPrefix ) { memcpy( pData + nDataLen, aTunnelInfo->szDelegatedPrefix, strlen(aTunnelInfo->szDelegatedPrefix) + 1 ); nDataLen += (uint16_t)strlen(aTunnelInfo->szDelegatedPrefix) + 1; } else { memset( pData + nDataLen, 0x00, 1 ); ++nDataLen; } // Append The delegated user domain to data buffer. if( aTunnelInfo->szUserDomain ) { memcpy( pData + nDataLen, aTunnelInfo->szUserDomain, strlen(aTunnelInfo->szUserDomain) + 1 ); nDataLen += (uint16_t)strlen(aTunnelInfo->szUserDomain) + 1; } else { memset( pData + nDataLen, 0x00, 1 ); ++nDataLen; } // Append tunnel uptime to data buffer. memcpy( pData + nDataLen, (void*)&(aTunnelInfo->tunnelUpTime), sizeof(time_t) ); nDataLen += sizeof(time_t); assert( nDataLen <= MSG_MAX_USERDATA ); // Buffer overflow has occured. // Create Message. pMsg = Message::CreateMessage( MESSAGEID_TUNNELINFO, nDataLen, pData ); assert( pMsg != NULL ); // Post the message. PostMessage( pMsg ); } // -------------------------------------------------------------------------- // Function : Send_BrokerList // // Description: // Will send a list of brokers. // A message is created with the information and posted to the send queue. // // Arguments: // aBrokerList: gogocBrokerList* [IN], The list of broker names. // // Return values: (none) // // -------------------------------------------------------------------------- void ServerMsgSender::Send_BrokerList( const gogocBrokerList* aBrokerList ) { Message* pMsg; uint8_t pData[MSG_MAX_USERDATA]; gogocBrokerList* list = (gogocBrokerList*)aBrokerList; unsigned int nDataLen = 0; assert( aBrokerList != NULL ); // Loop until the list is empty. do { // Append broker name to data buffer. if( list->szAddress ) { memcpy( pData + nDataLen, list->szAddress, strlen(list->szAddress) + 1 ); nDataLen += (uint16_t)strlen(list->szAddress) + 1; } else { memset( pData + nDataLen, 0x00, 1 ); ++nDataLen; } // Append distance memcpy( pData + nDataLen, (void*)&(list->nDistance), sizeof(int) ); nDataLen += sizeof(int); assert( nDataLen <= MSG_MAX_USERDATA ); // Buffer overflow occured. } while( (list = list->next) != NULL ); // Create Message. pMsg = Message::CreateMessage( MESSAGEID_BROKERLIST, nDataLen, pData ); assert( pMsg != NULL ); // Post the message. PostMessage( pMsg ); } // -------------------------------------------------------------------------- // Function : Send_HACCESSStatusInfo // // Description: // Will send the HACCESS Status Info. // A message is created with the information and posted to the send queue. // // Arguments: // aHACCESSStatusInfo: HACCESSStatusInfo* [IN], The HACCESS Status info. // // Return values: (none) // // -------------------------------------------------------------------------- void ServerMsgSender::Send_HACCESSStatusInfo( const HACCESSStatusInfo* aHACCESSStatusInfo ) { Message* pMsg; uint8_t pData[MSG_MAX_USERDATA]; PMAPPING_STATUS list = aHACCESSStatusInfo->haccess_devmap_statuses; unsigned int nDataLen = 0; assert( aHACCESSStatusInfo != NULL ); // Insert HACCESS features statuses (web, proxy, DMM). // Append HACCESS proxying status memcpy( pData + nDataLen, (void*)&(aHACCESSStatusInfo->haccess_proxy_status), sizeof(HACCESSFeatStts) ); nDataLen += sizeof(HACCESSFeatStts); // Append HACCESS web service status memcpy( pData + nDataLen, (void*)&(aHACCESSStatusInfo->haccess_web_status), sizeof(HACCESSFeatStts) ); nDataLen += sizeof(HACCESSFeatStts); // Append Device Mapping Module status memcpy( pData + nDataLen, (void*)&(aHACCESSStatusInfo->haccess_devmapmod_status), sizeof(HACCESSFeatStts) ); nDataLen += sizeof(HACCESSFeatStts); // Append the device mapping statuses. if( list != NULL ) { do { // Append device name to data buffer. if( list->device_name ) { memcpy( pData + nDataLen, list->device_name, strlen(list->device_name) + 1 ); nDataLen += (uint16_t)strlen(list->device_name) + 1; } else { memset( pData + nDataLen, 0x00, 1 ); ++nDataLen; } // Append mapping status memcpy( pData + nDataLen, (void*)&(list->mapping_status), sizeof(HACCESSDevMapStts) ); nDataLen += sizeof(HACCESSDevMapStts); assert( nDataLen <= MSG_MAX_USERDATA ); // Buffer overflow occured. } while( (list = list->next) != NULL ); } // Create Message. pMsg = Message::CreateMessage( MESSAGEID_HACCESSSTATUSINFO, nDataLen, pData ); assert( pMsg != NULL ); // Post the message. PostMessage( pMsg ); } } // namespace gogoc-1_2-RELEASE/gogoc-messaging/src/servermsgtranslator.cc0100644000000000000000000002154411301542460022610 0ustar rootroot// ************************************************************************** // $Id: servermsgtranslator.cc,v 1.1 2009/11/20 16:34:56 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Implementation of the ServerMsgTranslator class. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #include #include #include namespace gogocmessaging { // -------------------------------------------------------------------------- // Function : ServerMsgTranslator constructor // // Description: // Will initialize a new ServerMsgTranslator object. // // Arguments: (none) // // Return values: (N/A) // // -------------------------------------------------------------------------- ServerMsgTranslator::ServerMsgTranslator( void ) : MessageProcessor() { MessageProcessor::m_eProcessorState = STATE_ENABLED; } // -------------------------------------------------------------------------- // Function : ServerMsgTranslator destructor // // Description: // Will clean-up space allocated during object lifetime. // // Arguments: (none) // // Return values: (N/A) // // -------------------------------------------------------------------------- ServerMsgTranslator::~ServerMsgTranslator( void ) { } // -------------------------------------------------------------------------- // Function : ProcessMessage // // Description: // Will verify the message type and call the proper translator. // // Arguments: // pMsg: Message* [IN], The message to process. // // Return values: // GOGOCM_UIS__NOERROR: Successful operation. // GOGOCM_UIS_MESSAGENOTIMPL: Message not implemented. // GOGOCM_UIS_MSGPROCDISABLED: Message processing is disabled. // // // -------------------------------------------------------------------------- error_t ServerMsgTranslator::ProcessMessage( Message* pMsg ) { error_t retCode; assert( pMsg ); // Process messages only if the message processor is enabled. if( m_eProcessorState == STATE_ENABLED ) { // ------------------------------------- // Verify what kind of message this is. // ------------------------------------- switch( pMsg->msg.header._msgid ) { case MESSAGEID_REQUEST_STATUSINFO: retCode = TranslateStatusInfoReq( pMsg->msg._data, pMsg->msg.header._datalen ); break; case MESSAGEID_REQUEST_TUNNELINFO: retCode = TranslateTunnelInfoReq( pMsg->msg._data, pMsg->msg.header._datalen ); break; case MESSAGEID_REQUEST_BROKERLIST: retCode = TranslateBrokerListReq( pMsg->msg._data, pMsg->msg.header._datalen ); break; case MESSAGEID_HACCESSCONFIGINFO: retCode = TranslateHACCESSConfigInfo( pMsg->msg._data, pMsg->msg.header._datalen ); break; case MESSAGEID_REQUEST_HACCESSSTATUSINFO: retCode = TranslateHACCESSStatusInfoReq( pMsg->msg._data, pMsg->msg.header._datalen ); break; default: retCode = GOGOCM_UIS_MESSAGENOTIMPL; // Unknown / invalid message. break; } } else retCode = GOGOCM_UIS_MSGPROCDISABLED; // Return completion status. return retCode; } // -------------------------------------------------------------------------- // Function : TranslateStatusInfoReq // // Description: // Will translate the data sent from the GUI. In this case, there is no // data sent from the GUI so there isn't anything to translate. // // Arguments: // pData: uint8_t* [IN], The raw data. // nDataLen: uint16_t [IN], The length of the raw data. // // Return values: // GOGOCM_UIS__NOERROR: Successful operation. // any other value on error. // // -------------------------------------------------------------------------- error_t ServerMsgTranslator::TranslateStatusInfoReq( uint8_t* pData, const uint16_t nDataLen ) { // No translation is required for requests. // i.e.: GUI doesn't send information in requests. return Recv_StatusInfoRequest(); } // -------------------------------------------------------------------------- // Function : TranslateTunnelInfoReq // // Description: // Will translate the data sent from the GUI. In this case, there is no // data sent from the GUI so there isn't anything to translate. // // Arguments: // pData: uint8_t* [IN], The raw data. // nDataLen: uint16_t [IN], The length of the raw data. // // Return values: // GOGOCM_UIS__NOERROR: Successful operation. // any other value on error. // // -------------------------------------------------------------------------- error_t ServerMsgTranslator::TranslateTunnelInfoReq( uint8_t* pData, const uint16_t nDataLen ) { // No translation is required for requests. // i.e.: GUI doesn't send information in requests. return Recv_TunnelInfoRequest(); } // -------------------------------------------------------------------------- // Function : TranslateBrokerListReq // // Description: // Will translate the data sent from the GUI. In this case, there is no // data sent from the GUI so there isn't anything to translate. // // Arguments: // pData: uint8_t* [IN], The raw data. // nDataLen: uint16_t [IN], The length of the raw data. // // Return values: // GOGOCM_UIS__NOERROR: Successful operation. // any other value on error. // // -------------------------------------------------------------------------- error_t ServerMsgTranslator::TranslateBrokerListReq( uint8_t* pData, const uint16_t nDataLen ) { // No translation is required for requests. // i.e.: GUI doesn't send information in requests. return Recv_BrokerListRequest(); } // -------------------------------------------------------------------------- // Function : TranslateHACCESSConfigInfo // // Description: // Will translate the HACCESS configuration info message data and call the // handler with the translated information. // // Arguments: // pData: uint8_t* [IN], The raw data. // nDataLen: uint16_t [IN], The length of the raw data. // // Return values: // GOGOCM_UIS__NOERROR: Successful operation. // any other value on error. // // -------------------------------------------------------------------------- error_t ServerMsgTranslator::TranslateHACCESSConfigInfo( uint8_t* pData, const uint16_t nDataLen ) { HACCESSConfigInfo HACCESSConfigInfo; uint16_t nCursor = 0; error_t retCode; // -- D A T A E X T R A C T I O N -- // Extract HACCESS WWW document root from data buffer. HACCESSConfigInfo.haccess_doc_root = pal_strdup( (char*)(pData + nCursor) ); nCursor += (uint16_t)strlen( (char*)(pData + nCursor) ) + 1; // Extract proxy enabled from data buffer. memcpy( (void*)&(HACCESSConfigInfo.haccess_proxy_enabled), pData + nCursor, sizeof(HACCESSConfigInfo.haccess_proxy_enabled) ); nCursor += sizeof(HACCESSConfigInfo.haccess_proxy_enabled); // Extract web enabled from data buffer. memcpy( (void*)&(HACCESSConfigInfo.haccess_web_enabled), pData + nCursor, sizeof(HACCESSConfigInfo.haccess_web_enabled) ); nCursor += sizeof(HACCESSConfigInfo.haccess_web_enabled); // Extract if device mappings changed from data buffer. memcpy( (void*)&(HACCESSConfigInfo.haccess_devmap_changed), pData + nCursor, sizeof(HACCESSConfigInfo.haccess_devmap_changed) ); nCursor += sizeof(HACCESSConfigInfo.haccess_devmap_changed); // ----------------------------------------------------------------------- // Sanity check. Verify that the bytes of data we extracted match that of // what was expected. // ----------------------------------------------------------------------- assert( nCursor == nDataLen ); // --------------------------------- // Invoke derived function handler. // --------------------------------- retCode = Recv_HACCESSConfigInfo( &HACCESSConfigInfo ); // ----------------------------------------------- // Clean up allocated memory used for extraction. // ----------------------------------------------- free( HACCESSConfigInfo.haccess_doc_root ); return retCode; } // -------------------------------------------------------------------------- // Function : TranslateHACCESSStatusInfoReq // // Description: // Will translate the data sent from the GUI. In this case, there is no // data sent from the GUI so there isn't anything to translate. // // Arguments: // pData: uint8_t* [IN], The raw data. // nDataLen: uint16_t [IN], The length of the raw data. // // Return values: // GOGOCM_UIS__NOERROR: Successful operation. // any other value on error. // // -------------------------------------------------------------------------- error_t ServerMsgTranslator::TranslateHACCESSStatusInfoReq( uint8_t* pData, const uint16_t nDataLen ) { // No translation is required for requests. // i.e.: GUI doesn't send information in requests. return Recv_HACCESSStatusInfoRequest(); } } // namespace gogoc-1_2-RELEASE/gogoc-messaging/src/windows/0040755000000000000000000000000011346561542017654 5ustar rootrootgogoc-1_2-RELEASE/gogoc-messaging/src/windows/pipeclient.cc0100644000000000000000000001073011301542462022304 0ustar rootroot// ************************************************************************** // $Id: pipeclient.cc,v 1.1 2009/11/20 16:34:58 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Windows implementation of the PipeClient class. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #include #include #include #define PIPE_BUFSIZ 4096 #define PIPE_DFLT_TIMEOUT 200 // miliseconds namespace gogocmessaging { // -------------------------------------------------------------------------- // Function : PipeClient constructor // // Description: // Will initialize a new PipeClient object. // // Arguments: // aPipeName: string [IN], The name of the pipe this client will // connect to. // // Return values: (N/A) // // -------------------------------------------------------------------------- PipeClient::PipeClient( const string& aPipeName ) : IPCClient(), PipeIO(), m_PipeName(aPipeName) { assert( !aPipeName.empty() ); } // -------------------------------------------------------------------------- // Function : PipeClient destructor // // Description: // Will clean-up space allocated during object lifetime. // // Arguments: (none) // // Return values: (N/A) // // -------------------------------------------------------------------------- PipeClient::~PipeClient( void ) { // Is client pipe still online ? assert( m_Handle == INVALID_IPC_HANDLE ); } // -------------------------------------------------------------------------- // Function : Connect // // Description: // Will establish a client pipe with the server. // NOTE: THIS FUNCTION IS (big time) BLOCKING!!! // // Arguments: (none) // // Return values: // GOGOCM_UIS__NOERROR: Operation successful. // Any other value is an error. Use GetLastError() for more information. // // -------------------------------------------------------------------------- error_t PipeClient::Connect( void ) { // Check if client pipe handle is valid. if( m_Handle != INVALID_IPC_HANDLE ) return GOGOCM_UIS_CLIENTALRDYCONN; // Loop until we're connected. while( m_Handle == INVALID_IPC_HANDLE ) { // Check if server pipe endpoint is available. if( WaitNamedPipe( m_PipeName.c_str(), NMPWAIT_WAIT_FOREVER ) == TRUE ) { // Connect to server endpoint. m_Handle = (IPC_HANDLE)CreateFile( m_PipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL ); // Validate returned value. if( m_Handle == INVALID_IPC_HANDLE ) { return GOGOCM_UIS_FAILCREATECLIENTPIPE; } // Specify client transfer mode: MESSAGES DWORD dwMode = PIPE_READMODE_MESSAGE | PIPE_WAIT; if( SetNamedPipeHandleState( m_Handle, &dwMode, NULL, NULL ) == 0 ) { CloseHandle( m_Handle ); m_Handle = INVALID_IPC_HANDLE; return GOGOCM_UIS_FAILCREATECLIENTPIPE; } } else { // If no instances of the specified named pipe exist, the // WaitNamedPipe function returns immediately, regardless of // the time-out value. Sleep(20); // Wait a bit before retrying. // Failure to sleep will cause 100% CPU usage. } } // Connection to server successful. return GOGOCM_UIS__NOERROR; } // -------------------------------------------------------------------------- // Function : Disconnect // // Description: // Will terminate connection to the pipe server. // // Arguments: (none) // // Return values: // GOGOCM_UIS__NOERROR: Operation successful. // Any other value is an error. Use GetLastError() for more information. // // -------------------------------------------------------------------------- error_t PipeClient::Disconnect( void ) { // Check if client pipe handle is valid. if( m_Handle == INVALID_IPC_HANDLE ) return GOGOCM_UIS_PIPECLIDISCFAIL; // Close connection to server. if( CloseHandle( m_Handle ) == 0 ) { return GOGOCM_UIS_PIPECLIDISCFAIL; } m_Handle = INVALID_IPC_HANDLE; // Disconnection successful. return GOGOCM_UIS__NOERROR; } } gogoc-1_2-RELEASE/gogoc-messaging/src/windows/pipeio.cc0100644000000000000000000001257711301542462021450 0ustar rootroot// ************************************************************************** // $Id: pipeio.cc,v 1.1 2009/11/20 16:34:58 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Windows implementation of the PipeIO class. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #include #include #include namespace gogocmessaging { // -------------------------------------------------------------------------- // Function : PipeIO constructor // // Description: // Will initialize a new PipeIO object. // // Arguments: (none) // // Return values: (N/A) // // -------------------------------------------------------------------------- PipeIO::PipeIO( void ) : IPCServent() { } // -------------------------------------------------------------------------- // Function : PipeIO destructor // // Description: // Will clean-up space allocated during object lifetime. // // Arguments: (none) // // Return values: (N/A) // // -------------------------------------------------------------------------- PipeIO::~PipeIO( void ) { } // -------------------------------------------------------------------------- // Function : CanRead // // Description: // Will verify if a Read operation will be blocking. This is done by // verifying if there's data available for a read operation. // // Arguments: // bCanRead: boolean [OUT], Boolean indicating if there's data to read. // // Return values: // GOGOCM_UIS__NOERROR: On successful peek // GOGOCM_UIS_PEEKPIPEFAILED: Upon an IO error on the peek. // // -------------------------------------------------------------------------- error_t PipeIO::CanRead( bool& bCanRead ) const { error_t retCode = GOGOCM_UIS__NOERROR; DWORD nBytesAvailable; // Verify IPC handle. assert( m_Handle != INVALID_HANDLE_VALUE ); // Take a peek at the pipe to see if we've got stuff to read. if( PeekNamedPipe( m_Handle, NULL, 0, NULL, &nBytesAvailable, NULL ) == 0 ) { // PeekNamedPipe failed. retCode = GOGOCM_UIS_PEEKPIPEFAILED; nBytesAvailable = 0; } // Set whether we can read or not. bCanRead = (nBytesAvailable > 0); // Return operation result. return retCode; } // -------------------------------------------------------------------------- // Function : CanWrite // // Description: // Will verify if a Write operation will be blocking. // // Arguments: // bCanWrite: boolean [OUT], Boolean indicating if it's possible to write. // // Return values: // GOGOCM_UIS__NOERROR: On successful peek // GOGOCM_UIS_PEEKPIPEFAILED: Upon an IO error on the peek. // // -------------------------------------------------------------------------- error_t PipeIO::CanWrite( bool& bCanWrite ) const { error_t retCode = GOGOCM_UIS__NOERROR; DWORD dummy; // Verify IPC handle. assert( m_Handle != INVALID_HANDLE_VALUE ); bCanWrite = true; // This (dummy) call to PeekNamedPipe will verify if the handle is valid. if( PeekNamedPipe( m_Handle, NULL, 0, NULL, &dummy, NULL ) == 0 ) { // PeekNamedPipe failed. retCode = GOGOCM_UIS_PEEKPIPEFAILED; bCanWrite = false; } // ----------------------------------------------------------- // Writing should not block, except if send buffer is full... // ... and there's no way of knowing that. // ----------------------------------------------------------- // Return operation result. return retCode; } // -------------------------------------------------------------------------- // Function : Read // // Description: // Will attempt to receive data from the pipe. // // Arguments: // pvReadBuffer: void* [OUT], The receiving buffer. // nBufferSize: int [IN], The size in bytes allocated for read at the // receive buffer. // // Return values: // GOGOCM_UIS__NOERROR: Operation successful. // Any other value is an error. // // -------------------------------------------------------------------------- error_t PipeIO::Read( void* pvReadBuffer, const uint32_t nBufferSize, uint32_t& nRead ) { // Verify IPC handle. assert( m_Handle != INVALID_HANDLE_VALUE ); // Read from pipe. if( ReadFile( m_Handle, pvReadBuffer, (DWORD)nBufferSize, (DWORD*)(&nRead), NULL ) == 0 ) { return GOGOCM_UIS_READPIPEFAILED; } // Operation successful. return GOGOCM_UIS__NOERROR; } // -------------------------------------------------------------------------- // Function : Write // // Description: // Will attempt to write data to the pipe. // // Arguments: // pvData: void* [IN], The receiving buffer. // nDataSize: uint32_t [IN], The size in bytes to write. // nWritten: uint32_t [OUT], The number of bytes written. // // Return values: // GOGOCM_UIS__NOERROR: Operation successful. // Any other value is an error. // // -------------------------------------------------------------------------- error_t PipeIO::Write( const void* pvData, const uint32_t nDataSize, uint32_t& nWritten ) { // Verify IPC handle. assert( m_Handle != INVALID_HANDLE_VALUE ); // Write to pipe. if( WriteFile( m_Handle, pvData, (DWORD)nDataSize, (DWORD*)(&nWritten), NULL ) == 0 ) { return GOGOCM_UIS_WRITEPIPEFAILED; } // Operation successful. return GOGOCM_UIS__NOERROR; } } gogoc-1_2-RELEASE/gogoc-messaging/src/windows/pipeserver.cc0100644000000000000000000001302511301542462022334 0ustar rootroot// ************************************************************************** // $Id: pipeserver.cc,v 1.1 2009/11/20 16:34:58 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Windows implementation of the PipeServer class. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #include #include #include #define PIPE_BUFSIZ 65000 // Should be large enough to accomodate user messages. #define PIPE_DFLT_TIMEOUT 200 // miliseconds namespace gogocmessaging { // -------------------------------------------------------------------------- // Function : PipeServer constructor // // Description: // Will initialize a new PipeServer object. // // Arguments: // aPipeName: string [IN], The name of the pipe this server will create. // // Return values: (N/A) // // -------------------------------------------------------------------------- PipeServer::PipeServer( const string& aPipeName ) : IPCServer(), PipeIO(), m_PipeName(aPipeName), m_bClientConnected(false) { } // -------------------------------------------------------------------------- // Function : PipeServer destructor // // Description: // Will clean-up space allocated during object lifetime. // // Arguments: (none) // // Return values: (N/A) // // -------------------------------------------------------------------------- PipeServer::~PipeServer( void ) { // Is server pipe still online ? assert( m_Handle == INVALID_IPC_HANDLE ); // Is client still connected ? assert( m_bClientConnected == false ); } // -------------------------------------------------------------------------- // Function : CreateConnectionPoint // // Description: // Will create a NamedPipe server endpoint. // // Arguments: (none) // // Return values: // GOGOCM_UIS__NOERROR: Operation successful. // Any other value is an error. Use GetLastError() for more information. // // -------------------------------------------------------------------------- error_t PipeServer::CreateConnectionPoint( void ) { assert( !m_PipeName.empty() ); if( m_Handle != INVALID_IPC_HANDLE ) return GOGOCM_UIS_PIPESERVERALRDUP; // --------------------------------- // Create the server pipe endpoint. // --------------------------------- m_Handle = (IPC_HANDLE)CreateNamedPipe( m_PipeName.c_str(), PIPE_ACCESS_DUPLEX, // Open Mode PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1, PIPE_BUFSIZ, PIPE_BUFSIZ, PIPE_DFLT_TIMEOUT, NULL ); // Verify returned value. if( m_Handle == INVALID_IPC_HANDLE ) { return GOGOCM_UIS_FAILCREATESERVERPIPE; } // Successful operation. return GOGOCM_UIS__NOERROR; } // -------------------------------------------------------------------------- // Function : AcceptConnection // // Description: // Will accept a pipe client connection. // NOTE: THIS FUNCTION IS (big time) BLOCKING!!! // // Arguments: (none) // // Return values: // GOGOCM_UIS__NOERROR: Operation successful. // Any other value is an error. Use GetLastError() for more information. // // -------------------------------------------------------------------------- error_t PipeServer::AcceptConnection( void ) { if( m_bClientConnected ) return GOGOCM_UIS_CLIENTALRDYCONN; // Verify the server pipe handle. assert( m_Handle != INVALID_IPC_HANDLE ); // Await client connection if( ConnectNamedPipe( m_Handle, NULL ) == 0 ) { DWORD dwError = GetLastError(); // If a client connects before the ConnectNamedPipe function is called, // the function returns zero and GetLastError returns // ERROR_PIPE_CONNECTED. This can happen if a client connects in the // interval between the call to CreateNamedPipe and the call to // ConnectNamedPipe. In this situation, there is a good connection // between client and server, even though the function returns zero. if( dwError != ERROR_PIPE_CONNECTED ) return GOGOCM_UIS_CLIENTCONNFAILED; } // Client connection successful return GOGOCM_UIS__NOERROR; } // -------------------------------------------------------------------------- // Function : CloseConnection // // Description: // Will close the server-side pipe instance. // // Arguments: (none) // // Return values: // GOGOCM_UIS__NOERROR: Operation successful. // Any other value is an error. Use GetLastError() for more information. // // -------------------------------------------------------------------------- error_t PipeServer::CloseConnection( void ) { // Verify if the server pipe handle is valid. if( m_Handle == INVALID_IPC_HANDLE ) return GOGOCM_UIS__NOERROR; // Already closed, or cannot close. // Disconnect the client from the server side. if( DisconnectNamedPipe( m_Handle ) == 0 ) { return GOGOCM_UIS_PIPESVRDISCFAIL; } // Close server-side pipe instance. if( CloseHandle( m_Handle ) == 0 ) { return GOGOCM_UIS_PIPESVRDISCFAIL; } // Invalidate server pipe handle. m_Handle = INVALID_IPC_HANDLE; // Mark client as not connected. m_bClientConnected = false; // Server pipe disconnection successful. return GOGOCM_UIS__NOERROR; } } gogoc-1_2-RELEASE/gogoc-messaging/src/windows/semaphore.cc0100644000000000000000000000606011301542463022135 0ustar rootroot// ************************************************************************** // $Id: semaphore.cc,v 1.1 2009/11/20 16:34:59 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // Windows Semaphore wrapper. // // Author: Charles Nepveu // // Creation Date: December 2006 // __________________________________________________________________________ // ************************************************************************** #include #include namespace gogocmessaging { // -------------------------------------------------------------------------- // Function : Semaphore constructor // // Description: // Will initialize a new Semaphore object. // // Arguments: // nCount: int [IN], The initial count of semaphore // // Return values: (N/A) // // Exceptions: (none) // // -------------------------------------------------------------------------- Semaphore::Semaphore( unsigned int nMaxCount, unsigned int nInitialCount ): m_Semaphore(NULL) { m_Semaphore = (sem_t)CreateSemaphore( NULL, nInitialCount, nMaxCount, NULL ); assert( m_Semaphore != NULL ); } // -------------------------------------------------------------------------- // Function : Semaphore destructor // // Description: // Will clean-up space allocated during object lifetime. // // Arguments: (none) // // Return values: (N/A) // // Exceptions: (none) // // -------------------------------------------------------------------------- Semaphore::~Semaphore( void ) { if( m_Semaphore != NULL ) { CloseHandle( m_Semaphore ); m_Semaphore = NULL; } } // -------------------------------------------------------------------------- // Function : WaitAndLock // // Description: // Blocks execution until semaphore object is available. // Locks (decrements) semaphore count. // // Arguments: // ulWaitms: The number of miliseconds to wait until state is signalled. // If 0, the wait time is INFINITE. // // Return values: // 0: Successfuly obtained lock on semaphore object // -1: Invalid semaphore object, or an error occured. // // Exceptions: (none) // // -------------------------------------------------------------------------- int Semaphore::WaitAndLock( unsigned long ulWaitms ) { DWORD dwWait = (ulWaitms!=0) ? ulWaitms : INFINITE; return ( (m_Semaphore != NULL) && (WaitForSingleObject( m_Semaphore, dwWait ) == WAIT_OBJECT_0) ) ? 0 : -1; } // -------------------------------------------------------------------------- // Function : ReleaseLock // // Description: // Releases lock on semaphore object (increments semaphore count). // // Arguments: (none) // // Return values: // 0: Successfuly released lock on semaphore object // -1: Invalid semaphore object, or an error occured. // // Exceptions: (none) // // -------------------------------------------------------------------------- int Semaphore::ReleaseLock( void ) { return ( (m_Semaphore != NULL) && (ReleaseSemaphore( m_Semaphore, 1, NULL ) == TRUE) ) ? 0 : -1;; } } // namespace gogoc-1_2-RELEASE/gogoc-messaging/src/windows/threadwrapper.cc0100644000000000000000000001034511301542463023023 0ustar rootroot// ************************************************************************** // $Id: threadwrapper.cc,v 1.1 2009/11/20 16:34:59 jasminko Exp $ // // Copyright (c) 2007 gogo6 Inc. All rights reserved. // // For license information refer to CLIENT-LICENSE.TXT // // Description: // IPC Layer tester. // // Author: Charles Nepveu // // Creation Date: November 2006 // __________________________________________________________________________ // ************************************************************************** #include #include namespace gogocmessaging { // -------------------------------------------------------------------------- // Function : ThreadWrapper constructor // // Description: // Will initialize a new ThreadWrapper object. // // Arguments: (none) // // Return values: (N/A) // // Exceptions: (none) // // -------------------------------------------------------------------------- ThreadWrapper::ThreadWrapper( void ): m_hThread(NULL), m_hQuitEvent(NULL) { } // -------------------------------------------------------------------------- // Function : ThreadWrapper destructor // // Description: // Will clean-up space allocated during object lifetime. // // Arguments: (none) // // Return values: (N/A) // // Exceptions: (none) // // -------------------------------------------------------------------------- ThreadWrapper::~ThreadWrapper( void ) { } // -------------------------------------------------------------------------- // Function : Run // // Description: // Will start executing the ThreadProc function with this class. // // Arguments: (none) // // Return values: // true if thread execution started normally. // false otherwise. // // Exceptions: (none) // // -------------------------------------------------------------------------- bool ThreadWrapper::Run( void ) { DWORD tID; // Create event for thread termination. m_hQuitEvent = (event_t)CreateEvent( NULL, TRUE, FALSE, NULL ); if( m_hQuitEvent != NULL ) { // Create and launch thread. m_hThread = (thread_t)CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)&ThreadWrapper::ThreadProc, (void*)this, 0, &tID); } return ( m_hThread != NULL ); } // -------------------------------------------------------------------------- // Function : Stop // // Description: // Will stop execution of a running thread. // // Arguments: (none) // // Return values: // true if thread execution has stopped. // false otherwise. // // Exceptions: (none) // // -------------------------------------------------------------------------- bool ThreadWrapper::Stop( void ) { // Check thread handle. if( m_hThread == NULL ) return false; // Signal the thread that we want to quit. SetEvent( m_hQuitEvent ); // Wait 200ms for the thread to finish up... if( WaitForSingleObject( m_hThread, 200 ) != WAIT_OBJECT_0 ) { // Wait for thread failed. Terminate it. TerminateThread( m_hThread, 0 ); } // Close Event handle. CloseHandle( m_hQuitEvent ); // Close thread handle. CloseHandle( m_hThread ); return true; } // -------------------------------------------------------------------------- // Function : ShouldStop // // Description: // Verifies if the Quit event is set. // // Arguments: (none) // // Return values: // true if thread should terminate // false otherwise. // // Exceptions: (none) // // -------------------------------------------------------------------------- bool ThreadWrapper::ShouldStop( void ) const { assert( m_hQuitEvent != NULL ); return( WaitForSingleObject( m_hQuitEvent, 0 ) == WAIT_OBJECT_0); } // -------------------------------------------------------------------------- // Function : ThreadProc [ STATIC ] // // Description: // Will start executing the derived work function. // // Arguments: // lpvParam: void* [IN], this pointer. // // Return values: // true if thread execution started normally. // false otherwise. // // Exceptions: (none) // // -------------------------------------------------------------------------- uint32_t WINAPI ThreadWrapper::ThreadProc( LPVOID lpvParam ) { assert( lpvParam != NULL ); // Run the Work function of the object. ((ThreadWrapper*)lpvParam)->Work(); return 1; } } gogoc-1_2-RELEASE/gogoc-tsp/0040755000000000000000000000000011346561546014230 5ustar rootrootgogoc-1_2-RELEASE/gogoc-tsp/conf/0040755000000000000000000000000011346561543015152 5ustar rootrootgogoc-1_2-RELEASE/gogoc-tsp/conf/Makeconf.cmd0100644000000000000000000000276311301544570017357 0ustar rootroot@REM = '##################################################################### @ECHO OFF REM # $Id: Makeconf.cmd,v 1.1 2009/11/20 16:53:12 jasminko Exp $ REM # REM # For license information refer to CLIENT-LICENSE.TXT REM # REM # ####################################################################### REM # SET IN_DIR=%~1 SET OUT_DIR=%~2 SET TEMPLATE=%~3 SET IF_V6V4=%~4 SET IF_V6UDPV4=%~5 SET IF_V4V6=%~6 PATH=%PATH%;c:\perl\bin perl -x -S %0 %* SET STATUS=%errorlevel% IF %STATUS% == 9009 ECHO You do not have Perl in your PATH. GOTO endofperl @REM '; # Perl script starting... #!perl # use strict; # # Get environment variables # my $in_dir=$ENV{'IN_DIR'}; my $out_dir=$ENV{'OUT_DIR'}; my $template=$ENV{'TEMPLATE'}; my $if_v6v4=$ENV{'IF_V6V4'}; my $if_v6udpv4=$ENV{'IF_V6UDPV4'}; my $if_v4v6=$ENV{'IF_V4V6'}; my @content; my $line; # # Open input file, and read contents. # open( CONFIN, "$in_dir/gogoc.conf.in" ) or die "Unable to open $in_dir/gogoc.conf.in"; @content=; close( CONFIN ); # # Open output file and perform substitution. # open( CONFOUT, ">$out_dir/gogoc.conf.sample" ) or die "Unable to open $out_dir/gogoc.conf.sample"; foreach $line (@content) { chop($line); $line =~ s+\@ifname_v4v6\@+$if_v4v6+; $line =~ s+\@ifname_v6udpv4\@+$if_v6udpv4+; $line =~ s+\@ifname_v6v4\@+$if_v6v4+; $line =~ s+\@conf_template\@+$template+; print CONFOUT "$line\n"; } close( CONFOUT ); __END__ :endofperl exit %STATUS% gogoc-1_2-RELEASE/gogoc-tsp/conf/Makefile0100644000000000000000000000232011301544570016574 0ustar rootroot# ########################################################################### # # $Id: Makefile,v 1.1 2009/11/20 16:53:12 jasminko Exp $ # # For license information refer to CLIENT-LICENSE.TXT # # ########################################################################### # # NOTE: This makefile MUST be interpreted by GNU make. # Include the platform makefile, if it exists. -include $(PLATFORM_DIR)/$(PLATFORM)/platform.mak all: install: check-env gogoc.conf.sample .PHONY: all install check-env gogoc.conf.sample clean check-env: @[ -n "$(PLATFORM)" ] || { echo "Platform is undefined." ; exit 1 ; } @[ -n "$(INSTALL_DIR)" ] || { echo "Installation directory is undefined." ; exit 1 ; } gogoc.conf.sample: @echo Generating basic configuration file @[ ! -f $(BIN_DIR)/gogoc.conf.sample ] || { \ rm -f $(BIN_DIR)/gogoc.conf.sample; \ } @sed -e "s+@ifname_v4v6@+$(PLATFORM_V4V6)+" \ -e "s+@ifname_v6udpv4@+$(PLATFORM_V6UDPV4)+" \ -e "s+@ifname_v6v4@+$(PLATFORM_V6V4)+" \ -e "s+@conf_template@+$(PLATFORM)+" \ -e "s+@conf_gogoc_dir@+$(INSTALL_DIR)+" \ gogoc.conf.in > $(BIN_DIR)/gogoc.conf.sample @chmod 700 $(BIN_DIR)/gogoc.conf.sample clean: rm -f $(BIN_DIR)/gogoc.conf.sample gogoc-1_2-RELEASE/gogoc-tsp/conf/gogoc.conf.in0100644000000000000000000002402011301544570017507 0ustar rootroot#----------------------------------------------------------------------------- # $Id: gogoc.conf.in,v 1.1 2009/11/20 16:53:12 jasminko Exp $ #----------------------------------------------------------------------------- ########################## READ ME! ################################ # # Welcome to the gogoCLIENT configuration file. # In order to use the client, you need to modify the 'userid', 'passwd' and # 'server' parameters below depending on which of these situations applies: # # 1. If you created a Freenet6 account, enter your userid and password below. # Change the server name to "broker.freenet6.net" and auth_method to 'any'. # 2. If you would like to use Freenet6 without creating an account, # do not make any modifications and close this file. # 3. If this software was provided by your ISP, enter the userid, password and # server name provided by your ISP below. # ########################## BASIC CONFIGURATION ################################ # # User Identification and Password: # Specify your user name and password as provided by your ISP or Freenet6. # If you plan to connect anonymously, leave these values empty. # NOTE: Change auth_method option if you are using a username/password. # # userid= # passwd= # userid= passwd= # # gogoSERVER: # Specify a gogoSERVER name or IP address (provided by your ISP or # Freenet6). An optional port number can be added; the default port number # is 3653. # # Examples: # server=hostname # FQDN # server=A.B.C.D # IPv4 address # server=[X:X::X:X] # IPv6 address # server=hostname:port_number # server=A.B.C.D:port_number # server=[X:X::X:X]:port_number # # Freenet6 account holders should enter authenticated.freenet6.net, # otherwise use anonymous.freenet6.net. # Your ISP may provide you with a different server name. # server=anonymous.freenet6.net #server=authenticated.freenet6.net # # Authentication Method: # # auth_method=<{anonymous}|{any|passdss-3des-1|digest-md5|plain}> # # anonymous: Sends no username or password # # any: The most secure method will be used. # passdss-3des-1: The password is sent encrypted. # digest-md5: The password is sent encrypted. # plain: Both username and password are sent as plain text. # # Recommended values: # - any: If you are authenticating a username / password. # - anonymous: If you are connecting anonymously. # auth_method=anonymous #auth_method=any ########################## ROUTING CONFIGURATION ############################## # Use these parameters when you wish the client to act as a router and provide # IPv6 connectivity to IPv6-capable devices on your network. # # Local Host Type: # Change this value to 'router' to enable IPv6 advertisements. # # host_type= # host_type=host # # Prefix Length: # Length of the requested prefix. Valid values range between 0 and 64 when # using V6*V4 tunnel modes, and between 0 and 32 when using V4V6 tunnel mode. # # prefixlen= # prefixlen=64 # # Advertisement Interface Prefix: # Name of the interface that will be configured to send router advertisements. # This is an interface index on Windows (ex: 4) and a name on Linux # and BSD (ex: eth1 or fxp1). # # if_prefix= # if_prefix= # # DNS Server: # A DNS server list to which the reverse prefix will be delegated. Servers # are separated by the colon(:) delimiter. # # Example: dns_server=ns1.domain:ns2.domain:ns3.domain # dns_server= ######################### ADVANCED CONFIGURATION ############################## # # gogoCLIENT Installation Directory: # Directory where the gogoCLIENT will be installed. This value has been # set during installation. # gogoc_dir=@conf_gogoc_dir@ # # Auto-Retry Connect, Retry Delay and Max Retry Delay: # When auto_retry_connect=yes, the gogoCLIENT will attempt to reconnect # after a disconnection occurred. The time to wait is 'retry_delay' and that # delay is doubled at every 3 failed consecutive reconnection attempt. # However, the wait delay will never exceed retry_delay_max. # # # auto_retry_connect= # retry_delay= # retry_delay_max= # # Recommended values: "yes", 30, 300 # auto_retry_connect=yes retry_delay=30 retry_delay_max=300 # # Keepalive Feature and Message Interval: # Indicates if and how often the client will send data to keep the tunnel # active. # # keepalive= # keepalive_interval= # # Recommended values: "yes" and 30 # keepalive=yes keepalive_interval=30 # # Tunnel Encapsulation Mode: # v6v4: IPv6-in-IPv4 tunnel. # v6udpv4: IPv6-in-UDP-in-IPv4 tunnel (for clients behind a NAT). # v6anyv4: Lets the broker choose the best mode for IPv6 tunnel. # v4v6: IPv4-in-IPv6 tunnel. # # Recommended value: v6anyv4 # tunnel_mode=v6anyv4 # # Tunnel Interface Name: # The interface name assigned to the tunnel. This value is O/S dependent. # # if_tunnel_v6v4 is the tunnel interface name for v6v4 encapsulation mode # if_tunnel_v6udpv4 is the tunnel interface name for v6udpv4 encapsulate mode # if_tunnel_v4v6 is the tunnel interface name for v4v6 encapsulation mode # # Default values are set during installation. # if_tunnel_v6v4=@ifname_v6v4@ if_tunnel_v6udpv4=@ifname_v6udpv4@ if_tunnel_v4v6=@ifname_v4v6@ # # Local IP Address of the Client: # Allows you to set a specific address as the local tunnel endpoint. # # client_v4= # client_v6= # auto: The gogoCLIENT will find the local IP address endpoint. # # Recommended value: auto # client_v4=auto client_v6=auto # # Script Name: # File name of the script to run to install the tunnel interface. The # scripts are located in the template directory under the client # installation directory. # # template= # # Default value is set during installation. # template=@conf_template@ # # Proxy client: # Indicates that this client will request a tunnel for another endpoint, # such as a Cisco router. # # proxy_client= # # NOTE: NAT traversal is not possible in proxy mode. # proxy_client=no ############################ BROKER REDIRECTION ############################### # # Broker List File Name: # The 'broker_list' directive specifies the filename where the broker # list received during broker redirection will be saved. # # broker_list= # broker_list=tsp-broker-list.txt # # Last Server Used File Name: # The 'last_server' directive specifies the filename where the address of # the last broker to which a connection was successfully established will # be saved. # # last_server= # last_server=tsp-last-server.txt # # Always Use Last Known Working Server: # The value of the 'always_use_same_server' directive determines whether the # client should always try to connect to the broker found in the # 'last_server' directive filename. # # always_use_same_server= # always_use_same_server=no #################################### LOGGING ################################## # # Log Verbosity Configuration: # The format is 'log_=level', where possible values for # 'destination' are: # # - console (logging to the console [AKA stdout]) # - stderr (logging to standard error) # - file (logging to a file) # - syslog (logging to syslog [Unix only]) # # and 'level' is a digit between 0 and 3. A 'level' value of 0 disables # logging to the destination, while values 1 to 3 request increasing levels # of log verbosity and detail. If 'level' is not specified, a value of 1 is # assumed. # # Example: # log_file=3 (Maximal logging to a file) # log_stderr=0 (Logging to standard error disabled) # log_console= (Minimal logging to the console) # # - Default configuration on Windows platforms: # # log_console=0 # log_stderr=0 # log_file=1 # # - Default configuration on Unix platforms: # # log_console=0 # log_stderr=1 # log_file=0 # log_syslog=0 # #log_console= #log_stderr= #log_file= #log_syslog= # # Log File Name: # When logging to file is requested using the 'log_file' directive, the name # and path of the file to use may be specified using this directive. # # log_filename= # log_filename=gogoc.log # # Log File Rotation: # When logging to file is requested using the 'log_file' directive, log file # rotation may be enabled. When enabled, the contents of the log file will # be moved to a backup file just before it reaches the maximum log file size # specified via this directive. # # The name of the backup file is the name of the original log file with # '.' inserted before the file extension. If the file does not # have an extension, '.' is appended to the name of the original # log file. The timestamp specifies when the rotation occurred. # # After the contents of the log file have been moved to the backup file, the # original file is cleared, and logging resumes at the beginning of the file. # # log_rotation= # log_rotation=yes # # Log File Rotation Size: # The 'log_rotation_size' directive specifies the maximum size a log file may # reach before rotation occurs, if enabled. The value is expressed in # kilobytes. # # log_rotation_size=<16|32|128|1024> # log_rotation_size=32 # # Deletion of rotated log files: # The 'log_rotation_delete' directive specifies that no log backup will be # kept. When rotation occurs, the file is immediately wiped out and a new # log file is started. # # log_rotation_delete= # log_rotation_delete=no # # Syslog Logging Facility [Unix Only]: # When logging to syslog is requested using the 'log_syslog' directive, the # facility to use may be specified using this directive. # # syslog_facility= # syslog_facility=USER # end of gogoc.conf #------------------------------------------------------------------------------ gogoc-1_2-RELEASE/gogoc-tsp/man/0040755000000000000000000000000011346561543015000 5ustar rootrootgogoc-1_2-RELEASE/gogoc-tsp/man/man5/0040755000000000000000000000000011346561543015640 5ustar rootrootgogoc-1_2-RELEASE/gogoc-tsp/man/man5/gogoc.conf.50100644000000000000000000002706711346535070017755 0ustar rootroot.\" .\" Copyright (c) 2007 gogo6 Inc. All rights reserved. .\" .\" For license information refer to CLIENT-LICENSE.TXT .\" .\" $Id: gogoc.conf.5,v 1.2 2010/03/12 22:03:36 jasminko Exp $ .\" .\"Th Tunnel Setup Protocol client: File formats manual .Dd May 7, 2007 .Dt GOGOC.CONF 5 .Os BSD 4.2 .Sh NAME .Nm gogoc.conf .Nd gogoCLIENT Configuration File .Sh SYNOPSIS The gogoCLIENT .Xr gogoc 8 is a client program which enables a host to query a tunnel server to establish a tunnel between the host and the server using the TSP protocol. The gogoc configuration file contains information that is read by .Xr gogoc 8 for specific details regarding the server and the tunnel to be established. .Pp .Sh FILE FORMAT This file is designed to be human readable and may be edited with any text editor. The file consists of tokens and values, which are separated by the equal sign. Each "Token=Value" pair must be on their own line. .Pp The different configuration directives(or options) are grouped in the following sections: .Sh BASIC CONFIGURATION .Bl -tag -width -compact .It Sy userid The userid is used for authentication with the server. The TSP protocol supports both anonymous and authenticated tunnels. Refer to the server policies for supported modes and related Services, as well as for how to register your user name. The syntax to use is given below: .Pp userid=user_name .Pp This variable is MANDATORY if you are using an authenticated tunnel. Leave empty if you are using anonymous access. .It Sy passwd passwd=your_password .Pp Leave empty if you are using anonymous access. .It Sy server Name and port number of the tunnel server. This variable is used to specify the gogoSERVER to be queried. An IPv4 or IPv6 address or FQDN (Fully Qualified Domain Name) can be used. The port number is optional. The default TSP port is 3653. .Pp server=host[:port] .Pp server=broker.freenet6.net .Pp server=192.168.1.1:3653 .Pp This variable is MANDATORY. .It Sy auth_method The tunnel negotiation authentication method. If you are using anonymous access, enter `anonymous' here. Otherwise, choose one of the following authentication methods: any|digest-md5|passdss-3des-1|plain .Pp .Pa anonymous sends no username or password. .Pp .Pa any is the preferred one. The most secure mechanism common to the client and the broker will be used. .Pp .Pa digest-md5 sends the username in clear text, but not the password. .Pp .Pa passdss-3des-1 sends the username in clear text, but not the password. .Pp .Pa plain sends both username and password in clear text. .Pp Default: any .El .Sh ROUTER CONFIGURATION .Bl -tag -width -compact .It Sy host_type Set the value of this directive to `router' to configure the machine as a router. By doing so, you will be given a prefix to advertise on a local interface. .Pp host_type=host|router .Pp Default: host .Pp .It Sy prefixlen prefixlen specifies the required prefix length for the gogoCLIENT network. Valid values range from 0 to 64; however, values are usually between 48 and 64. .Pp Default: 64 .Pp .It Sy if_prefix if_prefix is the name of the OS interface that will be configured with the first /64 of the received prefix from the broker. The router advertisement daemon is started to advertise this prefix on the if_prefix interface. .Pp .It Sy dns_server This directive specifies the DNS servers that should be used for reverse DNS delegation of the prefix allocated. .Pp Syntax is: .Pp dns_server=fqdn[:fqdn]... .Pp For example, to set ns1.example.net and ns2.example.net as authoritative DNS servers for reverse DNS of the prefix, this line would be used in gogoc.conf: .Pp dns_server=ns1.example.net:ns2.example.net .Pp NOTE: Never use an IP address as a DNS server name. .El .Sh ADVANCED CONFIGURATION .Bl -tag -width -compact .It Sy tunnel_mode The tunnel encapsulation mode. It can take the following values: .Pp .Pa v6anyv4 This mode lets the broker determine whether or not the gogoCLIENT is behind a NAT. The broker will then inform the gogoCLIENT which tunnel mode to use: v6v4 or v6udpv4. .Pp .Pa v6v4 Explicitly requests an IPv6-in-IPv4 tunnel. .Pp .Pa v6udpv4 Explicitly requests an IPv6-in-UDP-IPv4 tunnel (for clients behind a NAT). This type of tunnel is supported under Linux, FreeBSD and Windows. .Pp .Pa v4v6 Explicitly requests an IPv4-in-IPv6 tunnel (for dual-stack transition mechanism). .Pp Default: v6anyv4 .It Sy auto_retry_connect This directive is used when a keepalive timeout or similar error occurred, resulting in a loss of connectivity with the tunnel endpoint. If you wish the gogoCLIENT to re-establish connectivity with tunnel endpoint when such an error occurs, set this variable to `yes'. .Pp auto_retry_connect=yes|no .Pp Default: yes .It Sy retry_delay The retry_delay directive is used to set the number of seconds to sleep before reattempting to establish a tunnel with the gogoSERVER. It will retry until it succeeds, unless you have set the auto_retry_connect variable to `no'. .Pp Default: 30 .Pp .It Sy keepalive keepalive indicates that this client will send keepalive packets to maintain tunnel activity and detect inactive tunnels (if no response is received from the server). This directive must be set to `yes' when using v6udpv4 tunnels to keep the NAT entry active. .Pp keepalive=yes|no .Pp Default: yes .Pp .It Sy keepalive_interval The keepalive_interval is a suggestion from the gogoCLIENT to the broker for the interval to wait between sending keepalive messages. The broker may impose a different interval value to the client if the suggested value is too low. .Pp keepalive_interval=30 .Pp Default: 30 .Pp .It Sy if_tunnel_v6v4 The logical interface name that will be used for the configured tunnel (IPv6 over IPv4). The syntax is: .Pp if_tunnel_v6v4=name .Pp Under *BSD: gif0 .Pp Under Linux: sit0 .Pp Under Windows: 2 .Pp This variable is MANDATORY. .It Sy if_tunnel_v6udpv4 The logical interface name that will be used for v6udpv4 tunnels (IPv6 over UDPv4). The syntax is: .Pp if_tunnel_v6udpv4=name .Pp Under FreeBSD: tun1 .Pp Under Linux: tun .Pp Under Windows: tunv6 .Pp .It Sy if_tunnel_v4v6 The logical interface name that will be used for v4v6 tunnels (IPv4 over IPv6). The syntax is: .Pp if_tunnel_v4v6=name .It Sy gogoc_dir The directory where the gogoCLIENT program is installed. Binaries, manual pages, this configuration file and templates are all located in this directory. This variable may resemble the following: .Pp gogoc_dir=/usr/local/gogoc .Pp This variable is MANDATORY. .It Sy template This directive indicates which configuration template must be used when configuring the tunnel. The configuration template is a script file, located in the template directory of the package, that contains the system commands to be executed for tunnel setup. The directives are passed to the script file as environment variables. The template directive is normally set when the package is built for the specific operating system. View the contents of the template directory to learn which ones are available. The template name must be the file name without the .sh or .cmd suffix. .Pp template=linux .Pp This variable is MANDATORY. .It Sy proxy_client The proxy_client directive indicates that this client acts as a TSP proxy for a remote client tunnel endpoint machine. It is set to `yes' if the machine running the gogoCLIENT requests a tunnel for another machine. (e.g.: cisco template). This directive must be used in conjunction with a static IPv4 address assigned to the client_v4 variable. .Pp NOTE: proxy_client=yes is incompatible with tunnel_mode=v6udpv4 .Pp Default: no .It Sy client_v4 The IPv4 address of the client tunnel endpoint. If the host has more than one IPv4 address, it is recommended to manually set this variable with its local IPv4 address as the value. If set to auto, it chooses the source IP address used when communicating with the server. This variable may resemble the following: .Pp client_v4=auto|a.b.c.d .Pp Default: auto .It Sy client_v6 This directive is similar te client_v4, except that this one is for users that have enabled IPv4 in IPv6 encapsulation (i.e., DSTM). .Pp client_v6=auto|XX:XX::XX:XX .Pp Default: auto .It Sy broker_list The 'broker_list' directive specifies the name of the file where the broker list received during broker redirection will be saved. .Pp Default: tsp-broker-list.txt .It Sy last_server The 'last_server' directive specifies the name of the file where the address of the last broker to which a connection was successfully established will be saved. .Pp Default: tsp-last-server.txt .It Sy always_use_same_server The value of the 'always_use_same_server' directive determines whether the client should always try to connect to the broker specified by the 'last_server' directive (if any). .Pp Default: no .El .Sh LOGGING CONFIGURATION .Bl -tag -width -compact .It Sy log_file This directive is used to specify the quantity of information that will be logged to the file. Values range inclusively from 0 (no logging) to 3 (full logging). .Pp Default: 0 .It Sy log_stderr This directive is used to specify the quantity of information that will be logged to the standard error device. Values range inclusively from 0 (no logging) to 3 (full logging). .Pp Default: 1 .It Sy log_console This directive is used to specify the quantity of information that will be logged to the console. Values range inclusively from 0 (no logging) to 3 (full logging). .Pp Default: 0 .It Sy log_syslog This directive is used to specify the quantity of information that will be logged to the syslog. Values range inclusively from 0 (no logging) to 3 (full logging). .Pp Default: 0 .It Sy log_filename When logging to file is requested via the 'log_file' directive, the name and path of the file to use may be specified using the 'log_filename' directive. .Pp log_filename=[/path/to/the/]file .Pp Default: gogoc.log .Pp .It Sy log_rotation When logging to file is requested via the 'log_file' directive, log file rotation may be enabled using the 'log_rotation' directive. .Pp When enabled, the contents of the log file will be moved to a backup file just before it reaches the maximum log file size specified via the `log_rotation_size' directive. .Pp The name of the backup file is the name of the original log file with `.' inserted before the file extension. If the file does not have an extension, `.' is appended to the name of the original log file. The timestamp specifies when the rotation occurred. .Pp After the contents of the log file have been moved to the backup file, the original file is cleared, and logging resumes at the beginning of the file. .Pp log_rotation=yes|no .Pp Default: yes .Pp .It Sy log_rotation_size The `log_rotation_size' directive specifies the maximum size a log file may reach before rotation occurs (if rotation has been enabled via the 'log_rotation' directive). .Pp The value is expressed in kilobytes. .Pp log_rotation_size=16|32|128|1024 .Pp Default value: 32 .Pp .It Sy log_rotation_delete The `log_rotation_delete' directive specifies that the log file will be recycled on rotation. No backup log files will be kept. (if rotation has been enabled via the 'log_rotation' directive). .Pp log_rotation_delete=yes|no .Pp Default: no .Pp .It Sy syslog_facility When logging to syslog is requested using the `log' directive, the facility to use may be specified using the `syslog_facility' directive. .Pp Valid values are USER, and LOCAL[0-7]. .Pp syslog_facility=FACILITY .Pp Default: USER .Pp .El .Sh FILES .Bl -tag -width /bin/gogoc.conf -compact .It Pa /bin/gogoc.conf .It Pa /bin/gogoc.conf.sample .El .Sh SEE ALSO .Xr gogoc 8 .Rs Freenet6 Web site: http://www.go6.net .Pp gogo6 Web site: http://www.gogo6.com .Re .\".Sh HISTORY gogoc-1_2-RELEASE/gogoc-tsp/man/man8/0040755000000000000000000000000011346561543015643 5ustar rootrootgogoc-1_2-RELEASE/gogoc-tsp/man/man8/gogoc.80100644000000000000000000000447411346540542017034 0ustar rootroot.\" .\" Copyright (c) 2007 gogo6 Inc. All rights reserved. .\" .\" For license information refer to CLIENT-LICENSE.TXT .\" .\" $Id: gogoc.8,v 1.5 2010/03/12 22:34:10 jasminko Exp $ .\" .Dd May 7, 2007 .Dt GOGOC 8 .Os gogoCLIENT .Sh NAME .Nm gogoc .Nd gogoCLIENT .Sh SYNOPSIS .Nm gogoc .Op Fl h .Op Fl ?\& .Op Fl y .Op Fl n .Op Fl b\& .Nm gogoc .Op Fl f Ar config_file .Op Fl i Ar interface_name .Op Fl u Ar interface_name .Op Fl s Ar interface_name .Op Fl r Ar retry_delay .Sh DESCRIPTION .Nm gogoc provides a means to configure a tunnel obtained from a tunnel server that supports the tunnel setup protocol (TSP). .Nm gogoc will connect to a tunnel server and request a tunnel according to the specifications given in the configuration file. As a background process, it will then monitor the state of the tunnel. In the event of a timeout, gogoc will establish a new tunnel. .Pp .Nm gogoc currently supports three types of tunnels: .Pp .Bl -tag -width .It Sy - v6v4 (IPv6 over IPv4) Supported on FreeBSD, NetBSD, OpenBSD, Linux, Windows, Solaris, Darwin and OpenWRT. .Pp .It Sy - v6udpv4 (IPv6 over UDP over IPv4) Supported on FreeBSD, Linux, Windows, Darwin and OpenWRT. .Pp .It Sy - v4v6 (IPv4 over IPv6 (DSTM)) Supported on FreeBSD and Windows. .Pp .El .Sh ARGUMENTS The following options are available: .Bl -tag -width indent .It Fl h, ?\& Displays a short usage summary and quits. .Pp .It Fl y\& Automatically accept server's public key. .Pp .It Fl n\& Run as a foreground process. .Pp .It Fl b\& Stop trying to reconnect upon first error received. .Pp .It Fl f Ar configuration_file Specifies a different configuration file. .br Default is /etc/gogoc/gogoc.conf. .Pp .It Fl s Ar interface_name Overrides .Nm client_v4 in .Xr gogoc.conf 5 .Pp .It Fl i Ar interface_name Overrides .Nm if_tunnel_v6v4 in .Xr gogoc.conf 5 .Pp .It Fl u Ar interface_name Overrides .Nm if_tunnel_v6udpv4 in .Xr gogoc.conf 5 .Pp .It Fl r Ar retry_delay Overrides .Nm retry_delay in .Xr gogoc.conf 5 .Pp .El .Sh SEE ALSO .Xr gogoc.conf 5 .br http://www.gogo6.com .Sh ACKNOWLEDGMENT This software uses code taken from other organizations as : .Bl -tag -width indent .It - Ar "RSA data security for md5." .It - Ar "The Apache Software Foundation for Base64 encoding and decoding." .El .Sh AUTHORS gogo6 Inc. .br http://www.gogo6.com .br support@gogo6.com .br gogoc-1_2-RELEASE/gogoc-tsp/man/Makefile0100644000000000000000000000075111301544576016436 0ustar rootroot# $Id: Makefile,v 1.1 2009/11/20 16:53:18 jasminko Exp $ # # Copyright (c) 2007 gogo6 Inc. All rights reserved. # # For license information refer to CLIENT-LICENSE.TXT # all: install: @echo Installing man pages @mkdir -p $(INSTALL_MAN)/man5 @mkdir -p $(INSTALL_MAN)/man8 @cp man5/gogoc.conf.5 $(INSTALL_MAN)/man5 @cp man8/gogoc.8 $(INSTALL_MAN)/man8 @echo "To view man pages, run :" @echo " man -M $(INSTALL_MAN) gogoc" @echo " man -M $(INSTALL_MAN) gogoc.conf" clean: gogoc-1_2-RELEASE/gogoc-tsp/.cvsignore0100644000000000000000000000000011301065042016170 0ustar rootrootgogoc-1_2-RELEASE/gogoc-tsp/Makefile0100644000000000000000000001416211345001542015651 0ustar rootroot# ########################################################################### # # $Id: Makefile,v 1.2 2010/03/07 19:49:54 carl Exp $ # # Copyright (c) 2007 gogo6 Inc. All rights reserved. # # For license information refer to CLIENT-LICENSE.TXT # # Description: GNU Makefile for gogoCLIENT application. # This application requires the following modules: # - gogoc-pal : Platform Abstraction Layer # - gogoc-config : Configuration Subsystem # - gogoc-messaging: Messaging Subsystem # # Usage: # make [platform=] [DEBUG=1] all # make [platform=] install # This makefile will attempt to detect your platform if not supplied. # # Author: Charles Nepveu # # Date: October 2007 # # ########################################################################### # # NOTE: This makefile MUST be interpreted by GNU make. PWD :=$(shell pwd) PLATFORM_DIR :=$(PWD)/platform OBJS_DIR :=$(PWD)/objs BIN_DIR :=$(PWD)/bin TARGET :=$(BIN_DIR)/gogoc GOGOCPAL_DIR :=$(PWD)/../gogoc-pal GOGOCPAL_INCDIR:=$(GOGOCPAL_DIR)/out_inc GOGOCPAL_DEFDIR:=$(GOGOCPAL_DIR)/defs GOGOCPAL_LIBDIR:=$(GOGOCPAL_DIR)/out_lib GOGOCCFG_DIR :=$(PWD)/../gogoc-config GOGOCCFG_INCDIR:=$(GOGOCCFG_DIR) GOGOCCFG_LIBDIR:=$(GOGOCCFG_DIR)/lib GOGOCMSG_DIR :=$(PWD)/../gogoc-messaging GOGOCMSG_INCDIR:=$(GOGOCMSG_DIR) GOGOCMSG_LIBDIR:=$(GOGOCMSG_DIR)/lib PLATFORM :=$(shell [ -z "$(platform)" ] && uname | tr "[A-Z]" "[a-z]" || echo "$(platform)" ) SUPPORTED_PLATFORMS=linux netbsd freebsd openbsd darwin sunos gogocpe INSTALL_DIR :=$(installdir) INSTALL_BIN :=$(INSTALL_DIR)/bin INSTALL_MAN :=$(INSTALL_DIR)/man INSTALL_TEMPL :=$(INSTALL_DIR)/template SUBDIRS=$(PWD)/src/lib \ $(PWD)/src/net \ $(PWD)/src/tsp \ $(PWD)/src/xml \ $(PLATFORM_DIR)/unix-common \ $(PLATFORM_DIR)/$(PLATFORM) \ $(PWD)/template \ $(PWD)/conf \ $(PWD)/man CC_INC_PATHS=-I$(PLATFORM_DIR)/$(PLATFORM) -I$(PWD)/include -I$(GOGOCPAL_INCDIR) -I$(GOGOCPAL_DEFDIR) -I$(GOGOCCFG_INCDIR) -I$(GOGOCMSG_INCDIR) LD_LIB_PATHS=-L$(GOGOCPAL_LIBDIR) -L$(GOGOCCFG_LIBDIR) -L$(GOGOCMSG_LIBDIR) LD_LIBRARIES=-lgogocpal -lgogocconfig -lgogocmessaging # Export these variables to sub-makes. export PLATFORM_DIR PLATFORM BIN_DIR OBJS_DIR TARGET DEBUG CC_INC_PATHS LD_LIB_PATHS LD_LIBRARIES INSTALL_DIR INSTALL_BIN INSTALL_MAN INSTALL_TEMPL # # ########################################################################### # .PHONY: all platform-check check-gogoc-pal check-gogoc-config check-gogoc-messaging build-gogoc check-gogoc-install install clean cleanall all: platform-check check-gogoc-pal check-gogoc-config check-gogoc-messaging build-gogoc # This makefile target will check the platform. # platform-check: @for plat in ${SUPPORTED_PLATFORMS} ; do \ [ "${PLATFORM}" = "$$plat" ] && platform_ok=xxx || platform_ok=$$platform_ok ; \ done && ([ -z "$$platform_ok" ] && { \ echo ; \ echo "Error: Target platform <${PLATFORM}> is invalid!"; \ echo "Syntax: make platform= all"; \ echo ; \ echo " where is one of the following:"; \ echo " linux for Linux." ; \ echo " freebsd for FreeBSD." ; \ echo " openbsd for OpenBSD." ; \ echo " netbsd for NetBSD." ; \ echo " darwin for Mac OS X darwin."; \ echo " openwrt for OpenWRT." ; \ echo " sunos for Sun/Solaris." ; \ echo ; \ exit 1;\ } || echo "Building gogoCLIENT for platform ${PLATFORM} ..." ; ) # This makefile target will check and build the gogoCLIENT Platform # Abstraction Layer if it is not built. # check-gogoc-pal: @[ -d ${GOGOCPAL_DIR} ] || { \ echo "gogoCLIENT Platform Abstraction Layer module is not found. (${GOGOCPAL_DIR})"; \ exit 1 ; \ } @[ -f ${GOGOCPAL_LIBDIR}/libgogocpal.a ] || { \ echo "Building gogoc-pal module ..." ; \ $(MAKE) -C ${GOGOCPAL_DIR} ; \ } # This makefile target will check and build the gogoCLIENT Configuration # Subsystem if it is not built. # check-gogoc-config: @[ -d ${GOGOCCFG_DIR} ] || { \ echo "gogoCLIENT Configuration Subsystem module is not found. (${GOGOCCFG_DIR})"; \ exit 1 ; \ } @[ -f ${GOGOCCFG_LIBDIR}/libgogocconfig.a ] || { \ echo "Building gogoc-config module ..." ; \ $(MAKE) -C ${GOGOCCFG_DIR} ; \ } # This makefile target will check and build the gogoCLIENT Messaging # Subsystem if it is not built. # check-gogoc-messaging: @[ -d ${GOGOCMSG_DIR} ] || { \ echo "gogoCLIENT Messaging Subsystem module is not found. (${GOGOCMSG_DIR})"; \ exit 1 ; \ } @[ -f ${GOGOCMSG_LIBDIR}/libgogocmessaging.a ] || { \ echo "Building gogoc-messaging module ..." ; \ $(MAKE) -C ${GOGOCMSG_DIR} ; \ } # This makefile target will build the gogoCLIENT. # build-gogoc: mkdir -p $(OBJS_DIR) mkdir -p $(BIN_DIR) @for dir in ${SUBDIRS}; do \ $(MAKE) -C $$dir all || exit 1; \ done # This makefile target will install the gogoCLIENT. # check-gogoc-install: @[ -n "$(INSTALL_DIR)" ] || { \ echo ; \ echo "Error: You must specify the install directory"; \ echo "Syntax: make [platform=] installdir= install"; \ echo ; \ exit 1;\ } install: check-gogoc-install all @mkdir -p $(INSTALL_DIR) @mkdir -p $(INSTALL_BIN) @mkdir -p $(INSTALL_MAN) @mkdir -p $(INSTALL_TEMPL) @for dir in ${SUBDIRS}; do \ $(MAKE) -C $$dir install || exit 1; \ done @cp $(TARGET) $(INSTALL_BIN) @cp $(BIN_DIR)/gogoc.conf.sample $(INSTALL_BIN) @[ -f $(INSTALL_BIN)/gogoc.conf ] || { \ cp $(INSTALL_BIN)/gogoc.conf.sample $(INSTALL_BIN)/gogoc.conf; \ } # This makefile target will clean the build tree of the gogoCLIENT. # clean: @for dir in ${SUBDIRS}; do \ $(MAKE) -C $$dir clean || exit 1; \ done rm -rf $(TARGET) $(BIN_DIR)/gogoc.conf.sample $(OBJS_DIR) # This makefile target will clean the build tree of the gogoCLIENT, # and the submodules. # cleanall: clean $(MAKE) -C ${GOGOCMSG_DIR} clean $(MAKE) -C ${GOGOCCFG_DIR} clean $(MAKE) -C ${GOGOCPAL_DIR} clean gogoc-1_2-RELEASE/gogoc-tsp/build-wince.cmd0100644000000000000000000000301211301544567017103 0ustar rootroot@ECHO OFF REM ************************************************************************* REM * $Id: build-wince.cmd,v 1.1 2009/11/20 16:53:11 jasminko Exp $ REM * REM * Batch file used to build the gogoCLIENT. REM * REM * Prerequisites: REM * - Visual Studio 2005 (SP1) REM * - Windows Embedded CE (5 or 6) SDK REM * - DEVENV executable in %PATH% REM * REM * Usage: REM * build-wince [/Release /Debug] REM * REM ************************************************************************* REM Defaults: SET CONFIGURATION=Release SET PLATFORM= SET COMMAND=Build REM Overrides: :ParseArgs IF /I "%~1" == "/?" GOTO Usage IF /I "%~1" == "-h" GOTO Usage IF /I "%~1" == "/Release" SET CONFIGURATION=Release& SHIFT& GOTO ParseArgs IF /I "%~1" == "/Debug" SET CONFIGURATION=Debug& SHIFT& GOTO ParseArgs IF /I "%~1" == "/Clean" SET COMMAND=Clean& SHIFT& GOTO ParseArgs IF "%~1" EQU "" GOTO Done_Args ECHO Unknown command-line switch: %~1 GOTO Usage :Done_Args REM Build the target ECHO Launching build of gogoc solution... ECHO Configuration: COMMAND=%COMMAND% CONFIGURATION=%CONFIGURATION% ECHO. DEVENV platform\wince\gogoc.sln /%COMMAND% "%CONFIGURATION%" IF %ERRORLEVEL% == 0 GOTO build_ok GOTO build_error :Usage ECHO. ECHO Usage: ECHO %0 ^[^/Release^|^/Debug^] ^[^/Clean^] ECHO. ECHO Defaults: ^/Release ECHO. GOTO the_end :build_ok ECHO. ECHO Build of gogoc solution completed successfully. GOTO the_end :build_error ECHO. ECHO Build of gogoc solution FAILED! :the_end gogoc-1_2-RELEASE/gogoc-tsp/build-winpc.cmd0100644000000000000000000000376311301544567017133 0ustar rootroot@ECHO OFF REM ************************************************************************* REM * $Id: build-winpc.cmd,v 1.1 2009/11/20 16:53:11 jasminko Exp $ REM * REM * Batch file used to build the gogoCLIENT. REM * REM * Prerequisites: REM * - Visual Studio 2005 (SP1) REM * - Windows Vista RTM SDK (Integrated in VS2005SP1) REM * - DEVENV executable in %PATH% REM * REM * Usage: REM * build-winpc [/Release /HACCESS-Release /Debug /HACCESS-Debug] [/Win32 /x64] REM * REM ************************************************************************* REM Defaults: SET CONFIGURATION=Release SET PLATFORM=Win32 SET COMMAND=Build REM Overrides: :ParseArgs IF /I "%~1" == "/?" GOTO Usage IF /I "%~1" == "-h" GOTO Usage IF /I "%~1" == "/Release" SET CONFIGURATION=Release& SHIFT& GOTO ParseArgs IF /I "%~1" == "/HACCESS-Release" SET CONFIGURATION=HACCESS-Release& SHIFT& GOTO ParseArgs IF /I "%~1" == "/Debug" SET CONFIGURATION=Debug& SHIFT& GOTO ParseArgs IF /I "%~1" == "/HACCESS-Debug" SET CONFIGURATION=HACCESS-Debug& SHIFT& GOTO ParseArgs IF /I "%~1" == "/Win32" SET PLATFORM=Win32& SHIFT& GOTO ParseArgs IF /I "%~1" == "/x64" SET PLATFORM=x64& SHIFT& GOTO ParseArgs IF /I "%~1" == "/Clean" SET COMMAND=Clean& SHIFT& GOTO ParseArgs IF "%~1" EQU "" GOTO Done_Args ECHO Unknown command-line switch: %~1 GOTO Usage :Done_Args REM Build the target ECHO Launching build of gogoc solution... ECHO Configuration: COMMAND=%COMMAND% PLATFORM=%PLATFORM% CONFIGURATION=%CONFIGURATION% ECHO. DEVENV platform\winpc\gogoc.sln /%COMMAND% "%CONFIGURATION%|%PLATFORM%" IF %ERRORLEVEL% == 0 GOTO build_ok GOTO build_error :Usage ECHO. ECHO Usage: ECHO %0 ^[^/Release^|^/HACCESS-Release^|^/Debug^|^/HACCESS-Debug^] ^[^/Win32^|^/x64^] ^[^/Clean^] ECHO. ECHO Defaults: ^/Release ^/Win32 ECHO. GOTO the_end :build_ok ECHO. ECHO Build of gogoc solution completed successfully. GOTO the_end :build_error ECHO. ECHO Build of gogoc solution FAILED! :the_end gogoc-1_2-RELEASE/gogoc-tsp/include/0040755000000000000000000000000011346561546015653 5ustar rootrootgogoc-1_2-RELEASE/gogoc-tsp/include/base64.h0100644000000000000000000000200611301544570017070 0ustar rootroot/* ----------------------------------------------------------------------------- base64.h - Base64 encoding and decoding prototypes. ----------------------------------------------------------------------------- $Id: base64.h,v 1.1 2009/11/20 16:53:12 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ sint32_t base64decode_len (const char *bufcoded); sint32_t base64decode (char *bufplain, const char *bufcoded); sint32_t base64decode_binary (unsigned char *bufplain, const char *bufcoded); sint32_t base64encode_len (sint32_t len); sint32_t base64encode (char *encoded, const char *string, sint32_t len); sint32_t base64encode_binary (char *encoded, const unsigned char *string, sint32_t len); gogoc-1_2-RELEASE/gogoc-tsp/include/bufaux.h0100644000000000000000000000335011301544571017302 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: bufaux.h,v 1.1 2009/11/20 16:53:13 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ /* $NetBSD: bufaux.h,v 1.1.1.7 2002/04/22 07:37:19 itojun Exp $ */ /* $OpenBSD: bufaux.h,v 1.18 2002/04/20 09:14:58 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * * As far as I am concerned, the code I have written for this software * can be used freely for any purpose. Any derived versions of this * software must be clearly marked as such, and if the derived work is * incompatible with the protocol description in the RFC file, it must be * called by a name other than "ssh" or "Secure Shell". */ #ifndef BUFAUX_H #define BUFAUX_H #ifndef NO_OPENSSL #include "buffer.h" #include void buffer_put_bignum (Buffer *, BIGNUM *); void buffer_get_bignum (Buffer *, BIGNUM *); uint32_t buffer_get_int (Buffer *); void buffer_put_int (Buffer *, uint32_t); sint32_t buffer_get_octet (Buffer *); void buffer_put_octet (Buffer *, sint32_t); void * buffer_get_string (Buffer *, uint32_t *); void buffer_put_string (Buffer *, const void *, uint32_t); void buffer_put_cstring (Buffer *, const char *); #endif // NO_OPENSSL #endif // BUFAUX_H gogoc-1_2-RELEASE/gogoc-tsp/include/buffer.h0100644000000000000000000000373011301544571017263 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: buffer.h,v 1.1 2009/11/20 16:53:13 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ /* $NetBSD: buffer.h,v 1.1.1.6 2002/03/08 01:20:34 itojun Exp $ */ /* $OpenBSD: buffer.h,v 1.11 2002/03/04 17:27:39 stevesk Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * Code for manipulating FIFO buffers. * * As far as I am concerned, the code I have written for this software * can be used freely for any purpose. Any derived versions of this * software must be clearly marked as such, and if the derived work is * incompatible with the protocol description in the RFC file, it must be * called by a name other than "ssh" or "Secure Shell". */ #ifndef BUFFER_H #define BUFFER_H typedef struct { uint8_t *buf; /* Buffer for data. */ size_t alloc; /* Number of bytes allocated for data. */ size_t offset; /* Offset of first byte containing data. */ size_t end; /* Offset of last byte containing data. */ } Buffer; void buffer_init (Buffer *); void buffer_clear (Buffer *); void buffer_free (Buffer *); size_t buffer_len (Buffer *); void * buffer_ptr (Buffer *); void buffer_append (Buffer *, const void *, size_t); void * buffer_append_space (Buffer *, size_t); void buffer_get (Buffer *, void *, uint32_t); void buffer_consume (Buffer *, uint32_t); void buffer_consume_end (Buffer *, uint32_t); #endif /* BUFFER_H */ gogoc-1_2-RELEASE/gogoc-tsp/include/cli.h0100644000000000000000000000110611301544571016554 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: cli.h,v 1.1 2009/11/20 16:53:13 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ #ifndef _CLI_H_ #define _CLI_H_ sint32_t ask (char *question, ...); void ParseArguments (sint32_t, char *[], tConf *); #endif gogoc-1_2-RELEASE/gogoc-tsp/include/cnfchk.h0100644000000000000000000000065011301544571017244 0ustar rootroot/* --------------------------------------------------------------------------- $Id: cnfchk.h,v 1.1 2009/11/20 16:53:13 jasminko Exp $ --------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. --------------------------------------------------------------------------- */ int tspFixConfig(void); gogoc-1_2-RELEASE/gogoc-tsp/include/config.h0100644000000000000000000000717211345003432017255 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: config.h,v 1.3 2010/03/07 20:05:46 carl Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ #ifndef CONFIG_H #define CONFIG_H /* these globals are defined by US used by alot of things in */ #define STR_CONFIG_TUNNELMODE_V6ANYV4 "v6anyv4" #define STR_CONFIG_TUNNELMODE_V6V4 "v6v4" #define STR_CONFIG_TUNNELMODE_V6UDPV4 "v6udpv4" #define STR_CONFIG_TUNNELMODE_V4V6 "v4v6" #define STR_CONFIG_TUNNELMODE_DSLITE "dslite" #define STR_XML_TUNNELMODE_V6ANYV4 "v6anyv4" #define STR_XML_TUNNELMODE_V6V4 "v6v4" #define STR_XML_TUNNELMODE_V6UDPV4 "v6udpv4" #define STR_XML_TUNNELMODE_V4V6 "v4v6" #ifdef FALSE #undef FALSE #endif #ifdef TRUE #undef TRUE #endif #define STR_CONFIG_BOOLEAN_FALSE "no" #define STR_CONFIG_BOOLEAN_TRUE "yes" typedef enum { FALSE=0, TRUE } tBoolean; typedef enum { V6V4=1, V6UDPV4=2, V6ANYV4=3, V4V6=4, DSLITE=5, } tTunnelMode; typedef struct stConf { char *tsp_dir, *server, *dslite_server, *dslite_client, *userid, *passwd, *auth_method, *client_v4, *client_v6, *protocol, *if_tunnel_v6v4, *if_tunnel_v6udpv4, *if_tunnel_v4v6, *dns_server, *routing_info, *if_prefix, *template, *host_type, *log_filename, *last_server_file, *haccess_document_root, *broker_list_file; sint32_t keepalive_interval; sint32_t prefixlen; sint32_t retry_delay; sint32_t retry_delay_max; sint32_t syslog_facility; sint32_t transport; sint32_t log_rotation_size; sint16_t log_level_stderr; sint16_t log_level_syslog; sint16_t log_level_console; sint16_t log_level_file; tBoolean keepalive; tBoolean syslog; tBoolean proxy_client; tBoolean log_rotation; tBoolean log_rotation_delete; tBoolean always_use_same_server; tBoolean auto_retry_connect; tTunnelMode tunnel_mode; tBoolean haccess_web_enabled; tBoolean haccess_proxy_enabled; tBoolean boot_mode; tBoolean nodaemon; tBoolean no_questions; // These are run-time, dynamically computed values // char addr_local_v4[INET6_ADDRSTRLEN]; uint16_t port_local_v4; char addr_remote_v4[INET6_ADDRSTRLEN]; uint16_t port_remote_v4; } tConf; typedef struct syslog_facility { char *string; sint32_t value; } syslog_facility_t; /* Valid syslog_facility values */ #define STR_CONFIG_SLOG_FACILITY_USER "USER" #define STR_CONFIG_SLOG_FACILITY_LOCAL0 "LOCAL0" #define STR_CONFIG_SLOG_FACILITY_LOCAL1 "LOCAL1" #define STR_CONFIG_SLOG_FACILITY_LOCAL2 "LOCAL2" #define STR_CONFIG_SLOG_FACILITY_LOCAL3 "LOCAL3" #define STR_CONFIG_SLOG_FACILITY_LOCAL4 "LOCAL4" #define STR_CONFIG_SLOG_FACILITY_LOCAL5 "LOCAL5" #define STR_CONFIG_SLOG_FACILITY_LOCAL6 "LOCAL6" #define STR_CONFIG_SLOG_FACILITY_LOCAL7 "LOCAL7" /* Valid log values */ #define STR_CONFIG_LOG_DESTINATION_STDERR "stderr" #define STR_CONFIG_LOG_DESTINATION_SYSLOG "syslog" #define STR_CONFIG_LOG_DESTINATION_CONSOLE "console" #define STR_CONFIG_LOG_DESTINATION_FILE "file" /* imports defined in the platform dependant file */ extern char *FileName; extern char *LogFile; extern char *ScriptInterpretor; extern char *ScriptExtension; extern char *ScriptDir; extern char *TspHomeDir; extern char DirSeparator; /* functions exported */ gogoc_status tspInitialize (sint32_t, char *[], tConf *); #endif gogoc-1_2-RELEASE/gogoc-tsp/include/console.h0100644000000000000000000000111211301544571017444 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: console.h,v 1.1 2009/11/20 16:53:13 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2006 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ #ifndef _CONSOLE_H_ #define _CONSOLE_H_ #if !defined(WINCE) sint32_t enable_console_input (void); sint32_t disable_console_input (void); #endif #endif gogoc-1_2-RELEASE/gogoc-tsp/include/deque.h0100644000000000000000000000323511301544571017115 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: deque.h,v 1.1 2009/11/20 16:53:13 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ /* * File : DEQUE.H * * Peter Yard 02 Jan 1993. */ #ifndef DEQUEUE__H #define DEQUEUE__H #define True_ 1 #define False_ 0 typedef struct nodeptr datanode; typedef struct nodeptr { void *data ; datanode *prev, *next ; } node ; typedef struct { node *head, *tail, *cursor; int size, sorted, item_deleted; } queue; typedef struct { void *dataptr; node *loc ; } index_elt ; int Q_Init(queue *q); int Q_Empty(queue *q); int Q_Size(queue *q); int Q_Start(queue *q); int Q_End(queue *q); int Q_PushHead(queue *q, void *d); int Q_PushTail(queue *q, void *d); void *Q_First(queue *q); void *Q_Last(queue *q); void *Q_PopHead(queue *q); void *Q_PopTail(queue *q); void *Q_Next(queue *q); void *Q_Previous(queue *q); void *Q_DelCur(queue *q); void *Q_Get(queue *q); int Q_Put(queue *q, void *data); int Q_Sort(queue *q, int (*Comp)(const void *, const void *)); int Q_Find(queue *q, void *data, int (*Comp)(const void *, const void *)); void *Q_Seek(queue *q, void *data, int (*Comp)(const void *, const void *)); int Q_Insert(queue *q, void *data, int (*Comp)(const void *, const void *)); #endif /* DEQUEUE__H */ gogoc-1_2-RELEASE/gogoc-tsp/include/dns.h0100644000000000000000000000363011301544572016576 0ustar rootroot/* ----------------------------------------------------------------------------- dns.h - Dynamic DNS update define ----------------------------------------------------------------------------- $Id: dns.h,v 1.1 2009/11/20 16:53:14 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ #ifndef _DNS_H_ #define _DNS_H_ #define DNS_UPDATE_PORT 853 #define DNS16SZ 2 #define DNS32SZ 4 /* * RFC 1035 defines the maximum encoded name length as 255, * which means the ascii representation is limited to 253. */ #define DNS_NAME_SIZE 253 #define DNS_LABEL_SIZE 63 #define DNS_HEADER_SIZE 12 #define DNS_BUFFER_SIZE 512 /* The proxy-ddns will overwrite the TTL value */ #define DNS_DEFAULT_TTL 3600 /* DNS opcode */ #define DNS_OPCODE_UPDATE 5 /* DNS type */ #define DNS_TYPE_SOA 6 #define DNS_TYPE_AAAA 28 #define DNS_TYPE_AAAA_SIZE 16 #define DNS_TYPE_ANY 255 /* DNS class */ #define DNS_CLASS_IN 1 #define DNS_CLASS_ANY 255 typedef enum { DNS_RCODE_NOERROR = 0, DNS_RCODE_FORMERR = 1, DNS_RCODE_SERVFAIL = 2, DNS_RCODE_NXDOMAIN = 3, DNS_RCODE_NOTIMP = 4, DNS_RCODE_REFUSED = 5, DNS_RCODE_YXDOMAIN = 6, DNS_RCODE_YXRRSET = 7, DNS_RCODE_NXRRSET = 8, DNS_RCODE_NOTAUTH = 9, DNS_RCODE_NOTZONE = 10, DNS_RCODE_11 = 11, DNS_RCODE_12 = 12, DNS_RCODE_13 = 13, DNS_RCODE_14 = 14, DNS_RCODE_15 = 15 } tDNSRCode; /* Public functions */ pal_socket_t DNSUpdateConnect (char *Server); tDNSRCode DNSUpdateAddAAAA (pal_socket_t Socket, char *Name, char *Domain, char *AAAA); tDNSRCode DNSUpdateDelRRSets (pal_socket_t Socket, char *Name, char *Domain); sint32_t DNSUpdateClose (pal_socket_t Socket); #endif /* _DNS_H_ */ gogoc-1_2-RELEASE/gogoc-tsp/include/errors.h0100644000000000000000000000256411301544572017333 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: errors.h,v 1.1 2009/11/20 16:53:14 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ #ifndef _ERRORS_H_ #define _ERRORS_H_ /* globals */ #ifdef NO_ERROR #undef NO_ERROR #endif #ifdef TSP_ERROR #undef TSP_ERROR #endif #ifdef SOCKET_ERROR #undef SOCKET_ERROR #endif #ifdef INTERFACE_SETUP_FAILED #undef INTERFACE_SETUP_FAILED #endif #ifdef KEEPALIVE_TIMEOUT #undef KEEPALIVE_TIMEOUT #endif #ifdef TUNNEL_ERROR #undef TUNNEL_ERROR #endif typedef enum { NO_ERROR = 0, NO_ERROR_SHOW_HELP, TSP_ERROR, SOCKET_ERROR, INTERFACE_SETUP_FAILED, KEEPALIVE_TIMEOUT, KEEPALIVE_ERROR, TUNNEL_ERROR, TSP_VERSION_ERROR, AUTHENTICATION_ERROR, LEASE_EXPIRED, SERVER_SIDE_ERROR, INVALID_ARGUMENTS, MEMORY_ERROR, INVALID_SERVER, INVALID_CONFIG_FILE, INVALID_CLIENT_IPV4, INVALID_CLIENT_IPV6, LOGGING_CONFIGURATION_ERROR, BROKER_REDIRECTION, BROKER_REDIRECTION_ERROR, SOCKET_ERROR_CANT_CONNECT, INITIALIZATION_ERROR, #ifdef HACCESS HACCESS_INITIALIZATION_ERROR, HACCESS_SETUP_ERROR, HACCESS_EXPOSE_DEVICES_ERROR #endif } tErrors; #endif gogoc-1_2-RELEASE/gogoc-tsp/include/getput.h0100644000000000000000000000443611301544572017327 0ustar rootroot/* --------------------------------------------------------------------------- $Id: getput.h,v 1.1 2009/11/20 16:53:14 jasminko Exp $ --------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. --------------------------------------------------------------------------- */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * Macros for storing and retrieving data in msb first and lsb first order. * * As far as I am concerned, the code I have written for this software * can be used freely for any purpose. Any derived versions of this * software must be clearly marked as such, and if the derived work is * incompatible with the protocol description in the RFC file, it must be * called by a name other than "ssh" or "Secure Shell". */ #ifndef GETPUT_H #define GETPUT_H /*------------ macros for storing/extracting msb first words -------------*/ #define GET_64BIT(cp) (((u_int64_t)(u_char)(cp)[0] << 56) | \ ((u_int64_t)(u_char)(cp)[1] << 48) | \ ((u_int64_t)(u_char)(cp)[2] << 40) | \ ((u_int64_t)(u_char)(cp)[3] << 32) | \ ((u_int64_t)(u_char)(cp)[4] << 24) | \ ((u_int64_t)(u_char)(cp)[5] << 16) | \ ((u_int64_t)(u_char)(cp)[6] << 8) | \ ((u_int64_t)(u_char)(cp)[7])) #define GET_32BIT(cp) (((u_long)(u_char)(cp)[0] << 24) | \ ((u_long)(u_char)(cp)[1] << 16) | \ ((u_long)(u_char)(cp)[2] << 8) | \ ((u_long)(u_char)(cp)[3])) #define GET_16BIT(cp) (((u_long)(u_char)(cp)[0] << 8) | \ ((u_long)(u_char)(cp)[1])) #define PUT_64BIT(cp, value) do { \ (cp)[0] = (value) >> 56; \ (cp)[1] = (value) >> 48; \ (cp)[2] = (value) >> 40; \ (cp)[3] = (value) >> 32; \ (cp)[4] = (value) >> 24; \ (cp)[5] = (value) >> 16; \ (cp)[6] = (value) >> 8; \ (cp)[7] = (value); } while (0) #define PUT_32BIT(cp, value) do { \ (cp)[0] = (value) >> 24; \ (cp)[1] = (value) >> 16; \ (cp)[2] = (value) >> 8; \ (cp)[3] = (value); } while (0) #define PUT_16BIT(cp, value) do { \ (cp)[0] = (value) >> 8; \ (cp)[1] = (value); } while (0) #endif /* GETPUT_H */ gogoc-1_2-RELEASE/gogoc-tsp/include/gogoc_status.h0100644000000000000000000001060111301544572020507 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: gogoc_status.h,v 1.1 2009/11/20 16:53:14 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2008 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. This module contains the status context and status number definition for the scope of the gogoCLIENT. TSP protocol codes are also defined here. ----------------------------------------------------------------------------- */ #ifndef __GOGOC_STATUS_H__ #define __GOGOC_STATUS_H__ // The status API can be defined using simple MACROs or inline functions. // -> Use MACROs. #define GOGOC_STATUS_MACRO // The gogoc_status type is defined as a 32-bit unsigned integer. // The lower 16 bits represent the status number, and the upper 16 bits the // status context. typedef uint32_t gogoc_status; // Context definitions. Context definitions must be <= 0x0000FFFF. enum gogoc_status_contexts { CTX_UNSPECIFIED = 0, // Unspecified context. CTX_CFGVALIDATION, // Configuration validation. CTX_NETWORKINIT, // Network initialization. CTX_NETWORKCONNECT, // Network connection. CTX_TSPCAPABILITIES, // TSP session: Capabilities. CTX_TSPAUTHENTICATION, // TSP session: Authentication. CTX_TSPTUNNEGOTIATION, // TSP session: Tunnel negotiation. CTX_TUNINTERFACESETUP, // Local Tunnel Setup. CTX_TUNNELLOOP, // Tunnel Lifetime. CTX_GOGOCTEARDOWN // Teardown / Exit Process. }; // Defined locally in tsp_client.c. !!!UPDATE if you ADD/REMOVE contexts!!! extern const char * GOGOCStatusContext[]; // Status definition. Status definitions must be <= 0x0000FFFF. enum gogoc_status_codes { SUCCESS = 0, ERR_WINSOCK_INIT, ERR_MEMORY_STARVATION, ERR_INVAL_CFG_FILE, ERR_INVAL_GOGOC_ADDRESS, ERR_INVAL_CLIENT_ADDR, ERR_FAIL_LOG_INIT, ERR_FAIL_LAST_SERVER, ERR_FAIL_RESOLV_ADDR, ERR_FAIL_SOCKET_CONNECT, ERR_SOCKET_IO, ERR_INVAL_TSP_VERSION, ERR_TSP_SERVER_TOO_BUSY, ERR_TSP_GENERIC_ERROR, ERR_BROKER_REDIRECTION, ERR_TUNMODE_NOT_AVAILABLE, ERR_AUTHENTICATION_FAILURE, ERR_NO_COMMON_AUTHENTICATION, ERR_INTERFACE_SETUP_FAILED, ERR_BAD_TUNNEL_PARAM, ERR_KEEPALIVE_ERROR, ERR_KEEPALIVE_TIMEOUT, ERR_TUN_LEASE_EXPIRED, ERR_TUNNEL_IO, ERR_HACCESS_INIT, ERR_HACCESS_SETUP, ERR_HACCESS_EXPOSE_DEVICES, // Events. EVNT_BROKER_REDIRECTION = 0x0000E001, }; // TSP protocol statuses and errors. From HexOS/hexosd/hex_tsp_protocol.h:55 enum tsp_protocol_codes { TSP_PROTOCOL_SUCCESS = 200, TSP_PROTOCOL_AUTH_FAILED = 300, TSP_PROTOCOL_NO_TUNNELS = 301, TSP_PROTOCOL_UNSUP_TSP_VER = 302, TSP_PROTOCOL_UNSUP_TUN_MODE = 303, TSP_PROTOCOL_UNDEFINED = 310, TSP_PROTOCOL_INVALID_REQUEST = 500, TSP_PROTOCOL_INVALID_IPV4 = 501, TSP_PROTOCOL_INVALID_IPV6 = 502, TSP_PROTOCOL_IPV4_PREFIX_ALREADY_USED = 506, TSP_PROTOCOL_REQ_PREFIX_LEN_UNAVAILABLE = 507, TSP_PROTOCOL_DNS_DELEGATION_ERROR = 509, TSP_PROTOCOL_UNSUPP_PREFIX_LEN = 518, TSP_PROTOCOL_MISSING_PREFIX_LEN = 520, TSP_PROTOCOL_REQ_IN_PROGRESS = 521, TSP_PROTOCOL_PREFIX_REQ_FOR_ANONYMOUS = 522, TSP_PROTOCOL_SERVER_TOO_BUSY = 530, // added for redirection PROTOTYPE. TSP_PROTOCOL_REDIRECT = 1200 }; #define STATUS_SUCCESS_INIT make_status(CTX_UNSPECIFIED, SUCCESS) // The status API can be defined using simple MACROs or inline functions. #ifdef GOGOC_STATUS_MACRO // GOGOC status macro definitions. #define make_status(stat_ctx,stat_num) ((gogoc_status)(stat_num | (stat_ctx << 16))) #define status_context(stat) ((uint32_t)((stat & 0xFFFF0000) >> 16)) #define status_number(stat) ((uint32_t)(stat & 0x0000FFFF)) #else // GOGOC status inline function definitions. inline gogoc_status make_status ( uint32_t stat_ctx, uint32_t stat_num ) { return (stat_num | (stat_ctx << 16)); } inline uint32_t status_context ( gogoc_status stat ) { return ((stat & 0xFFFF0000) >> 16); } inline uint32_t status_number ( gogoc_status stat ) { return (stat & 0x0000FFFF); } #endif #endif // __GOGOC_STATUS_H__ gogoc-1_2-RELEASE/gogoc-tsp/include/hex_strings.h0100644000000000000000000012106511345002057020345 0ustar rootroot/* ----------------------------------------------------------------------------- hex_strings.h - Definitions for strings used in the gogoc application. ----------------------------------------------------------------------------- $Id: hex_strings.h,v 1.4 2010/03/07 19:53:19 carl Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ #ifndef _GOGO_STRINGS_H_ #define _GOGO_STRINGS_H_ #define TARGET_NAME "gogoc" #define GOGO_STR_ENV_PRINT_VALUE "%-30.30s %s" #define GOGO_STR_NOT_DEF_AS_CLIENT_ERROR "%i is not defined as a client error. Might be a TSP error?" #define GOGO_STR_UNKNOWN_HOST_ADD_KEY "%s is an unknown host, do you want to add its key?" #define GOGO_STR_WARN_SERVER_KEY_AUTO_ADDED "Server key has been automatically added." #define GOGO_STR_WARN_STORED_LOCAL_KEY_NO_MATCH "Local key stored in %s for host %s doesn't match host key. *NOT CONNECTING*" #define GOGO_STR_API_EQUALS "API = %s, " #define GOGO_STR_BN_BN2BIN_FAILED "oi %d != bin_size %d." #define GOGO_STR_BAD_CLIENT_IPV4_RECVD "Bad value received from server for client_address_ipv4." #define GOGO_STR_BAD_CLIENT_IPV6_RECVD "Bad value received from server for client_address_ipv6." #define GOGO_STR_BAD_CLIENT_DNS_IPV6_RECVD "Bad value received from server for client_dns_server_address_ipv6." #define GOGO_STR_BAD_SERVER_PREFIX_RECVD "Bad value received from server for prefix." #define GOGO_STR_BAD_PREFIX_LEN_RECVD "Bad value received from server for prefix_length." #define GOGO_STR_BAD_SERVER_IPV4_RECVD "Bad value received from server for server_address_ipv4." #define GOGO_STR_BAD_SERVER_IPV6_RECVD "Bad value received from server for server_address_ipv6." #define GOGO_STR_CANT_OPEN_TMP_FILE "Failed to open temporary file." #define GOGO_STR_GOGOTUN_V4V6_NOT_INSTALLED "gogo6 Multi-Tunnel Virtual Adapter is missing and is required for V4V6 tunneling." #define GOGO_STR_GOGOTUN_V6UDPV4_NOT_INSTALLED "gogo6 Multi-Tunnel Virtual Adapter is missing and is required for V6UDPV4 tunneling." #define GOGO_STR_CANNOT_OPEN_LOG_FILE "Failed to open log file %s." #define GOGO_STR_CHECKING_LINUX_IPV6_SUPPORT "Checking for Linux IPv6 support..." #define GOGO_STR_SETUP_PROXY "Client proxying is %s." #define GOGO_STR_CANT_DELETE_SERVICE "Failed to delete service %s: %i." #define GOGO_STR_CANT_OPEN_SCM "Failed to open the SCM." #define GOGO_STR_DH_GEN_ERROR "DH generation error." #define GOGO_STR_DH_SHARED_COMPUTE_ERROR "DH shared key computation error." #define GOGO_STR_DH_SHARED_KEY "DH shared key: %s." #define GOGO_STR_INITIALIZATION_ERROR "DH initialization error." #define GOGO_STR_DSA_SIGN_R "DSA sign r:%s." #define GOGO_STR_DSA_SIGN_S "DSA sign s:%s." #define GOGO_STR_KEY_VERIF_ERROR "Key verification error." #define GOGO_STR_START_SRVS_CTRL_DISP_ERR_CODE "Error code for StartServiceCtrlDispatcher: %u." #define GOGO_STR_ERR_CONFIG_TUN_DEV_REASON "Failed to configure tun device %s : %s." #define GOGO_STR_ERR_CONFIG_TUN_DEV "Failed to configure tun device: %s." #define GOGO_STR_ERR_FROM_CFG_FILE "Error from config file: %s." #define GOGO_STR_ERR_IN_KEY_VERIF "Failed key verification." #define GOGO_STR_ERR_OPEN_DEV "Failed to open device: %s." #define GOGO_STR_ERR_OPEN_TUN_DEV "Failed to open tun device: %s." #define GOGO_STR_ERR_ROTATING_LOG_FILE "Failed to rotate the log file." #define GOGO_STR_ERR_FIND_DST_IP "Failed to find destination IP address." #define GOGO_STR_ERR_FIND_SRC_IP "Failed to find source IP address." #define GOGO_STR_ERR_FIND_SRC_IP_PORT "Failed to find source IP port." #define GOGO_STR_ERR_WAITING_SCRIPT "Failed to wait for the script to complete." #define GOGO_STR_ERR_SETENV "Failed to set environment variable %s: %s" #define GOGO_STR_FATAL_NOT_ROOT_FOR_TUN "You must be root to setup a tunnel." #define GOGO_STR_CANT_FIND_LOCALHOST_IP "Failed to get localhost IP address." #define GOGO_STR_GOING_DAEMON "Going daemon." #define GOGO_STR_IPV6_SUPPORT_FOUND "IPv6 support found." #define GOGO_STR_NO_IPV6_SUPPORT_FOUND "No IPv6 support found." #define GOGO_STR_BAD_SIG_FROM_SERVER "Incorrect signature from server." #define GOGO_STR_INVALID_PAYLOAD_SIZE "Invalid payload size." #define GOGO_STR_INVALID_RESPONSE_RECEIVED "Invalid response received." #define GOGO_STR_INVALID_VAL_FOR_LOG "Config: Invalid value for log: %s." #define GOGO_STR_LOG_FILE_CLOSED "Log file %s closed while it should be open." #define GOGO_STR_MATCHING_KEY_FOUND_USED "Matching server key found and used." #define GOGO_STR_NO_RUDP_REPLY "No RUDP reply." #define GOGO_STR_NO_CONFIG_CANNOT_LOG_TO_FILE "Failed to log to file: No configuration." #define GOGO_STR_NO_LOG_FILENAME_IN_CONFIG "Failed to log to file: No log file name in configuration." #define GOGO_STR_PASSDS_ENC_KEY "PASSDSS: encryption key: %s." #define GOGO_STR_PASSDS_INTEG_KEY "PASSDSS: integrity key: %s." #define GOGO_STR_PASSDS_IV "PASSDSS: iv: %s." #define GOGO_STR_PAYLOAD_BIGGER_PROTOFRMSIZE "Payload size is bigger than PROTOCOLFRAMESIZE." #define GOGO_STR_RCVD_DATA_INVALID "Received data is invalid." #define GOGO_STR_LOG_CFG_RECEIVED_NULL_CFG "Received NULL configuration." #define GOGO_STR_MESSAGE_ROTATING "** ROTATING LOG FILE **" #define GOGO_STR_SERVER_NOT_IPV4 "Failed to resolve server IPv4 address." #define GOGO_STR_SERVER_NOT_IPV6 "Failed to resolve server IPv6 address." #define GOGO_STR_SERVER_KEY_ACCEPTED_ADDED "Server key accepted and added." #define GOGO_STR_SERVER_KEY_REJECTED "Server key rejected." #define GOGO_STR_SERVER_KEY_REJECTED_USER "Server key rejected by the user." #define GOGO_STR_SERVICE "Service" #define GOGO_STR_SERVICE_PORT_INVALID "Service port not valid: %s." #define GOGO_STR_CANT_REGISTER_TSP "Failed to register "TARGET_NAME" service." #define GOGO_STR_CANT_UNREGISTER_TSP "Failed to unregister "TARGET_NAME" service." #define GOGO_STR_TSP_REGISTERED "Registration of "TARGET_NAME" service successful." #define GOGO_STR_TSP_UNREGISTERED "Unregistration of "TARGET_NAME" service successful." #define GOGO_STR_SIG_VERIF_ERROR "Signature verification error." #define GOGO_STR_SIGNED_HASH "Signed hash: %s." #define GOGO_STR_TEMPLATE_NOT_FOUND "Failed to find \"%s\" template." #define GOGO_STR_SETUP_HOST_TYPE "The host type is '%s'." #define GOGO_STR_SETUP_TUNNEL_TYPE "The tunnel type is %s." #define GOGO_STR_TRY_MODPROBE_IPV6 "Try \"modprobe ipv6\"." #define GOGO_STR_TRY_MODPROBE_TUN "Try \"modprobe tun\"." #define GOGO_STR_CANT_FORK "Failed to fork." #define GOGO_STR_CANT_READ_TEMPLATE_FROM_CFG "Failed to read the template name from the config file. Is it specified? Do you have %s in the current directory?" #define GOGO_STR_CANT_ROTATE_LOG_NO_FILENAME "Failed to rotate the log file: No file name specified." #define GOGO_STR_CANT_ROTATE_LOG_CANT_FLUSH "Failed to rotate the log file: Could not flush contents." #define GOGO_STR_CANT_ROTATE_LOG_BACKUP_NAME "Failed to rotate the log file: Could not generate a backup file name." #define GOGO_STR_CANT_ROTATE_LOG_CANT_COPY "Failed to rotate the log file: Could not backup the file." #define GOGO_STR_CANT_ROTATE_LOG_CANT_OPEN_NEW "Failed to rotate the log file: Could not open new empty log file." #define GOGO_STR_CANT_WRITE_LOG_BUFFER_TO_FILE "Failed to write the log buffer to file. Some logs may be lost." #define GOGO_STR_CANT_FPRINTF_TO_LOG "Failed to write to the log file." #define GOGO_STR_USING_AUTH_ANONYMOUS "Using AUTH-ANONYMOUS authentication mechanism." #define GOGO_STR_USING_AUTH_PLAIN "Using AUTH-PLAIN authentication mechanism." #define GOGO_STR_USING_AUTH_DIGEST_MD5 "Using DIGEST-MD5 authentication mechanism." #define GOGO_STR_USING_AUTH_PASSDSS_3DES_1 "Using PASSDSS-3DES-1 authentication mechanism." #define GOGO_STR_VERIF_AND_FIX_CFG_FILE "Verifying and fixing the config file..." #define GOGO_STR_WAITING_FOR_SETUP_SCRIPT "Waiting for setup script to complete." #define GOGO_STR_EXPECTED_CONTENT_LENGTH "Was expecting 'Content-length:'. Received %s." #define GOGO_STR_WRONG_TEMPLATE_NAME "Wrong template name in %s. Updating %s -> %s." #define GOGO_STR_YOUR_IPV4_IP_IS "Your IPv4 address is %s." #define GOGO_STR_YOUR_IPV6_IP_IS "Your IPv6 address is %s." #define GOGO_STR_YOUR_IPV6_DNS_IS "Your IPv6 DNS address is %s." #define GOGO_STR_YOUR_IPV4_PREFIX_IS "Your IPv4 prefix is %s/%s." #define GOGO_STR_YOUR_IPV6_PREFIX_IS "Your IPv6 prefix is %s/%s." #define GOGO_STR_ALLOC_NOT_SUPPORTED "alloc %u not supported." #define GOGO_STR_BAD_STRING_LENGTH "Invalid string length %u." #define GOGO_STR_CANT_HANDLE_BN_SIZE "Failed to handle BN of size %d." #define GOGO_STR_ERROR_CODE_EQUALS "Error code = %d, " #define GOGO_STR_GETNAMEINFO_FAILED "getnameinfo() failed: %ld." #define GOGO_STR_INPUT_BUF_TOO_SMALL "Input buffer too small." #define GOGO_STR_LEN_NOT_SUPPORTED "len %u not supported." #define GOGO_STR_MESSAGE_EQUALS "Message = %s" #define GOGO_STR_RECV_INVALID_TSP_DATA "Received invalid TSP data." #define GOGO_STR_REPLY_RUDP_PACKET "Reply: RUDP packet %i, RTO %f, sequence 0x%x timestamp %i." #define GOGO_STR_RUDP_PACKET "RUDP packet %i, RTO %f, sequence 0x%x timestamp %i." #define GOGO_STR_NO_V4V6_ON_PLATFORM "v4v6 is not supported on this platform." #define GOGO_STR_V4V6_TUNNEL_SETUP_FAILED "Failed to setup v4v6 tunnel interface properly." #define GOGO_STR_V6UDPV4_TUNNEL_SETUP_FAILED "Failed to setup v6udpv4 tunnel interface properly." #define GOGO_STR_NO_V6UDPV4_ON_PLATFORM "v6udpv4 (NAT traversal) is not supported on this platform." // Redirection strings. #define GOGO_STR_RECEIVED_REDIRECTION "Received a TSP redirection message from server %s (%s)." #define GOGO_STR_RDR_ADD_BROKER_INTERNAL_ERR "Internal error trying to add a server address to the server redirection list." #define GOGO_STR_RDR_ADD_BROKER_NO_MEM "Failed to allocate memory for a new server address in the server redirection list." #define GOGO_STR_RDR_ADD_BROKER_ADDRESS_TRUNC "Failed to set server Address in server redirection list: address too long." #define GOGO_STR_RDR_CREATE_LIST_CANT_ADD "Failed to add a new server address while creating the server redirection list." #define GOGO_STR_RDR_SORTING_BROKER_LIST "Sorting the server redirection list." #define GOGO_STR_RDR_SORT_LIST_CANT_GET_DIST "Failed to get server timing information while sorting the server redirection list." #define GOGO_STR_RDR_SORT_LIST_CANT_ALLOC "Failed to allocate memory for a new server address while sorting the server redirection list." #define GOGO_STR_RDR_SORT_LIST_CANT_INSERT "Failed to insert a new server address while sorting the server redirection list." #define GOGO_STR_RDR_CANT_EXTRACT_PAYLOAD "Failed to parse the XML payload while handling server redirection." #define GOGO_STR_RDR_CANT_CREATE_LIST "Failed to create the server redirection list." #define GOGO_STR_RDR_CANT_SORT_LIST "Failed to sort the server redirection list." #define GOGO_STR_RDR_CANT_SAVE_LIST "Failed to write the server redirection list to file." #define GOGO_STR_RDR_CANT_LOG "Failed to log server redirection details." #define GOGO_STR_RDR_NULL_LIST "Received an empty server address list while handling server redirection." #define GOGO_STR_RDR_READ_LAST_SERVER_INT_ERR "Internal error trying to read the last server address from the last_server file." #define GOGO_STR_RDR_WRITE_LAST_SERVER_INT_ERR "Internal error trying to write the last server address to the last_server file." #define GOGO_STR_RDR_WRITE_LAST_SERVER_CANT_OPEN "Failed to open %s to save the last server address." #define GOGO_STR_RDR_WRITE_LAST_SERVER_CANT_WRITE "Failed to write last server address %s to %s." #define GOGO_STR_RDR_WRITE_BROKER_LIST_INT_ERR "Internal error trying to write the server redirection list to the broker_list file." #define GOGO_STR_RDR_WRITE_BROKER_LIST_CANT_OPEN "Failed to open %s to save the server redirection list." #define GOGO_STR_RDR_WRITE_BROKER_LIST_CANT_WRITE "Failed to write the server redirection list to %s." #define GOGO_STR_RDR_READ_BROKER_LIST_CANT_ADD "Failed to add a new server address while creating the server redirection list from file %s." #define GOGO_STR_RDR_TRYING_LAST_SERVER "Trying last server address %s." #define GOGO_STR_RDR_NO_LAST_SERVER_FOUND "Failed to find last server in last_server file %s. Trying server address %s instead." #define GOGO_STR_RDR_CANT_OPEN_LAST_SERVER "Failed to open last_server file %s. Trying server %s instead." #define GOGO_STR_RDR_ERROR_READING_LAST_SERVER "Failed to read the last_server file %s." #define GOGO_STR_RDR_READING_BROKER_LIST "Trying to read the server redirection list from broker_list file %s." #define GOGO_STR_RDR_READ_BROKER_LIST_EMPTY "The server redirection list is empty." #define GOGO_STR_RDR_READ_BROKER_LIST_CREATED "The server redirection list was created successfully." #define GOGO_STR_RDR_CANT_OPEN_BROKER_LIST "Failed to open broker_list file %s." #define GOGO_STR_RDR_ERROR_READING_BROKER_LIST "Failed to create the server redirection list from broker_list file %s." #define GOGO_STR_RDR_BROKER_LIST_END "Reached the end of the server redirection list." #define GOGO_STR_RDR_NEXT_IN_BROKER_LIST "Moving to the next server address in the server redirection list (%s)." #define GOGO_STR_RDR_BROKER_LIST_INTERNAL_ERROR "Internal error processing the server redirection list." #define GOGO_STR_RDR_ERROR_PROCESSING_REDIRECTION "Failed to process a TSP redirection message from %s." #define GOGO_STR_RDR_BROKER_LIST_IS "The server redirection list is %s." #define GOGO_STR_RDR_SORTED_BROKER_LIST_IS "The optimized server redirection list is %s." #define GOGO_STR_RDR_TOO_MANY_BROKERS "Too many entries in the server redirection list than the allowed limit (%u). Discarding." #define GOGO_STR_RDR_CREATING_DISTANCE_THREAD "Creating server timing thread for %s." #define GOGO_STR_RDR_CANT_CREATE_DISTANCE_THREAD "Failed to create timing thread for %s." #define GOGO_STR_RDR_WAITING_FOR_THREAD "Waiting for %s timing thread to complete." #define GOGO_STR_RDR_ERR_WAITING_FOR_THREAD "Failed to wait for %s timing thread to complete." #define GOGO_STR_RDR_DISTANCE_CALCULATION_TIMEOUT "A timeout occurred during server timing for %s." #define GOGO_STR_RDR_DISTANCE_CALCULATION_OK "server timing for %s completed successfully (%u ms)." #define GOGO_STR_RDR_DISTANCE_CALCULATION_ERR "An error occurred during server timing for %s." #define GOGO_STR_RDR_ERROR_CREATE_STAT_ENGINE "Failed to allocate a stat engine to send an echo request to %s." #define GOGO_STR_RDR_ERROR_INIT_STAT_ENGINE "Failed to initialize a stat engine to send an echo request to %s." #define GOGO_STR_RDR_ERROR_GET_SOCKADDRESS "Failed to create an address structure to send an echo request to %s." #define GOGO_STR_RDR_ERROR_RESOLVING_DN "Failed to resolve %s to an IP address." #define GOGO_STR_RDR_ERROR_CONNECT_SOCKET "Failed to create a connected socket to send an echo request to %s." #define GOGO_STR_RDR_ERROR_PREPARING_RUDP_MSG "Failed to create an RUDP message to send an echo request to %s." #define GOGO_STR_RDR_MAX_ECHO_REPLY_ATTEMPTS "Maximal number of echo request attempts (%u) reached for %s." #define GOGO_STR_RDR_SENDING_ECHO_REQUEST "Sending echo request message #%u to %s." #define GOGO_STR_RDR_SEND_ECHO_REQUEST_FAILED "Failed to send an echo request message to %s." #define GOGO_STR_RDR_WAITING_ECHO_REPLY "Waiting for an echo reply from %s." #define GOGO_STR_RDR_WAITING_ECHO_REPLY_TIMEOUT "Timed out waiting for an echo reply from %s." #define GOGO_STR_RDR_RECEIVING_RUDP_MESSAGE "Receiving an RUDP message from %s." #define GOGO_STR_RDR_ERR_RECEIVING_RUDP_FROM "Failed to receive an RUDP message from %s." #define GOGO_STR_RDR_RECEIVED_RUDP_OK "Received RUDP message from %s correctly." #define GOGO_STR_RDR_RECV_RUDP_SEQ_DIFFERS "Sequence number of RUDP message from %s differs." #define GOGO_STR_RDR_ERR_WAITING_ECHO_REPLY "Failed to wait for an echo reply from %s." #define GOGO_STR_RDR_RCV_EXPECTED_ECHO_REPLY "Received expected echo reply from %s: %s." #define GOGO_STR_RDR_RCV_UNEXPECTED_ECHO_REPLY "Received unexpected echo reply from %s: %s." #define GOGO_STR_RDR_CANT_MALLOC_THREAD_ARRAY "Failed to allocate memory for the server timing threads." #define GOGO_STR_RDR_CANT_MALLOC_THREAD_ARGS "Failed to allocate memory for the server timing thread arguments." #define GOGO_STR_RDR_WRONG_ADDRESS_FAMILY "Server address %s is not compatible with the configured tunnel mode." #define GOGO_STR_INIT_MESSAGING_FAILED "Failed to initialize the messaging subsystem. Communication with GUI unavailable." #define GOGO_STR_UNINIT_MESSAGING_FAILED "Failed to uninitialize the messaging subsystem." // Home access and home web strings. #define GOGO_STR_HACCESS_MAKING_DEVICES_ACCESSIBLE "About to make the requested devices accessible." #define GOGO_STR_HACCESS_ABOUT_TO_PERFORM_SETUP "About to perform HomeAcces setup." #define GOGO_STR_HACCESS_ABOUT_TO_PERFORM_TEARDOWN "About to perform HomeAcces teardown." #define GOGO_STR_HACCESS_ATTEMPTING_DDNS_DELETE "Attempting to perform a DDNS deletion for %s.%s." #define GOGO_STR_HACCESS_ATTEMPTING_DDNS_UPDATE "Attempting to perform a DDNS update for %s.%s/%s." #define GOGO_STR_HACCESS_CONNECTING_TO_DDNS_PROXY "Connecting to the DDNS proxy (%s)." #define GOGO_STR_HACCESS_CREATING_DDNS_REQUEST "Creating a DDNS request for %s." #define GOGO_STR_HACCESS_DISCONNECTING_FROM_DDNS_PROXY "Disconnecting from the DDNS proxy." #define GOGO_STR_HACCESS_EXECUTING_EXTERNAL_COMMAND "Executing an external command: %s." #define GOGO_STR_HACCESS_EXECUTING_PROXY_CONFIG_SCRIPT "Executing the HomeAcces HTTP proxy configuration script." #define GOGO_STR_HACCESS_EXECUTING_SETUP_SCRIPT "Executing the HomeAcces setup script." #define GOGO_STR_HACCESS_EXECUTING_TEARDOWN_SCRIPT "Executing the HomeAcces teardown script." #define GOGO_STR_HACCESS_GENERATING_PROXY_CONFIG_FILE "Generating the HTTP proxy configuration file." #define GOGO_STR_HACCESS_ERR_PROCESSING_DDNS_REQUEST "Errors occurred while processing the DDNS request for %s.%s." #define GOGO_STR_HACCESS_ERR_ADDRESS_NOT_V4_OR_V6 "Host address for the DDNS request is not an IPv4 or IPv6 address." #define GOGO_STR_HACCESS_ERR_CANT_CONNECT_TO_DDNS_PROXY "Failed to connect to the DDNS proxy." #define GOGO_STR_HACCESS_ERR_CANT_DISCONNECT_FROM_DDNS_PROXY "Failed to disconnect from the DDNS proxy correctly." #define GOGO_STR_HACCESS_ERR_READING_DEVICE_MAPPING_CONFIG "Failed to read the device mapping information from the configuration file." #define GOGO_STR_HACCESS_ERR_EXECUTING_SCRIPT "Failed to execute the requested script." #define GOGO_STR_HACCESS_ERR_QUEUEING_DDNS_REQUEST "Failed to queue the required DDNS requests." #define GOGO_STR_HACCESS_ERR_SETTING_ENV_VARS "Failed to set the required environment variables." #define GOGO_STR_HACCESS_ERR_WRITING_SCRIPT_CALL_LINE "Failed to write the script invocation command to the buffer." #define GOGO_STR_HACCESS_ERR_INVALID_ARGS_FOR_DDNS_THREAD "Invalid arguments for the DDNS processing thread." #define GOGO_STR_HACCESS_ERR_INVALID_FUNCTION_ARGS "Invalid function arguments." #define GOGO_STR_HACCESS_ERR_NO_SPACE_IN_BUFFER_FOR_CALL_LINE "Not enough space in the buffer to generate the script invocation command." #define GOGO_STR_HACCESS_ERR_DDNS_ACTION_INVALID "The DDNS request action is invalid." #define GOGO_STR_HACCESS_ERR_ENV_VAR_UNKNOWN "The environment variable to be set is unknown." #define GOGO_STR_HACCESS_ERR_SCRIPT_EXIT_ERROR "Failed to execute script successfully." #define GOGO_STR_HACCESS_ERR_ADDRESS_TOO_LONG_FOR_REQ "The host address is too long to create a DDNS request." #define GOGO_STR_HACCESS_ERR_NAME_TOO_LONG_FOR_REQ "The host name is too long to create a DDNS request." #define GOGO_STR_HACCESS_ERR_UNKNOWN_SCRIPT "The script to be executed is unknown." #define GOGO_STR_HACCESS_ERR_CANT_CREATE_REQ "Failed to create the requested DDNS request." #define GOGO_STR_HACCESS_ERR_NO_MEM_FOR_STATUS_COPY "Failed to allocate memory for a copy of the device status." #define GOGO_STR_HACCESS_ERR_NO_MEM_FOR_DDNS_REQ "Failed to allocate memory for the DDNS request." #define GOGO_STR_HACCESS_ERR_NO_MEM_FOR_STATUS_NAME "Failed to allocate memory for the device name in the device status." #define GOGO_STR_HACCESS_ERR_NO_MEM_FOR_STATUS "Failed to allocate memory for the device status." #define GOGO_STR_HACCESS_ERR_CANT_CLEAR_STATUS "Failed to clear the status information." #define GOGO_STR_HACCESS_ERR_CANT_COPY_HOST_NAME "Failed to copy the host name from the device status." #define GOGO_STR_HACCESS_ERR_CANT_CREATE_PREP_MAPPING_FILE "Failed to create the prepared device mapping configuration file." #define GOGO_STR_HACCESS_ERR_CANT_GET_TIME "Failed to determine the current time." #define GOGO_STR_HACCESS_ERR_CANT_FREE_DDNS_REQ_QUEUE "Failed to free the DDNS request processing queue." #define GOGO_STR_HACCESS_ERR_CANT_FREE_DDNS_REQ "Failed to free the DDNS request." #define GOGO_STR_HACCESS_ERR_CANT_GEN_PROXY_CONFIG_FILE "Failed to generate the proxy configuration file." #define GOGO_STR_HACCESS_ERR_CANT_INIT_STATUS "Failed to initialize status information." #define GOGO_STR_HACCESS_ERR_CANT_INIT_DDNS_REQ_QUEUE "Failed to initialize the DDNS request processing queue." #define GOGO_STR_HACCESS_ERR_CANT_INIT_MAPPING_CONF_MODULE "Failed to initialize the device mapping configuration module." #define GOGO_STR_HACCESS_ERR_CANT_LOAD_MAPPING_CONF_FILE "Failed to load the device mapping configuration file." #define GOGO_STR_HACCESS_ERR_CANT_OPEN_PREP_MAPPING_FILE "Failed to open the prepared device mapping configuration file for writing." #define GOGO_STR_HACCESS_ERR_CANT_INIT_PLATFORM "Failed to perform the platform-specific initialization." #define GOGO_STR_HACCESS_ERR_CANT_SHUTDOWN_PLATFORM "Failed to perform the platform-specific shutdown operations." #define GOGO_STR_HACCESS_ERR_CANT_PREP_SCRIPT_CALL "Failed to prepare the script invocation command." #define GOGO_STR_HACCESS_ERR_CANT_PUSH_DDNS_REQ_BACK "Failed to push the DDNS request back on the DDNS request processing queue." #define GOGO_STR_HACCESS_ERR_CANT_PUSH_NEW_DDNS_REQ "Failed to push the new DDNS request on the DDNS request processing queue." #define GOGO_STR_HACCESS_ERR_CANT_REMOVE_PREP_MAPPING_FILE "Failed to remove the prepared device mapping configuration file." #define GOGO_STR_HACCESS_ERR_CANT_SEND_STATUS_TO_GUI "Failed to send the DDNS request status to the GUI." #define GOGO_STR_HACCESS_ERR_CANT_SET_ENV_VAR "Failed to set the requested environment variable." #define GOGO_STR_HACCESS_ERR_CANT_SIGNAL_SHUTDOWN "Failed to signal that the module is shutting down." #define GOGO_STR_HACCESS_ERR_CANT_START_DDNS_THREAD "Failed to start the DDNS request processing thread." #define GOGO_STR_HACCESS_ERR_CANT_UPDATE_DDNS_REQ_STATUS "Failed to update the DDNS request status." #define GOGO_STR_HACCESS_ERR_CANT_WRITE_TO_PREP_MAPPING_FILE "Failed to write an entry to the prepared device mapping configuration file." #define GOGO_STR_HACCESS_ERR_SET_STATUS_UNEXPECTED_STATE "Unexpected situation while trying to set the device status." #define GOGO_STR_HACCESS_SETUP_COMPLETED "HomeAcces setup completed." #define GOGO_STR_HACCESS_SHUTDOWN_COMPLETED "HomeAcces shutdown completed." #define GOGO_STR_HACCESS_TEARDOWN_COMPLETED "HomeAcces teardown completed." #define GOGO_STR_HACCESS_ADDRESS_IS_IPV4 "Host address is an IPv4 address; IPv6 address will be %s." #define GOGO_STR_HACCESS_ADDRESS_IS_IPV6 "Host address is an IPv6 address; IPv6 address will be %s." #define GOGO_STR_HACCESS_NOT_TIME_FOR_REQ "It is still not time to process this DDNS request. Pushing it back on the queue." #define GOGO_STR_HACCESS_TIME_FOR_REQ "It is time to process this DDNS request." #define GOGO_STR_HACCESS_POPPED_DDNS_REQ "Popped a DDNS request for %s.%s from the DDNS request processing queue." #define GOGO_STR_HACCESS_PREPARING_TO_QUEUE "Preparing to queue the required DDNS requests." #define GOGO_STR_HACCESS_REACHED_MAX_ATTEMPTS "Reached the maximum number of DDNS request attempts (%u) for %s.%s. Giving up." #define GOGO_STR_HACCESS_READING_MAPPING_CONFIG "Reading the device mapping configuration." #define GOGO_STR_HACCESS_RECEIVED_DDNS_SERVAIL "Received a SERVFAIL reply from the DDNS proxy." #define GOGO_STR_HACCESS_RECEIVED_DDNS_ERROR "Received an error reply from the DDNS proxy. The request for %s.%s was not processed successfully." #define GOGO_STR_HACCESS_RESTARTING_HTTP "Restarting the HTTP server." #define GOGO_STR_HACCESS_SHUTTING_DOWN "Shutting down HACCESS." #define GOGO_STR_HACCESS_STARTING_DDNS_THREAD "Starting the DDNS processing thread." #define GOGO_STR_HACCESS_DDNS_REQ_PROCESSED_SUCCESS "The DDNS request was processed successfully." #define GOGO_STR_HACCESS_PROXY_READY "The HTTP proxy configuration has been adjusted, and the required DDNS requests have been queued for processing." #define GOGO_STR_HACCESS_DDNS_REQ_ELIGIBLE_IN "This DDNS request will be eligible for processing in %u seconds." #define GOGO_STR_HACCESS_VERIFYING_IF_PROCESS_NOW "Verifying if the DDNS request for %s.%s should be processed now." #define GOGO_STR_HACCESS_ERR_PROCESSING_DDNS_REQS "An error occurred during the processing of the DDNS requests." #define GOGO_STR_HACCESS_ERR_CANT_START_PLATFORM_THREAD "Failed to start a platform-specific thread." #define GOGO_STR_HACCESS_ERR_CANT_SIGNAL_MODULE_SHUTDOWN "Failed to signal the module shutdown event." #define GOGO_STR_HACCESS_ERR_CANT_CREATE_PLATFORM_WAIT_EVENT "Failed to create a platform-specific wait event." #define GOGO_STR_HACCESS_ERR_CANT_CLOSE_SHUTDOWN_EVENT "Failed to close the module shutdown event." #define GOGO_STR_HACCESS_ERR_CANT_CLOSE_THREAD_HANDLE "Failed to close the DDNS request processing thread handle." #define GOGO_STR_HACCESS_ERR_CANT_INIT_MODULE "Failed to perform module initialization." #define GOGO_STR_HACCESS_ERR_CANT_DO_TEARDOWN "Failed to perform teardown." #define GOGO_STR_HACCESS_ERR_CANT_DO_SHUTDOWN "Failed to perform module shutdown." #define GOGO_STR_HACCESS_ERR_FAILED_TO_SETUP_HACCESS_FEATURES "Failed to setup the HACCESS features." #define GOGO_STR_HACCESS_ERR_FAILED_TO_EXPOSE_DEVICES "Failed to make the HomeAccess devices accessible." #define GOGO_STR_HACCESS_WARN_DEVICE_ADDRESS_NOT_IN_PREFIX "Device %s mapping refused: Device address '%s' is not within your delegated prefix '%s'." #define GOGO_STR_HACCESS_HIDING_DEVICES "About to remove the devices from the DNS server." #define GOGO_STR_HACCESS_ERR_CANT_SIGNAL_EMPTY_QUEUE "Failed to signal that the DDNS request queue is empty." #define GOGO_STR_HACCESS_ERR_CANT_SIGNAL_HIDING_EVENT "Failed to signal the device hiding completion event." #define GOGO_STR_HACCESS_ERR_CANT_WAIT_HIDING_EVENT "Failed to wait for the device hiding completion event to be signaled." #define GOGO_STR_HACCESS_ERR_CANT_WAIT_HIDING_DONE "Failed to wait for the completion of the DDNS deletion requests." #define GOGO_STR_HACCESS_ERR_CANT_DO_HIDE_DEVICES "Failed to remove the DNS entries." #define GOGO_STR_HACCESS_ERR_HIDING_TIMEOUT "Timed out waiting for the completion of the DDNS deletion requests." #define GOGO_STR_INVALID_IPHLPAPI_DLL "Failed to find required IPHLPAPI.DLL file, or invalid version." #define GOGO_STR_CANT_GET_LOCAL_DNSSERVERS "Failed to retrieve local system DNS servers" // Keepalive strings. #define STR_KA_INIT_FAIL_CAUSE "Keepalive initialisation failed: " #define STR_KA_START_FAIL_CAUSE "Keepalive start failed: " #define STR_KA_QRYSTATUS_FAIL_CAUSE "Keepalive status query failed: " #define STR_KA_STOP_FAIL_CAUSE "Keepalive stop failed: " #define STR_KA_DESTR_FAIL_CAUSE "Keepalive destruction failed: " #define STR_KA_INIT_INFO "Keepalive initialized with peer %s. Interval=%dms. Timeout=%dms. General timeout at %d consecutive timeouts." #define STR_KA_SEND_INFO "Keepalive request sent." #define STR_KA_RECV_INFO "Keepalive reply received. Roundtrip time: %.3fms" #define STR_KA_STOP_INFO_CAUSE "Keepalive processing stopped: " #define STR_KA_ERR_ALREADY_INIT "Already initialized." #define STR_KA_GENERAL_TIMEOUT "General timeout detected." #define STR_KA_EXPLICIT_STOP "Keepalive engine was explicitly stopped." #define STR_KA_ERR_DESTR_IEE "Failed to destroy ICMP echo engine." #define STR_KA_ERR_STOP_IEE "Failed to stop ICMP echo engine." #define STR_KA_ERR_THREAD_START "Thread start error: " #define STR_KA_ERR_THREAD_JOIN "Thread join error: " // General strings. #define STR_GEN_UNKNOWN_ERROR "Unknown or unhandled error." #define STR_GEN_NETWORK_ERROR "Networking error." #define STR_GEN_INVALID_POINTER "Invalid pointer." #define STR_GEN_MALLOC_ERROR "Failed memory allocation." #define STR_GEN_USING_TSP_PROTO_VER "Using TSP protocol version %s." #define STR_GEN_CONNECT_FAIL_SERVER "Failed to connect to server %s. Verify server name/address." #define STR_GEN_CONNECTED_SERVER "Connection to server %s successful." #define STR_GEN_EXEC_CFG_SCRIPT "Executing interface configuration script: %s." #define STR_GEN_SCRIPT_EXEC_SUCCESS "Interface configuration script completed successfully." #define STR_GEN_SCRIPT_EXEC_FAILED "Interface configuration script completed with errors." #define STR_GEN_DISCONNECTED_RETRY_NOW "Disconnected. Retrying." #define STR_GEN_DISCONNECTED_RETRY_SEC "Disconnected. Retrying in %d seconds." #define STR_GEN_LAST_STATUS_CONTEXT "Last status context is: %s." #define STR_GEN_FINISHED "Finished." // TSP strings. #define STR_TSP_GEN_ERROR "A TSP error occurred. Status: %d. Info: %s" #define STR_TSP_NO_LISTENER "Failed to contact TSP listener at %s." #define STR_TSP_INVALID_VERSION "TSP version not supported by server: %s." #define STR_TSP_SERVER_TOO_BUSY "The server is too busy to process your TSP request." #define STR_TSP_GETCAPABILITIES_FROM_SERVER "Retrieving TSP capabilities from Server." #define STR_TSP_GETCAPABILITIES_ERROR "Failed to retrieve TSP capabilities." #define STR_TSP_TUNMODE_NOT_AVAILABLE "Requested tunnel mode not available on server %s." #define STR_TSP_AUTHENTICATING "Authenticating..." #define STR_TSP_NO_COMMON_AUTHENTICATION "Failed to find common authentication method with server." #define STR_TSP_AUTH_FAILED_USER "The server failed to authenticate user %s." #define STR_TSP_UNKNOWN_ERR_AUTH_FAILED "Unknown TSP error during authentication. (%s)" #define STR_TSP_AUTH_SUCCESSFUL "Authentication successful." #define STR_TSP_NEGOTIATING_TUNNEL "Negotiating tunnel parameters with server" #define STR_TSP_TUNNEL_NEGO_FAILED "Tunnel negotiation failed. Status: %d" #define STR_TSP_TUNNEL_NEGO_SUCCESSFUL "Tunnel negotiation successful. Accepted offer." #define STR_TSP_ERRS_TUN_PARAM_FROM_SERVER "Errors in tunnel parameters in server response." #define STR_TSP_TUNNEL_LEASE_EXPIRED "Tunnel allocation lease expired. Sending back TSP request." // Network strings. #define STR_NET_USING_SOURCE_IPV4 "Using [%s] as source IPv4 address." #define STR_NET_USING_SOURCE_IPV6 "Using [%s] as source IPv6 address." #define STR_NET_FAILED_FIND_LOCALHOST_IPV4 "Failed to find localhost IPv4 address. (because client_v4=auto)" #define STR_NET_FAILED_FIND_LOCALHOST_IPV6 "Failed to find localhost IPv6 address. (because client_v6=auto)" #define STR_NET_CANT_GET_SRC_ADDRESS "Failed to get source address to communicate with server." #define STR_NET_CANT_GET_DST_ADDRESS "Failed to get destination address to communicate with the server." #define STR_NET_CONNECT_RUDP "Establishing connection to server %s using reliable UDP." #define STR_NET_CONNECT_RUDPV6 "Establishing connection to server %s using reliable UDPv6." #define STR_NET_CONNECT_TCP "Establishing connection to server %s using TCP." #define STR_NET_CONNECT_TCPV6 "Establishing connection to server %s using TCPv6." #define STR_NET_SENDING "Sending: '%s'" #define STR_NET_RECEIVED "Received: '%s'" #define STR_NET_FAIL_CONNECT_SERVER "Failed to connect to server %s on port %d." #define STR_NET_FAIL_RW_SOCKET "Failed to write/read on network socket." #define STR_NET_FAIL_W_SOCKET "Failed to write on network socket." #define STR_NET_FAIL_R_SOCKET "Failed to read from network socket." #define STR_NET_FAIL_R_TUN_DEV "Failed to read from tunnel device." #define STR_NET_FAIL_W_TUN_DEV "Failed to write to tunnel device." #define STR_NET_FAIL_TUN_DEV_BUFSMALL "Buffer size too small to attempt reading from tunnel device." // Miscellaneous error strings. #define STR_MISC_FAIL_TUN_INIT "Failed to initialize TUN device." #define STR_MISC_INVALID_MD5_RESPONSE "Invalid MD5 response from server." #define STR_MISC_FAIL_WRITE_LAST_SERVER "Failed to write the last server address (%s) to the last server file %s." #define STR_MISC_LOG_CONFIGURE_FAILED "Failed to configure the logging system." #define STR_MISC_PROCESS_SERVER_REPLY "Processing server reply." // String litterals #define STR_LIT_DISABLED "disabled" #define STR_LIT_ENABLED "enabled" // server status context. #define STR_CTX_UNSPECIFIED "Unspecified" #define STR_CTX_CFGVALIDATION "Configuration validation" #define STR_CTX_NETWORKINIT "Network initialisation" #define STR_CTX_NETWORKCONNECT "Network connection" #define STR_CTX_TSPCAPABILITIES "Retrieve TSP capabilities" #define STR_CTX_TSPAUTHENTICATION "TSP authentication" #define STR_CTX_TSPTUNNEGOTIATION "TSP tunnel negotiation" #define STR_CTX_TUNINTERFACESETUP "Tunnel interface setup" #define STR_CTX_TUNNELLOOP "Tunnel life loop" #define STR_CTX_GOGOCTEARDOWN "Application/tunnel teardown" // server TSP ptotocol strings #define STR_TSP_PROTO_SUCCESS "Operation successful." #define STR_TSP_PROTO_AUTH_FAILED "Authentication failed." #define STR_TSP_PROTO_NO_TUNNELS "The server has reached its tunnel capacity limit." #define STR_TSP_PROTO_UNSUP_TSP_VER "Unsupported TSP version." #define STR_TSP_PROTO_UNSUP_TUN_MODE "Unsupported tunnel type." #define STR_TSP_PROTO_UNDEFINED "Server-side error." #define STR_TSP_PROTO_INVALID_REQUEST "Invalid TSP request." #define STR_TSP_PROTO_INVALID_IPV4 "Invalid IPv4 address." #define STR_TSP_PROTO_INVALID_IPV6 "Invalid IPv6 address." #define STR_TSP_PROTO_IPV4_PREFIX_ALREADY_USED "IPv4 prefix already in use." #define STR_TSP_PROTO_REQ_PREFIX_LEN_UNAVAILABLE "Prefix length unavailable." #define STR_TSP_PROTO_DNS_DELEGATION_ERROR "DNS delegation error." #define STR_TSP_PROTO_UNSUPP_PREFIX_LEN "Unsupported prefix length." #define STR_TSP_PROTO_MISSING_PREFIX_LEN "Missing prefix length." #define STR_TSP_PROTO_REQ_IN_PROGRESS "Request already in progress." #define STR_TSP_PROTO_PREFIX_REQ_FOR_ANONYMOUS "Prefix requested for anonymous." #define STR_TSP_PROTO_SERVER_TOO_BUSY "Server too busy." #define STR_TSP_PROTO_REDIRECT "Redirection." #endif gogoc-1_2-RELEASE/gogoc-tsp/include/icmp_echo_engine.h0100644000000000000000000000627711301544572021277 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: icmp_echo_engine.h,v 1.1 2009/11/20 16:53:14 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2008 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. This engine is used for the following two use cases (see ICMP Echo Engine modes enumeration): 1. By the Keepalive(KA) engine. 2. By the Automatic Connectivity Detection(ACD) mechanism. The return value of IEE_destroy() depends in which use case it was called. For KA, the return values can be: - IEE_INVALID_PARMS : Means an invalid pp_config was passed. - IEE_GENERAL_ECHO_TIMEOUT : Means keepalive timeout. - IEE_SUCCESS : Means execution ended. (probably gogoc exiting) - IEE_GENERAL_ECHO_ERROR : Means a fatal error occured. For ACD, the return values can be: - IEE_INVALID_PARMS : Means an invalid pp_config was passed. - IEE_GENERAL_ECHO_TIMEOUT : Means all echo messages timed out. - IEE_CONNECTIVITY_ASSESSED: Means a reply was received. - IEE_GENERAL_ECHO_ERROR : Means a fatal error occured. ----------------------------------------------------------------------------- */ #ifndef _ICMP_ECHO_ENGINE_H_ #define _ICMP_ECHO_ENGINE_H_ // ICMP Echo Engine public return codes. typedef enum { IEE_SUCCESS = 0, // Returned by any IEE function on success. IEE_INVALID_PARMS, // Returned by any IEE function when invalid input parameter(s). IEE_RESOURCE_STARVATION, // Returned by IEE_init when failed to acquire system resource (memory). IEE_CONNECTIVITY_ASSESSED, // Returned by IEE_process for ACD only. IEE_GENERAL_ECHO_TIMEOUT, // Returned by IEE_process for ACD and KA. IEE_GENERAL_ECHO_ERROR // Returned by IEE_process when ICMP echo fatal error. } iee_ret_t; // ICMP Echo Engine modes. Must hold within 2 bits(because defined as such). typedef enum { IEE_MODE_OTHER=0, // Other use case, such as testing. IEE_MODE_KA=1, // Keepalive use case. IEE_MODE_ACD=2 // Automatic Connectivity Detection use case. } iee_mode_t; typedef void (*iee_send_clbk) ( void ); typedef void (*iee_recv_clbk) ( double rtt ); // Public function prototypes. iee_ret_t IEE_init ( void** pp_config, iee_mode_t eng_mode, uint32_t send_interval, uint32_t echo_num, uint32_t echo_timeout, uint8_t echo_timeout_threshold, char* src, char* dst, sint32_t af, iee_send_clbk send_clbk, iee_recv_clbk recv_clbk ); iee_ret_t IEE_destroy ( void** pp_config ); iee_ret_t IEE_process ( void* p_config ); // Should be called from an alternate thread to be of any value: iee_ret_t IEE_stop ( void* p_config ); #endif gogoc-1_2-RELEASE/gogoc-tsp/include/icmpapi.h0100644000000000000000000000316011301544573017433 0ustar rootroot/* --------------------------------------------------------------------------- $Id: icmpapi.h,v 1.1 2009/11/20 16:53:15 jasminko Exp $ --------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. --------------------------------------------------------------------------- */ #ifndef _ICMP_INCLUDED_ #define _ICMP_INCLUDED_ HANDLE WINAPI IcmpCreateFile( VOID ); BOOL WINAPI IcmpCloseHandle( HANDLE IcmpHandle ); DWORD WINAPI IcmpSendEcho( HANDLE IcmpHandle, IPAddr DestinationAddress, LPVOID RequestData, WORD RequestSize, PIP_OPTION_INFORMATION RequestOptions, LPVOID ReplyBuffer, DWORD ReplySize, DWORD Timeout ); DWORD WINAPI IcmpSendEcho2( HANDLE IcmpHandle, HANDLE Event, #ifdef PIO_APC_ROUTINE_DEFINED PIO_APC_ROUTINE ApcRoutine, #else FARPROC ApcRoutine, #endif PVOID ApcContext, IPAddr DestinationAddress, LPVOID RequestData, WORD RequestSize, PIP_OPTION_INFORMATION RequestOptions, LPVOID ReplyBuffer, DWORD ReplySize, DWORD Timeout ); DWORD IcmpParseReplies( LPVOID ReplyBuffer, DWORD ReplySize ); #endif // _ICMP_INCLUDED_ gogoc-1_2-RELEASE/gogoc-tsp/include/lib.h0100644000000000000000000000163611301544573016565 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: lib.h,v 1.1 2009/11/20 16:53:15 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ #ifndef _LIB_H_ #define _LIB_H_ /* globals */ #define IPv4Addr ".0123456789" #define IPv6Addr "ABCDEFabcdef:0123456789" #define IPAddrAny "ABCDEFabcdef:.0123456789" #define Numeric "0123456789" /* exports */ sint32_t IsAll ( char *, char * ); sint32_t IsPresent ( char * ); char* tspGetErrorByCode ( sint32_t code ); sint32_t IsAddressInPrefix ( const char* address, const char* prefix, const sint16_t prefix_len ); #endif gogoc-1_2-RELEASE/gogoc-tsp/include/log.h0100644000000000000000000000324011301544573016571 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: log.h,v 1.1 2009/11/20 16:53:15 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ #ifndef LOG_H #define LOG_H #define LOG_LEVEL_DISABLED 0 #define LOG_LEVEL_1 1 #define LOG_LEVEL_2 2 #define LOG_LEVEL_3 3 #define LOG_LEVEL_MIN LOG_LEVEL_DISABLED #define LOG_LEVEL_MAX LOG_LEVEL_3 #define LOG_IDENTITY_MAX_LENGTH 32 #define LOG_FILENAME_MAX_LENGTH 255 #define MAX_LOG_LINE_LENGTH 4096 #define LOG_IDENTITY "gogoc" #define DEFAULT_LOG_FILENAME "gogoc.log" #define DEFAULT_LOG_ROTATION_SIZE 32 enum tSeverityLevel { ELError, ELWarning, ELInfo, ELDebug }; typedef struct stLogConfiguration { char * identity; char * log_filename; sint32_t log_level_stderr; sint32_t log_level_console; sint32_t log_level_syslog; sint32_t log_level_file; sint32_t syslog_facility; sint32_t log_rotation_size; sint32_t log_rotation; sint32_t buffer; sint32_t delete_rotated_log; // 0 = FALSE } tLogConfiguration; sint32_t DirectErrorMessage (char *message, ...); void Display (sint32_t, enum tSeverityLevel, const char *, char *, ...); sint32_t LogConfigure (tLogConfiguration *); void LogClose (void); sint32_t DumpBufferToFile (char *filename); #endif gogoc-1_2-RELEASE/gogoc-tsp/include/md5.h0100644000000000000000000000447711301544573016512 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: md5.h,v 1.1 2009/11/20 16:53:15 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ /* $FreeBSD: src/sys/sys/md5.h,v 1.13 1999/12/29 04:24:44 peter Exp $ ----------------------------------------------------------------------------- Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved. License to copy and use this software is granted provided that it is identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing this software or this function. License is also granted to make and use derivative works provided that such works are identified as "derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing the derived work. RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided "as is" without express or implied warranty of any kind. These notices must be retained in any copies of any part of this documentation and/or software. */ #ifndef _SYS_MD5_H_ #define _SYS_MD5_H_ /* MD5 context. */ typedef struct MD5Context { uint32_t state[4]; /* state (ABCD) */ uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */ unsigned char buffer[64]; /* input buffer */ } MD5_CTX; #ifndef __P #define __P(X) X #endif void MD5Init (MD5_CTX *); void MD5Update (MD5_CTX *, const unsigned char *, unsigned int); void MD5Pad (MD5_CTX *); void MD5Final (unsigned char [16], MD5_CTX *); char * MD5End (MD5_CTX *, char *); char * MD5File (const char *, char *); char * MD5Data (const unsigned char *, unsigned int, char *); char * md5 (char *, size_t); void md5digest (char *, size_t, char *); #endif /* _SYS_MD5_H_ */ gogoc-1_2-RELEASE/gogoc-tsp/include/net.h0100644000000000000000000000257211301544573016605 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: net.h,v 1.1 2009/11/20 16:53:15 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ #ifndef _NET_H_ #define _NET_H_ struct net_tools { sint32_t (*netopen) (pal_socket_t *, char *, uint16_t); sint32_t (*netclose) (pal_socket_t); sint32_t (*netsendrecv) (pal_socket_t, char *, sint32_t, char *, sint32_t); sint32_t (*netsend) (pal_socket_t, char *, sint32_t); sint32_t (*netprintf) (pal_socket_t, char *, sint32_t, char *, ...); sint32_t (*netrecv) (pal_socket_t, char *, sint32_t); sint32_t (*netreadline) (char *, sint32_t, char*, sint32_t); }; typedef struct net_tools net_tools_t; #define NET_TOOLS_T_SIZE 5 #define NET_TOOLS_T_RUDP 0 #define NET_TOOLS_T_UDP 1 #define NET_TOOLS_T_TCP 2 #define NET_TOOLS_T_TCP6 3 #define NET_TOOLS_T_RUDP6 4 sint32_t parse_addr_port ( const char*, char**, uint16_t*, uint16_t ); struct in_addr * NetText2Addr ( char*, struct in_addr * ); struct in6_addr * NetText2Addr6 ( char*, struct in6_addr * ); #endif gogoc-1_2-RELEASE/gogoc-tsp/include/net_cksm.h0100644000000000000000000000074211301544573017617 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: net_cksm.h,v 1.1 2009/11/20 16:53:15 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ uint16_t in_cksum (uint16_t *addr, sint32_t len); gogoc-1_2-RELEASE/gogoc-tsp/include/net_echo_request.h0100644000000000000000000000226511301544573021352 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: net_echo_request.h,v 1.1 2009/11/20 16:53:15 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ #ifndef _NET_ECHO_REQUEST_H_ #define _NET_ECHO_REQUEST_H_ #define ECHO_REQUEST_COMMAND "ECHO REQUEST" #define ECHO_REQUEST_SUCCESS_STATUS 200 #define ECHO_REQUEST_IN_BUF_SIZE 4096 #define ECHO_REQUEST_OUT_BUF_SIZE 4096 #define ECHO_REQUEST_TIMEOUT 10 * 1000 #define ECHO_REQUEST_TIMEOUT_ADJUST ECHO_REQUEST_TIMEOUT * 2 #define ECHO_REQUEST_ERROR_ADJUST ECHO_REQUEST_TIMEOUT * 2 #define ECHO_REQUEST_WRONG_FAMILY_ADJUST ECHO_REQUEST_TIMEOUT * 3 #define ECHO_REQUEST_ATTEMPTS 3 typedef enum { SOCKET_ADDRESS_OK, SOCKET_ADDRESS_WRONG_FAMILY, SOCKET_ADDRESS_PROBLEM_RESOLVING, SOCKET_ADDRESS_ERROR } tSocketAddressStatus; extern tRedirectStatus tspDoEchoRequest(char *address, tBrokerAddressType address_type, tConf *conf, uint32_t *distance); #endif gogoc-1_2-RELEASE/gogoc-tsp/include/net_ka.h0100644000000000000000000000326311301544573017256 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: net_ka.h,v 1.1 2009/11/20 16:53:15 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. This is the definition of the keepalive(KA) feature. ----------------------------------------------------------------------------- */ #ifndef _NET_KA_H_ #define _NET_KA_H_ // Keepalive public return codes. typedef enum { KA_ERROR, // Keepalive operation failed. KA_SUCCESS // Keepalive operation successful. } ka_ret_t; // Keepalive public statuses. typedef enum { KA_STAT_INVALID, // Invalid status. This status indicates an error. KA_STAT_ONGOING, // Keepalive processing currently ongoing. KA_STAT_FIN_SUCCESS, // Keepalive processing finished successfully KA_STAT_FIN_TIMEOUT, // Keepalive timeout has been detected. KA_STAT_FIN_ERROR // Keepalive processing finished with errors } ka_status_t; // Keepalive public function prototypes. ka_ret_t KA_init ( void ** pp_engine, uint32_t ka_send_interval, char* ka_src_addr, char* ka_dst_addr, sint32_t ka_af ); ka_ret_t KA_start ( void * p_engine ); ka_status_t KA_qry_status ( void * p_engine ); ka_ret_t KA_stop ( void * p_engine ); ka_ret_t KA_destroy ( void ** pp_engine ); #endif gogoc-1_2-RELEASE/gogoc-tsp/include/net_ka_winxp.h0100644000000000000000000000143411301544573020501 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: net_ka_winxp.h,v 1.1 2009/11/20 16:53:15 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ extern sint32_t winxp_use_old_ka; // Defined in winpc/tsp_local.c sint32_t NetKeepaliveInit ( char *src, char *dst, sint32_t maximal_keepalive, sint32_t family ); void NetKeepaliveDestroy ( void ); sint32_t NetKeepaliveDo ( void ); void NetKeepaliveGotRead ( void ); void NetKeepaliveGotWrite( void ); gogoc-1_2-RELEASE/gogoc-tsp/include/net_rudp.h0100644000000000000000000000424411301544574017636 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: net_rudp.h,v 1.1 2009/11/20 16:53:16 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ #ifndef _rudp_h_ #define _rudp_h_ #define RTTENGINE_G (float)1/8 #define RTTENGINE_H (float)1/4 #define RTTENGINE_TMIN 2 #define RTTENGINE_TMAX 30 #define RTTENGINE_MAXRTT 3 #define RTTENGINE_MAXRT 8 extern sint32_t NetRUDPConnect (pal_socket_t *, char *, uint16_t); extern sint32_t NetRUDPClose (pal_socket_t); extern sint32_t NetRUDPReadWrite (pal_socket_t, char *, sint32_t, char *, sint32_t); extern sint32_t NetRUDPWrite (pal_socket_t, char *, sint32_t); extern sint32_t NetRUDPPrintf (pal_socket_t, char *, sint32_t, char *, ...); extern sint32_t NetRUDPRead (pal_socket_t, char *, sint32_t); typedef struct rudp_message_struct { uint32_t sequence; uint32_t timestamp; } rudp_msghdr_t; typedef struct rttengine_statistics { /* connected udp host stats */ struct sockaddr* sai; /* stat stats */ float rtt; float srtt; float rttvar; float rto; /* timeline stats */ uint32_t sequence; sint32_t retries; sint32_t last_recv_sequence; sint32_t initial_timestamp; sint32_t apply_backoff; sint32_t has_peer; sint32_t initiated; } rttengine_stat_t; extern rttengine_stat_t rttengine_stats; /* rudp engine functions */ extern sint32_t rttengine_init (rttengine_stat_t *); extern sint32_t rttengine_deinit (rttengine_stat_t *, void *, void *); extern void * internal_prepare_message(rudp_msghdr_t **, size_t); extern void internal_discard_message(void *); extern float rttengine_update (rttengine_stat_t *, uint32_t); extern uint32_t internal_get_timestamp(rttengine_stat_t *); extern float internal_get_adjusted_rto(float); extern sint32_t internal_send_recv (pal_socket_t, void *, sint32_t, void *, sint32_t); #endif gogoc-1_2-RELEASE/gogoc-tsp/include/net_rudp6.h0100644000000000000000000000172011301544574017720 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: net_rudp6.h,v 1.1 2009/11/20 16:53:16 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ #ifdef V4V6_SUPPORT #ifndef _rudp6_h_ #define _rudp6_h_ extern sint32_t NetRUDP6Connect (pal_socket_t *, char *, uint16_t); extern sint32_t NetRUDP6Close (pal_socket_t); extern sint32_t NetRUDP6ReadWrite (pal_socket_t, char *, sint32_t, char *, sint32_t); extern sint32_t NetRUDP6Write (pal_socket_t, char *, sint32_t); extern sint32_t NetRUDP6Printf (pal_socket_t, char *, sint32_t, char *, ...); extern sint32_t NetRUDP6Read (pal_socket_t, char *, sint32_t); #endif #endif /* V4V6_SUPPORT */ gogoc-1_2-RELEASE/gogoc-tsp/include/net_tcp.h0100644000000000000000000000164311301544574017452 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: net_tcp.h,v 1.1 2009/11/20 16:53:16 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ #ifndef _NET_TCP_H_ #define _NET_TCP_H_ extern sint32_t NetTCPConnect (pal_socket_t *, char *, uint16_t ); extern sint32_t NetTCPClose (pal_socket_t); extern sint32_t NetTCPReadWrite (pal_socket_t, char *, sint32_t, char *, sint32_t); extern sint32_t NetTCPWrite (pal_socket_t, char *, sint32_t); extern sint32_t NetTCPPrintf (pal_socket_t, char *, sint32_t, char *, ...); extern sint32_t NetTCPRead (pal_socket_t, char *, sint32_t); #endif gogoc-1_2-RELEASE/gogoc-tsp/include/net_tcp6.h0100644000000000000000000000305711301544574017541 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: net_tcp6.h,v 1.1 2009/11/20 16:53:16 jasminko Exp $ ----------------------------------------------------------------------------- * This source code copyright (c) gogo6 Inc. 2002-2004,2007. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2, * June 1991 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file GPL_LICENSE.txt. If not, write * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA ----------------------------------------------------------------------------- */ #ifndef _NET_TCP6_H_ #define _NET_TCP6_H_ extern sint32_t NetTCP6Connect (pal_socket_t *, char *, uint16_t); extern sint32_t NetTCP6Close (pal_socket_t); extern sint32_t NetTCP6ReadWrite (pal_socket_t, char *, sint32_t, char *, sint32_t); extern sint32_t NetTCP6Write (pal_socket_t, char *, sint32_t); extern sint32_t NetTCP6Printf (pal_socket_t, char *, sint32_t, char *, ...); extern sint32_t NetTCP6Read (pal_socket_t, char *, sint32_t); #endif gogoc-1_2-RELEASE/gogoc-tsp/include/net_udp.h0100644000000000000000000000164211301544574017453 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: net_udp.h,v 1.1 2009/11/20 16:53:16 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ #ifndef _NET_UDP_H_ #define _NET_UDP_H_ extern sint32_t NetUDPConnect (pal_socket_t *, char *, uint16_t ); extern sint32_t NetUDPClose (pal_socket_t); extern sint32_t NetUDPReadWrite (pal_socket_t, char *, sint32_t, char *, sint32_t); extern sint32_t NetUDPWrite (pal_socket_t, char *, sint32_t); extern sint32_t NetUDPPrintf (pal_socket_t, char *, sint32_t, char *, ...); extern sint32_t NetUDPRead (pal_socket_t, char *, sint32_t); #endif gogoc-1_2-RELEASE/gogoc-tsp/include/service.h0100644000000000000000000000140511301544574017452 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: service.h,v 1.1 2009/11/20 16:53:16 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2005 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ #ifndef _SERVICE_H_ #define _SERVICE_H_ BOOL service_init ( void ); BOOL service_create ( TCHAR *name ); BOOL service_delete ( TCHAR *name ); void service_parse_cli ( int argc, TCHAR *argv[] ); void service_main ( int argc, TCHAR *argv[] ); #endif gogoc-1_2-RELEASE/gogoc-tsp/include/tsp_auth.h0100644000000000000000000000213411301544574017641 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: tsp_auth.h,v 1.1 2009/11/20 16:53:16 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ #ifndef _TSP_AUTH_H_ #define _TSP_AUTH_H_ #include "tsp_cap.h" #include "net.h" #include "tsp_redirect.h" /**Bug1455: * If connecting to a Migration Server using TSP version 2.0.0 or earlier, * MD5 digest authentication may be wrongly calculated in some * username and other credentials combinations. The define below ensure * an MD5 digest compatible with earlier Migration Broker is generated * when the TSP protocol version is 2.0.0 or earlier. */ #define SUPPORT_MD5_BUG1455 1 gogoc_status tspAuthenticate (pal_socket_t, tCapability, net_tools_t *, tConf *, tBrokerList **, sint32_t); #endif gogoc-1_2-RELEASE/gogoc-tsp/include/tsp_auth_passdss.h0100644000000000000000000000131411301544574021400 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: tsp_auth_passdss.h,v 1.1 2009/11/20 16:53:16 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ #ifndef _TSP_AUTH_PASSDSS_H_ #define _TSP_AUTH_PASSDSS_H_ #ifndef NO_OPENSSL #include "net.h" #include "tsp_redirect.h" gogoc_status AuthPASSDSS_3DES_1 (pal_socket_t s, net_tools_t *nt, tConf *conf, tBrokerList **broker_list); #endif #endif gogoc-1_2-RELEASE/gogoc-tsp/include/tsp_cap.h0100644000000000000000000000262711301544575017453 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: tsp_cap.h,v 1.1 2009/11/20 16:53:17 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ #ifndef _TSP_CAP_H_ #define _TSP_CAP_H_ #include "net.h" #include "tsp_redirect.h" /* Capability bytes 16 8 1 |-------|------| `--' - TUNNEL TYPE 1-4 `--' AUTH METHOD 5-8 `------' RESERVED 9-16 */ /* the tunnel modes values correspond to tTunnelMode defined in config.h */ #define TUNNEL_V6V4 0x0001 #define TUNNEL_V6UDPV4 0x0002 #define TUNNEL_ANY 0x0003 #define TUNNEL_V4V6 0x0004 /* Authentication values */ #ifndef NO_OPENSSL #define AUTH_PASSDSS_3DES_1 0x0080 #endif #define AUTH_DIGEST_MD5 0x0040 #define AUTH_PLAIN 0x0020 #define AUTH_ANONYMOUS 0x0010 #define AUTH_ANY 0x00F0 typedef uint32_t tCapability; tCapability tspSetCapability ( char *, char * ); gogoc_status tspGetCapabilities ( pal_socket_t, net_tools_t *, tCapability *, int, tConf *, tBrokerList ** ); char* tspFormatCapabilities ( char* szBuffer, const size_t bufLen, const tCapability cap ); #endif gogoc-1_2-RELEASE/gogoc-tsp/include/tsp_client.h0100644000000000000000000000455211345002057020155 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: tsp_client.h,v 1.3 2010/03/07 19:53:19 carl Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ #ifndef _TSP_CLIENT_H_ #define _TSP_CLIENT_H_ #include "config.h" /* tConf */ #include "xml_tun.h" /* tTunnel , tspXMLParse() */ #include "tsp_net.h" /* tPayload */ #include "net.h" /* net_tools_t */ #include "tsp_redirect.h" typedef enum { CLIENT_VERSION_INDEX_2_0_2, CLIENT_VERSION_INDEX_2_0_1, CLIENT_VERSION_INDEX_2_0_0, CLIENT_VERSION_INDEX_1_0_1 } tClientVersionIndex; #define CLIENT_VERSION_INDEX_CURRENT CLIENT_VERSION_INDEX_2_0_2 #ifndef CLIENT_VERSION_INDEX_OLDEST /* Allow platform override */ #define CLIENT_VERSION_INDEX_OLDEST CLIENT_VERSION_INDEX_1_0_1 #endif #define CLIENT_VERSION_INDEX_V6UDPV4_START CLIENT_VERSION_INDEX_2_0_0 #define CLIENT_VERSION_INDEX_V4V6_START CLIENT_VERSION_INDEX_2_0_0 #define CLIENT_VERSION_STRING_2_0_2 "2.0.2" #define CLIENT_VERSION_STRING_2_0_1 "2.0.1" #define CLIENT_VERSION_STRING_2_0_0 "2.0.0" #define CLIENT_VERSION_STRING_1_0_1 "1.0.1" // Defined locally in tsp_client.c extern const char * TSPProtoVerStr[]; // Implemented in tsp_client.c sint32_t tspMain ( sint32_t, char *[] ); sint32_t tspExtractPayload ( char *, tTunnel * ); sint32_t tspGetStatusCode ( char * ); const char* tspGetTspStatusStr ( sint32_t ); // Implemented in each platform tsp_local.c extern uint16_t tspGetLocalPort ( pal_socket_t ); extern gogoc_status tspStartLocal ( pal_socket_t, tConf *, tTunnel *, net_tools_t * ); extern void tspSetEnv ( char *, char *, sint32_t ); extern sint32_t tspSetupInterfaceLocal( tConf* pConf, tTunnel* pTun ); extern sint32_t tspCheckForStopOrWait ( const uint32_t uiWaitMs ); extern void tspGetOSInfo ( const size_t len, char* buf ); extern char* tspGetLocalAddress ( pal_socket_t, char *, sint32_t ); #ifdef DSLITE_SUPPORT extern char* tspGetRemoteAddress ( pal_socket_t, char *, sint32_t ); #endif #endif gogoc-1_2-RELEASE/gogoc-tsp/include/tsp_lease.h0100644000000000000000000000113711301544575017774 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: tsp_lease.h,v 1.1 2009/11/20 16:53:17 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ #ifndef _TSP_LEASE_H_ #define _TSP_LEASE_H_ long tspLeaseGetExpTime ( const long tun_lifetime ); sint32_t tspLeaseCheckExp ( const long tun_expiration ); #endif gogoc-1_2-RELEASE/gogoc-tsp/include/tsp_net.h0100644000000000000000000000270011301544575017466 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: tsp_net.h,v 1.1 2009/11/20 16:53:17 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ #ifndef _TSP_NET_H_ #define _TSP_NET_H_ #include "net.h" /* definitions and constants */ #define MAXNAME 1024 #define MAXSERVER 1024 #define SERVER_PORT 3653 #define SERVER_PORT_STR "3653" #define PROTOCOLMAXPAYLOADCHUNK 2048 #define PROTOCOLFRAMESIZE 4096 #define PROTOCOLMAXHEADER 70 enum { PROTOCOL_OK, PROTOCOL_ERROR, PROTOCOL_EMEM, PROTOCOL_ESYNTAX, PROTOCOL_ESIZE, PROTOCOL_EREAD }; /* structures */ typedef struct stPayload { long size, PayloadCapacity; char *payload; } tPayload; // Public function prototypes. gogoc_status tspConnect ( pal_socket_t*, char *, uint16_t, net_tools_t * ); gogoc_status tspClose ( pal_socket_t, net_tools_t * ); sint32_t tspSendRecv ( pal_socket_t, tPayload *, tPayload *, net_tools_t * ); sint32_t tspSend ( pal_socket_t, tPayload *, net_tools_t * ); sint32_t tspReceive ( pal_socket_t, tPayload *, net_tools_t * ); #endif gogoc-1_2-RELEASE/gogoc-tsp/include/tsp_redirect.h0100644000000000000000000000655111301544575020511 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: tsp_redirect.h,v 1.1 2009/11/20 16:53:17 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ #ifndef _TSP_REDIRECT_H_ #define _TSP_REDIRECT_H_ #include #include "config.h" #include "xml_tun.h" #define DEFAULT_REDIRECT_LAST_SERVER_FILE "tsp-last-server.txt" #define DEFAULT_REDIRECT_BROKER_LIST_FILE "tsp-broker-list.txt" #define MAX_REDIRECT_ADDRESS_LENGTH 255 #define MAX_REDIRECT_LAST_SERVER_LENGTH 255 #define MAX_REDIRECT_BROKER_LIST_LENGTH 255 #define MAX_REDIRECT_LAST_SERVER_LINE_LENGTH 255 #define MAX_REDIRECT_BROKER_LIST_LINE_LENGTH 255 #define MAX_REDIRECT_BROKERS_IN_LIST 50 #define MAX_BROKER_LIST_STRING_LENGTH 4096 #define MAX_REDIRECT_STATUS_LENGTH 1024 #define REDIRECT_RECEIVE_BUFFER_SIZE 4096 #define BROKER_LIST_STRING_START "[ " #define BROKER_LIST_STRING_END " ]" #define BROKER_LIST_STRING_SEPARATOR ", " #define BROKER_LIST_STRING_SUSPENSION "..." #define REDIRECT_STATUS_CODE_BASE 1000 typedef enum { TSP_REDIRECT_OK, TSP_REDIRECT_INTERNAL_ERR, TSP_REDIRECT_CANT_OPEN_FILE, TSP_REDIRECT_NO_LAST_SERVER, TSP_REDIRECT_CANT_WRITE_TO_FILE, TSP_REDIRECT_CANT_ADD_BROKER_TO_LIST, TSP_REDIRECT_CANT_EXTRACT_PAYLOAD, TSP_REDIRECT_CANT_CREATE_LIST, TSP_REDIRECT_CANT_SORT_LIST, TSP_REDIRECT_CANT_LOG_REDIRECTION, TSP_REDIRECT_CANT_ALLOCATE_MEM, TSP_REDIRECT_ADDRESS_TRUNCATED, TSP_REDIRECT_CANT_GET_DISTANCES, TSP_REDIRECT_CANT_INSERT_BROKER_IN_LIST, TSP_REDIRECT_CANT_SAVE_BROKER_LIST, TSP_REDIRECT_EMPTY_BROKER_LIST, TSP_REDIRECT_TOO_MANY_BROKERS, TSP_REDIRECT_CANT_INIT_THREAD_ARG, TSP_REDIRECT_CANT_CREATE_THREAD, TSP_REDIRECT_CANT_WAIT_FOR_THREAD, TSP_REDIRECT_ECHO_REQUEST_TIMEOUT, TSP_REDIRECT_ECHO_REQUEST_ERROR, TSP_REDIRECT_CANT_MALLOC_THREAD_ARRAY, TSP_REDIRECT_CANT_MALLOC_THREAD_ARGS } tRedirectStatus; typedef enum { TSP_REDIRECT_BROKER_TYPE_NONE, TSP_REDIRECT_BROKER_TYPE_FQDN, TSP_REDIRECT_BROKER_TYPE_IPV4, TSP_REDIRECT_BROKER_TYPE_IPV6 } tBrokerAddressType; typedef struct stBrokerList { char address[MAX_REDIRECT_ADDRESS_LENGTH]; tBrokerAddressType address_type; unsigned int distance; struct stBrokerList *next; } tBrokerList; typedef struct stBrokerTimingThreadArg { tBrokerList *broker; tConf *conf; } tBrokerTimingThreadArg; extern tRedirectStatus tspGetBrokerDistances(tBrokerList *broker_list, int broker_count, tConf *conf); extern int tspIsRedirectStatus(int status); extern tRedirectStatus tspLogRedirectionList(tBrokerList *broker_list, int sorted); extern tRedirectStatus tspFreeBrokerList(tBrokerList *broker_list); extern tRedirectStatus tspHandleRedirect(char *payload, tConf *conf, tBrokerList **broker_list); extern tRedirectStatus tspReadLastServerFromFile(char *last_server_file, char *buffer); extern tRedirectStatus tspWriteLastServerToFile(char *last_server_file, char *last_server); extern tRedirectStatus tspReadBrokerListFromFile(char *broker_list_file, tBrokerList **broker_list); extern tRedirectStatus tspWriteBrokerListToFile(char *broker_list_file, tBrokerList *broker_list); #endif gogoc-1_2-RELEASE/gogoc-tsp/include/tsp_setup.h0100644000000000000000000000131411301544575020040 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: tsp_setup.h,v 1.1 2009/11/20 16:53:17 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ #ifndef _TSP_SETUP_H_ #define _TSP_SETUP_H_ #include "config.h" #include "xml_tun.h" sint32_t execScript ( const char *cmd ); gogoc_status tspSetupInterface ( tConf *c, tTunnel *t ); gogoc_status tspTearDownTunnel ( tConf* pConf, tTunnel* pTunInfo ); #endif gogoc-1_2-RELEASE/gogoc-tsp/include/tsp_tun_mgt.h0100644000000000000000000000177111301544575020364 0ustar rootroot/* --------------------------------------------------------------------------- $Id: tsp_tun_mgt.h,v 1.1 2009/11/20 16:53:17 jasminko Exp $ --------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. --------------------------------------------------------------------------- */ #ifndef __TSP_TUN_MGT_H__ #define __TSP_TUN_MGT_H__ typedef struct __TUNNEL_LOOP_CONFIG { char* ka_src_addr; // KA source address (usually local endpoint). char* ka_dst_addr; // KA destination address (usually broker). int sa_family; // Socket address family [AF_INET, AF_INET6]. unsigned int ka_interval; // Keepalive interval in seconds. long tun_lifetime; // Tunnel lifetime (tunnel expiration feature). } TUNNEL_LOOP_CONFIG, *PTUNNEL_LOOP_CONFIG; gogoc_status tspPerformTunnelLoop ( const PTUNNEL_LOOP_CONFIG pTunLoopCfg ); #endif gogoc-1_2-RELEASE/gogoc-tsp/include/version.h0100644000000000000000000000221611346561546017507 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: version.h,v 1.2 2010/03/09 13:21:30 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ #ifndef VERSION_H #define VERSION_H // Software option. #ifdef HACCESS #define TSP_CLIENT_OPT_SOFT "HACCESS enabled" #else #define TSP_CLIENT_OPT_SOFT "" #endif // Architecture type (For Windows builds only). #ifdef WIN32 #ifdef BUILD_OPT_X64 #define TSP_CLIENT_OPT_ARCH "64-bit" #else #define TSP_CLIENT_OPT_ARCH "32-bit" #endif #else #define TSP_CLIENT_OPT_ARCH "" #endif // Version number. #define TSP_CLIENT_VERSION "1.1-RELEASE" // Identification string. #define IDENTIFICATION "gogoCLIENT v" TSP_CLIENT_VERSION " build " __DATE__ \ "-" __TIME__ " " TSP_CLIENT_OPT_SOFT " " TSP_CLIENT_OPT_ARCH // defined in tsp_client.c extern char *TspProtocolVersionStrings[]; char * tsp_get_version ( void ); #endif gogoc-1_2-RELEASE/gogoc-tsp/include/xml_req.h0100644000000000000000000000111311301544576017457 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: xml_req.h,v 1.1 2009/11/20 16:53:18 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ #ifndef _XML_REQ_H_ #define _XML_REQ_H_ #include "config.h" char * tspBuildCreateRequest ( tConf * ); char * tspBuildCreateAcknowledge( void ); #endif gogoc-1_2-RELEASE/gogoc-tsp/include/xml_tun.h0100644000000000000000000000270011345002057017470 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: xml_tun.h,v 1.2 2010/03/07 19:53:19 carl Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ #ifndef XML_TUN_H #define XML_TUN_H #ifdef XMLTUN # define ACCESS #else # define ACCESS extern #endif typedef struct stLinkedList { char *Value; struct stLinkedList *next; } tLinkedList; typedef struct stTunnel { char *action, *type, *lifetime, *proxy, *mtu, *client_address_ipv4, *client_address_ipv6, *client_dns_server_address_ipv6, *client_dns_name, *server_address_ipv4, *server_address_ipv6, *router_protocol, *prefix_length, *prefix, *client_as, *server_as, *keepalive_interval, *keepalive_address; tLinkedList *dns_server_address_ipv4, *dns_server_address_ipv6, *broker_address_ipv4, *broker_address_ipv6, *broker_redirect_ipv4, *broker_redirect_ipv6, *broker_redirect_dn; } tTunnel; ACCESS sint32_t tspXMLParse ( char *Data, tTunnel *Tunnel ); ACCESS void tspClearTunnelInfo ( tTunnel *Tunnel ); #undef ACCESS #endif gogoc-1_2-RELEASE/gogoc-tsp/include/xmlparse.h0100644000000000000000000000376611301544576017663 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: xmlparse.h,v 1.1 2009/11/20 16:53:18 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT. ----------------------------------------------------------------------------- */ #ifndef XMLPARSE_H #define XMLPARSE_H #ifdef XMLPARSE # define ACCESS #else # define ACCESS extern #endif /* * In the node structure, the following identify how many attributes a node can * have max. It can be adjusted at compile time. */ #define MAX_ATTRIBUTES 5 /* * The following identify the format of a node processing function that must be * supplied in the node structure to take care of the information supplied in the * structure. */ struct stNode; typedef sint32_t processNode(struct stNode *n, char *content); /* * The node structure contains the relevant information of each node to be * parsed by each invocation of the parser. */ typedef struct stAttribute { char *name; char *value; } tAttribute; typedef struct stNode { char *name; processNode *p; tAttribute attributes[MAX_ATTRIBUTES + 1]; } tNode; /* * The XMLParser function is responsible of parsing the contain of a string, * calling the appropriate processNode function when a node token is recognized. * * Parameters: * * * Return value: * * 0 - Success * -1 - Memory allocation error * n - Parsing error at position n in the string */ ACCESS sint32_t XMLParse(char *str, tNode nodes[]); /* * The following macros are usefull to declare the node structures * * They assume that the event functions will be named the same as the * XML tags, prefixed with p_ * */ #define NODE(n) { #n, p_##n, { #define ENDNODE { "", 0 } } }, #define ATTR(a) { #a, 0 }, #define ENDLIST { "", 0, { { "", 0 } } } }; #define STARTLIST { #define PROC(pr) sint32_t p_##pr (tNode *n, char *content) #undef ACCESS #endif gogoc-1_2-RELEASE/gogoc-tsp/platform/0040755000000000000000000000000011346561546016054 5ustar rootrootgogoc-1_2-RELEASE/gogoc-tsp/platform/darwin/0040755000000000000000000000000011346561543017335 5ustar rootrootgogoc-1_2-RELEASE/gogoc-tsp/platform/darwin/Makefile0100644000000000000000000000220311301544600020751 0ustar rootroot# ########################################################################### # $Id: Makefile,v 1.1 2009/11/20 16:53:20 jasminko Exp $ # # This source code copyright (c) gogo6 Inc. 2002-2007. # # For license information refer to CLIENT-LICENSE.TXT # # ########################################################################### # # NOTE: This makefile MUST be interpreted by GNU make. # Include the platform makefile, if it exists. -include platform.mak ifdef DEBUG CFLAGS=-g -Wall $(CC_INC_PATHS) $(PLATFORM_CFLAGS) -D_REENTRANT -DDEBUG LDFLAGS=-g $(LD_LIB_PATHS) $(LD_LIBRARIES) -lcrypto -lstdc++ -fexceptions else CFLAGS=-O2 -Wall $(CC_INC_PATHS) $(PLATFORM_CFLAGS) -D_REENTRANT LDFLAGS=$(LD_LIB_PATHS) $(LD_LIBRARIES) -lcrypto -lstdc++ -fexceptions endif CC=gcc OBJS=$(OBJS_DIR)/tsp_local.o \ $(OBJS_DIR)/tsp_tun.o all: $(TARGET) install: all $(OBJS_DIR)/tsp_local.o: tsp_local.c $(CC) $(CFLAGS) -c tsp_local.c -o $(OBJS_DIR)/tsp_local.o $(OBJS_DIR)/tsp_tun.o: tsp_tun.c $(CC) $(CFLAGS) -c tsp_tun.c -o $(OBJS_DIR)/tsp_tun.o $(TARGET): $(OBJS) $(CC) -o $(TARGET) $(wildcard $(OBJS_DIR)/*.o) $(LDFLAGS) clean: rm -f $(OBJS) $(TARGET) gogoc-1_2-RELEASE/gogoc-tsp/platform/darwin/platform.h0100644000000000000000000000106111301544600021307 0ustar rootroot/* --------------------------------------------------------------------------- $Id: platform.h,v 1.1 2009/11/20 16:53:20 jasminko Exp $ --------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT --------------------------------------------------------------------------- */ #ifndef _PLATFORM_H_ #define _PLATFORM_H_ /* Mac OS X Darwin */ #include "pal.h" #define SCRIPT_TMP_FILE "/tmp/gogoc-tmp.log" #endif gogoc-1_2-RELEASE/gogoc-tsp/platform/darwin/platform.mak0100644000000000000000000000107311301544600021633 0ustar rootroot# ########################################################################### # # $Id: platform.mak,v 1.1 2009/11/20 16:53:20 jasminko Exp $ # # Copyright (c) 2007 gogo6 Inc. All rights reserved. # # For license information refer to CLIENT-LICENSE.TXT # # This file contains platform-specific makefile rules and symbols. # # ########################################################################### # # Additional platform CFLAGS. # PLATFORM_CFLAGS= # Platform default interface names for each tunnel mode. # PLATFORM_V6V4=gif0 PLATFORM_V6UDPV4=tun0 PLATFORM_V4V6= gogoc-1_2-RELEASE/gogoc-tsp/platform/darwin/tsp_local.c0100644000000000000000000002132111345003673021447 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: tsp_local.c,v 1.3 2010/03/07 20:08:27 carl Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ /* DARWIN */ #include "platform.h" #include "gogoc_status.h" #include #include #include "config.h" /* tConf */ #include "xml_tun.h" /* tTunnel */ #include "net.h" /* net_tools_t */ #include "log.h" /* Display */ #include "hex_strings.h" /* Display strings */ #include "tsp_net.h" /* tspClose */ #include "tsp_setup.h" /* tspSetupInterface */ #include "tsp_tun.h" /* TunInit, TunMainLoop */ #include "tsp_tun_mgt.h" /* tspPerformTunnelLoop */ /* these globals are defined by US used by alot of things in */ #define IFNAMSIZ 16 // from net/if.h char *FileName = "gogoc.conf"; char *ScriptInterpretor = "/bin/sh"; char *ScriptExtension = "sh"; char *ScriptDir = NULL; char *TspHomeDir = "/usr/local/etc/gogoc"; char DirSeparator = '/'; int indSigHUP = 0; // Set to 1 when HUP signal is trapped. #include // Dummy implementation for non-win32 targets // (Library gogocmessaging is not linked in non-win32 targets). error_t send_status_info( void ) { return GOGOCM_UIS__NOERROR; } error_t send_tunnel_info( void ) { return GOGOCM_UIS__NOERROR; } error_t send_broker_list( void ) { return GOGOCM_UIS__NOERROR; } error_t send_haccess_status_info( void ) { return GOGOCM_UIS__NOERROR; } // -------------------------------------------------------------------------- // Set an environment variable in the current process. // void tspSetEnv(char *Variable, char *Value, int Flag) { Display(LOG_LEVEL_3, ELInfo, "tspSetEnv", GOGO_STR_ENV_PRINT_VALUE, Variable, Value); setenv(Variable, Value, Flag); } // -------------------------------------------------------------------------- // Checks if the gogoCLIENT has been requested to stop and exit. // // Returns 1 if gogoCLIENT is being requested to stop and exit. // Else, waits 'uiWaitMs' miliseconds and returns 0. // // Defined in tsp_client.h // int tspCheckForStopOrWait( const unsigned int uiWaitMs ) { // Sleep for the amount of time specified, if signal has not been sent. if( indSigHUP == 0 ) { // usleep is expecting microseconds (1 microsecond = 0.000001 second). usleep( uiWaitMs * 1000 ); } return indSigHUP; } // -------------------------------------------------------------------------- // Called from tsp_setup.c -> tspSetupInterface // Do extra platform-specific stuff before tunnel script is launched. // int tspSetupInterfaceLocal( tConf* pConf, tTunnel* pTun ) { return 0; } // -------------------------------------------------------------------------- // Returns local address. // tspSetupTunnel() will callback here // char* tspGetLocalAddress(int socket, char *buffer, int size) { struct sockaddr_in6 addr; /* enough place for v4 and v6 */ struct sockaddr_in *addr_v4 = (struct sockaddr_in *)&addr; struct sockaddr_in6 *addr_v6 = (struct sockaddr_in6 *)&addr; socklen_t len; len = sizeof addr; if (getsockname(socket, (struct sockaddr *)&addr, &len) < 0) { Display(LOG_LEVEL_1, ELError, "TryServer", GOGO_STR_ERR_FIND_SRC_IP); return NULL; } if (addr.sin6_family == AF_INET6) return (char *)inet_ntop(AF_INET6, (const void*) &addr_v6->sin6_addr, buffer, size); else return (char *)inet_ntop(AF_INET, (const void*) &addr_v4->sin_addr, buffer, size); } // -------------------------------------------------------------------------- // tspSetupTunnel() will callback here // - setup interface and any daemons or anything needed. // #ifdef DSLITE_SUPPORT #error DSLITE support not implemented on platform #endif gogoc_status tspStartLocal( int socket, tConf *c, tTunnel *t, net_tools_t *nt ) { TUNNEL_LOOP_CONFIG tun_loop_cfg; gogoc_status status = STATUS_SUCCESS_INIT; int ka_interval = 0; int tunfd = -1; int pid; // Check if we got root privileges. if( geteuid() != 0 ) { // Error: we don't have root privileges. Display( LOG_LEVEL_1, ELError, "tspStartLocal", GOGO_STR_FATAL_NOT_ROOT_FOR_TUN ); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } // Check if we're already daemon. Calling multiple times the daemon() messes up pthreads. if( !c->nodaemon && getppid() != 1 ) { // Detach from controlling terminal and run in the background. Display( LOG_LEVEL_3, ELInfo, "tspStartLocal", GOGO_STR_GOING_DAEMON ); if( daemon(1, 0) == -1 ) { // Error: Failed to detach. Display( LOG_LEVEL_1, ELError, "tspStartLocal", GOGO_STR_CANT_FORK ); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } } // Check tunnel mode. if( strcasecmp(t->type, STR_CONFIG_TUNNELMODE_V4V6) == 0 ) { // V4V6 encapsulation (DSTM) not supported on darwin. Display( LOG_LEVEL_1, ELError, "tspStartLocal", GOGO_STR_NO_V4V6_ON_PLATFORM ); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } else if( strcasecmp(t->type, STR_CONFIG_TUNNELMODE_V6UDPV4) == 0 ) { // When using V6UDPV4 encapsulation, open the TUN device. tunfd = TunInit(c->if_tunnel_v6udpv4); if( tunfd == -1 ) { // Error: Failed to open TUN device. Display( LOG_LEVEL_1, ELError, "tspStartLocal", STR_MISC_FAIL_TUN_INIT ); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } // Get the real name of the opened tun device for the template script. free( c->if_tunnel_v6udpv4 ); c->if_tunnel_v6udpv4 = (char*) malloc( IFNAMSIZ ); TunName( tunfd, c->if_tunnel_v6udpv4, IFNAMSIZ ); } while( 1 ) // Dummy loop. 'break' instruction at the end. { // Run the config script in another thread, without giving it our tunnel // descriptor. This is important because otherwise the tunnel will stay // open if we get killed. // pid = fork(); if( pid < 0 ) { // fork() error status = make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); break; } else if( pid == 0 ) { // Child processing: run template script. if( tunfd != -1 ) { close(tunfd); } status = tspSetupInterface(c, t); exit( status ); } else { // Parent processing int s = 0; // Wait for child process to exit. Display( LOG_LEVEL_3, ELInfo, "tspStartLocal", GOGO_STR_WAITING_FOR_SETUP_SCRIPT ); if( wait(&s) != pid ) { // Error occured: we have no other child Display( LOG_LEVEL_1, ELError, "tspStartLocal", GOGO_STR_ERR_WAITING_SCRIPT ); status = make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); break; } // Check if process waited upon has exited. if( !WIFEXITED(s) ) { // Error: child has not exited properly. Maybe killed ? Display( LOG_LEVEL_1, ELError, "tspStartLocal", STR_GEN_SCRIPT_EXEC_FAILED ); status = make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); break; } // Check child exit code. status = WEXITSTATUS(s); if( status_number(status) != SUCCESS ) { break; } } // Retrieve keepalive inteval, if found in tunnel parameters. if( t->keepalive_interval != NULL ) { ka_interval = atoi(t->keepalive_interval); } // Start the tunnel loop, depending on tunnel mode // if( strcasecmp(t->type, STR_CONFIG_TUNNELMODE_V6UDPV4) == 0 ) { status = TunMainLoop( tunfd, socket, c->keepalive, ka_interval, t->client_address_ipv6, t->keepalive_address ); // We got out of main V6UDPV4 loop. tspClose(socket, nt); } else if( strcasecmp(t->type, STR_CONFIG_TUNNELMODE_V6V4) == 0 ) { memset( &tun_loop_cfg, 0x00, sizeof(TUNNEL_LOOP_CONFIG) ); tun_loop_cfg.ka_interval = ka_interval; tun_loop_cfg.ka_src_addr = t->client_address_ipv6; tun_loop_cfg.ka_dst_addr = t->keepalive_address; tun_loop_cfg.sa_family = AF_INET6; tun_loop_cfg.tun_lifetime = 0; status = tspPerformTunnelLoop( &tun_loop_cfg ); } break; // END of DUMMY loop. } // Cleanup: Close tunnel descriptor, if it was opened. if( tunfd != -1 ) { // The tunnel file descriptor should be closed before attempting to tear // down the tunnel. Destruction of the tunnel interface may fail if // descriptor is not closed. close( tunfd ); } // Cleanup: Handle tunnel teardown. tspTearDownTunnel( c, t ); return status; } gogoc-1_2-RELEASE/gogoc-tsp/platform/darwin/tsp_tun.c0100644000000000000000000001351711301544600021163 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: tsp_tun.c,v 1.1 2009/11/20 16:53:20 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2006 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ /* Darwin */ #include "platform.h" #include "gogoc_status.h" #include #include #include #include "tsp_tun.h" // Local function prototypes. #include "tsp_client.h" // tspCheckForStopOrWait() #include "net_ka.h" // KA function prototypes and types. #include "log.h" // Display and logging prototypes and types. #include "hex_strings.h" // String litterals #define TUN_BUFSIZE 2048 // Buffer size for TUN interface IO operations. // -------------------------------------------------------------------------- // TunName: Get the name of the tun device using file descriptor. // void TunName(int tunfd, char *name, size_t name_len ) { struct stat sbuf; char *unsafe_buffer; if( fstat( tunfd, &sbuf ) != -1 ) { unsafe_buffer = devname(sbuf.st_rdev, S_IFCHR); strncpy( name, unsafe_buffer, name_len ); } } // -------------------------------------------------------------------------- // TunInit: Open and initialize the TUN interface. // int TunInit( char* name ) { int tunfd; char iftun[128]; snprintf( iftun, sizeof(iftun), "/dev/%s", name ); tunfd = open( iftun, O_RDWR ); if( tunfd == -1 ) { Display(LOG_LEVEL_1, ELError, "TunInit", GOGO_STR_ERR_OPEN_TUN_DEV, iftun); return(-1); } return tunfd; } // -------------------------------------------------------------------------- // TunMainLoop: Initializes Keepalive engine and starts it. Then starts a // loop to transfer data from/to the socket and tunnel. // This process is repeated until tspCheckForStopOrWait indicates a stop. // gogoc_status TunMainLoop( int tunfd, pal_socket_t Socket, tBoolean keepalive, int keepalive_interval, char *local_address_ipv6, char *keepalive_address ) { fd_set rfds; int count, maxfd, ret; char bufin[TUN_BUFSIZE]; char bufout[TUN_BUFSIZE]; struct timeval timeout; void* p_ka_engine = NULL; ka_status_t ka_status; ka_ret_t ka_ret; int ongoing = 1; gogoc_status status; keepalive = (keepalive_interval != 0) ? TRUE : FALSE; if( keepalive == TRUE ) { // Initialize the keepalive engine. ka_ret = KA_init( &p_ka_engine, keepalive_interval * 1000, local_address_ipv6, keepalive_address, AF_INET6 ); if( ka_ret != KA_SUCCESS ) { return make_status(CTX_TUNNELLOOP, ERR_KEEPALIVE_ERROR); } // Start the keepalive loop(thread). ka_ret = KA_start( p_ka_engine ); if( ka_ret != KA_SUCCESS ) { KA_destroy( &p_ka_engine ); return make_status(CTX_TUNNELLOOP, ERR_KEEPALIVE_ERROR); } } // Data send loop. while( ongoing == 1 ) { // initialize status. status = STATUS_SUCCESS_INIT; if( tspCheckForStopOrWait( 0 ) != 0 ) { // We've been notified to stop. ongoing = 0; } if( keepalive == TRUE ) { // Check if we're stopping. if( ongoing == 0 ) { // Stop keepalive engine. KA_stop( p_ka_engine ); } // Query the keepalive status. ka_status = KA_qry_status( p_ka_engine ); switch( ka_status ) { case KA_STAT_ONGOING: case KA_STAT_FIN_SUCCESS: break; case KA_STAT_FIN_TIMEOUT: KA_stop( p_ka_engine ); status = make_status(CTX_TUNNELLOOP, ERR_KEEPALIVE_TIMEOUT); break; case KA_STAT_INVALID: case KA_STAT_FIN_ERROR: default: KA_stop( p_ka_engine ); status = make_status(CTX_TUNNELLOOP, ERR_KEEPALIVE_ERROR); break; } // Reinit select timeout variable; select modifies it. // Use 500ms because we need to re-check keepalive status. timeout.tv_sec = 0; timeout.tv_usec = 500000; // 500 milliseconds. } else { // Reinit select timeout variable; select modifies it. timeout.tv_sec = 7 * 24 * 60 * 60 ; // one week timeout.tv_usec = 0; } // Check if we're normal. if( status_number(status) != SUCCESS || ongoing != 1 ) { goto done; } FD_ZERO(&rfds); FD_SET(tunfd,&rfds); FD_SET(Socket,&rfds); maxfd = tunfd>Socket?tunfd:Socket; ret = select( maxfd+1, &rfds, 0, 0, &timeout ); if (ret > 0) { if( FD_ISSET(tunfd, &rfds) ) { // Data sent through UDP tunnel. /* ioctl(tunfd, FIONREAD, &count); */ if ((count = read(tunfd, bufout, TUN_BUFSIZE)) < -1) { Display(LOG_LEVEL_1, ELError, "TunMainLoop", STR_NET_FAIL_R_TUN_DEV); status = make_status(CTX_TUNNELLOOP, ERR_TUNNEL_IO); goto done; } if (send(Socket, bufout, count, 0) != count) { Display(LOG_LEVEL_1, ELError, "TunMainLoop", STR_NET_FAIL_W_SOCKET); status = make_status(CTX_TUNNELLOOP, ERR_TUNNEL_IO); goto done; } } if(FD_ISSET(Socket,&rfds)) { // Data received through UDP tunnel. count = recvfrom( Socket, bufin, TUN_BUFSIZE, 0, NULL, NULL ); if (write(tunfd, bufin, count) != count) { Display(LOG_LEVEL_1, ELError, "TunMainLoop", STR_NET_FAIL_W_TUN_DEV); status = make_status(CTX_TUNNELLOOP, ERR_TUNNEL_IO); goto done; } } } } // while ongoing == 1 /* Normal loop end */ status = STATUS_SUCCESS_INIT; done: if( keepalive == TRUE ) { KA_destroy( &p_ka_engine ); } return status; } gogoc-1_2-RELEASE/gogoc-tsp/platform/darwin/tsp_tun.h0100644000000000000000000000155711301544600021171 0ustar rootroot/* --------------------------------------------------------------------------- $Id: tsp_tun.h,v 1.1 2009/11/20 16:53:20 jasminko Exp $ --------------------------------------------------------------------------- Copyright (c) 2001-2006 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT --------------------------------------------------------------------------- */ #ifndef TUN_H #define TUN_H #include "config.h" // tBoolean void TunName ( int tunfd, char* name, size_t name_len ); int TunInit (char* name); gogoc_status TunMainLoop (int tun, int Socket, tBoolean keepalive, int keepalive_interval, char *local_address_ipv6, char *keepalive_address); #endif /* TUN_H */ gogoc-1_2-RELEASE/gogoc-tsp/platform/freebsd/0040755000000000000000000000000011346561543017463 5ustar rootrootgogoc-1_2-RELEASE/gogoc-tsp/platform/freebsd/Makefile0100644000000000000000000000217211301544603021107 0ustar rootroot# ########################################################################### # $Id: Makefile,v 1.1 2009/11/20 16:53:23 jasminko Exp $ # # This source code copyright (c) gogo6 Inc. 2002-2007. # # For license information refer to CLIENT-LICENSE.TXT # # ########################################################################### # # NOTE: This makefile MUST be interpreted by GNU make. # Include the platform makefile, if it exists. -include platform.mak ifdef DEBUG CFLAGS=-g -Wall $(CC_INC_PATHS) $(PLATFORM_CFLAGS) -D_REENTRANT -DDEBUG LDFLAGS=-g $(LD_LIB_PATHS) $(LD_LIBRARIES) -lcrypto -lpthread -lstdc++ else CFLAGS=-O2 -Wall $(CC_INC_PATHS) $(PLATFORM_CFLAGS) -D_REENTRANT LDFLAGS=$(LD_LIB_PATHS) $(LD_LIBRARIES) -lcrypto -lpthread -lstdc++ endif CC=gcc OBJS=$(OBJS_DIR)/tsp_local.o \ $(OBJS_DIR)/tsp_tun.o all: $(TARGET) install: all $(OBJS_DIR)/tsp_local.o:tsp_local.c $(CC) $(CFLAGS) -c tsp_local.c -o $(OBJS_DIR)/tsp_local.o $(OBJS_DIR)/tsp_tun.o:tsp_tun.c $(CC) $(CFLAGS) -c tsp_tun.c -o $(OBJS_DIR)/tsp_tun.o $(TARGET): $(OBJS) $(CC) -o $(TARGET) $(wildcard $(OBJS_DIR)/*.o) $(LDFLAGS) clean: rm -f $(OBJS) $(TARGET) gogoc-1_2-RELEASE/gogoc-tsp/platform/freebsd/platform.h0100644000000000000000000000107711301544603021447 0ustar rootroot/* --------------------------------------------------------------------------- $Id: platform.h,v 1.1 2009/11/20 16:53:23 jasminko Exp $ --------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT --------------------------------------------------------------------------- */ #ifndef _PLATFORM_H_ #define _PLATFORM_H_ /* FreeBSD */ #include "pal.h" #define V4V6_SUPPORT #define SCRIPT_TMP_FILE "/tmp/gogoc-tmp.log" #endif gogoc-1_2-RELEASE/gogoc-tsp/platform/freebsd/platform.mak0100644000000000000000000000107711301544603021770 0ustar rootroot# ########################################################################### # # $Id: platform.mak,v 1.1 2009/11/20 16:53:23 jasminko Exp $ # # Copyright (c) 2007 gogo6 Inc. All rights reserved. # # For license information refer to CLIENT-LICENSE.TXT # # This file contains platform-specific makefile rules and symbols. # # ########################################################################### # # Additional platform CFLAGS. # PLATFORM_CFLAGS= # Platform default interface names for each tunnel mode. # PLATFORM_V6V4=gif0 PLATFORM_V6UDPV4=tun1 PLATFORM_V4V6=gif0 gogoc-1_2-RELEASE/gogoc-tsp/platform/freebsd/tsp_local.c0100644000000000000000000002255211345003715021601 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: tsp_local.c,v 1.3 2010/03/07 20:08:45 carl Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ /* FREEBSD */ #include "platform.h" #include "gogoc_status.h" #include #include #include // For use with strerror #include "config.h" /* tConf and constants */ #include "xml_tun.h" /* tTunnel */ #include "net.h" /* net_tools_t */ #include "tsp_setup.h" /* tspSetupInterface() */ #include "tsp_net.h" /* tspClose() */ #include "tsp_client.h" /* tspMain() */ #include "tsp_tun_mgt.h" /* tspPerformTunnelLoop */ #include "log.h" #include "hex_strings.h" #include "tsp_tun.h" /* freebsd's tun */ #define IFNAMSIZ 16 // from net/if.h char *FileName = "gogoc.conf"; char *ScriptInterpretor = "/bin/sh"; char *ScriptExtension = "sh"; char *ScriptDir = NULL; char *TspHomeDir = "/usr/local/etc/gogoc"; char DirSeparator = '/'; int indSigHUP = 0; // Set to 1 when HUP signal is trapped. #include // Dummy implementation for non-win32 targets // (Library gogocmessaging is not linked in non-win32 targets). error_t send_status_info( void ) { return GOGOCM_UIS__NOERROR; } error_t send_tunnel_info( void ) { return GOGOCM_UIS__NOERROR; } error_t send_broker_list( void ) { return GOGOCM_UIS__NOERROR; } error_t send_haccess_status_info( void ) { return GOGOCM_UIS__NOERROR; } // -------------------------------------------------------------------------- // tspSetEnv // Now the function uses setenv because of putenv fix in FreeBSD 7. // void tspSetEnv(char *Variable, char *Value, int Flag) { int retCode; if( Variable != NULL && Value != NULL ) { // Overwrite the environment variable if it exists. retCode = setenv( Variable, Value, 1 ); if( retCode != 0 ) { // Failed to set environment variable. Display( LOG_LEVEL_1, ELError, GOGO_STR_ERR_SETENV, Variable, strerror(errno) ); } } } // -------------------------------------------------------------------------- // Checks if the gogoCLIENT has been requested to stop and exit. // // Returns 1 if gogoCLIENT is being requested to stop and exit. // Else, waits 'uiWaitMs' miliseconds and returns 0. // // Defined in tsp_client.h // int tspCheckForStopOrWait( const unsigned int uiWaitMs ) { // Sleep for the amount of time specified, if signal has not been sent. if( indSigHUP == 0 ) { // usleep is expecting microseconds (1 microsecond = 0.000001 second). usleep( uiWaitMs * 1000 ); } return indSigHUP; } // -------------------------------------------------------------------------- // Called from tsp_setup.c -> tspSetupInterface // Do extra platform-specific stuff before tunnel script is launched. // int tspSetupInterfaceLocal( tConf* pConf, tTunnel* pTun ) { return 0; } // -------------------------------------------------------------------------- /* tspSetupTunnel() will callback here */ char * tspGetLocalAddress(int socket, char *buffer, int size) { struct sockaddr_in6 addr; /* enough place for v4 and v6 */ struct sockaddr_in *addr_v4 = (struct sockaddr_in *)&addr; struct sockaddr_in6 *addr_v6 = (struct sockaddr_in6 *)&addr; int len; len = sizeof addr; if (getsockname(socket, (struct sockaddr *)&addr, &len) < 0) { Display(LOG_LEVEL_1, ELError, "TryServer", GOGO_STR_ERR_FIND_SRC_IP); return NULL; } if (addr.sin6_family == AF_INET6) return (char *)inet_ntop(AF_INET6, (const void*) &addr_v6->sin6_addr, buffer, size); else return (char *)inet_ntop(AF_INET, (const void*) &addr_v4->sin_addr, buffer, size); } // -------------------------------------------------------------------------- // tspSetupTunnel() will callback here // - start locally, ie, setup interface and any daemons or anything needed. // #ifdef DSLITE_SUPPORT #error DSLITE support not implemented on platform #endif gogoc_status tspStartLocal(int socket, tConf *c, tTunnel *t, net_tools_t *nt) { TUNNEL_LOOP_CONFIG tun_loop_cfg; gogoc_status status = STATUS_SUCCESS_INIT; int ka_interval = 0; int lifetime = 0; int tunfd = -1; int pid; // Check if we got root privileges. if( geteuid() != 0 ) { // Error: we don't have root privileges. Display(LOG_LEVEL_1, ELError, "tspStartLocal", GOGO_STR_FATAL_NOT_ROOT_FOR_TUN); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } // Check if we're already daemon. Calling multiple times the daemon() messes up pthreads. if( !c->nodaemon && getppid() != 1 ) { // Detach from controlling terminal and run in the background. Display(LOG_LEVEL_3, ELInfo, "tspStartLocal", GOGO_STR_GOING_DAEMON); if( daemon(1, 0) == -1 ) { // Error: Failed to detach. Display(LOG_LEVEL_1, ELError, "tspStartLocal", GOGO_STR_CANT_FORK); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } } // Check tunnel mode. if (strcasecmp(t->type, STR_CONFIG_TUNNELMODE_V6UDPV4) == 0 ) { // When using V6UDPV4 encapsulation, open the TUN device. tunfd = TunInit(c->if_tunnel_v6udpv4); if( tunfd == -1 ) { // Error: Failed to open TUN device. Display(LOG_LEVEL_1, ELError, "tspStartLocal", STR_MISC_FAIL_TUN_INIT); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } // Get the real name of the opened tun device for the template script. free( c->if_tunnel_v6udpv4 ); c->if_tunnel_v6udpv4 = (char*) malloc( IFNAMSIZ ); TunName(tunfd, c->if_tunnel_v6udpv4, IFNAMSIZ ); } while( 1 ) // Dummy loop. 'break' instruction at the end. { // Run the config script in another thread, without giving it our tunnel // descriptor. This is important because otherwise the tunnel will stay // open if we get killed. // pid = fork(); if( pid < 0 ) { // fork() error status = make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); break; } else if (pid == 0) // child { // Child processing: run template script. if( tunfd != -1 ) { close(tunfd); } // Run the interface configuration script. status = tspSetupInterface(c, t); exit(status); } else { // Parent processing int s = 0; // Wait for child process to exit. Display( LOG_LEVEL_3, ELInfo, "tspStartLocal", GOGO_STR_WAITING_FOR_SETUP_SCRIPT ); if( wait(&s) != pid ) { // Error occured: we have no other child Display( LOG_LEVEL_1, ELError, "tspStartLocal", GOGO_STR_ERR_WAITING_SCRIPT ); status = make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED);; break; } // Check if process waited upon has exited. if( !WIFEXITED(s) ) { // Error: child has not exited properly. Maybe killed ? Display( LOG_LEVEL_1, ELError, "tspStartLocal", STR_GEN_SCRIPT_EXEC_FAILED ); status = make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED);; break; } // Check child exit code. status = WEXITSTATUS(s); if( status_number(status) != SUCCESS ) { // Error in script processing. break; } } // Retrieve tunnel lifetime, if found in tunnel parameters. if (t->lifetime != NULL) { lifetime = atoi(t->lifetime); } // Retrieve keepalive inteval, if found in tunnel parameters. if( t->keepalive_interval != NULL ) { ka_interval = atoi(t->keepalive_interval); } // Start the tunnel loop, depending on tunnel mode // if( strcasecmp(t->type, STR_CONFIG_TUNNELMODE_V6UDPV4) == 0 ) { status = TunMainLoop( tunfd, socket, c->keepalive, ka_interval, t->client_address_ipv6, t->keepalive_address ); /* We got out of main loop = keepalive timeout || tunnel error || end */ tspClose(socket, nt); } else if( strcasecmp(t->type, STR_CONFIG_TUNNELMODE_V6V4) == 0 ) { memset( &tun_loop_cfg, 0x00, sizeof(TUNNEL_LOOP_CONFIG) ); tun_loop_cfg.ka_interval = ka_interval; tun_loop_cfg.ka_src_addr = t->client_address_ipv6; tun_loop_cfg.ka_dst_addr = t->keepalive_address; tun_loop_cfg.sa_family = AF_INET6; tun_loop_cfg.tun_lifetime = 0; status = tspPerformTunnelLoop( &tun_loop_cfg ); } else if( strcasecmp(t->type, STR_CONFIG_TUNNELMODE_V4V6) == 0 ) { memset( &tun_loop_cfg, 0x00, sizeof(TUNNEL_LOOP_CONFIG) ); tun_loop_cfg.ka_interval = ka_interval; tun_loop_cfg.ka_src_addr = t->client_address_ipv4; tun_loop_cfg.ka_dst_addr = t->keepalive_address; tun_loop_cfg.sa_family = AF_INET; tun_loop_cfg.tun_lifetime = lifetime; status = tspPerformTunnelLoop( &tun_loop_cfg ); } break; // END of DUMMY loop. } // Cleanup: Close tunnel descriptor, if it was opened. if( tunfd != -1 ) { // The tunnel file descriptor should be closed before attempting to tear // down the tunnel. Destruction of the tunnel interface may fail if // descriptor is not closed. close( tunfd ); } // Cleanup: Handle tunnel teardown. tspTearDownTunnel( c, t ); return status; } gogoc-1_2-RELEASE/gogoc-tsp/platform/freebsd/tsp_tun.c0100644000000000000000000001473611346533642021332 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: tsp_tun.c,v 1.2 2010/03/12 21:52:34 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2006 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ /* FreeBSD */ #include "platform.h" #include "gogoc_status.h" #include #include #include #include #include #include #include "tsp_tun.h" // Local function prototypes. #include "tsp_client.h" // tspCheckForStopOrWait() #include "net_ka.h" // KA function prototypes and types. #include "log.h" // Display and logging prototypes and types. #include "hex_strings.h" // String litterals #include "lib.h" #include "config.h" // tBoolean define #define TUN_BUFSIZE 2048 // Buffer size for TUN interface IO operations. // -------------------------------------------------------------------------- // TunName: Get the name of the tun device using file descriptor. // void TunName(int tunfd, char *name, size_t name_len ) { struct stat sbuf; char *unsafe_buffer; if( fstat( tunfd, &sbuf ) != -1 ) { dev_t dev = sbuf.st_rdev; sysctlbyname("kern.devname", name, &name_len, &dev, sizeof (dev)); } } // -------------------------------------------------------------------------- // TunInit: Open and initialize the TUN interface. // int TunInit( char* dont_care ) { int tunfd; int ifmode = IFF_POINTOPOINT | IFF_MULTICAST; int tundebug = 0; int tunhead = 1; const char* iftun = "/dev/tun"; tunfd = open(iftun,O_RDWR); if (tunfd == -1) { Display(LOG_LEVEL_1, ELError, "TunInit", GOGO_STR_ERR_OPEN_TUN_DEV, iftun); return(-1); } if ((ioctl(tunfd,TUNSDEBUG,&tundebug) == -1) || (ioctl(tunfd,TUNSIFMODE,&ifmode) == -1) || (ioctl(tunfd,TUNSIFHEAD,&tunhead) == -1)) { close(tunfd); Display(LOG_LEVEL_1, ELError, "TunInit", GOGO_STR_ERR_CONFIG_TUN_DEV, iftun); return(-1); } return tunfd; } // -------------------------------------------------------------------------- // TunMainLoop: Initializes Keepalive engine and starts it. Then starts a // loop to transfer data from/to the socket and tunnel. // This process is repeated until tspCheckForStopOrWait indicates a stop. // gogoc_status TunMainLoop(int tunfd, pal_socket_t Socket, tBoolean keepalive, int keepalive_interval, char *local_address_ipv6, char *keepalive_address) { fd_set rfds; int count, maxfd, ret; char bufin[TUN_BUFSIZE] = { 0x00, 0x00, 0x00, 0x1C }; char bufout[TUN_BUFSIZE]; struct timeval timeout; void* p_ka_engine = NULL; ka_status_t ka_status; ka_ret_t ka_ret; gogoc_status status; int ongoing = 1; keepalive = (keepalive_interval != 0) ? TRUE : FALSE; if( keepalive == TRUE ) { // Initialize the keepalive engine. ka_ret = KA_init( &p_ka_engine, keepalive_interval * 1000, local_address_ipv6, keepalive_address, AF_INET6 ); if( ka_ret != KA_SUCCESS ) { return make_status(CTX_TUNNELLOOP, ERR_KEEPALIVE_ERROR); } // Start the keepalive loop(thread). ka_ret = KA_start( p_ka_engine ); if( ka_ret != KA_SUCCESS ) { KA_destroy( &p_ka_engine ); return make_status(CTX_TUNNELLOOP, ERR_KEEPALIVE_ERROR); } } // Data send loop. while( ongoing == 1 ) { // initialize the status. status = STATUS_SUCCESS_INIT; if( tspCheckForStopOrWait( 0 ) != 0 ) { // We've been notified to stop. ongoing = 0; } if( keepalive == TRUE ) { // Check if we're stopping. if( ongoing == 0 ) { // Stop keepalive engine. KA_stop( p_ka_engine ); } // Query the keepalive status. ka_status = KA_qry_status( p_ka_engine ); switch( ka_status ) { case KA_STAT_ONGOING: case KA_STAT_FIN_SUCCESS: break; case KA_STAT_FIN_TIMEOUT: KA_stop( p_ka_engine ); status = make_status(CTX_TUNNELLOOP, ERR_KEEPALIVE_TIMEOUT); break; case KA_STAT_INVALID: case KA_STAT_FIN_ERROR: default: KA_stop( p_ka_engine ); status = make_status(CTX_TUNNELLOOP, ERR_KEEPALIVE_ERROR); break; } // Reinit select timeout variable; select modifies it. // Use 500ms because we need to re-check keepalive status. timeout.tv_sec = 0; timeout.tv_usec = 500000; // 500 milliseconds. } else { // Reinit select timeout variable; select modifies it. timeout.tv_sec = 7 * 24 * 60 * 60 ; // one week timeout.tv_usec = 0; } // Check if we're normal. if( status_number(status) != SUCCESS || ongoing != 1 ) { goto done; } FD_ZERO(&rfds); FD_SET(tunfd,&rfds); FD_SET(Socket,&rfds); maxfd = tunfd>Socket?tunfd:Socket; // Wait until data is sent or received. - OR - A signal has been caught. ret = select( maxfd+1, &rfds, 0, 0, &timeout ); if (ret > 0) { if( FD_ISSET(tunfd, &rfds) ) { // Data sent through UDP tunnel. ioctl(tunfd, FIONREAD, &count); if (count > sizeof(bufout)) { Display(LOG_LEVEL_1, ELError, "TunMainLoop", STR_NET_FAIL_TUN_DEV_BUFSMALL); status = make_status(CTX_TUNNELLOOP, ERR_TUNNEL_IO); goto done; } if (read(tunfd, bufout, count) != count) { Display(LOG_LEVEL_1, ELError, "TunMainLoop", STR_NET_FAIL_R_TUN_DEV); status = make_status(CTX_TUNNELLOOP, ERR_TUNNEL_IO); goto done; } if (send(Socket, bufout+4, count-4, 0) != count-4) { Display(LOG_LEVEL_1, ELError, "TunMainLoop", STR_NET_FAIL_W_SOCKET); status = make_status(CTX_TUNNELLOOP, ERR_TUNNEL_IO); goto done; } } if(FD_ISSET(Socket,&rfds)) { // Data received through UDP tunnel. count=recvfrom(Socket,bufin+4,TUN_BUFSIZE - 4,0,NULL,NULL); if (write(tunfd, bufin, count + 4) != count + 4) { Display(LOG_LEVEL_1, ELError, "TunMainLoop", STR_NET_FAIL_W_TUN_DEV); status = make_status(CTX_TUNNELLOOP, ERR_TUNNEL_IO); goto done; } } } } /* Normal loop end */ status = STATUS_SUCCESS_INIT; done: if( keepalive == TRUE ) { KA_destroy( &p_ka_engine ); } return status; } gogoc-1_2-RELEASE/gogoc-tsp/platform/freebsd/tsp_tun.h0100644000000000000000000000157211301544603021317 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: tsp_tun.h,v 1.1 2009/11/20 16:53:23 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2005 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ #ifndef TUN_H #define TUN_H #include "config.h" // tBoolean void TunName ( int tunfd, char* name, size_t name_len ); int TunInit (char *dont_care); gogoc_status TunMainLoop (int tun, int Socket, tBoolean keepalive, int keepalive_interval, char *local_address_ipv6, char *keepalive_address); #endif /* TUN_H */ gogoc-1_2-RELEASE/gogoc-tsp/platform/gogocpe/0040755000000000000000000000000011346561543017474 5ustar rootrootgogoc-1_2-RELEASE/gogoc-tsp/platform/gogocpe/Makefile0100644000000000000000000000307311345000334021115 0ustar rootroot# ########################################################################### # $Id: Makefile,v 1.1 2010/03/07 19:39:08 carl Exp $ # # This source code copyright (c) gogo6 Inc. 2002-2007. # # LICENSE NOTICE: You may use and modify this source code only if you # have executed a valid license agreement with gogo6 Inc. granting # you the right to do so, the said license agreement governing such # use and modifications. Copyright or other intellectual property # notices are not to be removed from the source code. # # ########################################################################### # # NOTE: This makefile MUST be interpreted by GNU make. # Include the platform makefile, if it exists. -include platform.mak ifdef DEBUG CFLAGS=-g -Wall $(CC_INC_PATHS) $(PLATFORM_CFLAGS) -D_REENTRANT -DDEBUG LDFLAGS=-g $(LD_LIB_PATHS) $(LD_LIBRARIES) $(EXTRA_LDFLAGS) else CFLAGS=-O2 -Wall $(CC_INC_PATHS) $(PLATFORM_CFLAGS) -D_REENTRANT LDFLAGS=$(LD_LIB_PATHS) $(LD_LIBRARIES) $(EXTRA_LDFLAGS) endif OBJS=$(OBJS_DIR)/tsp_local.o \ $(OBJS_DIR)/tsp_tun.o \ $(OBJS_DIR)/haccess-platform.o all: $(TARGET) install: all $(OBJS_DIR)/tsp_local.o:tsp_local.c $(CC) $(CFLAGS) -c tsp_local.c -o $(OBJS_DIR)/tsp_local.o $(OBJS_DIR)/tsp_tun.o:tsp_tun.c $(CC) $(CFLAGS) -c tsp_tun.c -o $(OBJS_DIR)/tsp_tun.o $(OBJS_DIR)/haccess-platform.o:haccess-platform.c $(CC) $(CFLAGS) -c haccess-platform.c -o $(OBJS_DIR)/haccess-platform.o $(TARGET): $(OBJS) $(CC) -o $(TARGET) $(wildcard $(OBJS_DIR)/*.o) $(LDFLAGS) ifdef DEBUG cp $(TARGET) $(TARGET).debug endif clean: rm -f $(OBJS) $(TARGET) gogoc-1_2-RELEASE/gogoc-tsp/platform/gogocpe/haccess-platform.c0100644000000000000000000003155211345000334023057 0ustar rootroot/* ---------------------------------------------------------------------- haccess.c - HACCESS Module -- Dongle6/Linux Specific ---------------------------------------------------------------------- $Id: haccess-platform.c,v 1.1 2010/03/07 19:39:08 carl Exp $ ---------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. LICENSE NOTICE: You may use and modify this source code only if you have executed a valid license agreement with gogo6 Inc. granting you the right to do so, the said license agreement governing such use and modifications. Copyright or other intellectual property notices are not to be removed from the source code. ---------------------------------------------------------------------- */ #include "platform.h" #include "gogoc_status.h" #include "hex_strings.h" #include "haccess-private.h" /* ================================================ ================================================ PRIVATE VARIABLES ================================================ ================================================ */ /* A condition variable that can be waited on and */ /* that will be signaled by the DDNS request */ /* processing thread when the processing of the */ /* DDNS deletion requests that are generated when */ /* the devices are hidden at client shutdown has */ /* completed. */ pthread_cond_t _haccess_ddns_device_hiding_done_event; /* A flag indicating that DDNS device hiding is done. */ /* It is enabled when we receive a signal that */ /* the DDNS request processing queue is empty while */ /* in the device hiding state. */ /* It is used as part of the boolean predicate checked */ /* to protect from spurious exits of the pthread_cond_timedwait */ /* function. A simple check of whether or not the DDNS */ /* request processing queue is empty is not a sufficient */ /* predicate as the spurious exit might occur in the */ /* timeframe during which the last DDNS request has been popped */ /* from the queue - making it empty - but not yet processed. */ /* Adding this flag to the check ensures that the queue is */ /* empty AND that the last request has been processed */ /* because the signal is sent only after the last */ /* request has been fully processed. */ _haccess_boolean _haccess_ddns_device_hiding_done; /* The mutex associated with the above condition */ /* variable. */ pthread_mutex_t _haccess_ddns_device_hiding_done_mutex; /* A flag indicating whether the client is in */ /* the device hiding state. In other words, */ /* it will be true if the client is shutting down */ /* and generating DDNS deletion requests. This is */ /* used to make sure that signals indicating */ /* that the DDNS request queue is empty are */ /* otherwise ignored. */ _haccess_boolean _haccess_ddns_device_hiding_active; /* The mutex used to protect the shared variable. */ pthread_mutex_t _haccess_ddns_device_hiding_active_mutex; /* The saved handle to the DDNS processing thread. */ pthread_t _haccess_ddns_processing_thread_handle; /* ================================================ ================================================ PRIVATE FUNCTION IMPLEMENTATIONS ================================================ ================================================ */ /* ================================================ FUNCTION _haccess_platform_ddns_processing_thread DESCRIPTION The function that is executed by the DDNS processing thread. ARGUMENTS void *arguments The thread arguments (actually a tTunnel *). RETURN VALUE Just conforming to the pthread API. NOTES TODO ================================================ */ void * _haccess_platform_ddns_processing_thread(void *arguments) { haccess_status status = HACCESS_STATUS_OK; /* Iterate until the HACCESS module signals that */ /* it is destructing. */ while (!_haccess_platform_module_is_destructing()) { /* Call the thread function from the HACCESS module */ /* that will do the real thread work. */ status = _haccess_ddns_processing_thread(arguments); if (status != HACCESS_STATUS_OK) { _HACCESS_LOG_ERROR(HACCESS_LOG_PREFIX_ERROR GOGO_STR_HACCESS_ERR_PROCESSING_DDNS_REQS) } /* Sleep until the next iteration. */ errno = 0; if (sleep(_HACCESS_DDNS_PROCESSING_THREAD_DELAY) || errno == EINTR) break; } pthread_exit(PTHREAD_CANCELED); return (void *)NULL; } /* ================================================ FUNCTION _haccess_platform_start_ddns_processing_thread DESCRIPTION Platform-specific function to start the DDNS processing thread. ARGUMENTS void *arguments The thread arguments (actually a tTunnel *). RETURN VALUE haccess_status Function execution status. NOTES TODO ================================================ */ haccess_status _haccess_platform_start_ddns_processing_thread(void *arguments) { haccess_status status = HACCESS_STATUS_OK; _HACCESS_ENTER_FUNCTION /* Start the thread, and save the handle to be able to use it later on. */ if (pthread_create(&_haccess_ddns_processing_thread_handle, NULL, &_haccess_platform_ddns_processing_thread, (void *)arguments) != 0) { /* The thread failed to start, that's an error. */ _HACCESS_LOG_DEBUG(HACCESS_LOG_PREFIX_ERROR GOGO_STR_HACCESS_ERR_CANT_START_PLATFORM_THREAD) status = HACCESS_STATUS_ERR; _HACCESS_LEAVE_FUNCTION(status) } pthread_detach(_haccess_ddns_processing_thread_handle); _HACCESS_LEAVE_FUNCTION(status) } /* ======================================================= FUNCTION _haccess_platform_signal_ddns_request_queue_empty DESCRIPTION Platform-specific function called to indicate that the DDNS request processing queue is empty. It will be called multiple times. ARGUMENTS None. RETURN VALUE haccess_status Function execution status. NOTES TODO ================================================ */ haccess_status _haccess_platform_signal_ddns_request_queue_empty() { _haccess_boolean ready_for_signal = _HACCESS_FALSE; haccess_status status = HACCESS_STATUS_OK; _HACCESS_ENTER_FUNCTION pthread_mutex_lock(&_haccess_ddns_device_hiding_active_mutex); ready_for_signal = _haccess_ddns_device_hiding_active; pthread_mutex_unlock(&_haccess_ddns_device_hiding_active_mutex); if (ready_for_signal == _HACCESS_TRUE) { pthread_mutex_lock(&_haccess_ddns_device_hiding_done_mutex); _haccess_ddns_device_hiding_done = _HACCESS_TRUE; if (pthread_cond_signal(&_haccess_ddns_device_hiding_done_event) != 0) { _HACCESS_LOG_DEBUG(HACCESS_LOG_PREFIX_ERROR GOGO_STR_HACCESS_ERR_CANT_SIGNAL_HIDING_EVENT) status = HACCESS_STATUS_ERR; } pthread_mutex_unlock(&_haccess_ddns_device_hiding_done_mutex); pthread_mutex_lock(&_haccess_ddns_device_hiding_active_mutex); _haccess_ddns_device_hiding_active = _HACCESS_FALSE; pthread_mutex_unlock(&_haccess_ddns_device_hiding_active_mutex); } _HACCESS_LEAVE_FUNCTION(status) } /* ======================================================= FUNCTION _haccess_platform_wait_ddns_hiding_done DESCRIPTION Platform-specific function called to wait until the DDNS request processing thread has finished processing the deletion requests or a timeout expires. ARGUMENTS int hiding_done_timeout The maximum number of seconds to wait if we aren't otherwise notified. RETURN VALUE haccess_status Function execution status. NOTES TODO ================================================ */ haccess_status _haccess_platform_wait_ddns_hiding_done(int hiding_done_timeout) { struct timespec timeout; _haccess_platform_event_wait_state state = _HACCESS_PLATFORM_HIDING_WAIT_LOOP; haccess_status status = HACCESS_STATUS_OK; _HACCESS_ENTER_FUNCTION pthread_mutex_lock(&_haccess_ddns_device_hiding_active_mutex); _haccess_ddns_device_hiding_active = _HACCESS_TRUE; pthread_mutex_unlock(&_haccess_ddns_device_hiding_active_mutex); clock_gettime(CLOCK_REALTIME, &timeout); timeout.tv_sec += hiding_done_timeout; while (state == _HACCESS_PLATFORM_HIDING_WAIT_LOOP) { pthread_mutex_lock(&_haccess_ddns_device_hiding_done_mutex); switch (pthread_cond_timedwait(&_haccess_ddns_device_hiding_done_event, &_haccess_ddns_device_hiding_done_mutex, &timeout)) { case 0: if (_haccess_ddns_device_hiding_done == _HACCESS_TRUE) { state = _HACCESS_PLATFORM_HIDING_WAIT_PROCEED; } break; case ETIMEDOUT: if (_haccess_ddns_device_hiding_done == _HACCESS_TRUE) { state = _HACCESS_PLATFORM_HIDING_WAIT_PROCEED; } else { state = _HACCESS_PLATFORM_HIDING_WAIT_TIMEOUT; } break; default: state = _HACCESS_PLATFORM_HIDING_WAIT_ERROR; break; } pthread_mutex_unlock(&_haccess_ddns_device_hiding_done_mutex); } if (state == _HACCESS_PLATFORM_HIDING_WAIT_TIMEOUT) { _HACCESS_LOG_ERROR(HACCESS_LOG_PREFIX_ERROR GOGO_STR_HACCESS_ERR_HIDING_TIMEOUT) } else if (state == _HACCESS_PLATFORM_HIDING_WAIT_ERROR) { _HACCESS_LOG_DEBUG(HACCESS_LOG_PREFIX_ERROR GOGO_STR_HACCESS_ERR_CANT_WAIT_HIDING_EVENT) } _HACCESS_LEAVE_FUNCTION(status) } /* ================================================ FUNCTION _haccess_platform_module_is_destructing DESCRIPTION The function called by the DDNS processing thread to see if it should stop iterating because the HACCESS module is destructing. ARGUMENTS None. RETURN VALUE int Whether or not the module is destructing. NOTES TODO Process possible errors! ================================================ */ int _haccess_platform_module_is_destructing() { int destructing = 0; /* Always return as if destruction is NOT occuring */ /* to make sure the DDNS request processing thread */ /* doesn't stop which, with uClibc's pthread implementation */ /* would kill the main thread. */ return destructing; } /* ================================================ FUNCTION _haccess_platform_set_module_destructing DESCRIPTION The function used by the HACCESS module to indicate that it is destructing. ARGUMENTS int thread_wait_delay The number of milliseconds to wait for the DDNS processing thread to terminate after destruction has been signaled. RETURN VALUE haccess_status Function execution status. NOTES TODO ================================================ */ haccess_status _haccess_platform_set_module_destructing(int thread_wait_delay) { haccess_status status = HACCESS_STATUS_OK; _HACCESS_ENTER_FUNCTION /* Not stopping the DDNS request processing thread here */ /* as it seems that, with uClbic's pthread implementation, */ /* it would also stop and kill the parent thread. */ _HACCESS_LEAVE_FUNCTION(status) } /* ================================================ FUNCTION _haccess_platform_initialize DESCRIPTION Platform-specific initialization function. ARGUMENTS None. RETURN VALUE haccess_status Function execution status. NOTES TODO ================================================ */ haccess_status _haccess_platform_initialize() { haccess_status status = HACCESS_STATUS_OK; _HACCESS_ENTER_FUNCTION /* Initialize general global variables. */ _haccess_ddns_device_hiding_done = _HACCESS_FALSE; _haccess_ddns_device_hiding_active = _HACCESS_FALSE; /* Initialize the condition variables. */ if (pthread_cond_init(&_haccess_ddns_device_hiding_done_event, NULL) != 0) { status = HACCESS_STATUS_ERR; } /* Initialize the mutexes. */ else if (pthread_mutex_init(&_haccess_ddns_device_hiding_done_mutex, NULL) != 0) { status = HACCESS_STATUS_ERR; } else if (pthread_mutex_init(&_haccess_ddns_device_hiding_active_mutex, NULL) != 0) { status = HACCESS_STATUS_ERR; } _HACCESS_LEAVE_FUNCTION(status) } /* ================================================ FUNCTION _haccess_platform_destruct DESCRIPTION Platform-specific destruction function. ARGUMENTS None. RETURN VALUE haccess_status Function execution status. NOTES TODO ================================================ */ haccess_status _haccess_platform_destruct() { int cancel_status = 0; haccess_status status = HACCESS_STATUS_OK; _HACCESS_ENTER_FUNCTION /* Cancel the DDNS request processing thread. */ cancel_status = pthread_cancel(_haccess_ddns_processing_thread_handle); if ((cancel_status != 0) && (cancel_status != ESRCH)) { status = HACCESS_STATUS_ERR; } /* Destroy the mutexes. */ if (pthread_mutex_destroy(&_haccess_ddns_device_hiding_active_mutex) != 0) { status = HACCESS_STATUS_ERR; } else if (pthread_mutex_destroy(&_haccess_ddns_device_hiding_done_mutex) != 0) { status = HACCESS_STATUS_ERR; } /* Destroy the condition variables. */ else if (pthread_cond_destroy(&_haccess_ddns_device_hiding_done_event) != 0) { status = HACCESS_STATUS_ERR; } _HACCESS_LEAVE_FUNCTION(status) } gogoc-1_2-RELEASE/gogoc-tsp/platform/gogocpe/haccess-platform.h0100644000000000000000000000776611345000335023077 0ustar rootroot/* ---------------------------------------------------------------------- haccess-platform.h - HACCESS Module Private Platform Definitions ---------------------------------------------------------------------- $Id: haccess-platform.h,v 1.1 2010/03/07 19:39:09 carl Exp $ ---------------------------------------------------------------------- Copyright (c) 2007 gogo6 Inc. All rights reserved. LICENSE NOTICE: You may use and modify this source code only if you have executed a valid license agreement with gogo6 Inc. granting you the right to do so, the said license agreement governing such use and modifications. Copyright or other intellectual property notices are not to be removed from the source code. ---------------------------------------------------------------------- */ #ifndef _HACCESS_PLATFORM_H_ #define _HACCESS_PLATFORM_H_ /* ================================================ ================================================ EXTERNAL SYMBOLS ================================================ ================================================ */ /* ================================================ ================================================ PRIVATE CONSTANTS ================================================ ================================================ */ /* External script locations. */ #define _HACCESS_SCRIPT_LOCATION_SETUP "/usr/lib/gogoc/haccess/setup/haccess-setup.sh" #define _HACCESS_SCRIPT_LOCATION_TEARDOWN "/usr/lib/gogoc/haccess/teardown/haccess-teardown.sh" #define _HACCESS_SCRIPT_LOCATION_PROXY "/usr/lib/gogoc/haccess/polipo/generators/haccess-polipo-http-proxy-conf.sh" #define _HACCESS_SCRIPT_LOCATION_SERVICE_CONTROL "/usr/lib/gogoc/haccess/polipo/control/haccess-polipo-service-control.sh" /* The name of the device mapping configuration file. */ #define _HACCESS_DEVICE_MAPPING_FILE "/var/etc/haccess-device-mapping.conf" /* The name of the prepared device mapping configuration file. */ /* This is a version of the file that includes only IPv4 addresses, and */ /* that is used to generate the HTTP proxy configuration. */ #define _HACCESS_PREPARED_DEVICE_MAPPING_FILE _HACCESS_DEVICE_MAPPING_FILE ".prepared" /* ================================================ ================================================ PRIVATE MACROS ================================================ ================================================ */ /* ================================================ ================================================ PRIVATE TYPES ================================================ ================================================ */ /* Possible states for the DDNS hiding done */ /* waiting loop. */ typedef enum { _HACCESS_PLATFORM_HIDING_WAIT_LOOP, _HACCESS_PLATFORM_HIDING_WAIT_PROCEED, _HACCESS_PLATFORM_HIDING_WAIT_TIMEOUT, _HACCESS_PLATFORM_HIDING_WAIT_ERROR } _haccess_platform_event_wait_state; /* ================================================ ================================================ PRIVATE VARIABLES ================================================ ================================================ */ /* ================================================ ================================================ PRIVATE FUNCTION DECLARATIONS ================================================ ================================================ */ void * _haccess_platform_ddns_processing_thread(void *arguments); haccess_status _haccess_platform_start_ddns_processing_thread(void *arguments); haccess_status _haccess_platform_signal_ddns_request_queue_empty(); haccess_status _haccess_platform_wait_ddns_hiding_done(int hiding_done_timeout); int _haccess_platform_module_is_destructing(); haccess_status _haccess_platform_set_module_destructing(int thread_wait_delay); haccess_status _haccess_platform_initialize(); haccess_status _haccess_platform_destruct(); #endif gogoc-1_2-RELEASE/gogoc-tsp/platform/gogocpe/platform.h0100644000000000000000000000156511345000335021457 0ustar rootroot/* --------------------------------------------------------------------------- $Id: platform.h,v 1.1 2010/03/07 19:39:09 carl Exp $ --------------------------------------------------------------------------- This source code copyright (c) gogo6 Inc. 2002-2007. LICENSE NOTICE: You may use and modify this source code only if you have executed a valid license agreement with gogo6 Inc. granting you the right to do so, the said license agreement governing such use and modifications. Copyright or other intellectual property notices are not to be removed from the source code. --------------------------------------------------------------------------- */ #ifndef _PLATFORM_H_ #define _PLATFORM_H_ /* Dongle6 */ #include "pal.h" #define SCRIPT_TMP_FILE "/tmp/gogoc-tmp.log" #define CLIENT_VERSION_INDEX_OLDEST CLIENT_VERSION_INDEX_2_0_2 #endif gogoc-1_2-RELEASE/gogoc-tsp/platform/gogocpe/platform.mak0100644000000000000000000000155511345000335021777 0ustar rootroot# ########################################################################### # # $Id: platform.mak,v 1.1 2010/03/07 19:39:09 carl Exp $ # # Copyright (c) 2007 gogo6 Inc. All rights reserved. # # LICENSE NOTICE: You may use and modify this source code only if you # have executed a valid license agreement with gogo6 Inc. granting # you the right to do so, the said license agreement governing such # use and modifications. Copyright or other intellectual property # notices are not to be removed from the source code. # # This file contains platform-specific makefile rules and symbols. # # ########################################################################### # # Additional platform CFLAGS. # PLATFORM_CFLAGS=$(HACCESS_DEFINES) $(EXTRA_CFLAGS) # Platform default interface names for each tunnel mode. # PLATFORM_V6V4=sit1 PLATFORM_V6UDPV4=tun PLATFORM_V4V6= gogoc-1_2-RELEASE/gogoc-tsp/platform/gogocpe/tsp_local.c0100644000000000000000000002711111345000335021601 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: tsp_local.c,v 1.1 2010/03/07 19:39:09 carl Exp $ ----------------------------------------------------------------------------- This source code copyright (c) gogo6 Inc. 2002-2007. LICENSE NOTICE: You may use and modify this source code only if you have executed a valid license agreement with gogo6 Inc. granting you the right to do so, the said license agreement governing such use and modifications. Copyright or other intellectual property notices are not to be removed from the source code. ----------------------------------------------------------------------------- */ /* LINUX */ #include #include #include #include "platform.h" #include "gogoc_status.h" #include "config.h" /* tConf */ #include "xml_tun.h" /* tTunnel */ #include "net.h" /* net_tools_t */ #include "tsp_net.h" /* tspClose */ #include "log.h" // Display #include "hex_strings.h" // Various string constants #include "tsp_tun.h" // linux tun support #include "tsp_client.h" // tspSetupInterfaceLocal() #include "tsp_setup.h" // tspSetupInterface() #include "tsp_tun_mgt.h" // tspPerformTunnelLoop() #include #ifdef HACCESS #include "haccess.h" #endif #define OPENWRT_MESSAGE_FILE "/tmp/gogoc-status.log" /* these globals are defined by US used by alot of things in */ char *FileName = "gogoc.conf"; char *ScriptInterpretor = "/bin/sh"; char *ScriptExtension = "sh"; char *ScriptDir = NULL; char *TspHomeDir = "/usr/local/etc/gogoc"; char DirSeparator = '/'; int indSigHUP = 0; // Set to 1 when HUP signal is trapped. // implementation for the openwrt platform // // Update a text file // for the GUI to show // static void openwrt_update_status_info() { FILE *f_config; // Open the status file for // total overwrite and destruction // f_config = fopen(OPENWRT_MESSAGE_FILE, "w"); if (f_config == NULL) return; switch (gStatusInfo.eStatus) { case GOGOC_CLISTAT__DISCONNECTEDIDLE: fprintf(f_config, "The tunnel service is disconnected, but idle.\n"); break; case GOGOC_CLISTAT__DISCONNECTEDERROR: fprintf(f_config, "The tunnel service is disconnected for the following reason: %s.\n", get_mui_string(gStatusInfo.nStatus)); break; case GOGOC_CLISTAT__CONNECTING: fprintf(f_config, "The tunnel service is connecting...\n"); break; case GOGOC_CLISTAT__CONNECTED: fprintf(f_config, "The tunnel service is connected; the routing prefix is %s.\n", gTunnelInfo.szDelegatedPrefix); break; } fclose(f_config); return; } error_t send_status_info( void ) { openwrt_update_status_info(); return GOGOCM_UIS__NOERROR; } error_t send_tunnel_info( void ) { openwrt_update_status_info(); return GOGOCM_UIS__NOERROR; } error_t send_broker_list( void ) { openwrt_update_status_info(); return GOGOCM_UIS__NOERROR; } error_t send_haccess_status_info( void ) { return GOGOCM_UIS__NOERROR; } // -------------------------------------------------------------------------- /* Verify for ipv6 support */ // gogoc_status tspTestIPv6Support() { struct stat buf; if(stat("/proc/net/if_inet6",&buf) == -1) { Display(LOG_LEVEL_1,ELError,"tspTestIPv6Support",GOGO_STR_NO_IPV6_SUPPORT_FOUND); Display(LOG_LEVEL_1,ELError,"tspTestIPv6Support",GOGO_STR_TRY_MODPROBE_IPV6); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } Display(LOG_LEVEL_2,ELInfo,"tspTestIPv6Support",GOGO_STR_IPV6_SUPPORT_FOUND); return STATUS_SUCCESS_INIT; } // -------------------------------------------------------------------------- // linux specific to setup an env variable // void tspSetEnv(char *Variable, char *Value, int Flag) { setenv( Variable, Value, Flag ); Display( LOG_LEVEL_3, ELInfo, "tspSetEnv", "%s=%s", Variable, Value ); } // -------------------------------------------------------------------------- // Checks if the gogoCLIENT has been requested to stop and exit. // // Returns 1 if gogoCLIENT is being requested to stop and exit. // Else, waits 'uiWaitMs' miliseconds and returns 0. // // Defined in tsp_client.h // int tspCheckForStopOrWait( const unsigned int uiWaitMs ) { // Sleep for the amount of time specified, if signal has not been sent. if( indSigHUP == 0 ) { // usleep is expecting microseconds (1 microsecond = 0.000001 second). usleep( uiWaitMs * 1000 ); } return indSigHUP; } // -------------------------------------------------------------------------- // Called from tsp_setup.c -> tspSetupInterface // Do extra platform-specific stuff before tunnel script is launched. // int tspSetupInterfaceLocal( tConf* pConf, tTunnel* pTun ) { return 0; } // -------------------------------------------------------------------------- // Returns local address. // tspSetupTunnel() will callback here // char* tspGetLocalAddress(int socket, char *buffer, int size) { struct sockaddr_in6 addr; /* enough place for v4 and v6 */ struct sockaddr_in *addr_v4 = (struct sockaddr_in *)&addr; struct sockaddr_in6 *addr_v6 = (struct sockaddr_in6 *)&addr; socklen_t len; len = sizeof addr; if (getsockname(socket, (struct sockaddr *)&addr, &len) < 0) { Display(LOG_LEVEL_1, ELError, "TryServer", GOGO_STR_ERR_FIND_SRC_IP); return NULL; } if (addr.sin6_family == AF_INET6) return (char *)inet_ntop(AF_INET6, (const void*) &addr_v6->sin6_addr, buffer, size); else return (char *)inet_ntop(AF_INET, (const void*) &addr_v4->sin_addr, buffer, size); } // -------------------------------------------------------------------------- // Setup tunneling interface and any daemons // tspSetupTunnel() will callback here. // #ifdef DSLITE_SUPPORT #error DSLITE support not implemented on platform #endif gogoc_status tspStartLocal(int socket, tConf *c, tTunnel *t, net_tools_t *nt) { TUNNEL_LOOP_CONFIG tun_loop_cfg; gogoc_status status = STATUS_SUCCESS_INIT; int ka_interval = 0; int tunfd = (-1); sint32_t redirect = 0; #ifdef HACCESS int do_haccess_teardown = 0; int do_haccess_hide_devices = 0; haccess_status action_status = HACCESS_STATUS_OK; #endif // Check if we got root privileges. if(geteuid() != 0) { // Error: we don't have root privileges. Display( LOG_LEVEL_1, ELError, "tspStartLocal", GOGO_STR_FATAL_NOT_ROOT_FOR_TUN ); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } // Check Ipv6 support. Display( LOG_LEVEL_2, ELInfo, "tspStartLocal", GOGO_STR_CHECKING_LINUX_IPV6_SUPPORT ); status = tspTestIPv6Support(); if( status_number(status) != SUCCESS ) { // Error: It seems the user does not have IPv6 support in kernel. return status; } // Don't call daemon() for the Dongle6. // It implies a fork, and the uClibC pthread implementation // has a problem with pthread_create() calls after a fork. #if 0 // Detach from controlling terminal and run in the background. Display( LOG_LEVEL_3, ELInfo, "tspStartLocal", GOGO_STR_GOING_DAEMON ); if( daemon(1,0) == -1 ) { // Error: Failed to detach. Display( LOG_LEVEL_1, ELError, "tspStartLocal", GOGO_STR_CANT_FORK ); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } #endif // Check tunnel mode. if( strcasecmp(t->type, STR_CONFIG_TUNNELMODE_V4V6) == 0 ) { // V4V6 tunnel mode is not supported on this platform. Display( LOG_LEVEL_1, ELError, "tspStartLocal", GOGO_STR_NO_V4V6_ON_PLATFORM ); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } else if( strcasecmp(t->type, STR_CONFIG_TUNNELMODE_V6UDPV4) == 0 ) { // When using V6UDPV4 encapsulation, open the TUN device. tunfd = TunInit(c->if_tunnel_v6udpv4); if( tunfd == -1 ) { // Error: Failed to open TUN device. Display( LOG_LEVEL_1, ELError, "tspStartLocal", STR_MISC_FAIL_TUN_INIT ); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } status = TunRedirect(tunfd, socket, nt, &redirect); if( status_number(status) != SUCCESS ) { goto done; } } // now, run the template script // status = tspSetupInterface(c, t); if( status_number(status) != SUCCESS ) { goto done; } gStatusInfo.eStatus = GOGOC_CLISTAT__CONNECTED; gStatusInfo.nStatus = GOGOCM_UIS__NOERROR; send_status_info(); #ifdef HACCESS /* If both HACCESS features are disabled, we just skip this. */ if ((c->haccess_web_enabled == TRUE) || (c->haccess_proxy_enabled == TRUE)) { /* Execute the setup action after the template script has run the system is setup. */ action_status = haccess_exec_action(HACCESS_ACTION_SETUP, c, t); do_haccess_teardown = 1; if (action_status != HACCESS_STATUS_OK) { /* Could not setup HACCESS, so all features fail. */ haccess_messaging_set_status_web(HACCESS_FEATSTTS_ERROR); haccess_messaging_set_status_proxy(HACCESS_FEATSTTS_ERROR); send_haccess_status_info(); status = make_status(CTX_TUNINTERFACESETUP, ERR_HACCESS_SETUP); goto teardown; } /* HACCESS setup ok, features up successfully. */ haccess_messaging_set_status_web(HACCESS_FEATSTTS_SUCCESS); haccess_messaging_set_status_proxy(HACCESS_FEATSTTS_SUCCESS); send_haccess_status_info(); if (c->haccess_proxy_enabled == TRUE) { /* If proxying is enabled, also expose the devices (proxy and DDNS). */ action_status = haccess_exec_action(HACCESS_ACTION_EXPOSE_DEVICES, c, t); do_haccess_hide_devices = 1; if (action_status != HACCESS_STATUS_OK) { /* Proxy feature failed. */ haccess_messaging_set_status_proxy(HACCESS_FEATSTTS_ERROR); send_haccess_status_info(); status = make_status(CTX_TUNINTERFACESETUP, ERR_HACCESS_EXPOSE_DEVICES); goto teardown; } } } #endif // Retrieve keepalive inteval, if found in tunnel parameters. if( t->keepalive_interval != NULL ) { ka_interval = atoi(t->keepalive_interval); } // Start the tunnel loop, depending on tunnel mode // if( strcasecmp(t->type, STR_CONFIG_TUNNELMODE_V6UDPV4) == 0 ) { status = TunMainLoop( tunfd, socket, redirect, c->keepalive, ka_interval, t->client_address_ipv6, t->keepalive_address); } else if( strcasecmp(t->type, STR_CONFIG_TUNNELMODE_V6V4) == 0 ) { memset( &tun_loop_cfg, 0x00, sizeof(TUNNEL_LOOP_CONFIG) ); tun_loop_cfg.ka_interval = ka_interval; tun_loop_cfg.ka_src_addr = t->client_address_ipv6; tun_loop_cfg.ka_dst_addr = t->keepalive_address; tun_loop_cfg.sa_family = AF_INET6; tun_loop_cfg.tun_lifetime = 0; status = tspPerformTunnelLoop( &tun_loop_cfg ); } teardown: #ifdef HACCESS if (do_haccess_hide_devices) { /* We need to send DDNS deletion requests to remove */ /* the devices from the DNS servers. */ action_status = haccess_exec_action(HACCESS_ACTION_HIDE_DEVICES, c, t); if (action_status != HACCESS_STATUS_OK) { Display(LOG_LEVEL_1, ELError, "tspStartLocal", HACCESS_LOG_PREFIX_ERROR GOGO_STR_HACCESS_ERR_CANT_DO_HIDE_DEVICES); } } if (do_haccess_teardown) { /* The teardown action must be executed when we disconnect */ /* to clean up what the setup action did. */ action_status = haccess_exec_action(HACCESS_ACTION_TEARDOWN, c, t); if (action_status != HACCESS_STATUS_OK) { Display(LOG_LEVEL_1, ELError, "tspStartLocal", HACCESS_LOG_PREFIX_ERROR GOGO_STR_HACCESS_ERR_CANT_DO_TEARDOWN); } } #endif // Cleanup: Handle tunnel teardown. tspTearDownTunnel( c, t ); done: if (tunfd >= 0) { close(tunfd); } return status; } gogoc-1_2-RELEASE/gogoc-tsp/platform/gogocpe/tsp_tun.c0100644000000000000000000002445411345000335021324 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: tsp_tun.c,v 1.1 2010/03/07 19:39:09 carl Exp $ ----------------------------------------------------------------------------- This source code copyright (c) gogo6 Inc. 2002-2006. LICENSE NOTICE: You may use and modify this source code only if you have executed a valid license agreement with gogo6 Inc. granting you the right to do so, the said license agreement governing such use and modifications. Copyright or other intellectual property notices are not to be removed from the source code. ----------------------------------------------------------------------------- */ /* OpenWRT */ #include #include #include #include #include "platform.h" #include "gogoc_status.h" #include #include #include #include "tsp_tun.h" // Local function prototypes. #include "tsp_client.h" // tspCheckForStopOrWait() #include "net_ka.h" // KA function prototypes and types. #include "log.h" // Display and logging prototypes and types. #include "hex_strings.h" // String litterals #define TUN_BUFSIZE 2048 // Buffer size for TUN interface IO operations. // -------------------------------------------------------------------------- // TunInit: Open and initialize the TUN interface. // sint32_t TunInit(char *TunDevice) { sint32_t tunfd; struct ifreq ifr; char iftun[128]; unsigned long ioctl_nochecksum = 1; /* for linux, force the use of "tun" */ strcpy(iftun,"/dev/net/tun"); tunfd = open(iftun,O_RDWR); if (tunfd == -1) { Display(LOG_LEVEL_1, ELError, "TunInit", GOGO_STR_ERR_OPEN_DEV, iftun); Display(LOG_LEVEL_1, ELError, "TunInit", GOGO_STR_TRY_MODPROBE_TUN); return (-1); } memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TUN; strncpy(ifr.ifr_name, TunDevice, IFNAMSIZ); /* Enable debugging on tunnel device */ /* Display(LOG_LEVEL_1, ELError, "TunInit" , "Enable tun device debugging"); if(ioctl(tunfd, TUNSETDEBUG, (void *) &ioctl_nochecksum) == -1) { Display(LOG_LEVEL_1, ELError,"TunInit","ioctl failed"); }*/ if((ioctl(tunfd, TUNSETIFF, (void *) &ifr) == -1) || (ioctl(tunfd, TUNSETNOCSUM, (void *) ioctl_nochecksum) == -1)) { Display(LOG_LEVEL_1, ELError, "TunInit", GOGO_STR_ERR_CONFIG_TUN_DEV_REASON, iftun,strerror(errno)); close(tunfd); return(-1); } return tunfd; } // -------------------------------------------------------------------------- // TunMainLoop: Initializes Keepalive engine and starts it. Then starts a // loop to transfer data from/to the socket and tunnel. // This process is repeated until tspCheckForStopOrWait indicates a stop. // gogoc_status TunMainLoop(sint32_t tunfd, pal_socket_t Socket, sint32_t redirect, tBoolean keepalive, sint32_t keepalive_interval, char *local_address_ipv6, char *keepalive_address) { fd_set rfds; int count, maxfd, ret; unsigned char bufin[TUN_BUFSIZE] = { 0x00, 0x00, 0x86, 0xDD }; unsigned char bufout[TUN_BUFSIZE]; struct timeval timeout; void* p_ka_engine = NULL; ka_status_t ka_status; ka_ret_t ka_ret; gogoc_status status; int ongoing = 1; keepalive = (keepalive_interval != 0) ? TRUE : FALSE; if( keepalive == TRUE ) { // Initialize the keepalive engine. ka_ret = KA_init( &p_ka_engine, keepalive_interval * 1000, local_address_ipv6, keepalive_address, AF_INET6 ); if( ka_ret != KA_SUCCESS ) { return make_status(CTX_TUNNELLOOP, ERR_KEEPALIVE_ERROR); } // Start the keepalive loop(thread). ka_ret = KA_start( p_ka_engine ); if( ka_ret != KA_SUCCESS ) { KA_destroy( &p_ka_engine ); return make_status(CTX_TUNNELLOOP, ERR_KEEPALIVE_ERROR); } } if (redirect) { const int tun_check_delay = 300; // 300 X 100ms = 30 sec. int tun_check = tun_check_delay; while( ongoing == 1 ) { // initialize status. status = STATUS_SUCCESS_INIT; if( tspCheckForStopOrWait( 100 ) != 0 ) { // We've been notified to stop. ongoing = 0; } if( keepalive == TRUE ) { // Check if we're stopping. if( ongoing == 0 ) { // Stop keepalive engine. KA_stop( p_ka_engine ); } // Query the keepalive status. ka_status = KA_qry_status( p_ka_engine ); switch( ka_status ) { case KA_STAT_ONGOING: case KA_STAT_FIN_SUCCESS: break; case KA_STAT_FIN_TIMEOUT: KA_stop( p_ka_engine ); status = make_status(CTX_TUNNELLOOP, ERR_KEEPALIVE_TIMEOUT); break; case KA_STAT_INVALID: case KA_STAT_FIN_ERROR: default: KA_stop( p_ka_engine ); status = make_status(CTX_TUNNELLOOP, ERR_KEEPALIVE_ERROR); break; } } // Check if we're normal. if( status_number(status) != SUCCESS || ongoing != 1 ) { goto done; } if (--tun_check <= 0) { int check_status = 0; if (ioctl(tunfd, TUNGETREDIRECTSTATUS, (void *)&check_status) < 0) { Display(LOG_LEVEL_3, ELInfo, "TunRedirect", "Failed to get tun redirect status."); } if(!check_status) { status = make_status(CTX_TUNNELLOOP, ERR_TUNNEL_IO); goto done; } tun_check = tun_check_delay; } } // while() } else while( ongoing == 1 ) { // initialize status. status = STATUS_SUCCESS_INIT; if( tspCheckForStopOrWait( 0 ) != 0 ) { // We've been notified to stop. ongoing = 0; } if( keepalive == TRUE ) { // Check if we're stopping. if( ongoing == 0 ) { // Stop keepalive engine. KA_stop( p_ka_engine ); } // Query the keepalive status. ka_status = KA_qry_status( p_ka_engine ); switch( ka_status ) { case KA_STAT_ONGOING: case KA_STAT_FIN_SUCCESS: break; case KA_STAT_FIN_TIMEOUT: KA_stop( p_ka_engine ); status = make_status(CTX_TUNNELLOOP, ERR_KEEPALIVE_TIMEOUT); break; case KA_STAT_INVALID: case KA_STAT_FIN_ERROR: default: KA_stop( p_ka_engine ); status = make_status(CTX_TUNNELLOOP, ERR_KEEPALIVE_ERROR); break; } // Reinit select timeout variable; select modifies it. // Use 500ms because we need to re-check keepalive status. timeout.tv_sec = 0; timeout.tv_usec = 500000; // 500 milliseconds. } else { // Reinit select timeout variable; select modifies it. timeout.tv_sec = 7 * 24 * 60 * 60 ; // one week timeout.tv_usec = 0; } // Check if we're normal. if( status_number(status) != SUCCESS || ongoing != 1 ) { goto done; } FD_ZERO(&rfds); FD_SET(tunfd,&rfds); FD_SET(Socket,&rfds); maxfd = tunfd>Socket?tunfd:Socket; ret = select( maxfd+1, &rfds, NULL, NULL, &timeout ); if( ret > 0 ) { if( FD_ISSET(tunfd,&rfds) ) { // Data sent through UDP tunnel if ( (count = read(tunfd,bufout,sizeof(bufout) )) == -1 ) { Display( LOG_LEVEL_1, ELError, "TunMainLoop",STR_NET_FAIL_R_TUN_DEV ); status = make_status(CTX_TUNNELLOOP, ERR_TUNNEL_IO); goto done; } if (send(Socket,bufout+4,count-4,0) != count-4) { Display( LOG_LEVEL_1, ELError, "TunMainLoop",STR_NET_FAIL_W_SOCKET ); status = make_status(CTX_TUNNELLOOP, ERR_TUNNEL_IO); goto done; } } if( FD_ISSET(Socket,&rfds) ) { // Data received through UDP tunnel. count = recvfrom( Socket, bufin+4, TUN_BUFSIZE-4, 0, NULL, NULL ); if( write(tunfd,bufin,count+4) != count+4 ) { Display( LOG_LEVEL_1, ELError, "TunMainLoop", STR_NET_FAIL_W_TUN_DEV ); status = make_status(CTX_TUNNELLOOP, ERR_TUNNEL_IO); goto done; } } } } // while() /* Normal loop end */ status = STATUS_SUCCESS_INIT; done: if( keepalive == TRUE ) { KA_destroy( &p_ka_engine ); } return status; } // -------------------------------------------------------------------------- gogoc_status TunRedirect(sint32_t tunfd, pal_socket_t socket, net_tools_t *nt, sint32_t *redirect) { *redirect = 0; if (ioctl(tunfd, TUNGETREDIRECTSUPPORT, (void *)redirect) < 0) { Display(LOG_LEVEL_3, ELInfo, "TunRedirect", "Failed to get tun redirect support."); } else { Display(LOG_LEVEL_3, ELInfo, "TunRedirect", "Tun redirect support: %u.", *redirect); } if (*redirect) { struct tun_setredirect args; struct sockaddr_in local; struct sockaddr_in remote; socklen_t len; len = sizeof(local); if (getsockname(socket, (struct sockaddr*)&local, &len) < 0) { Display(LOG_LEVEL_1, ELError, "TunRedirect", "Failed to get local name (%d).", errno); return make_status(CTX_TUNINTERFACESETUP, ERR_TUNNEL_IO); } len = sizeof(remote); if (getpeername(socket, (struct sockaddr*)&remote, &len) < 0) { Display(LOG_LEVEL_1, ELError, "TunRedirect", "Failed to get peer name (%d).", errno); return make_status(CTX_TUNINTERFACESETUP, ERR_TUNNEL_IO); } /* * To keep this code generic, * these should be provided by socket creator. */ args.family = PF_INET; args.type = SOCK_DGRAM; args.proto = IPPROTO_UDP; args.sock_rcvbuf_size = 256 * 1024; /* gives better performance thant default value */ args.sock_sndbuf_size = -1; /* use socket default value, does not affect performance */ args.local = (struct sockaddr*)&local; args.remote = (struct sockaddr*)&remote; args.pi.flags = 0; args.pi.proto = ETH_P_IPV6; /* Close socket to let kernel bind to same local address/port */ tspClose(socket, nt); socket = -1; Display(LOG_LEVEL_3, ELInfo, "TunRedirect", "Socket closed to let kernel take it."); if (ioctl(tunfd, TUNSETREDIRECT, (void *)&args) < 0) { Display(LOG_LEVEL_1, ELError, "TunRedirect", "Failed to set tun redirect."); return make_status(CTX_TUNINTERFACESETUP, ERR_TUNNEL_IO); } Display(LOG_LEVEL_3, ELInfo, "TunRedirect", "Tun redirection set."); } return STATUS_SUCCESS_INIT; } gogoc-1_2-RELEASE/gogoc-tsp/platform/gogocpe/tsp_tun.h0100644000000000000000000000235111345000335021321 0ustar rootroot/* --------------------------------------------------------------------------- $Id: tsp_tun.h,v 1.1 2010/03/07 19:39:09 carl Exp $ --------------------------------------------------------------------------- This source code copyright (c) gogo6 Inc. 2002-2005,2007. LICENSE NOTICE: You may use and modify this source code only if you have executed a valid license agreement with gogo6 Inc. granting you the right to do so, the said license agreement governing such use and modifications. Copyright or other intellectual property notices are not to be removed from the source code. --------------------------------------------------------------------------- */ #ifndef TUN_H #define TUN_H #include "config.h" #include "net.h" /* net_tools_t */ sint32_t TunInit (char *TunDevice); gogoc_status TunMainLoop (sint32_t tunfd, pal_socket_t Socket, sint32_t redirect, tBoolean keepalive, sint32_t keepalive_interval, char *local_address_ipv6, char *keepalive_address); gogoc_status TunRedirect (sint32_t tunfd, pal_socket_t Socket, net_tools_t *nt, sint32_t *redirect); #endif /* TUN_H */ gogoc-1_2-RELEASE/gogoc-tsp/platform/linux/0040755000000000000000000000000011346561543017210 5ustar rootrootgogoc-1_2-RELEASE/gogoc-tsp/platform/linux/Makefile0100644000000000000000000000217111301544604020634 0ustar rootroot# ########################################################################### # $Id: Makefile,v 1.1 2009/11/20 16:53:24 jasminko Exp $ # # This source code copyright (c) gogo6 Inc. 2002-2007. # # For license information refer to CLIENT-LICENSE.TXT # # ########################################################################### # # NOTE: This makefile MUST be interpreted by GNU make. # Include the platform makefile, if it exists. -include platform.mak ifdef DEBUG CFLAGS=-g -Wall $(CC_INC_PATHS) $(PLATFORM_CFLAGS) -D_REENTRANT -DDEBUG LDFLAGS=-g $(LD_LIB_PATHS) $(LD_LIBRARIES) -lcrypto -lpthread -lstdc++ else CFLAGS=-O2 -Wall $(CC_INC_PATHS) $(PLATFORM_CFLAGS) -D_REENTRANT LDFLAGS=$(LD_LIB_PATHS) $(LD_LIBRARIES) -lcrypto -lpthread -lstdc++ endif CC=gcc OBJS=$(OBJS_DIR)/tsp_local.o \ $(OBJS_DIR)/tsp_tun.o all: $(TARGET) install: all $(OBJS_DIR)/tsp_local.o:tsp_local.c $(CC) $(CFLAGS) -c tsp_local.c -o $(OBJS_DIR)/tsp_local.o $(OBJS_DIR)/tsp_tun.o:tsp_tun.c $(CC) $(CFLAGS) -c tsp_tun.c -o $(OBJS_DIR)/tsp_tun.o $(TARGET): $(OBJS) $(CC) -o $(TARGET) $(wildcard $(OBJS_DIR)/*.o) $(LDFLAGS) clean: rm -f $(OBJS) $(TARGET) gogoc-1_2-RELEASE/gogoc-tsp/platform/linux/platform.h0100644000000000000000000000104411301544604021167 0ustar rootroot/* --------------------------------------------------------------------------- $Id: platform.h,v 1.1 2009/11/20 16:53:24 jasminko Exp $ --------------------------------------------------------------------------- This source code copyright (c) gogo6 Inc. 2002-2007. For license information refer to CLIENT-LICENSE.TXT --------------------------------------------------------------------------- */ #ifndef _PLATFORM_H_ #define _PLATFORM_H_ /* Linux */ #include "pal.h" #define SCRIPT_TMP_FILE "/tmp/gogoc-tmp.log" #endif gogoc-1_2-RELEASE/gogoc-tsp/platform/linux/platform.mak0100644000000000000000000000107611301544604021515 0ustar rootroot# ########################################################################### # # $Id: platform.mak,v 1.1 2009/11/20 16:53:24 jasminko Exp $ # # Copyright (c) 2007 gogo6 Inc. All rights reserved. # # For license information refer to CLIENT-LICENSE.TXT # # This file contains platform-specific makefile rules and symbols. # # ########################################################################### # # Additional platform CFLAGS. # PLATFORM_CFLAGS= # Platform default interface names for each tunnel mode. # PLATFORM_V6V4=sit1 PLATFORM_V6UDPV4=tun PLATFORM_V4V6=sit0 gogoc-1_2-RELEASE/gogoc-tsp/platform/linux/tsp_local.c0100644000000000000000000002254611345003743021332 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: tsp_local.c,v 1.3 2010/03/07 20:09:07 carl Exp $ ----------------------------------------------------------------------------- This source code copyright (c) gogo6 Inc. 2002-2007. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ /* LINUX */ #include #include #include #include "platform.h" #include "gogoc_status.h" #include "config.h" /* tConf */ #include "xml_tun.h" /* tTunnel */ #include "net.h" /* net_tools_t */ #include "tsp_net.h" /* tspClose */ #include "log.h" // Display #include "hex_strings.h" // Various string constants #include "tsp_tun.h" // linux tun support #include "tsp_client.h" // tspSetupInterfaceLocal() #include "tsp_setup.h" // tspSetupInterface() #include "tsp_tun_mgt.h" // tspPerformTunnelLoop() /* these globals are defined by US used by alot of things in */ char *FileName = "gogoc.conf"; char *ScriptInterpretor = "/bin/sh"; char *ScriptExtension = "sh"; char *ScriptDir = NULL; char *TspHomeDir = "/usr/local/etc/gogoc"; char DirSeparator = '/'; int indSigHUP = 0; // Set to 1 when HUP signal is trapped. #include // Dummy implementation for non-win32 targets // (Library gogocmessaging is not linked in non-win32 targets). error_t send_status_info( void ) { return GOGOCM_UIS__NOERROR; } error_t send_tunnel_info( void ) { return GOGOCM_UIS__NOERROR; } error_t send_broker_list( void ) { return GOGOCM_UIS__NOERROR; } error_t send_haccess_status_info( void ) { return GOGOCM_UIS__NOERROR; } // -------------------------------------------------------------------------- /* Verify for ipv6 support */ // gogoc_status tspTestIPv6Support() { struct stat buf; if(stat("/proc/net/if_inet6",&buf) == -1) { Display(LOG_LEVEL_1,ELError,"tspTestIPv6Support",GOGO_STR_NO_IPV6_SUPPORT_FOUND); Display(LOG_LEVEL_1,ELError,"tspTestIPv6Support",GOGO_STR_TRY_MODPROBE_IPV6); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } Display(LOG_LEVEL_2,ELInfo,"tspTestIPv6Support",GOGO_STR_IPV6_SUPPORT_FOUND); return STATUS_SUCCESS_INIT; } // -------------------------------------------------------------------------- // linux specific to setup an env variable // void tspSetEnv(char *Variable, char *Value, int Flag) { setenv( Variable, Value, Flag ); Display( LOG_LEVEL_3, ELInfo, "tspSetEnv", "%s=%s", Variable, Value ); } // -------------------------------------------------------------------------- // Checks if the gogoCLIENT has been requested to stop and exit. // // Returns 1 if gogoCLIENT is being requested to stop and exit. // Else, waits 'uiWaitMs' miliseconds and returns 0. // // Defined in tsp_client.h // int tspCheckForStopOrWait( const unsigned int uiWaitMs ) { // Sleep for the amount of time specified, if signal has not been sent. if( indSigHUP == 0 ) { // usleep is expecting microseconds (1 microsecond = 0.000001 second). usleep( uiWaitMs * 1000 ); } return indSigHUP; } // -------------------------------------------------------------------------- // Called from tsp_setup.c -> tspSetupInterface // Do extra platform-specific stuff before tunnel script is launched. // int tspSetupInterfaceLocal( tConf* pConf, tTunnel* pTun ) { return 0; } // -------------------------------------------------------------------------- // Returns local address. // tspSetupTunnel() will callback here // char* tspGetLocalAddress(int socket, char *buffer, int size) { struct sockaddr_in6 addr; /* enough place for v4 and v6 */ struct sockaddr_in *addr_v4 = (struct sockaddr_in *)&addr; struct sockaddr_in6 *addr_v6 = (struct sockaddr_in6 *)&addr; socklen_t len; len = sizeof addr; if (getsockname(socket, (struct sockaddr *)&addr, &len) < 0) { Display(LOG_LEVEL_1, ELError, "TryServer", GOGO_STR_ERR_FIND_SRC_IP); return NULL; } if (addr.sin6_family == AF_INET6) return (char *)inet_ntop(AF_INET6, (const void*) &addr_v6->sin6_addr, buffer, size); else return (char *)inet_ntop(AF_INET, (const void*) &addr_v4->sin_addr, buffer, size); } // -------------------------------------------------------------------------- // Setup tunneling interface and any daemons // tspSetupTunnel() will callback here. // #ifdef DSLITE_SUPPORT #error DSLITE support not implemented on platform #endif gogoc_status tspStartLocal(int socket, tConf *c, tTunnel *t, net_tools_t *nt) { TUNNEL_LOOP_CONFIG tun_loop_cfg; gogoc_status status = STATUS_SUCCESS_INIT; int ka_interval = 0; int tunfd = (-1); int pid; // Check if we got root privileges. if(geteuid() != 0) { // Error: we don't have root privileges. Display( LOG_LEVEL_1, ELError, "tspStartLocal", GOGO_STR_FATAL_NOT_ROOT_FOR_TUN ); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } // Check Ipv6 support. Display( LOG_LEVEL_2, ELInfo, "tspStartLocal", GOGO_STR_CHECKING_LINUX_IPV6_SUPPORT ); status = tspTestIPv6Support(); if( status_number(status) != SUCCESS ) { // Error: It seems the user does not have IPv6 support in kernel. return status; } // Check if we're already daemon. Calling multiple times the daemon() messes up pthreads. if( !c->nodaemon && getppid() != 1 ) { // Detach from controlling terminal and run in the background. Display( LOG_LEVEL_3, ELInfo, "tspStartLocal", GOGO_STR_GOING_DAEMON ); if( daemon(1,0) == -1 ) { // Error: Failed to detach. Display( LOG_LEVEL_1, ELError, "tspStartLocal", GOGO_STR_CANT_FORK ); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } } // Check tunnel mode. if( strcasecmp(t->type, STR_CONFIG_TUNNELMODE_V4V6) == 0 ) { // V4V6 tunnel mode is not supported on this platform. Display( LOG_LEVEL_1, ELError, "tspStartLocal", GOGO_STR_NO_V4V6_ON_PLATFORM ); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } else if( strcasecmp(t->type, STR_CONFIG_TUNNELMODE_V6UDPV4) == 0 ) { // When using V6UDPV4 encapsulation, open the TUN device. tunfd = TunInit(c->if_tunnel_v6udpv4); if( tunfd == -1 ) { // Error: Failed to open TUN device. Display( LOG_LEVEL_1, ELError, "tspStartLocal", STR_MISC_FAIL_TUN_INIT ); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } } while( 1 ) // Dummy loop. 'break' instruction at the end. { // Run the config script in another thread, without giving it our tunnel // descriptor. This is important because otherwise the tunnel will stay // open if we get killed. // pid = fork(); if( pid < 0 ) { // fork() error status = make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); break; } else if (pid == 0) { // Child processing: run template script. if( tunfd != -1 ) { close(tunfd); } status = tspSetupInterface(c, t); exit(status); } else { // Parent processing int s = 0; // Wait for child process to exit. Display( LOG_LEVEL_3, ELInfo, "tspStartLocal", GOGO_STR_WAITING_FOR_SETUP_SCRIPT ); if( wait(&s) != pid ) { // Error occured: we have no other child Display( LOG_LEVEL_1, ELError, "tspStartLocal", GOGO_STR_ERR_WAITING_SCRIPT ); status = make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); break; } // Check if process waited upon has exited. if( !WIFEXITED(s) ) { // Error: child has not exited properly. Maybe killed ? Display( LOG_LEVEL_1, ELError, "tspStartLocal", STR_GEN_SCRIPT_EXEC_FAILED ); status = make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); break; } // Check child exit code. status = WEXITSTATUS(s); if( status_number(status) != SUCCESS ) { break; } } // Retrieve keepalive inteval, if found in tunnel parameters. if( t->keepalive_interval != NULL ) { ka_interval = atoi(t->keepalive_interval); } // Start the tunnel loop, depending on tunnel mode // if( strcasecmp(t->type, STR_CONFIG_TUNNELMODE_V6UDPV4) == 0 ) { status = TunMainLoop( tunfd, socket, c->keepalive, ka_interval, t->client_address_ipv6, t->keepalive_address); /* We got out of V6UDPV4 "TUN" tunnel loop */ tspClose(socket, nt); } else if( strcasecmp(t->type, STR_CONFIG_TUNNELMODE_V6V4) == 0 ) { memset( &tun_loop_cfg, 0x00, sizeof(TUNNEL_LOOP_CONFIG) ); tun_loop_cfg.ka_interval = ka_interval; tun_loop_cfg.ka_src_addr = t->client_address_ipv6; tun_loop_cfg.ka_dst_addr = t->keepalive_address; tun_loop_cfg.sa_family = AF_INET6; tun_loop_cfg.tun_lifetime = 0; status = tspPerformTunnelLoop( &tun_loop_cfg ); } break; // END of DUMMY loop. } // Cleanup: Close tunnel descriptor, if it was opened. if( tunfd != -1 ) { // The tunnel file descriptor should be closed before attempting to tear // down the tunnel. Destruction of the tunnel interface may fail if // descriptor is not closed. close( tunfd ); } // Cleanup: Handle tunnel teardown. tspTearDownTunnel( c, t ); return status; } gogoc-1_2-RELEASE/gogoc-tsp/platform/linux/tsp_tun.c0100644000000000000000000001374111301544604021041 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: tsp_tun.c,v 1.1 2009/11/20 16:53:24 jasminko Exp $ ----------------------------------------------------------------------------- This source code copyright (c) gogo6 Inc. 2002-2006. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ /* Linux */ #include #include #include #include #include "platform.h" #include "gogoc_status.h" #include #include #include "tsp_tun.h" // Local function prototypes. #include "tsp_client.h" // tspCheckForStopOrWait() #include "net_ka.h" // KA function prototypes and types. #include "log.h" // Display and logging prototypes and types. #include "hex_strings.h" // String litterals #define TUN_BUFSIZE 2048 // Buffer size for TUN interface IO operations. // -------------------------------------------------------------------------- // TunInit: Open and initialize the TUN interface. // sint32_t TunInit(char *TunDevice) { sint32_t tunfd; struct ifreq ifr; char iftun[128]; unsigned long ioctl_nochecksum = 1; /* for linux, force the use of "tun" */ strcpy(iftun,"/dev/net/tun"); tunfd = open(iftun,O_RDWR); if (tunfd == -1) { Display(LOG_LEVEL_1, ELError, "TunInit", GOGO_STR_ERR_OPEN_DEV, iftun); Display(LOG_LEVEL_1, ELError, "TunInit", GOGO_STR_TRY_MODPROBE_TUN); return (-1); } memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TUN; strncpy(ifr.ifr_name, TunDevice, IFNAMSIZ); if((ioctl(tunfd, TUNSETIFF, (void *) &ifr) == -1) || (ioctl(tunfd, TUNSETNOCSUM, (void *) ioctl_nochecksum) == -1)) { Display(LOG_LEVEL_1, ELError, "TunInit", GOGO_STR_ERR_CONFIG_TUN_DEV_REASON, iftun,strerror(errno)); close(tunfd); return(-1); } return tunfd; } // -------------------------------------------------------------------------- // TunMainLoop: Initializes Keepalive engine and starts it. Then starts a // loop to transfer data from/to the socket and tunnel. // This process is repeated until tspCheckForStopOrWait indicates a stop. // gogoc_status TunMainLoop(sint32_t tunfd, pal_socket_t Socket, tBoolean keepalive, sint32_t keepalive_interval, char *local_address_ipv6, char *keepalive_address) { fd_set rfds; int count, maxfd, ret; unsigned char bufin[TUN_BUFSIZE] = { 0x00, 0x00, 0x86, 0xDD }; unsigned char bufout[TUN_BUFSIZE]; struct timeval timeout; void* p_ka_engine = NULL; ka_status_t ka_status; ka_ret_t ka_ret; int ongoing = 1; gogoc_status status; keepalive = (keepalive_interval != 0) ? TRUE : FALSE; if( keepalive == TRUE ) { // Initialize the keepalive engine. ka_ret = KA_init( &p_ka_engine, keepalive_interval * 1000, local_address_ipv6, keepalive_address, AF_INET6 ); if( ka_ret != KA_SUCCESS ) { return make_status(CTX_TUNNELLOOP, ERR_KEEPALIVE_ERROR); } // Start the keepalive loop(thread). ka_ret = KA_start( p_ka_engine ); if( ka_ret != KA_SUCCESS ) { KA_destroy( &p_ka_engine ); return make_status(CTX_TUNNELLOOP, ERR_KEEPALIVE_ERROR); } } // Data send loop. while( ongoing == 1 ) { // initialize status. status = STATUS_SUCCESS_INIT; if( tspCheckForStopOrWait( 0 ) != 0 ) { // We've been notified to stop. ongoing = 0; } if( keepalive == TRUE ) { // Check if we're stopping. if( ongoing == 0 ) { // Stop keepalive engine. KA_stop( p_ka_engine ); } // Query the keepalive status. ka_status = KA_qry_status( p_ka_engine ); switch( ka_status ) { case KA_STAT_ONGOING: case KA_STAT_FIN_SUCCESS: break; case KA_STAT_FIN_TIMEOUT: KA_stop( p_ka_engine ); status = make_status(CTX_TUNNELLOOP, ERR_KEEPALIVE_TIMEOUT); break; case KA_STAT_INVALID: case KA_STAT_FIN_ERROR: default: KA_stop( p_ka_engine ); status = make_status(CTX_TUNNELLOOP, ERR_KEEPALIVE_ERROR); break; } // Reinit select timeout variable; select modifies it. // Use 500ms because we need to re-check keepalive status. timeout.tv_sec = 0; timeout.tv_usec = 500000; // 500 milliseconds. } else { // Reinit select timeout variable; select modifies it. timeout.tv_sec = 7 * 24 * 60 * 60 ; // one week timeout.tv_usec = 0; } // Check if we're normal. if( status_number(status) != SUCCESS || ongoing != 1 ) { goto done; } FD_ZERO(&rfds); FD_SET(tunfd,&rfds); FD_SET(Socket,&rfds); maxfd = tunfd>Socket?tunfd:Socket; ret = select( maxfd+1, &rfds, NULL, NULL, &timeout ); if( ret > 0 ) { if( FD_ISSET(tunfd,&rfds) ) { // Data sent through UDP tunnel if ( (count = read(tunfd,bufout,sizeof(bufout) )) == -1 ) { Display( LOG_LEVEL_1, ELError, "TunMainLoop",STR_NET_FAIL_R_TUN_DEV ); status = make_status(CTX_TUNNELLOOP, ERR_TUNNEL_IO); goto done; } if (send(Socket,bufout+4,count-4,0) != count-4) { Display( LOG_LEVEL_1, ELError, "TunMainLoop",STR_NET_FAIL_W_SOCKET ); status = make_status(CTX_TUNNELLOOP, ERR_TUNNEL_IO); goto done; } } if( FD_ISSET(Socket,&rfds) ) { // Data received through UDP tunnel. count = recvfrom( Socket, bufin+4, TUN_BUFSIZE-4, 0, NULL, NULL ); if( write(tunfd,bufin,count+4) != count+4 ) { Display( LOG_LEVEL_1, ELError, "TunMainLoop", STR_NET_FAIL_W_TUN_DEV ); status = make_status(CTX_TUNNELLOOP, ERR_TUNNEL_IO); goto done; } } } } // while() /* Normal loop end */ status = STATUS_SUCCESS_INIT; done: if( keepalive == TRUE ) { KA_destroy( &p_ka_engine ); } return status; } gogoc-1_2-RELEASE/gogoc-tsp/platform/linux/tsp_tun.h0100644000000000000000000000144111301544604021040 0ustar rootroot/* --------------------------------------------------------------------------- $Id: tsp_tun.h,v 1.1 2009/11/20 16:53:24 jasminko Exp $ --------------------------------------------------------------------------- This source code copyright (c) gogo6 Inc. 2002-2005. For license information refer to CLIENT-LICENSE.TXT --------------------------------------------------------------------------- */ #ifndef TUN_H #define TUN_H #include "config.h" sint32_t TunInit (char *TunDevice); gogoc_status TunMainLoop (sint32_t tunfd, pal_socket_t Socket, tBoolean keepalive, sint32_t keepalive_interval, char *local_address_ipv6, char *keepalive_address); #endif /* TUN_H */ gogoc-1_2-RELEASE/gogoc-tsp/platform/netbsd/0040755000000000000000000000000011346561543017330 5ustar rootrootgogoc-1_2-RELEASE/gogoc-tsp/platform/netbsd/Makefile0100644000000000000000000000202011301544605020746 0ustar rootroot# ########################################################################### # $Id: Makefile,v 1.1 2009/11/20 16:53:25 jasminko Exp $ # # This source code copyright (c) gogo6 Inc. 2002-2007. # # For license information refer to CLIENT-LICENSE.TXT # # ########################################################################### # # NOTE: This makefile MUST be interpreted by GNU make. # Include the platform makefile, if it exists. -include platform.mak ifdef DEBUG CFLAGS=-g -Wall $(CC_INC_PATHS) $(PLATFORM_CFLAGS) -D_REENTRANT -DDEBUG LDFLAGS=-g $(LD_LIB_PATHS) $(LD_LIBRARIES) -lcrypto -lpthread -lstdc++ -lm else CFLAGS=-O2 -Wall $(CC_INC_PATHS) $(PLATFORM_CFLAGS) -D_REENTRANT LDFLAGS=$(LD_LIB_PATHS) $(LD_LIBRARIES) -lcrypto -lpthread -lstdc++ -lm endif CC=gcc OBJS=$(OBJS_DIR)/tsp_local.o all: $(TARGET) install: all $(OBJS_DIR)/tsp_local.o:tsp_local.c $(CC) $(CFLAGS) -c tsp_local.c -o $(OBJS_DIR)/tsp_local.o $(TARGET): $(OBJS) $(CC) -o $(TARGET) $(wildcard $(OBJS_DIR)/*.o) $(LDFLAGS) clean: rm -f $(OBJS) $(TARGET) gogoc-1_2-RELEASE/gogoc-tsp/platform/netbsd/platform.h0100644000000000000000000000105011301544605021305 0ustar rootroot/* --------------------------------------------------------------------------- $Id: platform.h,v 1.1 2009/11/20 16:53:25 jasminko Exp $ --------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT --------------------------------------------------------------------------- */ #ifndef _PLATFORM_H_ #define _PLATFORM_H_ /* NetBSD */ #include "pal.h" #define SCRIPT_TMP_FILE "/tmp/gogoc-tmp.log" #endif gogoc-1_2-RELEASE/gogoc-tsp/platform/netbsd/platform.mak0100644000000000000000000000107311301544605021633 0ustar rootroot# ########################################################################### # # $Id: platform.mak,v 1.1 2009/11/20 16:53:25 jasminko Exp $ # # Copyright (c) 2007 gogo6 Inc. All rights reserved. # # For license information refer to CLIENT-LICENSE.TXT # # This file contains platform-specific makefile rules and symbols. # # ########################################################################### # # Additional platform CFLAGS. # PLATFORM_CFLAGS= # Platform default interface names for each tunnel mode. # PLATFORM_V6V4=gif0 PLATFORM_V6UDPV4= PLATFORM_V4V6=gif0 gogoc-1_2-RELEASE/gogoc-tsp/platform/netbsd/tsp_local.c0100644000000000000000000001615411345003752021450 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: tsp_local.c,v 1.3 2010/03/07 20:09:14 carl Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ /* NETBSD */ #include "platform.h" #include "gogoc_status.h" #include #include "config.h" /* tConf */ #include "xml_tun.h" /* tTunnel */ #include "net.h" /* net_tools_t */ #include "lib.h" #include "log.h" #include "hex_strings.h" #include "tsp_setup.h" #include "tsp_tun_mgt.h" // tspPerformTunnelLoop() /* these globals are defined by US used by alot of things in */ char *FileName = "gogoc.conf"; char *ScriptInterpretor = "/bin/sh"; char *ScriptExtension = "sh"; char *ScriptDir = NULL; char *TspHomeDir = "/usr/local/etc/gogoc"; char DirSeparator = '/'; int indSigHUP = 0; // Set to 1 when HUP signal is trapped. #include // Dummy implementation for non-win32 targets // (Library gogocmessaging is not linked in non-win32 targets). error_t send_status_info( void ) { return GOGOCM_UIS__NOERROR; } error_t send_tunnel_info( void ) { return GOGOCM_UIS__NOERROR; } error_t send_broker_list( void ) { return GOGOCM_UIS__NOERROR; } error_t send_haccess_status_info( void ) { return GOGOCM_UIS__NOERROR; } /* linux specific to setup an env variable */ void tspSetEnv(char *Variable, char *Value, int Flag) { Display(LOG_LEVEL_3, ELInfo, "tspSetEnv", GOGO_STR_ENV_PRINT_VALUE, Variable, Value); setenv(Variable, Value, Flag); } // -------------------------------------------------------------------------- // Checks if the gogoCLIENT has been requested to stop and exit. // // Returns 1 if gogoCLIENT is being requested to stop and exit. // Else, waits 'uiWaitMs' miliseconds and returns 0. // // Defined in tsp_client.h // int tspCheckForStopOrWait( const unsigned int uiWaitMs ) { // Sleep for the amount of time specified, if signal has not been sent. if( indSigHUP == 0 ) { pal_sleep( uiWaitMs ); } return indSigHUP; } // -------------------------------------------------------------------------- // Called from tsp_setup.c -> tspSetupInterface // Do extra platform-specific stuff before tunnel script is launched. // int tspSetupInterfaceLocal( tConf* pConf, tTunnel* pTun ) { return 0; } /* tspSetupTunnel() will callback here */ char * tspGetLocalAddress(int socket, char *buffer, int size) { struct sockaddr_in6 addr; /* enough place for v4 and v6 */ struct sockaddr_in *addr_v4 = (struct sockaddr_in *)&addr; struct sockaddr_in6 *addr_v6 = (struct sockaddr_in6 *)&addr; int len; len = sizeof addr; if (getsockname(socket, (struct sockaddr *)&addr, &len) < 0) { Display(LOG_LEVEL_1, ELError, "TryServer", GOGO_STR_ERR_FIND_SRC_IP); return NULL; } if (addr.sin6_family == AF_INET6) return (char *)inet_ntop(AF_INET6, (const void*) &addr_v6->sin6_addr, buffer, size); else return (char *)inet_ntop(AF_INET, (const void*) &addr_v4->sin_addr, buffer, size); } /* tspSetupTunnel() will callback here */ /* start locally, ie, setup interface and any daemons or anything needed */ #ifdef DSLITE_SUPPORT #error DSLITE support not implemented on platform #endif gogoc_status tspStartLocal(int socket, tConf *c, tTunnel *t, net_tools_t *nt) { TUNNEL_LOOP_CONFIG tun_loop_cfg; int keepalive_interval = 0; gogoc_status status = STATUS_SUCCESS_INIT; /* Test for root privileges */ if(geteuid() != 0) { Display(LOG_LEVEL_1, ELError, "tspStartLocal", GOGO_STR_FATAL_NOT_ROOT_FOR_TUN); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } /* start the tunneler service */ if (t->keepalive_interval != NULL) { keepalive_interval = atoi(t->keepalive_interval); } { Display(LOG_LEVEL_3, ELInfo, "tspStartLocal", GOGO_STR_GOING_DAEMON); // Check if we're already daemon. Calling multiple times the daemon() messes up pthreads. if( !c->nodaemon && getppid() != 1 ) { if (daemon(1, 0) == -1) { Display(LOG_LEVEL_1, ELError, "tspStartLocal", GOGO_STR_CANT_FORK); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } } if (strcasecmp(t->type, STR_CONFIG_TUNNELMODE_V6UDPV4) == 0 ) { Display(LOG_LEVEL_1, ELError, "tspStartLocal", GOGO_STR_NO_V6UDPV4_ON_PLATFORM); return(make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED)); } if (strcasecmp(t->type, STR_CONFIG_TUNNELMODE_V4V6) == 0 ) { Display(LOG_LEVEL_1, ELError, "tspStartLocal", GOGO_STR_NO_V4V6_ON_PLATFORM); return(make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED)); } /* now, run the config script without giving it our tunnel file descriptor. // // This is important because otherwise the tunnnel will stay open even // if we get killed. */ { int pid = fork(); if (pid < 0) { // fork() error return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } else if (pid == 0) { // Child process status = tspSetupInterface(c, t); exit(status); } else { // Parent process int s = 0; Display(LOG_LEVEL_3, ELInfo, "tspStartLocal", GOGO_STR_WAITING_FOR_SETUP_SCRIPT); if (wait(&s) == pid) { // Our child returned if ( !WIFEXITED(s) ) { Display(LOG_LEVEL_1, ELError, "tspStartLocal", STR_GEN_SCRIPT_EXEC_FAILED); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } // Check exit status. status = WEXITSTATUS(s); if( status_number(status) != SUCCESS ) { return status; } } else { // Error occured: we have no other child Display(LOG_LEVEL_1, ELError, "tspStartLocal", GOGO_STR_ERR_WAITING_SCRIPT); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } } } if( strcasecmp(t->type, STR_CONFIG_TUNNELMODE_V6V4) == 0 ) { memset( &tun_loop_cfg, 0x00, sizeof(TUNNEL_LOOP_CONFIG) ); tun_loop_cfg.ka_interval = keepalive_interval; tun_loop_cfg.ka_src_addr = t->client_address_ipv6; tun_loop_cfg.ka_dst_addr = t->keepalive_address; tun_loop_cfg.sa_family = AF_INET6; tun_loop_cfg.tun_lifetime = 0; status = tspPerformTunnelLoop( &tun_loop_cfg ); } /* v4v6 not supported yet if( strcasecmp(t->type, STR_CONFIG_TUNNELMODE_V4V6) == 0 ) { memset( &tun_loop_cfg, 0x00, sizeof(TUNNEL_LOOP_CONFIG) ); tun_loop_cfg.ka_interval = keepalive_interval; tun_loop_cfg.ka_src_addr = t->client_address_ipv4; tun_loop_cfg.ka_dst_addr = t->keepalive_address; tun_loop_cfg.sa_family = AF_INET; tun_loop_cfg.tun_lifetime = atoi(t->lifetime); status = tspPerformTunnelLoop( &tun_loop_cfg ); } */ } // Handle tunnel teardown. tspTearDownTunnel( c, t ); return status; } gogoc-1_2-RELEASE/gogoc-tsp/platform/openbsd/0040755000000000000000000000000011346561543017503 5ustar rootrootgogoc-1_2-RELEASE/gogoc-tsp/platform/openbsd/Makefile0100644000000000000000000000222411301544605021127 0ustar rootroot# ########################################################################### # $Id: Makefile,v 1.1 2009/11/20 16:53:25 jasminko Exp $ # # This source code copyright (c) gogo6 Inc. 2002-2007. # # For license information refer to CLIENT-LICENSE.TXT # # ########################################################################### # # NOTE: This makefile MUST be interpreted by GNU make. # Include the platform makefile, if it exists. -include platform.mak ifdef DEBUG CFLAGS=-g -Wall $(CC_INC_PATHS) $(PLATFORM_CFLAGS) -D_REENTRANT -DDEBUG LDFLAGS=-g $(LD_LIB_PATHS) $(LD_LIBRARIES) -lcrypto -lpthread -lstdc++ -lm else CFLAGS=-O2 -Wall $(CC_INC_PATHS) $(PLATFORM_CFLAGS) -D_REENTRANT LDFLAGS=$(LD_LIB_PATHS) $(LD_LIBRARIES) -lcrypto -lpthread -lstdc++ -lm endif CC=gcc OBJS=$(OBJS_DIR)/tsp_local.o $(OBJS_DIR)/tsp_tun.o all: $(TARGET) install: all $(OBJS_DIR)/tsp_local.o: tsp_local.c tsp_tun.h $(CC) $(CFLAGS) -c tsp_local.c -o $(OBJS_DIR)/tsp_local.o $(OBJS_DIR)/tsp_tun.o: tsp_tun.c tsp_tun.h $(CC) $(CFLAGS) -c tsp_tun.c -o $(OBJS_DIR)/tsp_tun.o $(TARGET): $(OBJS) $(CC) -o $(TARGET) $(wildcard $(OBJS_DIR)/*.o) $(LDFLAGS) clean: rm -f $(OBJS) $(TARGET) gogoc-1_2-RELEASE/gogoc-tsp/platform/openbsd/platform.h0100644000000000000000000000105211301544606021463 0ustar rootroot/* --------------------------------------------------------------------------- $Id: platform.h,v 1.1 2009/11/20 16:53:26 jasminko Exp $ --------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT --------------------------------------------------------------------------- */ #ifndef _PLATFORM_H_ #define _PLATFORM_H_ /* Open BSD */ #include "pal.h" #define SCRIPT_TMP_FILE "/tmp/gogoc-tmp.log" #endif gogoc-1_2-RELEASE/gogoc-tsp/platform/openbsd/platform.mak0100644000000000000000000000107711301544606022013 0ustar rootroot# ########################################################################### # # $Id: platform.mak,v 1.1 2009/11/20 16:53:26 jasminko Exp $ # # Copyright (c) 2007 gogo6 Inc. All rights reserved. # # For license information refer to CLIENT-LICENSE.TXT # # This file contains platform-specific makefile rules and symbols. # # ########################################################################### # # Additional platform CFLAGS. # PLATFORM_CFLAGS= # Platform default interface names for each tunnel mode. # PLATFORM_V6V4=gif0 PLATFORM_V6UDPV4=tun0 PLATFORM_V4V6=gif0 gogoc-1_2-RELEASE/gogoc-tsp/platform/openbsd/tsp_local.c0100644000000000000000000002167011345003770021622 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: tsp_local.c,v 1.3 2010/03/07 20:09:28 carl Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ /* OPENBSD */ #include "platform.h" #include "gogoc_status.h" #include #include "config.h" /* tConf */ #include "xml_tun.h" /* tTunnel */ #include "net.h" /* net_tools_t */ #include "tsp_setup.h" #include "tsp_net.h" #include "tsp_tun_mgt.h" // tspPerformTunnelLoop() #include "log.h" #include "hex_strings.h" #include "tsp_tun.h" #define IFNAMSIZ 16 // from net/if.h /* these globals are defined by US used by alot of things in */ char *FileName = "gogoc.conf"; char *ScriptInterpretor = "/bin/sh"; char *ScriptExtension = "sh"; char *ScriptDir = NULL; char *TspHomeDir = "/usr/local/etc/gogoc"; char DirSeparator = '/'; int indSigHUP = 0; // Set to 1 when HUP signal is trapped. #include // Dummy implementation for non-win32 targets // (Library gogocmessaging is not linked in non-win32 targets). error_t send_status_info( void ) { return GOGOCM_UIS__NOERROR; } error_t send_tunnel_info( void ) { return GOGOCM_UIS__NOERROR; } error_t send_broker_list( void ) { return GOGOCM_UIS__NOERROR; } error_t send_haccess_status_info( void ) { return GOGOCM_UIS__NOERROR; } // -------------------------------------------------------------------------- // Platform specific way to set an environment variable. // void tspSetEnv(char *Variable, char *Value, int Flag) { Display(LOG_LEVEL_3, ELInfo, "tspSetEnv", GOGO_STR_ENV_PRINT_VALUE, Variable, Value); setenv(Variable, Value, Flag); } // -------------------------------------------------------------------------- // Checks if the gogoCLIENT has been requested to stop and exit. // // Returns 1 if gogoCLIENT is being requested to stop and exit. // Else, waits 'uiWaitMs' miliseconds and returns 0. // // Defined in tsp_client.h // int tspCheckForStopOrWait( const unsigned int uiWaitMs ) { // Sleep for the amount of time specified, if signal has not been sent. if( indSigHUP == 0 ) { // usleep is expecting microseconds (1 microsecond = 0.000001 second). usleep( uiWaitMs * 1000 ); } return indSigHUP; } // -------------------------------------------------------------------------- // Called from tsp_setup.c -> tspSetupInterface // Do extra platform-specific stuff before tunnel script is launched. // int tspSetupInterfaceLocal( tConf* pConf, tTunnel* pTun ) { return 0; } // -------------------------------------------------------------------------- /* tspSetupTunnel() will callback here */ // char* tspGetLocalAddress(int socket, char *buffer, int size) { struct sockaddr_in6 addr; /* enough place for v4 and v6 */ struct sockaddr_in *addr_v4 = (struct sockaddr_in *)&addr; struct sockaddr_in6 *addr_v6 = (struct sockaddr_in6 *)&addr; int len; len = sizeof addr; if (getsockname(socket, (struct sockaddr *)&addr, &len) < 0) { Display(LOG_LEVEL_1, ELError, "TryServer", GOGO_STR_ERR_FIND_SRC_IP); return NULL; } if (addr.sin6_family == AF_INET6) return (char *)inet_ntop(AF_INET6, (const void*) &addr_v6->sin6_addr, buffer, size); else return (char *)inet_ntop(AF_INET, (const void*) &addr_v4->sin_addr, buffer, size); } // -------------------------------------------------------------------------- /* tspSetupTunnel() from tsp_client.c will callback here */ /* start locally, ie, setup interface and any daemons or anything needed */ // #ifdef DSLITE_SUPPORT #error DSLITE support not implemented on platform #endif gogoc_status tspStartLocal(int socket, tConf *c, tTunnel *t, net_tools_t *nt) { TUNNEL_LOOP_CONFIG tun_loop_cfg; gogoc_status status = STATUS_SUCCESS_INIT; int ka_interval = 0; int tunfd = -1; int pid; /* Test for root privileges */ if(geteuid() != 0) { Display(LOG_LEVEL_1, ELError, "tspStartLocal", GOGO_STR_FATAL_NOT_ROOT_FOR_TUN); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } // Check if we're already daemon. Calling multiple times the daemon() messes up pthreads. if( !c->nodaemon && getppid() != 1 ) { Display(LOG_LEVEL_1, ELInfo, "tspStartLocal", GOGO_STR_GOING_DAEMON); if (daemon(1, 0) == -1) { Display(LOG_LEVEL_1, ELError, "tspStartLocal", GOGO_STR_CANT_FORK); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } } if (strcasecmp(t->type, STR_CONFIG_TUNNELMODE_V6UDPV4) == 0 ) { // When using V6UDPV4 encapsulation, open the TUN device. tunfd = TunInit(c->if_tunnel_v6udpv4); if( tunfd == -1 ) { // Error: Failed to open TUN device. Display(LOG_LEVEL_1, ELError, "tspStartLocal", STR_MISC_FAIL_TUN_INIT); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } // Get the real name of the opened tun device for the template script. free( c->if_tunnel_v6udpv4 ); c->if_tunnel_v6udpv4 = (char*) malloc( IFNAMSIZ ); TunName(tunfd, c->if_tunnel_v6udpv4, IFNAMSIZ ); } else if (strcasecmp(t->type, STR_CONFIG_TUNNELMODE_V4V6) == 0 ) { Display(LOG_LEVEL_1, ELError, "tspStartLocal", GOGO_STR_NO_V4V6_ON_PLATFORM); return(make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED)); } while( 1 ) // Dummy loop. 'break' instruction at the end. { // Run the config script in another thread, without giving it our tunnel // descriptor. This is important because otherwise the tunnel will stay // open if we get killed. // pid = fork(); if( pid < 0 ) { // fork() error status = make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); break; } else if( pid == 0 ) { // Child processing: run template script. if( tunfd != -1 ) { close(tunfd); } // Run the interface configuration script. status = tspSetupInterface(c, t); exit(status); } else { // Parent processing int s = 0; // Wait for child process to exit. Display( LOG_LEVEL_3, ELInfo, "tspStartLocal", GOGO_STR_WAITING_FOR_SETUP_SCRIPT ); if( wait(&s) != pid ) { // Error occured: we have no other child Display( LOG_LEVEL_1, ELError, "tspStartLocal", GOGO_STR_ERR_WAITING_SCRIPT ); status = make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED);; break; } // Check if process waited upon has exited. if( !WIFEXITED(s) ) { // Error: child has not exited properly. Maybe killed ? Display( LOG_LEVEL_1, ELError, "tspStartLocal", STR_GEN_SCRIPT_EXEC_FAILED ); status = make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED);; break; } // Check child exit code. status = WEXITSTATUS(s); if( status_number(status) != SUCCESS ) { // Error in script processing. break; } } // Retrieve keepalive inteval, if found in tunnel parameters. if( t->keepalive_interval != NULL ) { ka_interval = atoi(t->keepalive_interval); } // Start the tunnel loop, depending on tunnel mode // if( strcasecmp(t->type, STR_CONFIG_TUNNELMODE_V6UDPV4) == 0 ) { status = TunMainLoop( tunfd, socket, c->keepalive, ka_interval, t->client_address_ipv6, t->keepalive_address ); /* We got out of main loop = keepalive timeout || tunnel error || end */ tspClose(socket, nt); } else if( strcasecmp(t->type, STR_CONFIG_TUNNELMODE_V6V4) == 0 ) { memset( &tun_loop_cfg, 0x00, sizeof(TUNNEL_LOOP_CONFIG) ); tun_loop_cfg.ka_interval = ka_interval; tun_loop_cfg.ka_src_addr = t->client_address_ipv6; tun_loop_cfg.ka_dst_addr = t->keepalive_address; tun_loop_cfg.sa_family = AF_INET6; tun_loop_cfg.tun_lifetime = 0; status = tspPerformTunnelLoop( &tun_loop_cfg ); } /* v4v6 not supported yet if (strcasecmp(t->type, STR_CONFIG_TUNNELMODE_V4V6) == 0 ) { TUNNEL_LOOP_CONFIG tun_loop_cfg; memset( &tun_loop_cfg, 0x00, sizeof(TUNNEL_LOOP_CONFIG) ); tun_loop_cfg.ka_interval = keepalive_interval; tun_loop_cfg.ka_src_addr = t->client_address_ipv4; tun_loop_cfg.ka_dst_addr = t->keepalive_address; tun_loop_cfg.sa_family = AF_INET; tun_loop_cfg.tun_lifetime = 0; status = tspPerformTunnelLoop( &tun_loop_cfg ); } */ break; // END of DUMMY loop. } // Cleanup: Close tunnel descriptor, if it was opened. if( tunfd != -1 ) { // The tunnel file descriptor should be closed before attempting to tear // down the tunnel. Destruction of the tunnel interface may fail if // descriptor is not closed. close( tunfd ); } // Cleanup: Handle tunnel teardown. tspTearDownTunnel( c, t ); return status; } gogoc-1_2-RELEASE/gogoc-tsp/platform/openbsd/tsp_tun.c0100644000000000000000000001430111301544606021327 0ustar rootroot/* --------------------------------------------------------------------------- $Id: tsp_tun.c,v 1.1 2009/11/20 16:53:26 jasminko Exp $ --------------------------------------------------------------------------- Copyright (c) 2001-2006 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT Special thanks to George Koehler and Urs Breinlinger for their contribution. --------------------------------------------------------------------------- */ /* OpenBSD */ /* * OpenBSD is here exactly like FreeBSD, except that there is no * TUNSIFHEAD or TUNSDEBUG. OpenBSD does not have TUNSIFHEAD or TUNSLMODE, * but always behaves like TUNSIFHEAD. * * When writing packets to the tun device, OpenBSD wants them to start * with AF_INET6 in network byte order. */ #include "platform.h" #include "gogoc_status.h" #include #include #include #include #include #include #include "tsp_tun.h" #include "tsp_client.h" #include "net_ka.h" #include "log.h" #include "hex_strings.h" #include "lib.h" #include "config.h" // --------------------------------------------------------------------------- /* Get the name of the tun device using file descriptor */ void TunName( int tunfd, char* name, size_t name_len ) { struct stat sbuf; char *internal_buffer; if( fstat(tunfd,&sbuf) != -1 ) { internal_buffer = devname(sbuf.st_rdev, S_IFCHR); strncpy(name, internal_buffer, name_len); } } // --------------------------------------------------------------------------- /* Initialize tun interface */ int TunInit(char *tun_device) { int tunfd; int ifmode = IFF_POINTOPOINT | IFF_MULTICAST; char iftun[128]; strcpy(iftun,"/dev/"); strcat(iftun, tun_device); tunfd = open(iftun,O_RDWR); if (tunfd == -1) { Display(LOG_LEVEL_1, ELError, "TunInit", GOGO_STR_ERR_OPEN_TUN_DEV, iftun); return(-1); } if ((ioctl(tunfd,TUNSIFMODE,&ifmode) == -1)) { close(tunfd); Display(LOG_LEVEL_1, ELError, "TunInit", GOGO_STR_ERR_CONFIG_TUN_DEV, iftun); return(-1); } return tunfd; } // --------------------------------------------------------------------------- gogoc_status TunMainLoop(int tunfd, pal_socket_t Socket, tBoolean keepalive, int keepalive_interval, char *local_address_ipv6, char *keepalive_address) { fd_set rfds; int count, maxfd, ret; char bufin[2048]; char bufout[2048]; struct timeval timeout; void* p_ka_engine = NULL; ka_status_t ka_status; ka_ret_t ka_ret; gogoc_status status; int ongoing = 1; keepalive = (keepalive_interval != 0) ? TRUE : FALSE; if( keepalive == TRUE ) { // Initialize the keepalive engine. ka_ret = KA_init( &p_ka_engine, keepalive_interval * 1000, local_address_ipv6, keepalive_address, AF_INET6 ); if( ka_ret != KA_SUCCESS ) { return make_status(CTX_TUNNELLOOP, ERR_KEEPALIVE_ERROR); } // Start the keepalive loop(thread). ka_ret = KA_start( p_ka_engine ); if( ka_ret != KA_SUCCESS ) { KA_destroy( &p_ka_engine ); return make_status(CTX_TUNNELLOOP, ERR_KEEPALIVE_ERROR); } } // tun device wants bufin[0]...[3] to contain AF_INET6 ((u_int32_t *)bufin)[0] = htonl(AF_INET6); // Data send loop. while( ongoing == 1 ) { // initialize the status. status = STATUS_SUCCESS_INIT; if( tspCheckForStopOrWait( 0 ) != 0 ) { // We've been notified to stop. ongoing = 0; } if( keepalive == TRUE ) { // Check if we're stopping. if( ongoing == 0 ) { // Stop keepalive engine. KA_stop( p_ka_engine ); } // Query the keepalive status. ka_status = KA_qry_status( p_ka_engine ); switch( ka_status ) { case KA_STAT_ONGOING: case KA_STAT_FIN_SUCCESS: break; case KA_STAT_FIN_TIMEOUT: KA_stop( p_ka_engine ); status = make_status(CTX_TUNNELLOOP, ERR_KEEPALIVE_TIMEOUT); break; case KA_STAT_INVALID: case KA_STAT_FIN_ERROR: default: KA_stop( p_ka_engine ); status = make_status(CTX_TUNNELLOOP, ERR_KEEPALIVE_ERROR); break; } // Reinit select timeout variable; select modifies it. // Use 500ms because we need to re-check keepalive status. timeout.tv_sec = 0; timeout.tv_usec = 500000; // 500 milliseconds. } else { // Reinit select timeout variable; select modifies it. timeout.tv_sec = 7 * 24 * 60 * 60 ; // one week timeout.tv_usec = 0; } // Check if we're normal. if( status_number(status) != SUCCESS || ongoing != 1 ) { goto done; } FD_ZERO(&rfds); FD_SET(tunfd,&rfds); FD_SET(Socket,&rfds); maxfd = tunfd>Socket?tunfd:Socket; ret = select(maxfd+1,&rfds,0,0,&timeout); if (ret > 0) { if( FD_ISSET(tunfd, &rfds) ) { /* data sent through udp tunnel */ ioctl(tunfd, FIONREAD, &count); if (count > sizeof(bufout)) { Display(LOG_LEVEL_1, ELError, "TunMainLoop", STR_NET_FAIL_TUN_DEV_BUFSMALL); status = make_status(CTX_TUNNELLOOP, ERR_TUNNEL_IO); goto done; } if (read(tunfd, bufout, count) != count) { Display(LOG_LEVEL_1, ELError, "TunMainLoop", STR_NET_FAIL_R_TUN_DEV); status = make_status(CTX_TUNNELLOOP, ERR_TUNNEL_IO); goto done; } if (send(Socket, bufout+4, count-4, 0) != count-4) { Display(LOG_LEVEL_1, ELError, "TunMainLoop", STR_NET_FAIL_W_SOCKET); status = make_status(CTX_TUNNELLOOP, ERR_TUNNEL_IO); goto done; } } if(FD_ISSET(Socket,&rfds)) { // Data received through UDP tunnel. count=recvfrom(Socket,bufin+4,2048 - 4,0,NULL,NULL); if (write(tunfd, bufin, count + 4) != count + 4) { Display(LOG_LEVEL_1, ELError, "TunMainLoop", STR_NET_FAIL_W_TUN_DEV); status = make_status(CTX_TUNNELLOOP, ERR_TUNNEL_IO); goto done; } } } } /* Normal loop end */ status = STATUS_SUCCESS_INIT; done: if( keepalive == TRUE ) { KA_destroy( &p_ka_engine ); } return status; } gogoc-1_2-RELEASE/gogoc-tsp/platform/openbsd/tsp_tun.h0100644000000000000000000000166311301544606021343 0ustar rootroot/* --------------------------------------------------------------------------- $Id: tsp_tun.h,v 1.1 2009/11/20 16:53:26 jasminko Exp $ --------------------------------------------------------------------------- Copyright (c) 2001-2005 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT Special thanks to George Koehler and Urs Breinlinger. --------------------------------------------------------------------------- */ #ifndef __TSP_TUN_H__ #define __TSP_TUN_H__ #include "config.h" // tBoolean void TunName ( int tunfd, char* name, size_t name_len ); int TunInit ( char *tun_device ); gogoc_status TunMainLoop (int tun, int Socket, tBoolean keepalive, int keepalive_interval, char *local_address_ipv6, char *keepalive_address); #endif gogoc-1_2-RELEASE/gogoc-tsp/platform/sunos/0040755000000000000000000000000011346561543017220 5ustar rootrootgogoc-1_2-RELEASE/gogoc-tsp/platform/sunos/Makefile0100644000000000000000000000217211301544611020643 0ustar rootroot# ########################################################################### # $Id: Makefile,v 1.1 2009/11/20 16:53:29 jasminko Exp $ # # This source code copyright (c) gogo6 Inc. 2002-2007. # # For license information refer to CLIENT-LICENSE.TXT # # ########################################################################### # # NOTE: This makefile MUST be interpreted by GNU make. # Include the platform makefile, if it exists. -include platform.mak ifdef DEBUG CFLAGS=-g -Wall $(CC_INC_PATHS) $(PLATFORM_CFLAGS) -D_REENTRANT -DDEBUG LDFLAGS=-g $(LD_LIB_PATHS) $(LD_LIBRARIES) -lsocket -lnsl -lcrypto -lpthread -lstdc++ -L/usr/sfw/lib -L/usr/local/ssl/lib else CFLAGS=-O2 -Wall $(CC_INC_PATHS) $(PLATFORM_CFLAGS) -D_REENTRANT LDFLAGS=$(LD_LIB_PATHS) $(LD_LIBRARIES) -lsocket -lnsl -lcrypto -lpthread -lstdc++ -L/usr/sfw/lib -L/usr/local/ssl/lib endif CC=gcc OBJS=$(OBJS_DIR)/tsp_local.o all: $(TARGET) install: all $(OBJS_DIR)/tsp_local.o:tsp_local.c $(CC) $(CFLAGS) -c tsp_local.c -o $(OBJS_DIR)/tsp_local.o $(DEFINES) $(TARGET): $(OBJS) $(CC) -o $(TARGET) $(wildcard $(OBJS_DIR)/*.o) $(LDFLAGS) clean: rm -f $(OBJS) $(TARGET) gogoc-1_2-RELEASE/gogoc-tsp/platform/sunos/platform.h0100644000000000000000000000105111301544611021173 0ustar rootroot/* --------------------------------------------------------------------------- $Id: platform.h,v 1.1 2009/11/20 16:53:29 jasminko Exp $ --------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT --------------------------------------------------------------------------- */ #ifndef _PLATFORM_H_ #define _PLATFORM_H_ /* Solaris */ #include "pal.h" #define SCRIPT_TMP_FILE "/tmp/gogoc-tmp.log" #endif gogoc-1_2-RELEASE/gogoc-tsp/platform/sunos/platform.mak0100644000000000000000000000111411301544611021514 0ustar rootroot# ########################################################################### # # $Id: platform.mak,v 1.1 2009/11/20 16:53:29 jasminko Exp $ # # Copyright (c) 2007 gogo6 Inc. All rights reserved. # # For license information refer to CLIENT-LICENSE.TXT # # This file contains platform-specific makefile rules and symbols. # # ########################################################################### # # Additional platform CFLAGS. # PLATFORM_CFLAGS=-I/usr/sfw/include # Platform default interface names for each tunnel mode. # PLATFORM_V6V4=ip.tun0 PLATFORM_V6UDPV4= PLATFORM_V4V6= gogoc-1_2-RELEASE/gogoc-tsp/platform/sunos/tsp_local.c0100644000000000000000000001647011334102364021336 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: tsp_local.c,v 1.2 2010/02/08 21:41:08 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ /* Solaris */ #include "platform.h" #include "gogoc_status.h" #include #include "config.h" /* tConf */ #include "xml_tun.h" /* tTunnel */ #include "net.h" /* net_tools_t */ #include "log.h" // Display() #include "hex_strings.h" // String constants #include "tsp_setup.h" // tspSetupInterface(), tspTearDownTunnel() #include "tsp_tun_mgt.h" // tspPerformTunnelLoop() /* these globals are defined by US used by alot of things in */ char *FileName = "gogoc.conf"; char *ScriptInterpretor = "/bin/sh"; char *ScriptExtension = "sh"; char *ScriptDir = NULL; char *TspHomeDir = "/usr/local/etc/gogoc"; char DirSeparator = '/'; int indSigHUP = 0; // Set to 1 when HUP signal is trapped. #include // Dummy implementation for non-win32 targets // (Library gogocmessaging is not linked in non-win32 targets). error_t send_status_info( void ) { return GOGOCM_UIS__NOERROR; } error_t send_tunnel_info( void ) { return GOGOCM_UIS__NOERROR; } error_t send_broker_list( void ) { return GOGOCM_UIS__NOERROR; } error_t send_haccess_status_info( void ) { return GOGOCM_UIS__NOERROR; } // -------------------------------------------------------------------------- // Solaris specific to setup an env variable // void tspSetEnv( char *Variable, char *Value, int Flag ) { char *buf; if(Value) { int size=(strlen(Variable) + strlen(Value) + 2); if((buf=malloc(size)) == NULL) { Display(LOG_LEVEL_1, ELError, "SetEnv", STR_GEN_MALLOC_ERROR); exit(1); } snprintf(buf, size, "%s=%s", Variable, Value); putenv(buf); Display(LOG_LEVEL_3, ELInfo, "tspSetEnv", GOGO_STR_ENV_PRINT_VALUE, Variable, Value); } } // -------------------------------------------------------------------------- // Checks if the gogoCLIENT has been requested to stop and exit. // // Returns 1 if gogoCLIENT is being requested to stop and exit. // Else, waits 'uiWaitMs' miliseconds and returns 0. // // Defined in tsp_client.h // int tspCheckForStopOrWait( const unsigned int uiWaitMs ) { // Sleep for the amount of time specified, if signal has not been sent. if( indSigHUP == 0 ) { // usleep is expecting microseconds (1 microsecond = 0.000001 second). usleep( uiWaitMs * 1000 ); } return indSigHUP; } // -------------------------------------------------------------------------- // Called from tsp_setup.c -> tspSetupInterface // Do extra platform-specific stuff before tunnel script is launched. // int tspSetupInterfaceLocal( tConf* pConf, tTunnel* pTun ) { return 0; } // -------------------------------------------------------------------------- // Will return the local address. // tspSetupTunnel() will callback here // char * tspGetLocalAddress(int socket, char *buffer, int size) { struct sockaddr_in6 addr; /* enough place for v4 and v6 */ struct sockaddr_in *addr_v4 = (struct sockaddr_in *)&addr; struct sockaddr_in6 *addr_v6 = (struct sockaddr_in6 *)&addr; int len; len = sizeof addr; if (getsockname(socket, (struct sockaddr *)&addr, &len) < 0) { Display(LOG_LEVEL_1, ELError, "TryServer", GOGO_STR_ERR_FIND_SRC_IP); return NULL; } if (addr.sin6_family == AF_INET6) return (char *)inet_ntop(AF_INET6, (const void*) &addr_v6->sin6_addr, buffer, size); else return (char *)inet_ntop(AF_INET, (const void*) &addr_v4->sin_addr, buffer, size); } // -------------------------------------------------------------------------- // start locally, ie, setup interface and any daemons or anything needed // tspSetupTunnel() will callback here // #ifdef DSLITE_SUPPORT #error DSLITE support not implemented on platform #endif gogoc_status tspStartLocal( int socket, tConf *c, tTunnel *t, net_tools_t *nt ) { TUNNEL_LOOP_CONFIG tun_loop_cfg; int keepalive_interval = 0; gogoc_status status; /* Test for root privileges */ if( geteuid() != 0 ) { Display( LOG_LEVEL_1, ELError, "tspStartLocal", GOGO_STR_FATAL_NOT_ROOT_FOR_TUN ); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } /* Test for keepalive */ if( t->keepalive_interval != NULL ) { keepalive_interval = atoi( t->keepalive_interval ); } { int pid_daemon; Display( LOG_LEVEL_3, ELInfo, "tspStartLocal", GOGO_STR_GOING_DAEMON ); pid_daemon = fork(); if( pid_daemon == -1 ) { Display( LOG_LEVEL_1, ELError, "tspStartLocal", GOGO_STR_CANT_FORK ); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } else if( pid_daemon != 0 ) { /* exit the parent */ exit(0); } if( strcasecmp(t->type, STR_CONFIG_TUNNELMODE_V6UDPV4) == 0 ) { Display( LOG_LEVEL_1, ELError, "tspStartLocal", GOGO_STR_NO_V6UDPV4_ON_PLATFORM ); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } else if( strcasecmp(t->type, STR_CONFIG_TUNNELMODE_V4V6) == 0 ) { Display( LOG_LEVEL_1, ELError, "tspStartLocal", GOGO_STR_NO_V4V6_ON_PLATFORM ); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } // else OK. /* Run the template script inm a child process. (Linux TUN stuff ported needlessly). // // This is important because otherwise the tunnnel will stay open even if we get killed */ { int pid = fork(); if( pid < 0 ) { // fork() error return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } else if (pid == 0) { // Child process. Run template script. status = tspSetupInterface(c, t); exit( status ); } else { // Parent process. int s = 0; // Wait for child to finish running template script. Display( LOG_LEVEL_3, ELInfo, "tspStartLocal", GOGO_STR_WAITING_FOR_SETUP_SCRIPT ); if( wait(&s) == pid ) { // ok our child returned. Check exit code. if( !WIFEXITED(s) ) { Display( LOG_LEVEL_1, ELError, "tspStartLocal", STR_GEN_SCRIPT_EXEC_FAILED ); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } status = WEXITSTATUS(s); if( status_number(status) != SUCCESS ) { return status; } } else { // An error occured; we have no other child. Display( LOG_LEVEL_1, ELError, "tspStartLocal", GOGO_STR_ERR_WAITING_SCRIPT ); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } } } memset( &tun_loop_cfg, 0x00, sizeof(TUNNEL_LOOP_CONFIG) ); tun_loop_cfg.ka_interval = keepalive_interval; tun_loop_cfg.ka_src_addr = t->client_address_ipv6; tun_loop_cfg.ka_dst_addr = t->keepalive_address; tun_loop_cfg.sa_family = AF_INET6; tun_loop_cfg.tun_lifetime = 0; status = tspPerformTunnelLoop( &tun_loop_cfg ); } // Handle tunnel teardown. tspTearDownTunnel( c, t ); return status; } gogoc-1_2-RELEASE/gogoc-tsp/platform/unix-common/0040755000000000000000000000000011346561543020322 5ustar rootrootgogoc-1_2-RELEASE/gogoc-tsp/platform/unix-common/Makefile0100644000000000000000000000170411301544612021746 0ustar rootroot# ########################################################################### # $Id: Makefile,v 1.1 2009/11/20 16:53:30 jasminko Exp $ # # This source code copyright (c) gogo6 Inc. 2002-2007. # # For license information refer to CLIENT-LICENSE.TXT # # ########################################################################### # # NOTE: This makefile MUST be interpreted by GNU make. # Include the platform makefile, if it exists. -include $(PLATFORM_DIR)/$(PLATFORM)/platform.mak ifdef DEBUG CFLAGS=-g -Wall $(CC_INC_PATHS) $(PLATFORM_CFLAGS) -DDEBUG else CFLAGS=-O2 -Wall $(CC_INC_PATHS) $(PLATFORM_CFLAGS) endif CC=gcc OS_UNAME=os_uname.h OBJS=$(OBJS_DIR)/unix-main.o all: $(OBJS) install: all $(OS_UNAME): @echo > $(OS_UNAME) @echo \#define OS_UNAME_INFO \"`uname -a`\" >> $(OS_UNAME) @echo >> $(OS_UNAME) $(OBJS_DIR)/unix-main.o:unix-main.c $(OS_UNAME) $(CC) $(CFLAGS) -c unix-main.c -o $(OBJS_DIR)/unix-main.o clean: rm -f $(OBJS) $(OS_UNAME) gogoc-1_2-RELEASE/gogoc-tsp/platform/unix-common/unix-main.c0100644000000000000000000000426211301544612022361 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: unix-main.c,v 1.1 2009/11/20 16:53:30 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2006 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ #include "platform.h" #include "gogoc_status.h" #include #include "tsp_client.h" #include "hex_strings.h" #include "log.h" #include "os_uname.h" #ifdef HACCESS #include "haccess.h" #endif extern int indSigHUP; /* Declared in every unix platform tsp_local.c */ /* -------------------------------------------------------------------------- // Signal handler function. KEEP THIS FUNCTION AS SIMPLE AS POSSIBLE. */ void signal_handler( int sigraised ) { if( sigraised == SIGHUP ) indSigHUP = 1; } // -------------------------------------------------------------------------- // Retrieves OS information and puts it nicely in a string ready for display. // // Defined in tsp_client.h // void tspGetOSInfo( const size_t len, char* buf ) { if( len > 0 && buf != NULL ) { #ifdef OS_UNAME_INFO snprintf( buf, len, "Built on ///%s///", OS_UNAME_INFO ); #else snprintf( buf, len, "Built on ///unknown UNIX/BSD/Linux version///" ); #endif } } // -------------------------------------------------------------------------- int main(int argc, char *argv[]) { int rc; #ifdef HACCESS haccess_status status = HACCESS_STATUS_OK; #endif /* Install new signal handler for HUP signal. */ signal( SIGHUP, &signal_handler ); #ifdef HACCESS /* Initialize the HACCESS module. */ status = haccess_initialize(); if (status != HACCESS_STATUS_OK) { DirectErrorMessage(HACCESS_LOG_PREFIX_ERROR GOGO_STR_HACCESS_ERR_CANT_INIT_MODULE); return ERR_HACCESS_INIT; } #endif /* entry point */ rc = tspMain(argc, argv); #ifdef HACCESS /* The HACCESS module destructs (deinitialization). */ status = haccess_destruct(); if (status != HACCESS_STATUS_OK) { DirectErrorMessage(HACCESS_LOG_PREFIX_ERROR GOGO_STR_HACCESS_ERR_CANT_DO_SHUTDOWN); } #endif return rc; } gogoc-1_2-RELEASE/gogoc-tsp/src/0040755000000000000000000000000011346561543015014 5ustar rootrootgogoc-1_2-RELEASE/gogoc-tsp/src/lib/0040755000000000000000000000000011346561546015565 5ustar rootrootgogoc-1_2-RELEASE/gogoc-tsp/src/lib/Makefile0100644000000000000000000000410111301544620017177 0ustar rootroot# ########################################################################### # $Id: Makefile,v 1.1 2009/11/20 16:53:36 jasminko Exp $ # # Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. # # For license information refer to CLIENT-LICENSE.TXT # # ########################################################################### # # NOTE: This makefile MUST be interpreted by GNU make. # Include the platform makefile, if it exists. -include $(PLATFORM_DIR)/$(PLATFORM)/platform.mak ifdef DEBUG CFLAGS=-g -Wall $(CC_INC_PATHS) $(PLATFORM_CFLAGS) -D_REENTRANT -DDEBUG else CFLAGS=-O2 -Wall $(CC_INC_PATHS) $(PLATFORM_CFLAGS) -D_REENTRANT endif CC=gcc OBJS=$(OBJS_DIR)/base64.o \ $(OBJS_DIR)/cli.o \ $(OBJS_DIR)/config.o \ $(OBJS_DIR)/lib.o \ $(OBJS_DIR)/log.o \ $(OBJS_DIR)/md5c.o \ $(OBJS_DIR)/buffer.o \ $(OBJS_DIR)/bufaux.o \ $(OBJS_DIR)/version.o \ $(OBJS_DIR)/dns.o \ $(OBJS_DIR)/deque.o HACCESS_OBJ=$(OBJS_DIR)/haccess.o all: $(OBJS) $(HACCESS_OBJ) install: all $(OBJS_DIR)/base64.o:base64.c $(CC) $(CFLAGS) -c base64.c -o $(OBJS_DIR)/base64.o $(OBJS_DIR)/cli.o:cli.c $(CC) $(CFLAGS) -c cli.c -o $(OBJS_DIR)/cli.o $(OBJS_DIR)/config.o:config.c $(CC) $(CFLAGS) -c config.c -o $(OBJS_DIR)/config.o $(OBJS_DIR)/lib.o:lib.c $(CC) $(CFLAGS) -c lib.c -o $(OBJS_DIR)/lib.o $(OBJS_DIR)/log.o:log.c $(CC) $(CFLAGS) -c log.c -o $(OBJS_DIR)/log.o $(OBJS_DIR)/md5c.o:md5c.c $(CC) $(CFLAGS) -c md5c.c -o $(OBJS_DIR)/md5c.o $(OBJS_DIR)/buffer.o:buffer.c $(CC) $(CFLAGS) -c buffer.c -o $(OBJS_DIR)/buffer.o $(OBJS_DIR)/bufaux.o:bufaux.c $(CC) $(CFLAGS) -c bufaux.c -o $(OBJS_DIR)/bufaux.o $(OBJS_DIR)/version.o:version.c $(CC) $(CFLAGS) -c version.c -o $(OBJS_DIR)/version.o $(OBJS_DIR)/dns.o:dns.c $(CC) $(CFLAGS) -c dns.c -o $(OBJS_DIR)/dns.o $(OBJS_DIR)/deque.o:deque.c $(CC) $(CFLAGS) -c deque.c -o $(OBJS_DIR)/deque.o $(OBJS_DIR)/haccess.o: @if [ ! -z "$(HACCESS_DEFINES)" ] && [ -f haccess.c ]; then \ echo $(CC) $(CFLAGS) -c haccess.c -o $(OBJS_DIR)/haccess.o ;\ $(CC) $(CFLAGS) -c haccess.c -o $(OBJS_DIR)/haccess.o ;\ fi clean: rm -f $(OBJS) rm -f $(HACCESS_OBJ) gogoc-1_2-RELEASE/gogoc-tsp/src/lib/base64.c0100644000000000000000000001762211301544620017003 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: base64.c,v 1.1 2009/11/20 16:53:36 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2000 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * * Portions of this software are based upon public domain software * originally written at the National Center for Supercomputing Applications, * University of Illinois, Urbana-Champaign. */ #include "pal.h" #include "base64.h" static const unsigned char pr2six[256] = { /* ASCII table */ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 }; sint32_t base64decode_len(const char *bufcoded) { sint32_t nbytesdecoded; register const unsigned char *bufin; register sint32_t nprbytes; bufin = (const unsigned char *) bufcoded; while (pr2six[*(bufin++)] <= 63); nprbytes = (sint32_t)(bufin - (const unsigned char *) bufcoded) - 1; nbytesdecoded = ((nprbytes + 3) / 4) * 3; return nbytesdecoded + 1; } sint32_t base64decode(char *bufplain, const char *bufcoded) { sint32_t len; len = base64decode_binary((unsigned char *) bufplain, bufcoded); bufplain[len] = '\0'; return len; } /* This is the same as base64udecode() except on EBCDIC machines, where * the conversion of the output to ebcdic is left out. */ sint32_t base64decode_binary(unsigned char *bufplain, const char *bufcoded) { sint32_t nbytesdecoded; register const unsigned char *bufin; register unsigned char *bufout; register sint32_t nprbytes; bufin = (const unsigned char *) bufcoded; while (pr2six[*(bufin++)] <= 63); nprbytes = (sint32_t)(bufin - (const unsigned char *) bufcoded) - 1; nbytesdecoded = ((nprbytes + 3) / 4) * 3; bufout = (unsigned char *) bufplain; bufin = (const unsigned char *) bufcoded; while (nprbytes > 4) { *(bufout++) = (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4); *(bufout++) = (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2); *(bufout++) = (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]); bufin += 4; nprbytes -= 4; } /* Note: (nprbytes == 1) would be an error, so just ingore that case */ if (nprbytes > 1) { *(bufout++) = (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4); } if (nprbytes > 2) { *(bufout++) = (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2); } if (nprbytes > 3) { *(bufout++) = (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]); } nbytesdecoded -= (4 - nprbytes) & 3; return nbytesdecoded; } static const char basis_64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; sint32_t base64encode_len(sint32_t len) { return ((len + 2) / 3 * 4) + 1; } sint32_t base64encode(char *encoded, const char *string, sint32_t len) { return base64encode_binary(encoded, (const unsigned char *) string, len); } /* This is the same as base64encode() except on EBCDIC machines, where * the conversion of the input to ascii is left out. */ sint32_t base64encode_binary(char *encoded, const unsigned char *string, sint32_t len) { sint32_t i; char *p; p = encoded; for (i = 0; i < len - 2; i += 3) { *p++ = basis_64[(string[i] >> 2) & 0x3F]; *p++ = basis_64[((string[i] & 0x3) << 4) | ((sint32_t) (string[i + 1] & 0xF0) >> 4)]; *p++ = basis_64[((string[i + 1] & 0xF) << 2) | ((sint32_t) (string[i + 2] & 0xC0) >> 6)]; *p++ = basis_64[string[i + 2] & 0x3F]; } if (i < len) { *p++ = basis_64[(string[i] >> 2) & 0x3F]; if (i == (len - 1)) { *p++ = basis_64[((string[i] & 0x3) << 4)]; *p++ = '='; } else { *p++ = basis_64[((string[i] & 0x3) << 4) | ((sint32_t) (string[i + 1] & 0xF0) >> 4)]; *p++ = basis_64[((string[i + 1] & 0xF) << 2)]; } *p++ = '='; } *p++ = '\0'; return (sint32_t)(p - encoded); } #ifdef MAIN sint32_t main(sint32_t argc, char **argv) { char Buffer[4000]; if(*argv[1] == 'e') base64encode(Buffer, argv[2], strlen(argv[2])); else base64decode(Buffer, argv[2]); printf("%s", Buffer); } #endif gogoc-1_2-RELEASE/gogoc-tsp/src/lib/bufaux.c0100644000000000000000000001607011301544620017205 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: bufaux.c,v 1.1 2009/11/20 16:53:36 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * Auxiliary functions for storing and retrieving various data types to/from * Buffers. * * As far as I am concerned, the code I have written for this software * can be used freely for any purpose. Any derived versions of this * software must be clearly marked as such, and if the derived work is * incompatible with the protocol description in the RFC file, it must be * called by a name other than "ssh" or "Secure Shell". * * * SSH2 packet format added by Markus Friedl * Copyright (c) 2000,2006,2007 Markus Friedl. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "platform.h" #ifndef NO_OPENSSL #include #include "bufaux.h" #include "getput.h" #include "log.h" #include "hex_strings.h" #define buffer_skip_string(b) \ do { u_int l = buffer_get_int(b); buffer_consume(b, l); } while(0) /** * Stores a BIGNUM to buffer in mpint format * * From draft-newman-sasl-passdss-01.txt: * mpint Represents multiple precision integers in two's complement * format, stored as a string, most significant octet first. * Negative numbers have one in the most significant bit of * the first octet of the string data. If the most significant * bit would be set for a positive number, the number MUST be * preceded by a zero byte. Unnecessary leading zero or 255 * bytes MUST NOT be included. The value zero MUST be stored * as a string with zero bytes of data. * * * @param buffer * @param value * * @return */ void buffer_put_bignum(Buffer *buffer, BIGNUM *value) { sint32_t bits = BN_num_bits(value); sint32_t bin_size = (bits + 7) / 8; uint8_t *buf = malloc(bin_size); sint32_t oi; if (buf == NULL) { Display(LOG_LEVEL_1, ELError, "buffer_put_bignum", STR_GEN_MALLOC_ERROR); exit(-1); } /* Get the value of in binary */ oi = BN_bn2bin(value, buf); if (oi != bin_size) { Display(LOG_LEVEL_1, ELError, "buffer_put_bignum", GOGO_STR_BN_BN2BIN_FAILED, oi, bin_size); exit(1); } /* Store the number of bits in the buffer in 4 bytes, msb first. */ buffer_put_int(buffer, bin_size); /* Store the binary data. */ buffer_append(buffer, (char *)buf, oi); memset(buf, 0, bin_size); free(buf); } /* * Retrieves an BIGNUM from the buffer. */ void buffer_get_bignum(Buffer *buffer, BIGNUM *value) { sint32_t bytes; uint8_t *bin; /* Get the number of bytes. */ bytes = buffer_get_int(buffer); if (bytes > 8 * 1024) { Display(LOG_LEVEL_1, ELError, "buffer_get_bignum", GOGO_STR_CANT_HANDLE_BN_SIZE, bytes); exit(1); } if( (sint32_t)buffer_len(buffer) < bytes) { Display(LOG_LEVEL_1, ELError, "buffer_get_bignum", GOGO_STR_INPUT_BUF_TOO_SMALL); exit(1); } bin = buffer_ptr(buffer); BN_bin2bn(bin, bytes, value); buffer_consume(buffer, bytes); } uint32_t buffer_get_int(Buffer *buffer) { u_char buf[4]; buffer_get(buffer, (char *) buf, 4); return GET_32BIT(buf); } void buffer_put_int(Buffer *buffer, uint32_t value) { char buf[4]; PUT_32BIT(buf, value); buffer_append(buffer, buf, 4); } /** * From draft-newman-sasl-passdss-01.txt: * "A string is a length-prefixed octet string. The length is * represented as a uint32 with the data immediately * following. A length of 0 indicates an empty string. The * string MAY contain NUL or 8-bit octets. When used to * represent textual strings, the characters are interpreted * in UTF-8 [UTF-8]. Other character encoding schemes MUST * NOT be used." * * Returns an arbitrary binary string from the buffer. The string * cannot be longer than 256k. The returned value points to memory * allocated with malloc; it is the responsibility of the calling * function to free the data. If length_ptr is non-NULL, the length * of the returned data will be stored there. A null character will * be automatically appended to the returned string, and is not * counted in length. * * @param buffer * @param s * * @return */ void * buffer_get_string(Buffer *buffer, uint32_t *length_ptr) { uint8_t *value; uint32_t len; /* Get the length. */ len = buffer_get_int(buffer); if (len > 256 * 1024) { Display(LOG_LEVEL_1, ELError, "buffer_get_string", GOGO_STR_BAD_STRING_LENGTH, len); exit(1); } /* Allocate space for the string. Add one byte for a null character. */ value = malloc(len + 1); /* Get the string. */ buffer_get(buffer, value, len); /* Append a null character to make processing easier. */ value[len] = 0; /* Optionally return the length of the string. */ if (length_ptr) *length_ptr = len; return value; } /* * Stores and arbitrary binary string in the buffer. */ void buffer_put_string(Buffer *buffer, const void *buf, uint32_t len) { buffer_put_int(buffer, len); buffer_append(buffer, buf, len); } void buffer_put_cstring(Buffer *buffer, const char *s) { if (s == NULL) { Display(LOG_LEVEL_1, ELError, "buffer_put_cstring", STR_GEN_INVALID_POINTER); exit(1); } buffer_put_string(buffer, s, (uint32_t)pal_strlen(s)); } /* * Returns a character from the buffer (0 - 255). */ sint32_t buffer_get_octet(Buffer *buffer) { char ch; buffer_get(buffer, &ch, 1); return (uint8_t) ch; } /* * Stores a character in the buffer. */ void buffer_put_octet(Buffer *buffer, sint32_t value) { char ch = (char)value; buffer_append(buffer, &ch, 1); } #endif gogoc-1_2-RELEASE/gogoc-tsp/src/lib/buffer.c0100644000000000000000000001020211301544620017153 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: buffer.c,v 1.1 2009/11/20 16:53:36 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved * Functions for manipulating fifo buffers (that can grow if needed). * * As far as I am concerned, the code I have written for this software * can be used freely for any purpose. Any derived versions of this * software must be clearly marked as such, and if the derived work is * incompatible with the protocol description in the RFC file, it must be * called by a name other than "ssh" or "Secure Shell". */ #include "platform.h" #include "buffer.h" #include "log.h" #include "hex_strings.h" /* Initializes the buffer structure. */ void buffer_init(Buffer *buffer) { const uint32_t len = 4096; buffer->alloc = 0; buffer->buf = malloc(len); buffer->alloc = len; buffer->offset = 0; buffer->end = 0; } /* Frees any memory used for the buffer. */ void buffer_free(Buffer *buffer) { if (buffer->alloc > 0) { memset(buffer->buf, 0, buffer->alloc); free(buffer->buf); buffer->buf = NULL; buffer->alloc = 0; } } /* * Clears any data from the buffer, making it empty. This does not actually * zero the memory. */ void buffer_clear(Buffer *buffer) { buffer->offset = 0; buffer->end = 0; } /* Appends data to the buffer, expanding it if necessary. */ void buffer_append(Buffer *buffer, const void *data, size_t len) { void *p; p = buffer_append_space(buffer, len); memcpy(p, data, len); } /* * Appends space to the buffer, expanding the buffer if necessary. This does * not actually copy the data into the buffer, but instead returns a pointer * to the allocated region. */ void * buffer_append_space(Buffer *buffer, size_t len) { size_t newlen; void *p; if (len > 0x100000) { Display(LOG_LEVEL_1, ELError, "buffer_append_space", GOGO_STR_LEN_NOT_SUPPORTED, len); exit(-1); } /* If the buffer is empty, start using it from the beginning. */ if (buffer->offset == buffer->end) { buffer->offset = 0; buffer->end = 0; } restart: /* If there is enough space to store all data, store it now. */ if (buffer->end + len < buffer->alloc) { p = buffer->buf + buffer->end; buffer->end += len; return p; } /* * If the buffer is quite empty, but all data is at the end, move the * data to the beginning and retry. */ if (buffer->offset > buffer->alloc / 2) { memmove(buffer->buf, buffer->buf + buffer->offset, buffer->end - buffer->offset); buffer->end -= buffer->offset; buffer->offset = 0; goto restart; } /* Increase the size of the buffer and retry. */ newlen = buffer->alloc + len + 32768; if (newlen > 0xa00000) { Display(LOG_LEVEL_1, ELError, "buffer_append_space", GOGO_STR_ALLOC_NOT_SUPPORTED, newlen); exit(-1); } buffer->buf = realloc(buffer->buf, newlen); buffer->alloc = newlen; goto restart; /* NOTREACHED */ } /* Returns the number of bytes of data in the buffer. */ size_t buffer_len(Buffer *buffer) { return buffer->end - buffer->offset; } /* Gets data from the beginning of the buffer. */ void buffer_get(Buffer *buffer, void *buf, uint32_t len) { if( len > buffer->end - buffer->offset ) { return; } memcpy(buf, buffer->buf + buffer->offset, len); buffer->offset += len; } /* Consumes the given number of bytes from the beginning of the buffer. */ void buffer_consume(Buffer *buffer, uint32_t bytes) { if( bytes > buffer->end - buffer->offset ) { return; } buffer->offset += bytes; } /* Consumes the given number of bytes from the end of the buffer. */ void buffer_consume_end(Buffer *buffer, uint32_t bytes) { if( bytes > buffer->end - buffer->offset ) { return; } buffer->end -= bytes; } /* Returns a pointer to the first used byte in the buffer. */ void * buffer_ptr(Buffer *buffer) { return buffer->buf + buffer->offset; } gogoc-1_2-RELEASE/gogoc-tsp/src/lib/cli.c0100644000000000000000000000714411345004301016457 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: cli.c,v 1.2 2010/03/07 20:12:49 carl Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ #include "platform.h" #include "gogoc_status.h" #include "config.h" #include "cli.h" #include "log.h" // Verbose #include "hex_strings.h" #include "lib.h" #if defined(WIN32) && !defined(WINCE) #include "console.h" #include "service.h" #endif // -------------------------------------------------------------------------- void PrintUsage( char *message ) { // Print the message, if a message was passed. if( message ) { printf(message); } // Print the usage. printf("usage: gogoc [options] [-f config_file] [-r seconds]\n" " where options are :\n" " -i gif interface to use for tunnel_v6v4\n" " -u interface to use for tunnel_v6udpv4\n" " -s interface to query to get IPv4 source address\n" " -f Read this config file instead of %s \n" " -r Retry after n seconds until success\n" " -b Boot mode: avoid reconnecting after failure\n" " -n Run in foreground\n" " -y Do not ask y/n questions\n" #if defined(WIN32) && !defined(WINCE) " --register install to run as service\n" " --unregister uninstall the service\n" #endif " -h help\n" " -? help\n\n", FileName); } // -------------------------------------------------------------------------- void ParseArguments(sint32_t argc, char *argv[], tConf *Conf) { sint32_t ch; #if defined(WIN32) && !defined(WINCE) // Platform HACK! service_parse_cli(argc, argv); #endif while( (ch = pal_getopt(argc, argv, "h?b?n?y?f:r:i:u:s:")) != -1 ) { switch( ch ) { case 'b': Conf->boot_mode = TRUE; break; case 'n': Conf->nodaemon = TRUE; break; case 'y': Conf->no_questions = TRUE; break; case 's': Conf->client_v4 = optarg; break; case 'i': Conf->if_tunnel_v6v4 = optarg; break; case 'u': Conf->if_tunnel_v6udpv4 = optarg; break; case 'f': FileName = optarg; break; case 'r': Conf->retry_delay = atoi(optarg); break; case '?': case 'h': PrintUsage(NULL); exit(0); default: PrintUsage("Error while parsing command line arguments"); exit(1); } } } // -------------------------------------------------------------------------- // Ask the question, return 0 if answer is N or n, 1 if answer is Y or y. // WINCE does not have console // This function is a travesty in a daemon or service // #if !defined(WINCE) sint32_t ask(char *question, ...) { va_list ap; char *buf; sint32_t c; sint32_t ret; #ifdef WIN32 enable_console_input(); #endif if ( (buf = malloc(sizeof(char) * 1024)) == NULL ) { Display(LOG_LEVEL_1, ELError, "ask", STR_GEN_MALLOC_ERROR); return 0; } va_start(ap, question); pal_vsnprintf(buf, 1024, question, ap); va_end(ap); ask_again: printf("%s? (Y/N) ", buf); c = fgetc(stdin); /* empty stdin */ fflush(stdin); c = tolower(c); if ((char)c == 'y') ret = 1; else if ((char)c == 'n') ret = 0; else goto ask_again; free(buf); #ifdef WIN32 disable_console_input(); #endif return ret; } #endif gogoc-1_2-RELEASE/gogoc-tsp/src/lib/cnfchk.c0100644000000000000000000000511711301544620017147 0ustar rootroot/* --------------------------------------------------------------------------- $Id: cnfchk.c,v 1.1 2009/11/20 16:53:36 jasminko Exp $ --------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT --------------------------------------------------------------------------- */ #include "platform.h" #include "cnfchk.h" #include "config.h" #include "log.h" #include "hex_strings.h" char *template_mappings[] = { "freebsd44", "freebsd", "freebsd4", "freebsd", "windows2000", "windows", "windows2003", "windows", "windowsXP", "windows", "solaris8", "solaris", NULL }; static int readfixwrite(char *, char *, char *, char *); /* This next function has to return -1 in any case - it exits the client and does nothing else. */ int tspFixConfig(void) { tConf t; char **tm = template_mappings; int worked = 0; Display(LOG_LEVEL_1, ELInfo, "tspFixConfig", GOGO_STR_VERIF_AND_FIX_CFG_FILE); memset(&t, 0, sizeof(tConf)); if (tspReadConfigFile(FileName, &t) != 0) { Display(LOG_LEVEL_1, ELError, "tspFixConfig", GOGO_STR_ERR_FROM_CFG_FILE, FileName); return -1; } if (t.template == NULL) { Display(LOG_LEVEL_1, ELError, "tspFixConfig", GOGO_STR_CANT_READ_TEMPLATE_FROM_CFG, FileName); return -1; } /* fix template names from older version */ while (*tm != NULL) { //Display(0, ELInfo, "tspFixConfig", "Checkout out %s, config is %s", *tm, t.template); if (strcmp(t.template, *tm) == 0) { Display(LOG_LEVEL_1, ELInfo, "tspFixConfig", GOGO_STR_WRONG_TEMPLATE_NAME, FileName, *tm, *(tm+1)); /* needs a replacement in the config file right here. rename the config file to .old and recreate one with the mapped template name. */ readfixwrite(FileName, "gogoc.conf.new", "template=", *(tm+1)); worked = 1; } tm+=2; } if (worked == 0) Display(LOG_LEVEL_1, ELInfo, "tspFixConfig", GOGO_STR_NOOP_CFG_VALID); return -1; } static int readfixwrite(char *in, char *out, char *pname, char *pvalue) { FILE *f_in, *f_out; char *line; line = (char *)malloc(256); if ( (f_in = fopen(in, "r")) == NULL) return 1; if ( (f_out = fopen(out, "w")) == NULL) return 1; while (fgets(line, 256, f_in) != NULL) { char buf[256]; strncpy(buf, line, strlen(pname)); if (strcmp(buf, pname) == 0) { memset(buf, 0, sizeof(buf)); strcat(buf, pname); strcat(buf, pvalue); strcat(buf, "\n"); fputs(buf, f_out); } else fputs(line, f_out); } fclose(f_in); fclose(f_out); unlink(in); rename(out, in); return 0; } gogoc-1_2-RELEASE/gogoc-tsp/src/lib/config.c0100644000000000000000000003054311345004301017154 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: config.c,v 1.3 2010/03/07 20:12:49 carl Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ /* Configuration file handling. */ #include "platform.h" #include "gogoc_status.h" #include "config.h" #include "log.h" #include "hex_strings.h" #include "cli.h" /* gogoCLIENT Configuration Subsystem */ #define TBOOLEAN_DECLARED #include #include #undef TBOOLEAN_DECLARED #if !(defined(WIN32) || defined(WINCE)) static syslog_facility_t syslog_facilities[] = { { STR_CONFIG_SLOG_FACILITY_USER, LOG_USER }, { STR_CONFIG_SLOG_FACILITY_LOCAL0, LOG_LOCAL0 }, { STR_CONFIG_SLOG_FACILITY_LOCAL1, LOG_LOCAL1 }, { STR_CONFIG_SLOG_FACILITY_LOCAL2, LOG_LOCAL2 }, { STR_CONFIG_SLOG_FACILITY_LOCAL3, LOG_LOCAL3 }, { STR_CONFIG_SLOG_FACILITY_LOCAL4, LOG_LOCAL4 }, { STR_CONFIG_SLOG_FACILITY_LOCAL5, LOG_LOCAL5 }, { STR_CONFIG_SLOG_FACILITY_LOCAL6, LOG_LOCAL6 }, { STR_CONFIG_SLOG_FACILITY_LOCAL7, LOG_LOCAL7 }, { NULL, 0 } }; /* ----------------------------------------------------------------------- */ /* Function: ParseSyslogFacility */ /* */ /* Description: */ /* Parse the configuration file's 'syslog_facility' directive. */ /* */ /* Arguments: */ /* pConf: tConf* [OUT], The global configuration object. */ /* facility: char* [IN], The input syslog facility. */ /* */ /* Return Values: */ /* 1 on error. */ /* 0 on successful completion. */ /* */ /* ----------------------------------------------------------------------- */ static sint32_t ParseSyslogFacility( tConf *pConf, char *facility ) { sint32_t index = 0; /* Loop through the known facility strings, and compare with the one we found. */ while( (syslog_facilities != NULL) && (syslog_facilities[index].string != NULL) ) { if (strcmp(facility, syslog_facilities[index].string) == 0) { pConf->syslog_facility = syslog_facilities[index].value; return 0; } index++; } return 1; } #endif /* ----------------------------------------------------------------------- */ /* Function: tspReadConfigFile */ /* */ /* Description: */ /* Will extract the configuration data from the configuration file. */ /* */ /* Arguments: */ /* szFile: char* [IN], The input configuration filename. */ /* pConf: tConf* [OUT], The global configuration object. */ /* */ /* Return Values: */ /* gogoc_err value. */ /* */ /* ----------------------------------------------------------------------- */ gogoc_status tspReadConfigFile( char* szFile, tConf* pConf ) { sint32_t i, nErrors, iRet; uint32_t* tErrors = NULL; char* szValue = NULL; /* Check input parameters. */ if( szFile == NULL || pConf == NULL ) { return make_status(CTX_CFGVALIDATION, ERR_INVAL_CFG_FILE); } /* --------------------------------------------------------------------- */ /* Read and load the configuration file. */ /* Will also perform thorough validation. */ /* --------------------------------------------------------------------- */ if( (iRet = initialize( szFile )) != 0 ) { if( iRet == -1 ) { /* Retrieve confguration error(s). */ get_config_errors( &nErrors, &tErrors ); for( i=0; iserver) ); if( strlen( pConf->server ) == 0 ) { free( pConf->server ); DirectErrorMessage( (char*)get_ui_string( GOGOC_UIS__G6V_SERVERMUSTBESPEC ) ); return make_status(CTX_CFGVALIDATION, ERR_INVAL_CFG_FILE); } get_gogoc_dir( &(pConf->tsp_dir) ); #ifdef DSLITE_SUPPORT get_dslite_server( &(pConf->dslite_server) ); get_dslite_client( &(pConf->dslite_client) ); #endif get_client_v4( &(pConf->client_v4) ); #ifdef V4V6_SUPPORT get_client_v6( &(pConf->client_v6) ); #endif /* V4V6_SUPPORT */ get_user_id( &(pConf->userid) ); get_passwd( &(pConf->passwd) ); get_auth_method( &(pConf->auth_method) ); get_host_type( &(pConf->host_type) ); get_template( &(pConf->template) ); get_if_tun_v6v4( &(pConf->if_tunnel_v6v4) ); get_if_tun_v6udpv4( &(pConf->if_tunnel_v6udpv4) ); #ifdef V4V6_SUPPORT get_if_tun_v4v6( &(pConf->if_tunnel_v4v6) ); #endif /* V4V6_SUPPORT */ get_tunnel_mode( &szValue ); if (strcmp(szValue, STR_CONFIG_TUNNELMODE_V6ANYV4) == 0) { pConf->tunnel_mode = V6ANYV4; } else if (strcmp(szValue, STR_CONFIG_TUNNELMODE_V6V4) == 0) { pConf->tunnel_mode = V6V4; } else if (strcmp(szValue, STR_CONFIG_TUNNELMODE_V6UDPV4) == 0) { pConf->tunnel_mode = V6UDPV4; } #ifdef V4V6_SUPPORT else if (strcmp(szValue, STR_CONFIG_TUNNELMODE_V4V6) == 0) { pConf->tunnel_mode = V4V6; } #endif /* V4V6_SUPPORT */ #ifdef DSLITE_SUPPORT else if (strcmp(szValue, STR_CONFIG_TUNNELMODE_DSLITE) == 0) { pConf->tunnel_mode = DSLITE; } #endif /* V4V6_SUPPORT */ free( szValue ); szValue = NULL; get_dns_server( &(pConf->dns_server) ); get_ifprefix( &(pConf->if_prefix) ); get_prefixlen( &(pConf->prefixlen) ); get_retry_delay( &(pConf->retry_delay) ); get_retry_delay_max( &(pConf->retry_delay_max) ); get_keepalive( &(pConf->keepalive) ); get_keepalive_interval( &(pConf->keepalive_interval) ); get_proxy_client( &(pConf->proxy_client) ); #if !(defined(WIN32) || defined(WINCE)) get_syslog_facility( &szValue ); ParseSyslogFacility( pConf, szValue ); free( szValue ); szValue = NULL; #endif get_log_filename( &(pConf->log_filename) ); get_log_rotation( &(pConf->log_rotation) ); get_log_rotation_sz( &(pConf->log_rotation_size) ); get_log_rotation_del( &(pConf->log_rotation_delete) ); get_log( STR_CONFIG_LOG_DESTINATION_STDERR, &(pConf->log_level_stderr) ); get_log( STR_CONFIG_LOG_DESTINATION_SYSLOG, &(pConf->log_level_syslog) ); get_log( STR_CONFIG_LOG_DESTINATION_CONSOLE, &(pConf->log_level_console) ); get_log( STR_CONFIG_LOG_DESTINATION_FILE, &(pConf->log_level_file) ); get_auto_retry_connect( &(pConf->auto_retry_connect) ); get_last_server_file( &(pConf->last_server_file) ); get_always_use_last_server( &(pConf->always_use_same_server) ); get_broker_list_file( &(pConf->broker_list_file) ); get_haccess_web_enabled( &(pConf->haccess_web_enabled) ); get_haccess_proxy_enabled( &(pConf->haccess_proxy_enabled) ); get_haccess_document_root( &(pConf->haccess_document_root) ); /* Close the gogoCLIENT configuration object. */ un_initialize(); /* Successful completion. */ return make_status(CTX_CFGVALIDATION, SUCCESS); } /* ----------------------------------------------------------------------- */ /* Function: tspInitialize */ /* */ /* Description: */ /* Initialize with default values, read configuration file and override */ /* defaults with config file values. */ /* */ /* Arguments: */ /* argc: char* [IN], Number of arguments passed on command line. */ /* argv: char*[] [IN], The command-line arguments. */ /* pConf: tConf* [OUT], The global configuration object. */ /* */ /* Return Values: */ /* gogoc_err value */ /* */ /* ----------------------------------------------------------------------- */ gogoc_status tspInitialize(sint32_t argc, char *argv[], tConf *pConf) { tConf CmdLine; gogoc_status status = STATUS_SUCCESS_INIT; const char* cszTemplDir = "template"; // Hard-coded parameters. Not configurable anymore. pConf->syslog = FALSE; pConf->protocol = pal_strdup( "default_route" ); pConf->routing_info = pal_strdup(""); /* --------------------------------------------------------------------- */ /* Read configuration data from the command-line arguments. */ /* --------------------------------------------------------------------- */ memset(&CmdLine, 0, sizeof(CmdLine)); if( argc > 1 ) { ParseArguments(argc, argv, &CmdLine); } /* --------------------------------------------------------------------- */ /* Read configuration data from the file. */ /* --------------------------------------------------------------------- */ status = tspReadConfigFile(FileName, pConf); if( status_number(status) != SUCCESS ) { return status; } /* --------------------------------------------------------------------- */ /* Override the config file with parameters from the command line. */ /* --------------------------------------------------------------------- */ if(CmdLine.if_tunnel_v6v4) pConf->if_tunnel_v6v4 = CmdLine.if_tunnel_v6v4; if(CmdLine.if_tunnel_v6udpv4) pConf->if_tunnel_v6udpv4 = CmdLine.if_tunnel_v6udpv4; #ifdef V4V6_SUPPORT if(CmdLine.if_tunnel_v4v6) pConf->if_tunnel_v4v6 = CmdLine.if_tunnel_v4v6; #endif /* V4V6_SUPPORT */ if(CmdLine.client_v4) pConf->client_v4 = CmdLine.client_v4; pConf->boot_mode = CmdLine.boot_mode; pConf->nodaemon = CmdLine.nodaemon; pConf->no_questions = CmdLine.no_questions; /* --------------------------------------------------------------------- */ /* Extrapolate directory in which template scripts are located. */ /* --------------------------------------------------------------------- */ if( strlen(pConf->tsp_dir) != 0 ) { TspHomeDir = pConf->tsp_dir; if( (ScriptDir = (char*)malloc( (size_t)(strlen(pConf->tsp_dir)+strlen(cszTemplDir)+2)) ) == NULL ) { DirectErrorMessage( STR_GEN_MALLOC_ERROR ); return make_status(CTX_CFGVALIDATION, ERR_MEMORY_STARVATION); } sprintf(ScriptDir, "%s%c%s", pConf->tsp_dir, DirSeparator, cszTemplDir); } else { if((ScriptDir = (char *)malloc((size_t)(strlen(TspHomeDir)+strlen(cszTemplDir)+2)))==NULL) { DirectErrorMessage( STR_GEN_MALLOC_ERROR ); return make_status(CTX_CFGVALIDATION, ERR_MEMORY_STARVATION); } sprintf(ScriptDir, "%s%c%s", TspHomeDir, DirSeparator, cszTemplDir); } return make_status(CTX_CFGVALIDATION, SUCCESS); } gogoc-1_2-RELEASE/gogoc-tsp/src/lib/deque.c0100644000000000000000000004447711301544621017033 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: deque.c,v 1.1 2009/11/20 16:53:37 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ /**************************************************************** * * File : DEQUE.c * * Author: Peter Yard [1993.01.02] -- 02 Jan 1993 * * Disclaimer: This code is released to the public domain. * * Description: * Generic double ended queue (Deque pronounced DEK) for handling * any data types, with sorting. * * By use of various functions in this module the caller * can create stacks, queues, lists, doubly linked lists, * sorted lists, indexed lists. All lists are dynamic. * * It is the responsibility of the caller to malloc and free * memory for insertion into the queue. A pointer to the object * is used so that not only can any data be used but various kinds * of data can be pushed on the same queue if one so wished e.g. * various length string literals mixed with pointers to structures * or integers etc. * * Enhancements: * A future improvement would be the option of multiple "cursors" * so that multiple locations could occur in the one queue to allow * placemarkers and additional flexibility. Perhaps even use queue * itself to have a list of cursors. * * Usage: * * /x init queue x/ * queue q; * Q_Init(&q); * * To create a stack : * * Q_PushHead(&q, &mydata1); /x push x/ * Q_PushHead(&q, &mydata2); * ..... * data_ptr = Q_PopHead(&q); /x pop x/ * ..... * data_ptr = Q_First(&q); /x top of stack x/ * * To create a FIFO: * * Q_PushHead(&q, &mydata1); * ..... * data_ptr = Q_PopTail(&q); * * To create a double list: * * data_ptr = Q_First(&q); * .... * data_ptr = Q_Next(&q); * data_ptr = Q_Last(&q); * if (Q_Empty(&q)) .... * ..... * data_ptr = Q_Previous(&q); * * To create a sorted list: * * Q_PushHead(&q, &mydata1); /x push x/ * Q_PushHead(&q, &mydata2); * ..... * if (!Q_Sort(&q, MyFunction)) * .. error .. * * /x fill in key field of mydata1. * * NB: Q_Find does linear search * x/ * * if (Q_Find(&q, &mydata1, MyFunction)) * { * /x found it, queue cursor now at correct record x/ * /x can retrieve with x/ * data_ptr = Q_Get(&q); * * /x alter data , write back with x/ * Q_Put(&q, data_ptr); * } * * /x Search with binary search x/ * if (Q_Seek(&q, &mydata, MyFunction)) * /x etc x/ * * ****************************************************************/ #include "pal.h" #include "deque.h" static void QuickSort(void *list[], int low, int high, int (*Comp)(const void *, const void *)); static int Q_BSearch(queue *q, void *key, int (*Comp)(const void *, const void *)); /* The index: a pointer to pointers */ static void **Q_index; static datanode **posn_index; /*** * ** function : Q_Init * ** purpose : Initialise queue object and pointers. * ** parameters : 'queue' pointer. * ** returns : True_ if init successful else False_ * ** comments : ***/ int Q_Init(queue *q) { q->head = q->tail = NULL; q->cursor = q->head; q->size = 0; q->sorted = False_; return True_; } /*** * ** function : Q_Start * ** purpose : tests if cursor is at head of queue * ** parameters : 'queue' pointer. * ** returns : boolean - True_ is at head else False_ * ** comments : * ***/ int Q_Start(queue *q) { return (q->cursor == q->head); } /*** * ** function : Q_End * ** purpose : boolean test if cursor at tail of queue * ** parameters : 'queue' pointer to test. * ** returns : True_ or False_ * ** comments : * ***/ int Q_End(queue *q) { return (q->cursor == q->tail); } /*** * ** function : Q_Empty * ** purpose : test if queue has nothing in it. * ** parameters : 'queue' pointer * ** returns : True_ if empty queue, else False_ * ** comments : * ***/ int Q_Empty(queue *q) { return (q->size == 0); } /*** * ** function : Q_Size * ** purpose : return the number of elements in the queue * ** parameters : queue pointer * ** returns : number of elements * ** comments : * ***/ int Q_Size(queue *q) { return q->size; } /*** * ** function : Q_First * ** purpose : position queue cursor to first element (head) of queue. * ** parameters : 'queue' pointer * ** returns : pointer to data at head. If queue is empty returns NULL * ** comments : * ***/ void *Q_First(queue *q) { if (Q_Empty(q)) return NULL; q->cursor = q->head; return q->cursor->data; } /*** * ** function : Q_Last * ** purpose : locate cursor at tail of queue. * ** parameters : 'queue' pointer * ** returns : pointer to data at tail , if queue empty returns NULL * ** comments : * ***/ void *Q_Last(queue *q) { if (Q_Empty(q)) return NULL; q->cursor = q->tail; return q->cursor->data; } /*** * ** function : Q_PushHead * ** purpose : put a data pointer at the head of the queue * ** parameters : 'queue' pointer, void pointer to the data. * ** returns : True_ if success else False_ if unable to push data. * ** comments : * ***/ int Q_PushHead(queue *q, void *d) { node *n = NULL; datanode *p; /* first entry - added by M. Zacho 990613 */ if (q->head == NULL) { q->head = malloc(sizeof(datanode)); if (q->head == NULL) return False_; } else { /* Peter's original code resumes */ q->head->prev = malloc(sizeof(datanode)); if (q->head->prev == NULL) return False_; n = q->head; p = q->head->prev; q->head = (node*)p; } q->head->prev = NULL; if (q->size == 0) { q->head->next = NULL; q->tail = q->head; } else q->head->next = (datanode*)n; q->head->data = d; q->size++; q->cursor = q->head; q->sorted = False_; return True_; } /*** * ** function : Q_PushTail * ** purpose : put a data element pointer at the tail of the queue * ** parameters : queue pointer, pointer to the data * ** returns : True_ if data pushed, False_ if data not inserted. * ** comments : * ***/ int Q_PushTail(queue *q, void *d) { node *p = NULL; datanode *n; /* first entry - added by M. Zacho 990613 */ if (q->tail == NULL) { q->tail = malloc(sizeof(datanode)); if (q->tail == NULL) return False_; } else { /* Peter's original code resumes */ q->tail->next = malloc(sizeof(datanode)); if (q->tail->next == NULL) return False_; p = q->tail; n = q->tail->next; q->tail = (node *)n; } if (q->size == 0) { q->tail->prev = NULL; q->head = q->tail; } else q->tail->prev = (datanode *)p; q->tail->next = NULL; q->tail->data = d; q->cursor = q->tail; q->size++; q->sorted = False_; return True_; } /*** * ** function : Q_PopHead * ** purpose : remove and return the top element at the head of the * queue. * ** parameters : queue pointer * ** returns : pointer to data element or NULL if queue is empty. * ** comments : * ***/ void *Q_PopHead(queue *q) { datanode *n; void *d; if (Q_Empty(q)) return NULL; d = q->head->data; n = q->head->next; free(q->head); q->size--; if (q->size == 0) q->head = q->tail = q->cursor = NULL; else { q->head = (node *)n; q->head->prev = NULL; q->cursor = q->head; } q->sorted = False_; return d; } /*** * ** function : Q_PopTail * ** purpose : remove element from tail of queue and return data. * ** parameters : queue pointer * ** returns : pointer to data element that was at tail. NULL if queue * empty. * ** comments : * ***/ void *Q_PopTail(queue *q) { datanode *p; void *d; if (Q_Empty(q)) return NULL; d = q->tail->data; p = q->tail->prev; free(q->tail); q->size--; if (q->size == 0) q->head = q->tail = q->cursor = NULL; else { q->tail = (node *)p; q->tail->next = NULL; q->cursor = q->tail; } q->sorted = False_; return d; } /*** * ** function : Q_Next * ** purpose : Move to the next element in the queue without popping * ** parameters : queue pointer. * ** returns : pointer to data element of new element or NULL if end * of the queue. * ** comments : This uses the cursor for the current position. Q_Next * only moves in the direction from the head of the queue * to the tail. ***/ void *Q_Next(queue *q) { if (q->cursor->next == NULL) return NULL; q->cursor = (node *)q->cursor->next; return q->cursor->data ; } /*** * ** function : Q_Previous * ** purpose : Opposite of Q_Next. Move to next element closer to the * head of the queue. * ** parameters : pointer to queue * ** returns : pointer to data of new element else NULL if queue empty * ** comments : Makes cursor move towards the head of the queue. * ***/ void *Q_Previous(queue *q) { if (q->cursor->prev == NULL) return NULL; q->cursor = (node *)q->cursor->prev; return q->cursor->data; } /*** * ** function : Q_DelCur * ** purpose : Delete the current queue element as pointed to by * the cursor. * ** parameters : queue pointer * ** returns : pointer to data element. * ** comments : WARNING! It is the responsibility of the caller to * free any memory. Queue cannot distinguish between * pointers to literals and malloced memory. * ***/ void *Q_DelCur(queue *q) { void *d; datanode *n, *p; if (q->cursor == NULL) return NULL; if (q->cursor == q->head) return Q_PopHead(q); if (q->cursor == q->tail) return Q_PopTail(q); n = q->cursor->next; p = q->cursor->prev; d = q->cursor->data; free(q->cursor); if (p != NULL) q->cursor = p; else q->cursor = n; q->size--; q->sorted = False_; return d; } /*** * ** function : Q_Get * ** purpose : get the pointer to the data at the cursor location * ** parameters : queue pointer * ** returns : data element pointer * ** comments : * ***/ void *Q_Get(queue *q) { if (q->cursor == NULL) return NULL; return q->cursor->data; } /*** * ** function : Q_Put * ** purpose : replace pointer to data with new pointer to data. * ** parameters : queue pointer, data pointer * ** returns : boolean- True_ if successful, False_ if cursor at NULL * ** comments : * ***/ int Q_Put(queue *q, void *data) { if (q->cursor == NULL) return False_; q->cursor->data = data; return True_; } /*** * ** function : Q_Find * ** purpose : Linear search of queue for match with key in *data * ** parameters : queue pointer q, data pointer with data containing key * comparison function here called Comp. * ** returns : True_ if found , False_ if not in queue. * ** comments : Useful for small queues that are constantly changing * and would otherwise need constant sorting with the * Q_Seek function. * For description of Comp see Q_Sort. * Queue cursor left on position found item else at end. * ***/ int Q_Find(queue *q, void *data, int (*Comp)(const void *, const void *)) { void *d; d = Q_First(q); do { if (Comp(d, data) == 0) return True_; d = Q_Next(q); } while (!Q_End(q)); if (Comp(d, data) == 0) return True_; return False_; } /*======== Sorted Queue and Index functions ========= */ static void QuickSort(void *list[], int low, int high, int (*Comp)(const void *, const void *)) { int flag = 1, i, j; void *key, *temp; if (low < high) { i = low; j = high + 1; key = list[ low ]; while (flag) { i++; while (Comp(list[i], key) < 0) i++; j--; while (Comp(list[j], key) > 0) j--; if (i < j) { temp = list[i]; list[i] = list[j]; list[j] = temp; } else flag = 0; } temp = list[low]; list[low] = list[j]; list[j] = temp; QuickSort(list, low, j-1, Comp); QuickSort(list, j+1, high, Comp); } } /*** * ** function : Q_Sort * ** purpose : sort the queue and allow index style access. * ** parameters : queue pointer, comparison function compatible with * with 'qsort'. * ** returns : True_ if sort succeeded. False_ if error occurred. * ** comments : Comp function supplied by caller must return * -1 if data1 < data2 * 0 if data1 == data2 * +1 if data1 > data2 * * for Comp(data1, data2) * * If queue is already sorted it frees the memory of the * old index and starts again. * ***/ int Q_Sort(queue *q, int (*Comp)(const void *, const void *)) { int i; void *d; datanode *dn; /* if already sorted free memory for tag array */ if (q->sorted) { free(Q_index); free(posn_index); q->sorted = False_; } /* Now allocate memory of array, array of pointers */ Q_index = malloc(q->size * sizeof(q->cursor->data)); if (Q_index == NULL) return False_; posn_index = malloc(q->size * sizeof(q->cursor)); if (posn_index == NULL) { free(Q_index); return False_; } /* Walk queue putting pointers into array */ d = Q_First(q); for (i=0; i < q->size; i++) { Q_index[i] = d; posn_index[i] = q->cursor; d = Q_Next(q); } /* Now sort the index */ QuickSort(Q_index, 0, q->size - 1, Comp); /* Rearrange the actual queue into correct order */ dn = q->head; i = 0; while (dn != NULL) { dn->data = Q_index[i++]; dn = dn->next; } /* Re-position to original element */ if (d != NULL) Q_Find(q, d, Comp); else Q_First(q); q->sorted = True_; return True_; } /*** * ** function : Q_BSearch * ** purpose : binary search of queue index for node containing key * ** parameters : queue pointer 'q', data pointer of key 'key', * Comp comparison function. * ** returns : integer index into array of node pointers, * or -1 if not found. * ** comments : see Q_Sort for description of 'Comp' function. * ***/ static int Q_BSearch( queue *q, void *key, int (*Comp)(const void *, const void*)) { int low, mid, hi, val; low = 0; hi = q->size - 1; while (low <= hi) { mid = (low + hi) / 2; val = Comp(key, Q_index[ mid ]); if (val < 0) hi = mid - 1; else if (val > 0) low = mid + 1; else /* Success */ return mid; } /* Not Found */ return -1; } /*** * ** function : Q_Seek * ** purpose : use index to locate data according to key in 'data' * ** parameters : queue pointer 'q', data pointer 'data', Comp comparison * function. * ** returns : pointer to data or NULL if could not find it or could * not sort queue. * ** comments : see Q_Sort for description of 'Comp' function. * ***/ void *Q_Seek(queue *q, void *data, int (*Comp)(const void *, const void *)) { int idx; if (!q->sorted) { if (!Q_Sort(q, Comp)) return NULL; } idx = Q_BSearch(q, data, Comp); if (idx < 0) return NULL; q->cursor = posn_index[idx]; return Q_index[idx]; } /*** * ** function : Q_Insert * ** purpose : Insert an element into an indexed queue * ** parameters : queue pointer 'q', data pointer 'data', Comp comparison * function. * ** returns : pointer to data or NULL if could not find it or could * not sort queue. * ** comments : see Q_Sort for description of 'Comp' function. * WARNING! This code can be very slow since each new * element means a new Q_Sort. Should only be used for * the insertion of the odd element ,not the piecemeal * building of an entire queue. ***/ int Q_Insert(queue *q, void *data, int (*Comp)(const void *, const void *)) { Q_PushHead(q, data); if (!Q_Sort(q, Comp)) return False_; return True_; } gogoc-1_2-RELEASE/gogoc-tsp/src/lib/dns.c0100644000000000000000000001673211301544621016505 0ustar rootroot/* ----------------------------------------------------------------------------- dns.c - Dynamic DNS update library ----------------------------------------------------------------------------- $Id: dns.c,v 1.1 2009/11/20 16:53:37 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ---------------------------------------------------------------------------------- */ #include "platform.h" #include "net.h" #include "net_tcp6.h" #include "dns.h" #define ADD16(b,s) {\ register uint16_t *bb = (uint16_t *) b; \ *bb = htons(s); \ b += DNS16SZ; \ } #define ADD32(b,s) {\ register uint32_t *bb = (uint32_t *) b; \ *bb = htonl(s); \ b += DNS32SZ; \ } #define GET16(b,s) {\ s = ntohs(*((uint16_t *) b)); \ b += DNS16SZ; \ } #define GET32(b,s) {\ s = ntohl(*((uint32_t *) b)); \ b += DNS32SZ; \ } /* * Generate a DNS id */ static uint16_t DNSGenerateID(void) { static uint16_t id = 0; struct timeval now; pal_gettimeofday(&now); if (!id) id = (uint16_t) (0xffff & (now.tv_sec ^ now.tv_usec ^ pal_getpid())); else id += 1 + (uint16_t)(now.tv_usec % 263); return id; } /* * Encode a DNS name in a DNS binary format * * *Pos_pp is the location inside the DNS message buffer where the name * must be written. At the end, it's updated to point to the location right * after the written name. * * Offset is the compression offset to use. A value of zero indicates no * compression. */ static tDNSRCode DNSNameEncode(char **Pos_pp, char *Name, uint16_t Offset) { char *Pos_p; char *Name_p; char *Dot_p; size_t Len; if (NULL == Pos_pp || NULL == *Pos_pp || NULL == Name || strlen(Name) > DNS_NAME_SIZE) return DNS_RCODE_FORMERR; Pos_p = *Pos_pp; Name_p = Name; while ('\0' != *Name_p) { /* Copy label */ Dot_p = strchr(Name_p, '.'); Len = (NULL != Dot_p) ? (size_t) (Dot_p - Name_p) : strlen(Name_p); if (Len) { /* Length of the label */ *Pos_p++ = (uint8_t) Len; /* Label */ memcpy(Pos_p, Name_p, Len); Pos_p += Len; Name_p += Len; } if (NULL != Dot_p) Name_p++; /* Skip dot */ } if (Offset) { /* Compression offset */ ADD16(Pos_p, 0xc000 | Offset); } else *Pos_p++ = 0; *Pos_pp = Pos_p; return DNS_RCODE_NOERROR; } /* * Create a DNS message. * * If AAAA is non NULL: * - create a AAAA update message for Name.Domain with value AAAA. * * If AAAA is NULL: * - create an update message for the deletion of all RRsets that belongs * to Name.Domain. * * *Len_p is set with the length of the created message. * */ static tDNSRCode DNSMessageCreate(char *Buffer, uint16_t DNSid, char *Domain, char *Name, uint32_t TTL, char *AAAA, size_t *Len_p) { char *p; size_t Domain_len; size_t Name_len; struct in6_addr AAAA_addr; struct in6_addr *AAAA_addr_p = NULL; tDNSRCode ret; if (NULL == Buffer || NULL == Name || NULL == Domain || NULL == Len_p) return DNS_RCODE_FORMERR; Name_len = strlen(Name); Domain_len = strlen(Domain); /* Validate Name.Domain length */ if (Name_len + 1 + Domain_len > DNS_NAME_SIZE || Name_len > DNS_LABEL_SIZE) return DNS_RCODE_FORMERR; /* Convert AAAA name */ if (NULL != AAAA) { AAAA_addr_p = NetText2Addr6(AAAA, &AAAA_addr); if (NULL == AAAA_addr_p) return DNS_RCODE_FORMERR; } /* Skip TCPMSGLENGTH (16 bits) - message length no known yet */ p = Buffer + DNS16SZ; /* DNS id (16 bits) */ ADD16(p, DNSid); /* * Fields QR (1 bit) = 0, Opcode (4 bits) = UPDATE, * Reserved (7 bits) = 0, RCode (4 bits) = 0. */ ADD16(p, DNS_OPCODE_UPDATE << 11); /* Zone count (16 bits) = 1 */ ADD16(p, 1); /* Prerequisite count (16 bits) = 0 */ ADD16(p, 0); /* Update count (16 bits) = 1 */ ADD16(p, 1); /* Additionnal data count (16 bits) = 0 */ ADD16(p, 0); /* * ZONE section */ ret = DNSNameEncode(&p, Domain, 0); /* ZNAME */ if (DNS_RCODE_NOERROR != ret) return ret; ADD16(p, DNS_TYPE_SOA); /* ZTYPE */ ADD16(p, DNS_CLASS_IN); /* CLASS */ /* * Ressource Record Section * * For the RRNAME, DNS compression is used. * DNS_HEADER_SIZE is the offset of the Zone Name. */ ret = DNSNameEncode(&p, Name, DNS_HEADER_SIZE); /* RRNAME */ if (DNS_RCODE_NOERROR != ret) return ret; if ( NULL != AAAA_addr_p) { /* Addition of AAAA record */ ADD16(p, DNS_TYPE_AAAA); /* RRTYPE */ ADD16(p, DNS_CLASS_IN); /* RRCLASS */ ADD32(p, TTL); /* RRTTL */ ADD16(p, DNS_TYPE_AAAA_SIZE); /* RRDLENGTH */ memcpy(p, AAAA_addr_p, DNS_TYPE_AAAA_SIZE); /* RRDATA */ p += DNS_TYPE_AAAA_SIZE; } else { /* Deletion of all RRSETS */ ADD16(p, DNS_TYPE_ANY); /* RRTYPE */ ADD16(p, DNS_CLASS_ANY); /* RRCLASS */ ADD32(p, 0); /* RRTTL */ ADD16(p, 0); /* RRDLENGTH */ } /* Update *Len_p and the TCPMSGLENGTH field */ *Len_p = p - Buffer; p = Buffer; ADD16(p, (u_short)(*Len_p) - DNS16SZ); return DNS_RCODE_NOERROR; } /* * Perform a DNS update for Name.Domain. * * A non NULL value for AAAA indicates the addition of a AAAA record * with value AAAA. * * A NULL value indicated the deletion of all Ressource Records associated * with Name.Domain. */ static tDNSRCode DNSUpdate(pal_socket_t Socket, char *Name, char *Domain, char *AAAA) { uint16_t DNSid; uint16_t DNSidReply; uint16_t Header; uint16_t QR; uint16_t OPCode; uint16_t RCode; tDNSRCode ret; char Buffer[DNS_BUFFER_SIZE]; size_t Len; char *p; /* Create DNS id */ DNSid = DNSGenerateID(); /* Create DNS Update message */ if (DNS_RCODE_NOERROR != (ret = DNSMessageCreate(Buffer, DNSid, Domain, Name, DNS_DEFAULT_TTL, AAAA, &Len))) return ret; /* Send request to server */ if (NetTCP6Write(Socket, Buffer, (sint32_t)Len) != (sint32_t)Len) return DNS_RCODE_SERVFAIL; /* Read response */ Len = NetTCP6Read(Socket, Buffer, sizeof(Buffer)); /* * We expect the response to be sent in one packet. * To be forward compatible, only the following is validated: * - response must be at least the size of the TCPMSGLENGTH field * plus the DNS header. * - DNSid must match. * - QR field must be set to 1. * - Opcode must be UPDATE (5). */ if (Len < DNS16SZ + DNS_HEADER_SIZE) return DNS_RCODE_SERVFAIL; /* * Skip TCPMSGLENGTH, in the future we might have answer larger than * the buffer size. */ p = Buffer + DNS16SZ; /* Extract DNSid */ GET16(p, DNSidReply); /* Extract QR, Opcode, and Return Code */ GET16(p, Header); QR = (Header & 0x8000) >> 15; OPCode = (Header & 0x7800) >> 11; RCode = Header & 0x000f; /* Validation */ if (DNSid != DNSidReply || QR != 1 || OPCode != DNS_OPCODE_UPDATE) return DNS_RCODE_SERVFAIL; /* Return Return Code */ return (tDNSRCode) RCode; } /* * Start a DNS update session. */ pal_socket_t DNSUpdateConnect(char *Server) { pal_socket_t sock; if( NetTCP6Connect( &sock, Server, DNS_UPDATE_PORT) == 0 ) return sock; return -1; } /* * Close DNS update session. */ sint32_t DNSUpdateClose(pal_socket_t Socket) { return NetTCP6Close(Socket); } /* * Perform a DNS update to add a AAAA record for Name.Domain with value AAAA. */ tDNSRCode DNSUpdateAddAAAA(pal_socket_t Socket, char *Name, char *Domain, char *AAAA) { return DNSUpdate(Socket, Name, Domain, AAAA); } /* * Perform a DNS update to delete all Ressource Records that belongs * to Name.Domain. */ tDNSRCode DNSUpdateDelRRSets(pal_socket_t Socket, char *Name, char *Domain) { return DNSUpdate(Socket, Name, Domain, NULL); } gogoc-1_2-RELEASE/gogoc-tsp/src/lib/lib.c0100644000000000000000000001015411301544621016457 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: lib.c,v 1.1 2009/11/20 16:53:37 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ #include "platform.h" #include "hex_strings.h" #include "lib.h" // these must be kept in sync with errors.h char *TspErrorCodesArray[] = { "NO_ERROR", "NO_ERROR_SHOW_HELP", "TSP_ERROR", "SOCKET_ERROR", "INTERFACE_SETUP_FAILED", "KEEPALIVE_TIMEOUT", "KEEPALIVE_ERROR", "TUNNEL_ERROR", "TSP_VERSION_ERROR", "AUTHENTICATION_ERROR", "LEASE_EXPIRED", "SERVER_SIDE_ERROR", "INVALID_ARGUMENTS", "MEMORY_ERROR", "INVALID_SERVER", "INVALID_CONFIG_FILE", "INVALID_CLIENT_IPV4", "INVALID_CLIENT_IPV6", "LOGGING_CONFIGURATION_ERROR", "BROKER_REDIRECTION", "BROKER_REDIRECTION_ERROR", "SOCKET_ERROR_CANT_CONNECT", "INITIALIZATION_ERROR", #ifdef HACCESS "HACCESS_INITIALIZATION_ERROR", "HACCESS_SETUP_ERROR", "HACCESS_EXPOSE_DEVICES_ERROR", #endif NULL }; // Prototype. sint32_t GetSizeOfNullTerminatedArray( char ** ); /* Check if all characters in Value are within AllowedChars list. */ sint32_t IsAll( char *AllowedChars, char *Value ) { if( Value ) { for(;*Value; Value++) { if(strchr(AllowedChars, *Value) == NULL) return 0; } } else { return 0; } return 1; } /* Check to see if there is a value in the char * If not, then the value was not supplied. */ sint32_t IsPresent( char *Value ) { if( Value && pal_strlen(Value) ) return 1; return 0; } /* This next function is very dangerous. If you can call be certain the array finished by NULL or it will do bad things. */ sint32_t GetSizeOfNullTerminatedArray(char **a) { sint32_t i; for (i = 0;;i++) { if (a[i] == NULL) return i; } // unreachable code. } char *tspGetErrorByCode(sint32_t code) { static char buf[1024]; sint32_t i; i = GetSizeOfNullTerminatedArray(TspErrorCodesArray); if (code < i && code > -1) return TspErrorCodesArray[code]; else pal_snprintf(buf, sizeof(buf), GOGO_STR_NOT_DEF_AS_CLIENT_ERROR, code); return buf; } /* Function: IsAddressInPrefix Verifies if a given IPv6 address is part of the given IPv6 prefix. Returns 0 if address is part of prefix. Returns 1 if address is NOT part of prefix. Returns -1 if either address or prefix is an invalid IPv6 address. */ sint32_t IsAddressInPrefix( const char* address, const char* prefix, const sint16_t prefix_len ) { short compare_bytes=0; short compare_bits =0; sint32_t ret_code=1; struct addrinfo hints, *res_address=NULL, *res_prefix=NULL; struct in6_addr *in6_address, *in6_prefix; memset( &hints, 0x00, sizeof(struct addrinfo) ); hints.ai_family = AF_INET6; while( 1 ) { if( (prefix_len > 0 && prefix_len <= 128) && (address != NULL && prefix != NULL ) && (getaddrinfo( address, NULL, &hints, &res_address ) != 0 || getaddrinfo( prefix, NULL, &hints, &res_prefix ) != 0) ) { ret_code = -1; break; } if( res_address == NULL || res_prefix == NULL ) { ret_code = -1; break; } in6_address = &((struct sockaddr_in6*)(res_address->ai_addr))->sin6_addr; in6_prefix = &((struct sockaddr_in6*)(res_prefix->ai_addr))->sin6_addr; /* Compute how many bytes and bits to compare */ compare_bytes = prefix_len / 8; compare_bits = prefix_len % 8; /* Compare the bytes of address and prefix */ if( memcmp( in6_address, in6_prefix, compare_bytes ) != 0 ) break; /* Compare the bits */ if( compare_bits > 0 ) if( (in6_address->s6_addr[compare_bytes] >> compare_bits) != (in6_prefix->s6_addr[compare_bytes] >> compare_bits) ) break; /* address is part of prefix */ ret_code = 0; break; } /* Free memory used. */ if( res_address ) freeaddrinfo( res_address ); if( res_prefix ) freeaddrinfo( res_prefix ); return ret_code; } gogoc-1_2-RELEASE/gogoc-tsp/src/lib/log.c0100644000000000000000000006000111301544621016466 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: log.c,v 1.1 2009/11/20 16:53:37 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ #include "platform.h" #include "gogoc_status.h" #include "log.h" #include "config.h" #include "buffer.h" #include "hex_strings.h" static FILE *Logfp; static tLogConfiguration *LogConfiguration = NULL; static Buffer LogBuffer; int LogMutexInitialized = 0; pal_cs_t logMutex; // -------------------------------------------------------------------------- // Returns a printable character representing a severity level. // char SeverityToChar( const enum tSeverityLevel sLvl ) { switch( sLvl ) { case ELError: return 'E'; case ELWarning: return 'W'; case ELInfo: return 'I'; case ELDebug: return 'D'; } // Never reached return 'E'; } // -------------------------------------------------------------------------- /* Generate a name for the backed up ('rotated') log file. */ static int GetLogFileBackupName(char *filename, char *backupname) { time_t t; struct tm *tm; char smallname[LOG_FILENAME_MAX_LENGTH]; char extension[LOG_FILENAME_MAX_LENGTH]; char *lastdot; if ((filename == NULL) || (backupname == NULL)) { return 1; } /* Create a timestamp with the current date and time. */ if ((t = pal_time(NULL)) == (time_t)-1) { return 1; } if ((tm = pal_localtime(&t)) == NULL) { return 1; } memset(smallname, 0, LOG_FILENAME_MAX_LENGTH); memset(extension, 0, LOG_FILENAME_MAX_LENGTH); /* Find the last dot, which should be where the extension starts. */ lastdot = strrchr(filename, '.'); /* If we find an extension, split the filename in two */ if (lastdot != NULL) { strncpy(smallname, filename, lastdot - filename); strncpy(extension, lastdot, pal_strlen(lastdot)); pal_snprintf(backupname, LOG_FILENAME_MAX_LENGTH, "%s.%04d%02d%02d%02d%02d%02d%s", smallname, tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, extension); } else { pal_snprintf(backupname, LOG_FILENAME_MAX_LENGTH, "%s.%04d%02d%02d%02d%02d%02d", filename, tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); } return 0; } // -------------------------------------------------------------------------- /* Copy the original log file to the backup ('rotated') file. */ static int CopyLogFileToBackup(char *filename, char *backupname) { FILE *from, *to; char buffer[MAX_LOG_LINE_LENGTH]; if ((filename == NULL) || (backupname == NULL)) { return 1; } /* Open the source and destination files. */ if ((from = fopen(filename, "r")) == NULL) { return 1; } if ((to = fopen(backupname, "w+")) == NULL) { fclose(from); return 1; } /* Loop, reading line after line from the source file. */ while (fgets(buffer, MAX_LOG_LINE_LENGTH, from)) { /* Copy each read line to the destination file. */ if (fputs(buffer, to) == EOF) { fclose(from); fclose(to); return 1; } } /* Check if we stopped looping because something went wrong. */ if (!feof(from)) { return 1; } /* Close the source and destination files. */ fclose(from); fclose(to); return 0; } // -------------------------------------------------------------------------- /* A chance to do something before the log file is closed and */ /* rotation to the backup file occurs. */ static int RotationPendingHook() { time_t t; struct tm *tm; char concat_buffer[MAX_LOG_LINE_LENGTH]; /* Get a timestamp to prepend to the message */ if ((t = pal_time(NULL)) == (time_t)-1) { return 1; } if ((tm = pal_localtime(&t)) == NULL) { return 1; } /* Concatenate the timestamp and the message. */ pal_snprintf(concat_buffer, sizeof(concat_buffer), "%04d/%02d/%02d %02d:%02d:%02d %s: %s\n", (tm->tm_year+1900), (tm->tm_mon+1), tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, ((LogConfiguration == NULL) || (LogConfiguration->identity == NULL)) ? LOG_IDENTITY : LogConfiguration->identity, GOGO_STR_MESSAGE_ROTATING); /* Try to write to the open log file, if any. */ if (Logfp != NULL) { if (fprintf(Logfp, "%s", concat_buffer) < 0) { return 1; } else { fflush(Logfp); return 0; } } else { return 1; } } // -------------------------------------------------------------------------- /* Rotate the log file. This basically means moving the file to a */ /* new name, and continuing to write to the same filename but with the */ /* previous contents gone. */ static int RotateLogFile( char *filename, int max_size, char *log_line ) { char backup_file_name[LOG_FILENAME_MAX_LENGTH + 1]; size_t delta = 0; long pos; /* Make sure there's a valid file pointer. */ if (Logfp == NULL) { return 1; } /* Make sure there's a file name. */ if (filename == NULL) { // [Temp removal] DirectErrorMessage(GOGO_STR_CANT_ROTATE_LOG_NO_FILENAME); return 1; } /* Flush to make sure everything is in sync. */ if (fflush(Logfp) != 0) { // [Temp removal] DirectErrorMessage(GOGO_STR_CANT_ROTATE_LOG_CANT_FLUSH); return 1; } /* Stat the file to get its size. */ pos = ftell(Logfp); if( pos == -1 ) { // An error occurred. return 1; } /* Determine the size of what we want to add to the file. */ if (log_line != NULL) { delta = pal_strlen(log_line); } /* If we're going to blow the limit... */ if ((int)(pos + delta) >= (max_size * 1024)) { /* Need to do something before we close the file for rotation? */ if (RotationPendingHook() != 0) { // Nothing for now } /* Close the file. */ fclose(Logfp); /* If we're configured to delete rotated logs, skip this step. */ if( LogConfiguration->delete_rotated_log == FALSE ) { /* Get a file name to save the current file under. */ if (GetLogFileBackupName(filename, backup_file_name) != 0) { // [Temp removal] DirectErrorMessage(GOGO_STR_CANT_ROTATE_LOG_BACKUP_NAME); return 1; } /* Copy the current contents to that backup file. */ if (CopyLogFileToBackup(filename, backup_file_name) != 0) { // [Temp removal] DirectErrorMessage(GOGO_STR_CANT_ROTATE_LOG_CANT_COPY); return 1; } } /* Reopen the current file, and start from scratch. */ if ((Logfp = fopen(filename, "w")) == NULL) { // [Temp removal] DirectErrorMessage(GOGO_STR_CANT_ROTATE_LOG_CANT_OPEN_NEW); return 1; } } return 0; } // -------------------------------------------------------------------------- /* Send a message to syslog. */ static int LogToSyslog(int VerboseLevel, enum tSeverityLevel SeverityLvl, const char *FunctionName, char *Format, ...) { va_list argp; char buffer[MAX_LOG_LINE_LENGTH]; char line_to_log[MAX_LOG_LINE_LENGTH]; va_start(argp, Format); pal_vsnprintf(line_to_log, sizeof(line_to_log), Format, argp); va_end(argp); /* Store what we want to send to syslog in a buffer, prepending */ /* the function name if it's a debug build. */ #if defined(_DEBUG) || defined(DEBUG) pal_snprintf(buffer, sizeof(buffer), " %s: %s", FunctionName, line_to_log); #else pal_snprintf(buffer, sizeof(buffer), "%s", line_to_log); #endif /* Send the message to syslog using the platform-specific code. */ /* Made this a switch case in case we want to do more stuff based */ /* on the log level in the future. */ switch( SeverityLvl ) { case ELError: pal_syslog(LOG_ERR, buffer); break; case ELWarning: pal_syslog(ELWarning, buffer); break; case ELInfo: case ELDebug: pal_syslog(LOG_DEBUG, buffer); break; } return 0; } // -------------------------------------------------------------------------- /* Dump a line of log that was stored in a buffer to file. */ static int LogBufferLineToFile(char *LogLine, tLogConfiguration *configuration, int *OutputBufferChars) { char buffer[MAX_LOG_LINE_LENGTH]; int output_chars; /* No configuration is bad. */ if (configuration == NULL) { // [Temp removal] DirectErrorMessage(GOGO_STR_NO_CONFIG_CANNOT_LOG_TO_FILE); *OutputBufferChars = 0; return 1; } /* No log filename in the configuration is bad. */ if (configuration->log_filename == NULL) { // [Temp removal] DirectErrorMessage(GOGO_STR_NO_LOG_FILENAME_IN_CONFIG); *OutputBufferChars = 0; return 1; } /* A closed logging file is bad. */ if (Logfp == NULL) { // [Temp removal] DirectErrorMessage(GOGO_STR_LOG_FILE_CLOSED, configuration->log_filename); *OutputBufferChars = 0; return 1; } /* Trying to dump nothing is bad. */ if (LogLine == NULL) { *OutputBufferChars = 0; return 1; } /* Write to a local temporary buffer */ output_chars = pal_snprintf(buffer, sizeof(buffer), "%s", LogLine); /* Rotate the log file (if needed) before we write this new line. */ if (configuration->log_rotation == TRUE) { if (RotateLogFile(configuration->log_filename, configuration->log_rotation_size, buffer) != 0) { // [Temp removal] DirectErrorMessage(GOGO_STR_ERR_ROTATING_LOG_FILE); } } /* Write the contents of the local temporary buffer to the log file. */ if (fprintf(Logfp, "%s", buffer) < 0) { // [Temp removal] DirectErrorMessage(GOGO_STR_CANT_FPRINTF_TO_LOG); *OutputBufferChars = 0; return 1; } /* Flush to make sure everything is in the file. */ if (fflush(Logfp) != 0) { *OutputBufferChars = 0; return 1; } *OutputBufferChars = output_chars; return 0; } // -------------------------------------------------------------------------- /* Write a log message to the log file. */ static int LogToFile(int buffer, enum tSeverityLevel SeverityLvl, const char *FunctionName, char *Format, ...) { va_list argp; time_t t; struct tm *tm; char *s1, *s2; size_t i, j; char line_to_log[MAX_LOG_LINE_LENGTH]; char temp_buffer[MAX_LOG_LINE_LENGTH]; /* We don't want to use the temporary file logging buffer, but we don't */ /* have an open file. That won't work. */ if( (Logfp == NULL) && (buffer == 0) ) { return 1; } va_start(argp, Format); pal_vsnprintf(line_to_log, sizeof(line_to_log), Format, argp); va_end(argp); /* Get a timestamp to prepend to the message */ t = pal_time(NULL); if( t == (time_t)-1 ) { return 1; } tm = pal_localtime(&t); if( tm == NULL ) { return 1; } i = pal_strlen(line_to_log); s1 = s2 = malloc(i + 1); if( s1 == NULL ) { return 1; } /* Remove EOL characters from the message */ for( j = 0;j < i; j++ ) { if( line_to_log[j] != '\r' && line_to_log[j] != '\n' ) { *s1++ = line_to_log[j]; } } *s1++ = '\0'; /* Concatenate everything into one single local buffer. */ pal_snprintf(temp_buffer, sizeof(temp_buffer), #if defined(_DEBUG) || defined(DEBUG) "%04d/%02d/%02d %02d:%02d:%02d %c %s: %s: %s\n", #else "%04d/%02d/%02d %02d:%02d:%02d %c %s: %s\n", #endif (tm->tm_year+1900), (tm->tm_mon+1), tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, SeverityToChar( SeverityLvl ), LogConfiguration->identity == NULL ? "" : LogConfiguration->identity, #if defined(_DEBUG) || defined(DEBUG) FunctionName == NULL ? "" : FunctionName, #endif s2 ); free(s2); if( buffer != 0 ) { /* If we're using the log file buffer (logging to file, but we don't */ /* know the file name yet), add the message to the buffer. */ buffer_append(&LogBuffer, (void *)temp_buffer, pal_strlen(temp_buffer) + 1); } else { /* Rotate the log file if required. */ if( LogConfiguration->log_rotation == TRUE ) { if( RotateLogFile(LogConfiguration->log_filename, LogConfiguration->log_rotation_size, temp_buffer) != 0 ) { } } /* Write the concatenated string to the log file. */ if( fprintf(Logfp, "%s", temp_buffer) < 0 ) { return 1; } /* Make sure everything is there by flushing the log file. */ if( fflush(Logfp) != 0 ) { return 1; } } return 0; } // -------------------------------------------------------------------------- /* Send a message to the console (stdout) or stderr */ static int LogToLocal(FILE *location, char *Format, ...) { static char buffer[MAX_LOG_LINE_LENGTH]; va_list argp; va_start(argp, Format); pal_vsnprintf(buffer, sizeof(buffer), Format, argp); va_end(argp); /* location should be stdout or stderr. Print to that. */ if (fprintf(location, "%s\n", buffer) < 0) { return 1; } return 0; } // -------------------------------------------------------------------------- // This function is the main logging function. // Input: // - VerboseLevel: The internal verbosity level assigned to the message. // - SeverityLvl: The message severity // void Display(int VerboseLevel, enum tSeverityLevel SeverityLvl, const char *func, char *format, ...) { va_list argp; int i, j; char fmt[5000]; char clean[5000]; #if !defined(_DEBUG) && !defined(DEBUG) // This is a RELEASE build. Remove debug messages. if( SeverityLvl == ELDebug ) { return; } #endif pal_enter_cs(&logMutex); va_start(argp, format); pal_vsnprintf(fmt, sizeof(fmt), format, argp); va_end(argp); /* Change CRLF to LF for log output */ for( i = 0, j = 0; i < sizeof(fmt); i++ ) { if( fmt[i] == '\r' && fmt[i + 1] == '\n' ) { continue; } clean[j++] = fmt[i]; if( fmt[i] == '\0' ) { break; } } if( LogConfiguration == NULL ) { pal_leave_cs(&logMutex); return; } /* Level says we should log the message to the console. */ if( VerboseLevel <= LogConfiguration->log_level_console ) { /* Log to the console. */ LogToLocal( stdout, clean ); } /* Level says we should log the message to stderr. */ if( VerboseLevel <= LogConfiguration->log_level_stderr ) { /* Log to stderr. */ LogToLocal( stderr, clean ); } /* Level says we should log the message to file. */ if( VerboseLevel <= LogConfiguration->log_level_file ) { /* Log to file. */ LogToFile( LogConfiguration->buffer, SeverityLvl, func, clean ); } /* Level says we should log the message to syslog. */ if( VerboseLevel <= LogConfiguration->log_level_syslog ) { /* Log to syslog. */ LogToSyslog( VerboseLevel, SeverityLvl, func, clean ); } pal_leave_cs(&logMutex); } // -------------------------------------------------------------------------- /* This is the function used to try to send some log out */ /* when there's a problem with the logging system itself. */ /* It tries to write to stderr, and then to the open log file. */ /* If there's no open log file, it will try to open the */ /* default log file, and write to that. */ int DirectErrorMessage(char *message, ...) { va_list argp; time_t t; struct tm *tm; char buffer[MAX_LOG_LINE_LENGTH]; char concat_buffer[MAX_LOG_LINE_LENGTH]; /* If we haven't done so already, initialize the */ /* logging mutex. */ if (LogMutexInitialized == 0) { pal_init_cs(&logMutex); LogMutexInitialized = 1; } pal_enter_cs(&logMutex); /* Write the message to a local buffer. */ va_start(argp, message); pal_vsnprintf(buffer, sizeof(buffer), message, argp); va_end(argp); /* Write the message to stderr. */ if (fprintf(stderr, "%s\n", buffer) < 0) { pal_leave_cs(&logMutex); return 1; } /* Get a timestamp for file logging. */ if ((t = pal_time(NULL)) == (time_t)-1) { pal_leave_cs(&logMutex); return 1; } if ((tm = pal_localtime(&t)) == NULL) { pal_leave_cs(&logMutex); return 1; } /* Concatenate the timestamp and the message. */ pal_snprintf(concat_buffer, sizeof(concat_buffer), "%04d/%02d/%02d %02d:%02d:%02d %c %s: %s\n", (tm->tm_year+1900), (tm->tm_mon+1), tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, SeverityToChar( ELInfo ), ((LogConfiguration == NULL) || (LogConfiguration->identity == NULL)) ? LOG_IDENTITY : LogConfiguration->identity, buffer); /* Try to write to the open log file, if any. */ if (Logfp != NULL) { if (fprintf(Logfp, "%s", concat_buffer) >= 0) { fflush(Logfp); pal_leave_cs(&logMutex); return 0; } } /* On windows, we also try to log to the default log file to give */ /* the GUI one more chance to have something to show to the user. */ #ifdef WIN32 { FILE* file; /* If that didn't work, try to open the default log file, and write to it. */ file = fopen(DEFAULT_LOG_FILENAME, "a+"); if( file == NULL ) { pal_leave_cs(&logMutex); return 1; } if( fprintf(file, "%s", concat_buffer) >= 0 ) { fflush(file); fclose(file); pal_leave_cs(&logMutex); return 0; } else { fclose(file); pal_leave_cs(&logMutex); return 1; } } #endif pal_leave_cs(&logMutex); return 1; } // -------------------------------------------------------------------------- /* Free a logging configuration object that we have allocated. */ static void FreeLogConfiguration(tLogConfiguration *configuration) { if (configuration != NULL) { /* 'identity' comes from a strdup(). */ if (configuration->identity != NULL) { free(configuration->identity); } /* 'log_filename' comes from a strdup(). */ if (configuration->log_filename != NULL) { free(configuration->log_filename); } free(configuration); } } // -------------------------------------------------------------------------- /* Configure the logging system with the values in the configuration structure. */ int LogConfigure(tLogConfiguration *configuration) { /* We have to initialize the file logging buffer once. */ /* Once we've done it, remember it. */ static int LogBufferInitialized = 0; int OutputBufferChars = 0; /* If we haven't done so already, initialize the */ /* file logging buffer. */ if (LogBufferInitialized == 0) { buffer_init(&LogBuffer); LogBufferInitialized = 1; } /* If we haven't done so already, initialize the */ /* logging mutex. */ if (LogMutexInitialized == 0) { pal_init_cs(&logMutex); LogMutexInitialized = 1; } /* We expect to be sent a configuration to use... */ if (configuration == NULL) { DirectErrorMessage(GOGO_STR_LOG_CFG_RECEIVED_NULL_CFG); if (LogConfiguration != NULL) { FreeLogConfiguration(LogConfiguration); LogConfiguration = NULL; } return 1; } /* If the configuration to apply says we want to log to file... */ if (configuration->log_level_file > LOG_LEVEL_DISABLED) { /* If we know which file name to log to. */ if (configuration->log_filename != NULL) { /* If there's a log file currently open. */ if (Logfp != NULL) { /* If there was no previous configuration or the new configuration */ /* specifies a different file name, we can't continue using that */ /* open file. */ if ((LogConfiguration == NULL) || (LogConfiguration->log_filename == NULL) || (strcmp(LogConfiguration->log_filename, configuration->log_filename) != 0)) { /* Make sure everything goes to the file by flushing it. */ fflush(Logfp); /* Close the file. */ fclose(Logfp); /* We then need to open the logging file again using the new */ /* logging file name. */ if ((Logfp = fopen(configuration->log_filename, "a")) == NULL) { DirectErrorMessage(GOGO_STR_CANNOT_OPEN_LOG_FILE, configuration->log_filename); if (LogConfiguration != NULL) { FreeLogConfiguration(LogConfiguration); LogConfiguration = NULL; } FreeLogConfiguration(configuration); return 1; } } } /* Otherwise, there's no configuration file currently open. */ else { /* Therefore, we open the file using the file name specified in the configuration. */ if ((Logfp = fopen(configuration->log_filename, "a")) == NULL) { DirectErrorMessage(GOGO_STR_CANNOT_OPEN_LOG_FILE, configuration->log_filename); if (LogConfiguration != NULL) { FreeLogConfiguration(LogConfiguration); LogConfiguration = NULL; } FreeLogConfiguration(configuration); return 1; } } /* While there's something in the buffer... */ while (buffer_len(&LogBuffer) > 0) { /* Write the next line of logging data to the log file */ if (LogBufferLineToFile(buffer_ptr(&LogBuffer), configuration, &OutputBufferChars) != 0) { DirectErrorMessage(GOGO_STR_CANT_WRITE_LOG_BUFFER_TO_FILE); } OutputBufferChars++; /* And 'consume' the characters we just dumped to file */ buffer_consume(&LogBuffer, OutputBufferChars); } /* Reset the log file buffer. */ buffer_clear(&LogBuffer); } } /* If the configuration to apply says we don't want to log to file... */ else { /* Reset the log file buffer. */ buffer_clear(&LogBuffer); /* If the log file is currently open, flush the contents and close it. */ if (Logfp != NULL) { fflush(Logfp); fclose(Logfp); } } /* If the configuration to apply says we want to log to syslog... */ if (configuration->log_level_syslog > LOG_LEVEL_DISABLED) { /* If there's no previous configuration.. */ if (LogConfiguration == NULL) { /* Just open syslog. */ pal_openlog(configuration->identity, 0, configuration->syslog_facility); } /* But if there was a previous configuration.. */ else { /* And it specified that syslog logging was enabled... */ if (LogConfiguration->log_level_syslog > LOG_LEVEL_DISABLED) { /* If the facility or identity changed, we can't continue */ /* with the same open handle to syslog. */ if ((LogConfiguration == NULL) || (LogConfiguration->identity == NULL) || (strcmp(LogConfiguration->identity, configuration->identity) != 0) || (LogConfiguration->syslog_facility != configuration->syslog_facility)) { /* Close syslog */ pal_closelog(); /* Open it again with the new identity and facility */ pal_openlog(configuration->identity, 0, configuration->syslog_facility); } } /* If the previous configuration had syslog turned off.. */ else { /* Open syslog */ pal_openlog(configuration->identity, 0, configuration->syslog_facility); } } } /* If the configuration to apply says we shouldn't log to syslog */ else { /* And syslog is open because of the previous configuration */ if ((LogConfiguration != NULL) && (LogConfiguration->log_level_syslog > LOG_LEVEL_DISABLED)) { /* Close syslog */ pal_closelog(); } } /* Free the previous configuration if there was one. */ if (LogConfiguration != NULL) { FreeLogConfiguration(LogConfiguration); } /* The current configuration is now the new one. */ LogConfiguration = configuration; return 0; } // -------------------------------------------------------------------------- /* Close the logging system. */ void LogClose(void) { /* Free the log file buffer. */ buffer_free(&LogBuffer); /* If there's a logging configuration object floating around, free it. */ if (LogConfiguration != NULL) { FreeLogConfiguration(LogConfiguration); LogConfiguration = NULL; } /* If the log file is open, close it. */ if (Logfp != NULL) { fclose(Logfp); Logfp = NULL; } /* Close syslog. */ pal_closelog(); } gogoc-1_2-RELEASE/gogoc-tsp/src/lib/md5c.c0100644000000000000000000002510511301544622016544 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: md5c.c,v 1.1 2009/11/20 16:53:38 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ /* * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm * * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All * rights reserved. * * License to copy and use this software is granted provided that it * is identified as the "RSA Data Security, Inc. MD5 Message-Digest * Algorithm" in all material mentioning or referencing this software * or this function. * * License is also granted to make and use derivative works provided * that such works are identified as "derived from the RSA Data * Security, Inc. MD5 Message-Digest Algorithm" in all material * mentioning or referencing the derived work. * * RSA Data Security, Inc. makes no representations concerning either * the merchantability of this software or the suitability of this * software for any particular purpose. It is provided "as is" * without express or implied warranty of any kind. * * These notices must be retained in any copies of any part of this * documentation and/or software. * * $FreeBSD: src/lib/libmd/md5c.c,v 1.11 1999/12/29 05:04:20 peter Exp $ * * This code is the same as the code published by RSA Inc. It has been * edited for clarity and style only. */ #ifdef _KERNEL #include #endif #include "platform.h" #include "md5.h" static void MD5Transform __P((uint32_t [4], const unsigned char [64])); #ifdef _KERNEL #define memset(x,y,z) bzero(x,z); #define memcpy(x,y,z) bcopy(y, x, z) #endif #ifdef i386 #define Encode memcpy #define Decode memcpy #else /* i386 */ /* * Encodes input (uint32_t) into output (unsigned char). Assumes len is * a multiple of 4. */ static void Encode (unsigned char *output, uint32_t *input, unsigned int len) { unsigned int i, j; for (i = 0, j = 0; j < len; i++, j += 4) { output[j] = (unsigned char)(input[i] & 0xff); output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); } } /* * Decodes input (unsigned char) into output (uint32_t). Assumes len is * a multiple of 4. */ static void Decode (uint32_t *output, const unsigned char *input, unsigned int len) { unsigned int i, j; for (i = 0, j = 0; j < len; i++, j += 4) output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j+1]) << 8) | (((uint32_t)input[j+2]) << 16) | (((uint32_t)input[j+3]) << 24); } #endif /* i386 */ static unsigned char PADDING[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* F, G, H and I are basic MD5 functions. */ #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) #define H(x, y, z) ((x) ^ (y) ^ (z)) #define I(x, y, z) ((y) ^ ((x) | (~z))) /* ROTATE_LEFT rotates x left n bits. */ #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) /* * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. * Rotation is separate from addition to prevent recomputation. */ #define FF(a, b, c, d, x, s, ac) { \ (a) += F ((b), (c), (d)) + (x) + (uint32_t)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define GG(a, b, c, d, x, s, ac) { \ (a) += G ((b), (c), (d)) + (x) + (uint32_t)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define HH(a, b, c, d, x, s, ac) { \ (a) += H ((b), (c), (d)) + (x) + (uint32_t)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define II(a, b, c, d, x, s, ac) { \ (a) += I ((b), (c), (d)) + (x) + (uint32_t)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } /* MD5 initialization. Begins an MD5 operation, writing a new context. */ void MD5Init (MD5_CTX *context) { context->count[0] = context->count[1] = 0; /* Load magic initialization constants. */ context->state[0] = 0x67452301; context->state[1] = 0xefcdab89; context->state[2] = 0x98badcfe; context->state[3] = 0x10325476; } /* * MD5 block update operation. Continues an MD5 message-digest * operation, processing another message block, and updating the * context. */ void MD5Update (MD5_CTX *context, const unsigned char *input, unsigned int inputLen) { unsigned int i, index, partLen; /* Compute number of bytes mod 64 */ index = (unsigned int)((context->count[0] >> 3) & 0x3F); /* Update number of bits */ if ((context->count[0] += ((uint32_t)inputLen << 3)) < ((uint32_t)inputLen << 3)) context->count[1]++; context->count[1] += ((uint32_t)inputLen >> 29); partLen = 64 - index; /* Transform as many times as possible. */ if (inputLen >= partLen) { memcpy((void *)&context->buffer[index], (const void *)input, partLen); MD5Transform (context->state, context->buffer); for (i = partLen; i + 63 < inputLen; i += 64) MD5Transform (context->state, &input[i]); index = 0; } else i = 0; /* Buffer remaining input */ memcpy ((void *)&context->buffer[index], (const void *)&input[i], inputLen-i); } /* * MD5 padding. Adds padding followed by original length. */ void MD5Pad (MD5_CTX *context) { unsigned char bits[8]; unsigned int index, padLen; /* Save number of bits */ Encode (bits, context->count, 8); /* Pad out to 56 mod 64. */ index = (unsigned int)((context->count[0] >> 3) & 0x3f); padLen = (index < 56) ? (56 - index) : (120 - index); MD5Update (context, PADDING, padLen); /* Append length (before padding) */ MD5Update (context, bits, 8); } /* * MD5 finalization. Ends an MD5 message-digest operation, writing the * the message digest and zeroizing the context. */ void MD5Final (unsigned char digest[16], MD5_CTX *context) { /* Do padding. */ MD5Pad (context); /* Store state in digest */ Encode (digest, context->state, 16); /* Zeroize sensitive information. */ memset ((void *)context, 0, sizeof (*context)); } /* MD5 basic transformation. Transforms state based on block. */ static void MD5Transform (uint32_t state[4], const unsigned char block[64]) { uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16]; Decode (x, block, 64); /* Round 1 */ #define S11 7 #define S12 12 #define S13 17 #define S14 22 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ /* Round 2 */ #define S21 5 #define S22 9 #define S23 14 #define S24 20 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ /* Round 3 */ #define S31 4 #define S32 11 #define S33 16 #define S34 23 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ /* Round 4 */ #define S41 6 #define S42 10 #define S43 15 #define S44 21 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ state[0] += a; state[1] += b; state[2] += c; state[3] += d; /* Zeroize sensitive information. */ memset ((void *)x, 0, sizeof (x)); } char *md5(char *string, size_t len) { MD5_CTX context; unsigned char digest[16]; static char output[33]; int i; MD5Init(&context); MD5Update (&context, (const unsigned char *)string, (int)len); MD5Final(digest, &context); memset(output, 0, 33); for (i = 0; i < 16; i++) sprintf(output+(i*2), "%02x", ((unsigned char)digest[i])); return output; } void md5digest(char *string, size_t len, char *digest) { MD5_CTX context; MD5Init(&context); MD5Update (&context, (const unsigned char *)string, (int)len); MD5Final((unsigned char *)digest, &context); } gogoc-1_2-RELEASE/gogoc-tsp/src/lib/version.c0100644000000000000000000000077311301544622017405 0ustar rootroot/* --------------------------------------------------------------------------- $Id: version.c,v 1.1 2009/11/20 16:53:38 jasminko Exp $ --------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT --------------------------------------------------------------------------- */ #include "platform.h" #include "version.h" char *tsp_get_version(void) { return IDENTIFICATION; } gogoc-1_2-RELEASE/gogoc-tsp/src/net/0040755000000000000000000000000011346561543015602 5ustar rootrootgogoc-1_2-RELEASE/gogoc-tsp/src/net/Makefile0100644000000000000000000000361111301544622017226 0ustar rootroot# ########################################################################### # $Id: Makefile,v 1.1 2009/11/20 16:53:38 jasminko Exp $ # # Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. # # For license information refer to CLIENT-LICENSE.TXT # # ########################################################################### # # NOTE: This makefile MUST be interpreted by GNU make. # Include the platform makefile, if it exists. -include $(PLATFORM_DIR)/$(PLATFORM)/platform.mak ifdef DEBUG CFLAGS=-g -Wall $(CC_INC_PATHS) $(PLATFORM_CFLAGS) -D_REENTRANT -DDEBUG else CFLAGS=-O2 -Wall $(CC_INC_PATHS) $(PLATFORM_CFLAGS) -D_REENTRANT endif CC=gcc OBJS=$(OBJS_DIR)/net.o \ $(OBJS_DIR)/net_rudp.o \ $(OBJS_DIR)/net_rudp6.o \ $(OBJS_DIR)/net_tcp.o \ $(OBJS_DIR)/net_udp.o \ $(OBJS_DIR)/net_ka.o \ $(OBJS_DIR)/net_cksm.o \ $(OBJS_DIR)/net_tcp6.o \ $(OBJS_DIR)/net_echo_request.o \ $(OBJS_DIR)/icmp_echo_engine.o all: $(OBJS) install: all $(OBJS_DIR)/net.o:net.c $(CC) $(CFLAGS) -c net.c -o $(OBJS_DIR)/net.o $(OBJS_DIR)/net_rudp.o:net_rudp.c $(CC) $(CFLAGS) -c net_rudp.c -o $(OBJS_DIR)/net_rudp.o $(OBJS_DIR)/net_tcp.o:net_tcp.c $(CC) $(CFLAGS) -c net_tcp.c -o $(OBJS_DIR)/net_tcp.o $(OBJS_DIR)/net_udp.o:net_udp.c $(CC) $(CFLAGS) -c net_udp.c -o $(OBJS_DIR)/net_udp.o $(OBJS_DIR)/net_ka.o:net_ka.c $(CC) $(CFLAGS) -c net_ka.c -o $(OBJS_DIR)/net_ka.o $(OBJS_DIR)/net_cksm.o:net_cksm.c $(CC) $(CFLAGS) -c net_cksm.c -o $(OBJS_DIR)/net_cksm.o $(OBJS_DIR)/net_tcp6.o:net_tcp6.c $(CC) $(CFLAGS) -c net_tcp6.c -o $(OBJS_DIR)/net_tcp6.o $(OBJS_DIR)/net_rudp6.o:net_rudp6.c $(CC) $(CFLAGS) -c net_rudp6.c -o $(OBJS_DIR)/net_rudp6.o $(OBJS_DIR)/net_echo_request.o:net_echo_request.c $(CC) $(CFLAGS) -c net_echo_request.c -o $(OBJS_DIR)/net_echo_request.o $(OBJS_DIR)/icmp_echo_engine.o:icmp_echo_engine.c $(CC) $(CFLAGS) -c icmp_echo_engine.c -o $(OBJS_DIR)/icmp_echo_engine.o clean: rm -f $(OBJS) gogoc-1_2-RELEASE/gogoc-tsp/src/net/icmp_echo_engine.c0100644000000000000000000013163511301544622021215 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: icmp_echo_engine.c,v 1.1 2009/11/20 16:53:38 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2008 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT Description: ICMP Echo Engine implementation. ----------------------------------------------------------------------------- */ #include "platform.h" #include "icmp_echo_engine.h" #include "net_cksm.h" // Used for ICMP header checksum. #include "log.h" #undef MIN #define MIN(X,Y) (((X)<(Y))?X:Y) #define ICMP_LITTERAL ((p_engine->icmp_saf==AF_INET)?"ICMP":"ICMPv6") #define ICMP4_ECHO_REQUEST_TYPE 8 #define ICMP4_ECHO_REPLY_TYPE 0 #define ICMP6_ECHO_REQUEST_TYPE 128 #define ICMP6_ECHO_REPLY_TYPE 129 #define ICMP6_ROUTER_ADVERTISEMENT 134 // Seen sometimes. #define ICMP6_NEIGHBOR_SOLICITATION 135 // Seen sometimes. #define ICMP6_NEIGHBOR_ADVERTISEMENT 136 // Seen sometimes. #define ICMP_ECHO_CODE 0 #define ICMP_ECHO_DATA_LEN sizeof(struct timeval) // A note for displaying messages in this module: // This module was meant to return precise information to the utilizing // module. Only debugging messages should be logged(Display()ed) in this // module. Informational, warning and error messages should be logged in // the utilizing module, because this module is used by different // scenarios. // Logging such messages here could mess up the intended log message flow // of other scenario implementations. #if defined(DEBUG) || defined(_DEBUG) #ifndef __FUNCTION__ #define __FUNCTION__ __func__ #endif #define DBG_PRINT(X, ...) Display( LOG_LEVEL_3, ELDebug, __FUNCTION__, X, ##__VA_ARGS__) #else #define DBG_PRINT(X, ...) #endif // -------------------------------------------------------------------------- // IPv4 and IPv6 ICMP ECHO [REQUEST and REPLY] header. typedef struct __ICMP_ECHO_HEADER { uint8_t icmp_type; uint8_t icmp_code; uint16_t icmp_cksm; uint16_t echo_id; uint16_t echo_seq; uint8_t echo_data[0]; } ICMP_ECHO_HEADER, * PICMP_ECHO_HEADER; // -------------------------------------------------------------------------- // IPv6 pseudo header used for ICMPv6 checksum computation. typedef struct __IP6_PSEUDO_HEADER { struct in6_addr ip6_src; // source address struct in6_addr ip6_dst; // destination address uint32_t hdr_len; // Upper Layer Packet Length uint8_t pad[3]; // - zeroed - uint8_t nxt_hdr; // IPPROTO_ICMPV6 uint8_t icmp_hdr[0]; // ICMP header. } IP6_PSEUDO_HEADER, * PIP6_PSEUDO_HEADER; // -------------------------------------------------------------------------- typedef struct __ECHO_EVENT { uint32_t echo_seq; // Echo sequence. struct timeval tv_timeout; // Time at which this echo event times out. struct __ECHO_EVENT* next; // Next chained echo event. } ECHO_EVENT, * PECHO_EVENT; // -------------------------------------------------------------------------- // ICMP echo engine parameters. typedef struct __ICMP_ECHO_ENGINE_PARMS { // Engine configurable parameters. uint32_t send_interval; uint32_t echo_num; uint32_t echo_timeout; // Not used in ACD. uint32_t echo_timeout_threshold; uint8_t eng_mode:2; // Mode flag used by engine. OTHER | ACD | KA. // Engine processing status. uint8_t eng_ongoing:1; // Flag used by engine to know when to stop. // Engine statistical variables. uint32_t count_send; // Total number of echo requests sent. uint32_t count_ontime; // Total number of echo replies received on time. uint32_t count_late; // Total number of echo replies that were late. uint8_t count_consec_late;// Number of consecutive late echo replies. // Engine echo event list. PECHO_EVENT event_list; // Engine echo send and receive callbacks. iee_send_clbk clbk_send; iee_recv_clbk clbk_recv; // Engine socket variables. uint32_t icmp_echo_id; // ICMP ECHO identifier (this process id). pal_socket_t icmp_sfd; // ICMP raw socket file descriptor. sint32_t icmp_saf; // ICMP raw socket address family. union { struct sockaddr_in in4; struct sockaddr_in6 in6; } echo_addr_src; // IPv4 or IPv6 source address. union { struct sockaddr_in in4; struct sockaddr_in6 in6; } echo_addr_dst; // IPv4 or IPv6 destination address. } ICMP_ECHO_ENGINE_PARMS, * PICMP_ECHO_ENGINE_PARMS; // -------------------------------------------------------------------------- // IEE internal private statuses typedef enum { READ_SELECT_ERROR, // Returned by _do_read READ_SELECT_TIMEOUT, // Returned by _do_read READ_SOCKET_CLOSED, // Returned by _do_read READ_RECV_ERROR, // Returned by _do_read SEND_PINGOUT_SUCCESS, // Returned by _do_send SEND_PINGOUT_ERROR, // Returned by _do_send SEND_MEMORY_STARVATION, // Returned by _do_send ANAL_PACKET_BAD, // Returned by _decode_icmp_packet & _do_read ANAL_PACKET_IGNORED, // Returned by _decode_icmp_packet & _do_read ANAL_PACKET_PINGIN_LATE, // Returned by _decode_icmp_packet & _do_read ANAL_PACKET_PINGIN_ONTIME,// Returned by _decode_icmp_packet & _do_read ECHO_EVENT_REMOVED, // Returned by _remove_free_echo_event ECHO_EVENT_NOTFOUND // Returned by _remove_free_echo_event } iee_priv_ret_t; // -------------------------------------------------------------------------- // Local private function prototypes. iee_ret_t _do_send_wrap ( PICMP_ECHO_ENGINE_PARMS p_engine ); iee_priv_ret_t _do_send ( PICMP_ECHO_ENGINE_PARMS p_engine ); void _calc_icmp_csum ( PICMP_ECHO_ENGINE_PARMS p_engine, PICMP_ECHO_HEADER icmp_hdr ); iee_ret_t _do_read_wrap ( PICMP_ECHO_ENGINE_PARMS p_engine, struct timeval* tv_ref ); iee_priv_ret_t _do_read ( PICMP_ECHO_ENGINE_PARMS p_engine, struct timeval* tv_delay, uint32_t* echo_seq ); iee_priv_ret_t _decode_icmp_packet ( PICMP_ECHO_ENGINE_PARMS p_engine, uint8_t* pkt_data, uint32_t pkt_len, uint32_t* echo_seq ); PECHO_EVENT _create_insert_echo_event( PICMP_ECHO_ENGINE_PARMS p_engine, struct timeval* tv_sent, uint32_t echo_seq ); void _insert_echo_event ( PICMP_ECHO_ENGINE_PARMS p_engine, PECHO_EVENT p_event_insert ); iee_priv_ret_t _remove_free_echo_event( PICMP_ECHO_ENGINE_PARMS p_engine, uint32_t echo_seq ); void _free_echo_event_list ( PECHO_EVENT p_event ); void _compute_next_send ( PICMP_ECHO_ENGINE_PARMS p_engine, struct timeval* tv_next_send ); void _compute_echo_timeout ( PICMP_ECHO_ENGINE_PARMS p_engine, struct timeval* tv_timeout ); void _conv_ms_to_tv ( double ms, struct timeval* tv ); double _compute_tv_diff_now ( struct timeval* tv_diff ); double _compare_tv ( struct timeval* tv_1, struct timeval* tv_2 ); // -------------------------------------------------------------------------- // IEE_init: ICMP Echo Engine initialisation routine. // // Parameters: // pp_config: Opaque double pointer to a ICMP_ECHO_ENGINE_PARMS structure. // eng_mode: The mode of the ICMP Echo Engine. // send_interval: Fixed interval, in miliseconds, at which ICMP echo // requests will be issued. // echo_num: Number of ICMP echo requests to issue(0=infinite). // echo_timeout: Number of miliseconds after which an unanswered ICMP // echo request will be marked as timed out. // echo_timeout_threshold: Number of consecutive timed-out ICMP echo // requests to declare a general echo timeout. // src: Source address used for sending ICMP echo requests. // dst: Destination address at which ICMP echo requests will be sent. // family: address family (INET or INET6) // // Return values: // IEE_SUCCESS on success. // IEE_INVALID_PARMS if invalid pp_config. // iee_ret_t IEE_init( void** pp_config, iee_mode_t eng_mode, uint32_t send_interval, uint32_t echo_num, uint32_t echo_timeout, uint8_t echo_timeout_threshold, char* src, char* dst, sint32_t af, iee_send_clbk send_clbk, iee_recv_clbk recv_clbk ) { PICMP_ECHO_ENGINE_PARMS p_engine = NULL; // Verify input parameters. if( pp_config == NULL || *pp_config != NULL || dst == NULL ) { // Error: bad input parameters. return IEE_INVALID_PARMS; } // Reserve memory for the engine parameters *pp_config = pal_malloc( sizeof(ICMP_ECHO_ENGINE_PARMS) ); p_engine = (PICMP_ECHO_ENGINE_PARMS)*pp_config; if( p_engine == NULL ) { // Error: Not enough memory for structure. return IEE_RESOURCE_STARVATION; } // Initialize engine structure with input parameters. memset( p_engine, 0, sizeof(ICMP_ECHO_ENGINE_PARMS) ); p_engine->send_interval = send_interval; p_engine->echo_num = echo_num; p_engine->echo_timeout = echo_timeout; // Not used in ACD p_engine->echo_timeout_threshold = echo_timeout_threshold; p_engine->eng_mode = eng_mode; // Initialize engine variables. p_engine->eng_ongoing = 1; p_engine->count_send = 0; p_engine->count_late = 0; p_engine->count_ontime = 0; p_engine->count_consec_late = 0; p_engine->event_list = NULL; // Set engine callback functions. p_engine->clbk_send = send_clbk; p_engine->clbk_recv = recv_clbk; // Initialize engine socket variables. p_engine->icmp_echo_id = pal_getpid(); p_engine->icmp_saf = af; switch( p_engine->icmp_saf ) { case AF_INET: if( pal_inet_pton( AF_INET, src, &p_engine->echo_addr_src.in4.sin_addr ) <= 0 ) { // Bad IPv4 address in 'src'. pal_free( p_engine ); return IEE_INVALID_PARMS; } p_engine->echo_addr_src.in4.sin_family = AF_INET; if( pal_inet_pton( AF_INET, dst, &p_engine->echo_addr_dst.in4.sin_addr ) <= 0 ) { // Bad IPv4 address in 'dst'. pal_free( p_engine ); return IEE_INVALID_PARMS; } p_engine->echo_addr_dst.in4.sin_family = AF_INET; p_engine->icmp_sfd = pal_socket( AF_INET, SOCK_RAW, IPPROTO_ICMP ); break; case AF_INET6: if( pal_inet_pton( AF_INET6, src, &p_engine->echo_addr_src.in6.sin6_addr ) <= 0 ) { // Bad IPv6 address in 'src'. pal_free( p_engine ); return IEE_INVALID_PARMS; } p_engine->echo_addr_src.in6.sin6_family = AF_INET6; if( pal_inet_pton( AF_INET6, dst, &p_engine->echo_addr_dst.in6.sin6_addr ) <= 0 ) { // Bad IPv6 address in 'dst'. pal_free( p_engine ); return IEE_INVALID_PARMS; } p_engine->echo_addr_dst.in6.sin6_family = AF_INET6; p_engine->icmp_sfd = pal_socket( AF_INET6, SOCK_RAW, IPPROTO_ICMPV6 ); break; default: // ERROR! Bad address family! pal_free( p_engine ); return IEE_INVALID_PARMS; } // Verify that the socket created is valid. if( p_engine->icmp_sfd == -1 ) { // Failed to open a socket descriptor. pal_free( p_engine ); return IEE_GENERAL_ECHO_ERROR; } return IEE_SUCCESS; } // -------------------------------------------------------------------------- // IEE_destroy: ICMP Echo Engine destruction routine. // // Parameters: // pp_config: Opaque double pointer to a ICMP_ECHO_ENGINE_PARMS structure. // // Return values: // IEE_SUCCESS on success. // IEE_INVALID_PARMS if invalid pp_config. // iee_ret_t IEE_destroy( void** pp_config ) { PICMP_ECHO_ENGINE_PARMS p_engine = NULL; // Verify input parameters. if( pp_config == NULL || *pp_config == NULL ) { // Error: invalid p_config, or already freed. return IEE_INVALID_PARMS; } // Cast opaque double pointer to allow manipulation. p_engine = (PICMP_ECHO_ENGINE_PARMS)*pp_config; // Close the ICMP raw socket. pal_closesocket( p_engine->icmp_sfd ); // Free the engine echo event list. _free_echo_event_list( p_engine->event_list ); // Deallocate the memory used by the engine structure. pal_free( p_engine ); *pp_config = NULL; return IEE_SUCCESS; } // -------------------------------------------------------------------------- // IEE_process: ICMP Echo Engine main processing routine. // // Parameters: // p_config: Opaque pointer to a ICMP_ECHO_ENGINE_PARMS structure. // // Return values: // IEE_SUCCESS on normal execution. // IEE_INVALID_PARMS if invalid p_config. // IEE_CONNECTIVITY_ASSESSED (ACD only) Received one echo reply on time. // IEE_GENERAL_ECHO_TIMEOUT when the maximal number of successive timeouts // has been detected. // IEE_GENERAL_ECHO_ERROR on a fatal error. // iee_ret_t IEE_process( void* p_config ) { PICMP_ECHO_ENGINE_PARMS p_engine = (PICMP_ECHO_ENGINE_PARMS)p_config; struct timeval tv_reference; iee_ret_t retval = IEE_SUCCESS; // Verify input parameters. if( p_engine == NULL ) { // Error: invalid p_config, or already freed. return IEE_INVALID_PARMS; } if( (iee_mode_t)p_engine->eng_mode == IEE_MODE_KA ) { // When icmp echo engine is is Keepalive(KA) mode, the first sent echo // REQUEST is sent after a full interval. => Wait for one interval. uint32_t total_sleep_time = p_engine->send_interval; uint32_t sleep_time; DBG_PRINT("Sleeping %d milliseconds before sending first ECHO REQUEST.\n", total_sleep_time); // Break the sleep in several chunks in case we're notified to stop. while( p_engine->eng_ongoing == 1 && total_sleep_time > 0 ) { sleep_time = (total_sleep_time>1000)?1000:total_sleep_time; pal_sleep( sleep_time ); total_sleep_time -= sleep_time; } } // ------------------------------------------------------------------------ // Main ICMP echo engine loop. Loop until we're notified to stop, or we've // sent the number of ECHO REQUESTS we had to. // ------------------------------------------------------------------------ while( p_engine->eng_ongoing == 1 && (p_engine->echo_num == 0 || p_engine->count_send < p_engine->echo_num) ) { // ------------------------------ // Time to send an ECHO request. // ------------------------------ retval = _do_send_wrap( p_engine ); if( retval != IEE_SUCCESS ) { // An error occurred while sending. break; } // Check if we've been notified to stop, or an event has triggered a stop. if( p_engine->eng_ongoing == 0 ) { // Stop processing. break; } // Synchronize time reference variable with 'now'. pal_gettimeofday( &tv_reference ); // Add one echo interval to tv_reference. _compute_next_send( p_engine, &tv_reference ); // ------------------------------------------------------------------- // Wait and read for incoming packets. // Function will return when tv_reference is approximatively 'now'. // ------------------------------------------------------------------- retval = _do_read_wrap( p_engine, &tv_reference ); if( retval != IEE_SUCCESS ) { // A retval different than IEE_SUCCESS indicates that we should stop // processing. It does not necessarily mean an error occurred. break; } DBG_PRINT("\n"); } DBG_PRINT("Statistics:\n\tSent: %03d\n\tReceived on time: %03d\n\tReceived late: %03d\n", p_engine->count_send, p_engine->count_ontime, p_engine->count_late ); return retval; } // -------------------------------------------------------------------------- // IEE_stop: ICMP Echo Engine stop procedure. Stops the IEE_process function. // This function should be called from an external thread. // // Parameters: // p_config: Opaque pointer to a ICMP_ECHO_ENGINE_PARMS structure. // // Return values: // IEE_SUCCESS on success. // IEE_INVALID_PARMS if invalid pp_config. // iee_ret_t IEE_stop( void* p_config ) { PICMP_ECHO_ENGINE_PARMS p_engine = (PICMP_ECHO_ENGINE_PARMS)p_config; // Verify input parameters. if( p_engine == NULL ) { // Error: invalid p_config, or already freed. return IEE_INVALID_PARMS; } // Notify the engine to stop. p_engine->eng_ongoing = 0; // Close the ICMP socket. // If the ICMP echo engine is currently in a read operation, the // IEE_process() function will not return until the call to select() // returns. This time lapse depends on the current processing. It can take // up to p_engine->send_interval milliseconds. To break the select() call, // we close the ICMP socket so it will return as an error. // pal_closesocket( p_engine->icmp_sfd ); // break a wait on 'select()'. return IEE_SUCCESS; } // -------------------------------------------------------------------------- // _do_send_wrap: Private function used to wrap the actual write operation // and analyze the return code from the send to translate it // in a more general return code. // // Parameters: // p_engine: p_config: Pointer to an ICMP_ECHO_ENGINE_PARMS structure. // // Return values: // IEE_SUCCESS: Operation was successful. Continue. // IEE_GENERAL_ECHO_ERROR: Fatal error occurred. Abort. // iee_ret_t _do_send_wrap( PICMP_ECHO_ENGINE_PARMS p_engine ) { iee_priv_ret_t priv_retval; iee_ret_t retval; // Send an ICMP ECHO request. priv_retval = _do_send( p_engine ); switch( priv_retval ) { case SEND_PINGOUT_SUCCESS: // No error. retval = IEE_SUCCESS; break; case SEND_MEMORY_STARVATION: // Failed to acquire memory. retval = IEE_RESOURCE_STARVATION; break; case SEND_PINGOUT_ERROR: default: // An error occurred while sending the echo request. retval = IEE_GENERAL_ECHO_ERROR; break; } return retval; } // -------------------------------------------------------------------------- // _do_send: Private function used to send an ICMP ECHO REQUEST. // Creates an ICMP ECHO REQUEST packet and sends it. Creates an echo event // and inserts it in the engine's list of echo events. // // Parameters: // p_engine: Pointer to a ICMP_ECHO_ENGINE_PARMS structure. // // Return values: // IEE_SUCCESS when no errors happened. // IEE_GENERAL_ECHO_ERROR on fatal error. // iee_priv_ret_t _do_send( PICMP_ECHO_ENGINE_PARMS p_engine ) { PICMP_ECHO_HEADER icmp_hdr; uint8_t send_buf[sizeof(ICMP_ECHO_HEADER) + ICMP_ECHO_DATA_LEN]; const uint16_t send_buf_len = sizeof(ICMP_ECHO_HEADER) + ICMP_ECHO_DATA_LEN; iee_priv_ret_t retval = SEND_PINGOUT_SUCCESS; sint32_t ret; // Map the ICMP header unto the send buffer. icmp_hdr = (PICMP_ECHO_HEADER)send_buf; if( p_engine->icmp_saf == AF_INET ) { icmp_hdr->icmp_type = ICMP4_ECHO_REQUEST_TYPE; } else { icmp_hdr->icmp_type = ICMP6_ECHO_REQUEST_TYPE; } icmp_hdr->icmp_code = ICMP_ECHO_CODE; icmp_hdr->icmp_cksm = 0; icmp_hdr->echo_id = p_engine->icmp_echo_id; icmp_hdr->echo_seq = (p_engine->count_send)++; // Starts at 0. pal_gettimeofday( (struct timeval*)(icmp_hdr->echo_data) ); // Calculate the ICMP header checksum. _calc_icmp_csum( p_engine, icmp_hdr ); // Create the echo event, and insert it in the echo engine sorted echo // event list. if( _create_insert_echo_event( p_engine, (struct timeval*)(icmp_hdr->echo_data), icmp_hdr->echo_seq ) != NULL ) { // Send the ICMP packet. DBG_PRINT(">> %s ECHO REQUEST, id:%d, seq:%d, len:%d...\n", ICMP_LITTERAL, icmp_hdr->echo_id, icmp_hdr->echo_seq, send_buf_len ); ret = sendto( p_engine->icmp_sfd, send_buf, send_buf_len, 0, (struct sockaddr*)&(p_engine->echo_addr_dst), sizeof(p_engine->echo_addr_dst) ); if( ret != send_buf_len ) { // The return value of 'sendto()' did not match what was expected. Error. retval = SEND_PINGOUT_ERROR; DBG_PRINT("Failed to send ICMP REQUEST packet. Error code:%d\n", ret); } else if( p_engine->clbk_send != NULL ) { p_engine->clbk_send(); } } else { // Resource starvation. Not enough memory. retval = SEND_MEMORY_STARVATION; DBG_PRINT("Failed to allocate memory for echo event.\n"); } return retval; } // -------------------------------------------------------------------------- // _calc_icmp_csum: Calculates the ICMP checksum. The checksum is stored in // the ICMP header passed in. // // Parameters: // p_engine: p_config: Pointer to an ICMP_ECHO_ENGINE_PARMS structure. // icmp_hdr: ICMP packet header. // // Return value: (none) // void _calc_icmp_csum( PICMP_ECHO_ENGINE_PARMS p_engine, PICMP_ECHO_HEADER icmp_hdr ) { PIP6_PSEUDO_HEADER ip6_pseudo; uint8_t pseudo_buf[sizeof(IP6_PSEUDO_HEADER) + sizeof(ICMP_ECHO_HEADER) + ICMP_ECHO_DATA_LEN]; const uint16_t pseudo_buf_len = sizeof(pseudo_buf); // From RFC 2460: // The IPv6 version of ICMP [ICMPv6] includes the above pseudo-header in // its checksum computation; this is a change from the IPv4 version of // ICMP, which does not include a pseudo-header in its checksum. The // reason for the change is to protect ICMP from misdelivery or // corruption of those fields of the IPv6 header on which it depends, // which, unlike IPv4, are not covered by an internet-layer checksum. // The Next Header field in the pseudo-header for ICMP contains the // value 58, which identifies the IPv6 version of ICMP. if( p_engine->icmp_saf == AF_INET6 ) { memset( pseudo_buf, 0, pseudo_buf_len ); // Map the IP6 pseudo header on the pseudo_buf. ip6_pseudo = (PIP6_PSEUDO_HEADER)pseudo_buf; // Fill in pseudo header data. memcpy( &ip6_pseudo->ip6_src, &p_engine->echo_addr_src.in6.sin6_addr, sizeof(ip6_pseudo->ip6_src) ); memcpy( &ip6_pseudo->ip6_dst, &p_engine->echo_addr_dst.in6.sin6_addr, sizeof(ip6_pseudo->ip6_dst) ); ip6_pseudo->hdr_len = htonl( sizeof(ICMP_ECHO_HEADER) + ICMP_ECHO_DATA_LEN ); ip6_pseudo->nxt_hdr = IPPROTO_ICMPV6; // Copy the ICMP header in the pseudov6 header. memcpy( ip6_pseudo->icmp_hdr, icmp_hdr, sizeof(ICMP_ECHO_HEADER) + ICMP_ECHO_DATA_LEN ); // Calculate the ICMP checksum. icmp_hdr->icmp_cksm = in_cksum( (uint16_t*)ip6_pseudo, pseudo_buf_len ); } else { // Calculate the ICMP checksum. icmp_hdr->icmp_cksm = in_cksum( (uint16_t*)icmp_hdr, sizeof(ICMP_ECHO_HEADER) + ICMP_ECHO_DATA_LEN ); } } // -------------------------------------------------------------------------- // _do_read_wrap: Private function used to wrap the actual read operation and // analyse the return code from the read to translate it in a more general // return code. // // Parameters: // p_engine: p_config: Pointer to an ICMP_ECHO_ENGINE_PARMS structure. // tv_ref: Absolute time at which we should exit this function. // // Return values: // IEE_SUCCESS: Operation was successful. Continue. // IEE_GENERAL_ECHO_ERROR: Fatal error occurred. Abort. // IEE_CONNECTIVITY_ASSESSED: (ACD only) Stop processing. // iee_ret_t _do_read_wrap( PICMP_ECHO_ENGINE_PARMS p_engine, struct timeval* tv_ref ) { double time_left_ms; // Time left to spend in this function. double read_delay; // Number of milliseconds before the soonest echo event times out. struct timeval tv_delay; // The actual time delay. uint32_t echo_seq_read; // Echo sequence read. iee_priv_ret_t priv_retval; iee_ret_t retval = IEE_SUCCESS; // Check how much time we have left to spend here. time_left_ms = _compute_tv_diff_now( tv_ref ); if( time_left_ms <= 0.0 ) { // Return because it's already time to send a new ECHO REQUEST. // Should not happen in normal processing. Can happen if debugging. return IEE_SUCCESS; } // Main read loop. do { if( p_engine->event_list != NULL ) { // Check how much time before the soonest echo event times out. read_delay = _compute_tv_diff_now( &p_engine->event_list->tv_timeout ); } else { read_delay = p_engine->send_interval; } // Translate that in a timeval structure. _conv_ms_to_tv( MIN(time_left_ms, read_delay), &tv_delay ); // ------------------------------------------ // Wait for an incoming packet, and read it. // ------------------------------------------ priv_retval = _do_read( p_engine, &tv_delay, &echo_seq_read ); // Perform operations depending on what happened in the read. switch( priv_retval ) { case ANAL_PACKET_BAD: case ANAL_PACKET_IGNORED: // We don't care. break; case READ_SELECT_TIMEOUT: if( time_left_ms > read_delay && p_engine->event_list != NULL ) { // An echo event has timed out. // => Increment late counter and consecutive late counter. p_engine->count_late++; p_engine->count_consec_late++; DBG_PRINT("--> Echo timeout detected! count_consec_late:%d\n",p_engine->count_consec_late); // => Remove the echo event from the list. _remove_free_echo_event( p_engine, p_engine->event_list->echo_seq ); } // else, we have reached the time to quit processing incoming // packets. break; case ANAL_PACKET_PINGIN_ONTIME: // We received an ECHO REPLY on time. // => Reset the consecutive late counter. Increment the ontime counter. p_engine->count_consec_late = 0; p_engine->count_ontime++; // => Remove the associated echo event from the list. priv_retval = _remove_free_echo_event( p_engine, echo_seq_read ); if( priv_retval != ECHO_EVENT_REMOVED ) { // This event was already removed from the list (Probably because // a READ_SELECT_TIMEOUT occured while waiting for it). // Since it is a valid on time reply, we've reset the consecutive // late count. p_engine->count_late--; DBG_PRINT("--> Last echo timeout cancelled.\n"); } // If the icmp echo engine is in mode Automatic Connectivity // Detection (ACD), any received reply assesses a valid // connectivity. if( (iee_mode_t)p_engine->eng_mode == IEE_MODE_ACD ) { p_engine->eng_ongoing = 0; retval = IEE_CONNECTIVITY_ASSESSED; DBG_PRINT("Connectivity has been assessed (ACD).\n"); } // ** INTENTIONAL FALLTHROUGH ** // case ANAL_PACKET_PINGIN_LATE: // The associated echo event should have already beed removed from // the list of echo events. // Check if this received ECHO REPLY was the last. if( p_engine->echo_num != 0 && p_engine->count_send >= p_engine->echo_num ) { // This is our last echo reply. p_engine->eng_ongoing = 0; } break; case READ_SOCKET_CLOSED: p_engine->eng_ongoing = 0; // Should have already been set. retval = IEE_SUCCESS; DBG_PRINT("ICMP echo engine socket has been closed."); break; case READ_SELECT_ERROR: // Fatal error case READ_RECV_ERROR: // Fatal error default: // Unhandled cases (Should not occur). p_engine->eng_ongoing = 0; retval = IEE_GENERAL_ECHO_ERROR; break; } // Check if we've reached the maximal number of consecutive timeouts. if( p_engine->count_consec_late >= p_engine->echo_timeout_threshold ) { retval = IEE_GENERAL_ECHO_TIMEOUT; p_engine->eng_ongoing = 0; DBG_PRINT("General Echo Timeout detected.\n"); } // Check how much time we have left to spend here. time_left_ms = _compute_tv_diff_now( tv_ref ); } // Loop until we have to stop reading packets, or we've been notified // to stop processing. while( time_left_ms > 0.0 && p_engine->eng_ongoing == 1 ); return retval; } // -------------------------------------------------------------------------- // _do_read: private function used to wait/read on the ICMP socket. If an // ICMP packet is read, it is given to the analysis function. // // Parameters: // p_engine: Pointer to a ICMP_ECHO_ENGINE_PARMS structure. // tv_delay : Time to wait for an incoming packet. // echo_seq: Emplacement where the read echo sequence will be stored. // // Return values: // IEE_SUCCESS when no errors happened. // IEE_GENERAL_ECHO_ERROR on fatal error. // iee_priv_ret_t _do_read( PICMP_ECHO_ENGINE_PARMS p_engine, struct timeval* tv_delay, uint32_t *echo_seq ) { uint8_t read_buf[2048]; fd_set fs; sint32_t ret; iee_priv_ret_t retval; FD_ZERO( &fs ); FD_SET( p_engine->icmp_sfd, &fs ); DBG_PRINT("Will wait for %.3f milliseconds.\n", ((double)(tv_delay->tv_sec * 1000)) + ((double)tv_delay->tv_usec) / 1000.0); // Wait on ICMP socket for incoming packet. ret = select( (sint32_t)p_engine->icmp_sfd + 1, &fs, NULL, NULL, tv_delay ); switch( ret ) { case 0: // There was no packet available to read in the time lapse. retval = READ_SELECT_TIMEOUT; break; case 1: // Data is available for read - or socket closed. ret = recv( p_engine->icmp_sfd, read_buf, sizeof(read_buf), 0 ); if( ret > 0 ) { // Analyse read packet. retval = _decode_icmp_packet( p_engine, read_buf, ret, echo_seq ); } else if( ret == -1 && p_engine->eng_ongoing == 0 ) { // Socket has been closed because we're exiting. See KA_stop(). retval = READ_SOCKET_CLOSED; } else { // Abnormal return value from 'recv()'. Error. retval = READ_RECV_ERROR; DBG_PRINT("Error occurred while receiving a packet. Error code:%d\n", ret); } break; default: // On Linux/Darwin/*BSD, a signal can cause an interruption in the select // routine. if( errno == EINTR ) { // A signal has been received and has interrupted the select(). retval = READ_SELECT_TIMEOUT; DBG_PRINT("Call to select() has been interrupted by a signal. Continuing."); } else if( errno == EBADF && p_engine->eng_ongoing == 0 ) { // Socket has been closed because we're exiting. See KA_stop(). retval = READ_SOCKET_CLOSED; } else { // Abnormal return value from 'select()'. Error. retval = READ_SELECT_ERROR; DBG_PRINT("Error occurred while waiting for a packet. Error code:%d\n", ret); } } return retval; } // -------------------------------------------------------------------------- // _decode_icmp_packet: private function used to analyse an incoming ICMP // packet. // // IMPORTANT NOTE: // IPv6 and IPv4 operate differently when receiving a socket with a type // of SOCK_RAW. The IPv4 receive packet includes the packet payload, the // next upper-level header (for example, the IP header for an ICMP // packet), and the IPv4 packet header. The IPv6 receive packet includes // the packet payload and the next upper-level header. The IPv6 receive // packet never includes the IPv6 packet header. // // Parameters: // p_engine: Pointer to a ICMP_ECHO_ENGINE_PARMS structure. // pkt_data: ICMP packet data. // pkt_len : ICMP packet length. // echo_seq: Pointer where the echo sequence received will be stored. // // Return values: // IEE_SUCCESS when no errors happened. // IEE_GENERAL_ECHO_ERROR on fatal error. // iee_priv_ret_t _decode_icmp_packet( PICMP_ECHO_ENGINE_PARMS p_engine, uint8_t* pkt_data, uint32_t pkt_len, uint32_t *echo_seq ) { PICMP_ECHO_HEADER icmp_hdr = NULL; // ICMP header pointer. uint8_t ip_ver, ip_len=0; // IP header version and length. double rtt; // Computed roundtrip time. iee_priv_ret_t priv_retval = ANAL_PACKET_PINGIN_ONTIME; do // Dummy loop used to 'break'. { if( p_engine->icmp_saf == AF_INET ) { // Retrieve this packet IP version. Assert IP header IP version. ip_ver = (pkt_data[0] & 0xF0) >> 4; if( ip_ver != 0x04 ) { // Packet IP address family does not match opened socket. priv_retval = ANAL_PACKET_BAD; DBG_PRINT("Invalid IP packet for address family. IP version:%d\n", ip_ver); break; } // Retrieve IP header length (found in bytes 4..7). ip_len = (pkt_data[0] & 0x0F) << 2; // Verify if packet length includes the IP header AND the ICMP header. if( pkt_len - ip_len < sizeof(ICMP_ECHO_HEADER) ) { // This packet is too small to be an ICMP packet. priv_retval = ANAL_PACKET_BAD; DBG_PRINT("Packet is too small to be an ICMP packet. ICMP length:%d\n", pkt_len - ip_len); break; } // Cast raw packet data to the ICMP echo header. icmp_hdr = (PICMP_ECHO_HEADER)(pkt_data + ip_len); // Check ICMP type switch( icmp_hdr->icmp_type ) { case ICMP4_ECHO_REPLY_TYPE: // Received an ECHO REPLY. Good. break; case ICMP4_ECHO_REQUEST_TYPE: // Received an ECHO REQUEST. We're not replying. priv_retval = ANAL_PACKET_IGNORED; DBG_PRINT("<< ICMP ECHO REQUEST, id:%d, seq:%d, len:%d\n", icmp_hdr->echo_id, icmp_hdr->echo_seq, pkt_len - ip_len ); break; default: // We have an unknown ICMP packet type. Do nothing. priv_retval = ANAL_PACKET_IGNORED; DBG_PRINT("Received unknown ICMP packet type: %d, code:%d, len:%d\n", icmp_hdr->icmp_type, icmp_hdr->icmp_code, pkt_len - ip_len); break; } } else if( p_engine->icmp_saf == AF_INET6 ) { // NOTE: On IPV6 raw sockets, the IPv6 is not included in the packet // data. // Verify if packet length is big enough to be an ICMP packet. if( pkt_len < sizeof(ICMP_ECHO_HEADER) ) { // This packet is too small to be an ICMP packet. priv_retval = ANAL_PACKET_BAD; DBG_PRINT("Packet is too small to be an ICMP packet. ICMP length:%d\n", pkt_len); break; } // Cast raw packet data to the ICMP echo header. icmp_hdr = (PICMP_ECHO_HEADER)pkt_data; // Check ICMP type switch( icmp_hdr->icmp_type ) { case ICMP6_ECHO_REPLY_TYPE: // Received an ECHO REPLY. Good. break; case ICMP6_ECHO_REQUEST_TYPE: // Received an ECHO REQUEST. We're not replying. priv_retval = ANAL_PACKET_IGNORED; DBG_PRINT("<< ICMPv6 ECHO REQUEST, id:%d, seq:%d, len:%d\n", icmp_hdr->echo_id, icmp_hdr->echo_seq, pkt_len ); break; case ICMP6_ROUTER_ADVERTISEMENT: // These are sometimes received on the ICMP socket. Logged for informational purposes only. priv_retval = ANAL_PACKET_IGNORED; DBG_PRINT("<< ICMPv6 ROUTER ADVERTISEMENT, code:%d, len:%d\n", icmp_hdr->icmp_code, pkt_len ); break; case ICMP6_NEIGHBOR_SOLICITATION: // These are sometimes received on the ICMP socket. Logged for informational purposes only. priv_retval = ANAL_PACKET_IGNORED; DBG_PRINT("<< ICMPv6 NEIGHBOR SOLICITATION, code:%d, len:%d\n", icmp_hdr->icmp_code, pkt_len ); break; case ICMP6_NEIGHBOR_ADVERTISEMENT: // These are sometimes received on the ICMP socket. Logged for informational purposes only. priv_retval = ANAL_PACKET_IGNORED; DBG_PRINT("<< ICMPv6 NEIGHBOR ADVERTISEMENT, code:%d, len:%d\n", icmp_hdr->icmp_code, pkt_len ); break; default: // We have an unknown ICMP packet type. Do nothing. priv_retval = ANAL_PACKET_IGNORED; DBG_PRINT("Received unknown ICMPv6 packet type: %d, len:%d\n", icmp_hdr->icmp_type, pkt_len ); break; } } if( priv_retval != ANAL_PACKET_PINGIN_ONTIME ) { // Packet is not an ICMP reply. Do not analyze it any further. break; } // Assert the ICMP code. if( icmp_hdr->icmp_code != ICMP_ECHO_CODE ) { // If the type is an ECHO reply, the code should be ICMP_ECHO_CODE. priv_retval = IEE_GENERAL_ECHO_ERROR; DBG_PRINT("Invalid ICMP code for ECHO REPLY. ICMP code:%d\n", icmp_hdr->icmp_code); break; } // Assert the ICMP echo ID. if( icmp_hdr->echo_id != p_engine->icmp_echo_id ) { // The echo ID is different than what we sent. Ignore. priv_retval = ANAL_PACKET_IGNORED; DBG_PRINT("Invalid ICMP echo ID for ECHO REPLY. Echo ID:%d\n", icmp_hdr->echo_id); break; } // ----------------------------------------------------------------- // At this point we should have a valid ICMP ECHO REPLY packet that // belongs to us. // ----------------------------------------------------------------- *echo_seq = icmp_hdr->echo_seq; // Returned echo sequence. // Compute the rtt. rtt = -_compute_tv_diff_now( (struct timeval*)icmp_hdr->echo_data ); if( rtt > (double)p_engine->echo_timeout ) { // We have received a late ICMP echo reply. priv_retval = ANAL_PACKET_PINGIN_LATE; } DBG_PRINT("<< %s ECHO REPLY, seq:%d, len:%d, rtt:%.3fms\n", ICMP_LITTERAL, icmp_hdr->echo_seq, pkt_len - ip_len, rtt ); // Callback the receive function. if( p_engine->clbk_recv != NULL ) { p_engine->clbk_recv( rtt ); } } // Dummy loop end. while(0); return priv_retval; } // -------------------------------------------------------------------------- // _create_insert_echo_event: Private function used to create and insert an // echo event in the engine sorted list of echo events. // // Parameters: // p_engine: Pointer to a ICMP_ECHO_ENGINE_PARMS structure. // tv_sent: Pointer to a timeval structure representing the time at which // an ECHO REQUEST has been sent. // echo_seq: ECHO REQUEST sequence number. // // Returned value: // NULL on memory allocation error. The pointer to the newly created echo // event is returned otherwise. // PECHO_EVENT _create_insert_echo_event( PICMP_ECHO_ENGINE_PARMS p_engine, struct timeval* tv_sent, uint32_t echo_seq ) { PECHO_EVENT p_event = NULL; // Allocate the memory for a new echo event. p_event = (PECHO_EVENT)pal_malloc( sizeof(ECHO_EVENT) ); if( p_event != NULL ) { p_event->next = NULL; p_event->echo_seq = echo_seq; memcpy( &p_event->tv_timeout, tv_sent, sizeof(struct timeval) ); // Add the default echo timeout to get time at which this echo request // will timeout. _compute_echo_timeout( p_engine, &p_event->tv_timeout ); // Insert the echo event in the sorted list of echo events. _insert_echo_event( p_engine, p_event ); } return p_event; } // -------------------------------------------------------------------------- // _insert_echo_event: Private function used to insert an echo event in the // echo engine sorted list of echo events. // // Parameter: // p_engine: Pointer to a ICMP_ECHO_ENGINE_PARMS structure. // p_event_insert: Echo event to insert. // // Return value: (none) // void _insert_echo_event( PICMP_ECHO_ENGINE_PARMS p_engine, PECHO_EVENT p_event_insert ) { PECHO_EVENT * pp_event = &(p_engine->event_list); // Insert the event in the sorted list. do { // End of list; insert here. if( *pp_event == NULL ) { *pp_event = p_event_insert; p_event_insert->next = NULL; break; } // Check if the p_event_insert is due later than the current list element. if( _compare_tv( &p_event_insert->tv_timeout, &(*pp_event)->tv_timeout ) > 0.0 ) { // The event to insert is due later. // => Move to the next element in the list. pp_event = &((*pp_event)->next); } else { // The event to insert is due sooner. // => Insert before the current list element. p_event_insert->next = *pp_event; (*pp_event)->next = p_event_insert; break; } } while(1); // Endless loop. } // -------------------------------------------------------------------------- // _remove_free_echo_event: Private function used to remove and free an echo // event from the echo engine sorted list of echo events. // // Parameters: // p_engine: Pointer to a ICMP_ECHO_ENGINE_PARMS structure. // echo_id: The echo id of the event to remove and free. // // Return value: // ECHO_EVENT_REMOVED if the echo event was found, and removed. // ECHO_EVENT_NOTFOUND if the echo event could not be found. // iee_priv_ret_t _remove_free_echo_event( PICMP_ECHO_ENGINE_PARMS p_engine, uint32_t echo_seq ) { iee_priv_ret_t priv_retval = ECHO_EVENT_NOTFOUND; PECHO_EVENT *pp_event = &(p_engine->event_list); PECHO_EVENT p_event_to_free = NULL; while( *pp_event != NULL ) { if( (*pp_event)->echo_seq == echo_seq ) { // Save the pointer to the echo event to remove. p_event_to_free = *pp_event; // Fix the chained event list. *pp_event = (*pp_event)->next; // Free the echo event. pal_free(p_event_to_free); priv_retval = ECHO_EVENT_REMOVED; break; } pp_event = &(*pp_event)->next; } return priv_retval; } // -------------------------------------------------------------------------- // _free_echo_event_list: Private function used to free a list of echo event // list. This function is called back recursively. // // Parameter: // p_event_list: list of echo events. // // Return value: (none) // void _free_echo_event_list( PECHO_EVENT p_event ) { if( p_event != NULL ) { // Free the next event firsthand. _free_echo_event_list( p_event->next ); // Free this event. pal_free( p_event ); } } // -------------------------------------------------------------------------- // _compute_next_send: private function used to compute the next value of // tv_next_send. Adds one send interval to the timeval. // // Parameters: // p_engine: Pointer to a ICMP_ECHO_ENGINE_PARMS structure. // tv_next_send: Pointer to timeval structure representing at what time the // next send should occur. // // Returned value: (none) // void _compute_next_send( PICMP_ECHO_ENGINE_PARMS p_engine, struct timeval* tv_next_send ) { tv_next_send->tv_sec += p_engine->send_interval / 1000; tv_next_send->tv_usec += (p_engine->send_interval % 1000) * 1000; } // -------------------------------------------------------------------------- // _compute_echo_timeout: private function used to compute the timeout value // of an echo event. // // Parameters: // p_engine: Pointer to a ICMP_ECHO_ENGINE_PARMS structure. // tv_timeout: Pointer to timeval structure that represents the time at // which an ECHO REQUEST was sent. // // Returned value: (none) // void _compute_echo_timeout( PICMP_ECHO_ENGINE_PARMS p_engine, struct timeval* tv_timeout ) { if( p_engine->eng_mode == IEE_MODE_ACD ) { // When the IEE is in mode ACD, the echo timeout is calculated in a // different way. p_engine->echo_timeout = p_engine->send_interval * (p_engine->echo_num - p_engine->count_send); } // Normal behavior: Add the echo timeout parameter to tv_timeout. tv_timeout->tv_sec += p_engine->echo_timeout / 1000; tv_timeout->tv_usec += (p_engine->echo_timeout % 1000) * 1000; // Check tv_usec overflow: while( tv_timeout->tv_usec > 1000000 ) { tv_timeout->tv_usec -= 1000000; tv_timeout->tv_sec++; } } // -------------------------------------------------------------------------- // _conv_ms_to_tv: private function to convert a double value expressing // milliseconds into a timeval, hence keeping the // microsecond precision. // If 'ms' is negative, tv is zeroed out. // // Parameters: // ms: Value to convert. This value expresses milliseconds with microsecond // precision. // tv: Will be set to represent the ms value. // // Return value: (none) // void _conv_ms_to_tv( double ms, struct timeval* tv ) { if( ms > 0.0 ) { tv->tv_sec = (uint32_t)ms / 1000; tv->tv_usec = (uint32_t)((ms - (tv->tv_sec * 1000)) * 1000.0); } else { // Zero. memset( tv, 0, sizeof(*tv)); } } // -------------------------------------------------------------------------- // _compute_tv_diff_now: private function used to calculate the difference // between a timeval value and 'now'. // // Parameters: // tv_diff: Pointer to timeval structure to diff with 'now'. // // Return value: // The number of miliseconds in which tv_diff will occur. If returned value // is negative, it means that tv_diff is in the past; i.e.: tv_diff < tv_now // double _compute_tv_diff_now( struct timeval* tv_diff ) { struct timeval tv_now; pal_gettimeofday( &tv_now ); return _compare_tv( tv_diff, &tv_now ); } // -------------------------------------------------------------------------- // _compare_tv: Private function use to compare two timeval structure values. // // Parameter: // tv_1: Pointer to timeval structure #1 // tv_2: Pointer to timeval structure #2 // // Return value: // The number of miliseconds of difference between each value: // if tv_1 > tv_2, the return value will be positive. // if tv_1 < tv_2, the return value will be negative. // If they're both equal, the return value will be zero. // double _compare_tv( struct timeval* tv_1, struct timeval* tv_2 ) { return ((double)(tv_1->tv_sec - tv_2->tv_sec)) * 1000.0 + ((double)(tv_1->tv_usec - tv_2->tv_usec)) / 1000.0; } gogoc-1_2-RELEASE/gogoc-tsp/src/net/net.c0100644000000000000000000001351711301544622016526 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: net.c,v 1.1 2009/11/20 16:53:38 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ #include "platform.h" #include "gogoc_status.h" #include "tsp_net.h" #include "net.h" #include "log.h" #include "hex_strings.h" // -------------------------------------------------------------------------- // parse_addr_port: // // This function will separate the hostname(or address) and port from a // string that contains both in the form: // inet4: "hostname.example.org:3756" // inet4: "24.58.29.78:3756" // inet6: "hostnamev6.example.com:3563" // inet6: "[2001:5c0::BABA]:3563" // If port is not specified, the default port number will be used. // // NOTE: MEMORY IS ALLOCATED HERE, USE free TO FREE 'addr' MEMORY. // // Return value: 0 on success, any other value means error. // sint32_t parse_addr_port( const char* addr_port, char** addr, uint16_t* port, uint16_t dflt_port ) { char buffer[MAXNAME]; // Memory buffer for string manipulations. char *srvname=NULL; char *srvport=NULL; // Parameter validation. if( addr == NULL ) return -1; // Work on a copy of 'addr_port'. pal_snprintf( buffer, sizeof buffer, "%s", addr_port); // ------------------- // Parse server name. // ------------------- srvname = strchr( buffer,'[' ); if( srvname != NULL ) { // IPv6 address. srvname = strtok( buffer, "]" ); srvname = buffer+1; } else { // IPv4 address srvname = strtok( buffer, ":" ); } // Alloc memory and copy server name in 'addr'. *addr = (char*) pal_malloc( pal_strlen(srvname) + 1 ); if( !*addr ) { Display(LOG_LEVEL_1, ELError, "parse_addr_port", STR_GEN_MALLOC_ERROR ); return -1; } pal_strcpy( *addr, srvname ); // ------------------- // Parse port number. // ------------------- srvport = strtok( NULL, ":" ); if( srvport != NULL ) { sint32_t si32_port = atoi(srvport); // Port was specified, perform integer validation. if( si32_port <= 0 || si32_port >= 65536 ) { Display( LOG_LEVEL_1, ELError, "parse_addr_port", GOGO_STR_SERVICE_PORT_INVALID, srvport ); pal_free( *addr ); return -1; } *port = (uint16_t)si32_port; } else { // Port was not specified, use default port. *port = dflt_port; } return 0; } /* * Convert IPv4 address from string format to in_addr structure. * Port information are discarted. * * in_addr structure must be supplied and allocated * * return NULL if errors, supplied in_addr structure if success. */ struct in_addr *NetText2Addr(char *Address, struct in_addr *in_p) { struct addrinfo hints; struct addrinfo *res=NULL, *result=NULL; char addr_cp[MAXSERVER]; char *addr; if (NULL == Address || NULL == in_p) return NULL; /* Prepare hints structure */ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = PF_UNSPEC; /* copy the string before using strtok */ strcpy(addr_cp, Address); /* be sure it is not an in-brackets v6 address */ if ((strchr(Address, '[') != NULL) || (strchr(Address, ']') != NULL)) goto error_v4; // be sure no more than on ':' is used to specify port number // (not IPv6 address without brakets! if( (addr = strchr(Address, ':')) != NULL ) { if( strchr(addr+1,':') != NULL ) goto error_v4; } /* Remove port number if any */ addr = addr_cp; strtok(addr_cp, ":"); if( (getaddrinfo(addr, NULL, &hints, &res)) == 0 ) { for(result = res; result; result = result->ai_next) { if (result->ai_family != AF_INET) continue; memcpy(in_p, &((struct sockaddr_in *)result->ai_addr)->sin_addr, sizeof(struct in_addr)); freeaddrinfo(res); return in_p; } } error_v4: /* Cannot resolve */ Display(LOG_LEVEL_3, ELWarning, "NetText2Addr", GOGO_STR_SERVER_NOT_IPV4); if (res != NULL) freeaddrinfo(res); return NULL; } /* * Convert IPv6 address from string format to in6_addr structure. * * The following format are supported (port information is ignored): * * "X:X::X:X" * "[X:X::X:X]" * "[X:X::X:X]:port" * "hostname" * "hostname:port" * * in6_addr structure must be supplied and allocated * * return NULL if errors, supplied in6_addr structure if success. */ struct in6_addr *NetText2Addr6(char *Address, struct in6_addr *in6_p) { struct addrinfo hints; struct addrinfo *res = NULL; struct addrinfo *result = NULL; char addr[MAXSERVER]; char *p; int c = 0; if (NULL == Address || NULL == in6_p) return NULL; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = PF_INET6; /* Copy the address before stripping */ addr[sizeof(addr) - 1] = '\0'; strncpy(addr, Address, sizeof(addr) - 1); /* * Numeric address has more than one colon */ for(p = addr; *p != '\0'; p++) if (':' == *p) c++; p = addr; if (c > 1) { /* Numeric address */ hints.ai_flags = AI_NUMERICHOST; /* Strip the bracket and port information if any */ if ('[' == *p) { strtok(p, "]"); p++; /* Skip [ */ } } else { /* Hostname: strip the port information if any */ strtok(p, ":"); } if ((getaddrinfo(p, NULL, &hints, &res)) == 0) { for (result = res; result; result = result->ai_next) { if (result->ai_family != AF_INET6) continue; memcpy(in6_p, &((struct sockaddr_in6 *)result->ai_addr)->sin6_addr, sizeof(struct in6_addr)); freeaddrinfo(res); return in6_p; } } /* Cannot resolve */ Display(LOG_LEVEL_3, ELWarning, "NetText2Addr6", GOGO_STR_SERVER_NOT_IPV6); if (res != NULL) freeaddrinfo(res); return NULL; } gogoc-1_2-RELEASE/gogoc-tsp/src/net/net_cksm.c0100644000000000000000000000153711301544623017543 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: net_cksm.c,v 1.1 2009/11/20 16:53:39 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ #include "platform.h" #include "net_cksm.h" /* checksum calculation */ uint16_t in_cksum( uint16_t *addr, sint32_t len ) { sint32_t nleft = len; sint32_t sum = 0; uint16_t *w = addr; uint16_t answer = 0; while (nleft > 1) { sum += *w++; nleft -= 2; } if (nleft == 1) { *(uint8_t *) (&answer) = *(uint8_t *) w; sum += answer; } sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); answer = (uint16_t)(~sum); return (answer); } gogoc-1_2-RELEASE/gogoc-tsp/src/net/net_echo_request.c0100644000000000000000000004646211301544623021302 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: net_echo_request.c,v 1.1 2009/11/20 16:53:39 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ #include "platform.h" #include "gogoc_status.h" #include "net_rudp.h" #include "tsp_net.h" #include "net.h" #include "log.h" #include "hex_strings.h" #include "tsp_redirect.h" #include "tsp_client.h" #include "net_echo_request.h" /* Create a stat engine for a distance calculation thread */ rttengine_stat_t *createStatEngine() { rttengine_stat_t *engine = NULL; /* Allocate memory */ engine = (rttengine_stat_t *)pal_malloc(sizeof(rttengine_stat_t)); if( engine == NULL ) { return NULL; } /* And zero it */ memset( engine, 0, sizeof(rttengine_stat_t) ); return engine; } /* Create a socket and connect it to a given address */ pal_socket_t createConnectedSocket(struct addrinfo *address_info) { pal_socket_t sfd; struct sockaddr_in sai; struct sockaddr_in6 sai6; struct sockaddr *sa = NULL; sint32_t sa_len = 0; /* Zero out the structures */ memset(&sai, 0, sizeof(struct sockaddr_in)); memset(&sai6, 0, sizeof(struct sockaddr_in6)); /* It's an IPv4 address */ if (address_info->ai_family == AF_INET) { /* Copy the information into the IPv4-specific structure */ memcpy(&sai.sin_addr, &(((struct sockaddr_in *)address_info->ai_addr)->sin_addr), sizeof(struct in_addr)); sai.sin_family = AF_INET; sai.sin_port = htons(SERVER_PORT); /* Set a generic pointer for the connect() call */ sa = (struct sockaddr *)&sai; sa_len = sizeof(struct sockaddr_in); } /* It's an IPv6 address */ else if (address_info->ai_family == AF_INET6) { /* Copy the information into the IPv6-specific structure */ memcpy(&(sai6.sin6_addr), &(((struct sockaddr_in6 *)address_info->ai_addr)->sin6_addr), sizeof(struct in6_addr)); sai6.sin6_family = AF_INET6; sai6.sin6_port = htons(SERVER_PORT); #ifdef SIN6_LEN sai6.sin6_len = sizeof(struct sockaddr_in6); #endif /* Set a generic pointer for the connect() call */ sa = (struct sockaddr *)&sai6; sa_len = sizeof(struct sockaddr_in6); } else { return (pal_socket_t)(-1); } /* Create the socket */ if ((sfd = pal_socket(address_info->ai_family, address_info->ai_socktype, 0)) == -1) { return (pal_socket_t)(-1); } /* And connect it using the generic pointer */ if (connect(sfd, sa, sa_len) == -1) { return (pal_socket_t)(-1); } return sfd; } /* Destroy a socket */ sint32_t destroySocket(pal_socket_t sfd) { pal_shutdown( sfd, PAL_SOCK_SHTDN_BOTH ); pal_closesocket( sfd ); return 0; } /* Thread routine to calculate the distance for a given broker */ pal_thread_ret_t PAL_THREAD_CALL tspGetBrokerDistance(void *threadarg) { tBrokerTimingThreadArg *arguments = NULL; tBrokerList *broker = NULL; tConf *conf = NULL; tRedirectStatus status = TSP_REDIRECT_OK; unsigned int distance = 0; /* The thread needs a broker argument to work with */ if (threadarg == NULL) { pal_thread_exit((pal_thread_ret_t)(-1)); return (pal_thread_ret_t)(-1); } /* Unwrap the arguments */ arguments = (tBrokerTimingThreadArg *)threadarg; broker = (tBrokerList *)arguments->broker; conf = (tConf *)arguments->conf; /* Perform the echo request, calculating the distance */ status = tspDoEchoRequest(broker->address, broker->address_type, conf, &distance); /* Set the calculated distance in the broker list element */ broker->distance = distance; /* Make the status available on join */ pal_thread_exit((pal_thread_ret_t)status); return (pal_thread_ret_t)status; } /* Fill the distance values for the brokers in a list */ tRedirectStatus tspGetBrokerDistances(tBrokerList *broker_list, int broker_count, tConf *conf) { sint32_t rc = 0; int t = 0; tRedirectStatus status = TSP_REDIRECT_OK; pal_thread_ret_t thread_status = 0; pal_thread_t *threads = NULL; tBrokerTimingThreadArg *thread_arguments = NULL; tBrokerList *broker_list_index = NULL; /* Initialize thread array */ if ((threads = (pal_thread_t *)malloc(broker_count * sizeof(pal_thread_t))) == NULL) { Display(LOG_LEVEL_1, ELError, "tspGetBrokerDistances", GOGO_STR_RDR_CANT_MALLOC_THREAD_ARRAY); return TSP_REDIRECT_CANT_MALLOC_THREAD_ARRAY; } /* Initialize thread argument array */ if ((thread_arguments = (tBrokerTimingThreadArg *)malloc(broker_count * sizeof(tBrokerTimingThreadArg))) == NULL) { free(threads); Display(LOG_LEVEL_1, ELError, "tspGetBrokerDistances", GOGO_STR_RDR_CANT_MALLOC_THREAD_ARGS); return TSP_REDIRECT_CANT_MALLOC_THREAD_ARGS; } /* We start at the beginning of the broker list */ broker_list_index = broker_list; /* Loop through the broker list */ for (t = 0; ((t < broker_count) && (broker_list_index != NULL)); t++) { Display(LOG_LEVEL_3, ELInfo, "tspGetBrokerDistances", GOGO_STR_RDR_CREATING_DISTANCE_THREAD, broker_list_index->address); /* Set the thread arguments */ thread_arguments[t].broker = broker_list_index; thread_arguments[t].conf = conf; /* Start the distance calculation thread for that broker in the list */ rc = pal_thread_create( &threads[t], &tspGetBrokerDistance, (void *)&thread_arguments[t] ); /* If we can't create the thread, return an error */ if( rc != 0 ) { free(threads); free(thread_arguments); Display(LOG_LEVEL_1, ELError, "tspGetBrokerDistances", GOGO_STR_RDR_CANT_CREATE_DISTANCE_THREAD, broker_list_index->address); return TSP_REDIRECT_CANT_CREATE_THREAD; } /* Move to the next broker in the list */ broker_list_index = broker_list_index->next; } /* We start from the begining of the list again to join the threads */ broker_list_index = broker_list; /* Loop through the broker list */ for (t = 0; ((t < broker_count) && (broker_list_index != NULL)); t++) { Display(LOG_LEVEL_3, ELInfo, "tspGetBrokerDistances", GOGO_STR_RDR_WAITING_FOR_THREAD, broker_list_index->address); /* Try to join the thread corresponding to the broker in the list */ rc = pal_thread_join( threads[t], (pal_thread_ret_t*)&thread_status ); /* If we can't join the thread, return an error */ if( rc != 0 ) { free(threads); free(thread_arguments); Display(LOG_LEVEL_1, ELError, "tspGetBrokerDistances", GOGO_STR_RDR_ERR_WAITING_FOR_THREAD, broker_list_index->address); return TSP_REDIRECT_CANT_WAIT_FOR_THREAD; } status = (tRedirectStatus)thread_status; /* The distance was calculated correctly */ if (status == TSP_REDIRECT_OK) { Display(LOG_LEVEL_3, ELInfo, "tspGetBrokerDistances", GOGO_STR_RDR_DISTANCE_CALCULATION_OK, broker_list_index->address, broker_list_index->distance); } /* Echo requests timed out */ else if (status == TSP_REDIRECT_ECHO_REQUEST_TIMEOUT) { Display(LOG_LEVEL_3, ELInfo, "tspGetBrokerDistances", GOGO_STR_RDR_DISTANCE_CALCULATION_TIMEOUT, broker_list_index->address); } /* There was an error somewhere */ else { Display(LOG_LEVEL_1, ELError, "tspGetBrokerDistances", GOGO_STR_RDR_DISTANCE_CALCULATION_ERR, broker_list_index->address); } /* We move to the next broker in the list */ broker_list_index = broker_list_index->next; } free(threads); free(thread_arguments); return TSP_REDIRECT_OK; } /* Calculate the roundtrip time to a brokre using a TSP echo request */ tRedirectStatus timeEchoRequestReply(pal_socket_t sfd, char *address, rttengine_stat_t *engine, uint32_t *distance) { char data_in[ECHO_REQUEST_IN_BUF_SIZE]; char data_out[ECHO_REQUEST_OUT_BUF_SIZE]; sint32_t data_in_size = 0; size_t data_out_size = 0; rudp_msghdr_t *imh = NULL; rudp_msghdr_t *omh = NULL; void *om = NULL; void *im = NULL; sint32_t length_sent = 0; sint32_t ret = 0; fd_set fs; struct timeval tv_select; /* The receive buffer is empty */ memset(data_in, 0, sizeof(data_in)); /* The send buffer contains the "ECHO REQUEST" command */ pal_snprintf(data_out, sizeof(data_out), ECHO_REQUEST_COMMAND); /* Calculate the buffer sizes */ data_in_size = sizeof(data_in); data_out_size = pal_strlen(data_out); /* Prepare RUDP messages */ im = internal_prepare_message(&imh, data_in_size); om = internal_prepare_message(&omh, data_out_size); /* A NULL message is an error */ if ((im == NULL) || (om == NULL)) { rttengine_deinit(engine, im, om); *distance += ECHO_REQUEST_ERROR_ADJUST; Display(LOG_LEVEL_1, ELError, "timeEchoRequestReply", GOGO_STR_RDR_ERROR_PREPARING_RUDP_MSG, address); return TSP_REDIRECT_ECHO_REQUEST_ERROR; } /* Zero them out */ memset(im, 0, data_in_size); memset(om, 0, data_out_size); /* Copy the outgoing data to the data part of the outgoing message */ memcpy((char*)om + sizeof(rudp_msghdr_t), data_out, data_out_size); /* Set the outgoing message's sequence number */ omh->sequence = htonl(engine->sequence++ | 0xf0000000); send_loop: /* Fail if we have reached the maximum number of echo request attempts */ if (engine->retries == ECHO_REQUEST_ATTEMPTS) { rttengine_deinit(engine, im, om); *distance += ECHO_REQUEST_TIMEOUT_ADJUST; Display(LOG_LEVEL_3, ELWarning, "timeEchoRequestReply", GOGO_STR_RDR_MAX_ECHO_REPLY_ATTEMPTS, ECHO_REQUEST_ATTEMPTS, address); return TSP_REDIRECT_ECHO_REQUEST_TIMEOUT; } /* Set the timestamp for the outgoing message */ omh->timestamp = htonl(internal_get_timestamp(engine)); /* Try to send the outgoing message */ Display(LOG_LEVEL_3, ELInfo, "timeEchoRequestReply", GOGO_STR_RDR_SENDING_ECHO_REQUEST, (engine->retries + 1), address); if ((length_sent = send(sfd, om, (sint32_t)(data_out_size + sizeof(rudp_msghdr_t)), 0)) == -1) { rttengine_deinit(engine, im, om); *distance += ECHO_REQUEST_ERROR_ADJUST; Display(LOG_LEVEL_1, ELError, "timeEchoRequestReply", GOGO_STR_RDR_SEND_ECHO_REQUEST_FAILED, address); return TSP_REDIRECT_ECHO_REQUEST_ERROR; } /* Set the timeout for the select */ /* This is the maximum time we will wait for an echo reply */ tv_select.tv_sec = ECHO_REQUEST_TIMEOUT / 1000; tv_select.tv_usec = (ECHO_REQUEST_TIMEOUT % 1000) * 1000; select_loop: FD_ZERO(&fs); FD_SET(sfd, &fs); Display(LOG_LEVEL_3, ELInfo, "timeEchoRequestReply", GOGO_STR_RDR_WAITING_ECHO_REPLY, address); /* Wait on the socket set */ ret = select((sint32_t)sfd + 1, &fs, NULL, NULL, &tv_select); switch(ret) { /* Select timed out, try again */ case 0: Display(LOG_LEVEL_3, ELWarning, "timeEchoRequestReply", GOGO_STR_RDR_WAITING_ECHO_REPLY_TIMEOUT, address); engine->retries++; goto send_loop; /* Ok, select got something */ case 1: Display(LOG_LEVEL_3, ELWarning, "timeEchoRequestReply", GOGO_STR_RDR_RECEIVING_RUDP_MESSAGE, address); /* Receive the incoming data, and store it in the incoming message */ ret = recv(sfd, im, (sizeof(rudp_msghdr_t) + data_in_size), 0); /* This is a fatal read error */ if (ret == -1) { rttengine_deinit(engine, im, om); *distance += ECHO_REQUEST_ERROR_ADJUST; Display(LOG_LEVEL_1, ELError, "timeEchoRequestReply", GOGO_STR_RDR_ERR_RECEIVING_RUDP_FROM, address); return TSP_REDIRECT_ECHO_REQUEST_ERROR; } /* If we have the same sequence number, this is the message we want */ if (imh->sequence == omh->sequence) { *distance += internal_get_timestamp(engine) - ntohl(omh->timestamp); ret = ret - sizeof(rudp_msghdr_t); Display(LOG_LEVEL_3, ELInfo, "timeEchoRequestReply", GOGO_STR_RDR_RECEIVED_RUDP_OK, address); break; } /* If the sequence numbers are different, see if we get something else */ else { Display(LOG_LEVEL_3, ELWarning, "timeEchoRequestReply", GOGO_STR_RDR_RECV_RUDP_SEQ_DIFFERS, address); goto select_loop; } /* This is an unknown error */ default: rttengine_deinit(engine, im, om); *distance += ECHO_REQUEST_ERROR_ADJUST; Display(LOG_LEVEL_1, ELError, "timeEchoRequestReply", GOGO_STR_RDR_ERR_WAITING_ECHO_REPLY, address); return TSP_REDIRECT_ECHO_REQUEST_ERROR; } /* Update the stat engine */ rttengine_update(engine, (internal_get_timestamp(engine) - ntohl(imh->timestamp))); /* Copy the data part of the incoming message to the receiving buffer */ memcpy(data_in, (char*)im + sizeof(rudp_msghdr_t), ret); /* Free the messages */ internal_discard_message(im); internal_discard_message(om); engine->retries = 0; /* Validate that we got the right answer from the broker */ if (tspGetStatusCode(data_in) != ECHO_REQUEST_SUCCESS_STATUS) { Display(LOG_LEVEL_1, ELError, "timeEchoRequestReply", GOGO_STR_RDR_RCV_UNEXPECTED_ECHO_REPLY, address, data_in); return TSP_REDIRECT_ECHO_REQUEST_ERROR; } Display(LOG_LEVEL_3, ELInfo, "timeEchoRequestReply", GOGO_STR_RDR_RCV_EXPECTED_ECHO_REPLY, address, data_in); return TSP_REDIRECT_OK; } /* Get a socket address structure from a server string */ tSocketAddressStatus getSocketAddress(char *server, tBrokerAddressType address_type, tTunnelMode tunnel_mode, struct addrinfo **address_info_root, struct addrinfo **address_info) { struct addrinfo hints; struct addrinfo *result = NULL; tSocketAddressStatus status = SOCKET_ADDRESS_OK; struct addrinfo *result_index = NULL; sint32_t need_v6_endpoint = 0; sint32_t found_family_address = 0; /* Zero out the hints */ memset(&hints, 0, sizeof(struct addrinfo)); /* We're doing UDP */ hints.ai_socktype = SOCK_DGRAM; /* Determine if we need to connect to an IPv6 address */ /* based on the configured tunnel mode */ if (tunnel_mode == V4V6) { need_v6_endpoint = 1; } /* Set some more hints based on the type of address */ /* present in the broker list */ switch (address_type) { case TSP_REDIRECT_BROKER_TYPE_NONE: return SOCKET_ADDRESS_ERROR; case TSP_REDIRECT_BROKER_TYPE_IPV4: hints.ai_family = AF_INET; hints.ai_flags |= AI_NUMERICHOST; break; case TSP_REDIRECT_BROKER_TYPE_IPV6: hints.ai_family = AF_INET6; hints.ai_flags |= AI_NUMERICHOST; break; case TSP_REDIRECT_BROKER_TYPE_FQDN: hints.ai_family = AF_UNSPEC; break; } /* Get an address structure using the broker address and the hints */ if ((getaddrinfo(server, SERVER_PORT_STR, &hints, &result)) != 0) { if (result != NULL) { freeaddrinfo(result); } return SOCKET_ADDRESS_PROBLEM_RESOLVING; } /* We start with the first address found */ result_index = result; switch (address_type) { case TSP_REDIRECT_BROKER_TYPE_NONE: return SOCKET_ADDRESS_ERROR; case TSP_REDIRECT_BROKER_TYPE_IPV4: if (need_v6_endpoint) { /* We need IPv6, but it's an IPv4 */ status = SOCKET_ADDRESS_WRONG_FAMILY; } else { status = SOCKET_ADDRESS_OK; } break; case TSP_REDIRECT_BROKER_TYPE_IPV6: if (need_v6_endpoint) { status = SOCKET_ADDRESS_OK; } else { /* We need IPv4, but it's an IPv6 */ status = SOCKET_ADDRESS_WRONG_FAMILY; } break; case TSP_REDIRECT_BROKER_TYPE_FQDN: /* It's an FQDN, try to find an address of the correct family */ for (result_index = result; result_index; result_index = result_index->ai_next) { if ((need_v6_endpoint && (result_index->ai_family == AF_INET6)) || (!need_v6_endpoint && (result_index->ai_family == AF_INET))) { /* We found one */ found_family_address = 1; break; } } /* If we found an address of the right family, all is ok */ if (found_family_address) { status = SOCKET_ADDRESS_OK; } /* If we did not, there's a family problem and we take the */ /* first address of the wrong family */ else { status = SOCKET_ADDRESS_WRONG_FAMILY; result_index = result; } break; } /* Set the address info root pointer so we can free it later */ *address_info_root = result; /* Set the pointer to the address information */ *address_info = result_index; return status; } /* Initialize what's needed, perform calculation using an echo */ /* request, and deinitialize */ tRedirectStatus tspDoEchoRequest(char *address, tBrokerAddressType address_type, tConf *conf, uint32_t *distance) { rttengine_stat_t *engine = NULL; struct addrinfo *address_info = NULL; struct addrinfo *address_info_root = NULL; pal_socket_t sfd; tSocketAddressStatus socket_address_status = SOCKET_ADDRESS_OK; tRedirectStatus status = TSP_REDIRECT_OK; /* Initilalize some stuff */ *distance = 0; /* Get an address structure and see if we have the right address family */ socket_address_status = getSocketAddress(address, address_type, conf->tunnel_mode, &address_info_root, &address_info); /* Wrong family, log and modify the distance so it goes at the end of the sorted list */ if (socket_address_status == SOCKET_ADDRESS_WRONG_FAMILY) { *distance = ECHO_REQUEST_WRONG_FAMILY_ADJUST; Display(LOG_LEVEL_1, ELError, "tspDoEchoRequest", GOGO_STR_RDR_WRONG_ADDRESS_FAMILY, address); } /* There was some kind of error, adjust the distance to make it go after the brokers that */ /* could be timed properly. */ else if (socket_address_status == SOCKET_ADDRESS_ERROR) { *distance = ECHO_REQUEST_ERROR_ADJUST; if (address_info_root != NULL) { freeaddrinfo(address_info_root); } Display(LOG_LEVEL_1, ELError, "tspDoEchoRequest", GOGO_STR_RDR_ERROR_GET_SOCKADDRESS, address); return TSP_REDIRECT_ECHO_REQUEST_ERROR; } /* Could not resolve, this is treated the same as an error */ else if (socket_address_status == SOCKET_ADDRESS_PROBLEM_RESOLVING) { *distance = ECHO_REQUEST_ERROR_ADJUST; if (address_info_root != NULL) { freeaddrinfo(address_info_root); } Display(LOG_LEVEL_1, ELError, "tspDoEchoRequest", GOGO_STR_RDR_ERROR_RESOLVING_DN, address); return TSP_REDIRECT_ECHO_REQUEST_ERROR; } /* Connect to the address */ if ((sfd = createConnectedSocket(address_info)) == -1) { *distance += ECHO_REQUEST_ERROR_ADJUST; if (address_info_root != NULL) { freeaddrinfo(address_info_root); } destroySocket(sfd); Display(LOG_LEVEL_1, ELError, "tspDoEchoRequest", GOGO_STR_RDR_ERROR_CONNECT_SOCKET, address); return TSP_REDIRECT_ECHO_REQUEST_ERROR; } if (address_info_root != NULL) { freeaddrinfo(address_info_root); } /* Create a stat engine */ if ((engine = createStatEngine()) == NULL) { *distance += ECHO_REQUEST_ERROR_ADJUST; destroySocket(sfd); Display(LOG_LEVEL_1, ELError, "tspDoEchoRequest", GOGO_STR_RDR_ERROR_CREATE_STAT_ENGINE, address); return TSP_REDIRECT_ECHO_REQUEST_ERROR; } /* Initialize the stat engine */ if (rttengine_init(engine) != 1) { *distance += ECHO_REQUEST_ERROR_ADJUST; destroySocket(sfd); pal_free(engine); Display(LOG_LEVEL_1, ELError, "tspDoEchoRequest", GOGO_STR_RDR_ERROR_INIT_STAT_ENGINE, address); return TSP_REDIRECT_ECHO_REQUEST_ERROR; } /* Calculate the roundtrip time */ status = timeEchoRequestReply(sfd, address, engine, distance); /* Destroy the socket */ destroySocket(sfd); /* Uninitialize the stat engine */ rttengine_deinit(engine, NULL, NULL); /* Free the stat engine */ pal_free(engine); return status; } gogoc-1_2-RELEASE/gogoc-tsp/src/net/net_ka.c0100644000000000000000000003355711301544623017210 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: net_ka.c,v 1.1 2009/11/20 16:53:39 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ #include "platform.h" #include "net_ka.h" #include "icmp_echo_engine.h" #include "log.h" #include "hex_strings.h" #define KA_ECHO_REPLY_TIMEOUT 5000 // 5 seconds timeout. #define KA_NUM_CONSEC_TIMEOUT 3 // 3 consecutive timeouts. #ifndef __FUNCTION__ #define __FUNCTION__ __func__ #endif #define LOG_MESSAGE(LVL,SEV,MSG,...) Display(LVL, SEV, __FUNCTION__, MSG, ##__VA_ARGS__) // -------------------------------------------------------------------------- // Keepalive engine parameters. typedef struct __KA_ENGINE_PARMS { pal_thread_t ka_thread_id; // Keepalive thread ID. ka_status_t ka_status; // Keepalive engine status. void* p_echo_engine; // Opaque data used by the ICMP echo engine. } KA_ENGINE_PARMS, * PKA_ENGINE_PARMS; // -------------------------------------------------------------------------- // KA internal private statuses typedef enum { KA_PRIV_SUCCESS, // General operation successful. KA_INVALID_PARMS, // Invalid input parameter(s). KA_RESOURCE_STARVATION // Resource starvation (memory alloc error). } ka_priv_ret_t; // -------------------------------------------------------------------------- // Local private function prototypes ka_priv_ret_t _create_ka_engine ( PKA_ENGINE_PARMS *pp_engine ); ka_priv_ret_t _destroy_ka_engine ( PKA_ENGINE_PARMS *pp_engine ); pal_thread_ret_t PAL_THREAD_CALL _ka_start_thread( void *arg ); void _ka_send_callback ( void ); void _ka_recv_callback ( double rtt ); // -------------------------------------------------------------------------- // KA_init: Initializes the keepalive engine. // // Parameters: // pp_engine: Double opaque pointer where the keepalive engine parameters // will be stored. // ka_send_interval: The keepalive send interval, in milliseconds. // ka_src_addr: Source address used when sending keepalives. // ka_dst_addr: Destination address where keepalives will be sent. // ka_af: Address family (INET or INET6) used to send keepalives. // // Returned value: // KA_SUCCESS if initialisation was successful. // KA_ERROR if an error occurred. // ka_ret_t KA_init( void ** pp_engine, uint32_t ka_send_interval, char* ka_src_addr, char* ka_dst_addr, sint32_t ka_af ) { PKA_ENGINE_PARMS p_ka_engine; iee_ret_t iee_ret; ka_priv_ret_t ka_priv_ret; // Allocate the Keepalive engine. ka_priv_ret = _create_ka_engine( (PKA_ENGINE_PARMS*)pp_engine ); switch( ka_priv_ret ) { case KA_PRIV_SUCCESS: // No error. Continue on. break; case KA_INVALID_PARMS: // Invalid keepalive engine pointer. LOG_MESSAGE( LOG_LEVEL_1, ELError, STR_KA_INIT_FAIL_CAUSE STR_KA_ERR_ALREADY_INIT ); return KA_ERROR; case KA_RESOURCE_STARVATION: // Memory allocation error. LOG_MESSAGE( LOG_LEVEL_1, ELError, STR_KA_INIT_FAIL_CAUSE STR_GEN_MALLOC_ERROR ); return KA_ERROR; } // Cast the double opaque pointer to a local valid pointer. p_ka_engine = (PKA_ENGINE_PARMS)*pp_engine; // Initialize the ICMP ECHO engine with the keepalive parameters. iee_ret = IEE_init( &p_ka_engine->p_echo_engine, IEE_MODE_KA, ka_send_interval, 0, KA_ECHO_REPLY_TIMEOUT, KA_NUM_CONSEC_TIMEOUT, ka_src_addr, ka_dst_addr, ka_af, &_ka_send_callback, &_ka_recv_callback ); switch( iee_ret ) { case IEE_SUCCESS: // Initialisation successful. LOG_MESSAGE( LOG_LEVEL_2, ELInfo, STR_KA_INIT_INFO, ka_dst_addr, ka_send_interval, KA_ECHO_REPLY_TIMEOUT, KA_NUM_CONSEC_TIMEOUT ); break; case IEE_INVALID_PARMS: // Invalid parameters. LOG_MESSAGE( LOG_LEVEL_1, ELError, STR_KA_INIT_FAIL_CAUSE STR_GEN_INVALID_POINTER ); _destroy_ka_engine( &p_ka_engine ); return KA_ERROR; case IEE_RESOURCE_STARVATION: // Memory allocation error. LOG_MESSAGE( LOG_LEVEL_1, ELError, STR_KA_INIT_FAIL_CAUSE STR_GEN_MALLOC_ERROR ); _destroy_ka_engine( &p_ka_engine ); return KA_ERROR; default: // Should never happen. LOG_MESSAGE( LOG_LEVEL_1, ELError, STR_KA_INIT_FAIL_CAUSE STR_GEN_UNKNOWN_ERROR ); _destroy_ka_engine( &p_ka_engine ); return KA_ERROR; } return KA_SUCCESS; } // -------------------------------------------------------------------------- // KA_start: Start the keepalive main processing thread. Returns immediately // (non-blocking). // // Parameter: // p_engine: Opaque pointer to the Keepalive engine. // // Return values: // KA_SUCCESS indicates the keepalive main thread was started. // KA_ERROR on error // ka_ret_t KA_start( void * p_engine ) { PKA_ENGINE_PARMS p_ka_engine = (PKA_ENGINE_PARMS)p_engine; sint32_t ret; // Check KA engine pointer validity. if( p_ka_engine == NULL ) { // Evil is at work someplace.. LOG_MESSAGE( LOG_LEVEL_1, ELError, STR_KA_START_FAIL_CAUSE STR_GEN_INVALID_POINTER ); return KA_ERROR; } // Start a new thread to process the keepalive messages. ret = pal_thread_create( &p_ka_engine->ka_thread_id, _ka_start_thread, p_ka_engine ); if( ret != 0 ) { // Error starting the keepalive main thread. LOG_MESSAGE( LOG_LEVEL_1, ELError, "%s%d", STR_KA_START_FAIL_CAUSE STR_KA_ERR_THREAD_START, ret ); return KA_ERROR; } // Change the engine status. p_ka_engine->ka_status = KA_STAT_ONGOING; return KA_SUCCESS; } // -------------------------------------------------------------------------- // KA_stop: Stops the ICMP echo engine and wait for the main keepalive // thread to finish. Retrieve the keepalive status with KA_get_status // after the stop is done. // // Parameters: // p_engine: Opaque pointer to the Keepalive engine. // // Return value: // KA_SUCCESS indicates a successful stop. // KA_ERROR on error. // ka_ret_t KA_stop( void * p_engine ) { PKA_ENGINE_PARMS p_ka_engine = (PKA_ENGINE_PARMS)p_engine; iee_ret_t iee_ret; sint32_t ret; // Check echo engine opaque pointer validity. if( p_ka_engine == NULL || p_ka_engine->p_echo_engine == NULL ) { // Evil is at work someplace.. LOG_MESSAGE( LOG_LEVEL_1, ELError, STR_KA_STOP_FAIL_CAUSE STR_GEN_INVALID_POINTER ); return KA_ERROR; } // Issue the stop to the engine. This will asynchronously cause the KA // thread to exit eventually. iee_ret = IEE_stop( p_ka_engine->p_echo_engine ); if( iee_ret != IEE_SUCCESS ) { // Error stopping the echo engine. LOG_MESSAGE( LOG_LEVEL_1, ELError, STR_KA_STOP_FAIL_CAUSE STR_KA_ERR_STOP_IEE ); return KA_ERROR; } // Wait on the KA thread to finish. ret = pal_thread_join( p_ka_engine->ka_thread_id, NULL ); if( ret != 0 ) { // Error joining the keepalive thread. LOG_MESSAGE( LOG_LEVEL_1, ELError, "%s%d", STR_KA_STOP_FAIL_CAUSE STR_KA_ERR_THREAD_JOIN, ret ); return KA_ERROR; } return KA_SUCCESS; } // -------------------------------------------------------------------------- // KA_qry_status: Retrieves the status of the keepalive engine. // // Parameter: // p_engine: Opaque pointer to the Keepalive engine. // // Return value: // The keepalive status (One of the ka_status_t enum). // If the pointer p_engine is invalid, KA_STAT_INVALID is returned. // ka_status_t KA_qry_status( void * p_engine ) { PKA_ENGINE_PARMS p_ka_engine = (PKA_ENGINE_PARMS)p_engine; // Check echo engine opaque pointer validity. if( p_ka_engine == NULL ) { LOG_MESSAGE( LOG_LEVEL_1, ELError, STR_KA_QRYSTATUS_FAIL_CAUSE STR_GEN_INVALID_POINTER ); return KA_STAT_INVALID; } // Return the keepalive status. return p_ka_engine->ka_status; } // -------------------------------------------------------------------------- // KA_destroy: Deallocates memory used by the ICMP echo engine. // // Parameters: // pp_engine: Double opaque pointer to the Keepalive engine. // // Return value: // KA_SUCCESS on success. // KA_ERROR if the destruction of the ICMP echo engine was not successful. // ka_ret_t KA_destroy( void ** pp_engine ) { PKA_ENGINE_PARMS p_ka_engine = (PKA_ENGINE_PARMS)*pp_engine; ka_priv_ret_t ka_priv_ret; iee_ret_t iee_ret; // Check echo engine opaque pointer validity. if( p_ka_engine == NULL || p_ka_engine->p_echo_engine == NULL ) { // Invalid pp_engine pointer. LOG_MESSAGE( LOG_LEVEL_1, ELError, STR_KA_DESTR_FAIL_CAUSE STR_GEN_INVALID_POINTER ); return KA_ERROR; } // Destroy the ICMP echo engine. iee_ret = IEE_destroy( &p_ka_engine->p_echo_engine ); if( iee_ret != IEE_SUCCESS ) { // Failed to destroy the ICMP echo engine. LOG_MESSAGE(LOG_LEVEL_1, ELError, STR_KA_DESTR_FAIL_CAUSE STR_KA_ERR_DESTR_IEE ); return KA_ERROR; } // Destroy the KA engine. ka_priv_ret = _destroy_ka_engine( (PKA_ENGINE_PARMS*)pp_engine ); switch( ka_priv_ret ) { case KA_PRIV_SUCCESS: // Success. break; case KA_INVALID_PARMS: // Invalid pp_engine pointer. LOG_MESSAGE(LOG_LEVEL_1, ELError, STR_KA_DESTR_FAIL_CAUSE STR_GEN_INVALID_POINTER ); return KA_ERROR; default: // Should never happen. LOG_MESSAGE( LOG_LEVEL_1, ELError, STR_KA_DESTR_FAIL_CAUSE STR_GEN_UNKNOWN_ERROR ); return KA_ERROR; } return KA_SUCCESS; } // -------------------------------------------------------------------------- // _create_ka_engine: Allocates the Keepalive engine and initializes it. // // Parameter: // pp_engine: double pointer to the keepalive engine. // // Returned values: // KA_PRIV_SUCCESS: Operation successful. // KA_RESOURCE_STARVATION: Memory allocation error. // KA_INVALID_PARMS: Invalid pp_engine pointer. // ka_priv_ret_t _create_ka_engine( PKA_ENGINE_PARMS* pp_engine ) { if( pp_engine == NULL || *pp_engine != NULL ) { // Invalid double pointer or pointer is not initialized to NULL. return KA_INVALID_PARMS; } *pp_engine = (PKA_ENGINE_PARMS)pal_malloc( sizeof(KA_ENGINE_PARMS) ); if( *pp_engine == NULL ) { // Failed to allocate memory for the keepalive engine. return KA_RESOURCE_STARVATION; } // Initialize the keepalive engine parameters. (*pp_engine)->ka_thread_id = 0; (*pp_engine)->ka_status = KA_STAT_INVALID; (*pp_engine)->p_echo_engine = NULL; return KA_PRIV_SUCCESS; } // -------------------------------------------------------------------------- // _destroy_ka_engine: Deallocates the memory used by the Keepalive engine. // // Parameter: // pp_engine: Double pointer to the keepalive engine. // // Returned values: // KA_PRIV_SUCCESS: Operation successful. // KA_INVALID_PARMS: Invalid pp_engine pointer. // ka_priv_ret_t _destroy_ka_engine( PKA_ENGINE_PARMS* pp_engine ) { if( pp_engine == NULL || *pp_engine == NULL ) { // Bad parameter: invalid double pointer or already freed. return KA_INVALID_PARMS; } // Free the reources allocated for the Keepalive engine. pal_free( *pp_engine ); *pp_engine = NULL; return KA_PRIV_SUCCESS; } // -------------------------------------------------------------------------- // _ka_start_thread: Private worker thread function used to run the keep- // alive processing. Calls the IEE_process function until it returns. // // Parameters: // arg: Opaque pointer to the keepalive engine. // // Return value: // The keepalive engine final status. // pal_thread_ret_t PAL_THREAD_CALL _ka_start_thread( void *arg ) { PKA_ENGINE_PARMS p_ka_engine = (PKA_ENGINE_PARMS)arg; iee_ret_t iee_ret; // Check input pointer. if( p_ka_engine != NULL ) { // Let the ICMP echo engine process the keepalive echo messages. iee_ret = IEE_process( p_ka_engine->p_echo_engine ); switch( iee_ret ) { case IEE_SUCCESS: // Keepalive processing stopped. // Most probable cause: KA_stop() was invoked. p_ka_engine->ka_status = KA_STAT_FIN_SUCCESS; LOG_MESSAGE( LOG_LEVEL_3, ELInfo, STR_KA_STOP_INFO_CAUSE STR_KA_EXPLICIT_STOP ); break; case IEE_GENERAL_ECHO_TIMEOUT: // Keepalive timeout detected! p_ka_engine->ka_status = KA_STAT_FIN_TIMEOUT; LOG_MESSAGE( LOG_LEVEL_1, ELWarning, STR_KA_STOP_INFO_CAUSE STR_KA_GENERAL_TIMEOUT ); break; case IEE_INVALID_PARMS: // Input error. p_ka_engine->ka_status = KA_STAT_FIN_ERROR; LOG_MESSAGE( LOG_LEVEL_1, ELError, STR_KA_STOP_INFO_CAUSE STR_GEN_INVALID_POINTER ); break; case IEE_GENERAL_ECHO_ERROR: // Keepalive processing error. p_ka_engine->ka_status = KA_STAT_FIN_ERROR; LOG_MESSAGE( LOG_LEVEL_1, ELError, STR_KA_STOP_INFO_CAUSE STR_GEN_NETWORK_ERROR ); break; default: // Unknown/Unhandled ERROR. p_ka_engine->ka_status = KA_STAT_FIN_ERROR; LOG_MESSAGE( LOG_LEVEL_1, ELError, STR_KA_STOP_INFO_CAUSE STR_GEN_UNKNOWN_ERROR ); break; } } else { // Invalid pointer input. LOG_MESSAGE( LOG_LEVEL_1, ELError, STR_KA_STOP_INFO_CAUSE STR_GEN_INVALID_POINTER ); } // Exit the thread. pal_thread_exit( 0 ); return 0; } // -------------------------------------------------------------------------- // _ka_send_callback: Function called back from the ICMP echo engine upon // successful send of an echo request message. // // Parameter: (none) // // Return value: (none) // void _ka_send_callback( void ) { LOG_MESSAGE( LOG_LEVEL_3, ELInfo, STR_KA_SEND_INFO ); } // -------------------------------------------------------------------------- // _ka_recv_callback: Function called back from the ICMP echo engine upon // successful reception of an echo reply message. // // Parameter: // rtt: Keepalive roundtrip time. // // Return value: (none) // void _ka_recv_callback( double rtt ) { LOG_MESSAGE( LOG_LEVEL_3, ELInfo, STR_KA_RECV_INFO, rtt ); } gogoc-1_2-RELEASE/gogoc-tsp/src/net/net_ka_winxp.c0100644000000000000000000004702511301544623020430 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: net_ka_winxp.c,v 1.1 2009/11/20 16:53:39 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ /* This implements a keepalive algorythm. Should be able to get a ping socket for all the platforms, generate the ICMP6 raw data and process the actual ping based on internal values. Algo: Start from the maximum value suggested by the server. Need: 1. Major fuzz factor The major fuzz factor is applied to major increases or decreases of the timeout value. +/- 0% - 40%, initial +25% 2. Minor fuzz factor Thee minor fuzz factor is applied after we have reached the upper timeout value zone. +/- 0% - 5%, initial +3% 3. Initial timeout Fixed to 5 seconds 4. Maximal timeout Given by the server 5. Upper timeout value zone ( (Maximal timeout - 25%) - Maximal timeout ) (ie, 75% - 100% of 30 seconds). This is meant as a comfort zone in which we can apply small changes to the keep alive value - changes in the order of the minor fuzz factor. (from Teredo, section 6.7) a) Apply +(Major fuzz factor) to the timeout value until we reach the upper timeout value zone, then throttle to +/-(Minor fuzz factor) with an adjustment to stay in the upper timeout value zone. b) When we get no replies, apply -(Major fuzz factor) to the timeout value until initial timeout is reached. Forfeit if we get too many timeouts. If reply, go to a) So. Each time NetKeepaliveDo() is called, we check next_event and see if we have to let out a keepalive packet. If so we do, recompute major_fuzz, minor_fuzz, apply either +(major_fuzz) or +/-(minor_fuzz) to next_event and exit. Apply +(major_fuzz) if outside the comfort zone, +/-(minor_fuzz) otherwise. If we have an event ready and we havent got a read from the socket, we send the keepalive and recompute major_fuzz, minor_fuzz, apply -(major_fuzz) to next_event and exit. */ #include "platform.h" #include "net_ka.h" #include "net_cksm.h" #include "log.h" // log levels + display #include "hex_strings.h" #include "tsp_lease.h" /* allocation lease stuff */ #include "errors.h" #define GOGO_STR_NEXT_KA_IN "Next keepalive scheduled in %3.2f seconds." #define GOGO_STR_KEEPALIVE_INITIALIZED "Keepalive initialised. Destination: %s, max interval: %d." #define GOGO_STR_CANT_CREATE_ICMP_HNDL_FILE "Failed to load IPHLPAPI.DLL" struct NetKeepAlive { sint32_t init; /* is it initialized? */ char host[512]; /* host to send ping to */ pal_socket_t keepalive_fd; sint32_t family; struct sockaddr_in6 sa6_local; /* our ipv6 */ /* needed for cksum */ struct sockaddr_in6 sa6; /* ping6 destination */ struct sockaddr_in sa_local; /* ipv4 keepalive */ struct sockaddr_in sa; /* ping4 destination */ sint32_t still_up; // link is still up? sint32_t doit; // we had no write out, ping out to keepalive sint32_t count; // read counter in between cycles sint32_t got_read; // read flag sint32_t got_write; // write flag sint32_t pinged; // pinged flag sint32_t consecutive_timeout; /* number of consecutive timeouts */ sint32_t maximal_keepalive; /* the maximal wait factor */ double current_keepalive; float minor_fuzz; /* the minor fuzz factor */ float major_fuzz; /* the major fuzz factor */ #define KA_INITIAL_KEEPALIVE 5 // initial timeout value #define KA_MAXIMAL_CYCLES 5 // maximal number of consecutive keepalive // missed before declaring a timeout struct timeval next_event; /* take action at OR after this time */ }; static struct NetKeepAlive ka; static void internal_adjust_major_fuzz(float *); static void internal_adjust_minor_fuzz(float *); static void internal_adjust_next_event(struct NetKeepAlive *, sint32_t got_reply, sint32_t pinged); static float internal_trim(float, float, float); static sint32_t internal_do_pingout(struct NetKeepAlive *); static sint32_t internal_do_pingin(struct NetKeepAlive *); static sint32_t seqn; #if defined(WIN32) || defined(WINCE) #include "iphlpapi.h" // IPHLPAPI ping for windows static HINSTANCE hndliphlp = NULL; static HANDLE hHandle = NULL; static HANDLE hEvent = NULL; static char ReplyBuffer[1500]; HANDLE (WINAPI *IcmpCreateFile)(VOID); BOOL (WINAPI *IcmpCloseHandle)(HANDLE); DWORD (WINAPI *IcmpSendEcho2)(HANDLE, HANDLE, FARPROC, PVOID, IPAddr, LPVOID, WORD, PIP_OPTION_INFORMATION, LPVOID, DWORD, DWORD); DWORD (WINAPI *IcmpParseReplies)(LPVOID, DWORD); HANDLE (WINAPI *Icmp6CreateFile)(VOID); DWORD (WINAPI *Icmp6SendEcho2)(HANDLE, HANDLE, FARPROC, PVOID, struct sockaddr_in6*, struct sockaddr_in6 *, LPVOID, WORD, PIP_OPTION_INFORMATION, LPVOID, DWORD, DWORD); DWORD (WINAPI *Icmp6ParseReplies)(LPVOID, DWORD); #endif sint32_t winxp_use_old_ka = 0; // Defined extern in header file. sint32_t NetKeepaliveInit(char *src, char *dst, sint32_t maximal_keepalive, sint32_t family) { struct timeval tv; #if defined(WIN32) || defined(WINCE) hndliphlp = LoadLibrary(TEXT("IPHLPAPI.DLL")); if (!hndliphlp) { Display(LOG_LEVEL_3, ELError, "NetKeepaliveInit", GOGO_STR_CANT_CREATE_ICMP_HNDL_FILE); return 1; } if (family == AF_INET6) { // Try to load IPv6 // support functions // from iphlpapi // Icmp6CreateFile = (HANDLE (WINAPI *)(void)) GetProcAddress(hndliphlp, TEXT("Icmp6CreateFile")); IcmpCloseHandle = (BOOL (WINAPI *)(HANDLE)) GetProcAddress(hndliphlp, TEXT("IcmpCloseHandle")); Icmp6SendEcho2 = (DWORD (WINAPI *)(HANDLE, HANDLE, FARPROC, PVOID, struct sockaddr_in6*, struct sockaddr_in6*, LPVOID, WORD, PIP_OPTION_INFORMATION, LPVOID, DWORD, DWORD)) GetProcAddress(hndliphlp, TEXT("Icmp6SendEcho2")); Icmp6ParseReplies = (DWORD (WINAPI *)(LPVOID, DWORD)) GetProcAddress(hndliphlp, TEXT("Icmp6ParseReplies")); if( (Icmp6CreateFile == NULL) || (IcmpCloseHandle == NULL) || (Icmp6SendEcho2 == NULL) || (Icmp6ParseReplies == NULL) ) { Display(LOG_LEVEL_3, ELError, "NetKeepaliveInit", GOGO_STR_CANT_CREATE_ICMP_HNDL_FILE); return 1; } hHandle = Icmp6CreateFile(); } #ifdef V4V6_SUPPORT else if (family == AF_INET) { // Try to load IPv4 // support functions // from iphlpapi // IcmpCreateFile = (HANDLE (WINAPI *)(VOID)) GetProcAddress(hndliphlp, TEXT("IcmpCreateFile")); IcmpCloseHandle = (BOOL (WINAPI *)(HANDLE)) GetProcAddress(hndliphlp, TEXT("IcmpCloseHandle")); IcmpSendEcho2 = (DWORD (WINAPI *)(HANDLE, HANDLE, FARPROC, PVOID, IPAddr, LPVOID, WORD, PIP_OPTION_INFORMATION, LPVOID, DWORD, DWORD)) GetProcAddress(hndliphlp, TEXT("IcmpSendEcho2")); IcmpParseReplies = (DWORD (WINAPI *)(LPVOID, DWORD)) GetProcAddress(hndliphlp, TEXT("IcmpParseReplies")); if ( (IcmpCreateFile == NULL) || (IcmpCloseHandle == NULL) || (IcmpSendEcho2 == NULL) || (IcmpParseReplies == NULL) ) { Display(LOG_LEVEL_3, ELError, "NetKeepaliveInit", GOGO_STR_CANT_CREATE_ICMP_HNDL_FILE); return 1; } hHandle = IcmpCreateFile(); } #endif if (hHandle == INVALID_HANDLE_VALUE) { Display(LOG_LEVEL_3, ELError, "NetKeepaliveInit", GOGO_STR_CANT_CREATE_ICMP_HNDL_FILE); return 1; } #endif /* Load the structure with passed in AND * initial values */ seqn = 0; if (strncpy(ka.host, dst, sizeof(ka.host)) == NULL) return 1; ka.maximal_keepalive = maximal_keepalive; ka.current_keepalive = KA_INITIAL_KEEPALIVE; ka.major_fuzz = (float) 0.60; ka.minor_fuzz = (float) 0.075; /* And initialize the next event */ /* Initial timeout is set to five seconds */ pal_gettimeofday(&tv); ka.next_event.tv_sec = tv.tv_sec + KA_INITIAL_KEEPALIVE; ka.next_event.tv_usec = tv.tv_usec; /* initialize the random source */ pal_srandom(tv.tv_usec); /* set the family */ ka.family = family; /* get a ping socket and a monitor socket */ if (family == AF_INET6) { pal_inet_pton(AF_INET6, dst, &ka.sa6.sin6_addr); ka.sa6.sin6_family = AF_INET6; pal_inet_pton(AF_INET6, src, &ka.sa6_local.sin6_addr); ka.sa6_local.sin6_family = AF_INET6; #if !(defined(WIN32) || defined(WINCE)) ka.keepalive_fd = pal_socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); #endif } #ifdef V4V6_SUPPORT else if (family == AF_INET) { pal_inet_pton(AF_INET, dst, &ka.sa.sin_addr); ka.sa.sin_family = AF_INET; pal_inet_pton(AF_INET, src, &ka.sa_local.sin_addr); ka.sa_local.sin_family = AF_INET; #if !(defined(WIN32) || defined(WINCE)) ka.keepalive_fd = pal_socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); #endif } #endif /* V4V6_SUPPORT */ ka.consecutive_timeout = 0; ka.still_up = 0; ka.doit = 1; ka.count = 0; ka.got_read = 0; ka.got_write = 0; ka.pinged = 1; /* ok, we are inialized */ ka.init = 1; Display(LOG_LEVEL_3, ELInfo, "NetKeepaliveInit", GOGO_STR_KEEPALIVE_INITIALIZED, dst, maximal_keepalive); return 0; } void NetKeepaliveDestroy( void ) { pal_shutdown( ka.keepalive_fd, PAL_SOCK_SHTDN_BOTH ); #if defined(WIN32) || defined(WINCE) if( hHandle != NULL ) { IcmpCloseHandle(hHandle); hHandle = NULL; } if( hEvent != NULL ) { CloseHandle(hEvent); hEvent = NULL; } // Free IP Helper API DLL handle, and invalidate function pointers. if( hndliphlp != NULL ) { IcmpCreateFile = NULL; IcmpCloseHandle = NULL; IcmpSendEcho2 = NULL; IcmpParseReplies = NULL; Icmp6CreateFile = NULL; Icmp6SendEcho2 = NULL; Icmp6ParseReplies = NULL; FreeLibrary( hndliphlp ); } #endif pal_closesocket( ka.keepalive_fd ); memset(&ka, 0, sizeof(struct NetKeepAlive)); } void NetKeepaliveGotRead() { if (ka.init == 1) { ka.got_read = 1; //Display(LOG_LEVEL_3, ELNotice, "NetKeepaliveGotRead", GOGO_STR_INCOMING_DATA_FROMTEXTUNNEL); } } void NetKeepaliveGotWrite() { if (ka.init == 1) { ka.got_write = 1; //Display(LOG_LEVEL_3, ELNotice, "NetKeepaliveGotWrite", GOGO_STR_OUT_DATATEXTOTEXTUNNEL); } } /* Should be called with a good resolution to allow for good precision. Every 50 to 100 ms. return values : 0 - everything is OK 1 - warning - timeout 2 - fatal - too many timeouts 3 - not initialised */ sint32_t NetKeepaliveDo() { struct timeval tv; sint32_t doit = 0; // local evaluation of if we should try to ping. // will be flagged only if we hit the next event time if (ka.init != 1) return 3; if (internal_do_pingin(&ka) != 0) // read echo replies ka.got_read = 1; if (ka.got_read == 1) { // if we did get a read in the last cycle, ka.consecutive_timeout = 0; // we can reset the consecutive timeouts counter. ka.count++; // increment the packet counter ka.got_read = 0; // and reset the read flag until next time } if (ka.got_write == 1) { // we did get a write in the last cycle? ka.doit = 0; // then no need to ping out ka.got_write = 0; // and also reset the write flag until next time } /* do we need to ping out ? */ pal_gettimeofday(&tv); /* If a ping is needed, then also take a look at the number of consecutive missreads we have. */ if (tv.tv_sec == ka.next_event.tv_sec) { if (tv.tv_sec >= ka.next_event.tv_usec) doit = 1; } else if (tv.tv_sec > ka.next_event.tv_sec) doit = 1; if (doit) { if (ka.doit == 0 && ka.count > 0) ka.still_up = 1; /* so if we had both read and writes, we are up? */ if (ka.consecutive_timeout != 0) /* if we had timeouts, ping */ ka.still_up = 0; if (ka.count == 2 || ka.count == 1) /* a count of 2 or 1 probably means */ /* only the keepalive packet was sent */ ka.still_up = 0; if (ka.doit == 1) /* no write, do it */ ka.still_up = 0; if ( ka.still_up == 0 ) { // if we havent got any // traffic for the last cycle, // generate a ping (and thus // a reply, and thus - traffic) // or none if we are down. // a count of 2 will mean only our ping got thru since // last time and it means we need to continue // pinging if (internal_do_pingout(&ka) > 0) { ka.got_write = 1; // if it worked, flag the write flag } ka.consecutive_timeout++; // we had a timeout of sorts // since we had to ping } ka.doit = 1; // re-ping unless noted otherwise ka.count = 0; // reset packet counter in between pings /* adjust internal values */ /* set the next event time */ internal_adjust_next_event(&ka, ka.still_up, ka.consecutive_timeout); /* adjust the major fuzz factor. it needs to vary +/- 10 - 40% and stay in the .40 - .80 range */ internal_adjust_major_fuzz(&ka.major_fuzz); /* then adjust the minor fuzz factor. this one needs to vary +/- 1 - 5% staying in the .03 - .07 range */ internal_adjust_minor_fuzz(&ka.minor_fuzz); if (ka.consecutive_timeout == KA_MAXIMAL_CYCLES) return 2; ka.still_up = 0; // until next time, we are down unless noted otherwise } /* and return */ return 0; } static void internal_adjust_major_fuzz(float *major_fuzz) { sint32_t i; float f; /* here we want a randomness of .40 - .80 */ i = pal_random()%40; f = (float) i / 100; /* 0 - 100% */ f += .40f; *major_fuzz = internal_trim(f, 0.40f, 0.80f); } static void internal_adjust_minor_fuzz(float *minor_fuzz) { sint32_t i; float f; /* here we want a randomness of .03 - .07 */ i = pal_random()%4; f = (float) i / 100; f += .03f; *minor_fuzz = internal_trim (f, 0.03f, 0.07f); } static void internal_adjust_next_event(struct NetKeepAlive *nka, sint32_t got_reply, sint32_t ct) { /* if we are in the comfort zone, apply minor_fuzz. Otherwise, apply major_fuzz If we are in the comfort zone and got no reply, force us out of it. */ sint32_t i; struct timeval tv; float minor_minimum, major_minimum; i = pal_random()&0x01; /* positive or negative shift? */ minor_minimum = KA_INITIAL_KEEPALIVE; major_minimum = (float) nka->maximal_keepalive * 0.75f; /* next_event = current_event * +/- factor */ if (nka->current_keepalive >= major_minimum) { // we are in the comfort zone // did we get any reply? // if not, bump down outside the zone // also ensure that if we // are stuck at either ends of the // spectrum, we get out fast #ifdef FAST_HANDOVER if (got_reply == 0 && ct > 1) nka->current_keepalive = major_minimum - 1; else #endif { float fuzz_factor; if (nka->current_keepalive == nka->maximal_keepalive) fuzz_factor = 1 - nka->minor_fuzz; else if (nka->current_keepalive == major_minimum) fuzz_factor = 1 + nka->minor_fuzz; else fuzz_factor = i ? (1 - nka->minor_fuzz) : (1 + nka->minor_fuzz); nka->current_keepalive = internal_trim((float)nka->current_keepalive * fuzz_factor, major_minimum, (float) nka->maximal_keepalive); } } /* else we are NOT in the comfort zone */ if (nka->current_keepalive < major_minimum) { /* if we got_reply we go up, otherwise we go down */ #ifdef FAST_HANDOVER float fuzz_factor; fuzz_factor = (ct < 2) ? (1 + nka->major_fuzz) : ( 1 - nka->major_fuzz); #else float fuzz_factor = 1; if (ct < 2) fuzz_factor = 1 + nka->major_fuzz; #endif nka->current_keepalive = internal_trim((float)nka->current_keepalive * fuzz_factor, minor_minimum, (float) nka->maximal_keepalive); } /* then put the next event in the timeval */ pal_gettimeofday(&tv); nka->next_event.tv_sec = tv.tv_sec + (sint32_t) nka->current_keepalive; nka->next_event.tv_usec = (long)( nka->current_keepalive - (sint32_t) nka->current_keepalive ) * 1000000; Display(LOG_LEVEL_3, ELInfo, "internal_adjust_next_event", GOGO_STR_NEXT_KA_IN, nka->current_keepalive); return; } static float internal_trim(float value, float lower, float higher) { if ( value <= lower) return lower; if (value >= higher) return higher; return value; } /* if this returns 0, no data was written. Otherwise, data was written */ static sint32_t internal_do_pingout(struct NetKeepAlive *nka) { sint32_t ret = 0; #if defined(WIN32) || defined(WINCE) IP_OPTION_INFORMATION ip_option_information; sint32_t icmp_send_ret = 0; #else sint32_t len = 0; char sendbuf[1500]; #ifdef V4V6_SUPPORT struct icmp *icmp; #endif /* V4V6_SUPPORT */ struct icmp6_hdr *icmp6; #endif #if defined(WIN32) || defined(WINCE) // WIN32 handling // memset( &ip_option_information, 0x00, sizeof(IP_OPTION_INFORMATION) ); ip_option_information.Ttl = 64; if (hEvent != NULL) { CloseHandle(hEvent); hEvent = NULL; } hEvent = CreateEvent(NULL, FALSE, FALSE, TEXT("gogocIcmpEvent")); // // Send a ping out then callback in // internal_do_pingin when the reply // comes in // if (nka->family == AF_INET6) { icmp_send_ret = Icmp6SendEcho2(hHandle, hEvent, NULL, NULL, &nka->sa6_local, &nka->sa6, NULL, 0, &ip_option_information, ReplyBuffer, sizeof(ReplyBuffer), 1000); if( (icmp_send_ret != 0) || ((icmp_send_ret == 0) && (GetLastError() == ERROR_IO_PENDING)) ) { // Success. ret = 1; } } #ifdef V4V6_SUPPORT else if (nka->family == AF_INET) { icmp_send_ret = IcmpSendEcho2(hHandle, hEvent, NULL, NULL, (IPAddr) nka->sa.sin_addr.S_un.S_addr, NULL, 0, &ip_option_information, ReplyBuffer, sizeof(ReplyBuffer), 1000); if( (icmp_send_ret != 0) || ((icmp_send_ret == 0) && (GetLastError() == ERROR_IO_PENDING)) ) { // Success. ret = 1; } } #endif #else // compute packet // and send it // #ifdef V4V6_SUPPORT if (nka->family == AF_INET) { /* icmp4 packet */ icmp = (struct icmp *)sendbuf; icmp->icmp_type = ICMP_ECHO; icmp->icmp_code = 0; icmp->icmp_id = getpid(); icmp->icmp_seq = seqn++; gettimeofday((struct timeval *) icmp->icmp_data, NULL); len = 8 /* icmp header */ + 56 /* icmp data */; icmp->icmp_cksum = 0; icmp->icmp_cksum = in_cksum((u_short *) icmp, len); ret = sendto(nka->keepalive_fd, sendbuf, len, 0, (struct sockaddr *) &(nka->sa), sizeof(nka->sa)); } #endif /* V4V6_SUPPORT */ if (nka->family == AF_INET6) { icmp6 = (struct icmp6_hdr *) sendbuf; icmp6->icmp6_type = ICMP6_ECHO_REQUEST; icmp6->icmp6_code = 0; icmp6->icmp6_id = getpid(); icmp6->icmp6_seq = seqn++; gettimeofday((struct timeval *) (icmp6+1), NULL); len = 8 /* icmp header */ + 56 /* icmp data */; ret = sendto(nka->keepalive_fd, sendbuf, len, 0, (struct sockaddr *) &(nka->sa6), sizeof(nka->sa6)); } #endif return ret; } /* if this next one returns zero, no ping reply. if it returns > 0, ping reply. */ static sint32_t internal_do_pingin(struct NetKeepAlive *nka) { sint32_t ret = 0; #if defined(WIN32) || defined(WINCE) // Check if windows signaled our event // meaning the ping reply came in // if ((hEvent != NULL) && (WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0)) { if (nka->family == AF_INET6) { ret = Icmp6ParseReplies(ReplyBuffer, sizeof(ReplyBuffer)); } #ifdef V4V6_SUPPORT else if (nka->family == AF_INET) { ret = IcmpParseReplies(ReplyBuffer, sizeof(ReplyBuffer)); } #endif CloseHandle(hEvent); hEvent = NULL; } #else unsigned char buffer[2048]; fd_set fs; struct timeval tv_sel; memset(buffer, 0, sizeof(buffer)); FD_ZERO(&fs); FD_SET(nka->keepalive_fd, &fs); memset(&tv_sel, 0, sizeof(tv_sel)); // set to zero - imitate polling ret = select(nka->keepalive_fd + 1, &fs, NULL, NULL, &tv_sel); if (ret > 0) ret = recv(nka->keepalive_fd, buffer, sizeof(buffer), 0); #endif //if (ret > 0) // Display(LOG_LEVEL_3, ELNotice, "internal_do_pingin", GOGO_STR_ICMP_ECHO_REPLY, ret); return ret; } gogoc-1_2-RELEASE/gogoc-tsp/src/net/net_rudp.c0100644000000000000000000002731611301544623017563 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: net_rudp.c,v 1.1 2009/11/20 16:53:39 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ #include "platform.h" #include "net_rudp.h" #include "net.h" #include "log.h" #include "hex_strings.h" // global variables rttengine_stat_t rttengine_stats; // forward declarations static struct sockaddr_in *internal_get_sai(rttengine_stat_t *, char *, unsigned short); /* Exported functions */ sint32_t NetRUDPInit(void) { memset(&rttengine_stats, 0, sizeof(rttengine_stat_t)); return rttengine_init(&rttengine_stats); } /* */ sint32_t NetRUDPDestroy(void) { if ( rttengine_deinit(&rttengine_stats, NULL, NULL) == 0) return 1; return 0; } // -------------------------------------------------------------------------- // NetRUDPConnect: // // Return values: // 0: success // -1: Failed to resolve srvname. // -2: Socket error / Failed to connect (TCP only). // sint32_t NetRUDPConnect(pal_socket_t *p_sock, char *Host, uint16_t Port) { pal_socket_t sfd; struct sockaddr_in *sai; if( rttengine_stats.initiated == 0 ) NetRUDPInit(); sai = internal_get_sai(&rttengine_stats, Host, Port); if( sai == NULL) { return -1; } /* and get a socket */ if ( (sfd = pal_socket(PF_INET, SOCK_DGRAM, 0)) == -1 ) { return -2; } /* then connect it */ if( (pal_connect(sfd,(struct sockaddr *) sai, sizeof(struct sockaddr_in))) == -1 ) { pal_closesocket( sfd ); return -2; } *p_sock = sfd; return 0; } /* */ sint32_t NetRUDPClose(pal_socket_t sock) { pal_shutdown( sock, PAL_SOCK_SHTDN_BOTH ); pal_closesocket( sock ); return NetRUDPDestroy(); } /* */ sint32_t NetRUDPReadWrite(pal_socket_t sock, char *in, sint32_t il, char *out, sint32_t ol) { return internal_send_recv(sock, in, il, out, ol); } /* */ sint32_t NetRUDPWrite(pal_socket_t sock, char *b, sint32_t l) { return NetRUDPReadWrite(sock, b, l, NULL, 0); } /* */ sint32_t NetRUDPPrintf(pal_socket_t sock, char *out, sint32_t ol, char *Format, ...) { va_list argp; char Data[1024]; va_start(argp, Format); pal_vsnprintf((char*)Data, sizeof Data, Format, argp); va_end(argp); return NetRUDPReadWrite(sock, Data, pal_strlen(Data), out, ol); } /* */ sint32_t NetRUDPRead(pal_socket_t sock, char *b, sint32_t l) { return NetRUDPReadWrite(sock, NULL, 0, b, l); } /* Internal functions; not exported */ /* needs a connected UDP socket or else all hell will break loose */ sint32_t internal_send_recv(pal_socket_t fd, void *in, sint32_t il, void *out, sint32_t ol) { fd_set fs; sint32_t ret, ls; /* return code, length sent */ rudp_msghdr_t *omh = NULL; /* outoing message header */ rudp_msghdr_t *imh = NULL; /* incoming message header */ void *om = NULL; void *im = NULL; /* outgoing and incoming messages raw data */ struct timeval tv_sel, tv_beg; if ( rttengine_stats.initiated == 0 ) return -1; om = internal_prepare_message(&omh,il); im = internal_prepare_message(&imh,ol); memset(om, 0, il); memset(im, 0, ol); if (om == NULL || im == NULL) { /* something in the memory allocation failed */ /* cleanup */ rttengine_deinit(&rttengine_stats, om, im); return -1; } memcpy((char*)om+sizeof(rudp_msghdr_t), in, il); /* Bug 3334: Byte ordering is important when sending 32 bit * values on the network: local and remote machines may not * have the same ordering. The rule observed here is that * data going in and out the network MUST be in "network * order". The fix here is to apply this rule to the * "timestamp" and "sequence" member of the RUDP header. The * rudp_msghdr_t struct thus contains "network ordered" * data */ /* stamp in the sequence number */ omh->sequence = htonl(rttengine_stats.sequence++ | 0xf0000000); sendloop: /* if we have no peer yet - that means retries = MAXRTT with no replies, quit it. * if we do have a peer, then now is a good time to apply exponential backoff */ if (rttengine_stats.retries == RTTENGINE_MAXRTT) { if (rttengine_stats.has_peer == 0) { rttengine_deinit(&rttengine_stats, om, im); return -1; } else rttengine_stats.apply_backoff = 1; } if (rttengine_stats.retries == RTTENGINE_MAXRT) { /* cleanup */ rttengine_deinit(&rttengine_stats, om, im); return -1; } /* update the timestamp of the message */ omh->timestamp = htonl(internal_get_timestamp(&rttengine_stats)); Display(LOG_LEVEL_3, ELInfo, "internal_send_recv", GOGO_STR_RUDP_PACKET,rttengine_stats.retries, rttengine_stats.rto, ntohl(omh->sequence), ntohl(omh->timestamp)); /* send the message */ if ( ( ls = send(fd, om, il+sizeof(rudp_msghdr_t), 0)) == -1) { /* cleanup */ rttengine_deinit(&rttengine_stats, om, im); return -1; /* if the send fails, quit it */ /* XXX check for a ICMP port unreachable here */ } tv_sel.tv_sec=(sint32_t)rttengine_stats.rto; /* get the RTO in a format select can understand */ tv_sel.tv_usec=(sint32_t)( (rttengine_stats.rto - tv_sel.tv_sec) * 1000 ); /* ie, 3.314 - 3 * 1000 = 314 milliseconds */ pal_gettimeofday(&tv_beg); selectloop: /* and wait for an answer */ FD_ZERO(&fs); FD_SET(fd, &fs); ret = select((sint32_t)fd+1, &fs, NULL, NULL, &tv_sel); switch (ret) { case 0: { /* select timed out with nothing to read */ /* so we might need to step back a little on the timeout, and do a resend */ Display(LOG_LEVEL_3, ELInfo, "internal_send_recv", GOGO_STR_NO_RUDP_REPLY); if (rttengine_stats.apply_backoff == 1) rttengine_stats.rto = internal_get_adjusted_rto(rttengine_stats.rto *= 2); rttengine_stats.retries++; goto sendloop; } case 1: { /* We did get a reply, is it what we were waiting for? * lets read everything the server is sending and see */ ret = recv(fd, im, sizeof(rudp_msghdr_t)+ol, 0); Display(LOG_LEVEL_3, ELInfo, "internal_send_recv", GOGO_STR_REPLY_RUDP_PACKET,rttengine_stats.retries, rttengine_stats.rto, ntohl(imh->sequence), ntohl(imh->timestamp)); if (ret == -1) { /* fatal read error */ /* cleanup */ rttengine_deinit(&rttengine_stats, om, im); return -1; } if ( imh->sequence == omh->sequence ) { ret = ret - sizeof(rudp_msghdr_t); /* we keep the lenght received minus the headers */ break; /* yes it is what we are waiting for */ } else { /* readjust tv to the remaining time */ /* tv_sel = time_now - time_beginning */ struct timeval tv_now; pal_gettimeofday(&tv_now); tv_sel.tv_sec -= (tv_now.tv_sec - tv_beg.tv_sec); tv_beg = tv_now; /* XXX substract the usec as well */ goto selectloop; } } default: { /* error of unknown origin, ret contains the ERRNO compatible error released by select() */ /* cleanup */ rttengine_deinit(&rttengine_stats, om, im); return -1; } }//switch /* update our stat engine, the RTT and compute the new RTO */ rttengine_update(&rttengine_stats, internal_get_timestamp(&rttengine_stats) - ntohl(imh->timestamp)); /* get the reply in a safe place */ memcpy(out, (char*)im+sizeof(rudp_msghdr_t), ret); /* free the memory */ internal_discard_message(om); internal_discard_message(im); /* and *goodbye* */ rttengine_stats.has_peer = 1; /* we have a peer it seems */ rttengine_stats.retries = 0; /* next packet can retry like it wishes to */ return ret; } /* */ sint32_t rttengine_init(rttengine_stat_t *s) { struct timeval tv; if (s == NULL) return 0; if (s->initiated == 1) return s->initiated; if ( pal_gettimeofday(&tv) == -1 ) memset(&tv, 0, sizeof(struct timeval)); s->rtt = 0; s->srtt = 0; s->rttvar = 0.50; s->rto = RTTENGINE_TMIN; /* Bug 3334: Implementation of client and server handles * sequence number in host order (little endian on i386), * which is broken (should be in network order). This causes * problems when client uses big endian format. */ /* On the wire, sequence number 0 in little endian format is * 00 00 00 f0, where f0 is the MSB. In network order, this * should be f0 00 00 00. * * In order to stay compatible with "old" HexOS versions, we * initialize the sequence number to 240 (0xf0), which creates * an initial sequence number of f0 00 00 f0. The following * sequences are: * f0 00 00 f1 * f0 00 00 f2 * f0 00 00 f3, ... * * A pre-4.0 HexOS server will interpret these numbers as * little endian: * f0 00 00 f0 * f1 00 00 f0 * f2 00 00 f0 ... * If more than 16 sequence numbers are needed, this will not * work: sequence number f0 00 01 00 will be dropped by HexOS * since the 0xf RUDP "signature" is gone. * Test with TSP using authenticated digest-md5 shows that 5 * sequence numbers are needed. Still have room for 11 more * packet exchange (sequence incremented by client only) * * HexOS >= 4.0 should convert the sequence number from network * order to host order, and should look for RUDP signature in * both MSB and LSB (backward compatible with old clients). */ s->sequence = 240; s->retries = 0; s->last_recv_sequence = 0xBAD; s->initial_timestamp = tv.tv_sec; s->has_peer = 0; s->apply_backoff = 0; s->initiated = 1; return s->initiated; } /* */ sint32_t rttengine_deinit(rttengine_stat_t *s, void *im, void *om) { if (s->sai != NULL) { free(s->sai); s->sai = NULL; } if (im != NULL) { internal_discard_message(im); im = NULL; } if (om != NULL) { internal_discard_message(om); om = NULL; } s->initiated = 0; return s->initiated; } /* */ float rttengine_update(rttengine_stat_t *s, uint32_t rtt) { float delta; if (s == NULL) return 0; s->rtt = rtt / 1000.0f; /* bring this back to seconds, the rest of the code uses milliseconds, including the timestamp that is in the payload */ delta = s->rtt - s->srtt; s->srtt = s->srtt + RTTENGINE_G * delta; s->rttvar = s->rttvar + RTTENGINE_H * ( delta<0?-delta:delta ); s->rto = s->srtt + 4 * s->rttvar; s->rto = internal_get_adjusted_rto(s->rto); s->retries = 0; /* update is called when a packet was acked OK, so we need to reset this here */ return s->rto; } /* */ void *internal_prepare_message(rudp_msghdr_t **hdr, size_t msglen) { void *buf; if (msglen == 0) buf = (rudp_msghdr_t *) malloc(sizeof(rudp_msghdr_t)); else buf = (void *) malloc(msglen+sizeof(rudp_msghdr_t)); if (buf!=NULL) *hdr = buf; return buf; } /* */ void internal_discard_message(void *m) { if (m != NULL) free(m); return; } /* */ uint32_t internal_get_timestamp(rttengine_stat_t *s) { struct timeval tv; if (pal_gettimeofday(&tv) == -1) return 0; return ( ((tv.tv_sec - s->initial_timestamp) * 1000 ) + (tv.tv_usec / 1000) ); } /* */ float internal_get_adjusted_rto(float rto) { if (rtoRTTENGINE_TMAX) return RTTENGINE_TMAX; return rto; } /* */ static struct sockaddr_in * internal_get_sai(rttengine_stat_t *s, char *Host, unsigned short Port) { /* we need to be reinitialised for each new connection, * so we can check if we already have something * cached and assume it is fit for the * current situation */ struct sockaddr_in *sai; struct in_addr addr; /* so, is it cached? */ if (s->sai != NULL) return (struct sockaddr_in *)s->sai; /* its not */ /* get the IP address from the hostname */ if(NetText2Addr(Host, &addr) == NULL ) return NULL; /* get memory for our patente */ if ( (sai = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in))) == NULL) return NULL; /* clear out our sockaddr_in entry, fill it and cache it */ memset(sai, 0, sizeof(struct sockaddr_in)); sai->sin_family = PF_INET; sai->sin_port = htons(Port); sai->sin_addr.s_addr = addr.s_addr; s->sai = (struct sockaddr *)sai; return sai; } gogoc-1_2-RELEASE/gogoc-tsp/src/net/net_rudp6.c0100644000000000000000000000711011301544623017637 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: net_rudp6.c,v 1.1 2009/11/20 16:53:39 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ #include "platform.h" #include "net_rudp.h" #include "net_rudp6.h" #include "net.h" #include "log.h" #ifdef V4V6_SUPPORT // forward declarations (IPv6 version of internal_get_sai()) static struct sockaddr_in6 *internal_get_sai6(rttengine_stat_t *, char *, unsigned short); /* Exported functions */ sint32_t NetRUDP6Init(void) { memset(&rttengine_stats, 0, sizeof(rttengine_stat_t)); return rttengine_init(&rttengine_stats); } /* */ sint32_t NetRUDP6Destroy(void) { if ( rttengine_deinit(&rttengine_stats, NULL, NULL) == 0) return 1; return 0; } // -------------------------------------------------------------------------- // NetRUDP6Connect: // // Return values: // 0: success // -1: Failed to resolve srvname. // -2: Socket error / Failed to connect (TCP only). // sint32_t NetRUDP6Connect(pal_socket_t *p_sock, char *Host, unsigned short Port) { pal_socket_t sfd; struct sockaddr_in6 *sai; if (rttengine_stats.initiated == 0) NetRUDP6Init(); if( (sai = internal_get_sai6(&rttengine_stats, Host, Port)) == NULL) { return -1; } /* and get a socket */ if( (sfd = pal_socket(PF_INET6, SOCK_DGRAM, 0)) == -1 ) { return -2; } /* then connect it */ if( (pal_connect(sfd,(struct sockaddr *) sai, sizeof(struct sockaddr_in6))) == -1 ) { pal_closesocket( sfd ); return -2; } *p_sock = sfd; return 0; } /* */ sint32_t NetRUDP6Close( pal_socket_t sock ) { pal_shutdown( sock, PAL_SOCK_SHTDN_BOTH ); pal_closesocket( sock ); return NetRUDP6Destroy(); } /* */ sint32_t NetRUDP6ReadWrite( pal_socket_t sock, char *in, sint32_t il, char *out, sint32_t ol ) { return internal_send_recv(sock, in, il, out, ol); } /* */ sint32_t NetRUDP6Write( pal_socket_t sock, char *b, sint32_t l ) { return NetRUDPReadWrite(sock, b, l, NULL, 0); } /* */ sint32_t NetRUDP6Printf( pal_socket_t sock, char *out, sint32_t ol, char *Format, ... ) { va_list argp; sint32_t Length; char Data[1024]; va_start(argp, Format); pal_vsnprintf(Data, sizeof Data, Format, argp); va_end(argp); Length = pal_strlen(Data); return NetRUDP6ReadWrite(sock, Data, pal_strlen(Data), out, ol); } /* */ sint32_t NetRUDP6Read( pal_socket_t sock, char *b, sint32_t l ) { return NetRUDP6ReadWrite(sock, NULL, 0, b, l); } static struct sockaddr_in6 * internal_get_sai6(rttengine_stat_t *s, char *Host, uint16_t Port ) { /* we need to be reinitialised for each new connection, * so we can check if we already have something * cached and assume it is fit for the * current situation */ struct sockaddr_in6 *sai; struct in6_addr addr6; /* so, is it cached? */ if (s->sai != NULL) return (struct sockaddr_in6 *)s->sai; /* its not */ /* get the IP address from the hostname */ if(NetText2Addr6(Host, &addr6) == NULL ) return NULL; /* get memory for our patente */ if ( (sai = (struct sockaddr_in6 *)malloc(sizeof(struct sockaddr_in6))) == NULL) return NULL; /* clear out our sockaddr_in entry, fill it and cache it */ memset(sai, 0, sizeof(struct sockaddr_in6)); sai->sin6_family = PF_INET6; sai->sin6_port = htons(Port); memcpy(&sai->sin6_addr, &addr6, sizeof(struct in6_addr)); s->sai = (struct sockaddr *)sai; return sai; } #endif /* V4V6_SUPPORT */ gogoc-1_2-RELEASE/gogoc-tsp/src/net/net_tcp.c0100644000000000000000000000534111301544624017372 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: net_tcp.c,v 1.1 2009/11/20 16:53:40 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ #include "platform.h" #include "net_tcp.h" #include "net.h" /* NetText2Addr */ // -------------------------------------------------------------------------- // NetTCPConnect: // // Return values: // 0: success // -1: Failed to resolve srvname. // -2: Socket error / Failed to connect (TCP only). // sint32_t NetTCPConnect( pal_socket_t *p_sock, char *Host, uint16_t Port ) { pal_socket_t sockfd; struct sockaddr_in serv_addr; struct in_addr addr; if( NetText2Addr(Host, &addr) == NULL ) { return -1; } memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(Port); serv_addr.sin_addr.s_addr = addr.s_addr; /* * Open a TCP socket (an Internet stream socket). */ if( (sockfd = pal_socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { return -2; } /* * Connect to the server. */ if( pal_connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0 ) { pal_closesocket( sockfd ); return -2; } *p_sock = sockfd; return 0; } // -------------------------------------------------------------------------- sint32_t NetTCPClose( pal_socket_t Socket ) { pal_shutdown( Socket, PAL_SOCK_SHTDN_BOTH ); return pal_closesocket(Socket); } /* */ sint32_t NetTCPReadWrite( pal_socket_t sock, char *bi, sint32_t li, char *bo, sint32_t lo ) { if( NetTCPWrite(sock, bi, li) != li ) return -1; return NetTCPRead(sock, bo, lo); } /* */ sint32_t NetTCPWrite( pal_socket_t sock, char *b, sint32_t l ) { sint32_t nleft, nwritten; char *ptr; ptr = b; /* can't do pointer arithmetic on void * */ nleft = l; while (nleft > 0) { if( (nwritten = send(sock, ptr, nleft, 0)) <= 0 ) { return nwritten; /* error */ } nleft -= nwritten; ptr += nwritten; } return l ; } /* */ sint32_t NetTCPPrintf( pal_socket_t sock, char *out, sint32_t pl, char *Format, ... ) { va_list argp; sint32_t Length; char Data[1024]; va_start(argp, Format); pal_vsnprintf(Data, sizeof Data, Format, argp); va_end(argp); Length = pal_strlen(Data); if( NetTCPWrite(sock, Data, pal_strlen(Data)) != Length ) { return 0; } return NetTCPRead(sock, out, pl); } /* */ sint32_t NetTCPRead( pal_socket_t sock, char *in, sint32_t l ) { return( recv(sock, in, l, 0) ); } gogoc-1_2-RELEASE/gogoc-tsp/src/net/net_tcp6.c0100644000000000000000000000644411301544624017465 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: net_tcp6.c,v 1.1 2009/11/20 16:53:40 jasminko Exp $ ----------------------------------------------------------------------------- * This source code copyright (c) gogo6 Inc. 2002-2004,2007. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2, * June 1991 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file GPL_LICENSE.txt. If not, write * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA ----------------------------------------------------------------------------- */ #include "platform.h" #include "net_tcp6.h" #include "net.h" /* NetText2Addr */ // -------------------------------------------------------------------------- // NetTCP6Connect: // // Return values: // 0: success // -1: Failed to resolve srvname. // -2: Socket error / Failed to connect (TCP only). // sint32_t NetTCP6Connect( pal_socket_t *p_sock, char *Host, uint16_t Port ) { pal_socket_t sockfd; struct sockaddr_in6 serv_addr; struct in6_addr addr; if( NULL == NetText2Addr6(Host, &addr) ) { return -1; } memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin6_family = AF_INET6; serv_addr.sin6_port = htons(Port); serv_addr.sin6_addr = addr; /* * Open a TCP socket (an Internet 6 stream socket). */ if( (sockfd = pal_socket(AF_INET6, SOCK_STREAM, 0)) < 0 ) { return -2; } /* * Connect to the server. */ if( pal_connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0 ) { pal_closesocket( sockfd ); return -2; } *p_sock = sockfd; return 0; } /* */ sint32_t NetTCP6Close( pal_socket_t Socket ) { pal_shutdown( Socket, PAL_SOCK_SHTDN_BOTH ); return pal_closesocket( Socket ); } /* */ sint32_t NetTCP6ReadWrite( pal_socket_t sock, char *bi, sint32_t li, char *bo, sint32_t lo ) { if ( NetTCP6Write(sock, bi, li) != li) return -1; return NetTCP6Read(sock, bo, lo); } /* */ sint32_t NetTCP6Write( pal_socket_t sock, char *b, sint32_t l ) { sint32_t nleft, nwritten; char *ptr; ptr = b; /* can't do pointer arithmetic on void * */ nleft = l; while( nleft > 0 ) { if( (nwritten = send(sock, ptr, nleft, 0)) <= 0 ) { return nwritten; /* error */ } nleft -= nwritten; ptr += nwritten; } return(l); } /* */ sint32_t NetTCP6Printf( pal_socket_t sock, char *out, sint32_t pl, char *Format, ... ) { va_list argp; sint32_t Length; char Data[1024]; va_start(argp, Format); pal_vsnprintf(Data, sizeof Data, Format, argp); va_end(argp); Length = pal_strlen(Data); if( NetTCP6Write(sock, Data, pal_strlen(Data)) != Length ) { return 0; } return NetTCP6Read(sock, out, pl); } /* */ sint32_t NetTCP6Read( pal_socket_t sock, char *in, sint32_t l ) { return( recv(sock, in, l, 0) ); } gogoc-1_2-RELEASE/gogoc-tsp/src/net/net_udp.c0100644000000000000000000000473111301544624017376 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: net_udp.c,v 1.1 2009/11/20 16:53:40 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ #include "platform.h" #include "net_udp.h" #include "net.h" // -------------------------------------------------------------------------- // NetUDPConnect: // // Return values: // 0: success // -1: Failed to resolve srvname. // -2: Socket error / Failed to connect (TCP only). // sint32_t NetUDPConnect(pal_socket_t *p_sock, char *Host, uint16_t Port) { pal_socket_t sockfd; struct sockaddr_in serv_addr; struct in_addr addr; if( NetText2Addr(Host, &addr) == NULL ) { return -1; } memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(Port); serv_addr.sin_addr.s_addr = addr.s_addr; /* * Open a UDP socket. */ if( (sockfd = pal_socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) { return -2; } /* * Connect to the server. */ if( pal_connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0 ) { pal_closesocket( sockfd ); return -2; } *p_sock = sockfd; return 0; } /* */ sint32_t NetUDPClose(pal_socket_t Socket) { pal_shutdown( Socket, PAL_SOCK_SHTDN_BOTH ); return pal_closesocket(Socket); } /* */ sint32_t NetUDPReadWrite(pal_socket_t sock, char *bi, sint32_t li, char *bo, sint32_t lo) { if ( NetUDPWrite(sock, bi, li) != li) return -1; return NetUDPRead(sock, bo, lo); } /* */ sint32_t NetUDPWrite(pal_socket_t sock, char *b, sint32_t l) { sint32_t nwritten, nleft; char *ptr; ptr = b; /* can't do pointer arithmetic on void* */ nleft = l; while (nleft > 0) { nwritten = send(sock, ptr, nleft, 0); if (nwritten <= 0) { return nwritten; /* error */ } nleft -= nwritten; ptr += nwritten; } return l; } /* */ sint32_t NetUDPPrintf(pal_socket_t sock, char *out, sint32_t ol, char *Format, ...) { va_list argp; char Data[1024]; va_start(argp, Format); pal_vsnprintf(Data, sizeof Data, Format, argp); va_end(argp); return NetUDPReadWrite(sock, Data, pal_strlen(Data), out, ol); } /* */ sint32_t NetUDPRead( pal_socket_t sock, char *b, sint32_t l ) { return(recvfrom(sock, b, l, 0, NULL, NULL)); } gogoc-1_2-RELEASE/gogoc-tsp/src/tsp/0040755000000000000000000000000011346561543015622 5ustar rootrootgogoc-1_2-RELEASE/gogoc-tsp/src/tsp/Makefile0100644000000000000000000000350111301544624017246 0ustar rootroot# ########################################################################### # $Id: Makefile,v 1.1 2009/11/20 16:53:40 jasminko Exp $ # # Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. # # For license information refer to CLIENT-LICENSE.TXT # # ########################################################################### # # NOTE: This makefile MUST be interpreted by GNU make. # Include the platform makefile, if it exists. -include $(PLATFORM_DIR)/$(PLATFORM)/platform.mak ifdef DEBUG CFLAGS=-g -Wall $(CC_INC_PATHS) $(PLATFORM_CFLAGS) -D_REENTRANT -DDEBUG else CFLAGS=-O2 -Wall $(CC_INC_PATHS) $(PLATFORM_CFLAGS) -D_REENTRANT endif CC=gcc OBJS=$(OBJS_DIR)/tsp_auth.o \ $(OBJS_DIR)/tsp_cap.o \ $(OBJS_DIR)/tsp_client.o \ $(OBJS_DIR)/tsp_net.o \ $(OBJS_DIR)/tsp_setup.o \ $(OBJS_DIR)/tsp_auth_passdss.o \ $(OBJS_DIR)/tsp_lease.o \ $(OBJS_DIR)/tsp_redirect.o \ $(OBJS_DIR)/tsp_tun_mgt.o all: $(OBJS) install: all $(OBJS_DIR)/tsp_auth.o:tsp_auth.c $(CC) $(CFLAGS) -c tsp_auth.c -o $(OBJS_DIR)/tsp_auth.o $(OBJS_DIR)/tsp_cap.o:tsp_cap.c $(CC) $(CFLAGS) -c tsp_cap.c -o $(OBJS_DIR)/tsp_cap.o $(OBJS_DIR)/tsp_client.o:tsp_client.c $(CC) $(CFLAGS) -c tsp_client.c -o $(OBJS_DIR)/tsp_client.o $(OBJS_DIR)/tsp_net.o:tsp_net.c $(CC) $(CFLAGS) -c tsp_net.c -o $(OBJS_DIR)/tsp_net.o $(OBJS_DIR)/tsp_setup.o:tsp_setup.c $(CC) $(CFLAGS) -c tsp_setup.c -o $(OBJS_DIR)/tsp_setup.o $(OBJS_DIR)/tsp_auth_passdss.o:tsp_auth_passdss.c $(CC) $(CFLAGS) -c tsp_auth_passdss.c -o $(OBJS_DIR)/tsp_auth_passdss.o $(OBJS_DIR)/tsp_lease.o:tsp_lease.c $(CC) $(CFLAGS) -c tsp_lease.c -o $(OBJS_DIR)/tsp_lease.o $(OBJS_DIR)/tsp_redirect.o:tsp_redirect.c $(CC) $(CFLAGS) -c tsp_redirect.c -o $(OBJS_DIR)/tsp_redirect.o $(OBJS_DIR)/tsp_tun_mgt.o:tsp_tun_mgt.c $(CC) $(CFLAGS) -c tsp_tun_mgt.c -o $(OBJS_DIR)/tsp_tun_mgt.o clean: rm -f $(OBJS) gogoc-1_2-RELEASE/gogoc-tsp/src/tsp/tsp_auth.c0100644000000000000000000005214011301544624017604 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: tsp_auth.c,v 1.1 2009/11/20 16:53:40 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ #include "platform.h" #include "gogoc_status.h" #include "tsp_redirect.h" #include "tsp_client.h" #include "tsp_auth.h" #ifndef NO_OPENSSL #include "tsp_auth_passdss.h" #endif #include "log.h" #include "hex_strings.h" #include "base64.h" #include "md5.h" #include "version.h" // Challenge structure. typedef struct { char *realm, *nonce, *qop, *algorithm, *charset, *rspauth; } tChallenge; // -------------------------------------------------------------------------- // AuthANONYMOUS: Performs an anonymous authentication with the server. // gogoc_status AuthANONYMOUS(pal_socket_t socket, net_tools_t *nt, tConf *conf, tBrokerList **broker_list) { char Buffer[REDIRECT_RECEIVE_BUFFER_SIZE]; char string[] = "AUTHENTICATE ANONYMOUS\r\n"; sint32_t tsp_status; // Send authentication mode. if( nt->netsendrecv(socket, string, sizeof(string), Buffer, sizeof(Buffer)) == -1 ) { Display(LOG_LEVEL_1, ELError, "AuthANONYMOUS", STR_NET_FAIL_RW_SOCKET); return make_status(CTX_TSPAUTHENTICATION, ERR_SOCKET_IO); } tsp_status = tspGetStatusCode(Buffer); // Check if the reply status indicated a broker redirection. if( tspIsRedirectStatus(tsp_status) ) { if( tspHandleRedirect(Buffer, conf, broker_list) == TSP_REDIRECT_OK ) { // Return a REDIRECT event. return make_status(CTX_TSPAUTHENTICATION, EVNT_BROKER_REDIRECTION); } else { // Redirect error. return make_status(CTX_TSPAUTHENTICATION, ERR_BROKER_REDIRECTION); } } // Check if authentication was successful. // No need to handle TSP_PROTOCOL_AUTH_FAILED here... if( tsp_status != TSP_PROTOCOL_SUCCESS ) { Display(LOG_LEVEL_1, ELError, "AuthANONYMOUS", STR_TSP_UNKNOWN_ERR_AUTH_FAILED, tspGetTspStatusStr(tsp_status)); return make_status(CTX_TSPAUTHENTICATION, ERR_TSP_GENERIC_ERROR); } // Successful anonymous authentication. return make_status(CTX_TSPAUTHENTICATION, SUCCESS); } // -------------------------------------------------------------------------- // AuthPLAIN: Performs a plain-text username and password authentication with // the server. // gogoc_status AuthPLAIN(pal_socket_t socket, net_tools_t *nt, tConf *conf, tBrokerList **broker_list) { char BufferIn[1024]; char BufferOut[REDIRECT_RECEIVE_BUFFER_SIZE]; char string[] = "AUTHENTICATE PLAIN\r\n"; int Length; sint32_t tsp_status; // Send authentication mode. if( nt->netsend(socket, string, sizeof(string)) == -1 ) { Display(LOG_LEVEL_1, ELError, "AuthPLAIN", STR_NET_FAIL_W_SOCKET); return make_status(CTX_TSPAUTHENTICATION, ERR_SOCKET_IO); } memset(BufferIn, 0, sizeof(BufferIn)); Length = pal_snprintf(BufferIn, sizeof(BufferIn), "%c%s%c%s\r\n", '\0', conf->userid, '\0', conf->passwd); // Send username/password for authentication. if( nt->netsendrecv(socket, BufferIn, Length, BufferOut, sizeof(BufferOut)) == -1 ) { Display(LOG_LEVEL_1, ELError, "AuthPLAIN", STR_NET_FAIL_RW_SOCKET); return make_status(CTX_TSPAUTHENTICATION, ERR_SOCKET_IO); } tsp_status = tspGetStatusCode(BufferOut); // Check if the reply status indicated a broker redirection. if( tspIsRedirectStatus(tsp_status) ) { if( tspHandleRedirect(BufferOut, conf, broker_list) == TSP_REDIRECT_OK ) { // Return a REDIRECT event. return make_status(CTX_TSPAUTHENTICATION, EVNT_BROKER_REDIRECTION); } else { // Redirect error. return make_status(CTX_TSPAUTHENTICATION, ERR_BROKER_REDIRECTION); } } // Check if authentication was successful. switch( tsp_status ) { case TSP_PROTOCOL_SUCCESS: break; case TSP_PROTOCOL_AUTH_FAILED: Display(LOG_LEVEL_1, ELError, "AuthPLAIN", STR_TSP_AUTH_FAILED_USER, conf->userid); return make_status(CTX_TSPAUTHENTICATION, ERR_AUTHENTICATION_FAILURE); default: Display(LOG_LEVEL_1, ELError, "AuthPLAIN", STR_TSP_UNKNOWN_ERR_AUTH_FAILED, tspGetTspStatusStr(tsp_status)); return make_status(CTX_TSPAUTHENTICATION, ERR_TSP_GENERIC_ERROR); } // Successful plain text authentication. return make_status(CTX_TSPAUTHENTICATION, SUCCESS); } // -------------------------------------------------------------------------- // InsertInChallegeStruct: Helper function to fill in a tChallenge struct. // sint32_t InsertInChallegeStruct(tChallenge *c, char *Token, char *Value) { if(strcmp(Token, "realm")==0) { c->realm = pal_strdup(Value); return 0; } if(strcmp(Token, "nonce")==0) { c->nonce = pal_strdup(Value); return 0; } if(strcmp(Token, "qop")==0) { c->qop = pal_strdup(Value); return 0; } if(strcmp(Token, "algorithm")==0) { c->algorithm = pal_strdup(Value); return 0; } if(strcmp(Token, "charset")==0) { c->charset = pal_strdup(Value); return 0; } if(strcmp(Token, "rspauth")==0) { c->rspauth = pal_strdup(Value); return 0; } return -1; } // -------------------------------------------------------------------------- // // void ExtractChallenge(tChallenge *c, char *String) { char *s, *e, *Token, *Value; int len; memset(c, 0, sizeof(tChallenge)); Token = (char*) pal_malloc( pal_strlen(String)+1 ); Value = (char*) pal_malloc( pal_strlen(String)+1 ); *Token=*Value=0; for(s=e=String; ; e++) { if(*e== ',' || *e == '\r' || *e == '\n' || *e==0) { if(s!=e) { if(*Token && (*Value==0)) { len = (int)((char *)e-(char *)s); /* Chop the quotes */ if((*s == '"') && len) { s++; len--; } if((s[len-1] == '"') && len) len--; if(len) memcpy(Value, s, len); Value[len] = 0; } if(*Token && *Value) { InsertInChallegeStruct(c, Token,Value); *Value = *Token = 0; } } if(*e == 0) break; s = ++e; } if((*e=='=' || *e== ',' || *e == '\r' || *e == '\n' || *e==0) && (*Token == 0) && (e != s)) { len = (int)((char *)e-(char *)s); memcpy(Token, s, len); Token[len] = 0; if(*e == 0) break; s = ++e; } } pal_free( Token ); pal_free( Value ); } // -------------------------------------------------------------------------- // AuthDIGEST_MD5: Performs a Digest-MD5 authentication with the server. // gogoc_status AuthDIGEST_MD5(pal_socket_t socket, net_tools_t *nt, tConf *conf, tBrokerList **broker_list, int version_index) { char Buffer[4096], Response[33], cResponse[33], *ChallengeString; char string[] = "AUTHENTICATE DIGEST-MD5\r\n"; char BufferIn[REDIRECT_RECEIVE_BUFFER_SIZE]; time_t cnonce = pal_time(NULL); tChallenge c; sint32_t tsp_status; // Send authentication mode. memset(BufferIn, 0, sizeof(BufferIn)); if( nt->netsendrecv(socket, string, sizeof(string), BufferIn, sizeof(BufferIn)) == -1 ) { Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_NET_FAIL_RW_SOCKET); return make_status(CTX_TSPAUTHENTICATION, ERR_SOCKET_IO); } tsp_status = tspGetStatusCode(BufferIn); // Check if the reply status indicated a broker redirection. if( tspIsRedirectStatus(tsp_status) ) { if( tspHandleRedirect(BufferIn, conf, broker_list) == TSP_REDIRECT_OK ) { // Return a REDIRECT event. return make_status(CTX_TSPAUTHENTICATION, EVNT_BROKER_REDIRECTION); } else { // Redirect error. return make_status(CTX_TSPAUTHENTICATION, ERR_BROKER_REDIRECTION); } } // Check for error in status. if( tsp_status == TSP_PROTOCOL_AUTH_FAILED ) { // Failed authentication. Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_TSP_AUTH_FAILED_USER, conf->userid); return make_status(CTX_TSPAUTHENTICATION, ERR_AUTHENTICATION_FAILURE); } // Allocate memory for challenge string. if( (ChallengeString = pal_malloc(pal_strlen(BufferIn) + 1)) == NULL ) { Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_GEN_MALLOC_ERROR); return make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION); } base64decode(ChallengeString, BufferIn); ExtractChallenge(&c, ChallengeString); pal_free(ChallengeString); { /*-----------------------------------------------------------*/ /* Extract from : RFC 2831 Digest SASL Mechanism Let H(s) be the 16 octet MD5 hash [RFC 1321] of the octet string s. Let KD(k, s) be H({k, ":", s}), i.e., the 16 octet hash of the string k, a colon and the string s. Let HEX(n) be the representation of the 16 octet MD5 hash n as a string of 32 hex digits (with alphabetic characters always in lower case, since MD5 is case sensitive). response-value = HEX( KD ( HEX(H(A1)), { nonce-value, ":" nc-value, ":", cnonce-value, ":", qop-value, ":", HEX(H(A2)) })) If authzid is not specified, then A1 is A1 = { H( { username-value, ":", realm-value, ":", passwd } ), ":", nonce-value, ":", cnonce-value } If the "qop" directive's value is "auth", then A2 is: A2 = { "AUTHENTICATE:", digest-uri-value } */ char *A1_1Fmt = "%s:%s:%s", #ifndef WIN32 *A1Fmt = ":%s:%lu", *ChallRespFmt = "%s:%s:00000001:%lu:%s:%s", *ResponseFmt = "charset=%s,username=\"%s\",realm=\"%s\",nonce=\"%s\",nc=00000001,cnonce=\"%lu\",digest-uri=\"tsp/%s\",response=%s,qop=auth", #else // 64 bit version. *A1Fmt = ":%s:%I64d", *ChallRespFmt = "%s:%s:00000001:%I64d:%s:%s", *ResponseFmt = "charset=%s,username=\"%s\",realm=\"%s\",nonce=\"%s\",nc=00000001,cnonce=\"%I64d\",digest-uri=\"tsp/%s\",response=%s,qop=auth", #endif *A2Fmt = "%s:tsp/%s", A1[33], A1_1[33], A2[33], cA2[33], *String; size_t len; /*-----------------------------------------------------------*/ /* Build HEX(H(A2)) & HEX(H(cA2)) */ len = pal_strlen(A2Fmt) + 12 /* AUTHENTICATE */ + pal_strlen(conf->server) + 1; if( (String = pal_malloc(len)) == NULL ) { Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_GEN_MALLOC_ERROR); return make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION); } pal_snprintf(String, len, A2Fmt, "AUTHENTICATE", conf->server); #if defined(_DEBUG) || defined(DEBUG) printf("A2 = %s\n", String); #endif strncpy(A2, md5(String, pal_strlen(String)), 33); pal_snprintf(String, len, A2Fmt, "", conf->server); #if defined(_DEBUG) || defined(DEBUG) printf("cA2 = %s\n", String); #endif strncpy(cA2, md5(String, pal_strlen(String)), 33); pal_free(String); /*-----------------------------------------------------------*/ /* Build HEX(H(A1)) */ /* A1_1 = { username-value, ":", realm-value, ":", passwd } */ /* A1 = { H( A1_1 ), ":", nonce-value, ":", cnonce-value } */ len = pal_strlen(A1_1Fmt) + pal_strlen(conf->userid) + pal_strlen(c.realm) + pal_strlen(conf->passwd) + 1; if( (String = pal_malloc(len)) == NULL ) { Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_GEN_MALLOC_ERROR); return make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION); } pal_snprintf(String, len, A1_1Fmt, conf->userid, c.realm, conf->passwd); #if defined(_DEBUG) || defined(DEBUG) printf("A1_1 = %s\n", String); #endif md5digest(String, pal_strlen(String), A1_1); pal_free(String); len = 16 /* A1_1 */ + 1 + pal_strlen(c.nonce) + 16 /* cnonce */ + 1; if( (String = pal_malloc(len)) == NULL ) { Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_GEN_MALLOC_ERROR); return make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION); } memcpy(String, A1_1, 16); pal_snprintf(String + 16, len - 16, A1Fmt, c.nonce, cnonce); #ifdef SUPPORT_MD5_BUG1455 A1_1[16] = '\0'; if ((pal_strlen(A1_1) < 16) && !((pal_strlen(TSPProtoVerStr[version_index]) > 5) || (strcmp(TSPProtoVerStr[version_index], CLIENT_VERSION_STRING_2_0_0) > 0))) strncpy(A1, md5(String, pal_strlen(String)), 33); else #endif /* SUPPORT_MD5_BUG1455 */ strncpy(A1, md5(String, 16 + pal_strlen(String + 16)), 33); pal_free(String); #if defined(_DEBUG) || defined(DEBUG) printf("A1 = [%s]\n", A1); #endif /*-----------------------------------------------------------*/ /* Build server's and client's challenge responses */ len = pal_strlen(ChallRespFmt) + 32 /* md5(A1) */ + pal_strlen(c.nonce) +16 /* cnonce */ + pal_strlen(c.qop) + 32 /* md5(A2) */ + 1; if((String = pal_malloc(len)) == NULL) { Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_GEN_MALLOC_ERROR); return make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION); } pal_snprintf(String, len, ChallRespFmt, A1, c.nonce, cnonce, c.qop, A2); #if defined(_DEBUG) || defined(DEBUG) printf("Response = [%s]\n", String); #endif strncpy(Response, md5(String, pal_strlen(String)), 33); #if defined(_DEBUG) || defined(DEBUG) printf("MD5 Response = %s\n", Response); #endif pal_snprintf(String, len, ChallRespFmt, A1, c.nonce, cnonce, c.qop, cA2); #if defined(_DEBUG) || defined(DEBUG) printf("cResponse = [%s]\n", String); #endif strncpy(cResponse, md5(String, pal_strlen(String)), 33); #if defined(_DEBUG) || defined(DEBUG) printf("MD5 cResponse = %s\n", cResponse); #endif pal_free(String); /*-----------------------------------------------------------*/ /* Build Response */ { char userid[512]; // UserId is theorically limited to 253 chars. char * cc; size_t i; // Escape malicious " and \ from conf->userid. for(cc=conf->userid, i=0; *cc && i<512; cc++, i++) { // Prepend a backslash (\). if( *cc == '"' || *cc == '\\' ) userid[i++] = '\\'; // Copy character. userid[i] = *cc; } userid[i] = '\0'; len = pal_strlen(ResponseFmt) + pal_strlen(c.charset) + pal_strlen(userid) + pal_strlen(c.realm) + pal_strlen(c.nonce) + 16 /*cnonce*/ + pal_strlen(conf->server) + 32 /* md5 response */; if( (String = pal_malloc(len)) == NULL ) { Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_GEN_MALLOC_ERROR); return make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION); } pal_snprintf(String, len, ResponseFmt, c.charset, userid, c.realm, c.nonce, cnonce, conf->server, Response); memset(Buffer, 0, sizeof(Buffer)); base64encode(Buffer, String, (int)pal_strlen(String)); pal_free(String); } } // Send authentication data. memset(BufferIn, 0, sizeof(BufferIn)); if( nt->netprintf(socket, BufferIn, sizeof(BufferIn), "%s\r\n", Buffer) == -1 ) { Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_NET_FAIL_W_SOCKET); return make_status(CTX_TSPAUTHENTICATION, ERR_SOCKET_IO); } tsp_status = tspGetStatusCode(BufferIn); // Check if the reply status indicated a broker redirection. if( tspIsRedirectStatus(tsp_status) ) { if( tspHandleRedirect(BufferIn, conf, broker_list) == TSP_REDIRECT_OK ) { // Return a REDIRECT event. return make_status(CTX_TSPAUTHENTICATION, EVNT_BROKER_REDIRECTION); } else { // Redirect error. return make_status(CTX_TSPAUTHENTICATION, ERR_BROKER_REDIRECTION); } } /*-----------------------------------------------------------*/ /* Verify server response */ if( tsp_status == TSP_PROTOCOL_AUTH_FAILED ) { // Failed authentication. Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_TSP_AUTH_FAILED_USER, conf->userid); return make_status(CTX_TSPAUTHENTICATION, ERR_AUTHENTICATION_FAILURE); } if( (ChallengeString = pal_malloc(pal_strlen(BufferIn) + 1)) == NULL ) { Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_GEN_MALLOC_ERROR); return make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION); } base64decode(ChallengeString, BufferIn); ExtractChallenge(&c, ChallengeString); pal_free(ChallengeString); if( memcmp(c.rspauth, cResponse, 32) ) { Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_MISC_INVALID_MD5_RESPONSE); return make_status(CTX_TSPAUTHENTICATION, ERR_AUTHENTICATION_FAILURE); } // Receive reply. if( nt->netrecv(socket, Buffer, sizeof(Buffer) ) == -1 ) { Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_NET_FAIL_R_SOCKET); return make_status(CTX_TSPAUTHENTICATION, ERR_SOCKET_IO); } tsp_status = tspGetStatusCode(Buffer); // Check if the reply status indicated a broker redirection. if( tspIsRedirectStatus(tsp_status) ) { if( tspHandleRedirect(Buffer, conf, broker_list) == TSP_REDIRECT_OK ) { // Return a REDIRECT event. return make_status(CTX_TSPAUTHENTICATION, EVNT_BROKER_REDIRECTION); } else { // Redirect error. return make_status(CTX_TSPAUTHENTICATION, ERR_BROKER_REDIRECTION); } } // Check if authentication was successful. switch( tsp_status ) { case TSP_PROTOCOL_SUCCESS: break; case TSP_PROTOCOL_AUTH_FAILED: Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_TSP_AUTH_FAILED_USER, conf->userid); return make_status(CTX_TSPAUTHENTICATION, ERR_AUTHENTICATION_FAILURE); default: Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_TSP_UNKNOWN_ERR_AUTH_FAILED, tspGetTspStatusStr(tsp_status)); return make_status(CTX_TSPAUTHENTICATION, ERR_TSP_GENERIC_ERROR); } // Successful MD5 authentication. return make_status(CTX_TSPAUTHENTICATION, SUCCESS); } // -------------------------------------------------------------------------- // Function : tspAuthenticate // // Synopsys: Will authenticate a session with the broker. // // Description: // First, we'll try to find the most secure common authentication method. // Once the authentication method has been chosen, the authentication // process is initiated with the broker. // // Arguments: (only local-specific arguments are listed here) // cap: bitfield [IN], The authentication methods suported by the broker. // conf: tConf* [IN], The global configuration object. // // Return values: // A gogoc_status status. // // -------------------------------------------------------------------------- gogoc_status tspAuthenticate(pal_socket_t socket, tCapability cap, net_tools_t *nt, tConf *conf, tBrokerList **broker_list, int version_index) { gogoc_status status = make_status(CTX_TSPAUTHENTICATION, ERR_NO_COMMON_AUTHENTICATION); tCapability Mechanism; // Get mechanism, depending on requested authentication method. if( pal_strcasecmp( conf->auth_method, "any" ) == 0 ) Mechanism = AUTH_ANY; else Mechanism = tspSetCapability("AUTH", conf->auth_method); if( pal_strcasecmp( conf->auth_method, "anonymous" ) != 0 ) { // Try the most secure authentication methods first: #ifndef NO_OPENSSL if( Mechanism & cap & AUTH_PASSDSS_3DES_1 ) { Display(LOG_LEVEL_3, ELInfo, "tspAuthenticate", GOGO_STR_USING_AUTH_PASSDSS_3DES_1); status = AuthPASSDSS_3DES_1(socket, nt, conf, broker_list); goto EndAuthenticate; } #endif if( Mechanism & cap & AUTH_DIGEST_MD5 ) { Display(LOG_LEVEL_3, ELInfo, "tspAuthenticate", GOGO_STR_USING_AUTH_DIGEST_MD5); status = AuthDIGEST_MD5(socket, nt, conf, broker_list, version_index); goto EndAuthenticate; } if( Mechanism & cap & AUTH_PLAIN ) { Display(LOG_LEVEL_3, ELInfo, "tspAuthenticate", GOGO_STR_USING_AUTH_PLAIN); status = AuthPLAIN(socket, nt, conf, broker_list); goto EndAuthenticate; } } else { // Finally, try anonymous if possible. if( Mechanism & cap & AUTH_ANONYMOUS ) { Display(LOG_LEVEL_3, ELInfo, "tspAuthenticate", GOGO_STR_USING_AUTH_ANONYMOUS); status = AuthANONYMOUS(socket, nt, conf, broker_list); goto EndAuthenticate; } } EndAuthenticate: if( status_number(status) == ERR_NO_COMMON_AUTHENTICATION ) { const char* szStrings[] = { "Server Authentication Capabilities: ", "Your Configured Authentication: " }; size_t nWritten; char bufDisplay[256]; // Display server authentication capabilities. pal_snprintf( bufDisplay, sizeof(bufDisplay), "%s", szStrings[0] ); nWritten = pal_strlen( szStrings[0] ); tspFormatCapabilities( bufDisplay + nWritten, sizeof(bufDisplay) - nWritten, cap ); Display( LOG_LEVEL_1, ELWarning, "tspAuthenticate", bufDisplay ); // Display user authentication choice. pal_snprintf( bufDisplay, sizeof(bufDisplay), "%s", szStrings[1] ); nWritten = pal_strlen( szStrings[1] ); tspFormatCapabilities( bufDisplay + nWritten, sizeof(bufDisplay) - nWritten, Mechanism ); Display( LOG_LEVEL_1, ELWarning, "tspAuthenticate", bufDisplay ); // Failed to find a common authentication method. Display(LOG_LEVEL_1, ELError, "tspAuthenticate", STR_TSP_NO_COMMON_AUTHENTICATION); } return status; } gogoc-1_2-RELEASE/gogoc-tsp/src/tsp/tsp_auth_passdss.c0100644000000000000000000006704411345004343021352 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: tsp_auth_passdss.c,v 1.2 2010/03/07 20:13:23 carl Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ #include "platform.h" #include "gogoc_status.h" #ifndef NO_OPENSSL #include #include #include #include #include #include "tsp_auth_passdss.h" #include "buffer.h" #include "bufaux.h" #include "log.h" #include "hex_strings.h" #include "base64.h" #include "cli.h" // ask() #include "tsp_redirect.h" #include "tsp_client.h" #define TSP_AUTH_PASSDSS_STRING "PASSDSS-3DES-1" #define TSP_AUTH_PASSDSS_BUFFERSIZE 4096 #define TSPC_DSA_KEYFILE "gogockeys.pub" #if defined(WIN32) && !defined(WINCE) extern BOOL IsService; // Declared in winpc/tsp_local.c #endif static int freadline(char *buf, int max_len, FILE *fp) { int pos; char c; pos = 0; while ( ((c=(char)fgetc(fp)) != EOF) && posp, bn_p) && !BN_cmp(dsa_1->q, bn_q) && !BN_cmp(dsa_1->g, bn_g) && !BN_cmp(dsa_1->pub_key, bn_pub_key) ) ret = 2; else ret = 3; } is_dsakey_in_keyfile_cleanup: if (str) pal_free(str); if (line_buf) pal_free(line_buf); if (fp) fclose(fp); if (bn_p) BN_clear_free(bn_p); if (bn_q) BN_clear_free(bn_q); if (bn_g) BN_clear_free(bn_g); if (bn_pub_key) BN_clear_free(bn_pub_key); if (keyfile_buf.buf) buffer_free(&keyfile_buf); return ret; } /** Add a DSA key to the tspc key file * * @param dsa the DSA param pointer filled with our key info * @param host the hostname of the corresponding broker * @param filename the keyfile to use * * @return 0 if error * 1 if ok * */ int add_dsakey_to_keyfile(DSA *dsa, char *host, char *filename, tBoolean autoaccept) { FILE *fp = NULL; Buffer buf; char *str = NULL; int ret = 0; switch (is_dsakey_in_keyfile(dsa, host, filename)) { case 0: Display(LOG_LEVEL_3, ELInfo, TSP_AUTH_PASSDSS_STRING, GOGO_STR_ERR_IN_KEY_VERIF); Display(LOG_LEVEL_3, ELWarning, TSP_AUTH_PASSDSS_STRING, GOGO_STR_SERVER_KEY_REJECTED); break; case 1: /* not in, we add and continue */ #if defined(WIN32) && !defined(WINCE) // When running as a service we can't ask user // permission. Compromise and accept the key auto // if (!IsService && !autoaccept) { #else if (!autoaccept) { #endif if (!ask(GOGO_STR_UNKNOWN_HOST_ADD_KEY, host)) { Display(LOG_LEVEL_3, ELWarning, TSP_AUTH_PASSDSS_STRING, GOGO_STR_SERVER_KEY_REJECTED_USER); break; } } else Display(LOG_LEVEL_1, ELWarning, TSP_AUTH_PASSDSS_STRING, GOGO_STR_WARN_SERVER_KEY_AUTO_ADDED); Display(LOG_LEVEL_2, ELInfo, TSP_AUTH_PASSDSS_STRING, GOGO_STR_SERVER_KEY_ACCEPTED_ADDED); buffer_init(&buf); if (buf.buf == NULL) break; buffer_put_cstring(&buf, "ssh-dss"); buffer_put_bignum(&buf, dsa->p); buffer_put_bignum(&buf, dsa->q); buffer_put_bignum(&buf, dsa->g); buffer_put_bignum(&buf, dsa->pub_key); if ( (str = pal_malloc(2 * buffer_len(&buf))) == NULL) break; if ( (base64encode(str, buffer_ptr(&buf), (int) buffer_len(&buf))) < 1) break; fp = fopen(filename, "a"); if (fp) { fprintf(fp, "%s ssh-dss %s\n", host, str); fclose(fp); ret = 1; } buffer_free(&buf); pal_free(str); break; case 2: /* in and matching correctly, hurray */ Display(LOG_LEVEL_2, ELInfo, TSP_AUTH_PASSDSS_STRING, GOGO_STR_MATCHING_KEY_FOUND_USED); ret = 1; break; case 3: /* in and NOT matching correctly */ Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, GOGO_STR_WARN_STORED_LOCAL_KEY_NO_MATCH, filename, host); Display(LOG_LEVEL_3, ELWarning, TSP_AUTH_PASSDSS_STRING, GOGO_STR_SERVER_KEY_REJECTED); ret = 0; break; } return ret; } /** * Authenticate to the Migration Broker using PASSDSS-3DES-1 * * Buf_H will contain the data used to validate the server * signature. The data is a concatenation of the following parameters, * in that order: * azname,authname,DH_public_key,pklength,"ssh-dss",p,q,g,z,Y,ssecmask,sbuflen,dh_K * * @param socket * @param user * @param passwd * @param host * @param nt * * @return * * @todo DH public key validation (RFC2631, 2.1.5) * @todo Local storage for server public keys * */ gogoc_status AuthPASSDSS_3DES_1(pal_socket_t socket, net_tools_t *nt, tConf *conf, tBrokerList **broker_list) { DH *dh = NULL; /**< client DH key used to exchange key with server */ DSA *dsa = NULL; /**< Remote server DSA key public information */ DSA_SIG *sig = NULL; /**< DSA signature */ char authenticate[] = "AUTHENTICATE PASSDSS-3DES-1\r\n"; char *BufferIn = NULL; char *BufferOut = NULL; char *BufferPtr = NULL; Buffer BufH; /**< Buffer to hold data used for signature. */ Buffer BufSpace; /**< Space to hold data before/after base64 conversion */ Buffer *Buf_H = &BufH; Buffer *Buf_Space = &BufSpace; BIO *bio_rw = NULL; /**< Memory buffer bio */ BIO *b64= NULL; /**< Base64 bio */ BIO *cipher = NULL; /**< Symmetric crypto bio */ BIGNUM *server_pubkey = NULL; /**< received server public DH key */ BIGNUM *dh_K = NULL; /**< DH computed shared secret */ u_char hash[20]; /**< SHA1 hash */ u_char enc_key[24]; /**< encryption key (3des) */ u_char enc_iv[8]; /**< initialization vector (3des) */ u_char int_key[20]; /**< cs integrity key */ u_char tmphash[40]; /**< temporary hash storage */ u_char hmac[EVP_MAX_MD_SIZE]; /**< HMAC for integrity of sent data (step L) */ int pklength = 0; /**< length of SSH-style DSA server public key */ int ssecmask = 0; /**< SASL security layers offered */ int sbuflen = 0; /**< maximum server security layer block size */ char *s = NULL; u_char num[3]; /**< Array to manupulate 3 octet number (sbuflen) */ /* Temporary variables */ int buflen, readlen, keysize, siglength; gogoc_status status = STATUS_SUCCESS_INIT; sint32_t tsp_status; /* From draft-newman-sasl-passdss-01. "This group was taken from the * ISAKMP/Oakley specification, and was originally generated by * Richard Schroeppel at the University of Arizona. Properties of * this prime are described in [Orm96]" */ /* RFC2409, DH group 2 (second Oakley group) */ static char *dh_group2= "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381" "FFFFFFFF" "FFFFFFFF"; static unsigned char dh_g[]={ 0x02, }; /* Initialize Diffie Hellman variables */ if ((dh = DH_new()) == NULL || (server_pubkey = BN_new()) == NULL) { Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, STR_GEN_MALLOC_ERROR); status = make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION); goto error; } /* Convert dh_group2 and dh_g to BIGNUM type */ BN_hex2bn(&dh->p, dh_group2); dh->g = BN_bin2bn(dh_g,sizeof(dh_g),NULL); if ((dh->p == NULL) || (dh->g == NULL)) { Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, GOGO_STR_INITIALIZATION_ERROR); status = make_status(CTX_TSPAUTHENTICATION, ERR_AUTHENTICATION_FAILURE); goto error; } if ((dh_K = BN_new()) == NULL) { Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, STR_GEN_MALLOC_ERROR); status = make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION); goto error; } /* Reserve storage for DSA key */ if ((dsa = DSA_new()) == NULL || (dsa->p = BN_new()) == NULL || (dsa->q = BN_new()) == NULL || (dsa->g = BN_new()) == NULL || (dsa->pub_key = BN_new()) == NULL || (dsa->priv_key = BN_new()) == NULL) { Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, STR_GEN_MALLOC_ERROR); status = make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION); goto error; } /* Allocate memory for DSA signature */ if ((sig = DSA_SIG_new()) == NULL) { Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, STR_GEN_MALLOC_ERROR); status = make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION); goto error; } /* Initialize data buffers */ BufferIn = calloc(1, TSP_AUTH_PASSDSS_BUFFERSIZE); BufferOut = calloc(1, TSP_AUTH_PASSDSS_BUFFERSIZE); if ((BufferIn == NULL) || (BufferOut == NULL)) { Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, STR_GEN_MALLOC_ERROR); status = make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION); goto error; } buffer_init(Buf_Space); buffer_init(Buf_H); if (Buf_Space->buf == NULL || Buf_H->buf == NULL) { Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, STR_GEN_MALLOC_ERROR); status = make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION); goto error; } /* Create a read/write memory BIO. Memory is segment is * created and resized as needed. When BIO is destroyed, the * memory is freed. */ bio_rw = BIO_new(BIO_s_mem()); /* Create a base64 BIO filter */ b64 = BIO_new(BIO_f_base64()); if ((bio_rw == NULL) || (b64 == NULL)) { Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, STR_GEN_MALLOC_ERROR); status = make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION); goto error; } /* Compute the Diffie-Hellman public value "X" as follows. If X has a value of 0, repeat. x X = g mod n where g = dh_g = 2 n = dh_group2 x = DH secret key X = DH public key */ if (DH_generate_key(dh) == 0) { Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, GOGO_STR_DH_GEN_ERROR); status = make_status(CTX_TSPAUTHENTICATION, ERR_AUTHENTICATION_FAILURE); goto error; } /* Validate DH public key (RFC2631, 2.1.5) */ /* Send message with SASL mechanism identifier */ if ( nt->netsend(socket, authenticate, sizeof(authenticate)) == -1 ) { Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, STR_NET_FAIL_W_SOCKET); status = make_status(CTX_TSPAUTHENTICATION, ERR_SOCKET_IO); goto error; } /* First PASSDSS message from client to server: string azname ; the user name to login as, may be empty if same as authentication name string authname ; the authentication name mpint X ; Diffie-Hellman parameter X */ /* azname is empty. Just insert a string length zero */ buffer_put_int(Buf_Space, 0); /* authname */ buffer_put_cstring(Buf_Space, conf->userid); /* DH public key */ buffer_put_bignum(Buf_Space, dh->pub_key); /* At this point, save the buffer into Buf_H. Used later for * signature verification. */ buffer_append(Buf_H, buffer_ptr(Buf_Space), buffer_len(Buf_Space)); /* Push base64 filter */ BIO_push(b64, bio_rw); /* no newline */ BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); /* Write Buffer content into bio_rw. Buffer will be base64 * encoded. */ BIO_write(b64, buffer_ptr(Buf_Space), (int) buffer_len(Buf_Space)); BIO_flush(b64); /* Get pointer to the result */ buflen = BIO_get_mem_data(bio_rw, &BufferPtr); // Send data to server, save response in BufferIn. if((readlen = nt->netsendrecv(socket, BufferPtr, buflen, BufferIn, TSP_AUTH_PASSDSS_BUFFERSIZE)) == -1) { Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, STR_NET_FAIL_RW_SOCKET); status = make_status(CTX_TSPAUTHENTICATION, ERR_SOCKET_IO); goto error; } /* remove base64 filter */ BIO_pop(bio_rw); buffer_clear(Buf_Space); buflen = 0; /* Decode response (base64) and extract server response * * The response format is as follows: uint32 pklength ; length of SSH-style DSA server public key (number of bytes up to y, inclusively) string "ssh-dss" ; constant string "ssh-dss" (lower case) mpint p ; DSA public key parameters mpint q mpint g mpint z (y in draft) mpint Y ; Diffie-Hellman parameter Y OCTET ssecmask ; SASL security layers offered 3 OCTET sbuflen ; maximum server security layer block size uint32 siglength ; length of SSH-style dss signature (number of bytes up to s inclusively) string "ssh-dss" ; constant string "ssh-dss" (lower case) mpint r ; DSA signature parameters mpint s */ buflen = base64decode(BufferOut, BufferIn); buffer_append(Buf_Space, BufferOut, buflen); /* Get pklength */ pklength = buffer_get_int(Buf_Space); /* Assuming that * p, g, and y are 512 bits, * q is 160 bits, * "ssh-dss" is 7 bytes * pklength should be at least 240 bytes. */ if (pklength < 240) { Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, GOGO_STR_RCVD_DATA_INVALID); status = make_status(CTX_TSPAUTHENTICATION, ERR_AUTHENTICATION_FAILURE); goto error; } /* Make a copy of (pklength|"ssh-dss"|p|q|g|z) in Buf_H */ /* Add pklength */ buffer_put_int(Buf_H, pklength); /* Add "ssh-dss"|p|q|g|z */ buffer_append(Buf_H, buffer_ptr(Buf_Space), pklength); /* Get "ssh-dss" string */ s = buffer_get_string(Buf_Space, (unsigned int*)&buflen); pal_free(s); s = NULL; /* Get p */ buffer_get_bignum(Buf_Space, dsa->p); /* Get q */ buffer_get_bignum(Buf_Space, dsa->q); /* Get g */ buffer_get_bignum(Buf_Space, dsa->g); /* Get z (pub_key) */ buffer_get_bignum(Buf_Space, dsa->pub_key); /* Get DH public key */ buffer_get_bignum(Buf_Space, server_pubkey); /* Copy in Buf_H for signature verification later */ buffer_put_bignum(Buf_H, server_pubkey); /* Buffer now points at ssecmask (1 octet), followed by * sbuflen (3 octets). Make a copy of these 4 octets in Buf_H * now, then extract these values. */ buffer_append(Buf_H, buffer_ptr(Buf_Space), 4); /* Get ssecmask */ ssecmask = buffer_get_octet(Buf_Space); /* Get sbuflen * Big endian binary unsigned integer */ buffer_get(Buf_Space, (char *)num, 3); sbuflen = (((u_long)(u_char)(num)[0] << 16) | ((u_long)(u_char)(num)[1] << 8) | ((u_long)(u_char)(num)[2])); /* DSS signature */ /* Get siglength */ siglength = buffer_get_int(Buf_Space); /* r and s are 20 bytes each, encoded as mpint (2*24) * "ssh-dss" is 7 bytes + int32 siglength should be >= 59 * octets (mpint may have leading zero byte) */ if (siglength < 59) { Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, GOGO_STR_RCVD_DATA_INVALID); status = make_status(CTX_TSPAUTHENTICATION, ERR_AUTHENTICATION_FAILURE); goto error; } /* Get "ssh-dss" string */ s = buffer_get_string(Buf_Space, (unsigned int*)&buflen); pal_free(s); s = NULL; /* Get DSA signature r and s*/ if ((sig->r= BN_new()) == NULL || (sig->s = BN_new()) == NULL) { Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, STR_GEN_MALLOC_ERROR); status = make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION); goto error; } /* Get r */ buffer_get_bignum(Buf_Space, sig->r); /* Get s */ buffer_get_bignum(Buf_Space, sig->s); /* Validate server DH public key (RFC2631, 2.1.5) */ { if( !add_dsakey_to_keyfile(dsa, conf->server, TSPC_DSA_KEYFILE, conf->no_questions) ) { Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, GOGO_STR_KEY_VERIF_ERROR); status = make_status(CTX_TSPAUTHENTICATION, ERR_AUTHENTICATION_FAILURE); goto error; } } /* Verify that DSA public key belongs to server */ /* Compute DH shared secret */ if ((s = calloc(1, DH_size(dh))) == NULL) { Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, STR_GEN_MALLOC_ERROR); status = make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION); goto error; } if( (keysize = DH_compute_key((unsigned char*)s, server_pubkey, dh)) < 0 ) { Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, GOGO_STR_DH_SHARED_COMPUTE_ERROR); status = make_status(CTX_TSPAUTHENTICATION, ERR_AUTHENTICATION_FAILURE); goto error; } BN_bin2bn((const unsigned char*)s, keysize, dh_K); memset(s, 0, keysize); pal_free(s); s = NULL; Display(LOG_LEVEL_3, ELDebug, TSP_AUTH_PASSDSS_STRING, GOGO_STR_DH_SHARED_KEY, BN_bn2hex(dh_K)); /* Append dh_K in to complete the buffer. Use Buffer to hold * result to keep Bf_H intact, since to will be used (without * dh_K) to compute HMAC for packet integrity. */ buffer_clear(Buf_Space); buffer_append(Buf_Space, buffer_ptr(Buf_H), buffer_len(Buf_H)); buffer_put_bignum(Buf_Space, dh_K); /* Compute SHA1 hash of Buffer */ SHA1(buffer_ptr(Buf_Space), buffer_len(Buf_Space), hash); /* Debug information available at level 4 */ { BIGNUM *h; h = BN_bin2bn(hash, 20, NULL); Display(LOG_LEVEL_3, ELDebug, TSP_AUTH_PASSDSS_STRING, GOGO_STR_SIGNED_HASH, BN_bn2hex(h)); BN_free(h); } Display(LOG_LEVEL_3, ELDebug, TSP_AUTH_PASSDSS_STRING, GOGO_STR_DSA_SIGN_R, BN_bn2hex(sig->r)); Display(LOG_LEVEL_3, ELDebug, TSP_AUTH_PASSDSS_STRING, GOGO_STR_DSA_SIGN_S, BN_bn2hex(sig->s)); // Verify that the DSS signature is a signature of hash. switch( DSA_do_verify(hash, sizeof(hash), sig, dsa) ) { case 0: Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, GOGO_STR_BAD_SIG_FROM_SERVER); status = make_status(CTX_TSPAUTHENTICATION, ERR_AUTHENTICATION_FAILURE); goto error; break; /* NOTREACHED */ case 1: /* correct signature */ break; default: /* -1 on error */ Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, GOGO_STR_SIG_VERIF_ERROR); status = make_status(CTX_TSPAUTHENTICATION, ERR_AUTHENTICATION_FAILURE); goto error; break; /* NOTREACHED */ } /* Step I: Compute 3DES key and iv */ /* cs-encryption-iv = SHA1( K || "A" || H ) sc-encryption-iv = SHA1( K || "B" || H ) cs-encryption-key-1 = SHA1( K || "C" || H ) cs-encryption-key-2 = SHA1( K || cs-encryption-key-1 ) cs-encryption-key = cs-encryption-key-1 || cs-encryption-key-2 sc-encryption-key-1 = SHA1( K || "D" || H ) sc-encryption-key-2 = SHA1( K || sc-encryption-key-1 ) sc-encryption-key = sc-encryption-key-1 || sc-encryption-key-2 cs-integrity-key = SHA1( K || "E" || H ) sc-integrity-key = SHA1( K || "F" || H ) K is dh_k in mpint format (string) H is hash */ /* Since we won't support SASL security layers, we need to * compute the following only: * cs-encryption-iv * cs-encryption-key * cs-integrity-key */ buffer_clear(Buf_Space); buffer_put_bignum(Buf_Space, dh_K); buffer_put_octet(Buf_Space,'A'); buffer_append(Buf_Space, hash, 20); SHA1(buffer_ptr(Buf_Space), buffer_len(Buf_Space), tmphash); /* Use first 8 octets as iv */ memcpy(enc_iv, tmphash, 8); buffer_clear(Buf_Space); buffer_put_bignum(Buf_Space, dh_K); buffer_put_octet(Buf_Space,'E'); buffer_append(Buf_Space, hash, 20); SHA1(buffer_ptr(Buf_Space), buffer_len(Buf_Space), int_key); buffer_clear(Buf_Space); buffer_put_bignum(Buf_Space, dh_K); buffer_put_octet(Buf_Space,'C'); buffer_append(Buf_Space, hash, 20); SHA1(buffer_ptr(Buf_Space), buffer_len(Buf_Space), tmphash); buffer_clear(Buf_Space); buffer_put_bignum(Buf_Space, dh_K); buffer_append(Buf_Space, tmphash, 20); SHA1(buffer_ptr(Buf_Space), buffer_len(Buf_Space), tmphash+20); /* Use first 24 octets as key */ memcpy(enc_key, tmphash, 24); { BIGNUM *enc, *i, *iv; enc = BN_bin2bn(enc_key, 24, NULL); iv = BN_bin2bn(enc_iv, 8, NULL); i = BN_bin2bn(int_key, 20, NULL); Display(LOG_LEVEL_3, ELDebug, TSP_AUTH_PASSDSS_STRING, GOGO_STR_PASSDS_ENC_KEY, BN_bn2hex(enc)); Display(LOG_LEVEL_3, ELDebug, TSP_AUTH_PASSDSS_STRING, GOGO_STR_PASSDS_IV, BN_bn2hex(iv)); Display(LOG_LEVEL_3, ELDebug, TSP_AUTH_PASSDSS_STRING, GOGO_STR_PASSDS_INTEG_KEY, BN_bn2hex(i)); BN_free(enc); BN_free(i); BN_free(iv); } /* (J) Create a buffer beginning with a bit mask for the selected security layer (it MUST be one offered from server) followed by three octets representing the maximum cipher-text buffer size (at least 32) the client can accept in network byte order. This is followed by a string containing the passphrase. */ buffer_clear(Buf_Space); buffer_put_octet(Buf_Space, ssecmask); buffer_put_octet(Buf_Space, 0); buffer_put_octet(Buf_Space, 0); buffer_put_octet(Buf_Space, 0); /**< @bug must be at least 32 */ buffer_put_cstring(Buf_Space, conf->passwd); /* (K) Create a buffer containing items (1) through (7) immediately followed by the first four octets of (J). */ buffer_append(Buf_H, buffer_ptr(Buf_Space), 4); /* (L) Compute HMAC-SHA-1 with (K) as the data and the cs-integrity- key from step (I) as the key. This produces a 20 octet result. */ HMAC(EVP_sha1(), int_key, sizeof(int_key), buffer_ptr(Buf_H), buffer_len(Buf_H), hmac, (unsigned int*)&keysize); /* (M) Create a buffer containing (J) followed by (L) followed by an arbitrary number of zero octets as necessary to reach the block size of DES and conceal the passphrase length from an eavesdropper. */ buffer_append(Buf_Space, hmac, keysize); /* (N) Apply the triple-DES algorithm to (M) with the first 8 octets of cs-encryption-iv from step (I) as the initialization vector and the first 24 octets of cs-encryption-key as the key. */ /* Padding is automatically done. From OpenSSL EVP_EncryptInit(3): EVP_CIPHER_CTX_set_padding() enables or disables padding. By default encryption operations are padded using standard block padding and the padding is checked and removed when decrypting. */ /* Create BIO filter to encrypt using 3des + convert to base64. Result is written in memory BIO. */ /* Erase BIO and buffer memory */ BIO_reset(bio_rw); memset(BufferOut, 0, TSP_AUTH_PASSDSS_BUFFERSIZE); memset(BufferIn, 0, TSP_AUTH_PASSDSS_BUFFERSIZE); buflen = 0; /* Create cipher BIO */ cipher = BIO_new(BIO_f_cipher()); BIO_set_cipher(cipher, EVP_des_ede3_cbc(), enc_key, enc_iv, 1); /* Assemble filters as cipher->b64->bio_rw */ BIO_push(cipher, b64); BIO_push(b64, bio_rw); /* Write Buffer content into bio_rw */ BIO_write(cipher, buffer_ptr(Buf_Space), (int) buffer_len(Buf_Space)); BIO_flush(cipher); /* Get pointer to the result. */ buflen = BIO_get_mem_data(bio_rw, &BufferPtr); /* wipe encryption material */ memset(enc_key, 0, sizeof(enc_key)); memset(enc_iv, 0, sizeof(enc_iv)); /* Send data to server, save response in BufferIn */ if( (readlen = nt->netsendrecv(socket, BufferPtr, buflen, BufferIn, TSP_AUTH_PASSDSS_BUFFERSIZE)) == -1) { Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, STR_NET_FAIL_RW_SOCKET); status = make_status(CTX_TSPAUTHENTICATION, ERR_SOCKET_IO); goto error; } tsp_status = tspGetStatusCode(BufferIn); // Check if the reply status indicated a broker redirection. if( tspIsRedirectStatus(tsp_status) ) { if( tspHandleRedirect(BufferIn, conf, broker_list) == TSP_REDIRECT_OK ) { status = make_status(CTX_TSPAUTHENTICATION, EVNT_BROKER_REDIRECTION); } else { // Redirect error. status = make_status(CTX_TSPAUTHENTICATION, ERR_BROKER_REDIRECTION); } goto error; } // Check if authentication was successful. switch( tsp_status ) { case TSP_PROTOCOL_SUCCESS: break; case TSP_PROTOCOL_AUTH_FAILED: Display(LOG_LEVEL_1, ELError, "AuthPASSDSS_3DES_1", STR_TSP_AUTH_FAILED_USER, conf->userid); status = make_status(CTX_TSPAUTHENTICATION, ERR_AUTHENTICATION_FAILURE); goto error; default: Display(LOG_LEVEL_1, ELError, "AuthPASSDSS_3DES_1", STR_TSP_UNKNOWN_ERR_AUTH_FAILED, tspGetTspStatusStr(tsp_status)); status = make_status(CTX_TSPAUTHENTICATION, ERR_TSP_GENERIC_ERROR); goto error; } status = STATUS_SUCCESS_INIT; error: /* Free storage for DSA key */ if (dsa != NULL) DSA_free(dsa); /* Also frees BIGNUMs inside struct */ /* DSA signature */ if (sig != NULL) DSA_SIG_free(sig); /* Free Diffie Hellman variables */ if (dh != NULL) DH_free(dh); /* Also frees BIGNUMs inside struct */ if (server_pubkey != NULL) BN_free(server_pubkey); if (dh_K != NULL) BN_free(dh_K); /* Buffers */ if (Buf_Space->buf != NULL) buffer_free(Buf_Space); if (Buf_H->buf != NULL) buffer_free(Buf_H); /* malloc'ed space*/ if (BufferIn != NULL) pal_free(BufferIn); if (BufferOut != NULL) pal_free(BufferOut); /* BIOs */ if (cipher != NULL) BIO_vfree(cipher); if (b64 != NULL) BIO_vfree(b64); if (bio_rw != NULL) BIO_vfree(bio_rw); /* strings buffers */ if (s != NULL) pal_free(s); return status; } #endif gogoc-1_2-RELEASE/gogoc-tsp/src/tsp/tsp_cap.c0100644000000000000000000001454311301544625017414 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: tsp_cap.c,v 1.1 2009/11/20 16:53:41 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ #include "platform.h" #include "gogoc_status.h" #include "tsp_cap.h" #include "tsp_client.h" // tspGetStatusCode() #include "net.h" #include "log.h" #include "hex_strings.h" #include "version.h" #include "tsp_redirect.h" // -------------------------------------------------------------------------- // Convert a CAPABILITY string in corresponding bit in capability flag. // tCapability tspExtractCapability(char *String) { tCapability flags = 0; char *s, *e, *Token, *Value; int len; Token = (char*) malloc( strlen(String)+1 ); Value = (char*) malloc( strlen(String)+1 ); *Token = *Value = 0; for(s=e=String+11; *e; e++) { if(*e== ' ' || *e == '\r' || *e == '\n' || *e == 0) { if(s!=e) { if(*Token && (*Value == 0)) { len = (int)((char *)e-(char *)s); memcpy(Value, s, len); Value[len] = 0; } if(*Token && *Value) { flags |= tspSetCapability(Token,Value); *Value = *Token = 0; } } s = ++e; } if((*e=='=' || *e== ' ' || *e == '\r' || *e == '\n' || *e == 0) && (e != s)) { len = (int)((char *)e-(char *)s); memcpy(Token, s, len); Token[len] = 0; s = ++e; } } free( Token ); free( Value ); return flags; } // -------------------------------------------------------------------------- // Return the capability flag corrsponding to the token. // tCapability tspSetCapability(char *Token, char *Value) { if(strcmp("TUNNEL", Token)==0) { if(strcmp("V6V4", Value)==0) return TUNNEL_V6V4; if(strcmp("V6UDPV4", Value)==0) return TUNNEL_V6UDPV4; #ifdef V4V6_SUPPORT if(strcmp("V4V6", Value)==0) return TUNNEL_V4V6; #endif /* V4V6_SUPPORT */ } if(strcmp("AUTH", Token)==0) { #ifndef NO_OPENSSL if(pal_strcasecmp("PASSDSS-3DES-1", Value)==0) return AUTH_PASSDSS_3DES_1; #endif if(pal_strcasecmp("DIGEST-MD5", Value)==0) return AUTH_DIGEST_MD5; if(pal_strcasecmp("ANONYMOUS", Value)==0) return AUTH_ANONYMOUS; if(pal_strcasecmp("PLAIN", Value)==0) return AUTH_PLAIN; } return 0; } // -------------------------------------------------------------------------- // tspGetCapabilities: // gogoc_status tspGetCapabilities(pal_socket_t socket, net_tools_t *nt, tCapability *capability, int version_index, tConf *conf, tBrokerList **broker_list) { char dataout[256]; char datain[REDIRECT_RECEIVE_BUFFER_SIZE]; sint32_t tsp_status; gogoc_status status = make_status(CTX_TSPCAPABILITIES, SUCCESS); memset( datain, 0, sizeof(datain) ); pal_snprintf(dataout, sizeof(dataout), "VERSION=%s\r\n", TSPProtoVerStr[version_index]); // Send TSP version to the server. Server should reply with the capabilities. if( nt->netsendrecv(socket, dataout, pal_strlen(dataout), datain, (sint32_t)sizeof(datain)) == -1 ) { // Error reading/writing to the socket. return make_status(CTX_TSPCAPABILITIES, ERR_SOCKET_IO); } // Check if we received the TSP capabilities. if( memcmp("CAPABILITY ", datain, 11) == 0 ) { // Extract the capabilities. *capability = tspExtractCapability(datain); } else { // Retrieve the TSP status from the reply. tsp_status = tspGetStatusCode(datain); // Check if it is a redirect TSP status. if( tspIsRedirectStatus(tsp_status) ) { if( tspHandleRedirect(datain, conf, broker_list) == TSP_REDIRECT_OK ) { // REDIRECT event. status = make_status(CTX_TSPCAPABILITIES, EVNT_BROKER_REDIRECTION); } else { // Redirect error. status = make_status(CTX_TSPCAPABILITIES, ERR_BROKER_REDIRECTION); } } else { switch( tsp_status ) { case TSP_PROTOCOL_SERVER_TOO_BUSY: // Ze server iz too busy. Display(LOG_LEVEL_1, ELWarning, "tspGetCapabilities", STR_TSP_SERVER_TOO_BUSY); status = make_status(CTX_TSPCAPABILITIES, ERR_TSP_SERVER_TOO_BUSY); break; case TSP_PROTOCOL_UNSUP_TSP_VER: // The status was an invalid TSP version. Display(LOG_LEVEL_1, ELWarning, "tspGetCapabilities", STR_TSP_INVALID_VERSION, TSPProtoVerStr[version_index]); status = make_status(CTX_TSPCAPABILITIES, ERR_INVAL_TSP_VERSION); break; default: // Unknown / unexpected TSP error occurred. Display(LOG_LEVEL_1, ELError, "tspGetCapabilities", STR_TSP_GEN_ERROR, tsp_status, tspGetTspStatusStr(tsp_status)); status = make_status(CTX_TSPCAPABILITIES, ERR_TSP_GENERIC_ERROR); break; } Display(LOG_LEVEL_1, ELError, "tspGetCapabilities", STR_TSP_GETCAPABILITIES_ERROR); } } // Successful operation. return status; } // -------------------------------------------------------------------------- // Formats a comma-separated string containing the capability(ies) in the buffer provided. // Returns the buffer. char* tspFormatCapabilities( char* szBuffer, const size_t bufLen, const tCapability cap ) { static const char* authTab[] = { "Any, ", #ifndef NO_OPENSSL "Passdss-3des-1, ", #endif "Digest MD5, ", "Anonymous, ", "Plain, " }; size_t nWritten = 0; /* AUTH_ANY is explicitly expanded in the following capabilities. */ #ifndef NO_OPENSSL if( (cap & AUTH_PASSDSS_3DES_1) == AUTH_PASSDSS_3DES_1 ) { strncpy( szBuffer + nWritten, authTab[1], bufLen - nWritten ); nWritten += strlen( authTab[1] ); } #endif if( (cap & AUTH_DIGEST_MD5) == AUTH_DIGEST_MD5 ) { strncpy( szBuffer + nWritten, authTab[2], bufLen - nWritten ); nWritten += strlen( authTab[2] ); } if( (cap & AUTH_ANONYMOUS) == AUTH_ANONYMOUS && (cap & AUTH_ANY) != AUTH_ANY ) { // ANY does not include ANONYMOUS strncpy( szBuffer + nWritten, authTab[3], bufLen - nWritten ); nWritten += strlen( authTab[3] ); } if( (cap & AUTH_PLAIN) == AUTH_PLAIN ) { strncpy( szBuffer + nWritten, authTab[4], bufLen - nWritten ); nWritten += strlen( authTab[4] ); } if( nWritten > 2 ) szBuffer[nWritten-2] = '\0'; // Remove the end comma. return szBuffer; } gogoc-1_2-RELEASE/gogoc-tsp/src/tsp/tsp_client.c0100644000000000000000000017100711345305421020123 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: tsp_client.c,v 1.6 2010/03/08 23:41:05 carl Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ #include #include "platform.h" #include "gogoc_status.h" #include "tsp_client.h" #include "net_udp.h" #include "net_rudp.h" #include "net_rudp6.h" #include "net_tcp.h" #include "net_tcp6.h" #include "net.h" #include "config.h" #include "tsp_cap.h" #include "tsp_auth.h" #include "tsp_net.h" #include "xml_tun.h" #include "xml_req.h" #include "tsp_redirect.h" #include "version.h" #include "log.h" #include "hex_strings.h" // The gogoCLIENT Messaging subsystem. #include #include #include #ifdef HACCESS #include "haccess.h" #endif #define CONSEC_RETRY_TO_DOUBLE_WAIT 3 // Consecutive failed connection retries before doubling wait time. #define TSP_VERSION_FALLBACK_DELAY 5 // -------------------------------------------------------------------------- const char *TSPProtoVerStr[] = { CLIENT_VERSION_STRING_2_0_2, CLIENT_VERSION_STRING_2_0_1, CLIENT_VERSION_STRING_2_0_0, CLIENT_VERSION_STRING_1_0_1, NULL }; const char *GOGOCStatusContext[] = { STR_CTX_UNSPECIFIED, STR_CTX_CFGVALIDATION, STR_CTX_NETWORKINIT, STR_CTX_NETWORKCONNECT, STR_CTX_TSPCAPABILITIES, STR_CTX_TSPAUTHENTICATION, STR_CTX_TSPTUNNEGOTIATION, STR_CTX_TUNINTERFACESETUP, STR_CTX_TUNNELLOOP, STR_CTX_GOGOCTEARDOWN, NULL }; struct __TSP_PROTOCOL_CODES_STR { sint32_t status; const char* status_str; } TSP_PROTOCOL_CODES_STR[] = { { TSP_PROTOCOL_SUCCESS, STR_TSP_PROTO_SUCCESS }, { TSP_PROTOCOL_AUTH_FAILED, STR_TSP_PROTO_AUTH_FAILED }, { TSP_PROTOCOL_NO_TUNNELS, STR_TSP_PROTO_NO_TUNNELS }, { TSP_PROTOCOL_UNSUP_TSP_VER, STR_TSP_PROTO_UNSUP_TSP_VER }, { TSP_PROTOCOL_UNSUP_TUN_MODE, STR_TSP_PROTO_UNSUP_TUN_MODE }, { TSP_PROTOCOL_UNDEFINED, STR_TSP_PROTO_UNDEFINED }, { TSP_PROTOCOL_INVALID_REQUEST, STR_TSP_PROTO_INVALID_REQUEST }, { TSP_PROTOCOL_INVALID_IPV4, STR_TSP_PROTO_INVALID_IPV4 }, { TSP_PROTOCOL_INVALID_IPV6, STR_TSP_PROTO_INVALID_IPV6 }, { TSP_PROTOCOL_IPV4_PREFIX_ALREADY_USED, STR_TSP_PROTO_IPV4_PREFIX_ALREADY_USED }, { TSP_PROTOCOL_REQ_PREFIX_LEN_UNAVAILABLE, STR_TSP_PROTO_REQ_PREFIX_LEN_UNAVAILABLE }, { TSP_PROTOCOL_DNS_DELEGATION_ERROR, STR_TSP_PROTO_DNS_DELEGATION_ERROR }, { TSP_PROTOCOL_UNSUPP_PREFIX_LEN, STR_TSP_PROTO_UNSUPP_PREFIX_LEN }, { TSP_PROTOCOL_MISSING_PREFIX_LEN, STR_TSP_PROTO_MISSING_PREFIX_LEN }, { TSP_PROTOCOL_REQ_IN_PROGRESS, STR_TSP_PROTO_REQ_IN_PROGRESS }, { TSP_PROTOCOL_PREFIX_REQ_FOR_ANONYMOUS, STR_TSP_PROTO_PREFIX_REQ_FOR_ANONYMOUS }, { TSP_PROTOCOL_SERVER_TOO_BUSY, STR_TSP_PROTO_SERVER_TOO_BUSY }, { TSP_PROTOCOL_REDIRECT, STR_TSP_PROTO_REDIRECT }, { 0, NULL } }; // -------------------------------------------------------------------------- // Global static variables used throughout program. gogocStatusInfo gStatusInfo; // Declared `extern' in gogoc_c_wrapper.h gogocTunnelInfo gTunnelInfo; // Declared `extern' in gogoc_c_wrapper.h char* gszBrokerListFile = NULL; // Local only. NOT USED HACCESSStatusInfo gHACCESSStatusInfo; // Declared `extern' in gogoc_c_wrapper.h // -------------------------------------------------------------------------- // Local function prototypes: void InitNetToolsArray ( net_tools_t nt_array[] ); sint32_t InitLogSystem ( const tConf* p_config ); void tspLogOSInfo ( void ); char * tspAddPayloadString ( tPayload *, char * ); gogoc_status tspUpdateSourceAddr ( tConf *Conf, pal_socket_t fd ); gogoc_status tspTunnelNegotiation ( pal_socket_t socket, tTunnel *t, tConf *conf, net_tools_t* nt, sint32_t version_index, tBrokerList **broker_list ); gogoc_status tspSetupTunnel ( tConf *, net_tools_t *, sint32_t version_index, tBrokerList **broker_list ); // -------------------------------------------------------------------------- // Call the XML parser. Data will be contained in the structure t. // sint32_t tspExtractPayload(char *Payload, tTunnel *t) { char *p; sint32_t rc; memset(t, 0, sizeof(tTunnel)); Display(LOG_LEVEL_3, ELInfo, "tspExtractPayload", STR_MISC_PROCESS_SERVER_REPLY); if((p = strchr(strchr(Payload, '\n'), '<')) == NULL) return 1; if((rc = tspXMLParse(p, t)) != 0) return 1; return(0); } // -------------------------------------------------------------------------- // tspGetStatusCode: Converts the tsp status found at the beginning of the // payload to a signed integer. If the payload is NULL, 0 is returned. // sint32_t tspGetStatusCode(char *payload) { return (payload!=NULL) ? atoi(payload) : 0; } // -------------------------------------------------------------------------- // tspGetTspStatusStr: // const char* tspGetTspStatusStr( sint32_t tsp_status ) { uint32_t i; for(i=0; TSP_PROTOCOL_CODES_STR[i].status != 0; i++) { if( TSP_PROTOCOL_CODES_STR[i].status == tsp_status ) return TSP_PROTOCOL_CODES_STR[i].status_str; } return NULL; } // -------------------------------------------------------------------------- // tspAddPayloadString: // char *tspAddPayloadString(tPayload *Payload, char *Addition) { char *NewPayload; if(Addition) { if(Payload->PayloadCapacity == 0) { if((NewPayload = Payload->payload = (char *)pal_malloc(PROTOCOLMAXPAYLOADCHUNK)) == NULL) { Display(LOG_LEVEL_1, ELError, "tspAddPayloadString", STR_GEN_MALLOC_ERROR); return NULL; } *Payload->payload = 0; Payload->PayloadCapacity = PROTOCOLMAXPAYLOADCHUNK; } if((Payload->size + (long)pal_strlen(Addition) + 1) > Payload->PayloadCapacity) { Payload->PayloadCapacity += PROTOCOLMAXPAYLOADCHUNK; if((NewPayload = (char *) pal_malloc(Payload->PayloadCapacity)) == NULL) { Display(LOG_LEVEL_1, ELError, "tspAddPayloadString", STR_GEN_MALLOC_ERROR); return NULL; } memcpy(NewPayload, Payload->payload, Payload->size + 1); pal_free(Payload->payload); Payload->payload = NewPayload; } strcat(Payload->payload, Addition); Payload->size += pal_strlen(Addition); } return Payload->payload; } // ----------------------------------------------------------------------- // Function: tspUpdateSourceAddr // // Description: // Retrieves the source IP addres to use for the TSP session. // // Arguments: // pConf: tConf* [OUT], The global configuration object. // // Return Values: // gogoc_status value. // // ----------------------------------------------------------------------- gogoc_status tspUpdateSourceAddr( tConf *pConf, pal_socket_t fd ) { if( pConf->tunnel_mode != V4V6 && pConf->tunnel_mode != DSLITE ) { // tunnel mode v6*v4, we need source IPv4 address if( pConf->client_v4 != NULL && pal_strlen(pConf->client_v4) != 0 ) { if( pal_strcasecmp(pConf->client_v4, "auto") == 0 ) { char addr_str[INET_ADDRSTRLEN+1]; // if current transport is v4, get source address of tsp session. If not, get host address. if (((pConf->transport == NET_TOOLS_T_RUDP) || (pConf->transport == NET_TOOLS_T_TCP)) && (tspGetLocalAddress(fd, addr_str, INET_ADDRSTRLEN) != NULL)) { pConf->client_v4 = pal_strdup(addr_str); Display(LOG_LEVEL_3, ELInfo, "tspUpdateSourceAddr", STR_NET_USING_SOURCE_IPV4, pConf->client_v4); } else { Display(LOG_LEVEL_1, ELError, "tspUpdateSourceAddr", STR_NET_FAILED_FIND_LOCALHOST_IPV4); return make_status(CTX_UNSPECIFIED, ERR_INVAL_CLIENT_ADDR); } } } } #ifdef V4V6_SUPPORT if( pConf->tunnel_mode == V4V6 #ifdef DSLITE_SUPPORT || pConf->tunnel_mode == DSLITE #endif ) { // tunnel mode v4v6, we need source IPv6 address. if( pConf->client_v6 != NULL && pal_strlen(pConf->client_v6) != 0 ) { if( pal_strcasecmp(pConf->client_v6, "auto") == 0 ) { char addr_str[INET6_ADDRSTRLEN+1]; // if current transport is v6, get source address of tsp session. If not, get host address. if (((pConf->transport == NET_TOOLS_T_RUDP6) || (pConf->transport == NET_TOOLS_T_TCP6)) && (tspGetLocalAddress(fd, addr_str, INET6_ADDRSTRLEN) != NULL)) { pConf->client_v6 = pal_strdup(addr_str); Display(LOG_LEVEL_3, ELInfo, "tspUpdateSourceAddr", STR_NET_USING_SOURCE_IPV6, pConf->client_v6); } else { Display(LOG_LEVEL_1, ELError, "tspUpdateSourceAddr", STR_NET_FAILED_FIND_LOCALHOST_IPV6); return make_status(CTX_UNSPECIFIED, ERR_INVAL_CLIENT_ADDR); } } else { // remove brackets if any char addr_str[INET6_ADDRSTRLEN+1]; char *ptr; memset(addr_str, 0, sizeof(addr_str)); strcpy(addr_str, pConf->client_v6); if((ptr = strtok(addr_str, "[")) != NULL) { if((ptr = strtok(ptr, "]")) != NULL) { // copy back address without brackets strcpy(pConf->client_v6, ptr); } } } } } #endif // V4V6_SUPPORT return make_status(CTX_UNSPECIFIED, SUCCESS); } // -------------------------------------------------------------------------- // tspTunnelNegotiation: Builds and sends a tunnel request to the server. // The server will then offer a tunnel. The tunnel settings will be put // in the tunnel structure(t). // gogoc_status tspTunnelNegotiation( pal_socket_t socket, tTunnel *tunnel_info, tConf *conf, net_tools_t* nt, sint32_t version_index, tBrokerList **broker_list ) { tPayload plin; tPayload plout; sint32_t tsp_status; sint32_t ret; memset(&plin, 0, sizeof(plin)); memset(&plout, 0, sizeof(plout)); // Prepare TSP tunnel request. plin.payload = tspAddPayloadString(&plin, tspBuildCreateRequest(conf)); // Prepare receive buffer. plout.size = REDIRECT_RECEIVE_BUFFER_SIZE; plout.payload = (char *)pal_malloc(REDIRECT_RECEIVE_BUFFER_SIZE); if( plout.payload == NULL ) { return make_status(CTX_TSPTUNNEGOTIATION, ERR_MEMORY_STARVATION); } memset(plout.payload, 0, plout.size); // Send TSP tunnel request over to the server. ret = tspSendRecv(socket, &plin, &plout, nt); if(ret <= 0) { pal_free(plout.payload); pal_free(plin.payload); plout.size = plin.size = 0; Display(LOG_LEVEL_1, ELError, "tspTunnelNegotiation", STR_NET_FAIL_RW_SOCKET); return make_status(CTX_TSPTUNNEGOTIATION, ERR_SOCKET_IO); } // Process tunnel reply from server. tsp_status = tspGetStatusCode(plout.payload); if( tspIsRedirectStatus(tsp_status) ) { if( tspHandleRedirect(plout.payload, conf, broker_list) == TSP_REDIRECT_OK ) { pal_free(plout.payload); pal_free(plin.payload); plout.size = plin.size = 0; return make_status(CTX_TSPTUNNEGOTIATION, EVNT_BROKER_REDIRECTION); } else { pal_free(plout.payload); pal_free(plin.payload); plout.size = plin.size = 0; return make_status(CTX_TSPTUNNEGOTIATION, ERR_BROKER_REDIRECTION); } } else if( tsp_status != TSP_PROTOCOL_SUCCESS ) { Display(LOG_LEVEL_1, ELError, "tspTunnelNegotiation", STR_TSP_GEN_ERROR, tsp_status, tspGetTspStatusStr(tsp_status) ); return make_status(CTX_TSPTUNNEGOTIATION, ERR_TSP_GENERIC_ERROR); } // Extract the tunnel information from the XML payload. tspExtractPayload(plout.payload, tunnel_info); // free some memory pal_free(plout.payload); pal_free(plin.payload); plout.size = plin.size = 0; // Version 1.0.1 requires that we immediatly jump in tunnel mode. // No need to acknowledge the tunnel offered by server. if( version_index == CLIENT_VERSION_INDEX_1_0_1 ) { // Successful operation. return make_status(CTX_TSPTUNNEGOTIATION, SUCCESS); } // Acknowledge TSP tunnel offer to server. memset(&plin, 0, sizeof(plin)); plin.payload = tspAddPayloadString(&plin, tspBuildCreateAcknowledge()); if( tspSend(socket, &plin, nt) == -1 ) { Display(LOG_LEVEL_1, ELError, "tspTunnelNegotiation", STR_NET_FAIL_W_SOCKET); return make_status(CTX_TSPTUNNEGOTIATION, ERR_SOCKET_IO); } // Free the last of the memory pal_free(plin.payload); plin.size=0; // Successful operation. return make_status(CTX_TSPTUNNEGOTIATION, SUCCESS); } // -------------------------------------------------------------------------- // Attempts to negotiate and setup a tunnel with the broker. // gogoc_status tspSetupTunnel(tConf *conf, net_tools_t* nt, sint32_t version_index, tBrokerList **broker_list) { pal_socket_t socket; tCapability cap; tTunnel tunnel_params; gogoc_status status = STATUS_SUCCESS_INIT; // Print the transport protocol we're using to perform the TSP session. switch( conf->transport ) { case NET_TOOLS_T_TCP: Display( LOG_LEVEL_2, ELInfo, "tspSetupTunnel", STR_NET_CONNECT_TCP, conf->server); break; case NET_TOOLS_T_RUDP: Display( LOG_LEVEL_2, ELInfo, "tspSetupTunnel", STR_NET_CONNECT_RUDP, conf->server); break; case NET_TOOLS_T_TCP6: Display( LOG_LEVEL_2, ELInfo, "tspSetupTunnel", STR_NET_CONNECT_TCPV6, conf->server); break; case NET_TOOLS_T_RUDP6: Display( LOG_LEVEL_2, ELInfo, "tspSetupTunnel", STR_NET_CONNECT_RUDPV6, conf->server); break; } // ----------------------------------------------------------- // Send(update) connectivity status to GUI. // ----------------------------------------------------------- gStatusInfo.eStatus = GOGOC_CLISTAT__CONNECTING; gStatusInfo.nStatus = GOGOCM_UIS__NOERROR; send_status_info(); // ---------------------------------------------------------------------- // Perform connection to the server using a specific transport protocol. // ---------------------------------------------------------------------- { char *srvname; // Parse the server name and server port from 'conf->server'. if( parse_addr_port( conf->server, &srvname, &conf->port_remote_v4, SERVER_PORT ) != 0 ) { // Bad server name, or bad port. return make_status(CTX_NETWORKCONNECT, ERR_INVAL_GOGOC_ADDRESS); } // Create socket and connect. status = tspConnect( &socket, srvname, conf->port_remote_v4, nt ); if( status_number(status) != SUCCESS ) { Display(LOG_LEVEL_1, ELError, "tspSetupTunnel", STR_NET_FAIL_CONNECT_SERVER, srvname, conf->port_remote_v4); pal_free( srvname ); return status; } pal_free( srvname ); } if( conf->transport == NET_TOOLS_T_TCP || conf->transport == NET_TOOLS_T_TCP6 ) { // Only display the 'Connected' message when we're using TCP or TCPv6. // Because it would be misleading to say we're connected when we're using RUDP/RUDPv6. Display(LOG_LEVEL_2, ELInfo, "tspSetupTunnel", STR_GEN_CONNECTED_SERVER, conf->server); } Display( LOG_LEVEL_3, ELInfo, "tspSetupTunnel", STR_GEN_USING_TSP_PROTO_VER, TSPProtoVerStr[version_index]); #ifdef DSLITE_SUPPORT if (conf->tunnel_mode != DSLITE) { #endif // -------------------------------------------- // Get the TSP capabilities from the server. // -------------------------------------------- Display(LOG_LEVEL_3, ELInfo, "tspSetupTunnel", STR_TSP_GETCAPABILITIES_FROM_SERVER); status = tspGetCapabilities(socket, nt, &cap, version_index, conf, broker_list); switch( status_number(status) ) { case SUCCESS: break; case EVNT_BROKER_REDIRECTION: // The redirection event is processed in the main loop. tspClose( socket, nt ); return status; case ERR_SOCKET_IO: // If the transport is RUDP or RUDPv6, in means we failed to reach a TSP listener. // Else, if the transport is TCP or TCPv6, then it's a socket IO error (because we're connected). if( conf->transport == NET_TOOLS_T_RUDP || conf->transport == NET_TOOLS_T_RUDP6 ) { Display(LOG_LEVEL_1, ELError, "tspSetupTunnel", STR_TSP_NO_LISTENER, conf->server); status = make_status(status_context(status), ERR_FAIL_SOCKET_CONNECT); } else Display(LOG_LEVEL_1, ELError, "tspSetupTunnel", STR_NET_FAIL_RW_SOCKET); // *** FALLTHROUGH *** default: tspClose( socket, nt ); return status; } // Verify if the requested tunnel mode is offered on the server. if( (conf->tunnel_mode & cap) == 0 ) { // Error: Tunnel mode not supported on server. Display(LOG_LEVEL_1, ELError, "tspSetupTunnel", STR_TSP_TUNMODE_NOT_AVAILABLE, conf->server); tspClose( socket, nt ); return make_status(CTX_TSPCAPABILITIES, ERR_TUNMODE_NOT_AVAILABLE); } // -------------------------------------------- // Perform TSP authentication on the server. // -------------------------------------------- Display(LOG_LEVEL_3, ELInfo, "tspSetupTunnel", STR_TSP_AUTHENTICATING); status = tspAuthenticate(socket, cap, nt, conf, broker_list, version_index); switch( status_number(status) ) { case SUCCESS: break; case EVNT_BROKER_REDIRECTION: // The redirection event is processed in the main loop. tspClose( socket, nt ); return status; default: // An error occurred. The error has already been logged. tspClose( socket, nt ); return status; } Display(LOG_LEVEL_2, ELInfo, "tspSetupTunnel", STR_TSP_AUTH_SUCCESSFUL); // ------------------------------------------------------------------- // Get the source address to use for local tunnel endpoint. // If it was set to 'auto', the source address of the socket is used. // ------------------------------------------------------------------- status = tspUpdateSourceAddr(conf, socket); if( status_number(status) != SUCCESS ) { Display(LOG_LEVEL_1, ELError, "tspSetupTunnel", STR_NET_CANT_GET_SRC_ADDRESS); tspClose( socket, nt ); return status; } // ---------------------------------------------------------------- // Build and send TSP tunnel request. Then, get tunnel parameters. // ---------------------------------------------------------------- Display(LOG_LEVEL_3, ELInfo, "tspSetupTunnel", STR_TSP_NEGOTIATING_TUNNEL); status = tspTunnelNegotiation( socket, &tunnel_params, conf, nt, version_index, broker_list ); switch( status_number(status) ) { case SUCCESS: break; case EVNT_BROKER_REDIRECTION: // The redirection event is processed in the main loop. tspClose( socket, nt ); return status; default: Display(LOG_LEVEL_1, ELError, "tspSetupTunnel", STR_TSP_TUNNEL_NEGO_FAILED, status); tspClose( socket, nt ); return status; } Display(LOG_LEVEL_2, ELInfo, "tspSetupTunnel", STR_TSP_TUNNEL_NEGO_SUCCESSFUL); #ifdef DSLITE_SUPPORT } else { memset(&tunnel_params, 0, sizeof(tunnel_params)); tunnel_params.type = pal_strdup(STR_CONFIG_TUNNELMODE_V4V6); tunnel_params.lifetime = pal_strdup("0"); tunnel_params.keepalive_interval = pal_strdup("0"); status = tspUpdateSourceAddr(conf, socket); if( status_number(status) != SUCCESS ) { Display(LOG_LEVEL_1, ELError, "tspSetupTunnel", STR_NET_CANT_GET_SRC_ADDRESS); tspClose( socket, nt ); return status; } { char addr_str[INET6_ADDRSTRLEN+1]; // if current transport is v6, get source address of tsp session. If not, get host address. if (tspGetRemoteAddress(socket, addr_str, INET6_ADDRSTRLEN) == NULL) { Display(LOG_LEVEL_1, ELError, "tspSetupTunnel", STR_NET_CANT_GET_DST_ADDRESS); tspClose( socket, nt ); return make_status(CTX_UNSPECIFIED, ERR_INVAL_GOGOC_ADDRESS); } tunnel_params.server_address_ipv6 = pal_strdup(addr_str); } tunnel_params.client_address_ipv6 = pal_strdup(conf->client_v6); tunnel_params.server_address_ipv4 = pal_strdup(conf->dslite_server); tunnel_params.client_address_ipv4 = pal_strdup(conf->dslite_client); } #endif // ------------------------------------------------------------------- // Save the current server address to the last-tsp-server.txt file. // ------------------------------------------------------------------- if( tspWriteLastServerToFile(conf->last_server_file, conf->server) != TSP_REDIRECT_OK ) { Display(LOG_LEVEL_1, ELError, "tspSetupTunnel", STR_MISC_FAIL_WRITE_LAST_SERVER, conf->server, conf->last_server_file); } // ------------------------------------------------------- // Run tunnel script and maintain keepalive (if enabled). // ------------------------------------------------------- status = tspStartLocal(socket, conf, &tunnel_params, nt); // ------------------------------------------- // Clear tunnel information and close socket. // ------------------------------------------- pal_free( gTunnelInfo.szDelegatedPrefix ); memset( &gTunnelInfo, 0x00, sizeof(struct __TUNNEL_INFO) ); tspClearTunnelInfo( &tunnel_params ); tspClose(socket, nt); return status; } // -------------------------------------------------------------------------- // Function : RetrieveStatusInfo // // Description: // Will set the status info in ppStatusInfo. // // Arguments: // ppStatusInfo: gogocStatusInfo** [IN,OUT], The status info. // // Return values: // GOGOCM_UIS__NOERROR: Successfully retrieved status info and populated the // Status Info object. // // -------------------------------------------------------------------------- error_t RetrieveStatusInfo( gogocStatusInfo** ppStatusInfo ) { assert( *ppStatusInfo == NULL ); // No allocation is made, really, we're just assigning the global variable. *ppStatusInfo = &gStatusInfo; return GOGOCM_UIS__NOERROR; } // -------------------------------------------------------------------------- // Function : RetrieveTunnelInfo // // Description: // Will set the tunnel info in ppTunnelInfo. // // Arguments: // ppTunnelInfo: gogocTunnelInfo** [IN,OUT], The tunnel info. // // Return values: // GOGOCM_UIS__NOERROR: Successfully retrieved tunnel info and populated the // Tunnel Info object. // // -------------------------------------------------------------------------- error_t RetrieveTunnelInfo( gogocTunnelInfo** ppTunnelInfo ) { assert( *ppTunnelInfo == NULL ); // No allocation is made, really, we're just assigning the global variable. *ppTunnelInfo = &gTunnelInfo; return GOGOCM_UIS__NOERROR; } // -------------------------------------------------------------------------- // Function : RetrieveBrokerList // // Description: // Will set the broker list in ppBrokerList. // // Arguments: // ppBrokerList: gogocBrokerList** [IN,OUT], The tunnel info. // // Return values: // GOGOCM_UIS__NOERROR: Successfully retrieved broker list and populated the // Broker List object. // GOGOCM_UIS_FAILEDBROKERLISTEXTRACTION: Failed broker list extraction. // // -------------------------------------------------------------------------- error_t RetrieveBrokerList( gogocBrokerList** ppBrokerList ) { tBrokerList* tspBrokerList = NULL;// Local format of broker list gogocBrokerList* pList; // Intermediate var assert( *ppBrokerList == NULL ); // Allocation is made here. // Read broker list from file. // if( gszBrokerListFile != NULL && tspReadBrokerListFromFile( gszBrokerListFile, &tspBrokerList ) != TSP_REDIRECT_OK ) { // Failed to extract broker list. return GOGOCM_UIS_FAILEDBROKERLISTEXTRACTION; } // Convert contents. if( tspBrokerList != NULL ) { *ppBrokerList = pList = (gogocBrokerList*)pal_malloc( sizeof(gogocBrokerList) ); // Copy the contents of the broker list struct to the // messaging subsystem broker list format. // while( tspBrokerList != NULL ) { pList->szAddress = pal_strdup(tspBrokerList->address); pList->nDistance = tspBrokerList->distance; if( (tspBrokerList = tspBrokerList->next) != NULL ) pList = (pList->next = (gogocBrokerList*)pal_malloc( sizeof(gogocBrokerList) )); else pList->next = NULL; } } return GOGOCM_UIS__NOERROR; } // -------------------------------------------------------------------------- // Function : RetrieveHACCESSStatusInfo // // Description: // Will set the global HACCESS Status Info object in ppHACCESSStatusInfo. // // Arguments: // ppHACCESSStatusInfo: HACCESSStatusInfo** [IN,OUT], The HACCESS Status info // returned to the GUI. // // Return values: // GOGOCM_UIS__NOERROR: Successfully retrieved the HACCESS status info. // // -------------------------------------------------------------------------- error_t RetrieveHACCESSStatusInfo( HACCESSStatusInfo** ppHACCESSStatusInfo ) { #ifdef HACCESS HACCESSStatusInfo *haccess_status_info_copy = NULL; haccess_status status = HACCESS_STATUS_OK; haccess_status_info_copy = (HACCESSStatusInfo *)pal_malloc(sizeof(HACCESSStatusInfo)); if (haccess_status_info_copy == NULL) { return GOGOCM_UIS_ERRMEMORYSTARVATION; } // Ask the HACCESS module for a copy of the current status information. status = haccess_messaging_get_status_info(&haccess_status_info_copy); if (status != HACCESS_STATUS_OK) { FreeHACCESSStatusInfo(&haccess_status_info_copy); return GOGOCM_UIS_ERRUNKNOWN; } *ppHACCESSStatusInfo = haccess_status_info_copy; return GOGOCM_UIS__NOERROR; #else // Not supposed to happen if HACCESS is not enabled return GOGOCM_UIS_ERRUNKNOWN; #endif } // -------------------------------------------------------------------------- void FreeStatusInfo( gogocStatusInfo** ppStatusInfo ) { if( *ppStatusInfo != NULL ) { // Nothing is really freed, because we're using the global variable. *ppStatusInfo = NULL; } } // -------------------------------------------------------------------------- void FreeTunnelInfo( gogocTunnelInfo** ppTunnelInfo ) { if( *ppTunnelInfo != NULL ) { // Nothing is really freed, because we're using the global variable. *ppTunnelInfo = NULL; } } // -------------------------------------------------------------------------- void FreeBrokerList( gogocBrokerList** ppBrokerList ) { gogocBrokerList* pList = *ppBrokerList; while( *ppBrokerList != NULL ) { pList = *ppBrokerList; // Keep reference for free() pal_free( pList->szAddress ); *ppBrokerList = pList->next; pal_free( pList ); } } // -------------------------------------------------------------------------- void FreeHACCESSStatusInfo( HACCESSStatusInfo** ppHACCESSStatusInfo ) { PMAPPING_STATUS pList = (*ppHACCESSStatusInfo)->haccess_devmap_statuses; while ( (*ppHACCESSStatusInfo)->haccess_devmap_statuses != NULL) { pList = (*ppHACCESSStatusInfo)->haccess_devmap_statuses; pal_free( pList->device_name ); (*ppHACCESSStatusInfo)->haccess_devmap_statuses = pList->next; pal_free( pList ); } pal_free(*ppHACCESSStatusInfo); *ppHACCESSStatusInfo = NULL; } // -------------------------------------------------------------------------- // Function : NotifyhaccessConfigInfo // // Description: // CALLBACK function from the Messaging Subsystem upon reception of a // HACCESS Config Info message. // // Arguments: // aHACCESSConfigInfo: HACCESSConfigInfo* [IN], The HACCESS Config Info from the GUI. // // Return values: // GOGOCM_UIS__NOERROR: Successfully processed the HACCESS Config info. // // -------------------------------------------------------------------------- error_t NotifyhaccessConfigInfo( const HACCESSConfigInfo* aHACCESSConfigInfo ) { return GOGOCM_UIS__NOERROR; } // -------------------------------------------------------------------------- // Function: FormatBrokerListAddr // // Description: Copies a tBrokerList element address to a destination // address. If the address is IPv6, a set of brackets are put // at the beginning and end. // i.e.: // 1.2.3.4 stays the same // broker.domain.com stays the same // 2001:BABA::0045 becomes [2001:BABA::0045] // // Arguments: // listElement: An element of the broker redirection list. // ppAddr: A pointer to a char array. // // Returns 0 on success, 1 on error. // int FormatBrokerListAddr( tBrokerList* listElement, char **ppAddr ) { if( ppAddr == NULL ) { // Invalid pointer. Display(LOG_LEVEL_1, ELError, "FormatBrokerListAddr", STR_GEN_INVALID_POINTER); return 1; } // Check if there's stuff pointed by ppAddr. Free it if so. if( *ppAddr != NULL ) { pal_free( *ppAddr ); *ppAddr = NULL; } // Copy address. if( listElement->address_type == TSP_REDIRECT_BROKER_TYPE_IPV6 ) { size_t len = pal_strlen(listElement->address) + 3; // Must put address between brackets ([]). *ppAddr = (char*)pal_malloc( len ); if( *ppAddr == NULL ) { // Memory allocation error Display(LOG_LEVEL_1, ELError, "FormatBrokerListAddr", STR_GEN_MALLOC_ERROR); return 1; } pal_snprintf( *ppAddr, len, "[%s]", listElement->address ); } else { // Not an IPv6 address, just strdup' it. *ppAddr = pal_strdup(listElement->address); } return 0; } // -------------------------------------------------------------------------- // gogoCLIENT TSP main entry point. // Called from every platform main() or service_main(). // sint32_t tspMain(sint32_t argc, char *argv[]) { tConf c; sint32_t log_display_ok = 0; // Don't use 'Display()'. tBrokerList *broker_list = NULL; sint32_t trying_original_server = 0; sint32_t read_last_server = 0; char original_server[MAX_REDIRECT_ADDRESS_LENGTH]; char last_server[MAX_REDIRECT_ADDRESS_LENGTH]; tRedirectStatus last_server_status = TSP_REDIRECT_OK; gogoc_status status; sint32_t loop_delay; // Initialize status info. gStatusInfo.eStatus = GOGOC_CLISTAT__DISCONNECTEDIDLE; gStatusInfo.nStatus = GOGOCM_UIS__NOERROR; // ------------------------------------------------------------------------ // Zero-memory the configuration object, because tspInitialize requires // it initialized. Then call the tspInitialize function. // ------------------------------------------------------------------------ memset( &c, 0, sizeof(c) ); status = tspInitialize(argc, argv, &c); if( status_number(status) != SUCCESS ) { gStatusInfo.nStatus = GOGOCM_UIS_ERRCFGDATA; goto endtspc; } // Initialize the logging system. if( InitLogSystem( &c ) != 0 ) { // Failed to allocate memory for the log configuration, or an error // happened. status = make_status(CTX_CFGVALIDATION, ERR_FAIL_LOG_INIT); gStatusInfo.nStatus = GOGOCM_UIS_ERRCFGDATA; goto endtspc; } log_display_ok = 1; // Log the OS information through the log system. tspLogOSInfo(); // Keep track of the broker list. gszBrokerListFile = c.broker_list_file; // For BROKER_LIST gogocmessaging message. // Save the original server value. strcpy(original_server, c.server); // If always_use_same_server is enabled. if( (c.always_use_same_server == TRUE) && (pal_strlen(c.last_server_file) > 0) ) { // Try to get the last server from the last_server file. last_server_status = tspReadLastServerFromFile(c.last_server_file, last_server); switch( last_server_status ) { case TSP_REDIRECT_OK: // Replace the configuration file's server value with the last server. pal_free(c.server); c.server = pal_strdup(last_server); // We found the last server. read_last_server = 1; // We're not trying the original server. trying_original_server = 0; Display(LOG_LEVEL_2, ELInfo, "tspMain", GOGO_STR_RDR_TRYING_LAST_SERVER, last_server); break; case TSP_REDIRECT_NO_LAST_SERVER: // Try the original server instead. trying_original_server = 1; Display(LOG_LEVEL_2, ELInfo, "tspMain", GOGO_STR_RDR_NO_LAST_SERVER_FOUND, c.last_server_file, original_server); break; case TSP_REDIRECT_CANT_OPEN_FILE: // Try the original server instead. trying_original_server = 1; Display(LOG_LEVEL_2, ELInfo, "tspMain", GOGO_STR_RDR_CANT_OPEN_LAST_SERVER, c.last_server_file, original_server); break; default: Display(LOG_LEVEL_1, ELError, "tspMain", GOGO_STR_RDR_ERROR_READING_LAST_SERVER, c.last_server_file); status = make_status(CTX_CFGVALIDATION, ERR_FAIL_LAST_SERVER); gStatusInfo.nStatus = GOGOCM_UIS_ERRBROKERREDIRECTION; goto endtspc; } } else { // If always_use_same_server is disabled, try the original server. trying_original_server = 1; } loop_delay = c.retry_delay; do { net_tools_t nt[NET_TOOLS_T_SIZE]; sint32_t version_index = CLIENT_VERSION_INDEX_CURRENT; sint32_t connected = 1; // try servers as long as connected is true */ sint32_t cycle = 0; // reconnect and fallback cycle */ sint32_t tsp_version_fallback = 0; // true if the TSP protocol version needs to fall back for the next retry */ sint32_t quick_cycle = 0; tBrokerList *current_broker_in_list = NULL; sint32_t trying_broker_list = 0; tRedirectStatus broker_list_status = TSP_REDIRECT_OK; uint16_t effective_retry_delay; uint8_t consec_retry = 0; // Initialize the net tools array. memset( nt, 0, sizeof(nt) ); InitNetToolsArray( nt ); // ------------------------------------------------------------------------ // Connection loop. // Perform loop until we give up (i.e.: an error is indicated), or user // requested a stop in the service (HUP signal or service stop). // while( connected ) { if (tspCheckForStopOrWait(0) != 0) goto endtspc; // While we loop in this while(), keep everything updated on our status. // if( gStatusInfo.eStatus != GOGOC_CLISTAT__DISCONNECTEDIDLE && gStatusInfo.nStatus != GOGOCM_UIS__NOERROR ) { // Status has been changed. send_status_info(); } // Choose the transport or cycle thru the list switch( c.tunnel_mode ) { case V6UDPV4: switch( cycle ) { default: cycle = 0; // Catch an overflow of the variable. // *** FALLTHROUGH *** case 0: if( tsp_version_fallback ) { if( version_index < CLIENT_VERSION_INDEX_V6UDPV4_START && version_index < CLIENT_VERSION_INDEX_OLDEST ) { version_index++; } else { connected = 0; continue; } tsp_version_fallback = 0; } else { version_index = CLIENT_VERSION_INDEX_CURRENT; } c.transport = NET_TOOLS_T_RUDP; break; } break; case V6ANYV4: case V6V4: switch( cycle ) { default: cycle = 0; // Catch an overflow of the variable. // *** FALLTHROUGH *** case 0: if( tsp_version_fallback ) { if( version_index < CLIENT_VERSION_INDEX_OLDEST ) { version_index++; } else { connected = 0; continue; } tsp_version_fallback = 0; } else { version_index = CLIENT_VERSION_INDEX_CURRENT; } c.transport = NET_TOOLS_T_RUDP; break; case 1: if( tsp_version_fallback ) { if( version_index < CLIENT_VERSION_INDEX_OLDEST ) { version_index++; } else { connected = 0; continue; } tsp_version_fallback = 0; } else { version_index = CLIENT_VERSION_INDEX_CURRENT; } c.transport = NET_TOOLS_T_TCP; break; } break; case V4V6: #ifdef V4V6_SUPPORT #ifdef DSLITE_SUPPORT case DSLITE: #endif switch( cycle ) { default: cycle = 0; // Catch an overflow of the variable. // *** FALLTHROUGH *** case 0: if( tsp_version_fallback ) { if( version_index < CLIENT_VERSION_INDEX_V4V6_START && version_index < CLIENT_VERSION_INDEX_OLDEST ) { version_index++; } else { connected = 0; continue; } tsp_version_fallback = 0; } else { version_index = CLIENT_VERSION_INDEX_CURRENT; } c.transport = NET_TOOLS_T_RUDP6; break; case 1: if( tsp_version_fallback ) { if( version_index < CLIENT_VERSION_INDEX_V4V6_START && version_index < CLIENT_VERSION_INDEX_OLDEST ) { version_index++; } else { connected = 0; continue; } tsp_version_fallback = 0; } else { version_index = CLIENT_VERSION_INDEX_CURRENT; } #ifdef DSLITE_SUPPORT c.transport = c.tunnel_mode == DSLITE ? NET_TOOLS_T_RUDP6 : NET_TOOLS_T_TCP6; #else c.transport = NET_TOOLS_T_TCP6; #endif break; } #endif break; } // switch(c.tunnel_mode) // Determine if we need to sleep between connection attempts. quick_cycle = 0; if( ( (c.tunnel_mode == V6ANYV4) || (c.tunnel_mode == V6V4) ) && (c.transport == NET_TOOLS_T_RUDP) ) { quick_cycle = 1; } #ifdef V4V6_SUPPORT if( (c.tunnel_mode == V4V6) && (c.transport == NET_TOOLS_T_RUDP6) ) { quick_cycle = 1; } #endif #ifdef DSLITE_SUPPORT if( (c.tunnel_mode == DSLITE) && (c.transport == NET_TOOLS_T_RUDP6) ) { quick_cycle = 1; } #endif // ----------------------------------------------- // *** Attempt to negotiate tunnel with broker *** // ----------------------------------------------- status = tspSetupTunnel(&c, &nt[c.transport], version_index, &broker_list); switch( status_number(status) ) { case SUCCESS: // If we are here with no error, we can assume we are finished. { gStatusInfo.eStatus = GOGOC_CLISTAT__DISCONNECTEDIDLE; gStatusInfo.nStatus = GOGOCM_UIS__NOERROR; connected = 0; continue; } break; case ERR_KEEPALIVE_TIMEOUT: // A keepalive timeout has occurred. { Display(LOG_LEVEL_1, ELError, "tspMain", STR_KA_GENERAL_TIMEOUT); gStatusInfo.eStatus = GOGOC_CLISTAT__DISCONNECTEDERROR; gStatusInfo.nStatus = GOGOCM_UIS_ERRKEEPALIVETIMEOUT; consec_retry = 0; if( c.auto_retry_connect == FALSE ) { gStatusInfo.eStatus = GOGOC_CLISTAT__DISCONNECTEDNORETRY; connected = 0; continue; } } break; case ERR_AUTHENTICATION_FAILURE: // There's nothing more to do if the authentication has failed. // The user needs to change its username/password. Abort. { gStatusInfo.eStatus = GOGOC_CLISTAT__DISCONNECTEDERROR; gStatusInfo.nStatus = GOGOCM_UIS_ERRAUTHENTICATIONFAILURE; connected = 0; continue; } break; case ERR_NO_COMMON_AUTHENTICATION: // Configured authentication method is not supported by server. // User needs to change configuration. Abort. { gStatusInfo.eStatus = GOGOC_CLISTAT__DISCONNECTEDERROR; gStatusInfo.nStatus = GOGOCM_UIS_ERRNOCOMMONAUTHENTICATION; connected = 0; continue; } break; case ERR_INTERFACE_SETUP_FAILED: // The tunnel interface configuration script failed. Abort. { gStatusInfo.eStatus = GOGOC_CLISTAT__DISCONNECTEDERROR; gStatusInfo.nStatus = GOGOCM_UIS_ERRINTERFACESETUPFAILED; connected = 0; continue; } break; case ERR_TUN_LEASE_EXPIRED: // The tunnel lease has expired. Reconnect. { gStatusInfo.eStatus = GOGOC_CLISTAT__DISCONNECTEDIDLE; gStatusInfo.nStatus = GOGOCM_UIS_ERRTUNLEASEEXPIRED; Display(LOG_LEVEL_1, ELWarning, "tspMain", STR_TSP_TUNNEL_LEASE_EXPIRED); continue; } case ERR_INVAL_TSP_VERSION: // Invalid TSP version used. Will change version on next connect. { gStatusInfo.eStatus = GOGOC_CLISTAT__DISCONNECTEDERROR; gStatusInfo.nStatus = GOGOCM_UIS_ERRTSPVERSIONERROR; tsp_version_fallback = 1; if( version_index == CLIENT_VERSION_INDEX_2_0_0 ) { cycle = 1; } // Wait a little to prevent the TSP version fallback problem with UDP // connections that have the same source port. See Bugzilla bug #3539 if ((version_index != CLIENT_VERSION_INDEX_2_0_0) && (c.transport == NET_TOOLS_T_RUDP #ifdef V4V6_SUPPORT || c.transport == NET_TOOLS_T_RUDP6 #endif )) { pal_sleep(TSP_VERSION_FALLBACK_DELAY); } Display (LOG_LEVEL_1, ELInfo, "tspMain", STR_GEN_DISCONNECTED_RETRY_NOW); continue; } break; case ERR_SOCKET_IO: // Socket error. Reconnect, don't change transport. { gStatusInfo.eStatus = GOGOC_CLISTAT__DISCONNECTEDERROR; gStatusInfo.nStatus = GOGOCM_UIS_ERRSOCKETIO; consec_retry = 0; if( quick_cycle != 0 ) { Display(LOG_LEVEL_1, ELInfo, "tspMain", STR_GEN_DISCONNECTED_RETRY_NOW); continue; } } break; case ERR_TSP_SERVER_TOO_BUSY: // The server is currently too busy to process the TSP request. { gStatusInfo.eStatus = GOGOC_CLISTAT__DISCONNECTEDERROR; gStatusInfo.nStatus = GOGOCM_UIS_ERRTSPSERVERTOOBUSY; // Force a wait. effective_retry_delay = c.retry_delay; consec_retry = 1; } break; case ERR_TSP_GENERIC_ERROR: // Unexpected TSP status in TSP session. Abort. { gStatusInfo.eStatus = GOGOC_CLISTAT__DISCONNECTEDERROR; gStatusInfo.nStatus = GOGOCM_UIS_ERRTSPGENERICERROR; connected = 0; continue; } break; case ERR_FAIL_SOCKET_CONNECT: // This means we could not connect to a server. // We'll try a different transport to the same server. // If that fails too, we'll go through the broker list (if any). { // Don't retry to avoid blocking the boot if (c.boot_mode) { connected = 0; continue; } if( quick_cycle == 1 ) { // We haven't tried all transports for this broker, there are more to try. cycle++; Display(LOG_LEVEL_1, ELInfo, "tspMain", STR_GEN_DISCONNECTED_RETRY_NOW); continue; } // If we have the last server, we always need to connect to this one. if( read_last_server == 1 ) { // Just cycle transports, try again with the last server. cycle++; break; } // Do the following only if we have tried all transports(and failed to connect) effective_retry_delay = c.retry_delay; consec_retry = 1; // Status update. gStatusInfo.eStatus = GOGOC_CLISTAT__DISCONNECTEDERROR; gStatusInfo.nStatus = GOGOCM_UIS_ERRFAILSOCKETCONNECT; // If we're trying to connect to the original server. if( trying_original_server == 1 ) { // Clear the broker list. tspFreeBrokerList(broker_list); broker_list = NULL; // If a broker_list file is specified, try to create the list if( pal_strlen(c.broker_list_file) > 0 ) { Display (LOG_LEVEL_2, ELInfo, "tspMain", GOGO_STR_RDR_READING_BROKER_LIST, c.broker_list_file); broker_list_status = tspReadBrokerListFromFile(c.broker_list_file, &broker_list); switch( broker_list_status ) { case TSP_REDIRECT_OK: // If the broker list is empty. if( broker_list == NULL ) { Display (LOG_LEVEL_2, ELInfo, "tspMain", GOGO_STR_RDR_READ_BROKER_LIST_EMPTY); // Just cycle transports, we'll try the original server again. cycle++; } // If the broker list is not empty. else { Display (LOG_LEVEL_2, ELInfo, "tspMain", GOGO_STR_RDR_READ_BROKER_LIST_CREATED); tspLogRedirectionList(broker_list, 0); // We're going through a broker list. trying_broker_list = 1; // We're not trying the original server anymore. trying_original_server = 0; // Start with the first broker in the list. current_broker_in_list = broker_list; // Copy the brokerList address to configuration server. if( FormatBrokerListAddr( current_broker_in_list, &(c.server) ) != 0 ) { tspFreeBrokerList(broker_list); broker_list = NULL; status = make_status( status_context(status), ERR_BROKER_REDIRECTION ); gStatusInfo.nStatus = GOGOCM_UIS_ERRBROKERREDIRECTION; connected = 0; goto endtspc; } // Adjust the transport cycle to start from the first one. cycle = 0; // Try the first broker in the list right now. continue; } break; case TSP_REDIRECT_CANT_OPEN_FILE: // If we can't open the file, maybe it's just not there. // This is normal if it hasn't been created. Display (LOG_LEVEL_2, ELInfo, "tspMain", GOGO_STR_RDR_CANT_OPEN_BROKER_LIST, c.broker_list_file); cycle++; tspFreeBrokerList(broker_list); broker_list = NULL; break; case TSP_REDIRECT_TOO_MANY_BROKERS: // If there were more brokers in the list than the allowed limit. Display (LOG_LEVEL_1, ELError, "tspMain", GOGO_STR_RDR_TOO_MANY_BROKERS, MAX_REDIRECT_BROKERS_IN_LIST); cycle++; tspFreeBrokerList(broker_list); broker_list = NULL; break; default: // There was a problem creating the list from the broker_list file Display (LOG_LEVEL_1, ELError, "tspMain", GOGO_STR_RDR_ERROR_READING_BROKER_LIST, c.broker_list_file); cycle++; tspFreeBrokerList(broker_list); broker_list = NULL; break; } } else { // Nothing specified in broker_list. Cycle transports, but // try same server again. cycle++; } } // If we're not trying to connect to the original server. // and we're going through a broker list. else if( trying_broker_list == 1 ) { // If the pointers aren't safe. if( (broker_list == NULL) || (current_broker_in_list == NULL) ) { Display(LOG_LEVEL_1, ELError, "tspMain", GOGO_STR_RDR_BROKER_LIST_INTERNAL_ERROR, current_broker_in_list->address); gStatusInfo.nStatus = GOGOCM_UIS_ERRBROKERREDIRECTION; status = make_status( status_context(status), ERR_BROKER_REDIRECTION ); tspFreeBrokerList(broker_list); broker_list = NULL; connected = 0; continue; } // If this is the last broker in the list. if( current_broker_in_list->next == NULL ) { Display (LOG_LEVEL_2, ELInfo, "tspMain", GOGO_STR_RDR_BROKER_LIST_END); // Prepare to retry the original server after the retry delay. pal_free(c.server); c.server = pal_strdup(original_server); cycle = 0; trying_original_server = 1; break; } // Prepare to try the next broker in the list. current_broker_in_list = current_broker_in_list->next; // Copy the brokerList address to configuration server. if( FormatBrokerListAddr( current_broker_in_list, &(c.server) ) != 0 ) { tspFreeBrokerList(broker_list); broker_list = NULL; status = make_status( status_context(status), ERR_BROKER_REDIRECTION ); gStatusInfo.nStatus = GOGOCM_UIS_ERRBROKERREDIRECTION; connected = 0; goto endtspc; } Display(LOG_LEVEL_2, ELInfo, "tspMain", GOGO_STR_RDR_NEXT_IN_BROKER_LIST, current_broker_in_list->address); // Try the next broker now, don't wait for the retry delay. cycle = 0; continue; } } break; case EVNT_BROKER_REDIRECTION: // This means we got a broker redirection message. The handling // function that sent us this signal has created the broker list. { gStatusInfo.eStatus = GOGOC_CLISTAT__DISCONNECTEDIDLE; gStatusInfo.nStatus = GOGOCM_UIS_EVNTBROKERREDIRECTION; // Check that the broker list has been created. if( broker_list != NULL ) { // We're going through a broker list. trying_broker_list = 1; // We're not trying to connect to the original server. trying_original_server = 0; // Prepare to try the first broker in the list. current_broker_in_list = broker_list; // Try the first broker in the list without waiting for the retry delay. cycle = 0; // Copy the brokerList address to configuration server. if( FormatBrokerListAddr( current_broker_in_list, &(c.server) ) != 0 ) { // Error: Failed to format the address. Abort. gStatusInfo.eStatus = GOGOC_CLISTAT__DISCONNECTEDERROR; gStatusInfo.nStatus = GOGOCM_UIS_ERRBROKERREDIRECTION; status = make_status(status_context(status), ERR_BROKER_REDIRECTION); connected = 0; } } else { // Error: Empty or invalid broker list. Abort. gStatusInfo.nStatus = GOGOCM_UIS_ERRBROKERREDIRECTION; status = make_status(status_context(status), ERR_BROKER_REDIRECTION); connected = 0; } continue; } break; case ERR_BROKER_REDIRECTION: // This means we got a broker redirection message, but there were // errors in handling it. { gStatusInfo.eStatus = GOGOC_CLISTAT__DISCONNECTEDERROR; gStatusInfo.nStatus = GOGOCM_UIS_ERRBROKERREDIRECTION; Display(LOG_LEVEL_1, ELError, "tspMain", GOGO_STR_RDR_ERROR_PROCESSING_REDIRECTION, c.server); tspFreeBrokerList(broker_list); broker_list = NULL; connected = 0; continue; } break; case ERR_MEMORY_STARVATION: // This is a fatal error. { gStatusInfo.eStatus = GOGOC_CLISTAT__DISCONNECTEDERROR; gStatusInfo.nStatus = GOGOCM_UIS_ERRMEMORYSTARVATION; connected = 0; continue; } break; case ERR_TUNMODE_NOT_AVAILABLE: // Configured tunnel mode is not available on the server. // User needs to change configuration. Abort. { gStatusInfo.eStatus = GOGOC_CLISTAT__DISCONNECTEDERROR; gStatusInfo.nStatus = GOGOCM_UIS_ERRTUNMODENOTAVAILABLE; connected = 0; continue; } break; case ERR_TUNNEL_IO: // Occurs if there is a problem during the tunneling with a TUN interface. { gStatusInfo.eStatus = GOGOC_CLISTAT__DISCONNECTEDERROR; gStatusInfo.nStatus = GOGOCM_UIS_ERRTUNNELIO; consec_retry = 0; } break; case ERR_KEEPALIVE_ERROR: // A keepalive error occured. Probably a network error. // Since the keepalive error occurs after the TSP session, it is safe // to assume that we can reconnect and try again. { gStatusInfo.eStatus = GOGOC_CLISTAT__DISCONNECTEDERROR; gStatusInfo.nStatus = GOGOCM_UIS_ERRKEEPALIVEERROR; consec_retry = 0; } break; case ERR_BAD_TUNNEL_PARAM: // The tunnel information that the server provided was bad. { gStatusInfo.eStatus = GOGOC_CLISTAT__DISCONNECTEDERROR; gStatusInfo.nStatus = GOGOCM_UIS_ERRBADTUNNELPARAM; connected = 0; continue; } break; #ifdef HACCESS case ERR_HACCESS_SETUP: { Display(LOG_LEVEL_1, ELError, "tspMain", HACCESS_LOG_PREFIX_ERROR GOGO_STR_HACCESS_ERR_FAILED_TO_SETUP_HACCESS_FEATURES); gStatusInfo.eStatus = GOGOC_CLISTAT__DISCONNECTEDHACCESSSETUPERROR; gStatusInfo.nStatus = GOGOCM_UIS_ERRHACCESSSETUP; connected = 0; continue; } break; case ERR_HACCESS_EXPOSE_DEVICES: // Home access error: Failed to make the devices available. Abort. { Display(LOG_LEVEL_1, ELError, "tspMain", HACCESS_LOG_PREFIX_ERROR GOGO_STR_HACCESS_ERR_FAILED_TO_EXPOSE_DEVICES); gStatusInfo.eStatus = GOGOC_CLISTAT__DISCONNECTEDHACCESSEXPOSEDEVICESERROR; gStatusInfo.nStatus = GOGOCM_UIS_ERRHACCESSEXPOSEDEVICES; connected = 0; continue; } break; #endif case ERR_INVAL_GOGOC_ADDRESS: case ERR_FAIL_RESOLV_ADDR: // Failed to parse server Address or resolve it. { gStatusInfo.eStatus = GOGOC_CLISTAT__DISCONNECTEDERROR; gStatusInfo.nStatus = GOGOCM_UIS_ERRINVALSERVERADDR; connected = 0; continue; } break; case ERR_INVAL_CFG_FILE: case ERR_INVAL_CLIENT_ADDR: default: // Any other error, quit immediatly. { gStatusInfo.eStatus = GOGOC_CLISTAT__DISCONNECTEDERROR; gStatusInfo.nStatus = GOGOCM_UIS_ERRUNKNOWN; connected = 0; continue; } break; } // status switch // Send status info about the current connection failure. // send_status_info(); // Do not wait if it is the first reconnection attempt. // The delay to wait SHALL be doubled at every 3 consecutive failed // connection attempts. It MUST NOT exceed configured retry_delay_max. // if( consec_retry > 0 ) { sint32_t sleepTime = c.retry_delay; if( consec_retry % CONSEC_RETRY_TO_DOUBLE_WAIT == 0 ) { // Double the effective wait time. effective_retry_delay *= 2; if( effective_retry_delay > c.retry_delay_max ) effective_retry_delay = c.retry_delay_max; } consec_retry++; sleepTime = effective_retry_delay; // Log connection failure & sleep before retrying. Display( LOG_LEVEL_1, ELInfo, "tspMain", STR_GEN_DISCONNECTED_RETRY_SEC, effective_retry_delay ); // Check for stop at each second. while( sleepTime-- > 0 && tspCheckForStopOrWait(1000) == 0 ); } else { consec_retry++; effective_retry_delay = c.retry_delay; // Log connection failure. Reconnect now. Display( LOG_LEVEL_1, ELInfo, "tspMain", STR_GEN_DISCONNECTED_RETRY_NOW ); } } // Profanely big connection while() { uint32_t sleepTime = loop_delay; while( sleepTime-- > 0 && tspCheckForStopOrWait(1000) == 0 ); } loop_delay *= 2; if (loop_delay > c.retry_delay_max) loop_delay = c.retry_delay_max; } while (!c.boot_mode); endtspc: // Send final status to GUI. send_status_info(); // Free the broker list. tspFreeBrokerList(broker_list); // Display the last status context, if the status number is not SUCCESS. if( status_number(status) != SUCCESS ) { if( log_display_ok == 0 ) DirectErrorMessage(STR_GEN_LAST_STATUS_CONTEXT, GOGOCStatusContext[status_context(status)]); else Display(LOG_LEVEL_1, ELWarning, "tspMain", STR_GEN_LAST_STATUS_CONTEXT, GOGOCStatusContext[status_context(status)]); } // Log end of program. if( log_display_ok == 0 ) DirectErrorMessage(STR_GEN_FINISHED); else Display(LOG_LEVEL_1, ELInfo, "tspMain", STR_GEN_FINISHED); // Close the log system LogClose(); return( status_number(status) ); } // -------------------------------------------------------------------------- // InitNetToolsArray: // // Parameter: // nt_array: Pointer to the net tools array to initialize. // // Returned values: (none) // void InitNetToolsArray( net_tools_t nt_array[] ) { // Fill up the array. (nt_array)[NET_TOOLS_T_RUDP].netopen = NetRUDPConnect; (nt_array)[NET_TOOLS_T_RUDP].netclose = NetRUDPClose; (nt_array)[NET_TOOLS_T_RUDP].netsendrecv = NetRUDPReadWrite; (nt_array)[NET_TOOLS_T_RUDP].netsend = NetRUDPWrite; (nt_array)[NET_TOOLS_T_RUDP].netprintf = NetRUDPPrintf; (nt_array)[NET_TOOLS_T_RUDP].netrecv = NetRUDPRead; (nt_array)[NET_TOOLS_T_UDP].netopen = NetUDPConnect; (nt_array)[NET_TOOLS_T_UDP].netclose = NetUDPClose; (nt_array)[NET_TOOLS_T_UDP].netsendrecv = NetUDPReadWrite; (nt_array)[NET_TOOLS_T_UDP].netsend = NetUDPWrite; (nt_array)[NET_TOOLS_T_UDP].netprintf = NetUDPPrintf; (nt_array)[NET_TOOLS_T_UDP].netrecv = NetUDPRead; (nt_array)[NET_TOOLS_T_TCP].netopen = NetTCPConnect; (nt_array)[NET_TOOLS_T_TCP].netclose = NetTCPClose; (nt_array)[NET_TOOLS_T_TCP].netsendrecv = NetTCPReadWrite; (nt_array)[NET_TOOLS_T_TCP].netsend = NetTCPWrite; (nt_array)[NET_TOOLS_T_TCP].netprintf = NetTCPPrintf; (nt_array)[NET_TOOLS_T_TCP].netrecv = NetTCPRead; #ifdef V4V6_SUPPORT (nt_array)[NET_TOOLS_T_TCP6].netopen = NetTCP6Connect; (nt_array)[NET_TOOLS_T_TCP6].netclose = NetTCP6Close; (nt_array)[NET_TOOLS_T_TCP6].netsendrecv = NetTCP6ReadWrite; (nt_array)[NET_TOOLS_T_TCP6].netsend = NetTCP6Write; (nt_array)[NET_TOOLS_T_TCP6].netprintf = NetTCP6Printf; (nt_array)[NET_TOOLS_T_TCP6].netrecv = NetTCP6Read; (nt_array)[NET_TOOLS_T_RUDP6].netopen = NetRUDP6Connect; (nt_array)[NET_TOOLS_T_RUDP6].netclose = NetRUDP6Close; (nt_array)[NET_TOOLS_T_RUDP6].netsendrecv = NetRUDP6ReadWrite; (nt_array)[NET_TOOLS_T_RUDP6].netsend = NetRUDP6Write; (nt_array)[NET_TOOLS_T_RUDP6].netprintf = NetRUDP6Printf; (nt_array)[NET_TOOLS_T_RUDP6].netrecv = NetRUDP6Read; #endif // V4V6_SUPPORT } // -------------------------------------------------------------------------- // InitLogSystem: Allocates memory for the log configuration parameters and // initializes them with the values pass in 'p_config'. // // Parameter: // p_config: A valid tConf structure containing log configuration info. // // Returned values: // 0 on success // -1 on error. // sint32_t InitLogSystem( const tConf* p_config ) { tLogConfiguration * p_log_config; // Check configuration pointer. if( p_config == NULL ) { return -1; } // Allocate memory for the logging configuration structure. p_log_config = (tLogConfiguration *)pal_malloc(sizeof(tLogConfiguration)); if( p_log_config == NULL ) { DirectErrorMessage(STR_GEN_MALLOC_ERROR); return -1; } // Fill the logging configuration structure with the values parsed from the // configuration. It is possible that some of those values are default // values that were automatically set by the client code if the user did // not specify alternative values. p_log_config->identity = pal_strdup(LOG_IDENTITY); p_log_config->log_filename = pal_strdup(p_config->log_filename); p_log_config->log_level_stderr = p_config->log_level_stderr; p_log_config->log_level_console = p_config->log_level_console; p_log_config->log_level_syslog = p_config->log_level_syslog; p_log_config->log_level_file = p_config->log_level_file; p_log_config->syslog_facility = p_config->syslog_facility; p_log_config->log_rotation = p_config->log_rotation; p_log_config->log_rotation_size = p_config->log_rotation_size; p_log_config->delete_rotated_log = p_config->log_rotation_delete; p_log_config->buffer = 0; // Configure the logging system with the values provided above. if( LogConfigure(p_log_config) != 0 ) { DirectErrorMessage(STR_MISC_LOG_CONFIGURE_FAILED); return -1; } // Successful operation. return 0; } // -------------------------------------------------------------------------- // tspLogOSInfo: Logs the OS information through the log system. // void tspLogOSInfo( void ) { char bufOSInfo[256]; // Display gogoCLIENT version and build option(s). Display( LOG_LEVEL_1, ELInfo, "tspLogOSInfo", "%s", tsp_get_version() ); // Display OS specific information. Handy for bug reporting. tspGetOSInfo( sizeof(bufOSInfo), bufOSInfo ); // in tsp_local.c Display( LOG_LEVEL_1, ELInfo, "tspLogOSInfo", "%s", bufOSInfo ); } gogoc-1_2-RELEASE/gogoc-tsp/src/tsp/tsp_lease.c0100644000000000000000000000215511301544625017736 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: tsp_lease.c,v 1.1 2009/11/20 16:53:41 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2006 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ #include "platform.h" // -------------------------------------------------------------------------- // This function returns the time at which tunnel will be expired. // The return value should be used with function tspLeaseCheck(). // long tspLeaseGetExpTime( const long tun_lifetime ) { struct timeval tv; // get current time. pal_gettimeofday(&tv); // calculate expiration time. return tv.tv_sec + tun_lifetime; } /* * This function verify if expiration time is reached. */ sint32_t tspLeaseCheckExp( const long tun_expiration ) { struct timeval tv; /* get current time */ pal_gettimeofday(&tv); /* if expired, return 1 */ if (tv.tv_sec > tun_expiration) return 1; else return 0; } gogoc-1_2-RELEASE/gogoc-tsp/src/tsp/tsp_net.c0100644000000000000000000001514211301544625017433 0ustar rootroot/* --------------------------------------------------------------------------- $Id: tsp_net.c,v 1.1 2009/11/20 16:53:41 jasminko Exp $ --------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT --------------------------------------------------------------------------- */ #include "platform.h" #include "gogoc_status.h" #include "tsp_net.h" #include "net.h" #include "log.h" #include "hex_strings.h" // -------------------------------------------------------------------------- // tspConnect: Creates a socket and connects to the specified server on the // specified port. // gogoc_status tspConnect( pal_socket_t *p_sock, char *srvname, uint16_t srvport, net_tools_t *nt ) { sint32_t ret; gogoc_status status = STATUS_SUCCESS_INIT; ret = nt->netopen( p_sock, srvname, srvport ); switch( ret ) { case 0: status = make_status(CTX_NETWORKCONNECT, SUCCESS); break; case -1: // Failed to resolve srvname. status = make_status(CTX_NETWORKCONNECT, ERR_FAIL_RESOLV_ADDR); break; case -2: // Failed to connect (TCP only) to srvname. status = make_status(CTX_NETWORKCONNECT, ERR_FAIL_SOCKET_CONNECT); break; } return status; } // -------------------------------------------------------------------------- // tspClose: // gogoc_status tspClose(pal_socket_t sock, net_tools_t *nt) { sint32_t ret = nt->netclose(sock); return make_status( CTX_UNSPECIFIED, (ret==0) ? SUCCESS : ERR_SOCKET_IO ); } // -------------------------------------------------------------------------- // tspSendRecv: Sends a payload to server and receives reply payload. // NOTE: plin is data to be sent and plout->payload is a buffer for data to // be received. // sint32_t tspSendRecv(pal_socket_t socket, tPayload *plin, tPayload *plout, net_tools_t *nt) { char string[] = "Content-length: %ld\r\n"; char buffer[PROTOCOLFRAMESIZE]; char *ptr_b, *ptr_c; sint32_t read, ret, size, left; // add in content-length to data to be sent. pal_snprintf(buffer, PROTOCOLFRAMESIZE, string, plin->size); size = pal_strlen(buffer); memcpy(buffer + size, plin->payload, plin->size); buffer[size + plin->size] = 0; Display(LOG_LEVEL_3, ELInfo, "tspSendRecv", STR_NET_SENDING, buffer); // Send 'buffer', recv in 'plout->payload'. ret = nt->netsendrecv(socket, buffer, size + plin->size, plout->payload, plout->size); if( ret <= 0 ) { Display(LOG_LEVEL_1, ELError, "tspSendRecv", STR_NET_FAIL_RW_SOCKET); return ret; } // Validate that we got 'Content-Length'. if( memcmp(plout->payload, "Content-length:", 15) ) { Display(LOG_LEVEL_1, ELError, "tspSendRecv", GOGO_STR_EXPECTED_CONTENT_LENGTH, plout->payload); return -1; } /* strip it from the returned string */ ptr_c = strchr(plout->payload, '\n'); /* test if valid data received (see bug 3295) */ if( ptr_c == NULL ) { Display(LOG_LEVEL_1, ELError, "tspSendRecv", GOGO_STR_RECV_INVALID_TSP_DATA); return -1; } ptr_c++; size = pal_strlen(ptr_c); /* validate received data using Content-Length (see bug: 3164) */ if( ((plout->size = atol(plout->payload + 15)) <= 0L) || (size > plout->size) ) { Display(LOG_LEVEL_1, ELError, "tspSendRecv", GOGO_STR_INVALID_PAYLOAD_SIZE); return -1; } left = plout->size - size; while( left > 0 ) { if( (read = nt->netrecv(socket, (ptr_c + size), left)) <= 0 ) { Display(LOG_LEVEL_1, ELError, "tspSendRecv", STR_NET_FAIL_R_SOCKET); return PROTOCOL_ERROR; } size += read; left -= read; } ptr_b = (char *)pal_malloc(++size); // need space for a little 0 at the end */ memset(ptr_b, 0, size); memcpy(ptr_b, ptr_c, --size); /* but need not to overwrite that little 0 */ pal_free(plout->payload); plout->payload = ptr_b; Display(LOG_LEVEL_3, ELInfo, "tspSendRecv", STR_NET_RECEIVED, plout->payload); return ret; } // -------------------------------------------------------------------------- // tspSend: // sint32_t tspSend(pal_socket_t socket, tPayload *pl, net_tools_t *nt) { char buffer[PROTOCOLFRAMESIZE]; long ClSize; sint32_t ret; pal_snprintf(buffer, PROTOCOLFRAMESIZE, "Content-length: %ld\r\n", pl->size); ClSize = pal_strlen(buffer); if( ClSize + pl->size > PROTOCOLFRAMESIZE ) { Display(LOG_LEVEL_1, ELError, "tspSend", GOGO_STR_PAYLOAD_BIGGER_PROTOFRMSIZE); return -1; } memcpy(buffer + ClSize,pl->payload, pl->size); buffer[ClSize + pl->size] = 0; Display(LOG_LEVEL_3, ELInfo, "tspSend", STR_NET_SENDING, buffer); ret = nt->netsend(socket, buffer, ClSize + pl->size); if( ret < 0 ) { Display(LOG_LEVEL_1, ELError, "tspSend", STR_NET_FAIL_W_SOCKET); return ret; } return ret; } /* ** COMMENTED OUT ON March 11, 2008. Code not used. ** Will need to be validated. // -------------------------------------------------------------------------- // tspReceive: // sint32_t tspReceive(pal_socket_t socket, tPayload *pl, net_tools_t *nt) { sint32_t BytesTotal = 0, BytesRead = 0, BytesLeft = 0; char Buffer[PROTOCOLFRAMESIZE+1]; char *StartOfPayload; memset(Buffer,0,sizeof(Buffer)); if (pl->payload) pal_free(pl->payload); if ((BytesRead = nt->netrecv(socket, Buffer, sizeof(Buffer))) <= 0) { Display(LOG_LEVEL_1, ELError, "tspReceive", STR_NET_FAIL_R_SOCKET); return -1; } Display(LOG_LEVEL_3, ELInfo, "tspReceive", STR_NET_RECEIVED, Buffer); if( memcmp(Buffer, "Content-length:", 15) ) { Display(LOG_LEVEL_1, ELError, "tspReceive", GOGO_STR_EXPECTED_CONTENT_LENGTH, Buffer); return -1; } // Start of payload is after Content-length: XX\r\n if( (StartOfPayload = strchr(Buffer,'\n')) == NULL ) { Display(LOG_LEVEL_1, ELError, "tspReceive", GOGO_STR_INVALID_RESPONSE_RECEIVED); return -1; } StartOfPayload++; BytesTotal = pal_strlen(StartOfPayload); if (((pl->size = atol(Buffer + 15)) <= 0L) || BytesTotal > pl->size) { Display(LOG_LEVEL_1, ELError, "tspReceive", GOGO_STR_INVALID_PAYLOAD_SIZE); return -1; } BytesLeft = pl->size - BytesTotal; while( BytesLeft > 0 ) { if((BytesRead = nt->netrecv(socket, (StartOfPayload + BytesTotal), BytesLeft)) <= 0) { Display(LOG_LEVEL_1, ELError, "tspReceive", STR_NET_FAIL_R_SOCKET); return -1; } BytesTotal += BytesRead; BytesLeft -= BytesRead; } if((pl->payload = (char *)pal_malloc((pl->size) + 1)) == NULL) { Display(LOG_LEVEL_1, ELError, "tspReceive", STR_GEN_MALLOC_ERROR); return(PROTOCOL_EMEM); } memset(pl->payload, 0, sizeof(pl->payload)); pal_strcpy(pl->payload, StartOfPayload); return PROTOCOL_OK; } */ gogoc-1_2-RELEASE/gogoc-tsp/src/tsp/tsp_redirect.c0100644000000000000000000004527511301544625020460 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: tsp_redirect.c,v 1.1 2009/11/20 16:53:41 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2008 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ #include "platform.h" #include "gogoc_status.h" #include "log.h" #include "config.h" #include "tsp_redirect.h" #include "tsp_client.h" #include "xml_tun.h" #include "hex_strings.h" /* Determine if a TSP status code means that */ /* redirection should be performed. */ sint32_t tspIsRedirectStatus(sint32_t status) { return (status > REDIRECT_STATUS_CODE_BASE); } /* Free a broker list */ tRedirectStatus tspFreeBrokerList(tBrokerList *broker_list) { tBrokerList *next_broker = NULL; /* Loop through the list, freeing each element */ while (broker_list != NULL) { next_broker = broker_list->next; pal_free(broker_list); broker_list = next_broker; } return TSP_REDIRECT_OK; } /* Add a new broker element to a list of brokers */ tRedirectStatus tspAddBrokerToList(tBrokerList **broker_list, char *address, tBrokerAddressType address_type, uint32_t distance) { tBrokerList *new_broker = NULL; /* Some internal error checking */ if (broker_list == NULL) { Display(LOG_LEVEL_1, ELError, "tspAddBrokerToList", GOGO_STR_RDR_ADD_BROKER_INTERNAL_ERR); return TSP_REDIRECT_INTERNAL_ERR; } if (address == NULL) { Display(LOG_LEVEL_1, ELError, "tspAddBrokerToList", GOGO_STR_RDR_ADD_BROKER_INTERNAL_ERR); return TSP_REDIRECT_INTERNAL_ERR; } /* Allocate a new broker element */ if ((new_broker = (tBrokerList *)pal_malloc(sizeof(tBrokerList))) == NULL) { Display(LOG_LEVEL_1, ELError, "tspAddBrokerToList", GOGO_STR_RDR_ADD_BROKER_NO_MEM); return TSP_REDIRECT_CANT_ALLOCATE_MEM; } /* Set the broker address */ pal_snprintf(new_broker->address, MAX_REDIRECT_ADDRESS_LENGTH, address); /* Validate that the address was set correctly */ if (strlen(new_broker->address) != strlen(address)) { pal_free(new_broker); Display(LOG_LEVEL_1, ELError, "tspAddBrokerToList", GOGO_STR_RDR_ADD_BROKER_ADDRESS_TRUNC); return TSP_REDIRECT_ADDRESS_TRUNCATED; } /* Set the broker distance */ new_broker->distance = distance; /* Set the broker address type */ new_broker->address_type = address_type; /* Add the new broker element at the end of the list */ new_broker->next = NULL; if (*broker_list == NULL) { *broker_list = new_broker; } else { while ((*broker_list)->next != NULL) { broker_list = &((*broker_list)->next); } (*broker_list)->next = new_broker; } return TSP_REDIRECT_OK; } /* Log a redirection broker list */ tRedirectStatus tspLogRedirectionList(tBrokerList *broker_list, sint32_t sorted) { char broker_list_string[MAX_BROKER_LIST_STRING_LENGTH]; char *index = broker_list_string; sint32_t first_broker = 1; size_t space_left = MAX_BROKER_LIST_STRING_LENGTH - 1; size_t space_needed = 0; /* Calculate the space we have for the string version of the broker list. */ /* We need to keep enough space to add '...' if the list is too long. */ space_left -= ( strlen(BROKER_LIST_STRING_START) + strlen(BROKER_LIST_STRING_SEPARATOR) + strlen(BROKER_LIST_STRING_SUSPENSION) + strlen(BROKER_LIST_STRING_END)); /* Start of list marker */ index += sprintf(index, "%s", BROKER_LIST_STRING_START); /* Loop through the list */ while (broker_list != NULL) { /* First element has no separator before it */ if (first_broker) { /* We need space for the broker's address */ space_needed = strlen(broker_list->address); /* If it fits in the space we have, put it there */ if (space_left >= space_needed) { index += sprintf(index, "%s", broker_list->address); } /* If it doesn't, indicate there's actually more to the list */ else { index += sprintf(index, "%s", BROKER_LIST_STRING_SUSPENSION); break; } /* Next broker won't be the first one anymore */ first_broker = 0; } else { /* We need space for a separator, and the broker's address */ space_needed = strlen(BROKER_LIST_STRING_SEPARATOR) + strlen(broker_list->address); /* If it fits in the space we have, put it there */ if (space_left >= space_needed) { index += sprintf(index, "%s%s", BROKER_LIST_STRING_SEPARATOR, broker_list->address); } /* If it doesn't, indicate there's actually more to the list */ else { index += sprintf(index, "%s%s", BROKER_LIST_STRING_SEPARATOR, BROKER_LIST_STRING_SUSPENSION); break; } } /* Move to the next element */ broker_list = broker_list->next; } /* End of list marker */ index += sprintf(index, "%s", BROKER_LIST_STRING_END); if (sorted) { Display(LOG_LEVEL_1, ELInfo, "tspLogRedirection", GOGO_STR_RDR_SORTED_BROKER_LIST_IS, broker_list_string); } else { Display(LOG_LEVEL_1, ELInfo, "tspLogRedirection", GOGO_STR_RDR_BROKER_LIST_IS, broker_list_string); } return TSP_REDIRECT_OK; } /* Create a broker list from parsed XML information */ tRedirectStatus tspCreateBrokerList(tTunnel *tunnel_info, tBrokerList **broker_list, sint32_t *broker_count) { tLinkedList *current_broker = NULL; /* Make sure we start from an empty list */ tspFreeBrokerList(*broker_list); *broker_list = NULL; /* Initially no element in the list */ *broker_count = 0; /* For each IPv4 broker in the message */ for (current_broker = tunnel_info->broker_redirect_ipv4; current_broker != NULL; current_broker = current_broker->next) { if (*broker_count < MAX_REDIRECT_BROKERS_IN_LIST) { /* Add a new element to the list */ if (tspAddBrokerToList(broker_list, current_broker->Value, TSP_REDIRECT_BROKER_TYPE_IPV4, 0) != TSP_REDIRECT_OK) { Display(LOG_LEVEL_1, ELError, "tspCreateBrokerList", GOGO_STR_RDR_CREATE_LIST_CANT_ADD); tspFreeBrokerList(*broker_list); *broker_list = NULL; return TSP_REDIRECT_CANT_ADD_BROKER_TO_LIST; } else { (*broker_count)++; } } else { Display(LOG_LEVEL_1, ELError, "tspCreateBrokerList", GOGO_STR_RDR_TOO_MANY_BROKERS, MAX_REDIRECT_BROKERS_IN_LIST); tspFreeBrokerList(*broker_list); *broker_list = NULL; return TSP_REDIRECT_TOO_MANY_BROKERS; } } /* For each IPv6 broker in the message */ for (current_broker = tunnel_info->broker_redirect_ipv6; current_broker != NULL; current_broker = current_broker->next) { if (*broker_count < MAX_REDIRECT_BROKERS_IN_LIST) { /* Add a new element to the list */ if (tspAddBrokerToList(broker_list, current_broker->Value, TSP_REDIRECT_BROKER_TYPE_IPV6, 0) != TSP_REDIRECT_OK) { Display(LOG_LEVEL_1, ELError, "tspCreateBrokerList", GOGO_STR_RDR_CREATE_LIST_CANT_ADD); tspFreeBrokerList(*broker_list); *broker_list = NULL; return TSP_REDIRECT_CANT_ADD_BROKER_TO_LIST; } else { (*broker_count)++; } } else { Display(LOG_LEVEL_1, ELError, "tspCreateBrokerList", GOGO_STR_RDR_TOO_MANY_BROKERS, MAX_REDIRECT_BROKERS_IN_LIST); tspFreeBrokerList(*broker_list); *broker_list = NULL; return TSP_REDIRECT_TOO_MANY_BROKERS; } } /* For each FQDN broker in the message */ for (current_broker = tunnel_info->broker_redirect_dn; current_broker != NULL; current_broker = current_broker->next) { if (*broker_count < MAX_REDIRECT_BROKERS_IN_LIST) { /* Add a new element to the list */ if (tspAddBrokerToList(broker_list, current_broker->Value, TSP_REDIRECT_BROKER_TYPE_FQDN, 0) != TSP_REDIRECT_OK) { Display(LOG_LEVEL_1, ELError, "tspCreateBrokerList", GOGO_STR_RDR_CREATE_LIST_CANT_ADD); tspFreeBrokerList(*broker_list); *broker_list = NULL; return TSP_REDIRECT_CANT_ADD_BROKER_TO_LIST; } else { (*broker_count)++; } } else { Display(LOG_LEVEL_1, ELError, "tspCreateBrokerList", GOGO_STR_RDR_TOO_MANY_BROKERS, MAX_REDIRECT_BROKERS_IN_LIST); tspFreeBrokerList(*broker_list); *broker_list = NULL; return TSP_REDIRECT_TOO_MANY_BROKERS; } } return TSP_REDIRECT_OK; } /* Insert a broker element in the list, ordering it based on the distance value */ tRedirectStatus tspInsertInBrokerList(tBrokerList *new_element, tBrokerList **sorted_list) { tBrokerList *compared_broker = NULL; tBrokerList *precedent_broker = NULL; /* If the list is empty, the inserted element becomes the list */ if (*sorted_list == NULL) { *sorted_list = new_element; } else { compared_broker = *sorted_list; /* Move to the new element's ordered position in the list */ while ((compared_broker != NULL) && (new_element->distance > compared_broker->distance)) { precedent_broker = compared_broker; compared_broker = compared_broker->next; } /* Adjust the pointers so that the new element becomes part of the list */ new_element->next = compared_broker; if (precedent_broker != NULL) { precedent_broker->next = new_element; } else { *sorted_list = new_element; } } return TSP_REDIRECT_OK; } /* Sort a list of brokers based on the distance value (roundtrip time) */ tRedirectStatus tspSortBrokerList(tBrokerList **broker_list, tConf *conf, sint32_t broker_count) { tBrokerList *sorted_list = NULL; tBrokerList *current_broker = NULL; tBrokerList *new_element = NULL; Display(LOG_LEVEL_2, ELInfo, "tspSortBrokerList", GOGO_STR_RDR_SORTING_BROKER_LIST); /* Get the distance values */ if (tspGetBrokerDistances(*broker_list, broker_count, conf) != TSP_REDIRECT_OK) { Display(LOG_LEVEL_1, ELError, "tspSortBrokerList", GOGO_STR_RDR_SORT_LIST_CANT_GET_DIST); return TSP_REDIRECT_CANT_GET_DISTANCES; } current_broker = *broker_list; /* For each broker in the original list */ while (current_broker != NULL) { /* Create a new broker element */ if ((new_element = (tBrokerList *)pal_malloc(sizeof(tBrokerList))) == NULL) { tspFreeBrokerList(sorted_list); Display(LOG_LEVEL_1, ELError, "tspSortBrokerList", GOGO_STR_RDR_SORT_LIST_CANT_ALLOC); return TSP_REDIRECT_CANT_ALLOCATE_MEM; } /* Copy the address from the broker in the original list */ strcpy(new_element->address, current_broker->address); /* Copy the distance from the broker in the original list */ new_element->distance = current_broker->distance; /* Copy the address_type as well! */ new_element->address_type = current_broker->address_type; new_element->next = NULL; /* Insert (sorted) the new element in the sorted list */ if (tspInsertInBrokerList(new_element, &sorted_list) != TSP_REDIRECT_OK) { tspFreeBrokerList(sorted_list); Display(LOG_LEVEL_1, ELError, "tspSortBrokerList", GOGO_STR_RDR_SORT_LIST_CANT_INSERT); return TSP_REDIRECT_CANT_INSERT_BROKER_IN_LIST; } /* Move to the next broker in the original list */ current_broker = current_broker->next; } /* Free the original list */ tspFreeBrokerList(*broker_list); /* Replace the original list with the sorted one */ *broker_list = sorted_list; return TSP_REDIRECT_OK; } /* A simple function to log the fact that we received a redirection message */ tRedirectStatus tspLogReceivedRedirection(char *payload, tConf *conf) { char status[MAX_REDIRECT_STATUS_LENGTH]; /* Clear out the buffer */ memset(status, 0, sizeof(status)); /* Read the status line from the broker's reply */ sscanf(payload, "%[^\n]", status); /* Log the message including the server and the redirection status */ Display(LOG_LEVEL_1, ELInfo, "tspLogReceivedRedirection", GOGO_STR_RECEIVED_REDIRECTION, conf->server, status); return TSP_REDIRECT_OK; } /* Main function to handle a redirection message */ tRedirectStatus tspHandleRedirect(char *payload, tConf *conf, tBrokerList **broker_list) { tTunnel tunnel_info; sint32_t broker_count = 0; tspLogReceivedRedirection(payload, conf); /* Parse the XML data in the payload */ if (tspExtractPayload(payload, &tunnel_info) != 0) { Display(LOG_LEVEL_1, ELError, "tspHandleRedirect", GOGO_STR_RDR_CANT_EXTRACT_PAYLOAD); return TSP_REDIRECT_CANT_EXTRACT_PAYLOAD; } /* Create a broker list from that information */ if (tspCreateBrokerList(&tunnel_info, broker_list, &broker_count) != TSP_REDIRECT_OK) { Display(LOG_LEVEL_1, ELError, "tspHandleRedirect", GOGO_STR_RDR_CANT_CREATE_LIST); return TSP_REDIRECT_CANT_CREATE_LIST; } /* Log the redirection message and details */ if (tspLogRedirectionList(*broker_list, 0) != TSP_REDIRECT_OK) { Display(LOG_LEVEL_1, ELError, "tspHandleRedirect", GOGO_STR_RDR_CANT_LOG); //return TSP_REDIRECT_CANT_LOG_REDIRECTION; } /* If the broker list has more than one element */ if (broker_count > 1) { /* Sort the broker list */ if (tspSortBrokerList(broker_list, conf, broker_count) != TSP_REDIRECT_OK) { Display(LOG_LEVEL_1, ELError, "tspHandleRedirect", GOGO_STR_RDR_CANT_SORT_LIST); return TSP_REDIRECT_CANT_SORT_LIST; } /* Log the redirection message and details */ if (tspLogRedirectionList(*broker_list, 1) != TSP_REDIRECT_OK) { Display(LOG_LEVEL_1, ELError, "tspHandleRedirect", GOGO_STR_RDR_CANT_LOG); //return TSP_REDIRECT_CANT_LOG_REDIRECTION; } /* Write the broker list to file */ if (tspWriteBrokerListToFile(conf->broker_list_file, *broker_list) != TSP_REDIRECT_OK) { Display(LOG_LEVEL_1, ELError, "tspHandleRedirect", GOGO_STR_RDR_CANT_SAVE_LIST); // return TSP_REDIRECT_CANT_SAVE_BROKER_LIST; } } /* An empty list is an error */ if (broker_count == 0) { Display(LOG_LEVEL_1, ELError, "tspHandleRedirect", GOGO_STR_RDR_NULL_LIST); return TSP_REDIRECT_EMPTY_BROKER_LIST; } return TSP_REDIRECT_OK; } /* Read the last server from the last_server file */ tRedirectStatus tspReadLastServerFromFile(char *last_server_file, char *buffer) { FILE *file; char line[MAX_REDIRECT_LAST_SERVER_LINE_LENGTH]; sint32_t found_server = 0; /* Some internal checking */ if (last_server_file == NULL) { Display(LOG_LEVEL_1, ELError, "tspReadLastServerFromFile", GOGO_STR_RDR_READ_LAST_SERVER_INT_ERR); return TSP_REDIRECT_INTERNAL_ERR; } if (buffer == NULL) { Display(LOG_LEVEL_1, ELError, "tspReadLastServerFromFile", GOGO_STR_RDR_READ_LAST_SERVER_INT_ERR); return TSP_REDIRECT_INTERNAL_ERR; } /* Try to open the last_server file */ if ((file = fopen(last_server_file, "r")) == NULL) { return TSP_REDIRECT_CANT_OPEN_FILE; } /* Loop through the lines in the file */ while (fgets(line, sizeof(line), file)) { /* Skip blank lines and comments */ if (*line == '#' || *line == '\r' || *line == '\n') { continue; } /* Remove CR and LF */ if (strlen(line) && (line[strlen(line) - 1] == '\n' || line[strlen(line) - 1] == '\r')) line[strlen(line) - 1] = '\0'; if (strlen(line) && (line[strlen(line) - 1] == '\n' || line[strlen(line) - 1] == '\r')) line[strlen(line) - 1] = '\0'; /* Copy the line to the buffer */ sprintf(buffer, line); /* We found a server, so stop looking */ found_server = 1; break; } /* Close the file */ fclose(file); if (found_server) { return TSP_REDIRECT_OK; } else { return TSP_REDIRECT_NO_LAST_SERVER; } } /* Write the last server to the last_server file */ tRedirectStatus tspWriteLastServerToFile(char *last_server_file, char *last_server) { FILE *file; /* Some internal checking */ if (last_server_file == NULL) { Display(LOG_LEVEL_1, ELError, "tspWriteLastServerToFile", GOGO_STR_RDR_WRITE_LAST_SERVER_INT_ERR); return TSP_REDIRECT_INTERNAL_ERR; } if (last_server == NULL) { Display(LOG_LEVEL_1, ELError, "tspWriteLastServerToFile", GOGO_STR_RDR_WRITE_LAST_SERVER_INT_ERR); return TSP_REDIRECT_INTERNAL_ERR; } /* Try to open the last_server file */ if ((file = fopen(last_server_file, "w")) == NULL) { Display(LOG_LEVEL_1, ELError, "tspWriteLastServerToFile", GOGO_STR_RDR_WRITE_LAST_SERVER_CANT_OPEN, last_server_file); return TSP_REDIRECT_CANT_OPEN_FILE; } /* Write the last server to the last_server file */ if (fprintf(file, "%s\n", last_server) < 0) { Display(LOG_LEVEL_1, ELError, "tspWriteLastServerToFile", GOGO_STR_RDR_WRITE_LAST_SERVER_CANT_WRITE, last_server, last_server_file); fclose(file); return TSP_REDIRECT_CANT_WRITE_TO_FILE; } /* Close the file */ fclose(file); return TSP_REDIRECT_OK; } /* Write a broker list to the broker_list file */ tRedirectStatus tspWriteBrokerListToFile(char *broker_list_file, tBrokerList *broker_list) { FILE *file; tBrokerList *current_broker = NULL; /* Some internal checking */ if (broker_list_file == NULL) { Display(LOG_LEVEL_1, ELError, "tspWriteBrokerListToFile", GOGO_STR_RDR_WRITE_BROKER_LIST_INT_ERR); return TSP_REDIRECT_INTERNAL_ERR; } /* Try to open the broker_list file */ if ((file = fopen(broker_list_file, "w")) == NULL) { Display(LOG_LEVEL_1, ELError, "tspWriteBrokerListToFile", GOGO_STR_RDR_WRITE_BROKER_LIST_CANT_OPEN, broker_list_file); return TSP_REDIRECT_CANT_OPEN_FILE; } /* Loop through the broker list */ for (current_broker = broker_list; current_broker != NULL; current_broker = current_broker->next) { /* Write each broker's address to the broker_list file */ if (fprintf(file, "%s\n", current_broker->address) < 0) { Display(LOG_LEVEL_1, ELError, "tspWriteBrokerListToFile", GOGO_STR_RDR_WRITE_BROKER_LIST_CANT_WRITE, broker_list_file); fclose(file); return TSP_REDIRECT_CANT_WRITE_TO_FILE; } } /* Close the file */ fclose(file); return TSP_REDIRECT_OK; } /* Create a broker list from the broker_list file */ tRedirectStatus tspReadBrokerListFromFile(char *broker_list_file, tBrokerList **broker_list) { FILE *file; char line[MAX_REDIRECT_BROKER_LIST_LINE_LENGTH]; sint32_t broker_count = 0; /* Some internal checking */ if (broker_list_file == NULL) { Display(LOG_LEVEL_1, ELError, "tspReadBrokerListFromFile", GOGO_STR_RDR_WRITE_BROKER_LIST_INT_ERR); return TSP_REDIRECT_INTERNAL_ERR; } if (broker_list == NULL) { Display(LOG_LEVEL_1, ELError, "tspReadBrokerListFromFile", GOGO_STR_RDR_WRITE_BROKER_LIST_INT_ERR); return TSP_REDIRECT_INTERNAL_ERR; } *broker_list = NULL; /* Try to open the broker_list file */ if ((file = fopen(broker_list_file, "r")) == NULL) { return TSP_REDIRECT_CANT_OPEN_FILE; } /* Loop through the lines in the file */ while (fgets(line, sizeof(line), file)) { /* Remove CR and LF */ if (strlen(line) && (line[strlen(line) - 1] == '\n' || line[strlen(line) - 1] == '\r')) line[strlen(line) - 1] = '\0'; if (strlen(line) && (line[strlen(line) - 1] == '\n' || line[strlen(line) - 1] == '\r')) line[strlen(line) - 1] = '\0'; if (strlen(line) > 0) { if (broker_count < MAX_REDIRECT_BROKERS_IN_LIST) { /* Add a new element to the broker list */ if (tspAddBrokerToList(broker_list, line, TSP_REDIRECT_BROKER_TYPE_NONE, 0) != TSP_REDIRECT_OK) { Display(LOG_LEVEL_1, ELError, "tspReadBrokerListFromFile", GOGO_STR_RDR_READ_BROKER_LIST_CANT_ADD, broker_list_file); fclose(file); return TSP_REDIRECT_CANT_ADD_BROKER_TO_LIST; } else { broker_count++; } } else { fclose(file); return TSP_REDIRECT_TOO_MANY_BROKERS; } } } /* Close the file */ fclose(file); return TSP_REDIRECT_OK; } gogoc-1_2-RELEASE/gogoc-tsp/src/tsp/tsp_setup.c0100644000000000000000000003465611345004450020013 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: tsp_setup.c,v 1.2 2010/03/07 20:14:32 carl Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ #include "platform.h" #include "gogoc_status.h" // Error codes #include "tsp_setup.h" #include "tsp_client.h" #include "config.h" // tConf #include "xml_tun.h" // tTunnel #include "log.h" // Display() #include "hex_strings.h" // Strings for Display() #include "lib.h" // IsAll, IPv4Addr, IPv6Addr, IPAddrAny, Numeric. // gogoCLIENT Messaging Subsystem. #include #define TSP_OPERATION_CREATETUNNEL "TSP_TUNNEL_CREATION" #define TSP_OPERATION_TEARDOWNTUNNEL "TSP_TUNNEL_TEARDOWN" /* Should be defined in platform.h */ #ifndef SCRIPT_TMP_FILE #error "SCRIPT_TMP_FILE is not defined in platform.h" #endif /* Execute cmd and send output to log subsystem */ sint32_t execScript( const char *cmd ) { char buf[1024]; FILE* f_log; sint32_t retVal; // Run the command. memset( buf, 0, sizeof(buf) ); pal_snprintf( buf, sizeof(buf), "%s > %s", cmd, SCRIPT_TMP_FILE ); retVal = pal_system( buf ); // Open resulting output file. f_log = fopen( SCRIPT_TMP_FILE, "r" ); if( f_log == NULL ) { Display( LOG_LEVEL_1, ELError, "execScript", GOGO_STR_CANT_OPEN_TMP_FILE SCRIPT_TMP_FILE ); return -1; } // Loop on the output file, and log the contents. while( !feof( f_log ) ) { if( fgets( buf, sizeof(buf), f_log ) != NULL ) { Display( LOG_LEVEL_MAX, ELInfo, "execScript", "%s", buf ); } } // Close file fclose( f_log ); // Remove command output. pal_unlink( SCRIPT_TMP_FILE ); return retVal; } // -------------------------------------------------------------------------- // This function validates the information found in the tunnel information // structure. // Returns number of errors found. 0 is successful validation. // sint32_t validate_tunnel_info( const tTunnel* pTunnelInfo ) { sint32_t err_num = 0; if( !IsAll(IPv4Addr, pTunnelInfo->client_address_ipv4) ) { Display(LOG_LEVEL_1, ELError, "validate_tunnel_info", GOGO_STR_BAD_CLIENT_IPV4_RECVD); err_num++; } if( !IsAll(IPv6Addr, pTunnelInfo->client_address_ipv6) ) { Display(LOG_LEVEL_1, ELError, "validate_tunnel_info", GOGO_STR_BAD_CLIENT_IPV6_RECVD); err_num++; } if( pTunnelInfo->client_dns_server_address_ipv6 != NULL ) { if( !IsAll(IPv6Addr, pTunnelInfo->client_dns_server_address_ipv6) ) { Display(LOG_LEVEL_1, ELError, "validate_tunnel_info", GOGO_STR_BAD_CLIENT_DNS_IPV6_RECVD); err_num++; } } if( !IsAll(IPv4Addr, pTunnelInfo->server_address_ipv4) ) { Display(LOG_LEVEL_1, ELError, "validate_tunnel_info", GOGO_STR_BAD_SERVER_IPV4_RECVD); err_num++; } if( !IsAll(IPv6Addr, pTunnelInfo->server_address_ipv6) ) { Display(LOG_LEVEL_1, ELError, "validate_tunnel_info", GOGO_STR_BAD_SERVER_IPV6_RECVD); err_num++; } // If prefix information is found, validate it. if( pTunnelInfo->prefix != NULL ) { if( !IsAll(IPAddrAny, pTunnelInfo->prefix) ) { Display(LOG_LEVEL_1, ELError, "validate_tunnel_info", GOGO_STR_BAD_SERVER_PREFIX_RECVD); err_num++; } if( !IsAll(Numeric, pTunnelInfo->prefix_length) ) { Display(LOG_LEVEL_1, ELError, "validate_tunnel_info", GOGO_STR_BAD_PREFIX_LEN_RECVD); err_num++; } } return err_num; } // -------------------------------------------------------------------------- void set_tsp_env_variables( const tConf* pConfig, const tTunnel* pTunnelInfo ) { char buffer[8]; // Specify log verbosity (MAXIMAL). pal_snprintf( buffer, sizeof buffer, "%d", LOG_LEVEL_MAX ); tspSetEnv("TSP_VERBOSE", buffer, 1); // Specify gogoCLIENT installation directory. tspSetEnv("TSP_HOME_DIR", TspHomeDir, 1); // Specify the tunnel mode. tspSetEnv("TSP_TUNNEL_MODE", pTunnelInfo->type, 1); // Specify host type {router, host} tspSetEnv("TSP_HOST_TYPE", pConfig->host_type, 1); // Specify tunnel interface, for setup. if (pal_strcasecmp(pTunnelInfo->type, STR_XML_TUNNELMODE_V6V4) == 0 ) { tspSetEnv("TSP_TUNNEL_INTERFACE", pConfig->if_tunnel_v6v4, 1); gTunnelInfo.eTunnelType = TUNTYPE_V6V4; } else if (pal_strcasecmp(pTunnelInfo->type, STR_XML_TUNNELMODE_V6UDPV4) == 0 ) { tspSetEnv("TSP_TUNNEL_INTERFACE", pConfig->if_tunnel_v6udpv4, 1); gTunnelInfo.eTunnelType = TUNTYPE_V6UDPV4; } #ifdef V4V6_SUPPORT else if (pal_strcasecmp(pTunnelInfo->type, STR_XML_TUNNELMODE_V4V6) == 0 ) { tspSetEnv("TSP_TUNNEL_INTERFACE", pConfig->if_tunnel_v4v6, 1); gTunnelInfo.eTunnelType = TUNTYPE_V4V6; } #endif /* V4V6_SUPPORT */ // Specify what interface will be used for routing advertizement, // if enabled. tspSetEnv("TSP_HOME_INTERFACE", pConfig->if_prefix, 1); // Specify local endpoint IPv4 address tspSetEnv("TSP_CLIENT_ADDRESS_IPV4", pTunnelInfo->client_address_ipv4, 1); gTunnelInfo.szIPV4AddrLocalEndpoint = pTunnelInfo->client_address_ipv4; // Specify local endpoint IPv6 address tspSetEnv("TSP_CLIENT_ADDRESS_IPV6", pTunnelInfo->client_address_ipv6, 1); gTunnelInfo.szIPV6AddrLocalEndpoint = pTunnelInfo->client_address_ipv6; // Specify client dns IPv6 address tspSetEnv("TSP_CLIENT_DNS_ADDRESS_IPV6", pTunnelInfo->client_dns_server_address_ipv6, 1); gTunnelInfo.szIPV6AddrDns = pTunnelInfo->client_dns_server_address_ipv6; // Specify local endpoint domain name if( pTunnelInfo->client_dns_name != NULL) { tspSetEnv("TSP_CLIENT_DNS_NAME", pTunnelInfo->client_dns_name, 1); gTunnelInfo.szUserDomain = pTunnelInfo->client_dns_name; } // Specify remote endpoint IPv4 address. tspSetEnv("TSP_SERVER_ADDRESS_IPV4", pTunnelInfo->server_address_ipv4, 1); gTunnelInfo.szIPV4AddrRemoteEndpoint = pTunnelInfo->server_address_ipv4; // Specify remote endpoint IPv6 address. tspSetEnv("TSP_SERVER_ADDRESS_IPV6", pTunnelInfo->server_address_ipv6, 1); gTunnelInfo.szIPV6AddrRemoteEndpoint = pTunnelInfo->server_address_ipv6; // Specify prefix for tunnel endpoint. if ((pal_strcasecmp(pTunnelInfo->type, STR_XML_TUNNELMODE_V6V4) == 0) || (pal_strcasecmp(pTunnelInfo->type, STR_XML_TUNNELMODE_V6UDPV4) == 0)) tspSetEnv("TSP_TUNNEL_PREFIXLEN", "128", 1); #ifdef V4V6_SUPPORT else tspSetEnv("TSP_TUNNEL_PREFIXLEN", "32", 1); #endif /* V4V6_SUPPORT */ // Free and clear delegated prefix from tunnel info. if( gTunnelInfo.szDelegatedPrefix != NULL ) { pal_free( gTunnelInfo.szDelegatedPrefix ); gTunnelInfo.szDelegatedPrefix = NULL; } // Have we been allocated a prefix for routing advertizement..? if( pTunnelInfo->prefix != NULL ) { char chPrefix[128]; size_t len, sep; /* Compute the number of characters that are significant out of the prefix. */ /* This is meaningful only for IPv6 prefixes; no contraction is possible for IPv4. */ if ((pal_strcasecmp(pTunnelInfo->type, STR_XML_TUNNELMODE_V6V4) == 0) || (pal_strcasecmp(pTunnelInfo->type, STR_XML_TUNNELMODE_V6UDPV4) == 0)) { len = (atoi(pTunnelInfo->prefix_length) % 16) ? (atoi(pTunnelInfo->prefix_length) / 16 + 1) * 4 : atoi(pTunnelInfo->prefix_length) / 16 * 4; sep = (atoi(pTunnelInfo->prefix_length) % 16) ? (atoi(pTunnelInfo->prefix_length) / 16) : (atoi(pTunnelInfo->prefix_length) / 16) -1; } else { len = pal_strlen( pTunnelInfo->prefix ); sep = 0; } memset(chPrefix, 0, 128); memcpy(chPrefix, pTunnelInfo->prefix, len+sep); // Specify delegated prefix for routing advertizement, if enabled. tspSetEnv("TSP_PREFIX", chPrefix, 1); gTunnelInfo.szDelegatedPrefix = (char*) pal_malloc( pal_strlen(chPrefix) + 10/*To append prefix_length*/ ); strcpy( gTunnelInfo.szDelegatedPrefix, chPrefix ); // Specify prefix length for routing advertizement, if enabled. tspSetEnv("TSP_PREFIXLEN", pTunnelInfo->prefix_length, 1); strcat( gTunnelInfo.szDelegatedPrefix, "/" ); strcat( gTunnelInfo.szDelegatedPrefix, pTunnelInfo->prefix_length ); } } // -------------------------------------------------------------------------- // Builds the template script execution path and returns the string. // // Returns NULL if error is detected and template execution path cannot be // built. // // NOTE: This function is NOT thread safe. Callee should not retain // pointer returned from this function. // static char* get_template_script( const tConf* pConfig ) { static char buffer[1024] = { 0x00 }; FILE* f_test; // If first run, get the required information and build template // script execution path. // if( buffer[0] == 0x00 ) { pal_snprintf( buffer, sizeof buffer, "%s%c%s.%s", ScriptDir, DirSeparator, pConfig->template, ScriptExtension); f_test = fopen( buffer, "r" ); if( f_test == NULL ) { Display( LOG_LEVEL_1, ELError, "tspSetupInterface", GOGO_STR_TEMPLATE_NOT_FOUND, buffer ); return NULL; } // Close the just opened file. fclose( f_test ); memset( buffer, 0, sizeof buffer ); // Append script interpretor to buffer, if any. if( ScriptInterpretor != NULL ) { pal_snprintf( buffer, sizeof buffer, "%s \"%s%c%s.%s\"", ScriptInterpretor, ScriptDir, DirSeparator, pConfig->template, ScriptExtension); } else { pal_snprintf( buffer, sizeof buffer, "\"%s%c%s.%s\"", ScriptDir, DirSeparator, pConfig->template, ScriptExtension); } } return buffer; } // -------------------------------------------------------------------------- // This function will set the required environment variables that will later // be used when invoking the template script to actually create the tunnel. // gogoc_status tspSetupInterface(tConf *c, tTunnel *t) { gogoc_status status = STATUS_SUCCESS_INIT; char* template_script; // Perform validation on tunnel information provided by server. if( validate_tunnel_info(t) != 0 ) { // Errors occured during verification of tunnel parameters. Display( LOG_LEVEL_1, ELError, "tspSetupInterface", STR_TSP_ERRS_TUN_PARAM_FROM_SERVER ); return make_status(CTX_TUNINTERFACESETUP, ERR_BAD_TUNNEL_PARAM); } // Specify TSP Operation: Tunnel Creation. tspSetEnv("TSP_OPERATION", TSP_OPERATION_CREATETUNNEL, 1 ); // Set environment variable for script execution. set_tsp_env_variables( c, t ); // Do some platform-specific stuff before tunnel setup script is launched. // The "tspSetupInterfaceLocal" is defined in tsp_local.c in every platform. if( tspSetupInterfaceLocal( c, t ) != 0 ) { // Errors occured during setup of interface. return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } // Get interface configuration script command string. template_script = get_template_script( c ); if( template_script == NULL ) { // Failed to get filename/directory. return make_status(CTX_TUNINTERFACESETUP, ERR_INVAL_CFG_FILE); } // --------------------------------------------------------------- // Run the interface configuration script to bring the tunnel up. // --------------------------------------------------------------- Display( LOG_LEVEL_2, ELInfo, "tspSetupInterface", STR_GEN_EXEC_CFG_SCRIPT, template_script ); if( execScript( template_script ) != 0 ) { // Error executing script. Display(LOG_LEVEL_1, ELError, "tspSetupInterface", STR_GEN_SCRIPT_EXEC_FAILED); return make_status(CTX_TUNINTERFACESETUP, ERR_INTERFACE_SETUP_FAILED); } Display(LOG_LEVEL_2, ELInfo, "tspSetupInterface", STR_GEN_SCRIPT_EXEC_SUCCESS); // Display a resume of the configured settings. Display(LOG_LEVEL_2, ELInfo, "tspSetupInterface", GOGO_STR_SETUP_HOST_TYPE, c->host_type); Display(LOG_LEVEL_2, ELInfo, "tspSetupInterface", GOGO_STR_SETUP_TUNNEL_TYPE, t->type); Display(LOG_LEVEL_3, ELInfo, "tspSetupInterface", GOGO_STR_SETUP_PROXY, c->proxy_client == TRUE ? STR_LIT_ENABLED : STR_LIT_DISABLED); if( (pal_strcasecmp(t->type, STR_XML_TUNNELMODE_V6V4) == 0) || (pal_strcasecmp(t->type, STR_XML_TUNNELMODE_V6UDPV4) == 0)) { Display(LOG_LEVEL_1, ELInfo, "tspSetupInterface", GOGO_STR_YOUR_IPV6_IP_IS, t->client_address_ipv6); if( (t->prefix != NULL) && (t->prefix_length != NULL) ) Display(LOG_LEVEL_1, ELInfo, "tspSetupInterface", GOGO_STR_YOUR_IPV6_PREFIX_IS, t->prefix, t->prefix_length); if (t->client_dns_server_address_ipv6 != NULL) Display(LOG_LEVEL_1, ELInfo, "tspSetupInterface", GOGO_STR_YOUR_IPV6_DNS_IS, t->client_dns_server_address_ipv6); } #ifdef V4V6_SUPPORT else { Display(LOG_LEVEL_1, ELInfo, "tspSetupInterface", GOGO_STR_YOUR_IPV4_IP_IS, t->client_address_ipv4); if( (t->prefix != NULL) && (t->prefix_length != NULL) ) Display(LOG_LEVEL_1, ELInfo, "tspSetupInterface", GOGO_STR_YOUR_IPV4_PREFIX_IS, t->prefix, t->prefix_length); } #endif /* V4V6_SUPPORT */ // Set the broker used for connection & the current time(now) for tunnel // start. Then send the tunnel info through the messaging subsystem. gTunnelInfo.szBrokerName = c->server; gTunnelInfo.tunnelUpTime = pal_time(NULL); send_tunnel_info(); return status; } // -------------------------------------------------------------------------- // This function will set the required environment variables that will later // be used when invoking the template script to tear down the existing // tunnel. // gogoc_status tspTearDownTunnel( tConf* pConf, tTunnel* pTunInfo ) { char* scriptName; // Specify TSP Operation: Tunnel Teardown. tspSetEnv( "TSP_OPERATION", TSP_OPERATION_TEARDOWNTUNNEL, 1 ); // Set environment variables (They may be not set). set_tsp_env_variables( pConf, pTunInfo ); // Format path to script. scriptName = get_template_script( pConf ); if( scriptName == NULL ) { return make_status(CTX_GOGOCTEARDOWN, ERR_INVAL_CFG_FILE); } // Run the template script to tear the tunnel down. Display(LOG_LEVEL_2, ELInfo, "tspTearDownTunnel", STR_GEN_EXEC_CFG_SCRIPT, scriptName ); if( execScript( scriptName ) != 0 ) { // Error executing script. Display(LOG_LEVEL_1, ELError, "tspTearDownTunnel", STR_GEN_SCRIPT_EXEC_FAILED ); return make_status(CTX_GOGOCTEARDOWN, ERR_INTERFACE_SETUP_FAILED); } Display(LOG_LEVEL_2, ELInfo, "tspTearDownTunnel", STR_GEN_SCRIPT_EXEC_SUCCESS ); // Return script execution return code. return STATUS_SUCCESS_INIT; } gogoc-1_2-RELEASE/gogoc-tsp/src/tsp/tsp_tun_mgt.c0100644000000000000000000001510411301544626020321 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: tsp_tun_mgt.c,v 1.1 2009/11/20 16:53:42 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ // Tunnel Management functions #include "platform.h" #include "gogoc_status.h" #include "tsp_tun_mgt.h" #include "tsp_client.h" // tspCheckForStopOrWait(). #include "net_ka.h" // Keepalive functionality. #include "net_ka_winxp.h" // Use old keep-alive implementation WinXP hack. #include "tsp_lease.h" // Tunnel lifetime functions. #include "log.h" // Log #define LOOP_WAIT_MS 500 #ifdef WIN32 // Prototype. static gogoc_status winxp_tspPerformTunnelLoop( const PTUNNEL_LOOP_CONFIG pTunLoopCfg ); #endif // -------------------------------------------------------------------------- // Function: tspPerformTunnelLoop // // Performs the 3 following actions: // 1. Handles tunnel keepalive functionnality (if configured). // 2. Checks tunnel lifetime expiration (if any). // 3. Checks for tunnel termination signal (Usually user-generated). // // When this function returns, program should tear down tunnel and exit. // // Possible return values: // - NO_ERROR: Exiting because we're terminating tunnel (user request). // - KEEP_ALIVE_ERROR: Something went wrong in keepalive initialisation. // - KEEP_ALIVE_TIMEOUT: Keepalive timeout occured. // - LEASE_EXPIRED: Tunnel lifetime has ended. // gogoc_status tspPerformTunnelLoop( const PTUNNEL_LOOP_CONFIG pTunLoopCfg ) { void* p_ka_engine = NULL; // Keepalive engine parameters. ka_status_t ka_status; // Keepalive status ka_ret_t ka_ret; // keepalive return code. uint8_t ongoing = 1; // Flag used to know when to stop. long tun_expiration = 0; // Tunnel expiration. gogoc_status status = STATUS_SUCCESS_INIT; #ifdef WIN32 if( winxp_use_old_ka == 1 ) // set by winpc/tsp_local.c { // Use old keepalive implementation for Windows XP only. Display( LOG_LEVEL_1, ELInfo, "tspPerformTunnelLoop", "Using previous keepalive implementation for Windows XP." ); return winxp_tspPerformTunnelLoop( pTunLoopCfg ); } #endif // Compute tunnel expiration time. (IETF DSTM Draft 6.1) // if( pTunLoopCfg->tun_lifetime != 0 ) { tun_expiration = tspLeaseGetExpTime( pTunLoopCfg->tun_lifetime ); } // Initialize keepalive, if configured, and start the processing. // if( pTunLoopCfg->ka_interval > 0 ) { // Initialize the keepalive engine. ka_ret = KA_init( &p_ka_engine, pTunLoopCfg->ka_interval * 1000, pTunLoopCfg->ka_src_addr, pTunLoopCfg->ka_dst_addr, pTunLoopCfg->sa_family ); if( ka_ret != KA_SUCCESS ) { return make_status(CTX_TUNNELLOOP, ERR_KEEPALIVE_ERROR); } // Start the keepalive processing. ka_ret = KA_start( p_ka_engine ); if( ka_ret != KA_SUCCESS ) { KA_destroy( &p_ka_engine ); return make_status(CTX_TUNNELLOOP, ERR_KEEPALIVE_ERROR); } } // Start tunnel management loop. // while( status_number(status) == SUCCESS && ongoing == 1 ) { // Check if we've been notified to stop processing. if( tspCheckForStopOrWait( LOOP_WAIT_MS ) != 0 ) { // We've been notified to stop. ongoing = 0; } // Perform a round of keepalive. if( pTunLoopCfg->ka_interval > 0 ) { // Check if we're stopping. if( ongoing == 0 ) { // Stop keepalive engine. KA_stop( p_ka_engine ); } ka_status = KA_qry_status( p_ka_engine ); switch( ka_status ) { case KA_STAT_FIN_SUCCESS: case KA_STAT_ONGOING: break; case KA_STAT_FIN_ERROR: case KA_STAT_INVALID: status = make_status(CTX_TUNNELLOOP, ERR_KEEPALIVE_ERROR); KA_stop( p_ka_engine ); break; case KA_STAT_FIN_TIMEOUT: status = make_status(CTX_TUNNELLOOP, ERR_KEEPALIVE_TIMEOUT); KA_stop( p_ka_engine ); break; } } // Check for tunnel lease expiration. if( tun_expiration != 0 && tspLeaseCheckExp( tun_expiration ) == 1 ) { status = make_status(CTX_TUNNELLOOP, ERR_TUN_LEASE_EXPIRED); } } // Clean-up resources allocated for keepalive functionnality. // if( pTunLoopCfg->ka_interval > 0 ) { KA_destroy( &p_ka_engine ); } // Exit function & return status. return status; } #ifdef WIN32 // -------------------------------------------------------------------------- // Function: tspPerformTunnelLoop // // This function implements the old keepalive algorithm. It is used only // by Windows XP. Windows XP cannot use new implementation because its // firewall always drops raw socket packets. // This old implementation uses Windows ICMP API which works through // its firewall. // #undef LOOP_WAIT_MS #define LOOP_WAIT_MS 100 static gogoc_status winxp_tspPerformTunnelLoop( const PTUNNEL_LOOP_CONFIG pTunLoopCfg ) { gogoc_status status = STATUS_SUCCESS_INIT; long tun_expiration = 0; int ret = 0; // Compute tunnel expiration time. (IETF DSTM Draft 6.1) // if( pTunLoopCfg->tun_lifetime != 0 ) { tun_expiration = tspLeaseGetExpTime( pTunLoopCfg->tun_lifetime ); } // Initialize keep-alive, if configured. // if( pTunLoopCfg->ka_interval > 0 ) { ret = NetKeepaliveInit( pTunLoopCfg->ka_src_addr, pTunLoopCfg->ka_dst_addr, pTunLoopCfg->ka_interval, pTunLoopCfg->sa_family ); if( ret != 0 ) { // Something went wrong in keep-alive initialisation. return make_status(CTX_TUNNELLOOP, ERR_KEEPALIVE_ERROR); } } // Start tunnel management loop. // while( status_number(status) == SUCCESS && tspCheckForStopOrWait( LOOP_WAIT_MS ) == 0 ) { // Perform a round of keep-alive. if( pTunLoopCfg->ka_interval > 0 && NetKeepaliveDo() == 2 ) { status = make_status(CTX_TUNNELLOOP, ERR_KEEPALIVE_TIMEOUT); } // Check for tunnel lease expiration. if( tun_expiration != 0 && tspLeaseCheckExp( tun_expiration ) == 1 ) { status = make_status(CTX_TUNNELLOOP, ERR_TUN_LEASE_EXPIRED); } } // Clean-up resources allocated for keep-alive functionnality. // if( pTunLoopCfg->ka_interval > 0 ) { NetKeepaliveDestroy(); } // Exit function & return status. return status; } #endif gogoc-1_2-RELEASE/gogoc-tsp/src/xml/0040755000000000000000000000000011346561543015614 5ustar rootrootgogoc-1_2-RELEASE/gogoc-tsp/src/xml/Makefile0100644000000000000000000000210111301544626017235 0ustar rootroot# ########################################################################### # $Id: Makefile,v 1.1 2009/11/20 16:53:42 jasminko Exp $ # # Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. # # For license information refer to CLIENT-LICENSE.TXT # # ########################################################################### # # NOTE: This makefile MUST be interpreted by GNU make. # Include the platform makefile, if it exists. -include $(PLATFORM_DIR)/$(PLATFORM)/platform.mak ifdef DEBUG CFLAGS=-g -Wall $(CC_INC_PATHS) $(PLATFORM_CFLAGS) -D_REENTRANT -DDEBUG else CFLAGS=-O2 -Wall $(CC_INC_PATHS) $(PLATFORM_CFLAGS) -D_REENTRANT endif CC=gcc OBJS=$(OBJS_DIR)/xmlparse.o \ $(OBJS_DIR)/xml_req.o \ $(OBJS_DIR)/xml_tun.o all: $(OBJS) install: all $(OBJS_DIR)/xmlparse.o:xmlparse.c $(CC) $(CFLAGS) -c xmlparse.c -o $(OBJS_DIR)/xmlparse.o $(DEFINES) $(OBJS_DIR)/xml_req.o:xml_req.c $(CC) $(CFLAGS) -c xml_req.c -o $(OBJS_DIR)/xml_req.o $(DEFINES) $(OBJS_DIR)/xml_tun.o:xml_tun.c $(CC) $(CFLAGS) -c xml_tun.c -o $(OBJS_DIR)/xml_tun.o $(DEFINES) clean: rm -f $(OBJS) gogoc-1_2-RELEASE/gogoc-tsp/src/xml/xml_req.c0100644000000000000000000001156111301544626017422 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: xml_req.c,v 1.1 2009/11/20 16:53:42 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2005 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ #include "platform.h" #include "gogoc_status.h" #include "xml_req.h" #include "config.h" /* Create XML request for tunnel */ char *tspBuildCreateRequest(tConf *conf) { static char *Request[5000], Buffer[1024]; /* XXX: This routine may overflow Request */ memset(Request, 0, sizeof(Request)); strcpy((char *)Request, "tunnel_mode == V6UDPV4) strcat((char *)Request, STR_XML_TUNNELMODE_V6UDPV4); else if (conf->tunnel_mode == V6V4) strcat((char *)Request, STR_XML_TUNNELMODE_V6V4); #ifdef V4V6_SUPPORT else if (conf->tunnel_mode == V4V6) strcat((char *)Request, STR_XML_TUNNELMODE_V4V6); #endif /* V4V6_SUPPORT */ else strcat((char *)Request, STR_XML_TUNNELMODE_V6ANYV4); if (conf->proxy_client == TRUE) strcat((char *)Request, "\" proxy=\"yes\">\r\n"); else strcat((char *)Request, "\" proxy=\"no\">\r\n"); strcat((char *)Request, " \r\n"); if (conf->tunnel_mode != V4V6) pal_snprintf(Buffer, sizeof Buffer, "
%s
\r\n", conf->client_v4); #ifdef V4V6_SUPPORT if (conf->tunnel_mode == V4V6) pal_snprintf(Buffer, sizeof Buffer, "
%s
\r\n", conf->client_v6); #endif /* V4V6_SUPPORT */ strcat((char *)Request, Buffer); /* ------------------------------------------------------- */ /* KEEPALIVE */ /* ------------------------------------------------------- */ if (conf->keepalive == TRUE) { if (conf->tunnel_mode != V4V6) pal_snprintf(Buffer, sizeof Buffer, " \r\n
::
\r\n
\r\n",conf->keepalive_interval); #ifdef V4V6_SUPPORT if (conf->tunnel_mode == V4V6) pal_snprintf(Buffer, sizeof Buffer, " \r\n
127.0.0.1
\r\n
\r\n",conf->keepalive_interval); #endif /* V4V6_SUPPORT */ strcat((char *) Request, Buffer); } /* ------------------------------------------------------- */ /* ROUTER SECTION */ /* ------------------------------------------------------- */ if (strcmp(conf->host_type, "router") == 0) { strcat((char *)Request, " protocol, "default_route") != 0) { pal_snprintf(Buffer, sizeof Buffer, " protocol=\"%s\"", conf->protocol); strcat((char *)Request, Buffer); } strcat((char *)Request, ">\r\n"); if (conf->prefixlen==0) { if (conf->tunnel_mode != V4V6) conf->prefixlen = 48; /* default to 48 for v6anyv4 */ #ifdef V4V6_SUPPORT if (conf->tunnel_mode == V4V6) conf->prefixlen = 24; /* default to 24 for v4v6 */ #endif /* V4V6_SUPPORT */ } pal_snprintf(Buffer, sizeof Buffer, " \r\n", conf->prefixlen); strcat((char *)Request, Buffer); /* ------------------------------------------------------- */ /* REVERSE DNS DELEGATION */ /* ------------------------------------------------------- */ if(strlen(conf->dns_server)) { char *Server; strcat((char *)Request, " \r\n"); for(Server = strtok(conf->dns_server, ":");Server; Server = strtok(NULL, ":")) { pal_snprintf(Buffer, sizeof Buffer, "
%s
\r\n", Server); strcat((char *)Request, Buffer); } strcat((char *)Request, "
\r\n"); } /* ------------------------------------------------------- */ /* ROUTING PROTOCOL SECTION */ /* ------------------------------------------------------- */ if (strcmp(conf->protocol, "default_route") == 0) { if (strlen(conf->routing_info) > 0) { pal_snprintf(Buffer, sizeof Buffer, " %s\r\n", conf->routing_info); strcat((char *)Request, Buffer); } } strcat((char *)Request, " \r\n"); } strcat((char *)Request, "
\r\n"); strcat((char *)Request, "
\r\n"); return (char *)Request; } /* Create XML tunnel acknowledge */ char *tspBuildCreateAcknowledge() { /*XXX Based on BuildCreateRequest - this is a reminder to fix memory usage of both functions.*/ static char *Request[5000]; memset(Request, 0, sizeof(Request)); strcpy((char *)Request, "\r\n"); return (char *)Request; } gogoc-1_2-RELEASE/gogoc-tsp/src/xml/xml_tun.c0100644000000000000000000003137311345004561017441 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: xml_tun.c,v 1.2 2010/03/07 20:15:45 carl Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2007 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ #include "platform.h" #include "xmlparse.h" #define XMLTUN #include "xml_tun.h" #define TEST 0 /* * Here are declarations of the appropriate treatment functions, taking care * of the content of the nodes parsed. This is required to insure binding to the * procedures in the node structure. * * Use the PROC macro to help insure proper declaration. */ PROC(tunnel); PROC(server); PROC(client); PROC(broker); PROC(address); PROC(dns_server); PROC(router); PROC(prefix); PROC(as); PROC(keepalive); /* * Here we define a simple node structure containing only one entry * corresponding to the root node. * * Such a structure must be created for each level of information that * is part of the expected xml content. */ tNode Root[] = STARTLIST NODE(tunnel) ATTR(action) ATTR(type) ATTR(lifetime) ATTR(proxy) ATTR(mtu) ENDNODE ENDLIST tNode Tunnel[] = STARTLIST NODE(server) ENDNODE NODE(client) ENDNODE NODE(broker) ENDNODE ENDLIST tNode Server[] = STARTLIST NODE(address) ATTR(type) ENDNODE NODE(router) ATTR(protocol) ENDNODE ENDLIST tNode Client[] = STARTLIST NODE(address) ATTR(type) ENDNODE NODE(dns_server) ATTR(type) ENDNODE NODE(router) ATTR(protocol) ENDNODE NODE(keepalive) ATTR(interval) ENDNODE ENDLIST tNode Router[] = STARTLIST NODE(prefix) ATTR(length) ENDNODE NODE(dns_server) ATTR(type) ENDNODE NODE(as) ATTR(number) ENDNODE ENDLIST tNode DNSServer[] = STARTLIST NODE(address) ATTR(type) ENDNODE ENDLIST tNode Broker[] = STARTLIST NODE(address) ATTR(type) ENDNODE ENDLIST tNode Keepalive[] = STARTLIST NODE(address) ATTR(type) ENDNODE ENDLIST /* * Support functions */ static int Assign(char *str, char **toStr) { char *tol; if (str == NULL) return 0; /* turn answer to lower case */ /* should help homogenize */ /* scripting */ tol = str; while (*tol != '\0') { *tol = (char)tolower((int)*tol); tol++; } *toStr = (char *) malloc(strlen(str) + 1); if (*toStr == NULL) { printf("Assign: Memory allocation error!\n"); return -1; } strcpy(*toStr, str); return 0; } static int AssignToList(char *str, tLinkedList **toList) { tLinkedList *ll; if (str == NULL) return 0; ll = (tLinkedList *) malloc(sizeof(tLinkedList)); if (ll == NULL) { printf("AssignToList: Memory allocation error!\n"); return -1; } ll->Value = (char *) malloc(strlen(str) + 1); if (ll->Value == NULL) { printf("AssignToList: Memory allocation error!\n"); return -1; } strcpy(ll->Value, str); ll->next = *toList; *toList = ll; return 0; } /* * Here are defined every treatment functions required. use the PROC * macro to help insure proper declaration. * * These event functions update the contain of the tTunnel instance with the * information that is part of the XML structure. */ static tTunnel *theTunnelInfo; static int client, server, router, dns_server, broker, keepalive; PROC(default) { printf("Found <%s>%.10s%s\n", n->name, content, strlen(content) > 10 ? "..." : "", n->name); return 0; } PROC(tunnel) { Assign(n->attributes[0].value, &theTunnelInfo->action ); Assign(n->attributes[1].value, &theTunnelInfo->type ); Assign(n->attributes[2].value, &theTunnelInfo->lifetime); Assign(n->attributes[3].value, &theTunnelInfo->proxy ); Assign(n->attributes[4].value, &theTunnelInfo->mtu ); return XMLParse(content, Tunnel); } PROC(server) { int res; server = 1; res = XMLParse(content, Server); server = 0; return res; } PROC(broker) { int res; broker = 1; res = XMLParse(content, Broker); broker = 0; return res; } PROC(client) { int res; client = 1; res = XMLParse(content, Client); client = 0; return res; } PROC(dns_server) { int res; dns_server = 1; res = XMLParse(content, DNSServer); dns_server = 0; return res; } PROC(router) { int res; router = 1; Assign(n->attributes[0].value, &theTunnelInfo->router_protocol); res = XMLParse(content, Router); router = 0; return res; } PROC(as) { if (client) { Assign(n->attributes[0].value, &theTunnelInfo->client_as); } else if (server) { Assign(n->attributes[0].value, &theTunnelInfo->server_as); } return 0; } PROC(keepalive) { int res; Assign(n->attributes[0].value, &theTunnelInfo->keepalive_interval); keepalive = 1; res = XMLParse(content, Keepalive); keepalive = 0; return res; } PROC(prefix) { Assign(n->attributes[0].value, &theTunnelInfo->prefix_length); Assign(content, &theTunnelInfo->prefix); return 0; } PROC(address) { if (client) { if (keepalive) { if ((!strcmp(n->attributes[0].value, "ipv6")) || (!strcmp(n->attributes[0].value, "ipv4"))) { Assign(content, &theTunnelInfo->keepalive_address); } } else if (router) { if (dns_server) { if (!strcmp(n->attributes[0].value, "ipv4")) { AssignToList(content, &theTunnelInfo->dns_server_address_ipv4); } else if (!strcmp(n->attributes[0].value, "ipv6")) { AssignToList(content, &theTunnelInfo->dns_server_address_ipv6); } } } else if (dns_server) { if (!strcmp(n->attributes[0].value, "ipv6")) { Assign(content, &theTunnelInfo->client_dns_server_address_ipv6); } } else { if (!strcmp(n->attributes[0].value, "ipv4")) { Assign(content, &theTunnelInfo->client_address_ipv4); } else if (!strcmp(n->attributes[0].value, "ipv6")) { Assign(content, &theTunnelInfo->client_address_ipv6); } else if (!strcmp(n->attributes[0].value, "dn")) { Assign(content, &theTunnelInfo->client_dns_name); } } } else if (server) { if (!strcmp(n->attributes[0].value, "ipv4")) { Assign(content, &theTunnelInfo->server_address_ipv4); } else if (!strcmp(n->attributes[0].value, "ipv6")) { Assign(content, &theTunnelInfo->server_address_ipv6); } } else if (broker) { if (!strcmp(n->attributes[0].value, "ipv4")) { AssignToList(content, &theTunnelInfo->broker_redirect_ipv4); } else if (!strcmp(n->attributes[0].value, "ipv6")) { AssignToList(content, &theTunnelInfo->broker_redirect_ipv6); } else if (!strcmp(n->attributes[0].value, "dn")) { AssignToList(content, &theTunnelInfo->broker_redirect_dn); } } return 0; } /* Put here any relevant code... */ void tspFree(char *var) { if (var) free(var); } void tspFreeLinkedList(tLinkedList *list) { if(list) { if(list->next) { tspFreeLinkedList(list->next); free(list->next); list->next = NULL; } if(list->Value) { free(list->Value); list->Value = NULL; } } } void tspClearTunnelInfo(tTunnel *Tunnel) { if (Tunnel) { tspFree(Tunnel->action); tspFree(Tunnel->type); tspFree(Tunnel->lifetime); tspFree(Tunnel->proxy); tspFree(Tunnel->mtu); tspFree(Tunnel->client_address_ipv4); tspFree(Tunnel->client_address_ipv6); tspFree(Tunnel->client_dns_server_address_ipv6); tspFree(Tunnel->client_dns_name); tspFree(Tunnel->server_address_ipv4); tspFree(Tunnel->server_address_ipv6); tspFree(Tunnel->router_protocol); tspFree(Tunnel->prefix_length); tspFree(Tunnel->prefix); tspFree(Tunnel->client_as); tspFree(Tunnel->server_as); tspFree(Tunnel->keepalive_interval); tspFree(Tunnel->keepalive_address); tspFreeLinkedList(Tunnel->dns_server_address_ipv4); tspFreeLinkedList(Tunnel->dns_server_address_ipv6); tspFreeLinkedList(Tunnel->broker_address_ipv4); tspFreeLinkedList(Tunnel->broker_redirect_ipv4); tspFreeLinkedList(Tunnel->broker_redirect_ipv6); tspFreeLinkedList(Tunnel->broker_redirect_dn); } } void ShowList(tLinkedList *l) { int first = 1; while (l != NULL) { if (!first) printf(", "); if (l->Value != NULL) printf("%s", l->Value); l = l->next; first = 0; } } void tspXMLShowInfo(tTunnel *Tunnel) { printf("Parsed Info:\n\n"); printf(" action = [%s]\n", Tunnel->action == NULL ? "" : Tunnel->action ); printf(" type = [%s]\n", Tunnel->type == NULL ? "" : Tunnel->type ); printf(" lifetime = [%s]\n", Tunnel->lifetime == NULL ? "" : Tunnel->lifetime ); printf(" proxy = [%s]\n", Tunnel->proxy == NULL ? "" : Tunnel->proxy ); printf(" mtu = [%s]\n", Tunnel->mtu == NULL ? "" : Tunnel->mtu ); printf(" client address ipv4 = [%s]\n", Tunnel->client_address_ipv4 == NULL ? "" : Tunnel->client_address_ipv4); printf(" client address ipv6 = [%s]\n", Tunnel->client_address_ipv6 == NULL ? "" : Tunnel->client_address_ipv6); printf(" client dns server address ipv6 = [%s]\n", Tunnel->client_dns_server_address_ipv6 == NULL ? "" : Tunnel->client_dns_server_address_ipv6); printf(" client dns name = [%s]\n", Tunnel->client_dns_name == NULL ? "" : Tunnel->client_dns_name ); printf(" server address ipv4 = [%s]\n", Tunnel->server_address_ipv4 == NULL ? "" : Tunnel->server_address_ipv4); printf(" server address ipv6 = [%s]\n", Tunnel->server_address_ipv6 == NULL ? "" : Tunnel->server_address_ipv6); printf(" router protocol = [%s]\n", Tunnel->router_protocol == NULL ? "" : Tunnel->router_protocol ); printf(" prefix length = [%s]\n", Tunnel->prefix_length == NULL ? "" : Tunnel->prefix_length ); printf(" prefix = [%s]\n", Tunnel->prefix == NULL ? "" : Tunnel->prefix ); printf(" client as number = [%s]\n", Tunnel->client_as == NULL ? "" : Tunnel->client_as ); printf(" server as number = [%s]\n", Tunnel->server_as == NULL ? "" : Tunnel->server_as ); printf(" keepalive interval = [%s]\n", Tunnel->keepalive_interval == NULL ? "" : Tunnel->keepalive_interval ); printf(" keepalive address = [%s]\n", Tunnel->keepalive_address == NULL ? "" : Tunnel->keepalive_address); printf(" dns server addresse(s) ipv4 = ["); ShowList(Tunnel->dns_server_address_ipv4); printf("]\n"); printf(" dns server addresse(s) ipv6 = ["); ShowList(Tunnel->dns_server_address_ipv6); printf("]\n"); printf(" broker addresse(s) ipv4 = ["); ShowList(Tunnel->broker_address_ipv4); printf("]\n"); printf(" broker redirect ipv4 = ["); ShowList(Tunnel->broker_redirect_ipv4); printf("]\n"); printf(" broker redirect ipv6 = ["); ShowList(Tunnel->broker_redirect_ipv6); printf("]\n"); printf(" broker redirect dn = ["); ShowList(Tunnel->broker_redirect_dn); printf("]\n"); } int tspXMLParse(char *Data, tTunnel *Tunnel) { tspClearTunnelInfo(Tunnel); client = server = router = dns_server = broker = 0; theTunnelInfo = Tunnel; return XMLParse(Data, Root); } #if TEST char *testData = " \n" " \n" "
206.123.31.114
\n" "
3ffe:b00:c18:ffff:0000:0000:0000:0000
\n" " \n" " \n" " \n" "
\n" " \n" "
1.1.1.1
\n" "
3ffe:b00:c18:ffff::0000:0000:0000:0001
\n" "
userid.domain
\n" " \n" " 3ffe:0b00:c18:1234::\n" " \n" " \n" "
2.3.4.5
\n" "
2.3.4.6
\n" "
3ffe:0c00::1
\n" "
\n" "
\n" "
::
\n" "
\n" "
\n"; main() { tTunnel t; static char string[5000]; int res; printf("Start....\n"); memset(&t, 0, sizeof(t)); strcpy(string, testData); res = tspXMLParse(string, &t); if (res != 0) { printf("Result = %d\n", res); } tspXMLShowInfo(&t); return 0; } #endif /*----- xmltsp.c -----------------------------------------------------------------------*/ gogoc-1_2-RELEASE/gogoc-tsp/src/xml/xmlparse.c0100644000000000000000000001517711301544627017616 0ustar rootroot/* ----------------------------------------------------------------------------- $Id: xmlparse.c,v 1.1 2009/11/20 16:53:43 jasminko Exp $ ----------------------------------------------------------------------------- Copyright (c) 2001-2005 gogo6 Inc. All rights reserved. For license information refer to CLIENT-LICENSE.TXT ----------------------------------------------------------------------------- */ #include "platform.h" #define _XMLParse_ #include "xmlparse.h" #ifndef XML_DEBUG #define XML_DEBUG 0 #endif int debug = XML_DEBUG; static tNode * findNode(char *name, tNode nodes[]) { tNode *n; n = nodes; while (n->name[0]) { if (strcmp(name, n->name) == 0) return n; n++; } return 0; } static tAttribute *findAttribute(char *name, tAttribute attributes[]) { tAttribute *a; a = attributes; while (a->name[0]) { if (strcmp(name, a->name) == 0) return a; a++; } return 0; } static int SkipBlanks(char *str, int pos) { while (str[pos] && ((str[pos] == ' ') || (str[pos] == '\t') || (str[pos] == '\r') || (str[pos] == '\n'))) { pos += 1; } return pos; } /* * return values: * * 0 : Success * n : Parsing error (position in the string where the parsing error occured) */ int XMLParse(char *str, tNode nodes[]) { char *string; int pos; int simple; /* 1 = complete node in a single <> like */ char *tagName; char *attrName; char *attrValue; char *endTag; tNode *n; tAttribute *a; char endToken[100]; int res; if (debug) printf("Beginning of XMLParse\n"); string = (char *) malloc(strlen(str) + 1); if (!string) { fprintf(stderr, "xmlparse: Error malloc\n"); return -1; } strcpy(string, str); pos = 0; while (string[pos]) { simple = 0; pos = SkipBlanks(string, pos); /* * If not at the beginning of a node tag, return with current position */ if (string[pos] == 0) { free(string); return 0; } if (string[pos] != '<') { free(string); return pos; } pos += 1; /* * We are not expecting here the end node (like ) */ if (!isalpha(string[pos])) { free(string); return pos; } /* * We now retrieve the node name and the attributes. * It must be ended by a space when there is some attributes, * a '/' if it's a simple node, or '>'. */ tagName = &string[pos]; while (string[pos] && (isalnum(string[pos]) || (string[pos] == '_'))) { pos += 1; } if (!string[pos]) { free(string); return pos; } if (string[pos] == '/') { simple = 1; string[pos] = 0; pos += 1; if (string[pos] != '>') { free(string); return pos; } string[pos] = 0; } else if (string[pos] == ' ') { string[pos] = 0; pos += 1; } else if (string[pos] == '>') { string[pos] = 0; /* we do not advance pos as it will indicate if '>' found */ } else { free(string); return pos; } /* * The nodename must at least contain one character */ if (!tagName[0]) { free(string); return pos; } if (debug) printf("tagName = %s\n", tagName); /* * Here we try to find the node structure corresponding to the * tag read from the xml containt */ if ((n = findNode(tagName, nodes)) != NULL) { /* * We found the node structure... */ if (debug) printf("Found corresponding structure: %s\n", n->name); /* * A null character indicate that there is no attribute available */ if (string[pos] == 0) { pos += 1; } else { /* * There may be some attributes. Parse them... */ pos = SkipBlanks(string, pos); while (isalpha(string[pos])) { attrName = &string[pos]; while (string[pos] && (isalnum(string[pos]) || (string[pos] == '_'))) pos += 1; if (string[pos] != '=') { free(string); return pos; } string[pos] = 0; pos += 1; a = findAttribute(attrName, n->attributes); if (debug) printf("Attribute %sfound in structure: %s", a == NULL ? "not " : "", attrName); if (string[pos] != '"') { free(string); return pos; } pos += 1; attrValue = &string[pos]; while (string[pos] && (string[pos] != '\n') && (string[pos] != '\r') && (string[pos] != '>' ) && (string[pos] != '"' )) pos += 1; if (string[pos] != '"') { free(string); return pos; } string[pos] = 0; pos += 1; if (a != NULL) { a->value = attrValue; } pos = SkipBlanks(string, pos); } if (string[pos] == '/') { simple = 1; pos += 1; } if (string[pos] == '>') { pos += 1; } else { free(string); return pos; } } } else { /* * There is no node structure entry corresponding to the tag found * we just skip the contain of the node up to the end of it. */ if (debug) printf("No structure definition: %s\n", tagName); if (string[pos] == 0) { pos += 1; } else { while (string[pos] && (string[pos] != '>')) pos += 1; if (string[pos] == '>') { pos += 1; } } if ((string[pos] == 0) && !simple) { free(string); return pos; } } if (simple) { /* * Call the processing function, if it exists... */ if (n && n->p) { res = (*n->p)(n, &string[pos]); if (res) { free(string); if (res > 0) res += pos; return res; } } } else { strcpy(endToken, ""); endTag = strstr(&string[pos], endToken); if (debug) printf("Computed end tag: %s\n", endToken); if (endTag) { if (debug) printf("Found node end: %s\n", endToken); *endTag = 0; /* * Call the processing function, if it exists... */ if (n && n->p) { res = (*n->p)(n, &string[pos]); if (res) { free(string); if (res > 0) res += pos; return res; } } pos = (int)(endTag - string) + (int)strlen(endToken); } else { free(string); return pos; } } //return 0; } free(string); return 0; } /*----- xmlparse.c --------------------------------------------------------------------*/ gogoc-1_2-RELEASE/gogoc-tsp/template/0040755000000000000000000000000011346561546016043 5ustar rootrootgogoc-1_2-RELEASE/gogoc-tsp/template/Makefile0100644000000000000000000000144211301544627017471 0ustar rootroot# ########################################################################### # # $Id: Makefile,v 1.1 2009/11/20 16:53:43 jasminko Exp $ # # This source code copyright (c) gogo6 Inc. 2005,2007. # # LICENSE NOTICE: You may use and modify this source code only if you # have executed a valid license agreement with gogo6 Inc. granting # you the right to do so, the said license agreement governing such # use and modifications. Copyright or other intellectual property # notices are not to be removed from the source code. # # ########################################################################### # all: install: @echo "Installing templates ..." @for template_var in README $(PLATFORM).sh; do \ cp $${template_var} $(INSTALL_TEMPL)/$${template_var}; \ done clean: gogoc-1_2-RELEASE/gogoc-tsp/template/README0100644000000000000000000000171211346561546016721 0ustar rootroot# $Id: README,v 1.1 2009/11/20 16:53:43 jasminko Exp $ # # This source code copyright (c) gogo6 Inc. 2005,2007. # # LICENSE NOTICE: You may use and modify this source code only if you # have executed a valid license agreement with gogo6 Inc. granting # you the right to do so, the said license agreement governing such # use and modifications. Copyright or other intellectual property # notices are not to be removed from the source code. # This is the client scripts executed by the user to configure the tunnel. Files description : openbsd.sh : Template for OpenBSD freebsd.sh : Template for FreeBSD netbsd.sh : Template for NetBSD linux.sh : Template for Linux solaris.sh : Template for Solaris darwin.sh : Template for Mac openwrt.sh : Template script for OpenWRT cisco.{cmd|sh} : Template to create a cisco configuration file. variables_environ : list of environment variables used by scripts. gogoc-1_2-RELEASE/gogoc-tsp/template/cisco.bat0100644000000000000000000000366111301544630017620 0ustar rootroot@echo off Rem #$Id Rem Rem Copyright (c) 2001-2003,2006,2007 gogo6 Inc. All rights reserved. Rem For license information refer to CLIENT-LICENSE.TXT Rem ************************************** Rem * Tunnel Server Protocol version 1.0 * Rem * Host configuration script * Rem * For Cisco Routers * Rem * Lanched from Windows * Rem ************************************** Rem * This script keeps a log set LOG=NUL set LOG2=NUL set CISCO="%TSP_HOME_DIR%\CISCOIPv6.TXT" if %TSP_VERBOSE% == 2 set LOG2=CON if not %TSP_VERBOSE% == 0 set LOG=CON date /T > %LOG% time /T > %LOG% Rem ***** Script an IPv6 tunnel ********** :begin echo IPv4 tunnel server address configured : %TSP_SERVER_ADDRESS_IPV4% > %LOG% echo ! Add these lines to your Cisco configuration > %CISCO% echo ! Script launched from a Microsoft environment >> %CISCO% echo ! >> %CISCO% echo ipv6 unicast-routing >> %CISCO% echo ! >> %CISCO% echo interface %TSP_TUNNEL_INTERFACE% >> %CISCO% echo ipv6 address %TSP_CLIENT_ADDRESS_IPV6%/128 >> %CISCO% echo tunnel source %TSP_CLIENT_ADDRESS_IPv4% >> %CISCO% echo tunnel destination %TSP_SERVER_ADDRESS_IPV4% >> %CISCO% echo tunnel mode ipv6ip >> %CISCO% echo ! >> %CISCO% echo ipv6 route ::/0 %TSP_TUNNEL_INTERFACE% >> %CISCO% if %TSP_HOST_TYPE% == router GOTO router_config goto success :router_config echo cisco Router will be configured as IPv6 router and it will do router advertisements for autoconfiguration > %LOG% echo Configuring IPv6_forwading on network interface > %LOG% echo ! >> %CISCO% echo interface %TSP_HOME_INTERFACE% >> %CISCO% echo ipv6 address %TSP_PREFIX%:1::/64 eui-64 >> %CISCO% echo ipv6 nd prefix-advertisement %TSP_PREFIX%:1::/64 43200 43200 onlink autoconfig >> %CISCO% goto success :success Echo Cisco IPv6 configuration done and saved in this file : %CISCO% Echo Look the file and apply these configuration lines to your Cisco configuration goto end :end Echo End of the script gogoc-1_2-RELEASE/gogoc-tsp/template/cisco.sh0100644000000000000000000000372211301544630017462 0ustar rootroot#!/bin/sh # Copyright (c) 2001-2003,2006,2007 gogo6 Inc. All rights reserved. # # For license information refer to CLIENT-LICENSE.TXT # # **************************************** # * Tunnel Server Protocol version 1.0 * # * Host configuration script * # * For Cisco Routers * # * Lanched from a unix OS * # **************************************** # * This script keeps a log * # **************************************** CISCO="$TSP_HOME_DIR/ciscoipv6.txt" if [ -z $TSP_VERBOSE ]; then TSP_VERBOSE=0 fi if [ $TSP_VERBOSE -ge 1 ]; then LOG="/dev/stdout" else LOG="/dev/null" fi # ***** Script an IPv6 tunnel ********** echo "IPv4 tunnel server address configured : $TSP_SERVER_ADDRESS_IPV4" > $LOG echo "! Add these lines to your Cisco configuration" > $CISCO echo "! Script launched from a `uname` environment" >> $CISCO echo "! Generated `date`" >> $CISCO echo "!" >> $CISCO echo "ipv6 unicast-routing" >> $CISCO echo "!" >> $CISCO echo "interface $TSP_TUNNEL_INTERFACE" >> $CISCO echo " ipv6 address $TSP_CLIENT_ADDRESS_IPV6/128" >> $CISCO echo " tunnel source $TSP_CLIENT_ADDRESS_IPV4" >> $CISCO echo " tunnel destination $TSP_SERVER_ADDRESS_IPV4" >> $CISCO echo " tunnel mode ipv6ip" >> $CISCO echo "!" >> $CISCO echo "ipv6 route ::/0 $TSP_TUNNEL_INTERFACE" >> $CISCO if [ X"$TSP_HOST_TYPE" = X"router" ]; then echo "cisco Router will be configured as IPv6 router and it will do router advertisements for autoconfiguration" > $LOG echo "Configuring IPv6_forwarding on network interface" > $LOG echo "!" >> $CISCO echo "interface $TSP_HOME_INTERFACE" >> $CISCO echo " ipv6 address $TSP_PREFIX:1::/64 eui-64" >> $CISCO echo " ipv6 nd prefix-advertisement $TSP_PREFIX:1::/64 43200 43200 onlink autoconfig" >> $CISCO fi echo "Cisco IPv6 configuration generated and saved in this file : $CISCO" > $LOG echo "Look at the file and apply these configuration lines to your Cisco configuration" > $LOG echo "End of the script" > $LOG gogoc-1_2-RELEASE/gogoc-tsp/template/darwin.sh0100644000000000000000000001277611344777405017676 0ustar rootroot#!/bin/sh -x # # $Id: darwin.sh,v 1.3 2010/03/07 19:31:17 carl Exp $ # # This source code copyright (c) gogo6 Inc. 2002-2005. # # For license information refer to CLIENT-LICENSE.TXT # LANGUAGE=C if [ -z $TSP_VERBOSE ]; then TSP_VERBOSE=0 fi KillProcess() { if [ ! -z $TSP_VERBOSE ]; then if [ $TSP_VERBOSE -ge 2 ]; then echo killing $* fi fi PIDs=`ps axww | grep $1 | grep -v grep | awk '{ print $1;}'` echo $PIDs for PID in $PIDs do if [ ! -z $PID ]; then kill $PID fi done } Display() { if [ -z $TSP_VERBOSE ]; then return; fi if [ $TSP_VERBOSE -lt $1 ]; then return; fi shift echo $* } Exec() { if [ ! -z $TSP_VERBOSE ]; then if [ $TSP_VERBOSE -ge 2 ]; then echo $* fi fi $* # Execute command if [ $? -ne 0 ]; then echo "Error while executing $1" echo " Command: $*" exit 1 fi } ExecNoCheck() { if [ ! -z $TSP_VERBOSE ]; then if [ $TSP_VERBOSE -ge 2 ]; then echo $* fi fi $* # Execute command } # Programs localization Display 1 "--- Start of configuration script. ---" Display 1 "Script: " `basename $0` ifconfig=/sbin/ifconfig route=/sbin/route rtadvd=/usr/sbin/rtadvd sysctl=/usr/sbin/sysctl resolv_conf=/etc/resolv.conf if [ -z $TSP_HOME_DIR ]; then echo "TSP_HOME_DIR variable not specified!;" exit 1 fi if [ ! -d $TSP_HOME_DIR ]; then echo "Error : directory $TSP_HOME_DIR does not exist" exit 1 fi # if [ -z $TSP_HOST_TYPE ]; then echo Error: TSP_HOST_TYPE not defined. exit 1 fi ############################################################################# # Run tunnel destruction script. # if [ X"${TSP_OPERATION}" = X"TSP_TUNNEL_TEARDOWN" ]; then Display 1 Tunnel tear down starting... # # DNS Display 1 "Removing DNS server" Display 1 "NOTE: Adjust template script to perform actions" # ExecNoCheck rm ${resolv_conf} # if [ -f ${resolv_conf}.bak ]; then # ExecNoCheck cp ${resolv_conf}.bak ${resolv_conf} # ExecNoCheck rm ${resolv_conf}.bak # fi # Router deconfiguration. if [ X"${TSP_HOST_TYPE}" = X"router" ]; then # Remove prefix routing on TSP_HOME_INTERFACE ExecNoCheck $route delete -inet6 $TSP_PREFIX:: # Remove blackhole. if [ X"${TSP_PREFIXLEN}" != X"64" ]; then ExecNoCheck $route delete -inet6 $TSP_PREFIX:: -prefixlen $TSP_PREFIXLEN ::1 fi # Remove static IPv6 address ExecNoCheck $ifconfig $TSP_HOME_INTERFACE inet6 $TSP_PREFIX::1 delete # Kill router advertisement daemon KillProcess rtadvd fi # Delete default IPv6 route ExecNoCheck $route delete -inet6 default # Delete the interface IPv6 configuration list=`$ifconfig $TSP_TUNNEL_INTERFACE | grep inet6 | awk '{print $2}' | grep -v '^fe80'` for ipv6address in $list do Exec $ifconfig $TSP_TUNNEL_INTERFACE inet6 $ipv6address delete done # Delete tunnel. ExecNoCheck $ifconfig $TSP_TUNNEL_INTERFACE deletetunnel Display 1 Tunnel tear down completed. exit 0 fi ############################################################################# # Tunnel over V4 # if [ X"${TSP_HOST_TYPE}" = X"host" ] || [ X"${TSP_HOST_TYPE}" = X"router" ]; then # # Configured tunnel config (IPv4) Display 1 Setting up interface $TSP_TUNNEL_INTERFACE # Delete first any previous tunnel. ExecNoCheck $ifconfig $TSP_TUNNEL_INTERFACE deletetunnel Exec $ifconfig $TSP_TUNNEL_INTERFACE tunnel $TSP_CLIENT_ADDRESS_IPV4 $TSP_SERVER_ADDRESS_IPV4 # # Configured tunnel config (IPv6) # Check if the interface already has an IPv6 configuration list=`$ifconfig $TSP_TUNNEL_INTERFACE | grep inet6 | awk '{print $2}' | grep -v '^fe80'` for ipv6address in $list do Exec $ifconfig $TSP_TUNNEL_INTERFACE inet6 $ipv6address delete done Exec $ifconfig $TSP_TUNNEL_INTERFACE inet6 $TSP_CLIENT_ADDRESS_IPV6 $TSP_SERVER_ADDRESS_IPV6 prefixlen $TSP_TUNNEL_PREFIXLEN alias Exec $ifconfig $TSP_TUNNEL_INTERFACE mtu 1280 # # Default route Display 1 Adding default route to $TSP_SERVER_ADDRESS_IPV6 # Delete any default IPv6 route, and add ours. ExecNoCheck $route delete -inet6 default Exec $route add -inet6 default $TSP_SERVER_ADDRESS_IPV6 # # DNS if [ X"${TSP_CLIENT_DNS_ADDRESS_IPV6}" != X"" ]; then Display 1 "Adding DNS server" Display 1 "NOTE: Adjust template script to perform actions" # ExecNoCheck cp ${resolv_conf} ${resolv_conf}.bak # echo "echo \"nameserver ${TSP_CLIENT_DNS_ADDRESS_IPV6}\" | cat - ${resolv_conf}.bak >${resolv_conf}" # echo "nameserver ${TSP_CLIENT_DNS_ADDRESS_IPV6}" | cat - ${resolv_conf}.bak >${resolv_conf} fi fi # Router configuration if host_type=router if [ X"${TSP_HOST_TYPE}" = X"router" ]; then Display 1 "Router configuration" # Kernel configuration. Exec $sysctl -w net.inet6.ip6.forwarding=1 # ipv6_forwarding enabled Exec $sysctl -w net.inet6.ip6.accept_rtadv=0 # routed must disable any router advertisement incoming # Add the IPv6 PREFIX::1 address to advertising interface. Exec $ifconfig $TSP_HOME_INTERFACE inet6 $TSP_PREFIX::1 prefixlen 64 # If prefix length is not 64 bits, then blackhole the remaining part. # Because we're only advertising the first /64 part of the prefix. if [ X"${TSP_PREFIXLEN}" != X"64" ]; then ExecNoCheck $route add -inet6 $TSP_PREFIX:: -prefixlen $TSP_PREFIXLEN ::1 fi # Stop and start router advertisement daemon. KillProcess rtadvd Exec $rtadvd $TSP_HOME_INTERFACE fi Display 1 "--- End of configuration script. ---" exit 0 gogoc-1_2-RELEASE/gogoc-tsp/template/freebsd.sh0100644000000000000000000002071011344777405020007 0ustar rootroot#!/bin/sh #$Id: freebsd.sh,v 1.3 2010/03/07 19:31:17 carl Exp $ # # This source code copyright (c) gogo6 Inc. 2002-2004,2007. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License (GPL) Version 2, # June 1991 as published by the Free Software Foundation. # # For license information refer to CLIENT-LICENSE.TXT # LANGUAGE=C if [ -z $TSP_VERBOSE ]; then TSP_VERBOSE=0 fi KillProcess() { if [ ! -z $TSP_VERBOSE ]; then if [ $TSP_VERBOSE -ge 2 ]; then echo killing $* fi fi PID=`ps axww | grep $1 | grep -v grep | awk '{ print $1;}'` echo $PID if [ ! -z $PID ]; then kill $PID fi } Display() { if [ -z $TSP_VERBOSE ]; then return; fi if [ $TSP_VERBOSE -lt $1 ]; then return; fi shift echo $* } Exec() { if [ ! -z $TSP_VERBOSE ]; then if [ $TSP_VERBOSE -ge 2 ]; then echo $* fi fi $* # Execute command if [ $? -ne 0 ]; then echo "Error while executing $1" echo " Command: $*" exit 1 fi } ExecNoCheck() { if [ ! -z $TSP_VERBOSE ]; then if [ $TSP_VERBOSE -ge 2 ]; then echo $* fi fi $* # Execute command } # Program localization Display 1 '--- Start of configuration script. ---' Display 1 "Script: " `basename $0` gifconfig=/usr/sbin/gifconfig ifconfig=/sbin/ifconfig route=/sbin/route rtadvd=/usr/sbin/rtadvd sysctl=/sbin/sysctl # find the release rel=4 for freebsd4.X, =5 for freebsd5.X rel=`/usr/bin/uname -r | cut -f1 -d"."` resolv_conf=/etc/resolv.conf if [ -z $TSP_HOME_DIR ]; then echo "TSP_HOME_DIR variable not specified!;" exit 1 fi if [ ! -d $TSP_HOME_DIR ]; then echo "Error : directory $TSP_HOME_DIR does not exist" exit 1 fi # if [ -z $TSP_HOST_TYPE ]; then echo Error: TSP_HOST_TYPE not defined. exit 1 fi ################################# # Run tunnel destruction script. ################################# if [ X"${TSP_OPERATION}" = X"TSP_TUNNEL_TEARDOWN" ]; then Display 1 Tunnel tear down starting... # # DNS Display 1 "Removing DNS server" Display 1 "NOTE: Adjust template script to perform actions" # ExecNoCheck rm ${resolv_conf} # if [ -f ${resolv_conf}.bak ]; then # ExecNoCheck cp ${resolv_conf}.bak ${resolv_conf} # ExecNoCheck rm ${resolv_conf}.bak # fi # Router deconfiguration. if [ X"${TSP_HOST_TYPE}" = X"router" ]; then # Remove prefix routing on TSP_HOME_INTERFACE ExecNoCheck $route delete -inet6 $TSP_PREFIX:: # Remove blackhole. if [ X"${TSP_PREFIXLEN}" != X"64" ]; then ExecNoCheck $route delete -inet6 $TSP_PREFIX:: -prefixlen $TSP_PREFIXLEN -interface lo0 fi # Remove static IPv6 address ExecNoCheck $ifconfig $TSP_HOME_INTERFACE inet6 $TSP_PREFIX::1 delete # Kill router advertisement daemon gracefully (SIGTERM) KillProcess rtadvd fi # Delete any routes if [ X"${TSP_TUNNEL_MODE}" = X"v6v4" ] || [ X"${TSP_TUNNEL_MODE}" = X"v6udpv4" ]; then # Delete any default IPv6 route ExecNoCheck $route delete -inet6 default else # Delete default IPv4 route ExecNoCheck $route delete -inet default fi # Check if interface exists and remove it $ifconfig $TSP_TUNNEL_INTERFACE >/dev/null 2>/dev/null if [ $? -eq 0 ]; then if [ X"${TSP_TUNNEL_MODE}" = X"v6v4" ] || [ X"${TSP_TUNNEL_MODE}" = X"v6udpv4" ]; then # Delete interface IPv6 configuration. list=`$ifconfig $TSP_TUNNEL_INTERFACE | grep inet6 | awk '{print $2}' | grep -v '^fe80'` for ipv6address in $list do ExecNoCheck $ifconfig $TSP_TUNNEL_INTERFACE inet6 $ipv6address delete done else # Delete interface IPv4 configuration. list=`$ifconfig $TSP_TUNNEL_INTERFACE | grep -v inet6 | grep inet | awk '{print $2}'` for ipv4address in $list do ExecNoCheck $ifconfig $TSP_TUNNEL_INTERFACE inet $ipv4address delete done fi # Bring interface down and TRY to destroy it (FreeBSD 6.2 STABLE and up). ExecNoCheck $ifconfig $TSP_TUNNEL_INTERFACE down ExecNoCheck $ifconfig $TSP_TUNNEL_INTERFACE destroy fi Display 1 Tunnel tear down completed. exit 0 fi ################## # Tunnel over V4 # ################## if [ X"${TSP_TUNNEL_MODE}" = X"v6v4" ] || [ X"${TSP_TUNNEL_MODE}" = X"v6udpv4" ]; then if [ X"${TSP_HOST_TYPE}" = X"host" ] || [ X"${TSP_HOST_TYPE}" = X"router" ]; then # # Configured tunnel config (IPv4) Display 1 Setting up interface $TSP_TUNNEL_INTERFACE # first delete any previous tunnel if [ X"${TSP_TUNNEL_MODE}" = X"v6v4" ]; then # Check if interface exists and remove it $ifconfig $TSP_TUNNEL_INTERFACE >/dev/null 2>/dev/null if [ $? -eq 0 ]; then Exec $ifconfig $TSP_TUNNEL_INTERFACE destroy fi Exec $ifconfig $TSP_TUNNEL_INTERFACE create if [ $rel -eq 4 ]; then Exec $gifconfig $TSP_TUNNEL_INTERFACE $TSP_CLIENT_ADDRESS_IPV4 $TSP_SERVER_ADDRESS_IPV4 else Exec $ifconfig $TSP_TUNNEL_INTERFACE tunnel $TSP_CLIENT_ADDRESS_IPV4 $TSP_SERVER_ADDRESS_IPV4 fi else # Check if the interface already has an IPv6 configuration list=`$ifconfig $TSP_TUNNEL_INTERFACE | grep inet6 | awk '{print $2}' | grep -v '^fe80'` for ipv6address in $list do Exec $ifconfig $TSP_TUNNEL_INTERFACE inet6 $ipv6address delete done Exec $ifconfig $TSP_TUNNEL_INTERFACE up fi # # Configured tunnel config (IPv6) Exec $ifconfig $TSP_TUNNEL_INTERFACE inet6 $TSP_CLIENT_ADDRESS_IPV6 $TSP_SERVER_ADDRESS_IPV6 prefixlen $TSP_TUNNEL_PREFIXLEN alias Exec $ifconfig $TSP_TUNNEL_INTERFACE mtu 1280 # # Default route Display 1 Adding default route to $TSP_SERVER_ADDRESS_IPV6 # Delete any default IPv6 route first ExecNoCheck $route delete -inet6 default Exec $route add -inet6 default $TSP_SERVER_ADDRESS_IPV6 fi # # DNS if [ X"${TSP_CLIENT_DNS_ADDRESS_IPV6}" != X"" ]; then Display 1 "Adding DNS server" Display 1 "NOTE: Adjust template script to perform actions" # ExecNoCheck cp ${resolv_conf} ${resolv_conf}.bak # echo "echo \"nameserver ${TSP_CLIENT_DNS_ADDRESS_IPV6}\" | cat - ${resolv_conf}.bak >${resolv_conf}" # echo "nameserver ${TSP_CLIENT_DNS_ADDRESS_IPV6}" | cat - ${resolv_conf}.bak >${resolv_conf} fi # Router configuration if required if [ X"${TSP_HOST_TYPE}" = X"router" ]; then Display 1 "Router configuration" Display 1 "Kernel setup" if [ X"${TSP_PREFIXLEN}" != X"64" ]; then ExecNoCheck $route add -inet6 $TSP_PREFIX:: -prefixlen $TSP_PREFIXLEN -interface lo0 fi Exec $sysctl -w net.inet6.ip6.forwarding=1 # ipv6_forwarding enabled Exec $sysctl -w net.inet6.ip6.accept_rtadv=0 # routed must disable any incoming router advertisement Display 1 "Adding prefix to $TSP_HOME_INTERFACE" Exec $ifconfig $TSP_HOME_INTERFACE inet6 $TSP_PREFIX::1 prefixlen 64 # Router advertisement startup KillProcess rtadvd Exec $rtadvd $TSP_HOME_INTERFACE fi ################## # Tunnel over V6 # ################## elif [ X"${TSP_TUNNEL_MODE}" = X"v4v6" ]; then if [ X"${TSP_HOST_TYPE}" = X"host" ] || [ X"${TSP_HOST_TYPE}" = X"router" ]; then # # Configured tunnel config (IPv4 or IPv6) Display 1 Setting up interface $TSP_TUNNEL_INTERFACE # Check if interface exists $ifconfig $TSP_TUNNEL_INTERFACE >/dev/null 2>/dev/null if [ $? -eq 0 ]; then # Interface exists, we destroy it completly instead of deconfiguring it Exec $ifconfig $TSP_TUNNEL_INTERFACE destroy fi Exec $ifconfig $TSP_TUNNEL_INTERFACE create #configure v4v6 tunnel Exec $ifconfig $TSP_TUNNEL_INTERFACE inet6 tunnel $TSP_CLIENT_ADDRESS_IPV6 $TSP_SERVER_ADDRESS_IPV6 Exec $ifconfig $TSP_TUNNEL_INTERFACE $TSP_CLIENT_ADDRESS_IPV4/$TSP_TUNNEL_PREFIXLEN $TSP_SERVER_ADDRESS_IPV4 #Validate if 1280 really is the good value here Exec $ifconfig $TSP_TUNNEL_INTERFACE mtu 1280 Display 1 "deleting actual v4 default route" ExecNoCheck $route delete -inet default Display 1 Adding v4 default route to $TSP_SERVER_ADDRESS_IPV4 Exec $route add default $TSP_SERVER_ADDRESS_IPV4 fi # Router configuration if required if [ X"${TSP_HOST_TYPE}" = X"router" ]; then Display 1 "Router configuration" # TODO: Enable v4 forwarding fi fi Display 1 '--- End of configuration script. ---' exit 0 gogoc-1_2-RELEASE/gogoc-tsp/template/gogocpe.sh0100644000000000000000000001531311344777256020027 0ustar rootroot#!/bin/sh # # $Id: gogocpe.sh,v 1.2 2010/03/07 19:29:50 carl Exp $ # # This source code copyright (c) gogo6 Inc. 2002-2007. # # For license information refer to CLIENT-LICENSE.TXT # # Note: IPV6 support and tun Support must be enabled before calling this script. # LANGUAGE=C if [ -z $TSP_VERBOSE ]; then TSP_VERBOSE=0 fi KillProcess() { if [ ! -z $TSP_VERBOSE ]; then if [ $TSP_VERBOSE -ge 2 ]; then echo killing $* fi fi PID=`ps axww | grep $1 | grep -v grep | awk '{ print $1;}'` echo $PID if [ ! -z $PID ]; then kill $PID fi } Display() { if [ -z $TSP_VERBOSE ]; then return; fi if [ $TSP_VERBOSE -lt $1 ]; then return; fi shift echo "$*" } Exec() { if [ ! -z $TSP_VERBOSE ]; then if [ $TSP_VERBOSE -ge 2 ]; then echo $* fi fi $* # Execute command if [ $? -ne 0 ]; then echo "Error while executing $1" echo " Command: $*" exit 1 fi } ExecNoCheck() { if [ ! -z $TSP_VERBOSE ]; then if [ $TSP_VERBOSE -ge 2 ]; then echo $* fi fi $* # Execute command } # Program localization Display 1 "--- Start of configuration script. ---" Display 1 "Script: " `basename $0` ifconfig=/sbin/ifconfig route=/sbin/route ipconfig=/usr/sbin/ip radvd_script=/etc/init.d/radvd radvd_conf=/var/etc/radvd.conf resolv_conf=/var/resolv.conf.auto if [ -z $TSP_HOME_DIR ]; then echo "TSP_HOME_DIR variable not specified!;" exit 1 fi if [ ! -d $TSP_HOME_DIR ]; then echo "Error : directory $TSP_HOME_DIR does not exist" exit 1 fi # if [ -z $TSP_HOST_TYPE ]; then echo Error: TSP_HOST_TYPE not defined. exit 1 fi ################################# # Run tunnel destruction script. ################################# if [ X"${TSP_OPERATION}" = X"TSP_TUNNEL_TEARDOWN" ]; then Display 1 Tunnel tear down starting... # Remove tunnel if [ X"${TSP_TUNNEL_MODE}" = X"v6v4" ]; then ExecNoCheck $ipconfig tunnel del $TSP_TUNNEL_INTERFACE fi # Remove addresses PREF=`echo $TSP_CLIENT_ADDRESS_IPV6 | sed "s/:0*/:/g" |cut -d : -f1-2` OLDADDR=`$ifconfig $TSP_TUNNEL_INTERFACE | grep "inet6.* $PREF" | sed -e "s/^.*inet6 addr: //" -e "s/ Scope.*\$//"` if [ ! -z $OLDADDR ]; then Display 1 "Removing old IPv6 address $OLDADDR" Exec $ifconfig $TSP_TUNNEL_INTERFACE del $OLDADDR fi # Bring interface down. ExecNoCheck $ifconfig $TSP_TUNNEL_INTERFACE down # Delete any IPv6 route ExecNoCheck $route -A inet6 del ::/0 2>/dev/null # delete old default route ExecNoCheck $route -A inet6 del 2000::/3 2>/dev/null # delete old gw route # # DNS Display 1 "Removing DNS server" ExecNoCheck rm ${resolv_conf} if [ -f ${resolv_conf}.bak ]; then ExecNoCheck cp ${resolv_conf}.bak ${resolv_conf} ExecNoCheck rm ${resolv_conf}.bak fi # Router deconfiguration. if [ X"${TSP_HOST_TYPE}" = X"router" ]; then # Remove prefix routing on TSP_HOME_INTERFACE ExecNoCheck $route -A inet6 del $TSP_PREFIX::/$TSP_PREFIXLEN # Remove address from TSP HOME INTERFACE OLDADDR=`$ifconfig $TSP_HOME_INTERFACE | grep "inet6.* $PREF" | sed -e "s/^.*inet6 addr: //" -e "s/ Scope.*\$//"` if [ ! -z $OLDADDR ]; then Display 1 "Removing old IPv6 address $OLDADDR" Exec $ifconfig $TSP_HOME_INTERFACE del $OLDADDR fi # Kill router advertisement daemon $radvd_script stop > /dev/null 2>&1 fi Display 1 Tunnel tear down completed. exit 0 fi if [ X"${TSP_HOST_TYPE}" = X"host" ] || [ X"${TSP_HOST_TYPE}" = X"router" ]; then # # Configured tunnel config (IPv6) Display 1 "$TSP_TUNNEL_INTERFACE setup" if [ X"${TSP_TUNNEL_MODE}" = X"v6v4" ]; then Display 1 "Setting up link to $TSP_SERVER_ADDRESS_IPV4" ExecNoCheck $ipconfig tunnel del $TSP_TUNNEL_INTERFACE ExecNoCheck sleep 1 Exec $ipconfig tunnel add $TSP_TUNNEL_INTERFACE mode sit ttl 64 remote $TSP_SERVER_ADDRESS_IPV4 fi Exec $ifconfig $TSP_TUNNEL_INTERFACE up PREF=`echo $TSP_CLIENT_ADDRESS_IPV6 | sed "s/:0*/:/g" |cut -d : -f1-2` OLDADDR=`$ifconfig $TSP_TUNNEL_INTERFACE | grep "inet6.* $PREF" | sed -e "s/^.*inet6 addr: //" -e "s/ Scope.*\$//"` if [ ! -z $OLDADDR ]; then Display 1 "Removing old IPv6 address $OLDADDR" Exec $ifconfig $TSP_TUNNEL_INTERFACE del $OLDADDR fi Display 1 "This host is: $TSP_CLIENT_ADDRESS_IPV6/$TSP_TUNNEL_PREFIXLEN" Exec $ifconfig $TSP_TUNNEL_INTERFACE add $TSP_CLIENT_ADDRESS_IPV6/$TSP_TUNNEL_PREFIXLEN Exec $ifconfig $TSP_TUNNEL_INTERFACE mtu 1280 # # Default route Display 1 "Adding default route" ExecNoCheck $route -A inet6 del ::/0 2>/dev/null # delete old default route ExecNoCheck $route -A inet6 del 2000::/3 2>/dev/null # delete old gw route Exec $route -A inet6 add ::/0 dev $TSP_TUNNEL_INTERFACE Exec $route -A inet6 add 2000::/3 dev $TSP_TUNNEL_INTERFACE # # DNS if [ X"${TSP_CLIENT_DNS_ADDRESS_IPV6}" != X"" ]; then Display 1 "Adding DNS server" ExecNoCheck cp ${resolv_conf} ${resolv_conf}.bak echo "echo \"nameserver ${TSP_CLIENT_DNS_ADDRESS_IPV6}\" | cat - ${resolv_conf}.bak >${resolv_conf}" echo "nameserver ${TSP_CLIENT_DNS_ADDRESS_IPV6}" | cat - ${resolv_conf}.bak >${resolv_conf} fi fi # Router configuration if required if [ X"${TSP_HOST_TYPE}" = X"router" ]; then Display 1 "Router configuration" Display 1 "Kernel setup" if [ X"${TSP_PREFIXLEN}" != X"64" ]; then #Better way on linux to avoid loop with the remaining /48? $route -A inet6 add $TSP_PREFIX::/$TSP_PREFIXLEN dev $TSP_HOME_INTERFACE 2>/dev/null fi Display 1 "Adding prefix to $TSP_HOME_INTERFACE" OLDADDR=`$ifconfig $TSP_HOME_INTERFACE | grep "inet6.* $PREF" | sed -e "s/^.*inet6 addr: //" -e "s/ Scope.*\$//"` if [ ! -z $OLDADDR ]; then Display 1 "Removing old IPv6 address $OLDADDR" Exec $ifconfig $TSP_HOME_INTERFACE del $OLDADDR fi Exec $ifconfig $TSP_HOME_INTERFACE add $TSP_PREFIX::1/64 # Router advertisement configuration Display 1 "Create new $radvd_conf" echo "##### Automatically generated by the gogoCLIENT ####" > "$radvd_conf" echo "interface $TSP_HOME_INTERFACE" >> "$radvd_conf" echo "{" >> "$radvd_conf" echo " AdvSendAdvert on;" >> "$radvd_conf" echo " prefix $TSP_PREFIX::/64" >> "$radvd_conf" echo " {" >> "$radvd_conf" echo " AdvOnLink on;" >> "$radvd_conf" echo " AdvAutonomous on;" >> "$radvd_conf" echo " };" >> "$radvd_conf" echo "};" >> "$radvd_conf" echo "" >> "$radvd_conf" $radvd_script stop > /dev/null 2>&1 if [ -f $radvd_conf ]; then $radvd_script start > /dev/null 2>&1 else echo "Error : file $radvd_conf not found" exit 1 fi fi Display 1 "--- End of configuration script. ---" exit 0 #--------------------------------------------------------------------- gogoc-1_2-RELEASE/gogoc-tsp/template/linux.sh0100644000000000000000000001702711344777405017543 0ustar rootroot#!/bin/sh # # $Id: linux.sh,v 1.3 2010/03/07 19:31:17 carl Exp $ # # This source code copyright (c) gogo6 Inc. 2002-2006. # # For license information refer to CLIENT-LICENSE.TXT # # Note: IPV6 support and tun Support must be enabled before calling this script. # LANGUAGE=C if [ -z $TSP_VERBOSE ]; then TSP_VERBOSE=0 fi KillProcess() { if [ ! -z $TSP_VERBOSE ]; then if [ $TSP_VERBOSE -ge 2 ]; then echo killing $* fi fi PID=`ps axww | grep $1 | grep -v grep | awk '{ print $1;}'` echo $PID if [ ! -z $PID ]; then kill $PID fi } Display() { if [ -z $TSP_VERBOSE ]; then return; fi if [ $TSP_VERBOSE -lt $1 ]; then return; fi shift echo "$*" } Exec() { if [ ! -z $TSP_VERBOSE ]; then if [ $TSP_VERBOSE -ge 2 ]; then echo $* fi fi $* # Execute command if [ $? -ne 0 ]; then echo "Error while executing $1" echo " Command: $*" exit 1 fi } ExecNoCheck() { if [ ! -z $TSP_VERBOSE ]; then if [ $TSP_VERBOSE -ge 2 ]; then echo $* fi fi $* # Execute command } # Program localization Display 1 "--- Start of configuration script. ---" Display 1 "Script: " `basename $0` ifconfig=/sbin/ifconfig route=/sbin/route ipconfig=/sbin/ip rtadvd=/usr/sbin/radvd rtadvd_pid=/var/run/radvd/radvd.pid sysctl=/sbin/sysctl rtadvdconfigfilename=gogoc-rtadvd.conf rtadvdconfigfile=$TSP_HOME_DIR/$rtadvdconfigfilename resolv_conf=/etc/resolv.conf if [ -z $TSP_HOME_DIR ]; then echo "TSP_HOME_DIR variable not specified!;" exit 1 fi if [ ! -d $TSP_HOME_DIR ]; then echo "Error : directory $TSP_HOME_DIR does not exist" exit 1 fi # if [ -z $TSP_HOST_TYPE ]; then echo Error: TSP_HOST_TYPE not defined. exit 1 fi ############################################################################# # Tunnel destruction script. # # Is invoked by the gogoCLIENT on shutdown when it receives the # SIGHUP signal. Use "kill -HUP ". # if [ X"${TSP_OPERATION}" = X"TSP_TUNNEL_TEARDOWN" ]; then Display 1 Tunnel tear down starting... # # DNS Display 1 "Removing DNS server" Display 1 "NOTE: Adjust template script to perform actions" # ExecNoCheck rm ${resolv_conf} # if [ -f ${resolv_conf}.bak ]; then # ExecNoCheck cp ${resolv_conf}.bak ${resolv_conf} # ExecNoCheck rm ${resolv_conf}.bak # fi # Router deconfiguration. if [ X"${TSP_HOST_TYPE}" = X"router" ]; then # Kill router advertisement daemon KillProcess $rtadvdconfigfile # Remove prefix routing on TSP_HOME_INTERFACE ExecNoCheck $route -A inet6 del $TSP_PREFIX::/$TSP_PREFIXLEN # Remove Blackhole. if [ X"${TSP_PREFIXLEN}" != X"64" ]; then ExecNoCheck $route -A inet6 del $TSP_PREFIX::/$TSP_PREFIXLEN dev lo fi # Remove address from TSP HOME INTERFACE ExecNoCheck $ifconfig $TSP_HOME_INTERFACE inet6 del $TSP_PREFIX::1/64 fi # Delete default IPv6 route(s). ExecNoCheck $route -A inet6 del ::/0 2>/dev/null # delete default route ExecNoCheck $route -A inet6 del 2000::/3 2>/dev/null # delete gw route # Destroy tunnel interface if [ -x $ipconfig ]; then # Delete tunnel via ipconfig ExecNoCheck $ipconfig tunnel del $TSP_TUNNEL_INTERFACE else # Check if interface exists and remove it $ifconfig $TSP_TUNNEL_INTERFACE >/dev/null 2>/dev/null if [ $? -eq 0 ]; then Delete interface IPv6 configuration. PREF=`echo $TSP_CLIENT_ADDRESS_IPV6 | sed "s/:0*/:/g" |cut -d : -f1-2` OLDADDR=`$ifconfig $TSP_TUNNEL_INTERFACE | grep "inet6.* $PREF" | sed -e "s/^.*inet6 addr: //" -e "s/ Scope.*\$//"` if [ ! -z $OLDADDR ]; then ExecNoCheck $ifconfig $TSP_TUNNEL_INTERFACE inet6 del $OLDADDR fi # Bring interface down ExecNoCheck $ifconfig $TSP_TUNNEL_INTERFACE down fi fi Display 1 Tunnel tear down completed. exit 0 fi ############################################################################# # Tunnel creation script. # if [ X"${TSP_HOST_TYPE}" = X"host" ] || [ X"${TSP_HOST_TYPE}" = X"router" ]; then # Set tunnel IPv6 configuration Display 1 "$TSP_TUNNEL_INTERFACE setup" if [ X"${TSP_TUNNEL_MODE}" = X"v6v4" ]; then Display 1 "Setting up link to $TSP_SERVER_ADDRESS_IPV4" if [ -x $ipconfig ]; then ExecNoCheck $ipconfig tunnel del $TSP_TUNNEL_INTERFACE ExecNoCheck sleep 1 Exec $ipconfig tunnel add $TSP_TUNNEL_INTERFACE mode sit ttl 64 remote $TSP_SERVER_ADDRESS_IPV4 else Exec $ifconfig $TSP_TUNNEL_INTERFACE tunnel ::$TSP_SERVER_ADDRESS_IPV4 fi fi Exec $ifconfig $TSP_TUNNEL_INTERFACE up # Clean-up old interface IPv6 configuration. PREF=`echo $TSP_CLIENT_ADDRESS_IPV6 | sed "s/:0*/:/g" |cut -d : -f1-2` OLDADDR=`$ifconfig $TSP_TUNNEL_INTERFACE | grep "inet6.* $PREF" | sed -e "s/^.*inet6 addr: //" -e "s/ Scope.*\$//"` if [ ! -z $OLDADDR ]; then Display 1 "Removing old IPv6 address $OLDADDR" Exec $ifconfig $TSP_TUNNEL_INTERFACE inet6 del $OLDADDR fi Display 1 "This host is: $TSP_CLIENT_ADDRESS_IPV6/$TSP_TUNNEL_PREFIXLEN" Exec $ifconfig $TSP_TUNNEL_INTERFACE add $TSP_CLIENT_ADDRESS_IPV6/$TSP_TUNNEL_PREFIXLEN Exec $ifconfig $TSP_TUNNEL_INTERFACE mtu 1280 # # Default route Display 1 "Adding default route" ExecNoCheck $route -A inet6 del ::/0 2>/dev/null # delete old default route ExecNoCheck $route -A inet6 del 2000::/3 2>/dev/null # delete old gw route Exec $route -A inet6 add ::/0 dev $TSP_TUNNEL_INTERFACE Exec $route -A inet6 add 2000::/3 dev $TSP_TUNNEL_INTERFACE # # DNS if [ X"${TSP_CLIENT_DNS_ADDRESS_IPV6}" != X"" ]; then Display 1 "Adding DNS server" Display 1 "NOTE: Adjust template script to perform actions" # ExecNoCheck cp ${resolv_conf} ${resolv_conf}.bak # echo "echo \"nameserver ${TSP_CLIENT_DNS_ADDRESS_IPV6}\" | cat - ${resolv_conf}.bak >${resolv_conf}" # echo "nameserver ${TSP_CLIENT_DNS_ADDRESS_IPV6}" | cat - ${resolv_conf}.bak >${resolv_conf} fi fi # Router configuration if required if [ X"${TSP_HOST_TYPE}" = X"router" ]; then Display 1 "Router configuration" # Tell kernel to forward IPv6 traffic. Exec $sysctl -w net.ipv6.conf.all.forwarding=1 # Blackholing on interface lo, if prefixlen is not 64. if [ X"${TSP_PREFIXLEN}" != X"64" ]; then # Sometimes this route does not show when using 'netstat -rn6'. ExecNoCheck $route -A inet6 add $TSP_PREFIX::/$TSP_PREFIXLEN dev lo 2>/dev/null fi # Add prefix::1 on advertising interface. Clean up before. OLDADDR=`$ifconfig $TSP_HOME_INTERFACE | grep "inet6.* $PREF" | sed -e "s/^.*inet6 addr: //" -e "s/ Scope.*\$//"` if [ ! -z $OLDADDR ]; then Display 1 "Removing old IPv6 address $OLDADDR" Exec $ifconfig $TSP_HOME_INTERFACE inet6 del $OLDADDR fi Display 1 "Adding prefix to $TSP_HOME_INTERFACE" Exec $ifconfig $TSP_HOME_INTERFACE add $TSP_PREFIX::1/64 # Stop radvd daemon if it was running. Twice. /etc/init.d/radvd stop if [ -f $rtadvdconfigfile ]; then KillProcess $rtadvdconfigfile fi # Create new radvd configuration file. cat > "$rtadvdconfigfile" </dev/null 2>/dev/null if [ $? -eq 0 ]; then # Delete interface IPv6 configuration list=`$ifconfig $TSP_TUNNEL_INTERFACE | grep inet6 | awk '{print $2}' | grep -v '^fe80'` for ipv6address in $list do ExecNoCheck $ifconfig $TSP_TUNNEL_INTERFACE inet6 $ipv6address delete done # Deconfiguration of tunnel ExecNoCheck $ifconfig $TSP_TUNNEL_INTERFACE deletetunnel # Bring interface down and TRY to destroy it ExecNoCheck $ifconfig $TSP_TUNNEL_INTERFACE down ExecNoCheck $ifconfig $TSP_TUNNEL_INTERFACE destroy fi Display 1 Tunnel tear down completed. exit 0 fi ########################## # Tunnel creation script. ########################## if [ X"${TSP_HOST_TYPE}" = X"host" ] || [ X"${TSP_HOST_TYPE}" = X"router" ]; then # # Configured tunnel config (IPv4) Display 1 Setting up interface $TSP_TUNNEL_INTERFACE # Check if interface exists $ifconfig $TSP_TUNNEL_INTERFACE >/dev/null 2>/dev/null if [ $? -eq 0 ]; then # Deconfiguration ExecNoCheck $ifconfig $TSP_TUNNEL_INTERFACE deletetunnel # Looking if the interface has already an IPv6 configuration list=`$ifconfig $TSP_TUNNEL_INTERFACE | grep inet6 | awk '{print $2}' | grep -v '^fe80'` for ipv6address in $list do Exec $ifconfig $TSP_TUNNEL_INTERFACE inet6 $ipv6address delete done else # We enter here only in netbsd >1.6 (clone interface) Exec $ifconfig $TSP_TUNNEL_INTERFACE create fi Exec $ifconfig $TSP_TUNNEL_INTERFACE tunnel $TSP_CLIENT_ADDRESS_IPV4 $TSP_SERVER_ADDRESS_IPV4 # Configured tunnel config (IPv6) Exec $ifconfig $TSP_TUNNEL_INTERFACE inet6 $TSP_CLIENT_ADDRESS_IPV6 $TSP_SERVER_ADDRESS_IPV6 prefixlen $TSP_TUNNEL_PREFIXLEN alias Exec $ifconfig $TSP_TUNNEL_INTERFACE mtu 1280 # # Default route Display 1 Adding default route to $TSP_SERVER_ADDRESS_IPV6 # Delete first any default IPv6 route ExecNoCheck $route delete -inet6 default Exec $route add -inet6 default $TSP_SERVER_ADDRESS_IPV6 # # DNS if [ X"${TSP_CLIENT_DNS_ADDRESS_IPV6}" != X"" ]; then Display 1 "Adding DNS server" Display 1 "NOTE: Adjust template script to perform actions" # ExecNoCheck cp ${resolv_conf} ${resolv_conf}.bak # echo "echo \"nameserver ${TSP_CLIENT_DNS_ADDRESS_IPV6}\" | cat - ${resolv_conf}.bak >${resolv_conf}" # echo "nameserver ${TSP_CLIENT_DNS_ADDRESS_IPV6}" | cat - ${resolv_conf}.bak >${resolv_conf} fi fi # Router configuration if required if [ X"${TSP_HOST_TYPE}" = X"router" ]; then Display 1 "Router configuration" Display 1 "Kernel setup" if [ X"${TSP_PREFIXLEN}" != X"64" ]; then ExecNoCheck $route add -inet6 $TSP_PREFIX:: -prefixlen $TSP_PREFIXLEN ::1 -interface fi Exec $sysctl -w net.inet6.ip6.forwarding=1 # ipv6_forwarding enabled Exec $sysctl -w net.inet6.ip6.accept_rtadv=0 # routed must disable any router advertisement incoming Exec $ifconfig $TSP_HOME_INTERFACE inet6 $TSP_PREFIX::1 prefixlen 64 alias # Router advertisement startup KillProcess rtadvd Exec $rtadvd $TSP_HOME_INTERFACE fi Display 1 "--- End of configuration script. ---" exit 0 gogoc-1_2-RELEASE/gogoc-tsp/template/openbsd.sh0100644000000000000000000001302511344777406020031 0ustar rootroot#!/bin/sh -x # # $Id: openbsd.sh,v 1.3 2010/03/07 19:31:18 carl Exp $ # # This source code copyright (c) gogo6 Inc. 2002-2005. # # For license information refer to CLIENT-LICENSE.TXT # LANGUAGE=C if [ -z $TSP_VERBOSE ]; then TSP_VERBOSE=0 fi KillProcess() { if [ ! -z $TSP_VERBOSE ]; then if [ $TSP_VERBOSE -ge 2 ]; then echo killing $* fi fi PID=`ps axww | grep $1 | grep -v grep | awk '{ print $1;}'` if [ ! -z "${PID}" ]; then kill $PID fi } Display() { if [ -z $TSP_VERBOSE ]; then return; fi if [ $TSP_VERBOSE -lt $1 ]; then return; fi shift echo $* } Exec() { if [ ! -z $TSP_VERBOSE ]; then if [ $TSP_VERBOSE -ge 2 ]; then echo $* fi fi $* # Execute command if [ $? -ne 0 ]; then echo "Error while executing $1" echo " Command: $*" exit 1 fi } ExecNoCheck() { if [ ! -z $TSP_VERBOSE ]; then if [ $TSP_VERBOSE -ge 2 ]; then echo $* fi fi $* # Execute command } # Programs localization Display 1 "--- Start of configuration script. ---" Display 1 "Script: " `basename $0` ifconfig=/sbin/ifconfig route=/sbin/route rtadvd=/usr/sbin/rtadvd sysctl=/usr/sbin/sysctl resolv_conf=/etc/resolv.conf if [ -z $TSP_HOME_DIR ]; then echo "TSP_HOME_DIR variable not specified!;" exit 1 fi if [ ! -d $TSP_HOME_DIR ]; then echo "Error : directory $TSP_HOME_DIR does not exist" exit 1 fi # if [ -z $TSP_HOST_TYPE ]; then echo Error: TSP_HOST_TYPE not defined. exit 1 fi ################################# # Run tunnel destruction script. ################################# if [ X"${TSP_OPERATION}" = X"TSP_TUNNEL_TEARDOWN" ]; then Display 1 Tunnel tear down starting... # # DNS Display 1 "Removing DNS server" Display 1 "NOTE: Adjust template script to perform actions" # ExecNoCheck rm ${resolv_conf} # if [ -f ${resolv_conf}.bak ]; then # ExecNoCheck cp ${resolv_conf}.bak ${resolv_conf} # ExecNoCheck rm ${resolv_conf}.bak # fi # Router deconfiguration. if [ X"${TSP_HOST_TYPE}" = X"router" ]; then # Kill router advertisement daemon KillProcess rtadvd # Remove IPv6 configuration of home interface (PREFIX::1). ExecNoCheck $ifconfig $TSP_HOME_INTERFACE inet6 $TSP_PREFIX::1 delete # Remove blackhole if [ X"${TSP_PREFIXLEN}" != X"64" ]; then ExecNoCheck $route delete -net -inet6 $TSP_PREFIX:: -prefixlen $TSP_PREFIXLEN ::1 fi fi # Delete default IPv6 route ExecNoCheck $route delete -inet6 default # Delete tunnel interface IPv6 configuration list=`$ifconfig $TSP_TUNNEL_INTERFACE | grep inet6 | awk '{print $2}' | grep -v '^fe80'` for ipv6address in $list do ExecNoCheck $ifconfig $TSP_TUNNEL_INTERFACE inet6 $ipv6address delete done # Deconfiguration of tunnel if [ X"${TSP_TUNNEL_MODE}" = X"v6v4" ]; then ExecNoCheck $ifconfig $TSP_TUNNEL_INTERFACE deletetunnel fi ExecNoCheck $ifconfig $TSP_TUNNEL_INTERFACE down # Try to destroy the tunnel interface, if possible. ExecNoCheck $ifconfig $TSP_TUNNEL_INTERFACE destroy Display 1 Tunnel tear down completed. exit 0 fi ########################## # Tunnel creation script. ########################## if [ X"${TSP_HOST_TYPE}" = X"host" ] || [ X"${TSP_HOST_TYPE}" = X"router" ]; then # # Configured tunnel config (IPv4) Display 1 Setting up interface $TSP_TUNNEL_INTERFACE if [ X"${TSP_TUNNEL_MODE}" = X"v6v4" ]; then # Create gif tunnel for v6v4 ExecNoCheck $ifconfig $TSP_TUNNEL_INTERFACE deletetunnel Exec $ifconfig $TSP_TUNNEL_INTERFACE giftunnel $TSP_CLIENT_ADDRESS_IPV4 $TSP_SERVER_ADDRESS_IPV4 else # Bring up tun for v6udpv4 Exec $ifconfig $TSP_TUNNEL_INTERFACE up fi # # Configured tunnel config (IPv6) # Check if the interface already has an IPv6 configuration list=`$ifconfig $TSP_TUNNEL_INTERFACE | grep inet6 | awk '{print $2}' | grep -v '^fe80'` for ipv6address in $list do Exec $ifconfig $TSP_TUNNEL_INTERFACE inet6 $ipv6address delete done Exec $ifconfig $TSP_TUNNEL_INTERFACE inet6 $TSP_CLIENT_ADDRESS_IPV6 $TSP_SERVER_ADDRESS_IPV6 prefixlen $TSP_TUNNEL_PREFIXLEN alias Exec $ifconfig $TSP_TUNNEL_INTERFACE mtu 1280 # Delete first any default IPv6 route, and set the new one. ExecNoCheck $route delete -inet6 default Exec $route add -inet6 default $TSP_SERVER_ADDRESS_IPV6 # # DNS if [ X"${TSP_CLIENT_DNS_ADDRESS_IPV6}" != X"" ]; then Display 1 "Adding DNS server" Display 1 "NOTE: Adjust template script to perform actions" # ExecNoCheck cp ${resolv_conf} ${resolv_conf}.bak # echo "echo \"nameserver ${TSP_CLIENT_DNS_ADDRESS_IPV6}\" | cat - ${resolv_conf}.bak >${resolv_conf}" # echo "nameserver ${TSP_CLIENT_DNS_ADDRESS_IPV6}" | cat - ${resolv_conf}.bak >${resolv_conf} fi fi # Router configuration if required if [ X"${TSP_HOST_TYPE}" = X"router" ]; then Display 1 "Router configuration" # Kernel configuration. Allow IPv6 forwarding. Exec $sysctl -w net.inet6.ip6.forwarding=1 Exec $sysctl -w net.inet6.ip6.accept_rtadv=0 # routed must disable any router advertisement incoming # Blackhole the remaining prefix portion that is not routed. if [ X"${TSP_PREFIXLEN}" != X"64" ]; then ExecNoCheck $route add -net -inet6 $TSP_PREFIX:: -prefixlen $TSP_PREFIXLEN ::1 fi # Add prefix::1 inet6 address to advertising interface. Exec $ifconfig $TSP_HOME_INTERFACE inet6 $TSP_PREFIX::1 prefixlen 64 alias # Router advertisement startup KillProcess rtadvd Exec $rtadvd $TSP_HOME_INTERFACE fi Display 1 "--- End of configuration script. ---" exit 0 gogoc-1_2-RELEASE/gogoc-tsp/template/openwrt.sh0100644000000000000000000001644011344777406020101 0ustar rootroot#!/bin/sh # # $Id: openwrt.sh,v 1.3 2010/03/07 19:31:18 carl Exp $ # # This source code copyright (c) gogo6 Inc. 2002-2007. # # For license information refer to CLIENT-LICENSE.TXT # # Note: IPV6 support and tun Support must be enabled before calling this script. # LANGUAGE=C if [ -z $TSP_VERBOSE ]; then TSP_VERBOSE=0 fi KillProcess() { if [ ! -z $TSP_VERBOSE ]; then if [ $TSP_VERBOSE -ge 2 ]; then echo killing $* fi fi PID=`ps axww | grep $1 | grep -v grep | awk '{ print $1;}'` echo $PID if [ ! -z $PID ]; then kill $PID fi } Display() { if [ -z $TSP_VERBOSE ]; then return; fi if [ $TSP_VERBOSE -lt $1 ]; then return; fi shift echo "$*" } Exec() { if [ ! -z $TSP_VERBOSE ]; then if [ $TSP_VERBOSE -ge 2 ]; then echo $* fi fi $* # Execute command if [ $? -ne 0 ]; then echo "Error while executing $1" echo " Command: $*" exit 1 fi } ExecNoCheck() { if [ ! -z $TSP_VERBOSE ]; then if [ $TSP_VERBOSE -ge 2 ]; then echo $* fi fi $* # Execute command } # Program localization Display 1 "--- Start of configuration script. ---" Display 1 "Script: " `basename $0` ifconfig=/sbin/ifconfig route=/sbin/route ipconfig=/usr/sbin/ip rtadvd=/usr/sbin/radvd rtadvd_pid=/var/run/radvd.pid sysctl=/sbin/sysctl rtadvdconfigfilename=gogoc-radvd.conf rtadvdconfigfile=/var/run/gogoc/$rtadvdconfigfilename resolv_conf=/etc/resolv.conf if [ -z $TSP_HOME_DIR ]; then echo "TSP_HOME_DIR variable not specified!;" exit 1 fi if [ ! -d $TSP_HOME_DIR ]; then echo "Error : directory $TSP_HOME_DIR does not exist" exit 1 fi # if [ -z $TSP_HOST_TYPE ]; then echo Error: TSP_HOST_TYPE not defined. exit 1 fi ################################# # Run tunnel destruction script. ################################# if [ X"${TSP_OPERATION}" = X"TSP_TUNNEL_TEARDOWN" ]; then Display 1 Tunnel tear down starting... # # DNS Display 1 "Removing DNS server" Display 1 "NOTE: Adjust template script to perform actions" # ExecNoCheck rm ${resolv_conf} # if [ -f ${resolv_conf}.bak ]; then # ExecNoCheck cp ${resolv_conf}.bak ${resolv_conf} # ExecNoCheck rm ${resolv_conf}.bak # fi # Remove tunnel if [ X"${TSP_TUNNEL_MODE}" = X"v6v4" ]; then ExecNoCheck $ipconfig tunnel del $TSP_TUNNEL_INTERFACE fi # Remove addresses PREF=`echo $TSP_CLIENT_ADDRESS_IPV6 | sed "s/:0*/:/g" |cut -d : -f1-2` OLDADDR=`$ifconfig $TSP_TUNNEL_INTERFACE | grep "inet6.* $PREF" | sed -e "s/^.*inet6 addr: //" -e "s/ Scope.*\$//"` if [ ! -z $OLDADDR ]; then Display 1 "Removing old IPv6 address $OLDADDR" Exec $ifconfig $TSP_TUNNEL_INTERFACE inet6 del $OLDADDR fi # Bring interface down. ExecNoCheck $ifconfig $TSP_TUNNEL_INTERFACE down # Delete any IPv6 route ExecNoCheck $route -A inet6 del ::/0 2>/dev/null # delete old default route ExecNoCheck $route -A inet6 del 2000::/3 2>/dev/null # delete old gw route # Router deconfiguration. if [ X"${TSP_HOST_TYPE}" = X"router" ]; then # Remove prefix routing on TSP_HOME_INTERFACE ExecNoCheck $route -A inet6 del $TSP_PREFIX::/$TSP_PREFIXLEN # Remove address from TSP HOME INTERFACE OLDADDR=`$ifconfig $TSP_HOME_INTERFACE | grep "inet6.* $PREF" | sed -e "s/^.*inet6 addr: //" -e "s/ Scope.*\$//"` if [ ! -z $OLDADDR ]; then Display 1 "Removing old IPv6 address $OLDADDR" Exec $ifconfig $TSP_HOME_INTERFACE del $OLDADDR fi # Kill router advertisement daemon /etc/init.d/S51radvd stop fi Display 1 Tunnel tear down completed. exit 0 fi if [ X"${TSP_HOST_TYPE}" = X"host" ] || [ X"${TSP_HOST_TYPE}" = X"router" ]; then # # Configured tunnel config (IPv6) Display 1 "$TSP_TUNNEL_INTERFACE setup" if [ X"${TSP_TUNNEL_MODE}" = X"v6v4" ]; then Display 1 "Setting up link to $TSP_SERVER_ADDRESS_IPV4" ExecNoCheck $ipconfig tunnel del $TSP_TUNNEL_INTERFACE ExecNoCheck sleep 1 Exec $ipconfig tunnel add $TSP_TUNNEL_INTERFACE mode sit ttl 64 remote $TSP_SERVER_ADDRESS_IPV4 fi Exec $ifconfig $TSP_TUNNEL_INTERFACE up PREF=`echo $TSP_CLIENT_ADDRESS_IPV6 | sed "s/:0*/:/g" |cut -d : -f1-2` OLDADDR=`$ifconfig $TSP_TUNNEL_INTERFACE | grep "inet6.* $PREF" | sed -e "s/^.*inet6 addr: //" -e "s/ Scope.*\$//"` if [ ! -z $OLDADDR ]; then Display 1 "Removing old IPv6 address $OLDADDR" Exec $ifconfig $TSP_TUNNEL_INTERFACE inet6 del $OLDADDR fi Display 1 "This host is: $TSP_CLIENT_ADDRESS_IPV6/$TSP_TUNNEL_PREFIXLEN" Exec $ifconfig $TSP_TUNNEL_INTERFACE add $TSP_CLIENT_ADDRESS_IPV6/$TSP_TUNNEL_PREFIXLEN Exec $ifconfig $TSP_TUNNEL_INTERFACE mtu 1280 # # Default route Display 1 "Adding default route" ExecNoCheck $route -A inet6 del ::/0 2>/dev/null # delete old default route ExecNoCheck $route -A inet6 del 2000::/3 2>/dev/null # delete old gw route Exec $route -A inet6 add ::/0 dev $TSP_TUNNEL_INTERFACE Exec $route -A inet6 add 2000::/3 dev $TSP_TUNNEL_INTERFACE # # DNS if [ X"${TSP_CLIENT_DNS_ADDRESS_IPV6}" != X"" ]; then Display 1 "Adding DNS server" Display 1 "NOTE: Adjust template script to perform actions" # ExecNoCheck cp ${resolv_conf} ${resolv_conf}.bak # echo "echo \"nameserver ${TSP_CLIENT_DNS_ADDRESS_IPV6}\" | cat - ${resolv_conf}.bak >${resolv_conf}" # echo "nameserver ${TSP_CLIENT_DNS_ADDRESS_IPV6}" | cat - ${resolv_conf}.bak >${resolv_conf} fi fi # Router configuration if required if [ X"${TSP_HOST_TYPE}" = X"router" ]; then Display 1 "Router configuration" Display 1 "Kernel setup" if [ X"${TSP_PREFIXLEN}" != X"64" ]; then #Better way on linux to avoid loop with the remaining /48? $route -A inet6 add $TSP_PREFIX::/$TSP_PREFIXLEN dev $TSP_HOME_INTERFACE 2>/dev/null fi Display 1 "Adding prefix to $TSP_HOME_INTERFACE" OLDADDR=`$ifconfig $TSP_HOME_INTERFACE | grep "inet6.* $PREF" | sed -e "s/^.*inet6 addr: //" -e "s/ Scope.*\$//"` if [ ! -z $OLDADDR ]; then Display 1 "Removing old IPv6 address $OLDADDR" Exec $ifconfig $TSP_HOME_INTERFACE del $OLDADDR fi Exec $ifconfig $TSP_HOME_INTERFACE add $TSP_PREFIX::1/64 # Router advertisement configuration Display 1 "Create new $rtadvdconfigfile" echo "##### rtadvd.conf made by gogoCLIENT ####" > "$rtadvdconfigfile" echo "interface $TSP_HOME_INTERFACE" >> "$rtadvdconfigfile" echo "{" >> "$rtadvdconfigfile" echo " AdvSendAdvert on;" >> "$rtadvdconfigfile" echo " prefix $TSP_PREFIX::/64" >> "$rtadvdconfigfile" echo " {" >> "$rtadvdconfigfile" echo " AdvOnLink on;" >> "$rtadvdconfigfile" echo " AdvAutonomous on;" >> "$rtadvdconfigfile" echo " };" >> "$rtadvdconfigfile" echo "};" >> "$rtadvdconfigfile" echo "" >> "$rtadvdconfigfile" /etc/init.d/S51radvd stop # Then enable forwarding. Killing # radvd disables forwarding and radvd # does NOT start without forwarding enabled Exec $sysctl -w net.ipv6.conf.all.forwarding=1 # ipv6_forwarding enabled if [ -f $rtadvdconfigfile ]; then Exec $rtadvd -p $rtadvd_pid -C $rtadvdconfigfile Display 1 "Starting radvd: $rtadvd -p $rtadvd_pid -C $rtadvdconfigfile" else echo "Error : file $rtadvdconfigfile not found" exit 1 fi fi Display 1 "--- End of configuration script. ---" exit 0 #--------------------------------------------------------------------- gogoc-1_2-RELEASE/gogoc-tsp/template/sunos.sh0100644000000000000000000001211711344777406017547 0ustar rootroot#!/bin/sh # # $Id: sunos.sh,v 1.3 2010/03/07 19:31:18 carl Exp $ # # This source code copyright (c) gogo6 Inc. 2002-2005. # # For license information refer to CLIENT-LICENSE.TXT # LANGUAGE=C if [ -z "$TSP_VERBOSE" ]; then TSP_VERBOSE=0 fi KillProcess() { if [ ! -z $TSP_VERBOSE ]; then if [ $TSP_VERBOSE -ge 2 ]; then echo killing $* fi fi pkill `basename $1` } Display() { if [ -z "$TSP_VERBOSE" ]; then return; fi if [ $TSP_VERBOSE -lt $1 ]; then return; fi shift echo $* } Exec() { if [ ! -z "$TSP_VERBOSE" ]; then if [ $TSP_VERBOSE -ge 2 ]; then echo $* fi fi $* ret=$? if [ $ret -ne 0 ]; then echo "Error while executing $1" echo " Command: $*" exit 1 fi echo "Command $1 succeed" } # Program localization Display 1 "--- Start of configuration script. ---" Display 1 "Script: " `basename $0` ifconfig=/sbin/ifconfig route=/usr/sbin/route ndpd=/usr/lib/inet/in.ndpd ndd=/usr/sbin/ndd resolv_conf=/etc/resolv.conf ndpdconfigfilename=ndpd.conf ndpdconfigfile=$TSP_HOME_DIR/$ndpdconfigfilename if [ -z "$TSP_HOME_DIR" ]; then echo "TSP_HOME_DIR variable not specified!;" exit 1 fi if [ ! -d $TSP_HOME_DIR ]; then echo "Error : directory $TSP_HOME_DIR does not exist" exit 1 fi # if [ -z "$TSP_HOST_TYPE" ]; then echo Error: TSP_HOST_TYPE not defined. exit 1 fi ################################# # Run tunnel destruction script. ################################# if [ X"${TSP_OPERATION}" = X"TSP_TUNNEL_TEARDOWN" ]; then Display 1 "Tunnel tear down starting..." # # DNS Display 1 "Removing DNS server" Display 1 "NOTE: Adjust template script to perform actions" # rm ${resolv_conf} # if [ -f ${resolv_conf}.bak ]; then # cp ${resolv_conf}.bak ${resolv_conf} # rm ${resolv_conf}.bak # fi # Disable neighbor discovery. if [ X"${TSP_HOST_TYPE}" = X"router" ]; then if [ -f "$ndpd" ]; then KillProcess $ndpd fi # Remove PREFIX::1 address from HOME interface. $ifconfig $TSP_HOME_INTERFACE inet6 removeif $TSP_PREFIX::1 $ndd -set /dev/ip ip6_forwarding 0 $ndd -set /dev/ip ip6_send_redirects 0 $ndd -set /dev/ip ip6_ignore_redirect 0 fi # Remove INET6 default route $route delete -inet6 default $TSP_SERVER_ADDRESS_IPV6 2>/dev/null # Unplumb and disable tunnel interface $ifconfig $TSP_TUNNEL_INTERFACE inet6 unplumb down 2>/dev/null Display 1 "Tunnel tear down completed." exit 0 fi ########################## # Tunnel creation script. ########################## if [ X"${TSP_HOST_TYPE}" = X"host" ] || [ X"${TSP_HOST_TYPE}" = X"router" ]; then Display 1 "Tunnel set up starting..." # Unplumb the tunnel interface and bring it down. $ifconfig $TSP_TUNNEL_INTERFACE inet6 unplumb down 2>/dev/null # Create tunnel on physical interface. At this point the physical # interface will have IPv6 link-local addresses. Exec $ifconfig $TSP_TUNNEL_INTERFACE inet6 plumb tsrc $TSP_CLIENT_ADDRESS_IPV4 tdst $TSP_SERVER_ADDRESS_IPV4 up # Configure IPv6 addresses tunnel endpoints, by creating new logical # interface (:1). This is required because we're using global IPv6 # addresses (compared to the link-local ones on the physical). Exec $ifconfig $TSP_TUNNEL_INTERFACE inet6 addif $TSP_CLIENT_ADDRESS_IPV6 $TSP_SERVER_ADDRESS_IPV6 up # Set physical interface MTU to 1280. Exec $ifconfig $TSP_TUNNEL_INTERFACE inet6 mtu 1280 # Set logical interface MTU to 1280. Exec $ifconfig ${TSP_TUNNEL_INTERFACE}:1 inet6 mtu 1280 # Default route: remove route and add new $route delete -inet6 default $TSP_SERVER_ADDRESS_IPV6 2>/dev/null Exec $route add -inet6 default $TSP_SERVER_ADDRESS_IPV6 # # DNS if [ X"${TSP_CLIENT_DNS_ADDRESS_IPV6}" != X"" ]; then Display 1 "Adding DNS server" Display 1 "NOTE: Adjust template script to perform actions" # cp ${resolv_conf} ${resolv_conf}.bak # echo "nameserver ${TSP_CLIENT_DNS_ADDRESS_IPV6}" | cat - ${resolv_conf}.bak >${resolv_conf} fi fi # Host only configuration if [ X"${TSP_HOST_TYPE}" = X"host" ]; then Exec $ndd -set /dev/ip ip6_forwarding 0 Exec $ndd -set /dev/ip ip6_send_redirects 0 Exec $ndd -set /dev/ip ip6_ignore_redirect 0 fi # Router configuration if required if [ X"${TSP_HOST_TYPE}" = X"router" ]; then Display 1 "Router configuration" # Kernel setup. Exec $ndd -set /dev/ip ip6_forwarding 1 Exec $ndd -set /dev/ip ip6_send_redirects 1 Exec $ndd -set /dev/ip ip6_ignore_redirect 1 # Put the PREFIX::1 address on HOME interface(Remove it if it was there). $ifconfig $TSP_HOME_INTERFACE inet6 removeif $TSP_PREFIX::1 Exec $ifconfig $TSP_HOME_INTERFACE inet6 addif $TSP_PREFIX::1/64 up # Check if router advertisement daemon exists. if [ -f "$ndpd" ]; then KillProcess $ndpd # Create configuration file. cat > "$ndpdconfigfile" < NUL if errorlevel 1 goto fail0 goto set_interface :test_ipv6_ping ping -6 -n 1 ::1 > NUL if errorlevel 1 goto fail10 REM *** ----------------------------------------------- *** REM *** Set up the interface *** :set_interface if %WINDOWS_VERSION% == 1 goto windows_xp_SP1 if %WINDOWS_VERSION% == 2 goto windows_xp_SP2 if %WINDOWS_VERSION% == 3 goto windows_xp if %WINDOWS_VERSION% == 4 goto windows_2000 if %WINDOWS_VERSION% == 5 goto windows_server_2003_SP1 if %WINDOWS_VERSION% == 6 goto windows_server_2003 if %WINDOWS_VERSION% == 7 goto windows_vista REM Windows XP SP1 and later script path. :windows_vista :windows_server_2003_SP1 :windows_server_2003 :windows_xp_SP2 :windows_xp_SP1 REM Set what we change to be non-persistant. set STORAGEARG=store=active :windows_xp echo Cycling the interface netsh.exe interface ipv6 delete interface %TEMPLATE_V6V4_TUNNEL_INTERFACE% > NUL Rem are we setting up nat traversal or V6V4 or V4V6? if %TSP_TUNNEL_MODE% == v6udpv4 goto v6udpv4_config if %TSP_TUNNEL_MODE% == v4v6 goto v4v6_config Rem else, setup v6v4 Rem can we spawn our own GIF interface on this os? if %WINDOWS_VERSION% == 1 goto create_gif if %WINDOWS_VERSION% == 2 goto create_gif REM skip xp and 2000 if %WINDOWS_VERSION% == 5 goto create_gif if %WINDOWS_VERSION% == 6 goto create_gif if %WINDOWS_VERSION% == 7 goto create_gif goto older_xp :create_gif echo Configuring V6V4 for XP Service Pack 1 and newer echo Overriding TSP_TUNNEL_INTERFACE from %TSP_TUNNEL_INTERFACE% to %TEMPLATE_V6V4_TUNNEL_INTERFACE% set TSP_TUNNEL_INTERFACE=%TEMPLATE_V6V4_TUNNEL_INTERFACE% netsh.exe interface ipv6 add v6v4tunnel %TSP_TUNNEL_INTERFACE% %TSP_CLIENT_ADDRESS_IPV4% %TSP_SERVER_ADDRESS_IPV4% > NUL if errorlevel 1 goto fail9 netsh.exe interface ipv6 add address %TSP_TUNNEL_INTERFACE% %TSP_CLIENT_ADDRESS_IPV6% %STORAGEARG% > NUL if errorlevel 1 goto fail2 netsh.exe interface ipv6 add route ::/0 %TSP_TUNNEL_INTERFACE% publish=yes %STORAGEARG% > NUL if errorlevel 1 goto fail1 goto set_mtu :older_xp echo Configuring V6V4 for XP with no service pack netsh.exe interface ipv6 add route prefix=::/0 interface=2 nexthop=::%TSP_SERVER_ADDRESS_IPV4% publish=yes > NUL if errorlevel 1 goto fail1 netsh.exe interface ipv6 add address interface=2 address=%TSP_CLIENT_ADDRESS_IPV6% > NUL if errorlevel 1 goto fail2 :set_mtu Rem We skip mtu setting if in windows XP without any SP, it doesnt support it if %WINDOWS_VERSION% == 3 goto check_router_config echo Setting MTU to 1280 on tunnel interface "%TSP_TUNNEL_INTERFACE%" netsh.exe interface ipv6 set interface interface="%TSP_TUNNEL_INTERFACE%" mtu=1280 > NUL if errorlevel 1 goto fail8 :check_router_config if %TSP_HOST_TYPE% == router GOTO router_config goto success :v6udpv4_config echo Configuring for V6UDPV4 (NAT traversal) netsh.exe interface ipv6 set address "%TSP_TUNNEL_INTERFACE%" %TSP_CLIENT_ADDRESS_IPV6% %STORAGEARG% > NUL if errorlevel 1 goto fail3 Rem We skip mtu setting if in windows XP without any SP, it doesnt support it if %WINDOWS_VERSION% == 3 goto skip_set_mtu echo Setting MTU to 1280 on tunnel interface "%TSP_TUNNEL_INTERFACE%" netsh.exe interface ipv6 set interface interface="%TSP_TUNNEL_INTERFACE%" mtu=1280 %STORAGEARG% > NUL if errorlevel 1 goto fail8 IF NOT %WINDOWS_VERSION% == 7 GOTO skip_vista_dns REM Windows Vista -ONLY- REM Add DNS servers to the tunnel interface. ECHO Adding DNS servers to tunnel interface "%TSP_TUNNEL_INTERFACE%" IF NOT "%TSP_LOCAL_DNS01%" == "" netsh interface ipv4 add dnsserver name="%TSP_TUNNEL_INTERFACE%" addr=%TSP_LOCAL_DNS01% > NUL IF NOT "%TSP_LOCAL_DNS02%" == "" netsh interface ipv4 add dnsserver name="%TSP_TUNNEL_INTERFACE%" addr=%TSP_LOCAL_DNS02% > NUL :skip_vista_dns :skip_set_mtu netsh.exe interface ipv6 add route %TSP_SERVER_ADDRESS_IPV6%/128 "%TSP_TUNNEL_INTERFACE%" %STORAGEARG% > NUL if NOT %WINDOWS_VERSION% == 7 if errorlevel 1 goto fail3 netsh.exe interface ipv6 add route ::/0 "%TSP_TUNNEL_INTERFACE%" %TSP_SERVER_ADDRESS_IPV6% publish=yes %STORAGEARG% > NUL if NOT %WINDOWS_VERSION% == 7 if errorlevel 1 goto fail3 if %TSP_HOST_TYPE% == router GOTO router_config goto success :v4v6_config echo Configuring for V4V6, %TSP_CLIENT_ADDRESS_IPV4% to %TSP_SERVER_ADDRESS_IPV4% on %TSP_TUNNEL_INTERFACE%... netsh.exe interface ip set address "%TSP_TUNNEL_INTERFACE%" static %TSP_CLIENT_ADDRESS_IPV4% 255.255.255.0 > NUL route.exe add %TSP_SERVER_ADDRESS_IPV4% mask 255.255.255.255 %TSP_CLIENT_ADDRESS_IPV4% route.exe add 0.0.0.0 mask 0.0.0.0 %TSP_SERVER_ADDRESS_IPV4% goto success_v4v6 :router_config ECHO Preparing router configuration... netsh.exe interface ipv6 set address "%TSP_HOME_INTERFACE%" %TSP_PREFIX%::1 %STORAGEARG% > NUL if errorlevel 1 goto fail6 echo Configuring IPv6 forwading on internal and external interfaces netsh.exe interface ipv6 set interface interface="%TSP_TUNNEL_INTERFACE%" forwarding=enabled %STORAGEARG% > NUL netsh.exe interface ipv6 set interface interface="%TSP_HOME_INTERFACE%" forwarding=enabled %STORAGEARG% > NUL netsh.exe interface ipv6 set interface interface=2 forwarding=enabled %STORAGEARG% > NUL Rem fix for XP with no service pack. forwarding only works if enabled Rem on the 6to4 interface. if %WINDOWS_VERSION% == 3 netsh.exe interface ipv6 set interface interface=3 forwarding=enabled %STORAGEARG% > NUL ECHO Configuring this computer to send router advertisements on interface "%TSP_HOME_INTERFACE%" netsh.exe interface ipv6 set interface "%TSP_HOME_INTERFACE%" advertise=enabled %STORAGEARG% > NUL if errorlevel 1 goto fail7 echo You got the IPv6 prefix : %TSP_PREFIX%/%TSP_PREFIXLEN% netsh.exe interface ipv6 add route prefix=%TSP_PREFIX%::/64 interface="%TSP_HOME_INTERFACE%" siteprefixlength=64 publish=yes %STORAGEARG% > NUL if NOT %WINDOWS_VERSION% == 7 if errorlevel 1 goto fail4 goto success Rem *** Windows 2000 script path *** :windows_2000 if %TSP_TUNNEL_MODE% == v6udpv4 goto fail3 echo IPv4 tunnel server address configured : %TSP_SERVER_ADDRESS_IPV4% ipv6.exe rtu ::/0 2/::%TSP_SERVER_ADDRESS_IPV4% pub if errorlevel 1 goto fail1 echo IPv6 host address configured : %TSP_CLIENT_ADDRESS_IPV6% ipv6.exe adu 2/%TSP_CLIENT_ADDRESS_IPV6% if errorlevel 1 goto fail2 if %TSP_HOST_TYPE% == router GOTO router_config_2000 goto success :router_config_2000 echo This computer will be configured as IPv6 router and it will do router advertisements for autoconfiguration > %LOG% echo Configuring IPv6_forwarding Rem we turn on forwarding on all interfaces here Rem to address the fact we need to enable it Rem on the 6to4 interface and its interface Rem number is variable ipv6.exe ifc %TSP_HOME_INTERFACE% forwards ipv6.exe ifc 2 forwards ipv6.exe ifc 3 forwards ipv6.exe ifc 4 forwards ipv6.exe ifc 5 forwards ipv6.exe ifc 6 forwards ipv6.exe ifc 7 forwards ipv6.exe ifc 8 forwards echo Configuring routing advertisement on the specified interface ipv6.exe ifc %TSP_HOME_INTERFACE% advertises echo You got the IPv6 prefix : %TSP_PREFIX%::/%TSP_PREFIXLEN% echo Your network interface %TSP_HOME_INTERFACE% will advertise %TSP_PREFIX%::/64 ipv6.exe rtu %TSP_PREFIX%::/64 %TSP_HOME_INTERFACE% publish life 86400 spl 64 if errorlevel 1 goto fail4 echo Address %TSP_PREFIX%::1 confired on interface %TSP_HOME_INTERFACE% ipv6.exe adu %TSP_HOME_INTERFACE%/%TSP_PREFIX%::1 goto success :fail0 echo Failed : IPv6 not installed. Use the command "ipv6 install" to enable it. exit 1 goto end :fail1 Echo Failed : cannot use the IPv4 tunnel server address exit 1 goto end :fail2 Echo Failed : cannot use the IPv6 host address exit 1 goto end :fail3 Echo Failed : cannot setup nat traversal exit 1 goto end :fail4 Echo Failed : cannot assign the %TSP_PREFIX% route on interface %TSP_HOME_INTERFACE% exit 1 goto end :fail5 Echo Failed : cannot disable the firewall on the outgoing interface exit 1 goto end :fail6 Echo Failed : cannot configure %TSP_PREFIX% on the %TSP_HOME_INTERFACE% interface exit 1 goto end :fail7 Echo Failed : cannot advertise the prefix %TSP_PREFIX%/64 on interface %TSP_HOME_INTERFACE% exit 1 goto end :fail8 Echo Failed : cannot set the MTU to 1280 on the tunnel interface exit 1 goto end :fail9 Echo Failed : cannot create a new v6v4 tunnel interface exit 1 goto end :fail10 Echo Failed : IPv6 not installed. Use the command "netsh interface ipv6 install" to enable it. exit 1 goto end :success Echo Success ! Now, you're ready to use IPv6 connectivity to Internet IPv6 if %TSP_HOST_TYPE% == router GOTO success2 goto end :success2 Echo The tunnel server uses this IPv6 address : %TSP_SERVER_ADDRESS_IPV6% Echo The prefix advertised is %TSP_PREFIX%/64 on interface %TSP_HOME_INTERFACE% goto end :success_v4v6 Echo Success! Now, you're ready to use IPv4 over IPv6! goto end :end Echo End of the script gogoc-1_2-RELEASE/gogoc-tsp/template/windows.cmd0100644000000000000000000005022211344777406020222 0ustar rootroot@ECHO OFF REM ######################################################################### REM $Id: windows.cmd,v 1.3 2010/03/07 19:31:18 carl Exp $ REM REM This source code copyright (c) gogo6 Inc. 2002-2007. REM REM For license information refer to CLIENT-LICENSE.TXT REM REM Description: REM This is the Windows version template script used by the gogoCLIENT REM to set(or destroy) up the negotiated tunnel. This script has multiple REM input parameters that are set in environment variables. Here's a short REM description for every variable set: REM REM TSP_TUNNEL_MODE: Tunnel mode (e.g.: v6v4, v6udpv4, v4v6) REM TSP_HOST_TYPE: Host type (e.g.: host or router) REM TSP_TUNNEL_INTERFACE: Tunneling interface to use (v6udpv4 & v4v6). REM TSP_HOME_INTERFACE: Interface used for router advertisements. REM TSP_CLIENT_ADDRESS_IPV4: Client IPv4 local endpoint address. REM TSP_CLIENT_ADDRESS_IPV6: Client IPv6 local endpoint address. REM TSP_CLIENT_DNS_NAME: Delegated user domain. REM TSP_SERVER_ADDRESS_IPV4: Server IPv4 remote endpoint address. REM TSP_SERVER_ADDRESS_IPV6: Server IPv6 remote endpoint address. REM TSP_TUNNEL_PREFIXLEN: Tunnel address length (e.g.: 128 or 32) REM TSP_PREFIX: Delegated prefix. REM TSP_PREFIXLEN: Delegated prefix length. REM TSP_VERBOSE: Verbosity level. Always 3. Not used. REM TSP_HOME_DIR: gogoCLIENT Installation directory. REM TSP_LOCAL_DNS[XX]: Local configured DNS server(s). REM TSP_OPERATION: The operation requested (CREATE or TEARDOWN) REM REM This script officially supoprts the following Windows versions: REM - Windows XP SP2 (32 and 64-bits), REM - Windows 2003 Server (32 and 64-bits), REM - Windows Vista (32 and 64-bits), REM This script may work on other versions of Windows, but it has not been REM tested. REM REM Author: Charles Nepveu REM REM Date created: June 2007 REM REM ######################################################################### REM Constant definitions, and variable initialisation. SET V6V4_STATIC_INTERFACE=gogo6_tunv6 SET NETSH_COMMAND_SCRIPT="%TSP_HOME_DIR%\netsh_tun_cmd.txt" SET NETSH_PERS=store=active SET ERRNO=0 REM Timestamp script start time. ECHO Script execution time: %DATE%, %TIME% REM Verify if the proper environment variables are set. If they're not, REM it's probably because this script was not invoked from the gogoCLIENT. IF "%TSP_HOME_DIR%" == "" GOTO PROC_ERR IF "%TSP_SERVER_ADDRESS_IPV4%" == "" GOTO PROC_ERR REM Determine Windows version. CALL :GET_WIN_VER_PROCEDURE IF %ERRNO% NEQ 0 GOTO PROC_ERR REM Verify if Windows version is supported. CALL :VERI_VER_PROCEDURE IF %ERRNO% NEQ 0 GOTO PROC_ERR REM Check if IPv6 is functionnal on local computer. CALL :IPV6_TEST_PROCEDURE IF %ERRNO% NEQ 0 GOTO PROC_ERR REM Check what operation we're attempting to do (CREATE, TEARDOWN). IF /i "%TSP_OPERATION%" == "TSP_TUNNEL_CREATION" CALL :OP_CREATE_TUN_PROCEDURE IF /i "%TSP_OPERATION%" == "TSP_TUNNEL_TEARDOWN" CALL :OP_TEARDOWN_TUN_PROCEDURE IF %ERRNO% NEQ 0 GOTO PROC_ERR REM Successful completion. GOTO :END_SUCCESS REM ------------------------------------------------------------------------- :GET_WIN_VER_PROCEDURE REM Retrieves the Windows version and sets it in WIN_VER variable. REM Windows version _can_ be provided by the environment variable REM TSP_CLIENT_OS. IF "%TSP_CLIENT_OS%" == "" GOTO :RUN_WIN_VER IF /i %TSP_CLIENT_OS% == winxpsp2 SET WIN_VER=2 && GOTO :EOF IF /i %TSP_CLIENT_OS% == winxp64 SET WIN_VER=6 && GOTO :EOF IF /i %TSP_CLIENT_OS% == winxp64sp1 SET WIN_VER=5 && GOTO :EOF IF /i %TSP_CLIENT_OS% == winxp64sp2 SET WIN_VER=8 && GOTO :EOF IF /i %TSP_CLIENT_OS% == win2003 SET WIN_VER=6 && GOTO :EOF IF /i %TSP_CLIENT_OS% == win2003sp1 SET WIN_VER=5 && GOTO :EOF IF /i %TSP_CLIENT_OS% == win2003sp2 SET WIN_VER=8 && GOTO :EOF IF /i %TSP_CLIENT_OS% == winvista SET WIN_VER=7 && GOTO :EOF IF /i %TSP_CLIENT_OS% == winxpsp3 SET WIN_VER=9 && GOTO :EOF GOTO :EOF :RUN_WIN_VER REM Run the win-ver executable and retrieve Windows version from errorlevel. "%TSP_HOME_DIR%\win-ver.exe" SET WIN_VER=%ERRORLEVEL% GOTO :EOF REM ------------------------------------------------------------------------- :VERI_VER_PROCEDURE REM Verifies if the Windows version detected earlier is supported in this REM script. REM Verify if Windows version was identified. IF "%WIN_VER%" == "" ( SET ERRNO=10 GOTO :EOF ) REM 1 = Windows XP SP1 REM 2 = Windows XP SP2 REM 3 = Windows XP REM 4 = Windows 2000 REM 5 = Windows Server 2003 SP1 / XP 64 SP1 REM 6 = Windows Server 2003 / XP 64 REM 7 = Windows Vista REM 8 = Windows Server 2003 SP2 / XP 64 SP2 REM 9 = Windows XP SP3 IF %WIN_VER% EQU 2 GOTO :EOF IF %WIN_VER% EQU 5 GOTO :EOF IF %WIN_VER% EQU 6 GOTO :EOF IF %WIN_VER% EQU 7 GOTO :EOF IF %WIN_VER% EQU 8 GOTO :EOF IF %WIN_VER% EQU 9 GOTO :EOF REM Version is not supported SET ERRNO=11 GOTO :EOF REM ------------------------------------------------------------------------- :IPV6_TEST_PROCEDURE REM Runs a simple test on the local computer to verify IPv6 connectivity. PING -6 -n 1 ::1 > NUL IF ERRORLEVEL 1 SET ERRNO=12 GOTO :EOF REM ------------------------------------------------------------------------- :OP_CREATE_TUN_PROCEDURE REM This is the path for tunnel creation REM Delete existing V6V4 builtin interface if it is still there. REM In case it was not deleted. REM TODO: Should perform entire cleanup. netsh int ipv6 dele int %V6V4_STATIC_INTERFACE% > NUL REM Set up the tunnel, with the negotiated parameters. IF /i %TSP_TUNNEL_MODE% == v6v4 CALL :V6V4_TUN_PROCEDURE IF /i %TSP_TUNNEL_MODE% == v6udpv4 CALL :V6UDPV4_TUN_PROCEDURE IF /i %TSP_TUNNEL_MODE% == v4v6 CALL :V4V6_TUN_PROCEDURE IF /i %ERRNO% NEQ 0 GOTO :EOF REM Perform router configuration, if host type is router. IF /i %TSP_HOST_TYPE% == router CALL :ROUTER_CONFIG_PROCEDURE IF %ERRNO% NEQ 0 GOTO :EOF REM Finished tunnel setup. GOTO :EOF REM ------------------------------------------------------------------------- :V6V4_TUN_PROCEDURE REM Sets up the V6V4 tunnel with the built-in tunnel interface. REM Override tunnel interface with static one. SET TSP_TUNNEL_INTERFACE=%V6V4_STATIC_INTERFACE% ECHO Setting up a V6V4 tunnel using built-in windows v6v4tunnel. ECHO Tunnel interface is: "%TSP_TUNNEL_INTERFACE%" REM Create the v6v4 tunnel interface. ECHO Creating the v6v4 tunnel interface ... netsh int ipv6 add v6v4tunnel "%TSP_TUNNEL_INTERFACE%" %TSP_CLIENT_ADDRESS_IPV4% %TSP_SERVER_ADDRESS_IPV4% > NUL IF ERRORLEVEL 1 ( SET ERRNO=20 GOTO :EOF ) REM Add the local IPv6 address on the v6v4 tunnel interface. ECHO Adding IPv6 address to the v6v4 tunnel interface ... netsh int ipv6 add addr "%TSP_TUNNEL_INTERFACE%" %TSP_CLIENT_ADDRESS_IPV6% %NETSH_PERS% > NUL IF ERRORLEVEL 1 ( SET ERRNO=21 GOTO :EOF ) REM Route all IPv6 traffic on the v6v4 tunnel interface. ECHO Routing all IPv6 traffic through the v6v4 tunnel interface ... netsh int ipv6 add route ::/0 "%TSP_TUNNEL_INTERFACE%" publish=yes %NETSH_PERS% > NUL IF ERRORLEVEL 1 ( SET ERRNO=22 GOTO :EOF ) REM Set the MTU to 1280 on the v6v4 tunnel interface. ECHO Setting MTU to 1280 on v6v4 tunnel interface ... netsh int ipv6 set int "%TSP_TUNNEL_INTERFACE%" MTU=1280 > NUL IF ERRORLEVEL 1 ( SET ERRNO=23 GOTO :EOF ) REM Set the DNS server on the v6v4 tunnel interface. IF NOT "%TSP_CLIENT_DNS_ADDRESS_IPV6%" == "" ( ECHO Setting the DNS server on the v6v4 tunnel interface ... netsh int ipv6 set dnsserver "%TSP_TUNNEL_INTERFACE%" static %TSP_CLIENT_DNS_ADDRESS_IPV6% none ) REM Finished setting up the v6v4 tunnel interface. ECHO V6V4 tunnel configuration successful. GOTO :EOF REM ------------------------------------------------------------------------- :V6UDPV4_TUN_PROCEDURE REM Sets up the V6UDPV4 tunnel, by configuring the gogotun tunnel adapter. ECHO Setting up a V6UDPV4 tunnel using gogo6's Multi-Virtual Tunnel Adapter. ECHO Tunnel interface is: "%TSP_TUNNEL_INTERFACE%" REM Set the IPv6 address on the tunnel interface. ECHO Setting IPv6 address on v6udpv4 tunnel interface ... netsh int ipv6 set addr "%TSP_TUNNEL_INTERFACE%" %TSP_CLIENT_ADDRESS_IPV6% %NETSH_PERS% > NUL IF ERRORLEVEL 1 ( SET ERRNO=30 GOTO :EOF ) REM Set the MTU to 1280 on the v6udpv4 tunnel interface. ECHO Setting MTU to 1280 on v6udpv4 tunnel interface ... netsh int ipv6 set int "%TSP_TUNNEL_INTERFACE%" MTU=1280 > NUL IF ERRORLEVEL 1 ( SET ERRNO=31 GOTO :EOF ) REM Windows vista hack: REM If the tunnel interface does not have a configured DNS server in its IPv4 REM stack, resolving of IPv6 addresses will fail. IF %WIN_VER% NEQ 7 GOTO :SKIP_VISTA_DNS_HACK ECHO Adding DNS servers to tunnel v6udpv4 tunnel interface ... IF DEFINED TSP_LOCAL_DNS01 netsh int ipv4 add dnsserver name="%TSP_TUNNEL_INTERFACE%" addr=%TSP_LOCAL_DNS01% > NUL IF DEFINED TSP_LOCAL_DNS02 netsh int ipv4 add dnsserver name="%TSP_TUNNEL_INTERFACE%" addr=%TSP_LOCAL_DNS02% > NUL :SKIP_VISTA_DNS_HACK REM Adding a route to the nexthop (which is the IPv6 address of the server) ECHO Adding a route to the remote tunnel IPV6 endpoint ... netsh int ipv6 add route %TSP_SERVER_ADDRESS_IPV6%/128 "%TSP_TUNNEL_INTERFACE%" %NETSH_PERS% > NUL IF %WIN_VER% NEQ 7 IF ERRORLEVEL 1 ( SET ERRNO=32 GOTO :EOF ) REM Route all IPv6 traffic through the v6udpv4 tunnel interface. ECHO Routing all IPv6 traffic through the v6udpv4 tunnel interface ... netsh int ipv6 add route ::/0 "%TSP_TUNNEL_INTERFACE%" publish=yes %NETSH_PERS% > NUL IF %WIN_VER% NEQ 7 IF ERRORLEVEL 1 ( SET ERRNO=33 GOTO :EOF ) REM Set the DNS server on the v6udpv4 tunnel interface. IF NOT "%TSP_CLIENT_DNS_ADDRESS_IPV6%" == "" ( ECHO Setting the DNS server on the v6udpv4 tunnel interface ... netsh int ipv6 set dnsserver "%TSP_TUNNEL_INTERFACE%" static %TSP_CLIENT_DNS_ADDRESS_IPV6% none ) REM Finished setting up the v6v4 tunnel interface. ECHO V6UDPV4 tunnel configuration successful. GOTO :EOF REM ------------------------------------------------------------------------- :V4V6_TUN_PROCEDURE REM Sets up the V4V6 tunnel, by configuring the gogotun tunnel adapter. ECHO Setting up a V4V6 tunnel using gogo6's Multi-Virtual Tunnel Adapter. ECHO Tunnel interface is: "%TSP_TUNNEL_INTERFACE%" REM Set the IPv4 address on the tunnel interface. ECHO Setting IPv4 address on v4v6 tunnel interface ... netsh int ip set addr "%TSP_TUNNEL_INTERFACE%" static %TSP_CLIENT_ADDRESS_IPV4% 255.255.255.0 > NUL IF ERRORLEVEL 1 ( SET ERRNO=40 GOTO :EOF ) REM Adding a route to the nexthop (which is the IPv4 address of the server) ECHO Adding a route to the remote tunnel IPv4 endpoint ... IF %WIN_VER% EQU 7 ( netsh int ip add route %TSP_SERVER_ADDRESS_IPV4%/32 "%TSP_TUNNEL_INTERFACE%" %TSP_CLIENT_ADDRESS_IPV4% %NETSH_PERS% > NUL ) ELSE ( route add %TSP_SERVER_ADDRESS_IPV4% mask 255.255.255.255 %TSP_CLIENT_ADDRESS_IPV4% ) IF ERRORLEVEL 1 ( SET ERRNO=41 GOTO :EOF ) REM Route all IPv4 traffic through the v4v6 tunnel interface. ECHO Routing all IPv4 traffic through the v4v6 tunnel interface ... IF %WIN_VER% EQU 7 ( netsh int ip add route 0.0.0.0/0 "%TSP_TUNNEL_INTERFACE%" %TSP_SERVER_ADDRESS_IPV4% publish=yes %NETSH_PERS% > NUL ) ELSE ( REM Wait 5 secs, then put route. Required by Win2003srvSP2. ping -n 5 ::1 > NUL route add 0.0.0.0 mask 0.0.0.0 %TSP_SERVER_ADDRESS_IPV4% ) IF ERRORLEVEL 1 ( SET ERRNO=42 GOTO :EOF ) REM Set interface MTU to 1240 for Windows Vista, else it fails transferring big packets. IF %WIN_VER% EQU 7 ( ECHO Setting interface MTU to 1240. netsh int ip set int "%TSP_TUNNEL_INTERFACE%" mtu=1240 %NETSH_PERS% > NUL IF ERRORLEVEL 1 ( SET ERRNO=43 GOTO :EOF ) ) REM Finished setting up the v4v6 tunnel interface. ECHO V4V6 tunnel configuration successful. GOTO :EOF REM ------------------------------------------------------------------------- :ROUTER_CONFIG_PROCEDURE REM Sets the local computer to send router advertisements on a local REM interface. ECHO Configuring local computer to act as a router. ECHO Routing advertisements will be published on interface "%TSP_HOME_INTERFACE%". REM Adding first address of prefix to the publishing interface. ECHO Adding first address of prefix to the publishing interface ... netsh int ipv6 set addr "%TSP_HOME_INTERFACE%" %TSP_PREFIX%::1 %NETSH_PERS% > NUL IF ERRORLEVEL 1 ( SET ERRNO=50 GOTO :EOF ) REM Enable forwarding on tunnel interface. ECHO Enabling forwarding on tunnel interface ... netsh int ipv6 set int "%TSP_TUNNEL_INTERFACE%" forwarding=enabled > NUL IF ERRORLEVEL 1 ( SET ERRNO=51 GOTO :EOF ) REM Enable forwarding and router advertisements on the publishing interface. ECHO Enabling forwarding and router advertisement on the publishing interface ... netsh int ipv6 set int "%TSP_HOME_INTERFACE%" forwarding=enabled advertise=enabled > NUL IF ERRORLEVEL 1 ( SET ERRNO=52 GOTO :EOF ) REM Route the first /64 of the prefix on the tunnel interface. ECHO Routing first /64 of the prefix on the publishing interface ... netsh int ipv6 add route %TSP_PREFIX%::/64 "%TSP_HOME_INTERFACE%" siteprefixlength=64 publish=yes %NETSH_PERS% > NUL IF %WIN_VER% NEQ 7 IF ERRORLEVEL 1 ( SET ERRNO=53 GOTO :EOF ) REM Finished router configuration. ECHO Router configuration successful. GOTO :EOF REM ------------------------------------------------------------------------- :OP_TEARDOWN_TUN_PROCEDURE REM This is the execution path to deconfigure an existing tunnel. REM No validation is done here. We try to delete it the best we can. REM Destroy & create a netsh command script to deconfigure tunnel. ECHO. > %NETSH_COMMAND_SCRIPT% REM Set up the tunnel, with the negotiated parameters. IF /i %TSP_TUNNEL_MODE% == v6v4 CALL :V6V4_DECONFIGURE_PROCEDURE >> %NETSH_COMMAND_SCRIPT% IF /i %TSP_TUNNEL_MODE% == v6udpv4 CALL :V6UV4_DECONFIGURE_PROCEDURE >> %NETSH_COMMAND_SCRIPT% IF /i %TSP_TUNNEL_MODE% == v4v6 CALL :V4V6_DECONFIGURE_PROCEDURE >> %NETSH_COMMAND_SCRIPT% REM Perform router deconfiguration, if host type is router. IF /i %TSP_HOST_TYPE% == router CALL :RT_DECONFIGURE_PROCEDURE >> %NETSH_COMMAND_SCRIPT% REM Run the netsh command script. netsh -f %NETSH_COMMAND_SCRIPT% REM Cleanup. del %NETSH_COMMAND_SCRIPT% REM Finished tunnel deconfiguration. GOTO :EOF REM ------------------------------------------------------------------------- :V6V4_DECONFIGURE_PROCEDURE REM This procedure deconfigures and deletes the interface for V6V4. REM Also deletes relevant routes. REM Override tunnel interface. SET TSP_TUNNEL_INTERFACE=%V6V4_STATIC_INTERFACE% REM Context. ECHO interface ipv6 REM Delete DNS Server. IF NOT "%TSP_CLIENT_DNS_ADDRESS_IPV6%" == "" ( ECHO dele dnsserver "%TSP_TUNNEL_INTERFACE%" %TSP_CLIENT_DNS_ADDRESS_IPV6% ) REM Delete IPv6 address assigned. ECHO dele addr inter="%TSP_TUNNEL_INTERFACE%" addr=%TSP_CLIENT_ADDRESS_IPV6% REM Delete route assigned. ECHO dele route prefix=::/0 inter="%TSP_TUNNEL_INTERFACE%" REM Delete interface. ECHO dele inter inter="%V6V4_STATIC_INTERFACE%" GOTO :EOF REM ------------------------------------------------------------------------- :V6UV4_DECONFIGURE_PROCEDURE REM This procedure deconfigures the interface for V6UDPV4. REM Also deletes relevant routes. REM Context. ECHO interface ipv6 REM Delete DNS Server. IF NOT "%TSP_CLIENT_DNS_ADDRESS_IPV6%" == "" ( ECHO dele dnsserver "%TSP_TUNNEL_INTERFACE%" %TSP_CLIENT_DNS_ADDRESS_IPV6% ) REM Delete IPv6 address assigned. ECHO dele addr inter="%TSP_TUNNEL_INTERFACE%" addr=%TSP_CLIENT_ADDRESS_IPV6% REM Delete route to nexthop. ECHO dele route prefix=%TSP_SERVER_ADDRESS_IPV6%/128 inter="%TSP_TUNNEL_INTERFACE%" REM Delete route assigned. ECHO dele route prefix=::/0 inter="%TSP_TUNNEL_INTERFACE%" GOTO :EOF REM ------------------------------------------------------------------------- :V4V6_DECONFIGURE_PROCEDURE REM This procedure deconfigures the interface for V4V6. REM Also deletes relevant routes. REM Context. ECHO interface ip REM Delete assigned IPv4 address. ECHO dele addr "%TSP_TUNNEL_INTERFACE%" addr=%TSP_CLIENT_ADDRESS_IPV4% gateway=all REM Delete next-hop route. IF %WIN_VER% EQU 7 ( ECHO dele route prefix=%TSP_SERVER_ADDRESS_IPV4%/32 inter="%TSP_TUNNEL_INTERFACE%" ) ELSE ( route delete %TSP_SERVER_ADDRESS_IPV4% mask 255.255.255.255 %TSP_CLIENT_ADDRESS_IPV4% ) REM Delete assigned route. IF %WIN_VER% EQU 7 ( ECHO dele route prefix=0.0.0.0/0 inter="%TSP_TUNNEL_INTERFACE%" ) ELSE ( route delete 0.0.0.0 mask 0.0.0.0 %TSP_SERVER_ADDRESS_IPV4% ) GOTO :EOF REM ------------------------------------------------------------------------- :RT_DECONFIGURE_PROCEDURE REM Context. REM Delete assigned IPv6 address. ECHO dele addr inter="%TSP_HOME_INTERFACE%" addr=%TSP_PREFIX%::1 REM Disable forwarding on tunnel interface. ECHO set int inter="%TSP_TUNNEL_INTERFACE%" forwarding=disabled REM Disable forwarding and router advertisements on the publishing interface. ECHO set int inter="%TSP_HOME_INTERFACE%" forwarding=disabled advertise=disabled REM Route the first /64 of the prefix on the tunnel interface. ECHO dele route prefix=%TSP_PREFIX%::/64 inter="%TSP_HOME_INTERFACE%" GOTO :EOF REM ------------------------------------------------------------------------- :PROC_ERR REM Error procedure. This prints the error message relative to ERRNO and REM exits script with the error code. REM Check if ERRNO is still set to 0. This means that the script was run from REM outside the gogoCLIENT. Do not call 'Exit' and end script. IF %ERRNO% EQU 0 ( ECHO ERROR: This script is meant to be executed inside the gogoCLIENT. ECHO Script execution terminated. GOTO :END ) REM Print an error message, relative to the error number previously set. IF %ERRNO% EQU 10 ECHO ERROR: Failed to identify your Windows version. && GOTO :END_ERR IF %ERRNO% EQU 11 ECHO ERROR: This version of windows is not supported by this script. && GOTO :END_ERR IF %ERRNO% EQU 12 ECHO ERROR: Failed to detect IPv6 connectivity on local computer. && GOTO :END_ERR IF %ERRNO% EQU 20 ECHO ERROR: Failed creation of v6v4tunnel. && GOTO :END_ERR IF %ERRNO% EQU 21 ECHO ERROR: Failed addition of local IPv6 address to tunnel interface. && GOTO :END_ERR IF %ERRNO% EQU 22 ECHO ERROR: Failed adding default route to tunnel interface. && GOTO :END_ERR IF %ERRNO% EQU 23 ECHO ERROR: Failed setting MTU on tunnel interface. && GOTO :END_ERR IF %ERRNO% EQU 30 ECHO ERROR: Failed assigning local IPv6 address to tunnel interface. && GOTO :END_ERR IF %ERRNO% EQU 31 ECHO ERROR: Failed setting MTU on tunnel interface. && GOTO :END_ERR IF %ERRNO% EQU 32 ECHO ERROR: Failed adding a route to the remote tunnel endpoint. && GOTO :END_ERR IF %ERRNO% EQU 33 ECHO ERROR: Failed adding default route to tunnel interface. && GOTO :END_ERR IF %ERRNO% EQU 40 ECHO ERROR: Failed assigning local IPv4 address to tunnel interface. && GOTO :END_ERR IF %ERRNO% EQU 41 ECHO ERROR: Failed adding a route to the remote tunnel endpoint. && GOTO :END_ERR IF %ERRNO% EQU 42 ECHO ERROR: Failed adding default route to tunnel interface. && GOTO :END_ERR IF %ERRNO% EQU 43 ECHO ERROR: Failed setting MTU on tunnel interface. && GOTO :END_ERR IF %ERRNO% EQU 50 ECHO ERROR: Failed assigning first prefix address to publishing interface. && GOTO :END_ERR IF %ERRNO% EQU 51 ECHO ERROR: Failed enabling forwarding on tunnel interface. && GOTO :END_ERR IF %ERRNO% EQU 52 ECHO ERROR: Failed enabling forwarding and advertisements on publishing interface. && GOTO :END_ERR IF %ERRNO% EQU 53 ECHO ERROR: Failed adding a route on the publishing interface. && GOTO :END_ERR :END_ERR ECHO Template script execution failed! Exiting with error code %ERRNO%. IF /i "%TSP_SCRIPT_ORIGIN%" == "gogoCLIENT" PAUSE exit %ERRNO% GOTO :END REM ------------------------------------------------------------------------- :END_SUCCESS REM Script terminated without error. ECHO Template script execution successful. GOTO :END REM ------------------------------------------------------------------------- REM Absolute end of script. :END gogoc-1_2-RELEASE/README0100644000000000000000000000625111346561546013207 0ustar rootroot -*- text -*- gogoCLIENT v1.2-RELEASE ============================ Current Web home: http://gogo6.com/ What's New ---------- Take a look at the release notes on http://gogonet.gogo6.com to know which bugs have been resolved, what are the known issues and what new features are included in this version: Description ----------- TSP is a control protocol used to establish and maintain static tunnels. The gogoCLIENT is used on the host computer to connect to a tunnel broker using the TSP protocol and to get the information for its tunnel. When it receives the information for the tunnel, the gogoCLIENT creates the static tunnel on its operating system. The gogoCLIENT code is mostly identical for all client platforms. However, creating the static tunnel is operating system dependent and is done by a script called by the gogoCLIENT. These scripts are located under the template directory in the gogoCLIENT installation directory. The script executed by the gogoCLIENT to configure the tunnel interface is customized for each type of supported operating system and takes care of all specifics for the target operating system. On Unix systems, it is a shell script. This separation of the binary and script enables fast and easy additions of new operating systems, as has been shown by the community contributions for many operating systems. Packaging --------- The gogoCLIENT is available either as part of the operating system distributions, such as Linux or FreeBSD; as downloadable software from the Web site of the tunnel broker service, such as Freenet6 (http://gogonet.gogo6.com); as included in the gogoSERVER CD-ROM; or directly from gogo6 (http://www.gogo6.com). Multi-site operation -------------------- The gogoCLIENT may be used to connect to a single gogoSERVER or to multiple servers across different locations. This serves two purposes: providing better quality of service by having users connect to the closest server and also provide redundancy if one site is unavailable. The mechanism used by TSP to announce multiple sites is called a broker list or broker redirection (in the case there's only one element in the list). The client receiving a broker list will test which sites are available and their respective topological distance using echo messages. The client then connects to each broker in the list, the closest one first, until a successful connection is established. Executing the gogoCLIENT ----------------------------- The gogoCLIENT is executed manually by typing the command gogoc. If no keepalive is negotiated, the gogoCLIENT program exits after setting up the tunnel. If the keepalive mechanism is negotiated, the gogoCLIENT forks itself and runs in the background to carry the keepalive with the tunnel broker. Keepalives are mandatory for IPv6 in UDP IPv4 tunnels to keep the NAT mapping up, but are optional for IPv6 in IPv4 tunnels and IPv4 in IPv6 tunnels. Please report bugs in the gogoCLIENT on http://gogonet.gogo6.com. MAINTAINER: gogo6, inc (http://www.gogo6.com/) Copyright (C) 2010 gogo6, inc. See CLIENT-LICENSE.TXT for license information. gogoc-1_2-RELEASE/INSTALL0100644000000000000000000001074411346467417013364 0ustar rootroot -*- text -*- gogoCLIENT Installation Procedure ====================================== 0. Introduction --------------- This document describes how to build the gogoCLIENT from source code on Unix-like systems. The preferred form of building the gogoCLIENT is to get a release archive and unpack it (which you have presumably done, since you are reading this). Four directories will be extracted from the archive: - gogoc-tsp (The gogoCLIENT Application) - gogoc-pal (Abstraction Layer submodule) - gogoc-config (Configuration submodule) - gogoc-messaging (Messaging submodule) 1. Dependencies --------------- To build the gogoCLIENT, your system must support a Unix-like command-line development environment, including the text-processing utilities (sh, grep, awk, sed, etc.) and a functional GNU C and C++ compiler. On some GNU/Linux systems, this means that you will need to install packages such as `gcc', `g++', `glibc-devel' (or `libc6-dev') and `gmake'. Most systems come with these packages preinstalled, but it doesn't hurt to check. If you have successfully compiled other software from source, you probably have them all. In addition to the C and C++ development environment, the gogoCLIENT can use a number of libraries to provide additional features, such as encrypted authentication. The "external" dependencies include: - OpenSSL -- for encryption routines. - libcrypto -- for encryption routines. - libpthread -- for POSIX threading. - libsocket, libnsl -- for SOLARIS platforms only. - GNU make. To be usable for building the gogoCLIENT, the listed libraries must be installed with their "development" header files. On GNU/Linux systems this typically means installing the corredponsing "lib-devel" or "lib-dev" package along with the package with "lib". 1.1 Kernel Dependencies ----------------------- In order to make the gogoCLIENT function properly, your system kernel must support the following: - Universal TUN/TAP device driver support. - IPv6-In-IPv4 tunneling support. - IPv4-In-IPv6 tunneling support (optional). - IPv6 support. These dependencies can be directly built in your system kernel, or dynamically loaded modules. In the later case, make sure the modules are loaded when starting the gogoCLIENT. 2. Configuration ---------------- As of now, no configuration script is provided. The current setting is generic and will, in most cases, work without modification. 3. Compilation -------------- To compile the gogoCLIENT, using the GNU make tool, move to the gogoc-tsp directory and simply type the following command: > gmake(or make) [platform=] all The `platform' variable is optional and usually automaticaly detected. However, if you need to specify it, the possible values are: - linux, freebsd, netbsd, openbsd, darwin, solaris, openwrt NOTE: You require the GNU make tool to interpret the makefiles correctly. Please report any problems related to configuration and compilation of the gogoCLIENT on the Go6 discussion forum (http://www.go6.net) or by email at support@go6.net. 4. Installation --------------- After the compilation a ready-to-use `gogoc' executable should reside in the bin directory. The next step is to install the compiled binary along with its default configuration file on your system. The following command will install the gogoCLIENT in the /usr/local/gogoc directory: > make [platform=] installdir=/usr/local/gogoc install Note that superuser privileges will probably be required to install the gogoCLIENT. You will probably want to edit the gogoCLIENT configuration file to specify your registered username, password and server . The configuration file can be found in the gogoCLIENT installation `bin' directory. To launch the gogoCLIENT, change directory to your installation `bin' directory (i.e.: /usr/local/gogoc/bin ) and type: ./gogoc The following command line options are available: -y Assume yes; assume that the answer to any questions asked is yes. Particularly useful for automatically adding public keys when running gogoCLIENT as a service and using authenticated mode. -n Run googCLIENT in foreground mode. Useful for debugging. -b Boot mode; stop trying to connect and exit when unable to connect. Consult the gogoc.log file to troubleshoot connection. You can enable more information to be printed in the log file by modifying the gogoCLIENT configuration file. gogoc-1_2-RELEASE/CLIENT-LICENSE.TXT0100644000000000000000000000270411346470730014757 0ustar rootrootCopyright (c) 2002-2010 gogo6 All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the gogo6 nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. gogoc-1_2-RELEASE/GUI-LICENSE.TXT0100644000000000000000000000671311346471433014432 0ustar rootrootIMPORTANT READ CAREFULLY: This is the License Agreement for gogo6 gogoCLIENT, in its object code version (the "Product" ). You are required to carefully read and accept the following terms and conditions before using the Product. Unless you have a different license agreement signed by gogo6, Inc. your use of the Product must be preceded by your acceptance of this License Agreement, such acceptance demonstrated by your clicking of the I AGREE button found hereunder. This License Agreement is provided to you free of charge and enables you to install and use the Product on computers such as a workstation, terminal or other devices (Computer), for internal use only and will not by copied or posted on any network computer or broadcast or published in any media. This License Agreement applies to updates, supplements and add-on components of the Product that gogo6, Inc. provides to you unless we provide other terms with the upgrade, supplement or add-on components. You may transfer the Product and all rights under this License Agreement to another party together with a copy of this License Agreement, if the other party agrees to accept the terms of this License Agreement, also by clicking the I AGREE button. If you transfer the Product, you must at the same time transfer all copies whether in printed or machine readable form to the same party or destroy any copies not transferred. You may not reverse engineer, decompile or disassemble the Product, except to the extent that it is expressly permitted by applicable law, notwithstanding this limitation. You may not resell the Product. gogo6, inc. reserves all rights not expressly granted to you in this License Agreement and use for any other purpose is prohibited by law. THIS PRODUCT IS MADE AVAILABLE AS IS BY GOGO6, INC. GOGO6, INC. DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESSED OR IMPLIED, INCLUDING WITHOUT LIMITATION ALL IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN NO EVENT SHALL GOGO6, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL, CONSEQUENTIAL, OR OTHER DAMAGES WHATSOEVER, WHETHER IN AN ACTION OF CONTRACT, TORT, OR STRICT LIABILITY, ARISING OUT OF OR IN ANY CONNECTION WITH THE USE OR PERFORMANCE OF THIS PRODUCT. SOME JURISDICTION DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO THE ABOVE EXCLUSION MAY NOT APPLY TO YOU. YOU MAY ALSO HAVE OTHER LEGAL RIGHTS WHICH VARY FROM JURISDICTION TO JURISDICTION. THESE LIMITATIONS AND EXCLUSIONS OF WARRANTIES AND LIABILITY DO NOT AFFECT OR PREJUDICE THE STATUTORY RIGHTS OF THE CONSUMER; THAT IS, A PERSON ACQUIRING GOODS OTHER THAN IN THE COURSE OF A BUSINESS. This License Agreement shall be governed by and construed in accordance with the laws of the province of Quebec, Canada, excluding that body of law applicable to choice of law and excluding the United Nations Convention on Contracts for the International Sale of Goods and any legislation implementing such Convention, if otherwise applicable. You agree that any action at law or in equity arising out of or relating to these terms shall be filed only in the provincial or federal courts located in the City of Montreal, Quebec and you hereby consent and submit to the personal jurisdiction of such courts for the purposes of litigating any such action. The Product is protected by copyright laws and other intellectual property laws and treaties. The Product is licensed, not sold. gogoSERVER, gogoCLIENT and gogo6 are trademarks of gogo6, inc. gogoc-1_2-RELEASE/Makefile0100644000000000000000000000023211346561546013760 0ustar rootroot# # Global gogoCLIENT Makefile. # all: cd gogoc-tsp && $(MAKE) all install: cd gogoc-tsp && $(MAKE) install clean: cd gogoc-tsp && $(MAKE) cleanall