return prot;
}
+/** Reason not to accept a server's new announcement. */
+enum lh_type {
+ ALLOWED, /**< The new server link is accepted. */
+ MAX_HOPS_EXCEEDED, /**< The path to the server is too long. */
+ NOT_ALLOWED_TO_HUB, /**< My peer is not allowed to hub for the server. */
+ I_AM_NOT_HUB /**< I have another active server link but not FEAT_HUB. */
+};
+
/** 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.
struct Client* acptr;
struct Client* LHcptr = NULL;
struct ConfItem* lhconf;
- int active_lh_line = 0, ii;
+ enum lh_type active_lh_line = ALLOWED;
+ int ii;
if (ghost)
*ghost = 0;
if (!feature_bool(FEAT_HUB))
for (ii = 0; ii <= HighestFd; ii++)
if (LocalClientArray[ii] && IsServer(LocalClientArray[ii])) {
- active_lh_line = 3;
+ active_lh_line = I_AM_NOT_HUB;
break;
}
}
else if (hop > lhconf->maximum)
{
- active_lh_line = 1;
+ /* Because "maximum" should be 0 for non-hub links, check whether
+ * there is a hub mask -- if not, complain that the server isn't
+ * allowed to hub.
+ */
+ active_lh_line = lhconf->hub_limit ? MAX_HOPS_EXCEEDED : NOT_ALLOWED_TO_HUB;
}
else if (lhconf->hub_limit && match(lhconf->hub_limit, host))
{
struct Client *ac3ptr;
- active_lh_line = 2;
+ active_lh_line = NOT_ALLOWED_TO_HUB;
if (junction)
for (ac3ptr = sptr; ac3ptr != &me; ac3ptr = cli_serv(ac3ptr)->up)
if (IsJunction(ac3ptr)) {
*/
if (IsConnecting(acptr))
{
- if (!active_lh_line && exit_client(cptr, acptr, &me,
+ if (active_lh_line == ALLOWED && exit_client(cptr, acptr, &me,
"Just connected via another link") == CPTR_KILLED)
return CPTR_KILLED;
/*
else if (cli_from(c2ptr) == cptr || IsServer(sptr))
{
struct Client *killedptrfrom = cli_from(c2ptr);
- if (active_lh_line)
+ if (active_lh_line != ALLOWED)
{
/*
* If the L: or H: line also gets rid of this link,
* line problem, we don't squit that.
*/
if (cli_from(c2ptr) == cptr || (LHcptr && a_kills_b_too(c2ptr, LHcptr)))
- active_lh_line = 0;
+ active_lh_line = ALLOWED;
else
{
/*
}
else
{
- if (active_lh_line)
+ if (active_lh_line != ALLOWED)
{
if (LHcptr && a_kills_b_too(LHcptr, acptr))
break;
if (cli_from(acptr) == cptr || (LHcptr && a_kills_b_too(acptr, LHcptr)))
- active_lh_line = 0;
+ active_lh_line = ALLOWED;
else
{
LHcptr = 0;
}
}
- if (active_lh_line)
+ if (active_lh_line != ALLOWED)
{
- int killed = 0;
- if (LHcptr)
- killed = a_kills_b_too(LHcptr, sptr);
- else
+ if (!LHcptr)
LHcptr = sptr;
- if (active_lh_line == 1)
+ if (active_lh_line == MAX_HOPS_EXCEEDED)
{
- if (exit_client_msg(cptr, LHcptr, &me,
- "Leaf-only link %s <- %s, check L:",
- cli_name(cptr), host) == CPTR_KILLED)
- return CPTR_KILLED;
+ return exit_client_msg(cptr, LHcptr, &me,
+ "Maximum hops exceeded for %s at %s",
+ cli_name(cptr), host);
}
- else if (active_lh_line == 2)
+ else if (active_lh_line == NOT_ALLOWED_TO_HUB)
{
- if (exit_client_msg(cptr, LHcptr, &me,
- "Non-Hub link %s <- %s, check H:",
- cli_name(cptr), host) == CPTR_KILLED)
- return CPTR_KILLED;
+ return exit_client_msg(cptr, LHcptr, &me,
+ "%s is not allowed to hub for %s",
+ cli_name(cptr), host);
}
- else
+ else /* I_AM_NOT_HUB */
{
ServerStats->is_ref++;
- if (exit_client(cptr, LHcptr, &me, "I'm a leaf, define HUB") == CPTR_KILLED)
- return CPTR_KILLED;
+ return exit_client(cptr, LHcptr, &me, "I'm a leaf, define the HUB feature");
}
- /*
- * Did we kill the incoming server off already ?
- */
- if (killed)
- return 0;
}
return 1;