Compare commits

..

148 Commits

Author SHA1 Message Date
Jeffrey Paul fdc1ccc68e kick off CI
continuous-integration/drone/push Build is passing Details
2020-03-22 07:57:35 -07:00
Jeffrey Paul 0875ba15f5 adds drone ci config 2020-03-22 07:48:16 -07:00
Jan Vidar Krey 35d8088b44 Handle socket errors from connected clients.
If a TLS error occurs, it could end up in a situation where the network handler code did not want to
read or write because it only had the error flag set. However, this was not handled, which left the
socket triggering in the event loop - but nothing was done to handle it.

This can easily cause a 100% cpu situation - the hub is still functioning though while this is
happening.
2019-12-13 10:51:40 +01:00
Jan Vidar Krey cff10910ad Issue 72: Improve ghost user detection
uhub has the ability to disconnect a 'ghost' user, e.g. if a user
reconnects then uhub will kick the existing user if it is still there.
However, this could also be triggered abusively by having two "tabs" or windows
connect at the same time from the same client. The process of connecting a new
client is rather expensive because it triggers a lot of updates on all connections.

With this change, uhub will only attempt to disconnect the existing client if
it is marked with the "flag_choke" flag, which indicates that messages must be
dropped simply because the client is not accepting data fast enough. This will
cause the new connection to fail because the user is already logged in.

