Previous Next Contents

5   Moving on

Now that we are familiar with inject and the basic format of a PLAN program, we can write more useful programs. PLAN is meant specifically for writing programs to be used in an active network---so let us run a very simple program that uses the active network.

5.1   Ping

The Ping program tries to reach a remote host, and once that task is accomplished, it sends the Ack program back to the original source which prints ``Success.''

svc print : 'a -> unit

fun ack() = print ("Success")

svc thisHostIs : host -> bool
svc getRB : void -> int
svc defaultRoute : host -> host * dev

fun ping (source, destination) =
  if (thisHostIs (destination)) then
    OnRemote (|ack| (), source, getRB (), defaultRoute)
  else
    OnRemote (|ping| (source, destination), 
              destination, getRB (), defaultRoute)

5.2   Understanding the program :
the OnRemote primitive

The OnRemote primitive is one of the two primitives8 provided in the language for specifying computation at a node across the network. It takes four arguments:

[What] The first argument specifies what to execute at the remote node. It must be of the form of a function call.9 Note that the arguments to the function call will be evaluated on the machine invoking OnRemote, while the function will be evaluated on the remote machine.
Where
The second argument specifies where to execute the packet next. Note that the packet may go through many other active nodes in the process of getting to the specified host, but it will not be executed at any intermediate nodes.
[How much] The third argument specifies how much of the current packet's resources to give to the outgoing packet.
[How to] The fourth argument specifies which routing function to use to get to the remote host.
The other network primitive provided is OnNeighbor. It requires that the second argument be adjacent to the current host; adjacency is defined in terms of the underlying link layer. When PLAN is running on top of IP, adjacency is defined by neighbors specified for each virtual IP device in the interface specification file. In our example in Section 3.1, interface file m1 specifies that m:3324 is adjacent to m:3325. When PLAN is running on top of Ethernet, two nodes are adjacent if they are on the same Ethernet. When two nodes are adjacent, no routing function is required, since routing is only necessary between physical networks. Instead, OnNeighbor needs the network interface through which to send the packet (which is of PLAN type dev).

The program consists of two function definitions. The first function, called ack simply prints ``Success.'' The second function, ping, is more interesting. It takes two arguments of type host and returns a unit result. The arguments name the source and destination10 of the computation. The body of the function first checks to see if the packet has arrived at the destination (the thisHostIs call). If so, it sends the ack function back to the source where ``Success'' will be printed. Otherwise, the function resends itself towards the destination. Both of these actions make use of the OnRemote primitive, and in both cases give all of current resources to the outgoing packet, and specify defaultRoute as the routing function to use.

5.3   Run this program

We'll use inject again, and we'll use the active network we set up at the end of Section 3, so our two nodes are m:3324 and m:3325. Suppose that you want to ping m:3325 from m:3324. The ping program may be found in the file rout_tests/ping.plan. We'll give this program a resource bound of 60 (will be explained later).

Then you invoke the program (from the plan directory) by the following :

% bin/inject -p 3324 rout_tests/ping.plan 60
And the initial invocation would be :

ping (getHostByName ("m:3324"), getHostByName ("m:3325"))
Notice that inject just provides a way from doing an OnRemote from the shell: the initial invocation specifies the first argument to OnRemote, the second and fourth arguments are specified with -ed and -rf options, and the third argument is specified by the RB.

Recall the initial invocation for the Hello World program -- simply the function call doit(). Here, the initial invocation is a bit more complex. We first specify that we want to execute the ping function when we reach our injection node, and then we specify the arguments to give to that function. Here, the first two arguments are themselves function calls. The interesting thing is that these arguments are evaluated immediately before being sent to the injection point. Therefore, the getHostByName function is executed locally, in the inject program, in order to resolve hostnames into PLAN values of type host. It is these PLAN values that are actually sent in the PLAN packet. getHostByName is one of a number of local services that are made available to programs using inject. These local service calls may only appear, and will only be evaluated, in the initial invocation provided to inject. For a complete list of local services, please refer to the PLAN Programmer's Guide [5]. Here, getHostByName looks up the name of the machine that you gave it, m, in the DNS table and retrieves the address for that machine which is then coupled with the provided port number to complete the virtual address of the node (having PLAN type host).

After typing this in, you should see a message on your screen :

Success

Previous Next Contents