Compare commits
	
		
			2 Commits
		
	
	
		
			master
			...
			link_suppo
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 51fba8a7a1 | ||
|  | a7898779cb | 
							
								
								
									
										17
									
								
								.drone.yml
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								.drone.yml
									
									
									
									
									
								
							| @ -1,17 +0,0 @@ | |||||||
| kind: pipeline |  | ||||||
| name: default |  | ||||||
| 
 |  | ||||||
| steps: |  | ||||||
| - name: docker |  | ||||||
|   image: plugins/docker |  | ||||||
|   network_mode: bridge |  | ||||||
|   settings: |  | ||||||
|     repo: sneak/uhub |  | ||||||
|     username: |  | ||||||
|       from_secret: docker_username |  | ||||||
|     password: |  | ||||||
|       from_secret: docker_password |  | ||||||
|     tags: |  | ||||||
|       - ${DRONE_BRANCH//\//-}-${DRONE_COMMIT_SHA:0:8} |  | ||||||
|       - ${DRONE_COMMIT_SHA} |  | ||||||
|       - ${DRONE_BRANCH/\//-} |  | ||||||
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -14,6 +14,7 @@ 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 | ||||||
| @ -21,3 +22,5 @@ debian/uhub.postrm.debhelper | |||||||
| debian/uhub.prerm.debhelper | debian/uhub.prerm.debhelper | ||||||
| debian/uhub.substvars | debian/uhub.substvars | ||||||
| uhub-passwd | uhub-passwd | ||||||
|  | src/version.h | ||||||
|  | 
 | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							| @ -1,3 +1,3 @@ | |||||||
| [submodule "thirdparty/sqlite"] | [submodule "thirdparty/sqlite"] | ||||||
| 	path = thirdparty/sqlite | 	path = thirdparty/sqlite | ||||||
| 	url = https://github.com/janvidar/sqlite.git | 	url = git://github.com/janvidar/sqlite.git | ||||||
|  | |||||||
							
								
								
									
										14
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								.travis.yml
									
									
									
									
									
								
							| @ -1,14 +0,0 @@ | |||||||
| language: cpp |  | ||||||
| dist: xenial |  | ||||||
| compiler: |  | ||||||
|   - gcc |  | ||||||
|   - clang |  | ||||||
| env: |  | ||||||
|   - CONFIG=minimal |  | ||||||
|   - CONFIG=full |  | ||||||
| install: |  | ||||||
|   - autotest/travis/install-build-depends.sh |  | ||||||
| script: |  | ||||||
|   - autotest/travis/build-and-test.sh |  | ||||||
| dist: xenial |  | ||||||
| 
 |  | ||||||
							
								
								
									
										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, and plugins | MiMic, Implemented user commands | ||||||
| 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 | ||||||
|  | |||||||
							
								
								
									
										3
									
								
								BUGS
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								BUGS
									
									
									
									
									
								
							| @ -1 +1,2 @@ | |||||||
| Bugs are tracked on: https://github.com/janvidar/uhub/issues | Bugs are tracked on: http://bugs.extatic.org/ | ||||||
|  | 
 | ||||||
|  | |||||||
							
								
								
									
										112
									
								
								CMakeLists.txt
									
									
									
									
									
								
							
							
						
						
									
										112
									
								
								CMakeLists.txt
									
									
									
									
									
								
							| @ -1,6 +1,6 @@ | |||||||
|  ## |  ## | ||||||
| ## Makefile for uhub | ## Makefile for uhub | ||||||
| ## Copyright (C) 2007-2013, Jan Vidar Krey <janvidar@extatic.org> | ## Copyright (C) 2007-2012, 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 5) | set (UHUB_VERSION_MINOR 4) | ||||||
| set (UHUB_VERSION_PATCH 1) | set (UHUB_VERSION_PATCH 1) | ||||||
| 
 | 
 | ||||||
| set (PROJECT_SOURCE_DIR "${CMAKE_SOURCE_DIR}/src") | set (PROJECT_SOURCE_DIR "${CMAKE_SOURCE_DIR}/src") | ||||||
| set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake/Modules) | 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(LOWLEVEL_DEBUG, "Enable low level debug messages." OFF) | option(LINK_SUPPORT "Allow hub linking" 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,24 +25,6 @@ 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) | ||||||
| @ -50,36 +32,26 @@ 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 were found!") | 		message(FATAL_ERROR "Neither OpenSSL nor GnuTLS are not found!") | ||||||
| 	endif() | 	endif() | ||||||
| endif() | endif() | ||||||
| 
 | 
 | ||||||
| if (NOT SQLITE3_FOUND) | if (LINK_SUPPORT) | ||||||
|     message(FATAL_ERROR "SQLite3 is not found!") | 	add_definitions(-DLINK_SUPPORT) | ||||||
| endif() | endif() | ||||||
| 
 | 
 | ||||||
| if (SYSTEMD_SUPPORT) | if (SYSTEMD_SUPPORT) | ||||||
|         INCLUDE(FindPkgConfig) |         INCLUDE(FindPkgConfig) | ||||||
|         pkg_search_module(SD REQUIRED libsystemd) |         pkg_search_module(SD_DAEMON REQUIRED libsystemd-daemon) | ||||||
|  |         pkg_search_module(SD_JOURNAL REQUIRED libsystemd-journal) | ||||||
| endif() | endif() | ||||||
| 
 | 
 | ||||||
| if (MSVC) | if (MSVC) | ||||||
| 	add_definitions(-D_CRT_SECURE_NO_WARNINGS) | 	add_definitions(-D_CRT_SECURE_NO_WARNINGS) | ||||||
| endif() | endif() | ||||||
| 
 | 
 | ||||||
| check_include_file(stdint.h HAVE_STDINT_H) |  | ||||||
| check_include_file(sys/types.h HAVE_SYS_TYPES_H) |  | ||||||
| if (HAVE_SYS_TYPES_H) |  | ||||||
| set (CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES} "sys/types.h") |  | ||||||
| endif() |  | ||||||
| check_type_size( ssize_t SSIZE_T ) |  | ||||||
| check_symbol_exists(memmem string.h HAVE_MEMMEM) |  | ||||||
| check_symbol_exists(strndup string.h HAVE_STRNDUP) |  | ||||||
| 
 |  | ||||||
| include_directories("${PROJECT_SOURCE_DIR}") | include_directories("${PROJECT_SOURCE_DIR}") | ||||||
| include_directories("${PROJECT_BINARY_DIR}") |  | ||||||
| include_directories(${SQLITE3_INCLUDE_DIRS}) | 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 | ||||||
| @ -99,7 +71,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_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") | if(CMAKE_COMPILER_IS_GNUCC) | ||||||
| 	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() | ||||||
| @ -108,7 +80,7 @@ add_dependencies(adc utils) | |||||||
| add_dependencies(network utils) | add_dependencies(network utils) | ||||||
| 
 | 
 | ||||||
| add_executable(uhub ${PROJECT_SOURCE_DIR}/core/main.c ${uhub_SOURCES} ) | add_executable(uhub ${PROJECT_SOURCE_DIR}/core/main.c ${uhub_SOURCES} ) | ||||||
| add_executable(autotest-bin ${CMAKE_SOURCE_DIR}/autotest/test.c ${uhub_SOURCES} ) | add_executable(test ${CMAKE_SOURCE_DIR}/autotest/test.c ${uhub_SOURCES} ) | ||||||
| add_executable(uhub-passwd ${PROJECT_SOURCE_DIR}/tools/uhub-passwd.c) | add_executable(uhub-passwd ${PROJECT_SOURCE_DIR}/tools/uhub-passwd.c) | ||||||
| 
 | 
 | ||||||
| add_library(mod_example MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_example.c) | add_library(mod_example MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_example.c) | ||||||
| @ -116,12 +88,18 @@ 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) | ||||||
| add_library(mod_auth_sqlite MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_auth_sqlite.c) | add_library(mod_auth_sqlite MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_auth_sqlite.c) | ||||||
| 
 | 
 | ||||||
|  | if(WIN32) | ||||||
|  | 	target_link_libraries(uhub ws2_32) | ||||||
|  | 	target_link_libraries(test ws2_32) | ||||||
|  | 	target_link_libraries(mod_logging ws2_32) | ||||||
|  | 	target_link_libraries(mod_welcome ws2_32) | ||||||
|  | endif() | ||||||
|  | 
 | ||||||
