Compare commits
80 Commits
link_suppo
...
0.5.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
37c80fd403 | ||
|
|
dcc7aa4018 | ||
|
|
9dce6693f6 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -14,7 +14,6 @@ uhub-admin
|
|||||||
adcrush
|
adcrush
|
||||||
uhub
|
uhub
|
||||||
build-stamp
|
build-stamp
|
||||||
build.ninja
|
|
||||||
debian/files
|
debian/files
|
||||||
debian/uhub.debhelper.log
|
debian/uhub.debhelper.log
|
||||||
debian/uhub.postinst.debhelper
|
debian/uhub.postinst.debhelper
|
||||||
@@ -23,4 +22,4 @@ debian/uhub.prerm.debhelper
|
|||||||
debian/uhub.substvars
|
debian/uhub.substvars
|
||||||
uhub-passwd
|
uhub-passwd
|
||||||
src/version.h
|
src/version.h
|
||||||
|
src/system.h
|
||||||
|
|||||||
11
.travis.yml
Normal file
11
.travis.yml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
language: cpp
|
||||||
|
compiler:
|
||||||
|
- gcc
|
||||||
|
- clang
|
||||||
|
env:
|
||||||
|
- CONFIG=minimal
|
||||||
|
- CONFIG=full
|
||||||
|
install:
|
||||||
|
- autotest/travis/install-build-depends.sh
|
||||||
|
script:
|
||||||
|
- autotest/travis/build-and-test.sh
|
||||||
2
AUTHORS
2
AUTHORS
@@ -4,7 +4,7 @@ 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 plugin code
|
FleetCommand, Hub topic plugin code
|
||||||
MiMic, Implemented user commands
|
MiMic, Implemented user commands, and plugins
|
||||||
Boris Pek (tehnick), Debian/Ubuntu packaging
|
Boris Pek (tehnick), Debian/Ubuntu packaging
|
||||||
Tillmann Karras (Tilka), Misc. bug fixes
|
Tillmann Karras (Tilka), Misc. bug fixes
|
||||||
Yoran Heling (Yorhel), TLS/SSL handshake detection bugfixes
|
Yoran Heling (Yorhel), TLS/SSL handshake detection bugfixes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
##
|
##
|
||||||
## 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.2)
|
cmake_minimum_required (VERSION 2.8.2)
|
||||||
@@ -9,14 +9,14 @@ 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 0)
|
||||||
|
|
||||||
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)
|
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" ON )
|
option(USE_OPENSSL "Use OpenSSL's SSL support" ON )
|
||||||
option(SYSTEMD_SUPPORT "Enable systemd notify and journal logging" OFF)
|
option(SYSTEMD_SUPPORT "Enable systemd notify and journal logging" OFF)
|
||||||
@@ -25,6 +25,24 @@ option(ADC_STRESS "Enable the stress tester client" OFF)
|
|||||||
find_package(Git)
|
find_package(Git)
|
||||||
find_package(Sqlite3)
|
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)
|
||||||
find_package(OpenSSL)
|
find_package(OpenSSL)
|
||||||
@@ -32,14 +50,10 @@ 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 (LINK_SUPPORT)
|
|
||||||
add_definitions(-DLINK_SUPPORT)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (SYSTEMD_SUPPORT)
|
if (SYSTEMD_SUPPORT)
|
||||||
INCLUDE(FindPkgConfig)
|
INCLUDE(FindPkgConfig)
|
||||||
pkg_search_module(SD_DAEMON REQUIRED libsystemd-daemon)
|
pkg_search_module(SD_DAEMON REQUIRED libsystemd-daemon)
|
||||||
@@ -50,8 +64,18 @@ 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(${SQLITE3_INCLUDE_DIRS})
|
include_directories(${SQLITE3_INCLUDE_DIRS})
|
||||||
|
link_directories(${SQLITE3_LIBRARY_DIRS})
|
||||||
|
|
||||||
file (GLOB uhub_SOURCES ${PROJECT_SOURCE_DIR}/core/*.c)
|
file (GLOB uhub_SOURCES ${PROJECT_SOURCE_DIR}/core/*.c)
|
||||||
list (REMOVE_ITEM uhub_SOURCES
|
list (REMOVE_ITEM uhub_SOURCES
|
||||||
@@ -71,7 +95,7 @@ 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_COMPILER_IS_GNUCC)
|
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(utils PROPERTIES COMPILE_FLAGS -fPIC)
|
||||||
set_target_properties(network PROPERTIES COMPILE_FLAGS -fPIC)
|
set_target_properties(network PROPERTIES COMPILE_FLAGS -fPIC)
|
||||||
endif()
|
endif()
|
||||||
@@ -88,6 +112,7 @@ add_library(mod_welcome MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_welcome.c)
|
|||||||
add_library(mod_logging MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_logging.c ${PROJECT_SOURCE_DIR}/adc/sid.c)
|
add_library(mod_logging MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_logging.c ${PROJECT_SOURCE_DIR}/adc/sid.c)
|
||||||
add_library(mod_auth_simple MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_auth_simple.c )
|
add_library(mod_auth_simple MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_auth_simple.c )
|
||||||
add_library(mod_chat_history MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_chat_history.c )
|
add_library(mod_chat_history MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_chat_history.c )
|
||||||
|
add_library(mod_chat_history_sqlite MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_chat_history_sqlite.c )
|
||||||
add_library(mod_chat_only MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_chat_only.c)
|
add_library(mod_chat_only MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_chat_only.c)
|
||||||
add_library(mod_topic MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_topic.c)
|
add_library(mod_topic MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_topic.c)
|
||||||
add_library(mod_no_guest_downloads MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_no_guest_downloads.c)
|
add_library(mod_no_guest_downloads MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_no_guest_downloads.c)
|
||||||
@@ -107,6 +132,7 @@ set_target_properties(
|
|||||||
mod_auth_simple
|
mod_auth_simple
|
||||||
mod_auth_sqlite
|
mod_auth_sqlite
|
||||||
mod_chat_history
|
mod_chat_history
|
||||||
|
mod_chat_history_sqlite
|
||||||
mod_chat_only
|
mod_chat_only
|
||||||
mod_no_guest_downloads
|
mod_no_guest_downloads
|
||||||
mod_topic
|
mod_topic
|
||||||
@@ -120,6 +146,7 @@ target_link_libraries(mod_welcome utils)
|
|||||||
target_link_libraries(mod_auth_simple utils)
|
target_link_libraries(mod_auth_simple utils)
|
||||||
target_link_libraries(mod_auth_sqlite ${SQLITE3_LIBRARIES} utils)
|
target_link_libraries(mod_auth_sqlite ${SQLITE3_LIBRARIES} utils)
|
||||||
target_link_libraries(mod_chat_history 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_no_guest_downloads utils)
|
||||||
target_link_libraries(mod_chat_only utils)
|
target_link_libraries(mod_chat_only utils)
|
||||||
target_link_libraries(mod_logging utils)
|
target_link_libraries(mod_logging utils)
|
||||||
@@ -197,19 +224,24 @@ if (SYSTEMD_SUPPORT)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
configure_file ("${PROJECT_SOURCE_DIR}/version.h.in" "${PROJECT_SOURCE_DIR}/version.h")
|
configure_file ("${PROJECT_SOURCE_DIR}/version.h.in" "${PROJECT_SOURCE_DIR}/version.h")
|
||||||
|
configure_file ("${PROJECT_SOURCE_DIR}/system.h.in" "${PROJECT_SOURCE_DIR}/system.h")
|
||||||
|
|
||||||
mark_as_advanced(FORCE CMAKE_BUILD_TYPE)
|
# mark_as_advanced(FORCE CMAKE_BUILD_TYPE)
|
||||||
if (RELEASE)
|
# if (RELEASE)
|
||||||
set(CMAKE_BUILD_TYPE Release)
|
# set(CMAKE_BUILD_TYPE Release)
|
||||||
add_definitions(-DNDEBUG)
|
# add_definitions(-DNDEBUG)
|
||||||
else()
|
#else()
|
||||||
set(CMAKE_BUILD_TYPE Debug)
|
# set(CMAKE_BUILD_TYPE Debug)
|
||||||
add_definitions(-DDEBUG)
|
# add_definitions(-DDEBUG)
|
||||||
|
#endif()
|
||||||
|
|
||||||
|
if (LOWLEVEL_DEBUG)
|
||||||
|
add_definitions(-DLOWLEVEL_DEBUG)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (UNIX)
|
if (UNIX)
|
||||||
install( TARGETS uhub uhub-passwd 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 mod_no_guest_downloads DESTINATION /usr/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}/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 )
|
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 )
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
20
ChangeLog
20
ChangeLog
@@ -1,3 +1,23 @@
|
|||||||
|
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:
|
0.4.1:
|
||||||
- Converted to CMake which replaces Visual Studio project files and GNU makefiles
|
- Converted to CMake which replaces Visual Studio project files and GNU makefiles
|
||||||
- Fix issues with SSL causing excessive CPU usage.
|
- Fix issues with SSL causing excessive CPU usage.
|
||||||
|
|||||||
@@ -516,6 +516,15 @@ int main(int argc, char** argv)
|
|||||||
exotic_add_test(&handle, &exotic_test_list_get_last_prev_2, "list_get_last_prev_2");
|
exotic_add_test(&handle, &exotic_test_list_get_last_prev_2, "list_get_last_prev_2");
|
||||||
exotic_add_test(&handle, &exotic_test_list_get_last_prev_next_1, "list_get_last_prev_next_1");
|
exotic_add_test(&handle, &exotic_test_list_get_last_prev_next_1, "list_get_last_prev_next_1");
|
||||||
exotic_add_test(&handle, &exotic_test_list_clear, "list_clear");
|
exotic_add_test(&handle, &exotic_test_list_clear, "list_clear");
|
||||||
|
exotic_add_test(&handle, &exotic_test_list_remove_first_1_1, "list_remove_first_1_1");
|
||||||
|
exotic_add_test(&handle, &exotic_test_list_remove_first_1_2, "list_remove_first_1_2");
|
||||||
|
exotic_add_test(&handle, &exotic_test_list_remove_first_1_3, "list_remove_first_1_3");
|
||||||
|
exotic_add_test(&handle, &exotic_test_list_remove_first_1_4, "list_remove_first_1_4");
|
||||||
|
exotic_add_test(&handle, &exotic_test_list_remove_first_1_5, "list_remove_first_1_5");
|
||||||
|
exotic_add_test(&handle, &exotic_test_list_append_list_1, "list_append_list_1");
|
||||||
|
exotic_add_test(&handle, &exotic_test_list_append_list_2, "list_append_list_2");
|
||||||
|
exotic_add_test(&handle, &exotic_test_list_append_list_3, "list_append_list_3");
|
||||||
|
exotic_add_test(&handle, &exotic_test_list_clear_list_last, "list_clear_list_last");
|
||||||
exotic_add_test(&handle, &exotic_test_list_destroy_1, "list_destroy_1");
|
exotic_add_test(&handle, &exotic_test_list_destroy_1, "list_destroy_1");
|
||||||
exotic_add_test(&handle, &exotic_test_list_destroy_2, "list_destroy_2");
|
exotic_add_test(&handle, &exotic_test_list_destroy_2, "list_destroy_2");
|
||||||
exotic_add_test(&handle, &exotic_test_test_message_refc_1, "test_message_refc_1");
|
exotic_add_test(&handle, &exotic_test_test_message_refc_1, "test_message_refc_1");
|
||||||
@@ -723,7 +732,8 @@ int main(int argc, char** argv)
|
|||||||
exotic_add_test(&handle, &exotic_test_rbtree_size_4, "rbtree_size_4");
|
exotic_add_test(&handle, &exotic_test_rbtree_size_4, "rbtree_size_4");
|
||||||
exotic_add_test(&handle, &exotic_test_rbtree_check_10000, "rbtree_check_10000");
|
exotic_add_test(&handle, &exotic_test_rbtree_check_10000, "rbtree_check_10000");
|
||||||
exotic_add_test(&handle, &exotic_test_rbtree_iterate_10000, "rbtree_iterate_10000");
|
exotic_add_test(&handle, &exotic_test_rbtree_iterate_10000, "rbtree_iterate_10000");
|
||||||
exotic_add_test(&handle, &exotic_test_rbtree_remove_5000, "rbtree_remove_5000");
|
exotic_add_test(&handle, &exotic_test_rbtree_remove_10000, "rbtree_remove_10000");
|
||||||
|
exotic_add_test(&handle, &exotic_test_rbtree_destroy_1, "rbtree_destroy_1");
|
||||||
exotic_add_test(&handle, &exotic_test_sid_create_pool, "sid_create_pool");
|
exotic_add_test(&handle, &exotic_test_sid_create_pool, "sid_create_pool");
|
||||||
exotic_add_test(&handle, &exotic_test_sid_check_0a, "sid_check_0a");
|
exotic_add_test(&handle, &exotic_test_sid_check_0a, "sid_check_0a");
|
||||||
exotic_add_test(&handle, &exotic_test_sid_check_0b, "sid_check_0b");
|
exotic_add_test(&handle, &exotic_test_sid_check_0b, "sid_check_0b");
|
||||||
@@ -761,6 +771,7 @@ int main(int argc, char** argv)
|
|||||||
exotic_add_test(&handle, &exotic_test_timer_add_5_events_1, "timer_add_5_events_1");
|
exotic_add_test(&handle, &exotic_test_timer_add_5_events_1, "timer_add_5_events_1");
|
||||||
exotic_add_test(&handle, &exotic_test_timer_check_5_events_1, "timer_check_5_events_1");
|
exotic_add_test(&handle, &exotic_test_timer_check_5_events_1, "timer_check_5_events_1");
|
||||||
exotic_add_test(&handle, &exotic_test_timer_process_5_events_1, "timer_process_5_events_1");
|
exotic_add_test(&handle, &exotic_test_timer_process_5_events_1, "timer_process_5_events_1");
|
||||||
|
exotic_add_test(&handle, &exotic_test_timer_shutdown, "timer_shutdown");
|
||||||
exotic_add_test(&handle, &exotic_test_tokenizer_basic_0, "tokenizer_basic_0");
|
exotic_add_test(&handle, &exotic_test_tokenizer_basic_0, "tokenizer_basic_0");
|
||||||
exotic_add_test(&handle, &exotic_test_tokenizer_basic_1, "tokenizer_basic_1");
|
exotic_add_test(&handle, &exotic_test_tokenizer_basic_1, "tokenizer_basic_1");
|
||||||
exotic_add_test(&handle, &exotic_test_tokenizer_basic_1a, "tokenizer_basic_1a");
|
exotic_add_test(&handle, &exotic_test_tokenizer_basic_1a, "tokenizer_basic_1a");
|
||||||
@@ -951,7 +962,6 @@ int exotic_initialize(struct exotic_handle* handle, int argc, char** argv)
|
|||||||
void exotic_add_test(struct exotic_handle* handle, exo_test_t func, const char* name)
|
void exotic_add_test(struct exotic_handle* handle, exo_test_t func, const char* name)
|
||||||
{
|
{
|
||||||
struct exo_test_data* test;
|
struct exo_test_data* test;
|
||||||
|
|
||||||
if (!handle)
|
if (!handle)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "exotic_add_test: failed, no handle!\n");
|
fprintf(stderr, "exotic_add_test: failed, no handle!\n");
|
||||||
|
|||||||
@@ -14,10 +14,8 @@ static void inf_create_hub()
|
|||||||
{
|
{
|
||||||
net_initialize();
|
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));
|
||||||
|
|
||||||
@@ -27,12 +25,9 @@ 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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ EXO_TEST(rbtree_size_3, { return rb_tree_size(tree) == 0; });
|
|||||||
|
|
||||||
EXO_TEST(rbtree_insert_10000, {
|
EXO_TEST(rbtree_insert_10000, {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < MAX_NODES ; i++)
|
for (i = 0; i < MAX_NODES; i++)
|
||||||
{
|
{
|
||||||
const char* key = strdup(uhub_itoa(i));
|
const char* key = strdup(uhub_itoa(i));
|
||||||
const char* val = strdup(uhub_itoa(i + 16384));
|
const char* val = strdup(uhub_itoa(i + 16384));
|
||||||
@@ -96,11 +96,11 @@ EXO_TEST(rbtree_insert_10000, {
|
|||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
EXO_TEST(rbtree_size_4, { return rb_tree_size(tree) == MAX_NODES ; });
|
EXO_TEST(rbtree_size_4, { return rb_tree_size(tree) == MAX_NODES; });
|
||||||
|
|
||||||
EXO_TEST(rbtree_check_10000, {
|
EXO_TEST(rbtree_check_10000, {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < MAX_NODES ; i++)
|
for (i = 0; i < MAX_NODES; i++)
|
||||||
{
|
{
|
||||||
char* key = strdup(uhub_itoa(i));
|
char* key = strdup(uhub_itoa(i));
|
||||||
const char* expect = uhub_itoa(i + 16384);
|
const char* expect = uhub_itoa(i + 16384);
|
||||||
@@ -116,29 +116,35 @@ EXO_TEST(rbtree_iterate_10000, {
|
|||||||
struct rb_node* n = (struct rb_node*) rb_tree_first(tree);
|
struct rb_node* n = (struct rb_node*) rb_tree_first(tree);
|
||||||
while (n)
|
while (n)
|
||||||
{
|
{
|
||||||
struct rb_node* p = n;
|
|
||||||
n = (struct rb_node*) rb_tree_next(tree);
|
n = (struct rb_node*) rb_tree_next(tree);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
return i == MAX_NODES ;
|
return i == MAX_NODES;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
static int freed_nodes = 0;
|
||||||
static void free_node(struct rb_node* n)
|
static void free_node(struct rb_node* n)
|
||||||
{
|
{
|
||||||
hub_free((void*) n->key);
|
hub_free((void*) n->key);
|
||||||
hub_free((void*) n->value);
|
hub_free((void*) n->value);
|
||||||
|
freed_nodes += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXO_TEST(rbtree_remove_5000, {
|
EXO_TEST(rbtree_remove_10000, {
|
||||||
int i = 0;
|
int i;
|
||||||
struct rb_node* n = (struct rb_node*) rb_tree_first(tree);
|
int j;
|
||||||
for (i = 0; i < MAX_NODES ; i += 2)
|
for (j = 0; j < 2; j++)
|
||||||
|
{
|
||||||
|
for (i = j; i < MAX_NODES; i += 2)
|
||||||
{
|
{
|
||||||
const char* key = uhub_itoa(i);
|
const char* key = uhub_itoa(i);
|
||||||
rb_tree_remove_node(tree, key, &free_node);
|
rb_tree_remove_node(tree, key, &free_node);
|
||||||
}
|
}
|
||||||
return 1;
|
}
|
||||||
|
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;
|
||||||
|
});
|
||||||
|
|||||||
38
autotest/travis/build-and-test.sh
Executable file
38
autotest/travis/build-and-test.sh
Executable file
@@ -0,0 +1,38 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -x
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
@@ -44,6 +44,7 @@ IF ( NOT SQLITE3_FOUND AND NOT PKG_CONFIG_FOUND )
|
|||||||
/opt/local/lib
|
/opt/local/lib
|
||||||
/sw/lib
|
/sw/lib
|
||||||
/usr/lib
|
/usr/lib
|
||||||
|
/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}
|
||||||
/usr/local/lib
|
/usr/local/lib
|
||||||
/usr/lib64
|
/usr/lib64
|
||||||
/usr/local/lib64
|
/usr/local/lib64
|
||||||
|
|||||||
@@ -13,6 +13,15 @@
|
|||||||
#
|
#
|
||||||
plugin /usr/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
|
||||||
#
|
#
|
||||||
@@ -22,7 +31,8 @@ plugin /usr/lib/uhub/mod_auth_sqlite.so "file=/etc/uhub/users.db"
|
|||||||
plugin /usr/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 /usr/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:
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2013, 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
|
||||||
@@ -34,7 +34,6 @@ typedef uint32_t fourcc_t;
|
|||||||
|
|
||||||
/* default welcome protocol support message, as sent by this server */
|
/* default welcome protocol support message, as sent by this server */
|
||||||
#define ADC_PROTO_SUPPORT "ADBASE ADTIGR ADPING ADUCMD"
|
#define ADC_PROTO_SUPPORT "ADBASE ADTIGR ADPING ADUCMD"
|
||||||
#define ADC_PROTO_LINK_SUPPORT "ADTIGR ADLINK"
|
|
||||||
|
|
||||||
/* Server sent commands */
|
/* Server sent commands */
|
||||||
#define ADC_CMD_ISID FOURCC('I','S','I','D')
|
#define ADC_CMD_ISID FOURCC('I','S','I','D')
|
||||||
@@ -102,12 +101,6 @@ typedef uint32_t fourcc_t;
|
|||||||
#define ADC_CMD_HCMD FOURCC('H','C','M','D')
|
#define ADC_CMD_HCMD FOURCC('H','C','M','D')
|
||||||
#define ADC_CMD_ICMD FOURCC('I','C','M','D')
|
#define ADC_CMD_ICMD FOURCC('I','C','M','D')
|
||||||
|
|
||||||
/* Link commands */
|
|
||||||
#define ADC_CMD_LSUP FOURCC('L','S','U','P') /* Link support handshake */
|
|
||||||
#define ADC_CMD_LINF FOURCC('L','I','N','F') /* Hub link info */
|
|
||||||
#define ADC_CMD_LGPA FOURCC('L','G','P','A') /* Hub link get password */
|
|
||||||
#define ADC_CMD_LPAS FOURCC('L','P','A','S') /* Hub link password */
|
|
||||||
#define ADC_CMD_LSTA FOURCC('L','S','T','A') /* Hub link status */
|
|
||||||
|
|
||||||
#define ADC_INF_FLAG_IPV4_ADDR "I4" /* ipv4 address */
|
#define ADC_INF_FLAG_IPV4_ADDR "I4" /* ipv4 address */
|
||||||
#define ADC_INF_FLAG_IPV6_ADDR "I6" /* ipv6 address */
|
#define ADC_INF_FLAG_IPV6_ADDR "I6" /* ipv6 address */
|
||||||
@@ -118,7 +111,10 @@ 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 */
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2013, 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
|
||||||
@@ -178,7 +178,6 @@ int adc_msg_get_arg_offset(struct adc_message* msg)
|
|||||||
|
|
||||||
case 'I':
|
case 'I':
|
||||||
case 'H':
|
case 'H':
|
||||||
case 'L':
|
|
||||||
return 4;
|
return 4;
|
||||||
|
|
||||||
case 'B':
|
case 'B':
|
||||||
@@ -284,23 +283,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);
|
||||||
@@ -384,9 +379,8 @@ struct adc_message* adc_msg_parse(const char* line, size_t length)
|
|||||||
ok = 0;
|
ok = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'I': /* Hub to client */
|
case 'I':
|
||||||
case 'H': /* Clien to hub */
|
case 'H':
|
||||||
case 'L': /* hub to hub Link */
|
|
||||||
ok = (length > 3);
|
ok = (length > 3);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -789,16 +783,6 @@ int adc_msg_add_argument(struct adc_message* cmd, const char* string)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int adc_msg_add_argument_string(struct adc_message* cmd, const char* string)
|
|
||||||
{
|
|
||||||
char* arg = adc_msg_escape(string);
|
|
||||||
int ret;
|
|
||||||
if (!arg) return -1;
|
|
||||||
ret = adc_msg_add_argument(cmd, arg);
|
|
||||||
hub_free(arg);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
char* adc_msg_get_argument(struct adc_message* cmd, int offset)
|
char* adc_msg_get_argument(struct adc_message* cmd, int offset)
|
||||||
{
|
{
|
||||||
@@ -880,21 +864,21 @@ int adc_msg_get_argument_index(struct adc_message* cmd, const char prefix[2])
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
size_t adc_msg_escape_length(const char* str)
|
int adc_msg_escape_length(const char* str)
|
||||||
{
|
{
|
||||||
size_t add = 0;
|
int add = 0;
|
||||||
size_t n = 0;
|
int n = 0;
|
||||||
for (; str[n]; n++)
|
for (; str[n]; n++)
|
||||||
if (str[n] == ' ' || str[n] == '\n' || str[n] == '\\') add++;
|
if (str[n] == ' ' || str[n] == '\n' || str[n] == '\\') add++;
|
||||||
return n + add;
|
return n + add;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t adc_msg_unescape_length(const char* str)
|
int adc_msg_unescape_length(const char* str)
|
||||||
{
|
{
|
||||||
size_t add = 0;
|
int add = 0;
|
||||||
size_t n = 0;
|
int n = 0;
|
||||||
size_t escape = 0;
|
int escape = 0;
|
||||||
for (; str[n]; n++)
|
for (; str[n]; n++)
|
||||||
{
|
{
|
||||||
if (escape)
|
if (escape)
|
||||||
@@ -1010,20 +994,3 @@ char* adc_msg_escape(const char* string)
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum msg_type adc_msg_get_type(const struct adc_message* msg)
|
|
||||||
{
|
|
||||||
switch (msg->cache[0])
|
|
||||||
{
|
|
||||||
case 'B': return msg_type_client_broadcast;
|
|
||||||
case 'C': return msg_type_client_to_client;
|
|
||||||
case 'D': return msg_type_client_direct;
|
|
||||||
case 'E': return msg_type_client_echo;
|
|
||||||
case 'F': return msg_type_client_feature;
|
|
||||||
case 'H': return msg_type_client_to_hub;
|
|
||||||
case 'I': return msg_type_hub_to_client;
|
|
||||||
case 'L': return msg_type_link_to_link;
|
|
||||||
case 'U': return msg_type_hub_to_client_udp;
|
|
||||||
}
|
|
||||||
return msg_type_unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2013, 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
|
||||||
@@ -43,20 +43,6 @@ enum msg_status_level
|
|||||||
status_level_fatal = 2, /* Fatal error (disconnect) */
|
status_level_fatal = 2, /* Fatal error (disconnect) */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum msg_type
|
|
||||||
{
|
|
||||||
msg_type_unknown = 0,
|
|
||||||
msg_type_client_broadcast = 'B',
|
|
||||||
msg_type_client_to_client = 'C',
|
|
||||||
msg_type_client_direct = 'D',
|
|
||||||
msg_type_client_echo = 'E',
|
|
||||||
msg_type_client_feature = 'F',
|
|
||||||
msg_type_client_to_hub = 'H',
|
|
||||||
msg_type_hub_to_client = 'I',
|
|
||||||
msg_type_link_to_link = 'L',
|
|
||||||
msg_type_hub_to_client_udp = 'U',
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Increase the reference counter for an ADC message struct.
|
* Increase the reference counter for an ADC message struct.
|
||||||
* NOTE: Always use the returned value, and not the passed value, as
|
* NOTE: Always use the returned value, and not the passed value, as
|
||||||
@@ -185,13 +171,6 @@ extern int adc_msg_replace_named_argument(struct adc_message* cmd, const char pr
|
|||||||
*/
|
*/
|
||||||
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);
|
||||||
|
|
||||||
/**
|
|
||||||
* Append a string argumnent.
|
|
||||||
* The string will automatcally be escaped.
|
|
||||||
* @return 0 if successful, or -1 if an error occured (out of memory).
|
|
||||||
*/
|
|
||||||
extern int adc_msg_add_argument_string(struct adc_message* cmd, const char* string);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append a named argument
|
* Append a named argument
|
||||||
*
|
*
|
||||||
@@ -237,12 +216,6 @@ extern int adc_msg_unescape_to_target(const char* string, char* target, size_t t
|
|||||||
*/
|
*/
|
||||||
extern char* adc_msg_escape(const char* string);
|
extern char* adc_msg_escape(const char* string);
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate the length str would be after escaping.
|
|
||||||
* Does not include any NULL terminator.
|
|
||||||
*/
|
|
||||||
size_t adc_msg_escape_length(const char* str);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This will ensure a newline is at the end of the command.
|
* This will ensure a newline is at the end of the command.
|
||||||
*/
|
*/
|
||||||
@@ -261,6 +234,4 @@ void adc_msg_unterminate(struct adc_message* cmd);
|
|||||||
*/
|
*/
|
||||||
int adc_msg_get_arg_offset(struct adc_message* msg);
|
int adc_msg_get_arg_offset(struct adc_message* msg);
|
||||||
|
|
||||||
enum msg_type adc_msg_get_type(const struct adc_message* msg);
|
|
||||||
|
|
||||||
#endif /* HAVE_UHUB_COMMAND_H */
|
#endif /* HAVE_UHUB_COMMAND_H */
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2009, Jan Vidar Krey
|
* Copyright (C) 2007-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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -330,13 +330,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 +398,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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -102,7 +102,7 @@ static int config_parse_line(char* line, int line_count, void* ptr_data)
|
|||||||
data = strip_white_space(data);
|
data = strip_white_space(data);
|
||||||
data = strip_off_quotes(data);
|
data = strip_off_quotes(data);
|
||||||
|
|
||||||
if (!*key /*|| !*data*/)
|
if (!*key || !*data)
|
||||||
{
|
{
|
||||||
LOG_FATAL("Configuration parse error on line %d", line_count);
|
LOG_FATAL("Configuration parse error on line %d", line_count);
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
* Copyright (C) 2007-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
|
||||||
|
|||||||
@@ -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.
|
||||||
@@ -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.
|
||||||
@@ -165,36 +165,6 @@
|
|||||||
<since>0.3.2</since>
|
<since>0.3.2</since>
|
||||||
</option>
|
</option>
|
||||||
|
|
||||||
<option name="hub_link_enabled" type="boolean" default="0">
|
|
||||||
<short>Allow other hubs to link to this hub</short>
|
|
||||||
<description><![CDATA[
|
|
||||||
This allows multiple hubs to link to this hub so
|
|
||||||
that users on the different hubs appear as being on one hub.
|
|
||||||
This is useful for distributing or load balancing large hubs.
|
|
||||||
]]></description>
|
|
||||||
<since>0.5.0</since>
|
|
||||||
<ifdef>LINK_SUPPORT</ifdef>
|
|
||||||
</option>
|
|
||||||
|
|
||||||
<option name="hub_link_secret" type="string" default="">
|
|
||||||
<short>A secret token required to accept hub linking</short>
|
|
||||||
<description><![CDATA[
|
|
||||||
This should be a secret token needed to authorize hubs
|
|
||||||
linking into this one.
|
|
||||||
]]></description>
|
|
||||||
<since>0.5.0</since>
|
|
||||||
<ifdef>LINK_SUPPORT</ifdef>
|
|
||||||
</option>
|
|
||||||
|
|
||||||
<option name="hub_link_connect" type="string" default="">
|
|
||||||
<short>Connect this to hub to another hub</short>
|
|
||||||
<description><![CDATA[
|
|
||||||
The other hub must allow links to be established.
|
|
||||||
Example: uhub://host:port
|
|
||||||
]]></description>
|
|
||||||
<since>0.5.0</since>
|
|
||||||
<ifdef>LINK_SUPPORT</ifdef>
|
|
||||||
</option>
|
|
||||||
|
|
||||||
<option name="max_recv_buffer" type="int" default="4096" advanced="true" >
|
<option name="max_recv_buffer" type="int" default="4096" advanced="true" >
|
||||||
<check min="1024" max="1048576" />
|
<check min="1024" max="1048576" />
|
||||||
@@ -449,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.
|
||||||
@@ -458,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>
|
||||||
@@ -475,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[
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
@@ -17,15 +23,6 @@ void config_defaults(struct hub_config* config)
|
|||||||
config->hub_name = hub_strdup("uhub");
|
config->hub_name = hub_strdup("uhub");
|
||||||
config->hub_description = hub_strdup("no description");
|
config->hub_description = hub_strdup("no description");
|
||||||
config->redirect_addr = hub_strdup("");
|
config->redirect_addr = hub_strdup("");
|
||||||
#ifdef LINK_SUPPORT
|
|
||||||
config->hub_link_enabled = 0;
|
|
||||||
#endif /* LINK_SUPPORT */
|
|
||||||
#ifdef LINK_SUPPORT
|
|
||||||
config->hub_link_secret = hub_strdup("");
|
|
||||||
#endif /* LINK_SUPPORT */
|
|
||||||
#ifdef LINK_SUPPORT
|
|
||||||
config->hub_link_connect = hub_strdup("");
|
|
||||||
#endif /* LINK_SUPPORT */
|
|
||||||
config->max_recv_buffer = 4096;
|
config->max_recv_buffer = 4096;
|
||||||
config->max_send_buffer = 131072;
|
config->max_send_buffer = 131072;
|
||||||
config->max_send_buffer_soft = 98304;
|
config->max_send_buffer_soft = 98304;
|
||||||
@@ -54,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");
|
||||||
@@ -254,42 +253,6 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LINK_SUPPORT
|
|
||||||
if (!strcmp(key, "hub_link_enabled"))
|
|
||||||
{
|
|
||||||
if (!apply_boolean(key, data, &config->hub_link_enabled))
|
|
||||||
{
|
|
||||||
LOG_ERROR("Configuration parse error on line %d", line_count);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* LINK_SUPPORT */
|
|
||||||
|
|
||||||
#ifdef LINK_SUPPORT
|
|
||||||
if (!strcmp(key, "hub_link_secret"))
|
|
||||||
{
|
|
||||||
if (!apply_string(key, data, &config->hub_link_secret, (char*) ""))
|
|
||||||
{
|
|
||||||
LOG_ERROR("Configuration parse error on line %d", line_count);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* LINK_SUPPORT */
|
|
||||||
|
|
||||||
#ifdef LINK_SUPPORT
|
|
||||||
if (!strcmp(key, "hub_link_connect"))
|
|
||||||
{
|
|
||||||
if (!apply_string(key, data, &config->hub_link_connect, (char*) ""))
|
|
||||||
{
|
|
||||||
LOG_ERROR("Configuration parse error on line %d", line_count);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* LINK_SUPPORT */
|
|
||||||
|
|
||||||
if (!strcmp(key, "max_recv_buffer"))
|
if (!strcmp(key, "max_recv_buffer"))
|
||||||
{
|
{
|
||||||
min = 1024;
|
min = 1024;
|
||||||
@@ -591,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*) ""))
|
||||||
@@ -988,20 +971,16 @@ void free_config(struct hub_config* config)
|
|||||||
|
|
||||||
hub_free(config->redirect_addr);
|
hub_free(config->redirect_addr);
|
||||||
|
|
||||||
#ifdef LINK_SUPPORT
|
|
||||||
hub_free(config->hub_link_secret);
|
|
||||||
#endif /* LINK_SUPPORT */
|
|
||||||
|
|
||||||
#ifdef LINK_SUPPORT
|
|
||||||
hub_free(config->hub_link_connect);
|
|
||||||
#endif /* LINK_SUPPORT */
|
|
||||||
|
|
||||||
hub_free(config->tls_require_redirect_addr);
|
hub_free(config->tls_require_redirect_addr);
|
||||||
|
|
||||||
hub_free(config->tls_certificate);
|
hub_free(config->tls_certificate);
|
||||||
|
|
||||||
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);
|
||||||
@@ -1127,21 +1106,6 @@ void dump_config(struct hub_config* config, int ignore_defaults)
|
|||||||
if (!ignore_defaults || strcmp(config->redirect_addr, "") != 0)
|
if (!ignore_defaults || strcmp(config->redirect_addr, "") != 0)
|
||||||
fprintf(stdout, "redirect_addr = \"%s\"\n", config->redirect_addr);
|
fprintf(stdout, "redirect_addr = \"%s\"\n", config->redirect_addr);
|
||||||
|
|
||||||
#ifdef LINK_SUPPORT
|
|
||||||
if (!ignore_defaults || config->hub_link_enabled != 0)
|
|
||||||
fprintf(stdout, "hub_link_enabled = %s\n", config->hub_link_enabled ? "yes" : "no");
|
|
||||||
#endif /* LINK_SUPPORT */
|
|
||||||
|
|
||||||
#ifdef LINK_SUPPORT
|
|
||||||
if (!ignore_defaults || strcmp(config->hub_link_secret, "") != 0)
|
|
||||||
fprintf(stdout, "hub_link_secret = \"%s\"\n", config->hub_link_secret);
|
|
||||||
#endif /* LINK_SUPPORT */
|
|
||||||
|
|
||||||
#ifdef LINK_SUPPORT
|
|
||||||
if (!ignore_defaults || strcmp(config->hub_link_connect, "") != 0)
|
|
||||||
fprintf(stdout, "hub_link_connect = \"%s\"\n", config->hub_link_connect);
|
|
||||||
#endif /* LINK_SUPPORT */
|
|
||||||
|
|
||||||
if (!ignore_defaults || config->max_recv_buffer != 4096)
|
if (!ignore_defaults || config->max_recv_buffer != 4096)
|
||||||
fprintf(stdout, "max_recv_buffer = %d\n", config->max_recv_buffer);
|
fprintf(stdout, "max_recv_buffer = %d\n", config->max_recv_buffer);
|
||||||
|
|
||||||
@@ -1226,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
|
||||||
{
|
{
|
||||||
@@ -17,15 +23,6 @@ struct hub_config
|
|||||||
char* hub_name; /*<<< Name of hub (default: "uhub") */
|
char* hub_name; /*<<< Name of hub (default: "uhub") */
|
||||||
char* hub_description; /*<<< Short hub description, topic or subject. (default: "no description") */
|
char* hub_description; /*<<< Short hub description, topic or subject. (default: "no description") */
|
||||||
char* redirect_addr; /*<<< A common hub redirect address. (default: "") */
|
char* redirect_addr; /*<<< A common hub redirect address. (default: "") */
|
||||||
#ifdef LINK_SUPPORT
|
|
||||||
int hub_link_enabled; /*<<< Allow other hubs to link to this hub (default: 0) */
|
|
||||||
#endif /* LINK_SUPPORT */
|
|
||||||
#ifdef LINK_SUPPORT
|
|
||||||
char* hub_link_secret; /*<<< A secret token required to accept hub linking (default: "") */
|
|
||||||
#endif /* LINK_SUPPORT */
|
|
||||||
#ifdef LINK_SUPPORT
|
|
||||||
char* hub_link_connect; /*<<< Connect this to hub to another hub (default: "") */
|
|
||||||
#endif /* LINK_SUPPORT */
|
|
||||||
int max_recv_buffer; /*<<< Max read buffer before parse, per user (default: 4096) */
|
int max_recv_buffer; /*<<< Max read buffer before parse, per user (default: 4096) */
|
||||||
int max_send_buffer; /*<<< Max send buffer before disconnect, per user (default: 131072) */
|
int max_send_buffer; /*<<< Max send buffer before disconnect, per user (default: 131072) */
|
||||||
int max_send_buffer_soft; /*<<< Max send buffer before message drops, per user (default: 98304) */
|
int max_send_buffer_soft; /*<<< Max send buffer before message drops, per user (default: 98304) */
|
||||||
@@ -54,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
|
||||||
@@ -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))
|
||||||
@@ -787,13 +791,6 @@ struct hub_info* hub_start_service(struct hub_config* config)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef LINK_SUPPORT
|
|
||||||
if (config->hub_link_enabled)
|
|
||||||
{
|
|
||||||
LOG_INFO("Hub linking support enabled");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
hub->config = config;
|
hub->config = config;
|
||||||
hub->users = NULL;
|
hub->users = NULL;
|
||||||
|
|
||||||
@@ -841,15 +838,6 @@ struct hub_info* hub_start_service(struct hub_config* config)
|
|||||||
|
|
||||||
// Start the hub command sub-system
|
// Start the hub command sub-system
|
||||||
hub->commands = command_initialize(hub);
|
hub->commands = command_initialize(hub);
|
||||||
|
|
||||||
#ifdef LINK_SUPPORT
|
|
||||||
if (*config->hub_link_connect)
|
|
||||||
{
|
|
||||||
link_connect_uri(hub, config->hub_link_connect);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
return hub;
|
return hub;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -913,14 +901,24 @@ void hub_plugins_unload(struct hub_info* hub)
|
|||||||
|
|
||||||
void hub_set_variables(struct hub_info* hub, struct acl_handle* acl)
|
void hub_set_variables(struct hub_info* hub, struct acl_handle* acl)
|
||||||
{
|
{
|
||||||
|
char* tmp;
|
||||||
|
char* server = adc_msg_escape(PRODUCT_STRING); /* FIXME: OOM */
|
||||||
|
|
||||||
hub->acl = acl;
|
hub->acl = acl;
|
||||||
hub->command_info = adc_msg_construct(ADC_CMD_IINF, 15);
|
hub->command_info = adc_msg_construct(ADC_CMD_IINF, 15);
|
||||||
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_string(hub->command_info, ADC_INF_FLAG_USER_AGENT, PRODUCT_STRING);
|
adc_msg_add_named_argument(hub->command_info, ADC_INF_FLAG_USER_AGENT_PRODUCT, PRODUCT);
|
||||||
adc_msg_add_named_argument_string(hub->command_info, ADC_INF_FLAG_NICK, hub->config->hub_name);
|
adc_msg_add_named_argument(hub->command_info, ADC_INF_FLAG_USER_AGENT_VERSION, GIT_VERSION);
|
||||||
adc_msg_add_named_argument_string(hub->command_info, ADC_INF_FLAG_DESCRIPTION, hub->config->hub_description);
|
|
||||||
|
tmp = adc_msg_escape(hub->config->hub_name);
|
||||||
|
adc_msg_add_named_argument(hub->command_info, ADC_INF_FLAG_NICK, tmp);
|
||||||
|
hub_free(tmp);
|
||||||
|
|
||||||
|
tmp = adc_msg_escape(hub->config->hub_description);
|
||||||
|
adc_msg_add_named_argument(hub->command_info, ADC_INF_FLAG_DESCRIPTION, tmp);
|
||||||
|
hub_free(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
hub->command_support = adc_msg_construct(ADC_CMD_ISUP, 6 + strlen(ADC_PROTO_SUPPORT));
|
hub->command_support = adc_msg_construct(ADC_CMD_ISUP, 6 + strlen(ADC_PROTO_SUPPORT));
|
||||||
@@ -929,14 +927,16 @@ void hub_set_variables(struct hub_info* hub, struct acl_handle* acl)
|
|||||||
adc_msg_add_argument(hub->command_support, ADC_PROTO_SUPPORT);
|
adc_msg_add_argument(hub->command_support, ADC_PROTO_SUPPORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
hub->command_banner = adc_msg_construct(ADC_CMD_ISTA, 100 + adc_msg_escape_length(PRODUCT_STRING));
|
hub->command_banner = adc_msg_construct(ADC_CMD_ISTA, 100 + strlen(server));
|
||||||
if (hub->command_banner)
|
if (hub->command_banner)
|
||||||
{
|
{
|
||||||
adc_msg_add_argument(hub->command_banner, "000");
|
|
||||||
if (hub->config->show_banner_sys_info)
|
if (hub->config->show_banner_sys_info)
|
||||||
adc_msg_add_argument_string(hub->command_banner, "Powered by " PRODUCT_STRING " on " OPSYS "/" CPUINFO);
|
tmp = adc_msg_escape("Powered by " PRODUCT_STRING " on " OPSYS "/" CPUINFO);
|
||||||
else
|
else
|
||||||
adc_msg_add_argument_string(hub->command_banner, "Powered by " PRODUCT_STRING);
|
tmp = adc_msg_escape("Powered by " PRODUCT_STRING);
|
||||||
|
adc_msg_add_argument(hub->command_banner, "000");
|
||||||
|
adc_msg_add_argument(hub->command_banner, tmp);
|
||||||
|
hub_free(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hub_plugins_load(hub) < 0)
|
if (hub_plugins_load(hub) < 0)
|
||||||
@@ -947,6 +947,7 @@ void hub_set_variables(struct hub_info* hub, struct acl_handle* acl)
|
|||||||
else
|
else
|
||||||
|
|
||||||
hub->status = (hub->config->hub_enabled ? hub_status_running : hub_status_disabled);
|
hub->status = (hub->config->hub_enabled ? hub_status_running : hub_status_disabled);
|
||||||
|
hub_free(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1324,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
|
||||||
@@ -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 */
|
||||||
@@ -115,10 +115,6 @@ struct hub_info
|
|||||||
struct command_base* commands; /* Hub command handler */
|
struct command_base* commands; /* Hub command handler */
|
||||||
struct uhub_plugins* plugins; /* Plug-ins loaded for this hub instance. */
|
struct uhub_plugins* plugins; /* Plug-ins loaded for this hub instance. */
|
||||||
|
|
||||||
#ifdef LINK_SUPPORT
|
|
||||||
struct linked_list* hub_links; /* Other hubs linked to this hub */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SSL_SUPPORT
|
#ifdef SSL_SUPPORT
|
||||||
struct ssl_context_handle* ctx;
|
struct ssl_context_handle* ctx;
|
||||||
#endif /* SSL_SUPPORT */
|
#endif /* SSL_SUPPORT */
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -366,21 +366,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -622,7 +638,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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -49,34 +49,6 @@ void ioq_recv_destroy(struct ioq_recv* q)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define IOQ_RECV_FLAGS_PREALLOC 1
|
|
||||||
#define IOQ_RECV_FLAGS_FULL 2
|
|
||||||
|
|
||||||
enum ioq_recv_status ioq_recv_read(struct ioq_recv* q, struct net_connection* con)
|
|
||||||
{
|
|
||||||
static char buf[MAX_RECV_BUF];
|
|
||||||
size_t buf_size = ioq_recv_get(q, buf, MAX_RECV_BUF);
|
|
||||||
ssize_t size;
|
|
||||||
|
|
||||||
if (buf_size >= MAX_RECV_BUF)
|
|
||||||
return ioq_recv_full;
|
|
||||||
|
|
||||||
size = net_con_recv(con, buf + buf_size, MAX_RECV_BUF - buf_size);
|
|
||||||
|
|
||||||
if (size > 0)
|
|
||||||
buf_size += size;
|
|
||||||
if (size < 0)
|
|
||||||
return ioq_recv_error;
|
|
||||||
if (size == 0)
|
|
||||||
return ioq_recv_later;
|
|
||||||
|
|
||||||
ioq_recv_set(q, buf, buf_size);
|
|
||||||
return ioq_recv_ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
size_t ioq_recv_get(struct ioq_recv* q, void* buf, size_t bufsize)
|
size_t ioq_recv_get(struct ioq_recv* q, void* buf, size_t bufsize)
|
||||||
{
|
{
|
||||||
uhub_assert(bufsize >= q->size);
|
uhub_assert(bufsize >= q->size);
|
||||||
@@ -116,21 +88,6 @@ size_t ioq_recv_set(struct ioq_recv* q, void* buf, size_t bufsize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int ioq_recv_consume(struct ioq_recv* q, size_t bytes)
|
|
||||||
{
|
|
||||||
size_t newsize;
|
|
||||||
void* ptr;
|
|
||||||
|
|
||||||
if (!q || bytes > q->size) return 0;
|
|
||||||
|
|
||||||
newsize = (q->size - bytes);
|
|
||||||
memmove(q->buf, q->buf + bytes, newsize);
|
|
||||||
ptr = hub_realloc(q->buf, newsize);
|
|
||||||
q->buf = ptr;
|
|
||||||
q->size = newsize;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ioq_send* ioq_send_create()
|
struct ioq_send* ioq_send_create()
|
||||||
{
|
{
|
||||||
struct ioq_send* q = hub_malloc_zero(sizeof(struct ioq_send));
|
struct ioq_send* q = hub_malloc_zero(sizeof(struct ioq_send));
|
||||||
@@ -173,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
|
||||||
@@ -39,7 +39,6 @@ struct ioq_recv
|
|||||||
{
|
{
|
||||||
char* buf;
|
char* buf;
|
||||||
size_t size;
|
size_t size;
|
||||||
// int flags;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -103,26 +102,5 @@ extern size_t ioq_recv_set(struct ioq_recv*, void* buf, size_t bufsize);
|
|||||||
extern int ioq_recv_is_empty(struct ioq_recv* buf);
|
extern int ioq_recv_is_empty(struct ioq_recv* buf);
|
||||||
|
|
||||||
|
|
||||||
enum ioq_recv_status
|
|
||||||
{
|
|
||||||
ioq_recv_ok = 0, // read data OK
|
|
||||||
ioq_recv_later = 1, // all OK, but call again later (no change)
|
|
||||||
ioq_recv_full = 2, // all OK, but the buffer is full
|
|
||||||
ioq_recv_error = 3, // error (connection is not working)
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Receive from connection into buffer.
|
|
||||||
*/
|
|
||||||
extern enum ioq_recv_status ioq_recv_read(struct ioq_recv* q, struct net_connection* con);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Consume 'bytes' bytes.
|
|
||||||
* 'bytes' must be <= q->size
|
|
||||||
*
|
|
||||||
* @return 1 on success, or 0 on error (only if q == NULL or bytes is > q->size).
|
|
||||||
*/
|
|
||||||
extern int ioq_recv_consume(struct ioq_recv* q, size_t bytes);
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* HAVE_UHUB_IO_QUEUE_H */
|
#endif /* HAVE_UHUB_IO_QUEUE_H */
|
||||||
|
|||||||
508
src/core/link.c
508
src/core/link.c
@@ -1,508 +0,0 @@
|
|||||||
/*
|
|
||||||
* uhub - A tiny ADC p2p connection hub
|
|
||||||
* Copyright (C) 2007-2013, Jan Vidar Krey
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "uhub.h"
|
|
||||||
|
|
||||||
#ifdef LINK_SUPPORT
|
|
||||||
static int link_send_support(struct hub_link* link);
|
|
||||||
|
|
||||||
static void link_net_event(struct net_connection* con, int event, void *arg)
|
|
||||||
{
|
|
||||||
LOG_INFO("link_net_event(), event=%d", event);
|
|
||||||
struct hub_link* link = (struct hub_link*) arg;
|
|
||||||
struct hub_info* hub = link->hub;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (event == NET_EVENT_TIMEOUT)
|
|
||||||
{
|
|
||||||
LOG_DEBUG("Hub link timeout!");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event & NET_EVENT_READ)
|
|
||||||
{
|
|
||||||
ret = link_handle_read(link);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
link_disconnect(link);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event & NET_EVENT_WRITE)
|
|
||||||
{
|
|
||||||
ret = link_handle_write(link);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
link_disconnect(link);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void link_disconnect(struct hub_link* link)
|
|
||||||
{
|
|
||||||
if (link->connection)
|
|
||||||
net_con_close(link->connection);
|
|
||||||
link->connection = NULL;
|
|
||||||
|
|
||||||
ioq_send_destroy(link->send_queue);
|
|
||||||
ioq_recv_destroy(link->recv_queue);
|
|
||||||
link->send_queue = NULL;
|
|
||||||
link->recv_queue = NULL;
|
|
||||||
|
|
||||||
// FIXME: Notify hub and disconnect users!
|
|
||||||
|
|
||||||
hub_free(link);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct hub_link* link_create_internal(struct hub_info* hub)
|
|
||||||
{
|
|
||||||
struct hub_link* link = NULL;
|
|
||||||
|
|
||||||
LOG_DEBUG("link_create_internal(), hub=%p");
|
|
||||||
link = (struct hub_link*) hub_malloc_zero(sizeof(struct hub_link));
|
|
||||||
if (link == NULL)
|
|
||||||
return NULL; /* OOM */
|
|
||||||
|
|
||||||
link->send_queue = ioq_send_create();
|
|
||||||
link->recv_queue = ioq_recv_create();
|
|
||||||
|
|
||||||
link->hub = hub;
|
|
||||||
link->state = state_protocol;
|
|
||||||
return link;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct hub_link* link_create(struct hub_info* hub, struct net_connection* con, struct ip_addr_encap* addr)
|
|
||||||
{
|
|
||||||
struct hub_link* link = link_create_internal(hub);
|
|
||||||
link->connection = con;
|
|
||||||
net_con_reinitialize(link->connection, link_net_event, link, NET_EVENT_READ);
|
|
||||||
link->mode = link_mode_server;
|
|
||||||
return link;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void link_connect_callback(struct net_connect_handle* handle, enum net_connect_status status, struct net_connection* con, void* ptr)
|
|
||||||
{
|
|
||||||
struct hub_link* link = (struct hub_link*) ptr;
|
|
||||||
link->connect_job = NULL;
|
|
||||||
|
|
||||||
LOG_DEBUG("link_connect_callback()");
|
|
||||||
|
|
||||||
switch (status)
|
|
||||||
{
|
|
||||||
case net_connect_status_ok:
|
|
||||||
link->connection = con;
|
|
||||||
net_con_reinitialize(link->connection, link_net_event, link, NET_EVENT_READ);
|
|
||||||
// FIXME: send handshake here
|
|
||||||
link_send_support(link);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case net_connect_status_host_not_found:
|
|
||||||
case net_connect_status_no_address:
|
|
||||||
case net_connect_status_dns_error:
|
|
||||||
case net_connect_status_refused:
|
|
||||||
case net_connect_status_unreachable:
|
|
||||||
case net_connect_status_timeout:
|
|
||||||
case net_connect_status_socket_error:
|
|
||||||
// FIXME: Unable to connect - start timer and re-try connection establishment!
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct link_address
|
|
||||||
{
|
|
||||||
char host[256];
|
|
||||||
uint16_t port;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int link_parse_address(const char* arg, struct link_address* addr)
|
|
||||||
{
|
|
||||||
int port;
|
|
||||||
char* split;
|
|
||||||
|
|
||||||
memset(addr, 0, sizeof(struct link_address));
|
|
||||||
|
|
||||||
/* Split hostname and port (if possible) */
|
|
||||||
split = strrchr(arg, ':');
|
|
||||||
if (split == 0 || strlen(split) < 2 || strlen(split) > 6)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Ensure port number is valid */
|
|
||||||
port = strtol(split+1, NULL, 10);
|
|
||||||
if (port <= 0 || port > 65535)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
memcpy(addr->host, arg, &split[0] - &arg[0]);
|
|
||||||
addr->port = port;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct hub_link* link_connect_uri(struct hub_info* hub, const char* address)
|
|
||||||
{
|
|
||||||
struct link_address link_address;
|
|
||||||
if (!link_parse_address(address, &link_address))
|
|
||||||
{
|
|
||||||
LOG_INFO("Invalid master hub link address");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return link_connect(hub, link_address.host, link_address.port);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct hub_link* link_connect(struct hub_info* hub, const char* address, uint16_t port)
|
|
||||||
{
|
|
||||||
struct hub_link* link = link_create_internal(hub);
|
|
||||||
|
|
||||||
LOG_DEBUG("Connecting to master link at %s:%d...", address, port);
|
|
||||||
|
|
||||||
link->mode = link_mode_client;
|
|
||||||
link->connect_job = net_con_connect(address, port, link_connect_callback, link);
|
|
||||||
if (!link->connect_job)
|
|
||||||
{
|
|
||||||
// FIXME: Immediate failure!
|
|
||||||
LOG_DEBUG("Error connecting to master hub link.");
|
|
||||||
link_disconnect(link);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return link;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int link_net_io_want_read(struct hub_link* link)
|
|
||||||
{
|
|
||||||
net_con_update(link->connection, NET_EVENT_READ);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int link_net_io_want_write(struct hub_link* link)
|
|
||||||
{
|
|
||||||
net_con_update(link->connection, NET_EVENT_READ | NET_EVENT_WRITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int link_handle_write(struct hub_link* link)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
while (ioq_send_get_bytes(link->send_queue))
|
|
||||||
{
|
|
||||||
ret = ioq_send_send(link->send_queue, link->connection);
|
|
||||||
if (ret <= 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret < 0)
|
|
||||||
return -1; // FIXME! Extract socket error!
|
|
||||||
|
|
||||||
if (ioq_send_get_bytes(link->send_queue))
|
|
||||||
link_net_io_want_write(link);
|
|
||||||
else
|
|
||||||
link_net_io_want_read(link);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int link_send_message(struct hub_link* link, struct adc_message* msg)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG_SENDQ
|
|
||||||
char* data = strndup(msg->cache, msg->length-1);
|
|
||||||
LOG_PROTO("[link] send %p: \"%s\"", link, data);
|
|
||||||
free(data);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!link->connection)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
uhub_assert(msg->cache && *msg->cache);
|
|
||||||
|
|
||||||
if (ioq_send_is_empty(link->send_queue) /*&& !user_flag_get(user, flag_pipeline)*/)
|
|
||||||
{
|
|
||||||
/* Perform oportunistic write */
|
|
||||||
ioq_send_add(link->send_queue, msg);
|
|
||||||
link_handle_write(link);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// if (check_send_queue(hub, user, msg) >= 0)
|
|
||||||
// {
|
|
||||||
ioq_send_add(link->send_queue, msg);
|
|
||||||
// if (!user_flag_get(user, flag_pipeline))
|
|
||||||
link_net_io_want_write(link);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int link_send_support(struct hub_link* link)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
struct adc_message* msg = adc_msg_construct(ADC_CMD_LSUP, 6 + strlen(ADC_PROTO_LINK_SUPPORT));
|
|
||||||
adc_msg_add_argument(msg, ADC_PROTO_LINK_SUPPORT);
|
|
||||||
ret = link_send_message(link, msg);
|
|
||||||
adc_msg_free(msg);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int link_send_welcome(struct hub_link* link)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
struct adc_message* info = adc_msg_construct(ADC_CMD_LINF, 128);
|
|
||||||
|
|
||||||
if (!info)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
adc_msg_add_named_argument(info, ADC_INF_FLAG_CLIENT_TYPE, ADC_CLIENT_TYPE_HUB);
|
|
||||||
adc_msg_add_named_argument_string(info, ADC_INF_FLAG_USER_AGENT, PRODUCT_STRING);
|
|
||||||
adc_msg_add_named_argument_string(info, ADC_INF_FLAG_NICK, link->hub->config->hub_name);
|
|
||||||
adc_msg_add_named_argument_string(info, ADC_INF_FLAG_DESCRIPTION, link->hub->config->hub_description);
|
|
||||||
|
|
||||||
ret = link_send_message(link, info);
|
|
||||||
|
|
||||||
link->state = state_normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int link_send_auth_response(struct hub_link* link, const char* challenge)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
struct adc_message* msg = adc_msg_construct(ADC_CMD_LPAS, 128);
|
|
||||||
|
|
||||||
// FIXME: Solve challenge.
|
|
||||||
|
|
||||||
ret = link_send_message(link, msg);
|
|
||||||
adc_msg_free(msg);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int link_send_auth_request(struct hub_link* link)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
struct adc_message* msg = adc_msg_construct(ADC_CMD_LGPA, 128);
|
|
||||||
|
|
||||||
// FIXME: Create challenge.
|
|
||||||
char buf[64];
|
|
||||||
uint64_t tiger_res[3];
|
|
||||||
static char tiger_buf[MAX_CID_LEN+1];
|
|
||||||
|
|
||||||
LOG_DEBUG("link_send_auth_request");
|
|
||||||
|
|
||||||
// FIXME: Generate a better nonce scheme.
|
|
||||||
snprintf(buf, 64, "%p%d", link, (int) net_con_get_sd(link->connection));
|
|
||||||
|
|
||||||
tiger((uint64_t*) buf, strlen(buf), (uint64_t*) tiger_res);
|
|
||||||
base32_encode((unsigned char*) tiger_res, TIGERSIZE, tiger_buf);
|
|
||||||
tiger_buf[MAX_CID_LEN] = 0;
|
|
||||||
|
|
||||||
// Add nonce to message
|
|
||||||
adc_msg_add_argument(msg, (const char*) tiger_buf);
|
|
||||||
ret = link_send_message(link, msg);
|
|
||||||
adc_msg_free(msg);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int link_handle_support(struct hub_link* link, struct adc_message* msg)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
LOG_DEBUG("link_handle_support");
|
|
||||||
|
|
||||||
if (link->mode == link_mode_server)
|
|
||||||
{
|
|
||||||
if (link->state == state_protocol)
|
|
||||||
{
|
|
||||||
ret = link_send_support(link);
|
|
||||||
if (ret == 0)
|
|
||||||
ret = link_send_auth_request(link);
|
|
||||||
link->state = state_verify;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int link_handle_auth_request(struct hub_link* link, struct adc_message* msg)
|
|
||||||
{
|
|
||||||
char* challenge;
|
|
||||||
int ret = -1;
|
|
||||||
|
|
||||||
LOG_DEBUG("link_handle_auth_request");
|
|
||||||
|
|
||||||
if (link->state == state_verify)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (link->mode == link_mode_client)
|
|
||||||
{
|
|
||||||
challenge = adc_msg_get_argument(msg, 0);
|
|
||||||
ret = link_send_auth_response(link, challenge);
|
|
||||||
hub_free(challenge);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int link_handle_auth_response(struct hub_link* link, struct adc_message* msg)
|
|
||||||
{
|
|
||||||
|
|
||||||
LOG_DEBUG("link_handle_auth_response. link_state=%d", (int) link->state);
|
|
||||||
|
|
||||||
if (link->state != state_verify)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
LOG_DEBUG("State is not verify!");
|
|
||||||
|
|
||||||
if (link->mode == link_mode_server)
|
|
||||||
{
|
|
||||||
// Check authentication data
|
|
||||||
// FIXME: Can involve plug-ins at this point.
|
|
||||||
return link_send_welcome(link);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG_DEBUG("Ignoring auth response - We're client mode!");
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int link_handle_link_info(struct hub_link* link, struct adc_message* msg)
|
|
||||||
{
|
|
||||||
LOG_DEBUG("link_handle_link_info");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int link_handle_status(struct hub_link* link, struct adc_message* msg)
|
|
||||||
{
|
|
||||||
LOG_DEBUG("link_handle_status");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int link_handle_message(struct hub_link* link, const char* message, size_t length)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
struct adc_message* cmd = 0;
|
|
||||||
|
|
||||||
LOG_INFO("link_handle_message(): %s (%d)", message, (int) length);
|
|
||||||
|
|
||||||
// FIXME: is this needed?
|
|
||||||
if (link->state == state_cleanup || link->state == state_disconnected)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
cmd = adc_msg_parse(message, length);
|
|
||||||
if (!cmd)
|
|
||||||
{
|
|
||||||
LOG_DEBUG("Unable to parse hub-link message");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (
|
|
||||||
|
|
||||||
switch (cmd->cmd)
|
|
||||||
{
|
|
||||||
case ADC_CMD_LSUP:
|
|
||||||
ret = link_handle_support(link, cmd);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ADC_CMD_LPAS:
|
|
||||||
ret = link_handle_auth_response(link, cmd);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ADC_CMD_LGPA:
|
|
||||||
ret = link_handle_auth_request(link, cmd);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ADC_CMD_LINF:
|
|
||||||
ret = link_handle_link_info(link, cmd);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ADC_CMD_LSTA:
|
|
||||||
ret = link_handle_status(link, cmd);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
adc_msg_free(cmd);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int link_read_message(struct hub_link* link)
|
|
||||||
{
|
|
||||||
char* lastPos = 0;
|
|
||||||
char* pos = 0;
|
|
||||||
char* start = link->recv_queue->buf;
|
|
||||||
size_t remaining = link->recv_queue->size;
|
|
||||||
|
|
||||||
while ((pos = memchr(start, '\n', remaining)))
|
|
||||||
{
|
|
||||||
lastPos = pos+1;
|
|
||||||
pos[0] = '\0';
|
|
||||||
|
|
||||||
if (link->flags & 1)
|
|
||||||
{
|
|
||||||
/* FIXME Unset maxbuf flag */
|
|
||||||
link->flags = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (link_handle_message(link, start, (pos - start)) == -1)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pos[0] = '\n'; /* FIXME: not needed */
|
|
||||||
pos ++;
|
|
||||||
remaining -= (pos - start);
|
|
||||||
start = pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
ioq_recv_consume(link->recv_queue, (start - link->recv_queue->buf));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int link_handle_read(struct hub_link* link)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
switch (ioq_recv_read(link->recv_queue, link->connection))
|
|
||||||
{
|
|
||||||
case ioq_recv_ok:
|
|
||||||
if (link_read_message(link) < 0)
|
|
||||||
{
|
|
||||||
// FIXME: propagate protocol error?
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
// Parse messages then call again
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ioq_recv_later:
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case ioq_recv_full:
|
|
||||||
link->flags = 1; // FIXME: MAXBUF
|
|
||||||
ioq_recv_set(link->recv_queue, 0, 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ioq_recv_error:
|
|
||||||
return -1; // FIXME: it would be good to signal type of socket error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* LINK_SUPPORT */
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
/*
|
|
||||||
* uhub - A tiny ADC p2p connection hub
|
|
||||||
* Copyright (C) 2007-2013, Jan Vidar Krey
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef HAVE_UHUB_LINK_H
|
|
||||||
#define HAVE_UHUB_LINK_H
|
|
||||||
|
|
||||||
#ifdef LINK_SUPPORT
|
|
||||||
|
|
||||||
struct hub_link
|
|
||||||
{
|
|
||||||
char name[MAX_NICK_LEN+1]; /** The name of the linked hub */
|
|
||||||
char user_agent[MAX_UA_LEN+1]; /** The user agent of the linked hub */
|
|
||||||
char address[256]; /** The official address of the linked hub */
|
|
||||||
enum link_mode { link_mode_client, link_mode_server } mode;
|
|
||||||
enum user_state state;
|
|
||||||
struct ioq_send* send_queue;
|
|
||||||
struct ioq_recv* recv_queue;
|
|
||||||
struct net_connection* connection; /** Connection data */
|
|
||||||
struct net_connect_handle* connect_job; /** Only used when establishing a connection in client mode */
|
|
||||||
struct hub_info* hub;
|
|
||||||
int flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a link from an accepted connection (act as a link server).
|
|
||||||
*/
|
|
||||||
extern struct hub_link* link_create(struct hub_info* hub, struct net_connection* con, struct ip_addr_encap* addr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Connect this hub to an upstream server (act as a link client).
|
|
||||||
*/
|
|
||||||
extern struct hub_link* link_connect(struct hub_info* hub, const char* address, uint16_t port);
|
|
||||||
extern struct hub_link* link_connect_uri(struct hub_info* hub, const char* address);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Disconnect a link connection.
|
|
||||||
*/
|
|
||||||
extern void link_disconnect(struct hub_link*);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read from link connection and process messages.
|
|
||||||
* @return 0 on success, and a negative value otherwise
|
|
||||||
*/
|
|
||||||
extern int link_handle_read(struct hub_link* link);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write queued messages to the link.
|
|
||||||
* @return 0 on success, and a negative value otherwise.
|
|
||||||
*/
|
|
||||||
extern int link_handle_write(struct hub_link* link);
|
|
||||||
|
|
||||||
#endif // LINK_SUPPORT
|
|
||||||
|
|
||||||
#endif /* HAVE_UHUB_LINK_H */
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2011, Jan Vidar Krey
|
* Copyright (C) 2007-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
|
||||||
@@ -125,10 +125,6 @@ int main_loop()
|
|||||||
hub_set_log_verbosity(arg_verbose);
|
hub_set_log_verbosity(arg_verbose);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
LOG_INFO("Debug messages enabled");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (read_config(arg_config, &configuration, !arg_have_config) == -1)
|
if (read_config(arg_config, &configuration, !arg_have_config) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
* Copyright (C) 2007-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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -71,17 +71,15 @@ static void probe_net_event(struct net_connection* con, int events, void *arg)
|
|||||||
probe_destroy(probe);
|
probe_destroy(probe);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#ifdef LINK_SUPPORT
|
else if ((memcmp(probe_recvbuf, "GET ", 4) == 0) ||
|
||||||
else if (probe->hub->config->hub_link_enabled && memcmp(probe_recvbuf, "LSUP", 4) == 0)
|
(memcmp(probe_recvbuf, "POST", 4) == 0) ||
|
||||||
|
(memcmp(probe_recvbuf, "HEAD", 4) == 0))
|
||||||
{
|
{
|
||||||
if (link_create(probe->hub, probe->connection, &probe->addr))
|
/* 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));
|
||||||
probe->connection = 0;
|
const char* buf = "501 Not implemented\r\n\r\n";
|
||||||
|
net_con_send(con, buf, strlen(buf));
|
||||||
}
|
}
|
||||||
probe_destroy(probe);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif /* LINK_SUPPORT */
|
|
||||||
#ifdef SSL_SUPPORT
|
#ifdef SSL_SUPPORT
|
||||||
else if (bytes >= 11 &&
|
else if (bytes >= 11 &&
|
||||||
probe_recvbuf[0] == 22 &&
|
probe_recvbuf[0] == 22 &&
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -99,7 +99,7 @@ int route_to_user(struct hub_info* hub, struct hub_user* user, struct adc_messag
|
|||||||
{
|
{
|
||||||
#ifdef DEBUG_SENDQ
|
#ifdef DEBUG_SENDQ
|
||||||
char* data = strndup(msg->cache, msg->length-1);
|
char* data = strndup(msg->cache, msg->length-1);
|
||||||
LOG_PROTO("[user] send %s: \"%s\"", sid_to_string(user->id.sid), data);
|
LOG_PROTO("send %s: \"%s\"", sid_to_string(user->id.sid), data);
|
||||||
free(data);
|
free(data);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -139,12 +139,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 +153,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 +204,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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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)" */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
@@ -148,7 +141,7 @@ int net_backend_process()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Process pending DNS results
|
// Process pending DNS results
|
||||||
net_dns_process();
|
// net_dns_process();
|
||||||
|
|
||||||
g_backend->handler.backend_process(g_backend->data, res);
|
g_backend->handler.backend_process(g_backend->data, res);
|
||||||
|
|
||||||
@@ -166,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
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2013, 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
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include "uhub.h"
|
#include "uhub.h"
|
||||||
#include "network/common.h"
|
#include "network/common.h"
|
||||||
|
#include "network/backend.h"
|
||||||
|
|
||||||
static int is_blocked_or_interrupted()
|
static int is_blocked_or_interrupted()
|
||||||
{
|
{
|
||||||
@@ -116,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);
|
||||||
@@ -178,11 +196,12 @@ static int net_connect_job_check(struct net_connect_job* job)
|
|||||||
int af = job->addr.ss_family;
|
int af = job->addr.ss_family;
|
||||||
enum net_connect_status status;
|
enum net_connect_status status;
|
||||||
|
|
||||||
int ret = net_connect(net_con_get_sd(con), (struct sockaddr*) &job->addr, af == AF_INET ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in));
|
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))
|
if (ret == 0 || (ret == -1 && net_error() == EISCONN))
|
||||||
{
|
{
|
||||||
LOG_TRACE("net_connect_job_check(): Socket connected!");
|
LOG_TRACE("net_connect_job_check(): Socket connected!");
|
||||||
job->con = NULL;
|
job->con = NULL;
|
||||||
|
net_con_clear_timeout(con);
|
||||||
net_connect_callback(job->handle, net_connect_status_ok, con);
|
net_connect_callback(job->handle, net_connect_status_ok, con);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -264,7 +283,6 @@ static int net_connect_job_process(struct net_connect_job* job)
|
|||||||
*/
|
*/
|
||||||
static void net_connect_job_internal_cb(struct net_connection* con, int event, void* ptr)
|
static void net_connect_job_internal_cb(struct net_connection* con, int event, void* ptr)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
struct net_connect_job* job = net_con_get_ptr(con);
|
struct net_connect_job* job = net_con_get_ptr(con);
|
||||||
struct net_connect_job* next_job = job->next;
|
struct net_connect_job* next_job = job->next;
|
||||||
struct net_connect_handle* handle = job->handle;
|
struct net_connect_handle* handle = job->handle;
|
||||||
@@ -307,7 +325,7 @@ static void net_connect_job_internal_cb(struct net_connection* con, int event, v
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int net_connect_cancel(struct net_connect_handle* handle)
|
static void net_connect_cancel(struct net_connect_handle* handle)
|
||||||
{
|
{
|
||||||
struct net_connect_job* job;
|
struct net_connect_job* job;
|
||||||
|
|
||||||
@@ -363,6 +381,7 @@ static int net_connect_process(struct net_connect_handle* handle)
|
|||||||
return 1; // Connected - cool!
|
return 1; // Connected - cool!
|
||||||
|
|
||||||
net_connect_process_queue(handle, handle->job4);
|
net_connect_process_queue(handle, handle->job4);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -421,7 +440,6 @@ static int net_con_connect_dns_callback(struct net_dns_job* job, const struct ne
|
|||||||
struct net_connect_handle* handle = (struct net_connect_handle*) net_dns_job_get_ptr(job);
|
struct net_connect_handle* handle = (struct net_connect_handle*) net_dns_job_get_ptr(job);
|
||||||
handle->dns = NULL;
|
handle->dns = NULL;
|
||||||
size_t usable = 0;
|
size_t usable = 0;
|
||||||
int ret;
|
|
||||||
|
|
||||||
LOG_TRACE("net_con_connect(): async - Got DNS results");
|
LOG_TRACE("net_con_connect(): async - Got DNS results");
|
||||||
if (!result)
|
if (!result)
|
||||||
@@ -506,3 +524,34 @@ static void net_connect_callback(struct net_connect_handle* handle, enum net_con
|
|||||||
// Cleanup
|
// Cleanup
|
||||||
net_connect_destroy(handle);
|
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-2013, 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
|
||||||
@@ -28,6 +28,7 @@
|
|||||||
#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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2013, 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
|
||||||
@@ -68,6 +68,11 @@ static void shutdown_free_results(void* ptr)
|
|||||||
net_dns_result_free(result);
|
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
|
// NOTE: Any job manipulating the members of this
|
||||||
// struct must lock the mutex!
|
// struct must lock the mutex!
|
||||||
@@ -76,6 +81,8 @@ struct net_dns_subsystem
|
|||||||
struct linked_list* jobs; // currently running jobs
|
struct linked_list* jobs; // currently running jobs
|
||||||
struct linked_list* results; // queue of results that are awaiting being delivered to callback.
|
struct linked_list* results; // queue of results that are awaiting being delivered to callback.
|
||||||
uhub_mutex_t mutex;
|
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;
|
static struct net_dns_subsystem* g_dns = NULL;
|
||||||
@@ -87,13 +94,11 @@ void net_dns_initialize()
|
|||||||
g_dns->jobs = list_create();
|
g_dns->jobs = list_create();
|
||||||
g_dns->results = list_create();
|
g_dns->results = list_create();
|
||||||
uhub_mutex_init(&g_dns->mutex);
|
uhub_mutex_init(&g_dns->mutex);
|
||||||
|
g_dns->notify_handle = net_notify_create(notify_callback, g_dns);
|
||||||
}
|
}
|
||||||
|
|
||||||
void net_dns_destroy()
|
void net_dns_destroy()
|
||||||
{
|
{
|
||||||
struct net_dns_job* job;
|
|
||||||
struct net_dns_result* result;
|
|
||||||
|
|
||||||
uhub_mutex_lock(&g_dns->mutex);
|
uhub_mutex_lock(&g_dns->mutex);
|
||||||
LOG_TRACE("net_dns_destroy(): jobs=%d", (int) list_size(g_dns->jobs));
|
LOG_TRACE("net_dns_destroy(): jobs=%d", (int) list_size(g_dns->jobs));
|
||||||
list_clear(g_dns->jobs, &shutdown_free_jobs);
|
list_clear(g_dns->jobs, &shutdown_free_jobs);
|
||||||
@@ -105,22 +110,18 @@ void net_dns_destroy()
|
|||||||
list_destroy(g_dns->jobs);
|
list_destroy(g_dns->jobs);
|
||||||
list_destroy(g_dns->results);
|
list_destroy(g_dns->results);
|
||||||
uhub_mutex_destroy(&g_dns->mutex);
|
uhub_mutex_destroy(&g_dns->mutex);
|
||||||
|
net_notify_destroy(g_dns->notify_handle);
|
||||||
hub_free(g_dns);
|
hub_free(g_dns);
|
||||||
g_dns = NULL;
|
g_dns = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dummy_free(void* ptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void net_dns_process()
|
void net_dns_process()
|
||||||
{
|
{
|
||||||
struct net_dns_result* result;
|
struct net_dns_result* result;
|
||||||
uhub_mutex_lock(&g_dns->mutex);
|
uhub_mutex_lock(&g_dns->mutex);
|
||||||
LOG_DUMP("net_dns_process(): jobs=%d, results=%d", (int) list_size(g_dns->jobs), (int) list_size(g_dns->results));
|
LOG_TRACE("net_dns_process(): jobs=%d, results=%d", (int) list_size(g_dns->jobs), (int) list_size(g_dns->results));
|
||||||
|
|
||||||
for (result = (struct net_dns_result*) list_get_first(g_dns->results); result; result = (struct net_dns_result*) list_get_next(g_dns->results))
|
LIST_FOREACH(struct net_dns_result*, result, g_dns->results,
|
||||||
{
|
{
|
||||||
struct net_dns_job* job = result->job;
|
struct net_dns_job* job = result->job;
|
||||||
#ifdef DEBUG_LOOKUP_TIME
|
#ifdef DEBUG_LOOKUP_TIME
|
||||||
@@ -146,9 +147,9 @@ void net_dns_process()
|
|||||||
result->job = NULL;
|
result->job = NULL;
|
||||||
free_job(job);
|
free_job(job);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
list_clear(g_dns->results, &dummy_free);
|
list_clear(g_dns->results, NULL);
|
||||||
uhub_mutex_unlock(&g_dns->mutex);
|
uhub_mutex_unlock(&g_dns->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,6 +216,7 @@ static void* job_thread_resolve_name(void* ptr)
|
|||||||
uhub_mutex_lock(&g_dns->mutex);
|
uhub_mutex_lock(&g_dns->mutex);
|
||||||
list_remove(g_dns->jobs, job);
|
list_remove(g_dns->jobs, job);
|
||||||
list_append(g_dns->results, dns_results);
|
list_append(g_dns->results, dns_results);
|
||||||
|
net_notify_signal(g_dns->notify_handle, 1);
|
||||||
uhub_mutex_unlock(&g_dns->mutex);
|
uhub_mutex_unlock(&g_dns->mutex);
|
||||||
|
|
||||||
return dns_results;
|
return dns_results;
|
||||||
@@ -273,14 +275,14 @@ extern struct net_dns_job* net_dns_gethostbyaddr(struct ip_addr_encap* ipaddr, n
|
|||||||
static struct net_dns_job* find_and_remove_job(struct net_dns_job* job)
|
static struct net_dns_job* find_and_remove_job(struct net_dns_job* job)
|
||||||
{
|
{
|
||||||
struct net_dns_job* it;
|
struct net_dns_job* it;
|
||||||
for (it = (struct net_dns_job*) list_get_first(g_dns->jobs); it; it = (struct net_dns_job*) list_get_next(g_dns->jobs))
|
LIST_FOREACH(struct net_dns_job*, it, g_dns->jobs,
|
||||||
{
|
{
|
||||||
if (it == job)
|
if (it == job)
|
||||||
{
|
{
|
||||||
list_remove(g_dns->jobs, it);
|
list_remove(g_dns->jobs, it);
|
||||||
return job;
|
return job;
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,14 +290,14 @@ 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)
|
static struct net_dns_result* find_and_remove_result(struct net_dns_job* job)
|
||||||
{
|
{
|
||||||
struct net_dns_result* it;
|
struct net_dns_result* it;
|
||||||
for (it = (struct net_dns_result*) list_get_first(g_dns->results); it; it = (struct net_dns_result*) list_get_next(g_dns->results))
|
LIST_FOREACH(struct net_dns_result*, it, g_dns->results,
|
||||||
{
|
{
|
||||||
if (it->job == job)
|
if (it->job == job)
|
||||||
{
|
{
|
||||||
list_remove(g_dns->results, it);
|
list_remove(g_dns->results, it);
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2013, 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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
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 <http://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 <http://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 */
|
||||||
@@ -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
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "uhub.h"
|
#include "uhub.h"
|
||||||
#include "network/common.h"
|
#include "network/common.h"
|
||||||
#include "network/tls.h"
|
#include "network/tls.h"
|
||||||
|
#include "network/backend.h"
|
||||||
|
|
||||||
#ifdef SSL_SUPPORT
|
#ifdef SSL_SUPPORT
|
||||||
#ifdef SSL_USE_OPENSSL
|
#ifdef SSL_USE_OPENSSL
|
||||||
@@ -32,6 +33,9 @@ struct net_ssl_openssl
|
|||||||
SSL* ssl;
|
SSL* ssl;
|
||||||
BIO* bio;
|
BIO* bio;
|
||||||
enum ssl_state state;
|
enum ssl_state state;
|
||||||
|
int events;
|
||||||
|
int ssl_read_events;
|
||||||
|
int ssl_write_events;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
size_t bytes_rx;
|
size_t bytes_rx;
|
||||||
size_t bytes_tx;
|
size_t bytes_tx;
|
||||||
@@ -39,8 +43,7 @@ struct net_ssl_openssl
|
|||||||
|
|
||||||
struct net_context_openssl
|
struct net_context_openssl
|
||||||
{
|
{
|
||||||
SSL_METHOD* ssl_method;
|
SSL_CTX* ssl;
|
||||||
SSL_CTX* ssl_ctx;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct net_ssl_openssl* get_handle(struct net_connection* con)
|
static struct net_ssl_openssl* get_handle(struct net_connection* con)
|
||||||
@@ -49,6 +52,29 @@ static struct net_ssl_openssl* get_handle(struct net_connection* con)
|
|||||||
return (struct net_ssl_openssl*) con->ssl;
|
return (struct net_ssl_openssl*) con->ssl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
static const char* get_state_str(enum ssl_state state)
|
||||||
|
{
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case tls_st_none: return "tls_st_none";
|
||||||
|
case tls_st_error: return "tls_st_error";
|
||||||
|
case tls_st_accepting: return "tls_st_accepting";
|
||||||
|
case tls_st_connecting: return "tls_st_connecting";
|
||||||
|
case tls_st_connected: return "tls_st_connected";
|
||||||
|
case tls_st_disconnecting: return "tls_st_disconnecting";
|
||||||
|
}
|
||||||
|
uhub_assert(!"This should not happen - invalid state!");
|
||||||
|
return "(UNKNOWN STATE)";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void net_ssl_set_state(struct net_ssl_openssl* handle, enum ssl_state new_state)
|
||||||
|
{
|
||||||
|
LOG_DEBUG("net_ssl_set_state(): prev_state=%s, new_state=%s", get_state_str(handle->state), get_state_str(new_state));
|
||||||
|
handle->state = new_state;
|
||||||
|
}
|
||||||
|
|
||||||
const char* net_ssl_get_provider()
|
const char* net_ssl_get_provider()
|
||||||
{
|
{
|
||||||
return OPENSSL_VERSION_TEXT;
|
return OPENSSL_VERSION_TEXT;
|
||||||
@@ -93,43 +119,83 @@ static void add_io_stats(struct net_ssl_openssl* handle)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const SSL_METHOD* get_ssl_method(const char* tls_version)
|
||||||
|
{
|
||||||
|
if (!tls_version || !*tls_version)
|
||||||
|
{
|
||||||
|
LOG_ERROR("tls_version is not set.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(tls_version, "1.0"))
|
||||||
|
return TLSv1_method();
|
||||||
|
if (!strcmp(tls_version, "1.1"))
|
||||||
|
return TLSv1_1_method();
|
||||||
|
if (!strcmp(tls_version, "1.2"))
|
||||||
|
return TLSv1_2_method();
|
||||||
|
|
||||||
|
LOG_ERROR("Unable to recognize tls_version.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new SSL context.
|
* Create a new SSL context.
|
||||||
*/
|
*/
|
||||||
struct ssl_context_handle* net_ssl_context_create()
|
struct ssl_context_handle* net_ssl_context_create(const char* tls_version, const char* tls_ciphersuite)
|
||||||
{
|
{
|
||||||
|
|
||||||
struct net_context_openssl* ctx = (struct net_context_openssl*) hub_malloc_zero(sizeof(struct net_context_openssl));
|
struct net_context_openssl* ctx = (struct net_context_openssl*) hub_malloc_zero(sizeof(struct net_context_openssl));
|
||||||
ctx->ssl_method = (SSL_METHOD*) SSLv23_method(); /* TLSv1_method() */
|
const SSL_METHOD* ssl_method = get_ssl_method(tls_version);
|
||||||
ctx->ssl_ctx = SSL_CTX_new(ctx->ssl_method);
|
|
||||||
|
if (!ssl_method)
|
||||||
|
{
|
||||||
|
hub_free(ctx);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->ssl = SSL_CTX_new(ssl_method);
|
||||||
|
|
||||||
/* Disable SSLv2 */
|
/* Disable SSLv2 */
|
||||||
SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv2);
|
SSL_CTX_set_options(ctx->ssl, SSL_OP_NO_SSLv2);
|
||||||
|
|
||||||
|
// #ifdef SSL_OP_NO_SSLv3
|
||||||
|
/* Disable SSLv3 */
|
||||||
|
SSL_CTX_set_options(ctx->ssl, SSL_OP_NO_SSLv3);
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// FIXME: Why did we need this again?
|
||||||
|
SSL_CTX_set_quiet_shutdown(ctx->ssl, 1);
|
||||||
|
|
||||||
#ifdef SSL_OP_NO_COMPRESSION
|
#ifdef SSL_OP_NO_COMPRESSION
|
||||||
/* Disable compression? */
|
/* Disable compression */
|
||||||
LOG_TRACE("Disabling SSL compression."); /* "CRIME" attack */
|
LOG_TRACE("Disabling SSL compression."); /* "CRIME" attack */
|
||||||
SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_COMPRESSION);
|
SSL_CTX_set_options(ctx->ssl, SSL_OP_NO_COMPRESSION);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SSL_CTX_set_quiet_shutdown(ctx->ssl_ctx, 1);
|
/* Set preferred cipher suite */
|
||||||
|
if (SSL_CTX_set_cipher_list(ctx->ssl, tls_ciphersuite) != 1)
|
||||||
|
{
|
||||||
|
LOG_ERROR("Unable to set cipher suite.");
|
||||||
|
SSL_CTX_free(ctx->ssl);
|
||||||
|
hub_free(ctx);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return (struct ssl_context_handle*) ctx;
|
return (struct ssl_context_handle*) ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void net_ssl_context_destroy(struct ssl_context_handle* ctx_)
|
void net_ssl_context_destroy(struct ssl_context_handle* ctx_)
|
||||||
{
|
{
|
||||||
struct net_context_openssl* ctx = (struct net_context_openssl*) ctx_;
|
struct net_context_openssl* ctx = (struct net_context_openssl*) ctx_;
|
||||||
SSL_CTX_free(ctx->ssl_ctx);
|
SSL_CTX_free(ctx->ssl);
|
||||||
hub_free(ctx);
|
hub_free(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ssl_load_certificate(struct ssl_context_handle* ctx_, const char* pem_file)
|
int ssl_load_certificate(struct ssl_context_handle* ctx_, const char* pem_file)
|
||||||
{
|
{
|
||||||
struct net_context_openssl* ctx = (struct net_context_openssl*) ctx_;
|
struct net_context_openssl* ctx = (struct net_context_openssl*) ctx_;
|
||||||
if (SSL_CTX_use_certificate_file(ctx->ssl_ctx, pem_file, SSL_FILETYPE_PEM) < 0)
|
if (SSL_CTX_use_certificate_chain_file(ctx->ssl, pem_file) < 0)
|
||||||
{
|
{
|
||||||
LOG_ERROR("SSL_CTX_use_certificate_file: %s", ERR_error_string(ERR_get_error(), NULL));
|
LOG_ERROR("SSL_CTX_use_certificate_chain_file: %s", ERR_error_string(ERR_get_error(), NULL));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,7 +205,7 @@ int ssl_load_certificate(struct ssl_context_handle* ctx_, const char* pem_file)
|
|||||||
int ssl_load_private_key(struct ssl_context_handle* ctx_, const char* pem_file)
|
int ssl_load_private_key(struct ssl_context_handle* ctx_, const char* pem_file)
|
||||||
{
|
{
|
||||||
struct net_context_openssl* ctx = (struct net_context_openssl*) ctx_;
|
struct net_context_openssl* ctx = (struct net_context_openssl*) ctx_;
|
||||||
if (SSL_CTX_use_PrivateKey_file(ctx->ssl_ctx, pem_file, SSL_FILETYPE_PEM) < 0)
|
if (SSL_CTX_use_PrivateKey_file(ctx->ssl, pem_file, SSL_FILETYPE_PEM) < 0)
|
||||||
{
|
{
|
||||||
LOG_ERROR("SSL_CTX_use_PrivateKey_file: %s", ERR_error_string(ERR_get_error(), NULL));
|
LOG_ERROR("SSL_CTX_use_PrivateKey_file: %s", ERR_error_string(ERR_get_error(), NULL));
|
||||||
return 0;
|
return 0;
|
||||||
@@ -150,7 +216,7 @@ int ssl_load_private_key(struct ssl_context_handle* ctx_, const char* pem_file)
|
|||||||
int ssl_check_private_key(struct ssl_context_handle* ctx_)
|
int ssl_check_private_key(struct ssl_context_handle* ctx_)
|
||||||
{
|
{
|
||||||
struct net_context_openssl* ctx = (struct net_context_openssl*) ctx_;
|
struct net_context_openssl* ctx = (struct net_context_openssl*) ctx_;
|
||||||
if (SSL_CTX_check_private_key(ctx->ssl_ctx) != 1)
|
if (SSL_CTX_check_private_key(ctx->ssl) != 1)
|
||||||
{
|
{
|
||||||
LOG_FATAL("SSL_CTX_check_private_key: Private key does not match the certificate public key: %s", ERR_error_string(ERR_get_error(), NULL));
|
LOG_FATAL("SSL_CTX_check_private_key: Private key does not match the certificate public key: %s", ERR_error_string(ERR_get_error(), NULL));
|
||||||
return 0;
|
return 0;
|
||||||
@@ -158,7 +224,7 @@ int ssl_check_private_key(struct ssl_context_handle* ctx_)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_openssl_error(struct net_connection* con, int ret, enum ssl_state forced_rwstate)
|
static int handle_openssl_error(struct net_connection* con, int ret, int read)
|
||||||
{
|
{
|
||||||
struct net_ssl_openssl* handle = get_handle(con);
|
struct net_ssl_openssl* handle = get_handle(con);
|
||||||
int err = SSL_get_error(handle->ssl, ret);
|
int err = SSL_get_error(handle->ssl, ret);
|
||||||
@@ -169,33 +235,43 @@ static int handle_openssl_error(struct net_connection* con, int ret, enum ssl_st
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
case SSL_ERROR_WANT_READ:
|
case SSL_ERROR_WANT_READ:
|
||||||
handle->state = forced_rwstate;
|
if (read)
|
||||||
net_con_update(con, NET_EVENT_READ);
|
handle->ssl_read_events = NET_EVENT_READ;
|
||||||
|
else
|
||||||
|
handle->ssl_write_events = NET_EVENT_READ;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case SSL_ERROR_WANT_WRITE:
|
case SSL_ERROR_WANT_WRITE:
|
||||||
handle->state = forced_rwstate;
|
if (read)
|
||||||
net_con_update(con, NET_EVENT_WRITE);
|
handle->ssl_read_events = NET_EVENT_WRITE;
|
||||||
|
else
|
||||||
|
handle->ssl_write_events = NET_EVENT_WRITE;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
case SSL_ERROR_SSL:
|
||||||
|
net_ssl_set_state(handle, tls_st_error);
|
||||||
|
return -2;
|
||||||
|
|
||||||
case SSL_ERROR_SYSCALL:
|
case SSL_ERROR_SYSCALL:
|
||||||
handle->state = tls_st_error;
|
net_ssl_set_state(handle, tls_st_error);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t net_con_ssl_accept(struct net_connection* con)
|
ssize_t net_con_ssl_accept(struct net_connection* con)
|
||||||
{
|
{
|
||||||
struct net_ssl_openssl* handle = get_handle(con);
|
struct net_ssl_openssl* handle = get_handle(con);
|
||||||
handle->state = tls_st_accepting;
|
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
net_ssl_set_state(handle, tls_st_accepting);
|
||||||
|
|
||||||
ret = SSL_accept(handle->ssl);
|
ret = SSL_accept(handle->ssl);
|
||||||
LOG_PROTO("SSL_accept() ret=%d", ret);
|
LOG_PROTO("SSL_accept() ret=%d", ret);
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
{
|
{
|
||||||
net_con_update(con, NET_EVENT_READ);
|
net_con_update(con, NET_EVENT_READ);
|
||||||
handle->state = tls_st_connected;
|
net_ssl_set_state(handle, tls_st_connected);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
return handle_openssl_error(con, ret, tls_st_accepting);
|
return handle_openssl_error(con, ret, tls_st_accepting);
|
||||||
@@ -205,30 +281,34 @@ ssize_t net_con_ssl_connect(struct net_connection* con)
|
|||||||
{
|
{
|
||||||
struct net_ssl_openssl* handle = get_handle(con);
|
struct net_ssl_openssl* handle = get_handle(con);
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
handle->state = tls_st_connecting;
|
net_ssl_set_state(handle, tls_st_connecting);
|
||||||
|
|
||||||
ret = SSL_connect(handle->ssl);
|
ret = SSL_connect(handle->ssl);
|
||||||
LOG_PROTO("SSL_connect() ret=%d", ret);
|
LOG_PROTO("SSL_connect() ret=%d", ret);
|
||||||
|
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
{
|
{
|
||||||
handle->state = tls_st_connected;
|
|
||||||
net_con_update(con, NET_EVENT_READ);
|
net_con_update(con, NET_EVENT_READ);
|
||||||
|
net_ssl_set_state(handle, tls_st_connected);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
return handle_openssl_error(con, ret, tls_st_connecting);
|
|
||||||
|
ret = handle_openssl_error(con, ret, tls_st_connecting);
|
||||||
|
LOG_ERROR("net_con_ssl_connect: ret=%d", ret);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode ssl_mode, struct ssl_context_handle* ssl_ctx)
|
ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode ssl_mode, struct ssl_context_handle* ssl_ctx)
|
||||||
{
|
{
|
||||||
uhub_assert(con);
|
uhub_assert(con);
|
||||||
|
uhub_assert(ssl_ctx);
|
||||||
|
|
||||||
struct net_context_openssl* ctx = (struct net_context_openssl*) ssl_ctx;
|
struct net_context_openssl* ctx = (struct net_context_openssl*) ssl_ctx;
|
||||||
struct net_ssl_openssl* handle = (struct net_ssl_openssl*) hub_malloc_zero(sizeof(struct net_ssl_openssl));
|
struct net_ssl_openssl* handle = (struct net_ssl_openssl*) hub_malloc_zero(sizeof(struct net_ssl_openssl));
|
||||||
|
|
||||||
if (ssl_mode == net_con_ssl_mode_server)
|
if (ssl_mode == net_con_ssl_mode_server)
|
||||||
{
|
{
|
||||||
handle->ssl = SSL_new(ctx->ssl_ctx);
|
handle->ssl = SSL_new(ctx->ssl);
|
||||||
if (!handle->ssl)
|
if (!handle->ssl)
|
||||||
{
|
{
|
||||||
LOG_ERROR("Unable to create new SSL stream\n");
|
LOG_ERROR("Unable to create new SSL stream\n");
|
||||||
@@ -241,31 +321,37 @@ ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
handle->ssl = SSL_new(SSL_CTX_new(TLSv1_method()));
|
handle->ssl = SSL_new(ctx->ssl);
|
||||||
SSL_set_fd(handle->ssl, con->sd);
|
SSL_set_fd(handle->ssl, con->sd);
|
||||||
handle->bio = SSL_get_rbio(handle->ssl);
|
handle->bio = SSL_get_rbio(handle->ssl);
|
||||||
con->ssl = (struct ssl_handle*) handle;
|
con->ssl = (struct ssl_handle*) handle;
|
||||||
return net_con_ssl_connect(con);
|
return net_con_ssl_connect(con);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t net_ssl_send(struct net_connection* con, const void* buf, size_t len)
|
ssize_t net_ssl_send(struct net_connection* con, const void* buf, size_t len)
|
||||||
{
|
{
|
||||||
struct net_ssl_openssl* handle = get_handle(con);
|
struct net_ssl_openssl* handle = get_handle(con);
|
||||||
|
|
||||||
uhub_assert(handle->state == tls_st_connected || handle->state == tls_st_need_write);
|
LOG_ERROR("net_ssl_send(), state=%d", (int) handle->state);
|
||||||
|
|
||||||
|
if (handle->state == tls_st_error)
|
||||||
|
return -2;
|
||||||
|
|
||||||
|
uhub_assert(handle->state == tls_st_connected);
|
||||||
|
|
||||||
|
|
||||||
ERR_clear_error();
|
ERR_clear_error();
|
||||||
ssize_t ret = SSL_write(handle->ssl, buf, len);
|
ssize_t ret = SSL_write(handle->ssl, buf, len);
|
||||||
add_io_stats(handle);
|
add_io_stats(handle);
|
||||||
LOG_PROTO("SSL_write(con=%p, buf=%p, len=" PRINTF_SIZE_T ") => %d", con, buf, len, ret);
|
LOG_PROTO("SSL_write(con=%p, buf=%p, len=" PRINTF_SIZE_T ") => %d", con, buf, len, ret);
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
{
|
handle->ssl_write_events = 0;
|
||||||
handle->state = tls_st_connected;
|
else
|
||||||
|
ret = handle_openssl_error(con, ret, 0);
|
||||||
|
|
||||||
|
net_ssl_update(con, handle->events); // Update backend only
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
return handle_openssl_error(con, ret, tls_st_need_write);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t net_ssl_recv(struct net_connection* con, void* buf, size_t len)
|
ssize_t net_ssl_recv(struct net_connection* con, void* buf, size_t len)
|
||||||
@@ -276,7 +362,10 @@ ssize_t net_ssl_recv(struct net_connection* con, void* buf, size_t len)
|
|||||||
if (handle->state == tls_st_error)
|
if (handle->state == tls_st_error)
|
||||||
return -2;
|
return -2;
|
||||||
|
|
||||||
uhub_assert(handle->state == tls_st_connected || handle->state == tls_st_need_read);
|
if (handle->state == tls_st_accepting || handle->state == tls_st_connecting)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
uhub_assert(handle->state == tls_st_connected);
|
||||||
|
|
||||||
ERR_clear_error();
|
ERR_clear_error();
|
||||||
|
|
||||||
@@ -284,29 +373,43 @@ ssize_t net_ssl_recv(struct net_connection* con, void* buf, size_t len)
|
|||||||
add_io_stats(handle);
|
add_io_stats(handle);
|
||||||
LOG_PROTO("SSL_read(con=%p, buf=%p, len=" PRINTF_SIZE_T ") => %d", con, buf, len, ret);
|
LOG_PROTO("SSL_read(con=%p, buf=%p, len=" PRINTF_SIZE_T ") => %d", con, buf, len, ret);
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
{
|
handle->ssl_read_events = 0;
|
||||||
handle->state = tls_st_connected;
|
else
|
||||||
|
ret = handle_openssl_error(con, ret, 1);
|
||||||
|
|
||||||
|
net_ssl_update(con, handle->events); // Update backend only
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
return handle_openssl_error(con, ret, tls_st_need_read);
|
|
||||||
|
void net_ssl_update(struct net_connection* con, int events)
|
||||||
|
{
|
||||||
|
struct net_ssl_openssl* handle = get_handle(con);
|
||||||
|
handle->events = events;
|
||||||
|
net_backend_update(con, handle->events | handle->ssl_read_events | handle->ssl_write_events);
|
||||||
}
|
}
|
||||||
|
|
||||||
void net_ssl_shutdown(struct net_connection* con)
|
void net_ssl_shutdown(struct net_connection* con)
|
||||||
{
|
{
|
||||||
struct net_ssl_openssl* handle = get_handle(con);
|
struct net_ssl_openssl* handle = get_handle(con);
|
||||||
|
if (handle)
|
||||||
|
{
|
||||||
SSL_shutdown(handle->ssl);
|
SSL_shutdown(handle->ssl);
|
||||||
SSL_clear(handle->ssl);
|
SSL_clear(handle->ssl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void net_ssl_destroy(struct net_connection* con)
|
void net_ssl_destroy(struct net_connection* con)
|
||||||
{
|
{
|
||||||
struct net_ssl_openssl* handle = get_handle(con);
|
struct net_ssl_openssl* handle = get_handle(con);
|
||||||
|
LOG_TRACE("net_ssl_destroy: %p", con);
|
||||||
SSL_free(handle->ssl);
|
SSL_free(handle->ssl);
|
||||||
|
hub_free(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void net_ssl_callback(struct net_connection* con, int events)
|
void net_ssl_callback(struct net_connection* con, int events)
|
||||||
{
|
{
|
||||||
struct net_ssl_openssl* handle = get_handle(con);
|
struct net_ssl_openssl* handle = get_handle(con);
|
||||||
|
int ret;
|
||||||
|
|
||||||
switch (handle->state)
|
switch (handle->state)
|
||||||
{
|
{
|
||||||
@@ -315,7 +418,7 @@ void net_ssl_callback(struct net_connection* con, int events)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case tls_st_error:
|
case tls_st_error:
|
||||||
con->callback(con, NET_EVENT_READ, con->ptr);
|
con->callback(con, NET_EVENT_ERROR, con->ptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tls_st_accepting:
|
case tls_st_accepting:
|
||||||
@@ -324,19 +427,27 @@ void net_ssl_callback(struct net_connection* con, int events)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case tls_st_connecting:
|
case tls_st_connecting:
|
||||||
if (net_con_ssl_connect(con) != 0)
|
ret = net_con_ssl_connect(con);
|
||||||
con->callback(con, NET_EVENT_READ, con->ptr);
|
if (ret == 0)
|
||||||
break;
|
return;
|
||||||
|
|
||||||
case tls_st_need_read:
|
if (ret > 0)
|
||||||
|
{
|
||||||
|
LOG_DEBUG("%p SSL connected!", con);
|
||||||
con->callback(con, NET_EVENT_READ, con->ptr);
|
con->callback(con, NET_EVENT_READ, con->ptr);
|
||||||
break;
|
}
|
||||||
|
else
|
||||||
case tls_st_need_write:
|
{
|
||||||
con->callback(con, NET_EVENT_WRITE, con->ptr);
|
LOG_DEBUG("%p SSL handshake failed!", con);
|
||||||
|
con->callback(con, NET_EVENT_ERROR, con->ptr);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tls_st_connected:
|
case tls_st_connected:
|
||||||
|
if (handle->ssl_read_events & events)
|
||||||
|
events |= NET_EVENT_READ;
|
||||||
|
if (handle->ssl_write_events & events)
|
||||||
|
events |= NET_EVENT_WRITE;
|
||||||
con->callback(con, events, con->ptr);
|
con->callback(con, events, con->ptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -345,6 +456,18 @@ void net_ssl_callback(struct net_connection* con, int events)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* net_ssl_get_tls_version(struct net_connection* con)
|
||||||
|
{
|
||||||
|
struct net_ssl_openssl* handle = get_handle(con);
|
||||||
|
return SSL_get_version(handle->ssl);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* net_ssl_get_tls_cipher(struct net_connection* con)
|
||||||
|
{
|
||||||
|
struct net_ssl_openssl* handle = get_handle(con);
|
||||||
|
const SSL_CIPHER *cipher = SSL_get_current_cipher(handle->ssl);
|
||||||
|
return SSL_CIPHER_get_name(cipher);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* SSL_USE_OPENSSL */
|
#endif /* SSL_USE_OPENSSL */
|
||||||
#endif /* SSL_SUPPORT */
|
#endif /* SSL_SUPPORT */
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -42,6 +42,7 @@ void timeout_queue_initialize(struct timeout_queue* t, time_t now, size_t max)
|
|||||||
{
|
{
|
||||||
t->last = now;
|
t->last = now;
|
||||||
t->max = max;
|
t->max = max;
|
||||||
|
memset(&t->lock, 0, sizeof(t->lock));
|
||||||
t->events = hub_malloc_zero(max * sizeof(struct timeout_evt*));
|
t->events = hub_malloc_zero(max * sizeof(struct timeout_evt*));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,12 +53,56 @@ void timeout_queue_shutdown(struct timeout_queue* t)
|
|||||||
t->max = 0;
|
t->max = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int timeout_queue_locked(struct timeout_queue* t)
|
||||||
|
{
|
||||||
|
return t->lock.ptr != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void timeout_queue_lock(struct timeout_queue* t)
|
||||||
|
{
|
||||||
|
t->lock.ptr = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
// unlock and flush the locked events to the main timeout queue.
|
||||||
|
static void timeout_queue_unlock(struct timeout_queue* t)
|
||||||
|
{
|
||||||
|
struct timeout_evt* evt, *tmp, *first;
|
||||||
|
size_t pos;
|
||||||
|
t->lock.ptr = NULL;
|
||||||
|
|
||||||
|
evt = t->lock.next;
|
||||||
|
while (evt)
|
||||||
|
{
|
||||||
|
tmp = evt->next;
|
||||||
|
pos = evt->timestamp % t->max;
|
||||||
|
first = t->events[pos];
|
||||||
|
if (first)
|
||||||
|
{
|
||||||
|
first->prev->next = evt;
|
||||||
|
evt->prev = first->prev;
|
||||||
|
first->prev = evt;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
t->events[pos] = evt;
|
||||||
|
evt->prev = evt;
|
||||||
|
}
|
||||||
|
evt->next = 0;
|
||||||
|
evt = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
t->lock.next = 0;
|
||||||
|
t->lock.prev = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t timeout_queue_process(struct timeout_queue* t, time_t now)
|
size_t timeout_queue_process(struct timeout_queue* t, time_t now)
|
||||||
{
|
{
|
||||||
size_t pos = (size_t) t->last;
|
size_t pos = (size_t) t->last;
|
||||||
size_t events = 0;
|
size_t events = 0;
|
||||||
struct timeout_evt* evt = 0;
|
struct timeout_evt* evt = 0;
|
||||||
t->last = now;
|
t->last = now;
|
||||||
|
timeout_queue_lock(t);
|
||||||
for (; pos <= now; pos++)
|
for (; pos <= now; pos++)
|
||||||
{
|
{
|
||||||
while ((evt = t->events[pos % t->max]))
|
while ((evt = t->events[pos % t->max]))
|
||||||
@@ -67,6 +112,7 @@ size_t timeout_queue_process(struct timeout_queue* t, time_t now)
|
|||||||
events++;
|
events++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
timeout_queue_unlock(t);
|
||||||
return events;
|
return events;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,6 +128,61 @@ size_t timeout_queue_get_next_timeout(struct timeout_queue* t, time_t now)
|
|||||||
return seconds;
|
return seconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void timeout_queue_insert_locked(struct timeout_queue* t, struct timeout_evt* evt)
|
||||||
|
{
|
||||||
|
/* All events point back to the sentinel.
|
||||||
|
* this means the event is considered schedule (see timeout_evt_is_scheduled),
|
||||||
|
* and it is easy to tell if the event is in the wait queue or not.
|
||||||
|
*/
|
||||||
|
evt->prev = &t->lock;
|
||||||
|
evt->next = NULL;
|
||||||
|
|
||||||
|
// The sentinel next points to the first event in the locked queue
|
||||||
|
// The sentinel prev points to the last evetnt in the locked queue.
|
||||||
|
// NOTE: if prev is != NULL then next also must be != NULL.
|
||||||
|
if (t->lock.prev)
|
||||||
|
{
|
||||||
|
t->lock.prev->next = evt;
|
||||||
|
t->lock.prev = evt;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
t->lock.next = evt;
|
||||||
|
t->lock.prev = evt;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void timeout_queue_remove_locked(struct timeout_queue* t, struct timeout_evt* evt)
|
||||||
|
{
|
||||||
|
uhub_assert(evt->prev == &t->lock);
|
||||||
|
if (t->lock.next == evt)
|
||||||
|
{
|
||||||
|
t->lock.next = evt->next;
|
||||||
|
if (t->lock.prev == evt)
|
||||||
|
t->lock.prev = evt->next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct timeout_evt *prev, *it;
|
||||||
|
prev = 0;
|
||||||
|
it = t->lock.next;
|
||||||
|
while (it)
|
||||||
|
{
|
||||||
|
prev = it;
|
||||||
|
it = it->next;
|
||||||
|
if (it == evt)
|
||||||
|
{
|
||||||
|
prev->next = it->next;
|
||||||
|
if (!prev->next)
|
||||||
|
t->lock.prev = prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
timeout_evt_reset(evt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void timeout_queue_insert(struct timeout_queue* t, struct timeout_evt* evt, size_t seconds)
|
void timeout_queue_insert(struct timeout_queue* t, struct timeout_evt* evt, size_t seconds)
|
||||||
{
|
{
|
||||||
@@ -90,6 +191,12 @@ void timeout_queue_insert(struct timeout_queue* t, struct timeout_evt* evt, size
|
|||||||
evt->timestamp = t->last + seconds;
|
evt->timestamp = t->last + seconds;
|
||||||
evt->next = 0;
|
evt->next = 0;
|
||||||
|
|
||||||
|
if (timeout_queue_locked(t))
|
||||||
|
{
|
||||||
|
timeout_queue_insert_locked(t, evt);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
first = t->events[pos];
|
first = t->events[pos];
|
||||||
|
|
||||||
if (first)
|
if (first)
|
||||||
@@ -112,6 +219,13 @@ void timeout_queue_remove(struct timeout_queue* t, struct timeout_evt* evt)
|
|||||||
size_t pos = (evt->timestamp % t->max);
|
size_t pos = (evt->timestamp % t->max);
|
||||||
struct timeout_evt* first = t->events[pos];
|
struct timeout_evt* first = t->events[pos];
|
||||||
|
|
||||||
|
// Removing a locked event
|
||||||
|
if (evt->prev == &t->lock)
|
||||||
|
{
|
||||||
|
timeout_queue_remove_locked(t, evt);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!first || !evt->prev)
|
if (!first || !evt->prev)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -43,6 +43,7 @@ struct timeout_queue
|
|||||||
{
|
{
|
||||||
time_t last;
|
time_t last;
|
||||||
size_t max;
|
size_t max;
|
||||||
|
struct timeout_evt lock;
|
||||||
struct timeout_evt** events;
|
struct timeout_evt** events;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -20,31 +20,4 @@
|
|||||||
#include "uhub.h"
|
#include "uhub.h"
|
||||||
#include "network/connection.h"
|
#include "network/connection.h"
|
||||||
|
|
||||||
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
|
||||||
@@ -32,8 +32,6 @@ enum ssl_state
|
|||||||
tls_st_accepting,
|
tls_st_accepting,
|
||||||
tls_st_connecting,
|
tls_st_connecting,
|
||||||
tls_st_connected,
|
tls_st_connected,
|
||||||
tls_st_need_read, /* special case of connected */
|
|
||||||
tls_st_need_write, /* special case of connected */
|
|
||||||
tls_st_disconnecting,
|
tls_st_disconnecting,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -58,8 +56,9 @@ extern int net_ssl_library_shutdown();
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new SSL context.
|
* Create a new SSL context.
|
||||||
|
* Specify a TLS version as a string: "1.2" for TLS 1.2.
|
||||||
*/
|
*/
|
||||||
extern struct ssl_context_handle* net_ssl_context_create();
|
extern struct ssl_context_handle* net_ssl_context_create(const char* tls_version, const char* tls_ciphersuite);
|
||||||
extern void net_ssl_context_destroy(struct ssl_context_handle* ctx);
|
extern void net_ssl_context_destroy(struct ssl_context_handle* ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -90,15 +89,26 @@ extern ssize_t net_con_ssl_connect(struct net_connection*);
|
|||||||
extern ssize_t net_ssl_send(struct net_connection* con, const void* buf, size_t len);
|
extern ssize_t net_ssl_send(struct net_connection* con, const void* buf, size_t len);
|
||||||
extern ssize_t net_ssl_recv(struct net_connection* con, void* buf, size_t len);
|
extern ssize_t net_ssl_recv(struct net_connection* con, void* buf, size_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the event mask. Additional events may be requested depending on the
|
||||||
|
* needs of the TLS layer.
|
||||||
|
*
|
||||||
|
* @param con Connection handle.
|
||||||
|
* @param events Event mask (NET_EVENT_*)
|
||||||
|
*/
|
||||||
|
extern void net_ssl_update(struct net_connection* con, int events);
|
||||||
|
|
||||||
extern void net_ssl_shutdown(struct net_connection* con);
|
extern void net_ssl_shutdown(struct net_connection* con);
|
||||||
extern void net_ssl_destroy(struct net_connection* con);
|
extern void net_ssl_destroy(struct net_connection* con);
|
||||||
extern void net_ssl_callback(struct net_connection* con, int events);
|
extern void net_ssl_callback(struct net_connection* con, int events);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode, struct ssl_context_handle* ssl_ctx);
|
extern ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode, struct ssl_context_handle* ssl_ctx);
|
||||||
extern int net_con_is_ssl(struct net_connection* con);
|
extern int net_con_is_ssl(struct net_connection* con);
|
||||||
|
|
||||||
|
extern const char* net_ssl_get_tls_version(struct net_connection* con);
|
||||||
|
extern const char* net_ssl_get_tls_cipher(struct net_connection* con);
|
||||||
|
|
||||||
#endif /* SSL_SUPPORT */
|
#endif /* SSL_SUPPORT */
|
||||||
#endif /* HAVE_UHUB_NETWORK_TLS_H */
|
#endif /* HAVE_UHUB_NETWORK_TLS_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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -110,6 +110,7 @@ struct plugin_command;
|
|||||||
struct plugin_command_arg_data;
|
struct plugin_command_arg_data;
|
||||||
|
|
||||||
typedef int (*hfunc_send_message)(struct plugin_handle*, struct plugin_user* user, const char* message);
|
typedef int (*hfunc_send_message)(struct plugin_handle*, struct plugin_user* user, const char* message);
|
||||||
|
typedef int (*hfunc_send_broadcast_message)(struct plugin_handle*, const char* message);
|
||||||
typedef int (*hfunc_send_status)(struct plugin_handle*, struct plugin_user* to, int code, const char* message);
|
typedef int (*hfunc_send_status)(struct plugin_handle*, struct plugin_user* to, int code, const char* message);
|
||||||
typedef int (*hfunc_user_disconnect)(struct plugin_handle*, struct plugin_user* user);
|
typedef int (*hfunc_user_disconnect)(struct plugin_handle*, struct plugin_user* user);
|
||||||
typedef int (*hfunc_command_add)(struct plugin_handle*, struct plugin_command_handle*);
|
typedef int (*hfunc_command_add)(struct plugin_handle*, struct plugin_command_handle*);
|
||||||
@@ -118,6 +119,8 @@ typedef int (*hfunc_command_del)(struct plugin_handle*, struct plugin_command_ha
|
|||||||
typedef size_t (*hfunc_command_arg_reset)(struct plugin_handle*, struct plugin_command*);
|
typedef size_t (*hfunc_command_arg_reset)(struct plugin_handle*, struct plugin_command*);
|
||||||
typedef struct plugin_command_arg_data* (*hfunc_command_arg_next)(struct plugin_handle*, struct plugin_command*, enum plugin_command_arg_type);
|
typedef struct plugin_command_arg_data* (*hfunc_command_arg_next)(struct plugin_handle*, struct plugin_command*, enum plugin_command_arg_type);
|
||||||
|
|
||||||
|
typedef size_t (*hfunc_get_usercount)(struct plugin_handle*);
|
||||||
|
|
||||||
typedef char* (*hfunc_get_hub_name)(struct plugin_handle*);
|
typedef char* (*hfunc_get_hub_name)(struct plugin_handle*);
|
||||||
typedef void (*hfunc_set_hub_name)(struct plugin_handle*, const char*);
|
typedef void (*hfunc_set_hub_name)(struct plugin_handle*, const char*);
|
||||||
typedef char* (*hfunc_get_hub_description)(struct plugin_handle*);
|
typedef char* (*hfunc_get_hub_description)(struct plugin_handle*);
|
||||||
@@ -130,12 +133,14 @@ typedef void (*hfunc_set_hub_description)(struct plugin_handle*, const char*);
|
|||||||
struct plugin_hub_funcs
|
struct plugin_hub_funcs
|
||||||
{
|
{
|
||||||
hfunc_send_message send_message;
|
hfunc_send_message send_message;
|
||||||
|
hfunc_send_broadcast_message send_broadcast_message;
|
||||||
hfunc_send_status send_status_message;
|
hfunc_send_status send_status_message;
|
||||||
hfunc_user_disconnect user_disconnect;
|
hfunc_user_disconnect user_disconnect;
|
||||||
hfunc_command_add command_add;
|
hfunc_command_add command_add;
|
||||||
hfunc_command_del command_del;
|
hfunc_command_del command_del;
|
||||||
hfunc_command_arg_reset command_arg_reset;
|
hfunc_command_arg_reset command_arg_reset;
|
||||||
hfunc_command_arg_next command_arg_next;
|
hfunc_command_arg_next command_arg_next;
|
||||||
|
hfunc_get_usercount get_usercount;
|
||||||
hfunc_get_hub_name get_name;
|
hfunc_get_hub_name get_name;
|
||||||
hfunc_set_hub_name set_name;
|
hfunc_set_hub_name set_name;
|
||||||
hfunc_get_hub_description get_description;
|
hfunc_get_hub_description get_description;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -177,16 +177,15 @@ static void unload_acl(struct acl_data* data)
|
|||||||
static plugin_st get_user(struct plugin_handle* plugin, const char* nickname, struct auth_info* data)
|
static plugin_st get_user(struct plugin_handle* plugin, const char* nickname, struct auth_info* data)
|
||||||
{
|
{
|
||||||
struct acl_data* acl = (struct acl_data*) plugin->ptr;
|
struct acl_data* acl = (struct acl_data*) plugin->ptr;
|
||||||
struct auth_info* info = (struct auth_info*) list_get_first(acl->users);
|
struct auth_info* info;
|
||||||
while (info)
|
LIST_FOREACH(struct auth_info*, info, acl->users,
|
||||||
{
|
{
|
||||||
if (strcasecmp((char*)info->nickname, nickname) == 0)
|
if (strcasecmp((char*)info->nickname, nickname) == 0)
|
||||||
{
|
{
|
||||||
memcpy(data, info, sizeof(struct auth_info));
|
memcpy(data, info, sizeof(struct auth_info));
|
||||||
return st_allow;
|
return st_allow;
|
||||||
}
|
}
|
||||||
info = (struct auth_info*) list_get_next(acl->users);
|
});
|
||||||
}
|
|
||||||
if (acl->exclusive)
|
if (acl->exclusive)
|
||||||
return st_deny;
|
return st_deny;
|
||||||
return st_default;
|
return st_default;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -50,9 +50,7 @@ static void history_add(struct plugin_handle* plugin, struct plugin_user* from,
|
|||||||
list_append(data->chat_history, log);
|
list_append(data->chat_history, log);
|
||||||
while (list_size(data->chat_history) > data->history_max)
|
while (list_size(data->chat_history) > data->history_max)
|
||||||
{
|
{
|
||||||
char* msg = list_get_first(data->chat_history);
|
list_remove_first(data->chat_history, hub_free);
|
||||||
list_remove(data->chat_history, msg);
|
|
||||||
hub_free(msg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,16 +77,14 @@ static size_t get_messages(struct chat_history_data* data, size_t num, struct cb
|
|||||||
skiplines = total - num;
|
skiplines = total - num;
|
||||||
|
|
||||||
cbuf_append(outbuf, "\n");
|
cbuf_append(outbuf, "\n");
|
||||||
message = (char*) list_get_first(messages);
|
LIST_FOREACH(char*, message, messages,
|
||||||
while (message)
|
|
||||||
{
|
{
|
||||||
if (--skiplines < 0)
|
if (--skiplines < 0)
|
||||||
{
|
{
|
||||||
cbuf_append(outbuf, message);
|
cbuf_append(outbuf, message);
|
||||||
lines++;
|
lines++;
|
||||||
}
|
}
|
||||||
message = (char*) list_get_next(messages);
|
});
|
||||||
}
|
|
||||||
cbuf_append(outbuf, "\n");
|
cbuf_append(outbuf, "\n");
|
||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|||||||
347
src/plugins/mod_chat_history_sqlite.c
Normal file
347
src/plugins/mod_chat_history_sqlite.c
Normal file
@@ -0,0 +1,347 @@
|
|||||||
|
/*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "plugin_api/handle.h"
|
||||||
|
#include "plugin_api/command_api.h"
|
||||||
|
#include "util/config_token.h"
|
||||||
|
#include <sqlite3.h>
|
||||||
|
#include "util/memory.h"
|
||||||
|
#include "util/misc.h"
|
||||||
|
#include "util/list.h"
|
||||||
|
#include "util/cbuffer.h"
|
||||||
|
|
||||||
|
#define MAX_HISTORY_SIZE 16384
|
||||||
|
|
||||||
|
struct chat_history_data
|
||||||
|
{
|
||||||
|
size_t history_max; ///<<< "the maximum number of chat messages kept in history."
|
||||||
|
size_t history_default; ///<<< "the default number of chat messages returned if no limit was provided"
|
||||||
|
size_t history_connect; ///<<< "the number of chat messages provided when users connect to the hub."
|
||||||
|
sqlite3* db; ///<<< "The chat history storage database."
|
||||||
|
struct plugin_command_handle* command_history_handle; ///<<< "A handle to the !history command."
|
||||||
|
struct plugin_command_handle* command_historycleanup_handle; ///<<< "A handle to the !historycleanup command."
|
||||||
|
};
|
||||||
|
|
||||||
|
struct chat_history_line
|
||||||
|
{
|
||||||
|
char message[MAX_HISTORY_SIZE];
|
||||||
|
char from[MAX_NICK_LEN];
|
||||||
|
char time[20];
|
||||||
|
};
|
||||||
|
|
||||||
|
static int null_callback(void* ptr, int argc, char **argv, char **colName) { return 0; }
|
||||||
|
|
||||||
|
static const char* sql_escape_string(const char* str)
|
||||||
|
{
|
||||||
|
static char out[1024];
|
||||||
|
size_t i = 0;
|
||||||
|
size_t n = 0;
|
||||||
|
for (; n < strlen(str); n++)
|
||||||
|
{
|
||||||
|
if (str[n] == '\'')
|
||||||
|
out[i++] = '\'';
|
||||||
|
out[i++] = str[n];
|
||||||
|
}
|
||||||
|
out[i++] = '\0';
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sql_execute(struct chat_history_data* sql, int (*callback)(void* ptr, int argc, char **argv, char **colName), void* ptr, const char* sql_fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
char query[1024];
|
||||||
|
char* errMsg;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
va_start(args, sql_fmt);
|
||||||
|
vsnprintf(query, sizeof(query), sql_fmt, args);
|
||||||
|
|
||||||
|
rc = sqlite3_exec(sql->db, query, callback, ptr, &errMsg);
|
||||||
|
if (rc != SQLITE_OK)
|
||||||
|
{
|
||||||
|
sqlite3_free(errMsg);
|
||||||
|
return -rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = sqlite3_changes(sql->db);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void create_tables(struct plugin_handle* plugin)
|
||||||
|
{
|
||||||
|
const char* table_create = "CREATE TABLE IF NOT EXISTS chat_history"
|
||||||
|
"("
|
||||||
|
"from_nick CHAR,"
|
||||||
|
"message TEXT,"
|
||||||
|
"time TIMESTAMP DEFAULT (DATETIME('NOW'))"
|
||||||
|
");";
|
||||||
|
|
||||||
|
struct chat_history_data* data = (struct chat_history_data*) plugin->ptr;
|
||||||
|
sql_execute(data, null_callback, NULL, table_create);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Add a chat message to history.
|
||||||
|
*/
|
||||||
|
static void history_add(struct plugin_handle* plugin, struct plugin_user* from, const char* message, int flags)
|
||||||
|
{
|
||||||
|
struct chat_history_data* data = (struct chat_history_data*) plugin->ptr;
|
||||||
|
char* history_line = strdup(sql_escape_string(message));
|
||||||
|
char* history_nick = strdup(sql_escape_string(from->nick));
|
||||||
|
|
||||||
|
sql_execute(data, null_callback, NULL, "INSERT INTO chat_history (from_nick, message) VALUES('%s', '%s');DELETE FROM chat_history WHERE time <= (SELECT time FROM chat_history ORDER BY time DESC LIMIT %d,1);", history_nick, history_line, data->history_max);
|
||||||
|
|
||||||
|
hub_free(history_line);
|
||||||
|
hub_free(history_nick);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain messages from the chat history as a linked list
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int get_messages_callback(void* ptr, int argc, char **argv, char **colName)
|
||||||
|
{
|
||||||
|
struct linked_list* messages = (struct linked_list*) ptr;
|
||||||
|
struct chat_history_line* line = hub_malloc(sizeof(struct chat_history_line));
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
memset(line, 0, sizeof(struct chat_history_line));
|
||||||
|
|
||||||
|
for (; i < argc; i++) {
|
||||||
|
if (strcmp(colName[i], "from_nick") == 0)
|
||||||
|
strncpy(line->from, argv[i], MAX_NICK_LEN);
|
||||||
|
else if (strcmp(colName[i], "message") == 0)
|
||||||
|
strncpy(line->message, argv[i], MAX_HISTORY_SIZE);
|
||||||
|
else if (strcmp(colName[i], "time") == 0)
|
||||||
|
strncpy(line->time, argv[i], 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
list_append(messages, line);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void user_login(struct plugin_handle* plugin, struct plugin_user* user)
|
||||||
|
{
|
||||||
|
struct chat_history_data* data = (struct chat_history_data*) plugin->ptr;
|
||||||
|
struct cbuffer* buf = NULL;
|
||||||
|
struct linked_list* found = (struct linked_list*) list_create();
|
||||||
|
|
||||||
|
sql_execute(data, get_messages_callback, found, "SELECT * FROM chat_history ORDER BY time DESC LIMIT 0,%d;", (int) data->history_connect);
|
||||||
|
|
||||||
|
if (data->history_connect > 0 && list_size(found) > 0)
|
||||||
|
{
|
||||||
|
buf = cbuf_create(MAX_HISTORY_SIZE);
|
||||||
|
cbuf_append(buf, "Chat history:\n\n");
|
||||||
|
struct chat_history_line* history_line;
|
||||||
|
history_line = (struct chat_history_line*) list_get_last(found);
|
||||||
|
while (history_line)
|
||||||
|
{
|
||||||
|
cbuf_append_format(buf, "[%s] <%s> %s\n", history_line->time, history_line->from, history_line->message);
|
||||||
|
list_remove(found, history_line);
|
||||||
|
hub_free(history_line);
|
||||||
|
history_line = (struct chat_history_line*) list_get_last(found);
|
||||||
|
}
|
||||||
|
plugin->hub.send_message(plugin, user, cbuf_get(buf));
|
||||||
|
cbuf_destroy(buf);
|
||||||
|
}
|
||||||
|
list_clear(found, &hub_free);
|
||||||
|
list_destroy(found);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The callback function for handling the !history command.
|
||||||
|
*/
|
||||||
|
static int command_history(struct plugin_handle* plugin, struct plugin_user* user, struct plugin_command* cmd)
|
||||||
|
{
|
||||||
|
struct chat_history_data* data = (struct chat_history_data*) plugin->ptr;
|
||||||
|
struct cbuffer* buf = cbuf_create(MAX_HISTORY_SIZE);
|
||||||
|
struct linked_list* found = (struct linked_list*) list_create();
|
||||||
|
struct plugin_command_arg_data* arg = plugin->hub.command_arg_next(plugin, cmd, plugin_cmd_arg_type_integer);
|
||||||
|
int maxlines;
|
||||||
|
|
||||||
|
if (arg)
|
||||||
|
maxlines = arg->data.integer;
|
||||||
|
else
|
||||||
|
maxlines = data->history_default;
|
||||||
|
|
||||||
|
sql_execute(data, get_messages_callback, found, "SELECT * FROM chat_history ORDER BY time DESC LIMIT 0,%d;", maxlines);
|
||||||
|
|
||||||
|
size_t linecount = list_size(found);
|
||||||
|
|
||||||
|
if (linecount > 0)
|
||||||
|
{
|
||||||
|
cbuf_append_format(buf, "*** %s: Chat History:\n\n", cmd->prefix);
|
||||||
|
struct chat_history_line* history_line;
|
||||||
|
history_line = (struct chat_history_line*) list_get_last(found);
|
||||||
|
while (history_line)
|
||||||
|
{
|
||||||
|
cbuf_append_format(buf, "[%s] <%s> %s\n", history_line->time, history_line->from, history_line->message);
|
||||||
|
list_remove(found, history_line);
|
||||||
|
hub_free(history_line);
|
||||||
|
history_line = (struct chat_history_line*) list_get_last(found);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cbuf_append_format(buf, "*** %s: No messages found.", cmd->prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin->hub.send_message(plugin, user, cbuf_get(buf));
|
||||||
|
cbuf_destroy(buf);
|
||||||
|
list_clear(found, &hub_free);
|
||||||
|
list_destroy(found);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int command_historycleanup(struct plugin_handle* plugin, struct plugin_user* user, struct plugin_command* cmd)
|
||||||
|
{
|
||||||
|
struct chat_history_data* data = (struct chat_history_data*) plugin->ptr;
|
||||||
|
struct cbuffer* buf = cbuf_create(128);
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
rc = sql_execute(data, null_callback, NULL, "DELETE FROM chat_history;");
|
||||||
|
|
||||||
|
if (!rc)
|
||||||
|
cbuf_append_format(buf, "*** %s: Unable to clean chat history table.", cmd->prefix);
|
||||||
|
else
|
||||||
|
cbuf_append_format(buf, "*** %s: Cleaned chat history table.", cmd->prefix);
|
||||||
|
|
||||||
|
plugin->hub.send_message(plugin, user, cbuf_get(buf));
|
||||||
|
cbuf_destroy(buf);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_error_message(struct plugin_handle* plugin, const char* msg)
|
||||||
|
{
|
||||||
|
plugin->error_msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct chat_history_data* parse_config(const char* line, struct plugin_handle* plugin)
|
||||||
|
{
|
||||||
|
struct chat_history_data* data = (struct chat_history_data*) hub_malloc_zero(sizeof(struct chat_history_data));
|
||||||
|
struct cfg_tokens* tokens = cfg_tokenize(line);
|
||||||
|
char* token = cfg_token_get_first(tokens);
|
||||||
|
|
||||||
|
uhub_assert(data != NULL);
|
||||||
|
|
||||||
|
data->history_max = 200;
|
||||||
|
data->history_default = 25;
|
||||||
|
data->history_connect = 5;
|
||||||
|
|
||||||
|
while (token)
|
||||||
|
{
|
||||||
|
struct cfg_settings* setting = cfg_settings_split(token);
|
||||||
|
|
||||||
|
if (!setting)
|
||||||
|
{
|
||||||
|
set_error_message(plugin, "Unable to parse startup parameters");
|
||||||
|
cfg_tokens_free(tokens);
|
||||||
|
hub_free(data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(cfg_settings_get_key(setting), "file") == 0)
|
||||||
|
{
|
||||||
|
if (!data->db)
|
||||||
|
{
|
||||||
|
if (sqlite3_open(cfg_settings_get_value(setting), &data->db))
|
||||||
|
{
|
||||||
|
cfg_tokens_free(tokens);
|
||||||
|
cfg_settings_free(setting);
|
||||||
|
hub_free(data);
|
||||||
|
set_error_message(plugin, "Unable to open database file");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strcmp(cfg_settings_get_key(setting), "history_max") == 0)
|
||||||
|
{
|
||||||
|
data->history_max = (size_t) uhub_atoi(cfg_settings_get_value(setting));
|
||||||
|
}
|
||||||
|
else if (strcmp(cfg_settings_get_key(setting), "history_default") == 0)
|
||||||
|
{
|
||||||
|
data->history_default = (size_t) uhub_atoi(cfg_settings_get_value(setting));
|
||||||
|
}
|
||||||
|
else if (strcmp(cfg_settings_get_key(setting), "history_connect") == 0)
|
||||||
|
{
|
||||||
|
data->history_connect = (size_t) uhub_atoi(cfg_settings_get_value(setting));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
set_error_message(plugin, "Unknown startup parameters given");
|
||||||
|
cfg_tokens_free(tokens);
|
||||||
|
cfg_settings_free(setting);
|
||||||
|
hub_free(data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg_settings_free(setting);
|
||||||
|
token = cfg_token_get_next(tokens);
|
||||||
|
}
|
||||||
|
cfg_tokens_free(tokens);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
int plugin_register(struct plugin_handle* plugin, const char* config)
|
||||||
|
{
|
||||||
|
struct chat_history_data* data;
|
||||||
|
PLUGIN_INITIALIZE(plugin, "SQLite chat history plugin", "1.0", "Provide a global chat history log.");
|
||||||
|
|
||||||
|
plugin->funcs.on_user_chat_message = history_add;
|
||||||
|
plugin->funcs.on_user_login = user_login;
|
||||||
|
data = parse_config(config, plugin);
|
||||||
|
|
||||||
|
if (!data)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
plugin->ptr = data;
|
||||||
|
|
||||||
|
create_tables(plugin);
|
||||||
|
|
||||||
|
data->command_history_handle = (struct plugin_command_handle*) hub_malloc(sizeof(struct plugin_command_handle));
|
||||||
|
PLUGIN_COMMAND_INITIALIZE(data->command_history_handle, plugin, "history", "?N", auth_cred_guest, &command_history, "Show chat message history.");
|
||||||
|
plugin->hub.command_add(plugin, data->command_history_handle);
|
||||||
|
|
||||||
|
data->command_historycleanup_handle = (struct plugin_command_handle*) hub_malloc(sizeof(struct plugin_command_handle));
|
||||||
|
PLUGIN_COMMAND_INITIALIZE(data->command_historycleanup_handle, plugin, "historycleanup", "", auth_cred_admin, &command_historycleanup, "Clean chat message history.");
|
||||||
|
plugin->hub.command_add(plugin, data->command_historycleanup_handle);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int plugin_unregister(struct plugin_handle* plugin)
|
||||||
|
{
|
||||||
|
struct chat_history_data* data = (struct chat_history_data*) plugin->ptr;
|
||||||
|
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
sqlite3_close(data->db);
|
||||||
|
|
||||||
|
plugin->hub.command_del(plugin, data->command_history_handle);
|
||||||
|
plugin->hub.command_del(plugin, data->command_historycleanup_handle);
|
||||||
|
hub_free(data->command_history_handle);
|
||||||
|
hub_free(data->command_historycleanup_handle);
|
||||||
|
hub_free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
171
src/plugins/mod_chat_is_privileged.c
Normal file
171
src/plugins/mod_chat_is_privileged.c
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
/*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "plugin_api/handle.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
|
||||||
|
struct user_info
|
||||||
|
{
|
||||||
|
sid_t sid;
|
||||||
|
int warnings;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct chat_restrictions_data
|
||||||
|
{
|
||||||
|
size_t num_users; // number of users tracked.
|
||||||
|
size_t max_users; // max users (hard limit max 1M users due to limitations in the SID (20 bits)).
|
||||||
|
struct user_info* users; // array of max_users
|
||||||
|
|
||||||
|
enum auth_credentials allow_privchat; // minimum credentials to allow using private chat
|
||||||
|
enum auth_credentials allow_op_contact; // minimum credentials to allow private chat to operators (including super and admins).
|
||||||
|
enum auth_credentials allow_mainchat; // minimum credentials to allow using main chat
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct chat_data* parse_config(struct plugin_handle* plugin, const char* line)
|
||||||
|
{
|
||||||
|
struct chat_data* data = (struct chat_data*) hub_malloc(sizeof(struct chat_data));
|
||||||
|
struct cfg_tokens* tokens = cfg_tokenize(line);
|
||||||
|
char* token = cfg_token_get_first(tokens);
|
||||||
|
|
||||||
|
// defaults
|
||||||
|
data->num_users = 0;
|
||||||
|
data->max_users = 512;
|
||||||
|
data->users = hub_malloc_zero(sizeof(struct user_info) * data->max_users);
|
||||||
|
data->allow_mainchat = auth_cred_guest;
|
||||||
|
data->allow_op_contact = auth_cred_guest;
|
||||||
|
data->allow_privchat = auth_cred_guest;
|
||||||
|
|
||||||
|
while (token)
|
||||||
|
{
|
||||||
|
struct cfg_settings* setting = cfg_settings_split(token);
|
||||||
|
|
||||||
|
if (!setting)
|
||||||
|
{
|
||||||
|
set_error_message(plugin, "Unable to parse startup parameters");
|
||||||
|
cfg_tokens_free(tokens);
|
||||||
|
hub_free(data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(cfg_settings_get_key(setting), "allow_privchat") == 0)
|
||||||
|
{
|
||||||
|
if (!string_to_boolean(cfg_settings_get_value(setting), &data->allow_privchat))
|
||||||
|
data->allow_privchat = 0;
|
||||||
|
}
|
||||||
|
else if (strcmp(cfg_settings_get_key(setting), "minimum_access") == 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
set_error_message(plugin, "Unknown startup parameters given");
|
||||||
|
cfg_tokens_free(tokens);
|
||||||
|
cfg_settings_free(setting);
|
||||||
|
hub_free(data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg_settings_free(setting);
|
||||||
|
token = cfg_token_get_next(tokens);
|
||||||
|
}
|
||||||
|
cfg_tokens_free(tokens);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct user_info* get_user_info(struct chat_data* data, sid_t sid)
|
||||||
|
{
|
||||||
|
struct user_info* u;
|
||||||
|
|
||||||
|
// resize buffer if needed.
|
||||||
|
if (sid >= data->max_users)
|
||||||
|
{
|
||||||
|
u = hub_malloc_zero(sizeof(struct user_info) * (sid + 1));
|
||||||
|
memcpy(u, data->users, data->max_users);
|
||||||
|
hub_free(data->users);
|
||||||
|
data->users = u;
|
||||||
|
data->max_users = sid;
|
||||||
|
u = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
u = &data->users[sid];
|
||||||
|
|
||||||
|
// reset counters if the user was not previously known.
|
||||||
|
if (!u->sid)
|
||||||
|
{
|
||||||
|
u->sid = sid;
|
||||||
|
u->warnings = 0;
|
||||||
|
data->num_users++;
|
||||||
|
}
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_user_login(struct plugin_handle* plugin, struct plugin_user* user)
|
||||||
|
{
|
||||||
|
struct chat_data* data = (struct chat_data*) plugin->ptr;
|
||||||
|
/*struct user_info* info = */
|
||||||
|
get_user_info(data, user->sid);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_user_logout(struct plugin_handle* plugin, struct plugin_user* user, const char* reason)
|
||||||
|
{
|
||||||
|
struct chat_data* data = (struct chat_data*) plugin->ptr;
|
||||||
|
struct user_info* info = get_user_info(data, user->sid);
|
||||||
|
if (info->sid)
|
||||||
|
data->num_users--;
|
||||||
|
info->warnings = 0;
|
||||||
|
info->sid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin_st on_chat_msg(struct plugin_handle* plugin, struct plugin_user* from, const char* message)
|
||||||
|
{
|
||||||
|
struct chat_data* data = (struct chat_data*) plugin->ptr;
|
||||||
|
if (from->credentials >=
|
||||||
|
return st_default;
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin_st on_private_msg(struct plugin_handle* plugin, struct plugin_user* from, struct plugin_user* to, const char* message)
|
||||||
|
{
|
||||||
|
return st_default;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int plugin_register(struct plugin_handle* plugin, const char* config)
|
||||||
|
{
|
||||||
|
PLUGIN_INITIALIZE(plugin, "Privileged chat hub", "1.0", "Only registered users can send messages on the main chat.");
|
||||||
|
plugin->ptr = cip_initialize();
|
||||||
|
|
||||||
|
plugin->funcs.on_user_login = on_user_login;
|
||||||
|
plugin->funcs.on_user_logout = on_user_logout;
|
||||||
|
plugin->funcs.on_chat_msg = on_chat_msg;
|
||||||
|
plugin->funcs.on_private_msg = on_private_msg;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int plugin_unregister(struct plugin_handle* plugin)
|
||||||
|
{
|
||||||
|
struct chat_data* data = (struct chat_data*) plugin->ptr;
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
hub_free(data->users);
|
||||||
|
hub_free(data);
|
||||||
|
}
|
||||||
|
return 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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
struct topic_plugin_data
|
struct topic_plugin_data
|
||||||
{
|
{
|
||||||
struct plugin_command_handle* topic;
|
struct plugin_command_handle* topic;
|
||||||
struct plugin_command_handle* cleartopic;
|
struct plugin_command_handle* resettopic;
|
||||||
struct plugin_command_handle* showtopic;
|
struct plugin_command_handle* showtopic;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -33,19 +33,20 @@ static int command_topic_handler(struct plugin_handle* plugin, struct plugin_use
|
|||||||
{
|
{
|
||||||
struct cbuffer* buf = cbuf_create(128);
|
struct cbuffer* buf = cbuf_create(128);
|
||||||
struct plugin_command_arg_data* arg = plugin->hub.command_arg_next(plugin, cmd, plugin_cmd_arg_type_string);
|
struct plugin_command_arg_data* arg = plugin->hub.command_arg_next(plugin, cmd, plugin_cmd_arg_type_string);
|
||||||
|
char* topic = arg ? arg->data.string : "";
|
||||||
|
|
||||||
plugin->hub.set_description(plugin, arg ? arg->data.string : NULL);
|
plugin->hub.set_description(plugin, topic);
|
||||||
cbuf_append_format(buf, "*** %s: Topic set to \"%s\"", cmd->prefix, arg->data.string);
|
cbuf_append_format(buf, "*** %s: Topic set to \"%s\"", cmd->prefix, topic);
|
||||||
plugin->hub.send_message(plugin, user, cbuf_get(buf));
|
plugin->hub.send_message(plugin, user, cbuf_get(buf));
|
||||||
cbuf_destroy(buf);
|
cbuf_destroy(buf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int command_cleartopic_handler(struct plugin_handle* plugin, struct plugin_user* user, struct plugin_command* cmd)
|
static int command_resettopic_handler(struct plugin_handle* plugin, struct plugin_user* user, struct plugin_command* cmd)
|
||||||
{
|
{
|
||||||
struct cbuffer* buf = cbuf_create(128);
|
struct cbuffer* buf = cbuf_create(128);
|
||||||
plugin->hub.set_description(plugin, NULL);
|
plugin->hub.set_description(plugin, NULL);
|
||||||
cbuf_append_format(buf, "*** %s: Topic cleared.", cmd->prefix);
|
cbuf_append_format(buf, "*** %s: Topic reset.", cmd->prefix);
|
||||||
plugin->hub.send_message(plugin, user, cbuf_get(buf));
|
plugin->hub.send_message(plugin, user, cbuf_get(buf));
|
||||||
cbuf_destroy(buf);
|
cbuf_destroy(buf);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -67,17 +68,17 @@ int plugin_register(struct plugin_handle* plugin, const char* config)
|
|||||||
struct topic_plugin_data* data = (struct topic_plugin_data*) hub_malloc(sizeof(struct topic_plugin_data));
|
struct topic_plugin_data* data = (struct topic_plugin_data*) hub_malloc(sizeof(struct topic_plugin_data));
|
||||||
|
|
||||||
data->topic = (struct plugin_command_handle*) hub_malloc_zero(sizeof(struct plugin_command_handle));
|
data->topic = (struct plugin_command_handle*) hub_malloc_zero(sizeof(struct plugin_command_handle));
|
||||||
data->cleartopic = (struct plugin_command_handle*) hub_malloc_zero(sizeof(struct plugin_command_handle));
|
data->resettopic = (struct plugin_command_handle*) hub_malloc_zero(sizeof(struct plugin_command_handle));
|
||||||
data->showtopic = (struct plugin_command_handle*) hub_malloc_zero(sizeof(struct plugin_command_handle));
|
data->showtopic = (struct plugin_command_handle*) hub_malloc_zero(sizeof(struct plugin_command_handle));
|
||||||
|
|
||||||
PLUGIN_INITIALIZE(plugin, "Topic plugin", "1.0", "Add commands for changing the hub topic (description)");
|
PLUGIN_INITIALIZE(plugin, "Topic plugin", "1.0", "Add commands for changing the hub topic (description)");
|
||||||
|
|
||||||
PLUGIN_COMMAND_INITIALIZE(data->topic, (void*) data, "topic", "+m", auth_cred_operator, command_topic_handler, "Set new topic");
|
PLUGIN_COMMAND_INITIALIZE(data->topic, (void*) data, "topic", "+m", auth_cred_operator, command_topic_handler, "Set new topic");
|
||||||
PLUGIN_COMMAND_INITIALIZE(data->cleartopic, (void*) data, "cleartopic", "", auth_cred_operator, command_cleartopic_handler, "Clear the current topic");
|
PLUGIN_COMMAND_INITIALIZE(data->resettopic, (void*) data, "resettopic", "", auth_cred_operator, command_resettopic_handler, "Set topic to default");
|
||||||
PLUGIN_COMMAND_INITIALIZE(data->showtopic, (void*) data, "showtopic", "", auth_cred_guest, command_showtopic_handler, "Shows the current topic");
|
PLUGIN_COMMAND_INITIALIZE(data->showtopic, (void*) data, "showtopic", "", auth_cred_guest, command_showtopic_handler, "Shows the current topic");
|
||||||
|
|
||||||
plugin->hub.command_add(plugin, data->topic);
|
plugin->hub.command_add(plugin, data->topic);
|
||||||
plugin->hub.command_add(plugin, data->cleartopic);
|
plugin->hub.command_add(plugin, data->resettopic);
|
||||||
plugin->hub.command_add(plugin, data->showtopic);
|
plugin->hub.command_add(plugin, data->showtopic);
|
||||||
plugin->ptr = data;
|
plugin->ptr = data;
|
||||||
|
|
||||||
@@ -90,10 +91,10 @@ int plugin_unregister(struct plugin_handle* plugin)
|
|||||||
struct topic_plugin_data* data = (struct topic_plugin_data*) plugin->ptr;
|
struct topic_plugin_data* data = (struct topic_plugin_data*) plugin->ptr;
|
||||||
|
|
||||||
plugin->hub.command_del(plugin, data->topic);
|
plugin->hub.command_del(plugin, data->topic);
|
||||||
plugin->hub.command_del(plugin, data->cleartopic);
|
plugin->hub.command_del(plugin, data->resettopic);
|
||||||
plugin->hub.command_del(plugin, data->showtopic);
|
plugin->hub.command_del(plugin, data->showtopic);
|
||||||
hub_free(data->topic);
|
hub_free(data->topic);
|
||||||
hub_free(data->cleartopic);
|
hub_free(data->resettopic);
|
||||||
hub_free(data->showtopic);
|
hub_free(data->showtopic);
|
||||||
hub_free(data);
|
hub_free(data);
|
||||||
plugin->ptr = NULL;
|
plugin->ptr = NULL;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -22,10 +22,6 @@
|
|||||||
|
|
||||||
#define _FILE_OFFSET_BITS 64
|
#define _FILE_OFFSET_BITS 64
|
||||||
|
|
||||||
#ifndef _GNU_SOURCE
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD_kernel__)
|
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD_kernel__)
|
||||||
#define BSD_LIKE
|
#define BSD_LIKE
|
||||||
#endif
|
#endif
|
||||||
@@ -38,10 +34,14 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__CYGWIN__) || defined(__MINGW32__)
|
#if defined(__CYGWIN__) || defined(__MINGW32__)
|
||||||
#define HAVE_SSIZE_T
|
|
||||||
#define NEED_GETOPT
|
#define NEED_GETOPT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#cmakedefine HAVE_SYS_TYPES_H
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WINSOCK
|
#ifdef WINSOCK
|
||||||
#ifndef FD_SETSIZE
|
#ifndef FD_SETSIZE
|
||||||
#define FD_SETSIZE 4096
|
#define FD_SETSIZE 4096
|
||||||
@@ -49,7 +49,6 @@
|
|||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#else
|
#else
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
@@ -62,7 +61,8 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
#ifndef __sun__
|
#cmakedefine HAVE_STDINT_H
|
||||||
|
#ifdef HAVE_STDINT_H
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -79,16 +79,14 @@
|
|||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#define HAVE_STRNDUP
|
|
||||||
#define HAVE_DLOPEN
|
#define HAVE_DLOPEN
|
||||||
#define HAVE_GETOPT
|
#define HAVE_GETOPT
|
||||||
#define HAVE_SSIZE_T
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#ifndef __HAIKU__
|
|
||||||
#define HAVE_MEMMEM
|
|
||||||
#endif
|
|
||||||
#define HAVE_GETRLIMIT
|
#define HAVE_GETRLIMIT
|
||||||
#endif
|
#endif
|
||||||
|
#cmakedefine HAVE_SSIZE_T
|
||||||
|
#cmakedefine HAVE_STRNDUP
|
||||||
|
#cmakedefine HAVE_MEMMEM
|
||||||
|
|
||||||
/* printf support for size_t and uint64_t */
|
/* printf support for size_t and uint64_t */
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
@@ -103,6 +101,8 @@
|
|||||||
#ifdef SSL_USE_OPENSSL
|
#ifdef SSL_USE_OPENSSL
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
|
#include <openssl/engine.h>
|
||||||
|
#include <openssl/conf.h>
|
||||||
#endif /* SSL_USE_OPENSSL */
|
#endif /* SSL_USE_OPENSSL */
|
||||||
#ifdef SSL_USE_GNUTLS
|
#ifdef SSL_USE_GNUTLS
|
||||||
#include <gnutls/gnutls.h>
|
#include <gnutls/gnutls.h>
|
||||||
@@ -136,11 +136,6 @@
|
|||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ( defined(BSD_LIKE) && !defined(__FreeBSD_kernel__) ) || defined(__sun__)
|
|
||||||
#undef HAVE_STRNDUP
|
|
||||||
#undef HAVE_MEMMEM
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_GETOPT
|
#ifdef HAVE_GETOPT
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#endif
|
#endif
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user