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 | ||||
| uhub | ||||
| build-stamp | ||||
| build.ninja | ||||
| debian/files | ||||
| debian/uhub.debhelper.log | ||||
| debian/uhub.postinst.debhelper | ||||
| @ -21,3 +22,5 @@ debian/uhub.postrm.debhelper | ||||
| debian/uhub.prerm.debhelper | ||||
| debian/uhub.substvars | ||||
| uhub-passwd | ||||
| src/version.h | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										2
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							| @ -1,3 +1,3 @@ | ||||
| [submodule "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 | ||||
| E_zombie, Centos/RedHat customization scripts and heavy load testing | ||||
| FleetCommand, Hub topic plugin code | ||||
| MiMic, Implemented user commands, and plugins | ||||
| MiMic, Implemented user commands | ||||
| Boris Pek (tehnick), Debian/Ubuntu packaging | ||||
| Tillmann Karras (Tilka), Misc. bug fixes | ||||
| 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 | ||||
| ## 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) | ||||
| @ -9,14 +9,14 @@ project (uhub NONE) | ||||
| enable_language(C) | ||||
| 
 | ||||
| set (UHUB_VERSION_MAJOR 0) | ||||
| set (UHUB_VERSION_MINOR 5) | ||||
| set (UHUB_VERSION_MINOR 4) | ||||
| set (UHUB_VERSION_PATCH 1) | ||||
| 
 | ||||
| set (PROJECT_SOURCE_DIR "${CMAKE_SOURCE_DIR}/src") | ||||
| set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake/Modules) | ||||
| 
 | ||||
| option(RELEASE "Release build, debug build if disabled" ON) | ||||
| option(LOWLEVEL_DEBUG, "Enable low level debug messages." OFF) | ||||
| option(LINK_SUPPORT "Allow hub linking" OFF) | ||||
| option(SSL_SUPPORT "Enable SSL support" ON) | ||||
| option(USE_OPENSSL "Use OpenSSL's SSL support" ON ) | ||||
| 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(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 (USE_OPENSSL) | ||||
| 		find_package(OpenSSL) | ||||
| @ -50,36 +32,26 @@ if (SSL_SUPPORT) | ||||
| 		find_package(GnuTLS) | ||||
| 	endif() | ||||
| 	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() | ||||
| 
 | ||||
| if (NOT SQLITE3_FOUND) | ||||
|     message(FATAL_ERROR "SQLite3 is not found!") | ||||
| if (LINK_SUPPORT) | ||||
| 	add_definitions(-DLINK_SUPPORT) | ||||
| endif() | ||||
| 
 | ||||
| if (SYSTEMD_SUPPORT) | ||||
|         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() | ||||
| 
 | ||||
| if (MSVC) | ||||
| 	add_definitions(-D_CRT_SECURE_NO_WARNINGS) | ||||
| 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_BINARY_DIR}") | ||||
| include_directories(${SQLITE3_INCLUDE_DIRS}) | ||||
| link_directories(${SQLITE3_LIBRARY_DIRS}) | ||||
| 
 | ||||
