\section{{\it x}-kernel}

% -----------------------------------------------------------------
\begin{slide}{}

   \subsection{Overview}

   \begin{sitem}
      \item Framework for Implementing Network Protocols
      \item Hides OS/Architecture-Specific Details
      \item Defines Network-Centric Abstractions (Interfaces)
      \begin{sitem}
         \item uniform protocol interface
         \item useful library routines
         \end{sitem}
      \item Implemented in C (not C++)
   \end{sitem}
\end{slide}

% -----------------------------------------------------------------
\begin{slide}{}

   \subsection{Protocol Objects}

   \pichere{prot_graph.eps,height=3in}

    \begin{verbatim}
    name=lance;
    name=eth protocols=lance;
    name=arp protocols=eth;
    name=ip protocols=eth,arp;
    name=icmp protocols=ip;
    name=udp protocols=ip;
    name=tcp protocols=ip;
    \end{verbatim}
\end{slide}

% -----------------------------------------------------------------
\begin{slide}{}

   \subsection{Operations on Protocol Objects}

   \begin{sitem}
      \item Active Open
      \begin{verbatim}
      Sessn xOpen(Protl hlp, 
                  Protl llp, 
                  Part *participants)
      \end{verbatim}

      \item Passive Open
      \begin{verbatim}
      XkReturn xOpenEnable(Protl hlp, 
                           Protl llp, 
                           Part *participant)

      XkReturn xOpenDone(Protl hlp, 
                         Protl llp,
                         Sessn session, 
                         Part *participants)
      \end{verbatim}

      \item Demultiplexing
      \begin{verbatim}
      XkReturn xDemux(Protl hlp, 
                      Sessn lls, 
                      Msg *message)
      \end{verbatim}
   \end{sitem}
\end{slide}

% -----------------------------------------------------------------
\begin{slide}{}

   \subsection{Session Objects}

   \begin{sitem}
      \item Local end-point of a channel
      \item Interpret messages and maintain channel state
      \item Export operations for sending and receiving messages
   \end{sitem}

   \bigskip
   Operations

   \begin{sitem}
      \item Send a Message
      \begin{verbatim}
      XkReturn xPush(Sessn lls, 
                     Msg *message)

      \end{verbatim}

      \item Deliver a Message
      \begin{verbatim}
      XkReturn xPop(Sessn hls, 
                    Sessn lls, 
                    Msg *message, 
                    void *hdr)
     \end{verbatim}
   \end{sitem}
\end{slide}

% -----------------------------------------------------------------
\begin{slide}{}

   \subsection{Relationship Between Protocols and Sessions}

   \pichere{protl_sessn.eps,height=4in}
\end{slide}

% -----------------------------------------------------------------
\begin{slide}{}

   \subsection{Process Model}

   \pichere{process.eps,height=4in}

   Synchronization Primitives

   \begin{verbatim}
   void semInit(Semaphore *s, int count)
   void semSignal(Semaphore *s)
   void semWait(Semaphore *s)
   \end{verbatim} 
\end{slide}

% -----------------------------------------------------------------
\begin{slide}{}

   \subsection{Message Library}

   \begin{sitem}
      \item Add a header to the front of a message
 
      \pichere{push.eps,height=2.5in}

      \item Strip a header from the front of a message
  
      \pichere{pop.eps,height=2.5in}

   \end{sitem}
\end{slide}

% -----------------------------------------------------------------
\begin{slide}{}

   \begin{sitem}
      \item Fragment a message into two messages

      \pichere{break.eps,height=3in}

      \item Reassemble two messages into one message

      \pichere{join.eps,height=3in}

   \end{sitem}
\end{slide}

% -----------------------------------------------------------------
\begin{slide}{}

   \begin{sitem}
      \item Other Operations

      \begin{verbatim}
      void msgConstructEmpty(Msg *message)

      void msgConstructBuffer(Msg *message, 
                              char *buffer, 
                              int length)

      char *msgConstructAllocate(Msg *message, 
                                 int length)

      void msgAssign(Msg *message_1, 
                     Msg *message_2)

      int msgLength(Msg *message)
      \end{verbatim}
   \end{sitem}
\end{slide}

% -----------------------------------------------------------------
\begin{slide}{}

   \begin{sitem}
      \item Implementation

      \pichere{dag.eps,height=3in}

      \noindent Key: Avoid copying packet data from one buffer to another.

      \item Traversing Message Data Structure

      \begin{verbatim}
      void msgWalkInit(MsgWalk *cxt, 
                       Msg *message)

      char *msgWalkNext(MsgWalk *cxt, 
                        int *len)

      void msgWalkDone(MsgWalk *cxt)
      \end{verbatim}
   \end{sitem}
\end{slide}

% -----------------------------------------------------------------
\begin{slide}{}

   \subsection{Event Library}

   \begin{sitem}
      \item Scheduling Timeouts

      \begin{verbatim}
      Event evSchedule(EvFunc function, 
                       void *argument, 
                       int time)

      EvCancelReturn evCancel(Event event)
      \end{verbatim}

      \item Implementation
      \begin{sitem}
         \item delta list
         \pichere{delta.eps,height=0.5in}

         \item insert event at time 14
         \pichere{delta2.eps,height=1in}
      \end{sitem}
   \end{sitem}
