🢀︎ unrealircd :: 614a7a2


commit 614a7a234e4d3d0182730162cee5ccfdfa3fa4bd
Author: acidvegas <acid.vegas@acid.vegas>
Date:   Sat Feb 15 09:50:50 2020 -0500

    Updated to 5.0.3

diff --git a/Config b/Config
index 1e9718e..0edb7c4 100755
--- a/Config
+++ b/Config
@@ -237,12 +237,12 @@ UNREALCWD="`pwd`"
 BASEPATH="$HOME/unrealircd"
 DEFPERM="0600"
 SSLDIR=""
-NICKNAMEHISTORYLENGTH="100"
+NICKNAMEHISTORYLENGTH="2000"
 MAXCONNECTIONS_REQUEST="auto"
-REMOTEINC="1"
+REMOTEINC=""
 CURLDIR=""
-PREFIXAQ="0"
-SHOWLISTMODES="0"
+PREFIXAQ="1"
+SHOWLISTMODES="1"
 NOOPEROVERRIDE=""
 OPEROVERRIDEVERIFY=""
 GENCERTIFICATE="1"
@@ -326,7 +326,7 @@ echo ""
 
 if [ -z "$NOCACHE" ] ; then
 	# This needs to be updated each release so auto-upgrading works for settings, modules, etc!!:
-	UNREALRELEASES="unrealircd-5.0.1 unrealircd-5.0.0 unrealircd-5.0.0-rc2 unrealircd-5.0.0-rc1"
+	UNREALRELEASES="unrealircd-5.0.2 unrealircd-5.0.1 unrealircd-5.0.0 unrealircd-5.0.0-rc2 unrealircd-5.0.0-rc1"
 	if [ -f "config.settings" ]; then
 		. ./config.settings
 	else