| set_target_properties( | set_target_properties( | ||||||
| 	mod_example | 	mod_example | ||||||
| 	mod_welcome | 	mod_welcome | ||||||
| @ -129,7 +107,6 @@ 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 | ||||||
| @ -137,32 +114,27 @@ set_target_properties( | |||||||
| 
 | 
 | ||||||
| target_link_libraries(uhub ${CMAKE_DL_LIBS} adc network utils) | target_link_libraries(uhub ${CMAKE_DL_LIBS} adc network utils) | ||||||
| target_link_libraries(uhub-passwd ${SQLITE3_LIBRARIES} utils) | target_link_libraries(uhub-passwd ${SQLITE3_LIBRARIES} utils) | ||||||
| target_link_libraries(autotest-bin ${CMAKE_DL_LIBS} adc network utils) | target_link_libraries(test ${CMAKE_DL_LIBS} adc network utils) | ||||||
| target_link_libraries(mod_example utils) | target_link_libraries(mod_example utils) | ||||||
| target_link_libraries(mod_welcome network utils) | 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 network utils) | target_link_libraries(mod_logging utils) | ||||||
| target_link_libraries(mod_topic utils) | target_link_libraries(mod_topic utils) | ||||||
| target_link_libraries(utils network) | target_link_libraries(utils network) | ||||||
|  | target_link_libraries(mod_welcome network) | ||||||
|  | target_link_libraries(mod_logging network) | ||||||
| 
 | 
 | ||||||
| if(WIN32) |  | ||||||
| 	target_link_libraries(uhub ws2_32) |  | ||||||
| 	target_link_libraries(autotest-bin ws2_32) |  | ||||||
| 	target_link_libraries(mod_logging ws2_32) |  | ||||||
| 	target_link_libraries(mod_welcome ws2_32) |  | ||||||
| endif() |  | ||||||
| 
 | 
 | ||||||
| if(UNIX) | if(UNIX) | ||||||
| 	add_library(adcclient STATIC ${adcclient_SOURCES}) | 	add_library(adcclient STATIC ${adcclient_SOURCES}) | ||||||
| 	add_executable(uhub-admin ${PROJECT_SOURCE_DIR}/tools/admin.c) | 	add_executable(uhub-admin ${PROJECT_SOURCE_DIR}/tools/admin.c) | ||||||
| 	target_link_libraries(uhub-admin adcclient adc network utils pthread) | 	target_link_libraries(uhub-admin adcclient adc network utils pthread) | ||||||
| 	target_link_libraries(uhub pthread) | 	target_link_libraries(uhub pthread) | ||||||
| 	target_link_libraries(autotest-bin pthread) | 	target_link_libraries(test pthread) | ||||||
| 
 | 
 | ||||||
| 	if (ADC_STRESS) | 	if (ADC_STRESS) | ||||||
| 		add_executable(adcrush ${PROJECT_SOURCE_DIR}/tools/adcrush.c ${adcclient_SOURCES}) | 		add_executable(adcrush ${PROJECT_SOURCE_DIR}/tools/adcrush.c ${adcclient_SOURCES}) | ||||||
| @ -201,7 +173,7 @@ endif() | |||||||
| 
 | 
 | ||||||
| if(SSL_SUPPORT) | if(SSL_SUPPORT) | ||||||
| 	target_link_libraries(uhub ${SSL_LIBS}) | 	target_link_libraries(uhub ${SSL_LIBS}) | ||||||
| 	target_link_libraries(autotest-bin ${SSL_LIBS}) | 	target_link_libraries(test ${SSL_LIBS}) | ||||||
| 	if(UNIX) | 	if(UNIX) | ||||||
| 		target_link_libraries(uhub-admin ${SSL_LIBS}) | 		target_link_libraries(uhub-admin ${SSL_LIBS}) | ||||||
| 	endif() | 	endif() | ||||||
| @ -213,33 +185,31 @@ if(SSL_SUPPORT) | |||||||
| endif() | endif() | ||||||
| 
 | 
 | ||||||
| if (SYSTEMD_SUPPORT) | if (SYSTEMD_SUPPORT) | ||||||
|         target_link_libraries(uhub ${SD_LIBRARIES}) |         target_link_libraries(uhub ${SD_DAEMON_LIBRARIES}) | ||||||
|         target_link_libraries(autotest-bin ${SD_LIBRARIES}) |         target_link_libraries(uhub ${SD_JOURNAL_LIBRARIES}) | ||||||
|         target_link_libraries(uhub-passwd ${SD_LIBRARIES}) |         target_link_libraries(test ${SD_DAEMON_LIBRARIES}) | ||||||
|         target_link_libraries(uhub-admin ${SD_LIBRARIES}) |         target_link_libraries(test ${SD_JOURNAL_LIBRARIES}) | ||||||
|         include_directories(${SD_INCLUDE_DIRS}) |         target_link_libraries(uhub-passwd ${SD_JOURNAL_LIBRARIES}) | ||||||
|  |         target_link_libraries(uhub-admin ${SD_JOURNAL_LIBRARIES}) | ||||||
|  |         include_directories(${SD_DAEMON_INCLUDE_DIRS}) | ||||||
|  |         include_directories(${SD_JOURNAL_INCLUDE_DIRS}) | ||||||
|         add_definitions(-DSYSTEMD) |         add_definitions(-DSYSTEMD) | ||||||
| endif() | endif() | ||||||
| 
 | 
 | ||||||
| configure_file ("${PROJECT_SOURCE_DIR}/version.h.in" "${PROJECT_BINARY_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_BINARY_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_history_sqlite 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_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() | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										26
									
								
								ChangeLog
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								ChangeLog
									
									
									
									
									
								
							| @ -1,23 +1,3 @@ | |||||||
| 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. | ||||||
| @ -47,8 +27,8 @@ | |||||||
| - marked plugin callbacks that are not called yet | - marked plugin callbacks that are not called yet | ||||||
| - add on_change_nick() to struct plugin_funcs | - add on_change_nick() to struct plugin_funcs | ||||||
| - minimal changes | - minimal changes | ||||||
| - Updated init script in Debian package. | - Updated init script in debian package. | ||||||
| - Updated list of man pages in Debian package. | - Updated list of man pages in debian package. | ||||||
| - Added man page for uhub-passwd. | - Added man page for uhub-passwd. | ||||||
| - Merge branch 'master' of https://github.com/Tilka/uhub | - Merge branch 'master' of https://github.com/Tilka/uhub | ||||||
| - Fix issue with QUI messages being allowed through the hub | - Fix issue with QUI messages being allowed through the hub | ||||||
| @ -78,7 +58,7 @@ | |||||||
| - minimal documentation fixes | - minimal documentation fixes | ||||||
| - update client software link | - update client software link | ||||||
| - update compile howto link | - update compile howto link | ||||||
| - fix Debian changelog | - fix debian changelog | ||||||
| - Fix bug #158 - Added plugin for setting topic (hub description). | - Fix bug #158 - Added plugin for setting topic (hub description). | ||||||
| - Command arguments handling + cleanups | - Command arguments handling + cleanups | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										19
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								Dockerfile
									
									
									
									
									
								
							| @ -1,19 +0,0 @@ | |||||||
| FROM alpine:latest as builder |  | ||||||
| RUN apk update && apk upgrade && apk add --no-cache bash util-linux cmake make gcc git sqlite-dev openssl-dev git build-base |  | ||||||
| WORKDIR /app |  | ||||||
| COPY . . |  | ||||||
| RUN cmake . && make |  | ||||||
| RUN sed -i 's/\/usr\/lib\/uhub\//\/libs\//g' ./doc/*.conf && \ |  | ||||||
| sed -i 's/\/usr\/lib\/uhub\//\/libs\//g' ./doc/rules.txt && \ |  | ||||||
| sed -i 's/\/etc\/uhub\//\/conf\//g' ./doc/*.conf && \ |  | ||||||
| sed -i 's/\/etc\/uhub\//\/conf\//g' ./doc/rules.txt && \ |  | ||||||
| echo 'Welcome to uHub' > ./doc/motd.txt |  | ||||||
| 
 |  | ||||||
| FROM alpine:latest |  | ||||||
| RUN apk update && apk upgrade && apk add --no-cache bash util-linux openssl-dev sqlite-dev |  | ||||||
| WORKDIR /app |  | ||||||
| COPY --from=builder /app/uhub . |  | ||||||
| COPY --from=builder /app/doc/plugins.conf /app/doc/uhub.conf /app/doc/users.conf /app/doc/rules.txt /app/doc/motd.txt /conf/ |  | ||||||
| COPY --from=builder /app/*.so /libs/ |  | ||||||
| ENTRYPOINT ["./uhub"] |  | ||||||
| CMD ["-c","/conf/uhub.conf"] |  | ||||||
| @ -1,13 +1,8 @@ | |||||||
| # uhub |  | ||||||
| 
 |  | ||||||
| Welcome and thanks for downloading uHub, a high performance ADC p2p hub. | Welcome and thanks for downloading uHub, a high performance ADC p2p hub. | ||||||
| 
 | 
 | ||||||
| For the official documentation, bugs and other information, please visit: | For the official documentation, bugs and other information, please visit: | ||||||
| https://www.uhub.org/ | http://www.uhub.org/ | ||||||
| 
 | 
 | ||||||
| For a list of compatible ADC clients, see: | For a list of compatible ADC clients, see: | ||||||
| https://en.wikipedia.org/wiki/Comparison_of_ADC_software#Client_software | http://en.wikipedia.org/wiki/Advanced_Direct_Connect#Client_software | ||||||
| 
 | 
 | ||||||
| # on dockerhub |  | ||||||
| 
 |  | ||||||
| * https://hub.docker.com/r/sneak/uhub |  | ||||||
| @ -78,7 +78,7 @@ Description: a high performance hub for the ADC peer-to-peer network | |||||||
|  Its low memory footprint allows it to handle several thousand users |  Its low memory footprint allows it to handle several thousand users | ||||||
|  on high-end servers, or a small private hub on embedded hardware. |  on high-end servers, or a small private hub on embedded hardware. | ||||||
|  . |  . | ||||||
| Homepage: https://www.uhub.org/ | Homepage: http://www.extatic.org/uhub/ | ||||||
| EOF | EOF | ||||||
| cd .. | cd .. | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -516,15 +516,6 @@ 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"); | ||||||
| @ -706,34 +697,6 @@ int main(int argc, char** argv) | |||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_10, "utf8_valid_10"); | 	exotic_add_test(&handle, &exotic_test_utf8_valid_10, "utf8_valid_10"); | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_11, "utf8_valid_11"); | 	exotic_add_test(&handle, &exotic_test_utf8_valid_11, "utf8_valid_11"); | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_12, "utf8_valid_12"); | 	exotic_add_test(&handle, &exotic_test_utf8_valid_12, "utf8_valid_12"); | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_13, "utf8_valid_13"); |  | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_14, "utf8_valid_14"); |  | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_15, "utf8_valid_15"); |  | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_16, "utf8_valid_16"); |  | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_17, "utf8_valid_17"); |  | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_18, "utf8_valid_18"); |  | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_19, "utf8_valid_19"); |  | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_20, "utf8_valid_20"); |  | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_21, "utf8_valid_21"); |  | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_22, "utf8_valid_22"); |  | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_23, "utf8_valid_23"); |  | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_24, "utf8_valid_24"); |  | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_25, "utf8_valid_25"); |  | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_26, "utf8_valid_26"); |  | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_27, "utf8_valid_27"); |  | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_28, "utf8_valid_28"); |  | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_29, "utf8_valid_29"); |  | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_30, "utf8_valid_30"); |  | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_31, "utf8_valid_31"); |  | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_32, "utf8_valid_32"); |  | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_33, "utf8_valid_33"); |  | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_34, "utf8_valid_34"); |  | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_35, "utf8_valid_35"); |  | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_36, "utf8_valid_36"); |  | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_37, "utf8_valid_37"); |  | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_38, "utf8_valid_38"); |  | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_39, "utf8_valid_39"); |  | ||||||
| 	exotic_add_test(&handle, &exotic_test_utf8_valid_40, "utf8_valid_40"); |  | ||||||
| 	exotic_add_test(&handle, &exotic_test_rbtree_create_destroy, "rbtree_create_destroy"); | 	exotic_add_test(&handle, &exotic_test_rbtree_create_destroy, "rbtree_create_destroy"); | ||||||
| 	exotic_add_test(&handle, &exotic_test_rbtree_create_1, "rbtree_create_1"); | 	exotic_add_test(&handle, &exotic_test_rbtree_create_1, "rbtree_create_1"); | ||||||
| 	exotic_add_test(&handle, &exotic_test_rbtree_size_0, "rbtree_size_0"); | 	exotic_add_test(&handle, &exotic_test_rbtree_size_0, "rbtree_size_0"); | ||||||
| @ -760,8 +723,7 @@ 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_10000, "rbtree_remove_10000"); | 	exotic_add_test(&handle, &exotic_test_rbtree_remove_5000, "rbtree_remove_5000"); | ||||||
| 	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"); | ||||||
| @ -799,7 +761,6 @@ 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"); | ||||||
| @ -990,6 +951,7 @@ 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,8 +14,10 @@ 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)); | ||||||
| 	 | 	 | ||||||
| @ -25,9 +27,12 @@ static void inf_create_hub() | |||||||
| 
 | 
 | ||||||
| static void inf_destroy_hub() | static void inf_destroy_hub() | ||||||
| { | { | ||||||
| 	uman_shutdown(inf_hub->users); | 	/* FIXME */ | ||||||
|  | 	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,16 +1,10 @@ | |||||||
| #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) | ||||||
| { | { | ||||||
| @ -130,83 +124,6 @@ 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); | ||||||
|  | |||||||
| @ -107,7 +107,6 @@ static const char test_utf_seq_6[] = { 0xE2, 0x82, 0xAC, 0x00}; // valid | |||||||
| static const char test_utf_seq_7[] = { 0xC2, 0x32, 0x00}; // invalid | static const char test_utf_seq_7[] = { 0xC2, 0x32, 0x00}; // invalid | ||||||
| static const char test_utf_seq_8[] = { 0xE2, 0x82, 0x32, 0x00}; // invalid | static const char test_utf_seq_8[] = { 0xE2, 0x82, 0x32, 0x00}; // invalid | ||||||
| static const char test_utf_seq_9[] = { 0xE2, 0x32, 0x82, 0x00}; // invalid | static const char test_utf_seq_9[] = { 0xE2, 0x32, 0x82, 0x00}; // invalid | ||||||
| static const char test_utf_seq_10[] = { 0xF0, 0x9F, 0x98, 0x81, 0x00}; // valid |  | ||||||
| 
 | 
 | ||||||
| EXO_TEST(utf8_valid_4, { return is_valid_utf8(test_utf_seq_1); }); | EXO_TEST(utf8_valid_4, { return is_valid_utf8(test_utf_seq_1); }); | ||||||
| EXO_TEST(utf8_valid_5, { return !is_valid_utf8(test_utf_seq_2); }); | EXO_TEST(utf8_valid_5, { return !is_valid_utf8(test_utf_seq_2); }); | ||||||
| @ -118,61 +117,5 @@ EXO_TEST(utf8_valid_9, { return is_valid_utf8(test_utf_seq_6); }); | |||||||
| EXO_TEST(utf8_valid_10, { return !is_valid_utf8(test_utf_seq_7); }); | EXO_TEST(utf8_valid_10, { return !is_valid_utf8(test_utf_seq_7); }); | ||||||
| EXO_TEST(utf8_valid_11, { return !is_valid_utf8(test_utf_seq_8); }); | EXO_TEST(utf8_valid_11, { return !is_valid_utf8(test_utf_seq_8); }); | ||||||
| EXO_TEST(utf8_valid_12, { return !is_valid_utf8(test_utf_seq_9); }); | EXO_TEST(utf8_valid_12, { return !is_valid_utf8(test_utf_seq_9); }); | ||||||
| EXO_TEST(utf8_valid_13, { return is_valid_utf8(test_utf_seq_10); }); |  | ||||||
| 
 | 
 | ||||||
| // Limits of utf-8 |  | ||||||
| static const char test_utf_seq_11[] = { 0x7F, 0x00 }; // valid last 7-bit character |  | ||||||
| static const char test_utf_seq_12[] = { 0x80, 0x00 }; // invalid truncated string |  | ||||||
| static const char test_utf_seq_13[] = { 0xBF, 0x00 }; // invalid truncated string |  | ||||||
| static const char test_utf_seq_14[] = { 0xC0, 0x80, 0x00 }; // invalid out of 2 bytes range |  | ||||||
| static const char test_utf_seq_15[] = { 0xC1, 0x7F, 0x00 }; // invalid out of 2 bytes range |  | ||||||
| static const char test_utf_seq_16[] = { 0xC2, 0x00 }; // invalid truncated string |  | ||||||
| static const char test_utf_seq_17[] = { 0xC2, 0x80, 0x00 }; // valid |  | ||||||
| static const char test_utf_seq_18[] = { 0xDF, 0xBF, 0x00 }; // valid |  | ||||||
| static const char test_utf_seq_19[] = { 0xE0, 0x80, 0x80, 0x00 }; // invalid out of 3 bytes range |  | ||||||
| static const char test_utf_seq_20[] = { 0xE0, 0x9F, 0xBF, 0x00 }; // invalid out of 3 bytes range |  | ||||||
| static const char test_utf_seq_21[] = { 0xE0, 0x00 }; // invalid truncated string |  | ||||||
| static const char test_utf_seq_22[] = { 0xE0, 0xA0, 0x00 }; // invalid truncated string |  | ||||||
| static const char test_utf_seq_23[] = { 0xE0, 0xA0, 0x80, 0x00 }; // valid |  | ||||||
| static const char test_utf_seq_24[] = { 0xEC, 0x9F, 0xBF, 0x00 }; // valid |  | ||||||
| static const char test_utf_seq_25[] = { 0xED, 0xA0, 0x80, 0x00 }; // invalid surrogate |  | ||||||
| static const char test_utf_seq_26[] = { 0xED, 0xBF, 0xBF, 0x00 }; // invalid surrogate |  | ||||||
| static const char test_utf_seq_27[] = { 0xEF, 0x80, 0x80, 0x00 }; // valid |  | ||||||
| static const char test_utf_seq_28[] = { 0xEF, 0xBF, 0xBF, 0x00 }; // valid |  | ||||||
| static const char test_utf_seq_29[] = { 0xF0, 0x80, 0x80, 0x80, 0x00 }; // invalid out of 4 bytes range |  | ||||||
| static const char test_utf_seq_30[] = { 0xF0, 0x8F, 0xBF, 0xBF, 0x00 }; // invalid out of 4 bytes range |  | ||||||
| static const char test_utf_seq_31[] = { 0xF0, 0x00 }; // invalid truncated string |  | ||||||
| static const char test_utf_seq_32[] = { 0xF0, 0x90, 0x00 }; // invalid truncated string |  | ||||||
| static const char test_utf_seq_33[] = { 0xF0, 0x90, 0x80, 0x00 }; // invalid truncated string |  | ||||||
| static const char test_utf_seq_34[] = { 0xF0, 0x90, 0x80, 0x80, 0x00 }; // valid |  | ||||||
| static const char test_utf_seq_35[] = { 0xF4, 0x8F, 0xBF, 0xBF, 0x00 }; // valid |  | ||||||
| static const char test_utf_seq_36[] = { 0xF4, 0x90, 0x80, 0x80, 0x00 }; // invalid out of 4 bytes range |  | ||||||
| static const char test_utf_seq_37[] = { 0xFF, 0xBF, 0xBF, 0xBF, 0x00 }; // invalid out of 4 bytes range |  | ||||||
| 
 | 
 | ||||||
| EXO_TEST(utf8_valid_14, { return is_valid_utf8(test_utf_seq_11); }); |  | ||||||
| EXO_TEST(utf8_valid_15, { return !is_valid_utf8(test_utf_seq_12); }); |  | ||||||
| EXO_TEST(utf8_valid_16, { return !is_valid_utf8(test_utf_seq_13); }); |  | ||||||
| EXO_TEST(utf8_valid_17, { return !is_valid_utf8(test_utf_seq_14); }); |  | ||||||
| EXO_TEST(utf8_valid_18, { return !is_valid_utf8(test_utf_seq_15); }); |  | ||||||
| EXO_TEST(utf8_valid_19, { return !is_valid_utf8(test_utf_seq_16); }); |  | ||||||
| EXO_TEST(utf8_valid_20, { return is_valid_utf8(test_utf_seq_17); }); |  | ||||||
| EXO_TEST(utf8_valid_21, { return is_valid_utf8(test_utf_seq_18); }); |  | ||||||
| EXO_TEST(utf8_valid_22, { return !is_valid_utf8(test_utf_seq_19); }); |  | ||||||
| EXO_TEST(utf8_valid_23, { return !is_valid_utf8(test_utf_seq_20); }); |  | ||||||
| EXO_TEST(utf8_valid_24, { return !is_valid_utf8(test_utf_seq_21); }); |  | ||||||
| EXO_TEST(utf8_valid_25, { return !is_valid_utf8(test_utf_seq_22); }); |  | ||||||
| EXO_TEST(utf8_valid_26, { return is_valid_utf8(test_utf_seq_23); }); |  | ||||||
| EXO_TEST(utf8_valid_27, { return is_valid_utf8(test_utf_seq_24); }); |  | ||||||
| EXO_TEST(utf8_valid_28, { return !is_valid_utf8(test_utf_seq_25); }); |  | ||||||
| EXO_TEST(utf8_valid_29, { return !is_valid_utf8(test_utf_seq_26); }); |  | ||||||
| EXO_TEST(utf8_valid_30, { return is_valid_utf8(test_utf_seq_27); }); |  | ||||||
| EXO_TEST(utf8_valid_31, { return is_valid_utf8(test_utf_seq_28); }); |  | ||||||
| EXO_TEST(utf8_valid_32, { return !is_valid_utf8(test_utf_seq_29); }); |  | ||||||
| EXO_TEST(utf8_valid_33, { return !is_valid_utf8(test_utf_seq_30); }); |  | ||||||
| EXO_TEST(utf8_valid_34, { return !is_valid_utf8(test_utf_seq_31); }); |  | ||||||
| EXO_TEST(utf8_valid_35, { return !is_valid_utf8(test_utf_seq_32); }); |  | ||||||
| EXO_TEST(utf8_valid_36, { return !is_valid_utf8(test_utf_seq_33); }); |  | ||||||
| EXO_TEST(utf8_valid_37, { return is_valid_utf8(test_utf_seq_34); }); |  | ||||||
| EXO_TEST(utf8_valid_38, { return is_valid_utf8(test_utf_seq_35); }); |  | ||||||
| EXO_TEST(utf8_valid_39, { return !is_valid_utf8(test_utf_seq_36); }); |  | ||||||
| EXO_TEST(utf8_valid_40, { return !is_valid_utf8(test_utf_seq_37); }); |  | ||||||
|  | |||||||
| @ -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,35 +116,29 @@ 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_10000, { | EXO_TEST(rbtree_remove_5000, { | ||||||
| 	int i; | 	int i = 0; | ||||||
| 	int j; | 	struct rb_node* n = (struct rb_node*) rb_tree_first(tree); | ||||||
| 	for (j = 0; j < 2; j++) | 	for (i = 0; i < MAX_NODES ; i += 2) | ||||||
| 	{ |  | ||||||
| 		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 freed_nodes == MAX_NODES; |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| EXO_TEST(rbtree_destroy_1, { |  | ||||||
| 	rb_tree_destroy(tree); |  | ||||||
| 	return 1; | 	return 1; | ||||||
| }); | }); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | |||||||
| @ -117,9 +117,3 @@ 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; |  | ||||||
| }); |  | ||||||
|  | |||||||
| @ -1,43 +0,0 @@ | |||||||
| #!/bin/sh |  | ||||||
| 
 |  | ||||||
| set -x |  | ||||||
| set -e |  | ||||||
| 
 |  | ||||||
| export CFLAGS="$(dpkg-buildflags --get CFLAGS) $(dpkg-buildflags --get CPPFLAGS)" |  | ||||||
| export LDFLAGS="$(dpkg-buildflags --get LDFLAGS) -Wl,--as-needed" |  | ||||||
| 
 |  | ||||||
| mkdir -p builddir |  | ||||||
| cd builddir |  | ||||||
| 
 |  | ||||||
| CMAKEOPTS=".. |  | ||||||
|            -DCMAKE_INSTALL_PREFIX=/usr" |  | ||||||
| 
 |  | ||||||
| if [ "${CONFIG}" = "full" ]; then |  | ||||||
|     CMAKEOPTS="${CMAKEOPTS} |  | ||||||
|                -DRELEASE=OFF |  | ||||||
|                -DLOWLEVEL_DEBUG=ON |  | ||||||
|                -DSSL_SUPPORT=ON |  | ||||||
|                -DUSE_OPENSSL=ON |  | ||||||
|                -DADC_STRESS=ON" |  | ||||||
| else |  | ||||||
|     CMAKEOPTS="${CMAKEOPTS} |  | ||||||
|                -DRELEASE=ON |  | ||||||
|                -DLOWLEVEL_DEBUG=OFF |  | ||||||
|                -DSSL_SUPPORT=OFF |  | ||||||
|                -DADC_STRESS=OFF" |  | ||||||
| fi |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| cmake ${CMAKEOPTS} \ |  | ||||||
|       -DCMAKE_C_FLAGS="${CFLAGS}" \ |  | ||||||
|       -DCMAKE_EXE_LINKER_FLAGS="${LDFLAGS}" |  | ||||||
| make VERBOSE=1 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| make VERBOSE=1 autotest-bin |  | ||||||
| ./autotest-bin |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| sudo make install |  | ||||||
| du -shc /etc/uhub/ /usr/bin/uhub* /usr/lib/uhub/ |  | ||||||
| 
 |  | ||||||
| @ -1,10 +0,0 @@ | |||||||
| #!/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 |  | ||||||
| 
 |  | ||||||
| @ -3,7 +3,7 @@ | |||||||
| # | # | ||||||
| #  SQLITE3_FOUND               True if sqlite3 got found | #  SQLITE3_FOUND               True if sqlite3 got found | ||||||
| #  SQLITE3_INCLUDEDIR          Location of sqlite3 headers | #  SQLITE3_INCLUDEDIR          Location of sqlite3 headers | ||||||
| #  SQLITE3_LIBRARIES           List of libraries to use sqlite3 | #  SQLITE3_LIBRARIES           List of libaries to use sqlite3 | ||||||
| #  SQLITE3_DEFINITIONS         Definitions to compile sqlite3 | #  SQLITE3_DEFINITIONS         Definitions to compile sqlite3 | ||||||
| # | # | ||||||
| # Copyright (c) 2007 Juha Tuomala <tuju@iki.fi> | # Copyright (c) 2007 Juha Tuomala <tuju@iki.fi> | ||||||
| @ -44,7 +44,6 @@ 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 | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								debian/control
									
									
									
									
										vendored
									
									
								
							| @ -20,5 +20,5 @@ Description: High performance ADC p2p hub | |||||||
|   - Advanced access control support |   - Advanced access control support | ||||||
|   - Easy configuration |   - Easy configuration | ||||||
|  . |  . | ||||||
| Homepage: https://www.uhub.org/ | Homepage: http://www.uhub.org/ | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								debian/copyright
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								debian/copyright
									
									
									
									
										vendored
									
									
								
							| @ -12,7 +12,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | |||||||
| GNU General Public License for more details. | GNU General Public License for more details. | ||||||
| 
 | 
 | ||||||
| You should have received a copy of the GNU General Public License | You should have received a copy of the GNU General Public License | ||||||
| along with this program.  If not, see <https://www.gnu.org/licenses/>. | along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
| 
 | 
 | ||||||
| On Debian GNU/Linux systems, the complete text of the GNU General Public | On Debian GNU/Linux systems, the complete text of the GNU General Public | ||||||
| License can be found in `/usr/share/common-licenses/GPL'. | License can be found in `/usr/share/common-licenses/GPL'. | ||||||
|  | |||||||
| @ -67,7 +67,7 @@ Accepting new users | |||||||
|  |            |                           | |  |            |                           | | ||||||
|  |            V                           | |  |            V                           | | ||||||
|  |  ---------------------         --------------------- |  |  ---------------------         --------------------- | ||||||
|  |  |   Send password   | ------> | Receive and check | |  |  |   Send password   | ------> | Reveive and check | | ||||||
|  |  | request, if needed|         | password.         | |  |  | request, if needed|         | password.         | | ||||||
|  |  ---------------------         --------------------- |  |  ---------------------         --------------------- | ||||||
|  |                                         | |  |                                         | | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| How to compile: | How to compile: | ||||||
| --------------- | --------------- | ||||||
| 
 | 
 | ||||||
| See the official compiling howto: https://www.uhub.org/compile.php | See the official compiling howto: http://www.uhub.org/compile.php | ||||||
| 
 | 
 | ||||||
| Prerequisites | Prerequisites | ||||||
| 
 | 
 | ||||||
| @ -12,7 +12,7 @@ Before you try to compile µHub, please make sure the following prerequisites ar | |||||||
|   * openssl > 0.9.8 (or use  "make USE_SSL=NO") |   * openssl > 0.9.8 (or use  "make USE_SSL=NO") | ||||||
|   * sqlite > 3.x |   * sqlite > 3.x | ||||||
| 
 | 
 | ||||||
| or read  https://www.uhub.org/compile.php for more info. | or read  http://www.uhub.org/compile.php for more info. | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| Linux, Mac OSX, FreeBSD, NetBSD and OpenBSD | Linux, Mac OSX, FreeBSD, NetBSD and OpenBSD | ||||||
|  | |||||||
| @ -28,10 +28,10 @@ The UDP packet SHOULD be echoed by the hub. | |||||||
| This UDP packet should contain simply 'HECH {cid} {token}' (Hub echo). | This UDP packet should contain simply 'HECH {cid} {token}' (Hub echo). | ||||||
| 
 | 
 | ||||||
| The hub should send a packet containing the token back: | The hub should send a packet containing the token back: | ||||||
| 'IECH {token} {host:port}', as well as the same message via TCP. | 'IECH {token} {host:port}', aswell as the same message via TCP. | ||||||
| 
 | 
 | ||||||
| If the client receives the message via UDP, it should now be able to determine the type of NAT. | If the client receives the message via UDP, it should now be able to determine the type of NAT. | ||||||
| If the client receives the message via TCP only it knows it has a firewall blocking incoming communication. | If the client receives the message via TCP only it knows it has a firewall blocking incomming communication. | ||||||
| If the client does not receive the message, it should assume a firewall is blocking all UDP communication, | If the client does not receive the message, it should assume a firewall is blocking all UDP communication, | ||||||
| and resume in passive mode. | and resume in passive mode. | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,8 @@ | |||||||
| Getting started guide | Getting started guide | ||||||
| --------------------- | --------------------- | ||||||
| 
 | 
 | ||||||
|  | (This document is maintained at http://www.extatic.org/uhub/getstarted.html ) | ||||||
|  | 
 | ||||||
| Unpack your binaries  | Unpack your binaries  | ||||||
| 
 | 
 | ||||||
| Example: | Example: | ||||||
| @ -15,7 +17,6 @@ Create configuration files. | |||||||
| If no configuration files are created, uhub will use the default parameters, so you can skip this step if you are in a hurry to see it run. | If no configuration files are created, uhub will use the default parameters, so you can skip this step if you are in a hurry to see it run. | ||||||
| 
 | 
 | ||||||
| As root, or use sudo. | As root, or use sudo. | ||||||
| 
 |  | ||||||
|   % mkdir /etc/uhub |   % mkdir /etc/uhub | ||||||
|   % cp doc/uhub.conf /etc/uhub |   % cp doc/uhub.conf /etc/uhub | ||||||
|   % cp doc/users.conf /etc/uhub |   % cp doc/users.conf /etc/uhub | ||||||
| @ -31,11 +32,8 @@ NOTE: It is important to use the "adc://" prefix, and the port number when using | |||||||
| 
 | 
 | ||||||
| If you modify the configuration files in /etc/uhub you will have to notify uhub by sending a HUP signal. | If you modify the configuration files in /etc/uhub you will have to notify uhub by sending a HUP signal. | ||||||
| 
 | 
 | ||||||
|   % ps aux | grep uhub |  | ||||||
|   % kill -HUP <pid of uhub> |   % kill -HUP <pid of uhub> | ||||||
| 
 |  | ||||||
| Or, for the lazy people | Or, for the lazy people | ||||||
| 
 |  | ||||||
|   % killall -HUP uhub |   % killall -HUP uhub | ||||||
| 
 | 
 | ||||||
| In order to run uhub as a daemon, start it with the -f switch which will make it fork into the background. | In order to run uhub as a daemon, start it with the -f switch which will make it fork into the background. | ||||||
| @ -43,25 +41,17 @@ In addition, use the -l to specify a log file instead of stdout. One can also sp | |||||||
| if one wishes to run uhub as a specific user using the -u and -g switches. | if one wishes to run uhub as a specific user using the -u and -g switches. | ||||||
| 
 | 
 | ||||||
| Example: | Example: | ||||||
| 
 |  | ||||||
|   % uhub -f -l mylog.txt -u nobody -g nogroup |   % uhub -f -l mylog.txt -u nobody -g nogroup | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| If you are planning to more than 1024 users on hub, you must increase the max number of file descriptors allowed. | If you are planning to more than 1024 users on hub, you must increase the max number of file descriptors allowed. | ||||||
| This limit needs to be higher than the configured max_users in uhub.conf. | This limit needs to be higher than the configured max_users in uhub.conf. | ||||||
| 
 | 
 | ||||||
| In Linux can add the following lines to /etc/security/limits.conf (allows for ~4000 users) | In linux can add the following lines to /etc/security/limits.conf (allows for ~4000 users) | ||||||
|       *     soft nofile 4096 |       *     soft nofile 4096 | ||||||
|       *     hard nofile 4096 |       *     hard nofile 4096 | ||||||
| 
 | 
 | ||||||
| Or, you can use (as root): | Or, you can use (as root): | ||||||
| 
 |  | ||||||
|   % ulimit -n 4096 |   % ulimit -n 4096 | ||||||
|                       |                       | ||||||
| You can interact with uhub in your hub main chat using the `!` prefix, followed by a command: |  | ||||||
| 
 |  | ||||||
| Example : |  | ||||||
| 
 |  | ||||||
|       *     to display help and the command you can use: |  | ||||||
|             !help  |  | ||||||
|                       |  | ||||||
| Your mileage may vary -- Good luck! | Your mileage may vary -- Good luck! | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| #!/bin/sh | #!/bin/sh | ||||||
| # | # | ||||||
| # chkconfig: - 91 35 | # chkconfig: - 91 35 | ||||||
| # description: Starts and stops the Uhub ( https://www.uhub.org ) daemons on RHEL\CentOS \ | # description: Starts and stops the Uhub ( http://www.uhub.org ) daemons on RHEL\CentOS \ | ||||||
| #	       used to provide p2p network services. | #	       used to provide p2p network services. | ||||||
| # | # | ||||||
| # pidfile: /var/run/uhub.pid | # pidfile: /var/run/uhub.pid | ||||||
|  | |||||||
| @ -13,15 +13,6 @@ | |||||||
| # | # | ||||||
| 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 | ||||||
| # | # | ||||||
| @ -31,8 +22,7 @@ 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: | ||||||
| @ -41,7 +31,7 @@ plugin /usr/lib/uhub/mod_logging.so "file=/var/log/uhub.log" | |||||||
| # | # | ||||||
| # Parameters: | # Parameters: | ||||||
| # motd: path/filename for the welcome message (message of the day) | # motd: path/filename for the welcome message (message of the day) | ||||||
| # rules: path/filename for the rules file | # rules: path/filenam for the rules file | ||||||
| # | # | ||||||
| # NOTE: The files MUST exist, however if you do not wish to provide one then these parameters can be omitted. | # NOTE: The files MUST exist, however if you do not wish to provide one then these parameters can be omitted. | ||||||
| # | # | ||||||
| @ -69,3 +59,4 @@ plugin /usr/lib/uhub/mod_welcome.so "motd=/etc/uhub/motd.txt rules=/etc/uhub/rul | |||||||
| # history_default: when !history is provided without arguments, then this default number of messages are returned. | # history_default: when !history is provided without arguments, then this default number of messages are returned. | ||||||
| # history_connect: the number of chat history messages to send when users connect (0 = do not send any history) | # history_connect: the number of chat history messages to send when users connect (0 = do not send any history) | ||||||
| plugin /usr/lib/uhub/mod_chat_history.so "history_max=200 history_default=10 history_connect=5" | plugin /usr/lib/uhub/mod_chat_history.so "history_max=200 history_default=10 history_connect=5" | ||||||
|  | 
 | ||||||
|  | |||||||
| @ -39,4 +39,4 @@ is one of 'admin', 'super', 'op', 'user' | |||||||
| This program was written by Jan Vidar Krey <janvidar@extatic.org> | This program was written by Jan Vidar Krey <janvidar@extatic.org> | ||||||
| .SH "BUG REPORTS" | .SH "BUG REPORTS" | ||||||
| If you find a bug in uhub please report it to | If you find a bug in uhub please report it to | ||||||
| .B https://github.com/janvidar/uhub/issues | .B http://bugs.extatic.org/ | ||||||
|  | |||||||
| @ -69,4 +69,4 @@ To run uhub as a daemon, and log to a file: | |||||||
| This program was written by Jan Vidar Krey <janvidar@extatic.org> | This program was written by Jan Vidar Krey <janvidar@extatic.org> | ||||||
| .SH "BUG REPORTS" | .SH "BUG REPORTS" | ||||||
| If you find a bug in uhub please report it to | If you find a bug in uhub please report it to | ||||||
| .B https://github.com/janvidar/uhub/issues | .B http://bugs.extatic.org/ | ||||||
|  | |||||||
| @ -2,10 +2,10 @@ | |||||||
| # You should normally place this file in /etc/uhub/uhub.conf | # You should normally place this file in /etc/uhub/uhub.conf | ||||||
| # and customize some of the settings below. | # and customize some of the settings below. | ||||||
| # | # | ||||||
| # This file is read only to the uhub daemon, and if you | # This file is read only to the uhub deamon, and if you | ||||||
| # make changes to it while uhub is running you can send a | # make changes to it while uhub is running you can send a | ||||||
| # HUP signal to it ( $ killall -HUP uhub ), to reparse configuration (only on UNIX). | # HUP signal to it ( $ killall -HUP uhub ), to reparse configuration (only on UNIX). | ||||||
| # All configuration directives: https://www.uhub.org/config.php | # All configuration directives: http://www.uhub.org/config.php | ||||||
| 
 | 
 | ||||||
| # Bind to this port and address | # Bind to this port and address | ||||||
| # server_bind_addr=any means listen to "::" if IPv6 is supported | # server_bind_addr=any means listen to "::" if IPv6 is supported | ||||||
| @ -104,11 +104,11 @@ msg_auth_invalid_password      = Password is wrong | |||||||
| msg_auth_user_not_found        = User not found in password database | msg_auth_user_not_found        = User not found in password database | ||||||
| msg_user_share_size_low	       = User is not sharing enough | msg_user_share_size_low	       = User is not sharing enough | ||||||
| msg_user_share_size_high       = User is sharing too much | msg_user_share_size_high       = User is sharing too much | ||||||
| msg_user_slots_low	       = User has too few upload slots | msg_user_slots_low	       = User have too few upload slots | ||||||
| msg_user_slots_high	       = User has too many upload slots | msg_user_slots_high	       = User have 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            = Out of memory | msg_error_no_memory            = No memory | ||||||
| msg_user_flood_chat            = Chat flood detected, messages are dropped. | msg_user_flood_chat            = Chat flood detected, messages are dropped. | ||||||
| msg_user_flood_connect         = Connect flood detected, connection refused. | msg_user_flood_connect         = Connect flood detected, connection refused. | ||||||
| msg_user_flood_search          = Search flood detected, search is stopped. | msg_user_flood_search          = Search flood detected, search is stopped. | ||||||
|  | |||||||
| @ -4,7 +4,7 @@ | |||||||
| inherit eutils | inherit eutils | ||||||
| 
 | 
 | ||||||
| if [ "$PV" != "9999" ]; then | if [ "$PV" != "9999" ]; then | ||||||
|         SRC_URI="https://www.extatic.org/downloads/uhub/${P}-src.tar.bz2" |         SRC_URI="http://www.extatic.org/downloads/uhub/${P}-src.tar.bz2" | ||||||
|         KEYWORDS="~amd64 ~x86" |         KEYWORDS="~amd64 ~x86" | ||||||
| else | else | ||||||
|         inherit git |         inherit git | ||||||
| @ -16,7 +16,7 @@ fi | |||||||
| EAPI="2" | EAPI="2" | ||||||
| 
 | 
 | ||||||
| DESCRIPTION="High performance ADC hub" | DESCRIPTION="High performance ADC hub" | ||||||
| HOMEPAGE="https://www.uhub.org/" | HOMEPAGE="http://www.uhub.org/" | ||||||
| 
 | 
 | ||||||
| LICENSE="GPL-3" | LICENSE="GPL-3" | ||||||
| SLOT="0" | SLOT="0" | ||||||
|  | |||||||
| @ -5,7 +5,7 @@ Release: 2 | |||||||
| License: GPLv3 | License: GPLv3 | ||||||
| Group: Networking/File transfer | Group: Networking/File transfer | ||||||
| Source: uhub-%{version}.tar.gz | Source: uhub-%{version}.tar.gz | ||||||
| URL: https://www.uhub.org | URL: http://www.uhub.org | ||||||
| BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root | BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root | ||||||
| 
 | 
 | ||||||
| BuildRequires: sqlite-devel | BuildRequires: sqlite-devel | ||||||
| @ -80,7 +80,7 @@ rm -rf $RPM_BUILD_ROOT | |||||||
| if [ $1 -gt 1 ] ; then | if [ $1 -gt 1 ] ; then | ||||||
|     /etc/rc.d/init.d/uhub restart >/dev/null || : |     /etc/rc.d/init.d/uhub restart >/dev/null || : | ||||||
| fi | fi | ||||||
| # need more information about add services and users in system | # need more informations about add services and users in system | ||||||
| /usr/sbin/adduser -M -d /tmp -G nobody -s /sbin/nologin -c 'The Uhub ADC p2p hub Daemon' uhub >/dev/null 2>&1 ||: | /usr/sbin/adduser -M -d /tmp -G nobody -s /sbin/nologin -c 'The Uhub ADC p2p hub Daemon' uhub >/dev/null 2>&1 ||: | ||||||
| # write SSL create  | # write SSL create  | ||||||
| echo "PLS see /usr/share/doc/uhub/" | echo "PLS see /usr/share/doc/uhub/" | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ start on filesystem or runlevel [2345] | |||||||
| stop on runlevel [!2345] | stop on runlevel [!2345] | ||||||
| 
 | 
 | ||||||
| # Allow the service to respawn, but if its happening too often | # Allow the service to respawn, but if its happening too often | ||||||
| # (10 times in 5 seconds) there's a problem and we should stop trying. | # (10 times in 5 seconds) theres a problem and we should stop trying. | ||||||
| respawn | respawn | ||||||
| respawn limit 10 5 | respawn limit 10 5 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2013, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -34,6 +34,7 @@ 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') | ||||||
| @ -101,6 +102,12 @@ 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 */ | ||||||
| @ -111,15 +118,12 @@ typedef uint32_t fourcc_t; | |||||||
| #define ADC_INF_FLAG_CLIENT_ID          "ID" /* client id, aka CID */ | #define ADC_INF_FLAG_CLIENT_ID          "ID" /* client id, aka CID */ | ||||||
| #define ADC_INF_FLAG_NICK               "NI" /* nick name */ | #define ADC_INF_FLAG_NICK               "NI" /* nick name */ | ||||||
| #define ADC_INF_FLAG_DESCRIPTION        "DE" /* user description */ | #define ADC_INF_FLAG_DESCRIPTION        "DE" /* user description */ | ||||||
| 
 | #define ADC_INF_FLAG_USER_AGENT         "VE" /* software version */ | ||||||
| #define ADC_INF_FLAG_USER_AGENT_PRODUCT "AP" /* software name */ |  | ||||||
| #define ADC_INF_FLAG_USER_AGENT_VERSION "VE" /* software version */ |  | ||||||
| 
 |  | ||||||
| #define ADC_INF_FLAG_SUPPORT            "SU" /* support (extensions, feature cast) */ | #define ADC_INF_FLAG_SUPPORT            "SU" /* support (extensions, feature cast) */ | ||||||
| #define ADC_INF_FLAG_SHARED_SIZE        "SS" /* size of total files shared in bytes */ | #define ADC_INF_FLAG_SHARED_SIZE        "SS" /* size of total files shared in bytes */ | ||||||
| #define ADC_INF_FLAG_SHARED_FILES       "SF" /* number of files shared */ | #define ADC_INF_FLAG_SHARED_FILES       "SF" /* number of files shared */ | ||||||
| #define ADC_INF_FLAG_UPLOAD_SPEED       "US" /* maximum upload speed achieved in bytes/sec */ | #define ADC_INF_FLAG_UPLOAD_SPEED       "US" /* maximum upload speed acheived in bytes/sec */ | ||||||
| #define ADC_INF_FLAG_DOWNLOAD_SPEED     "DS" /* maximum download speed achieved in bytes/sec */ | #define ADC_INF_FLAG_DOWNLOAD_SPEED     "DS" /* maximum download speed acheived in bytes/sec */ | ||||||
| #define ADC_INF_FLAG_UPLOAD_SLOTS       "SL" /* maximum upload slots (concurrent uploads) */ | #define ADC_INF_FLAG_UPLOAD_SLOTS       "SL" /* maximum upload slots (concurrent uploads) */ | ||||||
| #define ADC_INF_FLAG_AUTO_SLOTS         "AS" /* automatic slot if upload speed is less than this in bytes/sec */ | #define ADC_INF_FLAG_AUTO_SLOTS         "AS" /* automatic slot if upload speed is less than this in bytes/sec */ | ||||||
| #define ADC_INF_FLAG_AUTO_SLOTS_MAX     "AM" /* maximum number of automatic slots */ | #define ADC_INF_FLAG_AUTO_SLOTS_MAX     "AM" /* maximum number of automatic slots */ | ||||||
| @ -134,7 +138,7 @@ typedef uint32_t fourcc_t; | |||||||
| #define ADC_MSG_FLAG_PRIVATE            "PM" /* message is a private message */ | #define ADC_MSG_FLAG_PRIVATE            "PM" /* message is a private message */ | ||||||
| 
 | 
 | ||||||
| #define ADC_SCH_FLAG_INCLUDE            "AN" /* include given search term */ | #define ADC_SCH_FLAG_INCLUDE            "AN" /* include given search term */ | ||||||
| #define ADC_SCH_FLAG_EXCLUDE            "NO" /* exclude given search term */ | #define ADC_SCH_FLAG_EXCLUDE            "NO" /* exclude given serach term */ | ||||||
| #define ADC_SCH_FLAG_FILE_EXTENSION     "EX" /* search only for files with the given file extension */ | #define ADC_SCH_FLAG_FILE_EXTENSION     "EX" /* search only for files with the given file extension */ | ||||||
| #define ADC_SCH_FLAG_FILE_TYPE          "TY" /* search only for files with this file type (separate type) */ | #define ADC_SCH_FLAG_FILE_TYPE          "TY" /* search only for files with this file type (separate type) */ | ||||||
| #define ADC_SCH_FLAG_LESS_THAN          "LE" /* search for files with this size or less */ | #define ADC_SCH_FLAG_LESS_THAN          "LE" /* search for files with this size or less */ | ||||||
| @ -159,7 +163,6 @@ typedef uint32_t fourcc_t; | |||||||
| #define ADC_CLIENT_TYPE_BOT             "1" | #define ADC_CLIENT_TYPE_BOT             "1" | ||||||
| #define ADC_CLIENT_TYPE_REGISTERED_USER "2" | #define ADC_CLIENT_TYPE_REGISTERED_USER "2" | ||||||
| #define ADC_CLIENT_TYPE_OPERATOR        "4" | #define ADC_CLIENT_TYPE_OPERATOR        "4" | ||||||
| #define ADC_CLIENT_TYPE_HUBBOT           "5"  /* 1 + 4 */ |  | ||||||
| #define ADC_CLIENT_TYPE_SUPER_USER      "12"  /* 8 + 4 */ | #define ADC_CLIENT_TYPE_SUPER_USER      "12"  /* 8 + 4 */ | ||||||
| #define ADC_CLIENT_TYPE_ADMIN           "20"  /* 16 + 4 = hub owner */ | #define ADC_CLIENT_TYPE_ADMIN           "20"  /* 16 + 4 = hub owner */ | ||||||
| #define ADC_CLIENT_TYPE_HUB             "32"  /* the hub itself */ | #define ADC_CLIENT_TYPE_HUB             "32"  /* the hub itself */ | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2013, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -24,6 +24,7 @@ | |||||||
| 	uhub_assert(X); \ | 	uhub_assert(X); \ | ||||||
| 	uhub_assert(X->cache); \ | 	uhub_assert(X->cache); \ | ||||||
| 	uhub_assert(X->capacity); \ | 	uhub_assert(X->capacity); \ | ||||||
|  | 	uhub_assert(X->length); \ | ||||||
| 	uhub_assert(X->length <= X->capacity); \ | 	uhub_assert(X->length <= X->capacity); \ | ||||||
| 	uhub_assert(X->references > 0); \ | 	uhub_assert(X->references > 0); \ | ||||||
| 	uhub_assert(X->length == strlen(X->cache)); | 	uhub_assert(X->length == strlen(X->cache)); | ||||||
| @ -177,6 +178,7 @@ 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': | ||||||
| @ -282,19 +284,23 @@ 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(); | ||||||
| 		LIST_FOREACH(char*, tmp, cmd->feature_cast_include, | 		tmp = list_get_first(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(); | ||||||
| 		LIST_FOREACH(char*, tmp, cmd->feature_cast_exclude, | 		tmp = list_get_first(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); | ||||||
| @ -310,7 +316,7 @@ struct adc_message* adc_msg_parse_verify(struct hub_user* u, const char* line, s | |||||||
| 	if (!command) | 	if (!command) | ||||||
| 		return 0; | 		return 0; | ||||||
| 	 | 	 | ||||||
| 	if (command->source && (!u || (command->source != u->id.sid && !auth_cred_is_unrestricted(u->credentials)))) | 	if (command->source && (!u || command->source != u->id.sid)) | ||||||
| 	{ | 	{ | ||||||
| 		LOG_DEBUG("Command does not match user's SID (command->source=%d, user->id.sid=%d)", command->source, (u ? u->id.sid : 0)); | 		LOG_DEBUG("Command does not match user's SID (command->source=%d, user->id.sid=%d)", command->source, (u ? u->id.sid : 0)); | ||||||
| 		adc_msg_free(command); | 		adc_msg_free(command); | ||||||
| @ -378,8 +384,9 @@ struct adc_message* adc_msg_parse(const char* line, size_t length) | |||||||
| 			ok = 0; | 			ok = 0; | ||||||
| 			break; | 			break; | ||||||
| 
 | 
 | ||||||
| 		case 'I': | 		case 'I': /* Hub to client */ | ||||||
| 		case 'H': | 		case 'H': /* Clien to hub */ | ||||||
|  | 		case 'L': /* hub to hub Link */ | ||||||
| 			ok = (length > 3); | 			ok = (length > 3); | ||||||
| 			break; | 			break; | ||||||
| 
 | 
 | ||||||
| @ -782,6 +789,16 @@ 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) | ||||||
| { | { | ||||||
| @ -863,21 +880,21 @@ int adc_msg_get_argument_index(struct adc_message* cmd, const char prefix[2]) | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| int adc_msg_escape_length(const char* str) | size_t adc_msg_escape_length(const char* str) | ||||||
| { | { | ||||||
| 	int add = 0; | 	size_t add = 0; | ||||||
| 	int n = 0; | 	size_t 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; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| int adc_msg_unescape_length(const char* str) | size_t adc_msg_unescape_length(const char* str) | ||||||
| { | { | ||||||
| 	int add = 0; | 	size_t add = 0; | ||||||
| 	int n = 0; | 	size_t n = 0; | ||||||
| 	int escape = 0; | 	size_t escape = 0; | ||||||
| 	for (; str[n]; n++) | 	for (; str[n]; n++) | ||||||
| 	{ | 	{ | ||||||
| 		if (escape) | 		if (escape) | ||||||
| @ -993,3 +1010,20 @@ 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-2014, Jan Vidar Krey |  * Copyright (C) 2007-2013, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -43,6 +43,20 @@ 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 | ||||||
| @ -51,7 +65,7 @@ enum msg_status_level | |||||||
| extern struct adc_message* adc_msg_incref(struct adc_message* msg); | extern struct adc_message* adc_msg_incref(struct adc_message* msg); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Decrease the reference counter, and free the memory when appropriate. |  * Decrease the reference counter, and free the memory when apropriate. | ||||||
|  */ |  */ | ||||||
| extern void adc_msg_free(struct adc_message* msg); | extern void adc_msg_free(struct adc_message* msg); | ||||||
| 
 | 
 | ||||||
| @ -159,7 +173,7 @@ extern char* adc_msg_get_argument(struct adc_message* cmd, int offset); | |||||||
|  * |  * | ||||||
|  * @arg prefix a 2 character argument prefix |  * @arg prefix a 2 character argument prefix | ||||||
|  * @arg string must be escaped (see adc_msg_escape). |  * @arg string must be escaped (see adc_msg_escape). | ||||||
|  * @return  0 if successful, or -1 if an error occurred. |  * @return  0 if successful, or -1 if an error occured. | ||||||
|  */ |  */ | ||||||
| extern int adc_msg_replace_named_argument(struct adc_message* cmd, const char prefix[2], const char* string); | extern int adc_msg_replace_named_argument(struct adc_message* cmd, const char prefix[2], const char* string); | ||||||
| 
 | 
 | ||||||
| @ -167,16 +181,23 @@ extern int adc_msg_replace_named_argument(struct adc_message* cmd, const char pr | |||||||
|  * Append an argument |  * Append an argument | ||||||
|  * |  * | ||||||
|  * @arg string must be escaped (see adc_msg_escape). |  * @arg string must be escaped (see adc_msg_escape). | ||||||
|  * @return  0 if successful, or -1 if an error occurred (out of memory). |  * @return  0 if successful, or -1 if an error occured (out of memory). | ||||||
|  */ |  */ | ||||||
| extern int adc_msg_add_argument(struct adc_message* cmd, const char* string); | extern int adc_msg_add_argument(struct adc_message* cmd, const char* string); | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * 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 | ||||||
|  * |  * | ||||||
|  * @arg prefix a 2 character argument prefix |  * @arg prefix a 2 character argument prefix | ||||||
|  * @arg string must be escaped (see adc_msg_escape). |  * @arg string must be escaped (see adc_msg_escape). | ||||||
|  * @return  0 if successful, or -1 if an error occurred (out of memory). |  * @return  0 if successful, or -1 if an error occured (out of memory). | ||||||
|  */ |  */ | ||||||
| extern int adc_msg_add_named_argument(struct adc_message* cmd, const char prefix[2], const char* string); | extern int adc_msg_add_named_argument(struct adc_message* cmd, const char prefix[2], const char* string); | ||||||
| 
 | 
 | ||||||
| @ -186,7 +207,7 @@ extern int adc_msg_add_named_argument(struct adc_message* cmd, const char prefix | |||||||
|  * |  * | ||||||
|  * @arg prefix a 2 character argument prefix |  * @arg prefix a 2 character argument prefix | ||||||
|  * @arg string must NOT be escaped |  * @arg string must NOT be escaped | ||||||
|  * @return  0 if successful, or -1 if an error occurred (out of memory). |  * @return  0 if successful, or -1 if an error occured (out of memory). | ||||||
|  */ |  */ | ||||||
| extern int adc_msg_add_named_argument_string(struct adc_message* cmd, const char prefix[2], const char* string); | extern int adc_msg_add_named_argument_string(struct adc_message* cmd, const char prefix[2], const char* string); | ||||||
| 
 | 
 | ||||||
| @ -216,6 +237,12 @@ 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. | ||||||
|  */ |  */ | ||||||
| @ -234,4 +261,6 @@ 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-2014, Jan Vidar Krey |  * Copyright (C) 2007-2009, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2009, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2010, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -170,9 +170,6 @@ static int acl_parse_line(char* line, int line_count, void* ptr_data) | |||||||
| 	LOG_DEBUG("acl_parse_line: '%s'", line); | 	LOG_DEBUG("acl_parse_line: '%s'", line); | ||||||
| 
 | 
 | ||||||
| 	ACL_ADD_USER("bot",        handle->users, auth_cred_bot); | 	ACL_ADD_USER("bot",        handle->users, auth_cred_bot); | ||||||
| 	ACL_ADD_USER("ubot",        handle->users, auth_cred_ubot); |  | ||||||
| 	ACL_ADD_USER("opbot",        handle->users, auth_cred_opbot); |  | ||||||
| 	ACL_ADD_USER("opubot",        handle->users, auth_cred_opubot); |  | ||||||
| 	ACL_ADD_USER("user_admin", handle->users, auth_cred_admin); | 	ACL_ADD_USER("user_admin", handle->users, auth_cred_admin); | ||||||
| 	ACL_ADD_USER("user_super", handle->users, auth_cred_super); | 	ACL_ADD_USER("user_super", handle->users, auth_cred_super); | ||||||
| 	ACL_ADD_USER("user_op",    handle->users, auth_cred_operator); | 	ACL_ADD_USER("user_op",    handle->users, auth_cred_operator); | ||||||
| @ -333,11 +330,13 @@ 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) \ | ||||||
| 		LIST_FOREACH(char*, str, LIST, \ | 		str = (char*) list_get_first(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) | ||||||
| @ -401,28 +400,34 @@ 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* info = (struct ip_range*) list_get_first(handle->networks); | ||||||
| 
 |  | ||||||
| 	ip_convert_to_binary(ip_address, &raw); | 	ip_convert_to_binary(ip_address, &raw); | ||||||
| 	LIST_FOREACH(struct ip_range*, info, handle->networks, | 	 | ||||||
|  | 	while (info) | ||||||
| 	{ | 	{ | ||||||
| 		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* info = (struct ip_range*) list_get_first(handle->nat_override); | ||||||
| 
 |  | ||||||
| 	ip_convert_to_binary(ip_address, &raw); | 	ip_convert_to_binary(ip_address, &raw); | ||||||
| 	LIST_FOREACH(struct ip_range*, info, handle->nat_override, | 	 | ||||||
|  | 	while (info) | ||||||
| 	{ | 	{ | ||||||
| 		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-2014, Jan Vidar Krey |  * Copyright (C) 2007-2010, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2012, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -26,7 +26,7 @@ static void hub_command_args_free(struct hub_command* cmd) | |||||||
| 	if (!cmd->args) | 	if (!cmd->args) | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
| 	LIST_FOREACH(struct hub_command_arg_data*, data, cmd->args, | 	for (data = (struct hub_command_arg_data*) list_get_first(cmd->args); data; data = (struct hub_command_arg_data*) list_get_next(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,7 +64,6 @@ 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; | ||||||
| 
 | 
 | ||||||
| @ -78,15 +77,15 @@ static enum command_parse_status command_extract_arguments(struct hub_info* hub, | |||||||
| 		if (greedy) | 		if (greedy) | ||||||
| 		{ | 		{ | ||||||
| 			size = 1; | 			size = 1; | ||||||
| 			LIST_FOREACH(char*, tmp, tokens, { size += (strlen(tmp) + 1); }); | 			for (tmp = (char*) list_get_first(tokens); tmp; tmp = (char*) list_get_next(tokens)) | ||||||
|  | 				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 (offset > 0) | 				if (*token) | ||||||
| 					token[offset++] = ' '; | 					strcat(token, " "); | ||||||
| 				memcpy(token + offset, tmp, strlen(tmp)); | 				strcat(token, 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-2014, Jan Vidar Krey |  * Copyright (C) 2007-2012, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -30,7 +30,7 @@ struct command_base; | |||||||
|  * |  * | ||||||
|  * @param cbase Command base pointer. |  * @param cbase Command base pointer. | ||||||
|  * @param user User who invoked the command. |  * @param user User who invoked the command. | ||||||
|  * @param message The message that is to be interpreted as a command (including the invocation prefix '!' or '+') |  * @param message The message that is to be interpreted as a command (including the invokation prefix '!' or '+') | ||||||
|  * |  * | ||||||
|  * @return a hub_command that must be freed with command_free(). @See struct hub_command. |  * @return a hub_command that must be freed with command_free(). @See struct hub_command. | ||||||
|  */ |  */ | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2012, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -31,6 +31,8 @@ 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; | ||||||
| @ -96,14 +98,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); | ||||||
| 
 | 
 | ||||||
| 	LIST_FOREACH(struct command_handle*, handler, cbase->handlers, | 	for (handler = (struct command_handle*) list_get_first(cbase->handlers); handler; handler = (struct command_handle*) list_get_next(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; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -290,7 +292,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"); | ||||||
| 
 | 
 | ||||||
| 		LIST_FOREACH(struct command_handle*, command, cbase->handlers, | 		for (command = (struct command_handle*) list_get_first(cbase->handlers); command; command = (struct command_handle*) list_get_next(cbase->handlers)) | ||||||
| 		{ | 		{ | ||||||
| 			if (command_is_available(command, user->credentials)) | 			if (command_is_available(command, user->credentials)) | ||||||
| 			{ | 			{ | ||||||
| @ -299,7 +301,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 | ||||||
| 	{ | 	{ | ||||||
| @ -422,7 +424,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); | 		list_clear(users, &null_free); | ||||||
| 		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.")); | ||||||
| 	} | 	} | ||||||
| @ -430,14 +432,16 @@ 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" : "")); | ||||||
| 
 | 
 | ||||||
| 	LIST_FOREACH(struct hub_user*, u, users, | 	u = (struct hub_user*) list_get_first(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); | 	list_clear(users, &null_free); | ||||||
| 	list_destroy(users); | 	list_destroy(users); | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| @ -458,7 +462,8 @@ 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)); | ||||||
| 
 | 
 | ||||||
| 	LIST_FOREACH(struct hub_user*, target, cbase->hub->users->list, | 	target = (struct hub_user*) list_get_first(cbase->hub->users->list); | ||||||
|  | 	while (target) | ||||||
| 	{ | 	{ | ||||||
| 		if (target != user) | 		if (target != user) | ||||||
| 		{ | 		{ | ||||||
| @ -475,7 +480,8 @@ 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); | ||||||
| @ -507,7 +513,8 @@ 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); | ||||||
| 	LIST_FOREACH(struct hub_logout_info*, log, messages, | 	log = (struct hub_logout_info*) list_get_first(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; | ||||||
| @ -531,7 +538,8 @@ 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-2014, Jan Vidar Krey |  * Copyright (C) 2007-2012, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2010, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -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-2014, Jan Vidar Krey |  * Copyright (C) 2007-2010, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										289
									
								
								src/core/config.pl
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										289
									
								
								src/core/config.pl
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,289 @@ | |||||||
|  | #!/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"; | ||||||
|  | } | ||||||
| @ -1,255 +0,0 @@ | |||||||
| #!/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="[\x:.]+|any|loopback" /> | 		<check regexp="(\d\.\d\.\d\.\d\)|(any)|(loopback)|(.*)" /><!-- FIXME: add better IPv6 regexp in the future! --> | ||||||
| 		<short>Server bind address</short> | 		<short>Server bind address</short> | ||||||
| 		<description><![CDATA[ | 		<description><![CDATA[ | ||||||
| 			Specify the IP address the local hub should bind to. This can be an IPv4 or IPv6 address, or one of the special addresses "any" or "loopback". <br /> | 			Specify the IP address the local hub should bind to. This can be an IPv4 or IPv6 address, or one of the special addresses "any" or "loopback". <br /> | ||||||
| @ -58,7 +58,7 @@ | |||||||
| 	</option> | 	</option> | ||||||
| 
 | 
 | ||||||
| 	<option name="server_alt_ports" type="string" default=""> | 	<option name="server_alt_ports" type="string" default=""> | ||||||
| 		<check regexp="\d+(,\d+)*" /> | 		<check regexp="((\d+)(,(\d+))*)?" /> | ||||||
| 		<short>Comma separated list of alternative ports to listen to</short> | 		<short>Comma separated list of alternative ports to listen to</short> | ||||||
| 		<description><![CDATA[ | 		<description><![CDATA[ | ||||||
| 		In addition to the server_port the hub can listen to a list of alternative ports. | 		In addition to the server_port the hub can listen to a list of alternative ports. | ||||||
| @ -111,7 +111,7 @@ | |||||||
|    <option name="register_self" type="boolean" default="0"> |    <option name="register_self" type="boolean" default="0"> | ||||||
| 	   <short>Allow users to register themselves on the hub.</short> | 	   <short>Allow users to register themselves on the hub.</short> | ||||||
| 		<description><![CDATA[ | 		<description><![CDATA[ | ||||||
| 			If this is enabled guests can register their nickname on the hub using !register command. | 			If this is enabled guests can register their nickname on the hub. | ||||||
| 			Otherwise only operators can register users. | 			Otherwise only operators can register users. | ||||||
| 		]]></description> | 		]]></description> | ||||||
| 		<since>0.4.0</since> | 		<since>0.4.0</since> | ||||||
| @ -157,7 +157,7 @@ | |||||||
| 	</option> | 	</option> | ||||||
| 
 | 
 | ||||||
| 	<option name="redirect_addr" type="string" default=""> | 	<option name="redirect_addr" type="string" default=""> | ||||||
| 		<check regexp="(adcs?|dchub)://.*" /> | 		<check regexp="(adc|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,12 +165,42 @@ | |||||||
| 		<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" /> | ||||||
| 		<short>Max read buffer before parse, per user</short> | 		<short>Max read buffer before parse, per user</short> | ||||||
| 		<description><![CDATA[ | 		<description><![CDATA[ | ||||||
| 			Maximum receive buffer allowed before commands are processed. If a single ADC message exceeds this limit, it will be discarded by the hub. Use with caution. | 			Maximum receive buffer allowed before commands are procesed. If a single ADC message exceeds this limit, it will be discarded by the hub. Use with caution. | ||||||
| 		]]></description> | 		]]></description> | ||||||
| 		<since>0.1.3</since> | 		<since>0.1.3</since> | ||||||
| 	</option> | 	</option> | ||||||
| @ -419,7 +449,7 @@ | |||||||
| 	</option> | 	</option> | ||||||
| 
 | 
 | ||||||
| 	<option name="tls_require_redirect_addr" type="string" default=""> | 	<option name="tls_require_redirect_addr" type="string" default=""> | ||||||
| 		<check regexp="(adcs?|dchub)://.*" /> | 		<check regexp="(adc|adcs|dchub)://.*" /> | ||||||
| 		<short>A redirect address in case a client connects using "adc://" when "adcs://" is required.</short> | 		<short>A redirect address in case a client connects using "adc://" when "adcs://" is required.</short> | ||||||
| 		<description><![CDATA[ | 		<description><![CDATA[ | ||||||
| 		This is the redirect address used when the hub wants to redirect a client for not using ADCS. | 		This is the redirect address used when the hub wants to redirect a client for not using ADCS. | ||||||
| @ -428,10 +458,11 @@ | |||||||
| 		<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 or certificate chain (PEM format). | 			Path to a TLS/SSL certificate (PEM format). | ||||||
| 		]]></description> | 		]]></description> | ||||||
| 		<since>0.3.0</since> | 		<since>0.3.0</since> | ||||||
| 	</option> | 	</option> | ||||||
| @ -444,40 +475,6 @@ | |||||||
| 		<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[ | ||||||
| @ -567,7 +564,7 @@ | |||||||
| 	</option> | 	</option> | ||||||
| 
 | 
 | ||||||
| 	<option name="msg_inf_error_nick_taken" type="message" default="Nickname is already in use"> | 	<option name="msg_inf_error_nick_taken" type="message" default="Nickname is already in use"> | ||||||
| 		<description><![CDATA[This message will be sent to clients if their provided nickname is already in use on the hub.]]></description> | 		<description><![CDATA[This message will be sent to clients if their provided nickname is alredy in use on the hub.]]></description> | ||||||
| 		<since>0.2.0</since> | 		<since>0.2.0</since> | ||||||
| 	</option> | 	</option> | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2009, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2009, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -77,13 +77,15 @@ 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; | ||||||
| 	 | 	 | ||||||
| 	LIST_FOREACH(struct event_data*, data, queue->q1, | 	data = (struct event_data*) list_get_first(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); | ||||||
| @ -92,7 +94,13 @@ 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. */ | ||||||
| 	list_append_list(queue->q1, queue->q2); | 	data = (struct event_data*) list_get_first(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-2014, Jan Vidar Krey |  * Copyright (C) 2007-2009, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,10 +1,4 @@ | |||||||
| /*
 | /* 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) | ||||||
| { | { | ||||||
| @ -23,6 +17,15 @@ 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; | ||||||
| @ -51,8 +54,6 @@ 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"); | ||||||
| @ -253,6 +254,42 @@ 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; | ||||||
| @ -554,26 +591,6 @@ 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*) "")) | ||||||
| @ -971,16 +988,20 @@ 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); | ||||||
| @ -1106,6 +1127,21 @@ 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); | ||||||
| 
 | 
 | ||||||
| @ -1190,12 +1226,6 @@ 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,10 +1,4 @@ | |||||||
| /*
 | /* 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 | ||||||
| { | { | ||||||
| @ -23,6 +17,15 @@ 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) */ | ||||||
| @ -51,8 +54,6 @@ 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-2014, Jan Vidar Krey |  * Copyright (C) 2007-2012, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -23,7 +23,7 @@ struct hub_info* g_hub = 0; | |||||||
| 
 | 
 | ||||||
| /* FIXME: Flood control should be done in a plugin! */ | /* FIXME: Flood control should be done in a plugin! */ | ||||||
| #define CHECK_FLOOD(TYPE, WARN) \ | #define CHECK_FLOOD(TYPE, WARN) \ | ||||||
| 	if (flood_control_check(&u->flood_ ## TYPE , hub->config->flood_ctl_  ## TYPE, hub->config->flood_ctl_interval, net_get_time()) &&  !auth_cred_is_unrestricted(u->credentials)) \ | 	if (flood_control_check(&u->flood_ ## TYPE , hub->config->flood_ctl_  ## TYPE, hub->config->flood_ctl_interval, net_get_time())) \ | ||||||
| 	{ \ | 	{ \ | ||||||
| 		if (WARN) \ | 		if (WARN) \ | ||||||
| 		{ \ | 		{ \ | ||||||
| @ -731,11 +731,7 @@ 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(config->tls_version, config->tls_ciphersuite); | 		hub->ctx = net_ssl_context_create(); | ||||||
| 
 |  | ||||||
| 		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)) | ||||||
| @ -791,6 +787,13 @@ 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; | ||||||
| 
 | 
 | ||||||
| @ -838,6 +841,15 @@ 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; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -901,24 +913,14 @@ 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(hub->command_info, ADC_INF_FLAG_USER_AGENT_PRODUCT, PRODUCT); | 		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_VERSION, GIT_VERSION); | 		adc_msg_add_named_argument_string(hub->command_info, ADC_INF_FLAG_NICK, hub->config->hub_name); | ||||||
| 
 | 		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)); | ||||||
| @ -927,16 +929,14 @@ 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 + strlen(server)); | 	hub->command_banner = adc_msg_construct(ADC_CMD_ISTA, 100 + adc_msg_escape_length(PRODUCT_STRING)); | ||||||
| 	if (hub->command_banner) | 	if (hub->command_banner) | ||||||
| 	{ | 	{ | ||||||
| 		if (hub->config->show_banner_sys_info) |  | ||||||
| 			tmp = adc_msg_escape("Powered by " PRODUCT_STRING " on " OPSYS "/" CPUINFO); |  | ||||||
| 		else |  | ||||||
| 			tmp = adc_msg_escape("Powered by " PRODUCT_STRING); |  | ||||||
| 		adc_msg_add_argument(hub->command_banner, "000"); | 		adc_msg_add_argument(hub->command_banner, "000"); | ||||||
| 		adc_msg_add_argument(hub->command_banner, tmp); | 		if (hub->config->show_banner_sys_info) | ||||||
| 		hub_free(tmp); | 			adc_msg_add_argument_string(hub->command_banner, "Powered by " PRODUCT_STRING " on " OPSYS "/" CPUINFO); | ||||||
|  | 		else | ||||||
|  | 			adc_msg_add_argument_string(hub->command_banner, "Powered by " PRODUCT_STRING); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (hub_plugins_load(hub) < 0) | 	if (hub_plugins_load(hub) < 0) | ||||||
| @ -947,7 +947,6 @@ 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); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -1325,7 +1324,9 @@ 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) | ||||||
| 	{ | 	{ | ||||||
| 		list_remove_first(hub->logout_info, hub_free); | 		struct hub_logout_info* entry = list_get_first(hub->logout_info); | ||||||
|  | 		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-2014, Jan Vidar Krey |  * Copyright (C) 2007-2012, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -27,7 +27,7 @@ enum status_message | |||||||
| 	status_msg_hub_registered_users_only = -3,  /* hub is for registered users only */ | 	status_msg_hub_registered_users_only = -3,  /* hub is for registered users only */ | ||||||
| 	status_msg_inf_error_nick_missing    = -4,  /* no nickname given */ | 	status_msg_inf_error_nick_missing    = -4,  /* no nickname given */ | ||||||
| 	status_msg_inf_error_nick_multiple   = -5,  /* multiple nicknames given */ | 	status_msg_inf_error_nick_multiple   = -5,  /* multiple nicknames given */ | ||||||
| 	status_msg_inf_error_nick_invalid    = -6,  /* generic/unknown */ | 	status_msg_inf_error_nick_invalid    = -6,  /* generic/unkown */ | ||||||
| 	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, /* User is on too few hubs. */ | 	status_msg_user_hub_limit_low        = -44, /* Use is on too few hubs. */ | ||||||
| 	status_msg_user_hub_limit_high       = -45, /* User is on too many hubs. */ | 	status_msg_user_hub_limit_high       = -45, /* Use 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,6 +115,10 @@ 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-2014, Jan Vidar Krey |  * Copyright (C) 2007-2010, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2010, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2011, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -88,7 +88,7 @@ static int check_hash_tiger(const char* cid, const char* pid) | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  * FIXME: Only works for tiger hash. If a client doesn't support tiger we cannot let it in! |  * FIXME: Only works for tiger hash. If a client doesnt support tiger we cannot let it in! | ||||||
|  */ |  */ | ||||||
| static int check_cid(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd) | static int check_cid(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd) | ||||||
| { | { | ||||||
| @ -337,19 +337,9 @@ static int check_logged_in(struct hub_info* hub, struct hub_user* user, struct a | |||||||
| 	{ | 	{ | ||||||
| 		if (lookup1 == lookup2) | 		if (lookup1 == lookup2) | ||||||
| 		{ | 		{ | ||||||
| 			if (user_flag_get(lookup1, flag_choke)) | 			LOG_DEBUG("check_logged_in: exact same user is logged in: %s", user->id.nick); | ||||||
| 			{ |  | ||||||
| 				LOG_DEBUG("check_logged_in: exact same user is already logged in, but likely ghost: %s", user->id.nick); |  | ||||||
| 
 |  | ||||||
| 				// Old user unable to swallow data.
 |  | ||||||
| 				// Disconnect the existing user, and allow new user to enter.
 |  | ||||||
| 			hub_disconnect_user(hub, lookup1, quit_ghost_timeout); | 			hub_disconnect_user(hub, lookup1, quit_ghost_timeout); | ||||||
| 			} | 			return 0; | ||||||
| 			else |  | ||||||
| 			{ |  | ||||||
| 				LOG_DEBUG("check_logged_in: exact same user is already logged in: %s", user->id.nick); |  | ||||||
| 				return status_msg_inf_error_cid_taken; |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| @ -376,37 +366,21 @@ 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_name_encoded = 0; | 	char* ua_encoded = 0; | ||||||
| 	char* ua_version_encoded = 0; | 	char* ua = 0; | ||||||
| 	char* str = 0; |  | ||||||
| 	size_t offset = 0; |  | ||||||
| 	 | 	 | ||||||
| 	/* Get client user agent version */ | 	/* Get client user agent version */ | ||||||
| 	ua_name_encoded = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_USER_AGENT_PRODUCT); | 	ua_encoded = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_USER_AGENT); | ||||||
| 	ua_version_encoded = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_USER_AGENT_VERSION); | 	if (ua_encoded) | ||||||
| 	if (ua_name_encoded) |  | ||||||
| 	{ | 	{ | ||||||
| 		str = adc_msg_unescape(ua_name_encoded); | 		ua = adc_msg_unescape(ua_encoded); | ||||||
| 		if (str) | 		if (ua) | ||||||
| 		{ | 		{ | ||||||
| 			offset = strlen(str); | 			memcpy(user->id.user_agent, ua, MIN(strlen(ua), MAX_UA_LEN)); | ||||||
| 			memcpy(user->id.user_agent, str, MIN(offset, MAX_UA_LEN)); | 			hub_free(ua); | ||||||
| 			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; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -581,10 +555,6 @@ static int set_credentials(struct hub_info* hub, struct hub_user* user, struct a | |||||||
| 			adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_BOT); | 			adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_BOT); | ||||||
| 			break; | 			break; | ||||||
| 			 | 			 | ||||||
| 		case auth_cred_ubot: |  | ||||||
| 			adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_BOT); |  | ||||||
| 			break; |  | ||||||
| 
 |  | ||||||
| 		case auth_cred_guest: | 		case auth_cred_guest: | ||||||
| 			/* Nothing to be added to the info message */ | 			/* Nothing to be added to the info message */ | ||||||
| 			break; | 			break; | ||||||
| @ -597,14 +567,6 @@ static int set_credentials(struct hub_info* hub, struct hub_user* user, struct a | |||||||
| 			adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_OPERATOR); | 			adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_OPERATOR); | ||||||
| 			break; | 			break; | ||||||
| 			 | 			 | ||||||
| 		case auth_cred_opbot: |  | ||||||
| 			adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_HUBBOT); |  | ||||||
| 			break; |  | ||||||
| 
 |  | ||||||
| 		case auth_cred_opubot: |  | ||||||
| 			adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_HUBBOT); |  | ||||||
| 			break; |  | ||||||
| 
 |  | ||||||
| 		case auth_cred_super: | 		case auth_cred_super: | ||||||
| 			adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_SUPER_USER); | 			adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_SUPER_USER); | ||||||
| 			break; | 			break; | ||||||
| @ -660,8 +622,7 @@ 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_VERSION); | 		adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_USER_AGENT); | ||||||
| 		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-2014, Jan Vidar Krey |  * Copyright (C) 2007-2010, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2012, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -49,6 +49,34 @@ 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); | ||||||
| @ -88,6 +116,21 @@ 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)); | ||||||
| @ -130,7 +173,7 @@ void ioq_send_add(struct ioq_send* q, struct adc_message* msg_) | |||||||
| 	q->size += msg->length; | 	q->size += msg->length; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void ioq_send_remove(struct ioq_send* q, struct adc_message* msg) | void ioq_send_remove(struct ioq_send* q, struct adc_message* msg) | ||||||
| { | { | ||||||
| #ifdef DEBUG_SENDQ | #ifdef DEBUG_SENDQ | ||||||
| 	debug_msg("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-2014, Jan Vidar Krey |  * Copyright (C) 2007-2012, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -39,6 +39,7 @@ struct ioq_recv | |||||||
| { | { | ||||||
| 	char* buf; | 	char* buf; | ||||||
| 	size_t size; | 	size_t size; | ||||||
|  | 	// int flags;
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
| @ -102,5 +103,26 @@ 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
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										508
									
								
								src/core/link.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,508 @@ | |||||||
|  | /*
 | ||||||
|  |  * 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 */ | ||||||
							
								
								
									
										70
									
								
								src/core/link.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								src/core/link.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,70 @@ | |||||||
|  | /*
 | ||||||
|  |  * 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-2014, Jan Vidar Krey |  * Copyright (C) 2007-2011, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -125,6 +125,10 @@ 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; | ||||||
| 
 | 
 | ||||||
| @ -151,7 +155,7 @@ int main_loop() | |||||||
| 			setup_signal_handlers(hub); | 			setup_signal_handlers(hub); | ||||||
| #ifdef SYSTEMD | #ifdef SYSTEMD | ||||||
|                         /* Notify the service manager that this daemon has 
 |                         /* Notify the service manager that this daemon has 
 | ||||||
|                          * been successfully initialized and shall enter the |                          * been successfully initalized and shall enter the | ||||||
|                          * main loop. |                          * main loop. | ||||||
|                          */ |                          */ | ||||||
|                         sd_notifyf(0, "READY=1\n" |                         sd_notifyf(0, "READY=1\n" | ||||||
| @ -471,7 +475,7 @@ int main(int argc, char** argv) | |||||||
| 		} | 		} | ||||||
| 		else if (ret == 0) | 		else if (ret == 0) | ||||||
| 		{ | 		{ | ||||||
| 			/* child process - detach from TTY */ | 			/* child process - detatch from TTY */ | ||||||
| 			fclose(stdin); | 			fclose(stdin); | ||||||
| 			fclose(stdout); | 			fclose(stdout); | ||||||
| 			fclose(stderr); | 			fclose(stderr); | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2010, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -137,12 +137,6 @@ void net_event(struct net_connection* con, int event, void *arg) | |||||||
| 	LOG_TRACE("net_event() : fd=%d, ev=%d, arg=%p", con->sd, (int) event, arg); | 	LOG_TRACE("net_event() : fd=%d, ev=%d, arg=%p", con->sd, (int) event, arg); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 	if (event == NET_EVENT_ERROR) |  | ||||||
| 	{ |  | ||||||
| 		hub_disconnect_user(user->hub, user, quit_socket_error); |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if (event == NET_EVENT_TIMEOUT) | 	if (event == NET_EVENT_TIMEOUT) | ||||||
| 	{ | 	{ | ||||||
| 		if (user_is_connecting(user)) | 		if (user_is_connecting(user)) | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2010, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2011, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -40,11 +40,14 @@ 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); | ||||||
| 
 | 
 | ||||||
| 	LIST_FOREACH(struct plugin_command_handle*, cmdh, data->commands, | 	cmdh = (struct plugin_command_handle*) list_get_first(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; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -65,17 +68,6 @@ 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]; | ||||||
| @ -112,6 +104,7 @@ 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; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -120,6 +113,7 @@ 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); | ||||||
| @ -139,12 +133,6 @@ 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); | ||||||
| @ -200,14 +188,12 @@ 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-2014, Jan Vidar Krey |  * Copyright (C) 2007-2011, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2011, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -27,12 +27,13 @@ | |||||||
| 	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* plugin = (struct plugin_handle*) list_get_first(HUB->plugins->loaded); \ | ||||||
| 		LIST_FOREACH(struct plugin_handle*, plugin, HUB->plugins->loaded, \ | 		while (plugin) \ | ||||||
| 		{ \ | 		{ \ | ||||||
| 			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-2014, Jan Vidar Krey |  * Copyright (C) 2007-2011, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2011, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -102,6 +102,7 @@ struct plugin_handle* plugin_load(const char* filename, const char* config, stru | |||||||
| 	int ret; | 	int ret; | ||||||
| 	struct plugin_handle* handle = (struct plugin_handle*) hub_malloc_zero(sizeof(struct plugin_handle)); | 	struct plugin_handle* handle = (struct plugin_handle*) hub_malloc_zero(sizeof(struct plugin_handle)); | ||||||
| 	struct uhub_plugin* plugin = plugin_open(filename); | 	struct uhub_plugin* plugin = plugin_open(filename); | ||||||
|  | 	struct plugin_hub_internals* internals = (struct plugin_hub_internals*) plugin->internals; | ||||||
| 
 | 
 | ||||||
| 	if (!plugin) | 	if (!plugin) | ||||||
| 		return NULL; | 		return NULL; | ||||||
| @ -117,7 +118,6 @@ struct plugin_handle* plugin_load(const char* filename, const char* config, stru | |||||||
| 	unregister_f = plugin_lookup_symbol(plugin, "plugin_unregister"); | 	unregister_f = plugin_lookup_symbol(plugin, "plugin_unregister"); | ||||||
| 
 | 
 | ||||||
| 	// register hub internals
 | 	// register hub internals
 | ||||||
| 	struct plugin_hub_internals* internals = (struct plugin_hub_internals*) plugin->internals; |  | ||||||
| 	internals->unregister = unregister_f; | 	internals->unregister = unregister_f; | ||||||
| 	internals->hub = hub; | 	internals->hub = hub; | ||||||
| 	internals->callback_data = plugin_callback_data_create(); | 	internals->callback_data = plugin_callback_data_create(); | ||||||
| @ -229,16 +229,16 @@ int plugin_initialize(struct hub_config* config, struct hub_info* hub) | |||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void plugin_unload_ptr(void* ptr) |  | ||||||
| { |  | ||||||
| 	struct plugin_handle* plugin = (struct plugin_handle*) ptr; |  | ||||||
| 	plugin_unload(plugin); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| void plugin_shutdown(struct uhub_plugins* handle) | void plugin_shutdown(struct uhub_plugins* handle) | ||||||
| { | { | ||||||
| 	list_clear(handle->loaded, plugin_unload_ptr); | 	struct plugin_handle* plugin = (struct plugin_handle*) list_get_first(handle->loaded); | ||||||
|  | 	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-2014, Jan Vidar Krey |  * Copyright (C) 2007-2011, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2010, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -71,15 +71,17 @@ static void probe_net_event(struct net_connection* con, int events, void *arg) | |||||||
| 				probe_destroy(probe); | 				probe_destroy(probe); | ||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
| 			else if ((memcmp(probe_recvbuf, "GET ", 4) == 0) || | #ifdef LINK_SUPPORT | ||||||
| 				 (memcmp(probe_recvbuf, "POST", 4) == 0) || | 			else if (probe->hub->config->hub_link_enabled && memcmp(probe_recvbuf, "LSUP", 4) == 0) | ||||||
| 				 (memcmp(probe_recvbuf, "HEAD", 4) == 0)) |  | ||||||
| 			{ | 			{ | ||||||
| 				/* Looks like HTTP - Not supported, but we log it. */ | 				if (link_create(probe->hub, probe->connection, &probe->addr)) | ||||||
| 				LOG_TRACE("Probed HTTP connection. Not supported closing connection (%s)", ip_convert_to_string(&probe->addr)); | 				{ | ||||||
| 				const char* buf = "501 Not implemented\r\n\r\n"; | 					probe->connection = 0; | ||||||
| 				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 &&  | ||||||
| @ -90,14 +92,11 @@ static void probe_net_event(struct net_connection* con, int events, void *arg) | |||||||
| 				if (probe->hub->config->tls_enable) | 				if (probe->hub->config->tls_enable) | ||||||
| 				{ | 				{ | ||||||
| 					LOG_TRACE("Probed TLS %d.%d connection", (int) probe_recvbuf[9], (int) probe_recvbuf[10]); | 					LOG_TRACE("Probed TLS %d.%d connection", (int) probe_recvbuf[9], (int) probe_recvbuf[10]); | ||||||
| 					if (net_con_ssl_handshake(con, net_con_ssl_mode_server, probe->hub->ctx) < 0) | 					if (user_create(probe->hub, probe->connection, &probe->addr)) | ||||||
| 					{ |  | ||||||
| 						LOG_TRACE("TLS handshake negotiation failed."); |  | ||||||
| 					} |  | ||||||
| 					else if (user_create(probe->hub, probe->connection, &probe->addr)) |  | ||||||
| 					{ | 					{ | ||||||
| 						probe->connection = 0; | 						probe->connection = 0; | ||||||
| 					} | 					} | ||||||
|  | 					net_con_ssl_handshake(con, net_con_ssl_mode_server, probe->hub->ctx); | ||||||
| 				} | 				} | ||||||
| 				else | 				else | ||||||
| 				{ | 				{ | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2010, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2009, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -82,19 +82,16 @@ static int check_send_queue(struct hub_info* hub, struct hub_user* user, struct | |||||||
| 
 | 
 | ||||||
| 	if ((user->send_queue->size + msg->length) > get_max_send_queue(hub)) | 	if ((user->send_queue->size + msg->length) > get_max_send_queue(hub)) | ||||||
| 	{ | 	{ | ||||||
| 		user_flag_set(user, flag_choke); |  | ||||||
| 		LOG_WARN("send queue overflowed, message discarded."); | 		LOG_WARN("send queue overflowed, message discarded."); | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (user->send_queue->size > get_max_send_queue_soft(hub)) | 	if (user->send_queue->size > get_max_send_queue_soft(hub)) | ||||||
| 	{ | 	{ | ||||||
| 		user_flag_set(user, flag_choke); |  | ||||||
| 		LOG_WARN("send queue soft overflowed."); | 		LOG_WARN("send queue soft overflowed."); | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	user_flag_unset(user, flag_choke); |  | ||||||
| 	return 1; | 	return 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -102,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("send %s: \"%s\"", sid_to_string(user->id.sid), data); | 	LOG_PROTO("[user] send %s: \"%s\"", sid_to_string(user->id.sid), data); | ||||||
| 	free(data); | 	free(data); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| @ -142,11 +139,12 @@ 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* user = (struct hub_user*) list_get_first(hub->users->list); | ||||||
| 	LIST_FOREACH(struct hub_user*, user, hub->users->list, | 	while (user) | ||||||
| 	{ | 	{ | ||||||
| 		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; | ||||||
| } | } | ||||||
| @ -156,38 +154,47 @@ 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* user = (struct hub_user*) list_get_first(hub->users->list); | ||||||
| 	LIST_FOREACH(struct hub_user*, user, hub->users->list, | 	while (user) | ||||||
| 	{ | 	{ | ||||||
| 		if (user->feature_cast) | 		if (user->feature_cast) | ||||||
| 		{ | 		{ | ||||||
| 			do_send = 1; | 			do_send = 1; | ||||||
| 			 | 			 | ||||||
| 			LIST_FOREACH(char*, tmp, command->feature_cast_include, | 			tmp = list_get_first(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; | ||||||
|  | 			} | ||||||
| 			 | 			 | ||||||
| 			LIST_FOREACH(char*, tmp, command->feature_cast_exclude, | 			tmp = list_get_first(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; | ||||||
| } | } | ||||||
| @ -207,13 +214,16 @@ 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); | ||||||
| 	 | 	 | ||||||
| 		LIST_FOREACH(struct hub_user*, user, hub->users->list, | 		user = (struct hub_user*) list_get_first(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-2014, Jan Vidar Krey |  * Copyright (C) 2007-2009, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2010, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -232,12 +232,15 @@ 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; | 	char* tmp = list_get_first(user->feature_cast); | ||||||
| 	LIST_FOREACH(char*, tmp, user->feature_cast, | 	while (tmp) | ||||||
| 	{ | 	{ | ||||||
| 		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-2014, Jan Vidar Krey |  * Copyright (C) 2007-2010, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -68,7 +68,7 @@ enum user_quit_reason | |||||||
| 	quit_timeout        = 4,     /** User timed out (no data for a while) */ | 	quit_timeout        = 4,     /** User timed out (no data for a while) */ | ||||||
| 	quit_send_queue     = 5,     /** User's send queue was overflowed */ | 	quit_send_queue     = 5,     /** User's send queue was overflowed */ | ||||||
| 	quit_memory_error   = 6,     /** Not enough memory available */ | 	quit_memory_error   = 6,     /** Not enough memory available */ | ||||||
| 	quit_socket_error   = 7,     /** A socket error occurred */ | 	quit_socket_error   = 7,     /** A socket error occured */ | ||||||
| 	quit_protocol_error = 8,     /** Fatal protocol error */ | 	quit_protocol_error = 8,     /** Fatal protocol error */ | ||||||
| 	quit_logon_error    = 9,     /** Unable to login (wrong password, CID/PID, etc) */ | 	quit_logon_error    = 9,     /** Unable to login (wrong password, CID/PID, etc) */ | ||||||
| 	quit_update_error   = 10,    /** Update error. INF update changed share/slot info and no longer satisfies the hub limits. */ | 	quit_update_error   = 10,    /** Update error. INF update changed share/slot info and no longer satisfies the hub limits. */ | ||||||
| @ -76,7 +76,7 @@ enum user_quit_reason | |||||||
| 	quit_ghost_timeout  = 12,    /** The user is a ghost, and trying to login from another connection */ | 	quit_ghost_timeout  = 12,    /** The user is a ghost, and trying to login from another connection */ | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /** Returns an appropriate string for the given quit reason */ | /** Returns an apropriate string for the given quit reason */ | ||||||
| extern const char* user_get_quit_reason_string(enum user_quit_reason); | extern const char* user_get_quit_reason_string(enum user_quit_reason); | ||||||
| 
 | 
 | ||||||
| struct hub_user_info | struct hub_user_info | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2009, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -38,11 +38,6 @@ 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() | ||||||
| { | { | ||||||
| @ -51,10 +46,15 @@ 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,18 +64,11 @@ 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); | ||||||
| @ -88,9 +81,6 @@ 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); | ||||||
| @ -106,8 +96,6 @@ 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) | ||||||
| 	{ | 	{ | ||||||
| @ -132,29 +120,42 @@ 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*) rb_tree_get(users->cidmap, (const void*) cid); | 	struct hub_user* user = (struct hub_user*) list_get_first(users->list); /* iterate users - only on incoming INF msg */ | ||||||
|  | 	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*) rb_tree_get(users->nickmap, nick); | 	struct hub_user* user = (struct hub_user*) list_get_first(users->list); /* iterate users - only on incoming INF msg */ | ||||||
|  | 	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* user = (struct hub_user*) list_get_first(users->list); /* iterate users - only on incoming INF msg */ | ||||||
| 	LIST_FOREACH(struct hub_user*, user, users->list, | 	while (user) | ||||||
| 	{ | 	{ | ||||||
| 		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; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -163,8 +164,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 */ | ||||||
| 	LIST_FOREACH(struct hub_user*, user, users->list, | 	while (user) | ||||||
| 	{ | 	{ | ||||||
| 		if (user_is_logged_in(user)) | 		if (user_is_logged_in(user)) | ||||||
| 		{ | 		{ | ||||||
| @ -172,7 +173,8 @@ 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-2014, Jan Vidar Krey |  * Copyright (C) 2007-2009, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -24,12 +24,10 @@ 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)" */ |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
| @ -42,7 +40,7 @@ extern struct hub_user_manager* uman_init(); | |||||||
|  * Shuts down the user manager. |  * Shuts down the user manager. | ||||||
|  * All users will be disconnected and deleted as part of this. |  * All users will be disconnected and deleted as part of this. | ||||||
|  * |  * | ||||||
|  * @return 0 on success, or -1 in an error occurred (invalid pointer). |  * @return 0 on success, or -1 in an error occured (invalid pointer). | ||||||
|  */ |  */ | ||||||
| extern int uman_shutdown(struct hub_user_manager* users); | extern int uman_shutdown(struct hub_user_manager* users); | ||||||
| 
 | 
 | ||||||
| @ -106,7 +104,7 @@ extern struct hub_user* uman_get_user_by_nick(struct hub_user_manager* users, co | |||||||
|  * |  * | ||||||
|  * @param[out] target the list of users matching the address |  * @param[out] target the list of users matching the address | ||||||
|  * @param range the IP range of users to match |  * @param range the IP range of users to match | ||||||
|  * @return The number of users matching the addresses, or -1 on error (mask is wrong). |  * @return The number of users matching the addressess, or -1 on error (mask is wrong). | ||||||
|  */ |  */ | ||||||
| extern size_t uman_get_user_by_addr(struct hub_user_manager* users, struct linked_list* target, struct ip_range* range); | extern size_t uman_get_user_by_addr(struct hub_user_manager* users, struct linked_list* target, struct ip_range* range); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2012, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -102,7 +102,14 @@ void net_backend_shutdown() | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| void net_backend_update(struct net_connection* con, int 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_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); | ||||||
| } | } | ||||||
| @ -141,7 +148,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); | ||||||
| 
 | 
 | ||||||
| @ -159,8 +166,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(net_con_get_sd(con), 1); | 	net_set_nonblocking(con->sd, 1); | ||||||
| 	net_set_nosigpipe(net_con_get_sd(con), 1); | 	net_set_nosigpipe(con->sd, 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-2014, Jan Vidar Krey |  * Copyright (C) 2007-2012, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -75,14 +75,6 @@ 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-2014, Jan Vidar Krey |  * Copyright (C) 2007-2012, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2013, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,13 +13,12 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #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() | ||||||
| { | { | ||||||
| @ -117,27 +116,10 @@ void* net_con_get_ptr(struct net_connection* con) | |||||||
| 	return con->ptr; | 	return con->ptr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void net_con_update(struct net_connection* con, int events) |  | ||||||
| { |  | ||||||
| #ifdef SSL_SUPPORT |  | ||||||
| 	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) | void net_con_destroy(struct net_connection* con) | ||||||
| { | { | ||||||
| #ifdef SSL_SUPPORT | #ifdef SSL_SUPPORT | ||||||
| 	if (con && con->ssl) | 	if (con->ssl) | ||||||
| 		net_ssl_destroy(con); | 		net_ssl_destroy(con); | ||||||
| #endif | #endif | ||||||
| 	hub_free(con); | 	hub_free(con); | ||||||
| @ -196,12 +178,11 @@ 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_in) : sizeof(struct sockaddr_in6)); | 	int ret = net_connect(net_con_get_sd(con), (struct sockaddr*) &job->addr, af == AF_INET ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)); | ||||||
| 	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; | ||||||
| 	} | 	} | ||||||
| @ -283,6 +264,7 @@ 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; | ||||||
| @ -325,7 +307,7 @@ static void net_connect_job_internal_cb(struct net_connection* con, int event, v | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static void net_connect_cancel(struct net_connect_handle* handle) | static int net_connect_cancel(struct net_connect_handle* handle) | ||||||
| { | { | ||||||
| 	struct net_connect_job* job; | 	struct net_connect_job* job; | ||||||
| 
 | 
 | ||||||
| @ -381,7 +363,6 @@ 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; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -440,6 +421,7 @@ 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) | ||||||
| @ -524,34 +506,3 @@ 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-2014, Jan Vidar Krey |  * Copyright (C) 2007-2013, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -28,7 +28,6 @@ | |||||||
| #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 | ||||||
| { | { | ||||||
| @ -88,7 +87,7 @@ extern void net_con_close(struct net_connection* con); | |||||||
|  * |  * | ||||||
|  * @return returns the number of bytes sent. |  * @return returns the number of bytes sent. | ||||||
|  *         0 if no data is sent, and this function should be called again (EWOULDBLOCK/EINTR) |  *         0 if no data is sent, and this function should be called again (EWOULDBLOCK/EINTR) | ||||||
|  *        <0 if an error occurred, the negative number contains the error code. |  *        <0 if an error occured, the negative number contains the error code. | ||||||
|  */ |  */ | ||||||
| extern ssize_t net_con_send(struct net_connection* con, const void* buf, size_t len); | extern ssize_t net_con_send(struct net_connection* con, const void* buf, size_t len); | ||||||
| 
 | 
 | ||||||
| @ -97,7 +96,7 @@ extern ssize_t net_con_send(struct net_connection* con, const void* buf, size_t | |||||||
|  * |  * | ||||||
|  * @return returns the number of bytes sent. |  * @return returns the number of bytes sent. | ||||||
|  *         0 if no data is sent, and this function should be called again (EWOULDBLOCK/EINTR) |  *         0 if no data is sent, and this function should be called again (EWOULDBLOCK/EINTR) | ||||||
|  *        <0 if an error occurred, the negative number contains the error code. |  *        <0 if an error occured, the negative number contains the error code. | ||||||
|  */ |  */ | ||||||
| extern ssize_t net_con_recv(struct net_connection* con, void* buf, size_t len); | extern ssize_t net_con_recv(struct net_connection* con, void* buf, size_t len); | ||||||
| 
 | 
 | ||||||
| @ -109,7 +108,7 @@ extern ssize_t net_con_recv(struct net_connection* con, void* buf, size_t len); | |||||||
| extern ssize_t net_con_peek(struct net_connection* con, void* buf, size_t len); | extern ssize_t net_con_peek(struct net_connection* con, void* buf, size_t len); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Set timeout for connection. |  * Set timeout for connetion. | ||||||
|  * |  * | ||||||
|  * @param seconds the number of seconds into the future. |  * @param seconds the number of seconds into the future. | ||||||
|  */ |  */ | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2013, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -68,11 +68,6 @@ 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!
 | ||||||
| @ -81,8 +76,6 @@ 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; | ||||||
| @ -94,11 +87,13 @@ 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); | ||||||
| @ -110,18 +105,22 @@ 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_TRACE("net_dns_process(): jobs=%d, results=%d", (int) list_size(g_dns->jobs), (int) list_size(g_dns->results)); | 	LOG_DUMP("net_dns_process(): jobs=%d, results=%d", (int) list_size(g_dns->jobs), (int) list_size(g_dns->results)); | ||||||
| 
 | 
 | ||||||
| 	LIST_FOREACH(struct net_dns_result*, result, g_dns->results, | 	for (result = (struct net_dns_result*) list_get_first(g_dns->results); result; result = (struct net_dns_result*) list_get_next(g_dns->results)) | ||||||
| 	{ | 	{ | ||||||
| 		struct net_dns_job* job = result->job; | 		struct net_dns_job* job = result->job; | ||||||
| #ifdef DEBUG_LOOKUP_TIME | #ifdef DEBUG_LOOKUP_TIME | ||||||
| @ -147,9 +146,9 @@ void net_dns_process() | |||||||
| 			result->job = NULL; | 			result->job = NULL; | ||||||
| 			free_job(job); | 			free_job(job); | ||||||
| 		} | 		} | ||||||
| 	}); | 	} | ||||||
| 
 | 
 | ||||||
| 	list_clear(g_dns->results, NULL); | 	list_clear(g_dns->results, &dummy_free); | ||||||
| 	uhub_mutex_unlock(&g_dns->mutex); | 	uhub_mutex_unlock(&g_dns->mutex); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -216,7 +215,6 @@ 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; | ||||||
| @ -275,14 +273,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; | ||||||
| 	LIST_FOREACH(struct net_dns_job*, it, g_dns->jobs, | 	for (it = (struct net_dns_job*) list_get_first(g_dns->jobs); it; it = (struct net_dns_job*) list_get_next(g_dns->jobs)) | ||||||
| 	{ | 	{ | ||||||
| 		if (it == job) | 		if (it == job) | ||||||
| 		{ | 		{ | ||||||
| 			list_remove(g_dns->jobs, it); | 			list_remove(g_dns->jobs, it); | ||||||
| 			return job; | 			return job; | ||||||
| 		} | 		} | ||||||
| 	}); | 	} | ||||||
| 	return NULL; | 	return NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -290,14 +288,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; | ||||||
| 	LIST_FOREACH(struct net_dns_result*, it, g_dns->results, | 	for (it = (struct net_dns_result*) list_get_first(g_dns->results); it; it = (struct net_dns_result*) list_get_next(g_dns->results)) | ||||||
| 	{ | 	{ | ||||||
| 		if (it->job == job) | 		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-2014, Jan Vidar Krey |  * Copyright (C) 2007-2013, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2010, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2009, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2009, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -92,7 +92,7 @@ extern int ip_is_valid_ipv6(const char* address); | |||||||
|  * |  * | ||||||
|  * @param text_addr is an ipaddress either ipv6 or ipv4. |  * @param text_addr is an ipaddress either ipv6 or ipv4. | ||||||
|  *                  Special magic addresses called "any" and "loopback" exist, |  *                  Special magic addresses called "any" and "loopback" exist, | ||||||
|  *                  and will work across IPv6/IPv4. |  *                  and will work accross IPv6/IPv4. | ||||||
|  * @param port      Fill the struct sockaddr* with the given port, can safely be ignored. |  * @param port      Fill the struct sockaddr* with the given port, can safely be ignored. | ||||||
|  */ |  */ | ||||||
| extern int ip_convert_address(const char* text_address, int port, struct sockaddr* addr, socklen_t* addr_len); | extern int ip_convert_address(const char* text_address, int port, struct sockaddr* addr, socklen_t* addr_len); | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2010, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2019, Jan Vidar Krey |  * Copyright (C) 2007-2012, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -805,22 +805,4 @@ void net_stats_add_close() | |||||||
| 	stats.closed++; | 	stats.closed++; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void net_stats_tls_add_accept() |  | ||||||
| { |  | ||||||
| 	stats.tls_accept++; |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| void net_stats_tls_add_connect() |  | ||||||
| { |  | ||||||
| 	stats.tls_connect++; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void net_stats_tls_add_error() |  | ||||||
| { |  | ||||||
| 	stats.tls_error++; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void net_stats_tls_add_close() |  | ||||||
| { |  | ||||||
| 	stats.tls_close++; |  | ||||||
| } |  | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2019, Jan Vidar Krey |  * Copyright (C) 2007-2012, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -28,10 +28,6 @@ struct net_statistics | |||||||
| 	size_t accept; | 	size_t accept; | ||||||
| 	size_t closed; | 	size_t closed; | ||||||
| 	size_t errors; | 	size_t errors; | ||||||
| 	size_t tls_accept; |  | ||||||
| 	size_t tls_connect; |  | ||||||
| 	size_t tls_error; |  | ||||||
| 	size_t tls_close; |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct net_socket_t; | struct net_socket_t; | ||||||
| @ -57,7 +53,7 @@ extern int net_initialize(); | |||||||
| extern int net_destroy(); | extern int net_destroy(); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * @return the number of sockets currently being monitored. |  * @return the number of sockets currrently being monitored. | ||||||
|  */ |  */ | ||||||
| extern int net_monitor_count(); | extern int net_monitor_count(); | ||||||
| 
 | 
 | ||||||
| @ -67,7 +63,7 @@ extern int net_monitor_count(); | |||||||
| extern int net_monitor_capacity(); | extern int net_monitor_capacity(); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * @return the last error code occurred. |  * @return the last error code occured. | ||||||
|  * |  * | ||||||
|  * NOTE: On Windows this is the last error code from the socket library, but |  * NOTE: On Windows this is the last error code from the socket library, but | ||||||
|  *       on UNIX this is the errno variable that can be overwritten by any |  *       on UNIX this is the errno variable that can be overwritten by any | ||||||
| @ -251,14 +247,9 @@ extern void net_stats_report(); | |||||||
| extern void net_stats_reset(); | extern void net_stats_reset(); | ||||||
| extern void net_stats_add_tx(size_t bytes); | extern void net_stats_add_tx(size_t bytes); | ||||||
| extern void net_stats_add_rx(size_t bytes); | extern void net_stats_add_rx(size_t bytes); | ||||||
| extern void net_stats_tls_add_accept(); |  | ||||||
| extern void net_stats_tls_add_connect(); |  | ||||||
| extern void net_stats_tls_add_error(); |  | ||||||
| extern void net_stats_tls_add_close(); |  | ||||||
| extern void net_stats_add_accept(); | extern void net_stats_add_accept(); | ||||||
| extern void net_stats_add_error(); | extern void net_stats_add_error(); | ||||||
| extern void net_stats_add_close(); | extern void net_stats_add_close(); | ||||||
| extern void net_stats_add_connect(); |  | ||||||
| extern int net_stats_timeout(); | extern int net_stats_timeout(); | ||||||
| extern void net_stats_get(struct net_statistics** intermediate, struct net_statistics** total); | extern void net_stats_get(struct net_statistics** intermediate, struct net_statistics** total); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,102 +0,0 @@ | |||||||
| /*
 |  | ||||||
|  * uhub - A tiny ADC p2p connection hub |  | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  | ||||||
|  * |  | ||||||
|  * This program is free software; you can redistribute it and/or modify |  | ||||||
|  * it under the terms of the GNU General Public License as published by |  | ||||||
|  * the Free Software Foundation; either version 3 of the License, or |  | ||||||
|  * (at your option) any later version. |  | ||||||
|  * |  | ||||||
|  * This program is distributed in the hope that it will be useful, |  | ||||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
|  * GNU General Public License for more details. |  | ||||||
|  * |  | ||||||
|  * You should have received a copy of the GNU General Public License |  | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| #include "uhub.h" |  | ||||||
| 
 |  | ||||||
| struct uhub_notify_handle |  | ||||||
| { |  | ||||||
| 	net_notify_callback callback; |  | ||||||
| 	void* ptr; |  | ||||||
| #ifndef WIN32 |  | ||||||
| 	int pipe_fd[2]; |  | ||||||
| 	struct net_connection* con; |  | ||||||
| #endif |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * This contains a mechanism to wake up the main thread |  | ||||||
|  * in a thread safe manner while it would be blocking |  | ||||||
|  * in select() or something equivalent typically invoked from |  | ||||||
|  * net_backend_process(). |  | ||||||
|  * |  | ||||||
|  * The main usage is for the DNS resolver to notify the |  | ||||||
|  * main thread that there are DNS results to be |  | ||||||
|  * processed. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Create a notification handle. |  | ||||||
|  */ |  | ||||||
| #ifndef WIN32 |  | ||||||
| static void notify_callback(struct net_connection* con, int event, void* ptr) |  | ||||||
| { |  | ||||||
| 	LOG_TRACE("notify_callback()"); |  | ||||||
| 	struct uhub_notify_handle* handle = (struct uhub_notify_handle*) ptr; |  | ||||||
| 	char buf; |  | ||||||
| 	int ret = read(handle->pipe_fd[0], &buf, 1); |  | ||||||
| 	if (ret == 1) |  | ||||||
| 	{ |  | ||||||
| 		if (handle->callback) |  | ||||||
| 			handle->callback(handle, handle->ptr); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| struct uhub_notify_handle* net_notify_create(net_notify_callback cb, void* ptr) |  | ||||||
| { |  | ||||||
| 	LOG_TRACE("net_notify_create()"); |  | ||||||
| 	struct uhub_notify_handle* handle = (struct uhub_notify_handle*) hub_malloc(sizeof(struct uhub_notify_handle)); |  | ||||||
| 	handle->callback = cb; |  | ||||||
| 	handle->ptr = ptr; |  | ||||||
| #ifndef WIN32 |  | ||||||
| 	int ret = pipe(handle->pipe_fd); |  | ||||||
| 	if (ret == -1) |  | ||||||
| 	{ |  | ||||||
| 		LOG_ERROR("Unable to setup notification pipes."); |  | ||||||
| 		hub_free(handle); |  | ||||||
| 		return 0; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	handle->con = net_con_create(); |  | ||||||
| 	net_con_initialize(handle->con, handle->pipe_fd[0], notify_callback, handle, NET_EVENT_READ); |  | ||||||
| #endif |  | ||||||
| 	return handle; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| void net_notify_destroy(struct uhub_notify_handle* handle) |  | ||||||
| { |  | ||||||
| 	LOG_TRACE("net_notify_destroy()"); |  | ||||||
| #ifndef WIN32 |  | ||||||
| 	net_con_destroy(handle->con); |  | ||||||
| 	close(handle->pipe_fd[0]); |  | ||||||
| 	close(handle->pipe_fd[1]); |  | ||||||
| 	handle->pipe_fd[0] = -1; |  | ||||||
| 	handle->pipe_fd[0] = -1; |  | ||||||
| #endif |  | ||||||
| 	hub_free(handle); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void net_notify_signal(struct uhub_notify_handle* handle, char data) |  | ||||||
| { |  | ||||||
| 	LOG_TRACE("net_notify_signal()"); |  | ||||||
| #ifndef WIN32 |  | ||||||
| 	write(handle->pipe_fd[1], &data, 1); |  | ||||||
| #endif |  | ||||||
| } |  | ||||||
| @ -1,56 +0,0 @@ | |||||||
| /*
 |  | ||||||
|  * uhub - A tiny ADC p2p connection hub |  | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  | ||||||
|  * |  | ||||||
|  * This program is free software; you can redistribute it and/or modify |  | ||||||
|  * it under the terms of the GNU General Public License as published by |  | ||||||
|  * the Free Software Foundation; either version 3 of the License, or |  | ||||||
|  * (at your option) any later version. |  | ||||||
|  * |  | ||||||
|  * This program is distributed in the hope that it will be useful, |  | ||||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
|  * GNU General Public License for more details. |  | ||||||
|  * |  | ||||||
|  * You should have received a copy of the GNU General Public License |  | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  | ||||||
|  * |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| #ifndef HAVE_UHUB_NETWORK_NOTIFY_API_H |  | ||||||
| #define HAVE_UHUB_NETWORK_NOTIFY_API_H |  | ||||||
| 
 |  | ||||||
| struct uhub_notify_handle; |  | ||||||
| 
 |  | ||||||
| typedef void (*net_notify_callback)(struct uhub_notify_handle* handle, void* ptr); |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * This contains a mechanism to wake up the main thread |  | ||||||
|  * in a thread safe manner while it would be blocking |  | ||||||
|  * in select() or something equivalent typically invoked from |  | ||||||
|  * net_backend_process(). |  | ||||||
|  * |  | ||||||
|  * The main usage is for the DNS resolver to notify the |  | ||||||
|  * main thread that there are DNS results to be |  | ||||||
|  * processed. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Create a notification handle. |  | ||||||
|  */ |  | ||||||
| struct uhub_notify_handle* net_notify_create(net_notify_callback cb, void* ptr); |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Destroy a notification handle. |  | ||||||
|  */ |  | ||||||
| void net_notify_destroy(struct uhub_notify_handle*); |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Signal the notification handle, this will surely |  | ||||||
|  * interrupt the net_backend_process(), and force it to |  | ||||||
|  * process messages. |  | ||||||
|  */ |  | ||||||
| void net_notify_signal(struct uhub_notify_handle*, char data); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| #endif /* HAVE_UHUB_NETWORK_NOTIFY_API_H */ |  | ||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2019, Jan Vidar Krey |  * Copyright (C) 2007-2012, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,33 +13,25 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #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 | ||||||
| 
 | 
 | ||||||
| void net_stats_add_tx(size_t bytes); | void net_stats_add_tx(size_t bytes); | ||||||
| void net_stats_add_rx(size_t bytes); | void net_stats_add_rx(size_t bytes); | ||||||
| void net_stats_tls_add_accept(); |  | ||||||
| void net_stats_tls_add_errors(); |  | ||||||
| void net_stats_tls_add_accept(); |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| struct net_ssl_openssl | 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; | ||||||
| @ -47,7 +39,8 @@ struct net_ssl_openssl | |||||||
| 
 | 
 | ||||||
| struct net_context_openssl | struct net_context_openssl | ||||||
| { | { | ||||||
| 	SSL_CTX* ssl; | 	SSL_METHOD* ssl_method; | ||||||
|  | 	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) | ||||||
| @ -56,29 +49,6 @@ 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; | ||||||
| @ -95,9 +65,7 @@ int net_ssl_library_init() | |||||||
| int net_ssl_library_shutdown() | int net_ssl_library_shutdown() | ||||||
| { | { | ||||||
| 	ERR_clear_error(); | 	ERR_clear_error(); | ||||||
| #if OPENSSL_VERSION_NUMBER < 0x10100000L |  | ||||||
| 	ERR_remove_state(0); | 	ERR_remove_state(0); | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
| 	ENGINE_cleanup(); | 	ENGINE_cleanup(); | ||||||
| 	CONF_modules_unload(1); | 	CONF_modules_unload(1); | ||||||
| @ -112,173 +80,56 @@ int net_ssl_library_shutdown() | |||||||
| 
 | 
 | ||||||
| static void add_io_stats(struct net_ssl_openssl* handle) | static void add_io_stats(struct net_ssl_openssl* handle) | ||||||
| { | { | ||||||
| #if OPENSSL_VERSION_NUMBER < 0x10100000L | 	if (handle->bio->num_read > handle->bytes_rx) | ||||||
| 	unsigned long num_read = handle->bio->num_read; |  | ||||||
| 	unsigned long num_write = handle->bio->num_write; |  | ||||||
| #else |  | ||||||
| 	unsigned long num_read = BIO_number_read(handle->bio); |  | ||||||
| 	unsigned long num_write = BIO_number_written(handle->bio); |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| 	if (num_read > handle->bytes_rx) |  | ||||||
| 	{ | 	{ | ||||||
| 		net_stats_add_rx(num_read - handle->bytes_rx); | 		net_stats_add_rx(handle->bio->num_read - handle->bytes_rx); | ||||||
| 		handle->bytes_rx = num_read; | 		handle->bytes_rx = handle->bio->num_read; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (num_write > handle->bytes_tx) | 	if (handle->bio->num_write > handle->bytes_tx) | ||||||
| 	{ | 	{ | ||||||
| 		net_stats_add_tx(num_write - handle->bytes_tx); | 		net_stats_add_tx(handle->bio->num_write - handle->bytes_tx); | ||||||
| 		handle->bytes_tx = num_write; | 		handle->bytes_tx = handle->bio->num_write; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static const SSL_METHOD* get_ssl_method(const char* tls_version, long* flags) |  | ||||||
| { |  | ||||||
|         if (!flags) |  | ||||||
|         { |  | ||||||
|             LOG_ERROR("flags is null"); |  | ||||||
|             return 0; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
| 	if (!tls_version || !*tls_version) |  | ||||||
| 	{ |  | ||||||
|             LOG_ERROR("tls_version is not set."); |  | ||||||
|             return 0; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	*flags = 0; |  | ||||||
| 	*flags |= SSL_OP_NO_SSLv2; |  | ||||||
|         *flags |= SSL_OP_NO_SSLv3; |  | ||||||
| 
 |  | ||||||
| 	if (!strcmp(tls_version, "1.0")) |  | ||||||
|         { |  | ||||||
| #if OPENSSL_VERSION_NUMBER < 0x10100000L |  | ||||||
|             return TLSv1_method(); |  | ||||||
| #endif |  | ||||||
|         } |  | ||||||
|         else if (!strcmp(tls_version, "1.1")) |  | ||||||
|         { |  | ||||||
| #if OPENSSL_VERSION_NUMBER < 0x10100000L |  | ||||||
|             return TLSv1_1_method(); |  | ||||||
| #else |  | ||||||
|             *flags |= SSL_OP_NO_TLSv1; |  | ||||||
| #endif |  | ||||||
|         } |  | ||||||
|         else if (!strcmp(tls_version, "1.2")) |  | ||||||
|         { |  | ||||||
| #if OPENSSL_VERSION_NUMBER < 0x10100000L |  | ||||||
|             return TLSv1_2_method(); |  | ||||||
| #else |  | ||||||
|             *flags |= SSL_OP_NO_TLSv1; |  | ||||||
|             *flags |= SSL_OP_NO_TLSv1_1; |  | ||||||
| #endif |  | ||||||
|         } |  | ||||||
|         else if (!strcmp(tls_version, "1.3")) |  | ||||||
|         { |  | ||||||
| #if OPENSSL_VERSION_NUMBER < 0x10100000L |  | ||||||
|             LOG_ERROR("TLS 1.3 is not supported by this version of OpenSSL"); |  | ||||||
|             return 0; |  | ||||||
| #else |  | ||||||
|             *flags |= SSL_OP_NO_TLSv1; |  | ||||||
|             *flags |= SSL_OP_NO_TLSv1_1; |  | ||||||
|             *flags |= SSL_OP_NO_TLSv1_2; |  | ||||||
| #endif |  | ||||||
|         } |  | ||||||
|         else |  | ||||||
|         { |  | ||||||
|             LOG_ERROR("Unable to recognize tls_version: %s", tls_version); |  | ||||||
|             return 0; |  | ||||||
|         } |  | ||||||
| #if OPENSSL_VERSION_NUMBER < 0x10100000L |  | ||||||
|         // never gets here!
 |  | ||||||
| #else |  | ||||||
| 	return TLS_method(); |  | ||||||
| #endif |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * List of supported protocols for ALPN. |  | ||||||
|  * We only support "adc" protocol. |  | ||||||
|  */ |  | ||||||
| unsigned char alpn_protocols[] = { |  | ||||||
|      3, 'a', 'd', 'c', |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * Callback for the server to select a protocol from the list |  | ||||||
|  * sent by the client via ALPN. |  | ||||||
|  */ |  | ||||||
| static int alpn_server_select_protocol(SSL *ssl, const unsigned char **out, unsigned char *outlen, |  | ||||||
|                                  const unsigned char *in, unsigned int inlen, void *arg) |  | ||||||
| { |  | ||||||
|     int res = SSL_select_next_proto((unsigned char **)out, outlen, |  | ||||||
|                     alpn_protocols, sizeof(alpn_protocols), in, inlen); |  | ||||||
|     if (res == OPENSSL_NPN_NO_OVERLAP) |  | ||||||
|     { |  | ||||||
|         // set default protocol
 |  | ||||||
|         *out = alpn_protocols; |  | ||||||
|         *outlen = 1+alpn_protocols[0]; |  | ||||||
|     } |  | ||||||
|     return SSL_TLSEXT_ERR_OK; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /**
 | /**
 | ||||||
|  * Create a new SSL context. |  * Create a new SSL context. | ||||||
|  */ |  */ | ||||||
| struct ssl_context_handle* net_ssl_context_create(const char* tls_version, const char* tls_ciphersuite) | struct ssl_context_handle* net_ssl_context_create() | ||||||
| { | { | ||||||
|  | 
 | ||||||
| 	struct net_context_openssl* ctx = (struct net_context_openssl*) hub_malloc_zero(sizeof(struct net_context_openssl)); | 	struct net_context_openssl* ctx = (struct net_context_openssl*) hub_malloc_zero(sizeof(struct net_context_openssl)); | ||||||
|         long flags = 0; | 	ctx->ssl_method = (SSL_METHOD*) SSLv23_method(); /* TLSv1_method() */ | ||||||
| 	const SSL_METHOD* ssl_method = get_ssl_method(tls_version, &flags); | 	ctx->ssl_ctx = SSL_CTX_new(ctx->ssl_method); | ||||||
| 
 | 
 | ||||||
| 	if (!ssl_method) | 	/* Disable SSLv2 */ | ||||||
| 	{ | 	SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv2); | ||||||
| 		hub_free(ctx); |  | ||||||
| 		return 0; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	ctx->ssl = SSL_CTX_new(ssl_method); |  | ||||||
| 
 |  | ||||||
| 	// 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 */ | ||||||
| 	flags |= SSL_OP_NO_COMPRESSION; | 	SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_COMPRESSION); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|         // Set flags
 | 	SSL_CTX_set_quiet_shutdown(ctx->ssl_ctx, 1); | ||||||
|         SSL_CTX_set_options(ctx->ssl, flags); |  | ||||||
| 
 |  | ||||||
| 	/* 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; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	SSL_CTX_set_alpn_select_cb(ctx->ssl, alpn_server_select_protocol, NULL); |  | ||||||
| 
 | 
 | ||||||
| 	return (struct ssl_context_handle*) ctx; | 	return (struct ssl_context_handle*) ctx; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void net_ssl_context_destroy(struct ssl_context_handle* ctx_) | extern void net_ssl_context_destroy(struct ssl_context_handle* ctx_) | ||||||
| { | { | ||||||
| 	struct net_context_openssl* ctx = (struct net_context_openssl*) ctx_; | 	struct net_context_openssl* ctx = (struct net_context_openssl*) ctx_; | ||||||
| 	SSL_CTX_free(ctx->ssl); | 	SSL_CTX_free(ctx->ssl_ctx); | ||||||
| 	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_chain_file(ctx->ssl, pem_file) < 0) | 	if (SSL_CTX_use_certificate_file(ctx->ssl_ctx, pem_file, SSL_FILETYPE_PEM) < 0) | ||||||
| 	{ | 	{ | ||||||
| 		LOG_ERROR("SSL_CTX_use_certificate_chain_file: %s", ERR_error_string(ERR_get_error(), NULL)); | 		LOG_ERROR("SSL_CTX_use_certificate_file: %s", ERR_error_string(ERR_get_error(), NULL)); | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -288,7 +139,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, pem_file, SSL_FILETYPE_PEM) < 0) | 	if (SSL_CTX_use_PrivateKey_file(ctx->ssl_ctx, pem_file, SSL_FILETYPE_PEM) < 0) | ||||||
| 	{ | 	{ | ||||||
| 		LOG_ERROR("SSL_CTX_use_PrivateKey_file: %s", ERR_error_string(ERR_get_error(), NULL)); | 		LOG_ERROR("SSL_CTX_use_PrivateKey_file: %s", ERR_error_string(ERR_get_error(), NULL)); | ||||||
| 		return 0; | 		return 0; | ||||||
| @ -299,7 +150,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) != 1) | 	if (SSL_CTX_check_private_key(ctx->ssl_ctx) != 1) | ||||||
| 	{ | 	{ | ||||||
| 		LOG_FATAL("SSL_CTX_check_private_key: Private key does not match the certificate public key: %s", ERR_error_string(ERR_get_error(), NULL)); | 		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; | ||||||
| @ -307,7 +158,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, int read) | static int handle_openssl_error(struct net_connection* con, int ret, enum ssl_state forced_rwstate) | ||||||
| { | { | ||||||
| 	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); | ||||||
| @ -318,47 +169,33 @@ static int handle_openssl_error(struct net_connection* con, int ret, int read) | |||||||
| 			return -1; | 			return -1; | ||||||
| 
 | 
 | ||||||
| 		case SSL_ERROR_WANT_READ: | 		case SSL_ERROR_WANT_READ: | ||||||
| 			if (read) | 			handle->state = forced_rwstate; | ||||||
| 				handle->ssl_read_events = NET_EVENT_READ; | 			net_con_update(con, 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: | ||||||
| 			if (read) | 			handle->state = forced_rwstate; | ||||||
| 				handle->ssl_read_events = NET_EVENT_WRITE; | 			net_con_update(con, 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); |  | ||||||
| 			net_stats_tls_add_error(); |  | ||||||
| 			return -2; |  | ||||||
| 
 |  | ||||||
| 		case SSL_ERROR_SYSCALL: | 		case SSL_ERROR_SYSCALL: | ||||||
| 			net_ssl_set_state(handle, tls_st_error); | 			handle->state = tls_st_error; | ||||||
| 			net_stats_tls_add_error(); |  | ||||||
| 			return -2; | 			return -2; | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	net_stats_tls_add_error(); |  | ||||||
| 	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); | ||||||
| 		net_ssl_set_state(handle, tls_st_connected); | 		handle->state = tls_st_connected; | ||||||
|                 net_stats_tls_add_accept(); |  | ||||||
| 		return ret; | 		return ret; | ||||||
| 	} | 	} | ||||||
| 	return handle_openssl_error(con, ret, tls_st_accepting); | 	return handle_openssl_error(con, ret, tls_st_accepting); | ||||||
| @ -368,37 +205,30 @@ 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; | ||||||
| 	net_ssl_set_state(handle, tls_st_connecting); | 	handle->state = 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); |  | ||||||
|                 net_stats_tls_add_connect(); |  | ||||||
| 		return ret; | 		return ret; | ||||||
| 	} | 	} | ||||||
| 	 | 	return handle_openssl_error(con, ret, tls_st_connecting); | ||||||
| 	ret = handle_openssl_error(con, ret, tls_st_connecting); |  | ||||||
| 	 |  | ||||||
|         if (ret != 0) |  | ||||||
|             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); | 		handle->ssl = SSL_new(ctx->ssl_ctx); | ||||||
| 		if (!handle->ssl) | 		if (!handle->ssl) | ||||||
| 		{ | 		{ | ||||||
| 			LOG_ERROR("Unable to create new SSL stream\n"); | 			LOG_ERROR("Unable to create new SSL stream\n"); | ||||||
| @ -411,37 +241,31 @@ ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode | |||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		handle->ssl = SSL_new(ctx->ssl); | 		handle->ssl = SSL_new(SSL_CTX_new(TLSv1_method())); | ||||||
| 		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); | ||||||
| 
 | 
 | ||||||
| 	LOG_TRACE("net_ssl_send(), state=%d", (int) handle->state); | 	uhub_assert(handle->state == tls_st_connected || handle->state == tls_st_need_write); | ||||||
| 
 |  | ||||||
| 	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; | 	{ | ||||||
| 	else | 		handle->state = tls_st_connected; | ||||||
| 		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) | ||||||
| @ -452,10 +276,7 @@ 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; | ||||||
| 
 | 
 | ||||||
| 	if (handle->state == tls_st_accepting || handle->state == tls_st_connecting) | 	uhub_assert(handle->state == tls_st_connected || handle->state == tls_st_need_read); | ||||||
| 		return -1; |  | ||||||
| 
 |  | ||||||
| 	uhub_assert(handle->state == tls_st_connected); |  | ||||||
| 
 | 
 | ||||||
| 	ERR_clear_error(); | 	ERR_clear_error(); | ||||||
| 
 | 
 | ||||||
| @ -463,43 +284,29 @@ 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; | 	{ | ||||||
| 	else | 		handle->state = tls_st_connected; | ||||||
| 		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) | ||||||
| 	{ | 	{ | ||||||
| @ -508,7 +315,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_ERROR, con->ptr); | 			con->callback(con, NET_EVENT_READ, con->ptr); | ||||||
| 			break; | 			break; | ||||||
| 
 | 
 | ||||||
| 		case tls_st_accepting: | 		case tls_st_accepting: | ||||||
| @ -517,27 +324,19 @@ void net_ssl_callback(struct net_connection* con, int events) | |||||||
| 			break; | 			break; | ||||||
| 
 | 
 | ||||||
| 		case tls_st_connecting: | 		case tls_st_connecting: | ||||||
| 			ret = net_con_ssl_connect(con); | 			if (net_con_ssl_connect(con) != 0) | ||||||
| 			if (ret == 0) |  | ||||||
| 				return; |  | ||||||
| 
 |  | ||||||
| 			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_read: | ||||||
| 				LOG_DEBUG("%p SSL handshake failed!", con); | 			con->callback(con, NET_EVENT_READ, con->ptr); | ||||||
| 				con->callback(con, NET_EVENT_ERROR, con->ptr); | 			break; | ||||||
| 			} | 
 | ||||||
|  | 		case tls_st_need_write: | ||||||
|  | 			con->callback(con, NET_EVENT_WRITE, 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; | ||||||
| 
 | 
 | ||||||
| @ -546,18 +345,6 @@ 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-2014, Jan Vidar Krey |  * Copyright (C) 2007-2010, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| /*
 | /*
 | ||||||
|  * uhub - A tiny ADC p2p connection hub |  * uhub - A tiny ADC p2p connection hub | ||||||
|  * Copyright (C) 2007-2014, Jan Vidar Krey |  * Copyright (C) 2007-2010, Jan Vidar Krey | ||||||
|  * |  * | ||||||
|  * This program is free software; you can redistribute it and/or modify |  * This program is free software; you can redistribute it and/or modify | ||||||
|  * it under the terms of the GNU General Public License as published by |  * it under the terms of the GNU General Public License as published by | ||||||
| @ -13,7 +13,7 @@ | |||||||
|  * GNU General Public License for more details. |  * GNU General Public License for more details. | ||||||
|  * |  * | ||||||
|  * You should have received a copy of the GNU General Public License |  * You should have received a copy of the GNU General Public License | ||||||
|  * along wtimeout_evtith this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along wtimeout_evtith this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| @ -42,7 +42,6 @@ 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*)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -53,56 +52,12 @@ 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])) | ||||||
| @ -112,7 +67,6 @@ size_t timeout_queue_process(struct timeout_queue* t, time_t now) | |||||||
| 			events++; | 			events++; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	timeout_queue_unlock(t); |  | ||||||
| 	return events; | 	return events; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -128,61 +82,6 @@ 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) | ||||||
| { | { | ||||||
| @ -191,12 +90,6 @@ 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) | ||||||
| @ -219,13 +112,6 @@ 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; | ||||||
| 
 | 
 | ||||||
|  | |||||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue
	
	Block a user