Compare commits
202 Commits
gnutls_wor
...
master
Author | SHA1 | Date | |
---|---|---|---|
fdc1ccc68e | |||
0875ba15f5 | |||
|
35d8088b44 | ||
|
cff10910ad | ||
|
78a7039240 | ||
|
0ae96b0da8 | ||
|
022a9895ec | ||
|
891adb84fb | ||
|
9762b9389d | ||
|
076e75897b | ||
|
bc8974b9a3 | ||
|
1eb00ac04a | ||
|
cf3a6e06df | ||
|
cb04255006 | ||
|
2a57dc859d | ||
|
212064c166 | ||
|
56426f7b2a | ||
|
00bd8ba24d | ||
|
46906a9a9c | ||
|
566cd9a9db | ||
|
b27c44e633 | ||
|
d25fead3a8 | ||
|
ef83b31cec | ||
|
be1ad4f475 | ||
|
3435d53478 | ||
|
9038f56efe | ||
|
de01486c0f | ||
|
c383a53105 | ||
|
f0b67ea4cd | ||
|
ac96ace7df | ||
|
7970f80114 | ||
|
62216a7afe | ||
|
99711a5c6e | ||
|
e43aea35cc | ||
|
d54d723c59 | ||
|
c813231c8d | ||
|
debbca572f | ||
|
a8ee6e7f60 | ||
|
f0e9b2ffd9 | ||
|
ba19048ebc | ||
|
fd05f13fe4 | ||
|
11538d6909 | ||
|
90d05c9a19 | ||
|
ed5a59b16c | ||
|
70f2a43f67 | ||
|
dc80644471 | ||
|
889807da1b | ||
|
5151badbeb | ||
|
96cc46117f | ||
|
5e63ab2ccd | ||
|
32b7e68f00 | ||
|
5c5918a89d | ||
|
3f2641595b | ||
|
0e27e4219d | ||
|
e32bb3ff7a | ||
|
32c65ada49 | ||
|
77704f6e67 | ||
|
77323fa98d | ||
|
7840e09884 | ||
|
6ad5efea6d | ||
|
076daec846 | ||
|
223e01937e | ||
|
19068de088 | ||
|
c15f201d70 | ||
|
7bda215ad4 | ||
|
d86ef503b3 | ||
|
7865277324 | ||
|
8a7e892aeb | ||
|
05edfa48b2 | ||
|
204544298b | ||
|
418db22931 | ||
|
037ceff0a5 | ||
|
44708e8433 | ||
|
76ff2a1a13 | ||
|
280e28a6d4 | ||
|
c0ee55325c | ||
|
3d0b652ec9 | ||
|
2d45a37536 | ||
|
1da917e5b9 | ||
|
f71bc59527 | ||
|
d7c8c9426d | ||
|
4919aea8d5 | ||
|
95de69efeb | ||
|
b3b4876c08 | ||
|
ac543e3df4 | ||
|
46bdc77066 | ||
|
1526d63403 | ||
|
d33695435b | ||
|
bfdf707490 | ||
|
b8209d9d0a | ||
|
5c8d99d8ff | ||
|
4c5038c26d | ||
|
aeb006beb6 | ||
|
3b6c338ee8 | ||
|
652ac5f9b9 | ||
|
4263750bc5 | ||
|
2182feb052 | ||
|
48b76f7bd1 | ||
|
b5bedfe9e4 | ||
|
cbe0b4e108 | ||
|
b85381c0f5 | ||
|
0426cb523a | ||
|
9f78a2e85f | ||
|
f472fc9424 | ||
|
7706e1cb8a | ||
|
24b98358d3 | ||
|
12ce522a6d | ||
|
5e06b46deb | ||
|
a1f8c5bdbb | ||
|
992aa8c4af | ||
|
60393ca9d0 | ||
|
89aef4ddaf | ||
|
a38a82e318 | ||
|
3e8699ab24 | ||
|
3b38898045 | ||
|
1b8762c7ee | ||
|
ce06269128 | ||
|
e75a759693 | ||
|
7f2ffd7e1c | ||
|
e2b0757f4a | ||
|
c26e8aaefe | ||
|
c295461f4e | ||
|
8b442018a7 | ||
|
fa782e3d2c | ||
|
591d0ba5bb | ||
|
a81757c483 | ||
|
cf9be754aa | ||
|
22292e493e | ||
|
419e8888d0 | ||
|
73b4d51393 | ||
|
50b6221874 | ||
|
bb5865d368 | ||
|
550740f715 | ||
|
d73d213bc4 | ||
|
5672ba14e3 | ||
|
cd5c4ee622 | ||
|
52211a6bac | ||
|
f25015927a | ||
|
5835a06676 | ||
|
6c55ae1146 | ||
|
2d6f69d299 | ||
|
b81bb2cbd9 | ||
|
50e720861e | ||
|
d48ef710d8 | ||
|
cfa210b3f3 | ||
|
f6f7c7a3a4 | ||
|
1fbde2b0fd | ||
|
92b65a0e14 | ||
|
4d438e1e90 | ||
|
4f3c71234b | ||
|
fdaadccb99 | ||
|
41251f8d32 | ||
|
3b18ae251e | ||
|
b452488431 | ||
|
143b68588a | ||
|
5f2b7bc069 | ||
|
ce68c446d1 | ||
|
37c80fd403 | ||
|
dcc7aa4018 | ||
|
9dce6693f6 | ||
|
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 | ||
|
3a8c91004e | ||
|
deaadd053b | ||
|
c28a5d3a9b | ||
|
8b06a75d8e | ||
|
e6cb7a7e10 | ||
|
82caa6b81f | ||
|
ddfbb919a7 | ||
|
7fae42aa4d | ||
|
ba59e1a00e | ||
|
4fcfee8e82 | ||
|
63171b0ce2 | ||
|
dcfcf3110d | ||
|
53a5f5a243 | ||
|
af083efb0c | ||
|
e7aa63f3bd | ||
|
279c932b67 |
17
.drone.yml
Normal file
17
.drone.yml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
kind: pipeline
|
||||||
|
name: default
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: docker
|
||||||
|
image: plugins/docker
|
||||||
|
network_mode: bridge
|
||||||
|
settings:
|
||||||
|
repo: sneak/uhub
|
||||||
|
username:
|
||||||
|
from_secret: docker_username
|
||||||
|
password:
|
||||||
|
from_secret: docker_password
|
||||||
|
tags:
|
||||||
|
- ${DRONE_BRANCH//\//-}-${DRONE_COMMIT_SHA:0:8}
|
||||||
|
- ${DRONE_COMMIT_SHA}
|
||||||
|
- ${DRONE_BRANCH/\//-}
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -21,4 +21,3 @@ 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
|
|
2
.gitmodules
vendored
2
.gitmodules
vendored
@ -1,3 +1,3 @@
|
|||||||
[submodule "thirdparty/sqlite"]
|
[submodule "thirdparty/sqlite"]
|
||||||
path = thirdparty/sqlite
|
path = thirdparty/sqlite
|
||||||
url = git://github.com/janvidar/sqlite.git
|
url = https://github.com/janvidar/sqlite.git
|
||||||
|
14
.travis.yml
Normal file
14
.travis.yml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
language: cpp
|
||||||
|
dist: xenial
|
||||||
|
compiler:
|
||||||
|
- gcc
|
||||||
|
- clang
|
||||||
|
env:
|
||||||
|
- CONFIG=minimal
|
||||||
|
- CONFIG=full
|
||||||
|
install:
|
||||||
|
- autotest/travis/install-build-depends.sh
|
||||||
|
script:
|
||||||
|
- autotest/travis/build-and-test.sh
|
||||||
|
dist: xenial
|
||||||
|
|
10
AUTHORS
10
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, and plugins
|
||||||
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
|
||||||
|
3
BUGS
3
BUGS
@ -1,2 +1 @@
|
|||||||
Bugs are tracked on: http://bugs.extatic.org/
|
Bugs are tracked on: https://github.com/janvidar/uhub/issues
|
||||||
|
|
||||||
|
246
CMakeLists.txt
246
CMakeLists.txt
@ -1,27 +1,47 @@
|
|||||||
##
|
##
|
||||||
## Makefile for uhub
|
## Makefile for uhub
|
||||||
## Copyright (C) 2007-2012, Jan Vidar Krey <janvidar@extatic.org>
|
## Copyright (C) 2007-2013, Jan Vidar Krey <janvidar@extatic.org>
|
||||||
#
|
#
|
||||||
|
|
||||||
cmake_minimum_required (VERSION 2.8.3)
|
cmake_minimum_required (VERSION 2.8.2)
|
||||||
|
|
||||||
project (uhub NONE)
|
project (uhub NONE)
|
||||||
enable_language(C)
|
enable_language(C)
|
||||||
|
|
||||||
set (UHUB_VERSION_MAJOR 0)
|
set (UHUB_VERSION_MAJOR 0)
|
||||||
set (UHUB_VERSION_MINOR 4)
|
set (UHUB_VERSION_MINOR 5)
|
||||||
set (UHUB_VERSION_PATCH 1)
|
set (UHUB_VERSION_PATCH 1)
|
||||||
|
|
||||||
set (PROJECT_SOURCE_DIR "${CMAKE_SOURCE_DIR}/src")
|
set (PROJECT_SOURCE_DIR "${CMAKE_SOURCE_DIR}/src")
|
||||||
|
set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake/Modules)
|
||||||
|
|
||||||
option(RELEASE "Release build, debug build if disabled" ON)
|
option(RELEASE "Release build, debug build if disabled" ON)
|
||||||
option(LINK_SUPPORT "Allow hub linking" OFF)
|
option(LOWLEVEL_DEBUG, "Enable low level debug messages." OFF)
|
||||||
option(SSL_SUPPORT "Enable SSL support" ON)
|
option(SSL_SUPPORT "Enable SSL support" ON)
|
||||||
option(USE_OPENSSL "Use OpenSSL's SSL support" OFF)
|
option(USE_OPENSSL "Use OpenSSL's SSL support" ON )
|
||||||
option(SQLITE_SUPPORT "Enable SQLite support" ON)
|
option(SYSTEMD_SUPPORT "Enable systemd notify and journal logging" OFF)
|
||||||
option(ADC_STRESS "Enable the stress tester client" OFF)
|
option(ADC_STRESS "Enable the stress tester client" OFF)
|
||||||
|
|
||||||
find_package(Git)
|
find_package(Git)
|
||||||
|
find_package(Sqlite3)
|
||||||
|
|
||||||
|
include(TestBigEndian)
|
||||||
|
include(CheckSymbolExists)
|
||||||
|
include(CheckIncludeFile)
|
||||||
|
include(CheckTypeSize)
|
||||||
|
|
||||||
|
#Some functions need this to be found
|
||||||
|
add_definitions(-D_GNU_SOURCE)
|
||||||
|
set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D_GNU_SOURCE")
|
||||||
|
|
||||||
|
TEST_BIG_ENDIAN(BIGENDIAN)
|
||||||
|
if (BIGENDIAN)
|
||||||
|
add_definitions(-DARCH_BIGENDIAN)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (NOT RELEASE)
|
||||||
|
add_definitions(-DDEBUG)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (SSL_SUPPORT)
|
if (SSL_SUPPORT)
|
||||||
if (USE_OPENSSL)
|
if (USE_OPENSSL)
|
||||||
@ -30,67 +50,46 @@ if (SSL_SUPPORT)
|
|||||||
find_package(GnuTLS)
|
find_package(GnuTLS)
|
||||||
endif()
|
endif()
|
||||||
if (NOT GNUTLS_FOUND AND NOT OPENSSL_FOUND)
|
if (NOT GNUTLS_FOUND AND NOT OPENSSL_FOUND)
|
||||||
message(FATAL_ERROR "Neither OpenSSL nor GnuTLS are not found!")
|
message(FATAL_ERROR "Neither OpenSSL nor GnuTLS were found!")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (NOT SQLITE3_FOUND)
|
||||||
|
message(FATAL_ERROR "SQLite3 is not found!")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (SYSTEMD_SUPPORT)
|
||||||
|
INCLUDE(FindPkgConfig)
|
||||||
|
pkg_search_module(SD REQUIRED libsystemd)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
check_include_file(stdint.h HAVE_STDINT_H)
|
||||||
|
check_include_file(sys/types.h HAVE_SYS_TYPES_H)
|
||||||
|
if (HAVE_SYS_TYPES_H)
|
||||||
|
set (CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES} "sys/types.h")
|
||||||
|
endif()
|
||||||
|
check_type_size( ssize_t SSIZE_T )
|
||||||
|
check_symbol_exists(memmem string.h HAVE_MEMMEM)
|
||||||
|
check_symbol_exists(strndup string.h HAVE_STRNDUP)
|
||||||
|
|
||||||
include_directories("${PROJECT_SOURCE_DIR}")
|
include_directories("${PROJECT_SOURCE_DIR}")
|
||||||
|
include_directories("${PROJECT_BINARY_DIR}")
|
||||||
|
include_directories(${SQLITE3_INCLUDE_DIRS})
|
||||||
|
link_directories(${SQLITE3_LIBRARY_DIRS})
|
||||||
|
|
||||||
set (network_SOURCES
|
file (GLOB uhub_SOURCES ${PROJECT_SOURCE_DIR}/core/*.c)
|
||||||
${PROJECT_SOURCE_DIR}/network/backend.c
|
list (REMOVE_ITEM uhub_SOURCES
|
||||||
${PROJECT_SOURCE_DIR}/network/connection.c
|
${PROJECT_SOURCE_DIR}/core/gen_config.c
|
||||||
${PROJECT_SOURCE_DIR}/network/epoll.c
|
${PROJECT_SOURCE_DIR}/core/main.c
|
||||||
${PROJECT_SOURCE_DIR}/network/kqueue.c
|
|
||||||
${PROJECT_SOURCE_DIR}/network/select.c
|
|
||||||
${PROJECT_SOURCE_DIR}/network/timeout.c
|
|
||||||
${PROJECT_SOURCE_DIR}/network/timer.c
|
|
||||||
${PROJECT_SOURCE_DIR}/network/network.c
|
|
||||||
${PROJECT_SOURCE_DIR}/network/openssl.c
|
|
||||||
${PROJECT_SOURCE_DIR}/network/ipcalc.c
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set (uhub_SOURCES
|
file (GLOB adc_SOURCES ${PROJECT_SOURCE_DIR}/adc/*.c)
|
||||||
${PROJECT_SOURCE_DIR}/core/auth.c
|
file (GLOB network_SOURCES ${PROJECT_SOURCE_DIR}/network/*.c)
|
||||||
${PROJECT_SOURCE_DIR}/core/command_parser.c
|
file (GLOB utils_SOURCES ${PROJECT_SOURCE_DIR}/util/*.c)
|
||||||
${PROJECT_SOURCE_DIR}/core/commands.c
|
|
||||||
${PROJECT_SOURCE_DIR}/core/config.c
|
|
||||||
${PROJECT_SOURCE_DIR}/core/eventqueue.c
|
|
||||||
${PROJECT_SOURCE_DIR}/core/hub.c
|
|
||||||
${PROJECT_SOURCE_DIR}/core/hubevent.c
|
|
||||||
${PROJECT_SOURCE_DIR}/core/inf.c
|
|
||||||
${PROJECT_SOURCE_DIR}/core/ioqueue.c
|
|
||||||
${PROJECT_SOURCE_DIR}/core/netevent.c
|
|
||||||
${PROJECT_SOURCE_DIR}/core/probe.c
|
|
||||||
${PROJECT_SOURCE_DIR}/core/route.c
|
|
||||||
${PROJECT_SOURCE_DIR}/core/user.c
|
|
||||||
${PROJECT_SOURCE_DIR}/core/usermanager.c
|
|
||||||
${PROJECT_SOURCE_DIR}/core/plugincallback.c
|
|
||||||
${PROJECT_SOURCE_DIR}/core/plugininvoke.c
|
|
||||||
${PROJECT_SOURCE_DIR}/core/pluginloader.c
|
|
||||||
)
|
|
||||||
|
|
||||||
set (adc_SOURCES
|
|
||||||
${PROJECT_SOURCE_DIR}/adc/message.c
|
|
||||||
${PROJECT_SOURCE_DIR}/adc/sid.c
|
|
||||||
)
|
|
||||||
|
|
||||||
set (utils_SOURCES
|
|
||||||
${PROJECT_SOURCE_DIR}/util/cbuffer.c
|
|
||||||
${PROJECT_SOURCE_DIR}/util/config_token.c
|
|
||||||
${PROJECT_SOURCE_DIR}/util/credentials.c
|
|
||||||
${PROJECT_SOURCE_DIR}/util/floodctl.c
|
|
||||||
${PROJECT_SOURCE_DIR}/util/getopt.c
|
|
||||||
${PROJECT_SOURCE_DIR}/util/list.c
|
|
||||||
${PROJECT_SOURCE_DIR}/util/log.c
|
|
||||||
${PROJECT_SOURCE_DIR}/util/memory.c
|
|
||||||
${PROJECT_SOURCE_DIR}/util/misc.c
|
|
||||||
${PROJECT_SOURCE_DIR}/util/rbtree.c
|
|
||||||
${PROJECT_SOURCE_DIR}/util/tiger.c
|
|
||||||
)
|
|
||||||
|
|
||||||
set (adcclient_SOURCES
|
set (adcclient_SOURCES
|
||||||
${PROJECT_SOURCE_DIR}/tools/adcclient.c
|
${PROJECT_SOURCE_DIR}/tools/adcclient.c
|
||||||
@ -100,70 +99,94 @@ set (adcclient_SOURCES
|
|||||||
add_library(adc STATIC ${adc_SOURCES})
|
add_library(adc STATIC ${adc_SOURCES})
|
||||||
add_library(network STATIC ${network_SOURCES})
|
add_library(network STATIC ${network_SOURCES})
|
||||||
add_library(utils STATIC ${utils_SOURCES})
|
add_library(utils STATIC ${utils_SOURCES})
|
||||||
|
if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
|
||||||
|
set_target_properties(utils PROPERTIES COMPILE_FLAGS -fPIC)
|
||||||
|
set_target_properties(network PROPERTIES COMPILE_FLAGS -fPIC)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_dependencies(adc utils)
|
add_dependencies(adc utils)
|
||||||
add_dependencies(network utils)
|
add_dependencies(network utils)
|
||||||
|
|
||||||
add_executable(uhub ${PROJECT_SOURCE_DIR}/core/main.c ${uhub_SOURCES} )
|
add_executable(uhub ${PROJECT_SOURCE_DIR}/core/main.c ${uhub_SOURCES} )
|
||||||
|
add_executable(autotest-bin ${CMAKE_SOURCE_DIR}/autotest/test.c ${uhub_SOURCES} )
|
||||||
|
add_executable(uhub-passwd ${PROJECT_SOURCE_DIR}/tools/uhub-passwd.c)
|
||||||
|
|
||||||
add_library(mod_example MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_example.c ${utils_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 ${utils_SOURCES} ${network_SOURCES})
|
add_library(mod_welcome MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_welcome.c)
|
||||||
add_library(mod_logging MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_logging.c ${utils_SOURCES} ${PROJECT_SOURCE_DIR}/adc/sid.c ${network_SOURCES})
|
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 ${utils_SOURCES})
|
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 ${utils_SOURCES})
|
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 ${utils_SOURCES})
|
add_library(mod_chat_history_sqlite MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_chat_history_sqlite.c )
|
||||||
add_library(mod_topic MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_topic.c ${utils_SOURCES})
|
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)
|
||||||
if (SQLITE_SUPPORT)
|
add_library(mod_no_guest_downloads MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_no_guest_downloads.c)
|
||||||
add_library(mod_auth_sqlite MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_auth_sqlite.c ${utils_SOURCES})
|
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 ${PROJECT_SOURCE_DIR}/util/misc.c ${PROJECT_SOURCE_DIR}/util/memory.c ${PROJECT_SOURCE_DIR}/util/log.c ${PROJECT_SOURCE_DIR}/util/list.c)
|
|
||||||
|
|
||||||
target_link_libraries(mod_auth_sqlite sqlite3)
|
|
||||||
target_link_libraries(uhub-passwd sqlite3)
|
|
||||||
set_target_properties(mod_auth_sqlite PROPERTIES PREFIX "")
|
|
||||||
|
|
||||||
if (UNIX)
|
|
||||||
target_link_libraries(uhub pthread)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(WIN32)
|
|
||||||
target_link_libraries(uhub ws2_32)
|
|
||||||
target_link_libraries(mod_logging ws2_32)
|
|
||||||
target_link_libraries(mod_welcome ws2_32)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set_target_properties(
|
set_target_properties(
|
||||||
mod_example
|
mod_example
|
||||||
mod_welcome
|
mod_welcome
|
||||||
mod_logging
|
mod_logging
|
||||||
mod_auth_simple
|
mod_auth_simple
|
||||||
|
mod_auth_sqlite
|
||||||
mod_chat_history
|
mod_chat_history
|
||||||
|
mod_chat_history_sqlite
|
||||||
mod_chat_only
|
mod_chat_only
|
||||||
|
mod_no_guest_downloads
|
||||||
mod_topic
|
mod_topic
|
||||||
PROPERTIES PREFIX "")
|
PROPERTIES PREFIX "")
|
||||||
|
|
||||||
target_link_libraries(uhub ${CMAKE_DL_LIBS} adc network utils)
|
target_link_libraries(uhub ${CMAKE_DL_LIBS} adc network utils)
|
||||||
|
target_link_libraries(uhub-passwd ${SQLITE3_LIBRARIES} utils)
|
||||||
|
target_link_libraries(autotest-bin ${CMAKE_DL_LIBS} adc network utils)
|
||||||
|
target_link_libraries(mod_example utils)
|
||||||
|
target_link_libraries(mod_welcome network utils)
|
||||||
|
target_link_libraries(mod_auth_simple utils)
|
||||||
|
target_link_libraries(mod_auth_sqlite ${SQLITE3_LIBRARIES} utils)
|
||||||
|
target_link_libraries(mod_chat_history utils)
|
||||||
|
target_link_libraries(mod_chat_history_sqlite ${SQLITE3_LIBRARIES} utils)
|
||||||
|
target_link_libraries(mod_no_guest_downloads utils)
|
||||||
|
target_link_libraries(mod_chat_only utils)
|
||||||
|
target_link_libraries(mod_logging network utils)
|
||||||
|
target_link_libraries(mod_topic utils)
|
||||||
|
target_link_libraries(utils network)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
target_link_libraries(uhub ws2_32)
|
||||||
|
target_link_libraries(autotest-bin ws2_32)
|
||||||
|
target_link_libraries(mod_logging ws2_32)
|
||||||
|
target_link_libraries(mod_welcome ws2_32)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
add_library(adcclient STATIC ${adcclient_SOURCES})
|
add_library(adcclient STATIC ${adcclient_SOURCES})
|
||||||
add_executable(uhub-admin ${PROJECT_SOURCE_DIR}/tools/admin.c)
|
add_executable(uhub-admin ${PROJECT_SOURCE_DIR}/tools/admin.c)
|
||||||
target_link_libraries(uhub-admin adcclient adc network utils)
|
target_link_libraries(uhub-admin adcclient adc network utils pthread)
|
||||||
|
target_link_libraries(uhub pthread)
|
||||||
|
target_link_libraries(autotest-bin pthread)
|
||||||
|
|
||||||
if (ADC_STRESS)
|
if (ADC_STRESS)
|
||||||
add_executable(adcrush ${PROJECT_SOURCE_DIR}/tools/adcrush.c ${adcclient_SOURCES})
|
add_executable(adcrush ${PROJECT_SOURCE_DIR}/tools/adcrush.c ${adcclient_SOURCES})
|
||||||
target_link_libraries(adcrush adcclient adc network utils)
|
target_link_libraries(adcrush adcclient adc network utils pthread)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(GIT_FOUND AND IS_DIRECTORY ".git")
|
if (NOT UHUB_REVISION AND GIT_FOUND)
|
||||||
execute_process(COMMAND ${GIT_EXECUTABLE} show -s --pretty=format:%h OUTPUT_VARIABLE UHUB_REVISION)
|
execute_process(COMMAND ${GIT_EXECUTABLE} show -s --pretty=format:%h
|
||||||
set (UHUB_GIT_VERSION "${UHUB_VERSION_MAJOR}.${UHUB_VERSION_MINOR}.${UHUB_VERSION_PATCH}-git-${UHUB_REVISION}")
|
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||||
else()
|
OUTPUT_VARIABLE UHUB_REVISION_TEMP
|
||||||
set (UHUB_GIT_VERSION "${UHUB_VERSION_MAJOR}.${UHUB_VERSION_MINOR}.${UHUB_VERSION_PATCH}-release")
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
if (UHUB_REVISION_TEMP)
|
||||||
|
set (UHUB_REVISION "git-${UHUB_REVISION_TEMP}")
|
||||||
|
endif()
|
||||||
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)
|
if(OPENSSL_FOUND)
|
||||||
set(SSL_LIBS ${OPENSSL_LIBRARIES})
|
set(SSL_LIBS ${OPENSSL_LIBRARIES})
|
||||||
add_definitions(-DSSL_SUPPORT=1 -DSSL_USE_OPENSSL=1)
|
add_definitions(-DSSL_SUPPORT=1 -DSSL_USE_OPENSSL=1)
|
||||||
@ -178,6 +201,7 @@ endif()
|
|||||||
|
|
||||||
if(SSL_SUPPORT)
|
if(SSL_SUPPORT)
|
||||||
target_link_libraries(uhub ${SSL_LIBS})
|
target_link_libraries(uhub ${SSL_LIBS})
|
||||||
|
target_link_libraries(autotest-bin ${SSL_LIBS})
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
target_link_libraries(uhub-admin ${SSL_LIBS})
|
target_link_libraries(uhub-admin ${SSL_LIBS})
|
||||||
endif()
|
endif()
|
||||||
@ -188,27 +212,35 @@ if(SSL_SUPPORT)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
configure_file ("${PROJECT_SOURCE_DIR}/version.h.in" "${PROJECT_SOURCE_DIR}/version.h")
|
if (SYSTEMD_SUPPORT)
|
||||||
|
target_link_libraries(uhub ${SD_LIBRARIES})
|
||||||
|
target_link_libraries(autotest-bin ${SD_LIBRARIES})
|
||||||
|
target_link_libraries(uhub-passwd ${SD_LIBRARIES})
|
||||||
|
target_link_libraries(uhub-admin ${SD_LIBRARIES})
|
||||||
|
include_directories(${SD_INCLUDE_DIRS})
|
||||||
|
add_definitions(-DSYSTEMD)
|
||||||
|
endif()
|
||||||
|
|
||||||
mark_as_advanced(FORCE CMAKE_BUILD_TYPE)
|
configure_file ("${PROJECT_SOURCE_DIR}/version.h.in" "${PROJECT_BINARY_DIR}/version.h")
|
||||||
if (RELEASE)
|
configure_file ("${PROJECT_SOURCE_DIR}/system.h.in" "${PROJECT_BINARY_DIR}/system.h")
|
||||||
set(CMAKE_BUILD_TYPE Release)
|
|
||||||
else()
|
# mark_as_advanced(FORCE CMAKE_BUILD_TYPE)
|
||||||
set(CMAKE_BUILD_TYPE Debug)
|
# if (RELEASE)
|
||||||
# add_definitions(-DDEBUG)
|
# set(CMAKE_BUILD_TYPE Release)
|
||||||
|
# add_definitions(-DNDEBUG)
|
||||||
|
#else()
|
||||||
|
# set(CMAKE_BUILD_TYPE Debug)
|
||||||
|
# add_definitions(-DDEBUG)
|
||||||
|
#endif()
|
||||||
|
|
||||||
|
if (LOWLEVEL_DEBUG)
|
||||||
|
add_definitions(-DLOWLEVEL_DEBUG)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (UNIX)
|
if (UNIX)
|
||||||
install( TARGETS uhub RUNTIME DESTINATION bin )
|
install( TARGETS uhub uhub-passwd 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 DESTINATION /var/lib/uhub/ OPTIONAL )
|
install( TARGETS mod_example mod_welcome mod_logging mod_auth_simple mod_auth_sqlite mod_chat_history mod_chat_history_sqlite mod_chat_only mod_topic mod_no_guest_downloads DESTINATION /usr/lib/uhub/ OPTIONAL )
|
||||||
install( FILES ${CMAKE_SOURCE_DIR}/uhub.conf ${CMAKE_SOURCE_DIR}/plugins.conf ${CMAKE_SOURCE_DIR}/rules.txt ${CMAKE_SOURCE_DIR}/motd.txt DESTINATION /etc/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()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
41
ChangeLog
41
ChangeLog
@ -1,3 +1,38 @@
|
|||||||
|
0.5.0:
|
||||||
|
- Use TLS 1.2 and strong ciphers by default, but made this configurable.
|
||||||
|
- Fix TLS event handling which caused some busy loops
|
||||||
|
- TLS: Support certificate chains
|
||||||
|
- Fix bug #211: Better Hublist pinger support by adding the AP flag of the INF message.
|
||||||
|
- Fix bug #198: Timers could cause infinite loops
|
||||||
|
- Sqlite3 is now mandatory
|
||||||
|
- Added mod_chat_history_sqlite and mod_chat_is_privileged.
|
||||||
|
- Support for systemd notify and journal logging
|
||||||
|
- Improved flood control counting to strictly not allow more than the given amount of messages in the configured interval.
|
||||||
|
- Optimize lookups by CID and nick.
|
||||||
|
- Added an NMDC and ADC hub redirectors written in Python.
|
||||||
|
- Fix all Clang compile warnings.
|
||||||
|
- Install uhub-passwd also.
|
||||||
|
- Add support for detecting HTTP connections to the hub. Enough to tell browsers to stop calling.
|
||||||
|
- Compile fixes for OpenBSD, including warnings about strcat.
|
||||||
|
- Fix crashing autotest due to wrong initialization of the usermanager.
|
||||||
|
- mod_topic: check argument for NULL
|
||||||
|
- rename !cleartopic to !resettopic
|
||||||
|
|
||||||
|
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
|
||||||
@ -12,8 +47,8 @@
|
|||||||
- marked plugin callbacks that are not called yet
|
- marked plugin callbacks that are not called yet
|
||||||
- add on_change_nick() to struct plugin_funcs
|
- add on_change_nick() to struct plugin_funcs
|
||||||
- minimal changes
|
- minimal changes
|
||||||
- Updated init script in debian package.
|
- Updated init script in Debian package.
|
||||||
- Updated list of man pages in debian package.
|
- Updated list of man pages in Debian package.
|
||||||
- Added man page for uhub-passwd.
|
- Added man page for uhub-passwd.
|
||||||
- Merge branch 'master' of https://github.com/Tilka/uhub
|
- Merge branch 'master' of https://github.com/Tilka/uhub
|
||||||
- Fix issue with QUI messages being allowed through the hub
|
- Fix issue with QUI messages being allowed through the hub
|
||||||
@ -43,7 +78,7 @@
|
|||||||
- minimal documentation fixes
|
- minimal documentation fixes
|
||||||
- update client software link
|
- update client software link
|
||||||
- update compile howto link
|
- update compile howto link
|
||||||
- fix debian changelog
|
- fix Debian changelog
|
||||||
- Fix bug #158 - Added plugin for setting topic (hub description).
|
- Fix bug #158 - Added plugin for setting topic (hub description).
|
||||||
- Command arguments handling + cleanups
|
- Command arguments handling + cleanups
|
||||||
|
|
||||||
|
19
Dockerfile
Normal file
19
Dockerfile
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
FROM alpine:latest as builder
|
||||||
|
RUN apk update && apk upgrade && apk add --no-cache bash util-linux cmake make gcc git sqlite-dev openssl-dev git build-base
|
||||||
|
WORKDIR /app
|
||||||
|
COPY . .
|
||||||
|
RUN cmake . && make
|
||||||
|
RUN sed -i 's/\/usr\/lib\/uhub\//\/libs\//g' ./doc/*.conf && \
|
||||||
|
sed -i 's/\/usr\/lib\/uhub\//\/libs\//g' ./doc/rules.txt && \
|
||||||
|
sed -i 's/\/etc\/uhub\//\/conf\//g' ./doc/*.conf && \
|
||||||
|
sed -i 's/\/etc\/uhub\//\/conf\//g' ./doc/rules.txt && \
|
||||||
|
echo 'Welcome to uHub' > ./doc/motd.txt
|
||||||
|
|
||||||
|
FROM alpine:latest
|
||||||
|
RUN apk update && apk upgrade && apk add --no-cache bash util-linux openssl-dev sqlite-dev
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=builder /app/uhub .
|
||||||
|
COPY --from=builder /app/doc/plugins.conf /app/doc/uhub.conf /app/doc/users.conf /app/doc/rules.txt /app/doc/motd.txt /conf/
|
||||||
|
COPY --from=builder /app/*.so /libs/
|
||||||
|
ENTRYPOINT ["./uhub"]
|
||||||
|
CMD ["-c","/conf/uhub.conf"]
|
@ -1,8 +1,13 @@
|
|||||||
|
# uhub
|
||||||
|
|
||||||
Welcome and thanks for downloading uHub, a high performance ADC p2p hub.
|
Welcome and thanks for downloading uHub, a high performance ADC p2p hub.
|
||||||
|
|
||||||
For the official documentation, bugs and other information, please visit:
|
For the official documentation, bugs and other information, please visit:
|
||||||
http://www.uhub.org/
|
https://www.uhub.org/
|
||||||
|
|
||||||
For a list of compatible ADC clients, see:
|
For a list of compatible ADC clients, see:
|
||||||
http://en.wikipedia.org/wiki/Advanced_Direct_Connect#Client_software
|
https://en.wikipedia.org/wiki/Comparison_of_ADC_software#Client_software
|
||||||
|
|
||||||
|
# on dockerhub
|
||||||
|
|
||||||
|
* https://hub.docker.com/r/sneak/uhub
|
@ -78,7 +78,7 @@ Description: a high performance hub for the ADC peer-to-peer network
|
|||||||
Its low memory footprint allows it to handle several thousand users
|
Its low memory footprint allows it to handle several thousand users
|
||||||
on high-end servers, or a small private hub on embedded hardware.
|
on high-end servers, or a small private hub on embedded hardware.
|
||||||
.
|
.
|
||||||
Homepage: http://www.extatic.org/uhub/
|
Homepage: https://www.uhub.org/
|
||||||
EOF
|
EOF
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
'; }
|
||||||
|
|
1070
autotest/test.c
Normal file
1070
autotest/test.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -12,11 +12,10 @@ 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->list = list_create();
|
|
||||||
inf_hub->users->sids = sid_pool_create(500);
|
|
||||||
|
|
||||||
|
inf_hub->users = uman_init();
|
||||||
inf_hub->acl = (struct acl_handle*) hub_malloc_zero(sizeof(struct acl_handle));
|
inf_hub->acl = (struct acl_handle*) hub_malloc_zero(sizeof(struct acl_handle));
|
||||||
inf_hub->config = (struct hub_config*) hub_malloc_zero(sizeof(struct hub_config));
|
inf_hub->config = (struct hub_config*) hub_malloc_zero(sizeof(struct hub_config));
|
||||||
|
|
||||||
@ -26,15 +25,13 @@ static void inf_create_hub()
|
|||||||
|
|
||||||
static void inf_destroy_hub()
|
static void inf_destroy_hub()
|
||||||
{
|
{
|
||||||
/* FIXME */
|
uman_shutdown(inf_hub->users);
|
||||||
list_destroy(inf_hub->users->list);
|
|
||||||
sid_pool_destroy(inf_hub->users->sids);
|
|
||||||
acl_shutdown(inf_hub->acl);
|
acl_shutdown(inf_hub->acl);
|
||||||
free_config(inf_hub->config);
|
free_config(inf_hub->config);
|
||||||
hub_free(inf_hub->users);
|
|
||||||
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 +60,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 +105,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;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,10 +1,16 @@
|
|||||||
#include <uhub.h>
|
#include <uhub.h>
|
||||||
|
|
||||||
static struct linked_list* list = NULL;
|
static struct linked_list* list = NULL;
|
||||||
|
static struct linked_list* list2 = NULL;
|
||||||
|
|
||||||
static char A[2] = { 'A', 0 };
|
static char A[2] = { 'A', 0 };
|
||||||
static char B[2] = { 'B', 0 };
|
static char B[2] = { 'B', 0 };
|
||||||
static char C[2] = { 'C', 0 };
|
static char C[2] = { 'C', 0 };
|
||||||
|
static char A2[2] = { 'a', 0 };
|
||||||
|
static char B2[2] = { 'b', 0 };
|
||||||
|
static char C2[2] = { 'c', 0 };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void null_free(void* ptr)
|
static void null_free(void* ptr)
|
||||||
{
|
{
|
||||||
@ -124,6 +130,83 @@ EXO_TEST(list_clear, {
|
|||||||
return list->size == 0 && list->first == 0 && list->last == 0 && list->iterator == 0;
|
return list->size == 0 && list->first == 0 && list->last == 0 && list->iterator == 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
static int g_remove_flag = 0;
|
||||||
|
static void null_free_inc_flag(void* ptr)
|
||||||
|
{
|
||||||
|
(void) ptr;
|
||||||
|
g_remove_flag++;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXO_TEST(list_remove_first_1_1,
|
||||||
|
{
|
||||||
|
list_append(list, A);
|
||||||
|
list_append(list, B);
|
||||||
|
list_append(list, C);
|
||||||
|
return list->size == 3;
|
||||||
|
});
|
||||||
|
|
||||||
|
EXO_TEST(list_remove_first_1_2,
|
||||||
|
{
|
||||||
|
g_remove_flag = 0;
|
||||||
|
list_remove_first(list, null_free_inc_flag);
|
||||||
|
return list->size == 2 && g_remove_flag == 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
EXO_TEST(list_remove_first_1_3,
|
||||||
|
{
|
||||||
|
list_remove_first(list, NULL);
|
||||||
|
return list->size == 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
EXO_TEST(list_remove_first_1_4,
|
||||||
|
{
|
||||||
|
list_remove_first(list, NULL);
|
||||||
|
return list->size == 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
EXO_TEST(list_remove_first_1_5,
|
||||||
|
{
|
||||||
|
list_remove_first(list, NULL);
|
||||||
|
return list->size == 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
EXO_TEST(list_append_list_1,
|
||||||
|
{
|
||||||
|
list_append(list, A);
|
||||||
|
list_append(list, B);
|
||||||
|
list_append(list, C);
|
||||||
|
list2 = list_create();
|
||||||
|
list_append(list2, A2);
|
||||||
|
list_append(list2, B2);
|
||||||
|
list_append(list2, C2);
|
||||||
|
return list->size == 3 && list2->size == 3;
|
||||||
|
});
|
||||||
|
|
||||||
|
EXO_TEST(list_append_list_2,
|
||||||
|
{
|
||||||
|
list_append_list(list, list2);
|
||||||
|
return list->size == 6 && list2->size == 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
EXO_TEST(list_append_list_3,
|
||||||
|
{
|
||||||
|
list_destroy(list2);
|
||||||
|
return list_get_index(list, 0) == A &&
|
||||||
|
list_get_index(list, 1) == B &&
|
||||||
|
list_get_index(list, 2) == C &&
|
||||||
|
list_get_index(list, 3) == A2 &&
|
||||||
|
list_get_index(list, 4) == B2 &&
|
||||||
|
list_get_index(list, 5) == C2;
|
||||||
|
});
|
||||||
|
|
||||||
|
EXO_TEST(list_clear_list_last,
|
||||||
|
{
|
||||||
|
list_clear(list, &null_free);
|
||||||
|
return 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
EXO_TEST(list_destroy_1, {
|
EXO_TEST(list_destroy_1, {
|
||||||
list_destroy(list);
|
list_destroy(list);
|
||||||
|
@ -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,82 @@ 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
|
||||||
|
static const char test_utf_seq_10[] = { 0xF0, 0x9F, 0x98, 0x81, 0x00}; // valid
|
||||||
|
|
||||||
|
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); });
|
||||||
|
EXO_TEST(utf8_valid_13, { return is_valid_utf8(test_utf_seq_10); });
|
||||||
|
|
||||||
|
// Limits of utf-8
|
||||||
|
static const char test_utf_seq_11[] = { 0x7F, 0x00 }; // valid last 7-bit character
|
||||||
|
static const char test_utf_seq_12[] = { 0x80, 0x00 }; // invalid truncated string
|
||||||
|
static const char test_utf_seq_13[] = { 0xBF, 0x00 }; // invalid truncated string
|
||||||
|
static const char test_utf_seq_14[] = { 0xC0, 0x80, 0x00 }; // invalid out of 2 bytes range
|
||||||
|
static const char test_utf_seq_15[] = { 0xC1, 0x7F, 0x00 }; // invalid out of 2 bytes range
|
||||||
|
static const char test_utf_seq_16[] = { 0xC2, 0x00 }; // invalid truncated string
|
||||||
|
static const char test_utf_seq_17[] = { 0xC2, 0x80, 0x00 }; // valid
|
||||||
|
static const char test_utf_seq_18[] = { 0xDF, 0xBF, 0x00 }; // valid
|
||||||
|
static const char test_utf_seq_19[] = { 0xE0, 0x80, 0x80, 0x00 }; // invalid out of 3 bytes range
|
||||||
|
static const char test_utf_seq_20[] = { 0xE0, 0x9F, 0xBF, 0x00 }; // invalid out of 3 bytes range
|
||||||
|
static const char test_utf_seq_21[] = { 0xE0, 0x00 }; // invalid truncated string
|
||||||
|
static const char test_utf_seq_22[] = { 0xE0, 0xA0, 0x00 }; // invalid truncated string
|
||||||
|
static const char test_utf_seq_23[] = { 0xE0, 0xA0, 0x80, 0x00 }; // valid
|
||||||
|
static const char test_utf_seq_24[] = { 0xEC, 0x9F, 0xBF, 0x00 }; // valid
|
||||||
|
static const char test_utf_seq_25[] = { 0xED, 0xA0, 0x80, 0x00 }; // invalid surrogate
|
||||||
|
static const char test_utf_seq_26[] = { 0xED, 0xBF, 0xBF, 0x00 }; // invalid surrogate
|
||||||
|
static const char test_utf_seq_27[] = { 0xEF, 0x80, 0x80, 0x00 }; // valid
|
||||||
|
static const char test_utf_seq_28[] = { 0xEF, 0xBF, 0xBF, 0x00 }; // valid
|
||||||
|
static const char test_utf_seq_29[] = { 0xF0, 0x80, 0x80, 0x80, 0x00 }; // invalid out of 4 bytes range
|
||||||
|
static const char test_utf_seq_30[] = { 0xF0, 0x8F, 0xBF, 0xBF, 0x00 }; // invalid out of 4 bytes range
|
||||||
|
static const char test_utf_seq_31[] = { 0xF0, 0x00 }; // invalid truncated string
|
||||||
|
static const char test_utf_seq_32[] = { 0xF0, 0x90, 0x00 }; // invalid truncated string
|
||||||
|
static const char test_utf_seq_33[] = { 0xF0, 0x90, 0x80, 0x00 }; // invalid truncated string
|
||||||
|
static const char test_utf_seq_34[] = { 0xF0, 0x90, 0x80, 0x80, 0x00 }; // valid
|
||||||
|
static const char test_utf_seq_35[] = { 0xF4, 0x8F, 0xBF, 0xBF, 0x00 }; // valid
|
||||||
|
static const char test_utf_seq_36[] = { 0xF4, 0x90, 0x80, 0x80, 0x00 }; // invalid out of 4 bytes range
|
||||||
|
static const char test_utf_seq_37[] = { 0xFF, 0xBF, 0xBF, 0xBF, 0x00 }; // invalid out of 4 bytes range
|
||||||
|
|
||||||
|
EXO_TEST(utf8_valid_14, { return is_valid_utf8(test_utf_seq_11); });
|
||||||
|
EXO_TEST(utf8_valid_15, { return !is_valid_utf8(test_utf_seq_12); });
|
||||||
|
EXO_TEST(utf8_valid_16, { return !is_valid_utf8(test_utf_seq_13); });
|
||||||
|
EXO_TEST(utf8_valid_17, { return !is_valid_utf8(test_utf_seq_14); });
|
||||||
|
EXO_TEST(utf8_valid_18, { return !is_valid_utf8(test_utf_seq_15); });
|
||||||
|
EXO_TEST(utf8_valid_19, { return !is_valid_utf8(test_utf_seq_16); });
|
||||||
|
EXO_TEST(utf8_valid_20, { return is_valid_utf8(test_utf_seq_17); });
|
||||||
|
EXO_TEST(utf8_valid_21, { return is_valid_utf8(test_utf_seq_18); });
|
||||||
|
EXO_TEST(utf8_valid_22, { return !is_valid_utf8(test_utf_seq_19); });
|
||||||
|
EXO_TEST(utf8_valid_23, { return !is_valid_utf8(test_utf_seq_20); });
|
||||||
|
EXO_TEST(utf8_valid_24, { return !is_valid_utf8(test_utf_seq_21); });
|
||||||
|
EXO_TEST(utf8_valid_25, { return !is_valid_utf8(test_utf_seq_22); });
|
||||||
|
EXO_TEST(utf8_valid_26, { return is_valid_utf8(test_utf_seq_23); });
|
||||||
|
EXO_TEST(utf8_valid_27, { return is_valid_utf8(test_utf_seq_24); });
|
||||||
|
EXO_TEST(utf8_valid_28, { return !is_valid_utf8(test_utf_seq_25); });
|
||||||
|
EXO_TEST(utf8_valid_29, { return !is_valid_utf8(test_utf_seq_26); });
|
||||||
|
EXO_TEST(utf8_valid_30, { return is_valid_utf8(test_utf_seq_27); });
|
||||||
|
EXO_TEST(utf8_valid_31, { return is_valid_utf8(test_utf_seq_28); });
|
||||||
|
EXO_TEST(utf8_valid_32, { return !is_valid_utf8(test_utf_seq_29); });
|
||||||
|
EXO_TEST(utf8_valid_33, { return !is_valid_utf8(test_utf_seq_30); });
|
||||||
|
EXO_TEST(utf8_valid_34, { return !is_valid_utf8(test_utf_seq_31); });
|
||||||
|
EXO_TEST(utf8_valid_35, { return !is_valid_utf8(test_utf_seq_32); });
|
||||||
|
EXO_TEST(utf8_valid_36, { return !is_valid_utf8(test_utf_seq_33); });
|
||||||
|
EXO_TEST(utf8_valid_37, { return is_valid_utf8(test_utf_seq_34); });
|
||||||
|
EXO_TEST(utf8_valid_38, { return is_valid_utf8(test_utf_seq_35); });
|
||||||
|
EXO_TEST(utf8_valid_39, { return !is_valid_utf8(test_utf_seq_36); });
|
||||||
|
EXO_TEST(utf8_valid_40, { return !is_valid_utf8(test_utf_seq_37); });
|
||||||
|
150
autotest/test_rbtree.tcc
Normal file
150
autotest/test_rbtree.tcc
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
#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)
|
||||||
|
{
|
||||||
|
n = (struct rb_node*) rb_tree_next(tree);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return i == MAX_NODES;
|
||||||
|
});
|
||||||
|
|
||||||
|
static int freed_nodes = 0;
|
||||||
|
static void free_node(struct rb_node* n)
|
||||||
|
{
|
||||||
|
hub_free((void*) n->key);
|
||||||
|
hub_free((void*) n->value);
|
||||||
|
freed_nodes += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXO_TEST(rbtree_remove_10000, {
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < 2; j++)
|
||||||
|
{
|
||||||
|
for (i = j; i < MAX_NODES; i += 2)
|
||||||
|
{
|
||||||
|
const char* key = uhub_itoa(i);
|
||||||
|
rb_tree_remove_node(tree, key, &free_node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return freed_nodes == MAX_NODES;
|
||||||
|
});
|
||||||
|
|
||||||
|
EXO_TEST(rbtree_destroy_1, {
|
||||||
|
rb_tree_destroy(tree);
|
||||||
|
return 1;
|
||||||
|
});
|
@ -117,3 +117,9 @@ EXO_TEST(timer_process_5_events_1,{
|
|||||||
g_now = 4;
|
g_now = 4;
|
||||||
return timeout_queue_process(g_queue, g_now) == g_triggered;
|
return timeout_queue_process(g_queue, g_now) == g_triggered;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
EXO_TEST(timer_shutdown,{
|
||||||
|
timeout_queue_shutdown(g_queue);
|
||||||
|
hub_free(g_queue);
|
||||||
|
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++) {
|
||||||
|
43
autotest/travis/build-and-test.sh
Executable file
43
autotest/travis/build-and-test.sh
Executable file
@ -0,0 +1,43 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -x
|
||||||
|
set -e
|
||||||
|
|
||||||
|
export CFLAGS="$(dpkg-buildflags --get CFLAGS) $(dpkg-buildflags --get CPPFLAGS)"
|
||||||
|
export LDFLAGS="$(dpkg-buildflags --get LDFLAGS) -Wl,--as-needed"
|
||||||
|
|
||||||
|
mkdir -p builddir
|
||||||
|
cd builddir
|
||||||
|
|
||||||
|
CMAKEOPTS="..
|
||||||
|
-DCMAKE_INSTALL_PREFIX=/usr"
|
||||||
|
|
||||||
|
if [ "${CONFIG}" = "full" ]; then
|
||||||
|
CMAKEOPTS="${CMAKEOPTS}
|
||||||
|
-DRELEASE=OFF
|
||||||
|
-DLOWLEVEL_DEBUG=ON
|
||||||
|
-DSSL_SUPPORT=ON
|
||||||
|
-DUSE_OPENSSL=ON
|
||||||
|
-DADC_STRESS=ON"
|
||||||
|
else
|
||||||
|
CMAKEOPTS="${CMAKEOPTS}
|
||||||
|
-DRELEASE=ON
|
||||||
|
-DLOWLEVEL_DEBUG=OFF
|
||||||
|
-DSSL_SUPPORT=OFF
|
||||||
|
-DADC_STRESS=OFF"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
cmake ${CMAKEOPTS} \
|
||||||
|
-DCMAKE_C_FLAGS="${CFLAGS}" \
|
||||||
|
-DCMAKE_EXE_LINKER_FLAGS="${LDFLAGS}"
|
||||||
|
make VERBOSE=1
|
||||||
|
|
||||||
|
|
||||||
|
make VERBOSE=1 autotest-bin
|
||||||
|
./autotest-bin
|
||||||
|
|
||||||
|
|
||||||
|
sudo make install
|
||||||
|
du -shc /etc/uhub/ /usr/bin/uhub* /usr/lib/uhub/
|
||||||
|
|
10
autotest/travis/install-build-depends.sh
Executable file
10
autotest/travis/install-build-depends.sh
Executable file
@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
sudo apt-get update -qq
|
||||||
|
|
||||||
|
sudo apt-get install -qq cmake
|
||||||
|
|
||||||
|
if [ "${CONFIG}" = "full" ]; then
|
||||||
|
sudo apt-get install -qq libsqlite3-dev libssl-dev
|
||||||
|
fi
|
||||||
|
|
4
autotest/update.sh
Executable file
4
autotest/update.sh
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
./exotic *.tcc > test.c
|
||||||
|
|
78
cmake/Modules/FindSqlite3.cmake
Normal file
78
cmake/Modules/FindSqlite3.cmake
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
# - Try to find sqlite3
|
||||||
|
# Find sqlite3 headers, libraries and the answer to all questions.
|
||||||
|
#
|
||||||
|
# SQLITE3_FOUND True if sqlite3 got found
|
||||||
|
# SQLITE3_INCLUDEDIR Location of sqlite3 headers
|
||||||
|
# SQLITE3_LIBRARIES List of libraries to use sqlite3
|
||||||
|
# SQLITE3_DEFINITIONS Definitions to compile sqlite3
|
||||||
|
#
|
||||||
|
# Copyright (c) 2007 Juha Tuomala <tuju@iki.fi>
|
||||||
|
# Copyright (c) 2007 Daniel Gollub <gollub@b1-systems.de>
|
||||||
|
# Copyright (c) 2007 Alban Browaeys <prahal@yahoo.com>
|
||||||
|
#
|
||||||
|
# Redistribution and use is allowed according to the terms of the New
|
||||||
|
# BSD license.
|
||||||
|
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||||
|
#
|
||||||
|
|
||||||
|
INCLUDE( FindPkgConfig )
|
||||||
|
# Take care about sqlite3.pc settings
|
||||||
|
IF ( Sqlite3_FIND_REQUIRED )
|
||||||
|
SET( _pkgconfig_REQUIRED "REQUIRED" )
|
||||||
|
ELSE ( Sqlite3_FIND_REQUIRED )
|
||||||
|
SET( _pkgconfig_REQUIRED "" )
|
||||||
|
ENDIF ( Sqlite3_FIND_REQUIRED )
|
||||||
|
|
||||||
|
IF ( SQLITE3_MIN_VERSION )
|
||||||
|
PKG_SEARCH_MODULE( SQLITE3 ${_pkgconfig_REQUIRED} sqlite3>=${SQLITE3_MIN_VERSION} )
|
||||||
|
ELSE ( SQLITE3_MIN_VERSION )
|
||||||
|
pkg_search_module( SQLITE3 ${_pkgconfig_REQUIRED} sqlite3 )
|
||||||
|
ENDIF ( SQLITE3_MIN_VERSION )
|
||||||
|
|
||||||
|
|
||||||
|
# Look for sqlite3 include dir and libraries w/o pkgconfig
|
||||||
|
IF ( NOT SQLITE3_FOUND AND NOT PKG_CONFIG_FOUND )
|
||||||
|
FIND_PATH( _sqlite3_include_DIR sqlite3.h
|
||||||
|
PATHS
|
||||||
|
/opt/local/include/
|
||||||
|
/sw/include/
|
||||||
|
/usr/local/include/
|
||||||
|
/usr/include/
|
||||||
|
)
|
||||||
|
FIND_LIBRARY( _sqlite3_link_DIR sqlite3
|
||||||
|
PATHS
|
||||||
|
/opt/local/lib
|
||||||
|
/sw/lib
|
||||||
|
/usr/lib
|
||||||
|
/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}
|
||||||
|
/usr/local/lib
|
||||||
|
/usr/lib64
|
||||||
|
/usr/local/lib64
|
||||||
|
/opt/lib64
|
||||||
|
)
|
||||||
|
IF ( _sqlite3_include_DIR AND _sqlite3_link_DIR )
|
||||||
|
SET ( _sqlite3_FOUND TRUE )
|
||||||
|
ENDIF ( _sqlite3_include_DIR AND _sqlite3_link_DIR )
|
||||||
|
|
||||||
|
|
||||||
|
IF ( _sqlite3_FOUND )
|
||||||
|
SET ( SQLITE3_INCLUDE_DIRS ${_sqlite3_include_DIR} )
|
||||||
|
SET ( SQLITE3_LIBRARIES ${_sqlite3_link_DIR} )
|
||||||
|
ENDIF ( _sqlite3_FOUND )
|
||||||
|
|
||||||
|
# Report results
|
||||||
|
IF ( SQLITE3_LIBRARIES AND SQLITE3_INCLUDE_DIRS AND _sqlite3_FOUND )
|
||||||
|
SET( SQLITE3_FOUND 1 )
|
||||||
|
MESSAGE( STATUS "Found sqlite3: ${SQLITE3_LIBRARIES} ${SQLITE3_INCLUDE_DIRS}" )
|
||||||
|
ELSE ( SQLITE3_LIBRARIES AND SQLITE3_INCLUDE_DIRS AND _sqlite3_FOUND )
|
||||||
|
IF ( Sqlite3_FIND_REQUIRED )
|
||||||
|
MESSAGE( SEND_ERROR "Could NOT find sqlite3" )
|
||||||
|
ELSE ( Sqlite3_FIND_REQUIRED )
|
||||||
|
MESSAGE( STATUS "Could NOT find sqlite3" )
|
||||||
|
ENDIF ( Sqlite3_FIND_REQUIRED )
|
||||||
|
ENDIF ( SQLITE3_LIBRARIES AND SQLITE3_INCLUDE_DIRS AND _sqlite3_FOUND )
|
||||||
|
|
||||||
|
ENDIF ( NOT SQLITE3_FOUND AND NOT PKG_CONFIG_FOUND )
|
||||||
|
|
||||||
|
# Hide advanced variables from CMake GUIs
|
||||||
|
MARK_AS_ADVANCED( SQLITE3_LIBRARIES SQLITE3_INCLUDE_DIRS )
|
2
debian/control
vendored
2
debian/control
vendored
@ -20,5 +20,5 @@ Description: High performance ADC p2p hub
|
|||||||
- Advanced access control support
|
- Advanced access control support
|
||||||
- Easy configuration
|
- Easy configuration
|
||||||
.
|
.
|
||||||
Homepage: http://www.uhub.org/
|
Homepage: https://www.uhub.org/
|
||||||
|
|
||||||
|
2
debian/copyright
vendored
2
debian/copyright
vendored
@ -12,7 +12,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
On Debian GNU/Linux systems, the complete text of the GNU General Public
|
On Debian GNU/Linux systems, the complete text of the GNU General Public
|
||||||
License can be found in `/usr/share/common-licenses/GPL'.
|
License can be found in `/usr/share/common-licenses/GPL'.
|
||||||
|
@ -67,7 +67,7 @@ Accepting new users
|
|||||||
| | |
|
| | |
|
||||||
| V |
|
| V |
|
||||||
| --------------------- ---------------------
|
| --------------------- ---------------------
|
||||||
| | Send password | ------> | Reveive and check |
|
| | Send password | ------> | Receive and check |
|
||||||
| | request, if needed| | password. |
|
| | request, if needed| | password. |
|
||||||
| --------------------- ---------------------
|
| --------------------- ---------------------
|
||||||
| |
|
| |
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
How to compile:
|
How to compile:
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
See the official compiling howto: http://www.uhub.org/compile.php
|
See the official compiling howto: https://www.uhub.org/compile.php
|
||||||
|
|
||||||
Prerequisites
|
Prerequisites
|
||||||
|
|
||||||
@ -12,7 +12,7 @@ Before you try to compile µHub, please make sure the following prerequisites ar
|
|||||||
* openssl > 0.9.8 (or use "make USE_SSL=NO")
|
* openssl > 0.9.8 (or use "make USE_SSL=NO")
|
||||||
* sqlite > 3.x
|
* sqlite > 3.x
|
||||||
|
|
||||||
or read http://www.uhub.org/compile.php for more info.
|
or read https://www.uhub.org/compile.php for more info.
|
||||||
|
|
||||||
|
|
||||||
Linux, Mac OSX, FreeBSD, NetBSD and OpenBSD
|
Linux, Mac OSX, FreeBSD, NetBSD and OpenBSD
|
||||||
|
@ -28,10 +28,10 @@ The UDP packet SHOULD be echoed by the hub.
|
|||||||
This UDP packet should contain simply 'HECH {cid} {token}' (Hub echo).
|
This UDP packet should contain simply 'HECH {cid} {token}' (Hub echo).
|
||||||
|
|
||||||
The hub should send a packet containing the token back:
|
The hub should send a packet containing the token back:
|
||||||
'IECH {token} {host:port}', aswell as the same message via TCP.
|
'IECH {token} {host:port}', as well as the same message via TCP.
|
||||||
|
|
||||||
If the client receives the message via UDP, it should now be able to determine the type of NAT.
|
If the client receives the message via UDP, it should now be able to determine the type of NAT.
|
||||||
If the client receives the message via TCP only it knows it has a firewall blocking incomming communication.
|
If the client receives the message via TCP only it knows it has a firewall blocking incoming communication.
|
||||||
If the client does not receive the message, it should assume a firewall is blocking all UDP communication,
|
If the client does not receive the message, it should assume a firewall is blocking all UDP communication,
|
||||||
and resume in passive mode.
|
and resume in passive mode.
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
Getting started guide
|
Getting started guide
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
(This document is maintained at http://www.extatic.org/uhub/getstarted.html )
|
|
||||||
|
|
||||||
Unpack your binaries
|
Unpack your binaries
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
@ -17,6 +15,7 @@ Create configuration files.
|
|||||||
If no configuration files are created, uhub will use the default parameters, so you can skip this step if you are in a hurry to see it run.
|
If no configuration files are created, uhub will use the default parameters, so you can skip this step if you are in a hurry to see it run.
|
||||||
|
|
||||||
As root, or use sudo.
|
As root, or use sudo.
|
||||||
|
|
||||||
% mkdir /etc/uhub
|
% mkdir /etc/uhub
|
||||||
% cp doc/uhub.conf /etc/uhub
|
% cp doc/uhub.conf /etc/uhub
|
||||||
% cp doc/users.conf /etc/uhub
|
% cp doc/users.conf /etc/uhub
|
||||||
@ -32,8 +31,11 @@ NOTE: It is important to use the "adc://" prefix, and the port number when using
|
|||||||
|
|
||||||
If you modify the configuration files in /etc/uhub you will have to notify uhub by sending a HUP signal.
|
If you modify the configuration files in /etc/uhub you will have to notify uhub by sending a HUP signal.
|
||||||
|
|
||||||
|
% ps aux | grep uhub
|
||||||
% kill -HUP <pid of uhub>
|
% kill -HUP <pid of uhub>
|
||||||
|
|
||||||
Or, for the lazy people
|
Or, for the lazy people
|
||||||
|
|
||||||
% killall -HUP uhub
|
% killall -HUP uhub
|
||||||
|
|
||||||
In order to run uhub as a daemon, start it with the -f switch which will make it fork into the background.
|
In order to run uhub as a daemon, start it with the -f switch which will make it fork into the background.
|
||||||
@ -41,17 +43,25 @@ In addition, use the -l to specify a log file instead of stdout. One can also sp
|
|||||||
if one wishes to run uhub as a specific user using the -u and -g switches.
|
if one wishes to run uhub as a specific user using the -u and -g switches.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
% uhub -f -l mylog.txt -u nobody -g nogroup
|
|
||||||
|
|
||||||
|
% uhub -f -l mylog.txt -u nobody -g nogroup
|
||||||
|
|
||||||
If you are planning to more than 1024 users on hub, you must increase the max number of file descriptors allowed.
|
If you are planning to more than 1024 users on hub, you must increase the max number of file descriptors allowed.
|
||||||
This limit needs to be higher than the configured max_users in uhub.conf.
|
This limit needs to be higher than the configured max_users in uhub.conf.
|
||||||
|
|
||||||
In linux can add the following lines to /etc/security/limits.conf (allows for ~4000 users)
|
In Linux can add the following lines to /etc/security/limits.conf (allows for ~4000 users)
|
||||||
* soft nofile 4096
|
* soft nofile 4096
|
||||||
* hard nofile 4096
|
* hard nofile 4096
|
||||||
|
|
||||||
Or, you can use (as root):
|
Or, you can use (as root):
|
||||||
|
|
||||||
% ulimit -n 4096
|
% ulimit -n 4096
|
||||||
|
|
||||||
|
You can interact with uhub in your hub main chat using the `!` prefix, followed by a command:
|
||||||
|
|
||||||
|
Example :
|
||||||
|
|
||||||
|
* to display help and the command you can use:
|
||||||
|
!help
|
||||||
|
|
||||||
Your mileage may vary -- Good luck!
|
Your mileage may vary -- Good luck!
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
#
|
#
|
||||||
# chkconfig: - 91 35
|
# chkconfig: - 91 35
|
||||||
# description: Starts and stops the Uhub ( http://www.uhub.org ) daemons on RHEL\CentOS \
|
# description: Starts and stops the Uhub ( https://www.uhub.org ) daemons on RHEL\CentOS \
|
||||||
# used to provide p2p network services.
|
# used to provide p2p network services.
|
||||||
#
|
#
|
||||||
# pidfile: /var/run/uhub.pid
|
# pidfile: /var/run/uhub.pid
|
||||||
|
@ -11,18 +11,28 @@
|
|||||||
# 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"
|
||||||
|
|
||||||
|
# Topic commands.
|
||||||
|
# Note: "topic" == "hub description" (as configured in uhub.conf)
|
||||||
|
#
|
||||||
|
# !topic - change the topic (op required)
|
||||||
|
# !showtopic - show the topic
|
||||||
|
# !resettopic - reset the topic to the default (op required)
|
||||||
|
#
|
||||||
|
# This plugins takes no parameters.
|
||||||
|
#plugin /usr/lib/uhub/mod_topic.so
|
||||||
|
|
||||||
# Log file writer
|
# Log file writer
|
||||||
#
|
#
|
||||||
# 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:
|
||||||
@ -31,7 +41,7 @@ plugin /var/lib/uhub/mod_logging.so "file=/var/log/uhub.log"
|
|||||||
#
|
#
|
||||||
# Parameters:
|
# Parameters:
|
||||||
# motd: path/filename for the welcome message (message of the day)
|
# motd: path/filename for the welcome message (message of the day)
|
||||||
# rules: path/filenam for the rules file
|
# rules: path/filename for the rules file
|
||||||
#
|
#
|
||||||
# NOTE: The files MUST exist, however if you do not wish to provide one then these parameters can be omitted.
|
# NOTE: The files MUST exist, however if you do not wish to provide one then these parameters can be omitted.
|
||||||
#
|
#
|
||||||
@ -46,7 +56,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 +68,4 @@ 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"
|
||||||
|
|
||||||
|
@ -39,4 +39,4 @@ is one of 'admin', 'super', 'op', 'user'
|
|||||||
This program was written by Jan Vidar Krey <janvidar@extatic.org>
|
This program was written by Jan Vidar Krey <janvidar@extatic.org>
|
||||||
.SH "BUG REPORTS"
|
.SH "BUG REPORTS"
|
||||||
If you find a bug in uhub please report it to
|
If you find a bug in uhub please report it to
|
||||||
.B http://bugs.extatic.org/
|
.B https://github.com/janvidar/uhub/issues
|
||||||
|
@ -69,4 +69,4 @@ To run uhub as a daemon, and log to a file:
|
|||||||
This program was written by Jan Vidar Krey <janvidar@extatic.org>
|
This program was written by Jan Vidar Krey <janvidar@extatic.org>
|
||||||
.SH "BUG REPORTS"
|
.SH "BUG REPORTS"
|
||||||
If you find a bug in uhub please report it to
|
If you find a bug in uhub please report it to
|
||||||
.B http://bugs.extatic.org/
|
.B https://github.com/janvidar/uhub/issues
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
# You should normally place this file in /etc/uhub/uhub.conf
|
# You should normally place this file in /etc/uhub/uhub.conf
|
||||||
# and customize some of the settings below.
|
# and customize some of the settings below.
|
||||||
#
|
#
|
||||||
# This file is read only to the uhub deamon, and if you
|
# This file is read only to the uhub daemon, and if you
|
||||||
# make changes to it while uhub is running you can send a
|
# make changes to it while uhub is running you can send a
|
||||||
# HUP signal to it ( $ killall -HUP uhub ), to reparse configuration (only on UNIX).
|
# HUP signal to it ( $ killall -HUP uhub ), to reparse configuration (only on UNIX).
|
||||||
# All configuration directives: http://www.uhub.org/config.php
|
# All configuration directives: https://www.uhub.org/config.php
|
||||||
|
|
||||||
# Bind to this port and address
|
# Bind to this port and address
|
||||||
# server_bind_addr=any means listen to "::" if IPv6 is supported
|
# server_bind_addr=any means listen to "::" if IPv6 is supported
|
||||||
@ -104,11 +104,11 @@ msg_auth_invalid_password = Password is wrong
|
|||||||
msg_auth_user_not_found = User not found in password database
|
msg_auth_user_not_found = User not found in password database
|
||||||
msg_user_share_size_low = User is not sharing enough
|
msg_user_share_size_low = User is not sharing enough
|
||||||
msg_user_share_size_high = User is sharing too much
|
msg_user_share_size_high = User is sharing too much
|
||||||
msg_user_slots_low = User have too few upload slots
|
msg_user_slots_low = User has too few upload slots
|
||||||
msg_user_slots_high = User have too many upload slots
|
msg_user_slots_high = User has too many upload slots
|
||||||
msg_user_hub_limit_low = User is on too few hubs
|
msg_user_hub_limit_low = User is on too few hubs
|
||||||
msg_user_hub_limit_high = User is on too many hubs
|
msg_user_hub_limit_high = User is on too many hubs
|
||||||
msg_error_no_memory = No memory
|
msg_error_no_memory = Out of memory
|
||||||
msg_user_flood_chat = Chat flood detected, messages are dropped.
|
msg_user_flood_chat = Chat flood detected, messages are dropped.
|
||||||
msg_user_flood_connect = Connect flood detected, connection refused.
|
msg_user_flood_connect = Connect flood detected, connection refused.
|
||||||
msg_user_flood_search = Search flood detected, search is stopped.
|
msg_user_flood_search = Search flood detected, search is stopped.
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
inherit eutils
|
inherit eutils
|
||||||
|
|
||||||
if [ "$PV" != "9999" ]; then
|
if [ "$PV" != "9999" ]; then
|
||||||
SRC_URI="http://www.extatic.org/downloads/uhub/${P}-src.tar.bz2"
|
SRC_URI="https://www.extatic.org/downloads/uhub/${P}-src.tar.bz2"
|
||||||
KEYWORDS="~amd64 ~x86"
|
KEYWORDS="~amd64 ~x86"
|
||||||
else
|
else
|
||||||
inherit git
|
inherit git
|
||||||
@ -16,7 +16,7 @@ fi
|
|||||||
EAPI="2"
|
EAPI="2"
|
||||||
|
|
||||||
DESCRIPTION="High performance ADC hub"
|
DESCRIPTION="High performance ADC hub"
|
||||||
HOMEPAGE="http://www.uhub.org/"
|
HOMEPAGE="https://www.uhub.org/"
|
||||||
|
|
||||||
LICENSE="GPL-3"
|
LICENSE="GPL-3"
|
||||||
SLOT="0"
|
SLOT="0"
|
||||||
|
@ -5,7 +5,7 @@ Release: 2
|
|||||||
License: GPLv3
|
License: GPLv3
|
||||||
Group: Networking/File transfer
|
Group: Networking/File transfer
|
||||||
Source: uhub-%{version}.tar.gz
|
Source: uhub-%{version}.tar.gz
|
||||||
URL: http://www.uhub.org
|
URL: https://www.uhub.org
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
|
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
|
||||||
|
|
||||||
BuildRequires: sqlite-devel
|
BuildRequires: sqlite-devel
|
||||||
@ -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
|
||||||
@ -80,7 +80,7 @@ rm -rf $RPM_BUILD_ROOT
|
|||||||
if [ $1 -gt 1 ] ; then
|
if [ $1 -gt 1 ] ; then
|
||||||
/etc/rc.d/init.d/uhub restart >/dev/null || :
|
/etc/rc.d/init.d/uhub restart >/dev/null || :
|
||||||
fi
|
fi
|
||||||
# need more informations about add services and users in system
|
# need more information about add services and users in system
|
||||||
/usr/sbin/adduser -M -d /tmp -G nobody -s /sbin/nologin -c 'The Uhub ADC p2p hub Daemon' uhub >/dev/null 2>&1 ||:
|
/usr/sbin/adduser -M -d /tmp -G nobody -s /sbin/nologin -c 'The Uhub ADC p2p hub Daemon' uhub >/dev/null 2>&1 ||:
|
||||||
# write SSL create
|
# write SSL create
|
||||||
echo "PLS see /usr/share/doc/uhub/"
|
echo "PLS see /usr/share/doc/uhub/"
|
||||||
|
@ -8,7 +8,7 @@ start on filesystem or runlevel [2345]
|
|||||||
stop on runlevel [!2345]
|
stop on runlevel [!2345]
|
||||||
|
|
||||||
# Allow the service to respawn, but if its happening too often
|
# Allow the service to respawn, but if its happening too often
|
||||||
# (10 times in 5 seconds) theres a problem and we should stop trying.
|
# (10 times in 5 seconds) there's a problem and we should stop trying.
|
||||||
respawn
|
respawn
|
||||||
respawn limit 10 5
|
respawn limit 10 5
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2012, Jan Vidar Krey
|
* Copyright (C) 2007-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -111,12 +111,15 @@ typedef uint32_t fourcc_t;
|
|||||||
#define ADC_INF_FLAG_CLIENT_ID "ID" /* client id, aka CID */
|
#define ADC_INF_FLAG_CLIENT_ID "ID" /* client id, aka CID */
|
||||||
#define ADC_INF_FLAG_NICK "NI" /* nick name */
|
#define ADC_INF_FLAG_NICK "NI" /* nick name */
|
||||||
#define ADC_INF_FLAG_DESCRIPTION "DE" /* user description */
|
#define ADC_INF_FLAG_DESCRIPTION "DE" /* user description */
|
||||||
#define ADC_INF_FLAG_USER_AGENT "VE" /* software version */
|
|
||||||
|
#define ADC_INF_FLAG_USER_AGENT_PRODUCT "AP" /* software name */
|
||||||
|
#define ADC_INF_FLAG_USER_AGENT_VERSION "VE" /* software version */
|
||||||
|
|
||||||
#define ADC_INF_FLAG_SUPPORT "SU" /* support (extensions, feature cast) */
|
#define ADC_INF_FLAG_SUPPORT "SU" /* support (extensions, feature cast) */
|
||||||
#define ADC_INF_FLAG_SHARED_SIZE "SS" /* size of total files shared in bytes */
|
#define ADC_INF_FLAG_SHARED_SIZE "SS" /* size of total files shared in bytes */
|
||||||
#define ADC_INF_FLAG_SHARED_FILES "SF" /* number of files shared */
|
#define ADC_INF_FLAG_SHARED_FILES "SF" /* number of files shared */
|
||||||
#define ADC_INF_FLAG_UPLOAD_SPEED "US" /* maximum upload speed acheived in bytes/sec */
|
#define ADC_INF_FLAG_UPLOAD_SPEED "US" /* maximum upload speed achieved in bytes/sec */
|
||||||
#define ADC_INF_FLAG_DOWNLOAD_SPEED "DS" /* maximum download speed acheived in bytes/sec */
|
#define ADC_INF_FLAG_DOWNLOAD_SPEED "DS" /* maximum download speed achieved in bytes/sec */
|
||||||
#define ADC_INF_FLAG_UPLOAD_SLOTS "SL" /* maximum upload slots (concurrent uploads) */
|
#define ADC_INF_FLAG_UPLOAD_SLOTS "SL" /* maximum upload slots (concurrent uploads) */
|
||||||
#define ADC_INF_FLAG_AUTO_SLOTS "AS" /* automatic slot if upload speed is less than this in bytes/sec */
|
#define ADC_INF_FLAG_AUTO_SLOTS "AS" /* automatic slot if upload speed is less than this in bytes/sec */
|
||||||
#define ADC_INF_FLAG_AUTO_SLOTS_MAX "AM" /* maximum number of automatic slots */
|
#define ADC_INF_FLAG_AUTO_SLOTS_MAX "AM" /* maximum number of automatic slots */
|
||||||
@ -131,7 +134,7 @@ typedef uint32_t fourcc_t;
|
|||||||
#define ADC_MSG_FLAG_PRIVATE "PM" /* message is a private message */
|
#define ADC_MSG_FLAG_PRIVATE "PM" /* message is a private message */
|
||||||
|
|
||||||
#define ADC_SCH_FLAG_INCLUDE "AN" /* include given search term */
|
#define ADC_SCH_FLAG_INCLUDE "AN" /* include given search term */
|
||||||
#define ADC_SCH_FLAG_EXCLUDE "NO" /* exclude given serach term */
|
#define ADC_SCH_FLAG_EXCLUDE "NO" /* exclude given search term */
|
||||||
#define ADC_SCH_FLAG_FILE_EXTENSION "EX" /* search only for files with the given file extension */
|
#define ADC_SCH_FLAG_FILE_EXTENSION "EX" /* search only for files with the given file extension */
|
||||||
#define ADC_SCH_FLAG_FILE_TYPE "TY" /* search only for files with this file type (separate type) */
|
#define ADC_SCH_FLAG_FILE_TYPE "TY" /* search only for files with this file type (separate type) */
|
||||||
#define ADC_SCH_FLAG_LESS_THAN "LE" /* search for files with this size or less */
|
#define ADC_SCH_FLAG_LESS_THAN "LE" /* search for files with this size or less */
|
||||||
@ -156,6 +159,7 @@ typedef uint32_t fourcc_t;
|
|||||||
#define ADC_CLIENT_TYPE_BOT "1"
|
#define ADC_CLIENT_TYPE_BOT "1"
|
||||||
#define ADC_CLIENT_TYPE_REGISTERED_USER "2"
|
#define ADC_CLIENT_TYPE_REGISTERED_USER "2"
|
||||||
#define ADC_CLIENT_TYPE_OPERATOR "4"
|
#define ADC_CLIENT_TYPE_OPERATOR "4"
|
||||||
|
#define ADC_CLIENT_TYPE_HUBBOT "5" /* 1 + 4 */
|
||||||
#define ADC_CLIENT_TYPE_SUPER_USER "12" /* 8 + 4 */
|
#define ADC_CLIENT_TYPE_SUPER_USER "12" /* 8 + 4 */
|
||||||
#define ADC_CLIENT_TYPE_ADMIN "20" /* 16 + 4 = hub owner */
|
#define ADC_CLIENT_TYPE_ADMIN "20" /* 16 + 4 = hub owner */
|
||||||
#define ADC_CLIENT_TYPE_HUB "32" /* the hub itself */
|
#define ADC_CLIENT_TYPE_HUB "32" /* the hub itself */
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -24,7 +24,6 @@
|
|||||||
uhub_assert(X); \
|
uhub_assert(X); \
|
||||||
uhub_assert(X->cache); \
|
uhub_assert(X->cache); \
|
||||||
uhub_assert(X->capacity); \
|
uhub_assert(X->capacity); \
|
||||||
uhub_assert(X->length); \
|
|
||||||
uhub_assert(X->length <= X->capacity); \
|
uhub_assert(X->length <= X->capacity); \
|
||||||
uhub_assert(X->references > 0); \
|
uhub_assert(X->references > 0); \
|
||||||
uhub_assert(X->length == strlen(X->cache));
|
uhub_assert(X->length == strlen(X->cache));
|
||||||
@ -283,23 +282,19 @@ struct adc_message* adc_msg_copy(const struct adc_message* cmd)
|
|||||||
if (cmd->feature_cast_include)
|
if (cmd->feature_cast_include)
|
||||||
{
|
{
|
||||||
copy->feature_cast_include = list_create();
|
copy->feature_cast_include = list_create();
|
||||||
tmp = list_get_first(cmd->feature_cast_include);
|
LIST_FOREACH(char*, tmp, cmd->feature_cast_include,
|
||||||
while (tmp)
|
|
||||||
{
|
{
|
||||||
list_append(copy->feature_cast_include, hub_strdup(tmp));
|
list_append(copy->feature_cast_include, hub_strdup(tmp));
|
||||||
tmp = list_get_next(cmd->feature_cast_include);
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd->feature_cast_exclude)
|
if (cmd->feature_cast_exclude)
|
||||||
{
|
{
|
||||||
copy->feature_cast_exclude = list_create();
|
copy->feature_cast_exclude = list_create();
|
||||||
tmp = list_get_first(cmd->feature_cast_exclude);
|
LIST_FOREACH(char*, tmp, cmd->feature_cast_exclude,
|
||||||
while (tmp)
|
|
||||||
{
|
{
|
||||||
list_append(copy->feature_cast_exclude, hub_strdup(tmp));
|
list_append(copy->feature_cast_exclude, hub_strdup(tmp));
|
||||||
tmp = list_get_next(cmd->feature_cast_exclude);
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ADC_MSG_ASSERT(copy);
|
ADC_MSG_ASSERT(copy);
|
||||||
@ -315,7 +310,7 @@ struct adc_message* adc_msg_parse_verify(struct hub_user* u, const char* line, s
|
|||||||
if (!command)
|
if (!command)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (command->source && (!u || command->source != u->id.sid))
|
if (command->source && (!u || (command->source != u->id.sid && !auth_cred_is_unrestricted(u->credentials))))
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Command does not match user's SID (command->source=%d, user->id.sid=%d)", command->source, (u ? u->id.sid : 0));
|
LOG_DEBUG("Command does not match user's SID (command->source=%d, user->id.sid=%d)", command->source, (u ? u->id.sid : 0));
|
||||||
adc_msg_free(command);
|
adc_msg_free(command);
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ enum msg_status_level
|
|||||||
extern struct adc_message* adc_msg_incref(struct adc_message* msg);
|
extern struct adc_message* adc_msg_incref(struct adc_message* msg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decrease the reference counter, and free the memory when apropriate.
|
* Decrease the reference counter, and free the memory when appropriate.
|
||||||
*/
|
*/
|
||||||
extern void adc_msg_free(struct adc_message* msg);
|
extern void adc_msg_free(struct adc_message* msg);
|
||||||
|
|
||||||
@ -159,7 +159,7 @@ extern char* adc_msg_get_argument(struct adc_message* cmd, int offset);
|
|||||||
*
|
*
|
||||||
* @arg prefix a 2 character argument prefix
|
* @arg prefix a 2 character argument prefix
|
||||||
* @arg string must be escaped (see adc_msg_escape).
|
* @arg string must be escaped (see adc_msg_escape).
|
||||||
* @return 0 if successful, or -1 if an error occured.
|
* @return 0 if successful, or -1 if an error occurred.
|
||||||
*/
|
*/
|
||||||
extern int adc_msg_replace_named_argument(struct adc_message* cmd, const char prefix[2], const char* string);
|
extern int adc_msg_replace_named_argument(struct adc_message* cmd, const char prefix[2], const char* string);
|
||||||
|
|
||||||
@ -167,7 +167,7 @@ extern int adc_msg_replace_named_argument(struct adc_message* cmd, const char pr
|
|||||||
* Append an argument
|
* Append an argument
|
||||||
*
|
*
|
||||||
* @arg string must be escaped (see adc_msg_escape).
|
* @arg string must be escaped (see adc_msg_escape).
|
||||||
* @return 0 if successful, or -1 if an error occured (out of memory).
|
* @return 0 if successful, or -1 if an error occurred (out of memory).
|
||||||
*/
|
*/
|
||||||
extern int adc_msg_add_argument(struct adc_message* cmd, const char* string);
|
extern int adc_msg_add_argument(struct adc_message* cmd, const char* string);
|
||||||
|
|
||||||
@ -176,7 +176,7 @@ extern int adc_msg_add_argument(struct adc_message* cmd, const char* string);
|
|||||||
*
|
*
|
||||||
* @arg prefix a 2 character argument prefix
|
* @arg prefix a 2 character argument prefix
|
||||||
* @arg string must be escaped (see adc_msg_escape).
|
* @arg string must be escaped (see adc_msg_escape).
|
||||||
* @return 0 if successful, or -1 if an error occured (out of memory).
|
* @return 0 if successful, or -1 if an error occurred (out of memory).
|
||||||
*/
|
*/
|
||||||
extern int adc_msg_add_named_argument(struct adc_message* cmd, const char prefix[2], const char* string);
|
extern int adc_msg_add_named_argument(struct adc_message* cmd, const char prefix[2], const char* string);
|
||||||
|
|
||||||
@ -186,7 +186,7 @@ extern int adc_msg_add_named_argument(struct adc_message* cmd, const char prefix
|
|||||||
*
|
*
|
||||||
* @arg prefix a 2 character argument prefix
|
* @arg prefix a 2 character argument prefix
|
||||||
* @arg string must NOT be escaped
|
* @arg string must NOT be escaped
|
||||||
* @return 0 if successful, or -1 if an error occured (out of memory).
|
* @return 0 if successful, or -1 if an error occurred (out of memory).
|
||||||
*/
|
*/
|
||||||
extern int adc_msg_add_named_argument_string(struct adc_message* cmd, const char prefix[2], const char* string);
|
extern int adc_msg_add_named_argument_string(struct adc_message* cmd, const char prefix[2], const char* string);
|
||||||
|
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -170,6 +170,9 @@ static int acl_parse_line(char* line, int line_count, void* ptr_data)
|
|||||||
LOG_DEBUG("acl_parse_line: '%s'", line);
|
LOG_DEBUG("acl_parse_line: '%s'", line);
|
||||||
|
|
||||||
ACL_ADD_USER("bot", handle->users, auth_cred_bot);
|
ACL_ADD_USER("bot", handle->users, auth_cred_bot);
|
||||||
|
ACL_ADD_USER("ubot", handle->users, auth_cred_ubot);
|
||||||
|
ACL_ADD_USER("opbot", handle->users, auth_cred_opbot);
|
||||||
|
ACL_ADD_USER("opubot", handle->users, auth_cred_opubot);
|
||||||
ACL_ADD_USER("user_admin", handle->users, auth_cred_admin);
|
ACL_ADD_USER("user_admin", handle->users, auth_cred_admin);
|
||||||
ACL_ADD_USER("user_super", handle->users, auth_cred_super);
|
ACL_ADD_USER("user_super", handle->users, auth_cred_super);
|
||||||
ACL_ADD_USER("user_op", handle->users, auth_cred_operator);
|
ACL_ADD_USER("user_op", handle->users, auth_cred_operator);
|
||||||
@ -330,13 +333,11 @@ struct auth_info* acl_get_access_info(struct hub_info* hub, const char* name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define STR_LIST_CONTAINS(LIST, STR) \
|
#define STR_LIST_CONTAINS(LIST, STR) \
|
||||||
str = (char*) list_get_first(LIST); \
|
LIST_FOREACH(char*, str, LIST, \
|
||||||
while (str) \
|
|
||||||
{ \
|
{ \
|
||||||
if (strcasecmp(str, STR) == 0) \
|
if (strcasecmp(str, STR) == 0) \
|
||||||
return 1; \
|
return 1; \
|
||||||
str = (char*) list_get_next(LIST); \
|
}); \
|
||||||
} \
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
int acl_is_cid_banned(struct acl_handle* handle, const char* data)
|
int acl_is_cid_banned(struct acl_handle* handle, const char* data)
|
||||||
@ -400,34 +401,28 @@ int acl_user_unban_cid(struct acl_handle* handle, const char* cid)
|
|||||||
int acl_is_ip_banned(struct acl_handle* handle, const char* ip_address)
|
int acl_is_ip_banned(struct acl_handle* handle, const char* ip_address)
|
||||||
{
|
{
|
||||||
struct ip_addr_encap raw;
|
struct ip_addr_encap raw;
|
||||||
struct ip_range* info = (struct ip_range*) list_get_first(handle->networks);
|
struct ip_range* info;
|
||||||
ip_convert_to_binary(ip_address, &raw);
|
|
||||||
|
|
||||||
while (info)
|
ip_convert_to_binary(ip_address, &raw);
|
||||||
|
LIST_FOREACH(struct ip_range*, info, handle->networks,
|
||||||
{
|
{
|
||||||
if (ip_in_range(&raw, info))
|
if (ip_in_range(&raw, info))
|
||||||
{
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
});
|
||||||
info = (struct ip_range*) list_get_next(handle->networks);
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int acl_is_ip_nat_override(struct acl_handle* handle, const char* ip_address)
|
int acl_is_ip_nat_override(struct acl_handle* handle, const char* ip_address)
|
||||||
{
|
{
|
||||||
struct ip_addr_encap raw;
|
struct ip_addr_encap raw;
|
||||||
struct ip_range* info = (struct ip_range*) list_get_first(handle->nat_override);
|
struct ip_range* info;
|
||||||
ip_convert_to_binary(ip_address, &raw);
|
|
||||||
|
|
||||||
while (info)
|
ip_convert_to_binary(ip_address, &raw);
|
||||||
|
LIST_FOREACH(struct ip_range*, info, handle->nat_override,
|
||||||
{
|
{
|
||||||
if (ip_in_range(&raw, info))
|
if (ip_in_range(&raw, info))
|
||||||
{
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
});
|
||||||
info = (struct ip_range*) list_get_next(handle->nat_override);
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2012, Jan Vidar Krey
|
* Copyright (C) 2007-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ static void hub_command_args_free(struct hub_command* cmd)
|
|||||||
if (!cmd->args)
|
if (!cmd->args)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (data = (struct hub_command_arg_data*) list_get_first(cmd->args); data; data = (struct hub_command_arg_data*) list_get_next(cmd->args))
|
LIST_FOREACH(struct hub_command_arg_data*, data, cmd->args,
|
||||||
{
|
{
|
||||||
switch (data->type)
|
switch (data->type)
|
||||||
{
|
{
|
||||||
@ -39,7 +39,7 @@ static void hub_command_args_free(struct hub_command* cmd)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
list_clear(cmd->args, hub_free);
|
list_clear(cmd->args, hub_free);
|
||||||
list_destroy(cmd->args);
|
list_destroy(cmd->args);
|
||||||
@ -64,6 +64,7 @@ static enum command_parse_status command_extract_arguments(struct hub_info* hub,
|
|||||||
char* token = NULL;
|
char* token = NULL;
|
||||||
char* tmp = NULL;
|
char* tmp = NULL;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
|
size_t offset = 0;
|
||||||
struct hub_command_arg_data* data = NULL;
|
struct hub_command_arg_data* data = NULL;
|
||||||
enum command_parse_status status = cmd_status_ok;
|
enum command_parse_status status = cmd_status_ok;
|
||||||
|
|
||||||
@ -77,15 +78,15 @@ static enum command_parse_status command_extract_arguments(struct hub_info* hub,
|
|||||||
if (greedy)
|
if (greedy)
|
||||||
{
|
{
|
||||||
size = 1;
|
size = 1;
|
||||||
for (tmp = (char*) list_get_first(tokens); tmp; tmp = (char*) list_get_next(tokens))
|
LIST_FOREACH(char*, tmp, tokens, { size += (strlen(tmp) + 1); });
|
||||||
size += (strlen(tmp) + 1);
|
|
||||||
token = hub_malloc_zero(size);
|
token = hub_malloc_zero(size);
|
||||||
|
|
||||||
while ((tmp = list_get_first(tokens)))
|
while ((tmp = list_get_first(tokens)))
|
||||||
{
|
{
|
||||||
if (*token)
|
if (offset > 0)
|
||||||
strcat(token, " ");
|
token[offset++] = ' ';
|
||||||
strcat(token, tmp);
|
memcpy(token + offset, tmp, strlen(tmp));
|
||||||
|
offset += strlen(tmp);
|
||||||
list_remove(tokens, tmp);
|
list_remove(tokens, tmp);
|
||||||
hub_free(tmp);
|
hub_free(tmp);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2012, Jan Vidar Krey
|
* Copyright (C) 2007-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ struct command_base;
|
|||||||
*
|
*
|
||||||
* @param cbase Command base pointer.
|
* @param cbase Command base pointer.
|
||||||
* @param user User who invoked the command.
|
* @param user User who invoked the command.
|
||||||
* @param message The message that is to be interpreted as a command (including the invokation prefix '!' or '+')
|
* @param message The message that is to be interpreted as a command (including the invocation prefix '!' or '+')
|
||||||
*
|
*
|
||||||
* @return a hub_command that must be freed with command_free(). @See struct hub_command.
|
* @return a hub_command that must be freed with command_free(). @See struct hub_command.
|
||||||
*/
|
*/
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2012, Jan Vidar Krey
|
* Copyright (C) 2007-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -31,8 +31,6 @@ static int send_command_not_found(struct command_base* cbase, struct hub_user* u
|
|||||||
static int send_command_syntax_error(struct command_base* cbase, struct hub_user* user);
|
static int send_command_syntax_error(struct command_base* cbase, struct hub_user* user);
|
||||||
static int send_command_missing_arguments(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd);
|
static int send_command_missing_arguments(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd);
|
||||||
|
|
||||||
static void null_free(void* ptr) { }
|
|
||||||
|
|
||||||
struct command_base
|
struct command_base
|
||||||
{
|
{
|
||||||
struct hub_info* hub;
|
struct hub_info* hub;
|
||||||
@ -98,14 +96,14 @@ struct command_handle* command_handler_lookup(struct command_base* cbase, const
|
|||||||
struct command_handle* handler = NULL;
|
struct command_handle* handler = NULL;
|
||||||
size_t prefix_len = strlen(prefix);
|
size_t prefix_len = strlen(prefix);
|
||||||
|
|
||||||
for (handler = (struct command_handle*) list_get_first(cbase->handlers); handler; handler = (struct command_handle*) list_get_next(cbase->handlers))
|
LIST_FOREACH(struct command_handle*, handler, cbase->handlers,
|
||||||
{
|
{
|
||||||
if (prefix_len != handler->length)
|
if (prefix_len != handler->length)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!memcmp(prefix, handler->prefix, handler->length))
|
if (!memcmp(prefix, handler->prefix, handler->length))
|
||||||
return handler;
|
return handler;
|
||||||
}
|
});
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,7 +290,7 @@ static int command_help(struct command_base* cbase, struct hub_user* user, struc
|
|||||||
{
|
{
|
||||||
cbuf_append(buf, "Available commands:\n");
|
cbuf_append(buf, "Available commands:\n");
|
||||||
|
|
||||||
for (command = (struct command_handle*) list_get_first(cbase->handlers); command; command = (struct command_handle*) list_get_next(cbase->handlers))
|
LIST_FOREACH(struct command_handle*, command, cbase->handlers,
|
||||||
{
|
{
|
||||||
if (command_is_available(command, user->credentials))
|
if (command_is_available(command, user->credentials))
|
||||||
{
|
{
|
||||||
@ -301,7 +299,7 @@ static int command_help(struct command_base* cbase, struct hub_user* user, struc
|
|||||||
cbuf_append(buf, " ");
|
cbuf_append(buf, " ");
|
||||||
cbuf_append_format(buf, " - %s\n", command->description);
|
cbuf_append_format(buf, " - %s\n", command->description);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -424,7 +422,7 @@ static int command_whoip(struct command_base* cbase, struct hub_user* user, stru
|
|||||||
ret = uman_get_user_by_addr(cbase->hub->users, 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);
|
||||||
list_destroy(users);
|
list_destroy(users);
|
||||||
return command_status(cbase, user, cmd, cbuf_create_const("No users found."));
|
return command_status(cbase, user, cmd, cbuf_create_const("No users found."));
|
||||||
}
|
}
|
||||||
@ -432,16 +430,14 @@ static int command_whoip(struct command_base* cbase, struct hub_user* user, stru
|
|||||||
buf = cbuf_create(128 + ((MAX_NICK_LEN + INET6_ADDRSTRLEN + 5) * ret));
|
buf = cbuf_create(128 + ((MAX_NICK_LEN + INET6_ADDRSTRLEN + 5) * ret));
|
||||||
cbuf_append_format(buf, "*** %s: Found %d match%s:\n", cmd->prefix, ret, ((ret != 1) ? "es" : ""));
|
cbuf_append_format(buf, "*** %s: Found %d match%s:\n", cmd->prefix, ret, ((ret != 1) ? "es" : ""));
|
||||||
|
|
||||||
u = (struct hub_user*) list_get_first(users);
|
LIST_FOREACH(struct hub_user*, u, users,
|
||||||
while (u)
|
|
||||||
{
|
{
|
||||||
cbuf_append_format(buf, "%s (%s)\n", u->id.nick, user_get_address(u));
|
cbuf_append_format(buf, "%s (%s)\n", u->id.nick, user_get_address(u));
|
||||||
u = (struct hub_user*) list_get_next(users);
|
});
|
||||||
}
|
|
||||||
cbuf_append(buf, "\n");
|
cbuf_append(buf, "\n");
|
||||||
|
|
||||||
send_message(cbase, user, buf);
|
send_message(cbase, user, buf);
|
||||||
list_clear(users, &null_free);
|
list_clear(users, NULL);
|
||||||
list_destroy(users);
|
list_destroy(users);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -462,8 +458,7 @@ static int command_broadcast(struct command_base* cbase, struct hub_user* user,
|
|||||||
memcpy(from_sid, sid_to_string(user->id.sid), sizeof(from_sid));
|
memcpy(from_sid, sid_to_string(user->id.sid), sizeof(from_sid));
|
||||||
memcpy(pm_flag + 2, from_sid, sizeof(from_sid));
|
memcpy(pm_flag + 2, from_sid, sizeof(from_sid));
|
||||||
|
|
||||||
target = (struct hub_user*) list_get_first(cbase->hub->users->list);
|
LIST_FOREACH(struct hub_user*, target, cbase->hub->users->list,
|
||||||
while (target)
|
|
||||||
{
|
{
|
||||||
if (target != user)
|
if (target != user)
|
||||||
{
|
{
|
||||||
@ -480,8 +475,7 @@ static int command_broadcast(struct command_base* cbase, struct hub_user* user,
|
|||||||
route_to_user(cbase->hub, target, command);
|
route_to_user(cbase->hub, target, command);
|
||||||
adc_msg_free(command);
|
adc_msg_free(command);
|
||||||
}
|
}
|
||||||
target = (struct hub_user*) list_get_next(cbase->hub->users->list);
|
});
|
||||||
}
|
|
||||||
|
|
||||||
cbuf_append_format(buf, "*** %s: Delivered to " PRINTF_SIZE_T " user%s", cmd->prefix, recipients, (recipients != 1 ? "s" : ""));
|
cbuf_append_format(buf, "*** %s: Delivered to " PRINTF_SIZE_T " user%s", cmd->prefix, recipients, (recipients != 1 ? "s" : ""));
|
||||||
send_message(cbase, user, buf);
|
send_message(cbase, user, buf);
|
||||||
@ -513,8 +507,7 @@ static int command_log(struct command_base* cbase, struct hub_user* user, struct
|
|||||||
command_status(cbase, user, cmd, buf);
|
command_status(cbase, user, cmd, buf);
|
||||||
|
|
||||||
buf = cbuf_create(MAX_HELP_LINE);
|
buf = cbuf_create(MAX_HELP_LINE);
|
||||||
log = (struct hub_logout_info*) list_get_first(messages);
|
LIST_FOREACH(struct hub_logout_info*, log, messages,
|
||||||
while (log)
|
|
||||||
{
|
{
|
||||||
const char* address = ip_convert_to_string(&log->addr);
|
const char* address = ip_convert_to_string(&log->addr);
|
||||||
int show = 0;
|
int show = 0;
|
||||||
@ -538,8 +531,7 @@ static int command_log(struct command_base* cbase, struct hub_user* user, struct
|
|||||||
send_message(cbase, user, buf);
|
send_message(cbase, user, buf);
|
||||||
buf = cbuf_create(MAX_HELP_LINE);
|
buf = cbuf_create(MAX_HELP_LINE);
|
||||||
}
|
}
|
||||||
log = (struct hub_logout_info*) list_get_next(messages);
|
});
|
||||||
}
|
|
||||||
|
|
||||||
if (search_len)
|
if (search_len)
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2012, Jan Vidar Krey
|
* Copyright (C) 2007-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1,289 +0,0 @@
|
|||||||
#!/usr/bin/perl -w
|
|
||||||
|
|
||||||
use strict;
|
|
||||||
use XML::DOM;
|
|
||||||
|
|
||||||
sub write_c_header(@);
|
|
||||||
sub write_sql_dump(@);
|
|
||||||
sub get_data($);
|
|
||||||
|
|
||||||
my $dump_to_sql = 0;
|
|
||||||
|
|
||||||
# initialize parser and read the file
|
|
||||||
my $input = "./config.xml";
|
|
||||||
my $parser = new XML::DOM::Parser;
|
|
||||||
my $tree = $parser->parsefile($input) || die "Unable to parse XML file.";
|
|
||||||
|
|
||||||
# Get data
|
|
||||||
my $nodes = $tree->getElementsByTagName("option");
|
|
||||||
my @options = ();
|
|
||||||
for (my $i = 0; $i < $nodes->getLength; $i++)
|
|
||||||
{
|
|
||||||
my @data = get_data($nodes->item($i));
|
|
||||||
push @options, \@data;
|
|
||||||
}
|
|
||||||
|
|
||||||
write_c_header(@options);
|
|
||||||
write_sql_dump(@options) if ($dump_to_sql);
|
|
||||||
|
|
||||||
my $config_defaults = "void config_defaults(struct hub_config* config)\n{\n";
|
|
||||||
my $config_apply = "static int apply_config(struct hub_config* config, char* key, char* data, int line_count)\n{\n\tint max = 0;\n\tint min = 0;\n\n";
|
|
||||||
my $config_free = "void free_config(struct hub_config* config)\n{\n";
|
|
||||||
my $config_dump = "void dump_config(struct hub_config* config, int ignore_defaults)\n{\n";
|
|
||||||
|
|
||||||
foreach my $option (@options)
|
|
||||||
{
|
|
||||||
my ($type, $name, $default, $advanced, $short, $desc, $since, $example, $check, $ifdef) = @$option;
|
|
||||||
my $string = ($type =~ /(string|file|message)/);
|
|
||||||
my $min = undef;
|
|
||||||
my $max = undef;
|
|
||||||
my $regexp = undef;
|
|
||||||
|
|
||||||
if (defined $check)
|
|
||||||
{
|
|
||||||
$min = $check->getAttribute("min");
|
|
||||||
$max = $check->getAttribute("max");
|
|
||||||
$regexp = $check->getAttribute("regexp");
|
|
||||||
|
|
||||||
$max = undef if ($max eq "");
|
|
||||||
$min = undef if ($min eq "");
|
|
||||||
$regexp = undef if ($regexp eq "");
|
|
||||||
}
|
|
||||||
|
|
||||||
$config_defaults .= "#ifdef $ifdef\n" if ($ifdef ne "");
|
|
||||||
$config_defaults .= "\tconfig->$name = ";
|
|
||||||
$config_defaults .= "hub_strdup(\"" if ($string);
|
|
||||||
$config_defaults .= $default;
|
|
||||||
$config_defaults .= "\")" if ($string);
|
|
||||||
$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";
|
|
||||||
|
|
||||||
if ($type eq "int")
|
|
||||||
{
|
|
||||||
$config_apply .= "\t\tmin = $min;\n" if (defined $min);
|
|
||||||
$config_apply .= "\t\tmax = $max;\n" if (defined $max);
|
|
||||||
$config_apply .= "\t\tif (!apply_integer(key, data, &config->$name, ";
|
|
||||||
if (defined $min) { $config_apply .= "&min"; } else { $config_apply .= "0"; }
|
|
||||||
$config_apply .= ", ";
|
|
||||||
if (defined $max) { $config_apply .= "&max"; } else { $config_apply .= "0"; }
|
|
||||||
$config_apply .= "))\n";
|
|
||||||
}
|
|
||||||
elsif ($type eq "boolean")
|
|
||||||
{
|
|
||||||
$config_apply .= "\t\tif (!apply_boolean(key, data, &config->$name))\n";
|
|
||||||
}
|
|
||||||
elsif ($string)
|
|
||||||
{
|
|
||||||
$config_apply .="\t\tif (!apply_string(key, data, &config->$name, (char*) \"\"))\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
$config_apply .= "\t\t{\n" .
|
|
||||||
"\t\t\tLOG_ERROR(\"Configuration parse error on line %d\", line_count);\n" .
|
|
||||||
"\t\t\treturn -1;\n" .
|
|
||||||
"\t\t}\n" .
|
|
||||||
"\t\treturn 0;\n" .
|
|
||||||
"\t}\n";
|
|
||||||
$config_apply .= "#endif /* $ifdef */\n" if ($ifdef ne "");
|
|
||||||
$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 $val = "config->$name";
|
|
||||||
my $test = "config->$name != $default";
|
|
||||||
|
|
||||||
$out = "%d" if ($type eq "int");
|
|
||||||
$val = "config->$name ? \"yes\" : \"no\"" if ($type eq "boolean");
|
|
||||||
|
|
||||||
if ($string)
|
|
||||||
{
|
|
||||||
$out = "\\\"%s\\\"";
|
|
||||||
$test = "strcmp(config->$name, \"$default\") != 0";
|
|
||||||
}
|
|
||||||
|
|
||||||
$config_dump .= "#ifdef $ifdef\n" if ($ifdef ne "");
|
|
||||||
$config_dump .= "\tif (!ignore_defaults || $test)\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 .= "\tLOG_ERROR(\"Unknown configuration directive: '%s'\", key);\n";
|
|
||||||
$config_apply .= "\treturn -1;\n";
|
|
||||||
$config_apply .= "}\n\n";
|
|
||||||
$config_defaults .= "}\n\n";
|
|
||||||
$config_free .= "}\n\n";
|
|
||||||
$config_dump .= "}\n\n";
|
|
||||||
|
|
||||||
open GENIMPL, ">gen_config.c" || die "Unable to write source file";
|
|
||||||
print GENIMPL "/* THIS FILE IS AUTOGENERATED - DO NOT CHANGE IT! */\n\n";
|
|
||||||
print GENIMPL $config_defaults;
|
|
||||||
print GENIMPL $config_apply;
|
|
||||||
print GENIMPL $config_free;
|
|
||||||
print GENIMPL $config_dump;
|
|
||||||
|
|
||||||
|
|
||||||
sub get_data($)
|
|
||||||
{
|
|
||||||
my $p = shift;
|
|
||||||
|
|
||||||
my $short = "";
|
|
||||||
my $example = "";
|
|
||||||
my $description = "";
|
|
||||||
my $since = "";
|
|
||||||
my $ifdef = "";
|
|
||||||
|
|
||||||
$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());
|
|
||||||
$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());
|
|
||||||
my $check = $p->getElementsByTagName("check")->item(0);
|
|
||||||
$ifdef = $p->getElementsByTagName("ifdef")->item(0)->getFirstChild()->getData() if ($p->getElementsByTagName("ifdef")->getLength());
|
|
||||||
|
|
||||||
my @data = (
|
|
||||||
$p->getAttribute("type"),
|
|
||||||
$p->getAttribute("name"),
|
|
||||||
$p->getAttribute("default"),
|
|
||||||
$p->getAttribute("advanced"),
|
|
||||||
$short,
|
|
||||||
$description,
|
|
||||||
$since,
|
|
||||||
$example,
|
|
||||||
$check,
|
|
||||||
$ifdef
|
|
||||||
);
|
|
||||||
return @data;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Write header file
|
|
||||||
sub write_c_header(@)
|
|
||||||
{
|
|
||||||
my @data = @_;
|
|
||||||
|
|
||||||
open GENHEAD, ">gen_config.h" || die "Unable to write header file";
|
|
||||||
print GENHEAD "/* THIS FILE IS AUTOGENERATED - DO NOT CHANGE IT! */\n\n";
|
|
||||||
print GENHEAD "struct hub_config\n{\n";
|
|
||||||
|
|
||||||
foreach my $option (@data)
|
|
||||||
{
|
|
||||||
my ($type, $name, $default, $advanced, $short, $desc, $since, $example, $check, $ifdef) = @$option;
|
|
||||||
|
|
||||||
my $string = ($type =~ /(string|file|message)/);
|
|
||||||
|
|
||||||
print GENHEAD "#ifdef $ifdef\n" if ($ifdef ne "");
|
|
||||||
|
|
||||||
print GENHEAD "\t";
|
|
||||||
print GENHEAD "int " if ($type eq "int");
|
|
||||||
print GENHEAD "int " if ($type eq "boolean");
|
|
||||||
print GENHEAD "char*" if ($string);
|
|
||||||
print GENHEAD " " . $name . ";";
|
|
||||||
|
|
||||||
my $comment = "";
|
|
||||||
if ($type eq "message")
|
|
||||||
{
|
|
||||||
$comment = "\"" . $default . "\"";
|
|
||||||
}
|
|
||||||
elsif (defined $short && length $short > 0)
|
|
||||||
{
|
|
||||||
$comment = $short;
|
|
||||||
if (defined $default)
|
|
||||||
{
|
|
||||||
$comment .= " (default: ";
|
|
||||||
$comment .= "\"" if ($string);
|
|
||||||
$comment .= $default;
|
|
||||||
$comment .= "\"" if ($string);
|
|
||||||
$comment .= ")";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length $comment > 0)
|
|
||||||
{
|
|
||||||
my $pad = "";
|
|
||||||
for (my $i = length $name; $i < 32; $i++)
|
|
||||||
{
|
|
||||||
$pad .= " ";
|
|
||||||
}
|
|
||||||
$comment = $pad . "/*<<< " . $comment . " */";
|
|
||||||
}
|
|
||||||
print GENHEAD $comment . "\n";
|
|
||||||
print GENHEAD "#endif /* $ifdef */\n" if ($ifdef ne "");
|
|
||||||
}
|
|
||||||
|
|
||||||
print GENHEAD "};\n\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sub write_sql_dump(@)
|
|
||||||
{
|
|
||||||
my @data = @_;
|
|
||||||
|
|
||||||
# Write SQL dump code
|
|
||||||
open GENSQL, ">gen_config.sql" || die "Unable to write SQL dump";
|
|
||||||
print GENSQL "START TRANSACTION;\n\n
|
|
||||||
DROP TABLE uhub_config IF EXISTS;\n\n
|
|
||||||
CREATE TABLE uhub_config (
|
|
||||||
name VARCHAR(32) UNIQUE NOT NULL,
|
|
||||||
defaultValue TINYTEXT NOT NULL,
|
|
||||||
description LONGTEXT NOT NULL,
|
|
||||||
type TINYTEXT NOT NULL,
|
|
||||||
advanced BOOLEAN,
|
|
||||||
example LONGTEXT,
|
|
||||||
since TINYTEXT
|
|
||||||
);\n\n";
|
|
||||||
|
|
||||||
foreach my $option (@data)
|
|
||||||
{
|
|
||||||
my ($type, $name, $default, $advanced, $short, $desc, $since, $example, $check, $ifdef) = @$option;
|
|
||||||
|
|
||||||
if ($type =~ /(string|file|message)/ )
|
|
||||||
{
|
|
||||||
$default = "\\\"$default\\\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
$desc =~ s/\"/\\\"/g;
|
|
||||||
$type =~ s/^int$/integer/;
|
|
||||||
|
|
||||||
my $stmt = "INSERT INTO uhub_config VALUES(";
|
|
||||||
$stmt .= "\"$name\", ";
|
|
||||||
$stmt .= "\"$default\", ";
|
|
||||||
$stmt .= "\"$desc\", ";
|
|
||||||
$stmt .= "\"$type\", ";
|
|
||||||
|
|
||||||
if (defined $example)
|
|
||||||
{
|
|
||||||
my $example_str = $example;
|
|
||||||
$example_str =~ s/\\/\\\\/g;
|
|
||||||
$example_str =~ s/\"/\\\"/g;
|
|
||||||
$stmt .= "\"$example_str\", ";
|
|
||||||
} else {
|
|
||||||
$stmt .= "NULL, ";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (defined $since) {
|
|
||||||
$stmt .= "\"$since\", ";
|
|
||||||
} else {
|
|
||||||
$stmt .= "NULL, ";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (defined $advanced) {
|
|
||||||
$stmt .= "\"$advanced\"";
|
|
||||||
} else {
|
|
||||||
$stmt .= "NULL";
|
|
||||||
}
|
|
||||||
|
|
||||||
$stmt .= ");\n";
|
|
||||||
|
|
||||||
print GENSQL $stmt;
|
|
||||||
}
|
|
||||||
print GENSQL "\n\nCOMMIT;\n\n";
|
|
||||||
}
|
|
255
src/core/config.py
Executable file
255
src/core/config.py
Executable file
@ -0,0 +1,255 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
"""
|
||||||
|
uhub - A tiny ADC p2p connection hub
|
||||||
|
Copyright (C) 2007-2013, Jan Vidar Krey
|
||||||
|
"""
|
||||||
|
|
||||||
|
from xml.dom import minidom, Node
|
||||||
|
from datetime import datetime
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
class OptionParseError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Option(object):
|
||||||
|
def _get(self, node, name):
|
||||||
|
self.__dict__[name] = None
|
||||||
|
if (node.getElementsByTagName(name)):
|
||||||
|
self.__dict__[name] = node.getElementsByTagName(name)[0].firstChild.nodeValue
|
||||||
|
|
||||||
|
def _attr(self, node, name, required = False):
|
||||||
|
try:
|
||||||
|
return node.attributes[name].value
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
if (required):
|
||||||
|
raise OptionParseError("Option %s is required but not found!" % name)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def __init__(self, node):
|
||||||
|
self.otype = self._attr(node, 'type', True)
|
||||||
|
|
||||||
|
# Verify that the type is known
|
||||||
|
if not self.otype in ["int", "boolean", "string", "message", "file"]:
|
||||||
|
raise OptionParseError("Option %s has unknown type" % self.name)
|
||||||
|
|
||||||
|
self.name = self._attr(node, 'name', True)
|
||||||
|
self.default = self._attr(node, 'default', True)
|
||||||
|
self.advanced = self._attr(node, 'advanced', False)
|
||||||
|
self.is_string = self.otype in ["string", "message", "file"]
|
||||||
|
|
||||||
|
self._get(node, "short");
|
||||||
|
self._get(node, "description");
|
||||||
|
self._get(node, "syntax");
|
||||||
|
self._get(node, "since");
|
||||||
|
self._get(node, "example");
|
||||||
|
|
||||||
|
check = node.getElementsByTagName("check")
|
||||||
|
if (check):
|
||||||
|
check = node.getElementsByTagName("check")[0]
|
||||||
|
self.check_min = self._attr(check, 'min', False)
|
||||||
|
self.check_max = self._attr(check, 'max', False)
|
||||||
|
self.check_regexp = self._attr(check, 'regexp', False)
|
||||||
|
else:
|
||||||
|
self.check_min = None
|
||||||
|
self.check_max = None
|
||||||
|
self.check_regexp = None
|
||||||
|
|
||||||
|
|
||||||
|
def c_type(self):
|
||||||
|
if self.otype == "boolean":
|
||||||
|
return "int"
|
||||||
|
elif self.is_string:
|
||||||
|
return "char*"
|
||||||
|
else:
|
||||||
|
return self.otype
|
||||||
|
|
||||||
|
def sql_type(self):
|
||||||
|
if self.otype == "int":
|
||||||
|
return "integer"
|
||||||
|
return self.otype
|
||||||
|
|
||||||
|
def c_comment(self):
|
||||||
|
comment = ""
|
||||||
|
if (self.otype == "message"):
|
||||||
|
comment = self.formatted_default()
|
||||||
|
elif len(self.short):
|
||||||
|
comment = "%s (default: %s)" % (self.short, self.formatted_default())
|
||||||
|
return comment
|
||||||
|
|
||||||
|
def formatted_default(self):
|
||||||
|
if self.is_string:
|
||||||
|
return "\"%s\"" % self.default
|
||||||
|
return self.default
|
||||||
|
|
||||||
|
class SourceGenerator(object):
|
||||||
|
def __init__(self, filename, cppStyle = True):
|
||||||
|
print ("Generating %s..." % filename)
|
||||||
|
self.f = open(filename, 'w');
|
||||||
|
|
||||||
|
def write_header(self, Comment = True):
|
||||||
|
if Comment:
|
||||||
|
s = "/*\n * uhub - A tiny ADC p2p connection hub\n"
|
||||||
|
s += " * Copyright (C) 2007-%s, Jan Vidar Krey\n *\n" % datetime.now().strftime("%Y")
|
||||||
|
s += " * THIS FILE IS AUTOGENERATED - DO NOT MODIFY\n"
|
||||||
|
s += " * Created %s, by config.py\n */\n\n" % datetime.now().strftime("%Y-%m-%d %H:%M")
|
||||||
|
self.f.write(s)
|
||||||
|
|
||||||
|
class CHeaderGenerator(SourceGenerator):
|
||||||
|
def __init__(self, filename):
|
||||||
|
super(CHeaderGenerator, self).__init__(filename)
|
||||||
|
|
||||||
|
def _write_declaration(self, option):
|
||||||
|
comment = ' ' * (32 - len(option.name)) + "/*<<< %s */" % option.c_comment()
|
||||||
|
ptype = option.c_type() + (5 - len(option.c_type())) * ' '
|
||||||
|
self.f.write("\t%(type)s %(name)s;%(comment)s\n" % {
|
||||||
|
"type": ptype,
|
||||||
|
"name": option.name,
|
||||||
|
"comment": comment})
|
||||||
|
|
||||||
|
def write(self, options):
|
||||||
|
self.write_header()
|
||||||
|
self.f.write("struct hub_config\n{\n")
|
||||||
|
for option in options:
|
||||||
|
self._write_declaration(option)
|
||||||
|
self.f.write("};\n\n")
|
||||||
|
|
||||||
|
class CSourceGenerator(SourceGenerator):
|
||||||
|
def __init__(self, filename):
|
||||||
|
super(CSourceGenerator, self).__init__(filename)
|
||||||
|
|
||||||
|
def _write_default_impl(self, option):
|
||||||
|
s = "\tconfig->%s = " % option.name
|
||||||
|
if option.is_string:
|
||||||
|
s += "hub_strdup(%s);\n" % option.formatted_default()
|
||||||
|
else:
|
||||||
|
s += option.formatted_default() + ";\n"
|
||||||
|
self.f.write(s)
|
||||||
|
|
||||||
|
def _write_apply_impl(self, option):
|
||||||
|
s = "\tif (!strcmp(key, \"%s\"))\n\t{\n" % option.name
|
||||||
|
if option.otype == "int":
|
||||||
|
s_min = "0"
|
||||||
|
s_max = "0"
|
||||||
|
if (option.check_min):
|
||||||
|
s += "\t\tmin = %s;\n" % option.check_min
|
||||||
|
s_min = "&min"
|
||||||
|
if (option.check_max):
|
||||||
|
s += "\t\tmax = %s;\n" % option.check_max
|
||||||
|
s_max = "&max"
|
||||||
|
s+= "\t\tif (!apply_integer(key, data, &config->%s, %s, %s))\n" % (option.name, s_min, s_max)
|
||||||
|
elif option.otype == "boolean":
|
||||||
|
s += "\t\tif (!apply_boolean(key, data, &config->%s))\n" % option.name
|
||||||
|
elif option.is_string:
|
||||||
|
s += "\t\tif (!apply_string(key, data, &config->%s, (char*) \"\"))\n" % option.name
|
||||||
|
s += "\t\t{\n\t\t\tLOG_ERROR(\"Configuration parse error on line %d\", line_count);\n\t\t\treturn -1;\n\t\t}\n\t\treturn 0;\n\t}\n\n"
|
||||||
|
self.f.write(s)
|
||||||
|
|
||||||
|
def _write_free_impl(self, option):
|
||||||
|
if option.is_string:
|
||||||
|
self.f.write("\thub_free(config->%s);\n\n" % option.name)
|
||||||
|
|
||||||
|
def _write_dump_impl(self, option):
|
||||||
|
s = ""
|
||||||
|
fmt = "%s"
|
||||||
|
val = "config->%s" % option.name
|
||||||
|
test = "config->%s != %s" % (option.name, option.default)
|
||||||
|
|
||||||
|
if (option.otype == "int"):
|
||||||
|
fmt = "%d"
|
||||||
|
elif (option.otype == "boolean"):
|
||||||
|
val = "config->%s ? \"yes\" : \"no\"" % option.name
|
||||||
|
elif (option.is_string):
|
||||||
|
fmt = "\\\"%s\\\"";
|
||||||
|
test = "strcmp(config->%s, %s) != 0" % (option.name, option.formatted_default())
|
||||||
|
|
||||||
|
s += "\tif (!ignore_defaults || %s)\n" % test;
|
||||||
|
s += "\t\tfprintf(stdout, \"%s = %s\\n\", %s);\n\n" % (option.name, fmt, val)
|
||||||
|
self.f.write(s)
|
||||||
|
|
||||||
|
def write(self, options):
|
||||||
|
self.write_header()
|
||||||
|
self.f.write("void config_defaults(struct hub_config* config)\n{\n")
|
||||||
|
for option in options:
|
||||||
|
self._write_default_impl(option)
|
||||||
|
self.f.write("}\n\n")
|
||||||
|
self.f.write("static int apply_config(struct hub_config* config, char* key, char* data, int line_count)\n{\n\tint max = 0;\n\tint min = 0;\n\n")
|
||||||
|
for option in options:
|
||||||
|
self._write_apply_impl(option)
|
||||||
|
self.f.write("\t/* Still here -- unknown directive */\n\tLOG_ERROR(\"Unknown configuration directive: '%s'\", key);\n\treturn -1;\n}\n\n")
|
||||||
|
self.f.write("void free_config(struct hub_config* config)\n{\n")
|
||||||
|
for option in options:
|
||||||
|
self._write_free_impl(option)
|
||||||
|
self.f.write("}\n\n")
|
||||||
|
self.f.write("void dump_config(struct hub_config* config, int ignore_defaults)\n{\n")
|
||||||
|
for option in options:
|
||||||
|
self._write_dump_impl(option)
|
||||||
|
self.f.write("}\n\n")
|
||||||
|
|
||||||
|
class SqlWebsiteDocsGenerator(SourceGenerator):
|
||||||
|
def __init__(self, filename, sqlite_support = False):
|
||||||
|
self.sqlite_support = sqlite_support
|
||||||
|
super(SqlWebsiteDocsGenerator, self).__init__(filename)
|
||||||
|
|
||||||
|
def _sql_escape(self, s):
|
||||||
|
if self.sqlite_support:
|
||||||
|
return s.replace("\"", "\"\"")
|
||||||
|
return s.replace("\"", "\\\"")
|
||||||
|
|
||||||
|
|
||||||
|
def _write_or_null(self, s):
|
||||||
|
if (not s or len(s) == 0):
|
||||||
|
return "NULL"
|
||||||
|
return "\"%s\"" % self._sql_escape(s)
|
||||||
|
|
||||||
|
def write(self, options):
|
||||||
|
self.write_header(False)
|
||||||
|
table = "uhub_config"
|
||||||
|
|
||||||
|
s = ""
|
||||||
|
if not self.sqlite_support:
|
||||||
|
s += "START TRANSACTION;\n\nDROP TABLE %(table)s IF EXISTS;" % { "table": table }
|
||||||
|
s += "\n\nCREATE TABLE %(table)s (\n\tname VARCHAR(32) UNIQUE NOT NULL,\n\tdefaultValue TINYTEXT NOT NULL,\n\tdescription LONGTEXT NOT NULL,\n\ttype TINYTEXT NOT NULL,\n\tadvanced BOOLEAN,\n\texample LONGTEXT,\n\tsince TINYTEXT\n);\n\n" % { "table": table }
|
||||||
|
self.f.write(s)
|
||||||
|
|
||||||
|
for option in options:
|
||||||
|
s = "INSERT INTO %(table)s VALUES(\"%(name)s\", \"%(default)s\", \"%(description)s\", \"%(type)s\", %(example)s, %(since)s, %(advanced)s);\n" % {
|
||||||
|
"table": table,
|
||||||
|
"name": self._sql_escape(option.name),
|
||||||
|
"default": self._sql_escape(option.formatted_default()),
|
||||||
|
"description": self._sql_escape(option.description),
|
||||||
|
"type": option.sql_type(),
|
||||||
|
"example": self._write_or_null(option.example),
|
||||||
|
"since": self._write_or_null(option.since),
|
||||||
|
"advanced": self._write_or_null(option.example),
|
||||||
|
}
|
||||||
|
self.f.write(s)
|
||||||
|
|
||||||
|
if not self.sqlite_support:
|
||||||
|
self.f.write("\n\nCOMMIT;\n\n")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# parser = argparse.ArgumentParser(description = "Configuration file parser and source generator")
|
||||||
|
# parser.add_argument("--in", nargs=1, type=argparse.FileType('r'), default="config.xml", help="Input file (config.xml)", required = True)
|
||||||
|
# parser.add_argument("--c-decl", nargs=1, type=argparse.FileType('w'), default="gen_config.h", help="Output file for C declarations (gen_config.h)")
|
||||||
|
# parser.add_argument("--c-impl", nargs=1, type=argparse.FileType('w'), default="gen_config.c", help="Output file for C implementation (gen_config.c)")
|
||||||
|
# parser.add_argument("--doc-sql", nargs=1, type=argparse.FileType('w'), help="Output file for SQL documentation")
|
||||||
|
# args = parser.parse_args()
|
||||||
|
|
||||||
|
xmldoc = minidom.parse("./config.xml")
|
||||||
|
opt_tags = xmldoc.getElementsByTagName('option')
|
||||||
|
options = []
|
||||||
|
for option in opt_tags:
|
||||||
|
opt = Option(option)
|
||||||
|
options.append(opt)
|
||||||
|
|
||||||
|
header = CHeaderGenerator("./gen_config.h");
|
||||||
|
header.write(options);
|
||||||
|
|
||||||
|
source = CSourceGenerator("./gen_config.c");
|
||||||
|
source.write(options);
|
||||||
|
|
||||||
|
#sql = SqlWebsiteDocsGenerator("./gen_config.sql", True);
|
||||||
|
#sql.write(options);
|
||||||
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
|||||||
</option>
|
</option>
|
||||||
|
|
||||||
<option name="server_bind_addr" type="string" default="any">
|
<option name="server_bind_addr" type="string" default="any">
|
||||||
<check regexp="(\d\.\d\.\d\.\d\)|(any)|(loopback)|(.*)" /><!-- FIXME: add better IPv6 regexp in the future! -->
|
<check regexp="[\x:.]+|any|loopback" />
|
||||||
<short>Server bind address</short>
|
<short>Server bind address</short>
|
||||||
<description><![CDATA[
|
<description><![CDATA[
|
||||||
Specify the IP address the local hub should bind to. This can be an IPv4 or IPv6 address, or one of the special addresses "any" or "loopback". <br />
|
Specify the IP address the local hub should bind to. This can be an IPv4 or IPv6 address, or one of the special addresses "any" or "loopback". <br />
|
||||||
@ -58,7 +58,7 @@
|
|||||||
</option>
|
</option>
|
||||||
|
|
||||||
<option name="server_alt_ports" type="string" default="">
|
<option name="server_alt_ports" type="string" default="">
|
||||||
<check regexp="((\d+)(,(\d+))*)?" />
|
<check regexp="\d+(,\d+)*" />
|
||||||
<short>Comma separated list of alternative ports to listen to</short>
|
<short>Comma separated list of alternative ports to listen to</short>
|
||||||
<description><![CDATA[
|
<description><![CDATA[
|
||||||
In addition to the server_port the hub can listen to a list of alternative ports.
|
In addition to the server_port the hub can listen to a list of alternative ports.
|
||||||
@ -111,7 +111,7 @@
|
|||||||
<option name="register_self" type="boolean" default="0">
|
<option name="register_self" type="boolean" default="0">
|
||||||
<short>Allow users to register themselves on the hub.</short>
|
<short>Allow users to register themselves on the hub.</short>
|
||||||
<description><![CDATA[
|
<description><![CDATA[
|
||||||
If this is enabled guests can register their nickname on the hub.
|
If this is enabled guests can register their nickname on the hub using !register command.
|
||||||
Otherwise only operators can register users.
|
Otherwise only operators can register users.
|
||||||
]]></description>
|
]]></description>
|
||||||
<since>0.4.0</since>
|
<since>0.4.0</since>
|
||||||
@ -157,7 +157,7 @@
|
|||||||
</option>
|
</option>
|
||||||
|
|
||||||
<option name="redirect_addr" type="string" default="">
|
<option name="redirect_addr" type="string" default="">
|
||||||
<check regexp="(adc|adcs|dchub)://.*" />
|
<check regexp="(adcs?|dchub)://.*" />
|
||||||
<short>A common hub redirect address.</short>
|
<short>A common hub redirect address.</short>
|
||||||
<description><![CDATA[
|
<description><![CDATA[
|
||||||
This is the redirect address used when the hub wants to redirect a client for not fulfilling some requirements.
|
This is the redirect address used when the hub wants to redirect a client for not fulfilling some requirements.
|
||||||
@ -170,7 +170,7 @@
|
|||||||
<check min="1024" max="1048576" />
|
<check min="1024" max="1048576" />
|
||||||
<short>Max read buffer before parse, per user</short>
|
<short>Max read buffer before parse, per user</short>
|
||||||
<description><![CDATA[
|
<description><![CDATA[
|
||||||
Maximum receive buffer allowed before commands are procesed. If a single ADC message exceeds this limit, it will be discarded by the hub. Use with caution.
|
Maximum receive buffer allowed before commands are processed. If a single ADC message exceeds this limit, it will be discarded by the hub. Use with caution.
|
||||||
]]></description>
|
]]></description>
|
||||||
<since>0.1.3</since>
|
<since>0.1.3</since>
|
||||||
</option>
|
</option>
|
||||||
@ -419,7 +419,7 @@
|
|||||||
</option>
|
</option>
|
||||||
|
|
||||||
<option name="tls_require_redirect_addr" type="string" default="">
|
<option name="tls_require_redirect_addr" type="string" default="">
|
||||||
<check regexp="(adc|adcs|dchub)://.*" />
|
<check regexp="(adcs?|dchub)://.*" />
|
||||||
<short>A redirect address in case a client connects using "adc://" when "adcs://" is required.</short>
|
<short>A redirect address in case a client connects using "adc://" when "adcs://" is required.</short>
|
||||||
<description><![CDATA[
|
<description><![CDATA[
|
||||||
This is the redirect address used when the hub wants to redirect a client for not using ADCS.
|
This is the redirect address used when the hub wants to redirect a client for not using ADCS.
|
||||||
@ -428,11 +428,10 @@
|
|||||||
<since>0.3.3</since>
|
<since>0.3.3</since>
|
||||||
</option>
|
</option>
|
||||||
|
|
||||||
|
|
||||||
<option name="tls_certificate" type="file" default="">
|
<option name="tls_certificate" type="file" default="">
|
||||||
<short>Certificate file</short>
|
<short>Certificate file</short>
|
||||||
<description><![CDATA[
|
<description><![CDATA[
|
||||||
Path to a TLS/SSL certificate (PEM format).
|
Path to a TLS/SSL certificate or certificate chain (PEM format).
|
||||||
]]></description>
|
]]></description>
|
||||||
<since>0.3.0</since>
|
<since>0.3.0</since>
|
||||||
</option>
|
</option>
|
||||||
@ -445,6 +444,40 @@
|
|||||||
<since>0.3.0</since>
|
<since>0.3.0</since>
|
||||||
</option>
|
</option>
|
||||||
|
|
||||||
|
<option name="tls_ciphersuite" type="string" default="ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS">
|
||||||
|
<short>List of TLS ciphers to use</short>
|
||||||
|
<description><![CDATA[
|
||||||
|
This is a colon separated list of preferred ciphers in the OpenSSL format.
|
||||||
|
]]></description>
|
||||||
|
<since>0.5.0</since>
|
||||||
|
<example><![CDATA[
|
||||||
|
<p>
|
||||||
|
High security with emphasis on forward secrecy:<br />
|
||||||
|
tls_ciphersuite = "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS"
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Allow ChaCha20/Poly1305 which are secure, yet generally faster:<br />
|
||||||
|
tls_ciphersuite = "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA"
|
||||||
|
</p>
|
||||||
|
]]></example>
|
||||||
|
</option>
|
||||||
|
|
||||||
|
<option name="tls_version" type="string" default="1.2">
|
||||||
|
<short>Specify minimum TLS version supported.</short>
|
||||||
|
<description><![CDATA[
|
||||||
|
<p>
|
||||||
|
This allows you to specify the minimum TLS version the hub requires from connecting clients in order to
|
||||||
|
connect to the hub.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
TLS version 1.2 is recommended and enabled by default.
|
||||||
|
TLS version 1.1 is acceptable without any known flaws, and allows for older clients to connect.
|
||||||
|
TLS version 1.0 should be avoided, even though it is the most compatible with older ADC clients.
|
||||||
|
</p>
|
||||||
|
]]></description>
|
||||||
|
<since>0.5.0</since>
|
||||||
|
</option>
|
||||||
|
|
||||||
<option name="file_acl" type="file" default="">
|
<option name="file_acl" type="file" default="">
|
||||||
<short>File containing access control lists</short>
|
<short>File containing access control lists</short>
|
||||||
<description><![CDATA[
|
<description><![CDATA[
|
||||||
@ -534,7 +567,7 @@
|
|||||||
</option>
|
</option>
|
||||||
|
|
||||||
<option name="msg_inf_error_nick_taken" type="message" default="Nickname is already in use">
|
<option name="msg_inf_error_nick_taken" type="message" default="Nickname is already in use">
|
||||||
<description><![CDATA[This message will be sent to clients if their provided nickname is alredy in use on the hub.]]></description>
|
<description><![CDATA[This message will be sent to clients if their provided nickname is already in use on the hub.]]></description>
|
||||||
<since>0.2.0</since>
|
<since>0.2.0</since>
|
||||||
</option>
|
</option>
|
||||||
|
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -77,15 +77,13 @@ int event_queue_process(struct event_queue* queue)
|
|||||||
/* lock primary queue, and handle the primary queue messages. */
|
/* lock primary queue, and handle the primary queue messages. */
|
||||||
queue->locked = 1;
|
queue->locked = 1;
|
||||||
|
|
||||||
data = (struct event_data*) list_get_first(queue->q1);
|
LIST_FOREACH(struct event_data*, data, queue->q1,
|
||||||
while (data)
|
|
||||||
{
|
{
|
||||||
#ifdef EQ_DEBUG
|
#ifdef EQ_DEBUG
|
||||||
eq_debug("EXEC", data);
|
eq_debug("EXEC", data);
|
||||||
#endif
|
#endif
|
||||||
queue->callback(queue->callback_data, data);
|
queue->callback(queue->callback_data, data);
|
||||||
data = (struct event_data*) list_get_next(queue->q1);
|
});
|
||||||
}
|
|
||||||
|
|
||||||
list_clear(queue->q1, event_queue_cleanup_callback);
|
list_clear(queue->q1, event_queue_cleanup_callback);
|
||||||
uhub_assert(list_size(queue->q1) == 0);
|
uhub_assert(list_size(queue->q1) == 0);
|
||||||
@ -94,13 +92,7 @@ int event_queue_process(struct event_queue* queue)
|
|||||||
queue->locked = 0;
|
queue->locked = 0;
|
||||||
|
|
||||||
/* transfer from secondary queue to the primary queue. */
|
/* transfer from secondary queue to the primary queue. */
|
||||||
data = (struct event_data*) list_get_first(queue->q2);
|
list_append_list(queue->q1, queue->q2);
|
||||||
while (data)
|
|
||||||
{
|
|
||||||
list_remove(queue->q2, data);
|
|
||||||
list_append(queue->q1, data);
|
|
||||||
data = (struct event_data*) list_get_first(queue->q2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if more events exist, schedule it */
|
/* if more events exist, schedule it */
|
||||||
if (list_size(queue->q1))
|
if (list_size(queue->q1))
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1,4 +1,10 @@
|
|||||||
/* THIS FILE IS AUTOGENERATED - DO NOT CHANGE IT! */
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2014, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* THIS FILE IS AUTOGENERATED - DO NOT MODIFY
|
||||||
|
* Created 2014-07-29 12:22, by config.py
|
||||||
|
*/
|
||||||
|
|
||||||
void config_defaults(struct hub_config* config)
|
void config_defaults(struct hub_config* config)
|
||||||
{
|
{
|
||||||
@ -45,6 +51,8 @@ void config_defaults(struct hub_config* config)
|
|||||||
config->tls_require_redirect_addr = hub_strdup("");
|
config->tls_require_redirect_addr = hub_strdup("");
|
||||||
config->tls_certificate = hub_strdup("");
|
config->tls_certificate = hub_strdup("");
|
||||||
config->tls_private_key = hub_strdup("");
|
config->tls_private_key = hub_strdup("");
|
||||||
|
config->tls_ciphersuite = hub_strdup("ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS");
|
||||||
|
config->tls_version = hub_strdup("1.2");
|
||||||
config->file_acl = hub_strdup("");
|
config->file_acl = hub_strdup("");
|
||||||
config->file_plugins = hub_strdup("");
|
config->file_plugins = hub_strdup("");
|
||||||
config->msg_hub_full = hub_strdup("Hub is full");
|
config->msg_hub_full = hub_strdup("Hub is full");
|
||||||
@ -546,6 +554,26 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strcmp(key, "tls_ciphersuite"))
|
||||||
|
{
|
||||||
|
if (!apply_string(key, data, &config->tls_ciphersuite, (char*) ""))
|
||||||
|
{
|
||||||
|
LOG_ERROR("Configuration parse error on line %d", line_count);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(key, "tls_version"))
|
||||||
|
{
|
||||||
|
if (!apply_string(key, data, &config->tls_version, (char*) ""))
|
||||||
|
{
|
||||||
|
LOG_ERROR("Configuration parse error on line %d", line_count);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!strcmp(key, "file_acl"))
|
if (!strcmp(key, "file_acl"))
|
||||||
{
|
{
|
||||||
if (!apply_string(key, data, &config->file_acl, (char*) ""))
|
if (!apply_string(key, data, &config->file_acl, (char*) ""))
|
||||||
@ -949,6 +977,10 @@ void free_config(struct hub_config* config)
|
|||||||
|
|
||||||
hub_free(config->tls_private_key);
|
hub_free(config->tls_private_key);
|
||||||
|
|
||||||
|
hub_free(config->tls_ciphersuite);
|
||||||
|
|
||||||
|
hub_free(config->tls_version);
|
||||||
|
|
||||||
hub_free(config->file_acl);
|
hub_free(config->file_acl);
|
||||||
|
|
||||||
hub_free(config->file_plugins);
|
hub_free(config->file_plugins);
|
||||||
@ -1158,6 +1190,12 @@ void dump_config(struct hub_config* config, int ignore_defaults)
|
|||||||
if (!ignore_defaults || strcmp(config->tls_private_key, "") != 0)
|
if (!ignore_defaults || strcmp(config->tls_private_key, "") != 0)
|
||||||
fprintf(stdout, "tls_private_key = \"%s\"\n", config->tls_private_key);
|
fprintf(stdout, "tls_private_key = \"%s\"\n", config->tls_private_key);
|
||||||
|
|
||||||
|
if (!ignore_defaults || strcmp(config->tls_ciphersuite, "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS") != 0)
|
||||||
|
fprintf(stdout, "tls_ciphersuite = \"%s\"\n", config->tls_ciphersuite);
|
||||||
|
|
||||||
|
if (!ignore_defaults || strcmp(config->tls_version, "1.2") != 0)
|
||||||
|
fprintf(stdout, "tls_version = \"%s\"\n", config->tls_version);
|
||||||
|
|
||||||
if (!ignore_defaults || strcmp(config->file_acl, "") != 0)
|
if (!ignore_defaults || strcmp(config->file_acl, "") != 0)
|
||||||
fprintf(stdout, "file_acl = \"%s\"\n", config->file_acl);
|
fprintf(stdout, "file_acl = \"%s\"\n", config->file_acl);
|
||||||
|
|
||||||
|
@ -1,4 +1,10 @@
|
|||||||
/* THIS FILE IS AUTOGENERATED - DO NOT CHANGE IT! */
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2014, Jan Vidar Krey
|
||||||
|
*
|
||||||
|
* THIS FILE IS AUTOGENERATED - DO NOT MODIFY
|
||||||
|
* Created 2014-07-29 12:22, by config.py
|
||||||
|
*/
|
||||||
|
|
||||||
struct hub_config
|
struct hub_config
|
||||||
{
|
{
|
||||||
@ -45,6 +51,8 @@ struct hub_config
|
|||||||
char* tls_require_redirect_addr; /*<<< A redirect address in case a client connects using "adc://" when "adcs://" is required. (default: "") */
|
char* tls_require_redirect_addr; /*<<< A redirect address in case a client connects using "adc://" when "adcs://" is required. (default: "") */
|
||||||
char* tls_certificate; /*<<< Certificate file (default: "") */
|
char* tls_certificate; /*<<< Certificate file (default: "") */
|
||||||
char* tls_private_key; /*<<< Private key file (default: "") */
|
char* tls_private_key; /*<<< Private key file (default: "") */
|
||||||
|
char* tls_ciphersuite; /*<<< List of TLS ciphers to use (default: "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS") */
|
||||||
|
char* tls_version; /*<<< Specify minimum TLS version supported. (default: "1.2") */
|
||||||
char* file_acl; /*<<< File containing access control lists (default: "") */
|
char* file_acl; /*<<< File containing access control lists (default: "") */
|
||||||
char* file_plugins; /*<<< Plugin configuration file (default: "") */
|
char* file_plugins; /*<<< Plugin configuration file (default: "") */
|
||||||
char* msg_hub_full; /*<<< "Hub is full" */
|
char* msg_hub_full; /*<<< "Hub is full" */
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2012, Jan Vidar Krey
|
* Copyright (C) 2007-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ struct hub_info* g_hub = 0;
|
|||||||
|
|
||||||
/* FIXME: Flood control should be done in a plugin! */
|
/* FIXME: Flood control should be done in a plugin! */
|
||||||
#define CHECK_FLOOD(TYPE, WARN) \
|
#define CHECK_FLOOD(TYPE, WARN) \
|
||||||
if (flood_control_check(&u->flood_ ## TYPE , hub->config->flood_ctl_ ## TYPE, hub->config->flood_ctl_interval, net_get_time())) \
|
if (flood_control_check(&u->flood_ ## TYPE , hub->config->flood_ctl_ ## TYPE, hub->config->flood_ctl_interval, net_get_time()) && !auth_cred_is_unrestricted(u->credentials)) \
|
||||||
{ \
|
{ \
|
||||||
if (WARN) \
|
if (WARN) \
|
||||||
{ \
|
{ \
|
||||||
@ -731,7 +731,11 @@ static int load_ssl_certificates(struct hub_info* hub, struct hub_config* config
|
|||||||
{
|
{
|
||||||
if (config->tls_enable)
|
if (config->tls_enable)
|
||||||
{
|
{
|
||||||
hub->ctx = net_ssl_context_create();
|
hub->ctx = net_ssl_context_create(config->tls_version, config->tls_ciphersuite);
|
||||||
|
|
||||||
|
if (!hub->ctx)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (ssl_load_certificate(hub->ctx, config->tls_certificate) &&
|
if (ssl_load_certificate(hub->ctx, config->tls_certificate) &&
|
||||||
ssl_load_private_key(hub->ctx, config->tls_private_key) &&
|
ssl_load_private_key(hub->ctx, config->tls_private_key) &&
|
||||||
ssl_check_private_key(hub->ctx))
|
ssl_check_private_key(hub->ctx))
|
||||||
@ -905,7 +909,8 @@ void hub_set_variables(struct hub_info* hub, struct acl_handle* acl)
|
|||||||
if (hub->command_info)
|
if (hub->command_info)
|
||||||
{
|
{
|
||||||
adc_msg_add_named_argument(hub->command_info, ADC_INF_FLAG_CLIENT_TYPE, ADC_CLIENT_TYPE_HUB);
|
adc_msg_add_named_argument(hub->command_info, ADC_INF_FLAG_CLIENT_TYPE, ADC_CLIENT_TYPE_HUB);
|
||||||
adc_msg_add_named_argument(hub->command_info, ADC_INF_FLAG_USER_AGENT, server);
|
adc_msg_add_named_argument(hub->command_info, ADC_INF_FLAG_USER_AGENT_PRODUCT, PRODUCT);
|
||||||
|
adc_msg_add_named_argument(hub->command_info, ADC_INF_FLAG_USER_AGENT_VERSION, GIT_VERSION);
|
||||||
|
|
||||||
tmp = adc_msg_escape(hub->config->hub_name);
|
tmp = adc_msg_escape(hub->config->hub_name);
|
||||||
adc_msg_add_named_argument(hub->command_info, ADC_INF_FLAG_NICK, tmp);
|
adc_msg_add_named_argument(hub->command_info, ADC_INF_FLAG_NICK, tmp);
|
||||||
@ -1320,9 +1325,7 @@ void hub_logout_log(struct hub_info* hub, struct hub_user* user)
|
|||||||
list_append(hub->logout_info, loginfo);
|
list_append(hub->logout_info, loginfo);
|
||||||
while (list_size(hub->logout_info) > (size_t) hub->config->max_logout_log)
|
while (list_size(hub->logout_info) > (size_t) hub->config->max_logout_log)
|
||||||
{
|
{
|
||||||
struct hub_logout_info* entry = list_get_first(hub->logout_info);
|
list_remove_first(hub->logout_info, hub_free);
|
||||||
list_remove(hub->logout_info, entry);
|
|
||||||
hub_free(entry);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2012, Jan Vidar Krey
|
* Copyright (C) 2007-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ enum status_message
|
|||||||
status_msg_hub_registered_users_only = -3, /* hub is for registered users only */
|
status_msg_hub_registered_users_only = -3, /* hub is for registered users only */
|
||||||
status_msg_inf_error_nick_missing = -4, /* no nickname given */
|
status_msg_inf_error_nick_missing = -4, /* no nickname given */
|
||||||
status_msg_inf_error_nick_multiple = -5, /* multiple nicknames given */
|
status_msg_inf_error_nick_multiple = -5, /* multiple nicknames given */
|
||||||
status_msg_inf_error_nick_invalid = -6, /* generic/unkown */
|
status_msg_inf_error_nick_invalid = -6, /* generic/unknown */
|
||||||
status_msg_inf_error_nick_long = -7, /* nickname too long */
|
status_msg_inf_error_nick_long = -7, /* nickname too long */
|
||||||
status_msg_inf_error_nick_short = -8, /* nickname too short */
|
status_msg_inf_error_nick_short = -8, /* nickname too short */
|
||||||
status_msg_inf_error_nick_spaces = -9, /* nickname cannot start with spaces */
|
status_msg_inf_error_nick_spaces = -9, /* nickname cannot start with spaces */
|
||||||
@ -50,8 +50,8 @@ enum status_message
|
|||||||
status_msg_user_share_size_high = -41, /* User is sharing too much. */
|
status_msg_user_share_size_high = -41, /* User is sharing too much. */
|
||||||
status_msg_user_slots_low = -42, /* User has too few slots open. */
|
status_msg_user_slots_low = -42, /* User has too few slots open. */
|
||||||
status_msg_user_slots_high = -43, /* User has too many slots open. */
|
status_msg_user_slots_high = -43, /* User has too many slots open. */
|
||||||
status_msg_user_hub_limit_low = -44, /* Use is on too few hubs. */
|
status_msg_user_hub_limit_low = -44, /* User is on too few hubs. */
|
||||||
status_msg_user_hub_limit_high = -45, /* Use is on too many hubs. */
|
status_msg_user_hub_limit_high = -45, /* User is on too many hubs. */
|
||||||
|
|
||||||
status_msg_proto_no_common_hash = -50, /* No common hash algorithms */
|
status_msg_proto_no_common_hash = -50, /* No common hash algorithms */
|
||||||
status_msg_proto_obsolete_adc0 = -51, /* Client is using an obsolete protocol version */
|
status_msg_proto_obsolete_adc0 = -51, /* Client is using an obsolete protocol version */
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ static int check_hash_tiger(const char* cid, const char* pid)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME: Only works for tiger hash. If a client doesnt support tiger we cannot let it in!
|
* FIXME: Only works for tiger hash. If a client doesn't support tiger we cannot let it in!
|
||||||
*/
|
*/
|
||||||
static int check_cid(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
|
static int check_cid(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
|
||||||
{
|
{
|
||||||
@ -337,9 +337,19 @@ static int check_logged_in(struct hub_info* hub, struct hub_user* user, struct a
|
|||||||
{
|
{
|
||||||
if (lookup1 == lookup2)
|
if (lookup1 == lookup2)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("check_logged_in: exact same user is logged in: %s", user->id.nick);
|
if (user_flag_get(lookup1, flag_choke))
|
||||||
|
{
|
||||||
|
LOG_DEBUG("check_logged_in: exact same user is already logged in, but likely ghost: %s", user->id.nick);
|
||||||
|
|
||||||
|
// Old user unable to swallow data.
|
||||||
|
// Disconnect the existing user, and allow new user to enter.
|
||||||
hub_disconnect_user(hub, lookup1, quit_ghost_timeout);
|
hub_disconnect_user(hub, lookup1, quit_ghost_timeout);
|
||||||
return 0;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_DEBUG("check_logged_in: exact same user is already logged in: %s", user->id.nick);
|
||||||
|
return status_msg_inf_error_cid_taken;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -366,21 +376,37 @@ static int check_logged_in(struct hub_info* hub, struct hub_user* user, struct a
|
|||||||
*/
|
*/
|
||||||
static int check_user_agent(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
|
static int check_user_agent(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
|
||||||
{
|
{
|
||||||
char* ua_encoded = 0;
|
char* ua_name_encoded = 0;
|
||||||
char* ua = 0;
|
char* ua_version_encoded = 0;
|
||||||
|
char* str = 0;
|
||||||
|
size_t offset = 0;
|
||||||
|
|
||||||
/* Get client user agent version */
|
/* Get client user agent version */
|
||||||
ua_encoded = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_USER_AGENT);
|
ua_name_encoded = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_USER_AGENT_PRODUCT);
|
||||||
if (ua_encoded)
|
ua_version_encoded = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_USER_AGENT_VERSION);
|
||||||
|
if (ua_name_encoded)
|
||||||
{
|
{
|
||||||
ua = adc_msg_unescape(ua_encoded);
|
str = adc_msg_unescape(ua_name_encoded);
|
||||||
if (ua)
|
if (str)
|
||||||
{
|
{
|
||||||
memcpy(user->id.user_agent, ua, MIN(strlen(ua), MAX_UA_LEN));
|
offset = strlen(str);
|
||||||
hub_free(ua);
|
memcpy(user->id.user_agent, str, MIN(offset, MAX_UA_LEN));
|
||||||
|
hub_free(str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hub_free(ua_encoded);
|
|
||||||
|
if (ua_version_encoded)
|
||||||
|
{
|
||||||
|
str = adc_msg_unescape(ua_version_encoded);
|
||||||
|
if (str)
|
||||||
|
{
|
||||||
|
memcpy(user->id.user_agent + offset, str, MIN(strlen(str), MAX_UA_LEN - offset));
|
||||||
|
hub_free(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hub_free(ua_name_encoded);
|
||||||
|
hub_free(ua_version_encoded);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -555,6 +581,10 @@ static int set_credentials(struct hub_info* hub, struct hub_user* user, struct a
|
|||||||
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_BOT);
|
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_BOT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case auth_cred_ubot:
|
||||||
|
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_BOT);
|
||||||
|
break;
|
||||||
|
|
||||||
case auth_cred_guest:
|
case auth_cred_guest:
|
||||||
/* Nothing to be added to the info message */
|
/* Nothing to be added to the info message */
|
||||||
break;
|
break;
|
||||||
@ -567,6 +597,14 @@ static int set_credentials(struct hub_info* hub, struct hub_user* user, struct a
|
|||||||
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_OPERATOR);
|
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_OPERATOR);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case auth_cred_opbot:
|
||||||
|
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_HUBBOT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case auth_cred_opubot:
|
||||||
|
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_HUBBOT);
|
||||||
|
break;
|
||||||
|
|
||||||
case auth_cred_super:
|
case auth_cred_super:
|
||||||
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_SUPER_USER);
|
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_SUPER_USER);
|
||||||
break;
|
break;
|
||||||
@ -622,7 +660,8 @@ static int hub_handle_info_low_bandwidth(struct hub_info* hub, struct hub_user*
|
|||||||
{
|
{
|
||||||
if (hub->config->low_bandwidth_mode)
|
if (hub->config->low_bandwidth_mode)
|
||||||
{
|
{
|
||||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_USER_AGENT);
|
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_USER_AGENT_VERSION);
|
||||||
|
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_USER_AGENT_PRODUCT);
|
||||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_SHARED_FILES);
|
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_SHARED_FILES);
|
||||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_NORMAL);
|
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_NORMAL);
|
||||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_REGISTER);
|
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_REGISTER);
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2012, Jan Vidar Krey
|
* Copyright (C) 2007-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -130,7 +130,7 @@ void ioq_send_add(struct ioq_send* q, struct adc_message* msg_)
|
|||||||
q->size += msg->length;
|
q->size += msg->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ioq_send_remove(struct ioq_send* q, struct adc_message* msg)
|
static void ioq_send_remove(struct ioq_send* q, struct adc_message* msg)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_SENDQ
|
#ifdef DEBUG_SENDQ
|
||||||
debug_msg("ioq_send_remove", msg);
|
debug_msg("ioq_send_remove", msg);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2012, Jan Vidar Krey
|
* Copyright (C) 2007-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,12 +13,16 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "uhub.h"
|
#include "uhub.h"
|
||||||
|
|
||||||
|
#ifdef SYSTEMD
|
||||||
|
#include <systemd/sd-daemon.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
static int arg_verbose = 5;
|
static int arg_verbose = 5;
|
||||||
static int arg_fork = 0;
|
static int arg_fork = 0;
|
||||||
static int arg_check_config = 0;
|
static int arg_check_config = 0;
|
||||||
@ -136,10 +140,25 @@ 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
|
#ifdef SYSTEMD
|
||||||
|
/* Notify the service manager that this daemon has
|
||||||
|
* been successfully initialized and shall enter the
|
||||||
|
* main loop.
|
||||||
|
*/
|
||||||
|
sd_notifyf(0, "READY=1\n"
|
||||||
|
"MAINPID=%lu", (unsigned long) getpid());
|
||||||
|
#endif /* SYSTEMD */
|
||||||
|
|
||||||
|
#endif /* ! WIN32 */
|
||||||
}
|
}
|
||||||
|
|
||||||
hub_set_variables(hub, &acl);
|
hub_set_variables(hub, &acl);
|
||||||
@ -210,13 +229,17 @@ void print_usage(char* program)
|
|||||||
" -q Quiet mode - no output\n"
|
" -q Quiet mode - no output\n"
|
||||||
" -f Fork to background\n"
|
" -f Fork to background\n"
|
||||||
" -l <file> Log messages to given file (default: stderr)\n"
|
" -l <file> Log messages to given file (default: stderr)\n"
|
||||||
" -L Log messages to syslog\n"
|
|
||||||
" -c <file> Specify configuration file (default: " SERVER_CONFIG ")\n"
|
" -c <file> Specify configuration file (default: " SERVER_CONFIG ")\n"
|
||||||
" -C Check configuration and return\n"
|
" -C Check configuration and return\n"
|
||||||
" -s Show configuration parameters\n"
|
" -s Show configuration parameters\n"
|
||||||
" -S Show configuration parameters, but ignore defaults\n"
|
" -S Show configuration parameters, but ignore defaults\n"
|
||||||
" -h This message\n"
|
" -h This message\n"
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
|
#ifdef SYSTEMD
|
||||||
|
" -L Log messages to journal\n"
|
||||||
|
#else
|
||||||
|
" -L Log messages to syslog\n"
|
||||||
|
#endif
|
||||||
" -u <user> Run as given user\n"
|
" -u <user> Run as given user\n"
|
||||||
" -g <group> Run with given group permissions\n"
|
" -g <group> Run with given group permissions\n"
|
||||||
" -p <file> Store pid in file (process id)\n"
|
" -p <file> Store pid in file (process id)\n"
|
||||||
@ -448,7 +471,7 @@ int main(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
else if (ret == 0)
|
else if (ret == 0)
|
||||||
{
|
{
|
||||||
/* child process - detatch from TTY */
|
/* child process - detach from TTY */
|
||||||
fclose(stdin);
|
fclose(stdin);
|
||||||
fclose(stdout);
|
fclose(stdout);
|
||||||
fclose(stderr);
|
fclose(stderr);
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -137,6 +137,12 @@ void net_event(struct net_connection* con, int event, void *arg)
|
|||||||
LOG_TRACE("net_event() : fd=%d, ev=%d, arg=%p", con->sd, (int) event, arg);
|
LOG_TRACE("net_event() : fd=%d, ev=%d, arg=%p", con->sd, (int) event, arg);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (event == NET_EVENT_ERROR)
|
||||||
|
{
|
||||||
|
hub_disconnect_user(user->hub, user, quit_socket_error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (event == NET_EVENT_TIMEOUT)
|
if (event == NET_EVENT_TIMEOUT)
|
||||||
{
|
{
|
||||||
if (user_is_connecting(user))
|
if (user_is_connecting(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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -40,14 +40,11 @@ static int plugin_command_dispatch(struct command_base* cbase, struct hub_user*
|
|||||||
|
|
||||||
LOG_PLUGIN("plugin_command_dispatch: cmd=%s", cmd->prefix);
|
LOG_PLUGIN("plugin_command_dispatch: cmd=%s", cmd->prefix);
|
||||||
|
|
||||||
cmdh = (struct plugin_command_handle*) list_get_first(data->commands);
|
LIST_FOREACH(struct plugin_command_handle*, cmdh, data->commands,
|
||||||
while (cmdh)
|
|
||||||
{
|
{
|
||||||
if (strcmp(cmdh->prefix, cmd->prefix) == 0)
|
if (strcmp(cmdh->prefix, cmd->prefix) == 0)
|
||||||
return cmdh->handler(plugin, puser, pcommand);
|
return cmdh->handler(plugin, puser, pcommand);
|
||||||
|
});
|
||||||
cmdh = (struct plugin_command_handle*) list_get_next(data->commands);
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,6 +65,17 @@ static int cbfunc_send_message(struct plugin_handle* plugin, struct plugin_user*
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cbfunc_send_broadcast(struct plugin_handle* plugin, const char* message)
|
||||||
|
{
|
||||||
|
char* buffer = adc_msg_escape(message);
|
||||||
|
struct adc_message* command = adc_msg_construct(ADC_CMD_IMSG, strlen(buffer) + 6);
|
||||||
|
adc_msg_add_argument(command, buffer);
|
||||||
|
route_to_all(plugin_get_hub(plugin), command);
|
||||||
|
adc_msg_free(command);
|
||||||
|
hub_free(buffer);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int cbfunc_send_status(struct plugin_handle* plugin, struct plugin_user* user, int code, const char* message)
|
static int cbfunc_send_status(struct plugin_handle* plugin, struct plugin_user* user, int code, const char* message)
|
||||||
{
|
{
|
||||||
char code_str[4];
|
char code_str[4];
|
||||||
@ -104,7 +112,6 @@ static int cbfunc_command_add(struct plugin_handle* plugin, struct plugin_comman
|
|||||||
cmdh->internal_handle = command;
|
cmdh->internal_handle = command;
|
||||||
list_append(data->commands, cmdh);
|
list_append(data->commands, cmdh);
|
||||||
command_add(plugin_get_hub(plugin)->commands, command, (void*) plugin);
|
command_add(plugin_get_hub(plugin)->commands, command, (void*) plugin);
|
||||||
printf("*** Add plugin command: %s (%p, %p)\n", command->prefix, command, cmdh);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +120,6 @@ static int cbfunc_command_del(struct plugin_handle* plugin, struct plugin_comman
|
|||||||
struct plugin_callback_data* data = get_callback_data(plugin);
|
struct plugin_callback_data* data = get_callback_data(plugin);
|
||||||
struct command_handle* command = (struct command_handle*) cmdh->internal_handle;
|
struct command_handle* command = (struct command_handle*) cmdh->internal_handle;
|
||||||
|
|
||||||
printf("*** Del plugin command: %s (%p, %p)\n", command->prefix, command, cmdh);
|
|
||||||
list_remove(data->commands, cmdh);
|
list_remove(data->commands, cmdh);
|
||||||
command_del(plugin_get_hub(plugin)->commands, command);
|
command_del(plugin_get_hub(plugin)->commands, command);
|
||||||
hub_free(command);
|
hub_free(command);
|
||||||
@ -133,6 +139,12 @@ struct plugin_command_arg_data* cbfunc_command_arg_next(struct plugin_handle* pl
|
|||||||
return (struct plugin_command_arg_data*) hub_command_arg_next((struct hub_command*) cmd, (enum hub_command_arg_type) t);
|
return (struct plugin_command_arg_data*) hub_command_arg_next((struct hub_command*) cmd, (enum hub_command_arg_type) t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t cbfunc_get_usercount(struct plugin_handle* plugin)
|
||||||
|
{
|
||||||
|
struct hub_info* hub = plugin_get_hub(plugin);
|
||||||
|
return hub->users->count;
|
||||||
|
}
|
||||||
|
|
||||||
static char* cbfunc_get_hub_name(struct plugin_handle* plugin)
|
static char* cbfunc_get_hub_name(struct plugin_handle* plugin)
|
||||||
{
|
{
|
||||||
struct hub_info* hub = plugin_get_hub(plugin);
|
struct hub_info* hub = plugin_get_hub(plugin);
|
||||||
@ -188,12 +200,14 @@ static void cbfunc_set_hub_description(struct plugin_handle* plugin, const char*
|
|||||||
void plugin_register_callback_functions(struct plugin_handle* handle)
|
void plugin_register_callback_functions(struct plugin_handle* handle)
|
||||||
{
|
{
|
||||||
handle->hub.send_message = cbfunc_send_message;
|
handle->hub.send_message = cbfunc_send_message;
|
||||||
|
handle->hub.send_broadcast_message = cbfunc_send_broadcast;
|
||||||
handle->hub.send_status_message = cbfunc_send_status;
|
handle->hub.send_status_message = cbfunc_send_status;
|
||||||
handle->hub.user_disconnect = cbfunc_user_disconnect;
|
handle->hub.user_disconnect = cbfunc_user_disconnect;
|
||||||
handle->hub.command_add = cbfunc_command_add;
|
handle->hub.command_add = cbfunc_command_add;
|
||||||
handle->hub.command_del = cbfunc_command_del;
|
handle->hub.command_del = cbfunc_command_del;
|
||||||
handle->hub.command_arg_reset = cbfunc_command_arg_reset;
|
handle->hub.command_arg_reset = cbfunc_command_arg_reset;
|
||||||
handle->hub.command_arg_next = cbfunc_command_arg_next;
|
handle->hub.command_arg_next = cbfunc_command_arg_next;
|
||||||
|
handle->hub.get_usercount = cbfunc_get_usercount;
|
||||||
handle->hub.get_name = cbfunc_get_hub_name;
|
handle->hub.get_name = cbfunc_get_hub_name;
|
||||||
handle->hub.set_name = cbfunc_set_hub_name;
|
handle->hub.set_name = cbfunc_set_hub_name;
|
||||||
handle->hub.get_description = cbfunc_get_hub_description;
|
handle->hub.get_description = cbfunc_get_hub_description;
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -27,13 +27,12 @@
|
|||||||
PLUGIN_DEBUG(HUB, # FUNCNAME) \
|
PLUGIN_DEBUG(HUB, # FUNCNAME) \
|
||||||
if (HUB->plugins && HUB->plugins->loaded) \
|
if (HUB->plugins && HUB->plugins->loaded) \
|
||||||
{ \
|
{ \
|
||||||
struct plugin_handle* plugin = (struct plugin_handle*) list_get_first(HUB->plugins->loaded); \
|
struct plugin_handle* plugin;\
|
||||||
while (plugin) \
|
LIST_FOREACH(struct plugin_handle*, plugin, HUB->plugins->loaded, \
|
||||||
{ \
|
{ \
|
||||||
if (plugin->funcs.FUNCNAME) \
|
if (plugin->funcs.FUNCNAME) \
|
||||||
CODE \
|
CODE \
|
||||||
plugin = (struct plugin_handle*) list_get_next(HUB->plugins->loaded); \
|
}); \
|
||||||
} \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PLUGIN_INVOKE_STATUS_1(HUB, FUNCNAME, ARG1) \
|
#define PLUGIN_INVOKE_STATUS_1(HUB, FUNCNAME, ARG1) \
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -102,7 +102,6 @@ struct plugin_handle* plugin_load(const char* filename, const char* config, stru
|
|||||||
int ret;
|
int ret;
|
||||||
struct plugin_handle* handle = (struct plugin_handle*) hub_malloc_zero(sizeof(struct plugin_handle));
|
struct plugin_handle* handle = (struct plugin_handle*) hub_malloc_zero(sizeof(struct plugin_handle));
|
||||||
struct uhub_plugin* plugin = plugin_open(filename);
|
struct uhub_plugin* plugin = plugin_open(filename);
|
||||||
struct plugin_hub_internals* internals = (struct plugin_hub_internals*) plugin->internals;
|
|
||||||
|
|
||||||
if (!plugin)
|
if (!plugin)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -118,6 +117,7 @@ struct plugin_handle* plugin_load(const char* filename, const char* config, stru
|
|||||||
unregister_f = plugin_lookup_symbol(plugin, "plugin_unregister");
|
unregister_f = plugin_lookup_symbol(plugin, "plugin_unregister");
|
||||||
|
|
||||||
// register hub internals
|
// register hub internals
|
||||||
|
struct plugin_hub_internals* internals = (struct plugin_hub_internals*) plugin->internals;
|
||||||
internals->unregister = unregister_f;
|
internals->unregister = unregister_f;
|
||||||
internals->hub = hub;
|
internals->hub = hub;
|
||||||
internals->callback_data = plugin_callback_data_create();
|
internals->callback_data = plugin_callback_data_create();
|
||||||
@ -229,16 +229,16 @@ int plugin_initialize(struct hub_config* config, struct hub_info* hub)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void plugin_unload_ptr(void* ptr)
|
||||||
|
{
|
||||||
|
struct plugin_handle* plugin = (struct plugin_handle*) ptr;
|
||||||
|
plugin_unload(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void plugin_shutdown(struct uhub_plugins* handle)
|
void plugin_shutdown(struct uhub_plugins* handle)
|
||||||
{
|
{
|
||||||
struct plugin_handle* plugin = (struct plugin_handle*) list_get_first(handle->loaded);
|
list_clear(handle->loaded, plugin_unload_ptr);
|
||||||
while (plugin)
|
|
||||||
{
|
|
||||||
list_remove(handle->loaded, plugin);
|
|
||||||
plugin_unload(plugin);
|
|
||||||
plugin = (struct plugin_handle*) list_get_first(handle->loaded);
|
|
||||||
}
|
|
||||||
|
|
||||||
list_destroy(handle->loaded);
|
list_destroy(handle->loaded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -71,6 +71,15 @@ static void probe_net_event(struct net_connection* con, int events, void *arg)
|
|||||||
probe_destroy(probe);
|
probe_destroy(probe);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if ((memcmp(probe_recvbuf, "GET ", 4) == 0) ||
|
||||||
|
(memcmp(probe_recvbuf, "POST", 4) == 0) ||
|
||||||
|
(memcmp(probe_recvbuf, "HEAD", 4) == 0))
|
||||||
|
{
|
||||||
|
/* Looks like HTTP - Not supported, but we log it. */
|
||||||
|
LOG_TRACE("Probed HTTP connection. Not supported closing connection (%s)", ip_convert_to_string(&probe->addr));
|
||||||
|
const char* buf = "501 Not implemented\r\n\r\n";
|
||||||
|
net_con_send(con, buf, strlen(buf));
|
||||||
|
}
|
||||||
#ifdef SSL_SUPPORT
|
#ifdef SSL_SUPPORT
|
||||||
else if (bytes >= 11 &&
|
else if (bytes >= 11 &&
|
||||||
probe_recvbuf[0] == 22 &&
|
probe_recvbuf[0] == 22 &&
|
||||||
@ -81,11 +90,14 @@ static void probe_net_event(struct net_connection* con, int events, void *arg)
|
|||||||
if (probe->hub->config->tls_enable)
|
if (probe->hub->config->tls_enable)
|
||||||
{
|
{
|
||||||
LOG_TRACE("Probed TLS %d.%d connection", (int) probe_recvbuf[9], (int) probe_recvbuf[10]);
|
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 (net_con_ssl_handshake(con, net_con_ssl_mode_server, probe->hub->ctx) < 0)
|
||||||
|
{
|
||||||
|
LOG_TRACE("TLS handshake negotiation failed.");
|
||||||
|
}
|
||||||
|
else 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->ctx);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -82,16 +82,19 @@ static int check_send_queue(struct hub_info* hub, struct hub_user* user, struct
|
|||||||
|
|
||||||
if ((user->send_queue->size + msg->length) > get_max_send_queue(hub))
|
if ((user->send_queue->size + msg->length) > get_max_send_queue(hub))
|
||||||
{
|
{
|
||||||
|
user_flag_set(user, flag_choke);
|
||||||
LOG_WARN("send queue overflowed, message discarded.");
|
LOG_WARN("send queue overflowed, message discarded.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user->send_queue->size > get_max_send_queue_soft(hub))
|
if (user->send_queue->size > get_max_send_queue_soft(hub))
|
||||||
{
|
{
|
||||||
|
user_flag_set(user, flag_choke);
|
||||||
LOG_WARN("send queue soft overflowed.");
|
LOG_WARN("send queue soft overflowed.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
user_flag_unset(user, flag_choke);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,12 +142,11 @@ int route_flush_pipeline(struct hub_info* hub, struct hub_user* u)
|
|||||||
|
|
||||||
int route_to_all(struct hub_info* hub, struct adc_message* command) /* iterate users */
|
int route_to_all(struct hub_info* hub, struct adc_message* command) /* iterate users */
|
||||||
{
|
{
|
||||||
struct hub_user* user = (struct hub_user*) list_get_first(hub->users->list);
|
struct hub_user* user;
|
||||||
while (user)
|
LIST_FOREACH(struct hub_user*, user, hub->users->list,
|
||||||
{
|
{
|
||||||
route_to_user(hub, user, command);
|
route_to_user(hub, user, command);
|
||||||
user = (struct hub_user*) list_get_next(hub->users->list);
|
});
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -154,47 +156,38 @@ int route_to_subscribers(struct hub_info* hub, struct adc_message* command) /* i
|
|||||||
int do_send;
|
int do_send;
|
||||||
char* tmp;
|
char* tmp;
|
||||||
|
|
||||||
struct hub_user* user = (struct hub_user*) list_get_first(hub->users->list);
|
struct hub_user* user;
|
||||||
while (user)
|
LIST_FOREACH(struct hub_user*, user, hub->users->list,
|
||||||
{
|
{
|
||||||
if (user->feature_cast)
|
if (user->feature_cast)
|
||||||
{
|
{
|
||||||
do_send = 1;
|
do_send = 1;
|
||||||
|
|
||||||
tmp = list_get_first(command->feature_cast_include);
|
LIST_FOREACH(char*, tmp, command->feature_cast_include,
|
||||||
while (tmp)
|
|
||||||
{
|
{
|
||||||
if (!user_have_feature_cast_support(user, tmp))
|
if (!user_have_feature_cast_support(user, tmp))
|
||||||
{
|
{
|
||||||
do_send = 0;
|
do_send = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tmp = list_get_next(command->feature_cast_include);;
|
});
|
||||||
}
|
|
||||||
|
|
||||||
if (!do_send) {
|
if (!do_send)
|
||||||
user = (struct hub_user*) list_get_next(hub->users->list);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
tmp = list_get_first(command->feature_cast_exclude);
|
LIST_FOREACH(char*, tmp, command->feature_cast_exclude,
|
||||||
while (tmp)
|
|
||||||
{
|
{
|
||||||
if (user_have_feature_cast_support(user, tmp))
|
if (user_have_feature_cast_support(user, tmp))
|
||||||
{
|
{
|
||||||
do_send = 0;
|
do_send = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tmp = list_get_next(command->feature_cast_exclude);
|
});
|
||||||
}
|
|
||||||
|
|
||||||
if (do_send)
|
if (do_send)
|
||||||
{
|
|
||||||
route_to_user(hub, user, command);
|
route_to_user(hub, user, command);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
user = (struct hub_user*) list_get_next(hub->users->list);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -214,16 +207,13 @@ int route_info_message(struct hub_info* hub, struct hub_user* u)
|
|||||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR);
|
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR);
|
||||||
adc_msg_add_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR, address);
|
adc_msg_add_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR, address);
|
||||||
|
|
||||||
user = (struct hub_user*) list_get_first(hub->users->list);
|
LIST_FOREACH(struct hub_user*, user, hub->users->list,
|
||||||
while (user)
|
|
||||||
{
|
{
|
||||||
if (user_is_nat_override(user))
|
if (user_is_nat_override(user))
|
||||||
route_to_user(hub, user, cmd);
|
route_to_user(hub, user, cmd);
|
||||||
else
|
else
|
||||||
route_to_user(hub, user, u->info);
|
route_to_user(hub, user, u->info);
|
||||||
|
});
|
||||||
user = (struct hub_user*) list_get_next(hub->users->list);
|
|
||||||
}
|
|
||||||
adc_msg_free(cmd);
|
adc_msg_free(cmd);
|
||||||
}
|
}
|
||||||
return 0;
|
return 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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -232,15 +232,12 @@ void user_support_remove(struct hub_user* user, int fourcc)
|
|||||||
|
|
||||||
int user_have_feature_cast_support(struct hub_user* user, char feature[4])
|
int user_have_feature_cast_support(struct hub_user* user, char feature[4])
|
||||||
{
|
{
|
||||||
char* tmp = list_get_first(user->feature_cast);
|
char* tmp;
|
||||||
while (tmp)
|
LIST_FOREACH(char*, tmp, user->feature_cast,
|
||||||
{
|
{
|
||||||
if (strncmp(tmp, feature, 4) == 0)
|
if (strncmp(tmp, feature, 4) == 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
});
|
||||||
tmp = list_get_next(user->feature_cast);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ enum user_quit_reason
|
|||||||
quit_timeout = 4, /** User timed out (no data for a while) */
|
quit_timeout = 4, /** User timed out (no data for a while) */
|
||||||
quit_send_queue = 5, /** User's send queue was overflowed */
|
quit_send_queue = 5, /** User's send queue was overflowed */
|
||||||
quit_memory_error = 6, /** Not enough memory available */
|
quit_memory_error = 6, /** Not enough memory available */
|
||||||
quit_socket_error = 7, /** A socket error occured */
|
quit_socket_error = 7, /** A socket error occurred */
|
||||||
quit_protocol_error = 8, /** Fatal protocol error */
|
quit_protocol_error = 8, /** Fatal protocol error */
|
||||||
quit_logon_error = 9, /** Unable to login (wrong password, CID/PID, etc) */
|
quit_logon_error = 9, /** Unable to login (wrong password, CID/PID, etc) */
|
||||||
quit_update_error = 10, /** Update error. INF update changed share/slot info and no longer satisfies the hub limits. */
|
quit_update_error = 10, /** Update error. INF update changed share/slot info and no longer satisfies the hub limits. */
|
||||||
@ -76,7 +76,7 @@ enum user_quit_reason
|
|||||||
quit_ghost_timeout = 12, /** The user is a ghost, and trying to login from another connection */
|
quit_ghost_timeout = 12, /** The user is a ghost, and trying to login from another connection */
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Returns an apropriate string for the given quit reason */
|
/** Returns an appropriate string for the given quit reason */
|
||||||
extern const char* user_get_quit_reason_string(enum user_quit_reason);
|
extern const char* user_get_quit_reason_string(enum user_quit_reason);
|
||||||
|
|
||||||
struct hub_user_info
|
struct hub_user_info
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -38,6 +38,11 @@ static void clear_user_list_callback(void* ptr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int uman_map_compare(const void* a, const void* b)
|
||||||
|
{
|
||||||
|
return strcmp((const char*) a, (const char*) b);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct hub_user_manager* uman_init()
|
struct hub_user_manager* uman_init()
|
||||||
{
|
{
|
||||||
@ -46,15 +51,10 @@ struct hub_user_manager* uman_init()
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
users->list = list_create();
|
users->list = list_create();
|
||||||
|
users->nickmap = rb_tree_create(uman_map_compare, NULL, NULL);
|
||||||
|
users->cidmap = rb_tree_create(uman_map_compare, NULL, NULL);
|
||||||
users->sids = sid_pool_create(net_get_max_sockets());
|
users->sids = sid_pool_create(net_get_max_sockets());
|
||||||
|
|
||||||
if (!users->list)
|
|
||||||
{
|
|
||||||
list_destroy(users->list);
|
|
||||||
hub_free(users);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return users;
|
return users;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,11 +64,18 @@ int uman_shutdown(struct hub_user_manager* users)
|
|||||||
if (!users)
|
if (!users)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (users->nickmap)
|
||||||
|
rb_tree_destroy(users->nickmap);
|
||||||
|
|
||||||
|
if (users->cidmap)
|
||||||
|
rb_tree_destroy(users->cidmap);
|
||||||
|
|
||||||
if (users->list)
|
if (users->list)
|
||||||
{
|
{
|
||||||
list_clear(users->list, &clear_user_list_callback);
|
list_clear(users->list, &clear_user_list_callback);
|
||||||
list_destroy(users->list);
|
list_destroy(users->list);
|
||||||
}
|
}
|
||||||
|
|
||||||
sid_pool_destroy(users->sids);
|
sid_pool_destroy(users->sids);
|
||||||
|
|
||||||
hub_free(users);
|
hub_free(users);
|
||||||
@ -81,6 +88,9 @@ int uman_add(struct hub_user_manager* users, struct hub_user* user)
|
|||||||
if (!users || !user)
|
if (!users || !user)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
rb_tree_insert(users->nickmap, user->id.nick, user);
|
||||||
|
rb_tree_insert(users->cidmap, user->id.cid, user);
|
||||||
|
|
||||||
list_append(users->list, user);
|
list_append(users->list, user);
|
||||||
users->count++;
|
users->count++;
|
||||||
users->count_peak = MAX(users->count, users->count_peak);
|
users->count_peak = MAX(users->count, users->count_peak);
|
||||||
@ -96,6 +106,8 @@ int uman_remove(struct hub_user_manager* users, struct hub_user* user)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
list_remove(users->list, user);
|
list_remove(users->list, user);
|
||||||
|
rb_tree_remove(users->nickmap, user->id.nick);
|
||||||
|
rb_tree_remove(users->cidmap, user->id.cid);
|
||||||
|
|
||||||
if (users->count > 0)
|
if (users->count > 0)
|
||||||
{
|
{
|
||||||
@ -120,42 +132,29 @@ struct hub_user* uman_get_user_by_sid(struct hub_user_manager* users, sid_t sid)
|
|||||||
|
|
||||||
struct hub_user* uman_get_user_by_cid(struct hub_user_manager* users, 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(users->list); /* iterate users - only on incoming INF msg */
|
struct hub_user* user = (struct hub_user*) rb_tree_get(users->cidmap, (const void*) cid);
|
||||||
while (user)
|
|
||||||
{
|
|
||||||
if (strcmp(user->id.cid, cid) == 0)
|
|
||||||
return user;
|
return user;
|
||||||
user = (struct hub_user*) list_get_next(users->list);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct hub_user* uman_get_user_by_nick(struct hub_user_manager* users, 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(users->list); /* iterate users - only on incoming INF msg */
|
struct hub_user* user = (struct hub_user*) rb_tree_get(users->nickmap, nick);
|
||||||
while (user)
|
|
||||||
{
|
|
||||||
if (strcmp(user->id.nick, nick) == 0)
|
|
||||||
return user;
|
return user;
|
||||||
user = (struct hub_user*) list_get_next(users->list);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t uman_get_user_by_addr(struct hub_user_manager* users, struct linked_list* target, 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(users->list); /* iterate users - only on incoming INF msg */
|
struct hub_user* user;
|
||||||
while (user)
|
LIST_FOREACH(struct hub_user*, user, users->list,
|
||||||
{
|
{
|
||||||
if (ip_in_range(&user->id.addr, range))
|
if (ip_in_range(&user->id.addr, range))
|
||||||
{
|
{
|
||||||
list_append(target, user);
|
list_append(target, user);
|
||||||
num++;
|
num++;
|
||||||
}
|
}
|
||||||
user = (struct hub_user*) list_get_next(users->list);
|
});
|
||||||
}
|
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,8 +163,8 @@ int uman_send_user_list(struct hub_info* hub, struct hub_user_manager* users, st
|
|||||||
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(users->list); /* iterate users - only on INF or PAS msg */
|
|
||||||
while (user)
|
LIST_FOREACH(struct hub_user*, user, users->list,
|
||||||
{
|
{
|
||||||
if (user_is_logged_in(user))
|
if (user_is_logged_in(user))
|
||||||
{
|
{
|
||||||
@ -173,8 +172,7 @@ int uman_send_user_list(struct hub_info* hub, struct hub_user_manager* users, st
|
|||||||
if (!ret)
|
if (!ret)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
user = (struct hub_user*) list_get_next(users->list);
|
});
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
FIXME: FIXME FIXME handle send queue excess
|
FIXME: FIXME FIXME handle send queue excess
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -24,10 +24,12 @@ struct hub_user_manager
|
|||||||
{
|
{
|
||||||
size_t count; /**<< "Number of all fully connected and logged in users" */
|
size_t count; /**<< "Number of all fully connected and logged in users" */
|
||||||
size_t count_peak; /**<< "Peak number of users" */
|
size_t count_peak; /**<< "Peak number of users" */
|
||||||
struct sid_pool* sids;
|
|
||||||
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 sid_pool* sids; /**<< "Maps SIDs to users (constant time)" */
|
||||||
struct linked_list* list; /**<< "Contains all logged in users" */
|
struct linked_list* list; /**<< "Contains all logged in users" */
|
||||||
|
struct rb_tree* nickmap; /**<< "Maps nicknames to users (red black tree)" */
|
||||||
|
struct rb_tree* cidmap; /**<< "Maps CIDs to users (red black tree)" */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,7 +42,7 @@ 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 (invalid pointer).
|
* @return 0 on success, or -1 in an error occurred (invalid pointer).
|
||||||
*/
|
*/
|
||||||
extern int uman_shutdown(struct hub_user_manager* users);
|
extern int uman_shutdown(struct hub_user_manager* users);
|
||||||
|
|
||||||
@ -104,7 +106,7 @@ extern struct hub_user* uman_get_user_by_nick(struct hub_user_manager* users, co
|
|||||||
*
|
*
|
||||||
* @param[out] target the list of users matching the address
|
* @param[out] target the list of users matching the address
|
||||||
* @param range the IP range of users to match
|
* @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 addresses, or -1 on error (mask is wrong).
|
||||||
*/
|
*/
|
||||||
extern size_t uman_get_user_by_addr(struct hub_user_manager* users, struct linked_list* target, 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);
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2012, Jan Vidar Krey
|
* Copyright (C) 2007-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -102,14 +102,7 @@ void net_backend_shutdown()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void net_con_reinitialize(struct net_connection* con, net_connection_cb callback, const void* ptr, int events)
|
void net_backend_update(struct net_connection* con, int events)
|
||||||
{
|
|
||||||
con->callback = callback;
|
|
||||||
con->ptr = (void*) ptr;
|
|
||||||
net_con_update(con, events);
|
|
||||||
}
|
|
||||||
|
|
||||||
void net_con_update(struct net_connection* con, int events)
|
|
||||||
{
|
{
|
||||||
g_backend->handler.con_mod(g_backend->data, con, events);
|
g_backend->handler.con_mod(g_backend->data, con, events);
|
||||||
}
|
}
|
||||||
@ -132,9 +125,10 @@ struct timeout_queue* net_backend_get_timeout_queue()
|
|||||||
*/
|
*/
|
||||||
int net_backend_process()
|
int net_backend_process()
|
||||||
{
|
{
|
||||||
int res;
|
int res = 0;
|
||||||
size_t secs = timeout_queue_get_next_timeout(&g_backend->timeout_queue, g_backend->now);
|
size_t secs = timeout_queue_get_next_timeout(&g_backend->timeout_queue, g_backend->now);
|
||||||
|
|
||||||
|
if (g_backend->common.num)
|
||||||
res = g_backend->handler.backend_poll(g_backend->data, secs * 1000);
|
res = g_backend->handler.backend_poll(g_backend->data, secs * 1000);
|
||||||
|
|
||||||
g_backend->now = time(0);
|
g_backend->now = time(0);
|
||||||
@ -146,6 +140,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);
|
||||||
@ -162,8 +159,8 @@ void net_con_initialize(struct net_connection* con, int sd, net_connection_cb ca
|
|||||||
{
|
{
|
||||||
g_backend->handler.con_init(g_backend->data, con, sd, callback, ptr);
|
g_backend->handler.con_init(g_backend->data, con, sd, callback, ptr);
|
||||||
|
|
||||||
net_set_nonblocking(con->sd, 1);
|
net_set_nonblocking(net_con_get_sd(con), 1);
|
||||||
net_set_nosigpipe(con->sd, 1);
|
net_set_nosigpipe(net_con_get_sd(con), 1);
|
||||||
|
|
||||||
g_backend->handler.con_add(g_backend->data, con, events);
|
g_backend->handler.con_add(g_backend->data, con, events);
|
||||||
g_backend->common.num++;
|
g_backend->common.num++;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2012, Jan Vidar Krey
|
* Copyright (C) 2007-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -75,6 +75,14 @@ extern void net_backend_shutdown();
|
|||||||
*/
|
*/
|
||||||
extern int net_backend_process();
|
extern int net_backend_process();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the event mask.
|
||||||
|
*
|
||||||
|
* @param con Connection handle.
|
||||||
|
* @param events Event mask (NET_EVENT_*)
|
||||||
|
*/
|
||||||
|
extern void net_backend_update(struct net_connection* con, int events);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current time.
|
* Get the current time.
|
||||||
*/
|
*/
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2012, Jan Vidar Krey
|
* Copyright (C) 2007-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2012, Jan Vidar Krey
|
* Copyright (C) 2007-2014, 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
|
||||||
@ -13,17 +13,13 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "uhub.h"
|
#include "uhub.h"
|
||||||
#include "network/common.h"
|
#include "network/common.h"
|
||||||
|
#include "network/backend.h"
|
||||||
#ifdef SSL_SUPPORT
|
|
||||||
void net_stats_add_tx(size_t bytes);
|
|
||||||
void net_stats_add_rx(size_t bytes);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int is_blocked_or_interrupted()
|
static int is_blocked_or_interrupted()
|
||||||
{
|
{
|
||||||
@ -121,10 +117,27 @@ void* net_con_get_ptr(struct net_connection* con)
|
|||||||
return con->ptr;
|
return con->ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void net_con_destroy(struct net_connection* con)
|
void net_con_update(struct net_connection* con, int events)
|
||||||
{
|
{
|
||||||
#ifdef SSL_SUPPORT
|
#ifdef SSL_SUPPORT
|
||||||
if (con->ssl)
|
if (con->ssl)
|
||||||
|
net_ssl_update(con, events);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
net_backend_update(con, events);
|
||||||
|
}
|
||||||
|
|
||||||
|
void net_con_reinitialize(struct net_connection* con, net_connection_cb callback, const void* ptr, int events)
|
||||||
|
{
|
||||||
|
con->callback = callback;
|
||||||
|
con->ptr = (void*) ptr;
|
||||||
|
net_con_update(con, events);
|
||||||
|
}
|
||||||
|
|
||||||
|
void net_con_destroy(struct net_connection* con)
|
||||||
|
{
|
||||||
|
#ifdef SSL_SUPPORT
|
||||||
|
if (con && con->ssl)
|
||||||
net_ssl_destroy(con);
|
net_ssl_destroy(con);
|
||||||
#endif
|
#endif
|
||||||
hub_free(con);
|
hub_free(con);
|
||||||
@ -150,3 +163,395 @@ void net_con_callback(struct net_connection* con, int events)
|
|||||||
con->callback(con, events, con->ptr);
|
con->callback(con, events, con->ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct net_connect_job
|
||||||
|
{
|
||||||
|
struct net_connection* con;
|
||||||
|
struct net_connect_handle* handle;
|
||||||
|
struct sockaddr_storage addr;
|
||||||
|
struct net_connect_job* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct net_connect_handle
|
||||||
|
{
|
||||||
|
const char* address;
|
||||||
|
uint16_t port;
|
||||||
|
void* ptr;
|
||||||
|
net_connect_cb callback;
|
||||||
|
struct net_dns_job* dns;
|
||||||
|
const struct net_dns_result* result;
|
||||||
|
struct net_connect_job* job4;
|
||||||
|
struct net_connect_job* job6;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void net_connect_callback(struct net_connect_handle* handle, enum net_connect_status status, struct net_connection* con);
|
||||||
|
static void net_connect_job_internal_cb(struct net_connection* con, int event, void* ptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a connection job is completed.
|
||||||
|
* @return -1 on completed with an error, 0 on not yet completed, or 1 if completed successfully (connected).
|
||||||
|
*/
|
||||||
|
static int net_connect_job_check(struct net_connect_job* job)
|
||||||
|
{
|
||||||
|
struct net_connection* con = job->con;
|
||||||
|
int af = job->addr.ss_family;
|
||||||
|
enum net_connect_status status;
|
||||||
|
|
||||||
|
int ret = net_connect(net_con_get_sd(con), (struct sockaddr*) &job->addr, af == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6));
|
||||||
|
if (ret == 0 || (ret == -1 && net_error() == EISCONN))
|
||||||
|
{
|
||||||
|
LOG_TRACE("net_connect_job_check(): Socket connected!");
|
||||||
|
job->con = NULL;
|
||||||
|
net_con_clear_timeout(con);
|
||||||
|
net_connect_callback(job->handle, net_connect_status_ok, con);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (ret == -1 && (net_error() == EALREADY || net_error() == EINPROGRESS || net_error() == EWOULDBLOCK || net_error() == EINTR))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
LOG_TRACE("net_connect_job_check(): Socket error!");
|
||||||
|
|
||||||
|
switch (net_error())
|
||||||
|
{
|
||||||
|
case ECONNREFUSED:
|
||||||
|
status = net_connect_status_refused;
|
||||||
|
break;
|
||||||
|
case ENETUNREACH:
|
||||||
|
status = net_connect_status_unreachable;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
status = net_connect_status_socket_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
net_connect_callback(job->handle, status, NULL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void net_connect_job_free(struct net_connect_job* job)
|
||||||
|
{
|
||||||
|
if (job->con)
|
||||||
|
net_con_close(job->con);
|
||||||
|
job->handle = NULL;
|
||||||
|
job->next = NULL;
|
||||||
|
hub_free(job);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void net_connect_job_stop(struct net_connect_job* job)
|
||||||
|
{
|
||||||
|
if (job->addr.ss_family == AF_INET6)
|
||||||
|
{
|
||||||
|
job->handle->job6 = job->next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
job->handle->job4 = job->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
net_connect_job_free(job);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int net_connect_depleted(struct net_connect_handle* handle)
|
||||||
|
{
|
||||||
|
return (!handle->job6 && !handle->job4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int net_connect_job_process(struct net_connect_job* job)
|
||||||
|
{
|
||||||
|
int sd;
|
||||||
|
if (!job->con)
|
||||||
|
{
|
||||||
|
sd = net_socket_create(job->addr.ss_family, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
if (sd == -1)
|
||||||
|
{
|
||||||
|
LOG_DEBUG("net_connect_job_process: Unable to create socket!");
|
||||||
|
net_connect_callback(job->handle, net_connect_status_socket_error, NULL);
|
||||||
|
return -1; // FIXME
|
||||||
|
}
|
||||||
|
|
||||||
|
job->con = net_con_create();
|
||||||
|
net_con_initialize(job->con, sd, net_connect_job_internal_cb, job, NET_EVENT_WRITE);
|
||||||
|
net_con_set_timeout(job->con, TIMEOUT_CONNECTED); // FIXME: Use a proper timeout value!
|
||||||
|
}
|
||||||
|
|
||||||
|
return net_connect_job_check(job);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Internal callback used to establish an outbound connection.
|
||||||
|
*/
|
||||||
|
static void net_connect_job_internal_cb(struct net_connection* con, int event, void* ptr)
|
||||||
|
{
|
||||||
|
struct net_connect_job* job = net_con_get_ptr(con);
|
||||||
|
struct net_connect_job* next_job = job->next;
|
||||||
|
struct net_connect_handle* handle = job->handle;
|
||||||
|
|
||||||
|
if (event == NET_EVENT_TIMEOUT)
|
||||||
|
{
|
||||||
|
// FIXME: Try next address, or if no more addresses left declare failure to connect.
|
||||||
|
if (job->addr.ss_family == AF_INET6)
|
||||||
|
{
|
||||||
|
net_connect_job_stop(job);
|
||||||
|
|
||||||
|
if (!next_job)
|
||||||
|
{
|
||||||
|
LOG_TRACE("No more IPv6 addresses to try!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
net_connect_job_stop(job);
|
||||||
|
|
||||||
|
if (!next_job)
|
||||||
|
{
|
||||||
|
LOG_TRACE("No more IPv4 addresses to try!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (net_connect_depleted(handle))
|
||||||
|
{
|
||||||
|
LOG_TRACE("No more addresses left. Unable to connect!");
|
||||||
|
net_connect_callback(handle, net_connect_status_timeout, NULL);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event == NET_EVENT_WRITE)
|
||||||
|
{
|
||||||
|
net_connect_job_process(job);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void net_connect_cancel(struct net_connect_handle* handle)
|
||||||
|
{
|
||||||
|
struct net_connect_job* job;
|
||||||
|
|
||||||
|
job = handle->job6;
|
||||||
|
while (job)
|
||||||
|
{
|
||||||
|
job = job->next;
|
||||||
|
net_connect_job_free(handle->job6);
|
||||||
|
handle->job6 = job;
|
||||||
|
}
|
||||||
|
|
||||||
|
job = handle->job4;
|
||||||
|
while (job)
|
||||||
|
{
|
||||||
|
job = job->next;
|
||||||
|
net_connect_job_free(handle->job4);
|
||||||
|
handle->job4 = job;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int net_connect_process_queue(struct net_connect_handle* handle, struct net_connect_job* job)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
while (job)
|
||||||
|
{
|
||||||
|
ret = net_connect_job_process(job);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
net_connect_job_stop(job);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (ret == 0)
|
||||||
|
{
|
||||||
|
// Need to process again
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// FIXME: Success!
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int net_connect_process(struct net_connect_handle* handle)
|
||||||
|
{
|
||||||
|
int ret4, ret6;
|
||||||
|
|
||||||
|
ret6 = net_connect_process_queue(handle, handle->job6);
|
||||||
|
if (ret6 == 1)
|
||||||
|
return 1; // Connected - cool!
|
||||||
|
|
||||||
|
net_connect_process_queue(handle, handle->job4);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int net_connect_job_schedule(struct net_connect_handle* handle, struct ip_addr_encap* addr)
|
||||||
|
{
|
||||||
|
struct net_connect_job* job;
|
||||||
|
struct sockaddr_in* addr4;
|
||||||
|
struct sockaddr_in6* addr6;
|
||||||
|
|
||||||
|
if (addr->af == AF_INET6 && !net_is_ipv6_supported())
|
||||||
|
{
|
||||||
|
LOG_TRACE("net_connect_job_schedule(): Skipping IPv6 support since IPv6 is not supported.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
job = hub_malloc_zero(sizeof(struct net_connect_job));
|
||||||
|
job->handle = handle;
|
||||||
|
if (addr->af == AF_INET6)
|
||||||
|
{
|
||||||
|
addr6 = (struct sockaddr_in6*) &job->addr;
|
||||||
|
LOG_TRACE("net_connect_job_schedule(): Scheduling IPv6 connect job.");
|
||||||
|
addr6->sin6_family = AF_INET6;
|
||||||
|
addr6->sin6_port = htons(handle->port);
|
||||||
|
memcpy(&addr6->sin6_addr, &addr->internal_ip_data.in6, sizeof(struct in6_addr));
|
||||||
|
|
||||||
|
// prepend
|
||||||
|
job->next = handle->job6;
|
||||||
|
handle->job6 = job;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
addr4 = (struct sockaddr_in*) &job->addr;
|
||||||
|
LOG_TRACE("net_connect_job_schedule(): Scheduling IPv4 connect job.");
|
||||||
|
addr4->sin_family = AF_INET;
|
||||||
|
addr4->sin_port = htons(handle->port);
|
||||||
|
memcpy(&addr4->sin_addr, &addr->internal_ip_data.in, sizeof(struct in_addr));
|
||||||
|
|
||||||
|
// prepend
|
||||||
|
job->next = handle->job4;
|
||||||
|
handle->job4 = job;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Callback when the DNS results are ready.
|
||||||
|
* Create a list of IPv6 and IPv4 addresses, then
|
||||||
|
* start connecting to them one by one until one succeeds.
|
||||||
|
*/
|
||||||
|
static int net_con_connect_dns_callback(struct net_dns_job* job, const struct net_dns_result* result)
|
||||||
|
{
|
||||||
|
struct ip_addr_encap* addr;
|
||||||
|
struct net_connect_handle* handle = (struct net_connect_handle*) net_dns_job_get_ptr(job);
|
||||||
|
handle->dns = NULL;
|
||||||
|
size_t usable = 0;
|
||||||
|
|
||||||
|
LOG_TRACE("net_con_connect(): async - Got DNS results");
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
LOG_DEBUG("net_con_connect() - Unable to lookup host!");
|
||||||
|
net_connect_callback(handle, net_connect_status_dns_error, NULL);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!net_dns_result_size(result))
|
||||||
|
{
|
||||||
|
LOG_DEBUG("net_con_connect() - Host not found!");
|
||||||
|
net_connect_callback(handle, net_connect_status_host_not_found, NULL);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle->result = result;
|
||||||
|
|
||||||
|
// Extract results into a separate list of IPv4 and IPv6 addresses.
|
||||||
|
addr = net_dns_result_first(result);
|
||||||
|
while (addr)
|
||||||
|
{
|
||||||
|
if (net_connect_job_schedule(handle, addr))
|
||||||
|
usable++;
|
||||||
|
addr = net_dns_result_next(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
net_connect_process(handle);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// typedef void (*net_connect_cb)(struct net_connect_handle*, enum net_connect_handle_code, struct net_connection* con);
|
||||||
|
|
||||||
|
struct net_connect_handle* net_con_connect(const char* address, uint16_t port, net_connect_cb callback, void* ptr)
|
||||||
|
{
|
||||||
|
struct net_connect_handle* handle = hub_malloc_zero(sizeof(struct net_connect_handle));
|
||||||
|
|
||||||
|
handle->address = hub_strdup(address);
|
||||||
|
handle->port = port;
|
||||||
|
handle->ptr = ptr;
|
||||||
|
handle->callback = callback;
|
||||||
|
|
||||||
|
// FIXME: Check if DNS resolving is necessary ?
|
||||||
|
handle->dns = net_dns_gethostbyname(address, AF_UNSPEC, net_con_connect_dns_callback, handle);
|
||||||
|
if (!handle->dns)
|
||||||
|
{
|
||||||
|
LOG_TRACE("net_con_connect(): Unable to create DNS lookup job.");
|
||||||
|
hub_free((char*) handle->address);
|
||||||
|
hub_free(handle);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void net_connect_destroy(struct net_connect_handle* handle)
|
||||||
|
{
|
||||||
|
hub_free((char*) handle->address);
|
||||||
|
|
||||||
|
// cancel DNS job if pending
|
||||||
|
if (handle->dns)
|
||||||
|
net_dns_job_cancel(handle->dns);
|
||||||
|
|
||||||
|
// Stop any connect jobs.
|
||||||
|
net_connect_cancel(handle);
|
||||||
|
|
||||||
|
// free any DNS results
|
||||||
|
net_dns_result_free(handle->result);
|
||||||
|
|
||||||
|
hub_free(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void net_connect_callback(struct net_connect_handle* handle, enum net_connect_status status, struct net_connection* con)
|
||||||
|
{
|
||||||
|
uhub_assert(handle->callback != NULL);
|
||||||
|
|
||||||
|
// Call the callback
|
||||||
|
handle->callback(handle, status, con, handle->ptr);
|
||||||
|
handle->callback = NULL;
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
net_connect_destroy(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void timeout_callback(struct timeout_evt* evt)
|
||||||
|
{
|
||||||
|
net_con_callback((struct net_connection*) evt->ptr, NET_EVENT_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void net_con_set_timeout(struct net_connection* con, int seconds)
|
||||||
|
{
|
||||||
|
if (!con->timeout)
|
||||||
|
{
|
||||||
|
con->timeout = hub_malloc_zero(sizeof(struct timeout_evt));
|
||||||
|
timeout_evt_initialize(con->timeout, timeout_callback, con);
|
||||||
|
timeout_queue_insert(net_backend_get_timeout_queue(), con->timeout, seconds);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
timeout_queue_reschedule(net_backend_get_timeout_queue(), con->timeout, seconds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void net_con_clear_timeout(struct net_connection* con)
|
||||||
|
{
|
||||||
|
if (con->timeout && timeout_evt_is_scheduled(con->timeout))
|
||||||
|
{
|
||||||
|
timeout_queue_remove(net_backend_get_timeout_queue(), con->timeout);
|
||||||
|
hub_free(con->timeout);
|
||||||
|
con->timeout = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2012, Jan Vidar Krey
|
* Copyright (C) 2007-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -28,16 +28,48 @@
|
|||||||
#define NET_EVENT_TIMEOUT 0x0001
|
#define NET_EVENT_TIMEOUT 0x0001
|
||||||
#define NET_EVENT_READ 0x0002
|
#define NET_EVENT_READ 0x0002
|
||||||
#define NET_EVENT_WRITE 0x0004
|
#define NET_EVENT_WRITE 0x0004
|
||||||
|
#define NET_EVENT_ERROR 0x1000
|
||||||
|
|
||||||
struct net_connection
|
struct net_connection
|
||||||
{
|
{
|
||||||
NET_CON_STRUCT_COMMON
|
NET_CON_STRUCT_COMMON
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct net_connect_handle;
|
||||||
|
|
||||||
|
enum net_connect_status
|
||||||
|
{
|
||||||
|
net_connect_status_ok = 0,
|
||||||
|
net_connect_status_host_not_found = -1,
|
||||||
|
net_connect_status_no_address = -2,
|
||||||
|
net_connect_status_dns_error = -3,
|
||||||
|
net_connect_status_refused = -4,
|
||||||
|
net_connect_status_unreachable = -5,
|
||||||
|
net_connect_status_timeout = -6,
|
||||||
|
net_connect_status_socket_error = -7,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void (*net_connect_cb)(struct net_connect_handle*, enum net_connect_status status, struct net_connection* con, void* ptr);
|
||||||
|
|
||||||
extern int net_con_get_sd(struct net_connection* con);
|
extern int net_con_get_sd(struct net_connection* con);
|
||||||
extern void* net_con_get_ptr(struct net_connection* con);
|
extern void* net_con_get_ptr(struct net_connection* con);
|
||||||
|
|
||||||
extern struct net_connection* net_con_create();
|
extern struct net_connection* net_con_create();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Establish an outbound TCP connection.
|
||||||
|
* This will resolve the IP-addresses, and connect to
|
||||||
|
* either an IPv4 or IPv6 address depending if it is supported,
|
||||||
|
* and using the happy eyeballs algorithm.
|
||||||
|
*
|
||||||
|
* @param address Hostname, IPv4 or IPv6 address
|
||||||
|
* @param port TCP port number
|
||||||
|
* @param callback A callback to be called once the connection is established, or failed.
|
||||||
|
* @returns a handle to the connection establishment job, or NULL if an immediate error.
|
||||||
|
*/
|
||||||
|
extern struct net_connect_handle* net_con_connect(const char* address, uint16_t port, net_connect_cb callback, void* ptr);
|
||||||
|
extern void net_connect_destroy(struct net_connect_handle* handle);
|
||||||
|
|
||||||
extern void net_con_destroy(struct net_connection*);
|
extern void net_con_destroy(struct net_connection*);
|
||||||
extern void net_con_initialize(struct net_connection* con, int sd, net_connection_cb callback, const void* ptr, int events);
|
extern void net_con_initialize(struct net_connection* con, int sd, net_connection_cb callback, const void* ptr, int events);
|
||||||
extern void net_con_reinitialize(struct net_connection* con, net_connection_cb callback, const void* ptr, int events);
|
extern void net_con_reinitialize(struct net_connection* con, net_connection_cb callback, const void* ptr, int events);
|
||||||
@ -56,7 +88,7 @@ extern void net_con_close(struct net_connection* con);
|
|||||||
*
|
*
|
||||||
* @return returns the number of bytes sent.
|
* @return returns the number of bytes sent.
|
||||||
* 0 if no data is sent, and this function should be called again (EWOULDBLOCK/EINTR)
|
* 0 if no data is sent, and this function should be called again (EWOULDBLOCK/EINTR)
|
||||||
* <0 if an error occured, the negative number contains the error code.
|
* <0 if an error occurred, the negative number contains the error code.
|
||||||
*/
|
*/
|
||||||
extern ssize_t net_con_send(struct net_connection* con, const void* buf, size_t len);
|
extern ssize_t net_con_send(struct net_connection* con, const void* buf, size_t len);
|
||||||
|
|
||||||
@ -65,7 +97,7 @@ extern ssize_t net_con_send(struct net_connection* con, const void* buf, size_t
|
|||||||
*
|
*
|
||||||
* @return returns the number of bytes sent.
|
* @return returns the number of bytes sent.
|
||||||
* 0 if no data is sent, and this function should be called again (EWOULDBLOCK/EINTR)
|
* 0 if no data is sent, and this function should be called again (EWOULDBLOCK/EINTR)
|
||||||
* <0 if an error occured, the negative number contains the error code.
|
* <0 if an error occurred, the negative number contains the error code.
|
||||||
*/
|
*/
|
||||||
extern ssize_t net_con_recv(struct net_connection* con, void* buf, size_t len);
|
extern ssize_t net_con_recv(struct net_connection* con, void* buf, size_t len);
|
||||||
|
|
||||||
@ -77,7 +109,7 @@ extern ssize_t net_con_recv(struct net_connection* con, void* buf, size_t len);
|
|||||||
extern ssize_t net_con_peek(struct net_connection* con, void* buf, size_t len);
|
extern ssize_t net_con_peek(struct net_connection* con, void* buf, size_t len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set timeout for connetion.
|
* Set timeout for connection.
|
||||||
*
|
*
|
||||||
* @param seconds the number of seconds into the future.
|
* @param seconds the number of seconds into the future.
|
||||||
*/
|
*/
|
||||||
|
391
src/network/dnsresolver.c
Normal file
391
src/network/dnsresolver.c
Normal file
@ -0,0 +1,391 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2014, 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 <https://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);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void notify_callback(struct uhub_notify_handle* handle, void* ptr)
|
||||||
|
{
|
||||||
|
net_dns_process();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
struct uhub_notify_handle* notify_handle; // used to signal back to the event loop that there is something to process.
|
||||||
|
};
|
||||||
|
|
||||||
|
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);
|
||||||
|
g_dns->notify_handle = net_notify_create(notify_callback, g_dns);
|
||||||
|
}
|
||||||
|
|
||||||
|
void net_dns_destroy()
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
net_notify_destroy(g_dns->notify_handle);
|
||||||
|
hub_free(g_dns);
|
||||||
|
g_dns = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void net_dns_process()
|
||||||
|
{
|
||||||
|
struct net_dns_result* result;
|
||||||
|
uhub_mutex_lock(&g_dns->mutex);
|
||||||
|
LOG_TRACE("net_dns_process(): jobs=%d, results=%d", (int) list_size(g_dns->jobs), (int) list_size(g_dns->results));
|
||||||
|
|
||||||
|
LIST_FOREACH(struct net_dns_result*, result, 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, NULL);
|
||||||
|
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);
|
||||||
|
net_notify_signal(g_dns->notify_handle, 1);
|
||||||
|
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;
|
||||||
|
LIST_FOREACH(struct net_dns_job*, it, 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;
|
||||||
|
LIST_FOREACH(struct net_dns_result*, it, 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", ipaddr ? ip_convert_to_string(ipaddr) : "(no address)");
|
||||||
|
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", ipaddr ? ip_convert_to_string(ipaddr) : "(no more addresses)");
|
||||||
|
return ipaddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void net_dns_result_free(const struct net_dns_result* res)
|
||||||
|
{
|
||||||
|
if (!res)
|
||||||
|
return;
|
||||||
|
|
||||||
|
list_clear(res->addr_list, &hub_free);
|
||||||
|
list_destroy(res->addr_list);
|
||||||
|
free_job(res->job);
|
||||||
|
hub_free((struct net_dns_result*) 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-2014, 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 <https://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(const 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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ extern int ip_is_valid_ipv6(const char* address);
|
|||||||
*
|
*
|
||||||
* @param text_addr is an ipaddress either ipv6 or ipv4.
|
* @param text_addr is an ipaddress either ipv6 or ipv4.
|
||||||
* Special magic addresses called "any" and "loopback" exist,
|
* Special magic addresses called "any" and "loopback" exist,
|
||||||
* and will work accross IPv6/IPv4.
|
* and will work across IPv6/IPv4.
|
||||||
* @param port Fill the struct sockaddr* with the given port, can safely be ignored.
|
* @param port Fill the struct sockaddr* with the given port, can safely be ignored.
|
||||||
*/
|
*/
|
||||||
extern int ip_convert_address(const char* text_address, int port, struct sockaddr* addr, socklen_t* addr_len);
|
extern int ip_convert_address(const char* text_address, int port, struct sockaddr* addr, socklen_t* addr_len);
|
||||||
|
@ -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-2014, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -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-2019, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -49,23 +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
|
|
||||||
#ifdef SSL_USE_OPENSSL
|
|
||||||
LOG_TRACE("Initializing OpenSSL...");
|
|
||||||
SSL_library_init();
|
|
||||||
SSL_load_error_strings();
|
|
||||||
#endif /* SSL_USE_OPENSSL */
|
|
||||||
#endif /* SSL_SUPPORT */
|
|
||||||
|
|
||||||
net_initialized = 1;
|
net_initialized = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -99,14 +97,12 @@ 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
|
||||||
#ifdef SSL_USE_OPENSSL
|
net_ssl_library_shutdown();
|
||||||
ERR_free_strings();
|
|
||||||
EVP_cleanup();
|
|
||||||
CRYPTO_cleanup_all_ex_data();
|
|
||||||
#endif /* SSL_USE_OPENSSL */
|
|
||||||
#endif /* SSL_SUPPORT */
|
#endif /* SSL_SUPPORT */
|
||||||
|
|
||||||
#ifdef WINSOCK
|
#ifdef WINSOCK
|
||||||
@ -499,7 +495,6 @@ int net_socket_create(int af, int type, int protocol)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return sd;
|
return sd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -810,4 +805,22 @@ void net_stats_add_close()
|
|||||||
stats.closed++;
|
stats.closed++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void net_stats_tls_add_accept()
|
||||||
|
{
|
||||||
|
stats.tls_accept++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void net_stats_tls_add_connect()
|
||||||
|
{
|
||||||
|
stats.tls_connect++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void net_stats_tls_add_error()
|
||||||
|
{
|
||||||
|
stats.tls_error++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void net_stats_tls_add_close()
|
||||||
|
{
|
||||||
|
stats.tls_close++;
|
||||||
|
}
|
||||||
|
@ -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-2019, 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
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -28,6 +28,10 @@ struct net_statistics
|
|||||||
size_t accept;
|
size_t accept;
|
||||||
size_t closed;
|
size_t closed;
|
||||||
size_t errors;
|
size_t errors;
|
||||||
|
size_t tls_accept;
|
||||||
|
size_t tls_connect;
|
||||||
|
size_t tls_error;
|
||||||
|
size_t tls_close;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct net_socket_t;
|
struct net_socket_t;
|
||||||
@ -53,7 +57,7 @@ extern int net_initialize();
|
|||||||
extern int net_destroy();
|
extern int net_destroy();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the number of sockets currrently being monitored.
|
* @return the number of sockets currently being monitored.
|
||||||
*/
|
*/
|
||||||
extern int net_monitor_count();
|
extern int net_monitor_count();
|
||||||
|
|
||||||
@ -63,7 +67,7 @@ extern int net_monitor_count();
|
|||||||
extern int net_monitor_capacity();
|
extern int net_monitor_capacity();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the last error code occured.
|
* @return the last error code occurred.
|
||||||
*
|
*
|
||||||
* NOTE: On Windows this is the last error code from the socket library, but
|
* NOTE: On Windows this is the last error code from the socket library, but
|
||||||
* on UNIX this is the errno variable that can be overwritten by any
|
* on UNIX this is the errno variable that can be overwritten by any
|
||||||
@ -247,9 +251,14 @@ extern void net_stats_report();
|
|||||||
extern void net_stats_reset();
|
extern void net_stats_reset();
|
||||||
extern void net_stats_add_tx(size_t bytes);
|
extern void net_stats_add_tx(size_t bytes);
|
||||||
extern void net_stats_add_rx(size_t bytes);
|
extern void net_stats_add_rx(size_t bytes);
|
||||||
|
extern void net_stats_tls_add_accept();
|
||||||
|
extern void net_stats_tls_add_connect();
|
||||||
|
extern void net_stats_tls_add_error();
|
||||||
|
extern void net_stats_tls_add_close();
|
||||||
extern void net_stats_add_accept();
|
extern void net_stats_add_accept();
|
||||||
extern void net_stats_add_error();
|
extern void net_stats_add_error();
|
||||||
extern void net_stats_add_close();
|
extern void net_stats_add_close();
|
||||||
|
extern void net_stats_add_connect();
|
||||||
extern int net_stats_timeout();
|
extern int net_stats_timeout();
|
||||||
extern void net_stats_get(struct net_statistics** intermediate, struct net_statistics** total);
|
extern void net_stats_get(struct net_statistics** intermediate, struct net_statistics** total);
|
||||||
|
|
||||||
|
102
src/network/notify.c
Normal file
102
src/network/notify.c
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2014, 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uhub.h"
|
||||||
|
|
||||||
|
struct uhub_notify_handle
|
||||||
|
{
|
||||||
|
net_notify_callback callback;
|
||||||
|
void* ptr;
|
||||||
|
#ifndef WIN32
|
||||||
|
int pipe_fd[2];
|
||||||
|
struct net_connection* con;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This contains a mechanism to wake up the main thread
|
||||||
|
* in a thread safe manner while it would be blocking
|
||||||
|
* in select() or something equivalent typically invoked from
|
||||||
|
* net_backend_process().
|
||||||
|
*
|
||||||
|
* The main usage is for the DNS resolver to notify the
|
||||||
|
* main thread that there are DNS results to be
|
||||||
|
* processed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a notification handle.
|
||||||
|
*/
|
||||||
|
#ifndef WIN32
|
||||||
|
static void notify_callback(struct net_connection* con, int event, void* ptr)
|
||||||
|
{
|
||||||
|
LOG_TRACE("notify_callback()");
|
||||||
|
struct uhub_notify_handle* handle = (struct uhub_notify_handle*) ptr;
|
||||||
|
char buf;
|
||||||
|
int ret = read(handle->pipe_fd[0], &buf, 1);
|
||||||
|
if (ret == 1)
|
||||||
|
{
|
||||||
|
if (handle->callback)
|
||||||
|
handle->callback(handle, handle->ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct uhub_notify_handle* net_notify_create(net_notify_callback cb, void* ptr)
|
||||||
|
{
|
||||||
|
LOG_TRACE("net_notify_create()");
|
||||||
|
struct uhub_notify_handle* handle = (struct uhub_notify_handle*) hub_malloc(sizeof(struct uhub_notify_handle));
|
||||||
|
handle->callback = cb;
|
||||||
|
handle->ptr = ptr;
|
||||||
|
#ifndef WIN32
|
||||||
|
int ret = pipe(handle->pipe_fd);
|
||||||
|
if (ret == -1)
|
||||||
|
{
|
||||||
|
LOG_ERROR("Unable to setup notification pipes.");
|
||||||
|
hub_free(handle);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle->con = net_con_create();
|
||||||
|
net_con_initialize(handle->con, handle->pipe_fd[0], notify_callback, handle, NET_EVENT_READ);
|
||||||
|
#endif
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void net_notify_destroy(struct uhub_notify_handle* handle)
|
||||||
|
{
|
||||||
|
LOG_TRACE("net_notify_destroy()");
|
||||||
|
#ifndef WIN32
|
||||||
|
net_con_destroy(handle->con);
|
||||||
|
close(handle->pipe_fd[0]);
|
||||||
|
close(handle->pipe_fd[1]);
|
||||||
|
handle->pipe_fd[0] = -1;
|
||||||
|
handle->pipe_fd[0] = -1;
|
||||||
|
#endif
|
||||||
|
hub_free(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void net_notify_signal(struct uhub_notify_handle* handle, char data)
|
||||||
|
{
|
||||||
|
LOG_TRACE("net_notify_signal()");
|
||||||
|
#ifndef WIN32
|
||||||
|
write(handle->pipe_fd[1], &data, 1);
|
||||||
|
#endif
|
||||||
|
}
|
56
src/network/notify.h
Normal file
56
src/network/notify.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-2014, 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HAVE_UHUB_NETWORK_NOTIFY_API_H
|
||||||
|
#define HAVE_UHUB_NETWORK_NOTIFY_API_H
|
||||||
|
|
||||||
|
struct uhub_notify_handle;
|
||||||
|
|
||||||
|
typedef void (*net_notify_callback)(struct uhub_notify_handle* handle, void* ptr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This contains a mechanism to wake up the main thread
|
||||||
|
* in a thread safe manner while it would be blocking
|
||||||
|
* in select() or something equivalent typically invoked from
|
||||||
|
* net_backend_process().
|
||||||
|
*
|
||||||
|
* The main usage is for the DNS resolver to notify the
|
||||||
|
* main thread that there are DNS results to be
|
||||||
|
* processed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a notification handle.
|
||||||
|
*/
|
||||||
|
struct uhub_notify_handle* net_notify_create(net_notify_callback cb, void* ptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy a notification handle.
|
||||||
|
*/
|
||||||
|
void net_notify_destroy(struct uhub_notify_handle*);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signal the notification handle, this will surely
|
||||||
|
* interrupt the net_backend_process(), and force it to
|
||||||
|
* process messages.
|
||||||
|
*/
|
||||||
|
void net_notify_signal(struct uhub_notify_handle*, char data);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* HAVE_UHUB_NETWORK_NOTIFY_API_H */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user