Compare commits
31 Commits
gnutls_wor
...
async_dns_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d4763e54db | ||
|
|
38b19f633d | ||
|
|
d106ecdc65 | ||
|
|
99a2307d1d | ||
|
|
470c936e63 | ||
|
|
168fc5bfcc | ||
|
|
b34b90f95a | ||
|
|
793790d089 | ||
|
|
19559f4974 | ||
|
|
b999068555 | ||
|
|
4385266bb7 | ||
|
|
c50eb90bee | ||
|
|
1e0927f510 | ||
|
|
b9d43c784c | ||
|
|
46d365cafe | ||
|
|
3a8c91004e | ||
|
|
deaadd053b | ||
|
|
c28a5d3a9b | ||
|
|
8b06a75d8e | ||
|
|
e6cb7a7e10 | ||
|
|
82caa6b81f | ||
|
|
ddfbb919a7 | ||
|
|
7fae42aa4d | ||
|
|
ba59e1a00e | ||
|
|
4fcfee8e82 | ||
|
|
63171b0ce2 | ||
|
|
dcfcf3110d | ||
|
|
53a5f5a243 | ||
|
|
af083efb0c | ||
|
|
e7aa63f3bd | ||
|
|
279c932b67 |
132
CMakeLists.txt
132
CMakeLists.txt
@@ -17,7 +17,7 @@ set (PROJECT_SOURCE_DIR "${CMAKE_SOURCE_DIR}/src")
|
|||||||
option(RELEASE "Release build, debug build if disabled" ON)
|
option(RELEASE "Release build, debug build if disabled" ON)
|
||||||
option(LINK_SUPPORT "Allow hub linking" OFF)
|
option(LINK_SUPPORT "Allow hub linking" OFF)
|
||||||
option(SSL_SUPPORT "Enable SSL support" ON)
|
option(SSL_SUPPORT "Enable SSL support" ON)
|
||||||
option(USE_OPENSSL "Use OpenSSL's SSL support" OFF)
|
option(USE_OPENSSL "Use OpenSSL's SSL support" ON )
|
||||||
option(SQLITE_SUPPORT "Enable SQLite support" ON)
|
option(SQLITE_SUPPORT "Enable SQLite support" ON)
|
||||||
option(ADC_STRESS "Enable the stress tester client" OFF)
|
option(ADC_STRESS "Enable the stress tester client" OFF)
|
||||||
|
|
||||||
@@ -40,57 +40,15 @@ endif()
|
|||||||
|
|
||||||
include_directories("${PROJECT_SOURCE_DIR}")
|
include_directories("${PROJECT_SOURCE_DIR}")
|
||||||
|
|
||||||
set (network_SOURCES
|
file (GLOB uhub_SOURCES ${PROJECT_SOURCE_DIR}/core/*.c)
|
||||||
${PROJECT_SOURCE_DIR}/network/backend.c
|
list (REMOVE_ITEM uhub_SOURCES
|
||||||
${PROJECT_SOURCE_DIR}/network/connection.c
|
${PROJECT_SOURCE_DIR}/core/gen_config.c
|
||||||
${PROJECT_SOURCE_DIR}/network/epoll.c
|
${PROJECT_SOURCE_DIR}/core/main.c
|
||||||
${PROJECT_SOURCE_DIR}/network/kqueue.c
|
|
||||||
${PROJECT_SOURCE_DIR}/network/select.c
|
|
||||||
${PROJECT_SOURCE_DIR}/network/timeout.c
|
|
||||||
${PROJECT_SOURCE_DIR}/network/timer.c
|
|
||||||
${PROJECT_SOURCE_DIR}/network/network.c
|
|
||||||
${PROJECT_SOURCE_DIR}/network/openssl.c
|
|
||||||
${PROJECT_SOURCE_DIR}/network/ipcalc.c
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set (uhub_SOURCES
|
file (GLOB adc_SOURCES ${PROJECT_SOURCE_DIR}/adc/*.c)
|
||||||
${PROJECT_SOURCE_DIR}/core/auth.c
|
file (GLOB network_SOURCES ${PROJECT_SOURCE_DIR}/network/*.c)
|
||||||
${PROJECT_SOURCE_DIR}/core/command_parser.c
|
file (GLOB utils_SOURCES ${PROJECT_SOURCE_DIR}/util/*.c)
|
||||||
${PROJECT_SOURCE_DIR}/core/commands.c
|
|
||||||
${PROJECT_SOURCE_DIR}/core/config.c
|
|
||||||
${PROJECT_SOURCE_DIR}/core/eventqueue.c
|
|
||||||
${PROJECT_SOURCE_DIR}/core/hub.c
|
|
||||||
${PROJECT_SOURCE_DIR}/core/hubevent.c
|
|
||||||
${PROJECT_SOURCE_DIR}/core/inf.c
|
|
||||||
${PROJECT_SOURCE_DIR}/core/ioqueue.c
|
|
||||||
${PROJECT_SOURCE_DIR}/core/netevent.c
|
|
||||||
${PROJECT_SOURCE_DIR}/core/probe.c
|
|
||||||
${PROJECT_SOURCE_DIR}/core/route.c
|
|
||||||
${PROJECT_SOURCE_DIR}/core/user.c
|
|
||||||
${PROJECT_SOURCE_DIR}/core/usermanager.c
|
|
||||||
${PROJECT_SOURCE_DIR}/core/plugincallback.c
|
|
||||||
${PROJECT_SOURCE_DIR}/core/plugininvoke.c
|
|
||||||
${PROJECT_SOURCE_DIR}/core/pluginloader.c
|
|
||||||
)
|
|
||||||
|
|
||||||
set (adc_SOURCES
|
|
||||||
${PROJECT_SOURCE_DIR}/adc/message.c
|
|
||||||
${PROJECT_SOURCE_DIR}/adc/sid.c
|
|
||||||
)
|
|
||||||
|
|
||||||
set (utils_SOURCES
|
|
||||||
${PROJECT_SOURCE_DIR}/util/cbuffer.c
|
|
||||||
${PROJECT_SOURCE_DIR}/util/config_token.c
|
|
||||||
${PROJECT_SOURCE_DIR}/util/credentials.c
|
|
||||||
${PROJECT_SOURCE_DIR}/util/floodctl.c
|
|
||||||
${PROJECT_SOURCE_DIR}/util/getopt.c
|
|
||||||
${PROJECT_SOURCE_DIR}/util/list.c
|
|
||||||
${PROJECT_SOURCE_DIR}/util/log.c
|
|
||||||
${PROJECT_SOURCE_DIR}/util/memory.c
|
|
||||||
${PROJECT_SOURCE_DIR}/util/misc.c
|
|
||||||
${PROJECT_SOURCE_DIR}/util/rbtree.c
|
|
||||||
${PROJECT_SOURCE_DIR}/util/tiger.c
|
|
||||||
)
|
|
||||||
|
|
||||||
set (adcclient_SOURCES
|
set (adcclient_SOURCES
|
||||||
${PROJECT_SOURCE_DIR}/tools/adcclient.c
|
${PROJECT_SOURCE_DIR}/tools/adcclient.c
|
||||||
@@ -100,34 +58,34 @@ set (adcclient_SOURCES
|
|||||||
add_library(adc STATIC ${adc_SOURCES})
|
add_library(adc STATIC ${adc_SOURCES})
|
||||||
add_library(network STATIC ${network_SOURCES})
|
add_library(network STATIC ${network_SOURCES})
|
||||||
add_library(utils STATIC ${utils_SOURCES})
|
add_library(utils STATIC ${utils_SOURCES})
|
||||||
|
if(CMAKE_COMPILER_IS_GNUCC)
|
||||||
|
set_target_properties(utils PROPERTIES COMPILE_FLAGS -fPIC)
|
||||||
|
set_target_properties(network PROPERTIES COMPILE_FLAGS -fPIC)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_dependencies(adc utils)
|
add_dependencies(adc utils)
|
||||||
add_dependencies(network utils)
|
add_dependencies(network utils)
|
||||||
|
|
||||||
add_executable(uhub ${PROJECT_SOURCE_DIR}/core/main.c ${uhub_SOURCES} )
|
add_executable(uhub ${PROJECT_SOURCE_DIR}/core/main.c ${uhub_SOURCES} )
|
||||||
|
|
||||||
add_library(mod_example MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_example.c ${utils_SOURCES})
|
add_library(mod_example MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_example.c)
|
||||||
add_library(mod_welcome MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_welcome.c ${utils_SOURCES} ${network_SOURCES})
|
add_library(mod_welcome MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_welcome.c)
|
||||||
add_library(mod_logging MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_logging.c ${utils_SOURCES} ${PROJECT_SOURCE_DIR}/adc/sid.c ${network_SOURCES})
|
add_library(mod_logging MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_logging.c ${PROJECT_SOURCE_DIR}/adc/sid.c)
|
||||||
add_library(mod_auth_simple MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_auth_simple.c ${utils_SOURCES})
|
add_library(mod_auth_simple MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_auth_simple.c )
|
||||||
add_library(mod_chat_history MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_chat_history.c ${utils_SOURCES})
|
add_library(mod_chat_history MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_chat_history.c )
|
||||||
add_library(mod_chat_only MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_chat_only.c ${utils_SOURCES})
|
add_library(mod_chat_only MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_chat_only.c)
|
||||||
add_library(mod_topic MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_topic.c ${utils_SOURCES})
|
add_library(mod_topic MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_topic.c)
|
||||||
|
|
||||||
if (SQLITE_SUPPORT)
|
if (SQLITE_SUPPORT)
|
||||||
add_library(mod_auth_sqlite MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_auth_sqlite.c ${utils_SOURCES})
|
add_library(mod_auth_sqlite MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_auth_sqlite.c)
|
||||||
add_executable(uhub-passwd ${PROJECT_SOURCE_DIR}/tools/uhub-passwd.c ${PROJECT_SOURCE_DIR}/util/misc.c ${PROJECT_SOURCE_DIR}/util/memory.c ${PROJECT_SOURCE_DIR}/util/log.c ${PROJECT_SOURCE_DIR}/util/list.c)
|
add_executable(uhub-passwd ${PROJECT_SOURCE_DIR}/tools/uhub-passwd.c)
|
||||||
|
|
||||||
target_link_libraries(mod_auth_sqlite sqlite3)
|
target_link_libraries(mod_auth_sqlite sqlite3 utils)
|
||||||
target_link_libraries(uhub-passwd sqlite3)
|
target_link_libraries(uhub-passwd sqlite3 utils)
|
||||||
set_target_properties(mod_auth_sqlite PROPERTIES PREFIX "")
|
set_target_properties(mod_auth_sqlite PROPERTIES PREFIX "")
|
||||||
|
|
||||||
if (UNIX)
|
|
||||||
target_link_libraries(uhub pthread)
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
target_link_libraries(uhub ws2_32)
|
target_link_libraries(uhub ws2_32)
|
||||||
target_link_libraries(mod_logging ws2_32)
|
target_link_libraries(mod_logging ws2_32)
|
||||||
@@ -145,25 +103,46 @@ set_target_properties(
|
|||||||
PROPERTIES PREFIX "")
|
PROPERTIES PREFIX "")
|
||||||
|
|
||||||
target_link_libraries(uhub ${CMAKE_DL_LIBS} adc network utils)
|
target_link_libraries(uhub ${CMAKE_DL_LIBS} adc network utils)
|
||||||
|
target_link_libraries(mod_example utils)
|
||||||
|
target_link_libraries(mod_welcome utils)
|
||||||
|
target_link_libraries(mod_auth_simple utils)
|
||||||
|
target_link_libraries(mod_chat_history utils)
|
||||||
|
target_link_libraries(mod_chat_only utils)
|
||||||
|
target_link_libraries(mod_logging utils)
|
||||||
|
target_link_libraries(mod_topic utils)
|
||||||
|
target_link_libraries(utils network)
|
||||||
|
target_link_libraries(mod_welcome network)
|
||||||
|
target_link_libraries(mod_logging network)
|
||||||
|
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
add_library(adcclient STATIC ${adcclient_SOURCES})
|
add_library(adcclient STATIC ${adcclient_SOURCES})
|
||||||
add_executable(uhub-admin ${PROJECT_SOURCE_DIR}/tools/admin.c)
|
add_executable(uhub-admin ${PROJECT_SOURCE_DIR}/tools/admin.c)
|
||||||
target_link_libraries(uhub-admin adcclient adc network utils)
|
target_link_libraries(uhub-admin adcclient adc network utils pthread)
|
||||||
|
target_link_libraries(uhub pthread)
|
||||||
|
|
||||||
if (ADC_STRESS)
|
if (ADC_STRESS)
|
||||||
add_executable(adcrush ${PROJECT_SOURCE_DIR}/tools/adcrush.c ${adcclient_SOURCES})
|
add_executable(adcrush ${PROJECT_SOURCE_DIR}/tools/adcrush.c ${adcclient_SOURCES})
|
||||||
target_link_libraries(adcrush adcclient adc network utils)
|
target_link_libraries(adcrush adcclient adc network utils pthread)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(GIT_FOUND AND IS_DIRECTORY ".git")
|
if (NOT UHUB_REVISION AND GIT_FOUND)
|
||||||
execute_process(COMMAND ${GIT_EXECUTABLE} show -s --pretty=format:%h OUTPUT_VARIABLE UHUB_REVISION)
|
execute_process(COMMAND ${GIT_EXECUTABLE} show -s --pretty=format:%h
|
||||||
set (UHUB_GIT_VERSION "${UHUB_VERSION_MAJOR}.${UHUB_VERSION_MINOR}.${UHUB_VERSION_PATCH}-git-${UHUB_REVISION}")
|
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||||
else()
|
OUTPUT_VARIABLE UHUB_REVISION_TEMP
|
||||||
set (UHUB_GIT_VERSION "${UHUB_VERSION_MAJOR}.${UHUB_VERSION_MINOR}.${UHUB_VERSION_PATCH}-release")
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
if (UHUB_REVISION_TEMP)
|
||||||
|
set (UHUB_REVISION "git-${UHUB_REVISION_TEMP}")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (NOT UHUB_REVISION)
|
||||||
|
set (UHUB_REVISION "release")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set (UHUB_GIT_VERSION "${UHUB_VERSION_MAJOR}.${UHUB_VERSION_MINOR}.${UHUB_VERSION_PATCH}-${UHUB_REVISION}")
|
||||||
|
message (STATUS "Configuring uhub version: ${UHUB_GIT_VERSION}")
|
||||||
|
|
||||||
if(OPENSSL_FOUND)
|
if(OPENSSL_FOUND)
|
||||||
set(SSL_LIBS ${OPENSSL_LIBRARIES})
|
set(SSL_LIBS ${OPENSSL_LIBRARIES})
|
||||||
add_definitions(-DSSL_SUPPORT=1 -DSSL_USE_OPENSSL=1)
|
add_definitions(-DSSL_SUPPORT=1 -DSSL_USE_OPENSSL=1)
|
||||||
@@ -200,8 +179,8 @@ endif()
|
|||||||
|
|
||||||
if (UNIX)
|
if (UNIX)
|
||||||
install( TARGETS uhub RUNTIME DESTINATION bin )
|
install( TARGETS uhub RUNTIME DESTINATION bin )
|
||||||
install( TARGETS mod_example mod_welcome mod_logging mod_auth_simple mod_auth_sqlite mod_chat_history mod_chat_only mod_topic DESTINATION /var/lib/uhub/ OPTIONAL )
|
install( TARGETS mod_example mod_welcome mod_logging mod_auth_simple mod_auth_sqlite mod_chat_history mod_chat_only mod_topic DESTINATION /usr/lib/uhub/ OPTIONAL )
|
||||||
install( FILES ${CMAKE_SOURCE_DIR}/uhub.conf ${CMAKE_SOURCE_DIR}/plugins.conf ${CMAKE_SOURCE_DIR}/rules.txt ${CMAKE_SOURCE_DIR}/motd.txt DESTINATION /etc/uhub OPTIONAL )
|
install( FILES ${CMAKE_SOURCE_DIR}/doc/uhub.conf ${CMAKE_SOURCE_DIR}/doc/plugins.conf ${CMAKE_SOURCE_DIR}/doc/rules.txt ${CMAKE_SOURCE_DIR}/doc/motd.txt DESTINATION /etc/uhub OPTIONAL )
|
||||||
|
|
||||||
if (SQLITE_SUPPORT)
|
if (SQLITE_SUPPORT)
|
||||||
install( TARGETS uhub-passwd RUNTIME DESTINATION bin )
|
install( TARGETS uhub-passwd RUNTIME DESTINATION bin )
|
||||||
@@ -209,6 +188,3 @@ if (UNIX)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
# Parameters:
|
# Parameters:
|
||||||
# file: path/filename for database.
|
# file: path/filename for database.
|
||||||
#
|
#
|
||||||
plugin /var/lib/uhub/mod_auth_sqlite.so "file=/etc/uhub/users.db"
|
plugin /usr/lib/uhub/mod_auth_sqlite.so "file=/etc/uhub/users.db"
|
||||||
|
|
||||||
|
|
||||||
# Log file writer
|
# Log file writer
|
||||||
@@ -19,10 +19,10 @@ plugin /var/lib/uhub/mod_auth_sqlite.so "file=/etc/uhub/users.db"
|
|||||||
# Parameters:
|
# Parameters:
|
||||||
# file: path/filename for log file.
|
# file: path/filename for log file.
|
||||||
# syslog: if true then syslog is used instead of writing to a file (Unix only)
|
# syslog: if true then syslog is used instead of writing to a file (Unix only)
|
||||||
plugin /var/lib/uhub/mod_logging.so "file=/var/log/uhub.log"
|
plugin /usr/lib/uhub/mod_logging.so "file=/var/log/uhub.log"
|
||||||
|
|
||||||
# A simple example plugin
|
# A simple example plugin
|
||||||
# plugin /var/lib/uhub/mod_example.so
|
# plugin /usr/lib/uhub/mod_example.so
|
||||||
# A plugin sending a welcome message.
|
# A plugin sending a welcome message.
|
||||||
#
|
#
|
||||||
# This plugin provides the following commands:
|
# This plugin provides the following commands:
|
||||||
@@ -46,7 +46,7 @@ plugin /var/lib/uhub/mod_logging.so "file=/var/log/uhub.log"
|
|||||||
# %p - 'am' or 'pm'
|
# %p - 'am' or 'pm'
|
||||||
# %M - Minutes (00-59) (Hub local time)
|
# %M - Minutes (00-59) (Hub local time)
|
||||||
# %S - Seconds (00-60) (Hub local time)
|
# %S - Seconds (00-60) (Hub local time)
|
||||||
plugin /var/lib/uhub/mod_welcome.so "motd=/etc/uhub/motd.txt rules=/etc/uhub/rules.txt"
|
plugin /usr/lib/uhub/mod_welcome.so "motd=/etc/uhub/motd.txt rules=/etc/uhub/rules.txt"
|
||||||
|
|
||||||
# Load the chat history plugin.
|
# Load the chat history plugin.
|
||||||
#
|
#
|
||||||
@@ -58,5 +58,5 @@ plugin /var/lib/uhub/mod_welcome.so "motd=/etc/uhub/motd.txt rules=/etc/uhub/rul
|
|||||||
# history_max: the maximum number of messages to keep in history
|
# history_max: the maximum number of messages to keep in history
|
||||||
# history_default: when !history is provided without arguments, then this default number of messages are returned.
|
# history_default: when !history is provided without arguments, then this default number of messages are returned.
|
||||||
# history_connect: the number of chat history messages to send when users connect (0 = do not send any history)
|
# history_connect: the number of chat history messages to send when users connect (0 = do not send any history)
|
||||||
plugin /var/lib/uhub/mod_chat_history.so "history_max=200 history_default=10 history_connect=5"
|
plugin /usr/lib/uhub/mod_chat_history.so "history_max=200 history_default=10 history_connect=5"
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ mkdir -p $RPM_BUILD_ROOT/etc/init.d
|
|||||||
mkdir -p $RPM_BUILD_ROOT/etc/logrotate.d
|
mkdir -p $RPM_BUILD_ROOT/etc/logrotate.d
|
||||||
mkdir -p $RPM_BUILD_ROOT/etc/sysconfig
|
mkdir -p $RPM_BUILD_ROOT/etc/sysconfig
|
||||||
mkdir -p $RPM_BUILD_ROOT/usr/share/man/man1
|
mkdir -p $RPM_BUILD_ROOT/usr/share/man/man1
|
||||||
mkdir -p $RPM_BUILD_ROOT/var/lib/uhub
|
mkdir -p $RPM_BUILD_ROOT/usr/lib/uhub
|
||||||
|
|
||||||
install uhub $RPM_BUILD_ROOT/usr/bin/
|
install uhub $RPM_BUILD_ROOT/usr/bin/
|
||||||
install uhub-passwd $RPM_BUILD_ROOT/usr/bin/
|
install uhub-passwd $RPM_BUILD_ROOT/usr/bin/
|
||||||
@@ -52,7 +52,7 @@ install -m644 doc/init.d.RedHat/etc/sysconfig/uhub $RPM_BUILD_ROOT/etc/sysconfi
|
|||||||
install -m644 doc/init.d.RedHat/etc/logrotate.d/uhub $RPM_BUILD_ROOT/etc/logrotate.d/
|
install -m644 doc/init.d.RedHat/etc/logrotate.d/uhub $RPM_BUILD_ROOT/etc/logrotate.d/
|
||||||
/bin/gzip -9c doc/uhub.1 > doc/uhub.1.gz &&
|
/bin/gzip -9c doc/uhub.1 > doc/uhub.1.gz &&
|
||||||
install -m644 doc/uhub.1.gz $RPM_BUILD_ROOT/usr/share/man/man1
|
install -m644 doc/uhub.1.gz $RPM_BUILD_ROOT/usr/share/man/man1
|
||||||
install -m644 mod_*.so $RPM_BUILD_ROOT/var/lib/uhub
|
install -m644 mod_*.so $RPM_BUILD_ROOT/usr/lib/uhub
|
||||||
|
|
||||||
|
|
||||||
%files
|
%files
|
||||||
|
|||||||
@@ -136,7 +136,13 @@ int main_loop()
|
|||||||
{
|
{
|
||||||
hub = hub_start_service(&configuration);
|
hub = hub_start_service(&configuration);
|
||||||
if (!hub)
|
if (!hub)
|
||||||
|
{
|
||||||
|
acl_shutdown(&acl);
|
||||||
|
free_config(&configuration);
|
||||||
|
net_destroy();
|
||||||
|
hub_log_shutdown();
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
#if !defined(WIN32)
|
#if !defined(WIN32)
|
||||||
setup_signal_handlers(hub);
|
setup_signal_handlers(hub);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -146,6 +146,9 @@ int net_backend_process()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Process pending DNS results
|
||||||
|
net_dns_process();
|
||||||
|
|
||||||
g_backend->handler.backend_process(g_backend->data, res);
|
g_backend->handler.backend_process(g_backend->data, res);
|
||||||
|
|
||||||
net_cleanup_process(g_backend->cleaner);
|
net_cleanup_process(g_backend->cleaner);
|
||||||
|
|||||||
@@ -20,11 +20,6 @@
|
|||||||
#include "uhub.h"
|
#include "uhub.h"
|
||||||
#include "network/common.h"
|
#include "network/common.h"
|
||||||
|
|
||||||
#ifdef SSL_SUPPORT
|
|
||||||
void net_stats_add_tx(size_t bytes);
|
|
||||||
void net_stats_add_rx(size_t bytes);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int is_blocked_or_interrupted()
|
static int is_blocked_or_interrupted()
|
||||||
{
|
{
|
||||||
int err = net_error();
|
int err = net_error();
|
||||||
|
|||||||
386
src/network/dnsresolver.c
Normal file
386
src/network/dnsresolver.c
Normal file
@@ -0,0 +1,386 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* 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
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uhub.h"
|
||||||
|
|
||||||
|
static struct net_dns_job* find_and_remove_job(struct net_dns_job* job);
|
||||||
|
static struct net_dns_result* find_and_remove_result(struct net_dns_job* job);
|
||||||
|
|
||||||
|
struct net_dns_job
|
||||||
|
{
|
||||||
|
net_dns_job_cb callback;
|
||||||
|
void* ptr;
|
||||||
|
|
||||||
|
char* host;
|
||||||
|
int af;
|
||||||
|
|
||||||
|
#ifdef DEBUG_LOOKUP_TIME
|
||||||
|
struct timeval time_start;
|
||||||
|
struct timeval time_finish;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uhub_thread_t* thread_handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct net_dns_result
|
||||||
|
{
|
||||||
|
struct linked_list* addr_list;
|
||||||
|
struct net_dns_job* job;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void free_job(struct net_dns_job* job)
|
||||||
|
{
|
||||||
|
if (job)
|
||||||
|
{
|
||||||
|
hub_free(job->host);
|
||||||
|
hub_free(job);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void shutdown_free_jobs(void* ptr)
|
||||||
|
{
|
||||||
|
struct net_dns_job* job = (struct net_dns_job*) ptr;
|
||||||
|
uhub_thread_cancel(job->thread_handle);
|
||||||
|
uhub_thread_join(job->thread_handle);
|
||||||
|
free_job(job);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void shutdown_free_results(void* ptr)
|
||||||
|
{
|
||||||
|
struct net_dns_result* result = (struct net_dns_result*) ptr;
|
||||||
|
uhub_thread_join(result->job->thread_handle);
|
||||||
|
net_dns_result_free(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// NOTE: Any job manipulating the members of this
|
||||||
|
// struct must lock the mutex!
|
||||||
|
struct net_dns_subsystem
|
||||||
|
{
|
||||||
|
struct linked_list* jobs; // currently running jobs
|
||||||
|
struct linked_list* results; // queue of results that are awaiting being delivered to callback.
|
||||||
|
uhub_mutex_t mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct net_dns_subsystem* g_dns = NULL;
|
||||||
|
|
||||||
|
void net_dns_initialize()
|
||||||
|
{
|
||||||
|
LOG_TRACE("net_dns_initialize()");
|
||||||
|
g_dns = (struct net_dns_subsystem*) hub_malloc_zero(sizeof(struct net_dns_subsystem));
|
||||||
|
g_dns->jobs = list_create();
|
||||||
|
g_dns->results = list_create();
|
||||||
|
uhub_mutex_init(&g_dns->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void net_dns_destroy()
|
||||||
|
{
|
||||||
|
struct net_dns_job* job;
|
||||||
|
struct net_dns_result* result;
|
||||||
|
|
||||||
|
uhub_mutex_lock(&g_dns->mutex);
|
||||||
|
LOG_TRACE("net_dns_destroy(): jobs=%d", (int) list_size(g_dns->jobs));
|
||||||
|
list_clear(g_dns->jobs, &shutdown_free_jobs);
|
||||||
|
|
||||||
|
LOG_TRACE("net_dns_destroy(): results=%d", (int) list_size(g_dns->results));
|
||||||
|
list_clear(g_dns->results, &shutdown_free_results);
|
||||||
|
uhub_mutex_unlock(&g_dns->mutex);
|
||||||
|
|
||||||
|
list_destroy(g_dns->jobs);
|
||||||
|
list_destroy(g_dns->results);
|
||||||
|
uhub_mutex_destroy(&g_dns->mutex);
|
||||||
|
hub_free(g_dns);
|
||||||
|
g_dns = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dummy_free(void* ptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void net_dns_process()
|
||||||
|
{
|
||||||
|
struct net_dns_result* result;
|
||||||
|
uhub_mutex_lock(&g_dns->mutex);
|
||||||
|
LOG_DUMP("net_dns_process(): jobs=%d, results=%d", (int) list_size(g_dns->jobs), (int) list_size(g_dns->results));
|
||||||
|
|
||||||
|
for (result = (struct net_dns_result*) list_get_first(g_dns->results); result; result = (struct net_dns_result*) list_get_next(g_dns->results))
|
||||||
|
{
|
||||||
|
struct net_dns_job* job = result->job;
|
||||||
|
#ifdef DEBUG_LOOKUP_TIME
|
||||||
|
struct timeval time_result;
|
||||||
|
timersub(&result->job->time_finish, &result->job->time_start, &time_result);
|
||||||
|
LOG_TRACE("DNS lookup took %d ms", (time_result.tv_sec * 1000) + (time_result.tv_usec / 1000));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// wait for the work thread to finish
|
||||||
|
uhub_thread_join(job->thread_handle);
|
||||||
|
|
||||||
|
// callback - should we delete the data immediately?
|
||||||
|
if (job->callback(job, result))
|
||||||
|
{
|
||||||
|
net_dns_result_free(result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Caller wants to keep the result data, and
|
||||||
|
* thus needs to call net_dns_result_free() to release it later.
|
||||||
|
* We only clean up the job data here and keep the results intact.
|
||||||
|
*/
|
||||||
|
result->job = NULL;
|
||||||
|
free_job(job);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list_clear(g_dns->results, &dummy_free);
|
||||||
|
uhub_mutex_unlock(&g_dns->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void* job_thread_resolve_name(void* ptr)
|
||||||
|
{
|
||||||
|
struct net_dns_job* job = (struct net_dns_job*) ptr;
|
||||||
|
struct addrinfo hints, *result, *it;
|
||||||
|
struct net_dns_result* dns_results;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_family = job->af;
|
||||||
|
hints.ai_protocol = IPPROTO_TCP;
|
||||||
|
|
||||||
|
ret = getaddrinfo(job->host, NULL, &hints, &result);
|
||||||
|
if (ret != 0 && ret != EAI_NONAME)
|
||||||
|
{
|
||||||
|
LOG_TRACE("getaddrinfo() failed: %s", gai_strerror(ret));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dns_results = (struct net_dns_result*) hub_malloc(sizeof(struct net_dns_result));
|
||||||
|
dns_results->addr_list = list_create();
|
||||||
|
dns_results->job = job;
|
||||||
|
|
||||||
|
if (ret != EAI_NONAME)
|
||||||
|
{
|
||||||
|
for (it = result; it; it = it->ai_next)
|
||||||
|
{
|
||||||
|
struct ip_addr_encap* ipaddr = hub_malloc_zero(sizeof(struct ip_addr_encap));
|
||||||
|
ipaddr->af = it->ai_family;
|
||||||
|
|
||||||
|
if (it->ai_family == AF_INET)
|
||||||
|
{
|
||||||
|
struct sockaddr_in* addr4 = (struct sockaddr_in*) it->ai_addr;
|
||||||
|
memcpy(&ipaddr->internal_ip_data.in, &addr4->sin_addr, sizeof(struct in_addr));
|
||||||
|
}
|
||||||
|
else if (it->ai_family == AF_INET6)
|
||||||
|
{
|
||||||
|
struct sockaddr_in6* addr6 = (struct sockaddr_in6*) it->ai_addr;
|
||||||
|
memcpy(&ipaddr->internal_ip_data.in6, &addr6->sin6_addr, sizeof(struct in6_addr));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_TRACE("getaddrinfo() returned result with unknown address family: %d", it->ai_family);
|
||||||
|
hub_free(ipaddr);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DUMP("getaddrinfo() - Address (%d) %s for \"%s\"", ret++, ip_convert_to_string(ipaddr), job->host);
|
||||||
|
list_append(dns_results->addr_list, ipaddr);
|
||||||
|
}
|
||||||
|
freeaddrinfo(result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* hm */
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_LOOKUP_TIME
|
||||||
|
gettimeofday(&job->time_finish, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uhub_mutex_lock(&g_dns->mutex);
|
||||||
|
list_remove(g_dns->jobs, job);
|
||||||
|
list_append(g_dns->results, dns_results);
|
||||||
|
uhub_mutex_unlock(&g_dns->mutex);
|
||||||
|
|
||||||
|
return dns_results;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern struct net_dns_job* net_dns_gethostbyname(const char* host, int af, net_dns_job_cb callback, void* ptr)
|
||||||
|
{
|
||||||
|
struct net_dns_job* job = (struct net_dns_job*) hub_malloc_zero(sizeof(struct net_dns_job));
|
||||||
|
job->host = strdup(host);
|
||||||
|
job->af = af;
|
||||||
|
job->callback = callback;
|
||||||
|
job->ptr = ptr;
|
||||||
|
|
||||||
|
#ifdef DEBUG_LOOKUP_TIME
|
||||||
|
gettimeofday(&job->time_start, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// FIXME - scheduling - what about a max number of threads?
|
||||||
|
uhub_mutex_lock(&g_dns->mutex);
|
||||||
|
job->thread_handle = uhub_thread_create(job_thread_resolve_name, job);
|
||||||
|
if (!job->thread_handle)
|
||||||
|
{
|
||||||
|
LOG_WARN("Unable to create thread");
|
||||||
|
free_job(job);
|
||||||
|
job = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
list_append(g_dns->jobs, job);
|
||||||
|
}
|
||||||
|
uhub_mutex_unlock(&g_dns->mutex);
|
||||||
|
return job;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern struct net_dns_job* net_dns_gethostbyaddr(struct ip_addr_encap* ipaddr, net_dns_job_cb callback, void* ptr)
|
||||||
|
{
|
||||||
|
struct net_dns_job* job = (struct net_dns_job*) hub_malloc_zero(sizeof(struct net_dns_job));
|
||||||
|
// job->host = strdup(addr);
|
||||||
|
job->af = ipaddr->af;
|
||||||
|
job->callback = callback;
|
||||||
|
job->ptr = ptr;
|
||||||
|
|
||||||
|
|
||||||
|
// if (pthread_create(&job->thread_handle, NULL, start_job, job))
|
||||||
|
// {
|
||||||
|
// free_job(job);
|
||||||
|
// return NULL;
|
||||||
|
// }
|
||||||
|
return job;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: mutex must be locked first!
|
||||||
|
static struct net_dns_job* find_and_remove_job(struct net_dns_job* job)
|
||||||
|
{
|
||||||
|
struct net_dns_job* it;
|
||||||
|
for (it = (struct net_dns_job*) list_get_first(g_dns->jobs); it; it = (struct net_dns_job*) list_get_next(g_dns->jobs))
|
||||||
|
{
|
||||||
|
if (it == job)
|
||||||
|
{
|
||||||
|
list_remove(g_dns->jobs, it);
|
||||||
|
return job;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: mutex must be locked first!
|
||||||
|
static struct net_dns_result* find_and_remove_result(struct net_dns_job* job)
|
||||||
|
{
|
||||||
|
struct net_dns_result* it;
|
||||||
|
for (it = (struct net_dns_result*) list_get_first(g_dns->results); it; it = (struct net_dns_result*) list_get_next(g_dns->results))
|
||||||
|
{
|
||||||
|
if (it->job == job)
|
||||||
|
{
|
||||||
|
list_remove(g_dns->results, it);
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern int net_dns_job_cancel(struct net_dns_job* job)
|
||||||
|
{
|
||||||
|
int retval = 0;
|
||||||
|
struct net_dns_result* res;
|
||||||
|
|
||||||
|
LOG_TRACE("net_dns_job_cancel(): job=%p, name=%s", job, job->host);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function looks up the job in the jobs queue (which contains only active jobs)
|
||||||
|
* If that is found then the thread is cancelled, and the object is deleted.
|
||||||
|
* If the job was not found, that is either because it was an invalid job, or because
|
||||||
|
* it was already finished. At which point it was not deleted.
|
||||||
|
* If the job is already finished, but the result has not been delivered, then this
|
||||||
|
* deletes the result and the job.
|
||||||
|
*/
|
||||||
|
uhub_mutex_lock(&g_dns->mutex);
|
||||||
|
if (find_and_remove_job(job))
|
||||||
|
{
|
||||||
|
// job still active - cancel it, then close it.
|
||||||
|
uhub_thread_cancel(job->thread_handle);
|
||||||
|
uhub_thread_join(job->thread_handle);
|
||||||
|
free_job(job);
|
||||||
|
retval = 1;
|
||||||
|
}
|
||||||
|
else if ((res = find_and_remove_result(job)))
|
||||||
|
{
|
||||||
|
// job already finished - close it.
|
||||||
|
uhub_thread_join(job->thread_handle);
|
||||||
|
net_dns_result_free(res);
|
||||||
|
}
|
||||||
|
uhub_mutex_unlock(&g_dns->mutex);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern struct net_dns_result* net_dns_job_sync_wait(struct net_dns_job* job)
|
||||||
|
{
|
||||||
|
struct net_dns_result* res = NULL;
|
||||||
|
|
||||||
|
// Wait for job to finish (if not already)
|
||||||
|
// This should make sure the job is removed from jobs and a result is
|
||||||
|
// present in results.
|
||||||
|
uhub_thread_join(job->thread_handle);
|
||||||
|
|
||||||
|
// Remove the result in order to prevent the callback from being called.
|
||||||
|
uhub_mutex_lock(&g_dns->mutex);
|
||||||
|
res = find_and_remove_result(job);
|
||||||
|
uhub_assert(res != NULL);
|
||||||
|
res->job = NULL;
|
||||||
|
free_job(job);
|
||||||
|
uhub_mutex_unlock(&g_dns->mutex);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* net_dns_job_get_ptr(const struct net_dns_job* job)
|
||||||
|
{
|
||||||
|
return job->ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern size_t net_dns_result_size(const struct net_dns_result* res)
|
||||||
|
{
|
||||||
|
return list_size(res->addr_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern struct ip_addr_encap* net_dns_result_first(const struct net_dns_result* res)
|
||||||
|
{
|
||||||
|
struct ip_addr_encap* ipaddr = list_get_first(res->addr_list);
|
||||||
|
LOG_TRACE("net_dns_result_first() - Address: %s", ip_convert_to_string(ipaddr));
|
||||||
|
return ipaddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern struct ip_addr_encap* net_dns_result_next(const struct net_dns_result* res)
|
||||||
|
{
|
||||||
|
struct ip_addr_encap* ipaddr = list_get_next(res->addr_list);
|
||||||
|
LOG_TRACE("net_dns_result_next() - Address: %s", ip_convert_to_string(ipaddr));
|
||||||
|
return ipaddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void net_dns_result_free(struct net_dns_result* res)
|
||||||
|
{
|
||||||
|
list_clear(res->addr_list, &hub_free);
|
||||||
|
list_destroy(res->addr_list);
|
||||||
|
free_job(res->job);
|
||||||
|
hub_free(res);
|
||||||
|
}
|
||||||
119
src/network/dnsresolver.h
Normal file
119
src/network/dnsresolver.h
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* Copyright (C) 2007-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
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HAVE_UHUB_NETWORK_DNS_RESOLVER_H
|
||||||
|
#define HAVE_UHUB_NETWORK_DNS_RESOLVER_H
|
||||||
|
|
||||||
|
struct net_dns_job;
|
||||||
|
struct net_dns_result;
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/// Initialize the DNS subsystem
|
||||||
|
void net_dns_initialize();
|
||||||
|
|
||||||
|
/// Shutdown and destroy the DNS subsystem. This will cancel any pending DNS jobs.
|
||||||
|
void net_dns_destroy();
|
||||||
|
|
||||||
|
/// Process finished DNS lookups.
|
||||||
|
void net_dns_process();
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to be called when the DNS job has finished.
|
||||||
|
* If the name or address could not be resolved to an IP address (host not found, or found but has no address)
|
||||||
|
* then 'result' contains an empty list (@see net_dns_result_size()).
|
||||||
|
* If resolving caused an error then result is NULL.
|
||||||
|
*
|
||||||
|
* After this callback is called the job is considered done, and is freed.
|
||||||
|
*
|
||||||
|
* @param If 1 is returned then result is deleted immediately after the callback,
|
||||||
|
* otherwise the callback becomes owner of the result data which must be freed with net_dns_result_free().
|
||||||
|
*/
|
||||||
|
typedef int (*net_dns_job_cb)(struct net_dns_job*, const struct net_dns_result* result);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve a hostname.
|
||||||
|
*
|
||||||
|
* @param host the hostname to be resolved.
|
||||||
|
* @param af the indicated address family. Should be AF_INET, AF_INET6 (or AF_UNSPEC - which means both AF_INET and AF_INET6.
|
||||||
|
* @param callback the callback to be called when the hostname has been resolved.
|
||||||
|
* @param ptr A user-defined pointer value.
|
||||||
|
*
|
||||||
|
* @return A resolve job handle if the job has successfully started or NULL if unable to start resolving.
|
||||||
|
*/
|
||||||
|
extern struct net_dns_job* net_dns_gethostbyname(const char* host, int af, net_dns_job_cb callback, void* ptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform a reverse DNS lookup for a given IP address.
|
||||||
|
*
|
||||||
|
* @see net_dns_gethostbyname()
|
||||||
|
* @return A resolve job handle if the job has successfully started or NULL if unable to start resolving.
|
||||||
|
*/
|
||||||
|
extern struct net_dns_job* net_dns_gethostbyaddr(struct ip_addr_encap* ipaddr, net_dns_job_cb callback, void* ptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel a DNS lookup job.
|
||||||
|
*
|
||||||
|
* It is only allowed to call this once after a job has been started (@see net_dns_gethostbyname(), @see net_dns_gethostbyaddr())
|
||||||
|
* but before it has finished and delivered a to the callback address (@see net_dns_job_cb).
|
||||||
|
*
|
||||||
|
* @returns 1 if cancelled, or 0 if not cancelled (because the job was not found!)
|
||||||
|
*/
|
||||||
|
extern int net_dns_job_cancel(struct net_dns_job* job);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait in a synchronous manner for a running DNS job to finished and
|
||||||
|
* return the result here.
|
||||||
|
* The job must be started with net_dns_gethostbyaddr/net_dns_gethostbyname
|
||||||
|
* and not finished or cancelled.
|
||||||
|
*
|
||||||
|
* If this function is invoked then the callback function will not be called and
|
||||||
|
* can therefore be NULL.
|
||||||
|
*
|
||||||
|
* <code>
|
||||||
|
* struct net_dns_job* job = net_dns_gethostbyname("www.example.com", AF_INET, NULL, NULL);
|
||||||
|
* struct net_dns_result* net_dns_job_sync_wait(job);
|
||||||
|
* </code>
|
||||||
|
*/
|
||||||
|
extern struct net_dns_result* net_dns_job_sync_wait(struct net_dns_job* job);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the user specified pointer assigned to the resolving job
|
||||||
|
*/
|
||||||
|
extern void* net_dns_job_get_ptr(const struct net_dns_job* job);
|
||||||
|
|
||||||
|
/// Returns the number of results provided. This is 0 if the host could not be found (or has no matching IP address).
|
||||||
|
extern size_t net_dns_result_size(const struct net_dns_result*);
|
||||||
|
|
||||||
|
/// Returns the first result (if net_dns_result_size > 0), or NULL if not first result exists.
|
||||||
|
extern struct ip_addr_encap* net_dns_result_first(const struct net_dns_result*);
|
||||||
|
|
||||||
|
/// Returns the next result or NULL if no next result exists.
|
||||||
|
extern struct ip_addr_encap* net_dns_result_next(const struct net_dns_result*);
|
||||||
|
|
||||||
|
/// When finished with the results
|
||||||
|
extern void net_dns_result_free(struct net_dns_result*);
|
||||||
|
|
||||||
|
#endif /* HAVE_UHUB_NETWORK_DNS_RESOLVER_H */
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -49,23 +49,21 @@ int net_initialize()
|
|||||||
}
|
}
|
||||||
#endif /* WINSOCK */
|
#endif /* WINSOCK */
|
||||||
|
|
||||||
if (!net_backend_init())
|
if (!net_backend_init()
|
||||||
|
#ifdef SSL_SUPPORT
|
||||||
|
|| !net_ssl_library_init()
|
||||||
|
#endif
|
||||||
|
)
|
||||||
{
|
{
|
||||||
#ifdef WINSOCK
|
#ifdef WINSOCK
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
#endif
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
net_dns_initialize();
|
||||||
|
|
||||||
net_stats_initialize();
|
net_stats_initialize();
|
||||||
|
|
||||||
#ifdef SSL_SUPPORT
|
|
||||||
#ifdef SSL_USE_OPENSSL
|
|
||||||
LOG_TRACE("Initializing OpenSSL...");
|
|
||||||
SSL_library_init();
|
|
||||||
SSL_load_error_strings();
|
|
||||||
#endif /* SSL_USE_OPENSSL */
|
|
||||||
#endif /* SSL_SUPPORT */
|
|
||||||
|
|
||||||
net_initialized = 1;
|
net_initialized = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -99,14 +97,12 @@ int net_destroy()
|
|||||||
{
|
{
|
||||||
LOG_TRACE("Shutting down network monitor");
|
LOG_TRACE("Shutting down network monitor");
|
||||||
|
|
||||||
|
net_dns_destroy();
|
||||||
|
|
||||||
net_backend_shutdown();
|
net_backend_shutdown();
|
||||||
|
|
||||||
#ifdef SSL_SUPPORT
|
#ifdef SSL_SUPPORT
|
||||||
#ifdef SSL_USE_OPENSSL
|
net_ssl_library_shutdown();
|
||||||
ERR_free_strings();
|
|
||||||
EVP_cleanup();
|
|
||||||
CRYPTO_cleanup_all_ex_data();
|
|
||||||
#endif /* SSL_USE_OPENSSL */
|
|
||||||
#endif /* SSL_SUPPORT */
|
#endif /* SSL_SUPPORT */
|
||||||
|
|
||||||
#ifdef WINSOCK
|
#ifdef WINSOCK
|
||||||
@@ -499,7 +495,6 @@ int net_socket_create(int af, int type, int protocol)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return sd;
|
return sd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* uhub - A tiny ADC p2p connection hub
|
* uhub - A tiny ADC p2p connection hub
|
||||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
* Copyright (C) 2007-2012, Jan Vidar Krey
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -24,15 +24,17 @@
|
|||||||
#ifdef SSL_SUPPORT
|
#ifdef SSL_SUPPORT
|
||||||
#ifdef SSL_USE_OPENSSL
|
#ifdef SSL_USE_OPENSSL
|
||||||
|
|
||||||
#define NETWORK_DUMP_DEBUG
|
void net_stats_add_tx(size_t bytes);
|
||||||
|
void net_stats_add_rx(size_t bytes);
|
||||||
|
|
||||||
struct net_ssl_openssl
|
struct net_ssl_openssl
|
||||||
{
|
{
|
||||||
SSL* ssl;
|
SSL* ssl;
|
||||||
|
BIO* bio;
|
||||||
enum ssl_state state;
|
enum ssl_state state;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
BIO* biow;
|
size_t bytes_rx;
|
||||||
BIO* bior;
|
size_t bytes_tx;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct net_context_openssl
|
struct net_context_openssl
|
||||||
@@ -52,6 +54,44 @@ const char* net_ssl_get_provider()
|
|||||||
return OPENSSL_VERSION_TEXT;
|
return OPENSSL_VERSION_TEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int net_ssl_library_init()
|
||||||
|
{
|
||||||
|
LOG_TRACE("Initializing OpenSSL...");
|
||||||
|
SSL_library_init();
|
||||||
|
SSL_load_error_strings();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int net_ssl_library_shutdown()
|
||||||
|
{
|
||||||
|
ERR_clear_error();
|
||||||
|
ERR_remove_state(0);
|
||||||
|
|
||||||
|
ENGINE_cleanup();
|
||||||
|
CONF_modules_unload(1);
|
||||||
|
|
||||||
|
ERR_free_strings();
|
||||||
|
EVP_cleanup();
|
||||||
|
CRYPTO_cleanup_all_ex_data();
|
||||||
|
|
||||||
|
// sk_SSL_COMP_free(SSL_COMP_get_compression_methods());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_io_stats(struct net_ssl_openssl* handle)
|
||||||
|
{
|
||||||
|
if (handle->bio->num_read > handle->bytes_rx)
|
||||||
|
{
|
||||||
|
net_stats_add_rx(handle->bio->num_read - handle->bytes_rx);
|
||||||
|
handle->bytes_rx = handle->bio->num_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handle->bio->num_write > handle->bytes_tx)
|
||||||
|
{
|
||||||
|
net_stats_add_tx(handle->bio->num_write - handle->bytes_tx);
|
||||||
|
handle->bytes_tx = handle->bio->num_write;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new SSL context.
|
* Create a new SSL context.
|
||||||
@@ -161,9 +201,7 @@ ssize_t net_con_ssl_connect(struct net_connection* con)
|
|||||||
handle->state = tls_st_connecting;
|
handle->state = tls_st_connecting;
|
||||||
|
|
||||||
ret = SSL_connect(handle->ssl);
|
ret = SSL_connect(handle->ssl);
|
||||||
#ifdef NETWORK_DUMP_DEBUG
|
|
||||||
LOG_PROTO("SSL_connect() ret=%d", ret);
|
LOG_PROTO("SSL_connect() ret=%d", ret);
|
||||||
#endif /* NETWORK_DUMP_DEBUG */
|
|
||||||
|
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
{
|
{
|
||||||
@@ -190,8 +228,7 @@ ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
SSL_set_fd(handle->ssl, con->sd);
|
SSL_set_fd(handle->ssl, con->sd);
|
||||||
handle->bior = SSL_get_rbio(handle->ssl);
|
handle->bio = SSL_get_rbio(handle->ssl);
|
||||||
handle->biow = SSL_get_wbio(handle->ssl);
|
|
||||||
con->ssl = (struct ssl_handle*) handle;
|
con->ssl = (struct ssl_handle*) handle;
|
||||||
return net_con_ssl_accept(con);
|
return net_con_ssl_accept(con);
|
||||||
}
|
}
|
||||||
@@ -199,8 +236,7 @@ ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode
|
|||||||
{
|
{
|
||||||
handle->ssl = SSL_new(SSL_CTX_new(TLSv1_method()));
|
handle->ssl = SSL_new(SSL_CTX_new(TLSv1_method()));
|
||||||
SSL_set_fd(handle->ssl, con->sd);
|
SSL_set_fd(handle->ssl, con->sd);
|
||||||
handle->bior = SSL_get_rbio(handle->ssl);
|
handle->bio = SSL_get_rbio(handle->ssl);
|
||||||
handle->biow = SSL_get_wbio(handle->ssl);
|
|
||||||
con->ssl = (struct ssl_handle*) handle;
|
con->ssl = (struct ssl_handle*) handle;
|
||||||
return net_con_ssl_connect(con);
|
return net_con_ssl_connect(con);
|
||||||
}
|
}
|
||||||
@@ -215,6 +251,7 @@ ssize_t net_ssl_send(struct net_connection* con, const void* buf, size_t len)
|
|||||||
|
|
||||||
ERR_clear_error();
|
ERR_clear_error();
|
||||||
ssize_t ret = SSL_write(handle->ssl, buf, len);
|
ssize_t ret = SSL_write(handle->ssl, buf, len);
|
||||||
|
add_io_stats(handle);
|
||||||
LOG_PROTO("SSL_write(con=%p, buf=%p, len=" PRINTF_SIZE_T ") => %d", con, buf, len, ret);
|
LOG_PROTO("SSL_write(con=%p, buf=%p, len=" PRINTF_SIZE_T ") => %d", con, buf, len, ret);
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
{
|
{
|
||||||
@@ -237,6 +274,7 @@ ssize_t net_ssl_recv(struct net_connection* con, void* buf, size_t len)
|
|||||||
ERR_clear_error();
|
ERR_clear_error();
|
||||||
|
|
||||||
ret = SSL_read(handle->ssl, buf, len);
|
ret = SSL_read(handle->ssl, buf, len);
|
||||||
|
add_io_stats(handle);
|
||||||
LOG_PROTO("SSL_read(con=%p, buf=%p, len=" PRINTF_SIZE_T ") => %d", con, buf, len, ret);
|
LOG_PROTO("SSL_read(con=%p, buf=%p, len=" PRINTF_SIZE_T ") => %d", con, buf, len, ret);
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
{
|
{
|
||||||
@@ -302,4 +340,5 @@ void net_ssl_callback(struct net_connection* con, int events)
|
|||||||
|
|
||||||
|
|
||||||
#endif /* SSL_USE_OPENSSL */
|
#endif /* SSL_USE_OPENSSL */
|
||||||
#endif /* SSL_SUPPORT */
|
#endif /* SSL_SUPPORT */
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,12 @@ struct ssl_context_handle;
|
|||||||
*/
|
*/
|
||||||
extern const char* net_ssl_get_provider();
|
extern const char* net_ssl_get_provider();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return 0 if error, 1 on success.
|
||||||
|
*/
|
||||||
|
extern int net_ssl_library_init();
|
||||||
|
extern int net_ssl_library_shutdown();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new SSL context.
|
* Create a new SSL context.
|
||||||
*/
|
*/
|
||||||
@@ -91,11 +97,8 @@ extern void net_ssl_callback(struct net_connection* con, int events);
|
|||||||
|
|
||||||
|
|
||||||
extern ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode, struct ssl_context_handle* ssl_ctx);
|
extern ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode, struct ssl_context_handle* ssl_ctx);
|
||||||
extern SSL* net_con_get_ssl(struct net_connection* con);
|
|
||||||
#ifdef SSL_USE_OPENSSL
|
|
||||||
extern void net_con_set_ssl(struct net_connection* con, SSL*);
|
|
||||||
#endif // SSL_USE_OPENSSL
|
|
||||||
extern int net_con_is_ssl(struct net_connection* con);
|
extern int net_con_is_ssl(struct net_connection* con);
|
||||||
|
|
||||||
#endif /* SSL_SUPPORT */
|
#endif /* SSL_SUPPORT */
|
||||||
#endif /* HAVE_UHUB_NETWORK_TLS_H */
|
#endif /* HAVE_UHUB_NETWORK_TLS_H */
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#ifndef WINSOCK
|
#ifndef WINSOCK
|
||||||
#define WINSOCK
|
#define WINSOCK
|
||||||
#endif
|
#endif
|
||||||
|
#define WINTHREAD_SUPPORT 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__CYGWIN__) || defined(__MINGW32__)
|
#if defined(__CYGWIN__) || defined(__MINGW32__)
|
||||||
@@ -113,11 +114,13 @@
|
|||||||
#define uhub_assert assert
|
#define uhub_assert assert
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|
#define POSIX_THREAD_SUPPORT
|
||||||
#define USE_EPOLL
|
#define USE_EPOLL
|
||||||
#include <sys/epoll.h>
|
#include <sys/epoll.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BSD_LIKE
|
#ifdef BSD_LIKE
|
||||||
|
#define POSIX_THREAD_SUPPORT
|
||||||
/*
|
/*
|
||||||
#define USE_KQUEUE
|
#define USE_KQUEUE
|
||||||
#include <sys/event.h>
|
#include <sys/event.h>
|
||||||
@@ -129,7 +132,7 @@
|
|||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(BSD_LIKE) || defined(__sun__)
|
#if ( defined(BSD_LIKE) && !defined(__FreeBSD_kernel__) ) || defined(__sun__)
|
||||||
#undef HAVE_STRNDUP
|
#undef HAVE_STRNDUP
|
||||||
#undef HAVE_MEMMEM
|
#undef HAVE_MEMMEM
|
||||||
#endif
|
#endif
|
||||||
@@ -279,6 +282,10 @@ typedef unsigned __int64 uint64_t;
|
|||||||
#define NEED_GETOPT
|
#define NEED_GETOPT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef POSIX_THREAD_SUPPORT
|
||||||
|
#include <pthread.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(_MSC_VER)
|
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(_MSC_VER)
|
||||||
#define PLUGIN_API __declspec(dllexport)
|
#define PLUGIN_API __declspec(dllexport)
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
enum ADC_client_state
|
enum ADC_client_state
|
||||||
{
|
{
|
||||||
ps_none, /* Not connected */
|
ps_none, /* Not connected */
|
||||||
|
ps_dns, /* looking up name */
|
||||||
ps_conn, /* Connecting... */
|
ps_conn, /* Connecting... */
|
||||||
ps_conn_ssl, /* SSL handshake */
|
ps_conn_ssl, /* SSL handshake */
|
||||||
ps_protocol, /* Have sent HSUP */
|
ps_protocol, /* Have sent HSUP */
|
||||||
@@ -46,6 +47,13 @@ enum ADC_client_flags
|
|||||||
cflag_pipe = 4,
|
cflag_pipe = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ADC_client_address
|
||||||
|
{
|
||||||
|
enum Protocol { ADC, ADCS } protocol;
|
||||||
|
char* hostname;
|
||||||
|
uint16_t port;
|
||||||
|
};
|
||||||
|
|
||||||
struct ADC_client
|
struct ADC_client
|
||||||
{
|
{
|
||||||
sid_t sid;
|
sid_t sid;
|
||||||
@@ -59,8 +67,9 @@ struct ADC_client
|
|||||||
size_t timeout;
|
size_t timeout;
|
||||||
struct net_connection* con;
|
struct net_connection* con;
|
||||||
struct net_timer* timer;
|
struct net_timer* timer;
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_storage addr;
|
||||||
char* hub_address;
|
struct net_dns_job* dns_job;
|
||||||
|
struct ADC_client_address address;
|
||||||
char* nick;
|
char* nick;
|
||||||
char* desc;
|
char* desc;
|
||||||
int flags;
|
int flags;
|
||||||
@@ -100,6 +109,7 @@ static void ADC_client_debug(struct ADC_client* client, const char* format, ...)
|
|||||||
static const char* ADC_client_state_string[] =
|
static const char* ADC_client_state_string[] =
|
||||||
{
|
{
|
||||||
"ps_none",
|
"ps_none",
|
||||||
|
"ps_dns",
|
||||||
"ps_conn",
|
"ps_conn",
|
||||||
"ps_conn_ssl",
|
"ps_conn_ssl",
|
||||||
"ps_protocol",
|
"ps_protocol",
|
||||||
@@ -154,6 +164,9 @@ static void event_callback(struct net_connection* con, int events, void *arg)
|
|||||||
|
|
||||||
switch (client->state)
|
switch (client->state)
|
||||||
{
|
{
|
||||||
|
case ps_dns:
|
||||||
|
break;
|
||||||
|
|
||||||
case ps_conn:
|
case ps_conn:
|
||||||
if (events == NET_EVENT_TIMEOUT)
|
if (events == NET_EVENT_TIMEOUT)
|
||||||
{
|
{
|
||||||
@@ -162,7 +175,7 @@ static void event_callback(struct net_connection* con, int events, void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (events & NET_EVENT_WRITE)
|
if (events & NET_EVENT_WRITE)
|
||||||
ADC_client_connect(client, 0);
|
ADC_client_connect_internal(client);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef SSL_SUPPORT
|
#ifdef SSL_SUPPORT
|
||||||
@@ -493,7 +506,8 @@ void ADC_client_send(struct ADC_client* client, struct adc_message* msg)
|
|||||||
void ADC_client_send_info(struct ADC_client* client)
|
void ADC_client_send_info(struct ADC_client* client)
|
||||||
{
|
{
|
||||||
ADC_TRACE;
|
ADC_TRACE;
|
||||||
client->info = adc_msg_construct_source(ADC_CMD_BINF, client->sid, 64);
|
client->info = adc_msg_construct_source(ADC_CMD_BINF, client->sid, 96);
|
||||||
|
|
||||||
|
|
||||||
adc_msg_add_named_argument_string(client->info, ADC_INF_FLAG_NICK, client->nick);
|
adc_msg_add_named_argument_string(client->info, ADC_INF_FLAG_NICK, client->nick);
|
||||||
|
|
||||||
@@ -502,9 +516,20 @@ void ADC_client_send_info(struct ADC_client* client)
|
|||||||
adc_msg_add_named_argument_string(client->info, ADC_INF_FLAG_DESCRIPTION, client->desc);
|
adc_msg_add_named_argument_string(client->info, ADC_INF_FLAG_DESCRIPTION, client->desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
adc_msg_add_named_argument_string(client->info, ADC_INF_FLAG_USER_AGENT, PRODUCT "/" VERSION);
|
adc_msg_add_named_argument_string(client->info, ADC_INF_FLAG_USER_AGENT, PRODUCT " " VERSION);
|
||||||
|
adc_msg_add_named_argument_int(client->info, ADC_INF_FLAG_UPLOAD_SLOTS, 0);
|
||||||
|
adc_msg_add_named_argument_int(client->info, ADC_INF_FLAG_SHARED_SIZE, 0);
|
||||||
|
adc_msg_add_named_argument_int(client->info, ADC_INF_FLAG_SHARED_FILES, 0);
|
||||||
|
|
||||||
|
adc_msg_add_named_argument_int(client->info, ADC_INF_FLAG_COUNT_HUB_NORMAL, 1);
|
||||||
|
adc_msg_add_named_argument_int(client->info, ADC_INF_FLAG_COUNT_HUB_REGISTER, 0);
|
||||||
|
adc_msg_add_named_argument_int(client->info, ADC_INF_FLAG_COUNT_HUB_OPERATOR, 0);
|
||||||
|
|
||||||
|
adc_msg_add_named_argument_int(client->info, ADC_INF_FLAG_DOWNLOAD_SPEED, 5 * 1024 * 1024);
|
||||||
|
adc_msg_add_named_argument_int(client->info, ADC_INF_FLAG_UPLOAD_SPEED, 10 * 1024 * 1024);
|
||||||
|
|
||||||
adc_cid_pid(client);
|
adc_cid_pid(client);
|
||||||
|
|
||||||
ADC_client_send(client, client->info);
|
ADC_client_send(client, client->info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -541,21 +566,34 @@ void ADC_client_destroy(struct ADC_client* client)
|
|||||||
adc_msg_free(client->info);
|
adc_msg_free(client->info);
|
||||||
hub_free(client->nick);
|
hub_free(client->nick);
|
||||||
hub_free(client->desc);
|
hub_free(client->desc);
|
||||||
hub_free(client->hub_address);
|
hub_free(client->address.hostname);
|
||||||
|
hub_free(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ADC_client_connect(struct ADC_client* client, const char* address)
|
int ADC_client_connect(struct ADC_client* client, const char* address)
|
||||||
{
|
{
|
||||||
ADC_TRACE;
|
ADC_TRACE;
|
||||||
if (!client->hub_address)
|
if (client->state == ps_none)
|
||||||
{
|
{
|
||||||
|
// Parse address and start name resolving!
|
||||||
if (!ADC_client_parse_address(client, address))
|
if (!ADC_client_parse_address(client, address))
|
||||||
return 0;
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return ADC_client_connect_internal(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ADC_client_connect_internal(struct ADC_client* client)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
if (client->state == ps_dns)
|
||||||
|
{
|
||||||
|
// Done name resolving!
|
||||||
client->callback(client, ADC_CLIENT_CONNECTING, 0);
|
client->callback(client, ADC_CLIENT_CONNECTING, 0);
|
||||||
|
ADC_client_set_state(client, ps_conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret = net_connect(net_con_get_sd(client->con), (struct sockaddr*) &client->addr, sizeof(struct sockaddr_in));
|
ret = net_connect(net_con_get_sd(client->con), (struct sockaddr*) &client->addr, sizeof(struct sockaddr_in));
|
||||||
if (ret == 0 || (ret == -1 && net_error() == EISCONN))
|
if (ret == 0 || (ret == -1 && net_error() == EISCONN))
|
||||||
{
|
{
|
||||||
ADC_client_on_connected(client);
|
ADC_client_on_connected(client);
|
||||||
@@ -588,10 +626,12 @@ static void ADC_client_on_connected(struct ADC_client* client)
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
struct adc_message* handshake = adc_msg_create(ADC_HANDSHAKE);
|
||||||
net_con_update(client->con, NET_EVENT_READ);
|
net_con_update(client->con, NET_EVENT_READ);
|
||||||
client->callback(client, ADC_CLIENT_CONNECTED, 0);
|
client->callback(client, ADC_CLIENT_CONNECTED, 0);
|
||||||
ADC_client_send(client, adc_msg_create(ADC_HANDSHAKE));
|
ADC_client_send(client, handshake);
|
||||||
ADC_client_set_state(client, ps_protocol);
|
ADC_client_set_state(client, ps_protocol);
|
||||||
|
adc_msg_free(handshake);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -599,11 +639,13 @@ static void ADC_client_on_connected(struct ADC_client* client)
|
|||||||
static void ADC_client_on_connected_ssl(struct ADC_client* client)
|
static void ADC_client_on_connected_ssl(struct ADC_client* client)
|
||||||
{
|
{
|
||||||
ADC_TRACE;
|
ADC_TRACE;
|
||||||
|
struct adc_message* handshake = adc_msg_create(ADC_HANDSHAKE);
|
||||||
client->callback(client, ADC_CLIENT_SSL_OK, 0);
|
client->callback(client, ADC_CLIENT_SSL_OK, 0);
|
||||||
client->callback(client, ADC_CLIENT_CONNECTED, 0);
|
client->callback(client, ADC_CLIENT_CONNECTED, 0);
|
||||||
net_con_update(client->con, NET_EVENT_READ);
|
net_con_update(client->con, NET_EVENT_READ);
|
||||||
ADC_client_send(client, adc_msg_create(ADC_HANDSHAKE));
|
ADC_client_send(client, handshake);
|
||||||
ADC_client_set_state(client, ps_protocol);
|
ADC_client_set_state(client, ps_protocol);
|
||||||
|
adc_msg_free(handshake);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -632,19 +674,53 @@ void ADC_client_disconnect(struct ADC_client* client)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ADC_client_dns_callback(struct net_dns_job* job, const struct net_dns_result* result)
|
||||||
|
{
|
||||||
|
struct ADC_client* client = (struct ADC_client*) net_dns_job_get_ptr(job);
|
||||||
|
struct ip_addr_encap* ipaddr;
|
||||||
|
LOG_WARN("ADC_client_dns_callback(): result=%p (%d)", result, net_dns_result_size(result));
|
||||||
|
|
||||||
|
memset(&client->addr, 0, sizeof(client->addr));
|
||||||
|
|
||||||
|
ipaddr = net_dns_result_first(result);
|
||||||
|
switch (ipaddr->af)
|
||||||
|
{
|
||||||
|
case AF_INET:
|
||||||
|
{
|
||||||
|
struct sockaddr_in* addr4 = (struct sockaddr_in*) &client->addr;
|
||||||
|
addr4->sin_family = AF_INET;
|
||||||
|
addr4->sin_port = htons(client->address.port);
|
||||||
|
memcpy(&addr4->sin_addr, &ipaddr->internal_ip_data.in, sizeof(struct in_addr));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case AF_INET6:
|
||||||
|
{
|
||||||
|
struct sockaddr_in6* addr6 = (struct sockaddr_in6*) &client->addr;
|
||||||
|
addr6->sin6_family = AF_INET6;
|
||||||
|
addr6->sin6_port = htons(client->address.port);
|
||||||
|
memcpy(&addr6->sin6_addr, &ipaddr->internal_ip_data.in6, sizeof(struct in6_addr));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
LOG_WARN("Unknown ipaddr!");
|
||||||
|
}
|
||||||
|
|
||||||
|
ADC_client_connect_internal(client);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int ADC_client_parse_address(struct ADC_client* client, const char* arg)
|
static int ADC_client_parse_address(struct ADC_client* client, const char* arg)
|
||||||
{
|
{
|
||||||
ADC_TRACE;
|
ADC_TRACE;
|
||||||
|
const char* hub_address = arg;
|
||||||
char* split;
|
char* split;
|
||||||
int ssl = 0;
|
int ssl = 0;
|
||||||
struct hostent* dns;
|
|
||||||
struct in_addr* addr;
|
|
||||||
|
|
||||||
if (!arg)
|
if (!arg)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
client->hub_address = hub_strdup(arg);
|
|
||||||
|
|
||||||
/* Minimum length of a valid address */
|
/* Minimum length of a valid address */
|
||||||
if (strlen(arg) < 9)
|
if (strlen(arg) < 9)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -653,39 +729,33 @@ static int ADC_client_parse_address(struct ADC_client* client, const char* arg)
|
|||||||
if (!strncmp(arg, "adc://", 6))
|
if (!strncmp(arg, "adc://", 6))
|
||||||
{
|
{
|
||||||
client->flags &= ~cflag_ssl;
|
client->flags &= ~cflag_ssl;
|
||||||
|
client->address.protocol = ADC;
|
||||||
}
|
}
|
||||||
else if (!strncmp(arg, "adcs://", 7))
|
else if (!strncmp(arg, "adcs://", 7))
|
||||||
{
|
{
|
||||||
client->flags |= cflag_ssl;
|
client->flags |= cflag_ssl;
|
||||||
ssl = 1;
|
ssl = 1;
|
||||||
|
client->address.protocol = ADCS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Split hostname and port (if possible) */
|
/* Split hostname and port (if possible) */
|
||||||
split = strrchr(client->hub_address + 6 + ssl, ':');
|
hub_address = arg + 6 + ssl;
|
||||||
|
split = strrchr(hub_address, ':');
|
||||||
if (split == 0 || strlen(split) < 2 || strlen(split) > 6)
|
if (split == 0 || strlen(split) < 2 || strlen(split) > 6)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Ensure port number is valid */
|
/* Ensure port number is valid */
|
||||||
int port = strtol(split+1, NULL, 10);
|
client->address.port = strtol(split+1, NULL, 10);
|
||||||
if (port <= 0 || port > 65535)
|
if (client->address.port <= 0 || client->address.port > 65535)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
split[0] = 0;
|
client->address.hostname = strndup(hub_address, &split[0] - &hub_address[0]);
|
||||||
|
|
||||||
/* Resolve IP address (FIXME: blocking call) */
|
client->callback(client, ADC_CLIENT_NAME_LOOKUP, 0);
|
||||||
dns = gethostbyname(client->hub_address + 6 + ssl);
|
ADC_client_set_state(client, ps_dns);
|
||||||
if (dns)
|
client->dns_job = net_dns_gethostbyname(client->address.hostname, AF_UNSPEC, ADC_client_dns_callback, client);
|
||||||
{
|
|
||||||
addr = (struct in_addr*) dns->h_addr_list[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize the sockaddr struct.
|
|
||||||
memset(&client->addr, 0, sizeof(client->addr));
|
|
||||||
client->addr.sin_family = AF_INET;
|
|
||||||
client->addr.sin_port = htons(port);
|
|
||||||
memcpy(&client->addr.sin_addr, addr, sizeof(struct in_addr));
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ struct ADC_client;
|
|||||||
|
|
||||||
enum ADC_client_callback_type
|
enum ADC_client_callback_type
|
||||||
{
|
{
|
||||||
|
ADC_CLIENT_NAME_LOOKUP = 1000,
|
||||||
ADC_CLIENT_CONNECTING = 1001,
|
ADC_CLIENT_CONNECTING = 1001,
|
||||||
ADC_CLIENT_CONNECTED = 1002,
|
ADC_CLIENT_CONNECTED = 1002,
|
||||||
ADC_CLIENT_DISCONNECTED = 1003,
|
ADC_CLIENT_DISCONNECTED = 1003,
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ static struct ADC_user* user_get(sid_t sid)
|
|||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void user_remove(const struct ADC_client_quit_reason* quit)
|
static void user_remove(const struct ADC_client_quit_reason* quit)
|
||||||
{
|
{
|
||||||
struct ADC_user* user = user_get(quit->sid);
|
struct ADC_user* user = user_get(quit->sid);
|
||||||
@@ -91,6 +90,10 @@ static int handle(struct ADC_client* client, enum ADC_client_callback_type type,
|
|||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
|
case ADC_CLIENT_NAME_LOOKUP:
|
||||||
|
status("Looking up hostname...");
|
||||||
|
break;
|
||||||
|
|
||||||
case ADC_CLIENT_CONNECTING:
|
case ADC_CLIENT_CONNECTING:
|
||||||
status("Connecting...");
|
status("Connecting...");
|
||||||
break;
|
break;
|
||||||
@@ -107,6 +110,9 @@ static int handle(struct ADC_client* client, enum ADC_client_callback_type type,
|
|||||||
status("SSL handshake.");
|
status("SSL handshake.");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ADC_CLIENT_SSL_OK:
|
||||||
|
break;
|
||||||
|
|
||||||
case ADC_CLIENT_LOGGING_IN:
|
case ADC_CLIENT_LOGGING_IN:
|
||||||
status("Logging in...");
|
status("Logging in...");
|
||||||
break;
|
break;
|
||||||
@@ -155,6 +161,68 @@ static int handle(struct ADC_client* client, enum ADC_client_callback_type type,
|
|||||||
|
|
||||||
static int running = 1;
|
static int running = 1;
|
||||||
|
|
||||||
|
#if !defined(WIN32)
|
||||||
|
void adm_handle_signal(int sig)
|
||||||
|
{
|
||||||
|
switch (sig)
|
||||||
|
{
|
||||||
|
case SIGINT:
|
||||||
|
LOG_INFO("Interrupted. Shutting down...");
|
||||||
|
running = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIGTERM:
|
||||||
|
LOG_INFO("Terminated. Shutting down...");
|
||||||
|
running = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIGPIPE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIGHUP:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
LOG_TRACE("hub_handle_signal(): caught unknown signal: %d", signal);
|
||||||
|
running = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int signals[] =
|
||||||
|
{
|
||||||
|
SIGINT, /* Interrupt the application */
|
||||||
|
SIGTERM, /* Terminate the application */
|
||||||
|
SIGPIPE, /* prevent sigpipe from kills the application */
|
||||||
|
SIGHUP, /* reload configuration */
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
void adm_setup_signal_handlers()
|
||||||
|
{
|
||||||
|
sigset_t sig_set;
|
||||||
|
struct sigaction act;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
sigemptyset(&sig_set);
|
||||||
|
act.sa_mask = sig_set;
|
||||||
|
act.sa_flags = SA_ONSTACK | SA_RESTART;
|
||||||
|
act.sa_handler = adm_handle_signal;
|
||||||
|
|
||||||
|
for (i = 0; signals[i]; i++)
|
||||||
|
{
|
||||||
|
if (sigaction(signals[i], &act, 0) != 0)
|
||||||
|
{
|
||||||
|
LOG_ERROR("Error setting signal handler %d", signals[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void adm_shutdown_signal_handlers()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif /* !WIN32 */
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
@@ -163,6 +231,9 @@ int main(int argc, char** argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hub_set_log_verbosity(5);
|
||||||
|
adm_setup_signal_handlers();
|
||||||
|
|
||||||
struct ADC_client* client;
|
struct ADC_client* client;
|
||||||
net_initialize();
|
net_initialize();
|
||||||
|
|
||||||
@@ -176,6 +247,7 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
ADC_client_destroy(client);
|
ADC_client_destroy(client);
|
||||||
net_destroy();
|
net_destroy();
|
||||||
|
adm_shutdown_signal_handlers();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,12 +68,14 @@ extern "C" {
|
|||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
#include "util/misc.h"
|
#include "util/misc.h"
|
||||||
#include "util/tiger.h"
|
#include "util/tiger.h"
|
||||||
|
#include "util/threads.h"
|
||||||
|
|
||||||
#include "adc/sid.h"
|
#include "adc/sid.h"
|
||||||
#include "adc/message.h"
|
#include "adc/message.h"
|
||||||
|
|
||||||
#include "network/network.h"
|
#include "network/network.h"
|
||||||
#include "network/connection.h"
|
#include "network/connection.h"
|
||||||
|
#include "network/dnsresolver.h"
|
||||||
#include "network/ipcalc.h"
|
#include "network/ipcalc.h"
|
||||||
#include "network/timeout.h"
|
#include "network/timeout.h"
|
||||||
|
|
||||||
|
|||||||
149
src/util/threads.c
Normal file
149
src/util/threads.c
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* 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
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uhub.h"
|
||||||
|
|
||||||
|
#ifdef POSIX_THREAD_SUPPORT
|
||||||
|
|
||||||
|
struct pthread_data
|
||||||
|
{
|
||||||
|
pthread_t handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
void uhub_mutex_init(uhub_mutex_t* mutex)
|
||||||
|
{
|
||||||
|
pthread_mutex_init(mutex, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uhub_mutex_destroy(uhub_mutex_t* mutex)
|
||||||
|
{
|
||||||
|
pthread_mutex_destroy(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uhub_mutex_lock(uhub_mutex_t* mutex)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uhub_mutex_unlock(uhub_mutex_t* mutex)
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
int uhub_mutex_trylock(uhub_mutex_t* mutex)
|
||||||
|
{
|
||||||
|
int ret = pthread_mutex_trylock(mutex);
|
||||||
|
return (ret == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uhub_thread_t* uhub_thread_create(uhub_thread_start start, void* arg)
|
||||||
|
{
|
||||||
|
struct pthread_data* thread = (struct pthread_data*) hub_malloc_zero(sizeof(struct pthread_data));
|
||||||
|
int ret = pthread_create(&thread->handle, NULL, start, arg);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
hub_free(thread);
|
||||||
|
thread = NULL;
|
||||||
|
}
|
||||||
|
return thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
void uhub_thread_cancel(uhub_thread_t* thread)
|
||||||
|
{
|
||||||
|
pthread_cancel(thread->handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* uhub_thread_join(uhub_thread_t* thread)
|
||||||
|
{
|
||||||
|
void* ret = NULL;
|
||||||
|
pthread_join(thread->handle, &ret);
|
||||||
|
hub_free(thread);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* POSIX_THREAD_SUPPORT */
|
||||||
|
|
||||||
|
#ifdef WINTHREAD_SUPPORT
|
||||||
|
|
||||||
|
struct winthread_data
|
||||||
|
{
|
||||||
|
uhub_thread_t* handle;
|
||||||
|
uhub_thread_start start;
|
||||||
|
void* arg;
|
||||||
|
};
|
||||||
|
|
||||||
|
static DWORD WINAPI uhub_winthread_start(void* ptr)
|
||||||
|
{
|
||||||
|
struct winthread_data* data = (struct winthread_data*) ptr;
|
||||||
|
DWORD ret = (DWORD) data->start(data->arg);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void uhub_mutex_init(uhub_mutex_t* mutex)
|
||||||
|
{
|
||||||
|
InitializeCriticalSection(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uhub_mutex_destroy(uhub_mutex_t* mutex)
|
||||||
|
{
|
||||||
|
DeleteCriticalSection(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uhub_mutex_lock(uhub_mutex_t* mutex)
|
||||||
|
{
|
||||||
|
EnterCriticalSection(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uhub_mutex_unlock(uhub_mutex_t* mutex)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
int uhub_mutex_trylock(uhub_mutex_t* mutex)
|
||||||
|
{
|
||||||
|
return TryEnterCriticalSection(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
uhub_thread_t* uhub_thread_create(uhub_thread_start start, void* arg)
|
||||||
|
{
|
||||||
|
struct winthread_data* thread = (struct winthread_data*) hub_malloc_zero(sizeof(struct winthread_data));
|
||||||
|
thread->start = start;
|
||||||
|
thread->arg = arg;
|
||||||
|
thread->handle = CreateThread(NULL, 0, uhub_winthread_start, thread, 0, 0);
|
||||||
|
return thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
void uhub_thread_cancel(uhub_thread_t* thread)
|
||||||
|
{
|
||||||
|
TerminateThread(thread->handle, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* uhub_thread_join(uhub_thread_t* thread)
|
||||||
|
{
|
||||||
|
void* ret = NULL;
|
||||||
|
DWORD exitCode;
|
||||||
|
WaitForSingleObject(thread->handle, INFINITE);
|
||||||
|
GetExitCodeThread(thread->handle, &exitCode);
|
||||||
|
ret = &exitCode;
|
||||||
|
CloseHandle(thread->handle);
|
||||||
|
hub_free(thread);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif /* WINTHREAD_SUPPORT */
|
||||||
49
src/util/threads.h
Normal file
49
src/util/threads.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* uhub - A tiny ADC p2p connection hub
|
||||||
|
* 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
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HAVE_UHUB_UTIL_THREADS_H
|
||||||
|
#define HAVE_UHUB_UTIL_THREADS_H
|
||||||
|
|
||||||
|
typedef void*(*uhub_thread_start)(void*) ;
|
||||||
|
|
||||||
|
#ifdef POSIX_THREAD_SUPPORT
|
||||||
|
typedef struct pthread_data uhub_thread_t;
|
||||||
|
typedef pthread_mutex_t uhub_mutex_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WINTHREAD_SUPPORT
|
||||||
|
struct winthread_data;
|
||||||
|
typedef struct winthread_data uhub_thread_t;
|
||||||
|
typedef CRITICAL_SECTION uhub_mutex_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Mutexes
|
||||||
|
extern void uhub_mutex_init(uhub_mutex_t* mutex);
|
||||||
|
extern void uhub_mutex_destroy(uhub_mutex_t* mutex);
|
||||||
|
extern void uhub_mutex_lock(uhub_mutex_t* mutex);
|
||||||
|
extern void uhub_mutex_unlock(uhub_mutex_t* mutex);
|
||||||
|
extern int uhub_mutex_trylock(uhub_mutex_t* mutex);
|
||||||
|
|
||||||
|
// Threads
|
||||||
|
uhub_thread_t* uhub_thread_create(uhub_thread_start start, void* arg);
|
||||||
|
void uhub_thread_cancel(uhub_thread_t* thread);
|
||||||
|
void* uhub_thread_join(uhub_thread_t* thread);
|
||||||
|
|
||||||
|
#endif /* HAVE_UHUB_UTIL_THREADS_H */
|
||||||
|
|
||||||
Reference in New Issue
Block a user