          Lazy Links As Implemented in Hybrid
	  ===================================

  First off, read the original LazyLinks.txt spec.

  The bit map idea was used to mark which channels a leaf "knows" about.
This limits the number of LL servers to a hub at 32 for now. This is
easily rewritten, though a little more code consuming.
  Each client needs a bit mask as well, to mark if that client is
known to the leaf or not.

Now from original LazyLinks spec:
LLL = Lazy Link Leaf.

"1.1) Joining

When a client on a LLL sends a "JOIN #channel", LLL does as usual: if it
has the channel locally, it just joins the user, sends an SJOIN to HUB,
and all is well; if it doesn't have the channel, it creates it, sends a
SJOIN to HUB with the current time as the TS.  LLL tells the user that it
has joined the channel, but it doesn't tell it that it has ops yet.  So
LLL sends..."

I modified this to:
When a client on a LLL sends a "JOIN #channel", LLL does as usual: if it
has the channel locally, it just joins the user, sends an SJOIN to HUB,
and all is well; if it doesn't have the channel it sends a CBURST 
request to HUB. The client is then in hiatus until the LLL receives
back a LLJOIN (lazy link join ) from the HUB.

[LLL -> HUB]     :LLL CBURST #channel <LLLuser|LLLuser key>

  The Lazy Link Leaf (LLL), tells the HUB, it wants a channel burst for
"#channel", with the LLLuser joining. The HUB will send
a channel burst back for the specified channel in either case. This
results in the leaf now knowing about the channel. This helps prevent
"chatter," as the LLLuser could be trying to repeatedly join a channel
they are banned on. It now becomes the LLL servers responsibility
as usual in the non LL case.

So the HUB then sends
[HUB -> LLL]     :HUB LLJOIN #channel LLLuser key

  The Lazy Link Leaf then tries to join that client to the given channel,
as it already has requested a CBURST from the HUB, it now has full
information on the channel on the leaf.

"1.2) Bursts

The beauty of this is that, with the rules above, channel bursts get
avoided, without the need to do anything more.

When LLL and HUB connect to each other, LLL sends a channel burst as
usual; HUB doesn't.  By the rules above, HUB will reply to each first
LLL's SJOIN for a channel with a SJOIN back with its own info.  So at the
end of the burst, LLL has been put up to date with all the channels it
needs to know about."

This has been modified to do: In a burst, the leaf sends back CBURST
for each channel it knows about requesting further information from the
hub for each channel. The hub then sends back SJOIN's for each client
missing on the leaf (known by the bit map) and SJOIN's the client to
the channel.

"1.3) Parts, Kicks and Modes

When one of LLL's clients (say, LLLuser) leaves a channel, or is kicked
out of it, LLL needs to check if that was the last of its clients for
that channel.  

If that is the case, then LLL needs to inform HUB that it no longer holds
#channel, and destroy its local information about #channel:

	[LLL -> HUB]   :LLL DROP #channel


Upon receiving a "DROP" command from a Lazy Leaf, the Hub just clears
the Lazy Leaf's bit on that channel.

Alternatively, a Lazy Leaf could decide to cache channels even without
having any clients on them.  All it has to do is not send the "DROP"
command to its hub."

  In this implementation, the local channel is cached on LLL, with 
a timer running to clear out old local channels. After a configurable
number of seconds, any channel that has no local users on it is removed
locally, and the "DROP" is sent to the HUB. This again, helps prevent
channel "chatter." As it could be a local client trying to repeatedly
join a channel it is not wanted on. This stops a new CBURST being sent
for each non wanted join.


"2) Nicks

Nicks are simpler, because they are atomic, there is no list associated
with them."


- Diane Bruce <db@db.net>