Computer Science 461

Distributed Computing and Networking

Fall 1997


Assignment 4

In this assignment you will implement a name server process and code to search a distributed tree of name servers. Your solution will allow a program to bind a service to a name like "/cs461/echo/swedish_chef", and will allow clients to bind to the service by name. Thus it will no longer be necessary for clients to know the location of the services they are connecting to.

The AcmeNet naming protocols use authenticated connections, allowing a name server to control which users can access which parts of the name space.

Your task is to implement two classes: AcmeNet.Assn4.Naming and AcmeNet.Assn4.NameService. The Naming class gives clients a convenient way to talk to a group of distributed name services, and the NameService class is a base class that all of the individual name services will extend.

Naming in AcmeNet

The AcmeNet name space looks like the Unix file name space: a name consists of a sequence of components separated by '/' characters. The main difference is that rather than specifying a file, an AcmeNet name specifies an AcmeNet service.

Some AcmeNet services are name services: they speak the AcmeNet naming protocol. A client connected to a name service can send requests to the service and will receive replies according to the message formats defined in the AcmeNet naming protocol.

Name services play a role analogous to that of directories in the Unix file system. In other words, a name service provides a mapping from simple names (names without '/' characters) to services. Some of these services might themselves be name services; these name services act like subdirectories.

The result is that looking up a compound name like "/cs461/echo/swedish_chef" involves going to the root name service and looking up the name "cs461", then going to the name service returned by the first lookup and looking up the name "echo", then going to the name service returned by the second lookup and looking up the name "swedish_chef". (At any point in this chain of lookups, the search could fail because there was no mapping for a name, or because the requester didn't have permission to do a search.)

The Naming Protocol

The AcmeNet Naming Protocol provides a way for clients to ask name services to perform actions, and a way for the name services to send back results. To request an action, the client establishes an authenticated connection to the name service. The client then sends one request to the name service; the name service sends back the reply to that request; and then both sides break the connection.

We have provided you with the class AcmeNet.Assn4.NameServiceOperationCode, which defines integer codes for four kinds of naming operations and two kinds of return codes for those operations. Each of these codes is sent along the connection as a single byte.

We will describe the protocol by describing the four kinds of requests one at a time. All data is send and received using DataOutputStreams and DataInputStreams, using the writeX method to send values of type X (and writeUTF for Strings). Several places in the protocol need to send a ServiceAddress; this is sent as a String followed by two ints. The String is the IP or DNS address of the machine, the first int is a port number on that machine, and the second int is the service number.

Bind Requests

The Bind request asks to bind a service to a name; this is analogous to creating a file in a directory. The Bind request message consists of On receiving a valid Bind request, the name service checks whether the requestor has permission to bind the requested name. If the requestor has permission, the binding is set up and the Success return code (a byte) is sent back. If the requestor does not have permission, the Failure return code (a byte) is sent back.

Note that a requestor may bind a service to a name even if another service was already bound to that name. This has the effect of removing the pre-existing binding and replacing it with the new one.

Unbind Requests

The Unbind request asks to unbind the service (if any) bound to a name; this is analogous to removing a file from a directory. The Unbind request message consists of the request code for Unbind (a byte), followed by the name to unbind (a UTF string, without slashes).

On receiving a valid Unbind request, the name service checks whether there is a binding for the received name, and whether the requestor has permission to unbind names. If there is a binding for that name and the requestor has permission to unbind the name, the binding is removed and a Success return code (a byte) is sent back. Otherwise, a Failure return code (a byte) is sent back.

List Requests

The List request asks to get a list of all of the names bound in a name service; this is analogous to creating a list of the files in a directory. The List request message consists of a single byte: the List request code.

On receiving a valid List request, the name service checks whether the requestor has permission to do the List operation. If the requestor has permission, the name service sends back a reply that consists of the Success result code (a byte), followed by the number of names bound in the name service (an int), followed by a sequence of Strings giving all of the names bound in the name service. (The names may be sent in any order.)

Lookup Requests

The Lookup request asks to get the ServiceAddress of the service bound to a particular name; this is analogous to looking up a file in a directory. The Lookup request message consists of the request code for Lookup (a byte), followed by the string to be looked up (a UTF string, without slashes).

On receiving a valid Lookup request, the name service checks whether the name is bound and whether the requestor has permission to look up that name. If both of these conditions are satisfied, the name service sends back a reply message that consists of the Success result code (a byte), followed by the ServiceAddress of the service bound to the requested name. (The encoding for ServiceAddresses is described above.) If the name is not bound or the requestor does not have permission, the name service sends back a Failure result code (a byte).

Permissions

Each name service is free to set up its own security rules. The security rules are defined by the hasBindPermission, hasListPermission, and hasLookupPermission methods of the NameService class. Each method returns true if the requested operation is permitted, or false if it is forbidden. The implementation of the Bind and Unbind operations should call hasBindPermission(requestor, name) to check whether the requestor has permission to bind or unbind a particular name. Similarly, the List operation should call hasListPermission, and the Lookup operation should call hasLookupPermission.

The AcmeNet.Assn4.NameService class should provide implementations of the has*Permission methods that always return true, denoting that everybody has permission to do everything. Programmers can then change the permission rules by defining subclasses of NameService that override the permission-checking methods.

For example, the root name server implements a policy that allows everybody to do List or Lookup, but Bind and Unbind operations only if the name being bound or unbound is equal to the requestor's userid. This gives each student the ability to have a part of the name space in which nobody else can control name bindings.

AcmeNet.Assn4.Naming

In addition to the NameService class, which implements the server side of the naming mechanism, you must write code for the class AcmeNet.Assn4.Naming. This class is designed to provide clients with convenient access to the naming system. For example, the code in this class allows clients to use full pathnames like "/cs461/echo/swedish_chef"; the Naming class parses the full pathnames into their components and does the necessary sequence of Lookup operations on the necessary sequence of name services to resolve the full pathname it is given.

The details of the Naming class are given in the on-line documentation.


Copyright (c) 1997 by Edward W. Felten

Last modified: Friday, November 14, 1997<--webbot bot="Timestamp" endspan i-checksum="1341" -->