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