On Wed, Oct 19, 2005 at 10:27:19AM +1300, Andrew Miller wrote:
>     if ((chptr = FindChannel(name)))
>     {
>       /* Is the remote server confused? */
>       if (find_member_link(chptr, sptr)) {
>         protocol_violation(sptr, "%s tried to CREATE a channel already
> joined", cli_name(sptr));
>         continue;
>       }

This code looks incorrect.  The test for find_member_link
attempts to seems to try to check if a JOIN was received
already for this same user.  Thanks to the numeric prefixes
of CREATE and JOIN you can conclude that if that find_member_link
returns a non-zero value then a JOIN was received with the
same prefix from the same direction (server) as the CREATE
is received. Namely, at the moment the JOIN is received,
it would only add a member_link if the prefix is found and
corresponding to the direction that that user belongs to.
In turn a CREATE with the same prefix from another direction
would either be stopped, or the previous user (and therefore
all it's memberships) was destructed. I cannot believe that
part is broken.

Therefore we can assume that both, the previous JOIN and this
CREATE are received from the same direction. Apparently
the above code is in all servers that walloped (2.10.12.0?)
connected by HUB(s) of an older version that just pass on
JOIN and CREATE regardless. The error must therefore be in
the server of the user in question. The only way that can
happen is when that same server already sent out a message
removing this same user from the channel (either generated
itself, or as a result of a KICK or KILL received from other
servers behind it). Lets assume that it wasn't a KILL.
Then this message either a KICK or a PART (otherwise the prefix
changes). Then the only way the above protocol violation can
happen is when either the KICK or PART did not propagate,
while the CREATE did. Imho, a PART only stops propagating
when the user really left the channel, in which case the CREATE
wouldn't have caused the wallops.

Hence, this must have been a KICK. A KICK doesn't propagate
when the member who is being kicked already left the channel
as a result of an upstream message; in other words: another KICK
(upstream kicks don't remove members, just flag them as zombies).

Thus:

serverA---a CREATE---a KICK a---a KICK b-->-<--b KICK a---serverB

For example, when 'a' gets ops, kicks the whole channel and
cycles, while as a result of the kick flood is kicked himself
(but too late to finish his full channel kick).

The solution seems therefore to NOT wallops this 'protocol violation'
in the case the user is a zombie: that is not always a protocol violation.

I'd suggest the change code into:

    /* Is the remote server confused? */
    struct Membership* member;
    if ((member = find_member_link(chptr, sptr)) && !IsZombie(member)) {
      protocol_violation(sptr, "%s tried to CREATE a channel already joined", 
cli_name(sptr));


Regards,
Run

--
Carlo Wood <[EMAIL PROTECTED]>
_______________________________________________
Coder-com mailing list
Coder-com@undernet.org
http://undernet.sbg.org/mailman/listinfo/coder-com

Reply via email to