The following diff avoids the infinite recursion reported at https://sourceforge.net/tracker/?func=detail&aid=2793176&group_id=63470&atid=504080
I didn't write the original logic, and I'm not sure what the ideal behavior is, so I'm passing this patch along for review (instead of committing it immediately). Any constructive comments are appreciated. Entrope Index: ChangeLog =================================================================== --- ChangeLog (revision 1917) +++ ChangeLog (working copy) @@ -1,5 +1,17 @@ 2009-07-05 Michael Poole <[email protected]> + * include/s_serv.h (a_kills_b_too): Undeclare here. + + * ircd/s_serv.c (a_kills_b_too): Delete. + + * ircd/m_server.c (a_kills_b_too): Copy to here instead. + (check_loop_and_lh): Kill the server that violates its MaxLinks + rule, rather than the newly linked server that causes it to do so. + (As shown in bug #2793176, killing the remote server caused + infinite recursion in exit_downlinks().) + +2009-07-05 Michael Poole <[email protected]> + * ircd/m_gline.c (ms_gline): Fix the sense of the test for strtoul() when parsing G-line lifetimes -- zero indicates failure. Index: ircd/m_server.c =================================================================== --- ircd/m_server.c (revision 1917) +++ ircd/m_server.c (working copy) @@ -96,6 +96,19 @@ return prot; } +/** Indicate whether \a a is between \a b and #me (that is, \a b would + * be killed if \a a squits). + * + * @param a A server that may be between us and \a b. + * @param b A client that may be on the far side of \a a. + * @return Non-zero if \a a is between \a b and #me. + */ +static int a_kills_b_too(struct Client *a, struct Client *b) +{ + for (; b != a && b != &me; b = cli_serv(b)->up); + return (a == b ? 1 : 0); +} + /** Check whether the introduction of a new server would cause a loop * or be disallowed by leaf and hub configuration directives. * @param[in] cptr Neighbor who sent the message. @@ -137,6 +150,7 @@ else if (hop > lhconf->maximum) { active_lh_line = 1; + LHcptr = cptr; } else if (lhconf->hub_limit && match(lhconf->hub_limit, host)) { @@ -407,14 +421,14 @@ if (active_lh_line == 1) { if (exit_client_msg(cptr, LHcptr, &me, - "Leaf-only link %s <- %s, check L:", + "Too many hops at %s <- %s, check MaxLinks and Leaf", 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:", + "Non-Hub link %s <- %s, check Hub mask", cli_name(cptr), host) == CPTR_KILLED) return CPTR_KILLED; } Index: ircd/s_serv.c =================================================================== --- ircd/s_serv.c (revision 1917) +++ ircd/s_serv.c (working copy) @@ -94,18 +94,6 @@ return retval; } -/** Indicate whether \a a is between \a b and #me (that is, \a b would - * be killed if \a a squits). - * @param a A server that may be between us and \a b. - * @param b A client that may be on the far side of \a a. - * @return Non-zero if \a a is between \a b and #me. - */ -int a_kills_b_too(struct Client *a, struct Client *b) -{ - for (; b != a && b != &me; b = cli_serv(b)->up); - return (a == b ? 1 : 0); -} - /** Handle a connection that has sent a valid PASS and SERVER. * @param cptr New peer server. * @param aconf Connect block for \a cptr. Index: include/s_serv.h =================================================================== --- include/s_serv.h (revision 1917) +++ include/s_serv.h (working copy) @@ -20,7 +20,6 @@ */ extern int exit_new_server(struct Client* cptr, struct Client* sptr, const char* host, time_t timestamp, const char* fmt, ...); -extern int a_kills_b_too(struct Client *a, struct Client *b); extern int server_estab(struct Client *cptr, struct ConfItem *aconf); _______________________________________________ Patches mailing list [email protected] http://undernet.sbg.org/mailman/listinfo/patches
