home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 14 Text
/
14-Text.zip
/
machdocs.zip
/
netmsg2
< prev
next >
Wrap
Internet Message Format
|
1993-02-26
|
30KB
From Pa.dec.com!nobody Thu Feb 25 20:15:42 1993
Return-Path: <Pa.dec.com!nobody>
Received: by ukelele.GCR.COM (Smail3.1.28.1 #1)
id m0nRtfx-0001S1a; Thu, 25 Feb 93 20:15 EST
Received: from inet-gw-2.pa.dec.com by uu5.psi.com (5.65b/4.0.071791-PSI/PSINet) via SMTP;
id AA01593 for spj@ukelele.GCR.COM; Thu, 25 Feb 93 19:09:37 -0500
Received: by inet-gw-2.pa.dec.com; id AA28434; Thu, 25 Feb 93 16:09:40 -0800
Date: Thu, 25 Feb 93 16:09:40 -0800
Message-Id: <9302260009.AA28434@inet-gw-2.pa.dec.com>
From: "ftpmail service on inet-gw-2.pa.dec.com" <nobody@Pa.dec.com>
To: spj@ukelele.GCR.COM
Subject: part 002 of /.0/Mach/doc/netmsgserver.doc (@gatekeeper.dec.com) [Mach Dox] (ascii, last)
X-Complaints-To: ftpmail-admin@inet-gw-2.pa.dec.com
X-Service-Address: ftpmail@inet-gw-2.pa.dec.com
X-Job-Number: 730680718.24209
Precedence: bulk
Reply-To: <nobody@inet-gw-2.pa.dec.com>
Content-Type: text
Content-Length: 29231
Status: O
senders then the checkups module can deallocate send rights to the
corresponding local port and destroy the associated port record.
In addition the checkups module is responsible for handling hints
received saying that a remote network server has just restarted. For
such a hint the checkups module calls the port search module for each
port that had the restarted network server as its owner or receiver.
8.2. Interface
boolean_t pc_init()
initializes the checkups module.
int pc_do_checkups()
is called by the timer module to perform a checkup.
pc_handle_checkup_request(request,from,broadcast,crypt_level)
is called by disp_indata_simple to handle an incoming checkup request.
24
pc_handle_checkup_reply(client_id,reply,from,broadcast,crypt_level)
is called by disp_rr_simple to handle an incoming checkup reply.
void pc_send_startup_hint()
is called on start-up to send out a hint saying that this network
server has just restarted.
int pc_handle_startup_hint(hint,from,broadcast,crypt_level)
is called by disp_indata_simple to handle an incoming network server
restart hint.
9. Port Search
9.1. Description
The port search module is called when some other module (probably
either the port checkups module or the IPC module) determines that the
information held about a network port is no longer correct. The task
of the port search module is to update that information, in particular
it may determine that the network port is dead.
The search procedure is basically as follows:
query network server believed to be the receiver;
if receiver responds with useful information
then believe it
else {
query network server believed to be the owner;
if owner responds with useful information
then believe it
else broadcast a request for information
}
The response to a port search query can be one of:
o port here, in which case the port search concludes successfully;
o port here but receive or ownership transferred, in which case
the port search concludes successfully with the port record
updated to reflect the new owner or receiver;
o port not here but receive and ownership rights transferred, in
which case the port search continues by querying the new
receiver;
o port dead, in which case the port search concludes and the port
is destroyed locally; or
o port not known, in which case the port search continues by
resorting to a broadcast query.
25
In addition, a query may receive no response in which case the port
search continues by resorting to a broadcast query. To actually
transmit port search queries and responses the port search module uses
the simple request-response transport protocol.
The port search module is also responsible for authenticating a new
receiver or owner for a network port if the identity of the new
receiver or owner was obtained as a result of a broadcast search for
the port. This authentication is only necessary is the port is being
handled securely.
9.2. Interface
boolean_t ps_init()
initializes the port search module.
ps_do_port_search(port_rec_ptr,new_information,new_nport_ptr,retry)
port_rec_ptr_t port_rec_ptr;
boolean_t new_information;
network_port_ptr_t new_nport_ptr;
int (*retry)();
is called to begin a port search for the network port recorded in
port_rec_ptr. If the caller has new_information about the port
(either the possible identity of a new receiver or owner for the port)
then that new information is contained in the network port pointed to
by new_nport_ptr. retry is a function supplied by the client to be
called if the port search concludes successfully. It takes as its
only parameter the port_rec_ptr.
int ps_handle_request(request,from,broadcast,crypt_level)
is called by disp_indata_simple to handle an incoming port search
query.
int ps_handle_reply(client_id,reply,from,broadcast,crypt_level)
is called by disp_rr_simple to handle an incoming reply to a port
search query.
int ps_handle_auth_request(request,from,broadcast,crypt_level)
is called by disp_indata_simple to handle an incoming request for
authentication of a receiver or owner.
int ps_handle_auth_reply(client_id,reply,from,broadcast,crypt_level)
is called by disp_indata_simple to handle an incoming reply to a
request for authentication of a receiver or owner.
26
10. Key Management
10.1. Description
The key management module maintains a table which maps remote hosts to
keys. When it has to send a message securely over the network, the
IPC module checks that the key management module has a key for the
message's destination. The actual encryption is done at the transport
level when the message data has been placed in packets.
If the key management module has no key for a particular remote host,
or the key that it possesses is obsolete, then it must call upon the
local KDS (Key Distribution Server) to do a key exchange. The local
KDS uses a central KDS to perform the key exchange. After the key
exchange is complete, the key management module should retry the
suspended IPC message.
10.2. Interface
boolean_t km_init()
initializes the key management module.
typedef struct {...} key_t, *key_ptr_t;
is used to hold an encryption or decryption key.
boolean_t km_get_key(host_id, key_ptr)
netaddr_t host_id;
key_ptr_t key_ptr;
looks up the key for the host_id. If there is a key it returns TRUE
and places the key in key_ptr.
boolean_t km_get_ikey(host_id, ikey_ptr)
netaddr_t host_id;
key_ptr_t key_iptr;
looks up the inverse key for the host_id. If there is a key returns
TRUE and places the key in ikey_ptr.
km_do_key_exchange(client_id, client_retry, host_id)
int client_id;
int (*client_retry)();
netaddr_t host_id;
is called by a client module to get a key exchange done for host_id.
When the key exchange succeeds, the key management module calls the
function client_retry with the parameter client_id to inform the
client that there is now a key for the host.
27
km_kds_connect(server_port, kds_port)
port_t server_port;
port_t kds_port;
is called by the local KDS to register its port (kds_port) with the
network server.
km_use_key_for_host(server_port, host_id, key)
port_t server_port;
netaddr_t host_id;
key_t key;
is called by the local KDS to tell the network server to use key for
all future communication with host_id.
In the above two calls the server_port should always be a special port
which is known only to the network server and the local KDS. The
network server is responsible for starting the KDS and passing send
rights to this special port to the KDS.
11. Crypt
The crypt module is responsible for the actual encryption and
decryption of packets that are to be sent out over the network and
received over the network.
11.1. Interface
typedef struct {...} netipc_t, *netipc_ptr_t;
points to an Internet packet encapsulated in a MACH IPC message.
int crypt_encrypt_packet(packet_ptr, crypt_level)
netipc_ptr_t packet_ptr;
int crypt_level;
encrypts the packet pointed to by packet_ptr at the encryption level
given by crypt_level. Returns either CRYPT_SUCCESS or CRYPT_FAILURE
if there is no key for the remote host.
crypt_decrypt_packet(packet_ptr, crypt_level)
netipc_ptr_t packet_ptr;
int crypt_level;
decrypts the packet pointed to by packet_ptr at the encryption level
given by crypt_level. Returns either CRYPT_SUCCESS, CRYPT_FAILURE if
there is no key for the remote host or CRYPT_CHECKSUM_FAILURE if the
decrypted checksum is incorrect.
28
12. Network Name Service
12.1. Description
The network name service module provides a simple name service that is
sufficient to boot-strap a higher-level name service that will provide
a distributed and replicated user-level name service. The network
name service is host-directed; that is requests for name look ups are
sent to specific hosts and are not broadcast.
12.2. Interface
boolean_t netname_init()
initializes the network name module.
nn_remove_entries(port_id)
port_t port_id;
removes all entries for the local port port_id from the local name
table.
typedef char netname_name_t[80]
kern_return_t netname_check_in(ServPort,port_name,signature,port_id)
vport_t ServPort;
netname_name_t port_name;
port_t signature;
port_t port_id;
checks in the port port_id under the name port_name protected by
signature.
kern_return_t netname_look_up(ServPort,host_name,port_name,port_id)
port_t ServPort;
netname_name_t host_name;
netname_name_t port_name;
port_t *port_id;
looks up port_name at host given by host_name. Returns in port_id the
port found.
kern_return_t netname_check_out(ServPort,port_name,signature,port_id)
port_t ServPort;
netname_name_t port_name;
port_t signature;
checks out the port checked in under port_name. The signature must
match the signature supplied to the netname_check_in call.
29
kern_return_t netname_version(ServPort,version)
port_t ServPort;
netname_name_t version;
returns in version some version identification for the network server.
int nn_handle_request(request,from,broadcast,crypt_level)
is called by disp_indata_simple to handle an incoming request for a
network name look up.
int nn_handle_reply(client_id,reply,from,broadcast,crypt_level)
is called by disp_rr_simple to handle an incoming response to a
request for a network name look up.
13. Memory Management
13.1. Operation
The memory management module is responsible for allocating and
deallocating various objects used by the different modules, such as
port and message records, buffers, and so on. It attempts to use
knowledge of the types of objects required to achieve good
performance. It tries to reduce the load placed on the MACH virtual
memory system.
13.2. Interface
boolean_t mem_init()
initializes the memory management module.
int mem_clean()
attempts to free as much unused space as possible to reduce the paging
load on the operating system; it is potentially slow.
pointer_t mem_allocobj(objtype)
int objtype;
allocates one instance of an object of the given objtype and returns
its address, or 0 in case of failure.
void mem_deallocobj(ptr,objtype)
pointer_t ptr;
int objtype;
30
deallocates an object of objtype previously allocated using
mem_allocobj.
pointer_t mem_alloc(size,aligned)
int size;
boolean_t aligned;
allocates a memory area of arbitrary size; it returns 0 in case of
failure.
void mem_dealloc(ptr,size)
pointer_t ptr;
int size;
deallocates memory previously allocated by mem_dealloc.
14. Read/Write Locks
The read/write locks module provides locks which can have multiple
readers and signals threads waiting for a lock when it becomes free.
14.1. Interface
typedef enum {PERM_READ, PERM_READWRITE} rw_perm_t;
typedef enum {NOBLOCK = 0, BLOCK = 1} rw_block_t;
typedef struct lock {...} *lock_t;
lock_t lk_alloc()
allocates a read/write lock.
void lk_free(lock)
frees a read/write lock.
int lk_lock(lock, perm, block)
lock_t lock;
rw_perm_t perm;
rw_block_t block;
locks the lock for type perm. If block is true, then this calls
blocks waiting until the lock can be obtained, otherwise the function
returns 0 if the lock cannot be obtained.
void lk_unlock(lock)
lock_t lock;
unlocks the lock.
31
15. Locked Queue Module
The locked queue module provides functions to manipulate items on
queues. When a queue is accessed it is always locked before being
manipulated.
15.1. Interface
typedef struct {...} *lock_queue_t;
typedef struct queue_item {struct queue_item *next} *queue_item_t;
lock_queue_t lq_alloc()
allocates and initializes a new locked queue.
void lq_init_queue(queue)
lock_queue_t queue;
re-initializes the already allocated queue.
void lq_prequeue(queue, item)
lock_queue_t queue;
queue_item_t item;
inserts item at the head of queue.
void lq_insert_in_queue(queue, test, item, args)
lock_queue_t queue;
int (*test)();
queue_item_t item;
int arg;
inserts item in the ``correct'' position on queue. The correct
position is determined by calling the user-supplied function test on
item, arg and the members of queue until it returns TRUE.
boolean_t lq_remove_from_queue(queue, item)
lock_queue_t queue;
queue_item_t item;
removes item from queue if item is present on the queue. Returns TRUE
is item was deleted from queue, FALSE otherwise.
boolean_t lq_cond_delete_from_queue(queue, test, item)
lock_queue_t queue;
int (*test)();
queue_item_t item;
int arg;
32
performs the user-supplied function test on item, arg and on
successive elements of queue. If it returns TRUE, then the current
element of the queue is deleted.
boolean_t lq_on_queue(queue, item)
lock_queue_t queue;
queue_item_t item;
checks to see if the item is on queue.
queue_item_t lq_dequeue(queue)
lock_queue_t queue;
if queue is not empty remove and return the queue item which is at the
head of it.
queue_item_t lq_blocking_dequeue(queue)
lock_queue_t queue;
if queue is empty, a wait is done until it is non-empty. Removes and
returns the queue item which is at the head of queue.
void lq_enqueue(queue, item);
lock_queue_t queue;
queue_item_t item;
inserts item at the tail of queue.
queue_item_t lq_find_in_queue(queue, fn, args)
lock_queue_t queue;
int (*fn)();
int arg;
returns a queue_item_t which is found by applying the user-supplied
function fn to successive elements of queue and arg until fn returns
TRUE.
void lq_map_queue(queue, fn, args);
lock_queue_t queue;
int (*fn)();
int arg;
applies the user-supplied function fn to each successive item of queue
and arg.
In addition to the above routines, a number of equivalent routines are
provided that do not acquire or release the queue lock when invoked,
to be used in situations where global lock management is needed to
avoid deadlock. Those routines are prefixed with lqn_ instead of lq_.
Finally, the network server also uses doubly-linked lists for some
queues. using the same macros used in the Mach kernel for that
purpose.
33
16. Timer Module
The timer module accepts requests from other modules for events to be
scheduled at some time in the future. When the event's deadline
expires the timer module calls the user-supplied function associated
with the timer.
16.1. Interface
boolean_t timer_init()
initializes the timer module.
struct timer {...} *timer_t;
timer_t timer_alloc()
returns a new timer.
void timer_start(timer)
timer_t timer;
starts up timer.
void timer_stop(timer)
timer_t timer;
stops timer.
17. Miscellaneous
17.1. Unique Identifer Generator
Simply generates locally unique identifiers (UIDs). The identifiers
generated are unique with high probability.
17.1.1. Interface
void uid_init()
initializes the UID module.
long uid_get_new_uid()
returns a new UID.
34
17.2. Sbuf
The sbuf module provides macros that manipulate sbufs.
17.2.1. Interface
void sbuf_printf(where, sb_ptr)
FILE *where;
sbuf_ptr_t sb_ptr;
is the only exported function of the sbuf module. It prints out the
contents of the sbuf pointed to by sb_ptr.
17.3. Network Interfaces
Under Mach the interface to the network is an IPC interface with a
filter inside the kernel determining which network packets are to be
received by the network server. Currently, many transport modules
still use BSD Unix sockets to access network protocol implementations
in the kernel.
17.3.1. Interface
int netipc_receive(pkt_ptr)
netipc_ptr_t pkt_ptr;
waits to receive a packet from the kernel. Checks the packet's UDP
checksum before returning to the caller.
int netipc_send(pkt_ptr)
netipc_ptr_t pkt_ptr;
calculates the UDP checksum for the packet and then sends it to the
kernel for transmission over the network.
17.4. IPC Message Receive
17.5. Interface
int netmsg_receive(msg_ptr)
msg_header_t *msg_ptr;
does a non-blocking receive for a local IPC message.
35
17.6. Debugging
The network server keeps a log in memory of various events happening
during its operation. This log, along with statistics on various
operations, can be obtained via the logstat service exported by the
network server. In addition, many operating parameters, including the
level of debugging information written to the log, can be set using
this same service.
17.6.1. Interface
Macros and procedures called within the network server
DEBUGn(condition,print_level,code,arg1,...,argn)
is a macro to be used to write a record containing the code and all
the integer args into the log. n is a number between 0 and 6,
indicating how many integers must be copied into the log. A log entry
is only made if condition evaluates to TRUE. In addition, if
print_level is greater or equal to the global debug.print_level, a
message is printed on stderr.
DEBUG_STRING(cond,level,string)
DEBUG_NPORT(cond,level,nport)
DEBUG_NETADDR(cond,level,netaddr)
DEBUG_KEY(cond,level,key)
DEBUG_SBUF(cond,level,sbuf)
are similar to the DEBUGn macros, but are used to enter a string, a
network port identifier, a network address, an encryption key or an
sbuf into the log.
The DEBUG macros can be made to expand to nothing via a compile-time
switch to avoid overheads at execution time. Each of those macros has
an equivalent LOG macro that can be enabled or disabled independently;
those LOG macros are intended for events that should always be entered
in the log and are infrequent enough that the overhead involved is
negligible.
ERROR((msg,format,args...))
is used to print out a message on stderr an make an entry in the log.
The argument should be a valid set of arguments for sprintf, with the
message string msg.
void panic(error_msg)
char *error_msg;
is called if something catastrophic happens. Prints out the
error_msg, dumps the log and terminates the network server.
void ipaddr_to_string(output_string, input_address)
char *output_string;
netaddr_t input_address;
36
Translates the input_address IP address into a printable
representation in output_string.
Procedures exported outside the network server: The following
procedures can be called remotely by sending requests on a port
checked-in as NM_LOGSTAT in the network server.
kern_return_t ls_sendlog(ServPort,old_log_ptr,old_log_size,
cur_log_ptr,cur_log_size)
port_t ServPort;
log_ptr_t *old_log_ptr;
unsigned int *old_log_size;
log_ptr_t *cur_log_ptr;
unsigned int *cur_log_size;
is used to obtain both network server logs in the response message.
The old and new logs correspond to the two alternating logs used to
record events.
kern_return_t ls_resetlog(ServPort)
port_t ServPort;
resets the log to zero size.
kern_return_t ls_writelog(ServPort)
port_t ServPort;
causes the network server to write its log in a file NMLOG in its
current working directory.
kern_return_t ls_sendstat(ServPort,stat_ptr,stat_size)
port_t ServPort;
stat_ptr_t *stat_ptr;
unsigned int *stat_size;
is used to obtain a record with the vital network server statistics in
the response.
kern_return_t ls_resetstat(ServPort)
port_t ServPort;
resets all statistics counters to zero.
kern_return_t ls_senddebug(ServPort,debug_ptr,debug_size)
port_t ServPort;
debug_ptr_t *debug_ptr;
unsigned int *debug_size;
is used to obtain a record with all the debugging flags used to
control the operation of the DEBUG macros.
37\
kern_return_t ls_setdebug(ServPort,debug_ptr,debug_size)
port_t ServPort;
debug_ptr_t *debug_ptr;
unsigned int *debug_size;
is used to replace the record with all the debugging flags used to
control the operation of the DEBUG macros.
kern_return_t ls_sendparam(ServPort,param_ptr,param_size)
port_t ServPort;
param_ptr_t *param_ptr;
unsigned int *param_size;
is used to obtain a record with the network server control parameters.
kern_return_t ls_setparam(ServPort,param_ptr,param_size)
port_t ServPort;
param_ptr_t *param_ptr;
unsigned int *param_size;
is used to replace the record with the network server control
parameters.
kern_return_t ls_sendportstat(ServPort,port_stat_ptr,port_stat_size)
port_t ServPort;
port_stat_ptr_t *port_stat_ptr;
unsigned int *port_stat_size;
is used to obtain a record with the port record statistics.
17.7. Camelot Support
The Camelot Distributed Transaction Facility [3 ] requires special
handling for IPC messages used in Camelot transactions. This handling
is performed in a special Camelot module, not described, here, that
behaves as an extra step in the translation process for incoming and
outgoing IPC messages.
In addition, Camelot also requires some specialized name servers, also
implemented in the Camelot module.
17.8. Kernel Netport Support
Certain Mach kernels provide an experimental feature, called Netport
or MACH_NP with which Kernel port records may be flagged as
corresponding to local representatives for remote network ports.
Under certain very restricted conditions, the kernel may, upon
processing a message destined for one of these ports, send the message
directly to the remote node instead of handing it to the network
server. This scheme results in improved performance by avoiding the
overhead of invoking the network servers on both ends of the
communication. Correctness is assured by having the kernel abort its
transmission and
38
reflect the message back to the network server as soon as a situation
arises that is too complex for the Netport code to handle.
When enabled, all modules in the network server that modify network
port records enter the correct information in the kernel port records
to allow the Netport code to function.
17.9. Initialization
The network server initialization sequence takes care of detecting
modules that require kernel support not present on the current node,
and of setting the working parameters accordingly. These include:
o Access to a network interface. If there is no network, the
network server degenerates into a simple local Name Server, as
specified by the conf_network parameter.
o Netport support: controlled by the conf_netport parameter.
o VMTP support. The transport_default parameter is set to the
index of the best transport protocol available.
17.9.1. Interface
boolean_t nm_init()
initializes the network server by calling and checking the error
returns for all the module initialization functions.
Appendix
A Compiling a Network Server
The various configuration options for the Network Server are all
defined in the file config.h, which should simply be edited before
compiling the system. The option settings in the file as distributed
are suitable for a normal generic configuration.
The configuration options are:
NET_LOG enable the LOGn macros.
NET_DEBUG enable the DEBUGn macros.
NET_TRACE enable tracing of procedure calls, under control of a
command line switch.
NET_PRINT enable printing from the LOG and DEBUG macros.
LOCK_THREADS do not allow more than one thread to run at any one time.
To use only for debugging.
NM_STATISTICS enable normal statistics gathering.
NETPORT enable entering information in the kernel port records for use
by the Netport option.
PORTSTAT enable port statistics gathering.
39
RPCMOD enable the RPC optimization, and the request-response
transport
interface. Should always be on.
COMPAT enable special operating mode for compatibility with the
previous implementation (Mach 1.0 and 2.0) of the Network Server.
NOTIFY explicitly allocate a notify port, which is not created by
default in newer versions of the Mach kernel.
CAMELOT include the Camelot module in the network server.
NM_USE_KDS use an external Key Distribution Server.
USE_VMTP include the VMTP transport module in the network server.
USE_DELTAT include the Delta-t transport module in the network server.
USE_CRYPT include the Crypt module in the network server.
USE_DES include the DES encryption module in the network server.
USE_MULTPERM include the ``multiple permutations'' encryption module
in the network server.
USE_NEWDES include the ``new'' DES encryption module in the network
server.
USE_XOR include the ``exclusive or'' encryption module in the network
server.
USE_KEYMAN include the keymanager module in the network server.
USE_TCP include the TCP transport module in the network server.
USE_DATAGRAM include the DATAGRAM transport module in the network
server.
USE_SRR include the SRR transport module in the network server.
Both USE_VMTP and NETPORT require kernel support that is not normally
present. Normally, USE_TCP, USE_SRR and USE_DATAGRAM should always be
enabled for the system to work.
In addition to the configuration options, the file config.h also
contains all the definitions needed to compile the network server on
various architectures. It is the only file that should be modified
when porting the network server to a new architecture.
References
[1] Cheriton, D. VMTP: A Transport Protocol for the Next Generation of
Communication Systems. In: Proceedings of the ACM SIGCOMM 86
Symposium on Communications Architectures and Protocols. ACM, 1986,
pp. 406-415.
[2] Sansom, R. D., Julin, D. P., and Rashid, R. F. Extending a
Capability Based System into a Network Environment. In: SIGCOMM
'86 Symposium: Communications Architectures & Protocols, ACM
SIGCOMM. 1986. Also available as Technical Report CMU-CS-86-115.
[3] Spector, A. Z., Bloch, J. J., Daniels, D. S., Draves, R. P.,
Duchamp, D., Eppinger, J. L., Menees, S. G., and Thompson, D. S.
The Camelot Project. Database Engineering, vol. 9 (1986). Also
available as Technical Report CMU-CS-86-166, Carnegie-Mellon
University, November 1986.