Compare commits
1 Commits
master
...
command_cl
Author | SHA1 | Date | |
---|---|---|---|
|
714d110a94 |
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/\//-}
|
16
.gitignore
vendored
16
.gitignore
vendored
@ -1,23 +1,9 @@
|
||||
*~
|
||||
*.[oa]
|
||||
*.lib
|
||||
*.exe
|
||||
*.manifest
|
||||
*.gch
|
||||
CMakeFiles/*
|
||||
CMakeCache.txt
|
||||
cmake_install.cmake
|
||||
mod_*.dll
|
||||
mod_*.exp
|
||||
mod_*.so
|
||||
uhub-admin
|
||||
adcrush
|
||||
uhub
|
||||
build-stamp
|
||||
debian/files
|
||||
debian/uhub.debhelper.log
|
||||
debian/uhub.postinst.debhelper
|
||||
debian/uhub.postrm.debhelper
|
||||
debian/uhub.prerm.debhelper
|
||||
debian/uhub.substvars
|
||||
uhub-passwd
|
||||
revision.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
|
||||
|
10
AUTHORS
10
AUTHORS
@ -3,9 +3,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
|
||||
Boris Pek (tehnick), Debian/Ubuntu packaging
|
||||
Tillmann Karras (Tilka), Misc. bug fixes
|
||||
Yoran Heling (Yorhel), TLS/SSL handshake detection bugfixes
|
||||
Blair Bonnett, Misc. bug fixes
|
||||
FleetCommand, Hub topic
|
||||
MiMic, Implemented user commands
|
||||
tehnick, Debian and Ubuntu packaging.
|
||||
|
||||
|
8
BSDmakefile
Normal file
8
BSDmakefile
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
GMAKE=gmake
|
||||
|
||||
all:
|
||||
@${GMAKE} ${.TARGETS}
|
||||
|
||||
${.TARGETS}: all
|
||||
|
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/
|
||||
|
||||
|
246
CMakeLists.txt
246
CMakeLists.txt
@ -1,246 +0,0 @@
|
||||
##
|
||||
## Makefile for uhub
|
||||
## Copyright (C) 2007-2013, Jan Vidar Krey <janvidar@extatic.org>
|
||||
#
|
||||
|
||||
cmake_minimum_required (VERSION 2.8.2)
|
||||
|
||||
project (uhub NONE)
|
||||
enable_language(C)
|
||||
|
||||
set (UHUB_VERSION_MAJOR 0)
|
||||
set (UHUB_VERSION_MINOR 5)
|
||||
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(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)
|
||||
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)
|
||||
else()
|
||||
find_package(GnuTLS)
|
||||
endif()
|
||||
if (NOT GNUTLS_FOUND AND NOT OPENSSL_FOUND)
|
||||
message(FATAL_ERROR "Neither OpenSSL nor GnuTLS were found!")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (NOT SQLITE3_FOUND)
|
||||
message(FATAL_ERROR "SQLite3 is not found!")
|
||||
endif()
|
||||
|
||||
if (SYSTEMD_SUPPORT)
|
||||
INCLUDE(FindPkgConfig)
|
||||
pkg_search_module(SD REQUIRED libsystemd)
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
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
|
||||
${PROJECT_SOURCE_DIR}/core/gen_config.c
|
||||
${PROJECT_SOURCE_DIR}/core/main.c
|
||||
)
|
||||
|
||||
file (GLOB adc_SOURCES ${PROJECT_SOURCE_DIR}/adc/*.c)
|
||||
file (GLOB network_SOURCES ${PROJECT_SOURCE_DIR}/network/*.c)
|
||||
file (GLOB utils_SOURCES ${PROJECT_SOURCE_DIR}/util/*.c)
|
||||
|
||||
set (adcclient_SOURCES
|
||||
${PROJECT_SOURCE_DIR}/tools/adcclient.c
|
||||
${PROJECT_SOURCE_DIR}/core/ioqueue.c
|
||||
)
|
||||
|
||||
add_library(adc STATIC ${adc_SOURCES})
|
||||
add_library(network STATIC ${network_SOURCES})
|
||||
add_library(utils STATIC ${utils_SOURCES})
|
||||
if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
|
||||
set_target_properties(utils PROPERTIES COMPILE_FLAGS -fPIC)
|
||||
set_target_properties(network PROPERTIES COMPILE_FLAGS -fPIC)
|
||||
endif()
|
||||
|
||||
add_dependencies(adc utils)
|
||||
add_dependencies(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(uhub-passwd ${PROJECT_SOURCE_DIR}/tools/uhub-passwd.c)
|
||||
|
||||
add_library(mod_example MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_example.c)
|
||||
add_library(mod_welcome MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_welcome.c)
|
||||
add_library(mod_logging MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_logging.c ${PROJECT_SOURCE_DIR}/adc/sid.c)
|
||||
add_library(mod_auth_simple MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_auth_simple.c )
|
||||
add_library(mod_chat_history MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_chat_history.c )
|
||||
add_library(mod_chat_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)
|
||||
|
||||
set_target_properties(
|
||||
mod_example
|
||||
mod_welcome
|
||||
mod_logging
|
||||
mod_auth_simple
|
||||
mod_auth_sqlite
|
||||
mod_chat_history
|
||||
mod_chat_history_sqlite
|
||||
mod_chat_only
|
||||
mod_no_guest_downloads
|
||||
mod_topic
|
||||
PROPERTIES PREFIX "")
|
||||
|
||||
target_link_libraries(uhub ${CMAKE_DL_LIBS} adc network utils)
|
||||
target_link_libraries(uhub-passwd ${SQLITE3_LIBRARIES} utils)
|
||||
target_link_libraries(autotest-bin ${CMAKE_DL_LIBS} adc network utils)
|
||||
target_link_libraries(mod_example utils)
|
||||
target_link_libraries(mod_welcome network utils)
|
||||
target_link_libraries(mod_auth_simple utils)
|
||||
target_link_libraries(mod_auth_sqlite ${SQLITE3_LIBRARIES} utils)
|
||||
target_link_libraries(mod_chat_history utils)
|
||||
target_link_libraries(mod_chat_history_sqlite ${SQLITE3_LIBRARIES} utils)
|
||||
target_link_libraries(mod_no_guest_downloads utils)
|
||||
target_link_libraries(mod_chat_only utils)
|
||||
target_link_libraries(mod_logging network utils)
|
||||
target_link_libraries(mod_topic utils)
|
||||
target_link_libraries(utils network)
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(uhub ws2_32)
|
||||
target_link_libraries(autotest-bin ws2_32)
|
||||
target_link_libraries(mod_logging ws2_32)
|
||||
target_link_libraries(mod_welcome ws2_32)
|
||||
endif()
|
||||
|
||||
if(UNIX)
|
||||
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)
|
||||
|
||||
if (ADC_STRESS)
|
||||
add_executable(adcrush ${PROJECT_SOURCE_DIR}/tools/adcrush.c ${adcclient_SOURCES})
|
||||
target_link_libraries(adcrush adcclient adc network utils pthread)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (NOT UHUB_REVISION AND GIT_FOUND)
|
||||
execute_process(COMMAND ${GIT_EXECUTABLE} show -s --pretty=format:%h
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE UHUB_REVISION_TEMP
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if (UHUB_REVISION_TEMP)
|
||||
set (UHUB_REVISION "git-${UHUB_REVISION_TEMP}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (NOT UHUB_REVISION)
|
||||
set (UHUB_REVISION "release")
|
||||
endif()
|
||||
|
||||
set (UHUB_GIT_VERSION "${UHUB_VERSION_MAJOR}.${UHUB_VERSION_MINOR}.${UHUB_VERSION_PATCH}-${UHUB_REVISION}")
|
||||
message (STATUS "Configuring uhub version: ${UHUB_GIT_VERSION}")
|
||||
|
||||
if(OPENSSL_FOUND)
|
||||
set(SSL_LIBS ${OPENSSL_LIBRARIES})
|
||||
add_definitions(-DSSL_SUPPORT=1 -DSSL_USE_OPENSSL=1)
|
||||
include_directories(${OPENSSL_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
if (GNUTLS_FOUND)
|
||||
set(SSL_LIBS ${GNUTLS_LIBRARIES})
|
||||
add_definitions(-DSSL_SUPPORT=1 -DSSL_USE_GNUTLS=1 ${GNUTLS_DEFINITIONS})
|
||||
include_directories(${GNUTLS_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
if(SSL_SUPPORT)
|
||||
target_link_libraries(uhub ${SSL_LIBS})
|
||||
target_link_libraries(autotest-bin ${SSL_LIBS})
|
||||
if(UNIX)
|
||||
target_link_libraries(uhub-admin ${SSL_LIBS})
|
||||
endif()
|
||||
target_link_libraries(mod_welcome ${SSL_LIBS})
|
||||
target_link_libraries(mod_logging ${SSL_LIBS})
|
||||
if (ADC_STRESS)
|
||||
target_link_libraries(adcrush ${SSL_LIBS})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (SYSTEMD_SUPPORT)
|
||||
target_link_libraries(uhub ${SD_LIBRARIES})
|
||||
target_link_libraries(autotest-bin ${SD_LIBRARIES})
|
||||
target_link_libraries(uhub-passwd ${SD_LIBRARIES})
|
||||
target_link_libraries(uhub-admin ${SD_LIBRARIES})
|
||||
include_directories(${SD_INCLUDE_DIRS})
|
||||
add_definitions(-DSYSTEMD)
|
||||
endif()
|
||||
|
||||
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")
|
||||
|
||||
# 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)
|
||||
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( 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()
|
||||
|
||||
|
@ -1,25 +0,0 @@
|
||||
OpenSSL License Exception
|
||||
-------------------------
|
||||
|
||||
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 3 (GPL) as published by
|
||||
the Free Software Foundation.
|
||||
The full text the GPL can be found in the COPYING file.
|
||||
|
||||
In addition this distribution of uhub may be linked against OpenSSL
|
||||
according to the terms described here:
|
||||
|
||||
You have permission to copy, modify, propagate, and distribute a work
|
||||
formed by combining OpenSSL with uhub, or a work derivative of such a
|
||||
combination, even if such copying, modification, propagation, or
|
||||
distribution would otherwise violate the terms of the GPL. You must
|
||||
comply with the GPL in all respects for all of the code used other than
|
||||
OpenSSL.
|
||||
|
||||
You may include this OpenSSL exception and its grant of permissions when
|
||||
you distribute uhub. Inclusion of this notice with such a distribution
|
||||
constitutes a grant of such permission. If you do not wish to grant these
|
||||
permissions, delete this file.
|
||||
|
85
ChangeLog
85
ChangeLog
@ -1,88 +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.
|
||||
- Fix TLS/SSL handshake detection issues
|
||||
- Fixed crash in mod_chat_only.
|
||||
- Implemented red-black tree for better performance for certain lookups.
|
||||
- Better network statistics using the !stats command.
|
||||
- Improved protocol parsing, especially escape handling.
|
||||
- Fix cbuffer initialization.
|
||||
- Install plugins in /usr/lib/uhub, not /var/lib/uhub.
|
||||
- Improved init scripts and added a upstart script.
|
||||
- Work-around client security bugs by disallowing UCMD messages from being relayed.
|
||||
- Added asynchronous DNS resolver.
|
||||
|
||||
|
||||
0.4.0:
|
||||
- Cleaned up code generator for config file parsing.
|
||||
- Merge pull request #5 from yorhel/master
|
||||
- Print error message in case of shutting down due to errors loading plugins.
|
||||
- Fix Windows file read discrepancy.
|
||||
- convert_to_sqlite.pl: Update to the latest SQL schema + be more Perlish
|
||||
- Fix VS2010 project file - missing .c file.
|
||||
- Merge https://github.com/Tilka/uhub
|
||||
- use "I64u" instead of PRIu64 on Windows
|
||||
- remove obsolete settings in uhub.conf
|
||||
- fix uhub_itoa() and uhub_ulltoa()
|
||||
- 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.
|
||||
- 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
|
||||
- don't show error on SIGTERM in select() backend
|
||||
- fix dependency of 'install' target
|
||||
- changed all calls to assert() to uhub_assert()
|
||||
- Don't strip the U4/U6 port numbers if updated after login.
|
||||
- Fix compile issue with double typedefs.
|
||||
- Remove list assertion when removing element that is not in the list. Breaks autotest.
|
||||
- Cleaned up command handling code, by splitting into multiple files.
|
||||
- Fix bug #183 - Added proper OpenSSL license exception for the GPL.
|
||||
- OMG OPTIMIZED
|
||||
- use dh_prep instead of dh_clean -k
|
||||
- fix double free
|
||||
- use "0" instead of "false"
|
||||
- fix use of uninitialized struct ip_range
|
||||
- fix random crashes upon !reload
|
||||
- fix command syntax
|
||||
- use arg parser in !broadcast
|
||||
- Fixed tiny memory leak on reload/shutdown.
|
||||
- Merge https://github.com/Tilka/uhub
|
||||
- fix multiple optional arguments
|
||||
- small cleanup
|
||||
- also clean uhub-passwd
|
||||
- ignore files generated by dpkg-buildpackage
|
||||
- automatically clean up plugin commands
|
||||
- minimal documentation fixes
|
||||
- update client software link
|
||||
- update compile howto link
|
||||
- fix Debian changelog
|
||||
- Fix bug #158 - Added plugin for setting topic (hub description).
|
||||
- Command arguments handling + cleanups
|
||||
|
||||
|
||||
0.3.2:
|
||||
- Fixed bugs in the kqueue network backend (OSX/BSD)
|
||||
- Rewrote the configuration backend code.
|
||||
|
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"]
|
354
GNUmakefile
Normal file
354
GNUmakefile
Normal file
@ -0,0 +1,354 @@
|
||||
##
|
||||
## Makefile for uhub (Use GNU make)
|
||||
## Copyright (C) 2007-2010, Jan Vidar Krey <janvidar@extatic.org>
|
||||
#
|
||||
|
||||
-include Makefile.private
|
||||
|
||||
CC = gcc
|
||||
LD := $(CC)
|
||||
MV := mv
|
||||
RANLIB := ranlib
|
||||
CFLAGS += -pipe -Wall
|
||||
USE_SSL ?= YES
|
||||
USE_PLUGINS ?= YES
|
||||
USE_BIGENDIAN ?= AUTO
|
||||
BITS ?= AUTO
|
||||
SILENT ?= YES
|
||||
TERSE ?= NO
|
||||
STACK_PROTECT ?= NO
|
||||
NEED_LIBDL ?= NO
|
||||
|
||||
ifeq ($(OS), Windows_NT)
|
||||
WINDOWS ?= YES
|
||||
OPSYS ?= Windows
|
||||
else
|
||||
OPSYS ?= $(shell uname)
|
||||
endif
|
||||
|
||||
ifeq ($(OPSYS),SunOS)
|
||||
LDLIBS += -lsocket -lnsl
|
||||
endif
|
||||
|
||||
ifeq ($(OPSYS),Haiku)
|
||||
LDLIBS += -lnetwork
|
||||
endif
|
||||
|
||||
ifeq ($(OPSYS),Linux)
|
||||
NEED_LIBDL = YES
|
||||
endif
|
||||
|
||||
CFLAGS += -I./src/
|
||||
|
||||
ifeq ($(OPSYS),Windows)
|
||||
USE_BIGENDIAN := NO
|
||||
LDLIBS += -lws2_32
|
||||
UHUB_CONF_DIR ?= c:/uhub/
|
||||
UHUB_PREFIX ?= c:/uhub/
|
||||
CFLAGS += -mno-cygwin
|
||||
LDFLAGS += -mno-cygwin
|
||||
BIN_EXT ?= .exe
|
||||
else
|
||||
DESTDIR ?= /
|
||||
UHUB_CONF_DIR ?= $(DESTDIR)/etc/uhub
|
||||
UHUB_PREFIX ?= $(DESTDIR)/usr/local
|
||||
UHUB_MOD_DIR ?= $(DESTDIR)/var/lib/uhub
|
||||
CFLAGS += -I/usr/local/include
|
||||
LDFLAGS += -L/usr/local/lib
|
||||
BIN_EXT ?=
|
||||
endif
|
||||
|
||||
ifeq ($(SILENT),YES)
|
||||
MSG_CC=@echo " CC:" $(notdir $<) &&
|
||||
MSG_LD=@echo " LD:" $(notdir $@) &&
|
||||
MSG_AR=@echo " AR:" $(notdir $@) &&
|
||||
else
|
||||
MSG_CC=
|
||||
MSG_LD=
|
||||
MSG_AR=
|
||||
endif
|
||||
|
||||
ifeq ($(TERSE), YES)
|
||||
MSG_CC=@
|
||||
MSG_LD=@
|
||||
MSG_AR=@
|
||||
MSG_CLEAN=-n ""
|
||||
else
|
||||
MSG_CLEAN="Clean as a whistle"
|
||||
endif
|
||||
|
||||
ifeq ($(RELEASE),YES)
|
||||
CFLAGS += -O3 -DNDEBUG
|
||||
else
|
||||
CFLAGS += -ggdb -DDEBUG
|
||||
endif
|
||||
|
||||
ifeq ($(STACK_PROTECT),YES)
|
||||
CFLAGS += -fstack-protector-all
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(PROFILING),YES)
|
||||
CFLAGS += -pg
|
||||
LDFLAGS += -pg
|
||||
endif
|
||||
|
||||
ifeq ($(FUNCTRACE),YES)
|
||||
CFLAGS += -finstrument-functions
|
||||
CFLAGS += -DDEBUG_FUNCTION_TRACE
|
||||
endif
|
||||
|
||||
ifneq ($(BITS), AUTO)
|
||||
ifeq ($(BITS), 64)
|
||||
CFLAGS += -m64
|
||||
LDFLAGS += -m64
|
||||
else
|
||||
ifeq ($(BITS), 32)
|
||||
CFLAGS += -m32
|
||||
LDFLAGS += -m32
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(USE_BIGENDIAN),AUTO)
|
||||
ifeq ($(shell perl -e 'print pack("L", 0x554E4958)'),UNIX)
|
||||
CFLAGS += -DARCH_BIGENDIAN
|
||||
endif
|
||||
else
|
||||
ifeq ($(USE_BIGENDIAN),YES)
|
||||
CFLAGS += -DARCH_BIGENDIAN
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(USE_SSL),YES)
|
||||
CFLAGS += -DSSL_SUPPORT
|
||||
LDLIBS += -lssl -lcrypto
|
||||
endif
|
||||
|
||||
ifeq ($(NEED_LIBDL),YES)
|
||||
LDLIBS += -ldl
|
||||
endif
|
||||
|
||||
GIT_VERSION=$(shell git describe --tags 2>/dev/null || echo "")
|
||||
GIT_REVISION=$(shell git show --abbrev-commit 2>/dev/null | head -n 1 | cut -f 2 -d " " || echo "")
|
||||
OLD_REVISION=$(shell grep GIT_REVISION revision.h 2>/dev/null | cut -f 3 -d " " | tr -d "\"")
|
||||
|
||||
# Sources
|
||||
libuhub_SOURCES := \
|
||||
src/core/auth.c \
|
||||
src/core/commands.c \
|
||||
src/core/config.c \
|
||||
src/core/eventqueue.c \
|
||||
src/core/hub.c \
|
||||
src/core/hubevent.c \
|
||||
src/core/hubio.c \
|
||||
src/core/inf.c \
|
||||
src/core/netevent.c \
|
||||
src/core/probe.c \
|
||||
src/core/route.c \
|
||||
src/core/user.c \
|
||||
src/core/usermanager.c \
|
||||
src/core/plugincallback.c \
|
||||
src/core/plugininvoke.c \
|
||||
src/core/pluginloader.c \
|
||||
src/network/backend.c \
|
||||
src/network/connection.c \
|
||||
src/network/epoll.c \
|
||||
src/network/kqueue.c \
|
||||
src/network/select.c \
|
||||
src/network/timeout.c \
|
||||
src/network/timer.c
|
||||
|
||||
|
||||
libadc_common_SOURCES := \
|
||||
src/adc/message.c \
|
||||
src/adc/sid.c
|
||||
|
||||
libutils_SOURCES := \
|
||||
src/util/cbuffer.c \
|
||||
src/util/config_token.c \
|
||||
src/util/credentials.c \
|
||||
src/util/floodctl.c \
|
||||
src/util/ipcalc.c \
|
||||
src/util/list.c \
|
||||
src/util/log.c \
|
||||
src/util/memory.c \
|
||||
src/util/misc.c \
|
||||
src/network/network.c \
|
||||
src/util/rbtree.c \
|
||||
src/util/tiger.c
|
||||
|
||||
libadc_client_SOURCES := \
|
||||
src/tools/adcclient.c
|
||||
|
||||
uhub_SOURCES := src/core/main.c
|
||||
|
||||
uhub-passwd_SOURCES := src/tools/uhub-passwd.c
|
||||
uhub-passwd_LIBS := -lsqlite3
|
||||
|
||||
adcrush_SOURCES := src/tools/adcrush.c
|
||||
|
||||
admin_SOURCES := src/tools/admin.c
|
||||
|
||||
autotest_SOURCES := \
|
||||
autotest/test_commands.tcc \
|
||||
autotest/test_credentials.tcc \
|
||||
autotest/test_eventqueue.tcc \
|
||||
autotest/test_hub.tcc \
|
||||
autotest/test_inf.tcc \
|
||||
autotest/test_ipfilter.tcc \
|
||||
autotest/test_list.tcc \
|
||||
autotest/test_memory.tcc \
|
||||
autotest/test_message.tcc \
|
||||
autotest/test_misc.tcc \
|
||||
autotest/test_sid.tcc \
|
||||
autotest/test_tiger.tcc \
|
||||
autotest/test_timer.tcc \
|
||||
autotest/test_tokenizer.tcc \
|
||||
autotest/test_usermanager.tcc
|
||||
|
||||
autotest_OBJECTS = autotest.o
|
||||
|
||||
# Plugin targets:
|
||||
plugin_example_SOURCES := src/plugins/mod_example.c
|
||||
plugin_example_TARGET := mod_example.so
|
||||
|
||||
plugin_welcome_SOURCES := src/plugins/mod_welcome.c
|
||||
plugin_welcome_TARGET := mod_welcome.so
|
||||
|
||||
plugin_logging_SOURCES := src/plugins/mod_logging.c
|
||||
plugin_logging_TARGET := mod_logging.so
|
||||
|
||||
plugin_auth_SOURCES := src/plugins/mod_auth_simple.c
|
||||
plugin_auth_TARGET := mod_auth_simple.so
|
||||
|
||||
plugin_auth_sqlite_SOURCES := src/plugins/mod_auth_sqlite.c
|
||||
plugin_auth_sqlite_TARGET := mod_auth_sqlite.so
|
||||
plugin_auth_sqlite_LIBS := -lsqlite3
|
||||
|
||||
plugin_chat_history_SOURCE := src/plugins/mod_chat_history.c
|
||||
plugin_chat_history_TARGET := mod_chat_history.so
|
||||
|
||||
plugin_chat_only_SOURCE := src/plugins/mod_chat_only.c
|
||||
plugin_chat_only_TARGET := mod_chat_only.so
|
||||
|
||||
# Source to objects
|
||||
libuhub_OBJECTS := $(libuhub_SOURCES:.c=.o)
|
||||
libutils_OBJECTS := $(libutils_SOURCES:.c=.o)
|
||||
libadc_client_OBJECTS := $(libadc_client_SOURCES:.c=.o)
|
||||
libadc_common_OBJECTS := $(libadc_common_SOURCES:.c=.o)
|
||||
|
||||
uhub_OBJECTS := $(uhub_SOURCES:.c=.o)
|
||||
uhub-passwd_OBJECTS := $(uhub-passwd_SOURCES:.c=.o)
|
||||
adcrush_OBJECTS := $(adcrush_SOURCES:.c=.o)
|
||||
admin_OBJECTS := $(admin_SOURCES:.c=.o)
|
||||
|
||||
all_plugins := $(plugin_example_TARGET) $(plugin_logging_TARGET) $(plugin_auth_TARGET) $(plugin_auth_sqlite_TARGET) $(plugin_welcome_TARGET) $(plugin_chat_history_TARGET) $(plugin_chat_only_TARGET)
|
||||
all_OBJECTS := $(libuhub_OBJECTS) $(uhub_OBJECTS) $(libutils_OBJECTS) $(adcrush_OBJECTS) $(autotest_OBJECTS) $(admin_OBJECTS) $(libadc_common_OBJECTS) $(libadc_client_OBJECTS)
|
||||
all_OBJECTS += $(all_plugins)
|
||||
|
||||
uhub_BINARY=uhub$(BIN_EXT)
|
||||
uhub-passwd_BINARY=uhub-passwd$(BIN_EXT)
|
||||
adcrush_BINARY=adcrush$(BIN_EXT)
|
||||
admin_BINARY=uhub-admin$(BIN_EXT)
|
||||
autotest_BINARY=autotest/test$(BIN_EXT)
|
||||
|
||||
|
||||
.PHONY: revision.h.tmp all plugins
|
||||
|
||||
%.o: %.c version.h revision.h
|
||||
$(MSG_CC) $(CC) -fPIC -c $(CFLAGS) -o $@ $<
|
||||
|
||||
|
||||
#%.so: %.c
|
||||
# $(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
||||
|
||||
|
||||
all: $(uhub_BINARY) $(uhub-passwd_BINARY) plugins
|
||||
|
||||
plugins: $(uhub_BINARY) $(all_plugins)
|
||||
|
||||
$(plugin_auth_TARGET): $(plugin_auth_SOURCES) $(libutils_OBJECTS)
|
||||
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
||||
|
||||
$(plugin_auth_sqlite_TARGET): $(plugin_auth_sqlite_SOURCES) $(libutils_OBJECTS)
|
||||
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS) $(LDFLAGS) $(plugin_auth_sqlite_LIBS)
|
||||
|
||||
$(plugin_example_TARGET): $(plugin_example_SOURCES) $(libutils_OBJECTS)
|
||||
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
||||
|
||||
$(plugin_logging_TARGET): $(plugin_logging_SOURCES) $(libutils_OBJECTS) $(libadc_common_OBJECTS) src/network/network.o
|
||||
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
||||
|
||||
$(plugin_chat_history_TARGET): $(plugin_chat_history_SOURCE) $(libutils_OBJECTS)
|
||||
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
||||
|
||||
$(plugin_chat_only_TARGET): $(plugin_chat_only_SOURCE) $(libutils_OBJECTS)
|
||||
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
||||
|
||||
$(plugin_welcome_TARGET): $(plugin_welcome_SOURCES) $(libutils_OBJECTS)
|
||||
$(MSG_CC) $(CC) -shared -fPIC -o $@ $^ $(CFLAGS)
|
||||
|
||||
$(adcrush_BINARY): $(adcrush_OBJECTS) $(libuhub_OBJECTS) $(libutils_OBJECTS) $(libadc_common_OBJECTS) $(libadc_client_OBJECTS)
|
||||
$(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
|
||||
|
||||
$(admin_BINARY): $(admin_OBJECTS) $(libuhub_OBJECTS) $(libutils_OBJECTS) $(libadc_common_OBJECTS) $(libadc_client_OBJECTS)
|
||||
$(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
|
||||
|
||||
$(uhub_BINARY): $(uhub_OBJECTS) $(libuhub_OBJECTS) $(libutils_OBJECTS) $(libadc_common_OBJECTS)
|
||||
$(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
|
||||
|
||||
$(uhub-passwd_BINARY): $(uhub-passwd_OBJECTS)
|
||||
$(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS) $(uhub-passwd_LIBS)
|
||||
|
||||
|
||||
autotest.c: $(autotest_SOURCES)
|
||||
$(shell exotic --standalone $(autotest_SOURCES) > $@)
|
||||
|
||||
revision.h.tmp:
|
||||
@rm -f $@
|
||||
@echo "/* AUTOGENERATED FILE - DO NOT EDIT */" > $@
|
||||
@if [ -n '$(GIT_VERSION)' ]; then echo \#define GIT_VERSION \"$(GIT_VERSION)\" >> $@; fi
|
||||
@if [ -n '$(GIT_REVISION)' ]; then echo \#define GIT_REVISION \"$(GIT_REVISION)\" >> $@; fi
|
||||
|
||||
version.h: revision.h
|
||||
|
||||
revision.h: revision.h.tmp
|
||||
@if [ '$(GIT_REVISION)' != '$(OLD_REVISION)' ]; then cp $@.tmp $@; fi
|
||||
@if [ ! -f $@ ]; then cp $@.tmp $@; fi
|
||||
|
||||
$(autotest_OBJECTS): autotest.c
|
||||
$(MSG_CC) $(CC) -c $(CFLAGS) -Isrc -o $@ $<
|
||||
|
||||
$(autotest_BINARY): $(autotest_OBJECTS) $(libuhub_OBJECTS) $(libutils_OBJECTS) $(libadc_common_OBJECTS) $(libadc_client_OBJECTS)
|
||||
$(MSG_LD) $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
|
||||
|
||||
autotest: $(autotest_BINARY)
|
||||
@./$(autotest_BINARY) -s -f
|
||||
|
||||
ifeq ($(WINDOWS),YES)
|
||||
install:
|
||||
@echo "Cannot install automatically on windows."
|
||||
else
|
||||
install: $(uhub_BINARY)
|
||||
@echo Copying $(uhub_BINARY) to $(UHUB_PREFIX)/bin/
|
||||
@cp $(uhub_BINARY) $(UHUB_PREFIX)/bin/
|
||||
@cp $(uhub-passwd_BINARY) $(UHUB_PREFIX)/bin/
|
||||
@if [ ! -d $(UHUB_CONF_DIR) ]; then echo Creating $(UHUB_CONF_DIR); mkdir -p $(UHUB_CONF_DIR); fi
|
||||
@if [ ! -f $(UHUB_CONF_DIR)/uhub.conf ]; then cp doc/uhub.conf $(UHUB_CONF_DIR); fi
|
||||
@if [ ! -f $(UHUB_CONF_DIR)/rules.txt ]; then cp doc/rules.txt $(UHUB_CONF_DIR); fi
|
||||
@if [ ! -f $(UHUB_CONF_DIR)/plugins.conf ]; then cp doc/plugins.conf $(UHUB_CONF_DIR); fi
|
||||
@if [ ! -d $(UHUB_MOD_DIR) ]; then echo Creating $(UHUB_MOD_DIR); mkdir -p $(UHUB_MOD_DIR); fi
|
||||
@cp -f mod_*.so $(UHUB_MOD_DIR)
|
||||
@touch $(UHUB_CONF_DIR)/motd.txt
|
||||
@echo done.
|
||||
endif
|
||||
|
||||
dist-clean:
|
||||
@rm -rf $(all_OBJECTS) *~ core
|
||||
|
||||
clean:
|
||||
@rm -rf $(libuhub_OBJECTS) *~ core $(uhub_BINARY) $(admin_BINARY) $(autotest_BINARY) $(adcrush_BINARY) $(all_OBJECTS) $(all_plugins) autotest.c revision.h revision.h.tmp && \
|
||||
echo $(MSG_CLEAN)
|
||||
|
||||
|
@ -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://www.adcportal.com/wiki/index.php/ADC_Software_List#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 ..
|
||||
|
||||
|
372
autotest/exotic
372
autotest/exotic
@ -1,372 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
# exotic 0.4
|
||||
# Copyright (c) 2007-2012, Jan Vidar Krey
|
||||
|
||||
use strict;
|
||||
|
||||
my $program = $0;
|
||||
my $file;
|
||||
my $line;
|
||||
my @tests;
|
||||
my $found;
|
||||
my $test;
|
||||
my @files;
|
||||
|
||||
if ($#ARGV == -1)
|
||||
{
|
||||
die "Usage: $program files\n";
|
||||
}
|
||||
|
||||
my $version = "0.4";
|
||||
|
||||
foreach my $arg (@ARGV)
|
||||
{
|
||||
push(@files, $arg);
|
||||
}
|
||||
|
||||
|
||||
print "/* THIS FILE IS AUTOMATICALLY GENERATED BY EXOTIC - DO NOT EDIT THIS FILE! */\n";
|
||||
print "/* exotic/$version (Mon Nov 7 11:15:31 CET 2011) */\n\n";
|
||||
|
||||
print "#define __EXOTIC__STANDALONE__\n";
|
||||
standalone_include_exotic_h();
|
||||
|
||||
if ($#ARGV >= 0)
|
||||
{
|
||||
foreach $file (@ARGV)
|
||||
{
|
||||
$found = 0;
|
||||
open( FILE, "$file") || next;
|
||||
my @data = <FILE>;
|
||||
my $comment = 0;
|
||||
|
||||
foreach $line (@data) {
|
||||
chomp($line);
|
||||
|
||||
if ($comment == 1)
|
||||
{
|
||||
if ($line =~ /^(.*\*\/)(.*)/)
|
||||
{
|
||||
$line = $2;
|
||||
$comment = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
next; # ignore comment data
|
||||
}
|
||||
}
|
||||
|
||||
if ($line =~ /^(.*)\/\*(.*)\*\/(.*)$/)
|
||||
{
|
||||
$line = $1 . " " . $3; # exclude comment stuff in between "/*" and "*/".
|
||||
}
|
||||
|
||||
if ($line =~ /^(.*)(\/\/.*)$/) {
|
||||
$line = $1; # exclude stuff after "//" (FIXME: does not work if they are inside a string)
|
||||
}
|
||||
|
||||
if ($line =~ /\/\*/) {
|
||||
$comment = 1;
|
||||
next;
|
||||
}
|
||||
|
||||
if ($line =~ /^\s*EXO_TEST\(\s*(\w+)\s*,/)
|
||||
{
|
||||
$found++;
|
||||
push(@tests, $1);
|
||||
}
|
||||
}
|
||||
|
||||
if ($found > 0) {
|
||||
print "#include \"" . $file . "\"\n";
|
||||
}
|
||||
|
||||
close(FILE);
|
||||
}
|
||||
print "\n";
|
||||
}
|
||||
|
||||
# Write a main() that will start the test run
|
||||
print "int main(int argc, char** argv)\n{\n";
|
||||
print "\tstruct exotic_handle handle;\n\n";
|
||||
print "\tif (exotic_initialize(&handle, argc, argv) == -1)\n\t\treturn -1;\n\n";
|
||||
|
||||
if ($#tests > 0)
|
||||
{
|
||||
print "\t/* Register the tests to be run */\n";
|
||||
foreach $test (@tests)
|
||||
{
|
||||
print "\texotic_add_test(&handle, &exotic_test_" . $test . ", \"" . $test . "\");\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
print "\t/* No tests are found! */\n";
|
||||
}
|
||||
|
||||
print "\n";
|
||||
print "\treturn exotic_run(&handle);\n";
|
||||
print "}\n\n";
|
||||
|
||||
|
||||
standalone_include_exotic_c();
|
||||
|
||||
sub standalone_include_exotic_h {
|
||||
print '
|
||||
/*
|
||||
* Exotic (EXtatic.Org Test InfrastuCture)
|
||||
* Copyright (c) 2007, Jan Vidar Krey
|
||||
*/
|
||||
|
||||
#ifndef EXO_TEST
|
||||
#define EXO_TEST(NAME, block) int exotic_test_ ## NAME (void) block
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_EXOTIC_AUTOTEST_H
|
||||
#define HAVE_EXOTIC_AUTOTEST_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef int(*exo_test_t)();
|
||||
|
||||
enum exo_toggle { cfg_default, cfg_off, cfg_on };
|
||||
|
||||
struct exotic_handle
|
||||
{
|
||||
enum exo_toggle config_show_summary;
|
||||
enum exo_toggle config_show_pass;
|
||||
enum exo_toggle config_show_fail;
|
||||
unsigned int fail;
|
||||
unsigned int pass;
|
||||
struct exo_test_data* first;
|
||||
struct exo_test_data* current;
|
||||
};
|
||||
|
||||
extern int exotic_initialize(struct exotic_handle* handle, int argc, char** argv);
|
||||
extern void exotic_add_test(struct exotic_handle* handle, exo_test_t, const char* name);
|
||||
extern int exotic_run(struct exotic_handle* handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_EXOTIC_AUTOTEST_H */
|
||||
|
||||
'; }
|
||||
sub standalone_include_exotic_c {
|
||||
print '
|
||||
/*
|
||||
* Exotic - C/C++ source code testing
|
||||
* Copyright (c) 2007, Jan Vidar Krey
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static void exotic_version();
|
||||
|
||||
#ifndef __EXOTIC__STANDALONE__
|
||||
#include "autotest.h"
|
||||
static void exotic_version()
|
||||
{
|
||||
printf("Extatic.org Test Infrastructure: exotic " "${version}" "\n\n");
|
||||
printf("Copyright (C) 2007 Jan Vidar Krey, janvidar@extatic.org\n");
|
||||
printf("This is free software with ABSOLUTELY NO WARRANTY.\n\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
struct exo_test_data
|
||||
{
|
||||
exo_test_t test;
|
||||
char* name;
|
||||
struct exo_test_data* next;
|
||||
};
|
||||
|
||||
|
||||
static void exotic_summary(struct exotic_handle* handle)
|
||||
{
|
||||
int total = handle->pass + handle->fail;
|
||||
int pass_rate = total ? (100*handle->pass / total) : 0;
|
||||
int fail_rate = total ? (100*handle->fail / total) : 0;
|
||||
|
||||
printf("\n");
|
||||
printf("--------------------------------------------\n");
|
||||
printf("Results:\n");
|
||||
printf(" * Total tests run: %8d\n", total);
|
||||
printf(" * Tests passed: %8d (~%d%%)\n", (int) handle->pass, pass_rate);
|
||||
printf(" * Tests failed: %8d (~%d%%)\n", (int) handle->fail, fail_rate);
|
||||
printf("--------------------------------------------\n");
|
||||
}
|
||||
|
||||
|
||||
static void exotic_help(const char* program)
|
||||
{
|
||||
printf("Usage: %s [OPTIONS]\n\n", program);
|
||||
printf("Options:\n");
|
||||
printf(" --help -h Show this message\n");
|
||||
printf(" --version -v Show version\n");
|
||||
printf(" --summary -s show only summary)\n");
|
||||
printf(" --fail -f show only test failures\n");
|
||||
printf(" --pass -p show only test passes\n");
|
||||
printf("\nExamples:\n");
|
||||
printf(" %s -s -f\n\n", program);
|
||||
}
|
||||
|
||||
|
||||
int exotic_initialize(struct exotic_handle* handle, int argc, char** argv)
|
||||
{
|
||||
int n;
|
||||
if (!handle || !argv) return -1;
|
||||
|
||||
memset(handle, 0, sizeof(struct exotic_handle));
|
||||
|
||||
for (n = 1; n < argc; n++)
|
||||
{
|
||||
if (!strcmp(argv[n], "-h") || !strcmp(argv[n], "--help"))
|
||||
{
|
||||
exotic_help(argv[0]);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (!strcmp(argv[n], "-v") || !strcmp(argv[n], "--version"))
|
||||
{
|
||||
exotic_version();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (!strcmp(argv[n], "-s") || !strcmp(argv[n], "--summary"))
|
||||
{
|
||||
handle->config_show_summary = cfg_on;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[n], "-f") || !strcmp(argv[n], "--fail"))
|
||||
{
|
||||
handle->config_show_fail = cfg_on;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[n], "-p") || !strcmp(argv[n], "--pass"))
|
||||
{
|
||||
handle->config_show_pass = cfg_on;
|
||||
continue;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Unknown argument: %s\n\n", argv[n]);
|
||||
exotic_help(argv[0]);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (handle->config_show_summary == cfg_on)
|
||||
{
|
||||
if (handle->config_show_pass == cfg_default) handle->config_show_pass = cfg_off;
|
||||
if (handle->config_show_fail == cfg_default) handle->config_show_fail = cfg_off;
|
||||
|
||||
}
|
||||
else if (handle->config_show_pass == cfg_on)
|
||||
{
|
||||
if (handle->config_show_summary == cfg_default) handle->config_show_summary = cfg_off;
|
||||
if (handle->config_show_fail == cfg_default) handle->config_show_fail = cfg_off;
|
||||
}
|
||||
else if (handle->config_show_fail == cfg_on)
|
||||
{
|
||||
if (handle->config_show_summary == cfg_default) handle->config_show_summary = cfg_off;
|
||||
if (handle->config_show_fail == cfg_default) handle->config_show_fail = cfg_off;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (handle->config_show_summary == cfg_default) handle->config_show_summary = cfg_on;
|
||||
if (handle->config_show_fail == cfg_default) handle->config_show_fail = cfg_on;
|
||||
if (handle->config_show_pass == cfg_default) handle->config_show_pass = cfg_on;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void exotic_add_test(struct exotic_handle* handle, exo_test_t func, const char* name)
|
||||
{
|
||||
struct exo_test_data* test;
|
||||
if (!handle)
|
||||
{
|
||||
fprintf(stderr, "exotic_add_test: failed, no handle!\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
test = (struct exo_test_data*) malloc(sizeof(struct exo_test_data));
|
||||
if (!test)
|
||||
{
|
||||
fprintf(stderr, "exotic_add_test: out of memory!\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* Create the test */
|
||||
memset(test, 0, sizeof(struct exo_test_data));
|
||||
test->test = func;
|
||||
test->name = strdup(name);
|
||||
|
||||
/* Register the test in the handle */
|
||||
if (!handle->first)
|
||||
{
|
||||
handle->first = test;
|
||||
handle->current = test;
|
||||
}
|
||||
else
|
||||
{
|
||||
handle->current->next = test;
|
||||
handle->current = test;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int exotic_run(struct exotic_handle* handle)
|
||||
{
|
||||
struct exo_test_data* tmp = NULL;
|
||||
|
||||
if (!handle)
|
||||
{
|
||||
fprintf(stderr, "Error: exotic is not initialized\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
handle->current = handle->first;
|
||||
while (handle->current)
|
||||
{
|
||||
tmp = handle->current;
|
||||
|
||||
if (handle->current->test()) {
|
||||
if (handle->config_show_pass == cfg_on) printf("* PASS test \'%s\'\n", tmp->name);
|
||||
handle->pass++;
|
||||
} else {
|
||||
if (handle->config_show_fail == cfg_on) printf("* FAIL test \'%s\'\n", tmp->name);
|
||||
handle->fail++;
|
||||
}
|
||||
|
||||
handle->current = handle->current->next;
|
||||
|
||||
free(tmp->name);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
if (!handle->first)
|
||||
{
|
||||
printf("(No tests added)\n");
|
||||
}
|
||||
|
||||
if (handle->config_show_summary == cfg_on)
|
||||
exotic_summary(handle);
|
||||
|
||||
return (handle->fail) ? handle->fail : 0;
|
||||
}
|
||||
|
||||
|
||||
static void exotic_version() {
|
||||
printf("exotic 0.4-standalone\n\n");
|
||||
printf("Copyright (C) 2007 Jan Vidar Krey, janvidar@extatic.org\n");
|
||||
printf("This is free software with ABSOLUTELY NO WARRANTY.\n\n");
|
||||
}
|
||||
'; }
|
||||
|
1070
autotest/test.c
1070
autotest/test.c
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,6 @@
|
||||
#include <uhub.h>
|
||||
|
||||
static struct hub_info* hub = NULL;
|
||||
static struct hub_command* cmd = NULL;
|
||||
static struct hub_user user;
|
||||
static struct command_base* cbase = NULL;
|
||||
static struct command_handle* c_test1 = NULL;
|
||||
@ -18,14 +17,11 @@ static int result = 0;
|
||||
EXO_TEST(setup, {
|
||||
hub = hub_malloc_zero(sizeof(struct hub_info));
|
||||
cbase = command_initialize(hub);
|
||||
hub->commands = cbase;
|
||||
hub->users = uman_init();
|
||||
return cbase && hub && hub->users;
|
||||
return cbase && hub && uman_init(hub) == 0;
|
||||
});
|
||||
|
||||
static int test_handler(struct command_base* cbase, struct hub_user* user, struct hub_command* hcmd)
|
||||
{
|
||||
printf("test_handler\n");
|
||||
result = 1;
|
||||
return 0;
|
||||
}
|
||||
@ -39,7 +35,7 @@ static struct command_handle* create_handler(const char* prefix, const char* arg
|
||||
c->cred = cred;
|
||||
c->handler = test_handler;
|
||||
c->description = "A handler added by autotest.";
|
||||
c->origin = "exotic test";
|
||||
c->description = "exotic";
|
||||
c->ptr = &c->ptr;
|
||||
return c;
|
||||
}
|
||||
@ -71,7 +67,7 @@ EXO_TEST(command_create, {
|
||||
ADD_TEST(c_test1, "test1", "", auth_cred_guest);
|
||||
ADD_TEST(c_test2, "test2", "", auth_cred_operator);
|
||||
ADD_TEST(c_test3, "test3", "N?N?N", auth_cred_guest);
|
||||
ADD_TEST(c_test4, "test4", "u", auth_cred_guest);
|
||||
ADD_TEST(c_test4, "test4", "n", auth_cred_guest);
|
||||
ADD_TEST(c_test5, "test5", "i", auth_cred_guest);
|
||||
ADD_TEST(c_test6, "test6", "?c", auth_cred_guest);
|
||||
ADD_TEST(c_test6, "test7", "C", auth_cred_guest);
|
||||
@ -82,36 +78,12 @@ extern void command_destroy(struct hub_command* cmd);
|
||||
|
||||
static int verify(const char* str, enum command_parse_status expected)
|
||||
{
|
||||
struct hub_command* cmd = command_parse(cbase, hub, &user, str);
|
||||
struct hub_command* cmd = command_parse(cbase, &user, str);
|
||||
enum command_parse_status status = cmd->status;
|
||||
command_free(cmd);
|
||||
return status == expected;
|
||||
}
|
||||
|
||||
static struct hub_command_arg_data* verify_argument(struct hub_command* cmd, enum hub_command_arg_type type)
|
||||
{
|
||||
return hub_command_arg_next(cmd, type);
|
||||
}
|
||||
|
||||
static int verify_arg_integer(struct hub_command* cmd, int expected)
|
||||
{
|
||||
struct hub_command_arg_data* data = verify_argument(cmd, type_integer);
|
||||
return data->data.integer == expected;
|
||||
}
|
||||
|
||||
static int verify_arg_user(struct hub_command* cmd, struct hub_user* expected)
|
||||
{
|
||||
struct hub_command_arg_data* data = verify_argument(cmd, type_user);
|
||||
return data->data.user == expected;
|
||||
}
|
||||
|
||||
static int verify_arg_cred(struct hub_command* cmd, enum auth_credentials cred)
|
||||
{
|
||||
struct hub_command_arg_data* data = verify_argument(cmd, type_credentials);
|
||||
return data->data.credentials == cred;
|
||||
}
|
||||
|
||||
|
||||
EXO_TEST(command_access_1, { return verify("!test1", cmd_status_ok); });
|
||||
EXO_TEST(command_access_2, { return verify("!test2", cmd_status_access_error); });
|
||||
EXO_TEST(command_access_3, { user.credentials = auth_cred_operator; return verify("!test2", cmd_status_ok); });
|
||||
@ -128,7 +100,7 @@ EXO_TEST(command_number_3, { return verify("!test3 -12", cmd_status_ok); });
|
||||
|
||||
EXO_TEST(command_user_1, { return verify("!test4 tester", cmd_status_arg_nick); });
|
||||
EXO_TEST(command_user_2, { return verify("!test5 3AGHMAASJA2RFNM22AA6753V7B7DYEPNTIWHBAY", cmd_status_arg_cid); });
|
||||
EXO_TEST(command_user_3, { return uman_add(hub->users, &user) == 0; });
|
||||
EXO_TEST(command_user_3, { return uman_add(hub, &user) == 0; });
|
||||
EXO_TEST(command_user_4, { return verify("!test4 tester", cmd_status_ok); });
|
||||
EXO_TEST(command_user_5, { return verify("!test5 3AGHMAASJA2RFNM22AA6753V7B7DYEPNTIWHBAY", cmd_status_ok); });
|
||||
|
||||
@ -162,77 +134,7 @@ EXO_TEST(command_parse_3, { return verify("!fail", cmd_status_not_found); });
|
||||
// built-in command
|
||||
EXO_TEST(command_parse_4, { return verify("!help", cmd_status_ok); });
|
||||
|
||||
|
||||
#define SETUP_COMMAND(string) \
|
||||
do { \
|
||||
if (cmd) command_free(cmd); \
|
||||
cmd = command_parse(cbase, hub, &user, string); \
|
||||
} while(0)
|
||||
|
||||
EXO_TEST(command_argument_integer_1, {
|
||||
SETUP_COMMAND("!test3");
|
||||
return verify_argument(cmd, type_integer) == NULL;
|
||||
});
|
||||
|
||||
EXO_TEST(command_argument_integer_2, {
|
||||
SETUP_COMMAND("!test3 10 42");
|
||||
return verify_arg_integer(cmd, 10) && verify_arg_integer(cmd, 42) && verify_argument(cmd, type_integer) == NULL;
|
||||
});
|
||||
|
||||
EXO_TEST(command_argument_integer_3, {
|
||||
SETUP_COMMAND("!test3 10 42 6784");
|
||||
return verify_arg_integer(cmd, 10) && verify_arg_integer(cmd, 42) && verify_arg_integer(cmd, 6784);
|
||||
});
|
||||
|
||||
EXO_TEST(command_argument_user_1, {
|
||||
SETUP_COMMAND("!test4 tester");
|
||||
return verify_arg_user(cmd, &user) ;
|
||||
});
|
||||
|
||||
EXO_TEST(command_argument_cid_1, {
|
||||
SETUP_COMMAND("!test5 3AGHMAASJA2RFNM22AA6753V7B7DYEPNTIWHBAY");
|
||||
return verify_arg_user(cmd, &user) ;
|
||||
});
|
||||
|
||||
EXO_TEST(command_argument_cred_1, {
|
||||
SETUP_COMMAND("!test7 admin");
|
||||
return verify_arg_cred(cmd, auth_cred_admin);;
|
||||
});
|
||||
|
||||
EXO_TEST(command_argument_cred_2, {
|
||||
SETUP_COMMAND("!test7 op");
|
||||
return verify_arg_cred(cmd, auth_cred_operator);;
|
||||
});
|
||||
|
||||
EXO_TEST(command_argument_cred_3, {
|
||||
SETUP_COMMAND("!test7 operator");
|
||||
return verify_arg_cred(cmd, auth_cred_operator);
|
||||
});
|
||||
|
||||
EXO_TEST(command_argument_cred_4, {
|
||||
SETUP_COMMAND("!test7 super");
|
||||
return verify_arg_cred(cmd, auth_cred_super);
|
||||
});
|
||||
|
||||
EXO_TEST(command_argument_cred_5, {
|
||||
SETUP_COMMAND("!test7 guest");
|
||||
return verify_arg_cred(cmd, auth_cred_guest);
|
||||
});
|
||||
|
||||
EXO_TEST(command_argument_cred_6, {
|
||||
SETUP_COMMAND("!test7 user");
|
||||
return verify_arg_cred(cmd, auth_cred_user);
|
||||
});
|
||||
|
||||
#undef SETUP_COMMAND
|
||||
|
||||
EXO_TEST(command_user_destroy, { return uman_remove(hub->users, &user) == 0; });
|
||||
|
||||
EXO_TEST(command_destroy, {
|
||||
|
||||
command_free(cmd);
|
||||
cmd = NULL;
|
||||
|
||||
DEL_TEST(c_test1);
|
||||
DEL_TEST(c_test2);
|
||||
DEL_TEST(c_test3);
|
||||
@ -242,10 +144,3 @@ EXO_TEST(command_destroy, {
|
||||
DEL_TEST(c_test7);
|
||||
return 1;
|
||||
});
|
||||
|
||||
EXO_TEST(cleanup, {
|
||||
uman_shutdown(hub->users);
|
||||
command_shutdown(hub->commands);
|
||||
hub_free(hub);
|
||||
return 1;
|
||||
});
|
||||
|
@ -12,10 +12,11 @@ extern int hub_handle_info_login(struct hub_info* hub, struct hub_user* user, st
|
||||
|
||||
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,13 +26,15 @@ 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);
|
||||
net_destroy();
|
||||
}
|
||||
|
||||
|
||||
@ -60,14 +63,13 @@ EXO_TEST(inf_create_setup,
|
||||
|
||||
/* FIXME: MEMORY LEAK - Need to fix hub_handle_info_login */
|
||||
#define CHECK_INF(MSG, EXPECT) \
|
||||
do { \
|
||||
struct adc_message* msg = adc_msg_parse_verify(inf_user, MSG, strlen(MSG)); \
|
||||
int ok = hub_handle_info_login(inf_hub, inf_user, msg); /* FIXME: MEMORY LEAK */ \
|
||||
adc_msg_free(msg); \
|
||||
if (ok == EXPECT) \
|
||||
user_set_info(inf_user, 0); \
|
||||
return ok == EXPECT; \
|
||||
} while(0)
|
||||
struct adc_message* msg = adc_msg_parse_verify(inf_user, MSG, strlen(MSG)); \
|
||||
int ok = hub_handle_info_login(inf_hub, inf_user, msg); /* FIXME: MEMORY LEAK */ \
|
||||
adc_msg_free(msg); \
|
||||
if (ok == EXPECT) \
|
||||
user_set_info(inf_user, 0); \
|
||||
return ok == EXPECT;
|
||||
|
||||
|
||||
EXO_TEST(inf_ok_1, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", 0); });
|
||||
|
||||
@ -105,15 +107,12 @@ EXO_TEST(inf_nick_08, { CHECK_INF("BINF AAAB NIa\\nc IDGNSSMURMD7K466NGZIHU65TP3
|
||||
EXO_TEST(inf_nick_09, { CHECK_INF("BINF AAAB NIabc NIdef IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_nick_multiple); });
|
||||
EXO_TEST(inf_nick_10, {
|
||||
const char* line = "BINF AAAB IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n";
|
||||
int ok;
|
||||
char nick[10];
|
||||
struct adc_message* msg;
|
||||
|
||||
nick[0] = 0xf7; nick[1] = 0x80; nick[2] = 0x7f; nick[3] = 0x81; nick[4] = 0x98; nick[5] = 0x00;
|
||||
msg = adc_msg_parse_verify(inf_user, line, strlen(line));
|
||||
struct adc_message* msg = adc_msg_parse_verify(inf_user, line, strlen(line));
|
||||
|
||||
adc_msg_add_named_argument(msg, "NI", nick);
|
||||
ok = hub_handle_info_login(inf_hub, inf_user, msg);
|
||||
int ok = hub_handle_info_login(inf_hub, inf_user, msg);
|
||||
adc_msg_free(msg);
|
||||
if (ok != status_msg_inf_error_nick_not_utf8)
|
||||
printf("Expected %d, got %d\n", status_msg_inf_error_nick_not_utf8, ok);
|
||||
|
@ -429,51 +429,44 @@ EXO_TEST(check_ban_ipv4_5, {
|
||||
});
|
||||
|
||||
EXO_TEST(check_ban_ipv6_1, {
|
||||
struct ip_addr_encap addr;
|
||||
if (!ipv6) return 1;
|
||||
ip_convert_to_binary("2001::201:2ff:fefa:0", &addr);
|
||||
struct ip_addr_encap addr; ip_convert_to_binary("2001::201:2ff:fefa:0", &addr);
|
||||
return ip_in_range(&addr, &ban6);
|
||||
});
|
||||
|
||||
EXO_TEST(check_ban_ipv6_2, {
|
||||
struct ip_addr_encap addr;
|
||||
if (!ipv6) return 1;
|
||||
ip_convert_to_binary("2001::201:2ff:fefa:1", &addr);
|
||||
struct ip_addr_encap addr; ip_convert_to_binary("2001::201:2ff:fefa:1", &addr);
|
||||
return ip_in_range(&addr, &ban6);
|
||||
});
|
||||
|
||||
EXO_TEST(check_ban_ipv6_3, {
|
||||
struct ip_addr_encap addr;
|
||||
if (!ipv6) return 1;
|
||||
ip_convert_to_binary("2001::201:2ff:fefa:fffe", &addr);
|
||||
struct ip_addr_encap addr; ip_convert_to_binary("2001::201:2ff:fefa:fffe", &addr);
|
||||
return ip_in_range(&addr, &ban6);
|
||||
});
|
||||
|
||||
EXO_TEST(check_ban_ipv6_4, {
|
||||
struct ip_addr_encap addr;
|
||||
if (!ipv6) return 1;
|
||||
ip_convert_to_binary("2001::201:2ff:fefa:ffff", &addr);
|
||||
struct ip_addr_encap addr; ip_convert_to_binary("2001::201:2ff:fefa:ffff", &addr);
|
||||
return ip_in_range(&addr, &ban6);
|
||||
});
|
||||
|
||||
EXO_TEST(check_ban_ipv6_5, {
|
||||
struct ip_addr_encap addr;
|
||||
if (!ipv6) return 1;
|
||||
ip_convert_to_binary("2001::201:2ff:fefb:0", &addr);
|
||||
struct ip_addr_encap addr; ip_convert_to_binary("2001::201:2ff:fefb:0", &addr);
|
||||
return !ip_in_range(&addr, &ban6);
|
||||
});
|
||||
|
||||
EXO_TEST(check_ban_ipv6_6, {
|
||||
struct ip_addr_encap addr;
|
||||
if (!ipv6) return 1;
|
||||
ip_convert_to_binary("2001::201:2ff:fef9:ffff", &addr);
|
||||
struct ip_addr_encap addr; ip_convert_to_binary("2001::201:2ff:fef9:ffff", &addr);
|
||||
return !ip_in_range(&addr, &ban6);
|
||||
});
|
||||
|
||||
EXO_TEST(check_ban_afmix_1, {
|
||||
struct ip_addr_encap addr;
|
||||
if (!ipv6) return 1;
|
||||
ip_convert_to_binary("2001::201:2ff:fef9:ffff", &addr);
|
||||
struct ip_addr_encap addr; ip_convert_to_binary("2001::201:2ff:fef9:ffff", &addr);
|
||||
return !ip_in_range(&addr, &ban4);
|
||||
});
|
||||
|
||||
@ -617,10 +610,8 @@ EXO_TEST(ip_range_3, {
|
||||
});
|
||||
|
||||
EXO_TEST(ip_range_4, {
|
||||
struct ip_range range1;
|
||||
struct ip_range range2;
|
||||
memset(&range1, 0, sizeof(range1));
|
||||
memset(&range2, 0, sizeof(range2));
|
||||
struct ip_range range1; memset(&range1, 0, sizeof(range1));
|
||||
struct ip_range range2; memset(&range2, 0, sizeof(range2));
|
||||
return ip_convert_address_to_range("192.168.0.0/16", &range1) && ip_convert_address_to_range("192.168.0.0-192.168.255.255", &range2) && memcmp(&range1, &range2, sizeof(struct ip_range)) == 0;
|
||||
});
|
||||
|
||||
|
@ -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);
|
||||
|
@ -174,102 +174,91 @@ EXO_TEST(adc_message_parse_24, {
|
||||
|
||||
|
||||
EXO_TEST(adc_message_add_arg_1, {
|
||||
int ok;
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_add_argument(msg, "XXwtf?");
|
||||
ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat XXwtf?\n") == 0;
|
||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat XXwtf?\n") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_add_arg_2, {
|
||||
int ok;
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_add_named_argument(msg, "XX", "wtf?");
|
||||
ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat XXwtf?\n") == 0;
|
||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat XXwtf?\n") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_remove_arg_1, {
|
||||
int ok;
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_remove_named_argument(msg, "AA");
|
||||
ok = strcmp(msg->cache, "IINF BBbar CCwhat\n") == 0;
|
||||
int ok = strcmp(msg->cache, "IINF BBbar CCwhat\n") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_remove_arg_2, {
|
||||
int ok;
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_remove_named_argument(msg, "BB");
|
||||
ok = strcmp(msg->cache, "IINF AAfoo CCwhat\n") == 0;
|
||||
int ok = strcmp(msg->cache, "IINF AAfoo CCwhat\n") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_remove_arg_3, {
|
||||
int ok;
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_remove_named_argument(msg, "CC");
|
||||
ok = strcmp(msg->cache, "IINF AAfoo BBbar\n") == 0;
|
||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar\n") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_remove_arg_4, {
|
||||
/* this ensures we can remove the last element also */
|
||||
int ok;
|
||||
struct adc_message* msg = adc_msg_parse_verify(g_user, test_string3, strlen(test_string3));
|
||||
adc_msg_remove_named_argument(msg, "AW");
|
||||
ok = strcmp(msg->cache, "BINF AAAB IDAN7ZMSLIEBL53OPTM7WXGSTXUS3XOY6KQS5LBGX NIFriend DEstuff SL3 SS0 SF0 VEQuickDC/0.4.17 US6430 SUADC0,TCP4,UDP4 I4127.0.0.1 HO5 HN1\n") == 0;
|
||||
int ok = strcmp(msg->cache, "BINF AAAB IDAN7ZMSLIEBL53OPTM7WXGSTXUS3XOY6KQS5LBGX NIFriend DEstuff SL3 SS0 SF0 VEQuickDC/0.4.17 US6430 SUADC0,TCP4,UDP4 I4127.0.0.1 HO5 HN1\n") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_replace_arg_1, {
|
||||
int ok;
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_remove_named_argument(msg, "AA");
|
||||
ok = strcmp(msg->cache, "IINF BBbar CCwhat\n") == 0;
|
||||
int ok = strcmp(msg->cache, "IINF BBbar CCwhat\n") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_replace_arg_2, {
|
||||
int ok;
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_remove_named_argument(msg, "BB");
|
||||
ok = strcmp(msg->cache, "IINF AAfoo CCwhat\n") == 0;
|
||||
int ok = strcmp(msg->cache, "IINF AAfoo CCwhat\n") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_replace_arg_3, {
|
||||
int ok;
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_remove_named_argument(msg, "CC");
|
||||
ok = strcmp(msg->cache, "IINF AAfoo BBbar\n") == 0;
|
||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar\n") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_get_arg_1, {
|
||||
int ok;
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
char* c = adc_msg_get_argument(msg, 0);
|
||||
ok = strcmp(c, "AAfoo") == 0;
|
||||
int ok = strcmp(c, "AAfoo") == 0;
|
||||
adc_msg_free(msg);
|
||||
hub_free(c);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_get_arg_2, {
|
||||
int ok;
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
char* c = adc_msg_get_argument(msg, 1);
|
||||
ok = strcmp(c, "BBbar") == 0;
|
||||
int ok = strcmp(c, "BBbar") == 0;
|
||||
adc_msg_free(msg);
|
||||
hub_free(c);
|
||||
return ok;
|
||||
@ -351,31 +340,28 @@ EXO_TEST(adc_message_has_named_arg_3, {
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_has_named_arg_4, {
|
||||
int n;
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_add_argument(msg, "XXwtf?");
|
||||
n = adc_msg_has_named_argument(msg, "XX");
|
||||
int n = adc_msg_has_named_argument(msg, "XX");
|
||||
adc_msg_free(msg);
|
||||
return n == 1;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_has_named_arg_5, {
|
||||
int n;
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_add_argument(msg, "XXone");
|
||||
adc_msg_add_argument(msg, "XXtwo");
|
||||
n = adc_msg_has_named_argument(msg, "XX");
|
||||
int n = adc_msg_has_named_argument(msg, "XX");
|
||||
adc_msg_free(msg);
|
||||
return n == 2;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_has_named_arg_6, {
|
||||
int n;
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_add_argument(msg, "XXone");
|
||||
adc_msg_add_argument(msg, "XXtwo");
|
||||
adc_msg_add_argument(msg, "XXthree");
|
||||
n = adc_msg_has_named_argument(msg, "XX");
|
||||
int n = adc_msg_has_named_argument(msg, "XX");
|
||||
adc_msg_free(msg);
|
||||
return n == 3;
|
||||
});
|
||||
@ -388,70 +374,63 @@ EXO_TEST(adc_message_has_named_arg_7, {
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_terminate_1, {
|
||||
int ok;
|
||||
struct adc_message* msg = adc_msg_create("IINF AAfoo BBbar CCwhat");
|
||||
adc_msg_unterminate(msg);
|
||||
ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat") == 0;
|
||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_terminate_2, {
|
||||
int ok;
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_unterminate(msg);
|
||||
adc_msg_terminate(msg);
|
||||
ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat\n") == 0;
|
||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat\n") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_terminate_3, {
|
||||
int ok;
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_unterminate(msg);
|
||||
adc_msg_terminate(msg);
|
||||
adc_msg_unterminate(msg);
|
||||
ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat") == 0;
|
||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_terminate_4, {
|
||||
int ok;
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_unterminate(msg);
|
||||
adc_msg_terminate(msg);
|
||||
adc_msg_terminate(msg);
|
||||
ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat\n") == 0;
|
||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat\n") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_terminate_5, {
|
||||
int ok;
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_terminate(msg);
|
||||
adc_msg_terminate(msg);
|
||||
ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat\n") == 0;
|
||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat\n") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_terminate_6, {
|
||||
int ok;
|
||||
struct adc_message* msg = adc_msg_create(test_string1);
|
||||
adc_msg_unterminate(msg);
|
||||
adc_msg_unterminate(msg);
|
||||
ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat") == 0;
|
||||
int ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat") == 0;
|
||||
adc_msg_free(msg);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(adc_message_escape_1, {
|
||||
int ok;
|
||||
char* s = adc_msg_escape(test_string1);
|
||||
ok = strcmp(s, "IINF\\sAAfoo\\sBBbar\\sCCwhat\\n") == 0;
|
||||
int ok = strcmp(s, "IINF\\sAAfoo\\sBBbar\\sCCwhat\\n") == 0;
|
||||
hub_free(s);
|
||||
return ok;
|
||||
});
|
||||
|
@ -97,82 +97,15 @@ EXO_TEST(base32_invalid_31, { return !is_valid_base32_char('@'); });
|
||||
EXO_TEST(utf8_valid_1, { return is_valid_utf8("abcdefghijklmnopqrstuvwxyz"); });
|
||||
EXO_TEST(utf8_valid_2, { return is_valid_utf8("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); });
|
||||
EXO_TEST(utf8_valid_3, { return is_valid_utf8("0123456789"); });
|
||||
EXO_TEST(utf8_valid_4, { return is_valid_utf8( (char[]) { 0x65, 0x00} ); });
|
||||
EXO_TEST(utf8_valid_5, { return !is_valid_utf8( (char[]) { 0xD8, 0x00} ); });
|
||||
|
||||
static const char test_utf_seq_1[] = { 0x65, 0x00 }; // valid
|
||||
static const char test_utf_seq_2[] = { 0xD8, 0x00 }; // invalid
|
||||
static const char test_utf_seq_3[] = { 0x24, 0x00 }; // valid
|
||||
static const char test_utf_seq_4[] = { 0xC2, 0x24, 0x00}; // invalid
|
||||
static const char test_utf_seq_5[] = { 0xC2, 0xA2, 0x00}; // valid
|
||||
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_6, { return is_valid_utf8( (char[]) { 0x24, 0x00} ); });
|
||||
EXO_TEST(utf8_valid_7, { return !is_valid_utf8( (char[]) { 0xC2, 0x24, 0x00} ); });
|
||||
EXO_TEST(utf8_valid_8, { return is_valid_utf8( (char[]) { 0xC2, 0xA2, 0x00} ); });
|
||||
EXO_TEST(utf8_valid_9, { return is_valid_utf8( (char[]) { 0xE2, 0x82, 0xAC, 0x00} ); });
|
||||
EXO_TEST(utf8_valid_10, { return !is_valid_utf8( (char[]) { 0xC2, 0x32, 0x00} ); });
|
||||
EXO_TEST(utf8_valid_11, { return !is_valid_utf8( (char[]) { 0xE2, 0x82, 0x32, 0x00} ); });
|
||||
EXO_TEST(utf8_valid_12, { return !is_valid_utf8( (char[]) { 0xE2, 0x32, 0x82, 0x00} ); });
|
||||
|
||||
EXO_TEST(utf8_valid_4, { return is_valid_utf8(test_utf_seq_1); });
|
||||
EXO_TEST(utf8_valid_5, { return !is_valid_utf8(test_utf_seq_2); });
|
||||
EXO_TEST(utf8_valid_6, { return is_valid_utf8(test_utf_seq_3); });
|
||||
EXO_TEST(utf8_valid_7, { return !is_valid_utf8(test_utf_seq_4); });
|
||||
EXO_TEST(utf8_valid_8, { return is_valid_utf8(test_utf_seq_5); });
|
||||
EXO_TEST(utf8_valid_9, { return is_valid_utf8(test_utf_seq_6); });
|
||||
EXO_TEST(utf8_valid_10, { return !is_valid_utf8(test_utf_seq_7); });
|
||||
EXO_TEST(utf8_valid_11, { return !is_valid_utf8(test_utf_seq_8); });
|
||||
EXO_TEST(utf8_valid_12, { return !is_valid_utf8(test_utf_seq_9); });
|
||||
EXO_TEST(utf8_valid_13, { return is_valid_utf8(test_utf_seq_10); });
|
||||
|
||||
// Limits of utf-8
|
||||
static const char test_utf_seq_11[] = { 0x7F, 0x00 }; // valid last 7-bit character
|
||||
static const char test_utf_seq_12[] = { 0x80, 0x00 }; // invalid truncated string
|
||||
static const char test_utf_seq_13[] = { 0xBF, 0x00 }; // invalid truncated string
|
||||
static const char test_utf_seq_14[] = { 0xC0, 0x80, 0x00 }; // invalid out of 2 bytes range
|
||||
static const char test_utf_seq_15[] = { 0xC1, 0x7F, 0x00 }; // invalid out of 2 bytes range
|
||||
static const char test_utf_seq_16[] = { 0xC2, 0x00 }; // invalid truncated string
|
||||
static const char test_utf_seq_17[] = { 0xC2, 0x80, 0x00 }; // valid
|
||||
static const char test_utf_seq_18[] = { 0xDF, 0xBF, 0x00 }; // valid
|
||||
static const char test_utf_seq_19[] = { 0xE0, 0x80, 0x80, 0x00 }; // invalid out of 3 bytes range
|
||||
static const char test_utf_seq_20[] = { 0xE0, 0x9F, 0xBF, 0x00 }; // invalid out of 3 bytes range
|
||||
static const char test_utf_seq_21[] = { 0xE0, 0x00 }; // invalid truncated string
|
||||
static const char test_utf_seq_22[] = { 0xE0, 0xA0, 0x00 }; // invalid truncated string
|
||||
static const char test_utf_seq_23[] = { 0xE0, 0xA0, 0x80, 0x00 }; // valid
|
||||
static const char test_utf_seq_24[] = { 0xEC, 0x9F, 0xBF, 0x00 }; // valid
|
||||
static const char test_utf_seq_25[] = { 0xED, 0xA0, 0x80, 0x00 }; // invalid surrogate
|
||||
static const char test_utf_seq_26[] = { 0xED, 0xBF, 0xBF, 0x00 }; // invalid surrogate
|
||||
static const char test_utf_seq_27[] = { 0xEF, 0x80, 0x80, 0x00 }; // valid
|
||||
static const char test_utf_seq_28[] = { 0xEF, 0xBF, 0xBF, 0x00 }; // valid
|
||||
static const char test_utf_seq_29[] = { 0xF0, 0x80, 0x80, 0x80, 0x00 }; // invalid out of 4 bytes range
|
||||
static const char test_utf_seq_30[] = { 0xF0, 0x8F, 0xBF, 0xBF, 0x00 }; // invalid out of 4 bytes range
|
||||
static const char test_utf_seq_31[] = { 0xF0, 0x00 }; // invalid truncated string
|
||||
static const char test_utf_seq_32[] = { 0xF0, 0x90, 0x00 }; // invalid truncated string
|
||||
static const char test_utf_seq_33[] = { 0xF0, 0x90, 0x80, 0x00 }; // invalid truncated string
|
||||
static const char test_utf_seq_34[] = { 0xF0, 0x90, 0x80, 0x80, 0x00 }; // valid
|
||||
static const char test_utf_seq_35[] = { 0xF4, 0x8F, 0xBF, 0xBF, 0x00 }; // valid
|
||||
static const char test_utf_seq_36[] = { 0xF4, 0x90, 0x80, 0x80, 0x00 }; // invalid out of 4 bytes range
|
||||
static const char test_utf_seq_37[] = { 0xFF, 0xBF, 0xBF, 0xBF, 0x00 }; // invalid out of 4 bytes range
|
||||
|
||||
EXO_TEST(utf8_valid_14, { return is_valid_utf8(test_utf_seq_11); });
|
||||
EXO_TEST(utf8_valid_15, { return !is_valid_utf8(test_utf_seq_12); });
|
||||
EXO_TEST(utf8_valid_16, { return !is_valid_utf8(test_utf_seq_13); });
|
||||
EXO_TEST(utf8_valid_17, { return !is_valid_utf8(test_utf_seq_14); });
|
||||
EXO_TEST(utf8_valid_18, { return !is_valid_utf8(test_utf_seq_15); });
|
||||
EXO_TEST(utf8_valid_19, { return !is_valid_utf8(test_utf_seq_16); });
|
||||
EXO_TEST(utf8_valid_20, { return is_valid_utf8(test_utf_seq_17); });
|
||||
EXO_TEST(utf8_valid_21, { return is_valid_utf8(test_utf_seq_18); });
|
||||
EXO_TEST(utf8_valid_22, { return !is_valid_utf8(test_utf_seq_19); });
|
||||
EXO_TEST(utf8_valid_23, { return !is_valid_utf8(test_utf_seq_20); });
|
||||
EXO_TEST(utf8_valid_24, { return !is_valid_utf8(test_utf_seq_21); });
|
||||
EXO_TEST(utf8_valid_25, { return !is_valid_utf8(test_utf_seq_22); });
|
||||
EXO_TEST(utf8_valid_26, { return is_valid_utf8(test_utf_seq_23); });
|
||||
EXO_TEST(utf8_valid_27, { return is_valid_utf8(test_utf_seq_24); });
|
||||
EXO_TEST(utf8_valid_28, { return !is_valid_utf8(test_utf_seq_25); });
|
||||
EXO_TEST(utf8_valid_29, { return !is_valid_utf8(test_utf_seq_26); });
|
||||
EXO_TEST(utf8_valid_30, { return is_valid_utf8(test_utf_seq_27); });
|
||||
EXO_TEST(utf8_valid_31, { return is_valid_utf8(test_utf_seq_28); });
|
||||
EXO_TEST(utf8_valid_32, { return !is_valid_utf8(test_utf_seq_29); });
|
||||
EXO_TEST(utf8_valid_33, { return !is_valid_utf8(test_utf_seq_30); });
|
||||
EXO_TEST(utf8_valid_34, { return !is_valid_utf8(test_utf_seq_31); });
|
||||
EXO_TEST(utf8_valid_35, { return !is_valid_utf8(test_utf_seq_32); });
|
||||
EXO_TEST(utf8_valid_36, { return !is_valid_utf8(test_utf_seq_33); });
|
||||
EXO_TEST(utf8_valid_37, { return is_valid_utf8(test_utf_seq_34); });
|
||||
EXO_TEST(utf8_valid_38, { return is_valid_utf8(test_utf_seq_35); });
|
||||
EXO_TEST(utf8_valid_39, { return !is_valid_utf8(test_utf_seq_36); });
|
||||
EXO_TEST(utf8_valid_40, { return !is_valid_utf8(test_utf_seq_37); });
|
||||
|
@ -1,150 +0,0 @@
|
||||
#include <uhub.h>
|
||||
#include <util/rbtree.h>
|
||||
|
||||
#define MAX_NODES 10000
|
||||
|
||||
static struct rb_tree* tree = NULL;
|
||||
|
||||
int test_tree_compare(const void* a, const void* b)
|
||||
{
|
||||
return strcmp((const char*) a, (const char*) b);
|
||||
}
|
||||
|
||||
|
||||
EXO_TEST(rbtree_create_destroy, {
|
||||
int ok = 0;
|
||||
struct rb_tree* atree;
|
||||
atree = rb_tree_create(test_tree_compare, &hub_malloc, &hub_free);
|
||||
if (atree) ok = 1;
|
||||
rb_tree_destroy(atree);
|
||||
return ok;
|
||||
});
|
||||
|
||||
EXO_TEST(rbtree_create_1, {
|
||||
tree = rb_tree_create(test_tree_compare, &hub_malloc, &hub_free);
|
||||
return tree != NULL;
|
||||
});
|
||||
|
||||
EXO_TEST(rbtree_size_0, { return rb_tree_size(tree) == 0; });
|
||||
|
||||
EXO_TEST(rbtree_insert_1, {
|
||||
return rb_tree_insert(tree, "one", "1");
|
||||
});
|
||||
|
||||
EXO_TEST(rbtree_insert_2, {
|
||||
return rb_tree_insert(tree, "two", "2");
|
||||
});
|
||||
|
||||
EXO_TEST(rbtree_insert_3, {
|
||||
return rb_tree_insert(tree, "three", "3");
|
||||
});
|
||||
|
||||
EXO_TEST(rbtree_insert_3_again, {
|
||||
return !rb_tree_insert(tree, "three", "3-again");
|
||||
});
|
||||
|
||||
EXO_TEST(rbtree_size_1, { return rb_tree_size(tree) == 3; });
|
||||
|
||||
static int test_check_search(const char* key, const char* expect)
|
||||
{
|
||||
const char* value = (const char*) rb_tree_get(tree, key);
|
||||
if (!value) return !expect;
|
||||
if (!expect) return 0;
|
||||
return strcmp(value, expect) == 0;
|
||||
}
|
||||
|
||||
EXO_TEST(rbtree_search_1, { return test_check_search("one", "1"); });
|
||||
EXO_TEST(rbtree_search_2, { return test_check_search("two", "2"); });
|
||||
EXO_TEST(rbtree_search_3, { return test_check_search("three", "3"); });
|
||||
EXO_TEST(rbtree_search_4, { return test_check_search("four", NULL); });
|
||||
|
||||
|
||||
EXO_TEST(rbtree_remove_1, {
|
||||
return rb_tree_remove(tree, "one");
|
||||
});
|
||||
|
||||
EXO_TEST(rbtree_size_2, { return rb_tree_size(tree) == 2; });
|
||||
|
||||
EXO_TEST(rbtree_remove_2, {
|
||||
return rb_tree_remove(tree, "two");
|
||||
});
|
||||
|
||||
EXO_TEST(rbtree_remove_3, {
|
||||
return rb_tree_remove(tree, "three");
|
||||
});
|
||||
|
||||
EXO_TEST(rbtree_remove_3_again, {
|
||||
return !rb_tree_remove(tree, "three");
|
||||
});
|
||||
|
||||
EXO_TEST(rbtree_search_5, { return test_check_search("one", NULL); });
|
||||
EXO_TEST(rbtree_search_6, { return test_check_search("two", NULL); });
|
||||
EXO_TEST(rbtree_search_7, { return test_check_search("three", NULL); });
|
||||
EXO_TEST(rbtree_search_8, { return test_check_search("four", NULL); });
|
||||
|
||||
EXO_TEST(rbtree_size_3, { return rb_tree_size(tree) == 0; });
|
||||
|
||||
EXO_TEST(rbtree_insert_10000, {
|
||||
int i;
|
||||
for (i = 0; i < MAX_NODES; i++)
|
||||
{
|
||||
const char* key = strdup(uhub_itoa(i));
|
||||
const char* val = strdup(uhub_itoa(i + 16384));
|
||||
if (!rb_tree_insert(tree, key, val))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
});
|
||||
|
||||
EXO_TEST(rbtree_size_4, { return rb_tree_size(tree) == MAX_NODES; });
|
||||
|
||||
EXO_TEST(rbtree_check_10000, {
|
||||
int i;
|
||||
for (i = 0; i < MAX_NODES; i++)
|
||||
{
|
||||
char* key = strdup(uhub_itoa(i));
|
||||
const char* expect = uhub_itoa(i + 16384);
|
||||
if (!test_check_search(key, expect))
|
||||
return 0;
|
||||
hub_free(key);
|
||||
}
|
||||
return 1;
|
||||
});
|
||||
|
||||
EXO_TEST(rbtree_iterate_10000, {
|
||||
int i = 0;
|
||||
struct rb_node* n = (struct rb_node*) rb_tree_first(tree);
|
||||
while (n)
|
||||
{
|
||||
n = (struct rb_node*) rb_tree_next(tree);
|
||||
i++;
|
||||
}
|
||||
return i == MAX_NODES;
|
||||
});
|
||||
|
||||
static int freed_nodes = 0;
|
||||
static void free_node(struct rb_node* n)
|
||||
{
|
||||
hub_free((void*) n->key);
|
||||
hub_free((void*) n->value);
|
||||
freed_nodes += 1;
|
||||
}
|
||||
|
||||
EXO_TEST(rbtree_remove_10000, {
|
||||
int i;
|
||||
int j;
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
for (i = j; i < MAX_NODES; i += 2)
|
||||
{
|
||||
const char* key = uhub_itoa(i);
|
||||
rb_tree_remove_node(tree, key, &free_node);
|
||||
}
|
||||
}
|
||||
return freed_nodes == MAX_NODES;
|
||||
});
|
||||
|
||||
EXO_TEST(rbtree_destroy_1, {
|
||||
rb_tree_destroy(tree);
|
||||
return 1;
|
||||
});
|
@ -117,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;
|
||||
});
|
||||
|
@ -7,15 +7,13 @@
|
||||
static int match_str(const char* str1, char* str2)
|
||||
{
|
||||
size_t i;
|
||||
int ret;
|
||||
|
||||
for (i = 0; i < strlen(str2); i++)
|
||||
if (str2[i] == '_')
|
||||
str2[i] = ' ';
|
||||
else if (str2[i] == '|')
|
||||
str2[i] = '\t';
|
||||
|
||||
ret = strcmp(str1, str2);
|
||||
int ret = strcmp(str1, str2);
|
||||
if (ret) {
|
||||
fprintf(stderr, "\n Mismatch: \"%s\" != \"%s\"\n", str1, str2);
|
||||
}
|
||||
@ -31,11 +29,10 @@ static int count(const char* STR, size_t EXPECT) {
|
||||
|
||||
static int compare(const char* str, const char* ref) {
|
||||
size_t i, max;
|
||||
int pass;
|
||||
struct linked_list* compare = list_create();
|
||||
SETUP(tokens, str);
|
||||
split_string(ref, " ", compare, 0);
|
||||
pass = cfg_token_count(tokens) == list_size(compare);
|
||||
int pass = cfg_token_count(tokens) == list_size(compare);
|
||||
if (pass) {
|
||||
max = cfg_token_count(tokens);
|
||||
for (i = 0; i < max; i++) {
|
||||
|
@ -2,19 +2,32 @@
|
||||
|
||||
#define MAX_USERS 64
|
||||
|
||||
static struct hub_user_manager* uman = 0;
|
||||
static struct hub_info um_hub;
|
||||
static struct hub_user um_user[MAX_USERS];
|
||||
// static struct net_connection um_cons[MAX_USERS];
|
||||
|
||||
EXO_TEST(um_test_setup, {
|
||||
int i = 0;
|
||||
memset(&um_hub, 0, sizeof(um_hub));
|
||||
|
||||
for (i = 0; i < MAX_USERS; i++)
|
||||
{
|
||||
/* memset(&um_cons[i], 0, sizeof(struct net_connection));
|
||||
um_cons[i].sd = -1;
|
||||
|
||||
memset(&um_user[i], 0, sizeof(struct hub_user));
|
||||
um_user[i].id.sid = i+1;
|
||||
um_user[i].connection = &um_cons[i];*/
|
||||
}
|
||||
return 1;
|
||||
});
|
||||
|
||||
EXO_TEST(um_init_1, {
|
||||
sid_t s;
|
||||
uman = uman_init();
|
||||
|
||||
for (s = 0; s < MAX_USERS; s++)
|
||||
{
|
||||
memset(&um_user[s], 0, sizeof(struct hub_user));
|
||||
um_user[s].id.sid = s;
|
||||
}
|
||||
return !!uman;
|
||||
return uman_init(0) != 0;
|
||||
});
|
||||
|
||||
EXO_TEST(um_init_2, {
|
||||
return uman_init(&um_hub) == 0;
|
||||
});
|
||||
|
||||
EXO_TEST(um_shutdown_1, {
|
||||
@ -22,29 +35,32 @@ EXO_TEST(um_shutdown_1, {
|
||||
});
|
||||
|
||||
EXO_TEST(um_shutdown_2, {
|
||||
return uman_shutdown(uman) == 0;
|
||||
return uman_shutdown(&um_hub) == 0;
|
||||
});
|
||||
|
||||
EXO_TEST(um_init_2, {
|
||||
uman = uman_init();
|
||||
return !!uman;
|
||||
EXO_TEST(um_shutdown_3, {
|
||||
return uman_shutdown(&um_hub) == -1;
|
||||
});
|
||||
|
||||
EXO_TEST(um_init_3, {
|
||||
return uman_init(&um_hub) == 0;
|
||||
});
|
||||
|
||||
EXO_TEST(um_add_1, {
|
||||
return uman_add(uman, &um_user[0]) == 0;
|
||||
return uman_add(&um_hub, &um_user[0]) == 0;
|
||||
});
|
||||
|
||||
EXO_TEST(um_size_1, {
|
||||
return uman->count == 1;
|
||||
return hub_get_user_count(&um_hub) == 1;
|
||||
});
|
||||
|
||||
|
||||
EXO_TEST(um_remove_1, {
|
||||
return uman_remove(uman, &um_user[0]) == 0;
|
||||
return uman_remove(&um_hub, &um_user[0]) == 0;
|
||||
});
|
||||
|
||||
EXO_TEST(um_size_2, {
|
||||
return uman->count == 0;
|
||||
return hub_get_user_count(&um_hub) == 0;
|
||||
});
|
||||
|
||||
|
||||
@ -52,21 +68,25 @@ EXO_TEST(um_add_2, {
|
||||
int i;
|
||||
for (i = 0; i < MAX_USERS; i++)
|
||||
{
|
||||
if (uman_add(uman, &um_user[i]) != 0)
|
||||
if (uman_add(&um_hub, &um_user[i]) != 0)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
});
|
||||
|
||||
EXO_TEST(um_size_3, {
|
||||
return uman->count == MAX_USERS;
|
||||
return hub_get_user_count(&um_hub) == MAX_USERS;
|
||||
});
|
||||
|
||||
EXO_TEST(um_add_3, {
|
||||
return uman_add(&um_hub, &um_user[5]) != 0;
|
||||
});
|
||||
|
||||
EXO_TEST(um_remove_2, {
|
||||
int i;
|
||||
for (i = 0; i < MAX_USERS; i++)
|
||||
{
|
||||
if (uman_remove(uman, &um_user[i]) != 0)
|
||||
if (uman_remove(&um_hub, &um_user[i]) != 0)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@ -85,5 +105,5 @@ EXO_TEST(um_remove_2, {
|
||||
|
||||
/* Last test */
|
||||
EXO_TEST(um_shutdown_4, {
|
||||
return uman_shutdown(uman) == 0;
|
||||
return uman_shutdown(&um_hub) == 0;
|
||||
});
|
||||
|
@ -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
|
||||
|
@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
./exotic *.tcc > test.c
|
||||
|
@ -1,78 +0,0 @@
|
||||
# - Try to find sqlite3
|
||||
# Find sqlite3 headers, libraries and the answer to all questions.
|
||||
#
|
||||
# SQLITE3_FOUND True if sqlite3 got found
|
||||
# SQLITE3_INCLUDEDIR Location of sqlite3 headers
|
||||
# SQLITE3_LIBRARIES List of libraries to use sqlite3
|
||||
# SQLITE3_DEFINITIONS Definitions to compile sqlite3
|
||||
#
|
||||
# Copyright (c) 2007 Juha Tuomala <tuju@iki.fi>
|
||||
# Copyright (c) 2007 Daniel Gollub <gollub@b1-systems.de>
|
||||
# Copyright (c) 2007 Alban Browaeys <prahal@yahoo.com>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New
|
||||
# BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
#
|
||||
|
||||
INCLUDE( FindPkgConfig )
|
||||
# Take care about sqlite3.pc settings
|
||||
IF ( Sqlite3_FIND_REQUIRED )
|
||||
SET( _pkgconfig_REQUIRED "REQUIRED" )
|
||||
ELSE ( Sqlite3_FIND_REQUIRED )
|
||||
SET( _pkgconfig_REQUIRED "" )
|
||||
ENDIF ( Sqlite3_FIND_REQUIRED )
|
||||
|
||||
IF ( SQLITE3_MIN_VERSION )
|
||||
PKG_SEARCH_MODULE( SQLITE3 ${_pkgconfig_REQUIRED} sqlite3>=${SQLITE3_MIN_VERSION} )
|
||||
ELSE ( SQLITE3_MIN_VERSION )
|
||||
pkg_search_module( SQLITE3 ${_pkgconfig_REQUIRED} sqlite3 )
|
||||
ENDIF ( SQLITE3_MIN_VERSION )
|
||||
|
||||
|
||||
# Look for sqlite3 include dir and libraries w/o pkgconfig
|
||||
IF ( NOT SQLITE3_FOUND AND NOT PKG_CONFIG_FOUND )
|
||||
FIND_PATH( _sqlite3_include_DIR sqlite3.h
|
||||
PATHS
|
||||
/opt/local/include/
|
||||
/sw/include/
|
||||
/usr/local/include/
|
||||
/usr/include/
|
||||
)
|
||||
FIND_LIBRARY( _sqlite3_link_DIR sqlite3
|
||||
PATHS
|
||||
/opt/local/lib
|
||||
/sw/lib
|
||||
/usr/lib
|
||||
/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}
|
||||
/usr/local/lib
|
||||
/usr/lib64
|
||||
/usr/local/lib64
|
||||
/opt/lib64
|
||||
)
|
||||
IF ( _sqlite3_include_DIR AND _sqlite3_link_DIR )
|
||||
SET ( _sqlite3_FOUND TRUE )
|
||||
ENDIF ( _sqlite3_include_DIR AND _sqlite3_link_DIR )
|
||||
|
||||
|
||||
IF ( _sqlite3_FOUND )
|
||||
SET ( SQLITE3_INCLUDE_DIRS ${_sqlite3_include_DIR} )
|
||||
SET ( SQLITE3_LIBRARIES ${_sqlite3_link_DIR} )
|
||||
ENDIF ( _sqlite3_FOUND )
|
||||
|
||||
# Report results
|
||||
IF ( SQLITE3_LIBRARIES AND SQLITE3_INCLUDE_DIRS AND _sqlite3_FOUND )
|
||||
SET( SQLITE3_FOUND 1 )
|
||||
MESSAGE( STATUS "Found sqlite3: ${SQLITE3_LIBRARIES} ${SQLITE3_INCLUDE_DIRS}" )
|
||||
ELSE ( SQLITE3_LIBRARIES AND SQLITE3_INCLUDE_DIRS AND _sqlite3_FOUND )
|
||||
IF ( Sqlite3_FIND_REQUIRED )
|
||||
MESSAGE( SEND_ERROR "Could NOT find sqlite3" )
|
||||
ELSE ( Sqlite3_FIND_REQUIRED )
|
||||
MESSAGE( STATUS "Could NOT find sqlite3" )
|
||||
ENDIF ( Sqlite3_FIND_REQUIRED )
|
||||
ENDIF ( SQLITE3_LIBRARIES AND SQLITE3_INCLUDE_DIRS AND _sqlite3_FOUND )
|
||||
|
||||
ENDIF ( NOT SQLITE3_FOUND AND NOT PKG_CONFIG_FOUND )
|
||||
|
||||
# Hide advanced variables from CMake GUIs
|
||||
MARK_AS_ADVANCED( SQLITE3_LIBRARIES SQLITE3_INCLUDE_DIRS )
|
4
debian/changelog
vendored
4
debian/changelog
vendored
@ -2,13 +2,13 @@ uhub (0.3.2-1) unstable; urgency=low
|
||||
|
||||
* Updated upstream version.
|
||||
|
||||
-- Jan Vidar Krey <janvidar@extatic.org> Mon, 30 May 2010 18:00:00 +0200
|
||||
-- Jan Vidar Krey <janvidar@extatic.org> Mon 30 May 2010 18:00:00 +0200
|
||||
|
||||
uhub (0.3.1-1) unstable; urgency=low
|
||||
|
||||
* Updated version number.
|
||||
|
||||
-- Jan Vidar Krey <janvidar@extatic.org> Mon, 04 Apr 2010 16:44:21 +0200
|
||||
-- Jan Vidar Krey <janvidar@extatic.org> Mon 04 Apr 2010 16:44:21 +0200
|
||||
|
||||
uhub (0.3.0-2) unstable; urgency=low
|
||||
|
||||
|
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'.
|
||||
|
2
debian/rules
vendored
2
debian/rules
vendored
@ -24,7 +24,7 @@ binary-indep: build
|
||||
binary-arch: build
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_prep
|
||||
dh_clean -k
|
||||
dh_installdirs
|
||||
$(MAKE) install $(makeopts)
|
||||
dh_installdocs
|
||||
|
9
debian/uhub.init
vendored
9
debian/uhub.init
vendored
@ -5,8 +5,7 @@
|
||||
# Required-Stop: $remote_fs $network
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: Start daemon at boot time
|
||||
# Description: Enable service provided by daemon.
|
||||
# Short-Description: uhub - High performance ADC p2p hub.
|
||||
### END INIT INFO
|
||||
|
||||
PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
||||
@ -84,12 +83,8 @@ case "$1" in
|
||||
$0 start
|
||||
;;
|
||||
|
||||
status)
|
||||
status_of_proc $DAEMON $NAME && exit 0 || exit $?
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload|status}" >&2
|
||||
echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
1
debian/uhub.manpages
vendored
1
debian/uhub.manpages
vendored
@ -1,2 +1 @@
|
||||
doc/uhub.1
|
||||
doc/uhub-passwd.1
|
||||
|
@ -1,13 +1,13 @@
|
||||
= Architecture of uHub =
|
||||
|
||||
uHub is single-threaded and handles network and timer events using the
|
||||
uHub is single threaded and handles network and timer events using the
|
||||
libevent library.
|
||||
For each state there is a read event (and sometimes a write event) and timeout
|
||||
event in case an expected read (or write) event does not occur.
|
||||
|
||||
|
||||
== Protocol overview ==
|
||||
uHub "speaks" the ADC protocol, which works in short as follows:
|
||||
uHub use "speak" the ADC protocol, which works in short as follows:
|
||||
(C = client, S = server aka uHub).
|
||||
|
||||
C: HSUP ADBASE
|
||||
@ -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.extatic.org/uhub/compile.html
|
||||
|
||||
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 icomming 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
|
||||
@ -31,8 +31,7 @@ fi
|
||||
# Check that networking is up.
|
||||
[ ${NETWORKING} = "no" ] && exit 1
|
||||
|
||||
# Check that bin and uhub.conf exists.
|
||||
[ -f $UHUBBINFILE ] || exit 6
|
||||
# Check that uhub.conf exists.
|
||||
[ -f /etc/uhub/uhub.conf ] || exit 6
|
||||
|
||||
RETVAL=0
|
||||
@ -41,7 +40,7 @@ RETVAL=0
|
||||
start() {
|
||||
KIND="Uhub"
|
||||
echo -n $"Starting $KIND services: "
|
||||
daemon $UHUBBINFILE $UHUBOPTIONS
|
||||
daemon uhub $UHUBOPTIONS
|
||||
RETVAL=$?
|
||||
echo ""
|
||||
return $RETVAL
|
||||
@ -50,7 +49,7 @@ start() {
|
||||
stop() {
|
||||
KIND="Uhub"
|
||||
echo -n $"Shutting down $KIND services: "
|
||||
killproc $UHUBBINFILE
|
||||
killproc uhub
|
||||
RETVAL=$?
|
||||
echo ""
|
||||
return $RETVAL
|
||||
@ -78,7 +77,7 @@ relog() {
|
||||
}
|
||||
|
||||
rhstatus() {
|
||||
status $UHUBBINFILE
|
||||
status uhub
|
||||
RETVAL=$?
|
||||
if [ $RETVAL -ne 0 ] ; then
|
||||
return $RETVAL
|
||||
|
@ -1,6 +1,3 @@
|
||||
# locate bin file
|
||||
UHUBBINFILE=/usr/bin/uhub
|
||||
|
||||
# Options to UHUB
|
||||
# -v Verbose mode. Add more -v's for higher verbosity.
|
||||
# -q Quiet mode - no output
|
||||
|
@ -11,28 +11,18 @@
|
||||
# Parameters:
|
||||
# file: path/filename for database.
|
||||
#
|
||||
plugin /usr/lib/uhub/mod_auth_sqlite.so "file=/etc/uhub/users.db"
|
||||
plugin /var/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
|
||||
#
|
||||
# Parameters:
|
||||
# file: path/filename for log file.
|
||||
# syslog: if true then syslog is used instead of writing to a file (Unix only)
|
||||
plugin /usr/lib/uhub/mod_logging.so "file=/var/log/uhub.log"
|
||||
plugin /var/lib/uhub/mod_logging.so "file=/var/log/uhub.log"
|
||||
|
||||
# A simple example plugin
|
||||
#plugin /usr/lib/uhub/mod_example.so
|
||||
|
||||
# plugin /var/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.
|
||||
#
|
||||
@ -56,7 +46,7 @@ plugin /usr/lib/uhub/mod_logging.so "file=/var/log/uhub.log"
|
||||
# %p - 'am' or 'pm'
|
||||
# %M - Minutes (00-59) (Hub local time)
|
||||
# %S - Seconds (00-60) (Hub local time)
|
||||
plugin /usr/lib/uhub/mod_welcome.so "motd=/etc/uhub/motd.txt rules=/etc/uhub/rules.txt"
|
||||
plugin /var/lib/uhub/mod_welcome.so "motd=/etc/uhub/motd.txt rules=/etc/uhub/rules.txt"
|
||||
|
||||
# Load the chat history plugin.
|
||||
#
|
||||
@ -68,4 +58,5 @@ plugin /usr/lib/uhub/mod_welcome.so "motd=/etc/uhub/motd.txt rules=/etc/uhub/rul
|
||||
# history_max: the maximum number of messages to keep in history
|
||||
# history_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"
|
||||
plugin /var/lib/uhub/mod_chat_history.so "history_max=200 history_default=10 history_connect=5"
|
||||
|
||||
|
@ -1,42 +0,0 @@
|
||||
.TH UHUB-PASSWD "1" "May 2012"
|
||||
.SH NAME
|
||||
uhub-passwd \- small utility for manipulating passwords which are
|
||||
used by uhub daemon
|
||||
.SH SYNOPSIS
|
||||
.B uhub-passwd
|
||||
\fIfilename command \fR[...]
|
||||
.SH DESCRIPTION
|
||||
uHub is a high performance peer-to-peer hub for the ADC network.
|
||||
Its low memory footprint allows it to handle several thousand users
|
||||
on high-end servers, or a small private hub on embedded hardware.
|
||||
.SH "OPTIONS"
|
||||
.TP
|
||||
.BI \^create
|
||||
.TP
|
||||
.BI \^add " username password [credentials = user]"
|
||||
.TP
|
||||
.BI \^del " username"
|
||||
.TP
|
||||
.BI \^mod " username credentials"
|
||||
.TP
|
||||
.BI \^pass " username password"
|
||||
.TP
|
||||
.BI \^list
|
||||
.SH "PARAMETERS"
|
||||
.TP
|
||||
.B 'filename'
|
||||
is a database file
|
||||
.TP
|
||||
.B 'username'
|
||||
is a nickname (UTF\-8, up to 64 bytes)
|
||||
.TP
|
||||
.B 'password'
|
||||
is a password (UTF\-8, up to 64 bytes)
|
||||
.TP
|
||||
.B 'credentials'
|
||||
is one of 'admin', 'super', 'op', 'user'
|
||||
.SH AUTHOR
|
||||
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
|
@ -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/
|
||||
|
@ -1,11 +1,11 @@
|
||||
# uhub.conf - A example configuration file.
|
||||
# You should normally place this file in /etc/uhub/uhub.conf
|
||||
# and customize some of the settings below.
|
||||
# And change the file_acl and file_motd 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
|
||||
@ -38,6 +38,17 @@ hub_enabled=1
|
||||
# Access control list (user database)
|
||||
file_acl=/etc/uhub/users.conf
|
||||
|
||||
# This file can contain a message of the day. A welcome
|
||||
# message send to any client when connecting.
|
||||
# If the file does not exist, is empty, or cannot be opened
|
||||
# the motd will not be sent to the clients.
|
||||
# Normally this message is sent to clients when connecting.
|
||||
file_motd=/etc/uhub/motd.txt
|
||||
|
||||
# This file can contain a rules of the hub.
|
||||
# Normally this message is sent to clients when write in chat !rules
|
||||
file_rules=/etc/uhub/rules.txt
|
||||
|
||||
# This file can contain a conf for plugin subsystem
|
||||
file_plugins = /etc/uhub/plugins.conf
|
||||
|
||||
@ -104,11 +115,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
|
||||
@ -41,7 +41,7 @@ mkdir -p $RPM_BUILD_ROOT/etc/init.d
|
||||
mkdir -p $RPM_BUILD_ROOT/etc/logrotate.d
|
||||
mkdir -p $RPM_BUILD_ROOT/etc/sysconfig
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/share/man/man1
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/lib/uhub
|
||||
mkdir -p $RPM_BUILD_ROOT/var/lib/uhub
|
||||
|
||||
install uhub $RPM_BUILD_ROOT/usr/bin/
|
||||
install uhub-passwd $RPM_BUILD_ROOT/usr/bin/
|
||||
@ -52,7 +52,7 @@ install -m644 doc/init.d.RedHat/etc/sysconfig/uhub $RPM_BUILD_ROOT/etc/sysconfi
|
||||
install -m644 doc/init.d.RedHat/etc/logrotate.d/uhub $RPM_BUILD_ROOT/etc/logrotate.d/
|
||||
/bin/gzip -9c doc/uhub.1 > doc/uhub.1.gz &&
|
||||
install -m644 doc/uhub.1.gz $RPM_BUILD_ROOT/usr/share/man/man1
|
||||
install -m644 mod_*.so $RPM_BUILD_ROOT/usr/lib/uhub
|
||||
install -m644 mod_*.so $RPM_BUILD_ROOT/var/lib/uhub
|
||||
|
||||
|
||||
%files
|
||||
@ -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/"
|
||||
|
@ -1,28 +0,0 @@
|
||||
# uHub - a lightweight but high-performance hub for the ADC
|
||||
# peer-to-peer protocol.
|
||||
|
||||
description "uHub - High performance ADC peer-to-peer hub"
|
||||
|
||||
# Start and stop conditions.
|
||||
start on filesystem or runlevel [2345]
|
||||
stop on runlevel [!2345]
|
||||
|
||||
# Allow the service to respawn, but if its happening too often
|
||||
# (10 times in 5 seconds) there's a problem and we should stop trying.
|
||||
respawn
|
||||
respawn limit 10 5
|
||||
|
||||
# The program is going to fork, and upstart needs to know this
|
||||
# so it can track the change in PID.
|
||||
expect fork
|
||||
|
||||
# Set the mode the process should create files in.
|
||||
umask 022
|
||||
|
||||
# Make sure the log folder exists.
|
||||
pre-start script
|
||||
mkdir -p -m0755 /var/log/uhub
|
||||
end script
|
||||
|
||||
# Command to run it.
|
||||
exec /usr/bin/uhub -f -u uhub -g uhub -l /var/log/uhub/uhub.log -c /etc/uhub/uhub.conf
|
@ -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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -33,7 +33,7 @@ typedef uint32_t fourcc_t;
|
||||
#define FOURCC(a,b,c,d) (fourcc_t) ((a << 24) | (b << 16) | (c << 8) | d)
|
||||
|
||||
/* default welcome protocol support message, as sent by this server */
|
||||
#define ADC_PROTO_SUPPORT "ADBASE ADTIGR ADPING ADUCMD"
|
||||
#define ADC_PROTO_SUPPORT "ADBASE ADTIGR ADPING"
|
||||
|
||||
/* Server sent commands */
|
||||
#define ADC_CMD_ISID FOURCC('I','S','I','D')
|
||||
@ -85,23 +85,10 @@ typedef uint32_t fourcc_t;
|
||||
#define ADC_CMD_DINF FOURCC('D','I','N','F')
|
||||
#define ADC_CMD_EINF FOURCC('E','I','N','F')
|
||||
#define ADC_CMD_FINF FOURCC('F','I','N','F')
|
||||
#define ADC_CMD_BQUI FOURCC('B','Q','U','I')
|
||||
#define ADC_CMD_DQUI FOURCC('D','Q','U','I')
|
||||
#define ADC_CMD_EQUI FOURCC('E','Q','U','I')
|
||||
#define ADC_CMD_FQUI FOURCC('F','Q','U','I')
|
||||
|
||||
/* Extension messages */
|
||||
#define ADC_CMD_HCHK FOURCC('H','C','H','K')
|
||||
|
||||
/* UCMD Extension */
|
||||
#define ADC_CMD_BCMD FOURCC('B','C','M','D')
|
||||
#define ADC_CMD_DCMD FOURCC('D','C','M','D')
|
||||
#define ADC_CMD_ECMD FOURCC('E','C','M','D')
|
||||
#define ADC_CMD_FCMD FOURCC('F','C','M','D')
|
||||
#define ADC_CMD_HCMD FOURCC('H','C','M','D')
|
||||
#define ADC_CMD_ICMD FOURCC('I','C','M','D')
|
||||
|
||||
|
||||
#define ADC_INF_FLAG_IPV4_ADDR "I4" /* ipv4 address */
|
||||
#define ADC_INF_FLAG_IPV6_ADDR "I6" /* ipv6 address */
|
||||
#define ADC_INF_FLAG_IPV4_UDP_PORT "U4" /* port number */
|
||||
@ -111,15 +98,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 +118,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 */
|
||||
@ -156,10 +140,9 @@ typedef uint32_t fourcc_t;
|
||||
#define ADC_SUP_FLAG_ADD "AD"
|
||||
#define ADC_SUP_FLAG_REMOVE "RM"
|
||||
|
||||
#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_BOT "1"
|
||||
#define ADC_CLIENT_TYPE_REGISTERED_USER "2"
|
||||
#define ADC_CLIENT_TYPE_OPERATOR "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-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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -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));
|
||||
@ -62,33 +63,6 @@ static void msg_free(void* ptr)
|
||||
#define msg_free(X) hub_free(X)
|
||||
#endif /* MSG_MEMORY_DEBUG */
|
||||
|
||||
static int msg_check_escapes(const char* string, size_t len)
|
||||
{
|
||||
char* start = (char*) string;
|
||||
while ((start = memchr(start, '\\', len - (start - string))))
|
||||
{
|
||||
if (start+1 == (string + len))
|
||||
return 0;
|
||||
|
||||
switch (*(++start))
|
||||
{
|
||||
case '\\':
|
||||
case 'n':
|
||||
case 's':
|
||||
/* Increment so we don't check the escaped
|
||||
* character next time around. Not doing so
|
||||
* leads to messages with escaped backslashes
|
||||
* being incorrectly reported as having invalid
|
||||
* escapes. */
|
||||
++start;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
struct adc_message* adc_msg_incref(struct adc_message* msg)
|
||||
{
|
||||
@ -153,7 +127,7 @@ static int adc_msg_cache_append(struct adc_message* msg, const char* string, siz
|
||||
memcpy(&msg->cache[msg->length], string, len);
|
||||
adc_msg_set_length(msg, msg->length + len);
|
||||
|
||||
uhub_assert(msg->capacity > msg->length);
|
||||
assert(msg->capacity > msg->length);
|
||||
msg->cache[msg->length] = 0;
|
||||
return 1;
|
||||
}
|
||||
@ -167,24 +141,24 @@ int adc_msg_get_arg_offset(struct adc_message* msg)
|
||||
{
|
||||
if (!msg || !msg->cache)
|
||||
return -1;
|
||||
|
||||
|
||||
switch (msg->cache[0])
|
||||
{
|
||||
/* These *SHOULD* never be seen on a hub */
|
||||
case 'U':
|
||||
case 'C':
|
||||
return 4; /* Actually: 4 + strlen(cid). */
|
||||
|
||||
|
||||
case 'I':
|
||||
case 'H':
|
||||
return 4;
|
||||
|
||||
|
||||
case 'B':
|
||||
return 9;
|
||||
|
||||
|
||||
case 'F':
|
||||
return (10 + (list_size(msg->feature_cast_include)*5) + (list_size(msg->feature_cast_exclude)*5));
|
||||
|
||||
|
||||
case 'D':
|
||||
case 'E':
|
||||
return 14;
|
||||
@ -199,10 +173,10 @@ int adc_msg_is_empty(struct adc_message* msg)
|
||||
|
||||
if (offset == -1)
|
||||
return -1;
|
||||
|
||||
|
||||
if ((msg->length - 1) == (size_t) offset)
|
||||
return 1;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -282,19 +256,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);
|
||||
@ -306,17 +284,17 @@ struct adc_message* adc_msg_copy(const struct adc_message* cmd)
|
||||
struct adc_message* adc_msg_parse_verify(struct hub_user* u, const char* line, size_t length)
|
||||
{
|
||||
struct adc_message* command = adc_msg_parse(line, length);
|
||||
|
||||
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
@ -330,7 +308,7 @@ struct adc_message* adc_msg_parse(const char* line, size_t length)
|
||||
int ok = 1;
|
||||
int need_terminate = 0;
|
||||
struct linked_list* feature_cast_list;
|
||||
|
||||
|
||||
if (command == NULL)
|
||||
return NULL; /* OOM */
|
||||
|
||||
@ -341,13 +319,6 @@ struct adc_message* adc_msg_parse(const char* line, size_t length)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!msg_check_escapes(line, length))
|
||||
{
|
||||
LOG_DEBUG("Dropped message with invalid ADC escape.");
|
||||
msg_free(command);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (line[length-1] != '\n')
|
||||
{
|
||||
need_terminate = 1;
|
||||
@ -527,30 +498,6 @@ struct adc_message* adc_msg_create(const char* line)
|
||||
return adc_msg_parse(line, strlen(line));
|
||||
}
|
||||
|
||||
struct adc_message* adc_msg_construct_source(fourcc_t fourcc, sid_t source, size_t size)
|
||||
{
|
||||
struct adc_message* msg = adc_msg_construct(fourcc, size + 4 + 1);
|
||||
if (!msg)
|
||||
return NULL;
|
||||
|
||||
adc_msg_add_argument(msg, sid_to_string(source));
|
||||
msg->source = source;
|
||||
return msg;
|
||||
}
|
||||
|
||||
struct adc_message* adc_msg_construct_source_dest(fourcc_t fourcc, sid_t source, sid_t dest, size_t size)
|
||||
{
|
||||
struct adc_message* msg = adc_msg_construct(fourcc, size + 4 + 4 + 1);
|
||||
if (!msg)
|
||||
return NULL;
|
||||
|
||||
adc_msg_add_argument(msg, sid_to_string(source));
|
||||
adc_msg_add_argument(msg, sid_to_string(dest));
|
||||
msg->source = source;
|
||||
msg->target = dest;
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
||||
struct adc_message* adc_msg_construct(fourcc_t fourcc, size_t size)
|
||||
{
|
||||
@ -558,7 +505,9 @@ struct adc_message* adc_msg_construct(fourcc_t fourcc, size_t size)
|
||||
if (!msg)
|
||||
return NULL; /* OOM */
|
||||
|
||||
if (!adc_msg_grow(msg, sizeof(fourcc) + size + 1))
|
||||
if (size < sizeof(fourcc)) size = sizeof(fourcc);
|
||||
|
||||
if (!adc_msg_grow(msg, size+1))
|
||||
{
|
||||
msg_free(msg);
|
||||
return NULL; /* OOM */
|
||||
@ -594,14 +543,14 @@ int adc_msg_remove_named_argument(struct adc_message* cmd, const char prefix_[2]
|
||||
int found = 0;
|
||||
int arg_offset = adc_msg_get_arg_offset(cmd);
|
||||
size_t temp_len = 0;
|
||||
|
||||
|
||||
adc_msg_unterminate(cmd);
|
||||
|
||||
|
||||
start = memmem(&cmd->cache[arg_offset], (cmd->length - arg_offset), prefix, 3);
|
||||
while (start)
|
||||
{
|
||||
endInfo = &cmd->cache[cmd->length];
|
||||
|
||||
|
||||
if (&start[0] < &endInfo[0])
|
||||
{
|
||||
end = memchr(&start[1], ' ', &endInfo[0]-&start[1]);
|
||||
@ -610,13 +559,13 @@ int adc_msg_remove_named_argument(struct adc_message* cmd, const char prefix_[2]
|
||||
{
|
||||
end = NULL;
|
||||
}
|
||||
|
||||
|
||||
if (end)
|
||||
{
|
||||
|
||||
|
||||
temp_len = &end[0] - &start[0]; // strlen(start);
|
||||
endlen = strlen(end);
|
||||
|
||||
|
||||
memmove(start, end, endlen);
|
||||
start[endlen] = '\0';
|
||||
found++;
|
||||
@ -631,9 +580,9 @@ int adc_msg_remove_named_argument(struct adc_message* cmd, const char prefix_[2]
|
||||
}
|
||||
start = memmem(&cmd->cache[arg_offset], (cmd->length - arg_offset), prefix, 3);
|
||||
}
|
||||
|
||||
|
||||
adc_msg_terminate(cmd);
|
||||
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
@ -682,7 +631,7 @@ char* adc_msg_get_named_argument(struct adc_message* cmd, const char prefix_[2])
|
||||
length = &end[0] - &start[0];
|
||||
|
||||
argument = hub_strndup(start, length);
|
||||
|
||||
|
||||
if (length > 0 && argument[length-1] == '\n')
|
||||
{
|
||||
argument[length-1] = 0;
|
||||
@ -928,41 +877,6 @@ char* adc_msg_unescape(const char* string)
|
||||
return new_string;
|
||||
}
|
||||
|
||||
int adc_msg_unescape_to_target(const char* string, char* target, size_t target_size)
|
||||
{
|
||||
size_t w = 0;
|
||||
char* ptr = (char*) target;
|
||||
char* str = (char*) string;
|
||||
int escaped = 0;
|
||||
|
||||
while (*str && w < (target_size-1))
|
||||
{
|
||||
if (escaped) {
|
||||
if (*str == 's')
|
||||
*ptr++ = ' ';
|
||||
else if (*str == '\\')
|
||||
*ptr++ = '\\';
|
||||
else if (*str == 'n')
|
||||
*ptr++ = '\n';
|
||||
else
|
||||
*ptr++ = *str;
|
||||
w++;
|
||||
escaped = 0;
|
||||
} else {
|
||||
if (*str == '\\')
|
||||
escaped = 1;
|
||||
else
|
||||
{
|
||||
*ptr++ = *str;
|
||||
w++;
|
||||
}
|
||||
}
|
||||
str++;
|
||||
}
|
||||
*ptr = 0;
|
||||
w++;
|
||||
return w;
|
||||
}
|
||||
|
||||
char* adc_msg_escape(const char* string)
|
||||
{
|
||||
|
@ -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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -51,7 +51,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);
|
||||
|
||||
@ -91,13 +91,6 @@ extern struct adc_message* adc_msg_create(const char* string);
|
||||
*/
|
||||
extern struct adc_message* adc_msg_construct(fourcc_t fourcc, size_t size);
|
||||
|
||||
/**
|
||||
* Construct a message for the given 'fourcc' and add a source SID to it,
|
||||
* in addition pre-allocate 'size' bytes at the end of the message.
|
||||
*/
|
||||
extern struct adc_message* adc_msg_construct_source(fourcc_t fourcc, sid_t source, size_t size);
|
||||
extern struct adc_message* adc_msg_construct_source_dest(fourcc_t fourcc, sid_t source, sid_t dest, size_t size);
|
||||
|
||||
/**
|
||||
* Remove a named argument from the command.
|
||||
*
|
||||
@ -159,7 +152,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,7 +160,7 @@ 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);
|
||||
|
||||
@ -176,7 +169,7 @@ extern int adc_msg_add_argument(struct adc_message* cmd, const char* string);
|
||||
*
|
||||
* @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 +179,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);
|
||||
|
||||
@ -202,14 +195,6 @@ extern int adc_msg_add_named_argument_uint64(struct adc_message* cmd, const char
|
||||
*/
|
||||
extern char* adc_msg_unescape(const char* string);
|
||||
|
||||
/**
|
||||
* Convert a ADC command escaped string to a regular string.
|
||||
* @return The number of bytes written to target. If the target is not large enough then
|
||||
* the -1 is returned, but the string is guaranteed to always be \0 terminated.
|
||||
*/
|
||||
extern int adc_msg_unescape_to_target(const char* string, char* target, size_t target_size);
|
||||
|
||||
|
||||
/**
|
||||
* Convert a string to a ADC command escaped string.
|
||||
* @return adc command escaped string or NULL if out of memory.
|
||||
@ -229,7 +214,7 @@ void adc_msg_unterminate(struct adc_message* cmd);
|
||||
/**
|
||||
* @return the offset for the first command argument in msg->cache.
|
||||
* or -1 if the command is not understood.
|
||||
* NOTE: for 'U' and 'C' commands (normally not seen by hubs),
|
||||
* NOTE: for 'U' and 'C' commands (normally not seen by hubs),
|
||||
* this returns 4. Should be 4 + lengthOf(cid).
|
||||
*/
|
||||
int adc_msg_get_arg_offset(struct adc_message* msg);
|
||||
|
@ -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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -47,7 +47,7 @@ sid_t string_to_sid(const char* sid)
|
||||
sid_t nsid = 0;
|
||||
sid_t n, x;
|
||||
sid_t factors[] = { 32768, 1024, 32, 1};
|
||||
|
||||
|
||||
if (!sid || strlen(sid) != 4) return 0;
|
||||
|
||||
for (n = 0; n < 4; n++) {
|
||||
|
@ -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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -26,20 +26,20 @@
|
||||
static int check_cmd_bool(const char* cmd, struct linked_list* list, char* line, int line_count)
|
||||
{
|
||||
char* data;
|
||||
|
||||
|
||||
if (!strncmp(line, cmd, strlen(cmd)))
|
||||
{
|
||||
data = &line[strlen(cmd)];
|
||||
data[0] = '\0';
|
||||
data++;
|
||||
|
||||
|
||||
data = strip_white_space(data);
|
||||
if (!*data)
|
||||
{
|
||||
LOG_FATAL("ACL parse error on line %d", line_count);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
list_append(list, hub_strdup(data));
|
||||
LOG_DEBUG("ACL: Deny access for: '%s' (%s)", data, cmd);
|
||||
return 1;
|
||||
@ -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);
|
||||
@ -193,18 +190,18 @@ int acl_initialize(struct hub_config* config, struct acl_handle* handle)
|
||||
{
|
||||
int ret;
|
||||
memset(handle, 0, sizeof(struct acl_handle));
|
||||
|
||||
|
||||
handle->users = list_create();
|
||||
handle->users_denied = list_create();
|
||||
handle->users_banned = list_create();
|
||||
handle->cids = list_create();
|
||||
handle->networks = list_create();
|
||||
handle->nat_override = list_create();
|
||||
|
||||
|
||||
if (!handle->users || !handle->cids || !handle->networks || !handle->users_denied || !handle->users_banned || !handle->nat_override)
|
||||
{
|
||||
LOG_FATAL("acl_initialize: Out of memory");
|
||||
|
||||
|
||||
list_destroy(handle->users);
|
||||
list_destroy(handle->users_denied);
|
||||
list_destroy(handle->users_banned);
|
||||
@ -213,11 +210,11 @@ int acl_initialize(struct hub_config* config, struct acl_handle* handle)
|
||||
list_destroy(handle->nat_override);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (config)
|
||||
{
|
||||
if (!*config->file_acl) return 0;
|
||||
|
||||
|
||||
ret = file_read_lines(config->file_acl, handle, &acl_parse_line);
|
||||
if (ret == -1)
|
||||
return -1;
|
||||
@ -252,26 +249,26 @@ int acl_shutdown(struct acl_handle* handle)
|
||||
list_clear(handle->users, &acl_free_access_info);
|
||||
list_destroy(handle->users);
|
||||
}
|
||||
|
||||
|
||||
if (handle->users_denied)
|
||||
{
|
||||
list_clear(handle->users_denied, &hub_free);
|
||||
list_destroy(handle->users_denied);
|
||||
}
|
||||
|
||||
|
||||
if (handle->users_banned)
|
||||
{
|
||||
list_clear(handle->users_banned, &hub_free);
|
||||
list_destroy(handle->users_banned);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (handle->cids)
|
||||
{
|
||||
list_clear(handle->cids, &hub_free);
|
||||
list_destroy(handle->cids);
|
||||
}
|
||||
|
||||
|
||||
if (handle->networks)
|
||||
{
|
||||
list_clear(handle->networks, &acl_free_ip_info);
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -471,10 +476,10 @@ int acl_password_verify(struct hub_info* hub, struct hub_user* user, const char*
|
||||
base32_decode(challenge, (unsigned char*) raw_challenge, MAX_CID_LEN);
|
||||
|
||||
password_len = strlen(access->password);
|
||||
|
||||
|
||||
memcpy(&buf[0], access->password, password_len);
|
||||
memcpy(&buf[password_len], raw_challenge, TIGERSIZE);
|
||||
|
||||
|
||||
tiger((uint64_t*) buf, TIGERSIZE+password_len, (uint64_t*) tiger_res);
|
||||
base32_encode((unsigned char*) tiger_res, TIGERSIZE, password_calc);
|
||||
password_calc[MAX_CID_LEN] = 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,299 +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"
|
||||
|
||||
static void hub_command_args_free(struct hub_command* cmd)
|
||||
{
|
||||
struct hub_command_arg_data* data = NULL;
|
||||
|
||||
if (!cmd->args)
|
||||
return;
|
||||
|
||||
LIST_FOREACH(struct hub_command_arg_data*, data, cmd->args,
|
||||
{
|
||||
switch (data->type)
|
||||
{
|
||||
case type_string:
|
||||
hub_free(data->data.string);
|
||||
break;
|
||||
case type_range:
|
||||
hub_free(data->data.range);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
list_clear(cmd->args, hub_free);
|
||||
list_destroy(cmd->args);
|
||||
cmd->args = NULL;
|
||||
}
|
||||
|
||||
void command_free(struct hub_command* cmd)
|
||||
{
|
||||
if (!cmd) return;
|
||||
|
||||
hub_free(cmd->prefix);
|
||||
hub_command_args_free(cmd);
|
||||
hub_free(cmd);
|
||||
}
|
||||
|
||||
static enum command_parse_status command_extract_arguments(struct hub_info* hub, const struct hub_user* user, struct command_handle* command, struct linked_list* tokens, struct linked_list* args)
|
||||
{
|
||||
int arg = 0;
|
||||
int opt = 0;
|
||||
int greedy = 0;
|
||||
char arg_code;
|
||||
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;
|
||||
|
||||
// Ignore the first token since it is the prefix.
|
||||
token = list_get_first(tokens);
|
||||
list_remove(tokens, token);
|
||||
hub_free(token);
|
||||
|
||||
while (status == cmd_status_ok && (arg_code = command->args[arg++]))
|
||||
{
|
||||
if (greedy)
|
||||
{
|
||||
size = 1;
|
||||
LIST_FOREACH(char*, tmp, 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);
|
||||
list_remove(tokens, tmp);
|
||||
hub_free(tmp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
token = list_get_first(tokens);
|
||||
}
|
||||
|
||||
if (!token || !*token)
|
||||
{
|
||||
if (arg_code == '?' || opt == 1)
|
||||
status = cmd_status_ok;
|
||||
else
|
||||
status = cmd_status_missing_args;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (arg_code)
|
||||
{
|
||||
case '?':
|
||||
opt = 1;
|
||||
continue;
|
||||
|
||||
case '+':
|
||||
greedy = 1;
|
||||
continue;
|
||||
|
||||
case 'u':
|
||||
data = hub_malloc(sizeof(*data));
|
||||
data->type = type_user;
|
||||
data->data.user = uman_get_user_by_nick(hub->users, token);
|
||||
if (!data->data.user)
|
||||
{
|
||||
hub_free(data);
|
||||
data = NULL;
|
||||
status = cmd_status_arg_nick;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
data = hub_malloc(sizeof(*data));
|
||||
data->type = type_user;
|
||||
data->data.user = uman_get_user_by_cid(hub->users, token);
|
||||
if (!data->data.user)
|
||||
{
|
||||
hub_free(data);
|
||||
data = NULL;
|
||||
status = cmd_status_arg_cid;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
data = hub_malloc(sizeof(*data));
|
||||
data->type = type_address;
|
||||
if (ip_convert_to_binary(token, data->data.address) == -1)
|
||||
{
|
||||
hub_free(data);
|
||||
data = NULL;
|
||||
status = cmd_status_arg_address;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
data = hub_malloc(sizeof(*data));
|
||||
data->type = type_range;
|
||||
data->data.range = hub_malloc_zero(sizeof(struct ip_range));
|
||||
if (!ip_convert_address_to_range(token, data->data.range))
|
||||
{
|
||||
hub_free(data->data.range);
|
||||
hub_free(data);
|
||||
data = NULL;
|
||||
status = cmd_status_arg_address;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
case 'm':
|
||||
case 'p':
|
||||
data = hub_malloc(sizeof(*data));
|
||||
data->type = type_string;
|
||||
data->data.string = strdup(token);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
data = hub_malloc(sizeof(*data));
|
||||
data->type = type_command;
|
||||
data->data.command = command_handler_lookup(hub->commands, token);
|
||||
if (!data->data.command)
|
||||
{
|
||||
hub_free(data);
|
||||
data = NULL;
|
||||
status = cmd_status_arg_command;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
data = hub_malloc(sizeof(*data));
|
||||
data->type = type_credentials;
|
||||
if (!auth_string_to_cred(token, &data->data.credentials))
|
||||
{
|
||||
hub_free(data);
|
||||
data = NULL;
|
||||
status = cmd_status_arg_cred;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
data = hub_malloc(sizeof(*data));
|
||||
data->type = type_integer;
|
||||
if (!is_number(token, &data->data.integer))
|
||||
{
|
||||
hub_free(data);
|
||||
data = NULL;
|
||||
status = cmd_status_arg_number;
|
||||
}
|
||||
break;
|
||||
|
||||
case '\0':
|
||||
if (!opt)
|
||||
{
|
||||
status = cmd_status_missing_args;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = cmd_status_ok;
|
||||
}
|
||||
}
|
||||
|
||||
if (data)
|
||||
{
|
||||
list_append(args, data);
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
list_remove(tokens, token);
|
||||
hub_free(token);
|
||||
}
|
||||
|
||||
hub_free(data);
|
||||
return status;
|
||||
}
|
||||
|
||||
static struct command_handle* command_get_handler(struct command_base* cbase, const char* prefix, const struct hub_user* user, struct hub_command* cmd)
|
||||
{
|
||||
struct command_handle* handler = NULL;
|
||||
uhub_assert(cmd != NULL);
|
||||
|
||||
if (prefix && prefix[0] && prefix[1])
|
||||
{
|
||||
handler = command_handler_lookup(cbase, prefix + 1);
|
||||
if (handler)
|
||||
{
|
||||
cmd->ptr = handler->ptr;
|
||||
cmd->handler = handler->handler;
|
||||
cmd->status = command_is_available(handler, user->credentials) ? cmd_status_ok : cmd_status_access_error;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd->status = cmd_status_not_found;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd->status = cmd_status_syntax_error;
|
||||
}
|
||||
return handler;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse a command and break it down into a struct hub_command.
|
||||
*/
|
||||
struct hub_command* command_parse(struct command_base* cbase, struct hub_info* hub, const struct hub_user* user, const char* message)
|
||||
{
|
||||
struct linked_list* tokens = list_create();
|
||||
struct hub_command* cmd = NULL;
|
||||
struct command_handle* handle = NULL;
|
||||
|
||||
cmd = hub_malloc_zero(sizeof(struct hub_command));
|
||||
cmd->status = cmd_status_ok;
|
||||
cmd->message = message;
|
||||
cmd->prefix = NULL;
|
||||
cmd->args = list_create();
|
||||
cmd->user = user;
|
||||
|
||||
if (split_string(message, " ", tokens, 0) <= 0)
|
||||
{
|
||||
cmd->status = cmd_status_syntax_error;
|
||||
goto command_parse_cleanup;
|
||||
}
|
||||
|
||||
// Setup hub command.
|
||||
cmd->prefix = strdup(((char*) list_get_first(tokens)) + 1);
|
||||
|
||||
// Find a matching command handler
|
||||
handle = command_get_handler(cbase, list_get_first(tokens), user, cmd);
|
||||
if (cmd->status != cmd_status_ok)
|
||||
goto command_parse_cleanup;
|
||||
|
||||
// Parse arguments
|
||||
cmd->status = command_extract_arguments(hub, user, handle, tokens, cmd->args);
|
||||
goto command_parse_cleanup;
|
||||
|
||||
command_parse_cleanup:
|
||||
list_clear(tokens, &hub_free);
|
||||
list_destroy(tokens);
|
||||
return cmd;
|
||||
}
|
||||
|
@ -1,131 +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_COMMAND_PARSER_H
|
||||
#define HAVE_UHUB_COMMAND_PARSER_H
|
||||
|
||||
struct hub_command;
|
||||
struct hub_user;
|
||||
struct command_base;
|
||||
|
||||
/**
|
||||
* Parse a message as a command and return a status indicating if the command
|
||||
* is valid and that the arguments are sane.
|
||||
*
|
||||
* @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 '+')
|
||||
*
|
||||
* @return a hub_command that must be freed with command_free(). @See struct hub_command.
|
||||
*/
|
||||
extern struct hub_command* command_parse(struct command_base* cbase, struct hub_info* hub, const struct hub_user* user, const char* message);
|
||||
|
||||
/**
|
||||
* Free a hub_command that was created in command_parse().
|
||||
*/
|
||||
extern void command_free(struct hub_command* command);
|
||||
|
||||
|
||||
enum command_parse_status
|
||||
{
|
||||
cmd_status_ok, /** <<< "Everything seems to OK" */
|
||||
cmd_status_not_found, /** <<< "Command was not found" */
|
||||
cmd_status_access_error, /** <<< "You don't have access to this command" */
|
||||
cmd_status_syntax_error, /** <<< "Not a valid command." */
|
||||
cmd_status_missing_args, /** <<< "Missing some or all required arguments." */
|
||||
cmd_status_arg_nick, /** <<< "A nick argument does not match an online user. ('n')" */
|
||||
cmd_status_arg_cid, /** <<< "A cid argument does not match an online user. ('i')." */
|
||||
cmd_status_arg_address, /** <<< "A address range argument is not valid ('a')." */
|
||||
cmd_status_arg_number, /** <<< "A number argument is not valid ('N')" */
|
||||
cmd_status_arg_cred, /** <<< "A credentials argument is not valid ('C')" */
|
||||
cmd_status_arg_command, /** <<< "A command argument is not valid ('c')" */
|
||||
};
|
||||
|
||||
enum hub_command_arg_type
|
||||
{
|
||||
type_integer,
|
||||
type_string,
|
||||
type_user,
|
||||
type_address,
|
||||
type_range,
|
||||
type_credentials,
|
||||
type_command
|
||||
};
|
||||
|
||||
struct hub_command_arg_data
|
||||
{
|
||||
enum hub_command_arg_type type;
|
||||
union {
|
||||
int integer;
|
||||
char* string;
|
||||
struct hub_user* user;
|
||||
struct ip_addr_encap* address;
|
||||
struct ip_range* range;
|
||||
enum auth_credentials credentials;
|
||||
struct command_handle* command;
|
||||
} data;
|
||||
};
|
||||
|
||||
typedef int (*command_handler)(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd);
|
||||
|
||||
/**
|
||||
* This struct contains all information needed to invoke
|
||||
* a command, which includes the whole message, the prefix,
|
||||
* the decoded arguments (according to parameter list), and
|
||||
* the user pointer (ptr) which comes from the command it was matched to.
|
||||
*
|
||||
* The message and prefix is generally always available, but args only
|
||||
* if status == cmd_status_ok.
|
||||
* Handler and ptr are NULL if status == cmd_status_not_found, or status == cmd_status_access_error.
|
||||
* Ptr might also be NULL if cmd_status_ok because the command that handles it was added with a NULL ptr.
|
||||
*/
|
||||
struct hub_command
|
||||
{
|
||||
const char* message; /**<<< "The complete message." */
|
||||
char* prefix; /**<<< "The prefix extracted from the message." */
|
||||
struct linked_list* args; /**<<< "List of arguments of type struct hub_command_arg_data. Parsed from message." */
|
||||
enum command_parse_status status; /**<<< "Status of the parsed hub_command." */
|
||||
command_handler handler; /**<<< "The function handler to call in order to invoke this command." */
|
||||
const struct hub_user* user; /**<<< "The user who invoked this command." */
|
||||
void* ptr; /**<<< "A pointer of data which came from struct command_handler" */
|
||||
};
|
||||
|
||||
/**
|
||||
* Reset the command argument iterator and return the number of arguments
|
||||
* that can be extracted from a parsed command.
|
||||
*
|
||||
* @param cmd the command to start iterating arguments
|
||||
* @return returns the number of arguments provided for the command
|
||||
*/
|
||||
extern size_t hub_command_arg_reset(struct hub_command* cmd);
|
||||
|
||||
/**
|
||||
* Obtain the current argument and place it in data and increments the iterator.
|
||||
* If no argument exists, or the argument is of a different type than \param type, then 0 is returned.
|
||||
*
|
||||
* NOTE: when calling hub_command_arg_next the first time during a command callback it is safe to assume
|
||||
* that the first argument will be extracted. Thus you don't need to call hub_command_arg_reset().
|
||||
*
|
||||
* @param cmd the command used for iterating arguments.
|
||||
* @param type the expected type of this argument
|
||||
* @return NULL if no argument is found or if the argument found does not match the expected type.
|
||||
*/
|
||||
extern struct hub_command_arg_data* hub_command_arg_next(struct hub_command* cmd, enum hub_command_arg_type type);
|
||||
|
||||
#endif /* HAVE_UHUB_COMMAND_PARSER_H */
|
@ -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,13 +13,14 @@
|
||||
* 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"
|
||||
|
||||
#ifdef DEBUG
|
||||
// #define CRASH_DEBUG
|
||||
// #define DEBUG_UNLOAD_PLUGINS
|
||||
#endif
|
||||
|
||||
@ -31,11 +32,14 @@ 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;
|
||||
struct linked_list* handlers;
|
||||
size_t prefix_length_max;
|
||||
struct ip_range range; // cached for parsing. Only one can be used per parameter.
|
||||
};
|
||||
|
||||
struct command_base* command_initialize(struct hub_info* hub)
|
||||
@ -58,7 +62,7 @@ struct command_base* command_initialize(struct hub_info* hub)
|
||||
void command_shutdown(struct command_base* cbase)
|
||||
{
|
||||
commands_builtin_remove(cbase);
|
||||
uhub_assert(list_size(cbase->handlers) == 0);
|
||||
assert(list_size(cbase->handlers) == 0);
|
||||
list_destroy(cbase->handlers);
|
||||
hub_free(cbase);
|
||||
}
|
||||
@ -84,65 +88,296 @@ int command_del(struct command_base* cbase, struct command_handle* cmd)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int command_is_available(struct command_handle* handle, enum auth_credentials credentials)
|
||||
static int command_is_available(struct command_handle* handle, const struct hub_user* user)
|
||||
{
|
||||
uhub_assert(handle != NULL);
|
||||
return handle->cred <= credentials;
|
||||
uhub_assert(user != NULL);
|
||||
return handle->cred <= user->credentials;
|
||||
}
|
||||
|
||||
void hub_command_args_free(struct hub_command* cmd)
|
||||
{
|
||||
struct hub_command_arg_data* data = NULL;
|
||||
|
||||
struct command_handle* command_handler_lookup(struct command_base* cbase, const char* prefix)
|
||||
if (!cmd->args)
|
||||
return;
|
||||
|
||||
for (data = (struct hub_command_arg_data*) list_get_first(cmd->args); data; data = (struct hub_command_arg_data*) list_get_next(cmd->args))
|
||||
{
|
||||
switch (data->type)
|
||||
{
|
||||
case type_string:
|
||||
hub_free(data->data.string);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
list_clear(cmd->args, hub_free);
|
||||
list_destroy(cmd->args);
|
||||
cmd->args = NULL;
|
||||
}
|
||||
|
||||
void command_free(struct hub_command* cmd)
|
||||
{
|
||||
if (!cmd) return;
|
||||
|
||||
hub_free(cmd->prefix);
|
||||
hub_command_args_free(cmd);
|
||||
hub_free(cmd);
|
||||
}
|
||||
|
||||
static struct command_handle* command_handler_lookup(struct command_base* cbase, const char* prefix)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
static enum command_parse_status command_extract_arguments(struct command_base* cbase, const struct hub_user* user, struct command_handle* command, struct linked_list* tokens, struct linked_list* args)
|
||||
{
|
||||
int arg = 0;
|
||||
int opt = 0;
|
||||
char arg_code;
|
||||
char* token = NULL;
|
||||
struct hub_command_arg_data* data = NULL;
|
||||
enum command_parse_status status = cmd_status_ok;
|
||||
|
||||
// Ignore the first token since it is the prefix.
|
||||
token = list_get_first(tokens);
|
||||
list_remove(tokens, token);
|
||||
hub_free(token);
|
||||
|
||||
while (status == cmd_status_ok && (arg_code = command->args[arg++]))
|
||||
{
|
||||
token = list_get_first(tokens);
|
||||
if (!token || !*token)
|
||||
{
|
||||
status = (arg_code == '?' ? cmd_status_ok : cmd_status_missing_args);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (arg_code)
|
||||
{
|
||||
case '?':
|
||||
opt = 1;
|
||||
continue;
|
||||
|
||||
case 'n':
|
||||
data = hub_malloc(sizeof(*data));
|
||||
data->type = type_user;
|
||||
data->data.user = uman_get_user_by_nick(cbase->hub, token);
|
||||
if (!data->data.user)
|
||||
{
|
||||
hub_free(data);
|
||||
data = NULL;
|
||||
status = cmd_status_arg_nick;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
data = hub_malloc(sizeof(*data));
|
||||
data->type = type_user;
|
||||
data->data.user = uman_get_user_by_cid(cbase->hub, token);
|
||||
if (!data->data.user)
|
||||
{
|
||||
hub_free(data);
|
||||
data = NULL;
|
||||
status = cmd_status_arg_cid;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
data = hub_malloc(sizeof(*data));
|
||||
data->type = type_address;
|
||||
if (ip_convert_to_binary(token, data->data.address) == -1)
|
||||
{
|
||||
hub_free(data);
|
||||
data = NULL;
|
||||
status = cmd_status_arg_address;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
data = hub_malloc(sizeof(*data));
|
||||
data->type = type_range;
|
||||
if (!ip_convert_address_to_range(token, data->data.range))
|
||||
{
|
||||
hub_free(data);
|
||||
data = NULL;
|
||||
status = cmd_status_arg_address;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
case 'p':
|
||||
data = hub_malloc(sizeof(*data));
|
||||
data->type = type_string;
|
||||
data->data.string = strdup(token);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
data = hub_malloc(sizeof(*data));
|
||||
data->type = type_command;
|
||||
data->data.command = command_handler_lookup(cbase, token);
|
||||
if (!data->data.command)
|
||||
{
|
||||
hub_free(data);
|
||||
data = NULL;
|
||||
status = cmd_status_arg_command;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
data = hub_malloc(sizeof(*data));
|
||||
data->type = type_credentials;
|
||||
if (!auth_string_to_cred(token, &data->data.credentials))
|
||||
{
|
||||
hub_free(data);
|
||||
data = NULL;
|
||||
status = cmd_status_arg_cred;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
data->type = type_integer;
|
||||
if (!is_number(token, &data->data.integer))
|
||||
{
|
||||
hub_free(data);
|
||||
data = NULL;
|
||||
return cmd_status_arg_number;
|
||||
}
|
||||
break;
|
||||
|
||||
case '\0':
|
||||
if (!opt)
|
||||
{
|
||||
status = cmd_status_missing_args;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = cmd_status_ok;
|
||||
}
|
||||
}
|
||||
|
||||
if (data)
|
||||
{
|
||||
list_append(args, data);
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
list_remove(tokens, token);
|
||||
hub_free(token);
|
||||
}
|
||||
|
||||
hub_free(data);
|
||||
return status;
|
||||
}
|
||||
|
||||
static struct command_handle* command_get_handler(struct command_base* cbase, const char* prefix, const struct hub_user* user, struct hub_command* cmd)
|
||||
{
|
||||
struct command_handle* handler = NULL;
|
||||
uhub_assert(cmd != NULL);
|
||||
|
||||
if (prefix && prefix[0] && prefix[1])
|
||||
{
|
||||
handler = command_handler_lookup(cbase, prefix + 1);
|
||||
if (handler)
|
||||
{
|
||||
cmd->ptr = handler->ptr;
|
||||
cmd->handler = handler->handler;
|
||||
cmd->status = command_is_available(handler, user) ? cmd_status_ok : cmd_status_access_error;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd->status = cmd_status_not_found;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd->status = cmd_status_syntax_error;
|
||||
}
|
||||
return handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a command and break it down into a struct hub_command.
|
||||
*/
|
||||
struct hub_command* command_parse(struct command_base* cbase, const struct hub_user* user, const char* message)
|
||||
{
|
||||
struct linked_list* tokens = list_create();
|
||||
struct hub_command* cmd = NULL;
|
||||
struct command_handle* handle = NULL;
|
||||
|
||||
cmd = hub_malloc_zero(sizeof(struct hub_command));
|
||||
cmd->status = cmd_status_ok;
|
||||
cmd->message = message;
|
||||
cmd->prefix = NULL;
|
||||
cmd->args = list_create();
|
||||
cmd->user = user;
|
||||
|
||||
if (split_string(message, " ", tokens, 0) <= 0)
|
||||
{
|
||||
cmd->status = cmd_status_syntax_error;
|
||||
goto command_parse_cleanup;
|
||||
}
|
||||
|
||||
// Setup hub command.
|
||||
cmd->prefix = strdup(((char*) list_get_first(tokens)) + 1);
|
||||
|
||||
// Find a matching command handler
|
||||
handle = command_get_handler(cbase, list_get_first(tokens), user, cmd);
|
||||
if (cmd->status != cmd_status_ok)
|
||||
goto command_parse_cleanup;
|
||||
|
||||
// Parse arguments
|
||||
cmd->status = command_extract_arguments(cbase, user, handle, tokens, cmd->args);
|
||||
goto command_parse_cleanup;
|
||||
|
||||
command_parse_cleanup:
|
||||
list_clear(tokens, &hub_free);
|
||||
list_destroy(tokens);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
void command_get_syntax(struct command_handle* handler, struct cbuffer* buf)
|
||||
{
|
||||
size_t n, arg_count;
|
||||
size_t n = 0;
|
||||
int opt = 0;
|
||||
char arg_code, last_arg = -1;
|
||||
|
||||
cbuf_append_format(buf, "!%s", handler->prefix);
|
||||
if (handler->args)
|
||||
{
|
||||
arg_count = strlen(handler->args);
|
||||
for (n = 0; n < arg_count; n++)
|
||||
for (n = 0; n < strlen(handler->args); n++)
|
||||
{
|
||||
if (!strchr("?+", last_arg))
|
||||
cbuf_append(buf, " ");
|
||||
arg_code = handler->args[n];
|
||||
switch (arg_code)
|
||||
if (n > 0 && !opt) cbuf_append(buf, " ");
|
||||
switch (handler->args[n])
|
||||
{
|
||||
case '?': cbuf_append(buf, "["); opt++; break;
|
||||
case '+': /* ignore */ break;
|
||||
case 'n': cbuf_append(buf, "<nick>"); break;
|
||||
case 'u': cbuf_append(buf, "<user>"); break;
|
||||
case 'i': cbuf_append(buf, "<cid>"); break;
|
||||
case 'a': cbuf_append(buf, "<addr>"); break;
|
||||
case 'r': cbuf_append(buf, "<addr range>"); break;
|
||||
case 'm': cbuf_append(buf, "<message>"); break;
|
||||
case 'p': cbuf_append(buf, "<password>"); break;
|
||||
case '?': cbuf_append(buf, "["); opt = 1; continue;
|
||||
case 'n': cbuf_append(buf, "<nick>"); break;
|
||||
case 'i': cbuf_append(buf, "<cid>"); break;
|
||||
case 'a': cbuf_append(buf, "<addr>"); break;
|
||||
case 'm': cbuf_append(buf, "<message>"); break;
|
||||
case 'p': cbuf_append(buf, "<password>"); break;
|
||||
case 'C': cbuf_append(buf, "<credentials>"); break;
|
||||
case 'c': cbuf_append(buf, "<command>"); break;
|
||||
case 'N': cbuf_append(buf, "<number>"); break;
|
||||
default: LOG_ERROR("unknown argument code '%c'", arg_code);
|
||||
case 'c': cbuf_append(buf, "<command>"); break;
|
||||
case 'N': cbuf_append(buf, "<number>"); break;
|
||||
}
|
||||
if (opt)
|
||||
{
|
||||
cbuf_append(buf, "]");
|
||||
opt = 0;
|
||||
}
|
||||
last_arg = arg_code;
|
||||
}
|
||||
while (opt--)
|
||||
cbuf_append(buf, "]");
|
||||
}
|
||||
}
|
||||
|
||||
@ -215,7 +450,7 @@ int command_check_args(struct hub_command* cmd, struct command_handle* handler)
|
||||
int command_invoke(struct command_base* cbase, struct hub_user* user, const char* message)
|
||||
{
|
||||
int ret = 0;
|
||||
struct hub_command* cmd = command_parse(cbase, cbase->hub, user, message);
|
||||
struct hub_command* cmd = command_parse(cbase, user, message);
|
||||
|
||||
switch (cmd->status)
|
||||
{
|
||||
@ -231,11 +466,14 @@ int command_invoke(struct command_base* cbase, struct hub_user* user, const char
|
||||
ret = send_command_access_denied(cbase, user, cmd->prefix);
|
||||
break;
|
||||
|
||||
case cmd_status_syntax_error:
|
||||
ret = send_command_syntax_error(cbase, user);
|
||||
break;
|
||||
|
||||
case cmd_status_missing_args:
|
||||
ret = send_command_missing_arguments(cbase, user, cmd);
|
||||
break;
|
||||
|
||||
case cmd_status_syntax_error:
|
||||
case cmd_status_arg_nick:
|
||||
case cmd_status_arg_cid:
|
||||
case cmd_status_arg_address:
|
||||
@ -251,28 +489,9 @@ int command_invoke(struct command_base* cbase, struct hub_user* user, const char
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t hub_command_arg_reset(struct hub_command* cmd)
|
||||
{
|
||||
cmd->args->iterator = NULL;
|
||||
return list_size(cmd->args);
|
||||
}
|
||||
|
||||
struct hub_command_arg_data* hub_command_arg_next(struct hub_command* cmd, enum hub_command_arg_type type)
|
||||
{
|
||||
struct hub_command_arg_data* ptr = (struct hub_command_arg_data*) list_get_next(cmd->args);
|
||||
if (!ptr)
|
||||
return NULL;
|
||||
|
||||
uhub_assert(ptr->type == type);
|
||||
if (ptr->type != type)
|
||||
return NULL;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static int command_status(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd, struct cbuffer* msg)
|
||||
{
|
||||
struct cbuffer* buf = cbuf_create(cbuf_size(msg) + strlen(cmd->prefix) + 7);
|
||||
struct cbuffer* buf = cbuf_create(cbuf_size(msg) + strlen(cmd->prefix) + 8);
|
||||
cbuf_append_format(buf, "*** %s: %s", cmd->prefix, cbuf_get(msg));
|
||||
send_message(cbase, user, buf);
|
||||
cbuf_destroy(msg);
|
||||
@ -283,30 +502,29 @@ static int command_help(struct command_base* cbase, struct hub_user* user, struc
|
||||
{
|
||||
size_t n;
|
||||
struct cbuffer* buf = cbuf_create(MAX_HELP_LINE);
|
||||
struct hub_command_arg_data* data = hub_command_arg_next(cmd, type_command);
|
||||
struct command_handle* command;
|
||||
struct hub_command_arg_data* data = list_get_first(cmd->args);
|
||||
struct command_handle* command = data->data.command;
|
||||
|
||||
if (!data)
|
||||
if (!command)
|
||||
{
|
||||
cbuf_append(buf, "Available commands:\n");
|
||||
|
||||
LIST_FOREACH(struct command_handle*, command, cbase->handlers,
|
||||
for (command = (struct command_handle*) list_get_first(cbase->handlers); command; command = (struct command_handle*) list_get_next(cbase->handlers))
|
||||
{
|
||||
if (command_is_available(command, user->credentials))
|
||||
if (command_is_available(command, user))
|
||||
{
|
||||
cbuf_append_format(buf, "!%s", command->prefix);
|
||||
for (n = strlen(command->prefix); n < cbase->prefix_length_max; n++)
|
||||
cbuf_append(buf, " ");
|
||||
cbuf_append_format(buf, " - %s\n", command->description);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
command = data->data.command;
|
||||
if (command_is_available(command, user->credentials))
|
||||
if (command_is_available(command, user))
|
||||
{
|
||||
cbuf_append_format(buf, "Usage: ");
|
||||
cbuf_append_format(buf, "Usage: !%s ", command->prefix);
|
||||
command_get_syntax(command, buf);
|
||||
cbuf_append_format(buf, "\n%s\n", command->description);
|
||||
}
|
||||
@ -341,8 +559,7 @@ static int command_uptime(struct command_base* cbase, struct hub_user* user, str
|
||||
static int command_kick(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
|
||||
{
|
||||
struct cbuffer* buf;
|
||||
struct hub_command_arg_data* arg = hub_command_arg_next(cmd, type_user);
|
||||
struct hub_user* target = arg->data.user;
|
||||
struct hub_user* target = list_get_first(cmd->args);
|
||||
|
||||
buf = cbuf_create(128);
|
||||
if (target == user)
|
||||
@ -357,6 +574,49 @@ static int command_kick(struct command_base* cbase, struct hub_user* user, struc
|
||||
return command_status(cbase, user, cmd, buf);
|
||||
}
|
||||
|
||||
static int command_ban(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
|
||||
{
|
||||
struct cbuffer* buf = cbuf_create(128);
|
||||
struct hub_user* target = list_get_first(cmd->args);
|
||||
|
||||
if (target == user)
|
||||
{
|
||||
cbuf_append(buf, "Cannot kick/ban yourself");
|
||||
}
|
||||
else
|
||||
{
|
||||
cbuf_append_format(buf, "Banning user \"%s\"", target->id.nick);
|
||||
|
||||
hub_disconnect_user(cbase->hub, target, quit_kicked);
|
||||
acl_user_ban_nick(cbase->hub->acl, target->id.nick);
|
||||
acl_user_ban_cid(cbase->hub->acl, target->id.cid);
|
||||
}
|
||||
return command_status(cbase, user, cmd, buf);
|
||||
}
|
||||
|
||||
static int command_unban(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
|
||||
{
|
||||
return command_status(cbase, user, cmd, cbuf_create_const("Not implemented"));
|
||||
}
|
||||
|
||||
static int command_mute(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
|
||||
{
|
||||
struct hub_user* target = list_get_first(cmd->args);
|
||||
struct cbuffer* buf = cbuf_create(128);
|
||||
|
||||
if (strlen(cmd->prefix) == 4)
|
||||
{
|
||||
cbuf_append_format(buf, "Muted \"%s\"", target->id.nick);
|
||||
user_flag_set(target, flag_muted);
|
||||
}
|
||||
else
|
||||
{
|
||||
cbuf_append_format(buf, "Unmuted \"%s\"", target->id.nick);
|
||||
user_flag_unset(target, flag_muted);
|
||||
}
|
||||
return command_status(cbase, user, cmd, buf);
|
||||
}
|
||||
|
||||
static int command_reload(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
|
||||
{
|
||||
cbase->hub->status = hub_status_restart;
|
||||
@ -406,23 +666,23 @@ static int command_myip(struct command_base* cbase, struct hub_user* user, struc
|
||||
static int command_getip(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
|
||||
{
|
||||
struct cbuffer* buf = cbuf_create(128);
|
||||
struct hub_command_arg_data* arg = hub_command_arg_next(cmd, type_user);
|
||||
cbuf_append_format(buf, "\"%s\" has address \"%s\"", arg->data.user->id.nick, user_get_address(arg->data.user));
|
||||
struct hub_user* target = list_get_first(cmd->args);
|
||||
cbuf_append_format(buf, "\"%s\" has address \"%s\"", target->id.nick, user_get_address(target));
|
||||
return command_status(cbase, user, cmd, buf);
|
||||
}
|
||||
|
||||
static int command_whoip(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
|
||||
{
|
||||
struct cbuffer* buf;
|
||||
struct hub_command_arg_data* arg = hub_command_arg_next(cmd, type_range);
|
||||
struct ip_range* range = list_get_first(cmd->args);
|
||||
struct linked_list* users = (struct linked_list*) list_create();
|
||||
struct hub_user* u;
|
||||
int ret = 0;
|
||||
|
||||
ret = uman_get_user_by_addr(cbase->hub->users, users, arg->data.range);
|
||||
ret = uman_get_user_by_addr(cbase->hub, users, 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 +690,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;
|
||||
}
|
||||
@ -445,9 +707,9 @@ static int command_whoip(struct command_base* cbase, struct hub_user* user, stru
|
||||
|
||||
static int command_broadcast(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
|
||||
{
|
||||
struct hub_command_arg_data* arg = hub_command_arg_next(cmd, type_string);
|
||||
char* message = arg->data.string;
|
||||
size_t message_len = strlen(message);
|
||||
size_t offset = 11;
|
||||
size_t message_len = strlen(cmd->message + offset);
|
||||
char* message = adc_msg_escape(cmd->message + offset);
|
||||
char pm_flag[7] = "PM";
|
||||
char from_sid[5];
|
||||
size_t recipients = 0;
|
||||
@ -458,7 +720,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,21 +738,22 @@ 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);
|
||||
hub_free(message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int command_log(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
|
||||
{
|
||||
struct cbuffer* buf;
|
||||
struct hub_command_arg_data* arg = hub_command_arg_next(cmd, type_string);
|
||||
struct linked_list* messages = cbase->hub->logout_info;
|
||||
struct hub_logout_info* log;
|
||||
char* search = arg ? arg->data.string : "";
|
||||
size_t search_len = strlen(search);
|
||||
char* search = 0;
|
||||
size_t search_len = 0;
|
||||
size_t search_hits = 0;
|
||||
|
||||
if (!list_size(messages))
|
||||
@ -500,14 +764,21 @@ static int command_log(struct command_base* cbase, struct hub_user* user, struct
|
||||
buf = cbuf_create(128);
|
||||
cbuf_append_format(buf, "Logged entries: " PRINTF_SIZE_T, list_size(messages));
|
||||
|
||||
search = list_get_first(cmd->args);
|
||||
if (search)
|
||||
{
|
||||
search_len = strlen(search);
|
||||
}
|
||||
|
||||
if (search_len)
|
||||
{
|
||||
cbuf_append_format(buf, ", searching for \"%s\"", search);
|
||||
cbuf_append_format(buf, ", searching for \"%s\"", list_size(messages), search);
|
||||
}
|
||||
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 +802,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)
|
||||
{
|
||||
@ -545,32 +817,127 @@ static int command_log(struct command_base* cbase, struct hub_user* user, struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int command_register(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
|
||||
{
|
||||
struct cbuffer* buf = cbuf_create(128);
|
||||
struct auth_info data;
|
||||
struct hub_command_arg_data* args = (struct hub_command_arg_data*) list_get_first(cmd->args);
|
||||
char* password = args->data.string;
|
||||
|
||||
strncpy(data.nickname, user->id.nick, MAX_NICK_LEN);
|
||||
strncpy(data.password, password, MAX_PASS_LEN);
|
||||
data.nickname[MAX_NICK_LEN] = '\0';
|
||||
data.password[MAX_PASS_LEN] = '\0';
|
||||
data.credentials = auth_cred_user;
|
||||
|
||||
if (acl_register_user(cbase->hub, &data))
|
||||
{
|
||||
cbuf_append_format(buf, "User \"%s\" registered.", user->id.nick);
|
||||
}
|
||||
else
|
||||
{
|
||||
cbuf_append_format(buf, "Unable to register user \"%s\".", user->id.nick);
|
||||
}
|
||||
return command_status(cbase, user, cmd, buf);
|
||||
}
|
||||
|
||||
static int command_password(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
|
||||
{
|
||||
struct cbuffer* buf = cbuf_create(128);
|
||||
struct auth_info data;
|
||||
struct hub_command_arg_data* args = (struct hub_command_arg_data*) list_get_first(cmd->args);
|
||||
char* password = args->data.string;
|
||||
|
||||
strncpy(data.nickname, user->id.nick, MAX_NICK_LEN);
|
||||
strncpy(data.password, password, MAX_PASS_LEN);
|
||||
data.nickname[MAX_NICK_LEN] = '\0';
|
||||
data.password[MAX_PASS_LEN] = '\0';
|
||||
data.credentials = user->credentials;
|
||||
|
||||
if (acl_update_user(cbase->hub, &data))
|
||||
{
|
||||
cbuf_append(buf, "Password changed.");
|
||||
}
|
||||
else
|
||||
{
|
||||
cbuf_append_format(buf, "Unable to change password for user \"%s\".", user->id.nick);
|
||||
}
|
||||
return command_status(cbase, user, cmd, buf);
|
||||
}
|
||||
|
||||
static int command_useradd(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
|
||||
{
|
||||
struct cbuffer* buf = cbuf_create(128);
|
||||
struct auth_info data;
|
||||
char* nick = list_get_first(cmd->args);
|
||||
char* pass = list_get_next(cmd->args);
|
||||
char* cred = list_get_next(cmd->args);
|
||||
enum auth_credentials credentials;
|
||||
|
||||
if (!(cred && auth_string_to_cred(cred, &credentials)))
|
||||
credentials = auth_cred_user;
|
||||
|
||||
strncpy(data.nickname, nick, MAX_NICK_LEN);
|
||||
strncpy(data.password, pass, MAX_PASS_LEN);
|
||||
data.nickname[MAX_NICK_LEN] = '\0';
|
||||
data.password[MAX_PASS_LEN] = '\0';
|
||||
data.credentials = credentials;
|
||||
|
||||
if (acl_register_user(cbase->hub, &data))
|
||||
cbuf_append_format(buf, "User \"%s\" registered.", nick);
|
||||
else
|
||||
cbuf_append_format(buf, "Unable to register user \"%s\".", nick);
|
||||
return command_status(cbase, user, cmd, buf);
|
||||
}
|
||||
|
||||
static int command_userdel(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
|
||||
{
|
||||
struct cbuffer* buf = cbuf_create(128);
|
||||
char* nick = list_get_first(cmd->args);
|
||||
|
||||
if (acl_delete_user(cbase->hub, nick))
|
||||
cbuf_append_format(buf, "User \"%s\" is deleted.", nick);
|
||||
else
|
||||
cbuf_append_format(buf, "Unable to delete user \"%s\".", nick);
|
||||
return command_status(cbase, user, cmd, buf);
|
||||
}
|
||||
|
||||
static int command_usermod(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
|
||||
{
|
||||
return command_status(cbase, user, cmd, cbuf_create_const("Not implemented!"));
|
||||
}
|
||||
|
||||
static int command_userinfo(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
|
||||
{
|
||||
return command_status(cbase, user, cmd, cbuf_create_const("Not implemented!"));
|
||||
}
|
||||
|
||||
static int command_userpass(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
|
||||
{
|
||||
return command_status(cbase, user, cmd, cbuf_create_const("Not implemented!"));
|
||||
}
|
||||
|
||||
#ifdef CRASH_DEBUG
|
||||
static int command_crash(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
|
||||
{
|
||||
void (*crash)(void) = NULL;
|
||||
crash();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int command_stats(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
|
||||
{
|
||||
struct cbuffer* buf = cbuf_create(128);
|
||||
struct hub_info* hub = cbase->hub;
|
||||
static char rxbuf[64] = { "0 B" };
|
||||
static char txbuf[64] = { "0 B" };
|
||||
|
||||
cbuf_append(buf, "Hub statistics: ");
|
||||
cbuf_append_format(buf, PRINTF_SIZE_T "/" PRINTF_SIZE_T " users (peak %d). ", hub->users->count, hub->config->max_users, hub->users->count_peak);
|
||||
|
||||
format_size(hub->stats.net_rx, rxbuf, sizeof(rxbuf));
|
||||
format_size(hub->stats.net_tx, txbuf, sizeof(txbuf));
|
||||
|
||||
cbuf_append_format(buf, "Network: tx=%s/s, rx=%s/s", txbuf, rxbuf);
|
||||
|
||||
#ifdef SHOW_PEAK_NET_STATS /* currently disabled */
|
||||
format_size(hub->stats.net_rx_peak, rxbuf, sizeof(rxbuf));
|
||||
format_size(hub->stats.net_tx_peak, txbuf, sizeof(txbuf));
|
||||
cbuf_append_format(buf, ", peak_tx=%s/s, peak_rx=%s/s", txbuf, rxbuf);
|
||||
#endif
|
||||
|
||||
format_size(hub->stats.net_rx_total, rxbuf, sizeof(rxbuf));
|
||||
format_size(hub->stats.net_tx_total, txbuf, sizeof(txbuf));
|
||||
cbuf_append_format(buf, ", total_tx=%s", txbuf);
|
||||
cbuf_append_format(buf, ", total_rx=%s", rxbuf);
|
||||
|
||||
cbuf_append_format(buf, PRINTF_SIZE_T " users, peak: " PRINTF_SIZE_T ". Network (up/down): %d/%d KB/s, peak: %d/%d KB/s",
|
||||
hub->users->count,
|
||||
hub->users->count_peak,
|
||||
(int) hub->stats.net_tx / 1024,
|
||||
(int) hub->stats.net_rx / 1024,
|
||||
(int) hub->stats.net_tx_peak / 1024,
|
||||
(int) hub->stats.net_rx_peak / 1024);
|
||||
return command_status(cbase, user, cmd, buf);
|
||||
}
|
||||
|
||||
@ -593,18 +960,32 @@ static struct command_handle* add_builtin(struct command_base* cbase, const char
|
||||
|
||||
void commands_builtin_add(struct command_base* cbase)
|
||||
{
|
||||
ADD_COMMAND("broadcast", 9, "+m",auth_cred_operator, command_broadcast,"Send a message to all users" );
|
||||
ADD_COMMAND("getip", 5, "u", auth_cred_operator, command_getip, "Show IP address for a user" );
|
||||
ADD_COMMAND("ban", 3, "n", auth_cred_operator, command_ban, "Ban a user" );
|
||||
ADD_COMMAND("broadcast", 9, "m", auth_cred_operator, command_broadcast,"Send a message to all users" );
|
||||
#ifdef CRASH_DEBUG
|
||||
ADD_COMMAND("crash", 5, "", auth_cred_admin, command_crash, "Crash the hub (DEBUG)." );
|
||||
#endif
|
||||
ADD_COMMAND("getip", 5, "n", auth_cred_operator, command_getip, "Show IP address for a user" );
|
||||
ADD_COMMAND("help", 4, "?c",auth_cred_guest, command_help, "Show this help message." );
|
||||
ADD_COMMAND("kick", 4, "u", auth_cred_operator, command_kick, "Kick a user" );
|
||||
ADD_COMMAND("log", 3, "?m",auth_cred_operator, command_log, "Display log" ); // fail
|
||||
ADD_COMMAND("kick", 4, "n", auth_cred_operator, command_kick, "Kick a user" );
|
||||
ADD_COMMAND("log", 3, "?m", auth_cred_operator, command_log, "Display log" ); // fail
|
||||
ADD_COMMAND("mute", 4, "n", auth_cred_operator, command_mute, "Mute user" );
|
||||
ADD_COMMAND("myip", 4, "", auth_cred_guest, command_myip, "Show your own IP." );
|
||||
ADD_COMMAND("register", 8, "p", auth_cred_guest, command_register, "Register your username." ); // fail
|
||||
ADD_COMMAND("reload", 6, "", auth_cred_admin, command_reload, "Reload configuration files." );
|
||||
ADD_COMMAND("password", 8, "p", auth_cred_user, command_password, "Change your own password." ); // fail
|
||||
ADD_COMMAND("shutdown", 8, "", auth_cred_admin, command_shutdown_hub, "Shutdown hub." );
|
||||
ADD_COMMAND("stats", 5, "", auth_cred_super, command_stats, "Show hub statistics." );
|
||||
ADD_COMMAND("unban", 5, "n", auth_cred_operator, command_unban, "Lift ban on a user" ); // not implemented
|
||||
ADD_COMMAND("unmute", 6, "n", auth_cred_operator, command_mute, "Unmute user" );
|
||||
ADD_COMMAND("uptime", 6, "", auth_cred_guest, command_uptime, "Display hub uptime info." );
|
||||
ADD_COMMAND("useradd", 7, "np",auth_cred_operator, command_useradd, "Register a new user." ); // fail
|
||||
ADD_COMMAND("userdel", 7, "n", auth_cred_operator, command_userdel, "Delete a registered user." ); // fail
|
||||
ADD_COMMAND("userinfo", 8, "n", auth_cred_operator, command_userinfo, "Show registered user info." ); // fail
|
||||
ADD_COMMAND("usermod", 7, "nC",auth_cred_admin, command_usermod, "Modify user credentials." ); // fail
|
||||
ADD_COMMAND("userpass", 8, "np",auth_cred_operator, command_userpass, "Change password for a user." ); // fail
|
||||
ADD_COMMAND("version", 7, "", auth_cred_guest, command_version, "Show hub version info." );
|
||||
ADD_COMMAND("whoip", 5, "r", auth_cred_operator, command_whoip, "Show users matching IP range" );
|
||||
ADD_COMMAND("whoip", 5, "a", auth_cred_operator, command_whoip, "Show users matching IP range" ); // ok
|
||||
|
||||
#ifdef DEBUG_UNLOAD_PLUGINS
|
||||
ADD_COMMAND("load", 4, "", auth_cred_admin, command_load, "Load plugins." );
|
||||
|
@ -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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -24,12 +24,77 @@ struct command_base;
|
||||
struct command_handle;
|
||||
struct hub_command;
|
||||
|
||||
typedef int (*command_handler)(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd);
|
||||
|
||||
enum command_parse_status
|
||||
{
|
||||
cmd_status_ok, /** <<< "Everything seems to OK" */
|
||||
cmd_status_not_found, /** <<< "Command was not found" */
|
||||
cmd_status_access_error, /** <<< "You don't have access to this command" */
|
||||
cmd_status_syntax_error, /** <<< "Not a valid command." */
|
||||
cmd_status_missing_args, /** <<< "Missing some or all required arguments." */
|
||||
cmd_status_arg_nick, /** <<< "A nick argument does not match an online user. ('n')" */
|
||||
cmd_status_arg_cid, /** <<< "A cid argument does not match an online user. ('i')." */
|
||||
cmd_status_arg_address, /** <<< "A address range argument is not valid ('a')." */
|
||||
cmd_status_arg_number, /** <<< "A number argument is not valid ('N')" */
|
||||
cmd_status_arg_cred, /** <<< "A credentials argument is not valid ('C')" */
|
||||
cmd_status_arg_command, /** <<< "A command argument is not valid ('c')" */
|
||||
};
|
||||
|
||||
struct hub_command_arg_data
|
||||
{
|
||||
enum Type {
|
||||
type_integer,
|
||||
type_string,
|
||||
type_user,
|
||||
type_address,
|
||||
type_range,
|
||||
type_credentials,
|
||||
type_command
|
||||
} type;
|
||||
|
||||
union {
|
||||
int integer;
|
||||
char* string;
|
||||
struct hub_user* user;
|
||||
struct ip_addr_encap* address;
|
||||
struct ip_range* range;
|
||||
enum auth_credentials credentials;
|
||||
struct command_handle* command;
|
||||
} data;
|
||||
|
||||
struct hub_command_arg_data* next;
|
||||
};
|
||||
|
||||
void hub_command_args_free(struct hub_command* command);
|
||||
|
||||
/**
|
||||
* This struct contains all information needed to invoke
|
||||
* a command, which includes the whole message, the prefix,
|
||||
* the decoded arguments (according to parameter list), and
|
||||
* the user pointer (ptr) which comes from the command it was matched to.
|
||||
*
|
||||
* The message and prefix is generally always available, but args only
|
||||
* if status == cmd_status_ok.
|
||||
* Handler and ptr are NULL if status == cmd_status_not_found, or status == cmd_status_access_error.
|
||||
* Ptr might also be NULL if cmd_status_ok because the command that handles it was added with a NULL ptr.
|
||||
*/
|
||||
struct hub_command
|
||||
{
|
||||
const char* message; /**<<< "The complete message." */
|
||||
char* prefix; /**<<< "The prefix extracted from the message." */
|
||||
struct linked_list* args; /**<<< "List of all parsed arguments from the message. Type depends on expectations." */
|
||||
enum command_parse_status status; /**<<< "Status of the hub_command." */
|
||||
command_handler handler; /**<<< "The function handler to call in order to invoke this command." */
|
||||
const struct hub_user* user; /**<<< "The user who invoked this command." */
|
||||
void* ptr; /**<<< "A pointer of data which came from struct command_handler" */
|
||||
};
|
||||
|
||||
/**
|
||||
* Argument codes are used to automatically parse arguments
|
||||
* for a a hub command.
|
||||
*
|
||||
* u = user (must exist in hub session, or will cause error)
|
||||
* n = nick name (string)
|
||||
* n = nick name (must exist in hub session)
|
||||
* i = CID (must exist in hub)
|
||||
* a = (IP) address (must be a valid IPv4 or IPv6 address)
|
||||
* r = (IP) address range (either: IP-IP or IP/mask, both IPv4 or IPv6 work)
|
||||
@ -40,17 +105,12 @@ struct hub_command;
|
||||
* N = number (integer)
|
||||
*
|
||||
* Prefix an argument with ? to make it optional.
|
||||
* Prefix with + to make the argument greedy, which causes it to grab the rest of the line ignoring boundaries (only supported for string types).
|
||||
*
|
||||
* NOTE: if an argument is optional then all following arguments must also be optional.
|
||||
* NOTE: You can combine optional and greedy, example: "?+m" would match "", "a", "a b c", etc.
|
||||
* NOTE; if an argument is optional then all following arguments must also be optional.
|
||||
*
|
||||
* Example:
|
||||
* "nia" means "nick cid ip"
|
||||
* "n?p" means "nick [password]" where password is optional.
|
||||
* "?N?N" means zero, one, or two integers.
|
||||
* "?NN" means zero or two integers.
|
||||
* "?+m" means an optional string which may contain spaces that would otherwise be split into separate arguments.
|
||||
*
|
||||
*/
|
||||
struct command_handle
|
||||
{
|
||||
@ -93,15 +153,22 @@ extern int command_del(struct command_base*, struct command_handle*);
|
||||
extern int command_invoke(struct command_base*, struct hub_user* user, const char* message);
|
||||
|
||||
/**
|
||||
* Returns 1 if the command handle can be used with the given credentials, 0 otherwise.
|
||||
* Parse a message as a command and return a status indicating if the command
|
||||
* is valid and that the arguments are sane.
|
||||
*
|
||||
* @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 invokation prefix '!' or '+')
|
||||
*
|
||||
* @return a hub_command that must be freed with command_free(). @See struct hub_command.
|
||||
*/
|
||||
int command_is_available(struct command_handle* handle, enum auth_credentials credentials);
|
||||
extern struct hub_command* command_parse(struct command_base* cbase, const struct hub_user* user, const char* message);
|
||||
|
||||
/**
|
||||
* Lookup a command handle based on prefix.
|
||||
* If no matching command handle is found then NULL is returned.
|
||||
* Free a hub_command that was created in command_parse().
|
||||
*/
|
||||
struct command_handle* command_handler_lookup(struct command_base* cbase, const char* prefix);
|
||||
extern void command_free(struct hub_command* command);
|
||||
|
||||
|
||||
extern void commands_builtin_add(struct command_base*);
|
||||
extern void commands_builtin_remove(struct command_base*);
|
||||
|
@ -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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -76,7 +76,7 @@ static int config_parse_line(char* line, int line_count, void* ptr_data)
|
||||
struct hub_config* config = (struct hub_config*) ptr_data;
|
||||
|
||||
strip_off_ini_line_comments(line, line_count);
|
||||
|
||||
|
||||
if (!*line) return 0;
|
||||
|
||||
LOG_DUMP("config_parse_line(): '%s'", line);
|
||||
|
@ -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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
241
src/core/config.pl
Executable file
241
src/core/config.pl
Executable file
@ -0,0 +1,241 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use strict;
|
||||
use XML::Twig;
|
||||
|
||||
sub write_c_header(@);
|
||||
sub write_c_impl_defaults(@);
|
||||
sub write_c_impl_apply(@);
|
||||
sub write_c_impl_free(@);
|
||||
sub write_c_impl_dump(@);
|
||||
sub get_data($);
|
||||
|
||||
# initialize parser and read the file
|
||||
my $input = "./config.xml";
|
||||
my $parser = XML::Twig->new();
|
||||
my $tree = $parser->parsefile($input) || die "Unable to parse XML file.";
|
||||
|
||||
# Write header file
|
||||
open GENHEAD, ">gen_config.h" || die "Unable to write header file";
|
||||
print GENHEAD "/* THIS FILE IS AUTOGENERATED - DO NOT CHANGE IT! */\n\nstruct hub_config\n{\n";
|
||||
foreach my $p ($tree->root->children("option"))
|
||||
{
|
||||
write_c_header(get_data($p));
|
||||
}
|
||||
print GENHEAD "};\n\n";
|
||||
|
||||
# Write c source file
|
||||
open GENIMPL, ">gen_config.c" || die "Unable to write source file";
|
||||
print GENIMPL "/* THIS FILE IS AUTOGENERATED - DO NOT CHANGE IT! */\n\n";
|
||||
|
||||
# The defaults function
|
||||
print GENIMPL "void config_defaults(struct hub_config* config)\n{\n";
|
||||
foreach my $p ($tree->root->children("option"))
|
||||
{
|
||||
write_c_impl_defaults(get_data($p));
|
||||
}
|
||||
print GENIMPL "}\n\n";
|
||||
|
||||
# apply function
|
||||
print GENIMPL "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";
|
||||
|
||||
foreach my $p ($tree->root->children("option"))
|
||||
{
|
||||
write_c_impl_apply(get_data($p));
|
||||
}
|
||||
print GENIMPL "\t/* Still here -- unknown directive */\n";
|
||||
print GENIMPL "\tLOG_ERROR(\"Unknown configuration directive: '%s'\", key);\n";
|
||||
print GENIMPL "\t\treturn -1;\n";
|
||||
print GENIMPL "}\n\n";
|
||||
|
||||
# free function (for strings)
|
||||
print GENIMPL "void free_config(struct hub_config* config)\n{\n";
|
||||
foreach my $p ($tree->root->children("option"))
|
||||
{
|
||||
write_c_impl_free(get_data($p));
|
||||
}
|
||||
print GENIMPL "}\n\n";
|
||||
|
||||
# dump function
|
||||
print GENIMPL "void dump_config(struct hub_config* config, int ignore_defaults)\n{\n";
|
||||
foreach my $p ($tree->root->children("option"))
|
||||
{
|
||||
write_c_impl_dump(get_data($p));
|
||||
}
|
||||
print GENIMPL "}\n\n";
|
||||
|
||||
|
||||
|
||||
sub write_c_header(@)
|
||||
{
|
||||
my @output = @_;
|
||||
my ($type, $name, $default, $advanced, $short, $desc, $since, $example) = @output;
|
||||
|
||||
print GENHEAD "\t";
|
||||
print GENHEAD "int " if ($type eq "int");
|
||||
print GENHEAD "int " if ($type eq "boolean");
|
||||
print GENHEAD "char*" if ($type =~ /(string|file|message)/);
|
||||
print GENHEAD " " . $name . ";";
|
||||
|
||||
my $comment = "";
|
||||
if ($type eq "message")
|
||||
{
|
||||
$comment = "\"" . $default . "\"";
|
||||
}
|
||||
elsif (defined $short && length $short > 0)
|
||||
{
|
||||
$comment = $short;
|
||||
$comment .= " (default: " . $default . ")" if (defined $default);
|
||||
}
|
||||
|
||||
if (length $comment > 0)
|
||||
{
|
||||
my $pad = "";
|
||||
for (my $i = length $name; $i < 32; $i++)
|
||||
{
|
||||
$pad .= " ";
|
||||
}
|
||||
$comment = $pad . "/*<<< " . $comment . " */";
|
||||
}
|
||||
|
||||
print GENHEAD $comment . "\n";
|
||||
}
|
||||
|
||||
sub write_c_impl_defaults(@)
|
||||
{
|
||||
my @output = @_;
|
||||
my ($type, $name, $default, $advanced, $short, $desc, $since, $example) = @output;
|
||||
my $prefix = "";
|
||||
my $suffix = "";
|
||||
|
||||
print GENIMPL "\tconfig->$name = ";
|
||||
if ($type =~ /(string|file|message)/)
|
||||
{
|
||||
$prefix = "hub_strdup(\"";
|
||||
$suffix = "\")"
|
||||
}
|
||||
print GENIMPL $prefix . $default . $suffix . ";\n";
|
||||
}
|
||||
|
||||
sub write_c_impl_apply(@)
|
||||
{
|
||||
my @output = @_;
|
||||
my ($type, $name, $default, $advanced, $short, $desc, $since, $example, $p) = @output;
|
||||
|
||||
my $min;
|
||||
my $max;
|
||||
my $regexp;
|
||||
|
||||
if (defined $p)
|
||||
{
|
||||
$min = $p->att("min");
|
||||
$max = $p->att("max");
|
||||
$regexp = $p->att("regexp");
|
||||
|
||||
print "'check' is defined for option $name";
|
||||
print ", min=$min" if (defined $min);
|
||||
print ", max=$max" if (defined $max);
|
||||
print ", regexp=\"$regexp\"" if (defined $regexp);
|
||||
print "\n";
|
||||
}
|
||||
|
||||
print GENIMPL "\tif (!strcmp(key, \"" . $name . "\"))\n\t{\n";
|
||||
|
||||
if ($type eq "int")
|
||||
{
|
||||
if (defined $min)
|
||||
{
|
||||
print GENIMPL "\t\tmin = $min;\n"
|
||||
}
|
||||
if (defined $max)
|
||||
{
|
||||
print GENIMPL "\t\tmax = $max;\n"
|
||||
}
|
||||
|
||||
print GENIMPL "\t\tif (!apply_integer(key, data, &config->$name, ";
|
||||
|
||||
if (defined $min)
|
||||
{
|
||||
print GENIMPL "&min";
|
||||
}
|
||||
else
|
||||
{
|
||||
print GENIMPL "0";
|
||||
}
|
||||
|
||||
print GENIMPL ", ";
|
||||
|
||||
if (defined $max)
|
||||
{
|
||||
print GENIMPL "&max";
|
||||
}
|
||||
else
|
||||
{
|
||||
print GENIMPL "0";
|
||||
}
|
||||
|
||||
print GENIMPL "))\n";
|
||||
}
|
||||
elsif ($type eq "boolean")
|
||||
{
|
||||
print GENIMPL "\t\tif (!apply_boolean(key, data, &config->$name))\n";
|
||||
}
|
||||
elsif ($type =~ /(string|file|message)/)
|
||||
{
|
||||
print GENIMPL "\t\tif (!apply_string(key, data, &config->$name, (char*) \"\"))\n";
|
||||
}
|
||||
|
||||
print GENIMPL "\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";
|
||||
}
|
||||
|
||||
sub write_c_impl_free(@)
|
||||
{
|
||||
my @output = @_;
|
||||
my ($type, $name, $default, $advanced, $short, $desc, $since, $example) = @output;
|
||||
|
||||
if ($type =~ /(string|file|message)/)
|
||||
{
|
||||
print GENIMPL "\thub_free(config->" . $name . ");\n\n"
|
||||
}
|
||||
}
|
||||
|
||||
sub write_c_impl_dump(@)
|
||||
{
|
||||
my @output = @_;
|
||||
my ($type, $name, $default, $advanced, $short, $desc, $since, $example) = @output;
|
||||
my $out;
|
||||
my $val = "config->$name";
|
||||
my $test = "config->$name != $default";
|
||||
|
||||
if ($type eq "int")
|
||||
{
|
||||
$out = "%d";
|
||||
}
|
||||
elsif ($type eq "boolean")
|
||||
{
|
||||
$out = "%s";
|
||||
$val = "config->$name ? \"yes\" : \"no\"";
|
||||
}
|
||||
elsif ($type =~ /(string|file|message)/)
|
||||
{
|
||||
$out = "\\\"%s\\\"";
|
||||
$test = "strcmp(config->$name, \"$default\") != 0";
|
||||
}
|
||||
|
||||
print GENIMPL "\tif (!ignore_defaults || $test)\n";
|
||||
print GENIMPL "\t\tfprintf(stdout, \"$name = $out\\n\", $val);\n\n";
|
||||
}
|
||||
|
||||
sub get_data($)
|
||||
{
|
||||
my $p = shift;
|
||||
my $check = $p->first_child_matches("check");
|
||||
my @data = ($p->att("type"), $p->att("name"), $p->att("default"), $p->att("advanced"), $p->children_text("short"), $p->children_text("description"), $p->children_text("since"), $p->children_text("example"), $check);
|
||||
return @data;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -13,11 +13,11 @@
|
||||
<check min="1" max="65535" />
|
||||
<since>0.1.0</since>
|
||||
<short>Server port to bind to</short>
|
||||
<description><![CDATA[This specifies the port number the hub should listen on.]]></description>
|
||||
<description><![CDATA[This is specifies the port number the hub should listen on.]]></description>
|
||||
</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.
|
||||
@ -170,7 +170,7 @@
|
||||
<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>
|
||||
@ -409,7 +409,7 @@
|
||||
</option>
|
||||
|
||||
<option name="tls_require" type="boolean" default="0">
|
||||
<short>If SSL/TLS enabled, should it be required</short>
|
||||
<short>If SSL/TLS enabled, should it be required (default: 0)</short>
|
||||
<description><![CDATA[
|
||||
If TLS/SSL support is enabled it can either be optional or mandatory.
|
||||
If this option is disabled then SSL/TLS is not required to enter the hub, however it is possible to enter either with or without.
|
||||
@ -419,7 +419,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 +428,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 +445,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 +534,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>
|
||||
|
||||
@ -623,7 +590,7 @@
|
||||
</option>
|
||||
|
||||
<option name="msg_error_no_memory" type="message" default="No memory">
|
||||
<description><![CDATA[Hub has no more memory]]></description>
|
||||
<description><![CDATA[]]></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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -32,20 +32,20 @@ int event_queue_initialize(struct event_queue** queue, event_queue_callback call
|
||||
*queue = (struct event_queue*) hub_malloc_zero(sizeof(struct event_queue));
|
||||
if (!(*queue))
|
||||
return -1;
|
||||
|
||||
|
||||
(*queue)->q1 = list_create();
|
||||
(*queue)->q2 = list_create();
|
||||
|
||||
|
||||
if (!(*queue)->q1 || !(*queue)->q2)
|
||||
{
|
||||
list_destroy((*queue)->q1);
|
||||
list_destroy((*queue)->q2);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
(*queue)->callback = callback;
|
||||
(*queue)->callback_data = ptr;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -73,27 +73,35 @@ int event_queue_process(struct event_queue* queue)
|
||||
struct event_data* data;
|
||||
if (queue->locked)
|
||||
return 0;
|
||||
|
||||
|
||||
/* 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);
|
||||
|
||||
assert(list_size(queue->q1) == 0);
|
||||
|
||||
/* unlock 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))
|
||||
{
|
||||
@ -106,18 +114,18 @@ void event_queue_post(struct event_queue* queue, struct event_data* message)
|
||||
{
|
||||
struct linked_list* q = (!queue->locked) ? queue->q1 : queue->q2;
|
||||
struct event_data* data;
|
||||
|
||||
|
||||
data = (struct event_data*) hub_malloc(sizeof(struct event_data));
|
||||
if (data)
|
||||
{
|
||||
data->id = message->id;
|
||||
data->ptr = message->ptr;
|
||||
data->flags = message->flags;
|
||||
|
||||
|
||||
#ifdef EQ_DEBUG
|
||||
eq_debug("POST", data);
|
||||
#endif
|
||||
|
||||
|
||||
list_append(q, data);
|
||||
}
|
||||
else
|
||||
|
@ -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)
|
||||
{
|
||||
@ -51,8 +45,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");
|
||||
@ -110,9 +102,7 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
|
||||
|
||||
if (!strcmp(key, "server_port"))
|
||||
{
|
||||
min = 1;
|
||||
max = 65535;
|
||||
if (!apply_integer(key, data, &config->server_port, &min, &max))
|
||||
if (!apply_integer(key, data, &config->server_port, 0, 0))
|
||||
{
|
||||
LOG_ERROR("Configuration parse error on line %d", line_count);
|
||||
return -1;
|
||||
@ -132,8 +122,7 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
|
||||
|
||||
if (!strcmp(key, "server_listen_backlog"))
|
||||
{
|
||||
min = 5;
|
||||
if (!apply_integer(key, data, &config->server_listen_backlog, &min, 0))
|
||||
if (!apply_integer(key, data, &config->server_listen_backlog, 0, 0))
|
||||
{
|
||||
LOG_ERROR("Configuration parse error on line %d", line_count);
|
||||
return -1;
|
||||
@ -255,9 +244,7 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
|
||||
|
||||
if (!strcmp(key, "max_recv_buffer"))
|
||||
{
|
||||
min = 1024;
|
||||
max = 1048576;
|
||||
if (!apply_integer(key, data, &config->max_recv_buffer, &min, &max))
|
||||
if (!apply_integer(key, data, &config->max_recv_buffer, 0, 0))
|
||||
{
|
||||
LOG_ERROR("Configuration parse error on line %d", line_count);
|
||||
return -1;
|
||||
@ -267,8 +254,7 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
|
||||
|
||||
if (!strcmp(key, "max_send_buffer"))
|
||||
{
|
||||
min = 2048;
|
||||
if (!apply_integer(key, data, &config->max_send_buffer, &min, 0))
|
||||
if (!apply_integer(key, data, &config->max_send_buffer, 0, 0))
|
||||
{
|
||||
LOG_ERROR("Configuration parse error on line %d", line_count);
|
||||
return -1;
|
||||
@ -278,8 +264,7 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
|
||||
|
||||
if (!strcmp(key, "max_send_buffer_soft"))
|
||||
{
|
||||
min = 1024;
|
||||
if (!apply_integer(key, data, &config->max_send_buffer_soft, &min, 0))
|
||||
if (!apply_integer(key, data, &config->max_send_buffer_soft, 0, 0))
|
||||
{
|
||||
LOG_ERROR("Configuration parse error on line %d", line_count);
|
||||
return -1;
|
||||
@ -299,9 +284,7 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
|
||||
|
||||
if (!strcmp(key, "max_chat_history"))
|
||||
{
|
||||
min = 0;
|
||||
max = 250;
|
||||
if (!apply_integer(key, data, &config->max_chat_history, &min, &max))
|
||||
if (!apply_integer(key, data, &config->max_chat_history, 0, 0))
|
||||
{
|
||||
LOG_ERROR("Configuration parse error on line %d", line_count);
|
||||
return -1;
|
||||
@ -311,9 +294,7 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
|
||||
|
||||
if (!strcmp(key, "max_logout_log"))
|
||||
{
|
||||
min = 0;
|
||||
max = 2000;
|
||||
if (!apply_integer(key, data, &config->max_logout_log, &min, &max))
|
||||
if (!apply_integer(key, data, &config->max_logout_log, 0, 0))
|
||||
{
|
||||
LOG_ERROR("Configuration parse error on line %d", line_count);
|
||||
return -1;
|
||||
@ -323,8 +304,7 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
|
||||
|
||||
if (!strcmp(key, "limit_max_hubs_user"))
|
||||
{
|
||||
min = 0;
|
||||
if (!apply_integer(key, data, &config->limit_max_hubs_user, &min, 0))
|
||||
if (!apply_integer(key, data, &config->limit_max_hubs_user, 0, 0))
|
||||
{
|
||||
LOG_ERROR("Configuration parse error on line %d", line_count);
|
||||
return -1;
|
||||
@ -334,8 +314,7 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
|
||||
|
||||
if (!strcmp(key, "limit_max_hubs_reg"))
|
||||
{
|
||||
min = 0;
|
||||
if (!apply_integer(key, data, &config->limit_max_hubs_reg, &min, 0))
|
||||
if (!apply_integer(key, data, &config->limit_max_hubs_reg, 0, 0))
|
||||
{
|
||||
LOG_ERROR("Configuration parse error on line %d", line_count);
|
||||
return -1;
|
||||
@ -345,8 +324,7 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
|
||||
|
||||
if (!strcmp(key, "limit_max_hubs_op"))
|
||||
{
|
||||
min = 0;
|
||||
if (!apply_integer(key, data, &config->limit_max_hubs_op, &min, 0))
|
||||
if (!apply_integer(key, data, &config->limit_max_hubs_op, 0, 0))
|
||||
{
|
||||
LOG_ERROR("Configuration parse error on line %d", line_count);
|
||||
return -1;
|
||||
@ -356,8 +334,7 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
|
||||
|
||||
if (!strcmp(key, "limit_max_hubs"))
|
||||
{
|
||||
min = 0;
|
||||
if (!apply_integer(key, data, &config->limit_max_hubs, &min, 0))
|
||||
if (!apply_integer(key, data, &config->limit_max_hubs, 0, 0))
|
||||
{
|
||||
LOG_ERROR("Configuration parse error on line %d", line_count);
|
||||
return -1;
|
||||
@ -367,8 +344,7 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
|
||||
|
||||
if (!strcmp(key, "limit_min_hubs_user"))
|
||||
{
|
||||
min = 0;
|
||||
if (!apply_integer(key, data, &config->limit_min_hubs_user, &min, 0))
|
||||
if (!apply_integer(key, data, &config->limit_min_hubs_user, 0, 0))
|
||||
{
|
||||
LOG_ERROR("Configuration parse error on line %d", line_count);
|
||||
return -1;
|
||||
@ -378,8 +354,7 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
|
||||
|
||||
if (!strcmp(key, "limit_min_hubs_reg"))
|
||||
{
|
||||
min = 0;
|
||||
if (!apply_integer(key, data, &config->limit_min_hubs_reg, &min, 0))
|
||||
if (!apply_integer(key, data, &config->limit_min_hubs_reg, 0, 0))
|
||||
{
|
||||
LOG_ERROR("Configuration parse error on line %d", line_count);
|
||||
return -1;
|
||||
@ -389,8 +364,7 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
|
||||
|
||||
if (!strcmp(key, "limit_min_hubs_op"))
|
||||
{
|
||||
min = 0;
|
||||
if (!apply_integer(key, data, &config->limit_min_hubs_op, &min, 0))
|
||||
if (!apply_integer(key, data, &config->limit_min_hubs_op, 0, 0))
|
||||
{
|
||||
LOG_ERROR("Configuration parse error on line %d", line_count);
|
||||
return -1;
|
||||
@ -411,8 +385,7 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
|
||||
|
||||
if (!strcmp(key, "limit_max_share"))
|
||||
{
|
||||
min = 0;
|
||||
if (!apply_integer(key, data, &config->limit_max_share, &min, 0))
|
||||
if (!apply_integer(key, data, &config->limit_max_share, 0, 0))
|
||||
{
|
||||
LOG_ERROR("Configuration parse error on line %d", line_count);
|
||||
return -1;
|
||||
@ -422,8 +395,7 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
|
||||
|
||||
if (!strcmp(key, "limit_min_slots"))
|
||||
{
|
||||
min = 0;
|
||||
if (!apply_integer(key, data, &config->limit_min_slots, &min, 0))
|
||||
if (!apply_integer(key, data, &config->limit_min_slots, 0, 0))
|
||||
{
|
||||
LOG_ERROR("Configuration parse error on line %d", line_count);
|
||||
return -1;
|
||||
@ -433,8 +405,7 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
|
||||
|
||||
if (!strcmp(key, "limit_max_slots"))
|
||||
{
|
||||
min = 0;
|
||||
if (!apply_integer(key, data, &config->limit_max_slots, &min, 0))
|
||||
if (!apply_integer(key, data, &config->limit_max_slots, 0, 0))
|
||||
{
|
||||
LOG_ERROR("Configuration parse error on line %d", line_count);
|
||||
return -1;
|
||||
@ -554,26 +525,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*) ""))
|
||||
@ -956,7 +907,7 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
|
||||
|
||||
/* Still here -- unknown directive */
|
||||
LOG_ERROR("Unknown configuration directive: '%s'", key);
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void free_config(struct hub_config* config)
|
||||
@ -977,10 +928,6 @@ void free_config(struct hub_config* config)
|
||||
|
||||
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);
|
||||
@ -1190,12 +1137,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,18 +1,12 @@
|
||||
/*
|
||||
* 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
|
||||
{
|
||||
int hub_enabled; /*<<< Is server enabled (default: 1) */
|
||||
int server_port; /*<<< Server port to bind to (default: 1511) */
|
||||
char* server_bind_addr; /*<<< Server bind address (default: "any") */
|
||||
char* server_bind_addr; /*<<< Server bind address (default: any) */
|
||||
int server_listen_backlog; /*<<< Server listen backlog (default: 50) */
|
||||
char* server_alt_ports; /*<<< Comma separated list of alternative ports to listen to (default: "") */
|
||||
char* server_alt_ports; /*<<< Comma separated list of alternative ports to listen to (default: ) */
|
||||
int show_banner; /*<<< Show banner on connect (default: 1) */
|
||||
int show_banner_sys_info; /*<<< Show banner on connect (default: 1) */
|
||||
int max_users; /*<<< Maximum number of users allowed on the hub (default: 500) */
|
||||
@ -20,9 +14,9 @@ struct hub_config
|
||||
int register_self; /*<<< Allow users to register themselves on the hub. (default: 0) */
|
||||
int obsolete_clients; /*<<< Support obsolete clients using a ADC protocol prior to 1.0 (default: 0) */
|
||||
int chat_is_privileged; /*<<< Allow chat for operators and above only (default: 0) */
|
||||
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: "") */
|
||||
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: ) */
|
||||
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) */
|
||||
@ -47,14 +41,12 @@ struct hub_config
|
||||
int flood_ctl_update; /*<<< Max updates allowed in time interval (default: 0) */
|
||||
int flood_ctl_extras; /*<<< Max extra messages allowed in time interval (default: 0) */
|
||||
int tls_enable; /*<<< Enable SSL/TLS support (default: 0) */
|
||||
int tls_require; /*<<< If SSL/TLS enabled, should it be required (default: 0) */
|
||||
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: "") */
|
||||
int tls_require; /*<<< If SSL/TLS enabled, should it be required (default: 0) (default: 0) */
|
||||
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* file_acl; /*<<< File containing access control lists (default: ) */
|
||||
char* file_plugins; /*<<< Plugin configuration file (default: ) */
|
||||
char* msg_hub_full; /*<<< "Hub is full" */
|
||||
char* msg_hub_disabled; /*<<< "Hub is disabled" */
|
||||
char* msg_hub_registered_users_only; /*<<< "Hub is for registered users only" */
|
||||
|
131
src/core/hub.c
131
src/core/hub.c
@ -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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -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) \
|
||||
{ \
|
||||
@ -76,10 +76,6 @@ int hub_handle_message(struct hub_info* hub, struct hub_user* u, const char* lin
|
||||
case ADC_CMD_DINF:
|
||||
case ADC_CMD_EINF:
|
||||
case ADC_CMD_FINF:
|
||||
case ADC_CMD_BQUI:
|
||||
case ADC_CMD_DQUI:
|
||||
case ADC_CMD_EQUI:
|
||||
case ADC_CMD_FQUI:
|
||||
/* these must never be allowed for security reasons, so we ignore them. */
|
||||
CHECK_FLOOD(extras, 1);
|
||||
break;
|
||||
@ -110,33 +106,25 @@ int hub_handle_message(struct hub_info* hub, struct hub_user* u, const char* lin
|
||||
|
||||
case ADC_CMD_DRES:
|
||||
cmd->priority = -1;
|
||||
if (plugin_handle_search_result(hub, u, uman_get_user_by_sid(hub->users, cmd->target), cmd->cache) == st_deny)
|
||||
if (plugin_handle_search_result(hub, u, uman_get_user_by_sid(hub, cmd->target), cmd->cache) == st_deny)
|
||||
break;
|
||||
/* CHECK_FLOOD(search, 0); */
|
||||
ROUTE_MSG;
|
||||
|
||||
case ADC_CMD_DRCM:
|
||||
cmd->priority = -1;
|
||||
if (plugin_handle_revconnect(hub, u, uman_get_user_by_sid(hub->users, cmd->target)) == st_deny)
|
||||
if (plugin_handle_revconnect(hub, u, uman_get_user_by_sid(hub, cmd->target)) == st_deny)
|
||||
break;
|
||||
CHECK_FLOOD(connect, 1);
|
||||
ROUTE_MSG;
|
||||
|
||||
case ADC_CMD_DCTM:
|
||||
cmd->priority = -1;
|
||||
if (plugin_handle_connect(hub, u, uman_get_user_by_sid(hub->users, cmd->target)) == st_deny)
|
||||
if (plugin_handle_connect(hub, u, uman_get_user_by_sid(hub, cmd->target)) == st_deny)
|
||||
break;
|
||||
CHECK_FLOOD(connect, 1);
|
||||
ROUTE_MSG;
|
||||
|
||||
case ADC_CMD_BCMD:
|
||||
case ADC_CMD_DCMD:
|
||||
case ADC_CMD_ECMD:
|
||||
case ADC_CMD_FCMD:
|
||||
case ADC_CMD_HCMD:
|
||||
CHECK_FLOOD(extras, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
CHECK_FLOOD(extras, 1);
|
||||
ROUTE_MSG;
|
||||
@ -340,7 +328,7 @@ int hub_handle_chat_message(struct hub_info* hub, struct hub_user* u, struct adc
|
||||
}
|
||||
else if (private_msg)
|
||||
{
|
||||
struct hub_user* target = uman_get_user_by_sid(hub->users, cmd->target);
|
||||
struct hub_user* target = uman_get_user_by_sid(hub, cmd->target);
|
||||
if (target)
|
||||
status = plugin_handle_private_message(hub, u, target, message_decoded, 0);
|
||||
else
|
||||
@ -381,7 +369,7 @@ void hub_send_sid(struct hub_info* hub, struct hub_user* u)
|
||||
if (user_is_connecting(u))
|
||||
{
|
||||
command = adc_msg_construct(ADC_CMD_ISID, 10);
|
||||
sid = uman_get_free_sid(hub->users, u);
|
||||
sid = uman_get_free_sid(hub, u);
|
||||
adc_msg_add_argument(command, (const char*) sid_to_string(sid));
|
||||
route_to_user(hub, u, command);
|
||||
adc_msg_free(command);
|
||||
@ -520,11 +508,11 @@ static int check_duplicate_logins_ok(struct hub_info* hub, struct hub_user* user
|
||||
struct hub_user* lookup1;
|
||||
struct hub_user* lookup2;
|
||||
|
||||
lookup1 = uman_get_user_by_nick(hub->users, user->id.nick);
|
||||
lookup1 = uman_get_user_by_nick(hub, user->id.nick);
|
||||
if (lookup1)
|
||||
return status_msg_inf_error_nick_taken;
|
||||
|
||||
lookup2 = uman_get_user_by_cid(hub->users, user->id.cid);
|
||||
lookup2 = uman_get_user_by_cid(hub, user->id.cid);
|
||||
if (lookup2)
|
||||
return status_msg_inf_error_cid_taken;
|
||||
|
||||
@ -536,7 +524,7 @@ static void hub_event_dispatcher(void* callback_data, struct event_data* message
|
||||
int status;
|
||||
struct hub_info* hub = (struct hub_info*) callback_data;
|
||||
struct hub_user* user = (struct hub_user*) message->ptr;
|
||||
uhub_assert(hub != NULL);
|
||||
assert(hub != NULL);
|
||||
|
||||
switch (message->id)
|
||||
{
|
||||
@ -568,8 +556,8 @@ static void hub_event_dispatcher(void* callback_data, struct event_data* message
|
||||
|
||||
case UHUB_EVENT_USER_QUIT:
|
||||
{
|
||||
uman_remove(hub->users, user);
|
||||
uman_send_quit_message(hub, hub->users, user);
|
||||
uman_remove(hub, user);
|
||||
uman_send_quit_message(hub, user);
|
||||
on_logout_user(hub, user);
|
||||
hub_schedule_destroy_user(hub, user);
|
||||
break;
|
||||
@ -586,7 +574,7 @@ static void hub_event_dispatcher(void* callback_data, struct event_data* message
|
||||
struct hub_user* u = (struct hub_user*) list_get_first(hub->users->list);
|
||||
while (u)
|
||||
{
|
||||
uman_remove(hub->users, u);
|
||||
uman_remove(hub, u);
|
||||
user_destroy(u);
|
||||
u = (struct hub_user*) list_get_first(hub->users->list);
|
||||
}
|
||||
@ -600,31 +588,6 @@ static void hub_event_dispatcher(void* callback_data, struct event_data* message
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void hub_update_stats(struct hub_info* hub)
|
||||
{
|
||||
const int factor = TIMEOUT_STATS;
|
||||
struct net_statistics* total;
|
||||
struct net_statistics* intermediate;
|
||||
net_stats_get(&intermediate, &total);
|
||||
|
||||
hub->stats.net_tx = (intermediate->tx / factor);
|
||||
hub->stats.net_rx = (intermediate->rx / factor);
|
||||
hub->stats.net_tx_peak = MAX(hub->stats.net_tx, hub->stats.net_tx_peak);
|
||||
hub->stats.net_rx_peak = MAX(hub->stats.net_rx, hub->stats.net_rx_peak);
|
||||
hub->stats.net_tx_total = total->tx;
|
||||
hub->stats.net_rx_total = total->rx;
|
||||
|
||||
net_stats_reset();
|
||||
}
|
||||
|
||||
static void hub_timer_statistics(struct timeout_evt* t)
|
||||
{
|
||||
struct hub_info* hub = (struct hub_info*) t->ptr;
|
||||
hub_update_stats(hub);
|
||||
timeout_queue_reschedule(net_backend_get_timeout_queue(), hub->stats.timeout, TIMEOUT_STATS);
|
||||
}
|
||||
|
||||
static struct net_connection* start_listening_socket(const char* bind_addr, uint16_t port, int backlog, struct hub_info* hub)
|
||||
{
|
||||
struct net_connection* server;
|
||||
@ -731,29 +694,41 @@ 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);
|
||||
hub->ssl_method = (SSL_METHOD*) SSLv23_method(); /* TLSv1_method() */
|
||||
hub->ssl_ctx = SSL_CTX_new(hub->ssl_method);
|
||||
|
||||
if (!hub->ctx)
|
||||
return 0;
|
||||
/* Disable SSLv2 */
|
||||
SSL_CTX_set_options(hub->ssl_ctx, SSL_OP_NO_SSLv2);
|
||||
SSL_CTX_set_quiet_shutdown(hub->ssl_ctx, 1);
|
||||
|
||||
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))
|
||||
if (SSL_CTX_use_certificate_file(hub->ssl_ctx, config->tls_certificate, SSL_FILETYPE_PEM) < 0)
|
||||
{
|
||||
LOG_INFO("Enabling TLS (%s), using certificate: %s, private key: %s", net_ssl_get_provider(), config->tls_certificate, config->tls_private_key);
|
||||
return 1;
|
||||
LOG_ERROR("SSL_CTX_use_certificate_file: %s", ERR_error_string(ERR_get_error(), NULL));
|
||||
}
|
||||
return 0;
|
||||
|
||||
if (SSL_CTX_use_PrivateKey_file(hub->ssl_ctx, config->tls_private_key, SSL_FILETYPE_PEM) < 0)
|
||||
{
|
||||
LOG_ERROR("SSL_CTX_use_PrivateKey_file: %s", ERR_error_string(ERR_get_error(), NULL));
|
||||
}
|
||||
|
||||
if (SSL_CTX_check_private_key(hub->ssl_ctx) != 1)
|
||||
{
|
||||
LOG_FATAL("SSL_CTX_check_private_key: Private key does not match the certificate public key: %s", ERR_error_string(ERR_get_error(), NULL));
|
||||
return 0;
|
||||
}
|
||||
LOG_INFO("Enabling TLS, using certificate: %s, private key: %s", config->tls_certificate, config->tls_private_key);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void unload_ssl_certificates(struct hub_info* hub)
|
||||
{
|
||||
if (hub->ctx)
|
||||
net_ssl_context_destroy(hub->ctx);
|
||||
if (hub->ssl_ctx)
|
||||
{
|
||||
SSL_CTX_free(hub->ssl_ctx);
|
||||
}
|
||||
}
|
||||
#endif /* SSL_SUPPORT */
|
||||
#endif
|
||||
|
||||
struct hub_info* hub_start_service(struct hub_config* config)
|
||||
{
|
||||
@ -794,8 +769,7 @@ struct hub_info* hub_start_service(struct hub_config* config)
|
||||
hub->config = config;
|
||||
hub->users = NULL;
|
||||
|
||||
hub->users = uman_init();
|
||||
if (!hub->users)
|
||||
if (uman_init(hub) == -1)
|
||||
{
|
||||
net_con_close(hub->server);
|
||||
hub_free(hub);
|
||||
@ -805,7 +779,7 @@ struct hub_info* hub_start_service(struct hub_config* config)
|
||||
if (event_queue_initialize(&hub->queue, hub_event_dispatcher, (void*) hub) == -1)
|
||||
{
|
||||
net_con_close(hub->server);
|
||||
uman_shutdown(hub->users);
|
||||
uman_shutdown(hub);
|
||||
hub_free(hub);
|
||||
return 0;
|
||||
}
|
||||
@ -817,7 +791,7 @@ struct hub_info* hub_start_service(struct hub_config* config)
|
||||
net_con_close(hub->server);
|
||||
hub_free(hub->recvbuf);
|
||||
hub_free(hub->sendbuf);
|
||||
uman_shutdown(hub->users);
|
||||
uman_shutdown(hub);
|
||||
hub_free(hub);
|
||||
return 0;
|
||||
}
|
||||
@ -829,13 +803,6 @@ struct hub_info* hub_start_service(struct hub_config* config)
|
||||
|
||||
g_hub = hub;
|
||||
|
||||
if (net_backend_get_timeout_queue())
|
||||
{
|
||||
hub->stats.timeout = hub_malloc_zero(sizeof(struct timeout_evt));
|
||||
timeout_evt_initialize(hub->stats.timeout, hub_timer_statistics, hub);
|
||||
timeout_queue_insert(net_backend_get_timeout_queue(), hub->stats.timeout, TIMEOUT_STATS);
|
||||
}
|
||||
|
||||
// Start the hub command sub-system
|
||||
hub->commands = command_initialize(hub);
|
||||
return hub;
|
||||
@ -846,12 +813,6 @@ void hub_shutdown_service(struct hub_info* hub)
|
||||
{
|
||||
LOG_DEBUG("hub_shutdown_service()");
|
||||
|
||||
if (net_backend_get_timeout_queue())
|
||||
{
|
||||
timeout_queue_remove(net_backend_get_timeout_queue(), hub->stats.timeout);
|
||||
hub_free(hub->stats.timeout);
|
||||
}
|
||||
|
||||
#ifdef SSL_SUPPORT
|
||||
unload_ssl_certificates(hub);
|
||||
#endif
|
||||
@ -859,7 +820,7 @@ void hub_shutdown_service(struct hub_info* hub)
|
||||
event_queue_shutdown(hub->queue);
|
||||
net_con_close(hub->server);
|
||||
server_alt_port_stop(hub);
|
||||
uman_shutdown(hub->users);
|
||||
uman_shutdown(hub);
|
||||
hub->status = hub_status_stopped;
|
||||
hub_free(hub->sendbuf);
|
||||
hub_free(hub->recvbuf);
|
||||
@ -909,8 +870,7 @@ void hub_set_variables(struct hub_info* hub, struct acl_handle* acl)
|
||||
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);
|
||||
adc_msg_add_named_argument(hub->command_info, ADC_INF_FLAG_USER_AGENT, server);
|
||||
|
||||
tmp = adc_msg_escape(hub->config->hub_name);
|
||||
adc_msg_add_named_argument(hub->command_info, ADC_INF_FLAG_NICK, tmp);
|
||||
@ -941,7 +901,6 @@ void hub_set_variables(struct hub_info* hub, struct acl_handle* acl)
|
||||
|
||||
if (hub_plugins_load(hub) < 0)
|
||||
{
|
||||
LOG_FATAL("Unable to load plugins.");
|
||||
hub->status = hub_status_shutdown;
|
||||
}
|
||||
else
|
||||
@ -1325,7 +1284,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-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,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,12 +50,12 @@ 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 */
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
@ -81,7 +81,6 @@ struct hub_stats
|
||||
size_t net_rx_peak;
|
||||
size_t net_tx_total;
|
||||
size_t net_rx_total;
|
||||
struct timeout_evt* timeout; /**<< "Timeout handler for statistics" */
|
||||
};
|
||||
|
||||
struct hub_logout_info
|
||||
@ -116,7 +115,8 @@ struct hub_info
|
||||
struct uhub_plugins* plugins; /* Plug-ins loaded for this hub instance. */
|
||||
|
||||
#ifdef SSL_SUPPORT
|
||||
struct ssl_context_handle* ctx;
|
||||
SSL_METHOD* ssl_method;
|
||||
SSL_CTX* ssl_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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -24,12 +24,12 @@
|
||||
void on_login_success(struct hub_info* hub, struct hub_user* u)
|
||||
{
|
||||
/* Send user list of all existing users */
|
||||
if (!uman_send_user_list(hub, hub->users, u))
|
||||
if (!uman_send_user_list(hub, u))
|
||||
return;
|
||||
|
||||
/* Mark as being in the normal state, and add user to the user list */
|
||||
user_set_state(u, state_normal);
|
||||
uman_add(hub->users, u);
|
||||
uman_add(hub, u);
|
||||
|
||||
/* Announce new user to all connected users */
|
||||
if (user_is_logged_in(u))
|
||||
|
@ -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,11 +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 "hubio.h"
|
||||
|
||||
#ifdef DEBUG_SENDQ
|
||||
static void debug_msg(const char* prefix, struct adc_message* msg)
|
||||
@ -34,13 +35,13 @@ static void debug_msg(const char* prefix, struct adc_message* msg)
|
||||
}
|
||||
#endif
|
||||
|
||||
struct ioq_recv* ioq_recv_create()
|
||||
struct hub_recvq* hub_recvq_create()
|
||||
{
|
||||
struct ioq_recv* q = hub_malloc_zero(sizeof(struct ioq_recv));
|
||||
struct hub_recvq* q = hub_malloc_zero(sizeof(struct hub_recvq));
|
||||
return q;
|
||||
}
|
||||
|
||||
void ioq_recv_destroy(struct ioq_recv* q)
|
||||
void hub_recvq_destroy(struct hub_recvq* q)
|
||||
{
|
||||
if (q)
|
||||
{
|
||||
@ -49,9 +50,9 @@ void ioq_recv_destroy(struct ioq_recv* q)
|
||||
}
|
||||
}
|
||||
|
||||
size_t ioq_recv_get(struct ioq_recv* q, void* buf, size_t bufsize)
|
||||
size_t hub_recvq_get(struct hub_recvq* q, void* buf, size_t bufsize)
|
||||
{
|
||||
uhub_assert(bufsize >= q->size);
|
||||
assert(bufsize >= q->size);
|
||||
if (q->size)
|
||||
{
|
||||
size_t n = q->size;
|
||||
@ -64,7 +65,7 @@ size_t ioq_recv_get(struct ioq_recv* q, void* buf, size_t bufsize)
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t ioq_recv_set(struct ioq_recv* q, void* buf, size_t bufsize)
|
||||
size_t hub_recvq_set(struct hub_recvq* q, void* buf, size_t bufsize)
|
||||
{
|
||||
if (q->buf)
|
||||
{
|
||||
@ -72,7 +73,7 @@ size_t ioq_recv_set(struct ioq_recv* q, void* buf, size_t bufsize)
|
||||
q->buf = 0;
|
||||
q->size = 0;
|
||||
}
|
||||
|
||||
|
||||
if (!bufsize)
|
||||
{
|
||||
return 0;
|
||||
@ -88,9 +89,9 @@ size_t ioq_recv_set(struct ioq_recv* q, void* buf, size_t bufsize)
|
||||
}
|
||||
|
||||
|
||||
struct ioq_send* ioq_send_create()
|
||||
struct hub_sendq* hub_sendq_create()
|
||||
{
|
||||
struct ioq_send* q = hub_malloc_zero(sizeof(struct ioq_send));
|
||||
struct hub_sendq* q = hub_malloc_zero(sizeof(struct hub_sendq));
|
||||
if (!q)
|
||||
return 0;
|
||||
|
||||
@ -109,7 +110,7 @@ static void clear_send_queue_callback(void* ptr)
|
||||
adc_msg_free((struct adc_message*) ptr);
|
||||
}
|
||||
|
||||
void ioq_send_destroy(struct ioq_send* q)
|
||||
void hub_sendq_destroy(struct hub_sendq* q)
|
||||
{
|
||||
if (q)
|
||||
{
|
||||
@ -119,21 +120,21 @@ void ioq_send_destroy(struct ioq_send* q)
|
||||
}
|
||||
}
|
||||
|
||||
void ioq_send_add(struct ioq_send* q, struct adc_message* msg_)
|
||||
void hub_sendq_add(struct hub_sendq* q, struct adc_message* msg_)
|
||||
{
|
||||
struct adc_message* msg = adc_msg_incref(msg_);
|
||||
#ifdef DEBUG_SENDQ
|
||||
debug_msg("ioq_send_add", msg);
|
||||
debug_msg("hub_sendq_add", msg);
|
||||
#endif
|
||||
uhub_assert(msg->cache && *msg->cache);
|
||||
assert(msg->cache && *msg->cache);
|
||||
list_append(q->queue, msg);
|
||||
q->size += msg->length;
|
||||
}
|
||||
|
||||
static void ioq_send_remove(struct ioq_send* q, struct adc_message* msg)
|
||||
void hub_sendq_remove(struct hub_sendq* q, struct adc_message* msg)
|
||||
{
|
||||
#ifdef DEBUG_SENDQ
|
||||
debug_msg("ioq_send_remove", msg);
|
||||
debug_msg("hub_sendq_remove", msg);
|
||||
#endif
|
||||
list_remove(q->queue, msg);
|
||||
q->size -= msg->length;
|
||||
@ -141,13 +142,13 @@ static void ioq_send_remove(struct ioq_send* q, struct adc_message* msg)
|
||||
q->offset = 0;
|
||||
}
|
||||
|
||||
int ioq_send_send(struct ioq_send* q, struct net_connection* con)
|
||||
int hub_sendq_send(struct hub_sendq* q, struct hub_user* user)
|
||||
{
|
||||
int ret;
|
||||
struct adc_message* msg = list_get_first(q->queue);
|
||||
if (!msg) return 0;
|
||||
uhub_assert(msg->cache && *msg->cache);
|
||||
ret = net_con_send(con, msg->cache + q->offset, msg->length - q->offset);
|
||||
assert(msg->cache && *msg->cache);
|
||||
ret = net_con_send(user->connection, msg->cache + q->offset, msg->length - q->offset);
|
||||
|
||||
if (ret > 0)
|
||||
{
|
||||
@ -155,18 +156,18 @@ int ioq_send_send(struct ioq_send* q, struct net_connection* con)
|
||||
if (msg->length - q->offset > 0)
|
||||
return 0;
|
||||
|
||||
ioq_send_remove(q, msg);
|
||||
hub_sendq_remove(q, msg);
|
||||
return 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ioq_send_is_empty(struct ioq_send* q)
|
||||
int hub_sendq_is_empty(struct hub_sendq* q)
|
||||
{
|
||||
return (q->size - q->offset) == 0;
|
||||
}
|
||||
|
||||
size_t ioq_send_get_bytes(struct ioq_send* q)
|
||||
size_t hub_sendq_get_bytes(struct hub_sendq* q)
|
||||
{
|
||||
return q->size - q->offset;
|
||||
}
|
@ -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,29 +13,29 @@
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HAVE_UHUB_IO_QUEUE_H
|
||||
#define HAVE_UHUB_IO_QUEUE_H
|
||||
#ifndef HAVE_UHUB_HUB_IO_H
|
||||
#define HAVE_UHUB_HUB_IO_H
|
||||
|
||||
struct adc_message;
|
||||
struct linked_list;
|
||||
typedef int (*ioq_write)(void* desc, const void* buf, size_t len);
|
||||
typedef int (*ioq_read)(void* desc, void* buf, size_t len);
|
||||
typedef int (*hub_recvq_write)(void* desc, const void* buf, size_t len);
|
||||
typedef int (*hub_recvq_read)(void* desc, void* buf, size_t len);
|
||||
|
||||
struct ioq_send
|
||||
struct hub_sendq
|
||||
{
|
||||
size_t size; /** Size of send queue (in bytes, not messages) */
|
||||
size_t offset; /** Queue byte offset in the first message. Should be 0 unless a partial write. */
|
||||
#ifdef SSL_SUPPORT
|
||||
size_t last_send; /** When using SSL, one have to send the exact same buffer and length if a write cannot complete. */
|
||||
#endif
|
||||
struct linked_list* queue; /** List of queued messages (struct adc_message) */
|
||||
struct linked_list* queue; /** List of queued messages */
|
||||
};
|
||||
|
||||
struct ioq_recv
|
||||
struct hub_recvq
|
||||
{
|
||||
char* buf;
|
||||
size_t size;
|
||||
@ -44,63 +44,63 @@ struct ioq_recv
|
||||
/**
|
||||
* Create a send queue
|
||||
*/
|
||||
extern struct ioq_send* ioq_send_create();
|
||||
extern struct hub_sendq* hub_sendq_create();
|
||||
|
||||
/**
|
||||
* Destroy a send queue, and delete any queued messages.
|
||||
*/
|
||||
extern void ioq_send_destroy(struct ioq_send*);
|
||||
extern void hub_sendq_destroy(struct hub_sendq*);
|
||||
|
||||
/**
|
||||
* Add a message to the send queue.
|
||||
*/
|
||||
extern void ioq_send_add(struct ioq_send*, struct adc_message* msg);
|
||||
extern void hub_sendq_add(struct hub_sendq*, struct adc_message* msg);
|
||||
|
||||
/**
|
||||
* Process the send queue, and send as many messages as possible.
|
||||
* @returns -1 on error, 0 if unable to send more, 1 if more can be sent.
|
||||
*/
|
||||
extern int ioq_send_send(struct ioq_send*, struct net_connection* con);
|
||||
extern int hub_sendq_send(struct hub_sendq*, struct hub_user*);
|
||||
|
||||
/**
|
||||
* @returns 1 if send queue is empty, 0 otherwise.
|
||||
*/
|
||||
extern int ioq_send_is_empty(struct ioq_send*);
|
||||
extern int hub_sendq_is_empty(struct hub_sendq*);
|
||||
|
||||
/**
|
||||
* @returns the number of bytes remaining to be sent in the queue.
|
||||
*/
|
||||
extern size_t ioq_send_get_bytes(struct ioq_send*);
|
||||
extern size_t hub_sendq_get_bytes(struct hub_sendq*);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create a receive queue.
|
||||
*/
|
||||
extern struct ioq_recv* ioq_recv_create();
|
||||
extern struct hub_recvq* hub_recvq_create();
|
||||
|
||||
/**
|
||||
* Destroy a receive queue.
|
||||
*/
|
||||
extern void ioq_recv_destroy(struct ioq_recv*);
|
||||
extern void hub_recvq_destroy(struct hub_recvq*);
|
||||
|
||||
/**
|
||||
* Gets the buffer, copies it into buf and deallocates it.
|
||||
* NOTE: bufsize *MUST* be larger than the buffer, otherwise it asserts.
|
||||
* @return the number of bytes copied into buf.
|
||||
*/
|
||||
extern size_t ioq_recv_get(struct ioq_recv*, void* buf, size_t bufsize);
|
||||
extern size_t hub_recvq_get(struct hub_recvq*, void* buf, size_t bufsize);
|
||||
|
||||
/**
|
||||
* Sets the buffer
|
||||
*/
|
||||
extern size_t ioq_recv_set(struct ioq_recv*, void* buf, size_t bufsize);
|
||||
extern size_t hub_recvq_set(struct hub_recvq*, void* buf, size_t bufsize);
|
||||
|
||||
/**
|
||||
* @return 1 if size is zero, 0 otherwise.
|
||||
*/
|
||||
extern int ioq_recv_is_empty(struct ioq_recv* buf);
|
||||
extern int hub_recvq_is_empty(struct hub_recvq* buf);
|
||||
|
||||
|
||||
|
||||
#endif /* HAVE_UHUB_IO_QUEUE_H */
|
||||
#endif /* HAVE_UHUB_HUB_IO_H */
|
151
src/core/inf.c
151
src/core/inf.c
@ -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)
|
||||
{
|
||||
@ -109,14 +109,14 @@ static int check_cid(struct hub_info* hub, struct hub_user* user, struct adc_mes
|
||||
hub_free(pid);
|
||||
return status_msg_inf_error_cid_invalid;
|
||||
}
|
||||
|
||||
|
||||
if (strlen(pid) != MAX_CID_LEN)
|
||||
{
|
||||
hub_free(cid);
|
||||
hub_free(pid);
|
||||
return status_msg_inf_error_pid_invalid;
|
||||
}
|
||||
|
||||
|
||||
for (pos = 0; pos < MAX_CID_LEN; pos++)
|
||||
{
|
||||
if (!is_valid_base32_char(cid[pos]))
|
||||
@ -133,18 +133,18 @@ static int check_cid(struct hub_info* hub, struct hub_user* user, struct adc_mes
|
||||
return status_msg_inf_error_pid_invalid;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!check_hash_tiger(cid, pid))
|
||||
{
|
||||
hub_free(cid);
|
||||
hub_free(pid);
|
||||
return status_msg_inf_error_cid_invalid;
|
||||
}
|
||||
|
||||
|
||||
/* Set the cid in the user object */
|
||||
memcpy(user->id.cid, cid, MAX_CID_LEN);
|
||||
user->id.cid[MAX_CID_LEN] = 0;
|
||||
|
||||
|
||||
hub_free(cid);
|
||||
hub_free(pid);
|
||||
return 0;
|
||||
@ -154,7 +154,7 @@ static int check_cid(struct hub_info* hub, struct hub_user* user, struct adc_mes
|
||||
static int check_required_login_flags(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
|
||||
{
|
||||
int num = 0;
|
||||
|
||||
|
||||
num = adc_msg_has_named_argument(cmd, ADC_INF_FLAG_CLIENT_ID);
|
||||
if (num != 1)
|
||||
{
|
||||
@ -162,7 +162,7 @@ static int check_required_login_flags(struct hub_info* hub, struct hub_user* use
|
||||
return status_msg_inf_error_cid_missing;
|
||||
return status_msg_inf_error_cid_invalid;
|
||||
}
|
||||
|
||||
|
||||
num = adc_msg_has_named_argument(cmd, ADC_INF_FLAG_PRIVATE_ID);
|
||||
if (num != 1)
|
||||
{
|
||||
@ -190,7 +190,7 @@ static int check_required_login_flags(struct hub_info* hub, struct hub_user* use
|
||||
static int check_network(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
|
||||
{
|
||||
const char* address = user_get_address(user);
|
||||
|
||||
|
||||
/* Check for NAT override address */
|
||||
if (acl_is_ip_nat_override(hub->acl, address))
|
||||
{
|
||||
@ -226,7 +226,9 @@ static int check_network(struct hub_info* hub, struct hub_user* user, struct adc
|
||||
static void strip_network(struct hub_user* user, struct adc_message* cmd)
|
||||
{
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV6_ADDR);
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV6_UDP_PORT);
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR);
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV4_UDP_PORT);
|
||||
}
|
||||
|
||||
static int nick_length_ok(const char* nick)
|
||||
@ -236,12 +238,12 @@ static int nick_length_ok(const char* nick)
|
||||
{
|
||||
return nick_invalid_short;
|
||||
}
|
||||
|
||||
|
||||
if (length > MAX_NICK_LEN)
|
||||
{
|
||||
return nick_invalid_long;
|
||||
}
|
||||
|
||||
|
||||
return nick_ok;
|
||||
}
|
||||
|
||||
@ -249,16 +251,16 @@ static int nick_length_ok(const char* nick)
|
||||
static int nick_bad_characters(const char* nick)
|
||||
{
|
||||
const char* tmp;
|
||||
|
||||
|
||||
/* Nick must not start with a space */
|
||||
if (nick[0] == ' ')
|
||||
return nick_invalid_spaces;
|
||||
|
||||
|
||||
/* Check for ASCII values below 32 */
|
||||
for (tmp = nick; *tmp; tmp++)
|
||||
if ((*tmp < 32) && (*tmp > 0))
|
||||
return nick_invalid_bad_ascii;
|
||||
|
||||
|
||||
return nick_ok;
|
||||
}
|
||||
|
||||
@ -286,7 +288,7 @@ static int check_nick(struct hub_info* hub, struct hub_user* user, struct adc_me
|
||||
nick = adc_msg_unescape(tmp);
|
||||
free(tmp); tmp = 0;
|
||||
if (!nick) return 0;
|
||||
|
||||
|
||||
status = nick_length_ok(nick);
|
||||
if (status != nick_ok)
|
||||
{
|
||||
@ -295,7 +297,7 @@ static int check_nick(struct hub_info* hub, struct hub_user* user, struct adc_me
|
||||
return status_msg_inf_error_nick_short;
|
||||
return status_msg_inf_error_nick_long;
|
||||
}
|
||||
|
||||
|
||||
status = nick_bad_characters(nick);
|
||||
if (status != nick_ok)
|
||||
{
|
||||
@ -304,20 +306,20 @@ static int check_nick(struct hub_info* hub, struct hub_user* user, struct adc_me
|
||||
return status_msg_inf_error_nick_spaces;
|
||||
return status_msg_inf_error_nick_bad_chars;
|
||||
}
|
||||
|
||||
|
||||
status = nick_is_utf8(nick);
|
||||
if (status != nick_ok)
|
||||
{
|
||||
hub_free(nick);
|
||||
return status_msg_inf_error_nick_not_utf8;
|
||||
}
|
||||
|
||||
|
||||
if (user_is_connecting(user))
|
||||
{
|
||||
memcpy(user->id.nick, nick, strlen(nick));
|
||||
user->id.nick[strlen(nick)] = 0;
|
||||
}
|
||||
|
||||
|
||||
hub_free(nick);
|
||||
return 0;
|
||||
}
|
||||
@ -325,31 +327,21 @@ static int check_nick(struct hub_info* hub, struct hub_user* user, struct adc_me
|
||||
|
||||
static int check_logged_in(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
|
||||
{
|
||||
struct hub_user* lookup1 = uman_get_user_by_nick(hub->users, user->id.nick);
|
||||
struct hub_user* lookup2 = uman_get_user_by_cid(hub->users, user->id.cid);
|
||||
|
||||
struct hub_user* lookup1 = uman_get_user_by_nick(hub, user->id.nick);
|
||||
struct hub_user* lookup2 = uman_get_user_by_cid(hub, user->id.cid);
|
||||
|
||||
if (lookup1 == user)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if (lookup1 || lookup2)
|
||||
{
|
||||
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.
|
||||
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;
|
||||
}
|
||||
LOG_DEBUG("check_logged_in: exact same user is logged in: %s", user->id.nick);
|
||||
hub_disconnect_user(hub, lookup1, quit_ghost_timeout);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -376,37 +368,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;
|
||||
}
|
||||
|
||||
@ -417,7 +393,7 @@ static int check_acl(struct hub_info* hub, struct hub_user* user, struct adc_mes
|
||||
{
|
||||
return status_msg_ban_permanently;
|
||||
}
|
||||
|
||||
|
||||
if (acl_is_user_banned(hub->acl, user->id.nick))
|
||||
{
|
||||
return status_msg_ban_permanently;
|
||||
@ -427,7 +403,7 @@ static int check_acl(struct hub_info* hub, struct hub_user* user, struct adc_mes
|
||||
{
|
||||
return status_msg_inf_error_nick_restricted;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -496,7 +472,7 @@ static int check_limits(struct hub_info* hub, struct hub_user* user, struct adc_
|
||||
hub_free(arg);
|
||||
arg = 0;
|
||||
}
|
||||
|
||||
|
||||
arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_UPLOAD_SLOTS);
|
||||
if (arg)
|
||||
{
|
||||
@ -560,7 +536,7 @@ static int set_credentials(struct hub_info* hub, struct hub_user* user, struct a
|
||||
{
|
||||
int ret = 0;
|
||||
struct auth_info* info = acl_get_access_info(hub, user->id.nick);
|
||||
|
||||
|
||||
if (info)
|
||||
{
|
||||
user->credentials = info->credentials;
|
||||
@ -576,15 +552,11 @@ static int set_credentials(struct hub_info* hub, struct hub_user* user, struct a
|
||||
{
|
||||
case auth_cred_none:
|
||||
break;
|
||||
|
||||
|
||||
case auth_cred_bot:
|
||||
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;
|
||||
@ -596,15 +568,7 @@ static int set_credentials(struct hub_info* hub, struct hub_user* user, struct a
|
||||
case auth_cred_operator:
|
||||
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;
|
||||
@ -616,7 +580,7 @@ static int set_credentials(struct hub_info* hub, struct hub_user* user, struct a
|
||||
case auth_cred_link:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -649,10 +613,10 @@ static int hub_handle_info_common(struct hub_user* user, struct adc_message* cmd
|
||||
{
|
||||
/* Remove server restricted flags */
|
||||
remove_server_restricted_flags(cmd);
|
||||
|
||||
|
||||
/* Update/set the feature cast flags. */
|
||||
set_feature_cast_supports(user, cmd);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -660,8 +624,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);
|
||||
@ -674,7 +637,7 @@ static int hub_handle_info_low_bandwidth(struct hub_info* hub, struct hub_user*
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_DESCRIPTION);
|
||||
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_EMAIL);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -719,20 +682,20 @@ int hub_handle_info_login(struct hub_info* hub, struct hub_user* user, struct ad
|
||||
{
|
||||
return status_msg_hub_full;
|
||||
}
|
||||
|
||||
|
||||
if (check_registered_users_only(hub, user))
|
||||
{
|
||||
return status_msg_hub_registered_users_only;
|
||||
}
|
||||
|
||||
|
||||
INF_CHECK(check_limits, hub, user, cmd);
|
||||
|
||||
|
||||
/* strip off stuff if low_bandwidth_mode is enabled */
|
||||
hub_handle_info_low_bandwidth(hub, user, cmd);
|
||||
|
||||
|
||||
/* Set initial user info */
|
||||
user_set_info(user, cmd);
|
||||
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -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,16 +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"
|
||||
|
||||
#ifdef SYSTEMD
|
||||
#include <systemd/sd-daemon.h>
|
||||
#endif
|
||||
|
||||
static int arg_verbose = 5;
|
||||
static int arg_fork = 0;
|
||||
static int arg_check_config = 0;
|
||||
@ -87,7 +83,7 @@ void setup_signal_handlers(struct hub_info* hub)
|
||||
act.sa_mask = sig_set;
|
||||
act.sa_flags = SA_ONSTACK | SA_RESTART;
|
||||
act.sa_handler = hub_handle_signal;
|
||||
|
||||
|
||||
for (i = 0; signals[i]; i++)
|
||||
{
|
||||
if (sigaction(signals[i], &act, 0) != 0)
|
||||
@ -124,7 +120,7 @@ int main_loop()
|
||||
hub_log_initialize(arg_log, arg_log_syslog);
|
||||
hub_set_log_verbosity(arg_verbose);
|
||||
}
|
||||
|
||||
|
||||
if (read_config(arg_config, &configuration, !arg_have_config) == -1)
|
||||
return -1;
|
||||
|
||||
@ -140,25 +136,10 @@ int main_loop()
|
||||
{
|
||||
hub = hub_start_service(&configuration);
|
||||
if (!hub)
|
||||
{
|
||||
acl_shutdown(&acl);
|
||||
free_config(&configuration);
|
||||
net_destroy();
|
||||
hub_log_shutdown();
|
||||
return -1;
|
||||
}
|
||||
#if !defined(WIN32)
|
||||
setup_signal_handlers(hub);
|
||||
#ifdef SYSTEMD
|
||||
/* Notify the service manager that this daemon has
|
||||
* been successfully initialized and shall enter the
|
||||
* main loop.
|
||||
*/
|
||||
sd_notifyf(0, "READY=1\n"
|
||||
"MAINPID=%lu", (unsigned long) getpid());
|
||||
#endif /* SYSTEMD */
|
||||
|
||||
#endif /* ! WIN32 */
|
||||
#endif
|
||||
}
|
||||
|
||||
hub_set_variables(hub, &acl);
|
||||
@ -174,7 +155,7 @@ int main_loop()
|
||||
#if !defined(WIN32)
|
||||
shutdown_signal_handlers(hub);
|
||||
#endif
|
||||
|
||||
|
||||
if (hub)
|
||||
{
|
||||
hub_shutdown_service(hub);
|
||||
@ -229,17 +210,13 @@ void print_usage(char* program)
|
||||
" -q Quiet mode - no output\n"
|
||||
" -f Fork to background\n"
|
||||
" -l <file> Log messages to given file (default: stderr)\n"
|
||||
" -L Log messages to syslog\n"
|
||||
" -c <file> Specify configuration file (default: " SERVER_CONFIG ")\n"
|
||||
" -C Check configuration and return\n"
|
||||
" -s Show configuration parameters\n"
|
||||
" -S Show configuration parameters, but ignore defaults\n"
|
||||
" -h This message\n"
|
||||
#ifndef WIN32
|
||||
#ifdef SYSTEMD
|
||||
" -L Log messages to journal\n"
|
||||
#else
|
||||
" -L Log messages to syslog\n"
|
||||
#endif
|
||||
" -u <user> Run as given user\n"
|
||||
" -g <group> Run with given group permissions\n"
|
||||
" -p <file> Store pid in file (process id)\n"
|
||||
@ -288,7 +265,7 @@ void parse_command_line(int argc, char** argv)
|
||||
arg_dump_config = 1;
|
||||
arg_check_config = 1;
|
||||
break;
|
||||
|
||||
|
||||
case 'S':
|
||||
arg_dump_config = 2;
|
||||
arg_check_config = 1;
|
||||
@ -297,7 +274,7 @@ void parse_command_line(int argc, char** argv)
|
||||
case 'l':
|
||||
arg_log = optarg;
|
||||
break;
|
||||
|
||||
|
||||
case 'L':
|
||||
arg_log_syslog = 1;
|
||||
break;
|
||||
@ -471,7 +448,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,19 +13,22 @@
|
||||
* 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 "ioqueue.h"
|
||||
#include "hubio.h"
|
||||
#include "probe.h"
|
||||
|
||||
/* FIXME: This should not be needed! */
|
||||
extern struct hub_info* g_hub;
|
||||
|
||||
int handle_net_read(struct hub_user* user)
|
||||
{
|
||||
static char buf[MAX_RECV_BUF];
|
||||
struct ioq_recv* q = user->recv_queue;
|
||||
size_t buf_size = ioq_recv_get(q, buf, MAX_RECV_BUF);
|
||||
struct hub_recvq* q = user->recv_queue;
|
||||
size_t buf_size = hub_recvq_get(q, buf, MAX_RECV_BUF);
|
||||
ssize_t size;
|
||||
|
||||
if (user_flag_get(user, flag_maxbuf))
|
||||
@ -55,7 +58,7 @@ int handle_net_read(struct hub_user* user)
|
||||
|
||||
while ((pos = memchr(start, '\n', remaining)))
|
||||
{
|
||||
lastPos = pos+1;
|
||||
lastPos = pos;
|
||||
pos[0] = '\0';
|
||||
|
||||
#ifdef DEBUG_SENDQ
|
||||
@ -68,9 +71,9 @@ int handle_net_read(struct hub_user* user)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (((pos - start) > 0) && user->hub->config->max_recv_buffer > (pos - start))
|
||||
if (((pos - start) > 0) && g_hub->config->max_recv_buffer > (pos - start))
|
||||
{
|
||||
if (hub_handle_message(user->hub, user, start, (pos - start)) == -1)
|
||||
if (hub_handle_message(g_hub, user, start, (pos - start)) == -1)
|
||||
{
|
||||
return quit_protocol_error;
|
||||
}
|
||||
@ -85,20 +88,20 @@ int handle_net_read(struct hub_user* user)
|
||||
|
||||
if (lastPos || remaining)
|
||||
{
|
||||
if (remaining < (size_t) user->hub->config->max_recv_buffer)
|
||||
if (remaining < (size_t) g_hub->config->max_recv_buffer)
|
||||
{
|
||||
ioq_recv_set(q, lastPos ? lastPos : buf, remaining);
|
||||
hub_recvq_set(q, lastPos ? lastPos : buf, remaining);
|
||||
}
|
||||
else
|
||||
{
|
||||
ioq_recv_set(q, 0, 0);
|
||||
hub_recvq_set(q, 0, 0);
|
||||
user_flag_set(user, flag_maxbuf);
|
||||
LOG_WARN("Received message past max_recv_buffer, dropping message.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ioq_recv_set(q, 0, 0);
|
||||
hub_recvq_set(q, 0, 0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@ -107,9 +110,9 @@ int handle_net_read(struct hub_user* user)
|
||||
int handle_net_write(struct hub_user* user)
|
||||
{
|
||||
int ret = 0;
|
||||
while (ioq_send_get_bytes(user->send_queue))
|
||||
while (hub_sendq_get_bytes(user->send_queue))
|
||||
{
|
||||
ret = ioq_send_send(user->send_queue, user->connection);
|
||||
ret = hub_sendq_send(user->send_queue, user);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
}
|
||||
@ -117,7 +120,7 @@ int handle_net_write(struct hub_user* user)
|
||||
if (ret < 0)
|
||||
return quit_socket_error;
|
||||
|
||||
if (ioq_send_get_bytes(user->send_queue))
|
||||
if (hub_sendq_get_bytes(user->send_queue))
|
||||
{
|
||||
user_net_io_want_write(user);
|
||||
}
|
||||
@ -137,17 +140,11 @@ 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))
|
||||
{
|
||||
hub_disconnect_user(user->hub, user, quit_timeout);
|
||||
hub_disconnect_user(g_hub, user, quit_timeout);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -157,7 +154,7 @@ void net_event(struct net_connection* con, int event, void *arg)
|
||||
flag_close = handle_net_read(user);
|
||||
if (flag_close)
|
||||
{
|
||||
hub_disconnect_user(user->hub, user, flag_close);
|
||||
hub_disconnect_user(g_hub, user, flag_close);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -167,7 +164,7 @@ void net_event(struct net_connection* con, int event, void *arg)
|
||||
flag_close = handle_net_write(user);
|
||||
if (flag_close)
|
||||
{
|
||||
hub_disconnect_user(user->hub, user, flag_close);
|
||||
hub_disconnect_user(g_hub, user, flag_close);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -27,7 +27,10 @@ struct plugin_callback_data
|
||||
|
||||
static struct plugin_callback_data* get_callback_data(struct plugin_handle* plugin)
|
||||
{
|
||||
return get_internals(plugin)->callback_data;
|
||||
struct plugin_callback_data* data;
|
||||
uhub_assert(plugin && plugin->handle && plugin->handle->internals);
|
||||
data = (struct plugin_callback_data*) plugin->handle->internals;
|
||||
return data;
|
||||
}
|
||||
|
||||
static int plugin_command_dispatch(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
|
||||
@ -40,14 +43,37 @@ 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;
|
||||
}
|
||||
|
||||
struct plugin_callback_data* plugin_callback_data_create()
|
||||
{
|
||||
struct plugin_callback_data* data = (struct plugin_callback_data*) hub_malloc_zero(sizeof(struct plugin_callback_data));
|
||||
LOG_PLUGIN("plugin_callback_data_create()");
|
||||
data->commands = list_create();
|
||||
return data;
|
||||
}
|
||||
|
||||
void plugin_callback_data_destroy(struct plugin_callback_data* data)
|
||||
{
|
||||
LOG_PLUGIN("plugin_callback_data_destroy()");
|
||||
if (data->commands)
|
||||
{
|
||||
uhub_assert(list_size(data->commands) == 0);
|
||||
list_destroy(data->commands);
|
||||
}
|
||||
|
||||
hub_free(data);
|
||||
}
|
||||
|
||||
static struct hub_user* convert_user_type(struct plugin_user* user)
|
||||
{
|
||||
struct hub_user* huser = (struct hub_user*) user;
|
||||
@ -56,6 +82,7 @@ static struct hub_user* convert_user_type(struct plugin_user* user)
|
||||
|
||||
static int cbfunc_send_message(struct plugin_handle* plugin, struct plugin_user* user, const char* message)
|
||||
{
|
||||
// struct plugin_callback_data* data = get_callback_data(plugin);
|
||||
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);
|
||||
@ -65,19 +92,9 @@ 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)
|
||||
{
|
||||
// struct plugin_callback_data* data = get_callback_data(plugin);
|
||||
char code_str[4];
|
||||
char* buffer = adc_msg_escape(message);
|
||||
struct adc_message* command = adc_msg_construct(ADC_CMD_ISTA, strlen(buffer) + 10);
|
||||
@ -92,6 +109,7 @@ static int cbfunc_send_status(struct plugin_handle* plugin, struct plugin_user*
|
||||
|
||||
static int cbfunc_user_disconnect(struct plugin_handle* plugin, struct plugin_user* user)
|
||||
{
|
||||
// struct plugin_callback_data* data = get_callback_data(plugin);
|
||||
hub_disconnect_user(plugin_get_hub(plugin), convert_user_type(user), quit_kicked);
|
||||
return 0;
|
||||
}
|
||||
@ -112,6 +130,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 +139,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);
|
||||
@ -127,116 +147,16 @@ static int cbfunc_command_del(struct plugin_handle* plugin, struct plugin_comman
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t cbfunc_command_arg_reset(struct plugin_handle* plugin, struct plugin_command* cmd)
|
||||
{
|
||||
// TODO: Use proper function for rewriting for plugin_command -> hub_command
|
||||
return hub_command_arg_reset((struct hub_command*) cmd);
|
||||
}
|
||||
|
||||
struct plugin_command_arg_data* cbfunc_command_arg_next(struct plugin_handle* plugin, struct plugin_command* cmd, enum plugin_command_arg_type t)
|
||||
{
|
||||
// TODO: Use proper function for rewriting for plugin_command -> hub_command
|
||||
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);
|
||||
char* str_encoded = adc_msg_get_named_argument(hub->command_info, ADC_INF_FLAG_NICK);
|
||||
char* str = adc_msg_unescape(str_encoded);
|
||||
hub_free(str_encoded);
|
||||
return str;
|
||||
}
|
||||
|
||||
static char* cbfunc_get_hub_description(struct plugin_handle* plugin)
|
||||
{
|
||||
struct hub_info* hub = plugin_get_hub(plugin);
|
||||
char* str_encoded = adc_msg_get_named_argument(hub->command_info, ADC_INF_FLAG_DESCRIPTION);
|
||||
char* str = adc_msg_unescape(str_encoded);
|
||||
hub_free(str_encoded);
|
||||
return str;
|
||||
}
|
||||
|
||||
static void cbfunc_set_hub_name(struct plugin_handle* plugin, const char* str)
|
||||
{
|
||||
struct hub_info* hub = plugin_get_hub(plugin);
|
||||
struct adc_message* command;
|
||||
char* new_str = adc_msg_escape(str ? str : hub->config->hub_name);
|
||||
|
||||
adc_msg_replace_named_argument(hub->command_info, ADC_INF_FLAG_NICK, new_str);
|
||||
|
||||
// Broadcast hub name
|
||||
command = adc_msg_construct(ADC_CMD_IINF, (strlen(new_str) + 8));
|
||||
adc_msg_add_named_argument(command, ADC_INF_FLAG_NICK, new_str);
|
||||
route_to_all(hub, command);
|
||||
|
||||
adc_msg_free(command);
|
||||
hub_free(new_str);
|
||||
}
|
||||
|
||||
static void cbfunc_set_hub_description(struct plugin_handle* plugin, const char* str)
|
||||
{
|
||||
struct hub_info* hub = plugin_get_hub(plugin);
|
||||
struct adc_message* command;
|
||||
char* new_str = adc_msg_escape(str ? str : hub->config->hub_description);
|
||||
|
||||
adc_msg_replace_named_argument(hub->command_info, ADC_INF_FLAG_DESCRIPTION, new_str);
|
||||
|
||||
// Broadcast hub description
|
||||
command = adc_msg_construct(ADC_CMD_IINF, (strlen(new_str) + 8));
|
||||
adc_msg_add_named_argument(command, ADC_INF_FLAG_DESCRIPTION, new_str);
|
||||
route_to_all(hub, command);
|
||||
|
||||
adc_msg_free(command);
|
||||
hub_free(new_str);
|
||||
}
|
||||
|
||||
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;
|
||||
handle->hub.set_description = cbfunc_set_hub_description;
|
||||
}
|
||||
|
||||
void plugin_unregister_callback_functions(struct plugin_handle* handle)
|
||||
{
|
||||
}
|
||||
|
||||
struct plugin_callback_data* plugin_callback_data_create()
|
||||
{
|
||||
struct plugin_callback_data* data = (struct plugin_callback_data*) hub_malloc_zero(sizeof(struct plugin_callback_data));
|
||||
LOG_PLUGIN("plugin_callback_data_create()");
|
||||
data->commands = list_create();
|
||||
return data;
|
||||
}
|
||||
|
||||
void plugin_callback_data_destroy(struct plugin_handle* plugin, struct plugin_callback_data* data)
|
||||
{
|
||||
LOG_PLUGIN("plugin_callback_data_destroy()");
|
||||
if (data->commands)
|
||||
{
|
||||
// delete commands not deleted by the plugin itself:
|
||||
struct plugin_command_handle* cmd;
|
||||
while ( (cmd = list_get_first(data->commands)) )
|
||||
cbfunc_command_del(plugin, cmd);
|
||||
list_destroy(data->commands);
|
||||
}
|
||||
|
||||
hub_free(data);
|
||||
}
|
||||
|
@ -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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -24,9 +24,9 @@ struct plugin_handle;
|
||||
struct uhub_plugin;
|
||||
|
||||
extern struct plugin_callback_data* plugin_callback_data_create();
|
||||
extern void plugin_callback_data_destroy(struct plugin_handle* plugin, struct plugin_callback_data* data);
|
||||
extern void plugin_callback_data_destroy(struct plugin_callback_data* data);
|
||||
|
||||
extern void plugin_register_callback_functions(struct plugin_handle* plugin);
|
||||
extern void plugin_unregister_callback_functions(struct plugin_handle* plugin);
|
||||
|
||||
#endif /* HAVE_UHUB_PLUGIN_CALLBACK_H */
|
||||
#endif /* HAVE_UHUB_PLUGIN_CALLBACK_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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -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) \
|
||||
@ -81,13 +82,12 @@ static struct plugin_user* convert_user_type(struct hub_user* user)
|
||||
|
||||
plugin_st plugin_check_ip_early(struct hub_info* hub, struct ip_addr_encap* addr)
|
||||
{
|
||||
PLUGIN_INVOKE_STATUS_1(hub, on_check_ip_early, addr);
|
||||
PLUGIN_INVOKE_STATUS_1(hub, login_check_ip_early, addr);
|
||||
}
|
||||
|
||||
plugin_st plugin_check_ip_late(struct hub_info* hub, struct hub_user* who, struct ip_addr_encap* addr)
|
||||
plugin_st plugin_check_ip_late(struct hub_info* hub, struct ip_addr_encap* addr)
|
||||
{
|
||||
struct plugin_user* user = convert_user_type(who);
|
||||
PLUGIN_INVOKE_STATUS_2(hub, on_check_ip_late, user, addr);
|
||||
PLUGIN_INVOKE_STATUS_1(hub, login_check_ip_late, addr);
|
||||
}
|
||||
|
||||
void plugin_log_connection_accepted(struct hub_info* hub, struct ip_addr_encap* ipaddr)
|
||||
|
@ -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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -38,7 +38,7 @@ void plugin_log_chat_message(struct hub_info* hub, struct hub_user* from, const
|
||||
|
||||
/* IP ban related */
|
||||
plugin_st plugin_check_ip_early(struct hub_info* hub, struct ip_addr_encap* addr);
|
||||
plugin_st plugin_check_ip_late(struct hub_info* hub, struct hub_user* user, struct ip_addr_encap* addr);
|
||||
plugin_st plugin_check_ip_late(struct hub_info* hub, struct ip_addr_encap* addr);
|
||||
|
||||
/* Nickname allow/deny handling */
|
||||
plugin_st plugin_check_nickname_valid(struct hub_info* hub, const char* nick);
|
||||
|
@ -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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -23,10 +23,17 @@
|
||||
|
||||
struct plugin_callback_data;
|
||||
|
||||
struct plugin_hub_internals* get_internals(struct plugin_handle* handle)
|
||||
struct plugin_hub_internals
|
||||
{
|
||||
struct hub_info* hub;
|
||||
plugin_unregister_f unregister; /* The unregister function. */
|
||||
struct plugin_callback_data* callback_data; /* callback data that is unique for the plugin */
|
||||
};
|
||||
|
||||
static struct plugin_hub_internals* get_internals(struct plugin_handle* handle)
|
||||
{
|
||||
struct plugin_hub_internals* internals;
|
||||
uhub_assert(handle && handle->handle && handle->handle->internals);
|
||||
assert(handle && handle->handle && handle->handle->internals);
|
||||
internals = (struct plugin_hub_internals*) handle->handle->internals;
|
||||
return internals;
|
||||
}
|
||||
@ -69,7 +76,7 @@ void plugin_close(struct uhub_plugin* plugin)
|
||||
struct plugin_hub_internals* internals = (struct plugin_hub_internals*) plugin->internals;
|
||||
|
||||
LOG_PLUGIN("plugin_close: \"%s\"", plugin->filename);
|
||||
plugin_callback_data_destroy(plugin->handle, internals->callback_data);
|
||||
plugin_callback_data_destroy(internals->callback_data);
|
||||
hub_free(internals);
|
||||
plugin->internals = NULL;
|
||||
|
||||
@ -102,6 +109,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 +125,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();
|
||||
@ -155,8 +162,8 @@ struct plugin_handle* plugin_load(const char* filename, const char* config, stru
|
||||
void plugin_unload(struct plugin_handle* plugin)
|
||||
{
|
||||
struct plugin_hub_internals* internals = get_internals(plugin);
|
||||
internals->unregister(plugin);
|
||||
plugin_unregister_callback_functions(plugin);
|
||||
internals->unregister(plugin);
|
||||
plugin_close(plugin->handle);
|
||||
hub_free(plugin);
|
||||
}
|
||||
@ -229,16 +236,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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -32,7 +32,7 @@ struct uhub_plugin
|
||||
void* handle;
|
||||
plugin_unregister_f unregister;
|
||||
char* filename;
|
||||
void* internals; // Hub-internal stuff (struct plugin_hub_internals)
|
||||
void* internals; // Hub internal stuff
|
||||
};
|
||||
|
||||
struct uhub_plugins
|
||||
@ -40,7 +40,7 @@ struct uhub_plugins
|
||||
struct linked_list* loaded;
|
||||
};
|
||||
|
||||
// High level plugin loader code
|
||||
// High level plugin loader ode
|
||||
extern struct plugin_handle* plugin_load(const char* filename, const char* config, struct hub_info* hub);
|
||||
extern void plugin_unload(struct plugin_handle* plugin);
|
||||
|
||||
@ -54,14 +54,7 @@ extern void plugin_close(struct uhub_plugin*);
|
||||
extern void* plugin_lookup_symbol(struct uhub_plugin*, const char* symbol);
|
||||
|
||||
// Used internally only
|
||||
struct plugin_hub_internals
|
||||
{
|
||||
struct hub_info* hub;
|
||||
plugin_unregister_f unregister; /* The unregister function. */
|
||||
struct plugin_callback_data* callback_data; /* callback data that is unique for the plugin */
|
||||
};
|
||||
|
||||
extern struct plugin_hub_internals* get_internals(struct plugin_handle*);
|
||||
extern struct hub_info* plugin_get_hub(struct plugin_handle*);
|
||||
|
||||
#endif /* HAVE_UHUB_PLUGIN_LOADER_H */
|
||||
|
||||
|
@ -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,37 +71,26 @@ 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))
|
||||
{
|
||||
/* Looks like HTTP - Not supported, but we log it. */
|
||||
LOG_TRACE("Probed HTTP connection. Not supported closing connection (%s)", ip_convert_to_string(&probe->addr));
|
||||
const char* buf = "501 Not implemented\r\n\r\n";
|
||||
net_con_send(con, buf, strlen(buf));
|
||||
}
|
||||
#ifdef SSL_SUPPORT
|
||||
else if (bytes >= 11 &&
|
||||
probe_recvbuf[0] == 22 &&
|
||||
probe_recvbuf[0] == 22 &&
|
||||
probe_recvbuf[1] == 3 && /* protocol major version */
|
||||
probe_recvbuf[5] == 1 && /* message type */
|
||||
probe_recvbuf[9] == probe_recvbuf[1])
|
||||
probe_recvbuf[9] == probe_recvbuf[1] &&
|
||||
probe_recvbuf[10] == probe_recvbuf[2])
|
||||
{
|
||||
if (probe->hub->config->tls_enable)
|
||||
{
|
||||
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))
|
||||
LOG_TRACE("Probed TLS %d.%d connection", (int) probe_recvbuf[1], (int) probe_recvbuf[2]);
|
||||
if (user_create(probe->hub, probe->connection, &probe->addr))
|
||||
{
|
||||
probe->connection = 0;
|
||||
}
|
||||
net_con_ssl_handshake(con, net_con_ssl_mode_server, probe->hub->ssl_ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_TRACE("Probed TLS %d.%d connection. TLS disabled in hub.", (int) probe_recvbuf[9], (int) probe_recvbuf[10]);
|
||||
LOG_TRACE("Probed TLS %d.%d connection. TLS disabled in hub.", (int) probe_recvbuf[1], (int) probe_recvbuf[2]);
|
||||
}
|
||||
}
|
||||
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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -28,28 +28,28 @@ int route_message(struct hub_info* hub, struct hub_user* u, struct adc_message*
|
||||
case 'B': /* Broadcast to all logged in clients */
|
||||
route_to_all(hub, msg);
|
||||
break;
|
||||
|
||||
|
||||
case 'D':
|
||||
target = uman_get_user_by_sid(hub->users, msg->target);
|
||||
target = uman_get_user_by_sid(hub, msg->target);
|
||||
if (target)
|
||||
{
|
||||
route_to_user(hub, target, msg);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 'E':
|
||||
target = uman_get_user_by_sid(hub->users, msg->target);
|
||||
target = uman_get_user_by_sid(hub, msg->target);
|
||||
if (target)
|
||||
{
|
||||
route_to_user(hub, target, msg);
|
||||
route_to_user(hub, u, msg);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 'F':
|
||||
route_to_subscribers(hub, msg);
|
||||
break;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Ignore the message */
|
||||
break;
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -109,19 +106,19 @@ int route_to_user(struct hub_info* hub, struct hub_user* user, struct adc_messag
|
||||
if (!user->connection)
|
||||
return 0;
|
||||
|
||||
uhub_assert(msg->cache && *msg->cache);
|
||||
assert(msg->cache && *msg->cache);
|
||||
|
||||
if (ioq_send_is_empty(user->send_queue) && !user_flag_get(user, flag_pipeline))
|
||||
if (hub_sendq_is_empty(user->send_queue) && !user_flag_get(user, flag_pipeline))
|
||||
{
|
||||
/* Perform oportunistic write */
|
||||
ioq_send_add(user->send_queue, msg);
|
||||
hub_sendq_add(user->send_queue, msg);
|
||||
handle_net_write(user);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (check_send_queue(hub, user, msg) >= 0)
|
||||
{
|
||||
ioq_send_add(user->send_queue, msg);
|
||||
hub_sendq_add(user->send_queue, msg);
|
||||
if (!user_flag_get(user, flag_pipeline))
|
||||
user_net_io_want_write(user);
|
||||
}
|
||||
@ -131,7 +128,7 @@ int route_to_user(struct hub_info* hub, struct hub_user* user, struct adc_messag
|
||||
|
||||
int route_flush_pipeline(struct hub_info* hub, struct hub_user* u)
|
||||
{
|
||||
if (ioq_send_is_empty(u->send_queue))
|
||||
if (hub_sendq_is_empty(u->send_queue))
|
||||
return 0;
|
||||
|
||||
handle_net_write(u);
|
||||
@ -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;
|
||||
}
|
||||
@ -155,40 +153,49 @@ 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;
|
||||
}
|
||||
});
|
||||
|
||||
if (!do_send)
|
||||
tmp = list_get_next(command->feature_cast_include);;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -203,17 +210,20 @@ int route_info_message(struct hub_info* hub, struct hub_user* u)
|
||||
struct adc_message* cmd = adc_msg_copy(u->info);
|
||||
const char* address = user_get_address(u);
|
||||
struct hub_user* user = 0;
|
||||
|
||||
|
||||
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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -38,7 +38,7 @@ static const char* user_log_str(struct hub_user* user)
|
||||
struct hub_user* user_create(struct hub_info* hub, struct net_connection* con, struct ip_addr_encap* addr)
|
||||
{
|
||||
struct hub_user* user = NULL;
|
||||
|
||||
|
||||
LOG_TRACE("user_create(), hub=%p, con[sd=%d]", hub, net_con_get_sd(con));
|
||||
|
||||
user = (struct hub_user*) hub_malloc_zero(sizeof(struct hub_user));
|
||||
@ -46,8 +46,8 @@ struct hub_user* user_create(struct hub_info* hub, struct net_connection* con, s
|
||||
if (user == NULL)
|
||||
return NULL; /* OOM */
|
||||
|
||||
user->send_queue = ioq_send_create();
|
||||
user->recv_queue = ioq_recv_create();
|
||||
user->send_queue = hub_sendq_create();
|
||||
user->recv_queue = hub_recvq_create();
|
||||
|
||||
user->connection = con;
|
||||
net_con_reinitialize(user->connection, net_event, user, NET_EVENT_READ);
|
||||
@ -60,8 +60,6 @@ struct hub_user* user_create(struct hub_info* hub, struct net_connection* con, s
|
||||
flood_control_reset(&user->flood_search);
|
||||
flood_control_reset(&user->flood_update);
|
||||
flood_control_reset(&user->flood_extras);
|
||||
|
||||
user->hub = hub;
|
||||
return user;
|
||||
}
|
||||
|
||||
@ -70,8 +68,8 @@ void user_destroy(struct hub_user* user)
|
||||
{
|
||||
LOG_TRACE("user_destroy(), user=%p", user);
|
||||
|
||||
ioq_recv_destroy(user->recv_queue);
|
||||
ioq_send_destroy(user->send_queue);
|
||||
hub_recvq_destroy(user->recv_queue);
|
||||
hub_sendq_destroy(user->send_queue);
|
||||
|
||||
if (user->connection)
|
||||
{
|
||||
@ -90,7 +88,7 @@ void user_set_state(struct hub_user* user, enum user_state state)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
user->state = state;
|
||||
}
|
||||
|
||||
@ -135,7 +133,7 @@ void user_update_info(struct hub_user* u, struct adc_message* cmd)
|
||||
prefix[1] = argument[1];
|
||||
adc_msg_replace_named_argument(cmd_new, prefix, argument+2);
|
||||
}
|
||||
|
||||
|
||||
hub_free(argument);
|
||||
argument = adc_msg_get_argument(cmd, n++);
|
||||
}
|
||||
@ -232,12 +230,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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -51,7 +51,7 @@ enum user_flags
|
||||
flag_muted = 0x00800000, /** User is muted (cannot chat) */
|
||||
flag_ignore = 0x01000000, /** Ignore further reads */
|
||||
flag_maxbuf = 0x02000000, /** Hit max buf read, ignore msg */
|
||||
flag_choke = 0x04000000, /** Choked: Cannot send, waiting for write event */
|
||||
flag_choke = 0x04000000, /** Choked: Cannot send, waiting for write event */
|
||||
flag_want_read = 0x08000000, /** Need to read (SSL) */
|
||||
flag_want_write = 0x10000000, /** Need to write (SSL) */
|
||||
flag_user_list = 0x20000000, /** Send queue bypass (when receiving the send queue) */
|
||||
@ -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
|
||||
@ -109,12 +109,12 @@ struct hub_user
|
||||
struct hub_user_info id; /** Contains nick name and CID */
|
||||
enum auth_credentials credentials; /** see enum user_credentials */
|
||||
enum user_state state; /** see enum user_state */
|
||||
uint32_t flags; /** see enum user_flags */
|
||||
uint32_t flags; /** see enum user_features */
|
||||
struct linked_list* feature_cast; /** Features supported by feature cast */
|
||||
struct adc_message* info; /** ADC 'INF' message (broadcasted to everyone joining the hub) */
|
||||
struct hub_info* hub; /** The hub instance this user belong to */
|
||||
struct ioq_recv* recv_queue;
|
||||
struct ioq_send* send_queue;
|
||||
struct hub_recvq* recv_queue;
|
||||
struct hub_sendq* send_queue;
|
||||
struct net_connection* connection; /** Connection data */
|
||||
struct hub_user_limits limits; /** Data used for limitation */
|
||||
enum user_quit_reason quit_reason; /** Quit reason (see user_quit_reason) */
|
||||
@ -150,7 +150,7 @@ extern void user_destroy(struct hub_user* user);
|
||||
* This associates a INF message to the user.
|
||||
* If the user already has a INF message associated, then this is
|
||||
* released before setting the new one.
|
||||
*
|
||||
*
|
||||
* @param info new inf message (can be NULL)
|
||||
*/
|
||||
extern void user_set_info(struct hub_user* user, struct adc_message* info);
|
||||
@ -244,7 +244,7 @@ extern int user_flag_get(struct hub_user* user, enum user_flags flag);
|
||||
* Check if a user supports 'feature' for feature casting (basis for 'Fxxx' messages)
|
||||
* The feature cast is specified as the 'SU' argument to the user's
|
||||
* INF-message.
|
||||
*
|
||||
*
|
||||
* @param feature a feature to lookup (example: 'TCP4' or 'UDP4')
|
||||
* @return 1 if 'feature' supported, or 0 otherwise
|
||||
*/
|
||||
|
@ -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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -28,7 +28,7 @@ static void clear_user_list_callback(void* ptr)
|
||||
if (ptr)
|
||||
{
|
||||
struct hub_user* u = (struct hub_user*) ptr;
|
||||
|
||||
|
||||
/* Mark the user as already being disconnected.
|
||||
* This prevents the hub from trying to send
|
||||
* quit messages to other users.
|
||||
@ -38,133 +38,196 @@ static void clear_user_list_callback(void* ptr)
|
||||
}
|
||||
}
|
||||
|
||||
static int uman_map_compare(const void* a, const void* b)
|
||||
void uman_update_stats(struct hub_info* hub)
|
||||
{
|
||||
return strcmp((const char*) a, (const char*) b);
|
||||
const int factor = TIMEOUT_STATS;
|
||||
struct net_statistics* total;
|
||||
struct net_statistics* intermediate;
|
||||
net_stats_get(&intermediate, &total);
|
||||
|
||||
hub->stats.net_tx = (intermediate->tx / factor);
|
||||
hub->stats.net_rx = (intermediate->rx / factor);
|
||||
hub->stats.net_tx_peak = MAX(hub->stats.net_tx, hub->stats.net_tx_peak);
|
||||
hub->stats.net_rx_peak = MAX(hub->stats.net_rx, hub->stats.net_rx_peak);
|
||||
hub->stats.net_tx_total = total->tx;
|
||||
hub->stats.net_rx_total = total->rx;
|
||||
|
||||
net_stats_reset();
|
||||
}
|
||||
|
||||
|
||||
struct hub_user_manager* uman_init()
|
||||
void uman_print_stats(struct hub_info* hub)
|
||||
{
|
||||
struct hub_user_manager* users = (struct hub_user_manager*) hub_malloc_zero(sizeof(struct hub_user_manager));
|
||||
LOG_INFO("Statistics users=" PRINTF_SIZE_T " (peak_users=" PRINTF_SIZE_T "), net_tx=%d KB/s, net_rx=%d KB/s (peak_tx=%d KB/s, peak_rx=%d KB/s)",
|
||||
hub->users->count,
|
||||
hub->users->count_peak,
|
||||
(int) hub->stats.net_tx / 1024,
|
||||
(int) hub->stats.net_rx / 1024,
|
||||
(int) hub->stats.net_tx_peak / 1024,
|
||||
(int) hub->stats.net_rx_peak / 1024);
|
||||
}
|
||||
|
||||
static void timer_statistics(struct timeout_evt* t)
|
||||
{
|
||||
struct hub_info* hub = (struct hub_info*) t->ptr;
|
||||
uman_update_stats(hub);
|
||||
timeout_queue_reschedule(net_backend_get_timeout_queue(), hub->users->timeout, TIMEOUT_STATS);
|
||||
}
|
||||
|
||||
int uman_init(struct hub_info* hub)
|
||||
{
|
||||
struct hub_user_manager* users = NULL;
|
||||
if (!hub)
|
||||
return -1;
|
||||
|
||||
users = (struct hub_user_manager*) hub_malloc_zero(sizeof(struct hub_user_manager));
|
||||
if (!users)
|
||||
return NULL;
|
||||
return -1;
|
||||
|
||||
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());
|
||||
|
||||
return users;
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
if (!users->list)
|
||||
{
|
||||
list_clear(users->list, &clear_user_list_callback);
|
||||
list_destroy(users->list);
|
||||
hub_free(users);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sid_pool_destroy(users->sids);
|
||||
|
||||
hub_free(users);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
||||
users->shared_size += user->limits.shared_size;
|
||||
users->shared_files += user->limits.shared_files;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uman_remove(struct hub_user_manager* users, struct hub_user* user)
|
||||
{
|
||||
if (!users || !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)
|
||||
if (net_backend_get_timeout_queue())
|
||||
{
|
||||
users->count--;
|
||||
users->timeout = hub_malloc_zero(sizeof(struct timeout_evt));
|
||||
timeout_evt_initialize(users->timeout, timer_statistics, hub);
|
||||
timeout_queue_insert(net_backend_get_timeout_queue(), users->timeout, TIMEOUT_STATS);
|
||||
}
|
||||
|
||||
hub->users = users;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uman_shutdown(struct hub_info* hub)
|
||||
{
|
||||
if (!hub || !hub->users)
|
||||
return -1;
|
||||
|
||||
if (net_backend_get_timeout_queue())
|
||||
{
|
||||
timeout_queue_remove(net_backend_get_timeout_queue(), hub->users->timeout);
|
||||
hub_free(hub->users->timeout);
|
||||
}
|
||||
|
||||
if (hub->users->list)
|
||||
{
|
||||
list_clear(hub->users->list, &clear_user_list_callback);
|
||||
list_destroy(hub->users->list);
|
||||
}
|
||||
sid_pool_destroy(hub->users->sids);
|
||||
hub_free(hub->users);
|
||||
hub->users = 0;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uman_add(struct hub_info* hub, struct hub_user* user)
|
||||
{
|
||||
if (!hub || !user)
|
||||
return -1;
|
||||
|
||||
if (user->hub)
|
||||
return -1;
|
||||
|
||||
list_append(hub->users->list, user);
|
||||
hub->users->count++;
|
||||
hub->users->count_peak = MAX(hub->users->count, hub->users->count_peak);
|
||||
|
||||
hub->users->shared_size += user->limits.shared_size;
|
||||
hub->users->shared_files += user->limits.shared_files;
|
||||
|
||||
user->hub = hub;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uman_remove(struct hub_info* hub, struct hub_user* user)
|
||||
{
|
||||
if (!hub || !user)
|
||||
return -1;
|
||||
|
||||
list_remove(hub->users->list, user);
|
||||
|
||||
if (hub->users->count > 0)
|
||||
{
|
||||
hub->users->count--;
|
||||
}
|
||||
else
|
||||
{
|
||||
uhub_assert(!"negative count!");
|
||||
assert(!"negative count!");
|
||||
}
|
||||
|
||||
users->shared_size -= user->limits.shared_size;
|
||||
users->shared_files -= user->limits.shared_files;
|
||||
hub->users->shared_size -= user->limits.shared_size;
|
||||
hub->users->shared_files -= user->limits.shared_files;
|
||||
|
||||
user->hub = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct hub_user* uman_get_user_by_sid(struct hub_user_manager* users, sid_t sid)
|
||||
struct hub_user* uman_get_user_by_sid(struct hub_info* hub, sid_t sid)
|
||||
{
|
||||
return sid_lookup(users->sids, sid);
|
||||
return sid_lookup(hub->users->sids, sid);
|
||||
}
|
||||
|
||||
|
||||
struct hub_user* uman_get_user_by_cid(struct hub_user_manager* users, const char* cid)
|
||||
struct hub_user* uman_get_user_by_cid(struct hub_info* hub, const char* cid)
|
||||
{
|
||||
struct hub_user* user = (struct hub_user*) rb_tree_get(users->cidmap, (const void*) cid);
|
||||
return user;
|
||||
struct hub_user* user = (struct hub_user*) list_get_first(hub->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(hub->users->list);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
struct hub_user* uman_get_user_by_nick(struct hub_user_manager* users, const char* nick)
|
||||
struct hub_user* uman_get_user_by_nick(struct hub_info* hub, const char* nick)
|
||||
{
|
||||
struct hub_user* user = (struct hub_user*) rb_tree_get(users->nickmap, nick);
|
||||
return user;
|
||||
struct hub_user* user = (struct hub_user*) list_get_first(hub->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(hub->users->list);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t uman_get_user_by_addr(struct hub_user_manager* users, struct linked_list* target, struct ip_range* range)
|
||||
size_t uman_get_user_by_addr(struct hub_info* hub, struct linked_list* users, 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(hub->users->list); /* iterate users - only on incoming INF msg */
|
||||
while (user)
|
||||
{
|
||||
if (ip_in_range(&user->id.addr, range))
|
||||
{
|
||||
list_append(target, user);
|
||||
list_append(users, user);
|
||||
num++;
|
||||
}
|
||||
});
|
||||
user = (struct hub_user*) list_get_next(hub->users->list);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
int uman_send_user_list(struct hub_info* hub, struct hub_user_manager* users, struct hub_user* target)
|
||||
int uman_send_user_list(struct hub_info* hub, struct hub_user* target)
|
||||
{
|
||||
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(hub->users->list); /* iterate users - only on INF or PAS msg */
|
||||
while (user)
|
||||
{
|
||||
if (user_is_logged_in(user))
|
||||
{
|
||||
@ -172,7 +235,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(hub->users->list);
|
||||
}
|
||||
|
||||
#if 0
|
||||
FIXME: FIXME FIXME handle send queue excess
|
||||
@ -184,7 +248,7 @@ int uman_send_user_list(struct hub_info* hub, struct hub_user_manager* users, st
|
||||
return ret;
|
||||
}
|
||||
|
||||
void uman_send_quit_message(struct hub_info* hub, struct hub_user_manager* users, struct hub_user* leaving)
|
||||
void uman_send_quit_message(struct hub_info* hub, struct hub_user* leaving)
|
||||
{
|
||||
struct adc_message* command = adc_msg_construct(ADC_CMD_IQUI, 6);
|
||||
adc_msg_add_argument(command, (const char*) sid_to_string(leaving->id.sid));
|
||||
@ -197,9 +261,9 @@ void uman_send_quit_message(struct hub_info* hub, struct hub_user_manager* users
|
||||
adc_msg_free(command);
|
||||
}
|
||||
|
||||
sid_t uman_get_free_sid(struct hub_user_manager* users, struct hub_user* user)
|
||||
sid_t uman_get_free_sid(struct hub_info* hub, struct hub_user* user)
|
||||
{
|
||||
sid_t sid = sid_alloc(users->sids, user);
|
||||
sid_t sid = sid_alloc(hub->users->sids, user);
|
||||
user->id.sid = sid;
|
||||
return sid;
|
||||
}
|
||||
|
@ -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,41 +24,40 @@ 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)" */
|
||||
struct timeout_evt* timeout; /**<< "Timeout handler for statistics" */
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes the user manager.
|
||||
* @return 0 on success, or -1 if error (out of memory).
|
||||
*/
|
||||
extern struct hub_user_manager* uman_init();
|
||||
extern int uman_init(struct hub_info* hub);
|
||||
|
||||
/**
|
||||
* 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 (hub is invalid).
|
||||
*/
|
||||
extern int uman_shutdown(struct hub_user_manager* users);
|
||||
extern int uman_shutdown(struct hub_info* hub);
|
||||
|
||||
/**
|
||||
* Generate statistics for logfiles.
|
||||
*/
|
||||
extern void uman_update_stats(struct hub_user_manager* users);
|
||||
extern void uman_print_stats(struct hub_user_manager* users);
|
||||
extern void uman_update_stats(struct hub_info* hub);
|
||||
extern void uman_print_stats(struct hub_info* hub);
|
||||
|
||||
/**
|
||||
* Add a user to the user manager.
|
||||
*
|
||||
* @param users The usermanager to add the user to
|
||||
* @param hub The hub to add the user to
|
||||
* @param user The user to be added to the hub.
|
||||
*/
|
||||
extern int uman_add(struct hub_user_manager* users, struct hub_user* user);
|
||||
extern int uman_add(struct hub_info* hub, struct hub_user* user);
|
||||
|
||||
/**
|
||||
* Remove a user from the user manager.
|
||||
@ -67,19 +66,19 @@ extern int uman_add(struct hub_user_manager* users, struct hub_user* user);
|
||||
*
|
||||
* @return 0 if successfully removed, -1 if error.
|
||||
*/
|
||||
extern int uman_remove(struct hub_user_manager* users, struct hub_user* user);
|
||||
extern int uman_remove(struct hub_info* hub, struct hub_user* user);
|
||||
|
||||
/**
|
||||
* Returns and allocates an unused session ID (SID).
|
||||
*/
|
||||
extern sid_t uman_get_free_sid(struct hub_user_manager* users, struct hub_user* user);
|
||||
extern sid_t uman_get_free_sid(struct hub_info* hub, struct hub_user* user);
|
||||
|
||||
/**
|
||||
* Lookup a user based on the session ID (SID).
|
||||
*
|
||||
* NOTE: This function will only search connected users, which means
|
||||
* that SIDs assigned to users who are not yet completely logged in,
|
||||
* or are in the process of being disconnected will result in this
|
||||
* or are in the process of being disconnected will result in this
|
||||
* function returning NULL even though the sid is not freely available.
|
||||
*
|
||||
* FIXME: Is that really safe / sensible ?
|
||||
@ -87,28 +86,26 @@ extern sid_t uman_get_free_sid(struct hub_user_manager* users, struct hub_user*
|
||||
*
|
||||
* @return a user if found, or NULL if not found
|
||||
*/
|
||||
extern struct hub_user* uman_get_user_by_sid(struct hub_user_manager* users, sid_t sid);
|
||||
extern struct hub_user* uman_get_user_by_sid(struct hub_info* hub, sid_t sid);
|
||||
|
||||
/**
|
||||
* Lookup a user based on the client ID (CID).
|
||||
* @return a user if found, or NULL if not found
|
||||
*/
|
||||
extern struct hub_user* uman_get_user_by_cid(struct hub_user_manager* users, const char* cid);
|
||||
extern struct hub_user* uman_get_user_by_cid(struct hub_info* hub, const char* cid);
|
||||
|
||||
/**
|
||||
* Lookup a user based on the nick name.
|
||||
* @return a user if found, or NULL if not found
|
||||
*/
|
||||
extern struct hub_user* uman_get_user_by_nick(struct hub_user_manager* users, const char* nick);
|
||||
extern struct hub_user* uman_get_user_by_nick(struct hub_info* hub, const char* nick);
|
||||
|
||||
/**
|
||||
* Lookup users based on an ip address range.
|
||||
*
|
||||
* @param[out] target the list of users matching the address
|
||||
* @param range the IP range of users to match
|
||||
* @return The number of users matching the addresses, or -1 on error (mask is wrong).
|
||||
* @return The number of users matching the addressess, or -1 on error (mask is wrong).
|
||||
*/
|
||||
extern size_t uman_get_user_by_addr(struct hub_user_manager* users, struct linked_list* target, struct ip_range* range);
|
||||
extern size_t uman_get_user_by_addr(struct hub_info* hub, struct linked_list* users, struct ip_range* range);
|
||||
|
||||
/**
|
||||
* Send the user list of connected clients to 'user'.
|
||||
@ -116,13 +113,13 @@ extern size_t uman_get_user_by_addr(struct hub_user_manager* users, struct linke
|
||||
*
|
||||
* @return 1 if sending the user list succeeded, 0 otherwise.
|
||||
*/
|
||||
extern int uman_send_user_list(struct hub_info* hub, struct hub_user_manager* users, struct hub_user* user);
|
||||
extern int uman_send_user_list(struct hub_info* hub, struct hub_user* user);
|
||||
|
||||
/**
|
||||
* Send a quit message to all connected users when 'user' is
|
||||
* leaving the hub (for whatever reason).
|
||||
*/
|
||||
extern void uman_send_quit_message(struct hub_info* hub, struct hub_user_manager* users, struct hub_user* user);
|
||||
extern void uman_send_quit_message(struct hub_info* hub, struct hub_user* user);
|
||||
|
||||
|
||||
#endif /* HAVE_UHUB_USER_MANAGER_H */
|
||||
|
@ -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,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);
|
||||
}
|
||||
@ -125,11 +132,10 @@ struct timeout_queue* net_backend_get_timeout_queue()
|
||||
*/
|
||||
int net_backend_process()
|
||||
{
|
||||
int res = 0;
|
||||
int res;
|
||||
size_t secs = timeout_queue_get_next_timeout(&g_backend->timeout_queue, g_backend->now);
|
||||
|
||||
if (g_backend->common.num)
|
||||
res = g_backend->handler.backend_poll(g_backend->data, secs * 1000);
|
||||
res = g_backend->handler.backend_poll(g_backend->data, secs * 1000);
|
||||
|
||||
g_backend->now = time(0);
|
||||
timeout_queue_process(&g_backend->timeout_queue, g_backend->now);
|
||||
@ -140,9 +146,6 @@ int net_backend_process()
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Process pending DNS results
|
||||
// net_dns_process();
|
||||
|
||||
g_backend->handler.backend_process(g_backend->data, res);
|
||||
|
||||
net_cleanup_process(g_backend->cleaner);
|
||||
@ -159,8 +162,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++;
|
||||
@ -178,8 +181,11 @@ void net_con_close(struct net_connection* con)
|
||||
|
||||
#ifdef SSL_SUPPORT
|
||||
if (con->ssl)
|
||||
net_ssl_shutdown(con);
|
||||
#endif /* SSL_SUPPORT */
|
||||
{
|
||||
SSL_shutdown(con->ssl);
|
||||
SSL_clear(con->ssl);
|
||||
}
|
||||
#endif
|
||||
|
||||
net_close(con->sd);
|
||||
con->sd = -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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -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-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,17 +13,18 @@
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#define NET_WANT_READ NET_EVENT_READ
|
||||
#define NET_WANT_WRITE NET_EVENT_WRITE
|
||||
#define NET_WANT_ACCEPT NET_EVENT_READ
|
||||
|
||||
#define NET_SSL_ANY NET_WANT_SSL_READ | NET_WANT_SSL_WRITE | NET_WANT_SSL_ACCEPT | NET_WANT_SSL_CONNECT | NET_WANT_SSL_X509_LOOKUP
|
||||
|
||||
struct ssl_handle; /* abstract type */
|
||||
#define NET_WANT_SSL_READ 0x0010
|
||||
#define NET_WANT_SSL_WRITE 0x0020
|
||||
#define NET_WANT_SSL_ACCEPT 0x0040
|
||||
#define NET_WANT_SSL_CONNECT 0x0080
|
||||
#define NET_WANT_SSL_X509_LOOKUP 0x0100
|
||||
|
||||
#define NET_CLEANUP 0x8000
|
||||
|
||||
@ -35,7 +36,9 @@ struct ssl_handle; /* abstract type */
|
||||
struct timeout_evt* timeout; /** timeout event handler */
|
||||
|
||||
#define NET_CON_STRUCT_SSL \
|
||||
struct ssl_handle* ssl; /** SSL handle */
|
||||
SSL* ssl; /** SSL handle */ \
|
||||
uint32_t ssl_state; /** SSL state */ \
|
||||
size_t write_len; /** Length of last SSL_write(), only used if flags is NET_WANT_SSL_READ. */ \
|
||||
|
||||
#ifdef SSL_SUPPORT
|
||||
#define NET_CON_STRUCT_COMMON \
|
||||
|
@ -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,26 +13,139 @@
|
||||
* 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()
|
||||
#ifdef SSL_SUPPORT
|
||||
|
||||
enum uhub_tls_state
|
||||
{
|
||||
int err = net_error();
|
||||
return
|
||||
#ifdef WINSOCK
|
||||
err == WSAEWOULDBLOCK
|
||||
#else
|
||||
err == EWOULDBLOCK
|
||||
#endif
|
||||
|| err == EINTR;
|
||||
tls_st_none,
|
||||
tls_st_error,
|
||||
tls_st_accepting,
|
||||
tls_st_connecting,
|
||||
tls_st_connected,
|
||||
tls_st_disconnecting,
|
||||
};
|
||||
|
||||
static int handle_openssl_error(struct net_connection* con, int ret)
|
||||
{
|
||||
uhub_assert(con);
|
||||
|
||||
int error = SSL_get_error(con->ssl, ret);
|
||||
switch (error)
|
||||
{
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
LOG_PROTO("SSL_get_error: ret=%d, error=%d: SSL_ERROR_ZERO_RETURN", ret, error);
|
||||
con->ssl_state = tls_st_error;
|
||||
return -1;
|
||||
|
||||
case SSL_ERROR_WANT_READ:
|
||||
LOG_PROTO("SSL_get_error: ret=%d, error=%d: SSL_ERROR_WANT_READ", ret, error);
|
||||
con->flags |= NET_WANT_SSL_READ;
|
||||
net_con_update(con, NET_EVENT_READ);
|
||||
return 0;
|
||||
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
LOG_PROTO("SSL_get_error: ret=%d, error=%d: SSL_ERROR_WANT_WRITE", ret, error);
|
||||
con->flags |= NET_WANT_SSL_WRITE;
|
||||
net_con_update(con, NET_EVENT_READ | NET_EVENT_WRITE);
|
||||
return 0;
|
||||
|
||||
case SSL_ERROR_SYSCALL:
|
||||
LOG_PROTO("SSL_get_error: ret=%d, error=%d: SSL_ERROR_SYSCALL", ret, error);
|
||||
/* if ret == 0, connection closed, if ret == -1, check with errno */
|
||||
if (ret == 0)
|
||||
return -1;
|
||||
else
|
||||
return -net_error();
|
||||
|
||||
case SSL_ERROR_SSL:
|
||||
LOG_PROTO("SSL_get_error: ret=%d, error=%d: SSL_ERROR_SSL", ret, error);
|
||||
/* internal openssl error */
|
||||
con->ssl_state = tls_st_error;
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssize_t net_con_ssl_accept(struct net_connection* con)
|
||||
{
|
||||
uhub_assert(con);
|
||||
con->ssl_state = tls_st_accepting;
|
||||
ssize_t ret = SSL_accept(con->ssl);
|
||||
#ifdef NETWORK_DUMP_DEBUG
|
||||
LOG_PROTO("SSL_accept() ret=%d", ret);
|
||||
#endif
|
||||
if (ret > 0)
|
||||
{
|
||||
net_con_update(con, NET_EVENT_READ);
|
||||
con->ssl_state = tls_st_connected;
|
||||
}
|
||||
else
|
||||
{
|
||||
return handle_openssl_error(con, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t net_con_ssl_connect(struct net_connection* con)
|
||||
{
|
||||
uhub_assert(con);
|
||||
|
||||
con->ssl_state = tls_st_connecting;
|
||||
ssize_t ret = SSL_connect(con->ssl);
|
||||
#ifdef NETWORK_DUMP_DEBUG
|
||||
LOG_PROTO("SSL_connect() ret=%d", ret);
|
||||
#endif
|
||||
if (ret > 0)
|
||||
{
|
||||
con->ssl_state = tls_st_connected;
|
||||
net_con_update(con, NET_EVENT_READ);
|
||||
}
|
||||
else
|
||||
{
|
||||
return handle_openssl_error(con, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode ssl_mode, SSL_CTX* ssl_ctx)
|
||||
{
|
||||
uhub_assert(con);
|
||||
SSL* ssl = 0;
|
||||
|
||||
if (ssl_mode == net_con_ssl_mode_server)
|
||||
{
|
||||
ssl = SSL_new(ssl_ctx);
|
||||
if (!ssl)
|
||||
{
|
||||
LOG_ERROR("Unable to create new SSL stream\n");
|
||||
return -1;
|
||||
}
|
||||
SSL_set_fd(ssl, con->sd);
|
||||
net_con_set_ssl(con, ssl);
|
||||
return net_con_ssl_accept(con);
|
||||
}
|
||||
else
|
||||
{
|
||||
ssl = SSL_new(SSL_CTX_new(TLSv1_method()));
|
||||
SSL_set_fd(ssl, con->sd);
|
||||
net_con_set_ssl(con, ssl);
|
||||
return net_con_ssl_connect(con);
|
||||
}
|
||||
}
|
||||
#endif /* SSL_SUPPORT */
|
||||
|
||||
#ifdef SSL_SUPPORT
|
||||
void net_stats_add_tx(size_t bytes);
|
||||
void net_stats_add_rx(size_t bytes);
|
||||
#endif
|
||||
|
||||
ssize_t net_con_send(struct net_connection* con, const void* buf, size_t len)
|
||||
{
|
||||
int ret;
|
||||
@ -43,7 +156,13 @@ ssize_t net_con_send(struct net_connection* con, const void* buf, size_t len)
|
||||
ret = net_send(con->sd, buf, len, UHUB_SEND_SIGNAL);
|
||||
if (ret == -1)
|
||||
{
|
||||
if (is_blocked_or_interrupted())
|
||||
if (
|
||||
#ifdef WINSOCK
|
||||
net_error() == WSAEWOULDBLOCK
|
||||
#else
|
||||
net_error() == EWOULDBLOCK
|
||||
#endif
|
||||
|| net_error() == EINTR)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
@ -51,9 +170,19 @@ ssize_t net_con_send(struct net_connection* con, const void* buf, size_t len)
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = net_ssl_send(con, buf, len);
|
||||
con->write_len = len;
|
||||
ret = SSL_write(con->ssl, buf, len);
|
||||
LOG_PROTO("SSL_write(con=%p, buf=%p, len=" PRINTF_SIZE_T ") => %d", con, buf, len, ret);
|
||||
if (ret <= 0)
|
||||
{
|
||||
return handle_openssl_error(con, ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
net_stats_add_tx(ret);
|
||||
}
|
||||
}
|
||||
#endif /* SSL_SUPPORT */
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -61,13 +190,19 @@ ssize_t net_con_recv(struct net_connection* con, void* buf, size_t len)
|
||||
{
|
||||
int ret;
|
||||
#ifdef SSL_SUPPORT
|
||||
if (!con->ssl)
|
||||
if (!net_con_is_ssl(con))
|
||||
{
|
||||
#endif
|
||||
ret = net_recv(con->sd, buf, len, 0);
|
||||
if (ret == -1)
|
||||
{
|
||||
if (is_blocked_or_interrupted())
|
||||
if (
|
||||
#ifdef WINSOCK
|
||||
net_error() == WSAEWOULDBLOCK
|
||||
#else
|
||||
net_error() == EWOULDBLOCK
|
||||
#endif
|
||||
|| net_error() == EINTR)
|
||||
return 0;
|
||||
return -net_error();
|
||||
}
|
||||
@ -79,9 +214,22 @@ ssize_t net_con_recv(struct net_connection* con, void* buf, size_t len)
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = net_ssl_recv(con, buf, len);
|
||||
if (con->ssl_state == tls_st_error)
|
||||
return -1;
|
||||
|
||||
ret = SSL_read(con->ssl, buf, len);
|
||||
LOG_PROTO("SSL_read(con=%p, buf=%p, len=" PRINTF_SIZE_T ") => %d", con, buf, len, ret);
|
||||
if (ret > 0)
|
||||
{
|
||||
net_con_update(con, NET_EVENT_READ);
|
||||
net_stats_add_rx(ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
return handle_openssl_error(con, ret);
|
||||
}
|
||||
}
|
||||
#endif /* SSL_SUPPORT */
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -90,7 +238,13 @@ ssize_t net_con_peek(struct net_connection* con, void* buf, size_t len)
|
||||
int ret = net_recv(con->sd, buf, len, MSG_PEEK);
|
||||
if (ret == -1)
|
||||
{
|
||||
if (is_blocked_or_interrupted())
|
||||
if (
|
||||
#ifdef WINSOCK
|
||||
net_error() == WSAEWOULDBLOCK
|
||||
#else
|
||||
net_error() == EWOULDBLOCK
|
||||
#endif
|
||||
|| net_error() == EINTR)
|
||||
return 0;
|
||||
return -net_error();
|
||||
}
|
||||
@ -100,10 +254,19 @@ ssize_t net_con_peek(struct net_connection* con, void* buf, size_t len)
|
||||
}
|
||||
|
||||
#ifdef SSL_SUPPORT
|
||||
|
||||
int net_con_is_ssl(struct net_connection* con)
|
||||
{
|
||||
return !!con->ssl;
|
||||
return con->ssl != 0;
|
||||
}
|
||||
|
||||
SSL* net_con_get_ssl(struct net_connection* con)
|
||||
{
|
||||
return con->ssl;
|
||||
}
|
||||
|
||||
void net_con_set_ssl(struct net_connection* con, SSL* ssl)
|
||||
{
|
||||
con->ssl = ssl;
|
||||
}
|
||||
#endif /* SSL_SUPPORT */
|
||||
|
||||
@ -117,28 +280,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)
|
||||
net_ssl_destroy(con);
|
||||
SSL_free(con->ssl);
|
||||
#endif
|
||||
hub_free(con);
|
||||
}
|
||||
@ -150,408 +295,68 @@ void net_con_callback(struct net_connection* con, int events)
|
||||
|
||||
if (events == NET_EVENT_TIMEOUT)
|
||||
{
|
||||
LOG_TRACE("net_con_callback(%p, TIMEOUT)", con);
|
||||
LOG_TRACE("net_con_callback(%p, TIMEOUT", con);
|
||||
con->callback(con, events, con->ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef SSL_SUPPORT
|
||||
if (con->ssl)
|
||||
net_ssl_callback(con, events);
|
||||
else
|
||||
if (!con->ssl)
|
||||
{
|
||||
#endif
|
||||
con->callback(con, events, con->ptr);
|
||||
}
|
||||
|
||||
struct net_connect_job
|
||||
{
|
||||
struct net_connection* con;
|
||||
struct net_connect_handle* handle;
|
||||
struct sockaddr_storage addr;
|
||||
struct net_connect_job* next;
|
||||
};
|
||||
|
||||
struct net_connect_handle
|
||||
{
|
||||
const char* address;
|
||||
uint16_t port;
|
||||
void* ptr;
|
||||
net_connect_cb callback;
|
||||
struct net_dns_job* dns;
|
||||
const struct net_dns_result* result;
|
||||
struct net_connect_job* job4;
|
||||
struct net_connect_job* job6;
|
||||
};
|
||||
|
||||
static void net_connect_callback(struct net_connect_handle* handle, enum net_connect_status status, struct net_connection* con);
|
||||
static void net_connect_job_internal_cb(struct net_connection* con, int event, void* ptr);
|
||||
|
||||
/**
|
||||
* Check if a connection job is completed.
|
||||
* @return -1 on completed with an error, 0 on not yet completed, or 1 if completed successfully (connected).
|
||||
*/
|
||||
static int net_connect_job_check(struct net_connect_job* job)
|
||||
{
|
||||
struct net_connection* con = job->con;
|
||||
int af = job->addr.ss_family;
|
||||
enum net_connect_status status;
|
||||
|
||||
int ret = net_connect(net_con_get_sd(con), (struct sockaddr*) &job->addr, af == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6));
|
||||
if (ret == 0 || (ret == -1 && net_error() == EISCONN))
|
||||
{
|
||||
LOG_TRACE("net_connect_job_check(): Socket connected!");
|
||||
job->con = NULL;
|
||||
net_con_clear_timeout(con);
|
||||
net_connect_callback(job->handle, net_connect_status_ok, con);
|
||||
return 1;
|
||||
}
|
||||
else if (ret == -1 && (net_error() == EALREADY || net_error() == EINPROGRESS || net_error() == EWOULDBLOCK || net_error() == EINTR))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
LOG_TRACE("net_connect_job_check(): Socket error!");
|
||||
|
||||
switch (net_error())
|
||||
{
|
||||
case ECONNREFUSED:
|
||||
status = net_connect_status_refused;
|
||||
break;
|
||||
case ENETUNREACH:
|
||||
status = net_connect_status_unreachable;
|
||||
break;
|
||||
|
||||
default:
|
||||
status = net_connect_status_socket_error;
|
||||
}
|
||||
|
||||
net_connect_callback(job->handle, status, NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void net_connect_job_free(struct net_connect_job* job)
|
||||
{
|
||||
if (job->con)
|
||||
net_con_close(job->con);
|
||||
job->handle = NULL;
|
||||
job->next = NULL;
|
||||
hub_free(job);
|
||||
}
|
||||
|
||||
static void net_connect_job_stop(struct net_connect_job* job)
|
||||
{
|
||||
if (job->addr.ss_family == AF_INET6)
|
||||
{
|
||||
job->handle->job6 = job->next;
|
||||
#ifdef SSL_SUPPORT
|
||||
}
|
||||
else
|
||||
{
|
||||
job->handle->job4 = job->next;
|
||||
}
|
||||
|
||||
net_connect_job_free(job);
|
||||
}
|
||||
|
||||
static int net_connect_depleted(struct net_connect_handle* handle)
|
||||
{
|
||||
return (!handle->job6 && !handle->job4);
|
||||
}
|
||||
|
||||
static int net_connect_job_process(struct net_connect_job* job)
|
||||
{
|
||||
int sd;
|
||||
if (!job->con)
|
||||
{
|
||||
sd = net_socket_create(job->addr.ss_family, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (sd == -1)
|
||||
#ifdef NETWORK_DUMP_DEBUG
|
||||
LOG_PROTO("net_con_event: events=%d, con=%p, state=%d", events, con, con->ssl_state);
|
||||
#endif
|
||||
switch (con->ssl_state)
|
||||
{
|
||||
LOG_DEBUG("net_connect_job_process: Unable to create socket!");
|
||||
net_connect_callback(job->handle, net_connect_status_socket_error, NULL);
|
||||
return -1; // FIXME
|
||||
}
|
||||
case tls_st_none:
|
||||
con->callback(con, events, con->ptr);
|
||||
break;
|
||||
|
||||
job->con = net_con_create();
|
||||
net_con_initialize(job->con, sd, net_connect_job_internal_cb, job, NET_EVENT_WRITE);
|
||||
net_con_set_timeout(job->con, TIMEOUT_CONNECTED); // FIXME: Use a proper timeout value!
|
||||
}
|
||||
case tls_st_error:
|
||||
con->callback(con, NET_EVENT_READ, con->ptr);
|
||||
break;
|
||||
|
||||
return net_connect_job_check(job);
|
||||
}
|
||||
case tls_st_accepting:
|
||||
if (net_con_ssl_accept(con) < 0)
|
||||
{
|
||||
con->callback(con, NET_EVENT_READ, con->ptr);
|
||||
}
|
||||
break;
|
||||
|
||||
case tls_st_connecting:
|
||||
if (net_con_ssl_connect(con) < 0)
|
||||
{
|
||||
con->callback(con, NET_EVENT_READ, con->ptr);
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
* Internal callback used to establish an outbound connection.
|
||||
*/
|
||||
static void net_connect_job_internal_cb(struct net_connection* con, int event, void* ptr)
|
||||
{
|
||||
struct net_connect_job* job = net_con_get_ptr(con);
|
||||
struct net_connect_job* next_job = job->next;
|
||||
struct net_connect_handle* handle = job->handle;
|
||||
case tls_st_connected:
|
||||
LOG_PROTO("tls_st_connected, events=%s%s, ssl_flags=%s%s", (events & NET_EVENT_READ ? "R" : ""), (events & NET_EVENT_WRITE ? "W" : ""), con->flags & NET_WANT_SSL_READ ? "R" : "", con->flags & NET_WANT_SSL_WRITE ? "W" : "");
|
||||
if (events & NET_EVENT_WRITE && con->flags & NET_WANT_SSL_READ)
|
||||
{
|
||||
con->callback(con, events & NET_EVENT_READ, con->ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (event == NET_EVENT_TIMEOUT)
|
||||
{
|
||||
// FIXME: Try next address, or if no more addresses left declare failure to connect.
|
||||
if (job->addr.ss_family == AF_INET6)
|
||||
{
|
||||
net_connect_job_stop(job);
|
||||
if (events & NET_EVENT_READ && con->flags & NET_WANT_SSL_WRITE)
|
||||
{
|
||||
con->callback(con, events & NET_EVENT_READ, con->ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!next_job)
|
||||
{
|
||||
LOG_TRACE("No more IPv6 addresses to try!");
|
||||
}
|
||||
con->callback(con, events, con->ptr);
|
||||
break;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
net_connect_job_stop(job);
|
||||
|
||||
if (!next_job)
|
||||
{
|
||||
LOG_TRACE("No more IPv4 addresses to try!");
|
||||
}
|
||||
}
|
||||
|
||||
if (net_connect_depleted(handle))
|
||||
{
|
||||
LOG_TRACE("No more addresses left. Unable to connect!");
|
||||
net_connect_callback(handle, net_connect_status_timeout, NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (event == NET_EVENT_WRITE)
|
||||
{
|
||||
net_connect_job_process(job);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void net_connect_cancel(struct net_connect_handle* handle)
|
||||
{
|
||||
struct net_connect_job* job;
|
||||
|
||||
job = handle->job6;
|
||||
while (job)
|
||||
{
|
||||
job = job->next;
|
||||
net_connect_job_free(handle->job6);
|
||||
handle->job6 = job;
|
||||
}
|
||||
|
||||
job = handle->job4;
|
||||
while (job)
|
||||
{
|
||||
job = job->next;
|
||||
net_connect_job_free(handle->job4);
|
||||
handle->job4 = job;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int net_connect_process_queue(struct net_connect_handle* handle, struct net_connect_job* job)
|
||||
{
|
||||
int ret;
|
||||
while (job)
|
||||
{
|
||||
ret = net_connect_job_process(job);
|
||||
if (ret < 0)
|
||||
{
|
||||
net_connect_job_stop(job);
|
||||
continue;
|
||||
}
|
||||
else if (ret == 0)
|
||||
{
|
||||
// Need to process again
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME: Success!
|
||||
return 1;
|
||||
case tls_st_disconnecting:
|
||||
return;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int net_connect_process(struct net_connect_handle* handle)
|
||||
{
|
||||
int ret4, ret6;
|
||||
|
||||
ret6 = net_connect_process_queue(handle, handle->job6);
|
||||
if (ret6 == 1)
|
||||
return 1; // Connected - cool!
|
||||
|
||||
net_connect_process_queue(handle, handle->job4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int net_connect_job_schedule(struct net_connect_handle* handle, struct ip_addr_encap* addr)
|
||||
{
|
||||
struct net_connect_job* job;
|
||||
struct sockaddr_in* addr4;
|
||||
struct sockaddr_in6* addr6;
|
||||
|
||||
if (addr->af == AF_INET6 && !net_is_ipv6_supported())
|
||||
{
|
||||
LOG_TRACE("net_connect_job_schedule(): Skipping IPv6 support since IPv6 is not supported.");
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
job = hub_malloc_zero(sizeof(struct net_connect_job));
|
||||
job->handle = handle;
|
||||
if (addr->af == AF_INET6)
|
||||
{
|
||||
addr6 = (struct sockaddr_in6*) &job->addr;
|
||||
LOG_TRACE("net_connect_job_schedule(): Scheduling IPv6 connect job.");
|
||||
addr6->sin6_family = AF_INET6;
|
||||
addr6->sin6_port = htons(handle->port);
|
||||
memcpy(&addr6->sin6_addr, &addr->internal_ip_data.in6, sizeof(struct in6_addr));
|
||||
|
||||
// prepend
|
||||
job->next = handle->job6;
|
||||
handle->job6 = job;
|
||||
}
|
||||
else
|
||||
{
|
||||
addr4 = (struct sockaddr_in*) &job->addr;
|
||||
LOG_TRACE("net_connect_job_schedule(): Scheduling IPv4 connect job.");
|
||||
addr4->sin_family = AF_INET;
|
||||
addr4->sin_port = htons(handle->port);
|
||||
memcpy(&addr4->sin_addr, &addr->internal_ip_data.in, sizeof(struct in_addr));
|
||||
|
||||
// prepend
|
||||
job->next = handle->job4;
|
||||
handle->job4 = job;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Callback when the DNS results are ready.
|
||||
* Create a list of IPv6 and IPv4 addresses, then
|
||||
* start connecting to them one by one until one succeeds.
|
||||
*/
|
||||
static int net_con_connect_dns_callback(struct net_dns_job* job, const struct net_dns_result* result)
|
||||
{
|
||||
struct ip_addr_encap* addr;
|
||||
struct net_connect_handle* handle = (struct net_connect_handle*) net_dns_job_get_ptr(job);
|
||||
handle->dns = NULL;
|
||||
size_t usable = 0;
|
||||
|
||||
LOG_TRACE("net_con_connect(): async - Got DNS results");
|
||||
if (!result)
|
||||
{
|
||||
LOG_DEBUG("net_con_connect() - Unable to lookup host!");
|
||||
net_connect_callback(handle, net_connect_status_dns_error, NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!net_dns_result_size(result))
|
||||
{
|
||||
LOG_DEBUG("net_con_connect() - Host not found!");
|
||||
net_connect_callback(handle, net_connect_status_host_not_found, NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
handle->result = result;
|
||||
|
||||
// Extract results into a separate list of IPv4 and IPv6 addresses.
|
||||
addr = net_dns_result_first(result);
|
||||
while (addr)
|
||||
{
|
||||
if (net_connect_job_schedule(handle, addr))
|
||||
usable++;
|
||||
addr = net_dns_result_next(result);
|
||||
}
|
||||
|
||||
net_connect_process(handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// typedef void (*net_connect_cb)(struct net_connect_handle*, enum net_connect_handle_code, struct net_connection* con);
|
||||
|
||||
struct net_connect_handle* net_con_connect(const char* address, uint16_t port, net_connect_cb callback, void* ptr)
|
||||
{
|
||||
struct net_connect_handle* handle = hub_malloc_zero(sizeof(struct net_connect_handle));
|
||||
|
||||
handle->address = hub_strdup(address);
|
||||
handle->port = port;
|
||||
handle->ptr = ptr;
|
||||
handle->callback = callback;
|
||||
|
||||
// FIXME: Check if DNS resolving is necessary ?
|
||||
handle->dns = net_dns_gethostbyname(address, AF_UNSPEC, net_con_connect_dns_callback, handle);
|
||||
if (!handle->dns)
|
||||
{
|
||||
LOG_TRACE("net_con_connect(): Unable to create DNS lookup job.");
|
||||
hub_free((char*) handle->address);
|
||||
hub_free(handle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void net_connect_destroy(struct net_connect_handle* handle)
|
||||
{
|
||||
hub_free((char*) handle->address);
|
||||
|
||||
// cancel DNS job if pending
|
||||
if (handle->dns)
|
||||
net_dns_job_cancel(handle->dns);
|
||||
|
||||
// Stop any connect jobs.
|
||||
net_connect_cancel(handle);
|
||||
|
||||
// free any DNS results
|
||||
net_dns_result_free(handle->result);
|
||||
|
||||
hub_free(handle);
|
||||
}
|
||||
|
||||
static void net_connect_callback(struct net_connect_handle* handle, enum net_connect_status status, struct net_connection* con)
|
||||
{
|
||||
uhub_assert(handle->callback != NULL);
|
||||
|
||||
// Call the callback
|
||||
handle->callback(handle, status, con, handle->ptr);
|
||||
handle->callback = NULL;
|
||||
|
||||
// Cleanup
|
||||
net_connect_destroy(handle);
|
||||
}
|
||||
|
||||
static void timeout_callback(struct timeout_evt* evt)
|
||||
{
|
||||
net_con_callback((struct net_connection*) evt->ptr, NET_EVENT_TIMEOUT);
|
||||
}
|
||||
|
||||
|
||||
void net_con_set_timeout(struct net_connection* con, int seconds)
|
||||
{
|
||||
if (!con->timeout)
|
||||
{
|
||||
con->timeout = hub_malloc_zero(sizeof(struct timeout_evt));
|
||||
timeout_evt_initialize(con->timeout, timeout_callback, con);
|
||||
timeout_queue_insert(net_backend_get_timeout_queue(), con->timeout, seconds);
|
||||
}
|
||||
else
|
||||
{
|
||||
timeout_queue_reschedule(net_backend_get_timeout_queue(), con->timeout, seconds);
|
||||
}
|
||||
}
|
||||
|
||||
void net_con_clear_timeout(struct net_connection* con)
|
||||
{
|
||||
if (con->timeout && timeout_evt_is_scheduled(con->timeout))
|
||||
{
|
||||
timeout_queue_remove(net_backend_get_timeout_queue(), con->timeout);
|
||||
hub_free(con->timeout);
|
||||
con->timeout = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -23,53 +23,20 @@
|
||||
#include "uhub.h"
|
||||
#include "network/common.h"
|
||||
#include "network/backend.h"
|
||||
#include "network/tls.h"
|
||||
|
||||
#define NET_EVENT_TIMEOUT 0x0001
|
||||
#define NET_EVENT_READ 0x0002
|
||||
#define NET_EVENT_WRITE 0x0004
|
||||
#define NET_EVENT_ERROR 0x1000
|
||||
|
||||
struct net_connection
|
||||
{
|
||||
NET_CON_STRUCT_COMMON
|
||||
};
|
||||
|
||||
struct net_connect_handle;
|
||||
|
||||
enum net_connect_status
|
||||
{
|
||||
net_connect_status_ok = 0,
|
||||
net_connect_status_host_not_found = -1,
|
||||
net_connect_status_no_address = -2,
|
||||
net_connect_status_dns_error = -3,
|
||||
net_connect_status_refused = -4,
|
||||
net_connect_status_unreachable = -5,
|
||||
net_connect_status_timeout = -6,
|
||||
net_connect_status_socket_error = -7,
|
||||
};
|
||||
|
||||
typedef void (*net_connect_cb)(struct net_connect_handle*, enum net_connect_status status, struct net_connection* con, void* ptr);
|
||||
|
||||
extern int net_con_get_sd(struct net_connection* con);
|
||||
extern void* net_con_get_ptr(struct net_connection* con);
|
||||
|
||||
extern struct net_connection* net_con_create();
|
||||
|
||||
/**
|
||||
* Establish an outbound TCP connection.
|
||||
* This will resolve the IP-addresses, and connect to
|
||||
* either an IPv4 or IPv6 address depending if it is supported,
|
||||
* and using the happy eyeballs algorithm.
|
||||
*
|
||||
* @param address Hostname, IPv4 or IPv6 address
|
||||
* @param port TCP port number
|
||||
* @param callback A callback to be called once the connection is established, or failed.
|
||||
* @returns a handle to the connection establishment job, or NULL if an immediate error.
|
||||
*/
|
||||
extern struct net_connect_handle* net_con_connect(const char* address, uint16_t port, net_connect_cb callback, void* ptr);
|
||||
extern void net_connect_destroy(struct net_connect_handle* handle);
|
||||
|
||||
extern void net_con_destroy(struct net_connection*);
|
||||
extern void net_con_initialize(struct net_connection* con, int sd, net_connection_cb callback, const void* ptr, int events);
|
||||
extern void net_con_reinitialize(struct net_connection* con, net_connection_cb callback, const void* ptr, int events);
|
||||
@ -88,7 +55,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 +64,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,12 +76,36 @@ 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.
|
||||
*/
|
||||
extern void net_con_set_timeout(struct net_connection* con, int seconds);
|
||||
extern void net_con_clear_timeout(struct net_connection* con);
|
||||
|
||||
#ifdef SSL_SUPPORT
|
||||
/**
|
||||
* Start SSL_accept()
|
||||
*/
|
||||
extern ssize_t net_con_ssl_accept(struct net_connection*);
|
||||
|
||||
/**
|
||||
* Start SSL_connect()
|
||||
*/
|
||||
extern ssize_t net_con_ssl_connect(struct net_connection*);
|
||||
|
||||
enum net_con_ssl_mode
|
||||
{
|
||||
net_con_ssl_mode_server,
|
||||
net_con_ssl_mode_client,
|
||||
};
|
||||
|
||||
extern ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode, SSL_CTX* ssl_ctx);
|
||||
|
||||
extern int net_con_is_ssl(struct net_connection* con);
|
||||
extern SSL* net_con_get_ssl(struct net_connection* con);
|
||||
extern void net_con_set_ssl(struct net_connection* con, SSL*);
|
||||
#endif /* SSL_SUPPORT */
|
||||
|
||||
#endif /* HAVE_UHUB_NETWORK_CONNECTION_H */
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user