CMSC 433, Spring 2003

Programming Language Technologies and Paradigms

Project 6

Due May 14, 2003



A Distributed Peer-to-Peer Network: Part 2

In project 5 you built a program that let you broadcast messages on a distributed peer-to-peer network. In this project you will refine your implementation, improving its robustness in the face of errors and making it more functional.

One of the main lessons to learn from this project is that code you write continues to haunt you long after you thought you were done with it.

There are several small parts to this project. Parts 1-4 are all independent of one another, so you can implement those right away, in any order.

0. Multicasting somebodyPeerWithMe

In project 5 we relied heavily on joining the network by contacting a well-known Portal. For this project that option will also be available, but we will also supply you with some code to use multicast to find peers.

1. Dealing with Slow Portals

Your project 6 code should be able to handle slow peers. If you peer with a portal that responds to messages very slowly, your portal should still handle other messages while waiting for receive() to return from the slow portal. Our suggestion is to use a separate thread (or a command given to a PooledExecutor) to send each message.

2. Making Connection Failures Symmetric

Suppose that Portals A and B are peered, and furthermore suppose that Portal A tries to send a message to B just when someone in the machine room trips over a network cord and disconnects B from the network. Then Portal A will catch the RemoteException from receive() and remove B from its set of peers. But B has no way of knowing that A un-peered with it. So if the network cord is reconnected, then B can continue sending messages to A, even though A can't send messages to B.

There are several other similar situations that can happen. To solve this problem, your project 6 code should make network failures symmetric. The receive() method should raise an exception if invoked on a peer that is no longer in the local portal's myPeers set.

3. Reverse Path Forwarding

We have supplied a new LocalPortal interface with one additional method for doing reverse path forwarding:

  public void forwardBackToSource(Long id, Message msg);
The forwardBackToSource() method sends msg to the Peer who original sent this portal message #id. For example, suppose our peer-to-peer network looks like this:

Suppose that A broadcasts message #101 to the network. Then at D, if we invoke forwardBackToSource(#101, msg), D will send msg to B. And at B, if we invoke forwardBackToSource(#101, msg), B will send msg only to A, and not to C or D.

If forwardBackToSource is called and id hasn't been seen on this portal, forwardBackToSource can simply ignore the request.

4. Allow Downloaded Code

You must install a SecurityManager in so that you can run downloaded code. You should only allow downloaded code to connect to port 80 of any host, and you should not grant downloaded code any other permissions.

Once you've installed a security manager, you'll need to grant permissions to your local code as well. Here is a policy file that grants all code the permissions you need to read the port property and to connect to anything on the network:

grant {
    permission java.util.PropertyPermission "port", "read";
    permission "*:*", "connect,accept";
Instead, if you want, you can just grant your own code, which allows your own code to do any privileged action.

You will need to modify this policy file to restrict permissions for downloaded code. Remember, you specify a policy file by running you program with java You should use java.policy for the name of your policy file.

5. Find Routes on the Network

Finally, you should extend your Portal class to also implement the NetworkMeasurement interface, which is as follows:

  public interface NetworkMeasurement {
    static public interface Callback {
      public void foundPath(List path);
    void measureNetwork(Callback callback);
The NetworkMeasurement interface contains a method measureNetwork(callback) that finds all the paths on the network from the Portal to all other Portals. For each path it finds, it calls foundPath(path). The paths do not contain the Portal itself.

For example, if measureNetwork(c) is invoked on Portal A in the network from part 3, then A should call (in any order) c({B}), c({B, D}), and c({B, C}).

You should implement measureNetwork() by writing two new subclasses of Message whose code you will make available on the network (thus using part 4). Let P be the portal on which measureNetwork() is called. The first message should, like BroadcastTextMessage, forward itself to all portals on the network. Whenever the message reaches a Portal, it should make a new message (of the second message kind) and send that back to P using forwardBackToSender() (thus using part 3). On the way back, the second message should call getAddress() and keep a list of the portals on the path back to P. When it reaches P it should stop, and then the callback supplied to measureNetwork should be invoked with the path.

Important: You must incorporate your class account name into your new message class names in some way, so that your local message classes don't collide with downloaded message class names. You can either put your account name directly in the class name, or you can make a package using your accout name.

To make your Message class code available for downloading, you'll need to run a web server. Use the simple web server here. To use this web server, in your own file you can make a new ClassFileServer(port, classpath). Use . as the classpath, and get the port via the "fileport" property (using Integer.getInteger("fileport",8xxx), where xxx is the last three digits of your class account).

Even More Important: Once a remote client has downloaded the code for your message classes, it will not download the code from the same code base again, even if you change it. Thus we recommend that whenever you make a change to your message classes, change the portal your web file server listens on.

Final Notes

To submit this project, use a command like

java -jar ~/Submit.jar 6 *.java java.policy

As always, submit early and often.



Valid HTML 4.01!