+2007-03-17 Michael Poole <mdpoole@troilus.org>
+
+ * doc/example.conf (CRule): Document the support for multiple
+ server masks in a single CRule block.
+ (Port): Document the optional additional field for vhost entries.
+ Document the support for multiple vhost entries in a single Port
+ block.
+
+ * ircd/ircd_parser.y (USE_IPV4): Shift up by 16 bytes.
+ (USE_IPV6): Likewise.
+ (portblock): Iterate over hosts rather than using the single host.
+ (portitem): Add portvhostnumber alternative production.
+ (portnumber): Check port number here. If valid, combine address
+ family and port number in "port" variable. If a port-less item
+ exists in "hosts", set its port number.
+ (portvhost): Prepend mask to "hosts" list.
+ (portvhostnumber): New production.
+ (cruleblock): Iterate over hosts rather than using the single
+ host.
+ (cruleserver): Prepend server mask to "hosts" list.
+
2007-03-17 Michael Poole <mdpoole@troilus.org>
* ircd/listener.c (add_listener): Only try to create IPv6 sockets
#
# For an advanced, real-time rule-based routing decision making system
# you can use crule blocks. For more information, see doc/readme.crules.
+# If more than one server mask is present in a single crule, the rule
+# applies to all servers.
# CRULE
# {
# server = "servermask";
# IANA says we should use port 194, but that requires us to run as root,
# so we don't do that.
#
+#
# Port {
# port = [ipv4] [ipv6] number;
# mask = "ipmask";
# # Use this to control the interface you bind to.
# vhost = [ipv4] [ipv6] "virtualhostip";
+# # You can specify both virtual host and port number in one entry.
+# vhost = [ipv4] [ipv6] "virtualhostip" number;
# # Setting to yes makes this server only.
# server = yes;
# # Setting to yes makes the port "hidden" from stats.
port = 7000;
};
+# More than one vhost may be present in a single Port block; in this case,
+# we recommend listing the port number on the vhost line for clarity.
+Port {
+ vhost = "172.16.0.1" 6667;
+ vhost = "172.16.3.1" 6668;
+ hidden = no;
+};
+
# Quarantine blocks disallow operators from using OPMODE and CLEARMODE
# on certain channels. Opers with the force_opmode (for local
# channels, force_local_opmode) privilege may override the quarantine
#include <arpa/inet.h>
#define MAX_STRINGS 80 /* Maximum number of feature params. */
-#define USE_IPV4 (1 << 0)
-#define USE_IPV6 (1 << 1)
+#define USE_IPV4 (1 << 16)
+#define USE_IPV6 (1 << 17)
extern struct LocalConf localConf;
extern struct DenyConf* denyConfList;
;
/* The port block... */
-portblock: PORT '{' portitems '}' ';'
-{
- if (!FlagHas(&listen_flags, LISTEN_IPV4)
- && !FlagHas(&listen_flags, LISTEN_IPV6))
- {
- FlagSet(&listen_flags, LISTEN_IPV4);
- FlagSet(&listen_flags, LISTEN_IPV6);
+portblock: PORT '{' portitems '}' ';' {
+ struct ListenerFlags flags_here;
+ struct SLink *link;
+ for (link = hosts; link != NULL; link = link->next) {
+ memcpy(&flags_here, &listen_flags, sizeof(&flags_here));
+ switch (link->flags & (USE_IPV4 | USE_IPV6)) {
+ case USE_IPV4:
+ FlagSet(&flags_here, LISTEN_IPV4);
+ break;
+ case USE_IPV6:
+ FlagSet(&flags_here, LISTEN_IPV6);
+ break;
+ default: /* 0 or USE_IPV4|USE_IPV6 */
+ FlagSet(&flags_here, LISTEN_IPV4);
+ FlagSet(&flags_here, LISTEN_IPV6);
+ break;
+ }
+ if (link->flags & 65535)
+ port = link->flags & 65535;
+ add_listener(port, link->value.cp, pass, &flags_here);
}
- if (port > 0 && port <= 0xFFFF)
- add_listener(port, host, pass, &listen_flags);
- else
- parse_error("Port %d is out of range", port);
- MyFree(host);
+ free_slist(&hosts);
MyFree(pass);
memset(&listen_flags, 0, sizeof(listen_flags));
- host = pass = NULL;
+ pass = NULL;
port = 0;
};
portitems: portitem portitems | portitem;
-portitem: portnumber | portvhost | portmask | portserver | porthidden;
+portitem: portnumber | portvhost | portvhostnumber | portmask | portserver | porthidden;
portnumber: PORT '=' address_family NUMBER ';'
{
- int families = $3;
- if (families & USE_IPV4)
- FlagSet(&listen_flags, LISTEN_IPV4);
- else if (families & USE_IPV6)
- FlagSet(&listen_flags, LISTEN_IPV6);
- port = $4;
+ if ($4 < 1 || $4 > 65535) {
+ parse_error("Port %d is out of range", port);
+ } else {
+ port = $3 | $4;
+ if (hosts && (0 == (hosts->flags & 65535)))
+ hosts->flags = (hosts->flags & ~65535) | port;
+ }
};
portvhost: VHOST '=' address_family QSTRING ';'
{
- int families = $3;
- if (families & USE_IPV4)
- FlagSet(&listen_flags, LISTEN_IPV4);
- else if (families & USE_IPV6)
- FlagSet(&listen_flags, LISTEN_IPV6);
- MyFree(host);
- host = $4;
+ struct SLink *link;
+ link = make_link();
+ link->value.cp = $4;
+ link->flags = $3 | port;
+ link->next = hosts;
+ hosts = link;
+};
+
+portvhostnumber: VHOST '=' address_family QSTRING NUMBER ';'
+{
+ if ($5 < 1 || $5 > 65535) {
+ parse_error("Port %d is out of range", port);
+ } else {
+ struct SLink *link;
+ link = make_link();
+ link->value.cp = $4;
+ link->flags = $3 | $5;
+ link->next = hosts;
+ hosts = link;
+ }
};
portmask: MASK '=' QSTRING ';'
} '{' cruleitems '}' ';'
{
struct CRuleNode *node = NULL;
- if (host == NULL)
- parse_error("Missing host in crule block");
+ struct SLink *link;
+
+ if (hosts == NULL)
+ parse_error("Missing server(s) in crule block");
else if (pass == NULL)
parse_error("Missing rule in crule block");
else if ((node = crule_parse(pass)) == NULL)
parse_error("Invalid rule '%s' in crule block", pass);
- else
+ else for (link = hosts; link != NULL; link = link->next)
{
struct CRuleConf *p = (struct CRuleConf*) MyMalloc(sizeof(*p));
- p->hostmask = host;
- p->rule = pass;
+ if (node == NULL)
+ node = crule_parse(pass);
+ DupString(p->hostmask, link->value.cp);
+ DupString(p->rule, pass);
p->type = tconn;
p->node = node;
+ node = NULL;
p->next = cruleConfList;
cruleConfList = p;
}
- if (!node)
- {
- MyFree(host);
- MyFree(pass);
- }
- host = pass = NULL;
+ free_slist(&hosts);
+ MyFree(pass);
+ pass = NULL;
tconn = 0;
};
cruleserver: SERVER '=' QSTRING ';'
{
- MyFree(host);
- collapse($3);
- host = $3;
+ struct SLink *link;
+ link = make_link();
+ link->value.cp = $3;
+ link->next = hosts;
+ hosts = link;
};
crulerule: RULE '=' QSTRING ';'