Get rid of CONF_LEAF and CONF_HUB, and follow up with code cleanups.
authorMichael Poole <mdpoole@troilus.org>
Tue, 12 Oct 2004 18:24:13 +0000 (18:24 +0000)
committerMichael Poole <mdpoole@troilus.org>
Tue, 12 Oct 2004 18:24:13 +0000 (18:24 +0000)
git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/trunk@1240 c9e4aea6-c8fd-4c43-8297-357d70d61c8c

ChangeLog
doc/example.conf
include/list.h
include/s_conf.h
ircd/ircd_lexer.l
ircd/ircd_parser.y
ircd/m_server.c
ircd/s_conf.c
ircd/s_err.c
ircd/s_serv.c
ircd/s_stats.c

index 5ccf170b830287683c19a9886a60b855f15a881e..38ef8cee613a8c692fa20735be6c16538f8a8877 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,41 @@
+2004-10-12  Michael Poole <mdpoole@troilus.org>
+
+       * doc/example.conf: Update example config to reflect the changes
+       made in the remainder of this patch.
+
+       * include/list.h: Make make_conf() take a type argument.
+
+       * include/s_conf.h: Delete CONF_LEAF and CONF_HUB.  Add "maximum"
+       and "hub_limit" to ConfItem to compensate.
+
+       * ircd/ircd_lexer.l: Recognize MAXHOPS token.
+
+       * ircd/ircd_parser.y: Get rid of aconf global variable and add
+       hub_limit global variable.  Add MAXHOPS token, and productions
+       inside connectblock to recognize it and hub masks.  Allow maxlinks
+       field in a Client block, rather than overloading password field.
+       Convert serverblock to uworldblock and remove extraneous fields.
+
+       * ircd/m_server.c: Make check_loop_and_lh() look up ConfItem and
+       calculate LHcptr and active_lh_line.  Merge some duplicated code
+       so handling active_lh_line cases is clearer.
+
+       * ircd/s_conf.c: Make make_conf() take a type argument.  Delete
+       CONF_LEAF and CONF_HUB.  Do not overwrite server name with what
+       is specified in the config file.
+
+       * ircd/s_err.c: Remove the unused RPL_STATSNLINE and
+       RPL_STATSHLINE.  Remove useless parameters and format fields from
+       RPL_STATSCLINE, RPL_STATSILINE, RPL_STATSLLINE, RPL_STATSOLINE and
+       RPL_STATSULINE.
+
+       * ircd/s_serv.c: Delete CONF_LEAF and CONF_HUB.
+
+       * ircd/s_stats.c: Get rid of report_array and make
+       stats_configured_links() directly use RPL_STATSxLINE (adding the
+       new fields for Server and Client blocks).  Remove /stats h, since
+       that has no meaning.
+
 2004-10-12  Michael Poole <mdpoole@troilus.org>
 
        * ircd/m_burst.c: Mask off channel modes in a wiped-out channel by
index e5073920df2dd841eeeaa36f8ce953d83be53775..95b37da7b88401c50a71b8f6094639a7c9ae685b 100644 (file)
@@ -305,7 +305,7 @@ Client
  class = "Local";
 };
 
-# You can put a digit (0..9) in the password value, which will make ircd
+# You can put an expression in the maxlinks value, which will make ircd
 # only accept a client when the total number of connections to the network
 # from the same IP number doesn't exceed this number.
 # The following example would accept at most one connection per IP number
@@ -313,12 +313,12 @@ Client
 # that have "dial??.*" as host mask:
 # Client {
 #  host = "*@*.swipnet.se";
-#  password = "1";
+#  maxlinks = 1;
 #  class = "Other";
 # };
 # Client {
 #  host = "*@dial??.*";
-#  password = "2";
+#  maxlinks = 2;
 #  class = "Other";
 # };
 #
@@ -364,7 +364,7 @@ motd {
  file = "london.motd";
 };
 
-# [Server]
+# [UWorld]
 #
 # One of the many nice features of Undernet is "Uworld", a program
 # connected to the net as a server. This allows it to broadcast any mode