diff --git a/Makefile.in b/Makefile.in
index 98f2cc7..3db18f1 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -172,6 +172,8 @@ install: all
 	$(INSTALL) -m 0600 doc/conf/*.conf @CONFDIR@
 	$(INSTALL) -m 0600 doc/conf/*.motd @CONFDIR@
 	$(INSTALL) -m 0600 doc/conf/modules.sources.list @CONFDIR@ ; \
+	fi
+	-@extras/patches/patch_spamfilter_conf "@CONFDIR@"
 	$(INSTALL) -m 0700 unrealircd @SCRIPTDIR@
 	$(INSTALL) -m 0700 -d @MODULESDIR@
 	@rm -f @MODULESDIR@/*.so 1>/dev/null 2>&1
diff --git a/Makefile.windows b/Makefile.windows
index e5fc1f0..b70d90c 100644
--- a/Makefile.windows
+++ b/Makefile.windows
@@ -285,8 +285,11 @@ DLL_FILES=SRC/MODULES/CLOAK.DLL \
  SRC/MODULES/RESTRICT-COMMANDS.DLL \
  SRC/MODULES/RMTKL.DLL \
  SRC/MODULES/ECHO-MESSAGE.DLL \
+ SRC/MODULES/USERIP-TAG.DLL \
+ SRC/MODULES/USERHOST-TAG.DLL \
  SRC/MODULES/REQUIRE-MODULE.DLL \
- SRC/MODULES/IDENT_LOOKUP.DLL
+ SRC/MODULES/IDENT_LOOKUP.DLL \
+ SRC/MODULES/HISTORY.DLL
 
 
 ALL: CONF UNREALSVC.EXE UnrealIRCd.exe MODULES 
@@ -1059,10 +1062,19 @@ src/modules/rmtkl.dll: src/modules/rmtkl.c $(INCLUDES)
 src/modules/echo-message.dll: src/modules/echo-message.c $(INCLUDES)
 	$(CC) $(MODCFLAGS) /Fosrc/modules/ /Fesrc/modules/ src/modules/echo-message.c $(MODLFLAGS)
 
+src/modules/userip-tag.dll: src/modules/userip-tag.c $(INCLUDES)
+	$(CC) $(MODCFLAGS) /Fosrc/modules/ /Fesrc/modules/ src/modules/userip-tag.c $(MODLFLAGS)
+
+src/modules/userhost-tag.dll: src/modules/userhost-tag.c $(INCLUDES)
+	$(CC) $(MODCFLAGS) /Fosrc/modules/ /Fesrc/modules/ src/modules/userhost-tag.c $(MODLFLAGS)
+
 src/modules/require-module.dll: src/modules/require-module.c $(INCLUDES)
 	$(CC) $(MODCFLAGS) /Fosrc/modules/ /Fesrc/modules/ src/modules/require-module.c $(MODLFLAGS)
 
 src/modules/ident_lookup.dll: src/modules/ident_lookup.c $(INCLUDES)
 	$(CC) $(MODCFLAGS) /Fosrc/modules/ /Fesrc/modules/ src/modules/ident_lookup.c $(MODLFLAGS)
 
+src/modules/history.dll: src/modules/history.c $(INCLUDES)
+	$(CC) $(MODCFLAGS) /Fosrc/modules/ /Fesrc/modules/ src/modules/history.c $(MODLFLAGS)
+
 dummy:
diff --git a/configure b/configure
index f2d3a78..f1518fa 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for unrealircd 5.0.2.
+# Generated by GNU Autoconf 2.69 for unrealircd 5.0.3.
 #
 # Report bugs to <https://bugs.unrealircd.org/>.
 #
@@ -580,8 +580,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='unrealircd'
 PACKAGE_TARNAME='unrealircd'
-PACKAGE_VERSION='5.0.2'
-PACKAGE_STRING='unrealircd 5.0.2'
+PACKAGE_VERSION='5.0.3'
+PACKAGE_STRING='unrealircd 5.0.3'
 PACKAGE_BUGREPORT='https://bugs.unrealircd.org/'
 PACKAGE_URL='https://unrealircd.org/'
 
@@ -1325,7 +1325,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures unrealircd 5.0.2 to adapt to many kinds of systems.
+\`configure' configures unrealircd 5.0.3 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1391,7 +1391,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of unrealircd 5.0.2:";;
+     short | recursive ) echo "Configuration of unrealircd 5.0.3:";;
    esac
   cat <<\_ACEOF
 
@@ -1544,7 +1544,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-unrealircd configure 5.0.2
+unrealircd configure 5.0.3
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1913,7 +1913,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by unrealircd $as_me 5.0.2, which was
+It was created by unrealircd $as_me 5.0.3, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2321,7 +2321,7 @@ _ACEOF
 
 
 # Minor version number (e.g.: Z in X.Y.Z)
-UNREAL_VERSION_MINOR="2"
+UNREAL_VERSION_MINOR="3"
 
 cat >>confdefs.h <<_ACEOF
 #define UNREAL_VERSION_MINOR $UNREAL_VERSION_MINOR
@@ -8249,7 +8249,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by unrealircd $as_me 5.0.2, which was
+This file was extended by unrealircd $as_me 5.0.3, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -8312,7 +8312,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-unrealircd config.status 5.0.2
+unrealircd config.status 5.0.3
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
index 6dc2be2..7f649fe 100644
--- a/configure.ac
+++ b/configure.ac
@@ -7,7 +7,7 @@ dnl src/windows/unrealinst.iss
 dnl doc/Config.header
 dnl src/version.c.SH
 
-AC_INIT([unrealircd], [5.0.2], [https://bugs.unrealircd.org/], [], [https://unrealircd.org/])
+AC_INIT([unrealircd], [5.0.3], [https://bugs.unrealircd.org/], [], [https://unrealircd.org/])
 AC_CONFIG_SRCDIR([src/ircd.c])
 AC_CONFIG_HEADER([include/setup.h])
 AC_CONFIG_AUX_DIR([autoconf])
@@ -34,7 +34,7 @@ UNREAL_VERSION_MAJOR=["0"]
 AC_DEFINE_UNQUOTED([UNREAL_VERSION_MAJOR], [$UNREAL_VERSION_MAJOR], [Major version number (e.g.: Y for X.Y.Z)])
 
 # Minor version number (e.g.: Z in X.Y.Z)
-UNREAL_VERSION_MINOR=["2"]
+UNREAL_VERSION_MINOR=["3"]
 AC_DEFINE_UNQUOTED([UNREAL_VERSION_MINOR], [$UNREAL_VERSION_MINOR], [Minor version number (e.g.: Z for X.Y.Z)])
 
 # The version suffix such as a beta marker or release candidate
diff --git a/doc/Config.header b/doc/Config.header
index 5f42397..0647f06 100644
--- a/doc/Config.header
+++ b/doc/Config.header
@@ -7,7 +7,7 @@
  \___/|_| |_|_|  \___|\__,_|_|\___/\_| \_| \____/\__,_|
 
                                Configuration Program
-                                for UnrealIRCd 5.0.2
+                                for UnrealIRCd 5.0.3
                                     
 This program will help you to compile your IRC server, and ask you
 questions regarding the compile-time settings of it during the process. 
diff --git a/doc/RELEASE-NOTES.md b/doc/RELEASE-NOTES.md
index 8dc86f3..47051a2 100644
--- a/doc/RELEASE-NOTES.md
+++ b/doc/RELEASE-NOTES.md
@@ -1,6 +1,38 @@
-UnrealIRCd 5.0.2 Release Notes
+UnrealIRCd 5.0.3 Release Notes
 ===============================
 
+UnrealIRCd 5.0.3
+-----------------
+Fixes:
+* Fix serious flood issue in labeled-response implementation.
+* An IRCOp SQUIT'ing a far remote server may cause a broken link topology
+* In channels that are +D (delayed join), PARTs were not shown correctly to
+  channel operators.
+
+Enhancements:
+* A new HISTORY command for history playback (```HISTORY #channel number-of-lines```)
+  which allows you to fetch more lines than the on-join history playback.
+  Of course, taking into account the set limits in the +H channel mode.
+  This command is one of the [two interfaces](https://www.unrealircd.org/docs/Channel_history#Ways_to_retrieve_history)
+  to [Channel history](https://www.unrealircd.org/docs/Channel_history).
+* Two new [message tags](https://www.unrealircd.org/docs/Message_tags),
+  ```unrealircd.org/userip``` and ```unrealircd.org/userhost```
+  which communicate the user@ip and real user@host to IRCOps.
+
+Changes:
+* Drop the draft/ prefix now that the IRCv3
+  [labeled-response](https://ircv3.net/specs/extensions/labeled-response.html)
+  specification is out of draft.
+* The operclass permission ```immune:target-limit``` is now called
+  ```immune:max-concurrent-conversations```, since it bypasses
+  [set::anti-flood::max-concurrent-conversations](https://www.unrealircd.org/docs/Set_block#set::anti-flood::max-concurrent-conversations).
+  For 99% of the users this change is not important, but it may be
+  if you use highly customized [operclass blocks](https://www.unrealircd.org/docs/Operclass_block)
+
+Are you upgrading from UnrealIRCd 4.x to UnrealIRCd 5? If so,
+then check out the *UnrealIRCd 5* release notes further down. At the
+very least, check out [Upgrading from 4.x](https://www.unrealircd.org/docs/Upgrading_from_4.x).
+
 UnrealIRCd 5.0.2
 -----------------
 
@@ -39,10 +71,6 @@ Enhancements:
 * New options to exempt webirc users: [set::connthrottle::webirc-bypass](https://www.unrealircd.org/docs/Connthrottle),
   [set::restrict-commands::name-of-command::exempt-webirc](https://www.unrealircd.org/docs/Set_block#set::restrict-commands).
 
-Are you upgrading from UnrealIRCd 4.x to UnrealIRCd 5? If so,
-then check out the *UnrealIRCd 5* release notes further down. At the
-very least, check out [Upgrading from 4.x](https://www.unrealircd.org/docs/Upgrading_from_4.x).
-
 UnrealIRCd 5.0.1
 -----------------
 
diff --git a/doc/conf/except.conf b/doc/conf/except.conf
index 2e0cd6e..14a9be5 100644
--- a/doc/conf/except.conf
+++ b/doc/conf/except.conf
@@ -1,35 +1,35 @@
 # Localhost
-except ban { mask *@127.0.0.1; type { all; } }
+except ban { mask *@127.0.0.1; }
 
 # IRCCloud
-except ban { mask *@192.184.9.108;      type { all; } } # highgate.irccloud.com
-except ban { mask *@192.184.9.110;      type { all; } } # ealing.irccloud.com
-except ban { mask *@192.184.9.112;      type { all; } } # charlton.irccloud.com
-except ban { mask *@192.184.10.118;     type { all; } } # brockwell.irccloud.com
-except ban { mask *@192.184.10.9;       type { all; } } # tooting.irccloud.com
-except ban { mask *@192.184.8.73;       type { all; } } # hathersage.irccloud.com
-except ban { mask *@192.184.8.103;      type { all; } } # stonehaven.irccloud.com
-except ban { mask *@2001:67c:2f08::/48; type { all; } } # IPv6
+except ban { mask *@192.184.9.108;      } # highgate.irccloud.com
+except ban { mask *@192.184.9.110;      } # ealing.irccloud.com
+except ban { mask *@192.184.9.112;      } # charlton.irccloud.com
+except ban { mask *@192.184.10.118;     } # brockwell.irccloud.com
+except ban { mask *@192.184.10.9;       } # tooting.irccloud.com
+except ban { mask *@192.184.8.73;       } # hathersage.irccloud.com
+except ban { mask *@192.184.8.103;      } # stonehaven.irccloud.com
+except ban { mask *@2001:67c:2f08::/48; } # IPv6
 
 # IRC Source
-except ban { mask *@49.56.142.157;            type { all; } } # yin.ircs.me
-except ban { mask *@149.56.142.163;           type { all; } } # yang.ircs.me
-except ban { mask *@2607:5300:201:3100::13dd; type { all; } } # yin.ircs.me
-except ban { mask *@2607:5300:201:3100::299d; type { all; } } # yang.ircs.me
+except ban { mask *@49.56.142.157;            } # yin.ircs.me
+except ban { mask *@149.56.142.163;           } # yang.ircs.me
+except ban { mask *@2607:5300:201:3100::13dd; } # yin.ircs.me
+except ban { mask *@2607:5300:201:3100::299d; } # yang.ircs.me
 
 # KiwiIRC
-except ban { mask *@107.161.19.53;  type { all; } }
-except ban { mask *@107.161.19.109; type { all; } }
-except ban { mask *@109.169.31.4;   type { all; } }
-except ban { mask *@109.169.31.13;  type { all; } } # KiwiIRC Verify Bot (out.kiwiirc.com)
+except ban { mask *@107.161.19.53;  }
+except ban { mask *@107.161.19.109; }
+except ban { mask *@109.169.31.4;   }
+except ban { mask *@109.169.31.13;  } # KiwiIRC Verify Bot (out.kiwiirc.com)
 
 # Mibbit
-except ban { mask *@207.192.75.252;                 type { all; } } # ircip1.mibbit.com
-except ban { mask *@64.62.228.82;                   type { all; } } # ircip2.mibbit.com
-except ban { mask *@78.129.202.38;                  type { all; } } # ircip3.mibbit.com
-except ban { mask *@109.169.29.95;                  type { all; } } # ircip4.mibbit.com
-except ban { mask *@97.107.138.109;                 type { all; } } # bot.search.mibbit.com
-except ban { mask *@2600:3c03::f03c:91ff:fe96:c1fa; type { all; } } # bot.search.mibbit.com
+except ban { mask *@207.192.75.252;                 } # ircip1.mibbit.com
+except ban { mask *@64.62.228.82;                   } # ircip2.mibbit.com
+except ban { mask *@78.129.202.38;                  } # ircip3.mibbit.com
+except ban { mask *@109.169.29.95;                  } # ircip4.mibbit.com
+except ban { mask *@97.107.138.109;                 } # bot.search.mibbit.com
+except ban { mask *@2600:3c03::f03c:91ff:fe96:c1fa; } # bot.search.mibbit.com
 
 # Netsplit
-except ban { mask *@85.25.137.63; type { all; } } # eagle.netsplit.de
+except ban { mask *@85.25.137.63; } # eagle.netsplit.de
diff --git a/doc/conf/modules.conf b/doc/conf/modules.conf
index 7ddd119..d5a54c4 100644
--- a/doc/conf/modules.conf
+++ b/doc/conf/modules.conf
@@ -1,6 +1,3 @@
-// Cloaking (+x)
-loadmodule "cloak";
-
 // User Commands (Minimal)
 #loadmodule "admin";
 loadmodule "away";
@@ -37,6 +34,7 @@ loadmodule "cap";
 loadmodule "cycle";
 #loadmodule "dccallow";
 loadmodule "help";
+loadmodule "history";
 loadmodule "knock";
 loadmodule "lag";
 loadmodule "sasl";
@@ -81,7 +79,7 @@ loadmodule "unsqline";
 loadmodule "eos";
 loadmodule "md";
 loadmodule "netinfo";
-loadmodule "require-module";
+#loadmodule "require-module";
 loadmodule "server";
 loadmodule "sinfo";
 loadmodule "sjoin";
@@ -153,7 +151,7 @@ loadmodule "extbans/msgbypass";   /* +e ~m */
 #loadmodule "extbans/operclass";  /* +b ~O */
 #loadmodule "extbans/partmsg";    /* +b ~p */
 loadmodule "extbans/quiet";       /* +b ~q */
