Subject: Yet more onc() woes...

From: Andrew Wilson <[email-masked]>
Date: Sun, 26 Sep 1993 04:23:11 -0700

Ok, here's the problem:

              +------------+                   +-----------+
              |            |                   |           |
              | CardiffMOO |<----------------->| LambdaMOO |
              |            |                   |           |
              +------------+                   +-----------+

a)  CardiffMOO opens an onc() to LambdaMOO, connects to the player
    CardiffMOO@LambdaMOO and waits for an ACK which is read() back
    from the connection.

b)  CardiffMOO@LambdaMOO:confunc is triggered and sends back the ACK,
    in order to ensure that the NEXT thing it sends will get to CardiffMOO's
    server rather than to the read()ing code which set up the connection
    in a.

c)  The next thing LambdaMOO sends is a string of the form
    'connect LambdaMOO <somepwd>', which CardiffMOO's server sees and processes
    as for an ordinary player's login.

d)  So you end up with a Link player logged in on both ends of the same onc()
    The players are back-to-back, what one 'types' the other 'says' etc.  And
    that's basically how MOO-net gets to communicate between MOOs. [yawn]

The hassle starts when (for some reason I'm not sure about), CardiffMOO
momentarily looses its side of the onc().  The CardiffMOO server thinks that
the link to LambdaMOO has been dropped (it goes as far as calling the :disfunc
on the CardiffMOO side of the connection) and then automatically attempts to
reestablish the connection by doing the whole a-d sequence detailed above.

Now normally this is an ok thing to do.  Let's say LambdaMOO crashes or
gets a brown-out or something.  In that case LambdaMOO's server would also
have lost its hold on the connection and CardiffMOO's attempts to reestablish
the link would meet with success when LambdaMOO came back 'on-line'.

BUT, there are instances when LambdaMOO's server doesn't detect the dropped
connection.  As far as it is concerned, CardiffMOO is still there (albeit
rather quiet).  In this case, when CardiffMOO attempts a reconnection it
connects to a player, CardiffMOO@LambdaMOO which is STILL logged in and viable
as far as the LambdaMOO server is concerned.  So LambdaMOO's server does a:

	*** Redirecting old connection to this port ***

fails to call CardiffMOO@LambdaMOO:confunc, and so the whole a-d thing falls
flat on its face.  ie. LambdaMOO never tries to connect BACK to CardiffMOO
to fix both ends of the onc().  And, as you might imagine, under these
circumstances MOO-net breaks.

So, some questions:

1)  Anyone have any idea why a broken onc() on CardiffMOO's side is not
    reflected by a break in the connection on LambdaMOO's side.

2)  Any Astro-VR Jupiter types with a better way of maintaining onc()
    connections between MOOs wanna let me in on the secret.

[There are some EXTREMELY cludgey work-arounds to this problem, but I'd like
things to be simple if possible.  Really its down to, how come LambdaMOO
didn't see CardiffMOO drop?  Spooky.]

Andyworker.

---

From: David Van Buren <[email-masked]>
Date: Sun, 26 Sep 1993 09:41:09 -0700

> Ok, here's the problem:
     [see a previous post from Andrew Wilson for the problem]

If your "client" never sends a disconnect message to the moo how will
it ever know you disconnected?  The server just waits for input and
processes it, it doesn't go hunting for it.  If you have warning a
disconnect is going to happen you should send a messge to the other
moo so it can disconnect you gracefully.  The problem is that when you
kill, for example, a telnet connection it does that for you.  But onc
connections between moos don't, unless its a normal shutdown.

Here's what you can do.  Maintain a random number that both sides
agree is the "connection number".  This number is generated by the
"client" end whenever it starts a new connection and is set to zero
upon normal disconnects on the "server" end.  The "server" end can
tell the "client" what it thinks this number is.  If they are non-zero
and disagree a funky disconnect happened.  Just disconnect gracefully,
reconnect and synchronize the connection numbers.  If you are really
worried, you can test every now and then to see if the connection has
maintained integrity.

But what is really the problem if confunc() isn't run?  You will still
have the context of your last connection.  This last question merely
displays my ignorance of the details of your moonet code.  It would be
nice to see in more detail how it all works.

For example, I had the horrible idea a few weeks ago to make a client
that was just another moo.  Then you could program the client end in
moo-code too.  It would work like this: connect to your client moo, it
then connects to lambda (or whatevermoo).  I tried it and it works, if
you're willing to have a whole moo sitting in your computer doing
mostly nothing.  Obviosly, the problem you are having would occur here
too.  Anyone interested in this idea should grep back a month or so to
find the messages about 'stalk', a very interesting client with a
moo-like programming language.

Cheers - DVB

---

From: Pavel Curtis <[email-masked]>
Date: Sun, 26 Sep 1993 11:40:38 -0700

>     reflected by a break in the connection on LambdaMOO's side.

This is a fundamental property of the network itself.  TCP connection closure
is, inherently, unreliable; the packets attempting an orderly connection
shutdown can simply be lost in the ether and the other end will have no way of
knowing that the connection is dead, other than waiting for a timeout on the
receipt of a packet acknowledgement.  These timeouts are commonly on the scale
of several minutes, though.  Note that this issue is resolved well below the
level of the LambdaMOO server code, in the operating system.

>     connections between MOOs wanna let me in on the secret.

We don't do any MOO/MOO connections in any of our current work, so we don't
have any experience to offer you.

One workaround that comes to mind is to look for the `*** Redirecting ...'
message when you reconnect to a peer and, if found, shut down the connection
and try again.  Each time you repeat, there's a good chance of the normal,
orderly shutdown proceeding according to naive expectation.

Of course, another big help would be for the server to let the MOO-code know
when a redirect happens, analogously to the current :confunc/:disfunc
mechanisms.  Look for something along these lines in release 1.8.0 (don't ask).

	Pavel

---

From: Ron Frederick <[email-masked]>
Date: Mon, 27 Sep 1993 12:03:55 -0700

> BUT, there are instances when LambdaMOO's server doesn't detect the
> dropped connection.  As far as it is concerned, CardiffMOO is still there
> (albeit rather quiet).  In this case, when CardiffMOO attempts a
> reconnection it connects to a player, CardiffMOO@LambdaMOO
> which is STILL logged in and viable as far as the LambdaMOO server is
> concerned.  So LambdaMOO's server does a:
>

At the very least, there's a race condition here. If CardiffMOO does this
reconnect as _soon_ as it executes the :disfunc that goes along with the
TCP connection shutdown, there's some chance that LambdaMOO has
simply been busy and hasn't had a chance to shut down its side of the
connection yet.

Since the problem here appears to be that :confunc isn't run in the
redirect case, why not just avoid using it? Have CardiffMOO not only
send the "connect LambdaMOO ****" down the network connection, but
also a second line of "init_moonet" or something similar which is a verb
on the LambdaMOO player which runs the stuff currently being run out
of :confunc.

The advantage to this approach is that the verb will be run both in the
normal case and in the case where you are redirected. If the verb is
written such that it resets things back to the state where you're just
doing the initial handshake, things should work great.
--
Ron Frederick
[email-masked]