From 10798bae428a621a7c186e894140b625b7e56452 Mon Sep 17 00:00:00 2001 From: Michael Poole Date: Sun, 18 Mar 2007 02:46:56 +0000 Subject: [PATCH] Allow multiple server entries in a CRule and multiple vhosts in a Port. git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/branches/u2_10_12_branch@1784 c9e4aea6-c8fd-4c43-8297-357d70d61c8c --- ChangeLog | 21 +++++++++ doc/example.conf | 13 ++++++ ircd/ircd_parser.y | 113 ++++++++++++++++++++++++++++----------------- 3 files changed, 104 insertions(+), 43 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1d4f807..0688a24 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2007-03-17 Michael Poole + + * 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 * ircd/listener.c (add_listener): Only try to create IPv6 sockets diff --git a/doc/example.conf b/doc/example.conf index 93ad60e..0a93c2a 100644 --- a/doc/example.conf +++ b/doc/example.conf @@ -570,6 +570,8 @@ Connect { # # 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"; @@ -673,11 +675,14 @@ Operator { # 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. @@ -730,6 +735,14 @@ Port { 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 diff --git a/ircd/ircd_parser.y b/ircd/ircd_parser.y index dc815f9..67fddfc 100644 --- a/ircd/ircd_parser.y +++ b/ircd/ircd_parser.y @@ -60,8 +60,8 @@ #include #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; @@ -695,45 +695,68 @@ address_family: ; /* 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 ';' @@ -931,28 +954,30 @@ cruleblock: CRULE } '{' 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; }; @@ -961,9 +986,11 @@ cruleitem: cruleserver | crulerule | cruleall; 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 ';' -- 2.20.1