-loadmodule "extbans/realname";    /* +b ~r */
+#loadmodule "extbans/realname";    /* +b ~r */
 loadmodule "extbans/textban";     /* +b ~T */
 loadmodule "extbans/timedban";    /* +b ~t */
 
@@ -161,6 +159,7 @@ loadmodule "extbans/timedban";    /* +b ~t */
 loadmodule "account-tag";
 loadmodule "batch";
 loadmodule "echo-message";
+loadmodule "labeled-response";
 loadmodule "link-security";
 loadmodule "message-ids";
 loadmodule "message-tags";
@@ -178,11 +177,13 @@ loadmodule "charsys";
 loadmodule "connthrottle";
 loadmodule "hideserver";
 loadmodule "history_backend_mem";
+#loadmodule "history_backend_null";
 loadmodule "ident_lookup";
 loadmodule "jointhrottle";
-loadmodule "labeled-response";
 loadmodule "tkldb";
 loadmodule "tls_antidos";
+loadmodule "userhost-tag";
+loadmodule "userip-tag";
 loadmodule "reputation";
 loadmodule "restrict-commands";
 loadmodule "rmtkl";
diff --git a/doc/conf/new/auth.conf b/doc/conf/new/auth.conf
new file mode 100644
index 0000000..1a0ecab
--- /dev/null
+++ b/doc/conf/new/auth.conf
@@ -0,0 +1,122 @@
+admin { ""; }
+
+class clients { pingfreq 120; maxclients 100; sendq 1M; options { nofakelag; } }
+class servers { pingfreq 120; maxclients   2; sendq 1M; connfreq 30;       }
+
+allow { ip *; class clients; maxperip 2; }
+
+listen { ip *; port REDACTED; options { clientsonly; tls; } }
+listen { ip *; port REDACTED; options { serversonly; tls; } }
+
+require authentication {
+	mask *@*;
+	reason "8,4   E N T E R   T H E   V O I D   ";
+}
+
+link irc.supernets.org {
+	incoming { mask REDACTED; }
+	outgoing {
+		bind-ip *;
+		hostname REDACTED;
+		port REDACTED;
+		options { tls; autoconnect; }
+	}
+	password "REDACTED" { spkifp; }
+	class servers;
+}
+
+log "errors.log" { flags { errors; } maxsize 1K; }
+
+tld { mask *@*; motd remote.motd; rules remote.motd; options { remote; } }
+
+ulines { services.supernets.org; }
+
+set {
+	kline-address "8,4   E N T E R   T H E   V O I D   ";
+	gline-address "8,4   E N T E R   T H E   V O I D   ";
+	modes-on-connect "+ipRTx";
+	modes-on-oper "+HIq";
+	modes-on-join "+Cns";
+	level-on-join "op";
+	restrict-usermodes "ipRTx";
+	restrict-channelmodes "CnPps";
+	oper-auto-join "#help";
+	static-quit "EMO-QUIT";
+	static-part "EMO-PART";
+	who-limit 1;
+	nick-length 20;
+	maxchannelsperuser 10;
+	channel-command-prefix "`!@$.";
+	options { hide-ulines; flat-map; identd-check; }
+	network-name "SuperNETs";
+	default-server "irc.supernets.org";
+	services-server "services.supernets.org";
+	sasl-server "services.supernets.org";
+	help-channel "#help";
+	cloak-method ip;
+	cloak-keys {
+		"REDACTED";
+		"REDACTED";
+		"REDACTED";
+	}
+	hiddenhost-prefix "SUPER";
+	outdated-tls-policy {
+		user warn;
+		oper deny;
+		user-message "4WARNING: You are using an outdated SSL/TLS protocol or cipher";
+		oper-message "Network operators must connect using an up-to-date SSL/TLS protocol or cipher";
+	}
+	anti-flood {
+		away-flood 3:300;
+		connect-flood 3:300;
+		invite-flood 3:300;
+		join-flood 3:300;
+		knock-flood 3:300;
+		max-concurrent-conversations { users 5; new-user-every 60s; }
+		nick-flood 3:300;
+		unknown-flood-amount 2048;
+		unknown-flood-bantime 1h;
+	}
+	default-bantime 30d;
+	modef-default-unsettime 5;
+	spamfilter {
+		ban-time 30d;
+		ban-reason "8,4   E N T E R   T H E   V O I D   ";
+		except "#anythinggoes";
+	}
+	max-targets-per-command { kick 1; notice 1; part 1; privmsg 1; }
+	hide-ban-reason yes;
+	reject-message {
+		gline                "8,4   E N T E R   T H E   V O I D   ";
+		kline                "8,4   E N T E R   T H E   V O I D   ";
+		password-mismatch    "8,4   E N T E R   T H E   V O I D   ";
+		server-full          "8,4   E N T E R   T H E   V O I D   ";
+		too-many-connections "8,4   E N T E R   T H E   V O I D   ";
+		unauthorized         "8,4   E N T E R   T H E   V O I D   ";
+	}
+	antimixedutf8 {
+		score 10;
+		ban-action block;
+		ban-reason "8,4   E N T E R   T H E   V O I D   ";
+		ban-time 1d;
+	}
+	connthrottle {
+		known-users   { minimum-reputation-score 24; sasl-bypass yes;       }
+		new-users     { local-throttle 20:60;        global-throttle 30:60; }
+		disabled-when { reputation-gathering 1w;     start-delay 3m;        }
+	}
+	history {
+		channel {
+			playback-on-join        { lines 1000; time 1w; }
+			max-storage-per-channel { lines 1000; time 1w; }
+		}
+	}
+	manual-ban-target ip;
+}
+
+hideserver {
+	disable-map yes;
+	disable-links yes;
+	map-deny-message "Denied";
+	links-deny-message "Denied";
+}
\ No newline at end of file
diff --git a/doc/conf/new/public.conf b/doc/conf/new/public.conf
new file mode 100644
index 0000000..d3f0da1
--- /dev/null
+++ b/doc/conf/new/public.conf
@@ -0,0 +1,154 @@
+admin { ""; }
+
+class clients { pingfreq 120; maxclients 100; sendq 100000; recvq 8000;  }
+class servers { pingfreq 120; maxclients   2; sendq 100000; connfreq 30; }
+
+allow { ip *; class clients; maxperip 2; }
+
+listen { ip *; port 6667;      options { clientsonly;      } }
+listen { ip *; port 6697;      options { clientsonly; tls; } }
+listen { ip *; port REDACTED;  options { serversonly; tls; } }
+
+link sasl.supernets.org {
+	incoming { mask REDACTED; }
+	outgoing {
+		bind-ip *;
+		hostname REDACTED;
+		port REDACTED;
+		options { tls; autoconnect; }
+	}
+	password "REDACTED" { spkifp; }
+	class servers;
+}
+
+log "errors.log" { flags { errors; } maxsize 1K; }
+
+tld { mask *@*; motd remote.motd; rules remote.motd; options { remote; } }
+
+ulines { services.supernets.org; }
+
+blacklist dronebl {
+	dns {
+		name dnsbl.dronebl.org;
+		type record;
+		reply { 3; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16; }
+	}
+	action gzline;
+	ban-time 30d;
+	reason "8,4   E N T E R   T H E   V O I D   ";
+}
+
+blacklist efnetrbl {
+	dns {
+		name rbl.efnetrbl.org;
+		type record;
+		reply { 1; 4; 5; }
+	}
+	action gzline;
+	ban-time 30d;
+	reason "8,4   E N T E R   T H E   V O I D   ";
+}
+
+blacklist torbl {
+	dns {
+		name torexit.dan.me.uk;
+		type record;
+		reply { 100; }
+	}
+	action gzline;
+	ban-time 30d;
+	reason "8,4   E N T E R   T H E   V O I D   ";
+}
+
+set {
+	kline-address "8,4   E N T E R   T H E   V O I D   ";
+	gline-address "8,4   E N T E R   T H E   V O I D   ";
+	modes-on-connect "+ipRTx";
+	modes-on-oper "+HIq";
+	modes-on-join "+Cns";
+	level-on-join "op";
+	restrict-usermodes "ipRTx";
+	restrict-channelmodes "CnPps";
+	restrict-commands {
+		list { connect-delay 30; exempt-identified yes; }
+	}
+	static-quit "EMO-QUIT";
+	static-part "EMO-PART";
+	nick-length 20;
+	maxchannelsperuser 5;
+	channel-command-prefix "`!@$.";
+	options { hide-ulines; flat-map; identd-check; }
+	network-name "SuperNETs";
+	default-server "irc.supernets.org";
+	services-server "services.supernets.org";
+	sasl-server "services.supernets.org";
+	help-channel "#help";
+	cloak-method ip;
+	cloak-keys {
+		"REDACTED";
+		"REDACTED";
+		"REDACTED";
+	}
+	hiddenhost-prefix "SUPER";
+	plaintext-policy {
+		user warn;
+		user-message "4WARNING: You are not using a secure connection with SSL/TLS";
+	}
+	outdated-tls-policy {
+		user warn;
+		user-message "4WARNING: You are using an outdated SSL/TLS protocol or cipher";
+	}
+	anti-flood {
+		away-flood 3:300;
+		connect-flood 3:300;
+		invite-flood 3:300;
+		join-flood 3:300;
+		knock-flood 3:300;
+		max-concurrent-conversations { users 5; new-user-every 60s; }
+		nick-flood 3:300;
+		unknown-flood-amount 2048;
+		unknown-flood-bantime 1h;
+	}
+	default-bantime 30d;
+	modef-default-unsettime 5;
+	spamfilter {
+		ban-time 30d;
+		ban-reason "8,4   E N T E R   T H E   V O I D   ";
+		except "#anythinggoes";
+	}
+	max-targets-per-command { kick 1; notice 1; part 1; privmsg 1; }
+	hide-ban-reason yes;
+	reject-message {
+		gline                "8,4   E N T E R   T H E   V O I D   ";
+		kline                "8,4   E N T E R   T H E   V O I D   ";
+		password-mismatch    "8,4   E N T E R   T H E   V O I D   ";
+		server-full          "8,4   E N T E R   T H E   V O I D   ";
+		too-many-connections "8,4   E N T E R   T H E   V O I D   ";
+		unauthorized         "8,4   E N T E R   T H E   V O I D   ";
+	}
+	antimixedutf8 {
+		score 10;
+		ban-action block;
+		ban-reason "8,4   E N T E R   T H E   V O I D   ";
+		ban-time 1d;
+	}
+	connthrottle {
+		known-users   { minimum-reputation-score 24; sasl-bypass yes;       }
+		new-users     { local-throttle 20:60;        global-throttle 30:60; }
+		disabled-when { reputation-gathering 1w;     start-delay 3m;        }
+	}
+	history {
+		channel {
+			playback-on-join        { lines 1000; time 1w; }
+			max-storage-per-channel { lines 1000; time 1w; }
+		}
+	}
+	manual-ban-target ip;
+}
+
+hideserver {
+	disable-map yes;
+	disable-links yes;
+	map-deny-message "Denied";
+	links-deny-message "Denied";
+}
\ No newline at end of file
diff --git a/doc/conf/unrealircd.remote.conf b/doc/conf/unrealircd.remote.conf
index 19ce206..1d5053c 100644
--- a/doc/conf/unrealircd.remote.conf
+++ b/doc/conf/unrealircd.remote.conf
@@ -65,6 +65,15 @@ blacklist torbl {
 	reason "8,4   E N T E R   T H E   V O I D   ";
 }
 
