home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / mach / doc / unpublished / netmsgserver.doc.Z / netmsgserver.doc
Encoding:
Text File  |  1992-08-18  |  91.1 KB  |  3,259 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.                Network  Server  Design
  8.  
  9.  
  10.  
  11.                MACH  Networking  Group
  12.  
  13.  
  14.  
  15.              September  21,  1989
  16.  
  17.  
  18.  
  19. 1.   Introduction
  20.  
  21.  
  22.  
  23. The network server is responsible for extending the local MACH
  24. Inter-Process Communication abstraction over the network which
  25. interconnects MACH hosts.  We have designed and implemented a new
  26. version of the network server in a way in which we hope makes it more
  27. efficient, easier to understand, more modular and easier to extend.
  28. In particular we intend to use this new network server to experiment
  29. with various ideas in the area of distributed systems networking, such
  30. as:
  31.  
  32.  
  33.     o     evaluating the merits of various protocols for network
  34.     interprocess communication ---  in  particular, we want to examine:
  35.  
  36.           -  connection-oriented  versus  connectionless  protocols,
  37.  
  38.           -  request-response  protocols  for  remote  procedure  calls,  and
  39.  
  40.       -  the use of special-purpose protocols depending on the size or the
  41.              destination of
  42.              the  data  to  be  transported;
  43.  
  44.     o evaluating various models for the distribution of network
  45.       functions between the operating system kernel and user
  46.       processes, and how these two components should interact;
  47.  
  48.     o security  in  the  network  environment;
  49.  
  50.     o multicast  groups,  and  associated  delivery  problems;  and
  51.  
  52.     o copy-on-reference  operations  over  a  network.
  53.  
  54.  
  55. This document describes the design of the network server and details
  56. the interfaces to the modules that are used to implement it.  It is
  57. intended for implementers rather than users.  This document reflects
  58. the current state of the implementation, and does not constitute a
  59. commitment for future developments.
  60.  
  61.  
  62. In the next section the overall design of the network server is
  63. explained.  The subsequent sections describe the structure of
  64. individual modules.
  65.  
  66.  
  67.  
  68. 2.   Overall Structure
  69.  
  70.  
  71.  
  72. 2.1.   General Operation
  73.  
  74.  
  75.  
  76. The set of all network servers on a network cooperate to provide IPC
  77. (Inter-Process Communication) between processes on different hosts on
  78. that network.  They achieve that
  79.  
  80.  
  81.                   1
  82.  
  83.  
  84. cooperation by exchanging Network Server Messages.  Some of these
  85. messages contain the data of IPC messages that are to be transported
  86. across the network, while others are used by the network servers to
  87. communicate information about the status of the operations in
  88. progress, and to maintain a consistent view of the location of the
  89. ports used in the network environment.  A small dispatcher header is
  90. used to distinguish between these various network server messages.
  91.  
  92.  
  93. The network servers maintain a space of Network Ports and each network
  94. server maintains a mapping between ports local to its host and network
  95. ports.  Each network port is represented by a Network Port Identifier
  96. which contains information to locate the receiver and owner for the
  97. network port and information which allows the security of the Mach
  98. port abstraction to be maintained in the network environment.  (See
  99. [2] for further details.)
  100.  
  101.  
  102.  
  103. 2.2.   Control Structure
  104.  
  105.  
  106.  
  107. The server is structured as a collection of threads sharing the same
  108. address space.  Each thread is used to perform one specific task
  109. asynchronously with the other threads.  Typically, there is one thread
  110. for each ``wait point'' in the system.  Wait points are most often
  111. waits for IPC messages.  The thread is awakened whenever something
  112. happens at this wait point, performs all operations pertinent to the
  113. current event, and goes back to sleep.  Should the service of an event
  114. require a further wait, another thread is signalled and asked to
  115. continue operations after that wait.  In general, one thread should
  116. not have more than one wait point.  Appropriate locking facilities are
  117. used where threads must share access to data structures.  There are a
  118. fixed number of threads in the system:
  119.  
  120.  
  121.  
  122. Timer    Used by all the other threads whenever they need to schedule
  123.     some action to take place at some given time in the future.
  124.     The most common use of this facility is to schedule packet
  125.     retransmission.
  126.  
  127. IPC Send Waits for messages to arrive on any of the ports that are
  128.     local representatives of remote network ports.  Upon reception
  129.     of such a message, performs the necessary translations and
  130.         initiates transmission on the network.  This thread does not wait
  131.         for the transmission to complete; subsequent actions will be
  132.     taken by the timer thread or by a transport receive thread.
  133.  
  134. IPC Re-Send is awakened when some other thread or some external
  135.     condition indicates that a message previously handled by the
  136.     IPC send thread should be re-sent either to the original or to
  137.         another destination.  It essentially performs the same
  138.     functions as the IPC send thread, but might take advantage of
  139.         some work already done by the ormer.  This thread is called
  140.     into action when a port is not found at the expected location,
  141.     when a remote port is blocked, or when network errors occur.
  142.  
  143. Transport Receive (One or more per each transport protocol.)  Waits
  144.     for packets to arrive from the network interface.  Processes
  145.     these packets, perhaps assembling multiple packets into
  146.     contiguous data and perhaps matching incoming packets with
  147.     previously queued outgoing transmissions.  Passes IPC and
  148.     other network server data received from remote network servers
  149.     on to higher level modules for further processing.  As
  150.         suggested above, this thread may use the services of the timer
  151.     thread to schedule retransmissions of packets and to determine
  152.     when a transmission should be aborted.
  153.  
  154. Notify Messages Waits for notify messages from the kernel to arrive on
  155.     the server's notify port.  These messages indicate changes in
  156.     the status of local ports (death, movements of rights or local
  157.     IPC message accepted).  Takes appropriate action in
  158.     each case to update the server's records and may destroy a
  159.     port, transfer access
  160.  
  161.  
  162.                   2
  163.  
  164.  
  165.     rights to a network port to a remote network server or signal
  166.     the IPC re-send thread to retry a message transmission.
  167.  
  168. Name Service Handles requests from other tasks for network name
  169.     service.  Allows names to be looked up on this host, on a
  170.     specific remote host or by broadcasting to all hosts.
  171.  
  172. Key Management Handles messages from the external Key Distribution
  173.     Server.  These messages tell the network server to use new
  174.     encryption keys for remote hosts.
  175.  
  176. Other Services A number of other threads may be used to provide other
  177.     services included with the network server, such as monitoring
  178.     and specialized name services.  In each case, the thread is
  179.     waiting for requests on a particular service port.
  180.  
  181.  
  182.  
  183. In addition, if the operations to be performed upon reception of a
  184. network message are too long, the Transport Receive threads may hand
  185. the message to other specialized processing threads, in order to
  186. remain available for new network messages.  Note that it is
  187. impractical to allocate one thread to each IPC message in transit due
  188. to resource limitations.
  189.  
  190.  
  191.  
  192. 2.3.   Code Structure
  193.  
  194.  
  195.  
  196. The code is distributed between several modules, each pertaining to
  197. some specific set of related operations or the management of some data
  198. structure.  The main modules are:
  199.  
  200. Port Records Operations for the handling of port records.  The main
  201.     data structure used is a database of port records, which
  202.     maintains a mapping between local ports and network port
  203.     identifiers, as well as keeping general status information on the
  204.     ports themselves.  Almost every module uses this database to
  205.     obtain information, and a number of modules modify the
  206.     information to reflect new situations that they have
  207.        detected.
  208.  
  209. Transport Protocols Provide the complete transport mechanism for a
  210.     block of data of arbitrary size over the network.  There are
  211.     several such modules implementing several protocols; some
  212.     guarantee reliable delivery, others don't.  Clients of the
  213.     transport protocols transmit messages by making a function
  214.     call into the transport module; for all incoming messages a
  215.     transport protocol calls a dispatcher function to deliver the
  216.     message.
  217.  
  218. Dispatcher Dispatches incoming network messages assembled by the
  219.     transport protocols to the appropriate module according the
  220.     dispatcher type contained in the network message header.  The
  221.     handler functions are directly called by the dispatcher.
  222.  
  223. IPC Message Handling Provides operations for receiving local IPC
  224.     messages and handing them to the transport layer, and
  225.     receiving messages from the transport layer and handing them
  226.     to the local user processes.  To do this it must translate IPC    
  227.     messages to and from a format appropriate for transmission on
  228.     the network.  In particular it must translate ports, identify
  229.     out-of-line data and, if necessary perform byte-swapping (this
  230.     corresponds to the ISO presentation layer roughly).  It also
  231.     handles the blocking mechanism for network ports.
  232.  
  233. Port Operations Provides all port translation functions for the IPC
  234.     module.  Also handles transfers and deletion of port access
  235.     rights due to the reception of notify messages from the kernel
  236.     and from remote network servers.
  237.  
  238.  
  239.  
  240.                   3
  241.  
  242.  
  243. Port Checkups Periodically verifies the information maintained in the
  244.     local port records by consulting other network servers.
  245.  
  246. Port Search Implements the sequence of operations needed to update the
  247.     information kept about a remote port when it is believed that
  248.     the current information is incorrect.  The checkups module
  249.     calls this module when it finds an inconsistency in the
  250.     information maintained about a port.
  251.  
  252. Key Management Maintains a mapping between remote hosts and the keys
  253.     that should be use to encrypt secure messages.  Also responsible for
  254.     interfacing with the key distribution server to obtain new
  255.     keys for remote hosts.
  256.  
  257. Crypt Provides functions to encrypt and decrypt network messages.
  258.  
  259. Network Name Service Provides a simple, host-directed network name
  260.     look up service.
  261.  
  262. Memory Management Provides allocation and deallocation functions for
  263.     all memory objects used in the network server.
  264.  
  265. Read/Write Lock Provides functions implementing read/write locks with
  266.     multiple users.
  267.  
  268. Locked Queue Operations on shared (i.e.  locked) queues of objects.
  269.  
  270. Timer Service Allows other modules to schedule actions after a
  271.     specified interval.
  272.  
  273.  
  274.  
  275. Other, miscellaneous modules provide for the generation of unique
  276. identifiers, the initialization of the network server, the actual
  277. transmission of datagrams over the network, and other ancillary
  278. functions.
  279.  
  280.  
  281.  
  282. 2.4.   Data Representation
  283.  
  284.  
  285.  
  286. There are a number of circumstances during the processing of IPC
  287. messages when the server has to manipulate large amounts of data.  In
  288. order to minimize overhead, large blocks of data are represented in a
  289. special format designed to limit the need for data copying and space
  290. allocation.
  291.  
  292.  
  293. Any conceptually contiguous block of data may be stored internally as
  294. a set of separate segments of any size, and a special sbuf
  295. (Segmented Buffer) structure is used to identify the segments
  296. constituting one block.  No special meaning is attached to how a block
  297. is segmented, i.e.  the segments do not necessarily represent logical
  298. parts of a block of data.  The segments reside in shared memory and
  299. are accessible by every thread.  Data modification and data transfer
  300. between modules are accomplished by operations on sbufs (typedef
  301. struct {...}  sbuf_t, *sbuf_ptr_t).
  302.  
  303.  
  304. For instance, if some data must be inserted at the head or the tail of
  305. some existing buffer, a new segment is allocated and placed at the
  306. right location in the sbuf.  If some data inside a buffer must be
  307. modified (possibly changing its length), the sbuf is modified so that
  308. the target data spans complete segments only, and those segments are
  309. replaced in the sbuf by new segments containing the modified data.
  310.  
  311.  
  312. Maximum efficiency for the allocation and deallocation of space for
  313. the segments cannot be attained with a general mechanism,
  314. consequently, space management is handled on a case by case basis by
  315. the modules that use sbufs and is private to an individual module.
  316. The information needed to deallocate the space used by segments of a
  317. given sbuf is not kept in the sbuf itself, but is recorded by the
  318. module that created each particular segment.  To simplify
  319. record-keeping, no segment may be referenced in more than one (public)
  320. sbuf.
  321.  
  322.  
  323.  
  324.                                                                 4
  325.  
  326.  
  327. Typically, when an sbuf is passed between modules, the system provides
  328. a call-back procedure to signal the module that created the sbuf that
  329. it is no longer needed.
  330.  
  331.  
  332. Special macros are provided to extract data from an sbuf, making its
  333. structure transparent to most modules.  Special macros are also
  334. provided for inserting data, but for performance reasons, they cannot
  335. be made entirely transparent.
  336.  
  337.  
  338.  
  339. 3.   Port Records
  340.  
  341.  
  342.  
  343. 3.1.   Description
  344.  
  345.  
  346.  
  347. The port record module maintains all the data associated with ports.
  348. In particular it enables the network server to map local to network
  349. and network to local ports.  An individual port record:
  350.  
  351.  
  352.  
  353.    typedef  struct  {...}  port_rec_t,  *port_rec_ptr_t;
  354.  
  355.  
  356.  
  357. contains the local port, the network port, status information about
  358. the port, several fields used by the IPC module, several fields for
  359. security, a reference count and a read/write lock.
  360.  
  361.  
  362. A  network  port  identifier  has  the  following  structure:
  363.  
  364.  
  365.  
  366.    typedef  struct  {
  367.           long             np_uid_high;
  368.           long             np_uid_low;
  369.    }  np_uid_t;
  370.  
  371.  
  372.  
  373.    typedef  struct  {
  374.           netaddr_t    np_receiver;
  375.           netaddr_t    np_owner;
  376.           np_uid_t       np_puid;
  377.           np_uid_t       np_sid;
  378.    }  network_port_t,  *network_port_ptr_t;
  379.  
  380.  
  381.  
  382. where the np_puid is the network port's Public Unique Identifer and
  383. the np_sid is the port's Secret Identifer.
  384.  
  385.  
  386.  
  387.    typedef  unsigned  long  netaddr_t;
  388.  
  389.  
  390.  
  391. is used to identify all network addresses within the network server.
  392.  
  393.  
  394.  
  395. 3.2.   Interface
  396.  
  397.  
  398.  
  399.    boolean_t  pr_init()
  400.  
  401.  
  402.  
  403. initializes  the  port  records  module.
  404.  
  405.  
  406.                   5
  407.  
  408.  
  409.    void  pr_reference(port_rec_ptr)
  410.    port_rec_ptr_t  port_rec_ptr;
  411.  
  412.  
  413.  
  414. increments the reference count for the port record.
  415.  
  416.  
  417.  
  418.    void  pr_release(port_rec_ptr)
  419.    port_rec_ptr_t  port_rec_ptr;
  420.  
  421.  
  422.  
  423. decrements the reference count for the port record, unlocks it and
  424. frees all memory associated with it if the reference count becomes
  425. zero.
  426.  
  427.  
  428.  
  429.    void  pr_destroy(port_rec_ptr)
  430.    port_rec_ptr_t                port_rec_ptr;
  431.  
  432.  
  433.  
  434. logically destroys a port record by removing it from all tables and
  435. deallocating the local port associated with it.  The actual space
  436. occupied by the port record is not freed until the reference count
  437. becomes zero, but this function performs one pr_release before
  438. exiting.
  439.  
  440.  
  441.  
  442.    port_rec_ptr_t  pr_np_puid_lookup(np_puid)
  443.    np_uid_t                         np_puid;
  444.  
  445.  
  446.  
  447. looks up and locks a port record given a network port's public unique
  448. identifier.
  449.  
  450.  
  451.  
  452.    extern  port_rec_ptr_t  pr_nportlookup(nport_ptr)
  453.    network_port_ptr_t        nport_ptr;
  454.  
  455.  
  456.  
  457. looks up and locks a port record given a network port.
  458.  
  459.  
  460.  
  461.    portrec_ptr_t  pr_ntran(nport_ptr)
  462.    network_port_ptr_t        nport;
  463.  
  464.  
  465.  
  466. looks up and locks a port record given a network port, creating a new
  467. port record and allocating a new local port if necessary.
  468.  
  469.  
  470.  
  471.    extern  port_rec_ptr_t  pr_lportlookup(lport)
  472.    port_t                            lport;
  473.  
  474.  
  475.  
  476. looks up and locks a port record given a local port.
  477.  
  478.  
  479.  
  480.    portrec_ptr_t  pr_ltran(lport)
  481.    port_t                            lport;
  482.  
  483.  
  484.  
  485. looks up and locks a port record given a local port, creating a new
  486. port record and allocating a new network port if necessary.
  487.  
  488.  
  489.                   6
  490.  
  491.  
  492.    boolean_t  nport_equal(nport_ptr_1,nport_ptr_2)
  493.    network_port_ptr_t        nport_ptr_1;
  494.    network_port_ptr_t        nport_ptr_2;
  495.  
  496.  
  497.  
  498. tests to see if two network ports are equal.
  499.  
  500.  
  501.  
  502.    void  pr_nporttostring(nport_str,nport_ptr)
  503.    char                               *nport_str;
  504.    network_port_ptr_t        nport_ptr;
  505.  
  506.  
  507.  
  508. returns in nport_str a printable representation of a network port.
  509.  
  510.  
  511.  
  512.    lock_queue_t  pr_list()
  513.  
  514.  
  515.  
  516. returns a list of all the local ports for which there is a port
  517. record.  (See the section on locked queues for the definition of
  518. lock_queue_t.)
  519.  
  520.  
  521. In general, all functions that return a port record lock that record
  522. before returning.  Functions that take a port record as an argument
  523. require that record to be already locked on entry.  The reference
  524. count normally reflects the presence of the port record in both the
  525. local and global tables, but no additional reference is taken by any
  526. of the above functions when returning a locked port record.  Note that
  527. these functions will block on the lock if the record is already
  528. locked.
  529.  
  530.  
  531.  
  532. 4.   Transport Protocols
  533.  
  534.  
  535.  
  536. 4.1.   Description
  537.  
  538.  
  539.  
  540. Several transport modules co-exist within the network server, each of
  541. them implementing a different protocol.  Some protocols under
  542. consideration are Delta-t, VMTP, NETBLT, TCP, UDP, and various
  543. multicast schemes.  It is up to clients of the transport modules to
  544. choose the one that satisfies their needs best.  All the transport
  545. modules deliver messages into the same dispatcher, and are accessed
  546. via separate entry points, grouped into a table similar to the Mach
  547. device table.
  548.  
  549.  
  550. The organization of each protocol module is up to each implementor.
  551. Layered and non-layered approaches are both acceptable, as well as the
  552. use of external servers, not residing in the same address space as the
  553. network server.  Implementors are encouraged to use the sbuf mechanism
  554. to represent and manipulate data internally, and to copy data only at
  555. the last level before the network interface.  The timer module is
  556. available for handling periodic retransmission and other protocol
  557. functions needing timeouts.
  558.  
  559.  
  560.  
  561. 4.2.   Interface
  562.  
  563.  
  564.  
  565. Because of an ongoing revision of the implementation, there are
  566. currently two modes of operation for transport modules.
  567.  
  568.  
  569. The first mode of operation specifies a simple send operation to
  570. transmit a message to a given destination.  It is used by all modules
  571. except the IPC module, to exchange information with the corresponding
  572. modules in the network servers at other nodes.
  573.  
  574.  
  575.                   7
  576.  
  577.  
  578. The second mode of operation specifies a request-response interaction,
  579. in which one node (the client) sends a request to another node (the
  580. server), and then awaits the reception of exactly one response from
  581. that server.  The transport protocol always supports the transmission
  582. of a 32-bit completion code in the response, and may optionally
  583. support the transmission of data in that same response.  This mode of
  584. operation is used by the IPC module for the transmission of IPC
  585. message data; it is intended to be the standard for all transport
  586. protocols, and all other modules will be converted to use it.
  587.  
  588.  
  589. Currently, each specific transport module only implements one or the
  590. other mode of operation; and can therefore be used either by the IPC
  591. module or by all other modules, but not both.  In the future, all
  592. modules will be converted to the second mode of operations.
  593.  
  594.  
  595. The following table is used to hold all the entry points for all the
  596. possible transport modules.  Each transport module is assigned a
  597. specific number, to be used as an index into this table when invoking
  598. it, and to be used to identify it when it delivers a message to the
  599. upper level.
  600.  
  601.  
  602.  
  603.    typedef  struct  {
  604.           int              (*send)();
  605.           int              (*sendrequest)();
  606.           int              (*sendreply)();
  607.    }  transport_sw_entry_t;
  608.  
  609.  
  610.  
  611. The entries in this table are filled by each transport module when it
  612. initializes itself.  Any unused entry is set to the special function
  613. transport_no_function, which simply returns after emitting an error
  614. message.  The send entry is used for the simple send interface.  The
  615. sendrequest and sendreply entries are used for the request-response
  616. interface.  Any protocol supporting that interface must implement
  617. sendrequest, but not necessarily sendreply, as described above.
  618.  
  619.  
  620. In the following descriptions, xxx_ is used as a generic prefix, to be
  621. replaced by the name of each transport module.
  622.  
  623.  
  624.  
  625.    boolean_t  xxx_init()
  626.  
  627.  
  628.  
  629. initializes the transport module and places the entry points in the
  630. transport switch table.
  631.  
  632.  
  633.  
  634.    int  xxx_send(client_id,trid,data,to,service,crypt_level,cleanup)
  635.    int                                   client_id;
  636.    int                                   trid;
  637.    sbuf_ptr_t                       data;
  638.    netaddr_t                         to;
  639.    int                                   service;
  640.    int                                   crypt_level;
  641.    int                                   (*cleanup)();
  642.  
  643.  
  644.  
  645. attempts to send message data to destination to.  client_id is an ID
  646. used by the client to identify this message.  trid is a
  647. transport-level ID used to identify a current request-response
  648. interaction; it should be 0 if not used.  service is the kind of
  649. service required for this message; possible values are:
  650.  
  651.  
  652.                   8
  653.  
  654.  
  655.     o TRSERV_NORMAL:  normal  transmission  of  a  single  message.
  656.  
  657.     o TRSERV_IPC: transmission of an IPC message, ``call-back''
  658.       required.  (OBSOLETE)
  659.  
  660.     o TRSERV_RPC: transmission part of a request-response at the IPC
  661.       level.  Pairing information required and ``call-back'' required.
  662.       Note that the ``call-back'' can be implicitly be the delivery of
  663.       the response if the RPC succeeds.  (OBSOLETE)
  664.  
  665.     o TRSERV_URGENT: transmission of an urgent single message, to be
  666.       delivered before other non-urgent transmissions in progress if
  667.       possible.
  668.  
  669.  
  670.  
  671. crypt_level determines what kind of encryption should be used to
  672. protect the data.  Possible levels of encryption include:
  673. CRYPT_DONT_ENCRYPT and CRYPT_ENCRYPT.  cleanup is a function supplied
  674. by the client, to be called when the transmission is complete and the
  675. message data is no longer needed.  Depending on the service requested,
  676. it may indicate a simple local completion, or participate in the
  677. ``call-back'' mechanism.  It takes two arguments: the client ID, and a
  678. completion code.
  679.  
  680.  
  681. cleanup returns 0 when all is well.  xxx_send also returns a
  682. completion code to indicate the immediate local result of the call.
  683.  
  684.  
  685.  
  686.    int xxx_sendrequest(client_id,data,to,crypt_level,reply_proc) 
  687.    int        client_id; 
  688.    sbuf_ptr_t     data; 
  689.    netaddr_t     to; 
  690.    int         crypt_level;
  691.    int       (*reply_proc)();
  692.  
  693.  
  694. attempts to send a request containing data to destination to.
  695. client_id is an ID used by the client to identify this
  696. request-response interaction.  crypt_level determines what kind of
  697. encryption should be used to protect the data.  Possible levels of
  698. encryption include: CRYPT_DONT_ENCRYPT and CRYPT_ENCRYPT.  reply_proc
  699. is a procedure to be called from the transport module to deliver a
  700. response.
  701.  
  702.  
  703. xxx_sendrequest returns either TR_SUCCESS or a specific failure code.
  704. In the first case, a request-response interaction is initiated, that
  705. will terminate when reply_proc is called.  The data supplied in the
  706. request must be kept valid by the caller for the whole duration of the
  707. request-response interaction.  The reply procedure is guaranteed to be
  708. called exactly once, with the following arguments:
  709.  
  710.  
  711.  
  712.    void  reply_proc(client_id,reply_code,data)
  713.    int                     client_id;
  714.    int                     reply_code;
  715.    sbuf_ptr_t          data;
  716.  
  717.  
  718.  
  719. client_id is the ID given as argument to xxx_sendrequest.  reply_code
  720. is a completion code supplied either by the transport module (in case
  721. of transport errors) or by the server process that handled the
  722. request.  data may contain data supplied by the server in the
  723. response, or it may by null.  This data is kept valid by the transport
  724. module only until reply_proc returns.
  725.  
  726.  
  727. If xxx_sendrequest returns anything other than TR_SUCCESS, no
  728. request-response interaction is initiated, and reply_proc is never
  729. called.
  730.  
  731.  
  732.  
  733.                                                                 9
  734.  
  735.  
  736. The handler on the server side of a request-response interaction is
  737. invoked via the dispatcher module (see below).  This handler must
  738. return a code that determines how the response is sent.  If this code
  739. is anything other than DISP_WILL_REPLY, a response containing that
  740. code and no data is immediately sent back by the transport module.  If
  741. this code is DISP_WILL_REPLY, no response is generated by the
  742. transport module, and the higher-level module must explicit call
  743. xxx_sendreply to terminate the request-response interaction:
  744.  
  745.  
  746.  
  747.    int  xxx_sendreply(trid,code,data,crypt_level)
  748.    int                     trid;
  749.    int                     code;
  750.    sbuf_ptr_t          data;
  751.    int                     crypt_level;
  752.  
  753.  
  754.  
  755. trid is a transport-level ID supplied by the dispatcher with the
  756. request.  code and data are the reply code and data to be used in the
  757. call to reply_proc on the client.  crypt_level determines what kind of
  758. encryption should be used to protect the data.  data can be null.  If
  759. it is not, the data must be kept valid by the caller only until
  760. xxx_sendreply returns.
  761.  
  762.  
  763. The procedure returns TR_SUCCESS or TR_FAILURE.  It is an error to
  764. call xxx_sendreply for a terminated request-response interaction,
  765. including one terminated by the handler returning a code other than
  766. DISP_WILL_REPLY.  Similarly, it is an error for the handler to return
  767. DISP_WILL_REPLY if the transport module in use does not implement
  768. xxx_sendreply.
  769.  
  770.  
  771. Note that since multiple threads are involved, the reply procedure may
  772. be called before xxx_sendrequest returns.  Similarly, it is acceptable
  773. for the server to call xxx_sendreply before returning from the handler
  774. procedure for the request, provided that this handler eventually
  775. returns DISP_WILL_REPLY.
  776.  
  777.  
  778. The  completion  codes  for  transport  operations  are:
  779.  
  780.  
  781.  
  782.     o TR_CRYPT_FAILURE: the transmission failed either because of a
  783.       local encryption or a remote decryption failure --- the local
  784.       client module should try and get a new key for the destination
  785.       host and then retry the transmission;
  786.  
  787.     o TR_SEND_FAILURE: something went wrong with the transmission
  788.       before any data could be sent.
  789.  
  790.     o TR_FAILURE: something went wrong with the transmission within
  791.       either the local or remote transport module; the error was
  792.       detected too late to return TR_SEND_FAILURE.
  793.  
  794.     o TR_OVERLOAD: the transport module is currently overloaded.  No
  795.       data was sent; the user should retry later.
  796.  
  797.     o TR_SUCCESS: the transmission was successful but it was not
  798.       possible to determine whether the message was accepted by the
  799.       remote client.
  800.  
  801.     o a client-specific completion code (see, for example, the codes
  802.       returned by the IPC module).
  803.  
  804.  
  805.  
  806. Note that the transport-specific completion codes are in the same
  807. space as the client-specific completion codes; care must be taken to
  808. avoid collisions.
  809.  
  810.  
  811.  
  812.                   10
  813.  
  814.  
  815. 4.3.   Specific Transport Protocols
  816.  
  817.  
  818.  
  819. 4.3.1.   Delta-t
  820.  
  821.  
  822.  
  823. Delta-t is a connectionless transport protocol in which each packet
  824. sent over the network is individually acknowledged by the destination
  825. network server before the next packet is sent.  All the
  826. transport-level protocol handling is performed in the network server;
  827. network access at the IP level is achieved through the Mach network
  828. interface described below.  Retransmissions are scheduled using the
  829. timer module.  In order to detect duplicate packets, information about
  830. an incoming data packet is maintained by a network server either until
  831. the next packet in a sequence is received or the information has been
  832. held more that some minimum amount of time.
  833.  
  834.  
  835. Delta-t currently implements the request-response interface without
  836. deltat_sendreply.
  837.  
  838.  
  839. Delta-t is suitable for transmitting messages containing small amounts
  840. of data (less than a few packets in total).  If the message is part of
  841. a RPC protocol in which the response to the request is expected
  842. shortly, then it is better to use a more specialized request-response
  843. protocol such as VMTP.
  844.  
  845.  
  846.  
  847. 4.3.2.   VMTP
  848.  
  849.  
  850.  
  851. VMTP (Versatile Message Transport Protocol) is the request-response
  852. protocol developed at Stanford by D.  Cheriton and his group [1 ].
  853. The VMTP module creates a single well-known server entity to receive
  854. all network requests, and keeps a pool of client entities to use on
  855. the client side to initiate transactions.  Whenever vmtp_sendrequest
  856. is called, an unused client entity is pulled out of that pool; it is
  857. returned to the pool when the reply is delivered.  The actual VMTP
  858. protocol handling module is in the kernel; it communicates with the
  859. network server using sockets.
  860.  
  861.  
  862. There are currently two versions of the VMTP module.  vmtp1 implements
  863. the simple send interface and should not be used.  vmtp2 implements
  864. the full request-response interface, and is suitable for IPC messages.
  865.  
  866.  
  867.  
  868. 4.3.3.   TCP
  869.  
  870.  
  871.  
  872. The TCP module keeps a pool of TCP connections to the network servers
  873. on other nodes.  Each connection is created when needed to transmit a
  874. request, and is kept open as long as possible to service further
  875. requests to the same destination.  Open connections are recycled using
  876. a least-recently-used policy to limit their number.  The protocol
  877. handling module is in the kernel; it communicates with the network
  878. server using sockets.
  879.  
  880.  
  881. TCP currently implements the full request-response interface, and is
  882. suitable for IPC messages.
  883.  
  884.  
  885.  
  886. 4.3.4.   Datagram
  887.  
  888.  
  889.  
  890. The ``datagram'' transport protocol simply provides an interface to
  891. the UDP level.  It allows unreliable datagrams to be sent over the
  892. network.
  893.  
  894.  
  895.  
  896.                   11
  897.  
  898.  
  899. Datagram currently implements the simple send interface and cannot be
  900. used to transmit IPC message data.
  901.  
  902.  
  903.  
  904. 4.3.5.   Simple Request-Response
  905.  
  906.  
  907.  
  908. The simple request-response protocol permits the sending of a request
  909. over the network for which a response is expected.  The data of the
  910. request is guaranteed to fit in one network datagram.  This protocol
  911. will treat responses as acknowledgements to requests and inform its
  912. client either of the failure of the request (if no response was
  913. received after some number of tries) or of the success of the request
  914. in which case the response is returned to the client.  It is assumed
  915. that a request can be handled without delay by the higher-level
  916. protocol and the response is supplied on return from the request call.
  917. Requests made using this protocol should be idempotent.
  918.  
  919.  
  920. Although SRR is oriented toward request-response interactions, it
  921. implements the simple send interface and not the request-response
  922. interface.  It cannot therefore be used to transmit IPC message data.
  923.  
  924.  
  925.  
  926. 5.   Dispatcher Module
  927.  
  928.  
  929.  
  930. 5.1.   Operation
  931.  
  932.  
  933.  
  934. The dispatcher module is responsible for invoking the correct handler
  935. procedure when some network message has been received.  It is called
  936. by the various transport modules, examines the dispatcher header, and
  937. selects the appropriate routine to call according to the message type
  938. (incoming IPC, port death, and so on).
  939.  
  940.  
  941. This module can optionally establish a separation between a network
  942. thread and one or more other threads used to process the messages at
  943. the network server level.  This last scheme is to be used if the
  944. network thread would not be fast enough if it had to completely
  945. process each message before listening to the net again.  Note that
  946. with this mechanism, care must be taken to avoid problems when a
  947. transport module deallocates the space used by incoming data before
  948. that data has been processed at the higher level.
  949.  
  950. To allow communication between machines with different data
  951. representation, the dispatcher header always use a standard
  952. representation.  The rest of each message uses whatever representation
  953. is in use on the sending machine; a code for that representation is
  954. stored in the dispatcher header and made available to the message
  955. handler modules.
  956.  
  957.  
  958. To allow future expansion, the dispatcher also checks a version number
  959. for each incoming message.
  960.  
  961.  
  962. 5.2.   Interface
  963.  
  964.  
  965. As discussed in 4.2, there are currently two transport interfaces, to
  966. which correspond two dispatcher interfaces.  The following table holds
  967. a set of entry points for each message type.
  968.  
  969.  
  970.    typedef  struct  {
  971.           int              (*disp_indata)();
  972.           int              (*disp_inprobe)();
  973.           int              (*disp_indata_simple)();
  974.           int              (*disp_rr_simple)();
  975.           int              (*disp_in_request)();
  976.    }  dispatcher_switch_t;
  977.  
  978.                   12
  979.  
  980.  
  981.  
  982.  
  983. All modules place entry points in the table for each message type and
  984. each type of handler procedure that they support and wish to receive
  985. messages for.  Unused entries are set to the special procedure
  986. disp_no_function; the network server is organized in such a way that
  987. there are not collisions in the table.
  988.  
  989.  
  990. disp_indata, disp_inprobe, disp_indata_simple and disp_rr_simple are
  991. called by transport modules using the simple xxx_send interface, and
  992. will eventually be eliminated.
  993.  
  994.  
  995. disp_in_request is the sole entry point used with the request-response
  996. interface.
  997.  
  998.  
  999.  
  1000.    int  disp_init()
  1001.  
  1002.  
  1003.  
  1004. initializes the dispatcher module.
  1005.  
  1006.  
  1007.  
  1008.    int  disp_indata(trid,data,from,tr_cleanup,trmod,
  1009.                              client_id,crypt_level,broadcast)
  1010.    int                                   trid;
  1011.    sbuf_ptr_t                       *data;
  1012.    netaddr_t                         from;
  1013.    int                                   (*tr_cleanup)();
  1014.    int                                   trmod;
  1015.    int                                   client_id;
  1016.    int                                   crypt_level;
  1017.    boolean_t                         broadcast;
  1018.  
  1019.  
  1020.  
  1021. is the primary function used to dispatch incoming data in the simple
  1022. send mode of operation.  trid is a transport level identifier assigned
  1023. by the transport module trmod.  It should be used in the call to
  1024. tr_cleanup which signals to the transport module that the higher-level
  1025. module is finished with the data contained in the sbuf data.  Other
  1026. arguments are: from, the host that sent the data; client_id, an
  1027. identifier assigned by the client module within a prior call to
  1028. disp_inprobe (see below); crypt_level, the encryption level used to
  1029. send data over the network; and broadcast whether the data was
  1030. broadcast or not.  disp_indata returns DISP_FAILURE is the dispatcher
  1031. module did not find a higher-level routine to be called for the
  1032. incoming message type or if the version number of the incoming message
  1033. did not match the current version number of this implementation of the
  1034. network server; otherwise it returns the value returned by the
  1035. higher-level routine.
  1036.  
  1037.  
  1038.  
  1039.    int  disp_inprobe(trid,pkt,from,cancel,trmod,
  1040.                              client_id,crypt_level,broadcast)
  1041.    int                                   trid;
  1042.    sbuf_ptr_t                       pkt;
  1043.    netaddr_t                         from;
  1044.    int                                   *((*cancel)());
  1045.    int                                   trmod;
  1046.  
  1047.  
  1048.                   13
  1049.  
  1050.  
  1051.    int                                   *client_id;
  1052.    int                                   crypt_level;
  1053.    boolean_t                         broadcast;
  1054.  
  1055.  
  1056.  
  1057. allows the first packet of a message to be dispatched to a
  1058. higher-level probe routine.  This allows the higher-level routine to
  1059. decide before-hand whether to accept or reject an incoming message.
  1060. If it decides to accept the message based on the probe packet, the it
  1061. returns a client_id to allow it to later identify the whole incoming
  1062. message.  cancel (an out parameter) is called by the transport module
  1063. if it is unable to deliver the complete message after a probe has been
  1064. accepted.  It takes as argument the client_id and a reason code.
  1065. Other parameters are as for disp_indata.
  1066.  
  1067.  
  1068.  
  1069.    int  disp_indata_simple(client_id,data,from,crypt_level,broadcast)
  1070.    int                                   client_id;
  1071.    sbuf_ptr_t                       data;
  1072.    netaddr_t                         from;
  1073.    int                                   crypt_level;
  1074.    boolean_t                         broadcast;
  1075.  
  1076.  
  1077.  
  1078. is similar to disp_indata except that it is guaranteed that the data
  1079. is processed at the higher-level within the same thread that made the
  1080. call.  Hence there is no need for a tr_cleanup call because, when the
  1081. dispatcher call returns, the transport module knows that the data is
  1082. no longer needed and can do the cleanup synchronously.
  1083.  
  1084.  
  1085.  
  1086.    int  disp_rr_simple(data,from,crypt_level,broadcast)
  1087.    sbuf_ptr_t                       data;
  1088.    netaddr_t                         from;
  1089.    int                                   crypt_level;
  1090.    boolean_t                         broadcast;
  1091.  
  1092.  
  1093.  
  1094. allows a transport-level protocol to make a simple request-response
  1095. interaction with a higher level module.  The higher-level module
  1096. should process the request immediately and include the response on
  1097. returning from the call.  Note that this procedure is intended for
  1098. request-response interactions within the simple send mode of
  1099. operations, and not within the full request-response interface
  1100. described above.
  1101.  
  1102.  
  1103.  
  1104.    int  disp_in_request(trmod,trid,data_ptr,from,crypt_level,broadcast);
  1105.    int                                   trmod;
  1106.    int               trid;
  1107.    sbuf_ptr_t               data_ptr;
  1108.    netaddr_t               from;
  1109.    int               crypt_level;
  1110.    boolean_t               broadcast;
  1111.  
  1112.  
  1113.  
  1114. is the single function for dispatching in the request-response mode of
  1115. operation.  The arguments are similar to those of disp_indata.  The
  1116. data pointed to by data_ptr is valid only until this procedure
  1117. returns.  Any return value other than DISP_WILL_REPLY is interpreted
  1118. by the transport module as a completion code to be returned
  1119. immediately in a response to the client.  DISP_WILL_REPLY means that
  1120. the higher-level module assumes the responsibility to send a response,
  1121. and the transport module should do nothing when this procedure returns
  1122. (other than deallocate the space occupied by the data, if
  1123.  
  1124.  
  1125.                   14
  1126.  
  1127.  
  1128. appropriate).  Note that if the dispatcher returns DISP_FAILURE, that
  1129. code is returned to the client in the normal way.
  1130.  
  1131.  
  1132. In subsequent sections of this document, functions which are called
  1133. via the dispatcher module do not have their arguments described.  The
  1134. arguments are exactly as for the corresponding dispatcher function.
  1135.  
  1136.  
  1137.  
  1138. 6.   IPC Message Handling
  1139.  
  1140.  
  1141.  
  1142. The IPC Message Transfer module implements the upper layer of the
  1143. mechanism used to communicate with remote ports.  It relies on a
  1144. separate transport module to provide the lower-level network
  1145. transmission operations, and communicates with it using sbufs.  To
  1146. maximize performance, the IPC module tries to identify messages that
  1147. are part of a remote procedure call (RPC), and attempts to map the
  1148. request-response structure of such calls into a request-response
  1149. interaction at the transport level.
  1150.  
  1151.  
  1152.  
  1153. 6.1.   Normal Operation
  1154.  
  1155.  
  1156.  
  1157. The IPC module receives messages addressed to ports that are local
  1158. representatives of remote ports.  Upon reception of such a local IPC
  1159. message, the IPC module
  1160.  
  1161.  
  1162.  
  1163. 1.  allocates a transaction record (ipc_rec) to keep information about
  1164.     the transfer in progress,
  1165.  
  1166. 2.  consults the port records to find the remote port corresponding to
  1167.     the local port,
  1168.  
  1169. 3.  generates an IPC Header to contain special information to be used
  1170.     by the remote network server,
  1171.  
  1172. 4.  translates the ports and out-of-line pointers in the message so
  1173.     that they will be intelligible on the receiving node, and
  1174.  
  1175. 5.  selects a transport protocol to use, and hands the whole message
  1176.     to the appropriate module via xxx_sendrequest.
  1177.  
  1178.  
  1179.  
  1180. Note that the breakup of the message into several packets is the task
  1181. of a transport module and not the IPC module.
  1182.  
  1183.  
  1184. All these operations are performed on a message represented using an
  1185. sbuf.  In general, the segments contained in the sbuf are:
  1186.  
  1187.  
  1188.  
  1189.     o the IPC receive buffer, containing the inline data;
  1190.  
  1191.     o each out-of-line data section;
  1192.  
  1193.     o the IPC header, allocated by this module; and
  1194.  
  1195.     o any special data structures needed for the message translation
  1196.       process, such as accessibility maps or a network port
  1197.       dictionary.
  1198.  
  1199.  
  1200.  
  1201. In the remote network server receiving the message, all the component
  1202. packets are assembled by the transport module, which calls the IPC
  1203. module and hands it an sbuf representing the whole message.  Typically
  1204. segments in that sbuf are part of packet
  1205.  
  1206.  
  1207.                   15
  1208.  
  1209.  
  1210. buffers in which the message was received.  The module uses ipc_rec
  1211. records to store information about current incoming messages.  It
  1212. performs all necessary translations (including byte-swapping and data
  1213. type conversion), copies the message into a send buffer, and delivers
  1214. it to its local destination.
  1215.  
  1216.  
  1217. The IPC module on the sending network server may not discard the
  1218. message immediately after calling the transport module to initiate a
  1219. transmission, because it may be necessary to effect a complete
  1220. retransmission, possibly to a new destination and with different
  1221. accompanying data.  This is the case when some exceptional events,
  1222. described in the next section, prevent the receiving network server
  1223. from delivering the message to its ultimate destination.  In addition,
  1224. some operations pertaining to security must be performed by the IPC
  1225. module on the sending node only when it is certain that the message
  1226. has been correctly transmitted.  For these reasons, the network server
  1227. on the receiving node uses the request-response transport mechanism to
  1228. return a completion code indicating if it was able to deliver the
  1229. message, or what happened if it was not.  Upon reception of this
  1230. completion code, the sending network server may deallocate its ipc_rec
  1231. and the message data, or undertake the appropriate recovery action in
  1232. case of error, including initiating a new transmission.
  1233.  
  1234.  
  1235.  
  1236. 6.2.   Exceptional Events
  1237.  
  1238.  
  1239.  
  1240. The exceptional events are detected either at the transport level or
  1241. by the IPC module in the remote network server.  They are reported to
  1242. the sending IPC module through the request-response completion code
  1243. described above.  The IPC module must then freeze the current
  1244. transmission, and call another module to deal with that exception.
  1245. That module may in turn request the IPC module to attempt to retry the
  1246. transmission of any pending messages for a given destination port,
  1247. possibly after changing some information in the port's record.  In
  1248. that case, the IPC module will restart processing of any affected
  1249. messages as if that message had just been received on a local port.
  1250. As an optimization, it could reuse some of the information already
  1251. gathered, and stored in the record for this pending message.
  1252.  
  1253.  
  1254. Exceptional  events  include:
  1255.  
  1256.  
  1257.  
  1258.     o Modification of a port record while a message for that port is
  1259.       in transit by some other thread running concurrently with the
  1260.       IPC sending thread (for example in response to a port death
  1261.       message).  It simply triggers re-processing of the message.
  1262.  
  1263.     o Network failure, detected by the transport module.  The IPC
  1264.       module must decide to abort or retry the message, and find out
  1265.       if the port is dead.
  1266.  
  1267.     o Crypt failure, detected by the transport module at the local or
  1268.       remote node when it does not possess the correct key to encrypt
  1269.       or decrypt the message.  The IPC module calls the key management
  1270.       module to establish a new key.
  1271.  
  1272.     o Remote port not found at the expected node, signalled by the
  1273.       receiving IPC module --- a port search procedure is initiated (in
  1274.       another thread), and its completion will decide whether the
  1275.       transmission is to be restarted or aborted.
  1276.  
  1277.     o Remote port blocked, signalled by the remote IPC module.  The
  1278.       sending node suspends the message until further notice and
  1279.       indicates the situation in its port record.  A ipc_block record
  1280.       for the sending node is allocated at the receiving node.  When
  1281.       the port becomes unblocked, the list of those records is scanned
  1282.       and a special PORT_UNBLOCKED message is transmitted to each
  1283.       waiting network server, to indicate that transmission should be
  1284.       restarted.  If this unblock message is lost then the
  1285.  
  1286.  
  1287.                   16
  1288.  
  1289.  
  1290.       port checkups module will discover that the port has become
  1291.       unblocked and will retry the message transmission.
  1292.  
  1293.  
  1294.  
  1295. To avoid blocking the message delivery thread in the receiving network
  1296. server, all messages are always delivered using the SEND_NOTIFY option
  1297. of msg_send.  If the return from msg_send indicates that the local
  1298. port has become blocked, no other messages will be accepted for that
  1299. port until the kernel indicates that it has been unblocked.
  1300. Appropriate marking and locking of the port record guarantees that no
  1301. two threads can be in the situation of exercising the SEND_NOTIFY
  1302. option on the same port at the same time.  Note that this mechanism
  1303. does not require the receiving network server to return a port blocked
  1304. indication for a message accepted under the SEND_NOTIFY option,
  1305. thereby allowing the actual message delivery to be performed in
  1306. another thread after the dispatcher procedure has returned (the
  1307. current implementation does not take advantage of this feature).
  1308.  
  1309.  
  1310.  
  1311. 6.3.   RPC Interactions
  1312.  
  1313.  
  1314.  
  1315. The IPC module offers an optimization for RPC interactions for which
  1316. the user is willing to accept some semantic restrictions:
  1317.  
  1318.  
  1319.  
  1320.     o the request message is followed by exactly one response message
  1321.       addressed to the reply port indicated in the request.
  1322.  
  1323.     o the reply port is local to the node issuing the request.
  1324.  
  1325.     o no new request is sent using the same reply port while awaiting
  1326.       a response on that reply port.
  1327.  
  1328.     o the  reply  port  is  not  deallocated  while  awaiting  a  response.
  1329.  
  1330.     o the receive rights for the reply port are not transferred while
  1331.       awaiting a response.
  1332.  
  1333.     o the reply port is not blocked or locked while awaiting a
  1334.       response.
  1335.  
  1336.  
  1337.  
  1338. If any of those rules is violated, the response is not guaranteed to
  1339. be delivered, or may be delivered out of order; the behavior of the
  1340. network server may vary from one instance of such an erroneous
  1341. situation to the next.  The user must specify the MSG_TYPE_RPC bit in
  1342. the msg_type field of the message header for the request to indicate
  1343. that he accepts those modified message semantics.
  1344.  
  1345.  
  1346. Whenever a valid request is received with the MSG_TYPE_RPC bit set,
  1347. the network server on the server side uses DISP_WILL_REPLY if possible
  1348. to delay the transmission of the completion code at the transport
  1349. level.  It keeps track of the pending request in a ipc_rec, and
  1350. considers a new IPC message destined to the reply port as the response
  1351. for the RPC interaction.  Instead of sending this message with a new
  1352. transport interaction, it places it in the response for the pending
  1353. interaction.  Because the transport interface does not provide an
  1354. end-to-end acknowledgment that the data portion of a response was
  1355. correctly handled by the IPC module on the client side, the network
  1356. server on the server side must rely on the above assumptions for
  1357. delivery of the response to the reply port.
  1358.  
  1359.  
  1360. This scheme also relies on the assumption that the response message
  1361. will eventually be sent from the same node that received the request
  1362. message, and that no other traffic involving the reply port takes
  1363. place until that response is delivered.  This assumption
  1364.  
  1365.  
  1366.  
  1367.                   17
  1368.  
  1369.  
  1370. may easily be invalidated both by erroneous actions on the part of the
  1371. client or server processes, or by normal operations such as request
  1372. forwarding.  Because resources in the transport module are tied up as
  1373. long as the response has not been delivered, the IPC modules on both
  1374. sides check for all events that may suggest that a response may not be
  1375. forthcoming in the normal way.  When any such event occurs, they force
  1376. the transmission of a dummy response to terminate the request-response
  1377. interaction, letting the real response, if any, proceed normally as a
  1378. new single IPC message.  The events causing such an abort include:
  1379.  
  1380.  
  1381.  
  1382.     o transfer of receive or ownership rights for the reply port.
  1383.  
  1384.     o transmission of a new message using the same reply port.
  1385.  
  1386.     o reception of a message on the reply port on the client side,
  1387.       from a source other the expected server.
  1388.  
  1389.     o reception of a message on the reply port on the server side,
  1390.       with the MSG_TYPE_RPC bit set.
  1391.  
  1392.     o timeout at the network server on the server side (triggered by
  1393.       the port checkups mechanism).
  1394.  
  1395.  
  1396.  
  1397. Note that none of these aborts compromise the semantics of an RPC;
  1398. they simply nullify the performance benefits of the RPC optimization
  1399. when the situation is not simple.  In addition, the network server
  1400. itself never sets the MSG_TYPE_RPC bit when delivering a message to a
  1401. local port, to avoid hidden forwarding problems.
  1402.  
  1403.  
  1404.  
  1405. 6.4.   Message Ordering
  1406.  
  1407.  
  1408.  
  1409. A weak ordering of message delivery is provided through the use of a
  1410. queue of pending transactions for each remote network port.  This
  1411. queue operates in the following way:
  1412.  
  1413.  
  1414.  
  1415.     o all outgoing RPC requests and single IPC messages are queued in
  1416.       the order in which they are received on the local port.
  1417.  
  1418.     o as long as there are only RPC requests on the queue, each is
  1419.       transmitted as soon as it is queued; the system does not wait for a
  1420.       response before transmitting the next
  1421.        request.
  1422.  
  1423.     o as soon as one single IPC message is queued, newer messages (IPC
  1424.       or RPC) are queued but not transmitted until that IPC message is
  1425.       successfully transmitted and dequeued (including any number of
  1426.       retransmissions).
  1427.  
  1428.     o RPC responses are never queued; they are transmitted at once and
  1429.       never retransmitted.
  1430.  
  1431.     o whenever the status of the network port changes, retransmissions
  1432.       are initiated as needed in the order in which records are on the
  1433.       queue.
  1434.  
  1435.     o the local port is locked when the queue becomes too long and new
  1436.       messages cannot be transmitted.
  1437.  
  1438.  
  1439.  
  1440. This strategy guarantees that single IPC messages directed at the same
  1441. destination port from the same node are strictly ordered.  RPC's are
  1442. naturally ordered simply because the client waits for the response
  1443. before issuing the next request.  There are no ordering guarantees for
  1444. a single IPC immediately following the request for a RPC.
  1445.  
  1446.  
  1447.                   18
  1448.  
  1449.  
  1450. 6.5.   Interface
  1451.  
  1452.  
  1453.  
  1454.    boolean_t  ipc_init()
  1455.  
  1456.  
  1457.  
  1458. initializes  the  IPC  module.
  1459.  
  1460.  
  1461.  
  1462.    int  ipc_in_request(trmod,trid,data_ptr,from,crypt_level,broadcast)
  1463.  
  1464.  
  1465.  
  1466. is called from disp_in_request when a RPC request or single IPC is
  1467. received over the network by a transport module.  It is the main entry
  1468. point for incoming messages.  See the dispatcher module for details
  1469. about the parameters to this call.
  1470.  
  1471.  
  1472.  
  1473.    void  ipc_in_reply(client_id,code,data_ptr)
  1474.  
  1475.  
  1476.  
  1477. is the procedure used by the IPC module to receive responses from the
  1478. transport module after a call to xxx_sendrequest for IPC message data.
  1479. See the transport module for details about the parameters to this
  1480. call.
  1481.  
  1482.  
  1483.  
  1484.    ipc_in_unblock(client_id,data,from,broadcast,crypt_level)
  1485.  
  1486.  
  1487.  
  1488. is called by disp_indata_simple when an unblock message is received
  1489. from a remote network server.  It will cause the message transmission
  1490. to be retried.  See the dispatcher module for details about the
  1491. parameters to this call.
  1492.  
  1493.  
  1494.  
  1495.    void  ipc_msg_accepted(port_rec_ptr)
  1496.    port_rec_ptr_t                port_rec_ptr;
  1497.  
  1498.  
  1499.  
  1500. is called by the local port operations module when it receives a
  1501. notify message from the kernel saying that a particular port is now
  1502. unblocked.  The IPC module will send unblock notification messages to
  1503. remote network servers that are blocked waiting to send a message to
  1504. the port.
  1505.  
  1506.  
  1507.  
  1508.    void  ipc_port_dead(port_rec_ptr)
  1509.    port_rec_ptr_t                port_rec_ptr;
  1510.  
  1511.  
  1512.  
  1513. is called by the local port operations module either when it receives
  1514. a notify message from the kernel saying that a particular port is now
  1515. dead or when it receives a message from a remote network server saying
  1516. that a particular network port is now dead.  The IPC module will clean
  1517. up any data structures it has associated with the deceased port.
  1518.  
  1519.  
  1520.  
  1521.    void  ipc_port_moved(port_rec_ptr)
  1522.    port_rec_ptr_t                port_rec_ptr;
  1523.  
  1524.  
  1525.  
  1526. is called by the local port operations module when it receives a
  1527. message from a remote network server saying that a particular network
  1528. port has moved.  The IPC module will abort any pending RPC's involving
  1529. this port.
  1530.  
  1531.  
  1532.                   19
  1533.  
  1534.  
  1535.    int  ipc_in_abortreq(trmod,trid,data_ptr,from,crypt_level,broadcast)
  1536.  
  1537.  
  1538.  
  1539. is called from disp_in_request when a request to abort a pending
  1540. request-response interaction is received over the network by a
  1541. transport module.  The data specifies which RPC is to be aborted.  If
  1542. it is still pending, a dummy response is sent at once; otherwise, this
  1543. request is ignored.  See the dispatcher module for details about the
  1544. parameters to this call.
  1545.  
  1546.  
  1547.  
  1548.    void  ipc_in_abortreply(client_id,code,data_ptr)
  1549.  
  1550.  
  1551.  
  1552. is the procedure used by the IPC module to receive responses from the
  1553. transport module after a call to xxx_sendrequest for a request to
  1554. abort a pending RPC.  See the transport module for details about the
  1555. parameters to this call.
  1556.  
  1557.  
  1558.  
  1559.    void  ipc_retry(port_rec_ptr)
  1560.    port_rec_ptr_t                port_rec_ptr;
  1561.  
  1562.  
  1563.  
  1564. is called from other modules when a message transmission should be
  1565. retried following some change in the port records.  It will cause the
  1566. retransmission to be executed in a special ``resend'' thread distinct
  1567. from the one making the ipc_retry call.
  1568.  
  1569.  
  1570.  
  1571.    void  ipc_freeze(port_rec_ptr)
  1572.    port_rec_ptr_t                port_rec_ptr;
  1573.  
  1574.  
  1575.  
  1576. is called from other modules when the status of a port becomes such
  1577. that no further transmissions should be attempted to that port.
  1578. Transmission will be resumed when ipc_retry is called.
  1579.  
  1580.  
  1581.  
  1582. 7.   Port Operations
  1583.  
  1584.  
  1585.  
  1586. 7.1.   Description
  1587.  
  1588.  
  1589.  
  1590. The functions provided by the port operations module are called in one
  1591. of the following three circumstances:
  1592.  
  1593.  
  1594.  
  1595. 1.  A message is received from the local kernel notifying the network
  1596.     server about a change in condition of a local port.  These changes
  1597.     are:
  1598.  
  1599.           o the death of the local port;
  1600.  
  1601.           o the transfer of port access rights to another task
  1602.             (probably because the task holding the rights has died);
  1603.             and
  1604.  
  1605.           o the local unblocking of the port.
  1606.  
  1607. 2.  A message is received over the network notifying the network
  1608.     server of a change in the remote network port's condition.  The
  1609.     possible changes are as for the local case except that they should be
  1610.     interpreted in the context of the remote port.
  1611.  
  1612. 3.  Access rights to a port are being transferred in a normal IPC
  1613.     message which is about to be sent to a remote network server or has
  1614.     been received from a remote network server.
  1615.  
  1616.  
  1617.                   20
  1618.  
  1619.  
  1620. The behavior of the port operations module depends on whether the port
  1621. that it is handling must be treated securely or not.  For instance, if
  1622. send rights to a port are being transferred in an IPC message and the
  1623. port is meant to be secure, then a token should be created for the
  1624. port and transferred along with the network port identifier when the
  1625. message is sent to the remote network server.  Similarly, at the
  1626. receiving end, the port operations module should store the token in
  1627. the network port's record.  However, if the port is not meant to be
  1628. treated securely, then no transfer and storing of a token need be
  1629. done.
  1630.  
  1631.  
  1632. In general the port operations module will often have to directly
  1633. modify the port's records, it may retry or freeze the sending of an
  1634. IPC message, it may initiate a port search, or, when port rights are
  1635. being transferred, it will provide the information that must be sent
  1636. to the remote network server.  Conversely, it must process this
  1637. information when the information is received from a remote network
  1638. server.  In addition, when it is considering a secure port, it may
  1639. have to generate or check a token for the port or it may have to
  1640. transfer or check the key that represents receive or ownership rights
  1641. to the port.
  1642.  
  1643.  
  1644.  
  1645. 7.2.   Interface
  1646.  
  1647.  
  1648.  
  1649.    boolean_t  po_init()
  1650.  
  1651.  
  1652.  
  1653. initializes the port operations module.
  1654.  
  1655.  
  1656.  
  1657.    po_check_ipc_seq_no(port_rec_ptr,  host_id,  ipc_seq_no)
  1658.    port_rec_ptr_t                port_rec_ptr;
  1659.    netaddr_t                         host_id;
  1660.    long                                 ipc_seq_no;
  1661.  
  1662.  
  1663.  
  1664. checks that the incoming IPC sequence number of a message is greater
  1665. that the last sequence number received for the network port with port
  1666. record port_rec_ptr from the network server on machine host_id.  This
  1667. check is only done for secure messages and ensures that complete IPC
  1668. messages cannot be replayed by a malicious party.
  1669.  
  1670.  
  1671.  
  1672.    typedef  struct  {...}  secure_info_t,  *secure_info_ptr_t;
  1673.  
  1674.  
  1675.  
  1676. is used to hold the key representing receiver or ownership rights to a
  1677. network port.
  1678.  
  1679.  
  1680.  
  1681.    long  po_create_token(port_rec_ptr,  token_ptr)
  1682.    port_rec_ptr_t                port_rec_ptr;
  1683.    secure_info_ptr_t           token_ptr;
  1684.  
  1685.  
  1686.  
  1687. creates a token for a port.  Stores the token in token_ptr and returns
  1688. the random number used to construct the token.
  1689.  
  1690.  
  1691.  
  1692.    void  po_notify_port_death(port_rec_ptr)
  1693.    port_rec_ptr_t                port_rec_ptr;
  1694.  
  1695.  
  1696.  
  1697. triggers handling of a local port death.  Marks the port's record as
  1698. deleted, sends out an unreliable port death notification messages and
  1699. does other local cleanups.
  1700.  
  1701.  
  1702.                   21
  1703.  
  1704.  
  1705. void  po_port_deallocate(lport)
  1706. port_t                              lport
  1707.  
  1708.  
  1709.  
  1710. deallocates a port but retains send rights to it.  This allows the
  1711. network server to transfer receive or ownership rights to a port to a
  1712. local task using the notification mechanism of the kernel.
  1713.  
  1714.  
  1715.  
  1716.    int  po_translate_lport_rights(client_id,lport,right,security_level,
  1717.                              destination_hint,port_data)
  1718.    int                                   client_id;
  1719.    port_t                              lport;
  1720.    int                                   right;
  1721.    int                                   security_level;
  1722.    netaddr_t                         destination_hint;
  1723.    pointer_t                         port_data;
  1724.  
  1725.  
  1726.  
  1727. is called by the IPC module to pack up the data that needs to be sent
  1728. to the host destination_hint in order to transfer the access rights
  1729. right to port lport.  The data that needs to be sent depends on the
  1730. security_level of the transfer.  The data is packed into the space
  1731. pointed to by port_data and the size of the network port data that has
  1732. been created is returned as the function's result.  The client_id is
  1733. an identifier remembered by the port operations module so that it can
  1734. match up a subsequent po_port_rights_commit (see below) with this call
  1735. of po_translate_lport_rights.
  1736.  
  1737.  
  1738.  
  1739.    po_port_rights_commit(client_id,  completion_code,  destination)
  1740.    int                                   client_id;
  1741.    int                                   completion_code;
  1742.    netaddr_t                         destination;
  1743.  
  1744.  
  1745.  
  1746. informs the port operations module that a transfer of rights to a
  1747. remote network host has either succeeded or failed.  The client_id
  1748. allows the port operations module to match this call with a previous
  1749. call of po_translate_lport_rights.  The completion_code can be one of
  1750. PO_RIGHTS_XFER_SUCCESS and PO_RIGHTS_XFER_FAILURE.  The destination
  1751. names the remote network server to which the port rights were actually
  1752. transferred.  It may be different from the destination_hint passed to
  1753. po_translate_lport_rights.
  1754.  
  1755.  
  1756.  
  1757.    int  po_translate_nport_rights(source,port_data,security_level,
  1758.                              lport,right)
  1759.    netaddr_t                         source;
  1760.    pointer_t                         port_data;
  1761.    int                                   security_level;
  1762.    port_t                              *lport;
  1763.    int                                   *right;
  1764.  
  1765.  
  1766.  
  1767. is called by the IPC module when it receives access rights to a remote
  1768. network port in a message from a remote network server.  The access
  1769. rights are contained in the data pointed to by port_data and were
  1770. received from the network server on host source and at security_level.
  1771. The port data received is handled according to what access rights are
  1772. being transferred and the local port corresponding to the network port
  1773. that was transferred is returned in lport.  In addition the actual
  1774. right transferred is returned in right and the size of the port data
  1775. that was processed is returned as the function's result.
  1776.  
  1777.  
  1778.                   22
  1779.  
  1780.  
  1781.    int po_handle_ro_xfer_request(request,from,broadcast,crypt_level)
  1782.  
  1783.  
  1784.  
  1785. is called by disp_indata_simple to handle an incoming transfer of
  1786. receiver or ownership rights.
  1787.  
  1788.  
  1789.  
  1790.    int po_handle_ro_xfer_reply(client_id,reply,from,broadcast,crypt_level)
  1791.  
  1792.  
  1793.  
  1794. is called by disp_rr_simple to handle the response to a transfer of
  1795. receiver or ownership rights.
  1796.  
  1797.  
  1798.  
  1799.    int  po_handle_ro_xfer_hint(request,from,broadcast,crypt_level)
  1800.  
  1801.  
  1802.  
  1803. is called by disp_indata_simple to handle an unreliable notification
  1804. of a transfer of receiver or ownership rights.
  1805.  
  1806.  
  1807.  
  1808.    int  po_handle_nport_death(hint,from,broadcast,crypt_level)
  1809.  
  1810.  
  1811.  
  1812. is called by disp_indata_simple to handle an unreliable notification
  1813. of the death of a network port.
  1814.  
  1815.  
  1816.  
  1817.    int  po_handle_token_request(request,from,broadcast,crypt_level)
  1818.  
  1819.  
  1820.  
  1821. is called by disp_indata_simple to handle an incoming request for a
  1822. token of receiver/owner authenticity.
  1823.  
  1824.  
  1825.  
  1826.    int po_handle_token_reply(client_id,reply,from,broadcast,crypt_level)
  1827.  
  1828.  
  1829.  
  1830. is called by disp_rr_simple to handle the response to a request for a
  1831. token of receiver/owner authenticity.
  1832.  
  1833.  
  1834.  
  1835. 8.   Port Checkups
  1836.  
  1837.  
  1838.  
  1839. 8.1.   Description
  1840.  
  1841.  
  1842.  
  1843. The port checkups module does a periodic probing of other network
  1844. servers to find out whether the status of network ports has changed.
  1845. In particular, it is the default way in which the network server finds
  1846. out about the death of a network port or the fact that receive or
  1847. ownership rights have moved to a different network server.  These
  1848. special conditions can also be detected as part of the normal
  1849. transmission of IPC messages across the network.  The port checkups
  1850. routine should only be called periodically and when the network server
  1851. is otherwise idle; in other words it is of low priority.
  1852.  
  1853.  
  1854. The checkups module needs to be able to look at the port records in
  1855. order to examine a ``aliveness'' parameter associated with each port
  1856. record.  The aliveness parameter is decremented by the port checkups
  1857. module every time it is called.  Only when it goes below some
  1858. predetermined value, is a checkup performed for the port.  Moreover,
  1859. the aliveness
  1860.  
  1861.  
  1862.                   23
  1863.  
  1864.  
  1865. parameter is updated to fully-alive when the IPC module has
  1866. successfully sent a message over the network to the port.  In other
  1867. words, if the port is in regular use then no checkup is done for it.
  1868.  
  1869.  
  1870. When the checkups module actually decides to send a checkup request to
  1871. find out about ports, it constructs an sbuf for each network server
  1872. that it must query.  An sbuf contains the ports in which it is
  1873. interested for which it believes the remote network server is
  1874. responsible.  To transmit and receive checkup information across the
  1875. network, the port checkups module uses the simple request-response
  1876. transport protocol.  After making a request by calling srr_send, the
  1877. checkups module will either receive a checkup reply or a failure
  1878. notification from the transport module.
  1879.  
  1880.  
  1881. On receiving a checkup request, the checkups module looks at each port
  1882. contained in the request.  If the information about the port that the
  1883. requester sent does not match the information held locally, then the
  1884. port in the checkup packet is marked as being ``bad''.  The checkup
  1885. reply packet is then sent back to the requester.
  1886.  
  1887.  
  1888. On receiving a checkup reply, the requester examines all the ports in
  1889. the reply and for those ports with a ``bad'' status it calls the port
  1890. search module.  It is up to the port search module to find out more
  1891. about the status of the port.  If no response was received to the
  1892. checkup request then the checkups module must call the port search
  1893. module for each port in the checkup request in order to resolve the
  1894. port's status (e.g.  to determine whether it is dead).
  1895.  
  1896.  
  1897. One other function of the checkups module is to determine whether
  1898. there exist any tasks with send rights to each port the network server
  1899. knows about.  This is in order to extend the MACH ``no-senders''
  1900. notification message into the network environment.  The checkups
  1901. module can determine that a network port has no senders if there has
  1902. been no interactions (the reception of either an IPC message or a
  1903. checkup request) involving this port for some period of time
  1904. (typically some number of checkup rounds).  If the network port has no
  1905. senders then the checkups module can deallocate send rights to the
  1906. corresponding local port and destroy the associated port record.
  1907.  
  1908.  
  1909. In addition the checkups module is responsible for handling hints
  1910. received saying that a remote network server has just restarted.  For
  1911. such a hint the checkups module calls the port search module for each
  1912. port that had the restarted network server as its owner or receiver.
  1913.  
  1914.  
  1915.  
  1916. 8.2.   Interface
  1917.  
  1918.  
  1919.  
  1920.    boolean_t  pc_init()
  1921.  
  1922.  
  1923.  
  1924. initializes  the  checkups  module.
  1925.  
  1926.  
  1927.  
  1928.    int  pc_do_checkups()
  1929.  
  1930.  
  1931.  
  1932. is called by the timer module to perform a checkup.
  1933.  
  1934.  
  1935.  
  1936.    pc_handle_checkup_request(request,from,broadcast,crypt_level)
  1937.  
  1938.  
  1939.  
  1940. is called by disp_indata_simple to handle an incoming checkup request.
  1941.  
  1942.  
  1943.  
  1944.                   24
  1945.  
  1946.  
  1947.    pc_handle_checkup_reply(client_id,reply,from,broadcast,crypt_level)
  1948.  
  1949.  
  1950.  
  1951. is called by disp_rr_simple to handle an incoming checkup reply.
  1952.  
  1953.  
  1954.  
  1955.    void  pc_send_startup_hint()
  1956.  
  1957.  
  1958.  
  1959. is called on start-up to send out a hint saying that this network
  1960. server has just restarted.
  1961.  
  1962.  
  1963.  
  1964.    int  pc_handle_startup_hint(hint,from,broadcast,crypt_level)
  1965.  
  1966.  
  1967. is called by disp_indata_simple to handle an incoming network server
  1968. restart hint.
  1969.  
  1970.  
  1971.  
  1972. 9.   Port Search
  1973.  
  1974.  
  1975.  
  1976. 9.1.   Description
  1977.  
  1978.  
  1979.  
  1980. The port search module is called when some other module (probably
  1981. either the port checkups module or the IPC module) determines that the
  1982. information held about a network port is no longer correct.  The task
  1983. of the port search module is to update that information, in particular
  1984. it may determine that the network port is dead.
  1985.  
  1986.  
  1987. The  search  procedure  is  basically  as  follows:
  1988.  
  1989.  
  1990.  
  1991.        query  network server  believed  to  be  the  receiver;
  1992.        if  receiver responds  with  useful  information
  1993.        then  believe it
  1994.        else {
  1995.              query  network  server  believed  to  be  the  owner;
  1996.              if  owner  responds  with  useful  information
  1997.              then  believe  it
  1998.              else  broadcast  a  request  for  information
  1999.        }
  2000.  
  2001.  
  2002.  
  2003. The response to a port search query can be one of:
  2004.  
  2005.  
  2006.  
  2007.     o port here, in which case the port search concludes successfully;
  2008.  
  2009.     o port here but receive or ownership transferred, in which case
  2010.       the port search concludes successfully with the port record
  2011.       updated to reflect the new owner or receiver;
  2012.  
  2013.     o port not here but receive and ownership rights transferred, in
  2014.       which case the port search continues by querying the new
  2015.       receiver;
  2016.  
  2017.     o port dead, in which case the port search concludes and the port
  2018.       is destroyed locally; or
  2019.  
  2020.     o port not known, in which case the port search continues by
  2021.       resorting to a broadcast query.
  2022.  
  2023.  
  2024.                   25
  2025.  
  2026.  
  2027. In addition, a query may receive no response in which case the port
  2028. search continues by resorting to a broadcast query.  To actually
  2029. transmit port search queries and responses the port search module uses
  2030. the simple request-response transport protocol.
  2031.  
  2032.  
  2033. The port search module is also responsible for authenticating a new
  2034. receiver or owner for a network port if the identity of the new
  2035. receiver or owner was obtained as a result of a broadcast search for
  2036. the port.  This authentication is only necessary is the port is being
  2037. handled securely.
  2038.  
  2039.  
  2040.  
  2041. 9.2.   Interface
  2042.  
  2043.  
  2044.  
  2045.    boolean_t  ps_init()
  2046.  
  2047.  
  2048.  
  2049. initializes  the  port  search  module.
  2050.  
  2051.  
  2052.  
  2053.    ps_do_port_search(port_rec_ptr,new_information,new_nport_ptr,retry)
  2054.    port_rec_ptr_t                port_rec_ptr;
  2055.    boolean_t                         new_information;
  2056.    network_port_ptr_t          new_nport_ptr;
  2057.    int                                   (*retry)();
  2058.  
  2059.  
  2060.  
  2061. is called to begin a port search for the network port recorded in
  2062. port_rec_ptr.  If the caller has new_information about the port
  2063. (either the possible identity of a new receiver or owner for the port)
  2064. then that new information is contained in the network port pointed to
  2065. by new_nport_ptr.  retry is a function supplied by the client to be
  2066. called if the port search concludes successfully.  It takes as its
  2067. only parameter the port_rec_ptr.
  2068.  
  2069.  
  2070.  
  2071.    int  ps_handle_request(request,from,broadcast,crypt_level)
  2072.  
  2073.  
  2074.  
  2075. is called by disp_indata_simple to handle an incoming port search
  2076. query.
  2077.  
  2078.  
  2079.  
  2080.    int  ps_handle_reply(client_id,reply,from,broadcast,crypt_level)
  2081.  
  2082.  
  2083.  
  2084. is called by disp_rr_simple to handle an incoming reply to a port
  2085. search query.
  2086.  
  2087.  
  2088.  
  2089.    int  ps_handle_auth_request(request,from,broadcast,crypt_level)
  2090.  
  2091.  
  2092.  
  2093. is called by disp_indata_simple to handle an incoming request for
  2094. authentication of a receiver or owner.
  2095.  
  2096.  
  2097.  
  2098.    int ps_handle_auth_reply(client_id,reply,from,broadcast,crypt_level)
  2099.  
  2100.  
  2101.  
  2102. is called by disp_indata_simple to handle an incoming reply to a
  2103. request for authentication of a receiver or owner.
  2104.  
  2105.  
  2106.  
  2107.                   26
  2108.  
  2109.  
  2110. 10.   Key Management
  2111.  
  2112.  
  2113.  
  2114. 10.1.   Description
  2115.  
  2116.  
  2117.  
  2118. The key management module maintains a table which maps remote hosts to
  2119. keys.  When it has to send a message securely over the network, the
  2120. IPC module checks that the key management module has a key for the
  2121. message's destination.  The actual encryption is done at the transport
  2122. level when the message data has been placed in packets.
  2123.  
  2124.  
  2125. If the key management module has no key for a particular remote host,
  2126. or the key that it possesses is obsolete, then it must call upon the
  2127. local KDS (Key Distribution Server) to do a key exchange.  The local
  2128. KDS uses a central KDS to perform the key exchange.  After the key
  2129. exchange is complete, the key management module should retry the
  2130. suspended IPC message.
  2131.  
  2132.  
  2133.  
  2134. 10.2.   Interface
  2135.  
  2136.  
  2137.  
  2138.    boolean_t  km_init()
  2139.  
  2140.  
  2141.  
  2142. initializes the key management module.
  2143.  
  2144.  
  2145.  
  2146.    typedef  struct  {...}  key_t,  *key_ptr_t;
  2147.  
  2148.  
  2149.  
  2150. is used to hold an encryption or decryption key.
  2151.  
  2152.  
  2153.  
  2154.    boolean_t  km_get_key(host_id,  key_ptr)
  2155.    netaddr_t                         host_id;
  2156.    key_ptr_t                         key_ptr;
  2157.  
  2158.  
  2159.  
  2160. looks up the key for the host_id.  If there is a key it returns TRUE
  2161. and places the key in key_ptr.
  2162.  
  2163.  
  2164.  
  2165.    boolean_t  km_get_ikey(host_id,  ikey_ptr)
  2166.    netaddr_t                         host_id;
  2167.    key_ptr_t                         key_iptr;
  2168.  
  2169.  
  2170.  
  2171. looks up the inverse key for the host_id.  If there is a key returns
  2172. TRUE and places the key in ikey_ptr.
  2173.  
  2174.  
  2175.  
  2176.    km_do_key_exchange(client_id,  client_retry,  host_id)
  2177.    int                                   client_id;
  2178.    int                                   (*client_retry)();
  2179.    netaddr_t                         host_id;
  2180.  
  2181.  
  2182.  
  2183. is called by a client module to get a key exchange done for host_id.
  2184. When the key exchange succeeds, the key management module calls the
  2185. function client_retry with the parameter client_id to inform the
  2186. client that there is now a key for the host.
  2187.  
  2188.  
  2189.  
  2190.                   27
  2191.  
  2192.  
  2193. km_kds_connect(server_port, kds_port)
  2194. port_t                              server_port;
  2195. port_t                              kds_port;
  2196.  
  2197.  
  2198.  
  2199. is called by the local KDS to register its port (kds_port) with the
  2200. network server.
  2201.  
  2202.  
  2203.  
  2204.    km_use_key_for_host(server_port,  host_id,  key)
  2205.    port_t                              server_port;
  2206.    netaddr_t                         host_id;
  2207.    key_t                               key;
  2208.  
  2209.  
  2210.  
  2211. is called by the local KDS to tell the network server to use key for
  2212. all future communication with host_id.
  2213.  
  2214.  
  2215. In the above two calls the server_port should always be a special port
  2216. which is known only to the network server and the local KDS.  The
  2217. network server is responsible for starting the KDS and passing send
  2218. rights to this special port to the KDS.
  2219.  
  2220.  
  2221.  
  2222. 11.   Crypt
  2223.  
  2224.  
  2225.  
  2226. The crypt module is responsible for the actual encryption and
  2227. decryption of packets that are to be sent out over the network and
  2228. received over the network.
  2229.  
  2230.  
  2231.  
  2232. 11.1.   Interface
  2233.  
  2234.  
  2235.  
  2236.    typedef  struct  {...}  netipc_t,  *netipc_ptr_t;
  2237.  
  2238.  
  2239.  
  2240. points to an Internet packet encapsulated in a MACH IPC message.
  2241.  
  2242.  
  2243.  
  2244.    int  crypt_encrypt_packet(packet_ptr,  crypt_level)
  2245.    netipc_ptr_t                    packet_ptr;
  2246.    int                                   crypt_level;
  2247.  
  2248.  
  2249.  
  2250. encrypts the packet pointed to by packet_ptr at the encryption level
  2251. given by crypt_level.  Returns either CRYPT_SUCCESS or CRYPT_FAILURE
  2252. if there is no key for the remote host.
  2253.  
  2254.  
  2255.  
  2256.    crypt_decrypt_packet(packet_ptr, crypt_level)
  2257.    netipc_ptr_t                    packet_ptr;
  2258.    int                                   crypt_level;
  2259.  
  2260.  
  2261.  
  2262. decrypts the packet pointed to by packet_ptr at the encryption level
  2263. given by crypt_level.  Returns either CRYPT_SUCCESS, CRYPT_FAILURE if
  2264. there is no key for the remote host or CRYPT_CHECKSUM_FAILURE if the
  2265. decrypted checksum is incorrect.
  2266.  
  2267.  
  2268.  
  2269.                   28
  2270.  
  2271.  
  2272. 12.   Network Name Service
  2273.  
  2274.  
  2275.  
  2276. 12.1.   Description
  2277.  
  2278.  
  2279.  
  2280. The network name service module provides a simple name service that is
  2281. sufficient to boot-strap a higher-level name service that will provide
  2282. a distributed and replicated user-level name service.  The network
  2283. name service is host-directed; that is requests for name look ups are
  2284. sent to specific hosts and are not broadcast.
  2285.  
  2286.  
  2287.  
  2288. 12.2.   Interface
  2289.  
  2290.  
  2291.  
  2292.    boolean_t  netname_init()
  2293.  
  2294.  
  2295.  
  2296. initializes the network name module.
  2297.  
  2298.  
  2299.  
  2300.    nn_remove_entries(port_id)
  2301.    port_t                              port_id;
  2302.  
  2303.  
  2304.  
  2305. removes all entries for the local port port_id from the local name
  2306. table.
  2307.  
  2308.  
  2309.  
  2310.    typedef  char  netname_name_t[80]
  2311.  
  2312.  
  2313.  
  2314.    kern_return_t  netname_check_in(ServPort,port_name,signature,port_id)
  2315.    vport_t                            ServPort;
  2316.    netname_name_t                port_name;
  2317.    port_t                              signature;
  2318.    port_t                              port_id;
  2319.  
  2320.  
  2321.  
  2322. checks in the port port_id under the name port_name protected by
  2323. signature.
  2324.  
  2325.  
  2326.  
  2327.    kern_return_t  netname_look_up(ServPort,host_name,port_name,port_id)
  2328.    port_t                              ServPort;
  2329.    netname_name_t                host_name;
  2330.    netname_name_t                port_name;
  2331.    port_t                              *port_id;
  2332.  
  2333.  
  2334.  
  2335. looks up port_name at host given by host_name.  Returns in port_id the
  2336. port found.
  2337.  
  2338.  
  2339.  
  2340.    kern_return_t  netname_check_out(ServPort,port_name,signature,port_id)
  2341.    port_t                              ServPort;
  2342.    netname_name_t                port_name;
  2343.    port_t                              signature;
  2344.  
  2345.  
  2346.  
  2347. checks out the port checked in under port_name.  The signature must
  2348. match the signature supplied to the netname_check_in call.
  2349.  
  2350.  
  2351.  
  2352.                   29
  2353.  
  2354.  
  2355.    kern_return_t  netname_version(ServPort,version)
  2356.    port_t                              ServPort;
  2357.    netname_name_t                version;
  2358.  
  2359.  
  2360.  
  2361. returns in version some version identification for the network server.
  2362.  
  2363.  
  2364.  
  2365.    int  nn_handle_request(request,from,broadcast,crypt_level)
  2366.  
  2367.  
  2368.  
  2369. is called by disp_indata_simple to handle an incoming request for a
  2370. network name look up.
  2371.  
  2372.  
  2373.  
  2374.    int  nn_handle_reply(client_id,reply,from,broadcast,crypt_level)
  2375.  
  2376.  
  2377.  
  2378. is called by disp_rr_simple to handle an incoming response to a
  2379. request for a network name look up.
  2380.  
  2381.  
  2382.  
  2383. 13.   Memory Management
  2384.  
  2385.  
  2386.  
  2387. 13.1.   Operation
  2388.  
  2389.  
  2390.  
  2391. The memory management module is responsible for allocating and
  2392. deallocating various objects used by the different modules, such as
  2393. port and message records, buffers, and so on.  It attempts to use
  2394. knowledge of the types of objects required to achieve good
  2395. performance.  It tries to reduce the load placed on the MACH virtual
  2396. memory system.
  2397.  
  2398.  
  2399.  
  2400. 13.2.   Interface
  2401.  
  2402.  
  2403.  
  2404.    boolean_t  mem_init()
  2405.  
  2406.  
  2407.  
  2408. initializes the memory management module.
  2409.  
  2410.  
  2411.  
  2412.   int  mem_clean()
  2413.  
  2414.  
  2415.  
  2416. attempts to free as much unused space as possible to reduce the paging
  2417. load on the operating system; it is potentially slow.
  2418.  
  2419.  
  2420.  
  2421.    pointer_t  mem_allocobj(objtype)
  2422.    int                                   objtype;
  2423.  
  2424.  
  2425.  
  2426. allocates one instance of an object of the given objtype and returns
  2427. its address, or 0 in case of failure.
  2428.  
  2429.  
  2430.  
  2431.    void  mem_deallocobj(ptr,objtype)
  2432.    pointer_t                         ptr;
  2433.    int                                   objtype;
  2434.  
  2435.  
  2436.                   30
  2437.  
  2438.  
  2439. deallocates an object of objtype previously allocated using
  2440. mem_allocobj.
  2441.  
  2442.  
  2443.  
  2444.    pointer_t  mem_alloc(size,aligned)
  2445.    int                                   size;
  2446.    boolean_t                         aligned;
  2447.  
  2448.  
  2449.  
  2450. allocates a memory area of arbitrary size; it returns 0 in case of
  2451. failure.
  2452.  
  2453.  
  2454.  
  2455.    void  mem_dealloc(ptr,size)
  2456.    pointer_t                         ptr;
  2457.    int                                   size;
  2458.  
  2459.  
  2460.  
  2461. deallocates memory previously allocated by mem_dealloc.
  2462.  
  2463.  
  2464.  
  2465. 14.   Read/Write Locks
  2466.  
  2467.  
  2468.  
  2469. The read/write locks module provides locks which can have multiple
  2470. readers and signals threads waiting for a lock when it becomes free.
  2471.  
  2472.  
  2473.  
  2474. 14.1.   Interface
  2475.  
  2476.  
  2477.  
  2478.    typedef  enum  {PERM_READ,  PERM_READWRITE}  rw_perm_t;
  2479.    typedef  enum  {NOBLOCK  =  0,  BLOCK  =  1}  rw_block_t;
  2480.    typedef  struct  lock  {...}  *lock_t;
  2481.  
  2482.  
  2483.    lock_t  lk_alloc()
  2484.  
  2485.  
  2486.  
  2487. allocates a read/write lock.
  2488.  
  2489.  
  2490.  
  2491.    void  lk_free(lock)
  2492.  
  2493.  
  2494.  
  2495.    frees a read/write lock.
  2496.  
  2497.  
  2498.  
  2499.    int  lk_lock(lock,  perm,  block)
  2500.    lock_t                              lock;
  2501.    rw_perm_t                         perm;
  2502.    rw_block_t                       block;
  2503.  
  2504.  
  2505.  
  2506. locks the lock for type perm.  If block is true, then this calls
  2507. blocks waiting until the lock can be obtained, otherwise the function
  2508. returns 0 if the lock cannot be obtained.
  2509.  
  2510.  
  2511.  
  2512.    void  lk_unlock(lock)
  2513.    lock_t                              lock;
  2514.  
  2515.  
  2516.  
  2517. unlocks the lock.
  2518.  
  2519.  
  2520.                   31
  2521.  
  2522.  
  2523. 15.   Locked Queue Module
  2524.  
  2525.  
  2526.  
  2527. The locked queue module provides functions to manipulate items on
  2528. queues.  When a queue is accessed it is always locked before being
  2529. manipulated.
  2530.  
  2531.  
  2532.  
  2533. 15.1.   Interface
  2534.  
  2535.  
  2536.  
  2537.    typedef  struct  {...}  *lock_queue_t;
  2538.    typedef  struct  queue_item  {struct  queue_item  *next}  *queue_item_t;
  2539.  
  2540.  
  2541.  
  2542.    lock_queue_t  lq_alloc()
  2543.  
  2544.  
  2545.  
  2546. allocates and initializes a new locked queue.
  2547.  
  2548.  
  2549.  
  2550.    void  lq_init_queue(queue)
  2551.    lock_queue_t                    queue;
  2552.  
  2553.  
  2554.  
  2555. re-initializes the already allocated queue.
  2556.  
  2557.  
  2558.  
  2559.    void  lq_prequeue(queue,  item)
  2560.    lock_queue_t                    queue;
  2561.    queue_item_t                    item;
  2562.  
  2563.  
  2564.  
  2565. inserts item at the head of queue.
  2566.  
  2567.  
  2568.  
  2569.    void  lq_insert_in_queue(queue,  test,  item,  args)
  2570.    lock_queue_t                    queue;
  2571.    int                                   (*test)();
  2572.    queue_item_t                    item;
  2573.    int                                   arg;
  2574.  
  2575.  
  2576.  
  2577. inserts item in the ``correct'' position on queue.  The correct
  2578. position is determined by calling the user-supplied function test on
  2579. item, arg and the members of queue until it returns TRUE.
  2580.  
  2581.  
  2582.  
  2583.    boolean_t  lq_remove_from_queue(queue,  item)
  2584.    lock_queue_t                    queue;
  2585.    queue_item_t                    item;
  2586.  
  2587.  
  2588.  
  2589. removes item from queue if item is present on the queue.  Returns TRUE
  2590. is item was deleted from queue, FALSE otherwise.
  2591.  
  2592.  
  2593.  
  2594.    boolean_t  lq_cond_delete_from_queue(queue,  test,  item)
  2595.    lock_queue_t                    queue;
  2596.    int                                   (*test)();
  2597.    queue_item_t                    item;
  2598.    int                                   arg;
  2599.  
  2600.  
  2601.                   32
  2602.  
  2603.  
  2604. performs the user-supplied function test on item, arg and on
  2605. successive elements of queue.  If it returns TRUE, then the current
  2606. element of the queue is deleted.
  2607.  
  2608.  
  2609.  
  2610.    boolean_t  lq_on_queue(queue,  item)
  2611.    lock_queue_t                    queue;
  2612.    queue_item_t                    item;
  2613.  
  2614.  
  2615.  
  2616. checks to see if the item is on queue.
  2617.  
  2618.  
  2619.  
  2620.    queue_item_t  lq_dequeue(queue)
  2621.    lock_queue_t                    queue;
  2622.  
  2623.  
  2624.  
  2625. if queue is not empty remove and return the queue item which is at the
  2626. head of it.
  2627.  
  2628.  
  2629.  
  2630.    queue_item_t  lq_blocking_dequeue(queue)
  2631.    lock_queue_t                    queue;
  2632.  
  2633.  
  2634.  
  2635. if queue is empty, a wait is done until it is non-empty.  Removes and
  2636. returns the queue item which is at the head of queue.
  2637.  
  2638.  
  2639.  
  2640.    void  lq_enqueue(queue,  item);
  2641.    lock_queue_t                    queue;
  2642.    queue_item_t                    item;
  2643.  
  2644.  
  2645.  
  2646. inserts item at the tail of queue.
  2647.  
  2648.  
  2649.  
  2650.    queue_item_t  lq_find_in_queue(queue,  fn,  args)
  2651.    lock_queue_t                    queue;
  2652.    int                                   (*fn)();
  2653.    int                                   arg;
  2654.  
  2655.  
  2656.  
  2657. returns a queue_item_t which is found by applying the user-supplied
  2658. function fn to successive elements of queue and arg until fn returns
  2659. TRUE.
  2660.  
  2661.  
  2662.  
  2663.    void  lq_map_queue(queue,  fn,  args);
  2664.    lock_queue_t                    queue;
  2665.    int                                   (*fn)();
  2666.     int                                   arg;
  2667.  
  2668.  
  2669.  
  2670. applies the user-supplied function fn to each successive item of queue
  2671. and arg.
  2672.  
  2673.  
  2674. In addition to the above routines, a number of equivalent routines are
  2675. provided that do not acquire or release the queue lock when invoked,
  2676. to be used in situations where global lock management is needed to
  2677. avoid deadlock.  Those routines are prefixed with lqn_ instead of lq_.
  2678.  
  2679.  
  2680. Finally, the network server also uses doubly-linked lists for some
  2681. queues.  using the same macros used in the Mach kernel for that
  2682. purpose.
  2683.  
  2684.  
  2685.                   33
  2686.  
  2687.  
  2688. 16.   Timer Module
  2689.  
  2690.  
  2691.  
  2692. The timer module accepts requests from other modules for events to be
  2693. scheduled at some time in the future.  When the event's deadline
  2694. expires the timer module calls the user-supplied function associated
  2695. with the timer.
  2696.  
  2697.  
  2698.  
  2699. 16.1.   Interface
  2700.  
  2701.  
  2702.  
  2703.    boolean_t  timer_init()
  2704.  
  2705.  
  2706.  
  2707. initializes the timer module.
  2708.  
  2709.  
  2710.  
  2711.    struct  timer  {...}  *timer_t;
  2712.  
  2713.  
  2714.    timer_t timer_alloc()
  2715.  
  2716.  
  2717.  
  2718. returns a new timer.
  2719.  
  2720.  
  2721.  
  2722.    void  timer_start(timer)
  2723.    timer_t                            timer;
  2724.  
  2725.  
  2726.  
  2727. starts up timer.
  2728.  
  2729.  
  2730.  
  2731.    void  timer_stop(timer)
  2732.    timer_t                            timer;
  2733.  
  2734.  
  2735.  
  2736. stops timer.
  2737.  
  2738.  
  2739.  
  2740. 17.   Miscellaneous
  2741.  
  2742.  
  2743.  
  2744. 17.1.   Unique Identifer Generator
  2745.  
  2746.  
  2747.  
  2748. Simply generates locally unique identifiers (UIDs).  The identifiers
  2749. generated are unique with high probability.
  2750.  
  2751.  
  2752.  
  2753. 17.1.1.   Interface
  2754.  
  2755.  
  2756.  
  2757.    void  uid_init()
  2758.  
  2759.  
  2760.  
  2761. initializes the UID module.
  2762.  
  2763.  
  2764.  
  2765.    long  uid_get_new_uid()
  2766.  
  2767.  
  2768.  
  2769. returns a new UID.
  2770.  
  2771.  
  2772.                   34
  2773.  
  2774.  
  2775. 17.2.   Sbuf
  2776.  
  2777.  
  2778.  
  2779. The sbuf module provides macros that manipulate sbufs.
  2780.  
  2781.  
  2782.  
  2783. 17.2.1.   Interface
  2784.  
  2785.  
  2786.  
  2787.    void  sbuf_printf(where,  sb_ptr)
  2788.    FILE                                 *where;
  2789.    sbuf_ptr_t                       sb_ptr;
  2790.  
  2791.  
  2792.  
  2793. is the only exported function of the sbuf module.  It prints out the
  2794. contents of the sbuf pointed to by sb_ptr.
  2795.  
  2796.  
  2797.  
  2798. 17.3.   Network Interfaces
  2799.  
  2800.  
  2801.  
  2802. Under Mach the interface to the network is an IPC interface with a
  2803. filter inside the kernel determining which network packets are to be
  2804. received by the network server.  Currently, many transport modules
  2805. still use BSD Unix sockets to access network protocol implementations
  2806. in the kernel.
  2807.  
  2808.  
  2809.  
  2810. 17.3.1.   Interface
  2811.  
  2812.  
  2813.  
  2814.    int  netipc_receive(pkt_ptr)
  2815.    netipc_ptr_t                    pkt_ptr;
  2816.  
  2817.  
  2818.  
  2819. waits to receive a packet from the kernel.  Checks the packet's UDP
  2820. checksum before returning to the caller.
  2821.  
  2822.  
  2823.  
  2824.    int  netipc_send(pkt_ptr)
  2825.    netipc_ptr_t                    pkt_ptr;
  2826.  
  2827.  
  2828.  
  2829. calculates the UDP checksum for the packet and then sends it to the
  2830. kernel for transmission over the network.
  2831.  
  2832.  
  2833.  
  2834. 17.4.   IPC Message Receive
  2835.  
  2836.  
  2837.  
  2838. 17.5.   Interface
  2839.  
  2840.  
  2841.  
  2842.    int  netmsg_receive(msg_ptr)
  2843.    msg_header_t                    *msg_ptr;
  2844.  
  2845.  
  2846.  
  2847. does a non-blocking receive for a local IPC message.
  2848.  
  2849.  
  2850.  
  2851.                   35
  2852.  
  2853.  
  2854. 17.6.   Debugging
  2855.  
  2856.  
  2857.  
  2858. The network server keeps a log in memory of various events happening
  2859. during its operation.  This log, along with statistics on various
  2860. operations, can be obtained via the logstat service exported by the
  2861. network server.  In addition, many operating parameters, including the
  2862. level of debugging information written to the log, can be set using
  2863. this same service.
  2864.  
  2865.  
  2866.  
  2867. 17.6.1.   Interface
  2868.  
  2869.  
  2870.  
  2871. Macros and procedures called within the network server
  2872.  
  2873.  
  2874.  
  2875.    DEBUGn(condition,print_level,code,arg1,...,argn)
  2876.  
  2877.  
  2878.  
  2879. is a macro to be used to write a record containing the code and all
  2880. the integer args into the log.  n is a number between 0 and 6,
  2881. indicating how many integers must be copied into the log.  A log entry
  2882. is only made if condition evaluates to TRUE.  In addition, if
  2883. print_level is greater or equal to the global debug.print_level, a
  2884. message is printed on stderr.
  2885.  
  2886.  
  2887.  
  2888.    DEBUG_STRING(cond,level,string)
  2889.    DEBUG_NPORT(cond,level,nport)
  2890.    DEBUG_NETADDR(cond,level,netaddr)
  2891.    DEBUG_KEY(cond,level,key)
  2892.    DEBUG_SBUF(cond,level,sbuf)
  2893.  
  2894.  
  2895.  
  2896. are similar to the DEBUGn macros, but are used to enter a string, a
  2897. network port identifier, a network address, an encryption key or an
  2898. sbuf into the log.
  2899.  
  2900.  
  2901. The DEBUG macros can be made to expand to nothing via a compile-time
  2902. switch to avoid overheads at execution time.  Each of those macros has
  2903. an equivalent LOG macro that can be enabled or disabled independently;
  2904. those LOG macros are intended for events that should always be entered
  2905. in the log and are infrequent enough that the overhead involved is
  2906. negligible.
  2907.  
  2908.  
  2909.  
  2910.    ERROR((msg,format,args...))
  2911.  
  2912.  
  2913.  
  2914. is used to print out a message on stderr an make an entry in the log.
  2915. The argument should be a valid set of arguments for sprintf, with the
  2916. message string msg.
  2917.  
  2918.  
  2919.  
  2920.    void  panic(error_msg)
  2921.    char                                 *error_msg;
  2922.  
  2923.  
  2924.  
  2925. is called if something catastrophic happens.  Prints out the
  2926. error_msg, dumps the log and terminates the network server.
  2927.  
  2928.  
  2929.  
  2930.    void  ipaddr_to_string(output_string,  input_address)
  2931.    char                                 *output_string;
  2932.    netaddr_t                         input_address;
  2933.  
  2934.  
  2935.  
  2936.                   36
  2937.  
  2938.  
  2939. Translates the input_address IP address into a printable
  2940. representation in output_string.
  2941.  
  2942.  
  2943.  
  2944. Procedures exported outside the network server: The following
  2945. procedures can be called remotely by sending requests on a port
  2946. checked-in as NM_LOGSTAT in the network server.
  2947.  
  2948.  
  2949.  
  2950.    kern_return_t  ls_sendlog(ServPort,old_log_ptr,old_log_size,
  2951.                                            cur_log_ptr,cur_log_size)
  2952.    port_t                ServPort;
  2953.    log_ptr_t           *old_log_ptr;
  2954.    unsigned  int      *old_log_size;
  2955.    log_ptr_t           *cur_log_ptr;
  2956.    unsigned  int      *cur_log_size;
  2957.  
  2958.  
  2959.  
  2960. is used to obtain both network server logs in the response message.
  2961. The old and new logs correspond to the two alternating logs used to
  2962. record events.
  2963.  
  2964.  
  2965.  
  2966.    kern_return_t  ls_resetlog(ServPort)
  2967.    port_t                ServPort;
  2968.  
  2969.  
  2970.  
  2971. resets the log to zero size.
  2972.  
  2973.  
  2974.  
  2975.    kern_return_t  ls_writelog(ServPort)
  2976.    port_t                ServPort;
  2977.  
  2978.  
  2979.  
  2980. causes the network server to write its log in a file NMLOG in its
  2981. current working directory.
  2982.  
  2983.  
  2984.  
  2985.    kern_return_t  ls_sendstat(ServPort,stat_ptr,stat_size)
  2986.    port_t                ServPort;
  2987.    stat_ptr_t          *stat_ptr;
  2988.    unsigned  int      *stat_size;
  2989.  
  2990.  
  2991.  
  2992. is used to obtain a record with the vital network server statistics in
  2993. the response.
  2994.  
  2995.  
  2996.  
  2997.    kern_return_t  ls_resetstat(ServPort)
  2998.    port_t                ServPort;
  2999.  
  3000.  
  3001.  
  3002. resets all statistics counters to zero.
  3003.  
  3004.  
  3005.  
  3006.    kern_return_t  ls_senddebug(ServPort,debug_ptr,debug_size)
  3007.    port_t                ServPort;
  3008.    debug_ptr_t        *debug_ptr;
  3009.    unsigned  int      *debug_size;
  3010.  
  3011.  
  3012.  
  3013. is used to obtain a record with all the debugging flags used to
  3014. control the operation of the DEBUG macros.
  3015.  
  3016.  
  3017.                   37\
  3018.  
  3019.  
  3020.    kern_return_t  ls_setdebug(ServPort,debug_ptr,debug_size)
  3021.    port_t                ServPort;
  3022.    debug_ptr_t        *debug_ptr;
  3023.    unsigned  int      *debug_size;
  3024.  
  3025.  
  3026.  
  3027. is used to replace the record with all the debugging flags used to
  3028. control the operation of the DEBUG macros.
  3029.  
  3030.  
  3031.  
  3032.    kern_return_t  ls_sendparam(ServPort,param_ptr,param_size)
  3033.    port_t                ServPort;
  3034.    param_ptr_t        *param_ptr;
  3035.    unsigned  int      *param_size;
  3036.  
  3037.  
  3038.  
  3039. is used to obtain a record with the network server control parameters.
  3040.  
  3041.  
  3042.  
  3043.    kern_return_t  ls_setparam(ServPort,param_ptr,param_size)
  3044.    port_t                ServPort;
  3045.    param_ptr_t        *param_ptr;
  3046.    unsigned  int      *param_size;
  3047.  
  3048.  
  3049.  
  3050. is used to replace the record with the network server control
  3051. parameters.
  3052.  
  3053.  
  3054.  
  3055.    kern_return_t  ls_sendportstat(ServPort,port_stat_ptr,port_stat_size)
  3056.    port_t                ServPort;
  3057.    port_stat_ptr_t  *port_stat_ptr;
  3058.    unsigned  int      *port_stat_size;
  3059.  
  3060.  
  3061.  
  3062. is used to obtain a record with the port record statistics.
  3063.  
  3064.  
  3065.  
  3066. 17.7.   Camelot Support
  3067.  
  3068.  
  3069.  
  3070. The Camelot Distributed Transaction Facility [3 ] requires special
  3071. handling for IPC messages used in Camelot transactions.  This handling
  3072. is performed in a special Camelot module, not described, here, that
  3073. behaves as an extra step in the translation process for incoming and
  3074. outgoing IPC messages.
  3075.  
  3076.  
  3077. In addition, Camelot also requires some specialized name servers, also
  3078. implemented in the Camelot module.
  3079.  
  3080.  
  3081.  
  3082. 17.8.   Kernel Netport Support
  3083.  
  3084.  
  3085.  
  3086. Certain Mach kernels provide an experimental feature, called Netport
  3087. or MACH_NP with which Kernel port records may be flagged as
  3088. corresponding to local representatives for remote network ports.
  3089. Under certain very restricted conditions, the kernel may, upon
  3090. processing a message destined for one of these ports, send the message
  3091. directly to the remote node instead of handing it to the network
  3092. server.  This scheme results in improved performance by avoiding the
  3093. overhead of invoking the network servers on both ends of the
  3094. communication.  Correctness is assured by having the kernel abort its
  3095. transmission and
  3096.  
  3097.  
  3098.                   38
  3099.  
  3100.  
  3101. reflect the message back to the network server as soon as a situation
  3102. arises that is too complex for the Netport code to handle.
  3103.  
  3104.  
  3105. When enabled, all modules in the network server that modify network
  3106. port records enter the correct information in the kernel port records
  3107. to allow the Netport code to function.
  3108.  
  3109.  
  3110.  
  3111. 17.9.   Initialization
  3112.  
  3113.  
  3114.  
  3115. The network server initialization sequence takes care of detecting
  3116. modules that require kernel support not present on the current node,
  3117. and of setting the working parameters accordingly.  These include:
  3118.  
  3119.  
  3120.  
  3121.     o Access to a network interface.  If there is no network, the
  3122.       network server degenerates into a simple local Name Server, as
  3123.       specified by the conf_network parameter.
  3124.  
  3125.     o Netport support: controlled by the conf_netport parameter.
  3126.  
  3127.     o VMTP support.  The transport_default parameter is set to the
  3128.       index of the best transport protocol available.
  3129.  
  3130.  
  3131.  
  3132. 17.9.1.   Interface
  3133.  
  3134.  
  3135.  
  3136.    boolean_t  nm_init()
  3137.  
  3138.  
  3139.  
  3140. initializes the network server by calling and checking the error
  3141. returns for all the module initialization functions.
  3142.  
  3143.  
  3144.  
  3145.  
  3146. Appendix
  3147.  
  3148.  
  3149.  
  3150. A   Compiling a Network Server
  3151.  
  3152.  
  3153.  
  3154. The various configuration options for the Network Server are all
  3155. defined in the file config.h, which should simply be edited before
  3156. compiling the system.  The option settings in the file as distributed
  3157. are suitable for a normal generic configuration.
  3158.  
  3159.  
  3160. The configuration options are:
  3161.  
  3162.  
  3163.  
  3164. NET_LOG enable the LOGn macros.
  3165.  
  3166. NET_DEBUG enable the DEBUGn macros.
  3167.  
  3168. NET_TRACE enable tracing of procedure calls, under control of a
  3169.     command line switch.
  3170.  
  3171. NET_PRINT enable printing from the LOG and DEBUG macros.
  3172.  
  3173. LOCK_THREADS do not allow more than one thread to run at any one time.
  3174.     To use only for debugging.
  3175.  
  3176. NM_STATISTICS enable normal statistics gathering.
  3177.  
  3178. NETPORT enable entering information in the kernel port records for use
  3179.     by the Netport option.
  3180.  
  3181. PORTSTAT enable port statistics gathering.
  3182.  
  3183.  
  3184.                   39
  3185.  
  3186.  
  3187. RPCMOD     enable the RPC optimization, and the request-response
  3188.     transport
  3189.     interface.  Should always be on.
  3190.  
  3191. COMPAT     enable special operating mode for compatibility with the
  3192.     previous implementation (Mach 1.0 and 2.0) of the Network Server.
  3193.  
  3194. NOTIFY    explicitly allocate a notify port, which is not created by
  3195.     default in newer versions of the Mach kernel.
  3196.  
  3197. CAMELOT    include the Camelot module in the network server.
  3198.  
  3199. NM_USE_KDS use an external Key Distribution Server.
  3200.  
  3201. USE_VMTP include the VMTP transport module in the network server.
  3202.  
  3203. USE_DELTAT include the Delta-t transport module in the network server.
  3204.  
  3205. USE_CRYPT include the Crypt module in the network server.
  3206.  
  3207. USE_DES include the DES encryption module in the network server.
  3208.  
  3209. USE_MULTPERM include the ``multiple permutations'' encryption module
  3210.     in the network server.
  3211.  
  3212. USE_NEWDES include the ``new'' DES encryption module in the network
  3213.     server.
  3214.  
  3215. USE_XOR include the ``exclusive or'' encryption module in the network
  3216.     server.
  3217.  
  3218. USE_KEYMAN include the keymanager module in the network server.
  3219.  
  3220. USE_TCP    include the TCP transport module in the network server.
  3221.  
  3222. USE_DATAGRAM include the DATAGRAM transport module in the network
  3223.     server.
  3224.  
  3225. USE_SRR include the SRR transport module in the network server.
  3226.  
  3227.  
  3228.  
  3229. Both USE_VMTP and NETPORT require kernel support that is not normally
  3230. present.  Normally, USE_TCP, USE_SRR and USE_DATAGRAM should always be
  3231. enabled for the system to work.
  3232.  
  3233.  
  3234. In addition to the configuration options, the file config.h also
  3235. contains all the definitions needed to compile the network server on
  3236. various architectures.  It is the only file that should be modified
  3237. when porting the network server to a new architecture.
  3238.  
  3239.  
  3240.  
  3241. References
  3242.  
  3243.  
  3244. [1] Cheriton, D.  VMTP: A Transport Protocol for the Next Generation of
  3245.     Communication Systems.  In: Proceedings of the ACM SIGCOMM 86
  3246.     Symposium on Communications Architectures and Protocols.  ACM, 1986,
  3247.     pp. 406-415.
  3248.       
  3249. [2] Sansom, R. D., Julin, D. P., and Rashid, R. F. Extending a
  3250.     Capability Based System into a Network Environment.  In: SIGCOMM
  3251.     '86 Symposium: Communications Architectures & Protocols, ACM
  3252.     SIGCOMM.  1986.  Also available as Technical Report CMU-CS-86-115.
  3253.  
  3254. [3] Spector, A. Z., Bloch, J. J., Daniels, D. S., Draves, R. P.,
  3255.     Duchamp, D., Eppinger, J. L., Menees, S. G., and Thompson, D. S.
  3256.     The Camelot Project.  Database Engineering, vol. 9 (1986).  Also
  3257.     available as Technical Report CMU-CS-86-166, Carnegie-Mellon
  3258.     University, November 1986.
  3259.