@@ -373,17 +373,9 @@ motd {
 # There is only one slight problem: the TimeStamp protocol prevents this.
 # So there is a configuration option to allow them anyway from a certain
 # server.
-# Server {
+# UWorld {
 #  # The servername or wildcard mask for it that this applies to.
 #  name = "relservername";
-#  # The mask of servers they are allowed to introduce(for hub=yes;) or
-#  # not allowed to introduce(for leaf=yes).
-#  mask = "servermask";
-#  # No is assumed for these unless you set it to yes.
-#  uworld = no;
-#  hub = no;
-#  # Yes is assumed for "leaf" unless you set it to no.
-#  leaf = yes;
 # };
 #
 # Note: (1) These lines are agreed on by every server admin on Undernet;
@@ -393,7 +385,7 @@ motd {
 # If you're on Undernet, you MUST have these lines. I cannnot stress
 # this enough.  If all of the servers don't have the same lines, the
 # servers will try to undo the mode hacks that Uworld does.  Make SURE that
-# all of the servers have the EXACT same Ulines.
+# all of the servers have the EXACT same UWorld blocks.
 #
 # If your server starts on a bit larger network, you'll probably get
 # assigned one or two uplinks to which your server can connect.
@@ -403,59 +395,32 @@ motd {
 # You can also force a server(even one that doesn't connect to you)
 # to be a leaf with "leaf = yes;"
 
-Server {
+UWorld {
  name = "uworld.eu.undernet.org";
- mask = "*";
- uworld = yes;
- hub = yes;
 };
-Server {
+UWorld {
  name = "uworld2.undernet.org";
- mask = "*";
- uworld = yes;
- hub = yes;
 };
-Server {
+UWorld {
  name = "uworld.undernet.org";
- mask = "*";
- uworld = yes;
- hub = yes;
 };
-Server {
+UWorld {
  name = "channels.undernet.org";
- mask = "*";
- uworld = yes;
- hub = yes;
 };
-Server {
+UWorld {
  name = "channels2.undernet.org";
- mask = "*";
- uworld = yes;
- hub = yes;
 };
-Server {
+UWorld {
  name = "channels3.undernet.org";
- mask = "*";
- uworld = yes;
- hub = yes;
 };
-Server {
+UWorld {
  name = "channels4.undernet.org";
- mask = "*";
- uworld = yes;
- hub = yes;
 };
-Server {
+UWorld {
  name = "channels5.undernet.org";
- mask = "*";
- uworld = yes;
- hub = yes;
 };
-Server {
+UWorld {
  name = "channels6.undernet.org";
- mask = "*";
- uworld = yes;
- hub = yes;
 };
 Server {
  name = "Amsterdam.NL.Eu.UnderNet.org";
@@ -555,13 +520,21 @@ Kill
 #  password = "passwd";
 #  port = portno;
 #  class = "classname";
+#  maxhops = 2;
+#  hub = "*.eu.undernet.org";
 # };
 #
 # The "port" field defines the default port the server tries to connect
 # to if an operator uses /connect without specifying a port. This is also
-# the port used when the server attempts to auto-connect to the remote 
+# the port used when the server attempts to auto-connect to the remote
 # server. (See Class blocks for more informationa about auto-connects).
 #
+# The maxhops field causes an SQUIT if a hub tries to introduce
+# servers farther away than that; the element 'leaf;' is an alias for
+# 'maxhops = 0;'.  The hub field limits the names of servers that may
+# be introduced by a hub; the element 'hub;' is an alias for
+# 'hub = "*";'.
+#
 # Our primary uplink.
 Connect {
  name = "Amsterdam.NL.Eu.UnderNet.org";
@@ -569,6 +542,7 @@ Connect {
  password = "passwd";
  port = 4400;
  class = "Servers";
+ hub;
 };
 
 # [crule]
index 1e69ae97483e54a486db9b48816dbf1e31cbcb33..a400ee29c8e1e30abaa777ccb557b40f50353e33 100644 (file)
@@ -62,7 +62,7 @@ extern void remove_client_from_list(struct Client *cptr);
 extern void add_client_to_list(struct Client *cptr);
 extern struct DLink *add_dlink(struct DLink **lpp, struct Client *cp);
 extern void remove_dlink(struct DLink **lpp, struct DLink *lp);
-extern struct ConfItem *make_conf(void);
+extern struct ConfItem *make_conf(int type);
 extern void free_conf(struct ConfItem *aconf);
 extern void send_listinfo(struct Client *cptr, char *name);
 
index 3d48e8cbc75070466959dba659ef30ada3590edf..066e9dacf3202e70f25a37cbdf4315ac6e905351 100644 (file)
@@ -30,8 +30,6 @@ struct Message;
 #define CONF_CLIENT             0x0002     /**< ConfItem describes a Client block */
 #define CONF_SERVER             0x0004     /**< ConfItem describes a Connect block */
 #define CONF_OPERATOR           0x0020     /**< ConfItem describes an Operator block */
-#define CONF_LEAF               0x1000     /**< ConfItem describes a Server leaf */
-#define CONF_HUB                0x4000     /**< ConfItem describes a Server hub */
 #define CONF_UWORLD             0x8000     /**< ConfItem describes a Uworld server */
 
 /** Indicates ConfItem types that count associated clients. */
@@ -50,17 +48,22 @@ struct ConfItem
   struct ConfItem *next;    /**< Next ConfItem in #GlobalConfList */
   unsigned int status;      /**< Set of CONF_* bits. */
   unsigned int clients;     /**< Number of *LOCAL* clients using this */
+  unsigned int maximum;     /**< For CONF_SERVER, max hops.
+                               For CONF_CLIENT, max connects per IP. */
   struct ConnectionClass *conn_class;  /**< Class of connection */
-  struct irc_sockaddr origin;  /**< local address for outbound connections */
-  struct irc_sockaddr address; /**< ip and port */
-  char *host; /**< peer hostname */
-  char *origin_name; /**< text form of origin address */
-  char *passwd; /**< password field */
-  char *name; /**< name of peer */
-  time_t hold; /**< Earliest time to attempt an outbound connect on this ConfItem. */
-  int dns_pending; /**< a dns request is pending */
+  struct irc_sockaddr origin;  /**< Local address for outbound connections */
+  struct irc_sockaddr address; /**< IP and port */
+  char *host;         /**< Peer hostname */
+  char *origin_name;  /**< Text form of origin address */
+  char *passwd;       /**< Password field */
+  char *name;         /**< Name of peer */
+  char *hub_limit;    /**< Mask that limits servers allowed behind
+                         this one. */
+  time_t hold;        /**< Earliest time to attempt an outbound
+                         connect on this ConfItem. */
+  int dns_pending;    /**< A dns request is pending. */
   unsigned char bits; /**< Number of bits for ipkills. */
-  struct Privs privs; /**< Priviledges for opers. */
+  struct Privs privs; /**< Privileges for opers. */
   /** Used to detect if a privilege has been set by this ConfItem. */
   struct Privs privs_dirty;
 };
index 458e571cdd867cd1a4052c7725514d3524e2e7f0..2dd3e769c1bb570484941afbab5a2eee4db84a12 100644 (file)
@@ -46,6 +46,7 @@ static struct lexer_token {
   TOKEN(CONNECT),
   TOKEN(CONNECTFREQ),
   TOKEN(MAXLINKS),
+  TOKEN(MAXHOPS),
   TOKEN(SENDQ),
   TOKEN(NAME),
   TOKEN(HOST),
index ef910fb138e6b8498e42fc313e838f685a42bbb1..9f102009780dc10d192c8643a3bc58d7ae28d00a 100644 (file)
   extern struct ServerConf* serverConfList;
   extern struct s_map*      GlobalServiceMapList;
   extern struct qline*      GlobalQuarantineList;
 
   int yylex(void);
   /* Now all the globals we need :/... */
-  int tping, tconn, maxlinks, sendq, port, invert;
-  int stringno;
-  char *name, *pass, *host, *origin;
+  int tping, tconn, maxlinks, sendq, port, invert, stringno;
+  char *name, *pass, *host, *origin, *hub_limit;
   char *stringlist[MAX_STRINGS];
   struct ConnectionClass *c_class;
-  struct ConfItem *aconf;
   struct DenyConf *dconf;
   struct ServerConf *sconf;
   struct qline *qconf = NULL;
@@ -107,6 +104,7 @@ static void parse_error(char *pattern,...) {
 %token PINGFREQ
 %token CONNECTFREQ
 %token MAXLINKS
+%token MAXHOPS
 %token SENDQ
 %token NAME
 %token HOST
@@ -181,7 +179,7 @@ static void parse_error(char *pattern,...) {
 /* Blocks in the config file... */
 blocks: blocks block | block;
 block: adminblock | generalblock | classblock | connectblock |
-       serverblock | operblock | portblock | jupeblock | clientblock |
+       uworldblock | operblock | portblock | jupeblock | clientblock |
        killblock | cruleblock | motdblock | featuresblock | quarantineblock |
        pseudoblock | iauthblock | error;
 
@@ -387,26 +385,25 @@ classusermode: USERMODE '=' QSTRING ';'
 
 connectblock: CONNECT
 {
- name = pass = host = origin = NULL;
+ name = pass = host = origin = hub_limit = NULL;
  c_class = NULL;
  port = 0;
+ maxlinks = 65535;
 } '{' connectitems '}'
 {
  if (name != NULL && pass != NULL && host != NULL && c_class != NULL
      && !strchr(host, '*') && !strchr(host, '?'))
  {
-   aconf = make_conf();
-   aconf->status = CONF_SERVER;
+   struct ConfItem *aconf = make_conf(CONF_SERVER);
    aconf->name = name;
    aconf->origin_name = origin;
    aconf->passwd = pass;
    aconf->conn_class = c_class;
    aconf->address.port = port;
-   aconf->status = CONF_SERVER;
    aconf->host = host;
-   aconf->next = GlobalConfList;
+   aconf->maximum = maxlinks;
+   aconf->hub_limit = hub_limit;
    lookup_confhost(aconf);
-   GlobalConfList = aconf;
  }
  else
  {
@@ -414,13 +411,14 @@ connectblock: CONNECT
    MyFree(pass);
    MyFree(host);
    MyFree(origin);
+   MyFree(hub_limit);
    parse_error("Bad connect block");
  }
- name = pass = host = origin = NULL;
 }';';
 connectitems: connectitem connectitems | connectitem;
 connectitem: connectname | connectpass | connectclass | connecthost
-              | connectport | connectvhost | error;
+              | connectport | connectvhost | connectleaf | connecthub
+              | connecthublimit | connectmaxhops | error;
 connectname: NAME '=' QSTRING ';'
 {
  MyFree(name);
@@ -449,135 +447,103 @@ connectvhost: VHOST '=' QSTRING ';'
  MyFree(origin);
  DupString(origin, $3);
 };
-
-serverblock: SERVER
-{
- aconf = (struct ConfItem*) MyMalloc(sizeof(*aconf));
- memset(aconf, 0, sizeof(*aconf));
- aconf->status = CONF_LEAF;
-} '{' serveritems '}'
+connectleaf: LEAF ';'
 {
- if (aconf->status == 0)
- {
-   MyFree(aconf->host);
-   MyFree(aconf->name);
-   MyFree(aconf);
-   aconf = NULL;
-   parse_error("Bad server block");
- }
- else
- {
-   aconf->next = GlobalConfList;
-   GlobalConfList = aconf;
- }
-} ';';
-serveritems: serveritem serveritems | serveritem;
-serveritem: servername | servermask | serverhub | serverleaf |
-             serveruworld | error;
-servername: NAME '=' QSTRING
+ maxlinks = 0;
+};
+connecthub: HUB ';'
 {
- MyFree(aconf->name);
- DupString(aconf->name, $3);
-} ';' ;
-servermask: MASK '=' QSTRING
+ MyFree(hub_limit);
+ DupString(hub_limit, "*");
+};
+connecthublimit: HUB '=' QSTRING ';'
 {
- MyFree(aconf->host);
- DupString(aconf->host, $3);
-} ';' ;
-/* XXX - perhaps we should do this the hybrid way in connect blocks
- * instead -A1kmm. */
-serverhub: HUB '=' YES ';'
+ MyFree(hub_limit);
+ DupString(hub_limit, $3);
+};
+connectmaxhops: MAXHOPS '=' expr ';'
 {
- aconf->status |= CONF_HUB;
- aconf->status &= ~CONF_LEAF;
+  maxlinks = $3;
 }
-| HUB '=' NO
-{
- aconf->status &= ~CONF_HUB;
-} ';'; 
-serverleaf: LEAF '=' YES ';'
+
+uworldblock: UWORLD '{' uworlditems '}' ';'
 {
- if (!(aconf->status & CONF_HUB && aconf->status & CONF_UWORLD))
-  aconf->status |= CONF_LEAF;
+ if (name)
+ {
+  struct ConfItem *aconf = make_conf(CONF_UWORLD);
+  aconf->name = name;
+ }
  else
-  parse_error("Server is both leaf and a hub");
-}
-| LEAF '=' NO ';'
-{
- aconf->status &= ~CONF_LEAF;
+ {
+  MyFree(name);
+  parse_error("Bad UWorld block");
+ }
 };
-serveruworld: UWORLD '=' YES ';'
-{
- aconf->status |= CONF_UWORLD;
- aconf->status &= ~CONF_LEAF;
-}
-| UWORLD '=' NO ';'
+uworlditems: uworlditem uworlditems | uworlditem;
+uworlditem: uworldname | error;
+uworldname: NAME '=' QSTRING ';'
 {
-  aconf->status &= ~CONF_UWORLD;
+ MyFree(name);
+ DupString(name, $3);
 };
 
 operblock: OPER
 {
-  aconf = (struct ConfItem*) MyMalloc(sizeof(*aconf));
-  memset(aconf, 0, sizeof(*aconf));
+  name = pass = host = NULL;
+  c_class = NULL;
   memset(&privs, 0, sizeof(privs));
   memset(&privs_dirty, 0, sizeof(privs_dirty));
-  aconf->status = CONF_OPERATOR;
 } '{' operitems '}' ';'
 {
-  if (aconf->name != NULL && aconf->passwd != NULL && aconf->host != NULL
-      && aconf->conn_class != NULL)
+  if (name && pass && host && c_class)
   {
+    struct ConfItem *aconf = make_conf(CONF_OPERATOR);
+    aconf->name = name;
+    aconf->passwd = pass;
+    aconf->host = host;
+    aconf->conn_class = c_class;
     memcpy(&aconf->privs, &privs, sizeof(aconf->privs));
     memcpy(&aconf->privs_dirty, &privs_dirty, sizeof(aconf->privs_dirty));
     if (!PrivHas(&privs_dirty, PRIV_PROPAGATE)
-        && !PrivHas(&aconf->conn_class->privs_dirty, PRIV_PROPAGATE))
-      parse_error("Operator block for %s and class %s have no LOCAL setting", aconf->name, aconf->conn_class->cc_name);
-    aconf->next = GlobalConfList;
-    GlobalConfList = aconf;
+        && !PrivHas(&c_class->privs_dirty, PRIV_PROPAGATE))
+      parse_error("Operator block for %s and class %s have no LOCAL setting", name, c_class->cc_name);
   }
   else
   {
     log_write(LS_CONFIG, L_ERROR, 0, "operator blocks need a name, password, and host.");
-    MyFree(aconf->name);
-    MyFree(aconf->passwd);
-    MyFree(aconf->host);
-    MyFree(aconf);
-    aconf = NULL;
+    MyFree(name);
+    MyFree(pass);
+    MyFree(host);
   }
 };
 operitems: operitem | operitems operitem;
 operitem: opername | operpass | operhost | operclass | priv | error;
-
 opername: NAME '=' QSTRING ';'
 {
-  MyFree(aconf->name);
-  DupString(aconf->name, $3);
+  MyFree(name);
+  DupString(name, $3);
 };
-
 operpass: PASS '=' QSTRING ';'
 {
-  MyFree(aconf->passwd);
-  DupString(aconf->passwd, $3);
+  MyFree(pass);
+  DupString(pass, $3);
 };
-
 operhost: HOST '=' QSTRING ';'
 {
- MyFree(aconf->host);
+ MyFree(host);
  if (!strchr($3, '@'))
  {
    int uh_len;
    char *b = (char*) MyMalloc((uh_len = strlen($3)+3));
    ircd_snprintf(0, b, uh_len, "*@%s", $3);
-   aconf->host = b;
+   host = b;
  }
  else
-   DupString(aconf->host, $3);
+   DupString(host, $3);
 };
-
 operclass: CLASS '=' QSTRING ';'
 {
aconf->conn_class = find_class($3);
c_class = find_class($3);
 };
 
 priv: privtype '=' yesorno ';'
@@ -683,55 +649,52 @@ porthidden: HIDDEN '=' YES ';'
 
 clientblock: CLIENT
 {
-  aconf = (struct ConfItem*) MyMalloc(sizeof(*aconf));
-  memset(aconf, 0, sizeof(*aconf));
-  aconf->status = CONF_CLIENT;
-} '{' clientitems '}'
+  host = name = NULL;
+  c_class = NULL;
+  maxlinks = 65535;
+}
+'{' clientitems '}' ';'
 {
-  if ((aconf->host != NULL || aconf->name!=NULL))
+  if (host && name)
   {
-    if (aconf->host == NULL)
-      DupString(aconf->host, "");
-    if (aconf->name == NULL)
-      DupString(aconf->name, "");
-    if (aconf->conn_class == NULL)
-      aconf->conn_class = find_class("default");
-    aconf->next = GlobalConfList;
-    GlobalConfList = aconf;
-    aconf = NULL;
+    struct ConfItem *aconf = make_conf(CONF_CLIENT);
+    aconf->host = host;
+    aconf->name = name;
+    aconf->conn_class = c_class ? c_class : find_class("default");
+    aconf->maximum = maxlinks;
   }
   else
   {
-   MyFree(aconf->host);
-   MyFree(aconf->passwd);
-   MyFree(aconf);
-   aconf = NULL;
-   parse_error("Bad client block");
+    MyFree(host);
+    MyFree(name);
+    parse_error("Bad client block");
   }
-} ';';
+};
 clientitems: clientitem clientitems | clientitem;
-clientitem: clienthost | clientclass | clientpass | clientip | error;
+clientitem: clienthost | clientclass | clientpass | clientip
+  | clientmaxlinks | error;
 clientip: IP '=' QSTRING ';'
 {
-  MyFree(aconf->host);
-  DupString(aconf->host, $3);
+  MyFree(host);
+  DupString(host, $3);
 };
-
 clienthost: HOST '=' QSTRING ';'
 {
-  MyFree(aconf->name);
-  DupString(aconf->name, $3);
+  MyFree(name);
+  DupString(name, $3);
 };
-
 clientclass: CLASS '=' QSTRING ';'
 {
-  aconf->conn_class = find_class($3);
+  c_class = find_class($3);
 };
-
 clientpass: PASS '=' QSTRING ';'
 {
-  MyFree(aconf->passwd);
-  DupString(aconf->passwd, $3);
+  MyFree(pass);
+  DupString(pass, $3);
+};
+clientmaxlinks: MAXLINKS '=' expr ';'
+{
+  maxlinks = $3;
 };
 
 killblock: KILL
index f433c3d053c0a7e0bb797ab44a6bb0251f65fc24..d092fa4f2dc9e2889ca7dd40dc2e7fc9bb0341f9 100644 (file)
@@ -100,27 +100,56 @@ parse_protocol(const char *proto)
  * or be disallowed by leaf and hub configuration directives.
  * @param[in] cptr Neighbor who sent the message.
  * @param[in] sptr Client that originated the message.
- * @param[in] LHcptr Who to SQUIT on error (if NULL, SQUIT new server).
- * @param[in] lhconf Leaf or hub configuration block to use.
  * @param[out] ghost If non-NULL, receives ghost timestamp for new server.
  * @param[in] host Name of new server.
  * @param[in] numnick Numnick mask of new server.
  * @param[in] timestamp Claimed link timestamp of new server.
- * @param[in] active_lh_line Pseudo-enum value for rejection reason.
- * 0 means no leaf or hub restrictions.  1 means \a lhconf is a leaf
- * rule.  2 means \a lhconf is a hub rule.  3 means #me does not have
- * the HUB feature but already has a server link.
+ * @param[in] hop Number of hops to the new server.
+ * @param[in] junction Non-zero if the new server is still bursting.
  * @return CPTR_KILLED if \a cptr was SQUIT.  0 if some other server
  * was SQUIT.  1 if the new server is allowed.
  */
 static int
-check_loop_and_lh(struct Client* cptr, struct Client *sptr, struct Client *LHcptr, struct ConfItem *lhconf, time_t *ghost, const char *host, const char *numnick, time_t timestamp, int active_lh_line)
+check_loop_and_lh(struct Client* cptr, struct Client *sptr, time_t *ghost, const char *host, const char *numnick, time_t timestamp, int hop, int junction)
 {
   struct Client* acptr;
+  struct Client* LHcptr = NULL;
+  struct ConfItem* lhconf;
+  int active_lh_line = 0, ii;
 
   if (ghost)
     *ghost = 0;
 
+  /*
+   * Calculate type of connect limit and applicable config item.
+   */
+  lhconf = find_conf_byname(cli_confs(cptr), host, CONF_SERVER);
+  assert(lhconf != NULL);
+  if (cptr == sptr)
+  {
+    if (!feature_bool(FEAT_HUB))
+      for (ii = 0; ii <= HighestFd; ii++)
+        if (LocalClientArray[ii] && IsServer(LocalClientArray[ii])) {
+          active_lh_line = 3;
+          break;
+        }
+  }
+  else if (hop > lhconf->maximum)
+  {
+    active_lh_line = 1;
+  }
+  else if (lhconf->hub_limit && match(lhconf->hub_limit, host))
+  {
+    struct Client *ac3ptr;
+    active_lh_line = 2;
+    if (junction)
+      for (ac3ptr = sptr; ac3ptr != &me; ac3ptr = cli_serv(ac3ptr)->up)
+        if (IsJunction(ac3ptr)) {
+          LHcptr = ac3ptr;
+          break;
+        }
+  }
+
   /*
    *  We want to find IsConnecting() and IsHandshake() too,
    *  use FindClient().
@@ -370,37 +399,36 @@ check_loop_and_lh(struct Client* cptr, struct Client *sptr, struct Client *LHcpt
 
   if (active_lh_line)
   {
-    if (LHcptr == 0) {
-      return exit_new_server(cptr, sptr, host, timestamp,
-          (active_lh_line == 2) ?  "Non-Hub link %s <- %s(%s), check H:" :
-                                   "Leaf-only link %s <- %s(%s), check L:",
-          cli_name(cptr), host,
-          lhconf ? (lhconf->name ? lhconf->name : "*") : "!");
+    int killed = 0;
+    if (LHcptr)
+      killed = a_kills_b_too(LHcptr, sptr);
+    else
+      LHcptr = sptr;
+    if (active_lh_line == 1)
+    {
+      if (exit_client_msg(cptr, LHcptr, &me,
+                          "Leaf-only link %s <- %s, check L:",
+                          cli_name(cptr), host) == CPTR_KILLED)
+        return CPTR_KILLED;
+    }
+    else if (active_lh_line == 2)
+    {
+      if (exit_client_msg(cptr, LHcptr, &me,
+                          "Non-Hub link %s <- %s, check H:",
+                          cli_name(cptr), host) == CPTR_KILLED)
+        return CPTR_KILLED;
     }
     else
     {
-      int killed = a_kills_b_too(LHcptr, sptr);
-      if (active_lh_line < 3)
-      {
-        if (exit_client_msg(cptr, LHcptr, &me,
-            (active_lh_line == 2) ?  "Non-Hub link %s <- %s(%s), check H:" :
-                                     "Leaf-only link %s <- %s(%s), check L:",
-            cli_name(cptr), host,
-            lhconf ? (lhconf->name ? lhconf->name : "*") : "!") == CPTR_KILLED)
-          return CPTR_KILLED;
-      }
-      else
-      {
-        ServerStats->is_ref++;
-        if (exit_client(cptr, LHcptr, &me, "I'm a leaf, define HUB") == CPTR_KILLED)
-          return CPTR_KILLED;
-      }
-      /*
-       * Did we kill the incoming server off already ?
-       */
-      if (killed)
-        return 0;
+      ServerStats->is_ref++;
+      if (exit_client(cptr, LHcptr, &me, "I'm a leaf, define HUB") == CPTR_KILLED)
+        return CPTR_KILLED;
     }
+    /*
+     * Did we kill the incoming server off already ?
+     */
+    if (killed)
+      return 0;
   }
 
   return 1;
@@ -472,14 +500,11 @@ check_start_timestamp(struct Client *cptr, time_t timestamp, time_t start_timest
 int mr_server(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
 {
   char*            ch;
-  int              i;
   char*            host;
-  const char*      encr;
   struct ConfItem* aconf;
   struct Jupe*     ajupe;
   int              hop;
   int              ret;
-  int              active_lh_line = 0;
   unsigned short   prot;
   time_t           start_timestamp;
   time_t           timestamp;
@@ -566,9 +591,8 @@ int mr_server(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
     return exit_client_msg(cptr, cptr, &me,
                            "Access denied. No conf line for server %s", cli_name(cptr));
   }
-  encr = cli_passwd(cptr);
 
-  if (*aconf->passwd && !!strcmp(aconf->passwd, encr)) {
+  if (*aconf->passwd && !!strcmp(aconf->passwd, cli_passwd(cptr))) {
     ++ServerStats->is_ref;
     sendto_opmask_butone(0, SNO_OLDSNO, "Access denied (passwd mismatch) %s",
                          cli_name(cptr));
@@ -578,15 +602,7 @@ int mr_server(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
 
   memset(cli_passwd(cptr), 0, sizeof(cli_passwd(cptr)));
 
-  if (!feature_bool(FEAT_HUB)) {
-    for (i = 0; i <= HighestFd; i++)
-      if (LocalClientArray[i] && IsServer(LocalClientArray[i])) {
-        active_lh_line = 3;
-        break;
-      }
-  }
-
-  ret = check_loop_and_lh(cptr, sptr, NULL, NULL, &ghost, host, (parc > 7 ? parv[6] : NULL), timestamp, active_lh_line);
+  ret = check_loop_and_lh(cptr, sptr, &ghost, host, (parc > 7 ? parv[6] : NULL), timestamp, hop, 1);
   if (ret != 1)
     return ret;
 
@@ -649,11 +665,8 @@ int ms_server(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
   char*            host;
   struct Client*   acptr;
   struct Client*   bcptr;
-  struct Client*   LHcptr;
-  struct ConfItem* lhconf;
   int              hop;
   int              ret;
-  int              active_lh_line = 0;
   unsigned short   prot;
   time_t           start_timestamp;
   time_t           timestamp;
@@ -691,50 +704,11 @@ int ms_server(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
     return exit_client_msg(cptr, sptr, &me,
         "Bogus timestamps (%s %s)", parv[3], parv[4]);
 
-  /*
-   * A local server introduces a new server behind this link.
-   * Check if this is allowed according L:, H: and Q: lines.
-   */
   if (parv[parc - 1][0] == '\0')
     return exit_client_msg(cptr, cptr, &me,
                            "No server info specified for %s", host);
-  /*
-   * See if the newly found server is behind a guaranteed
-   * leaf (L-line). If so, close the link.
-   */
-  if ((lhconf = find_conf_byhost(cli_confs(cptr), cli_name(cptr), CONF_LEAF)) &&
-      (!lhconf->address.port || (hop > lhconf->address.port)))
-  {
-    /*
-     * L: lines normally come in pairs, here we try to
-     * make sure that the oldest link is squitted, not
-     * both.
-     */
-    active_lh_line = 1;
-    if (timestamp <= cli_serv(cptr)->timestamp)
-      LHcptr = 0;          /* Kill incoming server */
-    else
-      LHcptr = cptr;          /* Squit ourselfs */
-  }
-  else if (!(lhconf = find_conf_byname(cli_confs(cptr), cli_name(cptr), CONF_HUB)) ||
-           (lhconf->address.port && (hop > lhconf->address.port)) ||
-           (!BadPtr(lhconf->host) && match(lhconf->host, host)))
-  {
-    struct Client *ac3ptr;
-    active_lh_line = 2;
-    /* Look for net junction causing this: */
-    LHcptr = 0;            /* incoming server */
-    if (*parv[5] != 'J') {
-      for (ac3ptr = sptr; ac3ptr != &me; ac3ptr = cli_serv(ac3ptr)->up) {
-        if (IsJunction(ac3ptr)) {
-          LHcptr = ac3ptr;
-          break;
-        }
-      }
-    }
-  }
 
-  ret = check_loop_and_lh(cptr, sptr, LHcptr, lhconf, NULL, host, (parc > 7 ? parv[6] : NULL), timestamp, active_lh_line);
+  ret = check_loop_and_lh(cptr, sptr, NULL, host, (parc > 7 ? parv[6] : NULL), timestamp, hop, parv[5][0] == 'J');
   if (ret != 1)
     return ret;
 
index ff2863cf334e1b5a7e8996c18dcf21a12125e0ac..43c382862ee89d9bef518c95ea897b10f154c252 100644 (file)
@@ -121,10 +121,10 @@ static void killcomment(struct Client* sptr, const char* filename)
   fbclose(file);
 }
 
-/** Allocate a new struct ConfItem.
+/** Allocate a new struct ConfItem and link it to #GlobalConfList.
  * @return Newly allocated structure.
  */
-struct ConfItem* make_conf(void)
+struct ConfItem* make_conf(int type)
 {
   struct ConfItem* aconf;
 
@@ -134,7 +134,9 @@ struct ConfItem* make_conf(void)
   ++GlobalConfCount;
 #endif
   memset(aconf, 0, sizeof(struct ConfItem));
-  aconf->status       = CONF_ILLEGAL;
+  aconf->status  = type;
+  aconf->next    = GlobalConfList;
+  GlobalConfList = aconf;
   return aconf;
 }
 
@@ -829,10 +831,8 @@ int rehash(struct Client *cptr, int sig)
     if ((acptr = LocalClientArray[i])) {
       assert(!IsMe(acptr));
       if (IsServer(acptr)) {
-        det_confs_butmask(acptr,
-            ~(CONF_HUB | CONF_LEAF | CONF_UWORLD | CONF_ILLEGAL));
-        attach_confs_byname(acptr, cli_name(acptr),
-                            CONF_HUB | CONF_LEAF | CONF_UWORLD);
+        det_confs_butmask(acptr, ~(CONF_UWORLD | CONF_ILLEGAL));
+        attach_confs_byname(acptr, cli_name(acptr), CONF_UWORLD);
       }
       /* Because admin's are getting so uppity about people managing to
        * get past K/G's etc, we'll "fix" the bug by actually explaining
@@ -1054,19 +1054,18 @@ int conf_check_server(struct Client *cptr)
    */
   det_confs_butmask(cptr, 0);
   /*
-   * if no C or no N lines, then deny access
+   * if no Connect block, then deny access
    */
   if (!c_conf) {
     Debug((DEBUG_DNS, "sv_cl: access denied: %s[%s@%s]",
           cli_name(cptr), cli_username(cptr), cli_sockhost(cptr)));
     return -1;
   }
-  ircd_strncpy(cli_name(cptr), c_conf->name, HOSTLEN);
   /*
-   * attach the C and N lines to the client structure for later use.
+   * attach the Connect block to the client structure for later use.
    */
   attach_conf(cptr, c_conf);
-  attach_confs_byname(cptr, cli_name(cptr), CONF_HUB | CONF_LEAF | CONF_UWORLD);
+  attach_confs_byname(cptr, cli_name(cptr), CONF_UWORLD);
 
   if (!irc_in_addr_valid(&c_conf->address.addr))
     memcpy(&c_conf->address.addr, &cli_ip(cptr), sizeof(c_conf->address.addr));
index 23137fd022db16c00390ed6857fda8eb0a9bab1e..ace809342266d97a5400218ba6642b342ed90e45 100644 (file)
@@ -461,11 +461,11 @@ static Numeric replyTable[] = {
 /* 212 */
   { RPL_STATSCOMMANDS, "%s %u %u", "212" },
 /* 213 */
-  { RPL_STATSCLINE, "%c %s * %s %d %s", "213" },
+  { RPL_STATSCLINE, "C %s %d %s", "213" },
 /* 214 */
-  { RPL_STATSNLINE, "%c %s * %s %d %d", "214" },
+  { 0 },
 /* 215 */
-  { RPL_STATSILINE, "%c %s %s %s %d %s", "215" },
+  { RPL_STATSILINE, "I %s %d %s %d %s", "215" },
 /* 216 */
   { RPL_STATSKLINE, "%c %s \"%s\" %s 0 0", "216" },
 /* 217 */
@@ -517,13 +517,13 @@ static Numeric replyTable[] = {
 /* 240 */
   { 0 },
 /* 241 */
-  { RPL_STATSLLINE, "%c %s * %s %d %d", "241" },
+  { RPL_STATSLLINE, "Module Description EntryPoint", "241" },
 /* 242 */
   { RPL_STATSUPTIME, ":Server Up %d days, %d:%02d:%02d", "242" },
 /* 243 */
-  { RPL_STATSOLINE, "%c %s * %s %d %d", "243" },
+  { RPL_STATSOLINE, "O %s * %s %d %d", "243" },
 /* 244 */
-  { RPL_STATSHLINE, "%c %s * %s %d %d", "244" },
+  { 0 },
 /* 245 */
   { 0 },
 /* 246 */
@@ -531,7 +531,7 @@ static Numeric replyTable[] = {
 /* 247 */
   { RPL_STATSGLINE, "%c %s%s%s %Tu :%s", "247" },
 /* 248 */
-  { RPL_STATSULINE, "%c %s %s %s %d %d", "248" },
+  { RPL_STATSULINE, "U %s", "248" },
 /* 249 */
   { RPL_STATSDEBUG, 0, "249" },
 /* 250 */
index 7d9269258d1010cc1e4851f89c8943d6b6de11f6..1da2bfdd3679ebbd1ba759e5ba0317c9ad198901 100644 (file)
@@ -140,7 +140,7 @@ int server_estab(struct Client *cptr, struct ConfItem *aconf)
     IPcheck_connect_fail(&cli_ip(cptr));
   }
 
-  det_confs_butmask(cptr, CONF_LEAF | CONF_HUB | CONF_SERVER | CONF_UWORLD);
+  det_confs_butmask(cptr, CONF_SERVER | CONF_UWORLD);
 
   if (!IsHandshake(cptr))
     hAddClient(cptr);
index a60cb3d90c837048eb128afbd02bd3665fea325e..0f9f5f4fd80532516b4531b00e5029e5be1c0148 100644 (file)
  *       it--not reversed as in ircd.conf!
  */
 
-/** Stats response to use for various ConfItem types. */
-static unsigned int report_array[][3] = {
-  {CONF_SERVER, RPL_STATSCLINE, 'C'},
-  {CONF_CLIENT, RPL_STATSILINE, 'I'},
-  {CONF_LEAF, RPL_STATSLLINE, 'L'},
-  {CONF_OPERATOR, RPL_STATSOLINE, 'O'},
-  {CONF_HUB, RPL_STATSHLINE, 'H'},
-  {CONF_UWORLD, RPL_STATSULINE, 'U'},
-  {0, 0}
-};
-
 /* The statsinfo array should only be used in this file, but just TRY
  * telling the compiler that you want to forward declare a static
  * array without specifying a length, and see how it responds.  So we
@@ -96,46 +85,27 @@ stats_configured_links(struct Client *sptr, const struct StatDesc* sd,
 {
   static char null[] = "<NULL>";
   struct ConfItem *tmp;
-  int mask;
-  unsigned int *p;
   unsigned short int port;
-  char c, *host, *pass, *name;
+  int maximum;
+  char *host, *pass, *name;
 
-  mask = sd->sd_funcdata;
-
-  for (tmp = GlobalConfList; tmp; tmp = tmp->next) 
+  for (tmp = GlobalConfList; tmp; tmp = tmp->next)
   {
-    if ((tmp->status & mask))
+    if ((tmp->status & sd->sd_funcdata))
     {
-      for (p = &report_array[0][0]; *p; p += 3)
-        if (*p == tmp->status)
-          break;
-      if (!*p)
-        continue;
-      c = (char)*(p + 2);
       host = BadPtr(tmp->host) ? null : tmp->host;
       pass = BadPtr(tmp->passwd) ? null : tmp->passwd;
       name = BadPtr(tmp->name) ? null : tmp->name;
+      maximum = tmp->maximum;
       port = tmp->address.port;
-      /*
-       * On K line the passwd contents can be
-       * displayed on STATS reply.    -Vesa
-       */
-      /* Special-case 'k' or 'K' lines as appropriate... -Kev */
-      if ((tmp->status & CONF_UWORLD))
-       send_reply(sptr, p[1], c, host, pass, name, port, get_conf_class(tmp));
-      else if ((tmp->status & (CONF_SERVER | CONF_HUB)))
-       send_reply(sptr, p[1], c, "*", name, port, get_conf_class(tmp));
-      else if ((tmp->status & CONF_CLIENT))
-      {
-       if(tmp->passwd && IsDigit(*tmp->passwd) && (!tmp->passwd[1] ||
-           (IsDigit(tmp->passwd[1]) && !tmp->passwd[2])))
-         send_reply(sptr, p[1], c, host, pass, name, port, get_conf_class(tmp));
-       else
-         send_reply(sptr, p[1], c, host, "*", name, port, get_conf_class(tmp));
-      }
-      else
-       send_reply(sptr, p[1], c, host, name, port, get_conf_class(tmp));
+      if (tmp->status & CONF_UWORLD)
+       send_reply(sptr, RPL_STATSULINE, name);
+      else if (tmp->status & CONF_SERVER)
+       send_reply(sptr, RPL_STATSCLINE, name, port, get_conf_class(tmp));
+      else if (tmp->status & CONF_CLIENT)
+        send_reply(sptr, RPL_STATSILINE, host, maximum, name, port, get_conf_class(tmp));
+      else if (tmp->status & CONF_OPERATOR)
+       send_reply(sptr, RPL_STATSOLINE, host, name, port, get_conf_class(tmp));
     }
   }
 }
@@ -544,9 +514,6 @@ struct StatDesc statsinfo[] = {
   { 'g', "glines", STAT_FLAG_OPERFEAT, FEAT_HIS_STATS_g,
     gline_stats, 0,
     "Global bans (G-lines)." },
-  { 'h', "hubs", STAT_FLAG_OPERFEAT, FEAT_HIS_STATS_h,
-    stats_configured_links, (CONF_HUB | CONF_LEAF),
-    "Hubs information." },
   { 'i', "access", (STAT_FLAG_OPERFEAT | STAT_FLAG_VARPARAM), FEAT_HIS_STATS_i,
     stats_access, CONF_CLIENT,
     "Connection authorization lines." },