+webirc { mask 107.161.19.53;  password "REDACTED"; } # KiwiIRC
+webirc { mask 107.161.19.109; password "REDACTED"; }
+webirc { mask 107.161.31.4;   password "REDACTED"; }
+
+webirc { mask 207.192.75.252; password "REDACTED"; } # Mibbit
+webirc { mask 64.62.228.82;   password "REDACTED"; }
+webirc { mask 78.129.202.38;  password "REDACTED"; }
+webirc { mask 109.169.29.95 ; password "REDACTED"; }
+
 set {
 	kline-address "banned@supernets.org";
 	gline-address "banned@supernets.org";
diff --git a/extras/doxygen/Doxyfile b/extras/doxygen/Doxyfile
index 96283bc..7e3d7d7 100644
--- a/extras/doxygen/Doxyfile
+++ b/extras/doxygen/Doxyfile
@@ -38,7 +38,7 @@ PROJECT_NAME           = "UnrealIRCd"
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 5.0.2
+PROJECT_NUMBER         = 5.0.3
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
diff --git a/include/h.h b/include/h.h
index d2b39f2..a31729d 100644
--- a/include/h.h
+++ b/include/h.h
@@ -93,7 +93,7 @@ extern MODVAR ConfigItem_offchans	*conf_offchans;
 extern void		completed_connection(int, int, void *);
 extern void clear_unknown();
 extern EVENT(e_unload_module_delayed);
-extern EVENT(e_clean_out_throttling_buckets);
+extern EVENT(throttling_check_expire);
 
 extern void  module_loadall(void);
 extern long set_usermode(char *umode);
@@ -922,9 +922,9 @@ extern MessageTag *find_mtag(MessageTag *mtags, const char *token);
 extern MessageTag *duplicate_mtag(MessageTag *mtag);
 extern void free_message_tags(MessageTag *m);
 extern time_t server_time_to_unix_time(const char *tbuf);
+extern int history_set_limit(char *object, int max_lines, long max_t);
 extern int history_add(char *object, MessageTag *mtags, char *line);
 extern int history_request(Client *acptr, char *object, HistoryFilter *filter);
-extern int history_del(char *object, int max_lines, long max_time);
 extern int history_destroy(char *object);
 extern void special_delayed_unloading(void);
 extern int write_int64(FILE *fd, uint64_t t);
@@ -964,3 +964,4 @@ extern char *unreal_add_quotes(char *str);
 extern int unreal_add_quotes_r(char *i, char *o, size_t len);
 extern void user_account_login(MessageTag *recv_mtags, Client *client);
 extern void link_generator(void);
+extern void update_throttling_timer_settings(void);
diff --git a/include/modules.h b/include/modules.h
index f26f6e1..f3156ca 100644
--- a/include/modules.h
+++ b/include/modules.h
@@ -460,7 +460,8 @@ struct MessageTagHandler {
 	MessageTagHandler *prev, *next;
 	char *name;                                 /**< The name of the message-tag */
 	int flags;                                  /**< A flag of MTAG_HANDLER_FLAGS_* */
-	int (*is_ok)(Client *, char *, char *);    /**< Verify syntax and access rights */
+	int (*is_ok)(Client *, char *, char *);     /**< Verify syntax and access rights */
+	int (*can_send)(Client *);                  /**< Tag may be sent to this client (normally NULL!) */
 	Module *owner;                              /**< Module introducing this CAP. */
 	ClientCapability *clicap_handler;           /**< Client capability handler associated with this */
 	char unloaded;                              /**< Internal flag to indicate module is being unloaded */
@@ -473,6 +474,7 @@ typedef struct {
 	char *name;
 	int flags;
 	int (*is_ok)(Client *, char *, char *);
+	int (*can_send)(Client *);
 	ClientCapability *clicap_handler;
 } MessageTagHandlerInfo;
 
@@ -490,8 +492,8 @@ typedef struct HistoryBackend HistoryBackend;
 struct HistoryBackend {
 	HistoryBackend *prev, *next;
 	char *name;                                   /**< The name of the history backend (eg: "mem") */
+	int (*history_set_limit)(char *object, int max_lines, long max_time); /**< Impose a limit on a history object */
 	int (*history_add)(char *object, MessageTag *mtags, char *line); /**< Add to history */
-	int (*history_del)(char *object, int max_lines, long max_time); /**< Delete history, based on lines/time */
 	int (*history_request)(Client *acptr, char *object, HistoryFilter *filter);  /**< Request history */
 	int (*history_destroy)(char *object);  /**< Destroy history of this object completely */
 	Module *owner;                                /**< Module introducing this */
@@ -503,8 +505,8 @@ struct HistoryBackend {
  */
 typedef struct {
 	char *name;
+	int (*history_set_limit)(char *object, int max_lines, long max_time);
 	int (*history_add)(char *object, MessageTag *mtags, char *line);
-	int (*history_del)(char *object, int max_lines, long max_time);
 	int (*history_request)(Client *acptr, char *object, HistoryFilter *filter);
 	int (*history_destroy)(char *object);
 } HistoryBackendInfo;
diff --git a/include/struct.h b/include/struct.h
index 845874f..458c30c 100644
--- a/include/struct.h
+++ b/include/struct.h
@@ -178,7 +178,7 @@ typedef OperPermission (*OperClassEntryEvalCallback)(OperClassACLEntryVar* varia
 #define SIDLEN           3
 #define SWHOISLEN	256
 #define UMODETABLESZ (sizeof(long) * 8)
-#define MAXCCUSERS		20 /* Maximum for set::anti-flood::target-limit::max-concurrent-conversations */
+#define MAXCCUSERS		20 /* Maximum for set::anti-flood::max-concurrent-conversations */
 #define BATCHLEN	22
 
 /*
diff --git a/include/windows/setup.h b/include/windows/setup.h
index b3aec60..d3abf09 100644
--- a/include/windows/setup.h
+++ b/include/windows/setup.h
@@ -63,7 +63,7 @@
 #define UNREAL_VERSION_MAJOR 0
 
 /* Minor version number (e.g.: 1 for Unreal3.2.1) */
-#define UNREAL_VERSION_MINOR 2
+#define UNREAL_VERSION_MINOR 3
 
 /* Version suffix such as a beta marker or release candidate marker. (e.g.:
    -rcX for unrealircd-3.2.9-rcX) */
diff --git a/src/api-event.c b/src/api-event.c
index 997b8bd..6dcb888 100644
--- a/src/api-event.c
+++ b/src/api-event.c
@@ -47,20 +47,24 @@ extern EVENT(unrealdns_removeoldrecords);
 Event *EventAdd(Module *module, char *name, vFP event, void *data, long every_msec, int count)
 {
 	Event *newevent;
+
 	if (!name || (every_msec < 0) || (count < 0) || !event)
 	{
 		if (module)
 			module->errorcode = MODERR_INVALID;
 		return NULL;
 	}
-	if (every_msec < 100)
+
+	if ((every_msec < 100) && (count == 0))
 	{
-		ircd_log(LOG_ERROR, "[BUG] EventAdd() from module %s with suspiciously low every_msec value (%ld). "
+		ircd_log(LOG_ERROR, "[BUG] EventAdd() '%s' from module '%s' with suspiciously low every_msec value (%ld). "
 		                    "Note that it is in milliseconds now (1000 = 1 second)!",
+		                    name,
 		                    module ? module->header->name : "???",
 		                    every_msec);
 		every_msec = 100;
 	}
+
 	newevent = safe_alloc(sizeof(Event));
 	safe_strdup(newevent->name, name);
 	newevent->count = count;
@@ -139,7 +143,19 @@ int EventMod(Event *event, EventInfo *mods)
 	}
 
 	if (mods->flags & EMOD_EVERY)
+	{
+		if (mods->every_msec < 100)
+		{
+			ircd_log(LOG_ERROR, "[BUG] EventMod() for '%s' from module '%s' with suspiciously low every_msec value (%lld). "
+					    "Note that it is in milliseconds now (1000 = 1 second)!",
+					    event->name,
+					    event->owner ? event->owner->header->name : "???",
+					    (long long)mods->every_msec);
+			mods->every_msec = 100;
+		}
+
 		event->every_msec = mods->every_msec;
+	}
 	if (mods->flags & EMOD_HOWMANY)
 		event->count = mods->count;
 	if (mods->flags & EMOD_NAME)
diff --git a/src/api-history-backend.c b/src/api-history-backend.c
index d7c7c8c..f6eba60 100644
--- a/src/api-history-backend.c
+++ b/src/api-history-backend.c
@@ -61,11 +61,12 @@ HistoryBackend *HistoryBackendAdd(Module *module, HistoryBackendInfo *mreq)
 	HistoryBackend *m;
 	int exists = 0;
 
-	if (!mreq->history_add || !mreq->history_del || !mreq->history_request || !mreq->history_destroy)
+	if (!mreq->history_add || !mreq->history_request ||
+	    !mreq->history_destroy || !mreq->history_set_limit)
 	{
 		if (module)
 			module->errorcode = MODERR_INVALID;
-		ircd_log(LOG_ERROR, "HistoryBackendAdd(): missing a handler for add/del/request/destroy");
+		ircd_log(LOG_ERROR, "HistoryBackendAdd(): missing a handler for add/del/request/destroy/set_limit");
 		return NULL;
 	}
 	m = HistoryBackendFind(mreq->name);
@@ -89,9 +90,9 @@ HistoryBackend *HistoryBackendAdd(Module *module, HistoryBackendInfo *mreq)
 	/* Add or update the following fields: */
 	m->owner = module;
 	m->history_add = mreq->history_add;
-	m->history_del = mreq->history_del;
 	m->history_request = mreq->history_request;
 	m->history_destroy = mreq->history_destroy;
+	m->history_set_limit = mreq->history_set_limit;
 
 	if (!exists)
 		AddListItem(m, historybackends);
@@ -165,32 +166,32 @@ int history_add(char *object, MessageTag *mtags, char *line)
 	return 1;
 }
 
-int history_del(char *object, int max_lines, long max_time)
+int history_request(Client *client, char *object, HistoryFilter *filter)
 {
 	HistoryBackend *hb;
 
 	for (hb = historybackends; hb; hb=hb->next)
-		hb->history_del(object, max_lines, max_time);
+		hb->history_request(client, object, filter);
 
 	return 1;
 }
 
-int history_request(Client *client, char *object, HistoryFilter *filter)
+int history_destroy(char *object)
 {
 	HistoryBackend *hb;
 
 	for (hb = historybackends; hb; hb=hb->next)
-		hb->history_request(client, object, filter);
+		hb->history_destroy(object);
 
 	return 1;
 }
 
-int history_destroy(char *object)
+int history_set_limit(char *object, int max_lines, long max_t)
 {
 	HistoryBackend *hb;
 
 	for (hb = historybackends; hb; hb=hb->next)
-		hb->history_destroy(object);
+		hb->history_set_limit(object, max_lines, max_t);
 
 	return 1;
 }
diff --git a/src/api-messagetag.c b/src/api-messagetag.c
index 794a12e..458c5cf 100644
--- a/src/api-messagetag.c
+++ b/src/api-messagetag.c
@@ -83,6 +83,7 @@ MessageTagHandler *MessageTagHandlerAdd(Module *module, MessageTagHandlerInfo *m
 	m->owner = module;
 	m->flags = mreq->flags;
 	m->is_ok = mreq->is_ok;
+	m->can_send = mreq->can_send;
 	m->clicap_handler = mreq->clicap_handler;
 
 	/* Update reverse dependency (if any) */
diff --git a/src/conf.c b/src/conf.c
index 2a5cb6d..e65ebee 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -2730,25 +2730,7 @@ int	config_run()
 	free_iConf(&iConf);
 	memcpy(&iConf, &tempiConf, sizeof(iConf));
 	memset(&tempiConf, 0, sizeof(tempiConf));
-
-	{
-		EventInfo eInfo;
-		long v;
-		eInfo.flags = EMOD_EVERY;
-		if (!THROTTLING_PERIOD)
-			v = 120000;
-		else
-		{
-			v = THROTTLING_PERIOD/2;
-			if (v > 5)
-				v = 5000; /* accuracy, please */
-			if (v < 1)
-				v = 1000; /* duh */
-		}
-		eInfo.every_msec = v;
-		EventMod(EventFind("bucketcleaning"), &eInfo);
-	}
-
+	update_throttling_timer_settings();
 
 	/* initialize conf_files with defaults if the block isn't set: */
 	if(!conf_files)
diff --git a/src/hash.c b/src/hash.c
index 75d1be2..149e2cb 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -886,22 +886,35 @@ int   hash_del_watch_list(Client *client)
 
 struct MODVAR ThrottlingBucket *ThrottlingHash[THROTTLING_HASH_TABLE_SIZE];
 
-void init_throttling()
+void update_throttling_timer_settings(void)
 {
 	long v;
+	EventInfo eInfo;
 
 	if (!THROTTLING_PERIOD)
 	{
-		v = 120;
+		v = 120*1000;
 	} else
 	{
-		v = THROTTLING_PERIOD/2;
-		if (v > 5)
+		v = (THROTTLING_PERIOD*1000)/2;
+		if (v > 5000)
 			v = 5000; /* run at least every 5s */
-		if (v < 1)
+		if (v < 1000)
 			v = 1000; /* run at max once every 1s */
 	}
-	EventAdd(NULL, "bucketcleaning", e_clean_out_throttling_buckets, NULL, v, 0);