Compare commits
95 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6af0f293a6 | ||
|
|
a492f30950 | ||
|
|
a43953bc0d | ||
|
|
594801df46 | ||
|
|
3dcbb63a31 | ||
|
|
5d6184961b | ||
|
|
b17e88573e | ||
|
|
2d2ccc0039 | ||
|
|
0a2f9c4b79 | ||
|
|
ae62c35cb9 | ||
|
|
2ec2e73f16 | ||
|
|
d4763e54db | ||
|
|
38b19f633d | ||
|
|
d106ecdc65 | ||
|
|
99a2307d1d | ||
|
|
470c936e63 | ||
|
|
168fc5bfcc | ||
|
|
b34b90f95a | ||
|
|
793790d089 | ||
|
|
19559f4974 | ||
|
|
b999068555 | ||
|
|
4385266bb7 | ||
|
|
c50eb90bee | ||
|
|
1e0927f510 | ||
|
|
b9d43c784c | ||
|
|
46d365cafe | ||
|
|
2f830d3132 | ||
|
|
5884983a2f | ||
|
|
c43acd97bd | ||
|
|
b1f2c93738 | ||
|
|
50912bdf75 | ||
|
|
3a8c91004e | ||
|
|
deaadd053b | ||
|
|
c28a5d3a9b | ||
|
|
8b06a75d8e | ||
|
|
e6cb7a7e10 | ||
|
|
82caa6b81f | ||
|
|
ddfbb919a7 | ||
|
|
7fae42aa4d | ||
|
|
ba59e1a00e | ||
|
|
4fcfee8e82 | ||
|
|
63171b0ce2 | ||
|
|
dcfcf3110d | ||
|
|
53a5f5a243 | ||
|
|
f3922bb3e0 | ||
|
|
af083efb0c | ||
|
|
e7aa63f3bd | ||
|
|
279c932b67 | ||
|
|
69603ff70f | ||
|
|
f20c42d05f | ||
|
|
3ea38c59af | ||
|
|
50292cb8c9 | ||
|
|
e4fc91dde1 | ||
|
|
8086d89e23 | ||
|
|
cc2ead8136 | ||
|
|
10d8157477 | ||
|
|
0a7cb86014 | ||
|
|
2e8c99b7ec | ||
|
|
cb6236691b | ||
|
|
5136525abc | ||
|
|
07da142e65 | ||
|
|
aa21556600 | ||
|
|
16ee65422d | ||
|
|
f0b11dadf1 | ||
|
|
61073bd304 | ||
|
|
20a847e1b4 | ||
|
|
a90807fccb | ||
|
|
25c82076da | ||
|
|
089966d918 | ||
|
|
e95a892fb7 | ||
|
|
564f09ad65 | ||
|
|
a33851b13d | ||
|
|
20e445bf94 | ||
|
|
133707ef57 | ||
|
|
62d14a9c52 | ||
|
|
ab9dda1c61 | ||
|
|
37e78eada1 | ||
|
|
5b4467acd5 | ||
|
|
ff2e2a3d4c | ||
|
|
a599b29b9d | ||
|
|
fc52f0e030 | ||
|
|
35bfefa717 | ||
|
|
845aefc941 | ||
|
|
4fcf3ffc83 | ||
|
|
ac39ebf38a | ||
|
|
3f777ce5e2 | ||
|
|
b0aa690cb4 | ||
|
|
fb11589bb0 | ||
|
|
03c4292eea | ||
|
|
ccaf755da3 | ||
|
|
cba0121574 | ||
|
|
166a105e33 | ||
|
|
a32ea42754 | ||
|
|
949b54fcdd | ||
|
|
b9005b1724 |
9
.gitignore
vendored
9
.gitignore
vendored
@@ -1,12 +1,18 @@
|
|||||||
*~
|
*~
|
||||||
*.[oa]
|
*.[oa]
|
||||||
|
*.lib
|
||||||
*.exe
|
*.exe
|
||||||
|
*.manifest
|
||||||
*.gch
|
*.gch
|
||||||
|
CMakeFiles/*
|
||||||
|
CMakeCache.txt
|
||||||
|
cmake_install.cmake
|
||||||
|
mod_*.dll
|
||||||
|
mod_*.exp
|
||||||
mod_*.so
|
mod_*.so
|
||||||
uhub-admin
|
uhub-admin
|
||||||
adcrush
|
adcrush
|
||||||
uhub
|
uhub
|
||||||
revision.h*
|
|
||||||
build-stamp
|
build-stamp
|
||||||
debian/files
|
debian/files
|
||||||
debian/uhub.debhelper.log
|
debian/uhub.debhelper.log
|
||||||
@@ -15,3 +21,4 @@ debian/uhub.postrm.debhelper
|
|||||||
debian/uhub.prerm.debhelper
|
debian/uhub.prerm.debhelper
|
||||||
debian/uhub.substvars
|
debian/uhub.substvars
|
||||||
uhub-passwd
|
uhub-passwd
|
||||||
|
src/version.h
|
||||||
8
AUTHORS
8
AUTHORS
@@ -3,7 +3,9 @@ Authors of uhub
|
|||||||
|
|
||||||
Jan Vidar Krey, Design and implementation
|
Jan Vidar Krey, Design and implementation
|
||||||
E_zombie, Centos/RedHat customization scripts and heavy load testing
|
E_zombie, Centos/RedHat customization scripts and heavy load testing
|
||||||
FleetCommand, Hub topic
|
FleetCommand, Hub topic plugin code
|
||||||
MiMic, Implemented user commands
|
MiMic, Implemented user commands
|
||||||
tehnick, Debian and Ubuntu packaging.
|
Boris Pek (tehnick), Debian/Ubuntu packaging
|
||||||
|
Tillmann Karras (Tilka), Misc. bug fixes
|
||||||
|
Yoran Heling (Yorhel), TLS/SSL handshake detection bugfixes
|
||||||
|
Blair Bonnett, Misc. bug fixes
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
|
|
||||||
GMAKE=gmake
|
|
||||||
|
|
||||||
all:
|
|
||||||
@${GMAKE} ${.TARGETS}
|
|
||||||
|
|
||||||
${.TARGETS}: all
|
|
||||||
|
|
||||||
198
CMakeLists.txt
Normal file
198
CMakeLists.txt
Normal file
@@ -0,0 +1,198 @@
|
|||||||
|
##
|
||||||
|
## Makefile for uhub
|
||||||
|
## Copyright (C) 2007-2012, Jan Vidar Krey <janvidar@extatic.org>
|
||||||
|
#
|
||||||
|
|
||||||
|
cmake_minimum_required (VERSION 2.8.3)
|
||||||
|
|
||||||
|
project (uhub NONE)
|
||||||
|
enable_language(C)
|
||||||
|
|
||||||
|
set (UHUB_VERSION_MAJOR 0)
|
||||||
|
set (UHUB_VERSION_MINOR 4)
|
||||||
|
set (UHUB_VERSION_PATCH 1)
|
||||||
|
|
||||||
|
set (PROJECT_SOURCE_DIR "${CMAKE_SOURCE_DIR}/src")
|
||||||
|
|
||||||
|
option(RELEASE "Release build, debug build if disabled" ON)
|
||||||
|
option(LINK_SUPPORT "Allow hub linking" OFF)
|
||||||
|
option(SSL_SUPPORT "Enable SSL support" ON)
|
||||||
|
option(USE_OPENSSL "Use OpenSSL's SSL support" ON )
|
||||||
|
option(SQLITE_SUPPORT "Enable SQLite support" ON)
|
||||||
|
option(ADC_STRESS "Enable the stress tester client" OFF)
|
||||||
|
|
||||||
|
find_package(Git)
|
||||||
|
|
||||||
|
if (SSL_SUPPORT)
|
||||||
|
if (USE_OPENSSL)
|
||||||
|
find_package(OpenSSL)
|
||||||
|
else()
|
||||||
|
find_package(GnuTLS)
|
||||||
|
endif()
|
||||||
|
if (NOT GNUTLS_FOUND AND NOT OPENSSL_FOUND)
|
||||||
|
message(FATAL_ERROR "Neither OpenSSL nor GnuTLS are not found!")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (MSVC)
|
||||||
|
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include_directories("${PROJECT_SOURCE_DIR}")
|
||||||
|
|
||||||
|
file (GLOB uhub_SOURCES ${PROJECT_SOURCE_DIR}/core/*.c)
|
||||||
|
list (REMOVE_ITEM uhub_SOURCES
|
||||||
|
${PROJECT_SOURCE_DIR}/core/gen_config.c
|
||||||
|
${PROJECT_SOURCE_DIR}/core/main.c
|
||||||
|
)
|
||||||
|
|
||||||
|
file (GLOB adc_SOURCES ${PROJECT_SOURCE_DIR}/adc/*.c)
|
||||||
|
file (GLOB network_SOURCES ${PROJECT_SOURCE_DIR}/network/*.c)
|
||||||
|
file (GLOB utils_SOURCES ${PROJECT_SOURCE_DIR}/util/*.c)
|
||||||
|
|
||||||
|
set (adcclient_SOURCES
|
||||||
|
${PROJECT_SOURCE_DIR}/tools/adcclient.c
|
||||||
|
${PROJECT_SOURCE_DIR}/core/ioqueue.c
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(adc STATIC ${adc_SOURCES})
|
||||||
|
add_library(network STATIC ${network_SOURCES})
|
||||||
|
add_library(utils STATIC ${utils_SOURCES})
|
||||||
|
if(CMAKE_COMPILER_IS_GNUCC)
|
||||||
|
set_target_properties(utils PROPERTIES COMPILE_FLAGS -fPIC)
|
||||||
|
set_target_properties(network PROPERTIES COMPILE_FLAGS -fPIC)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_dependencies(adc utils)
|
||||||
|
add_dependencies(network utils)
|
||||||
|
|
||||||
|
add_executable(uhub ${PROJECT_SOURCE_DIR}/core/main.c ${uhub_SOURCES} )
|
||||||
|
add_executable(test ${CMAKE_SOURCE_DIR}/autotest/test.c ${uhub_SOURCES} )
|
||||||
|
|
||||||
|
add_library(mod_example MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_example.c)
|
||||||
|
add_library(mod_welcome MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_welcome.c)
|
||||||
|
add_library(mod_logging MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_logging.c ${PROJECT_SOURCE_DIR}/adc/sid.c)
|
||||||
|
add_library(mod_auth_simple MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_auth_simple.c )
|
||||||
|
add_library(mod_chat_history MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_chat_history.c )
|
||||||
|
add_library(mod_chat_only MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_chat_only.c)
|
||||||
|
add_library(mod_topic MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_topic.c)
|
||||||
|
add_library(mod_no_guest_downloads MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_no_guest_downloads.c)
|
||||||
|
|
||||||
|
if (SQLITE_SUPPORT)
|
||||||
|
add_library(mod_auth_sqlite MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_auth_sqlite.c)
|
||||||
|
add_executable(uhub-passwd ${PROJECT_SOURCE_DIR}/tools/uhub-passwd.c)
|
||||||
|
|
||||||
|
target_link_libraries(mod_auth_sqlite sqlite3 utils)
|
||||||
|
target_link_libraries(uhub-passwd sqlite3 utils)
|
||||||
|
set_target_properties(mod_auth_sqlite PROPERTIES PREFIX "")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
target_link_libraries(uhub ws2_32)
|
||||||
|
target_link_libraries(test ws2_32)
|
||||||
|
target_link_libraries(mod_logging ws2_32)
|
||||||
|
target_link_libraries(mod_welcome ws2_32)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set_target_properties(
|
||||||
|
mod_example
|
||||||
|
mod_welcome
|
||||||
|
mod_logging
|
||||||
|
mod_auth_simple
|
||||||
|
mod_chat_history
|
||||||
|
mod_chat_only
|
||||||
|
mod_no_guest_downloads
|
||||||
|
mod_topic
|
||||||
|
PROPERTIES PREFIX "")
|
||||||
|
|
||||||
|
target_link_libraries(uhub ${CMAKE_DL_LIBS} adc network utils)
|
||||||
|
target_link_libraries(test ${CMAKE_DL_LIBS} adc network utils)
|
||||||
|
target_link_libraries(mod_example utils)
|
||||||
|
target_link_libraries(mod_welcome utils)
|
||||||
|
target_link_libraries(mod_auth_simple utils)
|
||||||
|
target_link_libraries(mod_chat_history utils)
|
||||||
|
target_link_libraries(mod_no_guest_downloads utils)
|
||||||
|
target_link_libraries(mod_chat_only utils)
|
||||||
|
target_link_libraries(mod_logging utils)
|
||||||
|
target_link_libraries(mod_topic utils)
|
||||||
|
target_link_libraries(utils network)
|
||||||
|
target_link_libraries(mod_welcome network)
|
||||||
|
target_link_libraries(mod_logging network)
|
||||||
|
|
||||||
|
if(UNIX)
|
||||||
|
add_library(adcclient STATIC ${adcclient_SOURCES})
|
||||||
|
add_executable(uhub-admin ${PROJECT_SOURCE_DIR}/tools/admin.c)
|
||||||
|
target_link_libraries(uhub-admin adcclient adc network utils pthread)
|
||||||
|
target_link_libraries(uhub pthread)
|
||||||
|
target_link_libraries(test pthread)
|
||||||
|
|
||||||
|
if (ADC_STRESS)
|
||||||
|
add_executable(adcrush ${PROJECT_SOURCE_DIR}/tools/adcrush.c ${adcclient_SOURCES})
|
||||||
|
target_link_libraries(adcrush adcclient adc network utils pthread)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (NOT UHUB_REVISION AND GIT_FOUND)
|
||||||
|
execute_process(COMMAND ${GIT_EXECUTABLE} show -s --pretty=format:%h
|
||||||
|
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||||
|
OUTPUT_VARIABLE UHUB_REVISION_TEMP
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
if (UHUB_REVISION_TEMP)
|
||||||
|
set (UHUB_REVISION "git-${UHUB_REVISION_TEMP}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (NOT UHUB_REVISION)
|
||||||
|
set (UHUB_REVISION "release")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set (UHUB_GIT_VERSION "${UHUB_VERSION_MAJOR}.${UHUB_VERSION_MINOR}.${UHUB_VERSION_PATCH}-${UHUB_REVISION}")
|
||||||
|
message (STATUS "Configuring uhub version: ${UHUB_GIT_VERSION}")
|
||||||
|
|
||||||
|
if(OPENSSL_FOUND)
|
||||||
|
set(SSL_LIBS ${OPENSSL_LIBRARIES})
|
||||||
|
add_definitions(-DSSL_SUPPORT=1 -DSSL_USE_OPENSSL=1)
|
||||||
|
include_directories(${OPENSSL_INCLUDE_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (GNUTLS_FOUND)
|
||||||
|
set(SSL_LIBS ${GNUTLS_LIBRARIES})
|
||||||
|
add_definitions(-DSSL_SUPPORT=1 -DSSL_USE_GNUTLS=1 ${GNUTLS_DEFINITIONS})
|
||||||
|
include_directories(${GNUTLS_INCLUDE_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(SSL_SUPPORT)
|
||||||
|
target_link_libraries(uhub ${SSL_LIBS})
|
||||||
|
target_link_libraries(test ${SSL_LIBS})
|
||||||
|
if(UNIX)
|
||||||
|
target_link_libraries(uhub-admin ${SSL_LIBS})
|
||||||
|
endif()
|
||||||
|
target_link_libraries(mod_welcome ${SSL_LIBS})
|
||||||
|
target_link_libraries(mod_logging ${SSL_LIBS})
|
||||||
|
if (ADC_STRESS)
|
||||||
|
target_link_libraries(adcrush ${SSL_LIBS})
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
configure_file ("${PROJECT_SOURCE_DIR}/version.h.in" "${PROJECT_SOURCE_DIR}/version.h")
|
||||||
|
|
||||||
|
mark_as_advanced(FORCE CMAKE_BUILD_TYPE)
|
||||||
|
if (RELEASE)
|
||||||
|
set(CMAKE_BUILD_TYPE Release)
|
||||||
|
else()
|
||||||
|
set(CMAKE_BUILD_TYPE Debug)
|
||||||
|
# add_definitions(-DDEBUG)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (UNIX)
|
||||||
|
install( TARGETS uhub RUNTIME DESTINATION bin )
|
||||||
|
install( TARGETS mod_example mod_welcome mod_logging mod_auth_simple mod_auth_sqlite mod_chat_history mod_chat_only mod_topic mod_no_guest_downloads DESTINATION /usr/lib/uhub/ OPTIONAL )
|
||||||
|
install( FILES ${CMAKE_SOURCE_DIR}/doc/uhub.conf ${CMAKE_SOURCE_DIR}/doc/plugins.conf ${CMAKE_SOURCE_DIR}/doc/rules.txt ${CMAKE_SOURCE_DIR}/doc/motd.txt DESTINATION /etc/uhub OPTIONAL )
|
||||||
|
|
||||||
|
if (SQLITE_SUPPORT)
|
||||||
|
install( TARGETS uhub-passwd RUNTIME DESTINATION bin )
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
15
ChangeLog
15
ChangeLog
@@ -1,3 +1,18 @@
|
|||||||
|
0.4.1:
|
||||||
|
- Converted to CMake which replaces Visual Studio project files and GNU makefiles
|
||||||
|
- Fix issues with SSL causing excessive CPU usage.
|
||||||
|
- Fix TLS/SSL handshake detection issues
|
||||||
|
- Fixed crash in mod_chat_only.
|
||||||
|
- Implemented red-black tree for better performance for certain lookups.
|
||||||
|
- Better network statistics using the !stats command.
|
||||||
|
- Improved protocol parsing, especially escape handling.
|
||||||
|
- Fix cbuffer initialization.
|
||||||
|
- Install plugins in /usr/lib/uhub, not /var/lib/uhub.
|
||||||
|
- Improved init scripts and added a upstart script.
|
||||||
|
- Work-around client security bugs by disallowing UCMD messages from being relayed.
|
||||||
|
- Added asynchronous DNS resolver.
|
||||||
|
|
||||||
|
|
||||||
0.4.0:
|
0.4.0:
|
||||||
- Cleaned up code generator for config file parsing.
|
- Cleaned up code generator for config file parsing.
|
||||||
- Merge pull request #5 from yorhel/master
|
- Merge pull request #5 from yorhel/master
|
||||||
|
|||||||
378
GNUmakefile
378
GNUmakefile
@@ -1,378 +0,0 @@
|
|||||||
##
|
|
||||||
## Makefile for uhub (Use GNU make)
|
|
||||||
## Copyright (C) 2007-2010, Jan Vidar Krey <janvidar@extatic.org>
|
|
||||||
#
|
|
||||||
|
|
||||||
-include Makefile.private
|
|
||||||
|
|
||||||
CC = gcc
|
|
||||||
LD := $(CC)
|
|
||||||
MV := mv
|
|
||||||
RANLIB := ranlib
|
|
||||||
CFLAGS += -pipe -Wall
|
|
||||||
USE_SSL ?= YES
|
|
||||||
USE_PLUGINS ?= YES
|
|
||||||
USE_BIGENDIAN ?= AUTO
|
|
||||||
BITS ?= AUTO
|
|
||||||
SILENT ?= YES
|
|
||||||
TERSE ?= NO
|
|
||||||
STACK_PROTECT ?= NO
|
|
||||||
NEED_LIBDL ?= NO
|
|
||||||
|
|
||||||
ifeq ($(OS), Windows_NT)
|
|
||||||
WINDOWS ?= YES
|
|
||||||
OPSYS ?= Windows
|
|
||||||
else
|
|
||||||
OPSYS ?= $(shell uname)
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(OPSYS),SunOS)
|
|
||||||
LDLIBS += -lsocket -lnsl
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(OPSYS),Haiku)
|
|
||||||
LDLIBS += -lnetwork
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(OPSYS),Linux)
|
|
||||||
NEED_LIBDL = YES
|
|
||||||
endif
|
|
||||||
|
|
||||||
CFLAGS += -I./src/
|
|
||||||
|
|
||||||
ifeq ($(OPSYS),Windows)
|
|
||||||
USE_BIGENDIAN := NO
|
|
||||||
LDLIBS += -lws2_32
|
|
||||||
UHUB_CONF_DIR ?= c:/uhub/
|
|
||||||
UHUB_PREFIX ?= c:/uhub/
|
|
||||||
CFLAGS += -mno-cygwin
|
|
||||||
LDFLAGS += -mno-cygwin
|
|
||||||
BIN_EXT ?= .exe
|
|
||||||
else
|
|
||||||
DESTDIR ?= /
|
|
||||||
UHUB_CONF_DIR ?= $(DESTDIR)/etc/uhub
|
|
||||||
UHUB_PREFIX ?= $(DESTDIR)/usr/local
|
|
||||||
UHUB_MOD_DIR ?= $(DESTDIR)/var/lib/uhub
|
|
||||||
CFLAGS += -I/usr/local/include
|
|
||||||
LDFLAGS += -L/usr/local/lib
|
|
||||||
BIN_EXT ?=
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(SILENT),YES)
|
|
||||||
MSG_CC=@echo " CC:" $(notdir $<) &&
|
|
||||||
MSG_LD=@echo " LD:" $(notdir $@) &&
|
|
||||||
MSG_AR=@echo " AR:" $(notdir $@) &&
|
|
||||||
else
|
|
||||||
MSG_CC=
|
|
||||||
MSG_LD=
|
|
||||||
MSG_AR=
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(TERSE), YES)
|
|
||||||
MSG_CC=@
|
|
||||||
MSG_LD=@
|
|
||||||
MSG_AR=@
|
|
||||||
MSG_CLEAN=-n ""
|
|
||||||
else
|
|
||||||
MSG_CLEAN="Clean as a whistle"
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(RELEASE),YES)
|
|
||||||
CFLAGS += -O3 -DNDEBUG
|
|
||||||
else
|
|
||||||
CFLAGS += -ggdb -DDEBUG
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(STACK_PROTECT),YES)
|
|
||||||
CFLAGS += -fstack-protector-all
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
ifeq ($(PROFILING),YES)
|
|
||||||
CFLAGS += -pg
|
|
||||||
LDFLAGS += -pg
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(FUNCTRACE),YES)
|
|
||||||
CFLAGS += -finstrument-functions
|
|
||||||
CFLAGS += -DDEBUG_FUNCTION_TRACE
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(BITS), AUTO)
|
|
||||||
ifeq ($(BITS), 64)
|
|
||||||
CFLAGS += -m64
|
|
||||||
LDFLAGS += -m64
|
|
||||||
else
|
|
||||||
ifeq ($(BITS), 32)
|
|
||||||
CFLAGS += -m32
|
|
||||||
LDFLAGS += -m32
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(USE_BIGENDIAN),AUTO)
|
|
||||||
ifeq ($(shell perl -e 'print pack("L", 0x554E4958)'),UNIX)
|
|
||||||
CFLAGS += -DARCH_BIGENDIAN
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
ifeq ($(USE_BIGENDIAN),YES)
|
|
||||||
CFLAGS += -DARCH_BIGENDIAN
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(USE_SSL),YES)
|
|
||||||
CFLAGS += -DSSL_SUPPORT
|
|
||||||
LDLIBS += -lssl -lcrypto
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(NEED_LIBDL),YES)
|
|
||||||
LDLIBS += -ldl
|
|
||||||
endif
|
|
||||||
|
|
||||||
GIT_VERSION=$(shell git describe --tags 2>/dev/null || echo "")
|
|
||||||
GIT_REVISION=$(shell git show --abbrev-commit 2>/dev/null | head -n 1 | cut -f 2 -d " " || echo "")
|
|
||||||
OLD_REVISION=$(shell grep GIT_REVISION revision.h 2>/dev/null | cut -f 3 -d " " | tr -d "\"")
|
|
||||||
|
|
||||||
# Sources
|
|
||||||
libuhub_SOURCES := \
|
|
||||||
src/core/auth.c \
|
|
||||||
src/core/command_parser.c \
|
|
||||||
src/core/commands.c \
|
|
||||||
src/core/config.c \
|
|
||||||
src/core/eventqueue.c \
|
|
||||||
src/core/hub.c \
|
|
||||||
src/core/hubevent.c \
|
|
||||||
src/core/hubio.c \
|
|
||||||
src/core/inf.c \
|
|
||||||
src/core/netevent.c \
|
|
||||||
src/core/probe.c \
|
|
||||||
src/core/route.c \
|
|
||||||
src/core/user.c \
|
|
||||||
src/core/usermanager.c \
|
|
||||||
src/core/plugincallback.c \
|
|
||||||
src/core/plugininvoke.c \
|
|
||||||
src/core/pluginloader.c \
|
|
||||||
src/network/backend.c \
|
|
||||||
src/network/connection.c \
|
|
||||||
src/network/epoll.c \
|
|
||||||
src/network/kqueue.c \
|
|
||||||
src/network/select.c \
|
|
||||||
src/network/timeout.c \
|
|
||||||
src/network/timer.c
|
|
||||||
|
|
||||||
|
|
||||||
libadc_common_SOURCES := \
|
|
||||||
src/adc/message.c \
|
|
||||||
src/adc/sid.c
|
|
||||||
|
|
||||||
libutils_SOURCES := \
|
|
||||||
src/util/cbuffer.c \
|
|
||||||
src/util/config_token.c \
|
|
||||||
src/util/credentials.c \
|
|
||||||
src/util/floodctl.c \
|
|
||||||
src/util/ipcalc.c \
|
|
||||||
src/util/list.c \
|
|
||||||
src/util/log.c \
|
|
||||||
src/util/memory.c \
|
|
||||||
src/util/misc.c \
|
|
||||||
src/network/network.c \
|
|
||||||
src/util/rbtree.c \
|
|
||||||
src/util/tiger.c
|
|
||||||
|
|
||||||
libadc_client_SOURCES := \
|
|
||||||
src/tools/adcclient.c
|
|
||||||
|
|
||||||
uhub_SOURCES := src/core/main.c
|
|
||||||
|
|
||||||
uhub-passwd_SOURCES := src/tools/uhub-passwd.c
|
|
||||||
uhub-passwd_LIBS := -lsqlite3
|
|
||||||
|
|
||||||
adcrush_SOURCES := src/tools/adcrush.c
|
|
||||||
|
|
||||||
admin_SOURCES := src/tools/admin.c
|
|
||||||
|
|
||||||
autotest_SOURCES := \
|
|
||||||
autotest/test_commands.tcc \
|
|
||||||
autotest/test_credentials.tcc \
|
|
||||||
autotest/test_eventqueue.tcc \
|
|
||||||
autotest/test_hub.tcc \
|
|
||||||
autotest/test_inf.tcc \
|
|
||||||
autotest/test_ipfilter.tcc \
|
|
||||||
autotest/test_list.tcc \
|
|
||||||
autotest/test_memory.tcc \
|
|
||||||
autotest/test_message.tcc \
|
|
||||||
autotest/test_misc.tcc \
|
|
||||||
autotest/test_sid.tcc \
|
|
||||||
autotest/test_tiger.tcc \
|
|
||||||
autotest/test_timer.tcc \
|
|
||||||
autotest/test_tokenizer.tcc \
|
|
||||||
autotest/test_usermanager.tcc
|
|
||||||
|
|
||||||
autotest_OBJECTS = autotest.o
|
|
||||||
|
|
||||||
# Plugin targets:
|
|
||||||
plugin_example_SOURCES := src/plugins/mod_example.c
|
|
||||||
plugin_example_TARGET := mod_example.so
|
|
||||||
|
|
||||||
plugin_welcome_SOURCES := src/plugins/mod_welcome.c
|
|
||||||
plugin_welcome_TARGET := mod_welcome.so
|
|
||||||
|
|
||||||
plugin_logging_SOURCES := src/plugins/mod_logging.c
|
|
||||||
plugin_logging_TARGET := mod_logging.so
|
|
||||||
|
|
||||||
plugin_auth_SOURCES := src/plugins/mod_auth_simple.c
|
|
||||||
plugin_auth_TARGET := mod_auth_simple.so
|
|
||||||
|
|
||||||
plugin_auth_sqlite_SOURCES := src/plugins/mod_auth_sqlite.c
|
|
||||||
plugin_auth_sqlite_TARGET := mod_auth_sqlite.so
|
|
||||||
plugin_auth_sqlite_LIBS := -lsqlite3
|
|
||||||
|
|
||||||
plugin_chat_history_SOURCES := src/plugins/mod_chat_history.c
|
|
||||||
plugin_chat_history_TARGET := mod_chat_history.so
|
|
||||||
|
|
||||||
plugin_chat_only_SOURCES := src/plugins/mod_chat_only.c
|
|
||||||
plugin_chat_only_TARGET := mod_chat_only.so
|
|
||||||
|
|
||||||
plugin_topic_SOURCES := src/plugins/mod_topic.c
|
|
||||||
plugin_topic_TARGET := mod_topic.so
|
|
||||||
|
|
||||||
# Source to objects
|
|
||||||
libuhub_OBJECTS := $(libuhub_SOURCES:.c=.o)
|
|
||||||
libutils_OBJECTS := $(libutils_SOURCES:.c=.o)
|
|
||||||
libadc_client_OBJECTS := $(libadc_client_SOURCES:.c=.o)
|
|
||||||
libadc_common_OBJECTS := $(libadc_common_SOURCES:.c=.o)
|
|
||||||
|
|
||||||
uhub_OBJECTS := $(uhub_SOURCES:.c=.o)
|
|
||||||
uhub-passwd_OBJECTS := $(uhub-passwd_SOURCES:.c=.o)
|
|
||||||
adcrush_OBJECTS := $(adcrush_SOURCES:.c=.o)
|
|
||||||
admin_OBJECTS := $(admin_SOURCES:.c=.o)
|
|
||||||
|
|
||||||
all_plugins := \
|
|
||||||
$(plugin_example_TARGET) \
|
|
||||||
$(plugin_logging_TARGET) \
|
|
||||||
$(plugin_auth_TARGET) \
|
|
||||||
$(plugin_auth_sqlite_TARGET) \
|
|
||||||
$(plugin_welcome_TARGET) \
|
|
||||||
$(plugin_chat_history_TARGET) \
|
|
||||||
$(plugin_chat_only_TARGET) \
|
|
||||||
$(plugin_topic_TARGET)
|
|
||||||
|
|
||||||
all_OBJECTS := \
|
|
||||||
$(libuhub_OBJECTS) \
|
|
||||||
$(uhub_OBJECTS) \
|
|
||||||
$(libutils_OBJECTS) \
|
|
||||||
$(adcrush_OBJECTS) \
|
|
||||||
$(autotest_OBJECTS) \
|
|
||||||
$(admin_OBJECTS) \
|
|
||||||
$(libadc_common_OBJECTS) \
|
|
||||||
$(libadc_client_OBJECTS)
|
|
||||||
|
|
||||||
all_OBJECTS += $(all_plugins)
|
|
||||||
|
|
||||||
uhub_BINARY=uhub$(BIN_EXT)
|
|
||||||
uhub-passwd_BINARY=uhub-passwd$(BIN_EXT)
|
|
||||||
adcrush_BINARY=adcrush$(BIN_EXT)
|
|
||||||
admin_BINARY=uhub-admin$(BIN_EXT)
|
|
||||||
autotest_BINARY=autotest/test$(BIN_EXT)
|
|
||||||
|
|
||||||
|
|
||||||
.PHONY: revision.h.tmp all plugins
|
|
||||||
|
|
||||||
%.o: %.c version.h revision.h
|
|
||||||
$(MSG_CC) $(CC) -fPIC -c $(CFLAGS) -o $@ $<
|
|
||||||
|
|
||||||
|
|
||||||
#%.so: %.c
|
|
||||||
# $(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
|
||||||
|
|
||||||
|
|
||||||
all: $(uhub_BINARY) $(uhub-passwd_BINARY) plugins
|
|
||||||
|
|
||||||
plugins: $(uhub_BINARY) $(all_plugins)
|
|
||||||
|
|
||||||
$(plugin_auth_TARGET): $(plugin_auth_SOURCES) $(libutils_OBJECTS)
|
|
||||||
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
|
||||||
|
|
||||||
$(plugin_auth_sqlite_TARGET): $(plugin_auth_sqlite_SOURCES) $(libutils_OBJECTS)
|
|
||||||
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS) $(LDFLAGS) $(plugin_auth_sqlite_LIBS)
|
|
||||||
|
|
||||||
$(plugin_example_TARGET): $(plugin_example_SOURCES) $(libutils_OBJECTS)
|
|
||||||
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
|
||||||
|
|
||||||
$(plugin_logging_TARGET): $(plugin_logging_SOURCES) $(libutils_OBJECTS) $(libadc_common_OBJECTS) src/network/network.o
|
|
||||||
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
|
||||||
|
|
||||||
$(plugin_chat_history_TARGET): $(plugin_chat_history_SOURCES) $(libutils_OBJECTS)
|
|
||||||
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
|
||||||
|
|
||||||
$(plugin_chat_only_TARGET): $(plugin_chat_only_SOURCES) $(libutils_OBJECTS)
|
|
||||||
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
|
||||||
|
|
||||||
$(plugin_welcome_TARGET): $(plugin_welcome_SOURCES) $(libutils_OBJECTS)
|
|
||||||
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
|
||||||
|
|
||||||
$(plugin_topic_TARGET): $(plugin_topic_SOURCES) $(libutils_OBJECTS)
|
|
||||||
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
|
||||||
|
|
||||||
|
|
||||||
$(adcrush_BINARY): $(adcrush_OBJECTS) $(libuhub_OBJECTS) $(libutils_OBJECTS) $(libadc_common_OBJECTS) $(libadc_client_OBJECTS)
|
|
||||||
$(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
|
|
||||||
|
|
||||||
$(admin_BINARY): $(admin_OBJECTS) $(libuhub_OBJECTS) $(libutils_OBJECTS) $(libadc_common_OBJECTS) $(libadc_client_OBJECTS)
|
|
||||||
$(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
|
|
||||||
|
|
||||||
$(uhub_BINARY): $(uhub_OBJECTS) $(libuhub_OBJECTS) $(libutils_OBJECTS) $(libadc_common_OBJECTS)
|
|
||||||
$(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
|
|
||||||
|
|
||||||
$(uhub-passwd_BINARY): $(uhub-passwd_OBJECTS) src/util/misc.o src/util/list.o src/util/memory.o src/util/log.o
|
|
||||||
$(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS) $(uhub-passwd_LIBS)
|
|
||||||
|
|
||||||
|
|
||||||
autotest.c: $(autotest_SOURCES)
|
|
||||||
$(shell exotic --standalone $(autotest_SOURCES) > $@)
|
|
||||||
|
|
||||||
revision.h.tmp:
|
|
||||||
@rm -f $@
|
|
||||||
@echo "/* AUTOGENERATED FILE - DO NOT EDIT */" > $@
|
|
||||||
@if [ -n '$(GIT_VERSION)' ]; then echo \#define GIT_VERSION \"$(GIT_VERSION)\" >> $@; fi
|
|
||||||
@if [ -n '$(GIT_REVISION)' ]; then echo \#define GIT_REVISION \"$(GIT_REVISION)\" >> $@; fi
|
|
||||||
|
|
||||||
version.h: revision.h
|
|
||||||
|
|
||||||
revision.h: revision.h.tmp
|
|
||||||
@if [ '$(GIT_REVISION)' != '$(OLD_REVISION)' ]; then cp $@.tmp $@; fi
|
|
||||||
@if [ ! -f $@ ]; then cp $@.tmp $@; fi
|
|
||||||
|
|
||||||
$(autotest_OBJECTS): autotest.c
|
|
||||||
$(MSG_CC) $(CC) -c $(CFLAGS) -Isrc -o $@ $<
|
|
||||||
|
|
||||||
$(autotest_BINARY): $(autotest_OBJECTS) $(libuhub_OBJECTS) $(libutils_OBJECTS) $(libadc_common_OBJECTS) $(libadc_client_OBJECTS)
|
|
||||||
$(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
|
|
||||||
|
|
||||||
autotest: $(autotest_BINARY)
|
|
||||||
@./$(autotest_BINARY) -s -f
|
|
||||||
|
|
||||||
ifeq ($(WINDOWS),YES)
|
|
||||||
install:
|
|
||||||
@echo "Cannot install automatically on windows."
|
|
||||||
else
|
|
||||||
install: all
|
|
||||||
@echo Copying $(uhub_BINARY) to $(UHUB_PREFIX)/bin/
|
|
||||||
@cp $(uhub_BINARY) $(UHUB_PREFIX)/bin/
|
|
||||||
@cp $(uhub-passwd_BINARY) $(UHUB_PREFIX)/bin/
|
|
||||||
@if [ ! -d $(UHUB_CONF_DIR) ]; then echo Creating $(UHUB_CONF_DIR); mkdir -p $(UHUB_CONF_DIR); fi
|
|
||||||
@if [ ! -f $(UHUB_CONF_DIR)/uhub.conf ]; then cp doc/uhub.conf $(UHUB_CONF_DIR); fi
|
|
||||||
@if [ ! -f $(UHUB_CONF_DIR)/rules.txt ]; then cp doc/rules.txt $(UHUB_CONF_DIR); fi
|
|
||||||
@if [ ! -f $(UHUB_CONF_DIR)/plugins.conf ]; then cp doc/plugins.conf $(UHUB_CONF_DIR); fi
|
|
||||||
@if [ ! -d $(UHUB_MOD_DIR) ]; then echo Creating $(UHUB_MOD_DIR); mkdir -p $(UHUB_MOD_DIR); fi
|
|
||||||
@cp -f mod_*.so $(UHUB_MOD_DIR)
|
|
||||||
@touch $(UHUB_CONF_DIR)/motd.txt
|
|
||||||
@echo done.
|
|
||||||
endif
|
|
||||||
|
|
||||||
dist-clean:
|
|
||||||
@rm -rf $(all_OBJECTS) *~ core
|
|
||||||
|
|
||||||
clean:
|
|
||||||
@rm -rf $(libuhub_OBJECTS) *~ core $(uhub_BINARY) $(uhub-passwd_BINARY) $(admin_BINARY) $(autotest_BINARY) $(adcrush_BINARY) $(all_OBJECTS) $(all_plugins) autotest.c revision.h revision.h.tmp && \
|
|
||||||
echo $(MSG_CLEAN)
|
|
||||||
372
autotest/exotic
Executable file
372
autotest/exotic
Executable file
@@ -0,0 +1,372 @@
|
|||||||
|
#!/usr/bin/perl -w
|
||||||
|
# exotic 0.4
|
||||||
|
# Copyright (c) 2007-2012, Jan Vidar Krey
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
|
||||||
|
my $program = $0;
|
||||||
|
my $file;
|
||||||
|
my $line;
|
||||||
|
my @tests;
|
||||||
|
my $found;
|
||||||
|
my $test;
|
||||||
|
my @files;
|
||||||
|
|
||||||
|
if ($#ARGV == -1)
|
||||||
|
{
|
||||||
|
die "Usage: $program files\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
my $version = "0.4";
|
||||||
|
|
||||||
|
foreach my $arg (@ARGV)
|
||||||
|
{
|
||||||
|
push(@files, $arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
print "/* THIS FILE IS AUTOMATICALLY GENERATED BY EXOTIC - DO NOT EDIT THIS FILE! */\n";
|
||||||
|
print "/* exotic/$version (Mon Nov 7 11:15:31 CET 2011) */\n\n";
|
||||||
|
|
||||||
|
print "#define __EXOTIC__STANDALONE__\n";
|
||||||
|
standalone_include_exotic_h();
|
||||||
|
|
||||||
|
if ($#ARGV >= 0)
|
||||||
|
{
|
||||||
|
foreach $file (@ARGV)
|
||||||
|
{
|
||||||
|
$found = 0;
|
||||||
|
open( FILE, "$file") || next;
|
||||||
|
my @data = <FILE>;
|
||||||
|
my $comment = 0;
|
||||||
|
|
||||||
|
foreach $line (@data) {
|
||||||
|
chomp($line);
|
||||||
|
|
||||||
|
if ($comment == 1)
|
||||||
|
{
|
||||||
|
if ($line =~ /^(.*\*\/)(.*)/)
|
||||||
|
{
|
||||||
|
$line = $2;
|
||||||
|
$comment = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
next; # ignore comment data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($line =~ /^(.*)\/\*(.*)\*\/(.*)$/)
|
||||||
|
{
|
||||||
|
$line = $1 . " " . $3; # exclude comment stuff in between "/*" and "*/".
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($line =~ /^(.*)(\/\/.*)$/) {
|
||||||
|
$line = $1; # exclude stuff after "//" (FIXME: does not work if they are inside a string)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($line =~ /\/\*/) {
|
||||||
|
$comment = 1;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($line =~ /^\s*EXO_TEST\(\s*(\w+)\s*,/)
|
||||||
|
{
|
||||||
|
$found++;
|
||||||
|
push(@tests, $1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($found > 0) {
|
||||||
|
print "#include \"" . $file . "\"\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
close(FILE);
|
||||||
|
}
|
||||||
|
print "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Write a main() that will start the test run
|
||||||
|
print "int main(int argc, char** argv)\n{\n";
|
||||||
|
print "\tstruct exotic_handle handle;\n\n";
|
||||||
|
print "\tif (exotic_initialize(&handle, argc, argv) == -1)\n\t\treturn -1;\n\n";
|
||||||
|
|
||||||
|
if ($#tests > 0)
|
||||||
|
{
|
||||||
|
print "\t/* Register the tests to be run */\n";
|
||||||
|
foreach $test (@tests)
|
||||||
|
{
|
||||||
|
print "\texotic_add_test(&handle, &exotic_test_" . $test . ", \"" . $test . "\");\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
print "\t/* No tests are found! */\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
print "\n";
|
||||||
|
print "\treturn exotic_run(&handle);\n";
|
||||||
|
print "}\n\n";
|
||||||
|
|
||||||
|
|
||||||
|
standalone_include_exotic_c();
|
||||||
|
|
||||||
|
sub standalone_include_exotic_h {
|
||||||
|
print '
|
||||||
|
/*
|
||||||
|
* Exotic (EXtatic.Org Test InfrastuCture)
|
||||||
|
* Copyright (c) 2007, Jan Vidar Krey
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EXO_TEST
|
||||||
|
#define EXO_TEST(NAME, block) int exotic_test_ ## NAME (void) block
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_EXOTIC_AUTOTEST_H
|
||||||
|
#define HAVE_EXOTIC_AUTOTEST_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef int(*exo_test_t)();
|
||||||
|
|
||||||
|
enum exo_toggle { cfg_default, cfg_off, cfg_on };
|
||||||
|
|
||||||
|
struct exotic_handle
|
||||||
|
{
|
||||||
|
enum exo_toggle config_show_summary;
|
||||||
|
enum exo_toggle config_show_pass;
|
||||||
|
enum exo_toggle config_show_fail;
|
||||||
|
unsigned int fail;
|
||||||
|
unsigned int pass;
|
||||||
|
struct exo_test_data* first;
|
||||||
|
struct exo_test_data* current;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int exotic_initialize(struct exotic_handle* handle, int argc, char** argv);
|
||||||
|
extern void exotic_add_test(struct exotic_handle* handle, exo_test_t, const char* name);
|
||||||
|
extern int exotic_run(struct exotic_handle* handle);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HAVE_EXOTIC_AUTOTEST_H */
|
||||||
|
|
||||||
|
'; }
|
||||||
|
sub standalone_include_exotic_c {
|
||||||
|
print '
|
||||||
|
/*
|
||||||
|
* Exotic - C/C++ source code testing
|
||||||
|
* Copyright (c) 2007, Jan Vidar Krey
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static void exotic_version();
|
||||||
|
|
||||||
|
#ifndef __EXOTIC__STANDALONE__
|
||||||
|
#include "autotest.h"
|
||||||
|
static void exotic_version()
|
||||||
|
{
|
||||||
|
printf("Extatic.org Test Infrastructure: exotic " "${version}" "\n\n");
|
||||||
|
printf("Copyright (C) 2007 Jan Vidar Krey, janvidar@extatic.org\n");
|
||||||
|
printf("This is free software with ABSOLUTELY NO WARRANTY.\n\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct exo_test_data
|
||||||
|
{
|
||||||
|
exo_test_t test;
|
||||||
|
char* name;
|
||||||
|
struct exo_test_data* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void exotic_summary(struct exotic_handle* handle)
|
||||||
|
{
|
||||||
|
int total = handle->pass + handle->fail;
|
||||||
|
int pass_rate = total ? (100*handle->pass / total) : 0;
|
||||||
|
int fail_rate = total ? (100*handle->fail / total) : 0;
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
printf("--------------------------------------------\n");
|
||||||
|
printf("Results:\n");
|
||||||
|
printf(" * Total tests run: %8d\n", total);
|
||||||
|
printf(" * Tests passed: %8d (~%d%%)\n", (int) handle->pass, pass_rate);
|
||||||
|
printf(" * Tests failed: %8d (~%d%%)\n", (int) handle->fail, fail_rate);
|
||||||
|
printf("--------------------------------------------\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void exotic_help(const char* program)
|
||||||
|
{
|
||||||
|
printf("Usage: %s [OPTIONS]\n\n", program);
|
||||||
|
printf("Options:\n");
|
||||||
|
printf(" --help -h Show this message\n");
|
||||||
|
printf(" --version -v Show version\n");
|
||||||
|
printf(" --summary -s show only summary)\n");
|
||||||
|
printf(" --fail -f show only test failures\n");
|
||||||
|
printf(" --pass -p show only test passes\n");
|
||||||
|
printf("\nExamples:\n");
|
||||||
|
printf(" %s -s -f\n\n", program);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int exotic_initialize(struct exotic_handle* handle, int argc, char** argv)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
if (!handle || !argv) return -1;
|
||||||
|
|
||||||
|
memset(handle, 0, sizeof(struct exotic_handle));
|
||||||
|
|
||||||
|
for (n = 1; n < argc; n++)
|
||||||
|
{
|
||||||
|
if (!strcmp(argv[n], "-h") || !strcmp(argv[n], "--help"))
|
||||||
|
{
|
||||||
|
exotic_help(argv[0]);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(argv[n], "-v") || !strcmp(argv[n], "--version"))
|
||||||
|
{
|
||||||
|
exotic_version();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(argv[n], "-s") || !strcmp(argv[n], "--summary"))
|
||||||
|
{
|
||||||
|
handle->config_show_summary = cfg_on;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(argv[n], "-f") || !strcmp(argv[n], "--fail"))
|
||||||
|
{
|
||||||
|
handle->config_show_fail = cfg_on;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(argv[n], "-p") || !strcmp(argv[n], "--pass"))
|
||||||
|
{
|
||||||
|
handle->config_show_pass = cfg_on;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "Unknown argument: %s\n\n", argv[n]);
|
||||||
|
exotic_help(argv[0]);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handle->config_show_summary == cfg_on)
|
||||||
|
{
|
||||||
|
if (handle->config_show_pass == cfg_default) handle->config_show_pass = cfg_off;
|
||||||
|
if (handle->config_show_fail == cfg_default) handle->config_show_fail = cfg_off;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (handle->config_show_pass == cfg_on)
|
||||||
|
{
|
||||||
|
if (handle->config_show_summary == cfg_default) handle->config_show_summary = cfg_off;
|
||||||
|
if (handle->config_show_fail == cfg_default) handle->config_show_fail = cfg_off;
|
||||||
|
}
|
||||||
|
else if (handle->config_show_fail == cfg_on)
|
||||||
|
{
|
||||||
|
if (handle->config_show_summary == cfg_default) handle->config_show_summary = cfg_off;
|
||||||
|
if (handle->config_show_fail == cfg_default) handle->config_show_fail = cfg_off;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (handle->config_show_summary == cfg_default) handle->config_show_summary = cfg_on;
|
||||||
|
if (handle->config_show_fail == cfg_default) handle->config_show_fail = cfg_on;
|
||||||
|
if (handle->config_show_pass == cfg_default) handle->config_show_pass = cfg_on;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void exotic_add_test(struct exotic_handle* handle, exo_test_t func, const char* name)
|
||||||
|
{
|
||||||
|
struct exo_test_data* test;
|
||||||
|
if (!handle)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "exotic_add_test: failed, no handle!\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
test = (struct exo_test_data*) malloc(sizeof(struct exo_test_data));
|
||||||
|
if (!test)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "exotic_add_test: out of memory!\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the test */
|
||||||
|
memset(test, 0, sizeof(struct exo_test_data));
|
||||||
|
test->test = func;
|
||||||
|
test->name = strdup(name);
|
||||||
|
|
||||||
|
/* Register the test in the handle */
|
||||||
|
if (!handle->first)
|
||||||
|
{
|
||||||
|
handle->first = test;
|
||||||
|
handle->current = test;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
handle->current->next = test;
|
||||||
|
handle->current = test;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int exotic_run(struct exotic_handle* handle)
|
||||||
|
{
|
||||||
|
struct exo_test_data* tmp = NULL;
|
||||||
|
|
||||||
|
if (!handle)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error: exotic is not initialized\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle->current = handle->first;
|
||||||
|
while (handle->current)
|
||||||
|
{
|
||||||
|
tmp = handle->current;
|
||||||
|
|
||||||
|
if (handle->current->test()) {
|
||||||
|
if (handle->config_show_pass == cfg_on) printf("* PASS test \'%s\'\n", tmp->name);
|
||||||
|
handle->pass++;
|
||||||
|
} else {
|
||||||
|
if (handle->config_show_fail == cfg_on) printf("* FAIL test \'%s\'\n", tmp->name);
|
||||||
|
handle->fail++;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle->current = handle->current->next;
|
||||||
|
|
||||||
|
free(tmp->name);
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!handle->first)
|
||||||
|
{
|
||||||
|
printf("(No tests added)\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handle->config_show_summary == cfg_on)
|
||||||
|
exotic_summary(handle);
|
||||||
|
|
||||||
|
return (handle->fail) ? handle->fail : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void exotic_version() {
|
||||||
|
printf("exotic 0.4-standalone\n\n");
|
||||||
|
printf("Copyright (C) 2007 Jan Vidar Krey, janvidar@extatic.org\n");
|
||||||
|
printf("This is free software with ABSOLUTELY NO WARRANTY.\n\n");
|
||||||
|
}
|
||||||
|
'; }
|
||||||
|
|
||||||
1032
autotest/test.c
Normal file
1032
autotest/test.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -19,7 +19,8 @@ EXO_TEST(setup, {
|
|||||||
hub = hub_malloc_zero(sizeof(struct hub_info));
|
hub = hub_malloc_zero(sizeof(struct hub_info));
|
||||||
cbase = command_initialize(hub);
|
cbase = command_initialize(hub);
|
||||||
hub->commands = cbase;
|
hub->commands = cbase;
|
||||||
return cbase && hub && uman_init(hub) == 0;
|
hub->users = uman_init();
|
||||||
|
return cbase && hub && hub->users;
|
||||||
});
|
});
|
||||||
|
|
||||||
static int test_handler(struct command_base* cbase, struct hub_user* user, struct hub_command* hcmd)
|
static int test_handler(struct command_base* cbase, struct hub_user* user, struct hub_command* hcmd)
|
||||||
@@ -127,7 +128,7 @@ EXO_TEST(command_number_3, { return verify("!test3 -12", cmd_status_ok); });
|
|||||||
|
|
||||||
EXO_TEST(command_user_1, { return verify("!test4 tester", cmd_status_arg_nick); });
|
EXO_TEST(command_user_1, { return verify("!test4 tester", cmd_status_arg_nick); });
|
||||||
EXO_TEST(command_user_2, { return verify("!test5 3AGHMAASJA2RFNM22AA6753V7B7DYEPNTIWHBAY", cmd_status_arg_cid); });
|
EXO_TEST(command_user_2, { return verify("!test5 3AGHMAASJA2RFNM22AA6753V7B7DYEPNTIWHBAY", cmd_status_arg_cid); });
|
||||||
EXO_TEST(command_user_3, { return uman_add(hub, &user) == 0; });
|
EXO_TEST(command_user_3, { return uman_add(hub->users, &user) == 0; });
|
||||||
EXO_TEST(command_user_4, { return verify("!test4 tester", cmd_status_ok); });
|
EXO_TEST(command_user_4, { return verify("!test4 tester", cmd_status_ok); });
|
||||||
EXO_TEST(command_user_5, { return verify("!test5 3AGHMAASJA2RFNM22AA6753V7B7DYEPNTIWHBAY", cmd_status_ok); });
|
EXO_TEST(command_user_5, { return verify("!test5 3AGHMAASJA2RFNM22AA6753V7B7DYEPNTIWHBAY", cmd_status_ok); });
|
||||||
|
|
||||||
@@ -225,7 +226,7 @@ EXO_TEST(command_argument_cred_6, {
|
|||||||
|
|
||||||
#undef SETUP_COMMAND
|
#undef SETUP_COMMAND
|
||||||
|
|
||||||
EXO_TEST(command_user_destroy, { return uman_remove(hub, &user) == 0; });
|
EXO_TEST(command_user_destroy, { return uman_remove(hub->users, &user) == 0; });
|
||||||
|
|
||||||
EXO_TEST(command_destroy, {
|
EXO_TEST(command_destroy, {
|
||||||
|
|
||||||
@@ -241,3 +242,10 @@ EXO_TEST(command_destroy, {
|
|||||||
DEL_TEST(c_test7);
|
DEL_TEST(c_test7);
|
||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
EXO_TEST(cleanup, {
|
||||||
|
uman_shutdown(hub->users);
|
||||||
|
command_shutdown(hub->commands);
|
||||||
|
hub_free(hub);
|
||||||
|
return 1;
|
||||||
|
});
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ extern int hub_handle_info_login(struct hub_info* hub, struct hub_user* user, st
|
|||||||
|
|
||||||
static void inf_create_hub()
|
static void inf_create_hub()
|
||||||
{
|
{
|
||||||
|
net_initialize();
|
||||||
inf_hub = (struct hub_info*) hub_malloc_zero(sizeof(struct hub_info));
|
inf_hub = (struct hub_info*) hub_malloc_zero(sizeof(struct hub_info));
|
||||||
inf_hub->users = (struct hub_user_manager*) hub_malloc_zero(sizeof(struct hub_user_manager));
|
inf_hub->users = (struct hub_user_manager*) hub_malloc_zero(sizeof(struct hub_user_manager));
|
||||||
inf_hub->users->list = list_create();
|
inf_hub->users->list = list_create();
|
||||||
@@ -35,6 +36,7 @@ static void inf_destroy_hub()
|
|||||||
hub_free(inf_hub->acl);
|
hub_free(inf_hub->acl);
|
||||||
hub_free(inf_hub->config);
|
hub_free(inf_hub->config);
|
||||||
hub_free(inf_hub);
|
hub_free(inf_hub);
|
||||||
|
net_destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -63,13 +65,14 @@ EXO_TEST(inf_create_setup,
|
|||||||
|
|
||||||
/* FIXME: MEMORY LEAK - Need to fix hub_handle_info_login */
|
/* FIXME: MEMORY LEAK - Need to fix hub_handle_info_login */
|
||||||
#define CHECK_INF(MSG, EXPECT) \
|
#define CHECK_INF(MSG, EXPECT) \
|
||||||
|
do { \
|
||||||
struct adc_message* msg = adc_msg_parse_verify(inf_user, MSG, strlen(MSG)); \
|
struct adc_message* msg = adc_msg_parse_verify(inf_user, MSG, strlen(MSG)); \
|
||||||
int ok = hub_handle_info_login(inf_hub, inf_user, msg); /* FIXME: MEMORY LEAK */ \
|
int ok = hub_handle_info_login(inf_hub, inf_user, msg); /* FIXME: MEMORY LEAK */ \
|
||||||
adc_msg_free(msg); \
|
adc_msg_free(msg); \
|
||||||
if (ok == EXPECT) \
|
if (ok == EXPECT) \
|
||||||
user_set_info(inf_user, 0); \
|
user_set_info(inf_user, 0); \
|
||||||
return ok == EXPECT;
|
return ok == EXPECT; \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
EXO_TEST(inf_ok_1, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", 0); });
|
EXO_TEST(inf_ok_1, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", 0); });
|
||||||
|
|
||||||
@@ -107,12 +110,15 @@ EXO_TEST(inf_nick_08, { CHECK_INF("BINF AAAB NIa\\nc IDGNSSMURMD7K466NGZIHU65TP3
|
|||||||
EXO_TEST(inf_nick_09, { CHECK_INF("BINF AAAB NIabc NIdef IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_nick_multiple); });
|
EXO_TEST(inf_nick_09, { CHECK_INF("BINF AAAB NIabc NIdef IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_nick_multiple); });
|
||||||
EXO_TEST(inf_nick_10, {
|
EXO_TEST(inf_nick_10, {
|
||||||
const char* line = "BINF AAAB IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n";
|
const char* line = "BINF AAAB IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n";
|
||||||
|
int ok;
|
||||||
char nick[10];
|
char nick[10];
|
||||||
|
struct adc_message* msg;
|
||||||
|
|
||||||
nick[0] = 0xf7; nick[1] = 0x80; nick[2] = 0x7f; nick[3] = 0x81; nick[4] = 0x98; nick[5] = 0x00;
|
nick[0] = 0xf7; nick[1] = 0x80; nick[2] = 0x7f; nick[3] = 0x81; nick[4] = 0x98; nick[5] = 0x00;
|
||||||
struct adc_message* msg = adc_msg_parse_verify(inf_user, line, strlen(line));
|
msg = adc_msg_parse_verify(inf_user, line, strlen(line));
|
||||||
|
|
||||||
adc_msg_add_named_argument(msg, "NI", nick);
|
adc_msg_add_named_argument(msg, "NI", nick);
|
||||||
int ok = hub_handle_info_login(inf_hub, inf_user, msg);
|
ok = hub_handle_info_login(inf_hub, inf_user, msg);
|
||||||
adc_msg_free(msg);
|
adc_msg_free(msg);
|
||||||
if (ok != status_msg_inf_error_nick_not_utf8)
|
if (ok != status_msg_inf_error_nick_not_utf8)
|
||||||
printf("Expected %d, got %d\n", status_msg_inf_error_nick_not_utf8, ok);
|
printf("Expected %d, got %d\n", status_msg_inf_error_nick_not_utf8, ok);
|
||||||
|
|||||||
@@ -429,44 +429,51 @@ EXO_TEST(check_ban_ipv4_5, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(check_ban_ipv6_1, {
|
EXO_TEST(check_ban_ipv6_1, {
|
||||||
|
struct ip_addr_encap addr;
|
||||||
if (!ipv6) return 1;
|
if (!ipv6) return 1;
|
||||||
struct ip_addr_encap addr; ip_convert_to_binary("2001::201:2ff:fefa:0", &addr);
|
ip_convert_to_binary("2001::201:2ff:fefa:0", &addr);
|
||||||
return ip_in_range(&addr, &ban6);
|
return ip_in_range(&addr, &ban6);
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(check_ban_ipv6_2, {
|
EXO_TEST(check_ban_ipv6_2, {
|
||||||
|
struct ip_addr_encap addr;
|
||||||
if (!ipv6) return 1;
|
if (!ipv6) return 1;
|
||||||
struct ip_addr_encap addr; ip_convert_to_binary("2001::201:2ff:fefa:1", &addr);
|
ip_convert_to_binary("2001::201:2ff:fefa:1", &addr);
|
||||||
return ip_in_range(&addr, &ban6);
|
return ip_in_range(&addr, &ban6);
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(check_ban_ipv6_3, {
|
EXO_TEST(check_ban_ipv6_3, {
|
||||||
|
struct ip_addr_encap addr;
|
||||||
if (!ipv6) return 1;
|
if (!ipv6) return 1;
|
||||||
struct ip_addr_encap addr; ip_convert_to_binary("2001::201:2ff:fefa:fffe", &addr);
|
ip_convert_to_binary("2001::201:2ff:fefa:fffe", &addr);
|
||||||
return ip_in_range(&addr, &ban6);
|
return ip_in_range(&addr, &ban6);
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(check_ban_ipv6_4, {
|
EXO_TEST(check_ban_ipv6_4, {
|
||||||
|
struct ip_addr_encap addr;
|
||||||
if (!ipv6) return 1;
|
if (!ipv6) return 1;
|
||||||
struct ip_addr_encap addr; ip_convert_to_binary("2001::201:2ff:fefa:ffff", &addr);
|
ip_convert_to_binary("2001::201:2ff:fefa:ffff", &addr);
|
||||||
return ip_in_range(&addr, &ban6);
|
return ip_in_range(&addr, &ban6);
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(check_ban_ipv6_5, {
|
EXO_TEST(check_ban_ipv6_5, {
|
||||||
|
struct ip_addr_encap addr;
|
||||||
if (!ipv6) return 1;
|
if (!ipv6) return 1;
|
||||||
struct ip_addr_encap addr; ip_convert_to_binary("2001::201:2ff:fefb:0", &addr);
|
ip_convert_to_binary("2001::201:2ff:fefb:0", &addr);
|
||||||
return !ip_in_range(&addr, &ban6);
|
return !ip_in_range(&addr, &ban6);
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(check_ban_ipv6_6, {
|
EXO_TEST(check_ban_ipv6_6, {
|
||||||
|
struct ip_addr_encap addr;
|
||||||
if (!ipv6) return 1;
|
if (!ipv6) return 1;
|
||||||
struct ip_addr_encap addr; ip_convert_to_binary("2001::201:2ff:fef9:ffff", &addr);
|
ip_convert_to_binary("2001::201:2ff:fef9:ffff", &addr);
|
||||||
return !ip_in_range(&addr, &ban6);
|
return !ip_in_range(&addr, &ban6);
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(check_ban_afmix_1, {
|
EXO_TEST(check_ban_afmix_1, {
|
||||||
|
struct ip_addr_encap addr;
|
||||||
if (!ipv6) return 1;
|
if (!ipv6) return 1;
|
||||||
struct ip_addr_encap addr; ip_convert_to_binary("2001::201:2ff:fef9:ffff", &addr);
|
ip_convert_to_binary("2001::201:2ff:fef9:ffff", &addr);
|
||||||
return !ip_in_range(&addr, &ban4);
|
return !ip_in_range(&addr, &ban4);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -610,8 +617,10 @@ EXO_TEST(ip_range_3, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(ip_range_4, {
|
EXO_TEST(ip_range_4, {
|
||||||
struct ip_range range1; memset(&range1, 0, sizeof(range1));
|
struct ip_range range1;
|
||||||
struct ip_range range2; memset(&range2, 0, sizeof(range2));
|
struct ip_range range2;
|
||||||
|
memset(&range1, 0, sizeof(range1));
|
||||||
|
memset(&range2, 0, sizeof(range2));
|
||||||
return ip_convert_address_to_range("192.168.0.0/16", &range1) && ip_convert_address_to_range("192.168.0.0-192.168.255.255", &range2) && memcmp(&range1, &range2, sizeof(struct ip_range)) == 0;
|
return ip_convert_address_to_range("192.168.0.0/16", &range1) && ip_convert_address_to_range("192.168.0.0-192.168.255.255", &range2) && memcmp(&range1, &range2, sizeof(struct ip_range)) == 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -174,91 +174,102 @@ EXO_TEST(adc_message_parse_24, {
|
|||||||
|
|
||||||
|
|
||||||
EXO_TEST(adc_message_add_arg_1, {
|
EXO_TEST(adc_message_add_arg_1, {
|
||||||
|
int ok;
|
||||||
struct adc_message* msg = adc_msg_create(test_string1);
|
struct adc_message* msg = adc_msg_create(test_string1);
|
||||||
adc_msg_add_argument(msg, "XXwtf?");
|
adc_msg_add_argument(msg, "XXwtf?");
|
||||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat XXwtf?\n") == 0;
|
ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat XXwtf?\n") == 0;
|
||||||
adc_msg_free(msg);
|
adc_msg_free(msg);
|
||||||
return ok;
|
return ok;
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(adc_message_add_arg_2, {
|
EXO_TEST(adc_message_add_arg_2, {
|
||||||
|
int ok;
|
||||||
struct adc_message* msg = adc_msg_create(test_string1);
|
struct adc_message* msg = adc_msg_create(test_string1);
|
||||||
adc_msg_add_named_argument(msg, "XX", "wtf?");
|
adc_msg_add_named_argument(msg, "XX", "wtf?");
|
||||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat XXwtf?\n") == 0;
|
ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat XXwtf?\n") == 0;
|
||||||
adc_msg_free(msg);
|
adc_msg_free(msg);
|
||||||
return ok;
|
return ok;
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(adc_message_remove_arg_1, {
|
EXO_TEST(adc_message_remove_arg_1, {
|
||||||
|
int ok;
|
||||||
struct adc_message* msg = adc_msg_create(test_string1);
|
struct adc_message* msg = adc_msg_create(test_string1);
|
||||||
adc_msg_remove_named_argument(msg, "AA");
|
adc_msg_remove_named_argument(msg, "AA");
|
||||||
int ok = strcmp(msg->cache, "IINF BBbar CCwhat\n") == 0;
|
ok = strcmp(msg->cache, "IINF BBbar CCwhat\n") == 0;
|
||||||
adc_msg_free(msg);
|
adc_msg_free(msg);
|
||||||
return ok;
|
return ok;
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(adc_message_remove_arg_2, {
|
EXO_TEST(adc_message_remove_arg_2, {
|
||||||
|
int ok;
|
||||||
struct adc_message* msg = adc_msg_create(test_string1);
|
struct adc_message* msg = adc_msg_create(test_string1);
|
||||||
adc_msg_remove_named_argument(msg, "BB");
|
adc_msg_remove_named_argument(msg, "BB");
|
||||||
int ok = strcmp(msg->cache, "IINF AAfoo CCwhat\n") == 0;
|
ok = strcmp(msg->cache, "IINF AAfoo CCwhat\n") == 0;
|
||||||
adc_msg_free(msg);
|
adc_msg_free(msg);
|
||||||
return ok;
|
return ok;
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(adc_message_remove_arg_3, {
|
EXO_TEST(adc_message_remove_arg_3, {
|
||||||
|
int ok;
|
||||||
struct adc_message* msg = adc_msg_create(test_string1);
|
struct adc_message* msg = adc_msg_create(test_string1);
|
||||||
adc_msg_remove_named_argument(msg, "CC");
|
adc_msg_remove_named_argument(msg, "CC");
|
||||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar\n") == 0;
|
ok = strcmp(msg->cache, "IINF AAfoo BBbar\n") == 0;
|
||||||
adc_msg_free(msg);
|
adc_msg_free(msg);
|
||||||
return ok;
|
return ok;
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(adc_message_remove_arg_4, {
|
EXO_TEST(adc_message_remove_arg_4, {
|
||||||
/* this ensures we can remove the last element also */
|
/* this ensures we can remove the last element also */
|
||||||
|
int ok;
|
||||||
struct adc_message* msg = adc_msg_parse_verify(g_user, test_string3, strlen(test_string3));
|
struct adc_message* msg = adc_msg_parse_verify(g_user, test_string3, strlen(test_string3));
|
||||||
adc_msg_remove_named_argument(msg, "AW");
|
adc_msg_remove_named_argument(msg, "AW");
|
||||||
int ok = strcmp(msg->cache, "BINF AAAB IDAN7ZMSLIEBL53OPTM7WXGSTXUS3XOY6KQS5LBGX NIFriend DEstuff SL3 SS0 SF0 VEQuickDC/0.4.17 US6430 SUADC0,TCP4,UDP4 I4127.0.0.1 HO5 HN1\n") == 0;
|
ok = strcmp(msg->cache, "BINF AAAB IDAN7ZMSLIEBL53OPTM7WXGSTXUS3XOY6KQS5LBGX NIFriend DEstuff SL3 SS0 SF0 VEQuickDC/0.4.17 US6430 SUADC0,TCP4,UDP4 I4127.0.0.1 HO5 HN1\n") == 0;
|
||||||
adc_msg_free(msg);
|
adc_msg_free(msg);
|
||||||
return ok;
|
return ok;
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(adc_message_replace_arg_1, {
|
EXO_TEST(adc_message_replace_arg_1, {
|
||||||
|
int ok;
|
||||||
struct adc_message* msg = adc_msg_create(test_string1);
|
struct adc_message* msg = adc_msg_create(test_string1);
|
||||||
adc_msg_remove_named_argument(msg, "AA");
|
adc_msg_remove_named_argument(msg, "AA");
|
||||||
int ok = strcmp(msg->cache, "IINF BBbar CCwhat\n") == 0;
|
ok = strcmp(msg->cache, "IINF BBbar CCwhat\n") == 0;
|
||||||
adc_msg_free(msg);
|
adc_msg_free(msg);
|
||||||
return ok;
|
return ok;
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(adc_message_replace_arg_2, {
|
EXO_TEST(adc_message_replace_arg_2, {
|
||||||
|
int ok;
|
||||||
struct adc_message* msg = adc_msg_create(test_string1);
|
struct adc_message* msg = adc_msg_create(test_string1);
|
||||||
adc_msg_remove_named_argument(msg, "BB");
|
adc_msg_remove_named_argument(msg, "BB");
|
||||||
int ok = strcmp(msg->cache, "IINF AAfoo CCwhat\n") == 0;
|
ok = strcmp(msg->cache, "IINF AAfoo CCwhat\n") == 0;
|
||||||
adc_msg_free(msg);
|
adc_msg_free(msg);
|
||||||
return ok;
|
return ok;
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(adc_message_replace_arg_3, {
|
EXO_TEST(adc_message_replace_arg_3, {
|
||||||
|
int ok;
|
||||||
struct adc_message* msg = adc_msg_create(test_string1);
|
struct adc_message* msg = adc_msg_create(test_string1);
|
||||||
adc_msg_remove_named_argument(msg, "CC");
|
adc_msg_remove_named_argument(msg, "CC");
|
||||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar\n") == 0;
|
ok = strcmp(msg->cache, "IINF AAfoo BBbar\n") == 0;
|
||||||
adc_msg_free(msg);
|
adc_msg_free(msg);
|
||||||
return ok;
|
return ok;
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(adc_message_get_arg_1, {
|
EXO_TEST(adc_message_get_arg_1, {
|
||||||
|
int ok;
|
||||||
struct adc_message* msg = adc_msg_create(test_string1);
|
struct adc_message* msg = adc_msg_create(test_string1);
|
||||||
char* c = adc_msg_get_argument(msg, 0);
|
char* c = adc_msg_get_argument(msg, 0);
|
||||||
int ok = strcmp(c, "AAfoo") == 0;
|
ok = strcmp(c, "AAfoo") == 0;
|
||||||
adc_msg_free(msg);
|
adc_msg_free(msg);
|
||||||
hub_free(c);
|
hub_free(c);
|
||||||
return ok;
|
return ok;
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(adc_message_get_arg_2, {
|
EXO_TEST(adc_message_get_arg_2, {
|
||||||
|
int ok;
|
||||||
struct adc_message* msg = adc_msg_create(test_string1);
|
struct adc_message* msg = adc_msg_create(test_string1);
|
||||||
char* c = adc_msg_get_argument(msg, 1);
|
char* c = adc_msg_get_argument(msg, 1);
|
||||||
int ok = strcmp(c, "BBbar") == 0;
|
ok = strcmp(c, "BBbar") == 0;
|
||||||
adc_msg_free(msg);
|
adc_msg_free(msg);
|
||||||
hub_free(c);
|
hub_free(c);
|
||||||
return ok;
|
return ok;
|
||||||
@@ -340,28 +351,31 @@ EXO_TEST(adc_message_has_named_arg_3, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(adc_message_has_named_arg_4, {
|
EXO_TEST(adc_message_has_named_arg_4, {
|
||||||
|
int n;
|
||||||
struct adc_message* msg = adc_msg_create(test_string1);
|
struct adc_message* msg = adc_msg_create(test_string1);
|
||||||
adc_msg_add_argument(msg, "XXwtf?");
|
adc_msg_add_argument(msg, "XXwtf?");
|
||||||
int n = adc_msg_has_named_argument(msg, "XX");
|
n = adc_msg_has_named_argument(msg, "XX");
|
||||||
adc_msg_free(msg);
|
adc_msg_free(msg);
|
||||||
return n == 1;
|
return n == 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(adc_message_has_named_arg_5, {
|
EXO_TEST(adc_message_has_named_arg_5, {
|
||||||
|
int n;
|
||||||
struct adc_message* msg = adc_msg_create(test_string1);
|
struct adc_message* msg = adc_msg_create(test_string1);
|
||||||
adc_msg_add_argument(msg, "XXone");
|
adc_msg_add_argument(msg, "XXone");
|
||||||
adc_msg_add_argument(msg, "XXtwo");
|
adc_msg_add_argument(msg, "XXtwo");
|
||||||
int n = adc_msg_has_named_argument(msg, "XX");
|
n = adc_msg_has_named_argument(msg, "XX");
|
||||||
adc_msg_free(msg);
|
adc_msg_free(msg);
|
||||||
return n == 2;
|
return n == 2;
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(adc_message_has_named_arg_6, {
|
EXO_TEST(adc_message_has_named_arg_6, {
|
||||||
|
int n;
|
||||||
struct adc_message* msg = adc_msg_create(test_string1);
|
struct adc_message* msg = adc_msg_create(test_string1);
|
||||||
adc_msg_add_argument(msg, "XXone");
|
adc_msg_add_argument(msg, "XXone");
|
||||||
adc_msg_add_argument(msg, "XXtwo");
|
adc_msg_add_argument(msg, "XXtwo");
|
||||||
adc_msg_add_argument(msg, "XXthree");
|
adc_msg_add_argument(msg, "XXthree");
|
||||||
int n = adc_msg_has_named_argument(msg, "XX");
|
n = adc_msg_has_named_argument(msg, "XX");
|
||||||
adc_msg_free(msg);
|
adc_msg_free(msg);
|
||||||
return n == 3;
|
return n == 3;
|
||||||
});
|
});
|
||||||
@@ -374,63 +388,70 @@ EXO_TEST(adc_message_has_named_arg_7, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(adc_message_terminate_1, {
|
EXO_TEST(adc_message_terminate_1, {
|
||||||
|
int ok;
|
||||||
struct adc_message* msg = adc_msg_create("IINF AAfoo BBbar CCwhat");
|
struct adc_message* msg = adc_msg_create("IINF AAfoo BBbar CCwhat");
|
||||||
adc_msg_unterminate(msg);
|
adc_msg_unterminate(msg);
|
||||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat") == 0;
|
ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat") == 0;
|
||||||
adc_msg_free(msg);
|
adc_msg_free(msg);
|
||||||
return ok;
|
return ok;
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(adc_message_terminate_2, {
|
EXO_TEST(adc_message_terminate_2, {
|
||||||
|
int ok;
|
||||||
struct adc_message* msg = adc_msg_create(test_string1);
|
struct adc_message* msg = adc_msg_create(test_string1);
|
||||||
adc_msg_unterminate(msg);
|
adc_msg_unterminate(msg);
|
||||||
adc_msg_terminate(msg);
|
adc_msg_terminate(msg);
|
||||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat\n") == 0;
|
ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat\n") == 0;
|
||||||
adc_msg_free(msg);
|
adc_msg_free(msg);
|
||||||
return ok;
|
return ok;
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(adc_message_terminate_3, {
|
EXO_TEST(adc_message_terminate_3, {
|
||||||
|
int ok;
|
||||||
struct adc_message* msg = adc_msg_create(test_string1);
|
struct adc_message* msg = adc_msg_create(test_string1);
|
||||||
adc_msg_unterminate(msg);
|
adc_msg_unterminate(msg);
|
||||||
adc_msg_terminate(msg);
|
adc_msg_terminate(msg);
|
||||||
adc_msg_unterminate(msg);
|
adc_msg_unterminate(msg);
|
||||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat") == 0;
|
ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat") == 0;
|
||||||
adc_msg_free(msg);
|
adc_msg_free(msg);
|
||||||
return ok;
|
return ok;
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(adc_message_terminate_4, {
|
EXO_TEST(adc_message_terminate_4, {
|
||||||
|
int ok;
|
||||||
struct adc_message* msg = adc_msg_create(test_string1);
|
struct adc_message* msg = adc_msg_create(test_string1);
|
||||||
adc_msg_unterminate(msg);
|
adc_msg_unterminate(msg);
|
||||||
adc_msg_terminate(msg);
|
adc_msg_terminate(msg);
|
||||||
adc_msg_terminate(msg);
|
adc_msg_terminate(msg);
|
||||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat\n") == 0;
|
ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat\n") == 0;
|
||||||
adc_msg_free(msg);
|
adc_msg_free(msg);
|
||||||
return ok;
|
return ok;
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(adc_message_terminate_5, {
|
EXO_TEST(adc_message_terminate_5, {
|
||||||
|
int ok;
|
||||||
struct adc_message* msg = adc_msg_create(test_string1);
|
struct adc_message* msg = adc_msg_create(test_string1);
|
||||||
adc_msg_terminate(msg);
|
adc_msg_terminate(msg);
|
||||||
adc_msg_terminate(msg);
|
adc_msg_terminate(msg);
|
||||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat\n") == 0;
|
ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat\n") == 0;
|
||||||
adc_msg_free(msg);
|
adc_msg_free(msg);
|
||||||
return ok;
|
return ok;
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(adc_message_terminate_6, {
|
EXO_TEST(adc_message_terminate_6, {
|
||||||
|
int ok;
|
||||||
struct adc_message* msg = adc_msg_create(test_string1);
|
struct adc_message* msg = adc_msg_create(test_string1);
|
||||||
adc_msg_unterminate(msg);
|
adc_msg_unterminate(msg);
|
||||||
adc_msg_unterminate(msg);
|
adc_msg_unterminate(msg);
|
||||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat") == 0;
|
ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat") == 0;
|
||||||
adc_msg_free(msg);
|
adc_msg_free(msg);
|
||||||
return ok;
|
return ok;
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(adc_message_escape_1, {
|
EXO_TEST(adc_message_escape_1, {
|
||||||
|
int ok;
|
||||||
char* s = adc_msg_escape(test_string1);
|
char* s = adc_msg_escape(test_string1);
|
||||||
int ok = strcmp(s, "IINF\\sAAfoo\\sBBbar\\sCCwhat\\n") == 0;
|
ok = strcmp(s, "IINF\\sAAfoo\\sBBbar\\sCCwhat\\n") == 0;
|
||||||
hub_free(s);
|
hub_free(s);
|
||||||
return ok;
|
return ok;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -97,15 +97,25 @@ EXO_TEST(base32_invalid_31, { return !is_valid_base32_char('@'); });
|
|||||||
EXO_TEST(utf8_valid_1, { return is_valid_utf8("abcdefghijklmnopqrstuvwxyz"); });
|
EXO_TEST(utf8_valid_1, { return is_valid_utf8("abcdefghijklmnopqrstuvwxyz"); });
|
||||||
EXO_TEST(utf8_valid_2, { return is_valid_utf8("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); });
|
EXO_TEST(utf8_valid_2, { return is_valid_utf8("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); });
|
||||||
EXO_TEST(utf8_valid_3, { return is_valid_utf8("0123456789"); });
|
EXO_TEST(utf8_valid_3, { return is_valid_utf8("0123456789"); });
|
||||||
EXO_TEST(utf8_valid_4, { return is_valid_utf8( (char[]) { 0x65, 0x00} ); });
|
|
||||||
EXO_TEST(utf8_valid_5, { return !is_valid_utf8( (char[]) { 0xD8, 0x00} ); });
|
|
||||||
|
|
||||||
EXO_TEST(utf8_valid_6, { return is_valid_utf8( (char[]) { 0x24, 0x00} ); });
|
static const char test_utf_seq_1[] = { 0x65, 0x00 }; // valid
|
||||||
EXO_TEST(utf8_valid_7, { return !is_valid_utf8( (char[]) { 0xC2, 0x24, 0x00} ); });
|
static const char test_utf_seq_2[] = { 0xD8, 0x00 }; // invalid
|
||||||
EXO_TEST(utf8_valid_8, { return is_valid_utf8( (char[]) { 0xC2, 0xA2, 0x00} ); });
|
static const char test_utf_seq_3[] = { 0x24, 0x00 }; // valid
|
||||||
EXO_TEST(utf8_valid_9, { return is_valid_utf8( (char[]) { 0xE2, 0x82, 0xAC, 0x00} ); });
|
static const char test_utf_seq_4[] = { 0xC2, 0x24, 0x00}; // invalid
|
||||||
EXO_TEST(utf8_valid_10, { return !is_valid_utf8( (char[]) { 0xC2, 0x32, 0x00} ); });
|
static const char test_utf_seq_5[] = { 0xC2, 0xA2, 0x00}; // valid
|
||||||
EXO_TEST(utf8_valid_11, { return !is_valid_utf8( (char[]) { 0xE2, 0x82, 0x32, 0x00} ); });
|
static const char test_utf_seq_6[] = { 0xE2, 0x82, 0xAC, 0x00}; // valid
|
||||||
EXO_TEST(utf8_valid_12, { return !is_valid_utf8( (char[]) { 0xE2, 0x32, 0x82, 0x00} ); });
|
static const char test_utf_seq_7[] = { 0xC2, 0x32, 0x00}; // invalid
|
||||||
|
static const char test_utf_seq_8[] = { 0xE2, 0x82, 0x32, 0x00}; // invalid
|
||||||
|
static const char test_utf_seq_9[] = { 0xE2, 0x32, 0x82, 0x00}; // invalid
|
||||||
|
|
||||||
|
EXO_TEST(utf8_valid_4, { return is_valid_utf8(test_utf_seq_1); });
|
||||||
|
EXO_TEST(utf8_valid_5, { return !is_valid_utf8(test_utf_seq_2); });
|
||||||
|
EXO_TEST(utf8_valid_6, { return is_valid_utf8(test_utf_seq_3); });
|
||||||
|
EXO_TEST(utf8_valid_7, { return !is_valid_utf8(test_utf_seq_4); });
|
||||||
|
EXO_TEST(utf8_valid_8, { return is_valid_utf8(test_utf_seq_5); });
|
||||||
|
EXO_TEST(utf8_valid_9, { return is_valid_utf8(test_utf_seq_6); });
|
||||||
|
EXO_TEST(utf8_valid_10, { return !is_valid_utf8(test_utf_seq_7); });
|
||||||
|
EXO_TEST(utf8_valid_11, { return !is_valid_utf8(test_utf_seq_8); });
|
||||||
|
EXO_TEST(utf8_valid_12, { return !is_valid_utf8(test_utf_seq_9); });
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
144
autotest/test_rbtree.tcc
Normal file
144
autotest/test_rbtree.tcc
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
#include <uhub.h>
|
||||||
|
#include <util/rbtree.h>
|
||||||
|
|
||||||
|
#define MAX_NODES 10000
|
||||||
|
|
||||||
|
static struct rb_tree* tree = NULL;
|
||||||
|
|
||||||
|
int test_tree_compare(const void* a, const void* b)
|
||||||
|
{
|
||||||
|
return strcmp((const char*) a, (const char*) b);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EXO_TEST(rbtree_create_destroy, {
|
||||||
|
int ok = 0;
|
||||||
|
struct rb_tree* atree;
|
||||||
|
atree = rb_tree_create(test_tree_compare, &hub_malloc, &hub_free);
|
||||||
|
if (atree) ok = 1;
|
||||||
|
rb_tree_destroy(atree);
|
||||||
|
return ok;
|
||||||
|
});
|
||||||
|
|
||||||
|
EXO_TEST(rbtree_create_1, {
|
||||||
|
tree = rb_tree_create(test_tree_compare, &hub_malloc, &hub_free);
|
||||||
|
return tree != NULL;
|
||||||
|
});
|
||||||
|
|
||||||
|
EXO_TEST(rbtree_size_0, { return rb_tree_size(tree) == 0; });
|
||||||
|
|
||||||
|
EXO_TEST(rbtree_insert_1, {
|
||||||
|
return rb_tree_insert(tree, "one", "1");
|
||||||
|
});
|
||||||
|
|
||||||
|
EXO_TEST(rbtree_insert_2, {
|
||||||
|
return rb_tree_insert(tree, "two", "2");
|
||||||
|
});
|
||||||
|
|
||||||
|
EXO_TEST(rbtree_insert_3, {
|
||||||
|
return rb_tree_insert(tree, "three", "3");
|
||||||
|
});
|
||||||
|
|
||||||
|
EXO_TEST(rbtree_insert_3_again, {
|
||||||
|
return !rb_tree_insert(tree, "three", "3-again");
|
||||||
|
});
|
||||||
|
|
||||||
|
EXO_TEST(rbtree_size_1, { return rb_tree_size(tree) == 3; });
|
||||||
|
|
||||||
|
static int test_check_search(const char* key, const char* expect)
|
||||||
|
{
|
||||||
|
const char* value = (const char*) rb_tree_get(tree, key);
|
||||||
|
if (!value) return !expect;
|
||||||
|
if (!expect) return 0;
|
||||||
|
return strcmp(value, expect) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXO_TEST(rbtree_search_1, { return test_check_search("one", "1"); });
|
||||||
|
EXO_TEST(rbtree_search_2, { return test_check_search("two", "2"); });
|
||||||
|
EXO_TEST(rbtree_search_3, { return test_check_search("three", "3"); });
|
||||||
|
EXO_TEST(rbtree_search_4, { return test_check_search("four", NULL); });
|
||||||
|
|
||||||
|
|
||||||
|
EXO_TEST(rbtree_remove_1, {
|
||||||
|
return rb_tree_remove(tree, "one");
|
||||||
|
});
|
||||||
|
|
||||||
|
EXO_TEST(rbtree_size_2, { return rb_tree_size(tree) == 2; });
|
||||||
|
|
||||||
|
EXO_TEST(rbtree_remove_2, {
|
||||||
|
return rb_tree_remove(tree, "two");
|
||||||
|
});
|
||||||
|
|
||||||
|
EXO_TEST(rbtree_remove_3, {
|
||||||
|
return rb_tree_remove(tree, "three");
|
||||||
|
});
|
||||||
|
|
||||||
|
EXO_TEST(rbtree_remove_3_again, {
|
||||||
|
return !rb_tree_remove(tree, "three");
|
||||||
|
});
|
||||||
|
|
||||||
|
EXO_TEST(rbtree_search_5, { return test_check_search("one", NULL); });
|
||||||
|
EXO_TEST(rbtree_search_6, { return test_check_search("two", NULL); });
|
||||||
|
EXO_TEST(rbtree_search_7, { return test_check_search("three", NULL); });
|
||||||
|
EXO_TEST(rbtree_search_8, { return test_check_search("four", NULL); });
|
||||||
|
|
||||||
|
EXO_TEST(rbtree_size_3, { return rb_tree_size(tree) == 0; });
|
||||||
|
|
||||||
|
EXO_TEST(rbtree_insert_10000, {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < MAX_NODES ; i++)
|
||||||
|
{
|
||||||
|
const char* key = strdup(uhub_itoa(i));
|
||||||
|
const char* val = strdup(uhub_itoa(i + 16384));
|
||||||
|
if (!rb_tree_insert(tree, key, val))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
EXO_TEST(rbtree_size_4, { return rb_tree_size(tree) == MAX_NODES ; });
|
||||||
|
|
||||||
|
EXO_TEST(rbtree_check_10000, {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < MAX_NODES ; i++)
|
||||||
|
{
|
||||||
|
char* key = strdup(uhub_itoa(i));
|
||||||
|
const char* expect = uhub_itoa(i + 16384);
|
||||||
|
if (!test_check_search(key, expect))
|
||||||
|
return 0;
|
||||||
|
hub_free(key);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
EXO_TEST(rbtree_iterate_10000, {
|
||||||
|
int i = 0;
|
||||||
|
struct rb_node* n = (struct rb_node*) rb_tree_first(tree);
|
||||||
|
while (n)
|
||||||
|
{
|
||||||
|
struct rb_node* p = n;
|
||||||
|
n = (struct rb_node*) rb_tree_next(tree);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return i == MAX_NODES ;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
static void free_node(struct rb_node* n)
|
||||||
|
{
|
||||||
|
hub_free((void*) n->key);
|
||||||
|
hub_free((void*) n->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
EXO_TEST(rbtree_remove_5000, {
|
||||||
|
int i = 0;
|
||||||
|
struct rb_node* n = (struct rb_node*) rb_tree_first(tree);
|
||||||
|
for (i = 0; i < MAX_NODES ; i += 2)
|
||||||
|
{
|
||||||
|
const char* key = uhub_itoa(i);
|
||||||
|
rb_tree_remove_node(tree, key, &free_node);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -7,13 +7,15 @@
|
|||||||
static int match_str(const char* str1, char* str2)
|
static int match_str(const char* str1, char* str2)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
int ret;
|
||||||
|
|
||||||
for (i = 0; i < strlen(str2); i++)
|
for (i = 0; i < strlen(str2); i++)
|
||||||
if (str2[i] == '_')
|
if (str2[i] == '_')
|
||||||
str2[i] = ' ';
|
str2[i] = ' ';
|
||||||
else if (str2[i] == '|')
|
else if (str2[i] == '|')
|
||||||
str2[i] = '\t';
|
str2[i] = '\t';
|
||||||
|
|
||||||
int ret = strcmp(str1, str2);
|
ret = strcmp(str1, str2);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
fprintf(stderr, "\n Mismatch: \"%s\" != \"%s\"\n", str1, str2);
|
fprintf(stderr, "\n Mismatch: \"%s\" != \"%s\"\n", str1, str2);
|
||||||
}
|
}
|
||||||
@@ -29,10 +31,11 @@ static int count(const char* STR, size_t EXPECT) {
|
|||||||
|
|
||||||
static int compare(const char* str, const char* ref) {
|
static int compare(const char* str, const char* ref) {
|
||||||
size_t i, max;
|
size_t i, max;
|
||||||
|
int pass;
|
||||||
struct linked_list* compare = list_create();
|
struct linked_list* compare = list_create();
|
||||||
SETUP(tokens, str);
|
SETUP(tokens, str);
|
||||||
split_string(ref, " ", compare, 0);
|
split_string(ref, " ", compare, 0);
|
||||||
int pass = cfg_token_count(tokens) == list_size(compare);
|
pass = cfg_token_count(tokens) == list_size(compare);
|
||||||
if (pass) {
|
if (pass) {
|
||||||
max = cfg_token_count(tokens);
|
max = cfg_token_count(tokens);
|
||||||
for (i = 0; i < max; i++) {
|
for (i = 0; i < max; i++) {
|
||||||
|
|||||||
@@ -2,32 +2,19 @@
|
|||||||
|
|
||||||
#define MAX_USERS 64
|
#define MAX_USERS 64
|
||||||
|
|
||||||
static struct hub_info um_hub;
|
static struct hub_user_manager* uman = 0;
|
||||||
static struct hub_user um_user[MAX_USERS];
|
static struct hub_user um_user[MAX_USERS];
|
||||||
// static struct net_connection um_cons[MAX_USERS];
|
|
||||||
|
|
||||||
EXO_TEST(um_test_setup, {
|
|
||||||
int i = 0;
|
|
||||||
memset(&um_hub, 0, sizeof(um_hub));
|
|
||||||
|
|
||||||
for (i = 0; i < MAX_USERS; i++)
|
|
||||||
{
|
|
||||||
/* memset(&um_cons[i], 0, sizeof(struct net_connection));
|
|
||||||
um_cons[i].sd = -1;
|
|
||||||
|
|
||||||
memset(&um_user[i], 0, sizeof(struct hub_user));
|
|
||||||
um_user[i].id.sid = i+1;
|
|
||||||
um_user[i].connection = &um_cons[i];*/
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
});
|
|
||||||
|
|
||||||
EXO_TEST(um_init_1, {
|
EXO_TEST(um_init_1, {
|
||||||
return uman_init(0) != 0;
|
sid_t s;
|
||||||
});
|
uman = uman_init();
|
||||||
|
|
||||||
EXO_TEST(um_init_2, {
|
for (s = 0; s < MAX_USERS; s++)
|
||||||
return uman_init(&um_hub) == 0;
|
{
|
||||||
|
memset(&um_user[s], 0, sizeof(struct hub_user));
|
||||||
|
um_user[s].id.sid = s;
|
||||||
|
}
|
||||||
|
return !!uman;
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(um_shutdown_1, {
|
EXO_TEST(um_shutdown_1, {
|
||||||
@@ -35,32 +22,29 @@ EXO_TEST(um_shutdown_1, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(um_shutdown_2, {
|
EXO_TEST(um_shutdown_2, {
|
||||||
return uman_shutdown(&um_hub) == 0;
|
return uman_shutdown(uman) == 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(um_shutdown_3, {
|
EXO_TEST(um_init_2, {
|
||||||
return uman_shutdown(&um_hub) == -1;
|
uman = uman_init();
|
||||||
});
|
return !!uman;
|
||||||
|
|
||||||
EXO_TEST(um_init_3, {
|
|
||||||
return uman_init(&um_hub) == 0;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(um_add_1, {
|
EXO_TEST(um_add_1, {
|
||||||
return uman_add(&um_hub, &um_user[0]) == 0;
|
return uman_add(uman, &um_user[0]) == 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(um_size_1, {
|
EXO_TEST(um_size_1, {
|
||||||
return hub_get_user_count(&um_hub) == 1;
|
return uman->count == 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
EXO_TEST(um_remove_1, {
|
EXO_TEST(um_remove_1, {
|
||||||
return uman_remove(&um_hub, &um_user[0]) == 0;
|
return uman_remove(uman, &um_user[0]) == 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(um_size_2, {
|
EXO_TEST(um_size_2, {
|
||||||
return hub_get_user_count(&um_hub) == 0;
|
return uman->count == 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -68,25 +52,21 @@ EXO_TEST(um_add_2, {
|
|||||||
int i;
|
int i;
|
||||||
for (i = 0; i < MAX_USERS; i++)
|
for (i = 0; i < MAX_USERS; i++)
|
||||||
{
|
{
|
||||||
if (uman_add(&um_hub, &um_user[i]) != 0)
|
if (uman_add(uman, &um_user[i]) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(um_size_3, {
|
EXO_TEST(um_size_3, {
|
||||||
return hub_get_user_count(&um_hub) == MAX_USERS;
|
return uman->count == MAX_USERS;
|
||||||
});
|
|
||||||
|
|
||||||
EXO_TEST(um_add_3, {
|
|
||||||
return uman_add(&um_hub, &um_user[5]) != 0;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(um_remove_2, {
|
EXO_TEST(um_remove_2, {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < MAX_USERS; i++)
|
for (i = 0; i < MAX_USERS; i++)
|
||||||
{
|
{
|
||||||
if (uman_remove(&um_hub, &um_user[i]) != 0)
|
if (uman_remove(uman, &um_user[i]) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@@ -105,5 +85,5 @@ EXO_TEST(um_remove_2, {
|
|||||||
|
|
||||||
/* Last test */
|
/* Last test */
|
||||||
EXO_TEST(um_shutdown_4, {
|
EXO_TEST(um_shutdown_4, {
|
||||||
return uman_shutdown(&um_hub) == 0;
|
return uman_shutdown(uman) == 0;
|
||||||
});
|
});
|
||||||
|
|||||||
4
autotest/update.sh
Executable file
4
autotest/update.sh
Executable file
@@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
./exotic *.tcc > test.c
|
||||||
|
|
||||||
@@ -31,7 +31,8 @@ fi
|
|||||||
# Check that networking is up.
|
# Check that networking is up.
|
||||||
[ ${NETWORKING} = "no" ] && exit 1
|
[ ${NETWORKING} = "no" ] && exit 1
|
||||||
|
|
||||||
# Check that uhub.conf exists.
|
# Check that bin and uhub.conf exists.
|
||||||
|
[ -f $UHUBBINFILE ] || exit 6
|
||||||
[ -f /etc/uhub/uhub.conf ] || exit 6
|
[ -f /etc/uhub/uhub.conf ] || exit 6
|
||||||
|
|
||||||
RETVAL=0
|
RETVAL=0
|
||||||
@@ -40,7 +41,7 @@ RETVAL=0
|
|||||||
start() {
|
start() {
|
||||||
KIND="Uhub"
|
KIND="Uhub"
|
||||||
echo -n $"Starting $KIND services: "
|
echo -n $"Starting $KIND services: "
|
||||||
daemon uhub $UHUBOPTIONS
|
daemon $UHUBBINFILE $UHUBOPTIONS
|
||||||
RETVAL=$?
|
RETVAL=$?
|
||||||
echo ""
|
echo ""
|
||||||
return $RETVAL
|
return $RETVAL
|
||||||
@@ -49,7 +50,7 @@ start() {
|
|||||||
stop() {
|
stop() {
|
||||||
KIND="Uhub"
|
KIND="Uhub"
|
||||||
echo -n $"Shutting down $KIND services: "
|
echo -n $"Shutting down $KIND services: "
|
||||||
killproc uhub
|
killproc $UHUBBINFILE
|
||||||
RETVAL=$?
|
RETVAL=$?
|
||||||
echo ""
|
echo ""
|
||||||
return $RETVAL
|
return $RETVAL
|
||||||
@@ -77,7 +78,7 @@ relog() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rhstatus() {
|
rhstatus() {
|
||||||
status uhub
|
status $UHUBBINFILE
|
||||||
RETVAL=$?
|
RETVAL=$?
|
||||||
if [ $RETVAL -ne 0 ] ; then
|
if [ $RETVAL -ne 0 ] ; then
|
||||||
return $RETVAL
|
return $RETVAL
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
# locate bin file
|
||||||
|
UHUBBINFILE=/usr/bin/uhub
|
||||||
|
|
||||||
# Options to UHUB
|
# Options to UHUB
|
||||||
# -v Verbose mode. Add more -v's for higher verbosity.
|
# -v Verbose mode. Add more -v's for higher verbosity.
|
||||||
# -q Quiet mode - no output
|
# -q Quiet mode - no output
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
# Parameters:
|
# Parameters:
|
||||||
# file: path/filename for database.
|
# file: path/filename for database.
|
||||||
#
|
#
|
||||||
plugin /var/lib/uhub/mod_auth_sqlite.so "file=/etc/uhub/users.db"
|
plugin /usr/lib/uhub/mod_auth_sqlite.so "file=/etc/uhub/users.db"
|
||||||
|
|
||||||
|
|
||||||
# Log file writer
|
# Log file writer
|
||||||
@@ -19,10 +19,10 @@ plugin /var/lib/uhub/mod_auth_sqlite.so "file=/etc/uhub/users.db"
|
|||||||
# Parameters:
|
# Parameters:
|
||||||
# file: path/filename for log file.
|
# file: path/filename for log file.
|
||||||
# syslog: if true then syslog is used instead of writing to a file (Unix only)
|
# syslog: if true then syslog is used instead of writing to a file (Unix only)
|
||||||
plugin /var/lib/uhub/mod_logging.so "file=/var/log/uhub.log"
|
plugin /usr/lib/uhub/mod_logging.so "file=/var/log/uhub.log"
|
||||||
|
|
||||||
# A simple example plugin
|
# A simple example plugin
|
||||||
# plugin /var/lib/uhub/mod_example.so
|
# plugin /usr/lib/uhub/mod_example.so
|
||||||
# A plugin sending a welcome message.
|
# A plugin sending a welcome message.
|
||||||
#
|
#
|
||||||
# This plugin provides the following commands:
|
# This plugin provides the following commands:
|
||||||
@@ -46,7 +46,7 @@ plugin /var/lib/uhub/mod_logging.so "file=/var/log/uhub.log"
|
|||||||
# %p - 'am' or 'pm'
|
# %p - 'am' or 'pm'
|
||||||
# %M - Minutes (00-59) (Hub local time)
|
# %M - Minutes (00-59) (Hub local time)
|
||||||
# %S - Seconds (00-60) (Hub local time)
|
# %S - Seconds (00-60) (Hub local time)
|
||||||
plugin /var/lib/uhub/mod_welcome.so "motd=/etc/uhub/motd.txt rules=/etc/uhub/rules.txt"
|
plugin /usr/lib/uhub/mod_welcome.so "motd=/etc/uhub/motd.txt rules=/etc/uhub/rules.txt"
|
||||||
|
|
||||||
# Load the chat history plugin.
|
# Load the chat history plugin.
|
||||||
#
|
#
|
||||||
@@ -58,5 +58,5 @@ plugin /var/lib/uhub/mod_welcome.so "motd=/etc/uhub/motd.txt rules=/etc/uhub/rul
|
|||||||
# history_max: the maximum number of messages to keep in history
|
# history_max: the maximum number of messages to keep in history
|
||||||
# history_default: when !history is provided without arguments, then this default number of messages are returned.
|
# history_default: when !history is provided without arguments, then this default number of messages are returned.
|
||||||
# history_connect: the number of chat history messages to send when users connect (0 = do not send any history)
|
# history_connect: the number of chat history messages to send when users connect (0 = do not send any history)
|
||||||
plugin /var/lib/uhub/mod_chat_history.so "history_max=200 history_default=10 history_connect=5"
|
plugin /usr/lib/uhub/mod_chat_history.so "history_max=200 history_default=10 history_connect=5"
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ mkdir -p $RPM_BUILD_ROOT/etc/init.d
|
|||||||
mkdir -p $RPM_BUILD_ROOT/etc/logrotate.d
|
mkdir -p $RPM_BUILD_ROOT/etc/logrotate.d
|
||||||
mkdir -p $RPM_BUILD_ROOT/etc/sysconfig
|
mkdir -p $RPM_BUILD_ROOT/etc/sysconfig
|
||||||
mkdir -p $RPM_BUILD_ROOT/usr/share/man/man1
|
mkdir -p $RPM_BUILD_ROOT/usr/share/man/man1
|
||||||
mkdir -p $RPM_BUILD_ROOT/var/lib/uhub
|
mkdir -p $RPM_BUILD_ROOT/usr/lib/uhub
|
||||||
|
|
||||||
install uhub $RPM_BUILD_ROOT/usr/bin/
|
install uhub $RPM_BUILD_ROOT/usr/bin/
|
||||||
install uhub-passwd $RPM_BUILD_ROOT/usr/bin/
|
install uhub-passwd $RPM_BUILD_ROOT/usr/bin/
|
||||||
@@ -52,7 +52,7 @@ install -m644 doc/init.d.RedHat/etc/sysconfig/uhub $RPM_BUILD_ROOT/etc/sysconfi
|
|||||||
install -m644 doc/init.d.RedHat/etc/logrotate.d/uhub $RPM_BUILD_ROOT/etc/logrotate.d/
|
install -m644 doc/init.d.RedHat/etc/logrotate.d/uhub $RPM_BUILD_ROOT/etc/logrotate.d/
|
||||||
/bin/gzip -9c doc/uhub.1 > doc/uhub.1.gz &&
|
/bin/gzip -9c doc/uhub.1 > doc/uhub.1.gz &&
|
||||||
install -m644 doc/uhub.1.gz $RPM_BUILD_ROOT/usr/share/man/man1
|
install -m644 doc/uhub.1.gz $RPM_BUILD_ROOT/usr/share/man/man1
|
||||||
install -m644 mod_*.so $RPM_BUILD_ROOT/var/lib/uhub
|
install -m644 mod_*.so $RPM_BUILD_ROOT/usr/lib/uhub
|
||||||
|
|
||||||
|
|
||||||
%files
|
%files
|
||||||
|
|||||||
28
doc/upstart/etc/init/uhub.conf
Normal file
28
doc/upstart/etc/init/uhub.conf
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# uHub - a lightweight but high-performance hub for the ADC
|
||||||
|
# peer-to-peer protocol.
|
||||||
|
|
||||||
|
description "uHub - High performance ADC peer-to-peer hub"
|
||||||
|
|
||||||
|
# Start and stop conditions.
|
||||||
|
start on filesystem or runlevel [2345]
|
||||||
|
stop on runlevel [!2345]
|
||||||
|
|
||||||
|
# Allow the service to respawn, but if its happening too often
|
||||||
|
# (10 times in 5 seconds) theres a problem and we should stop trying.
|
||||||
|
respawn
|
||||||
|
respawn limit 10 5
|
||||||
|
|
||||||
|
# The program is going to fork, and upstart needs to know this
|
||||||
|
# so it can track the change in PID.
|
||||||
|
expect fork
|
||||||
|
|
||||||
|
# Set the mode the process should create files in.
|
||||||
|
umask 022
|
||||||
|
|
||||||
|
# Make sure the log folder exists.
|
||||||
|
pre-start script
|
||||||
|
mkdir -p -m0755 /var/log/uhub
|
||||||
|
end script
|
||||||
|
|
||||||
|
# Command to run it.
|
||||||
|
exec /usr/bin/uhub -f -u uhub -g uhub -l /var/log/uhub/uhub.log -c /etc/uhub/uhub.conf
|
||||||
@@ -33,7 +33,7 @@ typedef uint32_t fourcc_t;
|
|||||||
#define FOURCC(a,b,c,d) (fourcc_t) ((a << 24) | (b << 16) | (c << 8) | d)
|
#define FOURCC(a,b,c,d) (fourcc_t) ((a << 24) | (b << 16) | (c << 8) | d)
|
||||||
|
|
||||||
/* default welcome protocol support message, as sent by this server */
|
/* default welcome protocol support message, as sent by this server */
|
||||||
#define ADC_PROTO_SUPPORT "ADBASE ADTIGR ADPING"
|
#define ADC_PROTO_SUPPORT "ADBASE ADTIGR ADPING ADUCMD"
|
||||||
|
|
||||||
/* Server sent commands */
|
/* Server sent commands */
|
||||||
#define ADC_CMD_ISID FOURCC('I','S','I','D')
|
#define ADC_CMD_ISID FOURCC('I','S','I','D')
|
||||||
@@ -93,6 +93,15 @@ typedef uint32_t fourcc_t;
|
|||||||
/* Extension messages */
|
/* Extension messages */
|
||||||
#define ADC_CMD_HCHK FOURCC('H','C','H','K')
|
#define ADC_CMD_HCHK FOURCC('H','C','H','K')
|
||||||
|
|
||||||
|
/* UCMD Extension */
|
||||||
|
#define ADC_CMD_BCMD FOURCC('B','C','M','D')
|
||||||
|
#define ADC_CMD_DCMD FOURCC('D','C','M','D')
|
||||||
|
#define ADC_CMD_ECMD FOURCC('E','C','M','D')
|
||||||
|
#define ADC_CMD_FCMD FOURCC('F','C','M','D')
|
||||||
|
#define ADC_CMD_HCMD FOURCC('H','C','M','D')
|
||||||
|
#define ADC_CMD_ICMD FOURCC('I','C','M','D')
|
||||||
|
|
||||||
|
|
||||||
#define ADC_INF_FLAG_IPV4_ADDR "I4" /* ipv4 address */
|
#define ADC_INF_FLAG_IPV4_ADDR "I4" /* ipv4 address */
|
||||||
#define ADC_INF_FLAG_IPV6_ADDR "I6" /* ipv6 address */
|
#define ADC_INF_FLAG_IPV6_ADDR "I6" /* ipv6 address */
|
||||||
#define ADC_INF_FLAG_IPV4_UDP_PORT "U4" /* port number */
|
#define ADC_INF_FLAG_IPV4_UDP_PORT "U4" /* port number */
|
||||||
|
|||||||
@@ -63,6 +63,33 @@ static void msg_free(void* ptr)
|
|||||||
#define msg_free(X) hub_free(X)
|
#define msg_free(X) hub_free(X)
|
||||||
#endif /* MSG_MEMORY_DEBUG */
|
#endif /* MSG_MEMORY_DEBUG */
|
||||||
|
|
||||||
|
static int msg_check_escapes(const char* string, size_t len)
|
||||||
|
{
|
||||||
|
char* start = (char*) string;
|
||||||
|
while ((start = memchr(start, '\\', len - (start - string))))
|
||||||
|
{
|
||||||
|
if (start+1 == (string + len))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (*(++start))
|
||||||
|
{
|
||||||
|
case '\\':
|
||||||
|
case 'n':
|
||||||
|
case 's':
|
||||||
|
/* Increment so we don't check the escaped
|
||||||
|
* character next time around. Not doing so
|
||||||
|
* leads to messages with escaped backslashes
|
||||||
|
* being incorrectly reported as having invalid
|
||||||
|
* escapes. */
|
||||||
|
++start;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct adc_message* adc_msg_incref(struct adc_message* msg)
|
struct adc_message* adc_msg_incref(struct adc_message* msg)
|
||||||
{
|
{
|
||||||
@@ -319,6 +346,13 @@ struct adc_message* adc_msg_parse(const char* line, size_t length)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!msg_check_escapes(line, length))
|
||||||
|
{
|
||||||
|
LOG_DEBUG("Dropped message with invalid ADC escape.");
|
||||||
|
msg_free(command);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (line[length-1] != '\n')
|
if (line[length-1] != '\n')
|
||||||
{
|
{
|
||||||
need_terminate = 1;
|
need_terminate = 1;
|
||||||
@@ -498,6 +532,30 @@ struct adc_message* adc_msg_create(const char* line)
|
|||||||
return adc_msg_parse(line, strlen(line));
|
return adc_msg_parse(line, strlen(line));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct adc_message* adc_msg_construct_source(fourcc_t fourcc, sid_t source, size_t size)
|
||||||
|
{
|
||||||
|
struct adc_message* msg = adc_msg_construct(fourcc, size + 4 + 1);
|
||||||
|
if (!msg)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
adc_msg_add_argument(msg, sid_to_string(source));
|
||||||
|
msg->source = source;
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct adc_message* adc_msg_construct_source_dest(fourcc_t fourcc, sid_t source, sid_t dest, size_t size)
|
||||||
|
{
|
||||||
|
struct adc_message* msg = adc_msg_construct(fourcc, size + 4 + 4 + 1);
|
||||||
|
if (!msg)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
adc_msg_add_argument(msg, sid_to_string(source));
|
||||||
|
adc_msg_add_argument(msg, sid_to_string(dest));
|
||||||
|
msg->source = source;
|
||||||
|
msg->target = dest;
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct adc_message* adc_msg_construct(fourcc_t fourcc, size_t size)
|
struct adc_message* adc_msg_construct(fourcc_t fourcc, size_t size)
|
||||||
{
|
{
|
||||||
@@ -505,9 +563,7 @@ struct adc_message* adc_msg_construct(fourcc_t fourcc, size_t size)
|
|||||||
if (!msg)
|
if (!msg)
|
||||||
return NULL; /* OOM */
|
return NULL; /* OOM */
|
||||||
|
|
||||||
if (size < sizeof(fourcc)) size = sizeof(fourcc);
|
if (!adc_msg_grow(msg, sizeof(fourcc) + size + 1))
|
||||||
|
|
||||||
if (!adc_msg_grow(msg, size+1))
|
|
||||||
{
|
{
|
||||||
msg_free(msg);
|
msg_free(msg);
|
||||||
return NULL; /* OOM */
|
return NULL; /* OOM */
|
||||||
@@ -877,6 +933,41 @@ char* adc_msg_unescape(const char* string)
|
|||||||
return new_string;
|
return new_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int adc_msg_unescape_to_target(const char* string, char* target, size_t target_size)
|
||||||
|
{
|
||||||
|
size_t w = 0;
|
||||||
|
char* ptr = (char*) target;
|
||||||
|
char* str = (char*) string;
|
||||||
|
int escaped = 0;
|
||||||
|
|
||||||
|
while (*str && w < (target_size-1))
|
||||||
|
{
|
||||||
|
if (escaped) {
|
||||||
|
if (*str == 's')
|
||||||
|
*ptr++ = ' ';
|
||||||
|
else if (*str == '\\')
|
||||||
|
*ptr++ = '\\';
|
||||||
|
else if (*str == 'n')
|
||||||
|
*ptr++ = '\n';
|
||||||
|
else
|
||||||
|
*ptr++ = *str;
|
||||||
|
w++;
|
||||||
|
escaped = 0;
|
||||||
|
} else {
|
||||||
|
if (*str == '\\')
|
||||||
|
escaped = 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*ptr++ = *str;
|
||||||
|
w++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
*ptr = 0;
|
||||||
|
w++;
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
char* adc_msg_escape(const char* string)
|
char* adc_msg_escape(const char* string)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -91,6 +91,13 @@ extern struct adc_message* adc_msg_create(const char* string);
|
|||||||
*/
|
*/
|
||||||
extern struct adc_message* adc_msg_construct(fourcc_t fourcc, size_t size);
|
extern struct adc_message* adc_msg_construct(fourcc_t fourcc, size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a message for the given 'fourcc' and add a source SID to it,
|
||||||
|
* in addition pre-allocate 'size' bytes at the end of the message.
|
||||||
|
*/
|
||||||
|
extern struct adc_message* adc_msg_construct_source(fourcc_t fourcc, sid_t source, size_t size);
|
||||||
|
extern struct adc_message* adc_msg_construct_source_dest(fourcc_t fourcc, sid_t source, sid_t dest, size_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a named argument from the command.
|
* Remove a named argument from the command.
|
||||||
*
|
*
|
||||||
@@ -195,6 +202,14 @@ extern int adc_msg_add_named_argument_uint64(struct adc_message* cmd, const char
|
|||||||
*/
|
*/
|
||||||
extern char* adc_msg_unescape(const char* string);
|
extern char* adc_msg_unescape(const char* string);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a ADC command escaped string to a regular string.
|
||||||
|
* @return The number of bytes written to target. If the target is not large enough then
|
||||||
|
* the -1 is returned, but the string is guaranteed to always be \0 terminated.
|
||||||
|
*/
|
||||||
|
extern int adc_msg_unescape_to_target(const char* string, char* target, size_t target_size);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a string to a ADC command escaped string.
|
* Convert a string to a ADC command escaped string.
|
||||||
* @return adc command escaped string or NULL if out of memory.
|
* @return adc command escaped string or NULL if out of memory.
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ static enum command_parse_status command_extract_arguments(struct hub_info* hub,
|
|||||||
case 'u':
|
case 'u':
|
||||||
data = hub_malloc(sizeof(*data));
|
data = hub_malloc(sizeof(*data));
|
||||||
data->type = type_user;
|
data->type = type_user;
|
||||||
data->data.user = uman_get_user_by_nick(hub, token);
|
data->data.user = uman_get_user_by_nick(hub->users, token);
|
||||||
if (!data->data.user)
|
if (!data->data.user)
|
||||||
{
|
{
|
||||||
hub_free(data);
|
hub_free(data);
|
||||||
@@ -129,7 +129,7 @@ static enum command_parse_status command_extract_arguments(struct hub_info* hub,
|
|||||||
case 'i':
|
case 'i':
|
||||||
data = hub_malloc(sizeof(*data));
|
data = hub_malloc(sizeof(*data));
|
||||||
data->type = type_user;
|
data->type = type_user;
|
||||||
data->data.user = uman_get_user_by_cid(hub, token);
|
data->data.user = uman_get_user_by_cid(hub->users, token);
|
||||||
if (!data->data.user)
|
if (!data->data.user)
|
||||||
{
|
{
|
||||||
hub_free(data);
|
hub_free(data);
|
||||||
|
|||||||
@@ -421,7 +421,7 @@ static int command_whoip(struct command_base* cbase, struct hub_user* user, stru
|
|||||||
struct hub_user* u;
|
struct hub_user* u;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
ret = uman_get_user_by_addr(cbase->hub, users, arg->data.range);
|
ret = uman_get_user_by_addr(cbase->hub->users, users, arg->data.range);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
{
|
{
|
||||||
list_clear(users, &null_free);
|
list_clear(users, &null_free);
|
||||||
@@ -557,14 +557,28 @@ static int command_stats(struct command_base* cbase, struct hub_user* user, stru
|
|||||||
{
|
{
|
||||||
struct cbuffer* buf = cbuf_create(128);
|
struct cbuffer* buf = cbuf_create(128);
|
||||||
struct hub_info* hub = cbase->hub;
|
struct hub_info* hub = cbase->hub;
|
||||||
|
static char rxbuf[64] = { "0 B" };
|
||||||
|
static char txbuf[64] = { "0 B" };
|
||||||
|
|
||||||
|
cbuf_append(buf, "Hub statistics: ");
|
||||||
|
cbuf_append_format(buf, PRINTF_SIZE_T "/" PRINTF_SIZE_T " users (peak %d). ", hub->users->count, hub->config->max_users, hub->users->count_peak);
|
||||||
|
|
||||||
|
format_size(hub->stats.net_rx, rxbuf, sizeof(rxbuf));
|
||||||
|
format_size(hub->stats.net_tx, txbuf, sizeof(txbuf));
|
||||||
|
|
||||||
|
cbuf_append_format(buf, "Network: tx=%s/s, rx=%s/s", txbuf, rxbuf);
|
||||||
|
|
||||||
|
#ifdef SHOW_PEAK_NET_STATS /* currently disabled */
|
||||||
|
format_size(hub->stats.net_rx_peak, rxbuf, sizeof(rxbuf));
|
||||||
|
format_size(hub->stats.net_tx_peak, txbuf, sizeof(txbuf));
|
||||||
|
cbuf_append_format(buf, ", peak_tx=%s/s, peak_rx=%s/s", txbuf, rxbuf);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
format_size(hub->stats.net_rx_total, rxbuf, sizeof(rxbuf));
|
||||||
|
format_size(hub->stats.net_tx_total, txbuf, sizeof(txbuf));
|
||||||
|
cbuf_append_format(buf, ", total_tx=%s", txbuf);
|
||||||
|
cbuf_append_format(buf, ", total_rx=%s", rxbuf);
|
||||||
|
|
||||||
cbuf_append_format(buf, PRINTF_SIZE_T " users, peak: " PRINTF_SIZE_T ". Network (up/down): %d/%d KB/s, peak: %d/%d KB/s",
|
|
||||||
hub->users->count,
|
|
||||||
hub->users->count_peak,
|
|
||||||
(int) hub->stats.net_tx / 1024,
|
|
||||||
(int) hub->stats.net_rx / 1024,
|
|
||||||
(int) hub->stats.net_tx_peak / 1024,
|
|
||||||
(int) hub->stats.net_rx_peak / 1024);
|
|
||||||
return command_status(cbase, user, cmd, buf);
|
return command_status(cbase, user, cmd, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ my $config_dump = "void dump_config(struct hub_config* config, int ignore_defaul
|
|||||||
|
|
||||||
foreach my $option (@options)
|
foreach my $option (@options)
|
||||||
{
|
{
|
||||||
my ($type, $name, $default, $advanced, $short, $desc, $since, $example, $check) = @$option;
|
my ($type, $name, $default, $advanced, $short, $desc, $since, $example, $check, $ifdef) = @$option;
|
||||||
my $string = ($type =~ /(string|file|message)/);
|
my $string = ($type =~ /(string|file|message)/);
|
||||||
my $min = undef;
|
my $min = undef;
|
||||||
my $max = undef;
|
my $max = undef;
|
||||||
@@ -50,12 +50,15 @@ foreach my $option (@options)
|
|||||||
$regexp = undef if ($regexp eq "");
|
$regexp = undef if ($regexp eq "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$config_defaults .= "#ifdef $ifdef\n" if ($ifdef ne "");
|
||||||
$config_defaults .= "\tconfig->$name = ";
|
$config_defaults .= "\tconfig->$name = ";
|
||||||
$config_defaults .= "hub_strdup(\"" if ($string);
|
$config_defaults .= "hub_strdup(\"" if ($string);
|
||||||
$config_defaults .= $default;
|
$config_defaults .= $default;
|
||||||
$config_defaults .= "\")" if ($string);
|
$config_defaults .= "\")" if ($string);
|
||||||
$config_defaults .= ";\n";
|
$config_defaults .= ";\n";
|
||||||
|
$config_defaults .= "#endif /* $ifdef */\n" if ($ifdef ne "");
|
||||||
|
|
||||||
|
$config_apply .= "#ifdef $ifdef\n" if ($ifdef ne "");
|
||||||
$config_apply .= "\tif (!strcmp(key, \"" . $name . "\"))\n\t{\n";
|
$config_apply .= "\tif (!strcmp(key, \"" . $name . "\"))\n\t{\n";
|
||||||
|
|
||||||
if ($type eq "int")
|
if ($type eq "int")
|
||||||
@@ -82,10 +85,17 @@ foreach my $option (@options)
|
|||||||
"\t\t\treturn -1;\n" .
|
"\t\t\treturn -1;\n" .
|
||||||
"\t\t}\n" .
|
"\t\t}\n" .
|
||||||
"\t\treturn 0;\n" .
|
"\t\treturn 0;\n" .
|
||||||
"\t}\n\n";
|
"\t}\n";
|
||||||
|
$config_apply .= "#endif /* $ifdef */\n" if ($ifdef ne "");
|
||||||
$config_free .= "\thub_free(config->" . $name . ");\n\n" if ($string);
|
$config_apply .= "\n";
|
||||||
|
|
||||||
|
if ($string)
|
||||||
|
{
|
||||||
|
$config_free .= "#ifdef $ifdef\n" if ($ifdef ne "");
|
||||||
|
$config_free .= "\thub_free(config->" . $name . ");\n";
|
||||||
|
$config_free .= "#endif /* $ifdef */\n" if ($ifdef ne "");
|
||||||
|
$config_free .= "\n";
|
||||||
|
}
|
||||||
|
|
||||||
my $out = "%s";
|
my $out = "%s";
|
||||||
my $val = "config->$name";
|
my $val = "config->$name";
|
||||||
@@ -100,8 +110,11 @@ foreach my $option (@options)
|
|||||||
$test = "strcmp(config->$name, \"$default\") != 0";
|
$test = "strcmp(config->$name, \"$default\") != 0";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$config_dump .= "#ifdef $ifdef\n" if ($ifdef ne "");
|
||||||
$config_dump .= "\tif (!ignore_defaults || $test)\n";
|
$config_dump .= "\tif (!ignore_defaults || $test)\n";
|
||||||
$config_dump .= "\t\tfprintf(stdout, \"$name = $out\\n\", $val);\n\n";
|
$config_dump .= "\t\tfprintf(stdout, \"$name = $out\\n\", $val);\n";
|
||||||
|
$config_dump .= "#endif /* $ifdef */\n" if ($ifdef ne "");
|
||||||
|
$config_dump .= "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
$config_apply .= "\t/* Still here -- unknown directive */\n";
|
$config_apply .= "\t/* Still here -- unknown directive */\n";
|
||||||
@@ -128,12 +141,14 @@ sub get_data($)
|
|||||||
my $example = "";
|
my $example = "";
|
||||||
my $description = "";
|
my $description = "";
|
||||||
my $since = "";
|
my $since = "";
|
||||||
|
my $ifdef = "";
|
||||||
|
|
||||||
$short = $p->getElementsByTagName("short")->item(0)->getFirstChild()->getData() if ($p->getElementsByTagName("short")->getLength());
|
$short = $p->getElementsByTagName("short")->item(0)->getFirstChild()->getData() if ($p->getElementsByTagName("short")->getLength());
|
||||||
$since = $p->getElementsByTagName("since")->item(0)->getFirstChild()->getData() if ($p->getElementsByTagName("since")->getLength());
|
$since = $p->getElementsByTagName("since")->item(0)->getFirstChild()->getData() if ($p->getElementsByTagName("since")->getLength());
|
||||||
$example = $p->getElementsByTagName("example")->item(0)->getFirstChild()->getData() if ($p->getElementsByTagName("example")->getLength());
|
$example = $p->getElementsByTagName("example")->item(0)->getFirstChild()->getData() if ($p->getElementsByTagName("example")->getLength());
|
||||||
$description = $p->getElementsByTagName("description")->item(0)->getFirstChild()->getData() if ($p->getElementsByTagName("description")->getLength());
|
$description = $p->getElementsByTagName("description")->item(0)->getFirstChild()->getData() if ($p->getElementsByTagName("description")->getLength());
|
||||||
my $check = $p->getElementsByTagName("check")->item(0);
|
my $check = $p->getElementsByTagName("check")->item(0);
|
||||||
|
$ifdef = $p->getElementsByTagName("ifdef")->item(0)->getFirstChild()->getData() if ($p->getElementsByTagName("ifdef")->getLength());
|
||||||
|
|
||||||
my @data = (
|
my @data = (
|
||||||
$p->getAttribute("type"),
|
$p->getAttribute("type"),
|
||||||
@@ -144,7 +159,8 @@ sub get_data($)
|
|||||||
$description,
|
$description,
|
||||||
$since,
|
$since,
|
||||||
$example,
|
$example,
|
||||||
$check
|
$check,
|
||||||
|
$ifdef
|
||||||
);
|
);
|
||||||
return @data;
|
return @data;
|
||||||
}
|
}
|
||||||
@@ -160,10 +176,12 @@ sub write_c_header(@)
|
|||||||
|
|
||||||
foreach my $option (@data)
|
foreach my $option (@data)
|
||||||
{
|
{
|
||||||
my ($type, $name, $default, $advanced, $short, $desc, $since, $example) = @$option;
|
my ($type, $name, $default, $advanced, $short, $desc, $since, $example, $check, $ifdef) = @$option;
|
||||||
|
|
||||||
my $string = ($type =~ /(string|file|message)/);
|
my $string = ($type =~ /(string|file|message)/);
|
||||||
|
|
||||||
|
print GENHEAD "#ifdef $ifdef\n" if ($ifdef ne "");
|
||||||
|
|
||||||
print GENHEAD "\t";
|
print GENHEAD "\t";
|
||||||
print GENHEAD "int " if ($type eq "int");
|
print GENHEAD "int " if ($type eq "int");
|
||||||
print GENHEAD "int " if ($type eq "boolean");
|
print GENHEAD "int " if ($type eq "boolean");
|
||||||
@@ -198,6 +216,7 @@ sub write_c_header(@)
|
|||||||
$comment = $pad . "/*<<< " . $comment . " */";
|
$comment = $pad . "/*<<< " . $comment . " */";
|
||||||
}
|
}
|
||||||
print GENHEAD $comment . "\n";
|
print GENHEAD $comment . "\n";
|
||||||
|
print GENHEAD "#endif /* $ifdef */\n" if ($ifdef ne "");
|
||||||
}
|
}
|
||||||
|
|
||||||
print GENHEAD "};\n\n";
|
print GENHEAD "};\n\n";
|
||||||
@@ -224,7 +243,7 @@ sub write_sql_dump(@)
|
|||||||
|
|
||||||
foreach my $option (@data)
|
foreach my $option (@data)
|
||||||
{
|
{
|
||||||
my ($type, $name, $default, $advanced, $short, $desc, $since, $example) = @$option;
|
my ($type, $name, $default, $advanced, $short, $desc, $since, $example, $check, $ifdef) = @$option;
|
||||||
|
|
||||||
if ($type =~ /(string|file|message)/ )
|
if ($type =~ /(string|file|message)/ )
|
||||||
{
|
{
|
||||||
|
|||||||
109
src/core/hub.c
109
src/core/hub.c
@@ -110,25 +110,33 @@ int hub_handle_message(struct hub_info* hub, struct hub_user* u, const char* lin
|
|||||||
|
|
||||||
case ADC_CMD_DRES:
|
case ADC_CMD_DRES:
|
||||||
cmd->priority = -1;
|
cmd->priority = -1;
|
||||||
if (plugin_handle_search_result(hub, u, uman_get_user_by_sid(hub, cmd->target), cmd->cache) == st_deny)
|
if (plugin_handle_search_result(hub, u, uman_get_user_by_sid(hub->users, cmd->target), cmd->cache) == st_deny)
|
||||||
break;
|
break;
|
||||||
/* CHECK_FLOOD(search, 0); */
|
/* CHECK_FLOOD(search, 0); */
|
||||||
ROUTE_MSG;
|
ROUTE_MSG;
|
||||||
|
|
||||||
case ADC_CMD_DRCM:
|
case ADC_CMD_DRCM:
|
||||||
cmd->priority = -1;
|
cmd->priority = -1;
|
||||||
if (plugin_handle_revconnect(hub, u, uman_get_user_by_sid(hub, cmd->target)) == st_deny)
|
if (plugin_handle_revconnect(hub, u, uman_get_user_by_sid(hub->users, cmd->target)) == st_deny)
|
||||||
break;
|
break;
|
||||||
CHECK_FLOOD(connect, 1);
|
CHECK_FLOOD(connect, 1);
|
||||||
ROUTE_MSG;
|
ROUTE_MSG;
|
||||||
|
|
||||||
case ADC_CMD_DCTM:
|
case ADC_CMD_DCTM:
|
||||||
cmd->priority = -1;
|
cmd->priority = -1;
|
||||||
if (plugin_handle_connect(hub, u, uman_get_user_by_sid(hub, cmd->target)) == st_deny)
|
if (plugin_handle_connect(hub, u, uman_get_user_by_sid(hub->users, cmd->target)) == st_deny)
|
||||||
break;
|
break;
|
||||||
CHECK_FLOOD(connect, 1);
|
CHECK_FLOOD(connect, 1);
|
||||||
ROUTE_MSG;
|
ROUTE_MSG;
|
||||||
|
|
||||||
|
case ADC_CMD_BCMD:
|
||||||
|
case ADC_CMD_DCMD:
|
||||||
|
case ADC_CMD_ECMD:
|
||||||
|
case ADC_CMD_FCMD:
|
||||||
|
case ADC_CMD_HCMD:
|
||||||
|
CHECK_FLOOD(extras, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
CHECK_FLOOD(extras, 1);
|
CHECK_FLOOD(extras, 1);
|
||||||
ROUTE_MSG;
|
ROUTE_MSG;
|
||||||
@@ -332,7 +340,7 @@ int hub_handle_chat_message(struct hub_info* hub, struct hub_user* u, struct adc
|
|||||||
}
|
}
|
||||||
else if (private_msg)
|
else if (private_msg)
|
||||||
{
|
{
|
||||||
struct hub_user* target = uman_get_user_by_sid(hub, cmd->target);
|
struct hub_user* target = uman_get_user_by_sid(hub->users, cmd->target);
|
||||||
if (target)
|
if (target)
|
||||||
status = plugin_handle_private_message(hub, u, target, message_decoded, 0);
|
status = plugin_handle_private_message(hub, u, target, message_decoded, 0);
|
||||||
else
|
else
|
||||||
@@ -373,7 +381,7 @@ void hub_send_sid(struct hub_info* hub, struct hub_user* u)
|
|||||||
if (user_is_connecting(u))
|
if (user_is_connecting(u))
|
||||||
{
|
{
|
||||||
command = adc_msg_construct(ADC_CMD_ISID, 10);
|
command = adc_msg_construct(ADC_CMD_ISID, 10);
|
||||||
sid = uman_get_free_sid(hub, u);
|
sid = uman_get_free_sid(hub->users, u);
|
||||||
adc_msg_add_argument(command, (const char*) sid_to_string(sid));
|
adc_msg_add_argument(command, (const char*) sid_to_string(sid));
|
||||||
route_to_user(hub, u, command);
|
route_to_user(hub, u, command);
|
||||||
adc_msg_free(command);
|
adc_msg_free(command);
|
||||||
@@ -512,11 +520,11 @@ static int check_duplicate_logins_ok(struct hub_info* hub, struct hub_user* user
|
|||||||
struct hub_user* lookup1;
|
struct hub_user* lookup1;
|
||||||
struct hub_user* lookup2;
|
struct hub_user* lookup2;
|
||||||
|
|
||||||
lookup1 = uman_get_user_by_nick(hub, user->id.nick);
|
lookup1 = uman_get_user_by_nick(hub->users, user->id.nick);
|
||||||
if (lookup1)
|
if (lookup1)
|
||||||
return status_msg_inf_error_nick_taken;
|
return status_msg_inf_error_nick_taken;
|
||||||
|
|
||||||
lookup2 = uman_get_user_by_cid(hub, user->id.cid);
|
lookup2 = uman_get_user_by_cid(hub->users, user->id.cid);
|
||||||
if (lookup2)
|
if (lookup2)
|
||||||
return status_msg_inf_error_cid_taken;
|
return status_msg_inf_error_cid_taken;
|
||||||
|
|
||||||
@@ -560,8 +568,8 @@ static void hub_event_dispatcher(void* callback_data, struct event_data* message
|
|||||||
|
|
||||||
case UHUB_EVENT_USER_QUIT:
|
case UHUB_EVENT_USER_QUIT:
|
||||||
{
|
{
|
||||||
uman_remove(hub, user);
|
uman_remove(hub->users, user);
|
||||||
uman_send_quit_message(hub, user);
|
uman_send_quit_message(hub, hub->users, user);
|
||||||
on_logout_user(hub, user);
|
on_logout_user(hub, user);
|
||||||
hub_schedule_destroy_user(hub, user);
|
hub_schedule_destroy_user(hub, user);
|
||||||
break;
|
break;
|
||||||
@@ -578,7 +586,7 @@ static void hub_event_dispatcher(void* callback_data, struct event_data* message
|
|||||||
struct hub_user* u = (struct hub_user*) list_get_first(hub->users->list);
|
struct hub_user* u = (struct hub_user*) list_get_first(hub->users->list);
|
||||||
while (u)
|
while (u)
|
||||||
{
|
{
|
||||||
uman_remove(hub, u);
|
uman_remove(hub->users, u);
|
||||||
user_destroy(u);
|
user_destroy(u);
|
||||||
u = (struct hub_user*) list_get_first(hub->users->list);
|
u = (struct hub_user*) list_get_first(hub->users->list);
|
||||||
}
|
}
|
||||||
@@ -592,6 +600,31 @@ static void hub_event_dispatcher(void* callback_data, struct event_data* message
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void hub_update_stats(struct hub_info* hub)
|
||||||
|
{
|
||||||
|
const int factor = TIMEOUT_STATS;
|
||||||
|
struct net_statistics* total;
|
||||||
|
struct net_statistics* intermediate;
|
||||||
|
net_stats_get(&intermediate, &total);
|
||||||
|
|
||||||
|
hub->stats.net_tx = (intermediate->tx / factor);
|
||||||
|
hub->stats.net_rx = (intermediate->rx / factor);
|
||||||
|
hub->stats.net_tx_peak = MAX(hub->stats.net_tx, hub->stats.net_tx_peak);
|
||||||
|
hub->stats.net_rx_peak = MAX(hub->stats.net_rx, hub->stats.net_rx_peak);
|
||||||
|
hub->stats.net_tx_total = total->tx;
|
||||||
|
hub->stats.net_rx_total = total->rx;
|
||||||
|
|
||||||
|
net_stats_reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void hub_timer_statistics(struct timeout_evt* t)
|
||||||
|
{
|
||||||
|
struct hub_info* hub = (struct hub_info*) t->ptr;
|
||||||
|
hub_update_stats(hub);
|
||||||
|
timeout_queue_reschedule(net_backend_get_timeout_queue(), hub->stats.timeout, TIMEOUT_STATS);
|
||||||
|
}
|
||||||
|
|
||||||
static struct net_connection* start_listening_socket(const char* bind_addr, uint16_t port, int backlog, struct hub_info* hub)
|
static struct net_connection* start_listening_socket(const char* bind_addr, uint16_t port, int backlog, struct hub_info* hub)
|
||||||
{
|
{
|
||||||
struct net_connection* server;
|
struct net_connection* server;
|
||||||
@@ -698,41 +731,25 @@ static int load_ssl_certificates(struct hub_info* hub, struct hub_config* config
|
|||||||
{
|
{
|
||||||
if (config->tls_enable)
|
if (config->tls_enable)
|
||||||
{
|
{
|
||||||
hub->ssl_method = (SSL_METHOD*) SSLv23_method(); /* TLSv1_method() */
|
hub->ctx = net_ssl_context_create();
|
||||||
hub->ssl_ctx = SSL_CTX_new(hub->ssl_method);
|
if (ssl_load_certificate(hub->ctx, config->tls_certificate) &&
|
||||||
|
ssl_load_private_key(hub->ctx, config->tls_private_key) &&
|
||||||
/* Disable SSLv2 */
|
ssl_check_private_key(hub->ctx))
|
||||||
SSL_CTX_set_options(hub->ssl_ctx, SSL_OP_NO_SSLv2);
|
|
||||||
SSL_CTX_set_quiet_shutdown(hub->ssl_ctx, 1);
|
|
||||||
|
|
||||||
if (SSL_CTX_use_certificate_file(hub->ssl_ctx, config->tls_certificate, SSL_FILETYPE_PEM) < 0)
|
|
||||||
{
|
{
|
||||||
LOG_ERROR("SSL_CTX_use_certificate_file: %s", ERR_error_string(ERR_get_error(), NULL));
|
LOG_INFO("Enabling TLS (%s), using certificate: %s, private key: %s", net_ssl_get_provider(), config->tls_certificate, config->tls_private_key);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SSL_CTX_use_PrivateKey_file(hub->ssl_ctx, config->tls_private_key, SSL_FILETYPE_PEM) < 0)
|
|
||||||
{
|
|
||||||
LOG_ERROR("SSL_CTX_use_PrivateKey_file: %s", ERR_error_string(ERR_get_error(), NULL));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SSL_CTX_check_private_key(hub->ssl_ctx) != 1)
|
|
||||||
{
|
|
||||||
LOG_FATAL("SSL_CTX_check_private_key: Private key does not match the certificate public key: %s", ERR_error_string(ERR_get_error(), NULL));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
LOG_INFO("Enabling TLS, using certificate: %s, private key: %s", config->tls_certificate, config->tls_private_key);
|
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unload_ssl_certificates(struct hub_info* hub)
|
static void unload_ssl_certificates(struct hub_info* hub)
|
||||||
{
|
{
|
||||||
if (hub->ssl_ctx)
|
if (hub->ctx)
|
||||||
{
|
net_ssl_context_destroy(hub->ctx);
|
||||||
SSL_CTX_free(hub->ssl_ctx);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* SSL_SUPPORT */
|
||||||
|
|
||||||
struct hub_info* hub_start_service(struct hub_config* config)
|
struct hub_info* hub_start_service(struct hub_config* config)
|
||||||
{
|
{
|
||||||
@@ -773,7 +790,8 @@ struct hub_info* hub_start_service(struct hub_config* config)
|
|||||||
hub->config = config;
|
hub->config = config;
|
||||||
hub->users = NULL;
|
hub->users = NULL;
|
||||||
|
|
||||||
if (uman_init(hub) == -1)
|
hub->users = uman_init();
|
||||||
|
if (!hub->users)
|
||||||
{
|
{
|
||||||
net_con_close(hub->server);
|
net_con_close(hub->server);
|
||||||
hub_free(hub);
|
hub_free(hub);
|
||||||
@@ -783,7 +801,7 @@ struct hub_info* hub_start_service(struct hub_config* config)
|
|||||||
if (event_queue_initialize(&hub->queue, hub_event_dispatcher, (void*) hub) == -1)
|
if (event_queue_initialize(&hub->queue, hub_event_dispatcher, (void*) hub) == -1)
|
||||||
{
|
{
|
||||||
net_con_close(hub->server);
|
net_con_close(hub->server);
|
||||||
uman_shutdown(hub);
|
uman_shutdown(hub->users);
|
||||||
hub_free(hub);
|
hub_free(hub);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -795,7 +813,7 @@ struct hub_info* hub_start_service(struct hub_config* config)
|
|||||||
net_con_close(hub->server);
|
net_con_close(hub->server);
|
||||||
hub_free(hub->recvbuf);
|
hub_free(hub->recvbuf);
|
||||||
hub_free(hub->sendbuf);
|
hub_free(hub->sendbuf);
|
||||||
uman_shutdown(hub);
|
uman_shutdown(hub->users);
|
||||||
hub_free(hub);
|
hub_free(hub);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -807,6 +825,13 @@ struct hub_info* hub_start_service(struct hub_config* config)
|
|||||||
|
|
||||||
g_hub = hub;
|
g_hub = hub;
|
||||||
|
|
||||||
|
if (net_backend_get_timeout_queue())
|
||||||
|
{
|
||||||
|
hub->stats.timeout = hub_malloc_zero(sizeof(struct timeout_evt));
|
||||||
|
timeout_evt_initialize(hub->stats.timeout, hub_timer_statistics, hub);
|
||||||
|
timeout_queue_insert(net_backend_get_timeout_queue(), hub->stats.timeout, TIMEOUT_STATS);
|
||||||
|
}
|
||||||
|
|
||||||
// Start the hub command sub-system
|
// Start the hub command sub-system
|
||||||
hub->commands = command_initialize(hub);
|
hub->commands = command_initialize(hub);
|
||||||
return hub;
|
return hub;
|
||||||
@@ -817,6 +842,12 @@ void hub_shutdown_service(struct hub_info* hub)
|
|||||||
{
|
{
|
||||||
LOG_DEBUG("hub_shutdown_service()");
|
LOG_DEBUG("hub_shutdown_service()");
|
||||||
|
|
||||||
|
if (net_backend_get_timeout_queue())
|
||||||
|
{
|
||||||
|
timeout_queue_remove(net_backend_get_timeout_queue(), hub->stats.timeout);
|
||||||
|
hub_free(hub->stats.timeout);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef SSL_SUPPORT
|
#ifdef SSL_SUPPORT
|
||||||
unload_ssl_certificates(hub);
|
unload_ssl_certificates(hub);
|
||||||
#endif
|
#endif
|
||||||
@@ -824,7 +855,7 @@ void hub_shutdown_service(struct hub_info* hub)
|
|||||||
event_queue_shutdown(hub->queue);
|
event_queue_shutdown(hub->queue);
|
||||||
net_con_close(hub->server);
|
net_con_close(hub->server);
|
||||||
server_alt_port_stop(hub);
|
server_alt_port_stop(hub);
|
||||||
uman_shutdown(hub);
|
uman_shutdown(hub->users);
|
||||||
hub->status = hub_status_stopped;
|
hub->status = hub_status_stopped;
|
||||||
hub_free(hub->sendbuf);
|
hub_free(hub->sendbuf);
|
||||||
hub_free(hub->recvbuf);
|
hub_free(hub->recvbuf);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2011, Jan Vidar Krey
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -81,6 +81,7 @@ struct hub_stats
|
|||||||
size_t net_rx_peak;
|
size_t net_rx_peak;
|
||||||
size_t net_tx_total;
|
size_t net_tx_total;
|
||||||
size_t net_rx_total;
|
size_t net_rx_total;
|
||||||
|
struct timeout_evt* timeout; /**<< "Timeout handler for statistics" */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hub_logout_info
|
struct hub_logout_info
|
||||||
@@ -115,8 +116,7 @@ struct hub_info
|
|||||||
struct uhub_plugins* plugins; /* Plug-ins loaded for this hub instance. */
|
struct uhub_plugins* plugins; /* Plug-ins loaded for this hub instance. */
|
||||||
|
|
||||||
#ifdef SSL_SUPPORT
|
#ifdef SSL_SUPPORT
|
||||||
SSL_METHOD* ssl_method;
|
struct ssl_context_handle* ctx;
|
||||||
SSL_CTX* ssl_ctx;
|
|
||||||
#endif /* SSL_SUPPORT */
|
#endif /* SSL_SUPPORT */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -24,12 +24,12 @@
|
|||||||
void on_login_success(struct hub_info* hub, struct hub_user* u)
|
void on_login_success(struct hub_info* hub, struct hub_user* u)
|
||||||
{
|
{
|
||||||
/* Send user list of all existing users */
|
/* Send user list of all existing users */
|
||||||
if (!uman_send_user_list(hub, u))
|
if (!uman_send_user_list(hub, hub->users, u))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Mark as being in the normal state, and add user to the user list */
|
/* Mark as being in the normal state, and add user to the user list */
|
||||||
user_set_state(u, state_normal);
|
user_set_state(u, state_normal);
|
||||||
uman_add(hub, u);
|
uman_add(hub->users, u);
|
||||||
|
|
||||||
/* Announce new user to all connected users */
|
/* Announce new user to all connected users */
|
||||||
if (user_is_logged_in(u))
|
if (user_is_logged_in(u))
|
||||||
|
|||||||
@@ -325,8 +325,8 @@ static int check_nick(struct hub_info* hub, struct hub_user* user, struct adc_me
|
|||||||
|
|
||||||
static int check_logged_in(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
|
static int check_logged_in(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
|
||||||
{
|
{
|
||||||
struct hub_user* lookup1 = uman_get_user_by_nick(hub, user->id.nick);
|
struct hub_user* lookup1 = uman_get_user_by_nick(hub->users, user->id.nick);
|
||||||
struct hub_user* lookup2 = uman_get_user_by_cid(hub, user->id.cid);
|
struct hub_user* lookup2 = uman_get_user_by_cid(hub->users, user->id.cid);
|
||||||
|
|
||||||
if (lookup1 == user)
|
if (lookup1 == user)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -18,7 +18,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "uhub.h"
|
#include "uhub.h"
|
||||||
#include "hubio.h"
|
|
||||||
|
|
||||||
#ifdef DEBUG_SENDQ
|
#ifdef DEBUG_SENDQ
|
||||||
static void debug_msg(const char* prefix, struct adc_message* msg)
|
static void debug_msg(const char* prefix, struct adc_message* msg)
|
||||||
@@ -35,13 +34,13 @@ static void debug_msg(const char* prefix, struct adc_message* msg)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct hub_recvq* hub_recvq_create()
|
struct ioq_recv* ioq_recv_create()
|
||||||
{
|
{
|
||||||
struct hub_recvq* q = hub_malloc_zero(sizeof(struct hub_recvq));
|
struct ioq_recv* q = hub_malloc_zero(sizeof(struct ioq_recv));
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hub_recvq_destroy(struct hub_recvq* q)
|
void ioq_recv_destroy(struct ioq_recv* q)
|
||||||
{
|
{
|
||||||
if (q)
|
if (q)
|
||||||
{
|
{
|
||||||
@@ -50,7 +49,7 @@ void hub_recvq_destroy(struct hub_recvq* q)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t hub_recvq_get(struct hub_recvq* q, void* buf, size_t bufsize)
|
size_t ioq_recv_get(struct ioq_recv* q, void* buf, size_t bufsize)
|
||||||
{
|
{
|
||||||
uhub_assert(bufsize >= q->size);
|
uhub_assert(bufsize >= q->size);
|
||||||
if (q->size)
|
if (q->size)
|
||||||
@@ -65,7 +64,7 @@ size_t hub_recvq_get(struct hub_recvq* q, void* buf, size_t bufsize)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t hub_recvq_set(struct hub_recvq* q, void* buf, size_t bufsize)
|
size_t ioq_recv_set(struct ioq_recv* q, void* buf, size_t bufsize)
|
||||||
{
|
{
|
||||||
if (q->buf)
|
if (q->buf)
|
||||||
{
|
{
|
||||||
@@ -89,9 +88,9 @@ size_t hub_recvq_set(struct hub_recvq* q, void* buf, size_t bufsize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct hub_sendq* hub_sendq_create()
|
struct ioq_send* ioq_send_create()
|
||||||
{
|
{
|
||||||
struct hub_sendq* q = hub_malloc_zero(sizeof(struct hub_sendq));
|
struct ioq_send* q = hub_malloc_zero(sizeof(struct ioq_send));
|
||||||
if (!q)
|
if (!q)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -110,7 +109,7 @@ static void clear_send_queue_callback(void* ptr)
|
|||||||
adc_msg_free((struct adc_message*) ptr);
|
adc_msg_free((struct adc_message*) ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hub_sendq_destroy(struct hub_sendq* q)
|
void ioq_send_destroy(struct ioq_send* q)
|
||||||
{
|
{
|
||||||
if (q)
|
if (q)
|
||||||
{
|
{
|
||||||
@@ -120,21 +119,21 @@ void hub_sendq_destroy(struct hub_sendq* q)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hub_sendq_add(struct hub_sendq* q, struct adc_message* msg_)
|
void ioq_send_add(struct ioq_send* q, struct adc_message* msg_)
|
||||||
{
|
{
|
||||||
struct adc_message* msg = adc_msg_incref(msg_);
|
struct adc_message* msg = adc_msg_incref(msg_);
|
||||||
#ifdef DEBUG_SENDQ
|
#ifdef DEBUG_SENDQ
|
||||||
debug_msg("hub_sendq_add", msg);
|
debug_msg("ioq_send_add", msg);
|
||||||
#endif
|
#endif
|
||||||
uhub_assert(msg->cache && *msg->cache);
|
uhub_assert(msg->cache && *msg->cache);
|
||||||
list_append(q->queue, msg);
|
list_append(q->queue, msg);
|
||||||
q->size += msg->length;
|
q->size += msg->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hub_sendq_remove(struct hub_sendq* q, struct adc_message* msg)
|
void ioq_send_remove(struct ioq_send* q, struct adc_message* msg)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_SENDQ
|
#ifdef DEBUG_SENDQ
|
||||||
debug_msg("hub_sendq_remove", msg);
|
debug_msg("ioq_send_remove", msg);
|
||||||
#endif
|
#endif
|
||||||
list_remove(q->queue, msg);
|
list_remove(q->queue, msg);
|
||||||
q->size -= msg->length;
|
q->size -= msg->length;
|
||||||
@@ -142,13 +141,13 @@ void hub_sendq_remove(struct hub_sendq* q, struct adc_message* msg)
|
|||||||
q->offset = 0;
|
q->offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hub_sendq_send(struct hub_sendq* q, struct hub_user* user)
|
int ioq_send_send(struct ioq_send* q, struct net_connection* con)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct adc_message* msg = list_get_first(q->queue);
|
struct adc_message* msg = list_get_first(q->queue);
|
||||||
if (!msg) return 0;
|
if (!msg) return 0;
|
||||||
uhub_assert(msg->cache && *msg->cache);
|
uhub_assert(msg->cache && *msg->cache);
|
||||||
ret = net_con_send(user->connection, msg->cache + q->offset, msg->length - q->offset);
|
ret = net_con_send(con, msg->cache + q->offset, msg->length - q->offset);
|
||||||
|
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
{
|
{
|
||||||
@@ -156,18 +155,18 @@ int hub_sendq_send(struct hub_sendq* q, struct hub_user* user)
|
|||||||
if (msg->length - q->offset > 0)
|
if (msg->length - q->offset > 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
hub_sendq_remove(q, msg);
|
ioq_send_remove(q, msg);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hub_sendq_is_empty(struct hub_sendq* q)
|
int ioq_send_is_empty(struct ioq_send* q)
|
||||||
{
|
{
|
||||||
return (q->size - q->offset) == 0;
|
return (q->size - q->offset) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t hub_sendq_get_bytes(struct hub_sendq* q)
|
size_t ioq_send_get_bytes(struct ioq_send* q)
|
||||||
{
|
{
|
||||||
return q->size - q->offset;
|
return q->size - q->offset;
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -17,25 +17,25 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef HAVE_UHUB_HUB_IO_H
|
#ifndef HAVE_UHUB_IO_QUEUE_H
|
||||||
#define HAVE_UHUB_HUB_IO_H
|
#define HAVE_UHUB_IO_QUEUE_H
|
||||||
|
|
||||||
struct adc_message;
|
struct adc_message;
|
||||||
struct linked_list;
|
struct linked_list;
|
||||||
typedef int (*hub_recvq_write)(void* desc, const void* buf, size_t len);
|
typedef int (*ioq_write)(void* desc, const void* buf, size_t len);
|
||||||
typedef int (*hub_recvq_read)(void* desc, void* buf, size_t len);
|
typedef int (*ioq_read)(void* desc, void* buf, size_t len);
|
||||||
|
|
||||||
struct hub_sendq
|
struct ioq_send
|
||||||
{
|
{
|
||||||
size_t size; /** Size of send queue (in bytes, not messages) */
|
size_t size; /** Size of send queue (in bytes, not messages) */
|
||||||
size_t offset; /** Queue byte offset in the first message. Should be 0 unless a partial write. */
|
size_t offset; /** Queue byte offset in the first message. Should be 0 unless a partial write. */
|
||||||
#ifdef SSL_SUPPORT
|
#ifdef SSL_SUPPORT
|
||||||
size_t last_send; /** When using SSL, one have to send the exact same buffer and length if a write cannot complete. */
|
size_t last_send; /** When using SSL, one have to send the exact same buffer and length if a write cannot complete. */
|
||||||
#endif
|
#endif
|
||||||
struct linked_list* queue; /** List of queued messages */
|
struct linked_list* queue; /** List of queued messages (struct adc_message) */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hub_recvq
|
struct ioq_recv
|
||||||
{
|
{
|
||||||
char* buf;
|
char* buf;
|
||||||
size_t size;
|
size_t size;
|
||||||
@@ -44,63 +44,63 @@ struct hub_recvq
|
|||||||
/**
|
/**
|
||||||
* Create a send queue
|
* Create a send queue
|
||||||
*/
|
*/
|
||||||
extern struct hub_sendq* hub_sendq_create();
|
extern struct ioq_send* ioq_send_create();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy a send queue, and delete any queued messages.
|
* Destroy a send queue, and delete any queued messages.
|
||||||
*/
|
*/
|
||||||
extern void hub_sendq_destroy(struct hub_sendq*);
|
extern void ioq_send_destroy(struct ioq_send*);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a message to the send queue.
|
* Add a message to the send queue.
|
||||||
*/
|
*/
|
||||||
extern void hub_sendq_add(struct hub_sendq*, struct adc_message* msg);
|
extern void ioq_send_add(struct ioq_send*, struct adc_message* msg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process the send queue, and send as many messages as possible.
|
* Process the send queue, and send as many messages as possible.
|
||||||
* @returns -1 on error, 0 if unable to send more, 1 if more can be sent.
|
* @returns -1 on error, 0 if unable to send more, 1 if more can be sent.
|
||||||
*/
|
*/
|
||||||
extern int hub_sendq_send(struct hub_sendq*, struct hub_user*);
|
extern int ioq_send_send(struct ioq_send*, struct net_connection* con);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns 1 if send queue is empty, 0 otherwise.
|
* @returns 1 if send queue is empty, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
extern int hub_sendq_is_empty(struct hub_sendq*);
|
extern int ioq_send_is_empty(struct ioq_send*);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns the number of bytes remaining to be sent in the queue.
|
* @returns the number of bytes remaining to be sent in the queue.
|
||||||
*/
|
*/
|
||||||
extern size_t hub_sendq_get_bytes(struct hub_sendq*);
|
extern size_t ioq_send_get_bytes(struct ioq_send*);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a receive queue.
|
* Create a receive queue.
|
||||||
*/
|
*/
|
||||||
extern struct hub_recvq* hub_recvq_create();
|
extern struct ioq_recv* ioq_recv_create();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy a receive queue.
|
* Destroy a receive queue.
|
||||||
*/
|
*/
|
||||||
extern void hub_recvq_destroy(struct hub_recvq*);
|
extern void ioq_recv_destroy(struct ioq_recv*);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the buffer, copies it into buf and deallocates it.
|
* Gets the buffer, copies it into buf and deallocates it.
|
||||||
* NOTE: bufsize *MUST* be larger than the buffer, otherwise it asserts.
|
* NOTE: bufsize *MUST* be larger than the buffer, otherwise it asserts.
|
||||||
* @return the number of bytes copied into buf.
|
* @return the number of bytes copied into buf.
|
||||||
*/
|
*/
|
||||||
extern size_t hub_recvq_get(struct hub_recvq*, void* buf, size_t bufsize);
|
extern size_t ioq_recv_get(struct ioq_recv*, void* buf, size_t bufsize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the buffer
|
* Sets the buffer
|
||||||
*/
|
*/
|
||||||
extern size_t hub_recvq_set(struct hub_recvq*, void* buf, size_t bufsize);
|
extern size_t ioq_recv_set(struct ioq_recv*, void* buf, size_t bufsize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return 1 if size is zero, 0 otherwise.
|
* @return 1 if size is zero, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
extern int hub_recvq_is_empty(struct hub_recvq* buf);
|
extern int ioq_recv_is_empty(struct ioq_recv* buf);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* HAVE_UHUB_HUB_IO_H */
|
#endif /* HAVE_UHUB_IO_QUEUE_H */
|
||||||
@@ -136,7 +136,13 @@ int main_loop()
|
|||||||
{
|
{
|
||||||
hub = hub_start_service(&configuration);
|
hub = hub_start_service(&configuration);
|
||||||
if (!hub)
|
if (!hub)
|
||||||
|
{
|
||||||
|
acl_shutdown(&acl);
|
||||||
|
free_config(&configuration);
|
||||||
|
net_destroy();
|
||||||
|
hub_log_shutdown();
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
#if !defined(WIN32)
|
#if !defined(WIN32)
|
||||||
setup_signal_handlers(hub);
|
setup_signal_handlers(hub);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -18,17 +18,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <uhub.h>
|
#include <uhub.h>
|
||||||
#include "hubio.h"
|
#include "ioqueue.h"
|
||||||
#include "probe.h"
|
#include "probe.h"
|
||||||
|
|
||||||
/* FIXME: This should not be needed! */
|
|
||||||
extern struct hub_info* g_hub;
|
|
||||||
|
|
||||||
int handle_net_read(struct hub_user* user)
|
int handle_net_read(struct hub_user* user)
|
||||||
{
|
{
|
||||||
static char buf[MAX_RECV_BUF];
|
static char buf[MAX_RECV_BUF];
|
||||||
struct hub_recvq* q = user->recv_queue;
|
struct ioq_recv* q = user->recv_queue;
|
||||||
size_t buf_size = hub_recvq_get(q, buf, MAX_RECV_BUF);
|
size_t buf_size = ioq_recv_get(q, buf, MAX_RECV_BUF);
|
||||||
ssize_t size;
|
ssize_t size;
|
||||||
|
|
||||||
if (user_flag_get(user, flag_maxbuf))
|
if (user_flag_get(user, flag_maxbuf))
|
||||||
@@ -58,7 +55,7 @@ int handle_net_read(struct hub_user* user)
|
|||||||
|
|
||||||
while ((pos = memchr(start, '\n', remaining)))
|
while ((pos = memchr(start, '\n', remaining)))
|
||||||
{
|
{
|
||||||
lastPos = pos;
|
lastPos = pos+1;
|
||||||
pos[0] = '\0';
|
pos[0] = '\0';
|
||||||
|
|
||||||
#ifdef DEBUG_SENDQ
|
#ifdef DEBUG_SENDQ
|
||||||
@@ -71,9 +68,9 @@ int handle_net_read(struct hub_user* user)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (((pos - start) > 0) && g_hub->config->max_recv_buffer > (pos - start))
|
if (((pos - start) > 0) && user->hub->config->max_recv_buffer > (pos - start))
|
||||||
{
|
{
|
||||||
if (hub_handle_message(g_hub, user, start, (pos - start)) == -1)
|
if (hub_handle_message(user->hub, user, start, (pos - start)) == -1)
|
||||||
{
|
{
|
||||||
return quit_protocol_error;
|
return quit_protocol_error;
|
||||||
}
|
}
|
||||||
@@ -88,20 +85,20 @@ int handle_net_read(struct hub_user* user)
|
|||||||
|
|
||||||
if (lastPos || remaining)
|
if (lastPos || remaining)
|
||||||
{
|
{
|
||||||
if (remaining < (size_t) g_hub->config->max_recv_buffer)
|
if (remaining < (size_t) user->hub->config->max_recv_buffer)
|
||||||
{
|
{
|
||||||
hub_recvq_set(q, lastPos ? lastPos : buf, remaining);
|
ioq_recv_set(q, lastPos ? lastPos : buf, remaining);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hub_recvq_set(q, 0, 0);
|
ioq_recv_set(q, 0, 0);
|
||||||
user_flag_set(user, flag_maxbuf);
|
user_flag_set(user, flag_maxbuf);
|
||||||
LOG_WARN("Received message past max_recv_buffer, dropping message.");
|
LOG_WARN("Received message past max_recv_buffer, dropping message.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hub_recvq_set(q, 0, 0);
|
ioq_recv_set(q, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -110,9 +107,9 @@ int handle_net_read(struct hub_user* user)
|
|||||||
int handle_net_write(struct hub_user* user)
|
int handle_net_write(struct hub_user* user)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
while (hub_sendq_get_bytes(user->send_queue))
|
while (ioq_send_get_bytes(user->send_queue))
|
||||||
{
|
{
|
||||||
ret = hub_sendq_send(user->send_queue, user);
|
ret = ioq_send_send(user->send_queue, user->connection);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -120,7 +117,7 @@ int handle_net_write(struct hub_user* user)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return quit_socket_error;
|
return quit_socket_error;
|
||||||
|
|
||||||
if (hub_sendq_get_bytes(user->send_queue))
|
if (ioq_send_get_bytes(user->send_queue))
|
||||||
{
|
{
|
||||||
user_net_io_want_write(user);
|
user_net_io_want_write(user);
|
||||||
}
|
}
|
||||||
@@ -144,7 +141,7 @@ void net_event(struct net_connection* con, int event, void *arg)
|
|||||||
{
|
{
|
||||||
if (user_is_connecting(user))
|
if (user_is_connecting(user))
|
||||||
{
|
{
|
||||||
hub_disconnect_user(g_hub, user, quit_timeout);
|
hub_disconnect_user(user->hub, user, quit_timeout);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -154,7 +151,7 @@ void net_event(struct net_connection* con, int event, void *arg)
|
|||||||
flag_close = handle_net_read(user);
|
flag_close = handle_net_read(user);
|
||||||
if (flag_close)
|
if (flag_close)
|
||||||
{
|
{
|
||||||
hub_disconnect_user(g_hub, user, flag_close);
|
hub_disconnect_user(user->hub, user, flag_close);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -164,7 +161,7 @@ void net_event(struct net_connection* con, int event, void *arg)
|
|||||||
flag_close = handle_net_write(user);
|
flag_close = handle_net_write(user);
|
||||||
if (flag_close)
|
if (flag_close)
|
||||||
{
|
{
|
||||||
hub_disconnect_user(g_hub, user, flag_close);
|
hub_disconnect_user(user->hub, user, flag_close);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,21 +76,20 @@ static void probe_net_event(struct net_connection* con, int events, void *arg)
|
|||||||
probe_recvbuf[0] == 22 &&
|
probe_recvbuf[0] == 22 &&
|
||||||
probe_recvbuf[1] == 3 && /* protocol major version */
|
probe_recvbuf[1] == 3 && /* protocol major version */
|
||||||
probe_recvbuf[5] == 1 && /* message type */
|
probe_recvbuf[5] == 1 && /* message type */
|
||||||
probe_recvbuf[9] == probe_recvbuf[1] &&
|
probe_recvbuf[9] == probe_recvbuf[1])
|
||||||
probe_recvbuf[10] == probe_recvbuf[2])
|
|
||||||
{
|
{
|
||||||
if (probe->hub->config->tls_enable)
|
if (probe->hub->config->tls_enable)
|
||||||
{
|
{
|
||||||
LOG_TRACE("Probed TLS %d.%d connection", (int) probe_recvbuf[1], (int) probe_recvbuf[2]);
|
LOG_TRACE("Probed TLS %d.%d connection", (int) probe_recvbuf[9], (int) probe_recvbuf[10]);
|
||||||
if (user_create(probe->hub, probe->connection, &probe->addr))
|
if (user_create(probe->hub, probe->connection, &probe->addr))
|
||||||
{
|
{
|
||||||
probe->connection = 0;
|
probe->connection = 0;
|
||||||
}
|
}
|
||||||
net_con_ssl_handshake(con, net_con_ssl_mode_server, probe->hub->ssl_ctx);
|
net_con_ssl_handshake(con, net_con_ssl_mode_server, probe->hub->ctx);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG_TRACE("Probed TLS %d.%d connection. TLS disabled in hub.", (int) probe_recvbuf[1], (int) probe_recvbuf[2]);
|
LOG_TRACE("Probed TLS %d.%d connection. TLS disabled in hub.", (int) probe_recvbuf[9], (int) probe_recvbuf[10]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ int route_message(struct hub_info* hub, struct hub_user* u, struct adc_message*
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'D':
|
case 'D':
|
||||||
target = uman_get_user_by_sid(hub, msg->target);
|
target = uman_get_user_by_sid(hub->users, msg->target);
|
||||||
if (target)
|
if (target)
|
||||||
{
|
{
|
||||||
route_to_user(hub, target, msg);
|
route_to_user(hub, target, msg);
|
||||||
@@ -38,7 +38,7 @@ int route_message(struct hub_info* hub, struct hub_user* u, struct adc_message*
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'E':
|
case 'E':
|
||||||
target = uman_get_user_by_sid(hub, msg->target);
|
target = uman_get_user_by_sid(hub->users, msg->target);
|
||||||
if (target)
|
if (target)
|
||||||
{
|
{
|
||||||
route_to_user(hub, target, msg);
|
route_to_user(hub, target, msg);
|
||||||
@@ -108,17 +108,17 @@ int route_to_user(struct hub_info* hub, struct hub_user* user, struct adc_messag
|
|||||||
|
|
||||||
uhub_assert(msg->cache && *msg->cache);
|
uhub_assert(msg->cache && *msg->cache);
|
||||||
|
|
||||||
if (hub_sendq_is_empty(user->send_queue) && !user_flag_get(user, flag_pipeline))
|
if (ioq_send_is_empty(user->send_queue) && !user_flag_get(user, flag_pipeline))
|
||||||
{
|
{
|
||||||
/* Perform oportunistic write */
|
/* Perform oportunistic write */
|
||||||
hub_sendq_add(user->send_queue, msg);
|
ioq_send_add(user->send_queue, msg);
|
||||||
handle_net_write(user);
|
handle_net_write(user);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (check_send_queue(hub, user, msg) >= 0)
|
if (check_send_queue(hub, user, msg) >= 0)
|
||||||
{
|
{
|
||||||
hub_sendq_add(user->send_queue, msg);
|
ioq_send_add(user->send_queue, msg);
|
||||||
if (!user_flag_get(user, flag_pipeline))
|
if (!user_flag_get(user, flag_pipeline))
|
||||||
user_net_io_want_write(user);
|
user_net_io_want_write(user);
|
||||||
}
|
}
|
||||||
@@ -128,7 +128,7 @@ int route_to_user(struct hub_info* hub, struct hub_user* user, struct adc_messag
|
|||||||
|
|
||||||
int route_flush_pipeline(struct hub_info* hub, struct hub_user* u)
|
int route_flush_pipeline(struct hub_info* hub, struct hub_user* u)
|
||||||
{
|
{
|
||||||
if (hub_sendq_is_empty(u->send_queue))
|
if (ioq_send_is_empty(u->send_queue))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
handle_net_write(u);
|
handle_net_write(u);
|
||||||
|
|||||||
@@ -46,8 +46,8 @@ struct hub_user* user_create(struct hub_info* hub, struct net_connection* con, s
|
|||||||
if (user == NULL)
|
if (user == NULL)
|
||||||
return NULL; /* OOM */
|
return NULL; /* OOM */
|
||||||
|
|
||||||
user->send_queue = hub_sendq_create();
|
user->send_queue = ioq_send_create();
|
||||||
user->recv_queue = hub_recvq_create();
|
user->recv_queue = ioq_recv_create();
|
||||||
|
|
||||||
user->connection = con;
|
user->connection = con;
|
||||||
net_con_reinitialize(user->connection, net_event, user, NET_EVENT_READ);
|
net_con_reinitialize(user->connection, net_event, user, NET_EVENT_READ);
|
||||||
@@ -60,6 +60,8 @@ struct hub_user* user_create(struct hub_info* hub, struct net_connection* con, s
|
|||||||
flood_control_reset(&user->flood_search);
|
flood_control_reset(&user->flood_search);
|
||||||
flood_control_reset(&user->flood_update);
|
flood_control_reset(&user->flood_update);
|
||||||
flood_control_reset(&user->flood_extras);
|
flood_control_reset(&user->flood_extras);
|
||||||
|
|
||||||
|
user->hub = hub;
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,8 +70,8 @@ void user_destroy(struct hub_user* user)
|
|||||||
{
|
{
|
||||||
LOG_TRACE("user_destroy(), user=%p", user);
|
LOG_TRACE("user_destroy(), user=%p", user);
|
||||||
|
|
||||||
hub_recvq_destroy(user->recv_queue);
|
ioq_recv_destroy(user->recv_queue);
|
||||||
hub_sendq_destroy(user->send_queue);
|
ioq_send_destroy(user->send_queue);
|
||||||
|
|
||||||
if (user->connection)
|
if (user->connection)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -113,8 +113,8 @@ struct hub_user
|
|||||||
struct linked_list* feature_cast; /** Features supported by feature cast */
|
struct linked_list* feature_cast; /** Features supported by feature cast */
|
||||||
struct adc_message* info; /** ADC 'INF' message (broadcasted to everyone joining the hub) */
|
struct adc_message* info; /** ADC 'INF' message (broadcasted to everyone joining the hub) */
|
||||||
struct hub_info* hub; /** The hub instance this user belong to */
|
struct hub_info* hub; /** The hub instance this user belong to */
|
||||||
struct hub_recvq* recv_queue;
|
struct ioq_recv* recv_queue;
|
||||||
struct hub_sendq* send_queue;
|
struct ioq_send* send_queue;
|
||||||
struct net_connection* connection; /** Connection data */
|
struct net_connection* connection; /** Connection data */
|
||||||
struct hub_user_limits limits; /** Data used for limitation */
|
struct hub_user_limits limits; /** Data used for limitation */
|
||||||
enum user_quit_reason quit_reason; /** Quit reason (see user_quit_reason) */
|
enum user_quit_reason quit_reason; /** Quit reason (see user_quit_reason) */
|
||||||
|
|||||||
@@ -38,50 +38,12 @@ static void clear_user_list_callback(void* ptr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void uman_update_stats(struct hub_info* hub)
|
|
||||||
|
struct hub_user_manager* uman_init()
|
||||||
{
|
{
|
||||||
const int factor = TIMEOUT_STATS;
|
struct hub_user_manager* users = (struct hub_user_manager*) hub_malloc_zero(sizeof(struct hub_user_manager));
|
||||||
struct net_statistics* total;
|
|
||||||
struct net_statistics* intermediate;
|
|
||||||
net_stats_get(&intermediate, &total);
|
|
||||||
|
|
||||||
hub->stats.net_tx = (intermediate->tx / factor);
|
|
||||||
hub->stats.net_rx = (intermediate->rx / factor);
|
|
||||||
hub->stats.net_tx_peak = MAX(hub->stats.net_tx, hub->stats.net_tx_peak);
|
|
||||||
hub->stats.net_rx_peak = MAX(hub->stats.net_rx, hub->stats.net_rx_peak);
|
|
||||||
hub->stats.net_tx_total = total->tx;
|
|
||||||
hub->stats.net_rx_total = total->rx;
|
|
||||||
|
|
||||||
net_stats_reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void uman_print_stats(struct hub_info* hub)
|
|
||||||
{
|
|
||||||
LOG_INFO("Statistics users=" PRINTF_SIZE_T " (peak_users=" PRINTF_SIZE_T "), net_tx=%d KB/s, net_rx=%d KB/s (peak_tx=%d KB/s, peak_rx=%d KB/s)",
|
|
||||||
hub->users->count,
|
|
||||||
hub->users->count_peak,
|
|
||||||
(int) hub->stats.net_tx / 1024,
|
|
||||||
(int) hub->stats.net_rx / 1024,
|
|
||||||
(int) hub->stats.net_tx_peak / 1024,
|
|
||||||
(int) hub->stats.net_rx_peak / 1024);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void timer_statistics(struct timeout_evt* t)
|
|
||||||
{
|
|
||||||
struct hub_info* hub = (struct hub_info*) t->ptr;
|
|
||||||
uman_update_stats(hub);
|
|
||||||
timeout_queue_reschedule(net_backend_get_timeout_queue(), hub->users->timeout, TIMEOUT_STATS);
|
|
||||||
}
|
|
||||||
|
|
||||||
int uman_init(struct hub_info* hub)
|
|
||||||
{
|
|
||||||
struct hub_user_manager* users = NULL;
|
|
||||||
if (!hub)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
users = (struct hub_user_manager*) hub_malloc_zero(sizeof(struct hub_user_manager));
|
|
||||||
if (!users)
|
if (!users)
|
||||||
return -1;
|
return NULL;
|
||||||
|
|
||||||
users->list = list_create();
|
users->list = list_create();
|
||||||
users->sids = sid_pool_create(net_get_max_sockets());
|
users->sids = sid_pool_create(net_get_max_sockets());
|
||||||
@@ -90,143 +52,119 @@ int uman_init(struct hub_info* hub)
|
|||||||
{
|
{
|
||||||
list_destroy(users->list);
|
list_destroy(users->list);
|
||||||
hub_free(users);
|
hub_free(users);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return users;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int uman_shutdown(struct hub_user_manager* users)
|
||||||
|
{
|
||||||
|
if (!users)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
if (net_backend_get_timeout_queue())
|
if (users->list)
|
||||||
{
|
{
|
||||||
users->timeout = hub_malloc_zero(sizeof(struct timeout_evt));
|
list_clear(users->list, &clear_user_list_callback);
|
||||||
timeout_evt_initialize(users->timeout, timer_statistics, hub);
|
list_destroy(users->list);
|
||||||
timeout_queue_insert(net_backend_get_timeout_queue(), users->timeout, TIMEOUT_STATS);
|
|
||||||
}
|
}
|
||||||
|
sid_pool_destroy(users->sids);
|
||||||
|
|
||||||
hub->users = users;
|
hub_free(users);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int uman_shutdown(struct hub_info* hub)
|
int uman_add(struct hub_user_manager* users, struct hub_user* user)
|
||||||
{
|
{
|
||||||
if (!hub || !hub->users)
|
if (!users || !user)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (net_backend_get_timeout_queue())
|
list_append(users->list, user);
|
||||||
{
|
users->count++;
|
||||||
timeout_queue_remove(net_backend_get_timeout_queue(), hub->users->timeout);
|
users->count_peak = MAX(users->count, users->count_peak);
|
||||||
hub_free(hub->users->timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hub->users->list)
|
|
||||||
{
|
|
||||||
list_clear(hub->users->list, &clear_user_list_callback);
|
|
||||||
list_destroy(hub->users->list);
|
|
||||||
}
|
|
||||||
sid_pool_destroy(hub->users->sids);
|
|
||||||
hub_free(hub->users);
|
|
||||||
hub->users = 0;
|
|
||||||
|
|
||||||
|
|
||||||
|
users->shared_size += user->limits.shared_size;
|
||||||
|
users->shared_files += user->limits.shared_files;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int uman_remove(struct hub_user_manager* users, struct hub_user* user)
|
||||||
int uman_add(struct hub_info* hub, struct hub_user* user)
|
|
||||||
{
|
{
|
||||||
if (!hub || !user)
|
if (!users || !user)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (user->hub)
|
list_remove(users->list, user);
|
||||||
return -1;
|
|
||||||
|
|
||||||
list_append(hub->users->list, user);
|
if (users->count > 0)
|
||||||
hub->users->count++;
|
|
||||||
hub->users->count_peak = MAX(hub->users->count, hub->users->count_peak);
|
|
||||||
|
|
||||||
hub->users->shared_size += user->limits.shared_size;
|
|
||||||
hub->users->shared_files += user->limits.shared_files;
|
|
||||||
|
|
||||||
user->hub = hub;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int uman_remove(struct hub_info* hub, struct hub_user* user)
|
|
||||||
{
|
|
||||||
if (!hub || !user)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
list_remove(hub->users->list, user);
|
|
||||||
|
|
||||||
if (hub->users->count > 0)
|
|
||||||
{
|
{
|
||||||
hub->users->count--;
|
users->count--;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uhub_assert(!"negative count!");
|
uhub_assert(!"negative count!");
|
||||||
}
|
}
|
||||||
|
|
||||||
hub->users->shared_size -= user->limits.shared_size;
|
users->shared_size -= user->limits.shared_size;
|
||||||
hub->users->shared_files -= user->limits.shared_files;
|
users->shared_files -= user->limits.shared_files;
|
||||||
|
|
||||||
user->hub = 0;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct hub_user* uman_get_user_by_sid(struct hub_info* hub, sid_t sid)
|
struct hub_user* uman_get_user_by_sid(struct hub_user_manager* users, sid_t sid)
|
||||||
{
|
{
|
||||||
return sid_lookup(hub->users->sids, sid);
|
return sid_lookup(users->sids, sid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct hub_user* uman_get_user_by_cid(struct hub_info* hub, const char* cid)
|
struct hub_user* uman_get_user_by_cid(struct hub_user_manager* users, const char* cid)
|
||||||
{
|
{
|
||||||
struct hub_user* user = (struct hub_user*) list_get_first(hub->users->list); /* iterate users - only on incoming INF msg */
|
struct hub_user* user = (struct hub_user*) list_get_first(users->list); /* iterate users - only on incoming INF msg */
|
||||||
while (user)
|
while (user)
|
||||||
{
|
{
|
||||||
if (strcmp(user->id.cid, cid) == 0)
|
if (strcmp(user->id.cid, cid) == 0)
|
||||||
return user;
|
return user;
|
||||||
user = (struct hub_user*) list_get_next(hub->users->list);
|
user = (struct hub_user*) list_get_next(users->list);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct hub_user* uman_get_user_by_nick(struct hub_info* hub, const char* nick)
|
struct hub_user* uman_get_user_by_nick(struct hub_user_manager* users, const char* nick)
|
||||||
{
|
{
|
||||||
struct hub_user* user = (struct hub_user*) list_get_first(hub->users->list); /* iterate users - only on incoming INF msg */
|
struct hub_user* user = (struct hub_user*) list_get_first(users->list); /* iterate users - only on incoming INF msg */
|
||||||
while (user)
|
while (user)
|
||||||
{
|
{
|
||||||
if (strcmp(user->id.nick, nick) == 0)
|
if (strcmp(user->id.nick, nick) == 0)
|
||||||
return user;
|
return user;
|
||||||
user = (struct hub_user*) list_get_next(hub->users->list);
|
user = (struct hub_user*) list_get_next(users->list);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t uman_get_user_by_addr(struct hub_info* hub, struct linked_list* users, struct ip_range* range)
|
size_t uman_get_user_by_addr(struct hub_user_manager* users, struct linked_list* target, struct ip_range* range)
|
||||||
{
|
{
|
||||||
size_t num = 0;
|
size_t num = 0;
|
||||||
struct hub_user* user = (struct hub_user*) list_get_first(hub->users->list); /* iterate users - only on incoming INF msg */
|
struct hub_user* user = (struct hub_user*) list_get_first(users->list); /* iterate users - only on incoming INF msg */
|
||||||
while (user)
|
while (user)
|
||||||
{
|
{
|
||||||
if (ip_in_range(&user->id.addr, range))
|
if (ip_in_range(&user->id.addr, range))
|
||||||
{
|
{
|
||||||
list_append(users, user);
|
list_append(target, user);
|
||||||
num++;
|
num++;
|
||||||
}
|
}
|
||||||
user = (struct hub_user*) list_get_next(hub->users->list);
|
user = (struct hub_user*) list_get_next(users->list);
|
||||||
}
|
}
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
int uman_send_user_list(struct hub_info* hub, struct hub_user* target)
|
int uman_send_user_list(struct hub_info* hub, struct hub_user_manager* users, struct hub_user* target)
|
||||||
{
|
{
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
struct hub_user* user;
|
struct hub_user* user;
|
||||||
user_flag_set(target, flag_user_list);
|
user_flag_set(target, flag_user_list);
|
||||||
user = (struct hub_user*) list_get_first(hub->users->list); /* iterate users - only on INF or PAS msg */
|
user = (struct hub_user*) list_get_first(users->list); /* iterate users - only on INF or PAS msg */
|
||||||
while (user)
|
while (user)
|
||||||
{
|
{
|
||||||
if (user_is_logged_in(user))
|
if (user_is_logged_in(user))
|
||||||
@@ -235,7 +173,7 @@ int uman_send_user_list(struct hub_info* hub, struct hub_user* target)
|
|||||||
if (!ret)
|
if (!ret)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
user = (struct hub_user*) list_get_next(hub->users->list);
|
user = (struct hub_user*) list_get_next(users->list);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@@ -248,7 +186,7 @@ int uman_send_user_list(struct hub_info* hub, struct hub_user* target)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void uman_send_quit_message(struct hub_info* hub, struct hub_user* leaving)
|
void uman_send_quit_message(struct hub_info* hub, struct hub_user_manager* users, struct hub_user* leaving)
|
||||||
{
|
{
|
||||||
struct adc_message* command = adc_msg_construct(ADC_CMD_IQUI, 6);
|
struct adc_message* command = adc_msg_construct(ADC_CMD_IQUI, 6);
|
||||||
adc_msg_add_argument(command, (const char*) sid_to_string(leaving->id.sid));
|
adc_msg_add_argument(command, (const char*) sid_to_string(leaving->id.sid));
|
||||||
@@ -261,9 +199,9 @@ void uman_send_quit_message(struct hub_info* hub, struct hub_user* leaving)
|
|||||||
adc_msg_free(command);
|
adc_msg_free(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
sid_t uman_get_free_sid(struct hub_info* hub, struct hub_user* user)
|
sid_t uman_get_free_sid(struct hub_user_manager* users, struct hub_user* user)
|
||||||
{
|
{
|
||||||
sid_t sid = sid_alloc(hub->users->sids, user);
|
sid_t sid = sid_alloc(users->sids, user);
|
||||||
user->id.sid = sid;
|
user->id.sid = sid;
|
||||||
return sid;
|
return sid;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,36 +28,35 @@ struct hub_user_manager
|
|||||||
uint64_t shared_size; /**<< "The total number of shared bytes among fully connected users." */
|
uint64_t shared_size; /**<< "The total number of shared bytes among fully connected users." */
|
||||||
uint64_t shared_files; /**<< "The total number of shared files among fully connected users." */
|
uint64_t shared_files; /**<< "The total number of shared files among fully connected users." */
|
||||||
struct linked_list* list; /**<< "Contains all logged in users" */
|
struct linked_list* list; /**<< "Contains all logged in users" */
|
||||||
struct timeout_evt* timeout; /**<< "Timeout handler for statistics" */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the user manager.
|
* Initializes the user manager.
|
||||||
* @return 0 on success, or -1 if error (out of memory).
|
* @return 0 on success, or -1 if error (out of memory).
|
||||||
*/
|
*/
|
||||||
extern int uman_init(struct hub_info* hub);
|
extern struct hub_user_manager* uman_init();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shuts down the user manager.
|
* Shuts down the user manager.
|
||||||
* All users will be disconnected and deleted as part of this.
|
* All users will be disconnected and deleted as part of this.
|
||||||
*
|
*
|
||||||
* @return 0 on success, or -1 in an error occured (hub is invalid).
|
* @return 0 on success, or -1 in an error occured (invalid pointer).
|
||||||
*/
|
*/
|
||||||
extern int uman_shutdown(struct hub_info* hub);
|
extern int uman_shutdown(struct hub_user_manager* users);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate statistics for logfiles.
|
* Generate statistics for logfiles.
|
||||||
*/
|
*/
|
||||||
extern void uman_update_stats(struct hub_info* hub);
|
extern void uman_update_stats(struct hub_user_manager* users);
|
||||||
extern void uman_print_stats(struct hub_info* hub);
|
extern void uman_print_stats(struct hub_user_manager* users);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a user to the user manager.
|
* Add a user to the user manager.
|
||||||
*
|
*
|
||||||
* @param hub The hub to add the user to
|
* @param users The usermanager to add the user to
|
||||||
* @param user The user to be added to the hub.
|
* @param user The user to be added to the hub.
|
||||||
*/
|
*/
|
||||||
extern int uman_add(struct hub_info* hub, struct hub_user* user);
|
extern int uman_add(struct hub_user_manager* users, struct hub_user* user);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a user from the user manager.
|
* Remove a user from the user manager.
|
||||||
@@ -66,12 +65,12 @@ extern int uman_add(struct hub_info* hub, struct hub_user* user);
|
|||||||
*
|
*
|
||||||
* @return 0 if successfully removed, -1 if error.
|
* @return 0 if successfully removed, -1 if error.
|
||||||
*/
|
*/
|
||||||
extern int uman_remove(struct hub_info* hub, struct hub_user* user);
|
extern int uman_remove(struct hub_user_manager* users, struct hub_user* user);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns and allocates an unused session ID (SID).
|
* Returns and allocates an unused session ID (SID).
|
||||||
*/
|
*/
|
||||||
extern sid_t uman_get_free_sid(struct hub_info* hub, struct hub_user* user);
|
extern sid_t uman_get_free_sid(struct hub_user_manager* users, struct hub_user* user);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lookup a user based on the session ID (SID).
|
* Lookup a user based on the session ID (SID).
|
||||||
@@ -86,26 +85,28 @@ extern sid_t uman_get_free_sid(struct hub_info* hub, struct hub_user* user);
|
|||||||
*
|
*
|
||||||
* @return a user if found, or NULL if not found
|
* @return a user if found, or NULL if not found
|
||||||
*/
|
*/
|
||||||
extern struct hub_user* uman_get_user_by_sid(struct hub_info* hub, sid_t sid);
|
extern struct hub_user* uman_get_user_by_sid(struct hub_user_manager* users, sid_t sid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lookup a user based on the client ID (CID).
|
* Lookup a user based on the client ID (CID).
|
||||||
* @return a user if found, or NULL if not found
|
* @return a user if found, or NULL if not found
|
||||||
*/
|
*/
|
||||||
extern struct hub_user* uman_get_user_by_cid(struct hub_info* hub, const char* cid);
|
extern struct hub_user* uman_get_user_by_cid(struct hub_user_manager* users, const char* cid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lookup a user based on the nick name.
|
* Lookup a user based on the nick name.
|
||||||
* @return a user if found, or NULL if not found
|
* @return a user if found, or NULL if not found
|
||||||
*/
|
*/
|
||||||
extern struct hub_user* uman_get_user_by_nick(struct hub_info* hub, const char* nick);
|
extern struct hub_user* uman_get_user_by_nick(struct hub_user_manager* users, const char* nick);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lookup users based on an ip address range.
|
* Lookup users based on an ip address range.
|
||||||
*
|
*
|
||||||
|
* @param[out] target the list of users matching the address
|
||||||
|
* @param range the IP range of users to match
|
||||||
* @return The number of users matching the addressess, or -1 on error (mask is wrong).
|
* @return The number of users matching the addressess, or -1 on error (mask is wrong).
|
||||||
*/
|
*/
|
||||||
extern size_t uman_get_user_by_addr(struct hub_info* hub, struct linked_list* users, struct ip_range* range);
|
extern size_t uman_get_user_by_addr(struct hub_user_manager* users, struct linked_list* target, struct ip_range* range);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send the user list of connected clients to 'user'.
|
* Send the user list of connected clients to 'user'.
|
||||||
@@ -113,13 +114,13 @@ extern size_t uman_get_user_by_addr(struct hub_info* hub, struct linked_list* us
|
|||||||
*
|
*
|
||||||
* @return 1 if sending the user list succeeded, 0 otherwise.
|
* @return 1 if sending the user list succeeded, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
extern int uman_send_user_list(struct hub_info* hub, struct hub_user* user);
|
extern int uman_send_user_list(struct hub_info* hub, struct hub_user_manager* users, struct hub_user* user);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a quit message to all connected users when 'user' is
|
* Send a quit message to all connected users when 'user' is
|
||||||
* leaving the hub (for whatever reason).
|
* leaving the hub (for whatever reason).
|
||||||
*/
|
*/
|
||||||
extern void uman_send_quit_message(struct hub_info* hub, struct hub_user* user);
|
extern void uman_send_quit_message(struct hub_info* hub, struct hub_user_manager* users, struct hub_user* user);
|
||||||
|
|
||||||
|
|
||||||
#endif /* HAVE_UHUB_USER_MANAGER_H */
|
#endif /* HAVE_UHUB_USER_MANAGER_H */
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -146,6 +146,9 @@ int net_backend_process()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Process pending DNS results
|
||||||
|
net_dns_process();
|
||||||
|
|
||||||
g_backend->handler.backend_process(g_backend->data, res);
|
g_backend->handler.backend_process(g_backend->data, res);
|
||||||
|
|
||||||
net_cleanup_process(g_backend->cleaner);
|
net_cleanup_process(g_backend->cleaner);
|
||||||
@@ -181,11 +184,8 @@ void net_con_close(struct net_connection* con)
|
|||||||
|
|
||||||
#ifdef SSL_SUPPORT
|
#ifdef SSL_SUPPORT
|
||||||
if (con->ssl)
|
if (con->ssl)
|
||||||
{
|
net_ssl_shutdown(con);
|
||||||
SSL_shutdown(con->ssl);
|
#endif /* SSL_SUPPORT */
|
||||||
SSL_clear(con->ssl);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
net_close(con->sd);
|
net_close(con->sd);
|
||||||
con->sd = -1;
|
con->sd = -1;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -20,11 +20,10 @@
|
|||||||
#define NET_WANT_READ NET_EVENT_READ
|
#define NET_WANT_READ NET_EVENT_READ
|
||||||
#define NET_WANT_WRITE NET_EVENT_WRITE
|
#define NET_WANT_WRITE NET_EVENT_WRITE
|
||||||
#define NET_WANT_ACCEPT NET_EVENT_READ
|
#define NET_WANT_ACCEPT NET_EVENT_READ
|
||||||
#define NET_WANT_SSL_READ 0x0010
|
|
||||||
#define NET_WANT_SSL_WRITE 0x0020
|
#define NET_SSL_ANY NET_WANT_SSL_READ | NET_WANT_SSL_WRITE | NET_WANT_SSL_ACCEPT | NET_WANT_SSL_CONNECT | NET_WANT_SSL_X509_LOOKUP
|
||||||
#define NET_WANT_SSL_ACCEPT 0x0040
|
|
||||||
#define NET_WANT_SSL_CONNECT 0x0080
|
struct ssl_handle; /* abstract type */
|
||||||
#define NET_WANT_SSL_X509_LOOKUP 0x0100
|
|
||||||
|
|
||||||
#define NET_CLEANUP 0x8000
|
#define NET_CLEANUP 0x8000
|
||||||
|
|
||||||
@@ -36,9 +35,7 @@
|
|||||||
struct timeout_evt* timeout; /** timeout event handler */
|
struct timeout_evt* timeout; /** timeout event handler */
|
||||||
|
|
||||||
#define NET_CON_STRUCT_SSL \
|
#define NET_CON_STRUCT_SSL \
|
||||||
SSL* ssl; /** SSL handle */ \
|
struct ssl_handle* ssl; /** SSL handle */
|
||||||
uint32_t ssl_state; /** SSL state */ \
|
|
||||||
size_t write_len; /** Length of last SSL_write(), only used if flags is NET_WANT_SSL_READ. */ \
|
|
||||||
|
|
||||||
#ifdef SSL_SUPPORT
|
#ifdef SSL_SUPPORT
|
||||||
#define NET_CON_STRUCT_COMMON \
|
#define NET_CON_STRUCT_COMMON \
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -20,132 +20,18 @@
|
|||||||
#include "uhub.h"
|
#include "uhub.h"
|
||||||
#include "network/common.h"
|
#include "network/common.h"
|
||||||
|
|
||||||
#ifdef SSL_SUPPORT
|
static int is_blocked_or_interrupted()
|
||||||
|
|
||||||
enum uhub_tls_state
|
|
||||||
{
|
{
|
||||||
tls_st_none,
|
int err = net_error();
|
||||||
tls_st_error,
|
return
|
||||||
tls_st_accepting,
|
#ifdef WINSOCK
|
||||||
tls_st_connecting,
|
err == WSAEWOULDBLOCK
|
||||||
tls_st_connected,
|
#else
|
||||||
tls_st_disconnecting,
|
err == EWOULDBLOCK
|
||||||
};
|
|
||||||
|
|
||||||
static int handle_openssl_error(struct net_connection* con, int ret)
|
|
||||||
{
|
|
||||||
uhub_assert(con);
|
|
||||||
|
|
||||||
int error = SSL_get_error(con->ssl, ret);
|
|
||||||
switch (error)
|
|
||||||
{
|
|
||||||
case SSL_ERROR_ZERO_RETURN:
|
|
||||||
LOG_PROTO("SSL_get_error: ret=%d, error=%d: SSL_ERROR_ZERO_RETURN", ret, error);
|
|
||||||
con->ssl_state = tls_st_error;
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
case SSL_ERROR_WANT_READ:
|
|
||||||
LOG_PROTO("SSL_get_error: ret=%d, error=%d: SSL_ERROR_WANT_READ", ret, error);
|
|
||||||
con->flags |= NET_WANT_SSL_READ;
|
|
||||||
net_con_update(con, NET_EVENT_READ);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case SSL_ERROR_WANT_WRITE:
|
|
||||||
LOG_PROTO("SSL_get_error: ret=%d, error=%d: SSL_ERROR_WANT_WRITE", ret, error);
|
|
||||||
con->flags |= NET_WANT_SSL_WRITE;
|
|
||||||
net_con_update(con, NET_EVENT_READ | NET_EVENT_WRITE);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case SSL_ERROR_SYSCALL:
|
|
||||||
LOG_PROTO("SSL_get_error: ret=%d, error=%d: SSL_ERROR_SYSCALL", ret, error);
|
|
||||||
/* if ret == 0, connection closed, if ret == -1, check with errno */
|
|
||||||
if (ret == 0)
|
|
||||||
return -1;
|
|
||||||
else
|
|
||||||
return -net_error();
|
|
||||||
|
|
||||||
case SSL_ERROR_SSL:
|
|
||||||
LOG_PROTO("SSL_get_error: ret=%d, error=%d: SSL_ERROR_SSL", ret, error);
|
|
||||||
/* internal openssl error */
|
|
||||||
con->ssl_state = tls_st_error;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t net_con_ssl_accept(struct net_connection* con)
|
|
||||||
{
|
|
||||||
uhub_assert(con);
|
|
||||||
con->ssl_state = tls_st_accepting;
|
|
||||||
ssize_t ret = SSL_accept(con->ssl);
|
|
||||||
#ifdef NETWORK_DUMP_DEBUG
|
|
||||||
LOG_PROTO("SSL_accept() ret=%d", ret);
|
|
||||||
#endif
|
#endif
|
||||||
if (ret > 0)
|
|| err == EINTR;
|
||||||
{
|
|
||||||
net_con_update(con, NET_EVENT_READ);
|
|
||||||
con->ssl_state = tls_st_connected;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return handle_openssl_error(con, ret);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t net_con_ssl_connect(struct net_connection* con)
|
|
||||||
{
|
|
||||||
uhub_assert(con);
|
|
||||||
|
|
||||||
con->ssl_state = tls_st_connecting;
|
|
||||||
ssize_t ret = SSL_connect(con->ssl);
|
|
||||||
#ifdef NETWORK_DUMP_DEBUG
|
|
||||||
LOG_PROTO("SSL_connect() ret=%d", ret);
|
|
||||||
#endif
|
|
||||||
if (ret > 0)
|
|
||||||
{
|
|
||||||
con->ssl_state = tls_st_connected;
|
|
||||||
net_con_update(con, NET_EVENT_READ);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return handle_openssl_error(con, ret);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode ssl_mode, SSL_CTX* ssl_ctx)
|
|
||||||
{
|
|
||||||
uhub_assert(con);
|
|
||||||
SSL* ssl = 0;
|
|
||||||
|
|
||||||
if (ssl_mode == net_con_ssl_mode_server)
|
|
||||||
{
|
|
||||||
ssl = SSL_new(ssl_ctx);
|
|
||||||
if (!ssl)
|
|
||||||
{
|
|
||||||
LOG_ERROR("Unable to create new SSL stream\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
SSL_set_fd(ssl, con->sd);
|
|
||||||
net_con_set_ssl(con, ssl);
|
|
||||||
return net_con_ssl_accept(con);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ssl = SSL_new(SSL_CTX_new(TLSv1_method()));
|
|
||||||
SSL_set_fd(ssl, con->sd);
|
|
||||||
net_con_set_ssl(con, ssl);
|
|
||||||
return net_con_ssl_connect(con);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* SSL_SUPPORT */
|
|
||||||
|
|
||||||
#ifdef SSL_SUPPORT
|
|
||||||
void net_stats_add_tx(size_t bytes);
|
|
||||||
void net_stats_add_rx(size_t bytes);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ssize_t net_con_send(struct net_connection* con, const void* buf, size_t len)
|
ssize_t net_con_send(struct net_connection* con, const void* buf, size_t len)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@@ -156,13 +42,7 @@ ssize_t net_con_send(struct net_connection* con, const void* buf, size_t len)
|
|||||||
ret = net_send(con->sd, buf, len, UHUB_SEND_SIGNAL);
|
ret = net_send(con->sd, buf, len, UHUB_SEND_SIGNAL);
|
||||||
if (ret == -1)
|
if (ret == -1)
|
||||||
{
|
{
|
||||||
if (
|
if (is_blocked_or_interrupted())
|
||||||
#ifdef WINSOCK
|
|
||||||
net_error() == WSAEWOULDBLOCK
|
|
||||||
#else
|
|
||||||
net_error() == EWOULDBLOCK
|
|
||||||
#endif
|
|
||||||
|| net_error() == EINTR)
|
|
||||||
return 0;
|
return 0;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -170,19 +50,9 @@ ssize_t net_con_send(struct net_connection* con, const void* buf, size_t len)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
con->write_len = len;
|
ret = net_ssl_send(con, buf, len);
|
||||||
ret = SSL_write(con->ssl, buf, len);
|
|
||||||
LOG_PROTO("SSL_write(con=%p, buf=%p, len=" PRINTF_SIZE_T ") => %d", con, buf, len, ret);
|
|
||||||
if (ret <= 0)
|
|
||||||
{
|
|
||||||
return handle_openssl_error(con, ret);
|
|
||||||
}
|
}
|
||||||
else
|
#endif /* SSL_SUPPORT */
|
||||||
{
|
|
||||||
net_stats_add_tx(ret);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,19 +60,13 @@ ssize_t net_con_recv(struct net_connection* con, void* buf, size_t len)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
#ifdef SSL_SUPPORT
|
#ifdef SSL_SUPPORT
|
||||||
if (!net_con_is_ssl(con))
|
if (!con->ssl)
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
ret = net_recv(con->sd, buf, len, 0);
|
ret = net_recv(con->sd, buf, len, 0);
|
||||||
if (ret == -1)
|
if (ret == -1)
|
||||||
{
|
{
|
||||||
if (
|
if (is_blocked_or_interrupted())
|
||||||
#ifdef WINSOCK
|
|
||||||
net_error() == WSAEWOULDBLOCK
|
|
||||||
#else
|
|
||||||
net_error() == EWOULDBLOCK
|
|
||||||
#endif
|
|
||||||
|| net_error() == EINTR)
|
|
||||||
return 0;
|
return 0;
|
||||||
return -net_error();
|
return -net_error();
|
||||||
}
|
}
|
||||||
@@ -214,22 +78,9 @@ ssize_t net_con_recv(struct net_connection* con, void* buf, size_t len)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (con->ssl_state == tls_st_error)
|
ret = net_ssl_recv(con, buf, len);
|
||||||
return -1;
|
|
||||||
|
|
||||||
ret = SSL_read(con->ssl, buf, len);
|
|
||||||
LOG_PROTO("SSL_read(con=%p, buf=%p, len=" PRINTF_SIZE_T ") => %d", con, buf, len, ret);
|
|
||||||
if (ret > 0)
|
|
||||||
{
|
|
||||||
net_con_update(con, NET_EVENT_READ);
|
|
||||||
net_stats_add_rx(ret);
|
|
||||||
}
|
}
|
||||||
else
|
#endif /* SSL_SUPPORT */
|
||||||
{
|
|
||||||
return handle_openssl_error(con, ret);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,13 +89,7 @@ ssize_t net_con_peek(struct net_connection* con, void* buf, size_t len)
|
|||||||
int ret = net_recv(con->sd, buf, len, MSG_PEEK);
|
int ret = net_recv(con->sd, buf, len, MSG_PEEK);
|
||||||
if (ret == -1)
|
if (ret == -1)
|
||||||
{
|
{
|
||||||
if (
|
if (is_blocked_or_interrupted())
|
||||||
#ifdef WINSOCK
|
|
||||||
net_error() == WSAEWOULDBLOCK
|
|
||||||
#else
|
|
||||||
net_error() == EWOULDBLOCK
|
|
||||||
#endif
|
|
||||||
|| net_error() == EINTR)
|
|
||||||
return 0;
|
return 0;
|
||||||
return -net_error();
|
return -net_error();
|
||||||
}
|
}
|
||||||
@@ -254,19 +99,10 @@ ssize_t net_con_peek(struct net_connection* con, void* buf, size_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SSL_SUPPORT
|
#ifdef SSL_SUPPORT
|
||||||
|
|
||||||
int net_con_is_ssl(struct net_connection* con)
|
int net_con_is_ssl(struct net_connection* con)
|
||||||
{
|
{
|
||||||
return con->ssl != 0;
|
return !!con->ssl;
|
||||||
}
|
|
||||||
|
|
||||||
SSL* net_con_get_ssl(struct net_connection* con)
|
|
||||||
{
|
|
||||||
return con->ssl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void net_con_set_ssl(struct net_connection* con, SSL* ssl)
|
|
||||||
{
|
|
||||||
con->ssl = ssl;
|
|
||||||
}
|
}
|
||||||
#endif /* SSL_SUPPORT */
|
#endif /* SSL_SUPPORT */
|
||||||
|
|
||||||
@@ -283,7 +119,8 @@ void* net_con_get_ptr(struct net_connection* con)
|
|||||||
void net_con_destroy(struct net_connection* con)
|
void net_con_destroy(struct net_connection* con)
|
||||||
{
|
{
|
||||||
#ifdef SSL_SUPPORT
|
#ifdef SSL_SUPPORT
|
||||||
SSL_free(con->ssl);
|
if (con->ssl)
|
||||||
|
net_ssl_destroy(con);
|
||||||
#endif
|
#endif
|
||||||
hub_free(con);
|
hub_free(con);
|
||||||
}
|
}
|
||||||
@@ -295,68 +132,16 @@ void net_con_callback(struct net_connection* con, int events)
|
|||||||
|
|
||||||
if (events == NET_EVENT_TIMEOUT)
|
if (events == NET_EVENT_TIMEOUT)
|
||||||
{
|
{
|
||||||
LOG_TRACE("net_con_callback(%p, TIMEOUT", con);
|
LOG_TRACE("net_con_callback(%p, TIMEOUT)", con);
|
||||||
con->callback(con, events, con->ptr);
|
con->callback(con, events, con->ptr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SSL_SUPPORT
|
#ifdef SSL_SUPPORT
|
||||||
if (!con->ssl)
|
if (con->ssl)
|
||||||
{
|
net_ssl_callback(con, events);
|
||||||
#endif
|
|
||||||
con->callback(con, events, con->ptr);
|
|
||||||
#ifdef SSL_SUPPORT
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
#ifdef NETWORK_DUMP_DEBUG
|
|
||||||
LOG_PROTO("net_con_event: events=%d, con=%p, state=%d", events, con, con->ssl_state);
|
|
||||||
#endif
|
#endif
|
||||||
switch (con->ssl_state)
|
|
||||||
{
|
|
||||||
case tls_st_none:
|
|
||||||
con->callback(con, events, con->ptr);
|
con->callback(con, events, con->ptr);
|
||||||
break;
|
|
||||||
|
|
||||||
case tls_st_error:
|
|
||||||
con->callback(con, NET_EVENT_READ, con->ptr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case tls_st_accepting:
|
|
||||||
if (net_con_ssl_accept(con) < 0)
|
|
||||||
{
|
|
||||||
con->callback(con, NET_EVENT_READ, con->ptr);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case tls_st_connecting:
|
|
||||||
if (net_con_ssl_connect(con) < 0)
|
|
||||||
{
|
|
||||||
con->callback(con, NET_EVENT_READ, con->ptr);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case tls_st_connected:
|
|
||||||
LOG_PROTO("tls_st_connected, events=%s%s, ssl_flags=%s%s", (events & NET_EVENT_READ ? "R" : ""), (events & NET_EVENT_WRITE ? "W" : ""), con->flags & NET_WANT_SSL_READ ? "R" : "", con->flags & NET_WANT_SSL_WRITE ? "W" : "");
|
|
||||||
if (events & NET_EVENT_WRITE && con->flags & NET_WANT_SSL_READ)
|
|
||||||
{
|
|
||||||
con->callback(con, events & NET_EVENT_READ, con->ptr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (events & NET_EVENT_READ && con->flags & NET_WANT_SSL_WRITE)
|
|
||||||
{
|
|
||||||
con->callback(con, events & NET_EVENT_READ, con->ptr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
con->callback(con, events, con->ptr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case tls_st_disconnecting:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
#include "uhub.h"
|
#include "uhub.h"
|
||||||
#include "network/common.h"
|
#include "network/common.h"
|
||||||
#include "network/backend.h"
|
#include "network/backend.h"
|
||||||
|
#include "network/tls.h"
|
||||||
|
|
||||||
#define NET_EVENT_TIMEOUT 0x0001
|
#define NET_EVENT_TIMEOUT 0x0001
|
||||||
#define NET_EVENT_READ 0x0002
|
#define NET_EVENT_READ 0x0002
|
||||||
@@ -83,29 +84,5 @@ extern ssize_t net_con_peek(struct net_connection* con, void* buf, size_t len);
|
|||||||
extern void net_con_set_timeout(struct net_connection* con, int seconds);
|
extern void net_con_set_timeout(struct net_connection* con, int seconds);
|
||||||
extern void net_con_clear_timeout(struct net_connection* con);
|
extern void net_con_clear_timeout(struct net_connection* con);
|
||||||
|
|
||||||
#ifdef SSL_SUPPORT
|
|
||||||
/**
|
|
||||||
* Start SSL_accept()
|
|
||||||
*/
|
|
||||||
extern ssize_t net_con_ssl_accept(struct net_connection*);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start SSL_connect()
|
|
||||||
*/
|
|
||||||
extern ssize_t net_con_ssl_connect(struct net_connection*);
|
|
||||||
|
|
||||||
enum net_con_ssl_mode
|
|
||||||
{
|
|
||||||
net_con_ssl_mode_server,
|
|
||||||
net_con_ssl_mode_client,
|
|
||||||
};
|
|
||||||
|
|
||||||
extern ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode, SSL_CTX* ssl_ctx);
|
|
||||||
|
|
||||||
extern int net_con_is_ssl(struct net_connection* con);
|
|
||||||
extern SSL* net_con_get_ssl(struct net_connection* con);
|
|
||||||
extern void net_con_set_ssl(struct net_connection* con, SSL*);
|
|
||||||
#endif /* SSL_SUPPORT */
|
|
||||||
|
|
||||||
#endif /* HAVE_UHUB_NETWORK_CONNECTION_H */
|
#endif /* HAVE_UHUB_NETWORK_CONNECTION_H */
|
||||||
|
|
||||||
|
|||||||
386
src/network/dnsresolver.c
Normal file
386
src/network/dnsresolver.c
Normal file
@@ -0,0 +1,386 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uhub.h"
|
||||||
|
|
||||||
|
static struct net_dns_job* find_and_remove_job(struct net_dns_job* job);
|
||||||
|
static struct net_dns_result* find_and_remove_result(struct net_dns_job* job);
|
||||||
|
|
||||||
|
struct net_dns_job
|
||||||
|
{
|
||||||
|
net_dns_job_cb callback;
|
||||||
|
void* ptr;
|
||||||
|
|
||||||
|
char* host;
|
||||||
|
int af;
|
||||||
|
|
||||||
|
#ifdef DEBUG_LOOKUP_TIME
|
||||||
|
struct timeval time_start;
|
||||||
|
struct timeval time_finish;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uhub_thread_t* thread_handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct net_dns_result
|
||||||
|
{
|
||||||
|
struct linked_list* addr_list;
|
||||||
|
struct net_dns_job* job;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void free_job(struct net_dns_job* job)
|
||||||
|
{
|
||||||
|
if (job)
|
||||||
|
{
|
||||||
|
hub_free(job->host);
|
||||||
|
hub_free(job);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void shutdown_free_jobs(void* ptr)
|
||||||
|
{
|
||||||
|
struct net_dns_job* job = (struct net_dns_job*) ptr;
|
||||||
|
uhub_thread_cancel(job->thread_handle);
|
||||||
|
uhub_thread_join(job->thread_handle);
|
||||||
|
free_job(job);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void shutdown_free_results(void* ptr)
|
||||||
|
{
|
||||||
|
struct net_dns_result* result = (struct net_dns_result*) ptr;
|
||||||
|
uhub_thread_join(result->job->thread_handle);
|
||||||
|
net_dns_result_free(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// NOTE: Any job manipulating the members of this
|
||||||
|
// struct must lock the mutex!
|
||||||
|
struct net_dns_subsystem
|
||||||
|
{
|
||||||
|
struct linked_list* jobs; // currently running jobs
|
||||||
|
struct linked_list* results; // queue of results that are awaiting being delivered to callback.
|
||||||
|
uhub_mutex_t mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct net_dns_subsystem* g_dns = NULL;
|
||||||
|
|
||||||
|
void net_dns_initialize()
|
||||||
|
{
|
||||||
|
LOG_TRACE("net_dns_initialize()");
|
||||||
|
g_dns = (struct net_dns_subsystem*) hub_malloc_zero(sizeof(struct net_dns_subsystem));
|
||||||
|
g_dns->jobs = list_create();
|
||||||
|
g_dns->results = list_create();
|
||||||
|
uhub_mutex_init(&g_dns->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void net_dns_destroy()
|
||||||
|
{
|
||||||
|
struct net_dns_job* job;
|
||||||
|
struct net_dns_result* result;
|
||||||
|
|
||||||
|
uhub_mutex_lock(&g_dns->mutex);
|
||||||
|
LOG_TRACE("net_dns_destroy(): jobs=%d", (int) list_size(g_dns->jobs));
|
||||||
|
list_clear(g_dns->jobs, &shutdown_free_jobs);
|
||||||
|
|
||||||
|
LOG_TRACE("net_dns_destroy(): results=%d", (int) list_size(g_dns->results));
|
||||||
|
list_clear(g_dns->results, &shutdown_free_results);
|
||||||
|
uhub_mutex_unlock(&g_dns->mutex);
|
||||||
|
|
||||||
|
list_destroy(g_dns->jobs);
|
||||||
|
list_destroy(g_dns->results);
|
||||||
|
uhub_mutex_destroy(&g_dns->mutex);
|
||||||
|
hub_free(g_dns);
|
||||||
|
g_dns = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dummy_free(void* ptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void net_dns_process()
|
||||||
|
{
|
||||||
|
struct net_dns_result* result;
|
||||||
|
uhub_mutex_lock(&g_dns->mutex);
|
||||||
|
LOG_DUMP("net_dns_process(): jobs=%d, results=%d", (int) list_size(g_dns->jobs), (int) list_size(g_dns->results));
|
||||||
|
|
||||||
|
for (result = (struct net_dns_result*) list_get_first(g_dns->results); result; result = (struct net_dns_result*) list_get_next(g_dns->results))
|
||||||
|
{
|
||||||
|
struct net_dns_job* job = result->job;
|
||||||
|
#ifdef DEBUG_LOOKUP_TIME
|
||||||
|
struct timeval time_result;
|
||||||
|
timersub(&result->job->time_finish, &result->job->time_start, &time_result);
|
||||||
|
LOG_TRACE("DNS lookup took %d ms", (time_result.tv_sec * 1000) + (time_result.tv_usec / 1000));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// wait for the work thread to finish
|
||||||
|
uhub_thread_join(job->thread_handle);
|
||||||
|
|
||||||
|
// callback - should we delete the data immediately?
|
||||||
|
if (job->callback(job, result))
|
||||||
|
{
|
||||||
|
net_dns_result_free(result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Caller wants to keep the result data, and
|
||||||
|
* thus needs to call net_dns_result_free() to release it later.
|
||||||
|
* We only clean up the job data here and keep the results intact.
|
||||||
|
*/
|
||||||
|
result->job = NULL;
|
||||||
|
free_job(job);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list_clear(g_dns->results, &dummy_free);
|
||||||
|
uhub_mutex_unlock(&g_dns->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void* job_thread_resolve_name(void* ptr)
|
||||||
|
{
|
||||||
|
struct net_dns_job* job = (struct net_dns_job*) ptr;
|
||||||
|
struct addrinfo hints, *result, *it;
|
||||||
|
struct net_dns_result* dns_results;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_family = job->af;
|
||||||
|
hints.ai_protocol = IPPROTO_TCP;
|
||||||
|
|
||||||
|
ret = getaddrinfo(job->host, NULL, &hints, &result);
|
||||||
|
if (ret != 0 && ret != EAI_NONAME)
|
||||||
|
{
|
||||||
|
LOG_TRACE("getaddrinfo() failed: %s", gai_strerror(ret));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dns_results = (struct net_dns_result*) hub_malloc(sizeof(struct net_dns_result));
|
||||||
|
dns_results->addr_list = list_create();
|
||||||
|
dns_results->job = job;
|
||||||
|
|
||||||
|
if (ret != EAI_NONAME)
|
||||||
|
{
|
||||||
|
for (it = result; it; it = it->ai_next)
|
||||||
|
{
|
||||||
|
struct ip_addr_encap* ipaddr = hub_malloc_zero(sizeof(struct ip_addr_encap));
|
||||||
|
ipaddr->af = it->ai_family;
|
||||||
|
|
||||||
|
if (it->ai_family == AF_INET)
|
||||||
|
{
|
||||||
|
struct sockaddr_in* addr4 = (struct sockaddr_in*) it->ai_addr;
|
||||||
|
memcpy(&ipaddr->internal_ip_data.in, &addr4->sin_addr, sizeof(struct in_addr));
|
||||||
|
}
|
||||||
|
else if (it->ai_family == AF_INET6)
|
||||||
|
{
|
||||||
|
struct sockaddr_in6* addr6 = (struct sockaddr_in6*) it->ai_addr;
|
||||||
|
memcpy(&ipaddr->internal_ip_data.in6, &addr6->sin6_addr, sizeof(struct in6_addr));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_TRACE("getaddrinfo() returned result with unknown address family: %d", it->ai_family);
|
||||||
|
hub_free(ipaddr);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DUMP("getaddrinfo() - Address (%d) %s for \"%s\"", ret++, ip_convert_to_string(ipaddr), job->host);
|
||||||
|
list_append(dns_results->addr_list, ipaddr);
|
||||||
|
}
|
||||||
|
freeaddrinfo(result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* hm */
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_LOOKUP_TIME
|
||||||
|
gettimeofday(&job->time_finish, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uhub_mutex_lock(&g_dns->mutex);
|
||||||
|
list_remove(g_dns->jobs, job);
|
||||||
|
list_append(g_dns->results, dns_results);
|
||||||
|
uhub_mutex_unlock(&g_dns->mutex);
|
||||||
|
|
||||||
|
return dns_results;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern struct net_dns_job* net_dns_gethostbyname(const char* host, int af, net_dns_job_cb callback, void* ptr)
|
||||||
|
{
|
||||||
|
struct net_dns_job* job = (struct net_dns_job*) hub_malloc_zero(sizeof(struct net_dns_job));
|
||||||
|
job->host = strdup(host);
|
||||||
|
job->af = af;
|
||||||
|
job->callback = callback;
|
||||||
|
job->ptr = ptr;
|
||||||
|
|
||||||
|
#ifdef DEBUG_LOOKUP_TIME
|
||||||
|
gettimeofday(&job->time_start, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// FIXME - scheduling - what about a max number of threads?
|
||||||
|
uhub_mutex_lock(&g_dns->mutex);
|
||||||
|
job->thread_handle = uhub_thread_create(job_thread_resolve_name, job);
|
||||||
|
if (!job->thread_handle)
|
||||||
|
{
|
||||||
|
LOG_WARN("Unable to create thread");
|
||||||
|
free_job(job);
|
||||||
|
job = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
list_append(g_dns->jobs, job);
|
||||||
|
}
|
||||||
|
uhub_mutex_unlock(&g_dns->mutex);
|
||||||
|
return job;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern struct net_dns_job* net_dns_gethostbyaddr(struct ip_addr_encap* ipaddr, net_dns_job_cb callback, void* ptr)
|
||||||
|
{
|
||||||
|
struct net_dns_job* job = (struct net_dns_job*) hub_malloc_zero(sizeof(struct net_dns_job));
|
||||||
|
// job->host = strdup(addr);
|
||||||
|
job->af = ipaddr->af;
|
||||||
|
job->callback = callback;
|
||||||
|
job->ptr = ptr;
|
||||||
|
|
||||||
|
|
||||||
|
// if (pthread_create(&job->thread_handle, NULL, start_job, job))
|
||||||
|
// {
|
||||||
|
// free_job(job);
|
||||||
|
// return NULL;
|
||||||
|
// }
|
||||||
|
return job;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: mutex must be locked first!
|
||||||
|
static struct net_dns_job* find_and_remove_job(struct net_dns_job* job)
|
||||||
|
{
|
||||||
|
struct net_dns_job* it;
|
||||||
|
for (it = (struct net_dns_job*) list_get_first(g_dns->jobs); it; it = (struct net_dns_job*) list_get_next(g_dns->jobs))
|
||||||
|
{
|
||||||
|
if (it == job)
|
||||||
|
{
|
||||||
|
list_remove(g_dns->jobs, it);
|
||||||
|
return job;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: mutex must be locked first!
|
||||||
|
static struct net_dns_result* find_and_remove_result(struct net_dns_job* job)
|
||||||
|
{
|
||||||
|
struct net_dns_result* it;
|
||||||
|
for (it = (struct net_dns_result*) list_get_first(g_dns->results); it; it = (struct net_dns_result*) list_get_next(g_dns->results))
|
||||||
|
{
|
||||||
|
if (it->job == job)
|
||||||
|
{
|
||||||
|
list_remove(g_dns->results, it);
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern int net_dns_job_cancel(struct net_dns_job* job)
|
||||||
|
{
|
||||||
|
int retval = 0;
|
||||||
|
struct net_dns_result* res;
|
||||||
|
|
||||||
|
LOG_TRACE("net_dns_job_cancel(): job=%p, name=%s", job, job->host);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function looks up the job in the jobs queue (which contains only active jobs)
|
||||||
|
* If that is found then the thread is cancelled, and the object is deleted.
|
||||||
|
* If the job was not found, that is either because it was an invalid job, or because
|
||||||
|
* it was already finished. At which point it was not deleted.
|
||||||
|
* If the job is already finished, but the result has not been delivered, then this
|
||||||
|
* deletes the result and the job.
|
||||||
|
*/
|
||||||
|
uhub_mutex_lock(&g_dns->mutex);
|
||||||
|
if (find_and_remove_job(job))
|
||||||
|
{
|
||||||
|
// job still active - cancel it, then close it.
|
||||||
|
uhub_thread_cancel(job->thread_handle);
|
||||||
|
uhub_thread_join(job->thread_handle);
|
||||||
|
free_job(job);
|
||||||
|
retval = 1;
|
||||||
|
}
|
||||||
|
else if ((res = find_and_remove_result(job)))
|
||||||
|
{
|
||||||
|
// job already finished - close it.
|
||||||
|
uhub_thread_join(job->thread_handle);
|
||||||
|
net_dns_result_free(res);
|
||||||
|
}
|
||||||
|
uhub_mutex_unlock(&g_dns->mutex);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern struct net_dns_result* net_dns_job_sync_wait(struct net_dns_job* job)
|
||||||
|
{
|
||||||
|
struct net_dns_result* res = NULL;
|
||||||
|
|
||||||
|
// Wait for job to finish (if not already)
|
||||||
|
// This should make sure the job is removed from jobs and a result is
|
||||||
|
// present in results.
|
||||||
|
uhub_thread_join(job->thread_handle);
|
||||||
|
|
||||||
|
// Remove the result in order to prevent the callback from being called.
|
||||||
|
uhub_mutex_lock(&g_dns->mutex);
|
||||||
|
res = find_and_remove_result(job);
|
||||||
|
uhub_assert(res != NULL);
|
||||||
|
res->job = NULL;
|
||||||
|
free_job(job);
|
||||||
|
uhub_mutex_unlock(&g_dns->mutex);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* net_dns_job_get_ptr(const struct net_dns_job* job)
|
||||||
|
{
|
||||||
|
return job->ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern size_t net_dns_result_size(const struct net_dns_result* res)
|
||||||
|
{
|
||||||
|
return list_size(res->addr_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern struct ip_addr_encap* net_dns_result_first(const struct net_dns_result* res)
|
||||||
|
{
|
||||||
|
struct ip_addr_encap* ipaddr = list_get_first(res->addr_list);
|
||||||
|
LOG_TRACE("net_dns_result_first() - Address: %s", ip_convert_to_string(ipaddr));
|
||||||
|
return ipaddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern struct ip_addr_encap* net_dns_result_next(const struct net_dns_result* res)
|
||||||
|
{
|
||||||
|
struct ip_addr_encap* ipaddr = list_get_next(res->addr_list);
|
||||||
|
LOG_TRACE("net_dns_result_next() - Address: %s", ip_convert_to_string(ipaddr));
|
||||||
|
return ipaddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void net_dns_result_free(struct net_dns_result* res)
|
||||||
|
{
|
||||||
|
list_clear(res->addr_list, &hub_free);
|
||||||
|
list_destroy(res->addr_list);
|
||||||
|
free_job(res->job);
|
||||||
|
hub_free(res);
|
||||||
|
}
|
||||||
119
src/network/dnsresolver.h
Normal file
119
src/network/dnsresolver.h
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HAVE_UHUB_NETWORK_DNS_RESOLVER_H
|
||||||
|
#define HAVE_UHUB_NETWORK_DNS_RESOLVER_H
|
||||||
|
|
||||||
|
struct net_dns_job;
|
||||||
|
struct net_dns_result;
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/// Initialize the DNS subsystem
|
||||||
|
void net_dns_initialize();
|
||||||
|
|
||||||
|
/// Shutdown and destroy the DNS subsystem. This will cancel any pending DNS jobs.
|
||||||
|
void net_dns_destroy();
|
||||||
|
|
||||||
|
/// Process finished DNS lookups.
|
||||||
|
void net_dns_process();
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to be called when the DNS job has finished.
|
||||||
|
* If the name or address could not be resolved to an IP address (host not found, or found but has no address)
|
||||||
|
* then 'result' contains an empty list (@see net_dns_result_size()).
|
||||||
|
* If resolving caused an error then result is NULL.
|
||||||
|
*
|
||||||
|
* After this callback is called the job is considered done, and is freed.
|
||||||
|
*
|
||||||
|
* @param If 1 is returned then result is deleted immediately after the callback,
|
||||||
|
* otherwise the callback becomes owner of the result data which must be freed with net_dns_result_free().
|
||||||
|
*/
|
||||||
|
typedef int (*net_dns_job_cb)(struct net_dns_job*, const struct net_dns_result* result);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve a hostname.
|
||||||
|
*
|
||||||
|
* @param host the hostname to be resolved.
|
||||||
|
* @param af the indicated address family. Should be AF_INET, AF_INET6 (or AF_UNSPEC - which means both AF_INET and AF_INET6.
|
||||||
|
* @param callback the callback to be called when the hostname has been resolved.
|
||||||
|
* @param ptr A user-defined pointer value.
|
||||||
|
*
|
||||||
|
* @return A resolve job handle if the job has successfully started or NULL if unable to start resolving.
|
||||||
|
*/
|
||||||
|
extern struct net_dns_job* net_dns_gethostbyname(const char* host, int af, net_dns_job_cb callback, void* ptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform a reverse DNS lookup for a given IP address.
|
||||||
|
*
|
||||||
|
* @see net_dns_gethostbyname()
|
||||||
|
* @return A resolve job handle if the job has successfully started or NULL if unable to start resolving.
|
||||||
|
*/
|
||||||
|
extern struct net_dns_job* net_dns_gethostbyaddr(struct ip_addr_encap* ipaddr, net_dns_job_cb callback, void* ptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel a DNS lookup job.
|
||||||
|
*
|
||||||
|
* It is only allowed to call this once after a job has been started (@see net_dns_gethostbyname(), @see net_dns_gethostbyaddr())
|
||||||
|
* but before it has finished and delivered a to the callback address (@see net_dns_job_cb).
|
||||||
|
*
|
||||||
|
* @returns 1 if cancelled, or 0 if not cancelled (because the job was not found!)
|
||||||
|
*/
|
||||||
|
extern int net_dns_job_cancel(struct net_dns_job* job);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait in a synchronous manner for a running DNS job to finished and
|
||||||
|
* return the result here.
|
||||||
|
* The job must be started with net_dns_gethostbyaddr/net_dns_gethostbyname
|
||||||
|
* and not finished or cancelled.
|
||||||
|
*
|
||||||
|
* If this function is invoked then the callback function will not be called and
|
||||||
|
* can therefore be NULL.
|
||||||
|
*
|
||||||
|
* <code>
|
||||||
|
* struct net_dns_job* job = net_dns_gethostbyname("www.example.com", AF_INET, NULL, NULL);
|
||||||
|
* struct net_dns_result* net_dns_job_sync_wait(job);
|
||||||
|
* </code>
|
||||||
|
*/
|
||||||
|
extern struct net_dns_result* net_dns_job_sync_wait(struct net_dns_job* job);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the user specified pointer assigned to the resolving job
|
||||||
|
*/
|
||||||
|
extern void* net_dns_job_get_ptr(const struct net_dns_job* job);
|
||||||
|
|
||||||
|
/// Returns the number of results provided. This is 0 if the host could not be found (or has no matching IP address).
|
||||||
|
extern size_t net_dns_result_size(const struct net_dns_result*);
|
||||||
|
|
||||||
|
/// Returns the first result (if net_dns_result_size > 0), or NULL if not first result exists.
|
||||||
|
extern struct ip_addr_encap* net_dns_result_first(const struct net_dns_result*);
|
||||||
|
|
||||||
|
/// Returns the next result or NULL if no next result exists.
|
||||||
|
extern struct ip_addr_encap* net_dns_result_next(const struct net_dns_result*);
|
||||||
|
|
||||||
|
/// When finished with the results
|
||||||
|
extern void net_dns_result_free(struct net_dns_result*);
|
||||||
|
|
||||||
|
#endif /* HAVE_UHUB_NETWORK_DNS_RESOLVER_H */
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -49,21 +49,21 @@ int net_initialize()
|
|||||||
}
|
}
|
||||||
#endif /* WINSOCK */
|
#endif /* WINSOCK */
|
||||||
|
|
||||||
if (!net_backend_init())
|
if (!net_backend_init()
|
||||||
|
#ifdef SSL_SUPPORT
|
||||||
|
|| !net_ssl_library_init()
|
||||||
|
#endif
|
||||||
|
)
|
||||||
{
|
{
|
||||||
#ifdef WINSOCK
|
#ifdef WINSOCK
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
#endif
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
net_dns_initialize();
|
||||||
|
|
||||||
net_stats_initialize();
|
net_stats_initialize();
|
||||||
|
|
||||||
#ifdef SSL_SUPPORT
|
|
||||||
LOG_TRACE("Initializing OpenSSL...");
|
|
||||||
SSL_library_init();
|
|
||||||
SSL_load_error_strings();
|
|
||||||
#endif /* SSL_SUPPORT */
|
|
||||||
|
|
||||||
net_initialized = 1;
|
net_initialized = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -97,13 +97,13 @@ int net_destroy()
|
|||||||
{
|
{
|
||||||
LOG_TRACE("Shutting down network monitor");
|
LOG_TRACE("Shutting down network monitor");
|
||||||
|
|
||||||
|
net_dns_destroy();
|
||||||
|
|
||||||
net_backend_shutdown();
|
net_backend_shutdown();
|
||||||
|
|
||||||
#ifdef SSL_SUPPORT
|
#ifdef SSL_SUPPORT
|
||||||
ERR_free_strings();
|
net_ssl_library_shutdown();
|
||||||
EVP_cleanup();
|
#endif /* SSL_SUPPORT */
|
||||||
CRYPTO_cleanup_all_ex_data();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef WINSOCK
|
#ifdef WINSOCK
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
@@ -495,7 +495,6 @@ int net_socket_create(int af, int type, int protocol)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return sd;
|
return sd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -31,6 +31,7 @@ struct net_statistics
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct net_socket_t;
|
struct net_socket_t;
|
||||||
|
struct ip_addr_encap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the socket monitor subsystem.
|
* Initialize the socket monitor subsystem.
|
||||||
|
|||||||
351
src/network/openssl.c
Normal file
351
src/network/openssl.c
Normal file
@@ -0,0 +1,351 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uhub.h"
|
||||||
|
#include "network/common.h"
|
||||||
|
#include "network/tls.h"
|
||||||
|
|
||||||
|
#ifdef SSL_SUPPORT
|
||||||
|
#ifdef SSL_USE_OPENSSL
|
||||||
|
|
||||||
|
void net_stats_add_tx(size_t bytes);
|
||||||
|
void net_stats_add_rx(size_t bytes);
|
||||||
|
|
||||||
|
struct net_ssl_openssl
|
||||||
|
{
|
||||||
|
SSL* ssl;
|
||||||
|
BIO* bio;
|
||||||
|
enum ssl_state state;
|
||||||
|
uint32_t flags;
|
||||||
|
size_t bytes_rx;
|
||||||
|
size_t bytes_tx;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct net_context_openssl
|
||||||
|
{
|
||||||
|
SSL_METHOD* ssl_method;
|
||||||
|
SSL_CTX* ssl_ctx;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct net_ssl_openssl* get_handle(struct net_connection* con)
|
||||||
|
{
|
||||||
|
uhub_assert(con);
|
||||||
|
return (struct net_ssl_openssl*) con->ssl;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* net_ssl_get_provider()
|
||||||
|
{
|
||||||
|
return OPENSSL_VERSION_TEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
int net_ssl_library_init()
|
||||||
|
{
|
||||||
|
LOG_TRACE("Initializing OpenSSL...");
|
||||||
|
SSL_library_init();
|
||||||
|
SSL_load_error_strings();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int net_ssl_library_shutdown()
|
||||||
|
{
|
||||||
|
ERR_clear_error();
|
||||||
|
ERR_remove_state(0);
|
||||||
|
|
||||||
|
ENGINE_cleanup();
|
||||||
|
CONF_modules_unload(1);
|
||||||
|
|
||||||
|
ERR_free_strings();
|
||||||
|
EVP_cleanup();
|
||||||
|
CRYPTO_cleanup_all_ex_data();
|
||||||
|
|
||||||
|
// sk_SSL_COMP_free(SSL_COMP_get_compression_methods());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_io_stats(struct net_ssl_openssl* handle)
|
||||||
|
{
|
||||||
|
if (handle->bio->num_read > handle->bytes_rx)
|
||||||
|
{
|
||||||
|
net_stats_add_rx(handle->bio->num_read - handle->bytes_rx);
|
||||||
|
handle->bytes_rx = handle->bio->num_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handle->bio->num_write > handle->bytes_tx)
|
||||||
|
{
|
||||||
|
net_stats_add_tx(handle->bio->num_write - handle->bytes_tx);
|
||||||
|
handle->bytes_tx = handle->bio->num_write;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new SSL context.
|
||||||
|
*/
|
||||||
|
struct ssl_context_handle* net_ssl_context_create()
|
||||||
|
{
|
||||||
|
|
||||||
|
struct net_context_openssl* ctx = (struct net_context_openssl*) hub_malloc_zero(sizeof(struct net_context_openssl));
|
||||||
|
ctx->ssl_method = (SSL_METHOD*) SSLv23_method(); /* TLSv1_method() */
|
||||||
|
ctx->ssl_ctx = SSL_CTX_new(ctx->ssl_method);
|
||||||
|
|
||||||
|
/* Disable SSLv2 */
|
||||||
|
SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv2);
|
||||||
|
|
||||||
|
#ifdef SSL_OP_NO_COMPRESSION
|
||||||
|
/* Disable compression? */
|
||||||
|
LOG_TRACE("Disabling SSL compression."); /* "CRIME" attack */
|
||||||
|
SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_COMPRESSION);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SSL_CTX_set_quiet_shutdown(ctx->ssl_ctx, 1);
|
||||||
|
|
||||||
|
return (struct ssl_context_handle*) ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void net_ssl_context_destroy(struct ssl_context_handle* ctx_)
|
||||||
|
{
|
||||||
|
struct net_context_openssl* ctx = (struct net_context_openssl*) ctx_;
|
||||||
|
SSL_CTX_free(ctx->ssl_ctx);
|
||||||
|
hub_free(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ssl_load_certificate(struct ssl_context_handle* ctx_, const char* pem_file)
|
||||||
|
{
|
||||||
|
struct net_context_openssl* ctx = (struct net_context_openssl*) ctx_;
|
||||||
|
if (SSL_CTX_use_certificate_file(ctx->ssl_ctx, pem_file, SSL_FILETYPE_PEM) < 0)
|
||||||
|
{
|
||||||
|
LOG_ERROR("SSL_CTX_use_certificate_file: %s", ERR_error_string(ERR_get_error(), NULL));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ssl_load_private_key(struct ssl_context_handle* ctx_, const char* pem_file)
|
||||||
|
{
|
||||||
|
struct net_context_openssl* ctx = (struct net_context_openssl*) ctx_;
|
||||||
|
if (SSL_CTX_use_PrivateKey_file(ctx->ssl_ctx, pem_file, SSL_FILETYPE_PEM) < 0)
|
||||||
|
{
|
||||||
|
LOG_ERROR("SSL_CTX_use_PrivateKey_file: %s", ERR_error_string(ERR_get_error(), NULL));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ssl_check_private_key(struct ssl_context_handle* ctx_)
|
||||||
|
{
|
||||||
|
struct net_context_openssl* ctx = (struct net_context_openssl*) ctx_;
|
||||||
|
if (SSL_CTX_check_private_key(ctx->ssl_ctx) != 1)
|
||||||
|
{
|
||||||
|
LOG_FATAL("SSL_CTX_check_private_key: Private key does not match the certificate public key: %s", ERR_error_string(ERR_get_error(), NULL));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int handle_openssl_error(struct net_connection* con, int ret, enum ssl_state forced_rwstate)
|
||||||
|
{
|
||||||
|
struct net_ssl_openssl* handle = get_handle(con);
|
||||||
|
int err = SSL_get_error(handle->ssl, ret);
|
||||||
|
switch (err)
|
||||||
|
{
|
||||||
|
case SSL_ERROR_ZERO_RETURN:
|
||||||
|
// Not really an error, but SSL was shut down.
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
case SSL_ERROR_WANT_READ:
|
||||||
|
handle->state = forced_rwstate;
|
||||||
|
net_con_update(con, NET_EVENT_READ);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case SSL_ERROR_WANT_WRITE:
|
||||||
|
handle->state = forced_rwstate;
|
||||||
|
net_con_update(con, NET_EVENT_WRITE);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case SSL_ERROR_SYSCALL:
|
||||||
|
handle->state = tls_st_error;
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t net_con_ssl_accept(struct net_connection* con)
|
||||||
|
{
|
||||||
|
struct net_ssl_openssl* handle = get_handle(con);
|
||||||
|
handle->state = tls_st_accepting;
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
|
ret = SSL_accept(handle->ssl);
|
||||||
|
LOG_PROTO("SSL_accept() ret=%d", ret);
|
||||||
|
if (ret > 0)
|
||||||
|
{
|
||||||
|
net_con_update(con, NET_EVENT_READ);
|
||||||
|
handle->state = tls_st_connected;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return handle_openssl_error(con, ret, tls_st_accepting);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t net_con_ssl_connect(struct net_connection* con)
|
||||||
|
{
|
||||||
|
struct net_ssl_openssl* handle = get_handle(con);
|
||||||
|
ssize_t ret;
|
||||||
|
handle->state = tls_st_connecting;
|
||||||
|
|
||||||
|
ret = SSL_connect(handle->ssl);
|
||||||
|
LOG_PROTO("SSL_connect() ret=%d", ret);
|
||||||
|
|
||||||
|
if (ret > 0)
|
||||||
|
{
|
||||||
|
handle->state = tls_st_connected;
|
||||||
|
net_con_update(con, NET_EVENT_READ);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return handle_openssl_error(con, ret, tls_st_connecting);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode ssl_mode, struct ssl_context_handle* ssl_ctx)
|
||||||
|
{
|
||||||
|
uhub_assert(con);
|
||||||
|
|
||||||
|
struct net_context_openssl* ctx = (struct net_context_openssl*) ssl_ctx;
|
||||||
|
struct net_ssl_openssl* handle = (struct net_ssl_openssl*) hub_malloc_zero(sizeof(struct net_ssl_openssl));
|
||||||
|
|
||||||
|
if (ssl_mode == net_con_ssl_mode_server)
|
||||||
|
{
|
||||||
|
handle->ssl = SSL_new(ctx->ssl_ctx);
|
||||||
|
if (!handle->ssl)
|
||||||
|
{
|
||||||
|
LOG_ERROR("Unable to create new SSL stream\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
SSL_set_fd(handle->ssl, con->sd);
|
||||||
|
handle->bio = SSL_get_rbio(handle->ssl);
|
||||||
|
con->ssl = (struct ssl_handle*) handle;
|
||||||
|
return net_con_ssl_accept(con);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
handle->ssl = SSL_new(SSL_CTX_new(TLSv1_method()));
|
||||||
|
SSL_set_fd(handle->ssl, con->sd);
|
||||||
|
handle->bio = SSL_get_rbio(handle->ssl);
|
||||||
|
con->ssl = (struct ssl_handle*) handle;
|
||||||
|
return net_con_ssl_connect(con);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t net_ssl_send(struct net_connection* con, const void* buf, size_t len)
|
||||||
|
{
|
||||||
|
struct net_ssl_openssl* handle = get_handle(con);
|
||||||
|
|
||||||
|
uhub_assert(handle->state == tls_st_connected || handle->state == tls_st_need_write);
|
||||||
|
|
||||||
|
ERR_clear_error();
|
||||||
|
ssize_t ret = SSL_write(handle->ssl, buf, len);
|
||||||
|
add_io_stats(handle);
|
||||||
|
LOG_PROTO("SSL_write(con=%p, buf=%p, len=" PRINTF_SIZE_T ") => %d", con, buf, len, ret);
|
||||||
|
if (ret > 0)
|
||||||
|
{
|
||||||
|
handle->state = tls_st_connected;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return handle_openssl_error(con, ret, tls_st_need_write);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t net_ssl_recv(struct net_connection* con, void* buf, size_t len)
|
||||||
|
{
|
||||||
|
struct net_ssl_openssl* handle = get_handle(con);
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
|
if (handle->state == tls_st_error)
|
||||||
|
return -2;
|
||||||
|
|
||||||
|
uhub_assert(handle->state == tls_st_connected || handle->state == tls_st_need_read);
|
||||||
|
|
||||||
|
ERR_clear_error();
|
||||||
|
|
||||||
|
ret = SSL_read(handle->ssl, buf, len);
|
||||||
|
add_io_stats(handle);
|
||||||
|
LOG_PROTO("SSL_read(con=%p, buf=%p, len=" PRINTF_SIZE_T ") => %d", con, buf, len, ret);
|
||||||
|
if (ret > 0)
|
||||||
|
{
|
||||||
|
handle->state = tls_st_connected;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return handle_openssl_error(con, ret, tls_st_need_read);
|
||||||
|
}
|
||||||
|
|
||||||
|
void net_ssl_shutdown(struct net_connection* con)
|
||||||
|
{
|
||||||
|
struct net_ssl_openssl* handle = get_handle(con);
|
||||||
|
SSL_shutdown(handle->ssl);
|
||||||
|
SSL_clear(handle->ssl);
|
||||||
|
}
|
||||||
|
|
||||||
|
void net_ssl_destroy(struct net_connection* con)
|
||||||
|
{
|
||||||
|
struct net_ssl_openssl* handle = get_handle(con);
|
||||||
|
SSL_free(handle->ssl);
|
||||||
|
}
|
||||||
|
|
||||||
|
void net_ssl_callback(struct net_connection* con, int events)
|
||||||
|
{
|
||||||
|
struct net_ssl_openssl* handle = get_handle(con);
|
||||||
|
|
||||||
|
switch (handle->state)
|
||||||
|
{
|
||||||
|
case tls_st_none:
|
||||||
|
con->callback(con, events, con->ptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tls_st_error:
|
||||||
|
con->callback(con, NET_EVENT_READ, con->ptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tls_st_accepting:
|
||||||
|
if (net_con_ssl_accept(con) != 0)
|
||||||
|
con->callback(con, NET_EVENT_READ, con->ptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tls_st_connecting:
|
||||||
|
if (net_con_ssl_connect(con) != 0)
|
||||||
|
con->callback(con, NET_EVENT_READ, con->ptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tls_st_need_read:
|
||||||
|
con->callback(con, NET_EVENT_READ, con->ptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tls_st_need_write:
|
||||||
|
con->callback(con, NET_EVENT_WRITE, con->ptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tls_st_connected:
|
||||||
|
con->callback(con, events, con->ptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tls_st_disconnecting:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* SSL_USE_OPENSSL */
|
||||||
|
#endif /* SSL_SUPPORT */
|
||||||
|
|
||||||
104
src/network/tls.h
Normal file
104
src/network/tls.h
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HAVE_UHUB_NETWORK_TLS_H
|
||||||
|
#define HAVE_UHUB_NETWORK_TLS_H
|
||||||
|
|
||||||
|
#include "uhub.h"
|
||||||
|
|
||||||
|
#ifdef SSL_SUPPORT
|
||||||
|
|
||||||
|
|
||||||
|
enum ssl_state
|
||||||
|
{
|
||||||
|
tls_st_none,
|
||||||
|
tls_st_error,
|
||||||
|
tls_st_accepting,
|
||||||
|
tls_st_connecting,
|
||||||
|
tls_st_connected,
|
||||||
|
tls_st_need_read, /* special case of connected */
|
||||||
|
tls_st_need_write, /* special case of connected */
|
||||||
|
tls_st_disconnecting,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum net_con_ssl_mode
|
||||||
|
{
|
||||||
|
net_con_ssl_mode_server,
|
||||||
|
net_con_ssl_mode_client,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ssl_context_handle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string describing the TLS/SSL provider information
|
||||||
|
*/
|
||||||
|
extern const char* net_ssl_get_provider();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return 0 if error, 1 on success.
|
||||||
|
*/
|
||||||
|
extern int net_ssl_library_init();
|
||||||
|
extern int net_ssl_library_shutdown();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new SSL context.
|
||||||
|
*/
|
||||||
|
extern struct ssl_context_handle* net_ssl_context_create();
|
||||||
|
extern void net_ssl_context_destroy(struct ssl_context_handle* ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return 0 on error, 1 otherwise.
|
||||||
|
*/
|
||||||
|
extern int ssl_load_certificate(struct ssl_context_handle* ctx, const char* pem_file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return 0 on error, 1 otherwise.
|
||||||
|
*/
|
||||||
|
extern int ssl_load_private_key(struct ssl_context_handle* ctx, const char* pem_file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return 0 if private key does not match certificate, 1 if everything is OK.
|
||||||
|
*/
|
||||||
|
extern int ssl_check_private_key(struct ssl_context_handle* ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start SSL_accept()
|
||||||
|
*/
|
||||||
|
extern ssize_t net_con_ssl_accept(struct net_connection*);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start SSL_connect()
|
||||||
|
*/
|
||||||
|
extern ssize_t net_con_ssl_connect(struct net_connection*);
|
||||||
|
|
||||||
|
extern ssize_t net_ssl_send(struct net_connection* con, const void* buf, size_t len);
|
||||||
|
extern ssize_t net_ssl_recv(struct net_connection* con, void* buf, size_t len);
|
||||||
|
|
||||||
|
extern void net_ssl_shutdown(struct net_connection* con);
|
||||||
|
extern void net_ssl_destroy(struct net_connection* con);
|
||||||
|
extern void net_ssl_callback(struct net_connection* con, int events);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode, struct ssl_context_handle* ssl_ctx);
|
||||||
|
extern int net_con_is_ssl(struct net_connection* con);
|
||||||
|
|
||||||
|
#endif /* SSL_SUPPORT */
|
||||||
|
#endif /* HAVE_UHUB_NETWORK_TLS_H */
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include "util/credentials.h"
|
#include "util/credentials.h"
|
||||||
#include "util/ipcalc.h"
|
#include "network/ipcalc.h"
|
||||||
#include "plugin_api/types.h"
|
#include "plugin_api/types.h"
|
||||||
|
|
||||||
typedef void (*on_connection_accepted_t)(struct plugin_handle*, struct ip_addr_encap*);
|
typedef void (*on_connection_accepted_t)(struct plugin_handle*, struct ip_addr_encap*);
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
#include "plugin_api/handle.h"
|
#include "plugin_api/handle.h"
|
||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
#include "util/list.h"
|
#include "util/list.h"
|
||||||
#include "util/ipcalc.h"
|
|
||||||
#include "util/misc.h"
|
#include "util/misc.h"
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
#include "util/config_token.h"
|
#include "util/config_token.h"
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
#include <sqlite3.h>
|
#include <sqlite3.h>
|
||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
#include "util/list.h"
|
#include "util/list.h"
|
||||||
#include "util/ipcalc.h"
|
|
||||||
#include "util/misc.h"
|
#include "util/misc.h"
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
#include "util/config_token.h"
|
#include "util/config_token.h"
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ static size_t get_messages(struct chat_history_data* data, size_t num, struct cb
|
|||||||
char* message;
|
char* message;
|
||||||
int skiplines = 0;
|
int skiplines = 0;
|
||||||
size_t lines = 0;
|
size_t lines = 0;
|
||||||
int total = list_size(messages);
|
size_t total = list_size(messages);
|
||||||
|
|
||||||
if (total == 0)
|
if (total == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -64,13 +64,13 @@ static struct user_info* get_user_info(struct chat_only_data* data, sid_t sid)
|
|||||||
struct user_info* u;
|
struct user_info* u;
|
||||||
|
|
||||||
// resize buffer if needed.
|
// resize buffer if needed.
|
||||||
if (sid > data->max_users) // FIXME: >= ?
|
if (sid >= data->max_users)
|
||||||
{
|
{
|
||||||
u = hub_malloc_zero(sizeof(struct user_info) * (sid + 1));
|
u = hub_malloc_zero(sizeof(struct user_info) * (sid + 1));
|
||||||
memcpy(u, data->users, data->max_users);
|
memcpy(u, data->users, data->max_users);
|
||||||
hub_free(data->users);
|
hub_free(data->users);
|
||||||
data->users = u;
|
data->users = u;
|
||||||
data->max_users = sid;
|
data->max_users = sid + 1;
|
||||||
u = NULL;
|
u = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2011, Jan Vidar Krey
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -21,12 +21,14 @@
|
|||||||
#include "adc/adcconst.h"
|
#include "adc/adcconst.h"
|
||||||
#include "adc/sid.h"
|
#include "adc/sid.h"
|
||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
#include "util/ipcalc.h"
|
#include "network/ipcalc.h"
|
||||||
#include "plugin_api/handle.h"
|
#include "plugin_api/handle.h"
|
||||||
|
|
||||||
#include "util/misc.h"
|
#include "util/misc.h"
|
||||||
#include "util/config_token.h"
|
#include "util/config_token.h"
|
||||||
|
#ifndef WIN32
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
struct ip_addr_encap;
|
struct ip_addr_encap;
|
||||||
|
|
||||||
@@ -60,11 +62,13 @@ static int log_open_file(struct plugin_handle* plugin, struct log_data* data)
|
|||||||
return (data->fd != -1);
|
return (data->fd != -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
static int log_open_syslog(struct plugin_handle* plugin)
|
static int log_open_syslog(struct plugin_handle* plugin)
|
||||||
{
|
{
|
||||||
openlog("uhub", 0, LOG_USER);
|
openlog("uhub", 0, LOG_USER);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct log_data* parse_config(const char* line, struct plugin_handle* plugin)
|
static struct log_data* parse_config(const char* line, struct plugin_handle* plugin)
|
||||||
{
|
{
|
||||||
@@ -94,6 +98,7 @@ static struct log_data* parse_config(const char* line, struct plugin_handle* plu
|
|||||||
data->logfile = strdup(cfg_settings_get_value(setting));
|
data->logfile = strdup(cfg_settings_get_value(setting));
|
||||||
data->logmode = mode_file;
|
data->logmode = mode_file;
|
||||||
}
|
}
|
||||||
|
#ifndef WIN32
|
||||||
else if (strcmp(cfg_settings_get_key(setting), "syslog") == 0)
|
else if (strcmp(cfg_settings_get_key(setting), "syslog") == 0)
|
||||||
{
|
{
|
||||||
int use_syslog = 0;
|
int use_syslog = 0;
|
||||||
@@ -102,6 +107,7 @@ static struct log_data* parse_config(const char* line, struct plugin_handle* plu
|
|||||||
data->logmode = (use_syslog) ? mode_syslog : mode_file;
|
data->logmode = (use_syslog) ? mode_syslog : mode_file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
set_error_message(plugin, "Unknown startup parameters given");
|
set_error_message(plugin, "Unknown startup parameters given");
|
||||||
@@ -134,6 +140,7 @@ static struct log_data* parse_config(const char* line, struct plugin_handle* plu
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifndef WIN32
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!log_open_syslog(plugin))
|
if (!log_open_syslog(plugin))
|
||||||
@@ -144,7 +151,7 @@ static struct log_data* parse_config(const char* line, struct plugin_handle* plu
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,10 +162,12 @@ static void log_close(struct log_data* data)
|
|||||||
hub_free(data->logfile);
|
hub_free(data->logfile);
|
||||||
close(data->fd);
|
close(data->fd);
|
||||||
}
|
}
|
||||||
|
#ifndef WIN32
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
closelog();
|
closelog();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
hub_free(data);
|
hub_free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,19 +195,25 @@ static void log_message(struct log_data* data, const char *format, ...)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
_commit(data->fd);
|
||||||
|
#else
|
||||||
#if defined _POSIX_SYNCHRONIZED_IO && _POSIX_SYNCHRONIZED_IO > 0
|
#if defined _POSIX_SYNCHRONIZED_IO && _POSIX_SYNCHRONIZED_IO > 0
|
||||||
fdatasync(data->fd);
|
fdatasync(data->fd);
|
||||||
#else
|
#else
|
||||||
fsync(data->fd);
|
fsync(data->fd);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifndef WIN32
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
vsyslog(LOG_INFO, format, args);
|
vsyslog(LOG_INFO, format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void log_user_login(struct plugin_handle* plugin, struct plugin_user* user)
|
static void log_user_login(struct plugin_handle* plugin, struct plugin_user* user)
|
||||||
|
|||||||
60
src/plugins/mod_no_guest_downloads.c
Normal file
60
src/plugins/mod_no_guest_downloads.c
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "plugin_api/handle.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
|
||||||
|
static plugin_st on_search_result(struct plugin_handle* plugin, struct plugin_user* from, struct plugin_user* to, const char* search_data)
|
||||||
|
{
|
||||||
|
if (to->credentials >= auth_cred_user)
|
||||||
|
return st_default;
|
||||||
|
return st_deny;
|
||||||
|
}
|
||||||
|
|
||||||
|
static plugin_st on_search(struct plugin_handle* plugin, struct plugin_user* user, const char* search_data)
|
||||||
|
{
|
||||||
|
// Registered users are allowed to search.
|
||||||
|
if (user->credentials >= auth_cred_user)
|
||||||
|
return st_default;
|
||||||
|
return st_deny;
|
||||||
|
}
|
||||||
|
|
||||||
|
static plugin_st on_p2p_connect(struct plugin_handle* plugin, struct plugin_user* from, struct plugin_user* to)
|
||||||
|
{
|
||||||
|
if (from->credentials >= auth_cred_user)
|
||||||
|
return st_default;
|
||||||
|
return st_deny;
|
||||||
|
}
|
||||||
|
|
||||||
|
int plugin_register(struct plugin_handle* plugin, const char* config)
|
||||||
|
{
|
||||||
|
PLUGIN_INITIALIZE(plugin, "No guest downloading", "0.1", "This plug-in only allows registered users to search and initiate transfers.");
|
||||||
|
plugin->ptr = NULL;
|
||||||
|
plugin->funcs.on_search = on_search;
|
||||||
|
plugin->funcs.on_search_result = on_search_result;
|
||||||
|
plugin->funcs.on_p2p_connect = on_p2p_connect;
|
||||||
|
// plugin->funcs.on_p2p_revconnect = on_p2p_connect;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int plugin_unregister(struct plugin_handle* plugin)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -22,13 +22,12 @@
|
|||||||
#include "adc/sid.h"
|
#include "adc/sid.h"
|
||||||
#include "util/cbuffer.h"
|
#include "util/cbuffer.h"
|
||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
#include "util/ipcalc.h"
|
#include "network/ipcalc.h"
|
||||||
#include "plugin_api/handle.h"
|
#include "plugin_api/handle.h"
|
||||||
#include "plugin_api/command_api.h"
|
#include "plugin_api/command_api.h"
|
||||||
|
|
||||||
#include "util/misc.h"
|
#include "util/misc.h"
|
||||||
#include "util/config_token.h"
|
#include "util/config_token.h"
|
||||||
#include <syslog.h>
|
|
||||||
|
|
||||||
#define MAX_WELCOME_SIZE 16384
|
#define MAX_WELCOME_SIZE 16384
|
||||||
|
|
||||||
|
|||||||
19
src/system.h
19
src/system.h
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2009, Jan Vidar Krey
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -34,6 +34,7 @@
|
|||||||
#ifndef WINSOCK
|
#ifndef WINSOCK
|
||||||
#define WINSOCK
|
#define WINSOCK
|
||||||
#endif
|
#endif
|
||||||
|
#define WINTHREAD_SUPPORT 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__CYGWIN__) || defined(__MINGW32__)
|
#if defined(__CYGWIN__) || defined(__MINGW32__)
|
||||||
@@ -99,20 +100,27 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SSL_SUPPORT
|
#ifdef SSL_SUPPORT
|
||||||
|
#ifdef SSL_USE_OPENSSL
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
|
#endif /* SSL_USE_OPENSSL */
|
||||||
|
#ifdef SSL_USE_GNUTLS
|
||||||
|
#include <gnutls/gnutls.h>
|
||||||
|
#endif /* SSL_USE_GNUTLS */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "../version.h"
|
#include "version.h"
|
||||||
|
|
||||||
#define uhub_assert assert
|
#define uhub_assert assert
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|
#define POSIX_THREAD_SUPPORT
|
||||||
#define USE_EPOLL
|
#define USE_EPOLL
|
||||||
#include <sys/epoll.h>
|
#include <sys/epoll.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BSD_LIKE
|
#ifdef BSD_LIKE
|
||||||
|
#define POSIX_THREAD_SUPPORT
|
||||||
/*
|
/*
|
||||||
#define USE_KQUEUE
|
#define USE_KQUEUE
|
||||||
#include <sys/event.h>
|
#include <sys/event.h>
|
||||||
@@ -124,7 +132,7 @@
|
|||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(BSD_LIKE) || defined(__sun__)
|
#if ( defined(BSD_LIKE) && !defined(__FreeBSD_kernel__) ) || defined(__sun__)
|
||||||
#undef HAVE_STRNDUP
|
#undef HAVE_STRNDUP
|
||||||
#undef HAVE_MEMMEM
|
#undef HAVE_MEMMEM
|
||||||
#endif
|
#endif
|
||||||
@@ -270,9 +278,14 @@ typedef unsigned __int64 uint64_t;
|
|||||||
#define open _open
|
#define open _open
|
||||||
#define close _close
|
#define close _close
|
||||||
#define read _read
|
#define read _read
|
||||||
|
#define write _write
|
||||||
#define NEED_GETOPT
|
#define NEED_GETOPT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef POSIX_THREAD_SUPPORT
|
||||||
|
#include <pthread.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(_MSC_VER)
|
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(_MSC_VER)
|
||||||
#define PLUGIN_API __declspec(dllexport)
|
#define PLUGIN_API __declspec(dllexport)
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2011, Jan Vidar Krey
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -23,7 +23,59 @@
|
|||||||
#define ADC_CID_SIZE 39
|
#define ADC_CID_SIZE 39
|
||||||
#define BIG_BUFSIZE 32768
|
#define BIG_BUFSIZE 32768
|
||||||
#define TIGERSIZE 24
|
#define TIGERSIZE 24
|
||||||
|
#define MAX_RECV_BUFFER 65536
|
||||||
|
|
||||||
// #define ADCC_DEBUG
|
// #define ADCC_DEBUG
|
||||||
|
// #define ADC_CLIENT_DEBUG_PROTO
|
||||||
|
enum ADC_client_state
|
||||||
|
{
|
||||||
|
ps_none, /* Not connected */
|
||||||
|
ps_dns, /* looking up name */
|
||||||
|
ps_conn, /* Connecting... */
|
||||||
|
ps_conn_ssl, /* SSL handshake */
|
||||||
|
ps_protocol, /* Have sent HSUP */
|
||||||
|
ps_identify, /* Have sent BINF */
|
||||||
|
ps_verify, /* Have sent HPAS */
|
||||||
|
ps_normal, /* Are fully logged in */
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ADC_client_flags
|
||||||
|
{
|
||||||
|
cflag_none = 0,
|
||||||
|
cflag_ssl = 1,
|
||||||
|
cflag_choke = 2,
|
||||||
|
cflag_pipe = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ADC_client_address
|
||||||
|
{
|
||||||
|
enum Protocol { ADC, ADCS } protocol;
|
||||||
|
char* hostname;
|
||||||
|
uint16_t port;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ADC_client
|
||||||
|
{
|
||||||
|
sid_t sid;
|
||||||
|
enum ADC_client_state state;
|
||||||
|
struct adc_message* info;
|
||||||
|
struct ioq_recv* recv_queue;
|
||||||
|
struct ioq_send* send_queue;
|
||||||
|
adc_client_cb callback;
|
||||||
|
size_t s_offset;
|
||||||
|
size_t r_offset;
|
||||||
|
size_t timeout;
|
||||||
|
struct net_connection* con;
|
||||||
|
struct net_timer* timer;
|
||||||
|
struct sockaddr_storage addr;
|
||||||
|
struct net_dns_job* dns_job;
|
||||||
|
struct ADC_client_address address;
|
||||||
|
char* nick;
|
||||||
|
char* desc;
|
||||||
|
int flags;
|
||||||
|
void* ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static ssize_t ADC_client_recv(struct ADC_client* client);
|
static ssize_t ADC_client_recv(struct ADC_client* client);
|
||||||
static void ADC_client_send_info(struct ADC_client* client);
|
static void ADC_client_send_info(struct ADC_client* client);
|
||||||
@@ -34,7 +86,8 @@ static void ADC_client_on_connected_ssl(struct ADC_client* client);
|
|||||||
static void ADC_client_on_disconnected(struct ADC_client* client);
|
static void ADC_client_on_disconnected(struct ADC_client* client);
|
||||||
static void ADC_client_on_login(struct ADC_client* client);
|
static void ADC_client_on_login(struct ADC_client* client);
|
||||||
static int ADC_client_parse_address(struct ADC_client* client, const char* arg);
|
static int ADC_client_parse_address(struct ADC_client* client, const char* arg);
|
||||||
static void ADC_client_on_recv_line(struct ADC_client* client, const char* line, size_t length);
|
static int ADC_client_on_recv_line(struct ADC_client* client, const char* line, size_t length);
|
||||||
|
static int ADC_client_send_queue(struct ADC_client* client);
|
||||||
|
|
||||||
static void ADC_client_debug(struct ADC_client* client, const char* format, ...)
|
static void ADC_client_debug(struct ADC_client* client, const char* format, ...)
|
||||||
{
|
{
|
||||||
@@ -56,6 +109,7 @@ static void ADC_client_debug(struct ADC_client* client, const char* format, ...)
|
|||||||
static const char* ADC_client_state_string[] =
|
static const char* ADC_client_state_string[] =
|
||||||
{
|
{
|
||||||
"ps_none",
|
"ps_none",
|
||||||
|
"ps_dns",
|
||||||
"ps_conn",
|
"ps_conn",
|
||||||
"ps_conn_ssl",
|
"ps_conn_ssl",
|
||||||
"ps_protocol",
|
"ps_protocol",
|
||||||
@@ -110,6 +164,9 @@ static void event_callback(struct net_connection* con, int events, void *arg)
|
|||||||
|
|
||||||
switch (client->state)
|
switch (client->state)
|
||||||
{
|
{
|
||||||
|
case ps_dns:
|
||||||
|
break;
|
||||||
|
|
||||||
case ps_conn:
|
case ps_conn:
|
||||||
if (events == NET_EVENT_TIMEOUT)
|
if (events == NET_EVENT_TIMEOUT)
|
||||||
{
|
{
|
||||||
@@ -118,7 +175,7 @@ static void event_callback(struct net_connection* con, int events, void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (events & NET_EVENT_WRITE)
|
if (events & NET_EVENT_WRITE)
|
||||||
ADC_client_connect(client, 0);
|
ADC_client_connect_internal(client);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef SSL_SUPPORT
|
#ifdef SSL_SUPPORT
|
||||||
@@ -144,7 +201,7 @@ static void event_callback(struct net_connection* con, int events, void *arg)
|
|||||||
|
|
||||||
if (events & NET_EVENT_WRITE)
|
if (events & NET_EVENT_WRITE)
|
||||||
{
|
{
|
||||||
/* FIXME: Call send again */
|
ADC_client_send_queue(client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -156,12 +213,25 @@ static void event_callback(struct net_connection* con, int events, void *arg)
|
|||||||
TARGET = NULL; \
|
TARGET = NULL; \
|
||||||
hub_free(TMP);
|
hub_free(TMP);
|
||||||
|
|
||||||
|
#define UNESCAPE_ARG_X(TMP, TARGET, SIZE) \
|
||||||
|
if (TMP) \
|
||||||
|
adc_msg_unescape_to_target(TMP, TARGET, SIZE); \
|
||||||
|
else \
|
||||||
|
TARGET[0] = '\0'; \
|
||||||
|
hub_free(TMP);
|
||||||
|
|
||||||
#define EXTRACT_NAMED_ARG(MSG, NAME, TARGET) \
|
#define EXTRACT_NAMED_ARG(MSG, NAME, TARGET) \
|
||||||
do { \
|
do { \
|
||||||
char* tmp = adc_msg_get_named_argument(MSG, NAME); \
|
char* tmp = adc_msg_get_named_argument(MSG, NAME); \
|
||||||
UNESCAPE_ARG(tmp, TARGET); \
|
UNESCAPE_ARG(tmp, TARGET); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define EXTRACT_NAMED_ARG_X(MSG, NAME, TARGET, SIZE) \
|
||||||
|
do { \
|
||||||
|
char* tmp = adc_msg_get_named_argument(MSG, NAME); \
|
||||||
|
UNESCAPE_ARG_X(tmp, TARGET, SIZE); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
#define EXTRACT_POS_ARG(MSG, POS, TARGET) \
|
#define EXTRACT_POS_ARG(MSG, POS, TARGET) \
|
||||||
do { \
|
do { \
|
||||||
char* tmp = adc_msg_get_argument(MSG, POS); \
|
char* tmp = adc_msg_get_argument(MSG, POS); \
|
||||||
@@ -169,11 +239,14 @@ static void event_callback(struct net_connection* con, int events, void *arg)
|
|||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
static void ADC_client_on_recv_line(struct ADC_client* client, const char* line, size_t length)
|
static int ADC_client_on_recv_line(struct ADC_client* client, const char* line, size_t length)
|
||||||
{
|
{
|
||||||
|
struct ADC_chat_message chat;
|
||||||
|
struct ADC_client_callback_data data;
|
||||||
|
|
||||||
ADC_TRACE;
|
ADC_TRACE;
|
||||||
#ifdef ADC_CLIENT_DEBUG_PROTO
|
#ifdef ADC_CLIENT_DEBUG_PROTO
|
||||||
ADC_client_debug(client, "- LINE: '%s'", start);
|
ADC_client_debug(client, "- LINE: '%s'", line);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Parse message */
|
/* Parse message */
|
||||||
@@ -181,13 +254,13 @@ static void ADC_client_on_recv_line(struct ADC_client* client, const char* line,
|
|||||||
if (!msg)
|
if (!msg)
|
||||||
{
|
{
|
||||||
ADC_client_debug(client, "WARNING: Message cannot be decoded: \"%s\"", line);
|
ADC_client_debug(client, "WARNING: Message cannot be decoded: \"%s\"", line);
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (length < 4)
|
if (length < 4)
|
||||||
{
|
{
|
||||||
ADC_client_debug(client, "Unexpected response from hub: '%s'", line);
|
ADC_client_debug(client, "Unexpected response from hub: '%s'", line);
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (msg->cmd)
|
switch (msg->cmd)
|
||||||
@@ -210,12 +283,18 @@ static void ADC_client_on_recv_line(struct ADC_client* client, const char* line,
|
|||||||
case ADC_CMD_DMSG:
|
case ADC_CMD_DMSG:
|
||||||
case ADC_CMD_IMSG:
|
case ADC_CMD_IMSG:
|
||||||
{
|
{
|
||||||
struct ADC_chat_message chat;
|
|
||||||
struct ADC_client_callback_data data;
|
|
||||||
chat.from_sid = msg->source;
|
chat.from_sid = msg->source;
|
||||||
chat.to_sid = msg->target;
|
chat.to_sid = msg->target;
|
||||||
data.chat = &chat;
|
data.chat = &chat;
|
||||||
EXTRACT_POS_ARG(msg, 0, chat.message);
|
EXTRACT_POS_ARG(msg, 0, chat.message);
|
||||||
|
chat.flags = 0;
|
||||||
|
|
||||||
|
if (adc_msg_has_named_argument(msg, ADC_MSG_FLAG_ACTION))
|
||||||
|
chat.flags |= chat_flags_action;
|
||||||
|
|
||||||
|
if (adc_msg_has_named_argument(msg, ADC_MSG_FLAG_PRIVATE))
|
||||||
|
chat.flags |= chat_flags_private;
|
||||||
|
|
||||||
client->callback(client, ADC_CLIENT_MESSAGE, &data);
|
client->callback(client, ADC_CLIENT_MESSAGE, &data);
|
||||||
hub_free(chat.message);
|
hub_free(chat.message);
|
||||||
break;
|
break;
|
||||||
@@ -259,23 +338,32 @@ static void ADC_client_on_recv_line(struct ADC_client* client, const char* line,
|
|||||||
{
|
{
|
||||||
struct ADC_user user;
|
struct ADC_user user;
|
||||||
user.sid = msg->source;
|
user.sid = msg->source;
|
||||||
EXTRACT_NAMED_ARG(msg, "NI", user.name);
|
EXTRACT_NAMED_ARG_X(msg, "NI", user.name, sizeof(user.name));
|
||||||
EXTRACT_NAMED_ARG(msg, "DE", user.description);
|
EXTRACT_NAMED_ARG_X(msg, "DE", user.description, sizeof(user.description));
|
||||||
EXTRACT_NAMED_ARG(msg, "VE", user.version);
|
EXTRACT_NAMED_ARG_X(msg, "VE", user.version, sizeof(user.version));
|
||||||
EXTRACT_NAMED_ARG(msg, "ID", user.cid);
|
EXTRACT_NAMED_ARG_X(msg, "ID", user.cid, sizeof(user.cid));
|
||||||
EXTRACT_NAMED_ARG(msg, "I4", user.address);
|
EXTRACT_NAMED_ARG_X(msg, "I4", user.address, sizeof(user.address));
|
||||||
|
|
||||||
struct ADC_client_callback_data data;
|
struct ADC_client_callback_data data;
|
||||||
data.user = &user;
|
data.user = &user;
|
||||||
client->callback(client, ADC_CLIENT_USER_JOIN, &data);
|
client->callback(client, ADC_CLIENT_USER_JOIN, &data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
hub_free(user.name);
|
case ADC_CMD_IQUI:
|
||||||
hub_free(user.description);
|
{
|
||||||
hub_free(user.version);
|
struct ADC_client_quit_reason reason;
|
||||||
hub_free(user.cid);
|
memset(&reason, 0, sizeof(reason));
|
||||||
hub_free(user.address);
|
reason.sid = string_to_sid(&line[5]);
|
||||||
}
|
|
||||||
}
|
if (adc_msg_has_named_argument(msg, ADC_QUI_FLAG_DISCONNECT))
|
||||||
|
reason.flags |= 1;
|
||||||
|
|
||||||
|
data.quit = &reason;
|
||||||
|
client->callback(client, ADC_CLIENT_USER_QUIT, &data);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ADC_CMD_ISTA:
|
case ADC_CMD_ISTA:
|
||||||
@@ -292,77 +380,134 @@ static void ADC_client_on_recv_line(struct ADC_client* client, const char* line,
|
|||||||
}
|
}
|
||||||
|
|
||||||
adc_msg_free(msg);
|
adc_msg_free(msg);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t ADC_client_recv(struct ADC_client* client)
|
static ssize_t ADC_client_recv(struct ADC_client* client)
|
||||||
{
|
{
|
||||||
|
static char buf[BIG_BUFSIZE];
|
||||||
|
struct ioq_recv* q = client->recv_queue;
|
||||||
|
size_t buf_size = ioq_recv_get(q, buf, BIG_BUFSIZE);
|
||||||
|
ssize_t size;
|
||||||
|
|
||||||
ADC_TRACE;
|
ADC_TRACE;
|
||||||
ssize_t size = net_con_recv(client->con, &client->recvbuf[client->r_offset], ADC_BUFSIZE - client->r_offset);
|
|
||||||
if (size <= 0)
|
|
||||||
return size;
|
|
||||||
|
|
||||||
client->r_offset += size;
|
if (client->flags & cflag_choke)
|
||||||
client->recvbuf[client->r_offset] = 0;
|
buf_size = 0;
|
||||||
|
size = net_con_recv(client->con, buf + buf_size, BIG_BUFSIZE - buf_size);
|
||||||
|
|
||||||
char* start = client->recvbuf;
|
if (size > 0)
|
||||||
char* pos;
|
buf_size += size;
|
||||||
|
|
||||||
|
if (size < 0)
|
||||||
|
return -1;
|
||||||
|
else if (size == 0)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
char* lastPos = 0;
|
char* lastPos = 0;
|
||||||
size_t remaining = client->r_offset;
|
char* start = buf;
|
||||||
|
char* pos = 0;
|
||||||
|
size_t remaining = buf_size;
|
||||||
|
|
||||||
while ((pos = memchr(start, '\n', remaining)))
|
while ((pos = memchr(start, '\n', remaining)))
|
||||||
{
|
{
|
||||||
pos[0] = 0;
|
lastPos = pos+1;
|
||||||
|
pos[0] = '\0';
|
||||||
|
|
||||||
ADC_client_on_recv_line(client, start, pos - start);
|
#ifdef DEBUG_SENDQ
|
||||||
|
LOG_DUMP("PROC: \"%s\" (%d)\n", start, (int) (pos - start));
|
||||||
|
#endif
|
||||||
|
|
||||||
pos++;
|
if (client->flags & cflag_choke)
|
||||||
remaining -= (pos - start);
|
client->flags &= ~cflag_choke;
|
||||||
start = pos;
|
else
|
||||||
lastPos = pos;
|
{
|
||||||
|
if (((pos - start) > 0) && MAX_RECV_BUFFER > (pos - start))
|
||||||
|
{
|
||||||
|
if (ADC_client_on_recv_line(client, start, pos - start) == -1)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastPos)
|
pos[0] = '\n'; /* FIXME: not needed */
|
||||||
|
pos ++;
|
||||||
|
remaining -= (pos - start);
|
||||||
|
start = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastPos || remaining)
|
||||||
{
|
{
|
||||||
memmove(client->recvbuf, lastPos, remaining);
|
if (remaining < (size_t) MAX_RECV_BUFFER)
|
||||||
client->r_offset = remaining;
|
{
|
||||||
|
ioq_recv_set(q, lastPos ? lastPos : buf, remaining);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ioq_recv_set(q, 0, 0);
|
||||||
|
client->flags |= cflag_choke;
|
||||||
|
LOG_WARN("Received message past MAX_RECV_BUFFER (%d), dropping message.", MAX_RECV_BUFFER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ioq_recv_set(q, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ADC_client_send_queue(struct ADC_client* client)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
while (ioq_send_get_bytes(client->send_queue))
|
||||||
|
{
|
||||||
|
ret = ioq_send_send(client->send_queue, client->con);
|
||||||
|
if (ret <= 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
return quit_socket_error;
|
||||||
|
|
||||||
|
if (ioq_send_get_bytes(client->send_queue))
|
||||||
|
{
|
||||||
|
net_con_update(client->con, NET_EVENT_READ | NET_EVENT_WRITE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
net_con_update(client->con, NET_EVENT_READ);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ADC_client_send(struct ADC_client* client, char* msg)
|
void ADC_client_send(struct ADC_client* client, struct adc_message* msg)
|
||||||
{
|
{
|
||||||
ADC_TRACE;
|
ADC_TRACE;
|
||||||
int ret = net_con_send(client->con, msg, strlen(msg));
|
|
||||||
|
|
||||||
#ifdef ADC_CLIENT_DEBUG_PROTO
|
uhub_assert(client->con != NULL);
|
||||||
char* dump = strdup(msg);
|
uhub_assert(msg->cache && *msg->cache);
|
||||||
dump[strlen(msg) - 1] = 0;
|
|
||||||
ADC_client_debug(client, "- SEND: '%s'", dump);
|
|
||||||
free(dump);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (ret != strlen(msg))
|
if (ioq_send_is_empty(client->send_queue) && !(client->flags & cflag_pipe))
|
||||||
{
|
{
|
||||||
if (ret == -1)
|
/* Perform oportunistic write */
|
||||||
{
|
ioq_send_add(client->send_queue, msg);
|
||||||
if (net_error() != EWOULDBLOCK)
|
ADC_client_send_queue(client);
|
||||||
ADC_client_on_disconnected(client);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* FIXME: Not all data sent! */
|
ioq_send_add(client->send_queue, msg);
|
||||||
printf("ret (%d) != msg->length (%d)\n", ret, (int) strlen(msg));
|
if (!(client->flags & cflag_pipe))
|
||||||
}
|
net_con_update(client->con, NET_EVENT_READ | NET_EVENT_WRITE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ADC_client_send_info(struct ADC_client* client)
|
void ADC_client_send_info(struct ADC_client* client)
|
||||||
{
|
{
|
||||||
ADC_TRACE;
|
ADC_TRACE;
|
||||||
char binf[11];
|
client->info = adc_msg_construct_source(ADC_CMD_BINF, client->sid, 96);
|
||||||
snprintf(binf, 11, "BINF %s\n", sid_to_string(client->sid));
|
|
||||||
client->info = adc_msg_create(binf);
|
|
||||||
|
|
||||||
adc_msg_add_named_argument_string(client->info, ADC_INF_FLAG_NICK, client->nick);
|
adc_msg_add_named_argument_string(client->info, ADC_INF_FLAG_NICK, client->nick);
|
||||||
|
|
||||||
@@ -371,65 +516,84 @@ void ADC_client_send_info(struct ADC_client* client)
|
|||||||
adc_msg_add_named_argument_string(client->info, ADC_INF_FLAG_DESCRIPTION, client->desc);
|
adc_msg_add_named_argument_string(client->info, ADC_INF_FLAG_DESCRIPTION, client->desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
adc_msg_add_named_argument_string(client->info, ADC_INF_FLAG_USER_AGENT, PRODUCT "/" VERSION);
|
adc_msg_add_named_argument_string(client->info, ADC_INF_FLAG_USER_AGENT, PRODUCT " " VERSION);
|
||||||
|
adc_msg_add_named_argument_int(client->info, ADC_INF_FLAG_UPLOAD_SLOTS, 0);
|
||||||
|
adc_msg_add_named_argument_int(client->info, ADC_INF_FLAG_SHARED_SIZE, 0);
|
||||||
|
adc_msg_add_named_argument_int(client->info, ADC_INF_FLAG_SHARED_FILES, 0);
|
||||||
|
|
||||||
|
adc_msg_add_named_argument_int(client->info, ADC_INF_FLAG_COUNT_HUB_NORMAL, 1);
|
||||||
|
adc_msg_add_named_argument_int(client->info, ADC_INF_FLAG_COUNT_HUB_REGISTER, 0);
|
||||||
|
adc_msg_add_named_argument_int(client->info, ADC_INF_FLAG_COUNT_HUB_OPERATOR, 0);
|
||||||
|
|
||||||
|
adc_msg_add_named_argument_int(client->info, ADC_INF_FLAG_DOWNLOAD_SPEED, 5 * 1024 * 1024);
|
||||||
|
adc_msg_add_named_argument_int(client->info, ADC_INF_FLAG_UPLOAD_SPEED, 10 * 1024 * 1024);
|
||||||
|
|
||||||
adc_cid_pid(client);
|
adc_cid_pid(client);
|
||||||
ADC_client_send(client, client->info->cache);
|
|
||||||
|
ADC_client_send(client, client->info);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ADC_client_create(struct ADC_client* client, const char* nickname, const char* description)
|
|
||||||
|
struct ADC_client* ADC_client_create(const char* nickname, const char* description, void* ptr)
|
||||||
{
|
{
|
||||||
ADC_TRACE;
|
ADC_TRACE;
|
||||||
memset(client, 0, sizeof(struct ADC_client));
|
struct ADC_client* client = (struct ADC_client*) hub_malloc_zero(sizeof(struct ADC_client));
|
||||||
|
|
||||||
int sd = net_socket_create(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
int sd = net_socket_create(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
if (sd == -1) return -1;
|
if (sd == -1) return NULL;
|
||||||
|
|
||||||
client->con = net_con_create();
|
client->con = net_con_create();
|
||||||
#if 0
|
|
||||||
/* FIXME */
|
|
||||||
client->timer = 0; /* FIXME: hub_malloc(sizeof(struct net_timer)); */
|
|
||||||
#endif
|
|
||||||
net_con_initialize(client->con, sd, event_callback, client, 0);
|
net_con_initialize(client->con, sd, event_callback, client, 0);
|
||||||
#if 0
|
|
||||||
/* FIXME */
|
|
||||||
net_timer_initialize(client->timer, timer_callback, client);
|
|
||||||
#endif
|
|
||||||
ADC_client_set_state(client, ps_none);
|
ADC_client_set_state(client, ps_none);
|
||||||
|
|
||||||
client->nick = hub_strdup(nickname);
|
client->nick = hub_strdup(nickname);
|
||||||
client->desc = hub_strdup(description);
|
client->desc = hub_strdup(description);
|
||||||
|
|
||||||
return 0;
|
client->send_queue = ioq_send_create();
|
||||||
|
client->recv_queue = ioq_recv_create();
|
||||||
|
|
||||||
|
client->ptr = ptr;
|
||||||
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ADC_client_destroy(struct ADC_client* client)
|
void ADC_client_destroy(struct ADC_client* client)
|
||||||
{
|
{
|
||||||
ADC_TRACE;
|
ADC_TRACE;
|
||||||
ADC_client_disconnect(client);
|
ADC_client_disconnect(client);
|
||||||
#if 0
|
ioq_send_destroy(client->send_queue);
|
||||||
/* FIXME */
|
ioq_recv_destroy(client->recv_queue);
|
||||||
net_timer_shutdown(client->timer);
|
|
||||||
#endif
|
|
||||||
hub_free(client->timer);
|
hub_free(client->timer);
|
||||||
adc_msg_free(client->info);
|
adc_msg_free(client->info);
|
||||||
hub_free(client->nick);
|
hub_free(client->nick);
|
||||||
hub_free(client->desc);
|
hub_free(client->desc);
|
||||||
hub_free(client->hub_address);
|
hub_free(client->address.hostname);
|
||||||
|
hub_free(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ADC_client_connect(struct ADC_client* client, const char* address)
|
int ADC_client_connect(struct ADC_client* client, const char* address)
|
||||||
{
|
{
|
||||||
ADC_TRACE;
|
ADC_TRACE;
|
||||||
if (!client->hub_address)
|
if (client->state == ps_none)
|
||||||
{
|
{
|
||||||
|
// Parse address and start name resolving!
|
||||||
if (!ADC_client_parse_address(client, address))
|
if (!ADC_client_parse_address(client, address))
|
||||||
return 0;
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return ADC_client_connect_internal(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ADC_client_connect_internal(struct ADC_client* client)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
if (client->state == ps_dns)
|
||||||
|
{
|
||||||
|
// Done name resolving!
|
||||||
client->callback(client, ADC_CLIENT_CONNECTING, 0);
|
client->callback(client, ADC_CLIENT_CONNECTING, 0);
|
||||||
|
ADC_client_set_state(client, ps_conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret = net_connect(net_con_get_sd(client->con), (struct sockaddr*) &client->addr, sizeof(struct sockaddr_in));
|
ret = net_connect(net_con_get_sd(client->con), (struct sockaddr*) &client->addr, sizeof(struct sockaddr_in));
|
||||||
if (ret == 0 || (ret == -1 && net_error() == EISCONN))
|
if (ret == 0 || (ret == -1 && net_error() == EISCONN))
|
||||||
{
|
{
|
||||||
ADC_client_on_connected(client);
|
ADC_client_on_connected(client);
|
||||||
@@ -451,19 +615,23 @@ static void ADC_client_on_connected(struct ADC_client* client)
|
|||||||
{
|
{
|
||||||
ADC_TRACE;
|
ADC_TRACE;
|
||||||
#ifdef SSL_SUPPORT
|
#ifdef SSL_SUPPORT
|
||||||
if (client->ssl_enabled)
|
if (client->flags & cflag_ssl)
|
||||||
{
|
{
|
||||||
net_con_update(client->con, NET_EVENT_READ | NET_EVENT_WRITE);
|
net_con_update(client->con, NET_EVENT_READ | NET_EVENT_WRITE);
|
||||||
client->callback(client, ADC_CLIENT_SSL_HANDSHAKE, 0);
|
client->callback(client, ADC_CLIENT_SSL_HANDSHAKE, 0);
|
||||||
ADC_client_set_state(client, ps_conn_ssl);
|
ADC_client_set_state(client, ps_conn_ssl);
|
||||||
|
|
||||||
|
net_con_ssl_handshake(client->con, net_con_ssl_mode_client, NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
struct adc_message* handshake = adc_msg_create(ADC_HANDSHAKE);
|
||||||
net_con_update(client->con, NET_EVENT_READ);
|
net_con_update(client->con, NET_EVENT_READ);
|
||||||
client->callback(client, ADC_CLIENT_CONNECTED, 0);
|
client->callback(client, ADC_CLIENT_CONNECTED, 0);
|
||||||
ADC_client_send(client, ADC_HANDSHAKE);
|
ADC_client_send(client, handshake);
|
||||||
ADC_client_set_state(client, ps_protocol);
|
ADC_client_set_state(client, ps_protocol);
|
||||||
|
adc_msg_free(handshake);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -471,10 +639,13 @@ static void ADC_client_on_connected(struct ADC_client* client)
|
|||||||
static void ADC_client_on_connected_ssl(struct ADC_client* client)
|
static void ADC_client_on_connected_ssl(struct ADC_client* client)
|
||||||
{
|
{
|
||||||
ADC_TRACE;
|
ADC_TRACE;
|
||||||
net_con_update(client->con, NET_EVENT_READ);
|
struct adc_message* handshake = adc_msg_create(ADC_HANDSHAKE);
|
||||||
|
client->callback(client, ADC_CLIENT_SSL_OK, 0);
|
||||||
client->callback(client, ADC_CLIENT_CONNECTED, 0);
|
client->callback(client, ADC_CLIENT_CONNECTED, 0);
|
||||||
ADC_client_send(client, ADC_HANDSHAKE);
|
net_con_update(client->con, NET_EVENT_READ);
|
||||||
|
ADC_client_send(client, handshake);
|
||||||
ADC_client_set_state(client, ps_protocol);
|
ADC_client_set_state(client, ps_protocol);
|
||||||
|
adc_msg_free(handshake);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -503,58 +674,88 @@ void ADC_client_disconnect(struct ADC_client* client)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ADC_client_dns_callback(struct net_dns_job* job, const struct net_dns_result* result)
|
||||||
|
{
|
||||||
|
struct ADC_client* client = (struct ADC_client*) net_dns_job_get_ptr(job);
|
||||||
|
struct ip_addr_encap* ipaddr;
|
||||||
|
LOG_WARN("ADC_client_dns_callback(): result=%p (%d)", result, net_dns_result_size(result));
|
||||||
|
|
||||||
|
memset(&client->addr, 0, sizeof(client->addr));
|
||||||
|
|
||||||
|
ipaddr = net_dns_result_first(result);
|
||||||
|
switch (ipaddr->af)
|
||||||
|
{
|
||||||
|
case AF_INET:
|
||||||
|
{
|
||||||
|
struct sockaddr_in* addr4 = (struct sockaddr_in*) &client->addr;
|
||||||
|
addr4->sin_family = AF_INET;
|
||||||
|
addr4->sin_port = htons(client->address.port);
|
||||||
|
memcpy(&addr4->sin_addr, &ipaddr->internal_ip_data.in, sizeof(struct in_addr));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case AF_INET6:
|
||||||
|
{
|
||||||
|
struct sockaddr_in6* addr6 = (struct sockaddr_in6*) &client->addr;
|
||||||
|
addr6->sin6_family = AF_INET6;
|
||||||
|
addr6->sin6_port = htons(client->address.port);
|
||||||
|
memcpy(&addr6->sin6_addr, &ipaddr->internal_ip_data.in6, sizeof(struct in6_addr));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
LOG_WARN("Unknown ipaddr!");
|
||||||
|
}
|
||||||
|
|
||||||
|
ADC_client_connect_internal(client);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int ADC_client_parse_address(struct ADC_client* client, const char* arg)
|
static int ADC_client_parse_address(struct ADC_client* client, const char* arg)
|
||||||
{
|
{
|
||||||
ADC_TRACE;
|
ADC_TRACE;
|
||||||
|
const char* hub_address = arg;
|
||||||
char* split;
|
char* split;
|
||||||
int ssl = 0;
|
int ssl = 0;
|
||||||
struct hostent* dns;
|
|
||||||
struct in_addr* addr;
|
|
||||||
|
|
||||||
if (!arg)
|
if (!arg)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
client->hub_address = hub_strdup(arg);
|
|
||||||
|
|
||||||
/* Minimum length of a valid address */
|
/* Minimum length of a valid address */
|
||||||
if (strlen(arg) < 9)
|
if (strlen(arg) < 9)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Check for ADC or ADCS */
|
/* Check for ADC or ADCS */
|
||||||
if (!strncmp(arg, "adc://", 6))
|
if (!strncmp(arg, "adc://", 6))
|
||||||
client->ssl_enabled = 0;
|
{
|
||||||
|
client->flags &= ~cflag_ssl;
|
||||||
|
client->address.protocol = ADC;
|
||||||
|
}
|
||||||
else if (!strncmp(arg, "adcs://", 7))
|
else if (!strncmp(arg, "adcs://", 7))
|
||||||
{
|
{
|
||||||
client->ssl_enabled = 1;
|
client->flags |= cflag_ssl;
|
||||||
ssl = 1;
|
ssl = 1;
|
||||||
|
client->address.protocol = ADCS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Split hostname and port (if possible) */
|
/* Split hostname and port (if possible) */
|
||||||
split = strrchr(client->hub_address + 6 + ssl, ':');
|
hub_address = arg + 6 + ssl;
|
||||||
|
split = strrchr(hub_address, ':');
|
||||||
if (split == 0 || strlen(split) < 2 || strlen(split) > 6)
|
if (split == 0 || strlen(split) < 2 || strlen(split) > 6)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Ensure port number is valid */
|
/* Ensure port number is valid */
|
||||||
int port = strtol(split+1, NULL, 10);
|
client->address.port = strtol(split+1, NULL, 10);
|
||||||
if (port <= 0 || port > 65535)
|
if (client->address.port <= 0 || client->address.port > 65535)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
split[0] = 0;
|
client->address.hostname = strndup(hub_address, &split[0] - &hub_address[0]);
|
||||||
|
|
||||||
/* Resolve IP address (FIXME: blocking call) */
|
client->callback(client, ADC_CLIENT_NAME_LOOKUP, 0);
|
||||||
dns = gethostbyname(client->hub_address + 6 + ssl);
|
ADC_client_set_state(client, ps_dns);
|
||||||
if (dns)
|
client->dns_job = net_dns_gethostbyname(client->address.hostname, AF_UNSPEC, ADC_client_dns_callback, client);
|
||||||
{
|
|
||||||
addr = (struct in_addr*) dns->h_addr_list[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize the sockaddr struct.
|
|
||||||
memset(&client->addr, 0, sizeof(client->addr));
|
|
||||||
client->addr.sin_family = AF_INET;
|
|
||||||
client->addr.sin_port = htons(port);
|
|
||||||
memcpy(&client->addr.sin_addr, addr, sizeof(struct in_addr));
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -563,3 +764,23 @@ void ADC_client_set_callback(struct ADC_client* client, adc_client_cb cb)
|
|||||||
ADC_TRACE;
|
ADC_TRACE;
|
||||||
client->callback = cb;
|
client->callback = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sid_t ADC_client_get_sid(const struct ADC_client* client)
|
||||||
|
{
|
||||||
|
return client->sid;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* ADC_client_get_nick(const struct ADC_client* client)
|
||||||
|
{
|
||||||
|
return client->nick;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* ADC_client_get_description(const struct ADC_client* client)
|
||||||
|
{
|
||||||
|
return client->desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* ADC_client_get_ptr(const struct ADC_client* client)
|
||||||
|
{
|
||||||
|
return client->ptr;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2011, Jan Vidar Krey
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -24,21 +24,11 @@
|
|||||||
|
|
||||||
#define ADC_BUFSIZE 16384
|
#define ADC_BUFSIZE 16384
|
||||||
|
|
||||||
enum ADC_client_state
|
|
||||||
{
|
|
||||||
ps_none, /* Not connected */
|
|
||||||
ps_conn, /* Connecting... */
|
|
||||||
ps_conn_ssl, /* SSL handshake */
|
|
||||||
ps_protocol, /* Have sent HSUP */
|
|
||||||
ps_identify, /* Have sent BINF */
|
|
||||||
ps_verify, /* Have sent HPAS */
|
|
||||||
ps_normal, /* Are fully logged in */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ADC_client;
|
struct ADC_client;
|
||||||
|
|
||||||
enum ADC_client_callback_type
|
enum ADC_client_callback_type
|
||||||
{
|
{
|
||||||
|
ADC_CLIENT_NAME_LOOKUP = 1000,
|
||||||
ADC_CLIENT_CONNECTING = 1001,
|
ADC_CLIENT_CONNECTING = 1001,
|
||||||
ADC_CLIENT_CONNECTED = 1002,
|
ADC_CLIENT_CONNECTED = 1002,
|
||||||
ADC_CLIENT_DISCONNECTED = 1003,
|
ADC_CLIENT_DISCONNECTED = 1003,
|
||||||
@@ -71,6 +61,13 @@ struct ADC_hub_info
|
|||||||
char* version;
|
char* version;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ADC_chat_message_flags
|
||||||
|
{
|
||||||
|
chat_flags_none = 0,
|
||||||
|
chat_flags_action = 1,
|
||||||
|
chat_flags_private = 2
|
||||||
|
};
|
||||||
|
|
||||||
struct ADC_chat_message
|
struct ADC_chat_message
|
||||||
{
|
{
|
||||||
sid_t from_sid;
|
sid_t from_sid;
|
||||||
@@ -79,14 +76,23 @@ struct ADC_chat_message
|
|||||||
int flags;
|
int flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MAX_DESC_LEN 128
|
||||||
struct ADC_user
|
struct ADC_user
|
||||||
{
|
{
|
||||||
sid_t sid;
|
sid_t sid;
|
||||||
char* cid;
|
char cid[MAX_CID_LEN+1];
|
||||||
char* name;
|
char name[MAX_NICK_LEN+1];
|
||||||
char* description;
|
char description[MAX_DESC_LEN+1];
|
||||||
char* address;
|
char address[INET6_ADDRSTRLEN+1];
|
||||||
char* version;
|
char version[MAX_UA_LEN+1];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ADC_client_quit_reason
|
||||||
|
{
|
||||||
|
sid_t sid;
|
||||||
|
sid_t initator; // 0 = default/hub.
|
||||||
|
char message[128]; // optional
|
||||||
|
int flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -96,41 +102,23 @@ struct ADC_client_callback_data
|
|||||||
struct ADC_hub_info* hubinfo;
|
struct ADC_hub_info* hubinfo;
|
||||||
struct ADC_chat_message* chat;
|
struct ADC_chat_message* chat;
|
||||||
struct ADC_user* user;
|
struct ADC_user* user;
|
||||||
|
struct ADC_client_quit_reason* quit;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
sid_t ADC_client_get_sid(const struct ADC_client* client);
|
||||||
|
const char* ADC_client_get_nick(const struct ADC_client* client);
|
||||||
|
const char* ADC_client_get_description(const struct ADC_client* client);
|
||||||
|
void* ADC_client_get_ptr(const struct ADC_client* client);
|
||||||
|
|
||||||
typedef int (*adc_client_cb)(struct ADC_client*, enum ADC_client_callback_type, struct ADC_client_callback_data* data);
|
typedef int (*adc_client_cb)(struct ADC_client*, enum ADC_client_callback_type, struct ADC_client_callback_data* data);
|
||||||
|
|
||||||
struct ADC_client
|
struct ADC_client* ADC_client_create(const char* nickname, const char* description, void* ptr);
|
||||||
{
|
|
||||||
sid_t sid;
|
|
||||||
enum ADC_client_state state;
|
|
||||||
struct adc_message* info;
|
|
||||||
char recvbuf[ADC_BUFSIZE];
|
|
||||||
char sendbuf[ADC_BUFSIZE];
|
|
||||||
adc_client_cb callback;
|
|
||||||
size_t s_offset;
|
|
||||||
size_t r_offset;
|
|
||||||
size_t timeout;
|
|
||||||
struct net_connection* con;
|
|
||||||
struct net_timer* timer;
|
|
||||||
struct sockaddr_in addr;
|
|
||||||
char* hub_address;
|
|
||||||
char* nick;
|
|
||||||
char* desc;
|
|
||||||
int ssl_enabled;
|
|
||||||
#ifdef SSL_SUPPORT
|
|
||||||
const SSL_METHOD* ssl_method;
|
|
||||||
SSL_CTX* ssl_ctx;
|
|
||||||
#endif /* SSL_SUPPORT */
|
|
||||||
};
|
|
||||||
|
|
||||||
int ADC_client_create(struct ADC_client* client, const char* nickname, const char* description);
|
|
||||||
void ADC_client_set_callback(struct ADC_client* client, adc_client_cb);
|
void ADC_client_set_callback(struct ADC_client* client, adc_client_cb);
|
||||||
void ADC_client_destroy(struct ADC_client* client);
|
void ADC_client_destroy(struct ADC_client* client);
|
||||||
int ADC_client_connect(struct ADC_client* client, const char* address);
|
int ADC_client_connect(struct ADC_client* client, const char* address);
|
||||||
void ADC_client_disconnect(struct ADC_client* client);
|
void ADC_client_disconnect(struct ADC_client* client);
|
||||||
void ADC_client_send(struct ADC_client* client, char* msg);
|
void ADC_client_send(struct ADC_client* client, struct adc_message* msg);
|
||||||
|
|
||||||
#endif /* HAVE_UHUB_ADC_CLIENT_H */
|
#endif /* HAVE_UHUB_ADC_CLIENT_H */
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2011, Jan Vidar Krey
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -24,10 +24,12 @@
|
|||||||
#define ADC_CID_SIZE 39
|
#define ADC_CID_SIZE 39
|
||||||
#define BIG_BUFSIZE 32768
|
#define BIG_BUFSIZE 32768
|
||||||
#define TIGERSIZE 24
|
#define TIGERSIZE 24
|
||||||
|
#define STATS_INTERVAL 3
|
||||||
#define ADCRUSH "adcrush/0.3"
|
#define ADCRUSH "adcrush/0.3"
|
||||||
#define ADC_NICK "[BOT]adcrush"
|
#define ADC_NICK "[BOT]adcrush"
|
||||||
#define ADC_DESC "crash\\stest\\sdummy"
|
#define ADC_DESC "crash\\stest\\sdummy"
|
||||||
|
|
||||||
|
|
||||||
#define LVL_INFO 1
|
#define LVL_INFO 1
|
||||||
#define LVL_DEBUG 2
|
#define LVL_DEBUG 2
|
||||||
#define LVL_VERBOSE 3
|
#define LVL_VERBOSE 3
|
||||||
@@ -38,6 +40,32 @@ static int cfg_level = 1; /* activity level (0..3) */
|
|||||||
static int cfg_chat = 0; /* chat mode, allow sending chat messages */
|
static int cfg_chat = 0; /* chat mode, allow sending chat messages */
|
||||||
static int cfg_quiet = 0; /* quiet mode (no output) */
|
static int cfg_quiet = 0; /* quiet mode (no output) */
|
||||||
static int cfg_clients = ADC_CLIENTS_DEFAULT; /* number of clients */
|
static int cfg_clients = ADC_CLIENTS_DEFAULT; /* number of clients */
|
||||||
|
static int cfg_netstats_interval = STATS_INTERVAL;
|
||||||
|
static int running = 1;
|
||||||
|
static int logged_in = 0;
|
||||||
|
static int blank = 0;
|
||||||
|
static struct net_statistics* stats_intermediate;
|
||||||
|
static struct net_statistics* stats_total;
|
||||||
|
|
||||||
|
static int handle(struct ADC_client* client, enum ADC_client_callback_type type, struct ADC_client_callback_data* data);
|
||||||
|
static void timer_callback(struct timeout_evt* t);
|
||||||
|
|
||||||
|
static void do_blank(int n)
|
||||||
|
{
|
||||||
|
n++;
|
||||||
|
while (n > 0)
|
||||||
|
{
|
||||||
|
fprintf(stdout, " ");
|
||||||
|
n--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AdcFuzzUser
|
||||||
|
{
|
||||||
|
struct ADC_client* client;
|
||||||
|
struct timeout_evt* timer;
|
||||||
|
int logged_in;
|
||||||
|
};
|
||||||
|
|
||||||
#define MAX_CHAT_MSGS 35
|
#define MAX_CHAT_MSGS 35
|
||||||
const char* chat_messages[MAX_CHAT_MSGS] = {
|
const char* chat_messages[MAX_CHAT_MSGS] = {
|
||||||
@@ -103,10 +131,14 @@ static void bot_output(struct ADC_client* client, int level, const char* format,
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
if (cfg_debug >= level)
|
if (cfg_debug >= level)
|
||||||
fprintf(stdout, "* [%p] %s\n", client, logmsg);
|
{
|
||||||
|
int num = fprintf(stdout, "* [%p] %s", client, logmsg);
|
||||||
|
do_blank(blank - num);
|
||||||
|
fprintf(stdout, "\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
static size_t get_wait_rand(size_t max)
|
static size_t get_wait_rand(size_t max)
|
||||||
{
|
{
|
||||||
static size_t next = 0;
|
static size_t next = 0;
|
||||||
@@ -115,120 +147,144 @@ static size_t get_wait_rand(size_t max)
|
|||||||
return ((size_t )(next / 65536) % max);
|
return ((size_t )(next / 65536) % max);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t get_next_timeout_evt()
|
||||||
|
{
|
||||||
|
switch (cfg_level)
|
||||||
|
{
|
||||||
|
case 0: return get_wait_rand(120);
|
||||||
|
case 1: return get_wait_rand(60);
|
||||||
|
case 2: return get_wait_rand(15);
|
||||||
|
case 3: return get_wait_rand(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void perf_result(struct ADC_client* client, sid_t target, const char* what, const char* token);
|
static void perf_result(struct ADC_client* client, sid_t target, const char* what, const char* token);
|
||||||
|
|
||||||
static void perf_chat(struct ADC_client* client, int priv)
|
static void perf_chat(struct ADC_client* client, int priv)
|
||||||
{
|
{
|
||||||
char buf[1024] = { 0, };
|
|
||||||
size_t r = get_wait_rand(MAX_CHAT_MSGS-1);
|
size_t r = get_wait_rand(MAX_CHAT_MSGS-1);
|
||||||
char* msg = adc_msg_escape(chat_messages[r]);
|
char* msg = adc_msg_escape(chat_messages[r]);
|
||||||
|
struct adc_message* cmd = NULL;
|
||||||
|
|
||||||
if (priv)
|
if (priv)
|
||||||
{
|
cmd = adc_msg_construct_source_dest(ADC_CMD_DMSG, ADC_client_get_sid(client), ADC_client_get_sid(client), strlen(msg));
|
||||||
strcat(buf, "EMSG ");
|
|
||||||
strcat(buf, sid_to_string(client->sid));
|
|
||||||
strcat(buf, " ");
|
|
||||||
strcat(buf, sid_to_string(client->sid));
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
cmd = adc_msg_construct_source(ADC_CMD_BMSG, ADC_client_get_sid(client), strlen(msg));
|
||||||
strcat(buf, "BMSG ");
|
|
||||||
strcat(buf, sid_to_string(client->sid));
|
|
||||||
}
|
|
||||||
strcat(buf, " ");
|
|
||||||
|
|
||||||
strcat(buf, msg);
|
|
||||||
hub_free(msg);
|
hub_free(msg);
|
||||||
|
|
||||||
strcat(buf, "\n");
|
ADC_client_send(client, cmd);
|
||||||
ADC_client_send(client, buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void perf_search(struct ADC_client* client)
|
static void perf_search(struct ADC_client* client)
|
||||||
{
|
{
|
||||||
char buf[1024] = { 0, };
|
|
||||||
size_t r = get_wait_rand(MAX_SEARCH_MSGS-1);
|
size_t r = get_wait_rand(MAX_SEARCH_MSGS-1);
|
||||||
size_t pst = get_wait_rand(100);
|
size_t pst = get_wait_rand(100);
|
||||||
|
struct adc_message* cmd = NULL;
|
||||||
|
|
||||||
if (pst > 80)
|
if (pst > 80)
|
||||||
{
|
{
|
||||||
strcat(buf, "FSCH ");
|
cmd = adc_msg_construct_source(ADC_CMD_FSCH, ADC_client_get_sid(client), strlen(search_messages[r]) + 6);
|
||||||
strcat(buf, sid_to_string(client->sid));
|
adc_msg_add_argument(cmd, "+TCP4");
|
||||||
strcat(buf, " +TCP4 ");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strcat(buf, "BSCH ");
|
cmd = adc_msg_construct_source(ADC_CMD_BSCH, ADC_client_get_sid(client), strlen(search_messages[r]) + 6);
|
||||||
strcat(buf, sid_to_string(client->sid));
|
adc_msg_add_argument(cmd, "+TCP4");
|
||||||
strcat(buf, " ");
|
|
||||||
}
|
}
|
||||||
strcat(buf, search_messages[r]);
|
ADC_client_send(client, cmd);
|
||||||
strcat(buf, "\n");
|
|
||||||
ADC_client_send(client, buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void perf_result(struct ADC_client* client, sid_t target, const char* what, const char* token)
|
static void perf_result(struct ADC_client* client, sid_t target, const char* what, const char* token)
|
||||||
{
|
{
|
||||||
char buf[1024] = { 0, };
|
char tmp[256];
|
||||||
strcat(buf, "DRES ");
|
struct adc_message* cmd = adc_msg_construct_source_dest(ADC_CMD_DRES, ADC_client_get_sid(client), target, strlen(what) + strlen(token) + 64);
|
||||||
strcat(buf, sid_to_string(client->sid));
|
|
||||||
strcat(buf, " ");
|
snprintf(tmp, sizeof(tmp), "FNtest/%s.dat", what);
|
||||||
strcat(buf, sid_to_string(target));
|
adc_msg_add_argument(cmd, tmp);
|
||||||
strcat(buf, " FN" "test/");
|
|
||||||
strcat(buf, what);
|
adc_msg_add_argument(cmd, "SL0");
|
||||||
strcat(buf, ".dat");
|
adc_msg_add_argument(cmd, "SI1209818412");
|
||||||
strcat(buf, " SL" "0");
|
adc_msg_add_argument(cmd, "TR5T6YJYKO3WECS52BKWVSOP5VUG4IKNSZBZ5YHBA");
|
||||||
strcat(buf, " SI" "908987128912");
|
snprintf(tmp, sizeof(tmp), "TO%s", token);
|
||||||
strcat(buf, " TR" "5T6YJYKO3WECS52BKWVSOP5VUG4IKNSZBZ5YHBA");
|
adc_msg_add_argument(cmd, tmp);
|
||||||
strcat(buf, " TO");
|
|
||||||
strcat(buf, token);
|
ADC_client_send(client, cmd);
|
||||||
strcat(buf, "\n");
|
|
||||||
ADC_client_send(client, buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void perf_ctm(struct ADC_client* client)
|
static void perf_ctm(struct ADC_client* client)
|
||||||
{
|
{
|
||||||
char buf[1024] = { 0, };
|
char buf[1024] = { 0, };
|
||||||
strcat(buf, "DCTM ");
|
struct adc_message* cmd = adc_msg_construct_source_dest(ADC_CMD_DCTM, ADC_client_get_sid(client), ADC_client_get_sid(client), 32);
|
||||||
strcat(buf, sid_to_string(client->sid));
|
adc_msg_add_argument(cmd, "ADC/1.0");
|
||||||
strcat(buf, " ");
|
adc_msg_add_argument(cmd, "TOKEN123456");
|
||||||
strcat(buf, sid_to_string(client->sid));
|
adc_msg_add_argument(cmd, sid_to_string(ADC_client_get_sid(client)));
|
||||||
strcat(buf, " ");
|
ADC_client_send(client, cmd);
|
||||||
strcat(buf, "ADC/1.0");
|
|
||||||
strcat(buf, " TOKEN111");
|
|
||||||
strcat(buf, sid_to_string(client->sid));
|
|
||||||
strcat(buf, "\n");
|
|
||||||
ADC_client_send(client, buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void perf_update(struct ADC_client* client)
|
static void perf_update(struct ADC_client* client)
|
||||||
{
|
{
|
||||||
char buf[1024] = { 0, };
|
char buf[16] = { 0, };
|
||||||
int n = (int) get_wait_rand(10)+1;
|
int n = (int) get_wait_rand(10)+1;
|
||||||
|
struct adc_message* cmd = adc_msg_construct_source(ADC_CMD_BINF, ADC_client_get_sid(client), 32);
|
||||||
|
snprintf(buf, sizeof(buf), "HN%d", n);
|
||||||
|
adc_msg_add_argument(cmd, buf);
|
||||||
|
ADC_client_send(client, cmd);
|
||||||
|
}
|
||||||
|
|
||||||
strcat(buf, "BINF ");
|
static void client_disconnect(struct AdcFuzzUser* c)
|
||||||
strcat(buf, sid_to_string(client->sid));
|
{
|
||||||
strcat(buf, " HN");
|
ADC_client_destroy(c->client);
|
||||||
strcat(buf, uhub_itoa(n));
|
hub_free(c->client);
|
||||||
|
c->client = 0;
|
||||||
|
|
||||||
strcat(buf, "\n");
|
timeout_queue_remove(net_backend_get_timeout_queue(), c->timer);
|
||||||
ADC_client_send(client, buf);
|
hub_free(c->timer);
|
||||||
|
c->timer = 0;
|
||||||
|
|
||||||
|
c->logged_in = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void client_connect(struct AdcFuzzUser* c, const char* nick, const char* description)
|
||||||
|
{
|
||||||
|
size_t timeout = get_next_timeout_evt();
|
||||||
|
struct ADC_client* client = ADC_client_create(nick, description, c);
|
||||||
|
|
||||||
|
c->client = client;
|
||||||
|
c->timer = (struct timeout_evt*) hub_malloc(sizeof(struct timeout_evt));
|
||||||
|
timeout_evt_initialize(c->timer, timer_callback, c);
|
||||||
|
timeout_queue_insert(net_backend_get_timeout_queue(), c->timer, timeout);
|
||||||
|
|
||||||
|
bot_output(client, LVL_VERBOSE, "Initial timeout: %d seconds", timeout);
|
||||||
|
c->logged_in = 0;
|
||||||
|
|
||||||
|
ADC_client_set_callback(client, handle);
|
||||||
|
ADC_client_connect(client, cfg_uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void perf_normal_action(struct ADC_client* client)
|
static void perf_normal_action(struct ADC_client* client)
|
||||||
{
|
{
|
||||||
|
struct AdcFuzzUser* user = (struct AdcFuzzUser*) ADC_client_get_ptr(client);
|
||||||
size_t r = get_wait_rand(5);
|
size_t r = get_wait_rand(5);
|
||||||
size_t p = get_wait_rand(100);
|
size_t p = get_wait_rand(100);
|
||||||
|
|
||||||
switch (r)
|
switch (r)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
if (p > (90 - (10 * cfg_level)))
|
// if (p > (90 - (10 * cfg_level)))
|
||||||
{
|
{
|
||||||
|
struct ADC_client* c;
|
||||||
|
char* nick = hub_strdup(ADC_client_get_nick(client));
|
||||||
|
char* desc = hub_strdup(ADC_client_get_description(client));
|
||||||
|
|
||||||
bot_output(client, LVL_VERBOSE, "timeout -> disconnect");
|
bot_output(client, LVL_VERBOSE, "timeout -> disconnect");
|
||||||
ADC_client_disconnect(client);
|
client_disconnect(user);
|
||||||
|
client_connect(user, nick, desc);
|
||||||
|
|
||||||
|
hub_free(nick);
|
||||||
|
hub_free(desc);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -236,6 +292,7 @@ static void perf_normal_action(struct ADC_client* client)
|
|||||||
if (cfg_chat)
|
if (cfg_chat)
|
||||||
{
|
{
|
||||||
bot_output(client, LVL_VERBOSE, "timeout -> chat");
|
bot_output(client, LVL_VERBOSE, "timeout -> chat");
|
||||||
|
if (user->logged_in)
|
||||||
perf_chat(client, 0);
|
perf_chat(client, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -243,30 +300,35 @@ static void perf_normal_action(struct ADC_client* client)
|
|||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
bot_output(client, LVL_VERBOSE, "timeout -> search");
|
bot_output(client, LVL_VERBOSE, "timeout -> search");
|
||||||
|
if (user->logged_in)
|
||||||
perf_search(client);
|
perf_search(client);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
bot_output(client, LVL_VERBOSE, "timeout -> update");
|
bot_output(client, LVL_VERBOSE, "timeout -> update");
|
||||||
|
if (user->logged_in)
|
||||||
perf_update(client);
|
perf_update(client);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
bot_output(client, LVL_VERBOSE, "timeout -> privmsg");
|
bot_output(client, LVL_VERBOSE, "timeout -> privmsg");
|
||||||
|
if (user->logged_in)
|
||||||
perf_chat(client, 1);
|
perf_chat(client, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5:
|
case 5:
|
||||||
bot_output(client, LVL_VERBOSE, "timeout -> ctm/rcm");
|
bot_output(client, LVL_VERBOSE, "timeout -> ctm/rcm");
|
||||||
|
if (user->logged_in)
|
||||||
perf_ctm(client);
|
perf_ctm(client);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static int handle(struct ADC_client* client, enum ADC_client_callback_type type, struct ADC_client_callback_data* data)
|
static int handle(struct ADC_client* client, enum ADC_client_callback_type type, struct ADC_client_callback_data* data)
|
||||||
{
|
{
|
||||||
|
struct AdcFuzzUser* user = (struct AdcFuzzUser*) ADC_client_get_ptr(client);
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case ADC_CLIENT_CONNECTING:
|
case ADC_CLIENT_CONNECTING:
|
||||||
@@ -274,7 +336,7 @@ static int handle(struct ADC_client* client, enum ADC_client_callback_type type,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ADC_CLIENT_CONNECTED:
|
case ADC_CLIENT_CONNECTED:
|
||||||
bot_output(client, LVL_DEBUG, "*** Connected.");
|
// bot_output(client, LVL_DEBUG, "*** Connected.");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ADC_CLIENT_DISCONNECTED:
|
case ADC_CLIENT_DISCONNECTED:
|
||||||
@@ -282,38 +344,40 @@ static int handle(struct ADC_client* client, enum ADC_client_callback_type type,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ADC_CLIENT_LOGGING_IN:
|
case ADC_CLIENT_LOGGING_IN:
|
||||||
bot_output(client, LVL_DEBUG, "*** Logging in...");
|
// bot_output(client, LVL_DEBUG, "*** Logging in...");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ADC_CLIENT_PASSWORD_REQ:
|
case ADC_CLIENT_PASSWORD_REQ:
|
||||||
bot_output(client, LVL_DEBUG, "*** Requesting password.");
|
//bot_output(client, LVL_DEBUG, "*** Requesting password.");
|
||||||
|
break;
|
||||||
|
|
||||||
case ADC_CLIENT_LOGGED_IN:
|
case ADC_CLIENT_LOGGED_IN:
|
||||||
bot_output(client, LVL_DEBUG, "*** Logged in.");
|
bot_output(client, LVL_DEBUG, "*** Logged in.");
|
||||||
|
user->logged_in = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ADC_CLIENT_LOGIN_ERROR:
|
case ADC_CLIENT_LOGIN_ERROR:
|
||||||
bot_output(client, LVL_DEBUG, "*** Login error");
|
bot_output(client, LVL_DEBUG, "*** Login error");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ADC_CLIENT_SSL_HANDSHAKE:
|
||||||
|
case ADC_CLIENT_SSL_OK:
|
||||||
|
break;
|
||||||
|
|
||||||
case ADC_CLIENT_MESSAGE:
|
case ADC_CLIENT_MESSAGE:
|
||||||
bot_output(client, LVL_DEBUG, " <%s> %s", sid_to_string(data->chat->from_sid), data->chat->message);
|
// bot_output(client, LVL_DEBUG, " <%s> %s", sid_to_string(data->chat->from_sid), data->chat->message);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ADC_CLIENT_USER_JOIN:
|
case ADC_CLIENT_USER_JOIN:
|
||||||
bot_output(client, LVL_VERBOSE, " JOIN: %s", data->user->name);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ADC_CLIENT_USER_QUIT:
|
case ADC_CLIENT_USER_QUIT:
|
||||||
bot_output(client, LVL_VERBOSE, " QUIT");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ADC_CLIENT_SEARCH_REQ:
|
case ADC_CLIENT_SEARCH_REQ:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ADC_CLIENT_HUB_INFO:
|
case ADC_CLIENT_HUB_INFO:
|
||||||
bot_output(client, LVL_DEBUG, " Hub: \"%s\" [%s]\n"
|
|
||||||
" \"%s\"\n", data->hubinfo->name, data->hubinfo->version, data->hubinfo->description);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -324,40 +388,78 @@ static int handle(struct ADC_client* client, enum ADC_client_callback_type type,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void timer_callback(struct timeout_evt* t)
|
||||||
|
{
|
||||||
|
size_t timeout = get_next_timeout_evt();
|
||||||
|
struct AdcFuzzUser* client = (struct AdcFuzzUser*) t->ptr;
|
||||||
|
if (client->logged_in)
|
||||||
|
{
|
||||||
|
perf_normal_action(client->client);
|
||||||
|
bot_output(client->client, LVL_VERBOSE, "Next timeout: %d seconds", (int) timeout);
|
||||||
|
}
|
||||||
|
timeout_queue_reschedule(net_backend_get_timeout_queue(), client->timer, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct AdcFuzzUser client[ADC_MAX_CLIENTS];
|
||||||
|
void p_status()
|
||||||
|
{
|
||||||
|
static char rxbuf[64] = { "0 B" };
|
||||||
|
static char txbuf[64] = { "0 B" };
|
||||||
|
int logged_in = 0;
|
||||||
|
size_t n;
|
||||||
|
static size_t rx = 0, tx = 0;
|
||||||
|
|
||||||
|
for (n = 0; n < cfg_clients; n++)
|
||||||
|
{
|
||||||
|
if (client[n].logged_in)
|
||||||
|
logged_in++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (difftime(time(NULL), stats_intermediate->timestamp) >= cfg_netstats_interval)
|
||||||
|
{
|
||||||
|
net_stats_get(&stats_intermediate, &stats_total);
|
||||||
|
rx = stats_intermediate->rx / cfg_netstats_interval;
|
||||||
|
tx = stats_intermediate->tx / cfg_netstats_interval;
|
||||||
|
net_stats_reset();
|
||||||
|
format_size(rx, rxbuf, sizeof(rxbuf));
|
||||||
|
format_size(tx, txbuf, sizeof(txbuf));
|
||||||
|
}
|
||||||
|
|
||||||
|
n = blank;
|
||||||
|
blank = printf("Connected bots: %d/%d, network: rx=%s/s, tx=%s/s", logged_in, cfg_clients, rxbuf, txbuf);
|
||||||
|
if (n > blank)
|
||||||
|
do_blank(n-blank);
|
||||||
|
printf("\r");
|
||||||
|
}
|
||||||
|
|
||||||
void runloop(size_t clients)
|
void runloop(size_t clients)
|
||||||
{
|
{
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
struct ADC_client* client[ADC_MAX_CLIENTS];
|
blank = 0;
|
||||||
|
|
||||||
for (n = 0; n < clients; n++)
|
for (n = 0; n < clients; n++)
|
||||||
{
|
{
|
||||||
struct ADC_client* c = malloc(sizeof(struct ADC_client));
|
|
||||||
client[n] = c;
|
|
||||||
|
|
||||||
char nick[20];
|
char nick[20];
|
||||||
snprintf(nick, 20, "adcrush_%d", (int) n);
|
snprintf(nick, 20, "adcrush_%d", (int) n);
|
||||||
|
client_connect(&client[n], nick, "stresstester");
|
||||||
ADC_client_create(c, nick, "stresstester");
|
|
||||||
ADC_client_set_callback(c, handle);
|
|
||||||
ADC_client_connect(c, cfg_uri);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (net_backend_process())
|
while (running && net_backend_process())
|
||||||
{
|
{
|
||||||
|
p_status();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (n = 0; n < clients; n++)
|
for (n = 0; n < clients; n++)
|
||||||
{
|
{
|
||||||
ADC_client_destroy(client[n]);
|
struct AdcFuzzUser* c = &client[n];
|
||||||
free(client[n]);
|
client_disconnect(c);
|
||||||
client[n] = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_version()
|
static void print_version()
|
||||||
{
|
{
|
||||||
printf(ADCRUSH "\n");
|
printf(ADCRUSH "\n");
|
||||||
printf("Copyright (C) 2008-2009, Jan Vidar Krey\n");
|
printf("Copyright (C) 2008-2012, Jan Vidar Krey\n");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,6 +476,7 @@ static void print_usage(const char* program)
|
|||||||
printf(" -c Allow broadcasting chat messages.\n");
|
printf(" -c Allow broadcasting chat messages.\n");
|
||||||
printf(" -d Enable debug output.\n");
|
printf(" -d Enable debug output.\n");
|
||||||
printf(" -q Quiet mode (no output).\n");
|
printf(" -q Quiet mode (no output).\n");
|
||||||
|
printf(" -i <num> Average network statistics for given interval (default: 3)\n");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
@@ -407,6 +510,10 @@ int parse_arguments(int argc, char** argv)
|
|||||||
{
|
{
|
||||||
cfg_level = MIN(MAX(uhub_atoi(argv[opt]), 0), 3);
|
cfg_level = MIN(MAX(uhub_atoi(argv[opt]), 0), 3);
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(argv[opt], "-i") && (++opt) < argc)
|
||||||
|
{
|
||||||
|
cfg_netstats_interval = MAX(uhub_atoi(argv[opt]), 1);
|
||||||
|
}
|
||||||
else if (!strcmp(argv[opt], "-n") && (++opt) < argc)
|
else if (!strcmp(argv[opt], "-n") && (++opt) < argc)
|
||||||
{
|
{
|
||||||
cfg_clients = MIN(MAX(uhub_atoi(argv[opt]), 1), ADC_MAX_CLIENTS);
|
cfg_clients = MIN(MAX(uhub_atoi(argv[opt]), 1), ADC_MAX_CLIENTS);
|
||||||
@@ -428,13 +535,15 @@ void parse_command_line(int argc, char** argv)
|
|||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
|
||||||
parse_command_line(argc, argv);
|
parse_command_line(argc, argv);
|
||||||
|
|
||||||
net_initialize();
|
net_initialize();
|
||||||
|
net_stats_get(&stats_intermediate, &stats_total);
|
||||||
|
|
||||||
hub_log_initialize(NULL, 0);
|
hub_log_initialize(NULL, 0);
|
||||||
hub_set_log_verbosity(1000);
|
hub_set_log_verbosity(1000);
|
||||||
|
setvbuf(stdout, NULL, _IONBF, 0);
|
||||||
runloop(cfg_clients);
|
runloop(cfg_clients);
|
||||||
|
|
||||||
net_destroy();
|
net_destroy();
|
||||||
|
|||||||
@@ -19,52 +19,128 @@
|
|||||||
|
|
||||||
#include "adcclient.h"
|
#include "adcclient.h"
|
||||||
|
|
||||||
|
static struct ADC_user g_usermap[SID_MAX];
|
||||||
|
|
||||||
|
static void user_add(const struct ADC_user* user)
|
||||||
|
{
|
||||||
|
printf(" >> JOIN: %s (%s)\n", user->name, user->address);
|
||||||
|
memcpy(&g_usermap[user->sid], user, sizeof(struct ADC_user));
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct ADC_user* user_get(sid_t sid)
|
||||||
|
{
|
||||||
|
|
||||||
|
struct ADC_user* user = &g_usermap[sid];
|
||||||
|
uhub_assert(user->sid != 0);
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void user_remove(const struct ADC_client_quit_reason* quit)
|
||||||
|
{
|
||||||
|
struct ADC_user* user = user_get(quit->sid);
|
||||||
|
printf(" << QUIT: %s (%s)\n", user->name, quit->message);
|
||||||
|
memset(&g_usermap[quit->sid], 0, sizeof(struct ADC_user));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_message(struct ADC_chat_message* chat)
|
||||||
|
{
|
||||||
|
struct ADC_user* user;
|
||||||
|
const char* pm = (chat->flags & chat_flags_private) ? "PM" : " ";
|
||||||
|
const char* brack1 = (chat->flags & chat_flags_action) ? "*" : "<";
|
||||||
|
const char* brack2 = (chat->flags & chat_flags_action) ? "" : ">";
|
||||||
|
struct linked_list* lines;
|
||||||
|
int ret;
|
||||||
|
char* line;
|
||||||
|
|
||||||
|
if (!chat->from_sid)
|
||||||
|
{
|
||||||
|
printf("HUB ");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
user = user_get(chat->from_sid);
|
||||||
|
printf(" %s %s%s%s ", pm, brack1, user->name, brack2);
|
||||||
|
}
|
||||||
|
|
||||||
|
lines = list_create();
|
||||||
|
ret = split_string(chat->message, "\n", lines, 1);
|
||||||
|
|
||||||
|
line = (char*) list_get_first(lines);
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
while (line)
|
||||||
|
{
|
||||||
|
if (ret > 0)
|
||||||
|
printf(" ");
|
||||||
|
printf("%s\n", line);
|
||||||
|
ret++;
|
||||||
|
line = (char*) list_get_next(lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
list_clear(lines, &hub_free);
|
||||||
|
list_destroy(lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void status(const char* msg)
|
||||||
|
{
|
||||||
|
printf("*** %s\n", msg);
|
||||||
|
}
|
||||||
|
|
||||||
static int handle(struct ADC_client* client, enum ADC_client_callback_type type, struct ADC_client_callback_data* data)
|
static int handle(struct ADC_client* client, enum ADC_client_callback_type type, struct ADC_client_callback_data* data)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
|
case ADC_CLIENT_NAME_LOOKUP:
|
||||||
|
status("Looking up hostname...");
|
||||||
|
break;
|
||||||
|
|
||||||
case ADC_CLIENT_CONNECTING:
|
case ADC_CLIENT_CONNECTING:
|
||||||
puts("*** Connecting...");
|
status("Connecting...");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ADC_CLIENT_CONNECTED:
|
case ADC_CLIENT_CONNECTED:
|
||||||
puts("*** Connected.");
|
status("Connected.");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ADC_CLIENT_DISCONNECTED:
|
case ADC_CLIENT_DISCONNECTED:
|
||||||
puts("*** Disconnected.");
|
status("Disconnected.");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ADC_CLIENT_SSL_HANDSHAKE:
|
case ADC_CLIENT_SSL_HANDSHAKE:
|
||||||
puts("*** SSL handshake.");
|
status("SSL handshake.");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ADC_CLIENT_SSL_OK:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ADC_CLIENT_LOGGING_IN:
|
case ADC_CLIENT_LOGGING_IN:
|
||||||
puts("*** Logging in...");
|
status("Logging in...");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ADC_CLIENT_PASSWORD_REQ:
|
case ADC_CLIENT_PASSWORD_REQ:
|
||||||
puts("*** Requesting password.");
|
status("Requesting password.");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ADC_CLIENT_LOGGED_IN:
|
case ADC_CLIENT_LOGGED_IN:
|
||||||
puts("*** Logged in.");
|
status("Logged in.");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ADC_CLIENT_LOGIN_ERROR:
|
case ADC_CLIENT_LOGIN_ERROR:
|
||||||
puts("*** Login error");
|
status("Login error");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case ADC_CLIENT_MESSAGE:
|
case ADC_CLIENT_MESSAGE:
|
||||||
printf(" <%s> %s\n", sid_to_string(data->chat->from_sid), data->chat->message);
|
on_message(data->chat);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ADC_CLIENT_USER_JOIN:
|
case ADC_CLIENT_USER_JOIN:
|
||||||
printf(" JOIN: %s %s\n", sid_to_string(data->user->sid), data->user->name);
|
|
||||||
|
user_add(data->user);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ADC_CLIENT_USER_QUIT:
|
case ADC_CLIENT_USER_QUIT:
|
||||||
printf(" QUIT\n");
|
user_remove(data->quit);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ADC_CLIENT_SEARCH_REQ:
|
case ADC_CLIENT_SEARCH_REQ:
|
||||||
@@ -85,6 +161,68 @@ static int handle(struct ADC_client* client, enum ADC_client_callback_type type,
|
|||||||
|
|
||||||
static int running = 1;
|
static int running = 1;
|
||||||
|
|
||||||
|
#if !defined(WIN32)
|
||||||
|
void adm_handle_signal(int sig)
|
||||||
|
{
|
||||||
|
switch (sig)
|
||||||
|
{
|
||||||
|
case SIGINT:
|
||||||
|
LOG_INFO("Interrupted. Shutting down...");
|
||||||
|
running = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIGTERM:
|
||||||
|
LOG_INFO("Terminated. Shutting down...");
|
||||||
|
running = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIGPIPE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIGHUP:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
LOG_TRACE("hub_handle_signal(): caught unknown signal: %d", signal);
|
||||||
|
running = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int signals[] =
|
||||||
|
{
|
||||||
|
SIGINT, /* Interrupt the application */
|
||||||
|
SIGTERM, /* Terminate the application */
|
||||||
|
SIGPIPE, /* prevent sigpipe from kills the application */
|
||||||
|
SIGHUP, /* reload configuration */
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
void adm_setup_signal_handlers()
|
||||||
|
{
|
||||||
|
sigset_t sig_set;
|
||||||
|
struct sigaction act;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
sigemptyset(&sig_set);
|
||||||
|
act.sa_mask = sig_set;
|
||||||
|
act.sa_flags = SA_ONSTACK | SA_RESTART;
|
||||||
|
act.sa_handler = adm_handle_signal;
|
||||||
|
|
||||||
|
for (i = 0; signals[i]; i++)
|
||||||
|
{
|
||||||
|
if (sigaction(signals[i], &act, 0) != 0)
|
||||||
|
{
|
||||||
|
LOG_ERROR("Error setting signal handler %d", signals[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void adm_shutdown_signal_handlers()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif /* !WIN32 */
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
@@ -93,17 +231,23 @@ int main(int argc, char** argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ADC_client client;
|
hub_set_log_verbosity(5);
|
||||||
|
adm_setup_signal_handlers();
|
||||||
|
|
||||||
|
struct ADC_client* client;
|
||||||
net_initialize();
|
net_initialize();
|
||||||
|
|
||||||
ADC_client_create(&client, "uhub-admin", "stresstester");
|
memset(g_usermap, 0, sizeof(g_usermap));
|
||||||
ADC_client_set_callback(&client, handle);
|
|
||||||
ADC_client_connect(&client, argv[1]);
|
client = ADC_client_create("uhub-admin", "stresstester", NULL);
|
||||||
|
ADC_client_set_callback(client, handle);
|
||||||
|
ADC_client_connect(client, argv[1]);
|
||||||
|
|
||||||
while (running && net_backend_process()) { }
|
while (running && net_backend_process()) { }
|
||||||
|
|
||||||
ADC_client_destroy(&client);
|
ADC_client_destroy(client);
|
||||||
net_destroy();
|
net_destroy();
|
||||||
|
adm_shutdown_signal_handlers();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
10
src/uhub.h
10
src/uhub.h
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
#define TIMEOUT_CONNECTED 15
|
#define TIMEOUT_CONNECTED 15
|
||||||
#define TIMEOUT_HANDSHAKE 30
|
#define TIMEOUT_HANDSHAKE 30
|
||||||
#define TIMEOUT_SENDQ 120
|
#define TIMEOUT_SENDQ 120
|
||||||
#define TIMEOUT_STATS 60
|
#define TIMEOUT_STATS 10
|
||||||
|
|
||||||
#define MAX_CID_LEN 39
|
#define MAX_CID_LEN 39
|
||||||
#define MAX_NICK_LEN 64
|
#define MAX_NICK_LEN 64
|
||||||
@@ -63,18 +63,20 @@ extern "C" {
|
|||||||
#include "util/credentials.h"
|
#include "util/credentials.h"
|
||||||
#include "util/floodctl.h"
|
#include "util/floodctl.h"
|
||||||
#include "util/getopt.h"
|
#include "util/getopt.h"
|
||||||
#include "util/ipcalc.h"
|
|
||||||
#include "util/list.h"
|
#include "util/list.h"
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
#include "util/misc.h"
|
#include "util/misc.h"
|
||||||
#include "util/tiger.h"
|
#include "util/tiger.h"
|
||||||
|
#include "util/threads.h"
|
||||||
|
|
||||||
#include "adc/sid.h"
|
#include "adc/sid.h"
|
||||||
#include "adc/message.h"
|
#include "adc/message.h"
|
||||||
|
|
||||||
#include "network/network.h"
|
#include "network/network.h"
|
||||||
#include "network/connection.h"
|
#include "network/connection.h"
|
||||||
|
#include "network/dnsresolver.h"
|
||||||
|
#include "network/ipcalc.h"
|
||||||
#include "network/timeout.h"
|
#include "network/timeout.h"
|
||||||
|
|
||||||
#include "core/auth.h"
|
#include "core/auth.h"
|
||||||
@@ -82,7 +84,7 @@ extern "C" {
|
|||||||
#include "core/eventid.h"
|
#include "core/eventid.h"
|
||||||
#include "core/eventqueue.h"
|
#include "core/eventqueue.h"
|
||||||
#include "core/netevent.h"
|
#include "core/netevent.h"
|
||||||
#include "core/hubio.h"
|
#include "core/ioqueue.h"
|
||||||
#include "core/user.h"
|
#include "core/user.h"
|
||||||
#include "core/usermanager.h"
|
#include "core/usermanager.h"
|
||||||
#include "core/route.h"
|
#include "core/route.h"
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ extern struct cbuffer* cbuf_create(size_t capacity)
|
|||||||
buf->size = 0;
|
buf->size = 0;
|
||||||
buf->flags = 0;
|
buf->flags = 0;
|
||||||
buf->buf = hub_malloc(capacity + 1);
|
buf->buf = hub_malloc(capacity + 1);
|
||||||
|
buf->buf[0] = '\0';
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -305,6 +305,27 @@ int is_number(const char* value, int* num)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char* format_size(size_t bytes, char* buf, size_t bufsize)
|
||||||
|
{
|
||||||
|
static const char* quant[] = { "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB" };
|
||||||
|
size_t b = bytes;
|
||||||
|
size_t factor = 0;
|
||||||
|
size_t divisor = 1;
|
||||||
|
while (b > 1024)
|
||||||
|
{
|
||||||
|
factor++;
|
||||||
|
b = (b >> 10);
|
||||||
|
divisor = (divisor << 10);
|
||||||
|
}
|
||||||
|
uhub_assert(factor < (sizeof(quant) / sizeof(const char*)));
|
||||||
|
if (factor >= 2)
|
||||||
|
snprintf(buf, bufsize, "%.1f %s", (double) bytes / (double) divisor, quant[factor]);
|
||||||
|
else
|
||||||
|
snprintf(buf, bufsize, PRINTF_SIZE_T " %s", bytes / divisor, quant[factor]);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const char* uhub_itoa(int val)
|
const char* uhub_itoa(int val)
|
||||||
{
|
{
|
||||||
static char buf[22];
|
static char buf[22];
|
||||||
|
|||||||
@@ -42,6 +42,19 @@ extern char* strip_off_quotes(char* line);
|
|||||||
*/
|
*/
|
||||||
extern int is_number(const char* str, int* num);
|
extern int is_number(const char* str, int* num);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert the 'bytes' number into a formatted byte size string.
|
||||||
|
* E.g. "129012" becomes "125.99 KB".
|
||||||
|
* Note, if the output buffer is not large enough then the output
|
||||||
|
* will be truncated. The buffer will always be \0 terminated.
|
||||||
|
*
|
||||||
|
* @param bytes the number that should be formatted.
|
||||||
|
* @param[out] buf the buffer the string should be formatted into
|
||||||
|
* @param bufsize the size of 'buf'
|
||||||
|
* @return A pointer to buf.
|
||||||
|
*/
|
||||||
|
extern const char* format_size(size_t bytes, char* buf, size_t bufsize);
|
||||||
|
|
||||||
extern int file_read_lines(const char* file, void* data, file_line_handler_t handler);
|
extern int file_read_lines(const char* file, void* data, file_line_handler_t handler);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2009, Jan Vidar Krey
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -17,84 +17,141 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if 0
|
#include "uhub.h"
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include "rbtree.h"
|
#include "rbtree.h"
|
||||||
|
|
||||||
#define RED 0
|
// #define RB_TREE_CHECKS
|
||||||
#define BLACK 1
|
|
||||||
|
|
||||||
struct rb_node
|
|
||||||
{
|
|
||||||
const void* key;
|
|
||||||
const void* value; /* data */
|
|
||||||
int color;
|
|
||||||
struct rb_node* parent;
|
|
||||||
struct rb_node* left;
|
|
||||||
struct rb_node* right;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rb_tree
|
|
||||||
{
|
|
||||||
struct rb_node* root;
|
|
||||||
size_t elements;
|
|
||||||
rb_tree_alloc alloc;
|
|
||||||
rb_tree_free free;
|
|
||||||
rb_tree_compare compare;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* returns the grandparent of a node, if it exits */
|
|
||||||
static inline struct rb_node* get_grandparent(struct rb_node* n)
|
|
||||||
{
|
|
||||||
if (n->parent)
|
|
||||||
return n->parent->parent;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct rb_node* get_uncle(struct rb_node* n)
|
|
||||||
{
|
|
||||||
struct rb_node* gparent = n->parent ? n->parent->parent : 0;
|
|
||||||
if (gparent)
|
|
||||||
return (n->parent == gparent->left) ? gparent->right : gparent->left;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct rb_node* tree_search(struct rb_tree* tree, const void* key)
|
static struct rb_node* tree_search(struct rb_tree* tree, const void* key)
|
||||||
{
|
{
|
||||||
struct rb_node* node = tree->root;
|
struct rb_node* node = tree->root;
|
||||||
while (node)
|
while (node)
|
||||||
{
|
{
|
||||||
int res = tree->compare(key, node->key);
|
int res = tree->compare(node->key, key);
|
||||||
if (res < 0) node = node->left;
|
if (!res)
|
||||||
else if (res > 0) node = node->right;
|
break;
|
||||||
else return node;
|
node = node->link[res < 0];
|
||||||
}
|
}
|
||||||
return 0;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct rb_node* tree_insert(struct rb_tree* tree, const void* key, const void* value)
|
static struct rb_node* create_node(struct rb_tree* tree, const void* key, const void* value)
|
||||||
{
|
{
|
||||||
struct rb_node* node = tree->root;
|
struct rb_node* node = tree->alloc(sizeof(struct rb_node));
|
||||||
struct rb_node* newnode = tree->alloc(sizeof(struct rb_node));
|
node->key = key;
|
||||||
newnode->key = key;
|
node->value = value;
|
||||||
newnode->value = value;
|
node->red = 1;
|
||||||
newnode->color = RED;
|
node->link[0] = 0;
|
||||||
|
node->link[1] = 0;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int is_red(struct rb_node* node)
|
||||||
|
{
|
||||||
|
return node && node->red;
|
||||||
|
}
|
||||||
|
|
||||||
while (node)
|
#ifdef RB_TREE_CHECKS
|
||||||
{
|
int rb_tree_check(struct rb_tree* tree, struct rb_node* node)
|
||||||
int res = tree->compare(key, node->key);
|
{
|
||||||
if (res < 0) node = node->left;
|
int lh, rh;
|
||||||
else if (res > 0) node = node->right;
|
|
||||||
|
if (node == NULL)
|
||||||
|
return 1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* key already exists in tree */
|
struct rb_node *ln = node->link[0];
|
||||||
return node;
|
struct rb_node *rn = node->link[1];
|
||||||
|
|
||||||
|
/* Consecutive red links */
|
||||||
|
if (is_red(node)) {
|
||||||
|
if (is_red(ln) || is_red(rn))
|
||||||
|
{
|
||||||
|
puts("Red violation");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return newnode;
|
lh = rb_tree_check(tree, ln);
|
||||||
|
rh = rb_tree_check(tree, rn);
|
||||||
|
|
||||||
|
/* Invalid binary search tree - not sorted correctly */
|
||||||
|
if ((ln && tree->compare(ln->key, node->key) >= 0) || (rn && tree->compare(rn->key, node->key) <= 0))
|
||||||
|
{
|
||||||
|
puts("Binary tree violation");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Black height mismatch */
|
||||||
|
if ( lh != 0 && rh != 0 && lh != rh ) {
|
||||||
|
puts ( "Black violation" );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only count black links */
|
||||||
|
if (lh != 0 && rh != 0)
|
||||||
|
return is_red(node) ? lh : lh + 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // RB_TREE_CHECKS
|
||||||
|
|
||||||
|
static struct rb_node* rb_tree_rotate_single(struct rb_node* node, int dir)
|
||||||
|
{
|
||||||
|
struct rb_node* other = node->link[!dir];
|
||||||
|
|
||||||
|
node->link[!dir] = other->link[dir];
|
||||||
|
other->link[dir] = node;
|
||||||
|
|
||||||
|
node->red = 1;
|
||||||
|
other->red = 0;
|
||||||
|
return other;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct rb_node* rb_tree_rotate_double(struct rb_node* node, int dir)
|
||||||
|
{
|
||||||
|
node->link[!dir] = rb_tree_rotate_single(node->link[!dir], !dir);
|
||||||
|
return rb_tree_rotate_single(node, dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct rb_node* rb_tree_insert_r(struct rb_tree* tree, struct rb_node* node, const void* key, const void* value)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
if (!node)
|
||||||
|
return create_node(tree, key, value);
|
||||||
|
|
||||||
|
res = tree->compare(node->key, key);
|
||||||
|
if (!res)
|
||||||
|
{
|
||||||
|
puts("Node already exists!");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int dir = res < 0;
|
||||||
|
node->link[dir] = rb_tree_insert_r(tree, node->link[dir], key, value);
|
||||||
|
|
||||||
|
if (is_red(node->link[dir]))
|
||||||
|
{
|
||||||
|
if (is_red(node->link[!dir]))
|
||||||
|
{
|
||||||
|
/* Case 1 */
|
||||||
|
node->red = 1;
|
||||||
|
node->link[0]->red = 0;
|
||||||
|
node->link[1]->red = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Cases 2 & 3 */
|
||||||
|
if (is_red(node->link[dir]->link[dir]))
|
||||||
|
node = rb_tree_rotate_single(node, !dir);
|
||||||
|
else if (is_red(node->link[dir]->link[!dir]))
|
||||||
|
node = rb_tree_rotate_double(node, !dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -102,36 +159,224 @@ struct rb_tree* rb_tree_create(rb_tree_compare compare, rb_tree_alloc a, rb_tree
|
|||||||
{
|
{
|
||||||
struct rb_tree* tree = a(sizeof(struct rb_tree));
|
struct rb_tree* tree = a(sizeof(struct rb_tree));
|
||||||
tree->compare = compare;
|
tree->compare = compare;
|
||||||
tree->alloc = a;
|
tree->alloc = a ? a : hub_malloc;
|
||||||
tree->free = f;
|
tree->free = f ? f : hub_free;
|
||||||
|
tree->root = NULL;
|
||||||
|
tree->elements = 0;
|
||||||
|
tree->iterator.node = NULL;
|
||||||
|
tree->iterator.stack = list_create();
|
||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void rb_tree_destroy(struct rb_tree* tree)
|
void rb_tree_destroy(struct rb_tree* tree)
|
||||||
{
|
{
|
||||||
rb_tree_free f = tree->free;
|
list_destroy(tree->iterator.stack);
|
||||||
f(tree);
|
tree->free(tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* rb_tree_insert(struct rb_tree* tree, const void* key, const void* value)
|
int rb_tree_insert(struct rb_tree* tree, const void* key, const void* value)
|
||||||
{
|
{
|
||||||
struct rb_node* node = tree_insert(tree, key, value);
|
struct rb_node* node;
|
||||||
if (node)
|
if (tree_search(tree, key))
|
||||||
return (void*) node->value;
|
|
||||||
return 0;
|
return 0;
|
||||||
|
node = rb_tree_insert_r(tree, tree->root, key, value);
|
||||||
|
tree->root = node;
|
||||||
|
tree->root->red = 0;
|
||||||
|
tree->elements++;
|
||||||
|
#ifdef RB_TREE_CHECKS
|
||||||
|
rb_tree_check(tree, node);
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* rb_tree_remove(struct rb_tree* tree, const void* key)
|
void null_node_free(struct rb_node* n) { }
|
||||||
{
|
|
||||||
|
|
||||||
|
int rb_tree_remove(struct rb_tree* tree, const void* key)
|
||||||
|
{
|
||||||
|
return rb_tree_remove_node(tree, key, &null_node_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
int rb_tree_remove_node(struct rb_tree* tree, const void* key, rb_tree_free_node freecb)
|
||||||
|
{
|
||||||
|
struct rb_node head = {0}; /* False tree root */
|
||||||
|
struct rb_node *q, *p, *g; /* Helpers */
|
||||||
|
struct rb_node *f = NULL; /* Found item */
|
||||||
|
int dir = 1;
|
||||||
|
|
||||||
|
if (!tree->root)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Set up helpers */
|
||||||
|
q = &head;
|
||||||
|
g = p = NULL;
|
||||||
|
q->link[1] = tree->root;
|
||||||
|
|
||||||
|
/* Search and push a red down */
|
||||||
|
while (q->link[dir])
|
||||||
|
{
|
||||||
|
int last = dir;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
/* Update helpers */
|
||||||
|
g = p, p = q;
|
||||||
|
q = q->link[dir];
|
||||||
|
res = tree->compare(q->key, key);
|
||||||
|
dir = res < 0;
|
||||||
|
|
||||||
|
/* Save found node */
|
||||||
|
if (!res)
|
||||||
|
f = q;
|
||||||
|
|
||||||
|
/* Push the red node down */
|
||||||
|
if (!is_red(q) && !is_red(q->link[dir]))
|
||||||
|
{
|
||||||
|
if (is_red(q->link[!dir]))
|
||||||
|
p = p->link[last] = rb_tree_rotate_single(q, dir);
|
||||||
|
else if (!is_red(q->link[!dir]))
|
||||||
|
{
|
||||||
|
struct rb_node* s = p->link[!last];
|
||||||
|
if (s)
|
||||||
|
{
|
||||||
|
if (!is_red(s->link[!last]) && !is_red (s->link[last]))
|
||||||
|
{
|
||||||
|
/* Color flip */
|
||||||
|
p->red = 0;
|
||||||
|
s->red = 1;
|
||||||
|
q->red = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int dir2 = g->link[1] == p;
|
||||||
|
if (is_red(s->link[last]))
|
||||||
|
g->link[dir2] = rb_tree_rotate_double(p, last);
|
||||||
|
else if (is_red(s->link[!last]))
|
||||||
|
g->link[dir2] = rb_tree_rotate_single(p, last);
|
||||||
|
|
||||||
|
/* Ensure correct coloring */
|
||||||
|
q->red = g->link[dir2]->red = 1;
|
||||||
|
g->link[dir2]->link[0]->red = 0;
|
||||||
|
g->link[dir2]->link[1]->red = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Replace and remove if found */
|
||||||
|
if (f)
|
||||||
|
{
|
||||||
|
freecb(f);
|
||||||
|
f->key = q->key;
|
||||||
|
f->value = q->value;
|
||||||
|
p->link[p->link[1] == q] = q->link[q->link[0] == NULL];
|
||||||
|
tree->free(q);
|
||||||
|
tree->elements--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update root and make it black */
|
||||||
|
tree->root = head.link[1];
|
||||||
|
if (tree->root != NULL)
|
||||||
|
tree->root->red = 0;
|
||||||
|
|
||||||
|
#ifdef RB_TREE_CHECKS
|
||||||
|
rb_tree_check(tree, tree->root);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return f != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* rb_tree_get(struct rb_tree* tree, const void* key)
|
void* rb_tree_get(struct rb_tree* tree, const void* key)
|
||||||
{
|
{
|
||||||
struct rb_node* node = tree_search(tree, key);
|
struct rb_node* node = tree_search(tree, key);
|
||||||
if (node)
|
if (node)
|
||||||
return node->value;
|
return (void*) node->value;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
size_t rb_tree_size(struct rb_tree* tree)
|
||||||
|
{
|
||||||
|
return tree->elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void push(struct rb_tree* tree, struct rb_node* n)
|
||||||
|
{
|
||||||
|
list_append(tree->iterator.stack, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct rb_node* pop(struct rb_tree* tree)
|
||||||
|
{
|
||||||
|
struct rb_node* n = list_get_last(tree->iterator.stack);
|
||||||
|
if (n)
|
||||||
|
list_remove(tree->iterator.stack, n);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct rb_node* rb_it_set(struct rb_tree* tree, struct rb_node* n)
|
||||||
|
{
|
||||||
|
tree->iterator.node = n;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void null_free(void* ptr) { }
|
||||||
|
|
||||||
|
struct rb_node* rb_tree_first(struct rb_tree* tree)
|
||||||
|
{
|
||||||
|
struct rb_node* n = tree->root;
|
||||||
|
list_clear(tree->iterator.stack, &null_free);
|
||||||
|
while (n->link[0])
|
||||||
|
{
|
||||||
|
push(tree, n);
|
||||||
|
n = n->link[0];
|
||||||
|
}
|
||||||
|
return rb_it_set(tree, n);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static struct rb_node* rb_tree_traverse(struct rb_tree* tree, int dir)
|
||||||
|
{
|
||||||
|
struct rb_node* n = tree->iterator.node;
|
||||||
|
struct rb_node* p; /* parent */
|
||||||
|
|
||||||
|
if (n->link[dir])
|
||||||
|
{
|
||||||
|
push(tree, n);
|
||||||
|
n = n->link[dir];
|
||||||
|
while (n->link[!dir])
|
||||||
|
{
|
||||||
|
list_append(tree->iterator.stack, n);
|
||||||
|
n = n->link[!dir];
|
||||||
|
}
|
||||||
|
return rb_it_set(tree, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Need to walk upwards to the parent node.
|
||||||
|
p = pop(tree);
|
||||||
|
if (p)
|
||||||
|
{
|
||||||
|
// walk up in opposite direction
|
||||||
|
if (p->link[!dir] == n)
|
||||||
|
return rb_it_set(tree, p);
|
||||||
|
|
||||||
|
// walk up in hte current direction
|
||||||
|
while (p->link[dir] == n)
|
||||||
|
{
|
||||||
|
n = p;
|
||||||
|
p = pop(tree);
|
||||||
|
if (!p)
|
||||||
|
return rb_it_set(tree, NULL);
|
||||||
|
}
|
||||||
|
return rb_it_set(tree, p);
|
||||||
|
}
|
||||||
|
return rb_it_set(tree, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct rb_node* rb_tree_next(struct rb_tree* tree)
|
||||||
|
{
|
||||||
|
return rb_tree_traverse(tree, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct rb_node* rb_tree_prev(struct rb_tree* tree)
|
||||||
|
{
|
||||||
|
return rb_tree_traverse(tree, 0);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2009, Jan Vidar Krey
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -20,19 +20,122 @@
|
|||||||
#ifndef HAVE_UHUB_RED_BLACK_TREE_H
|
#ifndef HAVE_UHUB_RED_BLACK_TREE_H
|
||||||
#define HAVE_UHUB_RED_BLACK_TREE_H
|
#define HAVE_UHUB_RED_BLACK_TREE_H
|
||||||
|
|
||||||
struct rb_tree;
|
struct rb_node
|
||||||
|
{
|
||||||
|
const void* key;
|
||||||
|
const void* value; /* data */
|
||||||
|
int red;
|
||||||
|
struct rb_node* link[2];
|
||||||
|
};
|
||||||
|
|
||||||
typedef int (*rb_tree_compare)(const void* a, const void* b);
|
typedef int (*rb_tree_compare)(const void* a, const void* b);
|
||||||
typedef void* (*rb_tree_alloc)(size_t);
|
typedef void* (*rb_tree_alloc)(size_t);
|
||||||
typedef void (*rb_tree_free)(void*);
|
typedef void (*rb_tree_free)(void*);
|
||||||
|
typedef void (*rb_tree_free_node)(struct rb_node*);
|
||||||
|
|
||||||
|
struct rb_iterator
|
||||||
|
{
|
||||||
|
struct rb_node* node; // current node.
|
||||||
|
struct linked_list* stack; // stack from the top -- needed since we don't have parent pointers.
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rb_tree
|
||||||
|
{
|
||||||
|
struct rb_node* root;
|
||||||
|
size_t elements;
|
||||||
|
rb_tree_alloc alloc;
|
||||||
|
rb_tree_free free;
|
||||||
|
rb_tree_compare compare;
|
||||||
|
struct rb_iterator iterator;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
extern struct rb_tree* rb_tree_create(rb_tree_compare, rb_tree_alloc, rb_tree_free);
|
|
||||||
|
/**
|
||||||
|
* Create a tree.
|
||||||
|
*
|
||||||
|
* @param compare Comparison function
|
||||||
|
* @param alloc Allocator (if NULL then hub_malloc() is used)
|
||||||
|
* @param dealloc Deallocator (if NULL then hub_free() is used)
|
||||||
|
* @return a tree handle.
|
||||||
|
*/
|
||||||
|
extern struct rb_tree* rb_tree_create(rb_tree_compare compare, rb_tree_alloc alloc, rb_tree_free dealloc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes the tree and all the nodes.
|
||||||
|
* But not the content inside the nodes.
|
||||||
|
*/
|
||||||
extern void rb_tree_destroy(struct rb_tree*);
|
extern void rb_tree_destroy(struct rb_tree*);
|
||||||
|
|
||||||
extern void* rb_tree_insert(struct rb_tree* tree, const void* key, const void* data);
|
/**
|
||||||
extern void* rb_tree_remove(struct rb_tree* tree, const void* key);
|
* Insert a key into the tree, returns 1 if successful,
|
||||||
|
* or 0 if the key already existed.
|
||||||
|
*/
|
||||||
|
extern int rb_tree_insert(struct rb_tree* tree, const void* key, const void* data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a key from the tree.
|
||||||
|
* Returns 1 if the node was removed, or 0 if it was not removed (i.e. not found!)
|
||||||
|
*
|
||||||
|
* NOTE: the content of the node is not freed if it needs to be then use rb_tree_remove_node
|
||||||
|
* where you can specify a callback cleanup function.
|
||||||
|
*/
|
||||||
|
extern int rb_tree_remove(struct rb_tree* tree, const void* key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the node, but call the free callback before the node is removed.
|
||||||
|
* This is useful in cases where you need to deallocate the key and/or value from the node.
|
||||||
|
* Returns 1 if the node was removed, or 0 if not found.
|
||||||
|
*/
|
||||||
|
extern int rb_tree_remove_node(struct rb_tree* tree, const void* key, rb_tree_free_node free);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns NULL if the key was not found in the tree.
|
||||||
|
*/
|
||||||
extern void* rb_tree_get(struct rb_tree* tree, const void* key);
|
extern void* rb_tree_get(struct rb_tree* tree, const void* key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of elements inside the tree.
|
||||||
|
*/
|
||||||
|
extern size_t rb_tree_size(struct rb_tree* tree);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the first node in the tree.
|
||||||
|
* (leftmost, or lowest value in sorted order).
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* <code>
|
||||||
|
* struct rb_node* it;
|
||||||
|
* for (it = rb_tree_first(tree); it; it = rb_tree_next())
|
||||||
|
* {
|
||||||
|
* void* key = rb_iterator_key(it);
|
||||||
|
* void* value = rb_iterator_value(it);
|
||||||
|
* }
|
||||||
|
* </code>
|
||||||
|
*/
|
||||||
|
extern struct rb_node* rb_tree_first(struct rb_tree* tree);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Points the iterator at the next node.
|
||||||
|
* If the next node is NULL then the iterator becomes NULL too.
|
||||||
|
*/
|
||||||
|
extern struct rb_node* rb_tree_next(struct rb_tree* tree);
|
||||||
|
extern struct rb_node* rb_tree_prev(struct rb_tree* tree);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returnst the key of the node pointed to by the iterator.
|
||||||
|
* If this iterator is the same as rb_tree_end() then NULL is returned.
|
||||||
|
*/
|
||||||
|
extern void* rb_iterator_key(struct rb_iterator* it);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returnst the value of the node pointed to by the iterator.
|
||||||
|
* If this iterator is the same as rb_tree_end() then the behavior is undefined.
|
||||||
|
*/
|
||||||
|
extern void* rb_iterator_value(struct rb_iterator* it);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* HAVE_UHUB_RED_BLACK_TREE_H */
|
#endif /* HAVE_UHUB_RED_BLACK_TREE_H */
|
||||||
|
|
||||||
|
|||||||
149
src/util/threads.c
Normal file
149
src/util/threads.c
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uhub.h"
|
||||||
|
|
||||||
|
#ifdef POSIX_THREAD_SUPPORT
|
||||||
|
|
||||||
|
struct pthread_data
|
||||||
|
{
|
||||||
|
pthread_t handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
void uhub_mutex_init(uhub_mutex_t* mutex)
|
||||||
|
{
|
||||||
|
pthread_mutex_init(mutex, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uhub_mutex_destroy(uhub_mutex_t* mutex)
|
||||||
|
{
|
||||||
|
pthread_mutex_destroy(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uhub_mutex_lock(uhub_mutex_t* mutex)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uhub_mutex_unlock(uhub_mutex_t* mutex)
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
int uhub_mutex_trylock(uhub_mutex_t* mutex)
|
||||||
|
{
|
||||||
|
int ret = pthread_mutex_trylock(mutex);
|
||||||
|
return (ret == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uhub_thread_t* uhub_thread_create(uhub_thread_start start, void* arg)
|
||||||
|
{
|
||||||
|
struct pthread_data* thread = (struct pthread_data*) hub_malloc_zero(sizeof(struct pthread_data));
|
||||||
|
int ret = pthread_create(&thread->handle, NULL, start, arg);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
hub_free(thread);
|
||||||
|
thread = NULL;
|
||||||
|
}
|
||||||
|
return thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
void uhub_thread_cancel(uhub_thread_t* thread)
|
||||||
|
{
|
||||||
|
pthread_cancel(thread->handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* uhub_thread_join(uhub_thread_t* thread)
|
||||||
|
{
|
||||||
|
void* ret = NULL;
|
||||||
|
pthread_join(thread->handle, &ret);
|
||||||
|
hub_free(thread);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* POSIX_THREAD_SUPPORT */
|
||||||
|
|
||||||
|
#ifdef WINTHREAD_SUPPORT
|
||||||
|
|
||||||
|
struct winthread_data
|
||||||
|
{
|
||||||
|
uhub_thread_t* handle;
|
||||||
|
uhub_thread_start start;
|
||||||
|
void* arg;
|
||||||
|
};
|
||||||
|
|
||||||
|
static DWORD WINAPI uhub_winthread_start(void* ptr)
|
||||||
|
{
|
||||||
|
struct winthread_data* data = (struct winthread_data*) ptr;
|
||||||
|
DWORD ret = (DWORD) data->start(data->arg);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void uhub_mutex_init(uhub_mutex_t* mutex)
|
||||||
|
{
|
||||||
|
InitializeCriticalSection(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uhub_mutex_destroy(uhub_mutex_t* mutex)
|
||||||
|
{
|
||||||
|
DeleteCriticalSection(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uhub_mutex_lock(uhub_mutex_t* mutex)
|
||||||
|
{
|
||||||
|
EnterCriticalSection(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uhub_mutex_unlock(uhub_mutex_t* mutex)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
int uhub_mutex_trylock(uhub_mutex_t* mutex)
|
||||||
|
{
|
||||||
|
return TryEnterCriticalSection(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
uhub_thread_t* uhub_thread_create(uhub_thread_start start, void* arg)
|
||||||
|
{
|
||||||
|
struct winthread_data* thread = (struct winthread_data*) hub_malloc_zero(sizeof(struct winthread_data));
|
||||||
|
thread->start = start;
|
||||||
|
thread->arg = arg;
|
||||||
|
thread->handle = CreateThread(NULL, 0, uhub_winthread_start, thread, 0, 0);
|
||||||
|
return thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
void uhub_thread_cancel(uhub_thread_t* thread)
|
||||||
|
{
|
||||||
|
TerminateThread(thread->handle, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* uhub_thread_join(uhub_thread_t* thread)
|
||||||
|
{
|
||||||
|
void* ret = NULL;
|
||||||
|
DWORD exitCode;
|
||||||
|
WaitForSingleObject(thread->handle, INFINITE);
|
||||||
|
GetExitCodeThread(thread->handle, &exitCode);
|
||||||
|
ret = &exitCode;
|
||||||
|
CloseHandle(thread->handle);
|
||||||
|
hub_free(thread);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif /* WINTHREAD_SUPPORT */
|
||||||
49
src/util/threads.h
Normal file
49
src/util/threads.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HAVE_UHUB_UTIL_THREADS_H
|
||||||
|
#define HAVE_UHUB_UTIL_THREADS_H
|
||||||
|
|
||||||
|
typedef void*(*uhub_thread_start)(void*) ;
|
||||||
|
|
||||||
|
#ifdef POSIX_THREAD_SUPPORT
|
||||||
|
typedef struct pthread_data uhub_thread_t;
|
||||||
|
typedef pthread_mutex_t uhub_mutex_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WINTHREAD_SUPPORT
|
||||||
|
struct winthread_data;
|
||||||
|
typedef struct winthread_data uhub_thread_t;
|
||||||
|
typedef CRITICAL_SECTION uhub_mutex_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Mutexes
|
||||||
|
extern void uhub_mutex_init(uhub_mutex_t* mutex);
|
||||||
|
extern void uhub_mutex_destroy(uhub_mutex_t* mutex);
|
||||||
|
extern void uhub_mutex_lock(uhub_mutex_t* mutex);
|
||||||
|
extern void uhub_mutex_unlock(uhub_mutex_t* mutex);
|
||||||
|
extern int uhub_mutex_trylock(uhub_mutex_t* mutex);
|
||||||
|
|
||||||
|
// Threads
|
||||||
|
uhub_thread_t* uhub_thread_create(uhub_thread_start start, void* arg);
|
||||||
|
void uhub_thread_cancel(uhub_thread_t* thread);
|
||||||
|
void* uhub_thread_join(uhub_thread_t* thread);
|
||||||
|
|
||||||
|
#endif /* HAVE_UHUB_UTIL_THREADS_H */
|
||||||
|
|
||||||
36
src/version.h.in
Normal file
36
src/version.h.in
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* THIS FILE IS AUTO-GENERATED BY CMAKE - DO NOT EDIT MANUALLY! */
|
||||||
|
|
||||||
|
#ifndef VERSION
|
||||||
|
#define VERSION "@UHUB_VERSION_MAJOR@.@UHUB_VERSION_MINOR@.@UHUB_VERSION_PATCH@"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define GIT_VERSION "@UHUB_GIT_VERSION@"
|
||||||
|
|
||||||
|
#ifndef PRODUCT
|
||||||
|
#define PRODUCT "uhub"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PRODUCT_STRING PRODUCT "/" GIT_VERSION
|
||||||
|
|
||||||
|
#ifndef COPYRIGHT
|
||||||
|
#define COPYRIGHT "Copyright (c) 2007-2012, Jan Vidar Krey <janvidar@extatic.org>"
|
||||||
|
#endif
|
||||||
23
version.h
23
version.h
@@ -1,23 +0,0 @@
|
|||||||
#if !defined(_MSC_VER)
|
|
||||||
#include "revision.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PRODUCT
|
|
||||||
#define PRODUCT "uhub"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef VERSION
|
|
||||||
#define VERSION "0.4.0"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef GIT_REVISION
|
|
||||||
#define REVISION ""
|
|
||||||
#define PRODUCT_STRING PRODUCT "/" VERSION
|
|
||||||
#else
|
|
||||||
#define REVISION "git-" GIT_REVISION
|
|
||||||
#define PRODUCT_STRING PRODUCT "/" VERSION "-" REVISION
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef COPYRIGHT
|
|
||||||
#define COPYRIGHT "Copyright (c) 2007-2012, Jan Vidar Krey <janvidar@extatic.org>"
|
|
||||||
#endif
|
|
||||||
7
vs2010/.gitignore
vendored
7
vs2010/.gitignore
vendored
@@ -1,7 +0,0 @@
|
|||||||
*.vcproj.user
|
|
||||||
*.vcproj.filters
|
|
||||||
*.ncb
|
|
||||||
*.aps
|
|
||||||
*.suo
|
|
||||||
Debug
|
|
||||||
Release
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
</ItemGroup>
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<ProjectGuid>{A6674BB3-1B23-4E99-AF9B-1CCDB4EB049A}</ProjectGuid>
|
|
||||||
<RootNamespace>mod_auth_simple</RootNamespace>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
|
||||||
<ImportGroup Label="ExtensionSettings">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<PropertyGroup Label="UserMacros" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<IncludePath>$(SolutionDir)..\src;$(IncludePath)</IncludePath>
|
|
||||||
<LibraryPath>$(SolutionDir)vs2010\$(Configuration);$(LibraryPath)</LibraryPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<AdditionalDependencies>$(SolutionDir)\$(Configuration)\uhub_utils.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="..\..\..\src\plugins\mod_auth_simple.c" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
||||||
<ImportGroup Label="ExtensionTargets">
|
|
||||||
</ImportGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
</ItemGroup>
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<ProjectGuid>{0EF03E84-2720-4616-A5BE-4D5737F68445}</ProjectGuid>
|
|
||||||
<RootNamespace>mod_auth_sqlite</RootNamespace>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
|
||||||
<ImportGroup Label="ExtensionSettings">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<PropertyGroup Label="UserMacros" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<IncludePath>$(SolutionDir)..\src;$(IncludePath);$(SolutionDir)..\thirdparty\sqlite</IncludePath>
|
|
||||||
<LibraryPath>$(SolutionDir)vs2010\$(Configuration);$(LibraryPath)</LibraryPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<AdditionalDependencies>$(SolutionDir)\$(Configuration)\uhub_utils.lib;$(SolutionDir)\$(Configuration)\sqlite.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
<DelayLoadDLLs>
|
|
||||||
</DelayLoadDLLs>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="..\..\..\src\plugins\mod_auth_sqlite.c" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
||||||
<ImportGroup Label="ExtensionTargets">
|
|
||||||
</ImportGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
</ItemGroup>
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<ProjectGuid>{9BBAEFDA-8E0E-4E7F-B8B6-0050432FC45B}</ProjectGuid>
|
|
||||||
<Keyword>Win32Proj</Keyword>
|
|
||||||
<RootNamespace>mod_example</RootNamespace>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
|
||||||
<ImportGroup Label="ExtensionSettings">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<PropertyGroup Label="UserMacros" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<LinkIncremental>true</LinkIncremental>
|
|
||||||
<IncludePath>$(SolutionDir)..\src;$(IncludePath)</IncludePath>
|
|
||||||
<LibraryPath>$(SolutionDir)vs2010\$(Configuration);$(LibraryPath)</LibraryPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<LinkIncremental>false</LinkIncremental>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<PrecompiledHeader>
|
|
||||||
</PrecompiledHeader>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXAMPLE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Windows</SubSystem>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<AdditionalDependencies>$(SolutionDir)\$(Configuration)\uhub_utils.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<PrecompiledHeader>
|
|
||||||
</PrecompiledHeader>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXAMPLE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Windows</SubSystem>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="..\..\..\src\plugins\mod_example.c" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
||||||
<ImportGroup Label="ExtensionTargets">
|
|
||||||
</ImportGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
</ItemGroup>
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<ProjectGuid>{9BBAEFDA-8E0E-4E7F-B8B6-00A3432FC45B}</ProjectGuid>
|
|
||||||
<Keyword>Win32Proj</Keyword>
|
|
||||||
<RootNamespace>mod_topic</RootNamespace>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
|
||||||
<ImportGroup Label="ExtensionSettings">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<PropertyGroup Label="UserMacros" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<LinkIncremental>true</LinkIncremental>
|
|
||||||
<IncludePath>$(SolutionDir)..\src;$(IncludePath)</IncludePath>
|
|
||||||
<LibraryPath>$(SolutionDir)vs2010\$(Configuration);$(LibraryPath)</LibraryPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<LinkIncremental>false</LinkIncremental>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<PrecompiledHeader>
|
|
||||||
</PrecompiledHeader>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXAMPLE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Windows</SubSystem>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<AdditionalDependencies>$(SolutionDir)\$(Configuration)\uhub_utils.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<PrecompiledHeader>
|
|
||||||
</PrecompiledHeader>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXAMPLE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Windows</SubSystem>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="..\..\..\src\plugins\mod_topic.c" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
||||||
<ImportGroup Label="ExtensionTargets">
|
|
||||||
</ImportGroup>
|
|
||||||
</Project>
|
|
||||||
78
vs2010/thirdparty/sqlite/sqlite.vcxproj
vendored
78
vs2010/thirdparty/sqlite/sqlite.vcxproj
vendored
@@ -1,78 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="..\..\..\thirdparty\sqlite\shell.c" />
|
|
||||||
<ClCompile Include="..\..\..\thirdparty\sqlite\sqlite3.c" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="..\..\..\thirdparty\sqlite\sqlite3.h" />
|
|
||||||
<ClInclude Include="..\..\..\thirdparty\sqlite\sqlite3ext.h" />
|
|
||||||
</ItemGroup>
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<ProjectGuid>{A4FC9D62-D544-4D2A-88d7-A58529C3460B}</ProjectGuid>
|
|
||||||
<RootNamespace>sqlite</RootNamespace>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
|
||||||
<ImportGroup Label="ExtensionSettings">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<PropertyGroup Label="UserMacros" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<IncludePath>$(SolutionDir)..\src;$(IncludePath)</IncludePath>
|
|
||||||
<LibraryPath>$(SolutionDir)vs2010\$(Configuration);$(LibraryPath)</LibraryPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<AdditionalDependencies>$(SolutionDir)\$(Configuration)\uhub_utils.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
||||||
<ImportGroup Label="ExtensionTargets">
|
|
||||||
</ImportGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
</ItemGroup>
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<ProjectGuid>{E92EB860-AE9E-4532-A75F-0929A7BCF6D0}</ProjectGuid>
|
|
||||||
<Keyword>Win32Proj</Keyword>
|
|
||||||
<RootNamespace>uhubpasswd</RootNamespace>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
|
||||||
<ImportGroup Label="ExtensionSettings">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<PropertyGroup Label="UserMacros" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<LinkIncremental>true</LinkIncremental>
|
|
||||||
<LibraryPath>$(SolutionDir)vs2010\$(Configuration);$(LibraryPath)</LibraryPath>
|
|
||||||
<IncludePath>$(SolutionDir)..\src;$(IncludePath);$(SolutionDir)..\thirdparty\sqlite</IncludePath>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<LinkIncremental>false</LinkIncremental>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<PrecompiledHeader>
|
|
||||||
</PrecompiledHeader>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<AdditionalDependencies>$(SolutionDir)\$(Configuration)\uhub_utils.lib;$(SolutionDir)\$(Configuration)\sqlite.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<PrecompiledHeader>
|
|
||||||
</PrecompiledHeader>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="..\..\src\tools\uhub-passwd.c" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
||||||
<ImportGroup Label="ExtensionTargets">
|
|
||||||
</ImportGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
|
||||||
# Visual C++ Express 2010
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "uhub", "uhub.vcxproj", "{98D8BFE9-DACD-40E1-B7BE-C9079ABF832E}"
|
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
|
||||||
{0A3C1519-D877-47D9-A82E-40AC1BC79D75} = {0A3C1519-D877-47D9-A82E-40AC1BC79D75}
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "uhub_utils", "uhub_utils\uhub_utils.vcxproj", "{0A3C1519-D877-47D9-A82E-40AC1BC79D75}"
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_auth_simple", "plugins\mod_auth_simple\mod_auth_simple.vcxproj", "{A6674BB3-1B23-4E99-AF9B-1CCDB4EB049A}"
|
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
|
||||||
{0A3C1519-D877-47D9-A82E-40AC1BC79D75} = {0A3C1519-D877-47D9-A82E-40AC1BC79D75}
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_example", "plugins\mod_example\mod_example.vcxproj", "{9BBAEFDA-8E0E-4E7F-B8B6-0050432FC45B}"
|
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
|
||||||
{0A3C1519-D877-47D9-A82E-40AC1BC79D75} = {0A3C1519-D877-47D9-A82E-40AC1BC79D75}
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_auth_sqlite", "plugins\mod_auth_sqlite\mod_auth_sqlite.vcxproj", "{0EF03E84-2720-4616-A5BE-4D5737F68445}"
|
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
|
||||||
{0A3C1519-D877-47D9-A82E-40AC1BC79D75} = {0A3C1519-D877-47D9-A82E-40AC1BC79D75}
|
|
||||||
{A4FC9D62-D544-4D2A-88D7-A58529C3460B} = {A4FC9D62-D544-4D2A-88D7-A58529C3460B}
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sqlite", "thirdparty\sqlite\sqlite.vcxproj", "{A4FC9D62-D544-4D2A-88D7-A58529C3460B}"
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "uhub-passwd", "uhub-passwd\uhub-passwd.vcxproj", "{E92EB860-AE9E-4532-A75F-0929A7BCF6D0}"
|
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
|
||||||
{0A3C1519-D877-47D9-A82E-40AC1BC79D75} = {0A3C1519-D877-47D9-A82E-40AC1BC79D75}
|
|
||||||
{A4FC9D62-D544-4D2A-88D7-A58529C3460B} = {A4FC9D62-D544-4D2A-88D7-A58529C3460B}
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_topic", "plugins\mod_topic\mod_topic.vcxproj", "{9BBAEFDA-8E0E-4E7F-B8B6-00A3432FC45B}"
|
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
|
||||||
{0A3C1519-D877-47D9-A82E-40AC1BC79D75} = {0A3C1519-D877-47D9-A82E-40AC1BC79D75}
|
|
||||||
{98D8BFE9-DACD-40E1-B7BE-C9079ABF832E} = {98D8BFE9-DACD-40E1-B7BE-C9079ABF832E}
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
Debug|Win32 = Debug|Win32
|
|
||||||
Release|Win32 = Release|Win32
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{98D8BFE9-DACD-40E1-B7BE-C9079ABF832E}.Debug|Win32.ActiveCfg = Debug|Win32
|
|
||||||
{98D8BFE9-DACD-40E1-B7BE-C9079ABF832E}.Debug|Win32.Build.0 = Debug|Win32
|
|
||||||
{98D8BFE9-DACD-40E1-B7BE-C9079ABF832E}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{98D8BFE9-DACD-40E1-B7BE-C9079ABF832E}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
{0A3C1519-D877-47D9-A82E-40AC1BC79D75}.Debug|Win32.ActiveCfg = Debug|Win32
|
|
||||||
{0A3C1519-D877-47D9-A82E-40AC1BC79D75}.Debug|Win32.Build.0 = Debug|Win32
|
|
||||||
{0A3C1519-D877-47D9-A82E-40AC1BC79D75}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{0A3C1519-D877-47D9-A82E-40AC1BC79D75}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
{A6674BB3-1B23-4E99-AF9B-1CCDB4EB049A}.Debug|Win32.ActiveCfg = Debug|Win32
|
|
||||||
{A6674BB3-1B23-4E99-AF9B-1CCDB4EB049A}.Debug|Win32.Build.0 = Debug|Win32
|
|
||||||
{A6674BB3-1B23-4E99-AF9B-1CCDB4EB049A}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{A6674BB3-1B23-4E99-AF9B-1CCDB4EB049A}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
{9BBAEFDA-8E0E-4E7F-B8B6-0050432FC45B}.Debug|Win32.ActiveCfg = Debug|Win32
|
|
||||||
{9BBAEFDA-8E0E-4E7F-B8B6-0050432FC45B}.Debug|Win32.Build.0 = Debug|Win32
|
|
||||||
{9BBAEFDA-8E0E-4E7F-B8B6-0050432FC45B}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{9BBAEFDA-8E0E-4E7F-B8B6-0050432FC45B}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
{0EF03E84-2720-4616-A5BE-4D5737F68445}.Debug|Win32.ActiveCfg = Debug|Win32
|
|
||||||
{0EF03E84-2720-4616-A5BE-4D5737F68445}.Debug|Win32.Build.0 = Debug|Win32
|
|
||||||
{0EF03E84-2720-4616-A5BE-4D5737F68445}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{0EF03E84-2720-4616-A5BE-4D5737F68445}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
{A4FC9D62-D544-4D2A-88D7-A58529C3460B}.Debug|Win32.ActiveCfg = Debug|Win32
|
|
||||||
{A4FC9D62-D544-4D2A-88D7-A58529C3460B}.Debug|Win32.Build.0 = Debug|Win32
|
|
||||||
{A4FC9D62-D544-4D2A-88D7-A58529C3460B}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{A4FC9D62-D544-4D2A-88D7-A58529C3460B}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
{E92EB860-AE9E-4532-A75F-0929A7BCF6D0}.Debug|Win32.ActiveCfg = Debug|Win32
|
|
||||||
{E92EB860-AE9E-4532-A75F-0929A7BCF6D0}.Debug|Win32.Build.0 = Debug|Win32
|
|
||||||
{E92EB860-AE9E-4532-A75F-0929A7BCF6D0}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{E92EB860-AE9E-4532-A75F-0929A7BCF6D0}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
{9BBAEFDA-8E0E-4E7F-B8B6-00A3432FC45B}.Debug|Win32.ActiveCfg = Debug|Win32
|
|
||||||
{9BBAEFDA-8E0E-4E7F-B8B6-00A3432FC45B}.Debug|Win32.Build.0 = Debug|Win32
|
|
||||||
{9BBAEFDA-8E0E-4E7F-B8B6-00A3432FC45B}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{9BBAEFDA-8E0E-4E7F-B8B6-00A3432FC45B}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
</ItemGroup>
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<ProjectGuid>{98D8BFE9-DACD-40E1-B7BE-C9079ABF832E}</ProjectGuid>
|
|
||||||
<Keyword>Win32Proj</Keyword>
|
|
||||||
<RootNamespace>uhub</RootNamespace>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
|
||||||
<ImportGroup Label="ExtensionSettings">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<PropertyGroup Label="UserMacros" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<LinkIncremental>true</LinkIncremental>
|
|
||||||
<IncludePath>$(SolutionDir)..\src;$(IncludePath)</IncludePath>
|
|
||||||
<LibraryPath>$(SolutionDir)\$(Configuration);$(LibraryPath)</LibraryPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<LinkIncremental>false</LinkIncremental>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AdditionalIncludeDirectories>$(projectDir)..\src\</AdditionalIncludeDirectories>
|
|
||||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
|
||||||
<MinimalRebuild>false</MinimalRebuild>
|
|
||||||
<CompileAsManaged>false</CompileAsManaged>
|
|
||||||
<CompileAs>CompileAsC</CompileAs>
|
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies);ws2_32.lib;uhub_utils.lib</AdditionalDependencies>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="..\src\adc\message.c" />
|
|
||||||
<ClCompile Include="..\src\adc\sid.c" />
|
|
||||||
<ClCompile Include="..\src\core\auth.c" />
|
|
||||||
<ClCompile Include="..\src\core\commands.c" />
|
|
||||||
<ClCompile Include="..\src\core\command_parser.c" />
|
|
||||||
<ClCompile Include="..\src\core\config.c" />
|
|
||||||
<ClCompile Include="..\src\core\eventqueue.c" />
|
|
||||||
<ClCompile Include="..\src\core\hub.c" />
|
|
||||||
<ClCompile Include="..\src\core\hubevent.c" />
|
|
||||||
<ClCompile Include="..\src\core\hubio.c" />
|
|
||||||
<ClCompile Include="..\src\core\inf.c" />
|
|
||||||
<ClCompile Include="..\src\core\main.c" />
|
|
||||||
<ClCompile Include="..\src\core\netevent.c" />
|
|
||||||
<ClCompile Include="..\src\core\plugincallback.c" />
|
|
||||||
<ClCompile Include="..\src\core\plugininvoke.c" />
|
|
||||||
<ClCompile Include="..\src\core\pluginloader.c" />
|
|
||||||
<ClCompile Include="..\src\core\probe.c" />
|
|
||||||
<ClCompile Include="..\src\core\route.c" />
|
|
||||||
<ClCompile Include="..\src\core\user.c" />
|
|
||||||
<ClCompile Include="..\src\core\usermanager.c" />
|
|
||||||
<ClCompile Include="..\src\network\backend.c" />
|
|
||||||
<ClCompile Include="..\src\network\connection.c" />
|
|
||||||
<ClCompile Include="..\src\network\epoll.c" />
|
|
||||||
<ClCompile Include="..\src\network\kqueue.c" />
|
|
||||||
<ClCompile Include="..\src\network\network.c" />
|
|
||||||
<ClCompile Include="..\src\network\select.c" />
|
|
||||||
<ClCompile Include="..\src\network\timeout.c" />
|
|
||||||
<ClCompile Include="..\src\network\timer.c" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="..\src\adc\adcconst.h" />
|
|
||||||
<ClInclude Include="..\src\adc\message.h" />
|
|
||||||
<ClInclude Include="..\src\adc\sid.h" />
|
|
||||||
<ClInclude Include="..\src\core\auth.h" />
|
|
||||||
<ClInclude Include="..\src\core\commands.h" />
|
|
||||||
<ClInclude Include="..\src\core\commands_builtin.h" />
|
|
||||||
<ClInclude Include="..\src\core\command_parser.h" />
|
|
||||||
<ClInclude Include="..\src\core\config.h" />
|
|
||||||
<ClInclude Include="..\src\core\eventid.h" />
|
|
||||||
<ClInclude Include="..\src\core\eventqueue.h" />
|
|
||||||
<ClInclude Include="..\src\core\gen_config.h" />
|
|
||||||
<ClInclude Include="..\src\core\hub.h" />
|
|
||||||
<ClInclude Include="..\src\core\hubevent.h" />
|
|
||||||
<ClInclude Include="..\src\core\hubio.h" />
|
|
||||||
<ClInclude Include="..\src\core\inf.h" />
|
|
||||||
<ClInclude Include="..\src\core\netevent.h" />
|
|
||||||
<ClInclude Include="..\src\core\plugincallback.h" />
|
|
||||||
<ClInclude Include="..\src\core\plugininvoke.h" />
|
|
||||||
<ClInclude Include="..\src\core\pluginloader.h" />
|
|
||||||
<ClInclude Include="..\src\core\probe.h" />
|
|
||||||
<ClInclude Include="..\src\core\route.h" />
|
|
||||||
<ClInclude Include="..\src\core\user.h" />
|
|
||||||
<ClInclude Include="..\src\core\usermanager.h" />
|
|
||||||
<ClInclude Include="..\src\network\backend.h" />
|
|
||||||
<ClInclude Include="..\src\network\common.h" />
|
|
||||||
<ClInclude Include="..\src\network\connection.h" />
|
|
||||||
<ClInclude Include="..\src\network\network.h" />
|
|
||||||
<ClInclude Include="..\src\network\timeout.h" />
|
|
||||||
<ClInclude Include="..\src\plugin_api\command_api.h" />
|
|
||||||
<ClInclude Include="..\src\plugin_api\handle.h" />
|
|
||||||
<ClInclude Include="..\src\system.h" />
|
|
||||||
<ClInclude Include="..\src\uhub.h" />
|
|
||||||
<ClInclude Include="..\version.h" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
||||||
<ImportGroup Label="ExtensionTargets">
|
|
||||||
</ImportGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
</ItemGroup>
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<ProjectGuid>{0A3C1519-D877-47D9-A82E-40AC1BC79D75}</ProjectGuid>
|
|
||||||
<RootNamespace>uhub_utils</RootNamespace>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
|
||||||
<ImportGroup Label="ExtensionSettings">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<PropertyGroup Label="UserMacros" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<IncludePath>$(SolutionDir)..\src;$(IncludePath)</IncludePath>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
<AdditionalIncludeDirectories>
|
|
||||||
</AdditionalIncludeDirectories>
|
|
||||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="..\..\src\util\cbuffer.c" />
|
|
||||||
<ClCompile Include="..\..\src\util\config_token.c" />
|
|
||||||
<ClCompile Include="..\..\src\util\credentials.c" />
|
|
||||||
<ClCompile Include="..\..\src\util\floodctl.c" />
|
|
||||||
<ClCompile Include="..\..\src\util\getopt.c" />
|
|
||||||
<ClCompile Include="..\..\src\util\ipcalc.c" />
|
|
||||||
<ClCompile Include="..\..\src\util\list.c" />
|
|
||||||
<ClCompile Include="..\..\src\util\log.c" />
|
|
||||||
<ClCompile Include="..\..\src\util\memory.c" />
|
|
||||||
<ClCompile Include="..\..\src\util\misc.c" />
|
|
||||||
<ClCompile Include="..\..\src\util\rbtree.c" />
|
|
||||||
<ClCompile Include="..\..\src\util\tiger.c" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="..\..\src\util\cbuffer.h" />
|
|
||||||
<ClInclude Include="..\..\src\util\config_token.h" />
|
|
||||||
<ClInclude Include="..\..\src\util\credentials.h" />
|
|
||||||
<ClInclude Include="..\..\src\util\floodctl.h" />
|
|
||||||
<ClInclude Include="..\..\src\util\getopt.h" />
|
|
||||||
<ClInclude Include="..\..\src\util\ipcalc.h" />
|
|
||||||
<ClInclude Include="..\..\src\util\list.h" />
|
|
||||||
<ClInclude Include="..\..\src\util\log.h" />
|
|
||||||
<ClInclude Include="..\..\src\util\memory.h" />
|
|
||||||
<ClInclude Include="..\..\src\util\misc.h" />
|
|
||||||
<ClInclude Include="..\..\src\util\rbtree.h" />
|
|
||||||
<ClInclude Include="..\..\src\util\tiger.h" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
||||||
<ImportGroup Label="ExtensionTargets">
|
|
||||||
</ImportGroup>
|
|
||||||
</Project>
|
|
||||||
Reference in New Issue
Block a user