Compare commits

..
Author SHA1 Message Date
Jan Vidar Krey c7d40dc6e0 Add missing file (Stub) 2019-01-22 18:29:06 +01:00
Jan Vidar Krey 9ac1a378d0 WIP 2019-01-17 18:57:19 +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
Jan Vidar Krey f6f7c7a3a4 Make sure we compile release builds with NDEBUG defined (to disable asserts). 2013-02-05 22:44:31 +01:00
Jan Vidar Krey 1fbde2b0fd Re-factored the ADC client code to use the new connection establishment API. 2013-02-05 22:43:59 +01:00
Jan Vidar Krey 92b65a0e14 Created a connection establishment API.
This API provides transparent asynchronous DNS lookups
with both IPv4 and IPv6 support, and in addition will try
to connect to all addresses until one of them work.

This implements the "happy eyeballs" algorithm provided that the client supports IPv6
and that the DNS records provides both IPv6 and IPv4 addresses.
2013-02-05 22:40:20 +01:00
Jan Vidar Krey 4d438e1e90 Don't poll the connection monitor if there are no connections added.
This caused the backends to return an error code, which
in turn ended the mainloop. However, several other things
also might occur in the main loop, such as DNS lookups which
come prior to creating any connections that in turn would be monitored.
2013-02-05 22:38:13 +01:00
Jan Vidar Krey 4f3c71234b Merge branch 'master' of https://github.com/3M3RY/uhub 2012-11-22 22:26:46 +01:00
Jan Vidar Krey fdaadccb99 Merge pull request #18 from tehnick/fix-build-on-hurd-i386
(tehnick) Fix build in Debian GNU/Hurd.
2012-11-23 02:25:36 -08:00
Jan Vidar Krey 41251f8d32 Install uhub-passwd also. 2012-11-20 22:53:27 +01:00
Jan Vidar Krey 3b18ae251e Automatically find Sqlite3 - removed option to disable it.
This means Sqlite3 is now mandatory.
2012-11-20 22:53:27 +01:00
Boris Pek b452488431 Fix build in Debian GNU/Hurd. 2012-11-20 22:41:38 +02:00
Emery 143b68588a Systemd notify support 2012-11-17 09:57:14 -06:00
Jan Vidar Krey 5f2b7bc069 Merge pull request #16 from 3M3RY/master
Systemd journaling support
2012-11-11 23:56:51 -08:00
Emery ce68c446d1 Optional systemd journal logging 2012-11-11 15:21:00 -06: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
Jan Vidar Krey 6af0f293a6 Updated changelog for 0.4.1 release. 2012-11-07 20:24:06 +01:00
Jan Vidar Krey a492f30950 Update authors file. 2012-11-07 20:08:28 +01:00
Jan Vidar Krey a43953bc0d Added simple plugin that blocks downloads for non-registered users (guests). 2012-11-01 22:07:55 +01:00
Jan Vidar Krey 594801df46 Fix windows compile issues. 2012-11-01 21:52:33 +01:00
Jan Vidar Krey 3dcbb63a31 Implemented a simlpe red-black tree which should give better performance
for certain lookups.

The rb_tree will act as a general purpose key/value storage, and
also give a performance boost in the cases where the other
simple alternative would be to use a linked_list.

On average this should give on average O(log n) lookups, while the linked_list
would be O(n) at worst.
2012-11-01 21:46:44 +01:00
Jan Vidar Krey 5d6184961b Fix a failing test on Windows. 2012-11-01 21:18:49 +01:00
Jan Vidar Krey b17e88573e Fixed Windows VC compile issues with autotests. 2012-11-01 21:10:51 +01:00
Jan Vidar Krey 2d2ccc0039 Merge branch 'async_dns_api' 2012-11-01 10:42:19 +01:00
Jan Vidar Krey 0a2f9c4b79 Merge branch 'autotest' 2012-11-01 10:40:51 +01:00
Jan Vidar Krey ae62c35cb9 Disable SSL compression. 2012-11-01 10:39:31 +01:00
Jan Vidar Krey 2ec2e73f16 Make sure we always build the autotests.
Caveat, need to run the update script manually after changing the tests (adding or removing tests).
However, modifying existing tests does not require running the update script.

Added a copy of exotic in the repository

exotic automatically generates the skeleton code around the autotests in order to schedule
the tests.
2012-10-25 17:27:45 +02:00
Jan Vidar Krey d4763e54db Fixed memory leaks. 2012-10-25 04:13:45 +02:00
Jan Vidar Krey 38b19f633d Fix memory leaks and report "host is not found" correctly. 2012-10-25 04:13:05 +02:00
Jan Vidar Krey d106ecdc65 Bugfixes for pthreads. 2012-10-25 04:10:42 +02:00
Jan Vidar Krey 99a2307d1d Simple compile fix. 2012-10-25 00:44:21 +02:00
Jan Vidar Krey 470c936e63 Converted the DNS resolver to work with the new threading API abstraction. 2012-10-25 00:40:16 +02:00
Jan Vidar Krey 168fc5bfcc Abstracted the threading code so that it works with Winthreads and pthreads. 2012-10-25 00:39:44 +02:00
Jan Vidar Krey b34b90f95a Start using the async DNS API. 2012-10-24 23:22:10 +02:00
Jan Vidar Krey 793790d089 Initial implementation of an async DNS client API with getaddrinfo + pthreads. 2012-10-24 23:19:14 +02:00
Jan Vidar Krey 19559f4974 Make sure we count OpenSSL traffic for the byte IO statistics. 2012-10-18 11:40:18 +02:00
Jan Vidar Krey b999068555 Use OpenSSL by default. 2012-10-17 19:02:32 +00:00
Jan Vidar Krey 4385266bb7 Free all memory in case the hub does not start because of port already in use. 2012-10-17 20:54:46 +02:00
Jan Vidar Krey c50eb90bee Removed the last bits of OpenSSL code called directly 2012-10-17 20:53:05 +02:00
Jan Vidar Krey 1e0927f510 Update copyright year. 2012-10-17 20:00:52 +02:00
Jan Vidar Krey b9d43c784c Merge branch 'master' of github.com:janvidar/uhub
Conflicts:
	CMakeLists.txt
2012-10-17 19:59:02 +02:00
Jan Vidar Krey 46d365cafe Merge branch 'gnutls_work' 2012-10-17 15:47:16 +02:00
Jan Vidar Krey 2f830d3132 Cleaned up error handling. 2012-10-17 15:39:48 +02:00
Jan Vidar Krey 5884983a2f Return -1 as error for recv/send only to signal socket has closed, use a number < -1 for socket errors. 2012-10-17 15:02:32 +02:00
Jan Vidar Krey c43acd97bd Fixed accept/connect state event propagation.
Also removed some unused states and flags.
2012-10-17 09:25:15 +02:00
Jan Vidar Krey b1f2c93738 Reworked the error handling of non-blocking reads and writes.
This should prevent busy loops where the socket is makred readable
but we are really only looking for it to become writable.
2012-10-17 09:16:02 +02:00
Jan Vidar Krey 50912bdf75 More work on splitting out OpenSSL specific bits. 2012-10-15 20:39:03 +02:00
Jan Vidar Krey 3a8c91004e fixup! Add possibility to specify UHUB_REVISION manually. 2012-10-15 20:27:43 +02:00
Boris Pek deaadd053b Add possibility to specify UHUB_REVISION manually. 2012-10-15 20:24:42 +02:00
Jan Vidar Krey c28a5d3a9b Merge branch 'master' of github.com:janvidar/uhub 2012-10-15 20:20:17 +02:00
Jan Vidar Krey 8b06a75d8e Revert "Add possibility to specify UHUB_REVISION manually."
This reverts commit dcfcf3110d.
2012-10-15 00:24:59 +02:00
Jan Vidar Krey e6cb7a7e10 Revert "Add possibility to specify UHUB_REVISION manually."
This reverts commit dcfcf3110d.
2012-10-14 22:24:33 +00:00
Jan Vidar Krey 82caa6b81f Merge pull request #14 from tehnick/fix-build-on-kfreebsd-any
Fix build in Debian GNU/kFreeBSD.
2012-10-14 15:19:21 -07:00
Boris Pek ddfbb919a7 Fix build in Debian GNU/kFreeBSD. 2012-10-14 02:13:10 +03:00
Jan Vidar Krey 7fae42aa4d Merge pull request #12 from tehnick/fix-version
Add possibility to specify UHUB_REVISION manually.
2012-10-13 10:34:39 -07:00
Jan Vidar Krey ba59e1a00e Merge pull request #13 from tehnick/cmake-up
Simplify CMakeLists.txt
2012-10-13 10:34:23 -07:00
Jan Vidar Krey 4fcfee8e82 Merge pull request #11 from tehnick/fix-plugins-location
Use directory /usr/lib/uhub/ instead of /var/lib/uhub/
2012-10-13 10:33:09 -07:00
Boris Pek 63171b0ce2 Simplify CMakeLists.txt 2012-10-13 20:13:15 +03:00
Boris Pek dcfcf3110d Add possibility to specify UHUB_REVISION manually. 2012-10-13 19:46:44 +03:00
Boris Pek 53a5f5a243 Use directory /usr/lib/uhub/ instead of /var/lib/uhub/
in according with FHS (Filesystem Hierarchy Standard).
2012-10-13 18:48:24 +03:00
Jan Vidar Krey f3922bb3e0 Work on splitting out OpenSSL cleanly. 2012-10-12 14:24:03 +02:00
Jan Vidar Krey af083efb0c fixup! Don't compile the utils files multiple times. 2012-10-09 22:14:38 +02:00
Jan Vidar Krey e7aa63f3bd Don't compile the utils files multiple times. 2012-10-09 22:09:25 +02:00
Jan Vidar Krey 279c932b67 fixup! Add install make rule. 2012-10-09 19:31:54 +02:00
Jan Vidar Krey 69603ff70f Add install make rule. 2012-10-09 14:36:14 +02:00
Jan Vidar Krey f20c42d05f Wrapped everything OpenSSL related in a SSL_USE_OPENSSL check macro. 2012-10-02 23:59:11 +02:00
Jan Vidar Krey 3ea38c59af Better reporting using the !stats command. 2012-10-02 23:59:11 +02:00
Jan Vidar Krey 50292cb8c9 Update the network statistics every 10 seconds instead of 60 seconds. 2012-10-02 23:59:11 +02:00
Jan Vidar Krey e4fc91dde1 Made the network statistics work again. 2012-10-02 23:59:11 +02:00
Jan Vidar Krey 8086d89e23 Better formatting of byte sizes. 2012-10-02 23:59:11 +02:00
Jan Vidar Krey cc2ead8136 Use util's format_size. 2012-10-09 10:20:58 +02:00
Jan Vidar Krey 10d8157477 Added a utility function to convert an arbitrary byte size into a human readable string.
E.g. 849484 becomes "829.57 KB".
2012-10-09 10:20:12 +02:00
Jan Vidar Krey 0a7cb86014 Fixed a crash in plugin mod_chat_only. 2012-10-09 10:02:08 +02:00
Jan Vidar Krey 2e8c99b7ec Refurbished the ADC hub stress-tester tool; adcrush 2012-10-02 23:59:11 +02:00
Jan Vidar Krey cb6236691b Added more functionality to the ADC client test code. 2012-10-02 23:59:11 +02:00
Jan Vidar Krey 5136525abc Added API to construct ADC messages with source and destination. 2012-10-02 23:59:11 +02:00
Jan Vidar Krey 07da142e65 Only enable the C compiler (no C++ compiler required). 2012-10-05 09:09:54 +02:00
Jan Vidar Krey aa21556600 Use correct source directory for building outside of source. 2012-10-04 22:00:30 +00:00
Tillmann Karras 16ee65422d Fix cbuffer initialization
If no data was appended, cbuf_get() would return a pointer to
uninitialized memory. Now it returns a pointer to a string of zero
length.
2012-10-03 22:40:33 +02:00
Jan Vidar Krey f0b11dadf1 Refurbished adcrush (hub stress tester). 2012-10-03 13:51:07 +02:00
Jan Vidar Krey 61073bd304 Fix rare protocol parse error due to incorrect recv queue handling. 2012-10-03 13:49:50 +02:00
Jan Vidar Krey 20a847e1b4 Moved the ipcalc code to the network directory. 2012-10-03 12:59:05 +02:00
Jan Vidar Krey a90807fccb Fix version auto generation. 2012-10-03 12:02:35 +02:00
Jan Vidar Krey 25c82076da Cmake fixes, build adc client and link uhub with pthread if sqlite3 is used. 2012-10-03 11:45:21 +02:00
Jan Vidar Krey 089966d918 Fix ADC client send queue. 2012-10-03 11:44:07 +02:00
Jan Vidar Krey e95a892fb7 MSVC compile warnings fixed. 2012-10-02 22:47:43 +02:00
Jan Vidar Krey 564f09ad65 Update the CMake minimum version to 2.8.3 2012-10-02 20:16:30 +00:00
Jan Vidar Krey a33851b13d fixup! Updated .gitignore 2012-10-02 21:54:56 +02:00
Jan Vidar Krey 20e445bf94 Updated .gitignore 2012-10-02 21:49:25 +02:00
Jan Vidar Krey 133707ef57 Removed the VS2010 project files. Use CMake instead. 2012-10-02 21:43:58 +02:00
Jan Vidar Krey 62d14a9c52 Plugin compile fixes for windows systems. 2012-10-02 21:42:58 +02:00
Jan Vidar Krey ab9dda1c61 Some fixes for CMake on Windows.
Tested successfully with NMake.
2012-10-02 21:38:45 +02:00
Jan Vidar Krey 37e78eada1 Replaced the GNU makefiles with CMake. 2012-10-02 15:49:27 +02:00
Jan Vidar Krey 5b4467acd5 Minor stuff on the uhub-admin tool based on the changes in the ADC client code. 2012-09-28 15:52:39 +02:00
Jan Vidar Krey ff2e2a3d4c Misc ADC client fixes. 2012-09-28 15:51:39 +02:00
Jan Vidar Krey a599b29b9d Added more complete API for dealing with ADC messages.
- Added a construct method which would take a fourcc and a source.
- Added an unescape function that would write into pre-allocated memory.
2012-09-28 15:49:46 +02:00
Jan Vidar Krey fc52f0e030 Renamed the hub_sendq and hub_recvq to ioq_send and ioq_recv. 2012-09-28 09:24:04 +02:00
Jan Vidar Krey 35bfefa717 Fix debug output typo. 2012-09-27 15:29:19 +02:00
Jan Vidar Krey 845aefc941 Decouple hub and user manager more cleanly. 2012-09-27 15:29:00 +02:00
Jan Vidar Krey 4fcf3ffc83 Add support for configuration options that depend on certain #ifdefs. 2012-09-27 15:28:46 +02:00
Jan Vidar Krey ac39ebf38a Merge pull request #10 from blairbonnett/fix-check-escapes
Fix msg_check_escapes() so it allows escaped backslashes.
2012-09-17 11:49:14 -07:00
Blair Bonnett 3f777ce5e2 Fix msg_check_escapes() so it allows escaped backslashes.
If a valid escape (\n, \s, or \\) is found, increment the pointer
marking the start of the next search so we don't start looking at the
escaped character. The old behaviour was a problem for messages
containing slashes -- the escaped slash would be looked at in the next
pass and so the following character would be treated as an escape,
causing the message to be dropped for having "an invalid ADC escape".
2012-09-17 23:31:20 +12:00
Jan Vidar Krey b0aa690cb4 Merge branch 'master' of github.com:janvidar/uhub 2012-08-07 11:56:40 +02:00
Jan Vidar Krey fb11589bb0 Drop all ADC messages containing illegal ADC escapes. 2012-08-07 11:55:29 +02:00
Jan Vidar Krey 03c4292eea Merge pull request #8 from blairbonnett/upstart
Upstart script to run uhub as a service
2012-07-29 15:34:07 -07:00
Jan Vidar Krey ccaf755da3 Merge branch 'master' of github.com:janvidar/uhub 2012-07-30 00:08:38 +02:00
Jan Vidar Krey cba0121574 ADCH++ had a security bug that allowed UCMD extension to be relayed.
uhub did not have this security bug since the hub did not advertise support for the
UCMD extension, but the message was still correctly relayed as specified in the
protocol specification.

However, this commit adds support for the UCMD extension, but only to the extent
that uhub will advertise it and uhub will also drop any such CMD message
generated by a client and will (currently) never issues a CMD message by itself.
2012-07-30 00:08:12 +02:00
Blair Bonnett 166a105e33 Add upstart script to run uHub as a service.
Start and stop conditions are based off the OpenSSH upstart script which
ships with Ubuntu.
2012-07-29 16:22:38 +12:00
root a32ea42754 - Update RH init scripts 2012-06-13 14:30:17 +04:00
Jan Vidar Krey 949b54fcdd Merge pull request #7 from yorhel/master
TLS probing fix
2012-06-03 15:45:28 -07:00
Yorhel b9005b1724 core/probe.c: Fix TLS probe when handshake version != SSL version
GnuTLS sends a handshake with SSL 3.0 (0x0300) in the outer packet, but
mentions TLS 1.2 (0x0303) in the Client Hello. There's no real need for
uhub to validate these fields, as OpenSSL should do that itself already.
Just use the version mentioned in Client Hello for logging output.
2012-06-02 14:46:47 +02:00
Jan Vidar Krey 9651a99d46 Updated changelog. 2012-05-29 22:57:02 +02:00
Jan Vidar Krey 571abddd98 Cleaned up code generator for config file parsing. 2012-05-23 23:37:42 +02:00
Jan Vidar Krey 9ea85ad1ac Merge pull request #5 from yorhel/master
Small rewrite of convert_to_sqlite.pl
2012-05-14 14:38:22 -07:00
Jan Vidar Krey 3ae6da4a64 Print error message in case of shutting down due to errors loading plugins. 2012-05-14 23:35:53 +02:00
Jan Vidar Krey f3754fb4e4 Fix Windows file read discrepancy. 2012-05-14 23:33:54 +02:00
Yorhel 79ca108f48 convert_to_sqlite.pl: Update to the latest SQL schema + be more Perlish
The script behaves a little different as well, but it's more simpler
this way.
2012-05-14 19:06:11 +02:00
Jan Vidar Krey 210d5d276e Fix VS2010 project file - missing .c file. 2012-05-13 23:59:27 +02:00
Jan Vidar Krey a6d87f95ef Merge https://github.com/Tilka/uhub 2012-05-13 23:53:56 +02:00
Tilka 274f17bce0 use "I64u" instead of PRIu64 on Windows 2012-05-11 16:45:07 +02:00
Tilka 53b3087735 remove obsolete settings in uhub.conf
motd and rules are now handled by the mod_welcome plugin.
2012-05-11 03:10:05 +02:00
Tilka 8365278cbf fix uhub_itoa() and uhub_ulltoa() 2012-05-10 23:24:42 +02:00
Tilka eb49174ab3 marked plugin callbacks that are not called yet 2012-05-10 01:37:20 +02:00
Tilka 9e52ea7eff add on_change_nick() to struct plugin_funcs
It's not called anywhere yet.
Also reorder some typedefs, rename the ip check functions and add
struct {hub,plugin}_user parameter to on_check_ip_late(). Not sure where
to insert a call to that...
2012-05-09 23:33:03 +02:00
Tilka 05fd6bb723 minimal changes 2012-05-09 23:27:06 +02:00
Boris Pek 7b77f7dc31 Updated init script in debian package. 2012-05-08 23:40:16 +03:00
Boris Pek 685e56f4c6 Updated list of man pages in debian package. 2012-05-08 23:37:37 +03:00
Boris Pek d19e78941a Added man page for uhub-passwd. 2012-05-08 23:29:56 +03:00
Jan Vidar Krey c5516b5729 Merge branch 'master' of https://github.com/Tilka/uhub 2012-05-06 23:15:06 +02:00
Jan Vidar Krey 3aaabbc543 Fix issue with QUI messages being allowed through the hub 2012-05-06 23:09:02 +02:00
Tilka ccb66ced4f don't show error on SIGTERM in select() backend 2012-05-05 01:10:24 +02:00
Tilka dce8b97bba fix dependency of 'install' target 2012-05-03 10:13:21 +02:00
Tilka d49127b507 changed all calls to assert() to uhub_assert() 2012-05-02 21:06:46 +02:00
Jan Vidar Krey ccded3f642 Don't strip the U4/U6 port numbers if updated after login. 2012-05-02 20:45:31 +02:00
Jan Vidar Krey 216757a1f4 Fix compile issue with double typedefs. 2012-05-02 00:29:26 +02:00
Jan Vidar Krey 458c7fa741 Remove list assertion when removing element that is not in the list.
Breaks autotest.
2012-05-01 20:40:27 +02:00
Jan Vidar Krey 74ca5a0a33 Cleaned up command handling code, by splitting into multiple files. 2012-05-01 20:15:49 +02:00
Jan Vidar Krey 9efe4bce57 Fix bug #183 - Added proper OpenSSL license exception for the GPL. 2012-04-22 22:23:11 +02:00
Tilka e4cf01ff1f OMG OPTIMIZED 2012-04-21 16:56:22 +02:00
Tilka 82615fc86e use dh_prep instead of dh_clean -k 2012-04-21 16:53:56 +02:00
Tilka b72f5a407a fix double free 2012-04-21 16:51:41 +02:00
Tilka 776f7d0bff use "0" instead of "false"
otherwise compilation breaks when using a C90 compiler
2012-04-21 13:35:06 +02:00
Tilka 27ceb7ad33 fix use of uninitialized struct ip_range 2012-04-21 09:46:50 +02:00
Tilka c5036a3ff8 fix random crashes upon !reload
A struct plugin_hub_internals was falsely casted to struct
plugin_callback_data. This caused the contained commands list pointer to point to
a struct hub_info and commands->size took the value of a pointer to a struct
net_connection. Since size is increased/decreased every time an item is
added to/removed from the list, this resulted in some funny crashes.

This fix is a little dirty as it exports some internals.
2012-04-21 09:22:06 +02:00
Tilka 832277f653 fix command syntax 2012-04-21 06:08:36 +02:00
Tilka c525e59fa5 use arg parser in !broadcast 2012-04-21 01:56:26 +02:00
Jan Vidar Krey 781f22edab Fixed tiny memory leak on reload/shutdown. 2012-04-19 20:05:37 +02:00
Jan Vidar Krey 55030935a7 Merge https://github.com/Tilka/uhub 2012-04-19 23:17:39 +02:00
Tilka 4f0c8e0356 fix multiple optional arguments
Assuming the argument definition "?xy", it was previously not possible
to specify only x. Also, the syntax will now be shown as "[x [y]]"
instead of "[x] [y]".
2012-04-19 03:06:52 +02:00
Tilka e925db2b98 small cleanup 2012-04-19 02:56:27 +02:00
Tilka 0cbb382b14 also clean uhub-passwd 2012-04-19 02:54:56 +02:00
Tilka 303dbadac2 ignore files generated by dpkg-buildpackage 2012-04-19 02:54:21 +02:00
Tilka e408ae3eba automatically clean up plugin commands 2012-04-19 02:53:43 +02:00
Tilka 5b6ab7e1d2 minimal documentation fixes 2012-04-19 02:44:27 +02:00
Tilka 2298f09c0f update client software link
(adcportal.com has been terminated)
2012-04-19 02:43:59 +02:00
Tilka ad5e5d2837 update compile howto link 2012-04-19 02:43:39 +02:00
Tilka 106574008f fix debian changelog 2012-04-19 02:43:05 +02:00
Jan Vidar Krey 1dba731cc3 Fix bug #158 - Added plugin for setting topic (hub description).
Load plugin mod_topic, and it will provide 3 new user commands:

!topic - set new topic
!cleartopic - reset the topic (use default hub description)
!showtopic - show the current topic
2012-04-19 00:33:38 +02:00
Jan Vidar Krey df7bbc094f Command arguments handling + cleanups
Fix bug #185 - Args of !commands lost/damaged.
All string arguments were incorrectly freed after being added to the argument list for a command.
Instead this fix makes sure it is properly copied into a new string, and by doing so this requires
a new API for dealing with hub command arguments in a type safe manner, and also allows for each
argument to be cleaned up properly when the command is no longer needed.

This also fixes issues with parse errors for certain types, and optional arguments (previously it was impossible
to tell the difference for an integer with value 0 or if no integer was given).

All arguments can now be accessed through the new functions
hub_command_arg_reset() and hub_command_arg_next().

These functions are also exposed to plug-ins.

The argument type notations for 'n' has changed to mean nick (string),
and 'u' is used for a user (struct hub_user - must be online).
2012-04-18 23:03:05 +02:00
root 390b63e80a - update ./doc/uhub.conf example file for mod_chat_only.so 2012-01-31 14:48:29 +04:00
Jan Vidar Krey 5068fe8351 Cygwin/Mingw32 compile fixes. 2012-01-25 00:20:59 +01:00
root e4df1884d2 - change order load plugins on example file 2012-01-23 15:32:05 +04:00
Jan Vidar Krey 8607b40278 Fix bug #180 - Crash after signal SIGHUP. 2012-01-19 02:58:20 +01:00
Jan Vidar Krey a9b5c6db38 Fixed minor issues found with static code analyzis (Clang). 2012-01-13 01:31:34 +01:00
Jan Vidar Krey 0ae8a08f55 Revert "- add empty ./doc/users.db sqlite file"
This reverts commit 66215cc535.

This database is not created correctly.
Instead, create a database with the uhub-passwd tool:

uhub-passwd users.db create
2012-01-10 02:21:22 +01:00
Jan Vidar Krey ff639d87c3 Disable SQL debugging output. 2012-01-10 02:21:22 +01:00
Jan Vidar Krey 5edf2b60d4 Fixed bug #179 - !broadcast command does not work properly. 2012-01-10 02:21:22 +01:00
root 66215cc535 - add empty ./doc/users.db sqlite file 2012-01-10 10:26:11 +04:00
Jan Vidar Krey eee2636582 Added a chat only hub plugin that disables searching and connection setup.
This also deprecates the built-in chat_only configuration option.
If you need this functionality, then load the mod_chat_only plugin (if it is loaded then only operators
are able to search, connect, etc).
2012-01-09 20:58:19 +01:00
Jan Vidar Krey f44a420970 Updated the copyright to 2012 and git version display. 2012-01-04 11:08:07 +01:00
Jan Vidar Krey fcf6827a68 Also build the chat history plugin. 2012-01-03 22:41:56 +00:00
Jan Vidar Krey ca3782c570 Merge branch 'mod_chat_history_work'
Conflicts:
	doc/plugins.conf
2012-01-03 23:22:41 +01:00
Jan Vidar Krey 875f55a401 Added a chat history plugin.
The mod_chat_history plugin provides chat history for all public chat messages.

Can be configured in the following ways:

- history_max: max number of messages stored in history
- history_default: the default number of messages to be returned when invoking !history
- history_connect: if > 0, then this number of messages is automatically sent when connecting to the hub

Removed the built-in !history command in favour of the mod_chat_history plug-in.

Make sure we unescape all chat messages before forwarding any of them to plugins.

Update example plugins.conf in documentation directory.
2012-01-03 23:22:41 +01:00
Jan Vidar Krey a9ed03cf38 Cleaned up the mod_welcome parse failure code. 2012-01-02 12:54:35 +01:00
root b0a8c3251b Update plugins.conf example file for mod_welcome.so 2011-12-30 11:43:33 +04:00
Jan Vidar Krey 2ebd916992 Added sqlite as a git submodule. 2011-12-28 18:08:11 +01:00
Jan Vidar Krey 3c6254d007 Partial revert of importing sqlite into this repository. 2011-12-28 18:06:19 +01:00
Jan Vidar Krey 7b392acbf5 Format the help list appropriately (as in older versions). 2011-12-28 10:45:02 +01:00
Jan Vidar Krey 66c77d5170 Don't broadcast the \!example command when issuing it (mod_example.c bug). 2011-12-28 10:44:03 +01:00
Jan Vidar Krey c2e25453f6 Added VS2010 project for the uhub-passwd tool. 2011-12-22 01:51:10 +01:00
Jan Vidar Krey 1700a27619 Fix bug #173 - Fix the command parsing errors. 2011-12-22 01:49:21 +01:00
Jan Vidar Krey aa01fd40e5 Updated VS2010 solution and project files. 2011-12-22 01:43:04 +01:00
Jan Vidar Krey 5b7382a27c Added VS2010 project for mod_auth_sqlite. 2011-12-22 01:39:42 +01:00
Jan Vidar Krey a5b02d1672 Added thirdparty sqlite code to the VS2010 project. 2011-12-22 01:39:41 +01:00
Jan Vidar Krey fe15c4cb58 Fix VS2010 build issues. 2011-12-22 01:39:40 +01:00
Jan Vidar Krey ecedd44fee Added %c substitution to mod_welcome to print the current user credentials. 2011-12-22 00:14:34 +00:00
Jan Vidar Krey 24e2c2090e Fix welcome plugin handle, and build issues. 2011-12-21 23:50:23 +00:00
Jan Vidar Krey 2a190859bd Remove the configuration options 'file_motd' and 'file_rules'. Use mod_welcome instead. 2011-12-21 14:44:37 +01:00
Jan Vidar Krey 88dd1341d2 Started working on mod_welcome which will replace the built-in file_motd and file_rules configuration options. 2011-12-21 14:31:29 +01:00
Jan Vidar Krey b24d4b85cd Split out the command buffer code to a generic buffer. 2011-12-21 13:53:53 +01:00
Jan Vidar Krey f34f0328a3 Removed the PLUGIN_SUPPORT code, since plugin support is now mandatory. 2011-12-21 10:48:37 +01:00
Jan Vidar Krey f31fc65e1d VS2010 fixes. 2011-12-21 01:42:21 +01:00
Jan Vidar Krey 7325b15786 Fix bug #174 - Wrong check for fdatasync() availability. 2011-12-21 00:55:22 +01:00
Jan Vidar Krey ec3afc3a44 Added a simple tool to create and manipulate the uhub sqlite authentication database. 2011-12-20 16:20:54 +01:00
Jan Vidar Krey ba26f4c5e2 Update copyright notices and added licenses to files that were missing it. 2011-12-19 10:54:47 +01:00
Jan Vidar Krey 68dc3cafc7 Removed unused files. 2011-12-19 10:51:45 +01:00
Jan Vidar Krey 583900cec5 Fix compile warning about unused result for write() function. 2011-12-19 00:40:02 +01:00
Jan Vidar Krey 93caa9b3c1 Fix compile warning about uninitiaized variable. 2011-12-19 00:36:53 +01:00
Jan Vidar Krey f2cb84180a Refactored command parsing.
Allows for automatically tested command parsing by splitting parsing
and invokation of the commands.
2011-12-19 00:34:45 +01:00
Jan Vidar Krey fc5e09aa9e fixup! Fix bug #171 - Race condition could allow two users with same CID or nick to enter the hub. 2011-12-12 12:03:28 +01:00
Jan Vidar Krey b4779bfb12 Fix bug #171 - Race condition could allow two users with same CID or nick to enter the hub. 2011-12-11 13:38:36 +01:00
Jan Vidar Krey 6d609e18a2 Windows/VS2010 fixes. 2011-12-11 12:53:09 +01:00
Jan Vidar Krey ebd3ccf98e Disable the kqueue backend because it crashes under certain circumstances (see bug #169). 2011-12-09 17:01:02 +01:00
Jan Vidar Krey b28417c3a3 Added visual studio project file for mod_example. 2011-12-09 16:59:33 +01:00
Jan Vidar Krey aec89fc125 Fix memory leaks when parsing user commands. 2011-12-09 16:54:48 +01:00
Jan Vidar Krey 9377fb537a Fix memory leak when unloading plugins. 2011-12-09 16:39:19 +01:00
Jan Vidar Krey afda1d7b9d Added a LOG_PLUGIN macro for plugin output debug messages.
Converted all TRACE messages related to plugins to LOG_PLUGIN.
2011-12-09 16:38:11 +01:00
Jan Vidar Krey 2352e5a0dd Fix memory leak for built-in commands. 2011-12-09 16:35:42 +01:00
Jan Vidar Krey 1dc79c641c Cleanup: do not use strcat(). 2011-12-09 15:58:58 +01:00
Jan Vidar Krey 41824ce2bf Fix compile issues on debian ports for GNU Hurd and Linux for s390. 2011-12-09 14:31:02 +01:00
Jan Vidar Krey 65c2652a22 Fix build errors on the Debian kfreebsd port. 2011-12-09 14:24:21 +01:00
Jan Vidar Krey fb89307b0a fixup! Fix compiler warnings using gcc 4.6. 2011-12-09 14:21:16 +01:00
Jan Vidar Krey 8d607dff13 fixup! Fix bug #167 - Build errors on OpenBSD. 2011-12-09 13:44:36 +01:00
Jan Vidar Krey 7825c413d4 fixup! Added support for dynamic commands. 2011-12-09 13:04:05 +01:00
Jan Vidar Krey 318163c066 Added support for dynamic commands.
Dynamic commands are user commands that can be added dynamically to
the hub by a plugin.

The example plugin (mod_example.c) adds a !example command that when
invoked send a message to the user who invoked it.
2011-12-09 10:29:50 +01:00
Jan Vidar Krey 78ed83840b fixup! Fix bug #167 - Build errors on OpenBSD. 2011-12-02 13:56:41 +01:00
Jan Vidar Krey e972b03f38 Fix SSL disconnect memory leak. 2011-12-02 13:03:17 +01:00
Jan Vidar Krey 9f16298688 Fix minor valgrind issues
- Fix valgrind invalid write of 1 byte.
- Fix a few plugin related memory leaks.
2011-12-01 15:14:01 +01:00
Jan Vidar Krey c17b43e77f Fix bug #144 - Count SSL traffic in !stats. But this does not include the SSL overhead. 2011-11-30 14:54:54 +01:00
Jan Vidar Krey 675e6af3ba Don't print warnings about known extensions that don't affect the hub at all (DHT0). 2011-11-30 14:14:36 +01:00
Jan Vidar Krey 2396d8555c Fix bug #167 - Build errors on OpenBSD.
- Don't link with -ldl, as it is not needed in most cases
- Don't compile plugins if USE_PLUGINS=NO
- Fix warning about missing newline at end of getopt.h
- Removed the O_NOATIME open() flag from the logging plugin.
- Removed the O_LARGEFILE open() flag. _FILE_OFFSET_BITS is 64.
- Use fsync() if fdatasync() is not available for log file writing.
- Replaced some sprintf() with snprintf() due to compiler warnings (though, they were length limited otherwise).
- Replaced two occurences of strcpy() with memcpy().
2011-11-30 13:43:39 +01:00
Jan Vidar Krey 9981acca08 Supply sid with user information in adcclient test code. 2011-11-30 12:32:59 +01:00
Jan Vidar Krey 99e644597d Cleaned up the ADC client test code.
Now works with ADCS (not very well tested, though)
2011-11-29 16:39:09 +01:00
Jan Vidar Krey 3a39a36fbb Fix for bug #166 - TLS crash. 2011-11-29 10:19:43 +01:00
Jan Vidar Krey 1102a86463 Adcrush fixes. 2011-11-28 16:36:45 +01:00
Jan Vidar Krey bad4512a37 Fix compiler warnings using gcc 4.6. 2011-11-28 16:30:35 +01:00
Jan Vidar Krey 3b4a199673 Fix null pointer crash while encountering configuration file errors during parsing. 2011-10-17 09:50:14 +02:00
Jan Vidar Krey f8d057f15a [PATCH] Lintian warning hyphen-used-as-minus-sign
Thanks to tehnick for finding and fixing this issue.
2011-09-28 12:19:26 +02:00
Jan Vidar Krey 39572c3684 Made plugin loading work properly on Windows. 2011-09-08 01:00:32 +02:00
Jan Vidar Krey 0d8283930f Compile fix for Fedora/RedHat. Add -lcrypto to LDFLAGS. 2011-09-07 10:20:58 +02:00
Jan Vidar Krey 33b94d8eb4 Removed unused functions - prevents compile warnings. 2011-09-07 10:02:43 +02:00
Jan Vidar Krey 324bfcd2c8 Added plugin loader routines for windows. 2011-09-07 00:31:38 +02:00
Jan Vidar Krey 87535ff0d6 Added visual studio 2010 solution and project files. 2011-09-06 00:06:13 +02:00
Jan Vidar Krey 800f6a70f9 Added description to plugin_hub_info (an empty struct causes warning on VS2010). 2011-09-05 23:40:57 +02:00
Jan Vidar Krey 5d2a25a1be Updated copyright year. 2011-09-05 23:40:08 +02:00
Jan Vidar Krey 70f13158d3 Merge branch 'master' of github.com:janvidar/uhub 2011-09-05 23:34:05 +02:00
Jan Vidar Krey 9327615448 Compile warning fix. 2011-09-05 23:16:15 +02:00
Jan Vidar Krey ebe54bcf27 Added plugin events for server wide events (mostly for logging). 2011-08-16 15:11:15 +02:00
Jan Vidar Krey e4aa565fab Build plugins by default. 2011-08-16 15:10:33 +02:00
Jan Vidar Krey 998f5a57e2 Fix bug #152 - disable self-registering 2011-08-16 15:09:02 +02:00
Jan Vidar Krey 472c489ae1 Fix bug #154 - plugin system is disabled silently if one plugin fails to initialize. 2011-08-16 14:46:11 +02:00
Jan Vidar Krey bba7c0d05b Require setting the file name via file=/path/to/file for log file. 2011-08-16 14:33:15 +02:00
Jan Vidar Krey 169b8a4a75 Added option to redirect from adc:// to adcs:// if tls is required. 2011-08-16 12:11:04 +02:00
Jan Vidar Krey f13bcd8c28 Minor compile fixes. 2011-08-16 12:08:21 +02:00
Jan Vidar Krey a79fcd796e Shutdown SSL on close. 2011-08-16 12:07:17 +02:00
Jan Vidar Krey 474e2be308 Fix stupid mistake. 2011-08-16 12:06:44 +02:00
Jan Vidar Krey 47cf3326fd Don't do SSL_clear unless the SSL object is initialized. 2011-08-16 12:06:34 +02:00
Jan Vidar Krey 3353049ae3 Several SSL/TLS related memory leak fixes. 2011-08-16 12:06:17 +02:00
Jan Vidar Krey 3ccce614d0 Fix SSL/TLS related memory leak. 2011-08-16 12:04:14 +02:00
Jan Vidar Krey e30505b54e Fix 100% CPU issue with SSL connections. 2011-08-16 12:04:03 +02:00
Jan Vidar Krey 3bc764adf5 Winsock fixes. 2011-08-08 00:12:50 +02:00
Jan Vidar Krey 6becadc984 Compile fix for gcc. 2011-02-05 17:18:08 +01:00
Jan Vidar Krey 4a03accc34 Fix compile warning about PLUGIN_SUPPORT being redefined. 2011-02-05 17:16:14 +01:00
Jan Vidar Krey d01813ef48 Added project files for Visual Studio 2010. 2011-02-05 17:13:26 +01:00
Jan Vidar Krey e5bb7057de Windows fixes. 2011-02-05 17:11:23 +01:00
Jan Vidar Krey bf4ad5624a Visual Studio compile fixes. 2011-01-12 16:58:18 +01:00
Jan Vidar Krey 03b4252ab5 Link fix in case not everything is linked as one binary. 2011-01-06 12:25:28 +01:00
Jan Vidar Krey 863e0e9844 Merge branch 'master' of baracus:~/git/uhub 2011-01-03 00:19:21 +01:00
Jan Vidar Krey 4c238dd946 Fix compile warning. 2011-01-03 00:12:40 +01:00
Jan Vidar Krey e20b15ef74 Merge branch 'master' of github.com:janvidar/uhub 2011-01-03 00:09:00 +01:00
Jan Vidar Krey 9b57279628 Many Visual C++ compile warnings and errors fixed. 2011-01-03 00:03:07 +01:00
E_zombie e82ac17452 update docs in ./doc/plugins.conf 2010-12-30 15:11:47 +03:00
Jan Vidar Krey adb6641a17 PATCH: Redirect did not work properly (Thanks MiMic)
The SID was not included in the redirect and it was thus an
incorrect ADC message which were discarded by most clients.
2010-12-29 14:40:23 +01:00
Jan Vidar Krey 67eabb5a98 Fix #157: calculation of limits for min/max share on 32 bit architectures. 2010-12-20 23:18:41 +01:00
Jan Vidar Krey eaf867d513 Merge branch 'master' of github.com:janvidar/uhub 2010-12-20 11:52:37 +01:00
Jan Vidar Krey 4ede1b2d8a Fix for bug #156 2010-12-20 11:52:15 +01:00
E_zombie d4accea32c - update GNUmakefile 2010-11-23 16:07:39 +03:00
E_zombie 50e44f5272 - update GNUmakefile for install plugin modules 2010-11-23 15:54:57 +03:00
E_zombie 3b3862fa8d - update ./doc/compile.txt 2010-11-22 15:47:24 +03:00
E_zombie d86e1b8f0b - add comment in sqlite conver script 2010-11-22 10:39:39 +03:00
Jan Vidar Krey b993e97bb4 Fix bug in config parser where 'foo=bar' did not work, but 'foo = bar' did work due to extra whitespace between tokens. 2010-11-18 22:43:48 +01:00
Jan Vidar Krey 4f8e3ba10b Cleaned up command parsing, added register, password, useradd, userdel, userinfo, usermod and userpass.
Mostly not implemented.
2010-11-12 18:03:39 +01:00
Jan Vidar Krey 16fc3ea68e Clean up argument parsing for plugins. 2010-11-12 18:03:39 +01:00
Jan Vidar Krey a934dfaa70 Cleaned up boolean apply code. 2010-11-12 18:03:39 +01:00
Jan Vidar Krey 21c22288a2 Simplified plugin initialization by using a macro. 2010-11-12 18:03:39 +01:00
Jan Vidar Krey ff8b8f5175 Fix bug #139: Unable to use TLS - due to not handling quotes around configuration strings.
Conflicts:

	src/util/misc.c
2010-08-16 22:53:16 +02:00
Jan Vidar Krey 1af7e26c52 Moved flood control stuff to the util package. 2010-08-11 22:46:06 +02:00
Jan Vidar Krey 35b055f9b7 Allow for connections accepted/refused to be logged by plugins. 2010-08-11 22:46:06 +02:00
Jan Vidar Krey 4c960cb977 Added logging of chat messages in the plugin API. 2010-08-11 22:46:06 +02:00
E_zombie 5419d07efe - update plugins.conf for new parametrs of mod_logging.so 2010-08-05 10:19:26 +04:00
Jan Vidar Krey c2b7ecd49c Made sure the logging plugin logs on a format that looks almost the same as we used to have in the past. 2010-08-04 17:03:37 +02:00
Jan Vidar Krey 0c6a58d35a Make sure chat messages are routed through plugins. 2010-08-03 23:19:39 +02:00
Jan Vidar Krey 4a977da514 Remember to terminate the SQL escaped string. 2010-08-03 23:15:37 +02:00
root 04c02d3f2f - add "Reopen log file" on RH init.d script 2010-07-30 11:35:36 +04:00
Jan Vidar Krey e03b4ff0c1 Use correct sqlite escapes of strings. 2010-07-29 11:29:40 +02:00
Jan Vidar Krey 4bf882d385 Fixed credentials handling, and added debug output for SQL. 2010-07-29 11:22:57 +02:00
Jan Vidar Krey dbf790bb93 Added autotests for credentials handling. 2010-07-29 11:22:04 +02:00
Jan Vidar Krey f9abd40ff9 Update .gitignore, made it more precise. 2010-07-29 10:44:25 +02:00
Jan Vidar Krey 5d135bb5b7 Use the credentials converter to determine user level. 2010-07-29 10:39:34 +02:00
root 7c1e38602c * update .gitignore
* update uhub.spec  for plugins system

* update example plugins.conf

* modify header RH init script
2010-07-29 12:26:55 +04:00
Jan Vidar Krey 55ffe46a38 Added an SQLite authentication backend. 2010-07-29 08:49:24 +02:00
Jan Vidar Krey 93be2c584e Reworked plugin APIs slightly, added full support for authentication from plugins. 2010-07-29 08:43:22 +02:00
Jan Vidar Krey c75090cdf2 Added a generic string to boolean parser. 2010-07-29 08:42:40 +02:00
Jan Vidar Krey 97feb3635e Allow plugins to provide an error message. Useful for reporting problems
when registering the plugins.
2010-07-29 08:41:26 +02:00
root 920d696ff5 - add doc/plugins.conf file
- update doc/uhub.spec
- update uhub.conf example file
2010-07-26 11:57:49 +04:00
Jan Vidar Krey 350791cdf8 Added plugin invokers for authentication code. 2010-07-23 01:23:13 +02:00
Jan Vidar Krey c6cf03614f Implement more plugin invokers, and call them. 2010-07-23 00:38:11 +02:00
Jan Vidar Krey 1ff0f54a4b Fixup some minor details in tests. 2010-07-23 00:34:49 +02:00
Jan Vidar Krey bdcf35b63d Cleanup code and allow for plugins to provide an error message. 2010-07-19 01:36:23 +02:00
Jan Vidar Krey d41d649353 Encapsulate token API. 2010-07-18 19:43:11 +02:00
Jan Vidar Krey 56e5557146 Cleaned up the credentials handling, and made it ready for plugins. 2010-07-12 19:05:50 +02:00
Jan Vidar Krey e4977606a7 Made sure logs can be rotated by sending a SIGHUP to the hub. 2010-07-12 17:00:10 +02:00
Jan Vidar Krey f386e57de8 Updated copyright of touched files. 2010-07-10 03:41:49 +02:00
Jan Vidar Krey ccb318547d Started using new file reader tokenizer. 2010-07-10 03:36:47 +02:00
Jan Vidar Krey 394c8a5f95 Whitespace fixes. 2010-07-09 14:01:22 +02:00
Jan Vidar Krey 4b22ccb73c Added a proper config file tokenizer that supports escaping sequences
and comments.

This allows for:

'"foo bar"' can be represented as 'foo\ bar'.

And allows for comments using the hash symbol (#), but not inside
escapes or quotes. "#this is not a comment", \#this\ is\ not\ a comment.

All configuration file parsers should be rewritten using this functionality.
2010-07-09 14:01:03 +02:00
Jan Vidar Krey 849a791f79 Fixed plugin handling when using the utils code from within a plugin. 2010-07-08 14:26:07 +02:00
Jan Vidar Krey b4fa508265 Starting 0.4.x branch 2010-06-30 19:24:48 +02:00
Jan Vidar Krey 490f7dd835 Merge branch 'plugin_work' 2010-06-30 19:24:03 +02:00
Jan Vidar Krey aa26052479 Misc plugin work
* Fix crash when unloading plugins.
* Fixed plugin loader and plugin unload handler.
* Added a new example plugin: mod_logging which logs users logging in and out of the hub to stdout.
2010-06-29 15:40:19 +02:00
Jan Vidar Krey 7b96e2c912 Merge branch 'plugin_work' of git://github.com/janvidar/uhub 2010-06-22 14:35:15 +02:00
Jan Vidar Krey ccaa4860b4 Started working on the plugin configuration and loader code.
The example plugin works, but does not do anything.
2010-06-13 19:34:20 +02:00
Jan Vidar Krey 7218011449 Added missing plugin file. 2010-06-07 15:42:38 +02:00
Jan Vidar Krey 0810982b57 Fix bug #136 - !broadcast does not report status back to to sender. 2010-06-07 15:41:07 +02:00
Jan Vidar Krey baeba01835 Added file_plugins directive to configuration file. 2010-06-06 16:32:43 +02:00
Jan Vidar Krey 07d4e4470c More work on the plugin API. 2010-06-06 16:19:59 +02:00
Jan Vidar Krey ac5811633e Update to version 0.3.2 2010-05-31 17:13:40 +02:00
Jan Vidar Krey ed53034ad5 Added plugin loader code, merely a wrapper around dlopen() and friends. 2010-05-30 23:33:06 +02:00
Jan Vidar Krey fc8965f1c5 Started working on an authentication plugin API. 2010-05-30 13:03:03 +02:00
Jan Vidar Krey b3ed3a5526 Fix a silly invalid read operation 2010-05-28 15:23:44 +02:00
Jan Vidar Krey 1480b7e9c0 Fix bug #133 - Kqueue backend crash (BSD/OSX) 2010-05-28 15:22:33 +02:00
Jan Vidar Krey 50fde1c5c8 Updated the broadcast command to not send the message back to the user that sent it, but
instead summarize the number of users that received it.
2010-05-26 09:38:14 +02:00
Jan Vidar Krey 77faac0494 Fixed some minor issues found during code review. 2010-05-25 22:47:30 +02:00
Jan Vidar Krey 473ff0e159 Fix static buffer overrun - Thanks BlackSonar. 2010-05-25 22:23:40 +02:00
Jan Vidar Krey 62333c5f39 Update the command to send a PM originating from the operator/admin that sent it. 2010-05-25 22:21:56 +02:00
Jan Vidar Krey 44860c8477 Fix bug #131 - Missing escape handling for # in config files.
Added support for escaping stuff in the configuration file parser.
2010-05-25 19:43:32 +02:00
Jan Vidar Krey c70119870a Adding support for redirecting clients to other hubs when they fail to login
for various reasons.

Config variable is "redirect_addr".
2010-04-22 21:07:46 +02:00
Jan Vidar Krey b29f34af4a FreeBSD kqueue backend fixes.
This fixes bug #126 - Core dump on FreeBSD with obsolete_clients=0
2010-04-22 16:11:50 +02:00
Jan Vidar Krey 076492f1b9 Fix some small memory leaks. 2010-04-21 18:34:55 +02:00
Jan Vidar Krey b6fb2b41bd Fix a potential crash 2010-04-21 18:34:39 +02:00
Jan Vidar Krey c82f8ba167 Fix compile error. 2010-04-16 06:31:47 +02:00
Jan Vidar Krey 6c9cd4ca50 Fix some errors in the XML config spec. 2010-04-15 19:49:48 +02:00
Jan Vidar Krey 201acad409 Do not use C macros for configuration files. 2010-04-15 19:49:23 +02:00
Jan Vidar Krey 51c5b6169c Fix last commit. 2010-04-11 20:17:36 +02:00
Jan Vidar Krey b7e62b46cc Send message to old clients as a chat message not a status message. 2010-04-11 20:13:05 +02:00
Jan Vidar Krey 321cddad8e Fix bad boolean handling in config. 2010-04-09 10:41:01 +02:00
Jan Vidar Krey 8ec55a59f5 Merge branch 'master' of github.com:janvidar/uhub 2010-04-09 10:23:02 +02:00
Jan Vidar Krey d3ebc409cb Fix silly problem where default config is applied after reading the config file. 2010-04-09 10:22:45 +02:00
root 2fa5c01050 update example uhub.conf 2010-04-09 12:20:36 +04:00
Jan Vidar Krey 45462595ac Fix defaults for limix_min_hubs 2010-04-09 09:41:38 +02:00
Jan Vidar Krey 0a3fe10f16 Added XML file for configurations.
The XML file will be used to auto generate the configuratioin code
and the corresponding documentation in the future.

The perl script parses this XML format and outputs gen_config.{h,c} files
accordingly.
2010-04-07 17:26:27 +02:00
Jan Vidar Krey 8e816fd196 Update example configuration. 2010-04-05 16:53:17 +02:00
Jan Vidar Krey 88a22659a1 Update deb/rpm files. 2010-04-05 16:46:20 +02:00
Jan Vidar Krey 3393ee6a85 Updated changelog. 2010-04-05 16:43:43 +02:00
Jan Vidar Krey 58630fde08 Fixed getip to return the ip address of the target user, not self. 2010-04-05 16:35:55 +02:00
Jan Vidar Krey 8815118fde Added flood control support.
This closes bug #79: Flood control, and rate limits
2010-04-05 16:01:07 +02:00
Jan Vidar Krey 5454ae279a Fix bug #120: !getip does not work 2010-04-05 14:21:40 +02:00
Jan Vidar Krey 8e579f4601 Fix #123: accept() fails if IP is banned. 2010-04-05 13:44:17 +02:00
Jan Vidar Krey e220357176 Added configuration option to enable support for obsolete pre-ADC/1.0 clients. 2010-04-05 13:43:28 +02:00
Jan Vidar Krey 8bed952022 Fixed nasty hub freeze caused by timers being injected for the same timestamp as it is being removed from. 2010-03-23 01:06:04 +01:00
Jan Vidar Krey c4604a7e94 Make code clearer. 2010-03-23 00:46:25 +01:00
Jan Vidar Krey 236daeae53 Assert if inserting an invalid timer. 2010-03-15 22:59:16 +01:00
Jan Vidar Krey 862c6a1baf Reduce timeout queue window size. 2010-03-13 00:16:15 +01:00
Jan Vidar Krey 198d86a1ee Added some automatic tests for the timeout handling. 2010-02-25 17:57:50 +01:00
Jan Vidar Krey 2ded9f3e09 Make the revision file if it does not exist. 2010-02-25 16:38:05 +01:00
Jan Vidar Krey 59ed268f4d Added test cases for sid allocation.
This revealed a few bugs:
* when sid allocator is full, then uhub will loop indefinitely when allocating one more (unlikely to occur).
* looking up a user object based on a sid that is out of range (off by one) returns invalid memory.
2010-02-18 16:02:13 +01:00
Jan Vidar Krey 963416ad73 Cleanup reference adc message reference counting somewhat. 2010-02-16 20:51:10 +01:00
Jan Vidar Krey 29c162727c Added lots of new asserts which should trigger in case we double delete a ADC message. 2010-02-15 19:03:19 +01:00
Jan Vidar Krey 1ce258bccf Tidy up the certificate loading code somewhat. 2010-02-15 19:02:31 +01:00
Jan Vidar Krey 0de66286fa Partially fix bug #117 - tls_require ignored entirely in 0.3.0 released
If tls_require is enabled then the hub will simply close the connection if a
user connects without TLS.
In the future we should redirect the user either to another server or to the adcs server.
2010-02-15 19:00:48 +01:00
Jan Vidar Krey 1a98bb6810 Added optional include of local makefile. 2010-02-15 18:56:23 +01:00
Jan Vidar Krey 5e6879dffb Fix for partial read operations. 2010-02-12 20:33:17 +01:00
Jan Vidar Krey 1b56adb8c0 Fix wrong IQUI message. Partially fixes bug #4. 2010-02-12 19:25:09 +01:00
Jan Vidar Krey 685597c795 Make sure we delete the revision.h files when updating.
Also, only use annotated tags for git revision numbers.
2010-02-11 09:16:30 +01:00
Jan Vidar Krey 782f091637 Bump to 0.3.1-rc1 2010-02-11 09:03:07 +01:00
Jan Vidar Krey 82eeaa1fba Fix bug #114: FreeBSD compile error. 2010-02-11 07:54:42 +01:00
Jan Vidar Krey 977b57a385 Prefer the git-describe version number if it exists. 2010-02-11 01:21:08 +01:00
Jan Vidar Krey 19b9f72337 Make sure !version agrees with the connect time banner (same format). 2010-02-11 01:19:58 +01:00
Jan Vidar Krey 56605f7dcb Fix autotest crash. 2010-02-11 01:18:45 +01:00
Jan Vidar Krey bf1b64db53 Write git revision to a header file, then make version.h depend on that file. 2010-02-11 01:03:09 +01:00
Jan Vidar Krey 915cb56448 Fix bug #106: Show OS/CPU info in !version.
This can be controlled by the configuration variable "show_banner_sys_info" which is enabled by default.
2010-02-10 23:45:51 +01:00
Jan Vidar Krey 6992043f9d Fix bug #113: crash when using epoll backend. 2010-02-10 22:06:49 +01:00
Jan Vidar Krey 896bbfcb5d Compile multiple network backends into the binary and choose which one to use at runtime.
This makes it possible to share more code between the backends and also work around
bugs of certain backends on some (versions of) operating systems.
2010-02-10 22:00:13 +01:00
Jan Vidar Krey 6ac78e1a10 Fix autotest 2010-02-08 00:35:58 +01:00
Jan Vidar Krey 74a2191350 Fix bug #111: Added nmdc-redirector similar to the adc-redirector. 2010-02-07 23:37:21 +01:00
Jan Vidar Krey be8db21561 Fix bug #109: Confusing debug message for nat_ip. 2010-02-07 23:29:38 +01:00
Jan Vidar Krey 8065903604 Fix bug #108: share limits can be avoided.
This was due to updates to the share limit not being enforced after a succesful login.
2010-02-07 23:08:04 +01:00
Jan Vidar Krey 78ae9fb3ce Fix documentation about file descriptor limits. 2010-02-05 22:40:35 +01:00
root 4715815ba2 Update getstartd.txt for hub with more that 1024 users. 2010-02-05 09:40:57 +03:00
root cb9625f6a5 update example uhub.conf 2010-02-02 13:43:10 +03:00
root 9934bde050 add in README list of compatible ADC clients 2010-02-01 15:36:46 +03:00
root 9a1c5ee548 - update .spec file; - cosmetic in init.d scripts 2010-02-01 12:22:12 +03:00
Jan Vidar Krey 11df912162 libevent is NOT needed at all (nor is it supported) 2010-01-31 23:40:11 +01:00
root c8bc2f64fd update .ebuild ; update compile doc ; update RHEL init.d 2010-01-29 22:05:39 +03:00
Jan Vidar Krey 2dc95eca47 SunOS support. 2010-01-28 01:35:09 +01:00
Jan Vidar Krey 7637d9ba68 Added experimental Haiku OS support.
It compiles and it runs with some minor glitches.
2010-01-28 01:35:08 +01:00
Jan Vidar Krey 4e9488dd4d gcc 2.95 compile fixes. 2010-01-28 01:11:11 +01:00
Jan Vidar Krey e0003ebbb2 Only define MIN/MAX macros if not defined by the system. 2010-01-28 01:07:05 +01:00
Jan Vidar Krey 8e7e8c68f5 gcc v2.95 compile fixes. 2010-01-28 01:06:41 +01:00
root db32eaeafc update doc/uhub.conf for multiple ports 2010-01-28 10:53:03 +03:00
Jan Vidar Krey 1599f63134 Make sure the autotests work. 2010-01-28 00:07:42 +01:00
Jan Vidar Krey c3ad006d07 Fix bug #76: added support for multiple server listen ports.
Use server_alt_ports and supply a comma separated list of ports.
2010-01-27 23:55:52 +01:00
Jan Vidar Krey 1faca92167 Added a generic string splitter utility function that is based on callbacks instead of populating a list. 2010-01-27 23:55:05 +01:00
Jan Vidar Krey f0a13b4c23 Updated .ebuild and .spec files. 2010-01-27 19:01:50 +01:00
Jan Vidar Krey ccd1c8f160 kqueue() BSD fixes 2010-01-27 17:50:02 +01:00
Jan Vidar Krey 41418f21e7 Winsock compile fix. 2010-01-27 17:48:16 +01:00
Jan Vidar Krey 7a8a737cad More kqueue work in progress. 2010-01-27 01:04:32 +01:00
Jan Vidar Krey ac48ad01fb Work in progress on the kqueue backend. 2010-01-27 00:43:10 +01:00
Jan Vidar Krey 31a69b1f3f Thanks to E_zombie for all the Centos/RedHat contributions 2010-01-26 23:55:27 +01:00
Jan Vidar Krey d7a1a52c1a Started working kqueue() backend for OSX and BSD. 2010-01-26 23:30:32 +01:00
Jan Vidar Krey f54e8dbbba Moved the timeout code to where it belongs, along with the network backend code. 2010-01-26 22:55:08 +01:00
Jan Vidar Krey de72d4ae63 Merge branch 'master' of baracus-vpn:~/git/uhub 2010-01-26 17:46:51 +01:00
Jan Vidar Krey 01efc6cc20 Fixes for debian init.d scripts. 2010-01-26 17:46:47 +01:00
Jan Vidar Krey 7cf1181e6b Merge branch 'master' of github.com:janvidar/uhub 2010-01-26 17:28:45 +01:00
Jan Vidar Krey 4b64b28777 Added proper debian package scripts. 2010-01-26 17:27:34 +01:00
root e9f0331ca8 Merge branch 'master' of git://github.com/janvidar/uhub 2010-01-26 19:17:16 +03:00
root f263534aaf add .ebuild 2010-01-26 19:16:28 +03:00
Jan Vidar Krey 788b644c80 Merge branch 'master' of github.com:janvidar/uhub 2010-01-26 16:16:48 +01:00
Jan Vidar Krey 2d7ffa37fe Fix problem parsing configuration file if the last line is not empty 2010-01-26 16:16:41 +01:00
root fbaac98483 .spec Require fix 2010-01-26 17:39:57 +03:00
root bd9d8229ff add .SPEC file for build RPM in RHEL based distrs 2010-01-26 17:32:42 +03:00
Jan Vidar Krey dfa6d07455 Merge branch 'master' of github.com:janvidar/uhub 2010-01-26 12:04:55 +01:00
root 6bbdd24cb7 Merge branch 'master' of git://github.com/janvidar/uhub 2010-01-26 13:05:56 +03:00
root e3a644a853 Stupid mistake in path 2010-01-26 13:00:11 +03:00
Jan Vidar Krey 928225fb7b On Mac OS X getrlimit() returns 2^(sizeof(size_t) * 8) instead of the actual number of available socket descriptors. 2010-01-26 08:40:10 +01:00
Jan Vidar Krey e3cf41cb97 BSD/OSX compile fix. 2010-01-25 14:23:22 +01:00
Jan Vidar Krey 59f67f9e17 Updated ChangeLog and README. 2010-01-24 23:38:25 +01:00
Jan Vidar Krey bfc7c184a7 Fix release build compile warnings. 2010-01-23 14:59:51 +01:00
Jan Vidar Krey 92c448b855 Dont use SSL by default. 2010-01-23 01:09:00 +01:00
Jan Vidar Krey 304ecda16a Enable the statistics timer again, so that !stats provide up to date network statistics. 2010-01-23 00:43:38 +01:00
Jan Vidar Krey c670d13369 Make sure we shutdown SSL connections when an error occurs. 2010-01-23 00:20:48 +01:00
Jan Vidar Krey b2e7a2848f Optimize epoll to never modify the epoll mask unless it actually changed. 2010-01-23 00:03:45 +01:00
Jan Vidar Krey 84bd2591d6 SSL fixes, seems to work with stunnel4 as a client but not linuxdcpp using SSL directly. 2010-01-22 23:43:23 +01:00
Jan Vidar Krey 4aa65733d0 Poll as long as possible until next timeout the earliest. 2010-01-22 23:18:59 +01:00
Jan Vidar Krey 230ca28b46 Some unfinished SSL work. 2010-01-22 18:52:38 +01:00
Jan Vidar Krey 5f353ebe28 Added script to create SSL certificate. 2010-01-22 18:22:39 +01:00
Jan Vidar Krey 68a26e1160 Added proper POSIX signal handler. 2010-01-22 16:57:30 +01:00
Jan Vidar Krey 4711d26c11 Fix broken net_address_to_string(). 2010-01-22 16:09:19 +01:00
Jan Vidar Krey 1bb3bd90c1 Use non-default port to ensure autotests work even though a hub is running on the default port. 2010-01-22 16:05:48 +01:00
Jan Vidar Krey 5e253e8442 Fix compile error. 2010-01-22 16:04:36 +01:00
Jan Vidar Krey 26a2a384b6 Bump to version 0.3.0 2010-01-22 16:01:54 +01:00
Jan Vidar Krey 8b7f09c7f4 Fixed two cases of bad connection close. 2010-01-21 23:54:38 +01:00
Jan Vidar Krey b29da11f3b Make sure we call the timeout code. 2010-01-21 23:52:04 +01:00
Jan Vidar Krey 78ad9b8572 Fixed bad logic inside the timer scheduling. 2010-01-21 23:13:52 +01:00
Jan Vidar Krey b04a20c66e fixed off by one bug in due to message escape. 2010-01-21 22:20:26 +01:00
Jan Vidar Krey 21a5981905 Make sure start_listening_socket does everything, this will lead the way to multiple listen ports. 2010-01-21 17:31:55 +01:00
Jan Vidar Krey c47ea14047 Code cleanup for starting the listening socket. 2010-01-21 01:54:41 +01:00
Jan Vidar Krey 9f5aaf0148 Added a safe connection cleanup procedure for when a connection goes
down while it may be attempted to be used.
2010-01-21 01:12:57 +01:00
Jan Vidar Krey f645811f37 Merge branch 'master' of github.com:janvidar/uhub 2010-01-20 18:42:45 +01:00
Jan Vidar Krey 2f09fcea84 Added select() backend which can be used as a fallback if epoll is not available. 2010-01-20 18:39:55 +01:00
root 5e679e2d4f - add doc/init.d.RedHat/etc/logrotator.d/uhub file 2010-01-20 11:18:16 +03:00
root efeb36c492 - update uhub.conf example after add !rules
- add example rules.txt
- fix compile warning in  src/util/timeout.c
- add example config file for rotate log file in RHEL\CentOS
2010-01-20 11:12:43 +03:00
Jan Vidar Krey 7e60919596 sorted the commands shown in help. 2010-01-20 00:24:57 +01:00
Jan Vidar Krey e7cb4cd277 remove extra space before !broadcast messages 2010-01-20 00:12:39 +01:00
Jan Vidar Krey e45511827f Added the +rules command.
Also added the +motd command to see the message of the day, which is sent while connecting.
2010-01-19 23:30:26 +01:00
Jan Vidar Krey 80c6ad9d76 Added mute/unmute functionality. 2010-01-19 23:07:55 +01:00
Jan Vidar Krey f84f3b1fff Merge branch 'master' of github.com:janvidar/uhub into sans_libevent 2010-01-19 19:35:20 +01:00
Jan Vidar Krey f84073f7cc Various fixes for epoll handling without libevent.
This should take care of most compile issues as well as busy loops caused by unhandled recv() calls returning 0 and general cleanups.
2010-01-19 17:52:58 +01:00
Jan Vidar Krey af8421fa47 Crash fix. 2010-01-18 21:57:51 +01:00
Jan Vidar Krey 001fa6739a Crash fix. 2010-01-18 19:38:07 +01:00
Jan Vidar Krey 7dfa3162cb Epoll fixes. 2010-01-18 19:34:18 +01:00
Jan Vidar Krey 314707f499 Epoll fixes. 2010-01-18 16:15:38 +01:00
Jan Vidar Krey 1c58a85de1 More work on epoll. 2010-01-17 23:00:28 +01:00
lv77 eb5d3936a9 Add TODO file. Some modify example uhub.conf 2010-01-14 09:49:03 +03:00
lv77 23daa42b72 Add TODO file. Some modify example uhub.conf 2010-01-14 09:46:55 +03:00
root a643bb123d Add init.d files for RedHat\CentOS 2010-01-13 16:27:07 +03:00
Jan Vidar Krey 6a4b9c58f4 Work on removing libevent completely as a mandatory dependency. 2010-01-07 20:55:13 +01:00
Jan Vidar Krey f35b2c35cb Fix some compile errors. 2009-12-14 16:17:59 +01:00
Jan Vidar Krey b3aa5332c8 Work on epoll backend, and removing dependency on libevent. 2009-12-10 23:12:04 +01:00
Jan Vidar Krey 1f9cfe58c4 No need to allow users not yet logged in to send special hub commands to the hub.
Nothing bad will happen, except the hub will try to answer them even though the user is not yet fully logged in. This fix ensures that these messages are simply dropped instead.
2009-12-09 19:40:12 +01:00
Jan Vidar Krey 50f5ce9d32 Fix bug #100 - Null pointer crash if sending a chat message without the message part. 2009-12-09 19:30:08 +01:00
Jan Vidar Krey 4a4de0f2ac Make sure we have libevent enabled for now, and add macro protection around the areas of the code that still depend on libevent. 2009-12-09 17:27:46 +01:00
Jan Vidar Krey 2e2f93d0a4 Started working on new timeout handling which can be used when we remove libevent.
This will probably be used by default on UNIX platforms at some point.

The timeout handling accomplishes O(1) inserts, removes and reschedules
but the accuracy is limited to whole seconds.
2009-12-09 17:12:33 +01:00
Jan Vidar Krey 7c093dc5da Fix for very long messages that get dropped if they are sent alone (no other message before it) and does not fit inside one TCP packet.
(Thanks FleetCommand!)
2009-12-04 08:12:54 +01:00
Jan Vidar Krey 8bcdbdc061 Removed assert. 2009-11-21 11:52:25 +01:00
Jan Vidar Krey 53536f191d Crash fix. 2009-11-21 11:47:26 +01:00
Jan Vidar Krey e994f23ea0 Crash fix part 2 2009-11-18 18:35:31 +01:00
Jan Vidar Krey f489e77602 Crash fix? 2009-11-18 18:27:31 +01:00
Jan Vidar Krey 2526c8a9ed Silly compile error. 2009-11-18 17:43:11 +01:00
Jan Vidar Krey 4556623a87 Clarify flags as unsigned. 2009-11-18 17:41:22 +01:00
Jan Vidar Krey 828c19cfc6 Fix a wrong open() if no motd is specified. 2009-11-18 17:41:55 +01:00
Jan Vidar Krey 00995a1946 Fix potential memory leaks and crashes. 2009-11-18 17:41:28 +01:00
Jan Vidar Krey f4e82ef503 Cleanup the net_event handler. 2009-11-18 17:40:28 +01:00
Jan Vidar Krey eb7bec585e Fix problems with write events not being processed due to a read event taking presendence.
Conflicts:

	src/core/netevent.c
2009-11-18 17:40:23 +01:00
Jan Vidar Krey 066b3f5243 Fix protocol probe. Will detect ADC and TLS handshake - any other request
will simply cause the hub to close the connection.

Conflicts:

	src/core/netevent.c
	src/core/probe.c
2009-11-18 17:38:25 +01:00
Jan Vidar Krey a51e8830ce Log dropped messages. 2009-10-30 18:31:27 +01:00
Jan Vidar Krey e6cc47070c A few minor TLS fixes 2009-10-09 21:38:14 +02:00
Jan Vidar Krey 0c5d98c671 TLS compile and crash fixes. 2009-10-09 21:11:11 +02:00
Jan Vidar Krey 0f30ebf045 Some stability fixes. Removed log messages. 2009-10-09 20:35:04 +02:00
Jan Vidar Krey 4919c8f2f9 Fix compile error. 2009-10-09 00:11:09 +02:00
Jan Vidar Krey 2910c571b0 Fix protocol probe. Will detect ADC and TLS handshake - any other request
will simply cause the hub to close the connection.
Fix problems with write events not being processed due to a read event taking presendence.
Fix bug #86: Windows does not have "getrlimit()".
2009-10-08 23:16:15 +02:00
Jan Vidar Krey 11e5683a79 Cleanup code somewhat. 2009-10-06 18:33:06 +02:00
Jan Vidar Krey 17416def35 Make sure we flag JOIN/LEAVE messages as really verbose debug output. 2009-10-06 18:28:16 +02:00
Jan Vidar Krey 234f04f495 Removed extra main block. 2009-10-06 18:25:50 +02:00
Jan Vidar Krey 4898454c91 Removed redundant and ununsed operation mode for adcrush. 2009-10-06 18:24:21 +02:00
Jan Vidar Krey 255255ff20 Allow for command line specified host. 2009-10-06 18:16:38 +02:00
Jan Vidar Krey f50b40fb92 Fix bug #85 - Do not broadcast unknown commands, but allow for commands to be broadcasted if they are double escaped with ++ or !!. 2009-10-06 18:02:37 +02:00
Jan Vidar Krey 40fc09a7ef Whitespace cleanups. 2009-10-06 17:40:09 +02:00
Jan Vidar Krey 582bb58ff9 Refactor the address parsing bits of adcrush. 2009-10-06 17:25:38 +02:00
Jan Vidar Krey 7472e9ae4a Removed some old unused macros. 2009-10-06 15:53:24 +02:00
Jan Vidar Krey f076c67c33 Added a configurable listen() backlog (defaults to: server_listen_backlog=50) 2009-10-06 15:50:42 +02:00
Jan Vidar Krey 7eef032584 Doc update. 2009-10-06 14:39:47 +02:00
Jan Vidar Krey de793ea9d2 Some compile fixes and memory leak fixes for ADCRush. 2009-10-06 14:36:49 +02:00
Jan Vidar Krey 20ef6f8e53 Fix to net_con_close() which allows us to either delete the connection immediately if that is safe, or delete it later. 2009-10-06 14:36:05 +02:00
Jan Vidar Krey 310ddf4e9d More work on the ADC client lib. 2009-10-06 12:39:31 +02:00
Jan Vidar Krey 8592aa80d4 Compile fix. 2009-10-06 12:24:44 +02:00
Jan Vidar Krey c3ba8d52ee Merge branch 'master' of baracus-vpn:~/git/uhub
Conflicts:
	src/adc/message.c
2009-10-06 12:18:14 +02:00
Jan Vidar Krey 69f6d811bf Added lots of asserts, and split out the ip address from the connection object.
Still a lot of work remains and a massive network connection cleanup is needed.
2009-09-29 00:30:52 +02:00
Jan Vidar Krey a53c219f05 Fix bug #82 - Crash writing a log larger than 2GB on a 32 bit system as _FILE_OFFSET_BITS was not declared to be 64. 2009-09-14 12:24:18 +02:00
Jan Vidar Krey 96ce64ee07 Fix memory issues in ADC client lib. 2009-09-04 17:18:52 +02:00
Jan Vidar Krey a3d6646b99 Fix a failing autotest. 2009-08-31 20:37:47 +02:00
Jan Vidar Krey 4fd182c55e Fix compile warning. 2009-08-31 20:36:25 +02:00
Jan Vidar Krey 993d9ae33b Fix some issues regarding header extraction. 2009-08-31 19:45:47 +02:00
Jan Vidar Krey fe9b48f14c Added new convenient adc_msg_* functions for accessing named parameters. 2009-08-31 19:42:34 +02:00
Jan Vidar Krey 1e380ecf0f Fix bug #77 - Error in ACL command parsing. 2009-08-31 19:39:09 +02:00
Jan Vidar Krey af7b52b708 Cleanup argument extraction. 2009-08-31 12:25:06 +02:00
Jan Vidar Krey aeba7188c0 Added a macro that can keep the line count down. 2009-08-28 18:10:41 +02:00
Jan Vidar Krey 4ca5caa52b Various fixes, the admin tool at least compiles and runs. 2009-08-28 18:05:58 +02:00
Jan Vidar Krey 5203ecdadc Split uhub.h 2009-08-28 16:18:18 +02:00
Jan Vidar Krey 11b288a669 Various build fixes. 2009-08-28 16:04:45 +02:00
Jan Vidar Krey 52cbec24b6 Started splitting up ADC rush. Need a test client before we can proceed anyway. 2009-08-28 14:29:19 +02:00
Jan Vidar Krey 29d6d59d36 Misc connection changes. 2009-08-27 14:15:18 +02:00
Jan Vidar Krey 96c006ee13 Cleanup some code. 2009-08-23 14:36:52 +02:00
Jan Vidar Krey e67587b997 Fix output handling. 2009-08-23 14:36:17 +02:00
Jan Vidar Krey 1af613d9ce Fixed printf issues with size_t. Since Windows do not support %zu we have to use %Iu there instead.
Solved that with an ugly but needed macro.
2009-08-20 10:44:44 +02:00
Jan Vidar Krey 5bd258ca52 Move the network related flags from network.h to connection.h since that is where they are used. 2009-08-11 21:29:51 +02:00
Jan Vidar Krey 86ba3ca86f Complete moving all connection related data out of the hub_user object. 2009-08-07 00:22:30 +02:00
Jan Vidar Krey cfb450c3fc Added net_set_nonblocking for Solaris. 2009-08-06 23:28:44 +02:00
Jan Vidar Krey cd389742e6 Solaris fixes. 2009-08-06 23:15:55 +02:00
Jan Vidar Krey 4afa187f9a Expose SSL/TLS related config variables. 2009-08-06 23:05:53 +02:00
Jan Vidar Krey b3c40f7443 Use -levent not -lev 2009-08-04 04:59:52 +02:00
Jan Vidar Krey d45383fe4d Fix some asserts. 2009-08-04 04:58:55 +02:00
Jan Vidar Krey 1642b8dfbe Use new connection data structs. 2009-08-04 04:47:31 +02:00
Jan Vidar Krey ffd455474a Fix use of wrong event types. 2009-08-04 04:47:02 +02:00
Jan Vidar Krey 5baf277f5a Various fixes. 2009-08-04 04:46:24 +02:00
Jan Vidar Krey ab6eda2bbb Disabled SID allocation debug messages by default. 2009-08-04 03:38:12 +02:00
Jan Vidar Krey c17ae06b93 Added some memory debugging facilities to the adc_message structures. 2009-08-04 03:37:30 +02:00
Jan Vidar Krey faaa3d14e4 Dont clear the timer, instead set the TIMEOUT_IDLE when logging in (for now at least) 2009-08-04 01:07:12 +02:00
Jan Vidar Krey 9f784e808e Fix bug #70 - crash if client is in nat_ip zone, but does not provide an IP in the INF message. 2009-08-04 01:02:49 +02:00
Jan Vidar Krey b9adaa4f8b Fix libevent init. 2009-08-04 00:22:08 +02:00
Jan Vidar Krey 80dee0c020 Get rid of the event_base_set() calls. 2009-08-04 00:15:04 +02:00
Jan Vidar Krey 604c2d8836 Disable SSL by default. 2009-08-03 23:59:19 +02:00
Jan Vidar Krey eca0f931bd Fixes to shutdown... 2009-08-03 23:59:02 +02:00
Jan Vidar Krey fbe98d6011 Move the timeout handling to the connection object. 2009-08-03 21:57:18 +02:00
Jan Vidar Krey 4a5993ccc2 Added a generic SSL handshake mechanism. 2009-08-03 20:21:59 +02:00
Jan Vidar Krey a297c08bba Dont use DEBUG messages, instead a much lower level messages for SSL related debug messages. 2009-08-03 19:55:57 +02:00
Jan Vidar Krey 7229ad68ab Make sure we send with the same arguments again if SSL_write() fails with SSL_ERROR_WANT_READ. 2009-08-03 19:54:28 +02:00
Jan Vidar Krey 22f9be95d0 ensure we close the SSL connection if we get SSL_ERROR_ZERO_RETURN. 2009-08-03 18:20:08 +02:00
Jan Vidar Krey 4e43746c1b Moved the ipaddr object into the connection object. 2009-08-03 18:14:34 +02:00
Jan Vidar Krey 27c71a75ee Hook in the new connection work, also implemented some missing bits
and pieces of SSL.
SSL seems to work at some basic level, and is largely untested.
2009-08-03 17:25:52 +02:00
Jan Vidar Krey 1d363ed0b4 Expose the SSL_connect() and SSL_accept() functions. 2009-08-03 14:21:53 +02:00
Jan Vidar Krey 79cf5ee9db Some work on integrating OpenSSL. 2009-08-03 03:55:38 +02:00
Jan Vidar Krey d2da49d41a Added .gitignore file. 2009-08-02 23:44:23 +02:00
Jan Vidar Krey 4666311516 Add a quit reason to the log messages printed by !log. 2009-08-02 22:53:25 +02:00
Jan Vidar Krey 1f24bd6812 Fix autotests. 2009-08-02 22:29:22 +02:00
Jan Vidar Krey 0e1cd903da Make sure we create enough sids as there are socket descriptors. 2009-08-02 22:29:12 +02:00
Jan Vidar Krey 4931dc5dcb Added call functionality to figure out the maximum number of sockets (file descriptors) available on system. 2009-08-02 22:28:34 +02:00
Jan Vidar Krey 077bffd74f Fix capped whoip/history messages due to limit of 1024 bytes imposed wrongly on outgoing server generated messages. 2009-08-02 21:58:12 +02:00
Jan Vidar Krey cfb8a9f322 Started using the new connection abstraction. 2009-08-02 21:46:57 +02:00
Jan Vidar Krey 653cfb285e Started working on abstracting the connection data away from the user struct. 2009-08-02 21:37:55 +02:00
Jan Vidar Krey 053fb30192 Build fix. 2009-08-02 21:07:16 +02:00
Jan Vidar Krey 9bd0286c01 Fix bug #3, sid allocation overflow. May lead to double SIDs being given out. 2009-08-02 21:04:10 +02:00
Jan Vidar Krey b78d48795b !history had a wrong help description. 2009-08-02 19:26:21 +02:00
Jan Vidar Krey 9b58ba6516 Use correct prefix for log command. 2009-07-28 02:17:57 +02:00
Jan Vidar Krey f322fbb197 Fix !log command, split it up into multiple messages, and allow for searches. 2009-07-28 02:02:19 +02:00
Jan Vidar Krey 80348044c3 Make sure history messages are not escaped. 2009-07-26 18:22:53 +02:00
Jan Vidar Krey 31d4b0f0b1 Fix history - do not cache private messages. 2009-07-26 15:08:34 +02:00
Jan Vidar Krey 10615a9a1a Whitespace 2009-07-26 06:32:15 +02:00
Jan Vidar Krey 7b44036480 print ip address when using whoip. 2009-07-26 06:30:48 +02:00
Jan Vidar Krey 112fa2f845 Fixes to tests. 2009-07-26 06:27:16 +02:00
Jan Vidar Krey 945c6be14c Added tests for ip_convert_address_to_range 2009-07-26 06:21:22 +02:00
Jan Vidar Krey 099ed6dbe2 Fix autotest 2009-07-26 06:06:27 +02:00
Jan Vidar Krey 444f991f44 Fix bug #44 - [Request] IP log in the memory 2009-07-26 06:03:43 +02:00
Jan Vidar Krey b125ffe3c1 Fix bug #52 - [Request] Chat history command 2009-07-26 05:23:56 +02:00
Jan Vidar Krey 76b84499bc Fix bug #46: [Request] A broadcast command.
Use !broadcast <message>
2009-07-26 04:47:43 +02:00
Jan Vidar Krey 6358c7f9cd Fix bug #45: [Request] Whoip command.
Rewrote patches from Zoltan to support ip ranges and multiple results per IP.
Needed to make sure IPv6 mapped IPv4 addresses were converted to proper IPv4 addresses after accept().
2009-07-26 04:31:36 +02:00
Jan Vidar Krey 041ce7a1fb Generalized the IP range and mask parsing code. 2009-07-26 03:56:55 +02:00
Jan Vidar Krey 78bb1d3527 Typo - compilefix. 2009-07-26 02:06:02 +02:00
Jan Vidar Krey 48f3cae22b Ensure we delete the global evtimer only if it is initialized. 2009-07-26 02:05:01 +02:00
Jan Vidar Krey 817250c528 Fix wrong #if to #ifdef 2009-07-26 01:53:53 +02:00
Jan Vidar Krey f176e790e2 Whitespace fixes. 2009-07-26 01:53:01 +02:00
Jan Vidar Krey 367871e476 Renamed all "struct user" to hub_user in order to resolve a naming conflict on OpenWRT.
Basically: sed -i 's/struct user/struct hub_user/g' `find -type f`
2009-07-26 01:47:17 +02:00
Jan Vidar Krey 2ac5cc19cb Removed plugin.h, not in use. 2009-07-26 01:39:16 +02:00
Jan Vidar Krey 6e5d28c2d4 Rework logging code to be able to turn it off completely. 2009-07-26 01:38:38 +02:00
Jan Vidar Krey 5048ff9ae5 Whitespace fixes. 2009-07-26 00:58:25 +02:00
Jan Vidar Krey 36a07e3f7e Reorganized sources slightly. 2009-07-25 20:05:27 +02:00
Jan Vidar Krey e281f61472 Add support for better pipelining of commands, in order to reduce the number of send() calls. 2009-07-25 03:54:59 +02:00
Jan Vidar Krey bb27ff617c Re-fix chat_is_privileged. 2009-07-25 03:33:36 +02:00
Jan Vidar Krey dc90245ade No need to store event mask in the user object since libevent already does it for us. 2009-07-25 03:26:59 +02:00
Jan Vidar Krey 0ec4913e15 Debug for send queue fix. 2009-07-25 03:24:06 +02:00
Jan Vidar Krey 61d639bfa2 Fix to hub_sendq_is_empty in order to prevent event_add calls. 2009-07-25 03:23:06 +02:00
Jan Vidar Krey adeaf23f9c Kept spinning in send() 2009-07-19 14:45:15 +02:00
Jan Vidar Krey 03d3ffd20f Fix socket error due to EWOULDBLOCK. 2009-07-19 14:29:33 +02:00
Jan Vidar Krey bbae2603b0 Make sure we detect send errors. 2009-07-19 03:39:11 +02:00
Jan Vidar Krey 5f0c84f46a Fix shutdown problem and reduce event_{add,del,set} calls. 2009-07-19 03:12:47 +02:00
Jan Vidar Krey b02618d19c Bad mistake - never added message to send queue. 2009-07-19 02:46:01 +02:00
Jan Vidar Krey 927faf70fc Re-enabled send queue fixes. This will more aggressively prevent unimportant messages (like searches) to be forwarded to slow clients that cannot swallow what is sent to it. This should reduce memory usage somewhat on really large hubs. 2009-07-19 02:31:23 +02:00
Jan Vidar Krey 4a173bf066 Fix some nasty bugs related to read/write events and timeout events.
This would have caused users not being able to log in, and in some cases
100% cpu usage.
2009-07-19 02:12:50 +02:00
Jan Vidar Krey abd097acf0 This is a somewhat risky patch, but it has been intended for quite some time:
Remove the libevent handler for write events, only use one common event handler for both reading and writing.
2009-07-09 17:03:31 +02:00
Jan Vidar Krey 3fdbccb028 Fix bug #47 - Enable -ggdb instead of -g for DEBUG builds.
RELEASE builds are built with -O3 instead of -Os.
2009-07-09 17:01:45 +02:00
Jan Vidar Krey 3db2ec5e22 Added macros that can possibly make it easier to optimize functions using forced inlining and regparm. 2009-07-09 17:01:30 +02:00
Jan Vidar Krey e68cbd0cde Minor cleanups of old authentication stuff, and some documentation. 2009-07-03 01:29:04 +02:00
Jan Vidar Krey 98bffd93e9 Fix stupid crash on empty command. 2009-07-01 11:31:55 +02:00
Jan Vidar Krey e53119e92c Server did not answer due to wrong checks. 2009-07-01 09:50:46 +02:00
Jan Vidar Krey ee0ea5a427 Crash fix. 2009-06-30 22:15:08 +02:00
Jan Vidar Krey aa7be1dc4b Fix a command parse error output problem, plus some minor cleaning up. 2009-06-30 11:48:58 +02:00
Jan Vidar Krey 0ef248759c Minor cleanups.
Enabled !crash command if compiled with debug (not release).
2009-06-29 23:22:13 +02:00
Jan Vidar Krey 5b5d9faf96 Bumped to 0.3.0-rc3. 2009-06-26 01:16:18 +02:00
Jan Vidar Krey 1f7f6a43f9 Fixed small memory leak. 2009-06-26 01:16:07 +02:00
Jan Vidar Krey 3cf005a08e Fixed command parsing for in hub user commands.
Added a framework for automatic syntax checks, and correct number
of arguments to commands.
2009-06-26 01:15:06 +02:00
Jan Vidar Krey f3c5fced47 Documentation 2009-06-25 22:05:40 +02:00
Jan Vidar Krey 9c49f07826 Fixed the format of the git revision.
Removed the product title.
2009-06-25 22:04:48 +02:00
Jan Vidar Krey 0b59941102 Minor optimization. 2009-06-25 17:35:59 +02:00
Jan Vidar Krey 5f3f2d4f4d Autotest crash fix. 2009-06-25 17:31:39 +02:00
Jan Vidar Krey a3d4c8dbc3 Windows fix. 2009-06-25 17:29:50 +02:00
Jan Vidar Krey 7e3a26b0f3 Winsock fixes for shutdown() - typo 2009-06-25 17:07:21 +02:00
Jan Vidar Krey 9ebb38ae15 Winsock fixes for shutdown() 2009-06-25 17:05:59 +02:00
Jan Vidar Krey 5b29a3b403 Bump to 0.3.0 release candidate 2. 2009-06-25 09:29:59 +02:00
Jan Vidar Krey 75c4272a1b Fix problem with the !stats byte counter. 2009-06-25 09:29:23 +02:00
Jan Vidar Krey f272280faf Old versions of git 0.5 does not support the git show --oneline. - Maybe this works? 2009-06-24 09:18:03 +02:00
Jan Vidar Krey b1d4b1288f Bump to 0.3.0-rc1 2009-06-23 23:29:27 +02:00
Jan Vidar Krey ddba669af0 Some basic work on getting bans working.
Basically now it can ban a user (nick + cid), it will be added to the
ban list temporarily, and will not be enabled if you restart the hub.
A banned user will automatically be kicked.

unban does not work correctly.
2009-06-23 23:16:09 +02:00
Jan Vidar Krey 2ad2b66db3 Add a git revision to all debug builds... 2009-06-23 16:11:30 +02:00
Jan Vidar Krey ca33461851 Suppress send() or recv() errors from logs. They happen quite often and are not considered errors. 2009-06-23 01:57:55 +02:00
Jan Vidar Krey 4abdc3edbd Cleanup read/write socket handling somewhat. 2009-06-23 01:57:26 +02:00
Jan Vidar Krey 90078ad4b6 Minor cleanups and some work to prepare SSL. 2009-06-23 01:56:37 +02:00
Jan Vidar Krey 3bd5c36455 SSL work. 2009-06-23 01:09:55 +02:00
Jan Vidar Krey 8f0943621e Dont set socket buffers. 2009-06-22 21:13:41 +02:00
Jan Vidar Krey 155350b61b Fixed crash bug #33 2009-06-22 21:05:02 +02:00
Jan Vidar Krey 1c58120c03 Oportunistic write. 2009-06-22 20:25:22 +02:00
Jan Vidar Krey 1d9acece34 Ensure we set a max recv and send buffer per user, and that it does not
exceed the one used internally by the application.
2009-06-22 19:50:10 +02:00
Jan Vidar Krey 57fd872f14 Added a state check for protocol negotiation.
Will be used to negotiate SSL.
2009-06-22 19:38:24 +02:00
Jan Vidar Krey ca7544df9b Cleanups. 2009-06-22 19:37:56 +02:00
Jan Vidar Krey c7777e2624 Added functions:
* net_get_recvbuf_size
* net_set_recvbuf_size
* net_get_sendbuf_size
* net_set_sendbuf_size

Did some minor cleanups.
2009-06-22 19:36:55 +02:00
Jan Vidar Krey b2d543d433 Started work on SSL 2009-06-22 18:44:07 +02:00
Jan Vidar Krey ff47281197 Added a generic way to reset last read/write variables. 2009-06-22 18:38:39 +02:00
Jan Vidar Krey ddc91d1640 Make sure we close stdout, stdin and stderr after forking to background in order to properly detach from the TTY. 2009-06-22 18:36:48 +02:00
Jan Vidar Krey 0d084a5e14 Move to rc0 2009-06-22 17:32:38 +02:00
Jan Vidar Krey e6e26a02e7 Added a known crash for the admin only to use if compiled with CRASH_DEBUG enabled. 2009-06-22 01:18:51 +02:00
Jan Vidar Krey ea3cd1bd90 Work on optimizing send(), to use fewer send function calls. 2009-06-21 14:21:34 +02:00
Jan Vidar Krey 7f24238ab5 Disable sendq debugging. 2009-06-20 22:46:11 +02:00
Jan Vidar Krey 1d2d4e74f6 !stats did not work. 2009-06-18 01:46:17 +02:00
root 5250fdaf57 Fix bug #38 - Pid file support. 2009-06-17 12:52:49 +02:00
Jan Vidar Krey 7ddfd52dc7 Fix bug #34 - Disable admin\op account in example users.conf since it is being installed by default. 2009-06-01 19:55:03 +02:00
Jan Vidar Krey 513ab422f2 Compile fix. 2009-06-01 14:34:23 +02:00
Jan Vidar Krey 0eb91763fa Potential crash fix. 2009-06-01 01:52:57 +02:00
Jan Vidar Krey 507f429035 Fix send queue issue. 2009-05-28 23:44:28 +02:00
Jan Vidar Krey b1ab64242e Renamed a function. 2009-05-28 01:48:31 +02:00
Jan Vidar Krey 8b90f79bac Work in progress on optimizing the send() function calls, to use as few as possible.
(Although, this does not enable that code).
2009-05-28 01:47:48 +02:00
Jan Vidar Krey 8f7cc0b7a7 Fixed MAX and MIN macros. 2009-05-28 01:45:36 +02:00
Jan Vidar Krey 4812a5968b Added an ADC redirector script, which is useful to run from inetd, xinetd
or similar in case you move your hub to another machine.
It will accept ADC connections and redirect clients to the new hub
instead.
2009-05-28 01:33:23 +02:00
Jan Vidar Krey 8b5bfdd922 Compile fix. 2009-05-27 18:05:34 +02:00
Jan Vidar Krey 860310caff Massive restructuring. 2009-05-26 21:05:06 +02:00
Jan Vidar Krey 8167d79f5a Large reorganizations of the code base. 2009-05-26 19:46:51 +02:00
Jan Vidar Krey 9706a0a501 Fix compiler warning (bug #30) 2009-05-24 21:07:16 +02:00
Jan Vidar Krey 9309c925d3 Started working on new pipelines for sending and receiving data.
This will be useful for the next step; SSL.

(NOTE: This code is very chatty about debug messages)
2009-05-19 22:57:50 +02:00
Jan Vidar Krey 9a3a5bc2de Make sure the send() signature is correct, buf should be const. 2009-05-19 22:36:45 +02:00
Jan Vidar Krey e382e24337 Fix crash due to user->hub deref in acl handling. 2009-05-19 16:40:14 +02:00
Jan Vidar Krey be4ff1d8cc Fix command parsing for in-hub commands. 2009-05-19 11:22:57 +02:00
Jan Vidar Krey aa18ac047d Crash fix 2009-05-19 09:38:57 +02:00
Jan Vidar Krey e120d5c76d Minor cleanup - this code crashes. 2009-05-19 09:15:14 +02:00
Jan Vidar Krey 6853e92f89 Move user_is_protected() and user_is_registered() into user.h/.c 2009-05-18 17:52:30 +02:00
Jan Vidar Krey 1dbf2640d2 More API fixes; remove implicit relationship between hub and user
in APIs.
2009-05-18 16:30:17 +02:00
Jan Vidar Krey caec28f63f Warn on bad UTF-8 in the configuration file. 2009-05-16 12:48:17 +02:00
Jan Vidar Krey 5ea5efb875 Smome user manager functions did not have the uman_ prefix. 2009-05-16 12:42:30 +02:00
Jan Vidar Krey 326fcc467c Moved the update_user_info code into user_update_info 2009-05-16 12:32:48 +02:00
Jan Vidar Krey 078470ce64 Minor cleanup 2009-05-16 12:25:28 +02:00
Jan Vidar Krey 82ac450b4b Fixed further memory leaks in autotests. 2009-05-16 04:03:00 +02:00
Jan Vidar Krey b4f24b21f9 Document bandwidth optimization potential. 2009-05-16 03:45:05 +02:00
Jan Vidar Krey 968266b22f Fix memory leaks. 2009-05-16 03:44:51 +02:00
Jan Vidar Krey 548867de10 Removed ADC_UDP_OPERATION code as it is not used or needed. on_kick is also gone. 2009-05-16 03:14:20 +02:00
Jan Vidar Krey 953db2dcbc Fixed some autotest memory leaks. 2009-05-16 03:06:14 +02:00
Jan Vidar Krey 6e4ac1355f Fix autotest crashers. 2009-05-16 02:33:43 +02:00
Jan Vidar Krey 604364ffa5 Fixed various code deprecations
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-05-15 18:45:26 +02:00
Jan Vidar Krey 6cc1af5671 Disable code to prevent warnings. 2009-05-15 16:52:55 +02:00
Jan Vidar Krey 15e2053699 Fix #28 - Request: +/! characters for command handling (FleetCommand) 2009-05-15 16:52:04 +02:00
Jan Vidar Krey df1e832a3c Started working on a red-black tree implementation, need to speed up
certain operations, such as SID to user lookups, and nick to user.
2009-05-01 17:07:38 +02:00
Jan Vidar Krey 4c4cb4fb36 Dont allow clients that do not support BASE
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-04-13 05:31:41 +02:00
Jan Vidar Krey e49f9d4d30 Added kick support
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-04-09 00:48:00 +02:00
Jan Vidar Krey e73a931243 Ensure we do not allow update of certain elements.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-27 11:12:50 +01:00
Jan Vidar Krey ae017af758 Log version and method of libevent()
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-24 23:32:39 +01:00
Jan Vidar Krey 7a02f92a4c Cleanup after creating debian packages.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-24 23:16:09 +01:00
Jan Vidar Krey adeebb92a0 Added manual page. 2009-03-24 23:14:04 +01:00
Jan Vidar Krey 26f1864c1f Don't crash if one specify '-S' or '-s' and an invalid configuration file. 2009-03-24 23:10:51 +01:00
Jan Vidar Krey c14fa3c3a9 Added more debugging info for mainloop bug #16 - In addition to small fixes to it.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-24 22:06:26 +01:00
Jan Vidar Krey dfd2191103 White space cleanups. 2009-03-24 18:39:39 +01:00
Jan Vidar Krey 0042344054 Better dpkg system. 2009-03-24 18:38:59 +01:00
Jan Vidar Krey 8af965c0ca Fixed utf8 parse issue.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-24 00:21:38 +01:00
Jan Vidar Krey b3d3dcdb44 Actually do upload.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-23 23:45:39 +01:00
Jan Vidar Krey cb6190c5b4 FreeBSD fix.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-23 23:39:34 +01:00
Jan Vidar Krey 82ad62602d 0.2.8 release candidate.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-23 23:36:29 +01:00
Jan Vidar Krey 6d34bdd7e2 Added upload script.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-23 23:32:32 +01:00
Jan Vidar Krey c2832e59c0 Added build script setup for easy publishing...
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-23 23:30:51 +01:00
Jan Vidar Krey cf23c82c16 Added upload support.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-23 23:02:59 +01:00
Jan Vidar Krey 8bf0fd424a Added upload support. 2009-03-23 23:02:52 +01:00
Jan Vidar Krey 8f8284eb29 Ensure we build source .zip file. 2009-03-23 22:54:59 +01:00
Jan Vidar Krey 015c3368bd Added new script for building sources only.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-23 22:51:53 +01:00
Jan Vidar Krey 9186b441aa Minor build system tweaks.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-23 22:47:08 +01:00
Jan Vidar Krey 74af392e80 Stop in case of error.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-23 22:40:15 +01:00
Jan Vidar Krey 3a270564d2 Fixed up admin scripts.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-23 22:36:45 +01:00
Jan Vidar Krey f0938e8afa Fixed up build scripts somewhat. 2009-03-23 22:33:45 +01:00
Jan Vidar Krey 156c137237 Autotest for bug #12
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-23 21:55:24 +01:00
Jan Vidar Krey 7aeb8651ba Fix bug #12: asserts in adc_msg_parse -> enabled strict utf8 parsing.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-23 21:47:05 +01:00
Jan Vidar Krey ab4eb6db3d Document 0.2.8 changes. 2009-03-23 16:51:06 +01:00
Jan Vidar Krey 13a8700554 Make sure logs do not output configured messages, but rather code names.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-23 15:47:54 +01:00
Jan Vidar Krey 5d5dda2f9b Always obtain IP address during accept(), and not do it later as a call to getsockname().
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-23 15:05:27 +01:00
Jan Vidar Krey 95b741bb5e More message tests. 2009-03-23 14:58:15 +01:00
Jan Vidar Krey 90abf64e3a Do explicit logging in src/message.c 2009-03-23 08:18:25 +01:00
Jan Vidar Krey e9915df87c remove timezone from logs, as it screws up on windows.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-21 04:11:14 +01:00
Jan Vidar Krey 408829e330 Another 0.2.7 candidate.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-21 03:59:12 +01:00
Jan Vidar Krey 1a1b5bdb38 Fixed nasty crash if a user sends a very large command to the hub.
Will overwrite heap memory.
Thanks to Toast who found this bug.

Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-21 02:58:53 +01:00
Jan Vidar Krey abedec692a 0.2.7 release candidate
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-20 19:12:18 +01:00
Jan Vidar Krey 7738baf38e Log configuration reloads.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-20 19:09:55 +01:00
Jan Vidar Krey 3c4c52d0f9 Log configuration reloads.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-20 19:08:24 +01:00
Jan Vidar Krey 76588fb1bd Don't print OK or ERROR when dumping config.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-20 19:05:25 +01:00
Jan Vidar Krey f9e95ec582 Minor cleanups
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-20 19:02:32 +01:00
Jan Vidar Krey 7985d4fed0 Cleanup credentials to string handling
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-20 18:54:05 +01:00
Jan Vidar Krey 77343d3c21 Remove duplicate access_denied checks.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-20 18:38:42 +01:00
Jan Vidar Krey f8d5b72a89 Cleanup command list, automatically generate help list depending on user credentials. 2009-03-20 18:37:38 +01:00
Jan Vidar Krey cf2994b570 Fix whitespace 2009-03-20 18:37:05 +01:00
Jan Vidar Krey 7a9d40d8dd Fix autotests for event queue.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-20 17:42:29 +01:00
Jan Vidar Krey b1f84b5b4a Cleanup logging.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-20 17:40:50 +01:00
Jan Vidar Krey 998c6c36ce Fix indentation 2009-03-20 16:40:59 +01:00
Jan Vidar Krey 4112b8111a Fix problems with clients sending multiple INF messages during the login stage. Only the first one will be checked. 2009-03-20 16:40:34 +01:00
Jan Vidar Krey 1929f2fae7 Fix bug #9 - net_get_peer_address() failure on CentOS/Xen configurations.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-20 15:07:52 +01:00
Jan Vidar Krey 77e41371b5 Ensure we install to /usr/local by default.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-19 20:02:03 +01:00
Jan Vidar Krey 0266c8bb9c Libevent fixes, and memory leak fix.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-19 17:57:04 +01:00
Jan Vidar Krey 5e3eabb677 Fix help message typo
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-19 01:30:46 +01:00
Jan Vidar Krey 669ab14022 Minor cleanups and stack reduction.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-19 01:27:34 +01:00
Jan Vidar Krey 1d491055c5 Do not use event_loopexit with new event loop.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-19 01:13:02 +01:00
Jan Vidar Krey 08351ea8e7 Merge branch 'event_queue_work' 2009-03-19 01:08:57 +01:00
Jan Vidar Krey e2ac690164 Reindented code. 2009-03-19 01:01:36 +01:00
Jan Vidar Krey 3bb563b432 Cleaned up command system somewhat. Added admin commands for reload and shutdown. 2009-03-19 00:55:11 +01:00
Jan Vidar Krey e10582fec2 Cleaned up command system slightly.
Added admin commands for reload and shutdown.
2009-03-19 00:53:44 +01:00
Jan Vidar Krey 84e278658b Libevent changes. 2009-03-19 00:43:43 +01:00
Jan Vidar Krey c671851be8 Cleaned up local event queue.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-18 02:56:49 +01:00
Jan Vidar Krey 4f8edfe9c8 Started working on an updated libevent and event queue implementation that would not require timers.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-18 02:32:00 +01:00
Jan Vidar Krey 4d0ed61a05 A first stab at creating debian packages
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-17 01:38:55 +01:00
Jan Vidar Krey 008ec7c8df FreeBSD fixes. 2009-03-16 22:49:55 +01:00
Jan Vidar Krey 7dc88bd23f Add zip support. 2009-03-16 19:02:47 +01:00
Jan Vidar Krey 81eddd4bcf Added new admin files for managing release builds, etc. 2009-03-16 18:47:07 +01:00
Jan Vidar Krey 6f1069c5f7 Removed extra release related makefiles. 2009-03-16 18:27:57 +01:00
Jan Vidar Krey 52cc7d04cf Removed extra release related makefiles. 2009-03-16 18:27:29 +01:00
Jan Vidar Krey 041643c519 Remove references to subversion, replace it with git equivalents 2009-03-16 17:37:59 +01:00
Jan Vidar Krey 4762f007fe Remove obsolete info in README 2009-03-16 17:36:58 +01:00
Jan Vidar Krey 90d3d049a4 Added option TERSE to the makefile which does not display any information on stdout. 2009-03-16 17:36:28 +01:00
Jan Vidar Krey 5f3447c822 Update changelog for release. 2009-03-16 17:35:39 +01:00
Jan Vidar Krey a13b253e86 Document new bugs strategies 2009-03-16 17:35:08 +01:00
Jan Vidar Krey bb578095c0 Added compiling and getstarted notes. 2009-03-16 17:32:55 +01:00
Jan Vidar Krey b8a0b45245 Dump configuration does not quote integer and boolean settings.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-16 14:40:17 +01:00
Jan Vidar Krey eeaceee6f8 Release candidate 0.2.6
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-16 12:56:57 +01:00
Jan Vidar Krey 1e6f0a392a Don't produce errors if a user is already logged in and trying again. 2009-03-16 12:46:29 +01:00
Jan Vidar Krey f396902c57 Do not use socket call to print IP address when we do have a cached representation. 2009-03-16 12:45:13 +01:00
Jan Vidar Krey acc697c33a Do not use socket call to print IP address when we do have a cached representation. 2009-03-16 12:43:45 +01:00
Jan Vidar Krey c29815ed62 Fixed compile warning. 2009-03-16 12:40:12 +01:00
Jan Vidar Krey e74d2be318 Be more explicit when queueing.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-16 12:33:10 +01:00
Jan Vidar Krey 58e2982675 Fixed bug #1: Excessive send queue bug (corruption of the offset variable).
Low priority messages are not relayed if soft limit send queue is reached.

Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-16 12:28:58 +01:00
Jan Vidar Krey 4797d5ee90 SendQ debugging
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-14 02:09:45 +01:00
Jan Vidar Krey 5a0f01d1ec Don't assert, rather print error messages.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-13 17:07:06 +01:00
Jan Vidar Krey f6af8cf389 Merged changes from github.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-13 16:54:39 +01:00
Jan Vidar Krey 7337d9e1d1 Ensure the send queue offset is calculated correctly in case of a partial queued write.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-13 16:51:27 +01:00
Jan Vidar Krey 5a978d361c Added asserts in case send queue size goes below zero.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-13 01:29:21 +01:00
Jan Vidar Krey 62d489130c Dont do double I4/I6 records.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-13 01:10:13 +01:00
Jan Vidar Krey 3aecd67134 Re-fix #5: Always provide IP-address to all users, not just for active clients.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-13 00:54:37 +01:00
Jan Vidar Krey 2edafeba4e Changelog update 2009-03-12 16:27:10 +01:00
Jan Vidar Krey a3520fbf09 Always provide IP address to all clients.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-12 16:24:44 +01:00
Jan Vidar Krey 18b0dc713f Better dynamic send queue handling for large hubs at the cost of more memory use.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-12 16:00:56 +01:00
Jan Vidar Krey 6cf6e38a60 Document config default variables correctly. 2009-03-12 16:00:31 +01:00
Jan Vidar Krey 5912ad3ac3 Ensure operator flag is set for super users and hub owners.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-10 12:01:05 +01:00
Jan Vidar Krey 9770eaf559 Ensure admins and super users are also listed as operators
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-10 11:13:26 +01:00
Jan Vidar Krey fcd532fd4b Wrong stats, peak rx never calculated.
Signed-off-by: Jan Vidar Krey <janvidar@extatic.org>
2009-03-10 00:17:49 +01:00
Jan Vidar Krey dd5986c05f Better help message formatting. 2009-03-08 22:17:41 +01:00
Jan Vidar Krey d85b1bbc35 Added +myip command. 2009-03-08 17:12:01 +01:00
Jan Vidar Krey 990fc31296 Added +myip command. 2009-03-08 17:11:10 +01:00
Jan Vidar Krey 6511761991 Fixed uptime output formatting to be less verbose. 2009-03-06 00:46:45 +01:00
Jan Vidar Krey c02c45f2d0 Escalate user_disconnect to an error in case of a "ghost login". I want to see them in logs. 2009-03-04 18:44:53 +01:00
Jan Vidar Krey d4c8b657bf Better "!stats"; can display peak and current bandwidth usage.
Network stats are now updated every minute, so that we have them handy for
printing in logs, or by issuing the !stats command.

Note: this checkin disables the once-per-hour stats logging.
I do not know wether or not that is useful functionality.
2009-03-04 18:36:45 +01:00
Jan Vidar Krey 8eb1726abb ChangeLog update. 2009-03-04 17:46:47 +01:00
Jan Vidar Krey bcbcf89e38 Use proper formatting for uptime command. 2009-03-04 14:49:33 +01:00
Jan Vidar Krey 26766d8332 Optimization: Removed unneeded strlen() calls several places. 2009-03-02 19:41:49 +01:00
Jan Vidar Krey ac56e7a5b9 First git commit. 2009-02-19 17:14:09 +01:00
201 changed files with 34866 additions and 405 deletions
+25
View File
@@ -0,0 +1,25 @@
*~
*.[oa]
*.lib
*.exe
*.manifest
*.gch
CMakeFiles/*
CMakeCache.txt
cmake_install.cmake
mod_*.dll
mod_*.exp
mod_*.so
uhub-admin
adcrush
uhub
build-stamp
debian/files
debian/uhub.debhelper.log
debian/uhub.postinst.debhelper
debian/uhub.postrm.debhelper
debian/uhub.prerm.debhelper
debian/uhub.substvars
uhub-passwd
src/version.h
src/system.h
+3
View File
@@ -0,0 +1,3 @@
[submodule "thirdparty/sqlite"]
path = thirdparty/sqlite
url = git://github.com/janvidar/sqlite.git
+11
View File
@@ -0,0 +1,11 @@
language: cpp
compiler:
- gcc
- clang
env:
- CONFIG=minimal
- CONFIG=full
install:
- autotest/travis/install-build-depends.sh
script:
- autotest/travis/build-and-test.sh
+11
View File
@@ -0,0 +1,11 @@
Authors of uhub
===============
Jan Vidar Krey, Design and implementation
E_zombie, Centos/RedHat customization scripts and heavy load testing
FleetCommand, Hub topic plugin code
MiMic, Implemented user commands, and plugins
Boris Pek (tehnick), Debian/Ubuntu packaging
Tillmann Karras (Tilka), Misc. bug fixes
Yoran Heling (Yorhel), TLS/SSL handshake detection bugfixes
Blair Bonnett, Misc. bug fixes
+1
View File
@@ -0,0 +1 @@
Bugs are tracked on: https://github.com/janvidar/uhub/issues
+251
View File
@@ -0,0 +1,251 @@
##
## Makefile for uhub
## Copyright (C) 2007-2019, Jan Vidar Krey <janvidar@extatic.org>
#
cmake_minimum_required (VERSION 2.8.2)
project (uhub NONE)
enable_language(C)
set (UHUB_VERSION_MAJOR 0)
set (UHUB_VERSION_MINOR 5)
set (UHUB_VERSION_PATCH 1)
set (PROJECT_SOURCE_DIR "${CMAKE_SOURCE_DIR}/src")
set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake/Modules)
option(RELEASE "Release build, debug build if disabled" ON)
option(LOWLEVEL_DEBUG, "Enable low level debug messages." OFF)
option(SSL_SUPPORT "Enable SSL support" ON)
option(USE_OPENSSL "Use OpenSSL's SSL support" ON )
option(SYSTEMD_SUPPORT "Enable systemd notify and journal logging" OFF)
option(ADC_STRESS "Enable the stress tester client" OFF)
find_package(Git)
find_package(Sqlite3)
include(TestBigEndian)
include(CheckSymbolExists)
include(CheckIncludeFile)
include(CheckTypeSize)
#Some functions need this to be found
add_definitions(-D_GNU_SOURCE)
set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D_GNU_SOURCE")
TEST_BIG_ENDIAN(BIGENDIAN)
if (BIGENDIAN)
add_definitions(-DARCH_BIGENDIAN)
endif()
if (NOT RELEASE)
add_definitions(-DDEBUG)
endif()
if (SSL_SUPPORT)
if (USE_OPENSSL)
find_package(OpenSSL)
else()
find_package(GnuTLS)
endif()
if (NOT GNUTLS_FOUND AND NOT OPENSSL_FOUND)
message(FATAL_ERROR "Neither OpenSSL nor GnuTLS were found!")
endif()
endif()
if (NOT SQLITE3_FOUND)
message(FATAL_ERROR "SQLite3 is not found!")
endif()
if (SYSTEMD_SUPPORT)
INCLUDE(FindPkgConfig)
pkg_search_module(SD REQUIRED libsystemd)
endif()
if (MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif()
check_include_file(stdint.h HAVE_STDINT_H)
check_include_file(sys/types.h HAVE_SYS_TYPES_H)
if (HAVE_SYS_TYPES_H)
set (CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES} "sys/types.h")
endif()
check_type_size( ssize_t SSIZE_T )
check_symbol_exists(memmem string.h HAVE_MEMMEM)
check_symbol_exists(strndup string.h HAVE_STRNDUP)
include_directories("${PROJECT_SOURCE_DIR}")
include_directories(${SQLITE3_INCLUDE_DIRS})
link_directories(${SQLITE3_LIBRARY_DIRS})
file (GLOB uhub_SOURCES ${PROJECT_SOURCE_DIR}/core/*.c)
list (REMOVE_ITEM uhub_SOURCES
${PROJECT_SOURCE_DIR}/core/gen_config.c
${PROJECT_SOURCE_DIR}/core/main.c
)
file (GLOB adc_SOURCES ${PROJECT_SOURCE_DIR}/adc/*.c)
file (GLOB network_SOURCES ${PROJECT_SOURCE_DIR}/network/*.c)
file (GLOB utils_SOURCES ${PROJECT_SOURCE_DIR}/util/*.c)
set (adcclient_SOURCES
${PROJECT_SOURCE_DIR}/tools/adcclient.c
${PROJECT_SOURCE_DIR}/core/ioqueue.c
)
add_library(adc STATIC ${adc_SOURCES})
add_library(network STATIC ${network_SOURCES})
add_library(utils STATIC ${utils_SOURCES})
if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
set_target_properties(utils PROPERTIES COMPILE_FLAGS -fPIC)
set_target_properties(network PROPERTIES COMPILE_FLAGS -fPIC)
endif()
add_dependencies(adc utils)
add_dependencies(network utils)
add_executable(uhub ${PROJECT_SOURCE_DIR}/core/main.c ${uhub_SOURCES} )
add_executable(autotest-bin ${CMAKE_SOURCE_DIR}/autotest/test.c ${uhub_SOURCES} )
add_executable(uhub-passwd ${PROJECT_SOURCE_DIR}/tools/uhub-passwd.c)
add_library(mod_example MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_example.c)
add_library(mod_welcome MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_welcome.c)
add_library(mod_logging MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_logging.c ${PROJECT_SOURCE_DIR}/adc/sid.c)
add_library(mod_auth_simple MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_auth_simple.c )
add_library(mod_chat_history MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_chat_history.c )
add_library(mod_chat_history_sqlite MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_chat_history_sqlite.c )
add_library(mod_chat_only MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_chat_only.c)
add_library(mod_topic MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_topic.c)
add_library(mod_no_guest_downloads MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_no_guest_downloads.c)
add_library(mod_auth_sqlite MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_auth_sqlite.c)
add_library(mod_require_tls MODULE ${PROJECT_SOURCE_DIR}/plugins/mod_require_tls.c)
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()
set_target_properties(
mod_example
mod_welcome
mod_logging
mod_auth_simple
mod_auth_sqlite
mod_chat_history
mod_chat_history_sqlite
mod_chat_only
mod_no_guest_downloads
mod_topic
mod_require_tls
PROPERTIES PREFIX "")
target_link_libraries(uhub ${CMAKE_DL_LIBS} adc network utils)
target_link_libraries(uhub-passwd ${SQLITE3_LIBRARIES} utils)
target_link_libraries(autotest-bin ${CMAKE_DL_LIBS} adc network utils)
target_link_libraries(mod_example utils)
target_link_libraries(mod_welcome utils)
target_link_libraries(mod_auth_simple utils)
target_link_libraries(mod_auth_sqlite ${SQLITE3_LIBRARIES} utils)
target_link_libraries(mod_chat_history utils)
target_link_libraries(mod_chat_history_sqlite ${SQLITE3_LIBRARIES} utils)
target_link_libraries(mod_no_guest_downloads utils)
target_link_libraries(mod_chat_only utils)
target_link_libraries(mod_logging utils)
target_link_libraries(mod_topic utils)
target_link_libraries(mod_require_tls utils)
target_link_libraries(utils network)
target_link_libraries(mod_welcome network)
target_link_libraries(mod_logging network)
if(UNIX)
add_library(adcclient STATIC ${adcclient_SOURCES})
add_executable(uhub-admin ${PROJECT_SOURCE_DIR}/tools/admin.c)
target_link_libraries(uhub-admin adcclient adc network utils pthread)
target_link_libraries(uhub pthread)
target_link_libraries(autotest-bin pthread)
if (ADC_STRESS)
add_executable(adcrush ${PROJECT_SOURCE_DIR}/tools/adcrush.c ${adcclient_SOURCES})
target_link_libraries(adcrush adcclient adc network utils pthread)
endif()
endif()
if (NOT UHUB_REVISION AND GIT_FOUND)
execute_process(COMMAND ${GIT_EXECUTABLE} show -s --pretty=format:%h
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
OUTPUT_VARIABLE UHUB_REVISION_TEMP
OUTPUT_STRIP_TRAILING_WHITESPACE)
if (UHUB_REVISION_TEMP)
set (UHUB_REVISION "git-${UHUB_REVISION_TEMP}")
endif()
endif()
if (NOT UHUB_REVISION)
set (UHUB_REVISION "release")
endif()
set (UHUB_GIT_VERSION "${UHUB_VERSION_MAJOR}.${UHUB_VERSION_MINOR}.${UHUB_VERSION_PATCH}-${UHUB_REVISION}")
message (STATUS "Configuring uhub version: ${UHUB_GIT_VERSION}")
if(OPENSSL_FOUND)
set(SSL_LIBS ${OPENSSL_LIBRARIES})
add_definitions(-DSSL_SUPPORT=1 -DSSL_USE_OPENSSL=1)
include_directories(${OPENSSL_INCLUDE_DIR})
endif()
if (GNUTLS_FOUND)
set(SSL_LIBS ${GNUTLS_LIBRARIES})
add_definitions(-DSSL_SUPPORT=1 -DSSL_USE_GNUTLS=1 ${GNUTLS_DEFINITIONS})
include_directories(${GNUTLS_INCLUDE_DIR})
endif()
if(SSL_SUPPORT)
target_link_libraries(uhub ${SSL_LIBS})
target_link_libraries(autotest-bin ${SSL_LIBS})
if(UNIX)
target_link_libraries(uhub-admin ${SSL_LIBS})
endif()
target_link_libraries(mod_welcome ${SSL_LIBS})
target_link_libraries(mod_logging ${SSL_LIBS})
if (ADC_STRESS)
target_link_libraries(adcrush ${SSL_LIBS})
endif()
endif()
if (SYSTEMD_SUPPORT)
target_link_libraries(uhub ${SD_LIBRARIES})
target_link_libraries(autotest-bin ${SD_LIBRARIES})
target_link_libraries(uhub-passwd ${SD_LIBRARIES})
target_link_libraries(uhub-admin ${SD_LIBRARIES})
include_directories(${SD_INCLUDE_DIRS})
add_definitions(-DSYSTEMD)
endif()
configure_file ("${PROJECT_SOURCE_DIR}/version.h.in" "${PROJECT_SOURCE_DIR}/version.h")
configure_file ("${PROJECT_SOURCE_DIR}/system.h.in" "${PROJECT_SOURCE_DIR}/system.h")
# mark_as_advanced(FORCE CMAKE_BUILD_TYPE)
# if (RELEASE)
# set(CMAKE_BUILD_TYPE Release)
# add_definitions(-DNDEBUG)
#else()
# set(CMAKE_BUILD_TYPE Debug)
# add_definitions(-DDEBUG)
#endif()
if (LOWLEVEL_DEBUG)
add_definitions(-DLOWLEVEL_DEBUG)
endif()
if (UNIX)
install( TARGETS uhub uhub-passwd RUNTIME DESTINATION bin )
install( TARGETS mod_example mod_welcome mod_logging mod_auth_simple mod_auth_sqlite mod_chat_history mod_chat_history_sqlite mod_chat_only mod_topic mod_no_guest_downloads DESTINATION /usr/lib/uhub/ OPTIONAL )
install( FILES ${CMAKE_SOURCE_DIR}/doc/uhub.conf ${CMAKE_SOURCE_DIR}/doc/plugins.conf ${CMAKE_SOURCE_DIR}/doc/rules.txt ${CMAKE_SOURCE_DIR}/doc/motd.txt DESTINATION /etc/uhub OPTIONAL )
endif()
+674
View File
@@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+25
View File
@@ -0,0 +1,25 @@
OpenSSL License Exception
-------------------------
Copyright (c) 2007-2012, Jan Vidar Krey
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License 3 (GPL) as published by
the Free Software Foundation.
The full text the GPL can be found in the COPYING file.
In addition this distribution of uhub may be linked against OpenSSL
according to the terms described here:
You have permission to copy, modify, propagate, and distribute a work
formed by combining OpenSSL with uhub, or a work derivative of such a
combination, even if such copying, modification, propagation, or
distribution would otherwise violate the terms of the GPL. You must
comply with the GPL in all respects for all of the code used other than
OpenSSL.
You may include this OpenSSL exception and its grant of permissions when
you distribute uhub. Inclusion of this notice with such a distribution
constitutes a grant of such permission. If you do not wish to grant these
permissions, delete this file.
+270
View File
@@ -0,0 +1,270 @@
0.5.0:
- Use TLS 1.2 and strong ciphers by default, but made this configurable.
- Fix TLS event handling which caused some busy loops
- TLS: Support certificate chains
- Fix bug #211: Better Hublist pinger support by adding the AP flag of the INF message.
- Fix bug #198: Timers could cause infinite loops
- Sqlite3 is now mandatory
- Added mod_chat_history_sqlite and mod_chat_is_privileged.
- Support for systemd notify and journal logging
- Improved flood control counting to strictly not allow more than the given amount of messages in the configured interval.
- Optimize lookups by CID and nick.
- Added an NMDC and ADC hub redirectors written in Python.
- Fix all Clang compile warnings.
- Install uhub-passwd also.
- Add support for detecting HTTP connections to the hub. Enough to tell browsers to stop calling.
- Compile fixes for OpenBSD, including warnings about strcat.
- Fix crashing autotest due to wrong initialization of the usermanager.
- mod_topic: check argument for NULL
- rename !cleartopic to !resettopic
0.4.1:
- Converted to CMake which replaces Visual Studio project files and GNU makefiles
- Fix issues with SSL causing excessive CPU usage.
- Fix TLS/SSL handshake detection issues
- Fixed crash in mod_chat_only.
- Implemented red-black tree for better performance for certain lookups.
- Better network statistics using the !stats command.
- Improved protocol parsing, especially escape handling.
- Fix cbuffer initialization.
- Install plugins in /usr/lib/uhub, not /var/lib/uhub.
- Improved init scripts and added a upstart script.
- Work-around client security bugs by disallowing UCMD messages from being relayed.
- Added asynchronous DNS resolver.
0.4.0:
- Cleaned up code generator for config file parsing.
- Merge pull request #5 from yorhel/master
- Print error message in case of shutting down due to errors loading plugins.
- Fix Windows file read discrepancy.
- convert_to_sqlite.pl: Update to the latest SQL schema + be more Perlish
- Fix VS2010 project file - missing .c file.
- Merge https://github.com/Tilka/uhub
- use "I64u" instead of PRIu64 on Windows
- remove obsolete settings in uhub.conf
- fix uhub_itoa() and uhub_ulltoa()
- marked plugin callbacks that are not called yet
- add on_change_nick() to struct plugin_funcs
- minimal changes
- Updated init script in debian package.
- Updated list of man pages in debian package.
- Added man page for uhub-passwd.
- Merge branch 'master' of https://github.com/Tilka/uhub
- Fix issue with QUI messages being allowed through the hub
- don't show error on SIGTERM in select() backend
- fix dependency of 'install' target
- changed all calls to assert() to uhub_assert()
- Don't strip the U4/U6 port numbers if updated after login.
- Fix compile issue with double typedefs.
- Remove list assertion when removing element that is not in the list. Breaks autotest.
- Cleaned up command handling code, by splitting into multiple files.
- Fix bug #183 - Added proper OpenSSL license exception for the GPL.
- OMG OPTIMIZED
- use dh_prep instead of dh_clean -k
- fix double free
- use "0" instead of "false"
- fix use of uninitialized struct ip_range
- fix random crashes upon !reload
- fix command syntax
- use arg parser in !broadcast
- Fixed tiny memory leak on reload/shutdown.
- Merge https://github.com/Tilka/uhub
- fix multiple optional arguments
- small cleanup
- also clean uhub-passwd
- ignore files generated by dpkg-buildpackage
- automatically clean up plugin commands
- minimal documentation fixes
- update client software link
- update compile howto link
- fix debian changelog
- Fix bug #158 - Added plugin for setting topic (hub description).
- Command arguments handling + cleanups
0.3.2:
- Fixed bugs in the kqueue network backend (OSX/BSD)
- Rewrote the configuration backend code.
- Added support for escaping characters in the configuration files.
- Updated the !broadcast command to send private messages instead of main chat messages.
- Adding support for redirecting clients to other hubs when they fail to log in.
- Fix some out of memory related crashes.
- Fixed minor memory leaks.
0.3.1:
- Fixed bug where !getip did not work.
- Added flood control configuration options.
- Added configuration options to disallow old/obsolete ADC clients.
- Fixed crash bugs, an freezes.
- SSL/TLS fix for tls_require configuration option.
- Fixed disconnect messages, so that clients can interpret them.
- Fixed bugs where share limits could be circumvented.
- Added support for listening to multiple ports.
- kqueue backend for Mac OS X, and BSD systems.
0.3.0:
- More user commands: ban, broadcast, mute, rules, history, myip, whoip, log
- Experimental SSL support
- Large rewrite of the network stack in order to support SSL.
- Added rule file for defining hub rules.
- Many crash fixes and other important bug fixes.
- Optimizations: O(1) timeout scheduler
- New sid allocation code.
- Added configurable server_listen_backlog (default 50).
- Added init.d scripts for RedHat/CentOS
0.2.8:
- Fix bug #13: getsockname() failure, use sockaddr from accept() instead.
- Fix bug #10: Improve logging, ensure logs are machine readable.
- Fix bug #12: asserts in adc_msg_parse -> enabled strict utf8 parsing.
0.2.7:
- Fixed a nasty crash (bug #11), Thanks Toast for finding it.
- Fix bug #9 - net_get_peer_address() failure on CentOS/Xen configurations.
- Write a log message if an operator reloads the config file.
- Don't print OK or ERROR when using '-s' or '-S' show the configuration.
- Cleanup credential string handling
- Made sure "!help" only display accessible commands.
- Cleanup in-hub command parsing
- Fix a possible crash if multiple INF messages are sent during login.
- Rewrote the mainloop to not use a timer.
0.2.6:
- Better "!uptime" command formatting.
- Better "!stats"; can display peak and current bandwidth usage.
- Added "+myip" command.
- Ensure super users and hub owners also have the operator flag set.
- Bug #1: Disconnecting users due to excessive "send queue".
- Bug #5: Always provide IP-address for all users, not just for active clients.
- Better send queue priorities.
- Dump configuration does not quote integer and boolean settings.
- Sources hosted by GitHub.com, and bug tracker on bugs.extatic.org
- Minor optimizations.
0.2.5-3487:
- Fixed out of memory situations, used when uhub operates on a limited heap.
- Code cleanups, reduced heap memory footprint.
- Fixed bug throwing users out due to exessive send queue when logging into a large hub.
- Added some simple hub commands (!stats, !uptime, !version, !help, etc).
0.2.4-3470:
- Added option chat_is_privileged, which makes chat for privileged users only.
- Started working on hub commands.
- Fixed a double free() related crash / abort.
- Fixed several send() -> EPIPE related crashes.
0.2.3-3429:
- Fixed one crash bug (jump to NULL).
- Fixed IPv6 dual stack issues on Winsock, but needs Vista or later to compile.
- Disable IPv6 if dual stack is not supported (WinXP with IPv6).
- Fixed bind issue for IPv4 addresses.
- Made sure no chat message could have PM context flag, unless set by the hub.
- Ignore empty INF update messages.
0.2.2-3393:
- Fixed a crash related to hub login.
- Added some fixes for older versions of libevent
- Added option to log messages through syslog.
- Added low bandwidth mode for really big hubs.
- Started writing a benchmark tool for the hub.
- Fix bug: reload configuration reset uptime.
- Experimental support for NetBSD 3.1.
0.2.1-3321:
- Added more robust configuration file parsing.
- Use defaults if config file is not found, unless a file is specified.
- Added user class super user (above operator, below admin).
- Added NAT override for clients behind the same NAT as the hub.
- Fixed a bug summarizing shared size and files for the PING extension.
- Fixed bugs related to hub limits.
0.2.0-3293:
- Fixed multiple crash bugs.
- Fully compatible with ADC/1.0.
- Protocol extensions: 'TIGR' and 'PING'
- Added support for configuring min/max share size, slots, concurrent hubs, not very well tested.
- Made all status message strings configurable.
- Various BSD issues fixed. Should perform equally well as Linux.
- Allow ignored configuration options (used when deprecating configuration options).
- Added command line options for checking configuration.
- A windows port is more or less done (MinGW)
- Lots of new auto tests added.
0.1.6-2608:
- Changes required for the ADC/0.14 specification.
- Stability fixes.
- Win32 fixes, it compiles and runs, but not quite ported yet.
- Added CMAKE files, which can be used instead of GNU make.
- Made sure all messages are terminated when created.
- Use length of messages, instead of strlen() to determine them.
- Added more asserts for messages. Spotted a few errors as a result of that.
- Added support for more sophisticated memory allocation debugging.
0.1.5-2462
- Fixed double free (crash).
- Fixed password challenge/response coding error (crash).
- Changes required for the new ADC/0.13 specification.
- Fixed IPv6 netmask matching (banning)
- Added UDP server, needed for auto-configure extension (AUT0)
- Send 'ping' messages periodically if nothing heard from clients.
- Print IP when client disconnects.
- Lots of automatic testcases added, fix many bugs in the process.
- GCC 2.95 compile fixes.
0.1.4-2301:
- uHub now requires and utilizes libevent. This allows for greater code
portability, and less code complexity.
- Various FreeBSD/OpenBSD/NetBSD fixes have been applied.
- Can now log files other than stderr.
- Added several automatic testcases.
- The application should now be much more stable, and never consume much CPU.
- Fixed several small annoying bugs.
0.1.3-2147:
- Changed license to GPL3
- Fixed several crashes
- Major code cleanups
- Refactored event handling
- Log file format change (minor)
- Automatic regression testing of code base (via exotic).
- Memory handling debug infrastructure.
0.1.2-2020:
- Fix infinite loops
- Don't log users leaving unless they are logged in.
- Fix private messages in chat only hubs.
- Operators/admins override chat only hub settings.
- Fix client/server protocol support negotiation handling
- IP banning should now work (IPv6 is not tested yet).
0.1.1-1956:
- Fixed memory leaks in ACL handling
- Prevent unneeded malloc's in command handling when buffers are big enough.
- Code cleanups and more doxygen style comments added.
- Fixed crashes and infinite loops
- FreeBSD compile fixes
- Timestamp log messages.
- Log network/bandwidth statistics
0.1.0-1840:
- First public release
+8
View File
@@ -0,0 +1,8 @@
Welcome and thanks for downloading uHub, a high performance ADC p2p hub.
For the official documentation, bugs and other information, please visit:
http://www.uhub.org/
For a list of compatible ADC clients, see:
http://en.wikipedia.org/wiki/Advanced_Direct_Connect#Client_software
View File
+140
View File
@@ -0,0 +1,140 @@
HOST_SYSTEM=`uname -s | tr [:upper:] [:lower:] | sed s/darwin/macosx/`
if [ "${HOST_SYSTEM}" = "macosx" ]; then
HOST_MACHINE=`uname -p | tr [:upper:] [:lower:]`
else
HOST_MACHINE=`uname -m | tr [:upper:] [:lower:] | sed s/i686/i386/ | sed s/x86_64/amd64/ | sed s/ppc64/powerpc/`
fi
BINSUFFIX=
MAKEARGS=
MAKE=make
WANTZIP=0
if [ "${HOST_SYSTEM}" = "mingw32_nt-5.1" ]; then
HOST_SYSTEM=win32
BINSUFFIX=.exe
WANTZIP=1
MAKEARGS="USE_BIGENDIAN=NO"
fi
BINARY=uhub${BINSUFFIX}
if [ "${HOST_SYSTEM}" = "freebsd" ]; then
MAKE=gmake
fi
VERSION=`grep define\ VERSION version.h | cut -f 3 -d " " | tr -d [=\"=]`
SNAPSHOT=`date '+%Y%m%d'`
PACKAGE=uhub-${VERSION}
PACKAGE_SRC=${PACKAGE}-src
PACKAGE_BIN=${PACKAGE}-${HOST_SYSTEM}-${HOST_MACHINE}
ARCHIVE='build-archive:~/www/downloads/uhub/'
function export_source_directory
{
if [ -d ${PACKAGE} ]; then
rm -Rf ${PACKAGE};
fi
if [ ! -d .git ]; then
echo "No git repo found in `dirname $0`"
exit 1
fi
git archive --format=tar --prefix=${PACKAGE}/ HEAD > tmp.tar && tar -xf tmp.tar && rm tmp.tar
if [ ! -d ${PACKAGE} ]; then
echo "Something went wrong while exporting the repo."
exit 1
fi
}
function package_zips
{
tar cf $1.tar $2
gzip -c -9 $1.tar > $1.tar.gz
bzip2 -c -9 $1.tar > $1.tar.bz2
rm -f $1.tar
if [ $WANTZIP -eq 1 ]; then
zip -q -9 -r $1.zip $2
fi
}
function export_sources
{
if [ ! -d ${PACKAGE} ]; then
export_source_directory
fi
cd ${PACKAGE}
${MAKE} ${MAKEARGS} autotest.c
cd ..
if [ ! -f ${PACKAGE}/autotest.c ]; then
echo "Unable to create autotest.c, aborting..."
exit 1
fi
rm -Rf ${PACKAGE}/admin
package_zips ${PACKAGE_SRC} ${PACKAGE}
rm -Rf ${PACKAGE};
cp ChangeLog ChangeLog-${VERSION}
}
function build_binaries
{
if [ ! -d ${PACKAGE} ]; then
export_source_directory
fi
cd ${PACKAGE}
${MAKE} ${MAKEARGS} RELEASE=YES
cd ..
if [ ! -x ${PACKAGE}/${BINARY} ]; then
echo "Build failed, no binary found..."
exit 1
fi
}
function export_binaries
{
build_binaries
rm -Rf ${PACKAGE}/admin
rm -Rf ${PACKAGE}/autotest
rm -Rf ${PACKAGE}/src
rm -Rf ${PACKAGE}/debian
rm -f ${PACKAGE}/autotest.c
rm -f ${PACKAGE}/*akefile
rm -f ${PACKAGE}/version.h
rm -f ${PACKAGE}/doc/Doxyfile
rm -f ${PACKAGE}/doc/uhub.dot
rm -f ${PACKAGE}/libuhub*
package_zips ${PACKAGE_BIN} ${PACKAGE}
rm -Rf ${PACKAGE}
}
function upload_pkg
{
if [ -f $1 ]; then
scp $1 ${ARCHIVE}
fi
}
function upload_packages
{
upload_pkg ${PACKAGE_SRC}.tar.gz
upload_pkg ${PACKAGE_SRC}.tar.bz2
upload_pkg ${PACKAGE_SRC}.zip
upload_pkg ChangeLog-${VERSION}
upload_pkg ${PACKAGE_BIN}.tar.gz
upload_pkg ${PACKAGE_BIN}.tar.bz2
upload_pkg ${PACKAGE_BIN}.zip
}
+3
View File
@@ -0,0 +1,3 @@
#!/bin/bash
. admin/common.sh
export_source_directory
+95
View File
@@ -0,0 +1,95 @@
#!/bin/sh
. admin/common.sh
export_source_directory
build_binaries
DEB_REVISION=1
if [ -d deb ]; then
rm -Rf deb
fi
mkdir -p \
deb/DEBIAN \
deb/usr/bin \
deb/usr/share/man/man1/ \
deb/usr/share/doc/uhub \
deb/etc/uhub \
|| exit 1
find deb -type d | xargs chmod 755
# Copy binaries...
cp ${PACKAGE}/${BINARY} deb/usr/bin
strip deb/usr/bin/${BINARY}
# Copy configuration files...
cp ${PACKAGE}/doc/uhub.conf deb/etc/uhub
cp ${PACKAGE}/doc/users.conf deb/etc/uhub
echo "Welcome to uHub" > deb/etc/uhub/motd.txt
# Copy other files
cp ${PACKAGE}/README deb/usr/share/doc/uhub
cp ${PACKAGE}/AUTHORS deb/usr/share/doc/uhub
gzip -c --best < ${PACKAGE}/ChangeLog > deb/usr/share/doc/uhub/changelog.gz
gzip -c --best < ${PACKAGE}/doc/uhub.1 > deb/usr/share/man/man1/uhub.1.gz
cat > deb/usr/share/doc/uhub/copyright <<EOF
uHub - a high performance hub for the ADC peer-to-peer network
Copyright (C) 2007-2009 Jan Vidar Krey <janvidar@extatic.org>
uHub is free and open source software, licensed under the
GNU General Public License version 3.
For details, see /usr/share/common-licenses/GPL-3
EOF
gzip -c --best > deb/usr/share/doc/uhub/changelog.Debian.gz <<EOF
uhub (${VERSION}) stable; urgency=low
* See changelog.gz for details.
-- Jan Vidar Krey <janvidar@extatic.org> `date -R`
EOF
### Write control files
cd deb
echo "/etc/uhub/uhub.conf" > DEBIAN/conffiles
echo "/etc/uhub/users.conf" >> DEBIAN/conffiles
echo "/etc/uhub/motd.txt" >> DEBIAN/conffiles
md5sum `find usr -type f` > DEBIAN/md5sums
INSTALL_SIZE=`du -s | cut -f 1`
cat > DEBIAN/control <<EOF
Package: uhub
Version: ${VERSION}-${DEB_REVISION}
Architecture: ${HOST_MACHINE}
Maintainer: Jan Vidar Krey <janvidar@extatic.org>
Installed-Size: ${INSTALL_SIZE}
Depends: libc6 (>= 2.7-1), libevent1 (>= 1.3e-1)
Section: net
Priority: optional
Description: a high performance hub for the ADC peer-to-peer network
uHub is a high performance peer-to-peer hub for the ADC network.
Its low memory footprint allows it to handle several thousand users
on high-end servers, or a small private hub on embedded hardware.
.
Homepage: http://www.extatic.org/uhub/
EOF
cd ..
### Create deb file
fakeroot dpkg-deb --build deb
mv deb.deb uhub_${VERSION}-${DEB_REVISION}_${HOST_MACHINE}.deb
### Check for errors
lintian uhub_${VERSION}-${DEB_REVISION}_${HOST_MACHINE}.deb
### Cleanup
rm -Rf deb
rm -Rf ${PACKAGE}
+3
View File
@@ -0,0 +1,3 @@
#!/bin/bash
. admin/common.sh
export_binaries
+4
View File
@@ -0,0 +1,4 @@
#!/bin/bash
. admin/common.sh
WANTZIP=1
export_sources
+26
View File
@@ -0,0 +1,26 @@
#!/bin/bash
PUB="${HOME}/.ssh/id_rsa.pub"
CFG="${HOME}/.ssh/config"
if [ ! "`grep build-archive ${CFG}`" ]; then
echo "Updating ssh config (${CFG})..."
cat >> ${CFG} <<EOF
Host build-archive
ForwardX11 no
HostName login.domeneshop.no
User extatic
EOF
else
echo "ssh config seems OK (${CFG})"
fi
if [ ! -f ${PUB} ]; then
echo "No id_rsa.pub - run ssh-keygen"
exit 1
fi
echo "Copying public key (${PUB})..."
cat ${PUB} | ssh build-archive "cat >> .ssh/authorized_keys"
+3
View File
@@ -0,0 +1,3 @@
#!/bin/bash
. admin/common.sh
upload_packages
+372
View File
@@ -0,0 +1,372 @@
#!/usr/bin/perl -w
# exotic 0.4
# Copyright (c) 2007-2012, Jan Vidar Krey
use strict;
my $program = $0;
my $file;
my $line;
my @tests;
my $found;
my $test;
my @files;
if ($#ARGV == -1)
{
die "Usage: $program files\n";
}
my $version = "0.4";
foreach my $arg (@ARGV)
{
push(@files, $arg);
}
print "/* THIS FILE IS AUTOMATICALLY GENERATED BY EXOTIC - DO NOT EDIT THIS FILE! */\n";
print "/* exotic/$version (Mon Nov 7 11:15:31 CET 2011) */\n\n";
print "#define __EXOTIC__STANDALONE__\n";
standalone_include_exotic_h();
if ($#ARGV >= 0)
{
foreach $file (@ARGV)
{
$found = 0;
open( FILE, "$file") || next;
my @data = <FILE>;
my $comment = 0;
foreach $line (@data) {
chomp($line);
if ($comment == 1)
{
if ($line =~ /^(.*\*\/)(.*)/)
{
$line = $2;
$comment = 0;
}
else
{
next; # ignore comment data
}
}
if ($line =~ /^(.*)\/\*(.*)\*\/(.*)$/)
{
$line = $1 . " " . $3; # exclude comment stuff in between "/*" and "*/".
}
if ($line =~ /^(.*)(\/\/.*)$/) {
$line = $1; # exclude stuff after "//" (FIXME: does not work if they are inside a string)
}
if ($line =~ /\/\*/) {
$comment = 1;
next;
}
if ($line =~ /^\s*EXO_TEST\(\s*(\w+)\s*,/)
{
$found++;
push(@tests, $1);
}
}
if ($found > 0) {
print "#include \"" . $file . "\"\n";
}
close(FILE);
}
print "\n";
}
# Write a main() that will start the test run
print "int main(int argc, char** argv)\n{\n";
print "\tstruct exotic_handle handle;\n\n";
print "\tif (exotic_initialize(&handle, argc, argv) == -1)\n\t\treturn -1;\n\n";
if ($#tests > 0)
{
print "\t/* Register the tests to be run */\n";
foreach $test (@tests)
{
print "\texotic_add_test(&handle, &exotic_test_" . $test . ", \"" . $test . "\");\n";
}
}
else
{
print "\t/* No tests are found! */\n";
}
print "\n";
print "\treturn exotic_run(&handle);\n";
print "}\n\n";
standalone_include_exotic_c();
sub standalone_include_exotic_h {
print '
/*
* Exotic (EXtatic.Org Test InfrastuCture)
* Copyright (c) 2007, Jan Vidar Krey
*/
#ifndef EXO_TEST
#define EXO_TEST(NAME, block) int exotic_test_ ## NAME (void) block
#endif
#ifndef HAVE_EXOTIC_AUTOTEST_H
#define HAVE_EXOTIC_AUTOTEST_H
#ifdef __cplusplus
extern "C" {
#endif
typedef int(*exo_test_t)();
enum exo_toggle { cfg_default, cfg_off, cfg_on };
struct exotic_handle
{
enum exo_toggle config_show_summary;
enum exo_toggle config_show_pass;
enum exo_toggle config_show_fail;
unsigned int fail;
unsigned int pass;
struct exo_test_data* first;
struct exo_test_data* current;
};
extern int exotic_initialize(struct exotic_handle* handle, int argc, char** argv);
extern void exotic_add_test(struct exotic_handle* handle, exo_test_t, const char* name);
extern int exotic_run(struct exotic_handle* handle);
#ifdef __cplusplus
}
#endif
#endif /* HAVE_EXOTIC_AUTOTEST_H */
'; }
sub standalone_include_exotic_c {
print '
/*
* Exotic - C/C++ source code testing
* Copyright (c) 2007, Jan Vidar Krey
*/
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void exotic_version();
#ifndef __EXOTIC__STANDALONE__
#include "autotest.h"
static void exotic_version()
{
printf("Extatic.org Test Infrastructure: exotic " "${version}" "\n\n");
printf("Copyright (C) 2007 Jan Vidar Krey, janvidar@extatic.org\n");
printf("This is free software with ABSOLUTELY NO WARRANTY.\n\n");
}
#endif
struct exo_test_data
{
exo_test_t test;
char* name;
struct exo_test_data* next;
};
static void exotic_summary(struct exotic_handle* handle)
{
int total = handle->pass + handle->fail;
int pass_rate = total ? (100*handle->pass / total) : 0;
int fail_rate = total ? (100*handle->fail / total) : 0;
printf("\n");
printf("--------------------------------------------\n");
printf("Results:\n");
printf(" * Total tests run: %8d\n", total);
printf(" * Tests passed: %8d (~%d%%)\n", (int) handle->pass, pass_rate);
printf(" * Tests failed: %8d (~%d%%)\n", (int) handle->fail, fail_rate);
printf("--------------------------------------------\n");
}
static void exotic_help(const char* program)
{
printf("Usage: %s [OPTIONS]\n\n", program);
printf("Options:\n");
printf(" --help -h Show this message\n");
printf(" --version -v Show version\n");
printf(" --summary -s show only summary)\n");
printf(" --fail -f show only test failures\n");
printf(" --pass -p show only test passes\n");
printf("\nExamples:\n");
printf(" %s -s -f\n\n", program);
}
int exotic_initialize(struct exotic_handle* handle, int argc, char** argv)
{
int n;
if (!handle || !argv) return -1;
memset(handle, 0, sizeof(struct exotic_handle));
for (n = 1; n < argc; n++)
{
if (!strcmp(argv[n], "-h") || !strcmp(argv[n], "--help"))
{
exotic_help(argv[0]);
exit(0);
}
if (!strcmp(argv[n], "-v") || !strcmp(argv[n], "--version"))
{
exotic_version();
exit(0);
}
if (!strcmp(argv[n], "-s") || !strcmp(argv[n], "--summary"))
{
handle->config_show_summary = cfg_on;
continue;
}
if (!strcmp(argv[n], "-f") || !strcmp(argv[n], "--fail"))
{
handle->config_show_fail = cfg_on;
continue;
}
if (!strcmp(argv[n], "-p") || !strcmp(argv[n], "--pass"))
{
handle->config_show_pass = cfg_on;
continue;
}
fprintf(stderr, "Unknown argument: %s\n\n", argv[n]);
exotic_help(argv[0]);
exit(0);
}
if (handle->config_show_summary == cfg_on)
{
if (handle->config_show_pass == cfg_default) handle->config_show_pass = cfg_off;
if (handle->config_show_fail == cfg_default) handle->config_show_fail = cfg_off;
}
else if (handle->config_show_pass == cfg_on)
{
if (handle->config_show_summary == cfg_default) handle->config_show_summary = cfg_off;
if (handle->config_show_fail == cfg_default) handle->config_show_fail = cfg_off;
}
else if (handle->config_show_fail == cfg_on)
{
if (handle->config_show_summary == cfg_default) handle->config_show_summary = cfg_off;
if (handle->config_show_fail == cfg_default) handle->config_show_fail = cfg_off;
}
else
{
if (handle->config_show_summary == cfg_default) handle->config_show_summary = cfg_on;
if (handle->config_show_fail == cfg_default) handle->config_show_fail = cfg_on;
if (handle->config_show_pass == cfg_default) handle->config_show_pass = cfg_on;
}
return 0;
}
void exotic_add_test(struct exotic_handle* handle, exo_test_t func, const char* name)
{
struct exo_test_data* test;
if (!handle)
{
fprintf(stderr, "exotic_add_test: failed, no handle!\n");
exit(-1);
}
test = (struct exo_test_data*) malloc(sizeof(struct exo_test_data));
if (!test)
{
fprintf(stderr, "exotic_add_test: out of memory!\n");
exit(-1);
}
/* Create the test */
memset(test, 0, sizeof(struct exo_test_data));
test->test = func;
test->name = strdup(name);
/* Register the test in the handle */
if (!handle->first)
{
handle->first = test;
handle->current = test;
}
else
{
handle->current->next = test;
handle->current = test;
}
}
int exotic_run(struct exotic_handle* handle)
{
struct exo_test_data* tmp = NULL;
if (!handle)
{
fprintf(stderr, "Error: exotic is not initialized\n");
return -1;
}
handle->current = handle->first;
while (handle->current)
{
tmp = handle->current;
if (handle->current->test()) {
if (handle->config_show_pass == cfg_on) printf("* PASS test \'%s\'\n", tmp->name);
handle->pass++;
} else {
if (handle->config_show_fail == cfg_on) printf("* FAIL test \'%s\'\n", tmp->name);
handle->fail++;
}
handle->current = handle->current->next;
free(tmp->name);
free(tmp);
}
if (!handle->first)
{
printf("(No tests added)\n");
}
if (handle->config_show_summary == cfg_on)
exotic_summary(handle);
return (handle->fail) ? handle->fail : 0;
}
static void exotic_version() {
printf("exotic 0.4-standalone\n\n");
printf("Copyright (C) 2007 Jan Vidar Krey, janvidar@extatic.org\n");
printf("This is free software with ABSOLUTELY NO WARRANTY.\n\n");
}
'; }
+1070
View File
File diff suppressed because it is too large Load Diff
+251
View File
@@ -0,0 +1,251 @@
#include <uhub.h>
static struct hub_info* hub = NULL;
static struct hub_command* cmd = NULL;
static struct hub_user user;
static struct command_base* cbase = NULL;
static struct command_handle* c_test1 = NULL;
static struct command_handle* c_test2 = NULL;
static struct command_handle* c_test3 = NULL;
static struct command_handle* c_test4 = NULL;
static struct command_handle* c_test5 = NULL;
static struct command_handle* c_test6 = NULL;
static struct command_handle* c_test7 = NULL;
// for results:
static int result = 0;
EXO_TEST(setup, {
hub = hub_malloc_zero(sizeof(struct hub_info));
cbase = command_initialize(hub);
hub->commands = cbase;
hub->users = uman_init();
return cbase && hub && hub->users;
});
static int test_handler(struct command_base* cbase, struct hub_user* user, struct hub_command* hcmd)
{
printf("test_handler\n");
result = 1;
return 0;
}
static struct command_handle* create_handler(const char* prefix, const char* args, enum auth_credentials cred)
{
struct command_handle* c = hub_malloc_zero(sizeof(struct command_handle));
c->prefix = prefix;
c->length = strlen(prefix);
c->args = args;
c->cred = cred;
c->handler = test_handler;
c->description = "A handler added by autotest.";
c->origin = "exotic test";
c->ptr = &c->ptr;
return c;
}
EXO_TEST(command_setup_user, {
memset(&user, 0, sizeof(user));
user.id.sid = 1;
strcpy(user.id.nick, "tester");
strcpy(user.id.cid, "3AGHMAASJA2RFNM22AA6753V7B7DYEPNTIWHBAY");
user.credentials = auth_cred_guest;
return 1;
});
#define ADD_TEST(var, prefix, args, cred) \
var = create_handler(prefix, args, cred); \
if (!command_add(cbase, var, NULL)) \
return 0;
#define DEL_TEST(var) \
if (var) \
{ \
if (!command_del(cbase, var)) \
return 0; \
hub_free(var); \
var = NULL; \
}
EXO_TEST(command_create, {
ADD_TEST(c_test1, "test1", "", auth_cred_guest);
ADD_TEST(c_test2, "test2", "", auth_cred_operator);
ADD_TEST(c_test3, "test3", "N?N?N", auth_cred_guest);
ADD_TEST(c_test4, "test4", "u", auth_cred_guest);
ADD_TEST(c_test5, "test5", "i", auth_cred_guest);
ADD_TEST(c_test6, "test6", "?c", auth_cred_guest);
ADD_TEST(c_test6, "test7", "C", auth_cred_guest);
return 1;
});
extern void command_destroy(struct hub_command* cmd);
static int verify(const char* str, enum command_parse_status expected)
{
struct hub_command* cmd = command_parse(cbase, hub, &user, str);
enum command_parse_status status = cmd->status;
command_free(cmd);
return status == expected;
}
static struct hub_command_arg_data* verify_argument(struct hub_command* cmd, enum hub_command_arg_type type)
{
return hub_command_arg_next(cmd, type);
}
static int verify_arg_integer(struct hub_command* cmd, int expected)
{
struct hub_command_arg_data* data = verify_argument(cmd, type_integer);
return data->data.integer == expected;
}
static int verify_arg_user(struct hub_command* cmd, struct hub_user* expected)
{
struct hub_command_arg_data* data = verify_argument(cmd, type_user);
return data->data.user == expected;
}
static int verify_arg_cred(struct hub_command* cmd, enum auth_credentials cred)
{
struct hub_command_arg_data* data = verify_argument(cmd, type_credentials);
return data->data.credentials == cred;
}
EXO_TEST(command_access_1, { return verify("!test1", cmd_status_ok); });
EXO_TEST(command_access_2, { return verify("!test2", cmd_status_access_error); });
EXO_TEST(command_access_3, { user.credentials = auth_cred_operator; return verify("!test2", cmd_status_ok); });
EXO_TEST(command_syntax_1, { return verify("", cmd_status_syntax_error); });
EXO_TEST(command_syntax_2, { return verify("!", cmd_status_syntax_error); });
EXO_TEST(command_missing_args_1, { return verify("!test3", cmd_status_missing_args); });
EXO_TEST(command_missing_args_2, { return verify("!test3 12345", cmd_status_ok); });
EXO_TEST(command_missing_args_3, { return verify("!test3 1 2 345", cmd_status_ok); });
EXO_TEST(command_number_1, { return verify("!test3 abc", cmd_status_arg_number); });
EXO_TEST(command_number_2, { return verify("!test3 -", cmd_status_arg_number); });
EXO_TEST(command_number_3, { return verify("!test3 -12", cmd_status_ok); });
EXO_TEST(command_user_1, { return verify("!test4 tester", cmd_status_arg_nick); });
EXO_TEST(command_user_2, { return verify("!test5 3AGHMAASJA2RFNM22AA6753V7B7DYEPNTIWHBAY", cmd_status_arg_cid); });
EXO_TEST(command_user_3, { return uman_add(hub->users, &user) == 0; });
EXO_TEST(command_user_4, { return verify("!test4 tester", cmd_status_ok); });
EXO_TEST(command_user_5, { return verify("!test5 3AGHMAASJA2RFNM22AA6753V7B7DYEPNTIWHBAY", cmd_status_ok); });
EXO_TEST(command_command_1, { return verify("!test6 test1", cmd_status_ok); });
EXO_TEST(command_command_2, { return verify("!test6 test2", cmd_status_ok); });
EXO_TEST(command_command_3, { return verify("!test6 test3", cmd_status_ok); });
EXO_TEST(command_command_4, { return verify("!test6 test4", cmd_status_ok); });
EXO_TEST(command_command_5, { return verify("!test6 test5", cmd_status_ok); });
EXO_TEST(command_command_6, { return verify("!test6 test6", cmd_status_ok); });
EXO_TEST(command_command_7, { return verify("!test6 fail", cmd_status_arg_command); });
EXO_TEST(command_command_8, { return verify("!test6", cmd_status_ok); });
EXO_TEST(command_cred_1, { return verify("!test7 guest", cmd_status_ok); });
EXO_TEST(command_cred_2, { return verify("!test7 user", cmd_status_ok); });
EXO_TEST(command_cred_3, { return verify("!test7 operator", cmd_status_ok); });
EXO_TEST(command_cred_4, { return verify("!test7 super", cmd_status_ok); });
EXO_TEST(command_cred_5, { return verify("!test7 admin", cmd_status_ok); });
EXO_TEST(command_cred_6, { return verify("!test7 nobody", cmd_status_arg_cred); });
EXO_TEST(command_cred_7, { return verify("!test7 bot", cmd_status_ok); });
EXO_TEST(command_cred_8, { return verify("!test7 link", cmd_status_ok); });
#if 0
cmd_status_arg_cred, /** <<< "A credentials argument is not valid ('C')" */
};
#endif
// command not found
EXO_TEST(command_parse_3, { return verify("!fail", cmd_status_not_found); });
// built-in command
EXO_TEST(command_parse_4, { return verify("!help", cmd_status_ok); });
#define SETUP_COMMAND(string) \
do { \
if (cmd) command_free(cmd); \
cmd = command_parse(cbase, hub, &user, string); \
} while(0)
EXO_TEST(command_argument_integer_1, {
SETUP_COMMAND("!test3");
return verify_argument(cmd, type_integer) == NULL;
});
EXO_TEST(command_argument_integer_2, {
SETUP_COMMAND("!test3 10 42");
return verify_arg_integer(cmd, 10) && verify_arg_integer(cmd, 42) && verify_argument(cmd, type_integer) == NULL;
});
EXO_TEST(command_argument_integer_3, {
SETUP_COMMAND("!test3 10 42 6784");
return verify_arg_integer(cmd, 10) && verify_arg_integer(cmd, 42) && verify_arg_integer(cmd, 6784);
});
EXO_TEST(command_argument_user_1, {
SETUP_COMMAND("!test4 tester");
return verify_arg_user(cmd, &user) ;
});
EXO_TEST(command_argument_cid_1, {
SETUP_COMMAND("!test5 3AGHMAASJA2RFNM22AA6753V7B7DYEPNTIWHBAY");
return verify_arg_user(cmd, &user) ;
});
EXO_TEST(command_argument_cred_1, {
SETUP_COMMAND("!test7 admin");
return verify_arg_cred(cmd, auth_cred_admin);;
});
EXO_TEST(command_argument_cred_2, {
SETUP_COMMAND("!test7 op");
return verify_arg_cred(cmd, auth_cred_operator);;
});
EXO_TEST(command_argument_cred_3, {
SETUP_COMMAND("!test7 operator");
return verify_arg_cred(cmd, auth_cred_operator);
});
EXO_TEST(command_argument_cred_4, {
SETUP_COMMAND("!test7 super");
return verify_arg_cred(cmd, auth_cred_super);
});
EXO_TEST(command_argument_cred_5, {
SETUP_COMMAND("!test7 guest");
return verify_arg_cred(cmd, auth_cred_guest);
});
EXO_TEST(command_argument_cred_6, {
SETUP_COMMAND("!test7 user");
return verify_arg_cred(cmd, auth_cred_user);
});
#undef SETUP_COMMAND
EXO_TEST(command_user_destroy, { return uman_remove(hub->users, &user) == 0; });
EXO_TEST(command_destroy, {
command_free(cmd);
cmd = NULL;
DEL_TEST(c_test1);
DEL_TEST(c_test2);
DEL_TEST(c_test3);
DEL_TEST(c_test4);
DEL_TEST(c_test5);
DEL_TEST(c_test6);
DEL_TEST(c_test7);
return 1;
});
EXO_TEST(cleanup, {
uman_shutdown(hub->users);
command_shutdown(hub->commands);
hub_free(hub);
return 1;
});
+24
View File
@@ -0,0 +1,24 @@
#include <uhub.h>
EXO_TEST(cred_to_string_1, { return !strcmp(auth_cred_to_string(auth_cred_none), "none"); });
EXO_TEST(cred_to_string_2, { return !strcmp(auth_cred_to_string(auth_cred_bot), "bot"); });
EXO_TEST(cred_to_string_3, { return !strcmp(auth_cred_to_string(auth_cred_guest), "guest"); });
EXO_TEST(cred_to_string_4, { return !strcmp(auth_cred_to_string(auth_cred_user), "user"); });
EXO_TEST(cred_to_string_5, { return !strcmp(auth_cred_to_string(auth_cred_operator), "operator"); });
EXO_TEST(cred_to_string_6, { return !strcmp(auth_cred_to_string(auth_cred_super), "super"); });
EXO_TEST(cred_to_string_7, { return !strcmp(auth_cred_to_string(auth_cred_link), "link"); });
EXO_TEST(cred_to_string_8, { return !strcmp(auth_cred_to_string(auth_cred_admin), "admin"); });
#define CRED_FROM_STRING(STR, EXPECT) enum auth_credentials cred; return auth_string_to_cred(STR, &cred) && cred == EXPECT;
EXO_TEST(cred_from_string_1, { CRED_FROM_STRING("none", auth_cred_none); });
EXO_TEST(cred_from_string_2, { CRED_FROM_STRING("bot", auth_cred_bot); });
EXO_TEST(cred_from_string_3, { CRED_FROM_STRING("guest", auth_cred_guest); });
EXO_TEST(cred_from_string_4, { CRED_FROM_STRING("user", auth_cred_user); });
EXO_TEST(cred_from_string_5, { CRED_FROM_STRING("reg", auth_cred_user); });
EXO_TEST(cred_from_string_6, { CRED_FROM_STRING("operator", auth_cred_operator); });
EXO_TEST(cred_from_string_7, { CRED_FROM_STRING("op", auth_cred_operator); });
EXO_TEST(cred_from_string_8, { CRED_FROM_STRING("super", auth_cred_super); });
EXO_TEST(cred_from_string_9, { CRED_FROM_STRING("link", auth_cred_link); });
EXO_TEST(cred_from_string_10, { CRED_FROM_STRING("admin", auth_cred_admin); });
+85
View File
@@ -0,0 +1,85 @@
#include <uhub.h>
static struct event_queue* eq;
static int eq_val;
static void eq_callback(void* callback_data, struct event_data* event_data)
{
eq_val += event_data->id;
}
EXO_TEST(eventqueue_init_1, {
eq = 0;
eq_val = 0;
return event_queue_initialize(&eq, eq_callback, &eq_val) == 0 && event_queue_size(eq) == 0;
});
EXO_TEST(eventqueue_init_2, {
/* hack */
return eq->callback_data == &eq_val && eq->callback == eq_callback && eq->q1 && eq->q2 && !eq->locked;
});
EXO_TEST(eventqueue_post_1, {
struct event_data message;
message.id = 0x1001;
message.ptr = &message;
message.flags = message.id * 2;
event_queue_post(eq, &message);
return event_queue_size(eq) == 1;
});
EXO_TEST(eventqueue_process_1, {
event_queue_process(eq);
return eq_val == 0x1001;
});
EXO_TEST(eventqueue_size_1, {
eq_val = 0;
return event_queue_size(eq) == 0;
});
EXO_TEST(eventqueue_post_2, {
struct event_data message;
message.id = 0x1002;
message.ptr = &message;
message.flags = message.id * 2;
event_queue_post(eq, &message);
return event_queue_size(eq) == 1;
});
EXO_TEST(eventqueue_size_2, {
eq_val = 0;
return event_queue_size(eq) == 1;
});
EXO_TEST(eventqueue_post_3, {
struct event_data message;
message.id = 0x1003;
message.ptr = &message;
message.flags = message.id * 2;
event_queue_post(eq, &message);
return event_queue_size(eq) == 2;
});
EXO_TEST(eventqueue_size_3, {
eq_val = 0;
return event_queue_size(eq) == 2;
});
EXO_TEST(eventqueue_process_2, {
event_queue_process(eq);
return eq_val == 0x2005;
});
EXO_TEST(eventqueue_size_4, {
eq_val = 0;
return event_queue_size(eq) == 0;
});
EXO_TEST(eventqueue_shutdown_1, {
event_queue_shutdown(eq);
return 1;
});
+72
View File
@@ -0,0 +1,72 @@
#include <uhub.h>
static struct hub_config g_config;
static struct acl_handle g_acl;
static struct hub_info* g_hub;
/*
static void create_test_user()
{
if (g_user)
return;
g_user = (struct hub_user*) malloc(sizeof(struct hub_user));
memset(g_user, 0, sizeof(struct hub_user));
memcpy(g_user->id.nick, "exotic-tester", 13);
g_user->sid = 1;
}
*/
EXO_TEST(hub_net_startup, {
return (net_initialize() != -1);
});
EXO_TEST(hub_config_initialize, {
config_defaults(&g_config);
g_config.server_port = 65111;
return 1;
});
EXO_TEST(hub_acl_initialize, {
return (acl_initialize(&g_config, &g_acl) != -1);
});
EXO_TEST(hub_service_initialize, {
g_hub = hub_start_service(&g_config);
return g_hub ? 1 : 0;
});
EXO_TEST(hub_variables_startup, {
hub_set_variables(g_hub, &g_acl);
return 1;
});
/*** HUB IS OPERATIONAL HERE! ***/
EXO_TEST(hub_variables_shutdown, {
hub_free_variables(g_hub);
return 1;
});
EXO_TEST(hub_acl_shutdown, {
acl_shutdown(&g_acl);
return 1;
});
EXO_TEST(hub_config_shutdown, {
free_config(&g_config);
return 1;
});
EXO_TEST(hub_service_shutdown, {
if (g_hub)
{
hub_shutdown_service(g_hub);
return 1;
}
return 0;
});
EXO_TEST(hub_net_shutdown, {
return (net_destroy() != -1);
});
+162
View File
@@ -0,0 +1,162 @@
#include <uhub.h>
#define USER_CID "GNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI"
#define USER_PID "3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y"
#define USER_NICK "Friend"
#define USER_SID "AAAB"
static struct hub_user* inf_user = 0;
static struct hub_info* inf_hub = 0;
extern int hub_handle_info_login(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd);
static void inf_create_hub()
{
net_initialize();
inf_hub = (struct hub_info*) hub_malloc_zero(sizeof(struct hub_info));
inf_hub->users = uman_init();
inf_hub->acl = (struct acl_handle*) hub_malloc_zero(sizeof(struct acl_handle));
inf_hub->config = (struct hub_config*) hub_malloc_zero(sizeof(struct hub_config));
config_defaults(inf_hub->config);
acl_initialize(inf_hub->config, inf_hub->acl);
}
static void inf_destroy_hub()
{
uman_shutdown(inf_hub->users);
acl_shutdown(inf_hub->acl);
free_config(inf_hub->config);
hub_free(inf_hub->acl);
hub_free(inf_hub->config);
hub_free(inf_hub);
net_destroy();
}
static void inf_create_user()
{
if (inf_user) return;
inf_user = (struct hub_user*) hub_malloc_zero(sizeof(struct hub_user));
inf_user->id.sid = 1;
inf_user->limits.upload_slots = 1;
}
static void inf_destroy_user()
{
if (!inf_user) return;
hub_free(inf_user);
inf_user = 0;
}
EXO_TEST(inf_create_setup,
{
inf_create_hub();
inf_create_user();
return (inf_user && inf_hub);
});
/* FIXME: MEMORY LEAK - Need to fix hub_handle_info_login */
#define CHECK_INF(MSG, EXPECT) \
do { \
struct adc_message* msg = adc_msg_parse_verify(inf_user, MSG, strlen(MSG)); \
int ok = hub_handle_info_login(inf_hub, inf_user, msg); /* FIXME: MEMORY LEAK */ \
adc_msg_free(msg); \
if (ok == EXPECT) \
user_set_info(inf_user, 0); \
return ok == EXPECT; \
} while(0)
EXO_TEST(inf_ok_1, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", 0); });
/* check CID abuse */
EXO_TEST(inf_cid_1, { CHECK_INF("BINF AAAB NIFriend PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_cid_missing); });
EXO_TEST(inf_cid_2, { CHECK_INF("BINF AAAB NIFriend IDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_cid_invalid); });
EXO_TEST(inf_cid_3, { CHECK_INF("BINF AAAB NIFriend IDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_cid_invalid); });
EXO_TEST(inf_cid_4, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2R PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_cid_invalid); }); /* cid 1 byte short */
EXO_TEST(inf_cid_5, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RX PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_cid_invalid); }); /* cid 1 byte longer */
EXO_TEST(inf_cid_6, { CHECK_INF("BINF AAAB NIFriend IDA PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_cid_invalid); });
EXO_TEST(inf_cid_7, { CHECK_INF("BINF AAAB NIFriend IDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_cid_invalid); }); /* multi */
EXO_TEST(inf_cid_8, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y IDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n", status_msg_inf_error_cid_invalid); });
EXO_TEST(inf_cid_9, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI\n", status_msg_inf_error_cid_invalid); });
/* equivalent to the pid versions */
EXO_TEST(inf_pid_1, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI\n", status_msg_inf_error_pid_missing); }); /* pid missing */
EXO_TEST(inf_pid_2, { CHECK_INF("BINF AAAB NIFriend ID3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y PDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n", status_msg_inf_error_cid_invalid); }); /* variant of inf_cid_2 */
EXO_TEST(inf_pid_3, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n", status_msg_inf_error_pid_invalid); }); /* pid invalid */
EXO_TEST(inf_pid_4, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7\n", status_msg_inf_error_pid_invalid); }); /* pid 1 byte short */
EXO_TEST(inf_pid_5, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7YX\n", status_msg_inf_error_pid_invalid); }); /* pid 1 byte longer */
EXO_TEST(inf_pid_6, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PDA\n", status_msg_inf_error_pid_invalid); }); /* very short pid */
EXO_TEST(inf_pid_7, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y PDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n", status_msg_inf_error_pid_invalid); });
EXO_TEST(inf_pid_8, { CHECK_INF("BINF AAAB NIFriend PDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_pid_invalid); });
EXO_TEST(inf_pid_9, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_pid_invalid); });
/* check nickname abuse */
EXO_TEST(inf_nick_01, { CHECK_INF("BINF AAAB IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_nick_missing); });
EXO_TEST(inf_nick_02, { CHECK_INF("BINF AAAB NI IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_nick_short); });
EXO_TEST(inf_nick_03, { CHECK_INF("BINF AAAB NIa IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_nick_short); });
EXO_TEST(inf_nick_04, { CHECK_INF("BINF AAAB NIabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_nick_long); });
EXO_TEST(inf_nick_05, { CHECK_INF("BINF AAAB NI\\sabc IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_nick_spaces); });
EXO_TEST(inf_nick_06, { CHECK_INF("BINF AAAB NIa\\sc IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", 0); });
EXO_TEST(inf_nick_07, { CHECK_INF("BINF AAAB NIa\tc IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_nick_bad_chars); });
EXO_TEST(inf_nick_08, { CHECK_INF("BINF AAAB NIa\\nc IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_nick_bad_chars); });
EXO_TEST(inf_nick_09, { CHECK_INF("BINF AAAB NIabc NIdef IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n", status_msg_inf_error_nick_multiple); });
EXO_TEST(inf_nick_10, {
const char* line = "BINF AAAB IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y\n";
int ok;
char nick[10];
struct adc_message* msg;
nick[0] = 0xf7; nick[1] = 0x80; nick[2] = 0x7f; nick[3] = 0x81; nick[4] = 0x98; nick[5] = 0x00;
msg = adc_msg_parse_verify(inf_user, line, strlen(line));
adc_msg_add_named_argument(msg, "NI", nick);
ok = hub_handle_info_login(inf_hub, inf_user, msg);
adc_msg_free(msg);
if (ok != status_msg_inf_error_nick_not_utf8)
printf("Expected %d, got %d\n", status_msg_inf_error_nick_not_utf8, ok);
return ok == status_msg_inf_error_nick_not_utf8;
});
/* check limits for slots and share */
EXO_TEST(inf_limits_1, { inf_hub->config->limit_min_slots = 1; CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y SL0\n", status_msg_user_slots_low); });
EXO_TEST(inf_limits_2, { inf_hub->config->limit_max_slots = 5; CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y SL99\n", status_msg_user_slots_high); });
EXO_TEST(inf_limits_3, { inf_hub->config->limit_min_share = 100; CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y SS104857599\n", status_msg_user_share_size_low); });
EXO_TEST(inf_limits_4, { inf_hub->config->limit_max_share = 500; CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y SS524288001\n", status_msg_user_share_size_high); });
/* setup for check limits for hubs */
EXO_TEST(inf_limit_hubs_setup,
{
inf_hub->config->limit_min_slots = 0;
inf_hub->config->limit_max_slots = 0;
inf_hub->config->limit_max_share = 0;
inf_hub->config->limit_min_share = 0;
inf_hub->config->limit_max_hubs_user = 10;
inf_hub->config->limit_max_hubs_reg = 10;
inf_hub->config->limit_max_hubs_op = 10;
inf_hub->config->limit_min_hubs_user = 2;
inf_hub->config->limit_min_hubs_reg = 2;
inf_hub->config->limit_min_hubs_op = 2;
inf_hub->config->limit_max_hubs = 25;
return 1;
} );
EXO_TEST(inf_limit_hubs_1, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y HN15\n", status_msg_user_hub_limit_high); });
EXO_TEST(inf_limit_hubs_2, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y HN1\n", status_msg_user_hub_limit_low); });
EXO_TEST(inf_limit_hubs_3, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y HO15\n", status_msg_user_hub_limit_high); });
EXO_TEST(inf_limit_hubs_4, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y HO1\n", status_msg_user_hub_limit_low); });
EXO_TEST(inf_limit_hubs_5, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y HR15\n", status_msg_user_hub_limit_high); });
EXO_TEST(inf_limit_hubs_6, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y HR1\n", status_msg_user_hub_limit_low); });
EXO_TEST(inf_limit_hubs_7, { CHECK_INF("BINF AAAB NIFriend IDGNSSMURMD7K466NGZIHU65TP3S3UZSQ6MN5B2RI PD3A4545WFVGZLSGUXZLG7OS6ULQUVG3HM2T63I7Y HN15 HR15 HO15\n", status_msg_user_hub_limit_high); });
EXO_TEST(inf_destroy_setup,
{
inf_destroy_user();
inf_destroy_hub();
return 1;
});
+630
View File
@@ -0,0 +1,630 @@
#include <uhub.h>
static int ipv6 = 0;
static struct ip_addr_encap ip4_a;
static struct ip_addr_encap ip4_b;
static struct ip_addr_encap ip4_c;
static struct ip_addr_encap ip6_a;
static struct ip_addr_encap ip6_b;
static struct ip_addr_encap ip6_c;
static struct ip_addr_encap mask;
static struct ip_range ban6;
static struct ip_range ban4;
EXO_TEST(prepare_network, {
return net_initialize() == 0;
});
EXO_TEST(check_ipv6, {
ipv6 = net_is_ipv6_supported();
return ipv6 != -1;
});
EXO_TEST(create_addresses_1, {
return
ip_convert_to_binary("192.168.0.0", &ip4_a) &&
ip_convert_to_binary("192.168.255.255", &ip4_b) &&
ip_convert_to_binary("192.168.0.1", &ip4_c);
});
EXO_TEST(create_addresses_2, {
return
ip_convert_to_binary("2001::201:2ff:fefa:0", &ip6_a) &&
ip_convert_to_binary("2001::201:2ff:fefa:ffff", &ip6_b) &&
ip_convert_to_binary("2001::201:2ff:fefa:fffe", &ip6_c);
});
EXO_TEST(ip_is_valid_ipv4_1, {
return ip_is_valid_ipv4("127.0.0.1");
});
EXO_TEST(ip_is_valid_ipv4_2, {
return ip_is_valid_ipv4("10.18.1.178");
});
EXO_TEST(ip_is_valid_ipv4_3, {
return ip_is_valid_ipv4("10.18.1.178");
});
EXO_TEST(ip_is_valid_ipv4_4, {
return ip_is_valid_ipv4("224.0.0.1");
});
EXO_TEST(ip_is_valid_ipv4_5, {
return !ip_is_valid_ipv4("224.0.0.");
});
EXO_TEST(ip_is_valid_ipv4_6, {
return !ip_is_valid_ipv4("invalid");
});
EXO_TEST(ip_is_valid_ipv4_7, {
return !ip_is_valid_ipv4("localhost");
});
EXO_TEST(ip_is_valid_ipv4_8, {
return !ip_is_valid_ipv4("123.45.67.890");
});
EXO_TEST(ip_is_valid_ipv4_9, {
return !ip_is_valid_ipv4("777.777.777.777");
});
EXO_TEST(ip_is_valid_ipv6_1, {
if (!ipv6) return 1;
return ip_is_valid_ipv6("::");
});
EXO_TEST(ip_is_valid_ipv6_2, {
if (!ipv6) return 1;
return ip_is_valid_ipv6("::1");
});
EXO_TEST(ip_is_valid_ipv6_3, {
if (!ipv6) return 1;
return ip_is_valid_ipv6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
});
EXO_TEST(ip4_compare_1, {
return ip_compare(&ip4_a, &ip4_b) < 0;
});
EXO_TEST(ip4_compare_2, {
return ip_compare(&ip4_a, &ip4_c) < 0;
});
EXO_TEST(ip4_compare_3, {
return ip_compare(&ip4_b, &ip4_c) > 0;
});
EXO_TEST(ip4_compare_4, {
return ip_compare(&ip4_b, &ip4_a) > 0;
});
EXO_TEST(ip4_compare_5, {
return ip_compare(&ip4_c, &ip4_a) > 0;
});
EXO_TEST(ip4_compare_6, {
if (!ipv6) return 1;
return ip_compare(&ip4_c, &ip4_c) == 0;
});
EXO_TEST(ip6_compare_1, {
if (!ipv6) return 1;
return ip_compare(&ip6_a, &ip6_b) < 0;
});
EXO_TEST(ip6_compare_2, {
if (!ipv6) return 1;
return ip_compare(&ip6_a, &ip6_c) < 0;
});
EXO_TEST(ip6_compare_3, {
if (!ipv6) return 1;
return ip_compare(&ip6_b, &ip6_c) > 0;
});
EXO_TEST(ip6_compare_4, {
if (!ipv6) return 1;
return ip_compare(&ip6_b, &ip6_a) > 0;
});
EXO_TEST(ip6_compare_5, {
if (!ipv6) return 1;
return ip_compare(&ip6_c, &ip6_a) > 0;
});
EXO_TEST(ip6_compare_6, {
if (!ipv6) return 1;
return ip_compare(&ip6_c, &ip6_c) == 0;
});
static int compare_str(const char* s1, const char* s2)
{
int ok = strcmp(s1, s2);
#ifdef DEBUG_TESTS
if (ok)
{
printf("compare_str fail: s1='%s', s2='%s'\n", s1, s2);
}
#endif
return ok;
}
#define LMASK4(bits) !ip_mask_create_left (AF_INET, bits, &mask)
#define LMASK6(bits) (ipv6 ? !ip_mask_create_left (AF_INET6, bits, &mask) : 1)
#define RMASK4(bits) !ip_mask_create_right(AF_INET, bits, &mask)
#define RMASK6(bits) (ipv6 ? !ip_mask_create_right(AF_INET6, bits, &mask) : 1)
#define CHECK4(expect) !compare_str(ip_convert_to_string(&mask), expect)
#define CHECK6(expect) (ipv6 ? !compare_str(ip_convert_to_string(&mask), expect) : 1)
/* Check IPv4 masks */
EXO_TEST(ipv4_lmask_create_0, { return LMASK4( 0) && CHECK4("0.0.0.0"); });
EXO_TEST(ipv4_lmask_create_1, { return LMASK4( 1) && CHECK4("128.0.0.0"); });
EXO_TEST(ipv4_lmask_create_2, { return LMASK4( 2) && CHECK4("192.0.0.0"); });
EXO_TEST(ipv4_lmask_create_3, { return LMASK4( 3) && CHECK4("224.0.0.0"); });
EXO_TEST(ipv4_lmask_create_4, { return LMASK4( 4) && CHECK4("240.0.0.0"); });
EXO_TEST(ipv4_lmask_create_5, { return LMASK4( 5) && CHECK4("248.0.0.0"); });
EXO_TEST(ipv4_lmask_create_6, { return LMASK4( 6) && CHECK4("252.0.0.0"); });
EXO_TEST(ipv4_lmask_create_7, { return LMASK4( 7) && CHECK4("254.0.0.0"); });
EXO_TEST(ipv4_lmask_create_8, { return LMASK4( 8) && CHECK4("255.0.0.0"); });
EXO_TEST(ipv4_lmask_create_9, { return LMASK4( 9) && CHECK4("255.128.0.0"); });
EXO_TEST(ipv4_lmask_create_10, { return LMASK4(10) && CHECK4("255.192.0.0"); });
EXO_TEST(ipv4_lmask_create_11, { return LMASK4(11) && CHECK4("255.224.0.0"); });
EXO_TEST(ipv4_lmask_create_12, { return LMASK4(12) && CHECK4("255.240.0.0"); });
EXO_TEST(ipv4_lmask_create_13, { return LMASK4(13) && CHECK4("255.248.0.0"); });
EXO_TEST(ipv4_lmask_create_14, { return LMASK4(14) && CHECK4("255.252.0.0"); });
EXO_TEST(ipv4_lmask_create_15, { return LMASK4(15) && CHECK4("255.254.0.0"); });
EXO_TEST(ipv4_lmask_create_16, { return LMASK4(16) && CHECK4("255.255.0.0"); });
EXO_TEST(ipv4_lmask_create_17, { return LMASK4(17) && CHECK4("255.255.128.0"); });
EXO_TEST(ipv4_lmask_create_18, { return LMASK4(18) && CHECK4("255.255.192.0"); });
EXO_TEST(ipv4_lmask_create_19, { return LMASK4(19) && CHECK4("255.255.224.0"); });
EXO_TEST(ipv4_lmask_create_20, { return LMASK4(20) && CHECK4("255.255.240.0"); });
EXO_TEST(ipv4_lmask_create_21, { return LMASK4(21) && CHECK4("255.255.248.0"); });
EXO_TEST(ipv4_lmask_create_22, { return LMASK4(22) && CHECK4("255.255.252.0"); });
EXO_TEST(ipv4_lmask_create_23, { return LMASK4(23) && CHECK4("255.255.254.0"); });
EXO_TEST(ipv4_lmask_create_24, { return LMASK4(24) && CHECK4("255.255.255.0"); });
EXO_TEST(ipv4_lmask_create_25, { return LMASK4(25) && CHECK4("255.255.255.128"); });
EXO_TEST(ipv4_lmask_create_26, { return LMASK4(26) && CHECK4("255.255.255.192"); });
EXO_TEST(ipv4_lmask_create_27, { return LMASK4(27) && CHECK4("255.255.255.224"); });
EXO_TEST(ipv4_lmask_create_28, { return LMASK4(28) && CHECK4("255.255.255.240"); });
EXO_TEST(ipv4_lmask_create_29, { return LMASK4(29) && CHECK4("255.255.255.248"); });
EXO_TEST(ipv4_lmask_create_30, { return LMASK4(30) && CHECK4("255.255.255.252"); });
EXO_TEST(ipv4_lmask_create_31, { return LMASK4(31) && CHECK4("255.255.255.254"); });
EXO_TEST(ipv4_lmask_create_32, { return LMASK4(32) && CHECK4("255.255.255.255"); });
/* Check IPv4 right to left mask */
EXO_TEST(ipv4_rmask_create_0, { return RMASK4( 0) && CHECK4("0.0.0.0"); });
EXO_TEST(ipv4_rmask_create_1, { return RMASK4( 1) && CHECK4("0.0.0.1"); });
EXO_TEST(ipv4_rmask_create_2, { return RMASK4( 2) && CHECK4("0.0.0.3"); });
EXO_TEST(ipv4_rmask_create_3, { return RMASK4( 3) && CHECK4("0.0.0.7"); });
EXO_TEST(ipv4_rmask_create_4, { return RMASK4( 4) && CHECK4("0.0.0.15"); });
EXO_TEST(ipv4_rmask_create_5, { return RMASK4( 5) && CHECK4("0.0.0.31"); });
EXO_TEST(ipv4_rmask_create_6, { return RMASK4( 6) && CHECK4("0.0.0.63"); });
EXO_TEST(ipv4_rmask_create_7, { return RMASK4( 7) && CHECK4("0.0.0.127"); });
EXO_TEST(ipv4_rmask_create_8, { return RMASK4( 8) && CHECK4("0.0.0.255"); });
EXO_TEST(ipv4_rmask_create_9, { return RMASK4( 9) && CHECK4("0.0.1.255"); });
EXO_TEST(ipv4_rmask_create_10, { return RMASK4(10) && CHECK4("0.0.3.255"); });
EXO_TEST(ipv4_rmask_create_11, { return RMASK4(11) && CHECK4("0.0.7.255"); });
EXO_TEST(ipv4_rmask_create_12, { return RMASK4(12) && CHECK4("0.0.15.255"); });
EXO_TEST(ipv4_rmask_create_13, { return RMASK4(13) && CHECK4("0.0.31.255"); });
EXO_TEST(ipv4_rmask_create_14, { return RMASK4(14) && CHECK4("0.0.63.255"); });
EXO_TEST(ipv4_rmask_create_15, { return RMASK4(15) && CHECK4("0.0.127.255"); });
EXO_TEST(ipv4_rmask_create_16, { return RMASK4(16) && CHECK4("0.0.255.255"); });
EXO_TEST(ipv4_rmask_create_17, { return RMASK4(17) && CHECK4("0.1.255.255"); });
EXO_TEST(ipv4_rmask_create_18, { return RMASK4(18) && CHECK4("0.3.255.255"); });
EXO_TEST(ipv4_rmask_create_19, { return RMASK4(19) && CHECK4("0.7.255.255"); });
EXO_TEST(ipv4_rmask_create_20, { return RMASK4(20) && CHECK4("0.15.255.255"); });
EXO_TEST(ipv4_rmask_create_21, { return RMASK4(21) && CHECK4("0.31.255.255"); });
EXO_TEST(ipv4_rmask_create_22, { return RMASK4(22) && CHECK4("0.63.255.255"); });
EXO_TEST(ipv4_rmask_create_23, { return RMASK4(23) && CHECK4("0.127.255.255"); });
EXO_TEST(ipv4_rmask_create_24, { return RMASK4(24) && CHECK4("0.255.255.255"); });
EXO_TEST(ipv4_rmask_create_25, { return RMASK4(25) && CHECK4("1.255.255.255"); });
EXO_TEST(ipv4_rmask_create_26, { return RMASK4(26) && CHECK4("3.255.255.255"); });
EXO_TEST(ipv4_rmask_create_27, { return RMASK4(27) && CHECK4("7.255.255.255"); });
EXO_TEST(ipv4_rmask_create_28, { return RMASK4(28) && CHECK4("15.255.255.255"); });
EXO_TEST(ipv4_rmask_create_29, { return RMASK4(29) && CHECK4("31.255.255.255"); });
EXO_TEST(ipv4_rmask_create_30, { return RMASK4(30) && CHECK4("63.255.255.255"); });
EXO_TEST(ipv4_rmask_create_31, { return RMASK4(31) && CHECK4("127.255.255.255"); });
EXO_TEST(ipv4_rmask_create_32, { return RMASK4(32) && CHECK4("255.255.255.255"); });
/* Check IPv6 masks */
EXO_TEST(ip6_lmask_create_0, { return LMASK6( 0) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
EXO_TEST(ip6_lmask_create_1, { return LMASK6( 1) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe"); });
EXO_TEST(ip6_lmask_create_2, { return LMASK6( 2) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffc"); });
EXO_TEST(ip6_lmask_create_3, { return LMASK6( 3) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff8"); });
EXO_TEST(ip6_lmask_create_4, { return LMASK6( 4) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff0"); });
EXO_TEST(ip6_lmask_create_5, { return LMASK6( 5) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffe0"); });
EXO_TEST(ip6_lmask_create_6, { return LMASK6( 6) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffc0"); });
EXO_TEST(ip6_lmask_create_7, { return LMASK6( 7) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff80"); });
EXO_TEST(ip6_lmask_create_8, { return LMASK6( 8) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"); });
EXO_TEST(ip6_lmask_create_9, { return LMASK6( 9) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fe00"); });
EXO_TEST(ip6_lmask_create_10, { return LMASK6( 10) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fc00"); });
EXO_TEST(ip6_lmask_create_11, { return LMASK6( 11) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:f800"); });
EXO_TEST(ip6_lmask_create_12, { return LMASK6( 12) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:f000"); });
EXO_TEST(ip6_lmask_create_13, { return LMASK6( 13) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:e000"); });
EXO_TEST(ip6_lmask_create_14, { return LMASK6( 14) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:c000"); });
EXO_TEST(ip6_lmask_create_15, { return LMASK6( 15) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:8000"); });
EXO_TEST(ip6_lmask_create_16, { return LMASK6( 16) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff::")); });
EXO_TEST(ip6_lmask_create_17, { return LMASK6( 17) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:fffe:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:fffe::")); });
EXO_TEST(ip6_lmask_create_18, { return LMASK6( 18) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:fffc:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:fffc::")); });
EXO_TEST(ip6_lmask_create_19, { return LMASK6( 19) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:fff8:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:fff8::")); });
EXO_TEST(ip6_lmask_create_20, { return LMASK6( 20) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:fff0:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:fff0::")); });
EXO_TEST(ip6_lmask_create_21, { return LMASK6( 21) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffe0:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffe0::")); });
EXO_TEST(ip6_lmask_create_22, { return LMASK6( 22) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffc0:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffc0::")); });
EXO_TEST(ip6_lmask_create_23, { return LMASK6( 23) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ff80:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ff80::")); });
EXO_TEST(ip6_lmask_create_24, { return LMASK6( 24) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ff00:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ff00::")); });
EXO_TEST(ip6_lmask_create_25, { return LMASK6( 25) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:fe00:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:fe00::")); });
EXO_TEST(ip6_lmask_create_26, { return LMASK6( 26) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:fc00:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:fc00::")); });
EXO_TEST(ip6_lmask_create_27, { return LMASK6( 27) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:f800:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:f800::")); });
EXO_TEST(ip6_lmask_create_28, { return LMASK6( 28) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:f000:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:f000::")); });
EXO_TEST(ip6_lmask_create_29, { return LMASK6( 29) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:e000:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:e000::")); });
EXO_TEST(ip6_lmask_create_30, { return LMASK6( 30) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:c000:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:c000::")); });
EXO_TEST(ip6_lmask_create_31, { return LMASK6( 31) && (CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:8000:0") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:8000::")); });
EXO_TEST(ip6_lmask_create_32, { return LMASK6( 32) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff::"); });
EXO_TEST(ip6_lmask_create_33, { return LMASK6( 33) && CHECK6("ffff:ffff:ffff:ffff:ffff:fffe::"); });
EXO_TEST(ip6_lmask_create_34, { return LMASK6( 34) && CHECK6("ffff:ffff:ffff:ffff:ffff:fffc::"); });
EXO_TEST(ip6_lmask_create_35, { return LMASK6( 35) && CHECK6("ffff:ffff:ffff:ffff:ffff:fff8::"); });
EXO_TEST(ip6_lmask_create_36, { return LMASK6( 36) && CHECK6("ffff:ffff:ffff:ffff:ffff:fff0::"); });
EXO_TEST(ip6_lmask_create_37, { return LMASK6( 37) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffe0::"); });
EXO_TEST(ip6_lmask_create_38, { return LMASK6( 38) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffc0::"); });
EXO_TEST(ip6_lmask_create_39, { return LMASK6( 39) && CHECK6("ffff:ffff:ffff:ffff:ffff:ff80::"); });
EXO_TEST(ip6_lmask_create_40, { return LMASK6( 40) && CHECK6("ffff:ffff:ffff:ffff:ffff:ff00::"); });
EXO_TEST(ip6_lmask_create_41, { return LMASK6( 41) && CHECK6("ffff:ffff:ffff:ffff:ffff:fe00::"); });
EXO_TEST(ip6_lmask_create_42, { return LMASK6( 42) && CHECK6("ffff:ffff:ffff:ffff:ffff:fc00::"); });
EXO_TEST(ip6_lmask_create_43, { return LMASK6( 43) && CHECK6("ffff:ffff:ffff:ffff:ffff:f800::"); });
EXO_TEST(ip6_lmask_create_44, { return LMASK6( 44) && CHECK6("ffff:ffff:ffff:ffff:ffff:f000::"); });
EXO_TEST(ip6_lmask_create_45, { return LMASK6( 45) && CHECK6("ffff:ffff:ffff:ffff:ffff:e000::"); });
EXO_TEST(ip6_lmask_create_46, { return LMASK6( 46) && CHECK6("ffff:ffff:ffff:ffff:ffff:c000::"); });
EXO_TEST(ip6_lmask_create_47, { return LMASK6( 47) && CHECK6("ffff:ffff:ffff:ffff:ffff:8000::"); });
EXO_TEST(ip6_lmask_create_48, { return LMASK6( 48) && CHECK6("ffff:ffff:ffff:ffff:ffff::"); });
EXO_TEST(ip6_lmask_create_49, { return LMASK6( 49) && CHECK6("ffff:ffff:ffff:ffff:fffe::"); });
EXO_TEST(ip6_lmask_create_50, { return LMASK6( 50) && CHECK6("ffff:ffff:ffff:ffff:fffc::"); });
EXO_TEST(ip6_lmask_create_51, { return LMASK6( 51) && CHECK6("ffff:ffff:ffff:ffff:fff8::"); });
EXO_TEST(ip6_lmask_create_52, { return LMASK6( 52) && CHECK6("ffff:ffff:ffff:ffff:fff0::"); });
EXO_TEST(ip6_lmask_create_53, { return LMASK6( 53) && CHECK6("ffff:ffff:ffff:ffff:ffe0::"); });
EXO_TEST(ip6_lmask_create_54, { return LMASK6( 54) && CHECK6("ffff:ffff:ffff:ffff:ffc0::"); });
EXO_TEST(ip6_lmask_create_55, { return LMASK6( 55) && CHECK6("ffff:ffff:ffff:ffff:ff80::"); });
EXO_TEST(ip6_lmask_create_56, { return LMASK6( 56) && CHECK6("ffff:ffff:ffff:ffff:ff00::"); });
EXO_TEST(ip6_lmask_create_57, { return LMASK6( 57) && CHECK6("ffff:ffff:ffff:ffff:fe00::"); });
EXO_TEST(ip6_lmask_create_58, { return LMASK6( 58) && CHECK6("ffff:ffff:ffff:ffff:fc00::"); });
EXO_TEST(ip6_lmask_create_59, { return LMASK6( 59) && CHECK6("ffff:ffff:ffff:ffff:f800::"); });
EXO_TEST(ip6_lmask_create_60, { return LMASK6( 60) && CHECK6("ffff:ffff:ffff:ffff:f000::"); });
EXO_TEST(ip6_lmask_create_61, { return LMASK6( 61) && CHECK6("ffff:ffff:ffff:ffff:e000::"); });
EXO_TEST(ip6_lmask_create_62, { return LMASK6( 62) && CHECK6("ffff:ffff:ffff:ffff:c000::"); });
EXO_TEST(ip6_lmask_create_63, { return LMASK6( 63) && CHECK6("ffff:ffff:ffff:ffff:8000::"); });
EXO_TEST(ip6_lmask_create_64, { return LMASK6( 64) && CHECK6("ffff:ffff:ffff:ffff::"); });
EXO_TEST(ip6_lmask_create_65, { return LMASK6( 65) && CHECK6("ffff:ffff:ffff:fffe::"); });
EXO_TEST(ip6_lmask_create_66, { return LMASK6( 66) && CHECK6("ffff:ffff:ffff:fffc::"); });
EXO_TEST(ip6_lmask_create_67, { return LMASK6( 67) && CHECK6("ffff:ffff:ffff:fff8::"); });
EXO_TEST(ip6_lmask_create_68, { return LMASK6( 68) && CHECK6("ffff:ffff:ffff:fff0::"); });
EXO_TEST(ip6_lmask_create_69, { return LMASK6( 69) && CHECK6("ffff:ffff:ffff:ffe0::"); });
EXO_TEST(ip6_lmask_create_70, { return LMASK6( 70) && CHECK6("ffff:ffff:ffff:ffc0::"); });
EXO_TEST(ip6_lmask_create_71, { return LMASK6( 71) && CHECK6("ffff:ffff:ffff:ff80::"); });
EXO_TEST(ip6_lmask_create_72, { return LMASK6( 72) && CHECK6("ffff:ffff:ffff:ff00::"); });
EXO_TEST(ip6_lmask_create_73, { return LMASK6( 73) && CHECK6("ffff:ffff:ffff:fe00::"); });
EXO_TEST(ip6_lmask_create_74, { return LMASK6( 74) && CHECK6("ffff:ffff:ffff:fc00::"); });
EXO_TEST(ip6_lmask_create_75, { return LMASK6( 75) && CHECK6("ffff:ffff:ffff:f800::"); });
EXO_TEST(ip6_lmask_create_76, { return LMASK6( 76) && CHECK6("ffff:ffff:ffff:f000::"); });
EXO_TEST(ip6_lmask_create_77, { return LMASK6( 77) && CHECK6("ffff:ffff:ffff:e000::"); });
EXO_TEST(ip6_lmask_create_78, { return LMASK6( 78) && CHECK6("ffff:ffff:ffff:c000::"); });
EXO_TEST(ip6_lmask_create_79, { return LMASK6( 79) && CHECK6("ffff:ffff:ffff:8000::"); });
EXO_TEST(ip6_lmask_create_80, { return LMASK6( 80) && CHECK6("ffff:ffff:ffff::"); });
EXO_TEST(ip6_lmask_create_81, { return LMASK6( 81) && CHECK6("ffff:ffff:fffe::"); });
EXO_TEST(ip6_lmask_create_82, { return LMASK6( 82) && CHECK6("ffff:ffff:fffc::"); });
EXO_TEST(ip6_lmask_create_83, { return LMASK6( 83) && CHECK6("ffff:ffff:fff8::"); });
EXO_TEST(ip6_lmask_create_84, { return LMASK6( 84) && CHECK6("ffff:ffff:fff0::"); });
EXO_TEST(ip6_lmask_create_85, { return LMASK6( 85) && CHECK6("ffff:ffff:ffe0::"); });
EXO_TEST(ip6_lmask_create_86, { return LMASK6( 86) && CHECK6("ffff:ffff:ffc0::"); });
EXO_TEST(ip6_lmask_create_87, { return LMASK6( 87) && CHECK6("ffff:ffff:ff80::"); });
EXO_TEST(ip6_lmask_create_88, { return LMASK6( 88) && CHECK6("ffff:ffff:ff00::"); });
EXO_TEST(ip6_lmask_create_89, { return LMASK6( 89) && CHECK6("ffff:ffff:fe00::"); });
EXO_TEST(ip6_lmask_create_90, { return LMASK6( 90) && CHECK6("ffff:ffff:fc00::"); });
EXO_TEST(ip6_lmask_create_91, { return LMASK6( 91) && CHECK6("ffff:ffff:f800::"); });
EXO_TEST(ip6_lmask_create_92, { return LMASK6( 92) && CHECK6("ffff:ffff:f000::"); });
EXO_TEST(ip6_lmask_create_93, { return LMASK6( 93) && CHECK6("ffff:ffff:e000::"); });
EXO_TEST(ip6_lmask_create_94, { return LMASK6( 94) && CHECK6("ffff:ffff:c000::"); });
EXO_TEST(ip6_lmask_create_95, { return LMASK6( 95) && CHECK6("ffff:ffff:8000::"); });
EXO_TEST(ip6_lmask_create_96, { return LMASK6( 96) && CHECK6("ffff:ffff::"); });
EXO_TEST(ip6_lmask_create_97, { return LMASK6( 97) && CHECK6("ffff:fffe::"); });
EXO_TEST(ip6_lmask_create_98, { return LMASK6( 98) && CHECK6("ffff:fffc::"); });
EXO_TEST(ip6_lmask_create_99, { return LMASK6( 99) && CHECK6("ffff:fff8::"); });
EXO_TEST(ip6_lmask_create_100, { return LMASK6(100) && CHECK6("ffff:fff0::"); });
EXO_TEST(ip6_lmask_create_101, { return LMASK6(101) && CHECK6("ffff:ffe0::"); });
EXO_TEST(ip6_lmask_create_102, { return LMASK6(102) && CHECK6("ffff:ffc0::"); });
EXO_TEST(ip6_lmask_create_103, { return LMASK6(103) && CHECK6("ffff:ff80::"); });
EXO_TEST(ip6_lmask_create_104, { return LMASK6(104) && CHECK6("ffff:ff00::"); });
EXO_TEST(ip6_lmask_create_105, { return LMASK6(105) && CHECK6("ffff:fe00::"); });
EXO_TEST(ip6_lmask_create_106, { return LMASK6(106) && CHECK6("ffff:fc00::"); });
EXO_TEST(ip6_lmask_create_107, { return LMASK6(107) && CHECK6("ffff:f800::"); });
EXO_TEST(ip6_lmask_create_108, { return LMASK6(108) && CHECK6("ffff:f000::"); });
EXO_TEST(ip6_lmask_create_109, { return LMASK6(109) && CHECK6("ffff:e000::"); });
EXO_TEST(ip6_lmask_create_110, { return LMASK6(110) && CHECK6("ffff:c000::"); });
EXO_TEST(ip6_lmask_create_111, { return LMASK6(111) && CHECK6("ffff:8000::"); });
EXO_TEST(ip6_lmask_create_112, { return LMASK6(112) && CHECK6("ffff::"); });
EXO_TEST(ip6_lmask_create_113, { return LMASK6(113) && CHECK6("fffe::"); });
EXO_TEST(ip6_lmask_create_114, { return LMASK6(114) && CHECK6("fffc::"); });
EXO_TEST(ip6_lmask_create_115, { return LMASK6(115) && CHECK6("fff8::"); });
EXO_TEST(ip6_lmask_create_116, { return LMASK6(116) && CHECK6("fff0::"); });
EXO_TEST(ip6_lmask_create_117, { return LMASK6(117) && CHECK6("ffe0::"); });
EXO_TEST(ip6_lmask_create_118, { return LMASK6(118) && CHECK6("ffc0::"); });
EXO_TEST(ip6_lmask_create_119, { return LMASK6(119) && CHECK6("ff80::"); });
EXO_TEST(ip6_lmask_create_120, { return LMASK6(120) && CHECK6("ff00::"); });
EXO_TEST(ip6_lmask_create_121, { return LMASK6(121) && CHECK6("fe00::"); });
EXO_TEST(ip6_lmask_create_122, { return LMASK6(122) && CHECK6("fc00::"); });
EXO_TEST(ip6_lmask_create_123, { return LMASK6(123) && CHECK6("f800::"); });
EXO_TEST(ip6_lmask_create_124, { return LMASK6(124) && CHECK6("f000::"); });
EXO_TEST(ip6_lmask_create_125, { return LMASK6(125) && CHECK6("e000::"); });
EXO_TEST(ip6_lmask_create_126, { return LMASK6(126) && CHECK6("c000::"); });
EXO_TEST(ip6_lmask_create_127, { return LMASK6(127) && CHECK6("8000::"); });
EXO_TEST(ip6_lmask_create_128, { return LMASK6(128) && CHECK6("::"); });
/* Check IPv6 right to left masks */
EXO_TEST(ip6_rmask_create_0, { return RMASK6( 0) && CHECK6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
EXO_TEST(ip6_rmask_create_1, { return RMASK6( 1) && CHECK6("7fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
EXO_TEST(ip6_rmask_create_2, { return RMASK6( 2) && CHECK6("3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
EXO_TEST(ip6_rmask_create_3, { return RMASK6( 3) && CHECK6("1fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
EXO_TEST(ip6_rmask_create_4, { return RMASK6( 4) && CHECK6("fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
EXO_TEST(ip6_rmask_create_5, { return RMASK6( 5) && CHECK6("7ff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
EXO_TEST(ip6_rmask_create_6, { return RMASK6( 6) && CHECK6("3ff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
EXO_TEST(ip6_rmask_create_7, { return RMASK6( 7) && CHECK6("1ff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
EXO_TEST(ip6_rmask_create_8, { return RMASK6( 8) && CHECK6("ff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
EXO_TEST(ip6_rmask_create_9, { return RMASK6( 9) && CHECK6("7f:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
EXO_TEST(ip6_rmask_create_10, { return RMASK6( 10) && CHECK6("3f:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
EXO_TEST(ip6_rmask_create_11, { return RMASK6( 11) && CHECK6("1f:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
EXO_TEST(ip6_rmask_create_12, { return RMASK6( 12) && CHECK6("f:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
EXO_TEST(ip6_rmask_create_13, { return RMASK6( 13) && CHECK6("7:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
EXO_TEST(ip6_rmask_create_14, { return RMASK6( 14) && CHECK6("3:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
EXO_TEST(ip6_rmask_create_15, { return RMASK6( 15) && CHECK6("1:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); });
EXO_TEST(ip6_rmask_create_16, { return RMASK6( 16) && (CHECK6("0:ffff:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::ffff:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("ffff:ffff:ffff:ffff:ffff:ffff")); });
EXO_TEST(ip6_rmask_create_17, { return RMASK6( 17) && (CHECK6("0:7fff:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::7fff:ffff:ffff:ffff:ffff:ffff:ffff")); });
EXO_TEST(ip6_rmask_create_18, { return RMASK6( 18) && (CHECK6("0:3fff:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::3fff:ffff:ffff:ffff:ffff:ffff:ffff")); });
EXO_TEST(ip6_rmask_create_19, { return RMASK6( 19) && (CHECK6("0:1fff:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::1fff:ffff:ffff:ffff:ffff:ffff:ffff")); });
EXO_TEST(ip6_rmask_create_20, { return RMASK6( 20) && (CHECK6("0:fff:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::fff:ffff:ffff:ffff:ffff:ffff:ffff")); });
EXO_TEST(ip6_rmask_create_21, { return RMASK6( 21) && (CHECK6("0:7ff:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::7ff:ffff:ffff:ffff:ffff:ffff:ffff")); });
EXO_TEST(ip6_rmask_create_22, { return RMASK6( 22) && (CHECK6("0:3ff:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::3ff:ffff:ffff:ffff:ffff:ffff:ffff")); });
EXO_TEST(ip6_rmask_create_23, { return RMASK6( 23) && (CHECK6("0:1ff:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::1ff:ffff:ffff:ffff:ffff:ffff:ffff")); });
EXO_TEST(ip6_rmask_create_24, { return RMASK6( 24) && (CHECK6("0:ff:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::ff:ffff:ffff:ffff:ffff:ffff:ffff")); });
EXO_TEST(ip6_rmask_create_25, { return RMASK6( 25) && (CHECK6("0:7f:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::7f:ffff:ffff:ffff:ffff:ffff:ffff")); });
EXO_TEST(ip6_rmask_create_26, { return RMASK6( 26) && (CHECK6("0:3f:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::3f:ffff:ffff:ffff:ffff:ffff:ffff")); });
EXO_TEST(ip6_rmask_create_27, { return RMASK6( 27) && (CHECK6("0:1f:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::1f:ffff:ffff:ffff:ffff:ffff:ffff")); });
EXO_TEST(ip6_rmask_create_28, { return RMASK6( 28) && (CHECK6("0:f:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::f:ffff:ffff:ffff:ffff:ffff:ffff")); });
EXO_TEST(ip6_rmask_create_29, { return RMASK6( 29) && (CHECK6("0:7:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::7:ffff:ffff:ffff:ffff:ffff:ffff")); });
EXO_TEST(ip6_rmask_create_30, { return RMASK6( 30) && (CHECK6("0:3:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::3:ffff:ffff:ffff:ffff:ffff:ffff")); });
EXO_TEST(ip6_rmask_create_31, { return RMASK6( 31) && (CHECK6("0:1:ffff:ffff:ffff:ffff:ffff:ffff") || CHECK6("::1:ffff:ffff:ffff:ffff:ffff:ffff")); });
EXO_TEST(check_ban_setup_1, {
return ip_convert_to_binary("2001::201:2ff:fefa:0", &ban6.lo) &&
ip_convert_to_binary("2001::201:2ff:fefa:ffff", &ban6.hi) &&
ip_convert_to_binary("192.168.0.0", &ban4.lo) &&
ip_convert_to_binary("192.168.0.255", &ban4.hi);
});
EXO_TEST(check_ban_ipv4_1, {
struct ip_addr_encap addr; ip_convert_to_binary("192.168.0.0", &addr);
return ip_in_range(&addr, &ban4);
});
EXO_TEST(check_ban_ipv4_2, {
struct ip_addr_encap addr; ip_convert_to_binary("192.168.0.1", &addr);
return ip_in_range(&addr, &ban4);
});
EXO_TEST(check_ban_ipv4_3, {
struct ip_addr_encap addr; ip_convert_to_binary("192.168.0.255", &addr);
return ip_in_range(&addr, &ban4);
});
EXO_TEST(check_ban_ipv4_4, {
struct ip_addr_encap addr; ip_convert_to_binary("192.168.1.0", &addr);
return !ip_in_range(&addr, &ban4);
});
EXO_TEST(check_ban_ipv4_5, {
struct ip_addr_encap addr; ip_convert_to_binary("192.167.255.255", &addr);
return !ip_in_range(&addr, &ban4);
});
EXO_TEST(check_ban_ipv6_1, {
struct ip_addr_encap addr;
if (!ipv6) return 1;
ip_convert_to_binary("2001::201:2ff:fefa:0", &addr);
return ip_in_range(&addr, &ban6);
});
EXO_TEST(check_ban_ipv6_2, {
struct ip_addr_encap addr;
if (!ipv6) return 1;
ip_convert_to_binary("2001::201:2ff:fefa:1", &addr);
return ip_in_range(&addr, &ban6);
});
EXO_TEST(check_ban_ipv6_3, {
struct ip_addr_encap addr;
if (!ipv6) return 1;
ip_convert_to_binary("2001::201:2ff:fefa:fffe", &addr);
return ip_in_range(&addr, &ban6);
});
EXO_TEST(check_ban_ipv6_4, {
struct ip_addr_encap addr;
if (!ipv6) return 1;
ip_convert_to_binary("2001::201:2ff:fefa:ffff", &addr);
return ip_in_range(&addr, &ban6);
});
EXO_TEST(check_ban_ipv6_5, {
struct ip_addr_encap addr;
if (!ipv6) return 1;
ip_convert_to_binary("2001::201:2ff:fefb:0", &addr);
return !ip_in_range(&addr, &ban6);
});
EXO_TEST(check_ban_ipv6_6, {
struct ip_addr_encap addr;
if (!ipv6) return 1;
ip_convert_to_binary("2001::201:2ff:fef9:ffff", &addr);
return !ip_in_range(&addr, &ban6);
});
EXO_TEST(check_ban_afmix_1, {
struct ip_addr_encap addr;
if (!ipv6) return 1;
ip_convert_to_binary("2001::201:2ff:fef9:ffff", &addr);
return !ip_in_range(&addr, &ban4);
});
EXO_TEST(check_ban_afmix_2, {
struct ip_addr_encap addr; ip_convert_to_binary("10.20.30.40", &addr);
return !ip_in_range(&addr, &ban6);
});
EXO_TEST(ip4_bitwise_AND_1, {
ip_convert_to_binary("255.255.255.255", &ip4_a);
ip_convert_to_binary("255.255.255.0", &ip4_b);
ip_mask_apply_AND(&ip4_a, &ip4_b, &ip4_c);
return !strcmp(ip_convert_to_string(&ip4_c), "255.255.255.0");
});
EXO_TEST(ip4_bitwise_AND_2, {
ip_convert_to_binary("192.168.217.113", &ip4_a);
ip_convert_to_binary("255.255.255.0", &ip4_b);
ip_mask_apply_AND(&ip4_a, &ip4_b, &ip4_c);
return !strcmp(ip_convert_to_string(&ip4_c), "192.168.217.0");
});
EXO_TEST(ip4_bitwise_AND_3, {
ip_convert_to_binary("192.168.217.113", &ip4_a);
ip_convert_to_binary("255.255.0.0", &ip4_b);
ip_mask_apply_AND(&ip4_a, &ip4_b, &ip4_c);
return !strcmp(ip_convert_to_string(&ip4_c), "192.168.0.0");
});
EXO_TEST(ip4_bitwise_AND_4, {
ip_convert_to_binary("192.168.217.113", &ip4_a);
ip_convert_to_binary("255.0.0.0", &ip4_b);
ip_mask_apply_AND(&ip4_a, &ip4_b, &ip4_c);
return !strcmp(ip_convert_to_string(&ip4_c), "192.0.0.0");
});
EXO_TEST(ip4_bitwise_AND_5, {
ip_convert_to_binary("192.168.217.113", &ip4_a);
ip_convert_to_binary("0.0.0.0", &ip4_b);
ip_mask_apply_AND(&ip4_a, &ip4_b, &ip4_c);
return !strcmp(ip_convert_to_string(&ip4_c), "0.0.0.0");
});
EXO_TEST(ip4_bitwise_OR_1, {
ip_convert_to_binary("255.255.255.255", &ip4_a);
ip_convert_to_binary("255.255.255.0", &ip4_b);
ip_mask_apply_OR(&ip4_a, &ip4_b, &ip4_c);
return !strcmp(ip_convert_to_string(&ip4_c), "255.255.255.255");
});
EXO_TEST(ip4_bitwise_OR_2, {
ip_convert_to_binary("192.168.217.113", &ip4_a);
ip_convert_to_binary("255.255.255.0", &ip4_b);
ip_mask_apply_OR(&ip4_a, &ip4_b, &ip4_c);
return !strcmp(ip_convert_to_string(&ip4_c), "255.255.255.113");
});
EXO_TEST(ip4_bitwise_OR_3, {
ip_convert_to_binary("192.168.217.113", &ip4_a);
ip_convert_to_binary("255.255.0.0", &ip4_b);
ip_mask_apply_OR(&ip4_a, &ip4_b, &ip4_c);
return !strcmp(ip_convert_to_string(&ip4_c), "255.255.217.113");
});
EXO_TEST(ip4_bitwise_OR_4, {
ip_convert_to_binary("192.168.217.113", &ip4_a);
ip_convert_to_binary("255.0.0.0", &ip4_b);
ip_mask_apply_OR(&ip4_a, &ip4_b, &ip4_c);
return !strcmp(ip_convert_to_string(&ip4_c), "255.168.217.113");
});
EXO_TEST(ip4_bitwise_OR_5, {
ip_convert_to_binary("192.168.217.113", &ip4_a);
ip_convert_to_binary("0.0.0.0", &ip4_b);
ip_mask_apply_OR(&ip4_a, &ip4_b, &ip4_c);
return !strcmp(ip_convert_to_string(&ip4_c), "192.168.217.113");
});
EXO_TEST(ip6_bitwise_AND_1, {
if (!ipv6) return 1;
ip_convert_to_binary("7f7f:ffff:ffff:3f3f:ffff:ffff:ffff:ffff", &ip6_a);
ip_convert_to_binary("ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", &ip6_b);
ip_mask_apply_AND(&ip6_a, &ip6_b, &ip6_c);
return !strcmp(ip_convert_to_string(&ip6_c), "7f7f:ffff:ffff:3f3f:ffff:ffff:ffff:0") ||
!strcmp(ip_convert_to_string(&ip6_c), "7f7f:ffff:ffff:3f3f:ffff:ffff:ffff::");
});
EXO_TEST(ip6_bitwise_AND_2, {
if (!ipv6) return 1;
ip_convert_to_binary("7777:cccc:3333:1111:ffff:ffff:ffff:ffff", &ip6_a);
ip_convert_to_binary("ffff:ffff:ffff:ffff::", &ip6_b);
ip_mask_apply_AND(&ip6_a, &ip6_b, &ip6_c);
return !strcmp(ip_convert_to_string(&ip6_c), "7777:cccc:3333:1111::");
});
EXO_TEST(ip6_bitwise_AND_3, {
if (!ipv6) return 1;
ip_convert_to_binary("7777:cccc:3333:1111:ffff:ffff:ffff:ffff", &ip6_a);
ip_convert_to_binary("::", &ip6_b);
ip_mask_apply_AND(&ip6_a, &ip6_b, &ip6_c);
return !strcmp(ip_convert_to_string(&ip6_c), "::");
});
EXO_TEST(ip6_bitwise_OR_1, {
if (!ipv6) return 1;
ip_convert_to_binary("7f7f:ffff:ffff:3f3f:ffff:ffff:ffff:ffff", &ip6_a);
ip_convert_to_binary("ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", &ip6_b);
ip_mask_apply_OR(&ip6_a, &ip6_b, &ip6_c);
return !strcmp(ip_convert_to_string(&ip6_c), "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
});
EXO_TEST(ip6_bitwise_OR_2, {
if (!ipv6) return 1;
ip_convert_to_binary("7777:cccc:3333:1111:ffff:ffff:ffff:ffff", &ip6_a);
ip_convert_to_binary("ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", &ip6_b);
ip_mask_apply_OR(&ip6_a, &ip6_b, &ip6_c);
return !strcmp(ip_convert_to_string(&ip6_c), "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
});
EXO_TEST(ip6_bitwise_OR_3, {
if (!ipv6) return 1;
ip_convert_to_binary("7777:cccc:3333:1111:ffff:ffff:ffff:1c1c", &ip6_a);
ip_convert_to_binary("::", &ip6_b);
ip_mask_apply_OR(&ip6_a, &ip6_b, &ip6_c);
return !strcmp(ip_convert_to_string(&ip6_c), "7777:cccc:3333:1111:ffff:ffff:ffff:1c1c");
});
EXO_TEST(ip_range_1, {
struct ip_range range; memset(&range, 0, sizeof(range));
return ip_convert_address_to_range("192.168.0.1", &range) && memcmp(&range.lo, &range.hi, sizeof(struct ip_addr_encap)) == 0;
});
EXO_TEST(ip_range_2, {
struct ip_range range; memset(&range, 0, sizeof(range));
return ip_convert_address_to_range("192.168.0.0-192.168.255.255", &range) && range.lo.af == range.hi.af && memcmp(&range.lo, &range.hi, sizeof(struct ip_addr_encap)) != 0;
});
EXO_TEST(ip_range_3, {
struct ip_range range; memset(&range, 0, sizeof(range));
return ip_convert_address_to_range("192.168.0.0/16", &range) && range.lo.af == range.hi.af && memcmp(&range.lo, &range.hi, sizeof(struct ip_addr_encap)) != 0;
});
EXO_TEST(ip_range_4, {
struct ip_range range1;
struct ip_range range2;
memset(&range1, 0, sizeof(range1));
memset(&range2, 0, sizeof(range2));
return ip_convert_address_to_range("192.168.0.0/16", &range1) && ip_convert_address_to_range("192.168.0.0-192.168.255.255", &range2) && memcmp(&range1, &range2, sizeof(struct ip_range)) == 0;
});
EXO_TEST(shutdown_network, {
return net_destroy() == 0;
});
+220
View File
@@ -0,0 +1,220 @@
#include <uhub.h>
static struct linked_list* list = NULL;
static struct linked_list* list2 = NULL;
static char A[2] = { 'A', 0 };
static char B[2] = { 'B', 0 };
static char C[2] = { 'C', 0 };
static char A2[2] = { 'a', 0 };
static char B2[2] = { 'b', 0 };
static char C2[2] = { 'c', 0 };
static void null_free(void* ptr)
{
(void) ptr;
}
EXO_TEST(list_create_destroy, {
int ok = 0;
struct linked_list* alist;
alist = list_create();
if (alist) ok = 1;
list_destroy(alist);
return ok;
});
EXO_TEST(list_create, {
list = list_create();
return list->size == 0;
});
EXO_TEST(list_append_1, {
list_append(list, (char*) A);
return list->size == 1;
});
EXO_TEST(list_remove_1, {
list_remove(list, (char*) A);
return list->size == 0;
});
EXO_TEST(list_append_2, {
list_append(list, A);
list_append(list, B);
return list->size == 2;
});
EXO_TEST(list_remove_2, {
list_remove(list, (char*) A);
return list->size == 1;
});
EXO_TEST(list_remove_3, {
list_remove(list, (char*) A); /* already removed, so should have no effect */
return list->size == 1;
});
EXO_TEST(list_remove_4, {
list_remove(list, (char*) B); /* already removed, so should have no effect */
return list->size == 0;
});
EXO_TEST(list_append_3, {
list_append(list, A);
list_append(list, B);
list_append(list, C);
return list->size == 3;
});
EXO_TEST(list_append_4, {
list_append(list, A); /* OK. adding the same one *AGAIN* */
return list->size == 4;
});
EXO_TEST(list_remove_5, {
list_remove(list, A); /* removing the first one. */
return list->size == 3;
});
EXO_TEST(list_get_index_1, {
return list_get_index(list, 0) == B;
});
EXO_TEST(list_get_index_2, {
return list_get_index(list, 1) == C;
});
EXO_TEST(list_get_index_3, {
return list_get_index(list, 2) == A;
});
EXO_TEST(list_get_index_4, {
return list_get_index(list, 3) == NULL;
});
EXO_TEST(list_get_first_1, {
return list_get_first(list) == B;
});
EXO_TEST(list_get_first_next_1, {
return list_get_next(list) == C;
});
EXO_TEST(list_get_first_next_2, {
return list_get_next(list) == A;
});
EXO_TEST(list_get_last_1, {
return list_get_last(list) == A;
});
EXO_TEST(list_get_last_prev_1, {
return list_get_prev(list) == C;
});
EXO_TEST(list_get_last_prev_2, {
return list_get_prev(list) == B;
});
EXO_TEST(list_get_last_prev_next_1, {
return list_get_next(list) == C;
});
EXO_TEST(list_clear, {
list_clear(list, &null_free);
return list->size == 0 && list->first == 0 && list->last == 0 && list->iterator == 0;
});
static int g_remove_flag = 0;
static void null_free_inc_flag(void* ptr)
{
(void) ptr;
g_remove_flag++;
}
EXO_TEST(list_remove_first_1_1,
{
list_append(list, A);
list_append(list, B);
list_append(list, C);
return list->size == 3;
});
EXO_TEST(list_remove_first_1_2,
{
g_remove_flag = 0;
list_remove_first(list, null_free_inc_flag);
return list->size == 2 && g_remove_flag == 1;
});
EXO_TEST(list_remove_first_1_3,
{
list_remove_first(list, NULL);
return list->size == 1;
});
EXO_TEST(list_remove_first_1_4,
{
list_remove_first(list, NULL);
return list->size == 0;
});
EXO_TEST(list_remove_first_1_5,
{
list_remove_first(list, NULL);
return list->size == 0;
});
EXO_TEST(list_append_list_1,
{
list_append(list, A);
list_append(list, B);
list_append(list, C);
list2 = list_create();
list_append(list2, A2);
list_append(list2, B2);
list_append(list2, C2);
return list->size == 3 && list2->size == 3;
});
EXO_TEST(list_append_list_2,
{
list_append_list(list, list2);
return list->size == 6 && list2->size == 0;
});
EXO_TEST(list_append_list_3,
{
list_destroy(list2);
return list_get_index(list, 0) == A &&
list_get_index(list, 1) == B &&
list_get_index(list, 2) == C &&
list_get_index(list, 3) == A2 &&
list_get_index(list, 4) == B2 &&
list_get_index(list, 5) == C2;
});
EXO_TEST(list_clear_list_last,
{
list_clear(list, &null_free);
return 1;
});
EXO_TEST(list_destroy_1, {
list_destroy(list);
return 1;
});
EXO_TEST(list_destroy_2, {
list_destroy(0);
return 1;
});
+37
View File
@@ -0,0 +1,37 @@
#include <uhub.h>
struct adc_message* g_msg;
EXO_TEST(test_message_refc_1, {
g_msg = adc_msg_create("IMSG Hello\\sWorld!");
return g_msg != NULL;
});
EXO_TEST(test_message_refc_2, {
return g_msg->references == 1;
});
EXO_TEST(test_message_refc_3, {
adc_msg_incref(g_msg);
return g_msg->references == 2;
});
EXO_TEST(test_message_refc_4, {
adc_msg_incref(g_msg);
return g_msg->references == 3;
});
EXO_TEST(test_message_refc_5, {
adc_msg_free(g_msg);
return g_msg->references == 2;
});
EXO_TEST(test_message_refc_6, {
adc_msg_free(g_msg);
return g_msg->references == 1;
});
EXO_TEST(test_message_refc_7, {
adc_msg_free(g_msg);
return 1;
});
+581
View File
@@ -0,0 +1,581 @@
#include <uhub.h>
static struct hub_user* g_user = 0;
static const char* test_string1 = "IINF AAfoo BBbar CCwhat\n";
static const char* test_string2 = "BMSG AAAB Hello\\sWorld!\n";
static const char* test_string3 = "BINF AAAB IDAN7ZMSLIEBL53OPTM7WXGSTXUS3XOY6KQS5LBGX NIFriend DEstuff SL3 SS0 SF0 VEQuickDC/0.4.17 US6430 SUADC0,TCP4,UDP4 I4127.0.0.1 HO5 HN1 AW\n";
static const char* test_string4 = "BMSG AAAB\n";
static const char* test_string5 = "BMSG AAAB \n";
static void create_test_user()
{
if (g_user)
return;
g_user = (struct hub_user*) malloc(sizeof(struct hub_user));
memset(g_user, 0, sizeof(struct hub_user));
memcpy(g_user->id.nick, "exotic-tester", 13);
g_user->id.sid = 1;
}
EXO_TEST(adc_message_first, {
create_test_user();
return g_user != 0;
});
EXO_TEST(adc_message_parse_1, {
struct adc_message* msg = adc_msg_create("IMSG Hello\\sWorld!");
int ok = msg != NULL;
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_parse_2, {
struct adc_message* msg = adc_msg_create(test_string2);
int ok = (msg != NULL);
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_parse_3, {
struct adc_message* msg = adc_msg_parse_verify(g_user, "BMSG AAAB Hello\\sWorld!", 23);
int ok = msg != NULL;
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_parse_4, {
struct adc_message* msg = adc_msg_parse_verify(g_user, "BMSG AAAC Hello\\sWorld!", 23);
return msg == NULL;
});
EXO_TEST(adc_message_parse_5, {
struct adc_message* msg = adc_msg_parse_verify(g_user, "BMSG AAAB Hello\\sWorld!\n", 24);
int ok = msg != NULL;
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_parse_6, {
struct adc_message* msg = adc_msg_parse_verify(g_user, "FMSG AAAB +TCP4 Hello\\sWorld!\n", 30);
int ok = msg != NULL;
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_parse_7, {
struct adc_message* msg = adc_msg_parse_verify(g_user, "FMSG AAAB -TCP4 Hello\\sWorld!\n", 30);
int ok = msg != NULL;
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_parse_8, {
struct adc_message* msg = adc_msg_parse_verify(g_user, "FMSG AAAB +TCP4+UDP4 Hello\\sWorld!\n", 35);
int ok = msg != NULL;
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_parse_9, {
struct adc_message* msg = adc_msg_parse_verify(g_user, "FMSG AAAB +TCP4-UDP4 Hello\\sWorld!\n", 35);
int ok = msg != NULL;
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_parse_10, {
struct adc_message* msg = adc_msg_parse_verify(g_user, "FMSG AAAB -TCP4-UDP4 Hello\\sWorld!\n", 35);
int ok = msg != NULL;
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_parse_11, {
struct adc_message* msg = adc_msg_parse_verify(g_user, "FMSG AAAB Hello\\sWorld!\n", 24);
return msg == NULL;
});
EXO_TEST(adc_message_parse_12, {
struct adc_message* msg = adc_msg_parse_verify(g_user, "FMSG AAAB Hello\\sWorld!\n", 25);
return msg == NULL;
});
EXO_TEST(adc_message_parse_13, {
struct adc_message* msg = adc_msg_parse_verify(g_user, "FMSG AAAB +jalla Hello\\sWorld!\n", 31);
return msg == NULL;
});
EXO_TEST(adc_message_parse_14, {
struct adc_message* msg = adc_msg_parse_verify(g_user, "FMSG AAAB +jall Hello\\sWorld!\n", 30);
int ok = msg != NULL;
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_parse_15, {
struct adc_message* msg = adc_msg_parse_verify(g_user, "FMSG AAAB +TCP4 Hello\\sWorld!\n", 30);
int ok = msg != NULL;
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_parse_16, {
struct adc_message* msg = adc_msg_parse_verify(g_user, "BMSG AAAB Hello\\sWorld!\n", 24);
int ok = msg != NULL;
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_parse_17, {
struct adc_message* msg = adc_msg_parse_verify(g_user, "BMSG aaab Hello\\sWorld!\n", 24);
return msg == NULL;
});
EXO_TEST(adc_message_parse_18, {
struct adc_message* msg = adc_msg_parse_verify(g_user, "DMSG AAAB AAAC Hello\\sthere!\n", 29);
int ok = msg != NULL;
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_parse_19, {
struct adc_message* msg = adc_msg_parse_verify(g_user, "DMSG AAAC AAAB Hello\\sthere!\n", 29);
return msg == NULL;
});
EXO_TEST(adc_message_parse_20, {
struct adc_message* msg = adc_msg_parse_verify(g_user, "EMSG AAAB AAAC Hello\\sthere!\n", 29);
int ok = msg != NULL;
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_parse_21, {
struct adc_message* msg = adc_msg_parse_verify(g_user, "EMSG AAAC AAAB Hello\\sthere!\n", 29);
return msg == NULL;
});
EXO_TEST(adc_message_parse_22, {
struct adc_message* msg = adc_msg_parse_verify(g_user, "\n", 0);
return msg == NULL;
});
EXO_TEST(adc_message_parse_23, {
struct adc_message* msg = adc_msg_parse_verify(g_user, "\r\n", 1);
return msg == NULL;
});
EXO_TEST(adc_message_parse_24, {
struct adc_message* msg = adc_msg_parse_verify(g_user, "EMSG AAAC\0AAAB Hello\\sthere!\n", 29);
return msg == NULL;
});
EXO_TEST(adc_message_add_arg_1, {
int ok;
struct adc_message* msg = adc_msg_create(test_string1);
adc_msg_add_argument(msg, "XXwtf?");
ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat XXwtf?\n") == 0;
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_add_arg_2, {
int ok;
struct adc_message* msg = adc_msg_create(test_string1);
adc_msg_add_named_argument(msg, "XX", "wtf?");
ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat XXwtf?\n") == 0;
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_remove_arg_1, {
int ok;
struct adc_message* msg = adc_msg_create(test_string1);
adc_msg_remove_named_argument(msg, "AA");
ok = strcmp(msg->cache, "IINF BBbar CCwhat\n") == 0;
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_remove_arg_2, {
int ok;
struct adc_message* msg = adc_msg_create(test_string1);
adc_msg_remove_named_argument(msg, "BB");
ok = strcmp(msg->cache, "IINF AAfoo CCwhat\n") == 0;
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_remove_arg_3, {
int ok;
struct adc_message* msg = adc_msg_create(test_string1);
adc_msg_remove_named_argument(msg, "CC");
ok = strcmp(msg->cache, "IINF AAfoo BBbar\n") == 0;
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_remove_arg_4, {
/* this ensures we can remove the last element also */
int ok;
struct adc_message* msg = adc_msg_parse_verify(g_user, test_string3, strlen(test_string3));
adc_msg_remove_named_argument(msg, "AW");
ok = strcmp(msg->cache, "BINF AAAB IDAN7ZMSLIEBL53OPTM7WXGSTXUS3XOY6KQS5LBGX NIFriend DEstuff SL3 SS0 SF0 VEQuickDC/0.4.17 US6430 SUADC0,TCP4,UDP4 I4127.0.0.1 HO5 HN1\n") == 0;
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_replace_arg_1, {
int ok;
struct adc_message* msg = adc_msg_create(test_string1);
adc_msg_remove_named_argument(msg, "AA");
ok = strcmp(msg->cache, "IINF BBbar CCwhat\n") == 0;
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_replace_arg_2, {
int ok;
struct adc_message* msg = adc_msg_create(test_string1);
adc_msg_remove_named_argument(msg, "BB");
ok = strcmp(msg->cache, "IINF AAfoo CCwhat\n") == 0;
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_replace_arg_3, {
int ok;
struct adc_message* msg = adc_msg_create(test_string1);
adc_msg_remove_named_argument(msg, "CC");
ok = strcmp(msg->cache, "IINF AAfoo BBbar\n") == 0;
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_get_arg_1, {
int ok;
struct adc_message* msg = adc_msg_create(test_string1);
char* c = adc_msg_get_argument(msg, 0);
ok = strcmp(c, "AAfoo") == 0;
adc_msg_free(msg);
hub_free(c);
return ok;
});
EXO_TEST(adc_message_get_arg_2, {
int ok;
struct adc_message* msg = adc_msg_create(test_string1);
char* c = adc_msg_get_argument(msg, 1);
ok = strcmp(c, "BBbar") == 0;
adc_msg_free(msg);
hub_free(c);
return ok;
});
EXO_TEST(adc_message_get_arg_3, {
struct adc_message* msg = adc_msg_create(test_string1);
char* c = adc_msg_get_argument(msg, 2);
int ok = strcmp(c, "CCwhat") == 0;
adc_msg_free(msg);
hub_free(c);
return ok;
});
EXO_TEST(adc_message_get_arg_4, {
struct adc_message* msg = adc_msg_create(test_string1);
char* c = adc_msg_get_argument(msg, 3);
int ok = c == 0;
adc_msg_free(msg);
hub_free(c);
return ok;
});
EXO_TEST(adc_message_get_named_arg_1, {
struct adc_message* msg = adc_msg_create(test_string1);
char* c = adc_msg_get_named_argument(msg, "AA");
int ok = strcmp(c, "foo") == 0;
adc_msg_free(msg);
hub_free(c);
return ok;
});
EXO_TEST(adc_message_get_named_arg_2, {
struct adc_message* msg = adc_msg_create(test_string1);
char* c = adc_msg_get_named_argument(msg, "BB");
int ok = strcmp(c, "bar") == 0;
adc_msg_free(msg);
hub_free(c);
return ok;
});
EXO_TEST(adc_message_get_named_arg_3, {
struct adc_message* msg = adc_msg_create(test_string1);
char* c = adc_msg_get_named_argument(msg, "CC");
int ok = strcmp(c, "what") == 0;
adc_msg_free(msg);
hub_free(c);
return ok;
});
EXO_TEST(adc_message_get_named_arg_4, {
struct adc_message* msg = adc_msg_create(test_string1);
char* c = adc_msg_get_named_argument(msg, "XX");
int ok = c == 0;
adc_msg_free(msg);
hub_free(c);
return ok;
});
EXO_TEST(adc_message_has_named_arg_1, {
struct adc_message* msg = adc_msg_create(test_string1);
int n = adc_msg_has_named_argument(msg, "XX");
adc_msg_free(msg);
return n == 0;
});
EXO_TEST(adc_message_has_named_arg_2, {
struct adc_message* msg = adc_msg_create(test_string1);
int n = adc_msg_has_named_argument(msg, "BB");
adc_msg_free(msg);
return n == 1;
});
EXO_TEST(adc_message_has_named_arg_3, {
struct adc_message* msg = adc_msg_create(test_string1);
int n = adc_msg_has_named_argument(msg, "CC");
adc_msg_free(msg);
return n == 1;
});
EXO_TEST(adc_message_has_named_arg_4, {
int n;
struct adc_message* msg = adc_msg_create(test_string1);
adc_msg_add_argument(msg, "XXwtf?");
n = adc_msg_has_named_argument(msg, "XX");
adc_msg_free(msg);
return n == 1;
});
EXO_TEST(adc_message_has_named_arg_5, {
int n;
struct adc_message* msg = adc_msg_create(test_string1);
adc_msg_add_argument(msg, "XXone");
adc_msg_add_argument(msg, "XXtwo");
n = adc_msg_has_named_argument(msg, "XX");
adc_msg_free(msg);
return n == 2;
});
EXO_TEST(adc_message_has_named_arg_6, {
int n;
struct adc_message* msg = adc_msg_create(test_string1);
adc_msg_add_argument(msg, "XXone");
adc_msg_add_argument(msg, "XXtwo");
adc_msg_add_argument(msg, "XXthree");
n = adc_msg_has_named_argument(msg, "XX");
adc_msg_free(msg);
return n == 3;
});
EXO_TEST(adc_message_has_named_arg_7, {
struct adc_message* msg = adc_msg_create(test_string1);
int n = adc_msg_has_named_argument(msg, "AA");
adc_msg_free(msg);
return n == 1;
});
EXO_TEST(adc_message_terminate_1, {
int ok;
struct adc_message* msg = adc_msg_create("IINF AAfoo BBbar CCwhat");
adc_msg_unterminate(msg);
ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat") == 0;
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_terminate_2, {
int ok;
struct adc_message* msg = adc_msg_create(test_string1);
adc_msg_unterminate(msg);
adc_msg_terminate(msg);
ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat\n") == 0;
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_terminate_3, {
int ok;
struct adc_message* msg = adc_msg_create(test_string1);
adc_msg_unterminate(msg);
adc_msg_terminate(msg);
adc_msg_unterminate(msg);
ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat") == 0;
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_terminate_4, {
int ok;
struct adc_message* msg = adc_msg_create(test_string1);
adc_msg_unterminate(msg);
adc_msg_terminate(msg);
adc_msg_terminate(msg);
ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat\n") == 0;
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_terminate_5, {
int ok;
struct adc_message* msg = adc_msg_create(test_string1);
adc_msg_terminate(msg);
adc_msg_terminate(msg);
ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat\n") == 0;
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_terminate_6, {
int ok;
struct adc_message* msg = adc_msg_create(test_string1);
adc_msg_unterminate(msg);
adc_msg_unterminate(msg);
ok = strcmp(msg->cache, "IINF AAfoo BBbar CCwhat") == 0;
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_escape_1, {
int ok;
char* s = adc_msg_escape(test_string1);
ok = strcmp(s, "IINF\\sAAfoo\\sBBbar\\sCCwhat\\n") == 0;
hub_free(s);
return ok;
});
EXO_TEST(adc_message_escape_2, {
char* s = adc_msg_escape(test_string1);
char* s2 = adc_msg_unescape(s);
int ok = strcmp(s2, test_string1) == 0;
hub_free(s);
hub_free(s2);
return ok;
});
EXO_TEST(adc_message_escape_3, {
char* s = adc_msg_unescape(test_string1);
int ok = strcmp(s, test_string1) == 0;
hub_free(s);
return ok;
});
EXO_TEST(adc_message_copy_1, {
struct adc_message* msg1 = adc_msg_create(test_string1);
struct adc_message* msg2 = adc_msg_copy(msg1);
int ok = strncmp(msg1->cache, msg2->cache, msg1->length) == 0;
adc_msg_free(msg1);
adc_msg_free(msg2);
return ok;
});
EXO_TEST(adc_message_copy_2, {
struct adc_message* msg1 = adc_msg_parse_verify(g_user, test_string2, strlen(test_string2));
struct adc_message* msg2 = adc_msg_copy(msg1);
int ok = msg1->source == msg2->source;
adc_msg_free(msg1);
adc_msg_free(msg2);
return ok;
});
EXO_TEST(adc_message_copy_3, {
struct adc_message* msg1 = adc_msg_parse_verify(g_user, test_string2, strlen(test_string2));
struct adc_message* msg2 = adc_msg_copy(msg1);
int ok = ( msg1->cmd == msg2->cmd &&
msg1->source == msg2->source &&
msg1->target == msg2->target &&
msg1->length == msg2->length &&
msg1->priority == msg2->priority &&
msg1->capacity == msg2->capacity && /* might not be true! */
strcmp(msg1->cache, msg2->cache) == 0);
adc_msg_free(msg1);
adc_msg_free(msg2);
return ok;
});
EXO_TEST(adc_message_copy_4, {
struct adc_message* msg1 = adc_msg_parse_verify(g_user, test_string2, strlen(test_string2));
struct adc_message* msg2 = adc_msg_copy(msg1);
int ok = msg2->target == 0;
adc_msg_free(msg1);
adc_msg_free(msg2);
return ok;
});
static struct adc_message* updater1 = NULL;
static struct adc_message* updater2 = NULL;
static const char* update_info1 = "BINF AAAB IDABCDEFGHIJKLMNOPQRSTUVWXYZ1234567ABCDEF NItester SL10 SS12817126127 SF4125 HN3 HR0 HO0 VE++\\s0.698 US104857600 DS81911808 SUTCP4,UDP4 I4127.0.0.1\n";
static const char* update_info2 = "BINF AAAB HN34 SF4126 SS12817526127\n";
EXO_TEST(adc_message_update_1, {
updater1 = adc_msg_parse_verify(g_user, update_info1, strlen(update_info1));
return updater1 != NULL;
});
EXO_TEST(adc_message_update_2, {
user_set_info(g_user, updater1);
return strcmp(g_user->info->cache, updater1->cache) == 0 && g_user->info == updater1;
});
EXO_TEST(adc_message_update_3, {
updater2 = adc_msg_parse_verify(g_user, update_info2, strlen(update_info2));
return updater2 != NULL;
});
EXO_TEST(adc_message_update_4, {
user_update_info(g_user, updater2);
return strlen(g_user->info->cache) == 159;
});
EXO_TEST(adc_message_update_4_cleanup, {
adc_msg_free(updater1);
updater1 = 0;
adc_msg_free(updater2);
updater2 = 0;
adc_msg_free(g_user->info);
g_user->info = 0;
return 1;
});
EXO_TEST(adc_message_empty_1, {
struct adc_message* msg = adc_msg_parse_verify(g_user, test_string2, strlen(test_string2));
int ok = adc_msg_is_empty(msg) == 0;
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_empty_2, {
struct adc_message* msg = adc_msg_parse_verify(g_user, test_string4, strlen(test_string4));
int ok = adc_msg_is_empty(msg);
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_empty_3, {
struct adc_message* msg = adc_msg_parse_verify(g_user, test_string5, strlen(test_string5));
int ok = adc_msg_is_empty(msg) == 0; /* arguably not empty, contains a space */
adc_msg_free(msg);
return ok;
});
EXO_TEST(adc_message_last, {
hub_free(g_user);
g_user = 0;
return g_user == 0;
});
+178
View File
@@ -0,0 +1,178 @@
#include <uhub.h>
EXO_TEST(is_num_0, { return is_num('0'); });
EXO_TEST(is_num_1, { return is_num('1'); });
EXO_TEST(is_num_2, { return is_num('2'); });
EXO_TEST(is_num_3, { return is_num('3'); });
EXO_TEST(is_num_4, { return is_num('4'); });
EXO_TEST(is_num_5, { return is_num('5'); });
EXO_TEST(is_num_6, { return is_num('6'); });
EXO_TEST(is_num_7, { return is_num('7'); });
EXO_TEST(is_num_8, { return is_num('8'); });
EXO_TEST(is_num_9, { return is_num('9'); });
EXO_TEST(is_num_10, { return !is_num('/'); });
EXO_TEST(is_num_11, { return !is_num(':'); });
EXO_TEST(is_space_1, { return is_space(' '); });
EXO_TEST(is_space_2, { return !is_space('\t'); });
EXO_TEST(is_white_space_1, { return is_white_space(' '); });
EXO_TEST(is_white_space_2, { return is_white_space('\t'); });
EXO_TEST(is_white_space_3, { return !is_white_space('A'); });
EXO_TEST(is_white_space_4, { return !is_white_space('!'); });
EXO_TEST(itoa_1, { return strcmp(uhub_itoa(0), "0") == 0; });
EXO_TEST(itoa_2, { return strcmp(uhub_itoa(1), "1") == 0; });
EXO_TEST(itoa_3, { return strcmp(uhub_itoa(-1), "-1") == 0; });
EXO_TEST(itoa_4, { return strcmp(uhub_itoa(255), "255") == 0; });
EXO_TEST(itoa_5, { return strcmp(uhub_itoa(-3), "-3") == 0; });
EXO_TEST(itoa_6, { return strcmp(uhub_itoa(-2147483647), "-2147483647") == 0; });
EXO_TEST(itoa_7, { return strcmp(uhub_itoa(2147483647), "2147483647") == 0; });
EXO_TEST(itoa_8, { return strcmp(uhub_itoa(-65536), "-65536") == 0; });
EXO_TEST(base32_valid_1, { return is_valid_base32_char('A'); });
EXO_TEST(base32_valid_2, { return is_valid_base32_char('B'); });
EXO_TEST(base32_valid_3, { return is_valid_base32_char('C'); });
EXO_TEST(base32_valid_4, { return is_valid_base32_char('D'); });
EXO_TEST(base32_valid_5, { return is_valid_base32_char('E'); });
EXO_TEST(base32_valid_6, { return is_valid_base32_char('F'); });
EXO_TEST(base32_valid_7, { return is_valid_base32_char('G'); });
EXO_TEST(base32_valid_8, { return is_valid_base32_char('H'); });
EXO_TEST(base32_valid_9, { return is_valid_base32_char('I'); });
EXO_TEST(base32_valid_10, { return is_valid_base32_char('J'); });
EXO_TEST(base32_valid_11, { return is_valid_base32_char('K'); });
EXO_TEST(base32_valid_12, { return is_valid_base32_char('L'); });
EXO_TEST(base32_valid_13, { return is_valid_base32_char('M'); });
EXO_TEST(base32_valid_14, { return is_valid_base32_char('N'); });
EXO_TEST(base32_valid_15, { return is_valid_base32_char('O'); });
EXO_TEST(base32_valid_16, { return is_valid_base32_char('P'); });
EXO_TEST(base32_valid_17, { return is_valid_base32_char('Q'); });
EXO_TEST(base32_valid_18, { return is_valid_base32_char('R'); });
EXO_TEST(base32_valid_19, { return is_valid_base32_char('S'); });
EXO_TEST(base32_valid_20, { return is_valid_base32_char('T'); });
EXO_TEST(base32_valid_21, { return is_valid_base32_char('U'); });
EXO_TEST(base32_valid_22, { return is_valid_base32_char('V'); });
EXO_TEST(base32_valid_23, { return is_valid_base32_char('W'); });
EXO_TEST(base32_valid_24, { return is_valid_base32_char('X'); });
EXO_TEST(base32_valid_25, { return is_valid_base32_char('Y'); });
EXO_TEST(base32_valid_26, { return is_valid_base32_char('Z'); });
EXO_TEST(base32_valid_27, { return is_valid_base32_char('2'); });
EXO_TEST(base32_valid_28, { return is_valid_base32_char('3'); });
EXO_TEST(base32_valid_29, { return is_valid_base32_char('4'); });
EXO_TEST(base32_valid_30, { return is_valid_base32_char('5'); });
EXO_TEST(base32_valid_31, { return is_valid_base32_char('6'); });
EXO_TEST(base32_valid_32, { return is_valid_base32_char('7'); });
EXO_TEST(base32_invalid_1, { return !is_valid_base32_char('a'); });
EXO_TEST(base32_invalid_2, { return !is_valid_base32_char('b'); });
EXO_TEST(base32_invalid_3, { return !is_valid_base32_char('c'); });
EXO_TEST(base32_invalid_4, { return !is_valid_base32_char('d'); });
EXO_TEST(base32_invalid_5, { return !is_valid_base32_char('e'); });
EXO_TEST(base32_invalid_6, { return !is_valid_base32_char('f'); });
EXO_TEST(base32_invalid_7, { return !is_valid_base32_char('g'); });
EXO_TEST(base32_invalid_8, { return !is_valid_base32_char('h'); });
EXO_TEST(base32_invalid_9, { return !is_valid_base32_char('i'); });
EXO_TEST(base32_invalid_10, { return !is_valid_base32_char('j'); });
EXO_TEST(base32_invalid_11, { return !is_valid_base32_char('k'); });
EXO_TEST(base32_invalid_12, { return !is_valid_base32_char('l'); });
EXO_TEST(base32_invalid_13, { return !is_valid_base32_char('m'); });
EXO_TEST(base32_invalid_14, { return !is_valid_base32_char('n'); });
EXO_TEST(base32_invalid_15, { return !is_valid_base32_char('o'); });
EXO_TEST(base32_invalid_16, { return !is_valid_base32_char('p'); });
EXO_TEST(base32_invalid_17, { return !is_valid_base32_char('q'); });
EXO_TEST(base32_invalid_18, { return !is_valid_base32_char('r'); });
EXO_TEST(base32_invalid_19, { return !is_valid_base32_char('s'); });
EXO_TEST(base32_invalid_20, { return !is_valid_base32_char('t'); });
EXO_TEST(base32_invalid_21, { return !is_valid_base32_char('u'); });
EXO_TEST(base32_invalid_22, { return !is_valid_base32_char('v'); });
EXO_TEST(base32_invalid_23, { return !is_valid_base32_char('w'); });
EXO_TEST(base32_invalid_24, { return !is_valid_base32_char('x'); });
EXO_TEST(base32_invalid_25, { return !is_valid_base32_char('y'); });
EXO_TEST(base32_invalid_26, { return !is_valid_base32_char('z'); });
EXO_TEST(base32_invalid_27, { return !is_valid_base32_char('0'); });
EXO_TEST(base32_invalid_28, { return !is_valid_base32_char('1'); });
EXO_TEST(base32_invalid_29, { return !is_valid_base32_char('8'); });
EXO_TEST(base32_invalid_30, { return !is_valid_base32_char('9'); });
EXO_TEST(base32_invalid_31, { return !is_valid_base32_char('@'); });
EXO_TEST(utf8_valid_1, { return is_valid_utf8("abcdefghijklmnopqrstuvwxyz"); });
EXO_TEST(utf8_valid_2, { return is_valid_utf8("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); });
EXO_TEST(utf8_valid_3, { return is_valid_utf8("0123456789"); });
static const char test_utf_seq_1[] = { 0x65, 0x00 }; // valid
static const char test_utf_seq_2[] = { 0xD8, 0x00 }; // invalid
static const char test_utf_seq_3[] = { 0x24, 0x00 }; // valid
static const char test_utf_seq_4[] = { 0xC2, 0x24, 0x00}; // invalid
static const char test_utf_seq_5[] = { 0xC2, 0xA2, 0x00}; // valid
static const char test_utf_seq_6[] = { 0xE2, 0x82, 0xAC, 0x00}; // valid
static const char test_utf_seq_7[] = { 0xC2, 0x32, 0x00}; // invalid
static const char test_utf_seq_8[] = { 0xE2, 0x82, 0x32, 0x00}; // invalid
static const char test_utf_seq_9[] = { 0xE2, 0x32, 0x82, 0x00}; // invalid
static const char test_utf_seq_10[] = { 0xF0, 0x9F, 0x98, 0x81, 0x00}; // valid
EXO_TEST(utf8_valid_4, { return is_valid_utf8(test_utf_seq_1); });
EXO_TEST(utf8_valid_5, { return !is_valid_utf8(test_utf_seq_2); });
EXO_TEST(utf8_valid_6, { return is_valid_utf8(test_utf_seq_3); });
EXO_TEST(utf8_valid_7, { return !is_valid_utf8(test_utf_seq_4); });
EXO_TEST(utf8_valid_8, { return is_valid_utf8(test_utf_seq_5); });
EXO_TEST(utf8_valid_9, { return is_valid_utf8(test_utf_seq_6); });
EXO_TEST(utf8_valid_10, { return !is_valid_utf8(test_utf_seq_7); });
EXO_TEST(utf8_valid_11, { return !is_valid_utf8(test_utf_seq_8); });
EXO_TEST(utf8_valid_12, { return !is_valid_utf8(test_utf_seq_9); });
EXO_TEST(utf8_valid_13, { return is_valid_utf8(test_utf_seq_10); });
// Limits of utf-8
static const char test_utf_seq_11[] = { 0x7F, 0x00 }; // valid last 7-bit character
static const char test_utf_seq_12[] = { 0x80, 0x00 }; // invalid truncated string
static const char test_utf_seq_13[] = { 0xBF, 0x00 }; // invalid truncated string
static const char test_utf_seq_14[] = { 0xC0, 0x80, 0x00 }; // invalid out of 2 bytes range
static const char test_utf_seq_15[] = { 0xC1, 0x7F, 0x00 }; // invalid out of 2 bytes range
static const char test_utf_seq_16[] = { 0xC2, 0x00 }; // invalid truncated string
static const char test_utf_seq_17[] = { 0xC2, 0x80, 0x00 }; // valid
static const char test_utf_seq_18[] = { 0xDF, 0xBF, 0x00 }; // valid
static const char test_utf_seq_19[] = { 0xE0, 0x80, 0x80, 0x00 }; // invalid out of 3 bytes range
static const char test_utf_seq_20[] = { 0xE0, 0x9F, 0xBF, 0x00 }; // invalid out of 3 bytes range
static const char test_utf_seq_21[] = { 0xE0, 0x00 }; // invalid truncated string
static const char test_utf_seq_22[] = { 0xE0, 0xA0, 0x00 }; // invalid truncated string
static const char test_utf_seq_23[] = { 0xE0, 0xA0, 0x80, 0x00 }; // valid
static const char test_utf_seq_24[] = { 0xEC, 0x9F, 0xBF, 0x00 }; // valid
static const char test_utf_seq_25[] = { 0xED, 0xA0, 0x80, 0x00 }; // invalid surrogate
static const char test_utf_seq_26[] = { 0xED, 0xBF, 0xBF, 0x00 }; // invalid surrogate
static const char test_utf_seq_27[] = { 0xEF, 0x80, 0x80, 0x00 }; // valid
static const char test_utf_seq_28[] = { 0xEF, 0xBF, 0xBF, 0x00 }; // valid
static const char test_utf_seq_29[] = { 0xF0, 0x80, 0x80, 0x80, 0x00 }; // invalid out of 4 bytes range
static const char test_utf_seq_30[] = { 0xF0, 0x8F, 0xBF, 0xBF, 0x00 }; // invalid out of 4 bytes range
static const char test_utf_seq_31[] = { 0xF0, 0x00 }; // invalid truncated string
static const char test_utf_seq_32[] = { 0xF0, 0x90, 0x00 }; // invalid truncated string
static const char test_utf_seq_33[] = { 0xF0, 0x90, 0x80, 0x00 }; // invalid truncated string
static const char test_utf_seq_34[] = { 0xF0, 0x90, 0x80, 0x80, 0x00 }; // valid
static const char test_utf_seq_35[] = { 0xF4, 0x8F, 0xBF, 0xBF, 0x00 }; // valid
static const char test_utf_seq_36[] = { 0xF4, 0x90, 0x80, 0x80, 0x00 }; // invalid out of 4 bytes range
static const char test_utf_seq_37[] = { 0xFF, 0xBF, 0xBF, 0xBF, 0x00 }; // invalid out of 4 bytes range
EXO_TEST(utf8_valid_14, { return is_valid_utf8(test_utf_seq_11); });
EXO_TEST(utf8_valid_15, { return !is_valid_utf8(test_utf_seq_12); });
EXO_TEST(utf8_valid_16, { return !is_valid_utf8(test_utf_seq_13); });
EXO_TEST(utf8_valid_17, { return !is_valid_utf8(test_utf_seq_14); });
EXO_TEST(utf8_valid_18, { return !is_valid_utf8(test_utf_seq_15); });
EXO_TEST(utf8_valid_19, { return !is_valid_utf8(test_utf_seq_16); });
EXO_TEST(utf8_valid_20, { return is_valid_utf8(test_utf_seq_17); });
EXO_TEST(utf8_valid_21, { return is_valid_utf8(test_utf_seq_18); });
EXO_TEST(utf8_valid_22, { return !is_valid_utf8(test_utf_seq_19); });
EXO_TEST(utf8_valid_23, { return !is_valid_utf8(test_utf_seq_20); });
EXO_TEST(utf8_valid_24, { return !is_valid_utf8(test_utf_seq_21); });
EXO_TEST(utf8_valid_25, { return !is_valid_utf8(test_utf_seq_22); });
EXO_TEST(utf8_valid_26, { return is_valid_utf8(test_utf_seq_23); });
EXO_TEST(utf8_valid_27, { return is_valid_utf8(test_utf_seq_24); });
EXO_TEST(utf8_valid_28, { return !is_valid_utf8(test_utf_seq_25); });
EXO_TEST(utf8_valid_29, { return !is_valid_utf8(test_utf_seq_26); });
EXO_TEST(utf8_valid_30, { return is_valid_utf8(test_utf_seq_27); });
EXO_TEST(utf8_valid_31, { return is_valid_utf8(test_utf_seq_28); });
EXO_TEST(utf8_valid_32, { return !is_valid_utf8(test_utf_seq_29); });
EXO_TEST(utf8_valid_33, { return !is_valid_utf8(test_utf_seq_30); });
EXO_TEST(utf8_valid_34, { return !is_valid_utf8(test_utf_seq_31); });
EXO_TEST(utf8_valid_35, { return !is_valid_utf8(test_utf_seq_32); });
EXO_TEST(utf8_valid_36, { return !is_valid_utf8(test_utf_seq_33); });
EXO_TEST(utf8_valid_37, { return is_valid_utf8(test_utf_seq_34); });
EXO_TEST(utf8_valid_38, { return is_valid_utf8(test_utf_seq_35); });
EXO_TEST(utf8_valid_39, { return !is_valid_utf8(test_utf_seq_36); });
EXO_TEST(utf8_valid_40, { return !is_valid_utf8(test_utf_seq_37); });
+150
View File
@@ -0,0 +1,150 @@
#include <uhub.h>
#include <util/rbtree.h>
#define MAX_NODES 10000
static struct rb_tree* tree = NULL;
int test_tree_compare(const void* a, const void* b)
{
return strcmp((const char*) a, (const char*) b);
}
EXO_TEST(rbtree_create_destroy, {
int ok = 0;
struct rb_tree* atree;
atree = rb_tree_create(test_tree_compare, &hub_malloc, &hub_free);
if (atree) ok = 1;
rb_tree_destroy(atree);
return ok;
});
EXO_TEST(rbtree_create_1, {
tree = rb_tree_create(test_tree_compare, &hub_malloc, &hub_free);
return tree != NULL;
});
EXO_TEST(rbtree_size_0, { return rb_tree_size(tree) == 0; });
EXO_TEST(rbtree_insert_1, {
return rb_tree_insert(tree, "one", "1");
});
EXO_TEST(rbtree_insert_2, {
return rb_tree_insert(tree, "two", "2");
});
EXO_TEST(rbtree_insert_3, {
return rb_tree_insert(tree, "three", "3");
});
EXO_TEST(rbtree_insert_3_again, {
return !rb_tree_insert(tree, "three", "3-again");
});
EXO_TEST(rbtree_size_1, { return rb_tree_size(tree) == 3; });
static int test_check_search(const char* key, const char* expect)
{
const char* value = (const char*) rb_tree_get(tree, key);
if (!value) return !expect;
if (!expect) return 0;
return strcmp(value, expect) == 0;
}
EXO_TEST(rbtree_search_1, { return test_check_search("one", "1"); });
EXO_TEST(rbtree_search_2, { return test_check_search("two", "2"); });
EXO_TEST(rbtree_search_3, { return test_check_search("three", "3"); });
EXO_TEST(rbtree_search_4, { return test_check_search("four", NULL); });
EXO_TEST(rbtree_remove_1, {
return rb_tree_remove(tree, "one");
});
EXO_TEST(rbtree_size_2, { return rb_tree_size(tree) == 2; });
EXO_TEST(rbtree_remove_2, {
return rb_tree_remove(tree, "two");
});
EXO_TEST(rbtree_remove_3, {
return rb_tree_remove(tree, "three");
});
EXO_TEST(rbtree_remove_3_again, {
return !rb_tree_remove(tree, "three");
});
EXO_TEST(rbtree_search_5, { return test_check_search("one", NULL); });
EXO_TEST(rbtree_search_6, { return test_check_search("two", NULL); });
EXO_TEST(rbtree_search_7, { return test_check_search("three", NULL); });
EXO_TEST(rbtree_search_8, { return test_check_search("four", NULL); });
EXO_TEST(rbtree_size_3, { return rb_tree_size(tree) == 0; });
EXO_TEST(rbtree_insert_10000, {
int i;
for (i = 0; i < MAX_NODES; i++)
{
const char* key = strdup(uhub_itoa(i));
const char* val = strdup(uhub_itoa(i + 16384));
if (!rb_tree_insert(tree, key, val))
return 0;
}
return 1;
});
EXO_TEST(rbtree_size_4, { return rb_tree_size(tree) == MAX_NODES; });
EXO_TEST(rbtree_check_10000, {
int i;
for (i = 0; i < MAX_NODES; i++)
{
char* key = strdup(uhub_itoa(i));
const char* expect = uhub_itoa(i + 16384);
if (!test_check_search(key, expect))
return 0;
hub_free(key);
}
return 1;
});
EXO_TEST(rbtree_iterate_10000, {
int i = 0;
struct rb_node* n = (struct rb_node*) rb_tree_first(tree);
while (n)
{
n = (struct rb_node*) rb_tree_next(tree);
i++;
}
return i == MAX_NODES;
});
static int freed_nodes = 0;
static void free_node(struct rb_node* n)
{
hub_free((void*) n->key);
hub_free((void*) n->value);
freed_nodes += 1;
}
EXO_TEST(rbtree_remove_10000, {
int i;
int j;
for (j = 0; j < 2; j++)
{
for (i = j; i < MAX_NODES; i += 2)
{
const char* key = uhub_itoa(i);
rb_tree_remove_node(tree, key, &free_node);
}
}
return freed_nodes == MAX_NODES;
});
EXO_TEST(rbtree_destroy_1, {
rb_tree_destroy(tree);
return 1;
});
+138
View File
@@ -0,0 +1,138 @@
#include <uhub.h>
static struct sid_pool* sid_pool = 0;
struct dummy_user
{
sid_t sid;
};
static struct dummy_user* last = 0;
sid_t last_sid = 0;
EXO_TEST(sid_create_pool, {
sid_pool = sid_pool_create(4);
return sid_pool != 0;
});
EXO_TEST(sid_check_0a, {
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, 0);
return user == 0;
});
EXO_TEST(sid_check_0b, {
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, 5);
return user == 0;
});
EXO_TEST(sid_alloc_1, {
struct dummy_user* user = hub_malloc_zero(sizeof(struct dummy_user));
user->sid = sid_alloc(sid_pool, (struct hub_user*) user);
last = user;
last_sid = user->sid;
return (user->sid > 0 && user->sid < 1048576);
});
EXO_TEST(sid_check_1a, {
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, last_sid);
return last == user;
});
EXO_TEST(sid_check_1b, {
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, last_sid+1);
return user == 0;
});
EXO_TEST(sid_alloc_2, {
struct dummy_user* user = hub_malloc_zero(sizeof(struct dummy_user));
user->sid = sid_alloc(sid_pool, (struct hub_user*) user);
last_sid = user->sid;
return (user->sid > 0 && user->sid < 1048576);
});
EXO_TEST(sid_check_2, {
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, last_sid);
return last != user;
});
EXO_TEST(sid_alloc_3, {
struct dummy_user* user = hub_malloc_zero(sizeof(struct dummy_user));
user->sid = sid_alloc(sid_pool, (struct hub_user*) user);
last_sid = user->sid;
return (user->sid > 0 && user->sid < 1048576);
});
EXO_TEST(sid_check_3, {
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, last_sid);
return last != user;
});
EXO_TEST(sid_alloc_4, {
struct dummy_user* user = hub_malloc_zero(sizeof(struct dummy_user));
user->sid = sid_alloc(sid_pool, (struct hub_user*) user);
last_sid = user->sid;
return (user->sid > 0 && user->sid < 1048576);
});
EXO_TEST(sid_check_4, {
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, last_sid);
return last != user;
});
EXO_TEST(sid_alloc_5, {
struct dummy_user user;
sid_t sid;
sid = sid_alloc(sid_pool, (struct hub_user*) &user);
return sid == 0;
});
EXO_TEST(sid_check_6, {
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, 0);
return user == 0;
});
EXO_TEST(sid_list_all_1, {
sid_t s;
size_t n = 0;
int ok = 1;
for (s = last->sid; s <= last_sid; s++)
{
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, s);
if (s != (user ? user->sid : -1))
{
ok = 0;
break;
}
n++;
}
return ok && n == 4;
});
#define FREE_SID(N) \
struct dummy_user* user = (struct dummy_user*) sid_lookup(sid_pool, N); \
sid_free(sid_pool, N); \
hub_free(user); \
return sid_lookup(sid_pool, N) == NULL;
EXO_TEST(sid_remove_1, {
FREE_SID(2);
});
EXO_TEST(sid_remove_2, {
FREE_SID(1);
});
EXO_TEST(sid_remove_3, {
FREE_SID(4);
});
EXO_TEST(sid_remove_4, {
FREE_SID(3);
});
EXO_TEST(sid_destroy_pool, {
sid_pool_destroy(sid_pool);
sid_pool = 0;
return sid_pool == 0;
});
+69
View File
@@ -0,0 +1,69 @@
#include <uhub.h>
#define DEBUG_HASH
static char* byte_to_hex(char* dest, uint8_t c)
{
static const char* hexchars = "0123456789abcdef";
*dest = hexchars[c / 16]; dest++;
*dest = hexchars[c % 16]; dest++;
return dest;
}
static int test_tiger_hex(char* input, char* expected) {
char buf[TIGERSIZE*2+1];
uint64_t tiger_res[3];
int i = 0;
#ifdef DEBUG_HASH
int res = 0;
#endif
char* ptr = buf;
buf[TIGERSIZE*2] = 0;
tiger((uint64_t*) input, strlen(input), (uint64_t*) tiger_res);
for (i = 0; i < TIGERSIZE; i++)
ptr = byte_to_hex(ptr, (char) (((uint8_t*) tiger_res)[i]) );
#ifdef DEBUG_HASH
res = strcasecmp(buf, expected) == 0 ? 1 : 0;
if (!res)
{
printf("Expected: '%s', Got: '%s'\n", expected, buf);
}
return res;
#else
return strcasecmp(buf, expected) == 0;
#endif
}
EXO_TEST(hash_tiger_1, {
return test_tiger_hex("", "3293AC630C13F0245F92BBB1766E16167A4E58492DDE73F3");
});
EXO_TEST(hash_tiger_2, {
return test_tiger_hex("a", "77BEFBEF2E7EF8AB2EC8F93BF587A7FC613E247F5F247809");
});
EXO_TEST(hash_tiger_3, {
return test_tiger_hex("abc", "2AAB1484E8C158F2BFB8C5FF41B57A525129131C957B5F93");
});
EXO_TEST(hash_tiger_4, {
return test_tiger_hex("message digest", "D981F8CB78201A950DCF3048751E441C517FCA1AA55A29F6");
});
EXO_TEST(hash_tiger_5, {
return test_tiger_hex("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "0F7BF9A19B9C58F2B7610DF7E84F0AC3A71C631E7B53F78E");
});
EXO_TEST(hash_tiger_6, {
return test_tiger_hex("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "8DCEA680A17583EE502BA38A3C368651890FFBCCDC49A8CC");
});
EXO_TEST(hash_tiger_7, {
return test_tiger_hex("12345678901234567890123456789012345678901234567890123456789012345678901234567890", "1C14795529FD9F207A958F84C52F11E887FA0CABDFD91BFD");
});
+125
View File
@@ -0,0 +1,125 @@
#include <uhub.h>
#define MAX_EVENTS 15
static struct timeout_queue* g_queue;
static time_t g_now;
static size_t g_max;
static struct timeout_evt g_events[MAX_EVENTS];
static size_t g_triggered;
static void timeout_cb(struct timeout_evt* t)
{
g_triggered++;
}
/*
typedef void (*timeout_evt_cb)(struct timeout_evt*);
struct timeout_evt
{
time_t timestamp;
timeout_evt_cb callback;
void* ptr;
struct timeout_evt* prev;
struct timeout_evt* next;
};
void timeout_evt_initialize(struct timeout_evt*, timeout_evt_cb, void* ptr);
void timeout_evt_reset(struct timeout_evt*);
int timeout_evt_is_scheduled(struct timeout_evt*);
struct timeout_queue
{
time_t last;
size_t max;
struct timeout_evt** events;
};
void timeout_queue_initialize(struct timeout_queue*, time_t now, size_t max);
void timeout_queue_shutdown(struct timeout_queue*);
size_t timeout_queue_process(struct timeout_queue*, time_t now);
void timeout_queue_insert(struct timeout_queue*, struct timeout_evt*, size_t seconds);
void timeout_queue_remove(struct timeout_queue*, struct timeout_evt*);
void timeout_queue_reschedule(struct timeout_queue*, struct timeout_evt*, size_t seconds);
size_t timeout_queue_get_next_timeout(struct timeout_queue*, time_t now);
*/
EXO_TEST(timer_setup,{
size_t n;
g_queue = hub_malloc_zero(sizeof(struct timeout_queue));
g_now = 0;
g_max = 5;
g_triggered = 0;
timeout_queue_initialize(g_queue, g_now, g_max);
memset(g_events, 0, sizeof(g_events));
for (n = 0; n < MAX_EVENTS; n++)
{
timeout_evt_initialize(&g_events[n], timeout_cb, &g_events[n]);
}
return g_queue != NULL;
});
EXO_TEST(timer_check_timeout_0,{
return timeout_queue_get_next_timeout(g_queue, g_now) == g_max;
});
EXO_TEST(timer_add_event_1,{
timeout_queue_insert(g_queue, &g_events[0], 2);
return g_events[0].prev != NULL;
});
EXO_TEST(timer_check_timeout_1,{
return timeout_queue_get_next_timeout(g_queue, g_now) == 2;
});
EXO_TEST(timer_remove_event_1,{
timeout_queue_remove(g_queue, &g_events[0]);
return g_events[0].prev == NULL;
});
EXO_TEST(timer_check_timeout_2,{
return timeout_queue_get_next_timeout(g_queue, g_now) == g_max;
});
/* test re-removing an event - should not crash! */
EXO_TEST(timer_remove_event_1_no_crash,{
timeout_queue_remove(g_queue, &g_events[0]);
return g_events[0].prev == NULL;
});
EXO_TEST(timer_add_5_events_1,{
timeout_queue_insert(g_queue, &g_events[0], 0);
timeout_queue_insert(g_queue, &g_events[1], 1);
timeout_queue_insert(g_queue, &g_events[2], 2);
timeout_queue_insert(g_queue, &g_events[3], 3);
timeout_queue_insert(g_queue, &g_events[4], 4);
return (g_events[0].prev != NULL &&
g_events[1].prev != NULL &&
g_events[2].prev != NULL &&
g_events[3].prev != NULL &&
g_events[4].prev != NULL);
});
EXO_TEST(timer_check_5_events_1,{
return timeout_queue_get_next_timeout(g_queue, g_now) == 1;
});
EXO_TEST(timer_process_5_events_1,{
g_now = 4;
return timeout_queue_process(g_queue, g_now) == g_triggered;
});
EXO_TEST(timer_shutdown,{
timeout_queue_shutdown(g_queue);
hub_free(g_queue);
return 1;
});
+110
View File
@@ -0,0 +1,110 @@
#include <uhub.h>
#define SETUP(X, STR) struct cfg_tokens* tokens = cfg_tokenize(STR)
#define CLEANUP_LIST(X) do { list_clear(X, hub_free); list_destroy(X); } while(0)
#define CLEANUP_TOKENS(X) do { cfg_tokens_free(X); } while(0)
static int match_str(const char* str1, char* str2)
{
size_t i;
int ret;
for (i = 0; i < strlen(str2); i++)
if (str2[i] == '_')
str2[i] = ' ';
else if (str2[i] == '|')
str2[i] = '\t';
ret = strcmp(str1, str2);
if (ret) {
fprintf(stderr, "\n Mismatch: \"%s\" != \"%s\"\n", str1, str2);
}
return ret;
}
static int count(const char* STR, size_t EXPECT) {
SETUP(tokens, STR);
int pass = cfg_token_count(tokens) == EXPECT;
CLEANUP_TOKENS(tokens);
return pass;
}
static int compare(const char* str, const char* ref) {
size_t i, max;
int pass;
struct linked_list* compare = list_create();
SETUP(tokens, str);
split_string(ref, " ", compare, 0);
pass = cfg_token_count(tokens) == list_size(compare);
if (pass) {
max = cfg_token_count(tokens);
for (i = 0; i < max; i++) {
char* token = (char*) cfg_token_get(tokens, i);
char* refer = (char*) list_get_index(compare, i);
if (match_str(token, refer)) {
pass = 0;
break;
}
}
}
CLEANUP_TOKENS(tokens);
CLEANUP_LIST(compare);
return pass;
}
EXO_TEST(tokenizer_basic_0, { return count("", 0); });
EXO_TEST(tokenizer_basic_1, { return count("a", 1); });
EXO_TEST(tokenizer_basic_1a, { return count(" a", 1); })
EXO_TEST(tokenizer_basic_1b, { return count("\ta", 1); })
EXO_TEST(tokenizer_basic_1c, { return count(" a", 1); })
EXO_TEST(tokenizer_basic_1d, { return count(" a ", 1); })
EXO_TEST(tokenizer_basic_1e, { return count(" a ", 1); })
EXO_TEST(tokenizer_basic_2, { return count("a b", 2); });
EXO_TEST(tokenizer_basic_2a, { return count(" a b ", 2); });
EXO_TEST(tokenizer_basic_3, { return count("a b c", 3); });
EXO_TEST(tokenizer_basic_3a, { return count("a b c", 3); });
EXO_TEST(tokenizer_basic_3b, { return count("a b\tc", 3); });
EXO_TEST(tokenizer_basic_3c, { return count("a b c ", 3); });
EXO_TEST(tokenizer_basic_3d, { return count("a b c ", 3); });
EXO_TEST(tokenizer_basic_compare_0, { return compare("value1 value2 value3", "value1 value2 value3"); });
EXO_TEST(tokenizer_basic_compare_1, { return compare("a b c", "a b c"); });
EXO_TEST(tokenizer_basic_compare_2, { return compare("a b c", "a b c"); });
EXO_TEST(tokenizer_basic_compare_3, { return compare(" a b c", "a b c"); });
EXO_TEST(tokenizer_basic_compare_4, { return compare(" a b c ", "a b c"); });
EXO_TEST(tokenizer_basic_compare_5, { return compare("a b c ", "a b c"); });
EXO_TEST(tokenizer_basic_compare_6, { return compare("a b c ", "a b c"); });
EXO_TEST(tokenizer_comment_1, { return compare("value1 value2 # value3", "value1 value2"); });
EXO_TEST(tokenizer_comment_2, { return compare("value1 value2\\# value3", "value1 value2# value3"); });
EXO_TEST(tokenizer_comment_3, { return compare("value1 \"value2#\" value3", "value1 value2# value3"); });
EXO_TEST(tokenizer_escape_1, { return compare("\"value1\" value2", "value1 value2"); });
EXO_TEST(tokenizer_escape_2, { return compare("\"value1\\\"\" value2", "value1\" value2"); });
EXO_TEST(tokenizer_escape_3, { return compare("\"value1\" \"value 2\"", "value1 value_2"); });
EXO_TEST(tokenizer_escape_4, { return compare("\"value1\" value\\ 2", "value1 value_2"); });
EXO_TEST(tokenizer_escape_5, { return compare("\"value1\" value\\\\2", "value1 value\\2"); });
EXO_TEST(tokenizer_escape_6, { return compare("\"value1\" value\\\t2", "value1 value|2"); });
EXO_TEST(tokenizer_escape_7, { return compare("\"value1\" \"value\t2\"", "value1 value|2"); });
static int test_setting(const char* str, const char* expected_key, const char* expected_value)
{
int success = 0;
struct cfg_settings* setting = cfg_settings_split(str);
if (!setting) return expected_key == NULL;
success = (!strcmp(cfg_settings_get_key(setting), expected_key) && !strcmp(cfg_settings_get_value(setting), expected_value));
cfg_settings_free(setting);
return success;
}
EXO_TEST(tokenizer_settings_1, { return test_setting("foo=bar", "foo", "bar"); });
EXO_TEST(tokenizer_settings_2, { return test_setting("foo =bar", "foo", "bar"); });
EXO_TEST(tokenizer_settings_3, { return test_setting("foo= bar", "foo", "bar"); });
EXO_TEST(tokenizer_settings_4, { return test_setting("\tfoo=bar", "foo", "bar"); });
EXO_TEST(tokenizer_settings_5, { return test_setting("foo=bar\t", "foo", "bar"); });
EXO_TEST(tokenizer_settings_6, { return test_setting("\tfoo=bar\t", "foo", "bar"); });
EXO_TEST(tokenizer_settings_7, { return test_setting("\tfoo\t=\tbar\t", "foo", "bar"); });
EXO_TEST(tokenizer_settings_8, { return test_setting("foo=", "foo", ""); });
EXO_TEST(tokenizer_settings_9, { return test_setting("=bar", NULL, ""); });
+89
View File
@@ -0,0 +1,89 @@
#include <uhub.h>
#define MAX_USERS 64
static struct hub_user_manager* uman = 0;
static struct hub_user um_user[MAX_USERS];
EXO_TEST(um_init_1, {
sid_t s;
uman = uman_init();
for (s = 0; s < MAX_USERS; s++)
{
memset(&um_user[s], 0, sizeof(struct hub_user));
um_user[s].id.sid = s;
}
return !!uman;
});
EXO_TEST(um_shutdown_1, {
return uman_shutdown(0) == -1;
});
EXO_TEST(um_shutdown_2, {
return uman_shutdown(uman) == 0;
});
EXO_TEST(um_init_2, {
uman = uman_init();
return !!uman;
});
EXO_TEST(um_add_1, {
return uman_add(uman, &um_user[0]) == 0;
});
EXO_TEST(um_size_1, {
return uman->count == 1;
});
EXO_TEST(um_remove_1, {
return uman_remove(uman, &um_user[0]) == 0;
});
EXO_TEST(um_size_2, {
return uman->count == 0;
});
EXO_TEST(um_add_2, {
int i;
for (i = 0; i < MAX_USERS; i++)
{
if (uman_add(uman, &um_user[i]) != 0)
return 0;
}
return 1;
});
EXO_TEST(um_size_3, {
return uman->count == MAX_USERS;
});
EXO_TEST(um_remove_2, {
int i;
for (i = 0; i < MAX_USERS; i++)
{
if (uman_remove(uman, &um_user[i]) != 0)
return 0;
}
return 1;
});
/* Last test */
EXO_TEST(um_shutdown_4, {
return uman_shutdown(uman) == 0;
});
+43
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/
+10
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
+4
View File
@@ -0,0 +1,4 @@
#!/bin/sh
./exotic *.tcc > test.c
+78
View File
@@ -0,0 +1,78 @@
# - Try to find sqlite3
# Find sqlite3 headers, libraries and the answer to all questions.
#
# SQLITE3_FOUND True if sqlite3 got found
# SQLITE3_INCLUDEDIR Location of sqlite3 headers
# SQLITE3_LIBRARIES List of libaries to use sqlite3
# SQLITE3_DEFINITIONS Definitions to compile sqlite3
#
# Copyright (c) 2007 Juha Tuomala <tuju@iki.fi>
# Copyright (c) 2007 Daniel Gollub <gollub@b1-systems.de>
# Copyright (c) 2007 Alban Browaeys <prahal@yahoo.com>
#
# Redistribution and use is allowed according to the terms of the New
# BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
INCLUDE( FindPkgConfig )
# Take care about sqlite3.pc settings
IF ( Sqlite3_FIND_REQUIRED )
SET( _pkgconfig_REQUIRED "REQUIRED" )
ELSE ( Sqlite3_FIND_REQUIRED )
SET( _pkgconfig_REQUIRED "" )
ENDIF ( Sqlite3_FIND_REQUIRED )
IF ( SQLITE3_MIN_VERSION )
PKG_SEARCH_MODULE( SQLITE3 ${_pkgconfig_REQUIRED} sqlite3>=${SQLITE3_MIN_VERSION} )
ELSE ( SQLITE3_MIN_VERSION )
pkg_search_module( SQLITE3 ${_pkgconfig_REQUIRED} sqlite3 )
ENDIF ( SQLITE3_MIN_VERSION )
# Look for sqlite3 include dir and libraries w/o pkgconfig
IF ( NOT SQLITE3_FOUND AND NOT PKG_CONFIG_FOUND )
FIND_PATH( _sqlite3_include_DIR sqlite3.h
PATHS
/opt/local/include/
/sw/include/
/usr/local/include/
/usr/include/
)
FIND_LIBRARY( _sqlite3_link_DIR sqlite3
PATHS
/opt/local/lib
/sw/lib
/usr/lib
/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}
/usr/local/lib
/usr/lib64
/usr/local/lib64
/opt/lib64
)
IF ( _sqlite3_include_DIR AND _sqlite3_link_DIR )
SET ( _sqlite3_FOUND TRUE )
ENDIF ( _sqlite3_include_DIR AND _sqlite3_link_DIR )
IF ( _sqlite3_FOUND )
SET ( SQLITE3_INCLUDE_DIRS ${_sqlite3_include_DIR} )
SET ( SQLITE3_LIBRARIES ${_sqlite3_link_DIR} )
ENDIF ( _sqlite3_FOUND )
# Report results
IF ( SQLITE3_LIBRARIES AND SQLITE3_INCLUDE_DIRS AND _sqlite3_FOUND )
SET( SQLITE3_FOUND 1 )
MESSAGE( STATUS "Found sqlite3: ${SQLITE3_LIBRARIES} ${SQLITE3_INCLUDE_DIRS}" )
ELSE ( SQLITE3_LIBRARIES AND SQLITE3_INCLUDE_DIRS AND _sqlite3_FOUND )
IF ( Sqlite3_FIND_REQUIRED )
MESSAGE( SEND_ERROR "Could NOT find sqlite3" )
ELSE ( Sqlite3_FIND_REQUIRED )
MESSAGE( STATUS "Could NOT find sqlite3" )
ENDIF ( Sqlite3_FIND_REQUIRED )
ENDIF ( SQLITE3_LIBRARIES AND SQLITE3_INCLUDE_DIRS AND _sqlite3_FOUND )
ENDIF ( NOT SQLITE3_FOUND AND NOT PKG_CONFIG_FOUND )
# Hide advanced variables from CMake GUIs
MARK_AS_ADVANCED( SQLITE3_LIBRARIES SQLITE3_INCLUDE_DIRS )
+25
View File
@@ -0,0 +1,25 @@
uhub (0.3.2-1) unstable; urgency=low
* Updated upstream version.
-- Jan Vidar Krey <janvidar@extatic.org> Mon, 30 May 2010 18:00:00 +0200
uhub (0.3.1-1) unstable; urgency=low
* Updated version number.
-- Jan Vidar Krey <janvidar@extatic.org> Mon, 04 Apr 2010 16:44:21 +0200
uhub (0.3.0-2) unstable; urgency=low
* Fixed init.d scripts.
* Fixed lintian warnings.
-- Jan Vidar Krey <janvidar@extatic.org> Tue, 26 Jan 2010 19:02:02 +0100
uhub (0.3.0-1) unstable; urgency=low
* Initial Release.
-- Jan Vidar Krey <janvidar@extatic.org> Tue, 26 Jan 2010 18:59:02 +0100
+1
View File
@@ -0,0 +1 @@
7
+24
View File
@@ -0,0 +1,24 @@
Source: uhub
Section: net
Priority: optional
Maintainer: Jan Vidar Krey <janvidar@extatic.org>
Build-Depends: debhelper (>= 7.0.0)
Standards-Version: 3.8.3.0
Package: uhub
Architecture: any
Depends: ${shlibs:Depends}
Description: High performance ADC p2p hub
uhub is a high performance peer-to-peer hub for the ADC network.
Its low memory footprint allows it to handle several thousand users on
high-end servers, or a small private hub on embedded hardware.
.
Key features:
- High performance and low memory usage
- IPv4 and IPv6 support
- Experimental SSL support (optional)
- Advanced access control support
- Easy configuration
.
Homepage: http://www.uhub.org/
+19
View File
@@ -0,0 +1,19 @@
uhub - High performance ADC p2p hub.
Copyright (C) 2010 Jan Vidar Krey <janvidar@extatic.org>
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/>.
On Debian GNU/Linux systems, the complete text of the GNU General Public
License can be found in `/usr/share/common-licenses/GPL'.
Vendored Executable
+45
View File
@@ -0,0 +1,45 @@
#!/usr/bin/make -f
# export DH_VERBOSE=1
makeopts := DESTDIR=$(shell pwd)/debian/uhub/ \
UHUB_PREFIX=$(shell pwd)/debian/uhub/usr \
RELEASE=YES SILENT=YES
build: build-stamp
build-stamp:
dh_testdir
make $(makeopts)
touch build-stamp
clean:
dh_testdir
dh_testroot
rm -f build-stamp
make clean
dh_clean
binary-indep: build
binary-arch: build
dh_testdir
dh_testroot
dh_prep
dh_installdirs
$(MAKE) install $(makeopts)
dh_installdocs
dh_installinit
dh_installlogrotate
dh_installman -A
dh_installchangelogs ChangeLog
dh_strip
dh_compress
dh_installdeb
dh_shlibdeps
dh_gencontrol
dh_md5sums
dh_builddeb
binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary
+4
View File
@@ -0,0 +1,4 @@
# uhub - high performance adc hub.
UHUB_ENABLE=0
+6
View File
@@ -0,0 +1,6 @@
etc/default
etc/init.d
etc/logrotate.d
etc/uhub
usr/bin
var/log/uhub
+5
View File
@@ -0,0 +1,5 @@
AUTHORS
README
BUGS
TODO
doc/getstarted.txt
+97
View File
@@ -0,0 +1,97 @@
#!/bin/sh
### BEGIN INIT INFO
# Provides: uhub
# Required-Start: $remote_fs $network
# Required-Stop: $remote_fs $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start daemon at boot time
# Description: Enable service provided by daemon.
### END INIT INFO
PATH=/sbin:/bin:/usr/sbin:/usr/bin
NAME=uhub
DESC="ADC hub"
DAEMON=/usr/bin/uhub
PIDFILE=/var/run/uhub/uhub.pid
LOGFILE=/var/log/uhub/uhub.log
SCRIPTNAME=/etc/init.d/uhub
DEFAULTFILE=/etc/default/uhub
[ -r $DEFAULTFILE ] && . $DEFAULTFILE
DAEMON_ENABLE="${UHUB_ENABLE}"
DAEMON_OPTS="-l ${LOGFILE} -f -p ${PIDFILE}"
test -x $DAEMON || exit 0
. /lib/lsb/init-functions
ulimit -n 65536
mkdir -p /var/run/uhub/
set -e
case "$1" in
start)
if [ "$DAEMON_ENABLE" != "true" ]; then
log_daemon_msg "Disabled $DESC" $NAME
log_end_msg 0
exit 0
fi
log_daemon_msg "Starting $DESC" $NAME
if ! start-stop-daemon --start --quiet --oknodo \
--pidfile $PIDFILE --exec $DAEMON -- $DAEMON_OPTS
then
log_end_msg 1
else
log_end_msg 0
fi
;;
stop)
log_daemon_msg "Stopping $DESC" $NAME
if start-stop-daemon --quiet --stop --oknodo --retry 30 --oknodo \
--pidfile $PIDFILE --exec $DAEMON
then
rm -f $PIDFILE
log_end_msg 0
else
log_end_msg 1
fi
;;
reload)
log_daemon_msg "Reloading $DESC configuration" $NAME
if start-stop-daemon --stop --signal 2 --oknodo --retry 30 --oknodo \
--quiet --pidfile $PIDFILE --exec $DAEMON
then
if start-stop-daemon --start --quiet \
--pidfile $PIDFILE --exec $DAEMON -- $DAEMON_OPTS ; then
log_end_msg 0
else
log_end_msg 1
fi
else
log_end_msg 1
fi
;;
restart|force-reload)
$0 stop
$0 start
;;
status)
status_of_proc $DAEMON $NAME && exit 0 || exit $?
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload|status}" >&2
exit 1
;;
esac
exit 0
+9
View File
@@ -0,0 +1,9 @@
/var/log/uhub/*.log
{
compress
size 10M
rotate 10
missingok
notifempty
}
+2
View File
@@ -0,0 +1,2 @@
doc/uhub.1
doc/uhub-passwd.1
+27
View File
@@ -0,0 +1,27 @@
#!/bin/sh
set -e
case "$1" in
configure)
chmod 0750 /var/log/uhub
if [ -x /etc/init.d/uhub ]; then
update-rc.d uhub defaults >/dev/null
if [ -x /usr/sbin/invoke-rc.d ]; then
invoke-rc.d uhub restart
else
/etc/init.d/uhub restart
fi
fi
;;
abort-upgrade|abort-remove|abort-deconfigure)
;;
*)
echo "postinst: error: unknown argument: $1" >&2
exit 1
;;
esac
+6
View File
@@ -0,0 +1,6 @@
#!/bin/sh -e
if [ "$1" = purge ]; then
update-rc.d uhub remove >/dev/null
fi
+10
View File
@@ -0,0 +1,10 @@
#!/bin/sh -e
if [ "$1" = remove ]; then
if command -v invoke-rc.d >/dev/null 2>&1; then
invoke-rc.d uhub stop || true
else
/etc/init.d/uhub stop
fi
fi
+256
View File
@@ -0,0 +1,256 @@
# Doxyfile 1.5.5-KDevelop
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = uHub
PROJECT_NUMBER = 0.2.0-alpha
OUTPUT_DIRECTORY =
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF = "The $name class" \
"The $name widget" \
"The $name file" \
is \
provides \
specifies \
contains \
represents \
a \
an \
the
ALWAYS_DETAILED_SEC = YES
INLINE_INHERITED_MEMB = YES
FULL_PATH_NAMES = NO
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = YES
JAVADOC_AUTOBRIEF = NO
QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
DETAILS_AT_TOP = YES
INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 8
ALIASES =
OPTIMIZE_OUTPUT_FOR_C = YES
OPTIMIZE_OUTPUT_JAVA = NO
OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO
BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO
SIP_SUPPORT = NO
IDL_PROPERTY_SUPPORT = YES
DISTRIBUTE_GROUP_DOC = NO
SUBGROUPING = YES
TYPEDEF_HIDES_STRUCT = NO
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = YES
EXTRACT_PRIVATE = YES
EXTRACT_STATIC = YES
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = YES
EXTRACT_ANON_NSPACES = NO
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = YES
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO
SORT_GROUP_NAMES = NO
SORT_BY_SCOPE_NAME = YES
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_DIRECTORIES = NO
SHOW_FILES = YES
SHOW_NAMESPACES = YES
FILE_VERSION_FILTER =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = YES
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = .
INPUT_ENCODING = UTF-8
FILE_PATTERNS = *.c \
*.h
RECURSIVE = YES
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS = autotest/*
EXCLUDE_SYMBOLS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS = *
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = YES
INLINE_SOURCES = YES
STRIP_CODE_COMMENTS = YES
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION = YES
REFERENCES_LINK_SOURCE = YES
USE_HTAGS = NO
VERBATIM_HEADERS = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = YES
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER =
HTML_STYLESHEET =
HTML_ALIGN_MEMBERS = YES
GENERATE_HTMLHELP = YES
GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs"
DOCSET_BUNDLE_ID = org.doxygen.Project
HTML_DYNAMIC_SECTIONS = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
BINARY_TOC = NO
TOC_EXPAND = YES
DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 4
GENERATE_TREEVIEW = NONE
TREEVIEW_WIDTH = 250
FORMULA_FONTSIZE = 10
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4wide
EXTRA_PACKAGES =
LATEX_HEADER =
PDF_HYPERLINKS = YES
USE_PDFLATEX = YES
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED =
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE = uhub.tag
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
MSCGEN_PATH =
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = YES
DOT_FONTNAME = FreeSans
DOT_FONTPATH =
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = NO
TEMPLATE_RELATIONS = NO
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
CALL_GRAPH = NO
CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = NO
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
DOT_PATH =
DOTFILE_DIRS =
DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 1000
DOT_TRANSPARENT = YES
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES
#---------------------------------------------------------------------------
# Configuration::additions related to the search engine
#---------------------------------------------------------------------------
SEARCHENGINE = NO
+91
View File
@@ -0,0 +1,91 @@
= Architecture of uHub =
uHub is single-threaded and handles network and timer events using the
libevent library.
For each state there is a read event (and sometimes a write event) and timeout
event in case an expected read (or write) event does not occur.
== Protocol overview ==
uHub "speaks" the ADC protocol, which works in short as follows:
(C = client, S = server aka uHub).
C: HSUP ADBASE
Client connects to hub and supplies a list of supported features to the hub.
S: ISUP ADBASE { }
Server responds with a list of supported features.
S: ISID xxxx
Server assigns a session-ID to the client (4 bytes, BASE32 encoded).
C: BINF xxxx (...)
Client sends information about itself, such as nick name, etc.
The hub will relay this information to all users, including the client.
S: BINF xxx1 NInick1 (...)
S: BINF xxx2 NInick2
S: (...)
S: BINF xxxx (client's own nick)
Client gets list of other clients, which ends with the client's own user info.
At this point the client is successfully logged into the hub.
== The hub architecture ==
Accepting new users
--------------------- -----------------
| Accept connection | <---------- | libevent loop |
--------------------- -----------------
|
V
--------------------- ------------
| Setup login timer | --+----> | Timeout? | <----+
--------------------- | ------------ |
| | | |
V | V |
--------------------- | --------------- |
| Receive 'HSUP' | --+----> | DISCONNECT! | |
--------------------- --------------- |
| ^ |
V | |
--------------------- | |
| Send 'ISUP', and | | |
| assign Session ID | | |
--------------------- | |
| | |
V | |
--------------------- | |
| Receive 'BINF' |-----------------+------------
+--| Validate message | ^
| --------------------- |
| | |
| V |
| --------------------- ---------------------
| | Send password | ------> | Reveive and check |
| | request, if needed| | password. |
| --------------------- ---------------------
| |
| |
| ------------------------ |
+->| Send welcome message |<--------------+
------------------------
|
V
------------------------
| Send user list to |
| newly accepted user. |
------------------------
|
V
------------------------
| User is logged in. |
| Announce to all. |
------------------------
+26
View File
@@ -0,0 +1,26 @@
How to compile:
---------------
See the official compiling howto: http://www.uhub.org/compile.php
Prerequisites
Before you try to compile µHub, please make sure the following prerequisites are met.
* GNU make
* gcc > 3.0 (or MinGW on Windows)
* Perl 5
* openssl > 0.9.8 (or use "make USE_SSL=NO")
* sqlite > 3.x
or read http://www.uhub.org/compile.php for more info.
Linux, Mac OSX, FreeBSD, NetBSD and OpenBSD
-------------------------------------------
Simply, run:
% make
If you have an old gcc compiler, try disabling pre-compiled headers like this:
gmake USE_PCH=NO
+76
View File
@@ -0,0 +1,76 @@
ADC protocol extensions supported:
STATUS: **** Not yet implemented.
the 'AUT0' extension (network connection auto detection extension).
Rationale: Detect if client is capable of initiating active connections.
After logging in:
Client -> 'HCHK 12345 ABCD'.
Server sends a UDP packet containing token to the client's IP address at the given port as shown in the INF message.
Server -> 'ICHK ABCD'
The server should send it from a UDP socket bound to the same port as the TCP server, which means the server will
have to listen to both TCP and UDP.
If client receives the packet, it knows it can receive UDP connections, and will advertise it in the INF message as
a supported feature.
If the client does not receive any UDP packets within a few seconds, it MAY try to reconfigure the router using
UPnP/ZeroConf, and issue a HCHK command to the server again.
If the client still doesn't receive any UDP packets, hole punching can be tried.
The server will send a UDP packet to the hub (using the port of the TCP server), and reissue the HCHK command.
The UDP packet SHOULD be echoed by the hub.
This UDP packet should contain simply 'HECH {cid} {token}' (Hub echo).
The hub should send a packet containing the token back:
'IECH {token} {host:port}', aswell as the same message via TCP.
If the client receives the message via UDP, it should now be able to determine the type of NAT.
If the client receives the message via TCP only it knows it has a firewall blocking incomming communication.
If the client does not receive the message, it should assume a firewall is blocking all UDP communication,
and resume in passive mode.
Requirements:
'AUT0' in the extensions message (SUP) for client and hub.
Server will also listen to UDP messages on the same port as the TCP port.
The server MUST now respond to the 'HCHK' command via TCP
The server MUST now respond to the 'HECH' command via UDP.
The client will always initiate communication.
-------------------------------------------------------------------------------
Syntax: HCHK {port} {token}
- port is a 16-bit port number where the client is listening for packets.
- token is 4 bytes base32 encoded data specified by the client.
Example:
Client: 'HCHK 1511 BACD' (tcp)
Server: 'ICHK BACD' (udp)
-------------------------------------------------------------------------------
Syntax: HECH {cid} {token}
- cid is the client ID.
- token is 4 bytes base32 encoded data specified by the client.
Example:
Client: 'HECH 3NGFVJUDBRHX2CYRJGQ5HACRDM5CTNLGZ36M64I BACD' (udp)
Server: 'IECH BACD 192.168.0.1:1512' (udp)
Server: 'IECH BACD 192.168.0.1:1512' (tcp)
Security considerations:
The hub must verify that IP address where the HECH command originated from
matches the IP address where the user with the given CID is connected from.
If the CID and IP does not match, or the CID is not used the hub MUST ignore
the request.
+67
View File
@@ -0,0 +1,67 @@
Getting started guide
---------------------
Unpack your binaries
Example:
% tar xzf uhub-0.2.6-linux-i386.tar.gz
% cd uhub-0.2.6
Copy the binary to /usr/local/bin
% sudo cp uhub /usr/local/bin
Create configuration files.
If no configuration files are created, uhub will use the default parameters, so you can skip this step if you are in a hurry to see it run.
As root, or use sudo.
% mkdir /etc/uhub
% cp doc/uhub.conf /etc/uhub
% cp doc/users.conf /etc/uhub
% echo "welcome to uhub" > /etc/uhub/motd.txt
Start the hub in the foreground for the first time. Shut it down, by pressing CTRL+C.
% uhub
Thu, 05 Feb 2009 00:48:04 +0000 INFO: Starting server, listening on :::1511...
Connect to the hub using an ADC client, use the address adc://localhost:1511, or replace localhost with the correct hostname or IP address.
NOTE: It is important to use the "adc://" prefix, and the port number when using DC++ and other ADC clients.
If you modify the configuration files in /etc/uhub you will have to notify uhub by sending a HUP signal.
% ps aux | grep uhub
% kill -HUP <pid of uhub>
Or, for the lazy people
% killall -HUP uhub
In order to run uhub as a daemon, start it with the -f switch which will make it fork into the background.
In addition, use the -l to specify a log file instead of stdout. One can also specify a specific user and/or group,
if one wishes to run uhub as a specific user using the -u and -g switches.
Example:
% uhub -f -l mylog.txt -u nobody -g nogroup
If you are planning to more than 1024 users on hub, you must increase the max number of file descriptors allowed.
This limit needs to be higher than the configured max_users in uhub.conf.
In linux can add the following lines to /etc/security/limits.conf (allows for ~4000 users)
* soft nofile 4096
* hard nofile 4096
Or, you can use (as root):
% ulimit -n 4096
You can interact with uhub in your hub main chat using the `!` prefix, followed by a command:
Example :
* to display help and the command you can use:
!help
Your mileage may vary -- Good luck!
+113
View File
@@ -0,0 +1,113 @@
#!/bin/sh
#
# chkconfig: - 91 35
# description: Starts and stops the Uhub ( http://www.uhub.org ) daemons on RHEL\CentOS \
# used to provide p2p network services.
#
# pidfile: /var/run/uhub.pid
# config: /etc/uhub/uhub.conf
# Source function library.
if [ -f /etc/init.d/functions ] ; then
. /etc/init.d/functions
elif [ -f /etc/rc.d/init.d/functions ] ; then
. /etc/rc.d/init.d/functions
else
exit 1
fi
# Avoid using root's TMPDIR
unset TMPDIR
# Source networking configuration.
. /etc/sysconfig/network
if [ -f /etc/sysconfig/uhub ]; then
. /etc/sysconfig/uhub
fi
# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 1
# Check that bin and uhub.conf exists.
[ -f $UHUBBINFILE ] || exit 6
[ -f /etc/uhub/uhub.conf ] || exit 6
RETVAL=0
start() {
KIND="Uhub"
echo -n $"Starting $KIND services: "
daemon $UHUBBINFILE $UHUBOPTIONS
RETVAL=$?
echo ""
return $RETVAL
}
stop() {
KIND="Uhub"
echo -n $"Shutting down $KIND services: "
killproc $UHUBBINFILE
RETVAL=$?
echo ""
return $RETVAL
}
restart() {
stop
start
}
reload() {
echo -n $"Reloading uhub.conf / user.conf file: "
killproc uhub -HUP
RETVAL=$?
echo ""
return $RETVAL
}
relog() {
echo -n $"Reopen main log file: "
killproc uhub -SIGHUP
RETVAL=$?
echo ""
return $RETVAL
}
rhstatus() {
status $UHUBBINFILE
RETVAL=$?
if [ $RETVAL -ne 0 ] ; then
return $RETVAL
fi
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
reload)
reload
;;
relog)
relog
;;
status)
rhstatus
;;
*)
echo $"Usage: $0 {start|stop|restart|reload|relog|status}"
exit 2
esac
exit $?
+14
View File
@@ -0,0 +1,14 @@
# Log rotate for Uhub
# see man logrotate
#
#
/var/log/uhub.log {
compress
size 10M
rotate 10
missingok
notifempty
}
+16
View File
@@ -0,0 +1,16 @@
# locate bin file
UHUBBINFILE=/usr/bin/uhub
# Options to UHUB
# -v Verbose mode. Add more -v's for higher verbosity.
# -q Quiet mode - no output
# -f Fork to background
# -l <file> Log messages to given file (default: stderr)
# -L Log messages to syslog
# -c <file> Specify configuration file (default: /etc/uhub/uhub.conf)
# -S Show configuration parameters, but ignore defaults
# -u <user> Run as given user
# -g <group> Run with given group permissions
# -p <file> Store pid in file (process id)
UHUBOPTIONS=" -u uhub -f -p /var/run/uhub.pid -l /var/log/uhub.log"
+71
View File
@@ -0,0 +1,71 @@
# ATTENTION!
# Plugins are invoked in the order of listing in the plugin config file.
# Sqlite based user authentication.
#
# This plugin provides a Sqlite based authentication database for
# registered users.
# Use the uhub-passwd utility to create the database and add/remove users.
#
# Parameters:
# file: path/filename for database.
#
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
#
# Parameters:
# file: path/filename for log file.
# syslog: if true then syslog is used instead of writing to a file (Unix only)
plugin /usr/lib/uhub/mod_logging.so "file=/var/log/uhub.log"
# A simple example plugin
#plugin /usr/lib/uhub/mod_example.so
# A plugin sending a welcome message.
#
# This plugin provides the following commands:
# !motd - Message of the day
# !rules - Show hub rules.
#
# Parameters:
# motd: path/filename for the welcome message (message of the day)
# 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.
#
# The motd/rules files can do the following substitutions:
# %n - Nickname of the user who entered the hub or issued the command.
# %a - IP address of the user
# %c - The credentials of the user (guest, user, op, super, admin).
# %% - Becomes '%'
# %H - Hour 24-hour format (00-23) (Hub local time)
# %I - Hour 12-hour format (01-12) (Hub local time)
# %P - 'AM' or 'PM'
# %p - 'am' or 'pm'
# %M - Minutes (00-59) (Hub local time)
# %S - Seconds (00-60) (Hub local time)
plugin /usr/lib/uhub/mod_welcome.so "motd=/etc/uhub/motd.txt rules=/etc/uhub/rules.txt"
# Load the chat history plugin.
#
# This plugin provides chat history when users are connecting, or
# when users invoke the !history command.
# The history command can optionally take a parameter to indicate how many lines of history is requested.
#
# Parameters:
# history_max: the maximum number of messages to keep in history
# history_default: when !history is provided without arguments, then this default number of messages are returned.
# history_connect: the number of chat history messages to send when users connect (0 = do not send any history)
plugin /usr/lib/uhub/mod_chat_history.so "history_max=200 history_default=10 history_connect=5"
+5
View File
@@ -0,0 +1,5 @@
1. rule #1
2. rule #2
3. rule #3
......
34. Rule #34
+42
View File
@@ -0,0 +1,42 @@
.TH UHUB-PASSWD "1" "May 2012"
.SH NAME
uhub-passwd \- small utility for manipulating passwords which are
used by uhub daemon
.SH SYNOPSIS
.B uhub-passwd
\fIfilename command \fR[...]
.SH DESCRIPTION
uHub is a high performance peer-to-peer hub for the ADC network.
Its low memory footprint allows it to handle several thousand users
on high-end servers, or a small private hub on embedded hardware.
.SH "OPTIONS"
.TP
.BI \^create
.TP
.BI \^add " username password [credentials = user]"
.TP
.BI \^del " username"
.TP
.BI \^mod " username credentials"
.TP
.BI \^pass " username password"
.TP
.BI \^list
.SH "PARAMETERS"
.TP
.B 'filename'
is a database file
.TP
.B 'username'
is a nickname (UTF\-8, up to 64 bytes)
.TP
.B 'password'
is a password (UTF\-8, up to 64 bytes)
.TP
.B 'credentials'
is one of 'admin', 'super', 'op', 'user'
.SH AUTHOR
This program was written by Jan Vidar Krey <janvidar@extatic.org>
.SH "BUG REPORTS"
If you find a bug in uhub please report it to
.B https://github.com/janvidar/uhub/issues
+72
View File
@@ -0,0 +1,72 @@
.TH UHUB 1 "March 2009"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
.\" .nh disable hyphenation
.\" .hy enable hyphenation
.\" .ad l left justify
.\" .ad b justify to both left and right margins
.\" .nf disable filling
.\" .fi enable filling
.\" .br insert line break
.\" .sp <n> insert n+1 empty lines
.\" for manpage-specific macros, see man(7)
.SH NAME
uhub \- a high performance ADC peer-to-peer hub
.SH SYNOPSIS
.B uhub
.RI [ options ]
.SH DESCRIPTION
uHub is a high performance peer-to-peer hub for the ADC network.
Its low memory footprint allows it to handle several thousand users
on high-end servers, or a small private hub on embedded hardware.
.SH "OPTIONS"
.TP
.BI \^\-v
Verbose mode, add more \-v's for higher verbosity.
.TP
.BI \^\-q
Quiet mode, if quiet mode is enabled no output or logs are made.
.TP
.BI \^\-f
Fork uhub to background in order to run it as a daemon.
.TP
.BI \^\-l " logfile"
Log messages to the given logfile (default: stderr)
.TP
.BI \^\-L
Log messages to syslog.
.TP
.BI \^\-c " config"
Specify configuration file (default: /etc/uhub/uhub.conf)
.TP
.BI \^\-C
Check configuration files and return. Will print either \"OK\" or \"ERROR\".
.TP
.BI \^\-s
Show all configuration parameters. In a format that is compatible with
the configuration files.
.TP
.BI \^\-S
Show all non-default configuration parameters.
.TP
.BI \^\-h
Show the help message.
.TP
.BI \^\-u " user"
Drop privileges and run as the given user.
.TP
.BI \^\-g " group"
Drop privileges and run with the given group permissions.
.TP
.BI \^\-V
Show the version number
.SH EXAMPLES
To run uhub as a daemon, and log to a file:
.TP
.B uhub " -f -l /var/log/uhub/uhub.log"
.SH AUTHOR
This program was written by Jan Vidar Krey <janvidar@extatic.org>
.SH "BUG REPORTS"
If you find a bug in uhub please report it to
.B https://github.com/janvidar/uhub/issues
+124
View File
@@ -0,0 +1,124 @@
# uhub.conf - A example configuration file.
# You should normally place this file in /etc/uhub/uhub.conf
# and customize some of the settings below.
#
# This file is read only to the uhub deamon, and if you
# make changes to it while uhub is running you can send a
# HUP signal to it ( $ killall -HUP uhub ), to reparse configuration (only on UNIX).
# All configuration directives: http://www.uhub.org/config.php
# Bind to this port and address
# server_bind_addr=any means listen to "::" if IPv6 is supported
# by the host OS, otherwise 0.0.0.0.
server_port=1511
server_bind_addr=any
# Alternative server ports
# server_alt_ports = 1512, 1513
# The maximum amount of users allowed on the hub.
max_users=500
# If 1, will show a "Powered by uHub/{VERSION}".
show_banner=1
# If enabled then operating system and cpu architecture is part of the banner.
show_banner_sys_info=1
# Allow only registered users on the hub if set to 1.
registered_users_only=0
# A server name and description.
hub_name=my hub
hub_description=Powered by uHub
# Set this to 0, and the hub will disconnect everyone
hub_enabled=1
# Access control list (user database)
file_acl=/etc/uhub/users.conf
# This file can contain a conf for plugin subsystem
file_plugins = /etc/uhub/plugins.conf
# Slots/share/hubs limits
limit_max_hubs_user = 0
limit_max_hubs_reg = 0
limit_max_hubs_op = 0
limit_max_hubs = 0
limit_min_hubs_user = 0
limit_min_hubs_reg = 0
limit_min_hubs_op = 0
limit_min_share = 0
# Example:
# To require users to share at least 1 GB in order to enter the hub:
# limit_min_share = 1024
limit_max_share = 0
limit_min_slots = 0
limit_max_slots = 0
# Flood control support:
# set the interval to 5 seconds
flood_ctl_interval = 5
# Then the maximum chat, connect, search, updates etc will be measured over 5 seconds.
# So, 3 chat messages per 5 seconds allowed.
flood_ctl_chat=3
flood_ctl_connect=20
flood_ctl_search=1
flood_ctl_update=2
flood_ctl_extras=5
# chat control
# if chat_is_privileged=yes only registered users may write in main chat
chat_is_privileged = no
# if obsolete_clients=1 allows old clients to enter , 0 gives an error message (msg_proto_obsolete_adc0) if they try connect
# defaults obsolete_clients=1
obsolete_clients=1
# Configure status message as sent to clients in different circumstances.
msg_hub_full = Hub is full
msg_hub_disabled = Hub is disabled
msg_hub_registered_users_only = Hub is for registered users only
msg_inf_error_nick_missing = No nickname given
msg_inf_error_nick_multiple = Multiple nicknames given
msg_inf_error_nick_invalid = Nickname is invalid
msg_inf_error_nick_long = Nickname too long
msg_inf_error_nick_short = Nickname too short
msg_inf_error_nick_spaces = Nickname cannot start with spaces
msg_inf_error_nick_bad_chars = Nickname contains invalid characters
msg_inf_error_nick_not_utf8 = Nickname is not valid utf8
msg_inf_error_nick_taken = Nickname is already in use
msg_inf_error_nick_restricted = Nickname cannot be used on this hub
msg_inf_error_cid_invalid = CID is not valid
msg_inf_error_cid_missing = CID is not specified
msg_inf_error_cid_taken = CID is taken
msg_inf_error_pid_missing = PID is not specified
msg_inf_error_pid_invalid = PID is invalid
msg_ban_permanently = Banned permanently
msg_ban_temporarily = Banned temporarily
msg_auth_invalid_password = Password is wrong
msg_auth_user_not_found = User not found in password database
msg_user_share_size_low = User is not sharing enough
msg_user_share_size_high = User is sharing too much
msg_user_slots_low = User has too few upload slots
msg_user_slots_high = User has too many upload slots
msg_user_hub_limit_low = User is on too few hubs
msg_user_hub_limit_high = User is on too many hubs
msg_error_no_memory = Out of memory
msg_user_flood_chat = Chat flood detected, messages are dropped.
msg_user_flood_connect = Connect flood detected, connection refused.
msg_user_flood_search = Search flood detected, search is stopped.
msg_user_flood_update = Update flood detected.
msg_user_flood_extras = Flood detected.
# If a client that supports ADC but not a compatible hash algorithm (tiger),
# then the hub cannot accept the client:
msg_proto_no_common_hash = No common hash algorithm.
# Message to be shown to old clients using an older version of ADC than ADC/1.0
msg_proto_obsolete_adc0 = Client is using an obsolete ADC protocol version.
+59
View File
@@ -0,0 +1,59 @@
/**
* Overview of uHub
*/
digraph G
{
"main()" -> "event_dispatch()"
"event_dispatch()" -> "net_on_accept()"
"event_dispatch()" -> "net_on_read()"
"event_dispatch()" -> "net_on_write()"
"event_dispatch()" -> "event_queue_process()"
/* net events */
"net_on_write()" -> "net_send()"
"net_on_write()" -> "user_disconnect()"
"net_on_accept()" -> "user_create()"
"net_on_read()" -> "net_recv()"
"net_on_read()" -> "user_disconnect()"
"net_recv()" -> "hub_handle_message()"
/* adc message handling */
"hub_handle_message()" -> "hub_handle_password()"
"hub_handle_message()" -> "hub_handle_support()"
"hub_handle_password()" -> "user_disconnect()"
"hub_handle_support()" -> "user_disconnect()"
"hub_handle_password()" -> "route_to_user()"
"hub_handle_support()" -> "route_to_user()"
"hub_handle_message()" -> "hub_handle_info()"
"hub_handle_message()" -> "route_message()"
"hub_handle_info()" -> "route_to_user()"
"hub_handle_info()" -> "route_to_all()"
/* message routing, depending on message type */
"route_message()" -> "route_to_user()"
"route_message()" -> "route_to_all()" -> "route_to_user()"
"route_message()" -> "route_to_subscribers()" -> "route_to_user()"
"route_to_user()" -> "net_send()"
"route_to_user()" -> "queue_command()"
"route_to_user()" -> "user_disconnect()"
/* Message dispatcher */
"event_queue_process()" -> "hub_event_dispatcher()"
"hub_event_dispatcher()" -> "EVENT_USER_JOIN"
"hub_event_dispatcher()" -> "EVENT_USER_QUIT"
"EVENT_USER_QUIT" -> "route_to_all()"
"EVENT_USER_QUIT" -> "user_destroy()"
"EVENT_USER_JOIN" -> "route_to_all()"
/* user_disconnect() -- critical part */
"user_disconnect()" -> "user_set_state(state_cleanup)" -> "post: EVENT_USER_QUIT"
"user_disconnect()" -> "user_destroy()"
}
+42
View File
@@ -0,0 +1,42 @@
# Copyright 1999-2010 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: $
inherit eutils
if [ "$PV" != "9999" ]; then
SRC_URI="http://www.extatic.org/downloads/uhub/${P}-src.tar.bz2"
KEYWORDS="~amd64 ~x86"
else
inherit git
SRC_URI=""
EGIT_REPO_URI="git://github.com/janvidar/uhub.git"
KEYWORDS=""
fi
EAPI="2"
DESCRIPTION="High performance ADC hub"
HOMEPAGE="http://www.uhub.org/"
LICENSE="GPL-3"
SLOT="0"
IUSE="+ssl"
DEPEND="=dev-lang/perl-5*
ssl? ( >=dev-libs/openssl-0.9.8 )
"
RDEPEND="${DEPEND}"
src_compile() {
$opts=""
use ssl && opts="USE_SSL=YES $opts"
emake $opts
}
src_install() {
dodir /usr/bin
dodir /etc/uhub
emake DESTDIR="${D}" UHUB_PREFIX="${D}/usr" install || die "install failed"
newinitd doc/uhub.gentoo.rc uhub || newinitd ${FILESDIR}/uhub.rc uhub
}
pkg_postinst() {
enewuser uhub
}
+102
View File
@@ -0,0 +1,102 @@
Summary: High performance ADC p2p hub.
Name: uhub
Version: 0.4.0
Release: 2
License: GPLv3
Group: Networking/File transfer
Source: uhub-%{version}.tar.gz
URL: http://www.uhub.org
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
BuildRequires: sqlite-devel
BuildRequires: openssl-devel
%description
uhub is a high performance peer-to-peer hub for the ADC network.
Its low memory footprint allows it to handle several thousand users on
high-end servers, or a small private hub on embedded hardware.
Key features:
- High performance and low memory usage
- IPv4 and IPv6 support
- Experimental SSL support (optional)
- Advanced access control support
- Easy configuration
- plugin support
- mod_welcome - MOTD\RULES messages
- mod_auth_sipmle - auth with sqlite DB
- mod_logging - log hub activity
%prep
%setup -q -n %{name}-%{version}
%build
echo RPM_BUILD_ROOT = $RPM_BUILD_ROOT
make
%install
mkdir -p $RPM_BUILD_ROOT/usr/bin
mkdir -p $RPM_BUILD_ROOT/etc/uhub
mkdir -p $RPM_BUILD_ROOT/etc/init.d
mkdir -p $RPM_BUILD_ROOT/etc/logrotate.d
mkdir -p $RPM_BUILD_ROOT/etc/sysconfig
mkdir -p $RPM_BUILD_ROOT/usr/share/man/man1
mkdir -p $RPM_BUILD_ROOT/usr/lib/uhub
install uhub $RPM_BUILD_ROOT/usr/bin/
install uhub-passwd $RPM_BUILD_ROOT/usr/bin/
> doc/motd.txt
install -m644 doc/uhub.conf doc/users.conf doc/rules.txt doc/motd.txt doc/plugins.conf doc/users.db $RPM_BUILD_ROOT/etc/uhub
install doc/init.d.RedHat/etc/init.d/uhub $RPM_BUILD_ROOT/etc/init.d
install -m644 doc/init.d.RedHat/etc/sysconfig/uhub $RPM_BUILD_ROOT/etc/sysconfig/
install -m644 doc/init.d.RedHat/etc/logrotate.d/uhub $RPM_BUILD_ROOT/etc/logrotate.d/
/bin/gzip -9c doc/uhub.1 > doc/uhub.1.gz &&
install -m644 doc/uhub.1.gz $RPM_BUILD_ROOT/usr/share/man/man1
install -m644 mod_*.so $RPM_BUILD_ROOT/usr/lib/uhub
%files
%defattr(-,root,root)
%doc AUTHORS BUGS COPYING ChangeLog README TODO doc/Doxyfile doc/architecture.txt doc/compile.txt doc/extensions.txt doc/getstarted.txt doc/uhub.dot
%config(noreplace) /etc/uhub/uhub.conf
#%{_sysconfdir}/uhub/uhub.conf
%config(noreplace) %{_sysconfdir}/uhub/users.conf
%config(noreplace) %{_sysconfdir}/uhub/motd.txt
%config(noreplace) %{_sysconfdir}/uhub/rules.txt
%config(noreplace) %{_sysconfdir}/uhub/plugins.conf
%config(noreplace) %{_sysconfdir}/uhub/users.db
%{_sysconfdir}/init.d/uhub
%config(noreplace) %{_sysconfdir}/logrotate.d/uhub
%config(noreplace) %{_sysconfdir}/sysconfig/uhub
/usr/share/man/man1/uhub.1.gz
%{_bindir}/uhub
%{_libdir}/uhub/mod_*.so
%clean
rm -rf $RPM_BUILD_ROOT
%post
/sbin/chkconfig --add uhub
if [ $1 -gt 1 ] ; then
/etc/rc.d/init.d/uhub restart >/dev/null || :
fi
# need more informations about add services and users in system
/usr/sbin/adduser -M -d /tmp -G nobody -s /sbin/nologin -c 'The Uhub ADC p2p hub Daemon' uhub >/dev/null 2>&1 ||:
# write SSL create
echo "PLS see /usr/share/doc/uhub/"
%changelog
* Fri Dec 30 2011 E_zombie
- add users.db
- add new doc
* Tue Jun 26 2010 E_zombie
- add plugins.conf
* Tue Jan 31 2010 E_zombie
- change GROUP
- chmod for files
- add postinstall scripts
- fix "License"
* Tue Jan 26 2010 E_zombie
- first .spec release
+28
View File
@@ -0,0 +1,28 @@
# uHub - a lightweight but high-performance hub for the ADC
# peer-to-peer protocol.
description "uHub - High performance ADC peer-to-peer hub"
# Start and stop conditions.
start on filesystem or runlevel [2345]
stop on runlevel [!2345]
# Allow the service to respawn, but if its happening too often
# (10 times in 5 seconds) theres a problem and we should stop trying.
respawn
respawn limit 10 5
# The program is going to fork, and upstart needs to know this
# so it can track the change in PID.
expect fork
# Set the mode the process should create files in.
umask 022
# Make sure the log folder exists.
pre-start script
mkdir -p -m0755 /var/log/uhub
end script
# Command to run it.
exec /usr/bin/uhub -f -u uhub -g uhub -l /var/log/uhub/uhub.log -c /etc/uhub/uhub.conf
+51
View File
@@ -0,0 +1,51 @@
# uHub access control lists.
#
# Syntax: <command> [data]
#
# commands:
# 'user_reg' - registered user with no particular privileges (data=nick:password)
# 'user_op' - operator, can kick or ban people (data=nick:password)
# 'user_admin' - administrator, can do everything operators can, and reconfigure the hub (data=nick:password)
# 'deny_nick' - nick name that is not accepted (example; Administrator)
# 'deny_ip' - Unacceptable IP (masks can be specified as CIDR: 0.0.0.0/32 will block all IPv4)
# 'ban_nick' - banned user by nick
# 'ban_cid' - banned user by cid
# Administrator
# user_admin userA:password1
# user_op userB:password2
# We don't want users with these names
deny_nick Hub-Security
deny_nick Administrator
deny_nick root
deny_nick admin
deny_nick username
deny_nick user
deny_nick guest
deny_nick operator
# Banned users
# ban_nick H4X0R
# ban_cid FOIL5EK2UDZYAXT7UIUFEKL4SEBEAJE3INJDKAY
# ban by ip
#
# to ban by CIDR
# deny_ip 10.21.44.0/24
#
# to ban by IP-range.
# deny_ip 10.21.44.7-10.21.44.9
#
# to ban a single IP address
# deny_ip 10.21.44.7
# (which is equivalent to using):
# deny_ip 10.21.44.7/32
# Will not work, yet
# nat_ip 10.0.0.0/8
# nat_ip 127.0.0.0/8
# If you have made changes to this file, you must send a HANGUP signal
# to uHub so that it will re-read the configuration files.
# For example by invoking: 'killall -HUP uhub'
-63
View File
@@ -1,63 +0,0 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<title>uhub by janvidar</title>
<link rel="stylesheet" href="stylesheets/styles.css">
<link rel="stylesheet" href="stylesheets/pygment_trac.css">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<div class="wrapper">
<header>
<h1>uhub</h1>
<p>A high performance ADC peer to peer message hub.</p>
<p class="view"><a href="https://github.com/janvidar/uhub">View the Project on GitHub <small>janvidar/uhub</small></a></p>
<ul>
<li><a href="https://github.com/janvidar/uhub/zipball/master">Download <strong>ZIP File</strong></a></li>
<li><a href="https://github.com/janvidar/uhub/tarball/master">Download <strong>TAR Ball</strong></a></li>
<li><a href="https://github.com/janvidar/uhub">Fork On <strong>GitHub</strong></a></li>
</ul>
</header>
<section>
<h3>Welcome to GitHub Pages.</h3>
<p>This automatic page generator is the easiest way to create beautiful pages for all of your projects. Author your page content here using GitHub Flavored Markdown, select a template crafted by a designer, and publish. After your page is generated, you can check out the new branch:</p>
<pre><code>$ cd your_repo_root/repo_name
$ git fetch origin
$ git checkout gh-pages
</code></pre>
<p>If you're using the GitHub for Mac, simply sync your repository and you'll see the new branch.</p>
<h3>Designer Templates</h3>
<p>We've crafted some handsome templates for you to use. Go ahead and continue to layouts to browse through them. You can easily go back to edit your page before publishing. After publishing your page, you can revisit the page generator and switch to another theme. Your Page content will be preserved if it remained markdown format.</p>
<h3>Rather Drive Stick?</h3>
<p>If you prefer to not use the automatic generator, push a branch named <code>gh-pages</code> to your repository to create a page manually. In addition to supporting regular HTML content, GitHub Pages support Jekyll, a simple, blog aware static site generator written by our own Tom Preston-Werner. Jekyll makes it easy to create site-wide headers and footers without having to copy them across every page. It also offers intelligent blog support and other advanced templating features.</p>
<h3>Authors and Contributors</h3>
<p>You can <a href="https://github.com/blog/821" class="user-mention">@mention</a> a GitHub username to generate a link to their profile. The resulting <code>&lt;a&gt;</code> element will link to the contributor's GitHub Profile. For example: In 2007, Chris Wanstrath (<a href="https://github.com/defunkt" class="user-mention">@defunkt</a>), PJ Hyett (<a href="https://github.com/pjhyett" class="user-mention">@pjhyett</a>), and Tom Preston-Werner (<a href="https://github.com/mojombo" class="user-mention">@mojombo</a>) founded GitHub.</p>
<h3>Support or Contact</h3>
<p>Having trouble with Pages? Check out the documentation at <a href="http://help.github.com/pages">http://help.github.com/pages</a> or contact <a href="mailto:support@github.com">support@github.com</a> and we’ll help you sort it out.</p>
</section>
<footer>
<p>This project is maintained by <a href="https://github.com/janvidar">janvidar</a></p>
<p><small>Hosted on GitHub Pages &mdash; Theme by <a href="https://github.com/orderedlist">orderedlist</a></small></p>
</footer>
</div>
<script src="javascripts/scale.fix.js"></script>
</body>
</html>
-17
View File
@@ -1,17 +0,0 @@
var metas = document.getElementsByTagName('meta');
var i;
if (navigator.userAgent.match(/iPhone/i)) {
for (i=0; i<metas.length; i++) {
if (metas[i].name == "viewport") {
metas[i].content = "width=device-width, minimum-scale=1.0, maximum-scale=1.0";
}
}
document.addEventListener("gesturestart", gestureStart, false);
}
function gestureStart() {
for (i=0; i<metas.length; i++) {
if (metas[i].name == "viewport") {
metas[i].content = "width=device-width, minimum-scale=0.25, maximum-scale=1.6";
}
}
}
-1
View File
@@ -1 +0,0 @@
{"name":"uhub","body":"### Welcome to GitHub Pages.\r\nThis automatic page generator is the easiest way to create beautiful pages for all of your projects. Author your page content here using GitHub Flavored Markdown, select a template crafted by a designer, and publish. After your page is generated, you can check out the new branch:\r\n\r\n```\r\n$ cd your_repo_root/repo_name\r\n$ git fetch origin\r\n$ git checkout gh-pages\r\n```\r\n\r\nIf you're using the GitHub for Mac, simply sync your repository and you'll see the new branch.\r\n\r\n### Designer Templates\r\nWe've crafted some handsome templates for you to use. Go ahead and continue to layouts to browse through them. You can easily go back to edit your page before publishing. After publishing your page, you can revisit the page generator and switch to another theme. Your Page content will be preserved if it remained markdown format.\r\n\r\n### Rather Drive Stick?\r\nIf you prefer to not use the automatic generator, push a branch named `gh-pages` to your repository to create a page manually. In addition to supporting regular HTML content, GitHub Pages support Jekyll, a simple, blog aware static site generator written by our own Tom Preston-Werner. Jekyll makes it easy to create site-wide headers and footers without having to copy them across every page. It also offers intelligent blog support and other advanced templating features.\r\n\r\n### Authors and Contributors\r\nYou can @mention a GitHub username to generate a link to their profile. The resulting `<a>` element will link to the contributor's GitHub Profile. For example: In 2007, Chris Wanstrath (@defunkt), PJ Hyett (@pjhyett), and Tom Preston-Werner (@mojombo) founded GitHub.\r\n\r\n### Support or Contact\r\nHaving trouble with Pages? Check out the documentation at http://help.github.com/pages or contact support@github.com and we’ll help you sort it out.","tagline":"A high performance ADC peer to peer message hub.","google":"","note":"Don't delete this file! It's used internally to help with page regeneration."}
+168
View File
@@ -0,0 +1,168 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef HAVE_UHUB_ADC_CONSTANTS_H
#define HAVE_UHUB_ADC_CONSTANTS_H
#ifndef SID_T_DEFINED
typedef uint32_t sid_t;
#define SID_T_DEFINED
#endif
typedef uint32_t fourcc_t;
/* Internal uhub limit */
#define MAX_ADC_CMD_LEN 4096
#define FOURCC(a,b,c,d) (fourcc_t) ((a << 24) | (b << 16) | (c << 8) | d)
/* default welcome protocol support message, as sent by this server */
#define ADC_PROTO_SUPPORT "ADBASE ADTIGR ADPING ADUCMD"
/* Server sent commands */
#define ADC_CMD_ISID FOURCC('I','S','I','D')
#define ADC_CMD_ISUP FOURCC('I','S','U','P')
#define ADC_CMD_IGPA FOURCC('I','G','P','A')
#define ADC_CMD_ISTA FOURCC('I','S','T','A')
#define ADC_CMD_IINF FOURCC('I','I','N','F')
#define ADC_CMD_IMSG FOURCC('I','M','S','G')
#define ADC_CMD_IQUI FOURCC('I','Q','U','I')
/* Handshake and login/passwordstuff */
#define ADC_CMD_HSUP FOURCC('H','S','U','P')
#define ADC_CMD_HPAS FOURCC('H','P','A','S')
#define ADC_CMD_HINF FOURCC('H','I','N','F')
#define ADC_CMD_BINF FOURCC('B','I','N','F')
/* This is a Admin extension */
#define ADC_CMD_HDSC FOURCC('H','D','S','C')
/* Status/error messages */
#define ADC_CMD_HSTA FOURCC('H','S','T','A')
#define ADC_CMD_DSTA FOURCC('D','S','T','A')
/* searches */
#define ADC_CMD_BSCH FOURCC('B','S','C','H')
#define ADC_CMD_DSCH FOURCC('D','S','C','H')
#define ADC_CMD_ESCH FOURCC('E','S','C','H')
#define ADC_CMD_FSCH FOURCC('F','S','C','H')
#define ADC_CMD_DRES FOURCC('D','R','E','S')
/* invalid search results (spam) */
#define ADC_CMD_BRES FOURCC('B','R','E','S')
#define ADC_CMD_ERES FOURCC('E','R','E','S')
#define ADC_CMD_FRES FOURCC('F','R','E','S')
/* connection setup */
#define ADC_CMD_DCTM FOURCC('D','C','T','M')
#define ADC_CMD_DRCM FOURCC('D','R','C','M')
#define ADC_CMD_ECTM FOURCC('E','C','T','M')
#define ADC_CMD_ERCM FOURCC('E','R','C','M')
/* chat messages */
#define ADC_CMD_BMSG FOURCC('B','M','S','G')
#define ADC_CMD_DMSG FOURCC('D','M','S','G')
#define ADC_CMD_EMSG FOURCC('E','M','S','G')
#define ADC_CMD_FMSG FOURCC('F','M','S','G')
/* disallowed messages */
#define ADC_CMD_DINF FOURCC('D','I','N','F')
#define ADC_CMD_EINF FOURCC('E','I','N','F')
#define ADC_CMD_FINF FOURCC('F','I','N','F')
#define ADC_CMD_BQUI FOURCC('B','Q','U','I')
#define ADC_CMD_DQUI FOURCC('D','Q','U','I')
#define ADC_CMD_EQUI FOURCC('E','Q','U','I')
#define ADC_CMD_FQUI FOURCC('F','Q','U','I')
/* Extension messages */
#define ADC_CMD_HCHK FOURCC('H','C','H','K')
/* UCMD Extension */
#define ADC_CMD_BCMD FOURCC('B','C','M','D')
#define ADC_CMD_DCMD FOURCC('D','C','M','D')
#define ADC_CMD_ECMD FOURCC('E','C','M','D')
#define ADC_CMD_FCMD FOURCC('F','C','M','D')
#define ADC_CMD_HCMD FOURCC('H','C','M','D')
#define ADC_CMD_ICMD FOURCC('I','C','M','D')
#define ADC_INF_FLAG_IPV4_ADDR "I4" /* ipv4 address */
#define ADC_INF_FLAG_IPV6_ADDR "I6" /* ipv6 address */
#define ADC_INF_FLAG_IPV4_UDP_PORT "U4" /* port number */
#define ADC_INF_FLAG_IPV6_UDP_PORT "U6" /* port number */
#define ADC_INF_FLAG_CLIENT_TYPE "CT" /* client type */
#define ADC_INF_FLAG_PRIVATE_ID "PD" /* private id, aka PID */
#define ADC_INF_FLAG_CLIENT_ID "ID" /* client id, aka CID */
#define ADC_INF_FLAG_NICK "NI" /* nick name */
#define ADC_INF_FLAG_DESCRIPTION "DE" /* user description */
#define ADC_INF_FLAG_USER_AGENT_PRODUCT "AP" /* software name */
#define ADC_INF_FLAG_USER_AGENT_VERSION "VE" /* software version */
#define ADC_INF_FLAG_SUPPORT "SU" /* support (extensions, feature cast) */
#define ADC_INF_FLAG_SHARED_SIZE "SS" /* size of total files shared in bytes */
#define ADC_INF_FLAG_SHARED_FILES "SF" /* number of files shared */
#define ADC_INF_FLAG_UPLOAD_SPEED "US" /* maximum upload speed acheived in bytes/sec */
#define ADC_INF_FLAG_DOWNLOAD_SPEED "DS" /* maximum download speed acheived in bytes/sec */
#define ADC_INF_FLAG_UPLOAD_SLOTS "SL" /* maximum upload slots (concurrent uploads) */
#define ADC_INF_FLAG_AUTO_SLOTS "AS" /* automatic slot if upload speed is less than this in bytes/sec */
#define ADC_INF_FLAG_AUTO_SLOTS_MAX "AM" /* maximum number of automatic slots */
#define ADC_INF_FLAG_COUNT_HUB_NORMAL "HN" /* user is logged into this amount of hubs as a normal user (guest) */
#define ADC_INF_FLAG_COUNT_HUB_REGISTER "HR" /* user is logged into this amount of hubs as a registered user (password) */
#define ADC_INF_FLAG_COUNT_HUB_OPERATOR "HO" /* user is logged into this amount of hubs as an operator */
#define ADC_INF_FLAG_AWAY "AW" /* away flag, 1=away, 2=extended away */
#define ADC_INF_FLAG_REFERER "RF" /* URL to referer in case of hub redirect */
#define ADC_INF_FLAG_EMAIL "EM" /* E-mail address */
#define ADC_MSG_FLAG_ACTION "ME" /* message is an *action* 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_EXCLUDE "NO" /* exclude given serach term */
#define ADC_SCH_FLAG_FILE_EXTENSION "EX" /* search only for files with the given file extension */
#define ADC_SCH_FLAG_FILE_TYPE "TY" /* search only for files with this file type (separate type) */
#define ADC_SCH_FLAG_LESS_THAN "LE" /* search for files with this size or less */
#define ADC_SCH_FLAG_GREATER_THAN "GE" /* search for files with this size or greater */
#define ADC_SCH_FLAG_EQUAL "EQ" /* search only for files with this exact size */
#define ADC_SCH_FLAG_TOKEN "TO" /* use this token for search replies */
#define ADC_RES_FLAG_FILE_NAME "FN" /* file name */
#define ADC_RES_FLAG_FILE_SIZE "SI" /* file size */
#define ADC_RES_FLAG_UPLOAD_SLOTS "SL" /* number of upload slots available (if > 0, download is possible) */
#define ADC_RES_FLAG_TOKEN "TO" /* token, same as the token in the search request */
#define ADC_QUI_FLAG_TIME_LEFT "TL" /* time in seconds before reconnect is allowed, or -1 forever */
#define ADC_QUI_FLAG_MESSAGE "MS" /* kick/leave message */
#define ADC_QUI_FLAG_DISCONNECT "DI" /* all further transfers with this user should be disconnected */
#define ADC_QUI_FLAG_REDIRECT "RD" /* redirect to URL */
#define ADC_QUI_FLAG_KICK_OPERATOR "ID" /* SID of operator who disconnected the user */
#define ADC_SUP_FLAG_ADD "AD"
#define ADC_SUP_FLAG_REMOVE "RM"
#define ADC_CLIENT_TYPE_BOT "1"
#define ADC_CLIENT_TYPE_REGISTERED_USER "2"
#define ADC_CLIENT_TYPE_OPERATOR "4"
#define ADC_CLIENT_TYPE_HUBBOT "5" /* 1 + 4 */
#define ADC_CLIENT_TYPE_SUPER_USER "12" /* 8 + 4 */
#define ADC_CLIENT_TYPE_ADMIN "20" /* 16 + 4 = hub owner */
#define ADC_CLIENT_TYPE_HUB "32" /* the hub itself */
#endif /* HAVE_UHUB_ADC_CONSTANTS_H */
+995
View File
@@ -0,0 +1,995 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include "uhub.h"
#ifdef DEBUG
#define ADC_MSG_ASSERT(X) \
uhub_assert(X); \
uhub_assert(X->cache); \
uhub_assert(X->capacity); \
uhub_assert(X->length <= X->capacity); \
uhub_assert(X->references > 0); \
uhub_assert(X->length == strlen(X->cache));
#define ADC_MSG_NULL_ON_FREE
#else
#define ADC_MSG_ASSERT(X) do { } while(0)
#endif /* DEBUG */
#ifdef MSG_MEMORY_DEBUG
#undef msg_malloc
#undef msg_malloc_zero
#undef msg_free
static void* msg_malloc(size_t size)
{
void* ptr = valloc(size);
LOG_MEMORY("msg_malloc: %p %d", ptr, (int) size);
return ptr;
}
static void* msg_malloc_zero(size_t size)
{
void* ptr = msg_malloc(size);
memset(ptr, 0, size);
return ptr;
}
static void msg_free(void* ptr)
{
LOG_MEMORY("msg_free: %p", ptr);
hub_free(ptr);
}
#else
#define msg_malloc(X) hub_malloc(X)
#define msg_malloc_zero(X) hub_malloc_zero(X)
#define msg_free(X) hub_free(X)
#endif /* MSG_MEMORY_DEBUG */
static int msg_check_escapes(const char* string, size_t len)
{
char* start = (char*) string;
while ((start = memchr(start, '\\', len - (start - string))))
{
if (start+1 == (string + len))
return 0;
switch (*(++start))
{
case '\\':
case 'n':
case 's':
/* Increment so we don't check the escaped
* character next time around. Not doing so
* leads to messages with escaped backslashes
* being incorrectly reported as having invalid
* escapes. */
++start;
break;
default:
return 0;
}
}
return 1;
}
struct adc_message* adc_msg_incref(struct adc_message* msg)
{
#ifndef ADC_MESSAGE_INCREF
msg->references++;
#ifdef MSG_MEMORY_DEBUG
adc_msg_protect(msg);
#endif
return msg;
#else
struct adc_message* copy = adc_msg_copy(msg);
return copy;
#endif
}
static void adc_msg_set_length(struct adc_message* msg, size_t len)
{
msg->length = len;
}
static int adc_msg_grow(struct adc_message* msg, size_t size)
{
char* buf;
size_t newsize = 0;
if (!msg)
return 0;
if (msg->capacity > size)
return 1;
/* Make sure we align our data */
newsize = size;
newsize += 2; /* termination */
newsize += (newsize % sizeof(size_t)); /* alignment padding */
buf = msg_malloc_zero(newsize);
if (!buf)
return 0;
if (msg->cache)
{
memcpy(buf, msg->cache, msg->length);
msg_free(msg->cache);
}
msg->cache = buf;
msg->capacity = newsize;
return 1;
}
/* NOTE: msg must be unterminated here */
static int adc_msg_cache_append(struct adc_message* msg, const char* string, size_t len)
{
if (!adc_msg_grow(msg, msg->length + len))
{
/* FIXME: OOM! */
return 0;
}
memcpy(&msg->cache[msg->length], string, len);
adc_msg_set_length(msg, msg->length + len);
uhub_assert(msg->capacity > msg->length);
msg->cache[msg->length] = 0;
return 1;
}
/**
* Returns position of the first argument of the message.
* Excludes mandatory arguments for the given type of message
* like source and target.
*/
int adc_msg_get_arg_offset(struct adc_message* msg)
{
if (!msg || !msg->cache)
return -1;
switch (msg->cache[0])
{
/* These *SHOULD* never be seen on a hub */
case 'U':
case 'C':
return 4; /* Actually: 4 + strlen(cid). */
case 'I':
case 'H':
return 4;
case 'B':
return 9;
case 'F':
return (10 + (list_size(msg->feature_cast_include)*5) + (list_size(msg->feature_cast_exclude)*5));
case 'D':
case 'E':
return 14;
}
return -1;
}
int adc_msg_is_empty(struct adc_message* msg)
{
int offset = adc_msg_get_arg_offset(msg);
if (offset == -1)
return -1;
if ((msg->length - 1) == (size_t) offset)
return 1;
return 0;
}
void adc_msg_free(struct adc_message* msg)
{
if (!msg) return;
ADC_MSG_ASSERT(msg);
msg->references--;
if (msg->references == 0)
{
#ifdef ADC_MSG_NULL_ON_FREE
if (msg->cache)
{
*msg->cache = 0;
}
#endif
msg_free(msg->cache);
if (msg->feature_cast_include)
{
list_clear(msg->feature_cast_include, &hub_free);
list_destroy(msg->feature_cast_include);
msg->feature_cast_include = 0;
}
if (msg->feature_cast_exclude)
{
list_clear(msg->feature_cast_exclude, &hub_free);
list_destroy(msg->feature_cast_exclude);
msg->feature_cast_exclude = 0;
}
msg_free(msg);
}
}
struct adc_message* adc_msg_copy(const struct adc_message* cmd)
{
char* tmp = 0;
struct adc_message* copy = (struct adc_message*) msg_malloc_zero(sizeof(struct adc_message));
if (!copy) return NULL; /* OOM */
ADC_MSG_ASSERT(cmd);
/* deep copy */
copy->cmd = cmd->cmd;
copy->source = cmd->source;
copy->target = cmd->target;
copy->cache = 0;
copy->length = cmd->length;
copy->capacity = 0;
copy->priority = cmd->priority;
copy->references = 1;
copy->feature_cast_include = 0;
copy->feature_cast_exclude = 0;
if (!adc_msg_grow(copy, copy->length))
{
adc_msg_free(copy);
return NULL; /* OOM */
}
if (!copy->cache)
{
adc_msg_free(copy);
return NULL;
}
memcpy(copy->cache, cmd->cache, cmd->length);
copy->cache[copy->length] = 0;
if (cmd->feature_cast_include)
{
copy->feature_cast_include = list_create();
LIST_FOREACH(char*, tmp, cmd->feature_cast_include,
{
list_append(copy->feature_cast_include, hub_strdup(tmp));
});
}
if (cmd->feature_cast_exclude)
{
copy->feature_cast_exclude = list_create();
LIST_FOREACH(char*, tmp, cmd->feature_cast_exclude,
{
list_append(copy->feature_cast_exclude, hub_strdup(tmp));
});
}
ADC_MSG_ASSERT(copy);
return copy;
}
struct adc_message* adc_msg_parse_verify(struct hub_user* u, const char* line, size_t length)
{
struct adc_message* command = adc_msg_parse(line, length);
if (!command)
return 0;
if (command->source && (!u || (command->source != u->id.sid && !auth_cred_is_unrestricted(u->credentials))))
{
LOG_DEBUG("Command does not match user's SID (command->source=%d, user->id.sid=%d)", command->source, (u ? u->id.sid : 0));
adc_msg_free(command);
return 0;
}
return command;
}
struct adc_message* adc_msg_parse(const char* line, size_t length)
{
struct adc_message* command = (struct adc_message*) msg_malloc_zero(sizeof(struct adc_message));
char prefix = line[0];
size_t n = 0;
char temp_sid[5];
int ok = 1;
int need_terminate = 0;
struct linked_list* feature_cast_list;
if (command == NULL)
return NULL; /* OOM */
if (!is_printable_utf8(line, length))
{
LOG_DEBUG("Dropped message with non-printable UTF-8 characters.");
msg_free(command);
return NULL;
}
if (!msg_check_escapes(line, length))
{
LOG_DEBUG("Dropped message with invalid ADC escape.");
msg_free(command);
return NULL;
}
if (line[length-1] != '\n')
{
need_terminate = 1;
}
if (!adc_msg_grow(command, length + need_terminate))
{
msg_free(command);
return NULL; /* OOM */
}
adc_msg_set_length(command, length + need_terminate);
memcpy(command->cache, line, length);
/* Ensure we are zero terminated */
command->cache[length] = 0;
command->cache[length+need_terminate] = 0;
command->cmd = FOURCC(line[0], line[1], line[2], line[3]);
command->priority = 0;
command->references = 1;
switch (prefix)
{
case 'U':
case 'C':
/* these should never be seen on a hub */
ok = 0;
break;
case 'I':
case 'H':
ok = (length > 3);
break;
case 'B':
ok = (length > 8 &&
is_space(line[4]) &&
is_valid_base32_char(line[5]) &&
is_valid_base32_char(line[6]) &&
is_valid_base32_char(line[7]) &&
is_valid_base32_char(line[8]));
if (!ok) break;
temp_sid[0] = line[5];
temp_sid[1] = line[6];
temp_sid[2] = line[7];
temp_sid[3] = line[8];
temp_sid[4] = '\0';
command->source = string_to_sid(temp_sid);
break;
case 'F':
ok = (length > 8 &&
is_space(line[4]) &&
is_valid_base32_char(line[5]) &&
is_valid_base32_char(line[6]) &&
is_valid_base32_char(line[7]) &&
is_valid_base32_char(line[8]));
if (!ok) break;
temp_sid[0] = line[5];
temp_sid[1] = line[6];
temp_sid[2] = line[7];
temp_sid[3] = line[8];
temp_sid[4] = '\0';
command->source = string_to_sid(temp_sid);
/* Create feature cast lists */
command->feature_cast_include = list_create();
command->feature_cast_exclude = list_create();
if (!command->feature_cast_include || !command->feature_cast_exclude)
{
list_destroy(command->feature_cast_include);
list_destroy(command->feature_cast_exclude);
msg_free(command->cache);
msg_free(command);
return NULL; /* OOM */
}
n = 10;
while (line[n] == '+' || line[n] == '-')
{
if (line[n++] == '+')
feature_cast_list = command->feature_cast_include;
else
feature_cast_list = command->feature_cast_exclude;
temp_sid[0] = line[n++];
temp_sid[1] = line[n++];
temp_sid[2] = line[n++];
temp_sid[3] = line[n++];
temp_sid[4] = '\0';
list_append(feature_cast_list, hub_strdup(temp_sid));
}
if (n == 10)
ok = 0;
break;
case 'D':
case 'E':
ok = (length > 13 &&
is_space(line[4]) &&
is_valid_base32_char(line[5]) &&
is_valid_base32_char(line[6]) &&
is_valid_base32_char(line[7]) &&
is_valid_base32_char(line[8]) &&
is_space(line[9]) &&
is_valid_base32_char(line[10]) &&
is_valid_base32_char(line[11]) &&
is_valid_base32_char(line[12]) &&
is_valid_base32_char(line[13]));
if (!ok) break;
temp_sid[0] = line[5];
temp_sid[1] = line[6];
temp_sid[2] = line[7];
temp_sid[3] = line[8];
temp_sid[4] = '\0';
command->source = string_to_sid(temp_sid);
temp_sid[0] = line[10];
temp_sid[1] = line[11];
temp_sid[2] = line[12];
temp_sid[3] = line[13];
temp_sid[4] = '\0';
command->target = string_to_sid(temp_sid);
break;
default:
ok = 0;
}
if (need_terminate)
{
command->cache[length] = '\n';
}
if (!ok)
{
adc_msg_free(command);
return NULL;
}
/* At this point the arg_offset should point to a space, or the end of message */
n = adc_msg_get_arg_offset(command);
if (command->cache[n] == ' ')
{
if (command->cache[n+1] == ' ') ok = 0;
}
else if (command->cache[n] == '\n') ok = 1;
else ok = 0;
if (!ok)
{
adc_msg_free(command);
return NULL;
}
ADC_MSG_ASSERT(command);
return command;
}
struct adc_message* adc_msg_create(const char* line)
{
return adc_msg_parse(line, strlen(line));
}
struct adc_message* adc_msg_construct_source(fourcc_t fourcc, sid_t source, size_t size)
{
struct adc_message* msg = adc_msg_construct(fourcc, size + 4 + 1);
if (!msg)
return NULL;
adc_msg_add_argument(msg, sid_to_string(source));
msg->source = source;
return msg;
}
struct adc_message* adc_msg_construct_source_dest(fourcc_t fourcc, sid_t source, sid_t dest, size_t size)
{
struct adc_message* msg = adc_msg_construct(fourcc, size + 4 + 4 + 1);
if (!msg)
return NULL;
adc_msg_add_argument(msg, sid_to_string(source));
adc_msg_add_argument(msg, sid_to_string(dest));
msg->source = source;
msg->target = dest;
return msg;
}
struct adc_message* adc_msg_construct(fourcc_t fourcc, size_t size)
{
struct adc_message* msg = (struct adc_message*) msg_malloc_zero(sizeof(struct adc_message));
if (!msg)
return NULL; /* OOM */
if (!adc_msg_grow(msg, sizeof(fourcc) + size + 1))
{
msg_free(msg);
return NULL; /* OOM */
}
if (fourcc)
{
msg->cache[0] = (char) ((fourcc >> 24) & 0xff);
msg->cache[1] = (char) ((fourcc >> 16) & 0xff);
msg->cache[2] = (char) ((fourcc >> 8) & 0xff);
msg->cache[3] = (char) ((fourcc ) & 0xff);
msg->cache[4] = '\n';
/* Ensure we are zero terminated */
adc_msg_set_length(msg, 5);
msg->cache[msg->length] = 0;
}
msg->cmd = fourcc;
msg->priority = 0;
msg->references = 1;
return msg;
}
int adc_msg_remove_named_argument(struct adc_message* cmd, const char prefix_[2])
{
char* start;
char* end;
char* endInfo;
size_t endlen;
char prefix[4] = { ' ', prefix_[0], prefix_[1], '\0' };
int found = 0;
int arg_offset = adc_msg_get_arg_offset(cmd);
size_t temp_len = 0;
adc_msg_unterminate(cmd);
start = memmem(&cmd->cache[arg_offset], (cmd->length - arg_offset), prefix, 3);
while (start)
{
endInfo = &cmd->cache[cmd->length];
if (&start[0] < &endInfo[0])
{
end = memchr(&start[1], ' ', &endInfo[0]-&start[1]);
}
else
{
end = NULL;
}
if (end)
{
temp_len = &end[0] - &start[0]; // strlen(start);
endlen = strlen(end);
memmove(start, end, endlen);
start[endlen] = '\0';
found++;
adc_msg_set_length(cmd, cmd->length - temp_len);
}
else
{
found++;
adc_msg_set_length(cmd, cmd->length - strlen(start));
start[0] = '\0';
break;
}
start = memmem(&cmd->cache[arg_offset], (cmd->length - arg_offset), prefix, 3);
}
adc_msg_terminate(cmd);
return found;
}
int adc_msg_has_named_argument(struct adc_message* cmd, const char prefix_[2])
{
int count = 0;
char* start;
char prefix[4] = { ' ', prefix_[0], prefix_[1], '\0' };
int arg_offset = adc_msg_get_arg_offset(cmd);
ADC_MSG_ASSERT(cmd);
start = memmem(&cmd->cache[arg_offset], (cmd->length - arg_offset), prefix, 3);
while (start)
{
count++;
if ((size_t) (&start[0] - &cmd->cache[0]) < 1+cmd->length)
start = memmem(&start[1], (&cmd->cache[cmd->length] - &start[0]), prefix, 3);
else
start = NULL;
}
return count;
}
char* adc_msg_get_named_argument(struct adc_message* cmd, const char prefix_[2])
{
char* start;
char* end;
char* argument;
size_t length;
char prefix[4] = { ' ', prefix_[0], prefix_[1], '\0' };
int arg_offset = adc_msg_get_arg_offset(cmd);
ADC_MSG_ASSERT(cmd);
start = memmem(&cmd->cache[arg_offset], cmd->length - arg_offset, prefix, 3);
if (!start)
return NULL;
start = &start[3];
end = strchr(start, ' ');
if (!end) end = &cmd->cache[cmd->length];
length = &end[0] - &start[0];
argument = hub_strndup(start, length);
if (length > 0 && argument[length-1] == '\n')
{
argument[length-1] = 0;
}
return argument;
}
int adc_msg_replace_named_argument(struct adc_message* cmd, const char prefix[2], const char* string)
{
ADC_MSG_ASSERT(cmd);
while (adc_msg_has_named_argument(cmd, prefix))
{
adc_msg_remove_named_argument(cmd, prefix);
}
if (adc_msg_add_named_argument(cmd, prefix, string) == -1)
{
return -1;
}
ADC_MSG_ASSERT(cmd);
return 0;
}
void adc_msg_terminate(struct adc_message* cmd)
{
if (cmd->cache[cmd->length - 1] != '\n')
{
adc_msg_cache_append(cmd, "\n", 1);
}
ADC_MSG_ASSERT(cmd);
}
/* FIXME: this looks bogus */
void adc_msg_unterminate(struct adc_message* cmd)
{
ADC_MSG_ASSERT(cmd);
if (cmd->length > 0 && cmd->cache[cmd->length-1] == '\n')
{
cmd->length--;
cmd->cache[cmd->length] = 0;
}
}
int adc_msg_add_named_argument(struct adc_message* cmd, const char prefix[2], const char* string)
{
int ret = 0;
if (!string)
return -1;
ADC_MSG_ASSERT(cmd);
adc_msg_unterminate(cmd);
adc_msg_cache_append(cmd, " ", 1);
adc_msg_cache_append(cmd, prefix, 2);
adc_msg_cache_append(cmd, string, strlen(string));
adc_msg_terminate(cmd);
return ret;
}
int adc_msg_add_named_argument_string(struct adc_message* cmd, const char prefix[2], const char* string)
{
char* escaped = adc_msg_escape(string);
int ret = adc_msg_add_named_argument(cmd, prefix, escaped);
hub_free(escaped);
return ret;
}
int adc_msg_add_named_argument_int(struct adc_message* cmd, const char prefix[2], int num)
{
const char* s = uhub_itoa(num);
int ret = adc_msg_add_named_argument(cmd, prefix, s);
return ret;
}
int adc_msg_add_named_argument_uint64(struct adc_message* cmd, const char prefix[2], uint64_t num)
{
const char* s = uhub_ulltoa(num);
int ret = adc_msg_add_named_argument(cmd, prefix, s);
return ret;
}
int adc_msg_add_argument(struct adc_message* cmd, const char* string)
{
ADC_MSG_ASSERT(cmd);
adc_msg_unterminate(cmd);
adc_msg_cache_append(cmd, " ", 1);
adc_msg_cache_append(cmd, string, strlen(string));
adc_msg_terminate(cmd);
return 0;
}
char* adc_msg_get_argument(struct adc_message* cmd, int offset)
{
char* start;
char* end;
char* argument;
int count = 0;
ADC_MSG_ASSERT(cmd);
adc_msg_unterminate(cmd);
start = strchr(&cmd->cache[adc_msg_get_arg_offset(cmd)-1], ' ');
while (start)
{
end = strchr(&start[1], ' ');
if (count == offset)
{
if (end)
{
argument = hub_strndup(&start[1], (&end[0] - &start[1]));
}
else
{
argument = hub_strdup(&start[1]);
if (argument && *argument && argument[strlen(argument)-1] == '\n')
argument[strlen(argument)-1] = 0;
}
if (!argument)
return 0; // FIXME: OOM
if (*argument)
{
adc_msg_terminate(cmd);
return argument;
}
else
{
hub_free(argument);
}
}
count++;
start = end;
}
adc_msg_terminate(cmd);
return 0;
}
/**
* NOTE: Untested code.
*/
int adc_msg_get_argument_index(struct adc_message* cmd, const char prefix[2])
{
char* start;
char* end;
int count = 0;
ADC_MSG_ASSERT(cmd);
adc_msg_unterminate(cmd);
start = strchr(&cmd->cache[adc_msg_get_arg_offset(cmd)-1], ' ');
while (start)
{
end = strchr(&start[1], ' ');
if (((&end[0] - &start[1]) > 2) && ((start[1] == prefix[0]) && (start[2] == prefix[1])))
{
adc_msg_terminate(cmd);
return count;
}
count++;
start = end;
}
adc_msg_terminate(cmd);
return -1;
}
int adc_msg_escape_length(const char* str)
{
int add = 0;
int n = 0;
for (; str[n]; n++)
if (str[n] == ' ' || str[n] == '\n' || str[n] == '\\') add++;
return n + add;
}
int adc_msg_unescape_length(const char* str)
{
int add = 0;
int n = 0;
int escape = 0;
for (; str[n]; n++)
{
if (escape)
{
escape = 0;
}
else
{
if (str[n] == '\\')
{
escape = 1;
add++;
}
}
}
return n - add;
}
char* adc_msg_unescape(const char* string)
{
char* new_string = msg_malloc(adc_msg_unescape_length(string)+1);
char* ptr = (char*) new_string;
char* str = (char*) string;
int escaped = 0;
while (*str)
{
if (escaped) {
if (*str == 's')
*ptr++ = ' ';
else if (*str == '\\')
*ptr++ = '\\';
else if (*str == 'n')
*ptr++ = '\n';
else
*ptr++ = *str;
escaped = 0;
} else {
if (*str == '\\')
escaped = 1;
else
*ptr++ = *str;
}
str++;
}
*ptr = 0;
return new_string;
}
int adc_msg_unescape_to_target(const char* string, char* target, size_t target_size)
{
size_t w = 0;
char* ptr = (char*) target;
char* str = (char*) string;
int escaped = 0;
while (*str && w < (target_size-1))
{
if (escaped) {
if (*str == 's')
*ptr++ = ' ';
else if (*str == '\\')
*ptr++ = '\\';
else if (*str == 'n')
*ptr++ = '\n';
else
*ptr++ = *str;
w++;
escaped = 0;
} else {
if (*str == '\\')
escaped = 1;
else
{
*ptr++ = *str;
w++;
}
}
str++;
}
*ptr = 0;
w++;
return w;
}
char* adc_msg_escape(const char* string)
{
char* str = hub_malloc(adc_msg_escape_length(string)+1);
size_t n = 0;
size_t i = 0;
for (i = 0; i < strlen(string); i++)
{
switch (string[i]) {
case '\\': /* fall through */
str[n++] = '\\';
str[n++] = '\\';
break;
case '\n':
str[n++] = '\\';
str[n++] = 'n';
break;
case ' ':
str[n++] = '\\';
str[n++] = 's';
break;
default:
str[n++] = string[i];
break;
}
}
str[n] = '\0';
return str;
}
+237
View File
@@ -0,0 +1,237 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef HAVE_UHUB_COMMAND_H
#define HAVE_UHUB_COMMAND_H
struct hub_user;
struct adc_message
{
fourcc_t cmd;
sid_t source;
sid_t target;
char* cache;
size_t length;
size_t capacity;
size_t priority;
size_t references;
struct linked_list* feature_cast_include;
struct linked_list* feature_cast_exclude;
};
enum msg_status_level
{
status_level_info = 0, /* Success/informative status message */
status_level_error = 1, /* Recoverable error */
status_level_fatal = 2, /* Fatal error (disconnect) */
};
/**
* Increase the reference counter for an ADC message struct.
* NOTE: Always use the returned value, and not the passed value, as
* it ensures we can actually copy the value if needed.
*/
extern struct adc_message* adc_msg_incref(struct adc_message* msg);
/**
* Decrease the reference counter, and free the memory when apropriate.
*/
extern void adc_msg_free(struct adc_message* msg);
/**
* Perform deep copy a command.
* NOTE: 'references' will be zero for the copied command.
* @return a copy of cmd or NULL if not able to allocate memory.
*/
extern struct adc_message* adc_msg_copy(const struct adc_message* cmd);
/**
* This will parse 'string' and return it as a adc_message struct, or
* NULL if not able to allocate memory or 'string' does not contain
* a valid ADC command.
*
* The message is only considered valid if the user who sent it
* is the rightful origin of the message.
*/
extern struct adc_message* adc_msg_parse_verify(struct hub_user* u, const char* string, size_t length);
/**
* This will parse 'string' and return it as a adc_message struct, or
* NULL if not able to allocate memory or 'string' does not contain
* a valid ADC command.
*/
extern struct adc_message* adc_msg_parse(const char* string, size_t length);
/**
* This will construct a adc_message based on 'string'.
* Only to be used for server generated commands.
*/
extern struct adc_message* adc_msg_create(const char* string);
/**
* Construct a message with the given 'fourcc' and allocate
* 'size' bytes for later use.
*/
extern struct adc_message* adc_msg_construct(fourcc_t fourcc, size_t size);
/**
* Construct a message for the given 'fourcc' and add a source SID to it,
* in addition pre-allocate 'size' bytes at the end of the message.
*/
extern struct adc_message* adc_msg_construct_source(fourcc_t fourcc, sid_t source, size_t size);
extern struct adc_message* adc_msg_construct_source_dest(fourcc_t fourcc, sid_t source, sid_t dest, size_t size);
/**
* Remove a named argument from the command.
*
* @arg prefix a 2 character argument prefix
* @return the number of named arguments removed.
*/
extern int adc_msg_remove_named_argument(struct adc_message* cmd, const char prefix[2]);
/**
* Count the number of arguments matching the given 2 character prefix.
*
* @arg prefix a 2 character argument prefix
* @return the number of matching arguments
*/
extern int adc_msg_has_named_argument(struct adc_message* cmd, const char prefix[2]);
/**
* Returns a named arguments based on the 2 character prefix.
* If multiple matching arguments exists, only the first one will be returned
* by this function.
*
* NOTE: Returned memory must be free'd with hub_free().
*
* @arg prefix a 2 character argument prefix
* @return the argument or NULL if OOM/not found.
*/
extern char* adc_msg_get_named_argument(struct adc_message* cmd, const char prefix[2]);
/**
* Returns a offset of an argument based on the 2 character prefix.
* If multiple matching arguments exists, only the first one will be returned
* by this function.
*
* @arg prefix a 2 character argument prefix
* @return the offset or -1 if the argument is not found.
*/
extern int adc_msg_get_named_argument_index(struct adc_message* cmd, const char prefix[2]);
/**
* @param cmd command to be checked
* @return 1 if the command does not have any arguments (parameters), 0 otherwise, -1 if cmd is invalid.
*/
extern int adc_msg_is_empty(struct adc_message* cmd);
/**
* Returns the argument on the offset position in the command.
* If offset is invalid NULL is returned.
*
* NOTE: Returned memory must be free'd with hub_free().
*
* @return the argument or NULL if OOM/not found.
*/
extern char* adc_msg_get_argument(struct adc_message* cmd, int offset);
/**
* Replace a named argument in the command.
* This will remove any matching arguments (multiple, or none),
* then add 'string' as an argument using the given prefix.
*
* @arg prefix a 2 character argument prefix
* @arg string must be escaped (see adc_msg_escape).
* @return 0 if successful, or -1 if an error occured.
*/
extern int adc_msg_replace_named_argument(struct adc_message* cmd, const char prefix[2], const char* string);
/**
* Append an argument
*
* @arg string must be escaped (see adc_msg_escape).
* @return 0 if successful, or -1 if an error occured (out of memory).
*/
extern int adc_msg_add_argument(struct adc_message* cmd, const char* string);
/**
* Append a named argument
*
* @arg prefix a 2 character argument prefix
* @arg string must be escaped (see adc_msg_escape).
* @return 0 if successful, or -1 if an error occured (out of memory).
*/
extern int adc_msg_add_named_argument(struct adc_message* cmd, const char prefix[2], const char* string);
/**
* Append a string as a named argument.
* The string will automatcally be escaped, if you do not wish to escape th string use adc_msg_add_named_argument() instead.
*
* @arg prefix a 2 character argument prefix
* @arg string must NOT be escaped
* @return 0 if successful, or -1 if an error occured (out of memory).
*/
extern int adc_msg_add_named_argument_string(struct adc_message* cmd, const char prefix[2], const char* string);
/**
* Append an integer as a named argument.
*/
extern int adc_msg_add_named_argument_int(struct adc_message* cmd, const char prefix[2], int integer);
extern int adc_msg_add_named_argument_uint64(struct adc_message* cmd, const char prefix[2], uint64_t num);
/**
* Convert a ADC command escaped string to a regular string.
* @return string or NULL if out of memory
*/
extern char* adc_msg_unescape(const char* string);
/**
* Convert a ADC command escaped string to a regular string.
* @return The number of bytes written to target. If the target is not large enough then
* the -1 is returned, but the string is guaranteed to always be \0 terminated.
*/
extern int adc_msg_unescape_to_target(const char* string, char* target, size_t target_size);
/**
* Convert a string to a ADC command escaped string.
* @return adc command escaped string or NULL if out of memory.
*/
extern char* adc_msg_escape(const char* string);
/**
* This will ensure a newline is at the end of the command.
*/
void adc_msg_terminate(struct adc_message* cmd);
/**
* This will remove any newline from the end of the command
*/
void adc_msg_unterminate(struct adc_message* cmd);
/**
* @return the offset for the first command argument in msg->cache.
* or -1 if the command is not understood.
* NOTE: for 'U' and 'C' commands (normally not seen by hubs),
* this returns 4. Should be 4 + lengthOf(cid).
*/
int adc_msg_get_arg_offset(struct adc_message* msg);
#endif /* HAVE_UHUB_COMMAND_H */
+155
View File
@@ -0,0 +1,155 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include "uhub.h"
const char* BASE32_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
char* sid_to_string(sid_t sid_)
{
static char t_sid[5];
sid_t sid = (sid_ & 0xFFFFF); /* 20 bits only */
sid_t A, B, C, D = 0;
D = (sid % 32);
sid = (sid - D) / 32;
C = (sid % 32);
sid = (sid - C) / 32;
B = (sid % 32);
sid = (sid - B) / 32;
A = (sid % 32);
t_sid[0] = BASE32_ALPHABET[A];
t_sid[1] = BASE32_ALPHABET[B];
t_sid[2] = BASE32_ALPHABET[C];
t_sid[3] = BASE32_ALPHABET[D];
t_sid[4] = 0;
return t_sid;
}
sid_t string_to_sid(const char* sid)
{
sid_t nsid = 0;
sid_t n, x;
sid_t factors[] = { 32768, 1024, 32, 1};
if (!sid || strlen(sid) != 4) return 0;
for (n = 0; n < 4; n++) {
for (x = 0; x < strlen(BASE32_ALPHABET); x++)
if (sid[n] == BASE32_ALPHABET[x]) break;
if (x == 32) return 0;
nsid += x * factors[n];
}
return nsid;
}
/*
* Session IDs are heavily reused, since they are a fairly scarce
* resource. Only one (2^10)-1 exist, since it is a four byte base32-encoded
* value and 'AAAA' (0) is reserved for the hub.
*
* Initialize with sid_initialize(), which sets min and max to one, and count to 0.
*
* When allocating a session ID:
* - If 'count' is less than the pool size (max-min), then allocate within the pool
* - Increase the pool size (see below)
* - If unable to do that, hub is really full - don't let anyone in!
*
* When freeing a session ID:
* - If the session ID being freed is 'max', then decrease the pool size by one.
*
*/
struct sid_pool
{
sid_t min;
sid_t max;
sid_t count;
struct hub_user** map;
};
struct sid_pool* sid_pool_create(sid_t max)
{
struct sid_pool* pool = hub_malloc(sizeof(struct sid_pool));
if (!pool)
return 0;
pool->min = 1;
pool->max = max + 1;
pool->count = 0;
pool->map = hub_malloc_zero(sizeof(struct hub_user*) * pool->max);
if (!pool->map)
{
hub_free(pool);
return 0;
}
pool->map[0] = (struct hub_user*) pool; /* hack to reserve the first sid. */
#ifdef DEBUG_SID
LOG_DUMP("SID_POOL: max=%d", (int) pool->max);
#endif
return pool;
}
void sid_pool_destroy(struct sid_pool* pool)
{
#ifdef DEBUG_SID
LOG_DUMP("SID_POOL: destroying, current allocs=%d", (int) pool->count);
#endif
hub_free(pool->map);
hub_free(pool);
}
sid_t sid_alloc(struct sid_pool* pool, struct hub_user* user)
{
sid_t n;
if (pool->count >= (pool->max - pool->min))
{
#ifdef DEBUG_SID
LOG_DUMP("SID_POOL: alloc, sid pool is full.");
#endif
return 0;
}
n = (++pool->count);
for (; (pool->map[n % pool->max]); n++) ;
#ifdef DEBUG_SID
LOG_DUMP("SID_ALLOC: %d, user=%p", (int) n, user);
#endif
pool->map[n] = user;
return n;
}
void sid_free(struct sid_pool* pool, sid_t sid)
{
#ifdef DEBUG_SID
LOG_DUMP("SID_FREE: %d", (int) sid);
#endif
pool->map[sid] = 0;
pool->count--;
}
struct hub_user* sid_lookup(struct sid_pool* pool, sid_t sid)
{
if (!sid || (sid >= pool->max))
return 0;
return pool->map[sid];
}
+41
View File
@@ -0,0 +1,41 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef HAVE_UHUB_SID_H
#define HAVE_UHUB_SID_H
#define SID_MAX 1048576
struct sid_pool;
struct hub_user;
extern char* sid_to_string(sid_t sid_);
extern sid_t string_to_sid(const char* sid);
extern struct sid_pool* sid_pool_create(sid_t max);
extern void sid_pool_destroy(struct sid_pool*);
extern sid_t sid_alloc(struct sid_pool*, struct hub_user*);
extern void sid_free(struct sid_pool*, sid_t);
extern struct hub_user* sid_lookup(struct sid_pool*, sid_t);
#endif /* HAVE_UHUB_SID_H */
+492
View File
@@ -0,0 +1,492 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include "uhub.h"
#define ACL_ADD_USER(S, L, V) do { ret = check_cmd_user(S, V, L, line, line_count); if (ret != 0) return ret; } while(0)
#define ACL_ADD_BOOL(S, L) do { ret = check_cmd_bool(S, L, line, line_count); if (ret != 0) return ret; } while(0)
#define ACL_ADD_ADDR(S, L) do { ret = check_cmd_addr(S, L, line, line_count); if (ret != 0) return ret; } while(0)
static int check_cmd_bool(const char* cmd, struct linked_list* list, char* line, int line_count)
{
char* data;
if (!strncmp(line, cmd, strlen(cmd)))
{
data = &line[strlen(cmd)];
data[0] = '\0';
data++;
data = strip_white_space(data);
if (!*data)
{
LOG_FATAL("ACL parse error on line %d", line_count);
return -1;
}
list_append(list, hub_strdup(data));
LOG_DEBUG("ACL: Deny access for: '%s' (%s)", data, cmd);
return 1;
}
return 0;
}
static int check_cmd_user(const char* cmd, int status, struct linked_list* list, char* line, int line_count)
{
char* data;
char* data_extra;
struct auth_info* info = 0;
if (!strncmp(line, cmd, strlen(cmd)))
{
data = &line[strlen(cmd)];
data_extra = 0;
data[0] = '\0';
data++;
data = strip_white_space(data);
if (!*data)
{
LOG_FATAL("ACL parse error on line %d", line_count);
return -1;
}
info = hub_malloc_zero(sizeof(struct auth_info));
if (!info)
{
LOG_ERROR("ACL parse error. Out of memory!");
return -1;
}
if (strncmp(cmd, "user_", 5) == 0)
{
data_extra = strrchr(data, ':');
if (data_extra)
{
data_extra[0] = 0;
data_extra++;
}
}
strncpy(info->nickname, data, MAX_NICK_LEN);
if (data_extra)
strncpy(info->password, data_extra, MAX_PASS_LEN);
info->credentials = status;
list_append(list, info);
LOG_DEBUG("ACL: Added user '%s' (%s)", info->nickname, auth_cred_to_string(info->credentials));
return 1;
}
return 0;
}
static void add_ip_range(struct linked_list* list, struct ip_range* info)
{
char buf1[INET6_ADDRSTRLEN+1];
char buf2[INET6_ADDRSTRLEN+1];
if (info->lo.af == AF_INET)
{
net_address_to_string(AF_INET, &info->lo.internal_ip_data.in.s_addr, buf1, INET6_ADDRSTRLEN);
net_address_to_string(AF_INET, &info->hi.internal_ip_data.in.s_addr, buf2, INET6_ADDRSTRLEN);
}
else if (info->lo.af == AF_INET6)
{
net_address_to_string(AF_INET6, &info->lo.internal_ip_data.in6, buf1, INET6_ADDRSTRLEN);
net_address_to_string(AF_INET6, &info->hi.internal_ip_data.in6, buf2, INET6_ADDRSTRLEN);
}
LOG_DEBUG("ACL: Added ip range: %s-%s", buf1, buf2);
list_append(list, info);
}
static int check_cmd_addr(const char* cmd, struct linked_list* list, char* line, int line_count)
{
char* data;
struct ip_range* range = 0;
if (!strncmp(line, cmd, strlen(cmd)))
{
data = &line[strlen(cmd)];
data[0] = '\0';
data++;
data = strip_white_space(data);
if (!*data)
{
LOG_FATAL("ACL parse error on line %d", line_count);
return -1;
}
range = hub_malloc_zero(sizeof(struct ip_range));
if (!range)
{
LOG_ERROR("ACL parse error. Out of memory!");
return -1;
}
if (ip_convert_address_to_range(data, range))
{
add_ip_range(list, range);
return 1;
}
hub_free(range);
}
return 0;
}
static int acl_parse_line(char* line, int line_count, void* ptr_data)
{
struct acl_handle* handle = (struct acl_handle*) ptr_data;
int ret;
strip_off_ini_line_comments(line, line_count);
line = strip_white_space(line);
if (!*line)
return 0;
LOG_DEBUG("acl_parse_line: '%s'", line);
ACL_ADD_USER("bot", handle->users, auth_cred_bot);
ACL_ADD_USER("ubot", handle->users, auth_cred_ubot);
ACL_ADD_USER("opbot", handle->users, auth_cred_opbot);
ACL_ADD_USER("opubot", handle->users, auth_cred_opubot);
ACL_ADD_USER("user_admin", handle->users, auth_cred_admin);
ACL_ADD_USER("user_super", handle->users, auth_cred_super);
ACL_ADD_USER("user_op", handle->users, auth_cred_operator);
ACL_ADD_USER("user_reg", handle->users, auth_cred_user);
ACL_ADD_USER("link", handle->users, auth_cred_link);
ACL_ADD_BOOL("deny_nick", handle->users_denied);
ACL_ADD_BOOL("ban_nick", handle->users_banned);
ACL_ADD_BOOL("ban_cid", handle->cids);
ACL_ADD_ADDR("deny_ip", handle->networks);
ACL_ADD_ADDR("nat_ip", handle->nat_override);
LOG_ERROR("Unknown ACL command on line %d: '%s'", line_count, line);
return -1;
}
int acl_initialize(struct hub_config* config, struct acl_handle* handle)
{
int ret;
memset(handle, 0, sizeof(struct acl_handle));
handle->users = list_create();
handle->users_denied = list_create();
handle->users_banned = list_create();
handle->cids = list_create();
handle->networks = list_create();
handle->nat_override = list_create();
if (!handle->users || !handle->cids || !handle->networks || !handle->users_denied || !handle->users_banned || !handle->nat_override)
{
LOG_FATAL("acl_initialize: Out of memory");
list_destroy(handle->users);
list_destroy(handle->users_denied);
list_destroy(handle->users_banned);
list_destroy(handle->cids);
list_destroy(handle->networks);
list_destroy(handle->nat_override);
return -1;
}
if (config)
{
if (!*config->file_acl) return 0;
ret = file_read_lines(config->file_acl, handle, &acl_parse_line);
if (ret == -1)
return -1;
}
return 0;
}
static void acl_free_access_info(void* ptr)
{
struct auth_info* info = (struct auth_info*) ptr;
if (info)
{
hub_free(info);
}
}
static void acl_free_ip_info(void* ptr)
{
struct access_info* info = (struct access_info*) ptr;
if (info)
{
hub_free(info);
}
}
int acl_shutdown(struct acl_handle* handle)
{
if (handle->users)
{
list_clear(handle->users, &acl_free_access_info);
list_destroy(handle->users);
}
if (handle->users_denied)
{
list_clear(handle->users_denied, &hub_free);
list_destroy(handle->users_denied);
}
if (handle->users_banned)
{
list_clear(handle->users_banned, &hub_free);
list_destroy(handle->users_banned);
}
if (handle->cids)
{
list_clear(handle->cids, &hub_free);
list_destroy(handle->cids);
}
if (handle->networks)
{
list_clear(handle->networks, &acl_free_ip_info);
list_destroy(handle->networks);
}
if (handle->nat_override)
{
list_clear(handle->nat_override, &acl_free_ip_info);
list_destroy(handle->nat_override);
}
memset(handle, 0, sizeof(struct acl_handle));
return 0;
}
extern int acl_register_user(struct hub_info* hub, struct auth_info* info)
{
if (plugin_auth_register_user(hub, info) != st_allow)
{
return 0;
}
return 1;
}
extern int acl_update_user(struct hub_info* hub, struct auth_info* info)
{
if (plugin_auth_update_user(hub, info) != st_allow)
{
return 0;
}
return 1;
}
extern int acl_delete_user(struct hub_info* hub, const char* name)
{
struct auth_info data;
strncpy(data.nickname, name, MAX_NICK_LEN);
data.nickname[MAX_NICK_LEN] = '\0';
data.password[0] = '\0';
data.credentials = auth_cred_none;
if (plugin_auth_delete_user(hub, &data) != st_allow)
{
return 0;
}
return 1;
}
struct auth_info* acl_get_access_info(struct hub_info* hub, const char* name)
{
struct auth_info* info = 0;
info = (struct auth_info*) hub_malloc(sizeof(struct auth_info));
if (plugin_auth_get_user(hub, name, info) != st_allow)
{
hub_free(info);
return NULL;
}
return info;
}
#define STR_LIST_CONTAINS(LIST, STR) \
LIST_FOREACH(char*, str, LIST, \
{ \
if (strcasecmp(str, STR) == 0) \
return 1; \
}); \
return 0
int acl_is_cid_banned(struct acl_handle* handle, const char* data)
{
char* str;
if (!handle) return 0;
STR_LIST_CONTAINS(handle->cids, data);
}
int acl_is_user_banned(struct acl_handle* handle, const char* data)
{
char* str;
if (!handle) return 0;
STR_LIST_CONTAINS(handle->users_banned, data);
}
int acl_is_user_denied(struct acl_handle* handle, const char* data)
{
char* str;
if (!handle) return 0;
STR_LIST_CONTAINS(handle->users_denied, data);
}
int acl_user_ban_nick(struct acl_handle* handle, const char* nick)
{
char* data = hub_strdup(nick);
if (!data)
{
LOG_ERROR("ACL error: Out of memory!");
return -1;
}
list_append(handle->users_banned, data);
return 0;
}
int acl_user_ban_cid(struct acl_handle* handle, const char* cid)
{
char* data = hub_strdup(cid);
if (!data)
{
LOG_ERROR("ACL error: Out of memory!");
return -1;
}
list_append(handle->cids, data);
return 0;
}
int acl_user_unban_nick(struct acl_handle* handle, const char* nick)
{
return -1;
}
int acl_user_unban_cid(struct acl_handle* handle, const char* cid)
{
return -1;
}
int acl_is_ip_banned(struct acl_handle* handle, const char* ip_address)
{
struct ip_addr_encap raw;
struct ip_range* info;
ip_convert_to_binary(ip_address, &raw);
LIST_FOREACH(struct ip_range*, info, handle->networks,
{
if (ip_in_range(&raw, info))
return 1;
});
return 0;
}
int acl_is_ip_nat_override(struct acl_handle* handle, const char* ip_address)
{
struct ip_addr_encap raw;
struct ip_range* info;
ip_convert_to_binary(ip_address, &raw);
LIST_FOREACH(struct ip_range*, info, handle->nat_override,
{
if (ip_in_range(&raw, info))
return 1;
});
return 0;
}
/*
* This will generate the same challenge to the same user, always.
* The challenge is made up of the time of the user connected
* seconds since the unix epoch (modulus 1 million)
* and the SID of the user (0-1 million).
*/
const char* acl_password_generate_challenge(struct hub_info* hub, struct hub_user* user)
{
char buf[64];
uint64_t tiger_res[3];
static char tiger_buf[MAX_CID_LEN+1];
// FIXME: Generate a better nonce scheme.
snprintf(buf, 64, "%p%d%d", user, (int) user->id.sid, (int) net_con_get_sd(user->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;
return (const char*) tiger_buf;
}
int acl_password_verify(struct hub_info* hub, struct hub_user* user, const char* password)
{
char buf[1024];
struct auth_info* access;
const char* challenge;
char raw_challenge[64];
char password_calc[64];
uint64_t tiger_res[3];
size_t password_len;
if (!password || !user || strlen(password) != MAX_CID_LEN)
return 0;
access = acl_get_access_info(hub, user->id.nick);
if (!access)
return 0;
challenge = acl_password_generate_challenge(hub, user);
base32_decode(challenge, (unsigned char*) raw_challenge, MAX_CID_LEN);
password_len = strlen(access->password);
memcpy(&buf[0], access->password, password_len);
memcpy(&buf[password_len], raw_challenge, TIGERSIZE);
tiger((uint64_t*) buf, TIGERSIZE+password_len, (uint64_t*) tiger_res);
base32_encode((unsigned char*) tiger_res, TIGERSIZE, password_calc);
password_calc[MAX_CID_LEN] = 0;
hub_free(access);
if (strcasecmp(password, password_calc) == 0)
{
return 1;
}
return 0;
}
+70
View File
@@ -0,0 +1,70 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef HAVE_UHUB_ACL_H
#define HAVE_UHUB_ACL_H
struct hub_config;
struct hub_info;
struct hub_user;
struct ip_addr_encap;
struct acl_handle
{
struct linked_list* users; /* Known users. See enum user_status */
struct linked_list* cids; /* Known CIDs */
struct linked_list* networks; /* IP ranges, used for banning */
struct linked_list* nat_override; /* IPs inside these ranges can provide their false IP. Use with care! */
struct linked_list* users_banned; /* Users permanently banned */
struct linked_list* users_denied; /* bad nickname */
};
extern int acl_initialize(struct hub_config* config, struct acl_handle* handle);
extern int acl_shutdown(struct acl_handle* handle);
extern struct auth_info* acl_get_access_info(struct hub_info* hub, const char* name);
extern int acl_register_user(struct hub_info* hub, struct auth_info* info);
extern int acl_update_user(struct hub_info* hub, struct auth_info* info);
extern int acl_delete_user(struct hub_info* hub, const char* name);
extern int acl_is_cid_banned(struct acl_handle* handle, const char* cid);
extern int acl_is_ip_banned(struct acl_handle* handle, const char* ip_address);
extern int acl_is_ip_nat_override(struct acl_handle* handle, const char* ip_address);
extern int acl_is_user_banned(struct acl_handle* handle, const char* name);
extern int acl_is_user_denied(struct acl_handle* handle, const char* name);
extern int acl_user_ban_nick(struct acl_handle* handle, const char* nick);
extern int acl_user_ban_cid(struct acl_handle* handle, const char* cid);
extern int acl_user_unban_nick(struct acl_handle* handle, const char* nick);
extern int acl_user_unban_cid(struct acl_handle* handle, const char* cid);
/**
* Verify a password.
*
* @param password the hashed password (based on the nonce).
* @return 1 if the password matches, or 0 if the password is incorrect.
*/
extern int acl_password_verify(struct hub_info* hub, struct hub_user* user, const char* password);
extern const char* acl_password_generate_challenge(struct hub_info* hub, struct hub_user* user);
#endif /* HAVE_UHUB_ACL_H */
+299
View File
@@ -0,0 +1,299 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include "uhub.h"
static void hub_command_args_free(struct hub_command* cmd)
{
struct hub_command_arg_data* data = NULL;
if (!cmd->args)
return;
LIST_FOREACH(struct hub_command_arg_data*, data, cmd->args,
{
switch (data->type)
{
case type_string:
hub_free(data->data.string);
break;
case type_range:
hub_free(data->data.range);
break;
default:
break;
}
});
list_clear(cmd->args, hub_free);
list_destroy(cmd->args);
cmd->args = NULL;
}
void command_free(struct hub_command* cmd)
{
if (!cmd) return;
hub_free(cmd->prefix);
hub_command_args_free(cmd);
hub_free(cmd);
}
static enum command_parse_status command_extract_arguments(struct hub_info* hub, const struct hub_user* user, struct command_handle* command, struct linked_list* tokens, struct linked_list* args)
{
int arg = 0;
int opt = 0;
int greedy = 0;
char arg_code;
char* token = NULL;
char* tmp = NULL;
size_t size = 0;
size_t offset = 0;
struct hub_command_arg_data* data = NULL;
enum command_parse_status status = cmd_status_ok;
// Ignore the first token since it is the prefix.
token = list_get_first(tokens);
list_remove(tokens, token);
hub_free(token);
while (status == cmd_status_ok && (arg_code = command->args[arg++]))
{
if (greedy)
{
size = 1;
LIST_FOREACH(char*, tmp, tokens, { size += (strlen(tmp) + 1); });
token = hub_malloc_zero(size);
while ((tmp = list_get_first(tokens)))
{
if (offset > 0)
token[offset++] = ' ';
memcpy(token + offset, tmp, strlen(tmp));
offset += strlen(tmp);
list_remove(tokens, tmp);
hub_free(tmp);
}
}
else
{
token = list_get_first(tokens);
}
if (!token || !*token)
{
if (arg_code == '?' || opt == 1)
status = cmd_status_ok;
else
status = cmd_status_missing_args;
break;
}
switch (arg_code)
{
case '?':
opt = 1;
continue;
case '+':
greedy = 1;
continue;
case 'u':
data = hub_malloc(sizeof(*data));
data->type = type_user;
data->data.user = uman_get_user_by_nick(hub->users, token);
if (!data->data.user)
{
hub_free(data);
data = NULL;
status = cmd_status_arg_nick;
}
break;
case 'i':
data = hub_malloc(sizeof(*data));
data->type = type_user;
data->data.user = uman_get_user_by_cid(hub->users, token);
if (!data->data.user)
{
hub_free(data);
data = NULL;
status = cmd_status_arg_cid;
}
break;
case 'a':
data = hub_malloc(sizeof(*data));
data->type = type_address;
if (ip_convert_to_binary(token, data->data.address) == -1)
{
hub_free(data);
data = NULL;
status = cmd_status_arg_address;
}
break;
case 'r':
data = hub_malloc(sizeof(*data));
data->type = type_range;
data->data.range = hub_malloc_zero(sizeof(struct ip_range));
if (!ip_convert_address_to_range(token, data->data.range))
{
hub_free(data->data.range);
hub_free(data);
data = NULL;
status = cmd_status_arg_address;
}
break;
case 'n':
case 'm':
case 'p':
data = hub_malloc(sizeof(*data));
data->type = type_string;
data->data.string = strdup(token);
break;
case 'c':
data = hub_malloc(sizeof(*data));
data->type = type_command;
data->data.command = command_handler_lookup(hub->commands, token);
if (!data->data.command)
{
hub_free(data);
data = NULL;
status = cmd_status_arg_command;
}
break;
case 'C':
data = hub_malloc(sizeof(*data));
data->type = type_credentials;
if (!auth_string_to_cred(token, &data->data.credentials))
{
hub_free(data);
data = NULL;
status = cmd_status_arg_cred;
}
break;
case 'N':
data = hub_malloc(sizeof(*data));
data->type = type_integer;
if (!is_number(token, &data->data.integer))
{
hub_free(data);
data = NULL;
status = cmd_status_arg_number;
}
break;
case '\0':
if (!opt)
{
status = cmd_status_missing_args;
}
else
{
status = cmd_status_ok;
}
}
if (data)
{
list_append(args, data);
data = NULL;
}
list_remove(tokens, token);
hub_free(token);
}
hub_free(data);
return status;
}
static struct command_handle* command_get_handler(struct command_base* cbase, const char* prefix, const struct hub_user* user, struct hub_command* cmd)
{
struct command_handle* handler = NULL;
uhub_assert(cmd != NULL);
if (prefix && prefix[0] && prefix[1])
{
handler = command_handler_lookup(cbase, prefix + 1);
if (handler)
{
cmd->ptr = handler->ptr;
cmd->handler = handler->handler;
cmd->status = command_is_available(handler, user->credentials) ? cmd_status_ok : cmd_status_access_error;
}
else
{
cmd->status = cmd_status_not_found;
}
}
else
{
cmd->status = cmd_status_syntax_error;
}
return handler;
}
/**
* Parse a command and break it down into a struct hub_command.
*/
struct hub_command* command_parse(struct command_base* cbase, struct hub_info* hub, const struct hub_user* user, const char* message)
{
struct linked_list* tokens = list_create();
struct hub_command* cmd = NULL;
struct command_handle* handle = NULL;
cmd = hub_malloc_zero(sizeof(struct hub_command));
cmd->status = cmd_status_ok;
cmd->message = message;
cmd->prefix = NULL;
cmd->args = list_create();
cmd->user = user;
if (split_string(message, " ", tokens, 0) <= 0)
{
cmd->status = cmd_status_syntax_error;
goto command_parse_cleanup;
}
// Setup hub command.
cmd->prefix = strdup(((char*) list_get_first(tokens)) + 1);
// Find a matching command handler
handle = command_get_handler(cbase, list_get_first(tokens), user, cmd);
if (cmd->status != cmd_status_ok)
goto command_parse_cleanup;
// Parse arguments
cmd->status = command_extract_arguments(hub, user, handle, tokens, cmd->args);
goto command_parse_cleanup;
command_parse_cleanup:
list_clear(tokens, &hub_free);
list_destroy(tokens);
return cmd;
}
+131
View File
@@ -0,0 +1,131 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef HAVE_UHUB_COMMAND_PARSER_H
#define HAVE_UHUB_COMMAND_PARSER_H
struct hub_command;
struct hub_user;
struct command_base;
/**
* Parse a message as a command and return a status indicating if the command
* is valid and that the arguments are sane.
*
* @param cbase Command base pointer.
* @param user User who invoked the command.
* @param message The message that is to be interpreted as a command (including the invokation prefix '!' or '+')
*
* @return a hub_command that must be freed with command_free(). @See struct hub_command.
*/
extern struct hub_command* command_parse(struct command_base* cbase, struct hub_info* hub, const struct hub_user* user, const char* message);
/**
* Free a hub_command that was created in command_parse().
*/
extern void command_free(struct hub_command* command);
enum command_parse_status
{
cmd_status_ok, /** <<< "Everything seems to OK" */
cmd_status_not_found, /** <<< "Command was not found" */
cmd_status_access_error, /** <<< "You don't have access to this command" */
cmd_status_syntax_error, /** <<< "Not a valid command." */
cmd_status_missing_args, /** <<< "Missing some or all required arguments." */
cmd_status_arg_nick, /** <<< "A nick argument does not match an online user. ('n')" */
cmd_status_arg_cid, /** <<< "A cid argument does not match an online user. ('i')." */
cmd_status_arg_address, /** <<< "A address range argument is not valid ('a')." */
cmd_status_arg_number, /** <<< "A number argument is not valid ('N')" */
cmd_status_arg_cred, /** <<< "A credentials argument is not valid ('C')" */
cmd_status_arg_command, /** <<< "A command argument is not valid ('c')" */
};
enum hub_command_arg_type
{
type_integer,
type_string,
type_user,
type_address,
type_range,
type_credentials,
type_command
};
struct hub_command_arg_data
{
enum hub_command_arg_type type;
union {
int integer;
char* string;
struct hub_user* user;
struct ip_addr_encap* address;
struct ip_range* range;
enum auth_credentials credentials;
struct command_handle* command;
} data;
};
typedef int (*command_handler)(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd);
/**
* This struct contains all information needed to invoke
* a command, which includes the whole message, the prefix,
* the decoded arguments (according to parameter list), and
* the user pointer (ptr) which comes from the command it was matched to.
*
* The message and prefix is generally always available, but args only
* if status == cmd_status_ok.
* Handler and ptr are NULL if status == cmd_status_not_found, or status == cmd_status_access_error.
* Ptr might also be NULL if cmd_status_ok because the command that handles it was added with a NULL ptr.
*/
struct hub_command
{
const char* message; /**<<< "The complete message." */
char* prefix; /**<<< "The prefix extracted from the message." */
struct linked_list* args; /**<<< "List of arguments of type struct hub_command_arg_data. Parsed from message." */
enum command_parse_status status; /**<<< "Status of the parsed hub_command." */
command_handler handler; /**<<< "The function handler to call in order to invoke this command." */
const struct hub_user* user; /**<<< "The user who invoked this command." */
void* ptr; /**<<< "A pointer of data which came from struct command_handler" */
};
/**
* Reset the command argument iterator and return the number of arguments
* that can be extracted from a parsed command.
*
* @param cmd the command to start iterating arguments
* @return returns the number of arguments provided for the command
*/
extern size_t hub_command_arg_reset(struct hub_command* cmd);
/**
* Obtain the current argument and place it in data and increments the iterator.
* If no argument exists, or the argument is of a different type than \param type, then 0 is returned.
*
* NOTE: when calling hub_command_arg_next the first time during a command callback it is safe to assume
* that the first argument will be extracted. Thus you don't need to call hub_command_arg_reset().
*
* @param cmd the command used for iterating arguments.
* @param type the expected type of this argument
* @return NULL if no argument is found or if the argument found does not match the expected type.
*/
extern struct hub_command_arg_data* hub_command_arg_next(struct hub_command* cmd, enum hub_command_arg_type type);
#endif /* HAVE_UHUB_COMMAND_PARSER_H */
+623
View File
@@ -0,0 +1,623 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include "uhub.h"
#ifdef DEBUG
// #define DEBUG_UNLOAD_PLUGINS
#endif
#define MAX_HELP_MSG 16384
#define MAX_HELP_LINE 512
static int send_command_access_denied(struct command_base* cbase, struct hub_user* user, const char* prefix);
static int send_command_not_found(struct command_base* cbase, struct hub_user* user, const char* prefix);
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);
struct command_base
{
struct hub_info* hub;
struct linked_list* handlers;
size_t prefix_length_max;
};
struct command_base* command_initialize(struct hub_info* hub)
{
struct command_base* cbase = (struct command_base*) hub_malloc(sizeof(struct command_base));
uhub_assert(cbase != NULL);
// uhub_assert(hub != NULL);
cbase->hub = hub;
cbase->handlers = (struct linked_list*) list_create();
cbase->prefix_length_max = 0;
uhub_assert(cbase->handlers != NULL);
commands_builtin_add(cbase);
return cbase;
}
void command_shutdown(struct command_base* cbase)
{
commands_builtin_remove(cbase);
uhub_assert(list_size(cbase->handlers) == 0);
list_destroy(cbase->handlers);
hub_free(cbase);
}
int command_add(struct command_base* cbase, struct command_handle* cmd, void* ptr)
{
uhub_assert(cbase != NULL);
uhub_assert(cmd != NULL);
uhub_assert(cmd->length == strlen(cmd->prefix));
uhub_assert(cmd->handler != NULL);
uhub_assert(cmd->description && *cmd->description);
list_append(cbase->handlers, cmd);
cbase->prefix_length_max = MAX(cmd->length, cbase->prefix_length_max);
cmd->ptr = ptr;
return 1;
}
int command_del(struct command_base* cbase, struct command_handle* cmd)
{
uhub_assert(cbase != NULL);
uhub_assert(cmd != NULL);
list_remove(cbase->handlers, cmd);
return 1;
}
int command_is_available(struct command_handle* handle, enum auth_credentials credentials)
{
uhub_assert(handle != NULL);
return handle->cred <= credentials;
}
struct command_handle* command_handler_lookup(struct command_base* cbase, const char* prefix)
{
struct command_handle* handler = NULL;
size_t prefix_len = strlen(prefix);
LIST_FOREACH(struct command_handle*, handler, cbase->handlers,
{
if (prefix_len != handler->length)
continue;
if (!memcmp(prefix, handler->prefix, handler->length))
return handler;
});
return NULL;
}
void command_get_syntax(struct command_handle* handler, struct cbuffer* buf)
{
size_t n, arg_count;
int opt = 0;
char arg_code, last_arg = -1;
cbuf_append_format(buf, "!%s", handler->prefix);
if (handler->args)
{
arg_count = strlen(handler->args);
for (n = 0; n < arg_count; n++)
{
if (!strchr("?+", last_arg))
cbuf_append(buf, " ");
arg_code = handler->args[n];
switch (arg_code)
{
case '?': cbuf_append(buf, "["); opt++; break;
case '+': /* ignore */ break;
case 'n': cbuf_append(buf, "<nick>"); break;
case 'u': cbuf_append(buf, "<user>"); break;
case 'i': cbuf_append(buf, "<cid>"); break;
case 'a': cbuf_append(buf, "<addr>"); break;
case 'r': cbuf_append(buf, "<addr range>"); break;
case 'm': cbuf_append(buf, "<message>"); break;
case 'p': cbuf_append(buf, "<password>"); break;
case 'C': cbuf_append(buf, "<credentials>"); break;
case 'c': cbuf_append(buf, "<command>"); break;
case 'N': cbuf_append(buf, "<number>"); break;
default: LOG_ERROR("unknown argument code '%c'", arg_code);
}
last_arg = arg_code;
}
while (opt--)
cbuf_append(buf, "]");
}
}
void send_message(struct command_base* cbase, struct hub_user* user, struct cbuffer* buf)
{
char* buffer = adc_msg_escape(cbuf_get(buf));
struct adc_message* command = adc_msg_construct(ADC_CMD_IMSG, strlen(buffer) + 6);
adc_msg_add_argument(command, buffer);
route_to_user(cbase->hub, user, command);
adc_msg_free(command);
hub_free(buffer);
cbuf_destroy(buf);
}
static int send_command_access_denied(struct command_base* cbase, struct hub_user* user, const char* prefix)
{
struct cbuffer* buf = cbuf_create(128);
cbuf_append_format(buf, "*** %s: Access denied.", prefix);
send_message(cbase, user, buf);
return 0;
}
static int send_command_not_found(struct command_base* cbase, struct hub_user* user, const char* prefix)
{
struct cbuffer* buf = cbuf_create(128);
cbuf_append_format(buf, "*** %s: Command not found.", prefix);
send_message(cbase, user, buf);
return 0;
}
static int send_command_syntax_error(struct command_base* cbase, struct hub_user* user)
{
struct cbuffer* buf = cbuf_create(128);
cbuf_append(buf, "*** Syntax error.");
send_message(cbase, user, buf);
return 0;
}
static int send_command_missing_arguments(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
{
struct cbuffer* buf = cbuf_create(512);
cbuf_append_format(buf, "*** Missing argument: See !help %s\n", cmd->prefix);
send_message(cbase, user, buf);
return 0;
}
static size_t command_count_required_args(struct command_handle* handler)
{
size_t n = 0;
for (n = 0; n < strlen(handler->args); n++)
{
if (handler->args[n] == '?')
break;
}
return n;
}
int command_check_args(struct hub_command* cmd, struct command_handle* handler)
{
if (!handler->args)
return 1;
if (list_size(cmd->args) >= command_count_required_args(handler))
return 1;
return 0;
}
int command_invoke(struct command_base* cbase, struct hub_user* user, const char* message)
{
int ret = 0;
struct hub_command* cmd = command_parse(cbase, cbase->hub, user, message);
switch (cmd->status)
{
case cmd_status_ok:
ret = cmd->handler(cbase, user, cmd);
break;
case cmd_status_not_found:
ret = send_command_not_found(cbase, user, cmd->prefix);
break;
case cmd_status_access_error:
ret = send_command_access_denied(cbase, user, cmd->prefix);
break;
case cmd_status_missing_args:
ret = send_command_missing_arguments(cbase, user, cmd);
break;
case cmd_status_syntax_error:
case cmd_status_arg_nick:
case cmd_status_arg_cid:
case cmd_status_arg_address:
case cmd_status_arg_number:
case cmd_status_arg_cred:
case cmd_status_arg_command:
ret = send_command_syntax_error(cbase, user);
break;
}
command_free(cmd);
return ret;
}
size_t hub_command_arg_reset(struct hub_command* cmd)
{
cmd->args->iterator = NULL;
return list_size(cmd->args);
}
struct hub_command_arg_data* hub_command_arg_next(struct hub_command* cmd, enum hub_command_arg_type type)
{
struct hub_command_arg_data* ptr = (struct hub_command_arg_data*) list_get_next(cmd->args);
if (!ptr)
return NULL;
uhub_assert(ptr->type == type);
if (ptr->type != type)
return NULL;
return ptr;
}
static int command_status(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd, struct cbuffer* msg)
{
struct cbuffer* buf = cbuf_create(cbuf_size(msg) + strlen(cmd->prefix) + 7);
cbuf_append_format(buf, "*** %s: %s", cmd->prefix, cbuf_get(msg));
send_message(cbase, user, buf);
cbuf_destroy(msg);
return 0;
}
static int command_help(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
{
size_t n;
struct cbuffer* buf = cbuf_create(MAX_HELP_LINE);
struct hub_command_arg_data* data = hub_command_arg_next(cmd, type_command);
struct command_handle* command;
if (!data)
{
cbuf_append(buf, "Available commands:\n");
LIST_FOREACH(struct command_handle*, command, cbase->handlers,
{
if (command_is_available(command, user->credentials))
{
cbuf_append_format(buf, "!%s", command->prefix);
for (n = strlen(command->prefix); n < cbase->prefix_length_max; n++)
cbuf_append(buf, " ");
cbuf_append_format(buf, " - %s\n", command->description);
}
});
}
else
{
command = data->data.command;
if (command_is_available(command, user->credentials))
{
cbuf_append_format(buf, "Usage: ");
command_get_syntax(command, buf);
cbuf_append_format(buf, "\n%s\n", command->description);
}
else
{
cbuf_append(buf, "This command is not available to you.\n");
}
}
return command_status(cbase, user, cmd, buf);
}
static int command_uptime(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
{
struct cbuffer* buf = cbuf_create(128);
size_t d;
size_t h;
size_t m;
size_t D = (size_t) difftime(time(0), cbase->hub->tm_started);
d = D / (24 * 3600);
D = D % (24 * 3600);
h = D / 3600;
D = D % 3600;
m = D / 60;
if (d)
cbuf_append_format(buf, "%d day%s, ", (int) d, d != 1 ? "s" : "");
cbuf_append_format(buf, "%02d:%02d", (int) h, (int) m);
return command_status(cbase, user, cmd, buf);
}
static int command_kick(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
{
struct cbuffer* buf;
struct hub_command_arg_data* arg = hub_command_arg_next(cmd, type_user);
struct hub_user* target = arg->data.user;
buf = cbuf_create(128);
if (target == user)
{
cbuf_append(buf, "Cannot kick yourself.");
}
else
{
cbuf_append_format(buf, "Kicking user \"%s\".", target->id.nick);
hub_disconnect_user(cbase->hub, target, quit_kicked);
}
return command_status(cbase, user, cmd, buf);
}
static int command_reload(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
{
cbase->hub->status = hub_status_restart;
return command_status(cbase, user, cmd, cbuf_create_const("Reloading configuration..."));
}
#ifdef DEBUG_UNLOAD_PLUGINS
int hub_plugins_load(struct hub_info* hub);
int hub_plugins_unload(struct hub_info* hub);
static int command_load(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
{
hub_plugins_load(cbase->hub);
return command_status(cbase, user, cmd, cbuf_create_const("Loading plugins..."));
}
static int command_unload(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
{
hub_plugins_unload(cbase->hub);
return command_status(cbase, user, cmd, cbuf_create_const("Unloading plugins..."));
}
#endif /* DEBUG_UNLOAD_PLUGINS */
static int command_shutdown_hub(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
{
cbase->hub->status = hub_status_shutdown;
return command_status(cbase, user, cmd, cbuf_create_const("Hub shutting down..."));
}
static int command_version(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
{
struct cbuffer* buf;
if (cbase->hub->config->show_banner_sys_info)
buf = cbuf_create_const("Powered by " PRODUCT_STRING " on " OPSYS "/" CPUINFO);
else
buf = cbuf_create_const("Powered by " PRODUCT_STRING);
return command_status(cbase, user, cmd, buf);
}
static int command_myip(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
{
struct cbuffer* buf = cbuf_create(128);
cbuf_append_format(buf, "Your address is \"%s\"", user_get_address(user));
return command_status(cbase, user, cmd, buf);
}
static int command_getip(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
{
struct cbuffer* buf = cbuf_create(128);
struct hub_command_arg_data* arg = hub_command_arg_next(cmd, type_user);
cbuf_append_format(buf, "\"%s\" has address \"%s\"", arg->data.user->id.nick, user_get_address(arg->data.user));
return command_status(cbase, user, cmd, buf);
}
static int command_whoip(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
{
struct cbuffer* buf;
struct hub_command_arg_data* arg = hub_command_arg_next(cmd, type_range);
struct linked_list* users = (struct linked_list*) list_create();
struct hub_user* u;
int ret = 0;
ret = uman_get_user_by_addr(cbase->hub->users, users, arg->data.range);
if (!ret)
{
list_clear(users, NULL);
list_destroy(users);
return command_status(cbase, user, cmd, cbuf_create_const("No users found."));
}
buf = cbuf_create(128 + ((MAX_NICK_LEN + INET6_ADDRSTRLEN + 5) * ret));
cbuf_append_format(buf, "*** %s: Found %d match%s:\n", cmd->prefix, ret, ((ret != 1) ? "es" : ""));
LIST_FOREACH(struct hub_user*, u, users,
{
cbuf_append_format(buf, "%s (%s)\n", u->id.nick, user_get_address(u));
});
cbuf_append(buf, "\n");
send_message(cbase, user, buf);
list_clear(users, NULL);
list_destroy(users);
return 0;
}
static int command_broadcast(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
{
struct hub_command_arg_data* arg = hub_command_arg_next(cmd, type_string);
char* message = arg->data.string;
size_t message_len = strlen(message);
char pm_flag[7] = "PM";
char from_sid[5];
size_t recipients = 0;
struct hub_user* target;
struct cbuffer* buf = cbuf_create(128);
struct adc_message* command = NULL;
memcpy(from_sid, sid_to_string(user->id.sid), sizeof(from_sid));
memcpy(pm_flag + 2, from_sid, sizeof(from_sid));
LIST_FOREACH(struct hub_user*, target, cbase->hub->users->list,
{
if (target != user)
{
recipients++;
command = adc_msg_construct(ADC_CMD_DMSG, message_len + 23);
if (!command)
break;
adc_msg_add_argument(command, from_sid);
adc_msg_add_argument(command, sid_to_string(target->id.sid));
adc_msg_add_argument(command, message);
adc_msg_add_argument(command, pm_flag);
route_to_user(cbase->hub, target, command);
adc_msg_free(command);
}
});
cbuf_append_format(buf, "*** %s: Delivered to " PRINTF_SIZE_T " user%s", cmd->prefix, recipients, (recipients != 1 ? "s" : ""));
send_message(cbase, user, buf);
return 0;
}
static int command_log(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
{
struct cbuffer* buf;
struct hub_command_arg_data* arg = hub_command_arg_next(cmd, type_string);
struct linked_list* messages = cbase->hub->logout_info;
struct hub_logout_info* log;
char* search = arg ? arg->data.string : "";
size_t search_len = strlen(search);
size_t search_hits = 0;
if (!list_size(messages))
{
return command_status(cbase, user, cmd, cbuf_create_const("No entries logged."));
}
buf = cbuf_create(128);
cbuf_append_format(buf, "Logged entries: " PRINTF_SIZE_T, list_size(messages));
if (search_len)
{
cbuf_append_format(buf, ", searching for \"%s\"", search);
}
command_status(cbase, user, cmd, buf);
buf = cbuf_create(MAX_HELP_LINE);
LIST_FOREACH(struct hub_logout_info*, log, messages,
{
const char* address = ip_convert_to_string(&log->addr);
int show = 0;
if (search_len)
{
if (memmem(log->cid, MAX_CID_LEN, search, search_len) || memmem(log->nick, MAX_NICK_LEN, search, search_len) || memmem(address, strlen(address), search, search_len))
{
search_hits++;
show = 1;
}
}
else
{
show = 1;
}
if (show)
{
cbuf_append_format(buf, "* %s %s, %s [%s] - %s", get_timestamp(log->time), log->cid, log->nick, ip_convert_to_string(&log->addr), user_get_quit_reason_string(log->reason));
send_message(cbase, user, buf);
buf = cbuf_create(MAX_HELP_LINE);
}
});
if (search_len)
{
cbuf_append_format(buf, PRINTF_SIZE_T " entries shown.", search_hits);
command_status(cbase, user, cmd, buf);
buf = NULL;
}
if (buf)
cbuf_destroy(buf);
return 0;
}
static int command_stats(struct command_base* cbase, struct hub_user* user, struct hub_command* cmd)
{
struct cbuffer* buf = cbuf_create(128);
struct hub_info* hub = cbase->hub;
static char rxbuf[64] = { "0 B" };
static char txbuf[64] = { "0 B" };
cbuf_append(buf, "Hub statistics: ");
cbuf_append_format(buf, PRINTF_SIZE_T "/" PRINTF_SIZE_T " users (peak %d). ", hub->users->count, hub->config->max_users, hub->users->count_peak);
format_size(hub->stats.net_rx, rxbuf, sizeof(rxbuf));
format_size(hub->stats.net_tx, txbuf, sizeof(txbuf));
cbuf_append_format(buf, "Network: tx=%s/s, rx=%s/s", txbuf, rxbuf);
#ifdef SHOW_PEAK_NET_STATS /* currently disabled */
format_size(hub->stats.net_rx_peak, rxbuf, sizeof(rxbuf));
format_size(hub->stats.net_tx_peak, txbuf, sizeof(txbuf));
cbuf_append_format(buf, ", peak_tx=%s/s, peak_rx=%s/s", txbuf, rxbuf);
#endif
format_size(hub->stats.net_rx_total, rxbuf, sizeof(rxbuf));
format_size(hub->stats.net_tx_total, txbuf, sizeof(txbuf));
cbuf_append_format(buf, ", total_tx=%s", txbuf);
cbuf_append_format(buf, ", total_rx=%s", rxbuf);
return command_status(cbase, user, cmd, buf);
}
static struct command_handle* add_builtin(struct command_base* cbase, const char* prefix, const char* args, enum auth_credentials cred, command_handler handler, const char* description)
{
struct command_handle* handle = (struct command_handle*) hub_malloc_zero(sizeof(struct command_handle));
handle->prefix = prefix;
handle->length = strlen(prefix);
handle->args = args;
handle->cred = cred;
handle->handler = handler;
handle->description = description;
handle->origin = "built-in";
handle->ptr = cbase;
return handle;
}
#define ADD_COMMAND(PREFIX, LENGTH, ARGS, CREDENTIALS, FUNCTION, DESCRIPTION) \
command_add(cbase, add_builtin(cbase, PREFIX, ARGS, CREDENTIALS, FUNCTION, DESCRIPTION), NULL)
void commands_builtin_add(struct command_base* cbase)
{
ADD_COMMAND("broadcast", 9, "+m",auth_cred_operator, command_broadcast,"Send a message to all users" );
ADD_COMMAND("getip", 5, "u", auth_cred_operator, command_getip, "Show IP address for a user" );
ADD_COMMAND("help", 4, "?c",auth_cred_guest, command_help, "Show this help message." );
ADD_COMMAND("kick", 4, "u", auth_cred_operator, command_kick, "Kick a user" );
ADD_COMMAND("log", 3, "?m",auth_cred_operator, command_log, "Display log" ); // fail
ADD_COMMAND("myip", 4, "", auth_cred_guest, command_myip, "Show your own IP." );
ADD_COMMAND("reload", 6, "", auth_cred_admin, command_reload, "Reload configuration files." );
ADD_COMMAND("shutdown", 8, "", auth_cred_admin, command_shutdown_hub, "Shutdown hub." );
ADD_COMMAND("stats", 5, "", auth_cred_super, command_stats, "Show hub statistics." );
ADD_COMMAND("uptime", 6, "", auth_cred_guest, command_uptime, "Display hub uptime info." );
ADD_COMMAND("version", 7, "", auth_cred_guest, command_version, "Show hub version info." );
ADD_COMMAND("whoip", 5, "r", auth_cred_operator, command_whoip, "Show users matching IP range" );
#ifdef DEBUG_UNLOAD_PLUGINS
ADD_COMMAND("load", 4, "", auth_cred_admin, command_load, "Load plugins." );
ADD_COMMAND("unload", 6, "", auth_cred_admin, command_unload, "Unload plugins." );
#endif /* DEBUG_UNLOAD_PLUGINS */
}
void commands_builtin_remove(struct command_base* cbase)
{
struct command_handle* command;
while ((command = list_get_first(cbase->handlers)))
{
command_del(cbase, command);
hub_free(command);
}
}
+109
View File
@@ -0,0 +1,109 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef HAVE_UHUB_COMMANDS_H
#define HAVE_UHUB_COMMANDS_H
struct command_base;
struct command_handle;
struct hub_command;
/**
* Argument codes are used to automatically parse arguments
* for a a hub command.
*
* u = user (must exist in hub session, or will cause error)
* n = nick name (string)
* i = CID (must exist in hub)
* a = (IP) address (must be a valid IPv4 or IPv6 address)
* r = (IP) address range (either: IP-IP or IP/mask, both IPv4 or IPv6 work)
* m = message (string)
* p = password (string)
* C = credentials (see auth_string_to_cred).
* c = command (name of command)
* N = number (integer)
*
* Prefix an argument with ? to make it optional.
* Prefix with + to make the argument greedy, which causes it to grab the rest of the line ignoring boundaries (only supported for string types).
*
* NOTE: if an argument is optional then all following arguments must also be optional.
* NOTE: You can combine optional and greedy, example: "?+m" would match "", "a", "a b c", etc.
*
* Example:
* "nia" means "nick cid ip"
* "n?p" means "nick [password]" where password is optional.
* "?N?N" means zero, one, or two integers.
* "?NN" means zero or two integers.
* "?+m" means an optional string which may contain spaces that would otherwise be split into separate arguments.
*/
struct command_handle
{
const char* prefix; /**<<< "Command prefix, for instance 'help' would be the prefix for the !help command." */
size_t length; /**<<< "Length of the prefix" */
const char* args; /**<<< "Argument codes (see above)" */
enum auth_credentials cred; /**<<< "Minimum access level for the command" */
command_handler handler; /**<<< "Function pointer for the command" */
const char* description; /**<<< "Description for the command" */
const char* origin; /**<<< "Name of module where the command is implemented." */
void* ptr; /**<<< "A pointer which will be passed along to the handler. @See hub_command::ptr" */
};
/**
* Returns NULL on error, or handle
*/
extern struct command_base* command_initialize(struct hub_info* hub);
extern void command_shutdown(struct command_base* cbase);
/**
* Add a new command to the command base.
* Returns 1 on success, or 0 on error.
*/
extern int command_add(struct command_base*, struct command_handle*, void* ptr);
/**
* Remove a command from the command base.
* Returns 1 on success, or 0 on error.
*/
extern int command_del(struct command_base*, struct command_handle*);
/**
* Dispatch a message and forward it as a command.
* Returns 1 if the message should be forwarded as a chat message, or 0 if
* it is supposed to be handled internally in the dispatcher.
*
* This will break the message down into a struct hub_command and invoke the command handler
* for that command if the sufficient access credentials are met.
*/
extern int command_invoke(struct command_base*, struct hub_user* user, const char* message);
/**
* Returns 1 if the command handle can be used with the given credentials, 0 otherwise.
*/
int command_is_available(struct command_handle* handle, enum auth_credentials credentials);
/**
* Lookup a command handle based on prefix.
* If no matching command handle is found then NULL is returned.
*/
struct command_handle* command_handler_lookup(struct command_base* cbase, const char* prefix);
extern void commands_builtin_add(struct command_base*);
extern void commands_builtin_remove(struct command_base*);
#endif /* HAVE_UHUB_COMMANDS_H */
+140
View File
@@ -0,0 +1,140 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include "uhub.h"
#ifndef INT_MAX
#define INT_MAX 0x7fffffff
#endif
#ifndef INT_MIN
#define INT_MIN (-0x7fffffff - 1)
#endif
static int apply_boolean(const char* key, const char* data, int* target)
{
return string_to_boolean(data, target);
}
static int apply_string(const char* key, const char* data, char** target, char* regexp)
{
(void) regexp;
// FIXME: Add regexp checks for correct data
if (*target)
hub_free(*target);
*target = hub_strdup(data);
return 1;
}
static int apply_integer(const char* key, const char* data, int* target, int* min, int* max)
{
char* endptr;
int val;
errno = 0;
val = strtol(data, &endptr, 10);
if (((errno == ERANGE && (val == INT_MAX || val == INT_MIN)) || (errno != 0 && val == 0)) || endptr == data)
return 0;
if (min && val < *min)
return 0;
if (max && val > *max)
return 0;
*target = val;
return 1;
}
#include "gen_config.c"
static int config_parse_line(char* line, int line_count, void* ptr_data)
{
char* pos;
char* key;
char* data;
struct hub_config* config = (struct hub_config*) ptr_data;
strip_off_ini_line_comments(line, line_count);
if (!*line) return 0;
LOG_DUMP("config_parse_line(): '%s'", line);
if (!is_valid_utf8(line))
{
LOG_WARN("Invalid utf-8 characters on line %d", line_count);
}
if ((pos = strchr(line, '=')) != NULL)
{
pos[0] = 0;
}
else
{
return 0;
}
key = line;
data = &pos[1];
key = strip_white_space(key);
data = strip_white_space(data);
data = strip_off_quotes(data);
if (!*key || !*data)
{
LOG_FATAL("Configuration parse error on line %d", line_count);
return -1;
}
LOG_DUMP("config_parse_line: '%s' => '%s'", key, data);
return apply_config(config, key, data, line_count);
}
int read_config(const char* file, struct hub_config* config, int allow_missing)
{
int ret;
memset(config, 0, sizeof(struct hub_config));
config_defaults(config);
ret = file_read_lines(file, config, &config_parse_line);
if (ret < 0)
{
if (allow_missing && ret == -2)
{
LOG_DUMP("Using default configuration.");
}
else
{
return -1;
}
}
return 0;
}
+55
View File
@@ -0,0 +1,55 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef HAVE_UHUB_CONFIG_H
#define HAVE_UHUB_CONFIG_H
#include "gen_config.h"
/**
* This initializes the configuration variables, and sets the default
* variables.
*
* NOTE: Any variable is set to it's default variable if zero.
* This function is automatically called in read_config to set any
* configuration that was missing there.
*/
extern void config_defaults(struct hub_config* config);
/**
* Read configuration from file, and use the default variables for
* the missing variables.
*
* @return -1 on error, 0 on success.
*/
extern int read_config(const char* file, struct hub_config* config, int allow_missing);
/**
* Free the configuration data (allocated by read_config, or config_defaults).
*/
extern void free_config(struct hub_config* config);
/**
* Print all configuration data to standard out.
*/
extern void dump_config(struct hub_config* config, int ignore_defaults);
#endif /* HAVE_UHUB_CONFIG_H */
+255
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);
+695
View File
@@ -0,0 +1,695 @@
<?xml version='1.0' standalone="yes" ?>
<config>
<option name="hub_enabled" type="boolean" default="1">
<short>Is server enabled</short>
<description><![CDATA[
Use this to disable the hub for a while.
]]></description>
<since>0.1.3</since>
</option>
<option name="server_port" type="int" default="1511">
<check min="1" max="65535" />
<since>0.1.0</since>
<short>Server port to bind to</short>
<description><![CDATA[This specifies the port number the hub should listen on.]]></description>
</option>
<option name="server_bind_addr" type="string" default="any">
<check regexp="[\x:.]+|any|loopback" />
<short>Server bind address</short>
<description><![CDATA[
Specify the IP address the local hub should bind to. This can be an IPv4 or IPv6 address, or one of the special addresses "any" or "loopback". <br />
When "any" or "loopback" is used, the hub will automatically detect if IPv6 is supported and prefer that.
]]></description>
<syntax>
IPv4 address, IPv6 address, "any" or "loopback"
</syntax>
<since>0.1.2</since>
<example><![CDATA[
<p>
To listen to a specific IP:<br />
server_bind_addr = "192.168.12.69"
</p>
<p>
To listen to any IPv4 address:<br />
server_bind_addr = "0.0.0.0"
</p>
<p>
Or to listen to any address including IPv6 (if supported):<br />
server_bind_addr = "any"
</p>
]]></example>
</option>
<option name="server_listen_backlog" type="int" default="50">
<check min="5" />
<short>Server listen backlog</short>
<description><![CDATA[
<p>
This specifies the number of connections the hub will be able to accept in the backlog before they must be processed by the hub.
</p>
<p>
A too low number here will mean the hub will not accept connections fast enough when users are reconnecting really fast. The hub should under normal circumstances be able to empty the listen backlog several times per second.
</p>
]]></description>
<since>0.3.0</since>
</option>
<option name="server_alt_ports" type="string" default="">
<check regexp="\d+(,\d+)*" />
<short>Comma separated list of alternative ports to listen to</short>
<description><![CDATA[
In addition to the server_port the hub can listen to a list of alternative ports.
]]></description>
<example><![CDATA[
server_alt_ports = 1295,1512,53990
]]></example>
<since>0.3.0</since>
</option>
<option name="show_banner" type="boolean" default="1">
<short>Show banner on connect</short>
<description><![CDATA[
If enabled, the hub will announce the software version running to clients when they connect with a message like: "Powered by uhub/0.x.y"
]]></description>
<since>0.1.0</since>
</option>
<option name="show_banner_sys_info" type="boolean" default="1">
<short>Show banner on connect</short>
<description><![CDATA[
If enabled, the hub will announce the operating system and CPU architecture to clients when they join.<br />
This option has no effect if show_banner is disabled.
]]></description>
<since>0.3.0</since>
</option>
<option name="max_users" type="int" default="500">
<check min="1" max="1048576" />
<short>Maximum number of users allowed on the hub</short>
<description><![CDATA[
The maximum amount of users allowed on the hub.
No new users will be allowed to enter the hub if this number is exceeded, however privileged users (operators, admins, etc) are still able to log in.
]]></description>
<since>0.1.0</since>
<example><![CDATA[
To run a hub for max 25 users:<br />
max_users = 25
]]></example>
</option>
<option name="registered_users_only" type="boolean" default="0">
<short>Allow registered users only</short>
<description><![CDATA[
If this is enabled only registered users will be able to use the hub. A user must be registered in the acl file (file_acl).
]]></description>
<since>0.1.1</since>
</option>
<option name="register_self" type="boolean" default="0">
<short>Allow users to register themselves on the hub.</short>
<description><![CDATA[
If this is enabled guests can register their nickname on the hub using !register command.
Otherwise only operators can register users.
]]></description>
<since>0.4.0</since>
</option>
<option name="obsolete_clients" type="boolean" default="0">
<short>Support obsolete clients using a ADC protocol prior to 1.0</short>
<description><![CDATA[
If this is enabled users using old ADC clients are allowed to enter the hub,
however they cannot log in using passwords since the protocols are incompatible.
]]></description>
<since>0.3.1</since>
</option>
<option name="chat_is_privileged" type="boolean" default="0">
<short>Allow chat for operators and above only</short>
<description><![CDATA[
If enabled only operators and admins are allowed to chat in the main chat.
]]></description>
<since>0.2.4</since>
</option>
<option name="hub_name" type="string" default="uhub">
<short>Name of hub</short>
<description><![CDATA[
Configures the name of the hub
]]></description>
<since>0.1.0</since>
<example><![CDATA[
hub_name = "my hub"
]]></example>
</option>
<option name="hub_description" type="string" default="no description">
<short>Short hub description, topic or subject.</short>
<description><![CDATA[
This is the description of the hub, as seen by users and hub lists.
]]></description>
<since>0.1.0</since>
<example><![CDATA[
hub_description = "a friendly hub for friendly people"
]]></example>
</option>
<option name="redirect_addr" type="string" default="">
<check regexp="(adcs?|dchub)://.*" />
<short>A common hub redirect address.</short>
<description><![CDATA[
This is the redirect address used when the hub wants to redirect a client for not fulfilling some requirements.
]]></description>
<since>0.3.2</since>
</option>
<option name="max_recv_buffer" type="int" default="4096" advanced="true" >
<check min="1024" max="1048576" />
<short>Max read buffer before parse, per user</short>
<description><![CDATA[
Maximum receive buffer allowed before commands are procesed. If a single ADC message exceeds this limit, it will be discarded by the hub. Use with caution.
]]></description>
<since>0.1.3</since>
</option>
<option name="max_send_buffer" type="int" default="131072" advanced="true" >
<check min="2048" />
<short>Max send buffer before disconnect, per user</short>
<description><![CDATA[
Maximum amount of bytes allowed to be queued for sending to any particular user before the hub will disconnect the user. The lower the limit, the more aggressive the hub will be to disconnect slow clients. Use with caution.
]]></description>
<since>0.1.3</since>
</option>
<option name="max_send_buffer_soft" type="int" default="98304" advanced="true" >
<check min="1024" />
<short>Max send buffer before message drops, per user</short>
<description><![CDATA[
Same as max_send_buffer, however low priority messages may be discarded if this limit is reached. Use with caution.
]]></description>
<since>0.1.3</since>
</option>
<option name="low_bandwidth_mode" type="boolean" default="0" advanced="true" >
<short>Enable bandwidth saving measures</short>
<description><![CDATA[
If this is enabled the hub will remove excessive information from each user's info message before broadcasting to all connected users.
Description, e-mail address will be removed. This saves upload bandwidth for the hub.
]]></description>
<since>0.2.2</since>
</option>
<option name="max_chat_history" type="int" default="20">
<check min="0" max="250" />
<short>Number of chat messages kept in history</short>
<description><![CDATA[
This specifies the number of main chat messages that are kept in the history buffer.
Users can use the "!history" command to list these messages.
]]></description>
<since>0.3.0</since>
</option>
<option name="max_logout_log" type="int" default="20">
<check min="0" max="2000" />
<short>Number of log entries for people leaving the hub</short>
<description><![CDATA[
Operators can use the "!log" command to list users who have recently left the hub.
This option specifies the maximum size of this log.
]]></description>
<since>0.3.0</since>
</option>
<option name="limit_max_hubs_user" type="int" default="10">
<check min="0" />
<short>Max concurrent hubs as a guest user</short>
<description><![CDATA[
This limits the number of hubs a user can be logged into as a guest user. If this number is exceeded, the user will not be allowed to enter the hub.
]]></description>
<syntax>0 = off</syntax>
<since>0.2.0</since>
</option>
<option name="limit_max_hubs_reg" type="int" default="10">
<check min="0" />
<short>Max concurrent hubs as a registered user</short>
<description><![CDATA[
This limits the number of hubs a user can be logged into as a registered user. If this number is exceeded, the user will not be allowed to enter the hub.
]]></description>
<syntax>0 = off</syntax>
<since>0.2.0</since>
</option>
<option name="limit_max_hubs_op" type="int" default="10">
<check min="0" />
<short>Max concurrent hubs as a operator (or admin)</short>
<description><![CDATA[
This limits the number of hubs a user can be logged into as an operator. If this number is exceeded, the user will not be allowed to enter the hub.
]]></description>
<syntax>0 = off</syntax>
<since>0.2.0</since>
</option>
<option name="limit_max_hubs" type="int" default="25">
<check min="0" />
<short>Max total hub connections allowed, user/reg/op combined.</short>
<description><![CDATA[
Limit the number of hubs a user can be logged into in total regardless of registrations or privileges.
If this number is exceeded, the user will not be allowed to enter the hub.
]]></description>
<syntax>0 = off</syntax>
<since>0.2.0</since>
</option>
<option name="limit_min_hubs_user" type="int" default="0">
<check min="0" />
<short>Minimum concurrent hubs as a guest user</short>
<description><![CDATA[
Only allow users that are logged into other hubs with guest privileges to enter this hub.
]]></description>
<syntax>0 = off</syntax>
<since>0.2.0</since>
</option>
<option name="limit_min_hubs_reg" type="int" default="0">
<check min="0" />
<short>Minimum concurrent hubs as a registered user</short>
<description><![CDATA[
Only allow users that are logged into other hubs as a registered user to enter this hub.
]]></description>
<syntax>0 = off</syntax>
<since>0.2.0</since>
</option>
<option name="limit_min_hubs_op" type="int" default="0">
<check min="0" />
<short>Minimum concurrent hubs as a operator (or admin)</short>
<description><![CDATA[
Only allow users that are logged into other hubs with operator privileges to enter this hub.
]]></description>
<syntax>0 = off</syntax>
<since>0.2.0</since>
</option>
<option name="limit_min_share" type="int" default="0">
<check min="0" />
<short>Limit minimum share size in megabytes</short>
<description><![CDATA[
Minimum share limit in megabytes (MiB). Users sharing less than this will not be allowed to enter the hub.
]]></description>
<syntax>0 = off</syntax>
<since>0.2.0</since>
<example><![CDATA[
To require users to share at least 1 GB in order to enter the hub:<br />
limit_min_share = 1024
]]></example>
</option>
<option name="limit_max_share" type="int" default="0">
<check min="0" />
<short>Limit maximum share size in megabytes</short>
<description><![CDATA[
Maximum share limit in megabytes (MiB). Users sharing more than this will not be allowed to enter the hub.
]]></description>
<syntax>0 = off</syntax>
<since>0.2.0</since>
</option>
<option name="limit_min_slots" type="int" default="0">
<check min="0" />
<short>Limit minimum number of upload slots open per user</short>
<description><![CDATA[
Minimum number of upload slots required. Users with less than this will not be allowed to enter the hub.
]]></description>
<syntax>0 = off</syntax>
<since>0.2.0</since>
</option>
<option name="limit_max_slots" type="int" default="0">
<check min="0" />
<short>Limit minimum number of upload slots open per user</short>
<description><![CDATA[
Maximum number of upload slots allowed. Users with more than this will not be allowed to enter the hub.
]]></description>
<syntax>0 = off</syntax>
<since>0.2.0</since>
</option>
<option name="flood_ctl_interval" type="int" default="0">
<check min="1" max="60" />
<short>Time interval in seconds for flood control check.</short>
<description><![CDATA[
This is the time interval that will be used for all flood control calculations.
If this is 0 then all flood control is disabled.
]]></description>
<example><![CDATA[
To limit maximum chat messages to 5 messages on 10 seconds: <br />
flood_ctl_interval = 10 <br />
flood_ctl_chat = 5<br />
]]></example>
<syntax>0 = off</syntax>
<since>0.3.1</since>
</option>
<option name="flood_ctl_chat" type="int" default="0">
<short>Max chat messages allowed in time interval</short>
<description><![CDATA[
If this is 0 then no flood control is disabled for chat messages.
]]></description>
<syntax>0 = off</syntax>
<since>0.3.1</since>
</option>
<option name="flood_ctl_connect" type="int" default="0">
<short>Max connections requests allowed in time interval</short>
<description><![CDATA[
If this is 0 then no flood control is disabled for connection requests.
]]></description>
<syntax>0 = off</syntax>
<since>0.3.1</since>
</option>
<option name="flood_ctl_search" type="int" default="0">
<short>Max search requests allowed in time interval</short>
<description><![CDATA[
If this is 0 then no flood control is disabled for search requests.
]]></description>
<syntax>0 = off</syntax>
<since>0.3.1</since>
</option>
<option name="flood_ctl_update" type="int" default="0">
<short>Max updates allowed in time interval</short>
<description><![CDATA[
If this is 0 then no flood control is disabled for info updates (INF messages).
]]></description>
<syntax>0 = off</syntax>
<since>0.3.1</since>
</option>
<option name="flood_ctl_extras" type="int" default="0">
<short>Max extra messages allowed in time interval</short>
<description><![CDATA[
Extra messages are messages that don't fit into the category of chat, search, update or connect.
]]></description>
<syntax>0 = off</syntax>
<since>0.3.1</since>
</option>
<option name="tls_enable" type="boolean" default="0">
<short>Enable SSL/TLS support</short>
<description><![CDATA[
Enables/disables TLS/SSL support. tls_certificate and tls_private_key must be set if this is enabled.
]]></description>
<since>0.3.0</since>
</option>
<option name="tls_require" type="boolean" default="0">
<short>If SSL/TLS enabled, should it be required</short>
<description><![CDATA[
If TLS/SSL support is enabled it can either be optional or mandatory.
If this option is disabled then SSL/TLS is not required to enter the hub, however it is possible to enter either with or without.
This option has no effect unless tls_enable is enabled.
]]></description>
<since>0.3.0</since>
</option>
<option name="tls_require_redirect_addr" type="string" default="">
<check regexp="(adcs?|dchub)://.*" />
<short>A redirect address in case a client connects using "adc://" when "adcs://" is required.</short>
<description><![CDATA[
This is the redirect address used when the hub wants to redirect a client for not using ADCS.
For instance a hub at adc://adc.example.com might redirect to adcs://adc.example.com
]]></description>
<since>0.3.3</since>
</option>
<option name="tls_certificate" type="file" default="">
<short>Certificate file</short>
<description><![CDATA[
Path to a TLS/SSL certificate or certificate chain (PEM format).
]]></description>
<since>0.3.0</since>
</option>
<option name="tls_private_key" type="file" default="">
<short>Private key file</short>
<description><![CDATA[
Path to a TLS/SSL private key (PEM format).
]]></description>
<since>0.3.0</since>
</option>
<option name="tls_ciphersuite" type="string" default="ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS">
<short>List of TLS ciphers to use</short>
<description><![CDATA[
This is a colon separated list of preferred ciphers in the OpenSSL format.
]]></description>
<since>0.5.0</since>
<example><![CDATA[
<p>
High security with emphasis on forward secrecy:<br />
tls_ciphersuite = "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS"
</p>
<p>
Allow ChaCha20/Poly1305 which are secure, yet generally faster:<br />
tls_ciphersuite = "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA"
</p>
]]></example>
</option>
<option name="tls_version" type="string" default="1.2">
<short>Specify minimum TLS version supported.</short>
<description><![CDATA[
<p>
This allows you to specify the minimum TLS version the hub requires from connecting clients in order to
connect to the hub.
</p>
<p>
TLS version 1.2 is recommended and enabled by default.
TLS version 1.1 is acceptable without any known flaws, and allows for older clients to connect.
TLS version 1.0 should be avoided, even though it is the most compatible with older ADC clients.
</p>
]]></description>
<since>0.5.0</since>
</option>
<option name="file_acl" type="file" default="">
<short>File containing access control lists</short>
<description><![CDATA[
This is an access control list (acl) file.
In this file all registered users, bans, etc should be stored.
If the file is missing, or empty no registered users, or ban records are used.
]]></description>
<since>0.1.3</since>
<example><![CDATA[
<p>
Unix users: <br />
file_acl = "/etc/uhub/users.conf"
</p>
<p>
Windows users: <br />
file_acl = "c:\uhub\users.conf"
</p>
]]></example>
</option>
<option name="file_plugins" type="file" default="">
<short>Plugin configuration file</short>
<description><![CDATA[
Plugin configuration file.
]]></description>
<since>0.3.3</since>
<example><![CDATA[
<p>
file_plugins = "/etc/uhub/plugins.conf"
</p>
]]></example>
</option>
<option name="msg_hub_full" type="message" default="Hub is full" >
<description><![CDATA[This will be sent if the hub is full]]></description>
<since>0.2.0</since>
</option>
<option name="msg_hub_disabled" type="message" default="Hub is disabled" >
<description><![CDATA[This will be sent if the hub is disabled (hub_enable = off)]]></description>
<since>0.2.0</since>
</option>
<option name="msg_hub_registered_users_only" type="message" default="Hub is for registered users only" >
<description><![CDATA[This will be sent if the hub is configured to only accept registered users (registered_users_only = yes)]]></description>
<since>0.2.0</since>
</option>
<option name="msg_inf_error_nick_missing" type="message" default="No nickname given">
<description><![CDATA[This is an error message that will be sent to clients that do not provide a nickname.]]></description>
<since>0.2.0</since>
</option>
<option name="msg_inf_error_nick_multiple" type="message" default="Multiple nicknames given">
<description><![CDATA[This is an error message that will be sent to clients that provide multiple nicknames.]]></description>
<since>0.2.0</since>
</option>
<option name="msg_inf_error_nick_invalid" type="message" default="Nickname is invalid">
<description><![CDATA[This is an error message that will be sent to clients that provides an invalid nickname.]]></description>
<since>0.2.0</since>
</option>
<option name="msg_inf_error_nick_long" type="message" default="Nickname too long">
<description><![CDATA[This is an error message that will be sent to clients that provides a too long nickname.]]></description>
<since>0.2.0</since>
</option>
<option name="msg_inf_error_nick_short" type="message" default="Nickname too short">
<description><![CDATA[This is an error message that will be sent to clients that provides a too short nickname.]]></description>
<since>0.2.0</since>
</option>
<option name="msg_inf_error_nick_spaces" type="message" default="Nickname cannot start with spaces">
<description><![CDATA[This is an error message that will be sent to clients that provides a nickname that starts with a space.]]></description>
<since>0.2.0</since>
</option>
<option name="msg_inf_error_nick_bad_chars" type="message" default="Nickname contains invalid characters">
<description><![CDATA[This is an error message that will be sent to clients that provides invalid characters in the nickname.]]></description>
<since>0.2.0</since>
</option>
<option name="msg_inf_error_nick_not_utf8" type="message" default="Nickname is not valid UTF-8">
<description><![CDATA[This is an error message that will be sent to clients that provides a nick name that is not valid UTF-8 encoded.]]></description>
<since>0.2.0</since>
</option>
<option name="msg_inf_error_nick_taken" type="message" default="Nickname is already in use">
<description><![CDATA[This message will be sent to clients if their provided nickname is alredy in use on the hub.]]></description>
<since>0.2.0</since>
</option>
<option name="msg_inf_error_nick_restricted" type="message" default="Nickname cannot be used on this hub">
<description><![CDATA[This message will be sent to clients if they provide a restricted nickname. Restricted names can be configured in the acl.]]></description>
<since>0.2.0</since>
</option>
<option name="msg_inf_error_cid_invalid" type="message" default="CID is not valid">
<description><![CDATA[This is an error message that will be sent to clients that provides an invalid client ID (CID)]]></description>
<since>0.2.0</since>
</option>
<option name="msg_inf_error_cid_missing" type="message" default="CID is not specified">
<description><![CDATA[This is an error message that will be sent to clients that does not provide a client ID (CID)]]></description>
<since>0.2.0</since>
</option>
<option name="msg_inf_error_cid_taken" type="message" default="CID is taken">
<description><![CDATA[This is an error message that will be sent to clients that provides a client ID (CID) already in use on the hub.]]></description>
<since>0.2.0</since>
</option>
<option name="msg_inf_error_pid_missing" type="message" default="PID is not specified">
<description><![CDATA[This is an error message that will be sent to clients that does not provide a private ID (PID)]]></description>
<since>0.2.0</since>
</option>
<option name="msg_inf_error_pid_invalid" type="message" default="PID is invalid">
<description><![CDATA[This is an error message that will be sent to clients that provides an invalid private ID (PID)]]></description>
<since>0.2.0</since>
</option>
<option name="msg_ban_permanently" type="message" default="Banned permanently">
<description><![CDATA[This message is sent to users if they are banned (see acl)]]></description>
<since>0.2.0</since>
</option>
<option name="msg_ban_temporarily" type="message" default="Banned temporarily">
<description><![CDATA[This message is sent to users if they are banned temporarily]]></description>
<since>0.2.0</since>
</option>
<option name="msg_auth_invalid_password" type="message" default="Password is wrong">
<description><![CDATA[This message is sent to users if they provide a wrong password.]]></description>
<since>0.2.0</since>
</option>
<option name="msg_auth_user_not_found" type="message" default="User not found in password database">
<description><![CDATA[This message is used if a user cannot be found in the password database.]]></description>
<since>0.2.0</since> <!-- FIXME? -->
</option>
<option name="msg_error_no_memory" type="message" default="No memory">
<description><![CDATA[Hub has no more memory]]></description>
<since>0.2.0</since>
</option>
<option name="msg_user_share_size_low" type="message" default="User is not sharing enough">
<description><![CDATA[This message is sent to users if they are not sharing enough.]]></description>
<since>0.2.0</since>
</option>
<option name="msg_user_share_size_high" type="message" default="User is sharing too much">
<description><![CDATA[This message is sent to users if they are sharing too much.]]></description>
<since>0.2.0</since>
</option>
<option name="msg_user_slots_low" type="message" default="User have too few upload slots.">
<description><![CDATA[This message is sent to users if they do not have enough upload slots.]]></description>
<since>0.2.0</since>
</option>
<option name="msg_user_slots_high" type="message" default="User have too many upload slots.">
<description><![CDATA[This message is sent to users if they have too many upload slots.]]></description>
<since>0.2.0</since>
</option>
<option name="msg_user_hub_limit_low" type="message" default="User is on too few hubs.">
<description><![CDATA[This message is sent to users if they are on too few other hubs.]]></description>
<since>0.2.0</since>
</option>
<option name="msg_user_hub_limit_high" type="message" default="User is on too many hubs.">
<description><![CDATA[This message is sent to users if they are on too many other hubs.]]></description>
<since>0.2.0</since>
</option>
<option name="msg_user_flood_chat" type="message" default="Chat flood detected, messages are dropped.">
<description><![CDATA[This message is sent once to users who are flooding the chat.]]></description>
<since>0.3.1</since>
</option>
<option name="msg_user_flood_connect" type="message" default="Connect flood detected, connection refused.">
<description><![CDATA[This message is sent once to users who are sending too many connect requests too fast.]]></description>
<since>0.3.1</since>
</option>
<option name="msg_user_flood_search" type="message" default="Search flood detected, search is stopped.">
<description><![CDATA[This message is sent once to users who are sending too many search requests too fast.]]></description>
<since>0.3.1</since>
</option>
<option name="msg_user_flood_update" type="message" default="Update flood detected.">
<description><![CDATA[This message is sent once to users who are sending too many updates too fast.]]></description>
<since>0.3.1</since>
</option>
<option name="msg_user_flood_extras" type="message" default="Flood detected.">
<description><![CDATA[This message is sent once to users who are sending too many messages to the hub that neither are chat, searhes, updates nor connection requests..]]></description>
<since>0.3.1</since>
</option>
<option name="msg_proto_no_common_hash" type="message" default="No common hash algorithm.">
<description><![CDATA[This message is sent if a client connects that does support ADC/1.0 but not a hash algorithm that the hub supports.]]></description>
<since>0.3.1</since>
</option>
<option name="msg_proto_obsolete_adc0" type="message" default="Client is using an obsolete ADC protocol version.">
<description><![CDATA[This message is sent if a client connects that does not support ADC/1.0, but rather the obsolete ADC/0.1 version.]]></description>
<since>0.3.1</since>
</option>
</config>
+41
View File
@@ -0,0 +1,41 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef HAVE_UHUB_EVENT_ID_H
#define HAVE_UHUB_EVENT_ID_H
/* User join or quit messages */
#define UHUB_EVENT_USER_JOIN 0x1001
#define UHUB_EVENT_USER_QUIT 0x1002
#define UHUB_EVENT_USER_DESTROY 0x1003
/* Send a broadcast message */
#define UHUB_EVENT_BROADCAST 0x2000
/* Shutdown hub */
#define UHUB_EVENT_HUB_SHUTDOWN 0x3001
/* Statistics, OOM, reconfigure */
#define UHUB_EVENT_STATISTICS 0x4000
#define UHUB_EVENT_OUT_OF_MEMORY 0x4001
#define UHUB_EVENT_RECONFIGURE 0x4002
#endif /* HAVE_UHUB_EVENT_ID_H */
+136
View File
@@ -0,0 +1,136 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include "uhub.h"
#ifdef EQ_DEBUG
static void eq_debug(const char* prefix, struct event_data* data)
{
LOG_DUMP(">>> %s: %p, id: %x, flags=%d\n", prefix, data, data->id, data->flags);
}
#endif
int event_queue_initialize(struct event_queue** queue, event_queue_callback callback, void* ptr)
{
*queue = (struct event_queue*) hub_malloc_zero(sizeof(struct event_queue));
if (!(*queue))
return -1;
(*queue)->q1 = list_create();
(*queue)->q2 = list_create();
if (!(*queue)->q1 || !(*queue)->q2)
{
list_destroy((*queue)->q1);
list_destroy((*queue)->q2);
return -1;
}
(*queue)->callback = callback;
(*queue)->callback_data = ptr;
return 0;
}
void event_queue_shutdown(struct event_queue* queue)
{
/* Should be empty at this point! */
list_destroy(queue->q1);
list_destroy(queue->q2);
hub_free(queue);
}
static void event_queue_cleanup_callback(void* ptr)
{
#ifdef EQ_DEBUG
struct event_data* data = (struct event_data*) ptr;
eq_debug("NUKE", data);
#endif
hub_free((struct event_data*) ptr);
}
int event_queue_process(struct event_queue* queue)
{
struct event_data* data;
if (queue->locked)
return 0;
/* lock primary queue, and handle the primary queue messages. */
queue->locked = 1;
LIST_FOREACH(struct event_data*, data, queue->q1,
{
#ifdef EQ_DEBUG
eq_debug("EXEC", data);
#endif
queue->callback(queue->callback_data, data);
});
list_clear(queue->q1, event_queue_cleanup_callback);
uhub_assert(list_size(queue->q1) == 0);
/* unlock queue */
queue->locked = 0;
/* transfer from secondary queue to the primary queue. */
list_append_list(queue->q1, queue->q2);
/* if more events exist, schedule it */
if (list_size(queue->q1))
{
return 1;
}
return 0;
}
void event_queue_post(struct event_queue* queue, struct event_data* message)
{
struct linked_list* q = (!queue->locked) ? queue->q1 : queue->q2;
struct event_data* data;
data = (struct event_data*) hub_malloc(sizeof(struct event_data));
if (data)
{
data->id = message->id;
data->ptr = message->ptr;
data->flags = message->flags;
#ifdef EQ_DEBUG
eq_debug("POST", data);
#endif
list_append(q, data);
}
else
{
LOG_ERROR("event_queue_post: OUT OF MEMORY");
}
}
size_t event_queue_size(struct event_queue* queue)
{
return list_size(queue->q1) + list_size(queue->q2);
}
+48
View File
@@ -0,0 +1,48 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef HAVE_UHUB_EVENT_QUEUE_H
#define HAVE_UHUB_EVENT_QUEUE_H
struct event_data
{
int id;
void* ptr;
int flags;
};
typedef void (*event_queue_callback)(void* callback_data, struct event_data* event_data);
struct event_queue
{
int locked;
struct linked_list* q1; /* primary */
struct linked_list* q2; /* secondary, when primary is locked */
event_queue_callback callback;
void* callback_data;
};
extern int event_queue_initialize(struct event_queue** queue, event_queue_callback callback, void* ptr);
extern int event_queue_process(struct event_queue* queue);
extern void event_queue_shutdown(struct event_queue* queue);
extern void event_queue_post(struct event_queue* queue, struct event_data* message);
extern size_t event_queue_size(struct event_queue* queue);
#endif /* HAVE_UHUB_EVENT_QUEUE_H */
File diff suppressed because it is too large Load Diff
+95
View File
@@ -0,0 +1,95 @@
/*
* 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
{
int hub_enabled; /*<<< Is server enabled (default: 1) */
int server_port; /*<<< Server port to bind to (default: 1511) */
char* server_bind_addr; /*<<< Server bind address (default: "any") */
int server_listen_backlog; /*<<< Server listen backlog (default: 50) */
char* server_alt_ports; /*<<< Comma separated list of alternative ports to listen to (default: "") */
int show_banner; /*<<< Show banner on connect (default: 1) */
int show_banner_sys_info; /*<<< Show banner on connect (default: 1) */
int max_users; /*<<< Maximum number of users allowed on the hub (default: 500) */
int registered_users_only; /*<<< Allow registered users only (default: 0) */
int register_self; /*<<< Allow users to register themselves on the hub. (default: 0) */
int obsolete_clients; /*<<< Support obsolete clients using a ADC protocol prior to 1.0 (default: 0) */
int chat_is_privileged; /*<<< Allow chat for operators and above only (default: 0) */
char* hub_name; /*<<< Name of hub (default: "uhub") */
char* hub_description; /*<<< Short hub description, topic or subject. (default: "no description") */
char* redirect_addr; /*<<< A common hub redirect address. (default: "") */
int max_recv_buffer; /*<<< Max read buffer before parse, per user (default: 4096) */
int max_send_buffer; /*<<< Max send buffer before disconnect, per user (default: 131072) */
int max_send_buffer_soft; /*<<< Max send buffer before message drops, per user (default: 98304) */
int low_bandwidth_mode; /*<<< Enable bandwidth saving measures (default: 0) */
int max_chat_history; /*<<< Number of chat messages kept in history (default: 20) */
int max_logout_log; /*<<< Number of log entries for people leaving the hub (default: 20) */
int limit_max_hubs_user; /*<<< Max concurrent hubs as a guest user (default: 10) */
int limit_max_hubs_reg; /*<<< Max concurrent hubs as a registered user (default: 10) */
int limit_max_hubs_op; /*<<< Max concurrent hubs as a operator (or admin) (default: 10) */
int limit_max_hubs; /*<<< Max total hub connections allowed, user/reg/op combined. (default: 25) */
int limit_min_hubs_user; /*<<< Minimum concurrent hubs as a guest user (default: 0) */
int limit_min_hubs_reg; /*<<< Minimum concurrent hubs as a registered user (default: 0) */
int limit_min_hubs_op; /*<<< Minimum concurrent hubs as a operator (or admin) (default: 0) */
int limit_min_share; /*<<< Limit minimum share size in megabytes (default: 0) */
int limit_max_share; /*<<< Limit maximum share size in megabytes (default: 0) */
int limit_min_slots; /*<<< Limit minimum number of upload slots open per user (default: 0) */
int limit_max_slots; /*<<< Limit minimum number of upload slots open per user (default: 0) */
int flood_ctl_interval; /*<<< Time interval in seconds for flood control check. (default: 0) */
int flood_ctl_chat; /*<<< Max chat messages allowed in time interval (default: 0) */
int flood_ctl_connect; /*<<< Max connections requests allowed in time interval (default: 0) */
int flood_ctl_search; /*<<< Max search requests allowed in time interval (default: 0) */
int flood_ctl_update; /*<<< Max updates allowed in time interval (default: 0) */
int flood_ctl_extras; /*<<< Max extra messages allowed in time interval (default: 0) */
int tls_enable; /*<<< Enable SSL/TLS support (default: 0) */
int tls_require; /*<<< If SSL/TLS enabled, should it be required (default: 0) */
char* tls_require_redirect_addr; /*<<< A redirect address in case a client connects using "adc://" when "adcs://" is required. (default: "") */
char* tls_certificate; /*<<< Certificate file (default: "") */
char* tls_private_key; /*<<< Private key file (default: "") */
char* tls_ciphersuite; /*<<< List of TLS ciphers to use (default: "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS") */
char* tls_version; /*<<< Specify minimum TLS version supported. (default: "1.2") */
char* file_acl; /*<<< File containing access control lists (default: "") */
char* file_plugins; /*<<< Plugin configuration file (default: "") */
char* msg_hub_full; /*<<< "Hub is full" */
char* msg_hub_disabled; /*<<< "Hub is disabled" */
char* msg_hub_registered_users_only; /*<<< "Hub is for registered users only" */
char* msg_inf_error_nick_missing; /*<<< "No nickname given" */
char* msg_inf_error_nick_multiple; /*<<< "Multiple nicknames given" */
char* msg_inf_error_nick_invalid; /*<<< "Nickname is invalid" */
char* msg_inf_error_nick_long; /*<<< "Nickname too long" */
char* msg_inf_error_nick_short; /*<<< "Nickname too short" */
char* msg_inf_error_nick_spaces; /*<<< "Nickname cannot start with spaces" */
char* msg_inf_error_nick_bad_chars; /*<<< "Nickname contains invalid characters" */
char* msg_inf_error_nick_not_utf8; /*<<< "Nickname is not valid UTF-8" */
char* msg_inf_error_nick_taken; /*<<< "Nickname is already in use" */
char* msg_inf_error_nick_restricted; /*<<< "Nickname cannot be used on this hub" */
char* msg_inf_error_cid_invalid; /*<<< "CID is not valid" */
char* msg_inf_error_cid_missing; /*<<< "CID is not specified" */
char* msg_inf_error_cid_taken; /*<<< "CID is taken" */
char* msg_inf_error_pid_missing; /*<<< "PID is not specified" */
char* msg_inf_error_pid_invalid; /*<<< "PID is invalid" */
char* msg_ban_permanently; /*<<< "Banned permanently" */
char* msg_ban_temporarily; /*<<< "Banned temporarily" */
char* msg_auth_invalid_password; /*<<< "Password is wrong" */
char* msg_auth_user_not_found; /*<<< "User not found in password database" */
char* msg_error_no_memory; /*<<< "No memory" */
char* msg_user_share_size_low; /*<<< "User is not sharing enough" */
char* msg_user_share_size_high; /*<<< "User is sharing too much" */
char* msg_user_slots_low; /*<<< "User have too few upload slots." */
char* msg_user_slots_high; /*<<< "User have too many upload slots." */
char* msg_user_hub_limit_low; /*<<< "User is on too few hubs." */
char* msg_user_hub_limit_high; /*<<< "User is on too many hubs." */
char* msg_user_flood_chat; /*<<< "Chat flood detected, messages are dropped." */
char* msg_user_flood_connect; /*<<< "Connect flood detected, connection refused." */
char* msg_user_flood_search; /*<<< "Search flood detected, search is stopped." */
char* msg_user_flood_update; /*<<< "Update flood detected." */
char* msg_user_flood_extras; /*<<< "Flood detected." */
char* msg_proto_no_common_hash; /*<<< "No common hash algorithm." */
char* msg_proto_obsolete_adc0; /*<<< "Client is using an obsolete ADC protocol version." */
};
+1331
View File
File diff suppressed because it is too large Load Diff
+355
View File
@@ -0,0 +1,355 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef HAVE_UHUB_HUB_H
#define HAVE_UHUB_HUB_H
enum status_message
{
status_msg_hub_full = -1, /* hub is full */
status_msg_hub_disabled = -2, /* hub is disabled */
status_msg_hub_registered_users_only = -3, /* hub is for registered users only */
status_msg_inf_error_nick_missing = -4, /* no nickname given */
status_msg_inf_error_nick_multiple = -5, /* multiple nicknames given */
status_msg_inf_error_nick_invalid = -6, /* generic/unknown */
status_msg_inf_error_nick_long = -7, /* nickname too long */
status_msg_inf_error_nick_short = -8, /* nickname too short */
status_msg_inf_error_nick_spaces = -9, /* nickname cannot start with spaces */
status_msg_inf_error_nick_bad_chars = -10, /* nickname contains chars below ascii 32 */
status_msg_inf_error_nick_not_utf8 = -11, /* nickname is not valid utf8 */
status_msg_inf_error_nick_taken = -12, /* nickname is in use */
status_msg_inf_error_nick_restricted = -13, /* nickname cannot be used on this hub */
status_msg_inf_error_cid_invalid = -14, /* CID is not valid (generic error) */
status_msg_inf_error_cid_missing = -15, /* CID is not specified */
status_msg_inf_error_cid_taken = -16, /* CID is taken (already logged in?). */
status_msg_inf_error_pid_missing = -17, /* PID is not specified */
status_msg_inf_error_pid_invalid = -18, /* PID is invalid */
status_msg_ban_permanently = -19, /* Banned permanently */
status_msg_ban_temporarily = -20, /* Banned temporarily */
status_msg_auth_invalid_password = -21, /* Password is wrong */
status_msg_auth_user_not_found = -22, /* User not found in password database */
status_msg_error_no_memory = -23, /* Hub is out of memory */
status_msg_user_share_size_low = -40, /* User is not sharing enough. */
status_msg_user_share_size_high = -41, /* User is sharing too much. */
status_msg_user_slots_low = -42, /* User has too few slots open. */
status_msg_user_slots_high = -43, /* User has too many slots open. */
status_msg_user_hub_limit_low = -44, /* User is on too few hubs. */
status_msg_user_hub_limit_high = -45, /* User is on too many hubs. */
status_msg_proto_no_common_hash = -50, /* No common hash algorithms */
status_msg_proto_obsolete_adc0 = -51, /* Client is using an obsolete protocol version */
};
enum hub_state
{
hub_status_uninitialized = 0, /**<<<"Hub is uninitialized" */
hub_status_running = 1, /**<<<"Hub is running (normal operation)" */
hub_status_restart = 2, /**<<<"Hub is restarting (re-reading configuration, etc)" */
hub_status_shutdown = 3, /**<<<"Hub is shutting down, but not yet stopped. */
hub_status_stopped = 4, /**<<<"Hub is stopped (Pretty much the same as initialized) */
hub_status_disabled = 5, /**<<<"Hub is disabled (Running, but not accepting users) */
};
/**
* Always updated each minute.
*/
struct hub_stats
{
size_t net_tx;
size_t net_rx;
size_t net_tx_peak;
size_t net_rx_peak;
size_t net_tx_total;
size_t net_rx_total;
struct timeout_evt* timeout; /**<< "Timeout handler for statistics" */
};
struct hub_logout_info
{
time_t time;
char cid[MAX_CID_LEN+1];
char nick[MAX_NICK_LEN+1];
struct ip_addr_encap addr;
enum user_quit_reason reason;
};
struct hub_info
{
struct net_connection* server;
struct linked_list* server_alt_ports;
struct hub_stats stats;
struct event_queue* queue;
struct hub_config* config;
struct hub_user_manager* users;
struct acl_handle* acl;
struct adc_message* command_info; /* The hub's INF command */
struct adc_message* command_support; /* The hub's SUP command */
struct adc_message* command_banner; /* The default welcome message */
time_t tm_started;
int status;
char* recvbuf; /* Global receive buffer */
char* sendbuf; /* Global send buffer */
struct linked_list* logout_info; /* Log of people logging out. */
struct command_base* commands; /* Hub command handler */
struct uhub_plugins* plugins; /* Plug-ins loaded for this hub instance. */
#ifdef SSL_SUPPORT
struct ssl_context_handle* ctx;
#endif /* SSL_SUPPORT */
};
/**
* This is the message pre-routing centre.
*
* Any message coming in to the hub comes through here first,
* and will be routed further if valid.
*
* @return 0 on success, -1 on error
*/
extern int hub_handle_message(struct hub_info* hub, struct hub_user* u, const char* message, size_t length);
/**
* Handle protocol support/subscription messages received clients.
*
* @return 0 on success, -1 on error
*/
extern int hub_handle_support(struct hub_info* hub, struct hub_user* u, struct adc_message* cmd);
/**
* Handle password messages received from clients.
*
* @return 0 on success, -1 on error
*/
extern int hub_handle_password(struct hub_info* hub, struct hub_user* u, struct adc_message* cmd);
/**
* Handle chat messages received from clients.
* @return 0 on success, -1 on error.
*/
extern int hub_handle_chat_message(struct hub_info* hub, struct hub_user* u, struct adc_message* cmd);
/**
* Used internally by hub_handle_info
* @return 1 if nickname is OK, or 0 if nickname is not accepted.
*/
extern int hub_handle_info_check_nick(struct hub_info* hub, struct hub_user* u, struct adc_message* cmd);
/**
* Used internally by hub_handle_info
* @return 1 if CID/PID is OK, or 0 if not valid.
*/
extern int hub_handle_info_check_cid(struct hub_info* hub, struct hub_user* u, struct adc_message* cmd);
/**
* Send the support line for the hub to a particular user.
* Only used during the initial handshake.
*/
extern void hub_send_support(struct hub_info* hub, struct hub_user* u);
/**
* Send a message assigning a SID for a user.
* This is only sent after hub_send_support() during initial handshake.
*/
extern void hub_send_sid(struct hub_info* hub, struct hub_user* u);
/**
* Send a 'ping' message to user.
*/
extern void hub_send_ping(struct hub_info* hub, struct hub_user* user);
/**
* Send a message containing hub information to a particular user.
* This is sent during user connection, but can safely be sent at any
* point later.
*/
extern void hub_send_hubinfo(struct hub_info* hub, struct hub_user* u);
/**
* Send handshake. This basically calls
* hub_send_support() and hub_send_sid()
*/
extern void hub_send_handshake(struct hub_info* hub, struct hub_user* u);
/**
* Send a password challenge to a user.
* This is only used if the user tries to access the hub using a
* password protected nick name.
*/
extern void hub_send_password_challenge(struct hub_info* hub, struct hub_user* u);
/**
* Sends a status_message to a user.
*/
extern void hub_send_status(struct hub_info*, struct hub_user* user, enum status_message msg, enum msg_status_level level);
/**
* Warn user about flooding.
*/
extern void hub_send_flood_warning(struct hub_info*, struct hub_user* user, const char* message);
/**
* Allocates memory, initializes the hub based on the configuration,
* and returns a hub handle.
* This hub handle must be passed to hub_shutdown_service() in order to cleanup before exiting.
*
* @return a pointer to the hub info.
*/
extern struct hub_info* hub_start_service(struct hub_config* config);
/**
* This shuts down the hub.
*/
extern void hub_shutdown_service(struct hub_info* hub);
/**
* This configures the hub.
*/
extern void hub_set_variables(struct hub_info* hub, struct acl_handle* acl);
/**
* This frees the configuration of the hub.
*/
extern void hub_free_variables(struct hub_info* hub);
/**
* Returns a string for the given status_message (See enum status_message).
*/
extern const char* hub_get_status_message(struct hub_info* hub, enum status_message msg);
extern const char* hub_get_status_message_log(struct hub_info* hub, enum status_message msg);
/**
* Returns the number of logged in users on the hub.
*/
extern size_t hub_get_user_count(struct hub_info* hub);
/**
* Returns the maximum number of allowed users on the hub.
*/
extern size_t hub_get_max_user_count(struct hub_info* hub);
/**
* Returns the accumulated shared size for all logged in
* users on the hub.
*/
extern uint64_t hub_get_shared_size(struct hub_info* hub);
/**
* Returns the accumulated number of files for all logged
* in users on the hub.
*/
extern uint64_t hub_get_shared_files(struct hub_info* hub);
/**
* Returns the minimal share size limit as enforced by
* this hub's configuration.
*/
extern uint64_t hub_get_min_share(struct hub_info* hub);
/**
* Returns the minimal share size limit as enforced by
* this hub's configuration.
*/
extern uint64_t hub_get_max_share(struct hub_info* hub);
/**
* Returns the minimum upload slot limit as enforced by
* this hub's configuration.
* Users with fewer slots in total will not be allowed
* to enter the hub.
* @return limit or 0 if no limit.
*/
extern size_t hub_get_min_slots(struct hub_info* hub);
/**
* Returns the maximum upload slot limit as enforced by
* this hub's configuration.
* Users with more allowed upload slots will not be
* allowed to enter the hub.
* @return limit or 0 if no limit.
*/
extern size_t hub_get_max_slots(struct hub_info* hub);
/**
* Returns the maximum number of hubs a user can
* be logged in to simultaneously as a regular user (guest).
* Users on more hubs will not be allowed to stay on this hub.
* @return limit or 0 if no limit.
*/
extern size_t hub_get_max_hubs_user(struct hub_info* hub);
extern size_t hub_get_min_hubs_user(struct hub_info* hub);
/**
* Returns the maximum number of hubs a user can
* be logged in to simultaneously as a registered user (password required).
* Users on more hubs will not be allowed to stay on this hub.
* @return limit or 0 if no limit.
*/
extern size_t hub_get_max_hubs_reg(struct hub_info* hub);
extern size_t hub_get_min_hubs_reg(struct hub_info* hub);
/**
* Returns the maximum number of hubs a user can
* be logged in to simultaneously as an operator.
* Users who are operator on more than this amount of hubs
* will not be allowed to stay on this hub.
* @return limit or 0 if no limit.
*/
extern size_t hub_get_max_hubs_op(struct hub_info* hub);
extern size_t hub_get_min_hubs_op(struct hub_info* hub);
/**
* Returns the maximum number of hubs a user can
* be logged in to simultaneously regardless of the type of user.
*/
extern size_t hub_get_max_hubs_total(struct hub_info* hub);
/**
* Schedule runslice.
*/
extern void hub_schedule_runslice(struct hub_info* hub);
/**
* Run event loop.
*/
extern void hub_event_loop(struct hub_info* hub);
/**
* Schedule destroying a user.
*/
extern void hub_schedule_destroy_user(struct hub_info* hub, struct hub_user* user);
/**
* Disconnect a user from the hub.
*/
extern void hub_disconnect_user(struct hub_info* hub, struct hub_user* user, int reason);
/**
* Log a user logging out.
*/
extern void hub_logout_log(struct hub_info* hub, struct hub_user* user);
#endif /* HAVE_UHUB_HUB_H */
+73
View File
@@ -0,0 +1,73 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include "uhub.h"
#include "plugin_api/handle.h"
/* Notify plugins, etc */
void on_login_success(struct hub_info* hub, struct hub_user* u)
{
/* Send user list of all existing users */
if (!uman_send_user_list(hub, hub->users, u))
return;
/* Mark as being in the normal state, and add user to the user list */
user_set_state(u, state_normal);
uman_add(hub->users, u);
/* Announce new user to all connected users */
if (user_is_logged_in(u))
route_info_message(hub, u);
plugin_log_user_login_success(hub, u);
/* reset timeout */
net_con_clear_timeout(u->connection);
}
void on_login_failure(struct hub_info* hub, struct hub_user* u, enum status_message msg)
{
plugin_log_user_login_error(hub, u, hub_get_status_message_log(hub, msg));
hub_send_status(hub, u, msg, status_level_fatal);
hub_disconnect_user(hub, u, quit_logon_error);
}
void on_update_failure(struct hub_info* hub, struct hub_user* u, enum status_message msg)
{
plugin_log_user_update_error(hub, u, hub_get_status_message_log(hub, msg));
hub_send_status(hub, u, msg, status_level_fatal);
hub_disconnect_user(hub, u, quit_update_error);
}
void on_nick_change(struct hub_info* hub, struct hub_user* u, const char* nick)
{
if (user_is_logged_in(u))
{
plugin_log_user_nick_change(hub, u, nick);
}
}
void on_logout_user(struct hub_info* hub, struct hub_user* user)
{
const char* reason = user_get_quit_reason_string(user->quit_reason);
plugin_log_user_logout(hub, user, reason);
hub_logout_log(hub, user);
}
+46
View File
@@ -0,0 +1,46 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef HAVE_UHUB_HUB_EVENT_H
#define HAVE_UHUB_HUB_EVENT_H
/**
* This event is triggered whenever a user successfully logs in to the hub.
*/
extern void on_login_success(struct hub_info* hub, struct hub_user* u);
/**
* This event is triggered whenever a user failed to log in to the hub.
*/
extern void on_login_failure(struct hub_info* hub, struct hub_user* u, enum status_message msg);
extern void on_update_failure(struct hub_info* hub, struct hub_user* u, enum status_message msg);
/**
* This event is triggered whenever a previously logged in user leaves the hub.
*/
extern void on_logout_user(struct hub_info* hub, struct hub_user* u);
/**
* This event is triggered whenever a user changes his/her nickname.
*/
extern void on_nick_change(struct hub_info* hub, struct hub_user* u, const char* nick);
#endif /* HAVE_UHUB_HUB_EVENT_H */
+829
View File
@@ -0,0 +1,829 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include "uhub.h"
/*
* These flags can only be set by the hub.
* Make sure we don't allow clients to specify these themselves.
*
* NOTE: Some of them are legacy ADC flags and no longer used, these
* should be removed at some point in the future when functionality no
* longer depend on them.
*/
static void remove_server_restricted_flags(struct adc_message* cmd)
{
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE); /* Client type flag (CT, obsoletes BO, RG, OP, HU) */
adc_msg_remove_named_argument(cmd, "BO"); /* Obsolete: bot flag (CT) */
adc_msg_remove_named_argument(cmd, "RG"); /* Obsolete: registered user flag (CT) */
adc_msg_remove_named_argument(cmd, "OP"); /* Obsolete: operator flag (CT) */
adc_msg_remove_named_argument(cmd, "HU"); /* Obsolete: hub flag (CT) */
adc_msg_remove_named_argument(cmd, "HI"); /* Obsolete: hidden user flag */
adc_msg_remove_named_argument(cmd, "TO"); /* Client to client token - should not be seen here */
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_REFERER);
}
static int set_feature_cast_supports(struct hub_user* u, struct adc_message* cmd)
{
char *it, *tmp;
if (adc_msg_has_named_argument(cmd, ADC_INF_FLAG_SUPPORT))
{
tmp = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_SUPPORT);
if (!tmp)
return -1; // FIXME: OOM
user_clear_feature_cast_support(u);
it = tmp;
while (strlen(it) > 4)
{
it[4] = 0; /* FIXME: Not really needed */
user_set_feature_cast_support(u, it);
it = &it[5];
}
if (*it)
{
user_set_feature_cast_support(u, it);
}
hub_free(tmp);
}
return 0;
}
static int check_hash_tiger(const char* cid, const char* pid)
{
char x_pid[64];
char raw_pid[64];
uint64_t tiger_res[3];
memset(x_pid, 0, MAX_CID_LEN+1);
base32_decode(pid, (unsigned char*) raw_pid, MAX_CID_LEN);
tiger((uint64_t*) raw_pid, TIGERSIZE, (uint64_t*) tiger_res);
base32_encode((unsigned char*) tiger_res, TIGERSIZE, x_pid);
x_pid[MAX_CID_LEN] = 0;
if (strncasecmp(x_pid, cid, MAX_CID_LEN) == 0)
return 1;
return 0;
}
/*
* FIXME: Only works for tiger hash. If a client doesnt support tiger we cannot let it in!
*/
static int check_cid(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
{
size_t pos;
char* cid = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_CLIENT_ID);
char* pid = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_PRIVATE_ID);
if (!cid || !pid)
{
hub_free(cid);
hub_free(pid);
return status_msg_error_no_memory;
}
if (strlen(cid) != MAX_CID_LEN)
{
hub_free(cid);
hub_free(pid);
return status_msg_inf_error_cid_invalid;
}
if (strlen(pid) != MAX_CID_LEN)
{
hub_free(cid);
hub_free(pid);
return status_msg_inf_error_pid_invalid;
}
for (pos = 0; pos < MAX_CID_LEN; pos++)
{
if (!is_valid_base32_char(cid[pos]))
{
hub_free(cid);
hub_free(pid);
return status_msg_inf_error_cid_invalid;
}
if (!is_valid_base32_char(pid[pos]))
{
hub_free(cid);
hub_free(pid);
return status_msg_inf_error_pid_invalid;
}
}
if (!check_hash_tiger(cid, pid))
{
hub_free(cid);
hub_free(pid);
return status_msg_inf_error_cid_invalid;
}
/* Set the cid in the user object */
memcpy(user->id.cid, cid, MAX_CID_LEN);
user->id.cid[MAX_CID_LEN] = 0;
hub_free(cid);
hub_free(pid);
return 0;
}
static int check_required_login_flags(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
{
int num = 0;
num = adc_msg_has_named_argument(cmd, ADC_INF_FLAG_CLIENT_ID);
if (num != 1)
{
if (!num)
return status_msg_inf_error_cid_missing;
return status_msg_inf_error_cid_invalid;
}
num = adc_msg_has_named_argument(cmd, ADC_INF_FLAG_PRIVATE_ID);
if (num != 1)
{
if (!num)
return status_msg_inf_error_pid_missing;
return status_msg_inf_error_pid_invalid;
}
num = adc_msg_has_named_argument(cmd, ADC_INF_FLAG_NICK);
if (num != 1)
{
if (!num)
return status_msg_inf_error_nick_missing;
return status_msg_inf_error_nick_multiple;
}
return 0;
}
/**
* This will check the ip address of the user, and
* remove any wrong address, and replace it with the correct one
* as seen by the hub.
*/
static int check_network(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
{
const char* address = user_get_address(user);
/* Check for NAT override address */
if (acl_is_ip_nat_override(hub->acl, address))
{
char* client_given_ip = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR);
if (client_given_ip && strcmp(client_given_ip, "0.0.0.0") != 0)
{
user_set_nat_override(user);
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV6_ADDR);
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV6_UDP_PORT);
hub_free(client_given_ip);
return 0;
}
hub_free(client_given_ip);
}
if (strchr(address, '.'))
{
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV6_ADDR);
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV6_UDP_PORT);
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR);
adc_msg_add_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR, address);
}
else if (strchr(address, ':'))
{
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR);
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV4_UDP_PORT);
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV6_ADDR);
adc_msg_add_named_argument(cmd, ADC_INF_FLAG_IPV6_ADDR, address);
}
return 0;
}
static void strip_network(struct hub_user* user, struct adc_message* cmd)
{
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV6_ADDR);
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_IPV4_ADDR);
}
static int nick_length_ok(const char* nick)
{
size_t length = strlen(nick);
if (length <= 1)
{
return nick_invalid_short;
}
if (length > MAX_NICK_LEN)
{
return nick_invalid_long;
}
return nick_ok;
}
static int nick_bad_characters(const char* nick)
{
const char* tmp;
/* Nick must not start with a space */
if (nick[0] == ' ')
return nick_invalid_spaces;
/* Check for ASCII values below 32 */
for (tmp = nick; *tmp; tmp++)
if ((*tmp < 32) && (*tmp > 0))
return nick_invalid_bad_ascii;
return nick_ok;
}
static int nick_is_utf8(const char* nick)
{
/*
* Nick should be valid utf-8, but
* perhaps we should check if the nick is unicode normalized?
*/
if (!is_valid_utf8(nick))
return nick_invalid_bad_utf8;
return nick_ok;
}
static int check_nick(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
{
char* nick;
char* tmp;
enum nick_status status;
tmp = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_NICK);
if (!tmp) return 0;
nick = adc_msg_unescape(tmp);
free(tmp); tmp = 0;
if (!nick) return 0;
status = nick_length_ok(nick);
if (status != nick_ok)
{
hub_free(nick);
if (status == nick_invalid_short)
return status_msg_inf_error_nick_short;
return status_msg_inf_error_nick_long;
}
status = nick_bad_characters(nick);
if (status != nick_ok)
{
hub_free(nick);
if (status == nick_invalid_spaces)
return status_msg_inf_error_nick_spaces;
return status_msg_inf_error_nick_bad_chars;
}
status = nick_is_utf8(nick);
if (status != nick_ok)
{
hub_free(nick);
return status_msg_inf_error_nick_not_utf8;
}
if (user_is_connecting(user))
{
memcpy(user->id.nick, nick, strlen(nick));
user->id.nick[strlen(nick)] = 0;
}
hub_free(nick);
return 0;
}
static int check_logged_in(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
{
struct hub_user* lookup1 = uman_get_user_by_nick(hub->users, user->id.nick);
struct hub_user* lookup2 = uman_get_user_by_cid(hub->users, user->id.cid);
if (lookup1 == user)
{
return 0;
}
if (lookup1 || lookup2)
{
if (lookup1 == lookup2)
{
LOG_DEBUG("check_logged_in: exact same user is logged in: %s", user->id.nick);
hub_disconnect_user(hub, lookup1, quit_ghost_timeout);
return 0;
}
else
{
if (lookup1)
{
LOG_DEBUG("check_logged_in: nickname is in use: %s", user->id.nick);
return status_msg_inf_error_nick_taken;
}
else
{
LOG_DEBUG("check_logged_in: CID is in use: %s", user->id.cid);
return status_msg_inf_error_cid_taken;
}
}
}
return 0;
}
/*
* It is possible to do user-agent checking here.
* But this is not something we want to do, and is deprecated in the ADC specification.
* One should rather look at capabilities/features.
*/
static int check_user_agent(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
{
char* ua_name_encoded = 0;
char* ua_version_encoded = 0;
char* str = 0;
size_t offset = 0;
/* Get client user agent version */
ua_name_encoded = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_USER_AGENT_PRODUCT);
ua_version_encoded = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_USER_AGENT_VERSION);
if (ua_name_encoded)
{
str = adc_msg_unescape(ua_name_encoded);
if (str)
{
offset = strlen(str);
memcpy(user->id.user_agent, str, MIN(offset, MAX_UA_LEN));
hub_free(str);
}
}
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;
}
static int check_acl(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
{
if (acl_is_cid_banned(hub->acl, user->id.cid))
{
return status_msg_ban_permanently;
}
if (acl_is_user_banned(hub->acl, user->id.nick))
{
return status_msg_ban_permanently;
}
if (acl_is_user_denied(hub->acl, user->id.nick))
{
return status_msg_inf_error_nick_restricted;
}
return 0;
}
static int check_limits(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
{
char* arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_SHARED_SIZE);
if (arg)
{
int64_t shared_size = atoll(arg);
if (shared_size < 0)
shared_size = 0;
if (user_is_logged_in(user))
{
hub->users->shared_size -= user->limits.shared_size;
hub->users->shared_size += shared_size;
}
user->limits.shared_size = shared_size;
hub_free(arg);
arg = 0;
}
arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_SHARED_FILES);
if (arg)
{
int shared_files = atoi(arg);
if (shared_files < 0)
shared_files = 0;
if (user_is_logged_in(user))
{
hub->users->shared_files -= user->limits.shared_files;
hub->users->shared_files += shared_files;
}
user->limits.shared_files = shared_files;
hub_free(arg);
arg = 0;
}
arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_NORMAL);
if (arg)
{
int num = atoi(arg);
if (num < 0) num = 0;
user->limits.hub_count_user = num;
hub_free(arg);
arg = 0;
}
arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_REGISTER);
if (arg)
{
int num = atoi(arg);
if (num < 0) num = 0;
user->limits.hub_count_registered = num;
hub_free(arg);
arg = 0;
}
arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_OPERATOR);
if (arg)
{
int num = atoi(arg);
if (num < 0) num = 0;
user->limits.hub_count_operator = num;
hub_free(arg);
arg = 0;
}
arg = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_UPLOAD_SLOTS);
if (arg)
{
int num = atoi(arg);
if (num < 0) num = 0;
user->limits.upload_slots = num;
hub_free(arg);
arg = 0;
}
/* summarize total slots */
user->limits.hub_count_total = user->limits.hub_count_user + user->limits.hub_count_registered + user->limits.hub_count_operator;
if (!user_is_protected(user))
{
if (user->limits.shared_size < hub_get_min_share(hub) && hub_get_min_share(hub))
{
return status_msg_user_share_size_low;
}
if (user->limits.shared_size > hub_get_max_share(hub) && hub_get_max_share(hub))
{
return status_msg_user_share_size_high;
}
if ((user->limits.hub_count_user > hub_get_max_hubs_user(hub) && hub_get_max_hubs_user(hub)) ||
(user->limits.hub_count_registered > hub_get_max_hubs_reg(hub) && hub_get_max_hubs_reg(hub)) ||
(user->limits.hub_count_operator > hub_get_max_hubs_op(hub) && hub_get_max_hubs_op(hub)) ||
(user->limits.hub_count_total > hub_get_max_hubs_total(hub) && hub_get_max_hubs_total(hub)))
{
return status_msg_user_hub_limit_high;
}
if ((user->limits.hub_count_user < hub_get_min_hubs_user(hub) && hub_get_min_hubs_user(hub)) ||
(user->limits.hub_count_registered < hub_get_min_hubs_reg(hub) && hub_get_min_hubs_reg(hub)) ||
(user->limits.hub_count_operator < hub_get_min_hubs_op(hub) && hub_get_min_hubs_op(hub)))
{
return status_msg_user_hub_limit_low;
}
if (user->limits.upload_slots < hub_get_min_slots(hub) && hub_get_min_slots(hub))
{
return status_msg_user_slots_low;
}
if (user->limits.upload_slots > hub_get_max_slots(hub) && hub_get_max_slots(hub))
{
return status_msg_user_slots_high;
}
}
return 0;
}
/*
* Set the expected credentials, and returns 1 if authentication is needed,
* or 0 if not.
* If the hub is configured to allow only registered users and the user
* is not recognized this will return 1.
*/
static int set_credentials(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
{
int ret = 0;
struct auth_info* info = acl_get_access_info(hub, user->id.nick);
if (info)
{
user->credentials = info->credentials;
ret = 1;
}
else
{
user->credentials = auth_cred_guest;
}
hub_free(info);
switch (user->credentials)
{
case auth_cred_none:
break;
case auth_cred_bot:
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_BOT);
break;
case auth_cred_ubot:
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_BOT);
break;
case auth_cred_guest:
/* Nothing to be added to the info message */
break;
case auth_cred_user:
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_REGISTERED_USER);
break;
case auth_cred_operator:
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_OPERATOR);
break;
case auth_cred_opbot:
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_HUBBOT);
break;
case auth_cred_opubot:
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_HUBBOT);
break;
case auth_cred_super:
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_SUPER_USER);
break;
case auth_cred_admin:
adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_ADMIN);
break;
case auth_cred_link:
break;
}
return ret;
}
static int check_is_hub_full(struct hub_info* hub, struct hub_user* user)
{
/*
* If hub is full, don't let users in, but we still want to allow
* operators and admins to enter the hub.
*/
if (hub->config->max_users && hub->users->count >= (size_t) hub->config->max_users && !user_is_protected(user))
{
return 1;
}
return 0;
}
static int check_registered_users_only(struct hub_info* hub, struct hub_user* user)
{
if (hub->config->registered_users_only && !user_is_registered(user))
{
return 1;
}
return 0;
}
static int hub_handle_info_common(struct hub_user* user, struct adc_message* cmd)
{
/* Remove server restricted flags */
remove_server_restricted_flags(cmd);
/* Update/set the feature cast flags. */
set_feature_cast_supports(user, cmd);
return 0;
}
static int hub_handle_info_low_bandwidth(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
{
if (hub->config->low_bandwidth_mode)
{
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_USER_AGENT_VERSION);
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_USER_AGENT_PRODUCT);
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_SHARED_FILES);
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_NORMAL);
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_REGISTER);
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_COUNT_HUB_OPERATOR);
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_UPLOAD_SPEED);
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_DOWNLOAD_SPEED);
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_AUTO_SLOTS);
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_AUTO_SLOTS_MAX);
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_AWAY);
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_DESCRIPTION);
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_EMAIL);
}
return 0;
}
#define INF_CHECK(FUNC, HUB, USER, CMD) \
do { \
int ret = FUNC(HUB, USER, CMD); \
if (ret < 0) \
return ret; \
} while(0)
static int hub_perform_login_checks(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
{
/* Make syntax checks. */
INF_CHECK(check_required_login_flags, hub, user, cmd);
INF_CHECK(check_cid, hub, user, cmd);
INF_CHECK(check_nick, hub, user, cmd);
INF_CHECK(check_network, hub, user, cmd);
INF_CHECK(check_user_agent, hub, user, cmd);
INF_CHECK(check_acl, hub, user, cmd);
INF_CHECK(check_logged_in, hub, user, cmd);
return 0;
}
/**
* Perform additional INF checks used at time of login.
*
* @return 0 if success, <0 if error, >0 if authentication needed.
*/
int hub_handle_info_login(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
{
int code = 0;
INF_CHECK(hub_perform_login_checks, hub, user, cmd);
/* Private ID must never be broadcasted - drop it! */
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_PRIVATE_ID);
code = set_credentials(hub, user, cmd);
/* Note: this must be done *after* set_credentials. */
if (check_is_hub_full(hub, user))
{
return status_msg_hub_full;
}
if (check_registered_users_only(hub, user))
{
return status_msg_hub_registered_users_only;
}
INF_CHECK(check_limits, hub, user, cmd);
/* strip off stuff if low_bandwidth_mode is enabled */
hub_handle_info_low_bandwidth(hub, user, cmd);
/* Set initial user info */
user_set_info(user, cmd);
return code;
}
/*
* If user is in the connecting state, we need to do fairly
* strict checking of all arguments.
* This means we disconnect users when they provide invalid data
* during the login sequence.
* When users are merely updating their data after successful login
* we can just ignore any invalid data and not broadcast it.
*
* The data we need to check is:
* - nick name (valid, not taken, etc)
* - CID/PID (valid, not taken, etc).
* - IP addresses (IPv4 and IPv6)
*/
int hub_handle_info(struct hub_info* hub, struct hub_user* user, const struct adc_message* cmd_unmodified)
{
int ret;
struct adc_message* cmd = adc_msg_copy(cmd_unmodified);
if (!cmd) return -1; /* OOM */
cmd->priority = 1;
hub_handle_info_common(user, cmd);
/* If user is logging in, perform more checks,
otherwise only a few things need to be checked.
*/
if (user_is_connecting(user))
{
/*
* Don't allow the user to send multiple INF messages in this stage!
* Since that can have serious side-effects.
*/
if (user->info)
{
adc_msg_free(cmd);
return 0;
}
ret = hub_handle_info_login(hub, user, cmd);
if (ret < 0)
{
on_login_failure(hub, user, ret);
adc_msg_free(cmd);
return -1;
}
else
{
/* Post a message, the user has joined */
struct event_data post;
memset(&post, 0, sizeof(post));
post.id = UHUB_EVENT_USER_JOIN;
post.ptr = user;
post.flags = ret; /* 0 - all OK, 1 - need authentication */
event_queue_post(hub->queue, &post);
adc_msg_free(cmd);
return 0;
}
}
else
{
/* These must not be allowed updated, let's remove them! */
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_PRIVATE_ID);
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_CLIENT_ID);
/*
* If the nick is not accepted, do not relay it.
* Otherwise, the nickname will be updated.
*/
if (adc_msg_has_named_argument(cmd, ADC_INF_FLAG_NICK))
{
#ifdef ALLOW_CHANGE_NICK
if (!check_nick(hub, user, cmd))
#endif
adc_msg_remove_named_argument(cmd, ADC_INF_FLAG_NICK);
}
ret = check_limits(hub, user, cmd);
if (ret < 0)
{
on_update_failure(hub, user, ret);
adc_msg_free(cmd);
return -1;
}
strip_network(user, cmd);
hub_handle_info_low_bandwidth(hub, user, cmd);
user_update_info(user, cmd);
if (!adc_msg_is_empty(cmd))
{
route_message(hub, user, cmd);
}
adc_msg_free(cmd);
}
return 0;
}

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