\documentstyle[12pt,pocs-header]{article}
\Scribes{Uri Blank}
\Lecturer{Butler Lampson}
\LectureNumber{16}
\LectureDate{6 November 1991}
\begin{document}
\MakeScribeTop


\section{Handouts}
\begin{itemize}
\item Handout 33 Implementing Remote Procedure Call'' by Andrew
      Birrell and Bruce  J. Nelson
\item Handout 34 ``Performance of Firefly RPC'' by Michael D.
      Schroeder and Michael Burrows
\item Handout 35 - Solution to Problem Set 3.
\item Handout 36 ``Three-Way Handshake''
\end{itemize}

\section{Overview}
This lecture completes a discussion of the simple FIFO communication
channel and describes ``Three-way handshake'' protocol and a timer-based
protocol as examples of real network protocols.

\section{FIFO communication channel}
The idea of a connection is that after it is set up, there can be a
lot of information exchanged between network nodes.  A  nontrivial part of
a protocol is to make sure that information will be received before
the connection is terminated.  This requirement does not correspond to
the acknowledgement of an ``at-most-once message''.  Page 3 of handout
32 shows an at-most-once message delivery specification.

The spec says that there is a FIFO queue with two operations: Put and
Get. There are two complications. One is acknowledgements: the sender
wants to know if a message was delivered correctly.  In support of
this there is a acknowledgement operation -- the weakest possible. It
ACKs the last message the sender sent. If sender sends three messages
not waiting for ACKs, it will get an ACK for the most recent message,
but it will not know what happened to the second message (for
example).

The second complication is crashes.  The spec says if there is a
crash, then any subset of the messages in the queue may be dropped.
ACKs can be lost during the crash too.  For the lost ACK, Crash will
return ``false'', so that if an ACK is received it means the message
was delivered, if ACK is ``false'' then either the message was lost or
a crash occurred during the end-to-end delivery process.  An
expectation from a protocol would be the property that each message
sent is delivered for sure. That can be achieved by a significant
complication of an implementation; in particular, there must be a
state change to the stable state of the receiver {\em every time a message
is received}.  If there is no change to the stable
state, messages are delivered, and there is a crash, then the volatile
state will be lost and there will be no visible difference in the
state after the crash. So there will be no way to distinguish the case
when a message was delivered from the case when it was lost as a
result of the crash.  If the requirement is to deliver messages
``exactly once'', the receiver has to change the stable base, which
results in a severe performance degradation.

The simple-minded implementation of the spec assumes that all the
relevant states on both sides are in stable storage, so if there is a
failure it does not change the state.  In the implementation, it can
mean reading data from a disk or running some kind of recovery
protocol, but the state of the specification will not be changed.  In
these conditions no messages are lost.

Each message is tagged with an ID. The ID has to have the property
that the receiver knows that this is a new ID.  When sender picks the ID
it has to pick from the set of {\em good}\/ IDs. The sender notion of
a good ID is more conservative then the receiver's notion, because if
the sender picks an ID that the receiver does not think is good and
transmits it, the receiver may drop the message.  This will violate
the protocol, which says all the messages are supposed to be accepted.
The basic notion of the protocol is that sender keeps a current
variable c = (i,m) that consists of the id and the message, and it
retransmits it until it gets a positive ACK. 

The receiver sends a positive ACK even if the id is not in the good
set.  When there are no crashes, if the ID is not in a good set, it
must represent a message that has already been accepted.  Presumably
the previous ACK was lost and the current message is a retransmission.
(If an ACK is lost, the sender keeps retransmitting the message until
it gets a positive ACK.)  This protocol is very simple and is not used
in practice for networking. It is used in some message-queuing
systems.

\section{Protocols used for Networking}
There are two protocols discussed, the three-wayhandshake protocol
and the LSW timer-based protocol.

\subsection{Three-way handshake}
The implementation of the idea of a good set of IDs is subject to
certain constraints:

\begin{enumerate}
\item Negligible amount of stable-storage operations per message
      delivered. This means that there can be, for example, one
stable-storage operation per thousand delivered messages, not one
per message.

\item No state when idle. It is not acceptable to maintain states for
      all the nodes for which there have been sessions with in the
past. When a connection becomes idle, the sender and receiver can
throw away all session state information.

\item No synchronized clocks are needed.
\end{enumerate}

In the three-way handshake, the sender asks the receiver for a good
ID, because it is not allowed to keep any state. The sender's ID is
put in the request. Receiving this message more then one time will not
result in any damage, because the receiver is just suppose to allocate
another receiver ID if this happens. There can be performance
degradation if this happens too often, but it does not affect the
correctness.


In three-way handshake protocol receiver and sender are running in the
same state or perhaps the sender will be one step ahead. They both
start in the ``idle'' state; the sender goes to the ``need ID'' state,
which causes the receiver to enter the ``accepting'' state; the sender
enters the ``sending'' state, which pushes the receiver into the
``acking'' state; the
sender enters the ``idle'' state, which pushes the receiver into the
``idle'' state.

\begin{verbatim}      
   Put    Assign ID   Associate ID   Accept Msg   Accept ACK   Close
II --> NI --------> NA ----------> SA --------> SK --------> IK ---> II
\end{verbatim}

The possible transitions for crashes are discussed in the Three-Way
Handshake handout (Handout 36).

\subsection{Timer-based protocol}
Timer-based protocols use loosely synchronized clocks to provide the
identifiers for messages. There are two problems in providing
at-most-once delivery: the first is not to deliver a message twice, the
second is to deliver it if there is no crash. The protocol based on
clocks guarantees to deliver a message if there is no crash and the
clocks on the receiver and sender are not too far out of sync. The
receiver keeps track of LOWER, the biggest clock value for which it
has accepted a message: values bigger then LOWER are good. It also
keeps an UPPER bound on the biggest value of the message ID it will
accept, chosen to be larger then the receiver's clock plus the clock
skew.

  After the crash the receiver and sender have a current time that
gets incremented.  The fact that clocks are loosely synchronized can
be expressed as: $|T_r - T_s| <$ ``skew''.  After a crash the receiver
sets LOWER := UPPER; this ensures that no messages are accepted twice.
The sender clock advances, which ensures that he will get new
identifiers and also ensures he will eventually get past UPPER and
start sending messages that will be accepted. It is possible for the
receiver to advance LOWER spontaneously if it hasn't received a
message for a long time, as long as LOWER stays smaller than the
current time. This gives the receiver a chance to run several copies
of the implementation and make the values of LOWER the same for all of 
the idle senders. The receiver only needs to keep track a single LOWER
for all the idle senders, plus one for each active sender. So no
storage is needed for idle senders.

The sender can not send messages with the same ID, so if clocks are
ticking with certain period, only one message can be sent each tick.
To get around of this limitation, the ID space of messages can be
extended. The new ID would have time field extended by a counter that
is reset to zero with each new tick, and is incremented for each
message send.

\end{document}
