home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 14 Text / 14-Text.zip / machdocs.zip / netmsg1 < prev    next >
Internet Message Format  |  1993-02-26  |  65KB

  1. From Pa.dec.com!nobody Thu Feb 25 20:15:40 1993
  2. Return-Path: <Pa.dec.com!nobody>
  3. Received: by ukelele.GCR.COM (Smail3.1.28.1 #1)
  4.     id m0nRtfv-0001S0a; Thu, 25 Feb 93 20:15 EST
  5. Received: from inet-gw-2.pa.dec.com by uu5.psi.com (5.65b/4.0.071791-PSI/PSINet) via SMTP;
  6.         id AA01580 for spj@ukelele.GCR.COM; Thu, 25 Feb 93 19:09:28 -0500
  7. Received: by inet-gw-2.pa.dec.com; id AA28431; Thu, 25 Feb 93 16:09:32 -0800
  8. Date: Thu, 25 Feb 93 16:09:32 -0800
  9. Message-Id: <9302260009.AA28431@inet-gw-2.pa.dec.com>
  10. From: "ftpmail service on inet-gw-2.pa.dec.com" <nobody@Pa.dec.com>
  11. To: spj@ukelele.GCR.COM
  12. Subject: part 001 of /.0/Mach/doc/netmsgserver.doc (@gatekeeper.dec.com) [Mach Dox] (ascii)
  13. X-Complaints-To: ftpmail-admin@inet-gw-2.pa.dec.com
  14. X-Service-Address: ftpmail@inet-gw-2.pa.dec.com
  15. X-Job-Number: 730680718.24209
  16. Precedence: bulk
  17. Reply-To: <nobody@inet-gw-2.pa.dec.com>
  18. Content-Type: text
  19. Content-Length: 64070
  20. Status: O
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.                Network  Server  Design
  29.  
  30.  
  31.  
  32.                MACH  Networking  Group
  33.  
  34.  
  35.  
  36.              September  21,  1989
  37.  
  38.  
  39.  
  40. 1.   Introduction
  41.  
  42.  
  43.  
  44. The network server is responsible for extending the local MACH
  45. Inter-Process Communication abstraction over the network which
  46. interconnects MACH hosts.  We have designed and implemented a new
  47. version of the network server in a way in which we hope makes it more
  48. efficient, easier to understand, more modular and easier to extend.
  49. In particular we intend to use this new network server to experiment
  50. with various ideas in the area of distributed systems networking, such
  51. as:
  52.  
  53.  
  54.     o     evaluating the merits of various protocols for network
  55.     interprocess communication ---  in  particular, we want to examine:
  56.  
  57.           -  connection-oriented  versus  connectionless  protocols,
  58.  
  59.           -  request-response  protocols  for  remote  procedure  calls,  and
  60.  
  61.       -  the use of special-purpose protocols depending on the size or the
  62.              destination of
  63.              the  data  to  be  transported;
  64.  
  65.     o evaluating various models for the distribution of network
  66.       functions between the operating system kernel and user
  67.       processes, and how these two components should interact;
  68.  
  69.     o security  in  the  network  environment;
  70.  
  71.     o multicast  groups,  and  associated  delivery  problems;  and
  72.  
  73.     o copy-on-reference  operations  over  a  network.
  74.  
  75.  
  76. This document describes the design of the network server and details
  77. the interfaces to the modules that are used to implement it.  It is
  78. intended for implementers rather than users.  This document reflects
  79. the current state of the implementation, and does not constitute a
  80. commitment for future developments.
  81.  
  82.  
  83. In the next section the overall design of the network server is
  84. explained.  The subsequent sections describe the structure of
  85. individual modules.
  86.  
  87.  
  88.  
  89. 2.   Overall Structure
  90.  
  91.  
  92.  
  93. 2.1.   General Operation
  94.  
  95.  
  96.  
  97. The set of all network servers on a network cooperate to provide IPC
  98. (Inter-Process Communication) between processes on different hosts on
  99. that network.  They achieve that
  100.  
  101.  
  102.                   1
  103.  
  104.  
  105. cooperation by exchanging Network Server Messages.  Some of these
  106. messages contain the data of IPC messages that are to be transported
  107. across the network, while others are used by the network servers to
  108. communicate information about the status of the operations in
  109. progress, and to maintain a consistent view of the location of the
  110. ports used in the network environment.  A small dispatcher header is
  111. used to distinguish between these various network server messages.
  112.  
  113.  
  114. The network servers maintain a space of Network Ports and each network
  115. server maintains a mapping between ports local to its host and network
  116. ports.  Each network port is represented by a Network Port Identifier
  117. which contains information to locate the receiver and owner for the
  118. network port and information which allows the security of the Mach
  119. port abstraction to be maintained in the network environment.  (See
  120. [2] for further details.)
  121.  
  122.  
  123.  
  124. 2.2.   Control Structure
  125.  
  126.  
  127.  
  128. The server is structured as a collection of threads sharing the same
  129. address space.  Each thread is used to perform one specific task
  130. asynchronously with the other threads.  Typically, there is one thread
  131. for each ``wait point'' in the system.  Wait points are most often
  132. waits for IPC messages.  The thread is awakened whenever something
  133. happens at this wait point, performs all operations pertinent to the
  134. current event, and goes back to sleep.  Should the service of an event
  135. require a further wait, another thread is signalled and asked to
  136. continue operations after that wait.  In general, one thread should
  137. not have more than one wait point.  Appropriate locking facilities are
  138. used where threads must share access to data structures.  There are a
  139. fixed number of threads in the system:
  140.  
  141.  
  142.  
  143. Timer    Used by all the other threads whenever they need to schedule
  144.     some action to take place at some given time in the future.
  145.     The most common use of this facility is to schedule packet
  146.     retransmission.
  147.  
  148. IPC Send Waits for messages to arrive on any of the ports that are
  149.     local representatives of remote network ports.  Upon reception
  150.     of such a message, performs the necessary translations and
  151.         initiates transmission on the network.  This thread does not wait
  152.         for the transmission to complete; subsequent actions will be
  153.     taken by the timer thread or by a transport receive thread.
  154.  
  155. IPC Re-Send is awakened when some other thread or some external
  156.     condition indicates that a message previously handled by the
  157.     IPC send thread should be re-sent either to the original or to
  158.         another destination.  It essentially performs the same
  159.     functions as the IPC send thread, but might take advantage of
  160.         some work already done by the ormer.  This thread is called
  161.     into action when a port is not found at the expected location,
  162.     when a remote port is blocked, or when network errors occur.
  163.  
  164. Transport Receive (One or more per each transport protocol.)  Waits
  165.     for packets to arrive from the network interface.  Processes
  166.     these packets, perhaps assembling multiple packets into
  167.     contiguous data and perhaps matching incoming packets with
  168.     previously queued outgoing transmissions.  Passes IPC and
  169.     other network server data received from remote network servers
  170.     on to higher level modules for further processing.  As
  171.         suggested above, this thread may use the services of the timer
  172.     thread to schedule retransmissions of packets and to determine
  173.     when a transmission should be aborted.
  174.  
  175. Notify Messages Waits for notify messages from the kernel to arrive on
  176.     the server's notify port.  These messages indicate changes in
  177.     the status of local ports (death, movements of rights or local
  178.     IPC message accepted).  Takes appropriate action in
  179.     each case to update the server's records and may destroy a
  180.     port, transfer access
  181.  
  182.  
  183.                   2
  184.  
  185.  
  186.     rights to a network port to a remote network server or signal
  187.     the IPC re-send thread to retry a message transmission.
  188.  
  189. Name Service Handles requests from other tasks for network name
  190.     service.  Allows names to be looked up on this host, on a
  191.     specific remote host or by broadcasting to all hosts.
  192.  
  193. Key Management Handles messages from the external Key Distribution
  194.     Server.  These messages tell the network server to use new
  195.     encryption keys for remote hosts.
  196.  
  197. Other Services A number of other threads may be used to provide other
  198.     services included with the network server, such as monitoring
  199.     and specialized name services.  In each case, the thread is
  200.     waiting for requests on a particular service port.
  201.  
  202.  
  203.  
  204. In addition, if the operations to be performed upon reception of a
  205. network message are too long, the Transport Receive threads may hand
  206. the message to other specialized processing threads, in order to
  207. remain available for new network messages.  Note that it is
  208. impractical to allocate one thread to each IPC message in transit due
  209. to resource limitations.
  210.  
  211.  
  212.  
  213. 2.3.   Code Structure
  214.  
  215.  
  216.  
  217. The code is distributed between several modules, each pertaining to
  218. some specific set of related operations or the management of some data
  219. structure.  The main modules are:
  220.  
  221. Port Records Operations for the handling of port records.  The main
  222.     data structure used is a database of port records, which
  223.     maintains a mapping between local ports and network port
  224.     identifiers, as well as keeping general status information on the
  225.     ports themselves.  Almost every module uses this database to
  226.     obtain information, and a number of modules modify the
  227.     information to reflect new situations that they have
  228.        detected.
  229.  
  230. Transport Protocols Provide the complete transport mechanism for a
  231.     block of data of arbitrary size over the network.  There are
  232.     several such modules implementing several protocols; some
  233.     guarantee reliable delivery, others don't.  Clients of the
  234.     transport protocols transmit messages by making a function
  235.     call into the transport module; for all incoming messages a
  236.     transport protocol calls a dispatcher function to deliver the
  237.     message.
  238.  
  239. Dispatcher Dispatches incoming network messages assembled by the
  240.     transport protocols to the appropriate module according the
  241.     dispatcher type contained in the network message header.  The
  242.     handler functions are directly called by the dispatcher.
  243.  
  244. IPC Message Handling Provides operations for receiving local IPC
  245.     messages and handing them to the transport layer, and
  246.     receiving messages from the transport layer and handing them
  247.     to the local user processes.  To do this it must translate IPC    
  248.     messages to and from a format appropriate for transmission on
  249.     the network.  In particular it must translate ports, identify
  250.     out-of-line data and, if necessary perform byte-swapping (this
  251.     corresponds to the ISO presentation layer roughly).  It also
  252.     handles the blocking mechanism for network ports.
  253.  
  254. Port Operations Provides all port translation functions for the IPC
  255.     module.  Also handles transfers and deletion of port access
  256.     rights due to the reception of notify messages from the kernel
  257.     and from remote network servers.
  258.  
  259.  
  260.  
  261.                   3
  262.  
  263.  
  264. Port Checkups Periodically verifies the information maintained in the
  265.     local port records by consulting other network servers.
  266.  
  267. Port Search Implements the sequence of operations needed to update the
  268.     information kept about a remote port when it is believed that
  269.     the current information is incorrect.  The checkups module
  270.     calls this module when it finds an inconsistency in the
  271.     information maintained about a port.
  272.  
  273. Key Management Maintains a mapping between remote hosts and the keys
  274.     that should be use to encrypt secure messages.  Also responsible for
  275.     interfacing with the key distribution server to obtain new
  276.     keys for remote hosts.
  277.  
  278. Crypt Provides functions to encrypt and decrypt network messages.
  279.  
  280. Network Name Service Provides a simple, host-directed network name
  281.     look up service.
  282.  
  283. Memory Management Provides allocation and deallocation functions for
  284.     all memory objects used in the network server.
  285.  
  286. Read/Write Lock Provides functions implementing read/write locks with
  287.     multiple users.
  288.  
  289. Locked Queue Operations on shared (i.e.  locked) queues of objects.
  290.  
  291. Timer Service Allows other modules to schedule actions after a
  292.     specified interval.
  293.  
  294.  
  295.  
  296. Other, miscellaneous modules provide for the generation of unique
  297. identifiers, the initialization of the network server, the actual
  298. transmission of datagrams over the network, and other ancillary
  299. functions.
  300.  
  301.  
  302.  
  303. 2.4.   Data Representation
  304.  
  305.  
  306.  
  307. There are a number of circumstances during the processing of IPC
  308. messages when the server has to manipulate large amounts of data.  In
  309. order to minimize overhead, large blocks of data are represented in a
  310. special format designed to limit the need for data copying and space
  311. allocation.
  312.  
  313.  
  314. Any conceptually contiguous block of data may be stored internally as
  315. a set of separate segments of any size, and a special sbuf
  316. (Segmented Buffer) structure is used to identify the segments
  317. constituting one block.  No special meaning is attached to how a block
  318. is segmented, i.e.  the segments do not necessarily represent logical
  319. parts of a block of data.  The segments reside in shared memory and
  320. are accessible by every thread.  Data modification and data transfer
  321. between modules are accomplished by operations on sbufs (typedef
  322. struct {...}  sbuf_t, *sbuf_ptr_t).
  323.  
  324.  
  325. For instance, if some data must be inserted at the head or the tail of
  326. some existing buffer, a new segment is allocated and placed at the
  327. right location in the sbuf.  If some data inside a buffer must be
  328. modified (possibly changing its length), the sbuf is modified so that
  329. the target data spans complete segments only, and those segments are
  330. replaced in the sbuf by new segments containing the modified data.
  331.  
  332.  
  333. Maximum efficiency for the allocation and deallocation of space for
  334. the segments cannot be attained with a general mechanism,
  335. consequently, space management is handled on a case by case basis by
  336. the modules that use sbufs and is private to an individual module.
  337. The information needed to deallocate the space used by segments of a
  338. given sbuf is not kept in the sbuf itself, but is recorded by the
  339. module that created each particular segment.  To simplify
  340. record-keeping, no segment may be referenced in more than one (public)
  341. sbuf.
  342.  
  343.  
  344.  
  345.                                                                 4
  346.  
  347.  
  348. Typically, when an sbuf is passed between modules, the system provides
  349. a call-back procedure to signal the module that created the sbuf that
  350. it is no longer needed.
  351.  
  352.  
  353. Special macros are provided to extract data from an sbuf, making its
  354. structure transparent to most modules.  Special macros are also
  355. provided for inserting data, but for performance reasons, they cannot
  356. be made entirely transparent.
  357.  
  358.  
  359.  
  360. 3.   Port Records
  361.  
  362.  
  363.  
  364. 3.1.   Description
  365.  
  366.  
  367.  
  368. The port record module maintains all the data associated with ports.
  369. In particular it enables the network server to map local to network
  370. and network to local ports.  An individual port record:
  371.  
  372.  
  373.  
  374.    typedef  struct  {...}  port_rec_t,  *port_rec_ptr_t;
  375.  
  376.  
  377.  
  378. contains the local port, the network port, status information about
  379. the port, several fields used by the IPC module, several fields for
  380. security, a reference count and a read/write lock.
  381.  
  382.  
  383. A  network  port  identifier  has  the  following  structure:
  384.  
  385.  
  386.  
  387.    typedef  struct  {
  388.           long             np_uid_high;
  389.           long             np_uid_low;
  390.    }  np_uid_t;
  391.  
  392.  
  393.  
  394.    typedef  struct  {
  395.           netaddr_t    np_receiver;
  396.           netaddr_t    np_owner;
  397.           np_uid_t       np_puid;
  398.           np_uid_t       np_sid;
  399.    }  network_port_t,  *network_port_ptr_t;
  400.  
  401.  
  402.  
  403. where the np_puid is the network port's Public Unique Identifer and
  404. the np_sid is the port's Secret Identifer.
  405.  
  406.  
  407.  
  408.    typedef  unsigned  long  netaddr_t;
  409.  
  410.  
  411.  
  412. is used to identify all network addresses within the network server.
  413.  
  414.  
  415.  
  416. 3.2.   Interface
  417.  
  418.  
  419.  
  420.    boolean_t  pr_init()
  421.  
  422.  
  423.  
  424. initializes  the  port  records  module.
  425.  
  426.  
  427.                   5
  428.  
  429.  
  430.    void  pr_reference(port_rec_ptr)
  431.    port_rec_ptr_t  port_rec_ptr;
  432.  
  433.  
  434.  
  435. increments the reference count for the port record.
  436.  
  437.  
  438.  
  439.    void  pr_release(port_rec_ptr)
  440.    port_rec_ptr_t  port_rec_ptr;
  441.  
  442.  
  443.  
  444. decrements the reference count for the port record, unlocks it and
  445. frees all memory associated with it if the reference count becomes
  446. zero.
  447.  
  448.  
  449.  
  450.    void  pr_destroy(port_rec_ptr)
  451.    port_rec_ptr_t                port_rec_ptr;
  452.  
  453.  
  454.  
  455. logically destroys a port record by removing it from all tables and
  456. deallocating the local port associated with it.  The actual space
  457. occupied by the port record is not freed until the reference count
  458. becomes zero, but this function performs one pr_release before
  459. exiting.
  460.  
  461.  
  462.  
  463.    port_rec_ptr_t  pr_np_puid_lookup(np_puid)
  464.    np_uid_t                         np_puid;
  465.  
  466.  
  467.  
  468. looks up and locks a port record given a network port's public unique
  469. identifier.
  470.  
  471.  
  472.  
  473.    extern  port_rec_ptr_t  pr_nportlookup(nport_ptr)
  474.    network_port_ptr_t        nport_ptr;
  475.  
  476.  
  477.  
  478. looks up and locks a port record given a network port.
  479.  
  480.  
  481.  
  482.    portrec_ptr_t  pr_ntran(nport_ptr)
  483.    network_port_ptr_t        nport;
  484.  
  485.  
  486.  
  487. looks up and locks a port record given a network port, creating a new
  488. port record and allocating a new local port if necessary.
  489.  
  490.  
  491.  
  492.    extern  port_rec_ptr_t  pr_lportlookup(lport)
  493.    port_t                            lport;
  494.  
  495.  
  496.  
  497. looks up and locks a port record given a local port.
  498.  
  499.  
  500.  
  501.    portrec_ptr_t  pr_ltran(lport)
  502.    port_t                            lport;
  503.  
  504.  
  505.  
  506. looks up and locks a port record given a local port, creating a new
  507. port record and allocating a new network port if necessary.
  508.  
  509.  
  510.                   6
  511.  
  512.  
  513.    boolean_t  nport_equal(nport_ptr_1,nport_ptr_2)
  514.    network_port_ptr_t        nport_ptr_1;
  515.    network_port_ptr_t        nport_ptr_2;
  516.  
  517.  
  518.  
  519. tests to see if two network ports are equal.
  520.  
  521.  
  522.  
  523.    void  pr_nporttostring(nport_str,nport_ptr)
  524.    char                               *nport_str;
  525.    network_port_ptr_t        nport_ptr;
  526.  
  527.  
  528.  
  529. returns in nport_str a printable representation of a network port.
  530.  
  531.  
  532.  
  533.    lock_queue_t  pr_list()
  534.  
  535.  
  536.  
  537. returns a list of all the local ports for which there is a port
  538. record.  (See the section on locked queues for the definition of
  539. lock_queue_t.)
  540.  
  541.  
  542. In general, all functions that return a port record lock that record
  543. before returning.  Functions that take a port record as an argument
  544. require that record to be already locked on entry.  The reference
  545. count normally reflects the presence of the port record in both the
  546. local and global tables, but no additional reference is taken by any
  547. of the above functions when returning a locked port record.  Note that
  548. these functions will block on the lock if the record is already
  549. locked.
  550.  
  551.  
  552.  
  553. 4.   Transport Protocols
  554.  
  555.  
  556.  
  557. 4.1.   Description
  558.  
  559.  
  560.  
  561. Several transport modules co-exist within the network server, each of
  562. them implementing a different protocol.  Some protocols under
  563. consideration are Delta-t, VMTP, NETBLT, TCP, UDP, and various
  564. multicast schemes.  It is up to clients of the transport modules to
  565. choose the one that satisfies their needs best.  All the transport
  566. modules deliver messages into the same dispatcher, and are accessed
  567. via separate entry points, grouped into a table similar to the Mach
  568. device table.
  569.  
  570.  
  571. The organization of each protocol module is up to each implementor.
  572. Layered and non-layered approaches are both acceptable, as well as the
  573. use of external servers, not residing in the same address space as the
  574. network server.  Implementors are encouraged to use the sbuf mechanism
  575. to represent and manipulate data internally, and to copy data only at
  576. the last level before the network interface.  The timer module is
  577. available for handling periodic retransmission and other protocol
  578. functions needing timeouts.
  579.  
  580.  
  581.  
  582. 4.2.   Interface
  583.  
  584.  
  585.  
  586. Because of an ongoing revision of the implementation, there are
  587. currently two modes of operation for transport modules.
  588.  
  589.  
  590. The first mode of operation specifies a simple send operation to
  591. transmit a message to a given destination.  It is used by all modules
  592. except the IPC module, to exchange information with the corresponding
  593. modules in the network servers at other nodes.
  594.  
  595.  
  596.                   7
  597.  
  598.  
  599. The second mode of operation specifies a request-response interaction,
  600. in which one node (the client) sends a request to another node (the
  601. server), and then awaits the reception of exactly one response from
  602. that server.  The transport protocol always supports the transmission
  603. of a 32-bit completion code in the response, and may optionally
  604. support the transmission of data in that same response.  This mode of
  605. operation is used by the IPC module for the transmission of IPC
  606. message data; it is intended to be the standard for all transport
  607. protocols, and all other modules will be converted to use it.
  608.  
  609.  
  610. Currently, each specific transport module only implements one or the
  611. other mode of operation; and can therefore be used either by the IPC
  612. module or by all other modules, but not both.  In the future, all
  613. modules will be converted to the second mode of operations.
  614.  
  615.  
  616. The following table is used to hold all the entry points for all the
  617. possible transport modules.  Each transport module is assigned a
  618. specific number, to be used as an index into this table when invoking
  619. it, and to be used to identify it when it delivers a message to the
  620. upper level.
  621.  
  622.  
  623.  
  624.    typedef  struct  {
  625.           int              (*send)();
  626.           int              (*sendrequest)();
  627.           int              (*sendreply)();
  628.    }  transport_sw_entry_t;
  629.  
  630.  
  631.  
  632. The entries in this table are filled by each transport module when it
  633. initializes itself.  Any unused entry is set to the special function
  634. transport_no_function, which simply returns after emitting an error
  635. message.  The send entry is used for the simple send interface.  The
  636. sendrequest and sendreply entries are used for the request-response
  637. interface.  Any protocol supporting that interface must implement
  638. sendrequest, but not necessarily sendreply, as described above.
  639.  
  640.  
  641. In the following descriptions, xxx_ is used as a generic prefix, to be
  642. replaced by the name of each transport module.
  643.  
  644.  
  645.  
  646.    boolean_t  xxx_init()
  647.  
  648.  
  649.  
  650. initializes the transport module and places the entry points in the
  651. transport switch table.
  652.  
  653.  
  654.  
  655.    int  xxx_send(client_id,trid,data,to,service,crypt_level,cleanup)
  656.    int                                   client_id;
  657.    int                                   trid;
  658.    sbuf_ptr_t                       data;
  659.    netaddr_t                         to;
  660.    int                                   service;
  661.    int                                   crypt_level;
  662.    int                                   (*cleanup)();
  663.  
  664.  
  665.  
  666. attempts to send message data to destination to.  client_id is an ID
  667. used by the client to identify this message.  trid is a
  668. transport-level ID used to identify a current request-response
  669. interaction; it should be 0 if not used.  service is the kind of
  670. service required for this message; possible values are:
  671.  
  672.  
  673.                   8
  674.  
  675.  
  676.     o TRSERV_NORMAL:  normal  transmission  of  a  single  message.
  677.  
  678.     o TRSERV_IPC: transmission of an IPC message, ``call-back''
  679.       required.  (OBSOLETE)
  680.  
  681.     o TRSERV_RPC: transmission part of a request-response at the IPC
  682.       level.  Pairing information required and ``call-back'' required.
  683.       Note that the ``call-back'' can be implicitly be the delivery of
  684.       the response if the RPC succeeds.  (OBSOLETE)
  685.  
  686.     o TRSERV_URGENT: transmission of an urgent single message, to be
  687.       delivered before other non-urgent transmissions in progress if
  688.       possible.
  689.  
  690.  
  691.  
  692. crypt_level determines what kind of encryption should be used to
  693. protect the data.  Possible levels of encryption include:
  694. CRYPT_DONT_ENCRYPT and CRYPT_ENCRYPT.  cleanup is a function supplied
  695. by the client, to be called when the transmission is complete and the
  696. message data is no longer needed.  Depending on the service requested,
  697. it may indicate a simple local completion, or participate in the
  698. ``call-back'' mechanism.  It takes two arguments: the client ID, and a
  699. completion code.
  700.  
  701.  
  702. cleanup returns 0 when all is well.  xxx_send also returns a
  703. completion code to indicate the immediate local result of the call.
  704.  
  705.  
  706.  
  707.    int xxx_sendrequest(client_id,data,to,crypt_level,reply_proc) 
  708.    int        client_id; 
  709.    sbuf_ptr_t     data; 
  710.    netaddr_t     to; 
  711.    int         crypt_level;
  712.    int       (*reply_proc)();
  713.  
  714.  
  715. attempts to send a request containing data to destination to.
  716. client_id is an ID used by the client to identify this
  717. request-response interaction.  crypt_level determines what kind of
  718. encryption should be used to protect the data.  Possible levels of
  719. encryption include: CRYPT_DONT_ENCRYPT and CRYPT_ENCRYPT.  reply_proc
  720. is a procedure to be called from the transport module to deliver a
  721. response.
  722.  
  723.  
  724. xxx_sendrequest returns either TR_SUCCESS or a specific failure code.
  725. In the first case, a request-response interaction is initiated, that
  726. will terminate when reply_proc is called.  The data supplied in the
  727. request must be kept valid by the caller for the whole duration of the
  728. request-response interaction.  The reply procedure is guaranteed to be
  729. called exactly once, with the following arguments:
  730.  
  731.  
  732.  
  733.    void  reply_proc(client_id,reply_code,data)
  734.    int                     client_id;
  735.    int                     reply_code;
  736.    sbuf_ptr_t          data;
  737.  
  738.  
  739.  
  740. client_id is the ID given as argument to xxx_sendrequest.  reply_code
  741. is a completion code supplied either by the transport module (in case
  742. of transport errors) or by the server process that handled the
  743. request.  data may contain data supplied by the server in the
  744. response, or it may by null.  This data is kept valid by the transport
  745. module only until reply_proc returns.
  746.  
  747.  
  748. If xxx_sendrequest returns anything other than TR_SUCCESS, no
  749. request-response interaction is initiated, and reply_proc is never
  750. called.
  751.  
  752.  
  753.  
  754.                                                                 9
  755.  
  756.  
  757. The handler on the server side of a request-response interaction is
  758. invoked via the dispatcher module (see below).  This handler must
  759. return a code that determines how the response is sent.  If this code
  760. is anything other than DISP_WILL_REPLY, a response containing that
  761. code and no data is immediately sent back by the transport module.  If
  762. this code is DISP_WILL_REPLY, no response is generated by the
  763. transport module, and the higher-level module must explicit call
  764. xxx_sendreply to terminate the request-response interaction:
  765.  
  766.  
  767.  
  768.    int  xxx_sendreply(trid,code,data,crypt_level)
  769.    int                     trid;
  770.    int                     code;
  771.    sbuf_ptr_t          data;
  772.    int                     crypt_level;
  773.  
  774.  
  775.  
  776. trid is a transport-level ID supplied by the dispatcher with the
  777. request.  code and data are the reply code and data to be used in the
  778. call to reply_proc on the client.  crypt_level determines what kind of
  779. encryption should be used to protect the data.  data can be null.  If
  780. it is not, the data must be kept valid by the caller only until
  781. xxx_sendreply returns.
  782.  
  783.  
  784. The procedure returns TR_SUCCESS or TR_FAILURE.  It is an error to
  785. call xxx_sendreply for a terminated request-response interaction,
  786. including one terminated by the handler returning a code other than
  787. DISP_WILL_REPLY.  Similarly, it is an error for the handler to return
  788. DISP_WILL_REPLY if the transport module in use does not implement
  789. xxx_sendreply.
  790.  
  791.  
  792. Note that since multiple threads are involved, the reply procedure may
  793. be called before xxx_sendrequest returns.  Similarly, it is acceptable
  794. for the server to call xxx_sendreply before returning from the handler
  795. procedure for the request, provided that this handler eventually
  796. returns DISP_WILL_REPLY.
  797.  
  798.  
  799. The  completion  codes  for  transport  operations  are:
  800.  
  801.  
  802.  
  803.     o TR_CRYPT_FAILURE: the transmission failed either because of a
  804.       local encryption or a remote decryption failure --- the local
  805.       client module should try and get a new key for the destination
  806.       host and then retry the transmission;
  807.  
  808.     o TR_SEND_FAILURE: something went wrong with the transmission
  809.       before any data could be sent.
  810.  
  811.     o TR_FAILURE: something went wrong with the transmission within
  812.       either the local or remote transport module; the error was
  813.       detected too late to return TR_SEND_FAILURE.
  814.  
  815.     o TR_OVERLOAD: the transport module is currently overloaded.  No
  816.       data was sent; the user should retry later.
  817.  
  818.     o TR_SUCCESS: the transmission was successful but it was not
  819.       possible to determine whether the message was accepted by the
  820.       remote client.
  821.  
  822.     o a client-specific completion code (see, for example, the codes
  823.       returned by the IPC module).
  824.  
  825.  
  826.  
  827. Note that the transport-specific completion codes are in the same
  828. space as the client-specific completion codes; care must be taken to
  829. avoid collisions.
  830.  
  831.  
  832.  
  833.                   10
  834.  
  835.  
  836. 4.3.   Specific Transport Protocols
  837.  
  838.  
  839.  
  840. 4.3.1.   Delta-t
  841.  
  842.  
  843.  
  844. Delta-t is a connectionless transport protocol in which each packet
  845. sent over the network is individually acknowledged by the destination
  846. network server before the next packet is sent.  All the
  847. transport-level protocol handling is performed in the network server;
  848. network access at the IP level is achieved through the Mach network
  849. interface described below.  Retransmissions are scheduled using the
  850. timer module.  In order to detect duplicate packets, information about
  851. an incoming data packet is maintained by a network server either until
  852. the next packet in a sequence is received or the information has been
  853. held more that some minimum amount of time.
  854.  
  855.  
  856. Delta-t currently implements the request-response interface without
  857. deltat_sendreply.
  858.  
  859.  
  860. Delta-t is suitable for transmitting messages containing small amounts
  861. of data (less than a few packets in total).  If the message is part of
  862. a RPC protocol in which the response to the request is expected
  863. shortly, then it is better to use a more specialized request-response
  864. protocol such as VMTP.
  865.  
  866.  
  867.  
  868. 4.3.2.   VMTP
  869.  
  870.  
  871.  
  872. VMTP (Versatile Message Transport Protocol) is the request-response
  873. protocol developed at Stanford by D.  Cheriton and his group [1 ].
  874. The VMTP module creates a single well-known server entity to receive
  875. all network requests, and keeps a pool of client entities to use on
  876. the client side to initiate transactions.  Whenever vmtp_sendrequest
  877. is called, an unused client entity is pulled out of that pool; it is
  878. returned to the pool when the reply is delivered.  The actual VMTP
  879. protocol handling module is in the kernel; it communicates with the
  880. network server using sockets.
  881.  
  882.  
  883. There are currently two versions of the VMTP module.  vmtp1 implements
  884. the simple send interface and should not be used.  vmtp2 implements
  885. the full request-response interface, and is suitable for IPC messages.
  886.  
  887.  
  888.  
  889. 4.3.3.   TCP
  890.  
  891.  
  892.  
  893. The TCP module keeps a pool of TCP connections to the network servers
  894. on other nodes.  Each connection is created when needed to transmit a
  895. request, and is kept open as long as possible to service further
  896. requests to the same destination.  Open connections are recycled using
  897. a least-recently-used policy to limit their number.  The protocol
  898. handling module is in the kernel; it communicates with the network
  899. server using sockets.
  900.  
  901.  
  902. TCP currently implements the full request-response interface, and is
  903. suitable for IPC messages.
  904.  
  905.  
  906.  
  907. 4.3.4.   Datagram
  908.  
  909.  
  910.  
  911. The ``datagram'' transport protocol simply provides an interface to
  912. the UDP level.  It allows unreliable datagrams to be sent over the
  913. network.
  914.  
  915.  
  916.  
  917.                   11
  918.  
  919.  
  920. Datagram currently implements the simple send interface and cannot be
  921. used to transmit IPC message data.
  922.  
  923.  
  924.  
  925. 4.3.5.   Simple Request-Response
  926.  
  927.  
  928.  
  929. The simple request-response protocol permits the sending of a request
  930. over the network for which a response is expected.  The data of the
  931. request is guaranteed to fit in one network datagram.  This protocol
  932. will treat responses as acknowledgements to requests and inform its
  933. client either of the failure of the request (if no response was
  934. received after some number of tries) or of the success of the request
  935. in which case the response is returned to the client.  It is assumed
  936. that a request can be handled without delay by the higher-level
  937. protocol and the response is supplied on return from the request call.
  938. Requests made using this protocol should be idempotent.
  939.  
  940.  
  941. Although SRR is oriented toward request-response interactions, it
  942. implements the simple send interface and not the request-response
  943. interface.  It cannot therefore be used to transmit IPC message data.
  944.  
  945.  
  946.  
  947. 5.   Dispatcher Module
  948.  
  949.  
  950.  
  951. 5.1.   Operation
  952.  
  953.  
  954.  
  955. The dispatcher module is responsible for invoking the correct handler
  956. procedure when some network message has been received.  It is called
  957. by the various transport modules, examines the dispatcher header, and
  958. selects the appropriate routine to call according to the message type
  959. (incoming IPC, port death, and so on).
  960.  
  961.  
  962. This module can optionally establish a separation between a network
  963. thread and one or more other threads used to process the messages at
  964. the network server level.  This last scheme is to be used if the
  965. network thread would not be fast enough if it had to completely
  966. process each message before listening to the net again.  Note that
  967. with this mechanism, care must be taken to avoid problems when a
  968. transport module deallocates the space used by incoming data before
  969. that data has been processed at the higher level.
  970.  
  971. To allow communication between machines with different data
  972. representation, the dispatcher header always use a standard
  973. representation.  The rest of each message uses whatever representation
  974. is in use on the sending machine; a code for that representation is
  975. stored in the dispatcher header and made available to the message
  976. handler modules.
  977.  
  978.  
  979. To allow future expansion, the dispatcher also checks a version number
  980. for each incoming message.
  981.  
  982.  
  983. 5.2.   Interface
  984.  
  985.  
  986. As discussed in 4.2, there are currently two transport interfaces, to
  987. which correspond two dispatcher interfaces.  The following table holds
  988. a set of entry points for each message type.
  989.  
  990.  
  991.    typedef  struct  {
  992.           int              (*disp_indata)();
  993.           int              (*disp_inprobe)();
  994.           int              (*disp_indata_simple)();
  995.           int              (*disp_rr_simple)();
  996.           int              (*disp_in_request)();
  997.    }  dispatcher_switch_t;
  998.  
  999.                   12
  1000.  
  1001.  
  1002.  
  1003.  
  1004. All modules place entry points in the table for each message type and
  1005. each type of handler procedure that they support and wish to receive
  1006. messages for.  Unused entries are set to the special procedure
  1007. disp_no_function; the network server is organized in such a way that
  1008. there are not collisions in the table.
  1009.  
  1010.  
  1011. disp_indata, disp_inprobe, disp_indata_simple and disp_rr_simple are
  1012. called by transport modules using the simple xxx_send interface, and
  1013. will eventually be eliminated.
  1014.  
  1015.  
  1016. disp_in_request is the sole entry point used with the request-response
  1017. interface.
  1018.  
  1019.  
  1020.  
  1021.    int  disp_init()
  1022.  
  1023.  
  1024.  
  1025. initializes the dispatcher module.
  1026.  
  1027.  
  1028.  
  1029.    int  disp_indata(trid,data,from,tr_cleanup,trmod,
  1030.                              client_id,crypt_level,broadcast)
  1031.    int                                   trid;
  1032.    sbuf_ptr_t                       *data;
  1033.    netaddr_t                         from;
  1034.    int                                   (*tr_cleanup)();
  1035.    int                                   trmod;
  1036.    int                                   client_id;
  1037.    int                                   crypt_level;
  1038.    boolean_t                         broadcast;
  1039.  
  1040.  
  1041.  
  1042. is the primary function used to dispatch incoming data in the simple
  1043. send mode of operation.  trid is a transport level identifier assigned
  1044. by the transport module trmod.  It should be used in the call to
  1045. tr_cleanup which signals to the transport module that the higher-level
  1046. module is finished with the data contained in the sbuf data.  Other
  1047. arguments are: from, the host that sent the data; client_id, an
  1048. identifier assigned by the client module within a prior call to
  1049. disp_inprobe (see below); crypt_level, the encryption level used to
  1050. send data over the network; and broadcast whether the data was
  1051. broadcast or not.  disp_indata returns DISP_FAILURE is the dispatcher
  1052. module did not find a higher-level routine to be called for the
  1053. incoming message type or if the version number of the incoming message
  1054. did not match the current version number of this implementation of the
  1055. network server; otherwise it returns the value returned by the
  1056. higher-level routine.
  1057.  
  1058.  
  1059.  
  1060.    int  disp_inprobe(trid,pkt,from,cancel,trmod,
  1061.                              client_id,crypt_level,broadcast)
  1062.    int                                   trid;
  1063.    sbuf_ptr_t                       pkt;
  1064.    netaddr_t                         from;
  1065.    int                                   *((*cancel)());
  1066.    int                                   trmod;
  1067.  
  1068.  
  1069.                   13
  1070.  
  1071.  
  1072.    int                                   *client_id;
  1073.    int                                   crypt_level;
  1074.    boolean_t                         broadcast;
  1075.  
  1076.  
  1077.  
  1078. allows the first packet of a message to be dispatched to a
  1079. higher-level probe routine.  This allows the higher-level routine to
  1080. decide before-hand whether to accept or reject an incoming message.
  1081. If it decides to accept the message based on the probe packet, the it
  1082. returns a client_id to allow it to later identify the whole incoming
  1083. message.  cancel (an out parameter) is called by the transport module
  1084. if it is unable to deliver the complete message after a probe has been
  1085. accepted.  It takes as argument the client_id and a reason code.
  1086. Other parameters are as for disp_indata.
  1087.  
  1088.  
  1089.  
  1090.    int  disp_indata_simple(client_id,data,from,crypt_level,broadcast)
  1091.    int                                   client_id;
  1092.    sbuf_ptr_t                       data;
  1093.    netaddr_t                         from;
  1094.    int                                   crypt_level;
  1095.    boolean_t                         broadcast;
  1096.  
  1097.  
  1098.  
  1099. is similar to disp_indata except that it is guaranteed that the data
  1100. is processed at the higher-level within the same thread that made the
  1101. call.  Hence there is no need for a tr_cleanup call because, when the
  1102. dispatcher call returns, the transport module knows that the data is
  1103. no longer needed and can do the cleanup synchronously.
  1104.  
  1105.  
  1106.  
  1107.    int  disp_rr_simple(data,from,crypt_level,broadcast)
  1108.    sbuf_ptr_t                       data;
  1109.    netaddr_t                         from;
  1110.    int                                   crypt_level;
  1111.    boolean_t                         broadcast;
  1112.  
  1113.  
  1114.  
  1115. allows a transport-level protocol to make a simple request-response
  1116. interaction with a higher level module.  The higher-level module
  1117. should process the request immediately and include the response on
  1118. returning from the call.  Note that this procedure is intended for
  1119. request-response interactions within the simple send mode of
  1120. operations, and not within the full request-response interface
  1121. described above.
  1122.  
  1123.  
  1124.  
  1125.    int  disp_in_request(trmod,trid,data_ptr,from,crypt_level,broadcast);
  1126.    int                                   trmod;
  1127.    int               trid;
  1128.    sbuf_ptr_t               data_ptr;
  1129.    netaddr_t               from;
  1130.    int               crypt_level;
  1131.    boolean_t               broadcast;
  1132.  
  1133.  
  1134.  
  1135. is the single function for dispatching in the request-response mode of
  1136. operation.  The arguments are similar to those of disp_indata.  The
  1137. data pointed to by data_ptr is valid only until this procedure
  1138. returns.  Any return value other than DISP_WILL_REPLY is interpreted
  1139. by the transport module as a completion code to be returned
  1140. immediately in a response to the client.  DISP_WILL_REPLY means that
  1141. the higher-level module assumes the responsibility to send a response,
  1142. and the transport module should do nothing when this procedure returns
  1143. (other than deallocate the space occupied by the data, if
  1144.  
  1145.  
  1146.                   14
  1147.  
  1148.  
  1149. appropriate).  Note that if the dispatcher returns DISP_FAILURE, that
  1150. code is returned to the client in the normal way.
  1151.  
  1152.  
  1153. In subsequent sections of this document, functions which are called
  1154. via the dispatcher module do not have their arguments described.  The
  1155. arguments are exactly as for the corresponding dispatcher function.
  1156.  
  1157.  
  1158.  
  1159. 6.   IPC Message Handling
  1160.  
  1161.  
  1162.  
  1163. The IPC Message Transfer module implements the upper layer of the
  1164. mechanism used to communicate with remote ports.  It relies on a
  1165. separate transport module to provide the lower-level network
  1166. transmission operations, and communicates with it using sbufs.  To
  1167. maximize performance, the IPC module tries to identify messages that
  1168. are part of a remote procedure call (RPC), and attempts to map the
  1169. request-response structure of such calls into a request-response
  1170. interaction at the transport level.
  1171.  
  1172.  
  1173.  
  1174. 6.1.   Normal Operation
  1175.  
  1176.  
  1177.  
  1178. The IPC module receives messages addressed to ports that are local
  1179. representatives of remote ports.  Upon reception of such a local IPC
  1180. message, the IPC module
  1181.  
  1182.  
  1183.  
  1184. 1.  allocates a transaction record (ipc_rec) to keep information about
  1185.     the transfer in progress,
  1186.  
  1187. 2.  consults the port records to find the remote port corresponding to
  1188.     the local port,
  1189.  
  1190. 3.  generates an IPC Header to contain special information to be used
  1191.     by the remote network server,
  1192.  
  1193. 4.  translates the ports and out-of-line pointers in the message so
  1194.     that they will be intelligible on the receiving node, and
  1195.  
  1196. 5.  selects a transport protocol to use, and hands the whole message
  1197.     to the appropriate module via xxx_sendrequest.
  1198.  
  1199.  
  1200.  
  1201. Note that the breakup of the message into several packets is the task
  1202. of a transport module and not the IPC module.
  1203.  
  1204.  
  1205. All these operations are performed on a message represented using an
  1206. sbuf.  In general, the segments contained in the sbuf are:
  1207.  
  1208.  
  1209.  
  1210.     o the IPC receive buffer, containing the inline data;
  1211.  
  1212.     o each out-of-line data section;
  1213.  
  1214.     o the IPC header, allocated by this module; and
  1215.  
  1216.     o any special data structures needed for the message translation
  1217.       process, such as accessibility maps or a network port
  1218.       dictionary.
  1219.  
  1220.  
  1221.  
  1222. In the remote network server receiving the message, all the component
  1223. packets are assembled by the transport module, which calls the IPC
  1224. module and hands it an sbuf representing the whole message.  Typically
  1225. segments in that sbuf are part of packet
  1226.  
  1227.  
  1228.                   15
  1229.  
  1230.  
  1231. buffers in which the message was received.  The module uses ipc_rec
  1232. records to store information about current incoming messages.  It
  1233. performs all necessary translations (including byte-swapping and data
  1234. type conversion), copies the message into a send buffer, and delivers
  1235. it to its local destination.
  1236.  
  1237.  
  1238. The IPC module on the sending network server may not discard the
  1239. message immediately after calling the transport module to initiate a
  1240. transmission, because it may be necessary to effect a complete
  1241. retransmission, possibly to a new destination and with different
  1242. accompanying data.  This is the case when some exceptional events,
  1243. described in the next section, prevent the receiving network server
  1244. from delivering the message to its ultimate destination.  In addition,
  1245. some operations pertaining to security must be performed by the IPC
  1246. module on the sending node only when it is certain that the message
  1247. has been correctly transmitted.  For these reasons, the network server
  1248. on the receiving node uses the request-response transport mechanism to
  1249. return a completion code indicating if it was able to deliver the
  1250. message, or what happened if it was not.  Upon reception of this
  1251. completion code, the sending network server may deallocate its ipc_rec
  1252. and the message data, or undertake the appropriate recovery action in
  1253. case of error, including initiating a new transmission.
  1254.  
  1255.  
  1256.  
  1257. 6.2.   Exceptional Events
  1258.  
  1259.  
  1260.  
  1261. The exceptional events are detected either at the transport level or
  1262. by the IPC module in the remote network server.  They are reported to
  1263. the sending IPC module through the request-response completion code
  1264. described above.  The IPC module must then freeze the current
  1265. transmission, and call another module to deal with that exception.
  1266. That module may in turn request the IPC module to attempt to retry the
  1267. transmission of any pending messages for a given destination port,
  1268. possibly after changing some information in the port's record.  In
  1269. that case, the IPC module will restart processing of any affected
  1270. messages as if that message had just been received on a local port.
  1271. As an optimization, it could reuse some of the information already
  1272. gathered, and stored in the record for this pending message.
  1273.  
  1274.  
  1275. Exceptional  events  include:
  1276.  
  1277.  
  1278.  
  1279.     o Modification of a port record while a message for that port is
  1280.       in transit by some other thread running concurrently with the
  1281.       IPC sending thread (for example in response to a port death
  1282.       message).  It simply triggers re-processing of the message.
  1283.  
  1284.     o Network failure, detected by the transport module.  The IPC
  1285.       module must decide to abort or retry the message, and find out
  1286.       if the port is dead.
  1287.  
  1288.     o Crypt failure, detected by the transport module at the local or
  1289.       remote node when it does not possess the correct key to encrypt
  1290.       or decrypt the message.  The IPC module calls the key management
  1291.       module to establish a new key.
  1292.  
  1293.     o Remote port not found at the expected node, signalled by the
  1294.       receiving IPC module --- a port search procedure is initiated (in
  1295.       another thread), and its completion will decide whether the
  1296.       transmission is to be restarted or aborted.
  1297.  
  1298.     o Remote port blocked, signalled by the remote IPC module.  The
  1299.       sending node suspends the message until further notice and
  1300.       indicates the situation in its port record.  A ipc_block record
  1301.       for the sending node is allocated at the receiving node.  When
  1302.       the port becomes unblocked, the list of those records is scanned
  1303.       and a special PORT_UNBLOCKED message is transmitted to each
  1304.       waiting network server, to indicate that transmission should be
  1305.       restarted.  If this unblock message is lost then the
  1306.  
  1307.  
  1308.                   16
  1309.  
  1310.  
  1311.       port checkups module will discover that the port has become
  1312.       unblocked and will retry the message transmission.
  1313.  
  1314.  
  1315.  
  1316. To avoid blocking the message delivery thread in the receiving network
  1317. server, all messages are always delivered using the SEND_NOTIFY option
  1318. of msg_send.  If the return from msg_send indicates that the local
  1319. port has become blocked, no other messages will be accepted for that
  1320. port until the kernel indicates that it has been unblocked.
  1321. Appropriate marking and locking of the port record guarantees that no
  1322. two threads can be in the situation of exercising the SEND_NOTIFY
  1323. option on the same port at the same time.  Note that this mechanism
  1324. does not require the receiving network server to return a port blocked
  1325. indication for a message accepted under the SEND_NOTIFY option,
  1326. thereby allowing the actual message delivery to be performed in
  1327. another thread after the dispatcher procedure has returned (the
  1328. current implementation does not take advantage of this feature).
  1329.  
  1330.  
  1331.  
  1332. 6.3.   RPC Interactions
  1333.  
  1334.  
  1335.  
  1336. The IPC module offers an optimization for RPC interactions for which
  1337. the user is willing to accept some semantic restrictions:
  1338.  
  1339.  
  1340.  
  1341.     o the request message is followed by exactly one response message
  1342.       addressed to the reply port indicated in the request.
  1343.  
  1344.     o the reply port is local to the node issuing the request.
  1345.  
  1346.     o no new request is sent using the same reply port while awaiting
  1347.       a response on that reply port.
  1348.  
  1349.     o the  reply  port  is  not  deallocated  while  awaiting  a  response.
  1350.  
  1351.     o the receive rights for the reply port are not transferred while
  1352.       awaiting a response.
  1353.  
  1354.     o the reply port is not blocked or locked while awaiting a
  1355.       response.
  1356.  
  1357.  
  1358.  
  1359. If any of those rules is violated, the response is not guaranteed to
  1360. be delivered, or may be delivered out of order; the behavior of the
  1361. network server may vary from one instance of such an erroneous
  1362. situation to the next.  The user must specify the MSG_TYPE_RPC bit in
  1363. the msg_type field of the message header for the request to indicate
  1364. that he accepts those modified message semantics.
  1365.  
  1366.  
  1367. Whenever a valid request is received with the MSG_TYPE_RPC bit set,
  1368. the network server on the server side uses DISP_WILL_REPLY if possible
  1369. to delay the transmission of the completion code at the transport
  1370. level.  It keeps track of the pending request in a ipc_rec, and
  1371. considers a new IPC message destined to the reply port as the response
  1372. for the RPC interaction.  Instead of sending this message with a new
  1373. transport interaction, it places it in the response for the pending
  1374. interaction.  Because the transport interface does not provide an
  1375. end-to-end acknowledgment that the data portion of a response was
  1376. correctly handled by the IPC module on the client side, the network
  1377. server on the server side must rely on the above assumptions for
  1378. delivery of the response to the reply port.
  1379.  
  1380.  
  1381. This scheme also relies on the assumption that the response message
  1382. will eventually be sent from the same node that received the request
  1383. message, and that no other traffic involving the reply port takes
  1384. place until that response is delivered.  This assumption
  1385.  
  1386.  
  1387.  
  1388.                   17
  1389.  
  1390.  
  1391. may easily be invalidated both by erroneous actions on the part of the
  1392. client or server processes, or by normal operations such as request
  1393. forwarding.  Because resources in the transport module are tied up as
  1394. long as the response has not been delivered, the IPC modules on both
  1395. sides check for all events that may suggest that a response may not be
  1396. forthcoming in the normal way.  When any such event occurs, they force
  1397. the transmission of a dummy response to terminate the request-response
  1398. interaction, letting the real response, if any, proceed normally as a
  1399. new single IPC message.  The events causing such an abort include:
  1400.  
  1401.  
  1402.  
  1403.     o transfer of receive or ownership rights for the reply port.
  1404.  
  1405.     o transmission of a new message using the same reply port.
  1406.  
  1407.     o reception of a message on the reply port on the client side,
  1408.       from a source other the expected server.
  1409.  
  1410.     o reception of a message on the reply port on the server side,
  1411.       with the MSG_TYPE_RPC bit set.
  1412.  
  1413.     o timeout at the network server on the server side (triggered by
  1414.       the port checkups mechanism).
  1415.  
  1416.  
  1417.  
  1418. Note that none of these aborts compromise the semantics of an RPC;
  1419. they simply nullify the performance benefits of the RPC optimization
  1420. when the situation is not simple.  In addition, the network server
  1421. itself never sets the MSG_TYPE_RPC bit when delivering a message to a
  1422. local port, to avoid hidden forwarding problems.
  1423.  
  1424.  
  1425.  
  1426. 6.4.   Message Ordering
  1427.  
  1428.  
  1429.  
  1430. A weak ordering of message delivery is provided through the use of a
  1431. queue of pending transactions for each remote network port.  This
  1432. queue operates in the following way:
  1433.  
  1434.  
  1435.  
  1436.     o all outgoing RPC requests and single IPC messages are queued in
  1437.       the order in which they are received on the local port.
  1438.  
  1439.     o as long as there are only RPC requests on the queue, each is
  1440.       transmitted as soon as it is queued; the system does not wait for a
  1441.       response before transmitting the next
  1442.        request.
  1443.  
  1444.     o as soon as one single IPC message is queued, newer messages (IPC
  1445.       or RPC) are queued but not transmitted until that IPC message is
  1446.       successfully transmitted and dequeued (including any number of
  1447.       retransmissions).
  1448.  
  1449.     o RPC responses are never queued; they are transmitted at once and
  1450.       never retransmitted.
  1451.  
  1452.     o whenever the status of the network port changes, retransmissions
  1453.       are initiated as needed in the order in which records are on the
  1454.       queue.
  1455.  
  1456.     o the local port is locked when the queue becomes too long and new
  1457.       messages cannot be transmitted.
  1458.  
  1459.  
  1460.  
  1461. This strategy guarantees that single IPC messages directed at the same
  1462. destination port from the same node are strictly ordered.  RPC's are
  1463. naturally ordered simply because the client waits for the response
  1464. before issuing the next request.  There are no ordering guarantees for
  1465. a single IPC immediately following the request for a RPC.
  1466.  
  1467.  
  1468.                   18
  1469.  
  1470.  
  1471. 6.5.   Interface
  1472.  
  1473.  
  1474.  
  1475.    boolean_t  ipc_init()
  1476.  
  1477.  
  1478.  
  1479. initializes  the  IPC  module.
  1480.  
  1481.  
  1482.  
  1483.    int  ipc_in_request(trmod,trid,data_ptr,from,crypt_level,broadcast)
  1484.  
  1485.  
  1486.  
  1487. is called from disp_in_request when a RPC request or single IPC is
  1488. received over the network by a transport module.  It is the main entry
  1489. point for incoming messages.  See the dispatcher module for details
  1490. about the parameters to this call.
  1491.  
  1492.  
  1493.  
  1494.    void  ipc_in_reply(client_id,code,data_ptr)
  1495.  
  1496.  
  1497.  
  1498. is the procedure used by the IPC module to receive responses from the
  1499. transport module after a call to xxx_sendrequest for IPC message data.
  1500. See the transport module for details about the parameters to this
  1501. call.
  1502.  
  1503.  
  1504.  
  1505.    ipc_in_unblock(client_id,data,from,broadcast,crypt_level)
  1506.  
  1507.  
  1508.  
  1509. is called by disp_indata_simple when an unblock message is received
  1510. from a remote network server.  It will cause the message transmission
  1511. to be retried.  See the dispatcher module for details about the
  1512. parameters to this call.
  1513.  
  1514.  
  1515.  
  1516.    void  ipc_msg_accepted(port_rec_ptr)
  1517.    port_rec_ptr_t                port_rec_ptr;
  1518.  
  1519.  
  1520.  
  1521. is called by the local port operations module when it receives a
  1522. notify message from the kernel saying that a particular port is now
  1523. unblocked.  The IPC module will send unblock notification messages to
  1524. remote network servers that are blocked waiting to send a message to
  1525. the port.
  1526.  
  1527.  
  1528.  
  1529.    void  ipc_port_dead(port_rec_ptr)
  1530.    port_rec_ptr_t                port_rec_ptr;
  1531.  
  1532.  
  1533.  
  1534. is called by the local port operations module either when it receives
  1535. a notify message from the kernel saying that a particular port is now
  1536. dead or when it receives a message from a remote network server saying
  1537. that a particular network port is now dead.  The IPC module will clean
  1538. up any data structures it has associated with the deceased port.
  1539.  
  1540.  
  1541.  
  1542.    void  ipc_port_moved(port_rec_ptr)
  1543.    port_rec_ptr_t                port_rec_ptr;
  1544.  
  1545.  
  1546.  
  1547. is called by the local port operations module when it receives a
  1548. message from a remote network server saying that a particular network
  1549. port has moved.  The IPC module will abort any pending RPC's involving
  1550. this port.
  1551.  
  1552.  
  1553.                   19
  1554.  
  1555.  
  1556.    int  ipc_in_abortreq(trmod,trid,data_ptr,from,crypt_level,broadcast)
  1557.  
  1558.  
  1559.  
  1560. is called from disp_in_request when a request to abort a pending
  1561. request-response interaction is received over the network by a
  1562. transport module.  The data specifies which RPC is to be aborted.  If
  1563. it is still pending, a dummy response is sent at once; otherwise, this
  1564. request is ignored.  See the dispatcher module for details about the
  1565. parameters to this call.
  1566.  
  1567.  
  1568.  
  1569.    void  ipc_in_abortreply(client_id,code,data_ptr)
  1570.  
  1571.  
  1572.  
  1573. is the procedure used by the IPC module to receive responses from the
  1574. transport module after a call to xxx_sendrequest for a request to
  1575. abort a pending RPC.  See the transport module for details about the
  1576. parameters to this call.
  1577.  
  1578.  
  1579.  
  1580.    void  ipc_retry(port_rec_ptr)
  1581.    port_rec_ptr_t                port_rec_ptr;
  1582.  
  1583.  
  1584.  
  1585. is called from other modules when a message transmission should be
  1586. retried following some change in the port records.  It will cause the
  1587. retransmission to be executed in a special ``resend'' thread distinct
  1588. from the one making the ipc_retry call.
  1589.  
  1590.  
  1591.  
  1592.    void  ipc_freeze(port_rec_ptr)
  1593.    port_rec_ptr_t                port_rec_ptr;
  1594.  
  1595.  
  1596.  
  1597. is called from other modules when the status of a port becomes such
  1598. that no further transmissions should be attempted to that port.
  1599. Transmission will be resumed when ipc_retry is called.
  1600.  
  1601.  
  1602.  
  1603. 7.   Port Operations
  1604.  
  1605.  
  1606.  
  1607. 7.1.   Description
  1608.  
  1609.  
  1610.  
  1611. The functions provided by the port operations module are called in one
  1612. of the following three circumstances:
  1613.  
  1614.  
  1615.  
  1616. 1.  A message is received from the local kernel notifying the network
  1617.     server about a change in condition of a local port.  These changes
  1618.     are:
  1619.  
  1620.           o the death of the local port;
  1621.  
  1622.           o the transfer of port access rights to another task
  1623.             (probably because the task holding the rights has died);
  1624.             and
  1625.  
  1626.           o the local unblocking of the port.
  1627.  
  1628. 2.  A message is received over the network notifying the network
  1629.     server of a change in the remote network port's condition.  The
  1630.     possible changes are as for the local case except that they should be
  1631.     interpreted in the context of the remote port.
  1632.  
  1633. 3.  Access rights to a port are being transferred in a normal IPC
  1634.     message which is about to be sent to a remote network server or has
  1635.     been received from a remote network server.
  1636.  
  1637.  
  1638.                   20
  1639.  
  1640.  
  1641. The behavior of the port operations module depends on whether the port
  1642. that it is handling must be treated securely or not.  For instance, if
  1643. send rights to a port are being transferred in an IPC message and the
  1644. port is meant to be secure, then a token should be created for the
  1645. port and transferred along with the network port identifier when the
  1646. message is sent to the remote network server.  Similarly, at the
  1647. receiving end, the port operations module should store the token in
  1648. the network port's record.  However, if the port is not meant to be
  1649. treated securely, then no transfer and storing of a token need be
  1650. done.
  1651.  
  1652.  
  1653. In general the port operations module will often have to directly
  1654. modify the port's records, it may retry or freeze the sending of an
  1655. IPC message, it may initiate a port search, or, when port rights are
  1656. being transferred, it will provide the information that must be sent
  1657. to the remote network server.  Conversely, it must process this
  1658. information when the information is received from a remote network
  1659. server.  In addition, when it is considering a secure port, it may
  1660. have to generate or check a token for the port or it may have to
  1661. transfer or check the key that represents receive or ownership rights
  1662. to the port.
  1663.  
  1664.  
  1665.  
  1666. 7.2.   Interface
  1667.  
  1668.  
  1669.  
  1670.    boolean_t  po_init()
  1671.  
  1672.  
  1673.  
  1674. initializes the port operations module.
  1675.  
  1676.  
  1677.  
  1678.    po_check_ipc_seq_no(port_rec_ptr,  host_id,  ipc_seq_no)
  1679.    port_rec_ptr_t                port_rec_ptr;
  1680.    netaddr_t                         host_id;
  1681.    long                                 ipc_seq_no;
  1682.  
  1683.  
  1684.  
  1685. checks that the incoming IPC sequence number of a message is greater
  1686. that the last sequence number received for the network port with port
  1687. record port_rec_ptr from the network server on machine host_id.  This
  1688. check is only done for secure messages and ensures that complete IPC
  1689. messages cannot be replayed by a malicious party.
  1690.  
  1691.  
  1692.  
  1693.    typedef  struct  {...}  secure_info_t,  *secure_info_ptr_t;
  1694.  
  1695.  
  1696.  
  1697. is used to hold the key representing receiver or ownership rights to a
  1698. network port.
  1699.  
  1700.  
  1701.  
  1702.    long  po_create_token(port_rec_ptr,  token_ptr)
  1703.    port_rec_ptr_t                port_rec_ptr;
  1704.    secure_info_ptr_t           token_ptr;
  1705.  
  1706.  
  1707.  
  1708. creates a token for a port.  Stores the token in token_ptr and returns
  1709. the random number used to construct the token.
  1710.  
  1711.  
  1712.  
  1713.    void  po_notify_port_death(port_rec_ptr)
  1714.    port_rec_ptr_t                port_rec_ptr;
  1715.  
  1716.  
  1717.  
  1718. triggers handling of a local port death.  Marks the port's record as
  1719. deleted, sends out an unreliable port death notification messages and
  1720. does other local cleanups.
  1721.  
  1722.  
  1723.                   21
  1724.  
  1725.  
  1726. void  po_port_deallocate(lport)
  1727. port_t                              lport
  1728.  
  1729.  
  1730.  
  1731. deallocates a port but retains send rights to it.  This allows the
  1732. network server to transfer receive or ownership rights to a port to a
  1733. local task using the notification mechanism of the kernel.
  1734.  
  1735.  
  1736.  
  1737.    int  po_translate_lport_rights(client_id,lport,right,security_level,
  1738.                              destination_hint,port_data)
  1739.    int                                   client_id;
  1740.    port_t                              lport;
  1741.    int                                   right;
  1742.    int                                   security_level;
  1743.    netaddr_t                         destination_hint;
  1744.    pointer_t                         port_data;
  1745.  
  1746.  
  1747.  
  1748. is called by the IPC module to pack up the data that needs to be sent
  1749. to the host destination_hint in order to transfer the access rights
  1750. right to port lport.  The data that needs to be sent depends on the
  1751. security_level of the transfer.  The data is packed into the space
  1752. pointed to by port_data and the size of the network port data that has
  1753. been created is returned as the function's result.  The client_id is
  1754. an identifier remembered by the port operations module so that it can
  1755. match up a subsequent po_port_rights_commit (see below) with this call
  1756. of po_translate_lport_rights.
  1757.  
  1758.  
  1759.  
  1760.    po_port_rights_commit(client_id,  completion_code,  destination)
  1761.    int                                   client_id;
  1762.    int                                   completion_code;
  1763.    netaddr_t                         destination;
  1764.  
  1765.  
  1766.  
  1767. informs the port operations module that a transfer of rights to a
  1768. remote network host has either succeeded or failed.  The client_id
  1769. allows the port operations module to match this call with a previous
  1770. call of po_translate_lport_rights.  The completion_code can be one of
  1771. PO_RIGHTS_XFER_SUCCESS and PO_RIGHTS_XFER_FAILURE.  The destination
  1772. names the remote network server to which the port rights were actually
  1773. transferred.  It may be different from the destination_hint passed to
  1774. po_translate_lport_rights.
  1775.  
  1776.  
  1777.  
  1778.    int  po_translate_nport_rights(source,port_data,security_level,
  1779.                              lport,right)
  1780.    netaddr_t                         source;
  1781.    pointer_t                         port_data;
  1782.    int                                   security_level;
  1783.    port_t                              *lport;
  1784.    int                                   *right;
  1785.  
  1786.  
  1787.  
  1788. is called by the IPC module when it receives access rights to a remote
  1789. network port in a message from a remote network server.  The access
  1790. rights are contained in the data pointed to by port_data and were
  1791. received from the network server on host source and at security_level.
  1792. The port data received is handled according to what access rights are
  1793. being transferred and the local port corresponding to the network port
  1794. that was transferred is returned in lport.  In addition the actual
  1795. right transferred is returned in right and the size of the port data
  1796. that was processed is returned as the function's result.
  1797.  
  1798.  
  1799.                   22
  1800.  
  1801.  
  1802.    int po_handle_ro_xfer_request(request,from,broadcast,crypt_level)
  1803.  
  1804.  
  1805.  
  1806. is called by disp_indata_simple to handle an incoming transfer of
  1807. receiver or ownership rights.
  1808.  
  1809.  
  1810.  
  1811.    int po_handle_ro_xfer_reply(client_id,reply,from,broadcast,crypt_level)
  1812.  
  1813.  
  1814.  
  1815. is called by disp_rr_simple to handle the response to a transfer of
  1816. receiver or ownership rights.
  1817.  
  1818.  
  1819.  
  1820.    int  po_handle_ro_xfer_hint(request,from,broadcast,crypt_level)
  1821.  
  1822.  
  1823.  
  1824. is called by disp_indata_simple to handle an unreliable notification
  1825. of a transfer of receiver or ownership rights.
  1826.  
  1827.  
  1828.  
  1829.    int  po_handle_nport_death(hint,from,broadcast,crypt_level)
  1830.  
  1831.  
  1832.  
  1833. is called by disp_indata_simple to handle an unreliable notification
  1834. of the death of a network port.
  1835.  
  1836.  
  1837.  
  1838.    int  po_handle_token_request(request,from,broadcast,crypt_level)
  1839.  
  1840.  
  1841.  
  1842. is called by disp_indata_simple to handle an incoming request for a
  1843. token of receiver/owner authenticity.
  1844.  
  1845.  
  1846.  
  1847.    int po_handle_token_reply(client_id,reply,from,broadcast,crypt_level)
  1848.  
  1849.  
  1850.  
  1851. is called by disp_rr_simple to handle the response to a request for a
  1852. token of receiver/owner authenticity.
  1853.  
  1854.  
  1855.  
  1856. 8.   Port Checkups
  1857.  
  1858.  
  1859.  
  1860. 8.1.   Description
  1861.  
  1862.  
  1863.  
  1864. The port checkups module does a periodic probing of other network
  1865. servers to find out whether the status of network ports has changed.
  1866. In particular, it is the default way in which the network server finds
  1867. out about the death of a network port or the fact that receive or
  1868. ownership rights have moved to a different network server.  These
  1869. special conditions can also be detected as part of the normal
  1870. transmission of IPC messages across the network.  The port checkups
  1871. routine should only be called periodically and when the network server
  1872. is otherwise idle; in other words it is of low priority.
  1873.  
  1874.  
  1875. The checkups module needs to be able to look at the port records in
  1876. order to examine a ``aliveness'' parameter associated with each port
  1877. record.  The aliveness parameter is decremented by the port checkups
  1878. module every time it is called.  Only when it goes below some
  1879. predetermined value, is a checkup performed for the port.  Moreover,
  1880. the aliveness
  1881.  
  1882.  
  1883.                   23
  1884.  
  1885.  
  1886. parameter is updated to fully-alive when the IPC module has
  1887. successfully sent a message over the network to the port.  In other
  1888. words, if the port is in regular use then no checkup is done for it.
  1889.  
  1890.  
  1891. When the checkups module actually decides to send a checkup request to
  1892. find out about ports, it constructs an sbuf for each network server
  1893. that it must query.  An sbuf contains the ports in which it is
  1894. interested for which it believes the remote network server is
  1895. responsible.  To transmit and receive checkup information across the
  1896. network, the port checkups module uses the simple request-response
  1897. transport protocol.  After making a request by calling srr_send, the
  1898. checkups module will either receive a checkup reply or a failure
  1899. notification from the transport module.
  1900.  
  1901.  
  1902. On receiving a checkup request, the checkups module looks at each port
  1903. contained in the request.  If the information about the port that the
  1904. requester sent does not match the information held locally, then the
  1905. port in the checkup packet is marked as being ``bad''.  The checkup
  1906. reply packet is then sent back to the requester.
  1907.  
  1908.  
  1909. On receiving a checkup reply, the requester examines all the ports in
  1910. the reply and for those ports with a ``bad'' status it calls the port
  1911. search module.  It is up to the port search module to find out more
  1912. about the status of the port.  If no response was received to the
  1913. checkup request then the checkups module must call the port search
  1914. module for each port in the checkup request in order to resolve the
  1915. port's status (e.g.  to determine whether it is dead).
  1916.  
  1917.  
  1918. One other function of the checkups module is to determine whether
  1919. there exist any tasks with send rights to each port the network server
  1920. knows about.  This is in order to extend the MACH ``no-senders''
  1921. notification message into the network environment.  The checkups
  1922. module can determine that a network port has no senders if there has
  1923. been no interactions (the reception of either an IPC message or a
  1924. checkup request) involving this port for some period of time
  1925. (typically some number of checkup rounds).  If the network port has no
  1926.  
  1927.