This can be further improved by adding a timestamp for when the connection
previously was provable working. Which is possibly a better and more reliable
way of detecting ghost users.
2019-12-01 13:16:28 +01:00
Jan Vidar Krey 78a7039240 Fix CPU spikes for TLS connections using incompatible TLS protocol versions. 2019-06-18 16:01:44 +02:00
Jan Vidar Krey 0ae96b0da8 Add statistics about OpenSSL events such as handshakes, closes and errors. 2019-06-18 15:59:22 +02:00
Jan Vidar Krey 022a9895ec fixup! Fix OpenSSL error, wrong initialization order. 2019-04-24 10:53:39 +02:00
Jan Vidar Krey 891adb84fb fixup! Fix OpenSSL error, wrong initialization order. 2019-04-24 10:50:31 +02:00
Jan Vidar Krey 9762b9389d fixup! Fix OpenSSL error, wrong initialization order. 2019-04-24 10:46:59 +02:00
Jan Vidar Krey 076e75897b Fix OpenSSL error, wrong initialization order. 2019-04-24 10:32:01 +02:00
Jan Vidar Krey bc8974b9a3 Add better TLS protocol negotiation for OpenSSL >1.0.1 2019-04-23 16:16:36 +02:00
Boris Pek 1eb00ac04a Update link in README. 2019-04-23 15:59:03 +02:00
Boris Pek cf3a6e06df Secure URLs: http --> https (part 2) 2019-04-23 15:59:03 +02:00
Boris Pek cb04255006 Secure URLs: http --> https (part 1) 2019-04-23 15:59:03 +02:00
Jan Vidar Krey 2a57dc859d Merge branch 'direct-connect-alpn_static' 2019-03-31 19:34:19 +02:00
Jan Vidar Krey 212064c166 Fix alpn_server_select_protocol to be static. 2019-03-31 19:33:46 +02:00
Jan Vidar Krey 56426f7b2a Merge branch 'alpn_static' of git://github.com/direct-connect/uhub into direct-connect-alpn_static 2019-03-31 19:27:50 +02:00
Jan Vidar Krey 00bd8ba24d Compile with Ubuntu 16.04/xenial on Travis CI 2019-03-19 21:10:00 +01:00
Jan Vidar Krey 46906a9a9c Merge branch 'master' of github.com:janvidar/uhub 2019-03-15 11:31:29 +01:00
Denys Smirnov 566cd9a9db advertise ADC protocol with ALPN 2019-03-15 02:19:19 +02:00
Boris Pek b27c44e633 cmake: fix build out of source tree
when there is only read access to sources.
2019-02-25 19:50:56 +01:00
Boris Pek d25fead3a8 Fix spelling errors 2019-02-25 19:46:24 +01:00
Boris Pek ef83b31cec Fix spelling errors 2019-02-25 19:46:24 +01:00
Boris Pek be1ad4f475 Fix cross-compilation for MS Windows using MinGW
[Thanks to Felix Brucker]
(Closes: #55)
2019-01-14 12:49:35 +01:00
Boris Pek 3435d53478 Use secure URL of git submodule in .gitmodules
(Closes: #58)
2019-01-14 12:48:00 +01:00
Felix Brucker 9038f56efe Add Dockerfile 2019-01-02 10:42:40 +01:00
Jan Vidar Krey de01486c0f Fix plug-in API header files. 2018-11-27 13:20:41 +01:00
Jan Vidar Krey c383a53105 Fix crash if unable to load plugin. 2018-11-21 11:00:20 +01:00
Kcchouette f0b67ea4cd Update config.xml 2018-11-20 11:56:07 +01:00
Kcchouette ac96ace7df Finish adding bots to uhub-passwd
Related to https://github.com/janvidar/uhub/pull/28
2018-11-18 20:32:00 +01:00
Kcchouette 7970f80114 Update getstarted.txt 2018-11-18 20:31:37 +01:00
Kcchouette 62216a7afe Update issue url (#48)
* Update issue url

* Update uhub.1

* update bugs URL
2018-11-18 20:30:23 +01:00
Felix Brucker 99711a5c6e Allow many large messages 2018-10-11 23:29:32 +02:00
Felix Brucker e43aea35cc Use localtime instead of utc 2018-10-11 23:29:32 +02:00
makefu d54d723c59 add aarch64 to supported architectures
closes #46
2018-10-11 23:24:11 +02:00
Jan Vidar Krey c813231c8d
Merge pull request #44 from Kcchouette/patch-1
Update plugins.conf
2018-04-30 15:23:43 +02:00
Kcchouette debbca572f
Update plugins.conf 2018-04-30 15:22:42 +02:00
Jan Vidar Krey a8ee6e7f60 Bump version to 0.5.1 2018-02-26 14:13:21 +00:00
Jan Vidar Krey f0e9b2ffd9 Add support for OpenSSL 1.1 2018-02-26 10:58:41 +00:00
Jan Vidar Krey ba19048ebc Rename the test binary to autotest-bin, to avoid naming conflicts for the reserved 'test' target. 2018-02-19 11:59:34 +01:00
Jan Vidar Krey fd05f13fe4 Make error message if sqlite3 is not found! 2018-02-19 11:44:43 +01:00
Jan Vidar Krey 11538d6909 Mute debug log messages for net_send() that were incorrectly classified as error messages. 2018-01-15 17:00:56 +00:00
Yorhel 90d05c9a19 mod_logging: Fix inverted if statement in syslog config check 2016-07-11 09:26:34 +00:00
Jan Vidar Krey ed5a59b16c Merge pull request #35 from CoiLock/master
Fixed compilation on systemd > 210
2016-03-07 18:17:07 +01:00
CoiLock 70f2a43f67 Fixed compilation on systemd > 210 2016-03-07 17:54:07 +01:00
Jan Vidar Krey dc80644471 Merge pull request #28 from klondi/unrestricted_users
Allow unrestricted users on uhub
2014-12-15 09:36:49 +01:00
Jan Vidar Krey 889807da1b Merge pull request #31 from klondi/chat_history_sqlite_fixes
Chat history sqlite fixes
2014-11-26 13:56:07 +01:00
Jan Vidar Krey 5151badbeb Merge pull request #29 from klondi/run_travis_tests
Run travis tests
2014-11-26 13:55:52 +01:00
mimicmod 96cc46117f Fix previous commit (Added sqlite VACUUM to cleanup commands)
Conflicts:
	src/plugins/mod_chat_history_sqlite.c
2014-11-25 15:46:35 +01:00
Michal Micka 5e63ab2ccd Fix: Chat history sqlite truncating long messages 2014-11-25 15:42:40 +01:00
Francisco Blas (klondike) Izquierdo Riera 32b7e68f00 Run the unit tests before installation 2014-11-25 09:11:06 +01:00
Francisco Blas (klondike) Izquierdo Riera 5c5918a89d Use set -e to stop running as soon as we fail 2014-11-25 09:10:22 +01:00
Francisco Blas (klondike) Izquierdo Riera 3f2641595b Remove invalid assertion as \n has length 0 2014-11-25 09:07:03 +01:00
Jan Vidar Krey 0e27e4219d Merge pull request #30 from klondi/mimicfixes
Mimicfixes
2014-11-25 07:55:56 +01:00
Jan Vidar Krey e32bb3ff7a Merge pull request #27 from klondi/utf-8_fixes
Add support for 4 byte UTF-8 characters and stricter character checking
2014-11-25 07:54:12 +01:00
mimicmod 32c65ada49 Fixed usage of FlexHub regimport tool 2014-11-24 16:24:50 +01:00
mimicmod 77704f6e67 Added simple tool to import FlexHub users 2014-11-24 16:24:38 +01:00
mimicmod 77323fa98d Removed unnecessary step in PtokaX regimport tool 2014-11-24 16:23:32 +01:00
mimicmod 7840e09884 Added simple tool to import PtokaX (< 0.5.0.0) users 2014-11-24 16:23:16 +01:00
Michal Micka 6ad5efea6d Fix: Make config parser python 3 compatible 2014-11-24 16:08:47 +01:00
Francisco Blas (klondike) Izquierdo Riera 076daec846 Backport the HUBBOT constant defining a bot which is also an operator 2014-11-24 12:28:28 +01:00
Francisco Blas (klondike) Izquierdo Riera 223e01937e Fix boolean logic fuck up 2014-11-24 12:12:07 +01:00
klondike 19068de088 Make unrestricted... unrestricted 2014-11-24 12:11:54 +01:00
klondike c15f201d70 Add auth_cred_is_unrestricted 2014-11-24 12:11:41 +01:00
klondike 7bda215ad4 Add bots to uhub-passwd 2014-11-24 12:11:25 +01:00
klondike d86ef503b3 Add opbots and unrestricted bots 2014-11-24 12:11:11 +01:00
Francisco Blas (klondike) Izquierdo Riera 7865277324 Add tests for the utf-8 cases 2014-11-24 12:05:28 +01:00
Francisco Blas (klondike) Izquierdo Riera 8a7e892aeb Add support for 4 byte UTF-8 characters and stricter character checking 2014-11-24 10:28:50 +01:00
Jan Vidar Krey 05edfa48b2 Merge pull request #25 from schreda/master
added broadcast message and getter for user count in plugin API
2014-10-17 00:09:56 +02:00
Jan Vidar Krey 204544298b Cleanup debug logging. 2014-10-16 23:14:12 +02:00
Jan Vidar Krey 418db22931 Merge branch 'master' of github.com:janvidar/uhub 2014-10-16 23:10:28 +02:00
Jan Vidar Krey 037ceff0a5 Disable SSLv3 explicitly also. 2014-10-16 23:09:50 +02:00
Jan Vidar Krey 44708e8433 Move some network, timer code. 2014-10-16 23:09:12 +02:00
Jan Vidar Krey 76ff2a1a13 Fix TLS protocol mismatch assert causing the hub to shutdown. 2014-10-16 23:08:17 +02:00
Jan Vidar Krey 280e28a6d4 Merge pull request #26 from Tilka/foo
Release all memory in tests
2014-10-06 22:28:41 +02:00
Tillmann Karras c0ee55325c Release all memory in tests and fix comment 2014-10-06 21:06:33 +02:00
Tillmann Karras 3d0b652ec9 Remove some unused variables 2014-10-06 21:02:08 +02:00
Andre Schreder 2d45a37536 added broadcast message and getter for user count in plugin API 2014-10-03 15:23:36 +02:00
Jan Vidar Krey 1da917e5b9 Fix crash due to negative max copy length. 2014-09-23 00:01:15 +02:00
Jan Vidar Krey f71bc59527 Release version 0.5.0. 2014-08-06 20:56:07 +02:00
Jan Vidar Krey d7c8c9426d Fix memory leak by creating the SSL context once for ADC client.
This is done using reference counted global memory.
2014-08-06 17:37:06 +02:00
Jan Vidar Krey 4919aea8d5 Send information through ADC client interface about the TLS connection. 2014-08-05 17:45:32 +02:00
Jan Vidar Krey 95de69efeb Added functionality to fetch the TLS version and cipher info for a connection. 2014-08-05 17:43:24 +02:00
Jan Vidar Krey b3b4876c08 Use TLS 1.2 when connecting to a hub when using TLS. 2014-08-05 17:42:18 +02:00
Jan Vidar Krey ac543e3df4 Clear connection timeout timer when successfully connecting. 2014-08-05 17:40:55 +02:00
Jan Vidar Krey 46bdc77066 Added a notification mechanism for sending messages from
another thread to the mainthread in a safe manner.

This is used for the DNS lookup code, and can also
be used by the signal handler to safely report actions back
to the application mainloop without using global variables.
2014-08-05 16:21:56 +02:00
Jan Vidar Krey 1526d63403 Simplify list_clear(), allow NULL as free() function pointer.
This makes it redundant to create a null_free() or dummy_free() function
that does nothing.
2014-08-05 13:08:46 +02:00
klondike d33695435b Add propper check for stdint.h 2014-08-05 10:48:42 +02:00
klondike bfdf707490 Remove unnecessary include 2014-08-05 10:48:34 +02:00
klondike b8209d9d0a Check for ssize_t properly 2014-08-05 10:48:26 +02:00
klondike 5c8d99d8ff _GNU_SOURCE is now defined by CMake 2014-08-05 10:48:10 +02:00
klondike 4c5038c26d Add automatic strndup detection instead of the previous hack 2014-08-05 10:48:01 +02:00
klondike aeb006beb6 Add automatic memmem detction instead of the previous hack 2014-08-05 10:47:49 +02:00
klondike 3b6c338ee8 Start generating system.h dynamicallly 2014-08-05 10:47:29 +02:00
Jan Vidar Krey 652ac5f9b9 Fix #211 - ADC IINF should have flag AP for application name, and VE for version.
x# Please enter the commit message for your changes. Lines starting
2014-08-03 22:51:47 +02:00
Jan Vidar Krey 4263750bc5 Merge branch 'ssl_fixes' 2014-07-30 11:47:27 +02:00
Jan Vidar Krey 2182feb052 Added support for probing HTTP, enough to tell browsers to stop calling. 2014-07-30 11:46:54 +02:00
Jan Vidar Krey 48b76f7bd1 The DEBUG macro never got set, causes verbose log messages to never be compiled in. 2014-07-30 11:46:03 +02:00
Jan Vidar Krey b5bedfe9e4 uhub-admin: don't busy loop before a connection has been established.
This happened due to the network polling mechanism had nothing to poll
for, so it returned immediately only to be called again (during DNS lookup).

This fix introduces a control pipe that is polled for reading, althoug nothing
is ever sent to that pipe. But, it can be used instead of the signal
handler approach which is currently used for terminating the program.
2014-07-29 17:35:58 +02:00
Jan Vidar Krey cbe0b4e108 Potential crash fix for tools. 2014-07-29 17:35:14 +02:00
Jan Vidar Krey b85381c0f5 Added configuration options for TLS cipher suites and TLS versions. 2014-07-29 13:31:42 +02:00
Hector Martin 0426cb523a Fix: Rework SSL poll event handling to avoid infinite loops
The downstream connection callback must only be invoked when the event
that SSL requests for the connection to make progress has actually
occured. Otherwise, the downstream callback might do nothing but
re-queue an unrelated event (e.g. in user_net_io_want_write), and the
event loop comes around instantly while making no progress. Track the
SSL-requested events separately and deliver the required downstream
event when they fire.

Sample strace:

epoll_wait(0, {{EPOLLIN, {u32=96, u64=96}}}, 91, 10000) = 1
: net_ssl_callback in state tls_st_need_write calls cb NET_EVENT_WRITE
: User writes data, OpenSSL tries to write data
write(96, <snip>..., 170) = -1 EAGAIN (Resource temporarily unavailable)
: handle_openssl_error requests NET_EVENT_WRITE
epoll_ctl(0, EPOLL_CTL_MOD, 96, {EPOLLOUT, {u32=96, u64=96}}) = 0
: User callback then requests NET_EVENT_READ|NET_EVENT_WRITE
epoll_ctl(0, EPOLL_CTL_MOD, 96, {EPOLLIN|EPOLLOUT, {u32=96, u64=96}}) =
: Data available for *reading*
epoll_wait(0, {{EPOLLIN, {u32=96, u64=96}}}, 91, 10000) = 1
: net_ssl_callback in state tls_st_need_write calls cb NET_EVENT_WRITE
: again...
2014-07-29 12:09:07 +02:00
Jan Vidar Krey 9f78a2e85f Merge branch 'master' of github.com:janvidar/uhub 2014-05-30 15:06:23 +02:00
Jan Vidar Krey f472fc9424 Fix Clang compile warnings. 2014-05-14 21:00:42 +02:00
Jan Vidar Krey 7706e1cb8a Fix copyright year. 2014-05-14 11:39:18 +02:00
Jan Vidar Krey 24b98358d3 Remove usage of strcat, since OpenBSD does not like that. 2014-05-14 11:00:18 +02:00
Jan Vidar Krey 12ce522a6d Fix crashing autotest due to wrong initialization of the usermanager. 2014-05-14 11:00:14 +02:00
Jan Vidar Krey 5e06b46deb Fix compile warning due to missing newline at EOF. 2014-05-14 11:00:04 +02:00
Jan Vidar Krey a1f8c5bdbb Merge pull request #24 from tehnick/travis-ci
Add support of Travis CI.
2014-05-12 10:04:03 +02:00
Jan Vidar Krey 992aa8c4af Fix compile warning due to missing return value. 2014-05-12 00:05:07 +02:00
Jan Vidar Krey 60393ca9d0 Merge pull request #23 from tehnick/fix-clang
Fix build with Clang.
2014-05-12 00:01:50 +02:00
Boris Pek 89aef4ddaf Add support of Travis CI. 2014-05-11 16:07:38 +04:00
Boris Pek a38a82e318 Fix build with clang. 2014-05-11 15:22:14 +04:00
Jan Vidar Krey 3e8699ab24 Fix typo. 2014-05-10 01:08:32 +02:00
Jan Vidar Krey 3b38898045 Merge pull request #22 from tehnick/cmake-fix
Delete extra option from cmake rules.
2014-05-10 00:45:23 +02:00
Jan Vidar Krey 1b8762c7ee Merge pull request #20 from tehnick/cmake-sqlite3-fix
Fix cmake script for searching sqlite3 properly.
2014-05-10 00:44:28 +02:00
Boris Pek ce06269128 Delete extra option from cmake rules. 2014-05-10 02:03:04 +04:00
Boris Pek e75a759693 Fix cmake script for searching sqlite3 properly.
This is important for Debian, Ubuntu and other systems based on them. Details:
  https://wiki.debian.org/Multiarch
  https://wiki.ubuntu.com/MultiarchSpec

Have in mind that there are MIPS, ARM and many other architectures...
2014-05-08 22:52:10 +04:00
Jan Vidar Krey 7f2ffd7e1c Fix CMake/SQLite path issues on 64-bit Ubuntu 14.04 2014-05-08 13:33:45 +02:00
Jan Vidar Krey e2b0757f4a Improved flood control counting to strictly not allow more than
the given amount of messages in the configured interval.

The previous behavior allowed n+2 messages in the interval, due to
two off by one comparison rules.

In addition, if flooding is detected then each new message after the flooding
is detected will reset the interval timer, which means the client
cannot send another message until the timeout interval expires.
2014-05-08 13:30:09 +02:00
Jan Vidar Krey c26e8aaefe Merge pull request #19 from Tilka/master
Bunch of fixes
2013-09-10 01:38:29 -07:00
Tillmann Karras c295461f4e mod_topic: check argument for NULL
Better safe than sorry.
2013-09-10 08:30:27 +02:00
Tillmann Karras 8b442018a7 Fix struct mixup 2013-09-06 21:17:43 +02:00
Tillmann Karras fa782e3d2c Fix memleak 2013-09-06 21:17:31 +02:00
Tilka 591d0ba5bb Support certificate chains 2013-09-06 01:44:25 +02:00
Tilka a81757c483 Merge remote-tracking branch 'upstream/master' 2013-09-06 01:43:10 +02:00
Jan Vidar Krey cf9be754aa Rewrote the configuration file parser generator.
Converted from Perl to Python for a better
and cleaner object oriented design.
2013-04-22 21:58:06 +02:00
Jan Vidar Krey 22292e493e fixup! Fix for #193 - Can't build on OpenBSD 2013-04-17 22:40:04 +02:00
Jan Vidar Krey 419e8888d0 Fix for #193 - Can't build on OpenBSD 2013-04-16 00:24:42 +02:00
Jan Vidar Krey 73b4d51393 fixup! fixup! Updated copyright year. 2013-03-24 20:17:51 +01:00
Jan Vidar Krey 50b6221874 fixup! Updated copyright year. 2013-03-24 20:17:51 +01:00
Jan Vidar Krey bb5865d368 Fix double free() 2013-03-24 09:47:32 +01:00
Jan Vidar Krey 550740f715 Fix bug #198 - Timers could cause infinite loops
This could essentially happen due to time drift,
high load, or the process being put in sleep for a while.

The reason is that recurring timers could be added to the same time slot
as the timeslot being handled.
2013-03-24 09:47:32 +01:00
Jan Vidar Krey d73d213bc4 Remove the chat_is_privileged_plugin because it fails to compile 2013-03-23 22:47:32 +01:00
mimicmod 5672ba14e3 Added mod_chat_history_sqlite and mod_chat_is_privileged.
Use file=/path/to/db to specify the database file where chat history should be stored. Other config variables are the same as those for mod_chat_history.

Code merged adapted and merged from Mimicmod's repository:
https://github.com/mimicmod/uhub.git
2013-03-23 22:47:32 +01:00
Jan Vidar Krey cd5c4ee622 Optimize lookups by CID and nick.
This used to be a linear search O(n), but is now done
as a red-black tree O(log n) instead.

These operations can be further opimized with a hash-table
which would acheive near constant time lookups.
2013-03-23 22:11:05 +01:00
Jan Vidar Krey 52211a6bac Updated copyright year. 2013-03-22 20:00:40 +01:00
Jan Vidar Krey f25015927a Clean up white space. 2013-03-22 20:00:40 +01:00
Jan Vidar Krey 5835a06676 Removed redundant debug printf. 2013-03-22 20:00:40 +01:00
Jan Vidar Krey 6c55ae1146 Simple compile fix. 2013-03-22 20:00:40 +01:00
Jan Vidar Krey 2d6f69d299 Cleaned up usage of linked lists and added missing functionality.
- Added a list_remove_first() which is generally better than list_remove()
  provided you want to remove the first element.
- Added a list_append_list() to append and move all nodes from one list to
  another.
2013-03-22 20:00:40 +01:00
Jan Vidar Krey b81bb2cbd9 Cleaned up all list iterations, added macro named LIST_FOREACH.
Previously you would have to do something like this:

for (type foo = (type) list_get_first(list); foo; foo = (type) list_get_next(list)
{
    /* code */
}

Now, you can instead write this as:

LIST_FOREACH(type, foo, list,
{
    /* code */
})

Basically, boilerplate stuff including the casting is gone.
2013-03-22 00:58:14 +01:00
Jan Vidar Krey 50e720861e Detect if system is big endian (e.g. PPC64) 2013-02-20 00:30:02 +01:00
Jan Vidar Krey d48ef710d8 Added an ADC hub redirector written in python. 2013-02-10 22:56:36 +01:00
Jan Vidar Krey cfa210b3f3 Added a python version of the NMDC redirector. 2013-02-10 21:25:34 +01:00
Tillmann Karras 37c80fd403 rename !cleartopic to !resettopic
The command resets the topic to the default as configured in uhub.conf.
"clear" wrongly implies that the topic will be emptied.

Also added a plugin description in plugins.conf.
2012-11-08 15:14:58 +01:00
Tillmann Karras dcc7aa4018 some regex adjustments
IP addresses are now checked for correct charset rather than allowing
everything.
2012-11-08 12:36:37 +01:00
Tilka 9dce6693f6 fix error messages and comments 2012-11-08 12:27:08 +01:00
155 changed files with 3300 additions and 2155 deletions

17
.drone.yml Normal file
View File

@ -0,0 +1,17 @@
kind: pipeline
name: default
steps:
- name: docker
image: plugins/docker
network_mode: bridge
settings:
repo: sneak/uhub
username:
from_secret: docker_username
password:
from_secret: docker_password
tags:
- ${DRONE_BRANCH//\//-}-${DRONE_COMMIT_SHA:0:8}
- ${DRONE_COMMIT_SHA}
- ${DRONE_BRANCH/\//-}

3
.gitignore vendored
View File

@ -14,7 +14,6 @@ uhub-admin
adcrush adcrush
uhub uhub
build-stamp build-stamp
build.ninja
debian/files debian/files
debian/uhub.debhelper.log debian/uhub.debhelper.log
debian/uhub.postinst.debhelper debian/uhub.postinst.debhelper
@ -22,5 +21,3 @@ debian/uhub.postrm.debhelper
debian/uhub.prerm.debhelper debian/uhub.prerm.debhelper
debian/uhub.substvars debian/uhub.substvars
uhub-passwd uhub-passwd
src/version.h

2
.gitmodules vendored
View File

@ -1,3 +1,3 @@
[submodule "thirdparty/sqlite"] [submodule "thirdparty/sqlite"]
path = thirdparty/sqlite path = thirdparty/sqlite
url = git://github.com/janvidar/sqlite.git url = https://github.com/janvidar/sqlite.git

14
.travis.yml Normal file
View File

@ -0,0 +1,14 @@
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

View File

@ -4,7 +4,7 @@ Authors of uhub
Jan Vidar Krey, Design and implementation Jan Vidar Krey, Design and implementation
E_zombie, Centos/RedHat customization scripts and heavy load testing E_zombie, Centos/RedHat customization scripts and heavy load testing
FleetCommand, Hub topic plugin code FleetCommand, Hub topic plugin code
MiMic, Implemented user commands MiMic, Implemented user commands, and plugins
Boris Pek (tehnick), Debian/Ubuntu packaging Boris Pek (tehnick), Debian/Ubuntu packaging
Tillmann Karras (Tilka), Misc. bug fixes Tillmann Karras (Tilka), Misc. bug fixes
Yoran Heling (Yorhel), TLS/SSL handshake detection bugfixes Yoran Heling (Yorhel), TLS/SSL handshake detection bugfixes

3
BUGS
View File

@ -1,2 +1 @@
Bugs are tracked on: http://bugs.extatic.org/ Bugs are tracked on: https://github.com/janvidar/uhub/issues

View File

@ -1,6 +1,6 @@
## ##
## Makefile for uhub ## Makefile for uhub
## Copyright (C) 2007-2012, Jan Vidar Krey <janvidar@extatic.org> ## Copyright (C) 2007-2013, Jan Vidar Krey <janvidar@extatic.org>
# #
cmake_minimum_required (VERSION 2.8.2) cmake_minimum_required (VERSION 2.8.2)
@ -9,14 +9,14 @@ project (uhub NONE)
enable_language(C) enable_language(C)
set (UHUB_VERSION_MAJOR 0) set (UHUB_VERSION_MAJOR 0)
set (UHUB_VERSION_MINOR 4) set (UHUB_VERSION_MINOR 5)
set (UHUB_VERSION_PATCH 1) set (UHUB_VERSION_PATCH 1)
set (PROJECT_SOURCE_DIR "${CMAKE_SOURCE_DIR}/src") set (PROJECT_SOURCE_DIR "${CMAKE_SOURCE_DIR}/src")
set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake/Modules) set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake/Modules)
option(RELEASE "Release build, debug build if disabled" ON) option(RELEASE "Release build, debug build if disabled" ON)
option(LINK_SUPPORT "Allow hub linking" OFF) option(LOWLEVEL_DEBUG, "Enable low level debug messages." OFF)
option(SSL_SUPPORT "Enable SSL support" ON) option(SSL_SUPPORT "Enable SSL support" ON)
option(USE_OPENSSL "Use OpenSSL's SSL support" ON ) option(USE_OPENSSL "Use OpenSSL's SSL support" ON )
option(SYSTEMD_SUPPORT "Enable systemd notify and journal logging" OFF) option(SYSTEMD_SUPPORT "Enable systemd notify and journal logging" OFF)
@ -25,6 +25,24 @@ option(ADC_STRESS "Enable the stress tester client" OFF)
find_package(Git) find_package(Git)
find_package(Sqlite3) find_package(Sqlite3)
include(TestBigEndian)
include(CheckSymbolExists)
include(CheckIncludeFile)
include(CheckTypeSize)
#Some functions need this to be found
add_definitions(-D_GNU_SOURCE)
set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D_GNU_SOURCE")
TEST_BIG_ENDIAN(BIGENDIAN)
if (BIGENDIAN)
add_definitions(-DARCH_BIGENDIAN)
endif()
if (NOT RELEASE)
add_definitions(-DDEBUG)
endif()
if (SSL_SUPPORT) if (SSL_SUPPORT)
if (USE_OPENSSL) if (USE_OPENSSL)
find_package(OpenSSL) find_package(OpenSSL)
@ -32,26 +50,36 @@ if (SSL_SUPPORT)
find_package(GnuTLS) find_package(GnuTLS)
endif() endif()
if (NOT GNUTLS_FOUND AND NOT OPENSSL_FOUND) if (NOT GNUTLS_FOUND AND NOT OPENSSL_FOUND)
message(FATAL_ERROR "Neither OpenSSL nor GnuTLS are not found!") message(FATAL_ERROR "Neither OpenSSL nor GnuTLS were found!")
endif() endif()
endif() endif()
if (LINK_SUPPORT) if (NOT SQLITE3_FOUND)
add_definitions(-DLINK_SUPPORT) message(FATAL_ERROR "SQLite3 is not found!")
endif() endif()
if (SYSTEMD_SUPPORT) if (SYSTEMD_SUPPORT)
INCLUDE(FindPkgConfig) INCLUDE(FindPkgConfig)
pkg_search_module(SD_DAEMON REQUIRED libsystemd-daemon) pkg_search_module(SD REQUIRED libsystemd)
pkg_search_module(SD_JOURNAL REQUIRED libsystemd-journal)
endif() endif()
if (MSVC) if (MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS) add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif() endif()
check_include_file(stdint.h HAVE_STDINT_H)
check_include_file(sys/types.h HAVE_SYS_TYPES_H)
if (HAVE_SYS_TYPES_H)
set (CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES} "sys/types.h")
endif()
check_type_size( ssize_t SSIZE_T )
check_symbol_exists(memmem string.h HAVE_MEMMEM)
check_symbol_exists(strndup string.h HAVE_STRNDUP)
include_directories("${PROJECT_SOURCE_DIR}") include_directories("${PROJECT_SOURCE_DIR}")
include_directories("${PROJECT_BINARY_DIR}")
include_directories(${SQLITE3_INCLUDE_DIRS}) include_directories(${SQLITE3_INCLUDE_DIRS})
link_directories(${SQLITE3_LIBRARY_DIRS})
file (GLOB uhub_SOURCES ${PROJECT_SOURCE_DIR}/core/*.c) file (GLOB uhub_SOURCES ${PROJECT_SOURCE_DIR}/core/*.c)
list (REMOVE_ITEM uhub_SOURCES list (REMOVE_ITEM uhub_SOURCES
@ -71,7 +99,7 @@ set (adcclient_SOURCES
add_library(adc STATIC ${adc_SOURCES}) add_library(adc STATIC ${adc_SOURCES})
add_library(network STATIC ${network_SOURCES}) add_library(network STATIC ${network_SOURCES})
add_library(utils STATIC ${utils_SOURCES}) add_library(utils STATIC ${utils_SOURCES})
if(CMAKE_COMPILER_IS_GNUCC) if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
set_target_properties(utils PROPERTIES COMPILE_FLAGS -fPIC) set_target_properties(utils PROPERTIES COMPILE_FLAGS -fPIC)
set_target_properties(network PROPERTIES COMPILE_FLAGS -fPIC) set_target_properties(network PROPERTIES COMPILE_FLAGS -fPIC)
endif() endif()
@ -80,7 +108,7 @@ add_dependencies(adc utils)
add_dependencies(network utils) add_dependencies(network utils)
add_executable(uhub ${PROJECT_SOURCE_DIR}/core/main.c ${uhub_SOURCES} ) add_executable(uhub ${PROJECT_SOURCE_DIR}/core/main.c ${uhub_SOURCES} )
add_executable(test ${CMAKE_SOURCE_DIR}/autotest/test.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_executable(uhub-passwd ${PROJECT_SOURCE_DIR}/tools/uhub-passwd.c)
add_library(mod_example MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_example.c) add_library(mod_example MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_example.c)
@ -88,18 +116,12 @@ add_library(mod_welcome MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_welcome.c)
add_library(mod_logging MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_logging.c ${PROJECT_SOURCE_DIR}/adc/sid.c) add_library(mod_logging MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_logging.c ${PROJECT_SOURCE_DIR}/adc/sid.c)
add_library(mod_auth_simple MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_auth_simple.c ) add_library(mod_auth_simple MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_auth_simple.c )
add_library(mod_chat_history MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_chat_history.c ) add_library(mod_chat_history MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_chat_history.c )
add_library(mod_chat_history_sqlite MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_chat_history_sqlite.c )
add_library(mod_chat_only MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_chat_only.c) add_library(mod_chat_only MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_chat_only.c)
add_library(mod_topic MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_topic.c) add_library(mod_topic MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_topic.c)
add_library(mod_no_guest_downloads MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_no_guest_downloads.c) add_library(mod_no_guest_downloads MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_no_guest_downloads.c)
add_library(mod_auth_sqlite MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_auth_sqlite.c) add_library(mod_auth_sqlite MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_auth_sqlite.c)
if(WIN32)
target_link_libraries(uhub ws2_32)
target_link_libraries(test ws2_32)
target_link_libraries(mod_logging ws2_32)
target_link_libraries(mod_welcome ws2_32)
endif()
set_target_properties( set_target_properties(
mod_example mod_example
mod_welcome mod_welcome
@ -107,6 +129,7 @@ set_target_properties(
mod_auth_simple mod_auth_simple
mod_auth_sqlite mod_auth_sqlite
mod_chat_history mod_chat_history
mod_chat_history_sqlite
mod_chat_only mod_chat_only
mod_no_guest_downloads mod_no_guest_downloads
mod_topic mod_topic
@ -114,27 +137,32 @@ set_target_properties(
target_link_libraries(uhub ${CMAKE_DL_LIBS} adc network utils) target_link_libraries(uhub ${CMAKE_DL_LIBS} adc network utils)
target_link_libraries(uhub-passwd ${SQLITE3_LIBRARIES} utils) target_link_libraries(uhub-passwd ${SQLITE3_LIBRARIES} utils)
target_link_libraries(test ${CMAKE_DL_LIBS} adc network utils) target_link_libraries(autotest-bin ${CMAKE_DL_LIBS} adc network utils)
target_link_libraries(mod_example utils) target_link_libraries(mod_example utils)
target_link_libraries(mod_welcome utils) target_link_libraries(mod_welcome network utils)
target_link_libraries(mod_auth_simple utils) target_link_libraries(mod_auth_simple utils)
target_link_libraries(mod_auth_sqlite ${SQLITE3_LIBRARIES} utils) target_link_libraries(mod_auth_sqlite ${SQLITE3_LIBRARIES} utils)
target_link_libraries(mod_chat_history utils) target_link_libraries(mod_chat_history utils)
target_link_libraries(mod_chat_history_sqlite ${SQLITE3_LIBRARIES} utils)
target_link_libraries(mod_no_guest_downloads utils) target_link_libraries(mod_no_guest_downloads utils)
target_link_libraries(mod_chat_only utils) target_link_libraries(mod_chat_only utils)
target_link_libraries(mod_logging utils) target_link_libraries(mod_logging network utils)
target_link_libraries(mod_topic utils) target_link_libraries(mod_topic utils)
target_link_libraries(utils network) target_link_libraries(utils network)
target_link_libraries(mod_welcome network)
target_link_libraries(mod_logging network)
if(WIN32)
target_link_libraries(uhub ws2_32)
target_link_libraries(autotest-bin ws2_32)
target_link_libraries(mod_logging ws2_32)
target_link_libraries(mod_welcome ws2_32)
endif()
if(UNIX) if(UNIX)
add_library(adcclient STATIC ${adcclient_SOURCES}) add_library(adcclient STATIC ${adcclient_SOURCES})
add_executable(uhub-admin ${PROJECT_SOURCE_DIR}/tools/admin.c) add_executable(uhub-admin ${PROJECT_SOURCE_DIR}/tools/admin.c)
target_link_libraries(uhub-admin adcclient adc network utils pthread) target_link_libraries(uhub-admin adcclient adc network utils pthread)
target_link_libraries(uhub pthread) target_link_libraries(uhub pthread)
target_link_libraries(test pthread) target_link_libraries(autotest-bin 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})
@ -173,7 +201,7 @@ endif()
if(SSL_SUPPORT) if(SSL_SUPPORT)
target_link_libraries(uhub ${SSL_LIBS}) target_link_libraries(uhub ${SSL_LIBS})
target_link_libraries(test ${SSL_LIBS}) target_link_libraries(autotest-bin ${SSL_LIBS})
if(UNIX) if(UNIX)
target_link_libraries(uhub-admin ${SSL_LIBS}) target_link_libraries(uhub-admin ${SSL_LIBS})
endif() endif()
@ -185,31 +213,33 @@ if(SSL_SUPPORT)
endif() endif()
if (SYSTEMD_SUPPORT) if (SYSTEMD_SUPPORT)
target_link_libraries(uhub ${SD_DAEMON_LIBRARIES}) target_link_libraries(uhub ${SD_LIBRARIES})
target_link_libraries(uhub ${SD_JOURNAL_LIBRARIES}) target_link_libraries(autotest-bin ${SD_LIBRARIES})
target_link_libraries(test ${SD_DAEMON_LIBRARIES}) target_link_libraries(uhub-passwd ${SD_LIBRARIES})
target_link_libraries(test ${SD_JOURNAL_LIBRARIES}) target_link_libraries(uhub-admin ${SD_LIBRARIES})
target_link_libraries(uhub-passwd ${SD_JOURNAL_LIBRARIES}) include_directories(${SD_INCLUDE_DIRS})
target_link_libraries(uhub-admin ${SD_JOURNAL_LIBRARIES})
include_directories(${SD_DAEMON_INCLUDE_DIRS})
include_directories(${SD_JOURNAL_INCLUDE_DIRS})
add_definitions(-DSYSTEMD) add_definitions(-DSYSTEMD)
endif() endif()
configure_file ("${PROJECT_SOURCE_DIR}/version.h.in" "${PROJECT_SOURCE_DIR}/version.h") 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) # mark_as_advanced(FORCE CMAKE_BUILD_TYPE)
if (RELEASE) # if (RELEASE)
set(CMAKE_BUILD_TYPE Release) # set(CMAKE_BUILD_TYPE Release)
add_definitions(-DNDEBUG) # add_definitions(-DNDEBUG)
else() #else()
set(CMAKE_BUILD_TYPE Debug) # set(CMAKE_BUILD_TYPE Debug)
add_definitions(-DDEBUG) # add_definitions(-DDEBUG)
#endif()
if (LOWLEVEL_DEBUG)
add_definitions(-DLOWLEVEL_DEBUG)
endif() endif()
if (UNIX) if (UNIX)
install( TARGETS uhub uhub-passwd RUNTIME DESTINATION bin ) install( TARGETS uhub uhub-passwd RUNTIME DESTINATION bin )
install( TARGETS mod_example mod_welcome mod_logging mod_auth_simple mod_auth_sqlite mod_chat_history mod_chat_only mod_topic mod_no_guest_downloads DESTINATION /usr/lib/uhub/ OPTIONAL ) install( TARGETS mod_example mod_welcome mod_logging mod_auth_simple mod_auth_sqlite mod_chat_history mod_chat_history_sqlite mod_chat_only mod_topic mod_no_guest_downloads DESTINATION /usr/lib/uhub/ OPTIONAL )
install( FILES ${CMAKE_SOURCE_DIR}/doc/uhub.conf ${CMAKE_SOURCE_DIR}/doc/plugins.conf ${CMAKE_SOURCE_DIR}/doc/rules.txt ${CMAKE_SOURCE_DIR}/doc/motd.txt DESTINATION /etc/uhub OPTIONAL ) install( FILES ${CMAKE_SOURCE_DIR}/doc/uhub.conf ${CMAKE_SOURCE_DIR}/doc/plugins.conf ${CMAKE_SOURCE_DIR}/doc/rules.txt ${CMAKE_SOURCE_DIR}/doc/motd.txt DESTINATION /etc/uhub OPTIONAL )
endif() endif()

View File

@ -1,3 +1,23 @@
0.5.0:
- Use TLS 1.2 and strong ciphers by default, but made this configurable.
- Fix TLS event handling which caused some busy loops
- TLS: Support certificate chains
- Fix bug #211: Better Hublist pinger support by adding the AP flag of the INF message.
- Fix bug #198: Timers could cause infinite loops
- Sqlite3 is now mandatory
- Added mod_chat_history_sqlite and mod_chat_is_privileged.
- Support for systemd notify and journal logging
- Improved flood control counting to strictly not allow more than the given amount of messages in the configured interval.
- Optimize lookups by CID and nick.
- Added an NMDC and ADC hub redirectors written in Python.
- Fix all Clang compile warnings.
- Install uhub-passwd also.
- Add support for detecting HTTP connections to the hub. Enough to tell browsers to stop calling.
- Compile fixes for OpenBSD, including warnings about strcat.
- Fix crashing autotest due to wrong initialization of the usermanager.
- mod_topic: check argument for NULL
- rename !cleartopic to !resettopic
0.4.1: 0.4.1:
- Converted to CMake which replaces Visual Studio project files and GNU makefiles - Converted to CMake which replaces Visual Studio project files and GNU makefiles
- Fix issues with SSL causing excessive CPU usage. - Fix issues with SSL causing excessive CPU usage.
@ -27,8 +47,8 @@
- marked plugin callbacks that are not called yet - marked plugin callbacks that are not called yet
- add on_change_nick() to struct plugin_funcs - add on_change_nick() to struct plugin_funcs
- minimal changes - minimal changes
- Updated init script in debian package. - Updated init script in Debian package.
- Updated list of man pages in debian package. - Updated list of man pages in Debian package.
- Added man page for uhub-passwd. - Added man page for uhub-passwd.
- Merge branch 'master' of https://github.com/Tilka/uhub - Merge branch 'master' of https://github.com/Tilka/uhub
- Fix issue with QUI messages being allowed through the hub - Fix issue with QUI messages being allowed through the hub
@ -58,7 +78,7 @@
- minimal documentation fixes - minimal documentation fixes
- update client software link - update client software link
- update compile howto link - update compile howto link
- fix debian changelog - fix Debian changelog
- Fix bug #158 - Added plugin for setting topic (hub description). - Fix bug #158 - Added plugin for setting topic (hub description).
- Command arguments handling + cleanups - Command arguments handling + cleanups

19
Dockerfile Normal file
View File

@ -0,0 +1,19 @@
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"]

View File

@ -1,8 +1,13 @@
# uhub
Welcome and thanks for downloading uHub, a high performance ADC p2p hub. Welcome and thanks for downloading uHub, a high performance ADC p2p hub.
For the official documentation, bugs and other information, please visit: For the official documentation, bugs and other information, please visit:
http://www.uhub.org/ https://www.uhub.org/
For a list of compatible ADC clients, see: For a list of compatible ADC clients, see:
http://en.wikipedia.org/wiki/Advanced_Direct_Connect#Client_software https://en.wikipedia.org/wiki/Comparison_of_ADC_software#Client_software
# on dockerhub
* https://hub.docker.com/r/sneak/uhub

View File

@ -78,7 +78,7 @@ Description: a high performance hub for the ADC peer-to-peer network
Its low memory footprint allows it to handle several thousand users Its low memory footprint allows it to handle several thousand users
on high-end servers, or a small private hub on embedded hardware. on high-end servers, or a small private hub on embedded hardware.
. .
Homepage: http://www.extatic.org/uhub/ Homepage: https://www.uhub.org/
EOF EOF
cd .. cd ..

View File

@ -516,6 +516,15 @@ int main(int argc, char** argv)
exotic_add_test(&handle, &exotic_test_list_get_last_prev_2, "list_get_last_prev_2"); exotic_add_test(&handle, &exotic_test_list_get_last_prev_2, "list_get_last_prev_2");
exotic_add_test(&handle, &exotic_test_list_get_last_prev_next_1, "list_get_last_prev_next_1"); exotic_add_test(&handle, &exotic_test_list_get_last_prev_next_1, "list_get_last_prev_next_1");
exotic_add_test(&handle, &exotic_test_list_clear, "list_clear"); exotic_add_test(&handle, &exotic_test_list_clear, "list_clear");
exotic_add_test(&handle, &exotic_test_list_remove_first_1_1, "list_remove_first_1_1");
exotic_add_test(&handle, &exotic_test_list_remove_first_1_2, "list_remove_first_1_2");
exotic_add_test(&handle, &exotic_test_list_remove_first_1_3, "list_remove_first_1_3");
exotic_add_test(&handle, &exotic_test_list_remove_first_1_4, "list_remove_first_1_4");
exotic_add_test(&handle, &exotic_test_list_remove_first_1_5, "list_remove_first_1_5");
exotic_add_test(&handle, &exotic_test_list_append_list_1, "list_append_list_1");
exotic_add_test(&handle, &exotic_test_list_append_list_2, "list_append_list_2");
exotic_add_test(&handle, &exotic_test_list_append_list_3, "list_append_list_3");
exotic_add_test(&handle, &exotic_test_list_clear_list_last, "list_clear_list_last");
exotic_add_test(&handle, &exotic_test_list_destroy_1, "list_destroy_1"); exotic_add_test(&handle, &exotic_test_list_destroy_1, "list_destroy_1");
exotic_add_test(&handle, &exotic_test_list_destroy_2, "list_destroy_2"); exotic_add_test(&handle, &exotic_test_list_destroy_2, "list_destroy_2");
exotic_add_test(&handle, &exotic_test_test_message_refc_1, "test_message_refc_1"); exotic_add_test(&handle, &exotic_test_test_message_refc_1, "test_message_refc_1");
@ -697,6 +706,34 @@ int main(int argc, char** argv)
exotic_add_test(&handle, &exotic_test_utf8_valid_10, "utf8_valid_10"); exotic_add_test(&handle, &exotic_test_utf8_valid_10, "utf8_valid_10");
exotic_add_test(&handle, &exotic_test_utf8_valid_11, "utf8_valid_11"); exotic_add_test(&handle, &exotic_test_utf8_valid_11, "utf8_valid_11");
exotic_add_test(&handle, &exotic_test_utf8_valid_12, "utf8_valid_12"); exotic_add_test(&handle, &exotic_test_utf8_valid_12, "utf8_valid_12");
exotic_add_test(&handle, &exotic_test_utf8_valid_13, "utf8_valid_13");
exotic_add_test(&handle, &exotic_test_utf8_valid_14, "utf8_valid_14");
exotic_add_test(&handle, &exotic_test_utf8_valid_15, "utf8_valid_15");
exotic_add_test(&handle, &exotic_test_utf8_valid_16, "utf8_valid_16");
exotic_add_test(&handle, &exotic_test_utf8_valid_17, "utf8_valid_17");
exotic_add_test(&handle, &exotic_test_utf8_valid_18, "utf8_valid_18");
exotic_add_test(&handle, &exotic_test_utf8_valid_19, "utf8_valid_19");
exotic_add_test(&handle, &exotic_test_utf8_valid_20, "utf8_valid_20");
exotic_add_test(&handle, &exotic_test_utf8_valid_21, "utf8_valid_21");
exotic_add_test(&handle, &exotic_test_utf8_valid_22, "utf8_valid_22");
exotic_add_test(&handle, &exotic_test_utf8_valid_23, "utf8_valid_23");
exotic_add_test(&handle, &exotic_test_utf8_valid_24, "utf8_valid_24");
exotic_add_test(&handle, &exotic_test_utf8_valid_25, "utf8_valid_25");
exotic_add_test(&handle, &exotic_test_utf8_valid_26, "utf8_valid_26");
exotic_add_test(&handle, &exotic_test_utf8_valid_27, "utf8_valid_27");
exotic_add_test(&handle, &exotic_test_utf8_valid_28, "utf8_valid_28");
exotic_add_test(&handle, &exotic_test_utf8_valid_29, "utf8_valid_29");
exotic_add_test(&handle, &exotic_test_utf8_valid_30, "utf8_valid_30");
exotic_add_test(&handle, &exotic_test_utf8_valid_31, "utf8_valid_31");
exotic_add_test(&handle, &exotic_test_utf8_valid_32, "utf8_valid_32");
exotic_add_test(&handle, &exotic_test_utf8_valid_33, "utf8_valid_33");
exotic_add_test(&handle, &exotic_test_utf8_valid_34, "utf8_valid_34");
exotic_add_test(&handle, &exotic_test_utf8_valid_35, "utf8_valid_35");
exotic_add_test(&handle, &exotic_test_utf8_valid_36, "utf8_valid_36");
exotic_add_test(&handle, &exotic_test_utf8_valid_37, "utf8_valid_37");
exotic_add_test(&handle, &exotic_test_utf8_valid_38, "utf8_valid_38");
exotic_add_test(&handle, &exotic_test_utf8_valid_39, "utf8_valid_39");
exotic_add_test(&handle, &exotic_test_utf8_valid_40, "utf8_valid_40");
exotic_add_test(&handle, &exotic_test_rbtree_create_destroy, "rbtree_create_destroy"); exotic_add_test(&handle, &exotic_test_rbtree_create_destroy, "rbtree_create_destroy");
exotic_add_test(&handle, &exotic_test_rbtree_create_1, "rbtree_create_1"); exotic_add_test(&handle, &exotic_test_rbtree_create_1, "rbtree_create_1");
exotic_add_test(&handle, &exotic_test_rbtree_size_0, "rbtree_size_0"); exotic_add_test(&handle, &exotic_test_rbtree_size_0, "rbtree_size_0");
@ -723,7 +760,8 @@ int main(int argc, char** argv)
exotic_add_test(&handle, &exotic_test_rbtree_size_4, "rbtree_size_4"); exotic_add_test(&handle, &exotic_test_rbtree_size_4, "rbtree_size_4");
exotic_add_test(&handle, &exotic_test_rbtree_check_10000, "rbtree_check_10000"); exotic_add_test(&handle, &exotic_test_rbtree_check_10000, "rbtree_check_10000");
exotic_add_test(&handle, &exotic_test_rbtree_iterate_10000, "rbtree_iterate_10000"); exotic_add_test(&handle, &exotic_test_rbtree_iterate_10000, "rbtree_iterate_10000");
exotic_add_test(&handle, &exotic_test_rbtree_remove_5000, "rbtree_remove_5000"); exotic_add_test(&handle, &exotic_test_rbtree_remove_10000, "rbtree_remove_10000");
exotic_add_test(&handle, &exotic_test_rbtree_destroy_1, "rbtree_destroy_1");
exotic_add_test(&handle, &exotic_test_sid_create_pool, "sid_create_pool"); exotic_add_test(&handle, &exotic_test_sid_create_pool, "sid_create_pool");
exotic_add_test(&handle, &exotic_test_sid_check_0a, "sid_check_0a"); exotic_add_test(&handle, &exotic_test_sid_check_0a, "sid_check_0a");
exotic_add_test(&handle, &exotic_test_sid_check_0b, "sid_check_0b"); exotic_add_test(&handle, &exotic_test_sid_check_0b, "sid_check_0b");
@ -761,6 +799,7 @@ int main(int argc, char** argv)
exotic_add_test(&handle, &exotic_test_timer_add_5_events_1, "timer_add_5_events_1"); exotic_add_test(&handle, &exotic_test_timer_add_5_events_1, "timer_add_5_events_1");
exotic_add_test(&handle, &exotic_test_timer_check_5_events_1, "timer_check_5_events_1"); exotic_add_test(&handle, &exotic_test_timer_check_5_events_1, "timer_check_5_events_1");
exotic_add_test(&handle, &exotic_test_timer_process_5_events_1, "timer_process_5_events_1"); exotic_add_test(&handle, &exotic_test_timer_process_5_events_1, "timer_process_5_events_1");
exotic_add_test(&handle, &exotic_test_timer_shutdown, "timer_shutdown");
exotic_add_test(&handle, &exotic_test_tokenizer_basic_0, "tokenizer_basic_0"); exotic_add_test(&handle, &exotic_test_tokenizer_basic_0, "tokenizer_basic_0");
exotic_add_test(&handle, &exotic_test_tokenizer_basic_1, "tokenizer_basic_1"); exotic_add_test(&handle, &exotic_test_tokenizer_basic_1, "tokenizer_basic_1");
exotic_add_test(&handle, &exotic_test_tokenizer_basic_1a, "tokenizer_basic_1a"); exotic_add_test(&handle, &exotic_test_tokenizer_basic_1a, "tokenizer_basic_1a");
@ -951,7 +990,6 @@ int exotic_initialize(struct exotic_handle* handle, int argc, char** argv)
void exotic_add_test(struct exotic_handle* handle, exo_test_t func, const char* name) void exotic_add_test(struct exotic_handle* handle, exo_test_t func, const char* name)
{ {
struct exo_test_data* test; struct exo_test_data* test;
if (!handle) if (!handle)
{ {
fprintf(stderr, "exotic_add_test: failed, no handle!\n"); fprintf(stderr, "exotic_add_test: failed, no handle!\n");

View File

@ -14,10 +14,8 @@ static void inf_create_hub()
{ {
net_initialize(); net_initialize();
inf_hub = (struct hub_info*) hub_malloc_zero(sizeof(struct hub_info)); inf_hub = (struct hub_info*) hub_malloc_zero(sizeof(struct hub_info));
inf_hub->users = (struct hub_user_manager*) hub_malloc_zero(sizeof(struct hub_user_manager));
inf_hub->users->list = list_create();
inf_hub->users->sids = sid_pool_create(500);
inf_hub->users = uman_init();
inf_hub->acl = (struct acl_handle*) hub_malloc_zero(sizeof(struct acl_handle)); inf_hub->acl = (struct acl_handle*) hub_malloc_zero(sizeof(struct acl_handle));
inf_hub->config = (struct hub_config*) hub_malloc_zero(sizeof(struct hub_config)); inf_hub->config = (struct hub_config*) hub_malloc_zero(sizeof(struct hub_config));
@ -27,12 +25,9 @@ static void inf_create_hub()
static void inf_destroy_hub() static void inf_destroy_hub()
{ {
/* FIXME */ uman_shutdown(inf_hub->users);
list_destroy(inf_hub->users->list);
sid_pool_destroy(inf_hub->users->sids);
acl_shutdown(inf_hub->acl); acl_shutdown(inf_hub->acl);
free_config(inf_hub->config); free_config(inf_hub->config);
hub_free(inf_hub->users);
hub_free(inf_hub->acl); hub_free(inf_hub->acl);
hub_free(inf_hub->config); hub_free(inf_hub->config);
hub_free(inf_hub); hub_free(inf_hub);

View File

@ -1,10 +1,16 @@
#include <uhub.h> #include <uhub.h>
static struct linked_list* list = NULL; static struct linked_list* list = NULL;
static struct linked_list* list2 = NULL;
static char A[2] = { 'A', 0 }; static char A[2] = { 'A', 0 };
static char B[2] = { 'B', 0 }; static char B[2] = { 'B', 0 };
static char C[2] = { 'C', 0 }; static char C[2] = { 'C', 0 };
static char A2[2] = { 'a', 0 };
static char B2[2] = { 'b', 0 };
static char C2[2] = { 'c', 0 };
static void null_free(void* ptr) static void null_free(void* ptr)
{ {
@ -124,6 +130,83 @@ EXO_TEST(list_clear, {
return list->size == 0 && list->first == 0 && list->last == 0 && list->iterator == 0; return list->size == 0 && list->first == 0 && list->last == 0 && list->iterator == 0;
}); });
static int g_remove_flag = 0;
static void null_free_inc_flag(void* ptr)
{
(void) ptr;
g_remove_flag++;
}
EXO_TEST(list_remove_first_1_1,
{
list_append(list, A);
list_append(list, B);
list_append(list, C);
return list->size == 3;
});
EXO_TEST(list_remove_first_1_2,
{
g_remove_flag = 0;
list_remove_first(list, null_free_inc_flag);
return list->size == 2 && g_remove_flag == 1;
});
EXO_TEST(list_remove_first_1_3,
{
list_remove_first(list, NULL);
return list->size == 1;
});
EXO_TEST(list_remove_first_1_4,
{
list_remove_first(list, NULL);
return list->size == 0;
});
EXO_TEST(list_remove_first_1_5,
{
list_remove_first(list, NULL);
return list->size == 0;
});
EXO_TEST(list_append_list_1,
{
list_append(list, A);
list_append(list, B);
list_append(list, C);
list2 = list_create();
list_append(list2, A2);
list_append(list2, B2);
list_append(list2, C2);
return list->size == 3 && list2->size == 3;
});
EXO_TEST(list_append_list_2,
{
list_append_list(list, list2);
return list->size == 6 && list2->size == 0;
});
EXO_TEST(list_append_list_3,
{
list_destroy(list2);
return list_get_index(list, 0) == A &&
list_get_index(list, 1) == B &&
list_get_index(list, 2) == C &&
list_get_index(list, 3) == A2 &&
list_get_index(list, 4) == B2 &&
list_get_index(list, 5) == C2;
});
EXO_TEST(list_clear_list_last,
{
list_clear(list, &null_free);
return 1;
});
EXO_TEST(list_destroy_1, { EXO_TEST(list_destroy_1, {
list_destroy(list); list_destroy(list);

View File

@ -107,6 +107,7 @@ static const char test_utf_seq_6[] = { 0xE2, 0x82, 0xAC, 0x00}; // valid
static const char test_utf_seq_7[] = { 0xC2, 0x32, 0x00}; // invalid static const char test_utf_seq_7[] = { 0xC2, 0x32, 0x00}; // invalid
static const char test_utf_seq_8[] = { 0xE2, 0x82, 0x32, 0x00}; // invalid static const char test_utf_seq_8[] = { 0xE2, 0x82, 0x32, 0x00}; // invalid
static const char test_utf_seq_9[] = { 0xE2, 0x32, 0x82, 0x00}; // invalid static const char test_utf_seq_9[] = { 0xE2, 0x32, 0x82, 0x00}; // invalid
static const char test_utf_seq_10[] = { 0xF0, 0x9F, 0x98, 0x81, 0x00}; // valid
EXO_TEST(utf8_valid_4, { return is_valid_utf8(test_utf_seq_1); }); EXO_TEST(utf8_valid_4, { return is_valid_utf8(test_utf_seq_1); });
EXO_TEST(utf8_valid_5, { return !is_valid_utf8(test_utf_seq_2); }); EXO_TEST(utf8_valid_5, { return !is_valid_utf8(test_utf_seq_2); });
@ -117,5 +118,61 @@ EXO_TEST(utf8_valid_9, { return is_valid_utf8(test_utf_seq_6); });
EXO_TEST(utf8_valid_10, { return !is_valid_utf8(test_utf_seq_7); }); EXO_TEST(utf8_valid_10, { return !is_valid_utf8(test_utf_seq_7); });
EXO_TEST(utf8_valid_11, { return !is_valid_utf8(test_utf_seq_8); }); EXO_TEST(utf8_valid_11, { return !is_valid_utf8(test_utf_seq_8); });
EXO_TEST(utf8_valid_12, { return !is_valid_utf8(test_utf_seq_9); }); EXO_TEST(utf8_valid_12, { return !is_valid_utf8(test_utf_seq_9); });
EXO_TEST(utf8_valid_13, { return is_valid_utf8(test_utf_seq_10); });
// Limits of utf-8
static const char test_utf_seq_11[] = { 0x7F, 0x00 }; // valid last 7-bit character
static const char test_utf_seq_12[] = { 0x80, 0x00 }; // invalid truncated string
static const char test_utf_seq_13[] = { 0xBF, 0x00 }; // invalid truncated string
static const char test_utf_seq_14[] = { 0xC0, 0x80, 0x00 }; // invalid out of 2 bytes range
static const char test_utf_seq_15[] = { 0xC1, 0x7F, 0x00 }; // invalid out of 2 bytes range
static const char test_utf_seq_16[] = { 0xC2, 0x00 }; // invalid truncated string
static const char test_utf_seq_17[] = { 0xC2, 0x80, 0x00 }; // valid
static const char test_utf_seq_18[] = { 0xDF, 0xBF, 0x00 }; // valid
static const char test_utf_seq_19[] = { 0xE0, 0x80, 0x80, 0x00 }; // invalid out of 3 bytes range
static const char test_utf_seq_20[] = { 0xE0, 0x9F, 0xBF, 0x00 }; // invalid out of 3 bytes range
static const char test_utf_seq_21[] = { 0xE0, 0x00 }; // invalid truncated string
static const char test_utf_seq_22[] = { 0xE0, 0xA0, 0x00 }; // invalid truncated string
static const char test_utf_seq_23[] = { 0xE0, 0xA0, 0x80, 0x00 }; // valid
static const char test_utf_seq_24[] = { 0xEC, 0x9F, 0xBF, 0x00 }; // valid
static const char test_utf_seq_25[] = { 0xED, 0xA0, 0x80, 0x00 }; // invalid surrogate
static const char test_utf_seq_26[] = { 0xED, 0xBF, 0xBF, 0x00 }; // invalid surrogate
static const char test_utf_seq_27[] = { 0xEF, 0x80, 0x80, 0x00 }; // valid
static const char test_utf_seq_28[] = { 0xEF, 0xBF, 0xBF, 0x00 }; // valid
static const char test_utf_seq_29[] = { 0xF0, 0x80, 0x80, 0x80, 0x00 }; // invalid out of 4 bytes range
static const char test_utf_seq_30[] = { 0xF0, 0x8F, 0xBF, 0xBF, 0x00 }; // invalid out of 4 bytes range
static const char test_utf_seq_31[] = { 0xF0, 0x00 }; // invalid truncated string
static const char test_utf_seq_32[] = { 0xF0, 0x90, 0x00 }; // invalid truncated string
static const char test_utf_seq_33[] = { 0xF0, 0x90, 0x80, 0x00 }; // invalid truncated string
static const char test_utf_seq_34[] = { 0xF0, 0x90, 0x80, 0x80, 0x00 }; // valid
static const char test_utf_seq_35[] = { 0xF4, 0x8F, 0xBF, 0xBF, 0x00 }; // valid
static const char test_utf_seq_36[] = { 0xF4, 0x90, 0x80, 0x80, 0x00 }; // invalid out of 4 bytes range
static const char test_utf_seq_37[] = { 0xFF, 0xBF, 0xBF, 0xBF, 0x00 }; // invalid out of 4 bytes range
EXO_TEST(utf8_valid_14, { return is_valid_utf8(test_utf_seq_11); });
EXO_TEST(utf8_valid_15, { return !is_valid_utf8(test_utf_seq_12); });
EXO_TEST(utf8_valid_16, { return !is_valid_utf8(test_utf_seq_13); });
EXO_TEST(utf8_valid_17, { return !is_valid_utf8(test_utf_seq_14); });
EXO_TEST(utf8_valid_18, { return !is_valid_utf8(test_utf_seq_15); });
EXO_TEST(utf8_valid_19, { return !is_valid_utf8(test_utf_seq_16); });
EXO_TEST(utf8_valid_20, { return is_valid_utf8(test_utf_seq_17); });
EXO_TEST(utf8_valid_21, { return is_valid_utf8(test_utf_seq_18); });
EXO_TEST(utf8_valid_22, { return !is_valid_utf8(test_utf_seq_19); });
EXO_TEST(utf8_valid_23, { return !is_valid_utf8(test_utf_seq_20); });
EXO_TEST(utf8_valid_24, { return !is_valid_utf8(test_utf_seq_21); });
EXO_TEST(utf8_valid_25, { return !is_valid_utf8(test_utf_seq_22); });
EXO_TEST(utf8_valid_26, { return is_valid_utf8(test_utf_seq_23); });
EXO_TEST(utf8_valid_27, { return is_valid_utf8(test_utf_seq_24); });
EXO_TEST(utf8_valid_28, { return !is_valid_utf8(test_utf_seq_25); });
EXO_TEST(utf8_valid_29, { return !is_valid_utf8(test_utf_seq_26); });
EXO_TEST(utf8_valid_30, { return is_valid_utf8(test_utf_seq_27); });
EXO_TEST(utf8_valid_31, { return is_valid_utf8(test_utf_seq_28); });
EXO_TEST(utf8_valid_32, { return !is_valid_utf8(test_utf_seq_29); });
EXO_TEST(utf8_valid_33, { return !is_valid_utf8(test_utf_seq_30); });
EXO_TEST(utf8_valid_34, { return !is_valid_utf8(test_utf_seq_31); });
EXO_TEST(utf8_valid_35, { return !is_valid_utf8(test_utf_seq_32); });
EXO_TEST(utf8_valid_36, { return !is_valid_utf8(test_utf_seq_33); });
EXO_TEST(utf8_valid_37, { return is_valid_utf8(test_utf_seq_34); });
EXO_TEST(utf8_valid_38, { return is_valid_utf8(test_utf_seq_35); });
EXO_TEST(utf8_valid_39, { return !is_valid_utf8(test_utf_seq_36); });
EXO_TEST(utf8_valid_40, { return !is_valid_utf8(test_utf_seq_37); });

View File

@ -116,29 +116,35 @@ EXO_TEST(rbtree_iterate_10000, {
struct rb_node* n = (struct rb_node*) rb_tree_first(tree); struct rb_node* n = (struct rb_node*) rb_tree_first(tree);
while (n) while (n)
{ {
struct rb_node* p = n;
n = (struct rb_node*) rb_tree_next(tree); n = (struct rb_node*) rb_tree_next(tree);
i++; i++;
} }
return i == MAX_NODES; return i == MAX_NODES;
}); });
static int freed_nodes = 0;
static void free_node(struct rb_node* n) static void free_node(struct rb_node* n)
{ {
hub_free((void*) n->key); hub_free((void*) n->key);
hub_free((void*) n->value); hub_free((void*) n->value);
freed_nodes += 1;
} }
EXO_TEST(rbtree_remove_5000, { EXO_TEST(rbtree_remove_10000, {
int i = 0; int i;
struct rb_node* n = (struct rb_node*) rb_tree_first(tree); int j;
for (i = 0; i < MAX_NODES ; i += 2) for (j = 0; j < 2; j++)
{
for (i = j; i < MAX_NODES; i += 2)
{ {
const char* key = uhub_itoa(i); const char* key = uhub_itoa(i);
rb_tree_remove_node(tree, key, &free_node); rb_tree_remove_node(tree, key, &free_node);
} }
return 1; }
return freed_nodes == MAX_NODES;
}); });
EXO_TEST(rbtree_destroy_1, {
rb_tree_destroy(tree);
return 1;
});

View File

@ -117,3 +117,9 @@ EXO_TEST(timer_process_5_events_1,{
g_now = 4; g_now = 4;
return timeout_queue_process(g_queue, g_now) == g_triggered; return timeout_queue_process(g_queue, g_now) == g_triggered;
}); });
EXO_TEST(timer_shutdown,{
timeout_queue_shutdown(g_queue);
hub_free(g_queue);
return 1;
});

View File

@ -0,0 +1,43 @@
#!/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/

View File

@ -0,0 +1,10 @@
#!/bin/sh
sudo apt-get update -qq
sudo apt-get install -qq cmake
if [ "${CONFIG}" = "full" ]; then
sudo apt-get install -qq libsqlite3-dev libssl-dev
fi

View File

@ -3,7 +3,7 @@
# #
# SQLITE3_FOUND True if sqlite3 got found # SQLITE3_FOUND True if sqlite3 got found
# SQLITE3_INCLUDEDIR Location of sqlite3 headers # SQLITE3_INCLUDEDIR Location of sqlite3 headers
# SQLITE3_LIBRARIES List of libaries to use sqlite3 # SQLITE3_LIBRARIES List of libraries to use sqlite3
# SQLITE3_DEFINITIONS Definitions to compile sqlite3 # SQLITE3_DEFINITIONS Definitions to compile sqlite3
# #
# Copyright (c) 2007 Juha Tuomala <tuju@iki.fi> # Copyright (c) 2007 Juha Tuomala <tuju@iki.fi>
@ -44,6 +44,7 @@ IF ( NOT SQLITE3_FOUND AND NOT PKG_CONFIG_FOUND )
/opt/local/lib /opt/local/lib
/sw/lib /sw/lib
/usr/lib /usr/lib
/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}
/usr/local/lib /usr/local/lib
/usr/lib64 /usr/lib64
/usr/local/lib64 /usr/local/lib64

2
debian/control vendored
View File

@ -20,5 +20,5 @@ Description: High performance ADC p2p hub
- Advanced access control support - Advanced access control support
- Easy configuration - Easy configuration
. .
Homepage: http://www.uhub.org/ Homepage: https://www.uhub.org/

2
debian/copyright vendored
View File

@ -12,7 +12,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
On Debian GNU/Linux systems, the complete text of the GNU General Public On Debian GNU/Linux systems, the complete text of the GNU General Public
License can be found in `/usr/share/common-licenses/GPL'. License can be found in `/usr/share/common-licenses/GPL'.

View File

@ -67,7 +67,7 @@ Accepting new users
| | | | | |
| V | | V |
| --------------------- --------------------- | --------------------- ---------------------
| | Send password | ------> | Reveive and check | | | Send password | ------> | Receive and check |
| | request, if needed| | password. | | | request, if needed| | password. |
| --------------------- --------------------- | --------------------- ---------------------
| | | |

View File

@ -1,7 +1,7 @@
How to compile: How to compile:
--------------- ---------------
See the official compiling howto: http://www.uhub.org/compile.php See the official compiling howto: https://www.uhub.org/compile.php
Prerequisites Prerequisites
@ -12,7 +12,7 @@ Before you try to compile µHub, please make sure the following prerequisites ar
* openssl > 0.9.8 (or use "make USE_SSL=NO") * openssl > 0.9.8 (or use "make USE_SSL=NO")
* sqlite > 3.x * sqlite > 3.x
or read http://www.uhub.org/compile.php for more info. or read https://www.uhub.org/compile.php for more info.
Linux, Mac OSX, FreeBSD, NetBSD and OpenBSD Linux, Mac OSX, FreeBSD, NetBSD and OpenBSD

View File

@ -31,7 +31,7 @@ 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}', as well as the same message via TCP.
If the client receives the message via UDP, it should now be able to determine the type of NAT. If the client receives the message via UDP, it should now be able to determine the type of NAT.
If the client receives the message via TCP only it knows it has a firewall blocking incomming communication. If the client receives the message via TCP only it knows it has a firewall blocking incoming communication.
If the client does not receive the message, it should assume a firewall is blocking all UDP communication, If the client does not receive the message, it should assume a firewall is blocking all UDP communication,
and resume in passive mode. and resume in passive mode.

View File

@ -1,8 +1,6 @@
Getting started guide Getting started guide
--------------------- ---------------------
(This document is maintained at http://www.extatic.org/uhub/getstarted.html )
Unpack your binaries Unpack your binaries
Example: Example:
@ -17,6 +15,7 @@ Create configuration files.
If no configuration files are created, uhub will use the default parameters, so you can skip this step if you are in a hurry to see it run. If no configuration files are created, uhub will use the default parameters, so you can skip this step if you are in a hurry to see it run.
As root, or use sudo. As root, or use sudo.
% mkdir /etc/uhub % mkdir /etc/uhub
% cp doc/uhub.conf /etc/uhub % cp doc/uhub.conf /etc/uhub
% cp doc/users.conf /etc/uhub % cp doc/users.conf /etc/uhub
@ -32,8 +31,11 @@ NOTE: It is important to use the "adc://" prefix, and the port number when using
If you modify the configuration files in /etc/uhub you will have to notify uhub by sending a HUP signal. If you modify the configuration files in /etc/uhub you will have to notify uhub by sending a HUP signal.
% ps aux | grep uhub
% kill -HUP <pid of uhub> % kill -HUP <pid of uhub>
Or, for the lazy people Or, for the lazy people
% killall -HUP uhub % killall -HUP uhub
In order to run uhub as a daemon, start it with the -f switch which will make it fork into the background. In order to run uhub as a daemon, start it with the -f switch which will make it fork into the background.
@ -41,17 +43,25 @@ In addition, use the -l to specify a log file instead of stdout. One can also sp
if one wishes to run uhub as a specific user using the -u and -g switches. if one wishes to run uhub as a specific user using the -u and -g switches.
Example: Example:
% uhub -f -l mylog.txt -u nobody -g nogroup
% uhub -f -l mylog.txt -u nobody -g nogroup
If you are planning to more than 1024 users on hub, you must increase the max number of file descriptors allowed. If you are planning to more than 1024 users on hub, you must increase the max number of file descriptors allowed.
This limit needs to be higher than the configured max_users in uhub.conf. This limit needs to be higher than the configured max_users in uhub.conf.
In linux can add the following lines to /etc/security/limits.conf (allows for ~4000 users) In Linux can add the following lines to /etc/security/limits.conf (allows for ~4000 users)
* soft nofile 4096 * soft nofile 4096
* hard nofile 4096 * hard nofile 4096
Or, you can use (as root): Or, you can use (as root):
% ulimit -n 4096 % ulimit -n 4096
You can interact with uhub in your hub main chat using the `!` prefix, followed by a command:
Example :
* to display help and the command you can use:
!help
Your mileage may vary -- Good luck! Your mileage may vary -- Good luck!

View File

@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
# #
# chkconfig: - 91 35 # chkconfig: - 91 35
# description: Starts and stops the Uhub ( http://www.uhub.org ) daemons on RHEL\CentOS \ # description: Starts and stops the Uhub ( https://www.uhub.org ) daemons on RHEL\CentOS \
# used to provide p2p network services. # used to provide p2p network services.
# #
# pidfile: /var/run/uhub.pid # pidfile: /var/run/uhub.pid

View File

@ -13,6 +13,15 @@
# #
plugin /usr/lib/uhub/mod_auth_sqlite.so "file=/etc/uhub/users.db" plugin /usr/lib/uhub/mod_auth_sqlite.so "file=/etc/uhub/users.db"
# Topic commands.
# Note: "topic" == "hub description" (as configured in uhub.conf)
#
# !topic - change the topic (op required)
# !showtopic - show the topic
# !resettopic - reset the topic to the default (op required)
#
# This plugins takes no parameters.
#plugin /usr/lib/uhub/mod_topic.so
# Log file writer # Log file writer
# #
@ -23,6 +32,7 @@ plugin /usr/lib/uhub/mod_logging.so "file=/var/log/uhub.log"
# A simple example plugin # A simple example plugin
#plugin /usr/lib/uhub/mod_example.so #plugin /usr/lib/uhub/mod_example.so
# A plugin sending a welcome message. # A plugin sending a welcome message.
# #
# This plugin provides the following commands: # This plugin provides the following commands:
@ -31,7 +41,7 @@ plugin /usr/lib/uhub/mod_logging.so "file=/var/log/uhub.log"
# #
# Parameters: # Parameters:
# motd: path/filename for the welcome message (message of the day) # motd: path/filename for the welcome message (message of the day)
# rules: path/filenam for the rules file # rules: path/filename for the rules file
# #
# NOTE: The files MUST exist, however if you do not wish to provide one then these parameters can be omitted. # NOTE: The files MUST exist, however if you do not wish to provide one then these parameters can be omitted.
# #
@ -59,4 +69,3 @@ plugin /usr/lib/uhub/mod_welcome.so "motd=/etc/uhub/motd.txt rules=/etc/uhub/rul
# history_default: when !history is provided without arguments, then this default number of messages are returned. # history_default: when !history is provided without arguments, then this default number of messages are returned.
# history_connect: the number of chat history messages to send when users connect (0 = do not send any history) # history_connect: the number of chat history messages to send when users connect (0 = do not send any history)
plugin /usr/lib/uhub/mod_chat_history.so "history_max=200 history_default=10 history_connect=5" plugin /usr/lib/uhub/mod_chat_history.so "history_max=200 history_default=10 history_connect=5"

View File

@ -39,4 +39,4 @@ is one of 'admin', 'super', 'op', 'user'
This program was written by Jan Vidar Krey <janvidar@extatic.org> This program was written by Jan Vidar Krey <janvidar@extatic.org>
.SH "BUG REPORTS" .SH "BUG REPORTS"
If you find a bug in uhub please report it to If you find a bug in uhub please report it to
.B http://bugs.extatic.org/ .B https://github.com/janvidar/uhub/issues

View File

@ -69,4 +69,4 @@ To run uhub as a daemon, and log to a file:
This program was written by Jan Vidar Krey <janvidar@extatic.org> This program was written by Jan Vidar Krey <janvidar@extatic.org>
.SH "BUG REPORTS" .SH "BUG REPORTS"
If you find a bug in uhub please report it to If you find a bug in uhub please report it to
.B http://bugs.extatic.org/ .B https://github.com/janvidar/uhub/issues

View File

@ -2,10 +2,10 @@
# You should normally place this file in /etc/uhub/uhub.conf # You should normally place this file in /etc/uhub/uhub.conf
# and customize some of the settings below. # and customize some of the settings below.
# #
# This file is read only to the uhub deamon, and if you # This file is read only to the uhub daemon, and if you
# make changes to it while uhub is running you can send a # make changes to it while uhub is running you can send a
# HUP signal to it ( $ killall -HUP uhub ), to reparse configuration (only on UNIX). # HUP signal to it ( $ killall -HUP uhub ), to reparse configuration (only on UNIX).
# All configuration directives: http://www.uhub.org/config.php # All configuration directives: https://www.uhub.org/config.php
# Bind to this port and address # Bind to this port and address
# server_bind_addr=any means listen to "::" if IPv6 is supported # server_bind_addr=any means listen to "::" if IPv6 is supported
@ -104,11 +104,11 @@ msg_auth_invalid_password = Password is wrong
msg_auth_user_not_found = User not found in password database msg_auth_user_not_found = User not found in password database
msg_user_share_size_low = User is not sharing enough msg_user_share_size_low = User is not sharing enough
msg_user_share_size_high = User is sharing too much msg_user_share_size_high = User is sharing too much
msg_user_slots_low = User have too few upload slots msg_user_slots_low = User has too few upload slots
msg_user_slots_high = User have too many upload slots msg_user_slots_high = User has too many upload slots
msg_user_hub_limit_low = User is on too few hubs msg_user_hub_limit_low = User is on too few hubs
msg_user_hub_limit_high = User is on too many hubs msg_user_hub_limit_high = User is on too many hubs
msg_error_no_memory = No memory msg_error_no_memory = Out of memory
msg_user_flood_chat = Chat flood detected, messages are dropped. msg_user_flood_chat = Chat flood detected, messages are dropped.
msg_user_flood_connect = Connect flood detected, connection refused. msg_user_flood_connect = Connect flood detected, connection refused.
msg_user_flood_search = Search flood detected, search is stopped. msg_user_flood_search = Search flood detected, search is stopped.

View File

@ -4,7 +4,7 @@
inherit eutils inherit eutils
if [ "$PV" != "9999" ]; then if [ "$PV" != "9999" ]; then
SRC_URI="http://www.extatic.org/downloads/uhub/${P}-src.tar.bz2" SRC_URI="https://www.extatic.org/downloads/uhub/${P}-src.tar.bz2"
KEYWORDS="~amd64 ~x86" KEYWORDS="~amd64 ~x86"
else else
inherit git inherit git
@ -16,7 +16,7 @@ fi
EAPI="2" EAPI="2"
DESCRIPTION="High performance ADC hub" DESCRIPTION="High performance ADC hub"
HOMEPAGE="http://www.uhub.org/" HOMEPAGE="https://www.uhub.org/"
LICENSE="GPL-3" LICENSE="GPL-3"
SLOT="0" SLOT="0"

View File

@ -5,7 +5,7 @@ Release: 2
License: GPLv3 License: GPLv3
Group: Networking/File transfer Group: Networking/File transfer
Source: uhub-%{version}.tar.gz Source: uhub-%{version}.tar.gz
URL: http://www.uhub.org URL: https://www.uhub.org
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
BuildRequires: sqlite-devel BuildRequires: sqlite-devel
@ -80,7 +80,7 @@ rm -rf $RPM_BUILD_ROOT
if [ $1 -gt 1 ] ; then if [ $1 -gt 1 ] ; then
/etc/rc.d/init.d/uhub restart >/dev/null || : /etc/rc.d/init.d/uhub restart >/dev/null || :
fi fi
# need more informations about add services and users in system # need more information about add services and users in system
/usr/sbin/adduser -M -d /tmp -G nobody -s /sbin/nologin -c 'The Uhub ADC p2p hub Daemon' uhub >/dev/null 2>&1 ||: /usr/sbin/adduser -M -d /tmp -G nobody -s /sbin/nologin -c 'The Uhub ADC p2p hub Daemon' uhub >/dev/null 2>&1 ||:
# write SSL create # write SSL create
echo "PLS see /usr/share/doc/uhub/" echo "PLS see /usr/share/doc/uhub/"

View File

@ -8,7 +8,7 @@ start on filesystem or runlevel [2345]
stop on runlevel [!2345] stop on runlevel [!2345]
# Allow the service to respawn, but if its happening too often # Allow the service to respawn, but if its happening too often
# (10 times in 5 seconds) theres a problem and we should stop trying. # (10 times in 5 seconds) there's a problem and we should stop trying.
respawn respawn
respawn limit 10 5 respawn limit 10 5

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2013, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -34,7 +34,6 @@ typedef uint32_t fourcc_t;
/* default welcome protocol support message, as sent by this server */ /* default welcome protocol support message, as sent by this server */
#define ADC_PROTO_SUPPORT "ADBASE ADTIGR ADPING ADUCMD" #define ADC_PROTO_SUPPORT "ADBASE ADTIGR ADPING ADUCMD"
#define ADC_PROTO_LINK_SUPPORT "ADTIGR ADLINK"
/* Server sent commands */ /* Server sent commands */
#define ADC_CMD_ISID FOURCC('I','S','I','D') #define ADC_CMD_ISID FOURCC('I','S','I','D')
@ -102,12 +101,6 @@ typedef uint32_t fourcc_t;
#define ADC_CMD_HCMD FOURCC('H','C','M','D') #define ADC_CMD_HCMD FOURCC('H','C','M','D')
#define ADC_CMD_ICMD FOURCC('I','C','M','D') #define ADC_CMD_ICMD FOURCC('I','C','M','D')
/* Link commands */
#define ADC_CMD_LSUP FOURCC('L','S','U','P') /* Link support handshake */
#define ADC_CMD_LINF FOURCC('L','I','N','F') /* Hub link info */
#define ADC_CMD_LGPA FOURCC('L','G','P','A') /* Hub link get password */
#define ADC_CMD_LPAS FOURCC('L','P','A','S') /* Hub link password */
#define ADC_CMD_LSTA FOURCC('L','S','T','A') /* Hub link status */
#define ADC_INF_FLAG_IPV4_ADDR "I4" /* ipv4 address */ #define ADC_INF_FLAG_IPV4_ADDR "I4" /* ipv4 address */
#define ADC_INF_FLAG_IPV6_ADDR "I6" /* ipv6 address */ #define ADC_INF_FLAG_IPV6_ADDR "I6" /* ipv6 address */
@ -118,12 +111,15 @@ typedef uint32_t fourcc_t;
#define ADC_INF_FLAG_CLIENT_ID "ID" /* client id, aka CID */ #define ADC_INF_FLAG_CLIENT_ID "ID" /* client id, aka CID */
#define ADC_INF_FLAG_NICK "NI" /* nick name */ #define ADC_INF_FLAG_NICK "NI" /* nick name */
#define ADC_INF_FLAG_DESCRIPTION "DE" /* user description */ #define ADC_INF_FLAG_DESCRIPTION "DE" /* user description */
#define ADC_INF_FLAG_USER_AGENT "VE" /* software version */
#define ADC_INF_FLAG_USER_AGENT_PRODUCT "AP" /* software name */
#define ADC_INF_FLAG_USER_AGENT_VERSION "VE" /* software version */
#define ADC_INF_FLAG_SUPPORT "SU" /* support (extensions, feature cast) */ #define ADC_INF_FLAG_SUPPORT "SU" /* support (extensions, feature cast) */
#define ADC_INF_FLAG_SHARED_SIZE "SS" /* size of total files shared in bytes */ #define ADC_INF_FLAG_SHARED_SIZE "SS" /* size of total files shared in bytes */
#define ADC_INF_FLAG_SHARED_FILES "SF" /* number of files shared */ #define ADC_INF_FLAG_SHARED_FILES "SF" /* number of files shared */
#define ADC_INF_FLAG_UPLOAD_SPEED "US" /* maximum upload speed acheived in bytes/sec */ #define ADC_INF_FLAG_UPLOAD_SPEED "US" /* maximum upload speed achieved in bytes/sec */
#define ADC_INF_FLAG_DOWNLOAD_SPEED "DS" /* maximum download speed acheived in bytes/sec */ #define ADC_INF_FLAG_DOWNLOAD_SPEED "DS" /* maximum download speed achieved in bytes/sec */
#define ADC_INF_FLAG_UPLOAD_SLOTS "SL" /* maximum upload slots (concurrent uploads) */ #define ADC_INF_FLAG_UPLOAD_SLOTS "SL" /* maximum upload slots (concurrent uploads) */
#define ADC_INF_FLAG_AUTO_SLOTS "AS" /* automatic slot if upload speed is less than this in bytes/sec */ #define ADC_INF_FLAG_AUTO_SLOTS "AS" /* automatic slot if upload speed is less than this in bytes/sec */
#define ADC_INF_FLAG_AUTO_SLOTS_MAX "AM" /* maximum number of automatic slots */ #define ADC_INF_FLAG_AUTO_SLOTS_MAX "AM" /* maximum number of automatic slots */
@ -138,7 +134,7 @@ typedef uint32_t fourcc_t;
#define ADC_MSG_FLAG_PRIVATE "PM" /* message is a private message */ #define ADC_MSG_FLAG_PRIVATE "PM" /* message is a private message */
#define ADC_SCH_FLAG_INCLUDE "AN" /* include given search term */ #define ADC_SCH_FLAG_INCLUDE "AN" /* include given search term */
#define ADC_SCH_FLAG_EXCLUDE "NO" /* exclude given serach term */ #define ADC_SCH_FLAG_EXCLUDE "NO" /* exclude given search term */
#define ADC_SCH_FLAG_FILE_EXTENSION "EX" /* search only for files with the given file extension */ #define ADC_SCH_FLAG_FILE_EXTENSION "EX" /* search only for files with the given file extension */
#define ADC_SCH_FLAG_FILE_TYPE "TY" /* search only for files with this file type (separate type) */ #define ADC_SCH_FLAG_FILE_TYPE "TY" /* search only for files with this file type (separate type) */
#define ADC_SCH_FLAG_LESS_THAN "LE" /* search for files with this size or less */ #define ADC_SCH_FLAG_LESS_THAN "LE" /* search for files with this size or less */
@ -163,6 +159,7 @@ typedef uint32_t fourcc_t;
#define ADC_CLIENT_TYPE_BOT "1" #define ADC_CLIENT_TYPE_BOT "1"
#define ADC_CLIENT_TYPE_REGISTERED_USER "2" #define ADC_CLIENT_TYPE_REGISTERED_USER "2"
#define ADC_CLIENT_TYPE_OPERATOR "4" #define ADC_CLIENT_TYPE_OPERATOR "4"
#define ADC_CLIENT_TYPE_HUBBOT "5" /* 1 + 4 */
#define ADC_CLIENT_TYPE_SUPER_USER "12" /* 8 + 4 */ #define ADC_CLIENT_TYPE_SUPER_USER "12" /* 8 + 4 */
#define ADC_CLIENT_TYPE_ADMIN "20" /* 16 + 4 = hub owner */ #define ADC_CLIENT_TYPE_ADMIN "20" /* 16 + 4 = hub owner */
#define ADC_CLIENT_TYPE_HUB "32" /* the hub itself */ #define ADC_CLIENT_TYPE_HUB "32" /* the hub itself */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2013, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -24,7 +24,6 @@
uhub_assert(X); \ uhub_assert(X); \
uhub_assert(X->cache); \ uhub_assert(X->cache); \
uhub_assert(X->capacity); \ uhub_assert(X->capacity); \
uhub_assert(X->length); \
uhub_assert(X->length <= X->capacity); \ uhub_assert(X->length <= X->capacity); \
uhub_assert(X->references > 0); \ uhub_assert(X->references > 0); \
uhub_assert(X->length == strlen(X->cache)); uhub_assert(X->length == strlen(X->cache));
@ -178,7 +177,6 @@ int adc_msg_get_arg_offset(struct adc_message* msg)
case 'I': case 'I':
case 'H': case 'H':
case 'L':
return 4; return 4;
case 'B': case 'B':
@ -284,23 +282,19 @@ struct adc_message* adc_msg_copy(const struct adc_message* cmd)
if (cmd->feature_cast_include) if (cmd->feature_cast_include)
{ {
copy->feature_cast_include = list_create(); copy->feature_cast_include = list_create();
tmp = list_get_first(cmd->feature_cast_include); LIST_FOREACH(char*, tmp, cmd->feature_cast_include,
while (tmp)
{ {
list_append(copy->feature_cast_include, hub_strdup(tmp)); list_append(copy->feature_cast_include, hub_strdup(tmp));
tmp = list_get_next(cmd->feature_cast_include); });
}
} }
if (cmd->feature_cast_exclude) if (cmd->feature_cast_exclude)
{ {
copy->feature_cast_exclude = list_create(); copy->feature_cast_exclude = list_create();
tmp = list_get_first(cmd->feature_cast_exclude); LIST_FOREACH(char*, tmp, cmd->feature_cast_exclude,
while (tmp)
{ {
list_append(copy->feature_cast_exclude, hub_strdup(tmp)); list_append(copy->feature_cast_exclude, hub_strdup(tmp));
tmp = list_get_next(cmd->feature_cast_exclude); });
}
} }
ADC_MSG_ASSERT(copy); ADC_MSG_ASSERT(copy);
@ -316,7 +310,7 @@ struct adc_message* adc_msg_parse_verify(struct hub_user* u, const char* line, s
if (!command) if (!command)
return 0; return 0;
if (command->source && (!u || command->source != u->id.sid)) if (command->source && (!u || (command->source != u->id.sid && !auth_cred_is_unrestricted(u->credentials))))
{ {
LOG_DEBUG("Command does not match user's SID (command->source=%d, user->id.sid=%d)", command->source, (u ? u->id.sid : 0)); LOG_DEBUG("Command does not match user's SID (command->source=%d, user->id.sid=%d)", command->source, (u ? u->id.sid : 0));
adc_msg_free(command); adc_msg_free(command);
@ -384,9 +378,8 @@ struct adc_message* adc_msg_parse(const char* line, size_t length)
ok = 0; ok = 0;
break; break;
case 'I': /* Hub to client */ case 'I':
case 'H': /* Clien to hub */ case 'H':
case 'L': /* hub to hub Link */
ok = (length > 3); ok = (length > 3);
break; break;
@ -789,16 +782,6 @@ int adc_msg_add_argument(struct adc_message* cmd, const char* string)
return 0; return 0;
} }
int adc_msg_add_argument_string(struct adc_message* cmd, const char* string)
{
char* arg = adc_msg_escape(string);
int ret;
if (!arg) return -1;
ret = adc_msg_add_argument(cmd, arg);
hub_free(arg);
return ret;
}
char* adc_msg_get_argument(struct adc_message* cmd, int offset) char* adc_msg_get_argument(struct adc_message* cmd, int offset)
{ {
@ -880,21 +863,21 @@ int adc_msg_get_argument_index(struct adc_message* cmd, const char prefix[2])
size_t adc_msg_escape_length(const char* str) int adc_msg_escape_length(const char* str)
{ {
size_t add = 0; int add = 0;
size_t n = 0; int n = 0;
for (; str[n]; n++) for (; str[n]; n++)
if (str[n] == ' ' || str[n] == '\n' || str[n] == '\\') add++; if (str[n] == ' ' || str[n] == '\n' || str[n] == '\\') add++;
return n + add; return n + add;
} }
size_t adc_msg_unescape_length(const char* str) int adc_msg_unescape_length(const char* str)
{ {
size_t add = 0; int add = 0;
size_t n = 0; int n = 0;
size_t escape = 0; int escape = 0;
for (; str[n]; n++) for (; str[n]; n++)
{ {
if (escape) if (escape)
@ -1010,20 +993,3 @@ char* adc_msg_escape(const char* string)
return str; return str;
} }
enum msg_type adc_msg_get_type(const struct adc_message* msg)
{
switch (msg->cache[0])
{
case 'B': return msg_type_client_broadcast;
case 'C': return msg_type_client_to_client;
case 'D': return msg_type_client_direct;
case 'E': return msg_type_client_echo;
case 'F': return msg_type_client_feature;
case 'H': return msg_type_client_to_hub;
case 'I': return msg_type_hub_to_client;
case 'L': return msg_type_link_to_link;
case 'U': return msg_type_hub_to_client_udp;
}
return msg_type_unknown;
}

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2013, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -43,20 +43,6 @@ enum msg_status_level
status_level_fatal = 2, /* Fatal error (disconnect) */ status_level_fatal = 2, /* Fatal error (disconnect) */
}; };
enum msg_type
{
msg_type_unknown = 0,
msg_type_client_broadcast = 'B',
msg_type_client_to_client = 'C',
msg_type_client_direct = 'D',
msg_type_client_echo = 'E',
msg_type_client_feature = 'F',
msg_type_client_to_hub = 'H',
msg_type_hub_to_client = 'I',
msg_type_link_to_link = 'L',
msg_type_hub_to_client_udp = 'U',
};
/** /**
* Increase the reference counter for an ADC message struct. * Increase the reference counter for an ADC message struct.
* NOTE: Always use the returned value, and not the passed value, as * NOTE: Always use the returned value, and not the passed value, as
@ -65,7 +51,7 @@ enum msg_type
extern struct adc_message* adc_msg_incref(struct adc_message* msg); extern struct adc_message* adc_msg_incref(struct adc_message* msg);
/** /**
* Decrease the reference counter, and free the memory when apropriate. * Decrease the reference counter, and free the memory when appropriate.
*/ */
extern void adc_msg_free(struct adc_message* msg); extern void adc_msg_free(struct adc_message* msg);
@ -173,7 +159,7 @@ extern char* adc_msg_get_argument(struct adc_message* cmd, int offset);
* *
* @arg prefix a 2 character argument prefix * @arg prefix a 2 character argument prefix
* @arg string must be escaped (see adc_msg_escape). * @arg string must be escaped (see adc_msg_escape).
* @return 0 if successful, or -1 if an error occured. * @return 0 if successful, or -1 if an error occurred.
*/ */
extern int adc_msg_replace_named_argument(struct adc_message* cmd, const char prefix[2], const char* string); extern int adc_msg_replace_named_argument(struct adc_message* cmd, const char prefix[2], const char* string);
@ -181,23 +167,16 @@ extern int adc_msg_replace_named_argument(struct adc_message* cmd, const char pr
* Append an argument * Append an argument
* *
* @arg string must be escaped (see adc_msg_escape). * @arg string must be escaped (see adc_msg_escape).
* @return 0 if successful, or -1 if an error occured (out of memory). * @return 0 if successful, or -1 if an error occurred (out of memory).
*/ */
extern int adc_msg_add_argument(struct adc_message* cmd, const char* string); extern int adc_msg_add_argument(struct adc_message* cmd, const char* string);
/**
* Append a string argumnent.
* The string will automatcally be escaped.
* @return 0 if successful, or -1 if an error occured (out of memory).
*/
extern int adc_msg_add_argument_string(struct adc_message* cmd, const char* string);
/** /**
* Append a named argument * Append a named argument
* *
* @arg prefix a 2 character argument prefix * @arg prefix a 2 character argument prefix
* @arg string must be escaped (see adc_msg_escape). * @arg string must be escaped (see adc_msg_escape).
* @return 0 if successful, or -1 if an error occured (out of memory). * @return 0 if successful, or -1 if an error occurred (out of memory).
*/ */
extern int adc_msg_add_named_argument(struct adc_message* cmd, const char prefix[2], const char* string); extern int adc_msg_add_named_argument(struct adc_message* cmd, const char prefix[2], const char* string);
@ -207,7 +186,7 @@ extern int adc_msg_add_named_argument(struct adc_message* cmd, const char prefix
* *
* @arg prefix a 2 character argument prefix * @arg prefix a 2 character argument prefix
* @arg string must NOT be escaped * @arg string must NOT be escaped
* @return 0 if successful, or -1 if an error occured (out of memory). * @return 0 if successful, or -1 if an error occurred (out of memory).
*/ */
extern int adc_msg_add_named_argument_string(struct adc_message* cmd, const char prefix[2], const char* string); extern int adc_msg_add_named_argument_string(struct adc_message* cmd, const char prefix[2], const char* string);
@ -237,12 +216,6 @@ extern int adc_msg_unescape_to_target(const char* string, char* target, size_t t
*/ */
extern char* adc_msg_escape(const char* string); extern char* adc_msg_escape(const char* string);
/**
* Calculate the length str would be after escaping.
* Does not include any NULL terminator.
*/
size_t adc_msg_escape_length(const char* str);
/** /**
* This will ensure a newline is at the end of the command. * This will ensure a newline is at the end of the command.
*/ */
@ -261,6 +234,4 @@ void adc_msg_unterminate(struct adc_message* cmd);
*/ */
int adc_msg_get_arg_offset(struct adc_message* msg); int adc_msg_get_arg_offset(struct adc_message* msg);
enum msg_type adc_msg_get_type(const struct adc_message* msg);
#endif /* HAVE_UHUB_COMMAND_H */ #endif /* HAVE_UHUB_COMMAND_H */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2009, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2009, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2010, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -170,6 +170,9 @@ static int acl_parse_line(char* line, int line_count, void* ptr_data)
LOG_DEBUG("acl_parse_line: '%s'", line); LOG_DEBUG("acl_parse_line: '%s'", line);
ACL_ADD_USER("bot", handle->users, auth_cred_bot); ACL_ADD_USER("bot", handle->users, auth_cred_bot);
ACL_ADD_USER("ubot", handle->users, auth_cred_ubot);
ACL_ADD_USER("opbot", handle->users, auth_cred_opbot);
ACL_ADD_USER("opubot", handle->users, auth_cred_opubot);
ACL_ADD_USER("user_admin", handle->users, auth_cred_admin); ACL_ADD_USER("user_admin", handle->users, auth_cred_admin);
ACL_ADD_USER("user_super", handle->users, auth_cred_super); ACL_ADD_USER("user_super", handle->users, auth_cred_super);
ACL_ADD_USER("user_op", handle->users, auth_cred_operator); ACL_ADD_USER("user_op", handle->users, auth_cred_operator);
@ -330,13 +333,11 @@ struct auth_info* acl_get_access_info(struct hub_info* hub, const char* name)
} }
#define STR_LIST_CONTAINS(LIST, STR) \ #define STR_LIST_CONTAINS(LIST, STR) \
str = (char*) list_get_first(LIST); \ LIST_FOREACH(char*, str, LIST, \
while (str) \
{ \ { \
if (strcasecmp(str, STR) == 0) \ if (strcasecmp(str, STR) == 0) \
return 1; \ return 1; \
str = (char*) list_get_next(LIST); \ }); \
} \
return 0 return 0
int acl_is_cid_banned(struct acl_handle* handle, const char* data) int acl_is_cid_banned(struct acl_handle* handle, const char* data)
@ -400,34 +401,28 @@ int acl_user_unban_cid(struct acl_handle* handle, const char* cid)
int acl_is_ip_banned(struct acl_handle* handle, const char* ip_address) int acl_is_ip_banned(struct acl_handle* handle, const char* ip_address)
{ {
struct ip_addr_encap raw; struct ip_addr_encap raw;
struct ip_range* info = (struct ip_range*) list_get_first(handle->networks); struct ip_range* info;
ip_convert_to_binary(ip_address, &raw);
while (info) ip_convert_to_binary(ip_address, &raw);
LIST_FOREACH(struct ip_range*, info, handle->networks,
{ {
if (ip_in_range(&raw, info)) if (ip_in_range(&raw, info))
{
return 1; return 1;
} });
info = (struct ip_range*) list_get_next(handle->networks);
}
return 0; return 0;
} }
int acl_is_ip_nat_override(struct acl_handle* handle, const char* ip_address) int acl_is_ip_nat_override(struct acl_handle* handle, const char* ip_address)
{ {
struct ip_addr_encap raw; struct ip_addr_encap raw;
struct ip_range* info = (struct ip_range*) list_get_first(handle->nat_override); struct ip_range* info;
ip_convert_to_binary(ip_address, &raw);
while (info) ip_convert_to_binary(ip_address, &raw);
LIST_FOREACH(struct ip_range*, info, handle->nat_override,
{ {
if (ip_in_range(&raw, info)) if (ip_in_range(&raw, info))
{
return 1; return 1;
} });
info = (struct ip_range*) list_get_next(handle->nat_override);
}
return 0; return 0;
} }

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2010, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2012, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -26,7 +26,7 @@ static void hub_command_args_free(struct hub_command* cmd)
if (!cmd->args) if (!cmd->args)
return; return;
for (data = (struct hub_command_arg_data*) list_get_first(cmd->args); data; data = (struct hub_command_arg_data*) list_get_next(cmd->args)) LIST_FOREACH(struct hub_command_arg_data*, data, cmd->args,
{ {
switch (data->type) switch (data->type)
{ {
@ -39,7 +39,7 @@ static void hub_command_args_free(struct hub_command* cmd)
default: default:
break; break;
} }
} });
list_clear(cmd->args, hub_free); list_clear(cmd->args, hub_free);
list_destroy(cmd->args); list_destroy(cmd->args);
@ -64,6 +64,7 @@ static enum command_parse_status command_extract_arguments(struct hub_info* hub,
char* token = NULL; char* token = NULL;
char* tmp = NULL; char* tmp = NULL;
size_t size = 0; size_t size = 0;
size_t offset = 0;
struct hub_command_arg_data* data = NULL; struct hub_command_arg_data* data = NULL;
enum command_parse_status status = cmd_status_ok; enum command_parse_status status = cmd_status_ok;
@ -77,15 +78,15 @@ static enum command_parse_status command_extract_arguments(struct hub_info* hub,
if (greedy) if (greedy)
{ {
size = 1; size = 1;
for (tmp = (char*) list_get_first(tokens); tmp; tmp = (char*) list_get_next(tokens)) LIST_FOREACH(char*, tmp, tokens, { size += (strlen(tmp) + 1); });
size += (strlen(tmp) + 1);
token = hub_malloc_zero(size); token = hub_malloc_zero(size);
while ((tmp = list_get_first(tokens))) while ((tmp = list_get_first(tokens)))
{ {
if (*token) if (offset > 0)
strcat(token, " "); token[offset++] = ' ';
strcat(token, tmp); memcpy(token + offset, tmp, strlen(tmp));
offset += strlen(tmp);
list_remove(tokens, tmp); list_remove(tokens, tmp);
hub_free(tmp); hub_free(tmp);
} }

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2012, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -30,7 +30,7 @@ struct command_base;
* *
* @param cbase Command base pointer. * @param cbase Command base pointer.
* @param user User who invoked the command. * @param user User who invoked the command.
* @param message The message that is to be interpreted as a command (including the invokation prefix '!' or '+') * @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. * @return a hub_command that must be freed with command_free(). @See struct hub_command.
*/ */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2012, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -31,8 +31,6 @@ static int send_command_not_found(struct command_base* cbase, struct hub_user* u
static int send_command_syntax_error(struct command_base* cbase, struct hub_user* user); static int send_command_syntax_error(struct command_base* cbase, struct hub_user* user);
static int send_command_missing_arguments(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd); static int send_command_missing_arguments(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd);
static void null_free(void* ptr) { }
struct command_base struct command_base
{ {
struct hub_info* hub; struct hub_info* hub;
@ -98,14 +96,14 @@ struct command_handle* command_handler_lookup(struct command_base* cbase, const
struct command_handle* handler = NULL; struct command_handle* handler = NULL;
size_t prefix_len = strlen(prefix); size_t prefix_len = strlen(prefix);
for (handler = (struct command_handle*) list_get_first(cbase->handlers); handler; handler = (struct command_handle*) list_get_next(cbase->handlers)) LIST_FOREACH(struct command_handle*, handler, cbase->handlers,
{ {
if (prefix_len != handler->length) if (prefix_len != handler->length)
continue; continue;
if (!memcmp(prefix, handler->prefix, handler->length)) if (!memcmp(prefix, handler->prefix, handler->length))
return handler; return handler;
} });
return NULL; return NULL;
} }
@ -292,7 +290,7 @@ static int command_help(struct command_base* cbase, struct hub_user* user, struc
{ {
cbuf_append(buf, "Available commands:\n"); cbuf_append(buf, "Available commands:\n");
for (command = (struct command_handle*) list_get_first(cbase->handlers); command; command = (struct command_handle*) list_get_next(cbase->handlers)) LIST_FOREACH(struct command_handle*, command, cbase->handlers,
{ {
if (command_is_available(command, user->credentials)) if (command_is_available(command, user->credentials))
{ {
@ -301,7 +299,7 @@ static int command_help(struct command_base* cbase, struct hub_user* user, struc
cbuf_append(buf, " "); cbuf_append(buf, " ");
cbuf_append_format(buf, " - %s\n", command->description); cbuf_append_format(buf, " - %s\n", command->description);
} }
} });
} }
else else
{ {
@ -424,7 +422,7 @@ static int command_whoip(struct command_base* cbase, struct hub_user* user, stru
ret = uman_get_user_by_addr(cbase->hub->users, users, arg->data.range); ret = uman_get_user_by_addr(cbase->hub->users, users, arg->data.range);
if (!ret) if (!ret)
{ {
list_clear(users, &null_free); list_clear(users, NULL);
list_destroy(users); list_destroy(users);
return command_status(cbase, user, cmd, cbuf_create_const("No users found.")); return command_status(cbase, user, cmd, cbuf_create_const("No users found."));
} }
@ -432,16 +430,14 @@ static int command_whoip(struct command_base* cbase, struct hub_user* user, stru
buf = cbuf_create(128 + ((MAX_NICK_LEN + INET6_ADDRSTRLEN + 5) * ret)); buf = cbuf_create(128 + ((MAX_NICK_LEN + INET6_ADDRSTRLEN + 5) * ret));
cbuf_append_format(buf, "*** %s: Found %d match%s:\n", cmd->prefix, ret, ((ret != 1) ? "es" : "")); cbuf_append_format(buf, "*** %s: Found %d match%s:\n", cmd->prefix, ret, ((ret != 1) ? "es" : ""));
u = (struct hub_user*) list_get_first(users); LIST_FOREACH(struct hub_user*, u, users,
while (u)
{ {
cbuf_append_format(buf, "%s (%s)\n", u->id.nick, user_get_address(u)); cbuf_append_format(buf, "%s (%s)\n", u->id.nick, user_get_address(u));
u = (struct hub_user*) list_get_next(users); });
}
cbuf_append(buf, "\n"); cbuf_append(buf, "\n");
send_message(cbase, user, buf); send_message(cbase, user, buf);
list_clear(users, &null_free); list_clear(users, NULL);
list_destroy(users); list_destroy(users);
return 0; return 0;
} }
@ -462,8 +458,7 @@ static int command_broadcast(struct command_base* cbase, struct hub_user* user,
memcpy(from_sid, sid_to_string(user->id.sid), sizeof(from_sid)); memcpy(from_sid, sid_to_string(user->id.sid), sizeof(from_sid));
memcpy(pm_flag + 2, from_sid, sizeof(from_sid)); memcpy(pm_flag + 2, from_sid, sizeof(from_sid));
target = (struct hub_user*) list_get_first(cbase->hub->users->list); LIST_FOREACH(struct hub_user*, target, cbase->hub->users->list,
while (target)
{ {
if (target != user) if (target != user)
{ {
@ -480,8 +475,7 @@ static int command_broadcast(struct command_base* cbase, struct hub_user* user,
route_to_user(cbase->hub, target, command); route_to_user(cbase->hub, target, command);
adc_msg_free(command); adc_msg_free(command);
} }
target = (struct hub_user*) list_get_next(cbase->hub->users->list); });
}
cbuf_append_format(buf, "*** %s: Delivered to " PRINTF_SIZE_T " user%s", cmd->prefix, recipients, (recipients != 1 ? "s" : "")); cbuf_append_format(buf, "*** %s: Delivered to " PRINTF_SIZE_T " user%s", cmd->prefix, recipients, (recipients != 1 ? "s" : ""));
send_message(cbase, user, buf); send_message(cbase, user, buf);
@ -513,8 +507,7 @@ static int command_log(struct command_base* cbase, struct hub_user* user, struct
command_status(cbase, user, cmd, buf); command_status(cbase, user, cmd, buf);
buf = cbuf_create(MAX_HELP_LINE); buf = cbuf_create(MAX_HELP_LINE);
log = (struct hub_logout_info*) list_get_first(messages); LIST_FOREACH(struct hub_logout_info*, log, messages,
while (log)
{ {
const char* address = ip_convert_to_string(&log->addr); const char* address = ip_convert_to_string(&log->addr);
int show = 0; int show = 0;
@ -538,8 +531,7 @@ static int command_log(struct command_base* cbase, struct hub_user* user, struct
send_message(cbase, user, buf); send_message(cbase, user, buf);
buf = cbuf_create(MAX_HELP_LINE); buf = cbuf_create(MAX_HELP_LINE);
} }
log = (struct hub_logout_info*) list_get_next(messages); });
}
if (search_len) if (search_len)
{ {

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2012, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2010, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -102,7 +102,7 @@ static int config_parse_line(char* line, int line_count, void* ptr_data)
data = strip_white_space(data); data = strip_white_space(data);
data = strip_off_quotes(data); data = strip_off_quotes(data);
if (!*key /*|| !*data*/) if (!*key || !*data)
{ {
LOG_FATAL("Configuration parse error on line %d", line_count); LOG_FATAL("Configuration parse error on line %d", line_count);
return -1; return -1;

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2010, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */

View File

@ -1,289 +0,0 @@
#!/usr/bin/perl -w
use strict;
use XML::DOM;
sub write_c_header(@);
sub write_sql_dump(@);
sub get_data($);
my $dump_to_sql = 0;
# initialize parser and read the file
my $input = "./config.xml";
my $parser = new XML::DOM::Parser;
my $tree = $parser->parsefile($input) || die "Unable to parse XML file.";
# Get data
my $nodes = $tree->getElementsByTagName("option");
my @options = ();
for (my $i = 0; $i < $nodes->getLength; $i++)
{
my @data = get_data($nodes->item($i));
push @options, \@data;
}
write_c_header(@options);
write_sql_dump(@options) if ($dump_to_sql);
my $config_defaults = "void config_defaults(struct hub_config* config)\n{\n";
my $config_apply = "static int apply_config(struct hub_config* config, char* key, char* data, int line_count)\n{\n\tint max = 0;\n\tint min = 0;\n\n";
my $config_free = "void free_config(struct hub_config* config)\n{\n";
my $config_dump = "void dump_config(struct hub_config* config, int ignore_defaults)\n{\n";
foreach my $option (@options)
{
my ($type, $name, $default, $advanced, $short, $desc, $since, $example, $check, $ifdef) = @$option;
my $string = ($type =~ /(string|file|message)/);
my $min = undef;
my $max = undef;
my $regexp = undef;
if (defined $check)
{
$min = $check->getAttribute("min");
$max = $check->getAttribute("max");
$regexp = $check->getAttribute("regexp");
$max = undef if ($max eq "");
$min = undef if ($min eq "");
$regexp = undef if ($regexp eq "");
}
$config_defaults .= "#ifdef $ifdef\n" if ($ifdef ne "");
$config_defaults .= "\tconfig->$name = ";
$config_defaults .= "hub_strdup(\"" if ($string);
$config_defaults .= $default;
$config_defaults .= "\")" if ($string);
$config_defaults .= ";\n";
$config_defaults .= "#endif /* $ifdef */\n" if ($ifdef ne "");
$config_apply .= "#ifdef $ifdef\n" if ($ifdef ne "");
$config_apply .= "\tif (!strcmp(key, \"" . $name . "\"))\n\t{\n";
if ($type eq "int")
{
$config_apply .= "\t\tmin = $min;\n" if (defined $min);
$config_apply .= "\t\tmax = $max;\n" if (defined $max);
$config_apply .= "\t\tif (!apply_integer(key, data, &config->$name, ";
if (defined $min) { $config_apply .= "&min"; } else { $config_apply .= "0"; }
$config_apply .= ", ";
if (defined $max) { $config_apply .= "&max"; } else { $config_apply .= "0"; }
$config_apply .= "))\n";
}
elsif ($type eq "boolean")
{
$config_apply .= "\t\tif (!apply_boolean(key, data, &config->$name))\n";
}
elsif ($string)
{
$config_apply .="\t\tif (!apply_string(key, data, &config->$name, (char*) \"\"))\n";
}
$config_apply .= "\t\t{\n" .
"\t\t\tLOG_ERROR(\"Configuration parse error on line %d\", line_count);\n" .
"\t\t\treturn -1;\n" .
"\t\t}\n" .
"\t\treturn 0;\n" .
"\t}\n";
$config_apply .= "#endif /* $ifdef */\n" if ($ifdef ne "");
$config_apply .= "\n";
if ($string)
{
$config_free .= "#ifdef $ifdef\n" if ($ifdef ne "");
$config_free .= "\thub_free(config->" . $name . ");\n";
$config_free .= "#endif /* $ifdef */\n" if ($ifdef ne "");
$config_free .= "\n";
}
my $out = "%s";
my $val = "config->$name";
my $test = "config->$name != $default";
$out = "%d" if ($type eq "int");
$val = "config->$name ? \"yes\" : \"no\"" if ($type eq "boolean");
if ($string)
{
$out = "\\\"%s\\\"";
$test = "strcmp(config->$name, \"$default\") != 0";
}
$config_dump .= "#ifdef $ifdef\n" if ($ifdef ne "");
$config_dump .= "\tif (!ignore_defaults || $test)\n";
$config_dump .= "\t\tfprintf(stdout, \"$name = $out\\n\", $val);\n";
$config_dump .= "#endif /* $ifdef */\n" if ($ifdef ne "");
$config_dump .= "\n";
}
$config_apply .= "\t/* Still here -- unknown directive */\n";
$config_apply .= "\tLOG_ERROR(\"Unknown configuration directive: '%s'\", key);\n";
$config_apply .= "\treturn -1;\n";
$config_apply .= "}\n\n";
$config_defaults .= "}\n\n";
$config_free .= "}\n\n";
$config_dump .= "}\n\n";
open GENIMPL, ">gen_config.c" || die "Unable to write source file";
print GENIMPL "/* THIS FILE IS AUTOGENERATED - DO NOT CHANGE IT! */\n\n";
print GENIMPL $config_defaults;
print GENIMPL $config_apply;
print GENIMPL $config_free;
print GENIMPL $config_dump;
sub get_data($)
{
my $p = shift;
my $short = "";
my $example = "";
my $description = "";
my $since = "";
my $ifdef = "";
$short = $p->getElementsByTagName("short")->item(0)->getFirstChild()->getData() if ($p->getElementsByTagName("short")->getLength());
$since = $p->getElementsByTagName("since")->item(0)->getFirstChild()->getData() if ($p->getElementsByTagName("since")->getLength());
$example = $p->getElementsByTagName("example")->item(0)->getFirstChild()->getData() if ($p->getElementsByTagName("example")->getLength());
$description = $p->getElementsByTagName("description")->item(0)->getFirstChild()->getData() if ($p->getElementsByTagName("description")->getLength());
my $check = $p->getElementsByTagName("check")->item(0);
$ifdef = $p->getElementsByTagName("ifdef")->item(0)->getFirstChild()->getData() if ($p->getElementsByTagName("ifdef")->getLength());
my @data = (
$p->getAttribute("type"),
$p->getAttribute("name"),
$p->getAttribute("default"),
$p->getAttribute("advanced"),
$short,
$description,
$since,
$example,
$check,
$ifdef
);
return @data;
}
# Write header file
sub write_c_header(@)
{
my @data = @_;
open GENHEAD, ">gen_config.h" || die "Unable to write header file";
print GENHEAD "/* THIS FILE IS AUTOGENERATED - DO NOT CHANGE IT! */\n\n";
print GENHEAD "struct hub_config\n{\n";
foreach my $option (@data)
{
my ($type, $name, $default, $advanced, $short, $desc, $since, $example, $check, $ifdef) = @$option;
my $string = ($type =~ /(string|file|message)/);
print GENHEAD "#ifdef $ifdef\n" if ($ifdef ne "");
print GENHEAD "\t";
print GENHEAD "int " if ($type eq "int");
print GENHEAD "int " if ($type eq "boolean");
print GENHEAD "char*" if ($string);
print GENHEAD " " . $name . ";";
my $comment = "";
if ($type eq "message")
{
$comment = "\"" . $default . "\"";
}
elsif (defined $short && length $short > 0)
{
$comment = $short;
if (defined $default)
{
$comment .= " (default: ";
$comment .= "\"" if ($string);
$comment .= $default;
$comment .= "\"" if ($string);
$comment .= ")";
}
}
if (length $comment > 0)
{
my $pad = "";
for (my $i = length $name; $i < 32; $i++)
{
$pad .= " ";
}
$comment = $pad . "/*<<< " . $comment . " */";
}
print GENHEAD $comment . "\n";
print GENHEAD "#endif /* $ifdef */\n" if ($ifdef ne "");
}
print GENHEAD "};\n\n";
}
sub write_sql_dump(@)
{
my @data = @_;
# Write SQL dump code
open GENSQL, ">gen_config.sql" || die "Unable to write SQL dump";
print GENSQL "START TRANSACTION;\n\n
DROP TABLE uhub_config IF EXISTS;\n\n
CREATE TABLE uhub_config (
name VARCHAR(32) UNIQUE NOT NULL,
defaultValue TINYTEXT NOT NULL,
description LONGTEXT NOT NULL,
type TINYTEXT NOT NULL,
advanced BOOLEAN,
example LONGTEXT,
since TINYTEXT
);\n\n";
foreach my $option (@data)
{
my ($type, $name, $default, $advanced, $short, $desc, $since, $example, $check, $ifdef) = @$option;
if ($type =~ /(string|file|message)/ )
{
$default = "\\\"$default\\\"";
}
$desc =~ s/\"/\\\"/g;
$type =~ s/^int$/integer/;
my $stmt = "INSERT INTO uhub_config VALUES(";
$stmt .= "\"$name\", ";
$stmt .= "\"$default\", ";
$stmt .= "\"$desc\", ";
$stmt .= "\"$type\", ";
if (defined $example)
{
my $example_str = $example;
$example_str =~ s/\\/\\\\/g;
$example_str =~ s/\"/\\\"/g;
$stmt .= "\"$example_str\", ";
} else {
$stmt .= "NULL, ";
}
if (defined $since) {
$stmt .= "\"$since\", ";
} else {
$stmt .= "NULL, ";
}
if (defined $advanced) {
$stmt .= "\"$advanced\"";
} else {
$stmt .= "NULL";
}
$stmt .= ");\n";
print GENSQL $stmt;
}
print GENSQL "\n\nCOMMIT;\n\n";
}

255
src/core/config.py Executable file
View File

@ -0,0 +1,255 @@
#!/usr/bin/env python
"""
uhub - A tiny ADC p2p connection hub
Copyright (C) 2007-2013, Jan Vidar Krey
"""
from xml.dom import minidom, Node
from datetime import datetime
import argparse
class OptionParseError(Exception):
pass
class Option(object):
def _get(self, node, name):
self.__dict__[name] = None
if (node.getElementsByTagName(name)):
self.__dict__[name] = node.getElementsByTagName(name)[0].firstChild.nodeValue
def _attr(self, node, name, required = False):
try:
return node.attributes[name].value
except Exception:
pass
if (required):
raise OptionParseError("Option %s is required but not found!" % name)
return None
def __init__(self, node):
self.otype = self._attr(node, 'type', True)
# Verify that the type is known
if not self.otype in ["int", "boolean", "string", "message", "file"]:
raise OptionParseError("Option %s has unknown type" % self.name)
self.name = self._attr(node, 'name', True)
self.default = self._attr(node, 'default', True)
self.advanced = self._attr(node, 'advanced', False)
self.is_string = self.otype in ["string", "message", "file"]
self._get(node, "short");
self._get(node, "description");
self._get(node, "syntax");
self._get(node, "since");
self._get(node, "example");
check = node.getElementsByTagName("check")
if (check):
check = node.getElementsByTagName("check")[0]
self.check_min = self._attr(check, 'min', False)
self.check_max = self._attr(check, 'max', False)
self.check_regexp = self._attr(check, 'regexp', False)
else:
self.check_min = None
self.check_max = None
self.check_regexp = None
def c_type(self):
if self.otype == "boolean":
return "int"
elif self.is_string:
return "char*"
else:
return self.otype
def sql_type(self):
if self.otype == "int":
return "integer"
return self.otype
def c_comment(self):
comment = ""
if (self.otype == "message"):
comment = self.formatted_default()
elif len(self.short):
comment = "%s (default: %s)" % (self.short, self.formatted_default())
return comment
def formatted_default(self):
if self.is_string:
return "\"%s\"" % self.default
return self.default
class SourceGenerator(object):
def __init__(self, filename, cppStyle = True):
print ("Generating %s..." % filename)
self.f = open(filename, 'w');
def write_header(self, Comment = True):
if Comment:
s = "/*\n * uhub - A tiny ADC p2p connection hub\n"
s += " * Copyright (C) 2007-%s, Jan Vidar Krey\n *\n" % datetime.now().strftime("%Y")
s += " * THIS FILE IS AUTOGENERATED - DO NOT MODIFY\n"
s += " * Created %s, by config.py\n */\n\n" % datetime.now().strftime("%Y-%m-%d %H:%M")
self.f.write(s)
class CHeaderGenerator(SourceGenerator):
def __init__(self, filename):
super(CHeaderGenerator, self).__init__(filename)
def _write_declaration(self, option):
comment = ' ' * (32 - len(option.name)) + "/*<<< %s */" % option.c_comment()
ptype = option.c_type() + (5 - len(option.c_type())) * ' '
self.f.write("\t%(type)s %(name)s;%(comment)s\n" % {
"type": ptype,
"name": option.name,
"comment": comment})
def write(self, options):
self.write_header()
self.f.write("struct hub_config\n{\n")
for option in options:
self._write_declaration(option)
self.f.write("};\n\n")
class CSourceGenerator(SourceGenerator):
def __init__(self, filename):
super(CSourceGenerator, self).__init__(filename)
def _write_default_impl(self, option):
s = "\tconfig->%s = " % option.name
if option.is_string:
s += "hub_strdup(%s);\n" % option.formatted_default()
else:
s += option.formatted_default() + ";\n"
self.f.write(s)
def _write_apply_impl(self, option):
s = "\tif (!strcmp(key, \"%s\"))\n\t{\n" % option.name
if option.otype == "int":
s_min = "0"
s_max = "0"
if (option.check_min):
s += "\t\tmin = %s;\n" % option.check_min
s_min = "&min"
if (option.check_max):
s += "\t\tmax = %s;\n" % option.check_max
s_max = "&max"
s+= "\t\tif (!apply_integer(key, data, &config->%s, %s, %s))\n" % (option.name, s_min, s_max)
elif option.otype == "boolean":
s += "\t\tif (!apply_boolean(key, data, &config->%s))\n" % option.name
elif option.is_string:
s += "\t\tif (!apply_string(key, data, &config->%s, (char*) \"\"))\n" % option.name
s += "\t\t{\n\t\t\tLOG_ERROR(\"Configuration parse error on line %d\", line_count);\n\t\t\treturn -1;\n\t\t}\n\t\treturn 0;\n\t}\n\n"
self.f.write(s)
def _write_free_impl(self, option):
if option.is_string:
self.f.write("\thub_free(config->%s);\n\n" % option.name)
def _write_dump_impl(self, option):
s = ""
fmt = "%s"
val = "config->%s" % option.name
test = "config->%s != %s" % (option.name, option.default)
if (option.otype == "int"):
fmt = "%d"
elif (option.otype == "boolean"):
val = "config->%s ? \"yes\" : \"no\"" % option.name
elif (option.is_string):
fmt = "\\\"%s\\\"";
test = "strcmp(config->%s, %s) != 0" % (option.name, option.formatted_default())
s += "\tif (!ignore_defaults || %s)\n" % test;
s += "\t\tfprintf(stdout, \"%s = %s\\n\", %s);\n\n" % (option.name, fmt, val)
self.f.write(s)
def write(self, options):
self.write_header()
self.f.write("void config_defaults(struct hub_config* config)\n{\n")
for option in options:
self._write_default_impl(option)
self.f.write("}\n\n")
self.f.write("static int apply_config(struct hub_config* config, char* key, char* data, int line_count)\n{\n\tint max = 0;\n\tint min = 0;\n\n")
for option in options:
self._write_apply_impl(option)
self.f.write("\t/* Still here -- unknown directive */\n\tLOG_ERROR(\"Unknown configuration directive: '%s'\", key);\n\treturn -1;\n}\n\n")
self.f.write("void free_config(struct hub_config* config)\n{\n")
for option in options:
self._write_free_impl(option)
self.f.write("}\n\n")
self.f.write("void dump_config(struct hub_config* config, int ignore_defaults)\n{\n")
for option in options:
self._write_dump_impl(option)
self.f.write("}\n\n")
class SqlWebsiteDocsGenerator(SourceGenerator):
def __init__(self, filename, sqlite_support = False):
self.sqlite_support = sqlite_support
super(SqlWebsiteDocsGenerator, self).__init__(filename)
def _sql_escape(self, s):
if self.sqlite_support:
return s.replace("\"", "\"\"")
return s.replace("\"", "\\\"")
def _write_or_null(self, s):
if (not s or len(s) == 0):
return "NULL"
return "\"%s\"" % self._sql_escape(s)
def write(self, options):
self.write_header(False)
table = "uhub_config"
s = ""
if not self.sqlite_support:
s += "START TRANSACTION;\n\nDROP TABLE %(table)s IF EXISTS;" % { "table": table }
s += "\n\nCREATE TABLE %(table)s (\n\tname VARCHAR(32) UNIQUE NOT NULL,\n\tdefaultValue TINYTEXT NOT NULL,\n\tdescription LONGTEXT NOT NULL,\n\ttype TINYTEXT NOT NULL,\n\tadvanced BOOLEAN,\n\texample LONGTEXT,\n\tsince TINYTEXT\n);\n\n" % { "table": table }
self.f.write(s)
for option in options:
s = "INSERT INTO %(table)s VALUES(\"%(name)s\", \"%(default)s\", \"%(description)s\", \"%(type)s\", %(example)s, %(since)s, %(advanced)s);\n" % {
"table": table,
"name": self._sql_escape(option.name),
"default": self._sql_escape(option.formatted_default()),
"description": self._sql_escape(option.description),
"type": option.sql_type(),
"example": self._write_or_null(option.example),
"since": self._write_or_null(option.since),
"advanced": self._write_or_null(option.example),
}
self.f.write(s)
if not self.sqlite_support:
self.f.write("\n\nCOMMIT;\n\n")
if __name__ == "__main__":
# parser = argparse.ArgumentParser(description = "Configuration file parser and source generator")
# parser.add_argument("--in", nargs=1, type=argparse.FileType('r'), default="config.xml", help="Input file (config.xml)", required = True)
# parser.add_argument("--c-decl", nargs=1, type=argparse.FileType('w'), default="gen_config.h", help="Output file for C declarations (gen_config.h)")
# parser.add_argument("--c-impl", nargs=1, type=argparse.FileType('w'), default="gen_config.c", help="Output file for C implementation (gen_config.c)")
# parser.add_argument("--doc-sql", nargs=1, type=argparse.FileType('w'), help="Output file for SQL documentation")
# args = parser.parse_args()
xmldoc = minidom.parse("./config.xml")
opt_tags = xmldoc.getElementsByTagName('option')
options = []
for option in opt_tags:
opt = Option(option)
options.append(opt)
header = CHeaderGenerator("./gen_config.h");
header.write(options);
source = CSourceGenerator("./gen_config.c");
source.write(options);
#sql = SqlWebsiteDocsGenerator("./gen_config.sql", True);
#sql.write(options);

View File

@ -17,7 +17,7 @@
</option> </option>
<option name="server_bind_addr" type="string" default="any"> <option name="server_bind_addr" type="string" default="any">
<check regexp="(\d\.\d\.\d\.\d\)|(any)|(loopback)|(.*)" /><!-- FIXME: add better IPv6 regexp in the future! --> <check regexp="[\x:.]+|any|loopback" />
<short>Server bind address</short> <short>Server bind address</short>
<description><![CDATA[ <description><![CDATA[
Specify the IP address the local hub should bind to. This can be an IPv4 or IPv6 address, or one of the special addresses "any" or "loopback". <br /> Specify the IP address the local hub should bind to. This can be an IPv4 or IPv6 address, or one of the special addresses "any" or "loopback". <br />
@ -58,7 +58,7 @@
</option> </option>
<option name="server_alt_ports" type="string" default=""> <option name="server_alt_ports" type="string" default="">
<check regexp="((\d+)(,(\d+))*)?" /> <check regexp="\d+(,\d+)*" />
<short>Comma separated list of alternative ports to listen to</short> <short>Comma separated list of alternative ports to listen to</short>
<description><![CDATA[ <description><![CDATA[
In addition to the server_port the hub can listen to a list of alternative ports. In addition to the server_port the hub can listen to a list of alternative ports.
@ -111,7 +111,7 @@
<option name="register_self" type="boolean" default="0"> <option name="register_self" type="boolean" default="0">
<short>Allow users to register themselves on the hub.</short> <short>Allow users to register themselves on the hub.</short>
<description><![CDATA[ <description><![CDATA[
If this is enabled guests can register their nickname on the hub. If this is enabled guests can register their nickname on the hub using !register command.
Otherwise only operators can register users. Otherwise only operators can register users.
]]></description> ]]></description>
<since>0.4.0</since> <since>0.4.0</since>
@ -157,7 +157,7 @@
</option> </option>
<option name="redirect_addr" type="string" default=""> <option name="redirect_addr" type="string" default="">
<check regexp="(adc|adcs|dchub)://.*" /> <check regexp="(adcs?|dchub)://.*" />
<short>A common hub redirect address.</short> <short>A common hub redirect address.</short>
<description><![CDATA[ <description><![CDATA[
This is the redirect address used when the hub wants to redirect a client for not fulfilling some requirements. This is the redirect address used when the hub wants to redirect a client for not fulfilling some requirements.
@ -165,42 +165,12 @@
<since>0.3.2</since> <since>0.3.2</since>
</option> </option>
<option name="hub_link_enabled" type="boolean" default="0">
<short>Allow other hubs to link to this hub</short>
<description><![CDATA[
This allows multiple hubs to link to this hub so
that users on the different hubs appear as being on one hub.
This is useful for distributing or load balancing large hubs.
]]></description>
<since>0.5.0</since>
<ifdef>LINK_SUPPORT</ifdef>
</option>
<option name="hub_link_secret" type="string" default="">
<short>A secret token required to accept hub linking</short>
<description><![CDATA[
This should be a secret token needed to authorize hubs
linking into this one.
]]></description>
<since>0.5.0</since>
<ifdef>LINK_SUPPORT</ifdef>
</option>
<option name="hub_link_connect" type="string" default="">
<short>Connect this to hub to another hub</short>
<description><![CDATA[
The other hub must allow links to be established.
Example: uhub://host:port
]]></description>
<since>0.5.0</since>
<ifdef>LINK_SUPPORT</ifdef>
</option>
<option name="max_recv_buffer" type="int" default="4096" advanced="true" > <option name="max_recv_buffer" type="int" default="4096" advanced="true" >
<check min="1024" max="1048576" /> <check min="1024" max="1048576" />
<short>Max read buffer before parse, per user</short> <short>Max read buffer before parse, per user</short>
<description><![CDATA[ <description><![CDATA[
Maximum receive buffer allowed before commands are procesed. 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 processed. If a single ADC message exceeds this limit, it will be discarded by the hub. Use with caution.
]]></description> ]]></description>
<since>0.1.3</since> <since>0.1.3</since>
</option> </option>
@ -449,7 +419,7 @@
</option> </option>
<option name="tls_require_redirect_addr" type="string" default=""> <option name="tls_require_redirect_addr" type="string" default="">
<check regexp="(adc|adcs|dchub)://.*" /> <check regexp="(adcs?|dchub)://.*" />
<short>A redirect address in case a client connects using "adc://" when "adcs://" is required.</short> <short>A redirect address in case a client connects using "adc://" when "adcs://" is required.</short>
<description><![CDATA[ <description><![CDATA[
This is the redirect address used when the hub wants to redirect a client for not using ADCS. This is the redirect address used when the hub wants to redirect a client for not using ADCS.
@ -458,11 +428,10 @@
<since>0.3.3</since> <since>0.3.3</since>
</option> </option>
<option name="tls_certificate" type="file" default=""> <option name="tls_certificate" type="file" default="">
<short>Certificate file</short> <short>Certificate file</short>
<description><![CDATA[ <description><![CDATA[
Path to a TLS/SSL certificate (PEM format). Path to a TLS/SSL certificate or certificate chain (PEM format).
]]></description> ]]></description>
<since>0.3.0</since> <since>0.3.0</since>
</option> </option>
@ -475,6 +444,40 @@
<since>0.3.0</since> <since>0.3.0</since>
</option> </option>
<option name="tls_ciphersuite" type="string" default="ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS">
<short>List of TLS ciphers to use</short>
<description><![CDATA[
This is a colon separated list of preferred ciphers in the OpenSSL format.
]]></description>
<since>0.5.0</since>
<example><![CDATA[
<p>
High security with emphasis on forward secrecy:<br />
tls_ciphersuite = "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS"
</p>
<p>
Allow ChaCha20/Poly1305 which are secure, yet generally faster:<br />
tls_ciphersuite = "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA"
</p>
]]></example>
</option>
<option name="tls_version" type="string" default="1.2">
<short>Specify minimum TLS version supported.</short>
<description><![CDATA[
<p>
This allows you to specify the minimum TLS version the hub requires from connecting clients in order to
connect to the hub.
</p>
<p>
TLS version 1.2 is recommended and enabled by default.
TLS version 1.1 is acceptable without any known flaws, and allows for older clients to connect.
TLS version 1.0 should be avoided, even though it is the most compatible with older ADC clients.
</p>
]]></description>
<since>0.5.0</since>
</option>
<option name="file_acl" type="file" default=""> <option name="file_acl" type="file" default="">
<short>File containing access control lists</short> <short>File containing access control lists</short>
<description><![CDATA[ <description><![CDATA[
@ -564,7 +567,7 @@
</option> </option>
<option name="msg_inf_error_nick_taken" type="message" default="Nickname is already in use"> <option name="msg_inf_error_nick_taken" type="message" default="Nickname is already in use">
<description><![CDATA[This message will be sent to clients if their provided nickname is alredy in use on the hub.]]></description> <description><![CDATA[This message will be sent to clients if their provided nickname is already in use on the hub.]]></description>
<since>0.2.0</since> <since>0.2.0</since>
</option> </option>

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2009, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2009, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -77,15 +77,13 @@ int event_queue_process(struct event_queue* queue)
/* lock primary queue, and handle the primary queue messages. */ /* lock primary queue, and handle the primary queue messages. */
queue->locked = 1; queue->locked = 1;
data = (struct event_data*) list_get_first(queue->q1); LIST_FOREACH(struct event_data*, data, queue->q1,
while (data)
{ {
#ifdef EQ_DEBUG #ifdef EQ_DEBUG
eq_debug("EXEC", data); eq_debug("EXEC", data);
#endif #endif
queue->callback(queue->callback_data, data); queue->callback(queue->callback_data, data);
data = (struct event_data*) list_get_next(queue->q1); });
}
list_clear(queue->q1, event_queue_cleanup_callback); list_clear(queue->q1, event_queue_cleanup_callback);
uhub_assert(list_size(queue->q1) == 0); uhub_assert(list_size(queue->q1) == 0);
@ -94,13 +92,7 @@ int event_queue_process(struct event_queue* queue)
queue->locked = 0; queue->locked = 0;
/* transfer from secondary queue to the primary queue. */ /* transfer from secondary queue to the primary queue. */
data = (struct event_data*) list_get_first(queue->q2); list_append_list(queue->q1, queue->q2);
while (data)
{
list_remove(queue->q2, data);
list_append(queue->q1, data);
data = (struct event_data*) list_get_first(queue->q2);
}
/* if more events exist, schedule it */ /* if more events exist, schedule it */
if (list_size(queue->q1)) if (list_size(queue->q1))

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2009, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */

View File

@ -1,4 +1,10 @@
/* THIS FILE IS AUTOGENERATED - DO NOT CHANGE IT! */ /*
* uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2014, Jan Vidar Krey
*
* THIS FILE IS AUTOGENERATED - DO NOT MODIFY
* Created 2014-07-29 12:22, by config.py
*/
void config_defaults(struct hub_config* config) void config_defaults(struct hub_config* config)
{ {
@ -17,15 +23,6 @@ void config_defaults(struct hub_config* config)
config->hub_name = hub_strdup("uhub"); config->hub_name = hub_strdup("uhub");
config->hub_description = hub_strdup("no description"); config->hub_description = hub_strdup("no description");
config->redirect_addr = hub_strdup(""); config->redirect_addr = hub_strdup("");
#ifdef LINK_SUPPORT
config->hub_link_enabled = 0;
#endif /* LINK_SUPPORT */
#ifdef LINK_SUPPORT
config->hub_link_secret = hub_strdup("");
#endif /* LINK_SUPPORT */
#ifdef LINK_SUPPORT
config->hub_link_connect = hub_strdup("");
#endif /* LINK_SUPPORT */
config->max_recv_buffer = 4096; config->max_recv_buffer = 4096;
config->max_send_buffer = 131072; config->max_send_buffer = 131072;
config->max_send_buffer_soft = 98304; config->max_send_buffer_soft = 98304;
@ -54,6 +51,8 @@ void config_defaults(struct hub_config* config)
config->tls_require_redirect_addr = hub_strdup(""); config->tls_require_redirect_addr = hub_strdup("");
config->tls_certificate = hub_strdup(""); config->tls_certificate = hub_strdup("");
config->tls_private_key = hub_strdup(""); config->tls_private_key = hub_strdup("");
config->tls_ciphersuite = hub_strdup("ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS");
config->tls_version = hub_strdup("1.2");
config->file_acl = hub_strdup(""); config->file_acl = hub_strdup("");
config->file_plugins = hub_strdup(""); config->file_plugins = hub_strdup("");
config->msg_hub_full = hub_strdup("Hub is full"); config->msg_hub_full = hub_strdup("Hub is full");
@ -254,42 +253,6 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
return 0; return 0;
} }
#ifdef LINK_SUPPORT
if (!strcmp(key, "hub_link_enabled"))
{
if (!apply_boolean(key, data, &config->hub_link_enabled))
{
LOG_ERROR("Configuration parse error on line %d", line_count);
return -1;
}
return 0;
}
#endif /* LINK_SUPPORT */
#ifdef LINK_SUPPORT
if (!strcmp(key, "hub_link_secret"))
{
if (!apply_string(key, data, &config->hub_link_secret, (char*) ""))
{
LOG_ERROR("Configuration parse error on line %d", line_count);
return -1;
}
return 0;
}
#endif /* LINK_SUPPORT */
#ifdef LINK_SUPPORT
if (!strcmp(key, "hub_link_connect"))
{
if (!apply_string(key, data, &config->hub_link_connect, (char*) ""))
{
LOG_ERROR("Configuration parse error on line %d", line_count);
return -1;
}
return 0;
}
#endif /* LINK_SUPPORT */
if (!strcmp(key, "max_recv_buffer")) if (!strcmp(key, "max_recv_buffer"))
{ {
min = 1024; min = 1024;
@ -591,6 +554,26 @@ static int apply_config(struct hub_config* config, char* key, char* data, int li
return 0; return 0;
} }
if (!strcmp(key, "tls_ciphersuite"))
{
if (!apply_string(key, data, &config->tls_ciphersuite, (char*) ""))
{
LOG_ERROR("Configuration parse error on line %d", line_count);
return -1;
}
return 0;
}
if (!strcmp(key, "tls_version"))
{
if (!apply_string(key, data, &config->tls_version, (char*) ""))
{
LOG_ERROR("Configuration parse error on line %d", line_count);
return -1;
}
return 0;
}
if (!strcmp(key, "file_acl")) if (!strcmp(key, "file_acl"))
{ {
if (!apply_string(key, data, &config->file_acl, (char*) "")) if (!apply_string(key, data, &config->file_acl, (char*) ""))
@ -988,20 +971,16 @@ void free_config(struct hub_config* config)
hub_free(config->redirect_addr); hub_free(config->redirect_addr);
#ifdef LINK_SUPPORT
hub_free(config->hub_link_secret);
#endif /* LINK_SUPPORT */
#ifdef LINK_SUPPORT
hub_free(config->hub_link_connect);
#endif /* LINK_SUPPORT */
hub_free(config->tls_require_redirect_addr); hub_free(config->tls_require_redirect_addr);
hub_free(config->tls_certificate); hub_free(config->tls_certificate);
hub_free(config->tls_private_key); hub_free(config->tls_private_key);
hub_free(config->tls_ciphersuite);
hub_free(config->tls_version);
hub_free(config->file_acl); hub_free(config->file_acl);
hub_free(config->file_plugins); hub_free(config->file_plugins);
@ -1127,21 +1106,6 @@ void dump_config(struct hub_config* config, int ignore_defaults)
if (!ignore_defaults || strcmp(config->redirect_addr, "") != 0) if (!ignore_defaults || strcmp(config->redirect_addr, "") != 0)
fprintf(stdout, "redirect_addr = \"%s\"\n", config->redirect_addr); fprintf(stdout, "redirect_addr = \"%s\"\n", config->redirect_addr);
#ifdef LINK_SUPPORT
if (!ignore_defaults || config->hub_link_enabled != 0)
fprintf(stdout, "hub_link_enabled = %s\n", config->hub_link_enabled ? "yes" : "no");
#endif /* LINK_SUPPORT */
#ifdef LINK_SUPPORT
if (!ignore_defaults || strcmp(config->hub_link_secret, "") != 0)
fprintf(stdout, "hub_link_secret = \"%s\"\n", config->hub_link_secret);
#endif /* LINK_SUPPORT */
#ifdef LINK_SUPPORT
if (!ignore_defaults || strcmp(config->hub_link_connect, "") != 0)
fprintf(stdout, "hub_link_connect = \"%s\"\n", config->hub_link_connect);
#endif /* LINK_SUPPORT */
if (!ignore_defaults || config->max_recv_buffer != 4096) if (!ignore_defaults || config->max_recv_buffer != 4096)
fprintf(stdout, "max_recv_buffer = %d\n", config->max_recv_buffer); fprintf(stdout, "max_recv_buffer = %d\n", config->max_recv_buffer);
@ -1226,6 +1190,12 @@ void dump_config(struct hub_config* config, int ignore_defaults)
if (!ignore_defaults || strcmp(config->tls_private_key, "") != 0) if (!ignore_defaults || strcmp(config->tls_private_key, "") != 0)
fprintf(stdout, "tls_private_key = \"%s\"\n", config->tls_private_key); fprintf(stdout, "tls_private_key = \"%s\"\n", config->tls_private_key);
if (!ignore_defaults || strcmp(config->tls_ciphersuite, "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS") != 0)
fprintf(stdout, "tls_ciphersuite = \"%s\"\n", config->tls_ciphersuite);
if (!ignore_defaults || strcmp(config->tls_version, "1.2") != 0)
fprintf(stdout, "tls_version = \"%s\"\n", config->tls_version);
if (!ignore_defaults || strcmp(config->file_acl, "") != 0) if (!ignore_defaults || strcmp(config->file_acl, "") != 0)
fprintf(stdout, "file_acl = \"%s\"\n", config->file_acl); fprintf(stdout, "file_acl = \"%s\"\n", config->file_acl);

View File

@ -1,4 +1,10 @@
/* THIS FILE IS AUTOGENERATED - DO NOT CHANGE IT! */ /*
* uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2014, Jan Vidar Krey
*
* THIS FILE IS AUTOGENERATED - DO NOT MODIFY
* Created 2014-07-29 12:22, by config.py
*/
struct hub_config struct hub_config
{ {
@ -17,15 +23,6 @@ struct hub_config
char* hub_name; /*<<< Name of hub (default: "uhub") */ char* hub_name; /*<<< Name of hub (default: "uhub") */
char* hub_description; /*<<< Short hub description, topic or subject. (default: "no description") */ char* hub_description; /*<<< Short hub description, topic or subject. (default: "no description") */
char* redirect_addr; /*<<< A common hub redirect address. (default: "") */ char* redirect_addr; /*<<< A common hub redirect address. (default: "") */
#ifdef LINK_SUPPORT
int hub_link_enabled; /*<<< Allow other hubs to link to this hub (default: 0) */
#endif /* LINK_SUPPORT */
#ifdef LINK_SUPPORT
char* hub_link_secret; /*<<< A secret token required to accept hub linking (default: "") */
#endif /* LINK_SUPPORT */
#ifdef LINK_SUPPORT
char* hub_link_connect; /*<<< Connect this to hub to another hub (default: "") */
#endif /* LINK_SUPPORT */
int max_recv_buffer; /*<<< Max read buffer before parse, per user (default: 4096) */ int max_recv_buffer; /*<<< Max read buffer before parse, per user (default: 4096) */
int max_send_buffer; /*<<< Max send buffer before disconnect, per user (default: 131072) */ int max_send_buffer; /*<<< Max send buffer before disconnect, per user (default: 131072) */
int max_send_buffer_soft; /*<<< Max send buffer before message drops, per user (default: 98304) */ int max_send_buffer_soft; /*<<< Max send buffer before message drops, per user (default: 98304) */
@ -54,6 +51,8 @@ struct hub_config
char* tls_require_redirect_addr; /*<<< A redirect address in case a client connects using "adc://" when "adcs://" is required. (default: "") */ char* tls_require_redirect_addr; /*<<< A redirect address in case a client connects using "adc://" when "adcs://" is required. (default: "") */
char* tls_certificate; /*<<< Certificate file (default: "") */ char* tls_certificate; /*<<< Certificate file (default: "") */
char* tls_private_key; /*<<< Private key file (default: "") */ char* tls_private_key; /*<<< Private key file (default: "") */
char* tls_ciphersuite; /*<<< List of TLS ciphers to use (default: "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS") */
char* tls_version; /*<<< Specify minimum TLS version supported. (default: "1.2") */
char* file_acl; /*<<< File containing access control lists (default: "") */ char* file_acl; /*<<< File containing access control lists (default: "") */
char* file_plugins; /*<<< Plugin configuration file (default: "") */ char* file_plugins; /*<<< Plugin configuration file (default: "") */
char* msg_hub_full; /*<<< "Hub is full" */ char* msg_hub_full; /*<<< "Hub is full" */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2012, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -23,7 +23,7 @@ struct hub_info* g_hub = 0;
/* FIXME: Flood control should be done in a plugin! */ /* FIXME: Flood control should be done in a plugin! */
#define CHECK_FLOOD(TYPE, WARN) \ #define CHECK_FLOOD(TYPE, WARN) \
if (flood_control_check(&u->flood_ ## TYPE , hub->config->flood_ctl_ ## TYPE, hub->config->flood_ctl_interval, net_get_time())) \ 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 (WARN) \ if (WARN) \
{ \ { \
@ -731,7 +731,11 @@ static int load_ssl_certificates(struct hub_info* hub, struct hub_config* config
{ {
if (config->tls_enable) if (config->tls_enable)
{ {
hub->ctx = net_ssl_context_create(); hub->ctx = net_ssl_context_create(config->tls_version, config->tls_ciphersuite);
if (!hub->ctx)
return 0;
if (ssl_load_certificate(hub->ctx, config->tls_certificate) && if (ssl_load_certificate(hub->ctx, config->tls_certificate) &&
ssl_load_private_key(hub->ctx, config->tls_private_key) && ssl_load_private_key(hub->ctx, config->tls_private_key) &&
ssl_check_private_key(hub->ctx)) ssl_check_private_key(hub->ctx))
@ -787,13 +791,6 @@ struct hub_info* hub_start_service(struct hub_config* config)
} }
#endif #endif
#ifdef LINK_SUPPORT
if (config->hub_link_enabled)
{
LOG_INFO("Hub linking support enabled");
}
#endif
hub->config = config; hub->config = config;
hub->users = NULL; hub->users = NULL;
@ -841,15 +838,6 @@ struct hub_info* hub_start_service(struct hub_config* config)
// Start the hub command sub-system // Start the hub command sub-system
hub->commands = command_initialize(hub); hub->commands = command_initialize(hub);
#ifdef LINK_SUPPORT
if (*config->hub_link_connect)
{
link_connect_uri(hub, config->hub_link_connect);
}
#endif
return hub; return hub;
} }
@ -913,14 +901,24 @@ void hub_plugins_unload(struct hub_info* hub)
void hub_set_variables(struct hub_info* hub, struct acl_handle* acl) void hub_set_variables(struct hub_info* hub, struct acl_handle* acl)
{ {
char* tmp;
char* server = adc_msg_escape(PRODUCT_STRING); /* FIXME: OOM */
hub->acl = acl; hub->acl = acl;
hub->command_info = adc_msg_construct(ADC_CMD_IINF, 15); hub->command_info = adc_msg_construct(ADC_CMD_IINF, 15);
if (hub->command_info) if (hub->command_info)
{ {
adc_msg_add_named_argument(hub->command_info, ADC_INF_FLAG_CLIENT_TYPE, ADC_CLIENT_TYPE_HUB); adc_msg_add_named_argument(hub->command_info, ADC_INF_FLAG_CLIENT_TYPE, ADC_CLIENT_TYPE_HUB);
adc_msg_add_named_argument_string(hub->command_info, ADC_INF_FLAG_USER_AGENT, PRODUCT_STRING); adc_msg_add_named_argument(hub->command_info, ADC_INF_FLAG_USER_AGENT_PRODUCT, PRODUCT);
adc_msg_add_named_argument_string(hub->command_info, ADC_INF_FLAG_NICK, hub->config->hub_name); adc_msg_add_named_argument(hub->command_info, ADC_INF_FLAG_USER_AGENT_VERSION, GIT_VERSION);
adc_msg_add_named_argument_string(hub->command_info, ADC_INF_FLAG_DESCRIPTION, hub->config->hub_description);
tmp = adc_msg_escape(hub->config->hub_name);
adc_msg_add_named_argument(hub->command_info, ADC_INF_FLAG_NICK, tmp);
hub_free(tmp);
tmp = adc_msg_escape(hub->config->hub_description);
adc_msg_add_named_argument(hub->command_info, ADC_INF_FLAG_DESCRIPTION, tmp);
hub_free(tmp);
} }
hub->command_support = adc_msg_construct(ADC_CMD_ISUP, 6 + strlen(ADC_PROTO_SUPPORT)); hub->command_support = adc_msg_construct(ADC_CMD_ISUP, 6 + strlen(ADC_PROTO_SUPPORT));
@ -929,14 +927,16 @@ void hub_set_variables(struct hub_info* hub, struct acl_handle* acl)
adc_msg_add_argument(hub->command_support, ADC_PROTO_SUPPORT); adc_msg_add_argument(hub->command_support, ADC_PROTO_SUPPORT);
} }
hub->command_banner = adc_msg_construct(ADC_CMD_ISTA, 100 + adc_msg_escape_length(PRODUCT_STRING)); hub->command_banner = adc_msg_construct(ADC_CMD_ISTA, 100 + strlen(server));
if (hub->command_banner) if (hub->command_banner)
{ {
adc_msg_add_argument(hub->command_banner, "000");
if (hub->config->show_banner_sys_info) if (hub->config->show_banner_sys_info)
adc_msg_add_argument_string(hub->command_banner, "Powered by " PRODUCT_STRING " on " OPSYS "/" CPUINFO); tmp = adc_msg_escape("Powered by " PRODUCT_STRING " on " OPSYS "/" CPUINFO);
else else
adc_msg_add_argument_string(hub->command_banner, "Powered by " PRODUCT_STRING); tmp = adc_msg_escape("Powered by " PRODUCT_STRING);
adc_msg_add_argument(hub->command_banner, "000");
adc_msg_add_argument(hub->command_banner, tmp);
hub_free(tmp);
} }
if (hub_plugins_load(hub) < 0) if (hub_plugins_load(hub) < 0)
@ -947,6 +947,7 @@ void hub_set_variables(struct hub_info* hub, struct acl_handle* acl)
else else
hub->status = (hub->config->hub_enabled ? hub_status_running : hub_status_disabled); hub->status = (hub->config->hub_enabled ? hub_status_running : hub_status_disabled);
hub_free(server);
} }
@ -1324,9 +1325,7 @@ void hub_logout_log(struct hub_info* hub, struct hub_user* user)
list_append(hub->logout_info, loginfo); list_append(hub->logout_info, loginfo);
while (list_size(hub->logout_info) > (size_t) hub->config->max_logout_log) while (list_size(hub->logout_info) > (size_t) hub->config->max_logout_log)
{ {
struct hub_logout_info* entry = list_get_first(hub->logout_info); list_remove_first(hub->logout_info, hub_free);
list_remove(hub->logout_info, entry);
hub_free(entry);
} }
} }

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2012, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -27,7 +27,7 @@ enum status_message
status_msg_hub_registered_users_only = -3, /* hub is for registered users only */ status_msg_hub_registered_users_only = -3, /* hub is for registered users only */
status_msg_inf_error_nick_missing = -4, /* no nickname given */ status_msg_inf_error_nick_missing = -4, /* no nickname given */
status_msg_inf_error_nick_multiple = -5, /* multiple nicknames given */ status_msg_inf_error_nick_multiple = -5, /* multiple nicknames given */
status_msg_inf_error_nick_invalid = -6, /* generic/unkown */ status_msg_inf_error_nick_invalid = -6, /* generic/unknown */
status_msg_inf_error_nick_long = -7, /* nickname too long */ status_msg_inf_error_nick_long = -7, /* nickname too long */
status_msg_inf_error_nick_short = -8, /* nickname too short */ status_msg_inf_error_nick_short = -8, /* nickname too short */
status_msg_inf_error_nick_spaces = -9, /* nickname cannot start with spaces */ status_msg_inf_error_nick_spaces = -9, /* nickname cannot start with spaces */
@ -50,8 +50,8 @@ enum status_message
status_msg_user_share_size_high = -41, /* User is sharing too much. */ status_msg_user_share_size_high = -41, /* User is sharing too much. */
status_msg_user_slots_low = -42, /* User has too few slots open. */ status_msg_user_slots_low = -42, /* User has too few slots open. */
status_msg_user_slots_high = -43, /* User has too many slots open. */ status_msg_user_slots_high = -43, /* User has too many slots open. */
status_msg_user_hub_limit_low = -44, /* Use is on too few hubs. */ status_msg_user_hub_limit_low = -44, /* User is on too few hubs. */
status_msg_user_hub_limit_high = -45, /* Use is on too many hubs. */ status_msg_user_hub_limit_high = -45, /* User is on too many hubs. */
status_msg_proto_no_common_hash = -50, /* No common hash algorithms */ status_msg_proto_no_common_hash = -50, /* No common hash algorithms */
status_msg_proto_obsolete_adc0 = -51, /* Client is using an obsolete protocol version */ status_msg_proto_obsolete_adc0 = -51, /* Client is using an obsolete protocol version */
@ -115,10 +115,6 @@ struct hub_info
struct command_base* commands; /* Hub command handler */ struct command_base* commands; /* Hub command handler */
struct uhub_plugins* plugins; /* Plug-ins loaded for this hub instance. */ struct uhub_plugins* plugins; /* Plug-ins loaded for this hub instance. */
#ifdef LINK_SUPPORT
struct linked_list* hub_links; /* Other hubs linked to this hub */
#endif
#ifdef SSL_SUPPORT #ifdef SSL_SUPPORT
struct ssl_context_handle* ctx; struct ssl_context_handle* ctx;
#endif /* SSL_SUPPORT */ #endif /* SSL_SUPPORT */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2010, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2010, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2011, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://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 doesnt support tiger we cannot let it in! * FIXME: Only works for tiger hash. If a client doesn't support tiger we cannot let it in!
*/ */
static int check_cid(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd) static int check_cid(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
{ {
@ -337,9 +337,19 @@ static int check_logged_in(struct hub_info* hub, struct hub_user* user, struct a
{ {
if (lookup1 == lookup2) if (lookup1 == lookup2)
{ {
LOG_DEBUG("check_logged_in: exact same user is logged in: %s", user->id.nick); 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); hub_disconnect_user(hub, lookup1, quit_ghost_timeout);
return 0; }
else
{
LOG_DEBUG("check_logged_in: exact same user is already logged in: %s", user->id.nick);
return status_msg_inf_error_cid_taken;
}
} }
else else
{ {
@ -366,21 +376,37 @@ static int check_logged_in(struct hub_info* hub, struct hub_user* user, struct a
*/ */
static int check_user_agent(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd) static int check_user_agent(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
{ {
char* ua_encoded = 0; char* ua_name_encoded = 0;
char* ua = 0; char* ua_version_encoded = 0;
char* str = 0;
size_t offset = 0;
/* Get client user agent version */ /* Get client user agent version */
ua_encoded = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_USER_AGENT); ua_name_encoded = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_USER_AGENT_PRODUCT);
if (ua_encoded) ua_version_encoded = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_USER_AGENT_VERSION);
if (ua_name_encoded)
{ {
ua = adc_msg_unescape(ua_encoded); str = adc_msg_unescape(ua_name_encoded);
if (ua) if (str)
{ {
memcpy(user->id.user_agent, ua, MIN(strlen(ua), MAX_UA_LEN)); offset = strlen(str);
hub_free(ua); memcpy(user->id.user_agent, str, MIN(offset, MAX_UA_LEN));
hub_free(str);
} }
} }
hub_free(ua_encoded);
if (ua_version_encoded)
{
str = adc_msg_unescape(ua_version_encoded);
if (str)
{
memcpy(user->id.user_agent + offset, str, MIN(strlen(str), MAX_UA_LEN - offset));
hub_free(str);
}
}
hub_free(ua_name_encoded);
hub_free(ua_version_encoded);
return 0; return 0;
} }
@ -555,6 +581,10 @@ static int set_credentials(struct hub_info* hub, struct hub_user* user, struct a
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_BOT); adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_BOT);
break; break;
case auth_cred_ubot:
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_BOT);
break;
case auth_cred_guest: case auth_cred_guest:
/* Nothing to be added to the info message */ /* Nothing to be added to the info message */
break; break;
@ -567,6 +597,14 @@ static int set_credentials(struct hub_info* hub, struct hub_user* user, struct a
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_OPERATOR); adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_OPERATOR);
break; break;
case auth_cred_opbot:
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_HUBBOT);
break;
case auth_cred_opubot:
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_HUBBOT);
break;
case auth_cred_super: case auth_cred_super:
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_SUPER_USER); adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_SUPER_USER);
break; break;
@ -622,7 +660,8 @@ static int hub_handle_info_low_bandwidth(struct hub_info* hub, struct hub_user*
{ {
if (hub->config->low_bandwidth_mode) if (hub->config->low_bandwidth_mode)
{ {
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_USER_AGENT); adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_USER_AGENT_VERSION);
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_USER_AGENT_PRODUCT);
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_SHARED_FILES); adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_SHARED_FILES);
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_NORMAL); adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_NORMAL);
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_REGISTER); adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_REGISTER);

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2010, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2012, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -49,34 +49,6 @@ void ioq_recv_destroy(struct ioq_recv* q)
} }
} }
#define IOQ_RECV_FLAGS_PREALLOC 1
#define IOQ_RECV_FLAGS_FULL 2
enum ioq_recv_status ioq_recv_read(struct ioq_recv* q, struct net_connection* con)
{
static char buf[MAX_RECV_BUF];
size_t buf_size = ioq_recv_get(q, buf, MAX_RECV_BUF);
ssize_t size;
if (buf_size >= MAX_RECV_BUF)
return ioq_recv_full;
size = net_con_recv(con, buf + buf_size, MAX_RECV_BUF - buf_size);
if (size > 0)
buf_size += size;
if (size < 0)
return ioq_recv_error;
if (size == 0)
return ioq_recv_later;
ioq_recv_set(q, buf, buf_size);
return ioq_recv_ok;
}
size_t ioq_recv_get(struct ioq_recv* q, void* buf, size_t bufsize) size_t ioq_recv_get(struct ioq_recv* q, void* buf, size_t bufsize)
{ {
uhub_assert(bufsize >= q->size); uhub_assert(bufsize >= q->size);
@ -116,21 +88,6 @@ size_t ioq_recv_set(struct ioq_recv* q, void* buf, size_t bufsize)
} }
int ioq_recv_consume(struct ioq_recv* q, size_t bytes)
{
size_t newsize;
void* ptr;
if (!q || bytes > q->size) return 0;
newsize = (q->size - bytes);
memmove(q->buf, q->buf + bytes, newsize);
ptr = hub_realloc(q->buf, newsize);
q->buf = ptr;
q->size = newsize;
return 1;
}
struct ioq_send* ioq_send_create() struct ioq_send* ioq_send_create()
{ {
struct ioq_send* q = hub_malloc_zero(sizeof(struct ioq_send)); struct ioq_send* q = hub_malloc_zero(sizeof(struct ioq_send));
@ -173,7 +130,7 @@ void ioq_send_add(struct ioq_send* q, struct adc_message* msg_)
q->size += msg->length; q->size += msg->length;
} }
void ioq_send_remove(struct ioq_send* q, struct adc_message* msg) static void ioq_send_remove(struct ioq_send* q, struct adc_message* msg)
{ {
#ifdef DEBUG_SENDQ #ifdef DEBUG_SENDQ
debug_msg("ioq_send_remove", msg); debug_msg("ioq_send_remove", msg);

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2012, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -39,7 +39,6 @@ struct ioq_recv
{ {
char* buf; char* buf;
size_t size; size_t size;
// int flags;
}; };
/** /**
@ -103,26 +102,5 @@ extern size_t ioq_recv_set(struct ioq_recv*, void* buf, size_t bufsize);
extern int ioq_recv_is_empty(struct ioq_recv* buf); extern int ioq_recv_is_empty(struct ioq_recv* buf);
enum ioq_recv_status
{
ioq_recv_ok = 0, // read data OK
ioq_recv_later = 1, // all OK, but call again later (no change)
ioq_recv_full = 2, // all OK, but the buffer is full
ioq_recv_error = 3, // error (connection is not working)
};
/**
* Receive from connection into buffer.
*/
extern enum ioq_recv_status ioq_recv_read(struct ioq_recv* q, struct net_connection* con);
/**
* Consume 'bytes' bytes.
* 'bytes' must be <= q->size
*
* @return 1 on success, or 0 on error (only if q == NULL or bytes is > q->size).
*/
extern int ioq_recv_consume(struct ioq_recv* q, size_t bytes);
#endif /* HAVE_UHUB_IO_QUEUE_H */ #endif /* HAVE_UHUB_IO_QUEUE_H */

View File

@ -1,508 +0,0 @@
/*
* uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2013, Jan Vidar Krey
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "uhub.h"
#ifdef LINK_SUPPORT
static int link_send_support(struct hub_link* link);
static void link_net_event(struct net_connection* con, int event, void *arg)
{
LOG_INFO("link_net_event(), event=%d", event);
struct hub_link* link = (struct hub_link*) arg;
struct hub_info* hub = link->hub;
int ret = 0;
if (event == NET_EVENT_TIMEOUT)
{
LOG_DEBUG("Hub link timeout!");
}
if (event & NET_EVENT_READ)
{
ret = link_handle_read(link);
if (ret < 0)
{
link_disconnect(link);
return;
}
}
if (event & NET_EVENT_WRITE)
{
ret = link_handle_write(link);
if (ret < 0)
{
link_disconnect(link);
return;
}
}
}
void link_disconnect(struct hub_link* link)
{
if (link->connection)
net_con_close(link->connection);
link->connection = NULL;
ioq_send_destroy(link->send_queue);
ioq_recv_destroy(link->recv_queue);
link->send_queue = NULL;
link->recv_queue = NULL;
// FIXME: Notify hub and disconnect users!
hub_free(link);
}
static struct hub_link* link_create_internal(struct hub_info* hub)
{
struct hub_link* link = NULL;
LOG_DEBUG("link_create_internal(), hub=%p");
link = (struct hub_link*) hub_malloc_zero(sizeof(struct hub_link));
if (link == NULL)
return NULL; /* OOM */
link->send_queue = ioq_send_create();
link->recv_queue = ioq_recv_create();
link->hub = hub;
link->state = state_protocol;
return link;
}
struct hub_link* link_create(struct hub_info* hub, struct net_connection* con, struct ip_addr_encap* addr)
{
struct hub_link* link = link_create_internal(hub);
link->connection = con;
net_con_reinitialize(link->connection, link_net_event, link, NET_EVENT_READ);
link->mode = link_mode_server;
return link;
}
static void link_connect_callback(struct net_connect_handle* handle, enum net_connect_status status, struct net_connection* con, void* ptr)
{
struct hub_link* link = (struct hub_link*) ptr;
link->connect_job = NULL;
LOG_DEBUG("link_connect_callback()");
switch (status)
{
case net_connect_status_ok:
link->connection = con;
net_con_reinitialize(link->connection, link_net_event, link, NET_EVENT_READ);
// FIXME: send handshake here
link_send_support(link);
break;
case net_connect_status_host_not_found:
case net_connect_status_no_address:
case net_connect_status_dns_error:
case net_connect_status_refused:
case net_connect_status_unreachable:
case net_connect_status_timeout:
case net_connect_status_socket_error:
// FIXME: Unable to connect - start timer and re-try connection establishment!
break;
}
}
struct link_address
{
char host[256];
uint16_t port;
};
static int link_parse_address(const char* arg, struct link_address* addr)
{
int port;
char* split;
memset(addr, 0, sizeof(struct link_address));
/* Split hostname and port (if possible) */
split = strrchr(arg, ':');
if (split == 0 || strlen(split) < 2 || strlen(split) > 6)
return 0;
/* Ensure port number is valid */
port = strtol(split+1, NULL, 10);
if (port <= 0 || port > 65535)
return 0;
memcpy(addr->host, arg, &split[0] - &arg[0]);
addr->port = port;
return 1;
}
struct hub_link* link_connect_uri(struct hub_info* hub, const char* address)
{
struct link_address link_address;
if (!link_parse_address(address, &link_address))
{
LOG_INFO("Invalid master hub link address");
return NULL;
}
return link_connect(hub, link_address.host, link_address.port);
}
struct hub_link* link_connect(struct hub_info* hub, const char* address, uint16_t port)
{
struct hub_link* link = link_create_internal(hub);
LOG_DEBUG("Connecting to master link at %s:%d...", address, port);
link->mode = link_mode_client;
link->connect_job = net_con_connect(address, port, link_connect_callback, link);
if (!link->connect_job)
{
// FIXME: Immediate failure!
LOG_DEBUG("Error connecting to master hub link.");
link_disconnect(link);
return NULL;
}
return link;
}
static int link_net_io_want_read(struct hub_link* link)
{
net_con_update(link->connection, NET_EVENT_READ);
}
static int link_net_io_want_write(struct hub_link* link)
{
net_con_update(link->connection, NET_EVENT_READ | NET_EVENT_WRITE);
}
int link_handle_write(struct hub_link* link)
{
int ret = 0;
while (ioq_send_get_bytes(link->send_queue))
{
ret = ioq_send_send(link->send_queue, link->connection);
if (ret <= 0)
break;
}
if (ret < 0)
return -1; // FIXME! Extract socket error!
if (ioq_send_get_bytes(link->send_queue))
link_net_io_want_write(link);
else
link_net_io_want_read(link);
return 0;
}
int link_send_message(struct hub_link* link, struct adc_message* msg)
{
#ifdef DEBUG_SENDQ
char* data = strndup(msg->cache, msg->length-1);
LOG_PROTO("[link] send %p: \"%s\"", link, data);
free(data);
#endif
if (!link->connection)
return -1;
uhub_assert(msg->cache && *msg->cache);
if (ioq_send_is_empty(link->send_queue) /*&& !user_flag_get(user, flag_pipeline)*/)
{
/* Perform oportunistic write */
ioq_send_add(link->send_queue, msg);
link_handle_write(link);
}
else
{
// if (check_send_queue(hub, user, msg) >= 0)
// {
ioq_send_add(link->send_queue, msg);
// if (!user_flag_get(user, flag_pipeline))
link_net_io_want_write(link);
}
return 0;
}
static int link_send_support(struct hub_link* link)
{
int ret;
struct adc_message* msg = adc_msg_construct(ADC_CMD_LSUP, 6 + strlen(ADC_PROTO_LINK_SUPPORT));
adc_msg_add_argument(msg, ADC_PROTO_LINK_SUPPORT);
ret = link_send_message(link, msg);
adc_msg_free(msg);
return ret;
}
static int link_send_welcome(struct hub_link* link)
{
int ret;
struct adc_message* info = adc_msg_construct(ADC_CMD_LINF, 128);
if (!info)
return -1;
adc_msg_add_named_argument(info, ADC_INF_FLAG_CLIENT_TYPE, ADC_CLIENT_TYPE_HUB);
adc_msg_add_named_argument_string(info, ADC_INF_FLAG_USER_AGENT, PRODUCT_STRING);
adc_msg_add_named_argument_string(info, ADC_INF_FLAG_NICK, link->hub->config->hub_name);
adc_msg_add_named_argument_string(info, ADC_INF_FLAG_DESCRIPTION, link->hub->config->hub_description);
ret = link_send_message(link, info);
link->state = state_normal;
}
static int link_send_auth_response(struct hub_link* link, const char* challenge)
{
int ret;
struct adc_message* msg = adc_msg_construct(ADC_CMD_LPAS, 128);
// FIXME: Solve challenge.
ret = link_send_message(link, msg);
adc_msg_free(msg);
return ret;
}
static int link_send_auth_request(struct hub_link* link)
{
int ret;
struct adc_message* msg = adc_msg_construct(ADC_CMD_LGPA, 128);
// FIXME: Create challenge.
char buf[64];
uint64_t tiger_res[3];
static char tiger_buf[MAX_CID_LEN+1];
LOG_DEBUG("link_send_auth_request");
// FIXME: Generate a better nonce scheme.
snprintf(buf, 64, "%p%d", link, (int) net_con_get_sd(link->connection));
tiger((uint64_t*) buf, strlen(buf), (uint64_t*) tiger_res);
base32_encode((unsigned char*) tiger_res, TIGERSIZE, tiger_buf);
tiger_buf[MAX_CID_LEN] = 0;
// Add nonce to message
adc_msg_add_argument(msg, (const char*) tiger_buf);
ret = link_send_message(link, msg);
adc_msg_free(msg);
return ret;
}
static int link_handle_support(struct hub_link* link, struct adc_message* msg)
{
int ret = 0;
LOG_DEBUG("link_handle_support");
if (link->mode == link_mode_server)
{
if (link->state == state_protocol)
{
ret = link_send_support(link);
if (ret == 0)
ret = link_send_auth_request(link);
link->state = state_verify;
}
}
return ret;
}
static int link_handle_auth_request(struct hub_link* link, struct adc_message* msg)
{
char* challenge;
int ret = -1;
LOG_DEBUG("link_handle_auth_request");
if (link->state == state_verify)
return -1;
if (link->mode == link_mode_client)
{
challenge = adc_msg_get_argument(msg, 0);
ret = link_send_auth_response(link, challenge);
hub_free(challenge);
}
return ret;
}
static int link_handle_auth_response(struct hub_link* link, struct adc_message* msg)
{
LOG_DEBUG("link_handle_auth_response. link_state=%d", (int) link->state);
if (link->state != state_verify)
return -1;
LOG_DEBUG("State is not verify!");
if (link->mode == link_mode_server)
{
// Check authentication data
// FIXME: Can involve plug-ins at this point.
return link_send_welcome(link);
}
else
{
LOG_DEBUG("Ignoring auth response - We're client mode!");
}
return -1;
}
static int link_handle_link_info(struct hub_link* link, struct adc_message* msg)
{
LOG_DEBUG("link_handle_link_info");
return 0;
}
static int link_handle_status(struct hub_link* link, struct adc_message* msg)
{
LOG_DEBUG("link_handle_status");
return -1;
}
static int link_handle_message(struct hub_link* link, const char* message, size_t length)
{
int ret = 0;
struct adc_message* cmd = 0;
LOG_INFO("link_handle_message(): %s (%d)", message, (int) length);
// FIXME: is this needed?
if (link->state == state_cleanup || link->state == state_disconnected)
return -1;
cmd = adc_msg_parse(message, length);
if (!cmd)
{
LOG_DEBUG("Unable to parse hub-link message");
return -1;
}
// if (
switch (cmd->cmd)
{
case ADC_CMD_LSUP:
ret = link_handle_support(link, cmd);
break;
case ADC_CMD_LPAS:
ret = link_handle_auth_response(link, cmd);
break;
case ADC_CMD_LGPA:
ret = link_handle_auth_request(link, cmd);
break;
case ADC_CMD_LINF:
ret = link_handle_link_info(link, cmd);
break;
case ADC_CMD_LSTA:
ret = link_handle_status(link, cmd);
break;
}
adc_msg_free(cmd);
return ret;
}
static int link_read_message(struct hub_link* link)
{
char* lastPos = 0;
char* pos = 0;
char* start = link->recv_queue->buf;
size_t remaining = link->recv_queue->size;
while ((pos = memchr(start, '\n', remaining)))
{
lastPos = pos+1;
pos[0] = '\0';
if (link->flags & 1)
{
/* FIXME Unset maxbuf flag */
link->flags = 0;
}
else
{
if (link_handle_message(link, start, (pos - start)) == -1)
{
return -1;
}
}
pos[0] = '\n'; /* FIXME: not needed */
pos ++;
remaining -= (pos - start);
start = pos;
}
ioq_recv_consume(link->recv_queue, (start - link->recv_queue->buf));
return 0;
}
int link_handle_read(struct hub_link* link)
{
int ret = 0;
while (1)
{
switch (ioq_recv_read(link->recv_queue, link->connection))
{
case ioq_recv_ok:
if (link_read_message(link) < 0)
{
// FIXME: propagate protocol error?
return -1;
}
// Parse messages then call again
break;
case ioq_recv_later:
return 0;
case ioq_recv_full:
link->flags = 1; // FIXME: MAXBUF
ioq_recv_set(link->recv_queue, 0, 0);
break;
case ioq_recv_error:
return -1; // FIXME: it would be good to signal type of socket error
}
}
return 0;
}
#endif /* LINK_SUPPORT */

View File

@ -1,70 +0,0 @@
/*
* uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2013, Jan Vidar Krey
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef HAVE_UHUB_LINK_H
#define HAVE_UHUB_LINK_H
#ifdef LINK_SUPPORT
struct hub_link
{
char name[MAX_NICK_LEN+1]; /** The name of the linked hub */
char user_agent[MAX_UA_LEN+1]; /** The user agent of the linked hub */
char address[256]; /** The official address of the linked hub */
enum link_mode { link_mode_client, link_mode_server } mode;
enum user_state state;
struct ioq_send* send_queue;
struct ioq_recv* recv_queue;
struct net_connection* connection; /** Connection data */
struct net_connect_handle* connect_job; /** Only used when establishing a connection in client mode */
struct hub_info* hub;
int flags;
};
/**
* Create a link from an accepted connection (act as a link server).
*/
extern struct hub_link* link_create(struct hub_info* hub, struct net_connection* con, struct ip_addr_encap* addr);
/**
* Connect this hub to an upstream server (act as a link client).
*/
extern struct hub_link* link_connect(struct hub_info* hub, const char* address, uint16_t port);
extern struct hub_link* link_connect_uri(struct hub_info* hub, const char* address);
/**
* Disconnect a link connection.
*/
extern void link_disconnect(struct hub_link*);
/**
* Read from link connection and process messages.
* @return 0 on success, and a negative value otherwise
*/
extern int link_handle_read(struct hub_link* link);
/**
* Write queued messages to the link.
* @return 0 on success, and a negative value otherwise.
*/
extern int link_handle_write(struct hub_link* link);
#endif // LINK_SUPPORT
#endif /* HAVE_UHUB_LINK_H */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2011, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -125,10 +125,6 @@ int main_loop()
hub_set_log_verbosity(arg_verbose); hub_set_log_verbosity(arg_verbose);
} }
#ifdef DEBUG
LOG_INFO("Debug messages enabled");
#endif
if (read_config(arg_config, &configuration, !arg_have_config) == -1) if (read_config(arg_config, &configuration, !arg_have_config) == -1)
return -1; return -1;
@ -155,7 +151,7 @@ int main_loop()
setup_signal_handlers(hub); setup_signal_handlers(hub);
#ifdef SYSTEMD #ifdef SYSTEMD
/* Notify the service manager that this daemon has /* Notify the service manager that this daemon has
* been successfully initalized and shall enter the * been successfully initialized and shall enter the
* main loop. * main loop.
*/ */
sd_notifyf(0, "READY=1\n" sd_notifyf(0, "READY=1\n"
@ -475,7 +471,7 @@ int main(int argc, char** argv)
} }
else if (ret == 0) else if (ret == 0)
{ {
/* child process - detatch from TTY */ /* child process - detach from TTY */
fclose(stdin); fclose(stdin);
fclose(stdout); fclose(stdout);
fclose(stderr); fclose(stderr);

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2010, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -137,6 +137,12 @@ void net_event(struct net_connection* con, int event, void *arg)
LOG_TRACE("net_event() : fd=%d, ev=%d, arg=%p", con->sd, (int) event, arg); LOG_TRACE("net_event() : fd=%d, ev=%d, arg=%p", con->sd, (int) event, arg);
#endif #endif
if (event == NET_EVENT_ERROR)
{
hub_disconnect_user(user->hub, user, quit_socket_error);
return;
}
if (event == NET_EVENT_TIMEOUT) if (event == NET_EVENT_TIMEOUT)
{ {
if (user_is_connecting(user)) if (user_is_connecting(user))

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2010, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2011, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -40,14 +40,11 @@ static int plugin_command_dispatch(struct command_base* cbase, struct hub_user*
LOG_PLUGIN("plugin_command_dispatch: cmd=%s", cmd->prefix); LOG_PLUGIN("plugin_command_dispatch: cmd=%s", cmd->prefix);
cmdh = (struct plugin_command_handle*) list_get_first(data->commands); LIST_FOREACH(struct plugin_command_handle*, cmdh, data->commands,
while (cmdh)
{ {
if (strcmp(cmdh->prefix, cmd->prefix) == 0) if (strcmp(cmdh->prefix, cmd->prefix) == 0)
return cmdh->handler(plugin, puser, pcommand); return cmdh->handler(plugin, puser, pcommand);
});
cmdh = (struct plugin_command_handle*) list_get_next(data->commands);
}
return 0; return 0;
} }
@ -68,6 +65,17 @@ static int cbfunc_send_message(struct plugin_handle* plugin, struct plugin_user*
return 1; return 1;
} }
static int cbfunc_send_broadcast(struct plugin_handle* plugin, const char* message)
{
char* buffer = adc_msg_escape(message);
struct adc_message* command = adc_msg_construct(ADC_CMD_IMSG, strlen(buffer) + 6);
adc_msg_add_argument(command, buffer);
route_to_all(plugin_get_hub(plugin), command);
adc_msg_free(command);
hub_free(buffer);
return 1;
}
static int cbfunc_send_status(struct plugin_handle* plugin, struct plugin_user* user, int code, const char* message) static int cbfunc_send_status(struct plugin_handle* plugin, struct plugin_user* user, int code, const char* message)
{ {
char code_str[4]; char code_str[4];
@ -104,7 +112,6 @@ static int cbfunc_command_add(struct plugin_handle* plugin, struct plugin_comman
cmdh->internal_handle = command; cmdh->internal_handle = command;
list_append(data->commands, cmdh); list_append(data->commands, cmdh);
command_add(plugin_get_hub(plugin)->commands, command, (void*) plugin); command_add(plugin_get_hub(plugin)->commands, command, (void*) plugin);
printf("*** Add plugin command: %s (%p, %p)\n", command->prefix, command, cmdh);
return 0; return 0;
} }
@ -113,7 +120,6 @@ static int cbfunc_command_del(struct plugin_handle* plugin, struct plugin_comman
struct plugin_callback_data* data = get_callback_data(plugin); struct plugin_callback_data* data = get_callback_data(plugin);
struct command_handle* command = (struct command_handle*) cmdh->internal_handle; struct command_handle* command = (struct command_handle*) cmdh->internal_handle;
printf("*** Del plugin command: %s (%p, %p)\n", command->prefix, command, cmdh);
list_remove(data->commands, cmdh); list_remove(data->commands, cmdh);
command_del(plugin_get_hub(plugin)->commands, command); command_del(plugin_get_hub(plugin)->commands, command);
hub_free(command); hub_free(command);
@ -133,6 +139,12 @@ struct plugin_command_arg_data* cbfunc_command_arg_next(struct plugin_handle* pl
return (struct plugin_command_arg_data*) hub_command_arg_next((struct hub_command*) cmd, (enum hub_command_arg_type) t); return (struct plugin_command_arg_data*) hub_command_arg_next((struct hub_command*) cmd, (enum hub_command_arg_type) t);
} }
static size_t cbfunc_get_usercount(struct plugin_handle* plugin)
{
struct hub_info* hub = plugin_get_hub(plugin);
return hub->users->count;
}
static char* cbfunc_get_hub_name(struct plugin_handle* plugin) static char* cbfunc_get_hub_name(struct plugin_handle* plugin)
{ {
struct hub_info* hub = plugin_get_hub(plugin); struct hub_info* hub = plugin_get_hub(plugin);
@ -188,12 +200,14 @@ static void cbfunc_set_hub_description(struct plugin_handle* plugin, const char*
void plugin_register_callback_functions(struct plugin_handle* handle) void plugin_register_callback_functions(struct plugin_handle* handle)
{ {
handle->hub.send_message = cbfunc_send_message; handle->hub.send_message = cbfunc_send_message;
handle->hub.send_broadcast_message = cbfunc_send_broadcast;
handle->hub.send_status_message = cbfunc_send_status; handle->hub.send_status_message = cbfunc_send_status;
handle->hub.user_disconnect = cbfunc_user_disconnect; handle->hub.user_disconnect = cbfunc_user_disconnect;
handle->hub.command_add = cbfunc_command_add; handle->hub.command_add = cbfunc_command_add;
handle->hub.command_del = cbfunc_command_del; handle->hub.command_del = cbfunc_command_del;
handle->hub.command_arg_reset = cbfunc_command_arg_reset; handle->hub.command_arg_reset = cbfunc_command_arg_reset;
handle->hub.command_arg_next = cbfunc_command_arg_next; handle->hub.command_arg_next = cbfunc_command_arg_next;
handle->hub.get_usercount = cbfunc_get_usercount;
handle->hub.get_name = cbfunc_get_hub_name; handle->hub.get_name = cbfunc_get_hub_name;
handle->hub.set_name = cbfunc_set_hub_name; handle->hub.set_name = cbfunc_set_hub_name;
handle->hub.get_description = cbfunc_get_hub_description; handle->hub.get_description = cbfunc_get_hub_description;

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2011, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2011, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -27,13 +27,12 @@
PLUGIN_DEBUG(HUB, # FUNCNAME) \ PLUGIN_DEBUG(HUB, # FUNCNAME) \
if (HUB->plugins && HUB->plugins->loaded) \ if (HUB->plugins && HUB->plugins->loaded) \
{ \ { \
struct plugin_handle* plugin = (struct plugin_handle*) list_get_first(HUB->plugins->loaded); \ struct plugin_handle* plugin;\
while (plugin) \ LIST_FOREACH(struct plugin_handle*, plugin, HUB->plugins->loaded, \
{ \ { \
if (plugin->funcs.FUNCNAME) \ if (plugin->funcs.FUNCNAME) \
CODE \ CODE \
plugin = (struct plugin_handle*) list_get_next(HUB->plugins->loaded); \ }); \
} \
} }
#define PLUGIN_INVOKE_STATUS_1(HUB, FUNCNAME, ARG1) \ #define PLUGIN_INVOKE_STATUS_1(HUB, FUNCNAME, ARG1) \

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2011, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2011, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -102,7 +102,6 @@ struct plugin_handle* plugin_load(const char* filename, const char* config, stru
int ret; int ret;
struct plugin_handle* handle = (struct plugin_handle*) hub_malloc_zero(sizeof(struct plugin_handle)); struct plugin_handle* handle = (struct plugin_handle*) hub_malloc_zero(sizeof(struct plugin_handle));
struct uhub_plugin* plugin = plugin_open(filename); struct uhub_plugin* plugin = plugin_open(filename);
struct plugin_hub_internals* internals = (struct plugin_hub_internals*) plugin->internals;
if (!plugin) if (!plugin)
return NULL; return NULL;
@ -118,6 +117,7 @@ struct plugin_handle* plugin_load(const char* filename, const char* config, stru
unregister_f = plugin_lookup_symbol(plugin, "plugin_unregister"); unregister_f = plugin_lookup_symbol(plugin, "plugin_unregister");
// register hub internals // register hub internals
struct plugin_hub_internals* internals = (struct plugin_hub_internals*) plugin->internals;
internals->unregister = unregister_f; internals->unregister = unregister_f;
internals->hub = hub; internals->hub = hub;
internals->callback_data = plugin_callback_data_create(); internals->callback_data = plugin_callback_data_create();
@ -229,16 +229,16 @@ int plugin_initialize(struct hub_config* config, struct hub_info* hub)
return 0; return 0;
} }
void plugin_shutdown(struct uhub_plugins* handle) static void plugin_unload_ptr(void* ptr)
{ {
struct plugin_handle* plugin = (struct plugin_handle*) list_get_first(handle->loaded); struct plugin_handle* plugin = (struct plugin_handle*) ptr;
while (plugin)
{
list_remove(handle->loaded, plugin);
plugin_unload(plugin); plugin_unload(plugin);
plugin = (struct plugin_handle*) list_get_first(handle->loaded);
} }
void plugin_shutdown(struct uhub_plugins* handle)
{
list_clear(handle->loaded, plugin_unload_ptr);
list_destroy(handle->loaded); list_destroy(handle->loaded);
} }

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2011, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2010, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -71,17 +71,15 @@ static void probe_net_event(struct net_connection* con, int events, void *arg)
probe_destroy(probe); probe_destroy(probe);
return; return;
} }
#ifdef LINK_SUPPORT else if ((memcmp(probe_recvbuf, "GET ", 4) == 0) ||
else if (probe->hub->config->hub_link_enabled && memcmp(probe_recvbuf, "LSUP", 4) == 0) (memcmp(probe_recvbuf, "POST", 4) == 0) ||
(memcmp(probe_recvbuf, "HEAD", 4) == 0))
{ {
if (link_create(probe->hub, probe->connection, &probe->addr)) /* Looks like HTTP - Not supported, but we log it. */
{ LOG_TRACE("Probed HTTP connection. Not supported closing connection (%s)", ip_convert_to_string(&probe->addr));
probe->connection = 0; const char* buf = "501 Not implemented\r\n\r\n";
net_con_send(con, buf, strlen(buf));
} }
probe_destroy(probe);
return;
}
#endif /* LINK_SUPPORT */
#ifdef SSL_SUPPORT #ifdef SSL_SUPPORT
else if (bytes >= 11 && else if (bytes >= 11 &&
probe_recvbuf[0] == 22 && probe_recvbuf[0] == 22 &&
@ -92,11 +90,14 @@ static void probe_net_event(struct net_connection* con, int events, void *arg)
if (probe->hub->config->tls_enable) if (probe->hub->config->tls_enable)
{ {
LOG_TRACE("Probed TLS %d.%d connection", (int) probe_recvbuf[9], (int) probe_recvbuf[10]); LOG_TRACE("Probed TLS %d.%d connection", (int) probe_recvbuf[9], (int) probe_recvbuf[10]);
if (user_create(probe->hub, probe->connection, &probe->addr)) 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))
{ {
probe->connection = 0; probe->connection = 0;
} }
net_con_ssl_handshake(con, net_con_ssl_mode_server, probe->hub->ctx);
} }
else else
{ {

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2010, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2009, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -82,16 +82,19 @@ static int check_send_queue(struct hub_info* hub, struct hub_user* user, struct
if ((user->send_queue->size + msg->length) > get_max_send_queue(hub)) if ((user->send_queue->size + msg->length) > get_max_send_queue(hub))
{ {
user_flag_set(user, flag_choke);
LOG_WARN("send queue overflowed, message discarded."); LOG_WARN("send queue overflowed, message discarded.");
return -1; return -1;
} }
if (user->send_queue->size > get_max_send_queue_soft(hub)) if (user->send_queue->size > get_max_send_queue_soft(hub))
{ {
user_flag_set(user, flag_choke);
LOG_WARN("send queue soft overflowed."); LOG_WARN("send queue soft overflowed.");
return 0; return 0;
} }
user_flag_unset(user, flag_choke);
return 1; return 1;
} }
@ -99,7 +102,7 @@ int route_to_user(struct hub_info* hub, struct hub_user* user, struct adc_messag
{ {
#ifdef DEBUG_SENDQ #ifdef DEBUG_SENDQ
char* data = strndup(msg->cache, msg->length-1); char* data = strndup(msg->cache, msg->length-1);
LOG_PROTO("[user] send %s: \"%s\"", sid_to_string(user->id.sid), data); LOG_PROTO("send %s: \"%s\"", sid_to_string(user->id.sid), data);
free(data); free(data);
#endif #endif
@ -139,12 +142,11 @@ int route_flush_pipeline(struct hub_info* hub, struct hub_user* u)
int route_to_all(struct hub_info* hub, struct adc_message* command) /* iterate users */ int route_to_all(struct hub_info* hub, struct adc_message* command) /* iterate users */
{ {
struct hub_user* user = (struct hub_user*) list_get_first(hub->users->list); struct hub_user* user;
while (user) LIST_FOREACH(struct hub_user*, user, hub->users->list,
{ {
route_to_user(hub, user, command); route_to_user(hub, user, command);
user = (struct hub_user*) list_get_next(hub->users->list); });
}
return 0; return 0;
} }
@ -154,47 +156,38 @@ int route_to_subscribers(struct hub_info* hub, struct adc_message* command) /* i
int do_send; int do_send;
char* tmp; char* tmp;
struct hub_user* user = (struct hub_user*) list_get_first(hub->users->list); struct hub_user* user;
while (user) LIST_FOREACH(struct hub_user*, user, hub->users->list,
{ {
if (user->feature_cast) if (user->feature_cast)
{ {
do_send = 1; do_send = 1;
tmp = list_get_first(command->feature_cast_include); LIST_FOREACH(char*, tmp, command->feature_cast_include,
while (tmp)
{ {
if (!user_have_feature_cast_support(user, tmp)) if (!user_have_feature_cast_support(user, tmp))
{ {
do_send = 0; do_send = 0;
break; break;
} }
tmp = list_get_next(command->feature_cast_include);; });
}
if (!do_send) { if (!do_send)
user = (struct hub_user*) list_get_next(hub->users->list);
continue; continue;
}
tmp = list_get_first(command->feature_cast_exclude); LIST_FOREACH(char*, tmp, command->feature_cast_exclude,
while (tmp)
{ {
if (user_have_feature_cast_support(user, tmp)) if (user_have_feature_cast_support(user, tmp))
{ {
do_send = 0; do_send = 0;
break; break;
} }
tmp = list_get_next(command->feature_cast_exclude); });
}
if (do_send) if (do_send)
{
route_to_user(hub, user, command); route_to_user(hub, user, command);
} }
} });
user = (struct hub_user*) list_get_next(hub->users->list);
}
return 0; return 0;
} }
@ -214,16 +207,13 @@ int route_info_message(struct hub_info* hub, struct hub_user* u)
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR); adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR);
adc_msg_add_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR, address); adc_msg_add_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR, address);
user = (struct hub_user*) list_get_first(hub->users->list); LIST_FOREACH(struct hub_user*, user, hub->users->list,
while (user)
{ {
if (user_is_nat_override(user)) if (user_is_nat_override(user))
route_to_user(hub, user, cmd); route_to_user(hub, user, cmd);
else else
route_to_user(hub, user, u->info); route_to_user(hub, user, u->info);
});
user = (struct hub_user*) list_get_next(hub->users->list);
}
adc_msg_free(cmd); adc_msg_free(cmd);
} }
return 0; return 0;

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2009, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2010, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -232,15 +232,12 @@ void user_support_remove(struct hub_user* user, int fourcc)
int user_have_feature_cast_support(struct hub_user* user, char feature[4]) int user_have_feature_cast_support(struct hub_user* user, char feature[4])
{ {
char* tmp = list_get_first(user->feature_cast); char* tmp;
while (tmp) LIST_FOREACH(char*, tmp, user->feature_cast,
{ {
if (strncmp(tmp, feature, 4) == 0) if (strncmp(tmp, feature, 4) == 0)
return 1; return 1;
});
tmp = list_get_next(user->feature_cast);
}
return 0; return 0;
} }

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2010, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -68,7 +68,7 @@ enum user_quit_reason
quit_timeout = 4, /** User timed out (no data for a while) */ quit_timeout = 4, /** User timed out (no data for a while) */
quit_send_queue = 5, /** User's send queue was overflowed */ quit_send_queue = 5, /** User's send queue was overflowed */
quit_memory_error = 6, /** Not enough memory available */ quit_memory_error = 6, /** Not enough memory available */
quit_socket_error = 7, /** A socket error occured */ quit_socket_error = 7, /** A socket error occurred */
quit_protocol_error = 8, /** Fatal protocol error */ quit_protocol_error = 8, /** Fatal protocol error */
quit_logon_error = 9, /** Unable to login (wrong password, CID/PID, etc) */ quit_logon_error = 9, /** Unable to login (wrong password, CID/PID, etc) */
quit_update_error = 10, /** Update error. INF update changed share/slot info and no longer satisfies the hub limits. */ quit_update_error = 10, /** Update error. INF update changed share/slot info and no longer satisfies the hub limits. */
@ -76,7 +76,7 @@ enum user_quit_reason
quit_ghost_timeout = 12, /** The user is a ghost, and trying to login from another connection */ quit_ghost_timeout = 12, /** The user is a ghost, and trying to login from another connection */
}; };
/** Returns an apropriate string for the given quit reason */ /** Returns an appropriate string for the given quit reason */
extern const char* user_get_quit_reason_string(enum user_quit_reason); extern const char* user_get_quit_reason_string(enum user_quit_reason);
struct hub_user_info struct hub_user_info

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2009, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -38,6 +38,11 @@ static void clear_user_list_callback(void* ptr)
} }
} }
static int uman_map_compare(const void* a, const void* b)
{
return strcmp((const char*) a, (const char*) b);
}
struct hub_user_manager* uman_init() struct hub_user_manager* uman_init()
{ {
@ -46,15 +51,10 @@ struct hub_user_manager* uman_init()
return NULL; return NULL;
users->list = list_create(); users->list = list_create();
users->nickmap = rb_tree_create(uman_map_compare, NULL, NULL);
users->cidmap = rb_tree_create(uman_map_compare, NULL, NULL);
users->sids = sid_pool_create(net_get_max_sockets()); users->sids = sid_pool_create(net_get_max_sockets());
if (!users->list)
{
list_destroy(users->list);
hub_free(users);
return NULL;
}
return users; return users;
} }
@ -64,11 +64,18 @@ int uman_shutdown(struct hub_user_manager* users)
if (!users) if (!users)
return -1; return -1;
if (users->nickmap)
rb_tree_destroy(users->nickmap);
if (users->cidmap)
rb_tree_destroy(users->cidmap);
if (users->list) if (users->list)
{ {
list_clear(users->list, &clear_user_list_callback); list_clear(users->list, &clear_user_list_callback);
list_destroy(users->list); list_destroy(users->list);
} }
sid_pool_destroy(users->sids); sid_pool_destroy(users->sids);
hub_free(users); hub_free(users);
@ -81,6 +88,9 @@ int uman_add(struct hub_user_manager* users, struct hub_user* user)
if (!users || !user) if (!users || !user)
return -1; return -1;
rb_tree_insert(users->nickmap, user->id.nick, user);
rb_tree_insert(users->cidmap, user->id.cid, user);
list_append(users->list, user); list_append(users->list, user);
users->count++; users->count++;
users->count_peak = MAX(users->count, users->count_peak); users->count_peak = MAX(users->count, users->count_peak);
@ -96,6 +106,8 @@ int uman_remove(struct hub_user_manager* users, struct hub_user* user)
return -1; return -1;
list_remove(users->list, user); list_remove(users->list, user);
rb_tree_remove(users->nickmap, user->id.nick);
rb_tree_remove(users->cidmap, user->id.cid);
if (users->count > 0) if (users->count > 0)
{ {
@ -120,42 +132,29 @@ struct hub_user* uman_get_user_by_sid(struct hub_user_manager* users, sid_t sid)
struct hub_user* uman_get_user_by_cid(struct hub_user_manager* users, const char* cid) struct hub_user* uman_get_user_by_cid(struct hub_user_manager* users, const char* cid)
{ {
struct hub_user* user = (struct hub_user*) list_get_first(users->list); /* iterate users - only on incoming INF msg */ struct hub_user* user = (struct hub_user*) rb_tree_get(users->cidmap, (const void*) cid);
while (user)
{
if (strcmp(user->id.cid, cid) == 0)
return user; return user;
user = (struct hub_user*) list_get_next(users->list);
}
return NULL;
} }
struct hub_user* uman_get_user_by_nick(struct hub_user_manager* users, const char* nick) struct hub_user* uman_get_user_by_nick(struct hub_user_manager* users, const char* nick)
{ {
struct hub_user* user = (struct hub_user*) list_get_first(users->list); /* iterate users - only on incoming INF msg */ struct hub_user* user = (struct hub_user*) rb_tree_get(users->nickmap, nick);
while (user)
{
if (strcmp(user->id.nick, nick) == 0)
return user; return user;
user = (struct hub_user*) list_get_next(users->list);
}
return NULL;
} }
size_t uman_get_user_by_addr(struct hub_user_manager* users, struct linked_list* target, struct ip_range* range) size_t uman_get_user_by_addr(struct hub_user_manager* users, struct linked_list* target, struct ip_range* range)
{ {
size_t num = 0; size_t num = 0;
struct hub_user* user = (struct hub_user*) list_get_first(users->list); /* iterate users - only on incoming INF msg */ struct hub_user* user;
while (user) LIST_FOREACH(struct hub_user*, user, users->list,
{ {
if (ip_in_range(&user->id.addr, range)) if (ip_in_range(&user->id.addr, range))
{ {
list_append(target, user); list_append(target, user);
num++; num++;
} }
user = (struct hub_user*) list_get_next(users->list); });
}
return num; return num;
} }
@ -164,8 +163,8 @@ int uman_send_user_list(struct hub_info* hub, struct hub_user_manager* users, st
int ret = 1; int ret = 1;
struct hub_user* user; struct hub_user* user;
user_flag_set(target, flag_user_list); user_flag_set(target, flag_user_list);
user = (struct hub_user*) list_get_first(users->list); /* iterate users - only on INF or PAS msg */
while (user) LIST_FOREACH(struct hub_user*, user, users->list,
{ {
if (user_is_logged_in(user)) if (user_is_logged_in(user))
{ {
@ -173,8 +172,7 @@ int uman_send_user_list(struct hub_info* hub, struct hub_user_manager* users, st
if (!ret) if (!ret)
break; break;
} }
user = (struct hub_user*) list_get_next(users->list); });
}
#if 0 #if 0
FIXME: FIXME FIXME handle send queue excess FIXME: FIXME FIXME handle send queue excess

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2009, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -24,10 +24,12 @@ struct hub_user_manager
{ {
size_t count; /**<< "Number of all fully connected and logged in users" */ size_t count; /**<< "Number of all fully connected and logged in users" */
size_t count_peak; /**<< "Peak number of users" */ size_t count_peak; /**<< "Peak number of users" */
struct sid_pool* sids;
uint64_t shared_size; /**<< "The total number of shared bytes among fully connected users." */ uint64_t shared_size; /**<< "The total number of shared bytes among fully connected users." */
uint64_t shared_files; /**<< "The total number of shared files among fully connected users." */ uint64_t shared_files; /**<< "The total number of shared files among fully connected users." */
struct sid_pool* sids; /**<< "Maps SIDs to users (constant time)" */
struct linked_list* list; /**<< "Contains all logged in users" */ struct linked_list* list; /**<< "Contains all logged in users" */
struct rb_tree* nickmap; /**<< "Maps nicknames to users (red black tree)" */
struct rb_tree* cidmap; /**<< "Maps CIDs to users (red black tree)" */
}; };
/** /**
@ -40,7 +42,7 @@ extern struct hub_user_manager* uman_init();
* Shuts down the user manager. * Shuts down the user manager.
* All users will be disconnected and deleted as part of this. * All users will be disconnected and deleted as part of this.
* *
* @return 0 on success, or -1 in an error occured (invalid pointer). * @return 0 on success, or -1 in an error occurred (invalid pointer).
*/ */
extern int uman_shutdown(struct hub_user_manager* users); extern int uman_shutdown(struct hub_user_manager* users);
@ -104,7 +106,7 @@ extern struct hub_user* uman_get_user_by_nick(struct hub_user_manager* users, co
* *
* @param[out] target the list of users matching the address * @param[out] target the list of users matching the address
* @param range the IP range of users to match * @param range the IP range of users to match
* @return The number of users matching the addressess, or -1 on error (mask is wrong). * @return The number of users matching the addresses, or -1 on error (mask is wrong).
*/ */
extern size_t uman_get_user_by_addr(struct hub_user_manager* users, struct linked_list* target, struct ip_range* range); extern size_t uman_get_user_by_addr(struct hub_user_manager* users, struct linked_list* target, struct ip_range* range);

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2012, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -102,14 +102,7 @@ void net_backend_shutdown()
} }
void net_con_reinitialize(struct net_connection* con, net_connection_cb callback, const void* ptr, int events) void net_backend_update(struct net_connection* con, int events)
{
con->callback = callback;
con->ptr = (void*) ptr;
net_con_update(con, events);
}
void net_con_update(struct net_connection* con, int events)
{ {
g_backend->handler.con_mod(g_backend->data, con, events); g_backend->handler.con_mod(g_backend->data, con, events);
} }
@ -148,7 +141,7 @@ int net_backend_process()
} }
// Process pending DNS results // Process pending DNS results
net_dns_process(); // net_dns_process();
g_backend->handler.backend_process(g_backend->data, res); g_backend->handler.backend_process(g_backend->data, res);
@ -166,8 +159,8 @@ void net_con_initialize(struct net_connection* con, int sd, net_connection_cb ca
{ {
g_backend->handler.con_init(g_backend->data, con, sd, callback, ptr); g_backend->handler.con_init(g_backend->data, con, sd, callback, ptr);
net_set_nonblocking(con->sd, 1); net_set_nonblocking(net_con_get_sd(con), 1);
net_set_nosigpipe(con->sd, 1); net_set_nosigpipe(net_con_get_sd(con), 1);
g_backend->handler.con_add(g_backend->data, con, events); g_backend->handler.con_add(g_backend->data, con, events);
g_backend->common.num++; g_backend->common.num++;

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2012, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -75,6 +75,14 @@ extern void net_backend_shutdown();
*/ */
extern int net_backend_process(); extern int net_backend_process();
/**
* Update the event mask.
*
* @param con Connection handle.
* @param events Event mask (NET_EVENT_*)
*/
extern void net_backend_update(struct net_connection* con, int events);
/** /**
* Get the current time. * Get the current time.
*/ */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2012, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2013, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,12 +13,13 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
#include "uhub.h" #include "uhub.h"
#include "network/common.h" #include "network/common.h"
#include "network/backend.h"
static int is_blocked_or_interrupted() static int is_blocked_or_interrupted()
{ {
@ -116,10 +117,27 @@ void* net_con_get_ptr(struct net_connection* con)
return con->ptr; return con->ptr;
} }
void net_con_destroy(struct net_connection* con) void net_con_update(struct net_connection* con, int events)
{ {
#ifdef SSL_SUPPORT #ifdef SSL_SUPPORT
if (con->ssl) if (con->ssl)
net_ssl_update(con, events);
else
#endif
net_backend_update(con, events);
}
void net_con_reinitialize(struct net_connection* con, net_connection_cb callback, const void* ptr, int events)
{
con->callback = callback;
con->ptr = (void*) ptr;
net_con_update(con, events);
}
void net_con_destroy(struct net_connection* con)
{
#ifdef SSL_SUPPORT
if (con && con->ssl)
net_ssl_destroy(con); net_ssl_destroy(con);
#endif #endif
hub_free(con); hub_free(con);
@ -178,11 +196,12 @@ static int net_connect_job_check(struct net_connect_job* job)
int af = job->addr.ss_family; int af = job->addr.ss_family;
enum net_connect_status status; enum net_connect_status status;
int ret = net_connect(net_con_get_sd(con), (struct sockaddr*) &job->addr, af == AF_INET ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)); int ret = net_connect(net_con_get_sd(con), (struct sockaddr*) &job->addr, af == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6));
if (ret == 0 || (ret == -1 && net_error() == EISCONN)) if (ret == 0 || (ret == -1 && net_error() == EISCONN))
{ {
LOG_TRACE("net_connect_job_check(): Socket connected!"); LOG_TRACE("net_connect_job_check(): Socket connected!");
job->con = NULL; job->con = NULL;
net_con_clear_timeout(con);
net_connect_callback(job->handle, net_connect_status_ok, con); net_connect_callback(job->handle, net_connect_status_ok, con);
return 1; return 1;
} }
@ -264,7 +283,6 @@ static int net_connect_job_process(struct net_connect_job* job)
*/ */
static void net_connect_job_internal_cb(struct net_connection* con, int event, void* ptr) static void net_connect_job_internal_cb(struct net_connection* con, int event, void* ptr)
{ {
int ret;
struct net_connect_job* job = net_con_get_ptr(con); struct net_connect_job* job = net_con_get_ptr(con);
struct net_connect_job* next_job = job->next; struct net_connect_job* next_job = job->next;
struct net_connect_handle* handle = job->handle; struct net_connect_handle* handle = job->handle;
@ -307,7 +325,7 @@ static void net_connect_job_internal_cb(struct net_connection* con, int event, v
} }
static int net_connect_cancel(struct net_connect_handle* handle) static void net_connect_cancel(struct net_connect_handle* handle)
{ {
struct net_connect_job* job; struct net_connect_job* job;
@ -363,6 +381,7 @@ static int net_connect_process(struct net_connect_handle* handle)
return 1; // Connected - cool! return 1; // Connected - cool!
net_connect_process_queue(handle, handle->job4); net_connect_process_queue(handle, handle->job4);
return 0;
} }
@ -421,7 +440,6 @@ static int net_con_connect_dns_callback(struct net_dns_job* job, const struct ne
struct net_connect_handle* handle = (struct net_connect_handle*) net_dns_job_get_ptr(job); struct net_connect_handle* handle = (struct net_connect_handle*) net_dns_job_get_ptr(job);
handle->dns = NULL; handle->dns = NULL;
size_t usable = 0; size_t usable = 0;
int ret;
LOG_TRACE("net_con_connect(): async - Got DNS results"); LOG_TRACE("net_con_connect(): async - Got DNS results");
if (!result) if (!result)
@ -506,3 +524,34 @@ static void net_connect_callback(struct net_connect_handle* handle, enum net_con
// Cleanup // Cleanup
net_connect_destroy(handle); net_connect_destroy(handle);
} }
static void timeout_callback(struct timeout_evt* evt)
{
net_con_callback((struct net_connection*) evt->ptr, NET_EVENT_TIMEOUT);
}
void net_con_set_timeout(struct net_connection* con, int seconds)
{
if (!con->timeout)
{
con->timeout = hub_malloc_zero(sizeof(struct timeout_evt));
timeout_evt_initialize(con->timeout, timeout_callback, con);
timeout_queue_insert(net_backend_get_timeout_queue(), con->timeout, seconds);
}
else
{
timeout_queue_reschedule(net_backend_get_timeout_queue(), con->timeout, seconds);
}
}
void net_con_clear_timeout(struct net_connection* con)
{
if (con->timeout && timeout_evt_is_scheduled(con->timeout))
{
timeout_queue_remove(net_backend_get_timeout_queue(), con->timeout);
hub_free(con->timeout);
con->timeout = 0;
}
}

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2013, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -28,6 +28,7 @@
#define NET_EVENT_TIMEOUT 0x0001 #define NET_EVENT_TIMEOUT 0x0001
#define NET_EVENT_READ 0x0002 #define NET_EVENT_READ 0x0002
#define NET_EVENT_WRITE 0x0004 #define NET_EVENT_WRITE 0x0004
#define NET_EVENT_ERROR 0x1000
struct net_connection struct net_connection
{ {
@ -87,7 +88,7 @@ extern void net_con_close(struct net_connection* con);
* *
* @return returns the number of bytes sent. * @return returns the number of bytes sent.
* 0 if no data is sent, and this function should be called again (EWOULDBLOCK/EINTR) * 0 if no data is sent, and this function should be called again (EWOULDBLOCK/EINTR)
* <0 if an error occured, the negative number contains the error code. * <0 if an error occurred, the negative number contains the error code.
*/ */
extern ssize_t net_con_send(struct net_connection* con, const void* buf, size_t len); extern ssize_t net_con_send(struct net_connection* con, const void* buf, size_t len);
@ -96,7 +97,7 @@ extern ssize_t net_con_send(struct net_connection* con, const void* buf, size_t
* *
* @return returns the number of bytes sent. * @return returns the number of bytes sent.
* 0 if no data is sent, and this function should be called again (EWOULDBLOCK/EINTR) * 0 if no data is sent, and this function should be called again (EWOULDBLOCK/EINTR)
* <0 if an error occured, the negative number contains the error code. * <0 if an error occurred, the negative number contains the error code.
*/ */
extern ssize_t net_con_recv(struct net_connection* con, void* buf, size_t len); extern ssize_t net_con_recv(struct net_connection* con, void* buf, size_t len);
@ -108,7 +109,7 @@ extern ssize_t net_con_recv(struct net_connection* con, void* buf, size_t len);
extern ssize_t net_con_peek(struct net_connection* con, void* buf, size_t len); extern ssize_t net_con_peek(struct net_connection* con, void* buf, size_t len);
/** /**
* Set timeout for connetion. * Set timeout for connection.
* *
* @param seconds the number of seconds into the future. * @param seconds the number of seconds into the future.
*/ */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2013, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -68,6 +68,11 @@ static void shutdown_free_results(void* ptr)
net_dns_result_free(result); net_dns_result_free(result);
} }
static void notify_callback(struct uhub_notify_handle* handle, void* ptr)
{
net_dns_process();
}
// NOTE: Any job manipulating the members of this // NOTE: Any job manipulating the members of this
// struct must lock the mutex! // struct must lock the mutex!
@ -76,6 +81,8 @@ struct net_dns_subsystem
struct linked_list* jobs; // currently running jobs struct linked_list* jobs; // currently running jobs
struct linked_list* results; // queue of results that are awaiting being delivered to callback. struct linked_list* results; // queue of results that are awaiting being delivered to callback.
uhub_mutex_t mutex; uhub_mutex_t mutex;
struct uhub_notify_handle* notify_handle; // used to signal back to the event loop that there is something to process.
}; };
static struct net_dns_subsystem* g_dns = NULL; static struct net_dns_subsystem* g_dns = NULL;
@ -87,13 +94,11 @@ void net_dns_initialize()
g_dns->jobs = list_create(); g_dns->jobs = list_create();
g_dns->results = list_create(); g_dns->results = list_create();
uhub_mutex_init(&g_dns->mutex); uhub_mutex_init(&g_dns->mutex);
g_dns->notify_handle = net_notify_create(notify_callback, g_dns);
} }
void net_dns_destroy() void net_dns_destroy()
{ {
struct net_dns_job* job;
struct net_dns_result* result;
uhub_mutex_lock(&g_dns->mutex); uhub_mutex_lock(&g_dns->mutex);
LOG_TRACE("net_dns_destroy(): jobs=%d", (int) list_size(g_dns->jobs)); LOG_TRACE("net_dns_destroy(): jobs=%d", (int) list_size(g_dns->jobs));
list_clear(g_dns->jobs, &shutdown_free_jobs); list_clear(g_dns->jobs, &shutdown_free_jobs);
@ -105,22 +110,18 @@ void net_dns_destroy()
list_destroy(g_dns->jobs); list_destroy(g_dns->jobs);
list_destroy(g_dns->results); list_destroy(g_dns->results);
uhub_mutex_destroy(&g_dns->mutex); uhub_mutex_destroy(&g_dns->mutex);
net_notify_destroy(g_dns->notify_handle);
hub_free(g_dns); hub_free(g_dns);
g_dns = NULL; g_dns = NULL;
} }
static void dummy_free(void* ptr)
{
}
void net_dns_process() void net_dns_process()
{ {
struct net_dns_result* result; struct net_dns_result* result;
uhub_mutex_lock(&g_dns->mutex); uhub_mutex_lock(&g_dns->mutex);
LOG_DUMP("net_dns_process(): jobs=%d, results=%d", (int) list_size(g_dns->jobs), (int) list_size(g_dns->results)); LOG_TRACE("net_dns_process(): jobs=%d, results=%d", (int) list_size(g_dns->jobs), (int) list_size(g_dns->results));
for (result = (struct net_dns_result*) list_get_first(g_dns->results); result; result = (struct net_dns_result*) list_get_next(g_dns->results)) LIST_FOREACH(struct net_dns_result*, result, g_dns->results,
{ {
struct net_dns_job* job = result->job; struct net_dns_job* job = result->job;
#ifdef DEBUG_LOOKUP_TIME #ifdef DEBUG_LOOKUP_TIME
@ -146,9 +147,9 @@ void net_dns_process()
result->job = NULL; result->job = NULL;
free_job(job); free_job(job);
} }
} });
list_clear(g_dns->results, &dummy_free); list_clear(g_dns->results, NULL);
uhub_mutex_unlock(&g_dns->mutex); uhub_mutex_unlock(&g_dns->mutex);
} }
@ -215,6 +216,7 @@ static void* job_thread_resolve_name(void* ptr)
uhub_mutex_lock(&g_dns->mutex); uhub_mutex_lock(&g_dns->mutex);
list_remove(g_dns->jobs, job); list_remove(g_dns->jobs, job);
list_append(g_dns->results, dns_results); list_append(g_dns->results, dns_results);
net_notify_signal(g_dns->notify_handle, 1);
uhub_mutex_unlock(&g_dns->mutex); uhub_mutex_unlock(&g_dns->mutex);
return dns_results; return dns_results;
@ -273,14 +275,14 @@ extern struct net_dns_job* net_dns_gethostbyaddr(struct ip_addr_encap* ipaddr, n
static struct net_dns_job* find_and_remove_job(struct net_dns_job* job) static struct net_dns_job* find_and_remove_job(struct net_dns_job* job)
{ {
struct net_dns_job* it; struct net_dns_job* it;
for (it = (struct net_dns_job*) list_get_first(g_dns->jobs); it; it = (struct net_dns_job*) list_get_next(g_dns->jobs)) LIST_FOREACH(struct net_dns_job*, it, g_dns->jobs,
{ {
if (it == job) if (it == job)
{ {
list_remove(g_dns->jobs, it); list_remove(g_dns->jobs, it);
return job; return job;
} }
} });
return NULL; return NULL;
} }
@ -288,14 +290,14 @@ static struct net_dns_job* find_and_remove_job(struct net_dns_job* job)
static struct net_dns_result* find_and_remove_result(struct net_dns_job* job) static struct net_dns_result* find_and_remove_result(struct net_dns_job* job)
{ {
struct net_dns_result* it; struct net_dns_result* it;
for (it = (struct net_dns_result*) list_get_first(g_dns->results); it; it = (struct net_dns_result*) list_get_next(g_dns->results)) LIST_FOREACH(struct net_dns_result*, it, g_dns->results,
{ {
if (it->job == job) if (it->job == job)
{ {
list_remove(g_dns->results, it); list_remove(g_dns->results, it);
return it; return it;
} }
} });
return NULL; return NULL;
} }

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2013, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2010, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2009, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2009, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -92,7 +92,7 @@ extern int ip_is_valid_ipv6(const char* address);
* *
* @param text_addr is an ipaddress either ipv6 or ipv4. * @param text_addr is an ipaddress either ipv6 or ipv4.
* Special magic addresses called "any" and "loopback" exist, * Special magic addresses called "any" and "loopback" exist,
* and will work accross IPv6/IPv4. * and will work across IPv6/IPv4.
* @param port Fill the struct sockaddr* with the given port, can safely be ignored. * @param port Fill the struct sockaddr* with the given port, can safely be ignored.
*/ */
extern int ip_convert_address(const char* text_address, int port, struct sockaddr* addr, socklen_t* addr_len); extern int ip_convert_address(const char* text_address, int port, struct sockaddr* addr, socklen_t* addr_len);

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2010, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2012, Jan Vidar Krey * Copyright (C) 2007-2019, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -805,4 +805,22 @@ void net_stats_add_close()
stats.closed++; stats.closed++;
} }
void net_stats_tls_add_accept()
{
stats.tls_accept++;
}
void net_stats_tls_add_connect()
{
stats.tls_connect++;
}
void net_stats_tls_add_error()
{
stats.tls_error++;
}
void net_stats_tls_add_close()
{
stats.tls_close++;
}

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2012, Jan Vidar Krey * Copyright (C) 2007-2019, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -28,6 +28,10 @@ struct net_statistics
size_t accept; size_t accept;
size_t closed; size_t closed;
size_t errors; size_t errors;
size_t tls_accept;
size_t tls_connect;
size_t tls_error;
size_t tls_close;
}; };
struct net_socket_t; struct net_socket_t;
@ -53,7 +57,7 @@ extern int net_initialize();
extern int net_destroy(); extern int net_destroy();
/** /**
* @return the number of sockets currrently being monitored. * @return the number of sockets currently being monitored.
*/ */
extern int net_monitor_count(); extern int net_monitor_count();
@ -63,7 +67,7 @@ extern int net_monitor_count();
extern int net_monitor_capacity(); extern int net_monitor_capacity();
/** /**
* @return the last error code occured. * @return the last error code occurred.
* *
* NOTE: On Windows this is the last error code from the socket library, but * NOTE: On Windows this is the last error code from the socket library, but
* on UNIX this is the errno variable that can be overwritten by any * on UNIX this is the errno variable that can be overwritten by any
@ -247,9 +251,14 @@ extern void net_stats_report();
extern void net_stats_reset(); extern void net_stats_reset();
extern void net_stats_add_tx(size_t bytes); extern void net_stats_add_tx(size_t bytes);
extern void net_stats_add_rx(size_t bytes); extern void net_stats_add_rx(size_t bytes);
extern void net_stats_tls_add_accept();
extern void net_stats_tls_add_connect();
extern void net_stats_tls_add_error();
extern void net_stats_tls_add_close();
extern void net_stats_add_accept(); extern void net_stats_add_accept();
extern void net_stats_add_error(); extern void net_stats_add_error();
extern void net_stats_add_close(); extern void net_stats_add_close();
extern void net_stats_add_connect();
extern int net_stats_timeout(); extern int net_stats_timeout();
extern void net_stats_get(struct net_statistics** intermediate, struct net_statistics** total); extern void net_stats_get(struct net_statistics** intermediate, struct net_statistics** total);

102
src/network/notify.c Normal file
View File

@ -0,0 +1,102 @@
/*
* uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2014, Jan Vidar Krey
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "uhub.h"
struct uhub_notify_handle
{
net_notify_callback callback;
void* ptr;
#ifndef WIN32
int pipe_fd[2];
struct net_connection* con;
#endif
};
/*
* This contains a mechanism to wake up the main thread
* in a thread safe manner while it would be blocking
* in select() or something equivalent typically invoked from
* net_backend_process().
*
* The main usage is for the DNS resolver to notify the
* main thread that there are DNS results to be
* processed.
*/
/**
* Create a notification handle.
*/
#ifndef WIN32
static void notify_callback(struct net_connection* con, int event, void* ptr)
{
LOG_TRACE("notify_callback()");
struct uhub_notify_handle* handle = (struct uhub_notify_handle*) ptr;
char buf;
int ret = read(handle->pipe_fd[0], &buf, 1);
if (ret == 1)
{
if (handle->callback)
handle->callback(handle, handle->ptr);
}
}
#endif
struct uhub_notify_handle* net_notify_create(net_notify_callback cb, void* ptr)
{
LOG_TRACE("net_notify_create()");
struct uhub_notify_handle* handle = (struct uhub_notify_handle*) hub_malloc(sizeof(struct uhub_notify_handle));
handle->callback = cb;
handle->ptr = ptr;
#ifndef WIN32
int ret = pipe(handle->pipe_fd);
if (ret == -1)
{
LOG_ERROR("Unable to setup notification pipes.");
hub_free(handle);
return 0;
}
handle->con = net_con_create();
net_con_initialize(handle->con, handle->pipe_fd[0], notify_callback, handle, NET_EVENT_READ);
#endif
return handle;
}
void net_notify_destroy(struct uhub_notify_handle* handle)
{
LOG_TRACE("net_notify_destroy()");
#ifndef WIN32
net_con_destroy(handle->con);
close(handle->pipe_fd[0]);
close(handle->pipe_fd[1]);
handle->pipe_fd[0] = -1;
handle->pipe_fd[0] = -1;
#endif
hub_free(handle);
}
void net_notify_signal(struct uhub_notify_handle* handle, char data)
{
LOG_TRACE("net_notify_signal()");
#ifndef WIN32
write(handle->pipe_fd[1], &data, 1);
#endif
}

56
src/network/notify.h Normal file
View File

@ -0,0 +1,56 @@
/*
* uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2014, Jan Vidar Krey
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#ifndef HAVE_UHUB_NETWORK_NOTIFY_API_H
#define HAVE_UHUB_NETWORK_NOTIFY_API_H
struct uhub_notify_handle;
typedef void (*net_notify_callback)(struct uhub_notify_handle* handle, void* ptr);
/*
* This contains a mechanism to wake up the main thread
* in a thread safe manner while it would be blocking
* in select() or something equivalent typically invoked from
* net_backend_process().
*
* The main usage is for the DNS resolver to notify the
* main thread that there are DNS results to be
* processed.
*/
/**
* Create a notification handle.
*/
struct uhub_notify_handle* net_notify_create(net_notify_callback cb, void* ptr);
/**
* Destroy a notification handle.
*/
void net_notify_destroy(struct uhub_notify_handle*);
/**
* Signal the notification handle, this will surely
* interrupt the net_backend_process(), and force it to
* process messages.
*/
void net_notify_signal(struct uhub_notify_handle*, char data);
#endif /* HAVE_UHUB_NETWORK_NOTIFY_API_H */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2012, Jan Vidar Krey * Copyright (C) 2007-2019, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,25 +13,33 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
#include "uhub.h" #include "uhub.h"
#include "network/common.h" #include "network/common.h"
#include "network/tls.h" #include "network/tls.h"
#include "network/backend.h"
#ifdef SSL_SUPPORT #ifdef SSL_SUPPORT
#ifdef SSL_USE_OPENSSL #ifdef SSL_USE_OPENSSL
void net_stats_add_tx(size_t bytes); void net_stats_add_tx(size_t bytes);
void net_stats_add_rx(size_t bytes); void net_stats_add_rx(size_t bytes);
void net_stats_tls_add_accept();
void net_stats_tls_add_errors();
void net_stats_tls_add_accept();
struct net_ssl_openssl struct net_ssl_openssl
{ {
SSL* ssl; SSL* ssl;
BIO* bio; BIO* bio;
enum ssl_state state; enum ssl_state state;
int events;
int ssl_read_events;
int ssl_write_events;
uint32_t flags; uint32_t flags;
size_t bytes_rx; size_t bytes_rx;
size_t bytes_tx; size_t bytes_tx;
@ -39,8 +47,7 @@ struct net_ssl_openssl
struct net_context_openssl struct net_context_openssl
{ {
SSL_METHOD* ssl_method; SSL_CTX* ssl;
SSL_CTX* ssl_ctx;
}; };
static struct net_ssl_openssl* get_handle(struct net_connection* con) static struct net_ssl_openssl* get_handle(struct net_connection* con)
@ -49,6 +56,29 @@ static struct net_ssl_openssl* get_handle(struct net_connection* con)
return (struct net_ssl_openssl*) con->ssl; return (struct net_ssl_openssl*) con->ssl;
} }
#ifdef DEBUG
static const char* get_state_str(enum ssl_state state)
{
switch (state)
{
case tls_st_none: return "tls_st_none";
case tls_st_error: return "tls_st_error";
case tls_st_accepting: return "tls_st_accepting";
case tls_st_connecting: return "tls_st_connecting";
case tls_st_connected: return "tls_st_connected";
case tls_st_disconnecting: return "tls_st_disconnecting";
}
uhub_assert(!"This should not happen - invalid state!");
return "(UNKNOWN STATE)";
}
#endif
static void net_ssl_set_state(struct net_ssl_openssl* handle, enum ssl_state new_state)
{
LOG_DEBUG("net_ssl_set_state(): prev_state=%s, new_state=%s", get_state_str(handle->state), get_state_str(new_state));
handle->state = new_state;
}
const char* net_ssl_get_provider() const char* net_ssl_get_provider()
{ {
return OPENSSL_VERSION_TEXT; return OPENSSL_VERSION_TEXT;
@ -65,7 +95,9 @@ int net_ssl_library_init()
int net_ssl_library_shutdown() int net_ssl_library_shutdown()
{ {
ERR_clear_error(); ERR_clear_error();
#if OPENSSL_VERSION_NUMBER < 0x10100000L
ERR_remove_state(0); ERR_remove_state(0);
#endif
ENGINE_cleanup(); ENGINE_cleanup();
CONF_modules_unload(1); CONF_modules_unload(1);
@ -80,56 +112,173 @@ int net_ssl_library_shutdown()
static void add_io_stats(struct net_ssl_openssl* handle) static void add_io_stats(struct net_ssl_openssl* handle)
{ {
if (handle->bio->num_read > handle->bytes_rx) #if OPENSSL_VERSION_NUMBER < 0x10100000L
unsigned long num_read = handle->bio->num_read;
unsigned long num_write = handle->bio->num_write;
#else
unsigned long num_read = BIO_number_read(handle->bio);
unsigned long num_write = BIO_number_written(handle->bio);
#endif
if (num_read > handle->bytes_rx)
{ {
net_stats_add_rx(handle->bio->num_read - handle->bytes_rx); net_stats_add_rx(num_read - handle->bytes_rx);
handle->bytes_rx = handle->bio->num_read; handle->bytes_rx = num_read;
} }
if (handle->bio->num_write > handle->bytes_tx) if (num_write > handle->bytes_tx)
{ {
net_stats_add_tx(handle->bio->num_write - handle->bytes_tx); net_stats_add_tx(num_write - handle->bytes_tx);
handle->bytes_tx = handle->bio->num_write; handle->bytes_tx = num_write;
} }
} }
static const SSL_METHOD* get_ssl_method(const char* tls_version, long* flags)
{
if (!flags)
{
LOG_ERROR("flags is null");
return 0;
}
if (!tls_version || !*tls_version)
{
LOG_ERROR("tls_version is not set.");
return 0;
}
*flags = 0;
*flags |= SSL_OP_NO_SSLv2;
*flags |= SSL_OP_NO_SSLv3;
if (!strcmp(tls_version, "1.0"))
{
#if OPENSSL_VERSION_NUMBER < 0x10100000L
return TLSv1_method();
#endif
}
else if (!strcmp(tls_version, "1.1"))
{
#if OPENSSL_VERSION_NUMBER < 0x10100000L
return TLSv1_1_method();
#else
*flags |= SSL_OP_NO_TLSv1;
#endif
}
else if (!strcmp(tls_version, "1.2"))
{
#if OPENSSL_VERSION_NUMBER < 0x10100000L
return TLSv1_2_method();
#else
*flags |= SSL_OP_NO_TLSv1;
*flags |= SSL_OP_NO_TLSv1_1;
#endif
}
else if (!strcmp(tls_version, "1.3"))
{
#if OPENSSL_VERSION_NUMBER < 0x10100000L
LOG_ERROR("TLS 1.3 is not supported by this version of OpenSSL");
return 0;
#else
*flags |= SSL_OP_NO_TLSv1;
*flags |= SSL_OP_NO_TLSv1_1;
*flags |= SSL_OP_NO_TLSv1_2;
#endif
}
else
{
LOG_ERROR("Unable to recognize tls_version: %s", tls_version);
return 0;
}
#if OPENSSL_VERSION_NUMBER < 0x10100000L
// never gets here!
#else
return TLS_method();
#endif
}
/**
* List of supported protocols for ALPN.
* We only support "adc" protocol.
*/
unsigned char alpn_protocols[] = {
3, 'a', 'd', 'c',
};
/**
* Callback for the server to select a protocol from the list
* sent by the client via ALPN.
*/
static int alpn_server_select_protocol(SSL *ssl, const unsigned char **out, unsigned char *outlen,
const unsigned char *in, unsigned int inlen, void *arg)
{
int res = SSL_select_next_proto((unsigned char **)out, outlen,
alpn_protocols, sizeof(alpn_protocols), in, inlen);
if (res == OPENSSL_NPN_NO_OVERLAP)
{
// set default protocol
*out = alpn_protocols;
*outlen = 1+alpn_protocols[0];
}
return SSL_TLSEXT_ERR_OK;
}
/** /**
* Create a new SSL context. * Create a new SSL context.
*/ */
struct ssl_context_handle* net_ssl_context_create() struct ssl_context_handle* net_ssl_context_create(const char* tls_version, const char* tls_ciphersuite)
{ {
struct net_context_openssl* ctx = (struct net_context_openssl*) hub_malloc_zero(sizeof(struct net_context_openssl)); struct net_context_openssl* ctx = (struct net_context_openssl*) hub_malloc_zero(sizeof(struct net_context_openssl));
ctx->ssl_method = (SSL_METHOD*) SSLv23_method(); /* TLSv1_method() */ long flags = 0;
ctx->ssl_ctx = SSL_CTX_new(ctx->ssl_method); const SSL_METHOD* ssl_method = get_ssl_method(tls_version, &flags);
/* Disable SSLv2 */ if (!ssl_method)
SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv2); {
hub_free(ctx);
return 0;
}
ctx->ssl = SSL_CTX_new(ssl_method);
// FIXME: Why did we need this again?
SSL_CTX_set_quiet_shutdown(ctx->ssl, 1);
#ifdef SSL_OP_NO_COMPRESSION #ifdef SSL_OP_NO_COMPRESSION
/* Disable compression? */ /* Disable compression */
LOG_TRACE("Disabling SSL compression."); /* "CRIME" attack */ LOG_TRACE("Disabling SSL compression."); /* "CRIME" attack */
SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_COMPRESSION); flags |= SSL_OP_NO_COMPRESSION;
#endif #endif
SSL_CTX_set_quiet_shutdown(ctx->ssl_ctx, 1); // Set flags
SSL_CTX_set_options(ctx->ssl, flags);
/* Set preferred cipher suite */
if (SSL_CTX_set_cipher_list(ctx->ssl, tls_ciphersuite) != 1)
{
LOG_ERROR("Unable to set cipher suite.");
SSL_CTX_free(ctx->ssl);
hub_free(ctx);
return 0;
}
SSL_CTX_set_alpn_select_cb(ctx->ssl, alpn_server_select_protocol, NULL);
return (struct ssl_context_handle*) ctx; return (struct ssl_context_handle*) ctx;
} }
extern void net_ssl_context_destroy(struct ssl_context_handle* ctx_) void net_ssl_context_destroy(struct ssl_context_handle* ctx_)
{ {
struct net_context_openssl* ctx = (struct net_context_openssl*) ctx_; struct net_context_openssl* ctx = (struct net_context_openssl*) ctx_;
SSL_CTX_free(ctx->ssl_ctx); SSL_CTX_free(ctx->ssl);
hub_free(ctx); hub_free(ctx);
} }
int ssl_load_certificate(struct ssl_context_handle* ctx_, const char* pem_file) int ssl_load_certificate(struct ssl_context_handle* ctx_, const char* pem_file)
{ {
struct net_context_openssl* ctx = (struct net_context_openssl*) ctx_; struct net_context_openssl* ctx = (struct net_context_openssl*) ctx_;
if (SSL_CTX_use_certificate_file(ctx->ssl_ctx, pem_file, SSL_FILETYPE_PEM) < 0) if (SSL_CTX_use_certificate_chain_file(ctx->ssl, pem_file) < 0)
{ {
LOG_ERROR("SSL_CTX_use_certificate_file: %s", ERR_error_string(ERR_get_error(), NULL)); LOG_ERROR("SSL_CTX_use_certificate_chain_file: %s", ERR_error_string(ERR_get_error(), NULL));
return 0; return 0;
} }
@ -139,7 +288,7 @@ int ssl_load_certificate(struct ssl_context_handle* ctx_, const char* pem_file)
int ssl_load_private_key(struct ssl_context_handle* ctx_, const char* pem_file) int ssl_load_private_key(struct ssl_context_handle* ctx_, const char* pem_file)
{ {
struct net_context_openssl* ctx = (struct net_context_openssl*) ctx_; struct net_context_openssl* ctx = (struct net_context_openssl*) ctx_;
if (SSL_CTX_use_PrivateKey_file(ctx->ssl_ctx, pem_file, SSL_FILETYPE_PEM) < 0) if (SSL_CTX_use_PrivateKey_file(ctx->ssl, pem_file, SSL_FILETYPE_PEM) < 0)
{ {
LOG_ERROR("SSL_CTX_use_PrivateKey_file: %s", ERR_error_string(ERR_get_error(), NULL)); LOG_ERROR("SSL_CTX_use_PrivateKey_file: %s", ERR_error_string(ERR_get_error(), NULL));
return 0; return 0;
@ -150,7 +299,7 @@ int ssl_load_private_key(struct ssl_context_handle* ctx_, const char* pem_file)
int ssl_check_private_key(struct ssl_context_handle* ctx_) int ssl_check_private_key(struct ssl_context_handle* ctx_)
{ {
struct net_context_openssl* ctx = (struct net_context_openssl*) ctx_; struct net_context_openssl* ctx = (struct net_context_openssl*) ctx_;
if (SSL_CTX_check_private_key(ctx->ssl_ctx) != 1) if (SSL_CTX_check_private_key(ctx->ssl) != 1)
{ {
LOG_FATAL("SSL_CTX_check_private_key: Private key does not match the certificate public key: %s", ERR_error_string(ERR_get_error(), NULL)); LOG_FATAL("SSL_CTX_check_private_key: Private key does not match the certificate public key: %s", ERR_error_string(ERR_get_error(), NULL));
return 0; return 0;
@ -158,7 +307,7 @@ int ssl_check_private_key(struct ssl_context_handle* ctx_)
return 1; return 1;
} }
static int handle_openssl_error(struct net_connection* con, int ret, enum ssl_state forced_rwstate) static int handle_openssl_error(struct net_connection* con, int ret, int read)
{ {
struct net_ssl_openssl* handle = get_handle(con); struct net_ssl_openssl* handle = get_handle(con);
int err = SSL_get_error(handle->ssl, ret); int err = SSL_get_error(handle->ssl, ret);
@ -169,33 +318,47 @@ static int handle_openssl_error(struct net_connection* con, int ret, enum ssl_st
return -1; return -1;
case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_READ:
handle->state = forced_rwstate; if (read)
net_con_update(con, NET_EVENT_READ); handle->ssl_read_events = NET_EVENT_READ;
else
handle->ssl_write_events = NET_EVENT_READ;
return 0; return 0;
case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_WRITE:
handle->state = forced_rwstate; if (read)
net_con_update(con, NET_EVENT_WRITE); handle->ssl_read_events = NET_EVENT_WRITE;
else
handle->ssl_write_events = NET_EVENT_WRITE;
return 0; return 0;
case SSL_ERROR_SSL:
net_ssl_set_state(handle, tls_st_error);
net_stats_tls_add_error();
return -2;
case SSL_ERROR_SYSCALL: case SSL_ERROR_SYSCALL:
handle->state = tls_st_error; net_ssl_set_state(handle, tls_st_error);
net_stats_tls_add_error();
return -2; return -2;
} }
net_stats_tls_add_error();
return -2;
} }
ssize_t net_con_ssl_accept(struct net_connection* con) ssize_t net_con_ssl_accept(struct net_connection* con)
{ {
struct net_ssl_openssl* handle = get_handle(con); struct net_ssl_openssl* handle = get_handle(con);
handle->state = tls_st_accepting;
ssize_t ret; ssize_t ret;
net_ssl_set_state(handle, tls_st_accepting);
ret = SSL_accept(handle->ssl); ret = SSL_accept(handle->ssl);
LOG_PROTO("SSL_accept() ret=%d", ret); LOG_PROTO("SSL_accept() ret=%d", ret);
if (ret > 0) if (ret > 0)
{ {
net_con_update(con, NET_EVENT_READ); net_con_update(con, NET_EVENT_READ);
handle->state = tls_st_connected; net_ssl_set_state(handle, tls_st_connected);
net_stats_tls_add_accept();
return ret; return ret;
} }
return handle_openssl_error(con, ret, tls_st_accepting); return handle_openssl_error(con, ret, tls_st_accepting);
@ -205,30 +368,37 @@ ssize_t net_con_ssl_connect(struct net_connection* con)
{ {
struct net_ssl_openssl* handle = get_handle(con); struct net_ssl_openssl* handle = get_handle(con);
ssize_t ret; ssize_t ret;
handle->state = tls_st_connecting; net_ssl_set_state(handle, tls_st_connecting);
ret = SSL_connect(handle->ssl); ret = SSL_connect(handle->ssl);
LOG_PROTO("SSL_connect() ret=%d", ret); LOG_PROTO("SSL_connect() ret=%d", ret);
if (ret > 0) if (ret > 0)
{ {
handle->state = tls_st_connected;
net_con_update(con, NET_EVENT_READ); net_con_update(con, NET_EVENT_READ);
net_ssl_set_state(handle, tls_st_connected);
net_stats_tls_add_connect();
return ret; return ret;
} }
return handle_openssl_error(con, ret, tls_st_connecting);
ret = handle_openssl_error(con, ret, tls_st_connecting);
if (ret != 0)
LOG_ERROR("net_con_ssl_connect: ret=%d", ret);
return ret;
} }
ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode ssl_mode, struct ssl_context_handle* ssl_ctx) ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode ssl_mode, struct ssl_context_handle* ssl_ctx)
{ {
uhub_assert(con); uhub_assert(con);
uhub_assert(ssl_ctx);
struct net_context_openssl* ctx = (struct net_context_openssl*) ssl_ctx; struct net_context_openssl* ctx = (struct net_context_openssl*) ssl_ctx;
struct net_ssl_openssl* handle = (struct net_ssl_openssl*) hub_malloc_zero(sizeof(struct net_ssl_openssl)); struct net_ssl_openssl* handle = (struct net_ssl_openssl*) hub_malloc_zero(sizeof(struct net_ssl_openssl));
if (ssl_mode == net_con_ssl_mode_server) if (ssl_mode == net_con_ssl_mode_server)
{ {
handle->ssl = SSL_new(ctx->ssl_ctx); handle->ssl = SSL_new(ctx->ssl);
if (!handle->ssl) if (!handle->ssl)
{ {
LOG_ERROR("Unable to create new SSL stream\n"); LOG_ERROR("Unable to create new SSL stream\n");
@ -241,32 +411,38 @@ ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode
} }
else else
{ {
handle->ssl = SSL_new(SSL_CTX_new(TLSv1_method())); handle->ssl = SSL_new(ctx->ssl);
SSL_set_fd(handle->ssl, con->sd); SSL_set_fd(handle->ssl, con->sd);
handle->bio = SSL_get_rbio(handle->ssl); handle->bio = SSL_get_rbio(handle->ssl);
con->ssl = (struct ssl_handle*) handle; con->ssl = (struct ssl_handle*) handle;
return net_con_ssl_connect(con); return net_con_ssl_connect(con);
} }
} }
ssize_t net_ssl_send(struct net_connection* con, const void* buf, size_t len) ssize_t net_ssl_send(struct net_connection* con, const void* buf, size_t len)
{ {
struct net_ssl_openssl* handle = get_handle(con); struct net_ssl_openssl* handle = get_handle(con);
uhub_assert(handle->state == tls_st_connected || handle->state == tls_st_need_write); LOG_TRACE("net_ssl_send(), state=%d", (int) handle->state);
if (handle->state == tls_st_error)
return -2;
uhub_assert(handle->state == tls_st_connected);
ERR_clear_error(); ERR_clear_error();
ssize_t ret = SSL_write(handle->ssl, buf, len); ssize_t ret = SSL_write(handle->ssl, buf, len);
add_io_stats(handle); add_io_stats(handle);
LOG_PROTO("SSL_write(con=%p, buf=%p, len=" PRINTF_SIZE_T ") => %d", con, buf, len, ret); LOG_PROTO("SSL_write(con=%p, buf=%p, len=" PRINTF_SIZE_T ") => %d", con, buf, len, ret);
if (ret > 0) if (ret > 0)
{ handle->ssl_write_events = 0;
handle->state = tls_st_connected; else
ret = handle_openssl_error(con, ret, 0);
net_ssl_update(con, handle->events); // Update backend only
return ret; return ret;
} }
return handle_openssl_error(con, ret, tls_st_need_write);
}
ssize_t net_ssl_recv(struct net_connection* con, void* buf, size_t len) ssize_t net_ssl_recv(struct net_connection* con, void* buf, size_t len)
{ {
@ -276,7 +452,10 @@ ssize_t net_ssl_recv(struct net_connection* con, void* buf, size_t len)
if (handle->state == tls_st_error) if (handle->state == tls_st_error)
return -2; return -2;
uhub_assert(handle->state == tls_st_connected || handle->state == tls_st_need_read); if (handle->state == tls_st_accepting || handle->state == tls_st_connecting)
return -1;
uhub_assert(handle->state == tls_st_connected);
ERR_clear_error(); ERR_clear_error();
@ -284,29 +463,43 @@ ssize_t net_ssl_recv(struct net_connection* con, void* buf, size_t len)
add_io_stats(handle); add_io_stats(handle);
LOG_PROTO("SSL_read(con=%p, buf=%p, len=" PRINTF_SIZE_T ") => %d", con, buf, len, ret); LOG_PROTO("SSL_read(con=%p, buf=%p, len=" PRINTF_SIZE_T ") => %d", con, buf, len, ret);
if (ret > 0) if (ret > 0)
{ handle->ssl_read_events = 0;
handle->state = tls_st_connected; else
ret = handle_openssl_error(con, ret, 1);
net_ssl_update(con, handle->events); // Update backend only
return ret; return ret;
} }
return handle_openssl_error(con, ret, tls_st_need_read);
void net_ssl_update(struct net_connection* con, int events)
{
struct net_ssl_openssl* handle = get_handle(con);
handle->events = events;
net_backend_update(con, handle->events | handle->ssl_read_events | handle->ssl_write_events);
} }
void net_ssl_shutdown(struct net_connection* con) void net_ssl_shutdown(struct net_connection* con)
{ {
struct net_ssl_openssl* handle = get_handle(con); struct net_ssl_openssl* handle = get_handle(con);
if (handle)
{
SSL_shutdown(handle->ssl); SSL_shutdown(handle->ssl);
SSL_clear(handle->ssl); SSL_clear(handle->ssl);
} }
}
void net_ssl_destroy(struct net_connection* con) void net_ssl_destroy(struct net_connection* con)
{ {
struct net_ssl_openssl* handle = get_handle(con); struct net_ssl_openssl* handle = get_handle(con);
LOG_TRACE("net_ssl_destroy: %p", con);
SSL_free(handle->ssl); SSL_free(handle->ssl);
hub_free(handle);
} }
void net_ssl_callback(struct net_connection* con, int events) void net_ssl_callback(struct net_connection* con, int events)
{ {
struct net_ssl_openssl* handle = get_handle(con); struct net_ssl_openssl* handle = get_handle(con);
int ret;
switch (handle->state) switch (handle->state)
{ {
@ -315,7 +508,7 @@ void net_ssl_callback(struct net_connection* con, int events)
break; break;
case tls_st_error: case tls_st_error:
con->callback(con, NET_EVENT_READ, con->ptr); con->callback(con, NET_EVENT_ERROR, con->ptr);
break; break;
case tls_st_accepting: case tls_st_accepting:
@ -324,19 +517,27 @@ void net_ssl_callback(struct net_connection* con, int events)
break; break;
case tls_st_connecting: case tls_st_connecting:
if (net_con_ssl_connect(con) != 0) ret = net_con_ssl_connect(con);
con->callback(con, NET_EVENT_READ, con->ptr); if (ret == 0)
break; return;
case tls_st_need_read: if (ret > 0)
{
LOG_DEBUG("%p SSL connected!", con);
con->callback(con, NET_EVENT_READ, con->ptr); con->callback(con, NET_EVENT_READ, con->ptr);
break; }
else
case tls_st_need_write: {
con->callback(con, NET_EVENT_WRITE, con->ptr); LOG_DEBUG("%p SSL handshake failed!", con);
con->callback(con, NET_EVENT_ERROR, con->ptr);
}
break; break;
case tls_st_connected: case tls_st_connected:
if (handle->ssl_read_events & events)
events |= NET_EVENT_READ;
if (handle->ssl_write_events & events)
events |= NET_EVENT_WRITE;
con->callback(con, events, con->ptr); con->callback(con, events, con->ptr);
break; break;
@ -345,6 +546,18 @@ void net_ssl_callback(struct net_connection* con, int events)
} }
} }
const char* net_ssl_get_tls_version(struct net_connection* con)
{
struct net_ssl_openssl* handle = get_handle(con);
return SSL_get_version(handle->ssl);
}
const char* net_ssl_get_tls_cipher(struct net_connection* con)
{
struct net_ssl_openssl* handle = get_handle(con);
const SSL_CIPHER *cipher = SSL_get_current_cipher(handle->ssl);
return SSL_CIPHER_get_name(cipher);
}
#endif /* SSL_USE_OPENSSL */ #endif /* SSL_USE_OPENSSL */
#endif /* SSL_SUPPORT */ #endif /* SSL_SUPPORT */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2010, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */

View File

@ -1,6 +1,6 @@
/* /*
* uhub - A tiny ADC p2p connection hub * uhub - A tiny ADC p2p connection hub
* Copyright (C) 2007-2010, Jan Vidar Krey * Copyright (C) 2007-2014, Jan Vidar Krey
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along wtimeout_evtith this program. If not, see <http://www.gnu.org/licenses/>. * along wtimeout_evtith this program. If not, see <https://www.gnu.org/licenses/>.
* *
*/ */
@ -42,6 +42,7 @@ void timeout_queue_initialize(struct timeout_queue* t, time_t now, size_t max)
{ {
t->last = now; t->last = now;
t->max = max; t->max = max;
memset(&t->lock, 0, sizeof(t->lock));
t->events = hub_malloc_zero(max * sizeof(struct timeout_evt*)); t->events = hub_malloc_zero(max * sizeof(struct timeout_evt*));
} }
@ -52,12 +53,56 @@ void timeout_queue_shutdown(struct timeout_queue* t)
t->max = 0; t->max = 0;
} }
static int timeout_queue_locked(struct timeout_queue* t)
{
return t->lock.ptr != NULL;
}
static void timeout_queue_lock(struct timeout_queue* t)
{
t->lock.ptr = t;
}
// unlock and flush the locked events to the main timeout queue.
static void timeout_queue_unlock(struct timeout_queue* t)
{
struct timeout_evt* evt, *tmp, *first;
size_t pos;
t->lock.ptr = NULL;
evt = t->lock.next;
while (evt)
{
tmp = evt->next;
pos = evt->timestamp % t->max;
first = t->events[pos];
if (first)
{
first->prev->next = evt;
evt->prev = first->prev;
first->prev = evt;
}
else
{
t->events[pos] = evt;
evt->prev = evt;
}
evt->next = 0;
evt = tmp;
}
t->lock.next = 0;
t->lock.prev = 0;
}
size_t timeout_queue_process(struct timeout_queue* t, time_t now) size_t timeout_queue_process(struct timeout_queue* t, time_t now)
{ {
size_t pos = (size_t) t->last; size_t pos = (size_t) t->last;
size_t events = 0; size_t events = 0;
struct timeout_evt* evt = 0; struct timeout_evt* evt = 0;
t->last = now; t->last = now;
timeout_queue_lock(t);
for (; pos <= now; pos++) for (; pos <= now; pos++)
{ {
while ((evt = t->events[pos % t->max])) while ((evt = t->events[pos % t->max]))
@ -67,6 +112,7 @@ size_t timeout_queue_process(struct timeout_queue* t, time_t now)
events++; events++;
} }
} }
timeout_queue_unlock(t);
return events; return events;
} }
@ -82,6 +128,61 @@ size_t timeout_queue_get_next_timeout(struct timeout_queue* t, time_t now)
return seconds; return seconds;
} }
static void timeout_queue_insert_locked(struct timeout_queue* t, struct timeout_evt* evt)
{
/* All events point back to the sentinel.
* this means the event is considered schedule (see timeout_evt_is_scheduled),
* and it is easy to tell if the event is in the wait queue or not.
*/
evt->prev = &t->lock;
evt->next = NULL;
// The sentinel next points to the first event in the locked queue
// The sentinel prev points to the last evetnt in the locked queue.
// NOTE: if prev is != NULL then next also must be != NULL.
if (t->lock.prev)
{
t->lock.prev->next = evt;
t->lock.prev = evt;
}
else
{
t->lock.next = evt;
t->lock.prev = evt;
}
return;
}
static void timeout_queue_remove_locked(struct timeout_queue* t, struct timeout_evt* evt)
{
uhub_assert(evt->prev == &t->lock);
if (t->lock.next == evt)
{
t->lock.next = evt->next;
if (t->lock.prev == evt)
t->lock.prev = evt->next;
}
else
{
struct timeout_evt *prev, *it;
prev = 0;
it = t->lock.next;
while (it)
{
prev = it;
it = it->next;
if (it == evt)
{
prev->next = it->next;
if (!prev->next)
t->lock.prev = prev;
}
}
}
timeout_evt_reset(evt);
}
void timeout_queue_insert(struct timeout_queue* t, struct timeout_evt* evt, size_t seconds) void timeout_queue_insert(struct timeout_queue* t, struct timeout_evt* evt, size_t seconds)
{ {
@ -90,6 +191,12 @@ void timeout_queue_insert(struct timeout_queue* t, struct timeout_evt* evt, size
evt->timestamp = t->last + seconds; evt->timestamp = t->last + seconds;
evt->next = 0; evt->next = 0;
if (timeout_queue_locked(t))
{
timeout_queue_insert_locked(t, evt);
return;
}
first = t->events[pos]; first = t->events[pos];
if (first) if (first)
@ -112,6 +219,13 @@ void timeout_queue_remove(struct timeout_queue* t, struct timeout_evt* evt)
size_t pos = (evt->timestamp % t->max); size_t pos = (evt->timestamp % t->max);
struct timeout_evt* first = t->events[pos]; struct timeout_evt* first = t->events[pos];
// Removing a locked event
if (evt->prev == &t->lock)
{
timeout_queue_remove_locked(t, evt);
return;
}
if (!first || !evt->prev) if (!first || !evt->prev)
return; return;

Some files were not shown because too many files have changed in this diff Show More