\end{slide}

% -----------------------------------------------------------------
\begin{slide}{}

   \subsection{Map Library}

   \begin{sitem}
      \item Demultiplexing Packets

      \begin{verbatim}
      Map mapCreate(int number, 
                    int size)

      Binding mapBind(Map map, 
                      void *key, 
                      void *id)

      XkReturn mapResolve(Map map, 
                          void *key, 
                          void **id)
      \end{verbatim}

      \item Usage
      \begin{sitem}
         \item one map to remember active opens (active map)
         \item one map to remember passive opens (passive map)
      \end{sitem}

      \item Implementation
      \begin{sitem}
         \item hash table
         \item specialized code based on key size
         \item one-element cache
      \end{sitem}
   \end{sitem}
\end{slide}

% -----------------------------------------------------------------
\begin{slide}{}

   \subsection{Example}

\begin{verbatim}
static Sessn
aspOpen(Protl self, Protl hlp, Part *p)
{
    Sessn       asp_s;
    Sessn       lls;
    ActiveId    key;
    ProtlState  *pstate = (ProtlState *)self->state;
  
    bzero((char *)&key, sizeof(key));

    /* High level protocol must specify both */
    /* local and remote ASP port */
    key.localport = *((AspPort *) partPop(p[0]));
    key.remoteport = *((AspPort *) partPop(p[1]));

    /* Assume failure until proven otherwise */
    asp_s = XK_FAILURE;	
\end{verbatim}
\end{slide}

% -----------------------------------------------------------------
\begin{slide}{}

\begin{verbatim}
    /* Open session on low-level protocol */
    lls = xOpen(self, xGetDown(self, 0), p);
    if ( lls != XK_FAILURE ) 
    {
        key.lls = lls;
        /* Check for session in active map */
        if (mapResolve(pstate->activemap, &key, 
            (void **)&asp_s) == XK_FAILURE) 
        {
    	    /* Session not in map; initialize it */
            asp_s = asp_init_sessn(self, hlp, &key);
            if ( asp_s != XK_FAILURE ) 
            {
                /* A successful open */
                return asp_s;
            } 
        } 

        /* Error has occurred */
        xClose(lls);
    }
    return asp_s;
}
\end{verbatim}
\end{slide}

% -----------------------------------------------------------------
\begin{slide}{}

\begin{verbatim}
static XkReturn
aspPush(Sessn s, Msg *msg)
{
    SessnState *sstate;
    AspHdr     hdr;
    void       *buf;
    
    /* create a header */
    sstate = (SessnState *) s->state;
    hdr = sstate->hdr;
    hdr.ulen = msgLen(msg) + HLEN;
      
    /* attach header and send */
    buf = msgPush(msg, HLEN);
    aspHdrStore(&hdr, buf, HLEN, msg);
    return xPush(xGetDown(s, 0), msg);
}
\end{verbatim}
\end{slide}

% -----------------------------------------------------------------
\begin{slide}{}

\begin{verbatim}
static XkReturn
aspDemux(Protl self, Sessn lls, Msg *msg)
{
    AspHdr       h;
    Sessn        s;
    ActiveId     activeid;
    PassiveId    passiveid;
    ProtlState   *pstate;
    Enable       *e;
    void         *buf;
    
    pstate = (ProtlState *)self->state;
    
    /* extract the header from the message */
    buf = msgPop(msg, HLEN);
    aspHdrLoad(&h, buf, HLEN, msg);
    
    /* construct a demux key from the header */
    bzero((char *)&activeid, sizeof(activeid));
    activeid.localport = h.dport;
    activeid.remoteport = h.sport;
    activeid.lls = lls;
\end{verbatim}
\end{slide}

% -----------------------------------------------------------------
\begin{slide}{}

\begin{verbatim}
    /* see if demux key is in the active map */
    if (mapResolve(pstate->activemap, &activeid, 
        (void **)&s) == XK_FAILURE)
    {
        /* didn't find an active session, */
        /* so check passive map */
        passiveid = h.dport;
        if (mapResolve(pstate->passivemap, &passiveid, 
            (void **)&e) == XK_FAILURE)
        {
            /* drop the message */
            return XK_SUCCESS;
        }
  
        /* port was enabled, so create a new */
        /* session and inform hlp */
        s = asp_init_sessn(self, e->hlp, &activeid);
        xOpenDone(e->hlp, s, self);
    } 
    /* pop the message to the session */
    return xPop(s, lls, msg, &h);
}
\end{verbatim}
\end{slide}

% -----------------------------------------------------------------
\begin{slide}{}

\begin{verbatim}
static XkReturn
aspPop(Sessn s, Sessn ds, Msg *msg, void *inHdr)
{
    AspHdr    *h = (AspHdr *) inHdr;
  
    /* truncate message to length shown in header */
    if ((h->ulen - HLEN) < msgLen(msg)) 
        msgTruncate(msg, (int) h->ulen);

    /* pass message up the protocol stack */
    return xDemux(xGetUp(s), s, msg);
}
\end{verbatim}

\end{slide}