From 87adb627f71f9157a179c5f0c2f59a8e0ef8db1c Mon Sep 17 00:00:00 2001 From: Michael Poole Date: Tue, 12 Oct 2004 18:24:13 +0000 Subject: [PATCH] Get rid of CONF_LEAF and CONF_HUB, and follow up with code cleanups. git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/trunk@1240 c9e4aea6-c8fd-4c43-8297-357d70d61c8c --- ChangeLog | 38 ++++++++ doc/example.conf | 76 ++++++---------- include/list.h | 2 +- include/s_conf.h | 25 +++--- ircd/ircd_lexer.l | 1 + ircd/ircd_parser.y | 217 +++++++++++++++++++-------------------------- ircd/m_server.c | 156 ++++++++++++++------------------ ircd/s_conf.c | 21 +++-- ircd/s_err.c | 14 +-- ircd/s_serv.c | 2 +- ircd/s_stats.c | 59 +++--------- 11 files changed, 265 insertions(+), 346 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5ccf170..38ef8ce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,41 @@ +2004-10-12 Michael Poole + + * 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 * ircd/m_burst.c: Mask off channel modes in a wiped-out channel by diff --git a/doc/example.conf b/doc/example.conf index e507392..95b37da 100644 --- a/doc/example.conf +++ b/doc/example.conf @@ -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] diff --git a/include/list.h b/include/list.h index 1e69ae9..a400ee2 100644 --- a/include/list.h +++ b/include/list.h @@ -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); diff --git a/include/s_conf.h b/include/s_conf.h index 3d48e8c..066e9da 100644 --- a/include/s_conf.h +++ b/include/s_conf.h @@ -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; }; diff --git a/ircd/ircd_lexer.l b/ircd/ircd_lexer.l index 458e571..2dd3e76 100644 --- a/ircd/ircd_lexer.l +++ b/ircd/ircd_lexer.l @@ -46,6 +46,7 @@ static struct lexer_token { TOKEN(CONNECT), TOKEN(CONNECTFREQ), TOKEN(MAXLINKS), + TOKEN(MAXHOPS), TOKEN(SENDQ), TOKEN(NAME), TOKEN(HOST), diff --git a/ircd/ircd_parser.y b/ircd/ircd_parser.y index ef910fb..9f10200 100644 --- a/ircd/ircd_parser.y +++ b/ircd/ircd_parser.y @@ -65,16 +65,13 @@ 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 diff --git a/ircd/m_server.c b/ircd/m_server.c index f433c3d..d092fa4 100644 --- a/ircd/m_server.c +++ b/ircd/m_server.c @@ -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; diff --git a/ircd/s_conf.c b/ircd/s_conf.c index ff2863c..43c3828 100644 --- a/ircd/s_conf.c +++ b/ircd/s_conf.c @@ -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)); diff --git a/ircd/s_err.c b/ircd/s_err.c index 23137fd..ace8093 100644 --- a/ircd/s_err.c +++ b/ircd/s_err.c @@ -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 */ diff --git a/ircd/s_serv.c b/ircd/s_serv.c index 7d92692..1da2bfd 100644 --- a/ircd/s_serv.c +++ b/ircd/s_serv.c @@ -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); diff --git a/ircd/s_stats.c b/ircd/s_stats.c index a60cb3d..0f9f5f4 100644 --- a/ircd/s_stats.c +++ b/ircd/s_stats.c @@ -66,17 +66,6 @@ * 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[] = ""; 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." }, -- 2.20.1