| file (GLOB uhub_SOURCES ${PROJECT_SOURCE_DIR}/core/*.c) | ||||
| list (REMOVE_ITEM uhub_SOURCES | ||||
| @ -99,7 +71,7 @@ set (adcclient_SOURCES | ||||
| add_library(adc       STATIC ${adc_SOURCES}) | ||||
| add_library(network   STATIC ${network_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(network PROPERTIES COMPILE_FLAGS -fPIC) | ||||
| endif() | ||||
| @ -108,7 +80,7 @@ add_dependencies(adc utils) | ||||
| add_dependencies(network utils) | ||||
| 
 | ||||
| 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_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_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_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_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_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( | ||||
| 	mod_example | ||||
| 	mod_welcome | ||||
| @ -129,7 +107,6 @@ set_target_properties( | ||||
| 	mod_auth_simple | ||||
| 	mod_auth_sqlite | ||||
| 	mod_chat_history | ||||
| 	mod_chat_history_sqlite | ||||
| 	mod_chat_only | ||||
| 	mod_no_guest_downloads | ||||
| 	mod_topic | ||||
| @ -137,32 +114,27 @@ set_target_properties( | ||||
| 
 | ||||
| target_link_libraries(uhub ${CMAKE_DL_LIBS} adc network utils) | ||||
| target_link_libraries(uhub-passwd ${SQLITE3_LIBRARIES} utils) | ||||
| target_link_libraries(autotest-bin ${CMAKE_DL_LIBS} adc network utils) | ||||
| target_link_libraries(test ${CMAKE_DL_LIBS} adc network 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_sqlite ${SQLITE3_LIBRARIES} utils) | ||||
| target_link_libraries(mod_chat_history utils) | ||||
| target_link_libraries(mod_chat_history_sqlite ${SQLITE3_LIBRARIES} utils) | ||||
| target_link_libraries(mod_no_guest_downloads utils) | ||||
| target_link_libraries(mod_chat_only utils) | ||||
| target_link_libraries(mod_logging network utils) | ||||
| target_link_libraries(mod_logging utils) | ||||
| target_link_libraries(mod_topic utils) | ||||
| target_link_libraries(utils network) | ||||
| target_link_libraries(mod_welcome network) | ||||
| target_link_libraries(mod_logging network) | ||||
| 
 | ||||
| if(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) | ||||
| 	add_library(adcclient STATIC ${adcclient_SOURCES}) | ||||
| 	add_executable(uhub-admin ${PROJECT_SOURCE_DIR}/tools/admin.c) | ||||
| 	target_link_libraries(uhub-admin adcclient adc network utils pthread) | ||||
| 	target_link_libraries(uhub pthread) | ||||
| 	target_link_libraries(autotest-bin pthread) | ||||
| 	target_link_libraries(test pthread) | ||||
| 
 | ||||
| 	if (ADC_STRESS) | ||||
| 		add_executable(adcrush ${PROJECT_SOURCE_DIR}/tools/adcrush.c ${adcclient_SOURCES}) | ||||
| @ -201,7 +173,7 @@ endif() | ||||
| 
 | ||||
| if(SSL_SUPPORT) | ||||
| 	target_link_libraries(uhub ${SSL_LIBS}) | ||||
| 	target_link_libraries(autotest-bin ${SSL_LIBS}) | ||||
| 	target_link_libraries(test ${SSL_LIBS}) | ||||
| 	if(UNIX) | ||||
| 		target_link_libraries(uhub-admin ${SSL_LIBS}) | ||||
| 	endif() | ||||
| @ -213,33 +185,31 @@ if(SSL_SUPPORT) | ||||
| endif() | ||||
| 
 | ||||
| if (SYSTEMD_SUPPORT) | ||||
|         target_link_libraries(uhub ${SD_LIBRARIES}) | ||||
|         target_link_libraries(autotest-bin ${SD_LIBRARIES}) | ||||
|         target_link_libraries(uhub-passwd ${SD_LIBRARIES}) | ||||
|         target_link_libraries(uhub-admin ${SD_LIBRARIES}) | ||||
|         include_directories(${SD_INCLUDE_DIRS}) | ||||
|         target_link_libraries(uhub ${SD_DAEMON_LIBRARIES}) | ||||
|         target_link_libraries(uhub ${SD_JOURNAL_LIBRARIES}) | ||||
|         target_link_libraries(test ${SD_DAEMON_LIBRARIES}) | ||||
|         target_link_libraries(test ${SD_JOURNAL_LIBRARIES}) | ||||
|         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) | ||||
| endif() | ||||
| 
 | ||||
| configure_file ("${PROJECT_SOURCE_DIR}/version.h.in" "${PROJECT_BINARY_DIR}/version.h") | ||||
| configure_file ("${PROJECT_SOURCE_DIR}/system.h.in" "${PROJECT_BINARY_DIR}/system.h") | ||||
| configure_file ("${PROJECT_SOURCE_DIR}/version.h.in" "${PROJECT_SOURCE_DIR}/version.h") | ||||
| 
 | ||||
| # mark_as_advanced(FORCE CMAKE_BUILD_TYPE) | ||||
| # if (RELEASE) | ||||
| #	set(CMAKE_BUILD_TYPE Release) | ||||
| #	add_definitions(-DNDEBUG) | ||||
| #else() | ||||
| #	set(CMAKE_BUILD_TYPE Debug) | ||||
| #	add_definitions(-DDEBUG) | ||||
| #endif() | ||||
| 
 | ||||
| if (LOWLEVEL_DEBUG) | ||||
| 	add_definitions(-DLOWLEVEL_DEBUG) | ||||
| mark_as_advanced(FORCE CMAKE_BUILD_TYPE) | ||||
| if (RELEASE) | ||||
| 	set(CMAKE_BUILD_TYPE Release) | ||||
| 	add_definitions(-DNDEBUG) | ||||
| else() | ||||
| 	set(CMAKE_BUILD_TYPE Debug) | ||||
| 	add_definitions(-DDEBUG) | ||||
| endif() | ||||
| 
 | ||||
| if (UNIX) | ||||
| 	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 ) | ||||
| 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: | ||||
| - Converted to CMake which replaces Visual Studio project files and GNU makefiles | ||||
| - Fix issues with SSL causing excessive CPU usage. | ||||
| @ -47,8 +27,8 @@ | ||||
| - marked plugin callbacks that are not called yet | ||||
| - add on_change_nick() to struct plugin_funcs | ||||
| - minimal changes | ||||
| - Updated init script in Debian package. | ||||
| - Updated list of man pages in Debian package. | ||||
| - Updated init script in debian package. | ||||
| - Updated list of man pages in debian package. | ||||
| - Added man page for uhub-passwd. | ||||
| - Merge branch 'master' of https://github.com/Tilka/uhub | ||||
| - Fix issue with QUI messages being allowed through the hub | ||||
| @ -78,7 +58,7 @@ | ||||
| - minimal documentation fixes | ||||
| - update client software link | ||||
| - update compile howto link | ||||
| - fix Debian changelog | ||||
| - fix debian changelog | ||||
| - Fix bug #158 - Added plugin for setting topic (hub description). | ||||
| - 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. | ||||
| 
 | ||||
| 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: | ||||
| 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 | ||||
|  on high-end servers, or a small private hub on embedded hardware. | ||||
|  . | ||||
| Homepage: https://www.uhub.org/ | ||||
| Homepage: http://www.extatic.org/uhub/ | ||||
| EOF | ||||
| 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_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_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_2, "list_destroy_2"); | ||||
| 	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_11, "utf8_valid_11"); | ||||
| 	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_1, "rbtree_create_1"); | ||||
| 	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_check_10000, "rbtree_check_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_destroy_1, "rbtree_destroy_1"); | ||||
| 	exotic_add_test(&handle, &exotic_test_rbtree_remove_5000, "rbtree_remove_5000"); | ||||
| 	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_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_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_shutdown, "timer_shutdown"); | ||||
| 	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_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) | ||||
| { | ||||
| 	struct exo_test_data* test; | ||||
| 
 | ||||
| 	if (!handle) | ||||
| 	{ | ||||
| 		fprintf(stderr, "exotic_add_test: failed, no handle!\n"); | ||||
|  | ||||
| @ -14,8 +14,10 @@ static void inf_create_hub() | ||||
| { | ||||
| 	net_initialize(); | ||||
| 	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->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() | ||||
| { | ||||
| 	uman_shutdown(inf_hub->users); | ||||
| 	/* FIXME */ | ||||
| 	list_destroy(inf_hub->users->list); | ||||
| 	sid_pool_destroy(inf_hub->users->sids); | ||||
| 	acl_shutdown(inf_hub->acl); | ||||
| 	free_config(inf_hub->config); | ||||
| 	hub_free(inf_hub->users); | ||||
| 	hub_free(inf_hub->acl); | ||||
| 	hub_free(inf_hub->config); | ||||
| 	hub_free(inf_hub); | ||||
|  | ||||
| @ -1,16 +1,10 @@ | ||||
| #include <uhub.h> | ||||
| 
 | ||||
| static struct linked_list* list = NULL; | ||||
| static struct linked_list* list2 = NULL; | ||||
| 
 | ||||
| static char A[2] = { 'A', 0 }; | ||||
| static char B[2] = { 'B', 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) | ||||
| { | ||||
| @ -130,83 +124,6 @@ EXO_TEST(list_clear, { | ||||
| 	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, { | ||||
| 	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_8[] = { 0xE2, 0x82, 0x32, 0x00}; // invalid | ||||
| static const char test_utf_seq_9[] = { 0xE2, 0x32, 0x82, 0x00}; // invalid | ||||
| static const char test_utf_seq_10[] = { 0xF0, 0x9F, 0x98, 0x81, 0x00}; // valid | ||||
| 
 | ||||
| EXO_TEST(utf8_valid_4, { return is_valid_utf8(test_utf_seq_1); }); | ||||
| EXO_TEST(utf8_valid_5, { return !is_valid_utf8(test_utf_seq_2); }); | ||||
| @ -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_11, { return !is_valid_utf8(test_utf_seq_8); }); | ||||
| EXO_TEST(utf8_valid_12, { return !is_valid_utf8(test_utf_seq_9); }); | ||||
| EXO_TEST(utf8_valid_13, { return is_valid_utf8(test_utf_seq_10); }); | ||||
| 
 | ||||
| // Limits of utf-8 | ||||
| static const char test_utf_seq_11[] = { 0x7F, 0x00 }; // valid last 7-bit character | ||||
| static const char test_utf_seq_12[] = { 0x80, 0x00 }; // invalid truncated string | ||||
| static const char test_utf_seq_13[] = { 0xBF, 0x00 }; // invalid truncated string | ||||
| static const char test_utf_seq_14[] = { 0xC0, 0x80, 0x00 }; // invalid out of 2 bytes range | ||||
| static const char test_utf_seq_15[] = { 0xC1, 0x7F, 0x00 }; // invalid out of 2 bytes range | ||||
| static const char test_utf_seq_16[] = { 0xC2, 0x00 }; // invalid truncated string | ||||
| static const char test_utf_seq_17[] = { 0xC2, 0x80, 0x00 }; // valid | ||||
| static const char test_utf_seq_18[] = { 0xDF, 0xBF, 0x00 }; // valid | ||||
| static const char test_utf_seq_19[] = { 0xE0, 0x80, 0x80, 0x00 }; // invalid out of 3 bytes range | ||||
| static const char test_utf_seq_20[] = { 0xE0, 0x9F, 0xBF, 0x00 }; // invalid out of 3 bytes range | ||||
| static const char test_utf_seq_21[] = { 0xE0, 0x00 }; // invalid truncated string | ||||
| static const char test_utf_seq_22[] = { 0xE0, 0xA0, 0x00 }; // invalid truncated string | ||||
| static const char test_utf_seq_23[] = { 0xE0, 0xA0, 0x80, 0x00 }; // valid | ||||
| static const char test_utf_seq_24[] = { 0xEC, 0x9F, 0xBF, 0x00 }; // valid | ||||
| static const char test_utf_seq_25[] = { 0xED, 0xA0, 0x80, 0x00 }; // invalid surrogate | ||||
| static const char test_utf_seq_26[] = { 0xED, 0xBF, 0xBF, 0x00 }; // invalid surrogate | ||||
| static const char test_utf_seq_27[] = { 0xEF, 0x80, 0x80, 0x00 }; // valid | ||||
| static const char test_utf_seq_28[] = { 0xEF, 0xBF, 0xBF, 0x00 }; // valid | ||||
| static const char test_utf_seq_29[] = { 0xF0, 0x80, 0x80, 0x80, 0x00 }; // invalid out of 4 bytes range | ||||
| static const char test_utf_seq_30[] = { 0xF0, 0x8F, 0xBF, 0xBF, 0x00 }; // invalid out of 4 bytes range | ||||
| static const char test_utf_seq_31[] = { 0xF0, 0x00 }; // invalid truncated string | ||||
| static const char test_utf_seq_32[] = { 0xF0, 0x90, 0x00 }; // invalid truncated string | ||||
| static const char test_utf_seq_33[] = { 0xF0, 0x90, 0x80, 0x00 }; // invalid truncated string | ||||
| static const char test_utf_seq_34[] = { 0xF0, 0x90, 0x80, 0x80, 0x00 }; // valid | ||||
| static const char test_utf_seq_35[] = { 0xF4, 0x8F, 0xBF, 0xBF, 0x00 }; // valid | ||||
| static const char test_utf_seq_36[] = { 0xF4, 0x90, 0x80, 0x80, 0x00 }; // invalid out of 4 bytes range | ||||
| static const char test_utf_seq_37[] = { 0xFF, 0xBF, 0xBF, 0xBF, 0x00 }; // invalid out of 4 bytes range | ||||
| 
 | ||||
| EXO_TEST(utf8_valid_14, { return is_valid_utf8(test_utf_seq_11); }); | ||||
| EXO_TEST(utf8_valid_15, { return !is_valid_utf8(test_utf_seq_12); }); | ||||
| EXO_TEST(utf8_valid_16, { return !is_valid_utf8(test_utf_seq_13); }); | ||||
| EXO_TEST(utf8_valid_17, { return !is_valid_utf8(test_utf_seq_14); }); | ||||
| EXO_TEST(utf8_valid_18, { return !is_valid_utf8(test_utf_seq_15); }); | ||||
| EXO_TEST(utf8_valid_19, { return !is_valid_utf8(test_utf_seq_16); }); | ||||
| EXO_TEST(utf8_valid_20, { return is_valid_utf8(test_utf_seq_17); }); | ||||
| EXO_TEST(utf8_valid_21, { return is_valid_utf8(test_utf_seq_18); }); | ||||
| EXO_TEST(utf8_valid_22, { return !is_valid_utf8(test_utf_seq_19); }); | ||||
| EXO_TEST(utf8_valid_23, { return !is_valid_utf8(test_utf_seq_20); }); | ||||
| EXO_TEST(utf8_valid_24, { return !is_valid_utf8(test_utf_seq_21); }); | ||||
| EXO_TEST(utf8_valid_25, { return !is_valid_utf8(test_utf_seq_22); }); | ||||
| EXO_TEST(utf8_valid_26, { return is_valid_utf8(test_utf_seq_23); }); | ||||
| EXO_TEST(utf8_valid_27, { return is_valid_utf8(test_utf_seq_24); }); | ||||
| EXO_TEST(utf8_valid_28, { return !is_valid_utf8(test_utf_seq_25); }); | ||||
| EXO_TEST(utf8_valid_29, { return !is_valid_utf8(test_utf_seq_26); }); | ||||
| EXO_TEST(utf8_valid_30, { return is_valid_utf8(test_utf_seq_27); }); | ||||
| EXO_TEST(utf8_valid_31, { return is_valid_utf8(test_utf_seq_28); }); | ||||
| EXO_TEST(utf8_valid_32, { return !is_valid_utf8(test_utf_seq_29); }); | ||||
| EXO_TEST(utf8_valid_33, { return !is_valid_utf8(test_utf_seq_30); }); | ||||
| EXO_TEST(utf8_valid_34, { return !is_valid_utf8(test_utf_seq_31); }); | ||||
| EXO_TEST(utf8_valid_35, { return !is_valid_utf8(test_utf_seq_32); }); | ||||
| EXO_TEST(utf8_valid_36, { return !is_valid_utf8(test_utf_seq_33); }); | ||||
| EXO_TEST(utf8_valid_37, { return is_valid_utf8(test_utf_seq_34); }); | ||||
| EXO_TEST(utf8_valid_38, { return is_valid_utf8(test_utf_seq_35); }); | ||||
| EXO_TEST(utf8_valid_39, { return !is_valid_utf8(test_utf_seq_36); }); | ||||
| EXO_TEST(utf8_valid_40, { return !is_valid_utf8(test_utf_seq_37); }); | ||||
|  | ||||
| @ -86,7 +86,7 @@ EXO_TEST(rbtree_size_3, { return rb_tree_size(tree) == 0; }); | ||||
| 
 | ||||
| EXO_TEST(rbtree_insert_10000, { | ||||
| 	int i; | ||||
| 	for (i = 0; i < MAX_NODES; i++) | ||||
| 	for (i = 0; i < MAX_NODES ; i++) | ||||
| 	{ | ||||
| 		const char* key = strdup(uhub_itoa(i)); | ||||
| 		const char* val = strdup(uhub_itoa(i + 16384)); | ||||
| @ -96,11 +96,11 @@ EXO_TEST(rbtree_insert_10000, { | ||||
| 	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, { | ||||
| 	int i; | ||||
| 	for (i = 0; i < MAX_NODES; i++) | ||||
| 	for (i = 0; i < MAX_NODES ; i++) | ||||
| 	{ | ||||
| 		char* key = strdup(uhub_itoa(i)); | ||||
| 		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); | ||||
| 	while (n) | ||||
| 	{ | ||||
| 		struct rb_node* p = n; | ||||
| 		n = (struct rb_node*) rb_tree_next(tree); | ||||
| 		i++; | ||||
| 	} | ||||
| 	return i == MAX_NODES; | ||||
| 	return i == MAX_NODES ; | ||||
| }); | ||||
| 
 | ||||
| static int freed_nodes = 0; | ||||
| 
 | ||||
| static void free_node(struct rb_node* n) | ||||
| { | ||||
| 	hub_free((void*) n->key); | ||||
| 	hub_free((void*) n->value); | ||||
| 	freed_nodes += 1; | ||||
| } | ||||
| 
 | ||||
| EXO_TEST(rbtree_remove_10000, { | ||||
| 	int i; | ||||
| 	int j; | ||||
| 	for (j = 0; j < 2; j++) | ||||
| 	{ | ||||
| 		for (i = j; i < MAX_NODES; i += 2) | ||||
| EXO_TEST(rbtree_remove_5000, { | ||||
| 	int i = 0; | ||||
| 	struct rb_node* n = (struct rb_node*) rb_tree_first(tree); | ||||
| 	for (i = 0; i < MAX_NODES ; i += 2) | ||||
| 	{ | ||||
| 		const char* key = uhub_itoa(i); | ||||
| 		rb_tree_remove_node(tree, key, &free_node); | ||||
| 	} | ||||
| 	} | ||||
| 	return freed_nodes == MAX_NODES; | ||||
| }); | ||||
| 
 | ||||
| EXO_TEST(rbtree_destroy_1, { | ||||
| 	rb_tree_destroy(tree); | ||||
| 	return 1; | ||||
| }); | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -117,9 +117,3 @@ EXO_TEST(timer_process_5_events_1,{ | ||||
| 	g_now = 4; | ||||
| 	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_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 | ||||
| # | ||||
| # Copyright (c) 2007 Juha Tuomala <tuju@iki.fi> | ||||
| @ -44,7 +44,6 @@ IF ( NOT SQLITE3_FOUND AND NOT PKG_CONFIG_FOUND ) | ||||
| 		/opt/local/lib | ||||
| 		/sw/lib | ||||
| 		/usr/lib | ||||
| 		/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE} | ||||
| 		/usr/local/lib | ||||
| 		/usr/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 | ||||
|   - 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. | ||||
| 
 | ||||
| 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 | ||||
| License can be found in `/usr/share/common-licenses/GPL'. | ||||
|  | ||||
| @ -67,7 +67,7 @@ Accepting new users | ||||
|  |            |                           | | ||||
|  |            V                           | | ||||
|  |  ---------------------         --------------------- | ||||
|  |  |   Send password   | ------> | Receive and check | | ||||
|  |  |   Send password   | ------> | Reveive and check | | ||||
|  |  | request, if needed|         | password.         | | ||||
|  |  ---------------------         --------------------- | ||||
|  |                                         | | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| 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 | ||||
| 
 | ||||
| @ -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") | ||||
|   * 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 | ||||
|  | ||||
| @ -28,10 +28,10 @@ The UDP packet SHOULD be echoed by the hub. | ||||
| This UDP packet should contain simply 'HECH {cid} {token}' (Hub echo). | ||||
| 
 | ||||
| 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 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, | ||||
| and resume in passive mode. | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,8 @@ | ||||
| Getting started guide | ||||
| --------------------- | ||||
| 
 | ||||
| (This document is maintained at http://www.extatic.org/uhub/getstarted.html ) | ||||
| 
 | ||||
| Unpack your binaries  | ||||
| 
 | ||||
| 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. | ||||
| 
 | ||||
| As root, or use sudo. | ||||
| 
 | ||||
|   % mkdir /etc/uhub | ||||
|   % cp doc/uhub.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. | ||||
| 
 | ||||
|   % ps aux | grep uhub | ||||
|   % kill -HUP <pid of uhub> | ||||
| 
 | ||||
| Or, for the lazy people | ||||
| 
 | ||||
|   % 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. | ||||
| @ -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. | ||||
| 
 | ||||
| Example: | ||||
| 
 | ||||
|   % 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. | ||||
| 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 | ||||
|       *     hard nofile 4096 | ||||
| 
 | ||||
| Or, you can use (as root): | ||||
| 
 | ||||
|   % 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! | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| #!/bin/sh | ||||
| # | ||||
| # 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. | ||||
| # | ||||
| # pidfile: /var/run/uhub.pid | ||||
|  | ||||
| @ -13,15 +13,6 @@ | ||||
| # | ||||
| 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 | ||||
| # | ||||
| @ -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" | ||||
| 
 | ||||
| # A simple example plugin | ||||
| #plugin /usr/lib/uhub/mod_example.so | ||||
| 
 | ||||
| # plugin /usr/lib/uhub/mod_example.so | ||||
| # A plugin sending a welcome message. | ||||
| # | ||||
| # This plugin provides the following commands: | ||||
| @ -41,7 +31,7 @@ plugin /usr/lib/uhub/mod_logging.so "file=/var/log/uhub.log" | ||||
| # | ||||
| # Parameters: | ||||
| # 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. | ||||
| # | ||||
| @ -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_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" | ||||
| 
 | ||||
|  | ||||
| @ -39,4 +39,4 @@ is one of 'admin', 'super', 'op', 'user' | ||||
| This program was written by Jan Vidar Krey <janvidar@extatic.org> | ||||
| .SH "BUG REPORTS" | ||||
| 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> | ||||
| .SH "BUG REPORTS" | ||||
| 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 | ||||
| # 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 | ||||
| # 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 | ||||
| # 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_user_share_size_low	       = User is not sharing enough | ||||
| msg_user_share_size_high       = User is sharing too much | ||||
| msg_user_slots_low	       = User has too few upload slots | ||||
| msg_user_slots_high	       = User has too many upload slots | ||||
| msg_user_slots_low	       = User have too few 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_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_connect         = Connect flood detected, connection refused. | ||||
| msg_user_flood_search          = Search flood detected, search is stopped. | ||||
|  | ||||
| @ -4,7 +4,7 @@ | ||||
| inherit eutils | ||||
| 
 | ||||
| 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" | ||||
| else | ||||
|         inherit git | ||||
| @ -16,7 +16,7 @@ fi | ||||
| EAPI="2" | ||||
| 
 | ||||
| DESCRIPTION="High performance ADC hub" | ||||
| HOMEPAGE="https://www.uhub.org/" | ||||
| HOMEPAGE="http://www.uhub.org/" | ||||
| 
 | ||||
| LICENSE="GPL-3" | ||||
| SLOT="0" | ||||
|  | ||||
| @ -5,7 +5,7 @@ Release: 2 | ||||
| License: GPLv3 | ||||
| Group: Networking/File transfer | ||||
| Source: uhub-%{version}.tar.gz | ||||
| URL: https://www.uhub.org | ||||
| URL: http://www.uhub.org | ||||
| BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root | ||||
| 
 | ||||
| BuildRequires: sqlite-devel | ||||
| @ -80,7 +80,7 @@ rm -rf $RPM_BUILD_ROOT | ||||
| if [ $1 -gt 1 ] ; then | ||||
|     /etc/rc.d/init.d/uhub restart >/dev/null || : | ||||
| 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 ||: | ||||
| # write SSL create  | ||||
| echo "PLS see /usr/share/doc/uhub/" | ||||
|  | ||||
| @ -8,7 +8,7 @@ start on filesystem or runlevel [2345] | ||||
| stop on runlevel [!2345] | ||||
| 
 | ||||
| # Allow the service to respawn, but if its happening too often | ||||
| # (10 times in 5 seconds) there's a problem and we should stop trying. | ||||
| # (10 times in 5 seconds) theres a problem and we should stop trying. | ||||
| respawn | ||||
| respawn limit 10 5 | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * 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 */ | ||||
| #define ADC_PROTO_SUPPORT "ADBASE ADTIGR ADPING ADUCMD" | ||||
| #define ADC_PROTO_LINK_SUPPORT "ADTIGR ADLINK" | ||||
| 
 | ||||
| /* Server sent commands */ | ||||
| #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_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_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_NICK               "NI" /* nick name */ | ||||
| #define ADC_INF_FLAG_DESCRIPTION        "DE" /* user description */ | ||||
| 
 | ||||
| #define ADC_INF_FLAG_USER_AGENT_PRODUCT "AP" /* software name */ | ||||
| #define ADC_INF_FLAG_USER_AGENT_VERSION "VE" /* software version */ | ||||
| 
 | ||||
| #define ADC_INF_FLAG_USER_AGENT         "VE" /* software version */ | ||||
| #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_FILES       "SF" /* number of files shared */ | ||||
| #define ADC_INF_FLAG_UPLOAD_SPEED       "US" /* maximum upload speed achieved in bytes/sec */ | ||||
| #define ADC_INF_FLAG_DOWNLOAD_SPEED     "DS" /* maximum download 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 acheived in bytes/sec */ | ||||
| #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_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_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_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 */ | ||||
| @ -159,7 +163,6 @@ typedef uint32_t fourcc_t; | ||||
| #define ADC_CLIENT_TYPE_BOT             "1" | ||||
| #define ADC_CLIENT_TYPE_REGISTERED_USER "2" | ||||
| #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_ADMIN           "20"  /* 16 + 4 = hub owner */ | ||||
| #define ADC_CLIENT_TYPE_HUB             "32"  /* the hub itself */ | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| @ -24,6 +24,7 @@ | ||||
| 	uhub_assert(X); \ | ||||
| 	uhub_assert(X->cache); \ | ||||
| 	uhub_assert(X->capacity); \ | ||||
| 	uhub_assert(X->length); \ | ||||
| 	uhub_assert(X->length <= X->capacity); \ | ||||
| 	uhub_assert(X->references > 0); \ | ||||
| 	uhub_assert(X->length == strlen(X->cache)); | ||||
| @ -177,6 +178,7 @@ int adc_msg_get_arg_offset(struct adc_message* msg) | ||||
| 		 | ||||
| 		case 'I': | ||||
| 		case 'H': | ||||
| 		case 'L': | ||||
| 			return 4; | ||||
| 			 | ||||
| 		case 'B': | ||||
| @ -282,19 +284,23 @@ struct adc_message* adc_msg_copy(const struct adc_message* cmd) | ||||
| 	if (cmd->feature_cast_include) | ||||
| 	{ | ||||
| 		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)); | ||||
| 		}); | ||||
| 			tmp = list_get_next(cmd->feature_cast_include); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (cmd->feature_cast_exclude) | ||||
| 	{ | ||||
| 		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)); | ||||
| 		}); | ||||
| 			tmp = list_get_next(cmd->feature_cast_exclude); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	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) | ||||
| 		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)); | ||||
| 		adc_msg_free(command); | ||||
| @ -378,8 +384,9 @@ struct adc_message* adc_msg_parse(const char* line, size_t length) | ||||
| 			ok = 0; | ||||
| 			break; | ||||
| 
 | ||||
| 		case 'I': | ||||
| 		case 'H': | ||||
| 		case 'I': /* Hub to client */ | ||||
| 		case 'H': /* Clien to hub */ | ||||
| 		case 'L': /* hub to hub Link */ | ||||
| 			ok = (length > 3); | ||||
| 			break; | ||||
| 
 | ||||
| @ -782,6 +789,16 @@ int adc_msg_add_argument(struct adc_message* cmd, const char* string) | ||||
| 	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) | ||||
| { | ||||
| @ -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; | ||||
| 	int n = 0; | ||||
| 	size_t add = 0; | ||||
| 	size_t n = 0; | ||||
| 	for (; str[n]; n++) | ||||
| 		if (str[n] == ' ' || str[n] == '\n' || str[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; | ||||
| 	int n = 0; | ||||
| 	int escape = 0; | ||||
| 	size_t add = 0; | ||||
| 	size_t n = 0; | ||||
| 	size_t escape = 0; | ||||
| 	for (; str[n]; n++) | ||||
| 	{ | ||||
| 		if (escape) | ||||
| @ -993,3 +1010,20 @@ char* adc_msg_escape(const char* string) | ||||
| 	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 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * 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) */ | ||||
| }; | ||||
| 
 | ||||
| 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. | ||||
|  * 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); | ||||
| 
 | ||||
| /**
 | ||||
|  * 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); | ||||
| 
 | ||||
| @ -159,7 +173,7 @@ extern char* adc_msg_get_argument(struct adc_message* cmd, int offset); | ||||
|  * | ||||
|  * @arg prefix a 2 character argument prefix | ||||
|  * @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); | ||||
| 
 | ||||
| @ -167,16 +181,23 @@ extern int adc_msg_replace_named_argument(struct adc_message* cmd, const char pr | ||||
|  * Append an argument | ||||
|  * | ||||
|  * @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); | ||||
| 
 | ||||
| /**
 | ||||
|  * 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 | ||||
|  * | ||||
|  * @arg prefix a 2 character argument prefix | ||||
|  * @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); | ||||
| 
 | ||||
| @ -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 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); | ||||
| 
 | ||||
| @ -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); | ||||
| 
 | ||||
| /**
 | ||||
|  * 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. | ||||
|  */ | ||||
| @ -234,4 +261,6 @@ void adc_msg_unterminate(struct adc_message* cmd); | ||||
|  */ | ||||
| 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 */ | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * 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); | ||||
| 
 | ||||
| 	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_super", handle->users, auth_cred_super); | ||||
| 	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) \ | ||||
| 		LIST_FOREACH(char*, str, LIST, \ | ||||
| 		str = (char*) list_get_first(LIST); \ | ||||
| 		while (str) \ | ||||
| 		{ \ | ||||
| 			if (strcasecmp(str, STR) == 0) \ | ||||
| 				return 1; \ | ||||
| 		}); \ | ||||
| 			str = (char*) list_get_next(LIST); \ | ||||
| 		} \ | ||||
| 		return 0 | ||||
| 
 | ||||
| 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) | ||||
| { | ||||
| 	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); | ||||
| 	LIST_FOREACH(struct ip_range*, info, handle->networks, | ||||
| 	 | ||||
| 	while (info) | ||||
| 	{ | ||||
| 		if (ip_in_range(&raw, info)) | ||||
| 		{ | ||||
| 			return 1; | ||||
| 	}); | ||||
| 		} | ||||
| 		info = (struct ip_range*) list_get_next(handle->networks); | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int acl_is_ip_nat_override(struct acl_handle* handle, const char* ip_address) | ||||
| { | ||||
| 	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); | ||||
| 	LIST_FOREACH(struct ip_range*, info, handle->nat_override, | ||||
| 	 | ||||
| 	while (info) | ||||
| 	{ | ||||
| 		if (ip_in_range(&raw, info)) | ||||
| 		{ | ||||
| 			return 1; | ||||
| 	}); | ||||
| 		} | ||||
| 		info = (struct ip_range*) list_get_next(handle->nat_override); | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * 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) | ||||
| 		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) | ||||
| 		{ | ||||
| @ -39,7 +39,7 @@ static void hub_command_args_free(struct hub_command* cmd) | ||||
| 			default: | ||||
| 				break; | ||||
| 		} | ||||
| 	}); | ||||
| 	} | ||||
| 
 | ||||
| 	list_clear(cmd->args, hub_free); | ||||
| 	list_destroy(cmd->args); | ||||
| @ -64,7 +64,6 @@ static enum command_parse_status command_extract_arguments(struct hub_info* hub, | ||||
| 	char* token = NULL; | ||||
| 	char* tmp = NULL; | ||||
| 	size_t size = 0; | ||||
| 	size_t offset = 0; | ||||
| 	struct hub_command_arg_data* data = NULL; | ||||
| 	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) | ||||
| 		{ | ||||
| 			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); | ||||
| 
 | ||||
| 			while ((tmp = list_get_first(tokens))) | ||||
| 			{ | ||||
| 				if (offset > 0) | ||||
| 					token[offset++] = ' '; | ||||
| 				memcpy(token + offset, tmp, strlen(tmp)); | ||||
| 				offset += strlen(tmp); | ||||
| 				if (*token) | ||||
| 					strcat(token, " "); | ||||
| 				strcat(token, tmp); | ||||
| 				list_remove(tokens, tmp); | ||||
| 				hub_free(tmp); | ||||
| 			} | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * 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 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. | ||||
|  */ | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * 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_missing_arguments(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd); | ||||
| 
 | ||||
| static void null_free(void* ptr) { } | ||||
| 
 | ||||
| struct command_base | ||||
| { | ||||
| 	struct hub_info* hub; | ||||
| @ -96,14 +98,14 @@ struct command_handle* command_handler_lookup(struct command_base* cbase, const | ||||
| 	struct command_handle* handler = NULL; | ||||
| 	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) | ||||
| 			continue; | ||||
| 
 | ||||
| 		if (!memcmp(prefix, handler->prefix, handler->length)) | ||||
| 			return handler; | ||||
| 	}); | ||||
| 	} | ||||
| 	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"); | ||||
| 
 | ||||
| 		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)) | ||||
| 			{ | ||||
| @ -299,7 +301,7 @@ static int command_help(struct command_base* cbase, struct hub_user* user, struc | ||||
| 					cbuf_append(buf, " "); | ||||
| 				cbuf_append_format(buf, " - %s\n", command->description); | ||||
| 			} | ||||
| 		}); | ||||
| 		} | ||||
| 	} | ||||
| 	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); | ||||
| 	if (!ret) | ||||
| 	{ | ||||
| 		list_clear(users, NULL); | ||||
| 		list_clear(users, &null_free); | ||||
| 		list_destroy(users); | ||||
| 		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)); | ||||
| 	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)); | ||||
| 	}); | ||||
| 		u = (struct hub_user*) list_get_next(users); | ||||
| 	} | ||||
| 	cbuf_append(buf, "\n"); | ||||
| 
 | ||||
| 	send_message(cbase, user, buf); | ||||
| 	list_clear(users, NULL); | ||||
| 	list_clear(users, &null_free); | ||||
| 	list_destroy(users); | ||||
| 	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(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) | ||||
| 		{ | ||||
| @ -475,7 +480,8 @@ static int command_broadcast(struct command_base* cbase, struct hub_user* user, | ||||
| 			route_to_user(cbase->hub, target, 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" : "")); | ||||
| 	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); | ||||
| 
 | ||||
| 	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); | ||||
| 		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); | ||||
| 			buf = cbuf_create(MAX_HELP_LINE); | ||||
| 		} | ||||
| 	}); | ||||
| 		log = (struct hub_logout_info*) list_get_next(messages); | ||||
| 	} | ||||
| 
 | ||||
| 	if (search_len) | ||||
| 	{ | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * 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_off_quotes(data); | ||||
| 
 | ||||
| 	if (!*key || !*data) | ||||
| 	if (!*key /*|| !*data*/) | ||||
| 	{ | ||||
| 		LOG_FATAL("Configuration parse error on line %d", line_count); | ||||
| 		return -1; | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * 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 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> | ||||
| 		<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 /> | ||||
| @ -58,7 +58,7 @@ | ||||
| 	</option> | ||||
| 
 | ||||
| 	<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> | ||||
| 		<description><![CDATA[ | ||||
| 		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"> | ||||
| 	   <short>Allow users to register themselves on the hub.</short> | ||||
| 		<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. | ||||
| 		]]></description> | ||||
| 		<since>0.4.0</since> | ||||
| @ -157,7 +157,7 @@ | ||||
| 	</option> | ||||
| 
 | ||||
| 	<option name="redirect_addr" type="string" default=""> | ||||
| 		<check regexp="(adcs?|dchub)://.*" /> | ||||
| 		<check regexp="(adc|adcs|dchub)://.*" /> | ||||
| 		<short>A common hub redirect address.</short> | ||||
| 		<description><![CDATA[ | ||||
| 		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> | ||||
| 	</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" > | ||||
| 		<check min="1024" max="1048576" /> | ||||
| 		<short>Max read buffer before parse, per user</short> | ||||
| 		<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> | ||||
| 		<since>0.1.3</since> | ||||
| 	</option> | ||||
| @ -419,7 +449,7 @@ | ||||
| 	</option> | ||||
| 
 | ||||
| 	<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> | ||||
| 		<description><![CDATA[ | ||||
| 		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> | ||||
| 	</option> | ||||
| 
 | ||||
| 
 | ||||
| 	<option name="tls_certificate" type="file" default=""> | ||||
| 		<short>Certificate file</short> | ||||
| 		<description><![CDATA[ | ||||
| 			Path to a TLS/SSL certificate or certificate chain (PEM format). | ||||
| 			Path to a TLS/SSL certificate (PEM format). | ||||
| 		]]></description> | ||||
| 		<since>0.3.0</since> | ||||
| 	</option> | ||||
| @ -444,40 +475,6 @@ | ||||
| 		<since>0.3.0</since> | ||||
| 	</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=""> | ||||
| 		<short>File containing access control lists</short> | ||||
| 		<description><![CDATA[ | ||||
| @ -567,7 +564,7 @@ | ||||
| 	</option> | ||||
| 
 | ||||
| 	<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> | ||||
| 	</option> | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * 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. */ | ||||
| 	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 | ||||
| 		eq_debug("EXEC", data); | ||||
| #endif | ||||
| 		queue->callback(queue->callback_data, data); | ||||
| 	}); | ||||
| 		data = (struct event_data*) list_get_next(queue->q1); | ||||
| 	} | ||||
| 	 | ||||
| 	list_clear(queue->q1, event_queue_cleanup_callback); | ||||
| 	uhub_assert(list_size(queue->q1) == 0); | ||||
| @ -92,7 +94,13 @@ int event_queue_process(struct event_queue* queue) | ||||
| 	queue->locked = 0; | ||||
| 	 | ||||
| 	/* 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 (list_size(queue->q1)) | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
|  | ||||
| @ -1,10 +1,4 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  */ | ||||
| /* THIS FILE IS AUTOGENERATED - DO NOT CHANGE IT! */ | ||||
| 
 | ||||
| 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_description = hub_strdup("no description"); | ||||
| 	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_send_buffer = 131072; | ||||
| 	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_certificate = 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_plugins = hub_strdup(""); | ||||
| 	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; | ||||
| 	} | ||||
| 
 | ||||
| #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")) | ||||
| 	{ | ||||
| 		min = 1024; | ||||
| @ -554,26 +591,6 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li | ||||
| 		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 (!apply_string(key, data, &config->file_acl, (char*) "")) | ||||
| @ -971,16 +988,20 @@ void free_config(struct hub_config* config) | ||||
| 
 | ||||
| 	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_certificate); | ||||
| 
 | ||||
| 	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_plugins); | ||||
| @ -1106,6 +1127,21 @@ void dump_config(struct hub_config* config, int ignore_defaults) | ||||
| 	if (!ignore_defaults || strcmp(config->redirect_addr, "") != 0) | ||||
| 		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) | ||||
| 		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) | ||||
| 		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) | ||||
| 		fprintf(stdout, "file_acl = \"%s\"\n", config->file_acl); | ||||
| 
 | ||||
|  | ||||
| @ -1,10 +1,4 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  */ | ||||
| /* THIS FILE IS AUTOGENERATED - DO NOT CHANGE IT! */ | ||||
| 
 | ||||
| struct hub_config | ||||
| { | ||||
| @ -23,6 +17,15 @@ struct hub_config | ||||
| 	char* hub_name;                        /*<<< Name of hub (default: "uhub") */ | ||||
| 	char* hub_description;                 /*<<< Short hub description, topic or subject. (default: "no description") */ | ||||
| 	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_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) */ | ||||
| @ -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_certificate;                 /*<<< Certificate 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_plugins;                    /*<<< Plugin configuration file (default: "") */ | ||||
| 	char* msg_hub_full;                    /*<<< "Hub is full" */ | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * 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! */ | ||||
| #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) \ | ||||
| 		{ \ | ||||
| @ -731,11 +731,7 @@ static int load_ssl_certificates(struct hub_info* hub, struct hub_config* config | ||||
| { | ||||
| 	if (config->tls_enable) | ||||
| 	{ | ||||
| 		hub->ctx = net_ssl_context_create(config->tls_version, config->tls_ciphersuite); | ||||
| 
 | ||||
| 		if (!hub->ctx) | ||||
| 		  return 0; | ||||
| 
 | ||||
| 		hub->ctx = net_ssl_context_create(); | ||||
| 		if (ssl_load_certificate(hub->ctx, config->tls_certificate) && | ||||
| 			ssl_load_private_key(hub->ctx, config->tls_private_key) && | ||||
| 			ssl_check_private_key(hub->ctx)) | ||||
| @ -791,6 +787,13 @@ struct hub_info* hub_start_service(struct hub_config* config) | ||||
| 	} | ||||
| #endif | ||||
| 
 | ||||
| #ifdef LINK_SUPPORT | ||||
| 	if (config->hub_link_enabled) | ||||
| 	{ | ||||
| 		LOG_INFO("Hub linking support enabled"); | ||||
| 	} | ||||
| #endif | ||||
| 
 | ||||
| 	hub->config = config; | ||||
| 	hub->users = NULL; | ||||
| 
 | ||||
| @ -838,6 +841,15 @@ struct hub_info* hub_start_service(struct hub_config* config) | ||||
| 
 | ||||
| 	// Start the hub command sub-system
 | ||||
| 	hub->commands = command_initialize(hub); | ||||
| 
 | ||||
| #ifdef LINK_SUPPORT | ||||
| 	if (*config->hub_link_connect) | ||||
| 	{ | ||||
| 		link_connect_uri(hub, config->hub_link_connect); | ||||
| 	} | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| 	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) | ||||
| { | ||||
| 	char* tmp; | ||||
| 	char* server = adc_msg_escape(PRODUCT_STRING); /* FIXME: OOM */ | ||||
| 
 | ||||
| 	hub->acl = acl; | ||||
| 	hub->command_info = adc_msg_construct(ADC_CMD_IINF, 15); | ||||
| 	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_USER_AGENT_PRODUCT, PRODUCT); | ||||
| 		adc_msg_add_named_argument(hub->command_info, ADC_INF_FLAG_USER_AGENT_VERSION, GIT_VERSION); | ||||
| 
 | ||||
| 		tmp = adc_msg_escape(hub->config->hub_name); | ||||
| 		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); | ||||
| 		adc_msg_add_named_argument_string(hub->command_info, ADC_INF_FLAG_USER_AGENT, PRODUCT_STRING); | ||||
| 		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); | ||||
| 	} | ||||
| 
 | ||||
| 	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); | ||||
| 	} | ||||
| 
 | ||||
| 	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->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, tmp); | ||||
| 		hub_free(tmp); | ||||
| 		if (hub->config->show_banner_sys_info) | ||||
| 			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) | ||||
| @ -947,7 +947,6 @@ void hub_set_variables(struct hub_info* hub, struct acl_handle* acl) | ||||
| 	else | ||||
| 
 | ||||
| 	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); | ||||
| 	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 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * 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_inf_error_nick_missing    = -4,  /* no nickname 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_short      = -8,  /* nickname too short */ | ||||
| 	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_slots_low            = -42, /* User has too few 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_high       = -45, /* User is on too many hubs. */ | ||||
| 	status_msg_user_hub_limit_low        = -44, /* Use is on too few 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_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 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 | ||||
| 	struct ssl_context_handle* ctx; | ||||
| #endif /*  SSL_SUPPORT */ | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * 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) | ||||
| { | ||||
| @ -337,19 +337,9 @@ static int check_logged_in(struct hub_info* hub, struct hub_user* user, struct a | ||||
| 	{ | ||||
| 		if (lookup1 == lookup2) | ||||
| 		{ | ||||
| 			if (user_flag_get(lookup1, flag_choke)) | ||||
| 			{ | ||||
| 				LOG_DEBUG("check_logged_in: exact same user is already logged in, but likely ghost: %s", user->id.nick); | ||||
| 
 | ||||
| 				// Old user unable to swallow data.
 | ||||
| 				// Disconnect the existing user, and allow new user to enter.
 | ||||
| 			LOG_DEBUG("check_logged_in: exact same user is logged in: %s", user->id.nick); | ||||
| 			hub_disconnect_user(hub, lookup1, quit_ghost_timeout); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				LOG_DEBUG("check_logged_in: exact same user is already logged in: %s", user->id.nick); | ||||
| 				return status_msg_inf_error_cid_taken; | ||||
| 			} | ||||
| 			return 0; | ||||
| 		} | ||||
| 		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) | ||||
| { | ||||
| 	char* ua_name_encoded = 0; | ||||
| 	char* ua_version_encoded = 0; | ||||
| 	char* str = 0; | ||||
| 	size_t offset = 0; | ||||
| 	char* ua_encoded = 0; | ||||
| 	char* ua = 0; | ||||
| 	 | ||||
| 	/* Get client user agent version */ | ||||
| 	ua_name_encoded = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_USER_AGENT_PRODUCT); | ||||
| 	ua_version_encoded = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_USER_AGENT_VERSION); | ||||
| 	if (ua_name_encoded) | ||||
| 	ua_encoded = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_USER_AGENT); | ||||
| 	if (ua_encoded) | ||||
| 	{ | ||||
| 		str = adc_msg_unescape(ua_name_encoded); | ||||
| 		if (str) | ||||
| 		ua = adc_msg_unescape(ua_encoded); | ||||
| 		if (ua) | ||||
| 		{ | ||||
| 			offset = strlen(str); | ||||
| 			memcpy(user->id.user_agent, str, MIN(offset, MAX_UA_LEN)); | ||||
| 			hub_free(str); | ||||
| 			memcpy(user->id.user_agent, ua, MIN(strlen(ua), MAX_UA_LEN)); | ||||
| 			hub_free(ua); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	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); | ||||
| 	hub_free(ua_encoded); | ||||
| 	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); | ||||
| 			break; | ||||
| 			 | ||||
| 		case auth_cred_ubot: | ||||
| 			adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_BOT); | ||||
| 			break; | ||||
| 
 | ||||
| 		case auth_cred_guest: | ||||
| 			/* Nothing to be added to the info message */ | ||||
| 			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); | ||||
| 			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: | ||||
| 			adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_SUPER_USER); | ||||
| 			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) | ||||
| 	{ | ||||
| 		adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_USER_AGENT_VERSION); | ||||
| 		adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_USER_AGENT_PRODUCT); | ||||
| 		adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_USER_AGENT); | ||||
| 		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_REGISTER); | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * 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) | ||||
| { | ||||
| 	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* 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; | ||||
| } | ||||
| 
 | ||||
| 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 | ||||
| 	debug_msg("ioq_send_remove", msg); | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| @ -39,6 +39,7 @@ struct ioq_recv | ||||
| { | ||||
| 	char* buf; | ||||
| 	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); | ||||
| 
 | ||||
| 
 | ||||
| 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 */ | ||||
|  | ||||
							
								
								
									
										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 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * 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); | ||||
| 		} | ||||
| 
 | ||||
| #ifdef DEBUG | ||||
| 		LOG_INFO("Debug messages enabled"); | ||||
| #endif | ||||
| 	 | ||||
| 		if (read_config(arg_config, &configuration, !arg_have_config) == -1) | ||||
| 			return -1; | ||||
| 
 | ||||
| @ -151,7 +155,7 @@ int main_loop() | ||||
| 			setup_signal_handlers(hub); | ||||
| #ifdef SYSTEMD | ||||
|                         /* Notify the service manager that this daemon has 
 | ||||
|                          * been successfully initialized and shall enter the | ||||
|                          * been successfully initalized and shall enter the | ||||
|                          * main loop. | ||||
|                          */ | ||||
|                         sd_notifyf(0, "READY=1\n" | ||||
| @ -471,7 +475,7 @@ int main(int argc, char** argv) | ||||
| 		} | ||||
| 		else if (ret == 0) | ||||
| 		{ | ||||
| 			/* child process - detach from TTY */ | ||||
| 			/* child process - detatch from TTY */ | ||||
| 			fclose(stdin); | ||||
| 			fclose(stdout); | ||||
| 			fclose(stderr); | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * 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); | ||||
| #endif | ||||
| 
 | ||||
| 	if (event == NET_EVENT_ERROR) | ||||
| 	{ | ||||
| 		hub_disconnect_user(user->hub, user, quit_socket_error); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (event == NET_EVENT_TIMEOUT) | ||||
| 	{ | ||||
| 		if (user_is_connecting(user)) | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * 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); | ||||
| 
 | ||||
| 	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) | ||||
| 			return cmdh->handler(plugin, puser, pcommand); | ||||
| 	}); | ||||
| 
 | ||||
| 		cmdh = (struct plugin_command_handle*) list_get_next(data->commands); | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| @ -65,17 +68,6 @@ static int cbfunc_send_message(struct plugin_handle* plugin, struct plugin_user* | ||||
| 	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) | ||||
| { | ||||
| 	char code_str[4]; | ||||
| @ -112,6 +104,7 @@ static int cbfunc_command_add(struct plugin_handle* plugin, struct plugin_comman | ||||
| 	cmdh->internal_handle = command; | ||||
| 	list_append(data->commands, cmdh); | ||||
| 	command_add(plugin_get_hub(plugin)->commands, command, (void*) plugin); | ||||
| 	printf("*** Add plugin command: %s (%p, %p)\n", command->prefix, command, cmdh); | ||||
| 	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 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); | ||||
| 	command_del(plugin_get_hub(plugin)->commands, 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); | ||||
| } | ||||
| 
 | ||||
| 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) | ||||
| { | ||||
| 	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) | ||||
| { | ||||
| 	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.user_disconnect = cbfunc_user_disconnect; | ||||
| 	handle->hub.command_add = cbfunc_command_add; | ||||
| 	handle->hub.command_del = cbfunc_command_del; | ||||
| 	handle->hub.command_arg_reset = cbfunc_command_arg_reset; | ||||
| 	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.set_name = cbfunc_set_hub_name; | ||||
| 	handle->hub.get_description = cbfunc_get_hub_description; | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| @ -27,12 +27,13 @@ | ||||
| 	PLUGIN_DEBUG(HUB, # FUNCNAME) \ | ||||
| 	if (HUB->plugins && HUB->plugins->loaded) \ | ||||
| 	{ \ | ||||
| 		struct plugin_handle* plugin;\ | ||||
| 		LIST_FOREACH(struct plugin_handle*, plugin, HUB->plugins->loaded, \ | ||||
| 		struct plugin_handle* plugin = (struct plugin_handle*) list_get_first(HUB->plugins->loaded); \ | ||||
| 		while (plugin) \ | ||||
| 		{ \ | ||||
| 			if (plugin->funcs.FUNCNAME) \ | ||||
| 				CODE \ | ||||
| 		}); \ | ||||
| 			plugin = (struct plugin_handle*) list_get_next(HUB->plugins->loaded); \ | ||||
| 		} \ | ||||
| 	} | ||||
| 
 | ||||
| #define PLUGIN_INVOKE_STATUS_1(HUB, FUNCNAME, ARG1) \ | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * 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; | ||||
| 	struct plugin_handle* handle = (struct plugin_handle*) hub_malloc_zero(sizeof(struct plugin_handle)); | ||||
| 	struct uhub_plugin* plugin = plugin_open(filename); | ||||
| 	struct plugin_hub_internals* internals = (struct plugin_hub_internals*) plugin->internals; | ||||
| 
 | ||||
| 	if (!plugin) | ||||
| 		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"); | ||||
| 
 | ||||
| 	// register hub internals
 | ||||
| 	struct plugin_hub_internals* internals = (struct plugin_hub_internals*) plugin->internals; | ||||
| 	internals->unregister = unregister_f; | ||||
| 	internals->hub = hub; | ||||
| 	internals->callback_data = plugin_callback_data_create(); | ||||
| @ -229,16 +229,16 @@ int plugin_initialize(struct hub_config* config, struct hub_info* hub) | ||||
| 	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) | ||||
| { | ||||
| 	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); | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * 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); | ||||
| 				return; | ||||
| 			} | ||||
| 			else if ((memcmp(probe_recvbuf, "GET ", 4) == 0) || | ||||
| 				 (memcmp(probe_recvbuf, "POST", 4) == 0) || | ||||
| 				 (memcmp(probe_recvbuf, "HEAD", 4) == 0)) | ||||
| #ifdef LINK_SUPPORT | ||||
| 			else if (probe->hub->config->hub_link_enabled && memcmp(probe_recvbuf, "LSUP", 4) == 0) | ||||
| 			{ | ||||
| 				/* Looks like HTTP - Not supported, but we log it. */ | ||||
| 				LOG_TRACE("Probed HTTP connection. Not supported closing connection (%s)", ip_convert_to_string(&probe->addr)); | ||||
| 				const char* buf = "501 Not implemented\r\n\r\n"; | ||||
| 				net_con_send(con, buf, strlen(buf)); | ||||
| 				if (link_create(probe->hub, probe->connection, &probe->addr)) | ||||
| 				{ | ||||
| 					probe->connection = 0; | ||||
| 				} | ||||
| 				probe_destroy(probe); | ||||
| 				return; | ||||
| 			} | ||||
| #endif /* LINK_SUPPORT */ | ||||
| #ifdef SSL_SUPPORT | ||||
| 			else if (bytes >= 11 && | ||||
| 				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) | ||||
| 				{ | ||||
| 					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) | ||||
| 					{ | ||||
| 						LOG_TRACE("TLS handshake negotiation failed."); | ||||
| 					} | ||||
| 					else if (user_create(probe->hub, probe->connection, &probe->addr)) | ||||
| 					if (user_create(probe->hub, probe->connection, &probe->addr)) | ||||
| 					{ | ||||
| 						probe->connection = 0; | ||||
| 					} | ||||
| 					net_con_ssl_handshake(con, net_con_ssl_mode_server, probe->hub->ctx); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * 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)) | ||||
| 	{ | ||||
| 		user_flag_set(user, flag_choke); | ||||
| 		LOG_WARN("send queue overflowed, message discarded."); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	if (user->send_queue->size > get_max_send_queue_soft(hub)) | ||||
| 	{ | ||||
| 		user_flag_set(user, flag_choke); | ||||
| 		LOG_WARN("send queue soft overflowed."); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	user_flag_unset(user, flag_choke); | ||||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
| @ -102,7 +99,7 @@ int route_to_user(struct hub_info* hub, struct hub_user* user, struct adc_messag | ||||
| { | ||||
| #ifdef DEBUG_SENDQ | ||||
| 	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); | ||||
| #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 */ | ||||
| { | ||||
| 	struct hub_user* user; | ||||
| 	LIST_FOREACH(struct hub_user*, user, hub->users->list, | ||||
| 	struct hub_user* user = (struct hub_user*) list_get_first(hub->users->list); | ||||
| 	while (user) | ||||
| 	{ | ||||
| 		route_to_user(hub, user, command); | ||||
| 	}); | ||||
| 		user = (struct hub_user*) list_get_next(hub->users->list); | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| @ -156,38 +154,47 @@ int route_to_subscribers(struct hub_info* hub, struct adc_message* command) /* i | ||||
| 	int do_send; | ||||
| 	char* tmp; | ||||
| 	 | ||||
| 	struct hub_user* user; | ||||
| 	LIST_FOREACH(struct hub_user*, user, hub->users->list, | ||||
| 	struct hub_user* user = (struct hub_user*) list_get_first(hub->users->list); | ||||
| 	while (user) | ||||
| 	{ | ||||
| 		if (user->feature_cast) | ||||
| 		{ | ||||
| 			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)) | ||||
| 				{ | ||||
| 					do_send = 0; | ||||
| 					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; | ||||
| 			} | ||||
| 			 | ||||
| 			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)) | ||||
| 				{ | ||||
| 					do_send = 0; | ||||
| 					break; | ||||
| 				} | ||||
| 			}); | ||||
| 				tmp = list_get_next(command->feature_cast_exclude); | ||||
| 			} | ||||
| 			 | ||||
| 			if (do_send) | ||||
| 			{ | ||||
| 				route_to_user(hub, user, command); | ||||
| 			} | ||||
| 	}); | ||||
| 		} | ||||
| 		user = (struct hub_user*) list_get_next(hub->users->list); | ||||
| 	} | ||||
| 	 | ||||
| 	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_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)) | ||||
| 				route_to_user(hub, user, cmd); | ||||
| 			else | ||||
| 				route_to_user(hub, user, u->info); | ||||
| 		}); | ||||
| 			 | ||||
| 			user = (struct hub_user*) list_get_next(hub->users->list); | ||||
| 		} | ||||
| 		adc_msg_free(cmd); | ||||
| 	} | ||||
| 	return 0; | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * 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]) | ||||
| { | ||||
| 	char* tmp; | ||||
| 	LIST_FOREACH(char*, tmp, user->feature_cast, | ||||
| 	char* tmp = list_get_first(user->feature_cast); | ||||
| 	while (tmp) | ||||
| 	{ | ||||
| 		if (strncmp(tmp, feature, 4) == 0) | ||||
| 			return 1; | ||||
| 	}); | ||||
| 	 | ||||
| 		tmp = list_get_next(user->feature_cast); | ||||
| 	} | ||||
| 	 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * 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_send_queue     = 5,     /** User's send queue was overflowed */ | ||||
| 	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_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. */ | ||||
| @ -76,7 +76,7 @@ enum user_quit_reason | ||||
| 	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); | ||||
| 
 | ||||
| struct hub_user_info | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * 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() | ||||
| { | ||||
| @ -51,10 +46,15 @@ struct hub_user_manager* uman_init() | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	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()); | ||||
| 
 | ||||
| 	if (!users->list) | ||||
| 	{ | ||||
| 		list_destroy(users->list); | ||||
| 		hub_free(users); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	return users; | ||||
| } | ||||
| 
 | ||||
| @ -64,18 +64,11 @@ int uman_shutdown(struct hub_user_manager* users) | ||||
| 	if (!users) | ||||
| 		return -1; | ||||
| 
 | ||||
| 	if (users->nickmap) | ||||
| 		rb_tree_destroy(users->nickmap); | ||||
| 
 | ||||
| 	if (users->cidmap) | ||||
| 		rb_tree_destroy(users->cidmap); | ||||
| 
 | ||||
| 	if (users->list) | ||||
| 	{ | ||||
| 		list_clear(users->list, &clear_user_list_callback); | ||||
| 		list_destroy(users->list); | ||||
| 	} | ||||
| 
 | ||||
| 	sid_pool_destroy(users->sids); | ||||
| 
 | ||||
| 	hub_free(users); | ||||
| @ -88,9 +81,6 @@ int uman_add(struct hub_user_manager* users, struct hub_user* user) | ||||
| 	if (!users || !user) | ||||
| 		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); | ||||
| 	users->count++; | ||||
| 	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; | ||||
| 
 | ||||
| 	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) | ||||
| 	{ | ||||
| @ -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* 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; | ||||
| 		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* 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; | ||||
| 		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 num = 0; | ||||
| 	struct hub_user* user; | ||||
| 	LIST_FOREACH(struct hub_user*, user, users->list, | ||||
| 	struct hub_user* user = (struct hub_user*) list_get_first(users->list); /* iterate users - only on incoming INF msg */ | ||||
| 	while (user) | ||||
| 	{ | ||||
| 		if (ip_in_range(&user->id.addr, range)) | ||||
| 		{ | ||||
| 			list_append(target, user); | ||||
| 			num++; | ||||
| 		} | ||||
| 	}); | ||||
| 		user = (struct hub_user*) list_get_next(users->list); | ||||
| 	} | ||||
| 	return num; | ||||
| } | ||||
| 
 | ||||
| @ -163,8 +164,8 @@ int uman_send_user_list(struct hub_info* hub, struct hub_user_manager* users, st | ||||
| 	int ret = 1; | ||||
| 	struct hub_user* user; | ||||
| 	user_flag_set(target, flag_user_list); | ||||
| 
 | ||||
| 	LIST_FOREACH(struct hub_user*, user, users->list, | ||||
| 	user = (struct hub_user*) list_get_first(users->list); /* iterate users - only on INF or PAS msg */ | ||||
| 	while (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) | ||||
| 				break; | ||||
| 		} | ||||
| 	}); | ||||
| 		user = (struct hub_user*) list_get_next(users->list); | ||||
| 	} | ||||
| 
 | ||||
| #if 0 | ||||
| 	FIXME: FIXME FIXME handle send queue excess | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * 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_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_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 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. | ||||
|  * 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); | ||||
| 
 | ||||
| @ -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 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); | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * 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); | ||||
| } | ||||
| @ -141,7 +148,7 @@ int net_backend_process() | ||||
| 	} | ||||
| 
 | ||||
| 	// Process pending DNS results
 | ||||
| 	// net_dns_process();
 | ||||
| 	net_dns_process(); | ||||
| 
 | ||||
| 	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); | ||||
| 
 | ||||
| 	net_set_nonblocking(net_con_get_sd(con), 1); | ||||
| 	net_set_nosigpipe(net_con_get_sd(con), 1); | ||||
| 	net_set_nonblocking(con->sd, 1); | ||||
| 	net_set_nosigpipe(con->sd, 1); | ||||
| 
 | ||||
| 	g_backend->handler.con_add(g_backend->data, con, events); | ||||
| 	g_backend->common.num++; | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * 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(); | ||||
| 
 | ||||
| /**
 | ||||
|  * 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. | ||||
|  */ | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,13 +13,12 @@ | ||||
|  * 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/>.
 | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| #include "uhub.h" | ||||
| #include "network/common.h" | ||||
| #include "network/backend.h" | ||||
| 
 | ||||
| static int is_blocked_or_interrupted() | ||||
| { | ||||
| @ -117,27 +116,10 @@ void* net_con_get_ptr(struct net_connection* con) | ||||
| 	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) | ||||
| { | ||||
| #ifdef SSL_SUPPORT | ||||
| 	if (con && con->ssl) | ||||
| 	if (con->ssl) | ||||
| 		net_ssl_destroy(con); | ||||
| #endif | ||||
| 	hub_free(con); | ||||
| @ -196,12 +178,11 @@ static int net_connect_job_check(struct net_connect_job* job) | ||||
| 	int af = job->addr.ss_family; | ||||
| 	enum net_connect_status status; | ||||
| 
 | ||||
| 	int ret = net_connect(net_con_get_sd(con), (struct sockaddr*) &job->addr, af == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6)); | ||||
| 	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)) | ||||
| 	{ | ||||
| 		LOG_TRACE("net_connect_job_check(): Socket connected!"); | ||||
| 		job->con = NULL; | ||||
| 		net_con_clear_timeout(con); | ||||
| 		net_connect_callback(job->handle, net_connect_status_ok, con); | ||||
| 		return 1; | ||||
| 	} | ||||
| @ -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) | ||||
| { | ||||
| 	int ret; | ||||
| 	struct net_connect_job* job = net_con_get_ptr(con); | ||||
| 	struct net_connect_job* next_job = job->next; | ||||
| 	struct net_connect_handle* handle = job->handle; | ||||
| @ -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; | ||||
| 
 | ||||
| @ -381,7 +363,6 @@ static int net_connect_process(struct net_connect_handle* handle) | ||||
| 		return 1; // Connected - cool!
 | ||||
| 
 | ||||
| 	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); | ||||
| 	handle->dns = NULL; | ||||
| 	size_t usable = 0; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	LOG_TRACE("net_con_connect(): async - Got DNS results"); | ||||
| 	if (!result) | ||||
| @ -524,34 +506,3 @@ static void net_connect_callback(struct net_connect_handle* handle, enum net_con | ||||
| 	// Cleanup
 | ||||
| 	net_connect_destroy(handle); | ||||
| } | ||||
| 
 | ||||
| static void timeout_callback(struct timeout_evt* evt) | ||||
| { | ||||
| 	net_con_callback((struct net_connection*) evt->ptr, NET_EVENT_TIMEOUT); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void net_con_set_timeout(struct net_connection* con, int seconds) | ||||
| { | ||||
| 	if (!con->timeout) | ||||
| 	{ | ||||
| 		con->timeout = hub_malloc_zero(sizeof(struct timeout_evt)); | ||||
| 		timeout_evt_initialize(con->timeout, timeout_callback, con); | ||||
| 		timeout_queue_insert(net_backend_get_timeout_queue(), con->timeout, seconds); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		timeout_queue_reschedule(net_backend_get_timeout_queue(), con->timeout, seconds); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void net_con_clear_timeout(struct net_connection* con) | ||||
| { | ||||
| 	if (con->timeout && timeout_evt_is_scheduled(con->timeout)) | ||||
| 	{ | ||||
| 		timeout_queue_remove(net_backend_get_timeout_queue(), con->timeout); | ||||
| 		hub_free(con->timeout); | ||||
| 		con->timeout = 0; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * uhub - A tiny ADC p2p connection hub | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| @ -28,7 +28,6 @@ | ||||
| #define NET_EVENT_TIMEOUT         0x0001 | ||||
| #define NET_EVENT_READ            0x0002 | ||||
| #define NET_EVENT_WRITE           0x0004 | ||||
| #define NET_EVENT_ERROR           0x1000 | ||||
| 
 | ||||
| struct net_connection | ||||
| { | ||||
| @ -88,7 +87,7 @@ extern void net_con_close(struct net_connection* con); | ||||
|  * | ||||
|  * @return returns the number of bytes sent. | ||||
|  *         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); | ||||
| 
 | ||||
| @ -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. | ||||
|  *         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); | ||||
| 
 | ||||
| @ -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); | ||||
| 
 | ||||
| /**
 | ||||
|  * Set timeout for connection. | ||||
|  * Set timeout for connetion. | ||||
|  * | ||||
|  * @param seconds the number of seconds into the future. | ||||
|  */ | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * 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); | ||||
| } | ||||
| 
 | ||||
| static void notify_callback(struct uhub_notify_handle* handle, void* ptr) | ||||
| { | ||||
| 	net_dns_process(); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // NOTE: Any job manipulating the members of this
 | ||||
| // struct must lock the mutex!
 | ||||
| @ -81,8 +76,6 @@ struct net_dns_subsystem | ||||
| 	struct linked_list* jobs;    // currently running jobs
 | ||||
| 	struct linked_list* results; // queue of results that are awaiting being delivered to callback.
 | ||||
| 	uhub_mutex_t mutex; | ||||
| 
 | ||||
| 	struct uhub_notify_handle* notify_handle; // used to signal back to the event loop that there is something to process.
 | ||||
| }; | ||||
| 
 | ||||
| static struct net_dns_subsystem* g_dns = NULL; | ||||
| @ -94,11 +87,13 @@ void net_dns_initialize() | ||||
| 	g_dns->jobs = list_create(); | ||||
| 	g_dns->results = list_create(); | ||||
| 	uhub_mutex_init(&g_dns->mutex); | ||||
| 	g_dns->notify_handle = net_notify_create(notify_callback, g_dns); | ||||
| } | ||||
| 
 | ||||
| void net_dns_destroy() | ||||
| { | ||||
| 	struct net_dns_job* job; | ||||
| 	struct net_dns_result* result; | ||||
| 
 | ||||
| 	uhub_mutex_lock(&g_dns->mutex); | ||||
| 	LOG_TRACE("net_dns_destroy(): jobs=%d", (int) list_size(g_dns->jobs)); | ||||
| 	list_clear(g_dns->jobs, &shutdown_free_jobs); | ||||
| @ -110,18 +105,22 @@ void net_dns_destroy() | ||||
| 	list_destroy(g_dns->jobs); | ||||
| 	list_destroy(g_dns->results); | ||||
| 	uhub_mutex_destroy(&g_dns->mutex); | ||||
| 	net_notify_destroy(g_dns->notify_handle); | ||||
| 	hub_free(g_dns); | ||||
| 	g_dns = NULL; | ||||
| } | ||||
| 
 | ||||
| static void dummy_free(void* ptr) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void net_dns_process() | ||||
| { | ||||
| 	struct net_dns_result* result; | ||||
| 	uhub_mutex_lock(&g_dns->mutex); | ||||
| 	LOG_TRACE("net_dns_process(): jobs=%d, results=%d", (int) list_size(g_dns->jobs), (int) list_size(g_dns->results)); | ||||
| 	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; | ||||
| #ifdef DEBUG_LOOKUP_TIME | ||||
| @ -147,9 +146,9 @@ void net_dns_process() | ||||
| 			result->job = NULL; | ||||
| 			free_job(job); | ||||
| 		} | ||||
| 	}); | ||||
| 	} | ||||
| 
 | ||||
| 	list_clear(g_dns->results, NULL); | ||||
| 	list_clear(g_dns->results, &dummy_free); | ||||
| 	uhub_mutex_unlock(&g_dns->mutex); | ||||
| } | ||||
| 
 | ||||
| @ -216,7 +215,6 @@ static void* job_thread_resolve_name(void* ptr) | ||||
| 	uhub_mutex_lock(&g_dns->mutex); | ||||
| 	list_remove(g_dns->jobs, job); | ||||
| 	list_append(g_dns->results, dns_results); | ||||
| 	net_notify_signal(g_dns->notify_handle, 1); | ||||
| 	uhub_mutex_unlock(&g_dns->mutex); | ||||
| 
 | ||||
| 	return dns_results; | ||||
| @ -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) | ||||
| { | ||||
| 	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) | ||||
| 		{ | ||||
| 			list_remove(g_dns->jobs, it); | ||||
| 			return job; | ||||
| 		} | ||||
| 	}); | ||||
| 	} | ||||
| 	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) | ||||
| { | ||||
| 	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) | ||||
| 		{ | ||||
| 			list_remove(g_dns->results, it); | ||||
| 			return it; | ||||
| 		} | ||||
| 	}); | ||||
| 	} | ||||
| 	return NULL; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * 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. | ||||
|  *                  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. | ||||
|  */ | ||||
| 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 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| @ -805,22 +805,4 @@ void net_stats_add_close() | ||||
| 	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 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| @ -28,10 +28,6 @@ struct net_statistics | ||||
| 	size_t accept; | ||||
| 	size_t closed; | ||||
| 	size_t errors; | ||||
| 	size_t tls_accept; | ||||
| 	size_t tls_connect; | ||||
| 	size_t tls_error; | ||||
| 	size_t tls_close; | ||||
| }; | ||||
| 
 | ||||
| struct net_socket_t; | ||||
| @ -57,7 +53,7 @@ extern int net_initialize(); | ||||
| 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(); | ||||
| 
 | ||||
| @ -67,7 +63,7 @@ extern int net_monitor_count(); | ||||
| 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 | ||||
|  *       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_add_tx(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_error(); | ||||
| extern void net_stats_add_close(); | ||||
| extern void net_stats_add_connect(); | ||||
| extern int net_stats_timeout(); | ||||
| 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 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,33 +13,25 @@ | ||||
|  * 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/>.
 | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| #include "uhub.h" | ||||
| #include "network/common.h" | ||||
| #include "network/tls.h" | ||||
| #include "network/backend.h" | ||||
| 
 | ||||
| #ifdef SSL_SUPPORT | ||||
| #ifdef SSL_USE_OPENSSL | ||||
| 
 | ||||
| void net_stats_add_tx(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 | ||||
| { | ||||
| 	SSL* ssl; | ||||
| 	BIO* bio; | ||||
| 	enum ssl_state state; | ||||
| 	int events; | ||||
| 	int ssl_read_events; | ||||
| 	int ssl_write_events; | ||||
| 	uint32_t flags; | ||||
| 	size_t bytes_rx; | ||||
| 	size_t bytes_tx; | ||||
| @ -47,7 +39,8 @@ struct net_ssl_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) | ||||
| @ -56,29 +49,6 @@ static struct net_ssl_openssl* get_handle(struct net_connection* con) | ||||
| 	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() | ||||
| { | ||||
| 	return OPENSSL_VERSION_TEXT; | ||||
| @ -95,9 +65,7 @@ int net_ssl_library_init() | ||||
| int net_ssl_library_shutdown() | ||||
| { | ||||
| 	ERR_clear_error(); | ||||
| #if OPENSSL_VERSION_NUMBER < 0x10100000L | ||||
| 	ERR_remove_state(0); | ||||
| #endif | ||||
| 
 | ||||
| 	ENGINE_cleanup(); | ||||
| 	CONF_modules_unload(1); | ||||
| @ -112,173 +80,56 @@ int net_ssl_library_shutdown() | ||||
| 
 | ||||
| static void add_io_stats(struct net_ssl_openssl* handle) | ||||
| { | ||||
| #if OPENSSL_VERSION_NUMBER < 0x10100000L | ||||
| 	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) | ||||
| 	if (handle->bio->num_read > handle->bytes_rx) | ||||
| 	{ | ||||
| 		net_stats_add_rx(num_read - handle->bytes_rx); | ||||
| 		handle->bytes_rx = num_read; | ||||
| 		net_stats_add_rx(handle->bio->num_read - handle->bytes_rx); | ||||
| 		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); | ||||
| 		handle->bytes_tx = num_write; | ||||
| 		net_stats_add_tx(handle->bio->num_write - handle->bytes_tx); | ||||
| 		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. | ||||
|  */ | ||||
| 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)); | ||||
|         long flags = 0; | ||||
| 	const SSL_METHOD* ssl_method = get_ssl_method(tls_version, &flags); | ||||
| 	ctx->ssl_method = (SSL_METHOD*) SSLv23_method(); /* TLSv1_method() */ | ||||
| 	ctx->ssl_ctx = SSL_CTX_new(ctx->ssl_method); | ||||
| 
 | ||||
| 	if (!ssl_method) | ||||
| 	{ | ||||
| 		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); | ||||
| 	/* Disable SSLv2 */ | ||||
| 	SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv2); | ||||
| 
 | ||||
| #ifdef SSL_OP_NO_COMPRESSION | ||||
| 	/* Disable compression */ | ||||
| 	/* Disable compression? */ | ||||
| 	LOG_TRACE("Disabling SSL compression."); /* "CRIME" attack */ | ||||
| 	flags |= SSL_OP_NO_COMPRESSION; | ||||
| 	SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_COMPRESSION); | ||||
| #endif | ||||
| 
 | ||||
|         // Set flags
 | ||||
|         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); | ||||
| 	SSL_CTX_set_quiet_shutdown(ctx->ssl_ctx, 1); | ||||
| 
 | ||||
| 	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_; | ||||
| 	SSL_CTX_free(ctx->ssl); | ||||
| 	SSL_CTX_free(ctx->ssl_ctx); | ||||
| 	hub_free(ctx); | ||||
| } | ||||
| 
 | ||||
| int ssl_load_certificate(struct ssl_context_handle* ctx_, const char* pem_file) | ||||
| { | ||||
| 	struct net_context_openssl* ctx = (struct net_context_openssl*) ctx_; | ||||
| 	if (SSL_CTX_use_certificate_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; | ||||
| 	} | ||||
| 
 | ||||
| @ -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) | ||||
| { | ||||
| 	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)); | ||||
| 		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_) | ||||
| { | ||||
| 	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)); | ||||
| 		return 0; | ||||
| @ -307,7 +158,7 @@ int ssl_check_private_key(struct ssl_context_handle* ctx_) | ||||
| 	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); | ||||
| 	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; | ||||
| 
 | ||||
| 		case SSL_ERROR_WANT_READ: | ||||
| 			if (read) | ||||
| 				handle->ssl_read_events = NET_EVENT_READ; | ||||
| 			else | ||||
| 				handle->ssl_write_events = NET_EVENT_READ; | ||||
| 			handle->state = forced_rwstate; | ||||
| 			net_con_update(con, NET_EVENT_READ); | ||||
| 			return 0; | ||||
| 
 | ||||
| 		case SSL_ERROR_WANT_WRITE: | ||||
| 			if (read) | ||||
| 				handle->ssl_read_events = NET_EVENT_WRITE; | ||||
| 			else | ||||
| 				handle->ssl_write_events = NET_EVENT_WRITE; | ||||
| 			handle->state = forced_rwstate; | ||||
| 			net_con_update(con, NET_EVENT_WRITE); | ||||
| 			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: | ||||
| 			net_ssl_set_state(handle, tls_st_error); | ||||
| 			net_stats_tls_add_error(); | ||||
| 			handle->state = tls_st_error; | ||||
| 			return -2; | ||||
| 	} | ||||
| 
 | ||||
| 	net_stats_tls_add_error(); | ||||
| 	return -2; | ||||
| } | ||||
| 
 | ||||
| ssize_t net_con_ssl_accept(struct net_connection* con) | ||||
| { | ||||
| 	struct net_ssl_openssl* handle = get_handle(con); | ||||
| 	handle->state = tls_st_accepting; | ||||
| 	ssize_t ret; | ||||
| 	net_ssl_set_state(handle, tls_st_accepting); | ||||
| 
 | ||||
| 	ret = SSL_accept(handle->ssl); | ||||
| 	LOG_PROTO("SSL_accept() ret=%d", ret); | ||||
| 	if (ret > 0) | ||||
| 	{ | ||||
| 		net_con_update(con, NET_EVENT_READ); | ||||
| 		net_ssl_set_state(handle, tls_st_connected); | ||||
|                 net_stats_tls_add_accept(); | ||||
| 		handle->state = tls_st_connected; | ||||
| 		return ret; | ||||
| 	} | ||||
| 	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); | ||||
| 	ssize_t ret; | ||||
| 	net_ssl_set_state(handle, tls_st_connecting); | ||||
| 	handle->state = tls_st_connecting; | ||||
| 
 | ||||
| 	ret = SSL_connect(handle->ssl); | ||||
| 	LOG_PROTO("SSL_connect() ret=%d", ret); | ||||
| 
 | ||||
| 	if (ret > 0) | ||||
| 	{ | ||||
| 		handle->state = tls_st_connected; | ||||
| 		net_con_update(con, NET_EVENT_READ); | ||||
| 		net_ssl_set_state(handle, tls_st_connected); | ||||
|                 net_stats_tls_add_connect(); | ||||
| 		return ret; | ||||
| 	} | ||||
| 	 | ||||
| 	ret = handle_openssl_error(con, ret, tls_st_connecting); | ||||
| 	 | ||||
|         if (ret != 0) | ||||
|             LOG_ERROR("net_con_ssl_connect: ret=%d", ret); | ||||
| 	return ret; | ||||
| 	return handle_openssl_error(con, ret, tls_st_connecting); | ||||
| } | ||||
| 
 | ||||
| ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode ssl_mode, struct ssl_context_handle* ssl_ctx) | ||||
| { | ||||
| 	uhub_assert(con); | ||||
| 	uhub_assert(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)); | ||||
| 
 | ||||
| 	if (ssl_mode == net_con_ssl_mode_server) | ||||
| 	{ | ||||
| 		handle->ssl = SSL_new(ctx->ssl); | ||||
| 		handle->ssl = SSL_new(ctx->ssl_ctx); | ||||
| 		if (!handle->ssl) | ||||
| 		{ | ||||
| 			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 | ||||
| 	{ | ||||
| 		handle->ssl = SSL_new(ctx->ssl); | ||||
| 		handle->ssl = SSL_new(SSL_CTX_new(TLSv1_method())); | ||||
| 		SSL_set_fd(handle->ssl, con->sd); | ||||
| 		handle->bio = SSL_get_rbio(handle->ssl); | ||||
| 		con->ssl = (struct ssl_handle*) handle; | ||||
| 		return net_con_ssl_connect(con); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| ssize_t net_ssl_send(struct net_connection* con, const void* buf, size_t len) | ||||
| { | ||||
| 	struct net_ssl_openssl* handle = get_handle(con); | ||||
| 
 | ||||
| 	LOG_TRACE("net_ssl_send(), state=%d", (int) handle->state); | ||||
| 
 | ||||
| 	if (handle->state == tls_st_error) | ||||
| 		return -2; | ||||
| 
 | ||||
| 	uhub_assert(handle->state == tls_st_connected); | ||||
| 	 | ||||
| 	uhub_assert(handle->state == tls_st_connected || handle->state == tls_st_need_write); | ||||
| 
 | ||||
| 	ERR_clear_error(); | ||||
| 	ssize_t ret = SSL_write(handle->ssl, buf, len); | ||||
| 	add_io_stats(handle); | ||||
| 	LOG_PROTO("SSL_write(con=%p, buf=%p, len=" PRINTF_SIZE_T ") => %d", con, buf, len, ret); | ||||
| 	if (ret > 0) | ||||
| 		handle->ssl_write_events = 0; | ||||
| 	else | ||||
| 		ret = handle_openssl_error(con, ret, 0); | ||||
| 
 | ||||
| 	net_ssl_update(con, handle->events);  // Update backend only
 | ||||
| 	{ | ||||
| 		handle->state = tls_st_connected; | ||||
| 		return ret; | ||||
| 	} | ||||
| 	return handle_openssl_error(con, ret, tls_st_need_write); | ||||
| } | ||||
| 
 | ||||
| ssize_t net_ssl_recv(struct net_connection* con, void* buf, size_t len) | ||||
| @ -452,10 +276,7 @@ ssize_t net_ssl_recv(struct net_connection* con, void* buf, size_t len) | ||||
| 	if (handle->state == tls_st_error) | ||||
| 		return -2; | ||||
| 
 | ||||
| 	if (handle->state == tls_st_accepting || handle->state == tls_st_connecting) | ||||
| 		return -1; | ||||
| 
 | ||||
| 	uhub_assert(handle->state == tls_st_connected); | ||||
| 	uhub_assert(handle->state == tls_st_connected || handle->state == tls_st_need_read); | ||||
| 
 | ||||
| 	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); | ||||
| 	LOG_PROTO("SSL_read(con=%p, buf=%p, len=" PRINTF_SIZE_T ") => %d", con, buf, len, ret); | ||||
| 	if (ret > 0) | ||||
| 		handle->ssl_read_events = 0; | ||||
| 	else | ||||
| 		ret = handle_openssl_error(con, ret, 1); | ||||
| 
 | ||||
| 	net_ssl_update(con, handle->events);  // Update backend only
 | ||||
| 	{ | ||||
| 		handle->state = tls_st_connected; | ||||
| 		return ret; | ||||
| } | ||||
| 
 | ||||
| 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); | ||||
| 	} | ||||
| 	return handle_openssl_error(con, ret, tls_st_need_read); | ||||
| } | ||||
| 
 | ||||
| void net_ssl_shutdown(struct net_connection* con) | ||||
| { | ||||
| 	struct net_ssl_openssl* handle = get_handle(con); | ||||
| 	if (handle) | ||||
| 	{ | ||||
| 	SSL_shutdown(handle->ssl); | ||||
| 	SSL_clear(handle->ssl); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void net_ssl_destroy(struct net_connection* con) | ||||
| { | ||||
| 	struct net_ssl_openssl* handle = get_handle(con); | ||||
| 	LOG_TRACE("net_ssl_destroy: %p", con); | ||||
| 	SSL_free(handle->ssl); | ||||
| 	hub_free(handle); | ||||
| } | ||||
| 
 | ||||
| void net_ssl_callback(struct net_connection* con, int events) | ||||
| { | ||||
| 	struct net_ssl_openssl* handle = get_handle(con); | ||||
| 	int ret; | ||||
| 
 | ||||
| 	switch (handle->state) | ||||
| 	{ | ||||
| @ -508,7 +315,7 @@ void net_ssl_callback(struct net_connection* con, int events) | ||||
| 			break; | ||||
| 
 | ||||
| 		case tls_st_error: | ||||
| 			con->callback(con, NET_EVENT_ERROR, con->ptr); | ||||
| 			con->callback(con, NET_EVENT_READ, con->ptr); | ||||
| 			break; | ||||
| 
 | ||||
| 		case tls_st_accepting: | ||||
| @ -517,27 +324,19 @@ void net_ssl_callback(struct net_connection* con, int events) | ||||
| 			break; | ||||
| 
 | ||||
| 		case tls_st_connecting: | ||||
| 			ret = net_con_ssl_connect(con); | ||||
| 			if (ret == 0) | ||||
| 				return; | ||||
| 
 | ||||
| 			if (ret > 0) | ||||
| 			{ | ||||
| 				LOG_DEBUG("%p SSL connected!", con); | ||||
| 			if (net_con_ssl_connect(con) != 0) | ||||
| 				con->callback(con, NET_EVENT_READ, con->ptr); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				LOG_DEBUG("%p SSL handshake failed!", con); | ||||
| 				con->callback(con, NET_EVENT_ERROR, con->ptr); | ||||
| 			} | ||||
| 			break; | ||||
| 
 | ||||
| 		case tls_st_need_read: | ||||
| 			con->callback(con, NET_EVENT_READ, con->ptr); | ||||
| 			break; | ||||
| 
 | ||||
| 		case tls_st_need_write: | ||||
| 			con->callback(con, NET_EVENT_WRITE, con->ptr); | ||||
| 			break; | ||||
| 
 | ||||
| 		case tls_st_connected: | ||||
| 			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); | ||||
| 			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_SUPPORT */ | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * 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/>.
 | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| /*
 | ||||
|  * 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 | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
| @ -13,7 +13,7 @@ | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * 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->max = max; | ||||
| 	memset(&t->lock, 0, sizeof(t->lock)); | ||||
| 	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; | ||||
| } | ||||
| 
 | ||||
| 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 pos = (size_t) t->last; | ||||
| 	size_t events = 0; | ||||
| 	struct timeout_evt* evt = 0; | ||||
| 	t->last = now; | ||||
| 	timeout_queue_lock(t); | ||||
| 	for (; pos <= now; pos++) | ||||
| 	{ | ||||
| 		while ((evt = t->events[pos % t->max])) | ||||
| @ -112,7 +67,6 @@ size_t timeout_queue_process(struct timeout_queue* t, time_t now) | ||||
| 			events++; | ||||
| 		} | ||||
| 	} | ||||
| 	timeout_queue_unlock(t); | ||||
| 	return events; | ||||
| } | ||||
| 
 | ||||
| @ -128,61 +82,6 @@ size_t timeout_queue_get_next_timeout(struct timeout_queue* t, time_t now) | ||||
| 	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) | ||||
| { | ||||
| @ -191,12 +90,6 @@ void timeout_queue_insert(struct timeout_queue* t, struct timeout_evt* evt, size | ||||
| 	evt->timestamp = t->last + seconds; | ||||
| 	evt->next = 0; | ||||
| 	 | ||||
| 	if (timeout_queue_locked(t)) | ||||
| 	{ | ||||
| 		timeout_queue_insert_locked(t, evt); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	first = t->events[pos]; | ||||
| 	 | ||||
| 	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); | ||||
| 	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) | ||||
| 		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